Imported Upstream version 2.6.1 upstream upstream/2.6.1
authorhyokeun <hyokeun.jeon@samsung.com>
Tue, 27 Dec 2016 08:29:09 +0000 (17:29 +0900)
committerhyokeun <hyokeun.jeon@samsung.com>
Tue, 27 Dec 2016 08:29:09 +0000 (17:29 +0900)
2663 files changed:
.gitignore
.travis.yml
CODING_STYLE
HACKING
MAINTAINERS
Makefile
Makefile.objs
Makefile.target
VERSION
accel.c
aio-posix.c
aio-win32.c
arch_init.c
async.c
audio/audio.c
audio/audio.h
audio/audio_int.h
audio/audio_pt_int.h
audio/coreaudio.c
audio/mixeng.c
audio/mixeng.h
audio/noaudio.c
audio/ossaudio.c
audio/paaudio.c
audio/spiceaudio.c
audio/trace-events [deleted file]
audio/wavaudio.c
backends/hostmem.c
backends/msmouse.c
backends/rng-random.c
block.c
block/Makefile.objs
block/archipelago.c
block/backup.c
block/blkdebug.c
block/blkreplay.c
block/blkverify.c
block/block-backend.c
block/bochs.c
block/cloop.c
block/commit.c
block/crypto.c
block/curl.c
block/dirty-bitmap.c
block/dmg.c
block/gluster.c
block/io.c
block/iscsi.c
block/linux-aio.c
block/mirror.c
block/nbd-client.c
block/nbd-client.h
block/nbd.c
block/nfs.c
block/null.c
block/parallels.c
block/qapi.c
block/qcow.c
block/qcow2-cache.c
block/qcow2-cluster.c
block/qcow2-refcount.c
block/qcow2-snapshot.c
block/qcow2.c
block/qcow2.h
block/qed-check.c
block/qed-table.c
block/qed.c
block/quorum.c
block/raw-aio.h [moved from include/block/raw-aio.h with 74% similarity]
block/raw-posix.c
block/raw-win32.c
block/raw_bsd.c
block/rbd.c
block/sheepdog.c
block/snapshot.c
block/ssh.c
block/stream.c
block/throttle-groups.c
block/trace-events [deleted file]
block/vdi.c
block/vhdx-endian.c
block/vhdx-log.c
block/vhdx.c
block/vmdk.c
block/vpc.c
block/vvfat.c
block/win32-aio.c
blockdev.c
blockjob.c
bootdevice.c
bsd-user/elfload.c
bsd-user/i386/target_syscall.h
bsd-user/main.c
bsd-user/mmap.c
bsd-user/qemu.h
bsd-user/sparc/target_syscall.h
bsd-user/sparc64/target_syscall.h
bsd-user/syscall.c
bsd-user/x86_64/target_syscall.h
configure
contrib/ivshmem-client/ivshmem-client.h
contrib/ivshmem-server/ivshmem-server.c
contrib/ivshmem-server/ivshmem-server.h
cpu-exec-common.c
cpu-exec.c
cpus.c
cputlb.c
crypto/Makefile.objs
crypto/afsplit.c
crypto/block-luks.c
crypto/block-luks.h
crypto/block-qcow.h
crypto/block.c
crypto/blockpriv.h
crypto/hash-gcrypt.c [deleted file]
crypto/hash-glib.c [deleted file]
crypto/hash-nettle.c [deleted file]
crypto/hash.c
crypto/ivgenpriv.h
crypto/pbkdf-gcrypt.c
crypto/pbkdf-nettle.c
crypto/random-stub.c [moved from crypto/random-platform.c with 52% similarity]
crypto/tlscreds.c
crypto/tlscredspriv.h
crypto/tlscredsx509.c
crypto/tlssession.c
crypto/trace-events [deleted file]
default-configs/aarch64-softmmu.mak
default-configs/arm-softmmu.mak
default-configs/pci.mak
default-configs/ppc64-softmmu.mak
device_tree.c
disas/alpha.c
disas/arm.c
disas/i386.c
disas/m68k.c
disas/mips.c
disas/ppc.c
disas/sparc.c
dma-helpers.c
docs/atomics.txt
docs/build-system.txt
docs/igd-assign.txt [deleted file]
docs/memory.txt
docs/migration.txt
docs/multi-thread-compression.txt
docs/qapi-code-gen.txt
docs/qmp-events.txt
docs/specs/acpi_cpu_hotplug.txt
docs/specs/acpi_nvdimm.txt [deleted file]
docs/specs/parallels.txt
docs/specs/vhost-user.txt
docs/throttle.txt
docs/tracing.txt
docs/usb-storage.txt
docs/virtio-migration.txt
dump.c
exec.c
fpu/softfloat-specialize.h
fpu/softfloat.c
fsdev/9p-iov-marshal.c
fsdev/9p-iov-marshal.h
fsdev/9p-marshal.c
fsdev/9p-marshal.h
fsdev/file-op-9p.h
fsdev/qemu-fsdev-dummy.c
fsdev/qemu-fsdev-opts.c
fsdev/qemu-fsdev.c
fsdev/qemu-fsdev.h
fsdev/virtfs-proxy-helper.texi
gdbstub.c
hmp-commands-info.hx
hmp-commands.hx
hmp.c
hmp.h
hw/9pfs/9p-handle.c
hw/9pfs/9p-local.c
hw/9pfs/9p-proxy.c
hw/9pfs/9p-proxy.h
hw/9pfs/9p-synth.c
hw/9pfs/9p-synth.h
hw/9pfs/9p-xattr.h
hw/9pfs/9p.c
hw/9pfs/9p.h
hw/9pfs/codir.c
hw/9pfs/cofile.c
hw/9pfs/cofs.c
hw/9pfs/coth.c
hw/9pfs/coth.h
hw/9pfs/coxattr.c
hw/9pfs/trace-events [deleted file]
hw/9pfs/virtio-9p-device.c
hw/9pfs/virtio-9p.h
hw/acpi/Makefile.objs
hw/acpi/acpi_interface.c
hw/acpi/aml-build.c
hw/acpi/bios-linker-loader.c
hw/acpi/core.c
hw/acpi/cpu.c [deleted file]
hw/acpi/cpu_hotplug.c
hw/acpi/cpu_hotplug_acpi_table.c [new file with mode: 0644]
hw/acpi/ich9.c
hw/acpi/ipmi.c [deleted file]
hw/acpi/memory_hotplug.c
hw/acpi/nvdimm.c
hw/acpi/pcihp.c
hw/acpi/piix4.c
hw/acpi/trace-events [deleted file]
hw/alpha/alpha_sys.h
hw/alpha/pci.c
hw/alpha/trace-events [deleted file]
hw/alpha/typhoon.c
hw/arm/Makefile.objs
hw/arm/armv7m.c
hw/arm/ast2400.c
hw/arm/bcm2835_peripherals.c
hw/arm/boot.c
hw/arm/collie.c
hw/arm/digic.c
hw/arm/fsl-imx25.c
hw/arm/fsl-imx31.c
hw/arm/fsl-imx6.c [deleted file]
hw/arm/highbank.c
hw/arm/integratorcp.c
hw/arm/musicpal.c
hw/arm/nseries.c
hw/arm/palmetto-bmc.c
hw/arm/pxa2xx.c
hw/arm/pxa2xx_gpio.c
hw/arm/pxa2xx_pic.c
hw/arm/realview.c
hw/arm/sabrelite.c [deleted file]
hw/arm/spitz.c
hw/arm/stellaris.c
hw/arm/stm32f205_soc.c
hw/arm/strongarm.c
hw/arm/strongarm.h
hw/arm/tosa.c
hw/arm/trace-events [deleted file]
hw/arm/versatilepb.c
hw/arm/vexpress.c
hw/arm/virt-acpi-build.c
hw/arm/virt.c
hw/arm/xilinx_zynq.c
hw/arm/xlnx-ep108.c
hw/arm/xlnx-zynqmp.c
hw/arm/z2.c
hw/audio/cs4231.c
hw/audio/fmopl.h
hw/audio/gus.c
hw/audio/gusemu.h
hw/audio/gustate.h
hw/audio/intel-hda.c
hw/audio/lm4549.h
hw/audio/milkymist-ac97.c
hw/audio/pcspk.c
hw/audio/pl041.c
hw/audio/pl041.h
hw/audio/trace-events [deleted file]
hw/block/block.c
hw/block/dataplane/virtio-blk.c
hw/block/dataplane/virtio-blk.h
hw/block/fdc.c
hw/block/hd-geometry.c
hw/block/m25p80.c
hw/block/nand.c
hw/block/nvme.c
hw/block/onenand.c
hw/block/pflash_cfi01.c
hw/block/pflash_cfi02.c
hw/block/tc58128.c
hw/block/trace-events [deleted file]
hw/block/virtio-blk.c
hw/block/xen_blkif.h
hw/block/xen_disk.c
hw/bt/hci-csr.c
hw/bt/hci.c
hw/bt/l2cap.c
hw/bt/sdp.c
hw/char/bcm2835_aux.c
hw/char/cadence_uart.c
hw/char/digic-uart.c
hw/char/escc.c
hw/char/etraxfs_ser.c
hw/char/imx_serial.c
hw/char/ipoctal232.c
hw/char/lm32_juart.c
hw/char/lm32_uart.c
hw/char/milkymist-uart.c
hw/char/pl011.c
hw/char/sclpconsole-lm.c
hw/char/sclpconsole.c
hw/char/serial.c
hw/char/stm32f2xx_usart.c
hw/char/trace-events [deleted file]
hw/char/virtio-console.c
hw/char/virtio-serial-bus.c
hw/char/xen_console.c
hw/char/xilinx_uartlite.c
hw/core/Makefile.objs
hw/core/bus.c [deleted file]
hw/core/hotplug.c
hw/core/loader.c
hw/core/machine.c
hw/core/nmi.c
hw/core/ptimer.c
hw/core/qdev-properties-system.c
hw/core/qdev-properties.c
hw/core/qdev.c
hw/core/register.c [deleted file]
hw/core/sysbus.c
hw/core/uboot_image.h
hw/cpu/Makefile.objs
hw/cpu/a9mpcore.c
hw/cpu/core.c [deleted file]
hw/cris/axis_dev88.c
hw/cris/boot.h
hw/display/Makefile.objs
hw/display/ads7846.c
hw/display/bcm2835_fb.c
hw/display/blizzard.c
hw/display/blizzard_template.h [new file with mode: 0644]
hw/display/cg3.c
hw/display/dpcd.c [deleted file]
hw/display/exynos4210_fimd.c
hw/display/jazz_led.c
hw/display/milkymist-tmu2.c
hw/display/milkymist-vgafb.c
hw/display/omap_lcd_template.h
hw/display/omap_lcdc.c
hw/display/pl110.c
hw/display/qxl.c
hw/display/qxl.h
hw/display/ssd0323.c
hw/display/tc6393xb.c
hw/display/trace-events [deleted file]
hw/display/vga.c
hw/display/vga.h
hw/display/vga_int.h
hw/display/virtio-gpu-3d.c
hw/display/virtio-gpu-pci.c
hw/display/virtio-gpu.c
hw/display/virtio-vga.c
hw/display/xenfb.c
hw/display/xlnx_dp.c [deleted file]
hw/dma/Makefile.objs
hw/dma/bcm2835_dma.c
hw/dma/pl080.c
hw/dma/pl330.c
hw/dma/pxa2xx_dma.c
hw/dma/rc4030.c
hw/dma/trace-events [deleted file]
hw/dma/xlnx-zynq-devcfg.c [deleted file]
hw/dma/xlnx_dpdma.c [deleted file]
hw/gpio/gpio_key.c
hw/gpio/imx_gpio.c
hw/gpio/omap_gpio.c
hw/gpio/pl061.c
hw/gpio/zaurus.c
hw/i2c/Makefile.objs
hw/i2c/aspeed_i2c.c [deleted file]
hw/i2c/bitbang_i2c.c
hw/i2c/core.c
hw/i2c/exynos4210_i2c.c
hw/i2c/i2c-ddc.c [deleted file]
hw/i2c/imx_i2c.c
hw/i2c/omap_i2c.c
hw/i2c/smbus_ich9.c
hw/i2c/versatile_i2c.c
hw/i386/Makefile.objs
hw/i386/acpi-build.c
hw/i386/intel_iommu.c
hw/i386/intel_iommu_internal.h
hw/i386/kvm/apic.c
hw/i386/kvm/clock.c
hw/i386/kvm/i8254.c
hw/i386/kvm/pci-assign.c
hw/i386/kvmvapic.c
hw/i386/pc.c
hw/i386/pc_piix.c
hw/i386/pc_q35.c
hw/i386/trace-events [deleted file]
hw/i386/x86-iommu.c [deleted file]
hw/ide/ahci.c
hw/ide/ahci.h [moved from include/hw/ide/ahci.h with 99% similarity]
hw/ide/atapi.c
hw/ide/cmd646.c
hw/ide/core.c
hw/ide/ich.c
hw/ide/internal.h [moved from include/hw/ide/internal.h with 99% similarity]
hw/ide/isa.c
hw/ide/macio.c
hw/ide/microdrive.c
hw/ide/mmio.c
hw/ide/pci.c
hw/ide/pci.h [moved from include/hw/ide/pci.h with 98% similarity]
hw/ide/piix.c
hw/ide/qdev.c
hw/ide/via.c
hw/input/hid.c
hw/input/pckbd.c
hw/input/pl050.c
hw/input/trace-events [deleted file]
hw/input/virtio-input.c
hw/intc/Makefile.objs
hw/intc/allwinner-a10-pic.c
hw/intc/apic.c
hw/intc/apic_common.c
hw/intc/arm_gic.c
hw/intc/arm_gic_kvm.c
hw/intc/arm_gicv2m.c
hw/intc/arm_gicv3.c [deleted file]
hw/intc/arm_gicv3_common.c
hw/intc/arm_gicv3_cpuif.c [deleted file]
hw/intc/arm_gicv3_dist.c [deleted file]
hw/intc/arm_gicv3_kvm.c
hw/intc/arm_gicv3_redist.c [deleted file]
hw/intc/armv7m_nvic.c
hw/intc/aspeed_vic.c
hw/intc/bcm2835_ic.c
hw/intc/bcm2836_control.c
hw/intc/etraxfs_pic.c
hw/intc/exynos4210_combiner.c
hw/intc/exynos4210_gic.c
hw/intc/gic_internal.h
hw/intc/gicv3_internal.h [deleted file]
hw/intc/grlib_irqmp.c
hw/intc/i8259.c
hw/intc/imx_avic.c
hw/intc/ioapic.c
hw/intc/lm32_pic.c
hw/intc/mips_gic.c [deleted file]
hw/intc/omap_intc.c
hw/intc/openpic.c
hw/intc/openpic_kvm.c
hw/intc/pl190.c
hw/intc/s390_flic.c
hw/intc/s390_flic_kvm.c
hw/intc/slavio_intctl.c
hw/intc/trace-events [deleted file]
hw/intc/xics.c
hw/intc/xics_kvm.c
hw/intc/xics_spapr.c [deleted file]
hw/ipack/ipack.c
hw/ipack/tpci200.c
hw/ipmi/ipmi.c
hw/ipmi/ipmi_bmc_extern.c
hw/ipmi/isa_ipmi_bt.c
hw/ipmi/isa_ipmi_kcs.c
hw/isa/isa-bus.c
hw/isa/lpc_ich9.c
hw/isa/trace-events [deleted file]
hw/lm32/lm32.h
hw/lm32/lm32_boards.c
hw/lm32/milkymist-hw.h
hw/lm32/milkymist.c
hw/mem/nvdimm.c
hw/mem/pc-dimm.c
hw/microblaze/boot.h
hw/microblaze/petalogix_ml605_mmu.c
hw/microblaze/petalogix_s3adsp1800_mmu.c
hw/mips/cps.c
hw/mips/cputimer.c
hw/mips/gt64xxx_pci.c
hw/mips/mips_fulong2e.c
hw/mips/mips_int.c
hw/mips/mips_jazz.c
hw/mips/mips_malta.c
hw/mips/mips_mipssim.c
hw/mips/mips_r4k.c
hw/misc/Makefile.objs
hw/misc/arm11scu.c
hw/misc/arm_integrator_debug.c
hw/misc/arm_l2x0.c
hw/misc/arm_sysctl.c
hw/misc/aspeed_scu.c [deleted file]
hw/misc/auxbus.c [deleted file]
hw/misc/bcm2835_mbox.c
hw/misc/bcm2835_property.c
hw/misc/exynos4210_pmu.c
hw/misc/hyperv_testdev.c
hw/misc/imx25_ccm.c
hw/misc/imx31_ccm.c
hw/misc/imx6_ccm.c
hw/misc/imx6_src.c [deleted file]
hw/misc/imx_ccm.c
hw/misc/ivshmem.c
hw/misc/macio/cuda.c
hw/misc/macio/mac_dbdma.c
hw/misc/max111x.c
hw/misc/milkymist-hpdmc.c
hw/misc/milkymist-pfpu.c
hw/misc/mips_cmgcr.c
hw/misc/mips_cpc.c
hw/misc/mips_itu.c
hw/misc/mst_fpga.c
hw/misc/pc-testdev.c
hw/misc/pci-testdev.c
hw/misc/stm32f2xx_syscfg.c
hw/misc/trace-events [deleted file]
hw/misc/vmport.c
hw/misc/zynq-xadc.c
hw/misc/zynq_slcr.c
hw/net/Makefile.objs
hw/net/allwinner_emac.c
hw/net/cadence_gem.c
hw/net/dp8393x.c
hw/net/e1000.c
hw/net/e1000_regs.h
hw/net/e1000e.c [deleted file]
hw/net/e1000e_core.c [deleted file]
hw/net/e1000e_core.h [deleted file]
hw/net/e1000x_common.c [deleted file]
hw/net/e1000x_common.h [deleted file]
hw/net/eepro100.c
hw/net/etraxfs_eth.c
hw/net/fsl_etsec/etsec.c
hw/net/fsl_etsec/etsec.h
hw/net/fsl_etsec/registers.h
hw/net/fsl_etsec/rings.c
hw/net/imx_fec.c
hw/net/lan9118.c
hw/net/lance.c
hw/net/mcf_fec.c
hw/net/milkymist-minimac2.c
hw/net/mipsnet.c
hw/net/ne2000-isa.c
hw/net/ne2000.c
hw/net/ne2000.h
hw/net/net_rx_pkt.c [deleted file]
hw/net/net_rx_pkt.h [deleted file]
hw/net/net_tx_pkt.h [deleted file]
hw/net/opencores_eth.c
hw/net/pcnet-pci.c
hw/net/pcnet.h
hw/net/rocker/rocker.h
hw/net/rocker/rocker_desc.h
hw/net/rocker/rocker_fp.c
hw/net/rocker/rocker_fp.h
hw/net/rocker/rocker_hw.h
hw/net/rocker/rocker_of_dpa.c
hw/net/rocker/rocker_of_dpa.h
hw/net/rocker/rocker_tlv.h
hw/net/rocker/rocker_world.h
hw/net/rtl8139.c
hw/net/smc91c111.c
hw/net/spapr_llan.c
hw/net/stellaris_enet.c
hw/net/trace-events [deleted file]
hw/net/vhost_net.c
hw/net/virtio-net.c
hw/net/vmware_utils.h
hw/net/vmxnet3.c
hw/net/vmxnet3.h
hw/net/vmxnet_debug.h
hw/net/vmxnet_rx_pkt.c [new file with mode: 0644]
hw/net/vmxnet_rx_pkt.h [new file with mode: 0644]
hw/net/vmxnet_tx_pkt.c [moved from hw/net/net_tx_pkt.c with 52% similarity]
hw/net/vmxnet_tx_pkt.h [new file with mode: 0644]
hw/net/xen_nic.c
hw/net/xgmac.c
hw/net/xilinx_axienet.c
hw/net/xilinx_ethlite.c
hw/nvram/fw_cfg.c
hw/nvram/spapr_nvram.c
hw/nvram/trace-events [deleted file]
hw/pci-bridge/dec.h
hw/pci-bridge/ioh3420.c
hw/pci-bridge/pci_bridge_dev.c
hw/pci-bridge/pci_expander_bridge.c
hw/pci-bridge/xio3130_downstream.c
hw/pci-bridge/xio3130_upstream.c
hw/pci-bridge/xio3130_upstream.h
hw/pci-host/apb.c
hw/pci-host/grackle.c
hw/pci-host/piix.c
hw/pci-host/prep.c
hw/pci-host/q35.c
hw/pci-host/uninorth.c
hw/pci-host/versatile.c
hw/pci/msi.c
hw/pci/msix.c
hw/pci/pci.c
hw/pci/pcie.c
hw/pci/pcie_aer.c
hw/pci/trace-events [deleted file]
hw/ppc/Makefile.objs
hw/ppc/e500.c
hw/ppc/e500.h
hw/ppc/e500plat.c
hw/ppc/mac.h
hw/ppc/mac_newworld.c
hw/ppc/mac_oldworld.c
hw/ppc/ppc.c
hw/ppc/ppc405.h
hw/ppc/ppc4xx_devs.c
hw/ppc/ppce500_spin.c
hw/ppc/prep.c
hw/ppc/spapr.c
hw/ppc/spapr_cpu_core.c [deleted file]
hw/ppc/spapr_drc.c
hw/ppc/spapr_events.c
hw/ppc/spapr_hcall.c
hw/ppc/spapr_iommu.c
hw/ppc/spapr_pci.c
hw/ppc/spapr_pci_vfio.c
hw/ppc/spapr_rtas.c
hw/ppc/spapr_rtas_ddw.c [deleted file]
hw/ppc/spapr_vio.c
hw/ppc/trace-events [deleted file]
hw/ppc/virtex_ml507.c
hw/s390x/Makefile.objs
hw/s390x/ccw-device.c [deleted file]
hw/s390x/ccw-device.h [deleted file]
hw/s390x/css-bridge.c [deleted file]
hw/s390x/css.c
hw/s390x/css.h [moved from include/hw/s390x/css.h with 61% similarity]
hw/s390x/ipl.c
hw/s390x/ipl.h
hw/s390x/s390-pci-bus.c
hw/s390x/s390-pci-bus.h
hw/s390x/s390-pci-inst.c
hw/s390x/s390-pci-inst.h
hw/s390x/s390-skeys.c
hw/s390x/s390-virtio-ccw.c
hw/s390x/s390-virtio.h
hw/s390x/sclp.c
hw/s390x/sclpquiesce.c
hw/s390x/trace-events [deleted file]
hw/s390x/virtio-ccw.c
hw/s390x/virtio-ccw.h
hw/scsi/esp.c
hw/scsi/megasas.c
hw/scsi/mfi.h
hw/scsi/mptsas.c
hw/scsi/mptsas.h
hw/scsi/scsi-bus.c
hw/scsi/scsi-disk.c
hw/scsi/scsi-generic.c
hw/scsi/trace-events [deleted file]
hw/scsi/vhost-scsi.c
hw/scsi/virtio-scsi-dataplane.c
hw/scsi/virtio-scsi.c
hw/scsi/vmw_pvscsi.c
hw/sd/milkymist-memcard.c
hw/sd/pl181.c
hw/sd/sd.c
hw/sd/sdhci.c
hw/sd/ssi-sd.c
hw/sd/trace-events [deleted file]
hw/sh4/sh7750.c
hw/sh4/sh7750_regnames.h
hw/sh4/sh7750_regs.h
hw/sh4/sh_pci.c
hw/smbios/Makefile.objs
hw/smbios/smbios.c
hw/smbios/smbios_build.h [deleted file]
hw/smbios/smbios_type_38.c [deleted file]
hw/sparc/leon3.c
hw/sparc/sun4m.c
hw/sparc/trace-events [deleted file]
hw/ssi/Makefile.objs
hw/ssi/aspeed_smc.c [deleted file]
hw/ssi/imx_spi.c [deleted file]
hw/ssi/pl022.c
hw/ssi/ssi.c
hw/timer/Makefile.objs
hw/timer/allwinner-a10-pit.c
hw/timer/arm_timer.c
hw/timer/aspeed_timer.c
hw/timer/digic-timer.c
hw/timer/imx_epit.c
hw/timer/imx_gpt.c
hw/timer/lm32_timer.c
hw/timer/mc146818rtc.c
hw/timer/milkymist-sysctl.c
hw/timer/mips_gictimer.c [deleted file]
hw/timer/omap_gptimer.c
hw/timer/pl031.c
hw/timer/stm32f2xx_timer.c
hw/timer/trace-events [deleted file]
hw/tpm/tpm_util.h
hw/usb/Makefile.objs
hw/usb/bus.c
hw/usb/desc.c
hw/usb/dev-mtp.c
hw/usb/dev-network.c
hw/usb/dev-storage.c
hw/usb/dev-uas.c
hw/usb/hcd-ehci.c
hw/usb/hcd-ehci.h
hw/usb/hcd-ohci.c
hw/usb/hcd-xhci.c
hw/usb/host-libusb.c
hw/usb/redirect.c
hw/usb/trace-events [deleted file]
hw/usb/xen-usb.c [deleted file]
hw/vfio/Makefile.objs
hw/vfio/common.c
hw/vfio/pci-quirks.c
hw/vfio/pci.c
hw/vfio/pci.h
hw/vfio/platform.c
hw/vfio/spapr.c [deleted file]
hw/vfio/trace-events [deleted file]
hw/virtio/trace-events [deleted file]
hw/virtio/vhost-backend.c
hw/virtio/vhost-user.c
hw/virtio/vhost.c
hw/virtio/virtio-balloon.c
hw/virtio/virtio-bus.c
hw/virtio/virtio-mmio.c
hw/virtio/virtio-pci.c
hw/virtio/virtio-pci.h
hw/virtio/virtio-rng.c
hw/virtio/virtio.c
hw/watchdog/watchdog.c
hw/watchdog/wdt_diag288.c
hw/xen/xen-host-pci-device.h
hw/xen/xen_backend.c
hw/xen/xen_devconfig.c
hw/xen/xen_pt.h
hw/xen/xen_pt_config_init.c
hw/xen/xen_pt_msi.c
hw/xenpv/xen_domainbuild.h
hw/xenpv/xen_machine_pv.c
hw/xtensa/bootparam.h
hw/xtensa/pic_cpu.c
hw/xtensa/xtfpga.c
include/block/aio.h
include/block/block.h
include/block/block_int.h
include/block/blockjob.h
include/block/dirty-bitmap.h
include/block/nbd.h
include/block/scsi.h
include/block/thread-pool.h
include/block/throttle-groups.h
include/crypto/aes.h
include/crypto/afsplit.h
include/crypto/block.h
include/crypto/cipher.h
include/crypto/desrfb.h
include/crypto/hash.h
include/crypto/init.h
include/crypto/ivgen.h
include/crypto/pbkdf.h
include/crypto/random.h
include/crypto/secret.h
include/crypto/tlscreds.h
include/crypto/tlscredsanon.h
include/crypto/tlscredsx509.h
include/crypto/tlssession.h
include/crypto/xts.h
include/disas/bfd.h
include/disas/disas.h
include/elf.h
include/exec/address-spaces.h
include/exec/cpu-all.h
include/exec/cpu-common.h
include/exec/cpu-defs.h
include/exec/cpu_ldst_template.h
include/exec/cpu_ldst_useronly_template.h
include/exec/exec-all.h
include/exec/gdbstub.h
include/exec/gen-icount.h
include/exec/helper-gen.h
include/exec/helper-head.h
include/exec/helper-proto.h
include/exec/helper-tcg.h
include/exec/hwaddr.h
include/exec/ioport.h
include/exec/memory.h
include/exec/poison.h
include/exec/ram_addr.h
include/exec/softmmu-semi.h
include/exec/tb-context.h [deleted file]
include/exec/tb-hash-xx.h [deleted file]
include/exec/tb-hash.h
include/exec/user/abitypes.h
include/exec/user/thunk.h
include/fpu/softfloat.h
include/glib-compat.h
include/hw/acpi/acpi-defs.h
include/hw/acpi/acpi.h
include/hw/acpi/acpi_dev_interface.h
include/hw/acpi/aml-build.h
include/hw/acpi/bios-linker-loader.h
include/hw/acpi/cpu.h [deleted file]
include/hw/acpi/cpu_hotplug.h
include/hw/acpi/ich9.h
include/hw/acpi/ipmi.h [deleted file]
include/hw/acpi/memory_hotplug.h
include/hw/acpi/pcihp.h
include/hw/arm/arm.h
include/hw/arm/ast2400.h
include/hw/arm/digic.h
include/hw/arm/exynos4210.h
include/hw/arm/fsl-imx6.h [deleted file]
include/hw/arm/omap.h
include/hw/arm/pxa.h
include/hw/arm/soc_dma.h
include/hw/arm/stm32f205_soc.h
include/hw/arm/virt-acpi-build.h
include/hw/arm/virt.h
include/hw/arm/xlnx-zynqmp.h
include/hw/audio/audio.h
include/hw/audio/pcspk.h
include/hw/block/block.h
include/hw/block/flash.h
include/hw/boards.h
include/hw/bt.h
include/hw/char/cadence_uart.h
include/hw/char/escc.h
include/hw/char/lm32_juart.h
include/hw/char/pl011.h [deleted file]
include/hw/char/serial.h
include/hw/char/xilinx_uartlite.h [deleted file]
include/hw/compat.h
include/hw/cpu/core.h [deleted file]
include/hw/cris/etraxfs.h
include/hw/cris/etraxfs_dma.h
include/hw/display/dpcd.h [deleted file]
include/hw/display/xlnx_dp.h [deleted file]
include/hw/dma/xlnx_dpdma.h [deleted file]
include/hw/empty_slot.h
include/hw/fw-path-provider.h
include/hw/gpio/imx_gpio.h
include/hw/hotplug.h
include/hw/hw.h
include/hw/i2c/aspeed_i2c.h [deleted file]
include/hw/i2c/i2c-ddc.h [deleted file]
include/hw/i2c/i2c.h
include/hw/i2c/imx_i2c.h
include/hw/i2c/pm_smbus.h
include/hw/i386/apic-msidef.h
include/hw/i386/apic.h
include/hw/i386/apic_internal.h
include/hw/i386/ich9.h
include/hw/i386/intel_iommu.h
include/hw/i386/ioapic.h
include/hw/i386/ioapic_internal.h
include/hw/i386/pc.h
include/hw/i386/topology.h
include/hw/i386/x86-iommu.h [deleted file]
include/hw/input/adb.h
include/hw/input/ps2.h
include/hw/intc/allwinner-a10-pic.h
include/hw/intc/arm_gic.h
include/hw/intc/arm_gicv3.h [deleted file]
include/hw/intc/arm_gicv3_common.h
include/hw/intc/mips_gic.h [deleted file]
include/hw/ipack/ipack.h
include/hw/ipmi/ipmi.h
include/hw/isa/i8257.h
include/hw/isa/i8259_internal.h
include/hw/isa/isa.h
include/hw/m68k/mcf.h
include/hw/mem/nvdimm.h
include/hw/mem/pc-dimm.h
include/hw/mips/cps.h
include/hw/mips/cpudevs.h
include/hw/misc/arm_integrator_debug.h
include/hw/misc/aspeed_scu.h [deleted file]
include/hw/misc/auxbus.h [deleted file]
include/hw/misc/imx6_src.h [deleted file]
include/hw/misc/imx_ccm.h
include/hw/misc/mips_cmgcr.h
include/hw/misc/tmp105_regs.h
include/hw/net/allwinner_emac.h
include/hw/net/imx_fec.h
include/hw/nmi.h
include/hw/nvram/fw_cfg.h
include/hw/nvram/openbios_firmware_abi.h
include/hw/pci-host/apb.h
include/hw/pci-host/ppce500.h
include/hw/pci-host/q35.h
include/hw/pci-host/spapr.h
include/hw/pci/msi.h
include/hw/pci/msix.h
include/hw/pci/pci.h
include/hw/pci/pci_bridge.h
include/hw/pci/pci_bus.h
include/hw/pci/pci_ids.h
include/hw/pci/pci_regs.h
include/hw/pci/pcie.h
include/hw/pci/pcie_regs.h
include/hw/pcmcia.h
include/hw/platform-bus.h
include/hw/ppc/mac_dbdma.h
include/hw/ppc/openpic.h
include/hw/ppc/ppc.h
include/hw/ppc/ppc4xx.h
include/hw/ppc/spapr.h
include/hw/ppc/spapr_cpu_core.h [deleted file]
include/hw/ppc/spapr_drc.h
include/hw/ppc/spapr_vio.h
include/hw/ppc/xics.h
include/hw/ptimer.h
include/hw/qdev-core.h
include/hw/qdev-properties.h
include/hw/register.h [deleted file]
include/hw/s390x/css-bridge.h [deleted file]
include/hw/s390x/ebcdic.h
include/hw/s390x/event-facility.h
include/hw/s390x/s390-virtio-ccw.h
include/hw/s390x/s390_flic.h
include/hw/s390x/sclp.h
include/hw/s390x/storage-keys.h
include/hw/scsi/scsi.h
include/hw/sd/sd.h
include/hw/sh4/sh.h
include/hw/sh4/sh_intc.h
include/hw/smbios/ipmi.h [deleted file]
include/hw/smbios/smbios.h
include/hw/sparc/grlib.h
include/hw/ssi/aspeed_smc.h [deleted file]
include/hw/ssi/imx_spi.h [deleted file]
include/hw/ssi/ssi.h
include/hw/ssi/xilinx_spips.h
include/hw/stream.h
include/hw/sysbus.h
include/hw/timer/a9gtimer.h
include/hw/timer/allwinner-a10-pit.h
include/hw/timer/aspeed_timer.h
include/hw/timer/hpet.h
include/hw/timer/i8254.h
include/hw/timer/i8254_internal.h
include/hw/timer/imx_gpt.h
include/hw/timer/m48t59.h
include/hw/timer/mc146818rtc.h
include/hw/timer/mc146818rtc_regs.h
include/hw/timer/mips_gictimer.h [deleted file]
include/hw/tricore/tricore.h
include/hw/unicore32/puv3.h
include/hw/usb.h
include/hw/usb/ehci-regs.h
include/hw/usb/uhci-regs.h
include/hw/vfio/vfio-common.h
include/hw/vfio/vfio-platform.h
include/hw/vfio/vfio.h
include/hw/virtio/vhost-backend.h
include/hw/virtio/vhost.h
include/hw/virtio/virtio-access.h
include/hw/virtio/virtio-balloon.h
include/hw/virtio/virtio-blk.h
include/hw/virtio/virtio-bus.h
include/hw/virtio/virtio-gpu.h
include/hw/virtio/virtio-input.h
include/hw/virtio/virtio-net.h
include/hw/virtio/virtio-rng.h
include/hw/virtio/virtio-scsi.h
include/hw/virtio/virtio-serial.h
include/hw/virtio/virtio.h
include/hw/watchdog/wdt_diag288.h
include/hw/xen/xen.h
include/hw/xen/xen_backend.h
include/hw/xen/xen_common.h
include/io/channel-buffer.h
include/io/channel-command.h
include/io/channel-file.h
include/io/channel-socket.h
include/io/channel-tls.h
include/io/channel-util.h
include/io/channel-watch.h
include/io/channel-websock.h
include/io/channel.h
include/io/task.h
include/libdecnumber/decContext.h
include/libdecnumber/decNumber.h
include/libdecnumber/decNumberLocal.h
include/libdecnumber/dpd/decimal128.h
include/libdecnumber/dpd/decimal32.h
include/libdecnumber/dpd/decimal64.h
include/migration/block.h
include/migration/cpu.h [deleted file]
include/migration/migration.h
include/migration/qemu-file.h
include/migration/vmstate.h
include/monitor/hmp-target.h
include/monitor/monitor.h
include/monitor/qdev.h
include/net/checksum.h
include/net/eth.h
include/net/net.h
include/net/vhost-user.h
include/net/vhost_net.h
include/qapi/clone-visitor.h [deleted file]
include/qapi/dealloc-visitor.h
include/qapi/error.h
include/qapi/opts-visitor.h
include/qapi/qmp-input-visitor.h
include/qapi/qmp-output-visitor.h
include/qapi/qmp/dispatch.h
include/qapi/qmp/qerror.h
include/qapi/qmp/types.h
include/qapi/string-input-visitor.h
include/qapi/string-output-visitor.h
include/qapi/visitor-impl.h
include/qapi/visitor.h
include/qemu-common.h
include/qemu/acl.h
include/qemu/atomic.h
include/qemu/base64.h
include/qemu/bcd.h
include/qemu/bitmap.h
include/qemu/bitops.h
include/qemu/bswap.h
include/qemu/buffer.h
include/qemu/compiler.h
include/qemu/config-file.h
include/qemu/coroutine.h
include/qemu/coroutine_int.h
include/qemu/cutils.h
include/qemu/error-report.h
include/qemu/fifo32.h [deleted file]
include/qemu/fifo8.h
include/qemu/fprintf-fn.h
include/qemu/hbitmap.h
include/qemu/help_option.h
include/qemu/host-utils.h
include/qemu/id.h
include/qemu/log.h
include/qemu/main-loop.h
include/qemu/mmap-alloc.h
include/qemu/option.h
include/qemu/option_int.h
include/qemu/osdep.h
include/qemu/path.h
include/qemu/processor.h [deleted file]
include/qemu/qdist.h [deleted file]
include/qemu/qht.h [deleted file]
include/qemu/queue.h
include/qemu/range.h
include/qemu/ratelimit.h
include/qemu/rcu.h
include/qemu/rcu_queue.h
include/qemu/readline.h
include/qemu/seqlock.h
include/qemu/sockets.h
include/qemu/thread-posix.h
include/qemu/thread-win32.h
include/qemu/thread.h
include/qemu/timer.h
include/qemu/typedefs.h
include/qemu/unicode.h
include/qjson.h [moved from include/migration/qjson.h with 95% similarity]
include/qom/cpu.h
include/qom/object.h
include/standard-headers/linux/pci_regs.h
include/standard-headers/linux/virtio_config.h
include/sysemu/accel.h
include/sysemu/arch_init.h
include/sysemu/balloon.h
include/sysemu/block-backend.h
include/sysemu/bt.h
include/sysemu/char.h
include/sysemu/cpus.h
include/sysemu/device_tree.h
include/sysemu/dma.h
include/sysemu/hostmem.h
include/sysemu/kvm.h
include/sysemu/os-posix.h
include/sysemu/rng-random.h
include/sysemu/sysemu.h
include/sysemu/tpm_backend.h
include/sysemu/tpm_backend_int.h
include/sysemu/xen-mapcache.h
include/trace-tcg.h
include/trace.h
include/ui/console.h
include/ui/gtk.h
include/ui/qemu-spice.h
include/ui/sdl2.h
io/channel-buffer.c
io/channel-socket.c
io/channel-websock.c
io/channel.c
io/trace-events [deleted file]
ioport.c
kvm-all.c
kvm-stub.c
linux-headers/asm-arm/unistd.h
linux-headers/asm-arm64/unistd.h
linux-headers/asm-powerpc/unistd.h
linux-headers/asm-s390/kvm.h
linux-headers/asm-s390/unistd.h
linux-headers/asm-x86/kvm.h
linux-headers/asm-x86/unistd_x32.h
linux-headers/linux/kvm.h
linux-user/Makefile.objs
linux-user/aarch64/syscall_nr.h
linux-user/aarch64/target_cpu.h
linux-user/aarch64/target_signal.h
linux-user/aarch64/target_structs.h
linux-user/aarch64/target_syscall.h
linux-user/alpha/target_cpu.h
linux-user/alpha/target_signal.h
linux-user/alpha/target_structs.h
linux-user/alpha/target_syscall.h
linux-user/arm/nwfpe/fpa11.h
linux-user/arm/nwfpe/fpopcode.h
linux-user/arm/nwfpe/fpsr.h
linux-user/arm/target_cpu.h
linux-user/arm/target_signal.h
linux-user/arm/target_structs.h
linux-user/arm/target_syscall.h
linux-user/cris/target_cpu.h
linux-user/cris/target_signal.h
linux-user/cris/target_structs.h
linux-user/cris/target_syscall.h
linux-user/elfload.c
linux-user/errno_defs.h
linux-user/flatload.c
linux-user/host/aarch64/hostdep.h [deleted file]
linux-user/host/aarch64/safe-syscall.inc.S [deleted file]
linux-user/host/arm/hostdep.h [deleted file]
linux-user/host/arm/safe-syscall.inc.S [deleted file]
linux-user/host/i386/hostdep.h [deleted file]
linux-user/host/i386/safe-syscall.inc.S [deleted file]
linux-user/host/ia64/hostdep.h [deleted file]
linux-user/host/mips/hostdep.h [deleted file]
linux-user/host/ppc/hostdep.h [deleted file]
linux-user/host/ppc64/hostdep.h [deleted file]
linux-user/host/ppc64/safe-syscall.inc.S [deleted file]
linux-user/host/s390/hostdep.h [deleted file]
linux-user/host/s390x/hostdep.h [deleted file]
linux-user/host/s390x/safe-syscall.inc.S [deleted file]
linux-user/host/sparc/hostdep.h [deleted file]
linux-user/host/sparc64/hostdep.h [deleted file]
linux-user/host/x32/hostdep.h [deleted file]
linux-user/host/x86_64/hostdep.h [deleted file]
linux-user/host/x86_64/safe-syscall.inc.S [deleted file]
linux-user/i386/target_cpu.h
linux-user/i386/target_signal.h
linux-user/i386/target_structs.h
linux-user/i386/target_syscall.h
linux-user/ioctls.h
linux-user/linux_loop.h
linux-user/m68k/target_cpu.h
linux-user/m68k/target_signal.h
linux-user/m68k/target_structs.h
linux-user/m68k/target_syscall.h
linux-user/main.c
linux-user/microblaze/target_cpu.h
linux-user/microblaze/target_signal.h
linux-user/microblaze/target_structs.h
linux-user/microblaze/target_syscall.h
linux-user/mips/target_cpu.h
linux-user/mips/target_signal.h
linux-user/mips/target_structs.h
linux-user/mips/target_syscall.h
linux-user/mips64/target_signal.h
linux-user/mips64/target_syscall.h
linux-user/mmap.c
linux-user/openrisc/target_cpu.h
linux-user/openrisc/target_signal.h
linux-user/openrisc/target_structs.h
linux-user/openrisc/target_syscall.h
linux-user/ppc/target_cpu.h
linux-user/ppc/target_signal.h
linux-user/ppc/target_structs.h
linux-user/ppc/target_syscall.h
linux-user/qemu.h
linux-user/s390x/target_cpu.h
linux-user/s390x/target_signal.h
linux-user/s390x/target_structs.h
linux-user/s390x/target_syscall.h
linux-user/safe-syscall.S [deleted file]
linux-user/sh4/target_cpu.h
linux-user/sh4/target_signal.h
linux-user/sh4/target_structs.h
linux-user/sh4/target_syscall.h
linux-user/signal.c
linux-user/sparc/syscall_nr.h
linux-user/sparc/target_cpu.h
linux-user/sparc/target_signal.h
linux-user/sparc/target_structs.h
linux-user/sparc/target_syscall.h
linux-user/sparc64/target_signal.h
linux-user/sparc64/target_structs.h
linux-user/sparc64/target_syscall.h
linux-user/strace.c
linux-user/strace.list
linux-user/syscall.c
linux-user/syscall_defs.h
linux-user/syscall_types.h
linux-user/tilegx/syscall_nr.h
linux-user/tilegx/target_cpu.h
linux-user/tilegx/target_signal.h
linux-user/tilegx/target_structs.h
linux-user/tilegx/target_syscall.h
linux-user/trace-events [deleted file]
linux-user/uname.h
linux-user/unicore32/target_cpu.h
linux-user/unicore32/target_signal.h
linux-user/unicore32/target_structs.h
linux-user/unicore32/target_syscall.h
linux-user/x86_64/target_signal.h
linux-user/x86_64/target_structs.h
linux-user/x86_64/target_syscall.h
linux-user/x86_64/termbits.h
main-loop.c
memory.c
memory_mapping.c
migration/Makefile.objs
migration/block.c
migration/exec.c
migration/fd.c
migration/migration.c
migration/postcopy-ram.c
migration/qemu-file-buf.c [new file with mode: 0644]
migration/qemu-file-channel.c [deleted file]
migration/qemu-file-internal.h [moved from include/hw/dma/xlnx-zynq-devcfg.h with 53% similarity]
migration/qemu-file-stdio.c [new file with mode: 0644]
migration/qemu-file-unix.c [new file with mode: 0644]
migration/qemu-file.c
migration/ram.c
migration/rdma.c
migration/savevm.c
migration/socket.c [deleted file]
migration/tcp.c [new file with mode: 0644]
migration/tls.c [deleted file]
migration/trace-events [deleted file]
migration/unix.c [new file with mode: 0644]
migration/vmstate.c
monitor.c
nbd/client.c
nbd/common.c
nbd/nbd-internal.h
nbd/server.c
net/checksum.c
net/clients.h
net/dump.c
net/eth.c
net/filter-mirror.c
net/filter.c
net/hub.c
net/l2tpv3.c
net/net.c
net/netmap.c
net/slirp.c
net/socket.c
net/tap-linux.h
net/tap-win32.c
net/tap.c
net/tap_int.h
net/trace-events [deleted file]
net/vde.c
net/vhost-user.c
numa.c
os-posix.c
page_cache.c
pc-bios/bios-256k.bin
pc-bios/bios.bin
pc-bios/efi-e1000.rom
pc-bios/efi-e1000e.rom [deleted file]
pc-bios/efi-eepro100.rom
pc-bios/efi-ne2k_pci.rom
pc-bios/efi-pcnet.rom
pc-bios/efi-rtl8139.rom
pc-bios/efi-virtio.rom
pc-bios/efi-vmxnet3.rom [deleted file]
pc-bios/linuxboot_dma.bin [deleted file]
pc-bios/openbios-ppc
pc-bios/openbios-sparc32
pc-bios/openbios-sparc64
pc-bios/optionrom/Makefile
pc-bios/optionrom/code16gcc.h [deleted file]
pc-bios/optionrom/flat.lds [deleted file]
pc-bios/optionrom/linuxboot_dma.c [deleted file]
pc-bios/s390-ccw.img
pc-bios/s390-ccw/Makefile
pc-bios/s390-ccw/iplb.h [deleted file]
pc-bios/s390-ccw/main.c
pc-bios/s390-ccw/s390-ccw.h
pc-bios/s390-ccw/start.S
pc-bios/s390-ccw/virtio-scsi.c
pc-bios/s390-ccw/virtio.h
po/Makefile
po/bg.po [deleted file]
qapi-schema.json
qapi/Makefile.objs
qapi/block-core.json
qapi/crypto.json
qapi/opts-visitor.c
qapi/qapi-clone-visitor.c [deleted file]
qapi/qapi-dealloc-visitor.c
qapi/qapi-visit-core.c
qapi/qmp-dispatch.c
qapi/qmp-input-visitor.c
qapi/qmp-output-visitor.c
qapi/qmp-registry.c
qapi/string-input-visitor.c
qapi/string-output-visitor.c
qapi/trace.json
qemu-bridge-helper.c
qemu-char.c
qemu-doc.texi
qemu-img-cmds.hx
qemu-img.c
qemu-img.texi
qemu-io-cmds.c
qemu-io.c
qemu-nbd.c
qemu-nbd.texi
qemu-option-trace.texi [deleted file]
qemu-options.h
qemu-options.hx
qemu-timer.c
qga/channel-posix.c
qga/channel-win32.c
qga/channel.h
qga/commands-posix.c
qga/commands-win32.c
qga/commands.c
qga/guest-agent-command-state.c
qga/main.c
qga/service-win32.c
qga/service-win32.h
qga/vss-win32/install.cpp
qga/vss-win32/provider.cpp
qga/vss-win32/requester.cpp
qga/vss-win32/vss-common.h
qjson.c [moved from migration/qjson.c with 70% similarity]
qmp-commands.hx
qmp.c
qobject/json-lexer.c
qobject/json-parser.c
qobject/qdict.c
qobject/qjson.c
qobject/qlist.c
qobject/qobject.c
qom/cpu.c
qom/object.c
qom/object_interfaces.c
qom/qom-qobject.c
qom/trace-events [deleted file]
qtest.c
replay/replay-char.c
replay/replay-input.c
roms/Makefile
roms/config.seabios-128k
roms/ipxe/src/Makefile
roms/ipxe/src/Makefile.efi [deleted file]
roms/ipxe/src/Makefile.housekeeping
roms/ipxe/src/arch/arm/Makefile [deleted file]
roms/ipxe/src/arch/arm/Makefile.efi [deleted file]
roms/ipxe/src/arch/arm/core/arm_io.c [deleted file]
roms/ipxe/src/arch/arm/include/bits/endian.h [deleted file]
roms/ipxe/src/arch/arm/include/bits/errfile.h [deleted file]
roms/ipxe/src/arch/arm/include/bits/hyperv.h [deleted file]
roms/ipxe/src/arch/arm/include/bits/io.h [deleted file]
roms/ipxe/src/arch/arm/include/bits/iomap.h [deleted file]
roms/ipxe/src/arch/arm/include/bits/nap.h [deleted file]
roms/ipxe/src/arch/arm/include/bits/pci_io.h [deleted file]
roms/ipxe/src/arch/arm/include/bits/uart.h [deleted file]
roms/ipxe/src/arch/arm/include/bits/umalloc.h [deleted file]
roms/ipxe/src/arch/arm/include/bits/xen.h [deleted file]
roms/ipxe/src/arch/arm/include/ipxe/arm_io.h [deleted file]
roms/ipxe/src/arch/arm/include/ipxe/efi/efiarm_nap.h [deleted file]
roms/ipxe/src/arch/arm/interface/efi/efiarm_nap.c [deleted file]
roms/ipxe/src/arch/arm32/Makefile [deleted file]
roms/ipxe/src/arch/arm32/Makefile.efi [deleted file]
roms/ipxe/src/arch/arm32/core/arm32_bigint.c [deleted file]
roms/ipxe/src/arch/arm32/core/setjmp.S [deleted file]
roms/ipxe/src/arch/arm32/include/bits/bigint.h [deleted file]
roms/ipxe/src/arch/arm32/include/bits/bitops.h [deleted file]
roms/ipxe/src/arch/arm32/include/bits/byteswap.h [deleted file]
roms/ipxe/src/arch/arm32/include/bits/compiler.h [deleted file]
roms/ipxe/src/arch/arm32/include/bits/profile.h [deleted file]
roms/ipxe/src/arch/arm32/include/bits/stdint.h [deleted file]
roms/ipxe/src/arch/arm32/include/bits/string.h [deleted file]
roms/ipxe/src/arch/arm32/include/bits/strings.h [deleted file]
roms/ipxe/src/arch/arm32/include/bits/tcpip.h [deleted file]
roms/ipxe/src/arch/arm32/include/efi/ipxe/dhcp_arch.h [deleted file]
roms/ipxe/src/arch/arm32/include/gdbmach.h [deleted file]
roms/ipxe/src/arch/arm32/include/limits.h [deleted file]
roms/ipxe/src/arch/arm32/include/setjmp.h [deleted file]
roms/ipxe/src/arch/arm32/libgcc/lldivmod.S [deleted file]
roms/ipxe/src/arch/arm32/libgcc/llshift.S [deleted file]
roms/ipxe/src/arch/arm64/Makefile [deleted file]
roms/ipxe/src/arch/arm64/Makefile.efi [deleted file]
roms/ipxe/src/arch/arm64/core/arm64_bigint.c [deleted file]
roms/ipxe/src/arch/arm64/core/arm64_string.c [deleted file]
roms/ipxe/src/arch/arm64/core/arm64_tcpip.c [deleted file]
roms/ipxe/src/arch/arm64/core/setjmp.S [deleted file]
roms/ipxe/src/arch/arm64/include/bits/bigint.h [deleted file]
roms/ipxe/src/arch/arm64/include/bits/bitops.h [deleted file]
roms/ipxe/src/arch/arm64/include/bits/byteswap.h [deleted file]
roms/ipxe/src/arch/arm64/include/bits/compiler.h [deleted file]
roms/ipxe/src/arch/arm64/include/bits/profile.h [deleted file]
roms/ipxe/src/arch/arm64/include/bits/stdint.h [deleted file]
roms/ipxe/src/arch/arm64/include/bits/string.h [deleted file]
roms/ipxe/src/arch/arm64/include/bits/strings.h [deleted file]
roms/ipxe/src/arch/arm64/include/bits/tcpip.h [deleted file]
roms/ipxe/src/arch/arm64/include/efi/ipxe/dhcp_arch.h [deleted file]
roms/ipxe/src/arch/arm64/include/gdbmach.h [deleted file]
roms/ipxe/src/arch/arm64/include/limits.h [deleted file]
roms/ipxe/src/arch/arm64/include/setjmp.h [deleted file]
roms/ipxe/src/arch/i386/Makefile
roms/ipxe/src/arch/i386/Makefile.efi
roms/ipxe/src/arch/i386/Makefile.pcbios
roms/ipxe/src/arch/i386/core/basemem_packet.c [moved from roms/ipxe/src/arch/x86/core/basemem_packet.c with 100% similarity]
roms/ipxe/src/arch/i386/core/cachedhcp.c [moved from roms/ipxe/src/arch/x86/core/cachedhcp.c with 93% similarity]
roms/ipxe/src/arch/i386/core/dumpregs.c [moved from roms/ipxe/src/arch/x86/core/dumpregs.c with 78% similarity]
roms/ipxe/src/arch/i386/core/gdbidt.S
roms/ipxe/src/arch/i386/core/gdbmach.c [new file with mode: 0644]
roms/ipxe/src/arch/i386/core/patch_cf.S [moved from roms/ipxe/src/arch/x86/core/patch_cf.S with 100% similarity]
roms/ipxe/src/arch/i386/core/pci_autoboot.c [moved from roms/ipxe/src/arch/x86/core/pci_autoboot.c with 100% similarity]
roms/ipxe/src/arch/i386/core/rdtsc_timer.c [moved from roms/ipxe/src/arch/x86/core/rdtsc_timer.c with 100% similarity]
roms/ipxe/src/arch/i386/core/relocate.c [moved from roms/ipxe/src/arch/x86/core/relocate.c with 76% similarity]
roms/ipxe/src/arch/i386/core/runtime.c [moved from roms/ipxe/src/arch/x86/core/runtime.c with 100% similarity]
roms/ipxe/src/arch/i386/core/stack.S [moved from roms/ipxe/src/arch/x86/core/stack.S with 76% similarity]
roms/ipxe/src/arch/i386/core/stack16.S [moved from roms/ipxe/src/arch/x86/core/stack16.S with 100% similarity]
roms/ipxe/src/arch/i386/core/video_subr.c [moved from roms/ipxe/src/arch/x86/core/video_subr.c with 100% similarity]
roms/ipxe/src/arch/i386/core/virtaddr.S [new file with mode: 0644]
roms/ipxe/src/arch/i386/drivers/net/undi.c [moved from roms/ipxe/src/arch/x86/drivers/net/undi.c with 100% similarity]
roms/ipxe/src/arch/i386/drivers/net/undiisr.S [moved from roms/ipxe/src/arch/x86/drivers/net/undiisr.S with 100% similarity]
roms/ipxe/src/arch/i386/drivers/net/undiload.c [moved from roms/ipxe/src/arch/x86/drivers/net/undiload.c with 100% similarity]
roms/ipxe/src/arch/i386/drivers/net/undinet.c [moved from roms/ipxe/src/arch/x86/drivers/net/undinet.c with 99% similarity]
roms/ipxe/src/arch/i386/drivers/net/undionly.c [moved from roms/ipxe/src/arch/x86/drivers/net/undionly.c with 100% similarity]
roms/ipxe/src/arch/i386/drivers/net/undipreload.c [moved from roms/ipxe/src/arch/x86/drivers/net/undipreload.c with 100% similarity]
roms/ipxe/src/arch/i386/drivers/net/undirom.c [moved from roms/ipxe/src/arch/x86/drivers/net/undirom.c with 100% similarity]
roms/ipxe/src/arch/i386/firmware/pcbios/basemem.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/basemem.c with 100% similarity]
roms/ipxe/src/arch/i386/firmware/pcbios/bios_console.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/bios_console.c with 65% similarity]
roms/ipxe/src/arch/i386/firmware/pcbios/e820mangler.S [moved from roms/ipxe/src/arch/x86/interface/pcbios/e820mangler.S with 100% similarity]
roms/ipxe/src/arch/i386/firmware/pcbios/fakee820.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/fakee820.c with 96% similarity]
roms/ipxe/src/arch/i386/firmware/pcbios/hidemem.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/hidemem.c with 96% similarity]
roms/ipxe/src/arch/i386/firmware/pcbios/memmap.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/memmap.c with 98% similarity]
roms/ipxe/src/arch/i386/firmware/pcbios/pnpbios.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/pnpbios.c with 100% similarity]
roms/ipxe/src/arch/i386/hci/commands/pxe_cmd.c [moved from roms/ipxe/src/arch/x86/hci/commands/pxe_cmd.c with 100% similarity]
roms/ipxe/src/arch/i386/image/bootsector.c [moved from roms/ipxe/src/arch/x86/image/bootsector.c with 93% similarity]
roms/ipxe/src/arch/i386/image/bzimage.c [moved from roms/ipxe/src/arch/x86/image/bzimage.c with 99% similarity]
roms/ipxe/src/arch/i386/image/com32.c [moved from roms/ipxe/src/arch/x86/image/com32.c with 77% similarity]
roms/ipxe/src/arch/i386/image/comboot.c [moved from roms/ipxe/src/arch/x86/image/comboot.c with 98% similarity]
roms/ipxe/src/arch/i386/image/elfboot.c [moved from roms/ipxe/src/arch/x86/image/elfboot.c with 100% similarity]
roms/ipxe/src/arch/i386/image/initrd.c [moved from roms/ipxe/src/arch/x86/image/initrd.c with 100% similarity]
roms/ipxe/src/arch/i386/image/multiboot.c [moved from roms/ipxe/src/arch/x86/image/multiboot.c with 100% similarity]
roms/ipxe/src/arch/i386/image/nbi.c [moved from roms/ipxe/src/arch/x86/image/nbi.c with 99% similarity]
roms/ipxe/src/arch/i386/image/pxe_image.c [moved from roms/ipxe/src/arch/x86/image/pxe_image.c with 98% similarity]
roms/ipxe/src/arch/i386/image/sdi.c [moved from roms/ipxe/src/arch/x86/image/sdi.c with 100% similarity]
roms/ipxe/src/arch/i386/include/basemem.h [moved from roms/ipxe/src/arch/x86/include/basemem.h with 100% similarity]
roms/ipxe/src/arch/i386/include/basemem_packet.h [moved from roms/ipxe/src/arch/x86/include/basemem_packet.h with 100% similarity]
roms/ipxe/src/arch/i386/include/bios.h [moved from roms/ipxe/src/arch/x86/include/bios.h with 100% similarity]
roms/ipxe/src/arch/i386/include/bios_disks.h [moved from roms/ipxe/src/arch/x86/include/bios_disks.h with 100% similarity]
roms/ipxe/src/arch/i386/include/biosint.h [moved from roms/ipxe/src/arch/x86/include/biosint.h with 95% similarity]
roms/ipxe/src/arch/i386/include/bits/compiler.h
roms/ipxe/src/arch/i386/include/bits/entropy.h [moved from roms/ipxe/src/arch/x86/include/bits/entropy.h with 79% similarity]
roms/ipxe/src/arch/i386/include/bits/hyperv.h
roms/ipxe/src/arch/i386/include/bits/nap.h [moved from roms/ipxe/src/arch/x86/include/bits/nap.h with 79% similarity]
roms/ipxe/src/arch/i386/include/bits/reboot.h [moved from roms/ipxe/src/arch/x86/include/bits/reboot.h with 79% similarity]
roms/ipxe/src/arch/i386/include/bits/sanboot.h [moved from roms/ipxe/src/arch/x86/include/bits/sanboot.h with 79% similarity]
roms/ipxe/src/arch/i386/include/bits/smbios.h [moved from roms/ipxe/src/arch/x86/include/bits/smbios.h with 79% similarity]
roms/ipxe/src/arch/i386/include/bits/time.h [moved from roms/ipxe/src/arch/x86/include/bits/time.h with 79% similarity]
roms/ipxe/src/arch/i386/include/bits/timer.h [moved from roms/ipxe/src/arch/x86/include/bits/timer.h with 81% similarity]
roms/ipxe/src/arch/i386/include/bits/uaccess.h [moved from roms/ipxe/src/arch/x86/include/bits/uaccess.h with 76% similarity]
roms/ipxe/src/arch/i386/include/bits/umalloc.h [moved from roms/ipxe/src/arch/x86/include/bits/umalloc.h with 74% similarity]
roms/ipxe/src/arch/i386/include/bochs.h [moved from roms/ipxe/src/arch/x86/include/bochs.h with 100% similarity]
roms/ipxe/src/arch/i386/include/bootsector.h [moved from roms/ipxe/src/arch/x86/include/bootsector.h with 100% similarity]
roms/ipxe/src/arch/i386/include/bzimage.h [moved from roms/ipxe/src/arch/x86/include/bzimage.h with 100% similarity]
roms/ipxe/src/arch/i386/include/comboot.h [moved from roms/ipxe/src/arch/x86/include/comboot.h with 95% similarity]
roms/ipxe/src/arch/i386/include/fakee820.h [moved from roms/ipxe/src/arch/x86/include/fakee820.h with 100% similarity]
roms/ipxe/src/arch/i386/include/gdbmach.h
roms/ipxe/src/arch/i386/include/initrd.h [moved from roms/ipxe/src/arch/x86/include/initrd.h with 100% similarity]
roms/ipxe/src/arch/i386/include/int13.h [moved from roms/ipxe/src/arch/x86/include/int13.h with 100% similarity]
roms/ipxe/src/arch/i386/include/ipxe/bios_nap.h [moved from roms/ipxe/src/arch/x86/include/ipxe/bios_nap.h with 100% similarity]
roms/ipxe/src/arch/i386/include/ipxe/bios_reboot.h [moved from roms/ipxe/src/arch/x86/include/ipxe/bios_reboot.h with 100% similarity]
roms/ipxe/src/arch/i386/include/ipxe/bios_sanboot.h [moved from roms/ipxe/src/arch/x86/include/ipxe/bios_sanboot.h with 55% similarity]
roms/ipxe/src/arch/i386/include/ipxe/bios_smbios.h [moved from roms/ipxe/src/arch/x86/include/ipxe/bios_smbios.h with 100% similarity]
roms/ipxe/src/arch/i386/include/ipxe/bios_timer.h [moved from roms/ipxe/src/arch/x86/include/ipxe/bios_timer.h with 100% similarity]
roms/ipxe/src/arch/i386/include/ipxe/errno/pcbios.h [moved from roms/ipxe/src/arch/x86/include/ipxe/errno/pcbios.h with 100% similarity]
roms/ipxe/src/arch/i386/include/ipxe/guestrpc.h [moved from roms/ipxe/src/arch/x86/include/ipxe/guestrpc.h with 100% similarity]
roms/ipxe/src/arch/i386/include/ipxe/memtop_umalloc.h [moved from roms/ipxe/src/arch/x86/include/ipxe/memtop_umalloc.h with 100% similarity]
roms/ipxe/src/arch/i386/include/ipxe/rdtsc_timer.h [moved from roms/ipxe/src/arch/x86/include/ipxe/rdtsc_timer.h with 100% similarity]
roms/ipxe/src/arch/i386/include/ipxe/rtc_entropy.h [moved from roms/ipxe/src/arch/x86/include/ipxe/rtc_entropy.h with 100% similarity]
roms/ipxe/src/arch/i386/include/ipxe/rtc_time.h [moved from roms/ipxe/src/arch/x86/include/ipxe/rtc_time.h with 100% similarity]
roms/ipxe/src/arch/i386/include/ipxe/vesafb.h [moved from roms/ipxe/src/arch/x86/include/ipxe/vesafb.h with 100% similarity]
roms/ipxe/src/arch/i386/include/ipxe/vmware.h [moved from roms/ipxe/src/arch/x86/include/ipxe/vmware.h with 100% similarity]
roms/ipxe/src/arch/i386/include/kir.h [moved from roms/ipxe/src/arch/x86/include/kir.h with 100% similarity]
roms/ipxe/src/arch/i386/include/libkir.h [moved from roms/ipxe/src/arch/x86/include/libkir.h with 100% similarity]
roms/ipxe/src/arch/i386/include/librm.h [moved from roms/ipxe/src/arch/x86/include/librm.h with 56% similarity]
roms/ipxe/src/arch/i386/include/memsizes.h [moved from roms/ipxe/src/arch/x86/include/memsizes.h with 100% similarity]
roms/ipxe/src/arch/i386/include/multiboot.h [moved from roms/ipxe/src/arch/x86/include/multiboot.h with 100% similarity]
roms/ipxe/src/arch/i386/include/pnpbios.h [moved from roms/ipxe/src/arch/x86/include/pnpbios.h with 100% similarity]
roms/ipxe/src/arch/i386/include/pxe.h [moved from roms/ipxe/src/arch/x86/include/pxe.h with 99% similarity]
roms/ipxe/src/arch/i386/include/pxe_api.h [moved from roms/ipxe/src/arch/x86/include/pxe_api.h with 100% similarity]
roms/ipxe/src/arch/i386/include/pxe_call.h [moved from roms/ipxe/src/arch/x86/include/pxe_call.h with 97% similarity]
roms/ipxe/src/arch/i386/include/pxe_error.h [moved from roms/ipxe/src/arch/x86/include/pxe_error.h with 100% similarity]
roms/ipxe/src/arch/i386/include/pxe_types.h [moved from roms/ipxe/src/arch/x86/include/pxe_types.h with 100% similarity]
roms/ipxe/src/arch/i386/include/pxeparent.h [moved from roms/ipxe/src/arch/x86/include/pxeparent.h with 100% similarity]
roms/ipxe/src/arch/i386/include/realmode.h [moved from roms/ipxe/src/arch/x86/include/realmode.h with 100% similarity]
roms/ipxe/src/arch/i386/include/registers.h [moved from roms/ipxe/src/arch/x86/include/registers.h with 98% similarity]
roms/ipxe/src/arch/i386/include/rtc.h [moved from roms/ipxe/src/arch/x86/include/rtc.h with 100% similarity]
roms/ipxe/src/arch/i386/include/sdi.h [moved from roms/ipxe/src/arch/x86/include/sdi.h with 100% similarity]
roms/ipxe/src/arch/i386/include/setjmp.h
roms/ipxe/src/arch/i386/include/undi.h [moved from roms/ipxe/src/arch/x86/include/undi.h with 100% similarity]
roms/ipxe/src/arch/i386/include/undiload.h [moved from roms/ipxe/src/arch/x86/include/undiload.h with 100% similarity]
roms/ipxe/src/arch/i386/include/undinet.h [moved from roms/ipxe/src/arch/x86/include/undinet.h with 100% similarity]
roms/ipxe/src/arch/i386/include/undipreload.h [moved from roms/ipxe/src/arch/x86/include/undipreload.h with 100% similarity]
roms/ipxe/src/arch/i386/include/undirom.h [moved from roms/ipxe/src/arch/x86/include/undirom.h with 100% similarity]
roms/ipxe/src/arch/i386/include/vga.h [moved from roms/ipxe/src/arch/x86/include/vga.h with 100% similarity]
roms/ipxe/src/arch/i386/interface/pcbios/apm.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/apm.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/pcbios/bios_nap.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/bios_nap.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/pcbios/bios_reboot.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/bios_reboot.c with 95% similarity]
roms/ipxe/src/arch/i386/interface/pcbios/bios_smbios.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/bios_smbios.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/pcbios/bios_timer.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/bios_timer.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/pcbios/biosint.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/biosint.c with 78% similarity]
roms/ipxe/src/arch/i386/interface/pcbios/int13.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/int13.c with 98% similarity]
roms/ipxe/src/arch/i386/interface/pcbios/int13con.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/int13con.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/pcbios/memtop_umalloc.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/memtop_umalloc.c with 79% similarity]
roms/ipxe/src/arch/i386/interface/pcbios/pcibios.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/pcibios.c with 97% similarity]
roms/ipxe/src/arch/i386/interface/pcbios/rtc_entropy.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/rtc_entropy.c with 85% similarity]
roms/ipxe/src/arch/i386/interface/pcbios/rtc_time.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/rtc_time.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/pcbios/vesafb.c [moved from roms/ipxe/src/arch/x86/interface/pcbios/vesafb.c with 91% similarity]
roms/ipxe/src/arch/i386/interface/pxe/pxe_call.c [moved from roms/ipxe/src/arch/x86/interface/pxe/pxe_call.c with 85% similarity]
roms/ipxe/src/arch/i386/interface/pxe/pxe_entry.S [moved from roms/ipxe/src/arch/x86/interface/pxe/pxe_entry.S with 98% similarity]
roms/ipxe/src/arch/i386/interface/pxe/pxe_exit_hook.c [moved from roms/ipxe/src/arch/x86/interface/pxe/pxe_exit_hook.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/pxe/pxe_file.c [moved from roms/ipxe/src/arch/x86/interface/pxe/pxe_file.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/pxe/pxe_loader.c [moved from roms/ipxe/src/arch/x86/interface/pxe/pxe_loader.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/pxe/pxe_preboot.c [moved from roms/ipxe/src/arch/x86/interface/pxe/pxe_preboot.c with 93% similarity]
roms/ipxe/src/arch/i386/interface/pxe/pxe_tftp.c [moved from roms/ipxe/src/arch/x86/interface/pxe/pxe_tftp.c with 98% similarity]
roms/ipxe/src/arch/i386/interface/pxe/pxe_udp.c [moved from roms/ipxe/src/arch/x86/interface/pxe/pxe_udp.c with 97% similarity]
roms/ipxe/src/arch/i386/interface/pxe/pxe_undi.c [moved from roms/ipxe/src/arch/x86/interface/pxe/pxe_undi.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/pxeparent/pxeparent.c [moved from roms/ipxe/src/arch/x86/interface/pxeparent/pxeparent.c with 97% similarity]
roms/ipxe/src/arch/i386/interface/syslinux/com32_call.c [moved from roms/ipxe/src/arch/x86/interface/syslinux/com32_call.c with 91% similarity]
roms/ipxe/src/arch/i386/interface/syslinux/com32_wrapper.S [moved from roms/ipxe/src/arch/x86/interface/syslinux/com32_wrapper.S with 51% similarity]
roms/ipxe/src/arch/i386/interface/syslinux/comboot_call.c [moved from roms/ipxe/src/arch/x86/interface/syslinux/comboot_call.c with 93% similarity]
roms/ipxe/src/arch/i386/interface/syslinux/comboot_resolv.c [moved from roms/ipxe/src/arch/x86/interface/syslinux/comboot_resolv.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/vmware/guestinfo.c [moved from roms/ipxe/src/arch/x86/interface/vmware/guestinfo.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/vmware/guestrpc.c [moved from roms/ipxe/src/arch/x86/interface/vmware/guestrpc.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/vmware/vmconsole.c [moved from roms/ipxe/src/arch/x86/interface/vmware/vmconsole.c with 100% similarity]
roms/ipxe/src/arch/i386/interface/vmware/vmware.c [moved from roms/ipxe/src/arch/x86/interface/vmware/vmware.c with 100% similarity]
roms/ipxe/src/arch/i386/prefix/bootpart.S [moved from roms/ipxe/src/arch/x86/prefix/bootpart.S with 100% similarity]
roms/ipxe/src/arch/i386/prefix/dskprefix.S [moved from roms/ipxe/src/arch/x86/prefix/dskprefix.S with 99% similarity]
roms/ipxe/src/arch/i386/prefix/exeprefix.S [moved from roms/ipxe/src/arch/x86/prefix/exeprefix.S with 98% similarity]
roms/ipxe/src/arch/i386/prefix/hdprefix.S [moved from roms/ipxe/src/arch/x86/prefix/hdprefix.S with 95% similarity]
roms/ipxe/src/arch/i386/prefix/isaromprefix.S [moved from roms/ipxe/src/arch/x86/prefix/isaromprefix.S with 100% similarity]
roms/ipxe/src/arch/i386/prefix/kkkpxeprefix.S [moved from roms/ipxe/src/arch/x86/prefix/kkkpxeprefix.S with 100% similarity]
roms/ipxe/src/arch/i386/prefix/kkpxeprefix.S [moved from roms/ipxe/src/arch/x86/prefix/kkpxeprefix.S with 100% similarity]
roms/ipxe/src/arch/i386/prefix/kpxeprefix.S [moved from roms/ipxe/src/arch/x86/prefix/kpxeprefix.S with 100% similarity]
roms/ipxe/src/arch/i386/prefix/libprefix.S [moved from roms/ipxe/src/arch/x86/prefix/libprefix.S with 87% similarity]
roms/ipxe/src/arch/i386/prefix/lkrnprefix.S [moved from roms/ipxe/src/arch/x86/prefix/lkrnprefix.S with 98% similarity]
roms/ipxe/src/arch/i386/prefix/mbr.S [moved from roms/ipxe/src/arch/x86/prefix/mbr.S with 100% similarity]
roms/ipxe/src/arch/i386/prefix/mromprefix.S [moved from roms/ipxe/src/arch/x86/prefix/mromprefix.S with 100% similarity]
roms/ipxe/src/arch/i386/prefix/nbiprefix.S [moved from roms/ipxe/src/arch/x86/prefix/nbiprefix.S with 96% similarity]
roms/ipxe/src/arch/i386/prefix/nullprefix.S [moved from roms/ipxe/src/arch/x86/prefix/nullprefix.S with 100% similarity]
roms/ipxe/src/arch/i386/prefix/pciromprefix.S [moved from roms/ipxe/src/arch/x86/prefix/pciromprefix.S with 100% similarity]
roms/ipxe/src/arch/i386/prefix/pxeprefix.S [moved from roms/ipxe/src/arch/x86/prefix/pxeprefix.S with 99% similarity]
roms/ipxe/src/arch/i386/prefix/romprefix.S [moved from roms/ipxe/src/arch/x86/prefix/romprefix.S with 96% similarity]
roms/ipxe/src/arch/i386/prefix/undiloader.S [moved from roms/ipxe/src/arch/x86/prefix/undiloader.S with 83% similarity]
roms/ipxe/src/arch/i386/prefix/unlzma.S [moved from roms/ipxe/src/arch/x86/prefix/unlzma.S with 95% similarity]
roms/ipxe/src/arch/i386/prefix/unlzma16.S [moved from roms/ipxe/src/arch/x86/prefix/unlzma16.S with 100% similarity]
roms/ipxe/src/arch/i386/prefix/usbdisk.S [moved from roms/ipxe/src/arch/x86/prefix/usbdisk.S with 100% similarity]
roms/ipxe/src/arch/i386/scripts/i386.lds [moved from roms/ipxe/src/arch/x86/scripts/pcbios.lds with 86% similarity]
roms/ipxe/src/arch/i386/transitions/liba20.S [moved from roms/ipxe/src/arch/x86/transitions/liba20.S with 100% similarity]
roms/ipxe/src/arch/i386/transitions/libkir.S [moved from roms/ipxe/src/arch/x86/transitions/libkir.S with 100% similarity]
roms/ipxe/src/arch/i386/transitions/libpm.S [moved from roms/ipxe/src/arch/x86/transitions/libpm.S with 100% similarity]
roms/ipxe/src/arch/i386/transitions/librm.S [new file with mode: 0644]
roms/ipxe/src/arch/i386/transitions/librm_mgmt.c [new file with mode: 0644]
roms/ipxe/src/arch/i386/transitions/librm_test.c [moved from roms/ipxe/src/arch/x86/transitions/librm_test.c with 78% similarity]
roms/ipxe/src/arch/x86/Makefile
roms/ipxe/src/arch/x86/Makefile.efi
roms/ipxe/src/arch/x86/Makefile.pcbios [deleted file]
roms/ipxe/src/arch/x86/core/gdbmach.c [deleted file]
roms/ipxe/src/arch/x86/core/pcidirect.c
roms/ipxe/src/arch/x86/core/x86_io.c
roms/ipxe/src/arch/x86/core/x86_tcpip.c
roms/ipxe/src/arch/x86/include/bits/bitops.h [deleted file]
roms/ipxe/src/arch/x86/include/bits/errfile.h
roms/ipxe/src/arch/x86/include/bits/iomap.h [deleted file]
roms/ipxe/src/arch/x86/include/bits/tcpip.h
roms/ipxe/src/arch/x86/include/bits/xen.h
roms/ipxe/src/arch/x86/include/ipxe/iomap_pages.h [deleted file]
roms/ipxe/src/arch/x86/include/ipxe/x86_io.h
roms/ipxe/src/arch/x86/include/rmsetjmp.h [deleted file]
roms/ipxe/src/arch/x86/interface/efi/efi_entropy.c [moved from roms/ipxe/src/interface/efi/efi_entropy.c with 96% similarity]
roms/ipxe/src/arch/x86/prefix/efidrvprefix.c [moved from roms/ipxe/src/interface/efi/efidrvprefix.c with 100% similarity]
roms/ipxe/src/arch/x86/prefix/efiprefix.c [moved from roms/ipxe/src/interface/efi/efiprefix.c with 100% similarity]
roms/ipxe/src/arch/x86/scripts/efi.lds [moved from roms/ipxe/src/scripts/efi.lds with 100% similarity]
roms/ipxe/src/arch/x86/transitions/librm.S [deleted file]
roms/ipxe/src/arch/x86/transitions/librm_mgmt.c [deleted file]
roms/ipxe/src/arch/x86_64/Makefile
roms/ipxe/src/arch/x86_64/Makefile.efi
roms/ipxe/src/arch/x86_64/Makefile.pcbios [deleted file]
roms/ipxe/src/arch/x86_64/core/gdbidt.S [deleted file]
roms/ipxe/src/arch/x86_64/include/bits/compiler.h
roms/ipxe/src/arch/x86_64/include/bits/entropy.h [moved from roms/ipxe/src/arch/arm/include/bits/entropy.h with 74% similarity]
roms/ipxe/src/arch/x86_64/include/bits/hyperv.h
roms/ipxe/src/arch/x86_64/include/bits/nap.h [new file with mode: 0644]
roms/ipxe/src/arch/x86_64/include/bits/reboot.h [moved from roms/ipxe/src/arch/arm/include/bits/reboot.h with 74% similarity]
roms/ipxe/src/arch/x86_64/include/bits/sanboot.h [moved from roms/ipxe/src/arch/arm/include/bits/sanboot.h with 74% similarity]
roms/ipxe/src/arch/x86_64/include/bits/smbios.h [moved from roms/ipxe/src/arch/arm/include/bits/smbios.h with 53% similarity]
roms/ipxe/src/arch/x86_64/include/bits/time.h [moved from roms/ipxe/src/arch/arm/include/bits/time.h with 74% similarity]
roms/ipxe/src/arch/x86_64/include/bits/timer.h [moved from roms/ipxe/src/arch/arm/include/bits/timer.h with 52% similarity]
roms/ipxe/src/arch/x86_64/include/bits/uaccess.h [moved from roms/ipxe/src/arch/arm/include/bits/uaccess.h with 52% similarity]
roms/ipxe/src/arch/x86_64/include/bits/umalloc.h [new file with mode: 0644]
roms/ipxe/src/arch/x86_64/include/gdbmach.h
roms/ipxe/src/arch/x86_64/include/pcbios/ipxe/dhcp_arch.h [deleted file]
roms/ipxe/src/config/cloud/aws.ipxe [deleted file]
roms/ipxe/src/config/cloud/colour.h [deleted file]
roms/ipxe/src/config/cloud/console.h [deleted file]
roms/ipxe/src/config/cloud/crypto.h [deleted file]
roms/ipxe/src/config/cloud/general.h [deleted file]
roms/ipxe/src/config/cloud/serial.h [deleted file]
roms/ipxe/src/config/cloud/settings.h [deleted file]
roms/ipxe/src/config/cloud/sideband.h [deleted file]
roms/ipxe/src/config/cloud/usb.h [deleted file]
roms/ipxe/src/config/config.c
roms/ipxe/src/config/config_efi.c [deleted file]
roms/ipxe/src/config/config_ethernet.c
roms/ipxe/src/config/config_infiniband.c
roms/ipxe/src/config/config_linux.c [deleted file]
roms/ipxe/src/config/config_pcbios.c [deleted file]
roms/ipxe/src/config/config_usb.c
roms/ipxe/src/config/console.h
roms/ipxe/src/config/crypto.h
roms/ipxe/src/config/defaults/efi.h
roms/ipxe/src/config/defaults/pcbios.h
roms/ipxe/src/config/dhcp.h
roms/ipxe/src/config/general.h
roms/ipxe/src/config/usb.h
roms/ipxe/src/core/debug.c
roms/ipxe/src/core/downloader.c
roms/ipxe/src/core/exec.c
roms/ipxe/src/core/fbcon.c
roms/ipxe/src/core/gdbstub.c
roms/ipxe/src/core/getkey.c
roms/ipxe/src/core/image.c
roms/ipxe/src/core/iobuf.c
roms/ipxe/src/core/iomap_virt.c [deleted file]
roms/ipxe/src/core/malloc.c
roms/ipxe/src/core/memblock.c [new file with mode: 0644]
roms/ipxe/src/core/memmap_settings.c
roms/ipxe/src/core/pixbuf.c
roms/ipxe/src/core/random.c
roms/ipxe/src/core/serial.c
roms/ipxe/src/core/settings.c
roms/ipxe/src/core/string.c
roms/ipxe/src/core/time.c
roms/ipxe/src/core/timer.c
roms/ipxe/src/core/uri.c
roms/ipxe/src/core/vsprintf.c
roms/ipxe/src/crypto/asn1.c
roms/ipxe/src/crypto/certstore.c
roms/ipxe/src/crypto/drbg.c
roms/ipxe/src/crypto/hash_df.c
roms/ipxe/src/crypto/hmac.c
roms/ipxe/src/crypto/hmac_drbg.c
roms/ipxe/src/crypto/ocsp.c
roms/ipxe/src/crypto/privkey.c
roms/ipxe/src/crypto/rbg.c
roms/ipxe/src/crypto/rootcert.c
roms/ipxe/src/drivers/block/ibft.c
roms/ipxe/src/drivers/bus/pci.c
roms/ipxe/src/drivers/bus/pci_settings.c
roms/ipxe/src/drivers/bus/pciea.c [deleted file]
roms/ipxe/src/drivers/bus/pciextra.c
roms/ipxe/src/drivers/bus/usb.c
roms/ipxe/src/drivers/bus/virtio-pci.c
roms/ipxe/src/drivers/bus/virtio-ring.c
roms/ipxe/src/drivers/infiniband/CIB_PRM.h [deleted file]
roms/ipxe/src/drivers/infiniband/arbel.c
roms/ipxe/src/drivers/infiniband/arbel.h
roms/ipxe/src/drivers/infiniband/flexboot_nodnic.c [deleted file]
roms/ipxe/src/drivers/infiniband/flexboot_nodnic.h [deleted file]
roms/ipxe/src/drivers/infiniband/golan.c [deleted file]
roms/ipxe/src/drivers/infiniband/golan.h [deleted file]
roms/ipxe/src/drivers/infiniband/hermon.c
roms/ipxe/src/drivers/infiniband/hermon.h
roms/ipxe/src/drivers/infiniband/linda.c
roms/ipxe/src/drivers/infiniband/linda.h
roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_cmd.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_device.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_nodnic_data_structures.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_port.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_cmd.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_device.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_port.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_memory_priv.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_pci_priv.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_utils_priv.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_bail.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_icmd.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_logging.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_memory.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_pci.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_pci_gw.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_types.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_utils.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_blink_leds/mlx_blink_leds.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_blink_leds/mlx_blink_leds.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_mtu/mlx_mtu.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_mtu/mlx_mtu.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_prm.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_ocbb/mlx_ocbb.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_ocbb/mlx_ocbb.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_reg_access/mlx_reg_access.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_reg_access/mlx_reg_access.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_wol_rol/mlx_wol_rol.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_wol_rol/mlx_wol_rol.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/src/private/uefi/mlx_logging_impl.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_icmd.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_memory.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_pci.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_pci_gw.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_utils.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_logging_priv.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_types_priv.h [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_memory_priv.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c [deleted file]
roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_utils_priv.c [deleted file]
roms/ipxe/src/drivers/infiniband/nodnic_prm.h [deleted file]
roms/ipxe/src/drivers/infiniband/nodnic_shomron_prm.h [deleted file]
roms/ipxe/src/drivers/infiniband/qib7322.c
roms/ipxe/src/drivers/infiniband/qib7322.h
roms/ipxe/src/drivers/net/3c595.c
roms/ipxe/src/drivers/net/3c5x9.c
roms/ipxe/src/drivers/net/acm.c [deleted file]
roms/ipxe/src/drivers/net/acm.h [deleted file]
roms/ipxe/src/drivers/net/ath/ath.h
roms/ipxe/src/drivers/net/ath/ath5k/ath5k.c
roms/ipxe/src/drivers/net/ath/ath5k/ath5k_phy.c
roms/ipxe/src/drivers/net/ath/ath5k/ath5k_reset.c
roms/ipxe/src/drivers/net/ath/ath9k/ar9002_initvals.h
roms/ipxe/src/drivers/net/ath/ath9k/ar9003_2p2_initvals.h
roms/ipxe/src/drivers/net/ath/ath9k/ar9340_initvals.h
roms/ipxe/src/drivers/net/ath/ath9k/ar9485_initvals.h
roms/ipxe/src/drivers/net/ath/ath9k/ath9k_eeprom.c
roms/ipxe/src/drivers/net/ath/ath9k/ath9k_init.c
roms/ipxe/src/drivers/net/ath/ath9k/ath9k_recv.c
roms/ipxe/src/drivers/net/ath/ath_main.c [new file with mode: 0644]
roms/ipxe/src/drivers/net/axge.c [deleted file]
roms/ipxe/src/drivers/net/axge.h [deleted file]
roms/ipxe/src/drivers/net/dm96xx.c
roms/ipxe/src/drivers/net/ecm.c
roms/ipxe/src/drivers/net/efi/nii.c
roms/ipxe/src/drivers/net/efi/snp.c
roms/ipxe/src/drivers/net/efi/snpnet.c
roms/ipxe/src/drivers/net/efi/snponly.c
roms/ipxe/src/drivers/net/eoib.c [deleted file]
roms/ipxe/src/drivers/net/etherfabric.c
roms/ipxe/src/drivers/net/intel.c
roms/ipxe/src/drivers/net/intel.h
roms/ipxe/src/drivers/net/ipoib.c
roms/ipxe/src/drivers/net/ncm.c
roms/ipxe/src/drivers/net/ncm.h
roms/ipxe/src/drivers/net/phantom/phantom.c
roms/ipxe/src/drivers/net/sis190.c
roms/ipxe/src/drivers/net/sis190.h
roms/ipxe/src/drivers/net/skge.c
roms/ipxe/src/drivers/net/smsc75xx.c
roms/ipxe/src/drivers/net/smsc75xx.h
roms/ipxe/src/drivers/net/smsc95xx.c [deleted file]
roms/ipxe/src/drivers/net/smsc95xx.h [deleted file]
roms/ipxe/src/drivers/net/tg3/tg3.c
roms/ipxe/src/drivers/net/tg3/tg3.h
roms/ipxe/src/drivers/net/thunderx.c [deleted file]
roms/ipxe/src/drivers/net/thunderx.h [deleted file]
roms/ipxe/src/drivers/net/thunderxcfg.h [deleted file]
roms/ipxe/src/drivers/net/virtio-net.c
roms/ipxe/src/drivers/net/virtio-net.h
roms/ipxe/src/drivers/net/vmxnet3.c
roms/ipxe/src/drivers/net/vmxnet3.h
roms/ipxe/src/drivers/usb/ehci.c
roms/ipxe/src/drivers/usb/uhci.c
roms/ipxe/src/drivers/usb/usbhub.c
roms/ipxe/src/drivers/usb/usbhub.h
roms/ipxe/src/drivers/usb/usbio.c [deleted file]
roms/ipxe/src/drivers/usb/usbio.h [deleted file]
roms/ipxe/src/drivers/usb/usbkbd.c
roms/ipxe/src/drivers/usb/usbkbd.h
roms/ipxe/src/drivers/usb/usbnet.c
roms/ipxe/src/drivers/usb/xhci.c
roms/ipxe/src/hci/commands/ibmgmt_cmd.c [deleted file]
roms/ipxe/src/hci/commands/lotest_cmd.c
roms/ipxe/src/hci/commands/ntp_cmd.c [deleted file]
roms/ipxe/src/hci/mucurses/windows.c
roms/ipxe/src/image/efi_image.c
roms/ipxe/src/image/embedded.c
roms/ipxe/src/include/compiler.h
roms/ipxe/src/include/errno.h
roms/ipxe/src/include/ipxe/asn1.h
roms/ipxe/src/include/ipxe/bitops.h
roms/ipxe/src/include/ipxe/cdc.h
roms/ipxe/src/include/ipxe/dhcp.h
roms/ipxe/src/include/ipxe/efi/AArch64/ProcessorBind.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Arm/ProcessorBind.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Base.h
roms/ipxe/src/include/ipxe/efi/Guid/SmBios.h
roms/ipxe/src/include/ipxe/efi/Ia32/ProcessorBind.h
roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi20.h [deleted file]
roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi30.h [deleted file]
roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi40.h [deleted file]
roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi50.h [deleted file]
roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi51.h [deleted file]
roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi60.h [deleted file]
roms/ipxe/src/include/ipxe/efi/IndustryStandard/Bluetooth.h [deleted file]
roms/ipxe/src/include/ipxe/efi/IndustryStandard/Pci22.h
roms/ipxe/src/include/ipxe/efi/IndustryStandard/Tpm20.h [deleted file]
roms/ipxe/src/include/ipxe/efi/IndustryStandard/UefiTcgPlatform.h
roms/ipxe/src/include/ipxe/efi/IndustryStandard/Usb.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Library/BaseLib.h
roms/ipxe/src/include/ipxe/efi/Pi/PiDxeCis.h
roms/ipxe/src/include/ipxe/efi/Pi/PiFirmwareFile.h
roms/ipxe/src/include/ipxe/efi/Pi/PiHob.h
roms/ipxe/src/include/ipxe/efi/Pi/PiMultiPhase.h
roms/ipxe/src/include/ipxe/efi/ProcessorBind.h
roms/ipxe/src/include/ipxe/efi/Protocol/AbsolutePointer.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Protocol/AppleNetBoot.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Protocol/Cpu.h [new file with mode: 0644]
roms/ipxe/src/include/ipxe/efi/Protocol/DevicePath.h
roms/ipxe/src/include/ipxe/efi/Protocol/FormBrowser2.h
roms/ipxe/src/include/ipxe/efi/Protocol/HiiConfigAccess.h
roms/ipxe/src/include/ipxe/efi/Protocol/HiiFont.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Protocol/HiiImage.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Protocol/LoadFile.h
roms/ipxe/src/include/ipxe/efi/Protocol/SerialIo.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Protocol/SimpleNetwork.h
roms/ipxe/src/include/ipxe/efi/Protocol/SimplePointer.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Protocol/SimpleTextOut.h
roms/ipxe/src/include/ipxe/efi/Protocol/TcgService.h
roms/ipxe/src/include/ipxe/efi/Protocol/UgaDraw.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Protocol/UnicodeCollation.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Protocol/Usb2HostController.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Protocol/UsbHostController.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Protocol/UsbIo.h [deleted file]
roms/ipxe/src/include/ipxe/efi/Uefi/UefiBaseType.h
roms/ipxe/src/include/ipxe/efi/Uefi/UefiInternalFormRepresentation.h
roms/ipxe/src/include/ipxe/efi/Uefi/UefiMultiPhase.h
roms/ipxe/src/include/ipxe/efi/Uefi/UefiPxe.h
roms/ipxe/src/include/ipxe/efi/Uefi/UefiSpec.h
roms/ipxe/src/include/ipxe/efi/X64/ProcessorBind.h
roms/ipxe/src/include/ipxe/efi/efi.h
roms/ipxe/src/include/ipxe/efi/efi_driver.h
roms/ipxe/src/include/ipxe/efi/efi_pxe.h [deleted file]
roms/ipxe/src/include/ipxe/efi/efi_snp.h
roms/ipxe/src/include/ipxe/efi/efi_timer.h
roms/ipxe/src/include/ipxe/efi/efi_usb.h [deleted file]
roms/ipxe/src/include/ipxe/efi/efi_utils.h
roms/ipxe/src/include/ipxe/eoib.h [deleted file]
roms/ipxe/src/include/ipxe/errfile.h
roms/ipxe/src/include/ipxe/fbcon.h
roms/ipxe/src/include/ipxe/ib_cmrc.h
roms/ipxe/src/include/ipxe/ib_mad.h
roms/ipxe/src/include/ipxe/ib_mcast.h
roms/ipxe/src/include/ipxe/ib_packet.h
roms/ipxe/src/include/ipxe/ib_service.h [deleted file]
roms/ipxe/src/include/ipxe/if_arp.h
roms/ipxe/src/include/ipxe/image.h
roms/ipxe/src/include/ipxe/infiniband.h
roms/ipxe/src/include/ipxe/io.h
roms/ipxe/src/include/ipxe/iomap.h [deleted file]
roms/ipxe/src/include/ipxe/iomap_virt.h [deleted file]
roms/ipxe/src/include/ipxe/ipoib.h
roms/ipxe/src/include/ipxe/linux_compat.h [new file with mode: 0644]
roms/ipxe/src/include/ipxe/ntp.h [deleted file]
roms/ipxe/src/include/ipxe/pci.h
roms/ipxe/src/include/ipxe/pciea.h [deleted file]
roms/ipxe/src/include/ipxe/pool.h
roms/ipxe/src/include/ipxe/pseudobit.h [deleted file]
roms/ipxe/src/include/ipxe/sanboot.h
roms/ipxe/src/include/ipxe/settings.h
roms/ipxe/src/include/ipxe/smbios.h
roms/ipxe/src/include/ipxe/tcp.h
roms/ipxe/src/include/ipxe/tcpip.h
roms/ipxe/src/include/ipxe/time.h
roms/ipxe/src/include/ipxe/uri.h
roms/ipxe/src/include/ipxe/usb.h
roms/ipxe/src/include/ipxe/usbhid.h
roms/ipxe/src/include/ipxe/virtio-pci.h
roms/ipxe/src/include/ipxe/virtio-ring.h
roms/ipxe/src/include/ipxe/xen.h
roms/ipxe/src/include/ipxe/xsigo.h [deleted file]
roms/ipxe/src/include/nic.h
roms/ipxe/src/include/stddef.h
roms/ipxe/src/include/string.h
roms/ipxe/src/include/time.h
roms/ipxe/src/include/usr/ibmgmt.h [deleted file]
roms/ipxe/src/include/usr/lotest.h
roms/ipxe/src/include/usr/ntpmgmt.h [deleted file]
roms/ipxe/src/interface/bofm/bofm.c
roms/ipxe/src/interface/efi/efi_bofm.c
roms/ipxe/src/interface/efi/efi_console.c
roms/ipxe/src/interface/efi/efi_debug.c
roms/ipxe/src/interface/efi/efi_driver.c
roms/ipxe/src/interface/efi/efi_fbcon.c [deleted file]
roms/ipxe/src/interface/efi/efi_file.c
roms/ipxe/src/interface/efi/efi_guid.c
roms/ipxe/src/interface/efi/efi_local.c [deleted file]
roms/ipxe/src/interface/efi/efi_pci.c
roms/ipxe/src/interface/efi/efi_pxe.c [deleted file]
roms/ipxe/src/interface/efi/efi_snp.c
roms/ipxe/src/interface/efi/efi_snp_hii.c
roms/ipxe/src/interface/efi/efi_timer.c
roms/ipxe/src/interface/efi/efi_usb.c [deleted file]
roms/ipxe/src/interface/efi/efi_utils.c
roms/ipxe/src/interface/efi/efi_wrap.c
roms/ipxe/src/interface/hyperv/vmbus.c
roms/ipxe/src/interface/smbios/smbios_settings.c
roms/ipxe/src/libgcc/__divdi3.c
roms/ipxe/src/libgcc/__divmoddi4.c [deleted file]
roms/ipxe/src/libgcc/__moddi3.c
roms/ipxe/src/libgcc/implicit.c [deleted file]
roms/ipxe/src/libgcc/libgcc.h
roms/ipxe/src/libgcc/memcpy.c [new file with mode: 0644]
roms/ipxe/src/net/arp.c
roms/ipxe/src/net/ethernet.c
roms/ipxe/src/net/fakedhcp.c
roms/ipxe/src/net/infiniband.c
roms/ipxe/src/net/infiniband/ib_cm.c
roms/ipxe/src/net/infiniband/ib_cmrc.c
roms/ipxe/src/net/infiniband/ib_mcast.c
roms/ipxe/src/net/infiniband/ib_mi.c
roms/ipxe/src/net/infiniband/ib_packet.c
roms/ipxe/src/net/infiniband/ib_pathrec.c
roms/ipxe/src/net/infiniband/ib_service.c [deleted file]
roms/ipxe/src/net/infiniband/ib_sma.c
roms/ipxe/src/net/infiniband/ib_smc.c
roms/ipxe/src/net/infiniband/ib_srp.c
roms/ipxe/src/net/infiniband/xsigo.c [deleted file]
roms/ipxe/src/net/ipv4.c
roms/ipxe/src/net/ipv6.c
roms/ipxe/src/net/netdev_settings.c
roms/ipxe/src/net/netdevice.c
roms/ipxe/src/net/peerblk.c
roms/ipxe/src/net/stp.c
roms/ipxe/src/net/tcp.c
roms/ipxe/src/net/tcp/httpconn.c
roms/ipxe/src/net/tcp/httpcore.c
roms/ipxe/src/net/tcpip.c
roms/ipxe/src/net/tls.c
roms/ipxe/src/net/udp.c
roms/ipxe/src/net/udp/dhcp.c
roms/ipxe/src/net/udp/ntp.c [deleted file]
roms/ipxe/src/net/udp/slam.c
roms/ipxe/src/net/udp/tftp.c
roms/ipxe/src/net/validator.c
roms/ipxe/src/tests/bitops_test.c [deleted file]
roms/ipxe/src/tests/comboot/shuffle-simple.asm [moved from roms/ipxe/src/arch/x86/tests/comboot/shuffle-simple.asm with 99% similarity]
roms/ipxe/src/tests/comboot/version.asm [moved from roms/ipxe/src/arch/x86/tests/comboot/version.asm with 100% similarity]
roms/ipxe/src/tests/gdbstub_test.S [moved from roms/ipxe/src/arch/i386/tests/gdbstub_test.S with 100% similarity]
roms/ipxe/src/tests/gdbstub_test.gdb [moved from roms/ipxe/src/arch/i386/tests/gdbstub_test.gdb with 100% similarity]
roms/ipxe/src/tests/iobuf_test.c [deleted file]
roms/ipxe/src/tests/rsa_test.c
roms/ipxe/src/tests/settings_test.c
roms/ipxe/src/tests/tcpip_test.c
roms/ipxe/src/tests/tests.c
roms/ipxe/src/tests/uri_test.c
roms/ipxe/src/tests/vsprintf_test.c
roms/ipxe/src/usr/autoboot.c
roms/ipxe/src/usr/ibmgmt.c [deleted file]
roms/ipxe/src/usr/ifmgmt.c
roms/ipxe/src/usr/lotest.c
roms/ipxe/src/usr/ntpmgmt.c [deleted file]
roms/ipxe/src/util/efifatbin.c
roms/ipxe/src/util/efirom.c
roms/ipxe/src/util/elf2efi.c
roms/ipxe/src/util/genefidsk [deleted file]
roms/ipxe/src/util/geniso
roms/ipxe/src/util/parserom.pl
roms/ipxe/src/util/zbin.c
roms/openbios/arch/amd64/context.c
roms/openbios/arch/ppc/build.xml
roms/openbios/arch/ppc/qemu/context.c [deleted file]
roms/openbios/arch/ppc/qemu/context.h [deleted file]
roms/openbios/arch/ppc/qemu/init.c
roms/openbios/arch/ppc/qemu/ldscript
roms/openbios/arch/ppc/qemu/ofmem.c
roms/openbios/arch/ppc/qemu/start.S
roms/openbios/arch/ppc/qemu/switch.S [deleted file]
roms/openbios/arch/sparc32/openbios.c
roms/openbios/arch/sparc64/context.c
roms/openbios/forth/bootstrap/interpreter.fs
roms/openbios/forth/lib/build.xml
roms/openbios/forth/lib/rstack.fs [deleted file]
roms/openbios/include/arch/ppc/io.h
roms/seabios/.version
roms/seabios/scripts/layoutrom.py
roms/seabios/src/fw/paravirt.c
roms/seabios/src/fw/pciinit.c
roms/seabios/src/fw/smp.c
rules.mak
scripts/analyze-inclusions [deleted file]
scripts/checkpatch.pl
scripts/clean-header-guards.pl [deleted file]
scripts/clean-includes
scripts/cocci-macro-file.h
scripts/coccinelle/err-bad-newline.cocci [deleted file]
scripts/coccinelle/error_propagate_null.cocci [deleted file]
scripts/coccinelle/overflow_muldiv64.cocci [deleted file]
scripts/coccinelle/remove_local_err.cocci [deleted file]
scripts/coccinelle/remove_muldiv64.cocci [deleted file]
scripts/coccinelle/return_directly.cocci [deleted file]
scripts/coccinelle/round.cocci [deleted file]
scripts/coccinelle/simplify_muldiv64.cocci [deleted file]
scripts/coccinelle/swap_muldiv64.cocci [deleted file]
scripts/create_config
scripts/dump-guest-memory.py
scripts/feature_to_c.sh
scripts/kvm/kvm_stat [new file with mode: 0755]
scripts/kvm/kvm_stat.texi [new file with mode: 0644]
scripts/make_device_config.sh
scripts/qapi-commands.py
scripts/qapi-event.py
scripts/qapi-introspect.py
scripts/qapi-types.py
scripts/qapi-visit.py
scripts/qapi.py
scripts/qemu-binfmt-conf.sh [changed mode: 0755->0644]
scripts/qemu.py [deleted file]
scripts/qmp/__init__.py [deleted file]
scripts/qmp/qmp.py
scripts/qtest.py
scripts/signrom.py
scripts/tracetool/backend/dtrace.py
scripts/tracetool/backend/ftrace.py
scripts/tracetool/backend/log.py
scripts/tracetool/backend/simple.py
scripts/tracetool/backend/ust.py
scripts/tracetool/format/events_c.py
scripts/tracetool/format/events_h.py
scripts/tracetool/format/h.py
scripts/tracetool/format/tcg_helper_c.py
scripts/update-linux-headers.sh
scripts/vmstate-static-checker.py
slirp/Makefile.objs
slirp/bootp.c
slirp/bootp.h
slirp/cksum.c
slirp/dhcpv6.c [deleted file]
slirp/dhcpv6.h [deleted file]
slirp/dnssearch.c
slirp/if.c
slirp/if.h
slirp/ip.h
slirp/ip6.h
slirp/ip6_icmp.c
slirp/ip6_icmp.h
slirp/ip_icmp.h
slirp/ip_input.c
slirp/ip_output.c
slirp/libslirp.h
slirp/main.h
slirp/mbuf.c
slirp/mbuf.h
slirp/misc.c
slirp/misc.h
slirp/sbuf.c
slirp/sbuf.h
slirp/slirp.c
slirp/slirp.h
slirp/slirp_config.h
slirp/socket.c
slirp/socket.h
slirp/tcp.h
slirp/tcp_input.c
slirp/tcp_output.c
slirp/tcp_subr.c
slirp/tcp_timer.c
slirp/tcp_timer.h
slirp/tcp_var.h
slirp/tcpip.h
slirp/tftp.c
slirp/tftp.h
slirp/udp.c
slirp/udp.h
slirp/udp6.c
softmmu_template.h
stubs/Makefile.objs
stubs/cpu-get-icount.c
stubs/ipmi.c [deleted file]
stubs/pc_madt_cpu_entry.c [deleted file]
stubs/slirp.c
stubs/smbios_type_38.c [deleted file]
stubs/trace-control.c [deleted file]
target-alpha/cpu-qom.h
target-alpha/cpu.c
target-alpha/cpu.h
target-alpha/fpu_helper.c
target-alpha/gdbstub.c
target-alpha/helper.c
target-alpha/int_helper.c
target-alpha/machine.c
target-alpha/mem_helper.c
target-alpha/sys_helper.c
target-alpha/translate.c
target-alpha/vax_helper.c
target-arm/Makefile.objs
target-arm/arm-powerctl.c [deleted file]
target-arm/arm-powerctl.h [deleted file]
target-arm/arm-semi.c
target-arm/arm_ldst.h
target-arm/cpu-qom.h
target-arm/cpu.c
target-arm/cpu.h
target-arm/gdbstub.c
target-arm/gdbstub64.c
target-arm/helper-a64.c
target-arm/helper.c
target-arm/internals.h
target-arm/kvm-stub.c
target-arm/kvm.c
target-arm/kvm32.c
target-arm/kvm64.c
target-arm/kvm_arm.h
target-arm/machine.c
target-arm/monitor.c
target-arm/neon_helper.c
target-arm/op_helper.c
target-arm/psci.c
target-arm/translate-a64.c
target-arm/translate.c
target-arm/translate.h
target-cris/cpu-qom.h
target-cris/cpu.c
target-cris/cpu.h
target-cris/crisv32-decode.h
target-cris/gdbstub.c
target-cris/helper.c
target-cris/machine.c
target-cris/mmu.c
target-cris/op_helper.c
target-cris/translate.c
target-cris/translate_v10.c
target-i386/bpt_helper.c
target-i386/cpu-qom.h
target-i386/cpu.c
target-i386/cpu.h
target-i386/excp_helper.c
target-i386/fpu_helper.c
target-i386/gdbstub.c
target-i386/helper.c
target-i386/hyperv.h
target-i386/int_helper.c
target-i386/kvm-stub.c
target-i386/kvm.c
target-i386/machine.c
target-i386/mem_helper.c
target-i386/misc_helper.c
target-i386/mpx_helper.c
target-i386/seg_helper.c
target-i386/svm.h
target-i386/svm_helper.c
target-i386/trace-events [deleted file]
target-i386/translate.c
target-lm32/cpu-qom.h
target-lm32/cpu.c
target-lm32/cpu.h
target-lm32/gdbstub.c
target-lm32/helper.c
target-lm32/machine.c
target-lm32/op_helper.c
target-lm32/translate.c
target-m68k/cpu-qom.h
target-m68k/cpu.c
target-m68k/cpu.h
target-m68k/gdbstub.c
target-m68k/helper.c
target-m68k/m68k-semi.c
target-m68k/op_helper.c
target-m68k/translate.c
target-microblaze/cpu-qom.h
target-microblaze/cpu.c
target-microblaze/cpu.h
target-microblaze/gdbstub.c
target-microblaze/helper.c
target-microblaze/mmu.c
target-microblaze/op_helper.c
target-microblaze/translate.c
target-mips/cpu-qom.h
target-mips/cpu.c
target-mips/cpu.h
target-mips/gdbstub.c
target-mips/helper.c
target-mips/helper.h
target-mips/kvm.c
target-mips/kvm_mips.h
target-mips/machine.c
target-mips/mips-defs.h
target-mips/mips-semi.c
target-mips/msa_helper.c
target-mips/op_helper.c
target-mips/translate.c
target-mips/translate_init.c
target-moxie/cpu.c
target-moxie/cpu.h
target-moxie/helper.c
target-moxie/machine.c
target-moxie/mmu.h
target-moxie/translate.c
target-openrisc/cpu.c
target-openrisc/cpu.h
target-openrisc/exception.c
target-openrisc/exception.h
target-openrisc/gdbstub.c
target-openrisc/interrupt.c
target-openrisc/interrupt_helper.c
target-openrisc/machine.c
target-openrisc/mmu.c
target-openrisc/mmu_helper.c
target-openrisc/sys_helper.c
target-openrisc/translate.c
target-ppc/cpu-qom.h
target-ppc/cpu.h
target-ppc/excp_helper.c
target-ppc/fpu_helper.c
target-ppc/gdbstub.c
target-ppc/helper.h
target-ppc/helper_regs.h
target-ppc/int_helper.c
target-ppc/kvm-stub.c
target-ppc/kvm.c
target-ppc/kvm_ppc.h
target-ppc/machine.c
target-ppc/mem_helper.c
target-ppc/misc_helper.c
target-ppc/mmu-hash32.c
target-ppc/mmu-hash32.h
target-ppc/mmu-hash64.c
target-ppc/mmu-hash64.h
target-ppc/mmu_helper.c
target-ppc/timebase_helper.c
target-ppc/trace-events [deleted file]
target-ppc/translate.c
target-ppc/translate_init.c
target-s390x/cc_helper.c
target-s390x/cpu-qom.h
target-s390x/cpu.c
target-s390x/cpu.h
target-s390x/fpu_helper.c
target-s390x/gdbstub.c
target-s390x/helper.c
target-s390x/helper.h
target-s390x/int_helper.c
target-s390x/interrupt.c
target-s390x/ioinst.c
target-s390x/ioinst.h [moved from include/hw/s390x/ioinst.h with 87% similarity]
target-s390x/kvm.c
target-s390x/machine.c
target-s390x/mem_helper.c
target-s390x/misc_helper.c
target-s390x/trace-events [deleted file]
target-s390x/translate.c
target-sh4/cpu-qom.h
target-sh4/cpu.c
target-sh4/cpu.h
target-sh4/gdbstub.c
target-sh4/helper.c
target-sh4/op_helper.c
target-sh4/translate.c
target-sparc/asi.h [deleted file]
target-sparc/cc_helper.c
target-sparc/cpu-qom.h
target-sparc/cpu.c
target-sparc/cpu.h
target-sparc/fop_helper.c
target-sparc/gdbstub.c
target-sparc/helper.c
target-sparc/helper.h
target-sparc/ldst_helper.c
target-sparc/machine.c
target-sparc/mmu_helper.c
target-sparc/trace-events [deleted file]
target-sparc/translate.c
target-tilegx/cpu.c
target-tilegx/cpu.h
target-tilegx/helper.c
target-tilegx/opcode_tilegx.h
target-tilegx/translate.c
target-tricore/cpu-qom.h
target-tricore/cpu.c
target-tricore/cpu.h
target-tricore/helper.c
target-tricore/op_helper.c
target-tricore/translate.c
target-tricore/tricore-defs.h
target-unicore32/cpu-qom.h
target-unicore32/cpu.c
target-unicore32/cpu.h
target-unicore32/helper.c
target-unicore32/op_helper.c
target-unicore32/softmmu.c
target-unicore32/translate.c
target-xtensa/core-dc232b/core-isa.h
target-xtensa/core-dc233c/core-isa.h
target-xtensa/core-fsf/core-isa.h
target-xtensa/cpu-qom.h
target-xtensa/cpu.c
target-xtensa/cpu.h
target-xtensa/gdbstub.c
target-xtensa/helper.c
target-xtensa/op_helper.c
target-xtensa/translate.c
tcg/aarch64/tcg-target.h
tcg/aarch64/tcg-target.inc.c
tcg/arm/tcg-target.h
tcg/arm/tcg-target.inc.c
tcg/i386/tcg-target.h
tcg/i386/tcg-target.inc.c
tcg/ia64/tcg-target.h
tcg/ia64/tcg-target.inc.c
tcg/mips/tcg-target.h
tcg/mips/tcg-target.inc.c
tcg/optimize.c
tcg/ppc/tcg-target.h
tcg/ppc/tcg-target.inc.c
tcg/s390/tcg-target.h
tcg/s390/tcg-target.inc.c
tcg/sparc/tcg-target.h
tcg/sparc/tcg-target.inc.c
tcg/tcg-common.c
tcg/tcg-op.c
tcg/tcg-op.h
tcg/tcg.c
tcg/tcg.h
tcg/tci/tcg-target.h
tcg/tci/tcg-target.inc.c
tci.c
tests/.gitignore
tests/Makefile [moved from tests/Makefile.include with 91% similarity]
tests/ac97-test.c
tests/acpi-test-data/pc/APIC.cphp [deleted file]
tests/acpi-test-data/pc/DSDT
tests/acpi-test-data/pc/DSDT.bridge
tests/acpi-test-data/pc/DSDT.cphp [deleted file]
tests/acpi-test-data/pc/DSDT.ipmikcs [deleted file]
tests/acpi-test-data/q35/APIC.cphp [deleted file]
tests/acpi-test-data/q35/DSDT
tests/acpi-test-data/q35/DSDT.bridge
tests/acpi-test-data/q35/DSDT.cphp [deleted file]
tests/acpi-test-data/q35/DSDT.ipmibt [deleted file]
tests/ahci-test.c
tests/bios-tables-test.c
tests/boot-order-test.c
tests/boot-sector.h
tests/check-qdict.c
tests/check-qfloat.c
tests/check-qint.c
tests/check-qjson.c
tests/check-qlist.c
tests/check-qnull.c [deleted file]
tests/check-qom-interface.c
tests/check-qom-proplist.c
tests/check-qstring.c
tests/data/test-qga-config [deleted file]
tests/device-introspect-test.c
tests/display-vga-test.c
tests/docker/Makefile.include [deleted file]
tests/docker/common.rc [deleted file]
tests/docker/docker.py [deleted file]
tests/docker/dockerfiles/centos6.docker [deleted file]
tests/docker/dockerfiles/debian-bootstrap.docker [deleted file]
tests/docker/dockerfiles/debian-bootstrap.pre [deleted file]
tests/docker/dockerfiles/fedora.docker [deleted file]
tests/docker/dockerfiles/ubuntu.docker [deleted file]
tests/docker/run [deleted file]
tests/docker/test-clang [deleted file]
tests/docker/test-full [deleted file]
tests/docker/test-mingw [deleted file]
tests/docker/test-quick [deleted file]
tests/docker/travis [deleted file]
tests/docker/travis.py [deleted file]
tests/drive_del-test.c
tests/ds1338-test.c
tests/e1000-test.c
tests/e1000e-test.c [deleted file]
tests/eepro100-test.c
tests/endianness-test.c
tests/es1370-test.c
tests/fdc-test.c
tests/fw_cfg-test.c
tests/hd-geo-test.c
tests/i440fx-test.c
tests/i82801b11-test.c
tests/ide-test.c
tests/intel-hda-test.c
tests/ioh3420-test.c
tests/ipmi-bt-test.c
tests/ipmi-kcs-test.c
tests/ipoctal232-test.c
tests/ivshmem-test.c
tests/libqos/ahci.c
tests/libqos/ahci.h
tests/libqos/fw_cfg.c
tests/libqos/i2c-imx.c
tests/libqos/i2c-omap.c
tests/libqos/libqos-pc.h
tests/libqos/libqos.c
tests/libqos/libqos.h
tests/libqos/malloc-generic.c
tests/libqos/malloc-pc.c
tests/libqos/malloc.c
tests/libqos/pci-pc.c
tests/libqos/pci.c
tests/libqos/usb.c
tests/libqos/virtio-mmio.c
tests/libqos/virtio-pci.c
tests/libqos/virtio-pci.h
tests/libqos/virtio.c
tests/libqos/virtio.h
tests/libqtest.c
tests/m48t59-test.c
tests/migration/.gitignore [deleted file]
tests/migration/guestperf-batch.py [deleted file]
tests/migration/guestperf-plot.py [deleted file]
tests/migration/guestperf.py [deleted file]
tests/migration/guestperf/__init__.py [deleted file]
tests/migration/guestperf/comparison.py [deleted file]
tests/migration/guestperf/engine.py [deleted file]
tests/migration/guestperf/hardware.py [deleted file]
tests/migration/guestperf/plot.py [deleted file]
tests/migration/guestperf/progress.py [deleted file]
tests/migration/guestperf/report.py [deleted file]
tests/migration/guestperf/scenario.py [deleted file]
tests/migration/guestperf/shell.py [deleted file]
tests/migration/guestperf/timings.py [deleted file]
tests/migration/stress.c [deleted file]
tests/ne2000-test.c
tests/nvme-test.c
tests/pc-cpu-test.c
tests/pcnet-test.c
tests/postcopy-test.c [deleted file]
tests/prom-env-test.c [deleted file]
tests/pvpanic-test.c
tests/pxe-test.c
tests/q35-test.c
tests/qapi-schema/args-bad-boxed.err [deleted file]
tests/qapi-schema/args-bad-boxed.exit [deleted file]
tests/qapi-schema/args-bad-boxed.json [deleted file]
tests/qapi-schema/args-bad-boxed.out [deleted file]
tests/qapi-schema/args-boxed-anon.err [deleted file]
tests/qapi-schema/args-boxed-anon.exit [deleted file]
tests/qapi-schema/args-boxed-anon.json [deleted file]
tests/qapi-schema/args-boxed-anon.out [deleted file]
tests/qapi-schema/args-boxed-empty.err [deleted file]
tests/qapi-schema/args-boxed-empty.exit [deleted file]
tests/qapi-schema/args-boxed-empty.json [deleted file]
tests/qapi-schema/args-boxed-empty.out [deleted file]
tests/qapi-schema/args-boxed-string.err [deleted file]
tests/qapi-schema/args-boxed-string.exit [deleted file]
tests/qapi-schema/args-boxed-string.json [deleted file]
tests/qapi-schema/args-boxed-string.out [deleted file]
tests/qapi-schema/args-union.err
tests/qapi-schema/args-union.json
tests/qapi-schema/event-boxed-empty.err [deleted file]
tests/qapi-schema/event-boxed-empty.exit [deleted file]
tests/qapi-schema/event-boxed-empty.json [deleted file]
tests/qapi-schema/event-boxed-empty.out [deleted file]
tests/qapi-schema/event-case.out
tests/qapi-schema/flat-union-incomplete-branch.err [deleted file]
tests/qapi-schema/flat-union-incomplete-branch.exit [deleted file]
tests/qapi-schema/flat-union-incomplete-branch.json [deleted file]
tests/qapi-schema/flat-union-incomplete-branch.out [deleted file]
tests/qapi-schema/ident-with-escape.out
tests/qapi-schema/indented-expr.out
tests/qapi-schema/qapi-schema-test.json
tests/qapi-schema/qapi-schema-test.out
tests/qapi-schema/test-qapi.py
tests/qemu-iotests/004
tests/qemu-iotests/012
tests/qemu-iotests/023.out
tests/qemu-iotests/026.out
tests/qemu-iotests/026.out.nocache
tests/qemu-iotests/034
tests/qemu-iotests/039.out
tests/qemu-iotests/041
tests/qemu-iotests/048
tests/qemu-iotests/048.out
tests/qemu-iotests/052
tests/qemu-iotests/052.out
tests/qemu-iotests/061.out
tests/qemu-iotests/071.out
tests/qemu-iotests/077
tests/qemu-iotests/077.out
tests/qemu-iotests/083
tests/qemu-iotests/087.out
tests/qemu-iotests/089.out
tests/qemu-iotests/095
tests/qemu-iotests/096
tests/qemu-iotests/100 [new file with mode: 0755]
tests/qemu-iotests/100.out [new file with mode: 0644]
tests/qemu-iotests/109
tests/qemu-iotests/109.out
tests/qemu-iotests/136
tests/qemu-iotests/136.out
tests/qemu-iotests/137.out
tests/qemu-iotests/141.out
tests/qemu-iotests/144.out
tests/qemu-iotests/149
tests/qemu-iotests/149.out
tests/qemu-iotests/154 [deleted file]
tests/qemu-iotests/154.out [deleted file]
tests/qemu-iotests/155 [deleted file]
tests/qemu-iotests/155.out [deleted file]
tests/qemu-iotests/156 [deleted file]
tests/qemu-iotests/156.out [deleted file]
tests/qemu-iotests/157 [deleted file]
tests/qemu-iotests/157.out [deleted file]
tests/qemu-iotests/162 [deleted file]
tests/qemu-iotests/162.out [deleted file]
tests/qemu-iotests/README
tests/qemu-iotests/common
tests/qemu-iotests/common.config
tests/qemu-iotests/common.filter
tests/qemu-iotests/common.rc
tests/qemu-iotests/group
tests/qemu-iotests/iotests.py
tests/qht-bench.c [deleted file]
tests/qom-test.c
tests/rcutorture.c
tests/rtc-test.c
tests/rtl8139-test.c
tests/spapr-phb-test.c
tests/tcg/xtensa/linker.ld.S
tests/tco-test.c
tests/test-aio.c
tests/test-base64.c
tests/test-bitops.c
tests/test-blockjob-txn.c
tests/test-blockjob.c [deleted file]
tests/test-clone-visitor.c [deleted file]
tests/test-coroutine.c
tests/test-crypto-cipher.c
tests/test-crypto-hash.c
tests/test-crypto-secret.c
tests/test-crypto-xts.c
tests/test-cutils.c
tests/test-filter-mirror.c
tests/test-filter-redirector.c
tests/test-hbitmap.c
tests/test-int128.c
tests/test-io-channel-socket.c
tests/test-io-task.c
tests/test-iov.c
tests/test-logging.c
tests/test-mul64.c
tests/test-netfilter.c
tests/test-opts-visitor.c
tests/test-qdev-global-props.c
tests/test-qdist.c [deleted file]
tests/test-qemu-opts.c
tests/test-qga.c
tests/test-qht-par.c [deleted file]
tests/test-qht.c [deleted file]
tests/test-qmp-commands.c
tests/test-qmp-event.c
tests/test-qmp-input-strict.c
tests/test-qmp-input-visitor.c
tests/test-qmp-output-visitor.c
tests/test-rcu-list.c
tests/test-rfifolock.c
tests/test-string-input-visitor.c
tests/test-string-output-visitor.c
tests/test-thread-pool.c
tests/test-throttle.c
tests/test-timed-average.c
tests/test-visitor-serialization.c
tests/test-vmstate.c
tests/test-write-threshold.c
tests/test-x86-cpuid.c
tests/tmp105-test.c
tests/tpci200-test.c
tests/usb-hcd-ehci-test.c
tests/usb-hcd-ohci-test.c
tests/usb-hcd-uhci-test.c
tests/usb-hcd-xhci-test.c
tests/vhost-user-bridge.c
tests/vhost-user-test.c
tests/virtio-9p-test.c
tests/virtio-balloon-test.c
tests/virtio-blk-test.c
tests/virtio-console-test.c
tests/virtio-net-test.c
tests/virtio-rng-test.c
tests/virtio-scsi-test.c
tests/virtio-serial-test.c
tests/vmxnet3-test.c
tests/wdt_ib700-test.c
thread-pool.c
thunk.c
trace-events
trace/Makefile.objs
trace/control-internal.h
trace/control-target.c [deleted file]
trace/control.c
trace/control.h
trace/event-internal.h
trace/ftrace.h
trace/mem-internal.h [deleted file]
trace/mem.h [deleted file]
trace/qmp.c
translate-all.c
translate-all.h
translate-common.c
ui/console-gl.c
ui/console.c
ui/curses_keys.h
ui/cursor.c
ui/egl-helpers.c
ui/gtk-egl.c
ui/gtk-gl-area.c
ui/gtk.c
ui/input-linux.c
ui/keymaps.h
ui/qemu-pixman.c
ui/sdl2-2d.c
ui/sdl2-gl.c
ui/sdl_zoom.c
ui/sdl_zoom.h
ui/shader.c
ui/spice-display.c
ui/trace-events [deleted file]
ui/vnc-auth-sasl.h
ui/vnc-auth-vencrypt.h
ui/vnc-enc-tight.c
ui/vnc-enc-tight.h
ui/vnc-enc-zrle.h
ui/vnc-enc-zywrle.h
ui/vnc-palette.c
ui/vnc-ws.c
ui/vnc-ws.h
ui/vnc.c
ui/vnc.h
user-exec.c
util/Makefile.objs
util/acl.c
util/buffer.c
util/coroutine-gthread.c
util/cutils.c
util/error.c
util/hbitmap.c
util/iov.c
util/log.c
util/memfd.c
util/mmap-alloc.c
util/module.c
util/osdep.c
util/oslib-posix.c
util/oslib-win32.c
util/qdist.c [deleted file]
util/qemu-coroutine-io.c
util/qemu-coroutine-lock.c
util/qemu-coroutine-sleep.c
util/qemu-coroutine.c
util/qemu-sockets.c
util/qht.c [deleted file]
util/range.c [deleted file]
util/rfifolock.c
util/throttle.c
util/trace-events [deleted file]
util/uri.c
vl.c
xen-hvm.c
xen-mapcache.c

index 88ec249..88a80ff 100644 (file)
@@ -5,7 +5,6 @@
 /config-target.*
 /config.status
 /config-temp
-/trace-events-all
 /trace/generated-tracers.h
 /trace/generated-tracers.c
 /trace/generated-tracers-dtrace.h
 /pc-bios/optionrom/linuxboot.bin
 /pc-bios/optionrom/linuxboot.raw
 /pc-bios/optionrom/linuxboot.img
-/pc-bios/optionrom/linuxboot_dma.asm
-/pc-bios/optionrom/linuxboot_dma.bin
-/pc-bios/optionrom/linuxboot_dma.raw
-/pc-bios/optionrom/linuxboot_dma.img
 /pc-bios/optionrom/multiboot.asm
 /pc-bios/optionrom/multiboot.bin
 /pc-bios/optionrom/multiboot.raw
 cscope.*
 tags
 TAGS
-docker-src.*
 *~
index f30b10e..50ac17f 100644 (file)
@@ -17,7 +17,6 @@ addons:
       - libgtk-3-dev
       - libiscsi-dev
       - liblttng-ust-dev
-      - libnfs-dev
       - libncurses5-dev
       - libnss3-dev
       - libpixman-1-dev
@@ -34,13 +33,10 @@ addons:
       - sparse
       - uuid-dev
 
-# The channel name "irc.oftc.net#qemu" is encrypted against qemu/qemu
-# to prevent IRC notifications from forks. This was created using:
-# $ travis encrypt -r "qemu/qemu" "irc.oftc.net#qemu"
 notifications:
   irc:
     channels:
-      - secure: "F7GDRgjuOo5IUyRLqSkmDL7kvdU4UcH3Lm/W2db2JnDHTGCqgEdaYEYKciyCLZ57vOTsTsOgesN8iUT7hNHBd1KWKjZe9KDTZWppWRYVwAwQMzVeSOsbbU4tRoJ6Pp+3qhH1Z0eGYR9ZgKYAoTumDFgSAYRp4IscKS8jkoedOqM="
+      - "irc.oftc.net#qemu"
     on_success: change
     on_failure: always
 env:
@@ -67,6 +63,9 @@ script:
   - make -j3 && ${TEST_CMD}
 matrix:
   include:
+    # Sparse is GCC only
+    - env: CONFIG="--enable-sparse"
+      compiler: gcc
     # gprof/gcov are GCC features
     - env: CONFIG="--enable-gprof --enable-gcov --disable-pie"
       compiler: gcc
@@ -89,13 +88,3 @@ matrix:
     - env: CONFIG=""
       os: osx
       compiler: clang
-    - env: CONFIG=""
-      sudo: required
-      addons:
-      dist: trusty
-      compiler: gcc
-      before_install:
-        - sudo apt-get update -qq
-        - sudo apt-get build-dep -qq qemu
-        - wget -O - http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
-        - git submodule update --init --recursive
index e7fde15..3c6978f 100644 (file)
@@ -31,11 +31,7 @@ Do not leave whitespace dangling off the ends of lines.
 
 2. Line width
 
-Lines should be 80 characters; try not to make them longer.
-
-Sometimes it is hard to do, especially when dealing with QEMU subsystems
-that use long function or symbol names.  Even in that case, do not make
-lines much longer than 80 characters.
+Lines are 80 characters; not longer.
 
 Rationale:
  - Some people like to tile their 24" screens with a 6x4 matrix of 80x24
@@ -43,8 +39,6 @@ Rationale:
    let them keep doing it.
  - Code and especially patches is much more readable if limited to a sane
    line length.  Eighty is traditional.
- - The four-space indentation makes the most common excuse ("But look
-   at all that white space on the left!") moot.
  - It is the QEMU coding style.
 
 3. Naming
diff --git a/HACKING b/HACKING
index 20a9101..058aa8f 100644 (file)
--- a/HACKING
+++ b/HACKING
@@ -158,10 +158,6 @@ painful. These are:
  * you may assume that right shift of a signed integer duplicates
    the sign bit (ie it is an arithmetic shift, not a logical shift)
 
-In addition, QEMU assumes that the compiler does not use the latitude
-given in C99 and C11 to treat aspects of signed '<<' as undefined, as
-documented in the GNU Compiler Collection manual starting at version 4.0.
-
 7. Error handling and reporting
 
 7.1 Reporting errors to the human user
index b6fb84e..81e7fac 100644 (file)
@@ -165,7 +165,6 @@ F: hw/openrisc/
 F: tests/tcg/openrisc/
 
 PowerPC
-M: David Gibson <david@gibson.dropbear.id.au>
 M: Alexander Graf <agraf@suse.de>
 L: qemu-ppc@nongnu.org
 S: Maintained
@@ -189,8 +188,8 @@ F: hw/sh4/
 F: disas/sh4.c
 
 SPARC
+M: Blue Swirl <blauwirbel@gmail.com>
 M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
-M: Artyom Tarasenko <atar4qemu@gmail.com>
 S: Maintained
 F: target-sparc/
 F: hw/sparc/
@@ -449,23 +448,23 @@ S: Maintained
 F: hw/*/versatile*
 
 Xilinx Zynq
-M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
 M: Alistair Francis <alistair.francis@xilinx.com>
+M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
 L: qemu-arm@nongnu.org
 S: Maintained
-F: hw/*/xilinx_*
-F: hw/*/cadence_*
+F: hw/arm/xilinx_zynq.c
 F: hw/misc/zynq_slcr.c
-F: include/hw/xilinx.h
-X: hw/ssi/xilinx_*
+F: hw/*/cadence_*
+F: hw/ssi/xilinx_spips.c
 
 Xilinx ZynqMP
 M: Alistair Francis <alistair.francis@xilinx.com>
-M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
+M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
 L: qemu-arm@nongnu.org
 S: Maintained
-F: hw/*/xlnx*.c
-F: include/hw/*/xlnx*.c
+F: hw/arm/xlnx-zynqmp.c
+F: hw/arm/xlnx-ep108.c
+F: include/hw/arm/xlnx-zynqmp.h
 
 ARM ACPI Subsystem
 M: Shannon Zhao <zhaoshenglong@huawei.com>
@@ -598,7 +597,7 @@ F: hw/pci-host/grackle.c
 F: hw/misc/macio/
 
 PReP
-L: qemu-devel@nongnu.org
+M: Andreas Färber <andreas.faerber@web.de>
 L: qemu-ppc@nongnu.org
 S: Odd Fixes
 F: hw/ppc/prep.c
@@ -780,7 +779,6 @@ F: hw/ipack/
 
 PCI
 M: Michael S. Tsirkin <mst@redhat.com>
-M: Marcel Apfelbaum <marcel@redhat.com>
 S: Supported
 F: include/hw/pci/*
 F: hw/misc/pci-testdev.c
@@ -888,13 +886,12 @@ F: include/hw/virtio/
 
 virtio-9p
 M: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
-M: Greg Kurz <groug@kaod.org>
+M: Greg Kurz <gkurz@linux.vnet.ibm.com>
 S: Supported
 F: hw/9pfs/
 F: fsdev/
 F: tests/virtio-9p-test.c
 T: git git://github.com/kvaneesh/QEMU.git
-T: git git://github.com/gkurz/qemu.git 9p-next
 
 virtio-blk
 M: Stefan Hajnoczi <stefanha@redhat.com>
@@ -948,13 +945,13 @@ S: Supported
 F: hw/scsi/megasas.c
 F: hw/scsi/mfi.h
 
-Network packet abstractions
-M: Dmitry Fleytman <dmitry@daynix.com>
+Xilinx EDK
+M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
+M: Alistair Francis <alistair.francis@xilinx.com>
+M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
 S: Maintained
-F: include/net/eth.h
-F: net/eth.c
-F: hw/net/net_rx_pkt*
-F: hw/net/net_tx_pkt*
+F: hw/*/xilinx_*
+F: include/hw/xilinx.h
 
 Vmware
 M: Dmitry Fleytman <dmitry@daynix.com>
@@ -963,6 +960,7 @@ F: hw/net/vmxnet*
 F: hw/scsi/vmw_pvscsi*
 
 Rocker
+M: Scott Feldman <sfeldma@gmail.com>
 M: Jiri Pirko <jiri@resnulli.us>
 S: Maintained
 F: hw/net/rocker/
@@ -974,16 +972,6 @@ F: hw/acpi/nvdimm.c
 F: hw/mem/nvdimm.c
 F: include/hw/mem/nvdimm.h
 
-e1000x
-M: Dmitry Fleytman <dmitry@daynix.com>
-S: Maintained
-F: hw/net/e1000x*
-
-e1000e
-M: Dmitry Fleytman <dmitry@daynix.com>
-S: Maintained
-F: hw/net/e1000e*
-
 Subsystems
 ----------
 Audio
@@ -1018,7 +1006,6 @@ F: async.c
 F: aio-*.c
 F: block/io.c
 F: migration/block*
-F: include/block/aio.h
 T: git git://github.com/stefanha/qemu.git block
 
 Block Jobs
@@ -1059,7 +1046,7 @@ S: Supported
 F: scripts/coverity-model.c
 
 CPU
-L: qemu-devel@nongnu.org
+M: Andreas Färber <afaerber@suse.de>
 S: Supported
 F: qom/cpu.c
 F: include/qom/cpu.h
@@ -1118,6 +1105,7 @@ F: ui/
 F: include/ui/
 
 Cocoa graphics
+M: Andreas Färber <andreas.faerber@web.de>
 M: Peter Maydell <peter.maydell@linaro.org>
 S: Odd Fixes
 F: ui/cocoa.m
@@ -1169,13 +1157,6 @@ F: numa.c
 F: include/sysemu/numa.h
 T: git git://github.com/ehabkost/qemu.git numa
 
-Host Memory Backends
-M: Eduardo Habkost <ehabkost@redhat.com>
-M: Igor Mammedov <imammedo@redhat.com>
-S: Maintained
-F: backends/hostmem*.c
-F: include/sysemu/hostmem.h
-
 QAPI
 M: Markus Armbruster <armbru@redhat.com>
 M: Michael Roth <mdroth@linux.vnet.ibm.com>
@@ -1242,12 +1223,6 @@ F: docs/*qmp-*
 F: scripts/qmp/
 T: git git://repo.or.cz/qemu/armbru.git qapi-next
 
-Register API
-M: Alistair Francis <alistair.francis@xilinx.com>
-S: Maintained
-F: hw/core/register.c
-F: include/hw/register.h
-
 SLIRP
 M: Samuel Thibault <samuel.thibault@ens-lyon.org>
 M: Jan Kiszka <jan.kiszka@siemens.com>
@@ -1267,6 +1242,7 @@ F: docs/tracing.txt
 T: git git://github.com/stefanha/qemu.git tracing
 
 Checkpatch
+M: Blue Swirl <blauwirbel@gmail.com>
 S: Odd Fixes
 F: scripts/checkpatch.pl
 
@@ -1339,7 +1315,8 @@ F: thunk.c
 F: user-exec.c
 
 BSD user
-S: Orphan
+M: Blue Swirl <blauwirbel@gmail.com>
+S: Maintained
 F: bsd-user/
 
 Linux user
@@ -1402,7 +1379,8 @@ F: tcg/s390/
 F: disas/s390.c
 
 SPARC target
-S: Odd Fixes
+M: Blue Swirl <blauwirbel@gmail.com>
+S: Maintained
 F: tcg/sparc/
 F: disas/sparc.c
 
@@ -1422,8 +1400,9 @@ S: Orphan
 
 Stable 0.15
 L: qemu-stable@nongnu.org
+M: Andreas Färber <afaerber@suse.de>
 T: git git://git.qemu-project.org/qemu-stable-0.15.git
-S: Orphan
+S: Supported
 
 Stable 0.14
 L: qemu-stable@nongnu.org
@@ -1637,10 +1616,3 @@ Build system architecture
 M: Daniel P. Berrange <berrange@redhat.com>
 S: Odd Fixes
 F: docs/build-system.txt
-
-Docker testing
---------------
-Docker based testing framework and cases
-M: Fam Zheng <famz@redhat.com>
-S: Maintained
-F: tests/docker/
index 50b4b3a..1d076a9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ BUILD_DIR=$(CURDIR)
 # Before including a proper config-host.mak, assume we are in the source tree
 SRC_PATH=.
 
-UNCHECKED_GOALS := %clean TAGS cscope ctags docker docker-%
+UNCHECKED_GOALS := %clean TAGS cscope ctags
 
 # All following code might depend on configuration variables
 ifneq ($(wildcard config-host.mak),)
@@ -30,7 +30,8 @@ CONFIG_ALL=y
 -include config-all-devices.mak
 -include config-all-disas.mak
 
-config-host.mak: $(SRC_PATH)/configure $(SRC_PATH)/pc-bios
+include $(SRC_PATH)/rules.mak
+config-host.mak: $(SRC_PATH)/configure
        @echo $@ is out-of-date, running configure
        @# TODO: The next lines include code which supports a smooth
        @# transition from old configurations without config.status.
@@ -48,9 +49,7 @@ ifneq ($(filter-out $(UNCHECKED_GOALS),$(MAKECMDGOALS)),$(if $(MAKECMDGOALS),,fa
 endif
 endif
 
-include $(SRC_PATH)/rules.mak
-
-GENERATED_HEADERS = qemu-version.h config-host.h qemu-options.def
+GENERATED_HEADERS = config-host.h qemu-options.def
 GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h qapi-event.h
 GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c
 GENERATED_HEADERS += qmp-introspect.h
@@ -82,7 +81,7 @@ Makefile: ;
 configure: ;
 
 .PHONY: all clean cscope distclean dvi html info install install-doc \
-       pdf recurse-all speed test dist msi FORCE
+       pdf recurse-all speed test dist msi
 
 $(call set-vpath, $(SRC_PATH))
 
@@ -93,6 +92,9 @@ HELPERS-$(CONFIG_LINUX) = qemu-bridge-helper$(EXESUF)
 ifdef BUILD_DOCS
 DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
 DOCS+=qmp-commands.txt
+ifdef CONFIG_LINUX
+DOCS+=kvm_stat.1
+endif
 ifdef CONFIG_VIRTFS
 DOCS+=fsdev/virtfs-proxy-helper.1
 endif
@@ -117,7 +119,7 @@ endif
 
 -include $(SUBDIR_DEVICES_MAK_DEP)
 
-%/config-devices.mak: default-configs/%.mak $(SRC_PATH)/scripts/make_device_config.sh
+%/config-devices.mak: default-configs/%.mak
        $(call quiet-command, \
             $(SHELL) $(SRC_PATH)/scripts/make_device_config.sh $< $*-config-devices.mak.d $@ > $@.tmp, "  GEN   $@.tmp")
        $(call quiet-command, if test -f $@; then \
@@ -162,34 +164,14 @@ dummy := $(call unnest-vars,, \
                 common-obj-m)
 
 ifneq ($(wildcard config-host.mak),)
-include $(SRC_PATH)/tests/Makefile.include
+include $(SRC_PATH)/tests/Makefile
 endif
 
 all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all modules
 
-qemu-version.h: FORCE
-       $(call quiet-command, \
-               (cd $(SRC_PATH); \
-               printf '#define QEMU_PKGVERSION '; \
-               if test -n "$(PKGVERSION)"; then \
-                       printf '"$(PKGVERSION)"\n'; \
-               else \
-                       if test -d .git; then \
-                               printf '" ('; \
-                               git describe --match 'v*' 2>/dev/null | tr -d '\n'; \
-                               if ! git diff-index --quiet HEAD &>/dev/null; then \
-                                       printf -- '-dirty'; \
-                               fi; \
-                               printf ')"\n'; \
-                       else \
-                               printf '""\n'; \
-                       fi; \
-               fi) > $@.tmp)
-       $(call quiet-command, cmp -s $@ $@.tmp || mv $@.tmp $@)
-
 config-host.h: config-host.h-timestamp
 config-host.h-timestamp: config-host.mak
-qemu-options.def: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool
+qemu-options.def: $(SRC_PATH)/qemu-options.hx
        $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"  GEN   $@")
 
 SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS))
@@ -225,9 +207,8 @@ dtc/%:
 $(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y) $(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY))
 
 ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
-# Only keep -O and -g cflags
 romsubdir-%:
-       $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C pc-bios/$* V="$(V)" TARGET_DIR="$*/" CFLAGS="$(filter -O% -g%,$(CFLAGS))",)
+       $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C pc-bios/$* V="$(V)" TARGET_DIR="$*/",)
 
 ALL_SUBDIRS=$(TARGET_DIRS) $(patsubst %,pc-bios/%, $(ROMS))
 
@@ -262,7 +243,7 @@ qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o libqemuutil.a libqemustub.a
 fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/9p-marshal.o fsdev/9p-iov-marshal.o libqemuutil.a libqemustub.a
 fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap
 
-qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/scripts/hxtool
+qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
        $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"  GEN   $@")
 
 qemu-ga$(EXESUF): LIBS = $(LIBS_QGA)
@@ -375,7 +356,6 @@ clean:
        if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
        rm -f $$d/qemu-options.def; \
         done
-       rm -f $(SUBDIR_DEVICES_MAK) config-all-devices.mak
 
 VERSION ?= $(shell cat VERSION)
 
@@ -417,10 +397,9 @@ pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
 pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
 efi-e1000.rom efi-eepro100.rom efi-ne2k_pci.rom \
 efi-pcnet.rom efi-rtl8139.rom efi-virtio.rom \
-efi-e1000e.rom efi-vmxnet3.rom \
 qemu-icon.bmp qemu_logo_no_text.svg \
 bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
-multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin \
+multiboot.bin linuxboot.bin kvmvapic.bin \
 s390-ccw.img \
 spapr-rtas.bin slof.bin \
 palcode-clipper \
@@ -489,7 +468,7 @@ endif
        set -e; for x in $(KEYMAPS); do \
                $(INSTALL_DATA) $(SRC_PATH)/pc-bios/keymaps/$$x "$(DESTDIR)$(qemu_datadir)/keymaps"; \
        done
-       $(INSTALL_DATA) $(BUILD_DIR)/trace-events-all "$(DESTDIR)$(qemu_datadir)/trace-events-all"
+       $(INSTALL_DATA) $(SRC_PATH)/trace-events "$(DESTDIR)$(qemu_datadir)/trace-events"
        for d in $(TARGET_DIRS); do \
        $(MAKE) $(SUBDIR_MAKEFLAGS) TARGET_DIR=$$d/ -C $$d $@ || exit 1 ; \
         done
@@ -500,12 +479,12 @@ test speed: all
 
 .PHONY: ctags
 ctags:
-       rm -f tags
+       rm -f $@
        find "$(SRC_PATH)" -name '*.[hc]' -exec ctags --append {} +
 
 .PHONY: TAGS
 TAGS:
-       rm -f TAGS
+       rm -f $@
        find "$(SRC_PATH)" -name '*.[hc]' -exec etags --append {} +
 
 cscope:
@@ -546,19 +525,19 @@ TEXIFLAG=$(if $(V),,--quiet)
 %.pdf: %.texi
        $(call quiet-command,texi2pdf $(TEXIFLAG) -I . $<,"  GEN   $@")
 
-qemu-options.texi: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool
+qemu-options.texi: $(SRC_PATH)/qemu-options.hx
        $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"  GEN   $@")
 
-qemu-monitor.texi: $(SRC_PATH)/hmp-commands.hx $(SRC_PATH)/scripts/hxtool
+qemu-monitor.texi: $(SRC_PATH)/hmp-commands.hx
        $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"  GEN   $@")
 
-qemu-monitor-info.texi: $(SRC_PATH)/hmp-commands-info.hx $(SRC_PATH)/scripts/hxtool
+qemu-monitor-info.texi: $(SRC_PATH)/hmp-commands-info.hx
        $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"  GEN   $@")
 
-qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx $(SRC_PATH)/scripts/hxtool
+qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx
        $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -q < $< > $@,"  GEN   $@")
 
-qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/scripts/hxtool
+qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx
        $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"  GEN   $@")
 
 qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi qemu-monitor-info.texi
@@ -566,9 +545,8 @@ qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi qemu-monitor-info.texi
          perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< qemu.pod && \
          $(POD2MAN) --section=1 --center=" " --release=" " qemu.pod > $@, \
          "  GEN   $@")
-qemu.1: qemu-option-trace.texi
 
-qemu-img.1: qemu-img.texi qemu-option-trace.texi qemu-img-cmds.texi
+qemu-img.1: qemu-img.texi qemu-img-cmds.texi
        $(call quiet-command, \
          perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< qemu-img.pod && \
          $(POD2MAN) --section=1 --center=" " --release=" " qemu-img.pod > $@, \
@@ -580,7 +558,7 @@ fsdev/virtfs-proxy-helper.1: fsdev/virtfs-proxy-helper.texi
          $(POD2MAN) --section=1 --center=" " --release=" " fsdev/virtfs-proxy-helper.pod > $@, \
          "  GEN   $@")
 
-qemu-nbd.8: qemu-nbd.texi qemu-option-trace.texi
+qemu-nbd.8: qemu-nbd.texi
        $(call quiet-command, \
          perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< qemu-nbd.pod && \
          $(POD2MAN) --section=8 --center=" " --release=" " qemu-nbd.pod > $@, \
@@ -592,13 +570,19 @@ qemu-ga.8: qemu-ga.texi
          $(POD2MAN) --section=8 --center=" " --release=" " qemu-ga.pod > $@, \
          "  GEN   $@")
 
+kvm_stat.1: scripts/kvm/kvm_stat.texi
+       $(call quiet-command, \
+         perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< kvm_stat.pod && \
+         $(POD2MAN) --section=1 --center=" " --release=" " kvm_stat.pod > $@, \
+         "  GEN   $@")
+
 dvi: qemu-doc.dvi qemu-tech.dvi
 html: qemu-doc.html qemu-tech.html
 info: qemu-doc.info qemu-tech.info
 pdf: qemu-doc.pdf qemu-tech.pdf
 
 qemu-doc.dvi qemu-doc.html qemu-doc.info qemu-doc.pdf: \
-       qemu-img.texi qemu-nbd.texi qemu-options.texi qemu-option-trace.texi \
+       qemu-img.texi qemu-nbd.texi qemu-options.texi \
        qemu-monitor.texi qemu-img-cmds.texi qemu-ga.texi \
        qemu-monitor-info.texi
 
@@ -667,5 +651,3 @@ endif
 # Include automatically generated dependency files
 # Dependencies in Makefile.objs files come from our recursive subdir rules
 -include $(wildcard *.d tests/*.d)
-
-include $(SRC_PATH)/tests/docker/Makefile.include
index 6d5ddcf..8f705f6 100644 (file)
@@ -52,6 +52,7 @@ common-obj-$(CONFIG_LINUX) += fsdev/
 common-obj-y += migration/
 common-obj-y += qemu-char.o #aio.o
 common-obj-y += page_cache.o
+common-obj-y += qjson.o
 
 common-obj-$(CONFIG_SPICE) += spice-qemu-char.o
 
@@ -115,47 +116,3 @@ qga-vss-dll-obj-y = qga/
 # contrib
 ivshmem-client-obj-y = contrib/ivshmem-client/
 ivshmem-server-obj-y = contrib/ivshmem-server/
-
-
-######################################################################
-trace-events-y = trace-events
-trace-events-y += util/trace-events
-trace-events-y += crypto/trace-events
-trace-events-y += io/trace-events
-trace-events-y += migration/trace-events
-trace-events-y += block/trace-events
-trace-events-y += hw/block/trace-events
-trace-events-y += hw/char/trace-events
-trace-events-y += hw/intc/trace-events
-trace-events-y += hw/net/trace-events
-trace-events-y += hw/virtio/trace-events
-trace-events-y += hw/audio/trace-events
-trace-events-y += hw/misc/trace-events
-trace-events-y += hw/usb/trace-events
-trace-events-y += hw/scsi/trace-events
-trace-events-y += hw/nvram/trace-events
-trace-events-y += hw/display/trace-events
-trace-events-y += hw/input/trace-events
-trace-events-y += hw/timer/trace-events
-trace-events-y += hw/dma/trace-events
-trace-events-y += hw/sparc/trace-events
-trace-events-y += hw/sd/trace-events
-trace-events-y += hw/isa/trace-events
-trace-events-y += hw/i386/trace-events
-trace-events-y += hw/9pfs/trace-events
-trace-events-y += hw/ppc/trace-events
-trace-events-y += hw/pci/trace-events
-trace-events-y += hw/s390x/trace-events
-trace-events-y += hw/vfio/trace-events
-trace-events-y += hw/acpi/trace-events
-trace-events-y += hw/arm/trace-events
-trace-events-y += hw/alpha/trace-events
-trace-events-y += ui/trace-events
-trace-events-y += audio/trace-events
-trace-events-y += net/trace-events
-trace-events-y += target-i386/trace-events
-trace-events-y += target-sparc/trace-events
-trace-events-y += target-s390x/trace-events
-trace-events-y += target-ppc/trace-events
-trace-events-y += qom/trace-events
-trace-events-y += linux-user/trace-events
index a440bcb..34ddb7e 100644 (file)
@@ -48,7 +48,7 @@ else
 TARGET_TYPE=system
 endif
 
-$(QEMU_PROG).stp-installed: $(BUILD_DIR)/trace-events-all
+$(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events
        $(call quiet-command,$(TRACETOOL) \
                --format=stap \
                --backends=$(TRACE_BACKENDS) \
@@ -57,7 +57,7 @@ $(QEMU_PROG).stp-installed: $(BUILD_DIR)/trace-events-all
                --target-type=$(TARGET_TYPE) \
                < $< > $@,"  GEN   $(TARGET_DIR)$(QEMU_PROG).stp-installed")
 
-$(QEMU_PROG).stp: $(BUILD_DIR)/trace-events-all
+$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
        $(call quiet-command,$(TRACETOOL) \
                --format=stap \
                --backends=$(TRACE_BACKENDS) \
@@ -66,7 +66,7 @@ $(QEMU_PROG).stp: $(BUILD_DIR)/trace-events-all
                --target-type=$(TARGET_TYPE) \
                < $< > $@,"  GEN   $(TARGET_DIR)$(QEMU_PROG).stp")
 
-$(QEMU_PROG)-simpletrace.stp: $(BUILD_DIR)/trace-events-all
+$(QEMU_PROG)-simpletrace.stp: $(SRC_PATH)/trace-events
        $(call quiet-command,$(TRACETOOL) \
                --format=simpletrace-stap \
                --backends=$(TRACE_BACKENDS) \
@@ -108,9 +108,7 @@ obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal128.o
 
 ifdef CONFIG_LINUX_USER
 
-QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) \
-             -I$(SRC_PATH)/linux-user/host/$(ARCH) \
-             -I$(SRC_PATH)/linux-user
+QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
 
 obj-y += linux-user/
 obj-y += gdbstub.o thunk.o user-exec.o
@@ -203,13 +201,13 @@ endif
 gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
        $(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES),"  GEN   $(TARGET_DIR)$@")
 
-hmp-commands.h: $(SRC_PATH)/hmp-commands.hx $(SRC_PATH)/scripts/hxtool
+hmp-commands.h: $(SRC_PATH)/hmp-commands.hx
        $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"  GEN   $(TARGET_DIR)$@")
 
-hmp-commands-info.h: $(SRC_PATH)/hmp-commands-info.hx $(SRC_PATH)/scripts/hxtool
+hmp-commands-info.h: $(SRC_PATH)/hmp-commands-info.hx
        $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"  GEN   $(TARGET_DIR)$@")
 
-qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx $(SRC_PATH)/scripts/hxtool
+qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx
        $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"  GEN   $(TARGET_DIR)$@")
 
 clean:
diff --git a/VERSION b/VERSION
index 24ba9a3..6a6a3d8 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.7.0
+2.6.1
diff --git a/accel.c b/accel.c
index 403eb5e..0510b90 100644 (file)
--- a/accel.c
+++ b/accel.c
@@ -77,7 +77,7 @@ static int accel_init_machine(AccelClass *acc, MachineState *ms)
     return ret;
 }
 
-void configure_accelerator(MachineState *ms)
+int configure_accelerator(MachineState *ms)
 {
     const char *p;
     char buf[10];
@@ -128,6 +128,8 @@ void configure_accelerator(MachineState *ms)
     if (init_failed) {
         fprintf(stderr, "Back to %s accelerator.\n", acc->name);
     }
+
+    return !accel_initialised;
 }
 
 
index 43162a9..6006122 100644 (file)
@@ -485,13 +485,12 @@ bool aio_poll(AioContext *ctx, bool blocking)
     return progress;
 }
 
-void aio_context_setup(AioContext *ctx)
+void aio_context_setup(AioContext *ctx, Error **errp)
 {
 #ifdef CONFIG_EPOLL_CREATE1
     assert(!ctx->epollfd);
     ctx->epollfd = epoll_create1(EPOLL_CLOEXEC);
     if (ctx->epollfd == -1) {
-        fprintf(stderr, "Failed to create epoll instance: %s", strerror(errno));
         ctx->epoll_available = false;
     } else {
         ctx->epoll_available = true;
index c8c249e..6aaa32a 100644 (file)
@@ -371,6 +371,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
     return progress;
 }
 
-void aio_context_setup(AioContext *ctx)
+void aio_context_setup(AioContext *ctx, Error **errp)
 {
 }
index fa05973..e3bb1b3 100644 (file)
@@ -22,8 +22,6 @@
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/arch_init.h"
 #include "hw/pci/pci.h"
@@ -274,6 +272,13 @@ void do_smbios_option(QemuOpts *opts)
 #endif
 }
 
+void cpudef_init(void)
+{
+#if defined(cpudef_setup)
+    cpudef_setup(); /* parse cpu definitions in target config file */
+#endif
+}
+
 int kvm_available(void)
 {
 #ifdef CONFIG_KVM
diff --git a/async.c b/async.c
index 3bca9b0..b4bf205 100644 (file)
--- a/async.c
+++ b/async.c
@@ -29,7 +29,6 @@
 #include "block/thread-pool.h"
 #include "qemu/main-loop.h"
 #include "qemu/atomic.h"
-#include "block/raw-aio.h"
 
 /***********************************************************/
 /* bottom halves (can be seen as timers which expire ASAP) */
@@ -218,7 +217,7 @@ aio_ctx_check(GSource *source)
     for (bh = ctx->first_bh; bh; bh = bh->next) {
         if (!bh->deleted && bh->scheduled) {
             return true;
-        }
+       }
     }
     return aio_pending(ctx) || (timerlistgroup_deadline_ns(&ctx->tlg) == 0);
 }
@@ -243,14 +242,6 @@ aio_ctx_finalize(GSource     *source)
     qemu_bh_delete(ctx->notify_dummy_bh);
     thread_pool_free(ctx->thread_pool);
 
-#ifdef CONFIG_LINUX_AIO
-    if (ctx->linux_aio) {
-        laio_detach_aio_context(ctx->linux_aio, ctx);
-        laio_cleanup(ctx->linux_aio);
-        ctx->linux_aio = NULL;
-    }
-#endif
-
     qemu_mutex_lock(&ctx->bh_lock);
     while (ctx->first_bh) {
         QEMUBH *next = ctx->first_bh->next;
@@ -291,17 +282,6 @@ ThreadPool *aio_get_thread_pool(AioContext *ctx)
     return ctx->thread_pool;
 }
 
-#ifdef CONFIG_LINUX_AIO
-LinuxAioState *aio_get_linux_aio(AioContext *ctx)
-{
-    if (!ctx->linux_aio) {
-        ctx->linux_aio = laio_init();
-        laio_attach_aio_context(ctx->linux_aio, ctx);
-    }
-    return ctx->linux_aio;
-}
-#endif
-
 void aio_notify(AioContext *ctx)
 {
     /* Write e.g. bh->scheduled before reading ctx->notify_me.  Pairs
@@ -347,10 +327,14 @@ AioContext *aio_context_new(Error **errp)
 {
     int ret;
     AioContext *ctx;
+    Error *local_err = NULL;
 
     ctx = (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext));
-    aio_context_setup(ctx);
-
+    aio_context_setup(ctx, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        goto fail;
+    }
     ret = event_notifier_init(&ctx->notifier, false);
     if (ret < 0) {
         error_setg_errno(errp, -ret, "Failed to initialize event notifier");
@@ -361,9 +345,6 @@ AioContext *aio_context_new(Error **errp)
                            false,
                            (EventNotifierHandler *)
                            event_notifier_dummy_cb);
-#ifdef CONFIG_LINUX_AIO
-    ctx->linux_aio = NULL;
-#endif
     ctx->thread_pool = NULL;
     qemu_mutex_init(&ctx->bh_lock);
     rfifolock_init(&ctx->lock, aio_rfifolock_cb, ctx);
index c845a44..e60c124 100644 (file)
@@ -1131,6 +1131,8 @@ static void audio_timer (void *opaque)
  */
 int AUD_write (SWVoiceOut *sw, void *buf, int size)
 {
+    int bytes;
+
     if (!sw) {
         /* XXX: Consider options */
         return size;
@@ -1141,11 +1143,14 @@ int AUD_write (SWVoiceOut *sw, void *buf, int size)
         return 0;
     }
 
-    return sw->hw->pcm_ops->write(sw, buf, size);
+    bytes = sw->hw->pcm_ops->write (sw, buf, size);
+    return bytes;
 }
 
 int AUD_read (SWVoiceIn *sw, void *buf, int size)
 {
+    int bytes;
+
     if (!sw) {
         /* XXX: Consider options */
         return size;
@@ -1156,7 +1161,8 @@ int AUD_read (SWVoiceIn *sw, void *buf, int size)
         return 0;
     }
 
-    return sw->hw->pcm_ops->read(sw, buf, size);
+    bytes = sw->hw->pcm_ops->read (sw, buf, size);
+    return bytes;
 }
 
 int AUD_get_buffer_size_out (SWVoiceOut *sw)
@@ -1739,21 +1745,13 @@ static void audio_vm_change_state_handler (void *opaque, int running,
     audio_reset_timer (s);
 }
 
-static bool is_cleaning_up;
-
-bool audio_is_cleaning_up(void)
-{
-    return is_cleaning_up;
-}
-
-void audio_cleanup(void)
+static void audio_atexit (void)
 {
     AudioState *s = &glob_audio_state;
-    HWVoiceOut *hwo, *hwon;
-    HWVoiceIn *hwi, *hwin;
+    HWVoiceOut *hwo = NULL;
+    HWVoiceIn *hwi = NULL;
 
-    is_cleaning_up = true;
-    QLIST_FOREACH_SAFE(hwo, &glob_audio_state.hw_head_out, entries, hwon) {
+    while ((hwo = audio_pcm_hw_find_any_out (hwo))) {
         SWVoiceCap *sc;
 
         if (hwo->enabled) {
@@ -1769,20 +1767,17 @@ void audio_cleanup(void)
                 cb->ops.destroy (cb->opaque);
             }
         }
-        QLIST_REMOVE(hwo, entries);
     }
 
-    QLIST_FOREACH_SAFE(hwi, &glob_audio_state.hw_head_in, entries, hwin) {
+    while ((hwi = audio_pcm_hw_find_any_in (hwi))) {
         if (hwi->enabled) {
             hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
         }
         hwi->pcm_ops->fini_in (hwi);
-        QLIST_REMOVE(hwi, entries);
     }
 
     if (s->drv) {
         s->drv->fini (s->drv_opaque);
-        s->drv = NULL;
     }
 }
 
@@ -1810,7 +1805,7 @@ static void audio_init (void)
     QLIST_INIT (&s->hw_head_out);
     QLIST_INIT (&s->hw_head_in);
     QLIST_INIT (&s->cap_head);
-    atexit(audio_cleanup);
+    atexit (audio_atexit);
 
     s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);
 
@@ -1977,7 +1972,8 @@ CaptureVoiceOut *AUD_add_capture (
         QLIST_INSERT_HEAD (&s->cap_head, cap, entries);
         QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);
 
-        QLIST_FOREACH(hw, &glob_audio_state.hw_head_out, entries) {
+        hw = NULL;
+        while ((hw = audio_pcm_hw_find_any_out (hw))) {
             audio_attach_capture (hw);
         }
         return cap;
index c3c5198..b41a970 100644 (file)
@@ -21,7 +21,6 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
 #ifndef QEMU_AUDIO_H
 #define QEMU_AUDIO_H
 
@@ -163,7 +162,4 @@ static inline void *advance (void *p, int incr)
 int wav_start_capture (CaptureState *s, const char *path, int freq,
                        int bits, int nchannels);
 
-bool audio_is_cleaning_up(void);
-void audio_cleanup(void);
-
-#endif /* QEMU_AUDIO_H */
+#endif  /* audio.h */
index 5bcb1c6..566df5e 100644 (file)
@@ -21,7 +21,6 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
 #ifndef QEMU_AUDIO_INT_H
 #define QEMU_AUDIO_INT_H
 
@@ -258,4 +257,4 @@ static inline int audio_ring_dist (int dst, int src, int len)
 #define AUDIO_FUNC __FILE__ ":" AUDIO_STRINGIFY (__LINE__)
 #endif
 
-#endif /* QEMU_AUDIO_INT_H */
+#endif /* audio_int.h */
index 4c0c15b..0dfff76 100644 (file)
@@ -19,4 +19,4 @@ int audio_pt_wait (struct audio_pt *, const char *);
 int audio_pt_unlock_and_signal (struct audio_pt *, const char *);
 int audio_pt_join (struct audio_pt *, void **, const char *);
 
-#endif /* QEMU_AUDIO_PT_INT_H */
+#endif /* audio_pt_int.h */
index c751420..d4ad224 100644 (file)
@@ -36,6 +36,8 @@
 #define MAC_OS_X_VERSION_10_6 1060
 #endif
 
+static int isAtexit;
+
 typedef struct {
     int buffer_frames;
     int nbuffers;
@@ -376,6 +378,11 @@ static inline UInt32 isPlaying (AudioDeviceID outputDeviceID)
     return result;
 }
 
+static void coreaudio_atexit (void)
+{
+    isAtexit = 1;
+}
+
 static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
 {
     int err;
@@ -623,7 +630,7 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
     int err;
     coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
 
-    if (!audio_is_cleaning_up()) {
+    if (!isAtexit) {
         /* stop playback */
         if (isPlaying(core->outputDeviceID)) {
             status = AudioDeviceStop(core->outputDeviceID, core->ioprocid);
@@ -666,7 +673,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
 
     case VOICE_DISABLE:
         /* stop playback */
-        if (!audio_is_cleaning_up()) {
+        if (!isAtexit) {
             if (isPlaying(core->outputDeviceID)) {
                 status = AudioDeviceStop(core->outputDeviceID,
                                          core->ioprocid);
@@ -690,6 +697,7 @@ static void *coreaudio_audio_init (void)
     CoreaudioConf *conf = g_malloc(sizeof(CoreaudioConf));
     *conf = glob_conf;
 
+    atexit(coreaudio_atexit);
     return conf;
 }
 
index 66c0328..61ef869 100644 (file)
@@ -24,7 +24,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "qemu/bswap.h"
 #include "audio.h"
 
 #define AUDIO_CAP "mixeng"
index b53a5ef..9de443b 100644 (file)
@@ -21,7 +21,6 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
 #ifndef QEMU_MIXENG_H
 #define QEMU_MIXENG_H
 
@@ -49,4 +48,4 @@ void st_rate_stop (void *opaque);
 void mixeng_clear (struct st_sample *buf, int len);
 void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol);
 
-#endif /* QEMU_MIXENG_H */
+#endif  /* mixeng.h */
index 9ca9eaf..b360c19 100644 (file)
@@ -23,7 +23,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "qemu/host-utils.h"
 #include "audio.h"
 #include "qemu/timer.h"
 
index 0edd7ea..a0d9cda 100644 (file)
@@ -22,6 +22,7 @@
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
+#include <sys/mman.h>
 #include <sys/ioctl.h>
 #include <sys/soundcard.h>
 #include "qemu-common.h"
index 65beb6f..57678e7 100644 (file)
@@ -781,22 +781,23 @@ static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...)
 
             pa_threaded_mainloop_lock (g->mainloop);
 
-            op = pa_context_set_source_output_volume (g->context,
-                pa_stream_get_index (pa->stream),
+            /* FIXME: use the upcoming "set_source_output_{volume,mute}" */
+            op = pa_context_set_source_volume_by_index (g->context,
+                pa_stream_get_device_index (pa->stream),
                 &v, NULL, NULL);
             if (!op) {
                 qpa_logerr (pa_context_errno (g->context),
-                            "set_source_output_volume() failed\n");
+                            "set_source_volume() failed\n");
             } else {
                 pa_operation_unref(op);
             }
 
-            op = pa_context_set_source_output_mute (g->context,
+            op = pa_context_set_source_mute_by_index (g->context,
                 pa_stream_get_index (pa->stream),
                 sw->vol.mute, NULL, NULL);
             if (!op) {
                 qpa_logerr (pa_context_errno (g->context),
-                            "set_source_output_mute() failed\n");
+                            "set_source_mute() failed\n");
             } else {
                 pa_operation_unref (op);
             }
index 5580e76..dea71d3 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/hw.h"
-#include "qemu/host-utils.h"
 #include "qemu/error-report.h"
 #include "qemu/timer.h"
 #include "ui/qemu-spice.h"
diff --git a/audio/trace-events b/audio/trace-events
deleted file mode 100644 (file)
index 5173590..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# audio/alsaaudio.c
-alsa_revents(int revents) "revents = %d"
-alsa_pollout(int i, int fd) "i = %d fd = %d"
-alsa_set_handler(int events, int index, int fd, int err) "events=%#x index=%d fd=%d err=%d"
-alsa_wrote_zero(int len) "Failed to write %d frames (wrote zero)"
-alsa_read_zero(long len) "Failed to read %ld frames (read zero)"
-alsa_xrun_out(void) "Recovering from playback xrun"
-alsa_xrun_in(void) "Recovering from capture xrun"
-alsa_resume_out(void) "Resuming suspended output stream"
-alsa_resume_in(void) "Resuming suspended input stream"
-alsa_no_frames(int state) "No frames available and ALSA state is %d"
-
-# audio/ossaudio.c
-oss_version(int version) "OSS version = %#x"
-oss_invalid_available_size(int size, int bufsize) "Invalid available size, size=%d bufsize=%d"
index 341eec3..345952e 100644 (file)
@@ -22,7 +22,7 @@
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "qemu/host-utils.h"
+#include "hw/hw.h"
 #include "qemu/timer.h"
 #include "audio.h"
 
index b7a208d..6e28be1 100644 (file)
@@ -64,14 +64,6 @@ out:
     error_propagate(errp, local_err);
 }
 
-static uint16List **host_memory_append_node(uint16List **node,
-                                            unsigned long value)
-{
-     *node = g_malloc0(sizeof(**node));
-     (*node)->value = value;
-     return &(*node)->next;
-}
-
 static void
 host_memory_backend_get_host_nodes(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
@@ -82,23 +74,25 @@ host_memory_backend_get_host_nodes(Object *obj, Visitor *v, const char *name,
     unsigned long value;
 
     value = find_first_bit(backend->host_nodes, MAX_NODES);
-
-    node = host_memory_append_node(node, value);
-
     if (value == MAX_NODES) {
-        goto out;
+        return;
     }
 
+    *node = g_malloc0(sizeof(**node));
+    (*node)->value = value;
+    node = &(*node)->next;
+
     do {
         value = find_next_bit(backend->host_nodes, MAX_NODES, value + 1);
         if (value == MAX_NODES) {
             break;
         }
 
-        node = host_memory_append_node(node, value);
+        *node = g_malloc0(sizeof(**node));
+        (*node)->value = value;
+        node = &(*node)->next;
     } while (true);
 
-out:
     visit_type_uint16List(v, name, &host_nodes, errp);
 }
 
@@ -203,7 +197,6 @@ static bool host_memory_backend_get_prealloc(Object *obj, Error **errp)
 static void host_memory_backend_set_prealloc(Object *obj, bool value,
                                              Error **errp)
 {
-    Error *local_err = NULL;
     HostMemoryBackend *backend = MEMORY_BACKEND(obj);
 
     if (backend->force_prealloc) {
@@ -224,11 +217,7 @@ static void host_memory_backend_set_prealloc(Object *obj, bool value,
         void *ptr = memory_region_get_ram_ptr(&backend->mr);
         uint64_t sz = memory_region_size(&backend->mr);
 
-        os_mem_prealloc(fd, ptr, sz, &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            return;
-        }
+        os_mem_prealloc(fd, ptr, sz);
         backend->prealloc = true;
     }
 }
@@ -269,16 +258,6 @@ host_memory_backend_get_memory(HostMemoryBackend *backend, Error **errp)
     return memory_region_size(&backend->mr) ? &backend->mr : NULL;
 }
 
-void host_memory_backend_set_mapped(HostMemoryBackend *backend, bool mapped)
-{
-    backend->is_mapped = mapped;
-}
-
-bool host_memory_backend_is_mapped(HostMemoryBackend *backend)
-{
-    return backend->is_mapped;
-}
-
 static void
 host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
 {
@@ -291,7 +270,8 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
     if (bc->alloc) {
         bc->alloc(backend, &local_err);
         if (local_err) {
-            goto out;
+            error_propagate(errp, local_err);
+            return;
         }
 
         ptr = memory_region_get_ram_ptr(&backend->mr);
@@ -347,21 +327,18 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
          * specified NUMA policy in place.
          */
         if (backend->prealloc) {
-            os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz,
-                            &local_err);
-            if (local_err) {
-                goto out;
-            }
+            os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz);
         }
     }
-out:
-    error_propagate(errp, local_err);
 }
 
 static bool
 host_memory_backend_can_be_deleted(UserCreatable *uc, Error **errp)
 {
-    if (host_memory_backend_is_mapped(MEMORY_BACKEND(uc))) {
+    MemoryRegion *mr;
+
+    mr = host_memory_backend_get_memory(MEMORY_BACKEND(uc), errp);
+    if (memory_region_is_mapped(mr)) {
         return false;
     } else {
         return true;
index aeb9055..8dea5a1 100644 (file)
 #include "qemu-common.h"
 #include "sysemu/char.h"
 #include "ui/console.h"
-#include "ui/input.h"
 
 #define MSMOUSE_LO6(n) ((n) & 0x3f)
 #define MSMOUSE_HI2(n) (((n) & 0xc0) >> 6)
 
-typedef struct {
-    CharDriverState *chr;
-    QemuInputHandlerState *hs;
-    int axis[INPUT_AXIS__MAX];
-    bool btns[INPUT_BUTTON__MAX];
-    bool btnc[INPUT_BUTTON__MAX];
-    uint8_t outbuf[32];
-    int outlen;
-} MouseState;
-
-static void msmouse_chr_accept_input(CharDriverState *chr)
+static void msmouse_event(void *opaque,
+                          int dx, int dy, int dz, int buttons_state)
 {
-    MouseState *mouse = chr->opaque;
-    int len;
-
-    len = qemu_chr_be_can_write(chr);
-    if (len > mouse->outlen) {
-        len = mouse->outlen;
-    }
-    if (!len) {
-        return;
-    }
-
-    qemu_chr_be_write(chr, mouse->outbuf, len);
-    mouse->outlen -= len;
-    if (mouse->outlen) {
-        memmove(mouse->outbuf, mouse->outbuf + len, mouse->outlen);
-    }
-}
+    CharDriverState *chr = (CharDriverState *)opaque;
 
-static void msmouse_queue_event(MouseState *mouse)
-{
     unsigned char bytes[4] = { 0x40, 0x00, 0x00, 0x00 };
-    int dx, dy, count = 3;
-
-    dx = mouse->axis[INPUT_AXIS_X];
-    mouse->axis[INPUT_AXIS_X] = 0;
-
-    dy = mouse->axis[INPUT_AXIS_Y];
-    mouse->axis[INPUT_AXIS_Y] = 0;
 
     /* Movement deltas */
     bytes[0] |= (MSMOUSE_HI2(dy) << 2) | MSMOUSE_HI2(dx);
@@ -77,54 +42,14 @@ static void msmouse_queue_event(MouseState *mouse)
     bytes[2] |= MSMOUSE_LO6(dy);
 
     /* Buttons */
-    bytes[0] |= (mouse->btns[INPUT_BUTTON_LEFT]   ? 0x20 : 0x00);
-    bytes[0] |= (mouse->btns[INPUT_BUTTON_RIGHT]  ? 0x10 : 0x00);
-    if (mouse->btns[INPUT_BUTTON_MIDDLE] ||
-        mouse->btnc[INPUT_BUTTON_MIDDLE]) {
-        bytes[3] |= (mouse->btns[INPUT_BUTTON_MIDDLE] ? 0x20 : 0x00);
-        mouse->btnc[INPUT_BUTTON_MIDDLE] = false;
-        count = 4;
-    }
-
-    if (mouse->outlen <= sizeof(mouse->outbuf) - count) {
-        memcpy(mouse->outbuf + mouse->outlen, bytes, count);
-        mouse->outlen += count;
-    } else {
-        /* queue full -> drop event */
-    }
-}
-
-static void msmouse_input_event(DeviceState *dev, QemuConsole *src,
-                                InputEvent *evt)
-{
-    MouseState *mouse = (MouseState *)dev;
-    InputMoveEvent *move;
-    InputBtnEvent *btn;
-
-    switch (evt->type) {
-    case INPUT_EVENT_KIND_REL:
-        move = evt->u.rel.data;
-        mouse->axis[move->axis] += move->value;
-        break;
-
-    case INPUT_EVENT_KIND_BTN:
-        btn = evt->u.btn.data;
-        mouse->btns[btn->button] = btn->down;
-        mouse->btnc[btn->button] = true;
-        break;
-
-    default:
-        /* keep gcc happy */
-        break;
-    }
-}
-
-static void msmouse_input_sync(DeviceState *dev)
-{
-    MouseState *mouse = (MouseState *)dev;
-
-    msmouse_queue_event(mouse);
-    msmouse_chr_accept_input(mouse->chr);
+    bytes[0] |= (buttons_state & 0x01 ? 0x20 : 0x00);
+    bytes[0] |= (buttons_state & 0x02 ? 0x10 : 0x00);
+    bytes[3] |= (buttons_state & 0x04 ? 0x20 : 0x00);
+
+    /* We always send the packet of, so that we do not have to keep track
+       of previous state of the middle button. This can potentially confuse
+       some very old drivers for two button mice though. */
+    qemu_chr_be_write(chr, bytes, 4);
 }
 
 static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int len)
@@ -135,41 +60,26 @@ static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int
 
 static void msmouse_chr_close (struct CharDriverState *chr)
 {
-    MouseState *mouse = chr->opaque;
-
-    qemu_input_handler_unregister(mouse->hs);
-    g_free(mouse);
-    g_free(chr);
+    g_free (chr);
 }
 
-static QemuInputHandler msmouse_handler = {
-    .name  = "QEMU Microsoft Mouse",
-    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
-    .event = msmouse_input_event,
-    .sync  = msmouse_input_sync,
-};
-
 static CharDriverState *qemu_chr_open_msmouse(const char *id,
                                               ChardevBackend *backend,
                                               ChardevReturn *ret,
                                               Error **errp)
 {
     ChardevCommon *common = backend->u.msmouse.data;
-    MouseState *mouse;
     CharDriverState *chr;
 
     chr = qemu_chr_alloc(common, errp);
+    if (!chr) {
+        return NULL;
+    }
     chr->chr_write = msmouse_chr_write;
     chr->chr_close = msmouse_chr_close;
-    chr->chr_accept_input = msmouse_chr_accept_input;
     chr->explicit_be_open = true;
 
-    mouse = g_new0(MouseState, 1);
-    mouse->hs = qemu_input_handler_register((DeviceState *)mouse,
-                                            &msmouse_handler);
-
-    mouse->chr = chr;
-    chr->opaque = mouse;
+    qemu_add_mouse_event_handler(msmouse_event, chr, 0, "QEMU Microsoft Mouse");
 
     return chr;
 }
index e2a49b0..2e44e25 100644 (file)
@@ -17,7 +17,7 @@
 #include "qapi/qmp/qerror.h"
 #include "qemu/main-loop.h"
 
-struct RngRandom
+struct RndRandom
 {
     RngBackend parent;
 
@@ -34,7 +34,7 @@ struct RngRandom
 
 static void entropy_available(void *opaque)
 {
-    RngRandom *s = RNG_RANDOM(opaque);
+    RndRandom *s = RNG_RANDOM(opaque);
 
     while (!QSIMPLEQ_EMPTY(&s->parent.requests)) {
         RngRequest *req = QSIMPLEQ_FIRST(&s->parent.requests);
@@ -57,7 +57,7 @@ static void entropy_available(void *opaque)
 
 static void rng_random_request_entropy(RngBackend *b, RngRequest *req)
 {
-    RngRandom *s = RNG_RANDOM(b);
+    RndRandom *s = RNG_RANDOM(b);
 
     if (QSIMPLEQ_EMPTY(&s->parent.requests)) {
         /* If there are no pending requests yet, we need to
@@ -68,7 +68,7 @@ static void rng_random_request_entropy(RngBackend *b, RngRequest *req)
 
 static void rng_random_opened(RngBackend *b, Error **errp)
 {
-    RngRandom *s = RNG_RANDOM(b);
+    RndRandom *s = RNG_RANDOM(b);
 
     if (s->filename == NULL) {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
@@ -83,7 +83,7 @@ static void rng_random_opened(RngBackend *b, Error **errp)
 
 static char *rng_random_get_filename(Object *obj, Error **errp)
 {
-    RngRandom *s = RNG_RANDOM(obj);
+    RndRandom *s = RNG_RANDOM(obj);
 
     return g_strdup(s->filename);
 }
@@ -92,7 +92,7 @@ static void rng_random_set_filename(Object *obj, const char *filename,
                                  Error **errp)
 {
     RngBackend *b = RNG_BACKEND(obj);
-    RngRandom *s = RNG_RANDOM(obj);
+    RndRandom *s = RNG_RANDOM(obj);
 
     if (b->opened) {
         error_setg(errp, QERR_PERMISSION_DENIED);
@@ -105,7 +105,7 @@ static void rng_random_set_filename(Object *obj, const char *filename,
 
 static void rng_random_init(Object *obj)
 {
-    RngRandom *s = RNG_RANDOM(obj);
+    RndRandom *s = RNG_RANDOM(obj);
 
     object_property_add_str(obj, "filename",
                             rng_random_get_filename,
@@ -118,7 +118,7 @@ static void rng_random_init(Object *obj)
 
 static void rng_random_finalize(Object *obj)
 {
-    RngRandom *s = RNG_RANDOM(obj);
+    RndRandom *s = RNG_RANDOM(obj);
 
     if (s->fd != -1) {
         qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
@@ -139,7 +139,7 @@ static void rng_random_class_init(ObjectClass *klass, void *data)
 static const TypeInfo rng_random_info = {
     .name = TYPE_RNG_RANDOM,
     .parent = TYPE_RNG_BACKEND,
-    .instance_size = sizeof(RngRandom),
+    .instance_size = sizeof(RndRandom),
     .class_init = rng_random_class_init,
     .instance_init = rng_random_init,
     .instance_finalize = rng_random_finalize,
diff --git a/block.c b/block.c
index 30d64e6..d4939b4 100644 (file)
--- a/block.c
+++ b/block.c
@@ -38,6 +38,7 @@
 #include "qmp-commands.h"
 #include "qemu/timer.h"
 #include "qapi-event.h"
+#include "block/throttle-groups.h"
 #include "qemu/cutils.h"
 #include "qemu/id.h"
 
@@ -64,16 +65,16 @@ static QTAILQ_HEAD(, BlockDriverState) all_bdrv_states =
 static QLIST_HEAD(, BlockDriver) bdrv_drivers =
     QLIST_HEAD_INITIALIZER(bdrv_drivers);
 
-static BlockDriverState *bdrv_open_inherit(const char *filename,
-                                           const char *reference,
-                                           QDict *options, int flags,
-                                           BlockDriverState *parent,
-                                           const BdrvChildRole *child_role,
-                                           Error **errp);
+static int bdrv_open_inherit(BlockDriverState **pbs, const char *filename,
+                             const char *reference, QDict *options, int flags,
+                             BlockDriverState *parent,
+                             const BdrvChildRole *child_role, Error **errp);
 
 /* If non-zero, use only whitelisted block drivers */
 static int use_bdrv_whitelist;
 
+static void bdrv_close(BlockDriverState *bs);
+
 #ifdef _WIN32
 static int is_windows_drive_prefix(const char *filename)
 {
@@ -217,9 +218,16 @@ void bdrv_get_full_backing_filename(BlockDriverState *bs, char *dest, size_t sz,
 
 void bdrv_register(BlockDriver *bdrv)
 {
+    bdrv_setup_io_funcs(bdrv);
+
     QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
 }
 
+BlockDriverState *bdrv_new_root(void)
+{
+    return bdrv_new();
+}
+
 BlockDriverState *bdrv_new(void)
 {
     BlockDriverState *bs;
@@ -231,11 +239,11 @@ BlockDriverState *bdrv_new(void)
         QLIST_INIT(&bs->op_blockers[i]);
     }
     notifier_with_return_list_init(&bs->before_write_notifiers);
+    qemu_co_queue_init(&bs->throttled_reqs[0]);
+    qemu_co_queue_init(&bs->throttled_reqs[1]);
     bs->refcnt = 1;
     bs->aio_context = qemu_get_aio_context();
 
-    qemu_co_queue_init(&bs->flush_queue);
-
     QTAILQ_INSERT_TAIL(&all_bdrv_states, bs, bs_list);
 
     return bs;
@@ -303,7 +311,9 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
     assert(cco->drv);
 
     ret = cco->drv->bdrv_create(cco->filename, cco->opts, &local_err);
-    error_propagate(&cco->err, local_err);
+    if (local_err) {
+        error_propagate(&cco->err, local_err);
+    }
     cco->ret = ret;
 }
 
@@ -331,8 +341,8 @@ int bdrv_create(BlockDriver *drv, const char* filename,
         /* Fast-path if already in coroutine context */
         bdrv_create_co_entry(&cco);
     } else {
-        co = qemu_coroutine_create(bdrv_create_co_entry, &cco);
-        qemu_coroutine_enter(co);
+        co = qemu_coroutine_create(bdrv_create_co_entry);
+        qemu_coroutine_enter(co, &cco);
         while (cco.ret == NOT_DONE) {
             aio_poll(qemu_get_aio_context(), true);
         }
@@ -364,7 +374,9 @@ int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
     }
 
     ret = bdrv_create(drv, filename, opts, &local_err);
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
     return ret;
 }
 
@@ -538,10 +550,9 @@ BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
     return drv;
 }
 
-static int find_image_format(BdrvChild *file, const char *filename,
+static int find_image_format(BlockDriverState *bs, const char *filename,
                              BlockDriver **pdrv, Error **errp)
 {
-    BlockDriverState *bs = file->bs;
     BlockDriver *drv;
     uint8_t buf[BLOCK_PROBE_BUF_SIZE];
     int ret = 0;
@@ -552,7 +563,7 @@ static int find_image_format(BdrvChild *file, const char *filename,
         return ret;
     }
 
-    ret = bdrv_pread(file, 0, buf, sizeof(buf));
+    ret = bdrv_pread(bs, 0, buf, sizeof(buf));
     if (ret < 0) {
         error_setg_errno(errp, -ret, "Could not read image for determining its "
                          "format");
@@ -658,18 +669,6 @@ int bdrv_parse_cache_mode(const char *mode, int *flags, bool *writethrough)
     return 0;
 }
 
-static void bdrv_child_cb_drained_begin(BdrvChild *child)
-{
-    BlockDriverState *bs = child->opaque;
-    bdrv_drained_begin(bs);
-}
-
-static void bdrv_child_cb_drained_end(BdrvChild *child)
-{
-    BlockDriverState *bs = child->opaque;
-    bdrv_drained_end(bs);
-}
-
 /*
  * Returns the options and flags that a temporary snapshot should get, based on
  * the originally requested flags (the originally requested image will have
@@ -683,10 +682,6 @@ static void bdrv_temp_snapshot_options(int *child_flags, QDict *child_options,
     /* For temporary files, unconditional cache=unsafe is fine */
     qdict_set_default_str(child_options, BDRV_OPT_CACHE_DIRECT, "off");
     qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
-
-    /* aio=native doesn't work for cache.direct=off, so disable it for the
-     * temporary snapshot */
-    *child_flags &= ~BDRV_O_NATIVE_AIO;
 }
 
 /*
@@ -720,8 +715,6 @@ static void bdrv_inherited_options(int *child_flags, QDict *child_options,
 
 const BdrvChildRole child_file = {
     .inherit_options = bdrv_inherited_options,
-    .drained_begin   = bdrv_child_cb_drained_begin,
-    .drained_end     = bdrv_child_cb_drained_end,
 };
 
 /*
@@ -740,8 +733,6 @@ static void bdrv_inherited_fmt_options(int *child_flags, QDict *child_options,
 
 const BdrvChildRole child_format = {
     .inherit_options = bdrv_inherited_fmt_options,
-    .drained_begin   = bdrv_child_cb_drained_begin,
-    .drained_end     = bdrv_child_cb_drained_end,
 };
 
 /*
@@ -769,8 +760,6 @@ static void bdrv_backing_options(int *child_flags, QDict *child_options,
 
 static const BdrvChildRole child_backing = {
     .inherit_options = bdrv_backing_options,
-    .drained_begin   = bdrv_child_cb_drained_begin,
-    .drained_end     = bdrv_child_cb_drained_end,
 };
 
 static int bdrv_open_flags(BlockDriverState *bs, int flags)
@@ -940,6 +929,8 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *file,
         goto fail_opts;
     }
 
+    bs->request_alignment = 512;
+    bs->zero_beyond_eof = true;
     bs->read_only = !(bs->open_flags & BDRV_O_RDWR);
 
     if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) {
@@ -1019,7 +1010,7 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *file,
 
     assert(bdrv_opt_mem_align(bs) != 0);
     assert(bdrv_min_mem_align(bs) != 0);
-    assert(is_power_of_2(bs->bl.request_alignment));
+    assert((bs->request_alignment != 0) || bdrv_is_sg(bs));
 
     qemu_opts_del(opts);
     return 0;
@@ -1169,52 +1160,28 @@ static int bdrv_fill_options(QDict **options, const char *filename,
     return 0;
 }
 
-static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
-{
-    BlockDriverState *old_bs = child->bs;
-
-    if (old_bs) {
-        if (old_bs->quiesce_counter && child->role->drained_end) {
-            child->role->drained_end(child);
-        }
-        QLIST_REMOVE(child, next_parent);
-    }
-
-    child->bs = new_bs;
-
-    if (new_bs) {
-        QLIST_INSERT_HEAD(&new_bs->parents, child, next_parent);
-        if (new_bs->quiesce_counter && child->role->drained_begin) {
-            child->role->drained_begin(child);
-        }
-    }
-}
-
 BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
                                   const char *child_name,
-                                  const BdrvChildRole *child_role,
-                                  void *opaque)
+                                  const BdrvChildRole *child_role)
 {
     BdrvChild *child = g_new(BdrvChild, 1);
     *child = (BdrvChild) {
-        .bs     = NULL,
+        .bs     = child_bs,
         .name   = g_strdup(child_name),
         .role   = child_role,
-        .opaque = opaque,
     };
 
-    bdrv_replace_child(child, child_bs);
+    QLIST_INSERT_HEAD(&child_bs->parents, child, next_parent);
 
     return child;
 }
 
-BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
-                             BlockDriverState *child_bs,
-                             const char *child_name,
-                             const BdrvChildRole *child_role)
+static BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
+                                    BlockDriverState *child_bs,
+                                    const char *child_name,
+                                    const BdrvChildRole *child_role)
 {
-    BdrvChild *child = bdrv_root_attach_child(child_bs, child_name, child_role,
-                                              parent_bs);
+    BdrvChild *child = bdrv_root_attach_child(child_bs, child_name, child_role);
     QLIST_INSERT_HEAD(&parent_bs->children, child, next);
     return child;
 }
@@ -1225,9 +1192,7 @@ static void bdrv_detach_child(BdrvChild *child)
         QLIST_REMOVE(child, next);
         child->next.le_prev = NULL;
     }
-
-    bdrv_replace_child(child, NULL);
-
+    QLIST_REMOVE(child, next_parent);
     g_free(child->name);
     g_free(child);
 }
@@ -1254,27 +1219,6 @@ void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
     bdrv_root_unref_child(child);
 }
 
-
-static void bdrv_parent_cb_change_media(BlockDriverState *bs, bool load)
-{
-    BdrvChild *c;
-    QLIST_FOREACH(c, &bs->parents, next_parent) {
-        if (c->role->change_media) {
-            c->role->change_media(c, load);
-        }
-    }
-}
-
-static void bdrv_parent_cb_resize(BlockDriverState *bs)
-{
-    BdrvChild *c;
-    QLIST_FOREACH(c, &bs->parents, next_parent) {
-        if (c->role->resize) {
-            c->role->resize(c);
-        }
-    }
-}
-
 /*
  * Sets the backing file link of a BDS. A new reference is created; callers
  * which don't need their own reference any more must call bdrv_unref().
@@ -1381,13 +1325,14 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
         qdict_put(options, "driver", qstring_from_str(bs->backing_format));
     }
 
-    backing_hd = bdrv_open_inherit(*backing_filename ? backing_filename : NULL,
-                                   reference, options, 0, bs, &child_backing,
-                                   errp);
-    if (!backing_hd) {
+    backing_hd = NULL;
+    ret = bdrv_open_inherit(&backing_hd,
+                            *backing_filename ? backing_filename : NULL,
+                            reference, options, 0, bs, &child_backing,
+                            errp);
+    if (ret < 0) {
         bs->open_flags |= BDRV_O_NO_BACKING;
         error_prepend(errp, "Could not open backing file: ");
-        ret = -EINVAL;
         goto free_exit;
     }
 
@@ -1427,6 +1372,7 @@ BdrvChild *bdrv_open_child(const char *filename,
     BdrvChild *c = NULL;
     BlockDriverState *bs;
     QDict *image_options;
+    int ret;
     char *bdref_key_dot;
     const char *reference;
 
@@ -1446,9 +1392,10 @@ BdrvChild *bdrv_open_child(const char *filename,
         goto done;
     }
 
-    bs = bdrv_open_inherit(filename, reference, image_options, 0,
-                           parent, child_role, errp);
-    if (!bs) {
+    bs = NULL;
+    ret = bdrv_open_inherit(&bs, filename, reference, image_options, 0,
+                            parent, child_role, errp);
+    if (ret < 0) {
         goto done;
     }
 
@@ -1459,16 +1406,15 @@ done:
     return c;
 }
 
-static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
-                                                   int flags,
-                                                   QDict *snapshot_options,
-                                                   Error **errp)
+static int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags,
+                                     QDict *snapshot_options, Error **errp)
 {
     /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
     char *tmp_filename = g_malloc0(PATH_MAX + 1);
     int64_t total_size;
     QemuOpts *opts = NULL;
     BlockDriverState *bs_snapshot;
+    Error *local_err = NULL;
     int ret;
 
     /* if snapshot, we create a temporary backing file and open it
@@ -1477,6 +1423,7 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
     /* Get the required size from the image */
     total_size = bdrv_getlength(bs);
     if (total_size < 0) {
+        ret = total_size;
         error_setg_errno(errp, -total_size, "Could not get image size");
         goto out;
     }
@@ -1507,26 +1454,22 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
     qdict_put(snapshot_options, "driver",
               qstring_from_str("qcow2"));
 
-    bs_snapshot = bdrv_open(NULL, NULL, snapshot_options, flags, errp);
+    bs_snapshot = bdrv_new();
+
+    ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
+                    flags, &local_err);
     snapshot_options = NULL;
-    if (!bs_snapshot) {
-        ret = -EINVAL;
+    if (ret < 0) {
+        error_propagate(errp, local_err);
         goto out;
     }
 
-    /* bdrv_append() consumes a strong reference to bs_snapshot (i.e. it will
-     * call bdrv_unref() on it), so in order to be able to return one, we have
-     * to increase bs_snapshot's refcount here */
-    bdrv_ref(bs_snapshot);
     bdrv_append(bs_snapshot, bs);
 
-    g_free(tmp_filename);
-    return bs_snapshot;
-
 out:
     QDECREF(snapshot_options);
     g_free(tmp_filename);
-    return NULL;
+    return ret;
 }
 
 /*
@@ -1544,12 +1487,10 @@ out:
  * should be opened. If specified, neither options nor a filename may be given,
  * nor can an existing BDS be reused (that is, *pbs has to be NULL).
  */
-static BlockDriverState *bdrv_open_inherit(const char *filename,
-                                           const char *reference,
-                                           QDict *options, int flags,
-                                           BlockDriverState *parent,
-                                           const BdrvChildRole *child_role,
-                                           Error **errp)
+static int bdrv_open_inherit(BlockDriverState **pbs, const char *filename,
+                             const char *reference, QDict *options, int flags,
+                             BlockDriverState *parent,
+                             const BdrvChildRole *child_role, Error **errp)
 {
     int ret;
     BdrvChild *file = NULL;
@@ -1561,6 +1502,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
     QDict *snapshot_options = NULL;
     int snapshot_flags = 0;
 
+    assert(pbs);
     assert(!child_role || !flags);
     assert(!child_role == !parent);
 
@@ -1568,22 +1510,39 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
         bool options_non_empty = options ? qdict_size(options) : false;
         QDECREF(options);
 
+        if (*pbs) {
+            error_setg(errp, "Cannot reuse an existing BDS when referencing "
+                       "another block device");
+            return -EINVAL;
+        }
+
         if (filename || options_non_empty) {
             error_setg(errp, "Cannot reference an existing block device with "
                        "additional options or a new filename");
-            return NULL;
+            return -EINVAL;
         }
 
         bs = bdrv_lookup_bs(reference, reference, errp);
         if (!bs) {
-            return NULL;
+            return -ENODEV;
+        }
+
+        if (bs->throttle_state) {
+            error_setg(errp, "Cannot reference an existing block device for "
+                       "which I/O throttling is enabled");
+            return -EINVAL;
         }
 
         bdrv_ref(bs);
-        return bs;
+        *pbs = bs;
+        return 0;
     }
 
-    bs = bdrv_new();
+    if (*pbs) {
+        bs = *pbs;
+    } else {
+        bs = bdrv_new();
+    }
 
     /* NULL means an empty set of options */
     if (options == NULL) {
@@ -1593,6 +1552,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
     /* json: syntax counts as explicit options, as if in the QDict */
     parse_json_protocol(options, &filename, &local_err);
     if (local_err) {
+        ret = -EINVAL;
         goto fail;
     }
 
@@ -1619,6 +1579,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
         drv = bdrv_find_format(drvname);
         if (!drv) {
             error_setg(errp, "Unknown driver: '%s'", drvname);
+            ret = -EINVAL;
             goto fail;
         }
     }
@@ -1648,6 +1609,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
         file = bdrv_open_child(filename, options, "file", bs,
                                &child_file, true, &local_err);
         if (local_err) {
+            ret = -EINVAL;
             goto fail;
         }
     }
@@ -1655,7 +1617,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
     /* Image format probing */
     bs->probed = !drv;
     if (!drv && file) {
-        ret = find_image_format(file, filename, &drv, &local_err);
+        ret = find_image_format(file->bs, filename, &drv, &local_err);
         if (ret < 0) {
             goto fail;
         }
@@ -1674,6 +1636,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
         qdict_put(options, "driver", qstring_from_str(drv->format_name));
     } else if (!drv) {
         error_setg(errp, "Must specify either driver or file");
+        ret = -EINVAL;
         goto fail;
     }
 
@@ -1716,40 +1679,38 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
                        drv->format_name, entry->key);
         }
 
+        ret = -EINVAL;
         goto close_and_fail;
     }
 
     if (!bdrv_key_required(bs)) {
-        bdrv_parent_cb_change_media(bs, true);
+        if (bs->blk) {
+            blk_dev_change_media_cb(bs->blk, true);
+        }
     } else if (!runstate_check(RUN_STATE_PRELAUNCH)
                && !runstate_check(RUN_STATE_INMIGRATE)
                && !runstate_check(RUN_STATE_PAUSED)) { /* HACK */
         error_setg(errp,
                    "Guest must be stopped for opening of encrypted image");
+        ret = -EBUSY;
         goto close_and_fail;
     }
 
     QDECREF(options);
+    *pbs = bs;
 
     /* For snapshot=on, create a temporary qcow2 overlay. bs points to the
      * temporary snapshot afterwards. */
     if (snapshot_flags) {
-        BlockDriverState *snapshot_bs;
-        snapshot_bs = bdrv_append_temp_snapshot(bs, snapshot_flags,
-                                                snapshot_options, &local_err);
+        ret = bdrv_append_temp_snapshot(bs, snapshot_flags, snapshot_options,
+                                        &local_err);
         snapshot_options = NULL;
         if (local_err) {
             goto close_and_fail;
         }
-        /* We are not going to return bs but the overlay on top of it
-         * (snapshot_bs); thus, we have to drop the strong reference to bs
-         * (which we obtained by calling bdrv_new()). bs will not be deleted,
-         * though, because the overlay still has a reference to it. */
-        bdrv_unref(bs);
-        bs = snapshot_bs;
     }
 
-    return bs;
+    return 0;
 
 fail:
     if (file != NULL) {
@@ -1760,22 +1721,36 @@ fail:
     QDECREF(bs->options);
     QDECREF(options);
     bs->options = NULL;
-    bdrv_unref(bs);
-    error_propagate(errp, local_err);
-    return NULL;
+    if (!*pbs) {
+        /* If *pbs is NULL, a new BDS has been created in this function and
+           needs to be freed now. Otherwise, it does not need to be closed,
+           since it has not really been opened yet. */
+        bdrv_unref(bs);
+    }
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
+    return ret;
 
 close_and_fail:
-    bdrv_unref(bs);
+    /* See fail path, but now the BDS has to be always closed */
+    if (*pbs) {
+        bdrv_close(bs);
+    } else {
+        bdrv_unref(bs);
+    }
     QDECREF(snapshot_options);
     QDECREF(options);
-    error_propagate(errp, local_err);
-    return NULL;
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
+    return ret;
 }
 
-BlockDriverState *bdrv_open(const char *filename, const char *reference,
-                            QDict *options, int flags, Error **errp)
+int bdrv_open(BlockDriverState **pbs, const char *filename,
+              const char *reference, QDict *options, int flags, Error **errp)
 {
-    return bdrv_open_inherit(filename, reference, options, flags, NULL,
+    return bdrv_open_inherit(pbs, filename, reference, options, flags, NULL,
                              NULL, errp);
 }
 
@@ -2149,7 +2124,11 @@ static void bdrv_close(BlockDriverState *bs)
     BdrvAioNotifier *ban, *ban_next;
 
     assert(!bs->job);
-    assert(!bs->refcnt);
+
+    /* Disable I/O limits and drain all pending throttled requests */
+    if (bs->throttle_state) {
+        bdrv_io_limits_disable(bs);
+    }
 
     bdrv_drained_begin(bs); /* complete I/O */
     bdrv_flush(bs);
@@ -2158,6 +2137,10 @@ static void bdrv_close(BlockDriverState *bs)
     bdrv_release_named_dirty_bitmaps(bs);
     assert(QLIST_EMPTY(&bs->dirty_bitmaps));
 
+    if (bs->blk) {
+        blk_dev_change_media_cb(bs->blk, false);
+    }
+
     if (bs->drv) {
         BdrvChild *child, *next;
 
@@ -2186,9 +2169,10 @@ static void bdrv_close(BlockDriverState *bs)
         bs->backing_file[0] = '\0';
         bs->backing_format[0] = '\0';
         bs->total_sectors = 0;
-        bs->encrypted = false;
-        bs->valid_key = false;
-        bs->sg = false;
+        bs->encrypted = 0;
+        bs->valid_key = 0;
+        bs->sg = 0;
+        bs->zero_beyond_eof = false;
         QDECREF(bs->options);
         QDECREF(bs->explicit_options);
         bs->options = NULL;
@@ -2205,7 +2189,8 @@ static void bdrv_close(BlockDriverState *bs)
 
 void bdrv_close_all(void)
 {
-    block_job_cancel_sync_all();
+    BlockDriverState *bs;
+    AioContext *aio_context;
 
     /* Drop references from requests still in flight, such as canceled block
      * jobs whose AIO context has not been polled yet */
@@ -2214,36 +2199,74 @@ void bdrv_close_all(void)
     blk_remove_all_bs();
     blockdev_close_all_bdrv_states();
 
-    assert(QTAILQ_EMPTY(&all_bdrv_states));
+    /* Cancel all block jobs */
+    while (!QTAILQ_EMPTY(&all_bdrv_states)) {
+        QTAILQ_FOREACH(bs, &all_bdrv_states, bs_list) {
+            aio_context = bdrv_get_aio_context(bs);
+
+            aio_context_acquire(aio_context);
+            if (bs->job) {
+                block_job_cancel_sync(bs->job);
+                aio_context_release(aio_context);
+                break;
+            }
+            aio_context_release(aio_context);
+        }
+
+        /* All the remaining BlockDriverStates are referenced directly or
+         * indirectly from block jobs, so there needs to be at least one BDS
+         * directly used by a block job */
+        assert(bs);
+    }
+}
+
+/* Fields that need to stay with the top-level BDS */
+static void bdrv_move_feature_fields(BlockDriverState *bs_dest,
+                                     BlockDriverState *bs_src)
+{
+    /* move some fields that need to stay attached to the device */
 }
 
 static void change_parent_backing_link(BlockDriverState *from,
                                        BlockDriverState *to)
 {
-    BdrvChild *c, *next, *to_c;
+    BdrvChild *c, *next;
 
-    QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
-        if (c->role == &child_backing) {
-            /* @from is generally not allowed to be a backing file, except for
-             * when @to is the overlay. In that case, @from may not be replaced
-             * by @to as @to's backing node. */
-            QLIST_FOREACH(to_c, &to->children, next) {
-                if (to_c == c) {
-                    break;
-                }
-            }
-            if (to_c) {
-                continue;
-            }
-        }
+    if (from->blk) {
+        /* FIXME We bypass blk_set_bs(), so we need to make these updates
+         * manually. The root problem is not in this change function, but the
+         * existence of BlockDriverState.blk. */
+        to->blk = from->blk;
+        from->blk = NULL;
+    }
 
+    QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
         assert(c->role != &child_backing);
+        c->bs = to;
+        QLIST_REMOVE(c, next_parent);
+        QLIST_INSERT_HEAD(&to->parents, c, next_parent);
         bdrv_ref(to);
-        bdrv_replace_child(c, to);
         bdrv_unref(from);
     }
 }
 
+static void swap_feature_fields(BlockDriverState *bs_top,
+                                BlockDriverState *bs_new)
+{
+    BlockDriverState tmp;
+
+    bdrv_move_feature_fields(&tmp, bs_top);
+    bdrv_move_feature_fields(bs_top, bs_new);
+    bdrv_move_feature_fields(bs_new, &tmp);
+
+    assert(!bs_new->throttle_state);
+    if (bs_top->throttle_state) {
+        assert(bs_top->io_limits_enabled);
+        bdrv_io_limits_enable(bs_new, throttle_group_get_name(bs_top));
+        bdrv_io_limits_disable(bs_top);
+    }
+}
+
 /*
  * Add new bs contents at the top of an image chain while the chain is
  * live, while keeping required fields on the top layer.
@@ -2266,8 +2289,11 @@ void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top)
     assert(!bdrv_requests_pending(bs_new));
 
     bdrv_ref(bs_top);
-
     change_parent_backing_link(bs_top, bs_new);
+
+    /* Some fields always stay on top of the backing file chain */
+    swap_feature_fields(bs_top, bs_new);
+
     bdrv_set_backing_hd(bs_new, bs_top);
     bdrv_unref(bs_top);
 
@@ -2283,8 +2309,26 @@ void bdrv_replace_in_backing_chain(BlockDriverState *old, BlockDriverState *new)
 
     bdrv_ref(old);
 
+    if (old->blk) {
+        /* As long as these fields aren't in BlockBackend, but in the top-level
+         * BlockDriverState, it's not possible for a BDS to have two BBs.
+         *
+         * We really want to copy the fields from old to new, but we go for a
+         * swap instead so that pointers aren't duplicated and cause trouble.
+         * (Also, bdrv_swap() used to do the same.) */
+        assert(!new->blk);
+        swap_feature_fields(old, new);
+    }
     change_parent_backing_link(old, new);
 
+    /* Change backing files if a previously independent node is added to the
+     * chain. For active commit, we replace top by its own (indirect) backing
+     * file and don't do anything here so we don't build a loop. */
+    if (new->backing == NULL && !bdrv_chain_contains(backing_bs(old), new)) {
+        bdrv_set_backing_hd(new, backing_bs(old));
+        bdrv_set_backing_hd(old, NULL);
+    }
+
     bdrv_unref(old);
 }
 
@@ -2325,6 +2369,116 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix)
     return bs->drv->bdrv_check(bs, res, fix);
 }
 
+#define COMMIT_BUF_SECTORS 2048
+
+/* commit COW file into the raw image */
+int bdrv_commit(BlockDriverState *bs)
+{
+    BlockDriver *drv = bs->drv;
+    int64_t sector, total_sectors, length, backing_length;
+    int n, ro, open_flags;
+    int ret = 0;
+    uint8_t *buf = NULL;
+
+    if (!drv)
+        return -ENOMEDIUM;
+
+    if (!bs->backing) {
+        return -ENOTSUP;
+    }
+
+    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT_SOURCE, NULL) ||
+        bdrv_op_is_blocked(bs->backing->bs, BLOCK_OP_TYPE_COMMIT_TARGET, NULL)) {
+        return -EBUSY;
+    }
+
+    ro = bs->backing->bs->read_only;
+    open_flags =  bs->backing->bs->open_flags;
+
+    if (ro) {
+        if (bdrv_reopen(bs->backing->bs, open_flags | BDRV_O_RDWR, NULL)) {
+            return -EACCES;
+        }
+    }
+
+    length = bdrv_getlength(bs);
+    if (length < 0) {
+        ret = length;
+        goto ro_cleanup;
+    }
+
+    backing_length = bdrv_getlength(bs->backing->bs);
+    if (backing_length < 0) {
+        ret = backing_length;
+        goto ro_cleanup;
+    }
+
+    /* If our top snapshot is larger than the backing file image,
+     * grow the backing file image if possible.  If not possible,
+     * we must return an error */
+    if (length > backing_length) {
+        ret = bdrv_truncate(bs->backing->bs, length);
+        if (ret < 0) {
+            goto ro_cleanup;
+        }
+    }
+
+    total_sectors = length >> BDRV_SECTOR_BITS;
+
+    /* qemu_try_blockalign() for bs will choose an alignment that works for
+     * bs->backing->bs as well, so no need to compare the alignment manually. */
+    buf = qemu_try_blockalign(bs, COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
+    if (buf == NULL) {
+        ret = -ENOMEM;
+        goto ro_cleanup;
+    }
+
+    for (sector = 0; sector < total_sectors; sector += n) {
+        ret = bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n);
+        if (ret < 0) {
+            goto ro_cleanup;
+        }
+        if (ret) {
+            ret = bdrv_read(bs, sector, buf, n);
+            if (ret < 0) {
+                goto ro_cleanup;
+            }
+
+            ret = bdrv_write(bs->backing->bs, sector, buf, n);
+            if (ret < 0) {
+                goto ro_cleanup;
+            }
+        }
+    }
+
+    if (drv->bdrv_make_empty) {
+        ret = drv->bdrv_make_empty(bs);
+        if (ret < 0) {
+            goto ro_cleanup;
+        }
+        bdrv_flush(bs);
+    }
+
+    /*
+     * Make sure all data we wrote to the backing device is actually
+     * stable on disk.
+     */
+    if (bs->backing) {
+        bdrv_flush(bs->backing->bs);
+    }
+
+    ret = 0;
+ro_cleanup:
+    qemu_vfree(buf);
+
+    if (ro) {
+        /* ignoring error return here */
+        bdrv_reopen(bs->backing->bs, open_flags & ~BDRV_O_RDWR, NULL);
+    }
+
+    return ret;
+}
+
 /*
  * Return values:
  * 0        - success
@@ -2473,8 +2627,9 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset)
     if (ret == 0) {
         ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
         bdrv_dirty_bitmap_truncate(bs);
-        bdrv_parent_cb_resize(bs);
-        ++bs->write_gen;
+        if (bs->blk) {
+            blk_dev_resize_cb(bs->blk);
+        }
     }
     return ret;
 }
@@ -2537,30 +2692,30 @@ void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
     *nb_sectors_ptr = nb_sectors < 0 ? 0 : nb_sectors;
 }
 
-bool bdrv_is_read_only(BlockDriverState *bs)
+int bdrv_is_read_only(BlockDriverState *bs)
 {
     return bs->read_only;
 }
 
-bool bdrv_is_sg(BlockDriverState *bs)
+int bdrv_is_sg(BlockDriverState *bs)
 {
     return bs->sg;
 }
 
-bool bdrv_is_encrypted(BlockDriverState *bs)
+int bdrv_is_encrypted(BlockDriverState *bs)
 {
     if (bs->backing && bs->backing->bs->encrypted) {
-        return true;
+        return 1;
     }
     return bs->encrypted;
 }
 
-bool bdrv_key_required(BlockDriverState *bs)
+int bdrv_key_required(BlockDriverState *bs)
 {
     BdrvChild *backing = bs->backing;
 
     if (backing && backing->bs->encrypted && !backing->bs->valid_key) {
-        return true;
+        return 1;
     }
     return (bs->encrypted && !bs->valid_key);
 }
@@ -2582,11 +2737,13 @@ int bdrv_set_key(BlockDriverState *bs, const char *key)
     }
     ret = bs->drv->bdrv_set_key(bs, key);
     if (ret < 0) {
-        bs->valid_key = false;
+        bs->valid_key = 0;
     } else if (!bs->valid_key) {
-        /* call the change callback now, we skipped it on open */
-        bs->valid_key = true;
-        bdrv_parent_cb_change_media(bs, true);
+        bs->valid_key = 1;
+        if (bs->blk) {
+            /* call the change callback now, we skipped it on open */
+            blk_dev_change_media_cb(bs->blk, true);
+        }
     }
     return ret;
 }
@@ -2753,33 +2910,34 @@ BlockDriverState *bdrv_next_node(BlockDriverState *bs)
     return QTAILQ_NEXT(bs, node_list);
 }
 
-const char *bdrv_get_node_name(const BlockDriverState *bs)
-{
-    return bs->node_name;
-}
-
-const char *bdrv_get_parent_name(const BlockDriverState *bs)
+/* Iterates over all top-level BlockDriverStates, i.e. BDSs that are owned by
+ * the monitor or attached to a BlockBackend */
+BlockDriverState *bdrv_next(BlockDriverState *bs)
 {
-    BdrvChild *c;
-    const char *name;
-
-    /* If multiple parents have a name, just pick the first one. */
-    QLIST_FOREACH(c, &bs->parents, next_parent) {
-        if (c->role->get_name) {
-            name = c->role->get_name(c);
-            if (name && *name) {
-                return name;
-            }
+    if (!bs || bs->blk) {
+        bs = blk_next_root_bs(bs);
+        if (bs) {
+            return bs;
         }
     }
 
-    return NULL;
+    /* Ignore all BDSs that are attached to a BlockBackend here; they have been
+     * handled by the above block already */
+    do {
+        bs = bdrv_next_monitor_owned(bs);
+    } while (bs && bs->blk);
+    return bs;
+}
+
+const char *bdrv_get_node_name(const BlockDriverState *bs)
+{
+    return bs->node_name;
 }
 
 /* TODO check what callers really want: bs->node_name or blk_name() */
 const char *bdrv_get_device_name(const BlockDriverState *bs)
 {
-    return bdrv_get_parent_name(bs) ?: "";
+    return bs->blk ? blk_name(bs->blk) : "";
 }
 
 /* This can be used to identify nodes that might not have a device
@@ -2788,7 +2946,7 @@ const char *bdrv_get_device_name(const BlockDriverState *bs)
  * absent, then this returns an empty (non-null) string. */
 const char *bdrv_get_device_or_node_name(const BlockDriverState *bs)
 {
-    return bdrv_get_parent_name(bs) ?: bs->node_name;
+    return bs->blk ? blk_name(bs->blk) : bs->node_name;
 }
 
 int bdrv_get_flags(BlockDriverState *bs)
@@ -2837,7 +2995,7 @@ bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs)
 {
     BlockDriverInfo bdi;
 
-    if (!(bs->open_flags & BDRV_O_UNMAP)) {
+    if (bs->backing || !(bs->open_flags & BDRV_O_UNMAP)) {
         return false;
     }
 
@@ -3043,7 +3201,6 @@ void bdrv_init_with_whitelist(void)
 
 void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
 {
-    BdrvChild *child;
     Error *local_err = NULL;
     int ret;
 
@@ -3058,20 +3215,13 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
 
     if (bs->drv->bdrv_invalidate_cache) {
         bs->drv->bdrv_invalidate_cache(bs, &local_err);
-        if (local_err) {
-            bs->open_flags |= BDRV_O_INACTIVE;
-            error_propagate(errp, local_err);
-            return;
-        }
+    } else if (bs->file) {
+        bdrv_invalidate_cache(bs->file->bs, &local_err);
     }
-
-    QLIST_FOREACH(child, &bs->children, next) {
-        bdrv_invalidate_cache(child->bs, &local_err);
-        if (local_err) {
-            bs->open_flags |= BDRV_O_INACTIVE;
-            error_propagate(errp, local_err);
-            return;
-        }
+    if (local_err) {
+        bs->open_flags |= BDRV_O_INACTIVE;
+        error_propagate(errp, local_err);
+        return;
     }
 
     ret = refresh_total_sectors(bs, bs->total_sectors);
@@ -3084,11 +3234,10 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
 
 void bdrv_invalidate_cache_all(Error **errp)
 {
-    BlockDriverState *bs;
+    BlockDriverState *bs = NULL;
     Error *local_err = NULL;
-    BdrvNextIterator it;
 
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+    while ((bs = bdrv_next(bs)) != NULL) {
         AioContext *aio_context = bdrv_get_aio_context(bs);
 
         aio_context_acquire(aio_context);
@@ -3101,62 +3250,38 @@ void bdrv_invalidate_cache_all(Error **errp)
     }
 }
 
-static int bdrv_inactivate_recurse(BlockDriverState *bs,
-                                   bool setting_flag)
+static int bdrv_inactivate(BlockDriverState *bs)
 {
-    BdrvChild *child;
     int ret;
 
-    if (!setting_flag && bs->drv->bdrv_inactivate) {
+    if (bs->drv->bdrv_inactivate) {
         ret = bs->drv->bdrv_inactivate(bs);
         if (ret < 0) {
             return ret;
         }
     }
 
-    QLIST_FOREACH(child, &bs->children, next) {
-        ret = bdrv_inactivate_recurse(child->bs, setting_flag);
-        if (ret < 0) {
-            return ret;
-        }
-    }
-
-    if (setting_flag) {
-        bs->open_flags |= BDRV_O_INACTIVE;
-    }
+    bs->open_flags |= BDRV_O_INACTIVE;
     return 0;
 }
 
 int bdrv_inactivate_all(void)
 {
     BlockDriverState *bs = NULL;
-    BdrvNextIterator it;
-    int ret = 0;
-    int pass;
+    int ret;
 
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
-        aio_context_acquire(bdrv_get_aio_context(bs));
-    }
+    while ((bs = bdrv_next(bs)) != NULL) {
+        AioContext *aio_context = bdrv_get_aio_context(bs);
 
-    /* We do two passes of inactivation. The first pass calls to drivers'
-     * .bdrv_inactivate callbacks recursively so all cache is flushed to disk;
-     * the second pass sets the BDRV_O_INACTIVE flag so that no further write
-     * is allowed. */
-    for (pass = 0; pass < 2; pass++) {
-        for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
-            ret = bdrv_inactivate_recurse(bs, pass);
-            if (ret < 0) {
-                goto out;
-            }
+        aio_context_acquire(aio_context);
+        ret = bdrv_inactivate(bs);
+        aio_context_release(aio_context);
+        if (ret < 0) {
+            return ret;
         }
     }
 
-out:
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
-        aio_context_release(bdrv_get_aio_context(bs));
-    }
-
-    return ret;
+    return 0;
 }
 
 /**************************************************************/
@@ -3436,10 +3561,11 @@ void bdrv_img_create(const char *filename, const char *fmt,
                           qstring_from_str(backing_fmt));
             }
 
-            bs = bdrv_open(full_backing, NULL, backing_options, back_flags,
-                           &local_err);
+            bs = NULL;
+            ret = bdrv_open(&bs, full_backing, NULL, backing_options,
+                            back_flags, &local_err);
             g_free(full_backing);
-            if (!bs) {
+            if (ret < 0) {
                 goto out;
             }
             size = bdrv_getlength(bs);
@@ -3484,7 +3610,9 @@ void bdrv_img_create(const char *filename, const char *fmt,
 out:
     qemu_opts_del(opts);
     qemu_opts_free(create_opts);
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
 }
 
 AioContext *bdrv_get_aio_context(BlockDriverState *bs)
@@ -3492,40 +3620,29 @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs)
     return bs->aio_context;
 }
 
-static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban)
-{
-    QLIST_REMOVE(ban, list);
-    g_free(ban);
-}
-
 void bdrv_detach_aio_context(BlockDriverState *bs)
 {
-    BdrvAioNotifier *baf, *baf_tmp;
-    BdrvChild *child;
+    BdrvAioNotifier *baf;
 
     if (!bs->drv) {
         return;
     }
 
-    assert(!bs->walking_aio_notifiers);
-    bs->walking_aio_notifiers = true;
-    QLIST_FOREACH_SAFE(baf, &bs->aio_notifiers, list, baf_tmp) {
-        if (baf->deleted) {
-            bdrv_do_remove_aio_context_notifier(baf);
-        } else {
-            baf->detach_aio_context(baf->opaque);
-        }
+    QLIST_FOREACH(baf, &bs->aio_notifiers, list) {
+        baf->detach_aio_context(baf->opaque);
     }
-    /* Never mind iterating again to check for ->deleted.  bdrv_close() will
-     * remove remaining aio notifiers if we aren't called again.
-     */
-    bs->walking_aio_notifiers = false;
 
+    if (bs->throttle_state) {
+        throttle_timers_detach_aio_context(&bs->throttle_timers);
+    }
     if (bs->drv->bdrv_detach_aio_context) {
         bs->drv->bdrv_detach_aio_context(bs);
     }
-    QLIST_FOREACH(child, &bs->children, next) {
-        bdrv_detach_aio_context(child->bs);
+    if (bs->file) {
+        bdrv_detach_aio_context(bs->file->bs);
+    }
+    if (bs->backing) {
+        bdrv_detach_aio_context(bs->backing->bs);
     }
 
     bs->aio_context = NULL;
@@ -3534,8 +3651,7 @@ void bdrv_detach_aio_context(BlockDriverState *bs)
 void bdrv_attach_aio_context(BlockDriverState *bs,
                              AioContext *new_context)
 {
-    BdrvAioNotifier *ban, *ban_tmp;
-    BdrvChild *child;
+    BdrvAioNotifier *ban;
 
     if (!bs->drv) {
         return;
@@ -3543,23 +3659,22 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
 
     bs->aio_context = new_context;
 
-    QLIST_FOREACH(child, &bs->children, next) {
-        bdrv_attach_aio_context(child->bs, new_context);
+    if (bs->backing) {
+        bdrv_attach_aio_context(bs->backing->bs, new_context);
+    }
+    if (bs->file) {
+        bdrv_attach_aio_context(bs->file->bs, new_context);
     }
     if (bs->drv->bdrv_attach_aio_context) {
         bs->drv->bdrv_attach_aio_context(bs, new_context);
     }
+    if (bs->throttle_state) {
+        throttle_timers_attach_aio_context(&bs->throttle_timers, new_context);
+    }
 
-    assert(!bs->walking_aio_notifiers);
-    bs->walking_aio_notifiers = true;
-    QLIST_FOREACH_SAFE(ban, &bs->aio_notifiers, list, ban_tmp) {
-        if (ban->deleted) {
-            bdrv_do_remove_aio_context_notifier(ban);
-        } else {
-            ban->attached_aio_context(new_context, ban->opaque);
-        }
+    QLIST_FOREACH(ban, &bs->aio_notifiers, list) {
+        ban->attached_aio_context(new_context, ban->opaque);
     }
-    bs->walking_aio_notifiers = false;
 }
 
 void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
@@ -3601,14 +3716,11 @@ void bdrv_remove_aio_context_notifier(BlockDriverState *bs,
     QLIST_FOREACH_SAFE(ban, &bs->aio_notifiers, list, ban_next) {
         if (ban->attached_aio_context == attached_aio_context &&
             ban->detach_aio_context   == detach_aio_context   &&
-            ban->opaque               == opaque               &&
-            ban->deleted              == false)
+            ban->opaque               == opaque)
         {
-            if (bs->walking_aio_notifiers) {
-                ban->deleted = true;
-            } else {
-                bdrv_do_remove_aio_context_notifier(ban);
-            }
+            QLIST_REMOVE(ban, list);
+            g_free(ban);
+
             return;
         }
     }
@@ -3664,11 +3776,10 @@ bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
  */
 bool bdrv_is_first_non_filter(BlockDriverState *candidate)
 {
-    BlockDriverState *bs;
-    BdrvNextIterator it;
+    BlockDriverState *bs = NULL;
 
     /* walk down the bs forest recursively */
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+    while ((bs = bdrv_next(bs)) != NULL) {
         bool perm;
 
         /* try to recurse in this top level bs */
@@ -3870,52 +3981,3 @@ void bdrv_refresh_filename(BlockDriverState *bs)
         QDECREF(json);
     }
 }
-
-/*
- * Hot add/remove a BDS's child. So the user can take a child offline when
- * it is broken and take a new child online
- */
-void bdrv_add_child(BlockDriverState *parent_bs, BlockDriverState *child_bs,
-                    Error **errp)
-{
-
-    if (!parent_bs->drv || !parent_bs->drv->bdrv_add_child) {
-        error_setg(errp, "The node %s does not support adding a child",
-                   bdrv_get_device_or_node_name(parent_bs));
-        return;
-    }
-
-    if (!QLIST_EMPTY(&child_bs->parents)) {
-        error_setg(errp, "The node %s already has a parent",
-                   child_bs->node_name);
-        return;
-    }
-
-    parent_bs->drv->bdrv_add_child(parent_bs, child_bs, errp);
-}
-
-void bdrv_del_child(BlockDriverState *parent_bs, BdrvChild *child, Error **errp)
-{
-    BdrvChild *tmp;
-
-    if (!parent_bs->drv || !parent_bs->drv->bdrv_del_child) {
-        error_setg(errp, "The node %s does not support removing a child",
-                   bdrv_get_device_or_node_name(parent_bs));
-        return;
-    }
-
-    QLIST_FOREACH(tmp, &parent_bs->children, next) {
-        if (tmp == child) {
-            break;
-        }
-    }
-
-    if (!tmp) {
-        error_setg(errp, "The node %s does not have a child named %s",
-                   bdrv_get_device_or_node_name(parent_bs),
-                   bdrv_get_device_or_node_name(child->bs));
-        return;
-    }
-
-    parent_bs->drv->bdrv_del_child(parent_bs, child, errp);
-}
index 2593a2f..44a5416 100644 (file)
@@ -9,7 +9,7 @@ block-obj-y += block-backend.o snapshot.o qapi.o
 block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o
 block-obj-$(CONFIG_POSIX) += raw-posix.o
 block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
-block-obj-y += null.o mirror.o commit.o io.o
+block-obj-y += null.o mirror.o io.o
 block-obj-y += throttle-groups.o
 
 block-obj-y += nbd.o nbd-client.o sheepdog.o
@@ -26,6 +26,7 @@ block-obj-y += write-threshold.o
 block-obj-y += crypto.o
 
 common-obj-y += stream.o
+common-obj-y += commit.o
 common-obj-y += backup.o
 
 iscsi.o-cflags     := $(LIBISCSI_CFLAGS)
index 37b8aca..b9f5e69 100644 (file)
@@ -974,9 +974,11 @@ err_exit2:
 
 static int64_t qemu_archipelago_getlength(BlockDriverState *bs)
 {
+    int64_t ret;
     BDRVArchipelagoState *s = bs->opaque;
 
-    return archipelago_volume_info(s);
+    ret = archipelago_volume_info(s);
+    return ret;
 }
 
 static int qemu_archipelago_truncate(BlockDriverState *bs, int64_t offset)
index 2c05323..370c285 100644 (file)
@@ -36,7 +36,7 @@ typedef struct CowRequest {
 
 typedef struct BackupBlockJob {
     BlockJob common;
-    BlockBackend *target;
+    BlockDriverState *target;
     /* bitmap for sync=incremental */
     BdrvDirtyBitmap *sync_bitmap;
     MirrorSyncMode sync_mode;
@@ -47,7 +47,6 @@ typedef struct BackupBlockJob {
     uint64_t sectors_read;
     unsigned long *done_bitmap;
     int64_t cluster_size;
-    NotifierWithReturn before_write;
     QLIST_HEAD(, CowRequest) inflight_reqs;
 } BackupBlockJob;
 
@@ -94,12 +93,12 @@ static void cow_request_end(CowRequest *req)
     qemu_co_queue_restart_all(&req->wait_queue);
 }
 
-static int coroutine_fn backup_do_cow(BackupBlockJob *job,
+static int coroutine_fn backup_do_cow(BlockDriverState *bs,
                                       int64_t sector_num, int nb_sectors,
                                       bool *error_is_read,
                                       bool is_write_notifier)
 {
-    BlockBackend *blk = job->common.blk;
+    BackupBlockJob *job = (BackupBlockJob *)bs->job;
     CowRequest cow_request;
     struct iovec iov;
     QEMUIOVector bounce_qiov;
@@ -132,15 +131,20 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
                 start * sectors_per_cluster);
 
         if (!bounce_buffer) {
-            bounce_buffer = blk_blockalign(blk, job->cluster_size);
+            bounce_buffer = qemu_blockalign(bs, job->cluster_size);
         }
         iov.iov_base = bounce_buffer;
         iov.iov_len = n * BDRV_SECTOR_SIZE;
         qemu_iovec_init_external(&bounce_qiov, &iov, 1);
 
-        ret = blk_co_preadv(blk, start * job->cluster_size,
-                            bounce_qiov.size, &bounce_qiov,
-                            is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0);
+        if (is_write_notifier) {
+            ret = bdrv_co_readv_no_serialising(bs,
+                                           start * sectors_per_cluster,
+                                           n, &bounce_qiov);
+        } else {
+            ret = bdrv_co_readv(bs, start * sectors_per_cluster, n,
+                                &bounce_qiov);
+        }
         if (ret < 0) {
             trace_backup_do_cow_read_fail(job, start, ret);
             if (error_is_read) {
@@ -150,11 +154,13 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
         }
 
         if (buffer_is_zero(iov.iov_base, iov.iov_len)) {
-            ret = blk_co_pwrite_zeroes(job->target, start * job->cluster_size,
-                                       bounce_qiov.size, BDRV_REQ_MAY_UNMAP);
+            ret = bdrv_co_write_zeroes(job->target,
+                                       start * sectors_per_cluster,
+                                       n, BDRV_REQ_MAY_UNMAP);
         } else {
-            ret = blk_co_pwritev(job->target, start * job->cluster_size,
-                                 bounce_qiov.size, &bounce_qiov, 0);
+            ret = bdrv_co_writev(job->target,
+                                 start * sectors_per_cluster, n,
+                                 &bounce_qiov);
         }
         if (ret < 0) {
             trace_backup_do_cow_write_fail(job, start, ret);
@@ -191,16 +197,14 @@ static int coroutine_fn backup_before_write_notify(
         NotifierWithReturn *notifier,
         void *opaque)
 {
-    BackupBlockJob *job = container_of(notifier, BackupBlockJob, before_write);
     BdrvTrackedRequest *req = opaque;
     int64_t sector_num = req->offset >> BDRV_SECTOR_BITS;
     int nb_sectors = req->bytes >> BDRV_SECTOR_BITS;
 
-    assert(req->bs == blk_bs(job->common.blk));
     assert((req->offset & (BDRV_SECTOR_SIZE - 1)) == 0);
     assert((req->bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
 
-    return backup_do_cow(job, sector_num, nb_sectors, NULL, true);
+    return backup_do_cow(req->bs, sector_num, nb_sectors, NULL, true);
 }
 
 static void backup_set_speed(BlockJob *job, int64_t speed, Error **errp)
@@ -214,10 +218,19 @@ static void backup_set_speed(BlockJob *job, int64_t speed, Error **errp)
     ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE, SLICE_TIME);
 }
 
+static void backup_iostatus_reset(BlockJob *job)
+{
+    BackupBlockJob *s = container_of(job, BackupBlockJob, common);
+
+    if (s->target->blk) {
+        blk_iostatus_reset(s->target->blk);
+    }
+}
+
 static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
 {
     BdrvDirtyBitmap *bm;
-    BlockDriverState *bs = blk_bs(job->common.blk);
+    BlockDriverState *bs = job->common.bs;
 
     if (ret < 0 || block_job_is_cancelled(&job->common)) {
         /* Merge the successor back into the parent, delete nothing. */
@@ -246,31 +259,24 @@ static void backup_abort(BlockJob *job)
     }
 }
 
-static void backup_attached_aio_context(BlockJob *job, AioContext *aio_context)
-{
-    BackupBlockJob *s = container_of(job, BackupBlockJob, common);
-
-    blk_set_aio_context(s->target, aio_context);
-}
-
 static const BlockJobDriver backup_job_driver = {
-    .instance_size          = sizeof(BackupBlockJob),
-    .job_type               = BLOCK_JOB_TYPE_BACKUP,
-    .set_speed              = backup_set_speed,
-    .commit                 = backup_commit,
-    .abort                  = backup_abort,
-    .attached_aio_context   = backup_attached_aio_context,
+    .instance_size  = sizeof(BackupBlockJob),
+    .job_type       = BLOCK_JOB_TYPE_BACKUP,
+    .set_speed      = backup_set_speed,
+    .iostatus_reset = backup_iostatus_reset,
+    .commit         = backup_commit,
+    .abort          = backup_abort,
 };
 
 static BlockErrorAction backup_error_action(BackupBlockJob *job,
                                             bool read, int error)
 {
     if (read) {
-        return block_job_error_action(&job->common, job->on_source_error,
-                                      true, error);
+        return block_job_error_action(&job->common, job->common.bs,
+                                      job->on_source_error, true, error);
     } else {
-        return block_job_error_action(&job->common, job->on_target_error,
-                                      false, error);
+        return block_job_error_action(&job->common, job->target,
+                                      job->on_target_error, false, error);
     }
 }
 
@@ -283,7 +289,7 @@ static void backup_complete(BlockJob *job, void *opaque)
     BackupBlockJob *s = container_of(job, BackupBlockJob, common);
     BackupCompleteData *data = opaque;
 
-    blk_unref(s->target);
+    bdrv_unref(s->target);
 
     block_job_completed(job, data->ret);
     g_free(data);
@@ -325,6 +331,7 @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
     int64_t end;
     int64_t last_cluster = -1;
     int64_t sectors_per_cluster = cluster_size_sectors(job);
+    BlockDriverState *bs = job->common.bs;
     HBitmapIter hbi;
 
     granularity = bdrv_dirty_bitmap_granularity(job->sync_bitmap);
@@ -346,7 +353,7 @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
                 if (yield_and_check(job)) {
                     return ret;
                 }
-                ret = backup_do_cow(job, cluster * sectors_per_cluster,
+                ret = backup_do_cow(bs, cluster * sectors_per_cluster,
                                     sectors_per_cluster, &error_is_read,
                                     false);
                 if ((ret < 0) &&
@@ -379,8 +386,12 @@ static void coroutine_fn backup_run(void *opaque)
 {
     BackupBlockJob *job = opaque;
     BackupCompleteData *data;
-    BlockDriverState *bs = blk_bs(job->common.blk);
-    BlockBackend *target = job->target;
+    BlockDriverState *bs = job->common.bs;
+    BlockDriverState *target = job->target;
+    BlockdevOnError on_target_error = job->on_target_error;
+    NotifierWithReturn before_write = {
+        .notify = backup_before_write_notify,
+    };
     int64_t start, end;
     int64_t sectors_per_cluster = cluster_size_sectors(job);
     int ret = 0;
@@ -393,14 +404,20 @@ static void coroutine_fn backup_run(void *opaque)
 
     job->done_bitmap = bitmap_new(end);
 
-    job->before_write.notify = backup_before_write_notify;
-    bdrv_add_before_write_notifier(bs, &job->before_write);
+    if (target->blk) {
+        blk_set_on_error(target->blk, on_target_error, on_target_error);
+        blk_iostatus_enable(target->blk);
+    }
+
+    bdrv_add_before_write_notifier(bs, &before_write);
 
     if (job->sync_mode == MIRROR_SYNC_MODE_NONE) {
         while (!block_job_is_cancelled(&job->common)) {
             /* Yield until the job is cancelled.  We just let our before_write
              * notify callback service CoW requests. */
-            block_job_yield(&job->common);
+            job->common.busy = false;
+            qemu_coroutine_yield();
+            job->common.busy = true;
         }
     } else if (job->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
         ret = backup_run_incremental(job);
@@ -444,7 +461,7 @@ static void coroutine_fn backup_run(void *opaque)
                 }
             }
             /* FULL sync mode we copy the whole drive. */
-            ret = backup_do_cow(job, start * sectors_per_cluster,
+            ret = backup_do_cow(bs, start * sectors_per_cluster,
                                 sectors_per_cluster, &error_is_read, false);
             if (ret < 0) {
                 /* Depending on error action, fail now or retry cluster */
@@ -460,23 +477,26 @@ static void coroutine_fn backup_run(void *opaque)
         }
     }
 
-    notifier_with_return_remove(&job->before_write);
+    notifier_with_return_remove(&before_write);
 
     /* wait until pending backup_do_cow() calls have completed */
     qemu_co_rwlock_wrlock(&job->flush_rwlock);
     qemu_co_rwlock_unlock(&job->flush_rwlock);
     g_free(job->done_bitmap);
 
-    bdrv_op_unblock_all(blk_bs(target), job->common.blocker);
+    if (target->blk) {
+        blk_iostatus_disable(target->blk);
+    }
+    bdrv_op_unblock_all(target, job->common.blocker);
 
     data = g_malloc(sizeof(*data));
     data->ret = ret;
     block_job_defer_to_main_loop(&job->common, backup_complete, data);
 }
 
-void backup_start(const char *job_id, BlockDriverState *bs,
-                  BlockDriverState *target, int64_t speed,
-                  MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
+void backup_start(BlockDriverState *bs, BlockDriverState *target,
+                  int64_t speed, MirrorSyncMode sync_mode,
+                  BdrvDirtyBitmap *sync_bitmap,
                   BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
                   BlockCompletionFunc *cb, void *opaque,
@@ -489,12 +509,20 @@ void backup_start(const char *job_id, BlockDriverState *bs,
 
     assert(bs);
     assert(target);
+    assert(cb);
 
     if (bs == target) {
         error_setg(errp, "Source and target cannot be the same");
         return;
     }
 
+    if ((on_source_error == BLOCKDEV_ON_ERROR_STOP ||
+         on_source_error == BLOCKDEV_ON_ERROR_ENOSPC) &&
+        (!bs->blk || !blk_iostatus_is_enabled(bs->blk))) {
+        error_setg(errp, QERR_INVALID_PARAMETER, "on-source-error");
+        return;
+    }
+
     if (!bdrv_is_inserted(bs)) {
         error_setg(errp, "Device is not inserted: %s",
                    bdrv_get_device_name(bs));
@@ -541,17 +569,14 @@ void backup_start(const char *job_id, BlockDriverState *bs,
         goto error;
     }
 
-    job = block_job_create(job_id, &backup_job_driver, bs, speed,
-                           cb, opaque, errp);
+    job = block_job_create(&backup_job_driver, bs, speed, cb, opaque, errp);
     if (!job) {
         goto error;
     }
 
-    job->target = blk_new();
-    blk_insert_bs(job->target, target);
-
     job->on_source_error = on_source_error;
     job->on_target_error = on_target_error;
+    job->target = target;
     job->sync_mode = sync_mode;
     job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ?
                        sync_bitmap : NULL;
@@ -559,7 +584,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,
     /* If there is no backing file on the target, we cannot rely on COW if our
      * backup cluster size is smaller than the target cluster size. Even for
      * targets with a backing file, try to avoid COW if possible. */
-    ret = bdrv_get_info(target, &bdi);
+    ret = bdrv_get_info(job->target, &bdi);
     if (ret < 0 && !target->backing) {
         error_setg_errno(errp, -ret,
             "Couldn't determine the cluster size of the target image, "
@@ -576,9 +601,9 @@ void backup_start(const char *job_id, BlockDriverState *bs,
 
     bdrv_op_block_all(target, job->common.blocker);
     job->common.len = len;
-    job->common.co = qemu_coroutine_create(backup_run, job);
+    job->common.co = qemu_coroutine_create(backup_run);
     block_job_txn_add_job(txn, &job->common);
-    qemu_coroutine_enter(job->common.co);
+    qemu_coroutine_enter(job->common.co, job);
     return;
 
  error:
@@ -586,7 +611,6 @@ void backup_start(const char *job_id, BlockDriverState *bs,
         bdrv_reclaim_dirty_bitmap(bs, sync_bitmap, NULL);
     }
     if (job) {
-        blk_unref(job->target);
         block_job_unref(&job->common);
     }
 }
index d5db166..20d25bd 100644 (file)
 typedef struct BDRVBlkdebugState {
     int state;
     int new_state;
-    int align;
-
-    /* For blkdebug_refresh_filename() */
-    char *config_file;
 
     QLIST_HEAD(, BlkdebugRule) rules[BLKDBG__MAX];
     QSIMPLEQ_HEAD(, BlkdebugRule) active_rules;
@@ -354,6 +350,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
     BDRVBlkdebugState *s = bs->opaque;
     QemuOpts *opts;
     Error *local_err = NULL;
+    const char *config;
     uint64_t align;
     int ret;
 
@@ -366,8 +363,8 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
     }
 
     /* Read rules from config file or command line options */
-    s->config_file = g_strdup(qemu_opt_get(opts, "config"));
-    ret = read_config(s, s->config_file, options, errp);
+    config = qemu_opt_get(opts, "config");
+    ret = read_config(s, config, options, errp);
     if (ret) {
         goto out;
     }
@@ -385,10 +382,10 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
     }
 
     /* Set request alignment */
-    align = qemu_opt_get_size(opts, "align", 0);
-    if (align < INT_MAX && is_power_of_2(align)) {
-        s->align = align;
-    } else if (align) {
+    align = qemu_opt_get_size(opts, "align", bs->request_alignment);
+    if (align > 0 && align < INT_MAX && !(align & (align - 1))) {
+        bs->request_alignment = align;
+    } else {
         error_setg(errp, "Invalid alignment");
         ret = -EINVAL;
         goto fail_unref;
@@ -400,9 +397,6 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
 fail_unref:
     bdrv_unref_child(bs, bs->file);
 out:
-    if (ret < 0) {
-        g_free(s->config_file);
-    }
     qemu_opts_del(opts);
     return ret;
 }
@@ -462,7 +456,7 @@ static BlockAIOCB *blkdebug_aio_readv(BlockDriverState *bs,
         return inject_error(bs, cb, opaque, rule);
     }
 
-    return bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors,
+    return bdrv_aio_readv(bs->file->bs, sector_num, qiov, nb_sectors,
                           cb, opaque);
 }
 
@@ -485,7 +479,7 @@ static BlockAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
         return inject_error(bs, cb, opaque, rule);
     }
 
-    return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors,
+    return bdrv_aio_writev(bs->file->bs, sector_num, qiov, nb_sectors,
                            cb, opaque);
 }
 
@@ -520,8 +514,6 @@ static void blkdebug_close(BlockDriverState *bs)
             remove_rule(rule);
         }
     }
-
-    g_free(s->config_file);
 }
 
 static void suspend_request(BlockDriverState *bs, BlkdebugRule *rule)
@@ -628,7 +620,7 @@ static int blkdebug_debug_resume(BlockDriverState *bs, const char *tag)
 
     QLIST_FOREACH_SAFE(r, &s->suspended_reqs, next, next) {
         if (!strcmp(r->tag, tag)) {
-            qemu_coroutine_enter(r->co);
+            qemu_coroutine_enter(r->co, NULL);
             return 0;
         }
     }
@@ -654,7 +646,7 @@ static int blkdebug_debug_remove_breakpoint(BlockDriverState *bs,
     }
     QLIST_FOREACH_SAFE(r, &s->suspended_reqs, next, r_next) {
         if (!strcmp(r->tag, tag)) {
-            qemu_coroutine_enter(r->co);
+            qemu_coroutine_enter(r->co, NULL);
             ret = 0;
         }
     }
@@ -686,7 +678,6 @@ static int blkdebug_truncate(BlockDriverState *bs, int64_t offset)
 
 static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
 {
-    BDRVBlkdebugState *s = bs->opaque;
     QDict *opts;
     const QDictEntry *e;
     bool force_json = false;
@@ -708,7 +699,8 @@ static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
 
     if (!force_json && bs->file->bs->exact_filename[0]) {
         snprintf(bs->exact_filename, sizeof(bs->exact_filename),
-                 "blkdebug:%s:%s", s->config_file ?: "",
+                 "blkdebug:%s:%s",
+                 qdict_get_try_str(options, "config") ?: "",
                  bs->file->bs->exact_filename);
     }
 
@@ -728,15 +720,6 @@ static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
     bs->full_open_options = opts;
 }
 
-static void blkdebug_refresh_limits(BlockDriverState *bs, Error **errp)
-{
-    BDRVBlkdebugState *s = bs->opaque;
-
-    if (s->align) {
-        bs->bl.request_alignment = s->align;
-    }
-}
-
 static int blkdebug_reopen_prepare(BDRVReopenState *reopen_state,
                                    BlockReopenQueue *queue, Error **errp)
 {
@@ -755,7 +738,6 @@ static BlockDriver bdrv_blkdebug = {
     .bdrv_getlength         = blkdebug_getlength,
     .bdrv_truncate          = blkdebug_truncate,
     .bdrv_refresh_filename  = blkdebug_refresh_filename,
-    .bdrv_refresh_limits    = blkdebug_refresh_limits,
 
     .bdrv_aio_readv         = blkdebug_aio_readv,
     .bdrv_aio_writev        = blkdebug_aio_writev,
index 30f9d5f..42f1813 100755 (executable)
@@ -65,7 +65,7 @@ static int64_t blkreplay_getlength(BlockDriverState *bs)
 static void blkreplay_bh_cb(void *opaque)
 {
     Request *req = opaque;
-    qemu_coroutine_enter(req->co);
+    qemu_coroutine_enter(req->co, NULL);
     qemu_bh_delete(req->bh);
     g_free(req);
 }
@@ -81,44 +81,44 @@ static void block_request_create(uint64_t reqid, BlockDriverState *bs,
     replay_block_event(req->bh, reqid);
 }
 
-static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs,
-    uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags)
+static int coroutine_fn blkreplay_co_readv(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
     uint64_t reqid = request_id++;
-    int ret = bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
+    int ret = bdrv_co_readv(bs->file->bs, sector_num, nb_sectors, qiov);
     block_request_create(reqid, bs, qemu_coroutine_self());
     qemu_coroutine_yield();
 
     return ret;
 }
 
-static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs,
-    uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags)
+static int coroutine_fn blkreplay_co_writev(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
     uint64_t reqid = request_id++;
-    int ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
+    int ret = bdrv_co_writev(bs->file->bs, sector_num, nb_sectors, qiov);
     block_request_create(reqid, bs, qemu_coroutine_self());
     qemu_coroutine_yield();
 
     return ret;
 }
 
-static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs,
-    int64_t offset, int count, BdrvRequestFlags flags)
+static int coroutine_fn blkreplay_co_write_zeroes(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, BdrvRequestFlags flags)
 {
     uint64_t reqid = request_id++;
-    int ret = bdrv_co_pwrite_zeroes(bs->file, offset, count, flags);
+    int ret = bdrv_co_write_zeroes(bs->file->bs, sector_num, nb_sectors, flags);
     block_request_create(reqid, bs, qemu_coroutine_self());
     qemu_coroutine_yield();
 
     return ret;
 }
 
-static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,
-                                              int64_t offset, int count)
+static int coroutine_fn blkreplay_co_discard(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors)
 {
     uint64_t reqid = request_id++;
-    int ret = bdrv_co_pdiscard(bs->file->bs, offset, count);
+    int ret = bdrv_co_discard(bs->file->bs, sector_num, nb_sectors);
     block_request_create(reqid, bs, qemu_coroutine_self());
     qemu_coroutine_yield();
 
@@ -144,11 +144,11 @@ static BlockDriver bdrv_blkreplay = {
     .bdrv_close             = blkreplay_close,
     .bdrv_getlength         = blkreplay_getlength,
 
-    .bdrv_co_preadv         = blkreplay_co_preadv,
-    .bdrv_co_pwritev        = blkreplay_co_pwritev,
+    .bdrv_co_readv          = blkreplay_co_readv,
+    .bdrv_co_writev         = blkreplay_co_writev,
 
-    .bdrv_co_pwrite_zeroes  = blkreplay_co_pwrite_zeroes,
-    .bdrv_co_pdiscard       = blkreplay_co_pdiscard,
+    .bdrv_co_write_zeroes   = blkreplay_co_write_zeroes,
+    .bdrv_co_discard        = blkreplay_co_discard,
     .bdrv_co_flush          = blkreplay_co_flush,
 };
 
index da62d75..9414b7a 100644 (file)
@@ -247,9 +247,9 @@ static BlockAIOCB *blkverify_aio_readv(BlockDriverState *bs,
     qemu_iovec_init(&acb->raw_qiov, acb->qiov->niov);
     qemu_iovec_clone(&acb->raw_qiov, qiov, acb->buf);
 
-    bdrv_aio_readv(s->test_file, sector_num, qiov, nb_sectors,
+    bdrv_aio_readv(s->test_file->bs, sector_num, qiov, nb_sectors,
                    blkverify_aio_cb, acb);
-    bdrv_aio_readv(bs->file, sector_num, &acb->raw_qiov, nb_sectors,
+    bdrv_aio_readv(bs->file->bs, sector_num, &acb->raw_qiov, nb_sectors,
                    blkverify_aio_cb, acb);
     return &acb->common;
 }
@@ -262,9 +262,9 @@ static BlockAIOCB *blkverify_aio_writev(BlockDriverState *bs,
     BlkverifyAIOCB *acb = blkverify_aio_get(bs, true, sector_num, qiov,
                                             nb_sectors, cb, opaque);
 
-    bdrv_aio_writev(s->test_file, sector_num, qiov, nb_sectors,
+    bdrv_aio_writev(s->test_file->bs, sector_num, qiov, nb_sectors,
                     blkverify_aio_cb, acb);
-    bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors,
+    bdrv_aio_writev(bs->file->bs, sector_num, qiov, nb_sectors,
                     blkverify_aio_cb, acb);
     return &acb->common;
 }
@@ -293,6 +293,22 @@ static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs,
     return bdrv_recurse_is_first_non_filter(s->test_file->bs, candidate);
 }
 
+/* Propagate AioContext changes to ->test_file */
+static void blkverify_detach_aio_context(BlockDriverState *bs)
+{
+    BDRVBlkverifyState *s = bs->opaque;
+
+    bdrv_detach_aio_context(s->test_file->bs);
+}
+
+static void blkverify_attach_aio_context(BlockDriverState *bs,
+                                         AioContext *new_context)
+{
+    BDRVBlkverifyState *s = bs->opaque;
+
+    bdrv_attach_aio_context(s->test_file->bs, new_context);
+}
+
 static void blkverify_refresh_filename(BlockDriverState *bs, QDict *options)
 {
     BDRVBlkverifyState *s = bs->opaque;
@@ -340,6 +356,9 @@ static BlockDriver bdrv_blkverify = {
     .bdrv_aio_writev                  = blkverify_aio_writev,
     .bdrv_aio_flush                   = blkverify_aio_flush,
 
+    .bdrv_attach_aio_context          = blkverify_attach_aio_context,
+    .bdrv_detach_aio_context          = blkverify_detach_aio_context,
+
     .is_filter                        = true,
     .bdrv_recurse_is_first_non_filter = blkverify_recurse_is_first_non_filter,
 };
index effa038..16c9d5e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * QEMU Block backends
  *
- * Copyright (C) 2014-2016 Red Hat, Inc.
+ * Copyright (C) 2014 Red Hat, Inc.
  *
  * Authors:
  *  Markus Armbruster <armbru@redhat.com>,
@@ -19,7 +19,6 @@
 #include "sysemu/sysemu.h"
 #include "qapi-event.h"
 #include "qemu/id.h"
-#include "trace.h"
 
 /* Number of coroutines to reserve per attached device model */
 #define COROUTINE_POOL_RESERVATION 64
@@ -35,7 +34,6 @@ struct BlockBackend {
     DriveInfo *legacy_dinfo;    /* null unless created by drive_new() */
     QTAILQ_ENTRY(BlockBackend) link;         /* for block_backends */
     QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */
-    BlockBackendPublic public;
 
     void *dev;                  /* attached device model, if any */
     /* TODO change to DeviceState when all users are qdevified */
@@ -76,7 +74,6 @@ static const AIOCBInfo block_backend_aiocb_info = {
 };
 
 static void drive_info_del(DriveInfo *dinfo);
-static BlockBackend *bdrv_first_blk(BlockDriverState *bs);
 
 /* All BlockBackends */
 static QTAILQ_HEAD(, BlockBackend) block_backends =
@@ -93,26 +90,9 @@ static void blk_root_inherit_options(int *child_flags, QDict *child_options,
     /* We're not supposed to call this function for root nodes */
     abort();
 }
-static void blk_root_drained_begin(BdrvChild *child);
-static void blk_root_drained_end(BdrvChild *child);
-
-static void blk_root_change_media(BdrvChild *child, bool load);
-static void blk_root_resize(BdrvChild *child);
-
-static const char *blk_root_get_name(BdrvChild *child)
-{
-    return blk_name(child->opaque);
-}
 
 static const BdrvChildRole child_root = {
-    .inherit_options    = blk_root_inherit_options,
-
-    .change_media       = blk_root_change_media,
-    .resize             = blk_root_resize,
-    .get_name           = blk_root_get_name,
-
-    .drained_begin      = blk_root_drained_begin,
-    .drained_end        = blk_root_drained_end,
+    .inherit_options = blk_root_inherit_options,
 };
 
 /*
@@ -120,26 +100,40 @@ static const BdrvChildRole child_root = {
  * Store an error through @errp on failure, unless it's null.
  * Return the new BlockBackend on success, null on failure.
  */
-BlockBackend *blk_new(void)
+BlockBackend *blk_new(Error **errp)
 {
     BlockBackend *blk;
 
     blk = g_new0(BlockBackend, 1);
     blk->refcnt = 1;
-    blk_set_enable_write_cache(blk, true);
-
-    qemu_co_queue_init(&blk->public.throttled_reqs[0]);
-    qemu_co_queue_init(&blk->public.throttled_reqs[1]);
-
     notifier_list_init(&blk->remove_bs_notifiers);
     notifier_list_init(&blk->insert_bs_notifiers);
-
     QTAILQ_INSERT_TAIL(&block_backends, blk, link);
     return blk;
 }
 
 /*
- * Creates a new BlockBackend, opens a new BlockDriverState, and connects both.
+ * Create a new BlockBackend with a new BlockDriverState attached.
+ * Otherwise just like blk_new(), which see.
+ */
+BlockBackend *blk_new_with_bs(Error **errp)
+{
+    BlockBackend *blk;
+    BlockDriverState *bs;
+
+    blk = blk_new(errp);
+    if (!blk) {
+        return NULL;
+    }
+
+    bs = bdrv_new_root();
+    blk->root = bdrv_root_attach_child(bs, "root", &child_root);
+    bs->blk = blk;
+    return blk;
+}
+
+/*
+ * Calls blk_new_with_bs() and then calls bdrv_open() on the BlockDriverState.
  *
  * Just as with bdrv_open(), after having called this function the reference to
  * @options belongs to the block layer (even on failure).
@@ -154,16 +148,21 @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
                            QDict *options, int flags, Error **errp)
 {
     BlockBackend *blk;
-    BlockDriverState *bs;
+    int ret;
 
-    blk = blk_new();
-    bs = bdrv_open(filename, reference, options, flags, errp);
-    if (!bs) {
+    blk = blk_new_with_bs(errp);
+    if (!blk) {
+        QDECREF(options);
+        return NULL;
+    }
+
+    ret = bdrv_open(&blk->root->bs, filename, reference, options, flags, errp);
+    if (ret < 0) {
         blk_unref(blk);
         return NULL;
     }
 
-    blk->root = bdrv_root_attach_child(bs, "root", &child_root, blk);
+    blk_set_enable_write_cache(blk, true);
 
     return blk;
 }
@@ -178,6 +177,10 @@ static void blk_delete(BlockBackend *blk)
     }
     assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers));
     assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers));
+    if (blk->root_state.throttle_state) {
+        g_free(blk->root_state.throttle_group);
+        throttle_group_unref(blk->root_state.throttle_state);
+    }
     QTAILQ_REMOVE(&block_backends, blk, link);
     drive_info_del(blk->legacy_dinfo);
     block_acct_cleanup(&blk->stats);
@@ -264,45 +267,28 @@ BlockBackend *blk_next(BlockBackend *blk)
                : QTAILQ_FIRST(&monitor_block_backends);
 }
 
-/* Iterates over all top-level BlockDriverStates, i.e. BDSs that are owned by
- * the monitor or attached to a BlockBackend */
-BlockDriverState *bdrv_next(BdrvNextIterator *it)
+/*
+ * Iterates over all BlockDriverStates which are attached to a BlockBackend.
+ * This function is for use by bdrv_next().
+ *
+ * @bs must be NULL or a BDS that is attached to a BB.
+ */
+BlockDriverState *blk_next_root_bs(BlockDriverState *bs)
 {
-    BlockDriverState *bs;
+    BlockBackend *blk;
 
-    /* First, return all root nodes of BlockBackends. In order to avoid
-     * returning a BDS twice when multiple BBs refer to it, we only return it
-     * if the BB is the first one in the parent list of the BDS. */
-    if (it->phase == BDRV_NEXT_BACKEND_ROOTS) {
-        do {
-            it->blk = blk_all_next(it->blk);
-            bs = it->blk ? blk_bs(it->blk) : NULL;
-        } while (it->blk && (bs == NULL || bdrv_first_blk(bs) != it->blk));
-
-        if (bs) {
-            return bs;
-        }
-        it->phase = BDRV_NEXT_MONITOR_OWNED;
+    if (bs) {
+        assert(bs->blk);
+        blk = bs->blk;
+    } else {
+        blk = NULL;
     }
 
-    /* Then return the monitor-owned BDSes without a BB attached. Ignore all
-     * BDSes that are attached to a BlockBackend here; they have been handled
-     * by the above block already */
     do {
-        it->bs = bdrv_next_monitor_owned(it->bs);
-        bs = it->bs;
-    } while (bs && bdrv_has_blk(bs));
-
-    return bs;
-}
-
-BlockDriverState *bdrv_first(BdrvNextIterator *it)
-{
-    *it = (BdrvNextIterator) {
-        .phase = BDRV_NEXT_BACKEND_ROOTS,
-    };
+        blk = blk_all_next(blk);
+    } while (blk && !blk->root);
 
-    return bdrv_next(it);
+    return blk ? blk->root->bs : NULL;
 }
 
 /*
@@ -389,26 +375,6 @@ BlockDriverState *blk_bs(BlockBackend *blk)
     return blk->root ? blk->root->bs : NULL;
 }
 
-static BlockBackend *bdrv_first_blk(BlockDriverState *bs)
-{
-    BdrvChild *child;
-    QLIST_FOREACH(child, &bs->parents, next_parent) {
-        if (child->role == &child_root) {
-            return child->opaque;
-        }
-    }
-
-    return NULL;
-}
-
-/*
- * Returns true if @bs has an associated BlockBackend.
- */
-bool bdrv_has_blk(BlockDriverState *bs)
-{
-    return bdrv_first_blk(bs) != NULL;
-}
-
 /*
  * Return @blk's DriveInfo if any, else null.
  */
@@ -445,33 +411,17 @@ BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
 }
 
 /*
- * Returns a pointer to the publicly accessible fields of @blk.
- */
-BlockBackendPublic *blk_get_public(BlockBackend *blk)
-{
-    return &blk->public;
-}
-
-/*
- * Returns a BlockBackend given the associated @public fields.
- */
-BlockBackend *blk_by_public(BlockBackendPublic *public)
-{
-    return container_of(public, BlockBackend, public);
-}
-
-/*
  * Disassociates the currently associated BlockDriverState from @blk.
  */
 void blk_remove_bs(BlockBackend *blk)
 {
+    assert(blk->root->bs->blk == blk);
+
     notifier_list_notify(&blk->remove_bs_notifiers, blk);
-    if (blk->public.throttle_state) {
-        throttle_timers_detach_aio_context(&blk->public.throttle_timers);
-    }
 
     blk_update_root_state(blk);
 
+    blk->root->bs->blk = NULL;
     bdrv_root_unref_child(blk->root);
     blk->root = NULL;
 }
@@ -481,14 +431,12 @@ void blk_remove_bs(BlockBackend *blk)
  */
 void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs)
 {
+    assert(!blk->root && !bs->blk);
     bdrv_ref(bs);
-    blk->root = bdrv_root_attach_child(bs, "root", &child_root, blk);
+    blk->root = bdrv_root_attach_child(bs, "root", &child_root);
+    bs->blk = blk;
 
     notifier_list_notify(&blk->insert_bs_notifiers, blk);
-    if (blk->public.throttle_state) {
-        throttle_timers_attach_aio_context(
-            &blk->public.throttle_timers, bdrv_get_aio_context(bs));
-    }
 }
 
 /*
@@ -577,11 +525,6 @@ void blk_dev_change_media_cb(BlockBackend *blk, bool load)
     }
 }
 
-static void blk_root_change_media(BdrvChild *child, bool load)
-{
-    blk_dev_change_media_cb(child->opaque, load);
-}
-
 /*
  * Does @blk's attached device model have removable media?
  * %true if no device model is attached.
@@ -636,10 +579,8 @@ bool blk_dev_is_medium_locked(BlockBackend *blk)
 /*
  * Notify @blk's attached device model of a backend size change.
  */
-static void blk_root_resize(BdrvChild *child)
+void blk_dev_resize_cb(BlockBackend *blk)
 {
-    BlockBackend *blk = child->opaque;
-
     if (blk->dev_ops && blk->dev_ops->resize_cb) {
         blk->dev_ops->resize_cb(blk->dev_opaque);
     }
@@ -742,50 +683,34 @@ static int blk_check_request(BlockBackend *blk, int64_t sector_num,
                                   nb_sectors * BDRV_SECTOR_SIZE);
 }
 
-int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
-                               unsigned int bytes, QEMUIOVector *qiov,
-                               BdrvRequestFlags flags)
+static int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
+                                      unsigned int bytes, QEMUIOVector *qiov,
+                                      BdrvRequestFlags flags)
 {
-    int ret;
-
-    trace_blk_co_preadv(blk, blk_bs(blk), offset, bytes, flags);
-
-    ret = blk_check_byte_request(blk, offset, bytes);
+    int ret = blk_check_byte_request(blk, offset, bytes);
     if (ret < 0) {
         return ret;
     }
 
-    /* throttling disk I/O */
-    if (blk->public.throttle_state) {
-        throttle_group_co_io_limits_intercept(blk, bytes, false);
-    }
-
-    return bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);
+    return bdrv_co_do_preadv(blk_bs(blk), offset, bytes, qiov, flags);
 }
 
-int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
-                                unsigned int bytes, QEMUIOVector *qiov,
-                                BdrvRequestFlags flags)
+static int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
+                                      unsigned int bytes, QEMUIOVector *qiov,
+                                      BdrvRequestFlags flags)
 {
     int ret;
 
-    trace_blk_co_pwritev(blk, blk_bs(blk), offset, bytes, flags);
-
     ret = blk_check_byte_request(blk, offset, bytes);
     if (ret < 0) {
         return ret;
     }
 
-    /* throttling disk I/O */
-    if (blk->public.throttle_state) {
-        throttle_group_co_io_limits_intercept(blk, bytes, true);
-    }
-
     if (!blk->enable_write_cache) {
         flags |= BDRV_REQ_FUA;
     }
 
-    return bdrv_co_pwritev(blk->root, offset, bytes, qiov, flags);
+    return bdrv_co_do_pwritev(blk_bs(blk), offset, bytes, qiov, flags);
 }
 
 typedef struct BlkRwCo {
@@ -836,8 +761,8 @@ static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf,
         .ret    = NOT_DONE,
     };
 
-    co = qemu_coroutine_create(co_entry, &rwco);
-    qemu_coroutine_enter(co);
+    co = qemu_coroutine_create(co_entry);
+    qemu_coroutine_enter(co, &rwco);
 
     aio_context = blk_get_aio_context(blk);
     while (rwco.ret == NOT_DONE) {
@@ -847,32 +772,55 @@ static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf,
     return rwco.ret;
 }
 
-int blk_pread_unthrottled(BlockBackend *blk, int64_t offset, uint8_t *buf,
-                          int count)
+static int blk_rw(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
+                  int nb_sectors, CoroutineEntry co_entry,
+                  BdrvRequestFlags flags)
 {
+    if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
+        return -EINVAL;
+    }
+
+    return blk_prw(blk, sector_num << BDRV_SECTOR_BITS, buf,
+                   nb_sectors << BDRV_SECTOR_BITS, co_entry, flags);
+}
+
+int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
+             int nb_sectors)
+{
+    return blk_rw(blk, sector_num, buf, nb_sectors, blk_read_entry, 0);
+}
+
+int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
+                         int nb_sectors)
+{
+    BlockDriverState *bs = blk_bs(blk);
+    bool enabled;
     int ret;
 
-    ret = blk_check_byte_request(blk, offset, count);
+    ret = blk_check_request(blk, sector_num, nb_sectors);
     if (ret < 0) {
         return ret;
     }
 
-    blk_root_drained_begin(blk->root);
-    ret = blk_pread(blk, offset, buf, count);
-    blk_root_drained_end(blk->root);
+    enabled = bs->io_limits_enabled;
+    bs->io_limits_enabled = false;
+    ret = blk_read(blk, sector_num, buf, nb_sectors);
+    bs->io_limits_enabled = enabled;
     return ret;
 }
 
-int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
-                      int count, BdrvRequestFlags flags)
+int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf,
+              int nb_sectors)
 {
-    return blk_prw(blk, offset, NULL, count, blk_write_entry,
-                   flags | BDRV_REQ_ZERO_WRITE);
+    return blk_rw(blk, sector_num, (uint8_t*) buf, nb_sectors,
+                  blk_write_entry, 0);
 }
 
-int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags)
+int blk_write_zeroes(BlockBackend *blk, int64_t sector_num,
+                     int nb_sectors, BdrvRequestFlags flags)
 {
-    return bdrv_make_zero(blk->root, flags);
+    return blk_rw(blk, sector_num, NULL, nb_sectors, blk_write_entry,
+                  flags | BDRV_REQ_ZERO_WRITE);
 }
 
 static void error_callback_bh(void *opaque)
@@ -950,8 +898,8 @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,
     acb->bh = NULL;
     acb->has_returned = false;
 
-    co = qemu_coroutine_create(co_entry, acb);
-    qemu_coroutine_enter(co);
+    co = qemu_coroutine_create(co_entry);
+    qemu_coroutine_enter(co, acb);
 
     acb->has_returned = true;
     if (acb->rwco.ret != NOT_DONE) {
@@ -984,12 +932,18 @@ static void blk_aio_write_entry(void *opaque)
     blk_aio_complete(acb);
 }
 
-BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
-                                  int count, BdrvRequestFlags flags,
-                                  BlockCompletionFunc *cb, void *opaque)
+BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t sector_num,
+                                 int nb_sectors, BdrvRequestFlags flags,
+                                 BlockCompletionFunc *cb, void *opaque)
 {
-    return blk_aio_prwv(blk, offset, count, NULL, blk_aio_write_entry,
-                        flags | BDRV_REQ_ZERO_WRITE, cb, opaque);
+    if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
+        return blk_abort_aio_request(blk, cb, opaque, -EINVAL);
+    }
+
+    return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS,
+                        nb_sectors << BDRV_SECTOR_BITS, NULL,
+                        blk_aio_write_entry, flags | BDRV_REQ_ZERO_WRITE,
+                        cb, opaque);
 }
 
 int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count)
@@ -1001,11 +955,9 @@ int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count)
     return count;
 }
 
-int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count,
-               BdrvRequestFlags flags)
+int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count)
 {
-    int ret = blk_prw(blk, offset, (void *) buf, count, blk_write_entry,
-                      flags);
+    int ret = blk_prw(blk, offset, (void*) buf, count, blk_write_entry, 0);
     if (ret < 0) {
         return ret;
     }
@@ -1039,20 +991,30 @@ int64_t blk_nb_sectors(BlockBackend *blk)
     return bdrv_nb_sectors(blk_bs(blk));
 }
 
-BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
-                           QEMUIOVector *qiov, BdrvRequestFlags flags,
-                           BlockCompletionFunc *cb, void *opaque)
+BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num,
+                          QEMUIOVector *iov, int nb_sectors,
+                          BlockCompletionFunc *cb, void *opaque)
 {
-    return blk_aio_prwv(blk, offset, qiov->size, qiov,
-                        blk_aio_read_entry, flags, cb, opaque);
+    if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
+        return blk_abort_aio_request(blk, cb, opaque, -EINVAL);
+    }
+
+    assert(nb_sectors << BDRV_SECTOR_BITS == iov->size);
+    return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS, iov->size, iov,
+                        blk_aio_read_entry, 0, cb, opaque);
 }
 
-BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
-                            QEMUIOVector *qiov, BdrvRequestFlags flags,
-                            BlockCompletionFunc *cb, void *opaque)
+BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t sector_num,
+                           QEMUIOVector *iov, int nb_sectors,
+                           BlockCompletionFunc *cb, void *opaque)
 {
-    return blk_aio_prwv(blk, offset, qiov->size, qiov,
-                        blk_aio_write_entry, flags, cb, opaque);
+    if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
+        return blk_abort_aio_request(blk, cb, opaque, -EINVAL);
+    }
+
+    assert(nb_sectors << BDRV_SECTOR_BITS == iov->size);
+    return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS, iov->size, iov,
+                        blk_aio_write_entry, 0, cb, opaque);
 }
 
 BlockAIOCB *blk_aio_flush(BlockBackend *blk,
@@ -1065,16 +1027,16 @@ BlockAIOCB *blk_aio_flush(BlockBackend *blk,
     return bdrv_aio_flush(blk_bs(blk), cb, opaque);
 }
 
-BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk,
-                             int64_t offset, int count,
-                             BlockCompletionFunc *cb, void *opaque)
+BlockAIOCB *blk_aio_discard(BlockBackend *blk,
+                            int64_t sector_num, int nb_sectors,
+                            BlockCompletionFunc *cb, void *opaque)
 {
-    int ret = blk_check_byte_request(blk, offset, count);
+    int ret = blk_check_request(blk, sector_num, nb_sectors);
     if (ret < 0) {
         return blk_abort_aio_request(blk, cb, opaque, ret);
     }
 
-    return bdrv_aio_pdiscard(blk_bs(blk), offset, count, cb, opaque);
+    return bdrv_aio_discard(blk_bs(blk), sector_num, nb_sectors, cb, opaque);
 }
 
 void blk_aio_cancel(BlockAIOCB *acb)
@@ -1087,6 +1049,20 @@ void blk_aio_cancel_async(BlockAIOCB *acb)
     bdrv_aio_cancel_async(acb);
 }
 
+int blk_aio_multiwrite(BlockBackend *blk, BlockRequest *reqs, int num_reqs)
+{
+    int i, ret;
+
+    for (i = 0; i < num_reqs; i++) {
+        ret = blk_check_request(blk, reqs[i].sector, reqs[i].nb_sectors);
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
+    return bdrv_aio_multiwrite(blk_bs(blk), reqs, num_reqs);
+}
+
 int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
 {
     if (!blk_is_available(blk)) {
@@ -1106,14 +1082,14 @@ BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
     return bdrv_aio_ioctl(blk_bs(blk), req, buf, cb, opaque);
 }
 
-int blk_co_pdiscard(BlockBackend *blk, int64_t offset, int count)
+int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors)
 {
-    int ret = blk_check_byte_request(blk, offset, count);
+    int ret = blk_check_request(blk, sector_num, nb_sectors);
     if (ret < 0) {
         return ret;
     }
 
-    return bdrv_co_pdiscard(blk_bs(blk), offset, count);
+    return bdrv_co_discard(blk_bs(blk), sector_num, nb_sectors);
 }
 
 int blk_co_flush(BlockBackend *blk)
@@ -1173,7 +1149,6 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
         return BLOCK_ERROR_ACTION_REPORT;
     case BLOCKDEV_ON_ERROR_IGNORE:
         return BLOCK_ERROR_ACTION_IGNORE;
-    case BLOCKDEV_ON_ERROR_AUTO:
     default:
         abort();
     }
@@ -1309,16 +1284,15 @@ int blk_get_flags(BlockBackend *blk)
     }
 }
 
-/* Returns the maximum transfer length, in bytes; guaranteed nonzero */
-uint32_t blk_get_max_transfer(BlockBackend *blk)
+int blk_get_max_transfer_length(BlockBackend *blk)
 {
     BlockDriverState *bs = blk_bs(blk);
-    uint32_t max = 0;
 
     if (bs) {
-        max = bs->bl.max_transfer;
+        return bs->bl.max_transfer_length;
+    } else {
+        return 0;
     }
-    return MIN_NON_ZERO(max, INT_MAX);
 }
 
 int blk_get_max_iov(BlockBackend *blk)
@@ -1401,14 +1375,7 @@ void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
     BlockDriverState *bs = blk_bs(blk);
 
     if (bs) {
-        if (blk->public.throttle_state) {
-            throttle_timers_detach_aio_context(&blk->public.throttle_timers);
-        }
         bdrv_set_aio_context(bs, new_context);
-        if (blk->public.throttle_state) {
-            throttle_timers_attach_aio_context(&blk->public.throttle_timers,
-                                               new_context);
-        }
     }
 }
 
@@ -1477,10 +1444,15 @@ void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
     return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque);
 }
 
-int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
-                                      int count, BdrvRequestFlags flags)
+int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t sector_num,
+                                     int nb_sectors, BdrvRequestFlags flags)
 {
-    return blk_co_pwritev(blk, offset, count, NULL,
+    if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
+        return -EINVAL;
+    }
+
+    return blk_co_pwritev(blk, sector_num << BDRV_SECTOR_BITS,
+                          nb_sectors << BDRV_SECTOR_BITS, NULL,
                           flags | BDRV_REQ_ZERO_WRITE);
 }
 
@@ -1504,14 +1476,14 @@ int blk_truncate(BlockBackend *blk, int64_t offset)
     return bdrv_truncate(blk_bs(blk), offset);
 }
 
-int blk_pdiscard(BlockBackend *blk, int64_t offset, int count)
+int blk_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors)
 {
-    int ret = blk_check_byte_request(blk, offset, count);
+    int ret = blk_check_request(blk, sector_num, nb_sectors);
     if (ret < 0) {
         return ret;
     }
 
-    return bdrv_pdiscard(blk_bs(blk), offset, count);
+    return bdrv_discard(blk_bs(blk), sector_num, nb_sectors);
 }
 
 int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
@@ -1573,6 +1545,19 @@ void blk_update_root_state(BlockBackend *blk)
     blk->root_state.open_flags    = blk->root->bs->open_flags;
     blk->root_state.read_only     = blk->root->bs->read_only;
     blk->root_state.detect_zeroes = blk->root->bs->detect_zeroes;
+
+    if (blk->root_state.throttle_group) {
+        g_free(blk->root_state.throttle_group);
+        throttle_group_unref(blk->root_state.throttle_state);
+    }
+    if (blk->root->bs->throttle_state) {
+        const char *name = throttle_group_get_name(blk->root->bs);
+        blk->root_state.throttle_group = g_strdup(name);
+        blk->root_state.throttle_state = throttle_group_incref(name);
+    } else {
+        blk->root_state.throttle_group = NULL;
+        blk->root_state.throttle_state = NULL;
+    }
 }
 
 /*
@@ -1583,6 +1568,9 @@ void blk_update_root_state(BlockBackend *blk)
 void blk_apply_root_state(BlockBackend *blk, BlockDriverState *bs)
 {
     bs->detect_zeroes = blk->root_state.detect_zeroes;
+    if (blk->root_state.throttle_group) {
+        bdrv_io_limits_enable(bs, blk->root_state.throttle_group);
+    }
 }
 
 /*
@@ -1645,62 +1633,3 @@ int blk_flush_all(void)
 
     return result;
 }
-
-
-/* throttling disk I/O limits */
-void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg)
-{
-    throttle_group_config(blk, cfg);
-}
-
-void blk_io_limits_disable(BlockBackend *blk)
-{
-    assert(blk->public.throttle_state);
-    bdrv_drained_begin(blk_bs(blk));
-    throttle_group_unregister_blk(blk);
-    bdrv_drained_end(blk_bs(blk));
-}
-
-/* should be called before blk_set_io_limits if a limit is set */
-void blk_io_limits_enable(BlockBackend *blk, const char *group)
-{
-    assert(!blk->public.throttle_state);
-    throttle_group_register_blk(blk, group);
-}
-
-void blk_io_limits_update_group(BlockBackend *blk, const char *group)
-{
-    /* this BB is not part of any group */
-    if (!blk->public.throttle_state) {
-        return;
-    }
-
-    /* this BB is a part of the same group than the one we want */
-    if (!g_strcmp0(throttle_group_get_name(blk), group)) {
-        return;
-    }
-
-    /* need to change the group this bs belong to */
-    blk_io_limits_disable(blk);
-    blk_io_limits_enable(blk, group);
-}
-
-static void blk_root_drained_begin(BdrvChild *child)
-{
-    BlockBackend *blk = child->opaque;
-
-    /* Note that blk->root may not be accessible here yet if we are just
-     * attaching to a BlockDriverState that is drained. Use child instead. */
-
-    if (blk->public.io_limits_disabled++ == 0) {
-        throttle_group_restart_blk(blk);
-    }
-}
-
-static void blk_root_drained_end(BdrvChild *child)
-{
-    BlockBackend *blk = child->opaque;
-
-    assert(blk->public.io_limits_disabled);
-    --blk->public.io_limits_disabled;
-}
index 8c9652e..af8b7ab 100644 (file)
@@ -27,7 +27,6 @@
 #include "qemu-common.h"
 #include "block/block_int.h"
 #include "qemu/module.h"
-#include "qemu/bswap.h"
 
 /**************************************************************/
 
@@ -104,9 +103,9 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
     struct bochs_header bochs;
     int ret;
 
-    bs->read_only = true; /* no write support yet */
+    bs->read_only = 1; // no write support yet
 
-    ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
+    ret = bdrv_pread(bs->file->bs, 0, &bochs, sizeof(bochs));
     if (ret < 0) {
         return ret;
     }
@@ -140,7 +139,7 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
         return -ENOMEM;
     }
 
-    ret = bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,
+    ret = bdrv_pread(bs->file->bs, le32_to_cpu(bochs.header), s->catalog_bitmap,
                      s->catalog_size * 4);
     if (ret < 0) {
         goto fail;
@@ -188,11 +187,6 @@ fail:
     return ret;
 }
 
-static void bochs_refresh_limits(BlockDriverState *bs, Error **errp)
-{
-    bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
-}
-
 static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
 {
     BDRVBochsState *s = bs->opaque;
@@ -214,7 +208,7 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
         (s->extent_blocks + s->bitmap_blocks));
 
     /* read in bitmap for current extent */
-    ret = bdrv_pread(bs->file, bitmap_offset + (extent_offset / 8),
+    ret = bdrv_pread(bs->file->bs, bitmap_offset + (extent_offset / 8),
                      &bitmap_entry, 1);
     if (ret < 0) {
         return ret;
@@ -227,52 +221,38 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
     return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
 }
 
-static int coroutine_fn
-bochs_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
-                QEMUIOVector *qiov, int flags)
+static int bochs_read(BlockDriverState *bs, int64_t sector_num,
+                    uint8_t *buf, int nb_sectors)
 {
-    BDRVBochsState *s = bs->opaque;
-    uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
-    int nb_sectors = bytes >> BDRV_SECTOR_BITS;
-    uint64_t bytes_done = 0;
-    QEMUIOVector local_qiov;
     int ret;
 
-    assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
-    assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
-
-    qemu_iovec_init(&local_qiov, qiov->niov);
-    qemu_co_mutex_lock(&s->lock);
-
     while (nb_sectors > 0) {
         int64_t block_offset = seek_to_sector(bs, sector_num);
         if (block_offset < 0) {
-            ret = block_offset;
-            goto fail;
-        }
-
-        qemu_iovec_reset(&local_qiov);
-        qemu_iovec_concat(&local_qiov, qiov, bytes_done, 512);
-
-        if (block_offset > 0) {
-            ret = bdrv_co_preadv(bs->file, block_offset, 512,
-                                 &local_qiov, 0);
+            return block_offset;
+        } else if (block_offset > 0) {
+            ret = bdrv_pread(bs->file->bs, block_offset, buf, 512);
             if (ret < 0) {
-                goto fail;
+                return ret;
             }
         } else {
-            qemu_iovec_memset(&local_qiov, 0, 0, 512);
+            memset(buf, 0, 512);
         }
         nb_sectors--;
         sector_num++;
-        bytes_done += 512;
+        buf += 512;
     }
+    return 0;
+}
 
-    ret = 0;
-fail:
+static coroutine_fn int bochs_co_read(BlockDriverState *bs, int64_t sector_num,
+                                      uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVBochsState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = bochs_read(bs, sector_num, buf, nb_sectors);
     qemu_co_mutex_unlock(&s->lock);
-    qemu_iovec_destroy(&local_qiov);
-
     return ret;
 }
 
@@ -287,8 +267,7 @@ static BlockDriver bdrv_bochs = {
     .instance_size     = sizeof(BDRVBochsState),
     .bdrv_probe                = bochs_probe,
     .bdrv_open         = bochs_open,
-    .bdrv_refresh_limits = bochs_refresh_limits,
-    .bdrv_co_preadv = bochs_co_preadv,
+    .bdrv_read          = bochs_co_read,
     .bdrv_close                = bochs_close,
 };
 
index 7b75f7e..a84f140 100644 (file)
@@ -26,7 +26,6 @@
 #include "qemu-common.h"
 #include "block/block_int.h"
 #include "qemu/module.h"
-#include "qemu/bswap.h"
 #include <zlib.h>
 
 /* Maximum compressed block size */
@@ -66,10 +65,10 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
     uint32_t offsets_size, max_compressed_block_size = 1, i;
     int ret;
 
-    bs->read_only = true;
+    bs->read_only = 1;
 
     /* read header */
-    ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
+    ret = bdrv_pread(bs->file->bs, 128, &s->block_size, 4);
     if (ret < 0) {
         return ret;
     }
@@ -95,7 +94,7 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
         return -EINVAL;
     }
 
-    ret = bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4);
+    ret = bdrv_pread(bs->file->bs, 128 + 4, &s->n_blocks, 4);
     if (ret < 0) {
         return ret;
     }
@@ -126,7 +125,7 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
         return -ENOMEM;
     }
 
-    ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size);
+    ret = bdrv_pread(bs->file->bs, 128 + 4 + 4, s->offsets, offsets_size);
     if (ret < 0) {
         goto fail;
     }
@@ -198,11 +197,6 @@ fail:
     return ret;
 }
 
-static void cloop_refresh_limits(BlockDriverState *bs, Error **errp)
-{
-    bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
-}
-
 static inline int cloop_read_block(BlockDriverState *bs, int block_num)
 {
     BDRVCloopState *s = bs->opaque;
@@ -211,7 +205,7 @@ static inline int cloop_read_block(BlockDriverState *bs, int block_num)
         int ret;
         uint32_t bytes = s->offsets[block_num + 1] - s->offsets[block_num];
 
-        ret = bdrv_pread(bs->file, s->offsets[block_num],
+        ret = bdrv_pread(bs->file->bs, s->offsets[block_num],
                          s->compressed_block, bytes);
         if (ret != bytes) {
             return -1;
@@ -235,38 +229,33 @@ static inline int cloop_read_block(BlockDriverState *bs, int block_num)
     return 0;
 }
 
-static int coroutine_fn
-cloop_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
-                QEMUIOVector *qiov, int flags)
+static int cloop_read(BlockDriverState *bs, int64_t sector_num,
+                    uint8_t *buf, int nb_sectors)
 {
     BDRVCloopState *s = bs->opaque;
-    uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
-    int nb_sectors = bytes >> BDRV_SECTOR_BITS;
-    int ret, i;
-
-    assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
-    assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
-
-    qemu_co_mutex_lock(&s->lock);
+    int i;
 
     for (i = 0; i < nb_sectors; i++) {
-        void *data;
         uint32_t sector_offset_in_block =
             ((sector_num + i) % s->sectors_per_block),
             block_num = (sector_num + i) / s->sectors_per_block;
         if (cloop_read_block(bs, block_num) != 0) {
-            ret = -EIO;
-            goto fail;
+            return -1;
         }
-
-        data = s->uncompressed_block + sector_offset_in_block * 512;
-        qemu_iovec_from_buf(qiov, i * 512, data, 512);
+        memcpy(buf + i * 512,
+            s->uncompressed_block + sector_offset_in_block * 512, 512);
     }
+    return 0;
+}
 
-    ret = 0;
-fail:
+static coroutine_fn int cloop_co_read(BlockDriverState *bs, int64_t sector_num,
+                                      uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVCloopState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = cloop_read(bs, sector_num, buf, nb_sectors);
     qemu_co_mutex_unlock(&s->lock);
-
     return ret;
 }
 
@@ -284,8 +273,7 @@ static BlockDriver bdrv_cloop = {
     .instance_size  = sizeof(BDRVCloopState),
     .bdrv_probe     = cloop_probe,
     .bdrv_open      = cloop_open,
-    .bdrv_refresh_limits = cloop_refresh_limits,
-    .bdrv_co_preadv = cloop_co_preadv,
+    .bdrv_read      = cloop_co_read,
     .bdrv_close     = cloop_close,
 };
 
index 553e18d..cba0e8c 100644 (file)
@@ -36,36 +36,28 @@ typedef struct CommitBlockJob {
     BlockJob common;
     RateLimit limit;
     BlockDriverState *active;
-    BlockBackend *top;
-    BlockBackend *base;
+    BlockDriverState *top;
+    BlockDriverState *base;
     BlockdevOnError on_error;
     int base_flags;
     int orig_overlay_flags;
     char *backing_file_str;
 } CommitBlockJob;
 
-static int coroutine_fn commit_populate(BlockBackend *bs, BlockBackend *base,
+static int coroutine_fn commit_populate(BlockDriverState *bs,
+                                        BlockDriverState *base,
                                         int64_t sector_num, int nb_sectors,
                                         void *buf)
 {
     int ret = 0;
-    QEMUIOVector qiov;
-    struct iovec iov = {
-        .iov_base = buf,
-        .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
-    };
 
-    qemu_iovec_init_external(&qiov, &iov, 1);
-
-    ret = blk_co_preadv(bs, sector_num * BDRV_SECTOR_SIZE,
-                        qiov.size, &qiov, 0);
-    if (ret < 0) {
+    ret = bdrv_read(bs, sector_num, buf, nb_sectors);
+    if (ret) {
         return ret;
     }
 
-    ret = blk_co_pwritev(base, sector_num * BDRV_SECTOR_SIZE,
-                         qiov.size, &qiov, 0);
-    if (ret < 0) {
+    ret = bdrv_write(base, sector_num, buf, nb_sectors);
+    if (ret) {
         return ret;
     }
 
@@ -81,8 +73,8 @@ static void commit_complete(BlockJob *job, void *opaque)
     CommitBlockJob *s = container_of(job, CommitBlockJob, common);
     CommitCompleteData *data = opaque;
     BlockDriverState *active = s->active;
-    BlockDriverState *top = blk_bs(s->top);
-    BlockDriverState *base = blk_bs(s->base);
+    BlockDriverState *top = s->top;
+    BlockDriverState *base = s->base;
     BlockDriverState *overlay_bs;
     int ret = data->ret;
 
@@ -102,8 +94,6 @@ static void commit_complete(BlockJob *job, void *opaque)
         bdrv_reopen(overlay_bs, s->orig_overlay_flags, NULL);
     }
     g_free(s->backing_file_str);
-    blk_unref(s->top);
-    blk_unref(s->base);
     block_job_completed(&s->common, ret);
     g_free(data);
 }
@@ -112,39 +102,42 @@ static void coroutine_fn commit_run(void *opaque)
 {
     CommitBlockJob *s = opaque;
     CommitCompleteData *data;
+    BlockDriverState *top = s->top;
+    BlockDriverState *base = s->base;
     int64_t sector_num, end;
-    uint64_t delay_ns = 0;
     int ret = 0;
     int n = 0;
     void *buf = NULL;
     int bytes_written = 0;
     int64_t base_len;
 
-    ret = s->common.len = blk_getlength(s->top);
+    ret = s->common.len = bdrv_getlength(top);
 
 
     if (s->common.len < 0) {
         goto out;
     }
 
-    ret = base_len = blk_getlength(s->base);
+    ret = base_len = bdrv_getlength(base);
     if (base_len < 0) {
         goto out;
     }
 
     if (base_len < s->common.len) {
-        ret = blk_truncate(s->base, s->common.len);
+        ret = bdrv_truncate(base, s->common.len);
         if (ret) {
             goto out;
         }
     }
 
     end = s->common.len >> BDRV_SECTOR_BITS;
-    buf = blk_blockalign(s->top, COMMIT_BUFFER_SIZE);
+    buf = qemu_blockalign(top, COMMIT_BUFFER_SIZE);
 
     for (sector_num = 0; sector_num < end; sector_num += n) {
+        uint64_t delay_ns = 0;
         bool copy;
 
+wait:
         /* Note that even when no rate limit is applied we need to yield
          * with no pending I/O here so that bdrv_drain_all() returns.
          */
@@ -153,20 +146,25 @@ static void coroutine_fn commit_run(void *opaque)
             break;
         }
         /* Copy if allocated above the base */
-        ret = bdrv_is_allocated_above(blk_bs(s->top), blk_bs(s->base),
-                                      sector_num,
+        ret = bdrv_is_allocated_above(top, base, sector_num,
                                       COMMIT_BUFFER_SIZE / BDRV_SECTOR_SIZE,
                                       &n);
         copy = (ret == 1);
         trace_commit_one_iteration(s, sector_num, n, ret);
         if (copy) {
-            ret = commit_populate(s->top, s->base, sector_num, n, buf);
+            if (s->common.speed) {
+                delay_ns = ratelimit_calculate_delay(&s->limit, n);
+                if (delay_ns > 0) {
+                    goto wait;
+                }
+            }
+            ret = commit_populate(top, base, sector_num, n, buf);
             bytes_written += n * BDRV_SECTOR_SIZE;
         }
         if (ret < 0) {
-            BlockErrorAction action =
-                block_job_error_action(&s->common, false, s->on_error, -ret);
-            if (action == BLOCK_ERROR_ACTION_REPORT) {
+            if (s->on_error == BLOCKDEV_ON_ERROR_STOP ||
+                s->on_error == BLOCKDEV_ON_ERROR_REPORT||
+                (s->on_error == BLOCKDEV_ON_ERROR_ENOSPC && ret == -ENOSPC)) {
                 goto out;
             } else {
                 n = 0;
@@ -175,10 +173,6 @@ static void coroutine_fn commit_run(void *opaque)
         }
         /* Publish progress */
         s->common.offset += n * BDRV_SECTOR_SIZE;
-
-        if (copy && s->common.speed) {
-            delay_ns = ratelimit_calculate_delay(&s->limit, n);
-        }
     }
 
     ret = 0;
@@ -208,8 +202,8 @@ static const BlockJobDriver commit_job_driver = {
     .set_speed     = commit_set_speed,
 };
 
-void commit_start(const char *job_id, BlockDriverState *bs,
-                  BlockDriverState *base, BlockDriverState *top, int64_t speed,
+void commit_start(BlockDriverState *bs, BlockDriverState *base,
+                  BlockDriverState *top, int64_t speed,
                   BlockdevOnError on_error, BlockCompletionFunc *cb,
                   void *opaque, const char *backing_file_str, Error **errp)
 {
@@ -220,6 +214,13 @@ void commit_start(const char *job_id, BlockDriverState *bs,
     BlockDriverState *overlay_bs;
     Error *local_err = NULL;
 
+    if ((on_error == BLOCKDEV_ON_ERROR_STOP ||
+         on_error == BLOCKDEV_ON_ERROR_ENOSPC) &&
+        (!bs->blk || !blk_iostatus_is_enabled(bs->blk))) {
+        error_setg(errp, "Invalid parameter combination");
+        return;
+    }
+
     assert(top != bs);
     if (top == base) {
         error_setg(errp, "Invalid files for merge: top and base are the same");
@@ -233,12 +234,6 @@ void commit_start(const char *job_id, BlockDriverState *bs,
         return;
     }
 
-    s = block_job_create(job_id, &commit_job_driver, bs, speed,
-                         cb, opaque, errp);
-    if (!s) {
-        return;
-    }
-
     orig_base_flags    = bdrv_get_flags(base);
     orig_overlay_flags = bdrv_get_flags(overlay_bs);
 
@@ -255,18 +250,18 @@ void commit_start(const char *job_id, BlockDriverState *bs,
         bdrv_reopen_multiple(reopen_queue, &local_err);
         if (local_err != NULL) {
             error_propagate(errp, local_err);
-            block_job_unref(&s->common);
             return;
         }
     }
 
 
-    s->base = blk_new();
-    blk_insert_bs(s->base, base);
-
-    s->top = blk_new();
-    blk_insert_bs(s->top, top);
+    s = block_job_create(&commit_job_driver, bs, speed, cb, opaque, errp);
+    if (!s) {
+        return;
+    }
 
+    s->base   = base;
+    s->top    = top;
     s->active = bs;
 
     s->base_flags          = orig_base_flags;
@@ -275,129 +270,8 @@ void commit_start(const char *job_id, BlockDriverState *bs,
     s->backing_file_str = g_strdup(backing_file_str);
 
     s->on_error = on_error;
-    s->common.co = qemu_coroutine_create(commit_run, s);
+    s->common.co = qemu_coroutine_create(commit_run);
 
     trace_commit_start(bs, base, top, s, s->common.co, opaque);
-    qemu_coroutine_enter(s->common.co);
-}
-
-
-#define COMMIT_BUF_SECTORS 2048
-
-/* commit COW file into the raw image */
-int bdrv_commit(BlockDriverState *bs)
-{
-    BlockBackend *src, *backing;
-    BlockDriver *drv = bs->drv;
-    int64_t sector, total_sectors, length, backing_length;
-    int n, ro, open_flags;
-    int ret = 0;
-    uint8_t *buf = NULL;
-
-    if (!drv)
-        return -ENOMEDIUM;
-
-    if (!bs->backing) {
-        return -ENOTSUP;
-    }
-
-    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT_SOURCE, NULL) ||
-        bdrv_op_is_blocked(bs->backing->bs, BLOCK_OP_TYPE_COMMIT_TARGET, NULL)) {
-        return -EBUSY;
-    }
-
-    ro = bs->backing->bs->read_only;
-    open_flags =  bs->backing->bs->open_flags;
-
-    if (ro) {
-        if (bdrv_reopen(bs->backing->bs, open_flags | BDRV_O_RDWR, NULL)) {
-            return -EACCES;
-        }
-    }
-
-    src = blk_new();
-    blk_insert_bs(src, bs);
-
-    backing = blk_new();
-    blk_insert_bs(backing, bs->backing->bs);
-
-    length = blk_getlength(src);
-    if (length < 0) {
-        ret = length;
-        goto ro_cleanup;
-    }
-
-    backing_length = blk_getlength(backing);
-    if (backing_length < 0) {
-        ret = backing_length;
-        goto ro_cleanup;
-    }
-
-    /* If our top snapshot is larger than the backing file image,
-     * grow the backing file image if possible.  If not possible,
-     * we must return an error */
-    if (length > backing_length) {
-        ret = blk_truncate(backing, length);
-        if (ret < 0) {
-            goto ro_cleanup;
-        }
-    }
-
-    total_sectors = length >> BDRV_SECTOR_BITS;
-
-    /* blk_try_blockalign() for src will choose an alignment that works for
-     * backing as well, so no need to compare the alignment manually. */
-    buf = blk_try_blockalign(src, COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
-    if (buf == NULL) {
-        ret = -ENOMEM;
-        goto ro_cleanup;
-    }
-
-    for (sector = 0; sector < total_sectors; sector += n) {
-        ret = bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n);
-        if (ret < 0) {
-            goto ro_cleanup;
-        }
-        if (ret) {
-            ret = blk_pread(src, sector * BDRV_SECTOR_SIZE, buf,
-                            n * BDRV_SECTOR_SIZE);
-            if (ret < 0) {
-                goto ro_cleanup;
-            }
-
-            ret = blk_pwrite(backing, sector * BDRV_SECTOR_SIZE, buf,
-                             n * BDRV_SECTOR_SIZE, 0);
-            if (ret < 0) {
-                goto ro_cleanup;
-            }
-        }
-    }
-
-    if (drv->bdrv_make_empty) {
-        ret = drv->bdrv_make_empty(bs);
-        if (ret < 0) {
-            goto ro_cleanup;
-        }
-        blk_flush(src);
-    }
-
-    /*
-     * Make sure all data we wrote to the backing device is actually
-     * stable on disk.
-     */
-    blk_flush(backing);
-
-    ret = 0;
-ro_cleanup:
-    qemu_vfree(buf);
-
-    blk_unref(src);
-    blk_unref(backing);
-
-    if (ro) {
-        /* ignoring error return here */
-        bdrv_reopen(bs->backing->bs, open_flags & ~BDRV_O_RDWR, NULL);
-    }
-
-    return ret;
+    qemu_coroutine_enter(s->common.co, s);
 }
index 7f61e12..1903e84 100644 (file)
@@ -64,7 +64,7 @@ static ssize_t block_crypto_read_func(QCryptoBlock *block,
     BlockDriverState *bs = opaque;
     ssize_t ret;
 
-    ret = bdrv_pread(bs->file, offset, buf, buflen);
+    ret = bdrv_pread(bs->file->bs, offset, buf, buflen);
     if (ret < 0) {
         error_setg_errno(errp, -ret, "Could not read encryption header");
         return ret;
@@ -91,7 +91,7 @@ static ssize_t block_crypto_write_func(QCryptoBlock *block,
     struct BlockCryptoCreateData *data = opaque;
     ssize_t ret;
 
-    ret = blk_pwrite(data->blk, offset, buf, buflen, 0);
+    ret = blk_pwrite(data->blk, offset, buf, buflen);
     if (ret < 0) {
         error_setg_errno(errp, -ret, "Could not write encryption header");
         return ret;
@@ -193,16 +193,18 @@ block_crypto_open_opts_init(QCryptoBlockFormat format,
                             QemuOpts *opts,
                             Error **errp)
 {
-    Visitor *v;
+    OptsVisitor *ov;
     QCryptoBlockOpenOptions *ret = NULL;
     Error *local_err = NULL;
+    Error *end_err = NULL;
 
     ret = g_new0(QCryptoBlockOpenOptions, 1);
     ret->format = format;
 
-    v = opts_visitor_new(opts);
+    ov = opts_visitor_new(opts);
 
-    visit_start_struct(v, NULL, NULL, 0, &local_err);
+    visit_start_struct(opts_get_visitor(ov),
+                       NULL, NULL, 0, &local_err);
     if (local_err) {
         goto out;
     }
@@ -210,18 +212,16 @@ block_crypto_open_opts_init(QCryptoBlockFormat format,
     switch (format) {
     case Q_CRYPTO_BLOCK_FORMAT_LUKS:
         visit_type_QCryptoBlockOptionsLUKS_members(
-            v, &ret->u.luks, &local_err);
+            opts_get_visitor(ov), &ret->u.luks, &local_err);
         break;
 
     default:
         error_setg(&local_err, "Unsupported block format %d", format);
         break;
     }
-    if (!local_err) {
-        visit_check_struct(v, &local_err);
-    }
 
-    visit_end_struct(v, NULL);
+    visit_end_struct(opts_get_visitor(ov), &end_err);
+    error_propagate(&local_err, end_err);
 
  out:
     if (local_err) {
@@ -229,7 +229,7 @@ block_crypto_open_opts_init(QCryptoBlockFormat format,
         qapi_free_QCryptoBlockOpenOptions(ret);
         ret = NULL;
     }
-    visit_free(v);
+    opts_visitor_cleanup(ov);
     return ret;
 }
 
@@ -239,16 +239,18 @@ block_crypto_create_opts_init(QCryptoBlockFormat format,
                               QemuOpts *opts,
                               Error **errp)
 {
-    Visitor *v;
+    OptsVisitor *ov;
     QCryptoBlockCreateOptions *ret = NULL;
     Error *local_err = NULL;
+    Error *end_err = NULL;
 
     ret = g_new0(QCryptoBlockCreateOptions, 1);
     ret->format = format;
 
-    v = opts_visitor_new(opts);
+    ov = opts_visitor_new(opts);
 
-    visit_start_struct(v, NULL, NULL, 0, &local_err);
+    visit_start_struct(opts_get_visitor(ov),
+                       NULL, NULL, 0, &local_err);
     if (local_err) {
         goto out;
     }
@@ -256,18 +258,16 @@ block_crypto_create_opts_init(QCryptoBlockFormat format,
     switch (format) {
     case Q_CRYPTO_BLOCK_FORMAT_LUKS:
         visit_type_QCryptoBlockCreateOptionsLUKS_members(
-            v, &ret->u.luks, &local_err);
+            opts_get_visitor(ov), &ret->u.luks, &local_err);
         break;
 
     default:
         error_setg(&local_err, "Unsupported block format %d", format);
         break;
     }
-    if (!local_err) {
-        visit_check_struct(v, &local_err);
-    }
 
-    visit_end_struct(v, NULL);
+    visit_end_struct(opts_get_visitor(ov), &end_err);
+    error_propagate(&local_err, end_err);
 
  out:
     if (local_err) {
@@ -275,7 +275,7 @@ block_crypto_create_opts_init(QCryptoBlockFormat format,
         qapi_free_QCryptoBlockCreateOptions(ret);
         ret = NULL;
     }
-    visit_free(v);
+    opts_visitor_cleanup(ov);
     return ret;
 }
 
@@ -320,8 +320,8 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
         goto cleanup;
     }
 
-    bs->encrypted = true;
-    bs->valid_key = true;
+    bs->encrypted = 1;
+    bs->valid_key = 1;
 
     ret = 0;
  cleanup:
@@ -426,7 +426,7 @@ block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
         qemu_iovec_reset(&hd_qiov);
         qemu_iovec_add(&hd_qiov, cipher_data, cur_nr_sectors * 512);
 
-        ret = bdrv_co_readv(bs->file,
+        ret = bdrv_co_readv(bs->file->bs,
                             payload_offset + sector_num,
                             cur_nr_sectors, &hd_qiov);
         if (ret < 0) {
@@ -505,7 +505,7 @@ block_crypto_co_writev(BlockDriverState *bs, int64_t sector_num,
         qemu_iovec_reset(&hd_qiov);
         qemu_iovec_add(&hd_qiov, cipher_data, cur_nr_sectors * 512);
 
-        ret = bdrv_co_writev(bs->file,
+        ret = bdrv_co_writev(bs->file->bs,
                              payload_offset + sector_num,
                              cur_nr_sectors, &hd_qiov);
         if (ret < 0) {
@@ -563,53 +563,6 @@ static int block_crypto_create_luks(const char *filename,
                                        filename, opts, errp);
 }
 
-static int block_crypto_get_info_luks(BlockDriverState *bs,
-                                      BlockDriverInfo *bdi)
-{
-    BlockDriverInfo subbdi;
-    int ret;
-
-    ret = bdrv_get_info(bs->file->bs, &subbdi);
-    if (ret != 0) {
-        return ret;
-    }
-
-    bdi->unallocated_blocks_are_zero = false;
-    bdi->can_write_zeroes_with_unmap = false;
-    bdi->cluster_size = subbdi.cluster_size;
-
-    return 0;
-}
-
-static ImageInfoSpecific *
-block_crypto_get_specific_info_luks(BlockDriverState *bs)
-{
-    BlockCrypto *crypto = bs->opaque;
-    ImageInfoSpecific *spec_info;
-    QCryptoBlockInfo *info;
-
-    info = qcrypto_block_get_info(crypto->block, NULL);
-    if (!info) {
-        return NULL;
-    }
-    if (info->format != Q_CRYPTO_BLOCK_FORMAT_LUKS) {
-        qapi_free_QCryptoBlockInfo(info);
-        return NULL;
-    }
-
-    spec_info = g_new(ImageInfoSpecific, 1);
-    spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS;
-    spec_info->u.luks.data = g_new(QCryptoBlockInfoLUKS, 1);
-    *spec_info->u.luks.data = info->u.luks;
-
-    /* Blank out pointers we've just stolen to avoid double free */
-    memset(&info->u.luks, 0, sizeof(info->u.luks));
-
-    qapi_free_QCryptoBlockInfo(info);
-
-    return spec_info;
-}
-
 BlockDriver bdrv_crypto_luks = {
     .format_name        = "luks",
     .instance_size      = sizeof(BlockCrypto),
@@ -623,8 +576,6 @@ BlockDriver bdrv_crypto_luks = {
     .bdrv_co_readv      = block_crypto_co_readv,
     .bdrv_co_writev     = block_crypto_co_writev,
     .bdrv_getlength     = block_crypto_getlength,
-    .bdrv_get_info      = block_crypto_get_info_luks,
-    .bdrv_get_specific_info = block_crypto_get_specific_info_luks,
 };
 
 static void block_crypto_init(void)
index 426fb4d..5a8f8b6 100644 (file)
 // #define DEBUG_VERBOSE
 
 #ifdef DEBUG_CURL
-#define DEBUG_CURL_PRINT 1
+#define DPRINTF(fmt, ...) do { printf(fmt, ## __VA_ARGS__); } while (0)
 #else
-#define DEBUG_CURL_PRINT 0
+#define DPRINTF(fmt, ...) do { } while (0)
 #endif
-#define DPRINTF(fmt, ...)                                            \
-    do {                                                             \
-        if (DEBUG_CURL_PRINT) {                                      \
-            fprintf(stderr, fmt, ## __VA_ARGS__);                    \
-        }                                                            \
-    } while (0)
 
 #if LIBCURL_VERSION_NUM >= 0x071000
 /* The multi interface timer callback was introduced in 7.16.0 */
@@ -169,7 +163,7 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
     state->sock_fd = fd;
     s = state->s;
 
-    DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, (int)fd);
+    DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, fd);
     switch (action) {
         case CURL_POLL_IN:
             aio_set_fd_handler(s->aio_context, fd, false,
index f2bfdcf..4902ca5 100644 (file)
@@ -326,14 +326,14 @@ void bdrv_dirty_iter_init(BdrvDirtyBitmap *bitmap, HBitmapIter *hbi)
 }
 
 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
-                           int64_t cur_sector, int64_t nr_sectors)
+                           int64_t cur_sector, int nr_sectors)
 {
     assert(bdrv_dirty_bitmap_enabled(bitmap));
     hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
 }
 
 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
-                             int64_t cur_sector, int64_t nr_sectors)
+                             int64_t cur_sector, int nr_sectors)
 {
     assert(bdrv_dirty_bitmap_enabled(bitmap));
     hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
@@ -361,7 +361,7 @@ void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
 }
 
 void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
-                    int64_t nr_sectors)
+                    int nr_sectors)
 {
     BdrvDirtyBitmap *bitmap;
     QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
index b0ed89b..a496eb7 100644 (file)
@@ -32,6 +32,7 @@
 #ifdef CONFIG_BZIP2
 #include <bzlib.h>
 #endif
+#include <glib.h>
 
 enum {
     /* Limit chunk sizes to prevent unreasonable amounts of memory being used
@@ -86,7 +87,7 @@ static int read_uint64(BlockDriverState *bs, int64_t offset, uint64_t *result)
     uint64_t buffer;
     int ret;
 
-    ret = bdrv_pread(bs->file, offset, &buffer, 8);
+    ret = bdrv_pread(bs->file->bs, offset, &buffer, 8);
     if (ret < 0) {
         return ret;
     }
@@ -100,7 +101,7 @@ static int read_uint32(BlockDriverState *bs, int64_t offset, uint32_t *result)
     uint32_t buffer;
     int ret;
 
-    ret = bdrv_pread(bs->file, offset, &buffer, 4);
+    ret = bdrv_pread(bs->file->bs, offset, &buffer, 4);
     if (ret < 0) {
         return ret;
     }
@@ -153,9 +154,8 @@ static void update_max_chunk_size(BDRVDMGState *s, uint32_t chunk,
     }
 }
 
-static int64_t dmg_find_koly_offset(BdrvChild *file, Error **errp)
+static int64_t dmg_find_koly_offset(BlockDriverState *file_bs, Error **errp)
 {
-    BlockDriverState *file_bs = file->bs;
     int64_t length;
     int64_t offset = 0;
     uint8_t buffer[515];
@@ -179,7 +179,7 @@ static int64_t dmg_find_koly_offset(BdrvChild *file, Error **errp)
         offset = length - 511 - 512;
     }
     length = length < 515 ? length : 515;
-    ret = bdrv_pread(file, offset, buffer, length);
+    ret = bdrv_pread(file_bs, offset, buffer, length);
     if (ret < 0) {
         error_setg_errno(errp, -ret, "Failed while reading UDIF trailer");
         return ret;
@@ -356,7 +356,7 @@ static int dmg_read_resource_fork(BlockDriverState *bs, DmgHeaderState *ds,
         offset += 4;
 
         buffer = g_realloc(buffer, count);
-        ret = bdrv_pread(bs->file, offset, buffer, count);
+        ret = bdrv_pread(bs->file->bs, offset, buffer, count);
         if (ret < 0) {
             goto fail;
         }
@@ -393,7 +393,7 @@ static int dmg_read_plist_xml(BlockDriverState *bs, DmgHeaderState *ds,
 
     buffer = g_malloc(info_length + 1);
     buffer[info_length] = '\0';
-    ret = bdrv_pread(bs->file, info_begin, buffer, info_length);
+    ret = bdrv_pread(bs->file->bs, info_begin, buffer, info_length);
     if (ret != info_length) {
         ret = -EINVAL;
         goto fail;
@@ -439,8 +439,7 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
     int64_t offset;
     int ret;
 
-    bs->read_only = true;
-
+    bs->read_only = 1;
     s->n_chunks = 0;
     s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
     /* used by dmg_read_mish_block to keep track of the current I/O position */
@@ -449,7 +448,7 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
     ds.max_sectors_per_chunk = 1;
 
     /* locate the UDIF trailer */
-    offset = dmg_find_koly_offset(bs->file, errp);
+    offset = dmg_find_koly_offset(bs->file->bs, errp);
     if (offset < 0) {
         ret = offset;
         goto fail;
@@ -547,11 +546,6 @@ fail:
     return ret;
 }
 
-static void dmg_refresh_limits(BlockDriverState *bs, Error **errp)
-{
-    bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
-}
-
 static inline int is_sector_in_chunk(BDRVDMGState* s,
                 uint32_t chunk_num, uint64_t sector_num)
 {
@@ -600,7 +594,7 @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
         case 0x80000005: { /* zlib compressed */
             /* we need to buffer, because only the chunk as whole can be
              * inflated. */
-            ret = bdrv_pread(bs->file, s->offsets[chunk],
+            ret = bdrv_pread(bs->file->bs, s->offsets[chunk],
                              s->compressed_chunk, s->lengths[chunk]);
             if (ret != s->lengths[chunk]) {
                 return -1;
@@ -624,7 +618,7 @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
         case 0x80000006: /* bzip2 compressed */
             /* we need to buffer, because only the chunk as whole can be
              * inflated. */
-            ret = bdrv_pread(bs->file, s->offsets[chunk],
+            ret = bdrv_pread(bs->file->bs, s->offsets[chunk],
                              s->compressed_chunk, s->lengths[chunk]);
             if (ret != s->lengths[chunk]) {
                 return -1;
@@ -649,7 +643,7 @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
             break;
 #endif /* CONFIG_BZIP2 */
         case 1: /* copy */
-            ret = bdrv_pread(bs->file, s->offsets[chunk],
+            ret = bdrv_pread(bs->file->bs, s->offsets[chunk],
                              s->uncompressed_chunk, s->lengths[chunk]);
             if (ret != s->lengths[chunk]) {
                 return -1;
@@ -665,42 +659,38 @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
     return 0;
 }
 
-static int coroutine_fn
-dmg_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
-              QEMUIOVector *qiov, int flags)
+static int dmg_read(BlockDriverState *bs, int64_t sector_num,
+                    uint8_t *buf, int nb_sectors)
 {
     BDRVDMGState *s = bs->opaque;
-    uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
-    int nb_sectors = bytes >> BDRV_SECTOR_BITS;
-    int ret, i;
-
-    assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
-    assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
-
-    qemu_co_mutex_lock(&s->lock);
+    int i;
 
     for (i = 0; i < nb_sectors; i++) {
         uint32_t sector_offset_in_chunk;
-        void *data;
-
         if (dmg_read_chunk(bs, sector_num + i) != 0) {
-            ret = -EIO;
-            goto fail;
+            return -1;
         }
         /* Special case: current chunk is all zeroes. Do not perform a memcpy as
          * s->uncompressed_chunk may be too small to cover the large all-zeroes
          * section. dmg_read_chunk is called to find s->current_chunk */
         if (s->types[s->current_chunk] == 2) { /* all zeroes block entry */
-            qemu_iovec_memset(qiov, i * 512, 0, 512);
+            memset(buf + i * 512, 0, 512);
             continue;
         }
         sector_offset_in_chunk = sector_num + i - s->sectors[s->current_chunk];
-        data = s->uncompressed_chunk + sector_offset_in_chunk * 512;
-        qemu_iovec_from_buf(qiov, i * 512, data, 512);
+        memcpy(buf + i * 512,
+               s->uncompressed_chunk + sector_offset_in_chunk * 512, 512);
     }
+    return 0;
+}
 
-    ret = 0;
-fail:
+static coroutine_fn int dmg_co_read(BlockDriverState *bs, int64_t sector_num,
+                                    uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVDMGState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = dmg_read(bs, sector_num, buf, nb_sectors);
     qemu_co_mutex_unlock(&s->lock);
     return ret;
 }
@@ -725,8 +715,7 @@ static BlockDriver bdrv_dmg = {
     .instance_size  = sizeof(BDRVDMGState),
     .bdrv_probe     = dmg_probe,
     .bdrv_open      = dmg_open,
-    .bdrv_refresh_limits = dmg_refresh_limits,
-    .bdrv_co_preadv = dmg_co_preadv,
+    .bdrv_read      = dmg_co_read,
     .bdrv_close     = dmg_close,
 };
 
index 01b479f..a8aaacf 100644 (file)
 #include <glusterfs/api/glfs.h>
 #include "block/block_int.h"
 #include "qapi/error.h"
-#include "qapi/qmp/qerror.h"
 #include "qemu/uri.h"
-#include "qemu/error-report.h"
-
-#define GLUSTER_OPT_FILENAME        "filename"
-#define GLUSTER_OPT_VOLUME          "volume"
-#define GLUSTER_OPT_PATH            "path"
-#define GLUSTER_OPT_TYPE            "type"
-#define GLUSTER_OPT_SERVER_PATTERN  "server."
-#define GLUSTER_OPT_HOST            "host"
-#define GLUSTER_OPT_PORT            "port"
-#define GLUSTER_OPT_TO              "to"
-#define GLUSTER_OPT_IPV4            "ipv4"
-#define GLUSTER_OPT_IPV6            "ipv6"
-#define GLUSTER_OPT_SOCKET          "socket"
-#define GLUSTER_OPT_DEBUG           "debug"
-#define GLUSTER_DEFAULT_PORT        24007
-#define GLUSTER_DEBUG_DEFAULT       4
-#define GLUSTER_DEBUG_MAX           9
-
-#define GERR_INDEX_HINT "hint: check in 'server' array index '%d'\n"
 
 typedef struct GlusterAIOCB {
     int64_t size;
@@ -44,145 +24,28 @@ typedef struct GlusterAIOCB {
 typedef struct BDRVGlusterState {
     struct glfs *glfs;
     struct glfs_fd *fd;
-    bool supports_seek_data;
-    int debug_level;
 } BDRVGlusterState;
 
-typedef struct BDRVGlusterReopenState {
-    struct glfs *glfs;
-    struct glfs_fd *fd;
-} BDRVGlusterReopenState;
-
+typedef struct GlusterConf {
+    char *server;
+    int port;
+    char *volname;
+    char *image;
+    char *transport;
+} GlusterConf;
 
-static QemuOptsList qemu_gluster_create_opts = {
-    .name = "qemu-gluster-create-opts",
-    .head = QTAILQ_HEAD_INITIALIZER(qemu_gluster_create_opts.head),
-    .desc = {
-        {
-            .name = BLOCK_OPT_SIZE,
-            .type = QEMU_OPT_SIZE,
-            .help = "Virtual disk size"
-        },
-        {
-            .name = BLOCK_OPT_PREALLOC,
-            .type = QEMU_OPT_STRING,
-            .help = "Preallocation mode (allowed values: off, full)"
-        },
-        {
-            .name = GLUSTER_OPT_DEBUG,
-            .type = QEMU_OPT_NUMBER,
-            .help = "Gluster log level, valid range is 0-9",
-        },
-        { /* end of list */ }
+static void qemu_gluster_gconf_free(GlusterConf *gconf)
+{
+    if (gconf) {
+        g_free(gconf->server);
+        g_free(gconf->volname);
+        g_free(gconf->image);
+        g_free(gconf->transport);
+        g_free(gconf);
     }
-};
-
-static QemuOptsList runtime_opts = {
-    .name = "gluster",
-    .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
-    .desc = {
-        {
-            .name = GLUSTER_OPT_FILENAME,
-            .type = QEMU_OPT_STRING,
-            .help = "URL to the gluster image",
-        },
-        {
-            .name = GLUSTER_OPT_DEBUG,
-            .type = QEMU_OPT_NUMBER,
-            .help = "Gluster log level, valid range is 0-9",
-        },
-        { /* end of list */ }
-    },
-};
-
-static QemuOptsList runtime_json_opts = {
-    .name = "gluster_json",
-    .head = QTAILQ_HEAD_INITIALIZER(runtime_json_opts.head),
-    .desc = {
-        {
-            .name = GLUSTER_OPT_VOLUME,
-            .type = QEMU_OPT_STRING,
-            .help = "name of gluster volume where VM image resides",
-        },
-        {
-            .name = GLUSTER_OPT_PATH,
-            .type = QEMU_OPT_STRING,
-            .help = "absolute path to image file in gluster volume",
-        },
-        {
-            .name = GLUSTER_OPT_DEBUG,
-            .type = QEMU_OPT_NUMBER,
-            .help = "Gluster log level, valid range is 0-9",
-        },
-        { /* end of list */ }
-    },
-};
-
-static QemuOptsList runtime_type_opts = {
-    .name = "gluster_type",
-    .head = QTAILQ_HEAD_INITIALIZER(runtime_type_opts.head),
-    .desc = {
-        {
-            .name = GLUSTER_OPT_TYPE,
-            .type = QEMU_OPT_STRING,
-            .help = "tcp|unix",
-        },
-        { /* end of list */ }
-    },
-};
-
-static QemuOptsList runtime_unix_opts = {
-    .name = "gluster_unix",
-    .head = QTAILQ_HEAD_INITIALIZER(runtime_unix_opts.head),
-    .desc = {
-        {
-            .name = GLUSTER_OPT_SOCKET,
-            .type = QEMU_OPT_STRING,
-            .help = "socket file path)",
-        },
-        { /* end of list */ }
-    },
-};
-
-static QemuOptsList runtime_tcp_opts = {
-    .name = "gluster_tcp",
-    .head = QTAILQ_HEAD_INITIALIZER(runtime_tcp_opts.head),
-    .desc = {
-        {
-            .name = GLUSTER_OPT_TYPE,
-            .type = QEMU_OPT_STRING,
-            .help = "tcp|unix",
-        },
-        {
-            .name = GLUSTER_OPT_HOST,
-            .type = QEMU_OPT_STRING,
-            .help = "host address (hostname/ipv4/ipv6 addresses)",
-        },
-        {
-            .name = GLUSTER_OPT_PORT,
-            .type = QEMU_OPT_NUMBER,
-            .help = "port number on which glusterd is listening (default 24007)",
-        },
-        {
-            .name = "to",
-            .type = QEMU_OPT_NUMBER,
-            .help = "max port number, not supported by gluster",
-        },
-        {
-            .name = "ipv4",
-            .type = QEMU_OPT_BOOL,
-            .help = "ipv4 bool value, not supported by gluster",
-        },
-        {
-            .name = "ipv6",
-            .type = QEMU_OPT_BOOL,
-            .help = "ipv6 bool value, not supported by gluster",
-        },
-        { /* end of list */ }
-    },
-};
+}
 
-static int parse_volume_options(BlockdevOptionsGluster *gconf, char *path)
+static int parse_volume_options(GlusterConf *gconf, char *path)
 {
     char *p, *q;
 
@@ -196,29 +59,31 @@ static int parse_volume_options(BlockdevOptionsGluster *gconf, char *path)
     if (*p == '\0') {
         return -EINVAL;
     }
-    gconf->volume = g_strndup(q, p - q);
+    gconf->volname = g_strndup(q, p - q);
 
-    /* path */
+    /* image */
     p += strspn(p, "/");
     if (*p == '\0') {
         return -EINVAL;
     }
-    gconf->path = g_strdup(p);
+    gconf->image = g_strdup(p);
     return 0;
 }
 
 /*
- * file=gluster[+transport]://[host[:port]]/volume/path[?socket=...]
+ * file=gluster[+transport]://[server[:port]]/volname/image[?socket=...]
  *
  * 'gluster' is the protocol.
  *
  * 'transport' specifies the transport type used to connect to gluster
  * management daemon (glusterd). Valid transport types are
- * tcp or unix. If a transport type isn't specified, then tcp type is assumed.
+ * tcp, unix and rdma. If a transport type isn't specified, then tcp
+ * type is assumed.
  *
- * 'host' specifies the host where the volume file specification for
- * the given volume resides. This can be either hostname or ipv4 address.
- * If transport type is 'unix', then 'host' field should not be specified.
+ * 'server' specifies the server where the volume file specification for
+ * the given volume resides. This can be either hostname, ipv4 address
+ * or ipv6 address. ipv6 address needs to be within square brackets [ ].
+ * If transport type is 'unix', then 'server' field should not be specified.
  * The 'socket' field needs to be populated with the path to unix domain
  * socket.
  *
@@ -227,22 +92,23 @@ static int parse_volume_options(BlockdevOptionsGluster *gconf, char *path)
  * default port. If the transport type is unix, then 'port' should not be
  * specified.
  *
- * 'volume' is the name of the gluster volume which contains the VM image.
+ * 'volname' is the name of the gluster volume which contains the VM image.
  *
- * 'path' is the path to the actual VM image that resides on gluster volume.
+ * 'image' is the path to the actual VM image that resides on gluster volume.
  *
  * Examples:
  *
  * file=gluster://1.2.3.4/testvol/a.img
  * file=gluster+tcp://1.2.3.4/testvol/a.img
  * file=gluster+tcp://1.2.3.4:24007/testvol/dir/a.img
- * file=gluster+tcp://host.domain.com:24007/testvol/dir/a.img
+ * file=gluster+tcp://[1:2:3:4:5:6:7:8]/testvol/dir/a.img
+ * file=gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol/dir/a.img
+ * file=gluster+tcp://server.domain.com:24007/testvol/dir/a.img
  * file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
+ * file=gluster+rdma://1.2.3.4:24007/testvol/a.img
  */
-static int qemu_gluster_parse_uri(BlockdevOptionsGluster *gconf,
-                                  const char *filename)
+static int qemu_gluster_parseuri(GlusterConf *gconf, const char *filename)
 {
-    GlusterServer *gsconf;
     URI *uri;
     QueryParams *qp = NULL;
     bool is_unix = false;
@@ -253,21 +119,16 @@ static int qemu_gluster_parse_uri(BlockdevOptionsGluster *gconf,
         return -EINVAL;
     }
 
-    gconf->server = g_new0(GlusterServerList, 1);
-    gconf->server->value = gsconf = g_new0(GlusterServer, 1);
-
     /* transport */
     if (!uri->scheme || !strcmp(uri->scheme, "gluster")) {
-        gsconf->type = GLUSTER_TRANSPORT_TCP;
+        gconf->transport = g_strdup("tcp");
     } else if (!strcmp(uri->scheme, "gluster+tcp")) {
-        gsconf->type = GLUSTER_TRANSPORT_TCP;
+        gconf->transport = g_strdup("tcp");
     } else if (!strcmp(uri->scheme, "gluster+unix")) {
-        gsconf->type = GLUSTER_TRANSPORT_UNIX;
+        gconf->transport = g_strdup("unix");
         is_unix = true;
     } else if (!strcmp(uri->scheme, "gluster+rdma")) {
-        gsconf->type = GLUSTER_TRANSPORT_TCP;
-        error_report("Warning: rdma feature is not supported, falling "
-                     "back to tcp");
+        gconf->transport = g_strdup("rdma");
     } else {
         ret = -EINVAL;
         goto out;
@@ -293,14 +154,10 @@ static int qemu_gluster_parse_uri(BlockdevOptionsGluster *gconf,
             ret = -EINVAL;
             goto out;
         }
-        gsconf->u.q_unix.path = g_strdup(qp->p[0].value);
+        gconf->server = g_strdup(qp->p[0].value);
     } else {
-        gsconf->u.tcp.host = g_strdup(uri->server ? uri->server : "localhost");
-        if (uri->port) {
-            gsconf->u.tcp.port = g_strdup_printf("%d", uri->port);
-        } else {
-            gsconf->u.tcp.port = g_strdup_printf("%d", GLUSTER_DEFAULT_PORT);
-        }
+        gconf->server = g_strdup(uri->server ? uri->server : "localhost");
+        gconf->port = uri->port;
     }
 
 out:
@@ -311,62 +168,52 @@ out:
     return ret;
 }
 
-static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
-                                           Error **errp)
+static struct glfs *qemu_gluster_init(GlusterConf *gconf, const char *filename,
+                                      Error **errp)
 {
-    struct glfs *glfs;
+    struct glfs *glfs = NULL;
     int ret;
     int old_errno;
-    GlusterServerList *server;
 
-    glfs = glfs_new(gconf->volume);
-    if (!glfs) {
+    ret = qemu_gluster_parseuri(gconf, filename);
+    if (ret < 0) {
+        error_setg(errp, "Usage: file=gluster[+transport]://[server[:port]]/"
+                   "volname/image[?socket=...]");
+        errno = -ret;
         goto out;
     }
 
-    for (server = gconf->server; server; server = server->next) {
-        if (server->value->type  == GLUSTER_TRANSPORT_UNIX) {
-            ret = glfs_set_volfile_server(glfs,
-                                   GlusterTransport_lookup[server->value->type],
-                                   server->value->u.q_unix.path, 0);
-        } else {
-            ret = glfs_set_volfile_server(glfs,
-                                   GlusterTransport_lookup[server->value->type],
-                                   server->value->u.tcp.host,
-                                   atoi(server->value->u.tcp.port));
-        }
+    glfs = glfs_new(gconf->volname);
+    if (!glfs) {
+        goto out;
+    }
 
-        if (ret < 0) {
-            goto out;
-        }
+    ret = glfs_set_volfile_server(glfs, gconf->transport, gconf->server,
+            gconf->port);
+    if (ret < 0) {
+        goto out;
     }
 
-    ret = glfs_set_logging(glfs, "-", gconf->debug_level);
+    /*
+     * TODO: Use GF_LOG_ERROR instead of hard code value of 4 here when
+     * GlusterFS makes GF_LOG_* macros available to libgfapi users.
+     */
+    ret = glfs_set_logging(glfs, "-", 4);
     if (ret < 0) {
         goto out;
     }
 
     ret = glfs_init(glfs);
     if (ret) {
-        error_setg(errp, "Gluster connection for volume %s, path %s failed"
-                         " to connect", gconf->volume, gconf->path);
-        for (server = gconf->server; server; server = server->next) {
-            if (server->value->type  == GLUSTER_TRANSPORT_UNIX) {
-                error_append_hint(errp, "hint: failed on socket %s ",
-                                  server->value->u.q_unix.path);
-            } else {
-                error_append_hint(errp, "hint: failed on host %s and port %s ",
-                                  server->value->u.tcp.host,
-                                  server->value->u.tcp.port);
-            }
-        }
-
-        error_append_hint(errp, "Please refer to gluster logs for more info\n");
+        error_setg_errno(errp, errno,
+                         "Gluster connection failed for server=%s port=%d "
+                         "volume=%s image=%s transport=%s", gconf->server,
+                         gconf->port, gconf->volname, gconf->image,
+                         gconf->transport);
 
         /* glfs_init sometimes doesn't set errno although docs suggest that */
-        if (errno == 0) {
+        if (errno == 0)
             errno = EINVAL;
-        }
 
         goto out;
     }
@@ -381,233 +228,13 @@ out:
     return NULL;
 }
 
-static int qapi_enum_parse(const char *opt)
-{
-    int i;
-
-    if (!opt) {
-        return GLUSTER_TRANSPORT__MAX;
-    }
-
-    for (i = 0; i < GLUSTER_TRANSPORT__MAX; i++) {
-        if (!strcmp(opt, GlusterTransport_lookup[i])) {
-            return i;
-        }
-    }
-
-    return i;
-}
-
-/*
- * Convert the json formatted command line into qapi.
-*/
-static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf,
-                                  QDict *options, Error **errp)
-{
-    QemuOpts *opts;
-    GlusterServer *gsconf;
-    GlusterServerList *curr = NULL;
-    QDict *backing_options = NULL;
-    Error *local_err = NULL;
-    char *str = NULL;
-    const char *ptr;
-    size_t num_servers;
-    int i;
-
-    /* create opts info from runtime_json_opts list */
-    opts = qemu_opts_create(&runtime_json_opts, NULL, 0, &error_abort);
-    qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (local_err) {
-        goto out;
-    }
-
-    num_servers = qdict_array_entries(options, GLUSTER_OPT_SERVER_PATTERN);
-    if (num_servers < 1) {
-        error_setg(&local_err, QERR_MISSING_PARAMETER, "server");
-        goto out;
-    }
-
-    ptr = qemu_opt_get(opts, GLUSTER_OPT_VOLUME);
-    if (!ptr) {
-        error_setg(&local_err, QERR_MISSING_PARAMETER, GLUSTER_OPT_VOLUME);
-        goto out;
-    }
-    gconf->volume = g_strdup(ptr);
-
-    ptr = qemu_opt_get(opts, GLUSTER_OPT_PATH);
-    if (!ptr) {
-        error_setg(&local_err, QERR_MISSING_PARAMETER, GLUSTER_OPT_PATH);
-        goto out;
-    }
-    gconf->path = g_strdup(ptr);
-    qemu_opts_del(opts);
-
-    for (i = 0; i < num_servers; i++) {
-        str = g_strdup_printf(GLUSTER_OPT_SERVER_PATTERN"%d.", i);
-        qdict_extract_subqdict(options, &backing_options, str);
-
-        /* create opts info from runtime_type_opts list */
-        opts = qemu_opts_create(&runtime_type_opts, NULL, 0, &error_abort);
-        qemu_opts_absorb_qdict(opts, backing_options, &local_err);
-        if (local_err) {
-            goto out;
-        }
-
-        ptr = qemu_opt_get(opts, GLUSTER_OPT_TYPE);
-        gsconf = g_new0(GlusterServer, 1);
-        gsconf->type = qapi_enum_parse(ptr);
-        if (!ptr) {
-            error_setg(&local_err, QERR_MISSING_PARAMETER, GLUSTER_OPT_TYPE);
-            error_append_hint(&local_err, GERR_INDEX_HINT, i);
-            goto out;
-
-        }
-        if (gsconf->type == GLUSTER_TRANSPORT__MAX) {
-            error_setg(&local_err, QERR_INVALID_PARAMETER_VALUE,
-                       GLUSTER_OPT_TYPE, "tcp or unix");
-            error_append_hint(&local_err, GERR_INDEX_HINT, i);
-            goto out;
-        }
-        qemu_opts_del(opts);
-
-        if (gsconf->type == GLUSTER_TRANSPORT_TCP) {
-            /* create opts info from runtime_tcp_opts list */
-            opts = qemu_opts_create(&runtime_tcp_opts, NULL, 0, &error_abort);
-            qemu_opts_absorb_qdict(opts, backing_options, &local_err);
-            if (local_err) {
-                goto out;
-            }
-
-            ptr = qemu_opt_get(opts, GLUSTER_OPT_HOST);
-            if (!ptr) {
-                error_setg(&local_err, QERR_MISSING_PARAMETER,
-                           GLUSTER_OPT_HOST);
-                error_append_hint(&local_err, GERR_INDEX_HINT, i);
-                goto out;
-            }
-            gsconf->u.tcp.host = g_strdup(ptr);
-            ptr = qemu_opt_get(opts, GLUSTER_OPT_PORT);
-            if (!ptr) {
-                error_setg(&local_err, QERR_MISSING_PARAMETER,
-                           GLUSTER_OPT_PORT);
-                error_append_hint(&local_err, GERR_INDEX_HINT, i);
-                goto out;
-            }
-            gsconf->u.tcp.port = g_strdup(ptr);
-
-            /* defend for unsupported fields in InetSocketAddress,
-             * i.e. @ipv4, @ipv6  and @to
-             */
-            ptr = qemu_opt_get(opts, GLUSTER_OPT_TO);
-            if (ptr) {
-                gsconf->u.tcp.has_to = true;
-            }
-            ptr = qemu_opt_get(opts, GLUSTER_OPT_IPV4);
-            if (ptr) {
-                gsconf->u.tcp.has_ipv4 = true;
-            }
-            ptr = qemu_opt_get(opts, GLUSTER_OPT_IPV6);
-            if (ptr) {
-                gsconf->u.tcp.has_ipv6 = true;
-            }
-            if (gsconf->u.tcp.has_to) {
-                error_setg(&local_err, "Parameter 'to' not supported");
-                goto out;
-            }
-            if (gsconf->u.tcp.has_ipv4 || gsconf->u.tcp.has_ipv6) {
-                error_setg(&local_err, "Parameters 'ipv4/ipv6' not supported");
-                goto out;
-            }
-            qemu_opts_del(opts);
-        } else {
-            /* create opts info from runtime_unix_opts list */
-            opts = qemu_opts_create(&runtime_unix_opts, NULL, 0, &error_abort);
-            qemu_opts_absorb_qdict(opts, backing_options, &local_err);
-            if (local_err) {
-                goto out;
-            }
-
-            ptr = qemu_opt_get(opts, GLUSTER_OPT_SOCKET);
-            if (!ptr) {
-                error_setg(&local_err, QERR_MISSING_PARAMETER,
-                           GLUSTER_OPT_SOCKET);
-                error_append_hint(&local_err, GERR_INDEX_HINT, i);
-                goto out;
-            }
-            gsconf->u.q_unix.path = g_strdup(ptr);
-            qemu_opts_del(opts);
-        }
-
-        if (gconf->server == NULL) {
-            gconf->server = g_new0(GlusterServerList, 1);
-            gconf->server->value = gsconf;
-            curr = gconf->server;
-        } else {
-            curr->next = g_new0(GlusterServerList, 1);
-            curr->next->value = gsconf;
-            curr = curr->next;
-        }
-
-        qdict_del(backing_options, str);
-        g_free(str);
-        str = NULL;
-    }
-
-    return 0;
-
-out:
-    error_propagate(errp, local_err);
-    qemu_opts_del(opts);
-    if (str) {
-        qdict_del(backing_options, str);
-        g_free(str);
-    }
-    errno = EINVAL;
-    return -errno;
-}
-
-static struct glfs *qemu_gluster_init(BlockdevOptionsGluster *gconf,
-                                      const char *filename,
-                                      QDict *options, Error **errp)
-{
-    int ret;
-    if (filename) {
-        ret = qemu_gluster_parse_uri(gconf, filename);
-        if (ret < 0) {
-            error_setg(errp, "invalid URI");
-            error_append_hint(errp, "Usage: file=gluster[+transport]://"
-                                    "[host[:port]]/volume/path[?socket=...]\n");
-            errno = -ret;
-            return NULL;
-        }
-    } else {
-        ret = qemu_gluster_parse_json(gconf, options, errp);
-        if (ret < 0) {
-            error_append_hint(errp, "Usage: "
-                             "-drive driver=qcow2,file.driver=gluster,"
-                             "file.volume=testvol,file.path=/path/a.qcow2"
-                             "[,file.debug=9],file.server.0.type=tcp,"
-                             "file.server.0.host=1.2.3.4,"
-                             "file.server.0.port=24007,"
-                             "file.server.1.transport=unix,"
-                             "file.server.1.socket=/var/run/glusterd.socket ..."
-                             "\n");
-            errno = -ret;
-            return NULL;
-        }
-
-    }
-
-    return qemu_gluster_glfs_init(gconf, errp);
-}
-
 static void qemu_gluster_complete_aio(void *opaque)
 {
     GlusterAIOCB *acb = (GlusterAIOCB *)opaque;
 
     qemu_bh_delete(acb->bh);
     acb->bh = NULL;
-    qemu_coroutine_enter(acb->coroutine);
+    qemu_coroutine_enter(acb->coroutine, NULL);
 }
 
 /*
@@ -629,6 +256,20 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
     qemu_bh_schedule(acb->bh);
 }
 
+/* TODO Convert to fine grained options */
+static QemuOptsList runtime_opts = {
+    .name = "gluster",
+    .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
+    .desc = {
+        {
+            .name = "filename",
+            .type = QEMU_OPT_STRING,
+            .help = "URL to the gluster image",
+        },
+        { /* end of list */ }
+    },
+};
+
 static void qemu_gluster_parse_flags(int bdrv_flags, int *open_flags)
 {
     assert(open_flags != NULL);
@@ -646,35 +287,13 @@ static void qemu_gluster_parse_flags(int bdrv_flags, int *open_flags)
     }
 }
 
-/*
- * Do SEEK_DATA/HOLE to detect if it is functional. Older broken versions of
- * gfapi incorrectly return the current offset when SEEK_DATA/HOLE is used.
- * - Corrected versions return -1 and set errno to EINVAL.
- * - Versions that support SEEK_DATA/HOLE correctly, will return -1 and set
- *   errno to ENXIO when SEEK_DATA is called with a position of EOF.
- */
-static bool qemu_gluster_test_seek(struct glfs_fd *fd)
-{
-    off_t ret, eof;
-
-    eof = glfs_lseek(fd, 0, SEEK_END);
-    if (eof < 0) {
-        /* this should never occur */
-        return false;
-    }
-
-    /* this should always fail with ENXIO if SEEK_DATA is supported */
-    ret = glfs_lseek(fd, eof, SEEK_DATA);
-    return (ret < 0) && (errno == ENXIO);
-}
-
 static int qemu_gluster_open(BlockDriverState *bs,  QDict *options,
                              int bdrv_flags, Error **errp)
 {
     BDRVGlusterState *s = bs->opaque;
     int open_flags = 0;
     int ret = 0;
-    BlockdevOptionsGluster *gconf = NULL;
+    GlusterConf *gconf = g_new0(GlusterConf, 1);
     QemuOpts *opts;
     Error *local_err = NULL;
     const char *filename;
@@ -687,20 +306,9 @@ static int qemu_gluster_open(BlockDriverState *bs,  QDict *options,
         goto out;
     }
 
-    filename = qemu_opt_get(opts, GLUSTER_OPT_FILENAME);
+    filename = qemu_opt_get(opts, "filename");
 
-    s->debug_level = qemu_opt_get_number(opts, GLUSTER_OPT_DEBUG,
-                                         GLUSTER_DEBUG_DEFAULT);
-    if (s->debug_level < 0) {
-        s->debug_level = 0;
-    } else if (s->debug_level > GLUSTER_DEBUG_MAX) {
-        s->debug_level = GLUSTER_DEBUG_MAX;
-    }
-
-    gconf = g_new0(BlockdevOptionsGluster, 1);
-    gconf->debug_level = s->debug_level;
-    gconf->has_debug_level = true;
-    s->glfs = qemu_gluster_init(gconf, filename, options, errp);
+    s->glfs = qemu_gluster_init(gconf, filename, errp);
     if (!s->glfs) {
         ret = -errno;
         goto out;
@@ -725,16 +333,14 @@ static int qemu_gluster_open(BlockDriverState *bs,  QDict *options,
 
     qemu_gluster_parse_flags(bdrv_flags, &open_flags);
 
-    s->fd = glfs_open(s->glfs, gconf->path, open_flags);
+    s->fd = glfs_open(s->glfs, gconf->image, open_flags);
     if (!s->fd) {
         ret = -errno;
     }
 
-    s->supports_seek_data = qemu_gluster_test_seek(s->fd);
-
 out:
     qemu_opts_del(opts);
-    qapi_free_BlockdevOptionsGluster(gconf);
+    qemu_gluster_gconf_free(gconf);
     if (!ret) {
         return ret;
     }
@@ -747,29 +353,31 @@ out:
     return ret;
 }
 
+typedef struct BDRVGlusterReopenState {
+    struct glfs *glfs;
+    struct glfs_fd *fd;
+} BDRVGlusterReopenState;
+
+
 static int qemu_gluster_reopen_prepare(BDRVReopenState *state,
                                        BlockReopenQueue *queue, Error **errp)
 {
     int ret = 0;
-    BDRVGlusterState *s;
     BDRVGlusterReopenState *reop_s;
-    BlockdevOptionsGluster *gconf;
+    GlusterConf *gconf = NULL;
     int open_flags = 0;
 
     assert(state != NULL);
     assert(state->bs != NULL);
 
-    s = state->bs->opaque;
-
     state->opaque = g_new0(BDRVGlusterReopenState, 1);
     reop_s = state->opaque;
 
     qemu_gluster_parse_flags(state->flags, &open_flags);
 
-    gconf = g_new0(BlockdevOptionsGluster, 1);
-    gconf->debug_level = s->debug_level;
-    gconf->has_debug_level = true;
-    reop_s->glfs = qemu_gluster_init(gconf, state->bs->filename, NULL, errp);
+    gconf = g_new0(GlusterConf, 1);
+
+    reop_s->glfs = qemu_gluster_init(gconf, state->bs->filename, errp);
     if (reop_s->glfs == NULL) {
         ret = -errno;
         goto exit;
@@ -785,7 +393,7 @@ static int qemu_gluster_reopen_prepare(BDRVReopenState *state,
     }
 #endif
 
-    reop_s->fd = glfs_open(reop_s->glfs, gconf->path, open_flags);
+    reop_s->fd = glfs_open(reop_s->glfs, gconf->image, open_flags);
     if (reop_s->fd == NULL) {
         /* reops->glfs will be cleaned up in _abort */
         ret = -errno;
@@ -794,7 +402,7 @@ static int qemu_gluster_reopen_prepare(BDRVReopenState *state,
 
 exit:
     /* state->opaque will be freed in either the _abort or _commit */
-    qapi_free_BlockdevOptionsGluster(gconf);
+    qemu_gluster_gconf_free(gconf);
     return ret;
 }
 
@@ -846,14 +454,14 @@ static void qemu_gluster_reopen_abort(BDRVReopenState *state)
 }
 
 #ifdef CONFIG_GLUSTERFS_ZEROFILL
-static coroutine_fn int qemu_gluster_co_pwrite_zeroes(BlockDriverState *bs,
-                                                      int64_t offset,
-                                                      int size,
-                                                      BdrvRequestFlags flags)
+static coroutine_fn int qemu_gluster_co_write_zeroes(BlockDriverState *bs,
+        int64_t sector_num, int nb_sectors, BdrvRequestFlags flags)
 {
     int ret;
     GlusterAIOCB acb;
     BDRVGlusterState *s = bs->opaque;
+    off_t size = nb_sectors * BDRV_SECTOR_SIZE;
+    off_t offset = sector_num * BDRV_SECTOR_SIZE;
 
     acb.size = size;
     acb.ret = 0;
@@ -875,7 +483,7 @@ static inline bool gluster_supports_zerofill(void)
 }
 
 static inline int qemu_gluster_zerofill(struct glfs_fd *fd, int64_t offset,
-                                        int64_t size)
+        int64_t size)
 {
     return glfs_zerofill(fd, offset, size);
 }
@@ -887,7 +495,7 @@ static inline bool gluster_supports_zerofill(void)
 }
 
 static inline int qemu_gluster_zerofill(struct glfs_fd *fd, int64_t offset,
-                                        int64_t size)
+        int64_t size)
 {
     return 0;
 }
@@ -896,25 +504,15 @@ static inline int qemu_gluster_zerofill(struct glfs_fd *fd, int64_t offset,
 static int qemu_gluster_create(const char *filename,
                                QemuOpts *opts, Error **errp)
 {
-    BlockdevOptionsGluster *gconf;
     struct glfs *glfs;
     struct glfs_fd *fd;
     int ret = 0;
     int prealloc = 0;
     int64_t total_size = 0;
     char *tmp = NULL;
+    GlusterConf *gconf = g_new0(GlusterConf, 1);
 
-    gconf = g_new0(BlockdevOptionsGluster, 1);
-    gconf->debug_level = qemu_opt_get_number_del(opts, GLUSTER_OPT_DEBUG,
-                                                 GLUSTER_DEBUG_DEFAULT);
-    if (gconf->debug_level < 0) {
-        gconf->debug_level = 0;
-    } else if (gconf->debug_level > GLUSTER_DEBUG_MAX) {
-        gconf->debug_level = GLUSTER_DEBUG_MAX;
-    }
-    gconf->has_debug_level = true;
-
-    glfs = qemu_gluster_init(gconf, filename, NULL, errp);
+    glfs = qemu_gluster_init(gconf, filename, errp);
     if (!glfs) {
         ret = -errno;
         goto out;
@@ -926,17 +524,19 @@ static int qemu_gluster_create(const char *filename,
     tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
     if (!tmp || !strcmp(tmp, "off")) {
         prealloc = 0;
-    } else if (!strcmp(tmp, "full") && gluster_supports_zerofill()) {
+    } else if (!strcmp(tmp, "full") &&
+               gluster_supports_zerofill()) {
         prealloc = 1;
     } else {
         error_setg(errp, "Invalid preallocation mode: '%s'"
-                         " or GlusterFS doesn't support zerofill API", tmp);
+            " or GlusterFS doesn't support zerofill API",
+            tmp);
         ret = -EINVAL;
         goto out;
     }
 
-    fd = glfs_creat(glfs, gconf->path,
-                    O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR);
+    fd = glfs_creat(glfs, gconf->image,
+        O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR);
     if (!fd) {
         ret = -errno;
     } else {
@@ -954,7 +554,7 @@ static int qemu_gluster_create(const char *filename,
     }
 out:
     g_free(tmp);
-    qapi_free_BlockdevOptionsGluster(gconf);
+    qemu_gluster_gconf_free(gconf);
     if (glfs) {
         glfs_fini(glfs);
     }
@@ -962,8 +562,7 @@ out:
 }
 
 static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
-                                           int64_t sector_num, int nb_sectors,
-                                           QEMUIOVector *qiov, int write)
+        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int write)
 {
     int ret;
     GlusterAIOCB acb;
@@ -978,10 +577,10 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
 
     if (write) {
         ret = glfs_pwritev_async(s->fd, qiov->iov, qiov->niov, offset, 0,
-                                 gluster_finish_aiocb, &acb);
+            gluster_finish_aiocb, &acb);
     } else {
         ret = glfs_preadv_async(s->fd, qiov->iov, qiov->niov, offset, 0,
-                                gluster_finish_aiocb, &acb);
+            gluster_finish_aiocb, &acb);
     }
 
     if (ret < 0) {
@@ -1006,17 +605,13 @@ static int qemu_gluster_truncate(BlockDriverState *bs, int64_t offset)
 }
 
 static coroutine_fn int qemu_gluster_co_readv(BlockDriverState *bs,
-                                              int64_t sector_num,
-                                              int nb_sectors,
-                                              QEMUIOVector *qiov)
+        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
     return qemu_gluster_co_rw(bs, sector_num, nb_sectors, qiov, 0);
 }
 
 static coroutine_fn int qemu_gluster_co_writev(BlockDriverState *bs,
-                                               int64_t sector_num,
-                                               int nb_sectors,
-                                               QEMUIOVector *qiov)
+        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
     return qemu_gluster_co_rw(bs, sector_num, nb_sectors, qiov, 1);
 }
@@ -1077,12 +672,14 @@ error:
 }
 
 #ifdef CONFIG_GLUSTERFS_DISCARD
-static coroutine_fn int qemu_gluster_co_pdiscard(BlockDriverState *bs,
-                                                 int64_t offset, int size)
+static coroutine_fn int qemu_gluster_co_discard(BlockDriverState *bs,
+        int64_t sector_num, int nb_sectors)
 {
     int ret;
     GlusterAIOCB acb;
     BDRVGlusterState *s = bs->opaque;
+    size_t size = nb_sectors * BDRV_SECTOR_SIZE;
+    off_t offset = sector_num * BDRV_SECTOR_SIZE;
 
     acb.size = 0;
     acb.ret = 0;
@@ -1132,164 +729,29 @@ static int qemu_gluster_has_zero_init(BlockDriverState *bs)
     return 0;
 }
 
-/*
- * Find allocation range in @bs around offset @start.
- * May change underlying file descriptor's file offset.
- * If @start is not in a hole, store @start in @data, and the
- * beginning of the next hole in @hole, and return 0.
- * If @start is in a non-trailing hole, store @start in @hole and the
- * beginning of the next non-hole in @data, and return 0.
- * If @start is in a trailing hole or beyond EOF, return -ENXIO.
- * If we can't find out, return a negative errno other than -ENXIO.
- *
- * (Shamefully copied from raw-posix.c, only miniscule adaptions.)
- */
-static int find_allocation(BlockDriverState *bs, off_t start,
-                           off_t *data, off_t *hole)
-{
-    BDRVGlusterState *s = bs->opaque;
-    off_t offs;
-
-    if (!s->supports_seek_data) {
-        return -ENOTSUP;
-    }
-
-    /*
-     * SEEK_DATA cases:
-     * D1. offs == start: start is in data
-     * D2. offs > start: start is in a hole, next data at offs
-     * D3. offs < 0, errno = ENXIO: either start is in a trailing hole
-     *                              or start is beyond EOF
-     *     If the latter happens, the file has been truncated behind
-     *     our back since we opened it.  All bets are off then.
-     *     Treating like a trailing hole is simplest.
-     * D4. offs < 0, errno != ENXIO: we learned nothing
-     */
-    offs = glfs_lseek(s->fd, start, SEEK_DATA);
-    if (offs < 0) {
-        return -errno;          /* D3 or D4 */
-    }
-    assert(offs >= start);
-
-    if (offs > start) {
-        /* D2: in hole, next data at offs */
-        *hole = start;
-        *data = offs;
-        return 0;
-    }
-
-    /* D1: in data, end not yet known */
-
-    /*
-     * SEEK_HOLE cases:
-     * H1. offs == start: start is in a hole
-     *     If this happens here, a hole has been dug behind our back
-     *     since the previous lseek().
-     * H2. offs > start: either start is in data, next hole at offs,
-     *                   or start is in trailing hole, EOF at offs
-     *     Linux treats trailing holes like any other hole: offs ==
-     *     start.  Solaris seeks to EOF instead: offs > start (blech).
-     *     If that happens here, a hole has been dug behind our back
-     *     since the previous lseek().
-     * H3. offs < 0, errno = ENXIO: start is beyond EOF
-     *     If this happens, the file has been truncated behind our
-     *     back since we opened it.  Treat it like a trailing hole.
-     * H4. offs < 0, errno != ENXIO: we learned nothing
-     *     Pretend we know nothing at all, i.e. "forget" about D1.
-     */
-    offs = glfs_lseek(s->fd, start, SEEK_HOLE);
-    if (offs < 0) {
-        return -errno;          /* D1 and (H3 or H4) */
-    }
-    assert(offs >= start);
-
-    if (offs > start) {
-        /*
-         * D1 and H2: either in data, next hole at offs, or it was in
-         * data but is now in a trailing hole.  In the latter case,
-         * all bets are off.  Treating it as if it there was data all
-         * the way to EOF is safe, so simply do that.
-         */
-        *data = start;
-        *hole = offs;
-        return 0;
-    }
-
-    /* D1 and H1 */
-    return -EBUSY;
-}
-
-/*
- * Returns the allocation status of the specified sectors.
- *
- * If 'sector_num' is beyond the end of the disk image the return value is 0
- * and 'pnum' is set to 0.
- *
- * 'pnum' is set to the number of sectors (including and immediately following
- * the specified sector) that are known to be in the same
- * allocated/unallocated state.
- *
- * 'nb_sectors' is the max value 'pnum' should be set to.  If nb_sectors goes
- * beyond the end of the disk image it will be clamped.
- *
- * (Based on raw_co_get_block_status() from raw-posix.c.)
- */
-static int64_t coroutine_fn qemu_gluster_co_get_block_status(
-        BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum,
-        BlockDriverState **file)
-{
-    BDRVGlusterState *s = bs->opaque;
-    off_t start, data = 0, hole = 0;
-    int64_t total_size;
-    int ret = -EINVAL;
-
-    if (!s->fd) {
-        return ret;
-    }
-
-    start = sector_num * BDRV_SECTOR_SIZE;
-    total_size = bdrv_getlength(bs);
-    if (total_size < 0) {
-        return total_size;
-    } else if (start >= total_size) {
-        *pnum = 0;
-        return 0;
-    } else if (start + nb_sectors * BDRV_SECTOR_SIZE > total_size) {
-        nb_sectors = DIV_ROUND_UP(total_size - start, BDRV_SECTOR_SIZE);
-    }
-
-    ret = find_allocation(bs, start, &data, &hole);
-    if (ret == -ENXIO) {
-        /* Trailing hole */
-        *pnum = nb_sectors;
-        ret = BDRV_BLOCK_ZERO;
-    } else if (ret < 0) {
-        /* No info available, so pretend there are no holes */
-        *pnum = nb_sectors;
-        ret = BDRV_BLOCK_DATA;
-    } else if (data == start) {
-        /* On a data extent, compute sectors to the end of the extent,
-         * possibly including a partial sector at EOF. */
-        *pnum = MIN(nb_sectors, DIV_ROUND_UP(hole - start, BDRV_SECTOR_SIZE));
-        ret = BDRV_BLOCK_DATA;
-    } else {
-        /* On a hole, compute sectors to the beginning of the next extent.  */
-        assert(hole == start);
-        *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE);
-        ret = BDRV_BLOCK_ZERO;
+static QemuOptsList qemu_gluster_create_opts = {
+    .name = "qemu-gluster-create-opts",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_gluster_create_opts.head),
+    .desc = {
+        {
+            .name = BLOCK_OPT_SIZE,
+            .type = QEMU_OPT_SIZE,
+            .help = "Virtual disk size"
+        },
+        {
+            .name = BLOCK_OPT_PREALLOC,
+            .type = QEMU_OPT_STRING,
+            .help = "Preallocation mode (allowed values: off, full)"
+        },
+        { /* end of list */ }
     }
-
-    *file = bs;
-
-    return ret | BDRV_BLOCK_OFFSET_VALID | start;
-}
-
+};
 
 static BlockDriver bdrv_gluster = {
     .format_name                  = "gluster",
     .protocol_name                = "gluster",
     .instance_size                = sizeof(BDRVGlusterState),
-    .bdrv_needs_filename          = false,
+    .bdrv_needs_filename          = true,
     .bdrv_file_open               = qemu_gluster_open,
     .bdrv_reopen_prepare          = qemu_gluster_reopen_prepare,
     .bdrv_reopen_commit           = qemu_gluster_reopen_commit,
@@ -1304,12 +766,11 @@ static BlockDriver bdrv_gluster = {
     .bdrv_co_flush_to_disk        = qemu_gluster_co_flush_to_disk,
     .bdrv_has_zero_init           = qemu_gluster_has_zero_init,
 #ifdef CONFIG_GLUSTERFS_DISCARD
-    .bdrv_co_pdiscard             = qemu_gluster_co_pdiscard,
+    .bdrv_co_discard              = qemu_gluster_co_discard,
 #endif
 #ifdef CONFIG_GLUSTERFS_ZEROFILL
-    .bdrv_co_pwrite_zeroes        = qemu_gluster_co_pwrite_zeroes,
+    .bdrv_co_write_zeroes         = qemu_gluster_co_write_zeroes,
 #endif
-    .bdrv_co_get_block_status     = qemu_gluster_co_get_block_status,
     .create_opts                  = &qemu_gluster_create_opts,
 };
 
@@ -1317,7 +778,7 @@ static BlockDriver bdrv_gluster_tcp = {
     .format_name                  = "gluster",
     .protocol_name                = "gluster+tcp",
     .instance_size                = sizeof(BDRVGlusterState),
-    .bdrv_needs_filename          = false,
+    .bdrv_needs_filename          = true,
     .bdrv_file_open               = qemu_gluster_open,
     .bdrv_reopen_prepare          = qemu_gluster_reopen_prepare,
     .bdrv_reopen_commit           = qemu_gluster_reopen_commit,
@@ -1332,12 +793,11 @@ static BlockDriver bdrv_gluster_tcp = {
     .bdrv_co_flush_to_disk        = qemu_gluster_co_flush_to_disk,
     .bdrv_has_zero_init           = qemu_gluster_has_zero_init,
 #ifdef CONFIG_GLUSTERFS_DISCARD
-    .bdrv_co_pdiscard             = qemu_gluster_co_pdiscard,
+    .bdrv_co_discard              = qemu_gluster_co_discard,
 #endif
 #ifdef CONFIG_GLUSTERFS_ZEROFILL
-    .bdrv_co_pwrite_zeroes        = qemu_gluster_co_pwrite_zeroes,
+    .bdrv_co_write_zeroes         = qemu_gluster_co_write_zeroes,
 #endif
-    .bdrv_co_get_block_status     = qemu_gluster_co_get_block_status,
     .create_opts                  = &qemu_gluster_create_opts,
 };
 
@@ -1360,21 +820,14 @@ static BlockDriver bdrv_gluster_unix = {
     .bdrv_co_flush_to_disk        = qemu_gluster_co_flush_to_disk,
     .bdrv_has_zero_init           = qemu_gluster_has_zero_init,
 #ifdef CONFIG_GLUSTERFS_DISCARD
-    .bdrv_co_pdiscard             = qemu_gluster_co_pdiscard,
+    .bdrv_co_discard              = qemu_gluster_co_discard,
 #endif
 #ifdef CONFIG_GLUSTERFS_ZEROFILL
-    .bdrv_co_pwrite_zeroes        = qemu_gluster_co_pwrite_zeroes,
+    .bdrv_co_write_zeroes         = qemu_gluster_co_write_zeroes,
 #endif
-    .bdrv_co_get_block_status     = qemu_gluster_co_get_block_status,
     .create_opts                  = &qemu_gluster_create_opts,
 };
 
-/* rdma is deprecated (actually never supported for volfile fetch).
- * Let's maintain it for the protocol compatibility, to make sure things
- * won't break immediately. For now, gluster+rdma will fall back to gluster+tcp
- * protocol with a warning.
- * TODO: remove gluster+rdma interface support
- */
 static BlockDriver bdrv_gluster_rdma = {
     .format_name                  = "gluster",
     .protocol_name                = "gluster+rdma",
@@ -1394,12 +847,11 @@ static BlockDriver bdrv_gluster_rdma = {
     .bdrv_co_flush_to_disk        = qemu_gluster_co_flush_to_disk,
     .bdrv_has_zero_init           = qemu_gluster_has_zero_init,
 #ifdef CONFIG_GLUSTERFS_DISCARD
-    .bdrv_co_pdiscard             = qemu_gluster_co_pdiscard,
+    .bdrv_co_discard              = qemu_gluster_co_discard,
 #endif
 #ifdef CONFIG_GLUSTERFS_ZEROFILL
-    .bdrv_co_pwrite_zeroes        = qemu_gluster_co_pwrite_zeroes,
+    .bdrv_co_write_zeroes         = qemu_gluster_co_write_zeroes,
 #endif
-    .bdrv_co_get_block_status     = qemu_gluster_co_get_block_status,
     .create_opts                  = &qemu_gluster_create_opts,
 };
 
index 420944d..d02e0d5 100644 (file)
 #include "sysemu/block-backend.h"
 #include "block/blockjob.h"
 #include "block/block_int.h"
+#include "block/throttle-groups.h"
 #include "qemu/cutils.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 
 #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
 
-static BlockAIOCB *bdrv_co_aio_prw_vector(BdrvChild *child,
-                                          int64_t offset,
-                                          QEMUIOVector *qiov,
-                                          BdrvRequestFlags flags,
-                                          BlockCompletionFunc *cb,
-                                          void *opaque,
-                                          bool is_write);
+static BlockAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
+        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+        BlockCompletionFunc *cb, void *opaque);
+static BlockAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
+        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+        BlockCompletionFunc *cb, void *opaque);
+static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
+                                         int64_t sector_num, int nb_sectors,
+                                         QEMUIOVector *iov);
+static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
+                                         int64_t sector_num, int nb_sectors,
+                                         QEMUIOVector *iov);
+static BlockAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
+                                         int64_t sector_num,
+                                         QEMUIOVector *qiov,
+                                         int nb_sectors,
+                                         BdrvRequestFlags flags,
+                                         BlockCompletionFunc *cb,
+                                         void *opaque,
+                                         bool is_write);
 static void coroutine_fn bdrv_co_do_rw(void *opaque);
-static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
-    int64_t offset, int count, BdrvRequestFlags flags);
+static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, BdrvRequestFlags flags);
 
-static void bdrv_parent_drained_begin(BlockDriverState *bs)
+/* throttling disk I/O limits */
+void bdrv_set_io_limits(BlockDriverState *bs,
+                        ThrottleConfig *cfg)
 {
-    BdrvChild *c;
+    int i;
 
-    QLIST_FOREACH(c, &bs->parents, next_parent) {
-        if (c->role->drained_begin) {
-            c->role->drained_begin(c);
-        }
+    throttle_group_config(bs, cfg);
+
+    for (i = 0; i < 2; i++) {
+        qemu_co_enter_next(&bs->throttled_reqs[i]);
     }
 }
 
-static void bdrv_parent_drained_end(BlockDriverState *bs)
+/* this function drain all the throttled IOs */
+static bool bdrv_start_throttled_reqs(BlockDriverState *bs)
 {
-    BdrvChild *c;
+    bool drained = false;
+    bool enabled = bs->io_limits_enabled;
+    int i;
 
-    QLIST_FOREACH(c, &bs->parents, next_parent) {
-        if (c->role->drained_end) {
-            c->role->drained_end(c);
+    bs->io_limits_enabled = false;
+
+    for (i = 0; i < 2; i++) {
+        while (qemu_co_enter_next(&bs->throttled_reqs[i])) {
+            drained = true;
         }
     }
+
+    bs->io_limits_enabled = enabled;
+
+    return drained;
+}
+
+void bdrv_io_limits_disable(BlockDriverState *bs)
+{
+    bs->io_limits_enabled = false;
+    bdrv_start_throttled_reqs(bs);
+    throttle_group_unregister_bs(bs);
+}
+
+/* should be called before bdrv_set_io_limits if a limit is set */
+void bdrv_io_limits_enable(BlockDriverState *bs, const char *group)
+{
+    assert(!bs->io_limits_enabled);
+    throttle_group_register_bs(bs, group);
+    bs->io_limits_enabled = true;
+}
+
+void bdrv_io_limits_update_group(BlockDriverState *bs, const char *group)
+{
+    /* this bs is not part of any group */
+    if (!bs->throttle_state) {
+        return;
+    }
+
+    /* this bs is a part of the same group than the one we want */
+    if (!g_strcmp0(throttle_group_get_name(bs), group)) {
+        return;
+    }
+
+    /* need to change the group this bs belong to */
+    bdrv_io_limits_disable(bs);
+    bdrv_io_limits_enable(bs, group);
 }
 
-static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src)
+void bdrv_setup_io_funcs(BlockDriver *bdrv)
 {
-    dst->opt_transfer = MAX(dst->opt_transfer, src->opt_transfer);
-    dst->max_transfer = MIN_NON_ZERO(dst->max_transfer, src->max_transfer);
-    dst->opt_mem_alignment = MAX(dst->opt_mem_alignment,
-                                 src->opt_mem_alignment);
-    dst->min_mem_alignment = MAX(dst->min_mem_alignment,
-                                 src->min_mem_alignment);
-    dst->max_iov = MIN_NON_ZERO(dst->max_iov, src->max_iov);
+    /* Block drivers without coroutine functions need emulation */
+    if (!bdrv->bdrv_co_readv) {
+        bdrv->bdrv_co_readv = bdrv_co_readv_em;
+        bdrv->bdrv_co_writev = bdrv_co_writev_em;
+
+        /* bdrv_co_readv_em()/brdv_co_writev_em() work in terms of aio, so if
+         * the block driver lacks aio we need to emulate that too.
+         */
+        if (!bdrv->bdrv_aio_readv) {
+            /* add AIO emulation layer */
+            bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
+            bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
+        }
+    }
 }
 
 void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
@@ -88,9 +152,6 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
         return;
     }
 
-    /* Default alignment based on whether driver has byte interface */
-    bs->bl.request_alignment = drv->bdrv_co_preadv ? 1 : 512;
-
     /* Take some limits from the children as a default */
     if (bs->file) {
         bdrv_refresh_limits(bs->file->bs, &local_err);
@@ -98,7 +159,11 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
             error_propagate(errp, local_err);
             return;
         }
-        bdrv_merge_limits(&bs->bl, &bs->file->bs->bl);
+        bs->bl.opt_transfer_length = bs->file->bs->bl.opt_transfer_length;
+        bs->bl.max_transfer_length = bs->file->bs->bl.max_transfer_length;
+        bs->bl.min_mem_alignment = bs->file->bs->bl.min_mem_alignment;
+        bs->bl.opt_mem_alignment = bs->file->bs->bl.opt_mem_alignment;
+        bs->bl.max_iov = bs->file->bs->bl.max_iov;
     } else {
         bs->bl.min_mem_alignment = 512;
         bs->bl.opt_mem_alignment = getpagesize();
@@ -113,7 +178,21 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
             error_propagate(errp, local_err);
             return;
         }
-        bdrv_merge_limits(&bs->bl, &bs->backing->bs->bl);
+        bs->bl.opt_transfer_length =
+            MAX(bs->bl.opt_transfer_length,
+                bs->backing->bs->bl.opt_transfer_length);
+        bs->bl.max_transfer_length =
+            MIN_NON_ZERO(bs->bl.max_transfer_length,
+                         bs->backing->bs->bl.max_transfer_length);
+        bs->bl.opt_mem_alignment =
+            MAX(bs->bl.opt_mem_alignment,
+                bs->backing->bs->bl.opt_mem_alignment);
+        bs->bl.min_mem_alignment =
+            MAX(bs->bl.min_mem_alignment,
+                bs->backing->bs->bl.min_mem_alignment);
+        bs->bl.max_iov =
+            MIN(bs->bl.max_iov,
+                bs->backing->bs->bl.max_iov);
     }
 
     /* Then let the driver override it */
@@ -146,6 +225,12 @@ bool bdrv_requests_pending(BlockDriverState *bs)
     if (!QLIST_EMPTY(&bs->tracked_requests)) {
         return true;
     }
+    if (!qemu_co_queue_empty(&bs->throttled_reqs[0])) {
+        return true;
+    }
+    if (!qemu_co_queue_empty(&bs->throttled_reqs[1])) {
+        return true;
+    }
 
     QLIST_FOREACH(child, &bs->children, next) {
         if (bdrv_requests_pending(child->bs)) {
@@ -175,29 +260,18 @@ typedef struct {
     bool done;
 } BdrvCoDrainData;
 
-static void bdrv_drain_poll(BlockDriverState *bs)
-{
-    bool busy = true;
-
-    while (busy) {
-        /* Keep iterating */
-        busy = bdrv_requests_pending(bs);
-        busy |= aio_poll(bdrv_get_aio_context(bs), busy);
-    }
-}
-
 static void bdrv_co_drain_bh_cb(void *opaque)
 {
     BdrvCoDrainData *data = opaque;
     Coroutine *co = data->co;
 
     qemu_bh_delete(data->bh);
-    bdrv_drain_poll(data->bs);
+    bdrv_drain(data->bs);
     data->done = true;
-    qemu_coroutine_enter(co);
+    qemu_coroutine_enter(co, NULL);
 }
 
-static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs)
+void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
 {
     BdrvCoDrainData data;
 
@@ -220,34 +294,6 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs)
     assert(data.done);
 }
 
-void bdrv_drained_begin(BlockDriverState *bs)
-{
-    if (!bs->quiesce_counter++) {
-        aio_disable_external(bdrv_get_aio_context(bs));
-        bdrv_parent_drained_begin(bs);
-    }
-
-    bdrv_io_unplugged_begin(bs);
-    bdrv_drain_recurse(bs);
-    if (qemu_in_coroutine()) {
-        bdrv_co_yield_to_drain(bs);
-    } else {
-        bdrv_drain_poll(bs);
-    }
-    bdrv_io_unplugged_end(bs);
-}
-
-void bdrv_drained_end(BlockDriverState *bs)
-{
-    assert(bs->quiesce_counter > 0);
-    if (--bs->quiesce_counter > 0) {
-        return;
-    }
-
-    bdrv_parent_drained_end(bs);
-    aio_enable_external(bdrv_get_aio_context(bs));
-}
-
 /*
  * Wait for pending requests to complete on a single BlockDriverState subtree,
  * and suspend block driver's internal I/O until next request arrives.
@@ -259,17 +305,21 @@ void bdrv_drained_end(BlockDriverState *bs)
  * not depend on events in other AioContexts.  In that case, use
  * bdrv_drain_all() instead.
  */
-void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
-{
-    assert(qemu_in_coroutine());
-    bdrv_drained_begin(bs);
-    bdrv_drained_end(bs);
-}
-
 void bdrv_drain(BlockDriverState *bs)
 {
-    bdrv_drained_begin(bs);
-    bdrv_drained_end(bs);
+    bool busy = true;
+
+    bdrv_drain_recurse(bs);
+    if (qemu_in_coroutine()) {
+        bdrv_co_drain(bs);
+        return;
+    }
+    while (busy) {
+        /* Keep iterating */
+         bdrv_flush_io_queue(bs);
+         busy = bdrv_requests_pending(bs);
+         busy |= aio_poll(bdrv_get_aio_context(bs), busy);
+    }
 }
 
 /*
@@ -282,25 +332,16 @@ void bdrv_drain_all(void)
 {
     /* Always run first iteration so any pending completion BHs run */
     bool busy = true;
-    BlockDriverState *bs;
-    BdrvNextIterator it;
-    BlockJob *job = NULL;
+    BlockDriverState *bs = NULL;
     GSList *aio_ctxs = NULL, *ctx;
 
-    while ((job = block_job_next(job))) {
-        AioContext *aio_context = blk_get_aio_context(job->blk);
-
-        aio_context_acquire(aio_context);
-        block_job_pause(job);
-        aio_context_release(aio_context);
-    }
-
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+    while ((bs = bdrv_next(bs))) {
         AioContext *aio_context = bdrv_get_aio_context(bs);
 
         aio_context_acquire(aio_context);
-        bdrv_parent_drained_begin(bs);
-        bdrv_io_unplugged_begin(bs);
+        if (bs->job) {
+            block_job_pause(bs->job);
+        }
         bdrv_drain_recurse(bs);
         aio_context_release(aio_context);
 
@@ -320,10 +361,12 @@ void bdrv_drain_all(void)
 
         for (ctx = aio_ctxs; ctx != NULL; ctx = ctx->next) {
             AioContext *aio_context = ctx->data;
+            bs = NULL;
 
             aio_context_acquire(aio_context);
-            for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+            while ((bs = bdrv_next(bs))) {
                 if (aio_context == bdrv_get_aio_context(bs)) {
+                    bdrv_flush_io_queue(bs);
                     if (bdrv_requests_pending(bs)) {
                         busy = true;
                         aio_poll(aio_context, busy);
@@ -335,24 +378,17 @@ void bdrv_drain_all(void)
         }
     }
 
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+    bs = NULL;
+    while ((bs = bdrv_next(bs))) {
         AioContext *aio_context = bdrv_get_aio_context(bs);
 
         aio_context_acquire(aio_context);
-        bdrv_io_unplugged_end(bs);
-        bdrv_parent_drained_end(bs);
+        if (bs->job) {
+            block_job_resume(bs->job);
+        }
         aio_context_release(aio_context);
     }
     g_slist_free(aio_ctxs);
-
-    job = NULL;
-    while ((job = block_job_next(job))) {
-        AioContext *aio_context = blk_get_aio_context(job->blk);
-
-        aio_context_acquire(aio_context);
-        block_job_resume(job);
-        aio_context_release(aio_context);
-    }
 }
 
 /**
@@ -411,12 +447,12 @@ static void mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
 }
 
 /**
- * Round a region to cluster boundaries (sector-based)
+ * Round a region to cluster boundaries
  */
-void bdrv_round_sectors_to_clusters(BlockDriverState *bs,
-                                    int64_t sector_num, int nb_sectors,
-                                    int64_t *cluster_sector_num,
-                                    int *cluster_nb_sectors)
+void bdrv_round_to_clusters(BlockDriverState *bs,
+                            int64_t sector_num, int nb_sectors,
+                            int64_t *cluster_sector_num,
+                            int *cluster_nb_sectors)
 {
     BlockDriverInfo bdi;
 
@@ -431,26 +467,6 @@ void bdrv_round_sectors_to_clusters(BlockDriverState *bs,
     }
 }
 
-/**
- * Round a region to cluster boundaries
- */
-void bdrv_round_to_clusters(BlockDriverState *bs,
-                            int64_t offset, unsigned int bytes,
-                            int64_t *cluster_offset,
-                            unsigned int *cluster_bytes)
-{
-    BlockDriverInfo bdi;
-
-    if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
-        *cluster_offset = offset;
-        *cluster_bytes = bytes;
-    } else {
-        int64_t c = bdi.cluster_size;
-        *cluster_offset = QEMU_ALIGN_DOWN(offset, c);
-        *cluster_bytes = QEMU_ALIGN_UP(offset - *cluster_offset + bytes, c);
-    }
-}
-
 static int bdrv_get_cluster_size(BlockDriverState *bs)
 {
     BlockDriverInfo bdi;
@@ -458,7 +474,7 @@ static int bdrv_get_cluster_size(BlockDriverState *bs)
 
     ret = bdrv_get_info(bs, &bdi);
     if (ret < 0 || bdi.cluster_size == 0) {
-        return bs->bl.request_alignment;
+        return bs->request_alignment;
     } else {
         return bdi.cluster_size;
     }
@@ -552,7 +568,7 @@ static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
 }
 
 typedef struct RwCo {
-    BdrvChild *child;
+    BlockDriverState *bs;
     int64_t offset;
     QEMUIOVector *qiov;
     bool is_write;
@@ -565,26 +581,26 @@ static void coroutine_fn bdrv_rw_co_entry(void *opaque)
     RwCo *rwco = opaque;
 
     if (!rwco->is_write) {
-        rwco->ret = bdrv_co_preadv(rwco->child, rwco->offset,
-                                   rwco->qiov->size, rwco->qiov,
-                                   rwco->flags);
+        rwco->ret = bdrv_co_do_preadv(rwco->bs, rwco->offset,
+                                      rwco->qiov->size, rwco->qiov,
+                                      rwco->flags);
     } else {
-        rwco->ret = bdrv_co_pwritev(rwco->child, rwco->offset,
-                                    rwco->qiov->size, rwco->qiov,
-                                    rwco->flags);
+        rwco->ret = bdrv_co_do_pwritev(rwco->bs, rwco->offset,
+                                       rwco->qiov->size, rwco->qiov,
+                                       rwco->flags);
     }
 }
 
 /*
  * Process a vectored synchronous request using coroutines
  */
-static int bdrv_prwv_co(BdrvChild *child, int64_t offset,
+static int bdrv_prwv_co(BlockDriverState *bs, int64_t offset,
                         QEMUIOVector *qiov, bool is_write,
                         BdrvRequestFlags flags)
 {
     Coroutine *co;
     RwCo rwco = {
-        .child = child,
+        .bs = bs,
         .offset = offset,
         .qiov = qiov,
         .is_write = is_write,
@@ -592,14 +608,25 @@ static int bdrv_prwv_co(BdrvChild *child, int64_t offset,
         .flags = flags,
     };
 
+    /**
+     * In sync call context, when the vcpu is blocked, this throttling timer
+     * will not fire; so the I/O throttling function has to be disabled here
+     * if it has been enabled.
+     */
+    if (bs->io_limits_enabled) {
+        fprintf(stderr, "Disabling I/O throttling on '%s' due "
+                        "to synchronous I/O.\n", bdrv_get_device_name(bs));
+        bdrv_io_limits_disable(bs);
+    }
+
     if (qemu_in_coroutine()) {
         /* Fast-path if already in coroutine context */
         bdrv_rw_co_entry(&rwco);
     } else {
-        AioContext *aio_context = bdrv_get_aio_context(child->bs);
+        AioContext *aio_context = bdrv_get_aio_context(bs);
 
-        co = qemu_coroutine_create(bdrv_rw_co_entry, &rwco);
-        qemu_coroutine_enter(co);
+        co = qemu_coroutine_create(bdrv_rw_co_entry);
+        qemu_coroutine_enter(co, &rwco);
         while (rwco.ret == NOT_DONE) {
             aio_poll(aio_context, true);
         }
@@ -610,7 +637,7 @@ static int bdrv_prwv_co(BdrvChild *child, int64_t offset,
 /*
  * Process a synchronous request using coroutines
  */
-static int bdrv_rw_co(BdrvChild *child, int64_t sector_num, uint8_t *buf,
+static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
                       int nb_sectors, bool is_write, BdrvRequestFlags flags)
 {
     QEMUIOVector qiov;
@@ -624,15 +651,15 @@ static int bdrv_rw_co(BdrvChild *child, int64_t sector_num, uint8_t *buf,
     }
 
     qemu_iovec_init_external(&qiov, &iov, 1);
-    return bdrv_prwv_co(child, sector_num << BDRV_SECTOR_BITS,
+    return bdrv_prwv_co(bs, sector_num << BDRV_SECTOR_BITS,
                         &qiov, is_write, flags);
 }
 
 /* return < 0 if error. See bdrv_write() for the return codes */
-int bdrv_read(BdrvChild *child, int64_t sector_num,
+int bdrv_read(BlockDriverState *bs, int64_t sector_num,
               uint8_t *buf, int nb_sectors)
 {
-    return bdrv_rw_co(child, sector_num, buf, nb_sectors, false, 0);
+    return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false, 0);
 }
 
 /* Return < 0 if error. Important errors are:
@@ -641,39 +668,30 @@ int bdrv_read(BdrvChild *child, int64_t sector_num,
   -EINVAL      Invalid sector number or nb_sectors
   -EACCES      Trying to write a read-only device
 */
-int bdrv_write(BdrvChild *child, int64_t sector_num,
+int bdrv_write(BlockDriverState *bs, int64_t sector_num,
                const uint8_t *buf, int nb_sectors)
 {
-    return bdrv_rw_co(child, sector_num, (uint8_t *)buf, nb_sectors, true, 0);
+    return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true, 0);
 }
 
-int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,
-                       int count, BdrvRequestFlags flags)
+int bdrv_write_zeroes(BlockDriverState *bs, int64_t sector_num,
+                      int nb_sectors, BdrvRequestFlags flags)
 {
-    QEMUIOVector qiov;
-    struct iovec iov = {
-        .iov_base = NULL,
-        .iov_len = count,
-    };
-
-    qemu_iovec_init_external(&qiov, &iov, 1);
-    return bdrv_prwv_co(child, offset, &qiov, true,
-                        BDRV_REQ_ZERO_WRITE | flags);
+    return bdrv_rw_co(bs, sector_num, NULL, nb_sectors, true,
+                      BDRV_REQ_ZERO_WRITE | flags);
 }
 
 /*
- * Completely zero out a block device with the help of bdrv_pwrite_zeroes.
+ * Completely zero out a block device with the help of bdrv_write_zeroes.
  * The operation is sped up by checking the block status and only writing
  * zeroes to the device if they currently do not return zeroes. Optional
- * flags are passed through to bdrv_pwrite_zeroes (e.g. BDRV_REQ_MAY_UNMAP,
- * BDRV_REQ_FUA).
+ * flags are passed through to bdrv_write_zeroes (e.g. BDRV_REQ_MAY_UNMAP).
  *
  * Returns < 0 on error, 0 on success. For error codes see bdrv_write().
  */
-int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
+int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags)
 {
     int64_t target_sectors, ret, nb_sectors, sector_num = 0;
-    BlockDriverState *bs = child->bs;
     BlockDriverState *file;
     int n;
 
@@ -697,8 +715,7 @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
             sector_num += n;
             continue;
         }
-        ret = bdrv_pwrite_zeroes(child, sector_num << BDRV_SECTOR_BITS,
-                                 n << BDRV_SECTOR_BITS, flags);
+        ret = bdrv_write_zeroes(bs, sector_num, n, flags);
         if (ret < 0) {
             error_report("error writing zeroes at sector %" PRId64 ": %s",
                          sector_num, strerror(-ret));
@@ -708,39 +725,33 @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
     }
 }
 
-int bdrv_preadv(BdrvChild *child, int64_t offset, QEMUIOVector *qiov)
-{
-    int ret;
-
-    ret = bdrv_prwv_co(child, offset, qiov, false, 0);
-    if (ret < 0) {
-        return ret;
-    }
-
-    return qiov->size;
-}
-
-int bdrv_pread(BdrvChild *child, int64_t offset, void *buf, int bytes)
+int bdrv_pread(BlockDriverState *bs, int64_t offset, void *buf, int bytes)
 {
     QEMUIOVector qiov;
     struct iovec iov = {
         .iov_base = (void *)buf,
         .iov_len = bytes,
     };
+    int ret;
 
     if (bytes < 0) {
         return -EINVAL;
     }
 
     qemu_iovec_init_external(&qiov, &iov, 1);
-    return bdrv_preadv(child, offset, &qiov);
+    ret = bdrv_prwv_co(bs, offset, &qiov, false, 0);
+    if (ret < 0) {
+        return ret;
+    }
+
+    return bytes;
 }
 
-int bdrv_pwritev(BdrvChild *child, int64_t offset, QEMUIOVector *qiov)
+int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov)
 {
     int ret;
 
-    ret = bdrv_prwv_co(child, offset, qiov, true, 0);
+    ret = bdrv_prwv_co(bs, offset, qiov, true, 0);
     if (ret < 0) {
         return ret;
     }
@@ -748,7 +759,8 @@ int bdrv_pwritev(BdrvChild *child, int64_t offset, QEMUIOVector *qiov)
     return qiov->size;
 }
 
-int bdrv_pwrite(BdrvChild *child, int64_t offset, const void *buf, int bytes)
+int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
+                const void *buf, int bytes)
 {
     QEMUIOVector qiov;
     struct iovec iov = {
@@ -761,7 +773,7 @@ int bdrv_pwrite(BdrvChild *child, int64_t offset, const void *buf, int bytes)
     }
 
     qemu_iovec_init_external(&qiov, &iov, 1);
-    return bdrv_pwritev(child, offset, &qiov);
+    return bdrv_pwritev(bs, offset, &qiov);
 }
 
 /*
@@ -770,17 +782,17 @@ int bdrv_pwrite(BdrvChild *child, int64_t offset, const void *buf, int bytes)
  *
  * Returns 0 on success, -errno in error cases.
  */
-int bdrv_pwrite_sync(BdrvChild *child, int64_t offset,
-                     const void *buf, int count)
+int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
+    const void *buf, int count)
 {
     int ret;
 
-    ret = bdrv_pwrite(child, offset, buf, count);
+    ret = bdrv_pwrite(bs, offset, buf, count);
     if (ret < 0) {
         return ret;
     }
 
-    ret = bdrv_flush(child->bs);
+    ret = bdrv_flush(bs);
     if (ret < 0) {
         return ret;
     }
@@ -788,117 +800,8 @@ int bdrv_pwrite_sync(BdrvChild *child, int64_t offset,
     return 0;
 }
 
-typedef struct CoroutineIOCompletion {
-    Coroutine *coroutine;
-    int ret;
-} CoroutineIOCompletion;
-
-static void bdrv_co_io_em_complete(void *opaque, int ret)
-{
-    CoroutineIOCompletion *co = opaque;
-
-    co->ret = ret;
-    qemu_coroutine_enter(co->coroutine);
-}
-
-static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,
-                                           uint64_t offset, uint64_t bytes,
-                                           QEMUIOVector *qiov, int flags)
-{
-    BlockDriver *drv = bs->drv;
-    int64_t sector_num;
-    unsigned int nb_sectors;
-
-    assert(!(flags & ~BDRV_REQ_MASK));
-
-    if (drv->bdrv_co_preadv) {
-        return drv->bdrv_co_preadv(bs, offset, bytes, qiov, flags);
-    }
-
-    sector_num = offset >> BDRV_SECTOR_BITS;
-    nb_sectors = bytes >> BDRV_SECTOR_BITS;
-
-    assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
-    assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
-    assert((bytes >> BDRV_SECTOR_BITS) <= BDRV_REQUEST_MAX_SECTORS);
-
-    if (drv->bdrv_co_readv) {
-        return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
-    } else {
-        BlockAIOCB *acb;
-        CoroutineIOCompletion co = {
-            .coroutine = qemu_coroutine_self(),
-        };
-
-        acb = bs->drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
-                                      bdrv_co_io_em_complete, &co);
-        if (acb == NULL) {
-            return -EIO;
-        } else {
-            qemu_coroutine_yield();
-            return co.ret;
-        }
-    }
-}
-
-static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
-                                            uint64_t offset, uint64_t bytes,
-                                            QEMUIOVector *qiov, int flags)
-{
-    BlockDriver *drv = bs->drv;
-    int64_t sector_num;
-    unsigned int nb_sectors;
-    int ret;
-
-    assert(!(flags & ~BDRV_REQ_MASK));
-
-    if (drv->bdrv_co_pwritev) {
-        ret = drv->bdrv_co_pwritev(bs, offset, bytes, qiov,
-                                   flags & bs->supported_write_flags);
-        flags &= ~bs->supported_write_flags;
-        goto emulate_flags;
-    }
-
-    sector_num = offset >> BDRV_SECTOR_BITS;
-    nb_sectors = bytes >> BDRV_SECTOR_BITS;
-
-    assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
-    assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
-    assert((bytes >> BDRV_SECTOR_BITS) <= BDRV_REQUEST_MAX_SECTORS);
-
-    if (drv->bdrv_co_writev_flags) {
-        ret = drv->bdrv_co_writev_flags(bs, sector_num, nb_sectors, qiov,
-                                        flags & bs->supported_write_flags);
-        flags &= ~bs->supported_write_flags;
-    } else if (drv->bdrv_co_writev) {
-        assert(!bs->supported_write_flags);
-        ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
-    } else {
-        BlockAIOCB *acb;
-        CoroutineIOCompletion co = {
-            .coroutine = qemu_coroutine_self(),
-        };
-
-        acb = bs->drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors,
-                                       bdrv_co_io_em_complete, &co);
-        if (acb == NULL) {
-            ret = -EIO;
-        } else {
-            qemu_coroutine_yield();
-            ret = co.ret;
-        }
-    }
-
-emulate_flags:
-    if (ret == 0 && (flags & BDRV_REQ_FUA)) {
-        ret = bdrv_co_flush(bs);
-    }
-
-    return ret;
-}
-
 static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs,
-        int64_t offset, unsigned int bytes, QEMUIOVector *qiov)
+        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
     /* Perform I/O through a temporary buffer so that users who scribble over
      * their read buffer while the operation is in progress do not end up
@@ -910,20 +813,21 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs,
     BlockDriver *drv = bs->drv;
     struct iovec iov;
     QEMUIOVector bounce_qiov;
-    int64_t cluster_offset;
-    unsigned int cluster_bytes;
+    int64_t cluster_sector_num;
+    int cluster_nb_sectors;
     size_t skip_bytes;
     int ret;
 
     /* Cover entire cluster so no additional backing file I/O is required when
      * allocating cluster in the image file.
      */
-    bdrv_round_to_clusters(bs, offset, bytes, &cluster_offset, &cluster_bytes);
+    bdrv_round_to_clusters(bs, sector_num, nb_sectors,
+                           &cluster_sector_num, &cluster_nb_sectors);
 
-    trace_bdrv_co_do_copy_on_readv(bs, offset, bytes,
-                                   cluster_offset, cluster_bytes);
+    trace_bdrv_co_do_copy_on_readv(bs, sector_num, nb_sectors,
+                                   cluster_sector_num, cluster_nb_sectors);
 
-    iov.iov_len = cluster_bytes;
+    iov.iov_len = cluster_nb_sectors * BDRV_SECTOR_SIZE;
     iov.iov_base = bounce_buffer = qemu_try_blockalign(bs, iov.iov_len);
     if (bounce_buffer == NULL) {
         ret = -ENOMEM;
@@ -932,24 +836,22 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs,
 
     qemu_iovec_init_external(&bounce_qiov, &iov, 1);
 
-    ret = bdrv_driver_preadv(bs, cluster_offset, cluster_bytes,
-                             &bounce_qiov, 0);
+    ret = drv->bdrv_co_readv(bs, cluster_sector_num, cluster_nb_sectors,
+                             &bounce_qiov);
     if (ret < 0) {
         goto err;
     }
 
-    if (drv->bdrv_co_pwrite_zeroes &&
+    if (drv->bdrv_co_write_zeroes &&
         buffer_is_zero(bounce_buffer, iov.iov_len)) {
-        /* FIXME: Should we (perhaps conditionally) be setting
-         * BDRV_REQ_MAY_UNMAP, if it will allow for a sparser copy
-         * that still correctly reads as zero? */
-        ret = bdrv_co_do_pwrite_zeroes(bs, cluster_offset, cluster_bytes, 0);
+        ret = bdrv_co_do_write_zeroes(bs, cluster_sector_num,
+                                      cluster_nb_sectors, 0);
     } else {
         /* This does not change the data on the disk, it is not necessary
          * to flush even in cache=writethrough mode.
          */
-        ret = bdrv_driver_pwritev(bs, cluster_offset, cluster_bytes,
-                                  &bounce_qiov, 0);
+        ret = drv->bdrv_co_writev(bs, cluster_sector_num, cluster_nb_sectors,
+                                  &bounce_qiov);
     }
 
     if (ret < 0) {
@@ -960,8 +862,9 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs,
         goto err;
     }
 
-    skip_bytes = offset - cluster_offset;
-    qemu_iovec_from_buf(qiov, 0, bounce_buffer + skip_bytes, bytes);
+    skip_bytes = (sector_num - cluster_sector_num) * BDRV_SECTOR_SIZE;
+    qemu_iovec_from_buf(qiov, 0, bounce_buffer + skip_bytes,
+                        nb_sectors * BDRV_SECTOR_SIZE);
 
 err:
     qemu_vfree(bounce_buffer);
@@ -970,31 +873,23 @@ err:
 
 /*
  * Forwards an already correctly aligned request to the BlockDriver. This
- * handles copy on read, zeroing after EOF, and fragmentation of large
- * reads; any other features must be implemented by the caller.
+ * handles copy on read and zeroing after EOF; any other features must be
+ * implemented by the caller.
  */
 static int coroutine_fn bdrv_aligned_preadv(BlockDriverState *bs,
     BdrvTrackedRequest *req, int64_t offset, unsigned int bytes,
     int64_t align, QEMUIOVector *qiov, int flags)
 {
-    int64_t total_bytes, max_bytes;
-    int ret = 0;
-    uint64_t bytes_remaining = bytes;
-    int max_transfer;
+    BlockDriver *drv = bs->drv;
+    int ret;
+
+    int64_t sector_num = offset >> BDRV_SECTOR_BITS;
+    unsigned int nb_sectors = bytes >> BDRV_SECTOR_BITS;
 
-    assert(is_power_of_2(align));
-    assert((offset & (align - 1)) == 0);
-    assert((bytes & (align - 1)) == 0);
+    assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
+    assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
     assert(!qiov || bytes == qiov->size);
     assert((bs->open_flags & BDRV_O_NO_IO) == 0);
-    max_transfer = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_transfer, INT_MAX),
-                                   align);
-
-    /* TODO: We would need a per-BDS .supported_read_flags and
-     * potential fallback support, if we ever implement any read flags
-     * to pass through to drivers.  For now, there aren't any
-     * passthrough flags.  */
-    assert(!(flags & ~(BDRV_REQ_NO_SERIALISING | BDRV_REQ_COPY_ON_READ)));
 
     /* Handle Copy on Read and associated serialisation */
     if (flags & BDRV_REQ_COPY_ON_READ) {
@@ -1011,77 +906,76 @@ static int coroutine_fn bdrv_aligned_preadv(BlockDriverState *bs,
     }
 
     if (flags & BDRV_REQ_COPY_ON_READ) {
-        int64_t start_sector = offset >> BDRV_SECTOR_BITS;
-        int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
-        unsigned int nb_sectors = end_sector - start_sector;
         int pnum;
 
-        ret = bdrv_is_allocated(bs, start_sector, nb_sectors, &pnum);
+        ret = bdrv_is_allocated(bs, sector_num, nb_sectors, &pnum);
         if (ret < 0) {
             goto out;
         }
 
         if (!ret || pnum != nb_sectors) {
-            ret = bdrv_co_do_copy_on_readv(bs, offset, bytes, qiov);
+            ret = bdrv_co_do_copy_on_readv(bs, sector_num, nb_sectors, qiov);
             goto out;
         }
     }
 
-    /* Forward the request to the BlockDriver, possibly fragmenting it */
-    total_bytes = bdrv_getlength(bs);
-    if (total_bytes < 0) {
-        ret = total_bytes;
-        goto out;
-    }
-
-    max_bytes = ROUND_UP(MAX(0, total_bytes - offset), align);
-    if (bytes <= max_bytes && bytes <= max_transfer) {
-        ret = bdrv_driver_preadv(bs, offset, bytes, qiov, 0);
-        goto out;
-    }
+    /* Forward the request to the BlockDriver */
+    if (!bs->zero_beyond_eof) {
+        ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
+    } else {
+        /* Read zeros after EOF */
+        int64_t total_sectors, max_nb_sectors;
 
-    while (bytes_remaining) {
-        int num;
+        total_sectors = bdrv_nb_sectors(bs);
+        if (total_sectors < 0) {
+            ret = total_sectors;
+            goto out;
+        }
 
-        if (max_bytes) {
+        max_nb_sectors = ROUND_UP(MAX(0, total_sectors - sector_num),
+                                  align >> BDRV_SECTOR_BITS);
+        if (nb_sectors < max_nb_sectors) {
+            ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
+        } else if (max_nb_sectors > 0) {
             QEMUIOVector local_qiov;
 
-            num = MIN(bytes_remaining, MIN(max_bytes, max_transfer));
-            assert(num);
             qemu_iovec_init(&local_qiov, qiov->niov);
-            qemu_iovec_concat(&local_qiov, qiov, bytes - bytes_remaining, num);
+            qemu_iovec_concat(&local_qiov, qiov, 0,
+                              max_nb_sectors * BDRV_SECTOR_SIZE);
+
+            ret = drv->bdrv_co_readv(bs, sector_num, max_nb_sectors,
+                                     &local_qiov);
 
-            ret = bdrv_driver_preadv(bs, offset + bytes - bytes_remaining,
-                                     num, &local_qiov, 0);
-            max_bytes -= num;
             qemu_iovec_destroy(&local_qiov);
         } else {
-            num = bytes_remaining;
-            ret = qemu_iovec_memset(qiov, bytes - bytes_remaining, 0,
-                                    bytes_remaining);
+            ret = 0;
         }
-        if (ret < 0) {
-            goto out;
+
+        /* Reading beyond end of file is supposed to produce zeroes */
+        if (ret == 0 && total_sectors < sector_num + nb_sectors) {
+            uint64_t offset = MAX(0, total_sectors - sector_num);
+            uint64_t bytes = (sector_num + nb_sectors - offset) *
+                              BDRV_SECTOR_SIZE;
+            qemu_iovec_memset(qiov, offset * BDRV_SECTOR_SIZE, 0, bytes);
         }
-        bytes_remaining -= num;
     }
 
 out:
-    return ret < 0 ? ret : 0;
+    return ret;
 }
 
 /*
  * Handle a read request in coroutine context
  */
-int coroutine_fn bdrv_co_preadv(BdrvChild *child,
+int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs,
     int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
     BdrvRequestFlags flags)
 {
-    BlockDriverState *bs = child->bs;
     BlockDriver *drv = bs->drv;
     BdrvTrackedRequest req;
 
-    uint64_t align = bs->bl.request_alignment;
+    /* TODO Lift BDRV_SECTOR_SIZE restriction in BlockDriver interface */
+    uint64_t align = MAX(BDRV_SECTOR_SIZE, bs->request_alignment);
     uint8_t *head_buf = NULL;
     uint8_t *tail_buf = NULL;
     QEMUIOVector local_qiov;
@@ -1102,6 +996,11 @@ int coroutine_fn bdrv_co_preadv(BdrvChild *child,
         flags |= BDRV_REQ_COPY_ON_READ;
     }
 
+    /* throttling disk I/O */
+    if (bs->io_limits_enabled) {
+        throttle_group_co_io_limits_intercept(bs, bytes, false);
+    }
+
     /* Align read if necessary by padding qiov */
     if (offset & (align - 1)) {
         head_buf = qemu_blockalign(bs, align);
@@ -1142,7 +1041,7 @@ int coroutine_fn bdrv_co_preadv(BdrvChild *child,
     return ret;
 }
 
-static int coroutine_fn bdrv_co_do_readv(BdrvChild *child,
+static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,
     BdrvRequestFlags flags)
 {
@@ -1150,56 +1049,67 @@ static int coroutine_fn bdrv_co_do_readv(BdrvChild *child,
         return -EINVAL;
     }
 
-    return bdrv_co_preadv(child, sector_num << BDRV_SECTOR_BITS,
-                          nb_sectors << BDRV_SECTOR_BITS, qiov, flags);
+    return bdrv_co_do_preadv(bs, sector_num << BDRV_SECTOR_BITS,
+                             nb_sectors << BDRV_SECTOR_BITS, qiov, flags);
 }
 
-int coroutine_fn bdrv_co_readv(BdrvChild *child, int64_t sector_num,
-                               int nb_sectors, QEMUIOVector *qiov)
+int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
+    int nb_sectors, QEMUIOVector *qiov)
+{
+    trace_bdrv_co_readv(bs, sector_num, nb_sectors);
+
+    return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov, 0);
+}
+
+int coroutine_fn bdrv_co_readv_no_serialising(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
+{
+    trace_bdrv_co_readv_no_serialising(bs, sector_num, nb_sectors);
+
+    return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov,
+                            BDRV_REQ_NO_SERIALISING);
+}
+
+int coroutine_fn bdrv_co_copy_on_readv(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
-    trace_bdrv_co_readv(child->bs, sector_num, nb_sectors);
+    trace_bdrv_co_copy_on_readv(bs, sector_num, nb_sectors);
 
-    return bdrv_co_do_readv(child, sector_num, nb_sectors, qiov, 0);
+    return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov,
+                            BDRV_REQ_COPY_ON_READ);
 }
 
-/* Maximum buffer for write zeroes fallback, in bytes */
-#define MAX_WRITE_ZEROES_BOUNCE_BUFFER (32768 << BDRV_SECTOR_BITS)
+#define MAX_WRITE_ZEROES_BOUNCE_BUFFER 32768
 
-static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
-    int64_t offset, int count, BdrvRequestFlags flags)
+static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, BdrvRequestFlags flags)
 {
     BlockDriver *drv = bs->drv;
     QEMUIOVector qiov;
     struct iovec iov = {0};
     int ret = 0;
-    bool need_flush = false;
-    int head = 0;
-    int tail = 0;
-
-    int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes, INT_MAX);
-    int alignment = MAX(bs->bl.pwrite_zeroes_alignment,
-                        bs->bl.request_alignment);
 
-    assert(alignment % bs->bl.request_alignment == 0);
-    head = offset % alignment;
-    tail = (offset + count) % alignment;
-    max_write_zeroes = QEMU_ALIGN_DOWN(max_write_zeroes, alignment);
-    assert(max_write_zeroes >= bs->bl.request_alignment);
+    int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_write_zeroes,
+                                        BDRV_REQUEST_MAX_SECTORS);
 
-    while (count > 0 && !ret) {
-        int num = count;
+    while (nb_sectors > 0 && !ret) {
+        int num = nb_sectors;
 
         /* Align request.  Block drivers can expect the "bulk" of the request
-         * to be aligned, and that unaligned requests do not cross cluster
-         * boundaries.
+         * to be aligned.
          */
-        if (head) {
-            /* Make a small request up to the first aligned sector.  */
-            num = MIN(count, alignment - head);
-            head = 0;
-        } else if (tail && num > alignment) {
-            /* Shorten the request to the last aligned sector.  */
-            num -= tail;
+        if (bs->bl.write_zeroes_alignment
+            && num > bs->bl.write_zeroes_alignment) {
+            if (sector_num % bs->bl.write_zeroes_alignment != 0) {
+                /* Make a small request up to the first aligned sector.  */
+                num = bs->bl.write_zeroes_alignment;
+                num -= sector_num % bs->bl.write_zeroes_alignment;
+            } else if ((sector_num + num) % bs->bl.write_zeroes_alignment != 0) {
+                /* Shorten the request to the last aligned sector.  num cannot
+                 * underflow because num > bs->bl.write_zeroes_alignment.
+                 */
+                num -= (sector_num + num) % bs->bl.write_zeroes_alignment;
+            }
         }
 
         /* limit request size */
@@ -1209,90 +1119,64 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
 
         ret = -ENOTSUP;
         /* First try the efficient write zeroes operation */
-        if (drv->bdrv_co_pwrite_zeroes) {
-            ret = drv->bdrv_co_pwrite_zeroes(bs, offset, num,
-                                             flags & bs->supported_zero_flags);
-            if (ret != -ENOTSUP && (flags & BDRV_REQ_FUA) &&
-                !(bs->supported_zero_flags & BDRV_REQ_FUA)) {
-                need_flush = true;
-            }
-        } else {
-            assert(!bs->supported_zero_flags);
+        if (drv->bdrv_co_write_zeroes) {
+            ret = drv->bdrv_co_write_zeroes(bs, sector_num, num, flags);
         }
 
         if (ret == -ENOTSUP) {
             /* Fall back to bounce buffer if write zeroes is unsupported */
-            int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
+            int max_xfer_len = MIN_NON_ZERO(bs->bl.max_transfer_length,
                                             MAX_WRITE_ZEROES_BOUNCE_BUFFER);
-            BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;
-
-            if ((flags & BDRV_REQ_FUA) &&
-                !(bs->supported_write_flags & BDRV_REQ_FUA)) {
-                /* No need for bdrv_driver_pwrite() to do a fallback
-                 * flush on each chunk; use just one at the end */
-                write_flags &= ~BDRV_REQ_FUA;
-                need_flush = true;
-            }
-            num = MIN(num, max_transfer);
-            iov.iov_len = num;
+            num = MIN(num, max_xfer_len);
+            iov.iov_len = num * BDRV_SECTOR_SIZE;
             if (iov.iov_base == NULL) {
-                iov.iov_base = qemu_try_blockalign(bs, num);
+                iov.iov_base = qemu_try_blockalign(bs, num * BDRV_SECTOR_SIZE);
                 if (iov.iov_base == NULL) {
                     ret = -ENOMEM;
                     goto fail;
                 }
-                memset(iov.iov_base, 0, num);
+                memset(iov.iov_base, 0, num * BDRV_SECTOR_SIZE);
             }
             qemu_iovec_init_external(&qiov, &iov, 1);
 
-            ret = bdrv_driver_pwritev(bs, offset, num, &qiov, write_flags);
+            ret = drv->bdrv_co_writev(bs, sector_num, num, &qiov);
 
             /* Keep bounce buffer around if it is big enough for all
              * all future requests.
              */
-            if (num < max_transfer) {
+            if (num < max_xfer_len) {
                 qemu_vfree(iov.iov_base);
                 iov.iov_base = NULL;
             }
         }
 
-        offset += num;
-        count -= num;
+        sector_num += num;
+        nb_sectors -= num;
     }
 
 fail:
-    if (ret == 0 && need_flush) {
-        ret = bdrv_co_flush(bs);
-    }
     qemu_vfree(iov.iov_base);
     return ret;
 }
 
 /*
- * Forwards an already correctly aligned write request to the BlockDriver,
- * after possibly fragmenting it.
+ * Forwards an already correctly aligned write request to the BlockDriver.
  */
 static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs,
     BdrvTrackedRequest *req, int64_t offset, unsigned int bytes,
-    int64_t align, QEMUIOVector *qiov, int flags)
+    QEMUIOVector *qiov, int flags)
 {
     BlockDriver *drv = bs->drv;
     bool waited;
     int ret;
 
-    int64_t start_sector = offset >> BDRV_SECTOR_BITS;
-    int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
-    uint64_t bytes_remaining = bytes;
-    int max_transfer;
+    int64_t sector_num = offset >> BDRV_SECTOR_BITS;
+    unsigned int nb_sectors = bytes >> BDRV_SECTOR_BITS;
 
-    assert(is_power_of_2(align));
-    assert((offset & (align - 1)) == 0);
-    assert((bytes & (align - 1)) == 0);
+    assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
+    assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
     assert(!qiov || bytes == qiov->size);
     assert((bs->open_flags & BDRV_O_NO_IO) == 0);
-    assert(!(flags & ~BDRV_REQ_MASK));
-    max_transfer = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_transfer, INT_MAX),
-                                   align);
 
     waited = wait_serialising_requests(req);
     assert(!waited || !req->serialising);
@@ -1302,7 +1186,7 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs,
     ret = notifier_with_return_list_notify(&bs->before_write_notifiers, req);
 
     if (!ret && bs->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF &&
-        !(flags & BDRV_REQ_ZERO_WRITE) && drv->bdrv_co_pwrite_zeroes &&
+        !(flags & BDRV_REQ_ZERO_WRITE) && drv->bdrv_co_write_zeroes &&
         qemu_iovec_is_zero(qiov)) {
         flags |= BDRV_REQ_ZERO_WRITE;
         if (bs->detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP) {
@@ -1314,48 +1198,32 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs,
         /* Do nothing, write notifier decided to fail this request */
     } else if (flags & BDRV_REQ_ZERO_WRITE) {
         bdrv_debug_event(bs, BLKDBG_PWRITEV_ZERO);
-        ret = bdrv_co_do_pwrite_zeroes(bs, offset, bytes, flags);
-    } else if (bytes <= max_transfer) {
+        ret = bdrv_co_do_write_zeroes(bs, sector_num, nb_sectors, flags);
+    } else if (drv->bdrv_co_writev_flags) {
         bdrv_debug_event(bs, BLKDBG_PWRITEV);
-        ret = bdrv_driver_pwritev(bs, offset, bytes, qiov, flags);
+        ret = drv->bdrv_co_writev_flags(bs, sector_num, nb_sectors, qiov,
+                                        flags);
     } else {
+        assert(drv->supported_write_flags == 0);
         bdrv_debug_event(bs, BLKDBG_PWRITEV);
-        while (bytes_remaining) {
-            int num = MIN(bytes_remaining, max_transfer);
-            QEMUIOVector local_qiov;
-            int local_flags = flags;
-
-            assert(num);
-            if (num < bytes_remaining && (flags & BDRV_REQ_FUA) &&
-                !(bs->supported_write_flags & BDRV_REQ_FUA)) {
-                /* If FUA is going to be emulated by flush, we only
-                 * need to flush on the last iteration */
-                local_flags &= ~BDRV_REQ_FUA;
-            }
-            qemu_iovec_init(&local_qiov, qiov->niov);
-            qemu_iovec_concat(&local_qiov, qiov, bytes - bytes_remaining, num);
-
-            ret = bdrv_driver_pwritev(bs, offset + bytes - bytes_remaining,
-                                      num, &local_qiov, local_flags);
-            qemu_iovec_destroy(&local_qiov);
-            if (ret < 0) {
-                break;
-            }
-            bytes_remaining -= num;
-        }
+        ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
     }
     bdrv_debug_event(bs, BLKDBG_PWRITEV_DONE);
 
-    ++bs->write_gen;
-    bdrv_set_dirty(bs, start_sector, end_sector - start_sector);
+    if (ret == 0 && (flags & BDRV_REQ_FUA) &&
+        !(drv->supported_write_flags & BDRV_REQ_FUA))
+    {
+        ret = bdrv_co_flush(bs);
+    }
+
+    bdrv_set_dirty(bs, sector_num, nb_sectors);
 
     if (bs->wr_highest_offset < offset + bytes) {
         bs->wr_highest_offset = offset + bytes;
     }
 
     if (ret >= 0) {
-        bs->total_sectors = MAX(bs->total_sectors, end_sector);
-        ret = 0;
+        bs->total_sectors = MAX(bs->total_sectors, sector_num + nb_sectors);
     }
 
     return ret;
@@ -1370,7 +1238,7 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BlockDriverState *bs,
     uint8_t *buf = NULL;
     QEMUIOVector local_qiov;
     struct iovec iov;
-    uint64_t align = bs->bl.request_alignment;
+    uint64_t align = MAX(BDRV_SECTOR_SIZE, bs->request_alignment);
     unsigned int head_padding_bytes, tail_padding_bytes;
     int ret = 0;
 
@@ -1403,7 +1271,7 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BlockDriverState *bs,
 
         memset(buf + head_padding_bytes, 0, zero_bytes);
         ret = bdrv_aligned_pwritev(bs, req, offset & ~(align - 1), align,
-                                   align, &local_qiov,
+                                   &local_qiov,
                                    flags & ~BDRV_REQ_ZERO_WRITE);
         if (ret < 0) {
             goto fail;
@@ -1416,7 +1284,7 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BlockDriverState *bs,
     if (bytes >= align) {
         /* Write the aligned part in the middle. */
         uint64_t aligned_bytes = bytes & ~(align - 1);
-        ret = bdrv_aligned_pwritev(bs, req, offset, aligned_bytes, align,
+        ret = bdrv_aligned_pwritev(bs, req, offset, aligned_bytes,
                                    NULL, flags);
         if (ret < 0) {
             goto fail;
@@ -1440,7 +1308,7 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BlockDriverState *bs,
         bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
 
         memset(buf, 0, bytes);
-        ret = bdrv_aligned_pwritev(bs, req, offset, align, align,
+        ret = bdrv_aligned_pwritev(bs, req, offset, align,
                                    &local_qiov, flags & ~BDRV_REQ_ZERO_WRITE);
     }
 fail:
@@ -1452,13 +1320,13 @@ fail:
 /*
  * Handle a write request in coroutine context
  */
-int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
+int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
     int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
     BdrvRequestFlags flags)
 {
-    BlockDriverState *bs = child->bs;
     BdrvTrackedRequest req;
-    uint64_t align = bs->bl.request_alignment;
+    /* TODO Lift BDRV_SECTOR_SIZE restriction in BlockDriver interface */
+    uint64_t align = MAX(BDRV_SECTOR_SIZE, bs->request_alignment);
     uint8_t *head_buf = NULL;
     uint8_t *tail_buf = NULL;
     QEMUIOVector local_qiov;
@@ -1478,6 +1346,11 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
         return ret;
     }
 
+    /* throttling disk I/O */
+    if (bs->io_limits_enabled) {
+        throttle_group_co_io_limits_intercept(bs, bytes, true);
+    }
+
     /*
      * Align write if necessary by performing a read-modify-write cycle.
      * Pad qiov with the read parts and be sure to have a tracked request not
@@ -1519,14 +1392,6 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
 
         bytes += offset & (align - 1);
         offset = offset & ~(align - 1);
-
-        /* We have read the tail already if the request is smaller
-         * than one aligned block.
-         */
-        if (bytes < align) {
-            qemu_iovec_add(&local_qiov, head_buf + bytes, align - bytes);
-            bytes = align;
-        }
     }
 
     if ((offset + bytes) & (align - 1)) {
@@ -1566,7 +1431,7 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
         bytes = ROUND_UP(bytes, align);
     }
 
-    ret = bdrv_aligned_pwritev(bs, &req, offset, bytes, align,
+    ret = bdrv_aligned_pwritev(bs, &req, offset, bytes,
                                use_local_qiov ? &local_qiov : qiov,
                                flags);
 
@@ -1582,7 +1447,7 @@ out:
     return ret;
 }
 
-static int coroutine_fn bdrv_co_do_writev(BdrvChild *child,
+static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,
     BdrvRequestFlags flags)
 {
@@ -1590,29 +1455,30 @@ static int coroutine_fn bdrv_co_do_writev(BdrvChild *child,
         return -EINVAL;
     }
 
-    return bdrv_co_pwritev(child, sector_num << BDRV_SECTOR_BITS,
-                           nb_sectors << BDRV_SECTOR_BITS, qiov, flags);
+    return bdrv_co_do_pwritev(bs, sector_num << BDRV_SECTOR_BITS,
+                              nb_sectors << BDRV_SECTOR_BITS, qiov, flags);
 }
 
-int coroutine_fn bdrv_co_writev(BdrvChild *child, int64_t sector_num,
+int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
     int nb_sectors, QEMUIOVector *qiov)
 {
-    trace_bdrv_co_writev(child->bs, sector_num, nb_sectors);
+    trace_bdrv_co_writev(bs, sector_num, nb_sectors);
 
-    return bdrv_co_do_writev(child, sector_num, nb_sectors, qiov, 0);
+    return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov, 0);
 }
 
-int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
-                                       int count, BdrvRequestFlags flags)
+int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs,
+                                      int64_t sector_num, int nb_sectors,
+                                      BdrvRequestFlags flags)
 {
-    trace_bdrv_co_pwrite_zeroes(child->bs, offset, count, flags);
+    trace_bdrv_co_write_zeroes(bs, sector_num, nb_sectors, flags);
 
-    if (!(child->bs->open_flags & BDRV_O_UNMAP)) {
+    if (!(bs->open_flags & BDRV_O_UNMAP)) {
         flags &= ~BDRV_REQ_MAY_UNMAP;
     }
 
-    return bdrv_co_pwritev(child, offset, count, NULL,
-                           BDRV_REQ_ZERO_WRITE | flags);
+    return bdrv_co_do_writev(bs, sector_num, nb_sectors, NULL,
+                             BDRV_REQ_ZERO_WRITE | flags);
 }
 
 typedef struct BdrvCoGetBlockStatusData {
@@ -1797,9 +1663,8 @@ int64_t bdrv_get_block_status_above(BlockDriverState *bs,
     } else {
         AioContext *aio_context = bdrv_get_aio_context(bs);
 
-        co = qemu_coroutine_create(bdrv_get_block_status_above_co_entry,
-                                   &data);
-        qemu_coroutine_enter(co);
+        co = qemu_coroutine_create(bdrv_get_block_status_above_co_entry);
+        qemu_coroutine_enter(co, &data);
         while (!data.done) {
             aio_poll(aio_context, true);
         }
@@ -1901,134 +1766,273 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
     return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
 }
 
-typedef struct BdrvVmstateCo {
-    BlockDriverState    *bs;
-    QEMUIOVector        *qiov;
-    int64_t             pos;
-    bool                is_read;
-    int                 ret;
-} BdrvVmstateCo;
+int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
+                      int64_t pos, int size)
+{
+    QEMUIOVector qiov;
+    struct iovec iov = {
+        .iov_base   = (void *) buf,
+        .iov_len    = size,
+    };
+
+    qemu_iovec_init_external(&qiov, &iov, 1);
+    return bdrv_writev_vmstate(bs, &qiov, pos);
+}
 
-static int coroutine_fn
-bdrv_co_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos,
-                   bool is_read)
+int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
 {
     BlockDriver *drv = bs->drv;
 
     if (!drv) {
         return -ENOMEDIUM;
-    } else if (drv->bdrv_load_vmstate) {
-        return is_read ? drv->bdrv_load_vmstate(bs, qiov, pos)
-                       : drv->bdrv_save_vmstate(bs, qiov, pos);
+    } else if (drv->bdrv_save_vmstate) {
+        return drv->bdrv_save_vmstate(bs, qiov, pos);
     } else if (bs->file) {
-        return bdrv_co_rw_vmstate(bs->file->bs, qiov, pos, is_read);
+        return bdrv_writev_vmstate(bs->file->bs, qiov, pos);
     }
 
     return -ENOTSUP;
 }
 
-static void coroutine_fn bdrv_co_rw_vmstate_entry(void *opaque)
+int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
+                      int64_t pos, int size)
 {
-    BdrvVmstateCo *co = opaque;
-    co->ret = bdrv_co_rw_vmstate(co->bs, co->qiov, co->pos, co->is_read);
+    BlockDriver *drv = bs->drv;
+    if (!drv)
+        return -ENOMEDIUM;
+    if (drv->bdrv_load_vmstate)
+        return drv->bdrv_load_vmstate(bs, buf, pos, size);
+    if (bs->file)
+        return bdrv_load_vmstate(bs->file->bs, buf, pos, size);
+    return -ENOTSUP;
 }
 
-static inline int
-bdrv_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos,
-                bool is_read)
+/**************************************************************/
+/* async I/Os */
+
+BlockAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
+                           QEMUIOVector *qiov, int nb_sectors,
+                           BlockCompletionFunc *cb, void *opaque)
 {
-    if (qemu_in_coroutine()) {
-        return bdrv_co_rw_vmstate(bs, qiov, pos, is_read);
-    } else {
-        BdrvVmstateCo data = {
-            .bs         = bs,
-            .qiov       = qiov,
-            .pos        = pos,
-            .is_read    = is_read,
-            .ret        = -EINPROGRESS,
-        };
-        Coroutine *co = qemu_coroutine_create(bdrv_co_rw_vmstate_entry, &data);
+    trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
 
-        qemu_coroutine_enter(co);
-        while (data.ret == -EINPROGRESS) {
-            aio_poll(bdrv_get_aio_context(bs), true);
-        }
-        return data.ret;
-    }
+    return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 0,
+                                 cb, opaque, false);
 }
 
-int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
-                      int64_t pos, int size)
+BlockAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
+                            QEMUIOVector *qiov, int nb_sectors,
+                            BlockCompletionFunc *cb, void *opaque)
 {
-    QEMUIOVector qiov;
-    struct iovec iov = {
-        .iov_base   = (void *) buf,
-        .iov_len    = size,
-    };
-    int ret;
+    trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
 
-    qemu_iovec_init_external(&qiov, &iov, 1);
+    return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 0,
+                                 cb, opaque, true);
+}
 
-    ret = bdrv_writev_vmstate(bs, &qiov, pos);
-    if (ret < 0) {
-        return ret;
-    }
+BlockAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs,
+        int64_t sector_num, int nb_sectors, BdrvRequestFlags flags,
+        BlockCompletionFunc *cb, void *opaque)
+{
+    trace_bdrv_aio_write_zeroes(bs, sector_num, nb_sectors, flags, opaque);
 
-    return size;
+    return bdrv_co_aio_rw_vector(bs, sector_num, NULL, nb_sectors,
+                                 BDRV_REQ_ZERO_WRITE | flags,
+                                 cb, opaque, true);
 }
 
-int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
+
+typedef struct MultiwriteCB {
+    int error;
+    int num_requests;
+    int num_callbacks;
+    struct {
+        BlockCompletionFunc *cb;
+        void *opaque;
+        QEMUIOVector *free_qiov;
+    } callbacks[];
+} MultiwriteCB;
+
+static void multiwrite_user_cb(MultiwriteCB *mcb)
 {
-    return bdrv_rw_vmstate(bs, qiov, pos, false);
+    int i;
+
+    for (i = 0; i < mcb->num_callbacks; i++) {
+        mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error);
+        if (mcb->callbacks[i].free_qiov) {
+            qemu_iovec_destroy(mcb->callbacks[i].free_qiov);
+        }
+        g_free(mcb->callbacks[i].free_qiov);
+    }
 }
 
-int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
-                      int64_t pos, int size)
+static void multiwrite_cb(void *opaque, int ret)
 {
-    QEMUIOVector qiov;
-    struct iovec iov = {
-        .iov_base   = buf,
-        .iov_len    = size,
-    };
-    int ret;
+    MultiwriteCB *mcb = opaque;
 
-    qemu_iovec_init_external(&qiov, &iov, 1);
-    ret = bdrv_readv_vmstate(bs, &qiov, pos);
-    if (ret < 0) {
-        return ret;
+    trace_multiwrite_cb(mcb, ret);
+
+    if (ret < 0 && !mcb->error) {
+        mcb->error = ret;
     }
 
-    return size;
+    mcb->num_requests--;
+    if (mcb->num_requests == 0) {
+        multiwrite_user_cb(mcb);
+        g_free(mcb);
+    }
 }
 
-int bdrv_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
+static int multiwrite_req_compare(const void *a, const void *b)
 {
-    return bdrv_rw_vmstate(bs, qiov, pos, true);
-}
+    const BlockRequest *req1 = a, *req2 = b;
 
-/**************************************************************/
-/* async I/Os */
+    /*
+     * Note that we can't simply subtract req2->sector from req1->sector
+     * here as that could overflow the return value.
+     */
+    if (req1->sector > req2->sector) {
+        return 1;
+    } else if (req1->sector < req2->sector) {
+        return -1;
+    } else {
+        return 0;
+    }
+}
 
-BlockAIOCB *bdrv_aio_readv(BdrvChild *child, int64_t sector_num,
-                           QEMUIOVector *qiov, int nb_sectors,
-                           BlockCompletionFunc *cb, void *opaque)
+/*
+ * Takes a bunch of requests and tries to merge them. Returns the number of
+ * requests that remain after merging.
+ */
+static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
+    int num_reqs, MultiwriteCB *mcb)
 {
-    trace_bdrv_aio_readv(child->bs, sector_num, nb_sectors, opaque);
+    int i, outidx;
+
+    // Sort requests by start sector
+    qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare);
 
-    assert(nb_sectors << BDRV_SECTOR_BITS == qiov->size);
-    return bdrv_co_aio_prw_vector(child, sector_num << BDRV_SECTOR_BITS, qiov,
-                                  0, cb, opaque, false);
+    // Check if adjacent requests touch the same clusters. If so, combine them,
+    // filling up gaps with zero sectors.
+    outidx = 0;
+    for (i = 1; i < num_reqs; i++) {
+        int merge = 0;
+        int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors;
+
+        // Handle exactly sequential writes and overlapping writes.
+        if (reqs[i].sector <= oldreq_last) {
+            merge = 1;
+        }
+
+        if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 >
+            bs->bl.max_iov) {
+            merge = 0;
+        }
+
+        if (bs->bl.max_transfer_length && reqs[outidx].nb_sectors +
+            reqs[i].nb_sectors > bs->bl.max_transfer_length) {
+            merge = 0;
+        }
+
+        if (merge) {
+            size_t size;
+            QEMUIOVector *qiov = g_malloc0(sizeof(*qiov));
+            qemu_iovec_init(qiov,
+                reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1);
+
+            // Add the first request to the merged one. If the requests are
+            // overlapping, drop the last sectors of the first request.
+            size = (reqs[i].sector - reqs[outidx].sector) << 9;
+            qemu_iovec_concat(qiov, reqs[outidx].qiov, 0, size);
+
+            // We should need to add any zeros between the two requests
+            assert (reqs[i].sector <= oldreq_last);
+
+            // Add the second request
+            qemu_iovec_concat(qiov, reqs[i].qiov, 0, reqs[i].qiov->size);
+
+            // Add tail of first request, if necessary
+            if (qiov->size < reqs[outidx].qiov->size) {
+                qemu_iovec_concat(qiov, reqs[outidx].qiov, qiov->size,
+                                  reqs[outidx].qiov->size - qiov->size);
+            }
+
+            reqs[outidx].nb_sectors = qiov->size >> 9;
+            reqs[outidx].qiov = qiov;
+
+            mcb->callbacks[i].free_qiov = reqs[outidx].qiov;
+        } else {
+            outidx++;
+            reqs[outidx].sector     = reqs[i].sector;
+            reqs[outidx].nb_sectors = reqs[i].nb_sectors;
+            reqs[outidx].qiov       = reqs[i].qiov;
+        }
+    }
+
+    if (bs->blk) {
+        block_acct_merge_done(blk_get_stats(bs->blk), BLOCK_ACCT_WRITE,
+                              num_reqs - outidx - 1);
+    }
+
+    return outidx + 1;
 }
 
-BlockAIOCB *bdrv_aio_writev(BdrvChild *child, int64_t sector_num,
-                            QEMUIOVector *qiov, int nb_sectors,
-                            BlockCompletionFunc *cb, void *opaque)
+/*
+ * Submit multiple AIO write requests at once.
+ *
+ * On success, the function returns 0 and all requests in the reqs array have
+ * been submitted. In error case this function returns -1, and any of the
+ * requests may or may not be submitted yet. In particular, this means that the
+ * callback will be called for some of the requests, for others it won't. The
+ * caller must check the error field of the BlockRequest to wait for the right
+ * callbacks (if error != 0, no callback will be called).
+ *
+ * The implementation may modify the contents of the reqs array, e.g. to merge
+ * requests. However, the fields opaque and error are left unmodified as they
+ * are used to signal failure for a single request to the caller.
+ */
+int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
 {
-    trace_bdrv_aio_writev(child->bs, sector_num, nb_sectors, opaque);
+    MultiwriteCB *mcb;
+    int i;
+
+    /* don't submit writes if we don't have a medium */
+    if (bs->drv == NULL) {
+        for (i = 0; i < num_reqs; i++) {
+            reqs[i].error = -ENOMEDIUM;
+        }
+        return -1;
+    }
+
+    if (num_reqs == 0) {
+        return 0;
+    }
+
+    // Create MultiwriteCB structure
+    mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks));
+    mcb->num_requests = 0;
+    mcb->num_callbacks = num_reqs;
 
-    assert(nb_sectors << BDRV_SECTOR_BITS == qiov->size);
-    return bdrv_co_aio_prw_vector(child, sector_num << BDRV_SECTOR_BITS, qiov,
-                                  0, cb, opaque, true);
+    for (i = 0; i < num_reqs; i++) {
+        mcb->callbacks[i].cb = reqs[i].cb;
+        mcb->callbacks[i].opaque = reqs[i].opaque;
+    }
+
+    // Check for mergable requests
+    num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb);
+
+    trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs);
+
+    /* Run the aio requests. */
+    mcb->num_requests = num_reqs;
+    for (i = 0; i < num_reqs; i++) {
+        bdrv_co_aio_rw_vector(bs, reqs[i].sector, reqs[i].qiov,
+                              reqs[i].nb_sectors, reqs[i].flags,
+                              multiwrite_cb, mcb,
+                              true);
+    }
+
+    return 0;
 }
 
 void bdrv_aio_cancel(BlockAIOCB *acb)
@@ -2060,30 +2064,82 @@ void bdrv_aio_cancel_async(BlockAIOCB *acb)
 /**************************************************************/
 /* async block device emulation */
 
-typedef struct BlockRequest {
-    union {
-        /* Used during read, write, trim */
-        struct {
-            int64_t offset;
-            int bytes;
-            int flags;
-            QEMUIOVector *qiov;
-        };
-        /* Used during ioctl */
-        struct {
-            int req;
-            void *buf;
-        };
-    };
-    BlockCompletionFunc *cb;
-    void *opaque;
+typedef struct BlockAIOCBSync {
+    BlockAIOCB common;
+    QEMUBH *bh;
+    int ret;
+    /* vector translation state */
+    QEMUIOVector *qiov;
+    uint8_t *bounce;
+    int is_write;
+} BlockAIOCBSync;
+
+static const AIOCBInfo bdrv_em_aiocb_info = {
+    .aiocb_size         = sizeof(BlockAIOCBSync),
+};
+
+static void bdrv_aio_bh_cb(void *opaque)
+{
+    BlockAIOCBSync *acb = opaque;
+
+    if (!acb->is_write && acb->ret >= 0) {
+        qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size);
+    }
+    qemu_vfree(acb->bounce);
+    acb->common.cb(acb->common.opaque, acb->ret);
+    qemu_bh_delete(acb->bh);
+    acb->bh = NULL;
+    qemu_aio_unref(acb);
+}
+
+static BlockAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
+                                      int64_t sector_num,
+                                      QEMUIOVector *qiov,
+                                      int nb_sectors,
+                                      BlockCompletionFunc *cb,
+                                      void *opaque,
+                                      int is_write)
+
+{
+    BlockAIOCBSync *acb;
+
+    acb = qemu_aio_get(&bdrv_em_aiocb_info, bs, cb, opaque);
+    acb->is_write = is_write;
+    acb->qiov = qiov;
+    acb->bounce = qemu_try_blockalign(bs, qiov->size);
+    acb->bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_aio_bh_cb, acb);
+
+    if (acb->bounce == NULL) {
+        acb->ret = -ENOMEM;
+    } else if (is_write) {
+        qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
+        acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
+    } else {
+        acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
+    }
+
+    qemu_bh_schedule(acb->bh);
+
+    return &acb->common;
+}
+
+static BlockAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
+        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+        BlockCompletionFunc *cb, void *opaque)
+{
+    return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
+}
+
+static BlockAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
+        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+        BlockCompletionFunc *cb, void *opaque)
+{
+    return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
+}
 
-    int error;
-} BlockRequest;
 
 typedef struct BlockAIOCBCoroutine {
     BlockAIOCB common;
-    BdrvChild *child;
     BlockRequest req;
     bool is_write;
     bool need_bh;
@@ -2127,40 +2183,42 @@ static void bdrv_co_maybe_schedule_bh(BlockAIOCBCoroutine *acb)
 static void coroutine_fn bdrv_co_do_rw(void *opaque)
 {
     BlockAIOCBCoroutine *acb = opaque;
+    BlockDriverState *bs = acb->common.bs;
 
     if (!acb->is_write) {
-        acb->req.error = bdrv_co_preadv(acb->child, acb->req.offset,
-            acb->req.qiov->size, acb->req.qiov, acb->req.flags);
+        acb->req.error = bdrv_co_do_readv(bs, acb->req.sector,
+            acb->req.nb_sectors, acb->req.qiov, acb->req.flags);
     } else {
-        acb->req.error = bdrv_co_pwritev(acb->child, acb->req.offset,
-            acb->req.qiov->size, acb->req.qiov, acb->req.flags);
+        acb->req.error = bdrv_co_do_writev(bs, acb->req.sector,
+            acb->req.nb_sectors, acb->req.qiov, acb->req.flags);
     }
 
     bdrv_co_complete(acb);
 }
 
-static BlockAIOCB *bdrv_co_aio_prw_vector(BdrvChild *child,
-                                          int64_t offset,
-                                          QEMUIOVector *qiov,
-                                          BdrvRequestFlags flags,
-                                          BlockCompletionFunc *cb,
-                                          void *opaque,
-                                          bool is_write)
+static BlockAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
+                                         int64_t sector_num,
+                                         QEMUIOVector *qiov,
+                                         int nb_sectors,
+                                         BdrvRequestFlags flags,
+                                         BlockCompletionFunc *cb,
+                                         void *opaque,
+                                         bool is_write)
 {
     Coroutine *co;
     BlockAIOCBCoroutine *acb;
 
-    acb = qemu_aio_get(&bdrv_em_co_aiocb_info, child->bs, cb, opaque);
-    acb->child = child;
+    acb = qemu_aio_get(&bdrv_em_co_aiocb_info, bs, cb, opaque);
     acb->need_bh = true;
     acb->req.error = -EINPROGRESS;
-    acb->req.offset = offset;
+    acb->req.sector = sector_num;
+    acb->req.nb_sectors = nb_sectors;
     acb->req.qiov = qiov;
     acb->req.flags = flags;
     acb->is_write = is_write;
 
-    co = qemu_coroutine_create(bdrv_co_do_rw, acb);
-    qemu_coroutine_enter(co);
+    co = qemu_coroutine_create(bdrv_co_do_rw);
+    qemu_coroutine_enter(co, acb);
 
     bdrv_co_maybe_schedule_bh(acb);
     return &acb->common;
@@ -2187,37 +2245,38 @@ BlockAIOCB *bdrv_aio_flush(BlockDriverState *bs,
     acb->need_bh = true;
     acb->req.error = -EINPROGRESS;
 
-    co = qemu_coroutine_create(bdrv_aio_flush_co_entry, acb);
-    qemu_coroutine_enter(co);
+    co = qemu_coroutine_create(bdrv_aio_flush_co_entry);
+    qemu_coroutine_enter(co, acb);
 
     bdrv_co_maybe_schedule_bh(acb);
     return &acb->common;
 }
 
-static void coroutine_fn bdrv_aio_pdiscard_co_entry(void *opaque)
+static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
 {
     BlockAIOCBCoroutine *acb = opaque;
     BlockDriverState *bs = acb->common.bs;
 
-    acb->req.error = bdrv_co_pdiscard(bs, acb->req.offset, acb->req.bytes);
+    acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
     bdrv_co_complete(acb);
 }
 
-BlockAIOCB *bdrv_aio_pdiscard(BlockDriverState *bs, int64_t offset, int count,
-                              BlockCompletionFunc *cb, void *opaque)
+BlockAIOCB *bdrv_aio_discard(BlockDriverState *bs,
+        int64_t sector_num, int nb_sectors,
+        BlockCompletionFunc *cb, void *opaque)
 {
     Coroutine *co;
     BlockAIOCBCoroutine *acb;
 
-    trace_bdrv_aio_pdiscard(bs, offset, count, opaque);
+    trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque);
 
     acb = qemu_aio_get(&bdrv_em_co_aiocb_info, bs, cb, opaque);
     acb->need_bh = true;
     acb->req.error = -EINPROGRESS;
-    acb->req.offset = offset;
-    acb->req.bytes = count;
-    co = qemu_coroutine_create(bdrv_aio_pdiscard_co_entry, acb);
-    qemu_coroutine_enter(co);
+    acb->req.sector = sector_num;
+    acb->req.nb_sectors = nb_sectors;
+    co = qemu_coroutine_create(bdrv_aio_discard_co_entry);
+    qemu_coroutine_enter(co, acb);
 
     bdrv_co_maybe_schedule_bh(acb);
     return &acb->common;
@@ -2255,15 +2314,62 @@ void qemu_aio_unref(void *p)
 /**************************************************************/
 /* Coroutine block device emulation */
 
-typedef struct FlushCo {
-    BlockDriverState *bs;
+typedef struct CoroutineIOCompletion {
+    Coroutine *coroutine;
     int ret;
-} FlushCo;
+} CoroutineIOCompletion;
 
+static void bdrv_co_io_em_complete(void *opaque, int ret)
+{
+    CoroutineIOCompletion *co = opaque;
+
+    co->ret = ret;
+    qemu_coroutine_enter(co->coroutine, NULL);
+}
+
+static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,
+                                      int nb_sectors, QEMUIOVector *iov,
+                                      bool is_write)
+{
+    CoroutineIOCompletion co = {
+        .coroutine = qemu_coroutine_self(),
+    };
+    BlockAIOCB *acb;
+
+    if (is_write) {
+        acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
+                                       bdrv_co_io_em_complete, &co);
+    } else {
+        acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
+                                      bdrv_co_io_em_complete, &co);
+    }
+
+    trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb);
+    if (!acb) {
+        return -EIO;
+    }
+    qemu_coroutine_yield();
+
+    return co.ret;
+}
+
+static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
+                                         int64_t sector_num, int nb_sectors,
+                                         QEMUIOVector *iov)
+{
+    return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false);
+}
+
+static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
+                                         int64_t sector_num, int nb_sectors,
+                                         QEMUIOVector *iov)
+{
+    return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);
+}
 
 static void coroutine_fn bdrv_flush_co_entry(void *opaque)
 {
-    FlushCo *rwco = opaque;
+    RwCo *rwco = opaque;
 
     rwco->ret = bdrv_co_flush(rwco->bs);
 }
@@ -2280,15 +2386,6 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
 
     tracked_request_begin(&req, bs, 0, 0, BDRV_TRACKED_FLUSH);
 
-    int current_gen = bs->write_gen;
-
-    /* Wait until any previous flushes are completed */
-    while (bs->active_flush_req != NULL) {
-        qemu_co_queue_wait(&bs->flush_queue);
-    }
-
-    bs->active_flush_req = &req;
-
     /* Write back all layers by calling one driver function */
     if (bs->drv->bdrv_co_flush) {
         ret = bs->drv->bdrv_co_flush(bs);
@@ -2309,11 +2406,6 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
         goto flush_parent;
     }
 
-    /* Check if we really need to flush anything */
-    if (bs->flushed_gen == current_gen) {
-        goto flush_parent;
-    }
-
     BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_DISK);
     if (bs->drv->bdrv_co_flush_to_disk) {
         ret = bs->drv->bdrv_co_flush_to_disk(bs);
@@ -2344,7 +2436,6 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
          */
         ret = 0;
     }
-
     if (ret < 0) {
         goto out;
     }
@@ -2355,12 +2446,6 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
 flush_parent:
     ret = bs->file ? bdrv_co_flush(bs->file->bs) : 0;
 out:
-    /* Notify any pending flushes that we have completed */
-    bs->flushed_gen = current_gen;
-    bs->active_flush_req = NULL;
-    /* Return value is ignored - it's ok if wait queue is empty */
-    qemu_co_queue_next(&bs->flush_queue);
-
     tracked_request_end(&req);
     return ret;
 }
@@ -2368,52 +2453,51 @@ out:
 int bdrv_flush(BlockDriverState *bs)
 {
     Coroutine *co;
-    FlushCo flush_co = {
+    RwCo rwco = {
         .bs = bs,
         .ret = NOT_DONE,
     };
 
     if (qemu_in_coroutine()) {
         /* Fast-path if already in coroutine context */
-        bdrv_flush_co_entry(&flush_co);
+        bdrv_flush_co_entry(&rwco);
     } else {
         AioContext *aio_context = bdrv_get_aio_context(bs);
 
-        co = qemu_coroutine_create(bdrv_flush_co_entry, &flush_co);
-        qemu_coroutine_enter(co);
-        while (flush_co.ret == NOT_DONE) {
+        co = qemu_coroutine_create(bdrv_flush_co_entry);
+        qemu_coroutine_enter(co, &rwco);
+        while (rwco.ret == NOT_DONE) {
             aio_poll(aio_context, true);
         }
     }
 
-    return flush_co.ret;
+    return rwco.ret;
 }
 
 typedef struct DiscardCo {
     BlockDriverState *bs;
-    int64_t offset;
-    int count;
+    int64_t sector_num;
+    int nb_sectors;
     int ret;
 } DiscardCo;
-static void coroutine_fn bdrv_pdiscard_co_entry(void *opaque)
+static void coroutine_fn bdrv_discard_co_entry(void *opaque)
 {
     DiscardCo *rwco = opaque;
 
-    rwco->ret = bdrv_co_pdiscard(rwco->bs, rwco->offset, rwco->count);
+    rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors);
 }
 
-int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
-                                  int count)
+int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
+                                 int nb_sectors)
 {
     BdrvTrackedRequest req;
-    int max_pdiscard, ret;
-    int head, align;
+    int max_discard, ret;
 
     if (!bs->drv) {
         return -ENOMEDIUM;
     }
 
-    ret = bdrv_check_byte_request(bs, offset, count);
+    ret = bdrv_check_request(bs, sector_num, nb_sectors);
     if (ret < 0) {
         return ret;
     } else if (bs->read_only) {
@@ -2426,49 +2510,44 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
         return 0;
     }
 
-    if (!bs->drv->bdrv_co_pdiscard && !bs->drv->bdrv_aio_pdiscard) {
-        return 0;
-    }
-
-    /* Discard is advisory, so ignore any unaligned head or tail */
-    align = MAX(bs->bl.pdiscard_alignment, bs->bl.request_alignment);
-    assert(align % bs->bl.request_alignment == 0);
-    head = offset % align;
-    if (head) {
-        head = MIN(count, align - head);
-        count -= head;
-        offset += head;
-    }
-    count = QEMU_ALIGN_DOWN(count, align);
-    if (!count) {
+    if (!bs->drv->bdrv_co_discard && !bs->drv->bdrv_aio_discard) {
         return 0;
     }
 
-    tracked_request_begin(&req, bs, offset, count, BDRV_TRACKED_DISCARD);
+    tracked_request_begin(&req, bs, sector_num, nb_sectors,
+                          BDRV_TRACKED_DISCARD);
+    bdrv_set_dirty(bs, sector_num, nb_sectors);
 
-    ret = notifier_with_return_list_notify(&bs->before_write_notifiers, &req);
-    if (ret < 0) {
-        goto out;
-    }
-
-    max_pdiscard = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_pdiscard, INT_MAX),
-                                   align);
-    assert(max_pdiscard);
-
-    while (count > 0) {
+    max_discard = MIN_NON_ZERO(bs->bl.max_discard, BDRV_REQUEST_MAX_SECTORS);
+    while (nb_sectors > 0) {
         int ret;
-        int num = MIN(count, max_pdiscard);
+        int num = nb_sectors;
+
+        /* align request */
+        if (bs->bl.discard_alignment &&
+            num >= bs->bl.discard_alignment &&
+            sector_num % bs->bl.discard_alignment) {
+            if (num > bs->bl.discard_alignment) {
+                num = bs->bl.discard_alignment;
+            }
+            num -= sector_num % bs->bl.discard_alignment;
+        }
 
-        if (bs->drv->bdrv_co_pdiscard) {
-            ret = bs->drv->bdrv_co_pdiscard(bs, offset, num);
+        /* limit request size */
+        if (num > max_discard) {
+            num = max_discard;
+        }
+
+        if (bs->drv->bdrv_co_discard) {
+            ret = bs->drv->bdrv_co_discard(bs, sector_num, num);
         } else {
             BlockAIOCB *acb;
             CoroutineIOCompletion co = {
                 .coroutine = qemu_coroutine_self(),
             };
 
-            acb = bs->drv->bdrv_aio_pdiscard(bs, offset, num,
-                                             bdrv_co_io_em_complete, &co);
+            acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
+                                            bdrv_co_io_em_complete, &co);
             if (acb == NULL) {
                 ret = -EIO;
                 goto out;
@@ -2481,36 +2560,33 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
             goto out;
         }
 
-        offset += num;
-        count -= num;
+        sector_num += num;
+        nb_sectors -= num;
     }
     ret = 0;
 out:
-    ++bs->write_gen;
-    bdrv_set_dirty(bs, req.offset >> BDRV_SECTOR_BITS,
-                   req.bytes >> BDRV_SECTOR_BITS);
     tracked_request_end(&req);
     return ret;
 }
 
-int bdrv_pdiscard(BlockDriverState *bs, int64_t offset, int count)
+int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
 {
     Coroutine *co;
     DiscardCo rwco = {
         .bs = bs,
-        .offset = offset,
-        .count = count,
+        .sector_num = sector_num,
+        .nb_sectors = nb_sectors,
         .ret = NOT_DONE,
     };
 
     if (qemu_in_coroutine()) {
         /* Fast-path if already in coroutine context */
-        bdrv_pdiscard_co_entry(&rwco);
+        bdrv_discard_co_entry(&rwco);
     } else {
         AioContext *aio_context = bdrv_get_aio_context(bs);
 
-        co = qemu_coroutine_create(bdrv_pdiscard_co_entry, &rwco);
-        qemu_coroutine_enter(co);
+        co = qemu_coroutine_create(bdrv_discard_co_entry);
+        qemu_coroutine_enter(co, &rwco);
         while (rwco.ret == NOT_DONE) {
             aio_poll(aio_context, true);
         }
@@ -2572,9 +2648,9 @@ int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
         /* Fast-path if already in coroutine context */
         bdrv_co_ioctl_entry(&data);
     } else {
-        Coroutine *co = qemu_coroutine_create(bdrv_co_ioctl_entry, &data);
+        Coroutine *co = qemu_coroutine_create(bdrv_co_ioctl_entry);
 
-        qemu_coroutine_enter(co);
+        qemu_coroutine_enter(co, &data);
         while (data.ret == -EINPROGRESS) {
             aio_poll(bdrv_get_aio_context(bs), true);
         }
@@ -2602,8 +2678,8 @@ BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
     acb->req.error = -EINPROGRESS;
     acb->req.req = req;
     acb->req.buf = buf;
-    co = qemu_coroutine_create(bdrv_co_aio_ioctl_entry, acb);
-    qemu_coroutine_enter(co);
+    co = qemu_coroutine_create(bdrv_co_aio_ioctl_entry);
+    qemu_coroutine_enter(co, acb);
 
     bdrv_co_maybe_schedule_bh(acb);
     return &acb->common;
@@ -2671,66 +2747,48 @@ void bdrv_add_before_write_notifier(BlockDriverState *bs,
 
 void bdrv_io_plug(BlockDriverState *bs)
 {
-    BdrvChild *child;
-
-    QLIST_FOREACH(child, &bs->children, next) {
-        bdrv_io_plug(child->bs);
-    }
-
-    if (bs->io_plugged++ == 0 && bs->io_plug_disabled == 0) {
-        BlockDriver *drv = bs->drv;
-        if (drv && drv->bdrv_io_plug) {
-            drv->bdrv_io_plug(bs);
-        }
+    BlockDriver *drv = bs->drv;
+    if (drv && drv->bdrv_io_plug) {
+        drv->bdrv_io_plug(bs);
+    } else if (bs->file) {
+        bdrv_io_plug(bs->file->bs);
     }
 }
 
 void bdrv_io_unplug(BlockDriverState *bs)
 {
-    BdrvChild *child;
-
-    assert(bs->io_plugged);
-    if (--bs->io_plugged == 0 && bs->io_plug_disabled == 0) {
-        BlockDriver *drv = bs->drv;
-        if (drv && drv->bdrv_io_unplug) {
-            drv->bdrv_io_unplug(bs);
-        }
-    }
-
-    QLIST_FOREACH(child, &bs->children, next) {
-        bdrv_io_unplug(child->bs);
+    BlockDriver *drv = bs->drv;
+    if (drv && drv->bdrv_io_unplug) {
+        drv->bdrv_io_unplug(bs);
+    } else if (bs->file) {
+        bdrv_io_unplug(bs->file->bs);
     }
 }
 
-void bdrv_io_unplugged_begin(BlockDriverState *bs)
+void bdrv_flush_io_queue(BlockDriverState *bs)
 {
-    BdrvChild *child;
-
-    if (bs->io_plug_disabled++ == 0 && bs->io_plugged > 0) {
-        BlockDriver *drv = bs->drv;
-        if (drv && drv->bdrv_io_unplug) {
-            drv->bdrv_io_unplug(bs);
-        }
-    }
-
-    QLIST_FOREACH(child, &bs->children, next) {
-        bdrv_io_unplugged_begin(child->bs);
+    BlockDriver *drv = bs->drv;
+    if (drv && drv->bdrv_flush_io_queue) {
+        drv->bdrv_flush_io_queue(bs);
+    } else if (bs->file) {
+        bdrv_flush_io_queue(bs->file->bs);
     }
+    bdrv_start_throttled_reqs(bs);
 }
 
-void bdrv_io_unplugged_end(BlockDriverState *bs)
+void bdrv_drained_begin(BlockDriverState *bs)
 {
-    BdrvChild *child;
-
-    assert(bs->io_plug_disabled);
-    QLIST_FOREACH(child, &bs->children, next) {
-        bdrv_io_unplugged_end(child->bs);
+    if (!bs->quiesce_counter++) {
+        aio_disable_external(bdrv_get_aio_context(bs));
     }
+    bdrv_drain(bs);
+}
 
-    if (--bs->io_plug_disabled == 0 && bs->io_plugged > 0) {
-        BlockDriver *drv = bs->drv;
-        if (drv && drv->bdrv_io_plug) {
-            drv->bdrv_io_plug(bs);
-        }
+void bdrv_drained_end(BlockDriverState *bs)
+{
+    assert(bs->quiesce_counter > 0);
+    if (--bs->quiesce_counter > 0) {
+        return;
     }
+    aio_enable_external(bdrv_get_aio_context(bs));
 }
index 95ce9e1..0466c30 100644 (file)
@@ -2,7 +2,7 @@
  * QEMU Block driver for iSCSI images
  *
  * Copyright (c) 2010-2011 Ronnie Sahlberg <ronniesahlberg@gmail.com>
- * Copyright (c) 2012-2016 Peter Lieven <pl@kamp.de>
+ * Copyright (c) 2012-2015 Peter Lieven <pl@kamp.de>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -46,6 +46,7 @@
 
 #ifdef __linux__
 #include <scsi/sg.h>
+#include <block/scsi.h>
 #endif
 
 typedef struct IscsiLun {
@@ -61,23 +62,7 @@ typedef struct IscsiLun {
     struct scsi_inquiry_logical_block_provisioning lbp;
     struct scsi_inquiry_block_limits bl;
     unsigned char *zeroblock;
-    /* The allocmap tracks which clusters (pages) on the iSCSI target are
-     * allocated and which are not. In case a target returns zeros for
-     * unallocated pages (iscsilun->lprz) we can directly return zeros instead
-     * of reading zeros over the wire if a read request falls within an
-     * unallocated block. As there are 3 possible states we need 2 bitmaps to
-     * track. allocmap_valid keeps track if QEMU's information about a page is
-     * valid. allocmap tracks if a page is allocated or not. In case QEMU has no
-     * valid information about a page the corresponding allocmap entry should be
-     * switched to unallocated as well to force a new lookup of the allocation
-     * status as lookups are generally skipped if a page is suspect to be
-     * allocated. If a iSCSI target is opened with cache.direct = on the
-     * allocmap_valid does not exist turning all cached information invalid so
-     * that a fresh lookup is made for any page even if allocmap entry returns
-     * it's unallocated. */
-    unsigned long *allocmap;
-    unsigned long *allocmap_valid;
-    long allocmap_size;
+    unsigned long *allocationmap;
     int cluster_sectors;
     bool use_16_for_rw;
     bool write_protected;
@@ -168,7 +153,7 @@ static void iscsi_co_generic_bh_cb(void *opaque)
     struct IscsiTask *iTask = opaque;
     iTask->complete = 1;
     qemu_bh_delete(iTask->bh);
-    qemu_coroutine_enter(iTask->co);
+    qemu_coroutine_enter(iTask->co, NULL);
 }
 
 static void iscsi_retry_timer_expired(void *opaque)
@@ -176,7 +161,7 @@ static void iscsi_retry_timer_expired(void *opaque)
     struct IscsiTask *iTask = opaque;
     iTask->complete = 1;
     if (iTask->co) {
-        qemu_coroutine_enter(iTask->co);
+        qemu_coroutine_enter(iTask->co, NULL);
     }
 }
 
@@ -416,159 +401,55 @@ static int64_t sector_qemu2lun(int64_t sector, IscsiLun *iscsilun)
     return sector * BDRV_SECTOR_SIZE / iscsilun->block_size;
 }
 
-static bool is_byte_request_lun_aligned(int64_t offset, int count,
-                                        IscsiLun *iscsilun)
+static bool is_request_lun_aligned(int64_t sector_num, int nb_sectors,
+                                      IscsiLun *iscsilun)
 {
-    if (offset % iscsilun->block_size || count % iscsilun->block_size) {
-        error_report("iSCSI misaligned request: "
-                     "iscsilun->block_size %u, offset %" PRIi64
-                     ", count %d",
-                     iscsilun->block_size, offset, count);
-        return false;
-    }
-    return true;
-}
-
-static bool is_sector_request_lun_aligned(int64_t sector_num, int nb_sectors,
-                                          IscsiLun *iscsilun)
-{
-    assert(nb_sectors <= BDRV_REQUEST_MAX_SECTORS);
-    return is_byte_request_lun_aligned(sector_num << BDRV_SECTOR_BITS,
-                                       nb_sectors << BDRV_SECTOR_BITS,
-                                       iscsilun);
+    if ((sector_num * BDRV_SECTOR_SIZE) % iscsilun->block_size ||
+        (nb_sectors * BDRV_SECTOR_SIZE) % iscsilun->block_size) {
+            error_report("iSCSI misaligned request: "
+                         "iscsilun->block_size %u, sector_num %" PRIi64
+                         ", nb_sectors %d",
+                         iscsilun->block_size, sector_num, nb_sectors);
+            return 0;
+    }
+    return 1;
 }
 
-static void iscsi_allocmap_free(IscsiLun *iscsilun)
+static unsigned long *iscsi_allocationmap_init(IscsiLun *iscsilun)
 {
-    g_free(iscsilun->allocmap);
-    g_free(iscsilun->allocmap_valid);
-    iscsilun->allocmap = NULL;
-    iscsilun->allocmap_valid = NULL;
+    return bitmap_try_new(DIV_ROUND_UP(sector_lun2qemu(iscsilun->num_blocks,
+                                                       iscsilun),
+                                       iscsilun->cluster_sectors));
 }
 
-
-static int iscsi_allocmap_init(IscsiLun *iscsilun, int open_flags)
+static void iscsi_allocationmap_set(IscsiLun *iscsilun, int64_t sector_num,
+                                    int nb_sectors)
 {
-    iscsi_allocmap_free(iscsilun);
-
-    iscsilun->allocmap_size =
-        DIV_ROUND_UP(sector_lun2qemu(iscsilun->num_blocks, iscsilun),
-                     iscsilun->cluster_sectors);
-
-    iscsilun->allocmap = bitmap_try_new(iscsilun->allocmap_size);
-    if (!iscsilun->allocmap) {
-        return -ENOMEM;
-    }
-
-    if (open_flags & BDRV_O_NOCACHE) {
-        /* in case that cache.direct = on all allocmap entries are
-         * treated as invalid to force a relookup of the block
-         * status on every read request */
-        return 0;
-    }
-
-    iscsilun->allocmap_valid = bitmap_try_new(iscsilun->allocmap_size);
-    if (!iscsilun->allocmap_valid) {
-        /* if we are under memory pressure free the allocmap as well */
-        iscsi_allocmap_free(iscsilun);
-        return -ENOMEM;
-    }
-
-    return 0;
-}
-
-static void
-iscsi_allocmap_update(IscsiLun *iscsilun, int64_t sector_num,
-                      int nb_sectors, bool allocated, bool valid)
-{
-    int64_t cl_num_expanded, nb_cls_expanded, cl_num_shrunk, nb_cls_shrunk;
-
-    if (iscsilun->allocmap == NULL) {
-        return;
-    }
-    /* expand to entirely contain all affected clusters */
-    cl_num_expanded = sector_num / iscsilun->cluster_sectors;
-    nb_cls_expanded = DIV_ROUND_UP(sector_num + nb_sectors,
-                                   iscsilun->cluster_sectors) - cl_num_expanded;
-    /* shrink to touch only completely contained clusters */
-    cl_num_shrunk = DIV_ROUND_UP(sector_num, iscsilun->cluster_sectors);
-    nb_cls_shrunk = (sector_num + nb_sectors) / iscsilun->cluster_sectors
-                      - cl_num_shrunk;
-    if (allocated) {
-        bitmap_set(iscsilun->allocmap, cl_num_expanded, nb_cls_expanded);
-    } else {
-        bitmap_clear(iscsilun->allocmap, cl_num_shrunk, nb_cls_shrunk);
-    }
-
-    if (iscsilun->allocmap_valid == NULL) {
+    int64_t cluster_num, nb_clusters;
+    if (iscsilun->allocationmap == NULL) {
         return;
     }
-    if (valid) {
-        bitmap_set(iscsilun->allocmap_valid, cl_num_shrunk, nb_cls_shrunk);
-    } else {
-        bitmap_clear(iscsilun->allocmap_valid, cl_num_expanded,
-                     nb_cls_expanded);
-    }
+    cluster_num = sector_num / iscsilun->cluster_sectors;
+    nb_clusters = DIV_ROUND_UP(sector_num + nb_sectors,
+                               iscsilun->cluster_sectors) - cluster_num;
+    bitmap_set(iscsilun->allocationmap, cluster_num, nb_clusters);
 }
 
-static void
-iscsi_allocmap_set_allocated(IscsiLun *iscsilun, int64_t sector_num,
-                             int nb_sectors)
+static void iscsi_allocationmap_clear(IscsiLun *iscsilun, int64_t sector_num,
+                                      int nb_sectors)
 {
-    iscsi_allocmap_update(iscsilun, sector_num, nb_sectors, true, true);
-}
-
-static void
-iscsi_allocmap_set_unallocated(IscsiLun *iscsilun, int64_t sector_num,
-                               int nb_sectors)
-{
-    /* Note: if cache.direct=on the fifth argument to iscsi_allocmap_update
-     * is ignored, so this will in effect be an iscsi_allocmap_set_invalid.
-     */
-    iscsi_allocmap_update(iscsilun, sector_num, nb_sectors, false, true);
-}
-
-static void iscsi_allocmap_set_invalid(IscsiLun *iscsilun, int64_t sector_num,
-                                       int nb_sectors)
-{
-    iscsi_allocmap_update(iscsilun, sector_num, nb_sectors, false, false);
-}
-
-static void iscsi_allocmap_invalidate(IscsiLun *iscsilun)
-{
-    if (iscsilun->allocmap) {
-        bitmap_zero(iscsilun->allocmap, iscsilun->allocmap_size);
+    int64_t cluster_num, nb_clusters;
+    if (iscsilun->allocationmap == NULL) {
+        return;
     }
-    if (iscsilun->allocmap_valid) {
-        bitmap_zero(iscsilun->allocmap_valid, iscsilun->allocmap_size);
+    cluster_num = DIV_ROUND_UP(sector_num, iscsilun->cluster_sectors);
+    nb_clusters = (sector_num + nb_sectors) / iscsilun->cluster_sectors
+                  - cluster_num;
+    if (nb_clusters > 0) {
+        bitmap_clear(iscsilun->allocationmap, cluster_num, nb_clusters);
     }
 }
 
-static inline bool
-iscsi_allocmap_is_allocated(IscsiLun *iscsilun, int64_t sector_num,
-                            int nb_sectors)
-{
-    unsigned long size;
-    if (iscsilun->allocmap == NULL) {
-        return true;
-    }
-    size = DIV_ROUND_UP(sector_num + nb_sectors, iscsilun->cluster_sectors);
-    return !(find_next_bit(iscsilun->allocmap, size,
-                           sector_num / iscsilun->cluster_sectors) == size);
-}
-
-static inline bool iscsi_allocmap_is_valid(IscsiLun *iscsilun,
-                                           int64_t sector_num, int nb_sectors)
-{
-    unsigned long size;
-    if (iscsilun->allocmap_valid == NULL) {
-        return false;
-    }
-    size = DIV_ROUND_UP(sector_num + nb_sectors, iscsilun->cluster_sectors);
-    return (find_next_zero_bit(iscsilun->allocmap_valid, size,
-                               sector_num / iscsilun->cluster_sectors) == size);
-}
-
 static int coroutine_fn
 iscsi_co_writev_flags(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
                       QEMUIOVector *iov, int flags)
@@ -577,23 +458,23 @@ iscsi_co_writev_flags(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
     struct IscsiTask iTask;
     uint64_t lba;
     uint32_t num_sectors;
-    bool fua = flags & BDRV_REQ_FUA;
+    bool fua;
 
-    if (fua) {
-        assert(iscsilun->dpofua);
-    }
-    if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
+    if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
         return -EINVAL;
     }
 
-    if (bs->bl.max_transfer) {
-        assert(nb_sectors << BDRV_SECTOR_BITS <= bs->bl.max_transfer);
+    if (bs->bl.max_transfer_length && nb_sectors > bs->bl.max_transfer_length) {
+        error_report("iSCSI Error: Write of %d sectors exceeds max_xfer_len "
+                     "of %d sectors", nb_sectors, bs->bl.max_transfer_length);
+        return -EINVAL;
     }
 
     lba = sector_qemu2lun(sector_num, iscsilun);
     num_sectors = sector_qemu2lun(nb_sectors, iscsilun);
     iscsi_co_init_iscsitask(iscsilun, &iTask);
 retry:
+    fua = iscsilun->dpofua && (flags & BDRV_REQ_FUA);
     if (iscsilun->use_16_for_rw) {
         iTask.task = iscsi_write16_task(iscsilun->iscsi, iscsilun->lun, lba,
                                         NULL, num_sectors * iscsilun->block_size,
@@ -626,17 +507,34 @@ retry:
     }
 
     if (iTask.status != SCSI_STATUS_GOOD) {
-        iscsi_allocmap_set_invalid(iscsilun, sector_num, nb_sectors);
         return iTask.err_code;
     }
 
-    iscsi_allocmap_set_allocated(iscsilun, sector_num, nb_sectors);
+    iscsi_allocationmap_set(iscsilun, sector_num, nb_sectors);
 
     return 0;
 }
 
+static int coroutine_fn
+iscsi_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
+                QEMUIOVector *iov)
+{
+    return iscsi_co_writev_flags(bs, sector_num, nb_sectors, iov, 0);
+}
 
 
+static bool iscsi_allocationmap_is_allocated(IscsiLun *iscsilun,
+                                             int64_t sector_num, int nb_sectors)
+{
+    unsigned long size;
+    if (iscsilun->allocationmap == NULL) {
+        return true;
+    }
+    size = DIV_ROUND_UP(sector_num + nb_sectors, iscsilun->cluster_sectors);
+    return !(find_next_bit(iscsilun->allocationmap, size,
+                           sector_num / iscsilun->cluster_sectors) == size);
+}
+
 static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
                                                   int64_t sector_num,
                                                   int nb_sectors, int *pnum,
@@ -650,7 +548,7 @@ static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
 
     iscsi_co_init_iscsitask(iscsilun, &iTask);
 
-    if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
+    if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
         ret = -EINVAL;
         goto out;
     }
@@ -720,9 +618,9 @@ retry:
     }
 
     if (ret & BDRV_BLOCK_ZERO) {
-        iscsi_allocmap_set_unallocated(iscsilun, sector_num, *pnum);
+        iscsi_allocationmap_clear(iscsilun, sector_num, *pnum);
     } else {
-        iscsi_allocmap_set_allocated(iscsilun, sector_num, *pnum);
+        iscsi_allocationmap_set(iscsilun, sector_num, *pnum);
     }
 
     if (*pnum > nb_sectors) {
@@ -747,40 +645,26 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
     uint64_t lba;
     uint32_t num_sectors;
 
-    if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
+    if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
         return -EINVAL;
     }
 
-    if (bs->bl.max_transfer) {
-        assert(nb_sectors << BDRV_SECTOR_BITS <= bs->bl.max_transfer);
-    }
-
-    /* if cache.direct is off and we have a valid entry in our allocation map
-     * we can skip checking the block status and directly return zeroes if
-     * the request falls within an unallocated area */
-    if (iscsi_allocmap_is_valid(iscsilun, sector_num, nb_sectors) &&
-        !iscsi_allocmap_is_allocated(iscsilun, sector_num, nb_sectors)) {
-            qemu_iovec_memset(iov, 0, 0x00, iov->size);
-            return 0;
+    if (bs->bl.max_transfer_length && nb_sectors > bs->bl.max_transfer_length) {
+        error_report("iSCSI Error: Read of %d sectors exceeds max_xfer_len "
+                     "of %d sectors", nb_sectors, bs->bl.max_transfer_length);
+        return -EINVAL;
     }
 
-    if (nb_sectors >= ISCSI_CHECKALLOC_THRES &&
-        !iscsi_allocmap_is_valid(iscsilun, sector_num, nb_sectors) &&
-        !iscsi_allocmap_is_allocated(iscsilun, sector_num, nb_sectors)) {
+    if (iscsilun->lbprz && nb_sectors >= ISCSI_CHECKALLOC_THRES &&
+        !iscsi_allocationmap_is_allocated(iscsilun, sector_num, nb_sectors)) {
+        int64_t ret;
         int pnum;
         BlockDriverState *file;
-        /* check the block status from the beginning of the cluster
-         * containing the start sector */
-        int64_t ret = iscsi_co_get_block_status(bs,
-                          sector_num - sector_num % iscsilun->cluster_sectors,
-                          BDRV_REQUEST_MAX_SECTORS, &pnum, &file);
+        ret = iscsi_co_get_block_status(bs, sector_num, INT_MAX, &pnum, &file);
         if (ret < 0) {
             return ret;
         }
-        /* if the whole request falls into an unallocated area we can avoid
-         * to read and directly return zeroes instead */
-        if (ret & BDRV_BLOCK_ZERO &&
-            pnum >= nb_sectors + sector_num % iscsilun->cluster_sectors) {
+        if (ret & BDRV_BLOCK_ZERO && pnum >= nb_sectors) {
             qemu_iovec_memset(iov, 0, 0x00, iov->size);
             return 0;
         }
@@ -884,7 +768,6 @@ iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
     acb->ioh->driver_status = 0;
     acb->ioh->host_status   = 0;
     acb->ioh->resid         = 0;
-    acb->ioh->status        = status;
 
 #define SG_ERR_DRIVER_SENSE    0x08
 
@@ -1042,26 +925,29 @@ iscsi_getlength(BlockDriverState *bs)
 }
 
 static int
-coroutine_fn iscsi_co_pdiscard(BlockDriverState *bs, int64_t offset, int count)
+coroutine_fn iscsi_co_discard(BlockDriverState *bs, int64_t sector_num,
+                                   int nb_sectors)
 {
     IscsiLun *iscsilun = bs->opaque;
     struct IscsiTask iTask;
     struct unmap_list list;
 
-    assert(is_byte_request_lun_aligned(offset, count, iscsilun));
+    if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
+        return -EINVAL;
+    }
 
     if (!iscsilun->lbp.lbpu) {
         /* UNMAP is not supported by the target */
         return 0;
     }
 
-    list.lba = offset / iscsilun->block_size;
-    list.num = count / iscsilun->block_size;
+    list.lba = sector_qemu2lun(sector_num, iscsilun);
+    list.num = sector_qemu2lun(nb_sectors, iscsilun);
 
     iscsi_co_init_iscsitask(iscsilun, &iTask);
 retry:
     if (iscsi_unmap_task(iscsilun->iscsi, iscsilun->lun, 0, 0, &list, 1,
-                         iscsi_co_generic_cb, &iTask) == NULL) {
+                     iscsi_co_generic_cb, &iTask) == NULL) {
         return -ENOMEM;
     }
 
@@ -1091,15 +977,14 @@ retry:
         return iTask.err_code;
     }
 
-    iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
-                               count >> BDRV_SECTOR_BITS);
+    iscsi_allocationmap_clear(iscsilun, sector_num, nb_sectors);
 
     return 0;
 }
 
 static int
-coroutine_fn iscsi_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
-                                    int count, BdrvRequestFlags flags)
+coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,
+                                   int nb_sectors, BdrvRequestFlags flags)
 {
     IscsiLun *iscsilun = bs->opaque;
     struct IscsiTask iTask;
@@ -1107,8 +992,8 @@ coroutine_fn iscsi_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
     uint32_t nb_blocks;
     bool use_16_for_ws = iscsilun->use_16_for_rw;
 
-    if (!is_byte_request_lun_aligned(offset, count, iscsilun)) {
-        return -ENOTSUP;
+    if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
+        return -EINVAL;
     }
 
     if (flags & BDRV_REQ_MAY_UNMAP) {
@@ -1129,8 +1014,8 @@ coroutine_fn iscsi_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
         return -ENOTSUP;
     }
 
-    lba = offset / iscsilun->block_size;
-    nb_blocks = count / iscsilun->block_size;
+    lba = sector_qemu2lun(sector_num, iscsilun);
+    nb_blocks = sector_qemu2lun(nb_sectors, iscsilun);
 
     if (iscsilun->zeroblock == NULL) {
         iscsilun->zeroblock = g_try_malloc0(iscsilun->block_size);
@@ -1182,17 +1067,13 @@ retry:
     }
 
     if (iTask.status != SCSI_STATUS_GOOD) {
-        iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
-                                   count >> BDRV_SECTOR_BITS);
         return iTask.err_code;
     }
 
     if (flags & BDRV_REQ_MAY_UNMAP) {
-        iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
-                                   count >> BDRV_SECTOR_BITS);
+        iscsi_allocationmap_clear(iscsilun, sector_num, nb_sectors);
     } else {
-        iscsi_allocmap_set_allocated(iscsilun, offset >> BDRV_SECTOR_BITS,
-                                     count >> BDRV_SECTOR_BITS);
+        iscsi_allocationmap_set(iscsilun, sector_num, nb_sectors);
     }
 
     return 0;
@@ -1683,10 +1564,6 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
     task = NULL;
 
     iscsi_modesense_sync(iscsilun);
-    if (iscsilun->dpofua) {
-        bs->supported_write_flags = BDRV_REQ_FUA;
-    }
-    bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP;
 
     /* Check the write protect flag of the LUN if we want to write */
     if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) &&
@@ -1703,13 +1580,14 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
         goto out;
     }
     bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
+    bs->request_alignment = iscsilun->block_size;
 
     /* We don't have any emulation for devices other than disks and CD-ROMs, so
      * this must be sg ioctl compatible. We force it to be sg, otherwise qemu
      * will try to read from the device to guess the image format.
      */
     if (iscsilun->type != TYPE_DISK && iscsilun->type != TYPE_ROM) {
-        bs->sg = true;
+        bs->sg = 1;
     }
 
     task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
@@ -1765,7 +1643,10 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
         iscsilun->cluster_sectors = (iscsilun->bl.opt_unmap_gran *
                                      iscsilun->block_size) >> BDRV_SECTOR_BITS;
         if (iscsilun->lbprz) {
-            ret = iscsi_allocmap_init(iscsilun, bs->open_flags);
+            iscsilun->allocationmap = iscsi_allocationmap_init(iscsilun);
+            if (iscsilun->allocationmap == NULL) {
+                ret = -ENOMEM;
+            }
         }
     }
 
@@ -1802,54 +1683,48 @@ static void iscsi_close(BlockDriverState *bs)
     }
     iscsi_destroy_context(iscsi);
     g_free(iscsilun->zeroblock);
-    iscsi_allocmap_free(iscsilun);
+    g_free(iscsilun->allocationmap);
     memset(iscsilun, 0, sizeof(IscsiLun));
 }
 
+static int sector_limits_lun2qemu(int64_t sector, IscsiLun *iscsilun)
+{
+    return MIN(sector_lun2qemu(sector, iscsilun), INT_MAX / 2 + 1);
+}
+
 static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
 {
     /* We don't actually refresh here, but just return data queried in
      * iscsi_open(): iscsi targets don't change their limits. */
 
     IscsiLun *iscsilun = bs->opaque;
-    uint64_t max_xfer_len = iscsilun->use_16_for_rw ? 0xffffffff : 0xffff;
-
-    bs->bl.request_alignment = iscsilun->block_size;
+    uint32_t max_xfer_len = iscsilun->use_16_for_rw ? 0xffffffff : 0xffff;
 
     if (iscsilun->bl.max_xfer_len) {
         max_xfer_len = MIN(max_xfer_len, iscsilun->bl.max_xfer_len);
     }
 
-    if (max_xfer_len * iscsilun->block_size < INT_MAX) {
-        bs->bl.max_transfer = max_xfer_len * iscsilun->block_size;
-    }
+    bs->bl.max_transfer_length = sector_limits_lun2qemu(max_xfer_len, iscsilun);
 
     if (iscsilun->lbp.lbpu) {
-        if (iscsilun->bl.max_unmap < 0xffffffff / iscsilun->block_size) {
-            bs->bl.max_pdiscard =
-                iscsilun->bl.max_unmap * iscsilun->block_size;
+        if (iscsilun->bl.max_unmap < 0xffffffff) {
+            bs->bl.max_discard =
+                sector_limits_lun2qemu(iscsilun->bl.max_unmap, iscsilun);
         }
-        bs->bl.pdiscard_alignment =
-            iscsilun->bl.opt_unmap_gran * iscsilun->block_size;
-    } else {
-        bs->bl.pdiscard_alignment = iscsilun->block_size;
+        bs->bl.discard_alignment =
+            sector_limits_lun2qemu(iscsilun->bl.opt_unmap_gran, iscsilun);
     }
 
-    if (iscsilun->bl.max_ws_len < 0xffffffff / iscsilun->block_size) {
-        bs->bl.max_pwrite_zeroes =
-            iscsilun->bl.max_ws_len * iscsilun->block_size;
+    if (iscsilun->bl.max_ws_len < 0xffffffff) {
+        bs->bl.max_write_zeroes =
+            sector_limits_lun2qemu(iscsilun->bl.max_ws_len, iscsilun);
     }
     if (iscsilun->lbp.lbpws) {
-        bs->bl.pwrite_zeroes_alignment =
-            iscsilun->bl.opt_unmap_gran * iscsilun->block_size;
-    } else {
-        bs->bl.pwrite_zeroes_alignment = iscsilun->block_size;
-    }
-    if (iscsilun->bl.opt_xfer_len &&
-        iscsilun->bl.opt_xfer_len < INT_MAX / iscsilun->block_size) {
-        bs->bl.opt_transfer = pow2floor(iscsilun->bl.opt_xfer_len *
-                                        iscsilun->block_size);
+        bs->bl.write_zeroes_alignment =
+            sector_limits_lun2qemu(iscsilun->bl.opt_unmap_gran, iscsilun);
     }
+    bs->bl.opt_transfer_length =
+        sector_limits_lun2qemu(iscsilun->bl.opt_xfer_len, iscsilun);
 }
 
 /* Note that this will not re-establish a connection with an iSCSI target - it
@@ -1866,16 +1741,6 @@ static int iscsi_reopen_prepare(BDRVReopenState *state,
     return 0;
 }
 
-static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
-{
-    IscsiLun *iscsilun = reopen_state->bs->opaque;
-
-    /* the cache.direct status might have changed */
-    if (iscsilun->allocmap != NULL) {
-        iscsi_allocmap_init(iscsilun, reopen_state->flags);
-    }
-}
-
 static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
 {
     IscsiLun *iscsilun = bs->opaque;
@@ -1895,8 +1760,9 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
         return -EINVAL;
     }
 
-    if (iscsilun->allocmap != NULL) {
-        iscsi_allocmap_init(iscsilun, bs->open_flags);
+    if (iscsilun->allocationmap != NULL) {
+        g_free(iscsilun->allocationmap);
+        iscsilun->allocationmap = iscsi_allocationmap_init(iscsilun);
     }
 
     return 0;
@@ -1956,13 +1822,6 @@ static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
     return 0;
 }
 
-static void iscsi_invalidate_cache(BlockDriverState *bs,
-                                   Error **errp)
-{
-    IscsiLun *iscsilun = bs->opaque;
-    iscsi_allocmap_invalidate(iscsilun);
-}
-
 static QemuOptsList iscsi_create_opts = {
     .name = "iscsi-create-opts",
     .head = QTAILQ_HEAD_INITIALIZER(iscsi_create_opts.head),
@@ -1986,9 +1845,7 @@ static BlockDriver bdrv_iscsi = {
     .bdrv_close      = iscsi_close,
     .bdrv_create     = iscsi_create,
     .create_opts     = &iscsi_create_opts,
-    .bdrv_reopen_prepare   = iscsi_reopen_prepare,
-    .bdrv_reopen_commit    = iscsi_reopen_commit,
-    .bdrv_invalidate_cache = iscsi_invalidate_cache,
+    .bdrv_reopen_prepare  = iscsi_reopen_prepare,
 
     .bdrv_getlength  = iscsi_getlength,
     .bdrv_get_info   = iscsi_get_info,
@@ -1996,10 +1853,12 @@ static BlockDriver bdrv_iscsi = {
     .bdrv_refresh_limits = iscsi_refresh_limits,
 
     .bdrv_co_get_block_status = iscsi_co_get_block_status,
-    .bdrv_co_pdiscard      = iscsi_co_pdiscard,
-    .bdrv_co_pwrite_zeroes = iscsi_co_pwrite_zeroes,
+    .bdrv_co_discard      = iscsi_co_discard,
+    .bdrv_co_write_zeroes = iscsi_co_write_zeroes,
     .bdrv_co_readv         = iscsi_co_readv,
+    .bdrv_co_writev        = iscsi_co_writev,
     .bdrv_co_writev_flags  = iscsi_co_writev_flags,
+    .supported_write_flags = BDRV_REQ_FUA,
     .bdrv_co_flush_to_disk = iscsi_co_flush,
 
 #ifdef __linux__
index e906abe..805757e 100644 (file)
 #include "qemu-common.h"
 #include "block/aio.h"
 #include "qemu/queue.h"
-#include "block/block.h"
 #include "block/raw-aio.h"
 #include "qemu/event_notifier.h"
-#include "qemu/coroutine.h"
 
 #include <libaio.h>
 
  */
 #define MAX_EVENTS 128
 
+#define MAX_QUEUED_IO  128
+
 struct qemu_laiocb {
     BlockAIOCB common;
-    Coroutine *co;
-    LinuxAioState *ctx;
+    struct qemu_laio_state *ctx;
     struct iocb iocb;
     ssize_t ret;
     size_t nbytes;
@@ -42,15 +41,12 @@ struct qemu_laiocb {
 
 typedef struct {
     int plugged;
-    unsigned int in_queue;
-    unsigned int in_flight;
+    unsigned int n;
     bool blocked;
     QSIMPLEQ_HEAD(, qemu_laiocb) pending;
 } LaioQueue;
 
-struct LinuxAioState {
-    AioContext *aio_context;
-
+struct qemu_laio_state {
     io_context_t ctx;
     EventNotifier e;
 
@@ -64,7 +60,7 @@ struct LinuxAioState {
     int event_max;
 };
 
-static void ioq_submit(LinuxAioState *s);
+static void ioq_submit(struct qemu_laio_state *s);
 
 static inline ssize_t io_event_ret(struct io_event *ev)
 {
@@ -74,7 +70,8 @@ static inline ssize_t io_event_ret(struct io_event *ev)
 /*
  * Completes an AIO request (calls the callback and frees the ACB).
  */
-static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
+static void qemu_laio_process_completion(struct qemu_laio_state *s,
+    struct qemu_laiocb *laiocb)
 {
     int ret;
 
@@ -88,18 +85,13 @@ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
                 qemu_iovec_memset(laiocb->qiov, ret, 0,
                     laiocb->qiov->size - ret);
             } else {
-                ret = -ENOSPC;
+                ret = -EINVAL;
             }
         }
     }
+    laiocb->common.cb(laiocb->common.opaque, ret);
 
-    laiocb->ret = ret;
-    if (laiocb->co) {
-        qemu_coroutine_enter(laiocb->co);
-    } else {
-        laiocb->common.cb(laiocb->common.opaque, ret);
-        qemu_aio_unref(laiocb);
-    }
+    qemu_aio_unref(laiocb);
 }
 
 /* The completion BH fetches completed I/O requests and invokes their
@@ -107,7 +99,7 @@ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
  *
  * The function is somewhat tricky because it supports nested event loops, for
  * example when a request callback invokes aio_poll().  In order to do this,
- * the completion events array and index are kept in LinuxAioState.  The BH
+ * the completion events array and index are kept in qemu_laio_state.  The BH
  * reschedules itself as long as there are completions pending so it will
  * either be called again in a nested event loop or will be called after all
  * events have been completed.  When there are no events left to complete, the
@@ -115,7 +107,7 @@ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
  */
 static void qemu_laio_completion_bh(void *opaque)
 {
-    LinuxAioState *s = opaque;
+    struct qemu_laio_state *s = opaque;
 
     /* Fetch more completion events when empty */
     if (s->event_idx == s->event_max) {
@@ -130,7 +122,6 @@ static void qemu_laio_completion_bh(void *opaque)
             s->event_max = 0;
             return; /* no more events */
         }
-        s->io_q.in_flight -= s->event_max;
     }
 
     /* Reschedule so nested event loops see currently pending completions */
@@ -145,22 +136,20 @@ static void qemu_laio_completion_bh(void *opaque)
         laiocb->ret = io_event_ret(&s->events[s->event_idx]);
         s->event_idx++;
 
-        qemu_laio_process_completion(laiocb);
+        qemu_laio_process_completion(s, laiocb);
     }
 
     if (!s->io_q.plugged && !QSIMPLEQ_EMPTY(&s->io_q.pending)) {
         ioq_submit(s);
     }
-
-    qemu_bh_cancel(s->completion_bh);
 }
 
 static void qemu_laio_completion_cb(EventNotifier *e)
 {
-    LinuxAioState *s = container_of(e, LinuxAioState, e);
+    struct qemu_laio_state *s = container_of(e, struct qemu_laio_state, e);
 
     if (event_notifier_test_and_clear(&s->e)) {
-        qemu_laio_completion_bh(s);
+        qemu_bh_schedule(s->completion_bh);
     }
 }
 
@@ -192,26 +181,22 @@ static void ioq_init(LaioQueue *io_q)
 {
     QSIMPLEQ_INIT(&io_q->pending);
     io_q->plugged = 0;
-    io_q->in_queue = 0;
-    io_q->in_flight = 0;
+    io_q->n = 0;
     io_q->blocked = false;
 }
 
-static void ioq_submit(LinuxAioState *s)
+static void ioq_submit(struct qemu_laio_state *s)
 {
     int ret, len;
     struct qemu_laiocb *aiocb;
-    struct iocb *iocbs[MAX_EVENTS];
+    struct iocb *iocbs[MAX_QUEUED_IO];
     QSIMPLEQ_HEAD(, qemu_laiocb) completed;
 
     do {
-        if (s->io_q.in_flight >= MAX_EVENTS) {
-            break;
-        }
         len = 0;
         QSIMPLEQ_FOREACH(aiocb, &s->io_q.pending, next) {
             iocbs[len++] = &aiocb->iocb;
-            if (s->io_q.in_flight + len >= MAX_EVENTS) {
+            if (len == MAX_QUEUED_IO) {
                 break;
             }
         }
@@ -221,43 +206,55 @@ static void ioq_submit(LinuxAioState *s)
             break;
         }
         if (ret < 0) {
-            /* Fail the first request, retry the rest */
-            aiocb = QSIMPLEQ_FIRST(&s->io_q.pending);
-            QSIMPLEQ_REMOVE_HEAD(&s->io_q.pending, next);
-            s->io_q.in_queue--;
-            aiocb->ret = ret;
-            qemu_laio_process_completion(aiocb);
-            continue;
+            abort();
         }
 
-        s->io_q.in_flight += ret;
-        s->io_q.in_queue  -= ret;
+        s->io_q.n -= ret;
         aiocb = container_of(iocbs[ret - 1], struct qemu_laiocb, iocb);
         QSIMPLEQ_SPLIT_AFTER(&s->io_q.pending, aiocb, next, &completed);
     } while (ret == len && !QSIMPLEQ_EMPTY(&s->io_q.pending));
-    s->io_q.blocked = (s->io_q.in_queue > 0);
+    s->io_q.blocked = (s->io_q.n > 0);
 }
 
-void laio_io_plug(BlockDriverState *bs, LinuxAioState *s)
+void laio_io_plug(BlockDriverState *bs, void *aio_ctx)
 {
+    struct qemu_laio_state *s = aio_ctx;
+
     s->io_q.plugged++;
 }
 
-void laio_io_unplug(BlockDriverState *bs, LinuxAioState *s)
+void laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug)
 {
-    assert(s->io_q.plugged);
-    if (--s->io_q.plugged == 0 &&
-        !s->io_q.blocked && !QSIMPLEQ_EMPTY(&s->io_q.pending)) {
+    struct qemu_laio_state *s = aio_ctx;
+
+    assert(s->io_q.plugged > 0 || !unplug);
+
+    if (unplug && --s->io_q.plugged > 0) {
+        return;
+    }
+
+    if (!s->io_q.blocked && !QSIMPLEQ_EMPTY(&s->io_q.pending)) {
         ioq_submit(s);
     }
 }
 
-static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
-                          int type)
+BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
+        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+        BlockCompletionFunc *cb, void *opaque, int type)
 {
-    LinuxAioState *s = laiocb->ctx;
-    struct iocb *iocbs = &laiocb->iocb;
-    QEMUIOVector *qiov = laiocb->qiov;
+    struct qemu_laio_state *s = aio_ctx;
+    struct qemu_laiocb *laiocb;
+    struct iocb *iocbs;
+    off_t offset = sector_num * 512;
+
+    laiocb = qemu_aio_get(&laio_aiocb_info, bs, cb, opaque);
+    laiocb->nbytes = nb_sectors * 512;
+    laiocb->ctx = s;
+    laiocb->ret = -EINPROGRESS;
+    laiocb->is_read = (type == QEMU_AIO_READ);
+    laiocb->qiov = qiov;
+
+    iocbs = &laiocb->iocb;
 
     switch (type) {
     case QEMU_AIO_WRITE:
@@ -270,83 +267,43 @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
     default:
         fprintf(stderr, "%s: invalid AIO request type 0x%x.\n",
                         __func__, type);
-        return -EIO;
+        goto out_free_aiocb;
     }
     io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e));
 
     QSIMPLEQ_INSERT_TAIL(&s->io_q.pending, laiocb, next);
-    s->io_q.in_queue++;
+    s->io_q.n++;
     if (!s->io_q.blocked &&
-        (!s->io_q.plugged ||
-         s->io_q.in_flight + s->io_q.in_queue >= MAX_EVENTS)) {
+        (!s->io_q.plugged || s->io_q.n >= MAX_QUEUED_IO)) {
         ioq_submit(s);
     }
+    return &laiocb->common;
 
-    return 0;
-}
-
-int coroutine_fn laio_co_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
-                                uint64_t offset, QEMUIOVector *qiov, int type)
-{
-    int ret;
-    struct qemu_laiocb laiocb = {
-        .co         = qemu_coroutine_self(),
-        .nbytes     = qiov->size,
-        .ctx        = s,
-        .is_read    = (type == QEMU_AIO_READ),
-        .qiov       = qiov,
-    };
-
-    ret = laio_do_submit(fd, &laiocb, offset, type);
-    if (ret < 0) {
-        return ret;
-    }
-
-    qemu_coroutine_yield();
-    return laiocb.ret;
+out_free_aiocb:
+    qemu_aio_unref(laiocb);
+    return NULL;
 }
 
-BlockAIOCB *laio_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
-        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockCompletionFunc *cb, void *opaque, int type)
+void laio_detach_aio_context(void *s_, AioContext *old_context)
 {
-    struct qemu_laiocb *laiocb;
-    off_t offset = sector_num * BDRV_SECTOR_SIZE;
-    int ret;
-
-    laiocb = qemu_aio_get(&laio_aiocb_info, bs, cb, opaque);
-    laiocb->nbytes = nb_sectors * BDRV_SECTOR_SIZE;
-    laiocb->ctx = s;
-    laiocb->ret = -EINPROGRESS;
-    laiocb->is_read = (type == QEMU_AIO_READ);
-    laiocb->qiov = qiov;
-
-    ret = laio_do_submit(fd, laiocb, offset, type);
-    if (ret < 0) {
-        qemu_aio_unref(laiocb);
-        return NULL;
-    }
+    struct qemu_laio_state *s = s_;
 
-    return &laiocb->common;
-}
-
-void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context)
-{
     aio_set_event_notifier(old_context, &s->e, false, NULL);
     qemu_bh_delete(s->completion_bh);
 }
 
-void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context)
+void laio_attach_aio_context(void *s_, AioContext *new_context)
 {
-    s->aio_context = new_context;
+    struct qemu_laio_state *s = s_;
+
     s->completion_bh = aio_bh_new(new_context, qemu_laio_completion_bh, s);
     aio_set_event_notifier(new_context, &s->e, false,
                            qemu_laio_completion_cb);
 }
 
-LinuxAioState *laio_init(void)
+void *laio_init(void)
 {
-    LinuxAioState *s;
+    struct qemu_laio_state *s;
 
     s = g_malloc0(sizeof(*s));
     if (event_notifier_init(&s->e, false) < 0) {
@@ -368,8 +325,10 @@ out_free_state:
     return NULL;
 }
 
-void laio_cleanup(LinuxAioState *s)
+void laio_cleanup(void *s_)
 {
+    struct qemu_laio_state *s = s_;
+
     event_notifier_cleanup(&s->e);
 
     if (io_destroy(s->ctx) != 0) {
index e0b3f41..039f481 100644 (file)
 #include "qapi/qmp/qerror.h"
 #include "qemu/ratelimit.h"
 #include "qemu/bitmap.h"
+#include "qemu/error-report.h"
 
 #define SLICE_TIME    100000000ULL /* ns */
 #define MAX_IN_FLIGHT 16
-#define MAX_IO_SECTORS ((1 << 20) >> BDRV_SECTOR_BITS) /* 1 Mb */
-#define DEFAULT_MIRROR_BUF_SIZE \
-    (MAX_IN_FLIGHT * MAX_IO_SECTORS * BDRV_SECTOR_SIZE)
+#define DEFAULT_MIRROR_BUF_SIZE   (10 << 20)
 
 /* The mirroring buffer is a list of granularity-sized chunks.
  * Free chunks are organized in a list.
@@ -37,7 +36,7 @@ typedef struct MirrorBuffer {
 typedef struct MirrorBlockJob {
     BlockJob common;
     RateLimit limit;
-    BlockBackend *target;
+    BlockDriverState *target;
     BlockDriverState *base;
     /* The name of the graph node to replace */
     char *replaces;
@@ -46,7 +45,6 @@ typedef struct MirrorBlockJob {
     /* Used to block operations on the drive-mirror-replace target */
     Error *replace_blocker;
     bool is_none_mode;
-    BlockMirrorBackingMode backing_mode;
     BlockdevOnError on_source_error, on_target_error;
     bool synced;
     bool should_complete;
@@ -60,10 +58,9 @@ typedef struct MirrorBlockJob {
     QSIMPLEQ_HEAD(, MirrorBuffer) buf_free;
     int buf_free_count;
 
-    uint64_t last_pause_ns;
     unsigned long *in_flight_bitmap;
     int in_flight;
-    int64_t sectors_in_flight;
+    int sectors_in_flight;
     int ret;
     bool unmap;
     bool waiting_for_io;
@@ -83,11 +80,11 @@ static BlockErrorAction mirror_error_action(MirrorBlockJob *s, bool read,
 {
     s->synced = false;
     if (read) {
-        return block_job_error_action(&s->common, s->on_source_error,
-                                      true, error);
+        return block_job_error_action(&s->common, s->common.bs,
+                                      s->on_source_error, true, error);
     } else {
-        return block_job_error_action(&s->common, s->on_target_error,
-                                      false, error);
+        return block_job_error_action(&s->common, s->target,
+                                      s->on_target_error, false, error);
     }
 }
 
@@ -124,7 +121,7 @@ static void mirror_iteration_done(MirrorOp *op, int ret)
     g_free(op);
 
     if (s->waiting_for_io) {
-        qemu_coroutine_enter(s->common.co);
+        qemu_coroutine_enter(s->common.co, NULL);
     }
 }
 
@@ -160,8 +157,8 @@ static void mirror_read_complete(void *opaque, int ret)
         mirror_iteration_done(op, ret);
         return;
     }
-    blk_aio_pwritev(s->target, op->sector_num * BDRV_SECTOR_SIZE, &op->qiov,
-                    0, mirror_write_complete, op);
+    bdrv_aio_writev(s->target, op->sector_num, &op->qiov, op->nb_sectors,
+                    mirror_write_complete, op);
 }
 
 static inline void mirror_clip_sectors(MirrorBlockJob *s,
@@ -189,9 +186,8 @@ static int mirror_cow_align(MirrorBlockJob *s,
     need_cow |= !test_bit((*sector_num + *nb_sectors - 1) / chunk_sectors,
                           s->cow_bitmap);
     if (need_cow) {
-        bdrv_round_sectors_to_clusters(blk_bs(s->target), *sector_num,
-                                       *nb_sectors, &align_sector_num,
-                                       &align_nb_sectors);
+        bdrv_round_to_clusters(s->target, *sector_num, *nb_sectors,
+                               &align_sector_num, &align_nb_sectors);
     }
 
     if (align_nb_sectors > max_sectors) {
@@ -221,29 +217,23 @@ static inline void mirror_wait_for_io(MirrorBlockJob *s)
 }
 
 /* Submit async read while handling COW.
- * Returns: The number of sectors copied after and including sector_num,
- *          excluding any sectors copied prior to sector_num due to alignment.
- *          This will be nb_sectors if no alignment is necessary, or
+ * Returns: nb_sectors if no alignment is necessary, or
  *          (new_end - sector_num) if tail is rounded up or down due to
  *          alignment or buffer limit.
  */
 static int mirror_do_read(MirrorBlockJob *s, int64_t sector_num,
                           int nb_sectors)
 {
-    BlockBackend *source = s->common.blk;
+    BlockDriverState *source = s->common.bs;
     int sectors_per_chunk, nb_chunks;
-    int ret;
+    int ret = nb_sectors;
     MirrorOp *op;
-    int max_sectors;
 
     sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
-    max_sectors = sectors_per_chunk * s->max_iov;
 
     /* We can only handle as much as buf_size at a time. */
     nb_sectors = MIN(s->buf_size >> BDRV_SECTOR_BITS, nb_sectors);
-    nb_sectors = MIN(max_sectors, nb_sectors);
     assert(nb_sectors);
-    ret = nb_sectors;
 
     if (s->cow_bitmap) {
         ret += mirror_cow_align(s, &sector_num, &nb_sectors);
@@ -284,7 +274,7 @@ static int mirror_do_read(MirrorBlockJob *s, int64_t sector_num,
     s->sectors_in_flight += nb_sectors;
     trace_mirror_one_iteration(s, sector_num, nb_sectors);
 
-    blk_aio_preadv(source, sector_num * BDRV_SECTOR_SIZE, &op->qiov, 0,
+    bdrv_aio_readv(source, sector_num, &op->qiov, nb_sectors,
                    mirror_read_complete, op);
     return ret;
 }
@@ -306,12 +296,10 @@ static void mirror_do_zero_or_discard(MirrorBlockJob *s,
     s->in_flight++;
     s->sectors_in_flight += nb_sectors;
     if (is_discard) {
-        blk_aio_pdiscard(s->target, sector_num << BDRV_SECTOR_BITS,
-                         op->nb_sectors << BDRV_SECTOR_BITS,
+        bdrv_aio_discard(s->target, sector_num, op->nb_sectors,
                          mirror_write_complete, op);
     } else {
-        blk_aio_pwrite_zeroes(s->target, sector_num * BDRV_SECTOR_SIZE,
-                              op->nb_sectors * BDRV_SECTOR_SIZE,
+        bdrv_aio_write_zeroes(s->target, sector_num, op->nb_sectors,
                               s->unmap ? BDRV_REQ_MAY_UNMAP : 0,
                               mirror_write_complete, op);
     }
@@ -319,16 +307,13 @@ static void mirror_do_zero_or_discard(MirrorBlockJob *s,
 
 static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
 {
-    BlockDriverState *source = blk_bs(s->common.blk);
+    BlockDriverState *source = s->common.bs;
     int64_t sector_num, first_chunk;
     uint64_t delay_ns = 0;
     /* At least the first dirty chunk is mirrored in one iteration. */
     int nb_chunks = 1;
     int64_t end = s->bdev_length / BDRV_SECTOR_SIZE;
     int sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
-    bool write_zeroes_ok = bdrv_can_write_zeroes_with_unmap(blk_bs(s->target));
-    int max_io_sectors = MAX((s->buf_size >> BDRV_SECTOR_BITS) / MAX_IN_FLIGHT,
-                             MAX_IO_SECTORS);
 
     sector_num = hbitmap_iter_next(&s->hbi);
     if (sector_num < 0) {
@@ -340,12 +325,10 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
 
     first_chunk = sector_num / sectors_per_chunk;
     while (test_bit(first_chunk, s->in_flight_bitmap)) {
-        trace_mirror_yield_in_flight(s, sector_num, s->in_flight);
+        trace_mirror_yield_in_flight(s, first_chunk, s->in_flight);
         mirror_wait_for_io(s);
     }
 
-    block_job_pause_point(&s->common);
-
     /* Find the number of consective dirty chunks following the first dirty
      * one, and wait for in flight requests in them. */
     while (nb_chunks * sectors_per_chunk < (s->buf_size >> BDRV_SECTOR_BITS)) {
@@ -379,7 +362,7 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
     bitmap_set(s->in_flight_bitmap, sector_num / sectors_per_chunk, nb_chunks);
     while (nb_chunks > 0 && sector_num < end) {
         int ret;
-        int io_sectors, io_sectors_acct;
+        int io_sectors;
         BlockDriverState *file;
         enum MirrorMethod {
             MIRROR_METHOD_COPY,
@@ -392,9 +375,7 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
                                           nb_chunks * sectors_per_chunk,
                                           &io_sectors, &file);
         if (ret < 0) {
-            io_sectors = MIN(nb_chunks * sectors_per_chunk, max_io_sectors);
-        } else if (ret & BDRV_BLOCK_DATA) {
-            io_sectors = MIN(io_sectors, max_io_sectors);
+            io_sectors = nb_chunks * sectors_per_chunk;
         }
 
         io_sectors -= io_sectors % sectors_per_chunk;
@@ -403,9 +384,8 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
         } else if (ret >= 0 && !(ret & BDRV_BLOCK_DATA)) {
             int64_t target_sector_num;
             int target_nb_sectors;
-            bdrv_round_sectors_to_clusters(blk_bs(s->target), sector_num,
-                                           io_sectors,  &target_sector_num,
-                                           &target_nb_sectors);
+            bdrv_round_to_clusters(s->target, sector_num, io_sectors,
+                                   &target_sector_num, &target_nb_sectors);
             if (target_sector_num == sector_num &&
                 target_nb_sectors == io_sectors) {
                 mirror_method = ret & BDRV_BLOCK_ZERO ?
@@ -414,30 +394,16 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
             }
         }
 
-        while (s->in_flight >= MAX_IN_FLIGHT) {
-            trace_mirror_yield_in_flight(s, sector_num, s->in_flight);
-            mirror_wait_for_io(s);
-        }
-
-        if (s->ret < 0) {
-            return 0;
-        }
-
         mirror_clip_sectors(s, sector_num, &io_sectors);
         switch (mirror_method) {
         case MIRROR_METHOD_COPY:
             io_sectors = mirror_do_read(s, sector_num, io_sectors);
-            io_sectors_acct = io_sectors;
             break;
         case MIRROR_METHOD_ZERO:
+            mirror_do_zero_or_discard(s, sector_num, io_sectors, false);
+            break;
         case MIRROR_METHOD_DISCARD:
-            mirror_do_zero_or_discard(s, sector_num, io_sectors,
-                                      mirror_method == MIRROR_METHOD_DISCARD);
-            if (write_zeroes_ok) {
-                io_sectors_acct = 0;
-            } else {
-                io_sectors_acct = io_sectors;
-            }
+            mirror_do_zero_or_discard(s, sector_num, io_sectors, true);
             break;
         default:
             abort();
@@ -445,9 +411,7 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
         assert(io_sectors);
         sector_num += io_sectors;
         nb_chunks -= DIV_ROUND_UP(io_sectors, sectors_per_chunk);
-        if (s->common.speed) {
-            delay_ns = ratelimit_calculate_delay(&s->limit, io_sectors_acct);
-        }
+        delay_ns += ratelimit_calculate_delay(&s->limit, io_sectors);
     }
     return delay_ns;
 }
@@ -485,8 +449,7 @@ static void mirror_exit(BlockJob *job, void *opaque)
     MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
     MirrorExitData *data = opaque;
     AioContext *replace_aio_context = NULL;
-    BlockDriverState *src = blk_bs(s->common.blk);
-    BlockDriverState *target_bs = blk_bs(s->target);
+    BlockDriverState *src = s->common.bs;
 
     /* Make sure that the source BDS doesn't go away before we called
      * block_job_completed(). */
@@ -498,25 +461,26 @@ static void mirror_exit(BlockJob *job, void *opaque)
     }
 
     if (s->should_complete && data->ret == 0) {
-        BlockDriverState *to_replace = src;
+        BlockDriverState *to_replace = s->common.bs;
         if (s->to_replace) {
             to_replace = s->to_replace;
         }
 
-        if (bdrv_get_flags(target_bs) != bdrv_get_flags(to_replace)) {
-            bdrv_reopen(target_bs, bdrv_get_flags(to_replace), NULL);
+        /* This was checked in mirror_start_job(), but meanwhile one of the
+         * nodes could have been newly attached to a BlockBackend. */
+        if (to_replace->blk && s->target->blk) {
+            error_report("block job: Can't create node with two BlockBackends");
+            data->ret = -EINVAL;
+            goto out;
         }
 
-        /* The mirror job has no requests in flight any more, but we need to
-         * drain potential other users of the BDS before changing the graph. */
-        bdrv_drained_begin(target_bs);
-        bdrv_replace_in_backing_chain(to_replace, target_bs);
-        bdrv_drained_end(target_bs);
-
-        /* We just changed the BDS the job BB refers to */
-        blk_remove_bs(job->blk);
-        blk_insert_bs(job->blk, src);
+        if (bdrv_get_flags(s->target) != bdrv_get_flags(to_replace)) {
+            bdrv_reopen(s->target, bdrv_get_flags(to_replace), NULL);
+        }
+        bdrv_replace_in_backing_chain(to_replace, s->target);
     }
+
+out:
     if (s->to_replace) {
         bdrv_op_unblock_all(s->to_replace, s->replace_blocker);
         error_free(s->replace_blocker);
@@ -526,102 +490,29 @@ static void mirror_exit(BlockJob *job, void *opaque)
         aio_context_release(replace_aio_context);
     }
     g_free(s->replaces);
-    bdrv_op_unblock_all(target_bs, s->common.blocker);
-    blk_unref(s->target);
+    bdrv_op_unblock_all(s->target, s->common.blocker);
+    bdrv_unref(s->target);
     block_job_completed(&s->common, data->ret);
     g_free(data);
     bdrv_drained_end(src);
-    bdrv_unref(src);
-}
-
-static void mirror_throttle(MirrorBlockJob *s)
-{
-    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
-
-    if (now - s->last_pause_ns > SLICE_TIME) {
-        s->last_pause_ns = now;
-        block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0);
-    } else {
-        block_job_pause_point(&s->common);
-    }
-}
-
-static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
-{
-    int64_t sector_num, end;
-    BlockDriverState *base = s->base;
-    BlockDriverState *bs = blk_bs(s->common.blk);
-    BlockDriverState *target_bs = blk_bs(s->target);
-    int ret, n;
-
-    end = s->bdev_length / BDRV_SECTOR_SIZE;
-
-    if (base == NULL && !bdrv_has_zero_init(target_bs)) {
-        if (!bdrv_can_write_zeroes_with_unmap(target_bs)) {
-            bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, end);
-            return 0;
-        }
-
-        for (sector_num = 0; sector_num < end; ) {
-            int nb_sectors = MIN(end - sector_num,
-                QEMU_ALIGN_DOWN(INT_MAX, s->granularity) >> BDRV_SECTOR_BITS);
-
-            mirror_throttle(s);
-
-            if (block_job_is_cancelled(&s->common)) {
-                return 0;
-            }
-
-            if (s->in_flight >= MAX_IN_FLIGHT) {
-                trace_mirror_yield(s, s->in_flight, s->buf_free_count, -1);
-                mirror_wait_for_io(s);
-                continue;
-            }
-
-            mirror_do_zero_or_discard(s, sector_num, nb_sectors, false);
-            sector_num += nb_sectors;
-        }
-
-        mirror_drain(s);
-    }
-
-    /* First part, loop on the sectors and initialize the dirty bitmap.  */
-    for (sector_num = 0; sector_num < end; ) {
-        /* Just to make sure we are not exceeding int limit. */
-        int nb_sectors = MIN(INT_MAX >> BDRV_SECTOR_BITS,
-                             end - sector_num);
-
-        mirror_throttle(s);
-
-        if (block_job_is_cancelled(&s->common)) {
-            return 0;
-        }
-
-        ret = bdrv_is_allocated_above(bs, base, sector_num, nb_sectors, &n);
-        if (ret < 0) {
-            return ret;
-        }
-
-        assert(n > 0);
-        if (ret == 1) {
-            bdrv_set_dirty_bitmap(s->dirty_bitmap, sector_num, n);
-        }
-        sector_num += n;
+    if (qemu_get_aio_context() == bdrv_get_aio_context(src)) {
+        aio_enable_external(iohandler_get_aio_context());
     }
-    return 0;
+    bdrv_unref(src);
 }
 
 static void coroutine_fn mirror_run(void *opaque)
 {
     MirrorBlockJob *s = opaque;
     MirrorExitData *data;
-    BlockDriverState *bs = blk_bs(s->common.blk);
-    BlockDriverState *target_bs = blk_bs(s->target);
-    int64_t length;
+    BlockDriverState *bs = s->common.bs;
+    int64_t sector_num, end, length;
+    uint64_t last_pause_ns;
     BlockDriverInfo bdi;
     char backing_filename[2]; /* we only need 2 characters because we are only
                                  checking for a NULL string */
     int ret = 0;
+    int n;
     int target_cluster_size = BDRV_SECTOR_SIZE;
 
     if (block_job_is_cancelled(&s->common)) {
@@ -650,19 +541,20 @@ static void coroutine_fn mirror_run(void *opaque)
      * the destination do COW.  Instead, we copy sectors around the
      * dirty data if needed.  We need a bitmap to do that.
      */
-    bdrv_get_backing_filename(target_bs, backing_filename,
+    bdrv_get_backing_filename(s->target, backing_filename,
                               sizeof(backing_filename));
-    if (!bdrv_get_info(target_bs, &bdi) && bdi.cluster_size) {
+    if (!bdrv_get_info(s->target, &bdi) && bdi.cluster_size) {
         target_cluster_size = bdi.cluster_size;
     }
-    if (backing_filename[0] && !target_bs->backing
+    if (backing_filename[0] && !s->target->backing
         && s->granularity < target_cluster_size) {
         s->buf_size = MAX(s->buf_size, target_cluster_size);
         s->cow_bitmap = bitmap_new(length);
     }
     s->target_cluster_sectors = target_cluster_size >> BDRV_SECTOR_BITS;
-    s->max_iov = MIN(bs->bl.max_iov, target_bs->bl.max_iov);
+    s->max_iov = MIN(s->common.bs->bl.max_iov, s->target->bl.max_iov);
 
+    end = s->bdev_length / BDRV_SECTOR_SIZE;
     s->buf = qemu_try_blockalign(bs, s->buf_size);
     if (s->buf == NULL) {
         ret = -ENOMEM;
@@ -671,18 +563,45 @@ static void coroutine_fn mirror_run(void *opaque)
 
     mirror_free_init(s);
 
-    s->last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
     if (!s->is_none_mode) {
-        ret = mirror_dirty_init(s);
-        if (ret < 0 || block_job_is_cancelled(&s->common)) {
-            goto immediate_exit;
+        /* First part, loop on the sectors and initialize the dirty bitmap.  */
+        BlockDriverState *base = s->base;
+        bool mark_all_dirty = s->base == NULL && !bdrv_has_zero_init(s->target);
+
+        for (sector_num = 0; sector_num < end; ) {
+            /* Just to make sure we are not exceeding int limit. */
+            int nb_sectors = MIN(INT_MAX >> BDRV_SECTOR_BITS,
+                                 end - sector_num);
+            int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+
+            if (now - last_pause_ns > SLICE_TIME) {
+                last_pause_ns = now;
+                block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0);
+            }
+
+            if (block_job_is_cancelled(&s->common)) {
+                goto immediate_exit;
+            }
+
+            ret = bdrv_is_allocated_above(bs, base, sector_num, nb_sectors, &n);
+
+            if (ret < 0) {
+                goto immediate_exit;
+            }
+
+            assert(n > 0);
+            if (ret == 1 || mark_all_dirty) {
+                bdrv_set_dirty_bitmap(s->dirty_bitmap, sector_num, n);
+            }
+            sector_num += n;
         }
     }
 
     bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
     for (;;) {
         uint64_t delay_ns = 0;
-        int64_t cnt, delta;
+        int64_t cnt;
         bool should_complete;
 
         if (s->ret < 0) {
@@ -690,8 +609,6 @@ static void coroutine_fn mirror_run(void *opaque)
             goto immediate_exit;
         }
 
-        block_job_pause_point(&s->common);
-
         cnt = bdrv_get_dirty_count(s->dirty_bitmap);
         /* s->common.offset contains the number of bytes already processed so
          * far, cnt is the number of dirty sectors remaining and
@@ -705,10 +622,9 @@ static void coroutine_fn mirror_run(void *opaque)
          * We do so every SLICE_TIME nanoseconds, or when there is an error,
          * or when the source is clean, whichever comes first.
          */
-        delta = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - s->last_pause_ns;
-        if (delta < SLICE_TIME &&
+        if (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - last_pause_ns < SLICE_TIME &&
             s->common.iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
-            if (s->in_flight >= MAX_IN_FLIGHT || s->buf_free_count == 0 ||
+            if (s->in_flight == MAX_IN_FLIGHT || s->buf_free_count == 0 ||
                 (cnt == 0 && s->in_flight > 0)) {
                 trace_mirror_yield(s, s->in_flight, s->buf_free_count, cnt);
                 mirror_wait_for_io(s);
@@ -721,7 +637,7 @@ static void coroutine_fn mirror_run(void *opaque)
         should_complete = false;
         if (s->in_flight == 0 && cnt == 0) {
             trace_mirror_before_flush(s);
-            ret = blk_flush(s->target);
+            ret = bdrv_flush(s->target);
             if (ret < 0) {
                 if (mirror_error_action(s, false, -ret) ==
                     BLOCK_ERROR_ACTION_REPORT) {
@@ -776,7 +692,7 @@ static void coroutine_fn mirror_run(void *opaque)
             s->common.cancelled = false;
             break;
         }
-        s->last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+        last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
     }
 
 immediate_exit:
@@ -794,12 +710,21 @@ immediate_exit:
     g_free(s->cow_bitmap);
     g_free(s->in_flight_bitmap);
     bdrv_release_dirty_bitmap(bs, s->dirty_bitmap);
+    if (s->target->blk) {
+        blk_iostatus_disable(s->target->blk);
+    }
 
     data = g_malloc(sizeof(*data));
     data->ret = ret;
     /* Before we switch to target in mirror_exit, make sure data doesn't
      * change. */
-    bdrv_drained_begin(bs);
+    bdrv_drained_begin(s->common.bs);
+    if (qemu_get_aio_context() == bdrv_get_aio_context(bs)) {
+        /* FIXME: virtio host notifiers run on iohandler_ctx, therefore the
+         * above bdrv_drained_end isn't enough to quiesce it. This is ugly, we
+         * need a block layer API change to achieve this. */
+        aio_disable_external(iohandler_get_aio_context());
+    }
     block_job_defer_to_main_loop(&s->common, mirror_exit, data);
 }
 
@@ -814,31 +739,32 @@ static void mirror_set_speed(BlockJob *job, int64_t speed, Error **errp)
     ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE, SLICE_TIME);
 }
 
-static void mirror_complete(BlockJob *job, Error **errp)
+static void mirror_iostatus_reset(BlockJob *job)
 {
     MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
-    BlockDriverState *src, *target;
-
-    src = blk_bs(job->blk);
-    target = blk_bs(s->target);
 
-    if (!s->synced) {
-        error_setg(errp, "The active block job '%s' cannot be completed",
-                   job->id);
-        return;
+    if (s->target->blk) {
+        blk_iostatus_reset(s->target->blk);
     }
+}
 
-    if (s->backing_mode == MIRROR_OPEN_BACKING_CHAIN) {
-        int ret;
+static void mirror_complete(BlockJob *job, Error **errp)
+{
+    MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
+    Error *local_err = NULL;
+    int ret;
 
-        assert(!target->backing);
-        ret = bdrv_open_backing_file(target, NULL, "backing", errp);
-        if (ret < 0) {
-            return;
-        }
+    ret = bdrv_open_backing_file(s->target, NULL, "backing", &local_err);
+    if (ret < 0) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (!s->synced) {
+        error_setg(errp, QERR_BLOCK_JOB_NOT_READY, job->id);
+        return;
     }
 
-    /* block all operations on to_replace bs */
+    /* check the target bs is not blocked and block all operations on it */
     if (s->replaces) {
         AioContext *replace_aio_context;
 
@@ -859,57 +785,31 @@ static void mirror_complete(BlockJob *job, Error **errp)
         aio_context_release(replace_aio_context);
     }
 
-    if (s->backing_mode == MIRROR_SOURCE_BACKING_CHAIN) {
-        BlockDriverState *backing = s->is_none_mode ? src : s->base;
-        if (backing_bs(target) != backing) {
-            bdrv_set_backing_hd(target, backing);
-        }
-    }
-
     s->should_complete = true;
     block_job_enter(&s->common);
 }
 
-/* There is no matching mirror_resume() because mirror_run() will begin
- * iterating again when the job is resumed.
- */
-static void coroutine_fn mirror_pause(BlockJob *job)
-{
-    MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
-
-    mirror_drain(s);
-}
-
-static void mirror_attached_aio_context(BlockJob *job, AioContext *new_context)
-{
-    MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
-
-    blk_set_aio_context(s->target, new_context);
-}
-
 static const BlockJobDriver mirror_job_driver = {
-    .instance_size          = sizeof(MirrorBlockJob),
-    .job_type               = BLOCK_JOB_TYPE_MIRROR,
-    .set_speed              = mirror_set_speed,
-    .complete               = mirror_complete,
-    .pause                  = mirror_pause,
-    .attached_aio_context   = mirror_attached_aio_context,
+    .instance_size = sizeof(MirrorBlockJob),
+    .job_type      = BLOCK_JOB_TYPE_MIRROR,
+    .set_speed     = mirror_set_speed,
+    .iostatus_reset= mirror_iostatus_reset,
+    .complete      = mirror_complete,
 };
 
 static const BlockJobDriver commit_active_job_driver = {
-    .instance_size          = sizeof(MirrorBlockJob),
-    .job_type               = BLOCK_JOB_TYPE_COMMIT,
-    .set_speed              = mirror_set_speed,
-    .complete               = mirror_complete,
-    .pause                  = mirror_pause,
-    .attached_aio_context   = mirror_attached_aio_context,
+    .instance_size = sizeof(MirrorBlockJob),
+    .job_type      = BLOCK_JOB_TYPE_COMMIT,
+    .set_speed     = mirror_set_speed,
+    .iostatus_reset
+                   = mirror_iostatus_reset,
+    .complete      = mirror_complete,
 };
 
-static void mirror_start_job(const char *job_id, BlockDriverState *bs,
-                             BlockDriverState *target, const char *replaces,
+static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
+                             const char *replaces,
                              int64_t speed, uint32_t granularity,
                              int64_t buf_size,
-                             BlockMirrorBackingMode backing_mode,
                              BlockdevOnError on_source_error,
                              BlockdevOnError on_target_error,
                              bool unmap,
@@ -919,6 +819,7 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
                              bool is_none_mode, BlockDriverState *base)
 {
     MirrorBlockJob *s;
+    BlockDriverState *replaced_bs;
 
     if (granularity == 0) {
         granularity = bdrv_get_default_bitmap_granularity(target);
@@ -926,6 +827,13 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
 
     assert ((granularity & (granularity - 1)) == 0);
 
+    if ((on_source_error == BLOCKDEV_ON_ERROR_STOP ||
+         on_source_error == BLOCKDEV_ON_ERROR_ENOSPC) &&
+        (!bs->blk || !blk_iostatus_is_enabled(bs->blk))) {
+        error_setg(errp, QERR_INVALID_PARAMETER, "on-source-error");
+        return;
+    }
+
     if (buf_size < 0) {
         error_setg(errp, "Invalid parameter 'buf-size'");
         return;
@@ -935,19 +843,31 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
         buf_size = DEFAULT_MIRROR_BUF_SIZE;
     }
 
-    s = block_job_create(job_id, driver, bs, speed, cb, opaque, errp);
-    if (!s) {
+    /* We can't support this case as long as the block layer can't handle
+     * multiple BlockBackends per BlockDriverState. */
+    if (replaces) {
+        replaced_bs = bdrv_lookup_bs(replaces, replaces, errp);
+        if (replaced_bs == NULL) {
+            return;
+        }
+    } else {
+        replaced_bs = bs;
+    }
+    if (replaced_bs->blk && target->blk) {
+        error_setg(errp, "Can't create node with two BlockBackends");
         return;
     }
 
-    s->target = blk_new();
-    blk_insert_bs(s->target, target);
+    s = block_job_create(driver, bs, speed, cb, opaque, errp);
+    if (!s) {
+        return;
+    }
 
     s->replaces = g_strdup(replaces);
     s->on_source_error = on_source_error;
     s->on_target_error = on_target_error;
+    s->target = target;
     s->is_none_mode = is_none_mode;
-    s->backing_mode = backing_mode;
     s->base = base;
     s->granularity = granularity;
     s->buf_size = ROUND_UP(buf_size, granularity);
@@ -956,23 +876,25 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
     s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
     if (!s->dirty_bitmap) {
         g_free(s->replaces);
-        blk_unref(s->target);
         block_job_unref(&s->common);
         return;
     }
 
-    bdrv_op_block_all(target, s->common.blocker);
+    bdrv_op_block_all(s->target, s->common.blocker);
 
-    s->common.co = qemu_coroutine_create(mirror_run, s);
+    if (s->target->blk) {
+        blk_set_on_error(s->target->blk, on_target_error, on_target_error);
+        blk_iostatus_enable(s->target->blk);
+    }
+    s->common.co = qemu_coroutine_create(mirror_run);
     trace_mirror_start(bs, s, s->common.co, opaque);
-    qemu_coroutine_enter(s->common.co);
+    qemu_coroutine_enter(s->common.co, s);
 }
 
-void mirror_start(const char *job_id, BlockDriverState *bs,
-                  BlockDriverState *target, const char *replaces,
+void mirror_start(BlockDriverState *bs, BlockDriverState *target,
+                  const char *replaces,
                   int64_t speed, uint32_t granularity, int64_t buf_size,
-                  MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
-                  BlockdevOnError on_source_error,
+                  MirrorSyncMode mode, BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
                   bool unmap,
                   BlockCompletionFunc *cb,
@@ -987,14 +909,14 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
     }
     is_none_mode = mode == MIRROR_SYNC_MODE_NONE;
     base = mode == MIRROR_SYNC_MODE_TOP ? backing_bs(bs) : NULL;
-    mirror_start_job(job_id, bs, target, replaces,
-                     speed, granularity, buf_size, backing_mode,
+    mirror_start_job(bs, target, replaces,
+                     speed, granularity, buf_size,
                      on_source_error, on_target_error, unmap, cb, opaque, errp,
                      &mirror_job_driver, is_none_mode, base);
 }
 
-void commit_active_start(const char *job_id, BlockDriverState *bs,
-                         BlockDriverState *base, int64_t speed,
+void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
+                         int64_t speed,
                          BlockdevOnError on_error,
                          BlockCompletionFunc *cb,
                          void *opaque, Error **errp)
@@ -1035,8 +957,8 @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
         }
     }
 
-    mirror_start_job(job_id, bs, base, NULL, speed, 0, 0,
-                     MIRROR_LEAVE_BACKING_CHAIN,
+    bdrv_ref(base);
+    mirror_start_job(bs, base, NULL, speed, 0, 0,
                      on_error, on_error, false, cb, opaque, &local_err,
                      &commit_active_job_driver, false, base);
     if (local_err) {
index 2cf3237..6f6df46 100644 (file)
@@ -38,7 +38,7 @@ static void nbd_recv_coroutines_enter_all(NbdClientSession *s)
 
     for (i = 0; i < MAX_NBD_REQUESTS; i++) {
         if (s->recv_coroutine[i]) {
-            qemu_coroutine_enter(s->recv_coroutine[i]);
+            qemu_coroutine_enter(s->recv_coroutine[i], NULL);
         }
     }
 }
@@ -99,7 +99,7 @@ static void nbd_reply_ready(void *opaque)
     }
 
     if (s->recv_coroutine[i]) {
-        qemu_coroutine_enter(s->recv_coroutine[i]);
+        qemu_coroutine_enter(s->recv_coroutine[i], NULL);
         return;
     }
 
@@ -111,12 +111,12 @@ static void nbd_restart_write(void *opaque)
 {
     BlockDriverState *bs = opaque;
 
-    qemu_coroutine_enter(nbd_get_client_session(bs)->send_coroutine);
+    qemu_coroutine_enter(nbd_get_client_session(bs)->send_coroutine, NULL);
 }
 
 static int nbd_co_send_request(BlockDriverState *bs,
                                struct nbd_request *request,
-                               QEMUIOVector *qiov)
+                               QEMUIOVector *qiov, int offset)
 {
     NbdClientSession *s = nbd_get_client_session(bs);
     AioContext *aio_context;
@@ -149,8 +149,8 @@ static int nbd_co_send_request(BlockDriverState *bs,
         qio_channel_set_cork(s->ioc, true);
         rc = nbd_send_request(s->ioc, request);
         if (rc >= 0) {
-            ret = nbd_wr_syncv(s->ioc, qiov->iov, qiov->niov, request->len,
-                               false);
+            ret = nbd_wr_syncv(s->ioc, qiov->iov, qiov->niov,
+                               offset, request->len, 0);
             if (ret != request->len) {
                 rc = -EIO;
             }
@@ -167,9 +167,8 @@ static int nbd_co_send_request(BlockDriverState *bs,
 }
 
 static void nbd_co_receive_reply(NbdClientSession *s,
-                                 struct nbd_request *request,
-                                 struct nbd_reply *reply,
-                                 QEMUIOVector *qiov)
+    struct nbd_request *request, struct nbd_reply *reply,
+    QEMUIOVector *qiov, int offset)
 {
     int ret;
 
@@ -182,8 +181,8 @@ static void nbd_co_receive_reply(NbdClientSession *s,
         reply->error = EIO;
     } else {
         if (qiov && reply->error == 0) {
-            ret = nbd_wr_syncv(s->ioc, qiov->iov, qiov->niov, request->len,
-                               true);
+            ret = nbd_wr_syncv(s->ioc, qiov->iov, qiov->niov,
+                               offset, request->len, 1);
             if (ret != request->len) {
                 reply->error = EIO;
             }
@@ -218,62 +217,93 @@ static void nbd_coroutine_end(NbdClientSession *s,
     }
 }
 
-int nbd_client_co_preadv(BlockDriverState *bs, uint64_t offset,
-                         uint64_t bytes, QEMUIOVector *qiov, int flags)
+static int nbd_co_readv_1(BlockDriverState *bs, int64_t sector_num,
+                          int nb_sectors, QEMUIOVector *qiov,
+                          int offset)
 {
     NbdClientSession *client = nbd_get_client_session(bs);
-    struct nbd_request request = {
-        .type = NBD_CMD_READ,
-        .from = offset,
-        .len = bytes,
-    };
+    struct nbd_request request = { .type = NBD_CMD_READ };
     struct nbd_reply reply;
     ssize_t ret;
 
-    assert(bytes <= NBD_MAX_BUFFER_SIZE);
-    assert(!flags);
+    request.from = sector_num * 512;
+    request.len = nb_sectors * 512;
 
     nbd_coroutine_start(client, &request);
-    ret = nbd_co_send_request(bs, &request, NULL);
+    ret = nbd_co_send_request(bs, &request, NULL, 0);
     if (ret < 0) {
         reply.error = -ret;
     } else {
-        nbd_co_receive_reply(client, &request, &reply, qiov);
+        nbd_co_receive_reply(client, &request, &reply, qiov, offset);
     }
     nbd_coroutine_end(client, &request);
     return -reply.error;
+
 }
 
-int nbd_client_co_pwritev(BlockDriverState *bs, uint64_t offset,
-                          uint64_t bytes, QEMUIOVector *qiov, int flags)
+static int nbd_co_writev_1(BlockDriverState *bs, int64_t sector_num,
+                           int nb_sectors, QEMUIOVector *qiov,
+                           int offset, int *flags)
 {
     NbdClientSession *client = nbd_get_client_session(bs);
-    struct nbd_request request = {
-        .type = NBD_CMD_WRITE,
-        .from = offset,
-        .len = bytes,
-    };
+    struct nbd_request request = { .type = NBD_CMD_WRITE };
     struct nbd_reply reply;
     ssize_t ret;
 
-    if (flags & BDRV_REQ_FUA) {
-        assert(client->nbdflags & NBD_FLAG_SEND_FUA);
+    if ((*flags & BDRV_REQ_FUA) && (client->nbdflags & NBD_FLAG_SEND_FUA)) {
+        *flags &= ~BDRV_REQ_FUA;
         request.type |= NBD_CMD_FLAG_FUA;
     }
 
-    assert(bytes <= NBD_MAX_BUFFER_SIZE);
+    request.from = sector_num * 512;
+    request.len = nb_sectors * 512;
 
     nbd_coroutine_start(client, &request);
-    ret = nbd_co_send_request(bs, &request, qiov);
+    ret = nbd_co_send_request(bs, &request, qiov, offset);
     if (ret < 0) {
         reply.error = -ret;
     } else {
-        nbd_co_receive_reply(client, &request, &reply, NULL);
+        nbd_co_receive_reply(client, &request, &reply, NULL, 0);
     }
     nbd_coroutine_end(client, &request);
     return -reply.error;
 }
 
+int nbd_client_co_readv(BlockDriverState *bs, int64_t sector_num,
+                        int nb_sectors, QEMUIOVector *qiov)
+{
+    int offset = 0;
+    int ret;
+    while (nb_sectors > NBD_MAX_SECTORS) {
+        ret = nbd_co_readv_1(bs, sector_num, NBD_MAX_SECTORS, qiov, offset);
+        if (ret < 0) {
+            return ret;
+        }
+        offset += NBD_MAX_SECTORS * 512;
+        sector_num += NBD_MAX_SECTORS;
+        nb_sectors -= NBD_MAX_SECTORS;
+    }
+    return nbd_co_readv_1(bs, sector_num, nb_sectors, qiov, offset);
+}
+
+int nbd_client_co_writev(BlockDriverState *bs, int64_t sector_num,
+                         int nb_sectors, QEMUIOVector *qiov, int *flags)
+{
+    int offset = 0;
+    int ret;
+    while (nb_sectors > NBD_MAX_SECTORS) {
+        ret = nbd_co_writev_1(bs, sector_num, NBD_MAX_SECTORS, qiov, offset,
+                              flags);
+        if (ret < 0) {
+            return ret;
+        }
+        offset += NBD_MAX_SECTORS * 512;
+        sector_num += NBD_MAX_SECTORS;
+        nb_sectors -= NBD_MAX_SECTORS;
+    }
+    return nbd_co_writev_1(bs, sector_num, nb_sectors, qiov, offset, flags);
+}
+
 int nbd_client_co_flush(BlockDriverState *bs)
 {
     NbdClientSession *client = nbd_get_client_session(bs);
@@ -289,37 +319,36 @@ int nbd_client_co_flush(BlockDriverState *bs)
     request.len = 0;
 
     nbd_coroutine_start(client, &request);
-    ret = nbd_co_send_request(bs, &request, NULL);
+    ret = nbd_co_send_request(bs, &request, NULL, 0);
     if (ret < 0) {
         reply.error = -ret;
     } else {
-        nbd_co_receive_reply(client, &request, &reply, NULL);
+        nbd_co_receive_reply(client, &request, &reply, NULL, 0);
     }
     nbd_coroutine_end(client, &request);
     return -reply.error;
 }
 
-int nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset, int count)
+int nbd_client_co_discard(BlockDriverState *bs, int64_t sector_num,
+                          int nb_sectors)
 {
     NbdClientSession *client = nbd_get_client_session(bs);
-    struct nbd_request request = {
-        .type = NBD_CMD_TRIM,
-        .from = offset,
-        .len = count,
-    };
+    struct nbd_request request = { .type = NBD_CMD_TRIM };
     struct nbd_reply reply;
     ssize_t ret;
 
     if (!(client->nbdflags & NBD_FLAG_SEND_TRIM)) {
         return 0;
     }
+    request.from = sector_num * 512;
+    request.len = nb_sectors * 512;
 
     nbd_coroutine_start(client, &request);
-    ret = nbd_co_send_request(bs, &request, NULL);
+    ret = nbd_co_send_request(bs, &request, NULL, 0);
     if (ret < 0) {
         reply.error = -ret;
     } else {
-        nbd_co_receive_reply(client, &request, &reply, NULL);
+        nbd_co_receive_reply(client, &request, &reply, NULL, 0);
     }
     nbd_coroutine_end(client, &request);
     return -reply.error;
@@ -381,9 +410,6 @@ int nbd_client_init(BlockDriverState *bs,
         logout("Failed to negotiate with the NBD server\n");
         return ret;
     }
-    if (client->nbdflags & NBD_FLAG_SEND_FUA) {
-        bs->supported_write_flags = BDRV_REQ_FUA;
-    }
 
     qemu_co_mutex_init(&client->send_mutex);
     qemu_co_mutex_init(&client->free_sema);
index 044aca4..1243612 100644 (file)
@@ -44,12 +44,13 @@ int nbd_client_init(BlockDriverState *bs,
                     Error **errp);
 void nbd_client_close(BlockDriverState *bs);
 
-int nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset, int count);
+int nbd_client_co_discard(BlockDriverState *bs, int64_t sector_num,
+                          int nb_sectors);
 int nbd_client_co_flush(BlockDriverState *bs);
-int nbd_client_co_pwritev(BlockDriverState *bs, uint64_t offset,
-                          uint64_t bytes, QEMUIOVector *qiov, int flags);
-int nbd_client_co_preadv(BlockDriverState *bs, uint64_t offset,
-                         uint64_t bytes, QEMUIOVector *qiov, int flags);
+int nbd_client_co_writev(BlockDriverState *bs, int64_t sector_num,
+                         int nb_sectors, QEMUIOVector *qiov, int *flags);
+int nbd_client_co_readv(BlockDriverState *bs, int64_t sector_num,
+                        int nb_sectors, QEMUIOVector *qiov);
 
 void nbd_client_detach_aio_context(BlockDriverState *bs);
 void nbd_client_attach_aio_context(BlockDriverState *bs,
index 6bc06d6..f7ea3b3 100644 (file)
@@ -42,9 +42,6 @@
 
 typedef struct BDRVNBDState {
     NbdClientSession client;
-
-    /* For nbd_refresh_filename() */
-    char *path, *host, *port, *export, *tlscredsid;
 } BDRVNBDState;
 
 static int nbd_parse_uri(const char *filename, QDict *options)
@@ -191,15 +188,13 @@ out:
     g_free(file);
 }
 
-static SocketAddress *nbd_config(BDRVNBDState *s, QemuOpts *opts, Error **errp)
+static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, char **export,
+                                 Error **errp)
 {
     SocketAddress *saddr;
 
-    s->path = g_strdup(qemu_opt_get(opts, "path"));
-    s->host = g_strdup(qemu_opt_get(opts, "host"));
-
-    if (!s->path == !s->host) {
-        if (s->path) {
+    if (qdict_haskey(options, "path") == qdict_haskey(options, "host")) {
+        if (qdict_haskey(options, "path")) {
             error_setg(errp, "path and host may not be used at the same time.");
         } else {
             error_setg(errp, "one of path and host must be specified.");
@@ -209,28 +204,32 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QemuOpts *opts, Error **errp)
 
     saddr = g_new0(SocketAddress, 1);
 
-    if (s->path) {
+    if (qdict_haskey(options, "path")) {
         UnixSocketAddress *q_unix;
         saddr->type = SOCKET_ADDRESS_KIND_UNIX;
         q_unix = saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
-        q_unix->path = g_strdup(s->path);
+        q_unix->path = g_strdup(qdict_get_str(options, "path"));
+        qdict_del(options, "path");
     } else {
         InetSocketAddress *inet;
-
-        s->port = g_strdup(qemu_opt_get(opts, "port"));
-
         saddr->type = SOCKET_ADDRESS_KIND_INET;
         inet = saddr->u.inet.data = g_new0(InetSocketAddress, 1);
-        inet->host = g_strdup(s->host);
-        inet->port = g_strdup(s->port);
-        if (!inet->port) {
+        inet->host = g_strdup(qdict_get_str(options, "host"));
+        if (!qdict_get_try_str(options, "port")) {
             inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
+        } else {
+            inet->port = g_strdup(qdict_get_str(options, "port"));
         }
+        qdict_del(options, "host");
+        qdict_del(options, "port");
     }
 
     s->client.is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
 
-    s->export = g_strdup(qemu_opt_get(opts, "export"));
+    *export = g_strdup(qdict_get_try_str(options, "export"));
+    if (*export) {
+        qdict_del(options, "export");
+    }
 
     return saddr;
 }
@@ -293,66 +292,28 @@ static QCryptoTLSCreds *nbd_get_tls_creds(const char *id, Error **errp)
 }
 
 
-static QemuOptsList nbd_runtime_opts = {
-    .name = "nbd",
-    .head = QTAILQ_HEAD_INITIALIZER(nbd_runtime_opts.head),
-    .desc = {
-        {
-            .name = "host",
-            .type = QEMU_OPT_STRING,
-            .help = "TCP host to connect to",
-        },
-        {
-            .name = "port",
-            .type = QEMU_OPT_STRING,
-            .help = "TCP port to connect to",
-        },
-        {
-            .name = "path",
-            .type = QEMU_OPT_STRING,
-            .help = "Unix socket path to connect to",
-        },
-        {
-            .name = "export",
-            .type = QEMU_OPT_STRING,
-            .help = "Name of the NBD export to open",
-        },
-        {
-            .name = "tls-creds",
-            .type = QEMU_OPT_STRING,
-            .help = "ID of the TLS credentials to use",
-        },
-    },
-};
-
 static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
                     Error **errp)
 {
     BDRVNBDState *s = bs->opaque;
-    QemuOpts *opts = NULL;
-    Error *local_err = NULL;
+    char *export = NULL;
     QIOChannelSocket *sioc = NULL;
-    SocketAddress *saddr = NULL;
+    SocketAddress *saddr;
+    const char *tlscredsid;
     QCryptoTLSCreds *tlscreds = NULL;
     const char *hostname = NULL;
     int ret = -EINVAL;
 
-    opts = qemu_opts_create(&nbd_runtime_opts, NULL, 0, &error_abort);
-    qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        goto error;
-    }
-
     /* Pop the config into our state object. Exit if invalid. */
-    saddr = nbd_config(s, opts, errp);
+    saddr = nbd_config(s, options, &export, errp);
     if (!saddr) {
         goto error;
     }
 
-    s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds"));
-    if (s->tlscredsid) {
-        tlscreds = nbd_get_tls_creds(s->tlscredsid, errp);
+    tlscredsid = g_strdup(qdict_get_try_str(options, "tls-creds"));
+    if (tlscredsid) {
+        qdict_del(options, "tls-creds");
+        tlscreds = nbd_get_tls_creds(tlscredsid, errp);
         if (!tlscreds) {
             goto error;
         }
@@ -374,7 +335,7 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
     }
 
     /* NBD handshake */
-    ret = nbd_client_init(bs, sioc, s->export,
+    ret = nbd_client_init(bs, sioc, export,
                           tlscreds, hostname, errp);
  error:
     if (sioc) {
@@ -383,18 +344,42 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
     if (tlscreds) {
         object_unref(OBJECT(tlscreds));
     }
+    qapi_free_SocketAddress(saddr);
+    g_free(export);
+    return ret;
+}
+
+static int nbd_co_readv(BlockDriverState *bs, int64_t sector_num,
+                        int nb_sectors, QEMUIOVector *qiov)
+{
+    return nbd_client_co_readv(bs, sector_num, nb_sectors, qiov);
+}
+
+static int nbd_co_writev_flags(BlockDriverState *bs, int64_t sector_num,
+                               int nb_sectors, QEMUIOVector *qiov, int flags)
+{
+    int ret;
+
+    ret = nbd_client_co_writev(bs, sector_num, nb_sectors, qiov, &flags);
     if (ret < 0) {
-        g_free(s->path);
-        g_free(s->host);
-        g_free(s->port);
-        g_free(s->export);
-        g_free(s->tlscredsid);
+        return ret;
     }
-    qapi_free_SocketAddress(saddr);
-    qemu_opts_del(opts);
+
+    /* The flag wasn't sent to the server, so we need to emulate it with an
+     * explicit flush */
+    if (flags & BDRV_REQ_FUA) {
+        ret = nbd_client_co_flush(bs);
+    }
+
     return ret;
 }
 
+static int nbd_co_writev(BlockDriverState *bs, int64_t sector_num,
+                         int nb_sectors, QEMUIOVector *qiov)
+{
+    return nbd_co_writev_flags(bs, sector_num, nb_sectors, qiov, 0);
+}
+
 static int nbd_co_flush(BlockDriverState *bs)
 {
     return nbd_client_co_flush(bs);
@@ -402,21 +387,19 @@ static int nbd_co_flush(BlockDriverState *bs)
 
 static void nbd_refresh_limits(BlockDriverState *bs, Error **errp)
 {
-    bs->bl.max_pdiscard = NBD_MAX_BUFFER_SIZE;
-    bs->bl.max_transfer = NBD_MAX_BUFFER_SIZE;
+    bs->bl.max_discard = UINT32_MAX >> BDRV_SECTOR_BITS;
+    bs->bl.max_transfer_length = UINT32_MAX >> BDRV_SECTOR_BITS;
 }
 
-static void nbd_close(BlockDriverState *bs)
+static int nbd_co_discard(BlockDriverState *bs, int64_t sector_num,
+                          int nb_sectors)
 {
-    BDRVNBDState *s = bs->opaque;
+    return nbd_client_co_discard(bs, sector_num, nb_sectors);
+}
 
+static void nbd_close(BlockDriverState *bs)
+{
     nbd_client_close(bs);
-
-    g_free(s->path);
-    g_free(s->host);
-    g_free(s->port);
-    g_free(s->export);
-    g_free(s->tlscredsid);
 }
 
 static int64_t nbd_getlength(BlockDriverState *bs)
@@ -439,45 +422,48 @@ static void nbd_attach_aio_context(BlockDriverState *bs,
 
 static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
 {
-    BDRVNBDState *s = bs->opaque;
     QDict *opts = qdict_new();
+    const char *path   = qdict_get_try_str(options, "path");
+    const char *host   = qdict_get_try_str(options, "host");
+    const char *port   = qdict_get_try_str(options, "port");
+    const char *export = qdict_get_try_str(options, "export");
+    const char *tlscreds = qdict_get_try_str(options, "tls-creds");
 
     qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("nbd")));
 
-    if (s->path && s->export) {
+    if (path && export) {
         snprintf(bs->exact_filename, sizeof(bs->exact_filename),
-                 "nbd+unix:///%s?socket=%s", s->export, s->path);
-    } else if (s->path && !s->export) {
+                 "nbd+unix:///%s?socket=%s", export, path);
+    } else if (path && !export) {
         snprintf(bs->exact_filename, sizeof(bs->exact_filename),
-                 "nbd+unix://?socket=%s", s->path);
-    } else if (!s->path && s->export && s->port) {
+                 "nbd+unix://?socket=%s", path);
+    } else if (!path && export && port) {
         snprintf(bs->exact_filename, sizeof(bs->exact_filename),
-                 "nbd://%s:%s/%s", s->host, s->port, s->export);
-    } else if (!s->path && s->export && !s->port) {
+                 "nbd://%s:%s/%s", host, port, export);
+    } else if (!path && export && !port) {
         snprintf(bs->exact_filename, sizeof(bs->exact_filename),
-                 "nbd://%s/%s", s->host, s->export);
-    } else if (!s->path && !s->export && s->port) {
+                 "nbd://%s/%s", host, export);
+    } else if (!path && !export && port) {
         snprintf(bs->exact_filename, sizeof(bs->exact_filename),
-                 "nbd://%s:%s", s->host, s->port);
-    } else if (!s->path && !s->export && !s->port) {
+                 "nbd://%s:%s", host, port);
+    } else if (!path && !export && !port) {
         snprintf(bs->exact_filename, sizeof(bs->exact_filename),
-                 "nbd://%s", s->host);
+                 "nbd://%s", host);
     }
 
-    if (s->path) {
-        qdict_put_obj(opts, "path", QOBJECT(qstring_from_str(s->path)));
-    } else if (s->port) {
-        qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(s->host)));
-        qdict_put_obj(opts, "port", QOBJECT(qstring_from_str(s->port)));
+    if (path) {
+        qdict_put_obj(opts, "path", QOBJECT(qstring_from_str(path)));
+    } else if (port) {
+        qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(host)));
+        qdict_put_obj(opts, "port", QOBJECT(qstring_from_str(port)));
     } else {
-        qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(s->host)));
+        qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(host)));
     }
-    if (s->export) {
-        qdict_put_obj(opts, "export", QOBJECT(qstring_from_str(s->export)));
+    if (export) {
+        qdict_put_obj(opts, "export", QOBJECT(qstring_from_str(export)));
     }
-    if (s->tlscredsid) {
-        qdict_put_obj(opts, "tls-creds",
-                      QOBJECT(qstring_from_str(s->tlscredsid)));
+    if (tlscreds) {
+        qdict_put_obj(opts, "tls-creds", QOBJECT(qstring_from_str(tlscreds)));
     }
 
     bs->full_open_options = opts;
@@ -489,11 +475,13 @@ static BlockDriver bdrv_nbd = {
     .instance_size              = sizeof(BDRVNBDState),
     .bdrv_parse_filename        = nbd_parse_filename,
     .bdrv_file_open             = nbd_open,
-    .bdrv_co_preadv             = nbd_client_co_preadv,
-    .bdrv_co_pwritev            = nbd_client_co_pwritev,
+    .bdrv_co_readv              = nbd_co_readv,
+    .bdrv_co_writev             = nbd_co_writev,
+    .bdrv_co_writev_flags       = nbd_co_writev_flags,
+    .supported_write_flags      = BDRV_REQ_FUA,
     .bdrv_close                 = nbd_close,
     .bdrv_co_flush_to_os        = nbd_co_flush,
-    .bdrv_co_pdiscard           = nbd_client_co_pdiscard,
+    .bdrv_co_discard            = nbd_co_discard,
     .bdrv_refresh_limits        = nbd_refresh_limits,
     .bdrv_getlength             = nbd_getlength,
     .bdrv_detach_aio_context    = nbd_detach_aio_context,
@@ -507,11 +495,13 @@ static BlockDriver bdrv_nbd_tcp = {
     .instance_size              = sizeof(BDRVNBDState),
     .bdrv_parse_filename        = nbd_parse_filename,
     .bdrv_file_open             = nbd_open,
-    .bdrv_co_preadv             = nbd_client_co_preadv,
-    .bdrv_co_pwritev            = nbd_client_co_pwritev,
+    .bdrv_co_readv              = nbd_co_readv,
+    .bdrv_co_writev             = nbd_co_writev,
+    .bdrv_co_writev_flags       = nbd_co_writev_flags,
+    .supported_write_flags      = BDRV_REQ_FUA,
     .bdrv_close                 = nbd_close,
     .bdrv_co_flush_to_os        = nbd_co_flush,
-    .bdrv_co_pdiscard           = nbd_client_co_pdiscard,
+    .bdrv_co_discard            = nbd_co_discard,
     .bdrv_refresh_limits        = nbd_refresh_limits,
     .bdrv_getlength             = nbd_getlength,
     .bdrv_detach_aio_context    = nbd_detach_aio_context,
@@ -525,11 +515,13 @@ static BlockDriver bdrv_nbd_unix = {
     .instance_size              = sizeof(BDRVNBDState),
     .bdrv_parse_filename        = nbd_parse_filename,
     .bdrv_file_open             = nbd_open,
-    .bdrv_co_preadv             = nbd_client_co_preadv,
-    .bdrv_co_pwritev            = nbd_client_co_pwritev,
+    .bdrv_co_readv              = nbd_co_readv,
+    .bdrv_co_writev             = nbd_co_writev,
+    .bdrv_co_writev_flags       = nbd_co_writev_flags,
+    .supported_write_flags      = BDRV_REQ_FUA,
     .bdrv_close                 = nbd_close,
     .bdrv_co_flush_to_os        = nbd_co_flush,
-    .bdrv_co_pdiscard           = nbd_client_co_pdiscard,
+    .bdrv_co_discard            = nbd_co_discard,
     .bdrv_refresh_limits        = nbd_refresh_limits,
     .bdrv_getlength             = nbd_getlength,
     .bdrv_detach_aio_context    = nbd_detach_aio_context,
index 8602a44..60be45e 100644 (file)
@@ -38,7 +38,6 @@
 #include <nfsc/libnfs.h>
 
 #define QEMU_NFS_MAX_READAHEAD_SIZE 1048576
-#define QEMU_NFS_MAX_PAGECACHE_SIZE (8388608 / NFS_BLKSIZE)
 #define QEMU_NFS_MAX_DEBUG_LEVEL 2
 
 typedef struct NFSClient {
@@ -104,7 +103,7 @@ static void nfs_co_generic_bh_cb(void *opaque)
     NFSRPC *task = opaque;
     task->complete = 1;
     qemu_bh_delete(task->bh);
-    qemu_coroutine_enter(task->co);
+    qemu_coroutine_enter(task->co, NULL);
 }
 
 static void
@@ -343,26 +342,6 @@ static int64_t nfs_client_open(NFSClient *client, const char *filename,
                 val = QEMU_NFS_MAX_READAHEAD_SIZE;
             }
             nfs_set_readahead(client->context, val);
-#ifdef LIBNFS_FEATURE_PAGECACHE
-            nfs_set_pagecache_ttl(client->context, 0);
-#endif
-            client->cache_used = true;
-#endif
-#ifdef LIBNFS_FEATURE_PAGECACHE
-            nfs_set_pagecache_ttl(client->context, 0);
-        } else if (!strcmp(qp->p[i].name, "pagecache")) {
-            if (open_flags & BDRV_O_NOCACHE) {
-                error_setg(errp, "Cannot enable NFS pagecache "
-                                 "if cache.direct = on");
-                goto fail;
-            }
-            if (val > QEMU_NFS_MAX_PAGECACHE_SIZE) {
-                error_report("NFS Warning: Truncating NFS pagecache"
-                             " size to %d pages", QEMU_NFS_MAX_PAGECACHE_SIZE);
-                val = QEMU_NFS_MAX_PAGECACHE_SIZE;
-            }
-            nfs_set_pagecache(client->context, val);
-            nfs_set_pagecache_ttl(client->context, 0);
             client->cache_used = true;
 #endif
 #ifdef LIBNFS_FEATURE_DEBUG
@@ -545,8 +524,7 @@ static int nfs_reopen_prepare(BDRVReopenState *state,
     }
 
     if ((state->flags & BDRV_O_NOCACHE) && client->cache_used) {
-        error_setg(errp, "Cannot disable cache if libnfs readahead or"
-                         " pagecache is enabled");
+        error_setg(errp, "Cannot disable cache if libnfs readahead is enabled");
         return -EINVAL;
     }
 
@@ -564,15 +542,6 @@ static int nfs_reopen_prepare(BDRVReopenState *state,
     return 0;
 }
 
-#ifdef LIBNFS_FEATURE_PAGECACHE
-static void nfs_invalidate_cache(BlockDriverState *bs,
-                                 Error **errp)
-{
-    NFSClient *client = bs->opaque;
-    nfs_pagecache_invalidate(client->context, client->fh);
-}
-#endif
-
 static BlockDriver bdrv_nfs = {
     .format_name                    = "nfs",
     .protocol_name                  = "nfs",
@@ -596,10 +565,6 @@ static BlockDriver bdrv_nfs = {
 
     .bdrv_detach_aio_context        = nfs_detach_aio_context,
     .bdrv_attach_aio_context        = nfs_attach_aio_context,
-
-#ifdef LIBNFS_FEATURE_PAGECACHE
-    .bdrv_invalidate_cache          = nfs_invalidate_cache,
-#endif
 };
 
 static void nfs_block_init(void)
index b511010..396500b 100644 (file)
@@ -12,8 +12,6 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qstring.h"
 #include "block/block_int.h"
 
 #define NULL_OPT_LATENCY "latency-ns"
@@ -225,20 +223,6 @@ static int64_t coroutine_fn null_co_get_block_status(BlockDriverState *bs,
     }
 }
 
-static void null_refresh_filename(BlockDriverState *bs, QDict *opts)
-{
-    QINCREF(opts);
-    qdict_del(opts, "filename");
-
-    if (!qdict_size(opts)) {
-        snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s://",
-                 bs->drv->format_name);
-    }
-
-    qdict_put(opts, "driver", qstring_from_str(bs->drv->format_name));
-    bs->full_open_options = opts;
-}
-
 static BlockDriver bdrv_null_co = {
     .format_name            = "null-co",
     .protocol_name          = "null-co",
@@ -254,8 +238,6 @@ static BlockDriver bdrv_null_co = {
     .bdrv_reopen_prepare    = null_reopen_prepare,
 
     .bdrv_co_get_block_status   = null_co_get_block_status,
-
-    .bdrv_refresh_filename  = null_refresh_filename,
 };
 
 static BlockDriver bdrv_null_aio = {
@@ -273,8 +255,6 @@ static BlockDriver bdrv_null_aio = {
     .bdrv_reopen_prepare    = null_reopen_prepare,
 
     .bdrv_co_get_block_status   = null_co_get_block_status,
-
-    .bdrv_refresh_filename  = null_refresh_filename,
 };
 
 static void bdrv_null_init(void)
index 2ccefa7..324ed43 100644 (file)
@@ -33,7 +33,6 @@
 #include "block/block_int.h"
 #include "sysemu/block-backend.h"
 #include "qemu/module.h"
-#include "qemu/bswap.h"
 #include "qemu/bitmap.h"
 #include "qapi/util.h"
 
@@ -43,7 +42,6 @@
 #define HEADER_MAGIC2 "WithouFreSpacExt"
 #define HEADER_VERSION 2
 #define HEADER_INUSE_MAGIC  (0x746F6E59)
-#define MAX_PARALLELS_IMAGE_FACTOR (1ull << 32)
 
 #define DEFAULT_CLUSTER_SIZE 1048576        /* 1 MiB */
 
@@ -205,15 +203,13 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
         return -EINVAL;
     }
 
-    to_allocate = DIV_ROUND_UP(sector_num + *pnum, s->tracks) - idx;
+    to_allocate = (sector_num + *pnum + s->tracks - 1) / s->tracks - idx;
     space = to_allocate * s->tracks;
     if (s->data_end + space > bdrv_getlength(bs->file->bs) >> BDRV_SECTOR_BITS) {
         int ret;
         space += s->prealloc_size;
         if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) {
-            ret = bdrv_pwrite_zeroes(bs->file,
-                                     s->data_end << BDRV_SECTOR_BITS,
-                                     space << BDRV_SECTOR_BITS, 0);
+            ret = bdrv_write_zeroes(bs->file->bs, s->data_end, space, 0);
         } else {
             ret = bdrv_truncate(bs->file->bs,
                                 (s->data_end + space) << BDRV_SECTOR_BITS);
@@ -251,7 +247,7 @@ static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs)
         if (off + to_write > s->header_size) {
             to_write = s->header_size - off;
         }
-        ret = bdrv_pwrite(bs->file, off, (uint8_t *)s->header + off,
+        ret = bdrv_pwrite(bs->file->bs, off, (uint8_t *)s->header + off,
                           to_write);
         if (ret < 0) {
             qemu_co_mutex_unlock(&s->lock);
@@ -312,7 +308,7 @@ static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
         qemu_iovec_reset(&hd_qiov);
         qemu_iovec_concat(&hd_qiov, qiov, bytes_done, nbytes);
 
-        ret = bdrv_co_writev(bs->file, position, n, &hd_qiov);
+        ret = bdrv_co_writev(bs->file->bs, position, n, &hd_qiov);
         if (ret < 0) {
             break;
         }
@@ -352,7 +348,7 @@ static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
             qemu_iovec_reset(&hd_qiov);
             qemu_iovec_concat(&hd_qiov, qiov, bytes_done, nbytes);
 
-            ret = bdrv_co_readv(bs->file, position, n, &hd_qiov);
+            ret = bdrv_co_readv(bs->file->bs, position, n, &hd_qiov);
             if (ret < 0) {
                 break;
             }
@@ -433,7 +429,7 @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
     }
 
     if (flush_bat) {
-        ret = bdrv_pwrite_sync(bs->file, 0, s->header, s->header_size);
+        ret = bdrv_pwrite_sync(bs->file->bs, 0, s->header, s->header_size);
         if (ret < 0) {
             res->check_errors++;
             return ret;
@@ -476,10 +472,6 @@ static int parallels_create(const char *filename, QemuOpts *opts, Error **errp)
                           BDRV_SECTOR_SIZE);
     cl_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
                           DEFAULT_CLUSTER_SIZE), BDRV_SECTOR_SIZE);
-    if (total_size >= MAX_PARALLELS_IMAGE_FACTOR * cl_size) {
-        error_propagate(errp, local_err);
-        return -E2BIG;
-    }
 
     ret = bdrv_create_file(filename, opts, &local_err);
     if (ret < 0) {
@@ -520,12 +512,11 @@ static int parallels_create(const char *filename, QemuOpts *opts, Error **errp)
     memset(tmp, 0, sizeof(tmp));
     memcpy(tmp, &header, sizeof(header));
 
-    ret = blk_pwrite(file, 0, tmp, BDRV_SECTOR_SIZE, 0);
+    ret = blk_pwrite(file, 0, tmp, BDRV_SECTOR_SIZE);
     if (ret < 0) {
         goto exit;
     }
-    ret = blk_pwrite_zeroes(file, BDRV_SECTOR_SIZE,
-                            (bat_sectors - 1) << BDRV_SECTOR_BITS, 0);
+    ret = blk_write_zeroes(file, 1, bat_sectors - 1, 0);
     if (ret < 0) {
         goto exit;
     }
@@ -568,7 +559,7 @@ static int parallels_update_header(BlockDriverState *bs)
     if (size > s->header_size) {
         size = s->header_size;
     }
-    return bdrv_pwrite_sync(bs->file, 0, s->header, size);
+    return bdrv_pwrite_sync(bs->file->bs, 0, s->header, size);
 }
 
 static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
@@ -581,7 +572,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
     Error *local_err = NULL;
     char *buf;
 
-    ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
+    ret = bdrv_pread(bs->file->bs, 0, &ph, sizeof(ph));
     if (ret < 0) {
         goto fail;
     }
@@ -636,7 +627,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
         s->header_size = size;
     }
 
-    ret = bdrv_pread(bs->file, 0, s->header, s->header_size);
+    ret = bdrv_pread(bs->file->bs, 0, s->header, s->header_size);
     if (ret < 0) {
         goto fail;
     }
index 6f947e3..c5f6ba6 100644 (file)
@@ -67,10 +67,10 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
     info->backing_file_depth = bdrv_get_backing_file_depth(bs);
     info->detect_zeroes = bs->detect_zeroes;
 
-    if (blk && blk_get_public(blk)->throttle_state) {
+    if (bs->throttle_state) {
         ThrottleConfig cfg;
 
-        throttle_group_get_config(blk, &cfg);
+        throttle_group_get_config(bs, &cfg);
 
         info->bps     = cfg.buckets[THROTTLE_BPS_TOTAL].avg;
         info->bps_rd  = cfg.buckets[THROTTLE_BPS_READ].avg;
@@ -118,7 +118,7 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
         info->iops_size = cfg.op_size;
 
         info->has_group = true;
-        info->group = g_strdup(throttle_group_get_name(blk));
+        info->group = g_strdup(throttle_group_get_name(bs));
     }
 
     info->write_threshold = bdrv_write_threshold_get(bs);
@@ -690,15 +690,16 @@ static void dump_qdict(fprintf_function func_fprintf, void *f, int indentation,
 void bdrv_image_info_specific_dump(fprintf_function func_fprintf, void *f,
                                    ImageInfoSpecific *info_spec)
 {
+    QmpOutputVisitor *ov = qmp_output_visitor_new();
     QObject *obj, *data;
-    Visitor *v = qmp_output_visitor_new(&obj);
 
-    visit_type_ImageInfoSpecific(v, NULL, &info_spec, &error_abort);
-    visit_complete(v, &obj);
+    visit_type_ImageInfoSpecific(qmp_output_get_visitor(ov), NULL, &info_spec,
+                                 &error_abort);
+    obj = qmp_output_get_qobject(ov);
     assert(qobject_type(obj) == QTYPE_QDICT);
     data = qdict_get(qobject_to_qdict(obj), "data");
     dump_qobject(func_fprintf, f, 1, data);
-    visit_free(v);
+    qmp_output_visitor_cleanup(ov);
 }
 
 void bdrv_image_info_dump(fprintf_function func_fprintf, void *f,
index 6f9b2e2..60ddb12 100644 (file)
@@ -28,7 +28,6 @@
 #include "block/block_int.h"
 #include "sysemu/block-backend.h"
 #include "qemu/module.h"
-#include "qemu/bswap.h"
 #include <zlib.h>
 #include "qapi/qmp/qerror.h"
 #include "crypto/cipher.h"
@@ -105,7 +104,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
     int ret;
     QCowHeader header;
 
-    ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
+    ret = bdrv_pread(bs->file->bs, 0, &header, sizeof(header));
     if (ret < 0) {
         goto fail;
     }
@@ -162,19 +161,13 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
     if (s->crypt_method_header) {
         if (bdrv_uses_whitelist() &&
             s->crypt_method_header == QCOW_CRYPT_AES) {
-            error_setg(errp,
-                       "Use of AES-CBC encrypted qcow images is no longer "
-                       "supported in system emulators");
-            error_append_hint(errp,
-                              "You can use 'qemu-img convert' to convert your "
-                              "image to an alternative supported format, such "
-                              "as unencrypted qcow, or raw with the LUKS "
-                              "format instead.\n");
-            ret = -ENOSYS;
-            goto fail;
+            error_report("qcow built-in AES encryption is deprecated");
+            error_printf("Support for it will be removed in a future release.\n"
+                         "You can use 'qemu-img convert' to switch to an\n"
+                         "unencrypted qcow image, or a LUKS raw image.\n");
         }
 
-        bs->encrypted = true;
+        bs->encrypted = 1;
     }
     s->cluster_bits = header.cluster_bits;
     s->cluster_size = 1 << s->cluster_bits;
@@ -208,7 +201,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
         goto fail;
     }
 
-    ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table,
+    ret = bdrv_pread(bs->file->bs, s->l1_table_offset, s->l1_table,
                s->l1_size * sizeof(uint64_t));
     if (ret < 0) {
         goto fail;
@@ -239,7 +232,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
             ret = -EINVAL;
             goto fail;
         }
-        ret = bdrv_pread(bs->file, header.backing_file_offset,
+        ret = bdrv_pread(bs->file->bs, header.backing_file_offset,
                    bs->backing_file, len);
         if (ret < 0) {
             goto fail;
@@ -390,7 +383,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
         /* update the L1 entry */
         s->l1_table[l1_index] = l2_offset;
         tmp = cpu_to_be64(l2_offset);
-        if (bdrv_pwrite_sync(bs->file,
+        if (bdrv_pwrite_sync(bs->file->bs,
                 s->l1_table_offset + l1_index * sizeof(tmp),
                 &tmp, sizeof(tmp)) < 0)
             return 0;
@@ -420,11 +413,11 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
     l2_table = s->l2_cache + (min_index << s->l2_bits);
     if (new_l2_table) {
         memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
-        if (bdrv_pwrite_sync(bs->file, l2_offset, l2_table,
+        if (bdrv_pwrite_sync(bs->file->bs, l2_offset, l2_table,
                 s->l2_size * sizeof(uint64_t)) < 0)
             return 0;
     } else {
-        if (bdrv_pread(bs->file, l2_offset, l2_table,
+        if (bdrv_pread(bs->file->bs, l2_offset, l2_table,
                        s->l2_size * sizeof(uint64_t)) !=
             s->l2_size * sizeof(uint64_t))
             return 0;
@@ -450,7 +443,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
             cluster_offset = (cluster_offset + s->cluster_size - 1) &
                 ~(s->cluster_size - 1);
             /* write the cluster content */
-            if (bdrv_pwrite(bs->file, cluster_offset, s->cluster_cache,
+            if (bdrv_pwrite(bs->file->bs, cluster_offset, s->cluster_cache,
                             s->cluster_size) !=
                 s->cluster_size)
                 return -1;
@@ -480,7 +473,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
                                 errno = EIO;
                                 return -1;
                             }
-                            if (bdrv_pwrite(bs->file,
+                            if (bdrv_pwrite(bs->file->bs,
                                             cluster_offset + i * 512,
                                             s->cluster_data, 512) != 512)
                                 return -1;
@@ -495,7 +488,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
         /* update L2 table */
         tmp = cpu_to_be64(cluster_offset);
         l2_table[l2_index] = tmp;
-        if (bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp),
+        if (bdrv_pwrite_sync(bs->file->bs, l2_offset + l2_index * sizeof(tmp),
                 &tmp, sizeof(tmp)) < 0)
             return 0;
     }
@@ -565,7 +558,7 @@ static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
     if (s->cluster_cache_offset != coffset) {
         csize = cluster_offset >> (63 - s->cluster_bits);
         csize &= (s->cluster_size - 1);
-        ret = bdrv_pread(bs->file, coffset, s->cluster_data, csize);
+        ret = bdrv_pread(bs->file->bs, coffset, s->cluster_data, csize);
         if (ret != csize)
             return -1;
         if (decompress_buffer(s->cluster_cache, s->cluster_size,
@@ -619,7 +612,8 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
                 hd_iov.iov_len = n * 512;
                 qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
                 qemu_co_mutex_unlock(&s->lock);
-                ret = bdrv_co_readv(bs->backing, sector_num, n, &hd_qiov);
+                ret = bdrv_co_readv(bs->backing->bs, sector_num,
+                                    n, &hd_qiov);
                 qemu_co_mutex_lock(&s->lock);
                 if (ret < 0) {
                     goto fail;
@@ -643,7 +637,7 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
             hd_iov.iov_len = n * 512;
             qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
             qemu_co_mutex_unlock(&s->lock);
-            ret = bdrv_co_readv(bs->file,
+            ret = bdrv_co_readv(bs->file->bs,
                                 (cluster_offset >> 9) + index_in_cluster,
                                 n, &hd_qiov);
             qemu_co_mutex_lock(&s->lock);
@@ -745,7 +739,7 @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
         hd_iov.iov_len = n * 512;
         qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
         qemu_co_mutex_unlock(&s->lock);
-        ret = bdrv_co_writev(bs->file,
+        ret = bdrv_co_writev(bs->file->bs,
                              (cluster_offset >> 9) + index_in_cluster,
                              n, &hd_qiov);
         qemu_co_mutex_lock(&s->lock);
@@ -859,24 +853,24 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
     }
 
     /* write all the data */
-    ret = blk_pwrite(qcow_blk, 0, &header, sizeof(header), 0);
+    ret = blk_pwrite(qcow_blk, 0, &header, sizeof(header));
     if (ret != sizeof(header)) {
         goto exit;
     }
 
     if (backing_file) {
         ret = blk_pwrite(qcow_blk, sizeof(header),
-                         backing_file, backing_filename_len, 0);
+            backing_file, backing_filename_len);
         if (ret != backing_filename_len) {
             goto exit;
         }
     }
 
     tmp = g_malloc0(BDRV_SECTOR_SIZE);
-    for (i = 0; i < DIV_ROUND_UP(sizeof(uint64_t) * l1_size, BDRV_SECTOR_SIZE);
-         i++) {
-        ret = blk_pwrite(qcow_blk, header_size + BDRV_SECTOR_SIZE * i,
-                         tmp, BDRV_SECTOR_SIZE, 0);
+    for (i = 0; i < ((sizeof(uint64_t)*l1_size + BDRV_SECTOR_SIZE - 1)/
+        BDRV_SECTOR_SIZE); i++) {
+        ret = blk_pwrite(qcow_blk, header_size +
+            BDRV_SECTOR_SIZE*i, tmp, BDRV_SECTOR_SIZE);
         if (ret != BDRV_SECTOR_SIZE) {
             g_free(tmp);
             goto exit;
@@ -899,7 +893,7 @@ static int qcow_make_empty(BlockDriverState *bs)
     int ret;
 
     memset(s->l1_table, 0, l1_length);
-    if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table,
+    if (bdrv_pwrite_sync(bs->file->bs, s->l1_table_offset, s->l1_table,
             l1_length) < 0)
         return -1;
     ret = bdrv_truncate(bs->file->bs, s->l1_table_offset + l1_length);
@@ -913,49 +907,6 @@ static int qcow_make_empty(BlockDriverState *bs)
     return 0;
 }
 
-typedef struct QcowWriteCo {
-    BlockDriverState *bs;
-    int64_t sector_num;
-    const uint8_t *buf;
-    int nb_sectors;
-    int ret;
-} QcowWriteCo;
-
-static void qcow_write_co_entry(void *opaque)
-{
-    QcowWriteCo *co = opaque;
-    QEMUIOVector qiov;
-
-    struct iovec iov = (struct iovec) {
-        .iov_base   = (uint8_t*) co->buf,
-        .iov_len    = co->nb_sectors * BDRV_SECTOR_SIZE,
-    };
-    qemu_iovec_init_external(&qiov, &iov, 1);
-
-    co->ret = qcow_co_writev(co->bs, co->sector_num, co->nb_sectors, &qiov);
-}
-
-/* Wrapper for non-coroutine contexts */
-static int qcow_write(BlockDriverState *bs, int64_t sector_num,
-                      const uint8_t *buf, int nb_sectors)
-{
-    Coroutine *co;
-    AioContext *aio_context = bdrv_get_aio_context(bs);
-    QcowWriteCo data = {
-        .bs         = bs,
-        .sector_num = sector_num,
-        .buf        = buf,
-        .nb_sectors = nb_sectors,
-        .ret        = -EINPROGRESS,
-    };
-    co = qemu_coroutine_create(qcow_write_co_entry, &data);
-    qemu_coroutine_enter(co);
-    while (data.ret == -EINPROGRESS) {
-        aio_poll(aio_context, true);
-    }
-    return data.ret;
-}
-
 /* XXX: put compressed sectors first, then all the cluster aligned
    tables to avoid losing bytes in alignment */
 static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
@@ -983,7 +934,7 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
         return ret;
     }
 
-    out_buf = g_malloc(s->cluster_size);
+    out_buf = g_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
 
     /* best compression, small window, no zlib header */
     memset(&strm, 0, sizeof(strm));
@@ -1012,7 +963,7 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
 
     if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
         /* could not compress: write normal cluster */
-        ret = qcow_write(bs, sector_num, buf, s->cluster_sectors);
+        ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors);
         if (ret < 0) {
             goto fail;
         }
@@ -1025,7 +976,7 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
         }
 
         cluster_offset &= s->cluster_offset_mask;
-        ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len);
+        ret = bdrv_pwrite(bs->file->bs, cluster_offset, out_buf, out_len);
         if (ret < 0) {
             goto fail;
         }
index 6eaefed..0fe8eda 100644 (file)
 
 /* Needed for CONFIG_MADVISE */
 #include "qemu/osdep.h"
+
+#if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE)
+#include <sys/mman.h>
+#endif
+
 #include "block/block_int.h"
 #include "qemu-common.h"
 #include "qcow2.h"
@@ -210,7 +215,7 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
         BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
     }
 
-    ret = bdrv_pwrite(bs->file, c->entries[i].offset,
+    ret = bdrv_pwrite(bs->file->bs, c->entries[i].offset,
                       qcow2_cache_get_table_addr(bs, c, i), s->cluster_size);
     if (ret < 0) {
         return ret;
@@ -221,7 +226,7 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
     return 0;
 }
 
-int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c)
+int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c)
 {
     BDRVQcow2State *s = bs->opaque;
     int result = 0;
@@ -237,15 +242,8 @@ int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c)
         }
     }
 
-    return result;
-}
-
-int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c)
-{
-    int result = qcow2_cache_write(bs, c);
-
     if (result == 0) {
-        int ret = bdrv_flush(bs->file->bs);
+        ret = bdrv_flush(bs->file->bs);
         if (ret < 0) {
             result = ret;
         }
@@ -357,7 +355,7 @@ static int qcow2_cache_do_get(BlockDriverState *bs, Qcow2Cache *c,
             BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD);
         }
 
-        ret = bdrv_pread(bs->file, offset,
+        ret = bdrv_pread(bs->file->bs, offset,
                          qcow2_cache_get_table_addr(bs, c, i),
                          s->cluster_size);
         if (ret < 0) {
index f941835..22bdb47 100644 (file)
@@ -29,7 +29,6 @@
 #include "qemu-common.h"
 #include "block/block_int.h"
 #include "block/qcow2.h"
-#include "qemu/bswap.h"
 #include "trace.h"
 
 int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
@@ -109,7 +108,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
     BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
     for(i = 0; i < s->l1_size; i++)
         new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
-    ret = bdrv_pwrite_sync(bs->file, new_l1_table_offset,
+    ret = bdrv_pwrite_sync(bs->file->bs, new_l1_table_offset,
                            new_l1_table, new_l1_size2);
     if (ret < 0)
         goto fail;
@@ -118,9 +117,9 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
 
     /* set new table */
     BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE);
-    stl_be_p(data, new_l1_size);
+    cpu_to_be32w((uint32_t*)data, new_l1_size);
     stq_be_p(data + 4, new_l1_table_offset);
-    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size),
+    ret = bdrv_pwrite_sync(bs->file->bs, offsetof(QCowHeader, l1_size),
                            data, sizeof(data));
     if (ret < 0) {
         goto fail;
@@ -155,9 +154,11 @@ static int l2_load(BlockDriverState *bs, uint64_t l2_offset,
     uint64_t **l2_table)
 {
     BDRVQcow2State *s = bs->opaque;
+    int ret;
+
+    ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset, (void**) l2_table);
 
-    return qcow2_cache_get(bs, s->l2_table_cache, l2_offset,
-                           (void **)l2_table);
+    return ret;
 }
 
 /*
@@ -186,7 +187,7 @@ int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
     }
 
     BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
-    ret = bdrv_pwrite_sync(bs->file,
+    ret = bdrv_pwrite_sync(bs->file->bs,
                            s->l1_table_offset + 8 * l1_start_index,
                            buf, sizeof(buf));
     if (ret < 0) {
@@ -389,18 +390,22 @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
     return 0;
 }
 
-static int coroutine_fn do_perform_cow(BlockDriverState *bs,
-                                       uint64_t src_cluster_offset,
-                                       uint64_t cluster_offset,
-                                       int offset_in_cluster,
-                                       int bytes)
+static int coroutine_fn copy_sectors(BlockDriverState *bs,
+                                     uint64_t start_sect,
+                                     uint64_t cluster_offset,
+                                     int n_start, int n_end)
 {
     BDRVQcow2State *s = bs->opaque;
     QEMUIOVector qiov;
     struct iovec iov;
-    int ret;
+    int n, ret;
 
-    iov.iov_len = bytes;
+    n = n_end - n_start;
+    if (n <= 0) {
+        return 0;
+    }
+
+    iov.iov_len = n * BDRV_SECTOR_SIZE;
     iov.iov_base = qemu_try_blockalign(bs, iov.iov_len);
     if (iov.iov_base == NULL) {
         return -ENOMEM;
@@ -419,21 +424,17 @@ static int coroutine_fn do_perform_cow(BlockDriverState *bs,
      * interface.  This avoids double I/O throttling and request tracking,
      * which can lead to deadlock when block layer copy-on-read is enabled.
      */
-    ret = bs->drv->bdrv_co_preadv(bs, src_cluster_offset + offset_in_cluster,
-                                  bytes, &qiov, 0);
+    ret = bs->drv->bdrv_co_readv(bs, start_sect + n_start, n, &qiov);
     if (ret < 0) {
         goto out;
     }
 
     if (bs->encrypted) {
         Error *err = NULL;
-        int64_t sector = (cluster_offset + offset_in_cluster)
-                         >> BDRV_SECTOR_BITS;
         assert(s->cipher);
-        assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
-        assert((bytes & ~BDRV_SECTOR_MASK) == 0);
-        if (qcow2_encrypt_sectors(s, sector, iov.iov_base, iov.iov_base,
-                                  bytes >> BDRV_SECTOR_BITS, true, &err) < 0) {
+        if (qcow2_encrypt_sectors(s, start_sect + n_start,
+                                  iov.iov_base, iov.iov_base, n,
+                                  true, &err) < 0) {
             ret = -EIO;
             error_free(err);
             goto out;
@@ -441,14 +442,14 @@ static int coroutine_fn do_perform_cow(BlockDriverState *bs,
     }
 
     ret = qcow2_pre_write_overlap_check(bs, 0,
-            cluster_offset + offset_in_cluster, bytes);
+            cluster_offset + n_start * BDRV_SECTOR_SIZE, n * BDRV_SECTOR_SIZE);
     if (ret < 0) {
         goto out;
     }
 
     BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
-    ret = bdrv_co_pwritev(bs->file, cluster_offset + offset_in_cluster,
-                          bytes, &qiov, 0);
+    ret = bdrv_co_writev(bs->file->bs, (cluster_offset >> 9) + n_start, n,
+                         &qiov);
     if (ret < 0) {
         goto out;
     }
@@ -463,43 +464,47 @@ out:
 /*
  * get_cluster_offset
  *
- * For a given offset of the virtual disk, find the cluster type and offset in
- * the qcow2 file. The offset is stored in *cluster_offset.
+ * For a given offset of the disk image, find the cluster offset in
+ * qcow2 file. The offset is stored in *cluster_offset.
  *
- * On entry, *bytes is the maximum number of contiguous bytes starting at
- * offset that we are interested in.
+ * on entry, *num is the number of contiguous sectors we'd like to
+ * access following offset.
  *
- * On exit, *bytes is the number of bytes starting at offset that have the same
- * cluster type and (if applicable) are stored contiguously in the image file.
- * Compressed clusters are always returned one by one.
+ * on exit, *num is the number of contiguous sectors we can read.
  *
  * Returns the cluster type (QCOW2_CLUSTER_*) on success, -errno in error
  * cases.
  */
 int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
-                             unsigned int *bytes, uint64_t *cluster_offset)
+    int *num, uint64_t *cluster_offset)
 {
     BDRVQcow2State *s = bs->opaque;
     unsigned int l2_index;
     uint64_t l1_index, l2_offset, *l2_table;
     int l1_bits, c;
-    unsigned int offset_in_cluster;
-    uint64_t bytes_available, bytes_needed, nb_clusters;
+    unsigned int index_in_cluster, nb_clusters;
+    uint64_t nb_available, nb_needed;
     int ret;
 
-    offset_in_cluster = offset_into_cluster(s, offset);
-    bytes_needed = (uint64_t) *bytes + offset_in_cluster;
+    index_in_cluster = (offset >> 9) & (s->cluster_sectors - 1);
+    nb_needed = *num + index_in_cluster;
 
     l1_bits = s->l2_bits + s->cluster_bits;
 
-    /* compute how many bytes there are between the start of the cluster
-     * containing offset and the end of the l1 entry */
-    bytes_available = (1ULL << l1_bits) - (offset & ((1ULL << l1_bits) - 1))
-                    + offset_in_cluster;
+    /* compute how many bytes there are between the offset and
+     * the end of the l1 entry
+     */
+
+    nb_available = (1ULL << l1_bits) - (offset & ((1ULL << l1_bits) - 1));
+
+    /* compute the number of available sectors */
 
-    if (bytes_needed > bytes_available) {
-        bytes_needed = bytes_available;
+    nb_available = (nb_available >> 9) + index_in_cluster;
+
+    if (nb_needed > nb_available) {
+        nb_needed = nb_available;
     }
+    assert(nb_needed <= INT_MAX);
 
     *cluster_offset = 0;
 
@@ -536,11 +541,8 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
     l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
     *cluster_offset = be64_to_cpu(l2_table[l2_index]);
 
-    nb_clusters = size_to_clusters(s, bytes_needed);
-    /* bytes_needed <= *bytes + offset_in_cluster, both of which are unsigned
-     * integers; the minimum cluster size is 512, so this assertion is always
-     * true */
-    assert(nb_clusters <= INT_MAX);
+    /* nb_needed <= INT_MAX, thus nb_clusters <= INT_MAX, too */
+    nb_clusters = size_to_clusters(s, nb_needed << 9);
 
     ret = qcow2_get_cluster_type(*cluster_offset);
     switch (ret) {
@@ -587,18 +589,13 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
 
     qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
 
-    bytes_available = (int64_t)c * s->cluster_size;
+    nb_available = (c * s->cluster_sectors);
 
 out:
-    if (bytes_available > bytes_needed) {
-        bytes_available = bytes_needed;
-    }
+    if (nb_available > nb_needed)
+        nb_available = nb_needed;
 
-    /* bytes_available <= bytes_needed <= *bytes + offset_in_cluster;
-     * subtracting offset_in_cluster will therefore definitely yield something
-     * not exceeding UINT_MAX */
-    assert(bytes_available - offset_in_cluster <= UINT_MAX);
-    *bytes = bytes_available - offset_in_cluster;
+    *num = nb_available - index_in_cluster;
 
     return ret;
 
@@ -744,12 +741,14 @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m, Qcow2COWRegion *r)
     BDRVQcow2State *s = bs->opaque;
     int ret;
 
-    if (r->nb_bytes == 0) {
+    if (r->nb_sectors == 0) {
         return 0;
     }
 
     qemu_co_mutex_unlock(&s->lock);
-    ret = do_perform_cow(bs, m->offset, m->alloc_offset, r->offset, r->nb_bytes);
+    ret = copy_sectors(bs, m->offset / BDRV_SECTOR_SIZE, m->alloc_offset,
+                       r->offset / BDRV_SECTOR_SIZE,
+                       r->offset / BDRV_SECTOR_SIZE + r->nb_sectors);
     qemu_co_mutex_lock(&s->lock);
 
     if (ret < 0) {
@@ -811,14 +810,13 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
     assert(l2_index + m->nb_clusters <= s->l2_size);
     for (i = 0; i < m->nb_clusters; i++) {
         /* if two concurrent writes happen to the same unallocated cluster
-         * each write allocates separate cluster and writes data concurrently.
-         * The first one to complete updates l2 table with pointer to its
-         * cluster the second one has to do RMW (which is done above by
-         * perform_cow()), update l2 table with its cluster pointer and free
-         * old cluster. This is what this loop does */
-        if (l2_table[l2_index + i] != 0) {
+        * each write allocates separate cluster and writes data concurrently.
+        * The first one to complete updates l2 table with pointer to its
+        * cluster the second one has to do RMW (which is done above by
+        * copy_sectors()), update l2 table with its cluster pointer and free
+        * old cluster. This is what this loop does */
+        if(l2_table[l2_index + i] != 0)
             old_cluster[j++] = l2_table[l2_index + i];
-        }
 
         l2_table[l2_index + i] = cpu_to_be64((cluster_offset +
                     (i << s->cluster_bits)) | QCOW_OFLAG_COPIED);
@@ -1200,20 +1198,25 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
     /*
      * Save info needed for meta data update.
      *
-     * requested_bytes: Number of bytes from the start of the first
+     * requested_sectors: Number of sectors from the start of the first
      * newly allocated cluster to the end of the (possibly shortened
      * before) write request.
      *
-     * avail_bytes: Number of bytes from the start of the first
+     * avail_sectors: Number of sectors from the start of the first
      * newly allocated to the end of the last newly allocated cluster.
      *
-     * nb_bytes: The number of bytes from the start of the first
+     * nb_sectors: The number of sectors from the start of the first
      * newly allocated cluster to the end of the area that the write
      * request actually writes to (excluding COW at the end)
      */
-    uint64_t requested_bytes = *bytes + offset_into_cluster(s, guest_offset);
-    int avail_bytes = MIN(INT_MAX, nb_clusters << s->cluster_bits);
-    int nb_bytes = MIN(requested_bytes, avail_bytes);
+    int requested_sectors =
+        (*bytes + offset_into_cluster(s, guest_offset))
+        >> BDRV_SECTOR_BITS;
+    int avail_sectors = nb_clusters
+                        << (s->cluster_bits - BDRV_SECTOR_BITS);
+    int alloc_n_start = offset_into_cluster(s, guest_offset)
+                        >> BDRV_SECTOR_BITS;
+    int nb_sectors = MIN(requested_sectors, avail_sectors);
     QCowL2Meta *old_m = *m;
 
     *m = g_malloc0(sizeof(**m));
@@ -1224,21 +1227,23 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
         .alloc_offset   = alloc_cluster_offset,
         .offset         = start_of_cluster(s, guest_offset),
         .nb_clusters    = nb_clusters,
+        .nb_available   = nb_sectors,
 
         .cow_start = {
             .offset     = 0,
-            .nb_bytes   = offset_into_cluster(s, guest_offset),
+            .nb_sectors = alloc_n_start,
         },
         .cow_end = {
-            .offset     = nb_bytes,
-            .nb_bytes   = avail_bytes - nb_bytes,
+            .offset     = nb_sectors * BDRV_SECTOR_SIZE,
+            .nb_sectors = avail_sectors - nb_sectors,
         },
     };
     qemu_co_queue_init(&(*m)->dependent_requests);
     QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight);
 
     *host_offset = alloc_cluster_offset + offset_into_cluster(s, guest_offset);
-    *bytes = MIN(*bytes, nb_bytes - offset_into_cluster(s, guest_offset));
+    *bytes = MIN(*bytes, (nb_sectors * BDRV_SECTOR_SIZE)
+                         - offset_into_cluster(s, guest_offset));
     assert(*bytes != 0);
 
     return 1;
@@ -1270,8 +1275,7 @@ fail:
  * Return 0 on success and -errno in error cases
  */
 int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
-                               unsigned int *bytes, uint64_t *host_offset,
-                               QCowL2Meta **m)
+    int *num, uint64_t *host_offset, QCowL2Meta **m)
 {
     BDRVQcow2State *s = bs->opaque;
     uint64_t start, remaining;
@@ -1279,11 +1283,13 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
     uint64_t cur_bytes;
     int ret;
 
-    trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset, *bytes);
+    trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset, *num);
+
+    assert((offset & ~BDRV_SECTOR_MASK) == 0);
 
 again:
     start = offset;
-    remaining = *bytes;
+    remaining = (uint64_t)*num << BDRV_SECTOR_BITS;
     cluster_offset = 0;
     *host_offset = 0;
     cur_bytes = 0;
@@ -1369,8 +1375,8 @@ again:
         }
     }
 
-    *bytes -= remaining;
-    assert(*bytes > 0);
+    *num -= remaining >> BDRV_SECTOR_BITS;
+    assert(*num > 0);
     assert(*host_offset != 0);
 
     return 0;
@@ -1415,7 +1421,7 @@ int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
         sector_offset = coffset & 511;
         csize = nb_csectors * 512 - sector_offset;
         BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
-        ret = bdrv_read(bs->file, coffset >> 9, s->cluster_data,
+        ret = bdrv_read(bs->file->bs, coffset >> 9, s->cluster_data,
                         nb_csectors);
         if (ret < 0) {
             return ret;
@@ -1684,7 +1690,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
                     (void **)&l2_table);
         } else {
             /* load inactive L2 tables from disk */
-            ret = bdrv_read(bs->file, l2_offset / BDRV_SECTOR_SIZE,
+            ret = bdrv_read(bs->file->bs, l2_offset / BDRV_SECTOR_SIZE,
                             (void *)l2_table, s->cluster_sectors);
         }
         if (ret < 0) {
@@ -1759,7 +1765,8 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
                 goto fail;
             }
 
-            ret = bdrv_pwrite_zeroes(bs->file, offset, s->cluster_size, 0);
+            ret = bdrv_write_zeroes(bs->file->bs, offset / BDRV_SECTOR_SIZE,
+                                    s->cluster_sectors, 0);
             if (ret < 0) {
                 if (!preallocated) {
                     qcow2_free_clusters(bs, offset, s->cluster_size,
@@ -1791,7 +1798,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
                     goto fail;
                 }
 
-                ret = bdrv_write(bs->file, l2_offset / BDRV_SECTOR_SIZE,
+                ret = bdrv_write(bs->file->bs, l2_offset / BDRV_SECTOR_SIZE,
                                  (void *)l2_table, s->cluster_sectors);
                 if (ret < 0) {
                     goto fail;
@@ -1861,12 +1868,12 @@ int qcow2_expand_zero_clusters(BlockDriverState *bs,
     }
 
     for (i = 0; i < s->nb_snapshots; i++) {
-        int l1_sectors = DIV_ROUND_UP(s->snapshots[i].l1_size *
-                                      sizeof(uint64_t), BDRV_SECTOR_SIZE);
+        int l1_sectors = (s->snapshots[i].l1_size * sizeof(uint64_t) +
+                BDRV_SECTOR_SIZE - 1) / BDRV_SECTOR_SIZE;
 
         l1_table = g_realloc(l1_table, l1_sectors * BDRV_SECTOR_SIZE);
 
-        ret = bdrv_read(bs->file,
+        ret = bdrv_read(bs->file->bs,
                         s->snapshots[i].l1_table_offset / BDRV_SECTOR_SIZE,
                         (void *)l1_table, l1_sectors);
         if (ret < 0) {
index cbfb3fe..ca6094f 100644 (file)
@@ -28,7 +28,6 @@
 #include "block/block_int.h"
 #include "block/qcow2.h"
 #include "qemu/range.h"
-#include "qemu/bswap.h"
 
 static int64_t alloc_clusters_noref(BlockDriverState *bs, uint64_t size);
 static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
@@ -104,7 +103,7 @@ int qcow2_refcount_init(BlockDriverState *bs)
             goto fail;
         }
         BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_LOAD);
-        ret = bdrv_pread(bs->file, s->refcount_table_offset,
+        ret = bdrv_pread(bs->file->bs, s->refcount_table_offset,
                          s->refcount_table, refcount_table_size2);
         if (ret < 0) {
             goto fail;
@@ -218,10 +217,13 @@ static int load_refcount_block(BlockDriverState *bs,
                                void **refcount_block)
 {
     BDRVQcow2State *s = bs->opaque;
+    int ret;
 
     BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_LOAD);
-    return qcow2_cache_get(bs, s->refcount_block_cache, refcount_block_offset,
-                           refcount_block);
+    ret = qcow2_cache_get(bs, s->refcount_block_cache, refcount_block_offset,
+        refcount_block);
+
+    return ret;
 }
 
 /*
@@ -431,7 +433,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
     if (refcount_table_index < s->refcount_table_size) {
         uint64_t data64 = cpu_to_be64(new_block);
         BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP);
-        ret = bdrv_pwrite_sync(bs->file,
+        ret = bdrv_pwrite_sync(bs->file->bs,
             s->refcount_table_offset + refcount_table_index * sizeof(uint64_t),
             &data64, sizeof(data64));
         if (ret < 0) {
@@ -487,12 +489,14 @@ static int alloc_refcount_block(BlockDriverState *bs,
         uint64_t table_clusters =
             size_to_clusters(s, table_size * sizeof(uint64_t));
         blocks_clusters = 1 +
-            DIV_ROUND_UP(table_clusters, s->refcount_block_size);
+            ((table_clusters + s->refcount_block_size - 1)
+            / s->refcount_block_size);
         uint64_t meta_clusters = table_clusters + blocks_clusters;
 
         last_table_size = table_size;
         table_size = next_refcount_table_size(s, blocks_used +
-            DIV_ROUND_UP(meta_clusters, s->refcount_block_size));
+            ((meta_clusters + s->refcount_block_size - 1)
+            / s->refcount_block_size));
 
     } while (last_table_size != table_size);
 
@@ -533,7 +537,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
 
     /* Write refcount blocks to disk */
     BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS);
-    ret = bdrv_pwrite_sync(bs->file, meta_offset, new_blocks,
+    ret = bdrv_pwrite_sync(bs->file->bs, meta_offset, new_blocks,
         blocks_clusters * s->cluster_size);
     g_free(new_blocks);
     new_blocks = NULL;
@@ -547,7 +551,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
     }
 
     BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE);
-    ret = bdrv_pwrite_sync(bs->file, table_offset, new_table,
+    ret = bdrv_pwrite_sync(bs->file->bs, table_offset, new_table,
         table_size * sizeof(uint64_t));
     if (ret < 0) {
         goto fail_table;
@@ -562,10 +566,10 @@ static int alloc_refcount_block(BlockDriverState *bs,
         uint64_t d64;
         uint32_t d32;
     } data;
-    data.d64 = cpu_to_be64(table_offset);
-    data.d32 = cpu_to_be32(table_clusters);
+    cpu_to_be64w(&data.d64, table_offset);
+    cpu_to_be32w(&data.d32, table_clusters);
     BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE);
-    ret = bdrv_pwrite_sync(bs->file,
+    ret = bdrv_pwrite_sync(bs->file->bs,
                            offsetof(QCowHeader, refcount_table_offset),
                            &data, sizeof(data));
     if (ret < 0) {
@@ -615,7 +619,9 @@ void qcow2_process_discards(BlockDriverState *bs, int ret)
 
         /* Discard is optional, ignore the return value */
         if (ret >= 0) {
-            bdrv_pdiscard(bs->file->bs, d->offset, d->bytes);
+            bdrv_discard(bs->file->bs,
+                         d->offset >> BDRV_SECTOR_BITS,
+                         d->bytes >> BDRV_SECTOR_BITS);
         }
 
         g_free(d);
@@ -1068,7 +1074,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
         }
         l1_allocated = true;
 
-        ret = bdrv_pread(bs->file, l1_table_offset, l1_table, l1_size2);
+        ret = bdrv_pread(bs->file->bs, l1_table_offset, l1_table, l1_size2);
         if (ret < 0) {
             goto fail;
         }
@@ -1221,7 +1227,7 @@ fail:
             cpu_to_be64s(&l1_table[i]);
         }
 
-        ret = bdrv_pwrite_sync(bs->file, l1_table_offset,
+        ret = bdrv_pwrite_sync(bs->file->bs, l1_table_offset,
                                l1_table, l1_size2);
 
         for (i = 0; i < l1_size; i++) {
@@ -1380,7 +1386,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
     l2_size = s->l2_size * sizeof(uint64_t);
     l2_table = g_malloc(l2_size);
 
-    ret = bdrv_pread(bs->file, l2_offset, l2_table, l2_size);
+    ret = bdrv_pread(bs->file->bs, l2_offset, l2_table, l2_size);
     if (ret < 0) {
         fprintf(stderr, "ERROR: I/O error in check_refcounts_l2\n");
         res->check_errors++;
@@ -1512,7 +1518,7 @@ static int check_refcounts_l1(BlockDriverState *bs,
             res->check_errors++;
             goto fail;
         }
-        ret = bdrv_pread(bs->file, l1_table_offset, l1_table, l1_size2);
+        ret = bdrv_pread(bs->file->bs, l1_table_offset, l1_table, l1_size2);
         if (ret < 0) {
             fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n");
             res->check_errors++;
@@ -1610,7 +1616,7 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
             }
         }
 
-        ret = bdrv_pread(bs->file, l2_offset, l2_table,
+        ret = bdrv_pread(bs->file->bs, l2_offset, l2_table,
                          s->l2_size * sizeof(uint64_t));
         if (ret < 0) {
             fprintf(stderr, "ERROR: Could not read L2 table: %s\n",
@@ -1662,7 +1668,7 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
                 goto fail;
             }
 
-            ret = bdrv_pwrite(bs->file, l2_offset, l2_table,
+            ret = bdrv_pwrite(bs->file->bs, l2_offset, l2_table,
                               s->cluster_size);
             if (ret < 0) {
                 fprintf(stderr, "ERROR: Could not write L2 table: %s\n",
@@ -2096,7 +2102,7 @@ write_refblocks:
         on_disk_refblock = (void *)((char *) *refcount_table +
                                     refblock_index * s->cluster_size);
 
-        ret = bdrv_write(bs->file, refblock_offset / BDRV_SECTOR_SIZE,
+        ret = bdrv_write(bs->file->bs, refblock_offset / BDRV_SECTOR_SIZE,
                          on_disk_refblock, s->cluster_sectors);
         if (ret < 0) {
             fprintf(stderr, "ERROR writing refblock: %s\n", strerror(-ret));
@@ -2145,7 +2151,7 @@ write_refblocks:
     }
 
     assert(reftable_size < INT_MAX / sizeof(uint64_t));
-    ret = bdrv_pwrite(bs->file, reftable_offset, on_disk_reftable,
+    ret = bdrv_pwrite(bs->file->bs, reftable_offset, on_disk_reftable,
                       reftable_size * sizeof(uint64_t));
     if (ret < 0) {
         fprintf(stderr, "ERROR writing reftable: %s\n", strerror(-ret));
@@ -2153,11 +2159,12 @@ write_refblocks:
     }
 
     /* Enter new reftable into the image header */
-    reftable_offset_and_clusters.reftable_offset = cpu_to_be64(reftable_offset);
-    reftable_offset_and_clusters.reftable_clusters =
-        cpu_to_be32(size_to_clusters(s, reftable_size * sizeof(uint64_t)));
-    ret = bdrv_pwrite_sync(bs->file,
-                           offsetof(QCowHeader, refcount_table_offset),
+    cpu_to_be64w(&reftable_offset_and_clusters.reftable_offset,
+                 reftable_offset);
+    cpu_to_be32w(&reftable_offset_and_clusters.reftable_clusters,
+                 size_to_clusters(s, reftable_size * sizeof(uint64_t)));
+    ret = bdrv_pwrite_sync(bs->file->bs, offsetof(QCowHeader,
+                                                  refcount_table_offset),
                            &reftable_offset_and_clusters,
                            sizeof(reftable_offset_and_clusters));
     if (ret < 0) {
@@ -2404,7 +2411,7 @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
                 return -ENOMEM;
             }
 
-            ret = bdrv_pread(bs->file, l1_ofs, l1, l1_sz2);
+            ret = bdrv_pread(bs->file->bs, l1_ofs, l1, l1_sz2);
             if (ret < 0) {
                 g_free(l1);
                 return ret;
@@ -2557,7 +2564,7 @@ static int flush_refblock(BlockDriverState *bs, uint64_t **reftable,
             return ret;
         }
 
-        ret = bdrv_pwrite(bs->file, offset, refblock, s->cluster_size);
+        ret = bdrv_pwrite(bs->file->bs, offset, refblock, s->cluster_size);
         if (ret < 0) {
             error_setg_errno(errp, -ret, "Failed to write refblock");
             return ret;
@@ -2827,7 +2834,7 @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
         cpu_to_be64s(&new_reftable[i]);
     }
 
-    ret = bdrv_pwrite(bs->file, new_reftable_offset, new_reftable,
+    ret = bdrv_pwrite(bs->file->bs, new_reftable_offset, new_reftable,
                       new_reftable_size * sizeof(uint64_t));
 
     for (i = 0; i < new_reftable_size; i++) {
index 0324243..5f4a17e 100644 (file)
@@ -26,7 +26,6 @@
 #include "qapi/error.h"
 #include "block/block_int.h"
 #include "block/qcow2.h"
-#include "qemu/bswap.h"
 #include "qemu/error-report.h"
 #include "qemu/cutils.h"
 
@@ -67,7 +66,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
     for(i = 0; i < s->nb_snapshots; i++) {
         /* Read statically sized part of the snapshot header */
         offset = align_offset(offset, 8);
-        ret = bdrv_pread(bs->file, offset, &h, sizeof(h));
+        ret = bdrv_pread(bs->file->bs, offset, &h, sizeof(h));
         if (ret < 0) {
             goto fail;
         }
@@ -86,7 +85,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
         name_size = be16_to_cpu(h.name_size);
 
         /* Read extra data */
-        ret = bdrv_pread(bs->file, offset, &extra,
+        ret = bdrv_pread(bs->file->bs, offset, &extra,
                          MIN(sizeof(extra), extra_data_size));
         if (ret < 0) {
             goto fail;
@@ -105,7 +104,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
 
         /* Read snapshot ID */
         sn->id_str = g_malloc(id_str_size + 1);
-        ret = bdrv_pread(bs->file, offset, sn->id_str, id_str_size);
+        ret = bdrv_pread(bs->file->bs, offset, sn->id_str, id_str_size);
         if (ret < 0) {
             goto fail;
         }
@@ -114,7 +113,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
 
         /* Read snapshot name */
         sn->name = g_malloc(name_size + 1);
-        ret = bdrv_pread(bs->file, offset, sn->name, name_size);
+        ret = bdrv_pread(bs->file->bs, offset, sn->name, name_size);
         if (ret < 0) {
             goto fail;
         }
@@ -217,25 +216,25 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
         h.name_size = cpu_to_be16(name_size);
         offset = align_offset(offset, 8);
 
-        ret = bdrv_pwrite(bs->file, offset, &h, sizeof(h));
+        ret = bdrv_pwrite(bs->file->bs, offset, &h, sizeof(h));
         if (ret < 0) {
             goto fail;
         }
         offset += sizeof(h);
 
-        ret = bdrv_pwrite(bs->file, offset, &extra, sizeof(extra));
+        ret = bdrv_pwrite(bs->file->bs, offset, &extra, sizeof(extra));
         if (ret < 0) {
             goto fail;
         }
         offset += sizeof(extra);
 
-        ret = bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size);
+        ret = bdrv_pwrite(bs->file->bs, offset, sn->id_str, id_str_size);
         if (ret < 0) {
             goto fail;
         }
         offset += id_str_size;
 
-        ret = bdrv_pwrite(bs->file, offset, sn->name, name_size);
+        ret = bdrv_pwrite(bs->file->bs, offset, sn->name, name_size);
         if (ret < 0) {
             goto fail;
         }
@@ -257,7 +256,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
     header_data.nb_snapshots        = cpu_to_be32(s->nb_snapshots);
     header_data.snapshots_offset    = cpu_to_be64(snapshots_offset);
 
-    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots),
+    ret = bdrv_pwrite_sync(bs->file->bs, offsetof(QCowHeader, nb_snapshots),
                            &header_data, sizeof(header_data));
     if (ret < 0) {
         goto fail;
@@ -399,7 +398,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
         goto fail;
     }
 
-    ret = bdrv_pwrite(bs->file, sn->l1_table_offset, l1_table,
+    ret = bdrv_pwrite(bs->file->bs, sn->l1_table_offset, l1_table,
                       s->l1_size * sizeof(uint64_t));
     if (ret < 0) {
         goto fail;
@@ -512,7 +511,7 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
         goto fail;
     }
 
-    ret = bdrv_pread(bs->file, sn->l1_table_offset,
+    ret = bdrv_pread(bs->file->bs, sn->l1_table_offset,
                      sn_l1_table, sn_l1_bytes);
     if (ret < 0) {
         goto fail;
@@ -530,7 +529,7 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
         goto fail;
     }
 
-    ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset, sn_l1_table,
+    ret = bdrv_pwrite_sync(bs->file->bs, s->l1_table_offset, sn_l1_table,
                            cur_l1_bytes);
     if (ret < 0) {
         goto fail;
@@ -716,7 +715,7 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs,
         return -ENOMEM;
     }
 
-    ret = bdrv_pread(bs->file, sn->l1_table_offset,
+    ret = bdrv_pread(bs->file->bs, sn->l1_table_offset,
                      new_l1_table, new_l1_bytes);
     if (ret < 0) {
         error_setg(errp, "Failed to read l1 table for snapshot");
index 91ef4df..470734b 100644 (file)
@@ -36,7 +36,6 @@
 #include "trace.h"
 #include "qemu/option_int.h"
 #include "qemu/cutils.h"
-#include "qemu/bswap.h"
 
 /*
   Differences with QCOW:
@@ -107,7 +106,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
         printf("attempting to read extended header in offset %lu\n", offset);
 #endif
 
-        ret = bdrv_pread(bs->file, offset, &ext, sizeof(ext));
+        ret = bdrv_pread(bs->file->bs, offset, &ext, sizeof(ext));
         if (ret < 0) {
             error_setg_errno(errp, -ret, "qcow2_read_extension: ERROR: "
                              "pread fail from offset %" PRIu64, offset);
@@ -135,7 +134,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
                            sizeof(bs->backing_format));
                 return 2;
             }
-            ret = bdrv_pread(bs->file, offset, bs->backing_format, ext.len);
+            ret = bdrv_pread(bs->file->bs, offset, bs->backing_format, ext.len);
             if (ret < 0) {
                 error_setg_errno(errp, -ret, "ERROR: ext_backing_format: "
                                  "Could not read format name");
@@ -151,7 +150,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
         case QCOW2_EXT_MAGIC_FEATURE_TABLE:
             if (p_feature_table != NULL) {
                 void* feature_table = g_malloc0(ext.len + 2 * sizeof(Qcow2Feature));
-                ret = bdrv_pread(bs->file, offset , feature_table, ext.len);
+                ret = bdrv_pread(bs->file->bs, offset , feature_table, ext.len);
                 if (ret < 0) {
                     error_setg_errno(errp, -ret, "ERROR: ext_feature_table: "
                                      "Could not read table");
@@ -172,7 +171,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
                 uext->len = ext.len;
                 QLIST_INSERT_HEAD(&s->unknown_header_ext, uext, next);
 
-                ret = bdrv_pread(bs->file, offset , uext->data, uext->len);
+                ret = bdrv_pread(bs->file->bs, offset , uext->data, uext->len);
                 if (ret < 0) {
                     error_setg_errno(errp, -ret, "ERROR: unknown extension: "
                                      "Could not read data");
@@ -249,7 +248,7 @@ int qcow2_mark_dirty(BlockDriverState *bs)
     }
 
     val = cpu_to_be64(s->incompatible_features | QCOW2_INCOMPAT_DIRTY);
-    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, incompatible_features),
+    ret = bdrv_pwrite(bs->file->bs, offsetof(QCowHeader, incompatible_features),
                       &val, sizeof(val));
     if (ret < 0) {
         return ret;
@@ -817,7 +816,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
     uint64_t ext_end;
     uint64_t l1_vm_state_index;
 
-    ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
+    ret = bdrv_pread(bs->file->bs, 0, &header, sizeof(header));
     if (ret < 0) {
         error_setg_errno(errp, -ret, "Could not read qcow2 header");
         goto fail;
@@ -892,7 +891,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
     if (header.header_length > sizeof(header)) {
         s->unknown_header_fields_size = header.header_length - sizeof(header);
         s->unknown_header_fields = g_malloc(s->unknown_header_fields_size);
-        ret = bdrv_pread(bs->file, sizeof(header), s->unknown_header_fields,
+        ret = bdrv_pread(bs->file->bs, sizeof(header), s->unknown_header_fields,
                          s->unknown_header_fields_size);
         if (ret < 0) {
             error_setg_errno(errp, -ret, "Could not read unknown qcow2 header "
@@ -968,19 +967,13 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
     if (s->crypt_method_header) {
         if (bdrv_uses_whitelist() &&
             s->crypt_method_header == QCOW_CRYPT_AES) {
-            error_setg(errp,
-                       "Use of AES-CBC encrypted qcow2 images is no longer "
-                       "supported in system emulators");
-            error_append_hint(errp,
-                              "You can use 'qemu-img convert' to convert your "
-                              "image to an alternative supported format, such "
-                              "as unencrypted qcow2, or raw with the LUKS "
-                              "format instead.\n");
-            ret = -ENOSYS;
-            goto fail;
+            error_report("qcow2 built-in AES encryption is deprecated");
+            error_printf("Support for it will be removed in a future release.\n"
+                         "You can use 'qemu-img convert' to switch to an\n"
+                         "unencrypted qcow2 image, or a LUKS raw image.\n");
         }
 
-        bs->encrypted = true;
+        bs->encrypted = 1;
     }
 
     s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */
@@ -1066,7 +1059,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
             ret = -ENOMEM;
             goto fail;
         }
-        ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table,
+        ret = bdrv_pread(bs->file->bs, s->l1_table_offset, s->l1_table,
                          s->l1_size * sizeof(uint64_t));
         if (ret < 0) {
             error_setg_errno(errp, -ret, "Could not read L1 table");
@@ -1122,7 +1115,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
             ret = -EINVAL;
             goto fail;
         }
-        ret = bdrv_pread(bs->file, header.backing_file_offset,
+        ret = bdrv_pread(bs->file->bs, header.backing_file_offset,
                          bs->backing_file, len);
         if (ret < 0) {
             error_setg_errno(errp, -ret, "Could not read backing file name");
@@ -1199,11 +1192,7 @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
 {
     BDRVQcow2State *s = bs->opaque;
 
-    if (bs->encrypted) {
-        /* Encryption works on a sector granularity */
-        bs->bl.request_alignment = BDRV_SECTOR_SIZE;
-    }
-    bs->bl.pwrite_zeroes_alignment = s->cluster_size;
+    bs->bl.write_zeroes_alignment = s->cluster_sectors;
 }
 
 static int qcow2_set_key(BlockDriverState *bs, const char *key)
@@ -1341,20 +1330,16 @@ static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs,
     BDRVQcow2State *s = bs->opaque;
     uint64_t cluster_offset;
     int index_in_cluster, ret;
-    unsigned int bytes;
     int64_t status = 0;
 
-    bytes = MIN(INT_MAX, nb_sectors * BDRV_SECTOR_SIZE);
+    *pnum = nb_sectors;
     qemu_co_mutex_lock(&s->lock);
-    ret = qcow2_get_cluster_offset(bs, sector_num << 9, &bytes,
-                                   &cluster_offset);
+    ret = qcow2_get_cluster_offset(bs, sector_num << 9, pnum, &cluster_offset);
     qemu_co_mutex_unlock(&s->lock);
     if (ret < 0) {
         return ret;
     }
 
-    *pnum = bytes >> BDRV_SECTOR_BITS;
-
     if (cluster_offset != 0 && ret != QCOW2_CLUSTER_COMPRESSED &&
         !s->cipher) {
         index_in_cluster = sector_num & (s->cluster_sectors - 1);
@@ -1372,34 +1357,28 @@ static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs,
 
 /* handle reading after the end of the backing file */
 int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
-                        int64_t offset, int bytes)
+                  int64_t sector_num, int nb_sectors)
 {
-    uint64_t bs_size = bs->total_sectors * BDRV_SECTOR_SIZE;
     int n1;
-
-    if ((offset + bytes) <= bs_size) {
-        return bytes;
-    }
-
-    if (offset >= bs_size) {
+    if ((sector_num + nb_sectors) <= bs->total_sectors)
+        return nb_sectors;
+    if (sector_num >= bs->total_sectors)
         n1 = 0;
-    } else {
-        n1 = bs_size - offset;
-    }
+    else
+        n1 = bs->total_sectors - sector_num;
 
-    qemu_iovec_memset(qiov, n1, 0, bytes - n1);
+    qemu_iovec_memset(qiov, 512 * n1, 0, 512 * (nb_sectors - n1));
 
     return n1;
 }
 
-static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
-                                        uint64_t bytes, QEMUIOVector *qiov,
-                                        int flags)
+static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
+                          int remaining_sectors, QEMUIOVector *qiov)
 {
     BDRVQcow2State *s = bs->opaque;
-    int offset_in_cluster, n1;
+    int index_in_cluster, n1;
     int ret;
-    unsigned int cur_bytes; /* number of bytes in current iteration */
+    int cur_nr_sectors; /* number of sectors in current iteration */
     uint64_t cluster_offset = 0;
     uint64_t bytes_done = 0;
     QEMUIOVector hd_qiov;
@@ -1409,24 +1388,26 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
 
     qemu_co_mutex_lock(&s->lock);
 
-    while (bytes != 0) {
+    while (remaining_sectors != 0) {
 
         /* prepare next request */
-        cur_bytes = MIN(bytes, INT_MAX);
+        cur_nr_sectors = remaining_sectors;
         if (s->cipher) {
-            cur_bytes = MIN(cur_bytes,
-                            QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
+            cur_nr_sectors = MIN(cur_nr_sectors,
+                QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
         }
 
-        ret = qcow2_get_cluster_offset(bs, offset, &cur_bytes, &cluster_offset);
+        ret = qcow2_get_cluster_offset(bs, sector_num << 9,
+            &cur_nr_sectors, &cluster_offset);
         if (ret < 0) {
             goto fail;
         }
 
-        offset_in_cluster = offset_into_cluster(s, offset);
+        index_in_cluster = sector_num & (s->cluster_sectors - 1);
 
         qemu_iovec_reset(&hd_qiov);
-        qemu_iovec_concat(&hd_qiov, qiov, bytes_done, cur_bytes);
+        qemu_iovec_concat(&hd_qiov, qiov, bytes_done,
+            cur_nr_sectors * 512);
 
         switch (ret) {
         case QCOW2_CLUSTER_UNALLOCATED:
@@ -1434,17 +1415,18 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
             if (bs->backing) {
                 /* read from the base image */
                 n1 = qcow2_backing_read1(bs->backing->bs, &hd_qiov,
-                                         offset, cur_bytes);
+                    sector_num, cur_nr_sectors);
                 if (n1 > 0) {
                     QEMUIOVector local_qiov;
 
                     qemu_iovec_init(&local_qiov, hd_qiov.niov);
-                    qemu_iovec_concat(&local_qiov, &hd_qiov, 0, n1);
+                    qemu_iovec_concat(&local_qiov, &hd_qiov, 0,
+                                      n1 * BDRV_SECTOR_SIZE);
 
                     BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
                     qemu_co_mutex_unlock(&s->lock);
-                    ret = bdrv_co_preadv(bs->backing, offset, n1,
-                                         &local_qiov, 0);
+                    ret = bdrv_co_readv(bs->backing->bs, sector_num,
+                                        n1, &local_qiov);
                     qemu_co_mutex_lock(&s->lock);
 
                     qemu_iovec_destroy(&local_qiov);
@@ -1455,12 +1437,12 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
                 }
             } else {
                 /* Note: in this case, no need to wait */
-                qemu_iovec_memset(&hd_qiov, 0, 0, cur_bytes);
+                qemu_iovec_memset(&hd_qiov, 0, 0, 512 * cur_nr_sectors);
             }
             break;
 
         case QCOW2_CLUSTER_ZERO:
-            qemu_iovec_memset(&hd_qiov, 0, 0, cur_bytes);
+            qemu_iovec_memset(&hd_qiov, 0, 0, 512 * cur_nr_sectors);
             break;
 
         case QCOW2_CLUSTER_COMPRESSED:
@@ -1471,8 +1453,8 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
             }
 
             qemu_iovec_from_buf(&hd_qiov, 0,
-                                s->cluster_cache + offset_in_cluster,
-                                cur_bytes);
+                s->cluster_cache + index_in_cluster * 512,
+                512 * cur_nr_sectors);
             break;
 
         case QCOW2_CLUSTER_NORMAL:
@@ -1499,34 +1481,34 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
                     }
                 }
 
-                assert(cur_bytes <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
+                assert(cur_nr_sectors <=
+                    QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
                 qemu_iovec_reset(&hd_qiov);
-                qemu_iovec_add(&hd_qiov, cluster_data, cur_bytes);
+                qemu_iovec_add(&hd_qiov, cluster_data,
+                    512 * cur_nr_sectors);
             }
 
             BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
             qemu_co_mutex_unlock(&s->lock);
-            ret = bdrv_co_preadv(bs->file,
-                                 cluster_offset + offset_in_cluster,
-                                 cur_bytes, &hd_qiov, 0);
+            ret = bdrv_co_readv(bs->file->bs,
+                                (cluster_offset >> 9) + index_in_cluster,
+                                cur_nr_sectors, &hd_qiov);
             qemu_co_mutex_lock(&s->lock);
             if (ret < 0) {
                 goto fail;
             }
             if (bs->encrypted) {
                 assert(s->cipher);
-                assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
-                assert((cur_bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
                 Error *err = NULL;
-                if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS,
-                                          cluster_data, cluster_data,
-                                          cur_bytes >> BDRV_SECTOR_BITS,
-                                          false, &err) < 0) {
+                if (qcow2_encrypt_sectors(s, sector_num,  cluster_data,
+                                          cluster_data, cur_nr_sectors, false,
+                                          &err) < 0) {
                     error_free(err);
                     ret = -EIO;
                     goto fail;
                 }
-                qemu_iovec_from_buf(qiov, bytes_done, cluster_data, cur_bytes);
+                qemu_iovec_from_buf(qiov, bytes_done,
+                    cluster_data, 512 * cur_nr_sectors);
             }
             break;
 
@@ -1536,9 +1518,9 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
             goto fail;
         }
 
-        bytes -= cur_bytes;
-        offset += cur_bytes;
-        bytes_done += cur_bytes;
+        remaining_sectors -= cur_nr_sectors;
+        sector_num += cur_nr_sectors;
+        bytes_done += cur_nr_sectors * 512;
     }
     ret = 0;
 
@@ -1551,21 +1533,23 @@ fail:
     return ret;
 }
 
-static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
-                                         uint64_t bytes, QEMUIOVector *qiov,
-                                         int flags)
+static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
+                           int64_t sector_num,
+                           int remaining_sectors,
+                           QEMUIOVector *qiov)
 {
     BDRVQcow2State *s = bs->opaque;
-    int offset_in_cluster;
+    int index_in_cluster;
     int ret;
-    unsigned int cur_bytes; /* number of sectors in current iteration */
+    int cur_nr_sectors; /* number of sectors in current iteration */
     uint64_t cluster_offset;
     QEMUIOVector hd_qiov;
     uint64_t bytes_done = 0;
     uint8_t *cluster_data = NULL;
     QCowL2Meta *l2meta = NULL;
 
-    trace_qcow2_writev_start_req(qemu_coroutine_self(), offset, bytes);
+    trace_qcow2_writev_start_req(qemu_coroutine_self(), sector_num,
+                                 remaining_sectors);
 
     qemu_iovec_init(&hd_qiov, qiov->niov);
 
@@ -1573,21 +1557,22 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
 
     qemu_co_mutex_lock(&s->lock);
 
-    while (bytes != 0) {
+    while (remaining_sectors != 0) {
 
         l2meta = NULL;
 
         trace_qcow2_writev_start_part(qemu_coroutine_self());
-        offset_in_cluster = offset_into_cluster(s, offset);
-        cur_bytes = MIN(bytes, INT_MAX);
-        if (bs->encrypted) {
-            cur_bytes = MIN(cur_bytes,
-                            QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size
-                            - offset_in_cluster);
+        index_in_cluster = sector_num & (s->cluster_sectors - 1);
+        cur_nr_sectors = remaining_sectors;
+        if (bs->encrypted &&
+            cur_nr_sectors >
+            QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors - index_in_cluster) {
+            cur_nr_sectors =
+                QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors - index_in_cluster;
         }
 
-        ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes,
-                                         &cluster_offset, &l2meta);
+        ret = qcow2_alloc_cluster_offset(bs, sector_num << 9,
+            &cur_nr_sectors, &cluster_offset, &l2meta);
         if (ret < 0) {
             goto fail;
         }
@@ -1595,7 +1580,8 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
         assert((cluster_offset & 511) == 0);
 
         qemu_iovec_reset(&hd_qiov);
-        qemu_iovec_concat(&hd_qiov, qiov, bytes_done, cur_bytes);
+        qemu_iovec_concat(&hd_qiov, qiov, bytes_done,
+            cur_nr_sectors * 512);
 
         if (bs->encrypted) {
             Error *err = NULL;
@@ -1614,9 +1600,8 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
                    QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
             qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size);
 
-            if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS,
-                                      cluster_data, cluster_data,
-                                      cur_bytes >>BDRV_SECTOR_BITS,
+            if (qcow2_encrypt_sectors(s, sector_num, cluster_data,
+                                      cluster_data, cur_nr_sectors,
                                       true, &err) < 0) {
                 error_free(err);
                 ret = -EIO;
@@ -1624,11 +1609,13 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
             }
 
             qemu_iovec_reset(&hd_qiov);
-            qemu_iovec_add(&hd_qiov, cluster_data, cur_bytes);
+            qemu_iovec_add(&hd_qiov, cluster_data,
+                cur_nr_sectors * 512);
         }
 
         ret = qcow2_pre_write_overlap_check(bs, 0,
-                cluster_offset + offset_in_cluster, cur_bytes);
+                cluster_offset + index_in_cluster * BDRV_SECTOR_SIZE,
+                cur_nr_sectors * BDRV_SECTOR_SIZE);
         if (ret < 0) {
             goto fail;
         }
@@ -1636,10 +1623,10 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
         qemu_co_mutex_unlock(&s->lock);
         BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
         trace_qcow2_writev_data(qemu_coroutine_self(),
-                                cluster_offset + offset_in_cluster);
-        ret = bdrv_co_pwritev(bs->file,
-                              cluster_offset + offset_in_cluster,
-                              cur_bytes, &hd_qiov, 0);
+                                (cluster_offset >> 9) + index_in_cluster);
+        ret = bdrv_co_writev(bs->file->bs,
+                             (cluster_offset >> 9) + index_in_cluster,
+                             cur_nr_sectors, &hd_qiov);
         qemu_co_mutex_lock(&s->lock);
         if (ret < 0) {
             goto fail;
@@ -1665,10 +1652,10 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
             l2meta = next;
         }
 
-        bytes -= cur_bytes;
-        offset += cur_bytes;
-        bytes_done += cur_bytes;
-        trace_qcow2_writev_done_part(qemu_coroutine_self(), cur_bytes);
+        remaining_sectors -= cur_nr_sectors;
+        sector_num += cur_nr_sectors;
+        bytes_done += cur_nr_sectors * 512;
+        trace_qcow2_writev_done_part(qemu_coroutine_self(), cur_nr_sectors);
     }
     ret = 0;
 
@@ -1770,6 +1757,13 @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp)
 
     qcow2_close(bs);
 
+    bdrv_invalidate_cache(bs->file->bs, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        bs->drv = NULL;
+        return;
+    }
+
     memset(s, 0, sizeof(BDRVQcow2State));
     options = qdict_clone_shallow(bs->options);
 
@@ -1976,7 +1970,7 @@ int qcow2_update_header(BlockDriverState *bs)
     }
 
     /* Write the new header */
-    ret = bdrv_pwrite(bs->file, 0, header, s->cluster_size);
+    ret = bdrv_pwrite(bs->file->bs, 0, header, s->cluster_size);
     if (ret < 0) {
         goto fail;
     }
@@ -2010,19 +2004,19 @@ static int qcow2_change_backing_file(BlockDriverState *bs,
 
 static int preallocate(BlockDriverState *bs)
 {
-    uint64_t bytes;
+    uint64_t nb_sectors;
     uint64_t offset;
     uint64_t host_offset = 0;
-    unsigned int cur_bytes;
+    int num;
     int ret;
     QCowL2Meta *meta;
 
-    bytes = bdrv_getlength(bs);
+    nb_sectors = bdrv_nb_sectors(bs);
     offset = 0;
 
-    while (bytes) {
-        cur_bytes = MIN(bytes, INT_MAX);
-        ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes,
+    while (nb_sectors) {
+        num = MIN(nb_sectors, INT_MAX >> BDRV_SECTOR_BITS);
+        ret = qcow2_alloc_cluster_offset(bs, offset, &num,
                                          &host_offset, &meta);
         if (ret < 0) {
             return ret;
@@ -2048,8 +2042,8 @@ static int preallocate(BlockDriverState *bs)
 
         /* TODO Preallocate data if requested */
 
-        bytes -= cur_bytes;
-        offset += cur_bytes;
+        nb_sectors -= num;
+        offset += num << BDRV_SECTOR_BITS;
     }
 
     /*
@@ -2058,9 +2052,11 @@ static int preallocate(BlockDriverState *bs)
      * EOF). Extend the image to the last allocated sector.
      */
     if (host_offset != 0) {
-        uint8_t data = 0;
-        ret = bdrv_pwrite(bs->file, (host_offset + cur_bytes) - 1,
-                          &data, 1);
+        uint8_t buf[BDRV_SECTOR_SIZE];
+        memset(buf, 0, BDRV_SECTOR_SIZE);
+        ret = bdrv_write(bs->file->bs,
+                         (host_offset >> BDRV_SECTOR_BITS) + num - 1,
+                         buf, 1);
         if (ret < 0) {
             return ret;
         }
@@ -2211,7 +2207,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
             cpu_to_be64(QCOW2_COMPAT_LAZY_REFCOUNTS);
     }
 
-    ret = blk_pwrite(blk, 0, header, cluster_size, 0);
+    ret = blk_pwrite(blk, 0, header, cluster_size);
     g_free(header);
     if (ret < 0) {
         error_setg_errno(errp, -ret, "Could not write qcow2 header");
@@ -2221,7 +2217,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
     /* Write a refcount table with one refcount block */
     refcount_table = g_malloc0(2 * cluster_size);
     refcount_table[0] = cpu_to_be64(2 * cluster_size);
-    ret = blk_pwrite(blk, cluster_size, refcount_table, 2 * cluster_size, 0);
+    ret = blk_pwrite(blk, cluster_size, refcount_table, 2 * cluster_size);
     g_free(refcount_table);
 
     if (ret < 0) {
@@ -2404,7 +2400,9 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
     ret = qcow2_create2(filename, size, backing_file, backing_fmt, flags,
                         cluster_size, prealloc, opts, version, refcount_order,
                         &local_err);
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
 
 finish:
     g_free(backing_file);
@@ -2413,81 +2411,35 @@ finish:
     return ret;
 }
 
-
-static bool is_zero_sectors(BlockDriverState *bs, int64_t start,
-                            uint32_t count)
-{
-    int nr;
-    BlockDriverState *file;
-    int64_t res;
-
-    if (!count) {
-        return true;
-    }
-    res = bdrv_get_block_status_above(bs, NULL, start, count,
-                                      &nr, &file);
-    return res >= 0 && (res & BDRV_BLOCK_ZERO) && nr == count;
-}
-
-static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs,
-    int64_t offset, int count, BdrvRequestFlags flags)
+static coroutine_fn int qcow2_co_write_zeroes(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, BdrvRequestFlags flags)
 {
     int ret;
     BDRVQcow2State *s = bs->opaque;
 
-    uint32_t head = offset % s->cluster_size;
-    uint32_t tail = (offset + count) % s->cluster_size;
-
-    trace_qcow2_pwrite_zeroes_start_req(qemu_coroutine_self(), offset, count);
-
-    if (head || tail) {
-        int64_t cl_start = (offset - head) >> BDRV_SECTOR_BITS;
-        uint64_t off;
-        unsigned int nr;
-
-        assert(head + count <= s->cluster_size);
-
-        /* check whether remainder of cluster already reads as zero */
-        if (!(is_zero_sectors(bs, cl_start,
-                              DIV_ROUND_UP(head, BDRV_SECTOR_SIZE)) &&
-              is_zero_sectors(bs, (offset + count) >> BDRV_SECTOR_BITS,
-                              DIV_ROUND_UP(-tail & (s->cluster_size - 1),
-                                           BDRV_SECTOR_SIZE)))) {
-            return -ENOTSUP;
-        }
-
-        qemu_co_mutex_lock(&s->lock);
-        /* We can have new write after previous check */
-        offset = cl_start << BDRV_SECTOR_BITS;
-        count = s->cluster_size;
-        nr = s->cluster_size;
-        ret = qcow2_get_cluster_offset(bs, offset, &nr, &off);
-        if (ret != QCOW2_CLUSTER_UNALLOCATED && ret != QCOW2_CLUSTER_ZERO) {
-            qemu_co_mutex_unlock(&s->lock);
-            return -ENOTSUP;
-        }
-    } else {
-        qemu_co_mutex_lock(&s->lock);
+    /* Emulate misaligned zero writes */
+    if (sector_num % s->cluster_sectors || nb_sectors % s->cluster_sectors) {
+        return -ENOTSUP;
     }
 
-    trace_qcow2_pwrite_zeroes(qemu_coroutine_self(), offset, count);
-
     /* Whatever is left can use real zero clusters */
-    ret = qcow2_zero_clusters(bs, offset, count >> BDRV_SECTOR_BITS);
+    qemu_co_mutex_lock(&s->lock);
+    ret = qcow2_zero_clusters(bs, sector_num << BDRV_SECTOR_BITS,
+        nb_sectors);
     qemu_co_mutex_unlock(&s->lock);
 
     return ret;
 }
 
-static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,
-                                          int64_t offset, int count)
+static coroutine_fn int qcow2_co_discard(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors)
 {
     int ret;
     BDRVQcow2State *s = bs->opaque;
 
     qemu_co_mutex_lock(&s->lock);
-    ret = qcow2_discard_clusters(bs, offset, count >> BDRV_SECTOR_BITS,
-                                 QCOW2_DISCARD_REQUEST, false);
+    ret = qcow2_discard_clusters(bs, sector_num << BDRV_SECTOR_BITS,
+        nb_sectors, QCOW2_DISCARD_REQUEST, false);
     qemu_co_mutex_unlock(&s->lock);
     return ret;
 }
@@ -2523,7 +2475,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
 
     /* write updated header.size */
     offset = cpu_to_be64(offset);
-    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size),
+    ret = bdrv_pwrite_sync(bs->file->bs, offsetof(QCowHeader, size),
                            &offset, sizeof(uint64_t));
     if (ret < 0) {
         return ret;
@@ -2533,51 +2485,6 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
     return 0;
 }
 
-typedef struct Qcow2WriteCo {
-    BlockDriverState *bs;
-    int64_t sector_num;
-    const uint8_t *buf;
-    int nb_sectors;
-    int ret;
-} Qcow2WriteCo;
-
-static void qcow2_write_co_entry(void *opaque)
-{
-    Qcow2WriteCo *co = opaque;
-    QEMUIOVector qiov;
-    uint64_t offset = co->sector_num * BDRV_SECTOR_SIZE;
-    uint64_t bytes = co->nb_sectors * BDRV_SECTOR_SIZE;
-
-    struct iovec iov = (struct iovec) {
-        .iov_base   = (uint8_t*) co->buf,
-        .iov_len    = bytes,
-    };
-    qemu_iovec_init_external(&qiov, &iov, 1);
-
-    co->ret = qcow2_co_pwritev(co->bs, offset, bytes, &qiov, 0);
-}
-
-/* Wrapper for non-coroutine contexts */
-static int qcow2_write(BlockDriverState *bs, int64_t sector_num,
-                       const uint8_t *buf, int nb_sectors)
-{
-    Coroutine *co;
-    AioContext *aio_context = bdrv_get_aio_context(bs);
-    Qcow2WriteCo data = {
-        .bs         = bs,
-        .sector_num = sector_num,
-        .buf        = buf,
-        .nb_sectors = nb_sectors,
-        .ret        = -EINPROGRESS,
-    };
-    co = qemu_coroutine_create(qcow2_write_co_entry, &data);
-    qemu_coroutine_enter(co);
-    while (data.ret == -EINPROGRESS) {
-        aio_poll(aio_context, true);
-    }
-    return data.ret;
-}
-
 /* XXX: put compressed sectors first, then all the cluster aligned
    tables to avoid losing bytes in alignment */
 static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
@@ -2612,7 +2519,7 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
         return ret;
     }
 
-    out_buf = g_malloc(s->cluster_size);
+    out_buf = g_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
 
     /* best compression, small window, no zlib header */
     memset(&strm, 0, sizeof(strm));
@@ -2641,7 +2548,7 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
 
     if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
         /* could not compress: write normal cluster */
-        ret = qcow2_write(bs, sector_num, buf, s->cluster_sectors);
+        ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors);
         if (ret < 0) {
             goto fail;
         }
@@ -2660,7 +2567,7 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
         }
 
         BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
-        ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len);
+        ret = bdrv_pwrite(bs->file->bs, cluster_offset, out_buf, out_len);
         if (ret < 0) {
             goto fail;
         }
@@ -2709,8 +2616,8 @@ static int make_completely_empty(BlockDriverState *bs)
     /* After this call, neither the in-memory nor the on-disk refcount
      * information accurately describe the actual references */
 
-    ret = bdrv_pwrite_zeroes(bs->file, s->l1_table_offset,
-                             l1_clusters * s->cluster_size, 0);
+    ret = bdrv_write_zeroes(bs->file->bs, s->l1_table_offset / BDRV_SECTOR_SIZE,
+                            l1_clusters * s->cluster_sectors, 0);
     if (ret < 0) {
         goto fail_broken_refcounts;
     }
@@ -2723,8 +2630,9 @@ static int make_completely_empty(BlockDriverState *bs)
      * overwrite parts of the existing refcount and L1 table, which is not
      * an issue because the dirty flag is set, complete data loss is in fact
      * desired and partial data loss is consequently fine as well */
-    ret = bdrv_pwrite_zeroes(bs->file, s->cluster_size,
-                             (2 + l1_clusters) * s->cluster_size, 0);
+    ret = bdrv_write_zeroes(bs->file->bs, s->cluster_size / BDRV_SECTOR_SIZE,
+                            (2 + l1_clusters) * s->cluster_size /
+                            BDRV_SECTOR_SIZE, 0);
     /* This call (even if it failed overall) may have overwritten on-disk
      * refcount structures; in that case, the in-memory refcount information
      * will probably differ from the on-disk information which makes the BDS
@@ -2739,10 +2647,10 @@ static int make_completely_empty(BlockDriverState *bs)
     /* "Create" an empty reftable (one cluster) directly after the image
      * header and an empty L1 table three clusters after the image header;
      * the cluster between those two will be used as the first refblock */
-    l1_ofs_rt_ofs_cls.l1_offset = cpu_to_be64(3 * s->cluster_size);
-    l1_ofs_rt_ofs_cls.reftable_offset = cpu_to_be64(s->cluster_size);
-    l1_ofs_rt_ofs_cls.reftable_clusters = cpu_to_be32(1);
-    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_table_offset),
+    cpu_to_be64w(&l1_ofs_rt_ofs_cls.l1_offset, 3 * s->cluster_size);
+    cpu_to_be64w(&l1_ofs_rt_ofs_cls.reftable_offset, s->cluster_size);
+    cpu_to_be32w(&l1_ofs_rt_ofs_cls.reftable_clusters, 1);
+    ret = bdrv_pwrite_sync(bs->file->bs, offsetof(QCowHeader, l1_table_offset),
                            &l1_ofs_rt_ofs_cls, sizeof(l1_ofs_rt_ofs_cls));
     if (ret < 0) {
         goto fail_broken_refcounts;
@@ -2773,7 +2681,7 @@ static int make_completely_empty(BlockDriverState *bs)
 
     /* Enter the first refblock into the reftable */
     rt_entry = cpu_to_be64(2 * s->cluster_size);
-    ret = bdrv_pwrite_sync(bs->file, s->cluster_size,
+    ret = bdrv_pwrite_sync(bs->file->bs, s->cluster_size,
                            &rt_entry, sizeof(rt_entry));
     if (ret < 0) {
         goto fail_broken_refcounts;
@@ -2866,14 +2774,14 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs)
     int ret;
 
     qemu_co_mutex_lock(&s->lock);
-    ret = qcow2_cache_write(bs, s->l2_table_cache);
+    ret = qcow2_cache_flush(bs, s->l2_table_cache);
     if (ret < 0) {
         qemu_co_mutex_unlock(&s->lock);
         return ret;
     }
 
     if (qcow2_need_accurate_refcounts(s)) {
-        ret = qcow2_cache_write(bs, s->refcount_block_cache);
+        ret = qcow2_cache_flush(bs, s->refcount_block_cache);
         if (ret < 0) {
             qemu_co_mutex_unlock(&s->lock);
             return ret;
@@ -2953,20 +2861,36 @@ static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
                               int64_t pos)
 {
     BDRVQcow2State *s = bs->opaque;
+    int64_t total_sectors = bs->total_sectors;
+    bool zero_beyond_eof = bs->zero_beyond_eof;
+    int ret;
 
     BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE);
-    return bs->drv->bdrv_co_pwritev(bs, qcow2_vm_state_offset(s) + pos,
-                                    qiov->size, qiov, 0);
+    bs->zero_beyond_eof = false;
+    ret = bdrv_pwritev(bs, qcow2_vm_state_offset(s) + pos, qiov);
+    bs->zero_beyond_eof = zero_beyond_eof;
+
+    /* bdrv_co_do_writev will have increased the total_sectors value to include
+     * the VM state - the VM state is however not an actual part of the block
+     * device, therefore, we need to restore the old value. */
+    bs->total_sectors = total_sectors;
+
+    return ret;
 }
 
-static int qcow2_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
-                              int64_t pos)
+static int qcow2_load_vmstate(BlockDriverState *bs, uint8_t *buf,
+                              int64_t pos, int size)
 {
     BDRVQcow2State *s = bs->opaque;
+    bool zero_beyond_eof = bs->zero_beyond_eof;
+    int ret;
 
     BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_LOAD);
-    return bs->drv->bdrv_co_preadv(bs, qcow2_vm_state_offset(s) + pos,
-                                   qiov->size, qiov, 0);
+    bs->zero_beyond_eof = false;
+    ret = bdrv_pread(bs, qcow2_vm_state_offset(s) + pos, buf, size);
+    bs->zero_beyond_eof = zero_beyond_eof;
+
+    return ret;
 }
 
 /*
@@ -3405,12 +3329,12 @@ BlockDriver bdrv_qcow2 = {
     .bdrv_co_get_block_status = qcow2_co_get_block_status,
     .bdrv_set_key       = qcow2_set_key,
 
-    .bdrv_co_preadv         = qcow2_co_preadv,
-    .bdrv_co_pwritev        = qcow2_co_pwritev,
+    .bdrv_co_readv          = qcow2_co_readv,
+    .bdrv_co_writev         = qcow2_co_writev,
     .bdrv_co_flush_to_os    = qcow2_co_flush_to_os,
 
-    .bdrv_co_pwrite_zeroes  = qcow2_co_pwrite_zeroes,
-    .bdrv_co_pdiscard       = qcow2_co_pdiscard,
+    .bdrv_co_write_zeroes   = qcow2_co_write_zeroes,
+    .bdrv_co_discard        = qcow2_co_discard,
     .bdrv_truncate          = qcow2_truncate,
     .bdrv_write_compressed  = qcow2_write_compressed,
     .bdrv_make_empty        = qcow2_make_empty,
index b36a7bf..a063a3c 100644 (file)
@@ -302,8 +302,8 @@ typedef struct Qcow2COWRegion {
      */
     uint64_t    offset;
 
-    /** Number of bytes to copy */
-    int         nb_bytes;
+    /** Number of sectors to copy */
+    int         nb_sectors;
 } Qcow2COWRegion;
 
 /**
@@ -318,6 +318,12 @@ typedef struct QCowL2Meta
     /** Host offset of the first newly allocated cluster */
     uint64_t alloc_offset;
 
+    /**
+     * Number of sectors from the start of the first allocated cluster to
+     * the end of the (possibly shortened) request
+     */
+    int nb_available;
+
     /** Number of newly allocated clusters */
     int nb_clusters;
 
@@ -465,7 +471,8 @@ static inline uint64_t l2meta_cow_start(QCowL2Meta *m)
 
 static inline uint64_t l2meta_cow_end(QCowL2Meta *m)
 {
-    return m->offset + m->cow_end.offset + m->cow_end.nb_bytes;
+    return m->offset + m->cow_end.offset
+        + (m->cow_end.nb_sectors << BDRV_SECTOR_BITS);
 }
 
 static inline uint64_t refcount_diff(uint64_t r1, uint64_t r2)
@@ -537,10 +544,9 @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
                           int nb_sectors, bool enc, Error **errp);
 
 int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
-                             unsigned int *bytes, uint64_t *cluster_offset);
+    int *num, uint64_t *cluster_offset);
 int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
-                               unsigned int *bytes, uint64_t *host_offset,
-                               QCowL2Meta **m);
+    int *num, uint64_t *host_offset, QCowL2Meta **m);
 uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
                                          uint64_t offset,
                                          int compressed_size);
@@ -577,7 +583,6 @@ int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c);
 void qcow2_cache_entry_mark_dirty(BlockDriverState *bs, Qcow2Cache *c,
      void *table);
 int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c);
-int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c);
 int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c,
     Qcow2Cache *dependency);
 void qcow2_cache_depends_on_flush(Qcow2Cache *c);
index dcd4f03..622f308 100644 (file)
@@ -234,7 +234,8 @@ int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix)
     }
 
     check.result->bfi.total_clusters =
-        DIV_ROUND_UP(s->header.image_size, s->header.cluster_size);
+        (s->header.image_size + s->header.cluster_size - 1) /
+            s->header.cluster_size;
     ret = qed_check_l1_table(&check, s->l1_table);
     if (ret == 0) {
         /* Only check for leaks if entire image was scanned successfully */
index 1a731df..802945f 100644 (file)
@@ -16,7 +16,6 @@
 #include "trace.h"
 #include "qemu/sockets.h" /* for EINPROGRESS on Windows */
 #include "qed.h"
-#include "qemu/bswap.h"
 
 typedef struct {
     GenericCB gencb;
@@ -65,7 +64,7 @@ static void qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
     read_table_cb->iov.iov_len = s->header.cluster_size * s->header.table_size,
 
     qemu_iovec_init_external(qiov, &read_table_cb->iov, 1);
-    bdrv_aio_readv(s->bs->file, offset / BDRV_SECTOR_SIZE, qiov,
+    bdrv_aio_readv(s->bs->file->bs, offset / BDRV_SECTOR_SIZE, qiov,
                    qiov->size / BDRV_SECTOR_SIZE,
                    qed_read_table_cb, read_table_cb);
 }
@@ -154,7 +153,7 @@ static void qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
     /* Adjust for offset into table */
     offset += start * sizeof(uint64_t);
 
-    bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE,
+    bdrv_aio_writev(s->bs->file->bs, offset / BDRV_SECTOR_SIZE,
                     &write_table_cb->qiov,
                     write_table_cb->qiov.size / BDRV_SECTOR_SIZE,
                     qed_write_table_cb, write_table_cb);
index 426f3cb..0af5274 100644 (file)
@@ -15,7 +15,6 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu/timer.h"
-#include "qemu/bswap.h"
 #include "trace.h"
 #include "qed.h"
 #include "qapi/qmp/qerror.h"
@@ -86,7 +85,7 @@ int qed_write_header_sync(BDRVQEDState *s)
     int ret;
 
     qed_header_cpu_to_le(&s->header, &le);
-    ret = bdrv_pwrite(s->bs->file, 0, &le, sizeof(le));
+    ret = bdrv_pwrite(s->bs->file->bs, 0, &le, sizeof(le));
     if (ret != sizeof(le)) {
         return ret;
     }
@@ -123,7 +122,7 @@ static void qed_write_header_read_cb(void *opaque, int ret)
     /* Update header */
     qed_header_cpu_to_le(&s->header, (QEDHeader *)write_header_cb->buf);
 
-    bdrv_aio_writev(s->bs->file, 0, &write_header_cb->qiov,
+    bdrv_aio_writev(s->bs->file->bs, 0, &write_header_cb->qiov,
                     write_header_cb->nsectors, qed_write_header_cb,
                     write_header_cb);
 }
@@ -143,7 +142,8 @@ static void qed_write_header(BDRVQEDState *s, BlockCompletionFunc cb,
      * them, and write back.
      */
 
-    int nsectors = DIV_ROUND_UP(sizeof(QEDHeader), BDRV_SECTOR_SIZE);
+    int nsectors = (sizeof(QEDHeader) + BDRV_SECTOR_SIZE - 1) /
+                   BDRV_SECTOR_SIZE;
     size_t len = nsectors * BDRV_SECTOR_SIZE;
     QEDWriteHeaderCB *write_header_cb = gencb_alloc(sizeof(*write_header_cb),
                                                     cb, opaque);
@@ -155,7 +155,7 @@ static void qed_write_header(BDRVQEDState *s, BlockCompletionFunc cb,
     write_header_cb->iov.iov_len = len;
     qemu_iovec_init_external(&write_header_cb->qiov, &write_header_cb->iov, 1);
 
-    bdrv_aio_readv(s->bs->file, 0, &write_header_cb->qiov, nsectors,
+    bdrv_aio_readv(s->bs->file->bs, 0, &write_header_cb->qiov, nsectors,
                    qed_write_header_read_cb, write_header_cb);
 }
 
@@ -218,7 +218,7 @@ static bool qed_is_image_size_valid(uint64_t image_size, uint32_t cluster_size,
  *
  * The string is NUL-terminated.
  */
-static int qed_read_string(BdrvChild *file, uint64_t offset, size_t n,
+static int qed_read_string(BlockDriverState *file, uint64_t offset, size_t n,
                            char *buf, size_t buflen)
 {
     int ret;
@@ -389,7 +389,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
     s->bs = bs;
     QSIMPLEQ_INIT(&s->allocating_write_reqs);
 
-    ret = bdrv_pread(bs->file, 0, &le_header, sizeof(le_header));
+    ret = bdrv_pread(bs->file->bs, 0, &le_header, sizeof(le_header));
     if (ret < 0) {
         return ret;
     }
@@ -446,7 +446,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
             return -EINVAL;
         }
 
-        ret = qed_read_string(bs->file, s->header.backing_filename_offset,
+        ret = qed_read_string(bs->file->bs, s->header.backing_filename_offset,
                               s->header.backing_filename_size, bs->backing_file,
                               sizeof(bs->backing_file));
         if (ret < 0) {
@@ -517,7 +517,7 @@ static void bdrv_qed_refresh_limits(BlockDriverState *bs, Error **errp)
 {
     BDRVQEDState *s = bs->opaque;
 
-    bs->bl.pwrite_zeroes_alignment = s->header.cluster_size;
+    bs->bl.write_zeroes_alignment = s->header.cluster_size >> BDRV_SECTOR_BITS;
 }
 
 /* We have nothing to do for QED reopen, stubs just return
@@ -601,18 +601,18 @@ static int qed_create(const char *filename, uint32_t cluster_size,
     }
 
     qed_header_cpu_to_le(&header, &le_header);
-    ret = blk_pwrite(blk, 0, &le_header, sizeof(le_header), 0);
+    ret = blk_pwrite(blk, 0, &le_header, sizeof(le_header));
     if (ret < 0) {
         goto out;
     }
     ret = blk_pwrite(blk, sizeof(le_header), backing_file,
-                     header.backing_filename_size, 0);
+                     header.backing_filename_size);
     if (ret < 0) {
         goto out;
     }
 
     l1_table = g_malloc0(l1_size);
-    ret = blk_pwrite(blk, header.l1_table_offset, l1_table, l1_size, 0);
+    ret = blk_pwrite(blk, header.l1_table_offset, l1_table, l1_size);
     if (ret < 0) {
         goto out;
     }
@@ -708,7 +708,7 @@ static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t l
     }
 
     if (cb->co) {
-        qemu_coroutine_enter(cb->co);
+        qemu_coroutine_enter(cb->co, NULL);
     }
 }
 
@@ -800,7 +800,7 @@ static void qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
     qemu_iovec_concat(*backing_qiov, qiov, 0, size);
 
     BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
-    bdrv_aio_readv(s->bs->backing, pos / BDRV_SECTOR_SIZE,
+    bdrv_aio_readv(s->bs->backing->bs, pos / BDRV_SECTOR_SIZE,
                    *backing_qiov, size / BDRV_SECTOR_SIZE, cb, opaque);
 }
 
@@ -837,7 +837,7 @@ static void qed_copy_from_backing_file_write(void *opaque, int ret)
     }
 
     BLKDBG_EVENT(s->bs->file, BLKDBG_COW_WRITE);
-    bdrv_aio_writev(s->bs->file, copy_cb->offset / BDRV_SECTOR_SIZE,
+    bdrv_aio_writev(s->bs->file->bs, copy_cb->offset / BDRV_SECTOR_SIZE,
                     &copy_cb->qiov, copy_cb->qiov.size / BDRV_SECTOR_SIZE,
                     qed_copy_from_backing_file_cb, copy_cb);
 }
@@ -1087,7 +1087,7 @@ static void qed_aio_write_main(void *opaque, int ret)
     }
 
     BLKDBG_EVENT(s->bs->file, BLKDBG_WRITE_AIO);
-    bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE,
+    bdrv_aio_writev(s->bs->file->bs, offset / BDRV_SECTOR_SIZE,
                     &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE,
                     next_fn, acb);
 }
@@ -1319,7 +1319,7 @@ static void qed_aio_read_data(void *opaque, int ret,
     }
 
     BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
-    bdrv_aio_readv(bs->file, offset / BDRV_SECTOR_SIZE,
+    bdrv_aio_readv(bs->file->bs, offset / BDRV_SECTOR_SIZE,
                    &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE,
                    qed_aio_next_io, acb);
     return;
@@ -1418,21 +1418,21 @@ typedef struct {
     bool done;
 } QEDWriteZeroesCB;
 
-static void coroutine_fn qed_co_pwrite_zeroes_cb(void *opaque, int ret)
+static void coroutine_fn qed_co_write_zeroes_cb(void *opaque, int ret)
 {
     QEDWriteZeroesCB *cb = opaque;
 
     cb->done = true;
     cb->ret = ret;
     if (cb->co) {
-        qemu_coroutine_enter(cb->co);
+        qemu_coroutine_enter(cb->co, NULL);
     }
 }
 
-static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
-                                                  int64_t offset,
-                                                  int count,
-                                                  BdrvRequestFlags flags)
+static int coroutine_fn bdrv_qed_co_write_zeroes(BlockDriverState *bs,
+                                                 int64_t sector_num,
+                                                 int nb_sectors,
+                                                 BdrvRequestFlags flags)
 {
     BlockAIOCB *blockacb;
     BDRVQEDState *s = bs->opaque;
@@ -1440,22 +1440,25 @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
     QEMUIOVector qiov;
     struct iovec iov;
 
-    /* Fall back if the request is not aligned */
-    if (qed_offset_into_cluster(s, offset) ||
-        qed_offset_into_cluster(s, count)) {
-        return -ENOTSUP;
+    /* Refuse if there are untouched backing file sectors */
+    if (bs->backing) {
+        if (qed_offset_into_cluster(s, sector_num * BDRV_SECTOR_SIZE) != 0) {
+            return -ENOTSUP;
+        }
+        if (qed_offset_into_cluster(s, nb_sectors * BDRV_SECTOR_SIZE) != 0) {
+            return -ENOTSUP;
+        }
     }
 
     /* Zero writes start without an I/O buffer.  If a buffer becomes necessary
      * then it will be allocated during request processing.
      */
-    iov.iov_base = NULL;
-    iov.iov_len = count;
+    iov.iov_base = NULL,
+    iov.iov_len  = nb_sectors * BDRV_SECTOR_SIZE,
 
     qemu_iovec_init_external(&qiov, &iov, 1);
-    blockacb = qed_aio_setup(bs, offset >> BDRV_SECTOR_BITS, &qiov,
-                             count >> BDRV_SECTOR_BITS,
-                             qed_co_pwrite_zeroes_cb, &cb,
+    blockacb = qed_aio_setup(bs, sector_num, &qiov, nb_sectors,
+                             qed_co_write_zeroes_cb, &cb,
                              QED_AIOCB_WRITE | QED_AIOCB_ZERO);
     if (!blockacb) {
         return -EIO;
@@ -1575,7 +1578,7 @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs,
     }
 
     /* Write new header */
-    ret = bdrv_pwrite_sync(bs->file, 0, buffer, buffer_len);
+    ret = bdrv_pwrite_sync(bs->file->bs, 0, buffer, buffer_len);
     g_free(buffer);
     if (ret == 0) {
         memcpy(&s->header, &new_header, sizeof(new_header));
@@ -1591,6 +1594,12 @@ static void bdrv_qed_invalidate_cache(BlockDriverState *bs, Error **errp)
 
     bdrv_qed_close(bs);
 
+    bdrv_invalidate_cache(bs->file->bs, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
     memset(s, 0, sizeof(BDRVQEDState));
     ret = bdrv_qed_open(bs, NULL, bs->open_flags, &local_err);
     if (local_err) {
@@ -1660,7 +1669,7 @@ static BlockDriver bdrv_qed = {
     .bdrv_co_get_block_status = bdrv_qed_co_get_block_status,
     .bdrv_aio_readv           = bdrv_qed_aio_readv,
     .bdrv_aio_writev          = bdrv_qed_aio_writev,
-    .bdrv_co_pwrite_zeroes    = bdrv_qed_co_pwrite_zeroes,
+    .bdrv_co_write_zeroes     = bdrv_qed_co_write_zeroes,
     .bdrv_truncate            = bdrv_qed_truncate,
     .bdrv_getlength           = bdrv_qed_getlength,
     .bdrv_get_info            = bdrv_qed_get_info,
index 9cf876f..da15465 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu/cutils.h"
 #include "block/block_int.h"
 #include "qapi/qmp/qbool.h"
 #include "qapi/qmp/qdict.h"
@@ -68,9 +67,6 @@ typedef struct QuorumVotes {
 typedef struct BDRVQuorumState {
     BdrvChild **children;  /* children BlockDriverStates */
     int num_children;      /* children count */
-    unsigned next_child_index;  /* the index of the next child that should
-                                 * be added
-                                 */
     int threshold;         /* if less than threshold children reads gave the
                             * same result a quorum error occurs.
                             */
@@ -383,7 +379,7 @@ static bool quorum_rewrite_bad_versions(BDRVQuorumState *s, QuorumAIOCB *acb,
             continue;
         }
         QLIST_FOREACH(item, &version->items, next) {
-            bdrv_aio_writev(s->children[item->index], acb->sector_num,
+            bdrv_aio_writev(s->children[item->index]->bs, acb->sector_num,
                             acb->qiov, acb->nb_sectors, quorum_rewrite_aio_cb,
                             acb);
         }
@@ -660,7 +656,7 @@ static BlockAIOCB *read_quorum_children(QuorumAIOCB *acb)
     }
 
     for (i = 0; i < s->num_children; i++) {
-        acb->qcrs[i].aiocb = bdrv_aio_readv(s->children[i], acb->sector_num,
+        acb->qcrs[i].aiocb = bdrv_aio_readv(s->children[i]->bs, acb->sector_num,
                                             &acb->qcrs[i].qiov, acb->nb_sectors,
                                             quorum_aio_cb, &acb->qcrs[i]);
     }
@@ -678,7 +674,7 @@ static BlockAIOCB *read_fifo_child(QuorumAIOCB *acb)
     qemu_iovec_clone(&acb->qcrs[acb->child_iter].qiov, acb->qiov,
                      acb->qcrs[acb->child_iter].buf);
     acb->qcrs[acb->child_iter].aiocb =
-        bdrv_aio_readv(s->children[acb->child_iter], acb->sector_num,
+        bdrv_aio_readv(s->children[acb->child_iter]->bs, acb->sector_num,
                        &acb->qcrs[acb->child_iter].qiov, acb->nb_sectors,
                        quorum_aio_cb, &acb->qcrs[acb->child_iter]);
 
@@ -719,7 +715,7 @@ static BlockAIOCB *quorum_aio_writev(BlockDriverState *bs,
     int i;
 
     for (i = 0; i < s->num_children; i++) {
-        acb->qcrs[i].aiocb = bdrv_aio_writev(s->children[i], sector_num,
+        acb->qcrs[i].aiocb = bdrv_aio_writev(s->children[i]->bs, sector_num,
                                              qiov, nb_sectors, &quorum_aio_cb,
                                              &acb->qcrs[i]);
     }
@@ -751,6 +747,21 @@ static int64_t quorum_getlength(BlockDriverState *bs)
     return result;
 }
 
+static void quorum_invalidate_cache(BlockDriverState *bs, Error **errp)
+{
+    BDRVQuorumState *s = bs->opaque;
+    Error *local_err = NULL;
+    int i;
+
+    for (i = 0; i < s->num_children; i++) {
+        bdrv_invalidate_cache(s->children[i]->bs, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
+    }
+}
+
 static coroutine_fn int quorum_co_flush(BlockDriverState *bs)
 {
     BDRVQuorumState *s = bs->opaque;
@@ -887,9 +898,9 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
         ret = -EINVAL;
         goto exit;
     }
-    if (s->num_children < 1) {
+    if (s->num_children < 2) {
         error_setg(&local_err,
-                   "Number of provided children must be 1 or more");
+                   "Number of provided children must be greater than 1");
         ret = -EINVAL;
         goto exit;
     }
@@ -953,7 +964,6 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
 
         opened[i] = true;
     }
-    s->next_child_index = s->num_children;
 
     g_free(opened);
     goto exit;
@@ -971,7 +981,9 @@ close_exit:
 exit:
     qemu_opts_del(opts);
     /* propagate error */
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
     return ret;
 }
 
@@ -987,70 +999,25 @@ static void quorum_close(BlockDriverState *bs)
     g_free(s->children);
 }
 
-static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs,
-                             Error **errp)
+static void quorum_detach_aio_context(BlockDriverState *bs)
 {
     BDRVQuorumState *s = bs->opaque;
-    BdrvChild *child;
-    char indexstr[32];
-    int ret;
-
-    assert(s->num_children <= INT_MAX / sizeof(BdrvChild *));
-    if (s->num_children == INT_MAX / sizeof(BdrvChild *) ||
-        s->next_child_index == UINT_MAX) {
-        error_setg(errp, "Too many children");
-        return;
-    }
+    int i;
 
-    ret = snprintf(indexstr, 32, "children.%u", s->next_child_index);
-    if (ret < 0 || ret >= 32) {
-        error_setg(errp, "cannot generate child name");
-        return;
+    for (i = 0; i < s->num_children; i++) {
+        bdrv_detach_aio_context(s->children[i]->bs);
     }
-    s->next_child_index++;
-
-    bdrv_drained_begin(bs);
-
-    /* We can safely add the child now */
-    bdrv_ref(child_bs);
-    child = bdrv_attach_child(bs, child_bs, indexstr, &child_format);
-    s->children = g_renew(BdrvChild *, s->children, s->num_children + 1);
-    s->children[s->num_children++] = child;
-
-    bdrv_drained_end(bs);
 }
 
-static void quorum_del_child(BlockDriverState *bs, BdrvChild *child,
-                             Error **errp)
+static void quorum_attach_aio_context(BlockDriverState *bs,
+                                      AioContext *new_context)
 {
     BDRVQuorumState *s = bs->opaque;
     int i;
 
     for (i = 0; i < s->num_children; i++) {
-        if (s->children[i] == child) {
-            break;
-        }
+        bdrv_attach_aio_context(s->children[i]->bs, new_context);
     }
-
-    /* we have checked it in bdrv_del_child() */
-    assert(i < s->num_children);
-
-    if (s->num_children <= s->threshold) {
-        error_setg(errp,
-            "The number of children cannot be lower than the vote threshold %d",
-            s->threshold);
-        return;
-    }
-
-    bdrv_drained_begin(bs);
-
-    /* We can safely remove this child now */
-    memmove(&s->children[i], &s->children[i + 1],
-            (s->num_children - i - 1) * sizeof(BdrvChild *));
-    s->children = g_renew(BdrvChild *, s->children, --s->num_children);
-    bdrv_unref_child(bs, child);
-
-    bdrv_drained_end(bs);
 }
 
 static void quorum_refresh_filename(BlockDriverState *bs, QDict *options)
@@ -1103,9 +1070,10 @@ static BlockDriver bdrv_quorum = {
 
     .bdrv_aio_readv                     = quorum_aio_readv,
     .bdrv_aio_writev                    = quorum_aio_writev,
+    .bdrv_invalidate_cache              = quorum_invalidate_cache,
 
-    .bdrv_add_child                     = quorum_add_child,
-    .bdrv_del_child                     = quorum_del_child,
+    .bdrv_detach_aio_context            = quorum_detach_aio_context,
+    .bdrv_attach_aio_context            = quorum_attach_aio_context,
 
     .is_filter                          = true,
     .bdrv_recurse_is_first_non_filter   = quorum_recurse_is_first_non_filter,
similarity index 74%
rename from include/block/raw-aio.h
rename to block/raw-aio.h
index a4cdbbf..811e375 100644 (file)
@@ -15,7 +15,6 @@
 #ifndef QEMU_RAW_AIO_H
 #define QEMU_RAW_AIO_H
 
-#include "qemu/coroutine.h"
 #include "qemu/iov.h"
 
 /* AIO request types */
 
 /* linux-aio.c - Linux native implementation */
 #ifdef CONFIG_LINUX_AIO
-typedef struct LinuxAioState LinuxAioState;
-LinuxAioState *laio_init(void);
-void laio_cleanup(LinuxAioState *s);
-int coroutine_fn laio_co_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
-                                uint64_t offset, QEMUIOVector *qiov, int type);
-BlockAIOCB *laio_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
+void *laio_init(void);
+void laio_cleanup(void *s);
+BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
         BlockCompletionFunc *cb, void *opaque, int type);
-void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context);
-void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context);
-void laio_io_plug(BlockDriverState *bs, LinuxAioState *s);
-void laio_io_unplug(BlockDriverState *bs, LinuxAioState *s);
+void laio_detach_aio_context(void *s, AioContext *old_context);
+void laio_attach_aio_context(void *s, AioContext *new_context);
+void laio_io_plug(BlockDriverState *bs, void *aio_ctx);
+void laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug);
 #endif
 
 #ifdef _WIN32
index 6ed7547..906d5c9 100644 (file)
@@ -32,7 +32,7 @@
 #include "trace.h"
 #include "block/thread-pool.h"
 #include "qemu/iov.h"
-#include "block/raw-aio.h"
+#include "raw-aio.h"
 #include "qapi/util.h"
 #include "qapi/qmp/qstring.h"
 
@@ -137,6 +137,10 @@ typedef struct BDRVRawState {
     int open_flags;
     size_t buf_align;
 
+#ifdef CONFIG_LINUX_AIO
+    int use_aio;
+    void *aio_ctx;
+#endif
 #ifdef CONFIG_XFS
     bool is_xfs:1;
 #endif
@@ -150,6 +154,9 @@ typedef struct BDRVRawState {
 typedef struct BDRVRawReopenState {
     int fd;
     int open_flags;
+#ifdef CONFIG_LINUX_AIO
+    int use_aio;
+#endif
 } BDRVRawReopenState;
 
 static int fd_open(BlockDriverState *bs);
@@ -295,22 +302,22 @@ static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp)
     /* For SCSI generic devices the alignment is not really used.
        With buffered I/O, we don't have any restrictions. */
     if (bdrv_is_sg(bs) || !s->needs_alignment) {
-        bs->bl.request_alignment = 1;
+        bs->request_alignment = 1;
         s->buf_align = 1;
         return;
     }
 
-    bs->bl.request_alignment = 0;
+    bs->request_alignment = 0;
     s->buf_align = 0;
     /* Let's try to use the logical blocksize for the alignment. */
-    if (probe_logical_blocksize(fd, &bs->bl.request_alignment) < 0) {
-        bs->bl.request_alignment = 0;
+    if (probe_logical_blocksize(fd, &bs->request_alignment) < 0) {
+        bs->request_alignment = 0;
     }
 #ifdef CONFIG_XFS
     if (s->is_xfs) {
         struct dioattr da;
         if (xfsctl(NULL, fd, XFS_IOC_DIOINFO, &da) >= 0) {
-            bs->bl.request_alignment = da.d_miniosz;
+            bs->request_alignment = da.d_miniosz;
             /* The kernel returns wrong information for d_mem */
             /* s->buf_align = da.d_mem; */
         }
@@ -330,21 +337,21 @@ static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp)
         qemu_vfree(buf);
     }
 
-    if (!bs->bl.request_alignment) {
+    if (!bs->request_alignment) {
         size_t align;
         buf = qemu_memalign(s->buf_align, max_align);
         for (align = 512; align <= max_align; align <<= 1) {
             if (raw_is_io_aligned(fd, buf, align)) {
-                bs->bl.request_alignment = align;
+                bs->request_alignment = align;
                 break;
             }
         }
         qemu_vfree(buf);
     }
 
-    if (!s->buf_align || !bs->bl.request_alignment) {
-        error_setg(errp, "Could not find working O_DIRECT alignment");
-        error_append_hint(errp, "Try cache.direct=off\n");
+    if (!s->buf_align || !bs->request_alignment) {
+        error_setg(errp, "Could not find working O_DIRECT alignment. "
+                         "Try cache.direct=off.");
     }
 }
 
@@ -367,15 +374,58 @@ static void raw_parse_flags(int bdrv_flags, int *open_flags)
     }
 }
 
+static void raw_detach_aio_context(BlockDriverState *bs)
+{
+#ifdef CONFIG_LINUX_AIO
+    BDRVRawState *s = bs->opaque;
+
+    if (s->use_aio) {
+        laio_detach_aio_context(s->aio_ctx, bdrv_get_aio_context(bs));
+    }
+#endif
+}
+
+static void raw_attach_aio_context(BlockDriverState *bs,
+                                   AioContext *new_context)
+{
+#ifdef CONFIG_LINUX_AIO
+    BDRVRawState *s = bs->opaque;
+
+    if (s->use_aio) {
+        laio_attach_aio_context(s->aio_ctx, new_context);
+    }
+#endif
+}
+
 #ifdef CONFIG_LINUX_AIO
-static bool raw_use_aio(int bdrv_flags)
+static int raw_set_aio(void **aio_ctx, int *use_aio, int bdrv_flags)
 {
+    int ret = -1;
+    assert(aio_ctx != NULL);
+    assert(use_aio != NULL);
     /*
      * Currently Linux do AIO only for files opened with O_DIRECT
      * specified so check NOCACHE flag too
      */
-    return (bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
-                         (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO);
+    if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
+                      (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) {
+
+        /* if non-NULL, laio_init() has already been run */
+        if (*aio_ctx == NULL) {
+            *aio_ctx = laio_init();
+            if (!*aio_ctx) {
+                goto error;
+            }
+        }
+        *use_aio = 1;
+    } else {
+        *use_aio = 0;
+    }
+
+    ret = 0;
+
+error:
+    return ret;
 }
 #endif
 
@@ -444,7 +494,13 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
     s->fd = fd;
 
 #ifdef CONFIG_LINUX_AIO
-    if (!raw_use_aio(bdrv_flags) && (bdrv_flags & BDRV_O_NATIVE_AIO)) {
+    if (raw_set_aio(&s->aio_ctx, &s->use_aio, bdrv_flags)) {
+        qemu_close(fd);
+        ret = -errno;
+        error_setg_errno(errp, -ret, "Could not set AIO state");
+        goto fail;
+    }
+    if (!s->use_aio && (bdrv_flags & BDRV_O_NATIVE_AIO)) {
         error_setg(errp, "aio=native was specified, but it requires "
                          "cache.direct=on, which was not specified.");
         ret = -EINVAL;
@@ -461,7 +517,6 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
 
     s->has_discard = true;
     s->has_write_zeroes = true;
-    bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP;
     if ((bs->open_flags & BDRV_O_NOCACHE) != 0) {
         s->needs_alignment = true;
     }
@@ -511,6 +566,8 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
     }
 #endif
 
+    raw_attach_aio_context(bs, bdrv_get_aio_context(bs));
+
     ret = 0;
 fail:
     if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
@@ -524,9 +581,15 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
                     Error **errp)
 {
     BDRVRawState *s = bs->opaque;
+    Error *local_err = NULL;
+    int ret;
 
     s->type = FTYPE_FILE;
-    return raw_open_common(bs, options, flags, 0, errp);
+    ret = raw_open_common(bs, options, flags, 0, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
+    return ret;
 }
 
 static int raw_reopen_prepare(BDRVReopenState *state,
@@ -545,6 +608,18 @@ static int raw_reopen_prepare(BDRVReopenState *state,
     state->opaque = g_new0(BDRVRawReopenState, 1);
     raw_s = state->opaque;
 
+#ifdef CONFIG_LINUX_AIO
+    raw_s->use_aio = s->use_aio;
+
+    /* we can use s->aio_ctx instead of a copy, because the use_aio flag is
+     * valid in the 'false' condition even if aio_ctx is set, and raw_set_aio()
+     * won't override aio_ctx if aio_ctx is non-NULL */
+    if (raw_set_aio(&s->aio_ctx, &raw_s->use_aio, state->flags)) {
+        error_setg(errp, "Could not set AIO state");
+        return -1;
+    }
+#endif
+
     if (s->type == FTYPE_CD) {
         raw_s->open_flags |= O_NONBLOCK;
     }
@@ -569,7 +644,15 @@ static int raw_reopen_prepare(BDRVReopenState *state,
 
     if ((raw_s->open_flags & ~fcntl_flags) == (s->open_flags & ~fcntl_flags)) {
         /* dup the original fd */
-        raw_s->fd = qemu_dup(s->fd);
+        /* TODO: use qemu fcntl wrapper */
+#ifdef F_DUPFD_CLOEXEC
+        raw_s->fd = fcntl(s->fd, F_DUPFD_CLOEXEC, 0);
+#else
+        raw_s->fd = dup(s->fd);
+        if (raw_s->fd != -1) {
+            qemu_set_cloexec(raw_s->fd);
+        }
+#endif
         if (raw_s->fd >= 0) {
             ret = fcntl_setfl(raw_s->fd, raw_s->open_flags);
             if (ret) {
@@ -619,6 +702,9 @@ static void raw_reopen_commit(BDRVReopenState *state)
 
     qemu_close(s->fd);
     s->fd = raw_s->fd;
+#ifdef CONFIG_LINUX_AIO
+    s->use_aio = raw_s->use_aio;
+#endif
 
     g_free(state->opaque);
     state->opaque = NULL;
@@ -642,33 +728,9 @@ static void raw_reopen_abort(BDRVReopenState *state)
     state->opaque = NULL;
 }
 
-static int hdev_get_max_transfer_length(int fd)
-{
-#ifdef BLKSECTGET
-    int max_sectors = 0;
-    if (ioctl(fd, BLKSECTGET, &max_sectors) == 0) {
-        return max_sectors;
-    } else {
-        return -errno;
-    }
-#else
-    return -ENOSYS;
-#endif
-}
-
 static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
 {
     BDRVRawState *s = bs->opaque;
-    struct stat st;
-
-    if (!fstat(s->fd, &st)) {
-        if (S_ISBLK(st.st_mode)) {
-            int ret = hdev_get_max_transfer_length(s->fd);
-            if (ret > 0 && ret <= BDRV_REQUEST_MAX_SECTORS) {
-                bs->bl.max_transfer = pow2floor(ret << BDRV_SECTOR_BITS);
-            }
-        }
-    }
 
     raw_probe_alignment(bs, s->fd, errp);
     bs->bl.min_mem_alignment = s->buf_align;
@@ -1189,8 +1251,8 @@ static int aio_worker(void *arg)
 }
 
 static int paio_submit_co(BlockDriverState *bs, int fd,
-                          int64_t offset, QEMUIOVector *qiov,
-                          int count, int type)
+        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+        int type)
 {
     RawPosixAIOData *acb = g_new(RawPosixAIOData, 1);
     ThreadPool *pool;
@@ -1199,22 +1261,22 @@ static int paio_submit_co(BlockDriverState *bs, int fd,
     acb->aio_type = type;
     acb->aio_fildes = fd;
 
-    acb->aio_nbytes = count;
-    acb->aio_offset = offset;
+    acb->aio_nbytes = nb_sectors * BDRV_SECTOR_SIZE;
+    acb->aio_offset = sector_num * BDRV_SECTOR_SIZE;
 
     if (qiov) {
         acb->aio_iov = qiov->iov;
         acb->aio_niov = qiov->niov;
-        assert(qiov->size == count);
+        assert(qiov->size == acb->aio_nbytes);
     }
 
-    trace_paio_submit_co(offset, count, type);
+    trace_paio_submit_co(sector_num, nb_sectors, type);
     pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
     return thread_pool_submit_co(pool, aio_worker, acb);
 }
 
 static BlockAIOCB *paio_submit(BlockDriverState *bs, int fd,
-        int64_t offset, QEMUIOVector *qiov, int count,
+        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
         BlockCompletionFunc *cb, void *opaque, int type)
 {
     RawPosixAIOData *acb = g_new(RawPosixAIOData, 1);
@@ -1224,8 +1286,8 @@ static BlockAIOCB *paio_submit(BlockDriverState *bs, int fd,
     acb->aio_type = type;
     acb->aio_fildes = fd;
 
-    acb->aio_nbytes = count;
-    acb->aio_offset = offset;
+    acb->aio_nbytes = nb_sectors * BDRV_SECTOR_SIZE;
+    acb->aio_offset = sector_num * BDRV_SECTOR_SIZE;
 
     if (qiov) {
         acb->aio_iov = qiov->iov;
@@ -1233,18 +1295,19 @@ static BlockAIOCB *paio_submit(BlockDriverState *bs, int fd,
         assert(qiov->size == acb->aio_nbytes);
     }
 
-    trace_paio_submit(acb, opaque, offset, count, type);
+    trace_paio_submit(acb, opaque, sector_num, nb_sectors, type);
     pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
     return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
 }
 
-static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
-                                   uint64_t bytes, QEMUIOVector *qiov, int type)
+static BlockAIOCB *raw_aio_submit(BlockDriverState *bs,
+        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+        BlockCompletionFunc *cb, void *opaque, int type)
 {
     BDRVRawState *s = bs->opaque;
 
     if (fd_open(bs) < 0)
-        return -EIO;
+        return NULL;
 
     /*
      * Check if the underlying device requires requests to be aligned,
@@ -1256,52 +1319,63 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
         if (!bdrv_qiov_is_aligned(bs, qiov)) {
             type |= QEMU_AIO_MISALIGNED;
 #ifdef CONFIG_LINUX_AIO
-        } else if (bs->open_flags & BDRV_O_NATIVE_AIO) {
-            LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs));
-            assert(qiov->size == bytes);
-            return laio_co_submit(bs, aio, s->fd, offset, qiov, type);
+        } else if (s->use_aio) {
+            return laio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov,
+                               nb_sectors, cb, opaque, type);
 #endif
         }
     }
 
-    return paio_submit_co(bs, s->fd, offset, qiov, bytes, type);
-}
-
-static int coroutine_fn raw_co_preadv(BlockDriverState *bs, uint64_t offset,
-                                      uint64_t bytes, QEMUIOVector *qiov,
-                                      int flags)
-{
-    return raw_co_prw(bs, offset, bytes, qiov, QEMU_AIO_READ);
+    return paio_submit(bs, s->fd, sector_num, qiov, nb_sectors,
+                       cb, opaque, type);
 }
 
-static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, uint64_t offset,
-                                       uint64_t bytes, QEMUIOVector *qiov,
-                                       int flags)
+static void raw_aio_plug(BlockDriverState *bs)
 {
-    assert(flags == 0);
-    return raw_co_prw(bs, offset, bytes, qiov, QEMU_AIO_WRITE);
+#ifdef CONFIG_LINUX_AIO
+    BDRVRawState *s = bs->opaque;
+    if (s->use_aio) {
+        laio_io_plug(bs, s->aio_ctx);
+    }
+#endif
 }
 
-static void raw_aio_plug(BlockDriverState *bs)
+static void raw_aio_unplug(BlockDriverState *bs)
 {
 #ifdef CONFIG_LINUX_AIO
-    if (bs->open_flags & BDRV_O_NATIVE_AIO) {
-        LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs));
-        laio_io_plug(bs, aio);
+    BDRVRawState *s = bs->opaque;
+    if (s->use_aio) {
+        laio_io_unplug(bs, s->aio_ctx, true);
     }
 #endif
 }
 
-static void raw_aio_unplug(BlockDriverState *bs)
+static void raw_aio_flush_io_queue(BlockDriverState *bs)
 {
 #ifdef CONFIG_LINUX_AIO
-    if (bs->open_flags & BDRV_O_NATIVE_AIO) {
-        LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs));
-        laio_io_unplug(bs, aio);
+    BDRVRawState *s = bs->opaque;
+    if (s->use_aio) {
+        laio_io_unplug(bs, s->aio_ctx, false);
     }
 #endif
 }
 
+static BlockAIOCB *raw_aio_readv(BlockDriverState *bs,
+        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+        BlockCompletionFunc *cb, void *opaque)
+{
+    return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
+                          cb, opaque, QEMU_AIO_READ);
+}
+
+static BlockAIOCB *raw_aio_writev(BlockDriverState *bs,
+        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+        BlockCompletionFunc *cb, void *opaque)
+{
+    return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
+                          cb, opaque, QEMU_AIO_WRITE);
+}
+
 static BlockAIOCB *raw_aio_flush(BlockDriverState *bs,
         BlockCompletionFunc *cb, void *opaque)
 {
@@ -1317,6 +1391,13 @@ static void raw_close(BlockDriverState *bs)
 {
     BDRVRawState *s = bs->opaque;
 
+    raw_detach_aio_context(bs);
+
+#ifdef CONFIG_LINUX_AIO
+    if (s->use_aio) {
+        laio_cleanup(s->aio_ctx);
+    }
+#endif
     if (s->fd >= 0) {
         qemu_close(s->fd);
         s->fd = -1;
@@ -1786,27 +1867,27 @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
     return ret | BDRV_BLOCK_OFFSET_VALID | start;
 }
 
-static coroutine_fn BlockAIOCB *raw_aio_pdiscard(BlockDriverState *bs,
-    int64_t offset, int count,
+static coroutine_fn BlockAIOCB *raw_aio_discard(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors,
     BlockCompletionFunc *cb, void *opaque)
 {
     BDRVRawState *s = bs->opaque;
 
-    return paio_submit(bs, s->fd, offset, NULL, count,
+    return paio_submit(bs, s->fd, sector_num, NULL, nb_sectors,
                        cb, opaque, QEMU_AIO_DISCARD);
 }
 
-static int coroutine_fn raw_co_pwrite_zeroes(
-    BlockDriverState *bs, int64_t offset,
-    int count, BdrvRequestFlags flags)
+static int coroutine_fn raw_co_write_zeroes(
+    BlockDriverState *bs, int64_t sector_num,
+    int nb_sectors, BdrvRequestFlags flags)
 {
     BDRVRawState *s = bs->opaque;
 
     if (!(flags & BDRV_REQ_MAY_UNMAP)) {
-        return paio_submit_co(bs, s->fd, offset, NULL, count,
+        return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors,
                               QEMU_AIO_WRITE_ZEROES);
     } else if (s->discard_zeroes) {
-        return paio_submit_co(bs, s->fd, offset, NULL, count,
+        return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors,
                               QEMU_AIO_DISCARD);
     }
     return -ENOTSUP;
@@ -1859,15 +1940,16 @@ BlockDriver bdrv_file = {
     .bdrv_create = raw_create,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
     .bdrv_co_get_block_status = raw_co_get_block_status,
-    .bdrv_co_pwrite_zeroes = raw_co_pwrite_zeroes,
+    .bdrv_co_write_zeroes = raw_co_write_zeroes,
 
-    .bdrv_co_preadv         = raw_co_preadv,
-    .bdrv_co_pwritev        = raw_co_pwritev,
+    .bdrv_aio_readv = raw_aio_readv,
+    .bdrv_aio_writev = raw_aio_writev,
     .bdrv_aio_flush = raw_aio_flush,
-    .bdrv_aio_pdiscard = raw_aio_pdiscard,
+    .bdrv_aio_discard = raw_aio_discard,
     .bdrv_refresh_limits = raw_refresh_limits,
     .bdrv_io_plug = raw_aio_plug,
     .bdrv_io_unplug = raw_aio_unplug,
+    .bdrv_flush_io_queue = raw_aio_flush_io_queue,
 
     .bdrv_truncate = raw_truncate,
     .bdrv_getlength = raw_getlength,
@@ -1875,6 +1957,9 @@ BlockDriver bdrv_file = {
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
 
+    .bdrv_detach_aio_context = raw_detach_aio_context,
+    .bdrv_attach_aio_context = raw_attach_aio_context,
+
     .create_opts = &raw_create_opts,
 };
 
@@ -2140,7 +2225,9 @@ hdev_open_Mac_error:
 
     ret = raw_open_common(bs, options, flags, 0, &local_err);
     if (ret < 0) {
-        error_propagate(errp, local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+        }
 #if defined(__APPLE__) && defined(__MACH__)
         if (*bsd_path) {
             filename = bsd_path;
@@ -2203,8 +2290,8 @@ static int fd_open(BlockDriverState *bs)
     return -EIO;
 }
 
-static coroutine_fn BlockAIOCB *hdev_aio_pdiscard(BlockDriverState *bs,
-    int64_t offset, int count,
+static coroutine_fn BlockAIOCB *hdev_aio_discard(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors,
     BlockCompletionFunc *cb, void *opaque)
 {
     BDRVRawState *s = bs->opaque;
@@ -2212,12 +2299,12 @@ static coroutine_fn BlockAIOCB *hdev_aio_pdiscard(BlockDriverState *bs,
     if (fd_open(bs) < 0) {
         return NULL;
     }
-    return paio_submit(bs, s->fd, offset, NULL, count,
+    return paio_submit(bs, s->fd, sector_num, NULL, nb_sectors,
                        cb, opaque, QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV);
 }
 
-static coroutine_fn int hdev_co_pwrite_zeroes(BlockDriverState *bs,
-    int64_t offset, int count, BdrvRequestFlags flags)
+static coroutine_fn int hdev_co_write_zeroes(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, BdrvRequestFlags flags)
 {
     BDRVRawState *s = bs->opaque;
     int rc;
@@ -2227,10 +2314,10 @@ static coroutine_fn int hdev_co_pwrite_zeroes(BlockDriverState *bs,
         return rc;
     }
     if (!(flags & BDRV_REQ_MAY_UNMAP)) {
-        return paio_submit_co(bs, s->fd, offset, NULL, count,
+        return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors,
                               QEMU_AIO_WRITE_ZEROES|QEMU_AIO_BLKDEV);
     } else if (s->discard_zeroes) {
-        return paio_submit_co(bs, s->fd, offset, NULL, count,
+        return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors,
                               QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV);
     }
     return -ENOTSUP;
@@ -2302,15 +2389,16 @@ static BlockDriver bdrv_host_device = {
     .bdrv_reopen_abort   = raw_reopen_abort,
     .bdrv_create         = hdev_create,
     .create_opts         = &raw_create_opts,
-    .bdrv_co_pwrite_zeroes = hdev_co_pwrite_zeroes,
+    .bdrv_co_write_zeroes = hdev_co_write_zeroes,
 
-    .bdrv_co_preadv         = raw_co_preadv,
-    .bdrv_co_pwritev        = raw_co_pwritev,
+    .bdrv_aio_readv    = raw_aio_readv,
+    .bdrv_aio_writev   = raw_aio_writev,
     .bdrv_aio_flush    = raw_aio_flush,
-    .bdrv_aio_pdiscard   = hdev_aio_pdiscard,
+    .bdrv_aio_discard   = hdev_aio_discard,
     .bdrv_refresh_limits = raw_refresh_limits,
     .bdrv_io_plug = raw_aio_plug,
     .bdrv_io_unplug = raw_aio_unplug,
+    .bdrv_flush_io_queue = raw_aio_flush_io_queue,
 
     .bdrv_truncate      = raw_truncate,
     .bdrv_getlength    = raw_getlength,
@@ -2320,6 +2408,9 @@ static BlockDriver bdrv_host_device = {
     .bdrv_probe_blocksizes = hdev_probe_blocksizes,
     .bdrv_probe_geometry = hdev_probe_geometry,
 
+    .bdrv_detach_aio_context = raw_detach_aio_context,
+    .bdrv_attach_aio_context = raw_attach_aio_context,
+
     /* generic scsi device */
 #ifdef __linux__
     .bdrv_aio_ioctl     = hdev_aio_ioctl,
@@ -2342,11 +2433,17 @@ static int cdrom_open(BlockDriverState *bs, QDict *options, int flags,
                       Error **errp)
 {
     BDRVRawState *s = bs->opaque;
+    Error *local_err = NULL;
+    int ret;
 
     s->type = FTYPE_CD;
 
     /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
-    return raw_open_common(bs, options, flags, O_NONBLOCK, errp);
+    ret = raw_open_common(bs, options, flags, O_NONBLOCK, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
+    return ret;
 }
 
 static int cdrom_probe_device(const char *filename)
@@ -2425,13 +2522,13 @@ static BlockDriver bdrv_host_cdrom = {
     .bdrv_create         = hdev_create,
     .create_opts         = &raw_create_opts,
 
-
-    .bdrv_co_preadv         = raw_co_preadv,
-    .bdrv_co_pwritev        = raw_co_pwritev,
+    .bdrv_aio_readv     = raw_aio_readv,
+    .bdrv_aio_writev    = raw_aio_writev,
     .bdrv_aio_flush    = raw_aio_flush,
     .bdrv_refresh_limits = raw_refresh_limits,
     .bdrv_io_plug = raw_aio_plug,
     .bdrv_io_unplug = raw_aio_unplug,
+    .bdrv_flush_io_queue = raw_aio_flush_io_queue,
 
     .bdrv_truncate      = raw_truncate,
     .bdrv_getlength      = raw_getlength,
@@ -2439,6 +2536,9 @@ static BlockDriver bdrv_host_cdrom = {
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
 
+    .bdrv_detach_aio_context = raw_detach_aio_context,
+    .bdrv_attach_aio_context = raw_attach_aio_context,
+
     /* removable device support */
     .bdrv_is_inserted   = cdrom_is_inserted,
     .bdrv_eject         = cdrom_eject,
@@ -2461,7 +2561,9 @@ static int cdrom_open(BlockDriverState *bs, QDict *options, int flags,
 
     ret = raw_open_common(bs, options, flags, 0, &local_err);
     if (ret) {
-        error_propagate(errp, local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+        }
         return ret;
     }
 
@@ -2556,12 +2658,13 @@ static BlockDriver bdrv_host_cdrom = {
     .bdrv_create        = hdev_create,
     .create_opts        = &raw_create_opts,
 
-    .bdrv_co_preadv         = raw_co_preadv,
-    .bdrv_co_pwritev        = raw_co_pwritev,
+    .bdrv_aio_readv     = raw_aio_readv,
+    .bdrv_aio_writev    = raw_aio_writev,
     .bdrv_aio_flush    = raw_aio_flush,
     .bdrv_refresh_limits = raw_refresh_limits,
     .bdrv_io_plug = raw_aio_plug,
     .bdrv_io_unplug = raw_aio_unplug,
+    .bdrv_flush_io_queue = raw_aio_flush_io_queue,
 
     .bdrv_truncate      = raw_truncate,
     .bdrv_getlength      = raw_getlength,
@@ -2569,6 +2672,9 @@ static BlockDriver bdrv_host_cdrom = {
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
 
+    .bdrv_detach_aio_context = raw_detach_aio_context,
+    .bdrv_attach_aio_context = raw_attach_aio_context,
+
     /* removable device support */
     .bdrv_is_inserted   = cdrom_is_inserted,
     .bdrv_eject         = cdrom_eject,
index 56f45fe..fd23891 100644 (file)
@@ -27,7 +27,7 @@
 #include "qemu/timer.h"
 #include "block/block_int.h"
 #include "qemu/module.h"
-#include "block/raw-aio.h"
+#include "raw-aio.h"
 #include "trace.h"
 #include "block/thread-pool.h"
 #include "qemu/iov.h"
@@ -142,7 +142,7 @@ static int aio_worker(void *arg)
 }
 
 static BlockAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
-        int64_t offset, QEMUIOVector *qiov, int count,
+        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
         BlockCompletionFunc *cb, void *opaque, int type)
 {
     RawWin32AIOData *acb = g_new(RawWin32AIOData, 1);
@@ -155,12 +155,11 @@ static BlockAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
     if (qiov) {
         acb->aio_iov = qiov->iov;
         acb->aio_niov = qiov->niov;
-        assert(qiov->size == count);
     }
-    acb->aio_nbytes = count;
-    acb->aio_offset = offset;
+    acb->aio_nbytes = nb_sectors * 512;
+    acb->aio_offset = sector_num * 512;
 
-    trace_paio_submit(acb, opaque, offset, count, type);
+    trace_paio_submit(acb, opaque, sector_num, nb_sectors, type);
     pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
     return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
 }
@@ -223,7 +222,7 @@ static void raw_attach_aio_context(BlockDriverState *bs,
     }
 }
 
-static void raw_probe_alignment(BlockDriverState *bs, Error **errp)
+static void raw_probe_alignment(BlockDriverState *bs)
 {
     BDRVRawState *s = bs->opaque;
     DWORD sectorsPerCluster, freeClusters, totalClusters, count;
@@ -231,14 +230,14 @@ static void raw_probe_alignment(BlockDriverState *bs, Error **errp)
     BOOL status;
 
     if (s->type == FTYPE_CD) {
-        bs->bl.request_alignment = 2048;
+        bs->request_alignment = 2048;
         return;
     }
     if (s->type == FTYPE_HARDDISK) {
         status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
                                  NULL, 0, &dg, sizeof(dg), &count, NULL);
         if (status != 0) {
-            bs->bl.request_alignment = dg.Geometry.BytesPerSector;
+            bs->request_alignment = dg.Geometry.BytesPerSector;
             return;
         }
         /* try GetDiskFreeSpace too */
@@ -248,7 +247,7 @@ static void raw_probe_alignment(BlockDriverState *bs, Error **errp)
         GetDiskFreeSpace(s->drive_path, &sectorsPerCluster,
                          &dg.Geometry.BytesPerSector,
                          &freeClusters, &totalClusters);
-        bs->bl.request_alignment = dg.Geometry.BytesPerSector;
+        bs->request_alignment = dg.Geometry.BytesPerSector;
     }
 }
 
@@ -366,6 +365,7 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
         win32_aio_attach_aio_context(s->aio, bdrv_get_aio_context(bs));
     }
 
+    raw_probe_alignment(bs);
     ret = 0;
 fail:
     qemu_opts_del(opts);
@@ -379,10 +379,9 @@ static BlockAIOCB *raw_aio_readv(BlockDriverState *bs,
     BDRVRawState *s = bs->opaque;
     if (s->aio) {
         return win32_aio_submit(bs, s->aio, s->hfile, sector_num, qiov,
-                                nb_sectors, cb, opaque, QEMU_AIO_READ);
+                                nb_sectors, cb, opaque, QEMU_AIO_READ); 
     } else {
-        return paio_submit(bs, s->hfile, sector_num << BDRV_SECTOR_BITS, qiov,
-                           nb_sectors << BDRV_SECTOR_BITS,
+        return paio_submit(bs, s->hfile, sector_num, qiov, nb_sectors,
                            cb, opaque, QEMU_AIO_READ);
     }
 }
@@ -394,10 +393,9 @@ static BlockAIOCB *raw_aio_writev(BlockDriverState *bs,
     BDRVRawState *s = bs->opaque;
     if (s->aio) {
         return win32_aio_submit(bs, s->aio, s->hfile, sector_num, qiov,
-                                nb_sectors, cb, opaque, QEMU_AIO_WRITE);
+                                nb_sectors, cb, opaque, QEMU_AIO_WRITE); 
     } else {
-        return paio_submit(bs, s->hfile, sector_num << BDRV_SECTOR_BITS, qiov,
-                           nb_sectors << BDRV_SECTOR_BITS,
+        return paio_submit(bs, s->hfile, sector_num, qiov, nb_sectors,
                            cb, opaque, QEMU_AIO_WRITE);
     }
 }
@@ -552,7 +550,6 @@ BlockDriver bdrv_file = {
     .bdrv_needs_filename = true,
     .bdrv_parse_filename = raw_parse_filename,
     .bdrv_file_open     = raw_open,
-    .bdrv_refresh_limits = raw_probe_alignment,
     .bdrv_close         = raw_close,
     .bdrv_create        = raw_create,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
index 588d408..a6cc7e9 100644 (file)
@@ -1,6 +1,6 @@
 /* BlockDriver implementation for "raw"
  *
- * Copyright (C) 2010-2016 Red Hat, Inc.
+ * Copyright (C) 2010, 2013, Red Hat, Inc.
  * Copyright (C) 2010, Blue Swirl <blauwirbel@gmail.com>
  * Copyright (C) 2009, Anthony Liguori <aliguori@us.ibm.com>
  *
@@ -50,30 +50,33 @@ static int raw_reopen_prepare(BDRVReopenState *reopen_state,
     return 0;
 }
 
-static int coroutine_fn raw_co_preadv(BlockDriverState *bs, uint64_t offset,
-                                      uint64_t bytes, QEMUIOVector *qiov,
-                                      int flags)
+static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num,
+                                     int nb_sectors, QEMUIOVector *qiov)
 {
     BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
-    return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
+    return bdrv_co_readv(bs->file->bs, sector_num, nb_sectors, qiov);
 }
 
-static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, uint64_t offset,
-                                       uint64_t bytes, QEMUIOVector *qiov,
-                                       int flags)
+static int coroutine_fn
+raw_co_writev_flags(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
+                    QEMUIOVector *qiov, int flags)
 {
     void *buf = NULL;
     BlockDriver *drv;
     QEMUIOVector local_qiov;
     int ret;
 
-    if (bs->probed && offset < BLOCK_PROBE_BUF_SIZE && bytes) {
-        /* Handling partial writes would be a pain - so we just
-         * require that guests have 512-byte request alignment if
-         * probing occurred */
+    if (bs->probed && sector_num == 0) {
+        /* As long as these conditions are true, we can't get partial writes to
+         * the probe buffer and can just directly check the request. */
         QEMU_BUILD_BUG_ON(BLOCK_PROBE_BUF_SIZE != 512);
         QEMU_BUILD_BUG_ON(BDRV_SECTOR_SIZE != 512);
-        assert(offset == 0 && bytes >= BLOCK_PROBE_BUF_SIZE);
+
+        if (nb_sectors == 0) {
+            /* qemu_iovec_to_buf() would fail, but we want to return success
+             * instead of -EINVAL in this case. */
+            return 0;
+        }
 
         buf = qemu_try_blockalign(bs->file->bs, 512);
         if (!buf) {
@@ -102,7 +105,8 @@ static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, uint64_t offset,
     }
 
     BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
-    ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
+    ret = bdrv_co_do_pwritev(bs->file->bs, sector_num * BDRV_SECTOR_SIZE,
+                             nb_sectors * BDRV_SECTOR_SIZE, qiov, flags);
 
 fail:
     if (qiov == &local_qiov) {
@@ -112,6 +116,13 @@ fail:
     return ret;
 }
 
+static int coroutine_fn
+raw_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
+              QEMUIOVector *qiov)
+{
+    return raw_co_writev_flags(bs, sector_num, nb_sectors, qiov, 0);
+}
+
 static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
                                             int64_t sector_num,
                                             int nb_sectors, int *pnum,
@@ -123,17 +134,17 @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
            (sector_num << BDRV_SECTOR_BITS);
 }
 
-static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,
-                                             int64_t offset, int count,
-                                             BdrvRequestFlags flags)
+static int coroutine_fn raw_co_write_zeroes(BlockDriverState *bs,
+                                            int64_t sector_num, int nb_sectors,
+                                            BdrvRequestFlags flags)
 {
-    return bdrv_co_pwrite_zeroes(bs->file, offset, count, flags);
+    return bdrv_co_write_zeroes(bs->file->bs, sector_num, nb_sectors, flags);
 }
 
-static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
-                                        int64_t offset, int count)
+static int coroutine_fn raw_co_discard(BlockDriverState *bs,
+                                       int64_t sector_num, int nb_sectors)
 {
-    return bdrv_co_pdiscard(bs->file->bs, offset, count);
+    return bdrv_co_discard(bs->file->bs, sector_num, nb_sectors);
 }
 
 static int64_t raw_getlength(BlockDriverState *bs)
@@ -148,12 +159,7 @@ static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
 
 static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
 {
-    if (bs->probed) {
-        /* To make it easier to protect the first sector, any probed
-         * image is restricted to read-modify-write on sub-sector
-         * operations. */
-        bs->bl.request_alignment = BDRV_SECTOR_SIZE;
-    }
+    bs->bl = bs->file->bs->bl;
 }
 
 static int raw_truncate(BlockDriverState *bs, int64_t offset)
@@ -191,17 +197,20 @@ static int raw_has_zero_init(BlockDriverState *bs)
 
 static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
 {
-    return bdrv_create_file(filename, opts, errp);
+    Error *local_err = NULL;
+    int ret;
+
+    ret = bdrv_create_file(filename, opts, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
+    return ret;
 }
 
 static int raw_open(BlockDriverState *bs, QDict *options, int flags,
                     Error **errp)
 {
     bs->sg = bs->file->bs->sg;
-    bs->supported_write_flags = BDRV_REQ_FUA &
-        bs->file->bs->supported_write_flags;
-    bs->supported_zero_flags = (BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
-        bs->file->bs->supported_zero_flags;
 
     if (bs->probed && !bdrv_is_read_only(bs)) {
         fprintf(stderr,
@@ -246,10 +255,12 @@ BlockDriver bdrv_raw = {
     .bdrv_open            = &raw_open,
     .bdrv_close           = &raw_close,
     .bdrv_create          = &raw_create,
-    .bdrv_co_preadv       = &raw_co_preadv,
-    .bdrv_co_pwritev      = &raw_co_pwritev,
-    .bdrv_co_pwrite_zeroes = &raw_co_pwrite_zeroes,
-    .bdrv_co_pdiscard     = &raw_co_pdiscard,
+    .bdrv_co_readv        = &raw_co_readv,
+    .bdrv_co_writev       = &raw_co_writev,
+    .bdrv_co_writev_flags = &raw_co_writev_flags,
+    .supported_write_flags = BDRV_REQ_FUA,
+    .bdrv_co_write_zeroes = &raw_co_write_zeroes,
+    .bdrv_co_discard      = &raw_co_discard,
     .bdrv_co_get_block_status = &raw_co_get_block_status,
     .bdrv_truncate        = &raw_truncate,
     .bdrv_getlength       = &raw_getlength,
index 0106fea..5bc5b32 100644 (file)
@@ -290,8 +290,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf,
             if (only_read_conf_file) {
                 ret = rados_conf_read_file(cluster, value);
                 if (ret < 0) {
-                    error_setg_errno(errp, -ret, "error reading conf file %s",
-                                     value);
+                    error_setg(errp, "error reading conf file %s", value);
                     break;
                 }
             }
@@ -300,7 +299,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf,
         } else if (!only_read_conf_file) {
             ret = rados_conf_set(cluster, name, value);
             if (ret < 0) {
-                error_setg_errno(errp, -ret, "invalid conf option %s", name);
+                error_setg(errp, "invalid conf option %s", name);
                 ret = -EINVAL;
                 break;
             }
@@ -355,10 +354,9 @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
     }
 
     clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
-    ret = rados_create(&cluster, clientname);
-    if (ret < 0) {
-        error_setg_errno(errp, -ret, "error initializing");
-        return ret;
+    if (rados_create(&cluster, clientname) < 0) {
+        error_setg(errp, "error initializing");
+        return -EIO;
     }
 
     if (strstr(conf, "conf=") == NULL) {
@@ -383,27 +381,21 @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
         return -EIO;
     }
 
-    ret = rados_connect(cluster);
-    if (ret < 0) {
-        error_setg_errno(errp, -ret, "error connecting");
+    if (rados_connect(cluster) < 0) {
+        error_setg(errp, "error connecting");
         rados_shutdown(cluster);
-        return ret;
+        return -EIO;
     }
 
-    ret = rados_ioctx_create(cluster, pool, &io_ctx);
-    if (ret < 0) {
-        error_setg_errno(errp, -ret, "error opening pool %s", pool);
+    if (rados_ioctx_create(cluster, pool, &io_ctx) < 0) {
+        error_setg(errp, "error opening pool %s", pool);
         rados_shutdown(cluster);
-        return ret;
+        return -EIO;
     }
 
     ret = rbd_create(io_ctx, name, bytes, &obj_order);
     rados_ioctx_destroy(io_ctx);
     rados_shutdown(cluster);
-    if (ret < 0) {
-        error_setg_errno(errp, -ret, "error rbd create");
-        return ret;
-    }
 
     return ret;
 }
@@ -508,7 +500,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
     clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
     r = rados_create(&s->cluster, clientname);
     if (r < 0) {
-        error_setg_errno(errp, -r, "error initializing");
+        error_setg(errp, "error initializing");
         goto failed_opts;
     }
 
@@ -554,19 +546,19 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
 
     r = rados_connect(s->cluster);
     if (r < 0) {
-        error_setg_errno(errp, -r, "error connecting");
+        error_setg(errp, "error connecting");
         goto failed_shutdown;
     }
 
     r = rados_ioctx_create(s->cluster, pool, &s->io_ctx);
     if (r < 0) {
-        error_setg_errno(errp, -r, "error opening pool %s", pool);
+        error_setg(errp, "error opening pool %s", pool);
         goto failed_shutdown;
     }
 
     r = rbd_open(s->io_ctx, s->name, &s->image, s->snap);
     if (r < 0) {
-        error_setg_errno(errp, -r, "error reading header from %s", s->name);
+        error_setg(errp, "error reading header from %s", s->name);
         goto failed_open;
     }
 
@@ -649,9 +641,9 @@ static int rbd_aio_flush_wrapper(rbd_image_t image,
 }
 
 static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
-                                 int64_t off,
+                                 int64_t sector_num,
                                  QEMUIOVector *qiov,
-                                 int64_t size,
+                                 int nb_sectors,
                                  BlockCompletionFunc *cb,
                                  void *opaque,
                                  RBDAIOCmd cmd)
@@ -659,6 +651,7 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
     RBDAIOCB *acb;
     RADOSCB *rcb = NULL;
     rbd_completion_t c;
+    int64_t off, size;
     char *buf;
     int r;
 
@@ -667,7 +660,6 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
     acb = qemu_aio_get(&rbd_aiocb_info, bs, cb, opaque);
     acb->cmd = cmd;
     acb->qiov = qiov;
-    assert(!qiov || qiov->size == size);
     if (cmd == RBD_AIO_DISCARD || cmd == RBD_AIO_FLUSH) {
         acb->bounce = NULL;
     } else {
@@ -687,6 +679,9 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
 
     buf = acb->bounce;
 
+    off = sector_num * BDRV_SECTOR_SIZE;
+    size = nb_sectors * BDRV_SECTOR_SIZE;
+
     rcb = g_new(RADOSCB, 1);
     rcb->acb = acb;
     rcb->buf = buf;
@@ -736,8 +731,7 @@ static BlockAIOCB *qemu_rbd_aio_readv(BlockDriverState *bs,
                                       BlockCompletionFunc *cb,
                                       void *opaque)
 {
-    return rbd_start_aio(bs, sector_num << BDRV_SECTOR_BITS, qiov,
-                         nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
+    return rbd_start_aio(bs, sector_num, qiov, nb_sectors, cb, opaque,
                          RBD_AIO_READ);
 }
 
@@ -748,8 +742,7 @@ static BlockAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
                                        BlockCompletionFunc *cb,
                                        void *opaque)
 {
-    return rbd_start_aio(bs, sector_num << BDRV_SECTOR_BITS, qiov,
-                         nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
+    return rbd_start_aio(bs, sector_num, qiov, nb_sectors, cb, opaque,
                          RBD_AIO_WRITE);
 }
 
@@ -882,8 +875,10 @@ static int qemu_rbd_snap_rollback(BlockDriverState *bs,
                                   const char *snapshot_name)
 {
     BDRVRBDState *s = bs->opaque;
+    int r;
 
-    return rbd_snap_rollback(s->image, snapshot_name);
+    r = rbd_snap_rollback(s->image, snapshot_name);
+    return r;
 }
 
 static int qemu_rbd_snap_list(BlockDriverState *bs,
@@ -930,13 +925,13 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
 }
 
 #ifdef LIBRBD_SUPPORTS_DISCARD
-static BlockAIOCB *qemu_rbd_aio_pdiscard(BlockDriverState *bs,
-                                         int64_t offset,
-                                         int count,
-                                         BlockCompletionFunc *cb,
-                                         void *opaque)
+static BlockAIOCB* qemu_rbd_aio_discard(BlockDriverState *bs,
+                                        int64_t sector_num,
+                                        int nb_sectors,
+                                        BlockCompletionFunc *cb,
+                                        void *opaque)
 {
-    return rbd_start_aio(bs, offset, NULL, count, cb, opaque,
+    return rbd_start_aio(bs, sector_num, NULL, nb_sectors, cb, opaque,
                          RBD_AIO_DISCARD);
 }
 #endif
@@ -1000,7 +995,7 @@ static BlockDriver bdrv_rbd = {
 #endif
 
 #ifdef LIBRBD_SUPPORTS_DISCARD
-    .bdrv_aio_pdiscard      = qemu_rbd_aio_pdiscard,
+    .bdrv_aio_discard       = qemu_rbd_aio_discard,
 #endif
 
     .bdrv_snapshot_create   = qemu_rbd_snap_create,
index 66e1cb2..33e0a33 100644 (file)
@@ -294,16 +294,13 @@ static inline size_t count_data_objs(const struct SheepdogInode *inode)
 
 #undef DPRINTF
 #ifdef DEBUG_SDOG
-#define DEBUG_SDOG_PRINT 1
+#define DPRINTF(fmt, args...)                                       \
+    do {                                                            \
+        fprintf(stdout, "%s %d: " fmt, __func__, __LINE__, ##args); \
+    } while (0)
 #else
-#define DEBUG_SDOG_PRINT 0
+#define DPRINTF(fmt, args...)
 #endif
-#define DPRINTF(fmt, args...)                                           \
-    do {                                                                \
-        if (DEBUG_SDOG_PRINT) {                                         \
-            fprintf(stderr, "%s %d: " fmt, __func__, __LINE__, ##args); \
-        }                                                               \
-    } while (0)
 
 typedef struct SheepdogAIOCB SheepdogAIOCB;
 
@@ -495,7 +492,7 @@ static inline void free_aio_req(BDRVSheepdogState *s, AIOReq *aio_req)
 
 static void coroutine_fn sd_finish_aiocb(SheepdogAIOCB *acb)
 {
-    qemu_coroutine_enter(acb->coroutine);
+    qemu_coroutine_enter(acb->coroutine, NULL);
     qemu_aio_unref(acb);
 }
 
@@ -636,7 +633,7 @@ static void restart_co_req(void *opaque)
 {
     Coroutine *co = opaque;
 
-    qemu_coroutine_enter(co);
+    qemu_coroutine_enter(co, NULL);
 }
 
 typedef struct SheepdogReqCo {
@@ -726,8 +723,8 @@ static int do_req(int sockfd, AioContext *aio_context, SheepdogReq *hdr,
     if (qemu_in_coroutine()) {
         do_co_req(&srco);
     } else {
-        co = qemu_coroutine_create(do_co_req, &srco);
-        qemu_coroutine_enter(co);
+        co = qemu_coroutine_create(do_co_req);
+        qemu_coroutine_enter(co, &srco);
         while (!srco.finished) {
             aio_poll(aio_context, true);
         }
@@ -925,17 +922,17 @@ static void co_read_response(void *opaque)
     BDRVSheepdogState *s = opaque;
 
     if (!s->co_recv) {
-        s->co_recv = qemu_coroutine_create(aio_read_response, opaque);
+        s->co_recv = qemu_coroutine_create(aio_read_response);
     }
 
-    qemu_coroutine_enter(s->co_recv);
+    qemu_coroutine_enter(s->co_recv, opaque);
 }
 
 static void co_write_request(void *opaque)
 {
     BDRVSheepdogState *s = opaque;
 
-    qemu_coroutine_enter(s->co_send);
+    qemu_coroutine_enter(s->co_send, NULL);
 }
 
 /*
@@ -1681,7 +1678,7 @@ static int sd_prealloc(const char *filename, Error **errp)
         if (ret < 0) {
             goto out;
         }
-        ret = blk_pwrite(blk, idx * buf_size, buf, buf_size, 0);
+        ret = blk_pwrite(blk, idx * buf_size, buf, buf_size);
         if (ret < 0) {
             goto out;
         }
@@ -2784,24 +2781,17 @@ static int sd_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
     return ret;
 }
 
-static int sd_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
-                           int64_t pos)
+static int sd_load_vmstate(BlockDriverState *bs, uint8_t *data,
+                           int64_t pos, int size)
 {
     BDRVSheepdogState *s = bs->opaque;
-    void *buf;
-    int ret;
 
-    buf = qemu_blockalign(bs, qiov->size);
-    ret = do_load_save_vmstate(s, buf, pos, qiov->size, 1);
-    qemu_iovec_from_buf(qiov, 0, buf, qiov->size);
-    qemu_vfree(buf);
-
-    return ret;
+    return do_load_save_vmstate(s, data, pos, size, 1);
 }
 
 
-static coroutine_fn int sd_co_pdiscard(BlockDriverState *bs, int64_t offset,
-                                      int count)
+static coroutine_fn int sd_co_discard(BlockDriverState *bs, int64_t sector_num,
+                                      int nb_sectors)
 {
     SheepdogAIOCB *acb;
     BDRVSheepdogState *s = bs->opaque;
@@ -2811,7 +2801,7 @@ static coroutine_fn int sd_co_pdiscard(BlockDriverState *bs, int64_t offset,
     uint32_t zero = 0;
 
     if (!s->discard_supported) {
-        return 0;
+            return 0;
     }
 
     memset(&discard_iov, 0, sizeof(discard_iov));
@@ -2820,10 +2810,7 @@ static coroutine_fn int sd_co_pdiscard(BlockDriverState *bs, int64_t offset,
     iov.iov_len = sizeof(zero);
     discard_iov.iov = &iov;
     discard_iov.niov = 1;
-    assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
-    assert((count & (BDRV_SECTOR_SIZE - 1)) == 0);
-    acb = sd_aio_setup(bs, &discard_iov, offset >> BDRV_SECTOR_BITS,
-                       count >> BDRV_SECTOR_BITS);
+    acb = sd_aio_setup(bs, &discard_iov, sector_num, nb_sectors);
     acb->aiocb_type = AIOCB_DISCARD_OBJ;
     acb->aio_done_func = sd_finish_aiocb;
 
@@ -2957,7 +2944,7 @@ static BlockDriver bdrv_sheepdog = {
     .bdrv_co_readv  = sd_co_readv,
     .bdrv_co_writev = sd_co_writev,
     .bdrv_co_flush_to_disk  = sd_co_flush_to_disk,
-    .bdrv_co_pdiscard = sd_co_pdiscard,
+    .bdrv_co_discard = sd_co_discard,
     .bdrv_co_get_block_status = sd_co_get_block_status,
 
     .bdrv_snapshot_create   = sd_snapshot_create,
@@ -2993,7 +2980,7 @@ static BlockDriver bdrv_sheepdog_tcp = {
     .bdrv_co_readv  = sd_co_readv,
     .bdrv_co_writev = sd_co_writev,
     .bdrv_co_flush_to_disk  = sd_co_flush_to_disk,
-    .bdrv_co_pdiscard = sd_co_pdiscard,
+    .bdrv_co_discard = sd_co_discard,
     .bdrv_co_get_block_status = sd_co_get_block_status,
 
     .bdrv_snapshot_create   = sd_snapshot_create,
@@ -3029,7 +3016,7 @@ static BlockDriver bdrv_sheepdog_unix = {
     .bdrv_co_readv  = sd_co_readv,
     .bdrv_co_writev = sd_co_writev,
     .bdrv_co_flush_to_disk  = sd_co_flush_to_disk,
-    .bdrv_co_pdiscard = sd_co_pdiscard,
+    .bdrv_co_discard = sd_co_discard,
     .bdrv_co_get_block_status = sd_co_get_block_status,
 
     .bdrv_snapshot_create   = sd_snapshot_create,
index bf5c2ca..e9d721d 100644 (file)
@@ -358,7 +358,9 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
         ret = bdrv_snapshot_load_tmp(bs, NULL, id_or_name, &local_err);
     }
 
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
 
     return ret;
 }
@@ -371,10 +373,9 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
 bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs)
 {
     bool ok = true;
-    BlockDriverState *bs;
-    BdrvNextIterator it;
+    BlockDriverState *bs = NULL;
 
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+    while (ok && (bs = bdrv_next(bs))) {
         AioContext *ctx = bdrv_get_aio_context(bs);
 
         aio_context_acquire(ctx);
@@ -382,12 +383,8 @@ bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs)
             ok = bdrv_can_snapshot(bs);
         }
         aio_context_release(ctx);
-        if (!ok) {
-            goto fail;
-        }
     }
 
-fail:
     *first_bad_bs = bs;
     return ok;
 }
@@ -396,11 +393,10 @@ int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs,
                              Error **err)
 {
     int ret = 0;
-    BlockDriverState *bs;
-    BdrvNextIterator it;
+    BlockDriverState *bs = NULL;
     QEMUSnapshotInfo sn1, *snapshot = &sn1;
 
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+    while (ret == 0 && (bs = bdrv_next(bs))) {
         AioContext *ctx = bdrv_get_aio_context(bs);
 
         aio_context_acquire(ctx);
@@ -409,12 +405,8 @@ int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs,
             ret = bdrv_snapshot_delete_by_id_or_name(bs, name, err);
         }
         aio_context_release(ctx);
-        if (ret < 0) {
-            goto fail;
-        }
     }
 
-fail:
     *first_bad_bs = bs;
     return ret;
 }
@@ -423,10 +415,9 @@ fail:
 int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs)
 {
     int err = 0;
-    BlockDriverState *bs;
-    BdrvNextIterator it;
+    BlockDriverState *bs = NULL;
 
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+    while (err == 0 && (bs = bdrv_next(bs))) {
         AioContext *ctx = bdrv_get_aio_context(bs);
 
         aio_context_acquire(ctx);
@@ -434,12 +425,8 @@ int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs)
             err = bdrv_snapshot_goto(bs, name);
         }
         aio_context_release(ctx);
-        if (err < 0) {
-            goto fail;
-        }
     }
 
-fail:
     *first_bad_bs = bs;
     return err;
 }
@@ -448,10 +435,9 @@ int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs)
 {
     QEMUSnapshotInfo sn;
     int err = 0;
-    BlockDriverState *bs;
-    BdrvNextIterator it;
+    BlockDriverState *bs = NULL;
 
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+    while (err == 0 && (bs = bdrv_next(bs))) {
         AioContext *ctx = bdrv_get_aio_context(bs);
 
         aio_context_acquire(ctx);
@@ -459,12 +445,8 @@ int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs)
             err = bdrv_snapshot_find(bs, &sn, name);
         }
         aio_context_release(ctx);
-        if (err < 0) {
-            goto fail;
-        }
     }
 
-fail:
     *first_bad_bs = bs;
     return err;
 }
@@ -475,10 +457,9 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
                              BlockDriverState **first_bad_bs)
 {
     int err = 0;
-    BlockDriverState *bs;
-    BdrvNextIterator it;
+    BlockDriverState *bs = NULL;
 
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+    while (err == 0 && (bs = bdrv_next(bs))) {
         AioContext *ctx = bdrv_get_aio_context(bs);
 
         aio_context_acquire(ctx);
@@ -490,32 +471,23 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
             err = bdrv_snapshot_create(bs, sn);
         }
         aio_context_release(ctx);
-        if (err < 0) {
-            goto fail;
-        }
     }
 
-fail:
     *first_bad_bs = bs;
     return err;
 }
 
 BlockDriverState *bdrv_all_find_vmstate_bs(void)
 {
-    BlockDriverState *bs;
-    BdrvNextIterator it;
+    bool not_found = true;
+    BlockDriverState *bs = NULL;
 
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+    while (not_found && (bs = bdrv_next(bs))) {
         AioContext *ctx = bdrv_get_aio_context(bs);
-        bool found;
 
         aio_context_acquire(ctx);
-        found = bdrv_can_snapshot(bs);
+        not_found = !bdrv_can_snapshot(bs);
         aio_context_release(ctx);
-
-        if (found) {
-            break;
-        }
     }
     return bs;
 }
index 5ce12b6..06928ed 100644 (file)
@@ -508,73 +508,36 @@ static int authenticate(BDRVSSHState *s, const char *user, Error **errp)
     return ret;
 }
 
-static QemuOptsList ssh_runtime_opts = {
-    .name = "ssh",
-    .head = QTAILQ_HEAD_INITIALIZER(ssh_runtime_opts.head),
-    .desc = {
-        {
-            .name = "host",
-            .type = QEMU_OPT_STRING,
-            .help = "Host to connect to",
-        },
-        {
-            .name = "port",
-            .type = QEMU_OPT_NUMBER,
-            .help = "Port to connect to",
-        },
-        {
-            .name = "path",
-            .type = QEMU_OPT_STRING,
-            .help = "Path of the image on the host",
-        },
-        {
-            .name = "user",
-            .type = QEMU_OPT_STRING,
-            .help = "User as which to connect",
-        },
-        {
-            .name = "host_key_check",
-            .type = QEMU_OPT_STRING,
-            .help = "Defines how and what to check the host key against",
-        },
-    },
-};
-
 static int connect_to_ssh(BDRVSSHState *s, QDict *options,
                           int ssh_flags, int creat_mode, Error **errp)
 {
     int r, ret;
-    QemuOpts *opts = NULL;
-    Error *local_err = NULL;
     const char *host, *user, *path, *host_key_check;
     int port;
 
-    opts = qemu_opts_create(&ssh_runtime_opts, NULL, 0, &error_abort);
-    qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (local_err) {
-        ret = -EINVAL;
-        error_propagate(errp, local_err);
-        goto err;
-    }
-
-    host = qemu_opt_get(opts, "host");
-    if (!host) {
+    if (!qdict_haskey(options, "host")) {
         ret = -EINVAL;
         error_setg(errp, "No hostname was specified");
         goto err;
     }
+    host = qdict_get_str(options, "host");
 
-    port = qemu_opt_get_number(opts, "port", 22);
+    if (qdict_haskey(options, "port")) {
+        port = qdict_get_int(options, "port");
+    } else {
+        port = 22;
+    }
 
-    path = qemu_opt_get(opts, "path");
-    if (!path) {
+    if (!qdict_haskey(options, "path")) {
         ret = -EINVAL;
         error_setg(errp, "No path was specified");
         goto err;
     }
+    path = qdict_get_str(options, "path");
 
-    user = qemu_opt_get(opts, "user");
-    if (!user) {
+    if (qdict_haskey(options, "user")) {
+        user = qdict_get_str(options, "user");
+    } else {
         user = g_get_user_name();
         if (!user) {
             error_setg_errno(errp, errno, "Can't get user name");
@@ -583,8 +546,9 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
         }
     }
 
-    host_key_check = qemu_opt_get(opts, "host_key_check");
-    if (!host_key_check) {
+    if (qdict_haskey(options, "host_key_check")) {
+        host_key_check = qdict_get_str(options, "host_key_check");
+    } else {
         host_key_check = "yes";
     }
 
@@ -648,14 +612,21 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
         goto err;
     }
 
-    qemu_opts_del(opts);
-
     r = libssh2_sftp_fstat(s->sftp_handle, &s->attrs);
     if (r < 0) {
         sftp_error_setg(errp, s, "failed to read file attributes");
         return -EINVAL;
     }
 
+    /* Delete the options we've used; any not deleted will cause the
+     * block layer to give an error about unused options.
+     */
+    qdict_del(options, "host");
+    qdict_del(options, "port");
+    qdict_del(options, "user");
+    qdict_del(options, "path");
+    qdict_del(options, "host_key_check");
+
     return 0;
 
  err:
@@ -675,8 +646,6 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
     }
     s->session = NULL;
 
-    qemu_opts_del(opts);
-
     return ret;
 }
 
@@ -808,7 +777,7 @@ static void restart_coroutine(void *opaque)
 
     DPRINTF("co=%p", co);
 
-    qemu_coroutine_enter(co);
+    qemu_coroutine_enter(co, NULL);
 }
 
 static coroutine_fn void set_fd_handler(BDRVSSHState *s, BlockDriverState *bs)
index 3187481..332b9a1 100644 (file)
@@ -39,7 +39,7 @@ typedef struct StreamBlockJob {
     char *backing_file_str;
 } StreamBlockJob;
 
-static int coroutine_fn stream_populate(BlockBackend *blk,
+static int coroutine_fn stream_populate(BlockDriverState *bs,
                                         int64_t sector_num, int nb_sectors,
                                         void *buf)
 {
@@ -52,8 +52,7 @@ static int coroutine_fn stream_populate(BlockBackend *blk,
     qemu_iovec_init_external(&qiov, &iov, 1);
 
     /* Copy-on-read the unallocated clusters */
-    return blk_co_preadv(blk, sector_num * BDRV_SECTOR_SIZE, qiov.size, &qiov,
-                         BDRV_REQ_COPY_ON_READ);
+    return bdrv_co_copy_on_readv(bs, sector_num, nb_sectors, &qiov);
 }
 
 typedef struct {
@@ -65,7 +64,6 @@ static void stream_complete(BlockJob *job, void *opaque)
 {
     StreamBlockJob *s = container_of(job, StreamBlockJob, common);
     StreamCompleteData *data = opaque;
-    BlockDriverState *bs = blk_bs(job->blk);
     BlockDriverState *base = s->base;
 
     if (!block_job_is_cancelled(&s->common) && data->reached_end &&
@@ -77,8 +75,8 @@ static void stream_complete(BlockJob *job, void *opaque)
                 base_fmt = base->drv->format_name;
             }
         }
-        data->ret = bdrv_change_backing_file(bs, base_id, base_fmt);
-        bdrv_set_backing_hd(bs, base);
+        data->ret = bdrv_change_backing_file(job->bs, base_id, base_fmt);
+        bdrv_set_backing_hd(job->bs, base);
     }
 
     g_free(s->backing_file_str);
@@ -90,12 +88,10 @@ static void coroutine_fn stream_run(void *opaque)
 {
     StreamBlockJob *s = opaque;
     StreamCompleteData *data;
-    BlockBackend *blk = s->common.blk;
-    BlockDriverState *bs = blk_bs(blk);
+    BlockDriverState *bs = s->common.bs;
     BlockDriverState *base = s->base;
     int64_t sector_num = 0;
     int64_t end = -1;
-    uint64_t delay_ns = 0;
     int error = 0;
     int ret = 0;
     int n = 0;
@@ -124,8 +120,10 @@ static void coroutine_fn stream_run(void *opaque)
     }
 
     for (sector_num = 0; sector_num < end; sector_num += n) {
+        uint64_t delay_ns = 0;
         bool copy;
 
+wait:
         /* Note that even when no rate limit is applied we need to yield
          * with no pending I/O here so that bdrv_drain_all() returns.
          */
@@ -155,11 +153,18 @@ static void coroutine_fn stream_run(void *opaque)
         }
         trace_stream_one_iteration(s, sector_num, n, ret);
         if (copy) {
-            ret = stream_populate(blk, sector_num, n, buf);
+            if (s->common.speed) {
+                delay_ns = ratelimit_calculate_delay(&s->limit, n);
+                if (delay_ns > 0) {
+                    goto wait;
+                }
+            }
+            ret = stream_populate(bs, sector_num, n, buf);
         }
         if (ret < 0) {
             BlockErrorAction action =
-                block_job_error_action(&s->common, s->on_error, true, -ret);
+                block_job_error_action(&s->common, s->common.bs, s->on_error,
+                                       true, -ret);
             if (action == BLOCK_ERROR_ACTION_STOP) {
                 n = 0;
                 continue;
@@ -175,9 +180,6 @@ static void coroutine_fn stream_run(void *opaque)
 
         /* Publish progress */
         s->common.offset += n * BDRV_SECTOR_SIZE;
-        if (copy && s->common.speed) {
-            delay_ns = ratelimit_calculate_delay(&s->limit, n);
-        }
     }
 
     if (!base) {
@@ -214,15 +216,22 @@ static const BlockJobDriver stream_job_driver = {
     .set_speed     = stream_set_speed,
 };
 
-void stream_start(const char *job_id, BlockDriverState *bs,
-                  BlockDriverState *base, const char *backing_file_str,
-                  int64_t speed, BlockdevOnError on_error,
-                  BlockCompletionFunc *cb, void *opaque, Error **errp)
+void stream_start(BlockDriverState *bs, BlockDriverState *base,
+                  const char *backing_file_str, int64_t speed,
+                  BlockdevOnError on_error,
+                  BlockCompletionFunc *cb,
+                  void *opaque, Error **errp)
 {
     StreamBlockJob *s;
 
-    s = block_job_create(job_id, &stream_job_driver, bs, speed,
-                         cb, opaque, errp);
+    if ((on_error == BLOCKDEV_ON_ERROR_STOP ||
+         on_error == BLOCKDEV_ON_ERROR_ENOSPC) &&
+        (!bs->blk || !blk_iostatus_is_enabled(bs->blk))) {
+        error_setg(errp, QERR_INVALID_PARAMETER, "on-error");
+        return;
+    }
+
+    s = block_job_create(&stream_job_driver, bs, speed, cb, opaque, errp);
     if (!s) {
         return;
     }
@@ -231,7 +240,7 @@ void stream_start(const char *job_id, BlockDriverState *bs,
     s->backing_file_str = g_strdup(backing_file_str);
 
     s->on_error = on_error;
-    s->common.co = qemu_coroutine_create(stream_run, s);
+    s->common.co = qemu_coroutine_create(stream_run);
     trace_stream_start(bs, base, s, s->common.co, opaque);
-    qemu_coroutine_enter(s->common.co);
+    qemu_coroutine_enter(s->common.co, s);
 }
index 59545e2..4920e09 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "sysemu/block-backend.h"
 #include "block/throttle-groups.h"
 #include "qemu/queue.h"
 #include "qemu/thread.h"
 #include "sysemu/qtest.h"
 
 /* The ThrottleGroup structure (with its ThrottleState) is shared
- * among different BlockBackends and it's independent from
+ * among different BlockDriverState and it's independent from
  * AioContext, so in order to use it from different threads it needs
  * its own locking.
  *
  * The whole ThrottleGroup structure is private and invisible to
  * outside users, that only use it through its ThrottleState.
  *
- * In addition to the ThrottleGroup structure, BlockBackendPublic has
+ * In addition to the ThrottleGroup structure, BlockDriverState has
  * fields that need to be accessed by other members of the group and
- * therefore also need to be protected by this lock. Once a
- * BlockBackend is registered in a group those fields can be accessed
- * by other threads any time.
+ * therefore also need to be protected by this lock. Once a BDS is
+ * registered in a group those fields can be accessed by other threads
+ * any time.
  *
  * Again, all this is handled internally and is mostly transparent to
  * the outside. The 'throttle_timers' field however has an additional
  * constraint because it may be temporarily invalid (see for example
  * bdrv_set_aio_context()). Therefore in this file a thread will
- * access some other BlockBackend's timers only after verifying that
- * that BlockBackend has throttled requests in the queue.
+ * access some other BDS's timers only after verifying that that BDS
+ * has throttled requests in the queue.
  */
 typedef struct ThrottleGroup {
     char *name; /* This is constant during the lifetime of the group */
 
     QemuMutex lock; /* This lock protects the following four fields */
     ThrottleState ts;
-    QLIST_HEAD(, BlockBackendPublic) head;
-    BlockBackend *tokens[2];
+    QLIST_HEAD(, BlockDriverState) head;
+    BlockDriverState *tokens[2];
     bool any_timer_armed[2];
 
     /* These two are protected by the global throttle_groups_lock */
@@ -133,98 +132,93 @@ void throttle_group_unref(ThrottleState *ts)
     qemu_mutex_unlock(&throttle_groups_lock);
 }
 
-/* Get the name from a BlockBackend's ThrottleGroup. The name (and the pointer)
- * is guaranteed to remain constant during the lifetime of the group.
+/* Get the name from a BlockDriverState's ThrottleGroup. The name (and
+ * the pointer) is guaranteed to remain constant during the lifetime
+ * of the group.
  *
- * @blk:  a BlockBackend that is member of a throttling group
+ * @bs:   a BlockDriverState that is member of a throttling group
  * @ret:  the name of the group.
  */
-const char *throttle_group_get_name(BlockBackend *blk)
+const char *throttle_group_get_name(BlockDriverState *bs)
 {
-    BlockBackendPublic *blkp = blk_get_public(blk);
-    ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
+    ThrottleGroup *tg = container_of(bs->throttle_state, ThrottleGroup, ts);
     return tg->name;
 }
 
-/* Return the next BlockBackend in the round-robin sequence, simulating a
- * circular list.
+/* Return the next BlockDriverState in the round-robin sequence,
+ * simulating a circular list.
  *
  * This assumes that tg->lock is held.
  *
- * @blk: the current BlockBackend
- * @ret: the next BlockBackend in the sequence
+ * @bs:  the current BlockDriverState
+ * @ret: the next BlockDriverState in the sequence
  */
-static BlockBackend *throttle_group_next_blk(BlockBackend *blk)
+static BlockDriverState *throttle_group_next_bs(BlockDriverState *bs)
 {
-    BlockBackendPublic *blkp = blk_get_public(blk);
-    ThrottleState *ts = blkp->throttle_state;
+    ThrottleState *ts = bs->throttle_state;
     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
-    BlockBackendPublic *next = QLIST_NEXT(blkp, round_robin);
+    BlockDriverState *next = QLIST_NEXT(bs, round_robin);
 
     if (!next) {
-        next = QLIST_FIRST(&tg->head);
+        return QLIST_FIRST(&tg->head);
     }
 
-    return blk_by_public(next);
+    return next;
 }
 
-/* Return the next BlockBackend in the round-robin sequence with pending I/O
- * requests.
+/* Return the next BlockDriverState in the round-robin sequence with
+ * pending I/O requests.
  *
  * This assumes that tg->lock is held.
  *
- * @blk:       the current BlockBackend
+ * @bs:        the current BlockDriverState
  * @is_write:  the type of operation (read/write)
- * @ret:       the next BlockBackend with pending requests, or blk if there is
- *             none.
+ * @ret:       the next BlockDriverState with pending requests, or bs
+ *             if there is none.
  */
-static BlockBackend *next_throttle_token(BlockBackend *blk, bool is_write)
+static BlockDriverState *next_throttle_token(BlockDriverState *bs,
+                                             bool is_write)
 {
-    BlockBackendPublic *blkp = blk_get_public(blk);
-    ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
-    BlockBackend *token, *start;
+    ThrottleGroup *tg = container_of(bs->throttle_state, ThrottleGroup, ts);
+    BlockDriverState *token, *start;
 
     start = token = tg->tokens[is_write];
 
     /* get next bs round in round robin style */
-    token = throttle_group_next_blk(token);
-    while (token != start && !blkp->pending_reqs[is_write]) {
-        token = throttle_group_next_blk(token);
+    token = throttle_group_next_bs(token);
+    while (token != start && !token->pending_reqs[is_write]) {
+        token = throttle_group_next_bs(token);
     }
 
     /* If no IO are queued for scheduling on the next round robin token
      * then decide the token is the current bs because chances are
      * the current bs get the current request queued.
      */
-    if (token == start && !blkp->pending_reqs[is_write]) {
-        token = blk;
+    if (token == start && !token->pending_reqs[is_write]) {
+        token = bs;
     }
 
     return token;
 }
 
-/* Check if the next I/O request for a BlockBackend needs to be throttled or
- * not. If there's no timer set in this group, set one and update the token
- * accordingly.
+/* Check if the next I/O request for a BlockDriverState needs to be
+ * throttled or not. If there's no timer set in this group, set one
+ * and update the token accordingly.
  *
  * This assumes that tg->lock is held.
  *
- * @blk:        the current BlockBackend
+ * @bs:         the current BlockDriverState
  * @is_write:   the type of operation (read/write)
  * @ret:        whether the I/O request needs to be throttled or not
  */
-static bool throttle_group_schedule_timer(BlockBackend *blk, bool is_write)
+static bool throttle_group_schedule_timer(BlockDriverState *bs,
+                                          bool is_write)
 {
-    BlockBackendPublic *blkp = blk_get_public(blk);
-    ThrottleState *ts = blkp->throttle_state;
-    ThrottleTimers *tt = &blkp->throttle_timers;
+    ThrottleState *ts = bs->throttle_state;
+    ThrottleTimers *tt = &bs->throttle_timers;
     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
     bool must_wait;
 
-    if (blkp->io_limits_disabled) {
-        return false;
-    }
-
     /* Check if any of the timers in this group is already armed */
     if (tg->any_timer_armed[is_write]) {
         return true;
@@ -232,9 +226,9 @@ static bool throttle_group_schedule_timer(BlockBackend *blk, bool is_write)
 
     must_wait = throttle_schedule_timer(ts, tt, is_write);
 
-    /* If a timer just got armed, set blk as the current token */
+    /* If a timer just got armed, set bs as the current token */
     if (must_wait) {
-        tg->tokens[is_write] = blk;
+        tg->tokens[is_write] = bs;
         tg->any_timer_armed[is_write] = true;
     }
 
@@ -245,19 +239,18 @@ static bool throttle_group_schedule_timer(BlockBackend *blk, bool is_write)
  *
  * This assumes that tg->lock is held.
  *
- * @blk:       the current BlockBackend
+ * @bs:        the current BlockDriverState
  * @is_write:  the type of operation (read/write)
  */
-static void schedule_next_request(BlockBackend *blk, bool is_write)
+static void schedule_next_request(BlockDriverState *bs, bool is_write)
 {
-    BlockBackendPublic *blkp = blk_get_public(blk);
-    ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
+    ThrottleGroup *tg = container_of(bs->throttle_state, ThrottleGroup, ts);
     bool must_wait;
-    BlockBackend *token;
+    BlockDriverState *token;
 
     /* Check if there's any pending request to schedule next */
-    token = next_throttle_token(blk, is_write);
-    if (!blkp->pending_reqs[is_write]) {
+    token = next_throttle_token(bs, is_write);
+    if (!token->pending_reqs[is_write]) {
         return;
     }
 
@@ -266,12 +259,12 @@ static void schedule_next_request(BlockBackend *blk, bool is_write)
 
     /* If it doesn't have to wait, queue it for immediate execution */
     if (!must_wait) {
-        /* Give preference to requests from the current blk */
+        /* Give preference to requests from the current bs */
         if (qemu_in_coroutine() &&
-            qemu_co_queue_next(&blkp->throttled_reqs[is_write])) {
-            token = blk;
+            qemu_co_queue_next(&bs->throttled_reqs[is_write])) {
+            token = bs;
         } else {
-            ThrottleTimers *tt = &blkp->throttle_timers;
+            ThrottleTimers *tt = &token->throttle_timers;
             int64_t now = qemu_clock_get_ns(tt->clock_type);
             timer_mod(tt->timers[is_write], now + 1);
             tg->any_timer_armed[is_write] = true;
@@ -284,67 +277,53 @@ static void schedule_next_request(BlockBackend *blk, bool is_write)
  * if necessary, and schedule the next request using a round robin
  * algorithm.
  *
- * @blk:       the current BlockBackend
+ * @bs:        the current BlockDriverState
  * @bytes:     the number of bytes for this I/O
  * @is_write:  the type of operation (read/write)
  */
-void coroutine_fn throttle_group_co_io_limits_intercept(BlockBackend *blk,
+void coroutine_fn throttle_group_co_io_limits_intercept(BlockDriverState *bs,
                                                         unsigned int bytes,
                                                         bool is_write)
 {
     bool must_wait;
-    BlockBackend *token;
+    BlockDriverState *token;
 
-    BlockBackendPublic *blkp = blk_get_public(blk);
-    ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
+    ThrottleGroup *tg = container_of(bs->throttle_state, ThrottleGroup, ts);
     qemu_mutex_lock(&tg->lock);
 
     /* First we check if this I/O has to be throttled. */
-    token = next_throttle_token(blk, is_write);
+    token = next_throttle_token(bs, is_write);
     must_wait = throttle_group_schedule_timer(token, is_write);
 
     /* Wait if there's a timer set or queued requests of this type */
-    if (must_wait || blkp->pending_reqs[is_write]) {
-        blkp->pending_reqs[is_write]++;
+    if (must_wait || bs->pending_reqs[is_write]) {
+        bs->pending_reqs[is_write]++;
         qemu_mutex_unlock(&tg->lock);
-        qemu_co_queue_wait(&blkp->throttled_reqs[is_write]);
+        qemu_co_queue_wait(&bs->throttled_reqs[is_write]);
         qemu_mutex_lock(&tg->lock);
-        blkp->pending_reqs[is_write]--;
+        bs->pending_reqs[is_write]--;
     }
 
     /* The I/O will be executed, so do the accounting */
-    throttle_account(blkp->throttle_state, is_write, bytes);
+    throttle_account(bs->throttle_state, is_write, bytes);
 
     /* Schedule the next request */
-    schedule_next_request(blk, is_write);
+    schedule_next_request(bs, is_write);
 
     qemu_mutex_unlock(&tg->lock);
 }
 
-void throttle_group_restart_blk(BlockBackend *blk)
-{
-    BlockBackendPublic *blkp = blk_get_public(blk);
-    int i;
-
-    for (i = 0; i < 2; i++) {
-        while (qemu_co_enter_next(&blkp->throttled_reqs[i])) {
-            ;
-        }
-    }
-}
-
 /* Update the throttle configuration for a particular group. Similar
  * to throttle_config(), but guarantees atomicity within the
  * throttling group.
  *
- * @blk: a BlockBackend that is a member of the group
+ * @bs:  a BlockDriverState that is member of the group
  * @cfg: the configuration to set
  */
-void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg)
+void throttle_group_config(BlockDriverState *bs, ThrottleConfig *cfg)
 {
-    BlockBackendPublic *blkp = blk_get_public(blk);
-    ThrottleTimers *tt = &blkp->throttle_timers;
-    ThrottleState *ts = blkp->throttle_state;
+    ThrottleTimers *tt = &bs->throttle_timers;
+    ThrottleState *ts = bs->throttle_state;
     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
     qemu_mutex_lock(&tg->lock);
     /* throttle_config() cancels the timers */
@@ -356,22 +335,18 @@ void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg)
     }
     throttle_config(ts, tt, cfg);
     qemu_mutex_unlock(&tg->lock);
-
-    qemu_co_enter_next(&blkp->throttled_reqs[0]);
-    qemu_co_enter_next(&blkp->throttled_reqs[1]);
 }
 
 /* Get the throttle configuration from a particular group. Similar to
  * throttle_get_config(), but guarantees atomicity within the
  * throttling group.
  *
- * @blk: a BlockBackend that is a member of the group
+ * @bs:  a BlockDriverState that is member of the group
  * @cfg: the configuration will be written here
  */
-void throttle_group_get_config(BlockBackend *blk, ThrottleConfig *cfg)
+void throttle_group_get_config(BlockDriverState *bs, ThrottleConfig *cfg)
 {
-    BlockBackendPublic *blkp = blk_get_public(blk);
-    ThrottleState *ts = blkp->throttle_state;
+    ThrottleState *ts = bs->throttle_state;
     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
     qemu_mutex_lock(&tg->lock);
     throttle_get_config(ts, cfg);
@@ -381,13 +356,12 @@ void throttle_group_get_config(BlockBackend *blk, ThrottleConfig *cfg)
 /* ThrottleTimers callback. This wakes up a request that was waiting
  * because it had been throttled.
  *
- * @blk:       the BlockBackend whose request had been throttled
+ * @bs:        the BlockDriverState whose request had been throttled
  * @is_write:  the type of operation (read/write)
  */
-static void timer_cb(BlockBackend *blk, bool is_write)
+static void timer_cb(BlockDriverState *bs, bool is_write)
 {
-    BlockBackendPublic *blkp = blk_get_public(blk);
-    ThrottleState *ts = blkp->throttle_state;
+    ThrottleState *ts = bs->throttle_state;
     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
     bool empty_queue;
 
@@ -397,13 +371,13 @@ static void timer_cb(BlockBackend *blk, bool is_write)
     qemu_mutex_unlock(&tg->lock);
 
     /* Run the request that was waiting for this timer */
-    empty_queue = !qemu_co_enter_next(&blkp->throttled_reqs[is_write]);
+    empty_queue = !qemu_co_enter_next(&bs->throttled_reqs[is_write]);
 
     /* If the request queue was empty then we have to take care of
      * scheduling the next one */
     if (empty_queue) {
         qemu_mutex_lock(&tg->lock);
-        schedule_next_request(blk, is_write);
+        schedule_next_request(bs, is_write);
         qemu_mutex_unlock(&tg->lock);
     }
 }
@@ -418,17 +392,17 @@ static void write_timer_cb(void *opaque)
     timer_cb(opaque, true);
 }
 
-/* Register a BlockBackend in the throttling group, also initializing its
- * timers and updating its throttle_state pointer to point to it. If a
- * throttling group with that name does not exist yet, it will be created.
+/* Register a BlockDriverState in the throttling group, also
+ * initializing its timers and updating its throttle_state pointer to
+ * point to it. If a throttling group with that name does not exist
+ * yet, it will be created.
  *
- * @blk:       the BlockBackend to insert
+ * @bs:        the BlockDriverState to insert
  * @groupname: the name of the group
  */
-void throttle_group_register_blk(BlockBackend *blk, const char *groupname)
+void throttle_group_register_bs(BlockDriverState *bs, const char *groupname)
 {
     int i;
-    BlockBackendPublic *blkp = blk_get_public(blk);
     ThrottleState *ts = throttle_group_incref(groupname);
     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
     int clock_type = QEMU_CLOCK_REALTIME;
@@ -438,67 +412,67 @@ void throttle_group_register_blk(BlockBackend *blk, const char *groupname)
         clock_type = QEMU_CLOCK_VIRTUAL;
     }
 
-    blkp->throttle_state = ts;
+    bs->throttle_state = ts;
 
     qemu_mutex_lock(&tg->lock);
-    /* If the ThrottleGroup is new set this BlockBackend as the token */
+    /* If the ThrottleGroup is new set this BlockDriverState as the token */
     for (i = 0; i < 2; i++) {
         if (!tg->tokens[i]) {
-            tg->tokens[i] = blk;
+            tg->tokens[i] = bs;
         }
     }
 
-    QLIST_INSERT_HEAD(&tg->head, blkp, round_robin);
+    QLIST_INSERT_HEAD(&tg->head, bs, round_robin);
 
-    throttle_timers_init(&blkp->throttle_timers,
-                         blk_get_aio_context(blk),
+    throttle_timers_init(&bs->throttle_timers,
+                         bdrv_get_aio_context(bs),
                          clock_type,
                          read_timer_cb,
                          write_timer_cb,
-                         blk);
+                         bs);
 
     qemu_mutex_unlock(&tg->lock);
 }
 
-/* Unregister a BlockBackend from its group, removing it from the list,
- * destroying the timers and setting the throttle_state pointer to NULL.
+/* Unregister a BlockDriverState from its group, removing it from the
+ * list, destroying the timers and setting the throttle_state pointer
+ * to NULL.
  *
- * The BlockBackend must not have pending throttled requests, so the caller has
- * to drain them first.
+ * The BlockDriverState must not have pending throttled requests, so
+ * the caller has to drain them first.
  *
  * The group will be destroyed if it's empty after this operation.
  *
- * @blk: the BlockBackend to remove
+ * @bs: the BlockDriverState to remove
  */
-void throttle_group_unregister_blk(BlockBackend *blk)
+void throttle_group_unregister_bs(BlockDriverState *bs)
 {
-    BlockBackendPublic *blkp = blk_get_public(blk);
-    ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
+    ThrottleGroup *tg = container_of(bs->throttle_state, ThrottleGroup, ts);
     int i;
 
-    assert(blkp->pending_reqs[0] == 0 && blkp->pending_reqs[1] == 0);
-    assert(qemu_co_queue_empty(&blkp->throttled_reqs[0]));
-    assert(qemu_co_queue_empty(&blkp->throttled_reqs[1]));
+    assert(bs->pending_reqs[0] == 0 && bs->pending_reqs[1] == 0);
+    assert(qemu_co_queue_empty(&bs->throttled_reqs[0]));
+    assert(qemu_co_queue_empty(&bs->throttled_reqs[1]));
 
     qemu_mutex_lock(&tg->lock);
     for (i = 0; i < 2; i++) {
-        if (tg->tokens[i] == blk) {
-            BlockBackend *token = throttle_group_next_blk(blk);
-            /* Take care of the case where this is the last blk in the group */
-            if (token == blk) {
+        if (tg->tokens[i] == bs) {
+            BlockDriverState *token = throttle_group_next_bs(bs);
+            /* Take care of the case where this is the last bs in the group */
+            if (token == bs) {
                 token = NULL;
             }
             tg->tokens[i] = token;
         }
     }
 
-    /* remove the current blk from the list */
-    QLIST_REMOVE(blkp, round_robin);
-    throttle_timers_destroy(&blkp->throttle_timers);
+    /* remove the current bs from the list */
+    QLIST_REMOVE(bs, round_robin);
+    throttle_timers_destroy(&bs->throttle_timers);
     qemu_mutex_unlock(&tg->lock);
 
     throttle_group_unref(&tg->ts);
-    blkp->throttle_state = NULL;
+    bs->throttle_state = NULL;
 }
 
 static void throttle_groups_init(void)
diff --git a/block/trace-events b/block/trace-events
deleted file mode 100644 (file)
index 05fa13c..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# block.c
-bdrv_open_common(void *bs, const char *filename, int flags, const char *format_name) "bs %p filename \"%s\" flags %#x format_name \"%s\""
-bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
-
-# block/block-backend.c
-blk_co_preadv(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags %x"
-blk_co_pwritev(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags %x"
-
-# block/io.c
-bdrv_aio_pdiscard(void *bs, int64_t offset, int count, void *opaque) "bs %p offset %"PRId64" count %d opaque %p"
-bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
-bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
-bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
-bdrv_co_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
-bdrv_co_writev(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
-bdrv_co_pwrite_zeroes(void *bs, int64_t offset, int count, int flags) "bs %p offset %"PRId64" count %d flags %#x"
-bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, unsigned int cluster_bytes) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %u"
-
-# block/stream.c
-stream_one_iteration(void *s, int64_t sector_num, int nb_sectors, int is_allocated) "s %p sector_num %"PRId64" nb_sectors %d is_allocated %d"
-stream_start(void *bs, void *base, void *s, void *co, void *opaque) "bs %p base %p s %p co %p opaque %p"
-
-# block/commit.c
-commit_one_iteration(void *s, int64_t sector_num, int nb_sectors, int is_allocated) "s %p sector_num %"PRId64" nb_sectors %d is_allocated %d"
-commit_start(void *bs, void *base, void *top, void *s, void *co, void *opaque) "bs %p base %p top %p s %p co %p opaque %p"
-
-# block/mirror.c
-mirror_start(void *bs, void *s, void *co, void *opaque) "bs %p s %p co %p opaque %p"
-mirror_restart_iter(void *s, int64_t cnt) "s %p dirty count %"PRId64
-mirror_before_flush(void *s) "s %p"
-mirror_before_drain(void *s, int64_t cnt) "s %p dirty count %"PRId64
-mirror_before_sleep(void *s, int64_t cnt, int synced, uint64_t delay_ns) "s %p dirty count %"PRId64" synced %d delay %"PRIu64"ns"
-mirror_one_iteration(void *s, int64_t sector_num, int nb_sectors) "s %p sector_num %"PRId64" nb_sectors %d"
-mirror_iteration_done(void *s, int64_t sector_num, int nb_sectors, int ret) "s %p sector_num %"PRId64" nb_sectors %d ret %d"
-mirror_yield(void *s, int64_t cnt, int buf_free_count, int in_flight) "s %p dirty count %"PRId64" free buffers %d in_flight %d"
-mirror_yield_in_flight(void *s, int64_t sector_num, int in_flight) "s %p sector_num %"PRId64" in_flight %d"
-mirror_yield_buf_busy(void *s, int nb_chunks, int in_flight) "s %p requested chunks %d in_flight %d"
-mirror_break_buf_busy(void *s, int nb_chunks, int in_flight) "s %p requested chunks %d in_flight %d"
-
-# block/backup.c
-backup_do_cow_enter(void *job, int64_t start, int64_t sector_num, int nb_sectors) "job %p start %"PRId64" sector_num %"PRId64" nb_sectors %d"
-backup_do_cow_return(void *job, int64_t sector_num, int nb_sectors, int ret) "job %p sector_num %"PRId64" nb_sectors %d ret %d"
-backup_do_cow_skip(void *job, int64_t start) "job %p start %"PRId64
-backup_do_cow_process(void *job, int64_t start) "job %p start %"PRId64
-backup_do_cow_read_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d"
-backup_do_cow_write_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d"
-
-# blockdev.c
-qmp_block_job_cancel(void *job) "job %p"
-qmp_block_job_pause(void *job) "job %p"
-qmp_block_job_resume(void *job) "job %p"
-qmp_block_job_complete(void *job) "job %p"
-block_job_cb(void *bs, void *job, int ret) "bs %p job %p ret %d"
-qmp_block_stream(void *bs, void *job) "bs %p job %p"
-
-# block/raw-win32.c
-# block/raw-posix.c
-paio_submit_co(int64_t offset, int count, int type) "offset %"PRId64" count %d type %d"
-paio_submit(void *acb, void *opaque, int64_t offset, int count, int type) "acb %p opaque %p offset %"PRId64" count %d type %d"
-
-# block/qcow2.c
-qcow2_writev_start_req(void *co, int64_t offset, int bytes) "co %p offset %" PRIx64 " bytes %d"
-qcow2_writev_done_req(void *co, int ret) "co %p ret %d"
-qcow2_writev_start_part(void *co) "co %p"
-qcow2_writev_done_part(void *co, int cur_bytes) "co %p cur_bytes %d"
-qcow2_writev_data(void *co, uint64_t offset) "co %p offset %" PRIx64
-qcow2_pwrite_zeroes_start_req(void *co, int64_t offset, int count) "co %p offset %" PRIx64 " count %d"
-qcow2_pwrite_zeroes(void *co, int64_t offset, int count) "co %p offset %" PRIx64 " count %d"
-
-# block/qcow2-cluster.c
-qcow2_alloc_clusters_offset(void *co, uint64_t offset, int bytes) "co %p offset %" PRIx64 " bytes %d"
-qcow2_handle_copied(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64
-qcow2_handle_alloc(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64
-qcow2_do_alloc_clusters_offset(void *co, uint64_t guest_offset, uint64_t host_offset, int nb_clusters) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " nb_clusters %d"
-qcow2_cluster_alloc_phys(void *co) "co %p"
-qcow2_cluster_link_l2(void *co, int nb_clusters) "co %p nb_clusters %d"
-
-qcow2_l2_allocate(void *bs, int l1_index) "bs %p l1_index %d"
-qcow2_l2_allocate_get_empty(void *bs, int l1_index) "bs %p l1_index %d"
-qcow2_l2_allocate_write_l2(void *bs, int l1_index) "bs %p l1_index %d"
-qcow2_l2_allocate_write_l1(void *bs, int l1_index) "bs %p l1_index %d"
-qcow2_l2_allocate_done(void *bs, int l1_index, int ret) "bs %p l1_index %d ret %d"
-
-# block/qcow2-cache.c
-qcow2_cache_get(void *co, int c, uint64_t offset, bool read_from_disk) "co %p is_l2_cache %d offset %" PRIx64 " read_from_disk %d"
-qcow2_cache_get_replace_entry(void *co, int c, int i) "co %p is_l2_cache %d index %d"
-qcow2_cache_get_read(void *co, int c, int i) "co %p is_l2_cache %d index %d"
-qcow2_cache_get_done(void *co, int c, int i) "co %p is_l2_cache %d index %d"
-qcow2_cache_flush(void *co, int c) "co %p is_l2_cache %d"
-qcow2_cache_entry_flush(void *co, int c, int i) "co %p is_l2_cache %d index %d"
-
-# block/qed-l2-cache.c
-qed_alloc_l2_cache_entry(void *l2_cache, void *entry) "l2_cache %p entry %p"
-qed_unref_l2_cache_entry(void *entry, int ref) "entry %p ref %d"
-qed_find_l2_cache_entry(void *l2_cache, void *entry, uint64_t offset, int ref) "l2_cache %p entry %p offset %"PRIu64" ref %d"
-
-# block/qed-table.c
-qed_read_table(void *s, uint64_t offset, void *table) "s %p offset %"PRIu64" table %p"
-qed_read_table_cb(void *s, void *table, int ret) "s %p table %p ret %d"
-qed_write_table(void *s, uint64_t offset, void *table, unsigned int index, unsigned int n) "s %p offset %"PRIu64" table %p index %u n %u"
-qed_write_table_cb(void *s, void *table, int flush, int ret) "s %p table %p flush %d ret %d"
-
-# block/qed.c
-qed_need_check_timer_cb(void *s) "s %p"
-qed_start_need_check_timer(void *s) "s %p"
-qed_cancel_need_check_timer(void *s) "s %p"
-qed_aio_complete(void *s, void *acb, int ret) "s %p acb %p ret %d"
-qed_aio_setup(void *s, void *acb, int64_t sector_num, int nb_sectors, void *opaque, int flags) "s %p acb %p sector_num %"PRId64" nb_sectors %d opaque %p flags %#x"
-qed_aio_next_io(void *s, void *acb, int ret, uint64_t cur_pos) "s %p acb %p ret %d cur_pos %"PRIu64
-qed_aio_read_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
-qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
-qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
-qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
-qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
index 8a1cf97..75d4819 100644 (file)
@@ -54,7 +54,6 @@
 #include "block/block_int.h"
 #include "sysemu/block-backend.h"
 #include "qemu/module.h"
-#include "qemu/bswap.h"
 #include "migration/migration.h"
 #include "qemu/coroutine.h"
 #include "qemu/cutils.h"
@@ -403,7 +402,7 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
 
     logout("\n");
 
-    ret = bdrv_read(bs->file, 0, (uint8_t *)&header, 1);
+    ret = bdrv_read(bs->file->bs, 0, (uint8_t *)&header, 1);
     if (ret < 0) {
         goto fail;
     }
@@ -500,7 +499,7 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
         goto fail;
     }
 
-    ret = bdrv_read(bs->file, s->bmap_sector, (uint8_t *)s->bmap,
+    ret = bdrv_read(bs->file->bs, s->bmap_sector, (uint8_t *)s->bmap,
                     bmap_size);
     if (ret < 0) {
         goto fail_free_bmap;
@@ -558,109 +557,98 @@ static int64_t coroutine_fn vdi_co_get_block_status(BlockDriverState *bs,
     return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset;
 }
 
-static int coroutine_fn
-vdi_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
-              QEMUIOVector *qiov, int flags)
+static int vdi_co_read(BlockDriverState *bs,
+        int64_t sector_num, uint8_t *buf, int nb_sectors)
 {
     BDRVVdiState *s = bs->opaque;
-    QEMUIOVector local_qiov;
     uint32_t bmap_entry;
     uint32_t block_index;
-    uint32_t offset_in_block;
-    uint32_t n_bytes;
-    uint64_t bytes_done = 0;
+    uint32_t sector_in_block;
+    uint32_t n_sectors;
     int ret = 0;
 
     logout("\n");
 
-    qemu_iovec_init(&local_qiov, qiov->niov);
-
-    while (ret >= 0 && bytes > 0) {
-        block_index = offset / s->block_size;
-        offset_in_block = offset % s->block_size;
-        n_bytes = MIN(bytes, s->block_size - offset_in_block);
+    while (ret >= 0 && nb_sectors > 0) {
+        block_index = sector_num / s->block_sectors;
+        sector_in_block = sector_num % s->block_sectors;
+        n_sectors = s->block_sectors - sector_in_block;
+        if (n_sectors > nb_sectors) {
+            n_sectors = nb_sectors;
+        }
 
-        logout("will read %u bytes starting at offset %" PRIu64 "\n",
-               n_bytes, offset);
+        logout("will read %u sectors starting at sector %" PRIu64 "\n",
+               n_sectors, sector_num);
 
         /* prepare next AIO request */
         bmap_entry = le32_to_cpu(s->bmap[block_index]);
         if (!VDI_IS_ALLOCATED(bmap_entry)) {
             /* Block not allocated, return zeros, no need to wait. */
-            qemu_iovec_memset(qiov, bytes_done, 0, n_bytes);
+            memset(buf, 0, n_sectors * SECTOR_SIZE);
             ret = 0;
         } else {
-            uint64_t data_offset = s->header.offset_data +
-                                   (uint64_t)bmap_entry * s->block_size +
-                                   offset_in_block;
-
-            qemu_iovec_reset(&local_qiov);
-            qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
-
-            ret = bdrv_co_preadv(bs->file, data_offset, n_bytes,
-                                 &local_qiov, 0);
+            uint64_t offset = s->header.offset_data / SECTOR_SIZE +
+                              (uint64_t)bmap_entry * s->block_sectors +
+                              sector_in_block;
+            ret = bdrv_read(bs->file->bs, offset, buf, n_sectors);
         }
-        logout("%u bytes read\n", n_bytes);
+        logout("%u sectors read\n", n_sectors);
 
-        bytes -= n_bytes;
-        offset += n_bytes;
-        bytes_done += n_bytes;
+        nb_sectors -= n_sectors;
+        sector_num += n_sectors;
+        buf += n_sectors * SECTOR_SIZE;
     }
 
-    qemu_iovec_destroy(&local_qiov);
-
     return ret;
 }
 
-static int coroutine_fn
-vdi_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
-               QEMUIOVector *qiov, int flags)
+static int vdi_co_write(BlockDriverState *bs,
+        int64_t sector_num, const uint8_t *buf, int nb_sectors)
 {
     BDRVVdiState *s = bs->opaque;
-    QEMUIOVector local_qiov;
     uint32_t bmap_entry;
     uint32_t block_index;
-    uint32_t offset_in_block;
-    uint32_t n_bytes;
+    uint32_t sector_in_block;
+    uint32_t n_sectors;
     uint32_t bmap_first = VDI_UNALLOCATED;
     uint32_t bmap_last = VDI_UNALLOCATED;
     uint8_t *block = NULL;
-    uint64_t bytes_done = 0;
     int ret = 0;
 
     logout("\n");
 
-    qemu_iovec_init(&local_qiov, qiov->niov);
-
-    while (ret >= 0 && bytes > 0) {
-        block_index = offset / s->block_size;
-        offset_in_block = offset % s->block_size;
-        n_bytes = MIN(bytes, s->block_size - offset_in_block);
+    while (ret >= 0 && nb_sectors > 0) {
+        block_index = sector_num / s->block_sectors;
+        sector_in_block = sector_num % s->block_sectors;
+        n_sectors = s->block_sectors - sector_in_block;
+        if (n_sectors > nb_sectors) {
+            n_sectors = nb_sectors;
+        }
 
-        logout("will write %u bytes starting at offset %" PRIu64 "\n",
-               n_bytes, offset);
+        logout("will write %u sectors starting at sector %" PRIu64 "\n",
+               n_sectors, sector_num);
 
         /* prepare next AIO request */
         bmap_entry = le32_to_cpu(s->bmap[block_index]);
         if (!VDI_IS_ALLOCATED(bmap_entry)) {
             /* Allocate new block and write to it. */
-            uint64_t data_offset;
+            uint64_t offset;
             bmap_entry = s->header.blocks_allocated;
             s->bmap[block_index] = cpu_to_le32(bmap_entry);
             s->header.blocks_allocated++;
-            data_offset = s->header.offset_data +
-                          (uint64_t)bmap_entry * s->block_size;
+            offset = s->header.offset_data / SECTOR_SIZE +
+                     (uint64_t)bmap_entry * s->block_sectors;
             if (block == NULL) {
                 block = g_malloc(s->block_size);
                 bmap_first = block_index;
             }
             bmap_last = block_index;
             /* Copy data to be written to new block and zero unused parts. */
-            memset(block, 0, offset_in_block);
-            qemu_iovec_to_buf(qiov, bytes_done, block + offset_in_block,
-                              n_bytes);
-            memset(block + offset_in_block + n_bytes, 0,
-                   s->block_size - n_bytes - offset_in_block);
+            memset(block, 0, sector_in_block * SECTOR_SIZE);
+            memcpy(block + sector_in_block * SECTOR_SIZE,
+                   buf, n_sectors * SECTOR_SIZE);
+            memset(block + (sector_in_block + n_sectors) * SECTOR_SIZE, 0,
+                   (s->block_sectors - n_sectors - sector_in_block) * SECTOR_SIZE);
 
             /* Note that this coroutine does not yield anywhere from reading the
              * bmap entry until here, so in regards to all the coroutines trying
@@ -670,12 +658,12 @@ vdi_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
              * acquire the lock and thus the padded cluster is written before
              * the other coroutines can write to the affected area. */
             qemu_co_mutex_lock(&s->write_lock);
-            ret = bdrv_pwrite(bs->file, data_offset, block, s->block_size);
+            ret = bdrv_write(bs->file->bs, offset, block, s->block_sectors);
             qemu_co_mutex_unlock(&s->write_lock);
         } else {
-            uint64_t data_offset = s->header.offset_data +
-                                   (uint64_t)bmap_entry * s->block_size +
-                                   offset_in_block;
+            uint64_t offset = s->header.offset_data / SECTOR_SIZE +
+                              (uint64_t)bmap_entry * s->block_sectors +
+                              sector_in_block;
             qemu_co_mutex_lock(&s->write_lock);
             /* This lock is only used to make sure the following write operation
              * is executed after the write issued by the coroutine allocating
@@ -686,23 +674,16 @@ vdi_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
              * that that write operation has returned (there may be other writes
              * in flight, but they do not concern this very operation). */
             qemu_co_mutex_unlock(&s->write_lock);
-
-            qemu_iovec_reset(&local_qiov);
-            qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
-
-            ret = bdrv_co_pwritev(bs->file, data_offset, n_bytes,
-                                  &local_qiov, 0);
+            ret = bdrv_write(bs->file->bs, offset, buf, n_sectors);
         }
 
-        bytes -= n_bytes;
-        offset += n_bytes;
-        bytes_done += n_bytes;
+        nb_sectors -= n_sectors;
+        sector_num += n_sectors;
+        buf += n_sectors * SECTOR_SIZE;
 
-        logout("%u bytes written\n", n_bytes);
+        logout("%u sectors written\n", n_sectors);
     }
 
-    qemu_iovec_destroy(&local_qiov);
-
     logout("finished data write\n");
     if (ret < 0) {
         return ret;
@@ -713,13 +694,12 @@ vdi_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
         VdiHeader *header = (VdiHeader *) block;
         uint8_t *base;
         uint64_t offset;
-        uint32_t n_sectors;
 
         logout("now writing modified header\n");
         assert(VDI_IS_ALLOCATED(bmap_first));
         *header = s->header;
         vdi_header_to_le(header);
-        ret = bdrv_write(bs->file, 0, block, 1);
+        ret = bdrv_write(bs->file->bs, 0, block, 1);
         g_free(block);
         block = NULL;
 
@@ -737,7 +717,7 @@ vdi_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
         base = ((uint8_t *)&s->bmap[0]) + bmap_first * SECTOR_SIZE;
         logout("will write %u block map sectors starting from entry %u\n",
                n_sectors, bmap_first);
-        ret = bdrv_write(bs->file, offset, base, n_sectors);
+        ret = bdrv_write(bs->file->bs, offset, base, n_sectors);
     }
 
     return ret;
@@ -828,7 +808,7 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp)
     vdi_header_print(&header);
 #endif
     vdi_header_to_le(&header);
-    ret = blk_pwrite(blk, offset, &header, sizeof(header), 0);
+    ret = blk_pwrite(blk, offset, &header, sizeof(header));
     if (ret < 0) {
         error_setg(errp, "Error writing header to %s", filename);
         goto exit;
@@ -849,7 +829,7 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp)
                 bmap[i] = VDI_UNALLOCATED;
             }
         }
-        ret = blk_pwrite(blk, offset, bmap, bmap_size, 0);
+        ret = blk_pwrite(blk, offset, bmap, bmap_size);
         if (ret < 0) {
             error_setg(errp, "Error writing bmap to %s", filename);
             goto exit;
@@ -923,9 +903,9 @@ static BlockDriver bdrv_vdi = {
     .bdrv_co_get_block_status = vdi_co_get_block_status,
     .bdrv_make_empty = vdi_make_empty,
 
-    .bdrv_co_preadv     = vdi_co_preadv,
+    .bdrv_read = vdi_co_read,
 #if defined(CONFIG_VDI_WRITE)
-    .bdrv_co_pwritev    = vdi_co_pwritev,
+    .bdrv_write = vdi_co_write,
 #endif
 
     .bdrv_get_info = vdi_get_info,
index c306b90..da33cd3 100644 (file)
@@ -18,7 +18,6 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "block/block_int.h"
-#include "qemu/bswap.h"
 #include "block/vhdx.h"
 
 #include <uuid/uuid.h>
index 02eb104..7ea7187 100644 (file)
@@ -23,7 +23,6 @@
 #include "block/block_int.h"
 #include "qemu/error-report.h"
 #include "qemu/module.h"
-#include "qemu/bswap.h"
 #include "block/vhdx.h"
 
 
@@ -84,7 +83,7 @@ static int vhdx_log_peek_hdr(BlockDriverState *bs, VHDXLogEntries *log,
 
     offset = log->offset + read;
 
-    ret = bdrv_pread(bs->file, offset, hdr, sizeof(VHDXLogEntryHeader));
+    ret = bdrv_pread(bs->file->bs, offset, hdr, sizeof(VHDXLogEntryHeader));
     if (ret < 0) {
         goto exit;
     }
@@ -144,7 +143,7 @@ static int vhdx_log_read_sectors(BlockDriverState *bs, VHDXLogEntries *log,
         }
         offset = log->offset + read;
 
-        ret = bdrv_pread(bs->file, offset, buffer, VHDX_LOG_SECTOR_SIZE);
+        ret = bdrv_pread(bs->file->bs, offset, buffer, VHDX_LOG_SECTOR_SIZE);
         if (ret < 0) {
             goto exit;
         }
@@ -194,7 +193,7 @@ static int vhdx_log_write_sectors(BlockDriverState *bs, VHDXLogEntries *log,
             /* full */
             break;
         }
-        ret = bdrv_pwrite(bs->file, offset, buffer_tmp,
+        ret = bdrv_pwrite(bs->file->bs, offset, buffer_tmp,
                           VHDX_LOG_SECTOR_SIZE);
         if (ret < 0) {
             goto exit;
@@ -466,7 +465,7 @@ static int vhdx_log_flush_desc(BlockDriverState *bs, VHDXLogDescriptor *desc,
 
     /* count is only > 1 if we are writing zeroes */
     for (i = 0; i < count; i++) {
-        ret = bdrv_pwrite_sync(bs->file, file_offset, buffer,
+        ret = bdrv_pwrite_sync(bs->file->bs, file_offset, buffer,
                                VHDX_LOG_SECTOR_SIZE);
         if (ret < 0) {
             goto exit;
@@ -945,7 +944,7 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
 
         if (i == 0 && leading_length) {
             /* partial sector at the front of the buffer */
-            ret = bdrv_pread(bs->file, file_offset, merged_sector,
+            ret = bdrv_pread(bs->file->bs, file_offset, merged_sector,
                              VHDX_LOG_SECTOR_SIZE);
             if (ret < 0) {
                 goto exit;
@@ -955,7 +954,7 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
             sector_write = merged_sector;
         } else if (i == sectors - 1 && trailing_length) {
             /* partial sector at the end of the buffer */
-            ret = bdrv_pread(bs->file,
+            ret = bdrv_pread(bs->file->bs,
                             file_offset,
                             merged_sector + trailing_length,
                             VHDX_LOG_SECTOR_SIZE - trailing_length);
index 75ef2b1..2b7b332 100644 (file)
 #include "sysemu/block-backend.h"
 #include "qemu/module.h"
 #include "qemu/crc32c.h"
-#include "qemu/bswap.h"
 #include "block/vhdx.h"
 #include "migration/migration.h"
 
 #include <uuid/uuid.h>
+#include <glib.h>
 
 /* Options for VHDX creation */
 
@@ -298,10 +298,9 @@ static int vhdx_probe(const uint8_t *buf, int buf_size, const char *filename)
  * and then update the header checksum.  Header is converted to proper
  * endianness before being written to the specified file offset
  */
-static int vhdx_write_header(BdrvChild *file, VHDXHeader *hdr,
+static int vhdx_write_header(BlockDriverState *bs_file, VHDXHeader *hdr,
                              uint64_t offset, bool read)
 {
-    BlockDriverState *bs_file = file->bs;
     uint8_t *buffer = NULL;
     int ret;
     VHDXHeader *header_le;
@@ -316,7 +315,7 @@ static int vhdx_write_header(BdrvChild *file, VHDXHeader *hdr,
     buffer = qemu_blockalign(bs_file, VHDX_HEADER_SIZE);
     if (read) {
         /* if true, we can't assume the extra reserved bytes are 0 */
-        ret = bdrv_pread(file, offset, buffer, VHDX_HEADER_SIZE);
+        ret = bdrv_pread(bs_file, offset, buffer, VHDX_HEADER_SIZE);
         if (ret < 0) {
             goto exit;
         }
@@ -330,7 +329,7 @@ static int vhdx_write_header(BdrvChild *file, VHDXHeader *hdr,
     vhdx_header_le_export(hdr, header_le);
     vhdx_update_checksum(buffer, VHDX_HEADER_SIZE,
                          offsetof(VHDXHeader, checksum));
-    ret = bdrv_pwrite_sync(file, offset, header_le, sizeof(VHDXHeader));
+    ret = bdrv_pwrite_sync(bs_file, offset, header_le, sizeof(VHDXHeader));
 
 exit:
     qemu_vfree(buffer);
@@ -379,7 +378,7 @@ static int vhdx_update_header(BlockDriverState *bs, BDRVVHDXState *s,
         inactive_header->log_guid = *log_guid;
     }
 
-    ret = vhdx_write_header(bs->file, inactive_header, header_offset, true);
+    ret = vhdx_write_header(bs->file->bs, inactive_header, header_offset, true);
     if (ret < 0) {
         goto exit;
     }
@@ -431,7 +430,7 @@ static void vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s,
     /* We have to read the whole VHDX_HEADER_SIZE instead of
      * sizeof(VHDXHeader), because the checksum is over the whole
      * region */
-    ret = bdrv_pread(bs->file, VHDX_HEADER1_OFFSET, buffer,
+    ret = bdrv_pread(bs->file->bs, VHDX_HEADER1_OFFSET, buffer,
                      VHDX_HEADER_SIZE);
     if (ret < 0) {
         goto fail;
@@ -448,7 +447,7 @@ static void vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s,
         }
     }
 
-    ret = bdrv_pread(bs->file, VHDX_HEADER2_OFFSET, buffer,
+    ret = bdrv_pread(bs->file->bs, VHDX_HEADER2_OFFSET, buffer,
                      VHDX_HEADER_SIZE);
     if (ret < 0) {
         goto fail;
@@ -522,7 +521,7 @@ static int vhdx_open_region_tables(BlockDriverState *bs, BDRVVHDXState *s)
      * whole block */
     buffer = qemu_blockalign(bs, VHDX_HEADER_BLOCK_SIZE);
 
-    ret = bdrv_pread(bs->file, VHDX_REGION_TABLE_OFFSET, buffer,
+    ret = bdrv_pread(bs->file->bs, VHDX_REGION_TABLE_OFFSET, buffer,
                      VHDX_HEADER_BLOCK_SIZE);
     if (ret < 0) {
         goto fail;
@@ -635,7 +634,7 @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
 
     buffer = qemu_blockalign(bs, VHDX_METADATA_TABLE_MAX_SIZE);
 
-    ret = bdrv_pread(bs->file, s->metadata_rt.file_offset, buffer,
+    ret = bdrv_pread(bs->file->bs, s->metadata_rt.file_offset, buffer,
                      VHDX_METADATA_TABLE_MAX_SIZE);
     if (ret < 0) {
         goto exit;
@@ -738,7 +737,7 @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
         goto exit;
     }
 
-    ret = bdrv_pread(bs->file,
+    ret = bdrv_pread(bs->file->bs,
                      s->metadata_entries.file_parameters_entry.offset
                                          + s->metadata_rt.file_offset,
                      &s->params,
@@ -773,7 +772,7 @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
     /* determine virtual disk size, logical sector size,
      * and phys sector size */
 
-    ret = bdrv_pread(bs->file,
+    ret = bdrv_pread(bs->file->bs,
                      s->metadata_entries.virtual_disk_size_entry.offset
                                            + s->metadata_rt.file_offset,
                      &s->virtual_disk_size,
@@ -781,7 +780,7 @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
     if (ret < 0) {
         goto exit;
     }
-    ret = bdrv_pread(bs->file,
+    ret = bdrv_pread(bs->file->bs,
                      s->metadata_entries.logical_sector_size_entry.offset
                                              + s->metadata_rt.file_offset,
                      &s->logical_sector_size,
@@ -789,7 +788,7 @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
     if (ret < 0) {
         goto exit;
     }
-    ret = bdrv_pread(bs->file,
+    ret = bdrv_pread(bs->file->bs,
                      s->metadata_entries.phys_sector_size_entry.offset
                                           + s->metadata_rt.file_offset,
                      &s->physical_sector_size,
@@ -906,7 +905,7 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
     QLIST_INIT(&s->regions);
 
     /* validate the file signature */
-    ret = bdrv_pread(bs->file, 0, &signature, sizeof(uint64_t));
+    ret = bdrv_pread(bs->file->bs, 0, &signature, sizeof(uint64_t));
     if (ret < 0) {
         goto fail;
     }
@@ -965,7 +964,7 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
         goto fail;
     }
 
-    ret = bdrv_pread(bs->file, s->bat_offset, s->bat, s->bat_rt.length);
+    ret = bdrv_pread(bs->file->bs, s->bat_offset, s->bat, s->bat_rt.length);
     if (ret < 0) {
         goto fail;
     }
@@ -1118,7 +1117,7 @@ static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num,
                 break;
             case PAYLOAD_BLOCK_FULLY_PRESENT:
                 qemu_co_mutex_unlock(&s->lock);
-                ret = bdrv_co_readv(bs->file,
+                ret = bdrv_co_readv(bs->file->bs,
                                     sinfo.file_offset >> BDRV_SECTOR_BITS,
                                     sinfo.sectors_avail, &hd_qiov);
                 qemu_co_mutex_lock(&s->lock);
@@ -1327,7 +1326,7 @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
                 }
                 /* block exists, so we can just overwrite it */
                 qemu_co_mutex_unlock(&s->lock);
-                ret = bdrv_co_writev(bs->file,
+                ret = bdrv_co_writev(bs->file->bs,
                                     sinfo.file_offset >> BDRV_SECTOR_BITS,
                                     sectors_to_write, &hd_qiov);
                 qemu_co_mutex_lock(&s->lock);
@@ -1388,11 +1387,9 @@ exit:
  * There are 2 headers, and the highest sequence number will represent
  * the active header
  */
-static int vhdx_create_new_headers(BlockBackend *blk, uint64_t image_size,
+static int vhdx_create_new_headers(BlockDriverState *bs, uint64_t image_size,
                                    uint32_t log_size)
 {
-    BlockDriverState *bs = blk_bs(blk);
-    BdrvChild *child;
     int ret = 0;
     VHDXHeader *hdr = NULL;
 
@@ -1407,18 +1404,12 @@ static int vhdx_create_new_headers(BlockBackend *blk, uint64_t image_size,
     vhdx_guid_generate(&hdr->file_write_guid);
     vhdx_guid_generate(&hdr->data_write_guid);
 
-    /* XXX Ugly way to get blk->root, but that's a feature, not a bug. This
-     * hack makes it obvious that vhdx_write_header() bypasses the BlockBackend
-     * here, which it really shouldn't be doing. */
-    child = QLIST_FIRST(&bs->parents);
-    assert(!QLIST_NEXT(child, next_parent));
-
-    ret = vhdx_write_header(child, hdr, VHDX_HEADER1_OFFSET, false);
+    ret = vhdx_write_header(bs, hdr, VHDX_HEADER1_OFFSET, false);
     if (ret < 0) {
         goto exit;
     }
     hdr->sequence_number++;
-    ret = vhdx_write_header(child, hdr, VHDX_HEADER2_OFFSET, false);
+    ret = vhdx_write_header(bs, hdr, VHDX_HEADER2_OFFSET, false);
     if (ret < 0) {
         goto exit;
     }
@@ -1451,7 +1442,7 @@ exit:
  * The first 64KB of the Metadata section is reserved for the metadata
  * header and entries; beyond that, the metadata items themselves reside.
  */
-static int vhdx_create_new_metadata(BlockBackend *blk,
+static int vhdx_create_new_metadata(BlockDriverState *bs,
                                     uint64_t image_size,
                                     uint32_t block_size,
                                     uint32_t sector_size,
@@ -1547,13 +1538,13 @@ static int vhdx_create_new_metadata(BlockBackend *blk,
                                    VHDX_META_FLAGS_IS_VIRTUAL_DISK;
     vhdx_metadata_entry_le_export(&md_table_entry[4]);
 
-    ret = blk_pwrite(blk, metadata_offset, buffer, VHDX_HEADER_BLOCK_SIZE, 0);
+    ret = bdrv_pwrite(bs, metadata_offset, buffer, VHDX_HEADER_BLOCK_SIZE);
     if (ret < 0) {
         goto exit;
     }
 
-    ret = blk_pwrite(blk, metadata_offset + (64 * KiB), entry_buffer,
-                     VHDX_METADATA_ENTRY_BUFFER_SIZE, 0);
+    ret = bdrv_pwrite(bs, metadata_offset + (64 * KiB), entry_buffer,
+                      VHDX_METADATA_ENTRY_BUFFER_SIZE);
     if (ret < 0) {
         goto exit;
     }
@@ -1573,7 +1564,7 @@ exit:
  *  Fixed images: default state of the BAT is fully populated, with
  *                file offsets and state PAYLOAD_BLOCK_FULLY_PRESENT.
  */
-static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
+static int vhdx_create_bat(BlockDriverState *bs, BDRVVHDXState *s,
                            uint64_t image_size, VHDXImageType type,
                            bool use_zero_blocks, uint64_t file_offset,
                            uint32_t length)
@@ -1597,12 +1588,12 @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
     if (type == VHDX_TYPE_DYNAMIC) {
         /* All zeroes, so we can just extend the file - the end of the BAT
          * is the furthest thing we have written yet */
-        ret = blk_truncate(blk, data_file_offset);
+        ret = bdrv_truncate(bs, data_file_offset);
         if (ret < 0) {
             goto exit;
         }
     } else if (type == VHDX_TYPE_FIXED) {
-        ret = blk_truncate(blk, data_file_offset + image_size);
+        ret = bdrv_truncate(bs, data_file_offset + image_size);
         if (ret < 0) {
             goto exit;
         }
@@ -1613,7 +1604,7 @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
 
     if (type == VHDX_TYPE_FIXED ||
                 use_zero_blocks ||
-                bdrv_has_zero_init(blk_bs(blk)) == 0) {
+                bdrv_has_zero_init(bs) == 0) {
         /* for a fixed file, the default BAT entry is not zero */
         s->bat = g_try_malloc0(length);
         if (length && s->bat == NULL) {
@@ -1629,12 +1620,12 @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
             sinfo.file_offset = data_file_offset +
                                 (sector_num << s->logical_sector_size_bits);
             sinfo.file_offset = ROUND_UP(sinfo.file_offset, MiB);
-            vhdx_update_bat_table_entry(blk_bs(blk), s, &sinfo, &unused, &unused,
+            vhdx_update_bat_table_entry(bs, s, &sinfo, &unused, &unused,
                                         block_state);
             cpu_to_le64s(&s->bat[sinfo.bat_idx]);
             sector_num += s->sectors_per_block;
         }
-        ret = blk_pwrite(blk, file_offset, s->bat, length, 0);
+        ret = bdrv_pwrite(bs, file_offset, s->bat, length);
         if (ret < 0) {
             goto exit;
         }
@@ -1654,7 +1645,7 @@ exit:
  * to create the BAT itself, we will also cause the BAT to be
  * created.
  */
-static int vhdx_create_new_region_table(BlockBackend *blk,
+static int vhdx_create_new_region_table(BlockDriverState *bs,
                                         uint64_t image_size,
                                         uint32_t block_size,
                                         uint32_t sector_size,
@@ -1729,21 +1720,21 @@ static int vhdx_create_new_region_table(BlockBackend *blk,
 
     /* The region table gives us the data we need to create the BAT,
      * so do that now */
-    ret = vhdx_create_bat(blk, s, image_size, type, use_zero_blocks,
+    ret = vhdx_create_bat(bs, s, image_size, type, use_zero_blocks,
                           bat_file_offset, bat_length);
     if (ret < 0) {
         goto exit;
     }
 
     /* Now write out the region headers to disk */
-    ret = blk_pwrite(blk, VHDX_REGION_TABLE_OFFSET, buffer,
-                     VHDX_HEADER_BLOCK_SIZE, 0);
+    ret = bdrv_pwrite(bs, VHDX_REGION_TABLE_OFFSET, buffer,
+                      VHDX_HEADER_BLOCK_SIZE);
     if (ret < 0) {
         goto exit;
     }
 
-    ret = blk_pwrite(blk, VHDX_REGION_TABLE2_OFFSET, buffer,
-                     VHDX_HEADER_BLOCK_SIZE, 0);
+    ret = bdrv_pwrite(bs, VHDX_REGION_TABLE2_OFFSET, buffer,
+                      VHDX_HEADER_BLOCK_SIZE);
     if (ret < 0) {
         goto exit;
     }
@@ -1865,14 +1856,13 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
     creator = g_utf8_to_utf16("QEMU v" QEMU_VERSION, -1, NULL,
                               &creator_items, NULL);
     signature = cpu_to_le64(VHDX_FILE_SIGNATURE);
-    ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET, &signature, sizeof(signature),
-                     0);
+    ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET, &signature, sizeof(signature));
     if (ret < 0) {
         goto delete_and_exit;
     }
     if (creator) {
         ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET + sizeof(signature),
-                         creator, creator_items * sizeof(gunichar2), 0);
+                         creator, creator_items * sizeof(gunichar2));
         if (ret < 0) {
             goto delete_and_exit;
         }
@@ -1880,13 +1870,13 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
 
 
     /* Creates (B),(C) */
-    ret = vhdx_create_new_headers(blk, image_size, log_size);
+    ret = vhdx_create_new_headers(blk_bs(blk), image_size, log_size);
     if (ret < 0) {
         goto delete_and_exit;
     }
 
     /* Creates (D),(E),(G) explicitly. (F) created as by-product */
-    ret = vhdx_create_new_region_table(blk, image_size, block_size, 512,
+    ret = vhdx_create_new_region_table(blk_bs(blk), image_size, block_size, 512,
                                        log_size, use_zero_blocks, image_type,
                                        &metadata_offset);
     if (ret < 0) {
@@ -1894,7 +1884,7 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
     }
 
     /* Creates (H) */
-    ret = vhdx_create_new_metadata(blk, image_size, block_size, 512,
+    ret = vhdx_create_new_metadata(blk_bs(blk), image_size, block_size, 512,
                                    metadata_offset, image_type);
     if (ret < 0) {
         goto delete_and_exit;
index 46d474e..45f9d3c 100644 (file)
 #include "qapi/qmp/qerror.h"
 #include "qemu/error-report.h"
 #include "qemu/module.h"
-#include "qemu/bswap.h"
 #include "migration/migration.h"
 #include "qemu/cutils.h"
 #include <zlib.h>
+#include <glib.h>
 
 #define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
 #define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
@@ -252,7 +252,7 @@ static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
     int ret;
 
     desc = g_malloc0(DESC_SIZE);
-    ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
+    ret = bdrv_pread(bs->file->bs, s->desc_offset, desc, DESC_SIZE);
     if (ret < 0) {
         g_free(desc);
         return 0;
@@ -286,7 +286,7 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
 
     desc = g_malloc0(DESC_SIZE);
     tmp_desc = g_malloc0(DESC_SIZE);
-    ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
+    ret = bdrv_pread(bs->file->bs, s->desc_offset, desc, DESC_SIZE);
     if (ret < 0) {
         goto out;
     }
@@ -306,7 +306,7 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
         pstrcat(desc, DESC_SIZE, tmp_desc);
     }
 
-    ret = bdrv_pwrite_sync(bs->file, s->desc_offset, desc, DESC_SIZE);
+    ret = bdrv_pwrite_sync(bs->file->bs, s->desc_offset, desc, DESC_SIZE);
 
 out:
     g_free(desc);
@@ -350,7 +350,7 @@ static int vmdk_parent_open(BlockDriverState *bs)
     int ret;
 
     desc = g_malloc0(DESC_SIZE + 1);
-    ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
+    ret = bdrv_pread(bs->file->bs, s->desc_offset, desc, DESC_SIZE);
     if (ret < 0) {
         goto out;
     }
@@ -454,7 +454,7 @@ static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent,
         return -ENOMEM;
     }
 
-    ret = bdrv_pread(extent->file,
+    ret = bdrv_pread(extent->file->bs,
                      extent->l1_table_offset,
                      extent->l1_table,
                      l1_size);
@@ -474,7 +474,7 @@ static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent,
             ret = -ENOMEM;
             goto fail_l1;
         }
-        ret = bdrv_pread(extent->file,
+        ret = bdrv_pread(extent->file->bs,
                          extent->l1_backup_table_offset,
                          extent->l1_backup_table,
                          l1_size);
@@ -508,7 +508,7 @@ static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
     VMDK3Header header;
     VmdkExtent *extent;
 
-    ret = bdrv_pread(file, sizeof(magic), &header, sizeof(header));
+    ret = bdrv_pread(file->bs, sizeof(magic), &header, sizeof(header));
     if (ret < 0) {
         error_setg_errno(errp, -ret,
                          "Could not read header from file '%s'",
@@ -538,13 +538,14 @@ static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
 static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
                                QDict *options, Error **errp);
 
-static char *vmdk_read_desc(BdrvChild *file, uint64_t desc_offset, Error **errp)
+static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
+                            Error **errp)
 {
     int64_t size;
     char *buf;
     int ret;
 
-    size = bdrv_getlength(file->bs);
+    size = bdrv_getlength(file);
     if (size < 0) {
         error_setg_errno(errp, -size, "Could not access file");
         return NULL;
@@ -585,7 +586,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
     int64_t l1_backup_offset = 0;
     bool compressed;
 
-    ret = bdrv_pread(file, sizeof(magic), &header, sizeof(header));
+    ret = bdrv_pread(file->bs, sizeof(magic), &header, sizeof(header));
     if (ret < 0) {
         error_setg_errno(errp, -ret,
                          "Could not read header from file '%s'",
@@ -595,7 +596,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
     if (header.capacity == 0) {
         uint64_t desc_offset = le64_to_cpu(header.desc_offset);
         if (desc_offset) {
-            char *buf = vmdk_read_desc(file, desc_offset << 9, errp);
+            char *buf = vmdk_read_desc(file->bs, desc_offset << 9, errp);
             if (!buf) {
                 return -EINVAL;
             }
@@ -635,7 +636,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
             } QEMU_PACKED eos_marker;
         } QEMU_PACKED footer;
 
-        ret = bdrv_pread(file,
+        ret = bdrv_pread(file->bs,
             bs->file->bs->total_sectors * 512 - 1536,
             &footer, sizeof(footer));
         if (ret < 0) {
@@ -873,7 +874,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
             extent->flat_start_offset = flat_offset << 9;
         } else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
             /* SPARSE extent and VMFSSPARSE extent are both "COWD" sparse file*/
-            char *buf = vmdk_read_desc(extent_file, 0, errp);
+            char *buf = vmdk_read_desc(extent_file->bs, 0, errp);
             if (!buf) {
                 ret = -EINVAL;
             } else {
@@ -942,7 +943,7 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
     BDRVVmdkState *s = bs->opaque;
     uint32_t magic;
 
-    buf = vmdk_read_desc(bs->file, 0, errp);
+    buf = vmdk_read_desc(bs->file->bs, 0, errp);
     if (!buf) {
         return -EINVAL;
     }
@@ -996,9 +997,9 @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp)
 
     for (i = 0; i < s->num_extents; i++) {
         if (!s->extents[i].flat) {
-            bs->bl.pwrite_zeroes_alignment =
-                MAX(bs->bl.pwrite_zeroes_alignment,
-                    s->extents[i].cluster_sectors << BDRV_SECTOR_BITS);
+            bs->bl.write_zeroes_alignment =
+                MAX(bs->bl.write_zeroes_alignment,
+                    s->extents[i].cluster_sectors);
         }
     }
 }
@@ -1015,26 +1016,27 @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp)
  */
 static int get_whole_cluster(BlockDriverState *bs,
                              VmdkExtent *extent,
-                             uint64_t cluster_offset,
-                             uint64_t offset,
-                             uint64_t skip_start_bytes,
-                             uint64_t skip_end_bytes)
+                             uint64_t cluster_sector_num,
+                             uint64_t sector_num,
+                             uint64_t skip_start_sector,
+                             uint64_t skip_end_sector)
 {
     int ret = VMDK_OK;
     int64_t cluster_bytes;
     uint8_t *whole_grain;
 
     /* For COW, align request sector_num to cluster start */
+    sector_num = QEMU_ALIGN_DOWN(sector_num, extent->cluster_sectors);
     cluster_bytes = extent->cluster_sectors << BDRV_SECTOR_BITS;
-    offset = QEMU_ALIGN_DOWN(offset, cluster_bytes);
     whole_grain = qemu_blockalign(bs, cluster_bytes);
 
     if (!bs->backing) {
-        memset(whole_grain, 0, skip_start_bytes);
-        memset(whole_grain + skip_end_bytes, 0, cluster_bytes - skip_end_bytes);
+        memset(whole_grain, 0,  skip_start_sector << BDRV_SECTOR_BITS);
+        memset(whole_grain + (skip_end_sector << BDRV_SECTOR_BITS), 0,
+               cluster_bytes - (skip_end_sector << BDRV_SECTOR_BITS));
     }
 
-    assert(skip_end_bytes <= cluster_bytes);
+    assert(skip_end_sector <= extent->cluster_sectors);
     /* we will be here if it's first write on non-exist grain(cluster).
      * try to read from parent image, if exist */
     if (bs->backing && !vmdk_is_cid_valid(bs)) {
@@ -1043,43 +1045,42 @@ static int get_whole_cluster(BlockDriverState *bs,
     }
 
     /* Read backing data before skip range */
-    if (skip_start_bytes > 0) {
+    if (skip_start_sector > 0) {
         if (bs->backing) {
-            ret = bdrv_pread(bs->backing, offset, whole_grain,
-                             skip_start_bytes);
+            ret = bdrv_read(bs->backing->bs, sector_num,
+                            whole_grain, skip_start_sector);
             if (ret < 0) {
                 ret = VMDK_ERROR;
                 goto exit;
             }
         }
-        ret = bdrv_pwrite(extent->file, cluster_offset, whole_grain,
-                          skip_start_bytes);
+        ret = bdrv_write(extent->file->bs, cluster_sector_num, whole_grain,
+                         skip_start_sector);
         if (ret < 0) {
             ret = VMDK_ERROR;
             goto exit;
         }
     }
     /* Read backing data after skip range */
-    if (skip_end_bytes < cluster_bytes) {
+    if (skip_end_sector < extent->cluster_sectors) {
         if (bs->backing) {
-            ret = bdrv_pread(bs->backing, offset + skip_end_bytes,
-                             whole_grain + skip_end_bytes,
-                             cluster_bytes - skip_end_bytes);
+            ret = bdrv_read(bs->backing->bs, sector_num + skip_end_sector,
+                            whole_grain + (skip_end_sector << BDRV_SECTOR_BITS),
+                            extent->cluster_sectors - skip_end_sector);
             if (ret < 0) {
                 ret = VMDK_ERROR;
                 goto exit;
             }
         }
-        ret = bdrv_pwrite(extent->file, cluster_offset + skip_end_bytes,
-                          whole_grain + skip_end_bytes,
-                          cluster_bytes - skip_end_bytes);
+        ret = bdrv_write(extent->file->bs, cluster_sector_num + skip_end_sector,
+                         whole_grain + (skip_end_sector << BDRV_SECTOR_BITS),
+                         extent->cluster_sectors - skip_end_sector);
         if (ret < 0) {
             ret = VMDK_ERROR;
             goto exit;
         }
     }
 
-    ret = VMDK_OK;
 exit:
     qemu_vfree(whole_grain);
     return ret;
@@ -1090,7 +1091,8 @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
 {
     offset = cpu_to_le32(offset);
     /* update L2 table */
-    if (bdrv_pwrite_sync(extent->file,
+    if (bdrv_pwrite_sync(
+                extent->file->bs,
                 ((int64_t)m_data->l2_offset * 512)
                     + (m_data->l2_index * sizeof(offset)),
                 &offset, sizeof(offset)) < 0) {
@@ -1099,7 +1101,8 @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
     /* update backup L2 table */
     if (extent->l1_backup_table_offset != 0) {
         m_data->l2_offset = extent->l1_backup_table[m_data->l1_index];
-        if (bdrv_pwrite_sync(extent->file,
+        if (bdrv_pwrite_sync(
+                    extent->file->bs,
                     ((int64_t)m_data->l2_offset * 512)
                         + (m_data->l2_index * sizeof(offset)),
                     &offset, sizeof(offset)) < 0) {
@@ -1139,8 +1142,8 @@ static int get_cluster_offset(BlockDriverState *bs,
                               uint64_t offset,
                               bool allocate,
                               uint64_t *cluster_offset,
-                              uint64_t skip_start_bytes,
-                              uint64_t skip_end_bytes)
+                              uint64_t skip_start_sector,
+                              uint64_t skip_end_sector)
 {
     unsigned int l1_index, l2_offset, l2_index;
     int min_index, i, j;
@@ -1188,7 +1191,8 @@ static int get_cluster_offset(BlockDriverState *bs,
         }
     }
     l2_table = extent->l2_cache + (min_index * extent->l2_size);
-    if (bdrv_pread(extent->file,
+    if (bdrv_pread(
+                extent->file->bs,
                 (int64_t)l2_offset * 512,
                 l2_table,
                 extent->l2_size * sizeof(uint32_t)
@@ -1202,6 +1206,13 @@ static int get_cluster_offset(BlockDriverState *bs,
     l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
     cluster_sector = le32_to_cpu(l2_table[l2_index]);
 
+    if (m_data) {
+        m_data->valid = 1;
+        m_data->l1_index = l1_index;
+        m_data->l2_index = l2_index;
+        m_data->l2_offset = l2_offset;
+        m_data->l2_cache_entry = &l2_table[l2_index];
+    }
     if (extent->has_zero_grain && cluster_sector == VMDK_GTE_ZEROED) {
         zeroed = true;
     }
@@ -1219,18 +1230,13 @@ static int get_cluster_offset(BlockDriverState *bs,
          * This problem may occur because of insufficient space on host disk
          * or inappropriate VM shutdown.
          */
-        ret = get_whole_cluster(bs, extent, cluster_sector * BDRV_SECTOR_SIZE,
-                                offset, skip_start_bytes, skip_end_bytes);
+        ret = get_whole_cluster(bs, extent,
+                                cluster_sector,
+                                offset >> BDRV_SECTOR_BITS,
+                                skip_start_sector, skip_end_sector);
         if (ret) {
             return ret;
         }
-        if (m_data) {
-            m_data->valid = 1;
-            m_data->l1_index = l1_index;
-            m_data->l2_index = l2_index;
-            m_data->l2_offset = l2_offset;
-            m_data->l2_cache_entry = &l2_table[l2_index];
-        }
     }
     *cluster_offset = cluster_sector << BDRV_SECTOR_BITS;
     return VMDK_OK;
@@ -1253,24 +1259,15 @@ static VmdkExtent *find_extent(BDRVVmdkState *s,
     return NULL;
 }
 
-static inline uint64_t vmdk_find_offset_in_cluster(VmdkExtent *extent,
-                                                   int64_t offset)
-{
-    uint64_t extent_begin_offset, extent_relative_offset;
-    uint64_t cluster_size = extent->cluster_sectors * BDRV_SECTOR_SIZE;
-
-    extent_begin_offset =
-        (extent->end_sector - extent->sectors) * BDRV_SECTOR_SIZE;
-    extent_relative_offset = offset - extent_begin_offset;
-    return extent_relative_offset % cluster_size;
-}
-
 static inline uint64_t vmdk_find_index_in_cluster(VmdkExtent *extent,
                                                   int64_t sector_num)
 {
-    uint64_t offset;
-    offset = vmdk_find_offset_in_cluster(extent, sector_num * BDRV_SECTOR_SIZE);
-    return offset / BDRV_SECTOR_SIZE;
+    uint64_t index_in_cluster, extent_begin_sector, extent_relative_sector_num;
+
+    extent_begin_sector = extent->end_sector - extent->sectors;
+    extent_relative_sector_num = sector_num - extent_begin_sector;
+    index_in_cluster = extent_relative_sector_num % extent->cluster_sectors;
+    return index_in_cluster;
 }
 
 static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
@@ -1322,57 +1319,38 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
 }
 
 static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
-                            int64_t offset_in_cluster, QEMUIOVector *qiov,
-                            uint64_t qiov_offset, uint64_t n_bytes,
-                            uint64_t offset)
+                            int64_t offset_in_cluster, const uint8_t *buf,
+                            int nb_sectors, int64_t sector_num)
 {
     int ret;
     VmdkGrainMarker *data = NULL;
     uLongf buf_len;
-    QEMUIOVector local_qiov;
-    struct iovec iov;
+    const uint8_t *write_buf = buf;
+    int write_len = nb_sectors * 512;
     int64_t write_offset;
     int64_t write_end_sector;
 
     if (extent->compressed) {
-        void *compressed_data;
-
         if (!extent->has_marker) {
             ret = -EINVAL;
             goto out;
         }
         buf_len = (extent->cluster_sectors << 9) * 2;
         data = g_malloc(buf_len + sizeof(VmdkGrainMarker));
-
-        compressed_data = g_malloc(n_bytes);
-        qemu_iovec_to_buf(qiov, qiov_offset, compressed_data, n_bytes);
-        ret = compress(data->data, &buf_len, compressed_data, n_bytes);
-        g_free(compressed_data);
-
-        if (ret != Z_OK || buf_len == 0) {
+        if (compress(data->data, &buf_len, buf, nb_sectors << 9) != Z_OK ||
+                buf_len == 0) {
             ret = -EINVAL;
             goto out;
         }
-
-        data->lba = offset >> BDRV_SECTOR_BITS;
+        data->lba = sector_num;
         data->size = buf_len;
-
-        n_bytes = buf_len + sizeof(VmdkGrainMarker);
-        iov = (struct iovec) {
-            .iov_base   = data,
-            .iov_len    = n_bytes,
-        };
-        qemu_iovec_init_external(&local_qiov, &iov, 1);
-    } else {
-        qemu_iovec_init(&local_qiov, qiov->niov);
-        qemu_iovec_concat(&local_qiov, qiov, qiov_offset, n_bytes);
+        write_buf = (uint8_t *)data;
+        write_len = buf_len + sizeof(VmdkGrainMarker);
     }
-
     write_offset = cluster_offset + offset_in_cluster,
-    ret = bdrv_co_pwritev(extent->file, write_offset, n_bytes,
-                          &local_qiov, 0);
+    ret = bdrv_pwrite(extent->file->bs, write_offset, write_buf, write_len);
 
-    write_end_sector = DIV_ROUND_UP(write_offset + n_bytes, BDRV_SECTOR_SIZE);
+    write_end_sector = DIV_ROUND_UP(write_offset + write_len, BDRV_SECTOR_SIZE);
 
     if (extent->compressed) {
         extent->next_cluster_sector = write_end_sector;
@@ -1381,21 +1359,19 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
                                           write_end_sector);
     }
 
-    if (ret < 0) {
+    if (ret != write_len) {
+        ret = ret < 0 ? ret : -EIO;
         goto out;
     }
     ret = 0;
  out:
     g_free(data);
-    if (!extent->compressed) {
-        qemu_iovec_destroy(&local_qiov);
-    }
     return ret;
 }
 
 static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
-                            int64_t offset_in_cluster, QEMUIOVector *qiov,
-                            int bytes)
+                            int64_t offset_in_cluster, uint8_t *buf,
+                            int nb_sectors)
 {
     int ret;
     int cluster_bytes, buf_bytes;
@@ -1407,20 +1383,21 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
 
 
     if (!extent->compressed) {
-        ret = bdrv_co_preadv(extent->file,
-                             cluster_offset + offset_in_cluster, bytes,
-                             qiov, 0);
-        if (ret < 0) {
-            return ret;
+        ret = bdrv_pread(extent->file->bs,
+                          cluster_offset + offset_in_cluster,
+                          buf, nb_sectors * 512);
+        if (ret == nb_sectors * 512) {
+            return 0;
+        } else {
+            return -EIO;
         }
-        return 0;
     }
     cluster_bytes = extent->cluster_sectors * 512;
     /* Read two clusters in case GrainMarker + compressed data > one cluster */
     buf_bytes = cluster_bytes * 2;
     cluster_buf = g_malloc(buf_bytes);
     uncomp_buf = g_malloc(cluster_bytes);
-    ret = bdrv_pread(extent->file,
+    ret = bdrv_pread(extent->file->bs,
                 cluster_offset,
                 cluster_buf, buf_bytes);
     if (ret < 0) {
@@ -1445,11 +1422,11 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
 
     }
     if (offset_in_cluster < 0 ||
-            offset_in_cluster + bytes > buf_len) {
+            offset_in_cluster + nb_sectors * 512 > buf_len) {
         ret = -EINVAL;
         goto out;
     }
-    qemu_iovec_from_buf(qiov, 0, uncomp_buf + offset_in_cluster, bytes);
+    memcpy(buf, uncomp_buf + offset_in_cluster, nb_sectors * 512);
     ret = 0;
 
  out:
@@ -1458,73 +1435,64 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
     return ret;
 }
 
-static int coroutine_fn
-vmdk_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
-               QEMUIOVector *qiov, int flags)
+static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
+                    uint8_t *buf, int nb_sectors)
 {
     BDRVVmdkState *s = bs->opaque;
     int ret;
-    uint64_t n_bytes, offset_in_cluster;
+    uint64_t n, index_in_cluster;
     VmdkExtent *extent = NULL;
-    QEMUIOVector local_qiov;
     uint64_t cluster_offset;
-    uint64_t bytes_done = 0;
 
-    qemu_iovec_init(&local_qiov, qiov->niov);
-    qemu_co_mutex_lock(&s->lock);
-
-    while (bytes > 0) {
-        extent = find_extent(s, offset >> BDRV_SECTOR_BITS, extent);
+    while (nb_sectors > 0) {
+        extent = find_extent(s, sector_num, extent);
         if (!extent) {
-            ret = -EIO;
-            goto fail;
+            return -EIO;
         }
         ret = get_cluster_offset(bs, extent, NULL,
-                                 offset, false, &cluster_offset, 0, 0);
-        offset_in_cluster = vmdk_find_offset_in_cluster(extent, offset);
-
-        n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE
-                             - offset_in_cluster);
-
+                                 sector_num << 9, false, &cluster_offset,
+                                 0, 0);
+        index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
+        n = extent->cluster_sectors - index_in_cluster;
+        if (n > nb_sectors) {
+            n = nb_sectors;
+        }
         if (ret != VMDK_OK) {
             /* if not allocated, try to read from parent image, if exist */
             if (bs->backing && ret != VMDK_ZEROED) {
                 if (!vmdk_is_cid_valid(bs)) {
-                    ret = -EINVAL;
-                    goto fail;
+                    return -EINVAL;
                 }
-
-                qemu_iovec_reset(&local_qiov);
-                qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
-
-                ret = bdrv_co_preadv(bs->backing, offset, n_bytes,
-                                     &local_qiov, 0);
+                ret = bdrv_read(bs->backing->bs, sector_num, buf, n);
                 if (ret < 0) {
-                    goto fail;
+                    return ret;
                 }
             } else {
-                qemu_iovec_memset(qiov, bytes_done, 0, n_bytes);
+                memset(buf, 0, 512 * n);
             }
         } else {
-            qemu_iovec_reset(&local_qiov);
-            qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
-
-            ret = vmdk_read_extent(extent, cluster_offset, offset_in_cluster,
-                                   &local_qiov, n_bytes);
+            ret = vmdk_read_extent(extent,
+                            cluster_offset, index_in_cluster * 512,
+                            buf, n);
             if (ret) {
-                goto fail;
+                return ret;
             }
         }
-        bytes -= n_bytes;
-        offset += n_bytes;
-        bytes_done += n_bytes;
+        nb_sectors -= n;
+        sector_num += n;
+        buf += n * 512;
     }
+    return 0;
+}
 
-    ret = 0;
-fail:
+static coroutine_fn int vmdk_co_read(BlockDriverState *bs, int64_t sector_num,
+                                     uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVVmdkState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = vmdk_read(bs, sector_num, buf, nb_sectors);
     qemu_co_mutex_unlock(&s->lock);
-    qemu_iovec_destroy(&local_qiov);
-
     return ret;
 }
 
@@ -1538,38 +1506,38 @@ fail:
  *
  * Returns: error code with 0 for success.
  */
-static int vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
-                       uint64_t bytes, QEMUIOVector *qiov,
-                       bool zeroed, bool zero_dry_run)
+static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
+                      const uint8_t *buf, int nb_sectors,
+                      bool zeroed, bool zero_dry_run)
 {
     BDRVVmdkState *s = bs->opaque;
     VmdkExtent *extent = NULL;
     int ret;
-    int64_t offset_in_cluster, n_bytes;
+    int64_t index_in_cluster, n;
     uint64_t cluster_offset;
-    uint64_t bytes_done = 0;
     VmdkMetaData m_data;
 
-    if (DIV_ROUND_UP(offset, BDRV_SECTOR_SIZE) > bs->total_sectors) {
-        error_report("Wrong offset: offset=0x%" PRIx64
+    if (sector_num > bs->total_sectors) {
+        error_report("Wrong offset: sector_num=0x%" PRIx64
                      " total_sectors=0x%" PRIx64,
-                     offset, bs->total_sectors);
+                     sector_num, bs->total_sectors);
         return -EIO;
     }
 
-    while (bytes > 0) {
-        extent = find_extent(s, offset >> BDRV_SECTOR_BITS, extent);
+    while (nb_sectors > 0) {
+        extent = find_extent(s, sector_num, extent);
         if (!extent) {
             return -EIO;
         }
-        offset_in_cluster = vmdk_find_offset_in_cluster(extent, offset);
-        n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE
-                             - offset_in_cluster);
-
-        ret = get_cluster_offset(bs, extent, &m_data, offset,
+        index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
+        n = extent->cluster_sectors - index_in_cluster;
+        if (n > nb_sectors) {
+            n = nb_sectors;
+        }
+        ret = get_cluster_offset(bs, extent, &m_data, sector_num << 9,
                                  !(extent->compressed || zeroed),
-                                 &cluster_offset, offset_in_cluster,
-                                 offset_in_cluster + n_bytes);
+                                 &cluster_offset,
+                                 index_in_cluster, index_in_cluster + n);
         if (extent->compressed) {
             if (ret == VMDK_OK) {
                 /* Refuse write to allocated cluster for streamOptimized */
@@ -1578,7 +1546,7 @@ static int vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
                 return -EIO;
             } else {
                 /* allocate */
-                ret = get_cluster_offset(bs, extent, &m_data, offset,
+                ret = get_cluster_offset(bs, extent, &m_data, sector_num << 9,
                                          true, &cluster_offset, 0, 0);
             }
         }
@@ -1588,9 +1556,9 @@ static int vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
         if (zeroed) {
             /* Do zeroed write, buf is ignored */
             if (extent->has_zero_grain &&
-                    offset_in_cluster == 0 &&
-                    n_bytes >= extent->cluster_sectors * BDRV_SECTOR_SIZE) {
-                n_bytes = extent->cluster_sectors * BDRV_SECTOR_SIZE;
+                    index_in_cluster == 0 &&
+                    n >= extent->cluster_sectors) {
+                n = extent->cluster_sectors;
                 if (!zero_dry_run) {
                     /* update L2 tables */
                     if (vmdk_L2update(extent, &m_data, VMDK_GTE_ZEROED)
@@ -1602,8 +1570,9 @@ static int vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
                 return -ENOTSUP;
             }
         } else {
-            ret = vmdk_write_extent(extent, cluster_offset, offset_in_cluster,
-                                    qiov, bytes_done, n_bytes, offset);
+            ret = vmdk_write_extent(extent,
+                            cluster_offset, index_in_cluster * 512,
+                            buf, n, sector_num);
             if (ret) {
                 return ret;
             }
@@ -1616,9 +1585,9 @@ static int vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
                 }
             }
         }
-        bytes -= n_bytes;
-        offset += n_bytes;
-        bytes_done += n_bytes;
+        nb_sectors -= n;
+        sector_num += n;
+        buf += n * 512;
 
         /* update CID on the first write every time the virtual disk is
          * opened */
@@ -1633,84 +1602,43 @@ static int vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
     return 0;
 }
 
-static int coroutine_fn
-vmdk_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
-                QEMUIOVector *qiov, int flags)
+static coroutine_fn int vmdk_co_write(BlockDriverState *bs, int64_t sector_num,
+                                      const uint8_t *buf, int nb_sectors)
 {
     int ret;
     BDRVVmdkState *s = bs->opaque;
     qemu_co_mutex_lock(&s->lock);
-    ret = vmdk_pwritev(bs, offset, bytes, qiov, false, false);
+    ret = vmdk_write(bs, sector_num, buf, nb_sectors, false, false);
     qemu_co_mutex_unlock(&s->lock);
     return ret;
 }
 
-typedef struct VmdkWriteCompressedCo {
-    BlockDriverState *bs;
-    int64_t sector_num;
-    const uint8_t *buf;
-    int nb_sectors;
-    int ret;
-} VmdkWriteCompressedCo;
-
-static void vmdk_co_write_compressed(void *opaque)
-{
-    VmdkWriteCompressedCo *co = opaque;
-    QEMUIOVector local_qiov;
-    uint64_t offset = co->sector_num * BDRV_SECTOR_SIZE;
-    uint64_t bytes = co->nb_sectors * BDRV_SECTOR_SIZE;
-
-    struct iovec iov = (struct iovec) {
-        .iov_base   = (uint8_t*) co->buf,
-        .iov_len    = bytes,
-    };
-    qemu_iovec_init_external(&local_qiov, &iov, 1);
-
-    co->ret = vmdk_pwritev(co->bs, offset, bytes, &local_qiov, false, false);
-}
-
 static int vmdk_write_compressed(BlockDriverState *bs,
                                  int64_t sector_num,
                                  const uint8_t *buf,
                                  int nb_sectors)
 {
     BDRVVmdkState *s = bs->opaque;
-
     if (s->num_extents == 1 && s->extents[0].compressed) {
-        Coroutine *co;
-        AioContext *aio_context = bdrv_get_aio_context(bs);
-        VmdkWriteCompressedCo data = {
-            .bs         = bs,
-            .sector_num = sector_num,
-            .buf        = buf,
-            .nb_sectors = nb_sectors,
-            .ret        = -EINPROGRESS,
-        };
-        co = qemu_coroutine_create(vmdk_co_write_compressed, &data);
-        qemu_coroutine_enter(co);
-        while (data.ret == -EINPROGRESS) {
-            aio_poll(aio_context, true);
-        }
-        return data.ret;
+        return vmdk_write(bs, sector_num, buf, nb_sectors, false, false);
     } else {
         return -ENOTSUP;
     }
 }
 
-static int coroutine_fn vmdk_co_pwrite_zeroes(BlockDriverState *bs,
-                                              int64_t offset,
-                                              int bytes,
-                                              BdrvRequestFlags flags)
+static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs,
+                                             int64_t sector_num,
+                                             int nb_sectors,
+                                             BdrvRequestFlags flags)
 {
     int ret;
     BDRVVmdkState *s = bs->opaque;
-
     qemu_co_mutex_lock(&s->lock);
     /* write zeroes could fail if sectors not aligned to cluster, test it with
      * dry_run == true before really updating image */
-    ret = vmdk_pwritev(bs, offset, bytes, NULL, true, true);
+    ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, true);
     if (!ret) {
-        ret = vmdk_pwritev(bs, offset, bytes, NULL, true, false);
+        ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, false);
     }
     qemu_co_mutex_unlock(&s->lock);
     return ret;
@@ -1800,12 +1728,12 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
     header.check_bytes[3] = 0xa;
 
     /* write all the data */
-    ret = blk_pwrite(blk, 0, &magic, sizeof(magic), 0);
+    ret = blk_pwrite(blk, 0, &magic, sizeof(magic));
     if (ret < 0) {
         error_setg(errp, QERR_IO_ERROR);
         goto exit;
     }
-    ret = blk_pwrite(blk, sizeof(magic), &header, sizeof(header), 0);
+    ret = blk_pwrite(blk, sizeof(magic), &header, sizeof(header));
     if (ret < 0) {
         error_setg(errp, QERR_IO_ERROR);
         goto exit;
@@ -1825,7 +1753,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
         gd_buf[i] = cpu_to_le32(tmp);
     }
     ret = blk_pwrite(blk, le64_to_cpu(header.rgd_offset) * BDRV_SECTOR_SIZE,
-                     gd_buf, gd_buf_size, 0);
+                     gd_buf, gd_buf_size);
     if (ret < 0) {
         error_setg(errp, QERR_IO_ERROR);
         goto exit;
@@ -1837,7 +1765,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
         gd_buf[i] = cpu_to_le32(tmp);
     }
     ret = blk_pwrite(blk, le64_to_cpu(header.gd_offset) * BDRV_SECTOR_SIZE,
-                     gd_buf, gd_buf_size, 0);
+                     gd_buf, gd_buf_size);
     if (ret < 0) {
         error_setg(errp, QERR_IO_ERROR);
         goto exit;
@@ -1901,8 +1829,8 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
     int64_t total_size = 0, filesize;
     char *adapter_type = NULL;
     char *backing_file = NULL;
-    char *hw_version = NULL;
     char *fmt = NULL;
+    int flags = 0;
     int ret = 0;
     bool flat, split, compress;
     GString *ext_desc_lines;
@@ -1933,7 +1861,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
         "# The Disk Data Base\n"
         "#DDB\n"
         "\n"
-        "ddb.virtualHWVersion = \"%s\"\n"
+        "ddb.virtualHWVersion = \"%d\"\n"
         "ddb.geometry.cylinders = \"%" PRId64 "\"\n"
         "ddb.geometry.heads = \"%" PRIu32 "\"\n"
         "ddb.geometry.sectors = \"63\"\n"
@@ -1950,20 +1878,8 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
                           BDRV_SECTOR_SIZE);
     adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE);
     backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
-    hw_version = qemu_opt_get_del(opts, BLOCK_OPT_HWVERSION);
     if (qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false)) {
-        if (strcmp(hw_version, "undefined")) {
-            error_setg(errp,
-                       "compat6 cannot be enabled with hwversion set");
-            ret = -EINVAL;
-            goto exit;
-        }
-        g_free(hw_version);
-        hw_version = g_strdup("6");
-    }
-    if (strcmp(hw_version, "undefined") == 0) {
-        g_free(hw_version);
-        hw_version = g_strdup("4");
+        flags |= BLOCK_FLAG_COMPAT6;
     }
     fmt = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
     if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false)) {
@@ -2085,7 +2001,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
                            fmt,
                            parent_desc_line,
                            ext_desc_lines->str,
-                           hw_version,
+                           (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
                            total_size /
                                (int64_t)(63 * number_heads * BDRV_SECTOR_SIZE),
                            number_heads,
@@ -2112,7 +2028,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
 
     blk_set_allow_write_beyond_eof(new_blk, true);
 
-    ret = blk_pwrite(new_blk, desc_offset, desc, desc_len, 0);
+    ret = blk_pwrite(new_blk, desc_offset, desc, desc_len);
     if (ret < 0) {
         error_setg_errno(errp, -ret, "Could not write description");
         goto exit;
@@ -2131,7 +2047,6 @@ exit:
     }
     g_free(adapter_type);
     g_free(backing_file);
-    g_free(hw_version);
     g_free(fmt);
     g_free(desc);
     g_free(path);
@@ -2335,6 +2250,27 @@ static int vmdk_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
     return 0;
 }
 
+static void vmdk_detach_aio_context(BlockDriverState *bs)
+{
+    BDRVVmdkState *s = bs->opaque;
+    int i;
+
+    for (i = 0; i < s->num_extents; i++) {
+        bdrv_detach_aio_context(s->extents[i].file->bs);
+    }
+}
+
+static void vmdk_attach_aio_context(BlockDriverState *bs,
+                                    AioContext *new_context)
+{
+    BDRVVmdkState *s = bs->opaque;
+    int i;
+
+    for (i = 0; i < s->num_extents; i++) {
+        bdrv_attach_aio_context(s->extents[i].file->bs, new_context);
+    }
+}
+
 static QemuOptsList vmdk_create_opts = {
     .name = "vmdk-create-opts",
     .head = QTAILQ_HEAD_INITIALIZER(vmdk_create_opts.head),
@@ -2362,12 +2298,6 @@ static QemuOptsList vmdk_create_opts = {
             .def_value_str = "off"
         },
         {
-            .name = BLOCK_OPT_HWVERSION,
-            .type = QEMU_OPT_STRING,
-            .help = "VMDK hardware version",
-            .def_value_str = "undefined"
-        },
-        {
             .name = BLOCK_OPT_SUBFMT,
             .type = QEMU_OPT_STRING,
             .help =
@@ -2391,10 +2321,10 @@ static BlockDriver bdrv_vmdk = {
     .bdrv_open                    = vmdk_open,
     .bdrv_check                   = vmdk_check,
     .bdrv_reopen_prepare          = vmdk_reopen_prepare,
-    .bdrv_co_preadv               = vmdk_co_preadv,
-    .bdrv_co_pwritev              = vmdk_co_pwritev,
+    .bdrv_read                    = vmdk_co_read,
+    .bdrv_write                   = vmdk_co_write,
     .bdrv_write_compressed        = vmdk_write_compressed,
-    .bdrv_co_pwrite_zeroes        = vmdk_co_pwrite_zeroes,
+    .bdrv_co_write_zeroes         = vmdk_co_write_zeroes,
     .bdrv_close                   = vmdk_close,
     .bdrv_create                  = vmdk_create,
     .bdrv_co_flush_to_disk        = vmdk_co_flush,
@@ -2404,6 +2334,8 @@ static BlockDriver bdrv_vmdk = {
     .bdrv_get_specific_info       = vmdk_get_specific_info,
     .bdrv_refresh_limits          = vmdk_refresh_limits,
     .bdrv_get_info                = vmdk_get_info,
+    .bdrv_detach_aio_context      = vmdk_detach_aio_context,
+    .bdrv_attach_aio_context      = vmdk_attach_aio_context,
 
     .supports_backing             = true,
     .create_opts                  = &vmdk_create_opts,
index 43707ed..3e2ea69 100644 (file)
@@ -29,7 +29,6 @@
 #include "sysemu/block-backend.h"
 #include "qemu/module.h"
 #include "migration/migration.h"
-#include "qemu/bswap.h"
 #if defined(CONFIG_UUID)
 #include <uuid/uuid.h>
 #endif
@@ -237,7 +236,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
         goto fail;
     }
 
-    ret = bdrv_pread(bs->file, 0, s->footer_buf, HEADER_SIZE);
+    ret = bdrv_pread(bs->file->bs, 0, s->footer_buf, HEADER_SIZE);
     if (ret < 0) {
         error_setg(errp, "Unable to read VHD header");
         goto fail;
@@ -257,7 +256,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
         }
 
         /* If a fixed disk, the footer is found only at the end of the file */
-        ret = bdrv_pread(bs->file, offset-HEADER_SIZE, s->footer_buf,
+        ret = bdrv_pread(bs->file->bs, offset-HEADER_SIZE, s->footer_buf,
                          HEADER_SIZE);
         if (ret < 0) {
             goto fail;
@@ -328,7 +327,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
     }
 
     if (disk_type == VHD_DYNAMIC) {
-        ret = bdrv_pread(bs->file, be64_to_cpu(footer->data_offset), buf,
+        ret = bdrv_pread(bs->file->bs, be64_to_cpu(footer->data_offset), buf,
                          HEADER_SIZE);
         if (ret < 0) {
             error_setg(errp, "Error reading dynamic VHD header");
@@ -385,7 +384,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
 
         s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);
 
-        ret = bdrv_pread(bs->file, s->bat_offset, s->pagetable,
+        ret = bdrv_pread(bs->file->bs, s->bat_offset, s->pagetable,
                          pagetable_size);
         if (ret < 0) {
             error_setg(errp, "Error reading pagetable");
@@ -455,21 +454,22 @@ static int vpc_reopen_prepare(BDRVReopenState *state,
  * The parameter write must be 1 if the offset will be used for a write
  * operation (the block bitmaps is updated then), 0 otherwise.
  */
-static inline int64_t get_image_offset(BlockDriverState *bs, uint64_t offset,
-                                       bool write)
+static inline int64_t get_sector_offset(BlockDriverState *bs,
+    int64_t sector_num, int write)
 {
     BDRVVPCState *s = bs->opaque;
+    uint64_t offset = sector_num * 512;
     uint64_t bitmap_offset, block_offset;
-    uint32_t pagetable_index, offset_in_block;
+    uint32_t pagetable_index, pageentry_index;
 
     pagetable_index = offset / s->block_size;
-    offset_in_block = offset % s->block_size;
+    pageentry_index = (offset % s->block_size) / 512;
 
     if (pagetable_index >= s->max_table_entries || s->pagetable[pagetable_index] == 0xffffffff)
         return -1; /* not allocated */
 
     bitmap_offset = 512 * (uint64_t) s->pagetable[pagetable_index];
-    block_offset = bitmap_offset + s->bitmap_size + offset_in_block;
+    block_offset = bitmap_offset + s->bitmap_size + (512 * pageentry_index);
 
     /* We must ensure that we don't write to any sectors which are marked as
        unused in the bitmap. We get away with setting all bits in the block
@@ -481,18 +481,12 @@ static inline int64_t get_image_offset(BlockDriverState *bs, uint64_t offset,
 
         s->last_bitmap_offset = bitmap_offset;
         memset(bitmap, 0xff, s->bitmap_size);
-        bdrv_pwrite_sync(bs->file, bitmap_offset, bitmap, s->bitmap_size);
+        bdrv_pwrite_sync(bs->file->bs, bitmap_offset, bitmap, s->bitmap_size);
     }
 
     return block_offset;
 }
 
-static inline int64_t get_sector_offset(BlockDriverState *bs,
-                                        int64_t sector_num, bool write)
-{
-    return get_image_offset(bs, sector_num * BDRV_SECTOR_SIZE, write);
-}
-
 /*
  * Writes the footer to the end of the image file. This is needed when the
  * file grows as it overwrites the old footer
@@ -505,7 +499,7 @@ static int rewrite_footer(BlockDriverState* bs)
     BDRVVPCState *s = bs->opaque;
     int64_t offset = s->free_data_block_offset;
 
-    ret = bdrv_pwrite_sync(bs->file, offset, s->footer_buf, HEADER_SIZE);
+    ret = bdrv_pwrite_sync(bs->file->bs, offset, s->footer_buf, HEADER_SIZE);
     if (ret < 0)
         return ret;
 
@@ -519,7 +513,7 @@ static int rewrite_footer(BlockDriverState* bs)
  *
  * Returns the sectors' offset in the image file on success and < 0 on error
  */
-static int64_t alloc_block(BlockDriverState* bs, int64_t offset)
+static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
 {
     BDRVVPCState *s = bs->opaque;
     int64_t bat_offset;
@@ -528,18 +522,19 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t offset)
     uint8_t bitmap[s->bitmap_size];
 
     /* Check if sector_num is valid */
-    if ((offset < 0) || (offset > bs->total_sectors * BDRV_SECTOR_SIZE)) {
-        return -EINVAL;
-    }
+    if ((sector_num < 0) || (sector_num > bs->total_sectors))
+        return -1;
 
     /* Write entry into in-memory BAT */
-    index = offset / s->block_size;
-    assert(s->pagetable[index] == 0xFFFFFFFF);
+    index = (sector_num * 512) / s->block_size;
+    if (s->pagetable[index] != 0xFFFFFFFF)
+        return -1;
+
     s->pagetable[index] = s->free_data_block_offset / 512;
 
     /* Initialize the block's bitmap */
     memset(bitmap, 0xff, s->bitmap_size);
-    ret = bdrv_pwrite_sync(bs->file, s->free_data_block_offset, bitmap,
+    ret = bdrv_pwrite_sync(bs->file->bs, s->free_data_block_offset, bitmap,
         s->bitmap_size);
     if (ret < 0) {
         return ret;
@@ -554,15 +549,15 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t offset)
     /* Write BAT entry to disk */
     bat_offset = s->bat_offset + (4 * index);
     bat_value = cpu_to_be32(s->pagetable[index]);
-    ret = bdrv_pwrite_sync(bs->file, bat_offset, &bat_value, 4);
+    ret = bdrv_pwrite_sync(bs->file->bs, bat_offset, &bat_value, 4);
     if (ret < 0)
         goto fail;
 
-    return get_image_offset(bs, offset, false);
+    return get_sector_offset(bs, sector_num, 0);
 
 fail:
     s->free_data_block_offset -= (s->block_size + s->bitmap_size);
-    return ret;
+    return -1;
 }
 
 static int vpc_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
@@ -578,105 +573,104 @@ static int vpc_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
     return 0;
 }
 
-static int coroutine_fn
-vpc_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
-              QEMUIOVector *qiov, int flags)
+static int vpc_read(BlockDriverState *bs, int64_t sector_num,
+                    uint8_t *buf, int nb_sectors)
 {
     BDRVVPCState *s = bs->opaque;
     int ret;
-    int64_t image_offset;
-    int64_t n_bytes;
-    int64_t bytes_done = 0;
+    int64_t offset;
+    int64_t sectors, sectors_per_block;
     VHDFooter *footer = (VHDFooter *) s->footer_buf;
-    QEMUIOVector local_qiov;
 
     if (be32_to_cpu(footer->type) == VHD_FIXED) {
-        return bdrv_co_preadv(bs->file, offset, bytes, qiov, 0);
+        return bdrv_read(bs->file->bs, sector_num, buf, nb_sectors);
     }
+    while (nb_sectors > 0) {
+        offset = get_sector_offset(bs, sector_num, 0);
 
-    qemu_co_mutex_lock(&s->lock);
-    qemu_iovec_init(&local_qiov, qiov->niov);
-
-    while (bytes > 0) {
-        image_offset = get_image_offset(bs, offset, false);
-        n_bytes = MIN(bytes, s->block_size - (offset % s->block_size));
+        sectors_per_block = s->block_size >> BDRV_SECTOR_BITS;
+        sectors = sectors_per_block - (sector_num % sectors_per_block);
+        if (sectors > nb_sectors) {
+            sectors = nb_sectors;
+        }
 
-        if (image_offset == -1) {
-            qemu_iovec_memset(qiov, bytes_done, 0, n_bytes);
+        if (offset == -1) {
+            memset(buf, 0, sectors * BDRV_SECTOR_SIZE);
         } else {
-            qemu_iovec_reset(&local_qiov);
-            qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
-
-            ret = bdrv_co_preadv(bs->file, image_offset, n_bytes,
-                                 &local_qiov, 0);
-            if (ret < 0) {
-                goto fail;
+            ret = bdrv_pread(bs->file->bs, offset, buf,
+                sectors * BDRV_SECTOR_SIZE);
+            if (ret != sectors * BDRV_SECTOR_SIZE) {
+                return -1;
             }
         }
 
-        bytes -= n_bytes;
-        offset += n_bytes;
-        bytes_done += n_bytes;
+        nb_sectors -= sectors;
+        sector_num += sectors;
+        buf += sectors * BDRV_SECTOR_SIZE;
     }
+    return 0;
+}
 
-    ret = 0;
-fail:
-    qemu_iovec_destroy(&local_qiov);
+static coroutine_fn int vpc_co_read(BlockDriverState *bs, int64_t sector_num,
+                                    uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVVPCState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = vpc_read(bs, sector_num, buf, nb_sectors);
     qemu_co_mutex_unlock(&s->lock);
-
     return ret;
 }
 
-static int coroutine_fn
-vpc_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
-               QEMUIOVector *qiov, int flags)
+static int vpc_write(BlockDriverState *bs, int64_t sector_num,
+    const uint8_t *buf, int nb_sectors)
 {
     BDRVVPCState *s = bs->opaque;
-    int64_t image_offset;
-    int64_t n_bytes;
-    int64_t bytes_done = 0;
+    int64_t offset;
+    int64_t sectors, sectors_per_block;
     int ret;
     VHDFooter *footer =  (VHDFooter *) s->footer_buf;
-    QEMUIOVector local_qiov;
 
     if (be32_to_cpu(footer->type) == VHD_FIXED) {
-        return bdrv_co_pwritev(bs->file, offset, bytes, qiov, 0);
+        return bdrv_write(bs->file->bs, sector_num, buf, nb_sectors);
     }
+    while (nb_sectors > 0) {
+        offset = get_sector_offset(bs, sector_num, 1);
 
-    qemu_co_mutex_lock(&s->lock);
-    qemu_iovec_init(&local_qiov, qiov->niov);
-
-    while (bytes > 0) {
-        image_offset = get_image_offset(bs, offset, true);
-        n_bytes = MIN(bytes, s->block_size - (offset % s->block_size));
-
-        if (image_offset == -1) {
-            image_offset = alloc_block(bs, offset);
-            if (image_offset < 0) {
-                ret = image_offset;
-                goto fail;
-            }
+        sectors_per_block = s->block_size >> BDRV_SECTOR_BITS;
+        sectors = sectors_per_block - (sector_num % sectors_per_block);
+        if (sectors > nb_sectors) {
+            sectors = nb_sectors;
         }
 
-        qemu_iovec_reset(&local_qiov);
-        qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
+        if (offset == -1) {
+            offset = alloc_block(bs, sector_num);
+            if (offset < 0)
+                return -1;
+        }
 
-        ret = bdrv_co_pwritev(bs->file, image_offset, n_bytes,
-                              &local_qiov, 0);
-        if (ret < 0) {
-            goto fail;
+        ret = bdrv_pwrite(bs->file->bs, offset, buf,
+                          sectors * BDRV_SECTOR_SIZE);
+        if (ret != sectors * BDRV_SECTOR_SIZE) {
+            return -1;
         }
 
-        bytes -= n_bytes;
-        offset += n_bytes;
-        bytes_done += n_bytes;
+        nb_sectors -= sectors;
+        sector_num += sectors;
+        buf += sectors * BDRV_SECTOR_SIZE;
     }
 
-    ret = 0;
-fail:
-    qemu_iovec_destroy(&local_qiov);
-    qemu_co_mutex_unlock(&s->lock);
+    return 0;
+}
 
+static coroutine_fn int vpc_co_write(BlockDriverState *bs, int64_t sector_num,
+                                     const uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVVPCState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = vpc_write(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
     return ret;
 }
 
@@ -789,13 +783,13 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
     block_size = 0x200000;
     num_bat_entries = (total_sectors + block_size / 512) / (block_size / 512);
 
-    ret = blk_pwrite(blk, offset, buf, HEADER_SIZE, 0);
+    ret = blk_pwrite(blk, offset, buf, HEADER_SIZE);
     if (ret < 0) {
         goto fail;
     }
 
     offset = 1536 + ((num_bat_entries * 4 + 511) & ~511);
-    ret = blk_pwrite(blk, offset, buf, HEADER_SIZE, 0);
+    ret = blk_pwrite(blk, offset, buf, HEADER_SIZE);
     if (ret < 0) {
         goto fail;
     }
@@ -805,7 +799,7 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
 
     memset(buf, 0xFF, 512);
     for (i = 0; i < (num_bat_entries * 4 + 511) / 512; i++) {
-        ret = blk_pwrite(blk, offset, buf, 512, 0);
+        ret = blk_pwrite(blk, offset, buf, 512);
         if (ret < 0) {
             goto fail;
         }
@@ -832,7 +826,7 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
     /* Write the header */
     offset = 512;
 
-    ret = blk_pwrite(blk, offset, buf, 1024, 0);
+    ret = blk_pwrite(blk, offset, buf, 1024);
     if (ret < 0) {
         goto fail;
     }
@@ -854,7 +848,7 @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
         return ret;
     }
 
-    ret = blk_pwrite(blk, total_size - HEADER_SIZE, buf, HEADER_SIZE, 0);
+    ret = blk_pwrite(blk, total_size - HEADER_SIZE, buf, HEADER_SIZE);
     if (ret < 0) {
         return ret;
     }
@@ -1062,8 +1056,8 @@ static BlockDriver bdrv_vpc = {
     .bdrv_reopen_prepare    = vpc_reopen_prepare,
     .bdrv_create            = vpc_create,
 
-    .bdrv_co_preadv             = vpc_co_preadv,
-    .bdrv_co_pwritev            = vpc_co_pwritev,
+    .bdrv_read                  = vpc_co_read,
+    .bdrv_write                 = vpc_co_write,
     .bdrv_co_get_block_status   = vpc_co_get_block_status,
 
     .bdrv_get_info          = vpc_get_info,
index ba2620f..183fc4f 100644 (file)
@@ -27,7 +27,6 @@
 #include "qapi/error.h"
 #include "block/block_int.h"
 #include "qemu/module.h"
-#include "qemu/bswap.h"
 #include "migration/migration.h"
 #include "qapi/qmp/qint.h"
 #include "qapi/qmp/qbool.h"
@@ -114,12 +113,15 @@ static inline int array_ensure_allocated(array_t* array, int index)
 
 static inline void* array_get_next(array_t* array) {
     unsigned int next = array->next;
+    void* result;
 
     if (array_ensure_allocated(array, next) < 0)
        return NULL;
 
     array->next = next + 1;
-    return array_get(array, next);
+    result = array_get(array, next);
+
+    return result;
 }
 
 static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
@@ -341,8 +343,9 @@ typedef struct BDRVVVFATState {
     unsigned int current_cluster;
 
     /* write support */
+    BlockDriverState* write_target;
     char* qcow_filename;
-    BdrvChild* qcow;
+    BlockDriverState* qcow;
     void* fat2;
     char* used_clusters;
     array_t commits;
@@ -980,7 +983,7 @@ static int init_directories(BDRVVVFATState* s,
 static BDRVVVFATState *vvv = NULL;
 #endif
 
-static int enable_write_target(BlockDriverState *bs, Error **errp);
+static int enable_write_target(BDRVVVFATState *s, Error **errp);
 static int is_consistent(BDRVVVFATState *s);
 
 static QemuOptsList runtime_opts = {
@@ -1157,8 +1160,8 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
     s->current_cluster=0xffffffff;
 
     /* read only is the default for safety */
-    bs->read_only = true;
-    s->qcow = NULL;
+    bs->read_only = 1;
+    s->qcow = s->write_target = NULL;
     s->qcow_filename = NULL;
     s->fat2 = NULL;
     s->downcase_short_names = 1;
@@ -1169,11 +1172,11 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
     s->sector_count = cyls * heads * secs - (s->first_sectors_number - 1);
 
     if (qemu_opt_get_bool(opts, "rw", false)) {
-        ret = enable_write_target(bs, errp);
+        ret = enable_write_target(s, errp);
         if (ret < 0) {
             goto fail;
         }
-        bs->read_only = false;
+        bs->read_only = 0;
     }
 
     bs->total_sectors = cyls * heads * secs;
@@ -1207,11 +1210,6 @@ fail:
     return ret;
 }
 
-static void vvfat_refresh_limits(BlockDriverState *bs, Error **errp)
-{
-    bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
-}
-
 static inline void vvfat_close_current_file(BDRVVVFATState *s)
 {
     if(s->current_mapping) {
@@ -1390,10 +1388,9 @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
           return -1;
        if (s->qcow) {
            int n;
-            if (bdrv_is_allocated(s->qcow->bs, sector_num, nb_sectors-i, &n)) {
-                DLOG(fprintf(stderr, "sectors %d+%d allocated\n",
-                             (int)sector_num, n));
-                if (bdrv_read(s->qcow, sector_num, buf + i * 0x200, n)) {
+            if (bdrv_is_allocated(s->qcow, sector_num, nb_sectors-i, &n)) {
+DLOG(fprintf(stderr, "sectors %d+%d allocated\n", (int)sector_num, n));
+                if (bdrv_read(s->qcow, sector_num, buf + i*0x200, n)) {
                     return -1;
                 }
                 i += n - 1;
@@ -1424,31 +1421,14 @@ DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
     return 0;
 }
 
-static int coroutine_fn
-vvfat_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
-                QEMUIOVector *qiov, int flags)
+static coroutine_fn int vvfat_co_read(BlockDriverState *bs, int64_t sector_num,
+                                      uint8_t *buf, int nb_sectors)
 {
     int ret;
     BDRVVVFATState *s = bs->opaque;
-    uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
-    int nb_sectors = bytes >> BDRV_SECTOR_BITS;
-    void *buf;
-
-    assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
-    assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
-
-    buf = g_try_malloc(bytes);
-    if (bytes && buf == NULL) {
-        return -ENOMEM;
-    }
-
     qemu_co_mutex_lock(&s->lock);
     ret = vvfat_read(bs, sector_num, buf, nb_sectors);
     qemu_co_mutex_unlock(&s->lock);
-
-    qemu_iovec_from_buf(qiov, 0, buf, bytes);
-    g_free(buf);
-
     return ret;
 }
 
@@ -1669,15 +1649,12 @@ static inline int cluster_was_modified(BDRVVVFATState* s, uint32_t cluster_num)
     int was_modified = 0;
     int i, dummy;
 
-    if (s->qcow == NULL) {
-        return 0;
-    }
+    if (s->qcow == NULL)
+       return 0;
 
-    for (i = 0; !was_modified && i < s->sectors_per_cluster; i++) {
-        was_modified = bdrv_is_allocated(s->qcow->bs,
-                                         cluster2sector(s, cluster_num) + i,
-                                         1, &dummy);
-    }
+    for (i = 0; !was_modified && i < s->sectors_per_cluster; i++)
+       was_modified = bdrv_is_allocated(s->qcow,
+               cluster2sector(s, cluster_num) + i, 1, &dummy);
 
     return was_modified;
 }
@@ -1826,16 +1803,11 @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
 
                vvfat_close_current_file(s);
                 for (i = 0; i < s->sectors_per_cluster; i++) {
-                    int res;
-
-                    res = bdrv_is_allocated(s->qcow->bs, offset + i, 1, &dummy);
-                    if (!res) {
-                        res = vvfat_read(s->bs, offset, s->cluster_buffer, 1);
-                        if (res) {
+                    if (!bdrv_is_allocated(s->qcow, offset + i, 1, &dummy)) {
+                        if (vvfat_read(s->bs, offset, s->cluster_buffer, 1)) {
                             return -1;
                         }
-                        res = bdrv_write(s->qcow, offset, s->cluster_buffer, 1);
-                        if (res) {
+                        if (bdrv_write(s->qcow, offset, s->cluster_buffer, 1)) {
                             return -2;
                         }
                     }
@@ -1969,7 +1941,8 @@ DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i))
                /* check file size with FAT */
                cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
                if (cluster_count !=
-            DIV_ROUND_UP(le32_to_cpu(direntries[i].size), s->cluster_size)) {
+                       (le32_to_cpu(direntries[i].size) + s->cluster_size
+                        - 1) / s->cluster_size) {
                    DLOG(fprintf(stderr, "Cluster count mismatch\n"));
                    goto fail;
                }
@@ -2791,8 +2764,8 @@ static int do_commit(BDRVVVFATState* s)
        return ret;
     }
 
-    if (s->qcow->bs->drv->bdrv_make_empty) {
-        s->qcow->bs->drv->bdrv_make_empty(s->qcow->bs);
+    if (s->qcow->drv->bdrv_make_empty) {
+        s->qcow->drv->bdrv_make_empty(s->qcow);
     }
 
     memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
@@ -2907,31 +2880,14 @@ DLOG(checkpoint());
     return 0;
 }
 
-static int coroutine_fn
-vvfat_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
-                 QEMUIOVector *qiov, int flags)
+static coroutine_fn int vvfat_co_write(BlockDriverState *bs, int64_t sector_num,
+                                       const uint8_t *buf, int nb_sectors)
 {
     int ret;
     BDRVVVFATState *s = bs->opaque;
-    uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
-    int nb_sectors = bytes >> BDRV_SECTOR_BITS;
-    void *buf;
-
-    assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
-    assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
-
-    buf = g_try_malloc(bytes);
-    if (bytes && buf == NULL) {
-        return -ENOMEM;
-    }
-    qemu_iovec_to_buf(qiov, 0, buf, bytes);
-
     qemu_co_mutex_lock(&s->lock);
     ret = vvfat_write(bs, sector_num, buf, nb_sectors);
     qemu_co_mutex_unlock(&s->lock);
-
-    g_free(buf);
-
     return ret;
 }
 
@@ -2948,39 +2904,26 @@ static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs,
     return BDRV_BLOCK_DATA;
 }
 
-static int coroutine_fn
-write_target_commit(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
-                    QEMUIOVector *qiov, int flags)
-{
+static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
+       const uint8_t* buffer, int nb_sectors) {
     BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
     return try_commit(s);
 }
 
 static void write_target_close(BlockDriverState *bs) {
     BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
-    bdrv_unref_child(s->bs, s->qcow);
+    bdrv_unref(s->qcow);
     g_free(s->qcow_filename);
 }
 
 static BlockDriver vvfat_write_target = {
     .format_name        = "vvfat_write_target",
-    .bdrv_co_pwritev    = write_target_commit,
+    .bdrv_write         = write_target_commit,
     .bdrv_close         = write_target_close,
 };
 
-static void vvfat_qcow_options(int *child_flags, QDict *child_options,
-                               int parent_flags, QDict *parent_options)
+static int enable_write_target(BDRVVVFATState *s, Error **errp)
 {
-    *child_flags = BDRV_O_RDWR | BDRV_O_NO_FLUSH;
-}
-
-static const BdrvChildRole child_vvfat_qcow = {
-    .inherit_options    = vvfat_qcow_options,
-};
-
-static int enable_write_target(BlockDriverState *bs, Error **errp)
-{
-    BDRVVVFATState *s = bs->opaque;
     BlockDriver *bdrv_qcow = NULL;
     BlockDriverState *backing;
     QemuOpts *opts = NULL;
@@ -3017,13 +2960,12 @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
         goto err;
     }
 
+    s->qcow = NULL;
     options = qdict_new();
-    qdict_put(options, "write-target.driver", qstring_from_str("qcow"));
-    s->qcow = bdrv_open_child(s->qcow_filename, options, "write-target", bs,
-                              &child_vvfat_qcow, false, errp);
-    QDECREF(options);
-    if (!s->qcow) {
-        ret = -EINVAL;
+    qdict_put(options, "driver", qstring_from_str("qcow"));
+    ret = bdrv_open(&s->qcow, s->qcow_filename, NULL, options,
+                    BDRV_O_RDWR | BDRV_O_NO_FLUSH, errp);
+    if (ret < 0) {
         goto err;
     }
 
@@ -3070,11 +3012,10 @@ static BlockDriver bdrv_vvfat = {
 
     .bdrv_parse_filename    = vvfat_parse_filename,
     .bdrv_file_open         = vvfat_open,
-    .bdrv_refresh_limits    = vvfat_refresh_limits,
     .bdrv_close             = vvfat_close,
 
-    .bdrv_co_preadv         = vvfat_co_preadv,
-    .bdrv_co_pwritev        = vvfat_co_pwritev,
+    .bdrv_read              = vvfat_co_read,
+    .bdrv_write             = vvfat_co_write,
     .bdrv_co_get_block_status = vvfat_co_get_block_status,
 };
 
index 95e3ab1..2d509a9 100644 (file)
@@ -27,7 +27,7 @@
 #include "block/block_int.h"
 #include "qemu/module.h"
 #include "block/aio.h"
-#include "block/raw-aio.h"
+#include "raw-aio.h"
 #include "qemu/event_notifier.h"
 #include "qemu/iov.h"
 #include <windows.h>
index 2161400..260a6f5 100644 (file)
@@ -56,8 +56,6 @@
 static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
     QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states);
 
-static int do_open_tray(const char *device, bool force, Error **errp);
-
 static const char *const if_name[IF_COUNT] = {
     [IF_NONE] = "none",
     [IF_IDE] = "ide",
@@ -75,7 +73,7 @@ static int if_max_devs[IF_COUNT] = {
      * Do not change these numbers!  They govern how drive option
      * index maps to unit and bus.  That mapping is ABI.
      *
-     * All controllers used to implement if=T drives need to support
+     * All controllers used to imlement if=T drives need to support
      * if_max_devs[T] units, for any T with if_max_devs[T] != 0.
      * Otherwise, some index values map to "impossible" bus, unit
      * values.
@@ -483,6 +481,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
     const char *id;
     BlockdevDetectZeroesOptions detect_zeroes =
         BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
+    const char *blk_id;
     const char *throttling_group = NULL;
 
     /* Check common options by copying from bs_opts to opts, all other options
@@ -512,7 +511,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
 
     writethrough = !qemu_opt_get_bool(opts, BDRV_OPT_CACHE_WB, true);
 
-    id = qemu_opts_id(opts);
+    blk_id = qemu_opts_id(opts);
 
     qdict_extract_subqdict(bs_opts, &interval_dict, "stats-intervals.");
     qdict_array_split(interval_dict, &interval_list);
@@ -571,12 +570,25 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
     if ((!file || !*file) && !qdict_size(bs_opts)) {
         BlockBackendRootState *blk_rs;
 
-        blk = blk_new();
+        blk = blk_new(errp);
+        if (!blk) {
+            goto early_err;
+        }
+
         blk_rs = blk_get_root_state(blk);
         blk_rs->open_flags    = bdrv_flags;
         blk_rs->read_only     = !(bdrv_flags & BDRV_O_RDWR);
         blk_rs->detect_zeroes = detect_zeroes;
 
+        if (throttle_enabled(&cfg)) {
+            if (!throttling_group) {
+                throttling_group = blk_id;
+            }
+            blk_rs->throttle_group = g_strdup(throttling_group);
+            blk_rs->throttle_state = throttle_group_incref(throttling_group);
+            blk_rs->throttle_state->cfg = cfg;
+        }
+
         QDECREF(bs_opts);
     } else {
         if (file && !*file) {
@@ -602,6 +614,15 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
 
         bs->detect_zeroes = detect_zeroes;
 
+        /* disk I/O throttling */
+        if (throttle_enabled(&cfg)) {
+            if (!throttling_group) {
+                throttling_group = blk_id;
+            }
+            bdrv_io_limits_enable(bs, throttling_group);
+            bdrv_set_io_limits(bs, &cfg);
+        }
+
         if (bdrv_key_required(bs)) {
             autostart = 0;
         }
@@ -615,19 +636,10 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
         }
     }
 
-    /* disk I/O throttling */
-    if (throttle_enabled(&cfg)) {
-        if (!throttling_group) {
-            throttling_group = id;
-        }
-        blk_io_limits_enable(blk, throttling_group);
-        blk_set_io_limits(blk, &cfg);
-    }
-
     blk_set_enable_write_cache(blk, !writethrough);
     blk_set_on_error(blk, on_read_error, on_write_error);
 
-    if (!monitor_add_blk(blk, id, errp)) {
+    if (!monitor_add_blk(blk, blk_id, errp)) {
         blk_unref(blk);
         blk = NULL;
         goto err_no_bs_opts;
@@ -657,6 +669,7 @@ static BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
     QemuOpts *opts;
     Error *local_error = NULL;
     BlockdevDetectZeroesOptions detect_zeroes;
+    int ret;
     int bdrv_flags = 0;
 
     opts = qemu_opts_create(&qemu_root_bds_opts, NULL, 1, errp);
@@ -687,8 +700,9 @@ static BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
         bdrv_flags |= BDRV_O_INACTIVE;
     }
 
-    bs = bdrv_open(NULL, NULL, bs_opts, bdrv_flags, errp);
-    if (!bs) {
+    bs = NULL;
+    ret = bdrv_open(&bs, NULL, NULL, bs_opts, bdrv_flags, errp);
+    if (ret < 0) {
         goto fail_no_bs_opts;
     }
 
@@ -1641,7 +1655,7 @@ typedef struct ExternalSnapshotState {
 static void external_snapshot_prepare(BlkActionState *common,
                                       Error **errp)
 {
-    int flags = 0;
+    int flags = 0, ret;
     QDict *options = NULL;
     Error *local_err = NULL;
     /* Device and node name of the image to generate the snapshot from */
@@ -1766,16 +1780,17 @@ static void external_snapshot_prepare(BlkActionState *common,
         flags |= BDRV_O_NO_BACKING;
     }
 
-    state->new_bs = bdrv_open(new_image_file, snapshot_ref, options, flags,
-                              errp);
+    assert(state->new_bs == NULL);
+    ret = bdrv_open(&state->new_bs, new_image_file, snapshot_ref, options,
+                    flags, errp);
     /* We will manually add the backing_hd field to the bs later */
-    if (!state->new_bs) {
+    if (ret != 0) {
         return;
     }
 
-    if (bdrv_has_blk(state->new_bs)) {
+    if (state->new_bs->blk != NULL) {
         error_setg(errp, "The snapshot is already in use by %s",
-                   bdrv_get_parent_name(state->new_bs));
+                   blk_name(state->new_bs->blk));
         return;
     }
 
@@ -1838,9 +1853,9 @@ typedef struct DriveBackupState {
     BlockJob *job;
 } DriveBackupState;
 
-static void do_drive_backup(const char *job_id, const char *device,
-                            const char *target, bool has_format,
-                            const char *format, enum MirrorSyncMode sync,
+static void do_drive_backup(const char *device, const char *target,
+                            bool has_format, const char *format,
+                            enum MirrorSyncMode sync,
                             bool has_mode, enum NewImageMode mode,
                             bool has_speed, int64_t speed,
                             bool has_bitmap, const char *bitmap,
@@ -1878,8 +1893,7 @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)
     bdrv_drained_begin(blk_bs(blk));
     state->bs = blk_bs(blk);
 
-    do_drive_backup(backup->has_job_id ? backup->job_id : NULL,
-                    backup->device, backup->target,
+    do_drive_backup(backup->device, backup->target,
                     backup->has_format, backup->format,
                     backup->sync,
                     backup->has_mode, backup->mode,
@@ -1924,8 +1938,8 @@ typedef struct BlockdevBackupState {
     AioContext *aio_context;
 } BlockdevBackupState;
 
-static void do_blockdev_backup(const char *job_id, const char *device,
-                               const char *target, enum MirrorSyncMode sync,
+static void do_blockdev_backup(const char *device, const char *target,
+                               enum MirrorSyncMode sync,
                                bool has_speed, int64_t speed,
                                bool has_on_source_error,
                                BlockdevOnError on_source_error,
@@ -1937,8 +1951,7 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
 {
     BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
     BlockdevBackup *backup;
-    BlockBackend *blk;
-    BlockDriverState *target;
+    BlockBackend *blk, *target;
     Error *local_err = NULL;
 
     assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
@@ -1955,14 +1968,15 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
         return;
     }
 
-    target = bdrv_lookup_bs(backup->target, backup->target, errp);
+    target = blk_by_name(backup->target);
     if (!target) {
+        error_setg(errp, "Device '%s' not found", backup->target);
         return;
     }
 
     /* AioContext is released in .clean() */
     state->aio_context = blk_get_aio_context(blk);
-    if (state->aio_context != bdrv_get_aio_context(target)) {
+    if (state->aio_context != blk_get_aio_context(target)) {
         state->aio_context = NULL;
         error_setg(errp, "Backup between two IO threads is not implemented");
         return;
@@ -1971,8 +1985,8 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
     state->bs = blk_bs(blk);
     bdrv_drained_begin(state->bs);
 
-    do_blockdev_backup(backup->has_job_id ? backup->job_id : NULL,
-                       backup->device, backup->target, backup->sync,
+    do_blockdev_backup(backup->device, backup->target,
+                       backup->sync,
                        backup->has_speed, backup->speed,
                        backup->has_on_source_error, backup->on_source_error,
                        backup->has_on_target_error, backup->on_target_error,
@@ -2282,18 +2296,12 @@ exit:
 void qmp_eject(const char *device, bool has_force, bool force, Error **errp)
 {
     Error *local_err = NULL;
-    int rc;
-
-    if (!has_force) {
-        force = false;
-    }
 
-    rc = do_open_tray(device, force, &local_err);
-    if (rc && rc != -ENOSYS) {
+    qmp_blockdev_open_tray(device, has_force, force, &local_err);
+    if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
-    error_free(local_err);
 
     qmp_x_blockdev_remove_medium(device, errp);
 }
@@ -2322,41 +2330,35 @@ void qmp_block_passwd(bool has_device, const char *device,
     aio_context_release(aio_context);
 }
 
-/*
- * Attempt to open the tray of @device.
- * If @force, ignore its tray lock.
- * Else, if the tray is locked, don't open it, but ask the guest to open it.
- * On error, store an error through @errp and return -errno.
- * If @device does not exist, return -ENODEV.
- * If it has no removable media, return -ENOTSUP.
- * If it has no tray, return -ENOSYS.
- * If the guest was asked to open the tray, return -EINPROGRESS.
- * Else, return 0.
- */
-static int do_open_tray(const char *device, bool force, Error **errp)
+void qmp_blockdev_open_tray(const char *device, bool has_force, bool force,
+                            Error **errp)
 {
     BlockBackend *blk;
     bool locked;
 
+    if (!has_force) {
+        force = false;
+    }
+
     blk = blk_by_name(device);
     if (!blk) {
         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
                   "Device '%s' not found", device);
-        return -ENODEV;
+        return;
     }
 
     if (!blk_dev_has_removable_media(blk)) {
         error_setg(errp, "Device '%s' is not removable", device);
-        return -ENOTSUP;
+        return;
     }
 
     if (!blk_dev_has_tray(blk)) {
-        error_setg(errp, "Device '%s' does not have a tray", device);
-        return -ENOSYS;
+        /* Ignore this command on tray-less devices */
+        return;
     }
 
     if (blk_dev_is_tray_open(blk)) {
-        return 0;
+        return;
     }
 
     locked = blk_dev_is_medium_locked(blk);
@@ -2367,31 +2369,6 @@ static int do_open_tray(const char *device, bool force, Error **errp)
     if (!locked || force) {
         blk_dev_change_media_cb(blk, false);
     }
-
-    if (locked && !force) {
-        error_setg(errp, "Device '%s' is locked and force was not specified, "
-                   "wait for tray to open and try again", device);
-        return -EINPROGRESS;
-    }
-
-    return 0;
-}
-
-void qmp_blockdev_open_tray(const char *device, bool has_force, bool force,
-                            Error **errp)
-{
-    Error *local_err = NULL;
-    int rc;
-
-    if (!has_force) {
-        force = false;
-    }
-    rc = do_open_tray(device, force, &local_err);
-    if (rc && rc != -ENOSYS && rc != -EINPROGRESS) {
-        error_propagate(errp, local_err);
-        return;
-    }
-    error_free(local_err);
 }
 
 void qmp_blockdev_close_tray(const char *device, Error **errp)
@@ -2529,9 +2506,9 @@ void qmp_x_blockdev_insert_medium(const char *device, const char *node_name,
         return;
     }
 
-    if (bdrv_has_blk(bs)) {
+    if (bs->blk) {
         error_setg(errp, "Node '%s' is already in use by '%s'", node_name,
-                   bdrv_get_parent_name(bs));
+                   blk_name(bs->blk));
         return;
     }
 
@@ -2546,8 +2523,7 @@ void qmp_blockdev_change_medium(const char *device, const char *filename,
 {
     BlockBackend *blk;
     BlockDriverState *medium_bs = NULL;
-    int bdrv_flags;
-    int rc;
+    int bdrv_flags, ret;
     QDict *options = NULL;
     Error *err = NULL;
 
@@ -2591,24 +2567,25 @@ void qmp_blockdev_change_medium(const char *device, const char *filename,
         qdict_put(options, "driver", qstring_from_str(format));
     }
 
-    medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
-    if (!medium_bs) {
+    assert(!medium_bs);
+    ret = bdrv_open(&medium_bs, filename, NULL, options, bdrv_flags, errp);
+    if (ret < 0) {
         goto fail;
     }
 
+    blk_apply_root_state(blk, medium_bs);
+
     bdrv_add_key(medium_bs, NULL, &err);
     if (err) {
         error_propagate(errp, err);
         goto fail;
     }
 
-    rc = do_open_tray(device, false, &err);
-    if (rc && rc != -ENOSYS) {
+    qmp_blockdev_open_tray(device, false, false, &err);
+    if (err) {
         error_propagate(errp, err);
         goto fail;
     }
-    error_free(err);
-    err = NULL;
 
     qmp_x_blockdev_remove_medium(device, &err);
     if (err) {
@@ -2622,8 +2599,6 @@ void qmp_blockdev_change_medium(const char *device, const char *filename,
         goto fail;
     }
 
-    blk_apply_root_state(blk, medium_bs);
-
     qmp_blockdev_close_tray(device, errp);
 
 fail:
@@ -2634,17 +2609,49 @@ fail:
 }
 
 /* throttling disk I/O limits */
-void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
+void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
+                               int64_t bps_wr,
+                               int64_t iops,
+                               int64_t iops_rd,
+                               int64_t iops_wr,
+                               bool has_bps_max,
+                               int64_t bps_max,
+                               bool has_bps_rd_max,
+                               int64_t bps_rd_max,
+                               bool has_bps_wr_max,
+                               int64_t bps_wr_max,
+                               bool has_iops_max,
+                               int64_t iops_max,
+                               bool has_iops_rd_max,
+                               int64_t iops_rd_max,
+                               bool has_iops_wr_max,
+                               int64_t iops_wr_max,
+                               bool has_bps_max_length,
+                               int64_t bps_max_length,
+                               bool has_bps_rd_max_length,
+                               int64_t bps_rd_max_length,
+                               bool has_bps_wr_max_length,
+                               int64_t bps_wr_max_length,
+                               bool has_iops_max_length,
+                               int64_t iops_max_length,
+                               bool has_iops_rd_max_length,
+                               int64_t iops_rd_max_length,
+                               bool has_iops_wr_max_length,
+                               int64_t iops_wr_max_length,
+                               bool has_iops_size,
+                               int64_t iops_size,
+                               bool has_group,
+                               const char *group, Error **errp)
 {
     ThrottleConfig cfg;
     BlockDriverState *bs;
     BlockBackend *blk;
     AioContext *aio_context;
 
-    blk = blk_by_name(arg->device);
+    blk = blk_by_name(device);
     if (!blk) {
         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
-                  "Device '%s' not found", arg->device);
+                  "Device '%s' not found", device);
         return;
     }
 
@@ -2653,59 +2660,66 @@ void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
 
     bs = blk_bs(blk);
     if (!bs) {
-        error_setg(errp, "Device '%s' has no medium", arg->device);
+        error_setg(errp, "Device '%s' has no medium", device);
+        goto out;
+    }
+
+    /* The BlockBackend must be the only parent */
+    assert(QLIST_FIRST(&bs->parents));
+    if (QLIST_NEXT(QLIST_FIRST(&bs->parents), next_parent)) {
+        error_setg(errp, "Cannot throttle device with multiple parents");
         goto out;
     }
 
     throttle_config_init(&cfg);
-    cfg.buckets[THROTTLE_BPS_TOTAL].avg = arg->bps;
-    cfg.buckets[THROTTLE_BPS_READ].avg  = arg->bps_rd;
-    cfg.buckets[THROTTLE_BPS_WRITE].avg = arg->bps_wr;
+    cfg.buckets[THROTTLE_BPS_TOTAL].avg = bps;
+    cfg.buckets[THROTTLE_BPS_READ].avg  = bps_rd;
+    cfg.buckets[THROTTLE_BPS_WRITE].avg = bps_wr;
 
-    cfg.buckets[THROTTLE_OPS_TOTAL].avg = arg->iops;
-    cfg.buckets[THROTTLE_OPS_READ].avg  = arg->iops_rd;
-    cfg.buckets[THROTTLE_OPS_WRITE].avg = arg->iops_wr;
+    cfg.buckets[THROTTLE_OPS_TOTAL].avg = iops;
+    cfg.buckets[THROTTLE_OPS_READ].avg  = iops_rd;
+    cfg.buckets[THROTTLE_OPS_WRITE].avg = iops_wr;
 
-    if (arg->has_bps_max) {
-        cfg.buckets[THROTTLE_BPS_TOTAL].max = arg->bps_max;
+    if (has_bps_max) {
+        cfg.buckets[THROTTLE_BPS_TOTAL].max = bps_max;
     }
-    if (arg->has_bps_rd_max) {
-        cfg.buckets[THROTTLE_BPS_READ].max = arg->bps_rd_max;
+    if (has_bps_rd_max) {
+        cfg.buckets[THROTTLE_BPS_READ].max = bps_rd_max;
     }
-    if (arg->has_bps_wr_max) {
-        cfg.buckets[THROTTLE_BPS_WRITE].max = arg->bps_wr_max;
+    if (has_bps_wr_max) {
+        cfg.buckets[THROTTLE_BPS_WRITE].max = bps_wr_max;
     }
-    if (arg->has_iops_max) {
-        cfg.buckets[THROTTLE_OPS_TOTAL].max = arg->iops_max;
+    if (has_iops_max) {
+        cfg.buckets[THROTTLE_OPS_TOTAL].max = iops_max;
     }
-    if (arg->has_iops_rd_max) {
-        cfg.buckets[THROTTLE_OPS_READ].max = arg->iops_rd_max;
+    if (has_iops_rd_max) {
+        cfg.buckets[THROTTLE_OPS_READ].max = iops_rd_max;
     }
-    if (arg->has_iops_wr_max) {
-        cfg.buckets[THROTTLE_OPS_WRITE].max = arg->iops_wr_max;
+    if (has_iops_wr_max) {
+        cfg.buckets[THROTTLE_OPS_WRITE].max = iops_wr_max;
     }
 
-    if (arg->has_bps_max_length) {
-        cfg.buckets[THROTTLE_BPS_TOTAL].burst_length = arg->bps_max_length;
+    if (has_bps_max_length) {
+        cfg.buckets[THROTTLE_BPS_TOTAL].burst_length = bps_max_length;
     }
-    if (arg->has_bps_rd_max_length) {
-        cfg.buckets[THROTTLE_BPS_READ].burst_length = arg->bps_rd_max_length;
+    if (has_bps_rd_max_length) {
+        cfg.buckets[THROTTLE_BPS_READ].burst_length = bps_rd_max_length;
     }
-    if (arg->has_bps_wr_max_length) {
-        cfg.buckets[THROTTLE_BPS_WRITE].burst_length = arg->bps_wr_max_length;
+    if (has_bps_wr_max_length) {
+        cfg.buckets[THROTTLE_BPS_WRITE].burst_length = bps_wr_max_length;
     }
-    if (arg->has_iops_max_length) {
-        cfg.buckets[THROTTLE_OPS_TOTAL].burst_length = arg->iops_max_length;
+    if (has_iops_max_length) {
+        cfg.buckets[THROTTLE_OPS_TOTAL].burst_length = iops_max_length;
     }
-    if (arg->has_iops_rd_max_length) {
-        cfg.buckets[THROTTLE_OPS_READ].burst_length = arg->iops_rd_max_length;
+    if (has_iops_rd_max_length) {
+        cfg.buckets[THROTTLE_OPS_READ].burst_length = iops_rd_max_length;
     }
-    if (arg->has_iops_wr_max_length) {
-        cfg.buckets[THROTTLE_OPS_WRITE].burst_length = arg->iops_wr_max_length;
+    if (has_iops_wr_max_length) {
+        cfg.buckets[THROTTLE_OPS_WRITE].burst_length = iops_wr_max_length;
     }
 
-    if (arg->has_iops_size) {
-        cfg.op_size = arg->iops_size;
+    if (has_iops_size) {
+        cfg.op_size = iops_size;
     }
 
     if (!throttle_is_valid(&cfg, errp)) {
@@ -2715,17 +2729,16 @@ void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
     if (throttle_enabled(&cfg)) {
         /* Enable I/O limits if they're not enabled yet, otherwise
          * just update the throttling group. */
-        if (!blk_get_public(blk)->throttle_state) {
-            blk_io_limits_enable(blk,
-                                 arg->has_group ? arg->group : arg->device);
-        } else if (arg->has_group) {
-            blk_io_limits_update_group(blk, arg->group);
+        if (!bs->throttle_state) {
+            bdrv_io_limits_enable(bs, has_group ? group : device);
+        } else if (has_group) {
+            bdrv_io_limits_update_group(bs, group);
         }
         /* Set the new throttling configuration */
-        blk_set_io_limits(blk, &cfg);
-    } else if (blk_get_public(blk)->throttle_state) {
+        bdrv_set_io_limits(bs, &cfg);
+    } else if (bs->throttle_state) {
         /* If all throttling settings are set to 0, disable I/O limits */
-        blk_io_limits_disable(blk);
+        bdrv_io_limits_disable(bs);
     }
 
 out:
@@ -2976,7 +2989,7 @@ static void block_job_cb(void *opaque, int ret)
     }
 }
 
-void qmp_block_stream(bool has_job_id, const char *job_id, const char *device,
+void qmp_block_stream(const char *device,
                       bool has_base, const char *base,
                       bool has_backing_file, const char *backing_file,
                       bool has_speed, int64_t speed,
@@ -3035,8 +3048,8 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device,
     /* backing_file string overrides base bs filename */
     base_name = has_backing_file ? backing_file : base_name;
 
-    stream_start(has_job_id ? job_id : NULL, bs, base_bs, base_name,
-                 has_speed ? speed : 0, on_error, block_job_cb, bs, &local_err);
+    stream_start(bs, base_bs, base_name, has_speed ? speed : 0,
+                 on_error, block_job_cb, bs, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         goto out;
@@ -3048,7 +3061,7 @@ out:
     aio_context_release(aio_context);
 }
 
-void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
+void qmp_block_commit(const char *device,
                       bool has_base, const char *base,
                       bool has_top, const char *top,
                       bool has_backing_file, const char *backing_file,
@@ -3139,11 +3152,10 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
                              " but 'top' is the active layer");
             goto out;
         }
-        commit_active_start(has_job_id ? job_id : NULL, bs, base_bs, speed,
-                            on_error, block_job_cb, bs, &local_err);
+        commit_active_start(bs, base_bs, speed, on_error, block_job_cb,
+                            bs, &local_err);
     } else {
-        commit_start(has_job_id ? job_id : NULL, bs, base_bs, top_bs, speed,
-                     on_error, block_job_cb, bs,
+        commit_start(bs, base_bs, top_bs, speed, on_error, block_job_cb, bs,
                      has_backing_file ? backing_file : NULL, &local_err);
     }
     if (local_err != NULL) {
@@ -3155,9 +3167,9 @@ out:
     aio_context_release(aio_context);
 }
 
-static void do_drive_backup(const char *job_id, const char *device,
-                            const char *target, bool has_format,
-                            const char *format, enum MirrorSyncMode sync,
+static void do_drive_backup(const char *device, const char *target,
+                            bool has_format, const char *format,
+                            enum MirrorSyncMode sync,
                             bool has_mode, enum NewImageMode mode,
                             bool has_speed, int64_t speed,
                             bool has_bitmap, const char *bitmap,
@@ -3177,6 +3189,7 @@ static void do_drive_backup(const char *job_id, const char *device,
     Error *local_err = NULL;
     int flags;
     int64_t size;
+    int ret;
 
     if (!has_speed) {
         speed = 0;
@@ -3260,8 +3273,10 @@ static void do_drive_backup(const char *job_id, const char *device,
         qdict_put(options, "driver", qstring_from_str(format));
     }
 
-    target_bs = bdrv_open(target, NULL, options, flags, errp);
-    if (!target_bs) {
+    target_bs = NULL;
+    ret = bdrv_open(&target_bs, target, NULL, options, flags, &local_err);
+    if (ret < 0) {
+        error_propagate(errp, local_err);
         goto out;
     }
 
@@ -3276,11 +3291,11 @@ static void do_drive_backup(const char *job_id, const char *device,
         }
     }
 
-    backup_start(job_id, bs, target_bs, speed, sync, bmap,
+    backup_start(bs, target_bs, speed, sync, bmap,
                  on_source_error, on_target_error,
                  block_job_cb, bs, txn, &local_err);
-    bdrv_unref(target_bs);
     if (local_err != NULL) {
+        bdrv_unref(target_bs);
         error_propagate(errp, local_err);
         goto out;
     }
@@ -3289,8 +3304,7 @@ out:
     aio_context_release(aio_context);
 }
 
-void qmp_drive_backup(bool has_job_id, const char *job_id,
-                      const char *device, const char *target,
+void qmp_drive_backup(const char *device, const char *target,
                       bool has_format, const char *format,
                       enum MirrorSyncMode sync,
                       bool has_mode, enum NewImageMode mode,
@@ -3300,8 +3314,7 @@ void qmp_drive_backup(bool has_job_id, const char *job_id,
                       bool has_on_target_error, BlockdevOnError on_target_error,
                       Error **errp)
 {
-    return do_drive_backup(has_job_id ? job_id : NULL, device, target,
-                           has_format, format, sync,
+    return do_drive_backup(device, target, has_format, format, sync,
                            has_mode, mode, has_speed, speed,
                            has_bitmap, bitmap,
                            has_on_source_error, on_source_error,
@@ -3314,8 +3327,8 @@ BlockDeviceInfoList *qmp_query_named_block_nodes(Error **errp)
     return bdrv_named_nodes_list(errp);
 }
 
-void do_blockdev_backup(const char *job_id, const char *device,
-                        const char *target, enum MirrorSyncMode sync,
+void do_blockdev_backup(const char *device, const char *target,
+                         enum MirrorSyncMode sync,
                          bool has_speed, int64_t speed,
                          bool has_on_source_error,
                          BlockdevOnError on_source_error,
@@ -3323,7 +3336,7 @@ void do_blockdev_backup(const char *job_id, const char *device,
                          BlockdevOnError on_target_error,
                          BlockJobTxn *txn, Error **errp)
 {
-    BlockBackend *blk;
+    BlockBackend *blk, *target_blk;
     BlockDriverState *bs;
     BlockDriverState *target_bs;
     Error *local_err = NULL;
@@ -3354,33 +3367,31 @@ void do_blockdev_backup(const char *job_id, const char *device,
     }
     bs = blk_bs(blk);
 
-    target_bs = bdrv_lookup_bs(target, target, errp);
-    if (!target_bs) {
+    target_blk = blk_by_name(target);
+    if (!target_blk) {
+        error_setg(errp, "Device '%s' not found", target);
         goto out;
     }
 
-    if (bdrv_get_aio_context(target_bs) != aio_context) {
-        if (!bdrv_has_blk(target_bs)) {
-            /* The target BDS is not attached, we can safely move it to another
-             * AioContext. */
-            bdrv_set_aio_context(target_bs, aio_context);
-        } else {
-            error_setg(errp, "Target is attached to a different thread from "
-                             "source.");
-            goto out;
-        }
+    if (!blk_is_available(target_blk)) {
+        error_setg(errp, "Device '%s' has no medium", target);
+        goto out;
     }
-    backup_start(job_id, bs, target_bs, speed, sync, NULL, on_source_error,
+    target_bs = blk_bs(target_blk);
+
+    bdrv_ref(target_bs);
+    bdrv_set_aio_context(target_bs, aio_context);
+    backup_start(bs, target_bs, speed, sync, NULL, on_source_error,
                  on_target_error, block_job_cb, bs, txn, &local_err);
     if (local_err != NULL) {
+        bdrv_unref(target_bs);
         error_propagate(errp, local_err);
     }
 out:
     aio_context_release(aio_context);
 }
 
-void qmp_blockdev_backup(bool has_job_id, const char *job_id,
-                         const char *device, const char *target,
+void qmp_blockdev_backup(const char *device, const char *target,
                          enum MirrorSyncMode sync,
                          bool has_speed, int64_t speed,
                          bool has_on_source_error,
@@ -3389,8 +3400,7 @@ void qmp_blockdev_backup(bool has_job_id, const char *job_id,
                          BlockdevOnError on_target_error,
                          Error **errp)
 {
-    do_blockdev_backup(has_job_id ? job_id : NULL, device, target,
-                       sync, has_speed, speed,
+    do_blockdev_backup(device, target, sync, has_speed, speed,
                        has_on_source_error, on_source_error,
                        has_on_target_error, on_target_error,
                        NULL, errp);
@@ -3399,11 +3409,10 @@ void qmp_blockdev_backup(bool has_job_id, const char *job_id,
 /* Parameter check and block job starting for drive mirroring.
  * Caller should hold @device and @target's aio context (must be the same).
  **/
-static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+static void blockdev_mirror_common(BlockDriverState *bs,
                                    BlockDriverState *target,
                                    bool has_replaces, const char *replaces,
                                    enum MirrorSyncMode sync,
-                                   BlockMirrorBackingMode backing_mode,
                                    bool has_speed, int64_t speed,
                                    bool has_granularity, uint32_t granularity,
                                    bool has_buf_size, int64_t buf_size,
@@ -3451,6 +3460,10 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
     if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_MIRROR_TARGET, errp)) {
         return;
     }
+    if (target->blk) {
+        error_setg(errp, "Cannot mirror to an attached block device");
+        return;
+    }
 
     if (!bs->backing && sync == MIRROR_SYNC_MODE_TOP) {
         sync = MIRROR_SYNC_MODE_FULL;
@@ -3459,30 +3472,41 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
     /* pass the node name to replace to mirror start since it's loose coupling
      * and will allow to check whether the node still exist at mirror completion
      */
-    mirror_start(job_id, bs, target,
+    mirror_start(bs, target,
                  has_replaces ? replaces : NULL,
-                 speed, granularity, buf_size, sync, backing_mode,
+                 speed, granularity, buf_size, sync,
                  on_source_error, on_target_error, unmap,
                  block_job_cb, bs, errp);
 }
 
-void qmp_drive_mirror(DriveMirror *arg, Error **errp)
+void qmp_drive_mirror(const char *device, const char *target,
+                      bool has_format, const char *format,
+                      bool has_node_name, const char *node_name,
+                      bool has_replaces, const char *replaces,
+                      enum MirrorSyncMode sync,
+                      bool has_mode, enum NewImageMode mode,
+                      bool has_speed, int64_t speed,
+                      bool has_granularity, uint32_t granularity,
+                      bool has_buf_size, int64_t buf_size,
+                      bool has_on_source_error, BlockdevOnError on_source_error,
+                      bool has_on_target_error, BlockdevOnError on_target_error,
+                      bool has_unmap, bool unmap,
+                      Error **errp)
 {
     BlockDriverState *bs;
     BlockBackend *blk;
     BlockDriverState *source, *target_bs;
     AioContext *aio_context;
-    BlockMirrorBackingMode backing_mode;
     Error *local_err = NULL;
     QDict *options = NULL;
     int flags;
     int64_t size;
-    const char *format = arg->format;
+    int ret;
 
-    blk = blk_by_name(arg->device);
+    blk = blk_by_name(device);
     if (!blk) {
         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
-                  "Device '%s' not found", arg->device);
+                  "Device '%s' not found", device);
         return;
     }
 
@@ -3490,25 +3514,24 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
     aio_context_acquire(aio_context);
 
     if (!blk_is_available(blk)) {
-        error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, arg->device);
+        error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
         goto out;
     }
     bs = blk_bs(blk);
-    if (!arg->has_mode) {
-        arg->mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+    if (!has_mode) {
+        mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
     }
 
-    if (!arg->has_format) {
-        format = (arg->mode == NEW_IMAGE_MODE_EXISTING
-                  ? NULL : bs->drv->format_name);
+    if (!has_format) {
+        format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;
     }
 
     flags = bs->open_flags | BDRV_O_RDWR;
     source = backing_bs(bs);
-    if (!source && arg->sync == MIRROR_SYNC_MODE_TOP) {
-        arg->sync = MIRROR_SYNC_MODE_FULL;
+    if (!source && sync == MIRROR_SYNC_MODE_TOP) {
+        sync = MIRROR_SYNC_MODE_FULL;
     }
-    if (arg->sync == MIRROR_SYNC_MODE_NONE) {
+    if (sync == MIRROR_SYNC_MODE_NONE) {
         source = bs;
     }
 
@@ -3518,18 +3541,18 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
         goto out;
     }
 
-    if (arg->has_replaces) {
+    if (has_replaces) {
         BlockDriverState *to_replace_bs;
         AioContext *replace_aio_context;
         int64_t replace_size;
 
-        if (!arg->has_node_name) {
+        if (!has_node_name) {
             error_setg(errp, "a node-name must be provided when replacing a"
                              " named node of the graph");
             goto out;
         }
 
-        to_replace_bs = check_to_replace_node(bs, arg->replaces, &local_err);
+        to_replace_bs = check_to_replace_node(bs, replaces, &local_err);
 
         if (!to_replace_bs) {
             error_propagate(errp, local_err);
@@ -3548,26 +3571,20 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
         }
     }
 
-    if (arg->mode == NEW_IMAGE_MODE_ABSOLUTE_PATHS) {
-        backing_mode = MIRROR_SOURCE_BACKING_CHAIN;
-    } else {
-        backing_mode = MIRROR_OPEN_BACKING_CHAIN;
-    }
-
-    if ((arg->sync == MIRROR_SYNC_MODE_FULL || !source)
-        && arg->mode != NEW_IMAGE_MODE_EXISTING)
+    if ((sync == MIRROR_SYNC_MODE_FULL || !source)
+        && mode != NEW_IMAGE_MODE_EXISTING)
     {
         /* create new image w/o backing file */
         assert(format);
-        bdrv_img_create(arg->target, format,
+        bdrv_img_create(target, format,
                         NULL, NULL, NULL, size, flags, &local_err, false);
     } else {
-        switch (arg->mode) {
+        switch (mode) {
         case NEW_IMAGE_MODE_EXISTING:
             break;
         case NEW_IMAGE_MODE_ABSOLUTE_PATHS:
             /* create new image with backing file */
-            bdrv_img_create(arg->target, format,
+            bdrv_img_create(target, format,
                             source->filename,
                             source->drv->format_name,
                             NULL, size, flags, &local_err, false);
@@ -3583,8 +3600,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
     }
 
     options = qdict_new();
-    if (arg->has_node_name) {
-        qdict_put(options, "node-name", qstring_from_str(arg->node_name));
+    if (has_node_name) {
+        qdict_put(options, "node-name", qstring_from_str(node_name));
     }
     if (format) {
         qdict_put(options, "driver", qstring_from_str(format));
@@ -3593,31 +3610,34 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
     /* Mirroring takes care of copy-on-write using the source's backing
      * file.
      */
-    target_bs = bdrv_open(arg->target, NULL, options,
-                          flags | BDRV_O_NO_BACKING, errp);
-    if (!target_bs) {
+    target_bs = NULL;
+    ret = bdrv_open(&target_bs, target, NULL, options,
+                    flags | BDRV_O_NO_BACKING, &local_err);
+    if (ret < 0) {
+        error_propagate(errp, local_err);
         goto out;
     }
 
     bdrv_set_aio_context(target_bs, aio_context);
 
-    blockdev_mirror_common(arg->has_job_id ? arg->job_id : NULL, bs, target_bs,
-                           arg->has_replaces, arg->replaces, arg->sync,
-                           backing_mode, arg->has_speed, arg->speed,
-                           arg->has_granularity, arg->granularity,
-                           arg->has_buf_size, arg->buf_size,
-                           arg->has_on_source_error, arg->on_source_error,
-                           arg->has_on_target_error, arg->on_target_error,
-                           arg->has_unmap, arg->unmap,
+    blockdev_mirror_common(bs, target_bs,
+                           has_replaces, replaces, sync,
+                           has_speed, speed,
+                           has_granularity, granularity,
+                           has_buf_size, buf_size,
+                           has_on_source_error, on_source_error,
+                           has_on_target_error, on_target_error,
+                           has_unmap, unmap,
                            &local_err);
-    bdrv_unref(target_bs);
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        bdrv_unref(target_bs);
+    }
 out:
     aio_context_release(aio_context);
 }
 
-void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
-                         const char *device, const char *target,
+void qmp_blockdev_mirror(const char *device, const char *target,
                          bool has_replaces, const char *replaces,
                          MirrorSyncMode sync,
                          bool has_speed, int64_t speed,
@@ -3633,7 +3653,6 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
     BlockBackend *blk;
     BlockDriverState *target_bs;
     AioContext *aio_context;
-    BlockMirrorBackingMode backing_mode = MIRROR_LEAVE_BACKING_CHAIN;
     Error *local_err = NULL;
 
     blk = blk_by_name(device);
@@ -3656,10 +3675,11 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
 
+    bdrv_ref(target_bs);
     bdrv_set_aio_context(target_bs, aio_context);
 
-    blockdev_mirror_common(has_job_id ? job_id : NULL, bs, target_bs,
-                           has_replaces, replaces, sync, backing_mode,
+    blockdev_mirror_common(bs, target_bs,
+                           has_replaces, replaces, sync,
                            has_speed, speed,
                            has_granularity, granularity,
                            has_buf_size, buf_size,
@@ -3667,33 +3687,50 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
                            has_on_target_error, on_target_error,
                            true, true,
                            &local_err);
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        bdrv_unref(target_bs);
+    }
 
     aio_context_release(aio_context);
 }
 
-/* Get a block job using its ID and acquire its AioContext */
-static BlockJob *find_block_job(const char *id, AioContext **aio_context,
+/* Get the block job for a given device name and acquire its AioContext */
+static BlockJob *find_block_job(const char *device, AioContext **aio_context,
                                 Error **errp)
 {
-    BlockJob *job;
-
-    assert(id != NULL);
+    BlockBackend *blk;
+    BlockDriverState *bs;
 
     *aio_context = NULL;
 
-    job = block_job_get(id);
-
-    if (!job) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE,
-                  "Block job '%s' not found", id);
-        return NULL;
+    blk = blk_by_name(device);
+    if (!blk) {
+        goto notfound;
     }
 
-    *aio_context = blk_get_aio_context(job->blk);
+    *aio_context = blk_get_aio_context(blk);
     aio_context_acquire(*aio_context);
 
-    return job;
+    if (!blk_is_available(blk)) {
+        goto notfound;
+    }
+    bs = blk_bs(blk);
+
+    if (!bs->job) {
+        goto notfound;
+    }
+
+    return bs->job;
+
+notfound:
+    error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE,
+              "No active block job on device '%s'", device);
+    if (*aio_context) {
+        aio_context_release(*aio_context);
+        *aio_context = NULL;
+    }
+    return NULL;
 }
 
 void qmp_block_job_set_speed(const char *device, int64_t speed, Error **errp)
@@ -3761,7 +3798,6 @@ void qmp_block_job_resume(const char *device, Error **errp)
 
     job->user_paused = false;
     trace_qmp_block_job_resume(job);
-    block_job_iostatus_reset(job);
     block_job_resume(job);
     aio_context_release(aio_context);
 }
@@ -3864,7 +3900,9 @@ void qmp_change_backing_file(const char *device,
 
     if (ro) {
         bdrv_reopen(image_bs, open_flags, &local_err);
-        error_propagate(errp, local_err);
+        if (local_err) {
+            error_propagate(errp, local_err); /* will preserve prior errp */
+        }
     }
 
 out:
@@ -3904,10 +3942,10 @@ out:
 
 void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
 {
+    QmpOutputVisitor *ov = qmp_output_visitor_new();
     BlockDriverState *bs;
     BlockBackend *blk = NULL;
     QObject *obj;
-    Visitor *v = qmp_output_visitor_new(&obj);
     QDict *qdict;
     Error *local_err = NULL;
 
@@ -3926,13 +3964,14 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
         }
     }
 
-    visit_type_BlockdevOptions(v, NULL, &options, &local_err);
+    visit_type_BlockdevOptions(qmp_output_get_visitor(ov), NULL, &options,
+                               &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         goto fail;
     }
 
-    visit_complete(v, &obj);
+    obj = qmp_output_get_qobject(ov);
     qdict = qobject_to_qdict(obj);
 
     qdict_flatten(qdict);
@@ -3973,7 +4012,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
     }
 
 fail:
-    visit_free(v);
+    qmp_output_visitor_cleanup(ov);
 }
 
 void qmp_x_blockdev_del(bool has_id, const char *id,
@@ -4010,15 +4049,15 @@ void qmp_x_blockdev_del(bool has_id, const char *id,
         bs = blk_bs(blk);
         aio_context = blk_get_aio_context(blk);
     } else {
-        blk = NULL;
         bs = bdrv_find_node(node_name);
         if (!bs) {
             error_setg(errp, "Cannot find node %s", node_name);
             return;
         }
-        if (bdrv_has_blk(bs)) {
+        blk = bs->blk;
+        if (blk) {
             error_setg(errp, "Node %s is in use by %s",
-                       node_name, bdrv_get_parent_name(bs));
+                       node_name, blk_name(blk));
             return;
         }
         aio_context = bdrv_get_aio_context(bs);
@@ -4056,76 +4095,24 @@ out:
     aio_context_release(aio_context);
 }
 
-static BdrvChild *bdrv_find_child(BlockDriverState *parent_bs,
-                                  const char *child_name)
-{
-    BdrvChild *child;
-
-    QLIST_FOREACH(child, &parent_bs->children, next) {
-        if (strcmp(child->name, child_name) == 0) {
-            return child;
-        }
-    }
-
-    return NULL;
-}
-
-void qmp_x_blockdev_change(const char *parent, bool has_child,
-                           const char *child, bool has_node,
-                           const char *node, Error **errp)
-{
-    BlockDriverState *parent_bs, *new_bs = NULL;
-    BdrvChild *p_child;
-
-    parent_bs = bdrv_lookup_bs(parent, parent, errp);
-    if (!parent_bs) {
-        return;
-    }
-
-    if (has_child == has_node) {
-        if (has_child) {
-            error_setg(errp, "The parameters child and node are in conflict");
-        } else {
-            error_setg(errp, "Either child or node must be specified");
-        }
-        return;
-    }
-
-    if (has_child) {
-        p_child = bdrv_find_child(parent_bs, child);
-        if (!p_child) {
-            error_setg(errp, "Node '%s' does not have child '%s'",
-                       parent, child);
-            return;
-        }
-        bdrv_del_child(parent_bs, p_child, errp);
-    }
-
-    if (has_node) {
-        new_bs = bdrv_find_node(node);
-        if (!new_bs) {
-            error_setg(errp, "Node '%s' not found", node);
-            return;
-        }
-        bdrv_add_child(parent_bs, new_bs, errp);
-    }
-}
-
 BlockJobInfoList *qmp_query_block_jobs(Error **errp)
 {
     BlockJobInfoList *head = NULL, **p_next = &head;
-    BlockJob *job;
+    BlockDriverState *bs;
 
-    for (job = block_job_next(NULL); job; job = block_job_next(job)) {
-        BlockJobInfoList *elem = g_new0(BlockJobInfoList, 1);
-        AioContext *aio_context = blk_get_aio_context(job->blk);
+    for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
+        AioContext *aio_context = bdrv_get_aio_context(bs);
 
         aio_context_acquire(aio_context);
-        elem->value = block_job_query(job);
-        aio_context_release(aio_context);
 
-        *p_next = elem;
-        p_next = &elem->next;
+        if (bs->job) {
+            BlockJobInfoList *elem = g_new0(BlockJobInfoList, 1);
+            elem->value = block_job_query(bs->job);
+            *p_next = elem;
+            p_next = &elem->next;
+        }
+
+        aio_context_release(aio_context);
     }
 
     return head;
index a5ba3be..9fc37ca 100644 (file)
@@ -33,7 +33,6 @@
 #include "qapi/qmp/qerror.h"
 #include "qapi/qmp/qjson.h"
 #include "qemu/coroutine.h"
-#include "qemu/id.h"
 #include "qmp-commands.h"
 #include "qemu/timer.h"
 #include "qapi-event.h"
@@ -51,102 +50,17 @@ struct BlockJobTxn {
     int refcnt;
 };
 
-static QLIST_HEAD(, BlockJob) block_jobs = QLIST_HEAD_INITIALIZER(block_jobs);
-
-BlockJob *block_job_next(BlockJob *job)
-{
-    if (!job) {
-        return QLIST_FIRST(&block_jobs);
-    }
-    return QLIST_NEXT(job, job_list);
-}
-
-BlockJob *block_job_get(const char *id)
+void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
+                       int64_t speed, BlockCompletionFunc *cb,
+                       void *opaque, Error **errp)
 {
     BlockJob *job;
 
-    QLIST_FOREACH(job, &block_jobs, job_list) {
-        if (!strcmp(id, job->id)) {
-            return job;
-        }
-    }
-
-    return NULL;
-}
-
-/* Normally the job runs in its BlockBackend's AioContext.  The exception is
- * block_job_defer_to_main_loop() where it runs in the QEMU main loop.  Code
- * that supports both cases uses this helper function.
- */
-static AioContext *block_job_get_aio_context(BlockJob *job)
-{
-    return job->deferred_to_main_loop ?
-           qemu_get_aio_context() :
-           blk_get_aio_context(job->blk);
-}
-
-static void block_job_attached_aio_context(AioContext *new_context,
-                                           void *opaque)
-{
-    BlockJob *job = opaque;
-
-    if (job->driver->attached_aio_context) {
-        job->driver->attached_aio_context(job, new_context);
-    }
-
-    block_job_resume(job);
-}
-
-static void block_job_detach_aio_context(void *opaque)
-{
-    BlockJob *job = opaque;
-
-    /* In case the job terminates during aio_poll()... */
-    block_job_ref(job);
-
-    block_job_pause(job);
-
-    if (!job->paused) {
-        /* If job is !job->busy this kicks it into the next pause point. */
-        block_job_enter(job);
-    }
-    while (!job->paused && !job->completed) {
-        aio_poll(block_job_get_aio_context(job), true);
-    }
-
-    block_job_unref(job);
-}
-
-void *block_job_create(const char *job_id, const BlockJobDriver *driver,
-                       BlockDriverState *bs, int64_t speed,
-                       BlockCompletionFunc *cb, void *opaque, Error **errp)
-{
-    BlockBackend *blk;
-    BlockJob *job;
-
-    assert(cb);
     if (bs->job) {
         error_setg(errp, QERR_DEVICE_IN_USE, bdrv_get_device_name(bs));
         return NULL;
     }
-
-    if (job_id == NULL) {
-        job_id = bdrv_get_device_name(bs);
-    }
-
-    if (!id_wellformed(job_id)) {
-        error_setg(errp, "Invalid job ID '%s'", job_id);
-        return NULL;
-    }
-
-    if (block_job_get(job_id)) {
-        error_setg(errp, "Job ID '%s' already in use", job_id);
-        return NULL;
-    }
-
-    blk = blk_new();
-    blk_insert_bs(blk, bs);
-
+    bdrv_ref(bs);
     job = g_malloc0(driver->instance_size);
     error_setg(&job->blocker, "block device is in use by block job: %s",
                BlockJobType_lookup[driver->job_type]);
@@ -154,19 +68,14 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
     bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
 
     job->driver        = driver;
-    job->id            = g_strdup(job_id);
-    job->blk           = blk;
+    job->id            = g_strdup(bdrv_get_device_name(bs));
+    job->bs            = bs;
     job->cb            = cb;
     job->opaque        = opaque;
     job->busy          = true;
     job->refcnt        = 1;
     bs->job = job;
 
-    QLIST_INSERT_HEAD(&block_jobs, job, job_list);
-
-    blk_add_aio_context_notifier(blk, block_job_attached_aio_context,
-                                 block_job_detach_aio_context, job);
-
     /* Only set speed when necessary to avoid NotSupported error */
     if (speed != 0) {
         Error *local_err = NULL;
@@ -189,16 +98,11 @@ void block_job_ref(BlockJob *job)
 void block_job_unref(BlockJob *job)
 {
     if (--job->refcnt == 0) {
-        BlockDriverState *bs = blk_bs(job->blk);
-        bs->job = NULL;
-        bdrv_op_unblock_all(bs, job->blocker);
-        blk_remove_aio_context_notifier(job->blk,
-                                        block_job_attached_aio_context,
-                                        block_job_detach_aio_context, job);
-        blk_unref(job->blk);
+        job->bs->job = NULL;
+        bdrv_op_unblock_all(job->bs, job->blocker);
+        bdrv_unref(job->bs);
         error_free(job->blocker);
         g_free(job->id);
-        QLIST_REMOVE(job, job_list);
         g_free(job);
     }
 }
@@ -236,7 +140,7 @@ static void block_job_completed_txn_abort(BlockJob *job)
     txn->aborting = true;
     /* We are the first failed job. Cancel other jobs. */
     QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
-        ctx = blk_get_aio_context(other_job->blk);
+        ctx = bdrv_get_aio_context(other_job->bs);
         aio_context_acquire(ctx);
     }
     QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
@@ -253,7 +157,7 @@ static void block_job_completed_txn_abort(BlockJob *job)
         assert(other_job->completed);
     }
     QLIST_FOREACH_SAFE(other_job, &txn->jobs, txn_list, next) {
-        ctx = blk_get_aio_context(other_job->blk);
+        ctx = bdrv_get_aio_context(other_job->bs);
         block_job_completed_single(other_job);
         aio_context_release(ctx);
     }
@@ -275,7 +179,7 @@ static void block_job_completed_txn_success(BlockJob *job)
     }
     /* We are the last completed job, commit the transaction. */
     QLIST_FOREACH_SAFE(other_job, &txn->jobs, txn_list, next) {
-        ctx = blk_get_aio_context(other_job->blk);
+        ctx = bdrv_get_aio_context(other_job->bs);
         aio_context_acquire(ctx);
         assert(other_job->ret == 0);
         block_job_completed_single(other_job);
@@ -285,7 +189,9 @@ static void block_job_completed_txn_success(BlockJob *job)
 
 void block_job_completed(BlockJob *job, int ret)
 {
-    assert(blk_bs(job->blk)->job == job);
+    BlockDriverState *bs = job->bs;
+
+    assert(bs->job == job);
     assert(!job->completed);
     job->completed = true;
     job->ret = ret;
@@ -318,8 +224,7 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
 void block_job_complete(BlockJob *job, Error **errp)
 {
     if (job->pause_count || job->cancelled || !job->driver->complete) {
-        error_setg(errp, "The active block job '%s' cannot be completed",
-                   job->id);
+        error_setg(errp, QERR_BLOCK_JOB_NOT_READY, job->id);
         return;
     }
 
@@ -331,37 +236,11 @@ void block_job_pause(BlockJob *job)
     job->pause_count++;
 }
 
-static bool block_job_should_pause(BlockJob *job)
+bool block_job_is_paused(BlockJob *job)
 {
     return job->pause_count > 0;
 }
 
-void coroutine_fn block_job_pause_point(BlockJob *job)
-{
-    if (!block_job_should_pause(job)) {
-        return;
-    }
-    if (block_job_is_cancelled(job)) {
-        return;
-    }
-
-    if (job->driver->pause) {
-        job->driver->pause(job);
-    }
-
-    if (block_job_should_pause(job) && !block_job_is_cancelled(job)) {
-        job->paused = true;
-        job->busy = false;
-        qemu_coroutine_yield(); /* wait for block_job_resume() */
-        job->busy = true;
-        job->paused = false;
-    }
-
-    if (job->driver->resume) {
-        job->driver->resume(job);
-    }
-}
-
 void block_job_resume(BlockJob *job)
 {
     assert(job->pause_count > 0);
@@ -374,15 +253,15 @@ void block_job_resume(BlockJob *job)
 
 void block_job_enter(BlockJob *job)
 {
+    block_job_iostatus_reset(job);
     if (job->co && !job->busy) {
-        qemu_coroutine_enter(job->co);
+        qemu_coroutine_enter(job->co, NULL);
     }
 }
 
 void block_job_cancel(BlockJob *job)
 {
     job->cancelled = true;
-    block_job_iostatus_reset(job);
     block_job_enter(job);
 }
 
@@ -403,10 +282,11 @@ static int block_job_finish_sync(BlockJob *job,
                                  void (*finish)(BlockJob *, Error **errp),
                                  Error **errp)
 {
+    BlockDriverState *bs = job->bs;
     Error *local_err = NULL;
     int ret;
 
-    assert(blk_bs(job->blk)->job == job);
+    assert(bs->job == job);
 
     block_job_ref(job);
     finish(job, &local_err);
@@ -416,7 +296,9 @@ static int block_job_finish_sync(BlockJob *job,
         return -EBUSY;
     }
     while (!job->completed) {
-        aio_poll(block_job_get_aio_context(job), true);
+        aio_poll(job->deferred_to_main_loop ? qemu_get_aio_context() :
+                                              bdrv_get_aio_context(bs),
+                 true);
     }
     ret = (job->cancelled && job->ret == 0) ? -ECANCELED : job->ret;
     block_job_unref(job);
@@ -436,19 +318,6 @@ int block_job_cancel_sync(BlockJob *job)
     return block_job_finish_sync(job, &block_job_cancel_err, NULL);
 }
 
-void block_job_cancel_sync_all(void)
-{
-    BlockJob *job;
-    AioContext *aio_context;
-
-    while ((job = QLIST_FIRST(&block_jobs))) {
-        aio_context = blk_get_aio_context(job->blk);
-        aio_context_acquire(aio_context);
-        block_job_cancel_sync(job);
-        aio_context_release(aio_context);
-    }
-}
-
 int block_job_complete_sync(BlockJob *job, Error **errp)
 {
     return block_job_finish_sync(job, &block_job_complete, errp);
@@ -464,12 +333,12 @@ void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns)
     }
 
     job->busy = false;
-    if (!block_job_should_pause(job)) {
-        co_aio_sleep_ns(blk_get_aio_context(job->blk), type, ns);
+    if (block_job_is_paused(job)) {
+        qemu_coroutine_yield();
+    } else {
+        co_aio_sleep_ns(bdrv_get_aio_context(job->bs), type, ns);
     }
     job->busy = true;
-
-    block_job_pause_point(job);
 }
 
 void block_job_yield(BlockJob *job)
@@ -482,12 +351,8 @@ void block_job_yield(BlockJob *job)
     }
 
     job->busy = false;
-    if (!block_job_should_pause(job)) {
-        qemu_coroutine_yield();
-    }
+    qemu_coroutine_yield();
     job->busy = true;
-
-    block_job_pause_point(job);
 }
 
 BlockJobInfo *block_job_query(BlockJob *job)
@@ -546,14 +411,14 @@ void block_job_event_ready(BlockJob *job)
                                     job->speed, &error_abort);
 }
 
-BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
+BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs,
+                                        BlockdevOnError on_err,
                                         int is_read, int error)
 {
     BlockErrorAction action;
 
     switch (on_err) {
     case BLOCKDEV_ON_ERROR_ENOSPC:
-    case BLOCKDEV_ON_ERROR_AUTO:
         action = (error == ENOSPC) ?
                  BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
         break;
@@ -578,6 +443,9 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
         job->user_paused = true;
         block_job_pause(job);
         block_job_iostatus_set_err(job, error);
+        if (bs->blk && bs != job->bs) {
+            blk_iostatus_set_err(bs->blk, error);
+        }
     }
     return action;
 }
@@ -601,7 +469,7 @@ static void block_job_defer_to_main_loop_bh(void *opaque)
     aio_context_acquire(data->aio_context);
 
     /* Fetch BDS AioContext again, in case it has changed */
-    aio_context = blk_get_aio_context(data->job->blk);
+    aio_context = bdrv_get_aio_context(data->job->bs);
     aio_context_acquire(aio_context);
 
     data->job->deferred_to_main_loop = false;
@@ -621,7 +489,7 @@ void block_job_defer_to_main_loop(BlockJob *job,
     BlockJobDeferToMainLoopData *data = g_malloc(sizeof(*data));
     data->job = job;
     data->bh = qemu_bh_new(block_job_defer_to_main_loop_bh, data);
-    data->aio_context = blk_get_aio_context(job->blk);
+    data->aio_context = bdrv_get_aio_context(job->bs);
     data->fn = fn;
     data->opaque = opaque;
     job->deferred_to_main_loop = true;
index 33e3029..2e83ff0 100644 (file)
@@ -28,7 +28,6 @@
 #include "qapi/visitor.h"
 #include "qemu/error-report.h"
 #include "hw/hw.h"
-#include "hw/qdev-core.h"
 
 typedef struct FWBootEntry FWBootEntry;
 
@@ -302,7 +301,9 @@ static void device_set_bootindex(Object *obj, Visitor *v, const char *name,
     add_boot_device_path(*prop->bootindex, prop->dev, prop->suffix);
 
 out:
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
 }
 
 static void property_release_bootindex(Object *obj, const char *name,
index 41a1309..898ee05 100644 (file)
@@ -1,6 +1,7 @@
 /* This is the Linux kernel elf-loading code, ported into user space */
 
 #include "qemu/osdep.h"
+#include <sys/mman.h>
 
 #include "qemu.h"
 #include "disas/disas.h"
index 8f20138..82d1c58 100644 (file)
@@ -162,4 +162,4 @@ struct target_vm86plus_struct {
 
 #define UNAME_MACHINE "i386"
 
-#endif /* TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index 0fb08e4..27854c1 100644 (file)
  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "qemu/osdep.h"
-#include "qemu-version.h"
 #include <machine/trap.h>
+#include <sys/mman.h>
 
-#include "qapi/error.h"
 #include "qemu.h"
-#include "qemu/config-file.h"
 #include "qemu/path.h"
 #include "qemu/help_option.h"
 /* For tb_lock */
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "tcg.h"
 #include "qemu/timer.h"
 #include "qemu/envlist.h"
 #include "exec/log.h"
-#include "trace/control.h"
-#include "glib-compat.h"
 
 int singlestep;
 unsigned long mmap_min_addr;
@@ -172,7 +167,7 @@ void cpu_loop(CPUX86State *env)
     //target_siginfo_t info;
 
     for(;;) {
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_x86_exec(cs);
         switch(trapnr) {
         case 0x80:
             /* syscall from int $0x80 */
@@ -513,7 +508,7 @@ void cpu_loop(CPUSPARCState *env)
     //target_siginfo_t info;
 
     while (1) {
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_sparc_exec(cs);
 
         switch (trapnr) {
 #ifndef TARGET_SPARC64
@@ -668,8 +663,7 @@ void cpu_loop(CPUSPARCState *env)
 
 static void usage(void)
 {
-    printf("qemu-" TARGET_NAME " version " QEMU_VERSION QEMU_PKGVERSION
-           ", " QEMU_COPYRIGHT "\n"
+    printf("qemu-" TARGET_NAME " version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
            "usage: qemu-" TARGET_NAME " [options] program [arguments...]\n"
            "BSD CPU emulator (compiled for %s emulation)\n"
            "\n"
@@ -692,8 +686,6 @@ static void usage(void)
            "-p pagesize       set the host page size to 'pagesize'\n"
            "-singlestep       always run in singlestep mode\n"
            "-strace           log system calls\n"
-           "-trace            [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
-           "                  specify tracing options\n"
            "\n"
            "Environment variables:\n"
            "QEMU_STRACE       Print system calls and arguments similar to the\n"
@@ -742,7 +734,6 @@ int main(int argc, char **argv)
     int gdbstub_port = 0;
     char **target_environ, **wrk;
     envlist_t *envlist = NULL;
-    char *trace_file = NULL;
     bsd_type = target_openbsd;
 
     if (argc <= 1)
@@ -761,11 +752,12 @@ int main(int argc, char **argv)
     }
 
     cpu_model = NULL;
-
-    qemu_add_opts(&qemu_trace_opts);
+#if defined(cpudef_setup)
+    cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
+#endif
 
     optind = 1;
-    for (;;) {
+    for(;;) {
         if (optind >= argc)
             break;
         r = argv[optind];
@@ -850,17 +842,14 @@ int main(int argc, char **argv)
             singlestep = 1;
         } else if (!strcmp(r, "strace")) {
             do_strace = 1;
-        } else if (!strcmp(r, "trace")) {
-            g_free(trace_file);
-            trace_file = trace_opt_parse(optarg);
-        } else {
+        } else
+        {
             usage();
         }
     }
 
     /* init debug */
-    qemu_log_needs_buffers();
-    qemu_set_log_filename(log_file, &error_fatal);
+    qemu_set_log_filename(log_file);
     if (log_mask) {
         int mask;
 
@@ -877,11 +866,6 @@ int main(int argc, char **argv)
     }
     filename = argv[optind];
 
-    if (!trace_init_backends()) {
-        exit(1);
-    }
-    trace_init_file(trace_file);
-
     /* Zero out regs */
     memset(regs, 0, sizeof(struct target_pt_regs));
 
@@ -1133,7 +1117,6 @@ int main(int argc, char **argv)
         gdbserver_start (gdbstub_port);
         gdb_handlesig(cpu, 0);
     }
-    trace_init_vcpu_events();
     cpu_loop(env);
     /* never exits */
     return 0;
index 610f91b..6ab5334 100644 (file)
@@ -17,6 +17,7 @@
  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "qemu/osdep.h"
+#include <sys/mman.h>
 
 #include "qemu.h"
 #include "qemu-common.h"
index 2b2b918..03b502a 100644 (file)
@@ -19,7 +19,6 @@
 
 
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 #undef DEBUG_REMAP
@@ -209,6 +208,8 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
                        abi_ulong new_addr);
 int target_msync(abi_ulong start, abi_ulong len, int flags);
 extern unsigned long last_brk;
+void cpu_list_lock(void);
+void cpu_list_unlock(void);
 #if defined(CONFIG_USE_NPTL)
 void mmap_fork_start(void);
 void mmap_fork_end(int child);
@@ -356,7 +357,7 @@ static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy
 #ifdef DEBUG_REMAP
     {
         void *addr;
-        addr = g_malloc(len);
+        addr = malloc(len);
         if (copy)
             memcpy(addr, g2h(guest_addr), len);
         else
@@ -382,7 +383,7 @@ static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
         return;
     if (len > 0)
         memcpy(g2h(guest_addr), host_ptr, len);
-    g_free(host_ptr);
+    free(host_ptr);
 #endif
 }
 
index dfdf9f8..c7eec6b 100644 (file)
@@ -11,4 +11,4 @@ struct target_pt_regs {
 
 #define UNAME_MACHINE "sun4"
 
-#endif /* TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index 3a9f4c2..2f06100 100644 (file)
@@ -12,4 +12,4 @@ struct target_pt_regs {
 
 #define UNAME_MACHINE "sun4u"
 
-#endif /* TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index 66492aa..47cf865 100644 (file)
@@ -19,6 +19,7 @@
 #include "qemu/osdep.h"
 #include "qemu/cutils.h"
 #include "qemu/path.h"
+#include <sys/mman.h>
 #include <sys/syscall.h>
 #include <sys/param.h>
 #include <sys/sysctl.h>
@@ -315,14 +316,12 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
                             abi_long arg5, abi_long arg6, abi_long arg7,
                             abi_long arg8)
 {
-    CPUState *cpu = ENV_GET_CPU(cpu_env);
     abi_long ret;
     void *p;
 
 #ifdef DEBUG
     gemu_log("freebsd syscall %d\n", num);
 #endif
-    trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
     if(do_strace)
         print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
 
@@ -402,7 +401,6 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
     if (do_strace)
         print_freebsd_syscall_ret(num, ret);
-    trace_guest_user_syscall_ret(cpu, num, ret);
     return ret;
  efault:
     ret = -TARGET_EFAULT;
@@ -413,14 +411,12 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
                            abi_long arg2, abi_long arg3, abi_long arg4,
                            abi_long arg5, abi_long arg6)
 {
-    CPUState *cpu = ENV_GET_CPU(cpu_env);
     abi_long ret;
     void *p;
 
 #ifdef DEBUG
     gemu_log("netbsd syscall %d\n", num);
 #endif
-    trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 0);
     if(do_strace)
         print_netbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
 
@@ -477,7 +473,6 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
     if (do_strace)
         print_netbsd_syscall_ret(num, ret);
-    trace_guest_user_syscall_ret(cpu, num, ret);
     return ret;
  efault:
     ret = -TARGET_EFAULT;
@@ -488,14 +483,12 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
                             abi_long arg2, abi_long arg3, abi_long arg4,
                             abi_long arg5, abi_long arg6)
 {
-    CPUState *cpu = ENV_GET_CPU(cpu_env);
     abi_long ret;
     void *p;
 
 #ifdef DEBUG
     gemu_log("openbsd syscall %d\n", num);
 #endif
-    trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 0);
     if(do_strace)
         print_openbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
 
@@ -552,7 +545,6 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
     if (do_strace)
         print_openbsd_syscall_ret(num, ret);
-    trace_guest_user_syscall_ret(cpu, num, ret);
     return ret;
  efault:
     ret = -TARGET_EFAULT;
index 211ce29..85a9766 100644 (file)
@@ -118,4 +118,4 @@ struct target_msqid64_ds {
 #define TARGET_ARCH_GET_FS 0x1003
 #define TARGET_ARCH_GET_GS 0x1004
 
-#endif /* TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index 4b808f9..60e3c0d 100755 (executable)
--- a/configure
+++ b/configure
@@ -31,7 +31,6 @@ TMPCXX="${TMPDIR1}/${TMPB}.cxx"
 TMPL="${TMPDIR1}/${TMPB}.lo"
 TMPA="${TMPDIR1}/lib${TMPB}.la"
 TMPE="${TMPDIR1}/${TMPB}.exe"
-TMPMO="${TMPDIR1}/${TMPB}.mo"
 
 rm -f config.log
 
@@ -165,7 +164,7 @@ have_backend () {
 }
 
 # default parameters
-source_path=$(dirname "$0")
+source_path=`dirname "$0"`
 cpu=""
 iasl="iasl"
 interp_prefix="/usr/gnemul/qemu-%M"
@@ -208,7 +207,7 @@ fdt=""
 netmap="no"
 pixman=""
 sdl=""
-sdlabi=""
+sdlabi="1.2"
 virtfs=""
 vnc="yes"
 sparse="no"
@@ -270,6 +269,7 @@ aix="no"
 blobs="yes"
 pkgversion=""
 pie=""
+zero_malloc=""
 qom_cast_debug="yes"
 trace_backends="log"
 trace_file="trace"
@@ -305,8 +305,8 @@ archipelago="no"
 gtk=""
 gtkabi=""
 gtk_gl="no"
-tls_priority="NORMAL"
 gnutls=""
+gnutls_hash=""
 gnutls_rnd=""
 nettle=""
 nettle_kdf="no"
@@ -323,7 +323,7 @@ jemalloc="no"
 
 # parse CC options first
 for opt do
-  optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
+  optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
   case "$opt" in
   --cross-prefix=*) cross_prefix="$optarg"
   ;;
@@ -369,7 +369,6 @@ fi
 
 ar="${AR-${cross_prefix}ar}"
 as="${AS-${cross_prefix}as}"
-ccas="${CCAS-$cc}"
 cpp="${CPP-$cc -E}"
 objcopy="${OBJCOPY-${cross_prefix}objcopy}"
 ld="${LD-${cross_prefix}ld}"
@@ -399,7 +398,7 @@ if test "$debug_info" = "yes"; then
 fi
 
 # make source path absolute
-source_path=$(cd "$source_path"; pwd)
+source_path=`cd "$source_path"; pwd`
 
 # running configure in the source tree?
 # we know that's the case if configure is there.
@@ -444,7 +443,7 @@ elif check_define __sun__ ; then
 elif check_define __HAIKU__ ; then
   targetos='Haiku'
 else
-  targetos=$(uname -s)
+  targetos=`uname -s`
 fi
 
 # Some host OSes need non-standard checks for which CPU to use.
@@ -462,7 +461,7 @@ Darwin)
   fi
   ;;
 SunOS)
-  # $(uname -m) returns i86pc even on an x86_64 box, so default based on isainfo
+  # `uname -m` returns i86pc even on an x86_64 box, so default based on isainfo
   if test -z "$cpu" && test "$(isainfo -k)" = "amd64"; then
     cpu="x86_64"
   fi
@@ -508,7 +507,7 @@ elif check_define __aarch64__ ; then
 elif check_define __hppa__ ; then
   cpu="hppa"
 else
-  cpu=$(uname -m)
+  cpu=`uname -m`
 fi
 
 ARCH=
@@ -628,7 +627,7 @@ SunOS)
   ld="gld"
   smbd="${SMBD-/usr/sfw/sbin/smbd}"
   needs_libsunmath="no"
-  solarisrev=$(uname -r | cut -f2 -d.)
+  solarisrev=`uname -r | cut -f2 -d.`
   if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
     if test "$solarisrev" -le 9 ; then
       if test -f /opt/SUNWspro/prod/lib/libsunmath.so.1; then
@@ -723,7 +722,7 @@ fi
 werror=""
 
 for opt do
-  optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
+  optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
   case "$opt" in
   --help|-h) show_help=yes
   ;;
@@ -847,9 +846,9 @@ for opt do
   ;;
   --audio-drv-list=*) audio_drv_list="$optarg"
   ;;
-  --block-drv-rw-whitelist=*|--block-drv-whitelist=*) block_drv_rw_whitelist=$(echo "$optarg" | sed -e 's/,/ /g')
+  --block-drv-rw-whitelist=*|--block-drv-whitelist=*) block_drv_rw_whitelist=`echo "$optarg" | sed -e 's/,/ /g'`
   ;;
-  --block-drv-ro-whitelist=*) block_drv_ro_whitelist=$(echo "$optarg" | sed -e 's/,/ /g')
+  --block-drv-ro-whitelist=*) block_drv_ro_whitelist=`echo "$optarg" | sed -e 's/,/ /g'`
   ;;
   --enable-debug-tcg) debug_tcg="yes"
   ;;
@@ -944,7 +943,7 @@ for opt do
   ;;
   --enable-cocoa)
       cocoa="yes" ;
-      audio_drv_list="coreaudio $(echo $audio_drv_list | sed s,coreaudio,,g)"
+      audio_drv_list="coreaudio `echo $audio_drv_list | sed s,coreaudio,,g`"
   ;;
   --disable-system) softmmu="no"
   ;;
@@ -1098,8 +1097,6 @@ for opt do
   ;;
   --enable-gtk) gtk="yes"
   ;;
-  --tls-priority=*) tls_priority="$optarg"
-  ;;
   --disable-gnutls) gnutls="no"
   ;;
   --enable-gnutls) gnutls="yes"
@@ -1219,13 +1216,6 @@ esac
 QEMU_CFLAGS="$CPU_CFLAGS $QEMU_CFLAGS"
 EXTRA_CFLAGS="$CPU_CFLAGS $EXTRA_CFLAGS"
 
-# For user-mode emulation the host arch has to be one we explicitly
-# support, even if we're using TCI.
-if [ "$ARCH" = "unknown" ]; then
-  bsd_user="no"
-  linux_user="no"
-fi
-
 default_target_list=""
 
 mak_wilds=""
@@ -1311,7 +1301,6 @@ Advanced options (experts only):
   --disable-blobs          disable installing provided firmware blobs
   --with-vss-sdk=SDK-path  enable Windows VSS support in QEMU Guest Agent
   --with-win-sdk=SDK-path  path to Windows Platform SDK (to build VSS .tlb)
-  --tls-priority           default TLS protocol/cipher priority string
 
 Optional features, enabled with --enable-FEATURE and
 disabled with --disable-FEATURE, default is enabled if available:
@@ -1391,6 +1380,7 @@ fi
 if test "$ARCH" = "unknown"; then
     if test "$tcg_interpreter" = "yes" ; then
         echo "Unsupported CPU = $cpu, will use TCG with TCI (experimental)"
+        ARCH=tci
     else
         error_exit "Unsupported CPU = $cpu, try --enable-tcg-interpreter"
     fi
@@ -1398,9 +1388,11 @@ fi
 
 # Consult white-list to determine whether to enable werror
 # by default.  Only enable by default for git builds
+z_version=`cut -f3 -d. $source_path/VERSION`
+
 if test -z "$werror" ; then
     if test -d "$source_path/.git" -a \
-        \( "$linux" = "yes" -o "$mingw32" = "yes" \) ; then
+        "$linux" = "yes" ; then
         werror="yes"
     else
         werror="no"
@@ -1452,7 +1444,7 @@ fi
 gcc_flags="-Wold-style-declaration -Wold-style-definition -Wtype-limits"
 gcc_flags="-Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers $gcc_flags"
 gcc_flags="-Wmissing-include-dirs -Wempty-body -Wnested-externs $gcc_flags"
-gcc_flags="-Wendif-labels -Wno-shift-negative-value $gcc_flags"
+gcc_flags="-Wendif-labels $gcc_flags"
 gcc_flags="-Wno-initializer-overrides $gcc_flags"
 gcc_flags="-Wno-string-plus-int $gcc_flags"
 # Note that we do not add -Werror to gcc_flags here, because that would
@@ -1625,7 +1617,7 @@ if test "$solaris" = "yes" ; then
         "install fileutils from www.blastwave.org using pkg-get -i fileutils" \
         "to get ginstall which is used by default (which lives in /opt/csw/bin)"
   fi
-  if test "$(path_of $install)" = "/usr/sbin/install" ; then
+  if test "`path_of $install`" = "/usr/sbin/install" ; then
     error_exit "Solaris /usr/sbin/install is not an appropriate install program." \
         "try ginstall from the GNU fileutils available from www.blastwave.org" \
         "using pkg-get -i fileutils, or use --install=/usr/ucb/install"
@@ -1644,7 +1636,7 @@ fi
 if test -z "${target_list+xxx}" ; then
     target_list="$default_target_list"
 else
-    target_list=$(echo "$target_list" | sed -e 's/,/ /g')
+    target_list=`echo "$target_list" | sed -e 's/,/ /g'`
 fi
 
 # Check that we recognised the target name; this allows a more
@@ -1788,28 +1780,16 @@ fi
 ##########################################
 # avx2 optimization requirement check
 
-
-if test "$static" = "no" ; then
-  cat > $TMPC << EOF
-#pragma GCC push_options
-#pragma GCC target("avx2")
-#include <cpuid.h>
-#include <immintrin.h>
-
-static int bar(void *a) {
-    return _mm256_movemask_epi8(_mm256_cmpeq_epi8(*(__m256i *)a, (__m256i){0}));
-}
+cat > $TMPC << EOF
+static void bar(void) {}
 static void *bar_ifunc(void) {return (void*) bar;}
-int foo(void *a) __attribute__((ifunc("bar_ifunc")));
-int main(int argc, char *argv[]) { return foo(argv[0]);}
+static void foo(void) __attribute__((ifunc("bar_ifunc")));
+int main(void) { foo(); return 0; }
 EOF
-  if compile_object "" ; then
-      if has readelf; then
-          if readelf --syms $TMPO 2>/dev/null |grep -q "IFUNC.*foo"; then
-              avx2_opt="yes"
-          fi
-      fi
-  fi
+if compile_prog "-mavx2" "" ; then
+    if readelf --syms $TMPE |grep "IFUNC.*foo" >/dev/null 2>&1; then
+        avx2_opt="yes"
+    fi
 fi
 
 #########################################
@@ -1899,9 +1879,6 @@ if test "$seccomp" != "no" ; then
     arm|aarch64)
         libseccomp_minver="2.2.3"
         ;;
-    ppc|ppc64)
-        libseccomp_minver="2.3.0"
-        ;;
     *)
         libseccomp_minver=""
         ;;
@@ -1909,8 +1886,8 @@ if test "$seccomp" != "no" ; then
 
     if test "$libseccomp_minver" != "" &&
        $pkg_config --atleast-version=$libseccomp_minver libseccomp ; then
-        libs_softmmu="$libs_softmmu $($pkg_config --libs libseccomp)"
-        QEMU_CFLAGS="$QEMU_CFLAGS $($pkg_config --cflags libseccomp)"
+        libs_softmmu="$libs_softmmu `$pkg_config --libs libseccomp`"
+        QEMU_CFLAGS="$QEMU_CFLAGS `$pkg_config --cflags libseccomp`"
         seccomp="yes"
     else
         if test "$seccomp" = "yes" ; then
@@ -2150,8 +2127,8 @@ fi
 x11_cflags=
 x11_libs=-lX11
 if $pkg_config --exists "x11"; then
-    x11_cflags=$($pkg_config --cflags x11)
-    x11_libs=$($pkg_config --libs x11)
+    x11_cflags=`$pkg_config --cflags x11`
+    x11_libs=`$pkg_config --libs x11`
 fi
 
 ##########################################
@@ -2178,9 +2155,8 @@ if test "$gtk" != "no"; then
       gtkversion="2.18.0"
     fi
     if $pkg_config --exists "$gtkpackage >= $gtkversion"; then
-        gtk_cflags=$($pkg_config --cflags $gtkpackage)
-        gtk_libs=$($pkg_config --libs $gtkpackage)
-        gtk_version=$($pkg_config --modversion $gtkpackage)
+        gtk_cflags=`$pkg_config --cflags $gtkpackage`
+        gtk_libs=`$pkg_config --libs $gtkpackage`
         if $pkg_config --exists "$gtkx11package >= $gtkversion"; then
             gtk_cflags="$gtk_cflags $x11_cflags"
             gtk_libs="$gtk_libs $x11_libs"
@@ -2218,13 +2194,20 @@ gnutls_gcrypt=no
 gnutls_nettle=no
 if test "$gnutls" != "no"; then
     if gnutls_works; then
-        gnutls_cflags=$($pkg_config --cflags gnutls)
-        gnutls_libs=$($pkg_config --libs gnutls)
+        gnutls_cflags=`$pkg_config --cflags gnutls`
+        gnutls_libs=`$pkg_config --libs gnutls`
         libs_softmmu="$gnutls_libs $libs_softmmu"
         libs_tools="$gnutls_libs $libs_tools"
        QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
         gnutls="yes"
 
+       # gnutls_hash_init requires >= 2.9.10
+       if $pkg_config --exists "gnutls >= 2.9.10"; then
+            gnutls_hash="yes"
+       else
+           gnutls_hash="no"
+       fi
+
        # gnutls_rnd requires >= 2.11.0
        if $pkg_config --exists "gnutls >= 2.11.0"; then
            gnutls_rnd="yes"
@@ -2236,7 +2219,7 @@ if test "$gnutls" != "no"; then
            gnutls_gcrypt=no
            gnutls_nettle=yes
        elif $pkg_config --exists 'gnutls >= 2.12'; then
-           case $($pkg_config --libs --static gnutls) in
+           case `$pkg_config --libs --static gnutls` in
                *gcrypt*)
                    gnutls_gcrypt=yes
                    gnutls_nettle=no
@@ -2258,9 +2241,11 @@ if test "$gnutls" != "no"; then
        feature_not_found "gnutls" "Install gnutls devel"
     else
         gnutls="no"
+        gnutls_hash="no"
         gnutls_rnd="no"
     fi
 else
+    gnutls_hash="no"
     gnutls_rnd="no"
 fi
 
@@ -2295,7 +2280,7 @@ has_libgcrypt_config() {
 
     if test -n "$cross_prefix"
     then
-       host=$(libgcrypt-config --host)
+       host=`libgcrypt-config --host`
        if test "$host-" != $cross_prefix
        then
            return 1
@@ -2307,8 +2292,8 @@ has_libgcrypt_config() {
 
 if test "$gcrypt" != "no"; then
     if has_libgcrypt_config; then
-        gcrypt_cflags=$(libgcrypt-config --cflags)
-        gcrypt_libs=$(libgcrypt-config --libs)
+        gcrypt_cflags=`libgcrypt-config --cflags`
+        gcrypt_libs=`libgcrypt-config --libs`
         # Debian has remove -lgpg-error from libgcrypt-config
         # as it "spreads unnecessary dependencies" which in
         # turn breaks static builds...
@@ -2348,9 +2333,9 @@ fi
 
 if test "$nettle" != "no"; then
     if $pkg_config --exists "nettle"; then
-        nettle_cflags=$($pkg_config --cflags nettle)
-        nettle_libs=$($pkg_config --libs nettle)
-        nettle_version=$($pkg_config --modversion nettle)
+        nettle_cflags=`$pkg_config --cflags nettle`
+        nettle_libs=`$pkg_config --libs nettle`
+        nettle_version=`$pkg_config --modversion nettle`
         libs_softmmu="$nettle_libs $libs_softmmu"
         libs_tools="$nettle_libs $libs_tools"
         QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
@@ -2388,8 +2373,8 @@ tasn1=yes
 tasn1_cflags=""
 tasn1_libs=""
 if $pkg_config --exists "libtasn1"; then
-    tasn1_cflags=$($pkg_config --cflags libtasn1)
-    tasn1_libs=$($pkg_config --libs libtasn1)
+    tasn1_cflags=`$pkg_config --cflags libtasn1`
+    tasn1_libs=`$pkg_config --libs libtasn1`
 else
     tasn1=no
 fi
@@ -2408,25 +2393,20 @@ fi
 
 if test "$vte" != "no"; then
     if test "$gtkabi" = "3.0"; then
-      vteminversion="0.32.0"
-      if $pkg_config --exists "vte-2.91"; then
-        vtepackage="vte-2.91"
-      else
-        vtepackage="vte-2.90"
-      fi
+      vtepackage="vte-2.90"
+      vteversion="0.32.0"
     else
       vtepackage="vte"
-      vteminversion="0.24.0"
+      vteversion="0.24.0"
     fi
-    if $pkg_config --exists "$vtepackage >= $vteminversion"; then
-        vte_cflags=$($pkg_config --cflags $vtepackage)
-        vte_libs=$($pkg_config --libs $vtepackage)
-        vteversion=$($pkg_config --modversion $vtepackage)
+    if $pkg_config --exists "$vtepackage >= $vteversion"; then
+        vte_cflags=`$pkg_config --cflags $vtepackage`
+        vte_libs=`$pkg_config --libs $vtepackage`
         libs_softmmu="$vte_libs $libs_softmmu"
         vte="yes"
     elif test "$vte" = "yes"; then
         if test "$gtkabi" = "3.0"; then
-            feature_not_found "vte" "Install libvte-2.90/2.91 devel"
+            feature_not_found "vte" "Install libvte-2.90 devel"
         else
             feature_not_found "vte" "Install libvte devel"
         fi
@@ -2441,37 +2421,25 @@ fi
 # Look for sdl configuration program (pkg-config or sdl-config).  Try
 # sdl-config even without cross prefix, and favour pkg-config over sdl-config.
 
-if test "$sdlabi" = ""; then
-    if $pkg_config --exists "sdl"; then
-        sdlabi=1.2
-    elif $pkg_config --exists "sdl2"; then
-        sdlabi=2.0
-    else
-        sdlabi=1.2
-    fi
-fi
-
 if test $sdlabi = "2.0"; then
     sdl_config=$sdl2_config
     sdlname=sdl2
     sdlconfigname=sdl2_config
-elif test $sdlabi = "1.2"; then
+else
     sdlname=sdl
     sdlconfigname=sdl_config
-else
-    error_exit "Unknown sdlabi $sdlabi, must be 1.2 or 2.0"
 fi
 
-if test "$(basename $sdl_config)" != $sdlconfigname && ! has ${sdl_config}; then
+if test "`basename $sdl_config`" != $sdlconfigname && ! has ${sdl_config}; then
   sdl_config=$sdlconfigname
 fi
 
 if $pkg_config $sdlname --exists; then
   sdlconfig="$pkg_config $sdlname"
-  sdlversion=$($sdlconfig --modversion 2>/dev/null)
+  _sdlversion=`$sdlconfig --modversion 2>/dev/null | sed 's/[^0-9]//g'`
 elif has ${sdl_config}; then
   sdlconfig="$sdl_config"
-  sdlversion=$($sdlconfig --version)
+  _sdlversion=`$sdlconfig --version | sed 's/[^0-9]//g'`
 else
   if test "$sdl" = "yes" ; then
     feature_not_found "sdl" "Install SDL devel"
@@ -2489,14 +2457,14 @@ if test "$sdl" != "no" ; then
 #undef main /* We don't want SDL to override our main() */
 int main( void ) { return SDL_Init (SDL_INIT_VIDEO); }
 EOF
-  sdl_cflags=$($sdlconfig --cflags 2>/dev/null)
+  sdl_cflags=`$sdlconfig --cflags 2> /dev/null`
   if test "$static" = "yes" ; then
-    sdl_libs=$($sdlconfig --static-libs 2>/dev/null)
+    sdl_libs=`$sdlconfig --static-libs 2>/dev/null`
   else
-    sdl_libs=$($sdlconfig --libs 2>/dev/null)
+    sdl_libs=`$sdlconfig --libs 2> /dev/null`
   fi
   if compile_prog "$sdl_cflags" "$sdl_libs" ; then
-    if test $(echo $sdlversion | sed 's/[^0-9]//g') -lt 121 ; then
+    if test "$_sdlversion" -lt 121 ; then
       sdl_too_old=yes
     else
       sdl=yes
@@ -2505,8 +2473,8 @@ EOF
     # static link with sdl ? (note: sdl.pc's --static --libs is broken)
     if test "$sdl" = "yes" -a "$static" = "yes" ; then
       if test $? = 0 && echo $sdl_libs | grep -- -laa > /dev/null; then
-         sdl_libs="$sdl_libs $(aalib-config --static-libs 2>/dev/null)"
-         sdl_cflags="$sdl_cflags $(aalib-config --cflags 2>/dev/null)"
+         sdl_libs="$sdl_libs `aalib-config --static-libs 2>/dev/null`"
+         sdl_cflags="$sdl_cflags `aalib-config --cflags 2>/dev/null`"
       fi
       if compile_prog "$sdl_cflags" "$sdl_libs" ; then
        :
@@ -2623,8 +2591,8 @@ int main(void) {
 }
 EOF
   if $pkg_config libpng --exists; then
-    vnc_png_cflags=$($pkg_config libpng --cflags)
-    vnc_png_libs=$($pkg_config libpng --libs)
+    vnc_png_cflags=`$pkg_config libpng --cflags`
+    vnc_png_libs=`$pkg_config libpng --libs`
   else
     vnc_png_cflags=""
     vnc_png_libs="-lpng"
@@ -2818,7 +2786,7 @@ EOF
     fi
 }
 
-audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/,/ /g')
+audio_drv_list=`echo "$audio_drv_list" | sed -e 's/,/ /g'`
 for drv in $audio_drv_list; do
     case $drv in
     alsa)
@@ -2828,8 +2796,8 @@ for drv in $audio_drv_list; do
     ;;
 
     pa)
-    audio_drv_probe $drv pulse/pulseaudio.h "-lpulse" \
-        "pa_context_set_source_output_volume(NULL, 0, NULL, NULL, NULL); return 0;"
+    audio_drv_probe $drv pulse/mainloop.h "-lpulse" \
+        "pa_mainloop *m = 0; pa_mainloop_free (m); return 0;"
     libs_softmmu="-lpulse $libs_softmmu"
     audio_pt_int="yes"
     ;;
@@ -2930,8 +2898,8 @@ if test "$curl" != "no" ; then
 #include <curl/curl.h>
 int main(void) { curl_easy_init(); curl_multi_setopt(0, 0, 0); return 0; }
 EOF
-  curl_cflags=$($curlconfig --cflags 2>/dev/null)
-  curl_libs=$($curlconfig --libs 2>/dev/null)
+  curl_cflags=`$curlconfig --cflags 2>/dev/null`
+  curl_libs=`$curlconfig --libs 2>/dev/null`
   if compile_prog "$curl_cflags" "$curl_libs" ; then
     curl=yes
   else
@@ -2949,8 +2917,8 @@ if test "$bluez" != "no" ; then
 #include <bluetooth/bluetooth.h>
 int main(void) { return bt_error(0); }
 EOF
-  bluez_cflags=$($pkg_config --cflags bluez 2>/dev/null)
-  bluez_libs=$($pkg_config --libs bluez 2>/dev/null)
+  bluez_cflags=`$pkg_config --cflags bluez 2> /dev/null`
+  bluez_libs=`$pkg_config --libs bluez 2> /dev/null`
   if compile_prog "$bluez_cflags" "$bluez_libs" ; then
     bluez=yes
     libs_softmmu="$bluez_libs $libs_softmmu"
@@ -2973,8 +2941,8 @@ fi
 
 for i in $glib_modules; do
     if $pkg_config --atleast-version=$glib_req_ver $i; then
-        glib_cflags=$($pkg_config --cflags $i)
-        glib_libs=$($pkg_config --libs $i)
+        glib_cflags=`$pkg_config --cflags $i`
+        glib_libs=`$pkg_config --libs $i`
         CFLAGS="$glib_cflags $CFLAGS"
         LIBS="$glib_libs $LIBS"
         libs_qga="$glib_libs $libs_qga"
@@ -3063,8 +3031,8 @@ if test "$pixman" = "none"; then
   pixman_libs=
 elif test "$pixman" = "system"; then
   # pixman version has been checked above
-  pixman_cflags=$($pkg_config --cflags pixman-1)
-  pixman_libs=$($pkg_config --libs pixman-1)
+  pixman_cflags=`$pkg_config --cflags pixman-1`
+  pixman_libs=`$pkg_config --libs pixman-1`
 else
   if test ! -d ${source_path}/pixman/pixman; then
     error_exit "pixman >= 0.21.8 not present. Your options:" \
@@ -3124,7 +3092,6 @@ else
       if test "$found" = "no"; then
         LIBS="$pthread_lib $LIBS"
       fi
-      PTHREAD_LIB="$pthread_lib"
       break
     fi
   done
@@ -3181,8 +3148,8 @@ fi
 min_libssh2_version=1.2.8
 if test "$libssh2" != "no" ; then
   if $pkg_config --atleast-version=$min_libssh2_version libssh2; then
-    libssh2_cflags=$($pkg_config libssh2 --cflags)
-    libssh2_libs=$($pkg_config libssh2 --libs)
+    libssh2_cflags=`$pkg_config libssh2 --cflags`
+    libssh2_libs=`$pkg_config libssh2 --libs`
     libssh2=yes
   else
     if test "$libssh2" = "yes" ; then
@@ -3433,8 +3400,8 @@ fi
 if test "$glusterfs" != "no" ; then
   if $pkg_config --atleast-version=3 glusterfs-api; then
     glusterfs="yes"
-    glusterfs_cflags=$($pkg_config --cflags glusterfs-api)
-    glusterfs_libs=$($pkg_config --libs glusterfs-api)
+    glusterfs_cflags=`$pkg_config --cflags glusterfs-api`
+    glusterfs_libs=`$pkg_config --libs glusterfs-api`
     if $pkg_config --atleast-version=4 glusterfs-api; then
       glusterfs_xlator_opt="yes"
     fi
@@ -3814,8 +3781,8 @@ if compile_prog "" "" ; then
   epoll=yes
 fi
 
-# epoll_create1 is a later addition
-# so we must check separately for its presence
+# epoll_create1 and epoll_pwait are later additions
+# so we must check separately for their presence
 epoll_create1=no
 cat > $TMPC << EOF
 #include <sys/epoll.h>
@@ -3837,6 +3804,20 @@ if compile_prog "" "" ; then
   epoll_create1=yes
 fi
 
+epoll_pwait=no
+cat > $TMPC << EOF
+#include <sys/epoll.h>
+
+int main(void)
+{
+    epoll_pwait(0, 0, 0, 0, 0);
+    return 0;
+}
+EOF
+if compile_prog "" "" ; then
+  epoll_pwait=yes
+fi
+
 # check for sendfile support
 sendfile=no
 cat > $TMPC << EOF
@@ -4054,13 +4035,13 @@ fi
 
 if test "$mingw32" = "yes" -a "$guest_agent" != "no" -a "$vss_win32_sdk" != "no" ; then
   case "$vss_win32_sdk" in
-    "")   vss_win32_include="-isystem $source_path" ;;
+    "")   vss_win32_include="-I$source_path" ;;
     *\ *) # The SDK is installed in "Program Files" by default, but we cannot
           # handle path with spaces. So we symlink the headers into ".sdk/vss".
-          vss_win32_include="-isystem $source_path/.sdk/vss"
+          vss_win32_include="-I$source_path/.sdk/vss"
          symlink "$vss_win32_sdk/inc" "$source_path/.sdk/vss/inc"
          ;;
-    *)    vss_win32_include="-isystem $vss_win32_sdk"
+    *)    vss_win32_include="-I$vss_win32_sdk"
   esac
   cat > $TMPC << EOF
 #define __MIDL_user_allocate_free_DEFINED__
@@ -4192,6 +4173,24 @@ if compile_prog "" "" ; then
 fi
 
 ##########################################
+# check if we have usable SIGEV_THREAD_ID
+
+sigev_thread_id=no
+cat > $TMPC << EOF
+#include <signal.h>
+int main(void) {
+  struct sigevent ev;
+  ev.sigev_notify = SIGEV_THREAD_ID;
+  ev._sigev_un._tid = 0;
+  asm volatile("" : : "g"(&ev));
+  return 0;
+}
+EOF
+if compile_prog "" "" ; then
+    sigev_thread_id=yes
+fi
+
+##########################################
 # check if trace backend exists
 
 $python "$source_path/scripts/tracetool.py" "--backends=$trace_backends" --check-backends  > /dev/null 2> /dev/null
@@ -4209,12 +4208,12 @@ int main(void) { return 0; }
 EOF
   if compile_prog "" "" ; then
     if $pkg_config lttng-ust --exists; then
-      lttng_ust_libs=$($pkg_config --libs lttng-ust)
+      lttng_ust_libs=`$pkg_config --libs lttng-ust`
     else
       lttng_ust_libs="-llttng-ust"
     fi
     if $pkg_config liburcu-bp --exists; then
-      urcu_bp_libs=$($pkg_config --libs liburcu-bp)
+      urcu_bp_libs=`$pkg_config --libs liburcu-bp`
     else
       urcu_bp_libs="-lurcu-bp"
     fi
@@ -4511,38 +4510,6 @@ if compile_prog "" "" ; then
 fi
 
 ##########################################
-# check if rtnetlink.h exists and is useful
-have_rtnetlink=no
-cat > $TMPC << EOF
-#include <linux/rtnetlink.h>
-int main(void) {
-  return IFLA_PROTO_DOWN;
-}
-EOF
-if compile_prog "" "" ; then
-    have_rtnetlink=yes
-fi
-
-#################################################
-# Sparc implicitly links with --relax, which is
-# incompatible with -r, so --no-relax should be
-# given. It does no harm to give it on other
-# platforms too.
-
-# Note: the prototype is needed since QEMU_CFLAGS
-#       contains -Wmissing-prototypes
-cat > $TMPC << EOF
-extern int foo(void);
-int foo(void) { return 0; }
-EOF
-if ! compile_object ""; then
-  error_exit "Failed to compile object file for LD_REL_FLAGS test"
-fi
-if do_cc -nostdlib -Wl,-r -Wl,--no-relax -o $TMPMO $TMPO; then
-  LD_REL_FLAGS="-Wl,--no-relax"
-fi
-
-##########################################
 # End of CC checks
 # After here, no more $cc or $ld runs
 
@@ -4570,6 +4537,16 @@ if test "$libnfs" != "no" ; then
   fi
 fi
 
+# Disable zero malloc errors for official releases unless explicitly told to
+# enable/disable
+if test -z "$zero_malloc" ; then
+    if test "$z_version" = "50" ; then
+       zero_malloc="no"
+    else
+       zero_malloc="yes"
+    fi
+fi
+
 # Now we've finished running tests it's OK to add -Werror to the compiler flags
 if test "$werror" = "yes"; then
     QEMU_CFLAGS="-Werror $QEMU_CFLAGS"
@@ -4617,7 +4594,7 @@ if test "$softmmu" = yes ; then
       tools="$tools fsdev/virtfs-proxy-helper\$(EXESUF)"
     else
       if test "$virtfs" = yes; then
-        error_exit "VirtFS is supported only on Linux and requires libcap devel and libattr devel"
+        error_exit "VirtFS is supported only on Linux and requires libcap-devel and libattr-devel"
       fi
       virtfs=no
     fi
@@ -4676,10 +4653,10 @@ if test "$guest_agent_msi" = "yes"; then
   fi
 
   if test "$QEMU_GA_VERSION" = ""; then
-      QEMU_GA_VERSION=$(cat $source_path/VERSION)
+      QEMU_GA_VERSION=`cat $source_path/VERSION`
   fi
 
-  QEMU_GA_MSI_MINGW_DLL_PATH="-D Mingw_dlls=$($pkg_config --variable=prefix glib-2.0)/bin"
+  QEMU_GA_MSI_MINGW_DLL_PATH="-D Mingw_dlls=`$pkg_config --variable=prefix glib-2.0`/bin"
 
   case "$cpu" in
   x86_64)
@@ -4699,16 +4676,7 @@ roms=
 if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) -a \
         "$targetos" != "Darwin" -a "$targetos" != "SunOS" -a \
         "$softmmu" = yes ; then
-    # Different host OS linkers have different ideas about the name of the ELF
-    # emulation. Linux and OpenBSD use 'elf_i386'; FreeBSD uses the _fbsd
-    # variant; and Windows uses i386pe.
-    for emu in elf_i386 elf_i386_fbsd i386pe; do
-        if "$ld" -verbose 2>&1 | grep -q "^[[:space:]]*$emu[[:space:]]*$"; then
-            ld_i386_emulation="$emu"
-            roms="optionrom"
-            break
-        fi
-    done
+  roms="optionrom"
 fi
 if test "$cpu" = "ppc64" -a "$targetos" != "Darwin" ; then
   roms="$roms spapr-rtas"
@@ -4719,7 +4687,7 @@ if test "$cpu" = "s390x" ; then
 fi
 
 # Probe for the need for relocating the user-only binary.
-if ( [ "$linux_user" = yes ] || [ "$bsd_user" = yes ] ) && [ "$pie" = no ]; then
+if test "$pie" = "no" ; then
   textseg_addr=
   case "$cpu" in
     arm | i386 | ppc* | s390* | sparc* | x86_64 | x32)
@@ -4741,16 +4709,6 @@ EOF
       # In case ld does not support -Ttext-segment, edit the default linker
       # script via sed to set the .text start addr.  This is needed on FreeBSD
       # at least.
-      if ! $ld --verbose >/dev/null 2>&1; then
-        error_exit \
-            "We need to link the QEMU user mode binaries at a" \
-            "specific text address. Unfortunately your linker" \
-            "doesn't support either the -Ttext-segment option or" \
-            "printing the default linker script with --verbose." \
-            "If you don't want the user mode binaries, pass the" \
-            "--disable-user option to configure."
-      fi
-
       $ld --verbose | sed \
         -e '1,/==================================================/d' \
         -e '/==================================================/,$d' \
@@ -4761,27 +4719,21 @@ EOF
   fi
 fi
 
-echo_version() {
-    if test "$1" = "yes" ; then
-        echo "($2)"
-    fi
-}
-
 # prepend pixman and ftd flags after all config tests are done
 QEMU_CFLAGS="$pixman_cflags $fdt_cflags $QEMU_CFLAGS"
 libs_softmmu="$pixman_libs $libs_softmmu"
 
 echo "Install prefix    $prefix"
-echo "BIOS directory    $(eval echo $qemu_datadir)"
-echo "binary directory  $(eval echo $bindir)"
-echo "library directory $(eval echo $libdir)"
-echo "module directory  $(eval echo $qemu_moddir)"
-echo "libexec directory $(eval echo $libexecdir)"
-echo "include directory $(eval echo $includedir)"
-echo "config directory  $(eval echo $sysconfdir)"
+echo "BIOS directory    `eval echo $qemu_datadir`"
+echo "binary directory  `eval echo $bindir`"
+echo "library directory `eval echo $libdir`"
+echo "module directory  `eval echo $qemu_moddir`"
+echo "libexec directory `eval echo $libexecdir`"
+echo "include directory `eval echo $includedir`"
+echo "config directory  `eval echo $sysconfdir`"
 if test "$mingw32" = "no" ; then
-echo "local state directory   $(eval echo $local_statedir)"
-echo "Manual directory  $(eval echo $mandir)"
+echo "local state directory   `eval echo $local_statedir`"
+echo "Manual directory  `eval echo $mandir`"
 echo "ELF interp prefix $interp_prefix"
 else
 echo "local state directory   queried at runtime"
@@ -4816,18 +4768,22 @@ if test "$darwin" = "yes" ; then
     echo "Cocoa support     $cocoa"
 fi
 echo "pixman            $pixman"
-echo "SDL support       $sdl $(echo_version $sdl $sdlversion)"
-echo "GTK support       $gtk $(echo_version $gtk $gtk_version)"
+echo "SDL support       $sdl"
+echo "GTK support       $gtk"
 echo "GTK GL support    $gtk_gl"
-echo "VTE support       $vte $(echo_version $vte $vteversion)"
-echo "TLS priority      $tls_priority"
 echo "GNUTLS support    $gnutls"
+echo "GNUTLS hash       $gnutls_hash"
 echo "GNUTLS rnd        $gnutls_rnd"
 echo "libgcrypt         $gcrypt"
 echo "libgcrypt kdf     $gcrypt_kdf"
-echo "nettle            $nettle $(echo_version $nettle $nettle_version)"
+if test "$nettle" = "yes"; then
+    echo "nettle            $nettle ($nettle_version)"
+else
+    echo "nettle            $nettle"
+fi
 echo "nettle kdf        $nettle_kdf"
 echo "libtasn1          $tasn1"
+echo "VTE support       $vte"
 echo "curses support    $curses"
 echo "virgl support     $virglrenderer"
 echo "curl support      $curl"
@@ -4867,6 +4823,7 @@ echo "preadv support    $preadv"
 echo "fdatasync         $fdatasync"
 echo "madvise           $madvise"
 echo "posix_madvise     $posix_madvise"
+echo "sigev_thread_id   $sigev_thread_id"
 echo "uuid support      $uuid"
 echo "libcap-ng support $cap_ng"
 echo "vhost-net support $vhost_net"
@@ -4875,7 +4832,11 @@ echo "Trace backends    $trace_backends"
 if have_backend "simple"; then
 echo "Trace output file $trace_file-<pid>"
 fi
-echo "spice support     $spice $(echo_version $spice $spice_protocol_version/$spice_server_version)"
+if test "$spice" = "yes"; then
+echo "spice support     $spice ($spice_protocol_version/$spice_server_version)"
+else
+echo "spice support     $spice"
+fi
 echo "rbd support       $rbd"
 echo "xfsctl support    $xfs"
 echo "smartcard support $smartcard"
@@ -4954,7 +4915,7 @@ if test "$bigendian" = "yes" ; then
 fi
 if test "$mingw32" = "yes" ; then
   echo "CONFIG_WIN32=y" >> $config_host_mak
-  rc_version=$(cat $source_path/VERSION)
+  rc_version=`cat $source_path/VERSION`
   version_major=${rc_version%%.*}
   rc_version=${rc_version#*.}
   version_minor=${rc_version%%.*}
@@ -5030,7 +4991,7 @@ if test "$cap_ng" = "yes" ; then
 fi
 echo "CONFIG_AUDIO_DRIVERS=$audio_drv_list" >> $config_host_mak
 for drv in $audio_drv_list; do
-    def=CONFIG_$(echo $drv | LC_ALL=C tr '[a-z]' '[A-Z]')
+    def=CONFIG_`echo $drv | LC_ALL=C tr '[a-z]' '[A-Z]'`
     echo "$def=y" >> $config_host_mak
 done
 if test "$audio_pt_int" = "yes" ; then
@@ -5062,7 +5023,7 @@ fi
 if test "$xfs" = "yes" ; then
   echo "CONFIG_XFS=y" >> $config_host_mak
 fi
-qemu_version=$(head $source_path/VERSION)
+qemu_version=`head $source_path/VERSION`
 echo "VERSION=$qemu_version" >>$config_host_mak
 echo "PKGVERSION=$pkgversion" >>$config_host_mak
 echo "SRC_PATH=$source_path" >> $config_host_mak
@@ -5073,7 +5034,7 @@ fi
 if test "$modules" = "yes"; then
   # $shacmd can generate a hash started with digit, which the compiler doesn't
   # like as an symbol. So prefix it with an underscore
-  echo "CONFIG_STAMP=_$( (echo $qemu_version; echo $pkgversion; cat $0) | $shacmd - | cut -f1 -d\ )" >> $config_host_mak
+  echo "CONFIG_STAMP=_`(echo $qemu_version; echo $pkgversion; cat $0) | $shacmd - | cut -f1 -d\ `" >> $config_host_mak
   echo "CONFIG_MODULES=y" >> $config_host_mak
 fi
 if test "$sdl" = "yes" ; then
@@ -5138,6 +5099,9 @@ fi
 if test "$epoll_create1" = "yes" ; then
   echo "CONFIG_EPOLL_CREATE1=y" >> $config_host_mak
 fi
+if test "$epoll_pwait" = "yes" ; then
+  echo "CONFIG_EPOLL_PWAIT=y" >> $config_host_mak
+fi
 if test "$sendfile" = "yes" ; then
   echo "CONFIG_SENDFILE=y" >> $config_host_mak
 fi
@@ -5184,10 +5148,12 @@ if test "$gtk" = "yes" ; then
     echo "CONFIG_GTK_GL=y" >> $config_host_mak
   fi
 fi
-echo "CONFIG_TLS_PRIORITY=\"$tls_priority\"" >> $config_host_mak
 if test "$gnutls" = "yes" ; then
   echo "CONFIG_GNUTLS=y" >> $config_host_mak
 fi
+if test "$gnutls_hash" = "yes" ; then
+  echo "CONFIG_GNUTLS_HASH=y" >> $config_host_mak
+fi
 if test "$gnutls_rnd" = "yes" ; then
   echo "CONFIG_GNUTLS_RND=y" >> $config_host_mak
 fi
@@ -5279,6 +5245,9 @@ fi
 if test "$posix_madvise" = "yes" ; then
   echo "CONFIG_POSIX_MADVISE=y" >> $config_host_mak
 fi
+if test "$sigev_thread_id" = "yes" ; then
+  echo "CONFIG_SIGEV_THREAD_ID=y" >> $config_host_mak
+fi
 
 if test "$spice" = "yes" ; then
   echo "CONFIG_SPICE=y" >> $config_host_mak
@@ -5341,6 +5310,9 @@ if [ "$bsd" = "yes" ] ; then
   echo "CONFIG_BSD=y" >> $config_host_mak
 fi
 
+if test "$zero_malloc" = "yes" ; then
+  echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak
+fi
 if test "$localtime_r" = "yes" ; then
   echo "CONFIG_LOCALTIME_R=y" >> $config_host_mak
 fi
@@ -5474,10 +5446,6 @@ if test "$rdma" = "yes" ; then
   echo "CONFIG_RDMA=y" >> $config_host_mak
 fi
 
-if test "$have_rtnetlink" = "yes" ; then
-  echo "CONFIG_RTNETLINK=y" >> $config_host_mak
-fi
-
 # Hold two types of flag:
 #   CONFIG_THREAD_SETNAME_BYTHREAD  - we've got a way of setting the name on
 #                                     a thread we have a handle to
@@ -5523,7 +5491,6 @@ echo "OBJCC=$objcc" >> $config_host_mak
 echo "AR=$ar" >> $config_host_mak
 echo "ARFLAGS=$ARFLAGS" >> $config_host_mak
 echo "AS=$as" >> $config_host_mak
-echo "CCAS=$ccas" >> $config_host_mak
 echo "CPP=$cpp" >> $config_host_mak
 echo "OBJCOPY=$objcopy" >> $config_host_mak
 echo "LD=$ld" >> $config_host_mak
@@ -5547,11 +5514,8 @@ else
 fi
 echo "LDFLAGS=$LDFLAGS" >> $config_host_mak
 echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak
-echo "LD_REL_FLAGS=$LD_REL_FLAGS" >> $config_host_mak
-echo "LD_I386_EMULATION=$ld_i386_emulation" >> $config_host_mak
 echo "LIBS+=$LIBS" >> $config_host_mak
 echo "LIBS_TOOLS+=$libs_tools" >> $config_host_mak
-echo "PTHREAD_LIB=$PTHREAD_LIB" >> $config_host_mak
 echo "EXESUF=$EXESUF" >> $config_host_mak
 echo "DSOSUF=$DSOSUF" >> $config_host_mak
 echo "LDFLAGS_SHARED=$LDFLAGS_SHARED" >> $config_host_mak
@@ -5598,7 +5562,7 @@ fi
 for target in $target_list; do
 target_dir="$target"
 config_target_mak=$target_dir/config-target.mak
-target_name=$(echo $target | cut -d '-' -f 1)
+target_name=`echo $target | cut -d '-' -f 1`
 target_bigendian="no"
 
 case "$target_name" in
@@ -5638,7 +5602,7 @@ mkdir -p $target_dir
 echo "# Automatically generated by configure - do not modify" > $config_target_mak
 
 bflt="no"
-interp_prefix1=$(echo "$interp_prefix" | sed "s/%M/$target_name/g")
+interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_name/g"`
 gdb_xml_files=""
 
 TARGET_ARCH="$target_name"
@@ -5764,7 +5728,7 @@ upper() {
     echo "$@"| LC_ALL=C tr '[a-z]' '[A-Z]'
 }
 
-target_arch_name="$(upper $TARGET_ARCH)"
+target_arch_name="`upper $TARGET_ARCH`"
 echo "TARGET_$target_arch_name=y" >> $config_target_mak
 echo "TARGET_NAME=$target_name" >> $config_target_mak
 echo "TARGET_BASE_ARCH=$TARGET_BASE_ARCH" >> $config_target_mak
@@ -5980,11 +5944,11 @@ for bios_file in \
     $source_path/pc-bios/u-boot.* \
     $source_path/pc-bios/palcode-*
 do
-    FILES="$FILES pc-bios/$(basename $bios_file)"
+    FILES="$FILES pc-bios/`basename $bios_file`"
 done
-for test_file in $(find $source_path/tests/acpi-test-data -type f)
+for test_file in `find $source_path/tests/acpi-test-data -type f`
 do
-    FILES="$FILES tests/acpi-test-data$(echo $test_file | sed -e 's/.*acpi-test-data//')"
+    FILES="$FILES tests/acpi-test-data`echo $test_file | sed -e 's/.*acpi-test-data//'`"
 done
 mkdir -p $DIRS
 for f in $FILES ; do
@@ -5999,7 +5963,6 @@ for rom in seabios vgabios ; do
     echo "# Automatically generated by configure - do not modify" > $config_mak
     echo "SRC_PATH=$source_path/roms/$rom" >> $config_mak
     echo "AS=$as" >> $config_mak
-    echo "CCAS=$ccas" >> $config_mak
     echo "CC=$cc" >> $config_mak
     echo "BCC=bcc" >> $config_mak
     echo "CPP=$cpp" >> $config_mak
@@ -6008,11 +5971,6 @@ for rom in seabios vgabios ; do
     echo "LD=$ld" >> $config_mak
 done
 
-# set up tests data directory
-if [ ! -e tests/data ]; then
-    symlink "$source_path/tests/data" tests/data
-fi
-
 # set up qemu-iotests in this build directory
 iotests_common_env="tests/qemu-iotests/common.env"
 iotests_check="tests/qemu-iotests/check"
index 5ee9422..54cde17 100644 (file)
@@ -6,8 +6,8 @@
  * top-level directory.
  */
 
-#ifndef IVSHMEM_CLIENT_H
-#define IVSHMEM_CLIENT_H
+#ifndef _IVSHMEM_CLIENT_H_
+#define _IVSHMEM_CLIENT_H_
 
 /**
  * This file provides helper to implement an ivshmem client. It is used
@@ -209,4 +209,4 @@ ivshmem_client_search_peer(IvshmemClient *client, int64_t peer_id);
  */
 void ivshmem_client_dump(const IvshmemClient *client);
 
-#endif /* IVSHMEM_CLIENT_H */
+#endif /* _IVSHMEM_CLIENT_H_ */
index e2f295b..172db78 100644 (file)
@@ -7,9 +7,9 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "qemu/host-utils.h"
 #include "qemu/sockets.h"
 
+#include <sys/mman.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 
index 4af08e1..d37ca85 100644 (file)
@@ -6,8 +6,8 @@
  * top-level directory.
  */
 
-#ifndef IVSHMEM_SERVER_H
-#define IVSHMEM_SERVER_H
+#ifndef _IVSHMEM_SERVER_H_
+#define _IVSHMEM_SERVER_H_
 
 /**
  * The ivshmem server is a daemon that creates a unix socket in listen
@@ -163,4 +163,4 @@ ivshmem_server_search_peer(IvshmemServer *server, int64_t peer_id);
  */
 void ivshmem_server_dump(const IvshmemServer *server);
 
-#endif /* IVSHMEM_SERVER_H */
+#endif /* _IVSHMEM_SERVER_H_ */
index 0cb4ae6..1b1731c 100644 (file)
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "sysemu/cpus.h"
-#include "exec/exec-all.h"
 #include "exec/memory-internal.h"
 
 bool exit_request;
 CPUState *tcg_current_cpu;
 
-/* exit the current TB, but without causing any exception to be raised */
-void cpu_loop_exit_noexc(CPUState *cpu)
+/* exit the current TB from a signal handler. The host registers are
+   restored in a state compatible with the CPU emulator
+ */
+#if defined(CONFIG_SOFTMMU)
+void cpu_resume_from_signal(CPUState *cpu, void *puc)
 {
     /* XXX: restore cpu registers saved in host registers */
 
@@ -35,7 +37,6 @@ void cpu_loop_exit_noexc(CPUState *cpu)
     siglongjmp(cpu->jmp_env, 1);
 }
 
-#if defined(CONFIG_SOFTMMU)
 void cpu_reloading_memory_map(void)
 {
     if (qemu_in_vcpu_thread()) {
@@ -67,6 +68,7 @@ void cpu_reloading_memory_map(void)
 
 void cpu_loop_exit(CPUState *cpu)
 {
+    cpu->current_tb = NULL;
     siglongjmp(cpu->jmp_env, 1);
 }
 
@@ -75,5 +77,6 @@ void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc)
     if (pc) {
         cpu_restore_state(cpu, pc);
     }
+    cpu->current_tb = NULL;
     siglongjmp(cpu->jmp_env, 1);
 }
index 5d9710a..bbfcbfb 100644 (file)
@@ -20,7 +20,6 @@
 #include "cpu.h"
 #include "trace.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg.h"
 #include "qemu/atomic.h"
 #include "sysemu/qtest.h"
@@ -137,9 +136,7 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu)
 static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
 {
     CPUArchState *env = cpu->env_ptr;
-    uintptr_t ret;
-    TranslationBlock *last_tb;
-    int tb_exit;
+    uintptr_t next_tb;
     uint8_t *tb_ptr = itb->tc_ptr;
 
     qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,
@@ -163,125 +160,118 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
 #endif /* DEBUG_DISAS */
 
     cpu->can_do_io = !use_icount;
-    ret = tcg_qemu_tb_exec(env, tb_ptr);
+    next_tb = tcg_qemu_tb_exec(env, tb_ptr);
     cpu->can_do_io = 1;
-    last_tb = (TranslationBlock *)(ret & ~TB_EXIT_MASK);
-    tb_exit = ret & TB_EXIT_MASK;
-    trace_exec_tb_exit(last_tb, tb_exit);
+    trace_exec_tb_exit((void *) (next_tb & ~TB_EXIT_MASK),
+                       next_tb & TB_EXIT_MASK);
 
-    if (tb_exit > TB_EXIT_IDX1) {
+    if ((next_tb & TB_EXIT_MASK) > TB_EXIT_IDX1) {
         /* We didn't start executing this TB (eg because the instruction
          * counter hit zero); we must restore the guest PC to the address
          * of the start of the TB.
          */
         CPUClass *cc = CPU_GET_CLASS(cpu);
-        qemu_log_mask_and_addr(CPU_LOG_EXEC, last_tb->pc,
+        TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
+        qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,
                                "Stopped execution of TB chain before %p ["
                                TARGET_FMT_lx "] %s\n",
-                               last_tb->tc_ptr, last_tb->pc,
-                               lookup_symbol(last_tb->pc));
+                               itb->tc_ptr, itb->pc, lookup_symbol(itb->pc));
         if (cc->synchronize_from_tb) {
-            cc->synchronize_from_tb(cpu, last_tb);
+            cc->synchronize_from_tb(cpu, tb);
         } else {
             assert(cc->set_pc);
-            cc->set_pc(cpu, last_tb->pc);
+            cc->set_pc(cpu, tb->pc);
         }
     }
-    if (tb_exit == TB_EXIT_REQUESTED) {
+    if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
         /* We were asked to stop executing TBs (probably a pending
          * interrupt. We've now stopped, so clear the flag.
          */
         cpu->tcg_exit_req = 0;
     }
-    return ret;
+    return next_tb;
 }
 
-#ifndef CONFIG_USER_ONLY
 /* Execute the code without caching the generated code. An interpreter
    could be used if available. */
 static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
                              TranslationBlock *orig_tb, bool ignore_icount)
 {
     TranslationBlock *tb;
-    bool old_tb_flushed;
 
     /* Should never happen.
        We only end up here when an existing TB is too long.  */
     if (max_cycles > CF_COUNT_MASK)
         max_cycles = CF_COUNT_MASK;
 
-    old_tb_flushed = cpu->tb_flushed;
-    cpu->tb_flushed = false;
     tb = tb_gen_code(cpu, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
                      max_cycles | CF_NOCACHE
                          | (ignore_icount ? CF_IGNORE_ICOUNT : 0));
-    tb->orig_tb = cpu->tb_flushed ? NULL : orig_tb;
-    cpu->tb_flushed |= old_tb_flushed;
+    tb->orig_tb = tcg_ctx.tb_ctx.tb_invalidated_flag ? NULL : orig_tb;
+    cpu->current_tb = tb;
     /* execute the generated code */
     trace_exec_tb_nocache(tb, tb->pc);
     cpu_tb_exec(cpu, tb);
+    cpu->current_tb = NULL;
     tb_phys_invalidate(tb, -1);
     tb_free(tb);
 }
-#endif
 
-struct tb_desc {
-    target_ulong pc;
-    target_ulong cs_base;
-    CPUArchState *env;
-    tb_page_addr_t phys_page1;
-    uint32_t flags;
-};
-
-static bool tb_cmp(const void *p, const void *d)
+static TranslationBlock *tb_find_physical(CPUState *cpu,
+                                          target_ulong pc,
+                                          target_ulong cs_base,
+                                          uint64_t flags)
 {
-    const TranslationBlock *tb = p;
-    const struct tb_desc *desc = d;
-
-    if (tb->pc == desc->pc &&
-        tb->page_addr[0] == desc->phys_page1 &&
-        tb->cs_base == desc->cs_base &&
-        tb->flags == desc->flags) {
-        /* check next page if needed */
-        if (tb->page_addr[1] == -1) {
-            return true;
-        } else {
-            tb_page_addr_t phys_page2;
-            target_ulong virt_page2;
-
-            virt_page2 = (desc->pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
-            phys_page2 = get_page_addr_code(desc->env, virt_page2);
-            if (tb->page_addr[1] == phys_page2) {
-                return true;
+    CPUArchState *env = (CPUArchState *)cpu->env_ptr;
+    TranslationBlock *tb, **ptb1;
+    unsigned int h;
+    tb_page_addr_t phys_pc, phys_page1;
+    target_ulong virt_page2;
+
+    tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
+
+    /* find translated block using physical mappings */
+    phys_pc = get_page_addr_code(env, pc);
+    phys_page1 = phys_pc & TARGET_PAGE_MASK;
+    h = tb_phys_hash_func(phys_pc);
+    ptb1 = &tcg_ctx.tb_ctx.tb_phys_hash[h];
+    for(;;) {
+        tb = *ptb1;
+        if (!tb) {
+            return NULL;
+        }
+        if (tb->pc == pc &&
+            tb->page_addr[0] == phys_page1 &&
+            tb->cs_base == cs_base &&
+            tb->flags == flags) {
+            /* check next page if needed */
+            if (tb->page_addr[1] != -1) {
+                tb_page_addr_t phys_page2;
+
+                virt_page2 = (pc & TARGET_PAGE_MASK) +
+                    TARGET_PAGE_SIZE;
+                phys_page2 = get_page_addr_code(env, virt_page2);
+                if (tb->page_addr[1] == phys_page2) {
+                    break;
+                }
+            } else {
+                break;
             }
         }
+        ptb1 = &tb->phys_hash_next;
     }
-    return false;
-}
 
-static TranslationBlock *tb_find_physical(CPUState *cpu,
-                                          target_ulong pc,
-                                          target_ulong cs_base,
-                                          uint32_t flags)
-{
-    tb_page_addr_t phys_pc;
-    struct tb_desc desc;
-    uint32_t h;
-
-    desc.env = (CPUArchState *)cpu->env_ptr;
-    desc.cs_base = cs_base;
-    desc.flags = flags;
-    desc.pc = pc;
-    phys_pc = get_page_addr_code(desc.env, pc);
-    desc.phys_page1 = phys_pc & TARGET_PAGE_MASK;
-    h = tb_hash_func(phys_pc, pc, flags);
-    return qht_lookup(&tcg_ctx.tb_ctx.htable, tb_cmp, &desc, h);
+    /* Move the TB to the head of the list */
+    *ptb1 = tb->phys_hash_next;
+    tb->phys_hash_next = tcg_ctx.tb_ctx.tb_phys_hash[h];
+    tcg_ctx.tb_ctx.tb_phys_hash[h] = tb;
+    return tb;
 }
 
 static TranslationBlock *tb_find_slow(CPUState *cpu,
                                       target_ulong pc,
                                       target_ulong cs_base,
-                                      uint32_t flags)
+                                      uint64_t flags)
 {
     TranslationBlock *tb;
 
@@ -319,72 +309,26 @@ found:
     return tb;
 }
 
-static inline TranslationBlock *tb_find_fast(CPUState *cpu,
-                                             TranslationBlock **last_tb,
-                                             int tb_exit)
+static inline TranslationBlock *tb_find_fast(CPUState *cpu)
 {
     CPUArchState *env = (CPUArchState *)cpu->env_ptr;
     TranslationBlock *tb;
     target_ulong cs_base, pc;
-    uint32_t flags;
+    int flags;
 
     /* we record a subset of the CPU state. It will
        always be the same before a given translated block
        is executed. */
     cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
-    tb_lock();
     tb = cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
     if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
                  tb->flags != flags)) {
         tb = tb_find_slow(cpu, pc, cs_base, flags);
     }
-    if (cpu->tb_flushed) {
-        /* Ensure that no TB jump will be modified as the
-         * translation buffer has been flushed.
-         */
-        *last_tb = NULL;
-        cpu->tb_flushed = false;
-    }
-#ifndef CONFIG_USER_ONLY
-    /* We don't take care of direct jumps when address mapping changes in
-     * system emulation. So it's not safe to make a direct jump to a TB
-     * spanning two pages because the mapping for the second page can change.
-     */
-    if (tb->page_addr[1] != -1) {
-        *last_tb = NULL;
-    }
-#endif
-    /* See if we can patch the calling TB. */
-    if (*last_tb && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
-        tb_add_jump(*last_tb, tb_exit, tb);
-    }
-    tb_unlock();
     return tb;
 }
 
-static inline bool cpu_handle_halt(CPUState *cpu)
-{
-    if (cpu->halted) {
-#if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
-        if ((cpu->interrupt_request & CPU_INTERRUPT_POLL)
-            && replay_interrupt()) {
-            X86CPU *x86_cpu = X86_CPU(cpu);
-            apic_poll_irq(x86_cpu->apic_state);
-            cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
-        }
-#endif
-        if (!cpu_has_work(cpu)) {
-            current_cpu = NULL;
-            return true;
-        }
-
-        cpu->halted = 0;
-    }
-
-    return false;
-}
-
-static inline void cpu_handle_debug_exception(CPUState *cpu)
+static void cpu_handle_debug_exception(CPUState *cpu)
 {
     CPUClass *cc = CPU_GET_CLASS(cpu);
     CPUWatchpoint *wp;
@@ -398,197 +342,37 @@ static inline void cpu_handle_debug_exception(CPUState *cpu)
     cc->debug_excp_handler(cpu);
 }
 
-static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
-{
-    if (cpu->exception_index >= 0) {
-        if (cpu->exception_index >= EXCP_INTERRUPT) {
-            /* exit request from the cpu execution loop */
-            *ret = cpu->exception_index;
-            if (*ret == EXCP_DEBUG) {
-                cpu_handle_debug_exception(cpu);
-            }
-            cpu->exception_index = -1;
-            return true;
-        } else {
-#if defined(CONFIG_USER_ONLY)
-            /* if user mode only, we simulate a fake exception
-               which will be handled outside the cpu execution
-               loop */
-#if defined(TARGET_I386)
-            CPUClass *cc = CPU_GET_CLASS(cpu);
-            cc->do_interrupt(cpu);
-#endif
-            *ret = cpu->exception_index;
-            cpu->exception_index = -1;
-            return true;
-#else
-            if (replay_exception()) {
-                CPUClass *cc = CPU_GET_CLASS(cpu);
-                cc->do_interrupt(cpu);
-                cpu->exception_index = -1;
-            } else if (!replay_has_interrupt()) {
-                /* give a chance to iothread in replay mode */
-                *ret = EXCP_INTERRUPT;
-                return true;
-            }
-#endif
-        }
-#ifndef CONFIG_USER_ONLY
-    } else if (replay_has_exception()
-               && cpu->icount_decr.u16.low + cpu->icount_extra == 0) {
-        /* try to cause an exception pending in the log */
-        TranslationBlock *last_tb = NULL; /* Avoid chaining TBs */
-        cpu_exec_nocache(cpu, 1, tb_find_fast(cpu, &last_tb, 0), true);
-        *ret = -1;
-        return true;
-#endif
-    }
-
-    return false;
-}
-
-static inline void cpu_handle_interrupt(CPUState *cpu,
-                                        TranslationBlock **last_tb)
-{
-    CPUClass *cc = CPU_GET_CLASS(cpu);
-    int interrupt_request = cpu->interrupt_request;
-
-    if (unlikely(interrupt_request)) {
-        if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
-            /* Mask out external interrupts for this step. */
-            interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
-        }
-        if (interrupt_request & CPU_INTERRUPT_DEBUG) {
-            cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
-            cpu->exception_index = EXCP_DEBUG;
-            cpu_loop_exit(cpu);
-        }
-        if (replay_mode == REPLAY_MODE_PLAY && !replay_has_interrupt()) {
-            /* Do nothing */
-        } else if (interrupt_request & CPU_INTERRUPT_HALT) {
-            replay_interrupt();
-            cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
-            cpu->halted = 1;
-            cpu->exception_index = EXCP_HLT;
-            cpu_loop_exit(cpu);
-        }
-#if defined(TARGET_I386)
-        else if (interrupt_request & CPU_INTERRUPT_INIT) {
-            X86CPU *x86_cpu = X86_CPU(cpu);
-            CPUArchState *env = &x86_cpu->env;
-            replay_interrupt();
-            cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0);
-            do_cpu_init(x86_cpu);
-            cpu->exception_index = EXCP_HALTED;
-            cpu_loop_exit(cpu);
-        }
-#else
-        else if (interrupt_request & CPU_INTERRUPT_RESET) {
-            replay_interrupt();
-            cpu_reset(cpu);
-            cpu_loop_exit(cpu);
-        }
-#endif
-        /* The target hook has 3 exit conditions:
-           False when the interrupt isn't processed,
-           True when it is, and we should restart on a new TB,
-           and via longjmp via cpu_loop_exit.  */
-        else {
-            replay_interrupt();
-            if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {
-                *last_tb = NULL;
-            }
-            /* The target hook may have updated the 'cpu->interrupt_request';
-             * reload the 'interrupt_request' value */
-            interrupt_request = cpu->interrupt_request;
-        }
-        if (interrupt_request & CPU_INTERRUPT_EXITTB) {
-            cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
-            /* ensure that no TB jump will be modified as
-               the program flow was changed */
-            *last_tb = NULL;
-        }
-    }
-    if (unlikely(cpu->exit_request || replay_has_interrupt())) {
-        cpu->exit_request = 0;
-        cpu->exception_index = EXCP_INTERRUPT;
-        cpu_loop_exit(cpu);
-    }
-}
-
-static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
-                                    TranslationBlock **last_tb, int *tb_exit,
-                                    SyncClocks *sc)
-{
-    uintptr_t ret;
-
-    if (unlikely(cpu->exit_request)) {
-        return;
-    }
-
-    trace_exec_tb(tb, tb->pc);
-    ret = cpu_tb_exec(cpu, tb);
-    *last_tb = (TranslationBlock *)(ret & ~TB_EXIT_MASK);
-    *tb_exit = ret & TB_EXIT_MASK;
-    switch (*tb_exit) {
-    case TB_EXIT_REQUESTED:
-        /* Something asked us to stop executing
-         * chained TBs; just continue round the main
-         * loop. Whatever requested the exit will also
-         * have set something else (eg exit_request or
-         * interrupt_request) which we will handle
-         * next time around the loop.  But we need to
-         * ensure the tcg_exit_req read in generated code
-         * comes before the next read of cpu->exit_request
-         * or cpu->interrupt_request.
-         */
-        smp_rmb();
-        *last_tb = NULL;
-        break;
-    case TB_EXIT_ICOUNT_EXPIRED:
-    {
-        /* Instruction counter expired.  */
-#ifdef CONFIG_USER_ONLY
-        abort();
-#else
-        int insns_left = cpu->icount_decr.u32;
-        if (cpu->icount_extra && insns_left >= 0) {
-            /* Refill decrementer and continue execution.  */
-            cpu->icount_extra += insns_left;
-            insns_left = MIN(0xffff, cpu->icount_extra);
-            cpu->icount_extra -= insns_left;
-            cpu->icount_decr.u16.low = insns_left;
-        } else {
-            if (insns_left > 0) {
-                /* Execute remaining instructions.  */
-                cpu_exec_nocache(cpu, insns_left, *last_tb, false);
-                align_clocks(sc, cpu);
-            }
-            cpu->exception_index = EXCP_INTERRUPT;
-            *last_tb = NULL;
-            cpu_loop_exit(cpu);
-        }
-        break;
-#endif
-    }
-    default:
-        break;
-    }
-}
-
 /* main execution loop */
 
 int cpu_exec(CPUState *cpu)
 {
     CPUClass *cc = CPU_GET_CLASS(cpu);
-    int ret;
+#ifdef TARGET_I386
+    X86CPU *x86_cpu = X86_CPU(cpu);
+    CPUArchState *env = &x86_cpu->env;
+#endif
+    int ret, interrupt_request;
+    TranslationBlock *tb;
+    uintptr_t next_tb;
     SyncClocks sc;
 
     /* replay_interrupt may need current_cpu */
     current_cpu = cpu;
 
-    if (cpu_handle_halt(cpu)) {
-        return EXCP_HALTED;
+    if (cpu->halted) {
+#if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
+        if ((cpu->interrupt_request & CPU_INTERRUPT_POLL)
+            && replay_interrupt()) {
+            apic_poll_irq(x86_cpu->apic_state);
+            cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
+        }
+#endif
+        if (!cpu_has_work(cpu)) {
+            current_cpu = NULL;
+            return EXCP_HALTED;
+        }
+
+        cpu->halted = 0;
     }
 
     atomic_mb_set(&tcg_current_cpu, cpu);
@@ -607,25 +391,185 @@ int cpu_exec(CPUState *cpu)
      */
     init_delay_params(&sc, cpu);
 
+    /* prepare setjmp context for exception handling */
     for(;;) {
-        /* prepare setjmp context for exception handling */
         if (sigsetjmp(cpu->jmp_env, 0) == 0) {
-            TranslationBlock *tb, *last_tb = NULL;
-            int tb_exit = 0;
-
             /* if an exception is pending, we execute it here */
-            if (cpu_handle_exception(cpu, &ret)) {
+            if (cpu->exception_index >= 0) {
+                if (cpu->exception_index >= EXCP_INTERRUPT) {
+                    /* exit request from the cpu execution loop */
+                    ret = cpu->exception_index;
+                    if (ret == EXCP_DEBUG) {
+                        cpu_handle_debug_exception(cpu);
+                    }
+                    cpu->exception_index = -1;
+                    break;
+                } else {
+#if defined(CONFIG_USER_ONLY)
+                    /* if user mode only, we simulate a fake exception
+                       which will be handled outside the cpu execution
+                       loop */
+#if defined(TARGET_I386)
+                    cc->do_interrupt(cpu);
+#endif
+                    ret = cpu->exception_index;
+                    cpu->exception_index = -1;
+                    break;
+#else
+                    if (replay_exception()) {
+                        cc->do_interrupt(cpu);
+                        cpu->exception_index = -1;
+                    } else if (!replay_has_interrupt()) {
+                        /* give a chance to iothread in replay mode */
+                        ret = EXCP_INTERRUPT;
+                        break;
+                    }
+#endif
+                }
+            } else if (replay_has_exception()
+                       && cpu->icount_decr.u16.low + cpu->icount_extra == 0) {
+                /* try to cause an exception pending in the log */
+                cpu_exec_nocache(cpu, 1, tb_find_fast(cpu), true);
+                ret = -1;
                 break;
             }
 
-            cpu->tb_flushed = false; /* reset before first TB lookup */
+            next_tb = 0; /* force lookup of first TB */
             for(;;) {
-                cpu_handle_interrupt(cpu, &last_tb);
-                tb = tb_find_fast(cpu, &last_tb, tb_exit);
-                cpu_loop_exec_tb(cpu, tb, &last_tb, &tb_exit, &sc);
+                interrupt_request = cpu->interrupt_request;
+                if (unlikely(interrupt_request)) {
+                    if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
+                        /* Mask out external interrupts for this step. */
+                        interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
+                    }
+                    if (interrupt_request & CPU_INTERRUPT_DEBUG) {
+                        cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
+                        cpu->exception_index = EXCP_DEBUG;
+                        cpu_loop_exit(cpu);
+                    }
+                    if (replay_mode == REPLAY_MODE_PLAY
+                        && !replay_has_interrupt()) {
+                        /* Do nothing */
+                    } else if (interrupt_request & CPU_INTERRUPT_HALT) {
+                        replay_interrupt();
+                        cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
+                        cpu->halted = 1;
+                        cpu->exception_index = EXCP_HLT;
+                        cpu_loop_exit(cpu);
+                    }
+#if defined(TARGET_I386)
+                    else if (interrupt_request & CPU_INTERRUPT_INIT) {
+                        replay_interrupt();
+                        cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0);
+                        do_cpu_init(x86_cpu);
+                        cpu->exception_index = EXCP_HALTED;
+                        cpu_loop_exit(cpu);
+                    }
+#else
+                    else if (interrupt_request & CPU_INTERRUPT_RESET) {
+                        replay_interrupt();
+                        cpu_reset(cpu);
+                        cpu_loop_exit(cpu);
+                    }
+#endif
+                    /* The target hook has 3 exit conditions:
+                       False when the interrupt isn't processed,
+                       True when it is, and we should restart on a new TB,
+                       and via longjmp via cpu_loop_exit.  */
+                    else {
+                        replay_interrupt();
+                        if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {
+                            next_tb = 0;
+                        }
+                    }
+                    /* Don't use the cached interrupt_request value,
+                       do_interrupt may have updated the EXITTB flag. */
+                    if (cpu->interrupt_request & CPU_INTERRUPT_EXITTB) {
+                        cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
+                        /* ensure that no TB jump will be modified as
+                           the program flow was changed */
+                        next_tb = 0;
+                    }
+                }
+                if (unlikely(cpu->exit_request
+                             || replay_has_interrupt())) {
+                    cpu->exit_request = 0;
+                    cpu->exception_index = EXCP_INTERRUPT;
+                    cpu_loop_exit(cpu);
+                }
+                tb_lock();
+                tb = tb_find_fast(cpu);
+                /* Note: we do it here to avoid a gcc bug on Mac OS X when
+                   doing it in tb_find_slow */
+                if (tcg_ctx.tb_ctx.tb_invalidated_flag) {
+                    /* as some TB could have been invalidated because
+                       of memory exceptions while generating the code, we
+                       must recompute the hash index here */
+                    next_tb = 0;
+                    tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
+                }
+                /* see if we can patch the calling TB. When the TB
+                   spans two pages, we cannot safely do a direct
+                   jump. */
+                if (next_tb != 0 && tb->page_addr[1] == -1
+                    && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
+                    tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
+                                next_tb & TB_EXIT_MASK, tb);
+                }
+                tb_unlock();
+                if (likely(!cpu->exit_request)) {
+                    trace_exec_tb(tb, tb->pc);
+                    /* execute the generated code */
+                    cpu->current_tb = tb;
+                    next_tb = cpu_tb_exec(cpu, tb);
+                    cpu->current_tb = NULL;
+                    switch (next_tb & TB_EXIT_MASK) {
+                    case TB_EXIT_REQUESTED:
+                        /* Something asked us to stop executing
+                         * chained TBs; just continue round the main
+                         * loop. Whatever requested the exit will also
+                         * have set something else (eg exit_request or
+                         * interrupt_request) which we will handle
+                         * next time around the loop.  But we need to
+                         * ensure the tcg_exit_req read in generated code
+                         * comes before the next read of cpu->exit_request
+                         * or cpu->interrupt_request.
+                         */
+                        smp_rmb();
+                        next_tb = 0;
+                        break;
+                    case TB_EXIT_ICOUNT_EXPIRED:
+                    {
+                        /* Instruction counter expired.  */
+                        int insns_left = cpu->icount_decr.u32;
+                        if (cpu->icount_extra && insns_left >= 0) {
+                            /* Refill decrementer and continue execution.  */
+                            cpu->icount_extra += insns_left;
+                            insns_left = MIN(0xffff, cpu->icount_extra);
+                            cpu->icount_extra -= insns_left;
+                            cpu->icount_decr.u16.low = insns_left;
+                        } else {
+                            if (insns_left > 0) {
+                                /* Execute remaining instructions.  */
+                                tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
+                                cpu_exec_nocache(cpu, insns_left, tb, false);
+                                align_clocks(&sc, cpu);
+                            }
+                            cpu->exception_index = EXCP_INTERRUPT;
+                            next_tb = 0;
+                            cpu_loop_exit(cpu);
+                        }
+                        break;
+                    }
+                    default:
+                        break;
+                    }
+                }
                 /* Try to align the host and virtual clocks
                    if the guest is in advance */
                 align_clocks(&sc, cpu);
+                /* reset soft MMU for next block (it can currently
+                   only be set by a memory fault) */
             } /* for(;;) */
         } else {
 #if defined(__clang__) || !QEMU_GNUC_PREREQ(4, 6)
@@ -635,10 +579,18 @@ int cpu_exec(CPUState *cpu)
              * Newer versions of gcc would complain about this code (-Wclobbered). */
             cpu = current_cpu;
             cc = CPU_GET_CLASS(cpu);
+#ifdef TARGET_I386
+            x86_cpu = X86_CPU(cpu);
+            env = &x86_cpu->env;
+#endif
 #else /* buggy compiler */
             /* Assert that the compiler does not smash local variables. */
             g_assert(cpu == current_cpu);
             g_assert(cc == CPU_GET_CLASS(cpu));
+#ifdef TARGET_I386
+            g_assert(x86_cpu == X86_CPU(cpu));
+            g_assert(env == &x86_cpu->env);
+#endif
 #endif /* buggy compiler */
             cpu->can_do_io = 1;
             tb_lock_reset();
diff --git a/cpus.c b/cpus.c
index 84c3520..cbeb1f6 100644 (file)
--- a/cpus.c
+++ b/cpus.c
@@ -24,8 +24,7 @@
 
 /* Needed early for CONFIG_BSD etc. */
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
+
 #include "monitor/monitor.h"
 #include "qapi/qmp/qerror.h"
 #include "qemu/error-report.h"
@@ -35,7 +34,6 @@
 #include "sysemu/dma.h"
 #include "sysemu/kvm.h"
 #include "qmp-commands.h"
-#include "exec/exec-all.h"
 
 #include "qemu/thread.h"
 #include "sysemu/cpus.h"
@@ -249,13 +247,13 @@ int64_t cpu_get_clock(void)
 void cpu_enable_ticks(void)
 {
     /* Here, the really thing protected by seqlock is cpu_clock_offset. */
-    seqlock_write_begin(&timers_state.vm_clock_seqlock);
+    seqlock_write_lock(&timers_state.vm_clock_seqlock);
     if (!timers_state.cpu_ticks_enabled) {
         timers_state.cpu_ticks_offset -= cpu_get_host_ticks();
         timers_state.cpu_clock_offset -= get_clock();
         timers_state.cpu_ticks_enabled = 1;
     }
-    seqlock_write_end(&timers_state.vm_clock_seqlock);
+    seqlock_write_unlock(&timers_state.vm_clock_seqlock);
 }
 
 /* disable cpu_get_ticks() : the clock is stopped. You must not call
@@ -265,13 +263,13 @@ void cpu_enable_ticks(void)
 void cpu_disable_ticks(void)
 {
     /* Here, the really thing protected by seqlock is cpu_clock_offset. */
-    seqlock_write_begin(&timers_state.vm_clock_seqlock);
+    seqlock_write_lock(&timers_state.vm_clock_seqlock);
     if (timers_state.cpu_ticks_enabled) {
         timers_state.cpu_ticks_offset += cpu_get_host_ticks();
         timers_state.cpu_clock_offset = cpu_get_clock_locked();
         timers_state.cpu_ticks_enabled = 0;
     }
-    seqlock_write_end(&timers_state.vm_clock_seqlock);
+    seqlock_write_unlock(&timers_state.vm_clock_seqlock);
 }
 
 /* Correlation between real and virtual time is always going to be
@@ -294,7 +292,7 @@ static void icount_adjust(void)
         return;
     }
 
-    seqlock_write_begin(&timers_state.vm_clock_seqlock);
+    seqlock_write_lock(&timers_state.vm_clock_seqlock);
     cur_time = cpu_get_clock_locked();
     cur_icount = cpu_get_icount_locked();
 
@@ -315,7 +313,7 @@ static void icount_adjust(void)
     last_delta = delta;
     timers_state.qemu_icount_bias = cur_icount
                               - (timers_state.qemu_icount << icount_time_shift);
-    seqlock_write_end(&timers_state.vm_clock_seqlock);
+    seqlock_write_unlock(&timers_state.vm_clock_seqlock);
 }
 
 static void icount_adjust_rt(void *opaque)
@@ -355,7 +353,7 @@ static void icount_warp_rt(void)
         return;
     }
 
-    seqlock_write_begin(&timers_state.vm_clock_seqlock);
+    seqlock_write_lock(&timers_state.vm_clock_seqlock);
     if (runstate_is_running()) {
         int64_t clock = REPLAY_CLOCK(REPLAY_CLOCK_VIRTUAL_RT,
                                      cpu_get_clock_locked());
@@ -374,7 +372,7 @@ static void icount_warp_rt(void)
         timers_state.qemu_icount_bias += warp_delta;
     }
     vm_clock_warp_start = -1;
-    seqlock_write_end(&timers_state.vm_clock_seqlock);
+    seqlock_write_unlock(&timers_state.vm_clock_seqlock);
 
     if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {
         qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
@@ -399,9 +397,9 @@ void qtest_clock_warp(int64_t dest)
         int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
         int64_t warp = qemu_soonest_timeout(dest - clock, deadline);
 
-        seqlock_write_begin(&timers_state.vm_clock_seqlock);
+        seqlock_write_lock(&timers_state.vm_clock_seqlock);
         timers_state.qemu_icount_bias += warp;
-        seqlock_write_end(&timers_state.vm_clock_seqlock);
+        seqlock_write_unlock(&timers_state.vm_clock_seqlock);
 
         qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
         timerlist_run_timers(aio_context->tlg.tl[QEMU_CLOCK_VIRTUAL]);
@@ -468,9 +466,9 @@ void qemu_start_warp_timer(void)
              * It is useful when we want a deterministic execution time,
              * isolated from host latencies.
              */
-            seqlock_write_begin(&timers_state.vm_clock_seqlock);
+            seqlock_write_lock(&timers_state.vm_clock_seqlock);
             timers_state.qemu_icount_bias += deadline;
-            seqlock_write_end(&timers_state.vm_clock_seqlock);
+            seqlock_write_unlock(&timers_state.vm_clock_seqlock);
             qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
         } else {
             /*
@@ -481,11 +479,11 @@ void qemu_start_warp_timer(void)
              * you will not be sending network packets continuously instead of
              * every 100ms.
              */
-            seqlock_write_begin(&timers_state.vm_clock_seqlock);
+            seqlock_write_lock(&timers_state.vm_clock_seqlock);
             if (vm_clock_warp_start == -1 || vm_clock_warp_start > clock) {
                 vm_clock_warp_start = clock;
             }
-            seqlock_write_end(&timers_state.vm_clock_seqlock);
+            seqlock_write_unlock(&timers_state.vm_clock_seqlock);
             timer_mod_anticipate(icount_warp_timer, clock + deadline);
         }
     } else if (deadline == 0) {
@@ -621,7 +619,7 @@ int cpu_throttle_get_percentage(void)
 
 void cpu_ticks_init(void)
 {
-    seqlock_init(&timers_state.vm_clock_seqlock);
+    seqlock_init(&timers_state.vm_clock_seqlock, NULL);
     vmstate_register(NULL, 0, &vmstate_timers, &timers_state);
     throttle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
                                            cpu_throttle_timer_tick, NULL);
@@ -780,7 +778,7 @@ static void sigbus_reraise(void)
         raise(SIGBUS);
         sigemptyset(&set);
         sigaddset(&set, SIGBUS);
-        pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+        sigprocmask(SIG_UNBLOCK, &set, NULL);
     }
     perror("Failed to re-raise SIGBUS!\n");
     abort();
@@ -972,18 +970,6 @@ void async_run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)
     qemu_cpu_kick(cpu);
 }
 
-static void qemu_kvm_destroy_vcpu(CPUState *cpu)
-{
-    if (kvm_destroy_vcpu(cpu) < 0) {
-        error_report("kvm_destroy_vcpu failed");
-        exit(EXIT_FAILURE);
-    }
-}
-
-static void qemu_tcg_destroy_vcpu(CPUState *cpu)
-{
-}
-
 static void flush_queued_work(CPUState *cpu)
 {
     struct qemu_work_item *wi;
@@ -1073,7 +1059,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
     cpu->created = true;
     qemu_cond_signal(&qemu_cpu_cond);
 
-    do {
+    while (1) {
         if (cpu_can_run(cpu)) {
             r = kvm_cpu_exec(cpu);
             if (r == EXCP_DEBUG) {
@@ -1081,12 +1067,8 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
             }
         }
         qemu_kvm_wait_io_event(cpu);
-    } while (!cpu->unplug || cpu_can_run(cpu));
+    }
 
-    qemu_kvm_destroy_vcpu(cpu);
-    cpu->created = false;
-    qemu_cond_signal(&qemu_cpu_cond);
-    qemu_mutex_unlock_iothread();
     return NULL;
 }
 
@@ -1140,7 +1122,6 @@ static void tcg_exec_all(void);
 static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
     CPUState *cpu = arg;
-    CPUState *remove_cpu = NULL;
 
     rcu_register_thread();
 
@@ -1178,18 +1159,6 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
             }
         }
         qemu_tcg_wait_io_event(QTAILQ_FIRST(&cpus));
-        CPU_FOREACH(cpu) {
-            if (cpu->unplug && !cpu_can_run(cpu)) {
-                remove_cpu = cpu;
-                break;
-            }
-        }
-        if (remove_cpu) {
-            qemu_tcg_destroy_vcpu(remove_cpu);
-            cpu->created = false;
-            qemu_cond_signal(&qemu_cpu_cond);
-            remove_cpu = NULL;
-        }
     }
 
     return NULL;
@@ -1346,21 +1315,6 @@ void resume_all_vcpus(void)
     }
 }
 
-void cpu_remove(CPUState *cpu)
-{
-    cpu->stop = true;
-    cpu->unplug = true;
-    qemu_cpu_kick(cpu);
-}
-
-void cpu_remove_sync(CPUState *cpu)
-{
-    cpu_remove(cpu);
-    while (cpu->created) {
-        qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
-    }
-}
-
 /* For temporary buffers for forming a name */
 #define VCPU_THREAD_NAME_SIZE 16
 
@@ -1577,9 +1531,6 @@ static void tcg_exec_all(void)
                 break;
             }
         } else if (cpu->stop || cpu->stopped) {
-            if (cpu->unplug) {
-                next_cpu = CPU_NEXT(cpu);
-            }
             break;
         }
     }
@@ -1740,7 +1691,21 @@ exit:
 
 void qmp_inject_nmi(Error **errp)
 {
+#if defined(TARGET_I386)
+    CPUState *cs;
+
+    CPU_FOREACH(cs) {
+        X86CPU *cpu = X86_CPU(cs);
+
+        if (!cpu->apic_state) {
+            cpu_interrupt(cs, CPU_INTERRUPT_NMI);
+        } else {
+            apic_deliver_nmi(cpu->apic_state);
+        }
+    }
+#else
     nmi_monitor_handle(monitor_get_cpu_index(), errp);
+#endif
 }
 
 void dump_drift_info(FILE *f, fprintf_function cpu_fprintf)
index d068ee5..466663b 100644 (file)
--- a/cputlb.c
+++ b/cputlb.c
 
 #include "exec/memory-internal.h"
 #include "exec/ram_addr.h"
-#include "exec/exec-all.h"
 #include "tcg/tcg.h"
-#include "qemu/error-report.h"
-#include "exec/log.h"
 
 /* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
 /* #define DEBUG_TLB */
@@ -79,6 +76,10 @@ void tlb_flush(CPUState *cpu, int flush_global)
 
     tlb_debug("(%d)\n", flush_global);
 
+    /* must reset current TB so that interrupts cannot modify the
+       links while we are modifying them */
+    cpu->current_tb = NULL;
+
     memset(env->tlb_table, -1, sizeof(env->tlb_table));
     memset(env->tlb_v_table, -1, sizeof(env->tlb_v_table));
     memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
@@ -94,6 +95,9 @@ static inline void v_tlb_flush_by_mmuidx(CPUState *cpu, va_list argp)
     CPUArchState *env = cpu->env_ptr;
 
     tlb_debug("start\n");
+    /* must reset current TB so that interrupts cannot modify the
+       links while we are modifying them */
+    cpu->current_tb = NULL;
 
     for (;;) {
         int mmu_idx = va_arg(argp, int);
@@ -148,6 +152,9 @@ void tlb_flush_page(CPUState *cpu, target_ulong addr)
         tlb_flush(cpu, 1);
         return;
     }
+    /* must reset current TB so that interrupts cannot modify the
+       links while we are modifying them */
+    cpu->current_tb = NULL;
 
     addr &= TARGET_PAGE_MASK;
     i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
@@ -186,6 +193,9 @@ void tlb_flush_page_by_mmuidx(CPUState *cpu, target_ulong addr, ...)
         va_end(argp);
         return;
     }
+    /* must reset current TB so that interrupts cannot modify the
+       links while we are modifying them */
+    cpu->current_tb = NULL;
 
     addr &= TARGET_PAGE_MASK;
     i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
@@ -248,8 +258,7 @@ static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
 {
     ram_addr_t ram_addr;
 
-    ram_addr = qemu_ram_addr_from_host(ptr);
-    if (ram_addr == RAM_ADDR_INVALID) {
+    if (qemu_ram_addr_from_host(ptr, &ram_addr) == NULL) {
         fprintf(stderr, "Bad ram pointer %p\n", ptr);
         abort();
     }
@@ -429,39 +438,6 @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr,
                             prot, mmu_idx, size);
 }
 
-static void report_bad_exec(CPUState *cpu, target_ulong addr)
-{
-    /* Accidentally executing outside RAM or ROM is quite common for
-     * several user-error situations, so report it in a way that
-     * makes it clear that this isn't a QEMU bug and provide suggestions
-     * about what a user could do to fix things.
-     */
-    error_report("Trying to execute code outside RAM or ROM at 0x"
-                 TARGET_FMT_lx, addr);
-    error_printf("This usually means one of the following happened:\n\n"
-                 "(1) You told QEMU to execute a kernel for the wrong machine "
-                 "type, and it crashed on startup (eg trying to run a "
-                 "raspberry pi kernel on a versatilepb QEMU machine)\n"
-                 "(2) You didn't give QEMU a kernel or BIOS filename at all, "
-                 "and QEMU executed a ROM full of no-op instructions until "
-                 "it fell off the end\n"
-                 "(3) Your guest kernel has a bug and crashed by jumping "
-                 "off into nowhere\n\n"
-                 "This is almost always one of the first two, so check your "
-                 "command line and that you are using the right type of kernel "
-                 "for this machine.\n"
-                 "If you think option (3) is likely then you can try debugging "
-                 "your guest with the -d debug options; in particular "
-                 "-d guest_errors will cause the log to include a dump of the "
-                 "guest register state at this point.\n\n"
-                 "Execution cannot continue; stopping here.\n\n");
-
-    /* Report also to the logs, with more detail including register dump */
-    qemu_log_mask(LOG_GUEST_ERROR, "qemu: fatal: Trying to execute code "
-                  "outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
-    log_cpu_state_mask(LOG_GUEST_ERROR, cpu, CPU_DUMP_FPU | CPU_DUMP_CCOP);
-}
-
 /* NOTE: this function can trigger an exception */
 /* NOTE2: the returned address is not exactly the physical address: it
  * is actually a ram_addr_t (in system mode; the user mode emulation
@@ -490,43 +466,14 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
         if (cc->do_unassigned_access) {
             cc->do_unassigned_access(cpu, addr, false, true, 0, 4);
         } else {
-            report_bad_exec(cpu, addr);
-            exit(1);
+            cpu_abort(cpu, "Trying to execute code outside RAM or ROM at 0x"
+                      TARGET_FMT_lx "\n", addr);
         }
     }
     p = (void *)((uintptr_t)addr + env1->tlb_table[mmu_idx][page_index].addend);
     return qemu_ram_addr_from_host_nofail(p);
 }
 
-/* Return true if ADDR is present in the victim tlb, and has been copied
-   back to the main tlb.  */
-static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
-                           size_t elt_ofs, target_ulong page)
-{
-    size_t vidx;
-    for (vidx = 0; vidx < CPU_VTLB_SIZE; ++vidx) {
-        CPUTLBEntry *vtlb = &env->tlb_v_table[mmu_idx][vidx];
-        target_ulong cmp = *(target_ulong *)((uintptr_t)vtlb + elt_ofs);
-
-        if (cmp == page) {
-            /* Found entry in victim tlb, swap tlb and iotlb.  */
-            CPUTLBEntry tmptlb, *tlb = &env->tlb_table[mmu_idx][index];
-            CPUIOTLBEntry tmpio, *io = &env->iotlb[mmu_idx][index];
-            CPUIOTLBEntry *vio = &env->iotlb_v[mmu_idx][vidx];
-
-            tmptlb = *tlb; *tlb = *vtlb; *vtlb = tmptlb;
-            tmpio = *io; *io = *vio; *vio = tmpio;
-            return true;
-        }
-    }
-    return false;
-}
-
-/* Macro to call the above, with local variables from the use context.  */
-#define VICTIM_TLB_HIT(TY, ADDR) \
-  victim_tlb_hit(env, mmu_idx, index, offsetof(CPUTLBEntry, TY), \
-                 (ADDR) & TARGET_PAGE_MASK)
-
 #define MMUSUFFIX _mmu
 
 #define SHIFT 0
index a36d2d9..0737f48 100644 (file)
@@ -1,8 +1,5 @@
 crypto-obj-y = init.o
 crypto-obj-y += hash.o
-crypto-obj-$(CONFIG_NETTLE) += hash-nettle.o
-crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += hash-gcrypt.o
-crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT),n,y)) += hash-glib.o
 crypto-obj-y += aes.o
 crypto-obj-y += desrfb.o
 crypto-obj-y += cipher.o
@@ -13,7 +10,6 @@ crypto-obj-y += tlssession.o
 crypto-obj-y += secret.o
 crypto-obj-$(CONFIG_GCRYPT) += random-gcrypt.o
 crypto-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS_RND)) += random-gnutls.o
-crypto-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS_RND),n,y)) += random-platform.o
 crypto-obj-y += pbkdf.o
 crypto-obj-$(CONFIG_NETTLE_KDF) += pbkdf-nettle.o
 crypto-obj-$(if $(CONFIG_NETTLE_KDF),n,$(CONFIG_GCRYPT_KDF)) += pbkdf-gcrypt.o
@@ -30,4 +26,5 @@ crypto-obj-y += block-luks.o
 # Let the userspace emulators avoid linking gnutls/etc
 crypto-aes-obj-y = aes.o
 
+stub-obj-y += random-stub.o
 stub-obj-y += pbkdf-stub.o
index 825e2cf..8074913 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu/bswap.h"
 #include "crypto/afsplit.h"
 #include "crypto/random.h"
 
index aba4455..439f892 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qemu/bswap.h"
 
 #include "crypto/block-luks.h"
 
@@ -201,15 +200,6 @@ QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSHeader) != 592);
 
 struct QCryptoBlockLUKS {
     QCryptoBlockLUKSHeader header;
-
-    /* Cache parsed versions of what's in header fields,
-     * as we can't rely on QCryptoBlock.cipher being
-     * non-NULL */
-    QCryptoCipherAlgorithm cipher_alg;
-    QCryptoCipherMode cipher_mode;
-    QCryptoIVGenAlgorithm ivgen_alg;
-    QCryptoHashAlgorithm ivgen_hash_alg;
-    QCryptoHashAlgorithm hash_alg;
 };
 
 
@@ -785,11 +775,6 @@ qcrypto_block_luks_open(QCryptoBlock *block,
     }
 
     if (ivalg == QCRYPTO_IVGEN_ALG_ESSIV) {
-        if (!ivhash_name) {
-            ret = -EINVAL;
-            error_setg(errp, "Missing IV generator hash specification");
-            goto fail;
-        }
         ivcipheralg = qcrypto_block_luks_essiv_cipher(cipheralg,
                                                       ivhash,
                                                       &local_err);
@@ -799,13 +784,6 @@ qcrypto_block_luks_open(QCryptoBlock *block,
             goto fail;
         }
     } else {
-        /* Note we parsed the ivhash_name earlier in the cipher_mode
-         * spec string even with plain/plain64 ivgens, but we
-         * will ignore it, since it is irrelevant for these ivgens.
-         * This is for compat with dm-crypt which will silently
-         * ignore hash names with these ivgens rather than report
-         * an error about the invalid usage
-         */
         ivcipheralg = cipheralg;
     }
 
@@ -856,12 +834,6 @@ qcrypto_block_luks_open(QCryptoBlock *block,
     block->payload_offset = luks->header.payload_offset *
         QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
 
-    luks->cipher_alg = cipheralg;
-    luks->cipher_mode = ciphermode;
-    luks->ivgen_alg = ivalg;
-    luks->ivgen_hash_alg = ivhash;
-    luks->hash_alg = hash;
-
     g_free(masterkey);
     g_free(password);
 
@@ -931,15 +903,6 @@ qcrypto_block_luks_create(QCryptoBlock *block,
     if (!luks_opts.has_hash_alg) {
         luks_opts.hash_alg = QCRYPTO_HASH_ALG_SHA256;
     }
-    if (luks_opts.ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) {
-        if (!luks_opts.has_ivgen_hash_alg) {
-            luks_opts.ivgen_hash_alg = QCRYPTO_HASH_ALG_SHA256;
-            luks_opts.has_ivgen_hash_alg = true;
-        }
-    }
-    /* Note we're allowing ivgen_hash_alg to be set even for
-     * non-essiv iv generators that don't need a hash. It will
-     * be silently ignored, for compatibility with dm-crypt */
 
     if (!options->u.luks.key_secret) {
         error_setg(errp, "Parameter 'key-secret' is required for cipher");
@@ -1117,7 +1080,8 @@ qcrypto_block_luks_create(QCryptoBlock *block,
         luks->header.key_slots[i].key_offset =
             (QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET /
              QCRYPTO_BLOCK_LUKS_SECTOR_SIZE) +
-            (ROUND_UP(DIV_ROUND_UP(splitkeylen, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE),
+            (ROUND_UP(((splitkeylen + (QCRYPTO_BLOCK_LUKS_SECTOR_SIZE - 1)) /
+                       QCRYPTO_BLOCK_LUKS_SECTOR_SIZE),
                       (QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET /
                        QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) * i);
     }
@@ -1217,7 +1181,8 @@ qcrypto_block_luks_create(QCryptoBlock *block,
     luks->header.payload_offset =
         (QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET /
          QCRYPTO_BLOCK_LUKS_SECTOR_SIZE) +
-        (ROUND_UP(DIV_ROUND_UP(splitkeylen, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE),
+        (ROUND_UP(((splitkeylen + (QCRYPTO_BLOCK_LUKS_SECTOR_SIZE - 1)) /
+                   QCRYPTO_BLOCK_LUKS_SECTOR_SIZE),
                   (QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET /
                    QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) *
          QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS);
@@ -1286,12 +1251,6 @@ qcrypto_block_luks_create(QCryptoBlock *block,
         goto error;
     }
 
-    luks->cipher_alg = luks_opts.cipher_alg;
-    luks->cipher_mode = luks_opts.cipher_mode;
-    luks->ivgen_alg = luks_opts.ivgen_alg;
-    luks->ivgen_hash_alg = luks_opts.ivgen_hash_alg;
-    luks->hash_alg = luks_opts.hash_alg;
-
     memset(masterkey, 0, luks->header.key_bytes);
     g_free(masterkey);
     memset(slotkey, 0, luks->header.key_bytes);
@@ -1326,51 +1285,6 @@ qcrypto_block_luks_create(QCryptoBlock *block,
 }
 
 
-static int qcrypto_block_luks_get_info(QCryptoBlock *block,
-                                       QCryptoBlockInfo *info,
-                                       Error **errp)
-{
-    QCryptoBlockLUKS *luks = block->opaque;
-    QCryptoBlockInfoLUKSSlot *slot;
-    QCryptoBlockInfoLUKSSlotList *slots = NULL, **prev = &info->u.luks.slots;
-    size_t i;
-
-    info->u.luks.cipher_alg = luks->cipher_alg;
-    info->u.luks.cipher_mode = luks->cipher_mode;
-    info->u.luks.ivgen_alg = luks->ivgen_alg;
-    if (info->u.luks.ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) {
-        info->u.luks.has_ivgen_hash_alg = true;
-        info->u.luks.ivgen_hash_alg = luks->ivgen_hash_alg;
-    }
-    info->u.luks.hash_alg = luks->hash_alg;
-    info->u.luks.payload_offset = block->payload_offset;
-    info->u.luks.master_key_iters = luks->header.master_key_iterations;
-    info->u.luks.uuid = g_strndup((const char *)luks->header.uuid,
-                                  sizeof(luks->header.uuid));
-
-    for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
-        slots = g_new0(QCryptoBlockInfoLUKSSlotList, 1);
-        *prev = slots;
-
-        slots->value = slot = g_new0(QCryptoBlockInfoLUKSSlot, 1);
-        slot->active = luks->header.key_slots[i].active ==
-            QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED;
-        slot->key_offset = luks->header.key_slots[i].key_offset
-             * QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
-        if (slot->active) {
-            slot->has_iters = true;
-            slot->iters = luks->header.key_slots[i].iterations;
-            slot->has_stripes = true;
-            slot->stripes = luks->header.key_slots[i].stripes;
-        }
-
-        prev = &slots->next;
-    }
-
-    return 0;
-}
-
-
 static void qcrypto_block_luks_cleanup(QCryptoBlock *block)
 {
     g_free(block->opaque);
@@ -1408,7 +1322,6 @@ qcrypto_block_luks_encrypt(QCryptoBlock *block,
 const QCryptoBlockDriver qcrypto_block_driver_luks = {
     .open = qcrypto_block_luks_open,
     .create = qcrypto_block_luks_create,
-    .get_info = qcrypto_block_luks_get_info,
     .cleanup = qcrypto_block_luks_cleanup,
     .decrypt = qcrypto_block_luks_decrypt,
     .encrypt = qcrypto_block_luks_encrypt,
index b2d8a35..0934138 100644 (file)
  *
  */
 
-#ifndef QCRYPTO_BLOCK_LUKS_H
-#define QCRYPTO_BLOCK_LUKS_H
+#ifndef QCRYPTO_BLOCK_LUKS_H__
+#define QCRYPTO_BLOCK_LUKS_H__
 
 #include "crypto/blockpriv.h"
 
 extern const QCryptoBlockDriver qcrypto_block_driver_luks;
 
-#endif /* QCRYPTO_BLOCK_LUKS_H */
+#endif /* QCRYPTO_BLOCK_LUKS_H__ */
index 3e2c0a8..569f836 100644 (file)
  *
  */
 
-#ifndef QCRYPTO_BLOCK_QCOW_H
-#define QCRYPTO_BLOCK_QCOW_H
+#ifndef QCRYPTO_BLOCK_QCOW_H__
+#define QCRYPTO_BLOCK_QCOW_H__
 
 #include "crypto/blockpriv.h"
 
 extern const QCryptoBlockDriver qcrypto_block_driver_qcow;
 
-#endif /* QCRYPTO_BLOCK_QCOW_H */
+#endif /* QCRYPTO_BLOCK_QCOW_H__ */
index be823ee..da60eba 100644 (file)
@@ -105,23 +105,6 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
 }
 
 
-QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
-                                         Error **errp)
-{
-    QCryptoBlockInfo *info = g_new0(QCryptoBlockInfo, 1);
-
-    info->format = block->format;
-
-    if (block->driver->get_info &&
-        block->driver->get_info(block, info, errp) < 0) {
-        g_free(info);
-        return NULL;
-    }
-
-    return info;
-}
-
-
 int qcrypto_block_decrypt(QCryptoBlock *block,
                           uint64_t startsector,
                           uint8_t *buf,
index 68f0f06..6297085 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_BLOCKPRIV_H
-#define QCRYPTO_BLOCKPRIV_H
+#ifndef QCRYPTO_BLOCK_PRIV_H__
+#define QCRYPTO_BLOCK_PRIV_H__
 
 #include "crypto/block.h"
 
@@ -53,10 +53,6 @@ struct QCryptoBlockDriver {
                   void *opaque,
                   Error **errp);
 
-    int (*get_info)(QCryptoBlock *block,
-                    QCryptoBlockInfo *info,
-                    Error **errp);
-
     void (*cleanup)(QCryptoBlock *block);
 
     int (*encrypt)(QCryptoBlock *block,
@@ -93,4 +89,4 @@ int qcrypto_block_encrypt_helper(QCryptoCipher *cipher,
                                  size_t len,
                                  Error **errp);
 
-#endif /* QCRYPTO_BLOCKPRIV_H */
+#endif /* QCRYPTO_BLOCK_PRIV_H__ */
diff --git a/crypto/hash-gcrypt.c b/crypto/hash-gcrypt.c
deleted file mode 100644 (file)
index 7690690..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * QEMU Crypto hash algorithms
- *
- * Copyright (c) 2016 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include <gcrypt.h>
-#include "qapi/error.h"
-#include "crypto/hash.h"
-
-
-static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG__MAX] = {
-    [QCRYPTO_HASH_ALG_MD5] = GCRY_MD_MD5,
-    [QCRYPTO_HASH_ALG_SHA1] = GCRY_MD_SHA1,
-    [QCRYPTO_HASH_ALG_SHA224] = GCRY_MD_SHA224,
-    [QCRYPTO_HASH_ALG_SHA256] = GCRY_MD_SHA256,
-    [QCRYPTO_HASH_ALG_SHA384] = GCRY_MD_SHA384,
-    [QCRYPTO_HASH_ALG_SHA512] = GCRY_MD_SHA512,
-    [QCRYPTO_HASH_ALG_RIPEMD160] = GCRY_MD_RMD160,
-};
-
-gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
-{
-    if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map) &&
-        qcrypto_hash_alg_map[alg] != GCRY_MD_NONE) {
-        return true;
-    }
-    return false;
-}
-
-
-int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
-                        const struct iovec *iov,
-                        size_t niov,
-                        uint8_t **result,
-                        size_t *resultlen,
-                        Error **errp)
-{
-    int i, ret;
-    gcry_md_hd_t md;
-    unsigned char *digest;
-
-    if (!qcrypto_hash_supports(alg)) {
-        error_setg(errp,
-                   "Unknown hash algorithm %d",
-                   alg);
-        return -1;
-    }
-
-    ret = gcry_md_open(&md, qcrypto_hash_alg_map[alg], 0);
-
-    if (ret < 0) {
-        error_setg(errp,
-                   "Unable to initialize hash algorithm: %s",
-                   gcry_strerror(ret));
-        return -1;
-    }
-
-    for (i = 0; i < niov; i++) {
-        gcry_md_write(md, iov[i].iov_base, iov[i].iov_len);
-    }
-
-    ret = gcry_md_get_algo_dlen(qcrypto_hash_alg_map[alg]);
-    if (ret <= 0) {
-        error_setg(errp,
-                   "Unable to get hash length: %s",
-                   gcry_strerror(ret));
-        goto error;
-    }
-    if (*resultlen == 0) {
-        *resultlen = ret;
-        *result = g_new0(uint8_t, *resultlen);
-    } else if (*resultlen != ret) {
-        error_setg(errp,
-                   "Result buffer size %zu is smaller than hash %d",
-                   *resultlen, ret);
-        goto error;
-    }
-
-    digest = gcry_md_read(md, 0);
-    if (!digest) {
-        error_setg(errp,
-                   "No digest produced");
-        goto error;
-    }
-    memcpy(*result, digest, *resultlen);
-
-    gcry_md_close(md);
-    return 0;
-
- error:
-    gcry_md_close(md);
-    return -1;
-}
diff --git a/crypto/hash-glib.c b/crypto/hash-glib.c
deleted file mode 100644 (file)
index ec99ac9..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * QEMU Crypto hash algorithms
- *
- * Copyright (c) 2016 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "crypto/hash.h"
-
-
-static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG__MAX] = {
-    [QCRYPTO_HASH_ALG_MD5] = G_CHECKSUM_MD5,
-    [QCRYPTO_HASH_ALG_SHA1] = G_CHECKSUM_SHA1,
-    [QCRYPTO_HASH_ALG_SHA224] = -1,
-    [QCRYPTO_HASH_ALG_SHA256] = G_CHECKSUM_SHA256,
-    [QCRYPTO_HASH_ALG_SHA384] = -1,
-#if GLIB_CHECK_VERSION(2, 36, 0)
-    [QCRYPTO_HASH_ALG_SHA512] = G_CHECKSUM_SHA512,
-#else
-    [QCRYPTO_HASH_ALG_SHA512] = -1,
-#endif
-    [QCRYPTO_HASH_ALG_RIPEMD160] = -1,
-};
-
-gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
-{
-    if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map) &&
-        qcrypto_hash_alg_map[alg] != -1) {
-        return true;
-    }
-    return false;
-}
-
-
-int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
-                        const struct iovec *iov,
-                        size_t niov,
-                        uint8_t **result,
-                        size_t *resultlen,
-                        Error **errp)
-{
-    int i, ret;
-    GChecksum *cs;
-
-    if (!qcrypto_hash_supports(alg)) {
-        error_setg(errp,
-                   "Unknown hash algorithm %d",
-                   alg);
-        return -1;
-    }
-
-    cs = g_checksum_new(qcrypto_hash_alg_map[alg]);
-
-    for (i = 0; i < niov; i++) {
-        g_checksum_update(cs, iov[i].iov_base, iov[i].iov_len);
-    }
-
-    ret = g_checksum_type_get_length(qcrypto_hash_alg_map[alg]);
-    if (ret < 0) {
-        error_setg(errp, "%s",
-                   "Unable to get hash length");
-        goto error;
-    }
-    if (*resultlen == 0) {
-        *resultlen = ret;
-        *result = g_new0(uint8_t, *resultlen);
-    } else if (*resultlen != ret) {
-        error_setg(errp,
-                   "Result buffer size %zu is smaller than hash %d",
-                   *resultlen, ret);
-        goto error;
-    }
-
-    g_checksum_get_digest(cs, *result, resultlen);
-
-    g_checksum_free(cs);
-    return 0;
-
- error:
-    g_checksum_free(cs);
-    return -1;
-}
diff --git a/crypto/hash-nettle.c b/crypto/hash-nettle.c
deleted file mode 100644 (file)
index 6a206dc..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * QEMU Crypto hash algorithms
- *
- * Copyright (c) 2016 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "crypto/hash.h"
-#include <nettle/md5.h>
-#include <nettle/sha.h>
-#include <nettle/ripemd160.h>
-
-typedef void (*qcrypto_nettle_init)(void *ctx);
-typedef void (*qcrypto_nettle_write)(void *ctx,
-                                     unsigned int len,
-                                     const uint8_t *buf);
-typedef void (*qcrypto_nettle_result)(void *ctx,
-                                      unsigned int len,
-                                      uint8_t *buf);
-
-union qcrypto_hash_ctx {
-    struct md5_ctx md5;
-    struct sha1_ctx sha1;
-    struct sha224_ctx sha224;
-    struct sha256_ctx sha256;
-    struct sha384_ctx sha384;
-    struct sha512_ctx sha512;
-    struct ripemd160_ctx ripemd160;
-};
-
-struct qcrypto_hash_alg {
-    qcrypto_nettle_init init;
-    qcrypto_nettle_write write;
-    qcrypto_nettle_result result;
-    size_t len;
-} qcrypto_hash_alg_map[] = {
-    [QCRYPTO_HASH_ALG_MD5] = {
-        .init = (qcrypto_nettle_init)md5_init,
-        .write = (qcrypto_nettle_write)md5_update,
-        .result = (qcrypto_nettle_result)md5_digest,
-        .len = MD5_DIGEST_SIZE,
-    },
-    [QCRYPTO_HASH_ALG_SHA1] = {
-        .init = (qcrypto_nettle_init)sha1_init,
-        .write = (qcrypto_nettle_write)sha1_update,
-        .result = (qcrypto_nettle_result)sha1_digest,
-        .len = SHA1_DIGEST_SIZE,
-    },
-    [QCRYPTO_HASH_ALG_SHA224] = {
-        .init = (qcrypto_nettle_init)sha224_init,
-        .write = (qcrypto_nettle_write)sha224_update,
-        .result = (qcrypto_nettle_result)sha224_digest,
-        .len = SHA224_DIGEST_SIZE,
-    },
-    [QCRYPTO_HASH_ALG_SHA256] = {
-        .init = (qcrypto_nettle_init)sha256_init,
-        .write = (qcrypto_nettle_write)sha256_update,
-        .result = (qcrypto_nettle_result)sha256_digest,
-        .len = SHA256_DIGEST_SIZE,
-    },
-    [QCRYPTO_HASH_ALG_SHA384] = {
-        .init = (qcrypto_nettle_init)sha384_init,
-        .write = (qcrypto_nettle_write)sha384_update,
-        .result = (qcrypto_nettle_result)sha384_digest,
-        .len = SHA384_DIGEST_SIZE,
-    },
-    [QCRYPTO_HASH_ALG_SHA512] = {
-        .init = (qcrypto_nettle_init)sha512_init,
-        .write = (qcrypto_nettle_write)sha512_update,
-        .result = (qcrypto_nettle_result)sha512_digest,
-        .len = SHA512_DIGEST_SIZE,
-    },
-    [QCRYPTO_HASH_ALG_RIPEMD160] = {
-        .init = (qcrypto_nettle_init)ripemd160_init,
-        .write = (qcrypto_nettle_write)ripemd160_update,
-        .result = (qcrypto_nettle_result)ripemd160_digest,
-        .len = RIPEMD160_DIGEST_SIZE,
-    },
-};
-
-gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
-{
-    if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map) &&
-        qcrypto_hash_alg_map[alg].init != NULL) {
-        return true;
-    }
-    return false;
-}
-
-
-int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
-                        const struct iovec *iov,
-                        size_t niov,
-                        uint8_t **result,
-                        size_t *resultlen,
-                        Error **errp)
-{
-    int i;
-    union qcrypto_hash_ctx ctx;
-
-    if (!qcrypto_hash_supports(alg)) {
-        error_setg(errp,
-                   "Unknown hash algorithm %d",
-                   alg);
-        return -1;
-    }
-
-    qcrypto_hash_alg_map[alg].init(&ctx);
-
-    for (i = 0; i < niov; i++) {
-        /* Some versions of nettle have functions
-         * declared with 'int' instead of 'size_t'
-         * so to be safe avoid writing more than
-         * UINT_MAX bytes at a time
-         */
-        size_t len = iov[i].iov_len;
-        uint8_t *base = iov[i].iov_base;
-        while (len) {
-            size_t shortlen = MIN(len, UINT_MAX);
-            qcrypto_hash_alg_map[alg].write(&ctx, len, base);
-            len -= shortlen;
-            base += len;
-        }
-    }
-
-    if (*resultlen == 0) {
-        *resultlen = qcrypto_hash_alg_map[alg].len;
-        *result = g_new0(uint8_t, *resultlen);
-    } else if (*resultlen != qcrypto_hash_alg_map[alg].len) {
-        error_setg(errp,
-                   "Result buffer size %zu is smaller than hash %zu",
-                   *resultlen, qcrypto_hash_alg_map[alg].len);
-        return -1;
-    }
-
-    qcrypto_hash_alg_map[alg].result(&ctx, *resultlen, *result);
-
-    return 0;
-}
index 0f1ceac..b90af34 100644 (file)
 #include "qapi/error.h"
 #include "crypto/hash.h"
 
+#ifdef CONFIG_GNUTLS_HASH
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+#endif
+
+
 static size_t qcrypto_hash_alg_size[QCRYPTO_HASH_ALG__MAX] = {
     [QCRYPTO_HASH_ALG_MD5] = 16,
     [QCRYPTO_HASH_ALG_SHA1] = 20,
-    [QCRYPTO_HASH_ALG_SHA224] = 28,
     [QCRYPTO_HASH_ALG_SHA256] = 32,
-    [QCRYPTO_HASH_ALG_SHA384] = 48,
-    [QCRYPTO_HASH_ALG_SHA512] = 64,
-    [QCRYPTO_HASH_ALG_RIPEMD160] = 20,
 };
 
 size_t qcrypto_hash_digest_len(QCryptoHashAlgorithm alg)
 {
-    assert(alg < G_N_ELEMENTS(qcrypto_hash_alg_size));
+    if (alg >= G_N_ELEMENTS(qcrypto_hash_alg_size)) {
+        return 0;
+    }
     return qcrypto_hash_alg_size[alg];
 }
 
 
+#ifdef CONFIG_GNUTLS_HASH
+static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG__MAX] = {
+    [QCRYPTO_HASH_ALG_MD5] = GNUTLS_DIG_MD5,
+    [QCRYPTO_HASH_ALG_SHA1] = GNUTLS_DIG_SHA1,
+    [QCRYPTO_HASH_ALG_SHA256] = GNUTLS_DIG_SHA256,
+};
+
+gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
+{
+    if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map)) {
+        return true;
+    }
+    return false;
+}
+
+
+int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
+                        const struct iovec *iov,
+                        size_t niov,
+                        uint8_t **result,
+                        size_t *resultlen,
+                        Error **errp)
+{
+    int i, ret;
+    gnutls_hash_hd_t dig;
+
+    if (alg >= G_N_ELEMENTS(qcrypto_hash_alg_map)) {
+        error_setg(errp,
+                   "Unknown hash algorithm %d",
+                   alg);
+        return -1;
+    }
+
+    ret = gnutls_hash_init(&dig, qcrypto_hash_alg_map[alg]);
+
+    if (ret < 0) {
+        error_setg(errp,
+                   "Unable to initialize hash algorithm: %s",
+                   gnutls_strerror(ret));
+        return -1;
+    }
+
+    for (i = 0; i < niov; i++) {
+        ret = gnutls_hash(dig, iov[i].iov_base, iov[i].iov_len);
+        if (ret < 0) {
+            error_setg(errp,
+                       "Unable process hash data: %s",
+                       gnutls_strerror(ret));
+            goto error;
+        }
+    }
+
+    ret = gnutls_hash_get_len(qcrypto_hash_alg_map[alg]);
+    if (ret <= 0) {
+        error_setg(errp,
+                   "Unable to get hash length: %s",
+                   gnutls_strerror(ret));
+        goto error;
+    }
+    if (*resultlen == 0) {
+        *resultlen = ret;
+        *result = g_new0(uint8_t, *resultlen);
+    } else if (*resultlen != ret) {
+        error_setg(errp,
+                   "Result buffer size %zu is smaller than hash %d",
+                   *resultlen, ret);
+        goto error;
+    }
+
+    gnutls_hash_deinit(dig, *result);
+    return 0;
+
+ error:
+    gnutls_hash_deinit(dig, NULL);
+    return -1;
+}
+
+#else /* ! CONFIG_GNUTLS_HASH */
+
+gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg G_GNUC_UNUSED)
+{
+    return false;
+}
+
+int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
+                        const struct iovec *iov G_GNUC_UNUSED,
+                        size_t niov G_GNUC_UNUSED,
+                        uint8_t **result G_GNUC_UNUSED,
+                        size_t *resultlen G_GNUC_UNUSED,
+                        Error **errp)
+{
+    error_setg(errp,
+               "Hash algorithm %d not supported without GNUTLS",
+               alg);
+    return -1;
+}
+
+#endif /* ! CONFIG_GNUTLS_HASH */
+
 int qcrypto_hash_bytes(QCryptoHashAlgorithm alg,
                        const char *buf,
                        size_t len,
index 28e5c67..7b87e02 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_IVGENPRIV_H
-#define QCRYPTO_IVGENPRIV_H
+#ifndef QCRYPTO_IVGEN_PRIV_H__
+#define QCRYPTO_IVGEN_PRIV_H__
 
 #include "crypto/ivgen.h"
 
@@ -46,4 +46,4 @@ struct QCryptoIVGen {
 };
 
 
-#endif /* QCRYPTO_IVGENPRIV_H */
+#endif /* QCRYPTO_IVGEN_PRIV_H__ */
index 34af3a9..997b311 100644 (file)
@@ -19,9 +19,9 @@
  */
 
 #include "qemu/osdep.h"
-#include <gcrypt.h>
 #include "qapi/error.h"
 #include "crypto/pbkdf.h"
+#include "gcrypt.h"
 
 bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash)
 {
index d681a60..db9fc15 100644 (file)
@@ -19,9 +19,9 @@
  */
 
 #include "qemu/osdep.h"
-#include <nettle/pbkdf2.h>
 #include "qapi/error.h"
 #include "crypto/pbkdf.h"
+#include "nettle/pbkdf2.h"
 
 
 bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash)
similarity index 52%
rename from crypto/random-platform.c
rename to crypto/random-stub.c
index 82b755a..63bbf41 100644 (file)
@@ -26,39 +26,6 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
                          size_t buflen G_GNUC_UNUSED,
                          Error **errp)
 {
-    int fd;
-    int ret = -1;
-    int got;
-
-    /* TBD perhaps also add support for BSD getentropy / Linux
-     * getrandom syscalls directly */
-    fd = open("/dev/urandom", O_RDONLY);
-    if (fd == -1 && errno == ENOENT) {
-        fd = open("/dev/random", O_RDONLY);
-    }
-
-    if (fd < 0) {
-        error_setg(errp, "No /dev/urandom or /dev/random found");
-        return -1;
-    }
-
-    while (buflen > 0) {
-        got = read(fd, buf, buflen);
-        if (got < 0) {
-            error_setg_errno(errp, errno,
-                             "Unable to read random bytes");
-            goto cleanup;
-        } else if (!got) {
-            error_setg(errp,
-                       "Unexpected EOF reading random bytes");
-            goto cleanup;
-        }
-        buflen -= got;
-        buf += got;
-    }
-
-    ret = 0;
- cleanup:
-    close(fd);
-    return ret;
+    error_setg(errp, "No random byte source provided in this build");
+    return -1;
 }
index a896553..1620e12 100644 (file)
@@ -179,27 +179,6 @@ qcrypto_tls_creds_prop_get_dir(Object *obj,
 
 
 static void
-qcrypto_tls_creds_prop_set_priority(Object *obj,
-                                    const char *value,
-                                    Error **errp G_GNUC_UNUSED)
-{
-    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
-
-    creds->priority = g_strdup(value);
-}
-
-
-static char *
-qcrypto_tls_creds_prop_get_priority(Object *obj,
-                                    Error **errp G_GNUC_UNUSED)
-{
-    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
-
-    return g_strdup(creds->priority);
-}
-
-
-static void
 qcrypto_tls_creds_prop_set_endpoint(Object *obj,
                                     int value,
                                     Error **errp G_GNUC_UNUSED)
@@ -237,10 +216,6 @@ qcrypto_tls_creds_class_init(ObjectClass *oc, void *data)
                                    qcrypto_tls_creds_prop_get_endpoint,
                                    qcrypto_tls_creds_prop_set_endpoint,
                                    NULL);
-    object_class_property_add_str(oc, "priority",
-                                  qcrypto_tls_creds_prop_get_priority,
-                                  qcrypto_tls_creds_prop_set_priority,
-                                  NULL);
 }
 
 
@@ -259,7 +234,6 @@ qcrypto_tls_creds_finalize(Object *obj)
     QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
 
     g_free(creds->dir);
-    g_free(creds->priority);
 }
 
 
index 13e9b6c..9222be4 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_TLSCREDSPRIV_H
-#define QCRYPTO_TLSCREDSPRIV_H
+#ifndef QCRYPTO_TLSCRED_PRIV_H__
+#define QCRYPTO_TLSCRED_PRIV_H__
 
 #include "crypto/tlscreds.h"
 
@@ -38,4 +38,5 @@ int qcrypto_tls_creds_get_dh_params_file(QCryptoTLSCreds *creds,
 
 #endif
 
-#endif /* QCRYPTO_TLSCREDSPRIV_H */
+#endif /* QCRYPTO_TLSCRED_PRIV_H__ */
+
index 520d34d..6a0179c 100644 (file)
@@ -392,14 +392,11 @@ qcrypto_tls_creds_load_cert(QCryptoTLSCredsX509 *creds,
     gsize buflen;
     GError *gerr;
     int ret = -1;
-    int err;
 
     trace_qcrypto_tls_creds_x509_load_cert(creds, isServer, certFile);
 
-    err = gnutls_x509_crt_init(&cert);
-    if (err < 0) {
-        error_setg(errp, "Unable to initialize certificate: %s",
-                   gnutls_strerror(err));
+    if (gnutls_x509_crt_init(&cert) < 0) {
+        error_setg(errp, "Unable to initialize certificate");
         goto cleanup;
     }
 
@@ -413,13 +410,11 @@ qcrypto_tls_creds_load_cert(QCryptoTLSCredsX509 *creds,
     data.data = (unsigned char *)buf;
     data.size = strlen(buf);
 
-    err = gnutls_x509_crt_import(cert, &data, GNUTLS_X509_FMT_PEM);
-    if (err < 0) {
+    if (gnutls_x509_crt_import(cert, &data, GNUTLS_X509_FMT_PEM) < 0) {
         error_setg(errp, isServer ?
-                   "Unable to import server certificate %s: %s" :
-                   "Unable to import client certificate %s: %s",
-                   certFile,
-                   gnutls_strerror(err));
+                   "Unable to import server certificate %s" :
+                   "Unable to import client certificate %s",
+                   certFile);
         goto cleanup;
     }
 
index 2de42c6..a543e5a 100644 (file)
@@ -132,22 +132,14 @@ qcrypto_tls_session_new(QCryptoTLSCreds *creds,
     if (object_dynamic_cast(OBJECT(creds),
                             TYPE_QCRYPTO_TLS_CREDS_ANON)) {
         QCryptoTLSCredsAnon *acreds = QCRYPTO_TLS_CREDS_ANON(creds);
-        char *prio;
 
-        if (creds->priority != NULL) {
-            prio = g_strdup_printf("%s:+ANON-DH", creds->priority);
-        } else {
-            prio = g_strdup(CONFIG_TLS_PRIORITY ":+ANON-DH");
-        }
-
-        ret = gnutls_priority_set_direct(session->handle, prio, NULL);
+        ret = gnutls_priority_set_direct(session->handle,
+                                         "NORMAL:+ANON-DH", NULL);
         if (ret < 0) {
-            error_setg(errp, "Unable to set TLS session priority %s: %s",
-                       prio, gnutls_strerror(ret));
-            g_free(prio);
+            error_setg(errp, "Unable to set TLS session priority: %s",
+                       gnutls_strerror(ret));
             goto error;
         }
-        g_free(prio);
         if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
             ret = gnutls_credentials_set(session->handle,
                                          GNUTLS_CRD_ANON,
@@ -165,15 +157,11 @@ qcrypto_tls_session_new(QCryptoTLSCreds *creds,
     } else if (object_dynamic_cast(OBJECT(creds),
                                    TYPE_QCRYPTO_TLS_CREDS_X509)) {
         QCryptoTLSCredsX509 *tcreds = QCRYPTO_TLS_CREDS_X509(creds);
-        const char *prio = creds->priority;
-        if (!prio) {
-            prio = CONFIG_TLS_PRIORITY;
-        }
 
-        ret = gnutls_priority_set_direct(session->handle, prio, NULL);
+        ret = gnutls_set_default_priority(session->handle);
         if (ret < 0) {
-            error_setg(errp, "Cannot set default TLS session priority %s: %s",
-                       prio, gnutls_strerror(ret));
+            error_setg(errp, "Cannot set default TLS session priority: %s",
+                       gnutls_strerror(ret));
             goto error;
         }
         ret = gnutls_credentials_set(session->handle,
diff --git a/crypto/trace-events b/crypto/trace-events
deleted file mode 100644 (file)
index 8181843..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# crypto/tlscreds.c
-qcrypto_tls_creds_load_dh(void *creds, const char *filename) "TLS creds load DH creds=%p filename=%s"
-qcrypto_tls_creds_get_path(void *creds, const char *filename, const char *path) "TLS creds path creds=%p filename=%s path=%s"
-
-# crypto/tlscredsanon.c
-qcrypto_tls_creds_anon_load(void *creds, const char *dir) "TLS creds anon load creds=%p dir=%s"
-
-# crypto/tlscredsx509.c
-qcrypto_tls_creds_x509_load(void *creds, const char *dir) "TLS creds x509 load creds=%p dir=%s"
-qcrypto_tls_creds_x509_check_basic_constraints(void *creds, const char *file, int status) "TLS creds x509 check basic constraints creds=%p file=%s status=%d"
-qcrypto_tls_creds_x509_check_key_usage(void *creds, const char *file, int status, int usage, int critical) "TLS creds x509 check key usage creds=%p file=%s status=%d usage=%d critical=%d"
-qcrypto_tls_creds_x509_check_key_purpose(void *creds, const char *file, int status, const char *usage, int critical) "TLS creds x509 check key usage creds=%p file=%s status=%d usage=%s critical=%d"
-qcrypto_tls_creds_x509_load_cert(void *creds, int isServer, const char *file) "TLS creds x509 load cert creds=%p isServer=%d file=%s"
-qcrypto_tls_creds_x509_load_cert_list(void *creds, const char *file) "TLS creds x509 load cert list creds=%p file=%s"
-
-# crypto/tlssession.c
-qcrypto_tls_session_new(void *session, void *creds, const char *hostname, const char *aclname, int endpoint) "TLS session new session=%p creds=%p hostname=%s aclname=%s endpoint=%d"
index 2449483..96dd994 100644 (file)
@@ -3,7 +3,4 @@
 # We support all the 32 bit boards so need all their config
 include arm-softmmu.mak
 
-CONFIG_AUX=y
-CONFIG_DDC=y
-CONFIG_DPCD=y
 CONFIG_XLNX_ZYNQMP=y
index 7a19863..c63cdd0 100644 (file)
@@ -66,7 +66,6 @@ CONFIG_PXA2XX=y
 CONFIG_BITBANG_I2C=y
 CONFIG_FRAMEBUFFER=y
 CONFIG_XILINX_SPIPS=y
-CONFIG_ZYNQ_DEVCFG=y
 
 CONFIG_ARM11SCU=y
 CONFIG_A9SCU=y
@@ -101,7 +100,6 @@ CONFIG_ALLWINNER_A10_PIT=y
 CONFIG_ALLWINNER_A10_PIC=y
 CONFIG_ALLWINNER_A10=y
 
-CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
 
index fff7ce3..9c8bc68 100644 (file)
@@ -18,7 +18,6 @@ CONFIG_MEGASAS_SCSI_PCI=y
 CONFIG_MPTSAS_SCSI_PCI=y
 CONFIG_RTL8139_PCI=y
 CONFIG_E1000_PCI=y
-CONFIG_E1000E_PCI=y
 CONFIG_VMXNET3_PCI=y
 CONFIG_IDE_CORE=y
 CONFIG_IDE_QDEV=y
index c4be59f..bb71b23 100644 (file)
@@ -49,7 +49,6 @@ CONFIG_ETSEC=y
 CONFIG_LIBDECNUMBER=y
 # For pSeries
 CONFIG_XICS=$(CONFIG_PSERIES)
-CONFIG_XICS_SPAPR=$(CONFIG_PSERIES)
 CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM))
 # For PReP
 CONFIG_MC146818RTC=y
index 6e06320..ccba1fd 100644 (file)
@@ -20,7 +20,6 @@
 #include "qapi/error.h"
 #include "qemu-common.h"
 #include "qemu/error-report.h"
-#include "qemu/bswap.h"
 #include "sysemu/device_tree.h"
 #include "sysemu/sysemu.h"
 #include "hw/loader.h"
index b7b0ae0..44d00a3 100644 (file)
@@ -521,7 +521,7 @@ static unsigned
 insert_bdisp(unsigned insn, int value, const char **errmsg)
 {
   if (errmsg != (const char **)NULL && (value & 3))
-    *errmsg = "branch operand unaligned";
+    *errmsg = _("branch operand unaligned");
   return insn | ((value / 4) & 0x1FFFFF);
 }
 
@@ -539,7 +539,7 @@ static unsigned
 insert_jhint(unsigned insn, int value, const char **errmsg)
 {
   if (errmsg != (const char **)NULL && (value & 3))
-    *errmsg = "jump hint unaligned";
+    *errmsg = _("jump hint unaligned");
   return insn | ((value / 4) & 0x3FFF);
 }
 
@@ -556,7 +556,7 @@ static unsigned
 insert_ev6hwjhint(unsigned insn, int value, const char **errmsg)
 {
   if (errmsg != (const char **)NULL && (value & 3))
-    *errmsg = "jump hint unaligned";
+    *errmsg = _("jump hint unaligned");
   return insn | ((value / 4) & 0x1FFF);
 }
 
index 426270f..70da529 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "qemu/osdep.h"
 #include "disas/bfd.h"
+#define ATTRIBUTE_UNUSED __attribute__((unused))
 #define ISSPACE(x) ((x) == ' ' || (x) == '\t' || (x) == '\n')
 
 #define ARM_EXT_V1      0
@@ -1816,7 +1817,7 @@ print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
                          func (stream, "e");
                          break;
                        default:
-                         func (stream, "<illegal precision>");
+                         func (stream, _("<illegal precision>"));
                          break;
                        }
                      break;
index 57145d0..c0e717a 100644 (file)
@@ -3406,7 +3406,7 @@ static const struct dis386 three_byte_table[][256] = {
   }
 };
 
-#define INTERNAL_DISASSEMBLER_ERROR "<internal disassembler error>"
+#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
 
 static void
 ckprefix (void)
index 8e7c3f7..8f74ae1 100644 (file)
@@ -1676,7 +1676,7 @@ print_insn_arg (const char *d,
          (*info->fprintf_func) (info->stream, "%%sfc");
        else
          /* xgettext:c-format */
-         (*info->fprintf_func) (info->stream, "<function code %d>", fc);
+         (*info->fprintf_func) (info->stream, _("<function code %d>"), fc);
       }
       break;
 
@@ -1827,7 +1827,7 @@ match_insn_m68k (bfd_vma memaddr,
        {
          info->fprintf_func (info->stream,
                              /* xgettext:c-format */
-                             "<internal error in opcode table: %s %s>\n",
+                             _("<internal error in opcode table: %s %s>\n"),
                              best->name,  best->args);
          info->fprintf_func = save_printer;
          info->print_address_func = save_print_address;
index 97f661a..249931b 100644 (file)
@@ -4257,7 +4257,7 @@ print_insn_args (const char *d,
            case '\0':
              /* xgettext:c-format */
              (*info->fprintf_func) (info->stream,
-                                    "# internal error, incomplete extension sequence (+)");
+                                    _("# internal error, incomplete extension sequence (+)"));
              return;
 
            case 'A':
@@ -4515,7 +4515,7 @@ print_insn_args (const char *d,
            default:
              /* xgettext:c-format */
              (*info->fprintf_func) (info->stream,
-                                    "# internal error, undefined extension sequence (+%c)",
+                                    _("# internal error, undefined extension sequence (+%c)"),
                                     *d);
              return;
            }
@@ -4875,7 +4875,7 @@ print_insn_args (const char *d,
        default:
          /* xgettext:c-format */
          (*info->fprintf_func) (info->stream,
-                                "# internal error, undefined modifier(%c)",
+                                _("# internal error, undefined modifier(%c)"),
                                 *d);
          return;
        }
@@ -5739,7 +5739,7 @@ print_mips16_insn_arg (char type,
       /* xgettext:c-format */
       (*info->fprintf_func)
        (info->stream,
-        "# internal disassembler error, unrecognised modifier (%c)",
+        _("# internal disassembler error, unrecognised modifier (%c)"),
         type);
       abort ();
     }
@@ -5750,51 +5750,51 @@ print_mips_disassembler_options (FILE *stream)
 {
   unsigned int i;
 
-  fprintf (stream, "\n\
+  fprintf (stream, _("\n\
 The following MIPS specific disassembler options are supported for use\n\
-with the -M switch (multiple options should be separated by commas):\n");
+with the -M switch (multiple options should be separated by commas):\n"));
 
-  fprintf (stream, "\n\
+  fprintf (stream, _("\n\
   gpr-names=ABI            Print GPR names according to  specified ABI.\n\
-                           Default: based on binary being disassembled.\n");
+                           Default: based on binary being disassembled.\n"));
 
-  fprintf (stream, "\n\
+  fprintf (stream, _("\n\
   fpr-names=ABI            Print FPR names according to specified ABI.\n\
-                           Default: numeric.\n");
+                           Default: numeric.\n"));
 
-  fprintf (stream, "\n\
+  fprintf (stream, _("\n\
   cp0-names=ARCH           Print CP0 register names according to\n\
                            specified architecture.\n\
-                           Default: based on binary being disassembled.\n");
+                           Default: based on binary being disassembled.\n"));
 
-  fprintf (stream, "\n\
+  fprintf (stream, _("\n\
   hwr-names=ARCH           Print HWR names according to specified\n\
                           architecture.\n\
-                           Default: based on binary being disassembled.\n");
+                           Default: based on binary being disassembled.\n"));
 
-  fprintf (stream, "\n\
+  fprintf (stream, _("\n\
   reg-names=ABI            Print GPR and FPR names according to\n\
-                           specified ABI.\n");
+                           specified ABI.\n"));
 
-  fprintf (stream, "\n\
+  fprintf (stream, _("\n\
   reg-names=ARCH           Print CP0 register and HWR names according to\n\
-                           specified architecture.\n");
+                           specified architecture.\n"));
 
-  fprintf (stream, "\n\
+  fprintf (stream, _("\n\
   For the options above, the following values are supported for \"ABI\":\n\
-   ");
+   "));
   for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
     fprintf (stream, " %s", mips_abi_choices[i].name);
-  fprintf (stream, "\n");
+  fprintf (stream, _("\n"));
 
-  fprintf (stream, "\n\
+  fprintf (stream, _("\n\
   For the options above, The following values are supported for \"ARCH\":\n\
-   ");
+   "));
   for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
     if (*mips_arch_choices[i].name != '\0')
       fprintf (stream, " %s", mips_arch_choices[i].name);
-  fprintf (stream, "\n");
+  fprintf (stream, _("\n"));
 
-  fprintf (stream, "\n");
+  fprintf (stream, _("\n"));
 }
 #endif
index 052cebe..478332b 100644 (file)
@@ -1120,7 +1120,7 @@ insert_bo (unsigned long insn,
           const char **errmsg)
 {
   if (!valid_bo (value, dialect, 0))
-    *errmsg = "invalid conditional option";
+    *errmsg = _("invalid conditional option");
   return insn | ((value & 0x1f) << 21);
 }
 
@@ -1148,9 +1148,9 @@ insert_boe (unsigned long insn,
            const char **errmsg)
 {
   if (!valid_bo (value, dialect, 0))
-    *errmsg = "invalid conditional option";
+    *errmsg = _("invalid conditional option");
   else if ((value & 1) != 0)
-    *errmsg = "attempt to set y bit when using + or - modifier";
+    *errmsg = _("attempt to set y bit when using + or - modifier");
 
   return insn | ((value & 0x1f) << 21);
 }
@@ -1182,7 +1182,7 @@ insert_fxm (unsigned long insn,
     {
       if (value == 0 || (value & -value) != value)
        {
-         *errmsg = "invalid mask field";
+         *errmsg = _("invalid mask field");
          value = 0;
        }
     }
@@ -1208,7 +1208,7 @@ insert_fxm (unsigned long insn,
   /* Any other value on mfcr is an error.  */
   else if ((insn & (0x3ff << 1)) == 19 << 1)
     {
-      *errmsg = "ignoring invalid mfcr mask";
+      *errmsg = _("ignoring invalid mfcr mask");
       value = 0;
     }
 
@@ -1258,7 +1258,7 @@ insert_mbe (unsigned long insn,
 
   if (uval == 0)
     {
-      *errmsg = "illegal bitmask";
+      *errmsg = _("illegal bitmask");
       return insn;
     }
 
@@ -1293,7 +1293,7 @@ insert_mbe (unsigned long insn,
     me = 32;
 
   if (count != 2 && (count != 0 || ! last))
-    *errmsg = "illegal bitmask";
+    *errmsg = _("illegal bitmask");
 
   return insn | (mb << 6) | ((me - 1) << 1);
 }
@@ -1413,7 +1413,7 @@ insert_ram (unsigned long insn,
            const char **errmsg)
 {
   if ((unsigned long) value >= ((insn >> 21) & 0x1f))
-    *errmsg = "index register in load range";
+    *errmsg = _("index register in load range");
   return insn | ((value & 0x1f) << 16);
 }
 
@@ -1429,7 +1429,7 @@ insert_raq (unsigned long insn,
   long rtvalue = (insn & RT_MASK) >> 21;
 
   if (value == rtvalue)
-    *errmsg = "source and target register operands must be different";
+    *errmsg = _("source and target register operands must be different");
   return insn | ((value & 0x1f) << 16);
 }
 
@@ -1444,7 +1444,7 @@ insert_ras (unsigned long insn,
            const char **errmsg)
 {
   if (value == 0)
-    *errmsg = "invalid register operand when updating";
+    *errmsg = _("invalid register operand when updating");
   return insn | ((value & 0x1f) << 16);
 }
 
@@ -1526,7 +1526,7 @@ insert_sprg (unsigned long insn,
   if (value > 7
       || (value > 3
          && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0))
-    *errmsg = "invalid sprg number";
+    *errmsg = _("invalid sprg number");
 
   /* If this is mfsprg4..7 then use spr 260..263 which can be read in
      user mode.  Anything else must use spr 272..279.  */
index f120f4e..64bba8d 100644 (file)
@@ -2494,7 +2494,7 @@ compare_opcodes (const void * a, const void * b)
       fprintf
         (stderr,
          /* xgettext:c-format */
-         "Internal error:  bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
+         _("Internal error:  bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
          op0->name, match0, lose0);
       op0->lose &= ~op0->match;
       lose0 = op0->lose;
@@ -2505,7 +2505,7 @@ compare_opcodes (const void * a, const void * b)
       fprintf
         (stderr,
          /* xgettext:c-format */
-         "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
+         _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
          op1->name, match1, lose1);
       op1->lose &= ~op1->match;
       lose1 = op1->lose;
@@ -2555,7 +2555,7 @@ compare_opcodes (const void * a, const void * b)
       else
         fprintf (stderr,
                  /* xgettext:c-format */
-                 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
+                 _("Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"),
                  op0->name, op1->name);
     }
 
index 9defc10..4ad0bca 100644 (file)
@@ -70,17 +70,16 @@ void qemu_sglist_destroy(QEMUSGList *qsg)
 
 typedef struct {
     BlockAIOCB common;
-    AioContext *ctx;
+    BlockBackend *blk;
     BlockAIOCB *acb;
     QEMUSGList *sg;
-    uint64_t offset;
+    uint64_t sector_num;
     DMADirection dir;
     int sg_cur_index;
     dma_addr_t sg_cur_byte;
     QEMUIOVector iov;
     QEMUBH *bh;
     DMAIOFunc *io_func;
-    void *io_func_opaque;
 } DMAAIOCB;
 
 static void dma_blk_cb(void *opaque, int ret);
@@ -131,7 +130,7 @@ static void dma_blk_cb(void *opaque, int ret)
     trace_dma_blk_cb(dbs, ret);
 
     dbs->acb = NULL;
-    dbs->offset += dbs->iov.size;
+    dbs->sector_num += dbs->iov.size / 512;
 
     if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {
         dma_complete(dbs, ret);
@@ -155,7 +154,8 @@ static void dma_blk_cb(void *opaque, int ret)
 
     if (dbs->iov.size == 0) {
         trace_dma_map_wait(dbs);
-        dbs->bh = aio_bh_new(dbs->ctx, reschedule_dma, dbs);
+        dbs->bh = aio_bh_new(blk_get_aio_context(dbs->blk),
+                             reschedule_dma, dbs);
         cpu_register_map_client(dbs->bh);
         return;
     }
@@ -164,8 +164,8 @@ static void dma_blk_cb(void *opaque, int ret)
         qemu_iovec_discard_back(&dbs->iov, dbs->iov.size & ~BDRV_SECTOR_MASK);
     }
 
-    dbs->acb = dbs->io_func(dbs->offset, &dbs->iov,
-                            dma_blk_cb, dbs, dbs->io_func_opaque);
+    dbs->acb = dbs->io_func(dbs->blk, dbs->sector_num, &dbs->iov,
+                            dbs->iov.size / 512, dma_blk_cb, dbs);
     assert(dbs->acb);
 }
 
@@ -185,38 +185,29 @@ static void dma_aio_cancel(BlockAIOCB *acb)
     }
 }
 
-static AioContext *dma_get_aio_context(BlockAIOCB *acb)
-{
-    DMAAIOCB *dbs = container_of(acb, DMAAIOCB, common);
-
-    return dbs->ctx;
-}
 
 static const AIOCBInfo dma_aiocb_info = {
     .aiocb_size         = sizeof(DMAAIOCB),
     .cancel_async       = dma_aio_cancel,
-    .get_aio_context    = dma_get_aio_context,
 };
 
-BlockAIOCB *dma_blk_io(AioContext *ctx,
-    QEMUSGList *sg, uint64_t offset,
-    DMAIOFunc *io_func, void *io_func_opaque,
-    BlockCompletionFunc *cb,
+BlockAIOCB *dma_blk_io(
+    BlockBackend *blk, QEMUSGList *sg, uint64_t sector_num,
+    DMAIOFunc *io_func, BlockCompletionFunc *cb,
     void *opaque, DMADirection dir)
 {
-    DMAAIOCB *dbs = qemu_aio_get(&dma_aiocb_info, NULL, cb, opaque);
+    DMAAIOCB *dbs = blk_aio_get(&dma_aiocb_info, blk, cb, opaque);
 
-    trace_dma_blk_io(dbs, io_func_opaque, offset, (dir == DMA_DIRECTION_TO_DEVICE));
+    trace_dma_blk_io(dbs, blk, sector_num, (dir == DMA_DIRECTION_TO_DEVICE));
 
     dbs->acb = NULL;
+    dbs->blk = blk;
     dbs->sg = sg;
-    dbs->ctx = ctx;
-    dbs->offset = offset;
+    dbs->sector_num = sector_num;
     dbs->sg_cur_index = 0;
     dbs->sg_cur_byte = 0;
     dbs->dir = dir;
     dbs->io_func = io_func;
-    dbs->io_func_opaque = io_func_opaque;
     dbs->bh = NULL;
     qemu_iovec_init(&dbs->iov, sg->nsg);
     dma_blk_cb(dbs, 0);
@@ -224,39 +215,19 @@ BlockAIOCB *dma_blk_io(AioContext *ctx,
 }
 
 
-static
-BlockAIOCB *dma_blk_read_io_func(int64_t offset, QEMUIOVector *iov,
-                                 BlockCompletionFunc *cb, void *cb_opaque,
-                                 void *opaque)
-{
-    BlockBackend *blk = opaque;
-    return blk_aio_preadv(blk, offset, iov, 0, cb, cb_opaque);
-}
-
 BlockAIOCB *dma_blk_read(BlockBackend *blk,
-                         QEMUSGList *sg, uint64_t offset,
+                         QEMUSGList *sg, uint64_t sector,
                          void (*cb)(void *opaque, int ret), void *opaque)
 {
-    return dma_blk_io(blk_get_aio_context(blk),
-                      sg, offset, dma_blk_read_io_func, blk, cb, opaque,
+    return dma_blk_io(blk, sg, sector, blk_aio_readv, cb, opaque,
                       DMA_DIRECTION_FROM_DEVICE);
 }
 
-static
-BlockAIOCB *dma_blk_write_io_func(int64_t offset, QEMUIOVector *iov,
-                                  BlockCompletionFunc *cb, void *cb_opaque,
-                                  void *opaque)
-{
-    BlockBackend *blk = opaque;
-    return blk_aio_pwritev(blk, offset, iov, 0, cb, cb_opaque);
-}
-
 BlockAIOCB *dma_blk_write(BlockBackend *blk,
-                          QEMUSGList *sg, uint64_t offset,
+                          QEMUSGList *sg, uint64_t sector,
                           void (*cb)(void *opaque, int ret), void *opaque)
 {
-    return dma_blk_io(blk_get_aio_context(blk),
-                      sg, offset, dma_blk_write_io_func, blk, cb, opaque,
+    return dma_blk_io(blk, sg, sector, blk_aio_writev, cb, opaque,
                       DMA_DIRECTION_TO_DEVICE);
 }
 
index c95950b..ef285e3 100644 (file)
@@ -62,7 +62,7 @@ operations:
     typeof(*ptr) atomic_fetch_sub(ptr, val)
     typeof(*ptr) atomic_fetch_and(ptr, val)
     typeof(*ptr) atomic_fetch_or(ptr, val)
-    typeof(*ptr) atomic_xchg(ptr, val)
+    typeof(*ptr) atomic_xchg(ptr, val
     typeof(*ptr) atomic_cmpxchg(ptr, old, new)
 
 all of which return the old value of *ptr.  These operations are
@@ -326,41 +326,21 @@ and memory barriers, and the equivalents in QEMU:
   use a boxed atomic_t type; atomic operations in QEMU are polymorphic
   and use normal C types.
 
-- Originally, atomic_read and atomic_set in Linux gave no guarantee
-  at all. Linux 4.1 updated them to implement volatile
-  semantics via ACCESS_ONCE (or the more recent READ/WRITE_ONCE).
+- atomic_read and atomic_set in Linux give no guarantee at all;
+  atomic_read and atomic_set in QEMU include a compiler barrier
+  (similar to the ACCESS_ONCE macro in Linux).
 
-  QEMU's atomic_read/set implement, if the compiler supports it, C11
-  atomic relaxed semantics, and volatile semantics otherwise.
-  Both semantics prevent the compiler from doing certain transformations;
-  the difference is that atomic accesses are guaranteed to be atomic,
-  while volatile accesses aren't. Thus, in the volatile case we just cross
-  our fingers hoping that the compiler will generate atomic accesses,
-  since we assume the variables passed are machine-word sized and
-  properly aligned.
-  No barriers are implied by atomic_read/set in either Linux or QEMU.
-
-- atomic read-modify-write operations in Linux are of three kinds:
-
-         atomic_OP          returns void
-         atomic_OP_return   returns new value of the variable
-         atomic_fetch_OP    returns the old value of the variable
-         atomic_cmpxchg     returns the old value of the variable
-
-  In QEMU, the second kind does not exist.  Currently Linux has
-  atomic_fetch_or only.  QEMU provides and, or, inc, dec, add, sub.
+- most atomic read-modify-write operations in Linux return void;
+  in QEMU, all of them return the old value of the variable.
 
 - different atomic read-modify-write operations in Linux imply
   a different set of memory barriers; in QEMU, all of them enforce
   sequential consistency, which means they imply full memory barriers
   before and after the operation.
 
-- Linux does not have an equivalent of atomic_mb_set().  In particular,
-  note that smp_store_mb() is a little weaker than atomic_mb_set().
-  atomic_mb_read() compiles to the same instructions as Linux's
-  smp_load_acquire(), but this should be treated as an implementation
-  detail.  If required, QEMU might later add atomic_load_acquire() and
-  atomic_store_release() macros.
+- Linux does not have an equivalent of atomic_mb_read() and
+  atomic_mb_set().  In particular, note that set_mb() is a little
+  weaker than atomic_mb_set().
 
 
 SOURCES
index 2af1e66..5ddddea 100644 (file)
@@ -438,11 +438,6 @@ top level Makefile, so anything defined in this file will influence the
 entire build system. Care needs to be taken when writing rules for tests
 to ensure they only apply to the unit test execution / build.
 
-- tests/docker/Makefile.include
-
-Rules for Docker tests. Like tests/Makefile, this file is included
-directly by the top level Makefile, anything defined in this file will
-influence the entire build system.
 
 - po/Makefile
 
diff --git a/docs/igd-assign.txt b/docs/igd-assign.txt
deleted file mode 100644 (file)
index e17bb50..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-Intel Graphics Device (IGD) assignment with vfio-pci
-====================================================
-
-IGD has two different modes for assignment using vfio-pci:
-
-1) Universal Pass-Through (UPT) mode:
-
-   In this mode the IGD device is added as a *secondary* (ie. non-primary)
-   graphics device in combination with an emulated primary graphics device.
-   This mode *requires* guest driver support to remove the external
-   dependencies generally associated with IGD (see below).  Those guest
-   drivers only support this mode for Broadwell and newer IGD, according to
-   Intel.  Additionally, this mode by default, and as officially supported
-   by Intel, does not support direct video output.  The intention is to use
-   this mode either to provide hardware acceleration to the emulated graphics
-   or to use this mode in combination with guest-based remote access software,
-   for example VNC (see below for optional output support).  This mode
-   theoretically has no device specific handling dependencies on vfio-pci or
-   the VM firmware.
-
-2) "Legacy" mode:
-
-   In this mode the IGD device is intended to be the primary and exclusive
-   graphics device in the VM[1], as such QEMU does not facilitate any sort
-   of remote graphics to the VM in this mode.  A connected physical monitor
-   is the intended output device for IGD.  This mode includes several
-   requirements and restrictions:
-
-    * IGD must be given address 02.0 on the PCI root bus in the VM
-    * The host kernel must support vfio extensions for IGD (v4.6)
-    * vfio VGA support very likely needs to be enabled in the host kernel
-    * The VM firmware must support specific fw_cfg enablers for IGD
-    * The VM machine type must support a PCI host bridge at 00.0 (standard)
-    * The VM machine type must provide or allow to be created a special
-      ISA/LPC bridge device (vfio-pci-igd-lpc-bridge) on the root bus at
-      PCI address 1f.0.
-    * The IGD device must have a VGA ROM, either provided via the romfile
-      option or loaded automatically through vfio (standard).  rombar=0
-      will disable legacy mode support.
-    * Hotplug of the IGD device is not supported.
-    * The IGD device must be a SandyBridge or newer model device.
-
-For either mode, depending on the host kernel, the i915 driver in the host
-may generate faults and errors upon re-binding to an IGD device after it
-has been assigned to a VM.  It's therefore generally recommended to prevent
-such driver binding unless the host driver is known to work well for this.
-There are numerous ways to do this, i915 can be blacklisted on the host,
-the driver_override option can be used to ensure that only vfio-pci can bind
-to the device on the host[2], virsh nodedev-detach can be used to bind the
-device to vfio drivers and then managed='no' set in the VM xml to prevent
-re-binding to i915, etc.  Also note that IGD is also typically the primary
-graphics in the host and special options may be required beyond simply
-blacklisting i915 or using pci-stub/vfio-pci to take ownership of IGD as a
-PCI class device.  Lower level drivers exist that may still claim the device.
-It may therefore be necessary to use kernel boot options video=vesafb:off or
-video=efifb:off (depending on host BIOS/UEFI) or these can be combined to
-a catch-all, video=vesafb:off,efifb:off.  Error messages such as:
-
-    Failed to mmap 0000:00:02.0 BAR <>. Performance may be slow
-
-are a good indicator that such a problem exists.  The host files /proc/iomem
-and /proc/ioports are often useful for identifying drivers consuming ranges
-of the device to cause such conflicts.
-
-Additionally, IGD device are known to generate small numbers of DMAR faults
-when initially assigned.  It is believed that this is simply the IGD attempting
-to access the reserved GTT space after reset, which it no longer has access to
-when accessed from userspace.  So long as the DMAR faults are small in number
-and most importantly, not ongoing, these are not an indication of an error.
-
-Additionally++, analog VGA output (as opposed to digital outputs like HDMI,
-DVI, or DisplayPort) may be unsupported in some use cases.  In the author's
-experience, even DP to VGA adapters can be troublesome while adapters between
-digital formats work well.
-
-Usage
-=====
-The intention is for IGD assignment to be transparent for users and thus for
-management tools like libvirt.  To make use of legacy mode, simply remove all
-other graphics options and use "-nographic" and either "-vga none" or
-"-nodefaults", along with adding the device using vfio-pci:
-
-    -device vfio-pci,host=00:02.0,id=hostdev0,bus=pci.0,addr=0x2
-
-For UPT mode, retain the default emulated graphics and simply add the vfio-pci
-device making use of any other bus address other than 02.0.  libvirt will
-default to assigning the device a UPT compatible address while legacy mode
-users will need to manually edit the XML if using a tool like virt-manager
-where the VM device address is not expressly specified.
-
-An experimental vfio-pci option also exists to enable OpRegion, and thus
-external monitor support, for UPT mode.  This can be enabled by adding
-"x-igd-opregion=on" to the vfio-pci device options for the IGD device.  As
-with legacy mode, this requires the host to support features introduced in
-the v4.6 kernel.  If Intel chooses to embrace this support, the option may
-be made non-experimental in the future, opening it to libvirt support.
-
-Developer ABI
-=============
-Legacy mode IGD support imposes two fw_cfg requirements on the VM firmware:
-
-1) "etc/igd-opregion"
-
-   This fw_cfg file exposes the OpRegion for the IGD device.  A reserved
-   region should be created below 4GB (recommended 4KB alignment), sized
-   sufficient for the fw_cfg file size, and the content of this file copied
-   to it.  The dword based address of this reserved memory region must also
-   be written to the ASLS register at offset 0xFC on the IGD device.  It is
-   recommended that firmware should make use of this fw_cfg entry for any
-   PCI class VGA device with Intel vendor ID.  Multiple of such devices
-   within a VM is undefined.
-
-2) "etc/igd-bdsm-size"
-
-   This fw_cfg file contains an 8-byte, little endian integer indicating
-   the size of the reserved memory region required for IGD stolen memory.
-   Firmware must allocate a reserved memory below 4GB with required 1MB
-   alignment equal to this size.  Additionally the base address of this
-   reserved region must be written to the dword BDSM register in PCI config
-   space of the IGD device at offset 0x5C.  As this support is related to
-   running the IGD ROM, which has other dependencies on the device appearing
-   at guest address 00:02.0, it's expected that this fw_cfg file is only
-   relevant to a single PCI class VGA device with Intel vendor ID, appearing
-   at PCI bus address 00:02.0.
-
-Footnotes
-=========
-[1] Nothing precludes adding additional emulated or assigned graphics devices
-    as non-primary, other than the combination typically not working.  I only
-    intend to set user expectations, others are welcome to find working
-    combinations or fix whatever issues prevent this from working in the common
-    case.
-[2] # echo "vfio-pci" > /sys/bus/pci/devices/0000:00:02.0/driver_override
index 811b1bd..431d9ca 100644 (file)
@@ -41,13 +41,8 @@ MemoryRegion):
   MemoryRegionOps structure describing the callbacks.
 
 - ROM: a ROM memory region works like RAM for reads (directly accessing
-  a region of host memory), and forbids writes. You initialize these with
-  memory_region_init_rom().
-
-- ROM device: a ROM device memory region works like RAM for reads
-  (directly accessing a region of host memory), but like MMIO for
-  writes (invoking a callback).  You initialize these with
-  memory_region_init_rom_device().
+  a region of host memory), but like MMIO for writes (invoking a callback).
+  You initialize these with memory_region_init_rom_device().
 
 - IOMMU region: an IOMMU region translates addresses of accesses made to it
   and forwards them to some other target memory region.  As the name suggests,
index 6503c17..90209ab 100644 (file)
@@ -403,8 +403,8 @@ listen thread:                     --- page -- page -- page -- page -- page --
 
 On receipt of CMD_PACKAGED (1)
    All the data associated with the package - the ( ... ) section in the
-diagram - is read into memory, and the main thread recurses into
-qemu_loadvm_state_main to process the contents of the package (2)
+diagram - is read into memory (into a QEMUSizedBuffer), and the main thread
+recurses into qemu_loadvm_state_main to process the contents of the package (2)
 which contains commands (3,6) and devices (4...)
 
 On receipt of 'postcopy listen' - 3 -(i.e. the 1st command in the package)
index d0caaf7..3d477c3 100644 (file)
@@ -110,7 +110,7 @@ Usage
 =====
 1. Verify both the source and destination QEMU are able
 to support the multiple thread compression migration:
-    {qemu} info migrate_capabilities
+    {qemu} info_migrate_capabilities
     {qemu} ... compress: off ...
 
 2. Activate compression on the source:
index de298dc..0e4baff 100644 (file)
@@ -322,7 +322,7 @@ enum.  The value for each branch can be of any type.
 
 A flat union definition avoids nesting on the wire, and specifies a
 set of common members that occur in all variants of the union.  The
-'base' key must specify either a type name (the type must be a
+'base' key must specifiy either a type name (the type must be a
 struct, not a union), or a dictionary representing an anonymous type.
 All branches of the union must be complex types, and the top-level
 members of the union dictionary on the wire will be combination of
@@ -410,7 +410,7 @@ following example objects:
 === Commands ===
 
 Usage: { 'command': STRING, '*data': COMPLEX-TYPE-NAME-OR-DICT,
-         '*returns': TYPE-NAME, '*boxed': true,
+         '*returns': TYPE-NAME,
          '*gen': false, '*success-response': false }
 
 Commands are defined by using a dictionary containing several members,
@@ -461,20 +461,6 @@ which would validate this Client JSON Protocol transaction:
  => { "execute": "my-second-command" }
  <= { "return": [ { "value": "one" }, { } ] }
 
-The generator emits a prototype for the user's function implementing
-the command.  Normally, 'data' is a dictionary for an anonymous type,
-or names a struct type (possibly empty, but not a union), and its
-members are passed as separate arguments to this function.  If the
-command definition includes a key 'boxed' with the boolean value true,
-then 'data' is instead the name of any non-empty complex type
-(struct, union, or alternate), and a pointer to that QAPI type is
-passed as a single argument.
-
-The generator also emits a marshalling function that extracts
-arguments for the user's function out of an input QDict, calls the
-user's function, and if it succeeded, builds an output QObject from
-its return value.
-
 In rare cases, QAPI cannot express a type-safe representation of a
 corresponding Client JSON Protocol command.  You then have to suppress
 generation of a marshalling function by including a key 'gen' with
@@ -498,8 +484,7 @@ use of this member.
 
 === Events ===
 
-Usage: { 'event': STRING, '*data': COMPLEX-TYPE-NAME-OR-DICT,
-         '*boxed': true }
+Usage: { 'event': STRING, '*data': COMPLEX-TYPE-NAME-OR-DICT }
 
 Events are defined with the keyword 'event'.  It is not allowed to
 name an event 'MAX', since the generator also produces a C enumeration
@@ -520,14 +505,6 @@ Resulting in this JSON object:
   "data": { "b": "test string" },
   "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
 
-The generator emits a function to send the event.  Normally, 'data' is
-a dictionary for an anonymous type, or names a struct type (possibly
-empty, but not a union), and its members are passed as separate
-arguments to this function.  If the event definition includes a key
-'boxed' with the boolean value true, then 'data' is instead the name of
-any non-empty complex type (struct, union, or alternate), and a
-pointer to that QAPI type is passed as a single argument.
-
 
 == Client JSON Protocol introspection ==
 
@@ -825,28 +802,32 @@ Example:
 
     void qapi_free_UserDefOne(UserDefOne *obj)
     {
+        QapiDeallocVisitor *qdv;
         Visitor *v;
 
         if (!obj) {
             return;
         }
 
-        v = qapi_dealloc_visitor_new();
+        qdv = qapi_dealloc_visitor_new();
+        v = qapi_dealloc_get_visitor(qdv);
         visit_type_UserDefOne(v, NULL, &obj, NULL);
-        visit_free(v);
+        qapi_dealloc_visitor_cleanup(qdv);
     }
 
     void qapi_free_UserDefOneList(UserDefOneList *obj)
     {
+        QapiDeallocVisitor *qdv;
         Visitor *v;
 
         if (!obj) {
             return;
         }
 
-        v = qapi_dealloc_visitor_new();
+        qdv = qapi_dealloc_visitor_new();
+        v = qapi_dealloc_get_visitor(qdv);
         visit_type_UserDefOneList(v, NULL, &obj, NULL);
-        visit_free(v);
+        qapi_dealloc_visitor_cleanup(qdv);
     }
 
 === scripts/qapi-visit.py ===
@@ -918,16 +899,10 @@ Example:
             goto out_obj;
         }
         visit_type_UserDefOne_members(v, *obj, &err);
-        if (err) {
-            goto out_obj;
-        }
-        visit_check_struct(v, &err);
+        error_propagate(errp, err);
+        err = NULL;
     out_obj:
-        visit_end_struct(v, (void **)obj);
-        if (err && visit_is_input(v)) {
-            qapi_free_UserDefOne(*obj);
-            *obj = NULL;
-        }
+        visit_end_struct(v, &err);
     out:
         error_propagate(errp, err);
     }
@@ -935,27 +910,21 @@ Example:
     void visit_type_UserDefOneList(Visitor *v, const char *name, UserDefOneList **obj, Error **errp)
     {
         Error *err = NULL;
-        UserDefOneList *tail;
-        size_t size = sizeof(**obj);
+        GenericList *i, **prev;
 
-        visit_start_list(v, name, (GenericList **)obj, size, &err);
+        visit_start_list(v, name, &err);
         if (err) {
             goto out;
         }
 
-        for (tail = *obj; tail;
-             tail = (UserDefOneList *)visit_next_list(v, (GenericList *)tail, size)) {
-            visit_type_UserDefOne(v, NULL, &tail->value, &err);
-            if (err) {
-                break;
-            }
+        for (prev = (GenericList **)obj;
+             !err && (i = visit_next_list(v, prev, sizeof(**obj))) != NULL;
+             prev = &i) {
+            UserDefOneList *native_i = (UserDefOneList *)i;
+            visit_type_UserDefOne(v, NULL, &native_i->value, &err);
         }
 
-        visit_end_list(v, (void **)obj);
-        if (err && visit_is_input(v)) {
-            qapi_free_UserDefOneList(*obj);
-            *obj = NULL;
-        }
+        visit_end_list(v);
     out:
         error_propagate(errp, err);
     }
@@ -1003,37 +972,37 @@ Example:
     static void qmp_marshal_output_UserDefOne(UserDefOne *ret_in, QObject **ret_out, Error **errp)
     {
         Error *err = NULL;
+        QmpOutputVisitor *qov = qmp_output_visitor_new();
+        QapiDeallocVisitor *qdv;
         Visitor *v;
 
-        v = qmp_output_visitor_new(ret_out);
+        v = qmp_output_get_visitor(qov);
         visit_type_UserDefOne(v, "unused", &ret_in, &err);
-        if (!err) {
-            visit_complete(v, ret_out);
+        if (err) {
+            goto out;
         }
+        *ret_out = qmp_output_get_qobject(qov);
+
+    out:
         error_propagate(errp, err);
-        visit_free(v);
-        v = qapi_dealloc_visitor_new();
+        qmp_output_visitor_cleanup(qov);
+        qdv = qapi_dealloc_visitor_new();
+        v = qapi_dealloc_get_visitor(qdv);
         visit_type_UserDefOne(v, "unused", &ret_in, NULL);
-        visit_free(v);
+        qapi_dealloc_visitor_cleanup(qdv);
     }
 
     static void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp)
     {
         Error *err = NULL;
         UserDefOne *retval;
+        QmpInputVisitor *qiv = qmp_input_visitor_new_strict(QOBJECT(args));
+        QapiDeallocVisitor *qdv;
         Visitor *v;
         UserDefOneList *arg1 = NULL;
 
-        v = qmp_input_visitor_new(QOBJECT(args), true);
-        visit_start_struct(v, NULL, NULL, 0, &err);
-        if (err) {
-            goto out;
-        }
+        v = qmp_input_get_visitor(qiv);
         visit_type_UserDefOneList(v, "arg1", &arg1, &err);
-        if (!err) {
-            visit_check_struct(v, &err);
-        }
-        visit_end_struct(v, NULL);
         if (err) {
             goto out;
         }
@@ -1047,12 +1016,11 @@ Example:
 
     out:
         error_propagate(errp, err);
-        visit_free(v);
-        v = qapi_dealloc_visitor_new();
-        visit_start_struct(v, NULL, NULL, 0, NULL);
+        qmp_input_visitor_cleanup(qiv);
+        qdv = qapi_dealloc_visitor_new();
+        v = qapi_dealloc_get_visitor(qdv);
         visit_type_UserDefOneList(v, "arg1", &arg1, NULL);
-        visit_end_struct(v, NULL);
-        visit_free(v);
+        qapi_dealloc_visitor_cleanup(qdv);
     }
 
     static void qmp_init_marshal(void)
index 7967ec4..fa7574d 100644 (file)
@@ -92,8 +92,7 @@ Data:
 
 - "type":     Job type (json-string; "stream" for image streaming
                                      "commit" for block commit)
-- "device":   Job identifier. Originally the device name but other
-              values are allowed since QEMU 2.7 (json-string)
+- "device":   Device name (json-string)
 - "len":      Maximum progress value (json-int)
 - "offset":   Current progress value (json-int)
               On success this is equal to len.
@@ -117,8 +116,7 @@ Data:
 
 - "type":     Job type (json-string; "stream" for image streaming
                                      "commit" for block commit)
-- "device":   Job identifier. Originally the device name but other
-              values are allowed since QEMU 2.7 (json-string)
+- "device":   Device name (json-string)
 - "len":      Maximum progress value (json-int)
 - "offset":   Current progress value (json-int)
               On success this is equal to len.
@@ -145,8 +143,7 @@ Emitted when a block job encounters an error.
 
 Data:
 
-- "device": Job identifier. Originally the device name but other
-            values are allowed since QEMU 2.7 (json-string)
+- "device": device name (json-string)
 - "operation": I/O operation (json-string, "read" or "write")
 - "action": action that has been taken, it's one of the following (json-string):
     "ignore": error has been ignored, the job may fail later
@@ -170,8 +167,7 @@ Data:
 
 - "type":     Job type (json-string; "stream" for image streaming
                                      "commit" for block commit)
-- "device":   Job identifier. Originally the device name but other
-              values are allowed since QEMU 2.7 (json-string)
+- "device":   Device name (json-string)
 - "len":      Maximum progress value (json-int)
 - "offset":   Current progress value (json-int)
               On success this is equal to len.
index ee219c8..340b751 100644 (file)
@@ -4,91 +4,21 @@ QEMU<->ACPI BIOS CPU hotplug interface
 QEMU supports CPU hotplug via ACPI. This document
 describes the interface between QEMU and the ACPI BIOS.
 
-ACPI BIOS GPE.2 handler is dedicated for notifying OS about CPU hot-add
-and hot-remove events.
+ACPI GPE block (IO ports 0xafe0-0xafe3, byte access):
+-----------------------------------------
+
+Generic ACPI GPE block. Bit 2 (GPE.2) used to notify CPU
+hot-add/remove event to ACPI BIOS, via SCI interrupt.
 
-============================================
-Legacy ACPI CPU hotplug interface registers:
---------------------------------------------
 CPU present bitmap for:
   ICH9-LPC (IO port 0x0cd8-0xcf7, 1-byte access)
   PIIX-PM  (IO port 0xaf00-0xaf1f, 1-byte access)
-  One bit per CPU. Bit position reflects corresponding CPU APIC ID. Read-only.
-  The first DWORD in bitmap is used in write mode to switch from legacy
-  to new CPU hotplug interface, write 0 into it to do switch.
 ---------------------------------------------------------------
-QEMU sets corresponding CPU bit on hot-add event and issues SCI
-with GPE.2 event set. CPU present map is read by ACPI BIOS GPE.2 handler
-to notify OS about CPU hot-add events. CPU hot-remove isn't supported.
-
-=====================================
-ACPI CPU hotplug interface registers:
--------------------------------------
-Register block base address:
-    ICH9-LPC IO port 0x0cd8
-    PIIX-PM  IO port 0xaf00
-Register block size:
-    ACPI_CPU_HOTPLUG_REG_LEN = 12
-
-read access:
-    offset:
-    [0x0-0x3] reserved
-    [0x4] CPU device status fields: (1 byte access)
-        bits:
-           0: Device is enabled and may be used by guest
-           1: Device insert event, used to distinguish device for which
-              no device check event to OSPM was issued.
-              It's valid only when bit 0 is set.
-           2: Device remove event, used to distinguish device for which
-              no device eject request to OSPM was issued.
-           3-7: reserved and should be ignored by OSPM
-    [0x5-0x7] reserved
-    [0x8] Command data: (DWORD access)
-          in case of error or unsupported command reads is 0xFFFFFFFF
-          current 'Command field' value:
-              0: returns PXM value corresponding to device
-
-write access:
-    offset:
-    [0x0-0x3] CPU selector: (DWORD access)
-              selects active CPU device. All following accesses to other
-              registers will read/store data from/to selected CPU.
-    [0x4] CPU device control fields: (1 byte access)
-        bits:
-            0: reserved, OSPM must clear it before writing to register.
-            1: if set to 1 clears device insert event, set by OSPM
-               after it has emitted device check event for the
-               selected CPU device
-            2: if set to 1 clears device remove event, set by OSPM
-               after it has emitted device eject request for the
-               selected CPU device
-            3: if set to 1 initiates device eject, set by OSPM when it
-               triggers CPU device removal and calls _EJ0 method
-            4-7: reserved, OSPM must clear them before writing to register
-    [0x5] Command field: (1 byte access)
-          value:
-            0: selects a CPU device with inserting/removing events and
-               following reads from 'Command data' register return
-               selected CPU (CPU selector value). If no CPU with events
-               found, the current CPU selector doesn't change and
-               corresponding insert/remove event flags are not set.
-            1: following writes to 'Command data' register set OST event
-               register in QEMU
-            2: following writes to 'Command data' register set OST status
-               register in QEMU
-            other values: reserved
-    [0x6-0x7] reserved
-    [0x8] Command data: (DWORD access)
-          current 'Command field' value:
-              0: OSPM reads value of CPU selector
-              1: stores value into OST event register
-              2: stores value into OST status register, triggers
-                 ACPI_DEVICE_OST QMP event from QEMU to external applications
-                 with current values of OST event and status registers.
-            other values: reserved
+One bit per CPU. Bit position reflects corresponding CPU APIC ID.
+Read-only.
 
-Selecting CPU device beyond possible range has no effect on platform:
-   - write accesses to CPU hot-plug registers not documented above are
-     ignored
-   - read accesses to CPU hot-plug registers not documented above return
-     all bits set to 0.
+CPU hot-add/remove notification:
+-----------------------------------------------------
+QEMU sets/clears corresponding CPU bit on hot-add/remove event.
+CPU present map read by ACPI BIOS GPE.2 handler to notify OS of CPU
+hot-(un)plug events.
diff --git a/docs/specs/acpi_nvdimm.txt b/docs/specs/acpi_nvdimm.txt
deleted file mode 100644 (file)
index 0fdd251..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-QEMU<->ACPI BIOS NVDIMM interface
----------------------------------
-
-QEMU supports NVDIMM via ACPI. This document describes the basic concepts of
-NVDIMM ACPI and the interface between QEMU and the ACPI BIOS.
-
-NVDIMM ACPI Background
-----------------------
-NVDIMM is introduced in ACPI 6.0 which defines an NVDIMM root device under
-_SB scope with a _HID of “ACPI0012”. For each NVDIMM present or intended
-to be supported by platform, platform firmware also exposes an ACPI
-Namespace Device under the root device.
-
-The NVDIMM child devices under the NVDIMM root device are defined with _ADR
-corresponding to the NFIT device handle. The NVDIMM root device and the
-NVDIMM devices can have device specific methods (_DSM) to provide additional
-functions specific to a particular NVDIMM implementation.
-
-This is an example from ACPI 6.0, a platform contains one NVDIMM:
-
-Scope (\_SB){
-   Device (NVDR) // Root device
-   {
-      Name (_HID, “ACPI0012”)
-      Method (_STA) {...}
-      Method (_FIT) {...}
-      Method (_DSM, ...) {...}
-      Device (NVD)
-      {
-         Name(_ADR, h) //where h is NFIT Device Handle for this NVDIMM
-         Method (_DSM, ...) {...}
-      }
-   }
-}
-
-Method supported on both NVDIMM root device and NVDIMM device
-_DSM (Device Specific Method)
-   It is a control method that enables devices to provide device specific
-   control functions that are consumed by the device driver.
-   The NVDIMM DSM specification can be found at:
-        http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf
-
-   Arguments:
-   Arg0 – A Buffer containing a UUID (16 Bytes)
-   Arg1 – An Integer containing the Revision ID (4 Bytes)
-   Arg2 – An Integer containing the Function Index (4 Bytes)
-   Arg3 – A package containing parameters for the function specified by the
-          UUID, Revision ID, and Function Index
-
-   Return Value:
-   If Function Index = 0, a Buffer containing a function index bitfield.
-   Otherwise, the return value and type depends on the UUID, revision ID
-   and function index which are described in the DSM specification.
-
-Methods on NVDIMM ROOT Device
-_FIT(Firmware Interface Table)
-   It evaluates to a buffer returning data in the format of a series of NFIT
-   Type Structure.
-
-   Arguments: None
-
-   Return Value:
-   A Buffer containing a list of NFIT Type structure entries.
-
-   The detailed definition of the structure can be found at ACPI 6.0: 5.2.25
-   NVDIMM Firmware Interface Table (NFIT).
-
-QEMU NVDIMM Implemention
-========================
-QEMU uses 4 bytes IO Port starting from 0x0a18 and a RAM-based memory page
-for NVDIMM ACPI.
-
-Memory:
-   QEMU uses BIOS Linker/loader feature to ask BIOS to allocate a memory
-   page and dynamically patch its into a int32 object named "MEMA" in ACPI.
-
-   This page is RAM-based and it is used to transfer data between _DSM
-   method and QEMU. If ACPI has control, this pages is owned by ACPI which
-   writes _DSM input data to it, otherwise, it is owned by QEMU which
-   emulates _DSM access and writes the output data to it.
-
-   ACPI writes _DSM Input Data (based on the offset in the page):
-   [0x0 - 0x3]: 4 bytes, NVDIMM Device Handle, 0 is reserved for NVDIMM
-                Root device.
-   [0x4 - 0x7]: 4 bytes, Revision ID, that is the Arg1 of _DSM method.
-   [0x8 - 0xB]: 4 bytes. Function Index, that is the Arg2 of _DSM method.
-   [0xC - 0xFFF]: 4084 bytes, the Arg3 of _DSM method.
-
-   QEMU Writes Output Data (based on the offset in the page):
-   [0x0 - 0x3]: 4 bytes, the length of result
-   [0x4 - 0xFFF]: 4092 bytes, the DSM result filled by QEMU
-
-IO Port 0x0a18 - 0xa1b:
-   ACPI writes the address of the memory page allocated by BIOS to this
-   port then QEMU gets the control and fills the result in the memory page.
-
-   write Access:
-   [0x0a18 - 0xa1b]: 4 bytes, the address of the memory page allocated
-                     by BIOS.
-
-_DSM process diagram:
----------------------
-"MEMA" indicates the address of memory page allocated by BIOS.
-
- +----------------------+      +-----------------------+
- |    1. OSPM           |      |    2. OSPM            |
- | save _DSM input data |      |  write "MEMA" to      | Exit to QEMU
- | to the page          +----->|  IO port 0x0a18       +------------+
- | indicated by "MEMA"  |      |                       |            |
- +----------------------+      +-----------------------+            |
-                                                                    |
-                                                                    v
- +-------------   ----+       +-----------+      +------------------+--------+
- |      5 QEMU        |       | 4 QEMU    |      |        3. QEMU            |
- | write _DSM result  |       |  emulate  |      | get _DSM input data from  |
- | to the page        +<------+ _DSM      +<-----+ the page indicated by the |
- |                    |       |           |      | value from the IO port    |
- +--------+-----------+       +-----------+      +---------------------------+
-          |
-          | Enter Guest
-          |
-          v
- +--------------------------+      +--------------+
- |     6 OSPM               |      |   7 OSPM     |
- | result size is returned  |      |  _DSM return |
- | by reading  DSM          +----->+              |
- | result from the page     |      |              |
- +--------------------------+      +--------------+
-
- _FIT implementation
- -------------------
- TODO (will fill it when nvdimm hotplug is introduced)
index e9271eb..b4fe229 100644 (file)
@@ -94,7 +94,7 @@ Bytes:
               Bit 0: Empty Image bit. If set, the image should be
                      considered clear.
 
-              Bits 1-31: Unused.
+              Bits 2-31: Unused.
 
   56 - 63:    ext_off
               Format Extension offset, an offset, in sectors, from the start of
index 7890d71..777c49c 100644 (file)
@@ -37,8 +37,6 @@ consists of 3 header fields and a payload:
  * Flags: 32-bit bit field:
    - Lower 2 bits are the version (currently 0x01)
    - Bit 2 is the reply flag - needs to be sent on each reply from the slave
-   - Bit 3 is the need_reply flag - see VHOST_USER_PROTOCOL_F_REPLY_ACK for
-     details.
  * Size - 32-bit size of the payload
 
 
@@ -128,8 +126,6 @@ the ones that do:
  * VHOST_GET_VRING_BASE
  * VHOST_SET_LOG_BASE (if VHOST_USER_PROTOCOL_F_LOG_SHMFD)
 
-[ Also see the section on REPLY_ACK protocol extension. ]
-
 There are several messages that the master sends with file descriptors passed
 in the ancillary data:
 
@@ -258,7 +254,6 @@ Protocol features
 #define VHOST_USER_PROTOCOL_F_MQ             0
 #define VHOST_USER_PROTOCOL_F_LOG_SHMFD      1
 #define VHOST_USER_PROTOCOL_F_RARP           2
-#define VHOST_USER_PROTOCOL_F_REPLY_ACK      3
 
 Message types
 -------------
@@ -469,24 +464,3 @@ Message types
       is present in VHOST_USER_GET_PROTOCOL_FEATURES.
       The first 6 bytes of the payload contain the mac address of the guest to
       allow the vhost user backend to construct and broadcast the fake RARP.
-
-VHOST_USER_PROTOCOL_F_REPLY_ACK:
--------------------------------
-The original vhost-user specification only demands replies for certain
-commands. This differs from the vhost protocol implementation where commands
-are sent over an ioctl() call and block until the client has completed.
-
-With this protocol extension negotiated, the sender (QEMU) can set the
-"need_reply" [Bit 3] flag to any command. This indicates that
-the client MUST respond with a Payload VhostUserMsg indicating success or
-failure. The payload should be set to zero on success or non-zero on failure,
-unless the message already has an explicit reply body.
-
-The response payload gives QEMU a deterministic indication of the result
-of the command. Today, QEMU is expected to terminate the main vhost-user
-loop upon receiving such errors. In future, qemu could be taught to be more
-resilient for selective requests.
-
-For the message types that already solicit a reply from the client, the
-presence of VHOST_USER_PROTOCOL_F_REPLY_ACK or need_reply bit being set brings
-no behavioural change. (See the 'Communication' section for details.)
index 26d4d51..06ed9b3 100644 (file)
@@ -39,7 +39,7 @@ the parameters for both cases:
 | throttling.bps-write  | bps_wr                |
 |-----------------------+-----------------------|
 
-It is possible to set limits for both IOPS and bps at the same time,
+It is possible to set limits for both IOPS and bps and the same time,
 and for each case we can decide whether to have separate read and
 write limits or not, but note that if iops-total is set then neither
 iops-read nor iops-write can be set. The same applies to bps-total and
@@ -235,7 +235,7 @@ consider the following values:
   - Water leaks from the bucket at a rate of 100 IOPS.
   - Water can be added to the bucket at a rate of 2000 IOPS.
   - The size of the bucket is 2000 x 60 = 120000
-  - If 'iops-total-max' is unset then the bucket size is 100 x 60.
+  - If 'iops-total-max-length' is unset then the bucket size is 100.
 
 The bucket is initially empty, therefore water can be added until it's
 full at a rate of 2000 IOPS (the burst rate). Once the bucket is full
index 29f2f9a..0bd6b9c 100644 (file)
@@ -23,24 +23,20 @@ for debugging, profiling, and observing execution.
 
 4. Pretty-print the binary trace file:
 
-    ./scripts/simpletrace.py trace-events-all trace-* # Override * with QEMU <pid>
+    ./scripts/simpletrace.py trace-events trace-* # Override * with QEMU <pid>
 
 == Trace events ==
 
-Each directory in the source tree can declare a set of static trace events
-in a "trace-events" file. Each trace event declaration names the event, its
-arguments, and the format string which can be used for pretty-printing:
+There is a set of static trace events declared in the "trace-events" source
+file.  Each trace event declaration names the event, its arguments, and the
+format string which can be used for pretty-printing:
 
     qemu_vmalloc(size_t size, void *ptr) "size %zu ptr %p"
     qemu_vfree(void *ptr) "ptr %p"
 
-All "trace-events" files must be listed in the "trace-event-y" make variable
-in the top level Makefile.objs. During build the individual files are combined
-to create a "trace-events-all" file, which is processed by the "tracetool"
-script during build to generate code for the trace events. The
-"trace-events-all" file is also installed into "/usr/share/qemu".
-
-Trace events are invoked directly from source code like this:
+The "trace-events" file is processed by the "tracetool" script during build to
+generate code for the trace events.  Trace events are invoked directly from
+source code like this:
 
     #include "trace.h"  /* needed for trace event prototype */
     
@@ -200,12 +196,12 @@ Restriction: "ftrace" backend is restricted to Linux only.
 ==== Analyzing trace files ====
 
 The "simple" backend produces binary trace files that can be formatted with the
-simpletrace.py script.  The script takes the "trace-events-all" file and the
-binary trace:
+simpletrace.py script.  The script takes the "trace-events" file and the binary
+trace:
 
-    ./scripts/simpletrace.py trace-events-all trace-12345
+    ./scripts/simpletrace.py trace-events trace-12345
 
-You must ensure that the same "trace-events-all" file was used to build QEMU,
+You must ensure that the same "trace-events" file was used to build QEMU,
 otherwise trace event declarations may have changed and output will not be
 consistent.
 
@@ -263,11 +259,11 @@ probes:
                          --binary path/to/qemu-binary \
                          --target-type system \
                          --target-name x86_64 \
-                         <trace-events-all >qemu.stp
+                         <trace-events >qemu.stp
 
 == Trace event properties ==
 
-Each event in the "trace-events-all" file can be prefixed with a space-separated
+Each event in the "trace-events" file can be prefixed with a space-separated
 list of zero or more of the following event properties.
 
 === "disable" ===
@@ -279,7 +275,7 @@ programmatically disabled.
 In this case you should declare such event with the "disable" property. This
 will effectively disable the event at compile time (by using the "nop" backend),
 thus having no performance impact at all on regular builds (i.e., unless you
-edit the "trace-events-all" file).
+edit the "trace-events" file).
 
 In addition, there might be cases where relatively complex computations must be
 performed to generate values that are only used as arguments for a trace
index fbc1f2e..c5a3866 100644 (file)
@@ -40,18 +40,6 @@ numbers must be continuous, i.e. for three devices you must use 0+1+2.
 The 0+1+5 numbering from the "usb-uas" example isn't going to work
 with "usb-bot".
 
-Starting with qemu version 2.7 usb-bot and usb-uas devices can be
-hotplugged.  In the hotplug case they are added with "attached =
-false" so the guest will not see the device until the "attached"
-property is explicitly set to true.  That allows to attach one or more
-scsi devices before making the device visible to the guest, i.e. the
-workflow looks like this:
-
-   (1) device-add usb-bot,id=foo
-   (2) device-add scsi-{hd,cd},bus=foo.0,lun=0
-   (2b) optionally add more devices (luns 1 ... 15).
-   (3) scripts/qmp/qom-set foo.attached = true
-
 enjoy,
   Gerd
 
index 98a6b0f..cf66458 100644 (file)
@@ -28,8 +28,7 @@ virtio core               virtio transport          virtio device
 -----------               ----------------          -------------
 
                                                     save() function registered
-                                                    via VMState wrapper on
-                                                    device class
+                                                    via register_savevm()
 virtio_save()                                       <----------
              ------>      save_config()
                           - save proxy device
@@ -64,8 +63,7 @@ virtio core               virtio transport          virtio device
 -----------               ----------------          -------------
 
                                                     load() function registered
-                                                    via VMState wrapper on
-                                                    device class
+                                                    via register_savevm()
 virtio_load()                                       <----------
              ------>      load_config()
                           - load proxy device
diff --git a/dump.c b/dump.c
index f7b80d8..9726f1f 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -918,7 +918,9 @@ static void write_dump_header(DumpState *s, Error **errp)
     } else {
         create_header64(s, &local_err);
     }
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
 }
 
 static size_t dump_bitmap_get_bufsize(DumpState *s)
diff --git a/exec.c b/exec.c
index 8ffde75..fc75266 100644 (file)
--- a/exec.c
+++ b/exec.c
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #ifndef _WIN32
+#include <sys/mman.h>
 #endif
 
 #include "qemu/cutils.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "tcg.h"
-#include "hw/qdev-core.h"
+#include "hw/hw.h"
 #if !defined(CONFIG_USER_ONLY)
 #include "hw/boards.h"
-#include "hw/xen/xen.h"
 #endif
+#include "hw/qdev.h"
 #include "sysemu/kvm.h"
 #include "sysemu/sysemu.h"
+#include "hw/xen/xen.h"
 #include "qemu/timer.h"
 #include "qemu/config-file.h"
 #include "qemu/error-report.h"
-#if defined(CONFIG_USER_ONLY)
-#include "qemu.h"
-#else /* !CONFIG_USER_ONLY */
-#include "hw/hw.h"
 #include "exec/memory.h"
-#include "exec/ioport.h"
 #include "sysemu/dma.h"
 #include "exec/address-spaces.h"
+#if defined(CONFIG_USER_ONLY)
+#include <qemu.h>
+#else /* !CONFIG_USER_ONLY */
 #include "sysemu/xen-mapcache.h"
 #include "trace.h"
 #endif
@@ -56,8 +55,6 @@
 #include "exec/ram_addr.h"
 #include "exec/log.h"
 
-#include "migration/vmstate.h"
-
 #include "qemu/range.h"
 #ifndef _WIN32
 #include "qemu/mmap-alloc.h"
@@ -187,12 +184,10 @@ struct CPUAddressSpace {
 
 static void phys_map_node_reserve(PhysPageMap *map, unsigned nodes)
 {
-    static unsigned alloc_hint = 16;
     if (map->nodes_nb + nodes > map->nodes_nb_alloc) {
-        map->nodes_nb_alloc = MAX(map->nodes_nb_alloc, alloc_hint);
+        map->nodes_nb_alloc = MAX(map->nodes_nb_alloc * 2, 16);
         map->nodes_nb_alloc = MAX(map->nodes_nb_alloc, map->nodes_nb + nodes);
         map->nodes = g_renew(Node, map->nodes, map->nodes_nb_alloc);
-        alloc_hint = map->nodes_nb_alloc;
     }
 }
 
@@ -598,45 +593,56 @@ AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
 }
 #endif
 
-static int cpu_get_free_index(void)
+#ifndef CONFIG_USER_ONLY
+static DECLARE_BITMAP(cpu_index_map, MAX_CPUMASK_BITS);
+
+static int cpu_get_free_index(Error **errp)
 {
-    CPUState *some_cpu;
-    int cpu_index = 0;
+    int cpu = find_first_zero_bit(cpu_index_map, MAX_CPUMASK_BITS);
 
-    CPU_FOREACH(some_cpu) {
-        cpu_index++;
+    if (cpu >= MAX_CPUMASK_BITS) {
+        error_setg(errp, "Trying to use more CPUs than max of %d",
+                   MAX_CPUMASK_BITS);
+        return -1;
     }
-    return cpu_index;
+
+    bitmap_set(cpu_index_map, cpu, 1);
+    return cpu;
 }
 
 void cpu_exec_exit(CPUState *cpu)
 {
-    CPUClass *cc = CPU_GET_CLASS(cpu);
-
-    cpu_list_lock();
-    if (cpu->node.tqe_prev == NULL) {
-        /* there is nothing to undo since cpu_exec_init() hasn't been called */
-        cpu_list_unlock();
+    if (cpu->cpu_index == -1) {
+        /* cpu_index was never allocated by this @cpu or was already freed. */
         return;
     }
 
-    QTAILQ_REMOVE(&cpus, cpu, node);
-    cpu->node.tqe_prev = NULL;
-    cpu->cpu_index = UNASSIGNED_CPU_INDEX;
-    cpu_list_unlock();
+    bitmap_clear(cpu_index_map, cpu->cpu_index, 1);
+    cpu->cpu_index = -1;
+}
+#else
 
-    if (cc->vmsd != NULL) {
-        vmstate_unregister(NULL, cc->vmsd, cpu);
-    }
-    if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
-        vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
+static int cpu_get_free_index(Error **errp)
+{
+    CPUState *some_cpu;
+    int cpu_index = 0;
+
+    CPU_FOREACH(some_cpu) {
+        cpu_index++;
     }
+    return cpu_index;
 }
 
+void cpu_exec_exit(CPUState *cpu)
+{
+}
+#endif
+
 void cpu_exec_init(CPUState *cpu, Error **errp)
 {
-    CPUClass *cc ATTRIBUTE_UNUSED = CPU_GET_CLASS(cpu);
-    Error *local_err ATTRIBUTE_UNUSED = NULL;
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+    int cpu_index;
+    Error *local_err = NULL;
 
     cpu->as = NULL;
     cpu->num_ases = 0;
@@ -659,22 +665,27 @@ void cpu_exec_init(CPUState *cpu, Error **errp)
     object_ref(OBJECT(cpu->memory));
 #endif
 
+#if defined(CONFIG_USER_ONLY)
     cpu_list_lock();
-    if (cpu->cpu_index == UNASSIGNED_CPU_INDEX) {
-        cpu->cpu_index = cpu_get_free_index();
-        assert(cpu->cpu_index != UNASSIGNED_CPU_INDEX);
+#endif
+    cpu_index = cpu->cpu_index = cpu_get_free_index(&local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+#if defined(CONFIG_USER_ONLY)
+        cpu_list_unlock();
+#endif
+        return;
     }
     QTAILQ_INSERT_TAIL(&cpus, cpu, node);
+#if defined(CONFIG_USER_ONLY)
     cpu_list_unlock();
-
-#ifndef CONFIG_USER_ONLY
+#endif
     if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
-        vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu);
+        vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
     }
     if (cc->vmsd != NULL) {
-        vmstate_register(NULL, cpu->cpu_index, cc->vmsd, cpu);
+        vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
     }
-#endif
 }
 
 #if defined(CONFIG_USER_ONLY)
@@ -1032,7 +1043,8 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
 
     if (memory_region_is_ram(section->mr)) {
         /* Normal RAM.  */
-        iotlb = memory_region_get_ram_addr(section->mr) + xlat;
+        iotlb = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
+            + xlat;
         if (!section->readonly) {
             iotlb |= PHYS_SECTION_NOTDIRTY;
         } else {
@@ -1226,7 +1238,7 @@ static void *file_ram_alloc(RAMBlock *block,
     char *filename;
     char *sanitized_name;
     char *c;
-    void *area = MAP_FAILED;
+    void *area;
     int fd = -1;
     int64_t page_size;
 
@@ -1314,19 +1326,13 @@ static void *file_ram_alloc(RAMBlock *block,
     }
 
     if (mem_prealloc) {
-        os_mem_prealloc(fd, area, memory, errp);
-        if (errp && *errp) {
-            goto error;
-        }
+        os_mem_prealloc(fd, area, memory);
     }
 
     block->fd = fd;
     return area;
 
 error:
-    if (area != MAP_FAILED) {
-        qemu_ram_munmap(area, memory);
-    }
     if (unlink_on_error) {
         unlink(path);
     }
@@ -1402,16 +1408,34 @@ static void qemu_ram_setup_dump(void *addr, ram_addr_t size)
     }
 }
 
+/* Called within an RCU critical section, or while the ramlist lock
+ * is held.
+ */
+static RAMBlock *find_ram_block(ram_addr_t addr)
+{
+    RAMBlock *block;
+
+    QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
+        if (block->offset == addr) {
+            return block;
+        }
+    }
+
+    return NULL;
+}
+
 const char *qemu_ram_get_idstr(RAMBlock *rb)
 {
     return rb->idstr;
 }
 
 /* Called with iothread lock held.  */
-void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev)
+void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
 {
-    RAMBlock *block;
+    RAMBlock *new_block, *block;
 
+    rcu_read_lock();
+    new_block = find_ram_block(addr);
     assert(new_block);
     assert(!new_block->idstr[0]);
 
@@ -1424,10 +1448,8 @@ void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev)
     }
     pstrcat(new_block->idstr, sizeof(new_block->idstr), name);
 
-    rcu_read_lock();
     QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
-        if (block != new_block &&
-            !strcmp(block->idstr, new_block->idstr)) {
+        if (block != new_block && !strcmp(block->idstr, new_block->idstr)) {
             fprintf(stderr, "RAMBlock \"%s\" already registered, abort!\n",
                     new_block->idstr);
             abort();
@@ -1437,15 +1459,21 @@ void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev)
 }
 
 /* Called with iothread lock held.  */
-void qemu_ram_unset_idstr(RAMBlock *block)
+void qemu_ram_unset_idstr(ram_addr_t addr)
 {
+    RAMBlock *block;
+
     /* FIXME: arch_init.c assumes that this is not called throughout
      * migration.  Ignore the problem since hot-unplug during migration
      * does not work anyway.
      */
+
+    rcu_read_lock();
+    block = find_ram_block(addr);
     if (block) {
         memset(block->idstr, 0, sizeof(block->idstr));
     }
+    rcu_read_unlock();
 }
 
 static int memory_try_enable_merging(void *addr, size_t len)
@@ -1465,8 +1493,10 @@ static int memory_try_enable_merging(void *addr, size_t len)
  * resize callback to update device state and/or add assertions to detect
  * misuse, if necessary.
  */
-int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
+int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp)
 {
+    RAMBlock *block = find_ram_block(base);
+
     assert(block);
 
     newsize = HOST_PAGE_ALIGN(newsize);
@@ -1807,6 +1837,40 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
 }
 #endif /* !_WIN32 */
 
+int qemu_get_ram_fd(ram_addr_t addr)
+{
+    RAMBlock *block;
+    int fd;
+
+    rcu_read_lock();
+    block = qemu_get_ram_block(addr);
+    fd = block->fd;
+    rcu_read_unlock();
+    return fd;
+}
+
+void qemu_set_ram_fd(ram_addr_t addr, int fd)
+{
+    RAMBlock *block;
+
+    rcu_read_lock();
+    block = qemu_get_ram_block(addr);
+    block->fd = fd;
+    rcu_read_unlock();
+}
+
+void *qemu_get_ram_block_host_ptr(ram_addr_t addr)
+{
+    RAMBlock *block;
+    void *ptr;
+
+    rcu_read_lock();
+    block = qemu_get_ram_block(addr);
+    ptr = ramblock_ptr(block, 0);
+    rcu_read_unlock();
+    return ptr;
+}
+
 /* Return a host pointer to ram allocated with qemu_ram_alloc.
  * This should not be used for general purpose DMA.  Use address_space_map
  * or address_space_rw instead. For local memory (e.g. video ram) that the
@@ -1814,13 +1878,12 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
  *
  * Called within RCU critical section.
  */
-void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
+void *qemu_get_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
 {
     RAMBlock *block = ram_block;
 
     if (block == NULL) {
         block = qemu_get_ram_block(addr);
-        addr -= block->offset;
     }
 
     if (xen_enabled() && block->host == NULL) {
@@ -1834,10 +1897,10 @@ void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
 
         block->host = xen_map_cache(block->offset, block->max_length, 1);
     }
-    return ramblock_ptr(block, addr);
+    return ramblock_ptr(block, addr - block->offset);
 }
 
-/* Return a host pointer to guest's ram. Similar to qemu_map_ram_ptr
+/* Return a host pointer to guest's ram. Similar to qemu_get_ram_ptr
  * but takes a size argument.
  *
  * Called within RCU critical section.
@@ -1846,15 +1909,16 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
                                  hwaddr *size)
 {
     RAMBlock *block = ram_block;
+    ram_addr_t offset_inside_block;
     if (*size == 0) {
         return NULL;
     }
 
     if (block == NULL) {
         block = qemu_get_ram_block(addr);
-        addr -= block->offset;
     }
-    *size = MIN(*size, block->max_length - addr);
+    offset_inside_block = addr - block->offset;
+    *size = MIN(*size, block->max_length - offset_inside_block);
 
     if (xen_enabled() && block->host == NULL) {
         /* We need to check if the requested address is in the RAM
@@ -1868,7 +1932,7 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
         block->host = xen_map_cache(block->offset, block->max_length, 1);
     }
 
-    return ramblock_ptr(block, addr);
+    return ramblock_ptr(block, offset_inside_block);
 }
 
 /*
@@ -1889,18 +1953,18 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
  * ram_addr_t.
  */
 RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
+                                   ram_addr_t *ram_addr,
                                    ram_addr_t *offset)
 {
     RAMBlock *block;
     uint8_t *host = ptr;
 
     if (xen_enabled()) {
-        ram_addr_t ram_addr;
         rcu_read_lock();
-        ram_addr = xen_ram_addr_from_mapcache(ptr);
-        block = qemu_get_ram_block(ram_addr);
+        *ram_addr = xen_ram_addr_from_mapcache(ptr);
+        block = qemu_get_ram_block(*ram_addr);
         if (block) {
-            *offset = ram_addr - block->offset;
+            *offset = (host - block->host);
         }
         rcu_read_unlock();
         return block;
@@ -1930,6 +1994,7 @@ found:
     if (round_offset) {
         *offset &= TARGET_PAGE_MASK;
     }
+    *ram_addr = block->offset + *offset;
     rcu_read_unlock();
     return block;
 }
@@ -1956,17 +2021,18 @@ RAMBlock *qemu_ram_block_by_name(const char *name)
 
 /* Some of the softmmu routines need to translate from a host pointer
    (typically a TLB entry) back to a ram offset.  */
-ram_addr_t qemu_ram_addr_from_host(void *ptr)
+MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
 {
     RAMBlock *block;
-    ram_addr_t offset;
+    ram_addr_t offset; /* Not used */
+
+    block = qemu_ram_block_from_host(ptr, false, ram_addr, &offset);
 
-    block = qemu_ram_block_from_host(ptr, false, &offset);
     if (!block) {
-        return RAM_ADDR_INVALID;
+        return NULL;
     }
 
-    return block->offset + offset;
+    return block->mr;
 }
 
 /* Called within RCU critical section.  */
@@ -1978,13 +2044,13 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
     }
     switch (size) {
     case 1:
-        stb_p(qemu_map_ram_ptr(NULL, ram_addr), val);
+        stb_p(qemu_get_ram_ptr(NULL, ram_addr), val);
         break;
     case 2:
-        stw_p(qemu_map_ram_ptr(NULL, ram_addr), val);
+        stw_p(qemu_get_ram_ptr(NULL, ram_addr), val);
         break;
     case 4:
-        stl_p(qemu_map_ram_ptr(NULL, ram_addr), val);
+        stl_p(qemu_get_ram_ptr(NULL, ram_addr), val);
         break;
     default:
         abort();
@@ -2022,7 +2088,7 @@ static void check_watchpoint(int offset, int len, MemTxAttrs attrs, int flags)
     target_ulong pc, cs_base;
     target_ulong vaddr;
     CPUWatchpoint *wp;
-    uint32_t cpu_flags;
+    int cpu_flags;
 
     if (cpu->watchpoint_hit) {
         /* We re-entered the check after replacing the TB. Now raise
@@ -2056,7 +2122,7 @@ static void check_watchpoint(int offset, int len, MemTxAttrs attrs, int flags)
                 } else {
                     cpu_get_tb_cpu_state(env, &pc, &cs_base, &cpu_flags);
                     tb_gen_code(cpu, pc, cs_base, cpu_flags, 1);
-                    cpu_loop_exit_noexc(cpu);
+                    cpu_resume_from_signal(cpu, NULL);
                 }
             }
         } else {
@@ -2446,8 +2512,6 @@ static void invalidate_and_set_dirty(MemoryRegion *mr, hwaddr addr,
                                      hwaddr length)
 {
     uint8_t dirty_log_mask = memory_region_get_dirty_log_mask(mr);
-    addr += memory_region_get_ram_addr(mr);
-
     /* No early return if dirty_log_mask is or becomes 0, because
      * cpu_physical_memory_set_dirty_range will still call
      * xen_modified_memory.
@@ -2560,8 +2624,9 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
                 abort();
             }
         } else {
+            addr1 += memory_region_get_ram_addr(mr);
             /* RAM case */
-            ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+            ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
             memcpy(ptr, buf, l);
             invalidate_and_set_dirty(mr, addr1, l);
         }
@@ -2652,7 +2717,8 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
             }
         } else {
             /* RAM case */
-            ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+            ptr = qemu_get_ram_ptr(mr->ram_block,
+                                   memory_region_get_ram_addr(mr) + addr1);
             memcpy(buf, ptr, l);
         }
 
@@ -2735,8 +2801,9 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
               memory_region_is_romd(mr))) {
             l = memory_access_size(mr, l, addr1);
         } else {
+            addr1 += memory_region_get_ram_addr(mr);
             /* ROM/RAM case */
-            ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+            ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
             switch (type) {
             case WRITE_DATA:
                 memcpy(ptr, buf, l);
@@ -2894,6 +2961,7 @@ void *address_space_map(AddressSpace *as,
     hwaddr done = 0;
     hwaddr l, xlat, base;
     MemoryRegion *mr, *this_mr;
+    ram_addr_t raddr;
     void *ptr;
 
     if (len == 0) {
@@ -2928,6 +2996,7 @@ void *address_space_map(AddressSpace *as,
     }
 
     base = xlat;
+    raddr = memory_region_get_ram_addr(mr);
 
     for (;;) {
         len -= l;
@@ -2946,7 +3015,7 @@ void *address_space_map(AddressSpace *as,
 
     memory_region_ref(mr);
     *plen = done;
-    ptr = qemu_ram_ptr_length(mr->ram_block, base, plen);
+    ptr = qemu_ram_ptr_length(mr->ram_block, raddr + base, plen);
     rcu_read_unlock();
 
     return ptr;
@@ -2963,7 +3032,7 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
         MemoryRegion *mr;
         ram_addr_t addr1;
 
-        mr = memory_region_from_host(buffer, &addr1);
+        mr = qemu_ram_addr_from_host(buffer, &addr1);
         assert(mr != NULL);
         if (is_write) {
             invalidate_and_set_dirty(mr, addr1, access_len);
@@ -3030,7 +3099,10 @@ static inline uint32_t address_space_ldl_internal(AddressSpace *as, hwaddr addr,
 #endif
     } else {
         /* RAM case */
-        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+        ptr = qemu_get_ram_ptr(mr->ram_block,
+                               (memory_region_get_ram_addr(mr)
+                                & TARGET_PAGE_MASK)
+                               + addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = ldl_le_p(ptr);
@@ -3123,7 +3195,10 @@ static inline uint64_t address_space_ldq_internal(AddressSpace *as, hwaddr addr,
 #endif
     } else {
         /* RAM case */
-        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+        ptr = qemu_get_ram_ptr(mr->ram_block,
+                               (memory_region_get_ram_addr(mr)
+                                & TARGET_PAGE_MASK)
+                               + addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = ldq_le_p(ptr);
@@ -3236,7 +3311,10 @@ static inline uint32_t address_space_lduw_internal(AddressSpace *as,
 #endif
     } else {
         /* RAM case */
-        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+        ptr = qemu_get_ram_ptr(mr->ram_block,
+                               (memory_region_get_ram_addr(mr)
+                                & TARGET_PAGE_MASK)
+                               + addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = lduw_le_p(ptr);
@@ -3318,13 +3396,13 @@ void address_space_stl_notdirty(AddressSpace *as, hwaddr addr, uint32_t val,
 
         r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
     } else {
-        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+        addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
+        ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
         stl_p(ptr, val);
 
         dirty_log_mask = memory_region_get_dirty_log_mask(mr);
         dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE);
-        cpu_physical_memory_set_dirty_range(memory_region_get_ram_addr(mr) + addr,
-                                            4, dirty_log_mask);
+        cpu_physical_memory_set_dirty_range(addr1, 4, dirty_log_mask);
         r = MEMTX_OK;
     }
     if (result) {
@@ -3373,7 +3451,8 @@ static inline void address_space_stl_internal(AddressSpace *as,
         r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
     } else {
         /* RAM case */
-        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+        addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
+        ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             stl_le_p(ptr, val);
@@ -3482,7 +3561,8 @@ static inline void address_space_stw_internal(AddressSpace *as,
         r = memory_region_dispatch_write(mr, addr1, val, 2, attrs);
     } else {
         /* RAM case */
-        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+        addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
+        ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             stw_le_p(ptr, val);
index f5aed72..a4cbdad 100644 (file)
@@ -79,6 +79,16 @@ this code that are retained.
  * version 2 or later. See the COPYING file in the top-level directory.
  */
 
+/* Does the target distinguish signaling NaNs from non-signaling NaNs
+ * by setting the most significant bit of the mantissa for a signaling NaN?
+ * (The more common choice is to have it be zero for SNaN and one for QNaN.)
+ */
+#if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
+#define SNAN_BIT_IS_ONE 1
+#else
+#define SNAN_BIT_IS_ONE 0
+#endif
+
 #if defined(TARGET_XTENSA)
 /* Define for architectures which deviate from IEEE in not supporting
  * signaling NaNs (so all NaNs are treated as quiet).
@@ -89,106 +99,73 @@ this code that are retained.
 /*----------------------------------------------------------------------------
 | The pattern for a default generated half-precision NaN.
 *----------------------------------------------------------------------------*/
-float16 float16_default_nan(float_status *status)
-{
 #if defined(TARGET_ARM)
-    return const_float16(0x7E00);
-#else
-    if (status->snan_bit_is_one) {
-        return const_float16(0x7DFF);
-    } else {
-#if defined(TARGET_MIPS)
-        return const_float16(0x7E00);
+const float16 float16_default_nan = const_float16(0x7E00);
+#elif SNAN_BIT_IS_ONE
+const float16 float16_default_nan = const_float16(0x7DFF);
 #else
-        return const_float16(0xFE00);
+const float16 float16_default_nan = const_float16(0xFE00);
 #endif
-    }
-#endif
-}
 
 /*----------------------------------------------------------------------------
 | The pattern for a default generated single-precision NaN.
 *----------------------------------------------------------------------------*/
-float32 float32_default_nan(float_status *status)
-{
 #if defined(TARGET_SPARC)
-    return const_float32(0x7FFFFFFF);
+const float32 float32_default_nan = const_float32(0x7FFFFFFF);
 #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
       defined(TARGET_XTENSA) || defined(TARGET_S390X) || defined(TARGET_TRICORE)
-    return const_float32(0x7FC00000);
+const float32 float32_default_nan = const_float32(0x7FC00000);
+#elif SNAN_BIT_IS_ONE
+const float32 float32_default_nan = const_float32(0x7FBFFFFF);
 #else
-    if (status->snan_bit_is_one) {
-        return const_float32(0x7FBFFFFF);
-    } else {
-#if defined(TARGET_MIPS)
-        return const_float32(0x7FC00000);
-#else
-        return const_float32(0xFFC00000);
-#endif
-    }
+const float32 float32_default_nan = const_float32(0xFFC00000);
 #endif
-}
 
 /*----------------------------------------------------------------------------
 | The pattern for a default generated double-precision NaN.
 *----------------------------------------------------------------------------*/
-float64 float64_default_nan(float_status *status)
-{
 #if defined(TARGET_SPARC)
-    return const_float64(LIT64(0x7FFFFFFFFFFFFFFF));
+const float64 float64_default_nan = const_float64(LIT64( 0x7FFFFFFFFFFFFFFF ));
 #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
       defined(TARGET_S390X)
-    return const_float64(LIT64(0x7FF8000000000000));
-#else
-    if (status->snan_bit_is_one) {
-        return const_float64(LIT64(0x7FF7FFFFFFFFFFFF));
-    } else {
-#if defined(TARGET_MIPS)
-        return const_float64(LIT64(0x7FF8000000000000));
+const float64 float64_default_nan = const_float64(LIT64( 0x7FF8000000000000 ));
+#elif SNAN_BIT_IS_ONE
+const float64 float64_default_nan = const_float64(LIT64(0x7FF7FFFFFFFFFFFF));
 #else
-        return const_float64(LIT64(0xFFF8000000000000));
+const float64 float64_default_nan = const_float64(LIT64( 0xFFF8000000000000 ));
 #endif
-    }
-#endif
-}
 
 /*----------------------------------------------------------------------------
 | The pattern for a default generated extended double-precision NaN.
 *----------------------------------------------------------------------------*/
-floatx80 floatx80_default_nan(float_status *status)
-{
-    floatx80 r;
+#if SNAN_BIT_IS_ONE
+#define floatx80_default_nan_high 0x7FFF
+#define floatx80_default_nan_low  LIT64(0xBFFFFFFFFFFFFFFF)
+#else
+#define floatx80_default_nan_high 0xFFFF
+#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
+#endif
 
-    if (status->snan_bit_is_one) {
-        r.low = LIT64(0xBFFFFFFFFFFFFFFF);
-        r.high = 0x7FFF;
-    } else {
-        r.low = LIT64(0xC000000000000000);
-        r.high = 0xFFFF;
-    }
-    return r;
-}
+const floatx80 floatx80_default_nan
+    = make_floatx80_init(floatx80_default_nan_high, floatx80_default_nan_low);
 
 /*----------------------------------------------------------------------------
-| The pattern for a default generated quadruple-precision NaN.
+| The pattern for a default generated quadruple-precision NaN.  The `high' and
+| `low' values hold the most- and least-significant bits, respectively.
 *----------------------------------------------------------------------------*/
-float128 float128_default_nan(float_status *status)
-{
-    float128 r;
-
-    if (status->snan_bit_is_one) {
-        r.low = LIT64(0xFFFFFFFFFFFFFFFF);
-        r.high = LIT64(0x7FFF7FFFFFFFFFFF);
-    } else {
-        r.low = LIT64(0x0000000000000000);
-#if defined(TARGET_S390X)
-        r.high = LIT64(0x7FFF800000000000);
+#if SNAN_BIT_IS_ONE
+#define float128_default_nan_high LIT64(0x7FFF7FFFFFFFFFFF)
+#define float128_default_nan_low  LIT64(0xFFFFFFFFFFFFFFFF)
+#elif defined(TARGET_S390X)
+#define float128_default_nan_high LIT64( 0x7FFF800000000000 )
+#define float128_default_nan_low  LIT64( 0x0000000000000000 )
 #else
-        r.high = LIT64(0xFFFF800000000000);
+#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
+#define float128_default_nan_low  LIT64( 0x0000000000000000 )
 #endif
-    }
-    return r;
-}
+
+const float128 float128_default_nan
+    = make_float128_init(float128_default_nan_high, float128_default_nan_low);
 
 /*----------------------------------------------------------------------------
 | Raises the exceptions specified by `flags'.  Floating-point traps can be
@@ -197,7 +174,7 @@ float128 float128_default_nan(float_status *status)
 | should be simply `float_exception_flags |= flags;'.
 *----------------------------------------------------------------------------*/
 
-void float_raise(uint8_t flags, float_status *status)
+void float_raise(int8_t flags, float_status *status)
 {
     status->float_exception_flags |= flags;
 }
@@ -211,12 +188,12 @@ typedef struct {
 } commonNaNT;
 
 #ifdef NO_SIGNALING_NANS
-int float16_is_quiet_nan(float16 a_, float_status *status)
+int float16_is_quiet_nan(float16 a_)
 {
     return float16_is_any_nan(a_);
 }
 
-int float16_is_signaling_nan(float16 a_, float_status *status)
+int float16_is_signaling_nan(float16 a_)
 {
     return 0;
 }
@@ -226,14 +203,14 @@ int float16_is_signaling_nan(float16 a_, float_status *status)
 | NaN; otherwise returns 0.
 *----------------------------------------------------------------------------*/
 
-int float16_is_quiet_nan(float16 a_, float_status *status)
+int float16_is_quiet_nan(float16 a_)
 {
     uint16_t a = float16_val(a_);
-    if (status->snan_bit_is_one) {
-        return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
-    } else {
-        return ((a & ~0x8000) >= 0x7C80);
-    }
+#if SNAN_BIT_IS_ONE
+    return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
+#else
+    return ((a & ~0x8000) >= 0x7c80);
+#endif
 }
 
 /*----------------------------------------------------------------------------
@@ -241,14 +218,14 @@ int float16_is_quiet_nan(float16 a_, float_status *status)
 | NaN; otherwise returns 0.
 *----------------------------------------------------------------------------*/
 
-int float16_is_signaling_nan(float16 a_, float_status *status)
+int float16_is_signaling_nan(float16 a_)
 {
     uint16_t a = float16_val(a_);
-    if (status->snan_bit_is_one) {
-        return ((a & ~0x8000) >= 0x7C80);
-    } else {
-        return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
-    }
+#if SNAN_BIT_IS_ONE
+    return ((a & ~0x8000) >= 0x7c80);
+#else
+    return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
+#endif
 }
 #endif
 
@@ -256,16 +233,20 @@ int float16_is_signaling_nan(float16 a_, float_status *status)
 | Returns a quiet NaN if the half-precision floating point value `a' is a
 | signaling NaN; otherwise returns `a'.
 *----------------------------------------------------------------------------*/
-float16 float16_maybe_silence_nan(float16 a_, float_status *status)
+float16 float16_maybe_silence_nan(float16 a_)
 {
-    if (float16_is_signaling_nan(a_, status)) {
-        if (status->snan_bit_is_one) {
-            return float16_default_nan(status);
-        } else {
-            uint16_t a = float16_val(a_);
-            a |= (1 << 9);
-            return make_float16(a);
-        }
+    if (float16_is_signaling_nan(a_)) {
+#if SNAN_BIT_IS_ONE
+#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
+        return float16_default_nan;
+#  else
+#    error Rules for silencing a signaling NaN are target-specific
+#  endif
+#else
+        uint16_t a = float16_val(a_);
+        a |= (1 << 9);
+        return make_float16(a);
+#endif
     }
     return a_;
 }
@@ -280,12 +261,12 @@ static commonNaNT float16ToCommonNaN(float16 a, float_status *status)
 {
     commonNaNT z;
 
-    if (float16_is_signaling_nan(a, status)) {
+    if (float16_is_signaling_nan(a)) {
         float_raise(float_flag_invalid, status);
     }
     z.sign = float16_val(a) >> 15;
     z.low = 0;
-    z.high = ((uint64_t) float16_val(a)) << 54;
+    z.high = ((uint64_t) float16_val(a))<<54;
     return z;
 }
 
@@ -296,27 +277,27 @@ static commonNaNT float16ToCommonNaN(float16 a, float_status *status)
 
 static float16 commonNaNToFloat16(commonNaNT a, float_status *status)
 {
-    uint16_t mantissa = a.high >> 54;
+    uint16_t mantissa = a.high>>54;
 
     if (status->default_nan_mode) {
-        return float16_default_nan(status);
+        return float16_default_nan;
     }
 
     if (mantissa) {
         return make_float16(((((uint16_t) a.sign) << 15)
                              | (0x1F << 10) | mantissa));
     } else {
-        return float16_default_nan(status);
+        return float16_default_nan;
     }
 }
 
 #ifdef NO_SIGNALING_NANS
-int float32_is_quiet_nan(float32 a_, float_status *status)
+int float32_is_quiet_nan(float32 a_)
 {
     return float32_is_any_nan(a_);
 }
 
-int float32_is_signaling_nan(float32 a_, float_status *status)
+int float32_is_signaling_nan(float32 a_)
 {
     return 0;
 }
@@ -326,14 +307,14 @@ int float32_is_signaling_nan(float32 a_, float_status *status)
 | NaN; otherwise returns 0.
 *----------------------------------------------------------------------------*/
 
-int float32_is_quiet_nan(float32 a_, float_status *status)
+int float32_is_quiet_nan( float32 a_ )
 {
     uint32_t a = float32_val(a_);
-    if (status->snan_bit_is_one) {
-        return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF);
-    } else {
-        return ((uint32_t)(a << 1) >= 0xFF800000);
-    }
+#if SNAN_BIT_IS_ONE
+    return (((a >> 22) & 0x1ff) == 0x1fe) && (a & 0x003fffff);
+#else
+    return ((uint32_t)(a << 1) >= 0xff800000);
+#endif
 }
 
 /*----------------------------------------------------------------------------
@@ -341,14 +322,14 @@ int float32_is_quiet_nan(float32 a_, float_status *status)
 | NaN; otherwise returns 0.
 *----------------------------------------------------------------------------*/
 
-int float32_is_signaling_nan(float32 a_, float_status *status)
+int float32_is_signaling_nan( float32 a_ )
 {
     uint32_t a = float32_val(a_);
-    if (status->snan_bit_is_one) {
-        return ((uint32_t)(a << 1) >= 0xFF800000);
-    } else {
-        return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF);
-    }
+#if SNAN_BIT_IS_ONE
+    return ((uint32_t)(a << 1) >= 0xff800000);
+#else
+    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
+#endif
 }
 #endif
 
@@ -357,16 +338,20 @@ int float32_is_signaling_nan(float32 a_, float_status *status)
 | signaling NaN; otherwise returns `a'.
 *----------------------------------------------------------------------------*/
 
-float32 float32_maybe_silence_nan(float32 a_, float_status *status)
+float32 float32_maybe_silence_nan( float32 a_ )
 {
-    if (float32_is_signaling_nan(a_, status)) {
-        if (status->snan_bit_is_one) {
-            return float32_default_nan(status);
-        } else {
-            uint32_t a = float32_val(a_);
-            a |= (1 << 22);
-            return make_float32(a);
-        }
+    if (float32_is_signaling_nan(a_)) {
+#if SNAN_BIT_IS_ONE
+#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
+        return float32_default_nan;
+#  else
+#    error Rules for silencing a signaling NaN are target-specific
+#  endif
+#else
+        uint32_t a = float32_val(a_);
+        a |= (1 << 22);
+        return make_float32(a);
+#endif
     }
     return a_;
 }
@@ -381,12 +366,12 @@ static commonNaNT float32ToCommonNaN(float32 a, float_status *status)
 {
     commonNaNT z;
 
-    if (float32_is_signaling_nan(a, status)) {
+    if (float32_is_signaling_nan(a)) {
         float_raise(float_flag_invalid, status);
     }
-    z.sign = float32_val(a) >> 31;
+    z.sign = float32_val(a)>>31;
     z.low = 0;
-    z.high = ((uint64_t)float32_val(a)) << 41;
+    z.high = ( (uint64_t) float32_val(a) )<<41;
     return z;
 }
 
@@ -397,18 +382,17 @@ static commonNaNT float32ToCommonNaN(float32 a, float_status *status)
 
 static float32 commonNaNToFloat32(commonNaNT a, float_status *status)
 {
-    uint32_t mantissa = a.high >> 41;
+    uint32_t mantissa = a.high>>41;
 
     if (status->default_nan_mode) {
-        return float32_default_nan(status);
+        return float32_default_nan;
     }
 
-    if (mantissa) {
+    if ( mantissa )
         return make_float32(
-            (((uint32_t)a.sign) << 31) | 0x7F800000 | (a.high >> 41));
-    } else {
-        return float32_default_nan(status);
-    }
+            ( ( (uint32_t) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
+    else
+        return float32_default_nan;
 }
 
 /*----------------------------------------------------------------------------
@@ -510,10 +494,11 @@ static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
             return aIsLargerSignificand ? 0 : 1;
         }
         return bIsQNaN ? 1 : 0;
-    } else if (aIsQNaN) {
-        if (bIsSNaN || !bIsQNaN) {
+    }
+    else if (aIsQNaN) {
+        if (bIsSNaN || !bIsQNaN)
             return 0;
-        else {
+        else {
             return aIsLargerSignificand ? 0 : 1;
         }
     } else {
@@ -571,36 +556,19 @@ static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
         return 3;
     }
 
-    if (status->snan_bit_is_one) {
-        /* Prefer sNaN over qNaN, in the a, b, c order. */
-        if (aIsSNaN) {
-            return 0;
-        } else if (bIsSNaN) {
-            return 1;
-        } else if (cIsSNaN) {
-            return 2;
-        } else if (aIsQNaN) {
-            return 0;
-        } else if (bIsQNaN) {
-            return 1;
-        } else {
-            return 2;
-        }
+    /* Prefer sNaN over qNaN, in the a, b, c order. */
+    if (aIsSNaN) {
+        return 0;
+    } else if (bIsSNaN) {
+        return 1;
+    } else if (cIsSNaN) {
+        return 2;
+    } else if (aIsQNaN) {
+        return 0;
+    } else if (bIsQNaN) {
+        return 1;
     } else {
-        /* Prefer sNaN over qNaN, in the c, a, b order. */
-        if (cIsSNaN) {
-            return 2;
-        } else if (aIsSNaN) {
-            return 0;
-        } else if (bIsSNaN) {
-            return 1;
-        } else if (cIsQNaN) {
-            return 2;
-        } else if (aIsQNaN) {
-            return 0;
-        } else {
-            return 1;
-        }
+        return 2;
     }
 }
 #elif defined(TARGET_PPC)
@@ -658,10 +626,10 @@ static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status)
     flag aIsLargerSignificand;
     uint32_t av, bv;
 
-    aIsQuietNaN = float32_is_quiet_nan(a, status);
-    aIsSignalingNaN = float32_is_signaling_nan(a, status);
-    bIsQuietNaN = float32_is_quiet_nan(b, status);
-    bIsSignalingNaN = float32_is_signaling_nan(b, status);
+    aIsQuietNaN = float32_is_quiet_nan( a );
+    aIsSignalingNaN = float32_is_signaling_nan( a );
+    bIsQuietNaN = float32_is_quiet_nan( b );
+    bIsSignalingNaN = float32_is_signaling_nan( b );
     av = float32_val(a);
     bv = float32_val(b);
 
@@ -669,13 +637,12 @@ static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status)
         float_raise(float_flag_invalid, status);
     }
 
-    if (status->default_nan_mode) {
-        return float32_default_nan(status);
-    }
+    if (status->default_nan_mode)
+        return float32_default_nan;
 
-    if ((uint32_t)(av << 1) < (uint32_t)(bv << 1)) {
+    if ((uint32_t)(av<<1) < (uint32_t)(bv<<1)) {
         aIsLargerSignificand = 0;
-    } else if ((uint32_t)(bv << 1) < (uint32_t)(av << 1)) {
+    } else if ((uint32_t)(bv<<1) < (uint32_t)(av<<1)) {
         aIsLargerSignificand = 1;
     } else {
         aIsLargerSignificand = (av < bv) ? 1 : 0;
@@ -683,9 +650,9 @@ static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status)
 
     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                 aIsLargerSignificand)) {
-        return float32_maybe_silence_nan(b, status);
+        return float32_maybe_silence_nan(b);
     } else {
-        return float32_maybe_silence_nan(a, status);
+        return float32_maybe_silence_nan(a);
     }
 }
 
@@ -706,12 +673,12 @@ static float32 propagateFloat32MulAddNaN(float32 a, float32 b,
         cIsQuietNaN, cIsSignalingNaN;
     int which;
 
-    aIsQuietNaN = float32_is_quiet_nan(a, status);
-    aIsSignalingNaN = float32_is_signaling_nan(a, status);
-    bIsQuietNaN = float32_is_quiet_nan(b, status);
-    bIsSignalingNaN = float32_is_signaling_nan(b, status);
-    cIsQuietNaN = float32_is_quiet_nan(c, status);
-    cIsSignalingNaN = float32_is_signaling_nan(c, status);
+    aIsQuietNaN = float32_is_quiet_nan(a);
+    aIsSignalingNaN = float32_is_signaling_nan(a);
+    bIsQuietNaN = float32_is_quiet_nan(b);
+    bIsSignalingNaN = float32_is_signaling_nan(b);
+    cIsQuietNaN = float32_is_quiet_nan(c);
+    cIsSignalingNaN = float32_is_signaling_nan(c);
 
     if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
         float_raise(float_flag_invalid, status);
@@ -725,29 +692,29 @@ static float32 propagateFloat32MulAddNaN(float32 a, float32 b,
         /* Note that this check is after pickNaNMulAdd so that function
          * has an opportunity to set the Invalid flag.
          */
-        return float32_default_nan(status);
+        return float32_default_nan;
     }
 
     switch (which) {
     case 0:
-        return float32_maybe_silence_nan(a, status);
+        return float32_maybe_silence_nan(a);
     case 1:
-        return float32_maybe_silence_nan(b, status);
+        return float32_maybe_silence_nan(b);
     case 2:
-        return float32_maybe_silence_nan(c, status);
+        return float32_maybe_silence_nan(c);
     case 3:
     default:
-        return float32_default_nan(status);
+        return float32_default_nan;
     }
 }
 
 #ifdef NO_SIGNALING_NANS
-int float64_is_quiet_nan(float64 a_, float_status *status)
+int float64_is_quiet_nan(float64 a_)
 {
     return float64_is_any_nan(a_);
 }
 
-int float64_is_signaling_nan(float64 a_, float_status *status)
+int float64_is_signaling_nan(float64 a_)
 {
     return 0;
 }
@@ -757,15 +724,15 @@ int float64_is_signaling_nan(float64 a_, float_status *status)
 | NaN; otherwise returns 0.
 *----------------------------------------------------------------------------*/
 
-int float64_is_quiet_nan(float64 a_, float_status *status)
+int float64_is_quiet_nan( float64 a_ )
 {
     uint64_t a = float64_val(a_);
-    if (status->snan_bit_is_one) {
-        return (((a >> 51) & 0xFFF) == 0xFFE)
-            && (a & 0x0007FFFFFFFFFFFFULL);
-    } else {
-        return ((a << 1) >= 0xFFF0000000000000ULL);
-    }
+#if SNAN_BIT_IS_ONE
+    return (((a >> 51) & 0xfff) == 0xffe)
+           && (a & 0x0007ffffffffffffULL);
+#else
+    return ((a << 1) >= 0xfff0000000000000ULL);
+#endif
 }
 
 /*----------------------------------------------------------------------------
@@ -773,15 +740,16 @@ int float64_is_quiet_nan(float64 a_, float_status *status)
 | NaN; otherwise returns 0.
 *----------------------------------------------------------------------------*/
 
-int float64_is_signaling_nan(float64 a_, float_status *status)
+int float64_is_signaling_nan( float64 a_ )
 {
     uint64_t a = float64_val(a_);
-    if (status->snan_bit_is_one) {
-        return ((a << 1) >= 0xFFF0000000000000ULL);
-    } else {
-        return (((a >> 51) & 0xFFF) == 0xFFE)
-            && (a & LIT64(0x0007FFFFFFFFFFFF));
-    }
+#if SNAN_BIT_IS_ONE
+    return ((a << 1) >= 0xfff0000000000000ULL);
+#else
+    return
+           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
+        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
+#endif
 }
 #endif
 
@@ -790,16 +758,20 @@ int float64_is_signaling_nan(float64 a_, float_status *status)
 | signaling NaN; otherwise returns `a'.
 *----------------------------------------------------------------------------*/
 
-float64 float64_maybe_silence_nan(float64 a_, float_status *status)
+float64 float64_maybe_silence_nan( float64 a_ )
 {
-    if (float64_is_signaling_nan(a_, status)) {
-        if (status->snan_bit_is_one) {
-            return float64_default_nan(status);
-        } else {
-            uint64_t a = float64_val(a_);
-            a |= LIT64(0x0008000000000000);
-            return make_float64(a);
-        }
+    if (float64_is_signaling_nan(a_)) {
+#if SNAN_BIT_IS_ONE
+#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
+        return float64_default_nan;
+#  else
+#    error Rules for silencing a signaling NaN are target-specific
+#  endif
+#else
+        uint64_t a = float64_val(a_);
+        a |= LIT64( 0x0008000000000000 );
+        return make_float64(a);
+#endif
     }
     return a_;
 }
@@ -814,12 +786,12 @@ static commonNaNT float64ToCommonNaN(float64 a, float_status *status)
 {
     commonNaNT z;
 
-    if (float64_is_signaling_nan(a, status)) {
+    if (float64_is_signaling_nan(a)) {
         float_raise(float_flag_invalid, status);
     }
-    z.sign = float64_val(a) >> 63;
+    z.sign = float64_val(a)>>63;
     z.low = 0;
-    z.high = float64_val(a) << 12;
+    z.high = float64_val(a)<<12;
     return z;
 }
 
@@ -830,20 +802,19 @@ static commonNaNT float64ToCommonNaN(float64 a, float_status *status)
 
 static float64 commonNaNToFloat64(commonNaNT a, float_status *status)
 {
-    uint64_t mantissa = a.high >> 12;
+    uint64_t mantissa = a.high>>12;
 
     if (status->default_nan_mode) {
-        return float64_default_nan(status);
+        return float64_default_nan;
     }
 
-    if (mantissa) {
+    if ( mantissa )
         return make_float64(
-              (((uint64_t) a.sign) << 63)
-            | LIT64(0x7FF0000000000000)
-            | (a.high >> 12));
-    } else {
-        return float64_default_nan(status);
-    }
+              ( ( (uint64_t) a.sign )<<63 )
+            | LIT64( 0x7FF0000000000000 )
+            | ( a.high>>12 ));
+    else
+        return float64_default_nan;
 }
 
 /*----------------------------------------------------------------------------
@@ -858,10 +829,10 @@ static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status)
     flag aIsLargerSignificand;
     uint64_t av, bv;
 
-    aIsQuietNaN = float64_is_quiet_nan(a, status);
-    aIsSignalingNaN = float64_is_signaling_nan(a, status);
-    bIsQuietNaN = float64_is_quiet_nan(b, status);
-    bIsSignalingNaN = float64_is_signaling_nan(b, status);
+    aIsQuietNaN = float64_is_quiet_nan( a );
+    aIsSignalingNaN = float64_is_signaling_nan( a );
+    bIsQuietNaN = float64_is_quiet_nan( b );
+    bIsSignalingNaN = float64_is_signaling_nan( b );
     av = float64_val(a);
     bv = float64_val(b);
 
@@ -869,13 +840,12 @@ static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status)
         float_raise(float_flag_invalid, status);
     }
 
-    if (status->default_nan_mode) {
-        return float64_default_nan(status);
-    }
+    if (status->default_nan_mode)
+        return float64_default_nan;
 
-    if ((uint64_t)(av << 1) < (uint64_t)(bv << 1)) {
+    if ((uint64_t)(av<<1) < (uint64_t)(bv<<1)) {
         aIsLargerSignificand = 0;
-    } else if ((uint64_t)(bv << 1) < (uint64_t)(av << 1)) {
+    } else if ((uint64_t)(bv<<1) < (uint64_t)(av<<1)) {
         aIsLargerSignificand = 1;
     } else {
         aIsLargerSignificand = (av < bv) ? 1 : 0;
@@ -883,9 +853,9 @@ static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status)
 
     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                 aIsLargerSignificand)) {
-        return float64_maybe_silence_nan(b, status);
+        return float64_maybe_silence_nan(b);
     } else {
-        return float64_maybe_silence_nan(a, status);
+        return float64_maybe_silence_nan(a);
     }
 }
 
@@ -906,12 +876,12 @@ static float64 propagateFloat64MulAddNaN(float64 a, float64 b,
         cIsQuietNaN, cIsSignalingNaN;
     int which;
 
-    aIsQuietNaN = float64_is_quiet_nan(a, status);
-    aIsSignalingNaN = float64_is_signaling_nan(a, status);
-    bIsQuietNaN = float64_is_quiet_nan(b, status);
-    bIsSignalingNaN = float64_is_signaling_nan(b, status);
-    cIsQuietNaN = float64_is_quiet_nan(c, status);
-    cIsSignalingNaN = float64_is_signaling_nan(c, status);
+    aIsQuietNaN = float64_is_quiet_nan(a);
+    aIsSignalingNaN = float64_is_signaling_nan(a);
+    bIsQuietNaN = float64_is_quiet_nan(b);
+    bIsSignalingNaN = float64_is_signaling_nan(b);
+    cIsQuietNaN = float64_is_quiet_nan(c);
+    cIsSignalingNaN = float64_is_signaling_nan(c);
 
     if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
         float_raise(float_flag_invalid, status);
@@ -925,29 +895,29 @@ static float64 propagateFloat64MulAddNaN(float64 a, float64 b,
         /* Note that this check is after pickNaNMulAdd so that function
          * has an opportunity to set the Invalid flag.
          */
-        return float64_default_nan(status);
+        return float64_default_nan;
     }
 
     switch (which) {
     case 0:
-        return float64_maybe_silence_nan(a, status);
+        return float64_maybe_silence_nan(a);
     case 1:
-        return float64_maybe_silence_nan(b, status);
+        return float64_maybe_silence_nan(b);
     case 2:
-        return float64_maybe_silence_nan(c, status);
+        return float64_maybe_silence_nan(c);
     case 3:
     default:
-        return float64_default_nan(status);
+        return float64_default_nan;
     }
 }
 
 #ifdef NO_SIGNALING_NANS
-int floatx80_is_quiet_nan(floatx80 a_, float_status *status)
+int floatx80_is_quiet_nan(floatx80 a_)
 {
     return floatx80_is_any_nan(a_);
 }
 
-int floatx80_is_signaling_nan(floatx80 a_, float_status *status)
+int floatx80_is_signaling_nan(floatx80 a_)
 {
     return 0;
 }
@@ -958,19 +928,19 @@ int floatx80_is_signaling_nan(floatx80 a_, float_status *status)
 | function for other types as floatx80 has an explicit bit.
 *----------------------------------------------------------------------------*/
 
-int floatx80_is_quiet_nan(floatx80 a, float_status *status)
+int floatx80_is_quiet_nan( floatx80 a )
 {
-    if (status->snan_bit_is_one) {
-        uint64_t aLow;
+#if SNAN_BIT_IS_ONE
+    uint64_t aLow;
 
-        aLow = a.low & ~0x4000000000000000ULL;
-        return ((a.high & 0x7FFF) == 0x7FFF)
-            && (aLow << 1)
-            && (a.low == aLow);
-    } else {
-        return ((a.high & 0x7FFF) == 0x7FFF)
-            && (LIT64(0x8000000000000000) <= ((uint64_t)(a.low << 1)));
-    }
+    aLow = a.low & ~0x4000000000000000ULL;
+    return ((a.high & 0x7fff) == 0x7fff)
+        && (aLow << 1)
+        && (a.low == aLow);
+#else
+    return ( ( a.high & 0x7FFF ) == 0x7FFF )
+        && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
+#endif
 }
 
 /*----------------------------------------------------------------------------
@@ -979,19 +949,20 @@ int floatx80_is_quiet_nan(floatx80 a, float_status *status)
 | function for other types as floatx80 has an explicit bit.
 *----------------------------------------------------------------------------*/
 
-int floatx80_is_signaling_nan(floatx80 a, float_status *status)
+int floatx80_is_signaling_nan( floatx80 a )
 {
-    if (status->snan_bit_is_one) {
-        return ((a.high & 0x7FFF) == 0x7FFF)
-            && ((a.low << 1) >= 0x8000000000000000ULL);
-    } else {
-        uint64_t aLow;
+#if SNAN_BIT_IS_ONE
+    return ((a.high & 0x7fff) == 0x7fff)
+        && ((a.low << 1) >= 0x8000000000000000ULL);
+#else
+    uint64_t aLow;
 
-        aLow = a.low & ~LIT64(0x4000000000000000);
-        return ((a.high & 0x7FFF) == 0x7FFF)
-            && (uint64_t)(aLow << 1)
-            && (a.low == aLow);
-    }
+    aLow = a.low & ~ LIT64( 0x4000000000000000 );
+    return
+           ( ( a.high & 0x7FFF ) == 0x7FFF )
+        && (uint64_t) ( aLow<<1 )
+        && ( a.low == aLow );
+#endif
 }
 #endif
 
@@ -1000,15 +971,20 @@ int floatx80_is_signaling_nan(floatx80 a, float_status *status)
 | `a' is a signaling NaN; otherwise returns `a'.
 *----------------------------------------------------------------------------*/
 
-floatx80 floatx80_maybe_silence_nan(floatx80 a, float_status *status)
+floatx80 floatx80_maybe_silence_nan( floatx80 a )
 {
-    if (floatx80_is_signaling_nan(a, status)) {
-        if (status->snan_bit_is_one) {
-            a = floatx80_default_nan(status);
-        } else {
-            a.low |= LIT64(0xC000000000000000);
-            return a;
-        }
+    if (floatx80_is_signaling_nan(a)) {
+#if SNAN_BIT_IS_ONE
+#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
+        a.low = floatx80_default_nan_low;
+        a.high = floatx80_default_nan_high;
+#  else
+#    error Rules for silencing a signaling NaN are target-specific
+#  endif
+#else
+        a.low |= LIT64( 0xC000000000000000 );
+        return a;
+#endif
     }
     return a;
 }
@@ -1021,21 +997,19 @@ floatx80 floatx80_maybe_silence_nan(floatx80 a, float_status *status)
 
 static commonNaNT floatx80ToCommonNaN(floatx80 a, float_status *status)
 {
-    floatx80 dflt;
     commonNaNT z;
 
-    if (floatx80_is_signaling_nan(a, status)) {
+    if (floatx80_is_signaling_nan(a)) {
         float_raise(float_flag_invalid, status);
     }
-    if (a.low >> 63) {
+    if ( a.low >> 63 ) {
         z.sign = a.high >> 15;
         z.low = 0;
         z.high = a.low << 1;
     } else {
-        dflt = floatx80_default_nan(status);
-        z.sign = dflt.high >> 15;
+        z.sign = floatx80_default_nan_high >> 15;
         z.low = 0;
-        z.high = dflt.low << 1;
+        z.high = floatx80_default_nan_low << 1;
     }
     return z;
 }
@@ -1050,15 +1024,19 @@ static floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status)
     floatx80 z;
 
     if (status->default_nan_mode) {
-        return floatx80_default_nan(status);
+        z.low = floatx80_default_nan_low;
+        z.high = floatx80_default_nan_high;
+        return z;
     }
 
     if (a.high >> 1) {
-        z.low = LIT64(0x8000000000000000) | a.high >> 1;
-        z.high = (((uint16_t)a.sign) << 15) | 0x7FFF;
+        z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
+        z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
     } else {
-        z = floatx80_default_nan(status);
+        z.low = floatx80_default_nan_low;
+        z.high = floatx80_default_nan_high;
     }
+
     return z;
 }
 
@@ -1074,17 +1052,19 @@ static floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b,
     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
     flag aIsLargerSignificand;
 
-    aIsQuietNaN = floatx80_is_quiet_nan(a, status);
-    aIsSignalingNaN = floatx80_is_signaling_nan(a, status);
-    bIsQuietNaN = floatx80_is_quiet_nan(b, status);
-    bIsSignalingNaN = floatx80_is_signaling_nan(b, status);
+    aIsQuietNaN = floatx80_is_quiet_nan( a );
+    aIsSignalingNaN = floatx80_is_signaling_nan( a );
+    bIsQuietNaN = floatx80_is_quiet_nan( b );
+    bIsSignalingNaN = floatx80_is_signaling_nan( b );
 
     if (aIsSignalingNaN | bIsSignalingNaN) {
         float_raise(float_flag_invalid, status);
     }
 
     if (status->default_nan_mode) {
-        return floatx80_default_nan(status);
+        a.low = floatx80_default_nan_low;
+        a.high = floatx80_default_nan_high;
+        return a;
     }
 
     if (a.low < b.low) {
@@ -1097,19 +1077,19 @@ static floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b,
 
     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                 aIsLargerSignificand)) {
-        return floatx80_maybe_silence_nan(b, status);
+        return floatx80_maybe_silence_nan(b);
     } else {
-        return floatx80_maybe_silence_nan(a, status);
+        return floatx80_maybe_silence_nan(a);
     }
 }
 
 #ifdef NO_SIGNALING_NANS
-int float128_is_quiet_nan(float128 a_, float_status *status)
+int float128_is_quiet_nan(float128 a_)
 {
     return float128_is_any_nan(a_);
 }
 
-int float128_is_signaling_nan(float128 a_, float_status *status)
+int float128_is_signaling_nan(float128 a_)
 {
     return 0;
 }
@@ -1119,15 +1099,16 @@ int float128_is_signaling_nan(float128 a_, float_status *status)
 | NaN; otherwise returns 0.
 *----------------------------------------------------------------------------*/
 
-int float128_is_quiet_nan(float128 a, float_status *status)
+int float128_is_quiet_nan( float128 a )
 {
-    if (status->snan_bit_is_one) {
-        return (((a.high >> 47) & 0xFFFF) == 0xFFFE)
-            && (a.low || (a.high & 0x00007FFFFFFFFFFFULL));
-    } else {
-        return ((a.high << 1) >= 0xFFFF000000000000ULL)
-            && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL));
-    }
+#if SNAN_BIT_IS_ONE
+    return (((a.high >> 47) & 0xffff) == 0xfffe)
+        && (a.low || (a.high & 0x00007fffffffffffULL));
+#else
+    return
+        ((a.high << 1) >= 0xffff000000000000ULL)
+        && (a.low || (a.high & 0x0000ffffffffffffULL));
+#endif
 }
 
 /*----------------------------------------------------------------------------
@@ -1135,15 +1116,17 @@ int float128_is_quiet_nan(float128 a, float_status *status)
 | signaling NaN; otherwise returns 0.
 *----------------------------------------------------------------------------*/
 
-int float128_is_signaling_nan(float128 a, float_status *status)
+int float128_is_signaling_nan( float128 a )
 {
-    if (status->snan_bit_is_one) {
-        return ((a.high << 1) >= 0xFFFF000000000000ULL)
-            && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL));
-    } else {
-        return (((a.high >> 47) & 0xFFFF) == 0xFFFE)
-            && (a.low || (a.high & LIT64(0x00007FFFFFFFFFFF)));
-    }
+#if SNAN_BIT_IS_ONE
+    return
+        ((a.high << 1) >= 0xffff000000000000ULL)
+        && (a.low || (a.high & 0x0000ffffffffffffULL));
+#else
+    return
+           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
+        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
+#endif
 }
 #endif
 
@@ -1152,15 +1135,20 @@ int float128_is_signaling_nan(float128 a, float_status *status)
 | a signaling NaN; otherwise returns `a'.
 *----------------------------------------------------------------------------*/
 
-float128 float128_maybe_silence_nan(float128 a, float_status *status)
+float128 float128_maybe_silence_nan( float128 a )
 {
-    if (float128_is_signaling_nan(a, status)) {
-        if (status->snan_bit_is_one) {
-            a = float128_default_nan(status);
-        } else {
-            a.high |= LIT64(0x0000800000000000);
-            return a;
-        }
+    if (float128_is_signaling_nan(a)) {
+#if SNAN_BIT_IS_ONE
+#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
+        a.low = float128_default_nan_low;
+        a.high = float128_default_nan_high;
+#  else
+#    error Rules for silencing a signaling NaN are target-specific
+#  endif
+#else
+        a.high |= LIT64( 0x0000800000000000 );
+        return a;
+#endif
     }
     return a;
 }
@@ -1175,11 +1163,11 @@ static commonNaNT float128ToCommonNaN(float128 a, float_status *status)
 {
     commonNaNT z;
 
-    if (float128_is_signaling_nan(a, status)) {
+    if (float128_is_signaling_nan(a)) {
         float_raise(float_flag_invalid, status);
     }
-    z.sign = a.high >> 63;
-    shortShift128Left(a.high, a.low, 16, &z.high, &z.low);
+    z.sign = a.high>>63;
+    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
     return z;
 }
 
@@ -1193,11 +1181,13 @@ static float128 commonNaNToFloat128(commonNaNT a, float_status *status)
     float128 z;
 
     if (status->default_nan_mode) {
-        return float128_default_nan(status);
+        z.low = float128_default_nan_low;
+        z.high = float128_default_nan_high;
+        return z;
     }
 
-    shift128Right(a.high, a.low, 16, &z.high, &z.low);
-    z.high |= (((uint64_t)a.sign) << 63) | LIT64(0x7FFF000000000000);
+    shift128Right( a.high, a.low, 16, &z.high, &z.low );
+    z.high |= ( ( (uint64_t) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
     return z;
 }
 
@@ -1213,22 +1203,24 @@ static float128 propagateFloat128NaN(float128 a, float128 b,
     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
     flag aIsLargerSignificand;
 
-    aIsQuietNaN = float128_is_quiet_nan(a, status);
-    aIsSignalingNaN = float128_is_signaling_nan(a, status);
-    bIsQuietNaN = float128_is_quiet_nan(b, status);
-    bIsSignalingNaN = float128_is_signaling_nan(b, status);
+    aIsQuietNaN = float128_is_quiet_nan( a );
+    aIsSignalingNaN = float128_is_signaling_nan( a );
+    bIsQuietNaN = float128_is_quiet_nan( b );
+    bIsSignalingNaN = float128_is_signaling_nan( b );
 
     if (aIsSignalingNaN | bIsSignalingNaN) {
         float_raise(float_flag_invalid, status);
     }
 
     if (status->default_nan_mode) {
-        return float128_default_nan(status);
+        a.low = float128_default_nan_low;
+        a.high = float128_default_nan_high;
+        return a;
     }
 
-    if (lt128(a.high << 1, a.low, b.high << 1, b.low)) {
+    if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
         aIsLargerSignificand = 0;
-    } else if (lt128(b.high << 1, b.low, a.high << 1, a.low)) {
+    } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
         aIsLargerSignificand = 1;
     } else {
         aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
@@ -1236,8 +1228,9 @@ static float128 propagateFloat128NaN(float128 a, float128 b,
 
     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                 aIsLargerSignificand)) {
-        return float128_maybe_silence_nan(b, status);
+        return float128_maybe_silence_nan(b);
     } else {
-        return float128_maybe_silence_nan(a, status);
+        return float128_maybe_silence_nan(a);
     }
 }
+
index 9b1eccf..166c48e 100644 (file)
@@ -2105,7 +2105,7 @@ static float32 subFloat32Sigs(float32 a, float32 b, flag zSign,
             return propagateFloat32NaN(a, b, status);
         }
         float_raise(float_flag_invalid, status);
-        return float32_default_nan(status);
+        return float32_default_nan;
     }
     if ( aExp == 0 ) {
         aExp = 1;
@@ -2234,7 +2234,7 @@ float32 float32_mul(float32 a, float32 b, float_status *status)
         }
         if ( ( bExp | bSig ) == 0 ) {
             float_raise(float_flag_invalid, status);
-            return float32_default_nan(status);
+            return float32_default_nan;
         }
         return packFloat32( zSign, 0xFF, 0 );
     }
@@ -2244,7 +2244,7 @@ float32 float32_mul(float32 a, float32 b, float_status *status)
         }
         if ( ( aExp | aSig ) == 0 ) {
             float_raise(float_flag_invalid, status);
-            return float32_default_nan(status);
+            return float32_default_nan;
         }
         return packFloat32( zSign, 0xFF, 0 );
     }
@@ -2299,7 +2299,7 @@ float32 float32_div(float32 a, float32 b, float_status *status)
                 return propagateFloat32NaN(a, b, status);
             }
             float_raise(float_flag_invalid, status);
-            return float32_default_nan(status);
+            return float32_default_nan;
         }
         return packFloat32( zSign, 0xFF, 0 );
     }
@@ -2313,7 +2313,7 @@ float32 float32_div(float32 a, float32 b, float_status *status)
         if ( bSig == 0 ) {
             if ( ( aExp | aSig ) == 0 ) {
                 float_raise(float_flag_invalid, status);
-                return float32_default_nan(status);
+                return float32_default_nan;
             }
             float_raise(float_flag_divbyzero, status);
             return packFloat32( zSign, 0xFF, 0 );
@@ -2367,7 +2367,7 @@ float32 float32_rem(float32 a, float32 b, float_status *status)
             return propagateFloat32NaN(a, b, status);
         }
         float_raise(float_flag_invalid, status);
-        return float32_default_nan(status);
+        return float32_default_nan;
     }
     if ( bExp == 0xFF ) {
         if (bSig) {
@@ -2378,7 +2378,7 @@ float32 float32_rem(float32 a, float32 b, float_status *status)
     if ( bExp == 0 ) {
         if ( bSig == 0 ) {
             float_raise(float_flag_invalid, status);
-            return float32_default_nan(status);
+            return float32_default_nan;
         }
         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
     }
@@ -2493,7 +2493,7 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags,
 
     if (infzero) {
         float_raise(float_flag_invalid, status);
-        return float32_default_nan(status);
+        return float32_default_nan;
     }
 
     if (flags & float_muladd_negate_c) {
@@ -2514,7 +2514,7 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags,
         if (pInf && (pSign ^ cSign)) {
             /* addition of opposite-signed infinities => InvalidOperation */
             float_raise(float_flag_invalid, status);
-            return float32_default_nan(status);
+            return float32_default_nan;
         }
         /* Otherwise generate an infinity of the same sign */
         return packFloat32(cSign ^ signflip, 0xff, 0);
@@ -2690,12 +2690,12 @@ float32 float32_sqrt(float32 a, float_status *status)
         }
         if ( ! aSign ) return a;
         float_raise(float_flag_invalid, status);
-        return float32_default_nan(status);
+        return float32_default_nan;
     }
     if ( aSign ) {
         if ( ( aExp | aSig ) == 0 ) return a;
         float_raise(float_flag_invalid, status);
-        return float32_default_nan(status);
+        return float32_default_nan;
     }
     if ( aExp == 0 ) {
         if ( aSig == 0 ) return float32_zero;
@@ -2828,7 +2828,7 @@ float32 float32_log2(float32 a, float_status *status)
     }
     if ( aSign ) {
         float_raise(float_flag_invalid, status);
-        return float32_default_nan(status);
+        return float32_default_nan;
     }
     if ( aExp == 0xFF ) {
         if (aSig) {
@@ -2974,8 +2974,7 @@ int float32_eq_quiet(float32 a, float32 b, float_status *status)
     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
        ) {
-        if (float32_is_signaling_nan(a, status)
-         || float32_is_signaling_nan(b, status)) {
+        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 0;
@@ -3001,8 +3000,7 @@ int float32_le_quiet(float32 a, float32 b, float_status *status)
     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
        ) {
-        if (float32_is_signaling_nan(a, status)
-         || float32_is_signaling_nan(b, status)) {
+        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 0;
@@ -3033,8 +3031,7 @@ int float32_lt_quiet(float32 a, float32 b, float_status *status)
     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
        ) {
-        if (float32_is_signaling_nan(a, status)
-         || float32_is_signaling_nan(b, status)) {
+        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 0;
@@ -3063,8 +3060,7 @@ int float32_unordered_quiet(float32 a, float32 b, float_status *status)
     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
        ) {
-        if (float32_is_signaling_nan(a, status)
-         || float32_is_signaling_nan(b, status)) {
+        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 1;
@@ -3900,7 +3896,7 @@ static float64 subFloat64Sigs(float64 a, float64 b, flag zSign,
             return propagateFloat64NaN(a, b, status);
         }
         float_raise(float_flag_invalid, status);
-        return float64_default_nan(status);
+        return float64_default_nan;
     }
     if ( aExp == 0 ) {
         aExp = 1;
@@ -4027,7 +4023,7 @@ float64 float64_mul(float64 a, float64 b, float_status *status)
         }
         if ( ( bExp | bSig ) == 0 ) {
             float_raise(float_flag_invalid, status);
-            return float64_default_nan(status);
+            return float64_default_nan;
         }
         return packFloat64( zSign, 0x7FF, 0 );
     }
@@ -4037,7 +4033,7 @@ float64 float64_mul(float64 a, float64 b, float_status *status)
         }
         if ( ( aExp | aSig ) == 0 ) {
             float_raise(float_flag_invalid, status);
-            return float64_default_nan(status);
+            return float64_default_nan;
         }
         return packFloat64( zSign, 0x7FF, 0 );
     }
@@ -4094,7 +4090,7 @@ float64 float64_div(float64 a, float64 b, float_status *status)
                 return propagateFloat64NaN(a, b, status);
             }
             float_raise(float_flag_invalid, status);
-            return float64_default_nan(status);
+            return float64_default_nan;
         }
         return packFloat64( zSign, 0x7FF, 0 );
     }
@@ -4108,7 +4104,7 @@ float64 float64_div(float64 a, float64 b, float_status *status)
         if ( bSig == 0 ) {
             if ( ( aExp | aSig ) == 0 ) {
                 float_raise(float_flag_invalid, status);
-                return float64_default_nan(status);
+                return float64_default_nan;
             }
             float_raise(float_flag_divbyzero, status);
             return packFloat64( zSign, 0x7FF, 0 );
@@ -4166,7 +4162,7 @@ float64 float64_rem(float64 a, float64 b, float_status *status)
             return propagateFloat64NaN(a, b, status);
         }
         float_raise(float_flag_invalid, status);
-        return float64_default_nan(status);
+        return float64_default_nan;
     }
     if ( bExp == 0x7FF ) {
         if (bSig) {
@@ -4177,7 +4173,7 @@ float64 float64_rem(float64 a, float64 b, float_status *status)
     if ( bExp == 0 ) {
         if ( bSig == 0 ) {
             float_raise(float_flag_invalid, status);
-            return float64_default_nan(status);
+            return float64_default_nan;
         }
         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
     }
@@ -4279,7 +4275,7 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags,
 
     if (infzero) {
         float_raise(float_flag_invalid, status);
-        return float64_default_nan(status);
+        return float64_default_nan;
     }
 
     if (flags & float_muladd_negate_c) {
@@ -4300,7 +4296,7 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags,
         if (pInf && (pSign ^ cSign)) {
             /* addition of opposite-signed infinities => InvalidOperation */
             float_raise(float_flag_invalid, status);
-            return float64_default_nan(status);
+            return float64_default_nan;
         }
         /* Otherwise generate an infinity of the same sign */
         return packFloat64(cSign ^ signflip, 0x7ff, 0);
@@ -4498,12 +4494,12 @@ float64 float64_sqrt(float64 a, float_status *status)
         }
         if ( ! aSign ) return a;
         float_raise(float_flag_invalid, status);
-        return float64_default_nan(status);
+        return float64_default_nan;
     }
     if ( aSign ) {
         if ( ( aExp | aSig ) == 0 ) return a;
         float_raise(float_flag_invalid, status);
-        return float64_default_nan(status);
+        return float64_default_nan;
     }
     if ( aExp == 0 ) {
         if ( aSig == 0 ) return float64_zero;
@@ -4551,7 +4547,7 @@ float64 float64_log2(float64 a, float_status *status)
     }
     if ( aSign ) {
         float_raise(float_flag_invalid, status);
-        return float64_default_nan(status);
+        return float64_default_nan;
     }
     if ( aExp == 0x7FF ) {
         if (aSig) {
@@ -4698,8 +4694,7 @@ int float64_eq_quiet(float64 a, float64 b, float_status *status)
     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
        ) {
-        if (float64_is_signaling_nan(a, status)
-         || float64_is_signaling_nan(b, status)) {
+        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 0;
@@ -4727,8 +4722,7 @@ int float64_le_quiet(float64 a, float64 b, float_status *status)
     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
        ) {
-        if (float64_is_signaling_nan(a, status)
-         || float64_is_signaling_nan(b, status)) {
+        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 0;
@@ -4759,8 +4753,7 @@ int float64_lt_quiet(float64 a, float64 b, float_status *status)
     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
        ) {
-        if (float64_is_signaling_nan(a, status)
-         || float64_is_signaling_nan(b, status)) {
+        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 0;
@@ -4789,8 +4782,7 @@ int float64_unordered_quiet(float64 a, float64 b, float_status *status)
     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
        ) {
-        if (float64_is_signaling_nan(a, status)
-         || float64_is_signaling_nan(b, status)) {
+        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 1;
@@ -5215,6 +5207,7 @@ static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, flag zSign,
     int32_t aExp, bExp, zExp;
     uint64_t aSig, bSig, zSig0, zSig1;
     int32_t expDiff;
+    floatx80 z;
 
     aSig = extractFloatx80Frac( a );
     aExp = extractFloatx80Exp( a );
@@ -5228,7 +5221,9 @@ static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, flag zSign,
             return propagateFloatx80NaN(a, b, status);
         }
         float_raise(float_flag_invalid, status);
-        return floatx80_default_nan(status);
+        z.low = floatx80_default_nan_low;
+        z.high = floatx80_default_nan_high;
+        return z;
     }
     if ( aExp == 0 ) {
         aExp = 1;
@@ -5322,6 +5317,7 @@ floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status *status)
     flag aSign, bSign, zSign;
     int32_t aExp, bExp, zExp;
     uint64_t aSig, bSig, zSig0, zSig1;
+    floatx80 z;
 
     aSig = extractFloatx80Frac( a );
     aExp = extractFloatx80Exp( a );
@@ -5345,7 +5341,9 @@ floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status *status)
         if ( ( aExp | aSig ) == 0 ) {
  invalid:
             float_raise(float_flag_invalid, status);
-            return floatx80_default_nan(status);
+            z.low = floatx80_default_nan_low;
+            z.high = floatx80_default_nan_high;
+            return z;
         }
         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
     }
@@ -5379,6 +5377,7 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status)
     int32_t aExp, bExp, zExp;
     uint64_t aSig, bSig, zSig0, zSig1;
     uint64_t rem0, rem1, rem2, term0, term1, term2;
+    floatx80 z;
 
     aSig = extractFloatx80Frac( a );
     aExp = extractFloatx80Exp( a );
@@ -5410,7 +5409,9 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status)
             if ( ( aExp | aSig ) == 0 ) {
  invalid:
                 float_raise(float_flag_invalid, status);
-                return floatx80_default_nan(status);
+                z.low = floatx80_default_nan_low;
+                z.high = floatx80_default_nan_high;
+                return z;
             }
             float_raise(float_flag_divbyzero, status);
             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
@@ -5460,6 +5461,7 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
     int32_t aExp, bExp, expDiff;
     uint64_t aSig0, aSig1, bSig;
     uint64_t q, term0, term1, alternateASig0, alternateASig1;
+    floatx80 z;
 
     aSig0 = extractFloatx80Frac( a );
     aExp = extractFloatx80Exp( a );
@@ -5483,7 +5485,9 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
         if ( bSig == 0 ) {
  invalid:
             float_raise(float_flag_invalid, status);
-            return floatx80_default_nan(status);
+            z.low = floatx80_default_nan_low;
+            z.high = floatx80_default_nan_high;
+            return z;
         }
         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
     }
@@ -5555,6 +5559,7 @@ floatx80 floatx80_sqrt(floatx80 a, float_status *status)
     int32_t aExp, zExp;
     uint64_t aSig0, aSig1, zSig0, zSig1, doubleZSig0;
     uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
+    floatx80 z;
 
     aSig0 = extractFloatx80Frac( a );
     aExp = extractFloatx80Exp( a );
@@ -5570,7 +5575,9 @@ floatx80 floatx80_sqrt(floatx80 a, float_status *status)
         if ( ( aExp | aSig0 ) == 0 ) return a;
  invalid:
         float_raise(float_flag_invalid, status);
-        return floatx80_default_nan(status);
+        z.low = floatx80_default_nan_low;
+        z.high = floatx80_default_nan_high;
+        return z;
     }
     if ( aExp == 0 ) {
         if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
@@ -5738,8 +5745,8 @@ int floatx80_eq_quiet(floatx80 a, floatx80 b, float_status *status)
          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
        ) {
-        if (floatx80_is_signaling_nan(a, status)
-         || floatx80_is_signaling_nan(b, status)) {
+        if (    floatx80_is_signaling_nan( a )
+             || floatx80_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 0;
@@ -5769,8 +5776,8 @@ int floatx80_le_quiet(floatx80 a, floatx80 b, float_status *status)
          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
        ) {
-        if (floatx80_is_signaling_nan(a, status)
-         || floatx80_is_signaling_nan(b, status)) {
+        if (    floatx80_is_signaling_nan( a )
+             || floatx80_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 0;
@@ -5805,8 +5812,8 @@ int floatx80_lt_quiet(floatx80 a, floatx80 b, float_status *status)
          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
        ) {
-        if (floatx80_is_signaling_nan(a, status)
-         || floatx80_is_signaling_nan(b, status)) {
+        if (    floatx80_is_signaling_nan( a )
+             || floatx80_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 0;
@@ -5838,8 +5845,8 @@ int floatx80_unordered_quiet(floatx80 a, floatx80 b, float_status *status)
          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
        ) {
-        if (floatx80_is_signaling_nan(a, status)
-         || floatx80_is_signaling_nan(b, status)) {
+        if (    floatx80_is_signaling_nan( a )
+             || floatx80_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 1;
@@ -6378,6 +6385,7 @@ static float128 subFloat128Sigs(float128 a, float128 b, flag zSign,
     int32_t aExp, bExp, zExp;
     uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
     int32_t expDiff;
+    float128 z;
 
     aSig1 = extractFloat128Frac1( a );
     aSig0 = extractFloat128Frac0( a );
@@ -6395,7 +6403,9 @@ static float128 subFloat128Sigs(float128 a, float128 b, flag zSign,
             return propagateFloat128NaN(a, b, status);
         }
         float_raise(float_flag_invalid, status);
-        return float128_default_nan(status);
+        z.low = float128_default_nan_low;
+        z.high = float128_default_nan_high;
+        return z;
     }
     if ( aExp == 0 ) {
         aExp = 1;
@@ -6505,6 +6515,7 @@ float128 float128_mul(float128 a, float128 b, float_status *status)
     flag aSign, bSign, zSign;
     int32_t aExp, bExp, zExp;
     uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
+    float128 z;
 
     aSig1 = extractFloat128Frac1( a );
     aSig0 = extractFloat128Frac0( a );
@@ -6530,7 +6541,9 @@ float128 float128_mul(float128 a, float128 b, float_status *status)
         if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
  invalid:
             float_raise(float_flag_invalid, status);
-            return float128_default_nan(status);
+            z.low = float128_default_nan_low;
+            z.high = float128_default_nan_high;
+            return z;
         }
         return packFloat128( zSign, 0x7FFF, 0, 0 );
     }
@@ -6569,6 +6582,7 @@ float128 float128_div(float128 a, float128 b, float_status *status)
     int32_t aExp, bExp, zExp;
     uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
     uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
+    float128 z;
 
     aSig1 = extractFloat128Frac1( a );
     aSig0 = extractFloat128Frac0( a );
@@ -6602,7 +6616,9 @@ float128 float128_div(float128 a, float128 b, float_status *status)
             if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
  invalid:
                 float_raise(float_flag_invalid, status);
-                return float128_default_nan(status);
+                z.low = float128_default_nan_low;
+                z.high = float128_default_nan_high;
+                return z;
             }
             float_raise(float_flag_divbyzero, status);
             return packFloat128( zSign, 0x7FFF, 0, 0 );
@@ -6657,6 +6673,7 @@ float128 float128_rem(float128 a, float128 b, float_status *status)
     uint64_t aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;
     uint64_t allZero, alternateASig0, alternateASig1, sigMean1;
     int64_t sigMean0;
+    float128 z;
 
     aSig1 = extractFloat128Frac1( a );
     aSig0 = extractFloat128Frac0( a );
@@ -6682,7 +6699,9 @@ float128 float128_rem(float128 a, float128 b, float_status *status)
         if ( ( bSig0 | bSig1 ) == 0 ) {
  invalid:
             float_raise(float_flag_invalid, status);
-            return float128_default_nan(status);
+            z.low = float128_default_nan_low;
+            z.high = float128_default_nan_high;
+            return z;
         }
         normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
     }
@@ -6763,6 +6782,7 @@ float128 float128_sqrt(float128 a, float_status *status)
     int32_t aExp, zExp;
     uint64_t aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0;
     uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
+    float128 z;
 
     aSig1 = extractFloat128Frac1( a );
     aSig0 = extractFloat128Frac0( a );
@@ -6779,7 +6799,9 @@ float128 float128_sqrt(float128 a, float_status *status)
         if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
  invalid:
         float_raise(float_flag_invalid, status);
-        return float128_default_nan(status);
+        z.low = float128_default_nan_low;
+        z.high = float128_default_nan_high;
+        return z;
     }
     if ( aExp == 0 ) {
         if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 );
@@ -6947,8 +6969,8 @@ int float128_eq_quiet(float128 a, float128 b, float_status *status)
          || (    ( extractFloat128Exp( b ) == 0x7FFF )
               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
        ) {
-        if (float128_is_signaling_nan(a, status)
-         || float128_is_signaling_nan(b, status)) {
+        if (    float128_is_signaling_nan( a )
+             || float128_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 0;
@@ -6978,8 +7000,8 @@ int float128_le_quiet(float128 a, float128 b, float_status *status)
          || (    ( extractFloat128Exp( b ) == 0x7FFF )
               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
        ) {
-        if (float128_is_signaling_nan(a, status)
-         || float128_is_signaling_nan(b, status)) {
+        if (    float128_is_signaling_nan( a )
+             || float128_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 0;
@@ -7014,8 +7036,8 @@ int float128_lt_quiet(float128 a, float128 b, float_status *status)
          || (    ( extractFloat128Exp( b ) == 0x7FFF )
               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
        ) {
-        if (float128_is_signaling_nan(a, status)
-         || float128_is_signaling_nan(b, status)) {
+        if (    float128_is_signaling_nan( a )
+             || float128_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 0;
@@ -7048,8 +7070,8 @@ int float128_unordered_quiet(float128 a, float128 b, float_status *status)
          || (    ( extractFloat128Exp( b ) == 0x7FFF )
               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
        ) {
-        if (float128_is_signaling_nan(a, status)
-         || float128_is_signaling_nan(b, status)) {
+        if (    float128_is_signaling_nan( a )
+             || float128_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return 1;
@@ -7329,8 +7351,8 @@ static inline int float ## s ## _compare_internal(float ## s a, float ## s b,\
         ( ( extractFloat ## s ## Exp( b ) == nan_exp ) &&                    \
           extractFloat ## s ## Frac( b ) )) {                                \
         if (!is_quiet ||                                                     \
-            float ## s ## _is_signaling_nan(a, status) ||                  \
-            float ## s ## _is_signaling_nan(b, status)) {                 \
+            float ## s ## _is_signaling_nan( a ) ||                          \
+            float ## s ## _is_signaling_nan( b ) ) {                         \
             float_raise(float_flag_invalid, status);                         \
         }                                                                    \
         return float_relation_unordered;                                     \
@@ -7379,8 +7401,8 @@ static inline int floatx80_compare_internal(floatx80 a, floatx80 b,
         ( ( extractFloatx80Exp( b ) == 0x7fff ) &&
           ( extractFloatx80Frac( b )<<1 ) )) {
         if (!is_quiet ||
-            floatx80_is_signaling_nan(a, status) ||
-            floatx80_is_signaling_nan(b, status)) {
+            floatx80_is_signaling_nan( a ) ||
+            floatx80_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return float_relation_unordered;
@@ -7425,8 +7447,8 @@ static inline int float128_compare_internal(float128 a, float128 b,
         ( ( extractFloat128Exp( b ) == 0x7fff ) &&
           ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )) {
         if (!is_quiet ||
-            float128_is_signaling_nan(a, status) ||
-            float128_is_signaling_nan(b, status)) {
+            float128_is_signaling_nan( a ) ||
+            float128_is_signaling_nan( b ) ) {
             float_raise(float_flag_invalid, status);
         }
         return float_relation_unordered;
@@ -7486,11 +7508,11 @@ static inline float ## s float ## s ## _minmax(float ## s a, float ## s b,     \
     if (float ## s ## _is_any_nan(a) ||                                 \
         float ## s ## _is_any_nan(b)) {                                 \
         if (isieee) {                                                   \
-            if (float ## s ## _is_quiet_nan(a, status) &&               \
+            if (float ## s ## _is_quiet_nan(a) &&                       \
                 !float ## s ##_is_any_nan(b)) {                         \
                 return b;                                               \
-            } else if (float ## s ## _is_quiet_nan(b, status) &&        \
-                       !float ## s ## _is_any_nan(a)) {                \
+            } else if (float ## s ## _is_quiet_nan(b) &&                \
+                       !float ## s ## _is_any_nan(a)) {                 \
                 return a;                                               \
             }                                                           \
         }                                                               \
index 663cad5..fb40bdf 100644 (file)
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <glib/gprintf.h>
 #include <utime.h>
+#include <sys/uio.h>
 
 #include "9p-iov-marshal.h"
 #include "qemu/bswap.h"
@@ -207,25 +209,31 @@ ssize_t v9fs_iov_vmarshal(struct iovec *in_sg, int in_num, size_t offset,
             break;
         }
         case 'w': {
-            uint16_t val = va_arg(ap, int);
+            uint16_t val;
             if (bswap) {
-                val = cpu_to_le16(val);
+                cpu_to_le16w(&val, va_arg(ap, int));
+            } else {
+                val =  va_arg(ap, int);
             }
             copied = v9fs_pack(in_sg, in_num, offset, &val, sizeof(val));
             break;
         }
         case 'd': {
-            uint32_t val = va_arg(ap, uint32_t);
+            uint32_t val;
             if (bswap) {
-                val = cpu_to_le32(val);
+                cpu_to_le32w(&val, va_arg(ap, uint32_t));
+            } else {
+                val =  va_arg(ap, uint32_t);
             }
             copied = v9fs_pack(in_sg, in_num, offset, &val, sizeof(val));
             break;
         }
         case 'q': {
-            uint64_t val = va_arg(ap, uint64_t);
+            uint64_t val;
             if (bswap) {
-                val = cpu_to_le64(val);
+                cpu_to_le64w(&val, va_arg(ap, uint64_t));
+            } else {
+                val =  va_arg(ap, uint64_t);
             }
             copied = v9fs_pack(in_sg, in_num, offset, &val, sizeof(val));
             break;
index 1fb5016..6bccbfb 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef QEMU_9P_IOV_MARSHAL_H
-#define QEMU_9P_IOV_MARSHAL_H
+#ifndef _QEMU_9P_IOV_MARSHAL_H
+#define _QEMU_9P_IOV_MARSHAL_H
 
 #include "9p-marshal.h"
 
index 238dbf2..183d366 100644 (file)
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <glib/gprintf.h>
 #include <dirent.h>
 #include <utime.h>
+#include <sys/uio.h>
 
 #include "9p-marshal.h"
 
index 140db6d..e91b24e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef QEMU_9P_MARSHAL_H
-#define QEMU_9P_MARSHAL_H
+#ifndef _QEMU_9P_MARSHAL_H
+#define _QEMU_9P_MARSHAL_H
 
 typedef struct V9fsString
 {
index 6db9fea..b8c2602 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 9p
+ * Virtio 9p
  *
  * Copyright IBM, Corp. 2010
  *
  * the COPYING file in the top-level directory.
  *
  */
-
-#ifndef FILE_OP_9P_H
-#define FILE_OP_9P_H
-
+#ifndef _FILEOP_H
+#define _FILEOP_H
 #include <dirent.h>
 #include <utime.h>
+#include <sys/uio.h>
 #include <sys/vfs.h>
 
 #define SM_LOCAL_MODE_BITS    0600
@@ -119,7 +118,8 @@ struct FileOperations
                  int, FsCred *, V9fsFidOpenState *);
     void (*rewinddir)(FsContext *, V9fsFidOpenState *);
     off_t (*telldir)(FsContext *, V9fsFidOpenState *);
-    struct dirent * (*readdir)(FsContext *, V9fsFidOpenState *);
+    int (*readdir_r)(FsContext *, V9fsFidOpenState *,
+                     struct dirent *, struct dirent **);
     void (*seekdir)(FsContext *, V9fsFidOpenState *, off_t);
     ssize_t (*preadv)(FsContext *, V9fsFidOpenState *,
                       const struct iovec *, int, off_t);
index 6dc0fbc..7622e86 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 9p
+ * Virtio 9p
  *
  * Copyright IBM, Corp. 2010
  *
index 1dd8c7a..88a4ac3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 9p
+ * Virtio 9p
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or
  * later.  See the COPYING file in the top-level directory.
index 266e442..bf7f0b0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 9p
+ * Virtio 9p
  *
  * Copyright IBM, Corp. 2010
  *
index 29c9622..9fa45bf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 9p
+ * Virtio 9p
  *
  * Copyright IBM, Corp. 2010
  *
index f4cbb60..6eb2d50 100644 (file)
@@ -15,7 +15,7 @@ provide access to files beyond 9p export path.
 
 2) Running QEMU with root privilege could be a security issue.
 
-To overcome above issues, following approach is used: A new filesystem
+To overcome above issues, following approach is used: A new filesytem
 type 'proxy' is introduced. Proxy FS uses chroot + socket combination
 for securing the vulnerability known with following symbolic links.
 Intention of adding a new filesystem type is to allow qemu to run
index 5da66f1..0e431fd 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -19,7 +19,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu/cutils.h"
-#include "cpu.h"
+
 #ifdef CONFIG_USER_ONLY
 #include "qemu.h"
 #else
@@ -35,7 +35,6 @@
 #include "qemu/sockets.h"
 #include "sysemu/kvm.h"
 #include "exec/semihost.h"
-#include "exec/exec-all.h"
 
 #ifdef CONFIG_USER_ONLY
 #define GDB_ATTACHED "0"
@@ -333,7 +332,7 @@ static int get_char(GDBState *s)
         if (ret < 0) {
             if (errno == ECONNRESET)
                 s->fd = -1;
-            if (errno != EINTR)
+            if (errno != EINTR && errno != EAGAIN)
                 return -1;
         } else if (ret == 0) {
             close(s->fd);
@@ -394,7 +393,7 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int len)
     while (len > 0) {
         ret = send(s->fd, buf, len, 0);
         if (ret < 0) {
-            if (errno != EINTR)
+            if (errno != EINTR && errno != EAGAIN)
                 return;
         } else {
             buf += ret;
@@ -1494,6 +1493,19 @@ void gdb_exit(CPUArchState *env, int code)
 
 #ifdef CONFIG_USER_ONLY
 int
+gdb_queuesig (void)
+{
+    GDBState *s;
+
+    s = gdbserver_state;
+
+    if (gdbserver_fd < 0 || s->fd < 0)
+        return 0;
+    else
+        return 1;
+}
+
+int
 gdb_handlesig(CPUState *cpu, int sig)
 {
     GDBState *s;
@@ -1530,13 +1542,9 @@ gdb_handlesig(CPUState *cpu, int sig)
             for (i = 0; i < n; i++) {
                 gdb_read_byte(s, buf[i]);
             }
-        } else {
+        } else if (n == 0 || errno != EAGAIN) {
             /* XXX: Connection closed.  Should probably wait for another
                connection before continuing.  */
-            if (n == 0) {
-                close(s->fd);
-            }
-            s->fd = -1;
             return sig;
         }
     }
@@ -1591,6 +1599,8 @@ static void gdb_accept(void)
     gdb_has_xml = false;
 
     gdbserver_state = s;
+
+    fcntl(fd, F_SETFL, O_NONBLOCK);
 }
 
 static int gdbserver_open(int port)
@@ -1618,7 +1628,7 @@ static int gdbserver_open(int port)
         close(fd);
         return -1;
     }
-    ret = listen(fd, 1);
+    ret = listen(fd, 0);
     if (ret < 0) {
         perror("listen");
         close(fd);
index 74446c6..52539c3 100644 (file)
@@ -646,12 +646,10 @@ ETEXI
 
     {
         .name       = "trace-events",
-        .args_type  = "name:s?,vcpu:i?",
-        .params     = "[name] [vcpu]",
-        .help       = "show available trace-events & their state "
-                      "(name: event name pattern; vcpu: vCPU to query, default is any)",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show available trace-events & their state",
         .mhandler.cmd = hmp_info_trace_events,
-        .command_completion = info_trace_events_completion,
     },
 
 STEXI
@@ -802,20 +800,6 @@ STEXI
 Display the latest dump status.
 ETEXI
 
-    {
-        .name       = "hotpluggable-cpus",
-        .args_type  = "",
-        .params     = "",
-        .help       = "Show information about hotpluggable CPUs",
-        .mhandler.cmd = hmp_hotpluggable_cpus,
-    },
-
-STEXI
-@item info hotpluggable-cpus
-@findex hotpluggable-cpus
-Show information about hotpluggable CPUs
-ETEXI
-
 STEXI
 @end table
 ETEXI
index 848efee..4f4f60a 100644 (file)
@@ -281,10 +281,9 @@ ETEXI
 
     {
         .name       = "trace-event",
-        .args_type  = "name:s,option:b,vcpu:i?",
-        .params     = "name on|off [vcpu]",
-        .help       = "changes status of a specific trace event "
-                      "(vcpu: vCPU to set, default is all)",
+        .args_type  = "name:s,option:b",
+        .params     = "name on|off",
+        .help       = "changes status of a specific trace event",
         .mhandler.cmd = hmp_trace_event,
         .command_completion = trace_event_completion,
     },
@@ -1009,7 +1008,7 @@ ETEXI
 
     {
         .name       = "migrate_set_parameter",
-        .args_type  = "parameter:s,value:s",
+        .args_type  = "parameter:s,value:i",
         .params     = "parameter value",
         .help       = "Set the parameter for migration",
         .mhandler.cmd = hmp_migrate_set_parameter,
diff --git a/hmp.c b/hmp.c
index cc2056e..d510236 100644 (file)
--- a/hmp.c
+++ b/hmp.c
@@ -35,7 +35,6 @@
 #include "block/qapi.h"
 #include "qemu-io.h"
 #include "qemu/cutils.h"
-#include "qemu/error-report.h"
 
 #ifdef CONFIG_SPICE
 #include <spice/enums.h>
@@ -169,15 +168,8 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
     }
 
     if (info->has_status) {
-        monitor_printf(mon, "Migration status: %s",
+        monitor_printf(mon, "Migration status: %s\n",
                        MigrationStatus_lookup[info->status]);
-        if (info->status == MIGRATION_STATUS_FAILED &&
-            info->has_error_desc) {
-            monitor_printf(mon, " (%s)\n", info->error_desc);
-        } else {
-            monitor_printf(mon, "\n");
-        }
-
         monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
                        info->total_time);
         if (info->has_expected_downtime) {
@@ -217,10 +209,6 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
             monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n",
                            info->ram->dirty_pages_rate);
         }
-        if (info->ram->postcopy_requests) {
-            monitor_printf(mon, "postcopy request count: %" PRIu64 "\n",
-                           info->ram->postcopy_requests);
-        }
     }
 
     if (info->has_disk) {
@@ -247,9 +235,9 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
                        info->xbzrle_cache->overflow);
     }
 
-    if (info->has_cpu_throttle_percentage) {
+    if (info->has_x_cpu_throttle_percentage) {
         monitor_printf(mon, "cpu throttle percentage: %" PRIu64 "\n",
-                       info->cpu_throttle_percentage);
+                       info->x_cpu_throttle_percentage);
     }
 
     qapi_free_MigrationInfo(info);
@@ -293,17 +281,11 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
             MigrationParameter_lookup[MIGRATION_PARAMETER_DECOMPRESS_THREADS],
             params->decompress_threads);
         monitor_printf(mon, " %s: %" PRId64,
-            MigrationParameter_lookup[MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL],
-            params->cpu_throttle_initial);
+            MigrationParameter_lookup[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL],
+            params->x_cpu_throttle_initial);
         monitor_printf(mon, " %s: %" PRId64,
-            MigrationParameter_lookup[MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT],
-            params->cpu_throttle_increment);
-        monitor_printf(mon, " %s: '%s'",
-            MigrationParameter_lookup[MIGRATION_PARAMETER_TLS_CREDS],
-            params->tls_creds ? : "");
-        monitor_printf(mon, " %s: '%s'",
-            MigrationParameter_lookup[MIGRATION_PARAMETER_TLS_HOSTNAME],
-            params->tls_hostname ? : "");
+            MigrationParameter_lookup[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT],
+            params->x_cpu_throttle_increment);
         monitor_printf(mon, "\n");
     }
 
@@ -1077,28 +1059,31 @@ void hmp_block_resize(Monitor *mon, const QDict *qdict)
 
 void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
 {
+    const char *device = qdict_get_str(qdict, "device");
     const char *filename = qdict_get_str(qdict, "target");
     const char *format = qdict_get_try_str(qdict, "format");
     bool reuse = qdict_get_try_bool(qdict, "reuse", false);
     bool full = qdict_get_try_bool(qdict, "full", false);
+    enum NewImageMode mode;
     Error *err = NULL;
-    DriveMirror mirror = {
-        .device = (char *)qdict_get_str(qdict, "device"),
-        .target = (char *)filename,
-        .has_format = !!format,
-        .format = (char *)format,
-        .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
-        .has_mode = true,
-        .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS,
-        .unmap = true,
-    };
 
     if (!filename) {
         error_setg(&err, QERR_MISSING_PARAMETER, "target");
         hmp_handle_error(mon, &err);
         return;
     }
-    qmp_drive_mirror(&mirror, &err);
+
+    if (reuse) {
+        mode = NEW_IMAGE_MODE_EXISTING;
+    } else {
+        mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+    }
+
+    qmp_drive_mirror(device, filename, !!format, format,
+                     false, NULL, false, NULL,
+                     full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
+                     true, mode, false, 0, false, 0, false, 0,
+                     false, 0, false, 0, false, true, &err);
     hmp_handle_error(mon, &err);
 }
 
@@ -1124,7 +1109,7 @@ void hmp_drive_backup(Monitor *mon, const QDict *qdict)
         mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
     }
 
-    qmp_drive_backup(false, NULL, device, filename, !!format, format,
+    qmp_drive_backup(device, filename, !!format, format,
                      full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
                      true, mode, false, 0, false, NULL,
                      false, 0, false, 0, &err);
@@ -1250,17 +1235,13 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
 void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
 {
     const char *param = qdict_get_str(qdict, "parameter");
-    const char *valuestr = qdict_get_str(qdict, "value");
-    long valueint = 0;
+    int value = qdict_get_int(qdict, "value");
     Error *err = NULL;
     bool has_compress_level = false;
     bool has_compress_threads = false;
     bool has_decompress_threads = false;
-    bool has_cpu_throttle_initial = false;
-    bool has_cpu_throttle_increment = false;
-    bool has_tls_creds = false;
-    bool has_tls_hostname = false;
-    bool use_int_value = false;
+    bool has_x_cpu_throttle_initial = false;
+    bool has_x_cpu_throttle_increment = false;
     int i;
 
     for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) {
@@ -1268,46 +1249,25 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
             switch (i) {
             case MIGRATION_PARAMETER_COMPRESS_LEVEL:
                 has_compress_level = true;
-                use_int_value = true;
                 break;
             case MIGRATION_PARAMETER_COMPRESS_THREADS:
                 has_compress_threads = true;
-                use_int_value = true;
                 break;
             case MIGRATION_PARAMETER_DECOMPRESS_THREADS:
                 has_decompress_threads = true;
-                use_int_value = true;
-                break;
-            case MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL:
-                has_cpu_throttle_initial = true;
-                use_int_value = true;
-                break;
-            case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT:
-                has_cpu_throttle_increment = true;
                 break;
-            case MIGRATION_PARAMETER_TLS_CREDS:
-                has_tls_creds = true;
+            case MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL:
+                has_x_cpu_throttle_initial = true;
                 break;
-            case MIGRATION_PARAMETER_TLS_HOSTNAME:
-                has_tls_hostname = true;
+            case MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT:
+                has_x_cpu_throttle_increment = true;
                 break;
             }
-
-            if (use_int_value) {
-                if (qemu_strtol(valuestr, NULL, 10, &valueint) < 0) {
-                    error_setg(&err, "Unable to parse '%s' as an int",
-                               valuestr);
-                    goto cleanup;
-                }
-            }
-
-            qmp_migrate_set_parameters(has_compress_level, valueint,
-                                       has_compress_threads, valueint,
-                                       has_decompress_threads, valueint,
-                                       has_cpu_throttle_initial, valueint,
-                                       has_cpu_throttle_increment, valueint,
-                                       has_tls_creds, valuestr,
-                                       has_tls_hostname, valuestr,
+            qmp_migrate_set_parameters(has_compress_level, value,
+                                       has_compress_threads, value,
+                                       has_decompress_threads, value,
+                                       has_x_cpu_throttle_initial, value,
+                                       has_x_cpu_throttle_increment, value,
                                        &err);
             break;
         }
@@ -1317,7 +1277,6 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
         error_setg(&err, QERR_INVALID_PARAMETER, param);
     }
 
- cleanup:
     if (err) {
         error_report_err(err);
     }
@@ -1436,17 +1395,42 @@ void hmp_change(Monitor *mon, const QDict *qdict)
 void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
 {
     Error *err = NULL;
-    BlockIOThrottle throttle = {
-        .device = (char *) qdict_get_str(qdict, "device"),
-        .bps = qdict_get_int(qdict, "bps"),
-        .bps_rd = qdict_get_int(qdict, "bps_rd"),
-        .bps_wr = qdict_get_int(qdict, "bps_wr"),
-        .iops = qdict_get_int(qdict, "iops"),
-        .iops_rd = qdict_get_int(qdict, "iops_rd"),
-        .iops_wr = qdict_get_int(qdict, "iops_wr"),
-    };
 
-    qmp_block_set_io_throttle(&throttle, &err);
+    qmp_block_set_io_throttle(qdict_get_str(qdict, "device"),
+                              qdict_get_int(qdict, "bps"),
+                              qdict_get_int(qdict, "bps_rd"),
+                              qdict_get_int(qdict, "bps_wr"),
+                              qdict_get_int(qdict, "iops"),
+                              qdict_get_int(qdict, "iops_rd"),
+                              qdict_get_int(qdict, "iops_wr"),
+                              false, /* no burst max via HMP */
+                              0,
+                              false,
+                              0,
+                              false,
+                              0,
+                              false,
+                              0,
+                              false,
+                              0,
+                              false,
+                              0,
+                              false, /* no burst length via HMP */
+                              0,
+                              false,
+                              0,
+                              false,
+                              0,
+                              false,
+                              0,
+                              false,
+                              0,
+                              false,
+                              0,
+                              false, /* No default I/O size */
+                              0,
+                              false,
+                              NULL, &err);
     hmp_handle_error(mon, &err);
 }
 
@@ -1457,7 +1441,7 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
     const char *base = qdict_get_try_str(qdict, "base");
     int64_t speed = qdict_get_try_int(qdict, "speed", 0);
 
-    qmp_block_stream(false, NULL, device, base != NULL, base, false, NULL,
+    qmp_block_stream(device, base != NULL, base, false, NULL,
                      qdict_haskey(qdict, "speed"), speed,
                      true, BLOCKDEV_ON_ERROR_REPORT, &error);
 
@@ -1549,9 +1533,6 @@ static void hmp_migrate_status_cb(void *opaque)
         if (status->is_block_migration) {
             monitor_printf(status->mon, "\n");
         }
-        if (info->has_error_desc) {
-            error_report("%s", info->error_desc);
-        }
         monitor_resume(status->mon);
         timer_del(status->timer);
         g_free(status);
@@ -1694,7 +1675,7 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)
 {
     Error *err = NULL;
     QemuOpts *opts;
-    Visitor *v;
+    OptsVisitor *ov;
     Object *obj = NULL;
 
     opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &err);
@@ -1703,9 +1684,9 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)
         return;
     }
 
-    v = opts_visitor_new(opts);
-    obj = user_creatable_add(qdict, v, &err);
-    visit_free(v);
+    ov = opts_visitor_new(opts);
+    obj = user_creatable_add(qdict, opts_get_visitor(ov), &err);
+    opts_visitor_cleanup(ov);
     qemu_opts_del(opts);
 
     if (err) {
@@ -1927,12 +1908,7 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
 
     blk = blk_by_name(device);
     if (blk) {
-        AioContext *aio_context = blk_get_aio_context(blk);
-        aio_context_acquire(aio_context);
-
         qemuio_command(blk, command);
-
-        aio_context_release(aio_context);
     } else {
         error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
                   "Device '%s' not found", device);
@@ -1955,14 +1931,15 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict)
     Error *err = NULL;
     MemdevList *memdev_list = qmp_query_memdev(&err);
     MemdevList *m = memdev_list;
-    Visitor *v;
+    StringOutputVisitor *ov;
     char *str;
     int i = 0;
 
 
     while (m) {
-        v = string_output_visitor_new(false, &str);
-        visit_type_uint16List(v, NULL, &m->value->host_nodes, NULL);
+        ov = string_output_visitor_new(false);
+        visit_type_uint16List(string_output_get_visitor(ov), NULL,
+                              &m->value->host_nodes, NULL);
         monitor_printf(mon, "memory backend: %d\n", i);
         monitor_printf(mon, "  size:  %" PRId64 "\n", m->value->size);
         monitor_printf(mon, "  merge: %s\n",
@@ -1973,11 +1950,11 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict)
                        m->value->prealloc ? "true" : "false");
         monitor_printf(mon, "  policy: %s\n",
                        HostMemPolicy_lookup[m->value->policy]);
-        visit_complete(v, &str);
+        str = string_output_get_string(ov);
         monitor_printf(mon, "  host nodes: %s\n", str);
 
         g_free(str);
-        visit_free(v);
+        string_output_visitor_cleanup(ov);
         m = m->next;
         i++;
     }
@@ -2404,45 +2381,3 @@ void hmp_info_dump(Monitor *mon, const QDict *qdict)
 
     qapi_free_DumpQueryResult(result);
 }
-
-void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
-{
-    Error *err = NULL;
-    HotpluggableCPUList *l = qmp_query_hotpluggable_cpus(&err);
-    HotpluggableCPUList *saved = l;
-    CpuInstanceProperties *c;
-
-    if (err != NULL) {
-        hmp_handle_error(mon, &err);
-        return;
-    }
-
-    monitor_printf(mon, "Hotpluggable CPUs:\n");
-    while (l) {
-        monitor_printf(mon, "  type: \"%s\"\n", l->value->type);
-        monitor_printf(mon, "  vcpus_count: \"%" PRIu64 "\"\n",
-                       l->value->vcpus_count);
-        if (l->value->has_qom_path) {
-            monitor_printf(mon, "  qom_path: \"%s\"\n", l->value->qom_path);
-        }
-
-        c = l->value->props;
-        monitor_printf(mon, "  CPUInstance Properties:\n");
-        if (c->has_node_id) {
-            monitor_printf(mon, "    node-id: \"%" PRIu64 "\"\n", c->node_id);
-        }
-        if (c->has_socket_id) {
-            monitor_printf(mon, "    socket-id: \"%" PRIu64 "\"\n", c->socket_id);
-        }
-        if (c->has_core_id) {
-            monitor_printf(mon, "    core-id: \"%" PRIu64 "\"\n", c->core_id);
-        }
-        if (c->has_thread_id) {
-            monitor_printf(mon, "    thread-id: \"%" PRIu64 "\"\n", c->thread_id);
-        }
-
-        l = l->next;
-    }
-
-    qapi_free_HotpluggableCPUList(saved);
-}
diff --git a/hmp.h b/hmp.h
index 0876ec0..093d65f 100644 (file)
--- a/hmp.h
+++ b/hmp.h
@@ -115,7 +115,6 @@ void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
 void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
-void info_trace_events_completion(ReadLineState *rs, int nb_args, const char *str);
 void trace_event_completion(ReadLineState *rs, int nb_args, const char *str);
 void watchdog_action_completion(ReadLineState *rs, int nb_args,
                                 const char *str);
@@ -133,6 +132,5 @@ void hmp_rocker_ports(Monitor *mon, const QDict *qdict);
 void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict);
 void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict);
 void hmp_info_dump(Monitor *mon, const QDict *qdict);
-void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict);
 
 #endif
index 3d77594..8940414 100644 (file)
@@ -112,7 +112,7 @@ static int handle_close(FsContext *ctx, V9fsFidOpenState *fs)
 
 static int handle_closedir(FsContext *ctx, V9fsFidOpenState *fs)
 {
-    return closedir(fs->dir.stream);
+    return closedir(fs->dir);
 }
 
 static int handle_open(FsContext *ctx, V9fsPath *fs_path,
@@ -132,8 +132,8 @@ static int handle_opendir(FsContext *ctx,
     if (ret < 0) {
         return -1;
     }
-    fs->dir.stream = fdopendir(ret);
-    if (!fs->dir.stream) {
+    fs->dir = fdopendir(ret);
+    if (!fs->dir) {
         return -1;
     }
     return 0;
@@ -141,22 +141,24 @@ static int handle_opendir(FsContext *ctx,
 
 static void handle_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
 {
-    rewinddir(fs->dir.stream);
+    rewinddir(fs->dir);
 }
 
 static off_t handle_telldir(FsContext *ctx, V9fsFidOpenState *fs)
 {
-    return telldir(fs->dir.stream);
+    return telldir(fs->dir);
 }
 
-static struct dirent *handle_readdir(FsContext *ctx, V9fsFidOpenState *fs)
+static int handle_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
+                            struct dirent *entry,
+                            struct dirent **result)
 {
-    return readdir(fs->dir.stream);
+    return readdir_r(fs->dir, entry, result);
 }
 
 static void handle_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
 {
-    seekdir(fs->dir.stream, off);
+    seekdir(fs->dir, off);
 }
 
 static ssize_t handle_preadv(FsContext *ctx, V9fsFidOpenState *fs,
@@ -260,7 +262,7 @@ static int handle_fstat(FsContext *fs_ctx, int fid_type,
     int fd;
 
     if (fid_type == P9_FID_DIR) {
-        fd = dirfd(fs->dir.stream);
+        fd = dirfd(fs->dir);
     } else {
         fd = fs->fd;
     }
@@ -407,7 +409,7 @@ static int handle_fsync(FsContext *ctx, int fid_type,
     int fd;
 
     if (fid_type == P9_FID_DIR) {
-        fd = dirfd(fs->dir.stream);
+        fd = dirfd(fs->dir);
     } else {
         fd = fs->fd;
     }
@@ -679,7 +681,7 @@ FileOperations handle_ops = {
     .opendir      = handle_opendir,
     .rewinddir    = handle_rewinddir,
     .telldir      = handle_telldir,
-    .readdir      = handle_readdir,
+    .readdir_r    = handle_readdir_r,
     .seekdir      = handle_seekdir,
     .preadv       = handle_preadv,
     .pwritev      = handle_pwritev,
index 3f271fc..16f45f4 100644 (file)
@@ -348,7 +348,7 @@ static int local_close(FsContext *ctx, V9fsFidOpenState *fs)
 
 static int local_closedir(FsContext *ctx, V9fsFidOpenState *fs)
 {
-    return closedir(fs->dir.stream);
+    return closedir(fs->dir);
 }
 
 static int local_open(FsContext *ctx, V9fsPath *fs_path,
@@ -370,9 +370,9 @@ static int local_opendir(FsContext *ctx,
     char *path = fs_path->data;
 
     buffer = rpath(ctx, path);
-    fs->dir.stream = opendir(buffer);
+    fs->dir = opendir(buffer);
     g_free(buffer);
-    if (!fs->dir.stream) {
+    if (!fs->dir) {
         return -1;
     }
     return 0;
@@ -380,40 +380,38 @@ static int local_opendir(FsContext *ctx,
 
 static void local_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
 {
-    rewinddir(fs->dir.stream);
+    rewinddir(fs->dir);
 }
 
 static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs)
 {
-    return telldir(fs->dir.stream);
+    return telldir(fs->dir);
 }
 
-static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs)
+static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
+                           struct dirent *entry,
+                           struct dirent **result)
 {
-    struct dirent *entry;
+    int ret;
 
 again:
-    entry = readdir(fs->dir.stream);
-    if (!entry) {
-        return NULL;
-    }
-
+    ret = readdir_r(fs->dir, entry, result);
     if (ctx->export_flags & V9FS_SM_MAPPED) {
         entry->d_type = DT_UNKNOWN;
     } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
-        if (!strcmp(entry->d_name, VIRTFS_META_DIR)) {
+        if (!ret && *result != NULL &&
+            !strcmp(entry->d_name, VIRTFS_META_DIR)) {
             /* skp the meta data directory */
             goto again;
         }
         entry->d_type = DT_UNKNOWN;
     }
-
-    return entry;
+    return ret;
 }
 
 static void local_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
 {
-    seekdir(fs->dir.stream, off);
+    seekdir(fs->dir, off);
 }
 
 static ssize_t local_preadv(FsContext *ctx, V9fsFidOpenState *fs,
@@ -612,7 +610,7 @@ static int local_fstat(FsContext *fs_ctx, int fid_type,
     int err, fd;
 
     if (fid_type == P9_FID_DIR) {
-        fd = dirfd(fs->dir.stream);
+        fd = dirfd(fs->dir);
     } else {
         fd = fs->fd;
     }
@@ -1000,7 +998,7 @@ static int local_fsync(FsContext *ctx, int fid_type,
     int fd;
 
     if (fid_type == P9_FID_DIR) {
-        fd = dirfd(fs->dir.stream);
+        fd = dirfd(fs->dir);
     } else {
         fd = fs->fd;
     }
@@ -1256,7 +1254,7 @@ FileOperations local_ops = {
     .opendir = local_opendir,
     .rewinddir = local_rewinddir,
     .telldir = local_telldir,
-    .readdir = local_readdir,
+    .readdir_r = local_readdir_r,
     .seekdir = local_seekdir,
     .preadv = local_preadv,
     .pwritev = local_pwritev,
index f265501..00a4eb2 100644 (file)
@@ -633,7 +633,7 @@ static int proxy_close(FsContext *ctx, V9fsFidOpenState *fs)
 
 static int proxy_closedir(FsContext *ctx, V9fsFidOpenState *fs)
 {
-    return closedir(fs->dir.stream);
+    return closedir(fs->dir);
 }
 
 static int proxy_open(FsContext *ctx, V9fsPath *fs_path,
@@ -652,14 +652,14 @@ static int proxy_opendir(FsContext *ctx,
 {
     int serrno, fd;
 
-    fs->dir.stream = NULL;
+    fs->dir = NULL;
     fd = v9fs_request(ctx->private, T_OPEN, NULL, "sd", fs_path, O_DIRECTORY);
     if (fd < 0) {
         errno = -fd;
         return -1;
     }
-    fs->dir.stream = fdopendir(fd);
-    if (!fs->dir.stream) {
+    fs->dir = fdopendir(fd);
+    if (!fs->dir) {
         serrno = errno;
         close(fd);
         errno = serrno;
@@ -670,22 +670,24 @@ static int proxy_opendir(FsContext *ctx,
 
 static void proxy_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
 {
-    rewinddir(fs->dir.stream);
+    rewinddir(fs->dir);
 }
 
 static off_t proxy_telldir(FsContext *ctx, V9fsFidOpenState *fs)
 {
-    return telldir(fs->dir.stream);
+    return telldir(fs->dir);
 }
 
-static struct dirent *proxy_readdir(FsContext *ctx, V9fsFidOpenState *fs)
+static int proxy_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
+                           struct dirent *entry,
+                           struct dirent **result)
 {
-    return readdir(fs->dir.stream);
+    return readdir_r(fs->dir, entry, result);
 }
 
 static void proxy_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
 {
-    seekdir(fs->dir.stream, off);
+    seekdir(fs->dir, off);
 }
 
 static ssize_t proxy_preadv(FsContext *ctx, V9fsFidOpenState *fs,
@@ -789,7 +791,7 @@ static int proxy_fstat(FsContext *fs_ctx, int fid_type,
     int fd;
 
     if (fid_type == P9_FID_DIR) {
-        fd = dirfd(fs->dir.stream);
+        fd = dirfd(fs->dir);
     } else {
         fd = fs->fd;
     }
@@ -934,7 +936,7 @@ static int proxy_fsync(FsContext *ctx, int fid_type,
     int fd;
 
     if (fid_type == P9_FID_DIR) {
-        fd = dirfd(fs->dir.stream);
+        fd = dirfd(fs->dir);
     } else {
         fd = fs->fd;
     }
@@ -1190,7 +1192,7 @@ FileOperations proxy_ops = {
     .opendir      = proxy_opendir,
     .rewinddir    = proxy_rewinddir,
     .telldir      = proxy_telldir,
-    .readdir      = proxy_readdir,
+    .readdir_r    = proxy_readdir_r,
     .seekdir      = proxy_seekdir,
     .preadv       = proxy_preadv,
     .pwritev      = proxy_pwritev,
index b84301d..ba9ca20 100644 (file)
@@ -9,9 +9,8 @@
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
  */
-
-#ifndef QEMU_9P_PROXY_H
-#define QEMU_9P_PROXY_H
+#ifndef _QEMU_9P_PROXY_H
+#define _QEMU_9P_PROXY_H
 
 #define PROXY_MAX_IO_SZ (64 * 1024)
 #define V9FS_FD_VALID INT_MAX
index 4b6d4e6..f1475df 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 9p synthetic file system support
+ * Virtio 9p synthetic file system support
  *
  * Copyright IBM, Corp. 2011
  *
@@ -13,7 +13,9 @@
  */
 
 #include "qemu/osdep.h"
+#include "hw/virtio/virtio.h"
 #include "9p.h"
+#include "9p-xattr.h"
 #include "fsdev/qemu-fsdev.h"
 #include "9p-synth.h"
 #include "qemu/rcu.h"
 #include "qemu/cutils.h"
 
 /* Root node for synth file system */
-static V9fsSynthNode synth_root = {
+static V9fsSynthNode v9fs_synth_root = {
     .name = "/",
     .actual_attr = {
         .mode = 0555 | S_IFDIR,
         .nlink = 1,
     },
-    .attr = &synth_root.actual_attr,
+    .attr = &v9fs_synth_root.actual_attr,
 };
 
-static QemuMutex  synth_mutex;
-static int synth_node_count;
+static QemuMutex  v9fs_synth_mutex;
+static int v9fs_synth_node_count;
 /* set to 1 when the synth fs is ready */
-static int synth_fs;
+static int v9fs_synth_fs;
 
 static V9fsSynthNode *v9fs_add_dir_node(V9fsSynthNode *parent, int mode,
                                         const char *name,
@@ -69,16 +71,16 @@ int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode,
     int ret;
     V9fsSynthNode *node, *tmp;
 
-    if (!synth_fs) {
+    if (!v9fs_synth_fs) {
         return EAGAIN;
     }
     if (!name || (strlen(name) >= NAME_MAX)) {
         return EINVAL;
     }
     if (!parent) {
-        parent = &synth_root;
+        parent = &v9fs_synth_root;
     }
-    qemu_mutex_lock(&synth_mutex);
+    qemu_mutex_lock(&v9fs_synth_mutex);
     QLIST_FOREACH(tmp, &parent->child, sibling) {
         if (!strcmp(tmp->name, name)) {
             ret = EEXIST;
@@ -86,7 +88,7 @@ int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode,
         }
     }
     /* Add the name */
-    node = v9fs_add_dir_node(parent, mode, name, NULL, synth_node_count++);
+    node = v9fs_add_dir_node(parent, mode, name, NULL, v9fs_synth_node_count++);
     v9fs_add_dir_node(node, parent->attr->mode, "..",
                       parent->attr, parent->attr->inode);
     v9fs_add_dir_node(node, node->attr->mode, ".",
@@ -94,7 +96,7 @@ int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode,
     *result = node;
     ret = 0;
 err_out:
-    qemu_mutex_unlock(&synth_mutex);
+    qemu_mutex_unlock(&v9fs_synth_mutex);
     return ret;
 }
 
@@ -105,17 +107,17 @@ int qemu_v9fs_synth_add_file(V9fsSynthNode *parent, int mode,
     int ret;
     V9fsSynthNode *node, *tmp;
 
-    if (!synth_fs) {
+    if (!v9fs_synth_fs) {
         return EAGAIN;
     }
     if (!name || (strlen(name) >= NAME_MAX)) {
         return EINVAL;
     }
     if (!parent) {
-        parent = &synth_root;
+        parent = &v9fs_synth_root;
     }
 
-    qemu_mutex_lock(&synth_mutex);
+    qemu_mutex_lock(&v9fs_synth_mutex);
     QLIST_FOREACH(tmp, &parent->child, sibling) {
         if (!strcmp(tmp->name, name)) {
             ret = EEXIST;
@@ -126,7 +128,7 @@ int qemu_v9fs_synth_add_file(V9fsSynthNode *parent, int mode,
     mode = ((mode & 0777) | S_IFREG);
     node = g_malloc0(sizeof(V9fsSynthNode));
     node->attr         = &node->actual_attr;
-    node->attr->inode  = synth_node_count++;
+    node->attr->inode  = v9fs_synth_node_count++;
     node->attr->nlink  = 1;
     node->attr->read   = read;
     node->attr->write  = write;
@@ -136,11 +138,11 @@ int qemu_v9fs_synth_add_file(V9fsSynthNode *parent, int mode,
     QLIST_INSERT_HEAD_RCU(&parent->child, node, sibling);
     ret = 0;
 err_out:
-    qemu_mutex_unlock(&synth_mutex);
+    qemu_mutex_unlock(&v9fs_synth_mutex);
     return ret;
 }
 
-static void synth_fill_statbuf(V9fsSynthNode *node, struct stat *stbuf)
+static void v9fs_synth_fill_statbuf(V9fsSynthNode *node, struct stat *stbuf)
 {
     stbuf->st_dev = 0;
     stbuf->st_ino = node->attr->inode;
@@ -157,24 +159,24 @@ static void synth_fill_statbuf(V9fsSynthNode *node, struct stat *stbuf)
     stbuf->st_ctime = 0;
 }
 
-static int synth_lstat(FsContext *fs_ctx,
+static int v9fs_synth_lstat(FsContext *fs_ctx,
                             V9fsPath *fs_path, struct stat *stbuf)
 {
     V9fsSynthNode *node = *(V9fsSynthNode **)fs_path->data;
 
-    synth_fill_statbuf(node, stbuf);
+    v9fs_synth_fill_statbuf(node, stbuf);
     return 0;
 }
 
-static int synth_fstat(FsContext *fs_ctx, int fid_type,
+static int v9fs_synth_fstat(FsContext *fs_ctx, int fid_type,
                             V9fsFidOpenState *fs, struct stat *stbuf)
 {
     V9fsSynthOpenState *synth_open = fs->private;
-    synth_fill_statbuf(synth_open->node, stbuf);
+    v9fs_synth_fill_statbuf(synth_open->node, stbuf);
     return 0;
 }
 
-static int synth_opendir(FsContext *ctx,
+static int v9fs_synth_opendir(FsContext *ctx,
                              V9fsPath *fs_path, V9fsFidOpenState *fs)
 {
     V9fsSynthOpenState *synth_open;
@@ -187,7 +189,7 @@ static int synth_opendir(FsContext *ctx,
     return 0;
 }
 
-static int synth_closedir(FsContext *ctx, V9fsFidOpenState *fs)
+static int v9fs_synth_closedir(FsContext *ctx, V9fsFidOpenState *fs)
 {
     V9fsSynthOpenState *synth_open = fs->private;
     V9fsSynthNode *node = synth_open->node;
@@ -198,24 +200,24 @@ static int synth_closedir(FsContext *ctx, V9fsFidOpenState *fs)
     return 0;
 }
 
-static off_t synth_telldir(FsContext *ctx, V9fsFidOpenState *fs)
+static off_t v9fs_synth_telldir(FsContext *ctx, V9fsFidOpenState *fs)
 {
     V9fsSynthOpenState *synth_open = fs->private;
     return synth_open->offset;
 }
 
-static void synth_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
+static void v9fs_synth_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
 {
     V9fsSynthOpenState *synth_open = fs->private;
     synth_open->offset = off;
 }
 
-static void synth_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
+static void v9fs_synth_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
 {
-    synth_seekdir(ctx, fs, 0);
+    v9fs_synth_seekdir(ctx, fs, 0);
 }
 
-static void synth_direntry(V9fsSynthNode *node,
+static void v9fs_synth_direntry(V9fsSynthNode *node,
                                 struct dirent *entry, off_t off)
 {
     strcpy(entry->d_name, node->name);
@@ -223,8 +225,8 @@ static void synth_direntry(V9fsSynthNode *node,
     entry->d_off = off + 1;
 }
 
-static struct dirent *synth_get_dentry(V9fsSynthNode *dir,
-                                            struct dirent *entry, off_t off)
+static int v9fs_synth_get_dentry(V9fsSynthNode *dir, struct dirent *entry,
+                                 struct dirent **result, off_t off)
 {
     int i = 0;
     V9fsSynthNode *node;
@@ -240,25 +242,28 @@ static struct dirent *synth_get_dentry(V9fsSynthNode *dir,
     rcu_read_unlock();
     if (!node) {
         /* end of directory */
-        return NULL;
+        *result = NULL;
+        return 0;
     }
-    synth_direntry(node, entry, off);
-    return entry;
+    v9fs_synth_direntry(node, entry, off);
+    *result = entry;
+    return 0;
 }
 
-static struct dirent *synth_readdir(FsContext *ctx, V9fsFidOpenState *fs)
+static int v9fs_synth_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
+                                struct dirent *entry, struct dirent **result)
 {
-    struct dirent *entry;
+    int ret;
     V9fsSynthOpenState *synth_open = fs->private;
     V9fsSynthNode *node = synth_open->node;
-    entry = synth_get_dentry(node, &synth_open->dent, synth_open->offset);
-    if (entry) {
+    ret = v9fs_synth_get_dentry(node, entry, result, synth_open->offset);
+    if (!ret && *result != NULL) {
         synth_open->offset++;
     }
-    return entry;
+    return ret;
 }
 
-static int synth_open(FsContext *ctx, V9fsPath *fs_path,
+static int v9fs_synth_open(FsContext *ctx, V9fsPath *fs_path,
                            int flags, V9fsFidOpenState *fs)
 {
     V9fsSynthOpenState *synth_open;
@@ -271,7 +276,7 @@ static int synth_open(FsContext *ctx, V9fsPath *fs_path,
     return 0;
 }
 
-static int synth_open2(FsContext *fs_ctx, V9fsPath *dir_path,
+static int v9fs_synth_open2(FsContext *fs_ctx, V9fsPath *dir_path,
                             const char *name, int flags,
                             FsCred *credp, V9fsFidOpenState *fs)
 {
@@ -279,7 +284,7 @@ static int synth_open2(FsContext *fs_ctx, V9fsPath *dir_path,
     return -1;
 }
 
-static int synth_close(FsContext *ctx, V9fsFidOpenState *fs)
+static int v9fs_synth_close(FsContext *ctx, V9fsFidOpenState *fs)
 {
     V9fsSynthOpenState *synth_open = fs->private;
     V9fsSynthNode *node = synth_open->node;
@@ -290,7 +295,7 @@ static int synth_close(FsContext *ctx, V9fsFidOpenState *fs)
     return 0;
 }
 
-static ssize_t synth_pwritev(FsContext *ctx, V9fsFidOpenState *fs,
+static ssize_t v9fs_synth_pwritev(FsContext *ctx, V9fsFidOpenState *fs,
                                   const struct iovec *iov,
                                   int iovcnt, off_t offset)
 {
@@ -314,7 +319,7 @@ static ssize_t synth_pwritev(FsContext *ctx, V9fsFidOpenState *fs,
     return count;
 }
 
-static ssize_t synth_preadv(FsContext *ctx, V9fsFidOpenState *fs,
+static ssize_t v9fs_synth_preadv(FsContext *ctx, V9fsFidOpenState *fs,
                                  const struct iovec *iov,
                                  int iovcnt, off_t offset)
 {
@@ -338,112 +343,112 @@ static ssize_t synth_preadv(FsContext *ctx, V9fsFidOpenState *fs,
     return count;
 }
 
-static int synth_truncate(FsContext *ctx, V9fsPath *path, off_t offset)
+static int v9fs_synth_truncate(FsContext *ctx, V9fsPath *path, off_t offset)
 {
     errno = ENOSYS;
     return -1;
 }
 
-static int synth_chmod(FsContext *fs_ctx, V9fsPath *path, FsCred *credp)
+static int v9fs_synth_chmod(FsContext *fs_ctx, V9fsPath *path, FsCred *credp)
 {
     errno = EPERM;
     return -1;
 }
 
-static int synth_mknod(FsContext *fs_ctx, V9fsPath *path,
+static int v9fs_synth_mknod(FsContext *fs_ctx, V9fsPath *path,
                        const char *buf, FsCred *credp)
 {
     errno = EPERM;
     return -1;
 }
 
-static int synth_mkdir(FsContext *fs_ctx, V9fsPath *path,
+static int v9fs_synth_mkdir(FsContext *fs_ctx, V9fsPath *path,
                        const char *buf, FsCred *credp)
 {
     errno = EPERM;
     return -1;
 }
 
-static ssize_t synth_readlink(FsContext *fs_ctx, V9fsPath *path,
+static ssize_t v9fs_synth_readlink(FsContext *fs_ctx, V9fsPath *path,
                                    char *buf, size_t bufsz)
 {
     errno = ENOSYS;
     return -1;
 }
 
-static int synth_symlink(FsContext *fs_ctx, const char *oldpath,
+static int v9fs_synth_symlink(FsContext *fs_ctx, const char *oldpath,
                               V9fsPath *newpath, const char *buf, FsCred *credp)
 {
     errno = EPERM;
     return -1;
 }
 
-static int synth_link(FsContext *fs_ctx, V9fsPath *oldpath,
+static int v9fs_synth_link(FsContext *fs_ctx, V9fsPath *oldpath,
                            V9fsPath *newpath, const char *buf)
 {
     errno = EPERM;
     return -1;
 }
 
-static int synth_rename(FsContext *ctx, const char *oldpath,
+static int v9fs_synth_rename(FsContext *ctx, const char *oldpath,
                              const char *newpath)
 {
     errno = EPERM;
     return -1;
 }
 
-static int synth_chown(FsContext *fs_ctx, V9fsPath *path, FsCred *credp)
+static int v9fs_synth_chown(FsContext *fs_ctx, V9fsPath *path, FsCred *credp)
 {
     errno = EPERM;
     return -1;
 }
 
-static int synth_utimensat(FsContext *fs_ctx, V9fsPath *path,
+static int v9fs_synth_utimensat(FsContext *fs_ctx, V9fsPath *path,
                                 const struct timespec *buf)
 {
     errno = EPERM;
     return 0;
 }
 
-static int synth_remove(FsContext *ctx, const char *path)
+static int v9fs_synth_remove(FsContext *ctx, const char *path)
 {
     errno = EPERM;
     return -1;
 }
 
-static int synth_fsync(FsContext *ctx, int fid_type,
+static int v9fs_synth_fsync(FsContext *ctx, int fid_type,
                             V9fsFidOpenState *fs, int datasync)
 {
     errno = ENOSYS;
     return 0;
 }
 
-static int synth_statfs(FsContext *s, V9fsPath *fs_path,
+static int v9fs_synth_statfs(FsContext *s, V9fsPath *fs_path,
                              struct statfs *stbuf)
 {
     stbuf->f_type = 0xABCD;
     stbuf->f_bsize = 512;
     stbuf->f_blocks = 0;
-    stbuf->f_files = synth_node_count;
+    stbuf->f_files = v9fs_synth_node_count;
     stbuf->f_namelen = NAME_MAX;
     return 0;
 }
 
-static ssize_t synth_lgetxattr(FsContext *ctx, V9fsPath *path,
+static ssize_t v9fs_synth_lgetxattr(FsContext *ctx, V9fsPath *path,
                                     const char *name, void *value, size_t size)
 {
     errno = ENOTSUP;
     return -1;
 }
 
-static ssize_t synth_llistxattr(FsContext *ctx, V9fsPath *path,
+static ssize_t v9fs_synth_llistxattr(FsContext *ctx, V9fsPath *path,
                                      void *value, size_t size)
 {
     errno = ENOTSUP;
     return -1;
 }
 
-static int synth_lsetxattr(FsContext *ctx, V9fsPath *path,
+static int v9fs_synth_lsetxattr(FsContext *ctx, V9fsPath *path,
                                 const char *name, void *value,
                                 size_t size, int flags)
 {
@@ -451,14 +456,14 @@ static int synth_lsetxattr(FsContext *ctx, V9fsPath *path,
     return -1;
 }
 
-static int synth_lremovexattr(FsContext *ctx,
+static int v9fs_synth_lremovexattr(FsContext *ctx,
                                    V9fsPath *path, const char *name)
 {
     errno = ENOTSUP;
     return -1;
 }
 
-static int synth_name_to_path(FsContext *ctx, V9fsPath *dir_path,
+static int v9fs_synth_name_to_path(FsContext *ctx, V9fsPath *dir_path,
                                    const char *name, V9fsPath *target)
 {
     V9fsSynthNode *node;
@@ -471,7 +476,7 @@ static int synth_name_to_path(FsContext *ctx, V9fsPath *dir_path,
 
     }
     if (!dir_path) {
-        dir_node = &synth_root;
+        dir_node = &v9fs_synth_root;
     } else {
         dir_node = *(V9fsSynthNode **)dir_path->data;
     }
@@ -500,7 +505,7 @@ out:
     return 0;
 }
 
-static int synth_renameat(FsContext *ctx, V9fsPath *olddir,
+static int v9fs_synth_renameat(FsContext *ctx, V9fsPath *olddir,
                                const char *old_name, V9fsPath *newdir,
                                const char *new_name)
 {
@@ -508,62 +513,62 @@ static int synth_renameat(FsContext *ctx, V9fsPath *olddir,
     return -1;
 }
 
-static int synth_unlinkat(FsContext *ctx, V9fsPath *dir,
+static int v9fs_synth_unlinkat(FsContext *ctx, V9fsPath *dir,
                                const char *name, int flags)
 {
     errno = EPERM;
     return -1;
 }
 
-static int synth_init(FsContext *ctx)
+static int v9fs_synth_init(FsContext *ctx)
 {
-    QLIST_INIT(&synth_root.child);
-    qemu_mutex_init(&synth_mutex);
+    QLIST_INIT(&v9fs_synth_root.child);
+    qemu_mutex_init(&v9fs_synth_mutex);
 
     /* Add "." and ".." entries for root */
-    v9fs_add_dir_node(&synth_root, synth_root.attr->mode,
-                      "..", synth_root.attr, synth_root.attr->inode);
-    v9fs_add_dir_node(&synth_root, synth_root.attr->mode,
-                      ".", synth_root.attr, synth_root.attr->inode);
+    v9fs_add_dir_node(&v9fs_synth_root, v9fs_synth_root.attr->mode,
+                      "..", v9fs_synth_root.attr, v9fs_synth_root.attr->inode);
+    v9fs_add_dir_node(&v9fs_synth_root, v9fs_synth_root.attr->mode,
+                      ".", v9fs_synth_root.attr, v9fs_synth_root.attr->inode);
 
     /* Mark the subsystem is ready for use */
-    synth_fs = 1;
+    v9fs_synth_fs = 1;
     return 0;
 }
 
 FileOperations synth_ops = {
-    .init         = synth_init,
-    .lstat        = synth_lstat,
-    .readlink     = synth_readlink,
-    .close        = synth_close,
-    .closedir     = synth_closedir,
-    .open         = synth_open,
-    .opendir      = synth_opendir,
-    .rewinddir    = synth_rewinddir,
-    .telldir      = synth_telldir,
-    .readdir      = synth_readdir,
-    .seekdir      = synth_seekdir,
-    .preadv       = synth_preadv,
-    .pwritev      = synth_pwritev,
-    .chmod        = synth_chmod,
-    .mknod        = synth_mknod,
-    .mkdir        = synth_mkdir,
-    .fstat        = synth_fstat,
-    .open2        = synth_open2,
-    .symlink      = synth_symlink,
-    .link         = synth_link,
-    .truncate     = synth_truncate,
-    .rename       = synth_rename,
-    .chown        = synth_chown,
-    .utimensat    = synth_utimensat,
-    .remove       = synth_remove,
-    .fsync        = synth_fsync,
-    .statfs       = synth_statfs,
-    .lgetxattr    = synth_lgetxattr,
-    .llistxattr   = synth_llistxattr,
-    .lsetxattr    = synth_lsetxattr,
-    .lremovexattr = synth_lremovexattr,
-    .name_to_path = synth_name_to_path,
-    .renameat     = synth_renameat,
-    .unlinkat     = synth_unlinkat,
+    .init         = v9fs_synth_init,
+    .lstat        = v9fs_synth_lstat,
+    .readlink     = v9fs_synth_readlink,
+    .close        = v9fs_synth_close,
+    .closedir     = v9fs_synth_closedir,
+    .open         = v9fs_synth_open,
+    .opendir      = v9fs_synth_opendir,
+    .rewinddir    = v9fs_synth_rewinddir,
+    .telldir      = v9fs_synth_telldir,
+    .readdir_r    = v9fs_synth_readdir_r,
+    .seekdir      = v9fs_synth_seekdir,
+    .preadv       = v9fs_synth_preadv,
+    .pwritev      = v9fs_synth_pwritev,
+    .chmod        = v9fs_synth_chmod,
+    .mknod        = v9fs_synth_mknod,
+    .mkdir        = v9fs_synth_mkdir,
+    .fstat        = v9fs_synth_fstat,
+    .open2        = v9fs_synth_open2,
+    .symlink      = v9fs_synth_symlink,
+    .link         = v9fs_synth_link,
+    .truncate     = v9fs_synth_truncate,
+    .rename       = v9fs_synth_rename,
+    .chown        = v9fs_synth_chown,
+    .utimensat    = v9fs_synth_utimensat,
+    .remove       = v9fs_synth_remove,
+    .fsync        = v9fs_synth_fsync,
+    .statfs       = v9fs_synth_statfs,
+    .lgetxattr    = v9fs_synth_lgetxattr,
+    .llistxattr   = v9fs_synth_llistxattr,
+    .lsetxattr    = v9fs_synth_lsetxattr,
+    .lremovexattr = v9fs_synth_lremovexattr,
+    .name_to_path = v9fs_synth_name_to_path,
+    .renameat     = v9fs_synth_renameat,
+    .unlinkat     = v9fs_synth_unlinkat,
 };
index 6bcb44a..8296251 100644 (file)
@@ -10,9 +10,9 @@
  * the COPYING file in the top-level directory.
  *
  */
+#ifndef HW_9PFS_SYNTH_H
+#define HW_9PFS_SYNTH_H 1
 
-#ifndef QEMU_9P_SYNTH_H
-#define QEMU_9P_SYNTH_H
 
 typedef struct V9fsSynthNode V9fsSynthNode;
 typedef ssize_t (*v9fs_synth_read)(void *buf, int len, off_t offset,
@@ -40,7 +40,6 @@ struct V9fsSynthNode {
 typedef struct V9fsSynthOpenState {
     off_t offset;
     V9fsSynthNode *node;
-    struct dirent dent;
 } V9fsSynthOpenState;
 
 extern int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode,
index a853ea6..4d39a20 100644 (file)
@@ -10,9 +10,8 @@
  * the COPYING file in the top-level directory.
  *
  */
-
-#ifndef QEMU_9P_XATTR_H
-#define QEMU_9P_XATTR_H
+#ifndef _QEMU_9P_XATTR_H
+#define _QEMU_9P_XATTR_H
 
 #include "qemu/xattr.h"
 
index dfe293d..f5e3012 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/virtio/virtio.h"
+#include "hw/i386/pc.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "qemu/iov.h"
@@ -231,7 +232,7 @@ static int v9fs_reopen_fid(V9fsPDU *pdu, V9fsFidState *f)
             } while (err == -EINTR && !pdu->cancelled);
         }
     } else if (f->fid_type == P9_FID_DIR) {
-        if (f->fs.dir.stream == NULL) {
+        if (f->fs.dir == NULL) {
             do {
                 err = v9fs_co_opendir(pdu, f);
             } while (err == -EINTR && !pdu->cancelled);
@@ -300,9 +301,6 @@ static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid)
     f->next = s->fid_list;
     s->fid_list = f;
 
-    v9fs_readdir_init(&f->fs.dir);
-    v9fs_readdir_init(&f->fs_reclaim.dir);
-
     return f;
 }
 
@@ -348,7 +346,7 @@ static int free_fid(V9fsPDU *pdu, V9fsFidState *fidp)
             retval = v9fs_co_close(pdu, &fidp->fs);
         }
     } else if (fidp->fid_type == P9_FID_DIR) {
-        if (fidp->fs.dir.stream != NULL) {
+        if (fidp->fs.dir != NULL) {
             retval = v9fs_co_closedir(pdu, &fidp->fs);
         }
     } else if (fidp->fid_type == P9_FID_XATTR) {
@@ -446,7 +444,7 @@ void v9fs_reclaim_fd(V9fsPDU *pdu)
                 reclaim_count++;
             }
         } else if (f->fid_type == P9_FID_DIR) {
-            if (f->fs.dir.stream != NULL) {
+            if (f->fs.dir != NULL) {
                 /*
                  * Up the reference count so that
                  * a clunk request won't free this fid
@@ -454,8 +452,8 @@ void v9fs_reclaim_fd(V9fsPDU *pdu)
                 f->ref++;
                 f->rclm_lst = reclaim_list;
                 reclaim_list = f;
-                f->fs_reclaim.dir.stream = f->fs.dir.stream;
-                f->fs.dir.stream = NULL;
+                f->fs_reclaim.dir = f->fs.dir;
+                f->fs.dir = NULL;
                 reclaim_count++;
             }
         }
@@ -1010,7 +1008,6 @@ static void v9fs_attach(void *opaque)
         goto out;
     }
     err += offset;
-    memcpy(&s->root_qid, &qid, sizeof(qid));
     trace_v9fs_attach_return(pdu->tag, pdu->id,
                              qid.type, qid.version, qid.path);
     /*
@@ -1257,19 +1254,6 @@ static int v9fs_walk_marshal(V9fsPDU *pdu, uint16_t nwnames, V9fsQID *qids)
     return offset;
 }
 
-static bool name_is_illegal(const char *name)
-{
-    return !*name || strchr(name, '/') != NULL;
-}
-
-static bool not_same_qid(const V9fsQID *qid1, const V9fsQID *qid2)
-{
-    return
-        qid1->type != qid2->type ||
-        qid1->version != qid2->version ||
-        qid1->path != qid2->path;
-}
-
 static void v9fs_walk(void *opaque)
 {
     int name_idx;
@@ -1285,7 +1269,6 @@ static void v9fs_walk(void *opaque)
     V9fsFidState *newfidp = NULL;
     V9fsPDU *pdu = opaque;
     V9fsState *s = pdu->s;
-    V9fsQID qid;
 
     err = pdu_unmarshal(pdu, offset, "ddw", &fid, &newfid, &nwnames);
     if (err < 0) {
@@ -1304,10 +1287,6 @@ static void v9fs_walk(void *opaque)
             if (err < 0) {
                 goto out_nofid;
             }
-            if (name_is_illegal(wnames[i].data)) {
-                err = -ENOENT;
-                goto out_nofid;
-            }
             offset += err;
         }
     } else if (nwnames > P9_MAXWELEM) {
@@ -1319,12 +1298,6 @@ static void v9fs_walk(void *opaque)
         err = -ENOENT;
         goto out_nofid;
     }
-
-    err = fid_to_qid(pdu, fidp, &qid);
-    if (err < 0) {
-        goto out;
-    }
-
     v9fs_path_init(&dpath);
     v9fs_path_init(&path);
     /*
@@ -1334,22 +1307,16 @@ static void v9fs_walk(void *opaque)
     v9fs_path_copy(&dpath, &fidp->path);
     v9fs_path_copy(&path, &fidp->path);
     for (name_idx = 0; name_idx < nwnames; name_idx++) {
-        if (not_same_qid(&pdu->s->root_qid, &qid) ||
-            strcmp("..", wnames[name_idx].data)) {
-            err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data,
-                                       &path);
-            if (err < 0) {
-                goto out;
-            }
-
-            err = v9fs_co_lstat(pdu, &path, &stbuf);
-            if (err < 0) {
-                goto out;
-            }
-            stat_to_qid(&stbuf, &qid);
-            v9fs_path_copy(&dpath, &path);
+        err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data, &path);
+        if (err < 0) {
+            goto out;
         }
-        memcpy(&qids[name_idx], &qid, sizeof(qid));
+        err = v9fs_co_lstat(pdu, &path, &stbuf);
+        if (err < 0) {
+            goto out;
+        }
+        stat_to_qid(&stbuf, &qids[name_idx]);
+        v9fs_path_copy(&dpath, &path);
     }
     if (fid == newfid) {
         BUG_ON(fidp->fid_type != P9_FID_NONE);
@@ -1514,16 +1481,6 @@ static void v9fs_lcreate(void *opaque)
     }
     trace_v9fs_lcreate(pdu->tag, pdu->id, dfid, flags, mode, gid);
 
-    if (name_is_illegal(name.data)) {
-        err = -ENOENT;
-        goto out_nofid;
-    }
-
-    if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
-        err = -EEXIST;
-        goto out_nofid;
-    }
-
     fidp = get_fid(pdu, dfid);
     if (fidp == NULL) {
         err = -ENOENT;
@@ -1668,7 +1625,7 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu,
     int32_t count = 0;
     struct stat stbuf;
     off_t saved_dir_pos;
-    struct dirent *dent;
+    struct dirent *dent, *result;
 
     /* save the directory position */
     saved_dir_pos = v9fs_co_telldir(pdu, fidp);
@@ -1676,37 +1633,34 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu,
         return saved_dir_pos;
     }
 
+    dent = g_malloc(sizeof(struct dirent));
+
     while (1) {
         v9fs_path_init(&path);
-
-        v9fs_readdir_lock(&fidp->fs.dir);
-
-        err = v9fs_co_readdir(pdu, fidp, &dent);
-        if (err || !dent) {
+        err = v9fs_co_readdir_r(pdu, fidp, dent, &result);
+        if (err || !result) {
             break;
         }
         err = v9fs_co_name_to_path(pdu, &fidp->path, dent->d_name, &path);
         if (err < 0) {
-            break;
+            goto out;
         }
         err = v9fs_co_lstat(pdu, &path, &stbuf);
         if (err < 0) {
-            break;
+            goto out;
         }
         err = stat_to_v9stat(pdu, &path, &stbuf, &v9stat);
         if (err < 0) {
-            break;
+            goto out;
         }
         /* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */
         len = pdu_marshal(pdu, 11 + count, "S", &v9stat);
-
-        v9fs_readdir_unlock(&fidp->fs.dir);
-
         if ((len != (v9stat.size + 2)) || ((count + len) > max_count)) {
             /* Ran out of buffer. Set dir back to old position and return */
             v9fs_co_seekdir(pdu, fidp, saved_dir_pos);
             v9fs_stat_free(&v9stat);
             v9fs_path_free(&path);
+            g_free(dent);
             return count;
         }
         count += len;
@@ -1714,9 +1668,8 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu,
         v9fs_path_free(&path);
         saved_dir_pos = dent->d_off;
     }
-
-    v9fs_readdir_unlock(&fidp->fs.dir);
-
+out:
+    g_free(dent);
     v9fs_path_free(&path);
     if (err < 0) {
         return err;
@@ -1852,7 +1805,7 @@ static int v9fs_do_readdir(V9fsPDU *pdu,
     int len, err = 0;
     int32_t count = 0;
     off_t saved_dir_pos;
-    struct dirent *dent;
+    struct dirent *dent, *result;
 
     /* save the directory position */
     saved_dir_pos = v9fs_co_telldir(pdu, fidp);
@@ -1860,21 +1813,20 @@ static int v9fs_do_readdir(V9fsPDU *pdu,
         return saved_dir_pos;
     }
 
-    while (1) {
-        v9fs_readdir_lock(&fidp->fs.dir);
+    dent = g_malloc(sizeof(struct dirent));
 
-        err = v9fs_co_readdir(pdu, fidp, &dent);
-        if (err || !dent) {
+    while (1) {
+        err = v9fs_co_readdir_r(pdu, fidp, dent, &result);
+        if (err || !result) {
             break;
         }
         v9fs_string_init(&name);
         v9fs_string_sprintf(&name, "%s", dent->d_name);
         if ((count + v9fs_readdir_data_size(&name)) > max_count) {
-            v9fs_readdir_unlock(&fidp->fs.dir);
-
             /* Ran out of buffer. Set dir back to old position and return */
             v9fs_co_seekdir(pdu, fidp, saved_dir_pos);
             v9fs_string_free(&name);
+            g_free(dent);
             return count;
         }
         /*
@@ -1892,21 +1844,17 @@ static int v9fs_do_readdir(V9fsPDU *pdu,
         len = pdu_marshal(pdu, 11 + count, "Qqbs",
                           &qid, dent->d_off,
                           dent->d_type, &name);
-
-        v9fs_readdir_unlock(&fidp->fs.dir);
-
         if (len < 0) {
             v9fs_co_seekdir(pdu, fidp, saved_dir_pos);
             v9fs_string_free(&name);
+            g_free(dent);
             return len;
         }
         count += len;
         v9fs_string_free(&name);
         saved_dir_pos = dent->d_off;
     }
-
-    v9fs_readdir_unlock(&fidp->fs.dir);
-
+    g_free(dent);
     if (err < 0) {
         return err;
     }
@@ -1936,7 +1884,7 @@ static void v9fs_readdir(void *opaque)
         retval = -EINVAL;
         goto out_nofid;
     }
-    if (!fidp->fs.dir.stream) {
+    if (!fidp->fs.dir) {
         retval = -EINVAL;
         goto out;
     }
@@ -2118,16 +2066,6 @@ static void v9fs_create(void *opaque)
     }
     trace_v9fs_create(pdu->tag, pdu->id, fid, name.data, perm, mode);
 
-    if (name_is_illegal(name.data)) {
-        err = -ENOENT;
-        goto out_nofid;
-    }
-
-    if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
-        err = -EEXIST;
-        goto out_nofid;
-    }
-
     fidp = get_fid(pdu, fid);
     if (fidp == NULL) {
         err = -EINVAL;
@@ -2293,16 +2231,6 @@ static void v9fs_symlink(void *opaque)
     }
     trace_v9fs_symlink(pdu->tag, pdu->id, dfid, name.data, symname.data, gid);
 
-    if (name_is_illegal(name.data)) {
-        err = -ENOENT;
-        goto out_nofid;
-    }
-
-    if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
-        err = -EEXIST;
-        goto out_nofid;
-    }
-
     dfidp = get_fid(pdu, dfid);
     if (dfidp == NULL) {
         err = -EINVAL;
@@ -2377,16 +2305,6 @@ static void v9fs_link(void *opaque)
     }
     trace_v9fs_link(pdu->tag, pdu->id, dfid, oldfid, name.data);
 
-    if (name_is_illegal(name.data)) {
-        err = -ENOENT;
-        goto out_nofid;
-    }
-
-    if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
-        err = -EEXIST;
-        goto out_nofid;
-    }
-
     dfidp = get_fid(pdu, dfid);
     if (dfidp == NULL) {
         err = -ENOENT;
@@ -2469,22 +2387,6 @@ static void v9fs_unlinkat(void *opaque)
     if (err < 0) {
         goto out_nofid;
     }
-
-    if (name_is_illegal(name.data)) {
-        err = -ENOENT;
-        goto out_nofid;
-    }
-
-    if (!strcmp(".", name.data)) {
-        err = -EINVAL;
-        goto out_nofid;
-    }
-
-    if (!strcmp("..", name.data)) {
-        err = -ENOTEMPTY;
-        goto out_nofid;
-    }
-
     dfidp = get_fid(pdu, dfid);
     if (dfidp == NULL) {
         err = -EINVAL;
@@ -2591,17 +2493,6 @@ static void v9fs_rename(void *opaque)
     if (err < 0) {
         goto out_nofid;
     }
-
-    if (name_is_illegal(name.data)) {
-        err = -ENOENT;
-        goto out_nofid;
-    }
-
-    if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
-        err = -EISDIR;
-        goto out_nofid;
-    }
-
     fidp = get_fid(pdu, fid);
     if (fidp == NULL) {
         err = -ENOENT;
@@ -2714,17 +2605,6 @@ static void v9fs_renameat(void *opaque)
         goto out_err;
     }
 
-    if (name_is_illegal(old_name.data) || name_is_illegal(new_name.data)) {
-        err = -ENOENT;
-        goto out_err;
-    }
-
-    if (!strcmp(".", old_name.data) || !strcmp("..", old_name.data) ||
-        !strcmp(".", new_name.data) || !strcmp("..", new_name.data)) {
-        err = -EISDIR;
-        goto out_err;
-    }
-
     v9fs_path_write_lock(s);
     err = v9fs_complete_renameat(pdu, olddirfid,
                                  &old_name, newdirfid, &new_name);
@@ -2935,16 +2815,6 @@ static void v9fs_mknod(void *opaque)
     }
     trace_v9fs_mknod(pdu->tag, pdu->id, fid, mode, major, minor);
 
-    if (name_is_illegal(name.data)) {
-        err = -ENOENT;
-        goto out_nofid;
-    }
-
-    if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
-        err = -EEXIST;
-        goto out_nofid;
-    }
-
     fidp = get_fid(pdu, fid);
     if (fidp == NULL) {
         err = -ENOENT;
@@ -3096,16 +2966,6 @@ static void v9fs_mkdir(void *opaque)
     }
     trace_v9fs_mkdir(pdu->tag, pdu->id, fid, name.data, mode, gid);
 
-    if (name_is_illegal(name.data)) {
-        err = -ENOENT;
-        goto out_nofid;
-    }
-
-    if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
-        err = -EEXIST;
-        goto out_nofid;
-    }
-
     fidp = get_fid(pdu, fid);
     if (fidp == NULL) {
         err = -ENOENT;
@@ -3407,8 +3267,8 @@ void pdu_submit(V9fsPDU *pdu)
     if (is_ro_export(&s->ctx) && !is_read_only_op(pdu)) {
         handler = v9fs_fs_ro;
     }
-    co = qemu_coroutine_create(handler, pdu);
-    qemu_coroutine_enter(co);
+    co = qemu_coroutine_create(handler);
+    qemu_coroutine_enter(co, pdu);
 }
 
 /* Returns 0 on success, 1 on failure. */
index a386033..1a19418 100644 (file)
@@ -1,9 +1,12 @@
-#ifndef QEMU_9P_H
-#define QEMU_9P_H
+#ifndef _QEMU_9P_H
+#define _QEMU_9P_H
 
 #include <dirent.h>
 #include <utime.h>
 #include <sys/resource.h>
+#include <glib.h>
+#include "standard-headers/linux/virtio_9p.h"
+#include "hw/virtio/virtio.h"
 #include "fsdev/file-op-9p.h"
 #include "fsdev/9p-iov-marshal.h"
 #include "qemu/thread.h"
@@ -166,33 +169,13 @@ typedef struct V9fsXattr
     int flags;
 } V9fsXattr;
 
-typedef struct V9fsDir {
-    DIR *stream;
-    QemuMutex readdir_mutex;
-} V9fsDir;
-
-static inline void v9fs_readdir_lock(V9fsDir *dir)
-{
-    qemu_mutex_lock(&dir->readdir_mutex);
-}
-
-static inline void v9fs_readdir_unlock(V9fsDir *dir)
-{
-    qemu_mutex_unlock(&dir->readdir_mutex);
-}
-
-static inline void v9fs_readdir_init(V9fsDir *dir)
-{
-    qemu_mutex_init(&dir->readdir_mutex);
-}
-
 /*
  * Filled by fs driver on open and other
  * calls.
  */
 union V9fsFidOpenState {
     int fd;
-    V9fsDir dir;
+    DIR *dir;
     V9fsXattr xattr;
     /*
      * private pointer for fs drivers, that
@@ -236,7 +219,6 @@ typedef struct V9fsState
     int32_t root_fid;
     Error *migration_blocker;
     V9fsConf fsconf;
-    V9fsQID root_qid;
 } V9fsState;
 
 /* 9p2000.L open flags */
index d91f9ad..91df7f7 100644 (file)
@@ -1,5 +1,6 @@
+
 /*
- * 9p backend
+ * Virtio 9p backend
  *
  * Copyright IBM, Corp. 2011
  *
@@ -17,7 +18,8 @@
 #include "qemu/coroutine.h"
 #include "coth.h"
 
-int v9fs_co_readdir(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent **dent)
+int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent,
+                      struct dirent **result)
 {
     int err;
     V9fsState *s = pdu->s;
@@ -27,14 +29,11 @@ int v9fs_co_readdir(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent **dent)
     }
     v9fs_co_run_in_worker(
         {
-            struct dirent *entry;
-
             errno = 0;
-            entry = s->ops->readdir(&s->ctx, &fidp->fs);
-            if (!entry && errno) {
+            err = s->ops->readdir_r(&s->ctx, &fidp->fs, dent, result);
+            if (!*result && errno) {
                 err = -errno;
             } else {
-                *dent = entry;
                 err = 0;
             }
         });
index 10343c0..293483e 100644 (file)
@@ -1,5 +1,6 @@
+
 /*
- * 9p backend
+ * Virtio 9p backend
  *
  * Copyright IBM, Corp. 2011
  *
index 70f584f..18c81cb 100644 (file)
@@ -1,5 +1,6 @@
+
 /*
- * 9p backend
+ * Virtio 9p backend
  *
  * Copyright IBM, Corp. 2011
  *
index 89018de..464293e 100644 (file)
 #include "qemu-common.h"
 #include "block/thread-pool.h"
 #include "qemu/coroutine.h"
+#include "qemu/main-loop.h"
 #include "coth.h"
 
 /* Called from QEMU I/O thread.  */
 static void coroutine_enter_cb(void *opaque, int ret)
 {
     Coroutine *co = opaque;
-    qemu_coroutine_enter(co);
+    qemu_coroutine_enter(co, NULL);
 }
 
 /* Called from worker thread.  */
 static int coroutine_enter_func(void *arg)
 {
     Coroutine *co = arg;
-    qemu_coroutine_enter(co);
+    qemu_coroutine_enter(co, NULL);
     return 0;
 }
 
index 3c7424e..209fc6a 100644 (file)
  *
  */
 
-#ifndef QEMU_9P_COTH_H
-#define QEMU_9P_COTH_H
+#ifndef _QEMU_9P_COTH_H
+#define _QEMU_9P_COTH_H
 
 #include "qemu/thread.h"
 #include "qemu/coroutine.h"
-#include "qemu/main-loop.h"
-#include "9p.h"
+#include "virtio-9p.h"
 
 /*
  * we want to use bottom half because we want to make sure the below
     } while (0)
 
 extern void co_run_in_worker_bh(void *);
+extern int v9fs_init_worker_threads(void);
 extern int v9fs_co_readlink(V9fsPDU *, V9fsPath *, V9fsString *);
-extern int v9fs_co_readdir(V9fsPDU *, V9fsFidState *, struct dirent **);
+extern int v9fs_co_readdir_r(V9fsPDU *, V9fsFidState *,
+                           struct dirent *, struct dirent **result);
 extern off_t v9fs_co_telldir(V9fsPDU *, V9fsFidState *);
 extern void v9fs_co_seekdir(V9fsPDU *, V9fsFidState *, off_t);
 extern void v9fs_co_rewinddir(V9fsPDU *, V9fsFidState *);
index 133c4ea..6ad96ea 100644 (file)
@@ -1,5 +1,6 @@
+
 /*
- * 9p backend
+ * Virtio 9p backend
  *
  * Copyright IBM, Corp. 2011
  *
diff --git a/hw/9pfs/trace-events b/hw/9pfs/trace-events
deleted file mode 100644 (file)
index 48d3d8a..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/9pfs/virtio-9p.c
-v9fs_rerror(uint16_t tag, uint8_t id, int err) "tag %d id %d err %d"
-v9fs_version(uint16_t tag, uint8_t id, int32_t msize, char* version) "tag %d id %d msize %d version %s"
-v9fs_version_return(uint16_t tag, uint8_t id, int32_t msize, char* version) "tag %d id %d msize %d version %s"
-v9fs_attach(uint16_t tag, uint8_t id, int32_t fid, int32_t afid, char* uname, char* aname) "tag %u id %u fid %d afid %d uname %s aname %s"
-v9fs_attach_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) "tag %d id %d type %d version %d path %"PRId64
-v9fs_stat(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
-v9fs_stat_return(uint16_t tag, uint8_t id, int32_t mode, int32_t atime, int32_t mtime, int64_t length) "tag %d id %d stat={mode %d atime %d mtime %d length %"PRId64"}"
-v9fs_getattr(uint16_t tag, uint8_t id, int32_t fid, uint64_t request_mask) "tag %d id %d fid %d request_mask %"PRIu64
-v9fs_getattr_return(uint16_t tag, uint8_t id, uint64_t result_mask, uint32_t mode, uint32_t uid, uint32_t gid) "tag %d id %d getattr={result_mask %"PRId64" mode %u uid %u gid %u}"
-v9fs_walk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, uint16_t nwnames) "tag %d id %d fid %d newfid %d nwnames %d"
-v9fs_walk_return(uint16_t tag, uint8_t id, uint16_t nwnames, void* qids) "tag %d id %d nwnames %d qids %p"
-v9fs_open(uint16_t tag, uint8_t id, int32_t fid, int32_t mode) "tag %d id %d fid %d mode %d"
-v9fs_open_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
-v9fs_lcreate(uint16_t tag, uint8_t id, int32_t dfid, int32_t flags, int32_t mode, uint32_t gid) "tag %d id %d dfid %d flags %d mode %d gid %u"
-v9fs_lcreate_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int32_t iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
-v9fs_fsync(uint16_t tag, uint8_t id, int32_t fid, int datasync) "tag %d id %d fid %d datasync %d"
-v9fs_clunk(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
-v9fs_read(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t max_count) "tag %d id %d fid %d off %"PRIu64" max_count %u"
-v9fs_read_return(uint16_t tag, uint8_t id, int32_t count, ssize_t err) "tag %d id %d count %d err %zd"
-v9fs_readdir(uint16_t tag, uint8_t id, int32_t fid, uint64_t offset, uint32_t max_count) "tag %d id %d fid %d offset %"PRIu64" max_count %u"
-v9fs_readdir_return(uint16_t tag, uint8_t id, uint32_t count, ssize_t retval) "tag %d id %d count %u retval %zd"
-v9fs_write(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t count, int cnt) "tag %d id %d fid %d off %"PRIu64" count %u cnt %d"
-v9fs_write_return(uint16_t tag, uint8_t id, int32_t total, ssize_t err) "tag %d id %d total %d err %zd"
-v9fs_create(uint16_t tag, uint8_t id, int32_t fid, char* name, int32_t perm, int8_t mode) "tag %d id %d fid %d name %s perm %d mode %d"
-v9fs_create_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
-v9fs_symlink(uint16_t tag, uint8_t id, int32_t fid,  char* name, char* symname, uint32_t gid) "tag %d id %d fid %d name %s symname %s gid %u"
-v9fs_symlink_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) "tag %d id %d qid={type %d version %d path %"PRId64"}"
-v9fs_flush(uint16_t tag, uint8_t id, int16_t flush_tag) "tag %d id %d flush_tag %d"
-v9fs_link(uint16_t tag, uint8_t id, int32_t dfid, int32_t oldfid, char* name) "tag %d id %d dfid %d oldfid %d name %s"
-v9fs_remove(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
-v9fs_wstat(uint16_t tag, uint8_t id, int32_t fid, int32_t mode, int32_t atime, int32_t mtime) "tag %u id %u fid %d stat={mode %d atime %d mtime %d}"
-v9fs_mknod(uint16_t tag, uint8_t id, int32_t fid, int mode, int major, int minor) "tag %d id %d fid %d mode %d major %d minor %d"
-v9fs_mknod_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) "tag %d id %d qid={type %d version %d path %"PRId64"}"
-v9fs_lock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length) "tag %d id %d fid %d type %d start %"PRIu64" length %"PRIu64
-v9fs_lock_return(uint16_t tag, uint8_t id, int8_t status) "tag %d id %d status %d"
-v9fs_getlock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length)"tag %d id %d fid %d type %d start %"PRIu64" length %"PRIu64
-v9fs_getlock_return(uint16_t tag, uint8_t id, uint8_t type, uint64_t start, uint64_t length, uint32_t proc_id) "tag %d id %d type %d start %"PRIu64" length %"PRIu64" proc_id %u"
-v9fs_mkdir(uint16_t tag, uint8_t id, int32_t fid, char* name, int mode, uint32_t gid) "tag %u id %u fid %d name %s mode %d gid %u"
-v9fs_mkdir_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int err) "tag %u id %u qid={type %d version %d path %"PRId64"} err %d"
-v9fs_xattrwalk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, char* name) "tag %d id %d fid %d newfid %d name %s"
-v9fs_xattrwalk_return(uint16_t tag, uint8_t id, int64_t size) "tag %d id %d size %"PRId64
-v9fs_xattrcreate(uint16_t tag, uint8_t id, int32_t fid, char* name, int64_t size, int flags) "tag %d id %d fid %d name %s size %"PRId64" flags %d"
-v9fs_readlink(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
-v9fs_readlink_return(uint16_t tag, uint8_t id, char* target) "tag %d id %d name %s"
index 009b43f..a38850e 100644 (file)
 
 #include "qemu/osdep.h"
 #include "hw/virtio/virtio.h"
+#include "hw/i386/pc.h"
 #include "qemu/sockets.h"
 #include "virtio-9p.h"
 #include "fsdev/qemu-fsdev.h"
+#include "9p-xattr.h"
 #include "coth.h"
 #include "hw/virtio/virtio-access.h"
 #include "qemu/iov.h"
@@ -97,9 +99,14 @@ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
     g_free(cfg);
 }
 
-static int virtio_9p_load(QEMUFile *f, void *opaque, size_t size)
+static void virtio_9p_save(QEMUFile *f, void *opaque)
 {
-    return virtio_load(VIRTIO_DEVICE(opaque), f, 1);
+    virtio_save(VIRTIO_DEVICE(opaque), f);
+}
+
+static int virtio_9p_load(QEMUFile *f, void *opaque, int version_id)
+{
+    return virtio_load(VIRTIO_DEVICE(opaque), f, version_id);
 }
 
 static void virtio_9p_device_realize(DeviceState *dev, Error **errp)
@@ -115,6 +122,7 @@ static void virtio_9p_device_realize(DeviceState *dev, Error **errp)
     v->config_size = sizeof(struct virtio_9p_config) + strlen(s->fsconf.tag);
     virtio_init(vdev, "virtio-9p", VIRTIO_ID_9P, v->config_size);
     v->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output);
+    register_savevm(dev, "virtio-9p", -1, 1, virtio_9p_save, virtio_9p_load, v);
 
 out:
     return;
@@ -127,6 +135,7 @@ static void virtio_9p_device_unrealize(DeviceState *dev, Error **errp)
     V9fsState *s = &v->state;
 
     virtio_cleanup(vdev);
+    unregister_savevm(dev, "virtio-9p", v);
     v9fs_device_unrealize_common(s, errp);
 }
 
@@ -168,8 +177,6 @@ void virtio_init_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov,
 
 /* virtio-9p device */
 
-VMSTATE_VIRTIO_DEVICE(9p, 1, virtio_9p_load, virtio_vmstate_save);
-
 static Property virtio_9p_properties[] = {
     DEFINE_PROP_STRING("mount_tag", V9fsVirtioState, state.fsconf.tag),
     DEFINE_PROP_STRING("fsdev", V9fsVirtioState, state.fsconf.fsdev_id),
@@ -182,7 +189,6 @@ static void virtio_9p_class_init(ObjectClass *klass, void *data)
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
 
     dc->props = virtio_9p_properties;
-    dc->vmsd = &vmstate_virtio_9p;
     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
     vdc->realize = virtio_9p_device_realize;
     vdc->unrealize = virtio_9p_device_unrealize;
index 7586b79..7f6d885 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef QEMU_VIRTIO_9P_H
-#define QEMU_VIRTIO_9P_H
+#ifndef _QEMU_VIRTIO_9P_H
+#define _QEMU_VIRTIO_9P_H
 
 #include "standard-headers/linux/virtio_9p.h"
 #include "hw/virtio/virtio.h"
index 4b7da66..faee86c 100644 (file)
@@ -1,10 +1,8 @@
 common-obj-$(CONFIG_ACPI_X86) += core.o piix4.o pcihp.o
 common-obj-$(CONFIG_ACPI_X86_ICH) += ich9.o tco.o
-common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o
+common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o cpu_hotplug_acpi_table.o
 common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o memory_hotplug_acpi_table.o
-common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o
 obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
 common-obj-$(CONFIG_ACPI) += acpi_interface.o
 common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
 common-obj-$(CONFIG_ACPI) += aml-build.o
-common-obj-$(call land,$(CONFIG_ACPI),$(CONFIG_IPMI)) += ipmi.o
index 6583917..d821313 100644 (file)
@@ -2,15 +2,6 @@
 #include "hw/acpi/acpi_dev_interface.h"
 #include "qemu/module.h"
 
-void acpi_send_event(DeviceState *dev, AcpiEventStatusBits event)
-{
-    AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(dev);
-    if (adevc->send_event) {
-        AcpiDeviceIf *adev = ACPI_DEVICE_IF(dev);
-        adevc->send_event(adev, event);
-    }
-}
-
 static void register_types(void)
 {
     static const TypeInfo acpi_dev_if_info = {
index db3e914..ab89ca6 100644 (file)
@@ -24,6 +24,7 @@
 #include "hw/acpi/aml-build.h"
 #include "qemu/bswap.h"
 #include "qemu/bitops.h"
+#include "hw/acpi/bios-linker-loader.h"
 
 static GArray *build_alloc_array(void)
 {
@@ -324,9 +325,12 @@ static void aml_free(gpointer data, gpointer user_data)
 
 Aml *init_aml_allocator(void)
 {
+    Aml *var;
+
     assert(!alloc_list);
     alloc_list = g_ptr_array_new();
-    return aml_alloc();
+    var = aml_alloc();
+    return var;
 }
 
 void free_aml_allocator(void)
@@ -402,15 +406,6 @@ Aml *aml_return(Aml *val)
     return var;
 }
 
-/* ACPI 1.0b: 16.2.6.3 Debug Objects Encoding: DebugObj */
-Aml *aml_debug(void)
-{
-    Aml *var = aml_alloc();
-    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
-    build_append_byte(var->buf, 0x31); /* DebugOp */
-    return var;
-}
-
 /*
  * ACPI 1.0b: 16.2.3 Data Objects Encoding:
  * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp
@@ -448,10 +443,12 @@ Aml *aml_name_decl(const char *name, Aml *val)
 /* ACPI 1.0b: 16.2.6.1 Arg Objects Encoding */
 Aml *aml_arg(int pos)
 {
+    Aml *var;
     uint8_t op = 0x68 /* ARG0 op */ + pos;
 
     assert(pos <= 6);
-    return aml_opcode(op);
+    var = aml_opcode(op);
+    return var;
 }
 
 /* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToInteger */
@@ -660,20 +657,6 @@ Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4)
     return var;
 }
 
-/* helper to call method with 5 arguments */
-Aml *aml_call5(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4,
-               Aml *arg5)
-{
-    Aml *var = aml_alloc();
-    build_append_namestring(var->buf, "%s", method);
-    aml_append(var, arg1);
-    aml_append(var, arg2);
-    aml_append(var, arg3);
-    aml_append(var, arg4);
-    aml_append(var, arg5);
-    return var;
-}
-
 /*
  * ACPI 5.0: 6.4.3.8.1 GPIO Connection Descriptor
  * Type 1, Large Item Name 0xC
@@ -1091,10 +1074,12 @@ Aml *aml_string(const char *name_format, ...)
 /* ACPI 1.0b: 16.2.6.2 Local Objects Encoding */
 Aml *aml_local(int num)
 {
+    Aml *var;
     uint8_t op = 0x60 /* Local0Op */ + num;
 
     assert(num <= 7);
-    return aml_opcode(op);
+    var = aml_opcode(op);
+    return var;
 }
 
 /* ACPI 2.0a: 17.2.2 Data Objects Encoding: DefVarPackage */
@@ -1422,14 +1407,6 @@ Aml *aml_unicode(const char *str)
     return var;
 }
 
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefRefOf */
-Aml *aml_refof(Aml *arg)
-{
-    Aml *var = aml_opcode(0x71 /* RefOfOp */);
-    aml_append(var, arg);
-    return var;
-}
-
 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDerefOf */
 Aml *aml_derefof(Aml *arg)
 {
@@ -1495,21 +1472,11 @@ Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target)
                                  target);
 }
 
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefObjectType */
-Aml *aml_object_type(Aml *object)
-{
-    Aml *var = aml_opcode(0x8E /* ObjectTypeOp */);
-    aml_append(var, object);
-    return var;
-}
-
 void
-build_header(BIOSLinker *linker, GArray *table_data,
+build_header(GArray *linker, GArray *table_data,
              AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
              const char *oem_id, const char *oem_table_id)
 {
-    unsigned tbl_offset = (char *)h - table_data->data;
-    unsigned checksum_offset = (char *)&h->checksum - table_data->data;
     memcpy(&h->signature, sig, 4);
     h->length = cpu_to_le32(len);
     h->revision = rev;
@@ -1530,9 +1497,10 @@ build_header(BIOSLinker *linker, GArray *table_data,
     h->oem_revision = cpu_to_le32(1);
     memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
     h->asl_compiler_revision = cpu_to_le32(1);
+    h->checksum = 0;
     /* Checksum to be filled in by Guest linker */
     bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
-        tbl_offset, len, checksum_offset);
+                                    table_data, h, len, &h->checksum);
 }
 
 void *acpi_data_push(GArray *table_data, unsigned size)
@@ -1550,7 +1518,7 @@ unsigned acpi_data_len(GArray *table)
 
 void acpi_add_table(GArray *table_offsets, GArray *table_data)
 {
-    uint32_t offset = table_data->len;
+    uint32_t offset = cpu_to_le32(table_data->len);
     g_array_append_val(table_offsets, offset);
 }
 
@@ -1564,7 +1532,8 @@ void acpi_build_tables_init(AcpiBuildTables *tables)
 
 void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
 {
-    bios_linker_loader_cleanup(tables->linker);
+    void *linker_data = bios_linker_loader_cleanup(tables->linker);
+    g_free(linker_data);
     g_array_free(tables->rsdp, true);
     g_array_free(tables->table_data, true);
     g_array_free(tables->tcpalog, mfre);
@@ -1572,38 +1541,25 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
 
 /* Build rsdt table */
 void
-build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
+build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets,
            const char *oem_id, const char *oem_table_id)
 {
-    int i;
-    unsigned rsdt_entries_offset;
     AcpiRsdtDescriptorRev1 *rsdt;
-    const unsigned table_data_len = (sizeof(uint32_t) * table_offsets->len);
-    const unsigned rsdt_entry_size = sizeof(rsdt->table_offset_entry[0]);
-    const size_t rsdt_len = sizeof(*rsdt) + table_data_len;
+    size_t rsdt_len;
+    int i;
+    const int table_data_len = (sizeof(uint32_t) * table_offsets->len);
 
+    rsdt_len = sizeof(*rsdt) + table_data_len;
     rsdt = acpi_data_push(table_data, rsdt_len);
-    rsdt_entries_offset = (char *)rsdt->table_offset_entry - table_data->data;
+    memcpy(rsdt->table_offset_entry, table_offsets->data, table_data_len);
     for (i = 0; i < table_offsets->len; ++i) {
-        uint32_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i);
-        uint32_t rsdt_entry_offset = rsdt_entries_offset + rsdt_entry_size * i;
-
         /* rsdt->table_offset_entry to be filled by Guest linker */
         bios_linker_loader_add_pointer(linker,
-            ACPI_BUILD_TABLE_FILE, rsdt_entry_offset, rsdt_entry_size,
-            ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
+                                       ACPI_BUILD_TABLE_FILE,
+                                       ACPI_BUILD_TABLE_FILE,
+                                       table_data, &rsdt->table_offset_entry[i],
+                                       sizeof(uint32_t));
     }
     build_header(linker, table_data,
                  (void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
 }
-
-void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
-                       uint64_t len, int node, MemoryAffinityFlags flags)
-{
-    numamem->type = ACPI_SRAT_MEMORY;
-    numamem->length = sizeof(*numamem);
-    numamem->proximity = cpu_to_le32(node);
-    numamem->flags = cpu_to_le32(flags);
-    numamem->base_addr = cpu_to_le64(base);
-    numamem->range_length = cpu_to_le64(len);
-}
index d963ebe..5153ab1 100644 (file)
@@ -96,170 +96,134 @@ enum {
 };
 
 /*
- * BiosLinkerFileEntry:
- *
- * An internal type used for book-keeping file entries
- */
-typedef struct BiosLinkerFileEntry {
-    char *name; /* file name */
-    GArray *blob; /* data accosiated with @name */
-} BiosLinkerFileEntry;
-
-/*
- * bios_linker_loader_init: allocate a new linker object instance.
+ * bios_linker_loader_init: allocate a new linker file blob array.
  *
  * After initialization, linker commands can be added, and will
- * be stored in the linker.cmd_blob array.
+ * be stored in the array.
  */
-BIOSLinker *bios_linker_loader_init(void)
+GArray *bios_linker_loader_init(void)
 {
-    BIOSLinker *linker = g_new(BIOSLinker, 1);
-
-    linker->cmd_blob = g_array_new(false, true /* clear */, 1);
-    linker->file_list = g_array_new(false, true /* clear */,
-                                    sizeof(BiosLinkerFileEntry));
-    return linker;
+    return g_array_new(false, true /* clear */, 1);
 }
 
-/* Free linker wrapper */
-void bios_linker_loader_cleanup(BIOSLinker *linker)
+/* Free linker wrapper and return the linker array. */
+void *bios_linker_loader_cleanup(GArray *linker)
 {
-    int i;
-    BiosLinkerFileEntry *entry;
-
-    g_array_free(linker->cmd_blob, true);
-
-    for (i = 0; i < linker->file_list->len; i++) {
-        entry = &g_array_index(linker->file_list, BiosLinkerFileEntry, i);
-        g_free(entry->name);
-    }
-    g_array_free(linker->file_list, true);
-    g_free(linker);
-}
-
-static const BiosLinkerFileEntry *
-bios_linker_find_file(const BIOSLinker *linker, const char *name)
-{
-    int i;
-    BiosLinkerFileEntry *entry;
-
-    for (i = 0; i < linker->file_list->len; i++) {
-        entry = &g_array_index(linker->file_list, BiosLinkerFileEntry, i);
-        if (!strcmp(entry->name, name)) {
-            return entry;
-        }
-    }
-    return NULL;
+    return g_array_free(linker, false);
 }
 
 /*
  * bios_linker_loader_alloc: ask guest to load file into guest memory.
  *
- * @linker: linker object instance
- * @file_name: name of the file blob to be loaded
- * @file_blob: pointer to blob corresponding to @file_name
+ * @linker: linker file blob array
+ * @file: file to be loaded
  * @alloc_align: required minimal alignment in bytes. Must be a power of 2.
  * @alloc_fseg: request allocation in FSEG zone (useful for the RSDP ACPI table)
  *
  * Note: this command must precede any other linker command using this file.
  */
-void bios_linker_loader_alloc(BIOSLinker *linker,
-                              const char *file_name,
-                              GArray *file_blob,
+void bios_linker_loader_alloc(GArray *linker,
+                              const char *file,
                               uint32_t alloc_align,
                               bool alloc_fseg)
 {
     BiosLinkerLoaderEntry entry;
-    BiosLinkerFileEntry file = { g_strdup(file_name), file_blob};
 
     assert(!(alloc_align & (alloc_align - 1)));
 
-    assert(!bios_linker_find_file(linker, file_name));
-    g_array_append_val(linker->file_list, file);
-
     memset(&entry, 0, sizeof entry);
-    strncpy(entry.alloc.file, file_name, sizeof entry.alloc.file - 1);
+    strncpy(entry.alloc.file, file, sizeof entry.alloc.file - 1);
     entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ALLOCATE);
     entry.alloc.align = cpu_to_le32(alloc_align);
     entry.alloc.zone = alloc_fseg ? BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG :
                                     BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH;
 
     /* Alloc entries must come first, so prepend them */
-    g_array_prepend_vals(linker->cmd_blob, &entry, sizeof entry);
+    g_array_prepend_vals(linker, &entry, sizeof entry);
 }
 
 /*
- * bios_linker_loader_add_checksum: ask guest to add checksum of ACPI
- * table in the specified file at the specified offset.
+ * bios_linker_loader_add_checksum: ask guest to add checksum of file data
+ * into (same) file at the specified pointer.
  *
  * Checksum calculation simply sums -X for each byte X in the range
  * using 8-bit math (i.e. ACPI checksum).
  *
- * @linker: linker object instance
+ * @linker: linker file blob array
  * @file: file that includes the checksum to be calculated
  *        and the data to be checksummed
- * @start_offset, @size: range of data in the file to checksum,
- *                       relative to the start of file blob
- * @checksum_offset: location of the checksum to be patched within file blob,
- *                   relative to the start of file blob
+ * @table: @file blob contents
+ * @start, @size: range of data to checksum
+ * @checksum: location of the checksum to be patched within file blob
+ *
+ * Notes:
+ * - checksum byte initial value must have been pushed into @table
+ *   and reside at address @checksum.
+ * - @size bytes must have been pushed into @table and reside at address
+ *   @start.
+ * - Guest calculates checksum of specified range of data, result is added to
+ *   initial value at @checksum into copy of @file in Guest memory.
+ * - Range might include the checksum itself.
+ * - To avoid confusion, caller must always put 0x0 at @checksum.
+ * - @file must be loaded into Guest memory using bios_linker_loader_alloc
  */
-void bios_linker_loader_add_checksum(BIOSLinker *linker, const char *file_name,
-                                     unsigned start_offset, unsigned size,
-                                     unsigned checksum_offset)
+void bios_linker_loader_add_checksum(GArray *linker, const char *file,
+                                     GArray *table,
+                                     void *start, unsigned size,
+                                     uint8_t *checksum)
 {
     BiosLinkerLoaderEntry entry;
-    const BiosLinkerFileEntry *file = bios_linker_find_file(linker, file_name);
+    ptrdiff_t checksum_offset = (gchar *)checksum - table->data;
+    ptrdiff_t start_offset = (gchar *)start - table->data;
 
-    assert(file);
-    assert(start_offset < file->blob->len);
-    assert(start_offset + size <= file->blob->len);
-    assert(checksum_offset >= start_offset);
-    assert(checksum_offset + 1 <= start_offset + size);
+    assert(checksum_offset >= 0);
+    assert(start_offset >= 0);
+    assert(checksum_offset + 1 <= table->len);
+    assert(start_offset + size <= table->len);
+    assert(*checksum == 0x0);
 
-    *(file->blob->data + checksum_offset) = 0;
     memset(&entry, 0, sizeof entry);
-    strncpy(entry.cksum.file, file_name, sizeof entry.cksum.file - 1);
+    strncpy(entry.cksum.file, file, sizeof entry.cksum.file - 1);
     entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM);
     entry.cksum.offset = cpu_to_le32(checksum_offset);
     entry.cksum.start = cpu_to_le32(start_offset);
     entry.cksum.length = cpu_to_le32(size);
 
-    g_array_append_vals(linker->cmd_blob, &entry, sizeof entry);
+    g_array_append_vals(linker, &entry, sizeof entry);
 }
 
 /*
- * bios_linker_loader_add_pointer: ask guest to patch address in
- * destination file with a pointer to source file
+ * bios_linker_loader_add_pointer: ask guest to add address of source file
+ * into destination file at the specified pointer.
  *
- * @linker: linker object instance
+ * @linker: linker file blob array
  * @dest_file: destination file that must be changed
- * @dst_patched_offset: location within destination file blob to be patched
- *                      with the pointer to @src_file+@src_offset (i.e. source
- *                      blob allocated in guest memory + @src_offset), in bytes
- * @dst_patched_offset_size: size of the pointer to be patched
- *                      at @dst_patched_offset in @dest_file blob, in bytes
  * @src_file: source file who's address must be taken
- * @src_offset: location within source file blob to which
- *              @dest_file+@dst_patched_offset will point to after
- *              firmware's executed ADD_POINTER command
+ * @table: @dest_file blob contents array
+ * @pointer: location of the pointer to be patched within destination file blob
+ * @pointer_size: size of pointer to be patched, in bytes
+ *
+ * Notes:
+ * - @pointer_size bytes must have been pushed into @table
+ *   and reside at address @pointer.
+ * - Guest address is added to initial value at @pointer
+ *   into copy of @dest_file in Guest memory.
+ *   e.g. to get start of src_file in guest memory, put 0x0 there
+ *   to get address of a field at offset 0x10 in src_file, put 0x10 there
+ * - Both @dest_file and @src_file must be
+ *   loaded into Guest memory using bios_linker_loader_alloc
  */
-void bios_linker_loader_add_pointer(BIOSLinker *linker,
+void bios_linker_loader_add_pointer(GArray *linker,
                                     const char *dest_file,
-                                    uint32_t dst_patched_offset,
-                                    uint8_t dst_patched_size,
                                     const char *src_file,
-                                    uint32_t src_offset)
+                                    GArray *table, void *pointer,
+                                    uint8_t pointer_size)
 {
-    uint64_t le_src_offset;
     BiosLinkerLoaderEntry entry;
-    const BiosLinkerFileEntry *dst_file =
-        bios_linker_find_file(linker, dest_file);
-    const BiosLinkerFileEntry *source_file =
-        bios_linker_find_file(linker, src_file);
+    ptrdiff_t offset = (gchar *)pointer - table->data;
 
-    assert(dst_patched_offset < dst_file->blob->len);
-    assert(dst_patched_offset + dst_patched_size <= dst_file->blob->len);
-    assert(src_offset < source_file->blob->len);
+    assert(offset >= 0);
+    assert(offset + pointer_size <= table->len);
 
     memset(&entry, 0, sizeof entry);
     strncpy(entry.pointer.dest_file, dest_file,
@@ -267,14 +231,10 @@ void bios_linker_loader_add_pointer(BIOSLinker *linker,
     strncpy(entry.pointer.src_file, src_file,
             sizeof entry.pointer.src_file - 1);
     entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_POINTER);
-    entry.pointer.offset = cpu_to_le32(dst_patched_offset);
-    entry.pointer.size = dst_patched_size;
-    assert(dst_patched_size == 1 || dst_patched_size == 2 ||
-           dst_patched_size == 4 || dst_patched_size == 8);
-
-    le_src_offset = cpu_to_le64(src_offset);
-    memcpy(dst_file->blob->data + dst_patched_offset,
-           &le_src_offset, dst_patched_size);
+    entry.pointer.offset = cpu_to_le32(offset);
+    entry.pointer.size = pointer_size;
+    assert(pointer_size == 1 || pointer_size == 2 ||
+           pointer_size == 4 || pointer_size == 8);
 
-    g_array_append_vals(linker->cmd_blob, &entry, sizeof entry);
+    g_array_append_vals(linker, &entry, sizeof entry);
 }
index e890a5d..6a2f452 100644 (file)
@@ -239,11 +239,11 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
     char unsigned *blob = NULL;
 
     {
-        Visitor *v;
+        OptsVisitor *ov;
 
-        v = opts_visitor_new(opts);
-        visit_type_AcpiTableOptions(v, NULL, &hdrs, &err);
-        visit_free(v);
+        ov = opts_visitor_new(opts);
+        visit_type_AcpiTableOptions(opts_get_visitor(ov), NULL, &hdrs, &err);
+        opts_visitor_cleanup(ov);
     }
 
     if (err) {
@@ -491,12 +491,6 @@ void acpi_pm_tmr_update(ACPIREGS *ar, bool enable)
     }
 }
 
-static inline int64_t acpi_pm_tmr_get_clock(void)
-{
-    return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY,
-                    NANOSECONDS_PER_SECOND);
-}
-
 void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar)
 {
     int64_t d = acpi_pm_tmr_get_clock();
@@ -698,7 +692,7 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr)
 }
 
 void acpi_send_gpe_event(ACPIREGS *ar, qemu_irq irq,
-                         AcpiEventStatusBits status)
+                         AcpiGPEStatusBits status)
 {
     ar->gpe.sts[0] |= status;
     acpi_update_sci(ar, irq);
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
deleted file mode 100644 (file)
index c13b65c..0000000
+++ /dev/null
@@ -1,561 +0,0 @@
-#include "qemu/osdep.h"
-#include "hw/boards.h"
-#include "hw/acpi/cpu.h"
-#include "qapi/error.h"
-#include "qapi-event.h"
-#include "trace.h"
-
-#define ACPI_CPU_HOTPLUG_REG_LEN 12
-#define ACPI_CPU_SELECTOR_OFFSET_WR 0
-#define ACPI_CPU_FLAGS_OFFSET_RW 4
-#define ACPI_CPU_CMD_OFFSET_WR 5
-#define ACPI_CPU_CMD_DATA_OFFSET_RW 8
-
-enum {
-    CPHP_GET_NEXT_CPU_WITH_EVENT_CMD = 0,
-    CPHP_OST_EVENT_CMD = 1,
-    CPHP_OST_STATUS_CMD = 2,
-    CPHP_CMD_MAX
-};
-
-static ACPIOSTInfo *acpi_cpu_device_status(int idx, AcpiCpuStatus *cdev)
-{
-    ACPIOSTInfo *info = g_new0(ACPIOSTInfo, 1);
-
-    info->slot_type = ACPI_SLOT_TYPE_CPU;
-    info->slot = g_strdup_printf("%d", idx);
-    info->source = cdev->ost_event;
-    info->status = cdev->ost_status;
-    if (cdev->cpu) {
-        DeviceState *dev = DEVICE(cdev->cpu);
-        if (dev->id) {
-            info->device = g_strdup(dev->id);
-            info->has_device = true;
-        }
-    }
-    return info;
-}
-
-void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list)
-{
-    int i;
-
-    for (i = 0; i < cpu_st->dev_count; i++) {
-        ACPIOSTInfoList *elem = g_new0(ACPIOSTInfoList, 1);
-        elem->value = acpi_cpu_device_status(i, &cpu_st->devs[i]);
-        elem->next = NULL;
-        **list = elem;
-        *list = &elem->next;
-    }
-}
-
-static uint64_t cpu_hotplug_rd(void *opaque, hwaddr addr, unsigned size)
-{
-    uint64_t val = 0;
-    CPUHotplugState *cpu_st = opaque;
-    AcpiCpuStatus *cdev;
-
-    if (cpu_st->selector >= cpu_st->dev_count) {
-        return val;
-    }
-
-    cdev = &cpu_st->devs[cpu_st->selector];
-    switch (addr) {
-    case ACPI_CPU_FLAGS_OFFSET_RW: /* pack and return is_* fields */
-        val |= cdev->cpu ? 1 : 0;
-        val |= cdev->is_inserting ? 2 : 0;
-        val |= cdev->is_removing  ? 4 : 0;
-        trace_cpuhp_acpi_read_flags(cpu_st->selector, val);
-        break;
-    case ACPI_CPU_CMD_DATA_OFFSET_RW:
-        switch (cpu_st->command) {
-        case CPHP_GET_NEXT_CPU_WITH_EVENT_CMD:
-           val = cpu_st->selector;
-           break;
-        default:
-           break;
-        }
-        trace_cpuhp_acpi_read_cmd_data(cpu_st->selector, val);
-        break;
-    default:
-        break;
-    }
-    return val;
-}
-
-static void cpu_hotplug_wr(void *opaque, hwaddr addr, uint64_t data,
-                           unsigned int size)
-{
-    CPUHotplugState *cpu_st = opaque;
-    AcpiCpuStatus *cdev;
-    ACPIOSTInfo *info;
-
-    assert(cpu_st->dev_count);
-
-    if (addr) {
-        if (cpu_st->selector >= cpu_st->dev_count) {
-            trace_cpuhp_acpi_invalid_idx_selected(cpu_st->selector);
-            return;
-        }
-    }
-
-    switch (addr) {
-    case ACPI_CPU_SELECTOR_OFFSET_WR: /* current CPU selector */
-        cpu_st->selector = data;
-        trace_cpuhp_acpi_write_idx(cpu_st->selector);
-        break;
-    case ACPI_CPU_FLAGS_OFFSET_RW: /* set is_* fields  */
-        cdev = &cpu_st->devs[cpu_st->selector];
-        if (data & 2) { /* clear insert event */
-            cdev->is_inserting = false;
-            trace_cpuhp_acpi_clear_inserting_evt(cpu_st->selector);
-        } else if (data & 4) { /* clear remove event */
-            cdev->is_removing = false;
-            trace_cpuhp_acpi_clear_remove_evt(cpu_st->selector);
-        } else if (data & 8) {
-            DeviceState *dev = NULL;
-            HotplugHandler *hotplug_ctrl = NULL;
-
-            if (!cdev->cpu) {
-                trace_cpuhp_acpi_ejecting_invalid_cpu(cpu_st->selector);
-                break;
-            }
-
-            trace_cpuhp_acpi_ejecting_cpu(cpu_st->selector);
-            dev = DEVICE(cdev->cpu);
-            hotplug_ctrl = qdev_get_hotplug_handler(dev);
-            hotplug_handler_unplug(hotplug_ctrl, dev, NULL);
-        }
-        break;
-    case ACPI_CPU_CMD_OFFSET_WR:
-        trace_cpuhp_acpi_write_cmd(cpu_st->selector, data);
-        if (data < CPHP_CMD_MAX) {
-            cpu_st->command = data;
-            if (cpu_st->command == CPHP_GET_NEXT_CPU_WITH_EVENT_CMD) {
-                uint32_t iter = cpu_st->selector;
-
-                do {
-                    cdev = &cpu_st->devs[iter];
-                    if (cdev->is_inserting || cdev->is_removing) {
-                        cpu_st->selector = iter;
-                        trace_cpuhp_acpi_cpu_has_events(cpu_st->selector,
-                            cdev->is_inserting, cdev->is_removing);
-                        break;
-                    }
-                    iter = iter + 1 < cpu_st->dev_count ? iter + 1 : 0;
-                } while (iter != cpu_st->selector);
-            }
-        }
-        break;
-    case ACPI_CPU_CMD_DATA_OFFSET_RW:
-        switch (cpu_st->command) {
-        case CPHP_OST_EVENT_CMD: {
-           cdev = &cpu_st->devs[cpu_st->selector];
-           cdev->ost_event = data;
-           trace_cpuhp_acpi_write_ost_ev(cpu_st->selector, cdev->ost_event);
-           break;
-        }
-        case CPHP_OST_STATUS_CMD: {
-           cdev = &cpu_st->devs[cpu_st->selector];
-           cdev->ost_status = data;
-           info = acpi_cpu_device_status(cpu_st->selector, cdev);
-           qapi_event_send_acpi_device_ost(info, &error_abort);
-           qapi_free_ACPIOSTInfo(info);
-           trace_cpuhp_acpi_write_ost_status(cpu_st->selector,
-                                             cdev->ost_status);
-           break;
-        }
-        default:
-           break;
-        }
-        break;
-    default:
-        break;
-    }
-}
-
-static const MemoryRegionOps cpu_hotplug_ops = {
-    .read = cpu_hotplug_rd,
-    .write = cpu_hotplug_wr,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-    .valid = {
-        .min_access_size = 1,
-        .max_access_size = 4,
-    },
-};
-
-void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
-                         CPUHotplugState *state, hwaddr base_addr)
-{
-    MachineState *machine = MACHINE(qdev_get_machine());
-    MachineClass *mc = MACHINE_GET_CLASS(machine);
-    CPUArchIdList *id_list;
-    int i;
-
-    assert(mc->possible_cpu_arch_ids);
-    id_list = mc->possible_cpu_arch_ids(machine);
-    state->dev_count = id_list->len;
-    state->devs = g_new0(typeof(*state->devs), state->dev_count);
-    for (i = 0; i < id_list->len; i++) {
-        state->devs[i].cpu =  id_list->cpus[i].cpu;
-        state->devs[i].arch_id = id_list->cpus[i].arch_id;
-    }
-    g_free(id_list);
-    memory_region_init_io(&state->ctrl_reg, owner, &cpu_hotplug_ops, state,
-                          "acpi-mem-hotplug", ACPI_CPU_HOTPLUG_REG_LEN);
-    memory_region_add_subregion(as, base_addr, &state->ctrl_reg);
-}
-
-static AcpiCpuStatus *get_cpu_status(CPUHotplugState *cpu_st, DeviceState *dev)
-{
-    CPUClass *k = CPU_GET_CLASS(dev);
-    uint64_t cpu_arch_id = k->get_arch_id(CPU(dev));
-    int i;
-
-    for (i = 0; i < cpu_st->dev_count; i++) {
-        if (cpu_arch_id == cpu_st->devs[i].arch_id) {
-            return &cpu_st->devs[i];
-        }
-    }
-    return NULL;
-}
-
-void acpi_cpu_plug_cb(HotplugHandler *hotplug_dev,
-                      CPUHotplugState *cpu_st, DeviceState *dev, Error **errp)
-{
-    AcpiCpuStatus *cdev;
-
-    cdev = get_cpu_status(cpu_st, dev);
-    if (!cdev) {
-        return;
-    }
-
-    cdev->cpu = CPU(dev);
-    if (dev->hotplugged) {
-        cdev->is_inserting = true;
-        acpi_send_event(DEVICE(hotplug_dev), ACPI_CPU_HOTPLUG_STATUS);
-    }
-}
-
-void acpi_cpu_unplug_request_cb(HotplugHandler *hotplug_dev,
-                                CPUHotplugState *cpu_st,
-                                DeviceState *dev, Error **errp)
-{
-    AcpiCpuStatus *cdev;
-
-    cdev = get_cpu_status(cpu_st, dev);
-    if (!cdev) {
-        return;
-    }
-
-    cdev->is_removing = true;
-    acpi_send_event(DEVICE(hotplug_dev), ACPI_CPU_HOTPLUG_STATUS);
-}
-
-void acpi_cpu_unplug_cb(CPUHotplugState *cpu_st,
-                        DeviceState *dev, Error **errp)
-{
-    AcpiCpuStatus *cdev;
-
-    cdev = get_cpu_status(cpu_st, dev);
-    if (!cdev) {
-        return;
-    }
-
-    cdev->cpu = NULL;
-}
-
-static const VMStateDescription vmstate_cpuhp_sts = {
-    .name = "CPU hotplug device state",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
-    .fields      = (VMStateField[]) {
-        VMSTATE_BOOL(is_inserting, AcpiCpuStatus),
-        VMSTATE_BOOL(is_removing, AcpiCpuStatus),
-        VMSTATE_UINT32(ost_event, AcpiCpuStatus),
-        VMSTATE_UINT32(ost_status, AcpiCpuStatus),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-const VMStateDescription vmstate_cpu_hotplug = {
-    .name = "CPU hotplug state",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
-    .fields      = (VMStateField[]) {
-        VMSTATE_UINT32(selector, CPUHotplugState),
-        VMSTATE_UINT8(command, CPUHotplugState),
-        VMSTATE_STRUCT_VARRAY_POINTER_UINT32(devs, CPUHotplugState, dev_count,
-                                             vmstate_cpuhp_sts, AcpiCpuStatus),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-#define CPU_NAME_FMT      "C%.03X"
-#define CPUHP_RES_DEVICE  "PRES"
-#define CPU_LOCK          "CPLK"
-#define CPU_STS_METHOD    "CSTA"
-#define CPU_SCAN_METHOD   "CSCN"
-#define CPU_NOTIFY_METHOD "CTFY"
-#define CPU_EJECT_METHOD  "CEJ0"
-#define CPU_OST_METHOD    "COST"
-
-#define CPU_ENABLED       "CPEN"
-#define CPU_SELECTOR      "CSEL"
-#define CPU_COMMAND       "CCMD"
-#define CPU_DATA          "CDAT"
-#define CPU_INSERT_EVENT  "CINS"
-#define CPU_REMOVE_EVENT  "CRMV"
-#define CPU_EJECT_EVENT   "CEJ0"
-
-void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-                    hwaddr io_base,
-                    const char *res_root,
-                    const char *event_handler_method)
-{
-    Aml *ifctx;
-    Aml *field;
-    Aml *method;
-    Aml *cpu_ctrl_dev;
-    Aml *cpus_dev;
-    Aml *zero = aml_int(0);
-    Aml *one = aml_int(1);
-    Aml *sb_scope = aml_scope("_SB");
-    MachineClass *mc = MACHINE_GET_CLASS(machine);
-    CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine);
-    char *cphp_res_path = g_strdup_printf("%s." CPUHP_RES_DEVICE, res_root);
-    Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, NULL);
-    AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj);
-    AcpiDeviceIf *adev = ACPI_DEVICE_IF(obj);
-
-    cpu_ctrl_dev = aml_device("%s", cphp_res_path);
-    {
-        Aml *crs;
-
-        aml_append(cpu_ctrl_dev,
-            aml_name_decl("_HID", aml_eisaid("PNP0A06")));
-        aml_append(cpu_ctrl_dev,
-            aml_name_decl("_UID", aml_string("CPU Hotplug resources")));
-        aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
-
-        crs = aml_resource_template();
-        aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1,
-                               ACPI_CPU_HOTPLUG_REG_LEN));
-        aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs));
-
-        /* declare CPU hotplug MMIO region with related access fields */
-        aml_append(cpu_ctrl_dev,
-            aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base),
-                                 ACPI_CPU_HOTPLUG_REG_LEN));
-
-        field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,
-                          AML_WRITE_AS_ZEROS);
-        aml_append(field, aml_reserved_field(ACPI_CPU_FLAGS_OFFSET_RW * 8));
-        /* 1 if enabled, read only */
-        aml_append(field, aml_named_field(CPU_ENABLED, 1));
-        /* (read) 1 if has a insert event. (write) 1 to clear event */
-        aml_append(field, aml_named_field(CPU_INSERT_EVENT, 1));
-        /* (read) 1 if has a remove event. (write) 1 to clear event */
-        aml_append(field, aml_named_field(CPU_REMOVE_EVENT, 1));
-        /* initiates device eject, write only */
-        aml_append(field, aml_named_field(CPU_EJECT_EVENT, 1));
-        aml_append(field, aml_reserved_field(4));
-        aml_append(field, aml_named_field(CPU_COMMAND, 8));
-        aml_append(cpu_ctrl_dev, field);
-
-        field = aml_field("PRST", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE);
-        /* CPU selector, write only */
-        aml_append(field, aml_named_field(CPU_SELECTOR, 32));
-        /* flags + cmd + 2byte align */
-        aml_append(field, aml_reserved_field(4 * 8));
-        aml_append(field, aml_named_field(CPU_DATA, 32));
-        aml_append(cpu_ctrl_dev, field);
-
-        if (opts.has_legacy_cphp) {
-            method = aml_method("_INI", 0, AML_SERIALIZED);
-            /* switch off legacy CPU hotplug HW and use new one,
-             * on reboot system is in new mode and writing 0
-             * in CPU_SELECTOR selects BSP, which is NOP at
-             * the time _INI is called */
-            aml_append(method, aml_store(zero, aml_name(CPU_SELECTOR)));
-            aml_append(cpu_ctrl_dev, method);
-        }
-    }
-    aml_append(sb_scope, cpu_ctrl_dev);
-
-    cpus_dev = aml_device("\\_SB.CPUS");
-    {
-        int i;
-        Aml *ctrl_lock = aml_name("%s.%s", cphp_res_path, CPU_LOCK);
-        Aml *cpu_selector = aml_name("%s.%s", cphp_res_path, CPU_SELECTOR);
-        Aml *is_enabled = aml_name("%s.%s", cphp_res_path, CPU_ENABLED);
-        Aml *cpu_cmd = aml_name("%s.%s", cphp_res_path, CPU_COMMAND);
-        Aml *cpu_data = aml_name("%s.%s", cphp_res_path, CPU_DATA);
-        Aml *ins_evt = aml_name("%s.%s", cphp_res_path, CPU_INSERT_EVENT);
-        Aml *rm_evt = aml_name("%s.%s", cphp_res_path, CPU_REMOVE_EVENT);
-        Aml *ej_evt = aml_name("%s.%s", cphp_res_path, CPU_EJECT_EVENT);
-
-        aml_append(cpus_dev, aml_name_decl("_HID", aml_string("ACPI0010")));
-        aml_append(cpus_dev, aml_name_decl("_CID", aml_eisaid("PNP0A05")));
-
-        method = aml_method(CPU_NOTIFY_METHOD, 2, AML_NOTSERIALIZED);
-        for (i = 0; i < arch_ids->len; i++) {
-            Aml *cpu = aml_name(CPU_NAME_FMT, i);
-            Aml *uid = aml_arg(0);
-            Aml *event = aml_arg(1);
-
-            ifctx = aml_if(aml_equal(uid, aml_int(i)));
-            {
-                aml_append(ifctx, aml_notify(cpu, event));
-            }
-            aml_append(method, ifctx);
-        }
-        aml_append(cpus_dev, method);
-
-        method = aml_method(CPU_STS_METHOD, 1, AML_SERIALIZED);
-        {
-            Aml *idx = aml_arg(0);
-            Aml *sta = aml_local(0);
-
-            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
-            aml_append(method, aml_store(idx, cpu_selector));
-            aml_append(method, aml_store(zero, sta));
-            ifctx = aml_if(aml_equal(is_enabled, one));
-            {
-                aml_append(ifctx, aml_store(aml_int(0xF), sta));
-            }
-            aml_append(method, ifctx);
-            aml_append(method, aml_release(ctrl_lock));
-            aml_append(method, aml_return(sta));
-        }
-        aml_append(cpus_dev, method);
-
-        method = aml_method(CPU_EJECT_METHOD, 1, AML_SERIALIZED);
-        {
-            Aml *idx = aml_arg(0);
-
-            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
-            aml_append(method, aml_store(idx, cpu_selector));
-            aml_append(method, aml_store(one, ej_evt));
-            aml_append(method, aml_release(ctrl_lock));
-        }
-        aml_append(cpus_dev, method);
-
-        method = aml_method(CPU_SCAN_METHOD, 0, AML_SERIALIZED);
-        {
-            Aml *else_ctx;
-            Aml *while_ctx;
-            Aml *has_event = aml_local(0);
-            Aml *dev_chk = aml_int(1);
-            Aml *eject_req = aml_int(3);
-            Aml *next_cpu_cmd = aml_int(CPHP_GET_NEXT_CPU_WITH_EVENT_CMD);
-
-            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
-            aml_append(method, aml_store(one, has_event));
-            while_ctx = aml_while(aml_equal(has_event, one));
-            {
-                 /* clear loop exit condition, ins_evt/rm_evt checks
-                  * will set it to 1 while next_cpu_cmd returns a CPU
-                  * with events */
-                 aml_append(while_ctx, aml_store(zero, has_event));
-                 aml_append(while_ctx, aml_store(next_cpu_cmd, cpu_cmd));
-                 ifctx = aml_if(aml_equal(ins_evt, one));
-                 {
-                     aml_append(ifctx,
-                         aml_call2(CPU_NOTIFY_METHOD, cpu_data, dev_chk));
-                     aml_append(ifctx, aml_store(one, ins_evt));
-                     aml_append(ifctx, aml_store(one, has_event));
-                 }
-                 aml_append(while_ctx, ifctx);
-                 else_ctx = aml_else();
-                 ifctx = aml_if(aml_equal(rm_evt, one));
-                 {
-                     aml_append(ifctx,
-                         aml_call2(CPU_NOTIFY_METHOD, cpu_data, eject_req));
-                     aml_append(ifctx, aml_store(one, rm_evt));
-                     aml_append(ifctx, aml_store(one, has_event));
-                 }
-                 aml_append(else_ctx, ifctx);
-                 aml_append(while_ctx, else_ctx);
-            }
-            aml_append(method, while_ctx);
-            aml_append(method, aml_release(ctrl_lock));
-        }
-        aml_append(cpus_dev, method);
-
-        method = aml_method(CPU_OST_METHOD, 4, AML_SERIALIZED);
-        {
-            Aml *uid = aml_arg(0);
-            Aml *ev_cmd = aml_int(CPHP_OST_EVENT_CMD);
-            Aml *st_cmd = aml_int(CPHP_OST_STATUS_CMD);
-
-            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
-            aml_append(method, aml_store(uid, cpu_selector));
-            aml_append(method, aml_store(ev_cmd, cpu_cmd));
-            aml_append(method, aml_store(aml_arg(1), cpu_data));
-            aml_append(method, aml_store(st_cmd, cpu_cmd));
-            aml_append(method, aml_store(aml_arg(2), cpu_data));
-            aml_append(method, aml_release(ctrl_lock));
-        }
-        aml_append(cpus_dev, method);
-
-        /* build Processor object for each processor */
-        for (i = 0; i < arch_ids->len; i++) {
-            Aml *dev;
-            Aml *uid = aml_int(i);
-            GArray *madt_buf = g_array_new(0, 1, 1);
-            int arch_id = arch_ids->cpus[i].arch_id;
-
-            if (opts.apci_1_compatible && arch_id < 255) {
-                dev = aml_processor(i, 0, 0, CPU_NAME_FMT, i);
-            } else {
-                dev = aml_device(CPU_NAME_FMT, i);
-                aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
-                aml_append(dev, aml_name_decl("_UID", uid));
-            }
-
-            method = aml_method("_STA", 0, AML_SERIALIZED);
-            aml_append(method, aml_return(aml_call1(CPU_STS_METHOD, uid)));
-            aml_append(dev, method);
-
-            /* build _MAT object */
-            assert(adevc && adevc->madt_cpu);
-            adevc->madt_cpu(adev, i, arch_ids, madt_buf);
-            switch (madt_buf->data[0]) {
-            case ACPI_APIC_PROCESSOR: {
-                AcpiMadtProcessorApic *apic = (void *)madt_buf->data;
-                apic->flags = cpu_to_le32(1);
-                break;
-            }
-            default:
-                assert(0);
-            }
-            aml_append(dev, aml_name_decl("_MAT",
-                aml_buffer(madt_buf->len, (uint8_t *)madt_buf->data)));
-            g_array_free(madt_buf, true);
-
-            method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
-            aml_append(method, aml_call1(CPU_EJECT_METHOD, uid));
-            aml_append(dev, method);
-
-            method = aml_method("_OST", 3, AML_SERIALIZED);
-            aml_append(method,
-                aml_call4(CPU_OST_METHOD, uid, aml_arg(0),
-                          aml_arg(1), aml_arg(2))
-            );
-            aml_append(dev, method);
-            aml_append(cpus_dev, dev);
-        }
-    }
-    aml_append(sb_scope, cpus_dev);
-    aml_append(table, sb_scope);
-
-    method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
-    aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
-    aml_append(table, method);
-
-    g_free(cphp_res_path);
-    g_free(arch_ids);
-}
index e19d902..4d86743 100644 (file)
 #include "hw/acpi/cpu_hotplug.h"
 #include "qapi/error.h"
 #include "qom/cpu.h"
-#include "hw/i386/pc.h"
-
-#define CPU_EJECT_METHOD "CPEJ"
-#define CPU_MAT_METHOD "CPMA"
-#define CPU_ON_BITMAP "CPON"
-#define CPU_STATUS_METHOD "CPST"
-#define CPU_STATUS_MAP "PRS"
-#define CPU_SCAN_METHOD "PRSC"
 
 static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size)
 {
@@ -34,15 +26,7 @@ static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size)
 static void cpu_status_write(void *opaque, hwaddr addr, uint64_t data,
                              unsigned int size)
 {
-    /* firmware never used to write in CPU present bitmap so use
-       this fact as means to switch QEMU into modern CPU hotplug
-       mode by writing 0 at the beginning of legacy CPU bitmap
-     */
-    if (addr == 0 && data == 0) {
-        AcpiCpuHotplug *cpus = opaque;
-        object_property_set_bool(cpus->device, false, "cpu-hotplug-legacy",
-                                 &error_abort);
-    }
+    /* TODO: implement VCPU removal on guest signal that CPU can be removed */
 }
 
 static const MemoryRegionOps AcpiCpuHotplug_ops = {
@@ -70,18 +54,19 @@ static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu,
     g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
 }
 
-void legacy_acpi_cpu_plug_cb(HotplugHandler *hotplug_dev,
-                             AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+                      AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
 {
     acpi_set_cpu_present_bit(g, CPU(dev), errp);
     if (*errp != NULL) {
         return;
     }
-    acpi_send_event(DEVICE(hotplug_dev), ACPI_CPU_HOTPLUG_STATUS);
+
+    acpi_send_gpe_event(ar, irq, ACPI_CPU_HOTPLUG_STATUS);
 }
 
-void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
-                                  AcpiCpuHotplug *gpe_cpu, uint16_t base)
+void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+                           AcpiCpuHotplug *gpe_cpu, uint16_t base)
 {
     CPUState *cpu;
 
@@ -91,242 +76,4 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
     memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
                           gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
     memory_region_add_subregion(parent, base, &gpe_cpu->io);
-    gpe_cpu->device = owner;
-}
-
-void acpi_switch_to_modern_cphp(AcpiCpuHotplug *gpe_cpu,
-                                CPUHotplugState *cpuhp_state,
-                                uint16_t io_port)
-{
-    MemoryRegion *parent = pci_address_space_io(PCI_DEVICE(gpe_cpu->device));
-
-    memory_region_del_subregion(parent, &gpe_cpu->io);
-    cpu_hotplug_hw_init(parent, gpe_cpu->device, cpuhp_state, io_port);
-}
-
-void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState *machine,
-                                  uint16_t io_base)
-{
-    Aml *dev;
-    Aml *crs;
-    Aml *pkg;
-    Aml *field;
-    Aml *method;
-    Aml *if_ctx;
-    Aml *else_ctx;
-    int i, apic_idx;
-    Aml *sb_scope = aml_scope("_SB");
-    uint8_t madt_tmpl[8] = {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0};
-    Aml *cpu_id = aml_arg(1);
-    Aml *apic_id = aml_arg(0);
-    Aml *cpu_on = aml_local(0);
-    Aml *madt = aml_local(1);
-    Aml *cpus_map = aml_name(CPU_ON_BITMAP);
-    Aml *zero = aml_int(0);
-    Aml *one = aml_int(1);
-    MachineClass *mc = MACHINE_GET_CLASS(machine);
-    CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine);
-    PCMachineState *pcms = PC_MACHINE(machine);
-
-    /*
-     * _MAT method - creates an madt apic buffer
-     * apic_id = Arg0 = Local APIC ID
-     * cpu_id  = Arg1 = Processor ID
-     * cpu_on = Local0 = CPON flag for this cpu
-     * madt = Local1 = Buffer (in madt apic form) to return
-     */
-    method = aml_method(CPU_MAT_METHOD, 2, AML_NOTSERIALIZED);
-    aml_append(method,
-        aml_store(aml_derefof(aml_index(cpus_map, apic_id)), cpu_on));
-    aml_append(method,
-        aml_store(aml_buffer(sizeof(madt_tmpl), madt_tmpl), madt));
-    /* Update the processor id, lapic id, and enable/disable status */
-    aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(2))));
-    aml_append(method, aml_store(apic_id, aml_index(madt, aml_int(3))));
-    aml_append(method, aml_store(cpu_on, aml_index(madt, aml_int(4))));
-    aml_append(method, aml_return(madt));
-    aml_append(sb_scope, method);
-
-    /*
-     * _STA method - return ON status of cpu
-     * apic_id = Arg0 = Local APIC ID
-     * cpu_on = Local0 = CPON flag for this cpu
-     */
-    method = aml_method(CPU_STATUS_METHOD, 1, AML_NOTSERIALIZED);
-    aml_append(method,
-        aml_store(aml_derefof(aml_index(cpus_map, apic_id)), cpu_on));
-    if_ctx = aml_if(cpu_on);
-    {
-        aml_append(if_ctx, aml_return(aml_int(0xF)));
-    }
-    aml_append(method, if_ctx);
-    else_ctx = aml_else();
-    {
-        aml_append(else_ctx, aml_return(zero));
-    }
-    aml_append(method, else_ctx);
-    aml_append(sb_scope, method);
-
-    method = aml_method(CPU_EJECT_METHOD, 2, AML_NOTSERIALIZED);
-    aml_append(method, aml_sleep(200));
-    aml_append(sb_scope, method);
-
-    method = aml_method(CPU_SCAN_METHOD, 0, AML_NOTSERIALIZED);
-    {
-        Aml *while_ctx, *if_ctx2, *else_ctx2;
-        Aml *bus_check_evt = aml_int(1);
-        Aml *remove_evt = aml_int(3);
-        Aml *status_map = aml_local(5); /* Local5 = active cpu bitmap */
-        Aml *byte = aml_local(2); /* Local2 = last read byte from bitmap */
-        Aml *idx = aml_local(0); /* Processor ID / APIC ID iterator */
-        Aml *is_cpu_on = aml_local(1); /* Local1 = CPON flag for cpu */
-        Aml *status = aml_local(3); /* Local3 = active state for cpu */
-
-        aml_append(method, aml_store(aml_name(CPU_STATUS_MAP), status_map));
-        aml_append(method, aml_store(zero, byte));
-        aml_append(method, aml_store(zero, idx));
-
-        /* While (idx < SizeOf(CPON)) */
-        while_ctx = aml_while(aml_lless(idx, aml_sizeof(cpus_map)));
-        aml_append(while_ctx,
-            aml_store(aml_derefof(aml_index(cpus_map, idx)), is_cpu_on));
-
-        if_ctx = aml_if(aml_and(idx, aml_int(0x07), NULL));
-        {
-            /* Shift down previously read bitmap byte */
-            aml_append(if_ctx, aml_shiftright(byte, one, byte));
-        }
-        aml_append(while_ctx, if_ctx);
-
-        else_ctx = aml_else();
-        {
-            /* Read next byte from cpu bitmap */
-            aml_append(else_ctx, aml_store(aml_derefof(aml_index(status_map,
-                       aml_shiftright(idx, aml_int(3), NULL))), byte));
-        }
-        aml_append(while_ctx, else_ctx);
-
-        aml_append(while_ctx, aml_store(aml_and(byte, one, NULL), status));
-        if_ctx = aml_if(aml_lnot(aml_equal(is_cpu_on, status)));
-        {
-            /* State change - update CPON with new state */
-            aml_append(if_ctx, aml_store(status, aml_index(cpus_map, idx)));
-            if_ctx2 = aml_if(aml_equal(status, one));
-            {
-                aml_append(if_ctx2,
-                    aml_call2(AML_NOTIFY_METHOD, idx, bus_check_evt));
-            }
-            aml_append(if_ctx, if_ctx2);
-            else_ctx2 = aml_else();
-            {
-                aml_append(else_ctx2,
-                    aml_call2(AML_NOTIFY_METHOD, idx, remove_evt));
-            }
-        }
-        aml_append(if_ctx, else_ctx2);
-        aml_append(while_ctx, if_ctx);
-
-        aml_append(while_ctx, aml_increment(idx)); /* go to next cpu */
-        aml_append(method, while_ctx);
-    }
-    aml_append(sb_scope, method);
-
-    /* The current AML generator can cover the APIC ID range [0..255],
-     * inclusive, for VCPU hotplug. */
-    QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256);
-    g_assert(pcms->apic_id_limit <= ACPI_CPU_HOTPLUG_ID_LIMIT);
-
-    /* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */
-    dev = aml_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE));
-    aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A06")));
-    aml_append(dev,
-        aml_name_decl("_UID", aml_string("CPU Hotplug resources"))
-    );
-    /* device present, functioning, decoding, not shown in UI */
-    aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
-    crs = aml_resource_template();
-    aml_append(crs,
-        aml_io(AML_DECODE16, io_base, io_base, 1, ACPI_GPE_PROC_LEN)
-    );
-    aml_append(dev, aml_name_decl("_CRS", crs));
-    aml_append(sb_scope, dev);
-    /* declare CPU hotplug MMIO region and PRS field to access it */
-    aml_append(sb_scope, aml_operation_region(
-        "PRST", AML_SYSTEM_IO, aml_int(io_base), ACPI_GPE_PROC_LEN));
-    field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
-    aml_append(field, aml_named_field("PRS", 256));
-    aml_append(sb_scope, field);
-
-    /* build Processor object for each processor */
-    for (i = 0; i < apic_ids->len; i++) {
-        int apic_id = apic_ids->cpus[i].arch_id;
-
-        assert(apic_id < ACPI_CPU_HOTPLUG_ID_LIMIT);
-
-        dev = aml_processor(i, 0, 0, "CP%.02X", apic_id);
-
-        method = aml_method("_MAT", 0, AML_NOTSERIALIZED);
-        aml_append(method,
-            aml_return(aml_call2(CPU_MAT_METHOD, aml_int(apic_id), aml_int(i))
-        ));
-        aml_append(dev, method);
-
-        method = aml_method("_STA", 0, AML_NOTSERIALIZED);
-        aml_append(method,
-            aml_return(aml_call1(CPU_STATUS_METHOD, aml_int(apic_id))));
-        aml_append(dev, method);
-
-        method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
-        aml_append(method,
-            aml_return(aml_call2(CPU_EJECT_METHOD, aml_int(apic_id),
-                aml_arg(0)))
-        );
-        aml_append(dev, method);
-
-        aml_append(sb_scope, dev);
-    }
-
-    /* build this code:
-     *   Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}
-     */
-    /* Arg0 = APIC ID */
-    method = aml_method(AML_NOTIFY_METHOD, 2, AML_NOTSERIALIZED);
-    for (i = 0; i < apic_ids->len; i++) {
-        int apic_id = apic_ids->cpus[i].arch_id;
-
-        if_ctx = aml_if(aml_equal(aml_arg(0), aml_int(apic_id)));
-        aml_append(if_ctx,
-            aml_notify(aml_name("CP%.02X", apic_id), aml_arg(1))
-        );
-        aml_append(method, if_ctx);
-    }
-    aml_append(sb_scope, method);
-
-    /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
-     *
-     * Note: The ability to create variable-sized packages was first
-     * introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages
-     * ith up to 255 elements. Windows guests up to win2k8 fail when
-     * VarPackageOp is used.
-     */
-    pkg = pcms->apic_id_limit <= 255 ? aml_package(pcms->apic_id_limit) :
-                                       aml_varpackage(pcms->apic_id_limit);
-
-    for (i = 0, apic_idx = 0; i < apic_ids->len; i++) {
-        int apic_id = apic_ids->cpus[i].arch_id;
-
-        for (; apic_idx < apic_id; apic_idx++) {
-            aml_append(pkg, aml_int(0));
-        }
-        aml_append(pkg, aml_int(apic_ids->cpus[i].cpu ? 1 : 0));
-        apic_idx = apic_id + 1;
-    }
-    aml_append(sb_scope, aml_name_decl(CPU_ON_BITMAP, pkg));
-    g_free(apic_ids);
-
-    aml_append(ctx, sb_scope);
-
-    method = aml_method("\\_GPE._E02", 0, AML_NOTSERIALIZED);
-    aml_append(method, aml_call0("\\_SB." CPU_SCAN_METHOD));
-    aml_append(ctx, method);
 }
diff --git a/hw/acpi/cpu_hotplug_acpi_table.c b/hw/acpi/cpu_hotplug_acpi_table.c
new file mode 100644 (file)
index 0000000..97bb109
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/acpi/cpu_hotplug.h"
+
+void build_cpu_hotplug_aml(Aml *ctx)
+{
+    Aml *method;
+    Aml *if_ctx;
+    Aml *else_ctx;
+    Aml *sb_scope = aml_scope("_SB");
+    uint8_t madt_tmpl[8] = {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0};
+    Aml *cpu_id = aml_arg(0);
+    Aml *cpu_on = aml_local(0);
+    Aml *madt = aml_local(1);
+    Aml *cpus_map = aml_name(CPU_ON_BITMAP);
+    Aml *zero = aml_int(0);
+    Aml *one = aml_int(1);
+
+    /*
+     * _MAT method - creates an madt apic buffer
+     * cpu_id = Arg0 = Processor ID = Local APIC ID
+     * cpu_on = Local0 = CPON flag for this cpu
+     * madt = Local1 = Buffer (in madt apic form) to return
+     */
+    method = aml_method(CPU_MAT_METHOD, 1, AML_NOTSERIALIZED);
+    aml_append(method,
+        aml_store(aml_derefof(aml_index(cpus_map, cpu_id)), cpu_on));
+    aml_append(method,
+        aml_store(aml_buffer(sizeof(madt_tmpl), madt_tmpl), madt));
+    /* Update the processor id, lapic id, and enable/disable status */
+    aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(2))));
+    aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(3))));
+    aml_append(method, aml_store(cpu_on, aml_index(madt, aml_int(4))));
+    aml_append(method, aml_return(madt));
+    aml_append(sb_scope, method);
+
+    /*
+     * _STA method - return ON status of cpu
+     * cpu_id = Arg0 = Processor ID = Local APIC ID
+     * cpu_on = Local0 = CPON flag for this cpu
+     */
+    method = aml_method(CPU_STATUS_METHOD, 1, AML_NOTSERIALIZED);
+    aml_append(method,
+        aml_store(aml_derefof(aml_index(cpus_map, cpu_id)), cpu_on));
+    if_ctx = aml_if(cpu_on);
+    {
+        aml_append(if_ctx, aml_return(aml_int(0xF)));
+    }
+    aml_append(method, if_ctx);
+    else_ctx = aml_else();
+    {
+        aml_append(else_ctx, aml_return(zero));
+    }
+    aml_append(method, else_ctx);
+    aml_append(sb_scope, method);
+
+    method = aml_method(CPU_EJECT_METHOD, 2, AML_NOTSERIALIZED);
+    aml_append(method, aml_sleep(200));
+    aml_append(sb_scope, method);
+
+    method = aml_method(CPU_SCAN_METHOD, 0, AML_NOTSERIALIZED);
+    {
+        Aml *while_ctx, *if_ctx2, *else_ctx2;
+        Aml *bus_check_evt = aml_int(1);
+        Aml *remove_evt = aml_int(3);
+        Aml *status_map = aml_local(5); /* Local5 = active cpu bitmap */
+        Aml *byte = aml_local(2); /* Local2 = last read byte from bitmap */
+        Aml *idx = aml_local(0); /* Processor ID / APIC ID iterator */
+        Aml *is_cpu_on = aml_local(1); /* Local1 = CPON flag for cpu */
+        Aml *status = aml_local(3); /* Local3 = active state for cpu */
+
+        aml_append(method, aml_store(aml_name(CPU_STATUS_MAP), status_map));
+        aml_append(method, aml_store(zero, byte));
+        aml_append(method, aml_store(zero, idx));
+
+        /* While (idx < SizeOf(CPON)) */
+        while_ctx = aml_while(aml_lless(idx, aml_sizeof(cpus_map)));
+        aml_append(while_ctx,
+            aml_store(aml_derefof(aml_index(cpus_map, idx)), is_cpu_on));
+
+        if_ctx = aml_if(aml_and(idx, aml_int(0x07), NULL));
+        {
+            /* Shift down previously read bitmap byte */
+            aml_append(if_ctx, aml_shiftright(byte, one, byte));
+        }
+        aml_append(while_ctx, if_ctx);
+
+        else_ctx = aml_else();
+        {
+            /* Read next byte from cpu bitmap */
+            aml_append(else_ctx, aml_store(aml_derefof(aml_index(status_map,
+                       aml_shiftright(idx, aml_int(3), NULL))), byte));
+        }
+        aml_append(while_ctx, else_ctx);
+
+        aml_append(while_ctx, aml_store(aml_and(byte, one, NULL), status));
+        if_ctx = aml_if(aml_lnot(aml_equal(is_cpu_on, status)));
+        {
+            /* State change - update CPON with new state */
+            aml_append(if_ctx, aml_store(status, aml_index(cpus_map, idx)));
+            if_ctx2 = aml_if(aml_equal(status, one));
+            {
+                aml_append(if_ctx2,
+                    aml_call2(AML_NOTIFY_METHOD, idx, bus_check_evt));
+            }
+            aml_append(if_ctx, if_ctx2);
+            else_ctx2 = aml_else();
+            {
+                aml_append(else_ctx2,
+                    aml_call2(AML_NOTIFY_METHOD, idx, remove_evt));
+            }
+        }
+        aml_append(if_ctx, else_ctx2);
+        aml_append(while_ctx, if_ctx);
+
+        aml_append(while_ctx, aml_increment(idx)); /* go to next cpu */
+        aml_append(method, while_ctx);
+    }
+    aml_append(sb_scope, method);
+
+    aml_append(ctx, sb_scope);
+}
index e5a3c18..27e978f 100644 (file)
@@ -189,33 +189,6 @@ static const VMStateDescription vmstate_tco_io_state = {
     }
 };
 
-static bool vmstate_test_use_cpuhp(void *opaque)
-{
-    ICH9LPCPMRegs *s = opaque;
-    return !s->cpu_hotplug_legacy;
-}
-
-static int vmstate_cpuhp_pre_load(void *opaque)
-{
-    ICH9LPCPMRegs *s = opaque;
-    Object *obj = OBJECT(s->gpe_cpu.device);
-    object_property_set_bool(obj, false, "cpu-hotplug-legacy", &error_abort);
-    return 0;
-}
-
-static const VMStateDescription vmstate_cpuhp_state = {
-    .name = "ich9_pm/cpuhp",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
-    .needed = vmstate_test_use_cpuhp,
-    .pre_load = vmstate_cpuhp_pre_load,
-    .fields      = (VMStateField[]) {
-        VMSTATE_CPU_HOTPLUG(cpuhp_state, ICH9LPCPMRegs),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
 const VMStateDescription vmstate_ich9_pm = {
     .name = "ich9_pm",
     .version_id = 1,
@@ -236,7 +209,6 @@ const VMStateDescription vmstate_ich9_pm = {
     .subsections = (const VMStateDescription*[]) {
         &vmstate_memhp_state,
         &vmstate_tco_io_state,
-        &vmstate_cpuhp_state,
         NULL
     }
 };
@@ -301,8 +273,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
     pm->powerdown_notifier.notify = pm_powerdown_req;
     qemu_register_powerdown_notifier(&pm->powerdown_notifier);
 
-    legacy_acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci),
-        OBJECT(lpc_pci), &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
+    acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
+                          &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
 
     if (pm->acpi_memory_hotplug.is_enabled) {
         acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
@@ -334,26 +306,6 @@ static void ich9_pm_set_memory_hotplug_support(Object *obj, bool value,
     s->pm.acpi_memory_hotplug.is_enabled = value;
 }
 
-static bool ich9_pm_get_cpu_hotplug_legacy(Object *obj, Error **errp)
-{
-    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
-
-    return s->pm.cpu_hotplug_legacy;
-}
-
-static void ich9_pm_set_cpu_hotplug_legacy(Object *obj, bool value,
-                                           Error **errp)
-{
-    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
-
-    assert(!value);
-    if (s->pm.cpu_hotplug_legacy && value == false) {
-        acpi_switch_to_modern_cphp(&s->pm.gpe_cpu, &s->pm.cpuhp_state,
-                                   ICH9_CPU_HOTPLUG_IO_BASE);
-    }
-    s->pm.cpu_hotplug_legacy = value;
-}
-
 static void ich9_pm_get_disable_s3(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
@@ -445,7 +397,6 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
 {
     static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
     pm->acpi_memory_hotplug.is_enabled = true;
-    pm->cpu_hotplug_legacy = true;
     pm->disable_s3 = 0;
     pm->disable_s4 = 0;
     pm->s4_val = 2;
@@ -461,10 +412,6 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
                              ich9_pm_get_memory_hotplug_support,
                              ich9_pm_set_memory_hotplug_support,
                              NULL);
-    object_property_add_bool(obj, "cpu-hotplug-legacy",
-                             ich9_pm_get_cpu_hotplug_legacy,
-                             ich9_pm_set_cpu_hotplug_legacy,
-                             NULL);
     object_property_add(obj, ACPI_PM_PROP_S3_DISABLED, "uint8",
                         ich9_pm_get_disable_s3,
                         ich9_pm_set_disable_s3,
@@ -483,58 +430,39 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
                              NULL);
 }
 
-void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
-                            Error **errp)
+void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp)
 {
-    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
-
-    if (lpc->pm.acpi_memory_hotplug.is_enabled &&
+    if (pm->acpi_memory_hotplug.is_enabled &&
         object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
-        acpi_memory_plug_cb(hotplug_dev, &lpc->pm.acpi_memory_hotplug,
+        acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug,
                             dev, errp);
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
-        if (lpc->pm.cpu_hotplug_legacy) {
-            legacy_acpi_cpu_plug_cb(hotplug_dev, &lpc->pm.gpe_cpu, dev, errp);
-        } else {
-            acpi_cpu_plug_cb(hotplug_dev, &lpc->pm.cpuhp_state, dev, errp);
-        }
+        acpi_cpu_plug_cb(&pm->acpi_regs, pm->irq, &pm->gpe_cpu, dev, errp);
     } else {
         error_setg(errp, "acpi: device plug request for not supported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
     }
 }
 
-void ich9_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev,
-                                      DeviceState *dev, Error **errp)
+void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev,
+                                      Error **errp)
 {
-    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
-
-    if (lpc->pm.acpi_memory_hotplug.is_enabled &&
+    if (pm->acpi_memory_hotplug.is_enabled &&
         object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
-        acpi_memory_unplug_request_cb(hotplug_dev,
-                                      &lpc->pm.acpi_memory_hotplug, dev,
-                                      errp);
-    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
-               !lpc->pm.cpu_hotplug_legacy) {
-        acpi_cpu_unplug_request_cb(hotplug_dev, &lpc->pm.cpuhp_state,
-                                   dev, errp);
+        acpi_memory_unplug_request_cb(&pm->acpi_regs, pm->irq,
+                                      &pm->acpi_memory_hotplug, dev, errp);
     } else {
         error_setg(errp, "acpi: device unplug request for not supported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
     }
 }
 
-void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev,
                               Error **errp)
 {
-    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
-
-    if (lpc->pm.acpi_memory_hotplug.is_enabled &&
+    if (pm->acpi_memory_hotplug.is_enabled &&
         object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
-        acpi_memory_unplug_cb(&lpc->pm.acpi_memory_hotplug, dev, errp);
-    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
-               !lpc->pm.cpu_hotplug_legacy) {
-        acpi_cpu_unplug_cb(&lpc->pm.cpuhp_state, dev, errp);
+        acpi_memory_unplug_cb(&pm->acpi_memory_hotplug, dev, errp);
     } else {
         error_setg(errp, "acpi: device unplug for not supported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
@@ -546,7 +474,4 @@ void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
     ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
 
     acpi_memory_ospm_status(&s->pm.acpi_memory_hotplug, list);
-    if (!s->pm.cpu_hotplug_legacy) {
-        acpi_cpu_ospm_status(&s->pm.cpuhp_state, list);
-    }
 }
diff --git a/hw/acpi/ipmi.c b/hw/acpi/ipmi.c
deleted file mode 100644 (file)
index 7e74ce4..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * IPMI ACPI firmware handling
- *
- * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "hw/ipmi/ipmi.h"
-#include "hw/acpi/aml-build.h"
-#include "hw/acpi/acpi.h"
-#include "hw/acpi/ipmi.h"
-
-static Aml *aml_ipmi_crs(IPMIFwInfo *info)
-{
-    Aml *crs = aml_resource_template();
-
-    /*
-     * The base address is fixed and cannot change.  That may be different
-     * if someone does PCI, but we aren't there yet.
-     */
-    switch (info->memspace) {
-    case IPMI_MEMSPACE_IO:
-        aml_append(crs, aml_io(AML_DECODE16, info->base_address,
-                               info->base_address + info->register_length - 1,
-                               info->register_spacing, info->register_length));
-        break;
-    case IPMI_MEMSPACE_MEM32:
-        aml_append(crs,
-                   aml_dword_memory(AML_POS_DECODE,
-                            AML_MIN_FIXED, AML_MAX_FIXED,
-                            AML_NON_CACHEABLE, AML_READ_WRITE,
-                            0xffffffff,
-                            info->base_address,
-                            info->base_address + info->register_length - 1,
-                            info->register_spacing, info->register_length));
-        break;
-    case IPMI_MEMSPACE_MEM64:
-        aml_append(crs,
-                   aml_qword_memory(AML_POS_DECODE,
-                            AML_MIN_FIXED, AML_MAX_FIXED,
-                            AML_NON_CACHEABLE, AML_READ_WRITE,
-                            0xffffffffffffffffULL,
-                            info->base_address,
-                            info->base_address + info->register_length - 1,
-                            info->register_spacing, info->register_length));
-        break;
-    case IPMI_MEMSPACE_SMBUS:
-        aml_append(crs, aml_return(aml_int(info->base_address)));
-        break;
-    default:
-        abort();
-    }
-
-    if (info->interrupt_number) {
-        aml_append(crs, aml_irq_no_flags(info->interrupt_number));
-    }
-
-    return crs;
-}
-
-static Aml *aml_ipmi_device(IPMIFwInfo *info)
-{
-    Aml *dev;
-    uint16_t version = ((info->ipmi_spec_major_revision << 8)
-                        | (info->ipmi_spec_minor_revision << 4));
-
-    assert(info->ipmi_spec_minor_revision <= 15);
-
-    dev = aml_device("MI%d", info->uuid);
-    aml_append(dev, aml_name_decl("_HID", aml_eisaid("IPI0001")));
-    aml_append(dev, aml_name_decl("_STR", aml_string("ipmi_%s",
-                                                     info->interface_name)));
-    aml_append(dev, aml_name_decl("_UID", aml_int(info->uuid)));
-    aml_append(dev, aml_name_decl("_CRS", aml_ipmi_crs(info)));
-    aml_append(dev, aml_name_decl("_IFT", aml_int(info->interface_type)));
-    aml_append(dev, aml_name_decl("_SRV", aml_int(version)));
-
-    return dev;
-}
-
-void build_acpi_ipmi_devices(Aml *scope, BusState *bus)
-{
-
-    BusChild *kid;
-
-    QTAILQ_FOREACH(kid, &bus->children,  sibling) {
-        IPMIInterface *ii;
-        IPMIInterfaceClass *iic;
-        IPMIFwInfo info;
-        Object *obj = object_dynamic_cast(OBJECT(kid->child),
-                                          TYPE_IPMI_INTERFACE);
-
-        if (!obj) {
-            continue;
-        }
-
-        ii = IPMI_INTERFACE(obj);
-        iic = IPMI_INTERFACE_GET_CLASS(obj);
-        iic->get_fwinfo(ii, &info);
-        aml_append(scope, aml_ipmi_device(&info));
-    }
-}
index ec4e64b..f65a3a2 100644 (file)
@@ -228,7 +228,7 @@ acpi_memory_slot_status(MemHotplugState *mem_st,
     return &mem_st->devs[slot];
 }
 
-void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st,
+void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
                          DeviceState *dev, Error **errp)
 {
     MemStatus *mdev;
@@ -247,11 +247,13 @@ void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st,
     mdev->is_enabled = true;
     if (dev->hotplugged) {
         mdev->is_inserting = true;
-        acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS);
+
+        /* do ACPI magic */
+        acpi_send_gpe_event(ar, irq, ACPI_MEMORY_HOTPLUG_STATUS);
     }
 }
 
-void acpi_memory_unplug_request_cb(HotplugHandler *hotplug_dev,
+void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq,
                                    MemHotplugState *mem_st,
                                    DeviceState *dev, Error **errp)
 {
@@ -263,7 +265,9 @@ void acpi_memory_unplug_request_cb(HotplugHandler *hotplug_dev,
     }
 
     mdev->is_removing = true;
-    acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS);
+
+    /* Do ACPI magic */
+    acpi_send_gpe_event(ar, irq, ACPI_MEMORY_HOTPLUG_STATUS);
 }
 
 void acpi_memory_unplug_cb(MemHotplugState *mem_st,
index e486128..9531340 100644 (file)
@@ -216,26 +216,6 @@ static uint32_t nvdimm_slot_to_dcr_index(int slot)
     return nvdimm_slot_to_spa_index(slot) + 1;
 }
 
-static NVDIMMDevice *nvdimm_get_device_by_handle(uint32_t handle)
-{
-    NVDIMMDevice *nvdimm = NULL;
-    GSList *list, *device_list = nvdimm_get_plugged_device_list();
-
-    for (list = device_list; list; list = list->next) {
-        NVDIMMDevice *nvd = list->data;
-        int slot = object_property_get_int(OBJECT(nvd), PC_DIMM_SLOT_PROP,
-                                           NULL);
-
-        if (nvdimm_slot_to_handle(slot) == handle) {
-            nvdimm = nvd;
-            break;
-        }
-    }
-
-    g_slist_free(device_list);
-    return nvdimm;
-}
-
 /* ACPI 6.0: 5.2.25.1 System Physical Address Range Structure */
 static void
 nvdimm_build_structure_spa(GArray *structures, DeviceState *dev)
@@ -373,7 +353,7 @@ static GArray *nvdimm_build_device_structure(GSList *device_list)
 }
 
 static void nvdimm_build_nfit(GSList *device_list, GArray *table_offsets,
-                              GArray *table_data, BIOSLinker *linker)
+                              GArray *table_data, GArray *linker)
 {
     GArray *structures = nvdimm_build_device_structure(device_list);
     unsigned int header;
@@ -398,19 +378,17 @@ struct NvdimmDsmIn {
     uint32_t function;
     /* the remaining size in the page is used by arg3. */
     union {
-        uint8_t arg3[4084];
+        uint8_t arg3[0];
     };
 } QEMU_PACKED;
 typedef struct NvdimmDsmIn NvdimmDsmIn;
-QEMU_BUILD_BUG_ON(sizeof(NvdimmDsmIn) != 4096);
 
 struct NvdimmDsmOut {
     /* the size of buffer filled by QEMU. */
     uint32_t len;
-    uint8_t data[4092];
+    uint8_t data[0];
 } QEMU_PACKED;
 typedef struct NvdimmDsmOut NvdimmDsmOut;
-QEMU_BUILD_BUG_ON(sizeof(NvdimmDsmOut) != 4096);
 
 struct NvdimmDsmFunc0Out {
     /* the size of buffer filled by QEMU. */
@@ -426,282 +404,6 @@ struct NvdimmDsmFuncNoPayloadOut {
 } QEMU_PACKED;
 typedef struct NvdimmDsmFuncNoPayloadOut NvdimmDsmFuncNoPayloadOut;
 
-struct NvdimmFuncGetLabelSizeOut {
-    /* the size of buffer filled by QEMU. */
-    uint32_t len;
-    uint32_t func_ret_status; /* return status code. */
-    uint32_t label_size; /* the size of label data area. */
-    /*
-     * Maximum size of the namespace label data length supported by
-     * the platform in Get/Set Namespace Label Data functions.
-     */
-    uint32_t max_xfer;
-} QEMU_PACKED;
-typedef struct NvdimmFuncGetLabelSizeOut NvdimmFuncGetLabelSizeOut;
-QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelSizeOut) > 4096);
-
-struct NvdimmFuncGetLabelDataIn {
-    uint32_t offset; /* the offset in the namespace label data area. */
-    uint32_t length; /* the size of data is to be read via the function. */
-} QEMU_PACKED;
-typedef struct NvdimmFuncGetLabelDataIn NvdimmFuncGetLabelDataIn;
-QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelDataIn) +
-                  offsetof(NvdimmDsmIn, arg3) > 4096);
-
-struct NvdimmFuncGetLabelDataOut {
-    /* the size of buffer filled by QEMU. */
-    uint32_t len;
-    uint32_t func_ret_status; /* return status code. */
-    uint8_t out_buf[0]; /* the data got via Get Namesapce Label function. */
-} QEMU_PACKED;
-typedef struct NvdimmFuncGetLabelDataOut NvdimmFuncGetLabelDataOut;
-QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelDataOut) > 4096);
-
-struct NvdimmFuncSetLabelDataIn {
-    uint32_t offset; /* the offset in the namespace label data area. */
-    uint32_t length; /* the size of data is to be written via the function. */
-    uint8_t in_buf[0]; /* the data written to label data area. */
-} QEMU_PACKED;
-typedef struct NvdimmFuncSetLabelDataIn NvdimmFuncSetLabelDataIn;
-QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncSetLabelDataIn) +
-                  offsetof(NvdimmDsmIn, arg3) > 4096);
-
-static void
-nvdimm_dsm_function0(uint32_t supported_func, hwaddr dsm_mem_addr)
-{
-    NvdimmDsmFunc0Out func0 = {
-        .len = cpu_to_le32(sizeof(func0)),
-        .supported_func = cpu_to_le32(supported_func),
-    };
-    cpu_physical_memory_write(dsm_mem_addr, &func0, sizeof(func0));
-}
-
-static void
-nvdimm_dsm_no_payload(uint32_t func_ret_status, hwaddr dsm_mem_addr)
-{
-    NvdimmDsmFuncNoPayloadOut out = {
-        .len = cpu_to_le32(sizeof(out)),
-        .func_ret_status = cpu_to_le32(func_ret_status),
-    };
-    cpu_physical_memory_write(dsm_mem_addr, &out, sizeof(out));
-}
-
-static void nvdimm_dsm_root(NvdimmDsmIn *in, hwaddr dsm_mem_addr)
-{
-    /*
-     * function 0 is called to inquire which functions are supported by
-     * OSPM
-     */
-    if (!in->function) {
-        nvdimm_dsm_function0(0 /* No function supported other than
-                                  function 0 */, dsm_mem_addr);
-        return;
-    }
-
-    /* No function except function 0 is supported yet. */
-    nvdimm_dsm_no_payload(1 /* Not Supported */, dsm_mem_addr);
-}
-
-/*
- * the max transfer size is the max size transferred by both a
- * 'Get Namespace Label Data' function and a 'Set Namespace Label Data'
- * function.
- */
-static uint32_t nvdimm_get_max_xfer_label_size(void)
-{
-    uint32_t max_get_size, max_set_size, dsm_memory_size = 4096;
-
-    /*
-     * the max data ACPI can read one time which is transferred by
-     * the response of 'Get Namespace Label Data' function.
-     */
-    max_get_size = dsm_memory_size - sizeof(NvdimmFuncGetLabelDataOut);
-
-    /*
-     * the max data ACPI can write one time which is transferred by
-     * 'Set Namespace Label Data' function.
-     */
-    max_set_size = dsm_memory_size - offsetof(NvdimmDsmIn, arg3) -
-                   sizeof(NvdimmFuncSetLabelDataIn);
-
-    return MIN(max_get_size, max_set_size);
-}
-
-/*
- * DSM Spec Rev1 4.4 Get Namespace Label Size (Function Index 4).
- *
- * It gets the size of Namespace Label data area and the max data size
- * that Get/Set Namespace Label Data functions can transfer.
- */
-static void nvdimm_dsm_label_size(NVDIMMDevice *nvdimm, hwaddr dsm_mem_addr)
-{
-    NvdimmFuncGetLabelSizeOut label_size_out = {
-        .len = cpu_to_le32(sizeof(label_size_out)),
-    };
-    uint32_t label_size, mxfer;
-
-    label_size = nvdimm->label_size;
-    mxfer = nvdimm_get_max_xfer_label_size();
-
-    nvdimm_debug("label_size %#x, max_xfer %#x.\n", label_size, mxfer);
-
-    label_size_out.func_ret_status = cpu_to_le32(0 /* Success */);
-    label_size_out.label_size = cpu_to_le32(label_size);
-    label_size_out.max_xfer = cpu_to_le32(mxfer);
-
-    cpu_physical_memory_write(dsm_mem_addr, &label_size_out,
-                              sizeof(label_size_out));
-}
-
-static uint32_t nvdimm_rw_label_data_check(NVDIMMDevice *nvdimm,
-                                           uint32_t offset, uint32_t length)
-{
-    uint32_t ret = 3 /* Invalid Input Parameters */;
-
-    if (offset + length < offset) {
-        nvdimm_debug("offset %#x + length %#x is overflow.\n", offset,
-                     length);
-        return ret;
-    }
-
-    if (nvdimm->label_size < offset + length) {
-        nvdimm_debug("position %#x is beyond label data (len = %" PRIx64 ").\n",
-                     offset + length, nvdimm->label_size);
-        return ret;
-    }
-
-    if (length > nvdimm_get_max_xfer_label_size()) {
-        nvdimm_debug("length (%#x) is larger than max_xfer (%#x).\n",
-                     length, nvdimm_get_max_xfer_label_size());
-        return ret;
-    }
-
-    return 0 /* Success */;
-}
-
-/*
- * DSM Spec Rev1 4.5 Get Namespace Label Data (Function Index 5).
- */
-static void nvdimm_dsm_get_label_data(NVDIMMDevice *nvdimm, NvdimmDsmIn *in,
-                                      hwaddr dsm_mem_addr)
-{
-    NVDIMMClass *nvc = NVDIMM_GET_CLASS(nvdimm);
-    NvdimmFuncGetLabelDataIn *get_label_data;
-    NvdimmFuncGetLabelDataOut *get_label_data_out;
-    uint32_t status;
-    int size;
-
-    get_label_data = (NvdimmFuncGetLabelDataIn *)in->arg3;
-    le32_to_cpus(&get_label_data->offset);
-    le32_to_cpus(&get_label_data->length);
-
-    nvdimm_debug("Read Label Data: offset %#x length %#x.\n",
-                 get_label_data->offset, get_label_data->length);
-
-    status = nvdimm_rw_label_data_check(nvdimm, get_label_data->offset,
-                                        get_label_data->length);
-    if (status != 0 /* Success */) {
-        nvdimm_dsm_no_payload(status, dsm_mem_addr);
-        return;
-    }
-
-    size = sizeof(*get_label_data_out) + get_label_data->length;
-    assert(size <= 4096);
-    get_label_data_out = g_malloc(size);
-
-    get_label_data_out->len = cpu_to_le32(size);
-    get_label_data_out->func_ret_status = cpu_to_le32(0 /* Success */);
-    nvc->read_label_data(nvdimm, get_label_data_out->out_buf,
-                         get_label_data->length, get_label_data->offset);
-
-    cpu_physical_memory_write(dsm_mem_addr, get_label_data_out, size);
-    g_free(get_label_data_out);
-}
-
-/*
- * DSM Spec Rev1 4.6 Set Namespace Label Data (Function Index 6).
- */
-static void nvdimm_dsm_set_label_data(NVDIMMDevice *nvdimm, NvdimmDsmIn *in,
-                                      hwaddr dsm_mem_addr)
-{
-    NVDIMMClass *nvc = NVDIMM_GET_CLASS(nvdimm);
-    NvdimmFuncSetLabelDataIn *set_label_data;
-    uint32_t status;
-
-    set_label_data = (NvdimmFuncSetLabelDataIn *)in->arg3;
-
-    le32_to_cpus(&set_label_data->offset);
-    le32_to_cpus(&set_label_data->length);
-
-    nvdimm_debug("Write Label Data: offset %#x length %#x.\n",
-                 set_label_data->offset, set_label_data->length);
-
-    status = nvdimm_rw_label_data_check(nvdimm, set_label_data->offset,
-                                        set_label_data->length);
-    if (status != 0 /* Success */) {
-        nvdimm_dsm_no_payload(status, dsm_mem_addr);
-        return;
-    }
-
-    assert(sizeof(*in) + sizeof(*set_label_data) + set_label_data->length <=
-           4096);
-
-    nvc->write_label_data(nvdimm, set_label_data->in_buf,
-                          set_label_data->length, set_label_data->offset);
-    nvdimm_dsm_no_payload(0 /* Success */, dsm_mem_addr);
-}
-
-static void nvdimm_dsm_device(NvdimmDsmIn *in, hwaddr dsm_mem_addr)
-{
-    NVDIMMDevice *nvdimm = nvdimm_get_device_by_handle(in->handle);
-
-    /* See the comments in nvdimm_dsm_root(). */
-    if (!in->function) {
-        uint32_t supported_func = 0;
-
-        if (nvdimm && nvdimm->label_size) {
-            supported_func |= 0x1 /* Bit 0 indicates whether there is
-                                     support for any functions other
-                                     than function 0. */ |
-                              1 << 4 /* Get Namespace Label Size */ |
-                              1 << 5 /* Get Namespace Label Data */ |
-                              1 << 6 /* Set Namespace Label Data */;
-        }
-        nvdimm_dsm_function0(supported_func, dsm_mem_addr);
-        return;
-    }
-
-    if (!nvdimm) {
-        nvdimm_dsm_no_payload(2 /* Non-Existing Memory Device */,
-                              dsm_mem_addr);
-        return;
-    }
-
-    /* Encode DSM function according to DSM Spec Rev1. */
-    switch (in->function) {
-    case 4 /* Get Namespace Label Size */:
-        if (nvdimm->label_size) {
-            nvdimm_dsm_label_size(nvdimm, dsm_mem_addr);
-            return;
-        }
-        break;
-    case 5 /* Get Namespace Label Data */:
-        if (nvdimm->label_size) {
-            nvdimm_dsm_get_label_data(nvdimm, in, dsm_mem_addr);
-            return;
-        }
-        break;
-    case 0x6 /* Set Namespace Label Data */:
-        if (nvdimm->label_size) {
-            nvdimm_dsm_set_label_data(nvdimm, in, dsm_mem_addr);
-            return;
-        }
-        break;
-    }
-
-    nvdimm_dsm_no_payload(1 /* Not Supported */, dsm_mem_addr);
-}
-
 static uint64_t
 nvdimm_dsm_read(void *opaque, hwaddr addr, unsigned size)
 {
@@ -722,8 +424,8 @@ nvdimm_dsm_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
      * can change its content while we are doing DSM emulation. Avoid
      * this by copying DSM memory to QEMU local memory.
      */
-    in = g_new(NvdimmDsmIn, 1);
-    cpu_physical_memory_read(dsm_mem_addr, in, sizeof(*in));
+    in = g_malloc(TARGET_PAGE_SIZE);
+    cpu_physical_memory_read(dsm_mem_addr, in, TARGET_PAGE_SIZE);
 
     le32_to_cpus(&in->revision);
     le32_to_cpus(&in->function);
@@ -732,22 +434,26 @@ nvdimm_dsm_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
     nvdimm_debug("Revision %#x Handler %#x Function %#x.\n", in->revision,
                  in->handle, in->function);
 
-    if (in->revision != 0x1 /* Currently we only support DSM Spec Rev1. */) {
-        nvdimm_debug("Revision %#x is not supported, expect %#x.\n",
-                     in->revision, 0x1);
-        nvdimm_dsm_no_payload(1 /* Not Supported */, dsm_mem_addr);
-        goto exit;
-    }
-
-     /* Handle 0 is reserved for NVDIMM Root Device. */
-    if (!in->handle) {
-        nvdimm_dsm_root(in, dsm_mem_addr);
-        goto exit;
+    /*
+     * function 0 is called to inquire which functions are supported by
+     * OSPM
+     */
+    if (in->function == 0) {
+        NvdimmDsmFunc0Out func0 = {
+            .len = cpu_to_le32(sizeof(func0)),
+             /* No function supported other than function 0 */
+            .supported_func = cpu_to_le32(0),
+        };
+        cpu_physical_memory_write(dsm_mem_addr, &func0, sizeof func0);
+    } else {
+        /* No function except function 0 is supported yet. */
+        NvdimmDsmFuncNoPayloadOut out = {
+            .len = cpu_to_le32(sizeof(out)),
+            .func_ret_status = cpu_to_le32(1)  /* Not Supported */,
+        };
+        cpu_physical_memory_write(dsm_mem_addr, &out, sizeof(out));
     }
 
-    nvdimm_dsm_device(in, dsm_mem_addr);
-
-exit:
     g_free(in);
 }
 
@@ -769,7 +475,7 @@ void nvdimm_init_acpi_state(AcpiNVDIMMState *state, MemoryRegion *io,
     memory_region_add_subregion(io, NVDIMM_ACPI_IO_BASE, &state->io_mr);
 
     state->dsm_mem = g_array_new(false, true /* clear */, 1);
-    acpi_data_push(state->dsm_mem, sizeof(NvdimmDsmIn));
+    acpi_data_push(state->dsm_mem, TARGET_PAGE_SIZE);
     fw_cfg_add_file(fw_cfg, NVDIMM_DSM_MEM_FILE, state->dsm_mem->data,
                     state->dsm_mem->len);
 }
@@ -779,39 +485,18 @@ void nvdimm_init_acpi_state(AcpiNVDIMMState *state, MemoryRegion *io,
 
 static void nvdimm_build_common_dsm(Aml *dev)
 {
-    Aml *method, *ifctx, *function, *handle, *uuid, *dsm_mem, *result_size;
-    Aml *elsectx, *unsupport, *unpatched, *expected_uuid, *uuid_invalid;
-    Aml *pckg, *pckg_index, *pckg_buf;
+    Aml *method, *ifctx, *function, *dsm_mem, *unpatched, *result_size;
     uint8_t byte_list[1];
 
-    method = aml_method(NVDIMM_COMMON_DSM, 5, AML_SERIALIZED);
-    uuid = aml_arg(0);
+    method = aml_method(NVDIMM_COMMON_DSM, 4, AML_SERIALIZED);
     function = aml_arg(2);
-    handle = aml_arg(4);
     dsm_mem = aml_name(NVDIMM_ACPI_MEM_ADDR);
 
     /*
      * do not support any method if DSM memory address has not been
      * patched.
      */
-    unpatched = aml_equal(dsm_mem, aml_int(0x0));
-
-    expected_uuid = aml_local(0);
-
-    ifctx = aml_if(aml_equal(handle, aml_int(0x0)));
-    aml_append(ifctx, aml_store(
-               aml_touuid("2F10E7A4-9E91-11E4-89D3-123B93F75CBA")
-               /* UUID for NVDIMM Root Device */, expected_uuid));
-    aml_append(method, ifctx);
-    elsectx = aml_else();
-    aml_append(elsectx, aml_store(
-               aml_touuid("4309AC30-0D11-11E4-9191-0800200C9A66")
-               /* UUID for NVDIMM Devices */, expected_uuid));
-    aml_append(method, elsectx);
-
-    uuid_invalid = aml_lnot(aml_equal(uuid, expected_uuid));
-
-    unsupport = aml_if(aml_or(unpatched, uuid_invalid, NULL));
+    unpatched = aml_if(aml_equal(dsm_mem, aml_int(0x0)));
 
     /*
      * function 0 is called to inquire what functions are supported by
@@ -820,42 +505,24 @@ static void nvdimm_build_common_dsm(Aml *dev)
     ifctx = aml_if(aml_equal(function, aml_int(0)));
     byte_list[0] = 0 /* No function Supported */;
     aml_append(ifctx, aml_return(aml_buffer(1, byte_list)));
-    aml_append(unsupport, ifctx);
+    aml_append(unpatched, ifctx);
 
     /* No function is supported yet. */
     byte_list[0] = 1 /* Not Supported */;
-    aml_append(unsupport, aml_return(aml_buffer(1, byte_list)));
-    aml_append(method, unsupport);
+    aml_append(unpatched, aml_return(aml_buffer(1, byte_list)));
+    aml_append(method, unpatched);
 
     /*
      * The HDLE indicates the DSM function is issued from which device,
-     * it reserves 0 for root device and is the handle for NVDIMM devices.
-     * See the comments in nvdimm_slot_to_handle().
+     * it is not used at this time as no function is supported yet.
+     * Currently we make it always be 0 for all the devices and will set
+     * the appropriate value once real function is implemented.
      */
-    aml_append(method, aml_store(handle, aml_name("HDLE")));
+    aml_append(method, aml_store(aml_int(0x0), aml_name("HDLE")));
     aml_append(method, aml_store(aml_arg(1), aml_name("REVS")));
     aml_append(method, aml_store(aml_arg(2), aml_name("FUNC")));
 
     /*
-     * The fourth parameter (Arg3) of _DSM is a package which contains
-     * a buffer, the layout of the buffer is specified by UUID (Arg0),
-     * Revision ID (Arg1) and Function Index (Arg2) which are documented
-     * in the DSM Spec.
-     */
-    pckg = aml_arg(3);
-    ifctx = aml_if(aml_and(aml_equal(aml_object_type(pckg),
-                   aml_int(4 /* Package */)) /* It is a Package? */,
-                   aml_equal(aml_sizeof(pckg), aml_int(1)) /* 1 element? */,
-                   NULL));
-
-    pckg_index = aml_local(2);
-    pckg_buf = aml_local(3);
-    aml_append(ifctx, aml_store(aml_index(pckg, aml_int(0)), pckg_index));
-    aml_append(ifctx, aml_store(aml_derefof(pckg_index), pckg_buf));
-    aml_append(ifctx, aml_store(pckg_buf, aml_name("ARG3")));
-    aml_append(method, ifctx);
-
-    /*
      * tell QEMU about the real address of DSM memory, then QEMU
      * gets the control and fills the result in DSM memory.
      */
@@ -873,14 +540,13 @@ static void nvdimm_build_common_dsm(Aml *dev)
     aml_append(dev, method);
 }
 
-static void nvdimm_build_device_dsm(Aml *dev, uint32_t handle)
+static void nvdimm_build_device_dsm(Aml *dev)
 {
     Aml *method;
 
     method = aml_method("_DSM", 4, AML_NOTSERIALIZED);
-    aml_append(method, aml_return(aml_call5(NVDIMM_COMMON_DSM, aml_arg(0),
-                                  aml_arg(1), aml_arg(2), aml_arg(3),
-                                  aml_int(handle))));
+    aml_append(method, aml_return(aml_call4(NVDIMM_COMMON_DSM, aml_arg(0),
+                                  aml_arg(1), aml_arg(2), aml_arg(3))));
     aml_append(dev, method);
 }
 
@@ -905,14 +571,13 @@ static void nvdimm_build_nvdimm_devices(GSList *device_list, Aml *root_dev)
          */
         aml_append(nvdimm_dev, aml_name_decl("_ADR", aml_int(handle)));
 
-        nvdimm_build_device_dsm(nvdimm_dev, handle);
+        nvdimm_build_device_dsm(nvdimm_dev);
         aml_append(root_dev, nvdimm_dev);
     }
 }
 
 static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
-                              GArray *table_data, BIOSLinker *linker,
-                              GArray *dsm_dma_arrea)
+                              GArray *table_data, GArray *linker)
 {
     Aml *ssdt, *sb_scope, *dev, *field;
     int mem_addr_offset, nvdimm_ssdt;
@@ -943,7 +608,7 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
     aml_append(dev, aml_operation_region("NPIO", AML_SYSTEM_IO,
                aml_int(NVDIMM_ACPI_IO_BASE), NVDIMM_ACPI_IO_LEN));
     aml_append(dev, aml_operation_region("NRAM", AML_SYSTEM_MEMORY,
-               aml_name(NVDIMM_ACPI_MEM_ADDR), sizeof(NvdimmDsmIn)));
+               aml_name(NVDIMM_ACPI_MEM_ADDR), TARGET_PAGE_SIZE));
 
     /*
      * DSM notifier:
@@ -977,7 +642,8 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
     aml_append(field, aml_named_field("FUNC",
                sizeof(typeof_field(NvdimmDsmIn, function)) * BITS_PER_BYTE));
     aml_append(field, aml_named_field("ARG3",
-               (sizeof(NvdimmDsmIn) - offsetof(NvdimmDsmIn, arg3)) * BITS_PER_BYTE));
+               (TARGET_PAGE_SIZE - offsetof(NvdimmDsmIn, arg3)) *
+                BITS_PER_BYTE));
     aml_append(dev, field);
 
     /*
@@ -993,13 +659,12 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
     aml_append(field, aml_named_field("RLEN",
                sizeof(typeof_field(NvdimmDsmOut, len)) * BITS_PER_BYTE));
     aml_append(field, aml_named_field("ODAT",
-               (sizeof(NvdimmDsmOut) - offsetof(NvdimmDsmOut, data)) * BITS_PER_BYTE));
+               (TARGET_PAGE_SIZE - offsetof(NvdimmDsmOut, data)) *
+                     BITS_PER_BYTE));
     aml_append(dev, field);
 
     nvdimm_build_common_dsm(dev);
-
-    /* 0 is reserved for root device. */
-    nvdimm_build_device_dsm(dev, 0);
+    nvdimm_build_device_dsm(dev);
 
     nvdimm_build_nvdimm_devices(device_list, dev);
 
@@ -1013,12 +678,12 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
     mem_addr_offset = build_append_named_dword(table_data,
                                                NVDIMM_ACPI_MEM_ADDR);
 
-    bios_linker_loader_alloc(linker,
-                             NVDIMM_DSM_MEM_FILE, dsm_dma_arrea,
-                             sizeof(NvdimmDsmIn), false /* high memory */);
-    bios_linker_loader_add_pointer(linker,
-        ACPI_BUILD_TABLE_FILE, mem_addr_offset, sizeof(uint32_t),
-        NVDIMM_DSM_MEM_FILE, 0);
+    bios_linker_loader_alloc(linker, NVDIMM_DSM_MEM_FILE, TARGET_PAGE_SIZE,
+                             false /* high memory */);
+    bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+                                   NVDIMM_DSM_MEM_FILE, table_data,
+                                   table_data->data + mem_addr_offset,
+                                   sizeof(uint32_t));
     build_header(linker, table_data,
         (void *)(table_data->data + nvdimm_ssdt),
         "SSDT", table_data->len - nvdimm_ssdt, 1, NULL, "NVDIMM");
@@ -1026,7 +691,7 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
 }
 
 void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data,
-                       BIOSLinker *linker, GArray *dsm_dma_arrea)
+                       GArray *linker)
 {
     GSList *device_list;
 
@@ -1036,7 +701,6 @@ void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data,
         return;
     }
     nvdimm_build_nfit(device_list, table_offsets, table_data, linker);
-    nvdimm_build_ssdt(device_list, table_offsets, table_data, linker,
-                      dsm_dma_arrea);
+    nvdimm_build_ssdt(device_list, table_offsets, table_data, linker);
     g_slist_free(device_list);
 }
index d957d1e..71f4c4e 100644 (file)
@@ -182,7 +182,7 @@ void acpi_pcihp_reset(AcpiPciHpState *s)
     acpi_pcihp_update(s);
 }
 
-void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
+void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s,
                                DeviceState *dev, Error **errp)
 {
     PCIDevice *pdev = PCI_DEVICE(dev);
@@ -202,10 +202,11 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
     }
 
     s->acpi_pcihp_pci_status[bsel].up |= (1U << slot);
-    acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
+
+    acpi_send_gpe_event(ar, irq, ACPI_PCI_HOTPLUG_STATUS);
 }
 
-void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
+void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s,
                                  DeviceState *dev, Error **errp)
 {
     PCIDevice *pdev = PCI_DEVICE(dev);
@@ -218,7 +219,8 @@ void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
     }
 
     s->acpi_pcihp_pci_status[bsel].down |= (1U << slot);
-    acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
+
+    acpi_send_gpe_event(ar, irq, ACPI_PCI_HOTPLUG_STATUS);
 }
 
 static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
index 2adc246..16abdf1 100644 (file)
 #include "hw/acpi/piix4.h"
 #include "hw/acpi/pcihp.h"
 #include "hw/acpi/cpu_hotplug.h"
-#include "hw/acpi/cpu.h"
 #include "hw/hotplug.h"
 #include "hw/mem/pc-dimm.h"
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/xen/xen.h"
-#include "qom/cpu.h"
 
 //#define DEBUG
 
@@ -87,9 +85,7 @@ typedef struct PIIX4PMState {
     uint8_t disable_s4;
     uint8_t s4_val;
 
-    bool cpu_hotplug_legacy;
     AcpiCpuHotplug gpe_cpu;
-    CPUHotplugState cpuhp_state;
 
     MemHotplugState acpi_memory_hotplug;
 } PIIX4PMState;
@@ -276,32 +272,6 @@ static const VMStateDescription vmstate_memhp_state = {
     }
 };
 
-static bool vmstate_test_use_cpuhp(void *opaque)
-{
-    PIIX4PMState *s = opaque;
-    return !s->cpu_hotplug_legacy;
-}
-
-static int vmstate_cpuhp_pre_load(void *opaque)
-{
-    Object *obj = OBJECT(opaque);
-    object_property_set_bool(obj, false, "cpu-hotplug-legacy", &error_abort);
-    return 0;
-}
-
-static const VMStateDescription vmstate_cpuhp_state = {
-    .name = "piix4_pm/cpuhp",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
-    .needed = vmstate_test_use_cpuhp,
-    .pre_load = vmstate_cpuhp_pre_load,
-    .fields      = (VMStateField[]) {
-        VMSTATE_CPU_HOTPLUG(cpuhp_state, PIIX4PMState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
 /* qemu-kvm 1.2 uses version 3 but advertised as 2
  * To support incoming qemu-kvm 1.2 migration, change version_id
  * and minimum_version_id to 2 below (which breaks migration from
@@ -336,7 +306,6 @@ static const VMStateDescription vmstate_acpi = {
     },
     .subsections = (const VMStateDescription*[]) {
          &vmstate_memhp_state,
-         &vmstate_cpuhp_state,
          NULL
     }
 };
@@ -378,15 +347,12 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
 
     if (s->acpi_memory_hotplug.is_enabled &&
         object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
-        acpi_memory_plug_cb(hotplug_dev, &s->acpi_memory_hotplug, dev, errp);
+        acpi_memory_plug_cb(&s->ar, s->irq, &s->acpi_memory_hotplug, dev, errp);
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
-        acpi_pcihp_device_plug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, errp);
+        acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
+                                  errp);
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
-        if (s->cpu_hotplug_legacy) {
-            legacy_acpi_cpu_plug_cb(hotplug_dev, &s->gpe_cpu, dev, errp);
-        } else {
-            acpi_cpu_plug_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
-        }
+        acpi_cpu_plug_cb(&s->ar, s->irq, &s->gpe_cpu, dev, errp);
     } else {
         error_setg(errp, "acpi: device plug request for not supported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
@@ -400,14 +366,11 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev,
 
     if (s->acpi_memory_hotplug.is_enabled &&
         object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
-        acpi_memory_unplug_request_cb(hotplug_dev, &s->acpi_memory_hotplug,
+        acpi_memory_unplug_request_cb(&s->ar, s->irq, &s->acpi_memory_hotplug,
                                       dev, errp);
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
-        acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
+        acpi_pcihp_device_unplug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
                                     errp);
-    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
-               !s->cpu_hotplug_legacy) {
-        acpi_cpu_unplug_request_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
     } else {
         error_setg(errp, "acpi: device unplug request for not supported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
@@ -422,9 +385,6 @@ static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev,
     if (s->acpi_memory_hotplug.is_enabled &&
         object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
         acpi_memory_unplug_cb(&s->acpi_memory_hotplug, dev, errp);
-    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
-               !s->cpu_hotplug_legacy) {
-        acpi_cpu_unplug_cb(&s->cpuhp_state, dev, errp);
     } else {
         error_setg(errp, "acpi: device unplug for not supported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
@@ -600,26 +560,6 @@ static const MemoryRegionOps piix4_gpe_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-
-static bool piix4_get_cpu_hotplug_legacy(Object *obj, Error **errp)
-{
-    PIIX4PMState *s = PIIX4_PM(obj);
-
-    return s->cpu_hotplug_legacy;
-}
-
-static void piix4_set_cpu_hotplug_legacy(Object *obj, bool value, Error **errp)
-{
-    PIIX4PMState *s = PIIX4_PM(obj);
-
-    assert(!value);
-    if (s->cpu_hotplug_legacy && value == false) {
-        acpi_switch_to_modern_cphp(&s->gpe_cpu, &s->cpuhp_state,
-                                   PIIX4_CPU_HOTPLUG_IO_BASE);
-    }
-    s->cpu_hotplug_legacy = value;
-}
-
 static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
                                            PCIBus *bus, PIIX4PMState *s)
 {
@@ -630,13 +570,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
     acpi_pcihp_init(OBJECT(s), &s->acpi_pci_hotplug, bus, parent,
                     s->use_acpi_pci_hotplug);
 
-    s->cpu_hotplug_legacy = true;
-    object_property_add_bool(OBJECT(s), "cpu-hotplug-legacy",
-                             piix4_get_cpu_hotplug_legacy,
-                             piix4_set_cpu_hotplug_legacy,
-                             NULL);
-    legacy_acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
-                                 PIIX4_CPU_HOTPLUG_IO_BASE);
+    acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
+                          PIIX4_CPU_HOTPLUG_IO_BASE);
 
     if (s->acpi_memory_hotplug.is_enabled) {
         acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
@@ -648,16 +583,6 @@ static void piix4_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
     PIIX4PMState *s = PIIX4_PM(adev);
 
     acpi_memory_ospm_status(&s->acpi_memory_hotplug, list);
-    if (!s->cpu_hotplug_legacy) {
-        acpi_cpu_ospm_status(&s->cpuhp_state, list);
-    }
-}
-
-static void piix4_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
-{
-    PIIX4PMState *s = PIIX4_PM(adev);
-
-    acpi_send_gpe_event(&s->ar, s->irq, ev);
 }
 
 static Property piix4_pm_properties[] = {
@@ -698,8 +623,6 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
     hc->unplug_request = piix4_device_unplug_request_cb;
     hc->unplug = piix4_device_unplug_cb;
     adevc->ospm_status = piix4_ospm_status;
-    adevc->send_event = piix4_send_gpe;
-    adevc->madt_cpu = pc_madt_cpu_entry;
 }
 
 static const TypeInfo piix4_pm_info = {
diff --git a/hw/acpi/trace-events b/hw/acpi/trace-events
deleted file mode 100644 (file)
index c379607..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/acpi/memory_hotplug.c
-mhp_acpi_invalid_slot_selected(uint32_t slot) "0x%"PRIx32
-mhp_acpi_ejecting_invalid_slot(uint32_t slot) "0x%"PRIx32
-mhp_acpi_read_addr_lo(uint32_t slot, uint32_t addr) "slot[0x%"PRIx32"] addr lo: 0x%"PRIx32
-mhp_acpi_read_addr_hi(uint32_t slot, uint32_t addr) "slot[0x%"PRIx32"] addr hi: 0x%"PRIx32
-mhp_acpi_read_size_lo(uint32_t slot, uint32_t size) "slot[0x%"PRIx32"] size lo: 0x%"PRIx32
-mhp_acpi_read_size_hi(uint32_t slot, uint32_t size) "slot[0x%"PRIx32"] size hi: 0x%"PRIx32
-mhp_acpi_read_pxm(uint32_t slot, uint32_t pxm) "slot[0x%"PRIx32"] proximity: 0x%"PRIx32
-mhp_acpi_read_flags(uint32_t slot, uint32_t flags) "slot[0x%"PRIx32"] flags: 0x%"PRIx32
-mhp_acpi_write_slot(uint32_t slot) "set active slot: 0x%"PRIx32
-mhp_acpi_write_ost_ev(uint32_t slot, uint32_t ev) "slot[0x%"PRIx32"] OST EVENT: 0x%"PRIx32
-mhp_acpi_write_ost_status(uint32_t slot, uint32_t st) "slot[0x%"PRIx32"] OST STATUS: 0x%"PRIx32
-mhp_acpi_clear_insert_evt(uint32_t slot) "slot[0x%"PRIx32"] clear insert event"
-mhp_acpi_clear_remove_evt(uint32_t slot) "slot[0x%"PRIx32"] clear remove event"
-mhp_acpi_pc_dimm_deleted(uint32_t slot) "slot[0x%"PRIx32"] pc-dimm deleted"
-mhp_acpi_pc_dimm_delete_failed(uint32_t slot) "slot[0x%"PRIx32"] pc-dimm delete failed"
-
-# hw/acpi/cpu.c
-cpuhp_acpi_invalid_idx_selected(uint32_t idx) "0x%"PRIx32
-cpuhp_acpi_read_flags(uint32_t idx, uint8_t flags) "idx[0x%"PRIx32"] flags: 0x%"PRIx8
-cpuhp_acpi_write_idx(uint32_t idx) "set active cpu idx: 0x%"PRIx32
-cpuhp_acpi_write_cmd(uint32_t idx, uint8_t cmd) "idx[0x%"PRIx32"] cmd: 0x%"PRIx8
-cpuhp_acpi_read_cmd_data(uint32_t idx, uint32_t data) "idx[0x%"PRIx32"] data: 0x%"PRIx32
-cpuhp_acpi_cpu_has_events(uint32_t idx, bool ins, bool rm) "idx[0x%"PRIx32"] inserting: %d, removing: %d"
-cpuhp_acpi_clear_inserting_evt(uint32_t idx) "idx[0x%"PRIx32"]"
-cpuhp_acpi_clear_remove_evt(uint32_t idx) "idx[0x%"PRIx32"]"
-cpuhp_acpi_ejecting_invalid_cpu(uint32_t idx) "0x%"PRIx32
-cpuhp_acpi_ejecting_cpu(uint32_t idx) "0x%"PRIx32
-cpuhp_acpi_write_ost_ev(uint32_t slot, uint32_t ev) "idx[0x%"PRIx32"] OST EVENT: 0x%"PRIx32
-cpuhp_acpi_write_ost_status(uint32_t slot, uint32_t st) "idx[0x%"PRIx32"] OST STATUS: 0x%"PRIx32
index ed911f2..e11025b 100644 (file)
@@ -1,9 +1,8 @@
 /* Alpha cores and system support chips.  */
 
-#ifndef HW_ALPHA_SYS_H
-#define HW_ALPHA_SYS_H
+#ifndef HW_ALPHA_H
+#define HW_ALPHA_H 1
 
-#include "target-alpha/cpu-qom.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_host.h"
 #include "hw/ide.h"
index 8dde637..5baa0ea 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu-common.h"
+#include "cpu.h"
 #include "alpha_sys.h"
 #include "qemu/log.h"
 #include "sysemu/sysemu.h"
diff --git a/hw/alpha/trace-events b/hw/alpha/trace-events
deleted file mode 100644 (file)
index e44ff01..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/alpha/pci.c
-alpha_pci_iack_write(void) ""
index 883db13..97721b5 100644 (file)
@@ -824,6 +824,7 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
     int i;
 
     dev = qdev_create(NULL, TYPE_TYPHOON_PCI_HOST_BRIDGE);
+    qdev_init_nofail(dev);
 
     s = TYPHOON_PCI_HOST_BRIDGE(dev);
     phb = PCI_HOST_BRIDGE(dev);
@@ -888,7 +889,6 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
                          &s->pchip.reg_mem, &s->pchip.reg_io,
                          0, 64, TYPE_PCI_BUS);
     phb->bus = b;
-    qdev_init_nofail(dev);
 
     /* Host memory as seen from the PCI side, via the IOMMU.  */
     memory_region_init_iommu(&s->pchip.iommu, OBJECT(s), &typhoon_iommu_ops,
index 12764ef..954c9fe 100644 (file)
@@ -16,5 +16,4 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
-obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += ast2400.o palmetto-bmc.o
index 49d3078..bb2a22d 100644 (file)
@@ -132,14 +132,14 @@ typedef struct {
     uint32_t base;
 } BitBandState;
 
-static void bitband_init(Object *obj)
+static int bitband_init(SysBusDevice *dev)
 {
-    BitBandState *s = BITBAND(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    BitBandState *s = BITBAND(dev);
 
-    memory_region_init_io(&s->iomem, obj, &bitband_ops, &s->base,
+    memory_region_init_io(&s->iomem, OBJECT(s), &bitband_ops, &s->base,
                           "bitband", 0x02000000);
     sysbus_init_mmio(dev, &s->iomem);
+    return 0;
 }
 
 static void armv7m_bitband_init(void)
@@ -244,7 +244,9 @@ static Property bitband_properties[] = {
 static void bitband_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = bitband_init;
     dc->props = bitband_properties;
 }
 
@@ -252,7 +254,6 @@ static const TypeInfo bitband_info = {
     .name          = TYPE_BITBAND,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(BitBandState),
-    .instance_init = bitband_init,
     .class_init    = bitband_class_init,
 };
 
index 326fdb3..03f9938 100644 (file)
 #include "exec/address-spaces.h"
 #include "hw/arm/ast2400.h"
 #include "hw/char/serial.h"
-#include "qemu/log.h"
-#include "hw/i2c/aspeed_i2c.h"
 
 #define AST2400_UART_5_BASE      0x00184000
 #define AST2400_IOMEM_SIZE       0x00200000
 #define AST2400_IOMEM_BASE       0x1E600000
-#define AST2400_SMC_BASE         AST2400_IOMEM_BASE /* Legacy SMC */
-#define AST2400_FMC_BASE         0X1E620000
-#define AST2400_SPI_BASE         0X1E630000
 #define AST2400_VIC_BASE         0x1E6C0000
-#define AST2400_SCU_BASE         0x1E6E2000
 #define AST2400_TIMER_BASE       0x1E782000
-#define AST2400_I2C_BASE         0x1E78A000
-
-#define AST2400_FMC_FLASH_BASE   0x20000000
-#define AST2400_SPI_FLASH_BASE   0x30000000
 
 static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
 static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
@@ -75,35 +65,13 @@ static void ast2400_init(Object *obj)
     object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
     object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
     qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
-
-    object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
-    object_property_add_child(obj, "i2c", OBJECT(&s->i2c), NULL);
-    qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());
-
-    object_initialize(&s->scu, sizeof(s->scu), TYPE_ASPEED_SCU);
-    object_property_add_child(obj, "scu", OBJECT(&s->scu), NULL);
-    qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
-    qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
-                         AST2400_A0_SILICON_REV);
-    object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
-                              "hw-strap1", &error_abort);
-    object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
-                              "hw-strap2", &error_abort);
-
-    object_initialize(&s->smc, sizeof(s->smc), "aspeed.smc.fmc");
-    object_property_add_child(obj, "smc", OBJECT(&s->smc), NULL);
-    qdev_set_parent_bus(DEVICE(&s->smc), sysbus_get_default());
-
-    object_initialize(&s->spi, sizeof(s->spi), "aspeed.smc.spi");
-    object_property_add_child(obj, "spi", OBJECT(&s->spi), NULL);
-    qdev_set_parent_bus(DEVICE(&s->spi), sysbus_get_default());
 }
 
 static void ast2400_realize(DeviceState *dev, Error **errp)
 {
     int i;
     AST2400State *s = AST2400(dev);
-    Error *err = NULL, *local_err = NULL;
+    Error *err = NULL;
 
     /* IO space */
     memory_region_init_io(&s->iomem, NULL, &ast2400_io_ops, NULL,
@@ -135,54 +103,12 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
         sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
     }
 
-    /* SCU */
-    object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, AST2400_SCU_BASE);
-
     /* UART - attach an 8250 to the IO space as our UART5 */
     if (serial_hds[0]) {
         qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
         serial_mm_init(&s->iomem, AST2400_UART_5_BASE, 2,
                        uart5, 38400, serial_hds[0], DEVICE_LITTLE_ENDIAN);
     }
-
-    /* I2C */
-    object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, AST2400_I2C_BASE);
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
-                       qdev_get_gpio_in(DEVICE(&s->vic), 12));
-
-    /* SMC */
-    object_property_set_int(OBJECT(&s->smc), 1, "num-cs", &err);
-    object_property_set_bool(OBJECT(&s->smc), true, "realized", &local_err);
-    error_propagate(&err, local_err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 0, AST2400_FMC_BASE);
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 1, AST2400_FMC_FLASH_BASE);
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->smc), 0,
-                       qdev_get_gpio_in(DEVICE(&s->vic), 19));
-
-    /* SPI */
-    object_property_set_int(OBJECT(&s->spi), 1, "num-cs", &err);
-    object_property_set_bool(OBJECT(&s->spi), true, "realized", &local_err);
-    error_propagate(&err, local_err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 0, AST2400_SPI_BASE);
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 1, AST2400_SPI_FLASH_BASE);
 }
 
 static void ast2400_class_init(ObjectClass *oc, void *data)
index 2e641a3..234d518 100644 (file)
@@ -14,7 +14,6 @@
 #include "hw/misc/bcm2835_mbox_defs.h"
 #include "hw/arm/raspi_platform.h"
 #include "sysemu/char.h"
-#include "sysemu/sysemu.h"
 
 /* Peripheral base address on the VC (GPU) system bus */
 #define BCM2835_VC_PERI_BASE 0x7e000000
@@ -107,6 +106,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
     MemoryRegion *ram;
     Error *err = NULL;
     uint32_t ram_size, vcram_size;
+    CharDriverState *chr;
     int n;
 
     obj = object_property_get_link(OBJECT(dev), "ram", &err);
@@ -147,7 +147,6 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
     sysbus_pass_irq(SYS_BUS_DEVICE(s), SYS_BUS_DEVICE(&s->ic));
 
     /* UART0 */
-    qdev_prop_set_chr(DEVICE(s->uart0), "chardev", serial_hds[0]);
     object_property_set_bool(OBJECT(s->uart0), true, "realized", &err);
     if (err) {
         error_propagate(errp, err);
@@ -159,8 +158,17 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
     sysbus_connect_irq(s->uart0, 0,
         qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
                                INTERRUPT_UART));
+
     /* AUX / UART1 */
-    qdev_prop_set_chr(DEVICE(&s->aux), "chardev", serial_hds[1]);
+    /* TODO: don't call qemu_char_get_next_serial() here, instead set
+     * chardev properties for each uart at the board level, once pl011
+     * (uart0) has been updated to avoid qemu_char_get_next_serial()
+     */
+    chr = qemu_char_get_next_serial();
+    if (chr == NULL) {
+        chr = qemu_chr_new("bcm2835.uart1", "null", NULL);
+    }
+    qdev_prop_set_chr(DEVICE(&s->aux), "chardev", chr);
 
     object_property_set_bool(OBJECT(&s->aux), true, "realized", &err);
     if (err) {
@@ -284,6 +292,8 @@ static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data)
     DeviceClass *dc = DEVICE_CLASS(oc);
 
     dc->realize = bcm2835_peripherals_realize;
+    /* Reason: realize() method uses qemu_char_get_next_serial() */
+    dc->cannot_instantiate_with_device_add_yet = true;
 }
 
 static const TypeInfo bcm2835_peripherals_type_info = {
index 1b913a4..5876945 100644 (file)
@@ -14,7 +14,6 @@
 #include "hw/arm/linux-boot-if.h"
 #include "sysemu/kvm.h"
 #include "sysemu/sysemu.h"
-#include "sysemu/numa.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
 #include "elf.h"
@@ -406,9 +405,6 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
     void *fdt = NULL;
     int size, rc;
     uint32_t acells, scells;
-    char *nodename;
-    unsigned int i;
-    hwaddr mem_base, mem_len;
 
     if (binfo->dtb_filename) {
         char *filename;
@@ -460,39 +456,12 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
         goto fail;
     }
 
-    if (nb_numa_nodes > 0) {
-        /*
-         * Turn the /memory node created before into a NOP node, then create
-         * /memory@addr nodes for all numa nodes respectively.
-         */
-        qemu_fdt_nop_node(fdt, "/memory");
-        mem_base = binfo->loader_start;
-        for (i = 0; i < nb_numa_nodes; i++) {
-            mem_len = numa_info[i].node_mem;
-            nodename = g_strdup_printf("/memory@%" PRIx64, mem_base);
-            qemu_fdt_add_subnode(fdt, nodename);
-            qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
-            rc = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
-                                              acells, mem_base,
-                                              scells, mem_len);
-            if (rc < 0) {
-                fprintf(stderr, "couldn't set %s/reg for node %d\n", nodename,
-                        i);
-                goto fail;
-            }
-
-            qemu_fdt_setprop_cell(fdt, nodename, "numa-node-id", i);
-            mem_base += mem_len;
-            g_free(nodename);
-        }
-    } else {
-        rc = qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg",
-                                          acells, binfo->loader_start,
-                                          scells, binfo->ram_size);
-        if (rc < 0) {
-            fprintf(stderr, "couldn't set /memory/reg\n");
-            goto fail;
-        }
+    rc = qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg",
+                                      acells, binfo->loader_start,
+                                      scells, binfo->ram_size);
+    if (rc < 0) {
+        fprintf(stderr, "couldn't set /memory/reg\n");
+        goto fail;
     }
 
     if (binfo->kernel_cmdline && *binfo->kernel_cmdline) {
index 2e69531..8bb308a 100644 (file)
@@ -18,7 +18,6 @@
 #include "hw/block/flash.h"
 #include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
-#include "qom/cpu.h"
 
 static struct arm_boot_info collie_binfo = {
     .loader_start = SA_SDCS0,
index d60ea39..e0f9730 100644 (file)
@@ -23,7 +23,6 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/arm/digic.h"
-#include "sysemu/sysemu.h"
 
 #define DIGIC4_TIMER_BASE(n)    (0xc0210000 + (n) * 0x100)
 
@@ -85,7 +84,6 @@ static void digic_realize(DeviceState *dev, Error **errp)
         sysbus_mmio_map(sbd, 0, DIGIC4_TIMER_BASE(i));
     }
 
-    qdev_prop_set_chr(DEVICE(&s->uart), "chardev", serial_hds[0]);
     object_property_set_bool(OBJECT(&s->uart), true, "realized", &err);
     if (err != NULL) {
         error_propagate(errp, err);
index b4e358d..2f878b9 100644 (file)
@@ -51,7 +51,7 @@ static void fsl_imx25_init(Object *obj)
     }
 
     for (i = 0; i < FSL_IMX25_NUM_GPTS; i++) {
-        object_initialize(&s->gpt[i], sizeof(s->gpt[i]), TYPE_IMX25_GPT);
+        object_initialize(&s->gpt[i], sizeof(s->gpt[i]), TYPE_IMX_GPT);
         qdev_set_parent_bus(DEVICE(&s->gpt[i]), sysbus_get_default());
     }
 
@@ -191,7 +191,6 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
     }
 
     qdev_set_nic_properties(DEVICE(&s->fec), &nd_table[0]);
-
     object_property_set_bool(OBJECT(&s->fec), true, "realized", &err);
     if (err) {
         error_propagate(errp, err);
@@ -249,16 +248,16 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
     }
 
     /* initialize 2 x 16 KB ROM */
-    memory_region_init_rom(&s->rom[0], NULL,
-                           "imx25.rom0", FSL_IMX25_ROM0_SIZE, &err);
+    memory_region_init_rom_device(&s->rom[0], NULL, NULL, NULL,
+                                  "imx25.rom0", FSL_IMX25_ROM0_SIZE, &err);
     if (err) {
         error_propagate(errp, err);
         return;
     }
     memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM0_ADDR,
                                 &s->rom[0]);
-    memory_region_init_rom(&s->rom[1], NULL,
-                           "imx25.rom1", FSL_IMX25_ROM1_SIZE, &err);
+    memory_region_init_rom_device(&s->rom[1], NULL, NULL, NULL,
+                                  "imx25.rom1", FSL_IMX25_ROM1_SIZE, &err);
     if (err) {
         error_propagate(errp, err);
         return;
index fe204ac..31a3a87 100644 (file)
@@ -47,7 +47,7 @@ static void fsl_imx31_init(Object *obj)
         qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus_get_default());
     }
 
-    object_initialize(&s->gpt, sizeof(s->gpt), TYPE_IMX31_GPT);
+    object_initialize(&s->gpt, sizeof(s->gpt), TYPE_IMX_GPT);
     qdev_set_parent_bus(DEVICE(&s->gpt), sysbus_get_default());
 
     for (i = 0; i < FSL_IMX31_NUM_EPITS; i++) {
@@ -219,8 +219,9 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp)
     }
 
     /* On a real system, the first 16k is a `secure boot rom' */
-    memory_region_init_rom(&s->secure_rom, NULL, "imx31.secure_rom",
-                           FSL_IMX31_SECURE_ROM_SIZE, &err);
+    memory_region_init_rom_device(&s->secure_rom, NULL, NULL, NULL,
+                                  "imx31.secure_rom",
+                                  FSL_IMX31_SECURE_ROM_SIZE, &err);
     if (err) {
         error_propagate(errp, err);
         return;
@@ -229,8 +230,8 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp)
                                 &s->secure_rom);
 
     /* There is also a 16k ROM */
-    memory_region_init_rom(&s->rom, NULL, "imx31.rom",
-                           FSL_IMX31_ROM_SIZE, &err);
+    memory_region_init_rom_device(&s->rom, NULL, NULL, NULL, "imx31.rom",
+                                  FSL_IMX31_ROM_SIZE, &err);
     if (err) {
         error_propagate(errp, err);
         return;
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
deleted file mode 100644 (file)
index 6a1bf26..0000000
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
- *
- * i.MX6 SOC emulation.
- *
- * Based on hw/arm/fsl-imx31.c
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "hw/arm/fsl-imx6.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/char.h"
-#include "qemu/error-report.h"
-
-#define NAME_SIZE 20
-
-static void fsl_imx6_init(Object *obj)
-{
-    FslIMX6State *s = FSL_IMX6(obj);
-    char name[NAME_SIZE];
-    int i;
-
-    if (smp_cpus > FSL_IMX6_NUM_CPUS) {
-        error_report("%s: Only %d CPUs are supported (%d requested)",
-                     TYPE_FSL_IMX6, FSL_IMX6_NUM_CPUS, smp_cpus);
-        exit(1);
-    }
-
-    for (i = 0; i < smp_cpus; i++) {
-        object_initialize(&s->cpu[i], sizeof(s->cpu[i]),
-                          "cortex-a9-" TYPE_ARM_CPU);
-        snprintf(name, NAME_SIZE, "cpu%d", i);
-        object_property_add_child(obj, name, OBJECT(&s->cpu[i]), NULL);
-    }
-
-    object_initialize(&s->a9mpcore, sizeof(s->a9mpcore), TYPE_A9MPCORE_PRIV);
-    qdev_set_parent_bus(DEVICE(&s->a9mpcore), sysbus_get_default());
-    object_property_add_child(obj, "a9mpcore", OBJECT(&s->a9mpcore), NULL);
-
-    object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX6_CCM);
-    qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
-    object_property_add_child(obj, "ccm", OBJECT(&s->ccm), NULL);
-
-    object_initialize(&s->src, sizeof(s->src), TYPE_IMX6_SRC);
-    qdev_set_parent_bus(DEVICE(&s->src), sysbus_get_default());
-    object_property_add_child(obj, "src", OBJECT(&s->src), NULL);
-
-    for (i = 0; i < FSL_IMX6_NUM_UARTS; i++) {
-        object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_IMX_SERIAL);
-        qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus_get_default());
-        snprintf(name, NAME_SIZE, "uart%d", i + 1);
-        object_property_add_child(obj, name, OBJECT(&s->uart[i]), NULL);
-    }
-
-    object_initialize(&s->gpt, sizeof(s->gpt), TYPE_IMX6_GPT);
-    qdev_set_parent_bus(DEVICE(&s->gpt), sysbus_get_default());
-    object_property_add_child(obj, "gpt", OBJECT(&s->gpt), NULL);
-
-    for (i = 0; i < FSL_IMX6_NUM_EPITS; i++) {
-        object_initialize(&s->epit[i], sizeof(s->epit[i]), TYPE_IMX_EPIT);
-        qdev_set_parent_bus(DEVICE(&s->epit[i]), sysbus_get_default());
-        snprintf(name, NAME_SIZE, "epit%d", i + 1);
-        object_property_add_child(obj, name, OBJECT(&s->epit[i]), NULL);
-    }
-
-    for (i = 0; i < FSL_IMX6_NUM_I2CS; i++) {
-        object_initialize(&s->i2c[i], sizeof(s->i2c[i]), TYPE_IMX_I2C);
-        qdev_set_parent_bus(DEVICE(&s->i2c[i]), sysbus_get_default());
-        snprintf(name, NAME_SIZE, "i2c%d", i + 1);
-        object_property_add_child(obj, name, OBJECT(&s->i2c[i]), NULL);
-    }
-
-    for (i = 0; i < FSL_IMX6_NUM_GPIOS; i++) {
-        object_initialize(&s->gpio[i], sizeof(s->gpio[i]), TYPE_IMX_GPIO);
-        qdev_set_parent_bus(DEVICE(&s->gpio[i]), sysbus_get_default());
-        snprintf(name, NAME_SIZE, "gpio%d", i + 1);
-        object_property_add_child(obj, name, OBJECT(&s->gpio[i]), NULL);
-    }
-
-    for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
-        object_initialize(&s->esdhc[i], sizeof(s->esdhc[i]), TYPE_SYSBUS_SDHCI);
-        qdev_set_parent_bus(DEVICE(&s->esdhc[i]), sysbus_get_default());
-        snprintf(name, NAME_SIZE, "sdhc%d", i + 1);
-        object_property_add_child(obj, name, OBJECT(&s->esdhc[i]), NULL);
-    }
-
-    for (i = 0; i < FSL_IMX6_NUM_ECSPIS; i++) {
-        object_initialize(&s->spi[i], sizeof(s->spi[i]), TYPE_IMX_SPI);
-        qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
-        snprintf(name, NAME_SIZE, "spi%d", i + 1);
-        object_property_add_child(obj, name, OBJECT(&s->spi[i]), NULL);
-    }
-
-    object_initialize(&s->eth, sizeof(s->eth), TYPE_IMX_ENET);
-    qdev_set_parent_bus(DEVICE(&s->eth), sysbus_get_default());
-    object_property_add_child(obj, "eth", OBJECT(&s->eth), NULL);
-}
-
-static void fsl_imx6_realize(DeviceState *dev, Error **errp)
-{
-    FslIMX6State *s = FSL_IMX6(dev);
-    uint16_t i;
-    Error *err = NULL;
-
-    for (i = 0; i < smp_cpus; i++) {
-
-        /* On uniprocessor, the CBAR is set to 0 */
-        if (smp_cpus > 1) {
-            object_property_set_int(OBJECT(&s->cpu[i]), FSL_IMX6_A9MPCORE_ADDR,
-                                    "reset-cbar", &error_abort);
-        }
-
-        /* All CPU but CPU 0 start in power off mode */
-        if (i) {
-            object_property_set_bool(OBJECT(&s->cpu[i]), true,
-                                     "start-powered-off", &error_abort);
-        }
-
-        object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err);
-        if (err) {
-            error_propagate(errp, err);
-            return;
-        }
-    }
-
-    object_property_set_int(OBJECT(&s->a9mpcore), smp_cpus, "num-cpu",
-                            &error_abort);
-
-    object_property_set_int(OBJECT(&s->a9mpcore),
-                            FSL_IMX6_MAX_IRQ + GIC_INTERNAL, "num-irq",
-                            &error_abort);
-
-    object_property_set_bool(OBJECT(&s->a9mpcore), true, "realized", &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->a9mpcore), 0, FSL_IMX6_A9MPCORE_ADDR);
-
-    for (i = 0; i < smp_cpus; i++) {
-        sysbus_connect_irq(SYS_BUS_DEVICE(&s->a9mpcore), i,
-                           qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_IRQ));
-        sysbus_connect_irq(SYS_BUS_DEVICE(&s->a9mpcore), i + smp_cpus,
-                           qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_FIQ));
-    }
-
-    object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX6_CCM_ADDR);
-
-    object_property_set_bool(OBJECT(&s->src), true, "realized", &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX6_SRC_ADDR);
-
-    /* Initialize all UARTs */
-    for (i = 0; i < FSL_IMX6_NUM_UARTS; i++) {
-        static const struct {
-            hwaddr addr;
-            unsigned int irq;
-        } serial_table[FSL_IMX6_NUM_UARTS] = {
-            { FSL_IMX6_UART1_ADDR, FSL_IMX6_UART1_IRQ },
-            { FSL_IMX6_UART2_ADDR, FSL_IMX6_UART2_IRQ },
-            { FSL_IMX6_UART3_ADDR, FSL_IMX6_UART3_IRQ },
-            { FSL_IMX6_UART4_ADDR, FSL_IMX6_UART4_IRQ },
-            { FSL_IMX6_UART5_ADDR, FSL_IMX6_UART5_IRQ },
-        };
-
-        if (i < MAX_SERIAL_PORTS) {
-            CharDriverState *chr;
-
-            chr = serial_hds[i];
-
-            if (!chr) {
-                char *label = g_strdup_printf("imx6.uart%d", i + 1);
-                chr = qemu_chr_new(label, "null", NULL);
-                g_free(label);
-                serial_hds[i] = chr;
-            }
-
-            qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
-        }
-
-        object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err);
-        if (err) {
-            error_propagate(errp, err);
-            return;
-        }
-
-        sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
-        sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
-                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
-                                            serial_table[i].irq));
-    }
-
-    s->gpt.ccm = IMX_CCM(&s->ccm);
-
-    object_property_set_bool(OBJECT(&s->gpt), true, "realized", &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt), 0, FSL_IMX6_GPT_ADDR);
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), 0,
-                       qdev_get_gpio_in(DEVICE(&s->a9mpcore),
-                                        FSL_IMX6_GPT_IRQ));
-
-    /* Initialize all EPIT timers */
-    for (i = 0; i < FSL_IMX6_NUM_EPITS; i++) {
-        static const struct {
-            hwaddr addr;
-            unsigned int irq;
-        } epit_table[FSL_IMX6_NUM_EPITS] = {
-            { FSL_IMX6_EPIT1_ADDR, FSL_IMX6_EPIT1_IRQ },
-            { FSL_IMX6_EPIT2_ADDR, FSL_IMX6_EPIT2_IRQ },
-        };
-
-        s->epit[i].ccm = IMX_CCM(&s->ccm);
-
-        object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
-        if (err) {
-            error_propagate(errp, err);
-            return;
-        }
-
-        sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr);
-        sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
-                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
-                                            epit_table[i].irq));
-    }
-
-    /* Initialize all I2C */
-    for (i = 0; i < FSL_IMX6_NUM_I2CS; i++) {
-        static const struct {
-            hwaddr addr;
-            unsigned int irq;
-        } i2c_table[FSL_IMX6_NUM_I2CS] = {
-            { FSL_IMX6_I2C1_ADDR, FSL_IMX6_I2C1_IRQ },
-            { FSL_IMX6_I2C2_ADDR, FSL_IMX6_I2C2_IRQ },
-            { FSL_IMX6_I2C3_ADDR, FSL_IMX6_I2C3_IRQ }
-        };
-
-        object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err);
-        if (err) {
-            error_propagate(errp, err);
-            return;
-        }
-
-        sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
-        sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
-                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
-                                            i2c_table[i].irq));
-    }
-
-    /* Initialize all GPIOs */
-    for (i = 0; i < FSL_IMX6_NUM_GPIOS; i++) {
-        static const struct {
-            hwaddr addr;
-            unsigned int irq_low;
-            unsigned int irq_high;
-        } gpio_table[FSL_IMX6_NUM_GPIOS] = {
-            {
-                FSL_IMX6_GPIO1_ADDR,
-                FSL_IMX6_GPIO1_LOW_IRQ,
-                FSL_IMX6_GPIO1_HIGH_IRQ
-            },
-            {
-                FSL_IMX6_GPIO2_ADDR,
-                FSL_IMX6_GPIO2_LOW_IRQ,
-                FSL_IMX6_GPIO2_HIGH_IRQ
-            },
-            {
-                FSL_IMX6_GPIO3_ADDR,
-                FSL_IMX6_GPIO3_LOW_IRQ,
-                FSL_IMX6_GPIO3_HIGH_IRQ
-            },
-            {
-                FSL_IMX6_GPIO4_ADDR,
-                FSL_IMX6_GPIO4_LOW_IRQ,
-                FSL_IMX6_GPIO4_HIGH_IRQ
-            },
-            {
-                FSL_IMX6_GPIO5_ADDR,
-                FSL_IMX6_GPIO5_LOW_IRQ,
-                FSL_IMX6_GPIO5_HIGH_IRQ
-            },
-            {
-                FSL_IMX6_GPIO6_ADDR,
-                FSL_IMX6_GPIO6_LOW_IRQ,
-                FSL_IMX6_GPIO6_HIGH_IRQ
-            },
-            {
-                FSL_IMX6_GPIO7_ADDR,
-                FSL_IMX6_GPIO7_LOW_IRQ,
-                FSL_IMX6_GPIO7_HIGH_IRQ
-            },
-        };
-
-        object_property_set_bool(OBJECT(&s->gpio[i]), true, "has-edge-sel",
-                                 &error_abort);
-        object_property_set_bool(OBJECT(&s->gpio[i]), true, "has-upper-pin-irq",
-                                 &error_abort);
-        object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized", &err);
-        if (err) {
-            error_propagate(errp, err);
-            return;
-        }
-
-        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr);
-        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
-                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
-                                            gpio_table[i].irq_low));
-        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
-                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
-                                            gpio_table[i].irq_high));
-    }
-
-    /* Initialize all SDHC */
-    for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
-        static const struct {
-            hwaddr addr;
-            unsigned int irq;
-        } esdhc_table[FSL_IMX6_NUM_ESDHCS] = {
-            { FSL_IMX6_uSDHC1_ADDR, FSL_IMX6_uSDHC1_IRQ },
-            { FSL_IMX6_uSDHC2_ADDR, FSL_IMX6_uSDHC2_IRQ },
-            { FSL_IMX6_uSDHC3_ADDR, FSL_IMX6_uSDHC3_IRQ },
-            { FSL_IMX6_uSDHC4_ADDR, FSL_IMX6_uSDHC4_IRQ },
-        };
-
-        object_property_set_bool(OBJECT(&s->esdhc[i]), true, "realized", &err);
-        if (err) {
-            error_propagate(errp, err);
-            return;
-        }
-        sysbus_mmio_map(SYS_BUS_DEVICE(&s->esdhc[i]), 0, esdhc_table[i].addr);
-        sysbus_connect_irq(SYS_BUS_DEVICE(&s->esdhc[i]), 0,
-                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
-                                            esdhc_table[i].irq));
-    }
-
-    /* Initialize all ECSPI */
-    for (i = 0; i < FSL_IMX6_NUM_ECSPIS; i++) {
-        static const struct {
-            hwaddr addr;
-            unsigned int irq;
-        } spi_table[FSL_IMX6_NUM_ECSPIS] = {
-            { FSL_IMX6_eCSPI1_ADDR, FSL_IMX6_ECSPI1_IRQ },
-            { FSL_IMX6_eCSPI2_ADDR, FSL_IMX6_ECSPI2_IRQ },
-            { FSL_IMX6_eCSPI3_ADDR, FSL_IMX6_ECSPI3_IRQ },
-            { FSL_IMX6_eCSPI4_ADDR, FSL_IMX6_ECSPI4_IRQ },
-            { FSL_IMX6_eCSPI5_ADDR, FSL_IMX6_ECSPI5_IRQ },
-        };
-
-        /* Initialize the SPI */
-        object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", &err);
-        if (err) {
-            error_propagate(errp, err);
-            return;
-        }
-
-        sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, spi_table[i].addr);
-        sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
-                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
-                                            spi_table[i].irq));
-    }
-
-    object_property_set_bool(OBJECT(&s->eth), true, "realized", &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth), 0, FSL_IMX6_ENET_ADDR);
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth), 0,
-                       qdev_get_gpio_in(DEVICE(&s->a9mpcore),
-                                        FSL_IMX6_ENET_MAC_IRQ));
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth), 1,
-                       qdev_get_gpio_in(DEVICE(&s->a9mpcore),
-                                        FSL_IMX6_ENET_MAC_1588_IRQ));
-
-    /* ROM memory */
-    memory_region_init_rom(&s->rom, NULL, "imx6.rom",
-                           FSL_IMX6_ROM_SIZE, &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    memory_region_add_subregion(get_system_memory(), FSL_IMX6_ROM_ADDR,
-                                &s->rom);
-
-    /* CAAM memory */
-    memory_region_init_rom(&s->caam, NULL, "imx6.caam",
-                           FSL_IMX6_CAAM_MEM_SIZE, &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    memory_region_add_subregion(get_system_memory(), FSL_IMX6_CAAM_MEM_ADDR,
-                                &s->caam);
-
-    /* OCRAM memory */
-    memory_region_init_ram(&s->ocram, NULL, "imx6.ocram", FSL_IMX6_OCRAM_SIZE,
-                           &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    memory_region_add_subregion(get_system_memory(), FSL_IMX6_OCRAM_ADDR,
-                                &s->ocram);
-    vmstate_register_ram_global(&s->ocram);
-
-    /* internal OCRAM (256 KB) is aliased over 1 MB */
-    memory_region_init_alias(&s->ocram_alias, NULL, "imx6.ocram_alias",
-                             &s->ocram, 0, FSL_IMX6_OCRAM_ALIAS_SIZE);
-    memory_region_add_subregion(get_system_memory(), FSL_IMX6_OCRAM_ALIAS_ADDR,
-                                &s->ocram_alias);
-}
-
-static void fsl_imx6_class_init(ObjectClass *oc, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(oc);
-
-    dc->realize = fsl_imx6_realize;
-
-    /*
-     * Reason: creates an ARM CPU, thus use after free(), see
-     * arm_cpu_class_init()
-     */
-    dc->cannot_destroy_with_object_finalize_yet = true;
-    dc->desc = "i.MX6 SOC";
-}
-
-static const TypeInfo fsl_imx6_type_info = {
-    .name = TYPE_FSL_IMX6,
-    .parent = TYPE_DEVICE,
-    .instance_size = sizeof(FslIMX6State),
-    .instance_init = fsl_imx6_init,
-    .class_init = fsl_imx6_class_init,
-};
-
-static void fsl_imx6_register_types(void)
-{
-    type_register_static(&fsl_imx6_type_info);
-}
-
-type_init(fsl_imx6_register_types)
index 80e5fd4..d9930c0 100644 (file)
@@ -30,7 +30,6 @@
 #include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
 #include "qemu/error-report.h"
-#include "hw/char/pl011.h"
 
 #define SMP_BOOT_ADDR           0x100
 #define SMP_BOOT_REG            0x40
@@ -169,20 +168,23 @@ static void highbank_regs_reset(DeviceState *dev)
     s->regs[0x43] = 0x05F40121;
 }
 
-static void highbank_regs_init(Object *obj)
+static int highbank_regs_init(SysBusDevice *dev)
 {
-    HighbankRegsState *s = HIGHBANK_REGISTERS(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    HighbankRegsState *s = HIGHBANK_REGISTERS(dev);
 
-    memory_region_init_io(&s->iomem, obj, &hb_mem_ops, s->regs,
+    memory_region_init_io(&s->iomem, OBJECT(s), &hb_mem_ops, s->regs,
                           "highbank_regs", 0x1000);
     sysbus_init_mmio(dev, &s->iomem);
+
+    return 0;
 }
 
 static void highbank_regs_class_init(ObjectClass *klass, void *data)
 {
+    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
+    sbc->init = highbank_regs_init;
     dc->desc = "Calxeda Highbank registers";
     dc->vmsd = &vmstate_highbank_regs;
     dc->reset = highbank_regs_reset;
@@ -192,7 +194,6 @@ static const TypeInfo highbank_regs_info = {
     .name          = TYPE_HIGHBANK_REGISTERS,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(HighbankRegsState),
-    .instance_init = highbank_regs_init,
     .class_init    = highbank_regs_class_init,
 };
 
@@ -327,7 +328,7 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
     busdev = SYS_BUS_DEVICE(dev);
     sysbus_mmio_map(busdev, 0, 0xfff34000);
     sysbus_connect_irq(busdev, 0, pic[18]);
-    pl011_create(0xfff36000, pic[20], serial_hds[0]);
+    sysbus_create_simple("pl011", 0xfff36000, pic[20]);
 
     dev = qdev_create(NULL, "highbank-regs");
     qdev_init_nofail(dev);
index 96dc150..e31bca6 100644 (file)
@@ -20,7 +20,6 @@
 #include "exec/address-spaces.h"
 #include "sysemu/sysemu.h"
 #include "qemu/error-report.h"
-#include "hw/char/pl011.h"
 
 #define TYPE_INTEGRATOR_CM "integrator_core"
 #define INTEGRATOR_CM(obj) \
@@ -243,10 +242,9 @@ static const MemoryRegionOps integratorcm_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void integratorcm_init(Object *obj)
+static int integratorcm_init(SysBusDevice *dev)
 {
-    IntegratorCMState *s = INTEGRATOR_CM(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    IntegratorCMState *s = INTEGRATOR_CM(dev);
 
     s->cm_osc = 0x01000048;
     /* ??? What should the high bits of this value be?  */
@@ -271,16 +269,17 @@ static void integratorcm_init(Object *obj)
     s->cm_init = 0x00000112;
     s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
                                    1000);
-    memory_region_init_ram(&s->flash, obj, "integrator.flash", 0x100000,
+    memory_region_init_ram(&s->flash, OBJECT(s), "integrator.flash", 0x100000,
                            &error_fatal);
     vmstate_register_ram_global(&s->flash);
 
-    memory_region_init_io(&s->iomem, obj, &integratorcm_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &integratorcm_ops, s,
                           "integratorcm", 0x00800000);
     sysbus_init_mmio(dev, &s->iomem);
 
     integratorcm_do_remap(s);
     /* ??? Save/restore.  */
+    return 0;
 }
 
 /* Integrator/CP hardware emulation.  */
@@ -395,18 +394,18 @@ static const MemoryRegionOps icp_pic_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void icp_pic_init(Object *obj)
+static int icp_pic_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    icp_pic_state *s = INTEGRATOR_PIC(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    icp_pic_state *s = INTEGRATOR_PIC(dev);
 
     qdev_init_gpio_in(dev, icp_pic_set_irq, 32);
     sysbus_init_irq(sbd, &s->parent_irq);
     sysbus_init_irq(sbd, &s->parent_fiq);
-    memory_region_init_io(&s->iomem, obj, &icp_pic_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &icp_pic_ops, s,
                           "icp-pic", 0x00800000);
     sysbus_init_mmio(sbd, &s->iomem);
+    return 0;
 }
 
 /* CP control registers.  */
@@ -589,8 +588,8 @@ static void integratorcp_init(MachineState *machine)
     sysbus_create_varargs("integrator_pit", 0x13000000,
                           pic[5], pic[6], pic[7], NULL);
     sysbus_create_simple("pl031", 0x15000000, pic[8]);
-    pl011_create(0x16000000, pic[1], serial_hds[0]);
-    pl011_create(0x17000000, pic[2], serial_hds[1]);
+    sysbus_create_simple("pl011", 0x16000000, pic[1]);
+    sysbus_create_simple("pl011", 0x17000000, pic[2]);
     icp = sysbus_create_simple(TYPE_ICP_CONTROL_REGS, 0xcb000000,
                                qdev_get_gpio_in(sic, 3));
     sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]);
@@ -631,7 +630,9 @@ static Property core_properties[] = {
 static void core_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = integratorcm_init;
     dc->props = core_properties;
 }
 
@@ -639,15 +640,21 @@ static const TypeInfo core_info = {
     .name          = TYPE_INTEGRATOR_CM,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(IntegratorCMState),
-    .instance_init = integratorcm_init,
     .class_init    = core_class_init,
 };
 
+static void icp_pic_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = icp_pic_init;
+}
+
 static const TypeInfo icp_pic_info = {
     .name          = TYPE_INTEGRATOR_PIC,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(icp_pic_state),
-    .instance_init = icp_pic_init,
+    .class_init    = icp_pic_class_init,
 };
 
 static const TypeInfo icp_ctrl_regs_info = {
index cc50ace..7a4cc07 100644 (file)
@@ -378,7 +378,7 @@ static void eth_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_mv88w8618_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = eth_receive,
     .cleanup = eth_cleanup,
index fea911e..5382505 100644 (file)
@@ -20,9 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "cpu.h"
 #include "qemu/cutils.h"
-#include "qemu/bswap.h"
 #include "sysemu/sysemu.h"
 #include "hw/arm/omap.h"
 #include "hw/arm/arm.h"
@@ -37,7 +35,6 @@
 #include "hw/loader.h"
 #include "sysemu/block-backend.h"
 #include "hw/sysbus.h"
-#include "qemu/log.h"
 #include "exec/address-spaces.h"
 
 /* Nokia N8x0 support */
@@ -1351,7 +1348,7 @@ static void n8x0_init(MachineState *machine,
     n8x0_dss_setup(s);
     n8x0_cbus_setup(s);
     n8x0_uart_setup(s);
-    if (machine_usb(machine)) {
+    if (usb_enabled()) {
         n8x0_usb_setup(s);
     }
 
@@ -1367,7 +1364,7 @@ static void n8x0_init(MachineState *machine,
 
     if (option_rom[0].name &&
         (machine->boot_order[0] == 'n' || !machine->kernel_filename)) {
-        uint8_t *nolo_tags = g_new(uint8_t, 0x10000);
+        uint8_t nolo_tags[0x10000];
         /* No, wait, better start at the ROM.  */
         s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
 
@@ -1386,7 +1383,6 @@ static void n8x0_init(MachineState *machine,
 
         n800_setup_nolo_tags(nolo_tags);
         cpu_physical_memory_write(OMAP2_SRAM_BASE, nolo_tags, 0x10000);
-        g_free(nolo_tags);
     }
 }
 
index 54e29a8..89ebd92 100644 (file)
@@ -17,9 +17,6 @@
 #include "hw/arm/arm.h"
 #include "hw/arm/ast2400.h"
 #include "hw/boards.h"
-#include "qemu/log.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
 
 static struct arm_boot_info palmetto_bmc_binfo = {
     .loader_start = AST2400_SDRAM_BASE,
@@ -32,32 +29,6 @@ typedef struct PalmettoBMCState {
     MemoryRegion ram;
 } PalmettoBMCState;
 
-static void palmetto_bmc_init_flashes(AspeedSMCState *s, const char *flashtype,
-                                      Error **errp)
-{
-    int i ;
-
-    for (i = 0; i < s->num_cs; ++i) {
-        AspeedSMCFlash *fl = &s->flashes[i];
-        DriveInfo *dinfo = drive_get_next(IF_MTD);
-        qemu_irq cs_line;
-
-        /*
-         * FIXME: check that we are not using a flash module exceeding
-         * the controller segment size
-         */
-        fl->flash = ssi_create_slave_no_init(s->spi, flashtype);
-        if (dinfo) {
-            qdev_prop_set_drive(fl->flash, "drive", blk_by_legacy_dinfo(dinfo),
-                                errp);
-        }
-        qdev_init_nofail(fl->flash);
-
-        cs_line = qdev_get_gpio_in_named(fl->flash, SSI_GPIO_CS, 0);
-        sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line);
-    }
-}
-
 static void palmetto_bmc_init(MachineState *machine)
 {
     PalmettoBMCState *bmc;
@@ -72,14 +43,9 @@ static void palmetto_bmc_init(MachineState *machine)
                                 &bmc->ram);
     object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram),
                                    &error_abort);
-    object_property_set_int(OBJECT(&bmc->soc), 0x120CE416, "hw-strap1",
-                            &error_abort);
     object_property_set_bool(OBJECT(&bmc->soc), true, "realized",
                              &error_abort);
 
-    palmetto_bmc_init_flashes(&bmc->soc.smc, "n25q256a", &error_abort);
-    palmetto_bmc_init_flashes(&bmc->soc.spi, "mx25l25635e", &error_abort);
-
     palmetto_bmc_binfo.kernel_filename = machine->kernel_filename;
     palmetto_bmc_binfo.initrd_filename = machine->initrd_filename;
     palmetto_bmc_binfo.kernel_cmdline = machine->kernel_cmdline;
index cb55704..1a8c360 100644 (file)
@@ -1107,10 +1107,9 @@ static const MemoryRegionOps pxa2xx_rtc_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void pxa2xx_rtc_init(Object *obj)
+static int pxa2xx_rtc_init(SysBusDevice *dev)
 {
-    PXA2xxRTCState *s = PXA2XX_RTC(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    PXA2xxRTCState *s = PXA2XX_RTC(dev);
     struct tm tm;
     int wom;
 
@@ -1139,9 +1138,11 @@ static void pxa2xx_rtc_init(Object *obj)
 
     sysbus_init_irq(dev, &s->rtc_irq);
 
-    memory_region_init_io(&s->iomem, obj, &pxa2xx_rtc_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &pxa2xx_rtc_ops, s,
                           "pxa2xx-rtc", 0x10000);
     sysbus_init_mmio(dev, &s->iomem);
+
+    return 0;
 }
 
 static void pxa2xx_rtc_pre_save(void *opaque)
@@ -1194,7 +1195,9 @@ static const VMStateDescription vmstate_pxa2xx_rtc_regs = {
 static void pxa2xx_rtc_sysbus_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = pxa2xx_rtc_init;
     dc->desc = "PXA2xx RTC Controller";
     dc->vmsd = &vmstate_pxa2xx_rtc_regs;
 }
@@ -1203,7 +1206,6 @@ static const TypeInfo pxa2xx_rtc_sysbus_info = {
     .name          = TYPE_PXA2XX_RTC,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(PXA2xxRTCState),
-    .instance_init = pxa2xx_rtc_init,
     .class_init    = pxa2xx_rtc_sysbus_class_init,
 };
 
@@ -1499,18 +1501,19 @@ PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
     return s;
 }
 
-static void pxa2xx_i2c_initfn(Object *obj)
+static int pxa2xx_i2c_initfn(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    PXA2xxI2CState *s = PXA2XX_I2C(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    PXA2xxI2CState *s = PXA2XX_I2C(dev);
 
     s->bus = i2c_init_bus(dev, "i2c");
 
-    memory_region_init_io(&s->iomem, obj, &pxa2xx_i2c_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &pxa2xx_i2c_ops, s,
                           "pxa2xx-i2c", s->region_size);
     sysbus_init_mmio(sbd, &s->iomem);
     sysbus_init_irq(sbd, &s->irq);
+
+    return 0;
 }
 
 I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s)
@@ -1527,7 +1530,9 @@ static Property pxa2xx_i2c_properties[] = {
 static void pxa2xx_i2c_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = pxa2xx_i2c_initfn;
     dc->desc = "PXA2xx I2C Bus Controller";
     dc->vmsd = &vmstate_pxa2xx_i2c;
     dc->props = pxa2xx_i2c_properties;
@@ -1537,7 +1542,6 @@ static const TypeInfo pxa2xx_i2c_info = {
     .name          = TYPE_PXA2XX_I2C,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(PXA2xxI2CState),
-    .instance_init = pxa2xx_i2c_initfn,
     .class_init    = pxa2xx_i2c_class_init,
 };
 
@@ -2165,8 +2169,10 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
         s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
     }
 
-    sysbus_create_simple("sysbus-ohci", 0x4c000000,
-                         qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
+    if (usb_enabled()) {
+        sysbus_create_simple("sysbus-ohci", 0x4c000000,
+                        qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
+    }
 
     s->pcmcia[0] = pxa2xx_pcmcia_init(address_space, 0x20000000);
     s->pcmcia[1] = pxa2xx_pcmcia_init(address_space, 0x30000000);
@@ -2296,8 +2302,10 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
         s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
     }
 
-    sysbus_create_simple("sysbus-ohci", 0x4c000000,
-                         qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
+    if (usb_enabled()) {
+        sysbus_create_simple("sysbus-ohci", 0x4c000000,
+                        qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
+    }
 
     s->pcmcia[0] = pxa2xx_pcmcia_init(address_space, 0x20000000);
     s->pcmcia[1] = pxa2xx_pcmcia_init(address_space, 0x30000000);
index 576a8eb..67e7e70 100644 (file)
@@ -8,11 +8,9 @@
  */
 
 #include "qemu/osdep.h"
-#include "cpu.h"
 #include "hw/hw.h"
 #include "hw/sysbus.h"
 #include "hw/arm/pxa.h"
-#include "qemu/log.h"
 
 #define PXA2XX_GPIO_BANKS      4
 
index b516ced..7e51532 100644 (file)
@@ -310,10 +310,17 @@ static VMStateDescription vmstate_pxa2xx_pic_regs = {
     },
 };
 
+static int pxa2xx_pic_initfn(SysBusDevice *dev)
+{
+    return 0;
+}
+
 static void pxa2xx_pic_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = pxa2xx_pic_initfn;
     dc->desc = "PXA2xx PIC";
     dc->vmsd = &vmstate_pxa2xx_pic_regs;
 }
index 8eafcca..3222b36 100644 (file)
@@ -23,7 +23,6 @@
 #include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
 #include "qemu/error-report.h"
-#include "hw/char/pl011.h"
 
 #define SMP_BOOT_ADDR 0xe0000000
 #define SMP_BOOTREG_ADDR 0x10000030
@@ -203,10 +202,10 @@ static void realview_init(MachineState *machine,
     sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]);
     sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]);
 
-    pl011_create(0x10009000, pic[12], serial_hds[0]);
-    pl011_create(0x1000a000, pic[13], serial_hds[1]);
-    pl011_create(0x1000b000, pic[14], serial_hds[2]);
-    pl011_create(0x1000c000, pic[15], serial_hds[3]);
+    sysbus_create_simple("pl011", 0x10009000, pic[12]);
+    sysbus_create_simple("pl011", 0x1000a000, pic[13]);
+    sysbus_create_simple("pl011", 0x1000b000, pic[14]);
+    sysbus_create_simple("pl011", 0x1000c000, pic[15]);
 
     /* DMA controller is optional, apparently.  */
     sysbus_create_simple("pl081", 0x10030000, pic[24]);
@@ -254,7 +253,7 @@ static void realview_init(MachineState *machine,
         sysbus_connect_irq(busdev, 2, pic[50]);
         sysbus_connect_irq(busdev, 3, pic[51]);
         pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
-        if (machine_usb(machine)) {
+        if (usb_enabled()) {
             pci_create_simple(pci_bus, -1, "pci-ohci");
         }
         n = drive_get_max_bus(IF_SCSI);
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
deleted file mode 100644 (file)
index 4e7ac8c..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * SABRELITE Board System emulation.
- *
- * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
- *
- * This code is licensed under the GPL, version 2 or later.
- * See the file `COPYING' in the top level directory.
- *
- * It (partially) emulates a sabrelite board, with a Freescale
- * i.MX6 SoC
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "hw/arm/fsl-imx6.h"
-#include "hw/boards.h"
-#include "sysemu/sysemu.h"
-#include "qemu/error-report.h"
-#include "sysemu/qtest.h"
-
-typedef struct IMX6Sabrelite {
-    FslIMX6State soc;
-    MemoryRegion ram;
-} IMX6Sabrelite;
-
-static struct arm_boot_info sabrelite_binfo = {
-    /* DDR memory start */
-    .loader_start = FSL_IMX6_MMDC_ADDR,
-    /* No board ID, we boot from DT tree */
-    .board_id = -1,
-};
-
-/* No need to do any particular setup for secondary boot */
-static void sabrelite_write_secondary(ARMCPU *cpu,
-                                      const struct arm_boot_info *info)
-{
-}
-
-/* Secondary cores are reset through SRC device */
-static void sabrelite_reset_secondary(ARMCPU *cpu,
-                                      const struct arm_boot_info *info)
-{
-}
-
-static void sabrelite_init(MachineState *machine)
-{
-    IMX6Sabrelite *s = g_new0(IMX6Sabrelite, 1);
-    Error *err = NULL;
-
-    /* Check the amount of memory is compatible with the SOC */
-    if (machine->ram_size > FSL_IMX6_MMDC_SIZE) {
-        error_report("RAM size " RAM_ADDR_FMT " above max supported (%08x)",
-                     machine->ram_size, FSL_IMX6_MMDC_SIZE);
-        exit(1);
-    }
-
-    object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX6);
-    object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
-                              &error_abort);
-
-    object_property_set_bool(OBJECT(&s->soc), true, "realized", &err);
-    if (err != NULL) {
-        error_report("%s", error_get_pretty(err));
-        exit(1);
-    }
-
-    memory_region_allocate_system_memory(&s->ram, NULL, "sabrelite.ram",
-                                         machine->ram_size);
-    memory_region_add_subregion(get_system_memory(), FSL_IMX6_MMDC_ADDR,
-                                &s->ram);
-
-    {
-        /*
-         * TODO: Ideally we would expose the chip select and spi bus on the
-         * SoC object using alias properties; then we would not need to
-         * directly access the underlying spi device object.
-         */
-        /* Add the sst25vf016b NOR FLASH memory to first SPI */
-        Object *spi_dev;
-
-        spi_dev = object_resolve_path_component(OBJECT(&s->soc), "spi1");
-        if (spi_dev) {
-            SSIBus *spi_bus;
-
-            spi_bus = (SSIBus *)qdev_get_child_bus(DEVICE(spi_dev), "spi");
-            if (spi_bus) {
-                DeviceState *flash_dev;
-                qemu_irq cs_line;
-                DriveInfo *dinfo = drive_get_next(IF_MTD);
-
-                flash_dev = ssi_create_slave_no_init(spi_bus, "sst25vf016b");
-                if (dinfo) {
-                    qdev_prop_set_drive(flash_dev, "drive",
-                                        blk_by_legacy_dinfo(dinfo),
-                                        &error_fatal);
-                }
-                qdev_init_nofail(flash_dev);
-
-                cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
-                sysbus_connect_irq(SYS_BUS_DEVICE(spi_dev), 1, cs_line);
-            }
-        }
-    }
-
-    sabrelite_binfo.ram_size = machine->ram_size;
-    sabrelite_binfo.kernel_filename = machine->kernel_filename;
-    sabrelite_binfo.kernel_cmdline = machine->kernel_cmdline;
-    sabrelite_binfo.initrd_filename = machine->initrd_filename;
-    sabrelite_binfo.nb_cpus = smp_cpus;
-    sabrelite_binfo.secure_boot = true;
-    sabrelite_binfo.write_secondary_boot = sabrelite_write_secondary;
-    sabrelite_binfo.secondary_cpu_reset_hook = sabrelite_reset_secondary;
-
-    if (!qtest_enabled()) {
-        arm_load_kernel(&s->soc.cpu[0], &sabrelite_binfo);
-    }
-}
-
-static void sabrelite_machine_init(MachineClass *mc)
-{
-    mc->desc = "Freescale i.MX6 Quad SABRE Lite Board (Cortex A9)";
-    mc->init = sabrelite_init;
-    mc->max_cpus = FSL_IMX6_NUM_CPUS;
-}
-
-DEFINE_MACHINE("sabrelite", sabrelite_machine_init)
index 41cc2ee..bf61d63 100644 (file)
@@ -164,10 +164,9 @@ static void sl_flash_register(PXA2xxState *cpu, int size)
     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, FLASH_BASE);
 }
 
-static void sl_nand_init(Object *obj)
+static int sl_nand_init(SysBusDevice *dev)
 {
-    SLNANDState *s = SL_NAND(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    SLNANDState *s = SL_NAND(dev);
     DriveInfo *nand;
 
     s->ctl = 0;
@@ -176,8 +175,10 @@ static void sl_nand_init(Object *obj)
     s->nand = nand_init(nand ? blk_by_legacy_dinfo(nand) : NULL,
                         s->manf_id, s->chip_id);
 
-    memory_region_init_io(&s->iomem, obj, &sl_ops, s, "sl", 0x40);
+    memory_region_init_io(&s->iomem, OBJECT(s), &sl_ops, s, "sl", 0x40);
     sysbus_init_mmio(dev, &s->iomem);
+
+    return 0;
 }
 
 /* Spitz Keyboard */
@@ -500,10 +501,10 @@ static void spitz_keyboard_register(PXA2xxState *cpu)
     qemu_add_kbd_event_handler(spitz_keyboard_handler, s);
 }
 
-static void spitz_keyboard_init(Object *obj)
+static int spitz_keyboard_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    SpitzKeyboardState *s = SPITZ_KEYBOARD(obj);
+    DeviceState *dev = DEVICE(sbd);
+    SpitzKeyboardState *s = SPITZ_KEYBOARD(dev);
     int i, j;
 
     for (i = 0; i < 0x80; i ++)
@@ -518,6 +519,8 @@ static void spitz_keyboard_init(Object *obj)
     s->kbdtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, spitz_keyboard_tick, s);
     qdev_init_gpio_in(dev, spitz_keyboard_strobe, SPITZ_KEY_STROBE_NUM);
     qdev_init_gpio_out(dev, s->sense, SPITZ_KEY_SENSE_NUM);
+
+    return 0;
 }
 
 /* LCD backlight controller */
@@ -598,13 +601,15 @@ static uint32_t spitz_lcdtg_transfer(SSISlave *dev, uint32_t value)
     return 0;
 }
 
-static void spitz_lcdtg_realize(SSISlave *dev, Error **errp)
+static int spitz_lcdtg_init(SSISlave *dev)
 {
     SpitzLCDTG *s = FROM_SSI_SLAVE(SpitzLCDTG, dev);
 
     spitz_lcdtg = s;
     s->bl_power = 0;
     s->bl_intensity = 0x20;
+
+    return 0;
 }
 
 /* SSP devices */
@@ -664,7 +669,7 @@ static void spitz_adc_temp_on(void *opaque, int line, int level)
         max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
 }
 
-static void corgi_ssp_realize(SSISlave *d, Error **errp)
+static int corgi_ssp_init(SSISlave *d)
 {
     DeviceState *dev = DEVICE(d);
     CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, d);
@@ -673,6 +678,8 @@ static void corgi_ssp_realize(SSISlave *d, Error **errp)
     s->bus[0] = ssi_create_bus(dev, "ssi0");
     s->bus[1] = ssi_create_bus(dev, "ssi1");
     s->bus[2] = ssi_create_bus(dev, "ssi2");
+
+    return 0;
 }
 
 static void spitz_ssp_attach(PXA2xxState *cpu)
@@ -1058,7 +1065,9 @@ static Property sl_nand_properties[] = {
 static void sl_nand_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = sl_nand_init;
     dc->vmsd = &vmstate_sl_nand_info;
     dc->props = sl_nand_properties;
     /* Reason: init() method uses drive_get() */
@@ -1069,7 +1078,6 @@ static const TypeInfo sl_nand_info = {
     .name          = TYPE_SL_NAND,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(SLNANDState),
-    .instance_init = sl_nand_init,
     .class_init    = sl_nand_class_init,
 };
 
@@ -1089,7 +1097,9 @@ static VMStateDescription vmstate_spitz_kbd = {
 static void spitz_keyboard_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = spitz_keyboard_init;
     dc->vmsd = &vmstate_spitz_kbd;
 }
 
@@ -1097,7 +1107,6 @@ static const TypeInfo spitz_keyboard_info = {
     .name          = TYPE_SPITZ_KEYBOARD,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(SpitzKeyboardState),
-    .instance_init = spitz_keyboard_init,
     .class_init    = spitz_keyboard_class_init,
 };
 
@@ -1117,7 +1126,7 @@ static void corgi_ssp_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 
-    k->realize = corgi_ssp_realize;
+    k->init = corgi_ssp_init;
     k->transfer = corgi_ssp_transfer;
     dc->vmsd = &vmstate_corgi_ssp_regs;
 }
@@ -1146,7 +1155,7 @@ static void spitz_lcdtg_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 
-    k->realize = spitz_lcdtg_realize;
+    k->init = spitz_lcdtg_init;
     k->transfer = spitz_lcdtg_transfer;
     dc->vmsd = &vmstate_spitz_lcdtg_regs;
 }
index 794a3ad..c1766f8 100644 (file)
 #include "hw/i2c/i2c.h"
 #include "net/net.h"
 #include "hw/boards.h"
-#include "qemu/log.h"
 #include "exec/address-spaces.h"
 #include "sysemu/sysemu.h"
-#include "hw/char/pl011.h"
 
 #define GPIO_A 0
 #define GPIO_B 1
@@ -318,22 +316,23 @@ static const VMStateDescription vmstate_stellaris_gptm = {
     }
 };
 
-static void stellaris_gptm_init(Object *obj)
+static int stellaris_gptm_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    gptm_state *s = STELLARIS_GPTM(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    gptm_state *s = STELLARIS_GPTM(dev);
 
     sysbus_init_irq(sbd, &s->irq);
     qdev_init_gpio_out(dev, &s->trigger, 1);
 
-    memory_region_init_io(&s->iomem, obj, &gptm_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &gptm_ops, s,
                           "gptm", 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
 
     s->opaque[0] = s->opaque[1] = s;
     s->timer[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, gptm_tick, &s->opaque[0]);
     s->timer[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, gptm_tick, &s->opaque[1]);
+    vmstate_register(dev, -1, &vmstate_stellaris_gptm, s);
+    return 0;
 }
 
 
@@ -874,22 +873,23 @@ static const VMStateDescription vmstate_stellaris_i2c = {
     }
 };
 
-static void stellaris_i2c_init(Object *obj)
+static int stellaris_i2c_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    stellaris_i2c_state *s = STELLARIS_I2C(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    stellaris_i2c_state *s = STELLARIS_I2C(dev);
     I2CBus *bus;
 
     sysbus_init_irq(sbd, &s->irq);
     bus = i2c_init_bus(dev, "i2c");
     s->bus = bus;
 
-    memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &stellaris_i2c_ops, s,
                           "i2c", 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
     /* ??? For now we only implement the master interface.  */
     stellaris_i2c_reset(s);
+    vmstate_register(dev, -1, &vmstate_stellaris_i2c, s);
+    return 0;
 }
 
 /* Analogue to Digital Converter.  This is only partially implemented,
@@ -1160,22 +1160,23 @@ static const VMStateDescription vmstate_stellaris_adc = {
     }
 };
 
-static void stellaris_adc_init(Object *obj)
+static int stellaris_adc_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    stellaris_adc_state *s = STELLARIS_ADC(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    stellaris_adc_state *s = STELLARIS_ADC(dev);
     int n;
 
     for (n = 0; n < 4; n++) {
         sysbus_init_irq(sbd, &s->irq[n]);
     }
 
-    memory_region_init_io(&s->iomem, obj, &stellaris_adc_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &stellaris_adc_ops, s,
                           "adc", 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
     stellaris_adc_reset(s);
     qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
+    vmstate_register(dev, -1, &vmstate_stellaris_adc, s);
+    return 0;
 }
 
 static
@@ -1304,9 +1305,8 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
 
     for (i = 0; i < 4; i++) {
         if (board->dc2 & (1 << i)) {
-            pl011_luminary_create(0x4000c000 + i * 0x1000,
-                                  qdev_get_gpio_in(nvic, uart_irq[i]),
-                                  serial_hds[i]);
+            sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
+                                 qdev_get_gpio_in(nvic, uart_irq[i]));
         }
     }
     if (board->dc2 & (1 << 4)) {
@@ -1425,46 +1425,43 @@ type_init(stellaris_machine_init)
 
 static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
 
-    dc->vmsd = &vmstate_stellaris_i2c;
+    sdc->init = stellaris_i2c_init;
 }
 
 static const TypeInfo stellaris_i2c_info = {
     .name          = TYPE_STELLARIS_I2C,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(stellaris_i2c_state),
-    .instance_init = stellaris_i2c_init,
     .class_init    = stellaris_i2c_class_init,
 };
 
 static void stellaris_gptm_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
 
-    dc->vmsd = &vmstate_stellaris_gptm;
+    sdc->init = stellaris_gptm_init;
 }
 
 static const TypeInfo stellaris_gptm_info = {
     .name          = TYPE_STELLARIS_GPTM,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(gptm_state),
-    .instance_init = stellaris_gptm_init,
     .class_init    = stellaris_gptm_class_init,
 };
 
 static void stellaris_adc_class_init(ObjectClass *klass, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
 
-    dc->vmsd = &vmstate_stellaris_adc;
+    sdc->init = stellaris_adc_init;
 }
 
 static const TypeInfo stellaris_adc_info = {
     .name          = TYPE_STELLARIS_ADC,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(stellaris_adc_state),
-    .instance_init = stellaris_adc_init,
     .class_init    = stellaris_adc_class_init,
 };
 
index de26b8c..a5ea1e2 100644 (file)
@@ -25,6 +25,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
+#include "cpu.h"
 #include "hw/arm/arm.h"
 #include "exec/address-spaces.h"
 #include "hw/arm/stm32f205_soc.h"
@@ -107,7 +108,6 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
     /* Attach UART (uses USART registers) and USART controllers */
     for (i = 0; i < STM_NUM_USARTS; i++) {
         usartdev = DEVICE(&(s->usart[i]));
-        qdev_prop_set_chr(usartdev, "chardev", i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL);
         object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err);
         if (err != NULL) {
             error_propagate(errp, err);
index f1b2c6c..1eeb1ab 100644 (file)
@@ -38,7 +38,6 @@
 #include "sysemu/sysemu.h"
 #include "hw/ssi/ssi.h"
 #include "qemu/cutils.h"
-#include "qemu/log.h"
 
 //#define DEBUG
 
@@ -180,18 +179,19 @@ static const MemoryRegionOps strongarm_pic_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void strongarm_pic_initfn(Object *obj)
+static int strongarm_pic_initfn(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    StrongARMPICState *s = STRONGARM_PIC(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    StrongARMPICState *s = STRONGARM_PIC(dev);
 
     qdev_init_gpio_in(dev, strongarm_pic_set_irq, SA_PIC_SRCS);
-    memory_region_init_io(&s->iomem, obj, &strongarm_pic_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_pic_ops, s,
                           "pic", 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
     sysbus_init_irq(sbd, &s->irq);
     sysbus_init_irq(sbd, &s->fiq);
+
+    return 0;
 }
 
 static int strongarm_pic_post_load(void *opaque, int version_id)
@@ -217,7 +217,9 @@ static VMStateDescription vmstate_strongarm_pic_regs = {
 static void strongarm_pic_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = strongarm_pic_initfn;
     dc->desc = "StrongARM PIC";
     dc->vmsd = &vmstate_strongarm_pic_regs;
 }
@@ -226,7 +228,6 @@ static const TypeInfo strongarm_pic_info = {
     .name          = TYPE_STRONGARM_PIC,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(StrongARMPICState),
-    .instance_init = strongarm_pic_initfn,
     .class_init    = strongarm_pic_class_init,
 };
 
@@ -380,10 +381,9 @@ static const MemoryRegionOps strongarm_rtc_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void strongarm_rtc_init(Object *obj)
+static int strongarm_rtc_init(SysBusDevice *dev)
 {
-    StrongARMRTCState *s = STRONGARM_RTC(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    StrongARMRTCState *s = STRONGARM_RTC(dev);
     struct tm tm;
 
     s->rttr = 0x0;
@@ -400,9 +400,11 @@ static void strongarm_rtc_init(Object *obj)
     sysbus_init_irq(dev, &s->rtc_irq);
     sysbus_init_irq(dev, &s->rtc_hz_irq);
 
-    memory_region_init_io(&s->iomem, obj, &strongarm_rtc_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_rtc_ops, s,
                           "rtc", 0x10000);
     sysbus_init_mmio(dev, &s->iomem);
+
+    return 0;
 }
 
 static void strongarm_rtc_pre_save(void *opaque)
@@ -441,7 +443,9 @@ static const VMStateDescription vmstate_strongarm_rtc_regs = {
 static void strongarm_rtc_sysbus_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = strongarm_rtc_init;
     dc->desc = "StrongARM RTC Controller";
     dc->vmsd = &vmstate_strongarm_rtc_regs;
 }
@@ -450,7 +454,6 @@ static const TypeInfo strongarm_rtc_sysbus_info = {
     .name          = TYPE_STRONGARM_RTC,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(StrongARMRTCState),
-    .instance_init = strongarm_rtc_init,
     .class_init    = strongarm_rtc_sysbus_class_init,
 };
 
@@ -643,17 +646,16 @@ static DeviceState *strongarm_gpio_init(hwaddr base,
     return dev;
 }
 
-static void strongarm_gpio_initfn(Object *obj)
+static int strongarm_gpio_initfn(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    StrongARMGPIOInfo *s = STRONGARM_GPIO(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    StrongARMGPIOInfo *s = STRONGARM_GPIO(dev);
     int i;
 
     qdev_init_gpio_in(dev, strongarm_gpio_set, 28);
     qdev_init_gpio_out(dev, s->handler, 28);
 
-    memory_region_init_io(&s->iomem, obj, &strongarm_gpio_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_gpio_ops, s,
                           "gpio", 0x1000);
 
     sysbus_init_mmio(sbd, &s->iomem);
@@ -661,6 +663,8 @@ static void strongarm_gpio_initfn(Object *obj)
         sysbus_init_irq(sbd, &s->irqs[i]);
     }
     sysbus_init_irq(sbd, &s->irqX);
+
+    return 0;
 }
 
 static const VMStateDescription vmstate_strongarm_gpio_regs = {
@@ -683,7 +687,9 @@ static const VMStateDescription vmstate_strongarm_gpio_regs = {
 static void strongarm_gpio_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = strongarm_gpio_initfn;
     dc->desc = "StrongARM GPIO controller";
     dc->vmsd = &vmstate_strongarm_gpio_regs;
 }
@@ -692,7 +698,6 @@ static const TypeInfo strongarm_gpio_info = {
     .name          = TYPE_STRONGARM_GPIO,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(StrongARMGPIOInfo),
-    .instance_init = strongarm_gpio_initfn,
     .class_init    = strongarm_gpio_class_init,
 };
 
@@ -819,19 +824,20 @@ static const MemoryRegionOps strongarm_ppc_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void strongarm_ppc_init(Object *obj)
+static int strongarm_ppc_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    StrongARMPPCInfo *s = STRONGARM_PPC(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    StrongARMPPCInfo *s = STRONGARM_PPC(dev);
 
     qdev_init_gpio_in(dev, strongarm_ppc_set, 22);
     qdev_init_gpio_out(dev, s->handler, 22);
 
-    memory_region_init_io(&s->iomem, obj, &strongarm_ppc_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_ppc_ops, s,
                           "ppc", 0x1000);
 
     sysbus_init_mmio(sbd, &s->iomem);
+
+    return 0;
 }
 
 static const VMStateDescription vmstate_strongarm_ppc_regs = {
@@ -853,7 +859,9 @@ static const VMStateDescription vmstate_strongarm_ppc_regs = {
 static void strongarm_ppc_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = strongarm_ppc_init;
     dc->desc = "StrongARM PPC controller";
     dc->vmsd = &vmstate_strongarm_ppc_regs;
 }
@@ -862,7 +870,6 @@ static const TypeInfo strongarm_ppc_info = {
     .name          = TYPE_STRONGARM_PPC,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(StrongARMPPCInfo),
-    .instance_init = strongarm_ppc_init,
     .class_init    = strongarm_ppc_class_init,
 };
 
@@ -1224,12 +1231,11 @@ static const MemoryRegionOps strongarm_uart_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void strongarm_uart_init(Object *obj)
+static int strongarm_uart_init(SysBusDevice *dev)
 {
-    StrongARMUARTState *s = STRONGARM_UART(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    StrongARMUARTState *s = STRONGARM_UART(dev);
 
-    memory_region_init_io(&s->iomem, obj, &strongarm_uart_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_uart_ops, s,
                           "uart", 0x10000);
     sysbus_init_mmio(dev, &s->iomem);
     sysbus_init_irq(dev, &s->irq);
@@ -1244,6 +1250,8 @@ static void strongarm_uart_init(Object *obj)
                         strongarm_uart_event,
                         s);
     }
+
+    return 0;
 }
 
 static void strongarm_uart_reset(DeviceState *dev)
@@ -1313,7 +1321,9 @@ static Property strongarm_uart_properties[] = {
 static void strongarm_uart_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = strongarm_uart_init;
     dc->desc = "StrongARM UART controller";
     dc->reset = strongarm_uart_reset;
     dc->vmsd = &vmstate_strongarm_uart_regs;
@@ -1324,7 +1334,6 @@ static const TypeInfo strongarm_uart_info = {
     .name          = TYPE_STRONGARM_UART,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(StrongARMUARTState),
-    .instance_init = strongarm_uart_init,
     .class_init    = strongarm_uart_class_init,
 };
 
index 1470eac..2893f94 100644 (file)
@@ -1,8 +1,7 @@
-#ifndef STRONGARM_H
-#define STRONGARM_H
+#ifndef _STRONGARM_H
+#define _STRONGARM_H
 
 #include "exec/memory.h"
-#include "target-arm/cpu-qom.h"
 
 #define SA_CS0          0x00000000
 #define SA_CS1          0x08000000
index 2db6650..4e9494f 100644 (file)
@@ -127,9 +127,10 @@ static uint32_t tosa_ssp_tansfer(SSISlave *dev, uint32_t value)
     return 0;
 }
 
-static void tosa_ssp_realize(SSISlave *dev, Error **errp)
+static int tosa_ssp_init(SSISlave *dev)
 {
     /* Nothing to do.  */
+    return 0;
 }
 
 #define TYPE_TOSA_DAC "tosa_dac"
@@ -282,7 +283,7 @@ static void tosa_ssp_class_init(ObjectClass *klass, void *data)
 {
     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 
-    k->realize = tosa_ssp_realize;
+    k->init = tosa_ssp_init;
     k->transfer = tosa_ssp_tansfer;
 }
 
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
deleted file mode 100644 (file)
index d5f33a2..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/arm/virt-acpi-build.c
-virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
index 8ae5392..e5a80c2 100644 (file)
@@ -23,7 +23,6 @@
 #include "exec/address-spaces.h"
 #include "hw/block/flash.h"
 #include "qemu/error-report.h"
-#include "hw/char/pl011.h"
 
 #define VERSATILE_FLASH_ADDR 0x34000000
 #define VERSATILE_FLASH_SIZE (64 * 1024 * 1024)
@@ -154,11 +153,10 @@ static const MemoryRegionOps vpb_sic_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void vpb_sic_init(Object *obj)
+static int vpb_sic_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    vpb_sic_state *s = VERSATILE_PB_SIC(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    vpb_sic_state *s = VERSATILE_PB_SIC(dev);
     int i;
 
     qdev_init_gpio_in(dev, vpb_sic_set_irq, 32);
@@ -166,9 +164,10 @@ static void vpb_sic_init(Object *obj)
         sysbus_init_irq(sbd, &s->parent[i]);
     }
     s->irq = 31;
-    memory_region_init_io(&s->iomem, obj, &vpb_sic_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &vpb_sic_ops, s,
                           "vpb-sic", 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
+    return 0;
 }
 
 /* Board init.  */
@@ -276,7 +275,7 @@ static void versatile_init(MachineState *machine, int board_id)
             pci_nic_init_nofail(nd, pci_bus, "rtl8139", NULL);
         }
     }
-    if (machine_usb(machine)) {
+    if (usb_enabled()) {
         pci_create_simple(pci_bus, -1, "pci-ohci");
     }
     n = drive_get_max_bus(IF_SCSI);
@@ -285,10 +284,10 @@ static void versatile_init(MachineState *machine, int board_id)
         n--;
     }
 
-    pl011_create(0x101f1000, pic[12], serial_hds[0]);
-    pl011_create(0x101f2000, pic[13], serial_hds[1]);
-    pl011_create(0x101f3000, pic[14], serial_hds[2]);
-    pl011_create(0x10009000, sic[6], serial_hds[3]);
+    sysbus_create_simple("pl011", 0x101f1000, pic[12]);
+    sysbus_create_simple("pl011", 0x101f2000, pic[13]);
+    sysbus_create_simple("pl011", 0x101f3000, pic[14]);
+    sysbus_create_simple("pl011", 0x10009000, sic[6]);
 
     sysbus_create_simple("pl080", 0x10130000, pic[17]);
     sysbus_create_simple("sp804", 0x101e2000, pic[4]);
@@ -428,7 +427,9 @@ type_init(versatile_machine_init)
 static void vpb_sic_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = vpb_sic_init;
     dc->vmsd = &vmstate_vpb_sic;
 }
 
@@ -436,7 +437,6 @@ static const TypeInfo vpb_sic_info = {
     .name          = TYPE_VERSATILE_PB_SIC,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(vpb_sic_state),
-    .instance_init = vpb_sic_init,
     .class_init    = vpb_sic_class_init,
 };
 
index 58760f4..70b3e70 100644 (file)
@@ -39,7 +39,6 @@
 #include "sysemu/device_tree.h"
 #include "qemu/error-report.h"
 #include <libfdt.h>
-#include "hw/char/pl011.h"
 
 #define VEXPRESS_BOARD_ID 0x8e0
 #define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024)
@@ -632,10 +631,10 @@ static void vexpress_common_init(MachineState *machine)
     sysbus_create_simple("pl050_keyboard", map[VE_KMI0], pic[12]);
     sysbus_create_simple("pl050_mouse", map[VE_KMI1], pic[13]);
 
-    pl011_create(map[VE_UART0], pic[5], serial_hds[0]);
-    pl011_create(map[VE_UART1], pic[6], serial_hds[1]);
-    pl011_create(map[VE_UART2], pic[7], serial_hds[2]);
-    pl011_create(map[VE_UART3], pic[8], serial_hds[3]);
+    sysbus_create_simple("pl011", map[VE_UART0], pic[5]);
+    sysbus_create_simple("pl011", map[VE_UART1], pic[6]);
+    sysbus_create_simple("pl011", map[VE_UART2], pic[7]);
+    sysbus_create_simple("pl011", map[VE_UART3], pic[8]);
 
     sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]);
     sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]);
index 28fc59c..f51fe39 100644 (file)
@@ -43,7 +43,6 @@
 #include "hw/acpi/aml-build.h"
 #include "hw/pci/pcie_host.h"
 #include "hw/pci/pci.h"
-#include "sysemu/numa.h"
 
 #define ARM_SPI_BASE 32
 #define ACPI_POWER_BUTTON_DEVICE "PWRB"
@@ -231,8 +230,7 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
         aml_append(rbuf,
             aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
                              AML_NON_CACHEABLE, AML_READ_WRITE, 0x0000,
-                             base_mmio_high,
-                             base_mmio_high + size_mmio_high - 1, 0x0000,
+                             base_mmio_high, base_mmio_high, 0x0000,
                              size_mmio_high));
     }
 
@@ -354,14 +352,11 @@ static void acpi_dsdt_add_power_button(Aml *scope)
 
 /* RSDP */
 static GArray *
-build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
+build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
 {
     AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
-    unsigned rsdt_pa_size = sizeof(rsdp->rsdt_physical_address);
-    unsigned rsdt_pa_offset =
-        (char *)&rsdp->rsdt_physical_address - rsdp_table->data;
 
-    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,
+    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16,
                              true /* fseg memory */);
 
     memcpy(&rsdp->signature, "RSD PTR ", sizeof(rsdp->signature));
@@ -369,21 +364,24 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
     rsdp->length = cpu_to_le32(sizeof(*rsdp));
     rsdp->revision = 0x02;
 
+    /* Point to RSDT */
+    rsdp->rsdt_physical_address = cpu_to_le32(rsdt);
     /* Address to be filled by Guest linker */
-    bios_linker_loader_add_pointer(linker,
-        ACPI_BUILD_RSDP_FILE, rsdt_pa_offset, rsdt_pa_size,
-        ACPI_BUILD_TABLE_FILE, rsdt_tbl_offset);
-
+    bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
+                                   ACPI_BUILD_TABLE_FILE,
+                                   rsdp_table, &rsdp->rsdt_physical_address,
+                                   sizeof rsdp->rsdt_physical_address);
+    rsdp->checksum = 0;
     /* Checksum to be filled by Guest linker */
     bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
-        (char *)rsdp - rsdp_table->data, sizeof *rsdp,
-        (char *)&rsdp->checksum - rsdp_table->data);
+                                    rsdp_table, rsdp, sizeof *rsdp,
+                                    &rsdp->checksum);
 
     return rsdp_table;
 }
 
 static void
-build_spcr(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
+build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
 {
     AcpiSerialPortConsoleRedirection *spcr;
     const MemMapEntry *uart_memmap = &guest_info->memmap[VIRT_UART];
@@ -416,52 +414,7 @@ build_spcr(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
 }
 
 static void
-build_srat(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
-{
-    AcpiSystemResourceAffinityTable *srat;
-    AcpiSratProcessorGiccAffinity *core;
-    AcpiSratMemoryAffinity *numamem;
-    int i, j, srat_start;
-    uint64_t mem_base;
-    uint32_t *cpu_node = g_malloc0(guest_info->smp_cpus * sizeof(uint32_t));
-
-    for (i = 0; i < guest_info->smp_cpus; i++) {
-        for (j = 0; j < nb_numa_nodes; j++) {
-            if (test_bit(i, numa_info[j].node_cpu)) {
-                cpu_node[i] = j;
-                break;
-            }
-        }
-    }
-
-    srat_start = table_data->len;
-    srat = acpi_data_push(table_data, sizeof(*srat));
-    srat->reserved1 = cpu_to_le32(1);
-
-    for (i = 0; i < guest_info->smp_cpus; ++i) {
-        core = acpi_data_push(table_data, sizeof(*core));
-        core->type = ACPI_SRAT_PROCESSOR_GICC;
-        core->length = sizeof(*core);
-        core->proximity = cpu_to_le32(cpu_node[i]);
-        core->acpi_processor_uid = cpu_to_le32(i);
-        core->flags = cpu_to_le32(1);
-    }
-    g_free(cpu_node);
-
-    mem_base = guest_info->memmap[VIRT_MEM].base;
-    for (i = 0; i < nb_numa_nodes; ++i) {
-        numamem = acpi_data_push(table_data, sizeof(*numamem));
-        build_srat_memory(numamem, mem_base, numa_info[i].node_mem, i,
-                          MEM_AFFINITY_ENABLED);
-        mem_base += numa_info[i].node_mem;
-    }
-
-    build_header(linker, table_data, (void *)srat, "SRAT",
-                 table_data->len - srat_start, 3, NULL, NULL);
-}
-
-static void
-build_mcfg(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
+build_mcfg(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
 {
     AcpiTableMcfg *mcfg;
     const MemMapEntry *memmap = guest_info->memmap;
@@ -481,7 +434,7 @@ build_mcfg(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
 
 /* GTDT */
 static void
-build_gtdt(GArray *table_data, BIOSLinker *linker)
+build_gtdt(GArray *table_data, GArray *linker)
 {
     int gtdt_start = table_data->len;
     AcpiGenericTimerTable *gtdt;
@@ -507,7 +460,7 @@ build_gtdt(GArray *table_data, BIOSLinker *linker)
 
 /* MADT */
 static void
-build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
+build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
 {
     int madt_start = table_data->len;
     const MemMapEntry *memmap = guest_info->memmap;
@@ -523,7 +476,6 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
     gicd->type = ACPI_APIC_GENERIC_DISTRIBUTOR;
     gicd->length = sizeof(*gicd);
     gicd->base_address = memmap[VIRT_GIC_DIST].base;
-    gicd->version = guest_info->gic_version;
 
     for (i = 0; i < guest_info->smp_cpus; i++) {
         AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,
@@ -539,10 +491,6 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
         gicc->arm_mpidr = armcpu->mp_affinity;
         gicc->uid = i;
         gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
-
-        if (armcpu->has_pmu) {
-            gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
-        }
     }
 
     if (guest_info->gic_version == 3) {
@@ -571,10 +519,9 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
 
 /* FADT */
 static void
-build_fadt(GArray *table_data, BIOSLinker *linker, unsigned dsdt_tbl_offset)
+build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)
 {
     AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
-    unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
 
     /* Hardware Reduced = 1 and use PSCI 0.2+ and with HVC */
     fadt->flags = cpu_to_le32(1 << ACPI_FADT_F_HW_REDUCED_ACPI);
@@ -584,10 +531,12 @@ build_fadt(GArray *table_data, BIOSLinker *linker, unsigned dsdt_tbl_offset)
     /* ACPI v5.1 (fadt->revision.fadt->minor_revision) */
     fadt->minor_revision = 0x1;
 
+    fadt->dsdt = cpu_to_le32(dsdt);
     /* DSDT address to be filled by Guest linker */
-    bios_linker_loader_add_pointer(linker,
-        ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
-        ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
+    bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+                                   ACPI_BUILD_TABLE_FILE,
+                                   table_data, &fadt->dsdt,
+                                   sizeof fadt->dsdt);
 
     build_header(linker, table_data,
                  (void *)fadt, "FACP", sizeof(*fadt), 5, NULL, NULL);
@@ -595,7 +544,7 @@ build_fadt(GArray *table_data, BIOSLinker *linker, unsigned dsdt_tbl_offset)
 
 /* DSDT */
 static void
-build_dsdt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
+build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
 {
     Aml *scope, *dsdt;
     const MemMapEntry *memmap = guest_info->memmap;
@@ -655,8 +604,7 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
     table_offsets = g_array_new(false, true /* clear */,
                                         sizeof(uint32_t));
 
-    bios_linker_loader_alloc(tables->linker,
-                             ACPI_BUILD_TABLE_FILE, tables_blob,
+    bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
                              64, false /* high memory */);
 
     /*
@@ -690,11 +638,6 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
     acpi_add_table(table_offsets, tables_blob);
     build_spcr(tables_blob, tables->linker, guest_info);
 
-    if (nb_numa_nodes > 0) {
-        acpi_add_table(table_offsets, tables_blob);
-        build_srat(tables_blob, tables->linker, guest_info);
-    }
-
     /* RSDT is pointed to by RSDP */
     rsdt = tables_blob->len;
     build_rsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);
@@ -735,7 +678,7 @@ static void virt_acpi_build_update(void *build_opaque)
 
     acpi_ram_update(build_state->table_mr, tables.table_data);
     acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
-    acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob);
+    acpi_ram_update(build_state->linker_mr, tables.linker);
 
 
     acpi_build_tables_cleanup(&tables, true);
@@ -793,8 +736,7 @@ void virt_acpi_setup(VirtGuestInfo *guest_info)
     assert(build_state->table_mr != NULL);
 
     build_state->linker_mr =
-        acpi_add_rom_blob(build_state, tables.linker->cmd_blob,
-                          "etc/table-loader", 0);
+        acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);
 
     fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
                     tables.tcpalog->data, acpi_data_len(tables.tcpalog));
index a193b5a..a535285 100644 (file)
 #include "net/net.h"
 #include "sysemu/block-backend.h"
 #include "sysemu/device_tree.h"
-#include "sysemu/numa.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
 #include "hw/boards.h"
-#include "hw/compat.h"
 #include "hw/loader.h"
 #include "exec/address-spaces.h"
 #include "qemu/bitops.h"
@@ -52,8 +50,7 @@
 #include "hw/arm/sysbus-fdt.h"
 #include "hw/platform-bus.h"
 #include "hw/arm/fdt.h"
-#include "hw/intc/arm_gic.h"
-#include "hw/intc/arm_gicv3_common.h"
+#include "hw/intc/arm_gic_common.h"
 #include "kvm_arm.h"
 #include "hw/smbios/smbios.h"
 #include "qapi/visitor.h"
@@ -83,7 +80,6 @@ typedef struct VirtBoardInfo {
 typedef struct {
     MachineClass parent;
     VirtBoardInfo *daughterboard;
-    bool disallow_affinity_adjustment;
 } VirtMachineClass;
 
 typedef struct {
@@ -101,36 +97,6 @@ typedef struct {
 #define VIRT_MACHINE_CLASS(klass) \
     OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE)
 
-
-#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
-    static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
-                                                    void *data) \
-    { \
-        MachineClass *mc = MACHINE_CLASS(oc); \
-        virt_machine_##major##_##minor##_options(mc); \
-        mc->desc = "QEMU " # major "." # minor " ARM Virtual Machine"; \
-        if (latest) { \
-            mc->alias = "virt"; \
-        } \
-    } \
-    static const TypeInfo machvirt_##major##_##minor##_info = { \
-        .name = MACHINE_TYPE_NAME("virt-" # major "." # minor), \
-        .parent = TYPE_VIRT_MACHINE, \
-        .instance_init = virt_##major##_##minor##_instance_init, \
-        .class_init = virt_##major##_##minor##_class_init, \
-    }; \
-    static void machvirt_machine_##major##_##minor##_init(void) \
-    { \
-        type_register_static(&machvirt_##major##_##minor##_info); \
-    } \
-    type_init(machvirt_machine_##major##_##minor##_init);
-
-#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \
-    DEFINE_VIRT_MACHINE_LATEST(major, minor, true)
-#define DEFINE_VIRT_MACHINE(major, minor) \
-    DEFINE_VIRT_MACHINE_LATEST(major, minor, false)
-
-
 /* RAM limit in GB. Since VIRT_MEM starts at the 1GB mark, this means
  * RAM can go up to the 256GB mark, leaving 256GB of the physical
  * address space unallocated and free for future use between 256G and 512G.
@@ -363,7 +329,6 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
 {
     int cpu;
     int addr_cells = 1;
-    unsigned int i;
 
     /*
      * From Documentation/devicetree/bindings/arm/cpus.txt
@@ -413,12 +378,6 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
                                   armcpu->mp_affinity);
         }
 
-        for (i = 0; i < nb_numa_nodes; i++) {
-            if (test_bit(cpu, numa_info[i].node_cpu)) {
-                qemu_fdt_setprop_cell(vbi->fdt, nodename, "numa-node-id", i);
-            }
-        }
-
         g_free(nodename);
     }
 }
@@ -469,37 +428,6 @@ static void fdt_add_gic_node(VirtBoardInfo *vbi, int type)
     qemu_fdt_setprop_cell(vbi->fdt, "/intc", "phandle", vbi->gic_phandle);
 }
 
-static void fdt_add_pmu_nodes(const VirtBoardInfo *vbi, int gictype)
-{
-    CPUState *cpu;
-    ARMCPU *armcpu;
-    uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI;
-
-    CPU_FOREACH(cpu) {
-        armcpu = ARM_CPU(cpu);
-        if (!armcpu->has_pmu ||
-            !kvm_arm_pmu_create(cpu, PPI(VIRTUAL_PMU_IRQ))) {
-            return;
-        }
-    }
-
-    if (gictype == 2) {
-        irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
-                             GIC_FDT_IRQ_PPI_CPU_WIDTH,
-                             (1 << vbi->smp_cpus) - 1);
-    }
-
-    armcpu = ARM_CPU(qemu_get_cpu(0));
-    qemu_fdt_add_subnode(vbi->fdt, "/pmu");
-    if (arm_feature(&armcpu->env, ARM_FEATURE_V8)) {
-        const char compat[] = "arm,armv8-pmuv3";
-        qemu_fdt_setprop(vbi->fdt, "/pmu", "compatible",
-                         compat, sizeof(compat));
-        qemu_fdt_setprop_cells(vbi->fdt, "/pmu", "interrupts",
-                               GIC_FDT_IRQ_TYPE_PPI, VIRTUAL_PMU_IRQ, irqflags);
-    }
-}
-
 static void create_v2m(VirtBoardInfo *vbi, qemu_irq *pic)
 {
     int i;
@@ -589,7 +517,7 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type, bool secure)
 }
 
 static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic, int uart,
-                        MemoryRegion *mem, CharDriverState *chr)
+                        MemoryRegion *mem)
 {
     char *nodename;
     hwaddr base = vbi->memmap[uart].base;
@@ -600,7 +528,6 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic, int uart,
     DeviceState *dev = qdev_create(NULL, "pl011");
     SysBusDevice *s = SYS_BUS_DEVICE(dev);
 
-    qdev_prop_set_chr(dev, "chardev", chr);
     qdev_init_nofail(dev);
     memory_region_add_subregion(mem, base,
                                 sysbus_mmio_get_region(s, 0));
@@ -1023,7 +950,6 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
     qemu_fdt_setprop_cell(vbi->fdt, nodename, "#size-cells", 2);
     qemu_fdt_setprop_cells(vbi->fdt, nodename, "bus-range", 0,
                            nr_pcie_buses - 1);
-    qemu_fdt_setprop(vbi->fdt, nodename, "dma-coherent", NULL, 0);
 
     if (vbi->v2m_phandle) {
         qemu_fdt_setprop_cells(vbi->fdt, nodename, "msi-parent",
@@ -1167,7 +1093,6 @@ void virt_guest_info_machine_done(Notifier *notifier, void *data)
 static void machvirt_init(MachineState *machine)
 {
     VirtMachineState *vms = VIRT_MACHINE(machine);
-    VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
     qemu_irq pic[NUM_IRQS];
     MemoryRegion *sysmem = get_system_memory();
     MemoryRegion *secure_sysmem = NULL;
@@ -1179,12 +1104,7 @@ static void machvirt_init(MachineState *machine)
     VirtGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state);
     VirtGuestInfo *guest_info = &guest_info_state->info;
     char **cpustr;
-    ObjectClass *oc;
-    const char *typename;
-    CPUClass *cc;
-    Error *err = NULL;
     bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
-    uint8_t clustersz;
 
     if (!cpu_model) {
         cpu_model = "cortex-a15";
@@ -1230,10 +1150,8 @@ static void machvirt_init(MachineState *machine)
      */
     if (gic_version == 3) {
         virt_max_cpus = vbi->memmap[VIRT_GIC_REDIST].size / 0x20000;
-        clustersz = GICV3_TARGETLIST_BITS;
     } else {
         virt_max_cpus = GIC_NCPU;
-        clustersz = GIC_TARGETLIST_BITS;
     }
 
     if (max_cpus > virt_max_cpus) {
@@ -1269,37 +1187,25 @@ static void machvirt_init(MachineState *machine)
 
     create_fdt(vbi);
 
-    oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
-    if (!oc) {
-        error_report("Unable to find CPU definition");
-        exit(1);
-    }
-    typename = object_class_get_name(oc);
-
-    /* convert -smp CPU options specified by the user into global props */
-    cc = CPU_CLASS(oc);
-    cc->parse_features(typename, cpustr[1], &err);
-    g_strfreev(cpustr);
-    if (err) {
-        error_report_err(err);
-        exit(1);
-    }
-
     for (n = 0; n < smp_cpus; n++) {
-        Object *cpuobj = object_new(typename);
-        if (!vmc->disallow_affinity_adjustment) {
-            /* Adjust MPIDR like 64-bit KVM hosts, which incorporate the
-             * GIC's target-list limitations. 32-bit KVM hosts currently
-             * always create clusters of 4 CPUs, but that is expected to
-             * change when they gain support for gicv3. When KVM is enabled
-             * it will override the changes we make here, therefore our
-             * purposes are to make TCG consistent (with 64-bit KVM hosts)
-             * and to improve SGI efficiency.
-             */
-            uint8_t aff1 = n / clustersz;
-            uint8_t aff0 = n % clustersz;
-            object_property_set_int(cpuobj, (aff1 << ARM_AFF1_SHIFT) | aff0,
-                                    "mp-affinity", NULL);
+        ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
+        CPUClass *cc = CPU_CLASS(oc);
+        Object *cpuobj;
+        Error *err = NULL;
+        char *cpuopts = g_strdup(cpustr[1]);
+
+        if (!oc) {
+            error_report("Unable to find CPU definition");
+            exit(1);
+        }
+        cpuobj = object_new(object_class_get_name(oc));
+
+        /* Handle any CPU options specified by the user */
+        cc->parse_features(CPU(cpuobj), cpuopts, &err);
+        g_free(cpuopts);
+        if (err) {
+            error_report_err(err);
+            exit(1);
         }
 
         if (!vms->secure) {
@@ -1331,6 +1237,7 @@ static void machvirt_init(MachineState *machine)
 
         object_property_set_bool(cpuobj, true, "realized", NULL);
     }
+    g_strfreev(cpustr);
     fdt_add_timer_nodes(vbi, gic_version);
     fdt_add_cpu_nodes(vbi);
     fdt_add_psci_node(vbi);
@@ -1343,13 +1250,11 @@ static void machvirt_init(MachineState *machine)
 
     create_gic(vbi, pic, gic_version, vms->secure);
 
-    fdt_add_pmu_nodes(vbi, gic_version);
-
-    create_uart(vbi, pic, VIRT_UART, sysmem, serial_hds[0]);
+    create_uart(vbi, pic, VIRT_UART, sysmem);
 
     if (vms->secure) {
         create_secure_ram(vbi, secure_sysmem);
-        create_uart(vbi, pic, VIRT_SECURE_UART, secure_sysmem, serial_hds[1]);
+        create_uart(vbi, pic, VIRT_SECURE_UART, secure_sysmem);
     }
 
     create_rtc(vbi, pic);
@@ -1473,13 +1378,7 @@ static const TypeInfo virt_machine_info = {
     .class_init    = virt_machine_class_init,
 };
 
-static void machvirt_machine_init(void)
-{
-    type_register_static(&virt_machine_info);
-}
-type_init(machvirt_machine_init);
-
-static void virt_2_7_instance_init(Object *obj)
+static void virt_2_6_instance_init(Object *obj)
 {
     VirtMachineState *vms = VIRT_MACHINE(obj);
 
@@ -1512,25 +1411,29 @@ static void virt_2_7_instance_init(Object *obj)
                                     "Valid values are 2, 3 and host", NULL);
 }
 
-static void virt_machine_2_7_options(MachineClass *mc)
+static void virt_2_6_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
+        { /* end of list */ }
+    };
+
+    mc->desc = "QEMU 2.6 ARM Virtual Machine";
+    mc->alias = "virt";
+    mc->compat_props = compat_props;
 }
-DEFINE_VIRT_MACHINE_AS_LATEST(2, 7)
 
-#define VIRT_COMPAT_2_6 \
-    HW_COMPAT_2_6
+static const TypeInfo machvirt_info = {
+    .name = MACHINE_TYPE_NAME("virt-2.6"),
+    .parent = TYPE_VIRT_MACHINE,
+    .instance_init = virt_2_6_instance_init,
+    .class_init = virt_2_6_class_init,
+};
 
-static void virt_2_6_instance_init(Object *obj)
+static void machvirt_machine_init(void)
 {
-    virt_2_7_instance_init(obj);
+    type_register_static(&virt_machine_info);
+    type_register_static(&machvirt_info);
 }
 
-static void virt_machine_2_6_options(MachineClass *mc)
-{
-    VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
-
-    virt_machine_2_7_options(mc);
-    SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_6);
-    vmc->disallow_affinity_adjustment = true;
-}
-DEFINE_VIRT_MACHINE(2, 6)
+type_init(machvirt_machine_init);
index 7dac20d..98b17c9 100644 (file)
@@ -32,7 +32,6 @@
 #include "hw/ssi/ssi.h"
 #include "qemu/error-report.h"
 #include "hw/sd/sd.h"
-#include "hw/char/cadence_uart.h"
 
 #define NUM_SPI_FLASHES 4
 #define NUM_QSPI_FLASHES 2
@@ -138,13 +137,7 @@ static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
         spi = (SSIBus *)qdev_get_child_bus(dev, bus_name);
 
         for (j = 0; j < num_ss; ++j) {
-            DriveInfo *dinfo = drive_get_next(IF_MTD);
-            flash_dev = ssi_create_slave_no_init(spi, "n25q128");
-            if (dinfo) {
-                qdev_prop_set_drive(flash_dev, "drive",
-                                    blk_by_legacy_dinfo(dinfo), &error_fatal);
-            }
-            qdev_init_nofail(flash_dev);
+            flash_dev = ssi_create_slave(spi, "n25q128");
 
             cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
             sysbus_connect_irq(busdev, i * num_ss + j + 1, cs_line);
@@ -242,8 +235,8 @@ static void zynq_init(MachineState *machine)
     sysbus_create_simple("xlnx,ps7-usb", 0xE0002000, pic[53-IRQ_OFFSET]);
     sysbus_create_simple("xlnx,ps7-usb", 0xE0003000, pic[76-IRQ_OFFSET]);
 
-    cadence_uart_create(0xE0000000, pic[59 - IRQ_OFFSET], serial_hds[0]);
-    cadence_uart_create(0xE0001000, pic[82 - IRQ_OFFSET], serial_hds[1]);
+    sysbus_create_simple("cadence_uart", 0xE0000000, pic[59-IRQ_OFFSET]);
+    sysbus_create_simple("cadence_uart", 0xE0001000, pic[82-IRQ_OFFSET]);
 
     sysbus_create_varargs("cadence_ttc", 0xF8001000,
             pic[42-IRQ_OFFSET], pic[43-IRQ_OFFSET], pic[44-IRQ_OFFSET], NULL);
@@ -300,12 +293,6 @@ static void zynq_init(MachineState *machine)
         sysbus_connect_irq(busdev, n + 1, pic[dma_irqs[n] - IRQ_OFFSET]);
     }
 
-    dev = qdev_create(NULL, "xlnx.ps7-dev-cfg");
-    qdev_init_nofail(dev);
-    busdev = SYS_BUS_DEVICE(dev);
-    sysbus_connect_irq(busdev, 0, pic[40 - IRQ_OFFSET]);
-    sysbus_mmio_map(busdev, 0, 0xF8007000);
-
     zynq_binfo.ram_size = ram_size;
     zynq_binfo.kernel_filename = kernel_filename;
     zynq_binfo.kernel_cmdline = kernel_cmdline;
index 4ec590a..5f48018 100644 (file)
@@ -23,7 +23,6 @@
 #include "hw/boards.h"
 #include "qemu/error-report.h"
 #include "exec/address-spaces.h"
-#include "qemu/log.h"
 
 typedef struct XlnxEP108 {
     XlnxZynqMPState soc;
@@ -88,19 +87,12 @@ static void xlnx_ep108_init(MachineState *machine)
         SSIBus *spi_bus;
         DeviceState *flash_dev;
         qemu_irq cs_line;
-        DriveInfo *dinfo = drive_get_next(IF_MTD);
         gchar *bus_name = g_strdup_printf("spi%d", i);
 
         spi_bus = (SSIBus *)qdev_get_child_bus(DEVICE(&s->soc), bus_name);
         g_free(bus_name);
 
-        flash_dev = ssi_create_slave_no_init(spi_bus, "sst25wf080");
-        if (dinfo) {
-            qdev_prop_set_drive(flash_dev, "drive", blk_by_legacy_dinfo(dinfo),
-                                &error_fatal);
-        }
-        qdev_init_nofail(flash_dev);
-
+        flash_dev = ssi_create_slave(spi_bus, "sst25wf080");
         cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
 
         sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.spi[i]), 1, cs_line);
@@ -121,11 +113,3 @@ static void xlnx_ep108_machine_init(MachineClass *mc)
 }
 
 DEFINE_MACHINE("xlnx-ep108", xlnx_ep108_machine_init)
-
-static void xlnx_zcu102_machine_init(MachineClass *mc)
-{
-    mc->desc = "Xilinx ZynqMP ZCU102 board";
-    mc->init = xlnx_ep108_init;
-}
-
-DEFINE_MACHINE("xlnx-zcu102", xlnx_zcu102_machine_init)
index 23c7199..4d504da 100644 (file)
@@ -22,8 +22,6 @@
 #include "hw/arm/xlnx-zynqmp.h"
 #include "hw/intc/arm_gic_common.h"
 #include "exec/address-spaces.h"
-#include "sysemu/kvm.h"
-#include "kvm_arm.h"
 
 #define GIC_NUM_SPI_INTR 160
 
 #define SATA_ADDR           0xFD0C0000
 #define SATA_NUM_PORTS      2
 
-#define DP_ADDR             0xfd4a0000
-#define DP_IRQ              113
-
-#define DPDMA_ADDR          0xfd4c0000
-#define DPDMA_IRQ           116
-
 static const uint64_t gem_addr[XLNX_ZYNQMP_NUM_GEMS] = {
     0xFF0B0000, 0xFF0C0000, 0xFF0D0000, 0xFF0E0000,
 };
@@ -91,41 +83,6 @@ static inline int arm_gic_ppi_index(int cpu_nr, int ppi_index)
     return GIC_NUM_SPI_INTR + cpu_nr * GIC_INTERNAL + ppi_index;
 }
 
-static void xlnx_zynqmp_create_rpu(XlnxZynqMPState *s, const char *boot_cpu,
-                                   Error **errp)
-{
-    Error *err = NULL;
-    int i;
-
-    for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) {
-        char *name;
-
-        object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]),
-                          "cortex-r5-" TYPE_ARM_CPU);
-        object_property_add_child(OBJECT(s), "rpu-cpu[*]",
-                                  OBJECT(&s->rpu_cpu[i]), &error_abort);
-
-        name = object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i]));
-        if (strcmp(name, boot_cpu)) {
-            /* Secondary CPUs start in PSCI powered-down state */
-            object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true,
-                                     "start-powered-off", &error_abort);
-        } else {
-            s->boot_cpu_ptr = &s->rpu_cpu[i];
-        }
-        g_free(name);
-
-        object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, "reset-hivecs",
-                                 &error_abort);
-        object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, "realized",
-                                 &err);
-        if (err) {
-            error_propagate(errp, err);
-            return;
-        }
-    }
-}
-
 static void xlnx_zynqmp_init(Object *obj)
 {
     XlnxZynqMPState *s = XLNX_ZYNQMP(obj);
@@ -138,12 +95,19 @@ static void xlnx_zynqmp_init(Object *obj)
                                   &error_abort);
     }
 
+    for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) {
+        object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]),
+                          "cortex-r5-" TYPE_ARM_CPU);
+        object_property_add_child(obj, "rpu-cpu[*]", OBJECT(&s->rpu_cpu[i]),
+                                  &error_abort);
+    }
+
     object_property_add_link(obj, "ddr-ram", TYPE_MEMORY_REGION,
                              (Object **)&s->ddr_ram,
                              qdev_prop_allow_set_link_before_realize,
                              OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
 
-    object_initialize(&s->gic, sizeof(s->gic), gic_class_name());
+    object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
     qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
 
     for (i = 0; i < XLNX_ZYNQMP_NUM_GEMS; i++) {
@@ -171,12 +135,6 @@ static void xlnx_zynqmp_init(Object *obj)
                           TYPE_XILINX_SPIPS);
         qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
     }
-
-    object_initialize(&s->dp, sizeof(s->dp), TYPE_XLNX_DP);
-    qdev_set_parent_bus(DEVICE(&s->dp), sysbus_get_default());
-
-    object_initialize(&s->dpdma, sizeof(s->dpdma), TYPE_XLNX_DPDMA);
-    qdev_set_parent_bus(DEVICE(&s->dpdma), sysbus_get_default());
 }
 
 static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
@@ -238,42 +196,11 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
     qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32);
     qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2);
     qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", XLNX_ZYNQMP_NUM_APU_CPUS);
-
-    /* Realize APUs before realizing the GIC. KVM requires this.  */
-    for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
-        char *name;
-
-        object_property_set_int(OBJECT(&s->apu_cpu[i]), QEMU_PSCI_CONDUIT_SMC,
-                                "psci-conduit", &error_abort);
-
-        name = object_get_canonical_path_component(OBJECT(&s->apu_cpu[i]));
-        if (strcmp(name, boot_cpu)) {
-            /* Secondary CPUs start in PSCI powered-down state */
-            object_property_set_bool(OBJECT(&s->apu_cpu[i]), true,
-                                     "start-powered-off", &error_abort);
-        } else {
-            s->boot_cpu_ptr = &s->apu_cpu[i];
-        }
-        g_free(name);
-
-        object_property_set_bool(OBJECT(&s->apu_cpu[i]),
-                                 s->secure, "has_el3", NULL);
-        object_property_set_int(OBJECT(&s->apu_cpu[i]), GIC_BASE_ADDR,
-                                "reset-cbar", &error_abort);
-        object_property_set_bool(OBJECT(&s->apu_cpu[i]), true, "realized",
-                                 &err);
-        if (err) {
-            error_propagate(errp, err);
-            return;
-        }
-    }
-
     object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
     if (err) {
         error_propagate(errp, err);
         return;
     }
-
     assert(ARRAY_SIZE(xlnx_zynqmp_gic_regions) == XLNX_ZYNQMP_GIC_REGIONS);
     for (i = 0; i < XLNX_ZYNQMP_GIC_REGIONS; i++) {
         SysBusDevice *gic = SYS_BUS_DEVICE(&s->gic);
@@ -296,6 +223,29 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
 
     for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
         qemu_irq irq;
+        char *name;
+
+        object_property_set_int(OBJECT(&s->apu_cpu[i]), QEMU_PSCI_CONDUIT_SMC,
+                                "psci-conduit", &error_abort);
+
+        name = object_get_canonical_path_component(OBJECT(&s->apu_cpu[i]));
+        if (strcmp(name, boot_cpu)) {
+            /* Secondary CPUs start in PSCI powered-down state */
+            object_property_set_bool(OBJECT(&s->apu_cpu[i]), true,
+                                     "start-powered-off", &error_abort);
+        } else {
+            s->boot_cpu_ptr = &s->apu_cpu[i];
+        }
+        g_free(name);
+
+        object_property_set_int(OBJECT(&s->apu_cpu[i]), GIC_BASE_ADDR,
+                                "reset-cbar", &error_abort);
+        object_property_set_bool(OBJECT(&s->apu_cpu[i]), true, "realized",
+                                 &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
 
         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i,
                            qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]),
@@ -308,8 +258,23 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
         qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 1, irq);
     }
 
-    if (s->has_rpu) {
-        xlnx_zynqmp_create_rpu(s, boot_cpu, &err);
+    for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) {
+        char *name;
+
+        name = object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i]));
+        if (strcmp(name, boot_cpu)) {
+            /* Secondary CPUs start in PSCI powered-down state */
+            object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true,
+                                     "start-powered-off", &error_abort);
+        } else {
+            s->boot_cpu_ptr = &s->rpu_cpu[i];
+        }
+        g_free(name);
+
+        object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, "reset-hivecs",
+                                 &error_abort);
+        object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, "realized",
+                                 &err);
         if (err) {
             error_propagate(errp, err);
             return;
@@ -343,7 +308,6 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
     }
 
     for (i = 0; i < XLNX_ZYNQMP_NUM_UARTS; i++) {
-        qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hds[i]);
         object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err);
         if (err) {
             error_propagate(errp, err);
@@ -400,32 +364,12 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
         object_property_add_alias(OBJECT(s), bus_name,
                                   OBJECT(&s->spi[i]), "spi0",
                                   &error_abort);
-        g_free(bus_name);
-    }
-
-    object_property_set_bool(OBJECT(&s->dp), true, "realized", &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->dp), 0, DP_ADDR);
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->dp), 0, gic_spi[DP_IRQ]);
-
-    object_property_set_bool(OBJECT(&s->dpdma), true, "realized", &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
+       g_free(bus_name);
     }
-    object_property_set_link(OBJECT(&s->dp), OBJECT(&s->dpdma), "dpdma",
-                             &error_abort);
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->dpdma), 0, DPDMA_ADDR);
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->dpdma), 0, gic_spi[DPDMA_IRQ]);
 }
 
 static Property xlnx_zynqmp_props[] = {
     DEFINE_PROP_STRING("boot-cpu", XlnxZynqMPState, boot_cpu),
-    DEFINE_PROP_BOOL("secure", XlnxZynqMPState, secure, false),
-    DEFINE_PROP_BOOL("has_rpu", XlnxZynqMPState, has_rpu, false),
     DEFINE_PROP_END_OF_LIST()
 };
 
index 68a92f3..aea895a 100644 (file)
@@ -151,12 +151,14 @@ static void z2_lcd_cs(void *opaque, int line, int level)
     z2_lcd->selected = !level;
 }
 
-static void zipit_lcd_realize(SSISlave *dev, Error **errp)
+static int zipit_lcd_init(SSISlave *dev)
 {
     ZipitLCD *z = FROM_SSI_SLAVE(ZipitLCD, dev);
     z->selected = 0;
     z->enabled = 0;
     z->pos = 0;
+
+    return 0;
 }
 
 static VMStateDescription vmstate_zipit_lcd_state = {
@@ -179,7 +181,7 @@ static void zipit_lcd_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 
-    k->realize = zipit_lcd_realize;
+    k->init = zipit_lcd_init;
     k->transfer = zipit_lcd_transfer;
     dc->vmsd = &vmstate_zipit_lcd_state;
 }
index 30690f9..caf97c1 100644 (file)
@@ -145,15 +145,16 @@ static const VMStateDescription vmstate_cs4231 = {
     }
 };
 
-static void cs4231_init(Object *obj)
+static int cs4231_init1(SysBusDevice *dev)
 {
-    CSState *s = CS4231(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    CSState *s = CS4231(dev);
 
-    memory_region_init_io(&s->iomem, obj, &cs_mem_ops, s, "cs4321",
+    memory_region_init_io(&s->iomem, OBJECT(s), &cs_mem_ops, s, "cs4321",
                           CS_SIZE);
     sysbus_init_mmio(dev, &s->iomem);
     sysbus_init_irq(dev, &s->irq);
+
+    return 0;
 }
 
 static Property cs4231_properties[] = {
@@ -163,7 +164,9 @@ static Property cs4231_properties[] = {
 static void cs4231_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = cs4231_init1;
     dc->reset = cs_reset;
     dc->vmsd = &vmstate_cs4231;
     dc->props = cs4231_properties;
@@ -173,7 +176,6 @@ static const TypeInfo cs4231_info = {
     .name          = TYPE_CS4231,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(CSState),
-    .instance_init = cs4231_init,
     .class_init    = cs4231_class_init,
 };
 
index fdda7f9..24ba5f4 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef FMOPL_H
-#define FMOPL_H
+#ifndef __FMOPL_H_
+#define __FMOPL_H_
 
 /* --- select emulation chips --- */
 #define BUILD_YM3812 (HAS_YM3812)
index 6c02646..9dd6947 100644 (file)
@@ -144,7 +144,7 @@ static void GUS_callback (void *opaque, int free)
     s->left = samples;
 
  reset:
-    gus_irqgen (&s->emu, (uint64_t)net * 1000000 / s->freq);
+    gus_irqgen (&s->emu, muldiv64 (net, 1000000, s->freq));
 }
 
 int GUS_irqrequest (GUSEmuState *emu, int hwirq, int n)
index 9aec7bf..b7f0751 100644 (file)
@@ -101,4 +101,4 @@ void gus_irqgen(GUSEmuState *state, unsigned int elapsed_time);
 /* lower values won´t provide any benefit at all, higher values can cause audible timing delays */
 /* note: masked timers are also calculated by this function, thus it might be needed even without any IRQs in use! */
 
-#endif /* GUSEMU_H */
+#endif  /* gusemu.h */
index d162971..ece903a 100644 (file)
 
 #define gusdataend (VSRegsEnd+4)
 
-#endif /* GUSTATE_H */
+#endif  /* gustate.h */
index cd95340..d372d4a 100644 (file)
@@ -26,7 +26,6 @@
 #include "intel-hda.h"
 #include "intel-hda-defs.h"
 #include "sysemu/dma.h"
-#include "qapi/error.h"
 
 /* --------------------------------------------------------------------- */
 /* hda bus                                                               */
@@ -51,28 +50,25 @@ void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, size_t bus_size,
     bus->xfer = xfer;
 }
 
-static void hda_codec_dev_realize(DeviceState *qdev, Error **errp)
+static int hda_codec_dev_init(DeviceState *qdev)
 {
-    HDACodecBus *bus = HDA_BUS(qdev->parent_bus);
-    HDACodecDevice *dev = HDA_CODEC_DEVICE(qdev);
+    HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, qdev->parent_bus);
+    HDACodecDevice *dev = DO_UPCAST(HDACodecDevice, qdev, qdev);
     HDACodecDeviceClass *cdc = HDA_CODEC_DEVICE_GET_CLASS(dev);
 
     if (dev->cad == -1) {
         dev->cad = bus->next_cad;
     }
     if (dev->cad >= 15) {
-        error_setg(errp, "HDA audio codec address is full");
-        return;
+        return -1;
     }
     bus->next_cad = dev->cad + 1;
-    if (cdc->init(dev) != 0) {
-        error_setg(errp, "HDA audio init failed");
-    }
+    return cdc->init(dev);
 }
 
 static int hda_codec_dev_exit(DeviceState *qdev)
 {
-    HDACodecDevice *dev = HDA_CODEC_DEVICE(qdev);
+    HDACodecDevice *dev = DO_UPCAST(HDACodecDevice, qdev, qdev);
     HDACodecDeviceClass *cdc = HDA_CODEC_DEVICE_GET_CLASS(dev);
 
     if (cdc->exit) {
@@ -88,7 +84,7 @@ HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad)
 
     QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
         DeviceState *qdev = kid->child;
-        cdev = HDA_CODEC_DEVICE(qdev);
+        cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
         if (cdev->cad == cad) {
             return cdev;
         }
@@ -98,14 +94,14 @@ HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad)
 
 void hda_codec_response(HDACodecDevice *dev, bool solicited, uint32_t response)
 {
-    HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
+    HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, dev->qdev.parent_bus);
     bus->response(dev, solicited, response);
 }
 
 bool hda_codec_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
                     uint8_t *buf, uint32_t len)
 {
-    HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
+    HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, dev->qdev.parent_bus);
     return bus->xfer(dev, stnr, output, buf, len);
 }
 
@@ -191,7 +187,7 @@ struct IntelHDAState {
 
     /* properties */
     uint32_t debug;
-    OnOffAuto msi;
+    uint32_t msi;
     bool old_msi_addr;
 };
 
@@ -219,7 +215,10 @@ static void intel_hda_reset(DeviceState *dev);
 
 static hwaddr intel_hda_addr(uint32_t lbase, uint32_t ubase)
 {
-    return ((uint64_t)ubase << 32) | lbase;
+    hwaddr addr;
+
+    addr = ((uint64_t)ubase << 32) | lbase;
+    return addr;
 }
 
 static void intel_hda_update_int_sts(IntelHDAState *d)
@@ -256,7 +255,7 @@ static void intel_hda_update_int_sts(IntelHDAState *d)
 
 static void intel_hda_update_irq(IntelHDAState *d)
 {
-    bool msi = msi_enabled(&d->pci);
+    int msi = d->msi && msi_enabled(&d->pci);
     int level;
 
     intel_hda_update_int_sts(d);
@@ -338,7 +337,7 @@ static void intel_hda_corb_run(IntelHDAState *d)
 
 static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t response)
 {
-    HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
+    HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, dev->qdev.parent_bus);
     IntelHDAState *d = container_of(bus, IntelHDAState, codecs);
     hwaddr addr;
     uint32_t wp, ex;
@@ -387,7 +386,7 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
 static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
                            uint8_t *buf, uint32_t len)
 {
-    HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus);
+    HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, dev->qdev.parent_bus);
     IntelHDAState *d = container_of(bus, IntelHDAState, codecs);
     hwaddr addr;
     uint32_t s, copy, left;
@@ -494,7 +493,7 @@ static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool runn
         DeviceState *qdev = kid->child;
         HDACodecDeviceClass *cdc;
 
-        cdev = HDA_CODEC_DEVICE(qdev);
+        cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
         cdc = HDA_CODEC_DEVICE_GET_CLASS(cdev);
         if (cdc->stream) {
             cdc->stream(cdev, stream, running, output);
@@ -1121,7 +1120,7 @@ static void intel_hda_reset(DeviceState *dev)
     /* reset codecs */
     QTAILQ_FOREACH(kid, &d->codecs.qbus.children, sibling) {
         DeviceState *qdev = kid->child;
-        cdev = HDA_CODEC_DEVICE(qdev);
+        cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
         device_reset(DEVICE(cdev));
         d->state_sts |= (1 << cdev->cad);
     }
@@ -1132,8 +1131,6 @@ static void intel_hda_realize(PCIDevice *pci, Error **errp)
 {
     IntelHDAState *d = INTEL_HDA(pci);
     uint8_t *conf = d->pci.config;
-    Error *err = NULL;
-    int ret;
 
     d->name = object_get_typename(OBJECT(d));
 
@@ -1142,27 +1139,12 @@ static void intel_hda_realize(PCIDevice *pci, Error **errp)
     /* HDCTL off 0x40 bit 0 selects signaling mode (1-HDA, 0 - Ac97) 18.1.19 */
     conf[0x40] = 0x01;
 
-    if (d->msi != ON_OFF_AUTO_OFF) {
-        ret = msi_init(&d->pci, d->old_msi_addr ? 0x50 : 0x60,
-                       1, true, false, &err);
-        /* Any error other than -ENOTSUP(board's MSI support is broken)
-         * is a programming error */
-        assert(!ret || ret == -ENOTSUP);
-        if (ret && d->msi == ON_OFF_AUTO_ON) {
-            /* Can't satisfy user's explicit msi=on request, fail */
-            error_append_hint(&err, "You have to use msi=auto (default) or "
-                    "msi=off with this machine type.\n");
-            error_propagate(errp, err);
-            return;
-        }
-        assert(!err || d->msi == ON_OFF_AUTO_AUTO);
-        /* With msi=auto, we fall back to MSI off silently */
-        error_free(err);
-    }
-
     memory_region_init_io(&d->mmio, OBJECT(d), &intel_hda_mmio_ops, d,
                           "intel-hda", 0x4000);
     pci_register_bar(&d->pci, 0, 0, &d->mmio);
+    if (d->msi) {
+        msi_init(&d->pci, d->old_msi_addr ? 0x50 : 0x60, 1, true, false);
+    }
 
     hda_codec_bus_init(DEVICE(pci), &d->codecs, sizeof(d->codecs),
                        intel_hda_response, intel_hda_xfer);
@@ -1252,7 +1234,7 @@ static const VMStateDescription vmstate_intel_hda = {
 
 static Property intel_hda_properties[] = {
     DEFINE_PROP_UINT32("debug", IntelHDAState, debug, 0),
-    DEFINE_PROP_ON_OFF_AUTO("msi", IntelHDAState, msi, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_UINT32("msi", IntelHDAState, msi, 1),
     DEFINE_PROP_BOOL("old_msi_addr", IntelHDAState, old_msi_addr, false),
     DEFINE_PROP_END_OF_LIST(),
 };
@@ -1316,7 +1298,7 @@ static const TypeInfo intel_hda_info_ich9 = {
 static void hda_codec_device_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *k = DEVICE_CLASS(klass);
-    k->realize = hda_codec_dev_realize;
+    k->init = hda_codec_dev_init;
     k->exit = hda_codec_dev_exit;
     set_bit(DEVICE_CATEGORY_SOUND, k->categories);
     k->bus_type = TYPE_HDA_BUS;
index 74c3ee8..812a7a4 100644 (file)
@@ -40,4 +40,4 @@ uint32_t lm4549_read(lm4549_state *s, hwaddr offset);
 void lm4549_write(lm4549_state *s, hwaddr offset, uint32_t value);
 uint32_t lm4549_write_samples(lm4549_state *s, uint32_t left, uint32_t right);
 
-#endif /* HW_LM4549_H */
+#endif /* #ifndef HW_LM4549_H */
index bc8db71..6a3b536 100644 (file)
@@ -18,7 +18,7 @@
  *
  *
  * Specification available at:
- *   http://milkymist.walle.cc/socdoc/ac97.pdf
+ *   http://www.milkymist.org/socdoc/ac97.pdf
  */
 
 #include "qemu/osdep.h"
@@ -284,26 +284,16 @@ static int ac97_post_load(void *opaque, int version_id)
     return 0;
 }
 
-static void milkymist_ac97_init(Object *obj)
+static int milkymist_ac97_init(SysBusDevice *dev)
 {
-    MilkymistAC97State *s = MILKYMIST_AC97(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    MilkymistAC97State *s = MILKYMIST_AC97(dev);
 
+    struct audsettings as;
     sysbus_init_irq(dev, &s->crrequest_irq);
     sysbus_init_irq(dev, &s->crreply_irq);
     sysbus_init_irq(dev, &s->dmar_irq);
     sysbus_init_irq(dev, &s->dmaw_irq);
 
-    memory_region_init_io(&s->regs_region, obj, &ac97_mmio_ops, s,
-            "milkymist-ac97", R_MAX * 4);
-    sysbus_init_mmio(dev, &s->regs_region);
-}
-
-static void milkymist_ac97_realize(DeviceState *dev, Error **errp)
-{
-    MilkymistAC97State *s = MILKYMIST_AC97(dev);
-    struct audsettings as;
-
     AUD_register_card("Milkymist AC'97", &s->card);
 
     as.freq = 48000;
@@ -315,6 +305,12 @@ static void milkymist_ac97_realize(DeviceState *dev, Error **errp)
             "mm_ac97.in", s, ac97_in_cb, &as);
     s->voice_out = AUD_open_out(&s->card, s->voice_out,
             "mm_ac97.out", s, ac97_out_cb, &as);
+
+    memory_region_init_io(&s->regs_region, OBJECT(s), &ac97_mmio_ops, s,
+            "milkymist-ac97", R_MAX * 4);
+    sysbus_init_mmio(dev, &s->regs_region);
+
+    return 0;
 }
 
 static const VMStateDescription vmstate_milkymist_ac97 = {
@@ -331,8 +327,9 @@ static const VMStateDescription vmstate_milkymist_ac97 = {
 static void milkymist_ac97_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    dc->realize = milkymist_ac97_realize;
+    k->init = milkymist_ac97_init;
     dc->reset = milkymist_ac97_reset;
     dc->vmsd = &vmstate_milkymist_ac97;
 }
@@ -341,7 +338,6 @@ static const TypeInfo milkymist_ac97_info = {
     .name          = TYPE_MILKYMIST_AC97,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(MilkymistAC97State),
-    .instance_init = milkymist_ac97_init,
     .class_init    = milkymist_ac97_class_init,
 };
 
index 42a6f48..f9afc8e 100644 (file)
 #include "qemu/timer.h"
 #include "hw/timer/i8254.h"
 #include "hw/audio/pcspk.h"
-#include "qapi/error.h"
 
 #define PCSPK_BUF_LEN 1792
 #define PCSPK_SAMPLE_RATE 32000
 #define PCSPK_MAX_FREQ (PCSPK_SAMPLE_RATE >> 1)
-#define PCSPK_MIN_COUNT DIV_ROUND_UP(PIT_FREQ, PCSPK_MAX_FREQ)
+#define PCSPK_MIN_COUNT ((PIT_FREQ + PCSPK_MAX_FREQ - 1) / PCSPK_MAX_FREQ)
 
 #define PC_SPEAKER(obj) OBJECT_CHECK(PCSpkState, (obj), TYPE_PC_SPEAKER)
 
@@ -170,11 +169,6 @@ static void pcspk_initfn(Object *obj)
     PCSpkState *s = PC_SPEAKER(obj);
 
     memory_region_init_io(&s->ioport, OBJECT(s), &pcspk_io_ops, s, "pcspk", 1);
-
-    object_property_add_link(obj, "pit", TYPE_PIT_COMMON,
-                             (Object **)&s->pit,
-                             qdev_prop_allow_set_link_before_realize,
-                             0, &error_abort);
 }
 
 static void pcspk_realizefn(DeviceState *dev, Error **errp)
@@ -189,6 +183,7 @@ static void pcspk_realizefn(DeviceState *dev, Error **errp)
 
 static Property pcspk_properties[] = {
     DEFINE_PROP_UINT32("iobase", PCSpkState, iobase,  -1),
+    DEFINE_PROP_PTR("pit", PCSpkState, pit),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -199,7 +194,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data)
     dc->realize = pcspk_realizefn;
     set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
     dc->props = pcspk_properties;
-    /* Reason: realize sets global pcspk_state */
+    /* Reason: pointer property "pit", realize sets global pcspk_state */
     dc->cannot_instantiate_with_device_add_yet = true;
 }
 
index 6e9c104..4717bc9 100644 (file)
@@ -22,7 +22,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
-#include "qemu/log.h"
 
 #include "pl041.h"
 #include "lm4549.h"
index 515db47..427ab6d 100644 (file)
@@ -132,4 +132,4 @@ enum {
 #define RXTOFEC3     (1 << 11)
 #define RXTOFEC4     (1 << 12)
 
-#endif /* HW_PL041_H */
+#endif /* #ifndef HW_PL041_H */
diff --git a/hw/audio/trace-events b/hw/audio/trace-events
deleted file mode 100644 (file)
index 3210386..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/audio/cs4231.c
-cs4231_mem_readl_dreg(uint32_t reg, uint32_t ret) "read dreg %d: 0x%02x"
-cs4231_mem_readl_reg(uint32_t reg, uint32_t ret) "read reg %d: 0x%08x"
-cs4231_mem_writel_reg(uint32_t reg, uint32_t old, uint32_t val) "write reg %d: 0x%08x -> 0x%08x"
-cs4231_mem_writel_dreg(uint32_t reg, uint32_t old, uint32_t val) "write dreg %d: 0x%02x -> 0x%02x"
-
-# hw/audio/milkymist-ac97.c
-milkymist_ac97_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_ac97_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_ac97_pulse_irq_crrequest(void) "Pulse IRQ CR request"
-milkymist_ac97_pulse_irq_crreply(void) "Pulse IRQ CR reply"
-milkymist_ac97_pulse_irq_dmaw(void) "Pulse IRQ DMA write"
-milkymist_ac97_pulse_irq_dmar(void) "Pulse IRQ DMA read"
-milkymist_ac97_in_cb(int avail, uint32_t remaining) "avail %d remaining %u"
-milkymist_ac97_in_cb_transferred(int transferred) "transferred %d"
-milkymist_ac97_out_cb(int free, uint32_t remaining) "free %d remaining %u"
-milkymist_ac97_out_cb_transferred(int transferred) "transferred %d"
index 8dc9d84..97a59d4 100644 (file)
@@ -51,34 +51,6 @@ void blkconf_blocksizes(BlockConf *conf)
     }
 }
 
-void blkconf_apply_backend_options(BlockConf *conf)
-{
-    BlockBackend *blk = conf->blk;
-    BlockdevOnError rerror, werror;
-    bool wce;
-
-    switch (conf->wce) {
-    case ON_OFF_AUTO_ON:    wce = true; break;
-    case ON_OFF_AUTO_OFF:   wce = false; break;
-    case ON_OFF_AUTO_AUTO:  wce = blk_enable_write_cache(blk); break;
-    default:
-        abort();
-    }
-
-    rerror = conf->rerror;
-    if (rerror == BLOCKDEV_ON_ERROR_AUTO) {
-        rerror = blk_get_on_error(blk, true);
-    }
-
-    werror = conf->werror;
-    if (werror == BLOCKDEV_ON_ERROR_AUTO) {
-        werror = blk_get_on_error(blk, false);
-    }
-
-    blk_set_enable_write_cache(blk, wce);
-    blk_set_on_error(blk, rerror, werror);
-}
-
 void blkconf_geometry(BlockConf *conf, int *ptrans,
                       unsigned cyls_max, unsigned heads_max, unsigned secs_max,
                       Error **errp)
index 704a763..3cb97c9 100644 (file)
@@ -31,9 +31,13 @@ struct VirtIOBlockDataPlane {
     bool stopping;
 
     VirtIOBlkConf *conf;
+
     VirtIODevice *vdev;
+    VirtQueue *vq;                  /* virtqueue vring */
+    EventNotifier *guest_notifier;  /* irq */
     QEMUBH *bh;                     /* bh for guest notification */
-    unsigned long *batch_notify_vqs;
+
+    Notifier insert_notifier, remove_notifier;
 
     /* Note that these EventNotifiers are assigned by value.  This is
      * fine as long as you do not call event_notifier_cleanup on them
@@ -42,41 +46,76 @@ struct VirtIOBlockDataPlane {
      */
     IOThread *iothread;
     AioContext *ctx;
+
+    /* Operation blocker on BDS */
+    Error *blocker;
 };
 
 /* Raise an interrupt to signal guest, if necessary */
-void virtio_blk_data_plane_notify(VirtIOBlockDataPlane *s, VirtQueue *vq)
+void virtio_blk_data_plane_notify(VirtIOBlockDataPlane *s)
 {
-    set_bit(virtio_get_queue_index(vq), s->batch_notify_vqs);
     qemu_bh_schedule(s->bh);
 }
 
 static void notify_guest_bh(void *opaque)
 {
     VirtIOBlockDataPlane *s = opaque;
-    unsigned nvqs = s->conf->num_queues;
-    unsigned long bitmap[BITS_TO_LONGS(nvqs)];
-    unsigned j;
-
-    memcpy(bitmap, s->batch_notify_vqs, sizeof(bitmap));
-    memset(s->batch_notify_vqs, 0, sizeof(bitmap));
 
-    for (j = 0; j < nvqs; j += BITS_PER_LONG) {
-        unsigned long bits = bitmap[j];
+    if (!virtio_should_notify(s->vdev, s->vq)) {
+        return;
+    }
 
-        while (bits != 0) {
-            unsigned i = j + ctzl(bits);
-            VirtQueue *vq = virtio_get_queue(s->vdev, i);
+    event_notifier_set(s->guest_notifier);
+}
 
-            if (virtio_should_notify(s->vdev, vq)) {
-                event_notifier_set(virtio_queue_get_guest_notifier(vq));
-            }
+static void data_plane_set_up_op_blockers(VirtIOBlockDataPlane *s)
+{
+    assert(!s->blocker);
+    error_setg(&s->blocker, "block device is in use by data plane");
+    blk_op_block_all(s->conf->conf.blk, s->blocker);
+    blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_RESIZE, s->blocker);
+    blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker);
+    blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_BACKUP_SOURCE, s->blocker);
+    blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_CHANGE, s->blocker);
+    blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_COMMIT_SOURCE, s->blocker);
+    blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_COMMIT_TARGET, s->blocker);
+    blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_EJECT, s->blocker);
+    blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT,
+                   s->blocker);
+    blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT,
+                   s->blocker);
+    blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE,
+                   s->blocker);
+    blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_MIRROR_SOURCE, s->blocker);
+    blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_STREAM, s->blocker);
+    blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_REPLACE, s->blocker);
+}
 
-            bits &= bits - 1; /* clear right-most bit */
-        }
+static void data_plane_remove_op_blockers(VirtIOBlockDataPlane *s)
+{
+    if (s->blocker) {
+        blk_op_unblock_all(s->conf->conf.blk, s->blocker);
+        error_free(s->blocker);
+        s->blocker = NULL;
     }
 }
 
+static void data_plane_blk_insert_notifier(Notifier *n, void *data)
+{
+    VirtIOBlockDataPlane *s = container_of(n, VirtIOBlockDataPlane,
+                                           insert_notifier);
+    assert(s->conf->conf.blk == data);
+    data_plane_set_up_op_blockers(s);
+}
+
+static void data_plane_blk_remove_notifier(Notifier *n, void *data)
+{
+    VirtIOBlockDataPlane *s = container_of(n, VirtIOBlockDataPlane,
+                                           remove_notifier);
+    assert(s->conf->conf.blk == data);
+    data_plane_remove_op_blockers(s);
+}
+
 /* Context: QEMU global mutex held */
 void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
                                   VirtIOBlockDataPlane **dataplane,
@@ -93,7 +132,7 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
     }
 
     /* Don't try if transport does not support notifiers. */
-    if (!k->set_guest_notifiers || !k->ioeventfd_started) {
+    if (!k->set_guest_notifiers || !k->set_host_notifier) {
         error_setg(errp,
                    "device is incompatible with dataplane "
                    "(transport does not support notifiers)");
@@ -112,11 +151,19 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
     s->vdev = vdev;
     s->conf = conf;
 
-    s->iothread = conf->iothread;
-    object_ref(OBJECT(s->iothread));
+    if (conf->iothread) {
+        s->iothread = conf->iothread;
+        object_ref(OBJECT(s->iothread));
+    }
     s->ctx = iothread_get_aio_context(s->iothread);
     s->bh = aio_bh_new(s->ctx, notify_guest_bh, s);
-    s->batch_notify_vqs = bitmap_new(conf->num_queues);
+
+    s->insert_notifier.notify = data_plane_blk_insert_notifier;
+    s->remove_notifier.notify = data_plane_blk_remove_notifier;
+    blk_add_insert_bs_notifier(conf->conf.blk, &s->insert_notifier);
+    blk_add_remove_bs_notifier(conf->conf.blk, &s->remove_notifier);
+
+    data_plane_set_up_op_blockers(s);
 
     *dataplane = s;
 }
@@ -129,7 +176,9 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
     }
 
     virtio_blk_data_plane_stop(s);
-    g_free(s->batch_notify_vqs);
+    data_plane_remove_op_blockers(s);
+    notifier_remove(&s->insert_notifier);
+    notifier_remove(&s->remove_notifier);
     qemu_bh_delete(s->bh);
     object_unref(OBJECT(s->iothread));
     g_free(s);
@@ -152,8 +201,6 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
     BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s->vdev)));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
     VirtIOBlock *vblk = VIRTIO_BLK(s->vdev);
-    unsigned i;
-    unsigned nvqs = s->conf->num_queues;
     int r;
 
     if (vblk->dataplane_started || s->starting) {
@@ -161,25 +208,22 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
     }
 
     s->starting = true;
+    s->vq = virtio_get_queue(s->vdev, 0);
 
     /* Set up guest notifier (irq) */
-    r = k->set_guest_notifiers(qbus->parent, nvqs, true);
+    r = k->set_guest_notifiers(qbus->parent, 1, true);
     if (r != 0) {
         fprintf(stderr, "virtio-blk failed to set guest notifier (%d), "
                 "ensure -enable-kvm is set\n", r);
         goto fail_guest_notifiers;
     }
+    s->guest_notifier = virtio_queue_get_guest_notifier(s->vq);
 
     /* Set up virtqueue notify */
-    for (i = 0; i < nvqs; i++) {
-        r = virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, true);
-        if (r != 0) {
-            fprintf(stderr, "virtio-blk failed to set host notifier (%d)\n", r);
-            while (i--) {
-                virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
-            }
-            goto fail_guest_notifiers;
-        }
+    r = k->set_host_notifier(qbus->parent, 0, true);
+    if (r != 0) {
+        fprintf(stderr, "virtio-blk failed to set host notifier (%d)\n", r);
+        goto fail_host_notifier;
     }
 
     s->starting = false;
@@ -189,23 +233,17 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
     blk_set_aio_context(s->conf->conf.blk, s->ctx);
 
     /* Kick right away to begin processing requests already in vring */
-    for (i = 0; i < nvqs; i++) {
-        VirtQueue *vq = virtio_get_queue(s->vdev, i);
-
-        event_notifier_set(virtio_queue_get_host_notifier(vq));
-    }
+    event_notifier_set(virtio_queue_get_host_notifier(s->vq));
 
     /* Get this show started by hooking up our callbacks */
     aio_context_acquire(s->ctx);
-    for (i = 0; i < nvqs; i++) {
-        VirtQueue *vq = virtio_get_queue(s->vdev, i);
-
-        virtio_queue_aio_set_host_notifier_handler(vq, s->ctx,
-                virtio_blk_data_plane_handle_output);
-    }
+    virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx,
+                                               virtio_blk_data_plane_handle_output);
     aio_context_release(s->ctx);
     return;
 
+  fail_host_notifier:
+    k->set_guest_notifiers(qbus->parent, 1, false);
   fail_guest_notifiers:
     vblk->dataplane_disabled = true;
     s->starting = false;
@@ -218,8 +256,6 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
     BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s->vdev)));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
     VirtIOBlock *vblk = VIRTIO_BLK(s->vdev);
-    unsigned i;
-    unsigned nvqs = s->conf->num_queues;
 
     if (!vblk->dataplane_started || s->stopping) {
         return;
@@ -237,23 +273,17 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
     aio_context_acquire(s->ctx);
 
     /* Stop notifications for new requests from guest */
-    for (i = 0; i < nvqs; i++) {
-        VirtQueue *vq = virtio_get_queue(s->vdev, i);
-
-        virtio_queue_aio_set_host_notifier_handler(vq, s->ctx, NULL);
-    }
+    virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx, NULL);
 
     /* Drain and switch bs back to the QEMU main loop */
     blk_set_aio_context(s->conf->conf.blk, qemu_get_aio_context());
 
     aio_context_release(s->ctx);
 
-    for (i = 0; i < nvqs; i++) {
-        virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
-    }
+    k->set_host_notifier(qbus->parent, 0, false);
 
     /* Clean up guest notifier (irq) */
-    k->set_guest_notifiers(qbus->parent, nvqs, false);
+    k->set_guest_notifiers(qbus->parent, 1, false);
 
     vblk->dataplane_started = false;
     s->stopping = false;
index b1f0b95..0714c11 100644 (file)
@@ -26,6 +26,6 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s);
 void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s);
 void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s);
 void virtio_blk_data_plane_drain(VirtIOBlockDataPlane *s);
-void virtio_blk_data_plane_notify(VirtIOBlockDataPlane *s, VirtQueue *vq);
+void virtio_blk_data_plane_notify(VirtIOBlockDataPlane *s);
 
 #endif /* HW_DATAPLANE_VIRTIO_BLK_H */
index f73af7d..3722275 100644 (file)
@@ -223,13 +223,6 @@ static int fd_sector(FDrive *drv)
                           NUM_SIDES(drv));
 }
 
-/* Returns current position, in bytes, for given drive */
-static int fd_offset(FDrive *drv)
-{
-    g_assert(fd_sector(drv) < INT_MAX >> BDRV_SECTOR_BITS);
-    return fd_sector(drv) << BDRV_SECTOR_BITS;
-}
-
 /* Seek to a new position:
  * returns 0 if already on right track
  * returns 1 if track changed
@@ -1636,8 +1629,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan,
         if (fdctrl->data_dir != FD_DIR_WRITE ||
             len < FD_SECTOR_LEN || rel_pos != 0) {
             /* READ & SCAN commands and realign to a sector for WRITE */
-            if (blk_pread(cur_drv->blk, fd_offset(cur_drv),
-                          fdctrl->fifo, BDRV_SECTOR_SIZE) < 0) {
+            if (blk_read(cur_drv->blk, fd_sector(cur_drv),
+                         fdctrl->fifo, 1) < 0) {
                 FLOPPY_DPRINTF("Floppy: error getting sector %d\n",
                                fd_sector(cur_drv));
                 /* Sure, image size is too small... */
@@ -1664,8 +1657,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan,
 
             k->read_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos,
                            fdctrl->data_pos, len);
-            if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv),
-                           fdctrl->fifo, BDRV_SECTOR_SIZE, 0) < 0) {
+            if (blk_write(cur_drv->blk, fd_sector(cur_drv),
+                          fdctrl->fifo, 1) < 0) {
                 FLOPPY_DPRINTF("error writing sector %d\n",
                                fd_sector(cur_drv));
                 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
@@ -1748,8 +1741,7 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
                                    fd_sector(cur_drv));
                     return 0;
                 }
-            if (blk_pread(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
-                          BDRV_SECTOR_SIZE)
+            if (blk_read(cur_drv->blk, fd_sector(cur_drv), fdctrl->fifo, 1)
                 < 0) {
                 FLOPPY_DPRINTF("error getting sector %d\n",
                                fd_sector(cur_drv));
@@ -1828,8 +1820,7 @@ static void fdctrl_format_sector(FDCtrl *fdctrl)
     }
     memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
     if (cur_drv->blk == NULL ||
-        blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
-                   BDRV_SECTOR_SIZE, 0) < 0) {
+        blk_write(cur_drv->blk, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
         FLOPPY_DPRINTF("error formatting sector %d\n", fd_sector(cur_drv));
         fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
     } else {
@@ -2252,8 +2243,8 @@ static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
         if (pos == FD_SECTOR_LEN - 1 ||
             fdctrl->data_pos == fdctrl->data_len) {
             cur_drv = get_cur_drv(fdctrl);
-            if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
-                           BDRV_SECTOR_SIZE, 0) < 0) {
+            if (blk_write(cur_drv->blk, fd_sector(cur_drv), fdctrl->fifo, 1)
+                < 0) {
                 FLOPPY_DPRINTF("error writing sector %d\n",
                                fd_sector(cur_drv));
                 break;
index 57ad501..6d02192 100644 (file)
@@ -32,7 +32,6 @@
 
 #include "qemu/osdep.h"
 #include "sysemu/block-backend.h"
-#include "qemu/bswap.h"
 #include "hw/block/block.h"
 #include "trace.h"
 
@@ -67,7 +66,7 @@ static int guess_disk_lchs(BlockBackend *blk,
      * but also in async I/O mode. So the I/O throttling function has to
      * be disabled temporarily here, not permanently.
      */
-    if (blk_pread_unthrottled(blk, 0, buf, BDRV_SECTOR_SIZE) < 0) {
+    if (blk_read_unthrottled(blk, 0, buf, 1) < 0) {
         return -1;
     }
     /* test msdos magic */
index 9828ee6..906b712 100644 (file)
@@ -27,8 +27,6 @@
 #include "sysemu/blockdev.h"
 #include "hw/ssi/ssi.h"
 #include "qemu/bitops.h"
-#include "qemu/log.h"
-#include "qapi/error.h"
 
 #ifndef M25P80_ERR_DEBUG
 #define M25P80_ERR_DEBUG 0
 /* 16 MiB max in 3 byte address mode */
 #define MAX_3BYTES_SIZE 0x1000000
 
-#define SPI_NOR_MAX_ID_LEN 6
-
 typedef struct FlashPartInfo {
     const char *part_name;
-    /*
-     * This array stores the ID bytes.
-     * The first three bytes are the JEDIC ID.
-     * JEDEC ID zero means "no ID" (mostly older chips).
-     */
-    uint8_t id[SPI_NOR_MAX_ID_LEN];
-    uint8_t id_len;
+    /* jedec code. (jedec >> 16) & 0xff is the 1st byte, >> 8 the 2nd etc */
+    uint32_t jedec;
+    /* extended jedec code */
+    uint16_t ext_jedec;
     /* there is confusion between manufacturers as to what a sector is. In this
      * device model, a "sector" is the size that is erased by the ERASE_SECTOR
      * command (opcode 0xd8).
@@ -76,33 +69,11 @@ typedef struct FlashPartInfo {
 } FlashPartInfo;
 
 /* adapted from linux */
-/* Used when the "_ext_id" is two bytes at most */
-#define INFO(_part_name, _jedec_id, _ext_id, _sector_size, _n_sectors, _flags)\
-    .part_name = _part_name,\
-    .id = {\
-        ((_jedec_id) >> 16) & 0xff,\
-        ((_jedec_id) >> 8) & 0xff,\
-        (_jedec_id) & 0xff,\
-        ((_ext_id) >> 8) & 0xff,\
-        (_ext_id) & 0xff,\
-          },\
-    .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),\
-    .sector_size = (_sector_size),\
-    .n_sectors = (_n_sectors),\
-    .page_size = 256,\
-    .flags = (_flags),
-
-#define INFO6(_part_name, _jedec_id, _ext_id, _sector_size, _n_sectors, _flags)\
-    .part_name = _part_name,\
-    .id = {\
-        ((_jedec_id) >> 16) & 0xff,\
-        ((_jedec_id) >> 8) & 0xff,\
-        (_jedec_id) & 0xff,\
-        ((_ext_id) >> 16) & 0xff,\
-        ((_ext_id) >> 8) & 0xff,\
-        (_ext_id) & 0xff,\
-          },\
-    .id_len = 6,\
+
+#define INFO(_part_name, _jedec, _ext_jedec, _sector_size, _n_sectors, _flags)\
+    .part_name = (_part_name),\
+    .jedec = (_jedec),\
+    .ext_jedec = (_ext_jedec),\
     .sector_size = (_sector_size),\
     .n_sectors = (_n_sectors),\
     .page_size = 256,\
@@ -130,27 +101,12 @@ typedef struct FlashPartInfo {
 #define EVCFG_QUAD_IO_ENABLED (1 << 7)
 #define NVCFG_4BYTE_ADDR_MASK (1 << 0)
 #define NVCFG_LOWER_SEGMENT_MASK (1 << 1)
+#define CFG_UPPER_128MB_SEG_ENABLED 0x3
 
 /* Numonyx (Micron) Flag Status Register macros */
 #define FSR_4BYTE_ADDR_MODE_ENABLED 0x1
 #define FSR_FLASH_READY (1 << 7)
 
-/* Spansion configuration registers macros. */
-#define SPANSION_QUAD_CFG_POS 0
-#define SPANSION_QUAD_CFG_LEN 1
-#define SPANSION_DUMMY_CLK_POS 0
-#define SPANSION_DUMMY_CLK_LEN 4
-#define SPANSION_ADDR_LEN_POS 7
-#define SPANSION_ADDR_LEN_LEN 1
-
-/*
- * Spansion read mode command length in bytes,
- * the mode is currently not supported.
-*/
-
-#define SPANSION_CONTINUOUS_READ_MODE_CMD_LEN 1
-#define WINBOND_CONTINUOUS_READ_MODE_CMD_LEN 1
-
 static const FlashPartInfo known_devices[] = {
     /* Atmel -- some are (confusingly) marketed as "DataFlash" */
     { INFO("at25fs010",   0x1f6601,      0,  32 << 10,   4, ER_4K) },
@@ -201,8 +157,6 @@ static const FlashPartInfo known_devices[] = {
     { INFO("mx25l12855e", 0xc22618,      0,  64 << 10, 256, 0) },
     { INFO("mx25l25635e", 0xc22019,      0,  64 << 10, 512, 0) },
     { INFO("mx25l25655e", 0xc22619,      0,  64 << 10, 512, 0) },
-    { INFO("mx66u51235f", 0xc2253a,      0,  64 << 10, 1024, ER_4K | ER_32K) },
-    { INFO("mx66u1g45g",  0xc2253b,      0,  64 << 10, 2048, ER_4K | ER_32K) },
 
     /* Micron */
     { INFO("n25q032a11",  0x20bb16,      0,  64 << 10,  64, ER_4K) },
@@ -213,11 +167,6 @@ static const FlashPartInfo known_devices[] = {
     { INFO("n25q128a13",  0x20ba18,      0,  64 << 10, 256, ER_4K) },
     { INFO("n25q256a11",  0x20bb19,      0,  64 << 10, 512, ER_4K) },
     { INFO("n25q256a13",  0x20ba19,      0,  64 << 10, 512, ER_4K) },
-    { INFO("n25q128",     0x20ba18,      0,  64 << 10, 256, 0) },
-    { INFO("n25q256a",    0x20ba19,      0,  64 << 10, 512, ER_4K) },
-    { INFO("n25q512a",    0x20ba20,      0,  64 << 10, 1024, ER_4K) },
-    { INFO("mt25ql01g",   0x20ba21,      0,  64 << 10, 2048, ER_4K) },
-    { INFO("mt25qu01g",   0x20bb21,      0,  64 << 10, 2048, ER_4K) },
 
     /* Spansion -- single (large) sector size only, at least
      * for the chips listed here (without boot sectors).
@@ -226,8 +175,8 @@ static const FlashPartInfo known_devices[] = {
     { INFO("s25sl064p",   0x010216, 0x4d00,  64 << 10, 128, ER_4K) },
     { INFO("s25fl256s0",  0x010219, 0x4d00, 256 << 10, 128, 0) },
     { INFO("s25fl256s1",  0x010219, 0x4d01,  64 << 10, 512, 0) },
-    { INFO6("s25fl512s",  0x010220, 0x4d0080, 256 << 10, 256, 0) },
-    { INFO6("s70fl01gs",  0x010221, 0x4d0080, 256 << 10, 512, 0) },
+    { INFO("s25fl512s",   0x010220, 0x4d00, 256 << 10, 256, 0) },
+    { INFO("s70fl01gs",   0x010221, 0x4d00, 256 << 10, 256, 0) },
     { INFO("s25sl12800",  0x012018, 0x0300, 256 << 10,  64, 0) },
     { INFO("s25sl12801",  0x012018, 0x0301,  64 << 10, 256, 0) },
     { INFO("s25fl129p0",  0x012018, 0x4d00, 256 << 10,  64, 0) },
@@ -240,10 +189,6 @@ static const FlashPartInfo known_devices[] = {
     { INFO("s25fl016k",   0xef4015,      0,  64 << 10,  32, ER_4K | ER_32K) },
     { INFO("s25fl064k",   0xef4017,      0,  64 << 10, 128, ER_4K | ER_32K) },
 
-    /* Spansion --  boot sectors support  */
-    { INFO6("s25fs512s",    0x010220, 0x4d0081, 256 << 10, 256, 0) },
-    { INFO6("s70fs01gs",    0x010221, 0x4d0081, 256 << 10, 512, 0) },
-
     /* SST -- large erase sizes are "overlays", "sectors" are 4<< 10 */
     { INFO("sst25vf040b", 0xbf258d,      0,  64 << 10,   8, ER_4K) },
     { INFO("sst25vf080b", 0xbf258e,      0,  64 << 10,  16, ER_4K) },
@@ -294,6 +239,10 @@ static const FlashPartInfo known_devices[] = {
     { INFO("w25q80",      0xef5014,      0,  64 << 10,  16, ER_4K) },
     { INFO("w25q80bl",    0xef4014,      0,  64 << 10,  16, ER_4K) },
     { INFO("w25q256",     0xef4019,      0,  64 << 10, 512, ER_4K) },
+
+    { INFO("n25q128",      0x20ba18,      0,  64 << 10, 256, 0) },
+    { INFO("n25q256a",     0x20ba19,      0,  64 << 10, 512, ER_4K) },
+    { INFO("n25q512a",     0x20ba20,      0,  64 << 10, 1024, ER_4K) },
 };
 
 typedef enum {
@@ -305,7 +254,6 @@ typedef enum {
     JEDEC_READ = 0x9f,
     BULK_ERASE = 0xc7,
     READ_FSR = 0x70,
-    RDCR = 0x15,
 
     READ = 0x03,
     READ4 = 0x13,
@@ -322,14 +270,12 @@ typedef enum {
 
     PP = 0x02,
     PP4 = 0x12,
-    PP4_4 = 0x3e,
     DPP = 0xa2,
     QPP = 0x32,
 
     ERASE_4K = 0x20,
     ERASE4_4K = 0x21,
     ERASE_32K = 0x52,
-    ERASE4_32K = 0x5c,
     ERASE_SECTOR = 0xd8,
     ERASE4_SECTOR = 0xdc,
 
@@ -342,13 +288,6 @@ typedef enum {
     RESET_ENABLE = 0x66,
     RESET_MEMORY = 0x99,
 
-    /*
-     * Micron: 0x35 - enable QPI
-     * Spansion: 0x35 - read control register
-     */
-    RDCR_EQIO = 0x35,
-    RSTQIO = 0xf5,
-
     RNVCR = 0xB5,
     WNVCR = 0xB1,
 
@@ -364,18 +303,9 @@ typedef enum {
     STATE_PAGE_PROGRAM,
     STATE_READ,
     STATE_COLLECTING_DATA,
-    STATE_COLLECTING_VAR_LEN_DATA,
     STATE_READING_DATA,
 } CMDState;
 
-typedef enum {
-    MAN_SPANSION,
-    MAN_MACRONIX,
-    MAN_NUMONYX,
-    MAN_WINBOND,
-    MAN_GENERIC,
-} Manufacturer;
-
 typedef struct Flash {
     SSISlave parent_obj;
 
@@ -391,24 +321,13 @@ typedef struct Flash {
     uint32_t pos;
     uint8_t needed_bytes;
     uint8_t cmd_in_progress;
-    uint32_t cur_addr;
+    uint64_t cur_addr;
     uint32_t nonvolatile_cfg;
-    /* Configuration register for Macronix */
     uint32_t volatile_cfg;
     uint32_t enh_volatile_cfg;
-    /* Spansion cfg registers. */
-    uint8_t spansion_cr1nv;
-    uint8_t spansion_cr2nv;
-    uint8_t spansion_cr3nv;
-    uint8_t spansion_cr4nv;
-    uint8_t spansion_cr1v;
-    uint8_t spansion_cr2v;
-    uint8_t spansion_cr3v;
-    uint8_t spansion_cr4v;
     bool write_enable;
     bool four_bytes_address_mode;
     bool reset_enable;
-    bool quad_enable;
     uint8_t ear;
 
     int64_t dirty_page;
@@ -430,29 +349,8 @@ typedef struct M25P80Class {
 #define M25P80_GET_CLASS(obj) \
      OBJECT_GET_CLASS(M25P80Class, (obj), TYPE_M25P80)
 
-static inline Manufacturer get_man(Flash *s)
-{
-    switch (s->pi->id[0]) {
-    case 0x20:
-        return MAN_NUMONYX;
-    case 0xEF:
-        return MAN_WINBOND;
-    case 0x01:
-        return MAN_SPANSION;
-    case 0xC2:
-        return MAN_MACRONIX;
-    default:
-        return MAN_GENERIC;
-    }
-}
-
 static void blk_sync_complete(void *opaque, int ret)
 {
-    QEMUIOVector *iov = opaque;
-
-    qemu_iovec_destroy(iov);
-    g_free(iov);
-
     /* do nothing. Masters do not directly interact with the backing store,
      * only the working copy so no mutexing required.
      */
@@ -460,33 +358,39 @@ static void blk_sync_complete(void *opaque, int ret)
 
 static void flash_sync_page(Flash *s, int page)
 {
-    QEMUIOVector *iov;
+    int blk_sector, nb_sectors;
+    QEMUIOVector iov;
 
     if (!s->blk || blk_is_read_only(s->blk)) {
         return;
     }
 
-    iov = g_new(QEMUIOVector, 1);
-    qemu_iovec_init(iov, 1);
-    qemu_iovec_add(iov, s->storage + page * s->pi->page_size,
-                   s->pi->page_size);
-    blk_aio_pwritev(s->blk, page * s->pi->page_size, iov, 0,
-                    blk_sync_complete, iov);
+    blk_sector = (page * s->pi->page_size) / BDRV_SECTOR_SIZE;
+    nb_sectors = DIV_ROUND_UP(s->pi->page_size, BDRV_SECTOR_SIZE);
+    qemu_iovec_init(&iov, 1);
+    qemu_iovec_add(&iov, s->storage + blk_sector * BDRV_SECTOR_SIZE,
+                   nb_sectors * BDRV_SECTOR_SIZE);
+    blk_aio_writev(s->blk, blk_sector, &iov, nb_sectors, blk_sync_complete,
+                   NULL);
 }
 
 static inline void flash_sync_area(Flash *s, int64_t off, int64_t len)
 {
-    QEMUIOVector *iov;
+    int64_t start, end, nb_sectors;
+    QEMUIOVector iov;
 
     if (!s->blk || blk_is_read_only(s->blk)) {
         return;
     }
 
     assert(!(len % BDRV_SECTOR_SIZE));
-    iov = g_new(QEMUIOVector, 1);
-    qemu_iovec_init(iov, 1);
-    qemu_iovec_add(iov, s->storage + off, len);
-    blk_aio_pwritev(s->blk, off, iov, 0, blk_sync_complete, iov);
+    start = off / BDRV_SECTOR_SIZE;
+    end = (off + len) / BDRV_SECTOR_SIZE;
+    nb_sectors = end - start;
+    qemu_iovec_init(&iov, 1);
+    qemu_iovec_add(&iov, s->storage + (start * BDRV_SECTOR_SIZE),
+                                        nb_sectors * BDRV_SECTOR_SIZE);
+    blk_aio_writev(s->blk, start, &iov, nb_sectors, blk_sync_complete, NULL);
 }
 
 static void flash_erase(Flash *s, int offset, FlashCMD cmd)
@@ -501,7 +405,6 @@ static void flash_erase(Flash *s, int offset, FlashCMD cmd)
         capa_to_assert = ER_4K;
         break;
     case ERASE_32K:
-    case ERASE4_32K:
         len = 32 << 10;
         capa_to_assert = ER_32K;
         break;
@@ -539,9 +442,9 @@ static inline void flash_sync_dirty(Flash *s, int64_t newpage)
 }
 
 static inline
-void flash_write8(Flash *s, uint32_t addr, uint8_t data)
+void flash_write8(Flash *s, uint64_t addr, uint8_t data)
 {
-    uint32_t page = addr / s->pi->page_size;
+    int64_t page = addr / s->pi->page_size;
     uint8_t prev = s->storage[s->cur_addr];
 
     if (!s->write_enable) {
@@ -549,7 +452,7 @@ void flash_write8(Flash *s, uint32_t addr, uint8_t data)
     }
 
     if ((prev ^ data) & data) {
-        DB_PRINT_L(1, "programming zero to one! addr=%" PRIx32 "  %" PRIx8
+        DB_PRINT_L(1, "programming zero to one! addr=%" PRIx64 "  %" PRIx8
                    " -> %" PRIx8 "\n", addr, prev, data);
     }
 
@@ -572,11 +475,9 @@ static inline int get_addr_length(Flash *s)
 
    switch (s->cmd_in_progress) {
    case PP4:
-   case PP4_4:
    case READ4:
    case QIOR4:
    case ERASE4_4K:
-   case ERASE4_32K:
    case ERASE4_SECTOR:
    case FAST_READ4:
    case DOR4:
@@ -590,16 +491,18 @@ static inline int get_addr_length(Flash *s)
 
 static void complete_collecting_data(Flash *s)
 {
-    int i, n;
+    int i;
+
+    s->cur_addr = 0;
 
-    n = get_addr_length(s);
-    s->cur_addr = (n == 3 ? s->ear : 0);
-    for (i = 0; i < n; ++i) {
+    for (i = 0; i < get_addr_length(s); ++i) {
         s->cur_addr <<= 8;
         s->cur_addr |= s->data[i];
     }
 
-    s->cur_addr &= s->size - 1;
+    if (get_addr_length(s) == 3) {
+        s->cur_addr += (s->ear & 0x3) * MAX_3BYTES_SIZE;
+    }
 
     s->state = STATE_IDLE;
 
@@ -608,7 +511,6 @@ static void complete_collecting_data(Flash *s)
     case QPP:
     case PP:
     case PP4:
-    case PP4_4:
         s->state = STATE_PAGE_PROGRAM;
         break;
     case READ:
@@ -628,25 +530,11 @@ static void complete_collecting_data(Flash *s)
     case ERASE_4K:
     case ERASE4_4K:
     case ERASE_32K:
-    case ERASE4_32K:
     case ERASE_SECTOR:
     case ERASE4_SECTOR:
         flash_erase(s, s->cur_addr, s->cmd_in_progress);
         break;
     case WRSR:
-        switch (get_man(s)) {
-        case MAN_SPANSION:
-            s->quad_enable = !!(s->data[1] & 0x02);
-            break;
-        case MAN_MACRONIX:
-            s->quad_enable = extract32(s->data[0], 6, 1);
-            if (s->len > 1) {
-                s->four_bytes_address_mode = extract32(s->data[1], 5, 1);
-            }
-            break;
-        default:
-            break;
-        }
         if (s->write_enable) {
             s->write_enable = false;
         }
@@ -680,10 +568,8 @@ static void reset_memory(Flash *s)
     s->state = STATE_IDLE;
     s->write_enable = false;
     s->reset_enable = false;
-    s->quad_enable = false;
 
-    switch (get_man(s)) {
-    case MAN_NUMONYX:
+    if (((s->pi->jedec >> 16) & 0xFF) == JEDEC_NUMONYX) {
         s->volatile_cfg = 0;
         s->volatile_cfg |= VCFG_DUMMY;
         s->volatile_cfg |= VCFG_WRAP_SEQUENTIAL;
@@ -713,148 +599,16 @@ static void reset_memory(Flash *s)
             s->four_bytes_address_mode = true;
         }
         if (!(s->nonvolatile_cfg & NVCFG_LOWER_SEGMENT_MASK)) {
-            s->ear = s->size / MAX_3BYTES_SIZE - 1;
+            s->ear = CFG_UPPER_128MB_SEG_ENABLED;
         }
-        break;
-    case MAN_MACRONIX:
-        s->volatile_cfg = 0x7;
-        break;
-    case MAN_SPANSION:
-        s->spansion_cr1v = s->spansion_cr1nv;
-        s->spansion_cr2v = s->spansion_cr2nv;
-        s->spansion_cr3v = s->spansion_cr3nv;
-        s->spansion_cr4v = s->spansion_cr4nv;
-        s->quad_enable = extract32(s->spansion_cr1v,
-                                   SPANSION_QUAD_CFG_POS,
-                                   SPANSION_QUAD_CFG_LEN
-                                   );
-        s->four_bytes_address_mode = extract32(s->spansion_cr2v,
-                SPANSION_ADDR_LEN_POS,
-                SPANSION_ADDR_LEN_LEN
-                );
-        break;
-    default:
-        break;
     }
 
     DB_PRINT_L(0, "Reset done.\n");
 }
 
-static void decode_fast_read_cmd(Flash *s)
-{
-    s->needed_bytes = get_addr_length(s);
-    switch (get_man(s)) {
-    /* Dummy cycles - modeled with bytes writes instead of bits */
-    case MAN_WINBOND:
-        s->needed_bytes += 8;
-        break;
-    case MAN_NUMONYX:
-        s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
-        break;
-    case MAN_MACRONIX:
-        if (extract32(s->volatile_cfg, 6, 2) == 1) {
-            s->needed_bytes += 6;
-        } else {
-            s->needed_bytes += 8;
-        }
-        break;
-    case MAN_SPANSION:
-        s->needed_bytes += extract32(s->spansion_cr2v,
-                                    SPANSION_DUMMY_CLK_POS,
-                                    SPANSION_DUMMY_CLK_LEN
-                                    );
-        break;
-    default:
-        break;
-    }
-    s->pos = 0;
-    s->len = 0;
-    s->state = STATE_COLLECTING_DATA;
-}
-
-static void decode_dio_read_cmd(Flash *s)
-{
-    s->needed_bytes = get_addr_length(s);
-    /* Dummy cycles modeled with bytes writes instead of bits */
-    switch (get_man(s)) {
-    case MAN_WINBOND:
-        s->needed_bytes += WINBOND_CONTINUOUS_READ_MODE_CMD_LEN;
-        break;
-    case MAN_SPANSION:
-        s->needed_bytes += SPANSION_CONTINUOUS_READ_MODE_CMD_LEN;
-        s->needed_bytes += extract32(s->spansion_cr2v,
-                                    SPANSION_DUMMY_CLK_POS,
-                                    SPANSION_DUMMY_CLK_LEN
-                                    );
-        break;
-    case MAN_NUMONYX:
-        s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
-        break;
-    case MAN_MACRONIX:
-        switch (extract32(s->volatile_cfg, 6, 2)) {
-        case 1:
-            s->needed_bytes += 6;
-            break;
-        case 2:
-            s->needed_bytes += 8;
-            break;
-        default:
-            s->needed_bytes += 4;
-            break;
-        }
-        break;
-    default:
-        break;
-    }
-    s->pos = 0;
-    s->len = 0;
-    s->state = STATE_COLLECTING_DATA;
-}
-
-static void decode_qio_read_cmd(Flash *s)
-{
-    s->needed_bytes = get_addr_length(s);
-    /* Dummy cycles modeled with bytes writes instead of bits */
-    switch (get_man(s)) {
-    case MAN_WINBOND:
-        s->needed_bytes += WINBOND_CONTINUOUS_READ_MODE_CMD_LEN;
-        s->needed_bytes += 4;
-        break;
-    case MAN_SPANSION:
-        s->needed_bytes += SPANSION_CONTINUOUS_READ_MODE_CMD_LEN;
-        s->needed_bytes += extract32(s->spansion_cr2v,
-                                    SPANSION_DUMMY_CLK_POS,
-                                    SPANSION_DUMMY_CLK_LEN
-                                    );
-        break;
-    case MAN_NUMONYX:
-        s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
-        break;
-    case MAN_MACRONIX:
-        switch (extract32(s->volatile_cfg, 6, 2)) {
-        case 1:
-            s->needed_bytes += 4;
-            break;
-        case 2:
-            s->needed_bytes += 8;
-            break;
-        default:
-            s->needed_bytes += 6;
-            break;
-        }
-        break;
-    default:
-        break;
-    }
-    s->pos = 0;
-    s->len = 0;
-    s->state = STATE_COLLECTING_DATA;
-}
-
 static void decode_new_cmd(Flash *s, uint32_t value)
 {
     s->cmd_in_progress = value;
-    int i;
     DB_PRINT_L(0, "decoded new command:%x\n", value);
 
     if (value != RESET_MEMORY) {
@@ -866,7 +620,6 @@ static void decode_new_cmd(Flash *s, uint32_t value)
     case ERASE_4K:
     case ERASE4_4K:
     case ERASE_32K:
-    case ERASE4_32K:
     case ERASE_SECTOR:
     case ERASE4_SECTOR:
     case READ:
@@ -875,7 +628,6 @@ static void decode_new_cmd(Flash *s, uint32_t value)
     case QPP:
     case PP:
     case PP4:
-    case PP4_4:
         s->needed_bytes = get_addr_length(s);
         s->pos = 0;
         s->len = 0;
@@ -888,35 +640,56 @@ static void decode_new_cmd(Flash *s, uint32_t value)
     case DOR4:
     case QOR:
     case QOR4:
-        decode_fast_read_cmd(s);
+        s->needed_bytes = get_addr_length(s);
+        if (((s->pi->jedec >> 16) & 0xFF) == JEDEC_NUMONYX) {
+            /* Dummy cycles modeled with bytes writes instead of bits */
+            s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
+        }
+        s->pos = 0;
+        s->len = 0;
+        s->state = STATE_COLLECTING_DATA;
         break;
 
     case DIOR:
     case DIOR4:
-        decode_dio_read_cmd(s);
+        switch ((s->pi->jedec >> 16) & 0xFF) {
+        case JEDEC_WINBOND:
+        case JEDEC_SPANSION:
+            s->needed_bytes = 4;
+            break;
+        default:
+            s->needed_bytes = get_addr_length(s);
+            /* Dummy cycles modeled with bytes writes instead of bits */
+            s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
+        }
+        s->pos = 0;
+        s->len = 0;
+        s->state = STATE_COLLECTING_DATA;
         break;
 
     case QIOR:
     case QIOR4:
-        decode_qio_read_cmd(s);
+        switch ((s->pi->jedec >> 16) & 0xFF) {
+        case JEDEC_WINBOND:
+        case JEDEC_SPANSION:
+            s->needed_bytes = 6;
+            break;
+        default:
+            s->needed_bytes = get_addr_length(s);
+            /* Dummy cycles modeled with bytes writes instead of bits */
+            s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
+        }
+        s->pos = 0;
+        s->len = 0;
+        s->state = STATE_COLLECTING_DATA;
         break;
 
     case WRSR:
         if (s->write_enable) {
-            switch (get_man(s)) {
-            case MAN_SPANSION:
-                s->needed_bytes = 2;
-                s->state = STATE_COLLECTING_DATA;
-                break;
-            case MAN_MACRONIX:
-                s->needed_bytes = 2;
-                s->state = STATE_COLLECTING_VAR_LEN_DATA;
-                break;
-            default:
-                s->needed_bytes = 1;
-                s->state = STATE_COLLECTING_DATA;
-            }
+            s->needed_bytes = 1;
             s->pos = 0;
+            s->len = 0;
+            s->state = STATE_COLLECTING_DATA;
         }
         break;
 
@@ -929,9 +702,6 @@ static void decode_new_cmd(Flash *s, uint32_t value)
 
     case RDSR:
         s->data[0] = (!!s->write_enable) << 1;
-        if (get_man(s) == MAN_MACRONIX) {
-            s->data[0] |= (!!s->quad_enable) << 6;
-        }
         s->pos = 0;
         s->len = 1;
         s->state = STATE_READING_DATA;
@@ -949,20 +719,17 @@ static void decode_new_cmd(Flash *s, uint32_t value)
 
     case JEDEC_READ:
         DB_PRINT_L(0, "populated jedec code\n");
-        for (i = 0; i < s->pi->id_len; i++) {
-            s->data[i] = s->pi->id[i];
+        s->data[0] = (s->pi->jedec >> 16) & 0xff;
+        s->data[1] = (s->pi->jedec >> 8) & 0xff;
+        s->data[2] = s->pi->jedec & 0xff;
+        if (s->pi->ext_jedec) {
+            s->data[3] = (s->pi->ext_jedec >> 8) & 0xff;
+            s->data[4] = s->pi->ext_jedec & 0xff;
+            s->len = 5;
+        } else {
+            s->len = 3;
         }
-
-        s->len = s->pi->id_len;
-        s->pos = 0;
-        s->state = STATE_READING_DATA;
-        break;
-
-    case RDCR:
-        s->data[0] = s->volatile_cfg & 0xFF;
-        s->data[0] |= (!!s->four_bytes_address_mode) << 5;
         s->pos = 0;
-        s->len = 1;
         s->state = STATE_READING_DATA;
         break;
 
@@ -1005,7 +772,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
         s->state = STATE_READING_DATA;
         break;
     case WNVCR:
-        if (s->write_enable && get_man(s) == MAN_NUMONYX) {
+        if (s->write_enable) {
             s->needed_bytes = 2;
             s->pos = 0;
             s->len = 0;
@@ -1048,24 +815,6 @@ static void decode_new_cmd(Flash *s, uint32_t value)
             reset_memory(s);
         }
         break;
-    case RDCR_EQIO:
-        switch (get_man(s)) {
-        case MAN_SPANSION:
-            s->data[0] = (!!s->quad_enable) << 1;
-            s->pos = 0;
-            s->len = 1;
-            s->state = STATE_READING_DATA;
-            break;
-        case MAN_MACRONIX:
-            s->quad_enable = true;
-            break;
-        default:
-            break;
-        }
-        break;
-    case RSTQIO:
-        s->quad_enable = false;
-        break;
     default:
         qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Unknown cmd %x\n", value);
         break;
@@ -1077,9 +826,6 @@ static int m25p80_cs(SSISlave *ss, bool select)
     Flash *s = M25P80(ss);
 
     if (select) {
-        if (s->state == STATE_COLLECTING_VAR_LEN_DATA) {
-            complete_collecting_data(s);
-        }
         s->len = 0;
         s->pos = 0;
         s->state = STATE_IDLE;
@@ -1099,21 +845,20 @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
     switch (s->state) {
 
     case STATE_PAGE_PROGRAM:
-        DB_PRINT_L(1, "page program cur_addr=%#" PRIx32 " data=%" PRIx8 "\n",
+        DB_PRINT_L(1, "page program cur_addr=%#" PRIx64 " data=%" PRIx8 "\n",
                    s->cur_addr, (uint8_t)tx);
         flash_write8(s, s->cur_addr, (uint8_t)tx);
-        s->cur_addr = (s->cur_addr + 1) & (s->size - 1);
+        s->cur_addr++;
         break;
 
     case STATE_READ:
         r = s->storage[s->cur_addr];
-        DB_PRINT_L(1, "READ 0x%" PRIx32 "=%" PRIx8 "\n", s->cur_addr,
+        DB_PRINT_L(1, "READ 0x%" PRIx64 "=%" PRIx8 "\n", s->cur_addr,
                    (uint8_t)r);
-        s->cur_addr = (s->cur_addr + 1) & (s->size - 1);
+        s->cur_addr = (s->cur_addr + 1) % s->size;
         break;
 
     case STATE_COLLECTING_DATA:
-    case STATE_COLLECTING_VAR_LEN_DATA:
         s->data[s->len] = (uint8_t)tx;
         s->len++;
 
@@ -1140,8 +885,9 @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
     return r;
 }
 
-static void m25p80_realize(SSISlave *ss, Error **errp)
+static int m25p80_init(SSISlave *ss)
 {
+    DriveInfo *dinfo;
     Flash *s = M25P80(ss);
     M25P80Class *mc = M25P80_GET_CLASS(s);
 
@@ -1150,19 +896,29 @@ static void m25p80_realize(SSISlave *ss, Error **errp)
     s->size = s->pi->sector_size * s->pi->n_sectors;
     s->dirty_page = -1;
 
-    if (s->blk) {
+    /* FIXME use a qdev drive property instead of drive_get_next() */
+    dinfo = drive_get_next(IF_MTD);
+
+    if (dinfo) {
         DB_PRINT_L(0, "Binding to IF_MTD drive\n");
+        s->blk = blk_by_legacy_dinfo(dinfo);
+        blk_attach_dev_nofail(s->blk, s);
+
         s->storage = blk_blockalign(s->blk, s->size);
 
-        if (blk_pread(s->blk, 0, s->storage, s->size) != s->size) {
-            error_setg(errp, "failed to read the initial flash content");
-            return;
+        /* FIXME: Move to late init */
+        if (blk_read(s->blk, 0, s->storage,
+                     DIV_ROUND_UP(s->size, BDRV_SECTOR_SIZE))) {
+            fprintf(stderr, "Failed to initialize SPI flash!\n");
+            return 1;
         }
     } else {
         DB_PRINT_L(0, "No BDRV - binding to RAM\n");
         s->storage = blk_blockalign(NULL, s->size);
         memset(s->storage, 0xFF, s->size);
     }
+
+    return 0;
 }
 
 static void m25p80_reset(DeviceState *d)
@@ -1178,19 +934,13 @@ static void m25p80_pre_save(void *opaque)
 }
 
 static Property m25p80_properties[] = {
-    /* This is default value for Micron flash */
     DEFINE_PROP_UINT32("nonvolatile-cfg", Flash, nonvolatile_cfg, 0x8FFF),
-    DEFINE_PROP_UINT8("spansion-cr1nv", Flash, spansion_cr1nv, 0x0),
-    DEFINE_PROP_UINT8("spansion-cr2nv", Flash, spansion_cr2nv, 0x8),
-    DEFINE_PROP_UINT8("spansion-cr3nv", Flash, spansion_cr3nv, 0x2),
-    DEFINE_PROP_UINT8("spansion-cr4nv", Flash, spansion_cr4nv, 0x10),
-    DEFINE_PROP_DRIVE("drive", Flash, blk),
     DEFINE_PROP_END_OF_LIST(),
 };
 
 static const VMStateDescription vmstate_m25p80 = {
     .name = "xilinx_spi",
-    .version_id = 3,
+    .version_id = 2,
     .minimum_version_id = 1,
     .pre_save = m25p80_pre_save,
     .fields = (VMStateField[]) {
@@ -1200,8 +950,7 @@ static const VMStateDescription vmstate_m25p80 = {
         VMSTATE_UINT32(pos, Flash),
         VMSTATE_UINT8(needed_bytes, Flash),
         VMSTATE_UINT8(cmd_in_progress, Flash),
-        VMSTATE_UNUSED(4),
-        VMSTATE_UINT32(cur_addr, Flash),
+        VMSTATE_UINT64(cur_addr, Flash),
         VMSTATE_BOOL(write_enable, Flash),
         VMSTATE_BOOL_V(reset_enable, Flash, 2),
         VMSTATE_UINT8_V(ear, Flash, 2),
@@ -1209,11 +958,6 @@ static const VMStateDescription vmstate_m25p80 = {
         VMSTATE_UINT32_V(nonvolatile_cfg, Flash, 2),
         VMSTATE_UINT32_V(volatile_cfg, Flash, 2),
         VMSTATE_UINT32_V(enh_volatile_cfg, Flash, 2),
-        VMSTATE_BOOL_V(quad_enable, Flash, 3),
-        VMSTATE_UINT8_V(spansion_cr1nv, Flash, 3),
-        VMSTATE_UINT8_V(spansion_cr2nv, Flash, 3),
-        VMSTATE_UINT8_V(spansion_cr3nv, Flash, 3),
-        VMSTATE_UINT8_V(spansion_cr4nv, Flash, 3),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -1224,7 +968,7 @@ static void m25p80_class_init(ObjectClass *klass, void *data)
     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
     M25P80Class *mc = M25P80_CLASS(klass);
 
-    k->realize = m25p80_realize;
+    k->init = m25p80_init;
     k->transfer = m25p80_transfer8;
     k->set_cs = m25p80_cs;
     k->cs_polarity = SSI_CS_LOW;
index c69e675..29c6596 100644 (file)
@@ -663,8 +663,7 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s)
         sector = SECTOR(s->addr);
         off = (s->addr & PAGE_MASK) + s->offset;
         soff = SECTOR_OFFSET(s->addr);
-        if (blk_pread(s->blk, sector << BDRV_SECTOR_BITS, iobuf,
-                      PAGE_SECTORS << BDRV_SECTOR_BITS) < 0) {
+        if (blk_read(s->blk, sector, iobuf, PAGE_SECTORS) < 0) {
             printf("%s: read error in sector %" PRIu64 "\n", __func__, sector);
             return;
         }
@@ -676,24 +675,21 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s)
                             MIN(OOB_SIZE, off + s->iolen - PAGE_SIZE));
         }
 
-        if (blk_pwrite(s->blk, sector << BDRV_SECTOR_BITS, iobuf,
-                       PAGE_SECTORS << BDRV_SECTOR_BITS, 0) < 0) {
+        if (blk_write(s->blk, sector, iobuf, PAGE_SECTORS) < 0) {
             printf("%s: write error in sector %" PRIu64 "\n", __func__, sector);
         }
     } else {
         off = PAGE_START(s->addr) + (s->addr & PAGE_MASK) + s->offset;
         sector = off >> 9;
         soff = off & 0x1ff;
-        if (blk_pread(s->blk, sector << BDRV_SECTOR_BITS, iobuf,
-                      (PAGE_SECTORS + 2) << BDRV_SECTOR_BITS) < 0) {
+        if (blk_read(s->blk, sector, iobuf, PAGE_SECTORS + 2) < 0) {
             printf("%s: read error in sector %" PRIu64 "\n", __func__, sector);
             return;
         }
 
         mem_and(iobuf + soff, s->io, s->iolen);
 
-        if (blk_pwrite(s->blk, sector << BDRV_SECTOR_BITS, iobuf,
-                       (PAGE_SECTORS + 2) << BDRV_SECTOR_BITS, 0) < 0) {
+        if (blk_write(s->blk, sector, iobuf, PAGE_SECTORS + 2) < 0) {
             printf("%s: write error in sector %" PRIu64 "\n", __func__, sector);
         }
     }
@@ -720,20 +716,17 @@ static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s)
         i = SECTOR(addr);
         page = SECTOR(addr + (1 << (ADDR_SHIFT + s->erase_shift)));
         for (; i < page; i ++)
-            if (blk_pwrite(s->blk, i << BDRV_SECTOR_BITS, iobuf,
-                           BDRV_SECTOR_SIZE, 0) < 0) {
+            if (blk_write(s->blk, i, iobuf, 1) < 0) {
                 printf("%s: write error in sector %" PRIu64 "\n", __func__, i);
             }
     } else {
         addr = PAGE_START(addr);
         page = addr >> 9;
-        if (blk_pread(s->blk, page << BDRV_SECTOR_BITS, iobuf,
-                      BDRV_SECTOR_SIZE) < 0) {
+        if (blk_read(s->blk, page, iobuf, 1) < 0) {
             printf("%s: read error in sector %" PRIu64 "\n", __func__, page);
         }
         memset(iobuf + (addr & 0x1ff), 0xff, (~addr & 0x1ff) + 1);
-        if (blk_pwrite(s->blk, page << BDRV_SECTOR_BITS, iobuf,
-                       BDRV_SECTOR_SIZE, 0) < 0) {
+        if (blk_write(s->blk, page, iobuf, 1) < 0) {
             printf("%s: write error in sector %" PRIu64 "\n", __func__, page);
         }
 
@@ -741,20 +734,18 @@ static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s)
         i = (addr & ~0x1ff) + 0x200;
         for (addr += ((PAGE_SIZE + OOB_SIZE) << s->erase_shift) - 0x200;
                         i < addr; i += 0x200) {
-            if (blk_pwrite(s->blk, i, iobuf, BDRV_SECTOR_SIZE, 0) < 0) {
+            if (blk_write(s->blk, i >> 9, iobuf, 1) < 0) {
                 printf("%s: write error in sector %" PRIu64 "\n",
                        __func__, i >> 9);
             }
         }
 
         page = i >> 9;
-        if (blk_pread(s->blk, page << BDRV_SECTOR_BITS, iobuf,
-                      BDRV_SECTOR_SIZE) < 0) {
+        if (blk_read(s->blk, page, iobuf, 1) < 0) {
             printf("%s: read error in sector %" PRIu64 "\n", __func__, page);
         }
         memset(iobuf, 0xff, ((addr - 1) & 0x1ff) + 1);
-        if (blk_pwrite(s->blk, page << BDRV_SECTOR_BITS, iobuf,
-                       BDRV_SECTOR_SIZE, 0) < 0) {
+        if (blk_write(s->blk, page, iobuf, 1) < 0) {
             printf("%s: write error in sector %" PRIu64 "\n", __func__, page);
         }
     }
@@ -769,8 +760,7 @@ static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s,
 
     if (s->blk) {
         if (s->mem_oob) {
-            if (blk_pread(s->blk, SECTOR(addr) << BDRV_SECTOR_BITS, s->io,
-                          PAGE_SECTORS << BDRV_SECTOR_BITS) < 0) {
+            if (blk_read(s->blk, SECTOR(addr), s->io, PAGE_SECTORS) < 0) {
                 printf("%s: read error in sector %" PRIu64 "\n",
                                 __func__, SECTOR(addr));
             }
@@ -779,8 +769,8 @@ static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s,
                             OOB_SIZE);
             s->ioaddr = s->io + SECTOR_OFFSET(s->addr) + offset;
         } else {
-            if (blk_pread(s->blk, PAGE_START(addr), s->io,
-                          (PAGE_SECTORS + 2) << BDRV_SECTOR_BITS) < 0) {
+            if (blk_read(s->blk, PAGE_START(addr) >> 9,
+                         s->io, (PAGE_SECTORS + 2)) < 0) {
                 printf("%s: read error in sector %" PRIu64 "\n",
                                 __func__, PAGE_START(addr) >> 9);
             }
index cef3bb4..173988e 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "hw/block/block.h"
-#include "hw/hw.h"
-#include "hw/pci/msix.h"
-#include "hw/pci/pci.h"
+#include <hw/block/block.h>
+#include <hw/hw.h>
+#include <hw/pci/msix.h>
+#include <hw/pci/pci.h>
 #include "sysemu/sysemu.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
@@ -239,7 +239,7 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
     uint8_t lba_index  = NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas);
     uint8_t data_shift = ns->id_ns.lbaf[lba_index].ds;
     uint64_t data_size = (uint64_t)nlb << data_shift;
-    uint64_t data_offset = slba << data_shift;
+    uint64_t aio_slba  = slba << (data_shift - BDRV_SECTOR_BITS);
     int is_write = rw->opcode == NVME_CMD_WRITE ? 1 : 0;
     enum BlockAcctType acct = is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ;
 
@@ -258,8 +258,8 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
     req->has_sg = true;
     dma_acct_start(n->conf.blk, &req->acct, &req->qsg, acct);
     req->aiocb = is_write ?
-        dma_blk_write(n->conf.blk, &req->qsg, data_offset, nvme_rw_cb, req) :
-        dma_blk_read(n->conf.blk, &req->qsg, data_offset, nvme_rw_cb, req);
+        dma_blk_write(n->conf.blk, &req->qsg, aio_slba, nvme_rw_cb, req) :
+        dma_blk_read(n->conf.blk, &req->qsg, aio_slba, nvme_rw_cb, req);
 
     return NVME_NO_COMPLETE;
 }
@@ -469,22 +469,19 @@ static uint16_t nvme_create_cq(NvmeCtrl *n, NvmeCmd *cmd)
     return NVME_SUCCESS;
 }
 
-static uint16_t nvme_identify_ctrl(NvmeCtrl *n, NvmeIdentify *c)
-{
-    uint64_t prp1 = le64_to_cpu(c->prp1);
-    uint64_t prp2 = le64_to_cpu(c->prp2);
-
-    return nvme_dma_read_prp(n, (uint8_t *)&n->id_ctrl, sizeof(n->id_ctrl),
-        prp1, prp2);
-}
-
-static uint16_t nvme_identify_ns(NvmeCtrl *n, NvmeIdentify *c)
+static uint16_t nvme_identify(NvmeCtrl *n, NvmeCmd *cmd)
 {
     NvmeNamespace *ns;
+    NvmeIdentify *c = (NvmeIdentify *)cmd;
+    uint32_t cns  = le32_to_cpu(c->cns);
     uint32_t nsid = le32_to_cpu(c->nsid);
     uint64_t prp1 = le64_to_cpu(c->prp1);
     uint64_t prp2 = le64_to_cpu(c->prp2);
 
+    if (cns) {
+        return nvme_dma_read_prp(n, (uint8_t *)&n->id_ctrl, sizeof(n->id_ctrl),
+            prp1, prp2);
+    }
     if (nsid == 0 || nsid > n->num_namespaces) {
         return NVME_INVALID_NSID | NVME_DNR;
     }
@@ -494,48 +491,6 @@ static uint16_t nvme_identify_ns(NvmeCtrl *n, NvmeIdentify *c)
         prp1, prp2);
 }
 
-static uint16_t nvme_identify_nslist(NvmeCtrl *n, NvmeIdentify *c)
-{
-    static const int data_len = 4096;
-    uint32_t min_nsid = le32_to_cpu(c->nsid);
-    uint64_t prp1 = le64_to_cpu(c->prp1);
-    uint64_t prp2 = le64_to_cpu(c->prp2);
-    uint32_t *list;
-    uint16_t ret;
-    int i, j = 0;
-
-    list = g_malloc0(data_len);
-    for (i = 0; i < n->num_namespaces; i++) {
-        if (i < min_nsid) {
-            continue;
-        }
-        list[j++] = cpu_to_le32(i + 1);
-        if (j == data_len / sizeof(uint32_t)) {
-            break;
-        }
-    }
-    ret = nvme_dma_read_prp(n, (uint8_t *)list, data_len, prp1, prp2);
-    g_free(list);
-    return ret;
-}
-
-
-static uint16_t nvme_identify(NvmeCtrl *n, NvmeCmd *cmd)
-{
-    NvmeIdentify *c = (NvmeIdentify *)cmd;
-
-    switch (le32_to_cpu(c->cns)) {
-    case 0x00:
-        return nvme_identify_ns(n, c);
-    case 0x01:
-        return nvme_identify_ctrl(n, c);
-    case 0x02:
-        return nvme_identify_nslist(n, c);
-    default:
-        return NVME_INVALID_FIELD | NVME_DNR;
-    }
-}
-
 static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
 {
     uint32_t dw10 = le32_to_cpu(cmd->cdw10);
@@ -848,7 +803,6 @@ static int nvme_init(PCIDevice *pci_dev)
         return -1;
     }
     blkconf_blocksizes(&n->conf);
-    blkconf_apply_backend_options(&n->conf);
 
     pci_conf = pci_dev->config;
     pci_conf[PCI_INTERRUPT_PIN] = 1;
@@ -954,7 +908,7 @@ static void nvme_class_init(ObjectClass *oc, void *data)
     pc->class_id = PCI_CLASS_STORAGE_EXPRESS;
     pc->vendor_id = PCI_VENDOR_ID_INTEL;
     pc->device_id = 0x5845;
-    pc->revision = 2;
+    pc->revision = 1;
     pc->is_express = 1;
 
     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
index 8d84227..883f4b1 100644 (file)
@@ -224,8 +224,7 @@ static void onenand_reset(OneNANDState *s, int cold)
         /* Lock the whole flash */
         memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks);
 
-        if (s->blk_cur && blk_pread(s->blk_cur, 0, s->boot[0],
-                                    8 << BDRV_SECTOR_BITS) < 0) {
+        if (s->blk_cur && blk_read(s->blk_cur, 0, s->boot[0], 8) < 0) {
             hw_error("%s: Loading the BootRAM failed.\n", __func__);
         }
     }
@@ -241,11 +240,8 @@ static void onenand_system_reset(DeviceState *dev)
 static inline int onenand_load_main(OneNANDState *s, int sec, int secn,
                 void *dest)
 {
-    assert(UINT32_MAX >> BDRV_SECTOR_BITS > sec);
-    assert(UINT32_MAX >> BDRV_SECTOR_BITS > secn);
     if (s->blk_cur) {
-        return blk_pread(s->blk_cur, sec << BDRV_SECTOR_BITS, dest,
-                         secn << BDRV_SECTOR_BITS) < 0;
+        return blk_read(s->blk_cur, sec, dest, secn) < 0;
     } else if (sec + secn > s->secs_cur) {
         return 1;
     }
@@ -261,22 +257,19 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
     int result = 0;
 
     if (secn > 0) {
-        uint32_t size = secn << BDRV_SECTOR_BITS;
-        uint32_t offset = sec << BDRV_SECTOR_BITS;
-        assert(UINT32_MAX >> BDRV_SECTOR_BITS > sec);
-        assert(UINT32_MAX >> BDRV_SECTOR_BITS > secn);
+        uint32_t size = (uint32_t)secn * 512;
         const uint8_t *sp = (const uint8_t *)src;
         uint8_t *dp = 0;
         if (s->blk_cur) {
             dp = g_malloc(size);
-            if (!dp || blk_pread(s->blk_cur, offset, dp, size) < 0) {
+            if (!dp || blk_read(s->blk_cur, sec, dp, secn) < 0) {
                 result = 1;
             }
         } else {
             if (sec + secn > s->secs_cur) {
                 result = 1;
             } else {
-                dp = (uint8_t *)s->current + offset;
+                dp = (uint8_t *)s->current + (sec << 9);
             }
         }
         if (!result) {
@@ -285,7 +278,7 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
                 dp[i] &= sp[i];
             }
             if (s->blk_cur) {
-                result = blk_pwrite(s->blk_cur, offset, dp, size, 0) < 0;
+                result = blk_write(s->blk_cur, sec, dp, secn) < 0;
             }
         }
         if (dp && s->blk_cur) {
@@ -302,8 +295,7 @@ static inline int onenand_load_spare(OneNANDState *s, int sec, int secn,
     uint8_t buf[512];
 
     if (s->blk_cur) {
-        uint32_t offset = (s->secs_cur + (sec >> 5)) << BDRV_SECTOR_BITS;
-        if (blk_pread(s->blk_cur, offset, buf, BDRV_SECTOR_SIZE) < 0) {
+        if (blk_read(s->blk_cur, s->secs_cur + (sec >> 5), buf, 1) < 0) {
             return 1;
         }
         memcpy(dest, buf + ((sec & 31) << 4), secn << 4);
@@ -312,7 +304,7 @@ static inline int onenand_load_spare(OneNANDState *s, int sec, int secn,
     } else {
         memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4);
     }
-
     return 0;
 }
 
@@ -323,12 +315,10 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
     if (secn > 0) {
         const uint8_t *sp = (const uint8_t *)src;
         uint8_t *dp = 0, *dpp = 0;
-        uint32_t offset = (s->secs_cur + (sec >> 5)) << BDRV_SECTOR_BITS;
-        assert(UINT32_MAX >> BDRV_SECTOR_BITS > s->secs_cur + (sec >> 5));
         if (s->blk_cur) {
             dp = g_malloc(512);
             if (!dp
-                || blk_pread(s->blk_cur, offset, dp, BDRV_SECTOR_SIZE) < 0) {
+                || blk_read(s->blk_cur, s->secs_cur + (sec >> 5), dp, 1) < 0) {
                 result = 1;
             } else {
                 dpp = dp + ((sec & 31) << 4);
@@ -346,8 +336,8 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
                 dpp[i] &= sp[i];
             }
             if (s->blk_cur) {
-                result = blk_pwrite(s->blk_cur, offset, dp,
-                                    BDRV_SECTOR_SIZE, 0) < 0;
+                result = blk_write(s->blk_cur, s->secs_cur + (sec >> 5),
+                                   dp, 1) < 0;
             }
         }
         g_free(dp);
@@ -365,17 +355,14 @@ static inline int onenand_erase(OneNANDState *s, int sec, int num)
     for (; num > 0; num--, sec++) {
         if (s->blk_cur) {
             int erasesec = s->secs_cur + (sec >> 5);
-            if (blk_pwrite(s->blk_cur, sec << BDRV_SECTOR_BITS, blankbuf,
-                           BDRV_SECTOR_SIZE, 0) < 0) {
+            if (blk_write(s->blk_cur, sec, blankbuf, 1) < 0) {
                 goto fail;
             }
-            if (blk_pread(s->blk_cur, erasesec << BDRV_SECTOR_BITS, tmpbuf,
-                          BDRV_SECTOR_SIZE) < 0) {
+            if (blk_read(s->blk_cur, erasesec, tmpbuf, 1) < 0) {
                 goto fail;
             }
             memcpy(tmpbuf + ((sec & 31) << 4), blankbuf, 1 << 4);
-            if (blk_pwrite(s->blk_cur, erasesec << BDRV_SECTOR_BITS, tmpbuf,
-                           BDRV_SECTOR_SIZE, 0) < 0) {
+            if (blk_write(s->blk_cur, erasesec, tmpbuf, 1) < 0) {
                 goto fail;
             }
         } else {
index 62d7a56..106a775 100644 (file)
@@ -45,7 +45,6 @@
 #include "qemu/bitops.h"
 #include "exec/address-spaces.h"
 #include "qemu/host-utils.h"
-#include "qemu/log.h"
 #include "hw/sysbus.h"
 #include "sysemu/sysemu.h"
 
@@ -65,6 +64,7 @@ do {                                                        \
 #define DPRINTF(fmt, ...) do { } while (0)
 #endif
 
+#define TYPE_CFI_PFLASH01 "cfi.pflash01"
 #define CFI_PFLASH01(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH01)
 
 #define PFLASH_BE          0
@@ -413,11 +413,11 @@ static void pflash_update(pflash_t *pfl, int offset,
     int offset_end;
     if (pfl->blk) {
         offset_end = offset + size;
-        /* widen to sector boundaries */
-        offset = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE);
-        offset_end = QEMU_ALIGN_UP(offset_end, BDRV_SECTOR_SIZE);
-        blk_pwrite(pfl->blk, offset, pfl->storage + offset,
-                   offset_end - offset, 0);
+        /* round to sectors */
+        offset = offset >> 9;
+        offset_end = (offset_end + 511) >> 9;
+        blk_write(pfl->blk, offset, pfl->storage + (offset << 9),
+                  offset_end - offset);
     }
 }
 
@@ -739,7 +739,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
 
     if (pfl->blk) {
         /* read the initial flash content */
-        ret = blk_pread(pfl->blk, 0, pfl->storage, total_len);
+        ret = blk_read(pfl->blk, 0, pfl->storage, total_len >> 9);
 
         if (ret < 0) {
             vmstate_unregister_ram(&pfl->mem, DEVICE(pfl));
index 4f6105c..b13172c 100644 (file)
@@ -57,6 +57,7 @@ do {                                                       \
 
 #define PFLASH_LAZY_ROMD_THRESHOLD 42
 
+#define TYPE_CFI_PFLASH02 "cfi.pflash02"
 #define CFI_PFLASH02(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH02)
 
 struct pflash_t {
@@ -252,11 +253,11 @@ static void pflash_update(pflash_t *pfl, int offset,
     int offset_end;
     if (pfl->blk) {
         offset_end = offset + size;
-        /* widen to sector boundaries */
-        offset = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE);
-        offset_end = QEMU_ALIGN_UP(offset_end, BDRV_SECTOR_SIZE);
-        blk_pwrite(pfl->blk, offset, pfl->storage + offset,
-                   offset_end - offset, 0);
+        /* round to sectors */
+        offset = offset >> 9;
+        offset_end = (offset_end + 511) >> 9;
+        blk_write(pfl->blk, offset, pfl->storage + (offset << 9),
+                  offset_end - offset);
     }
 }
 
@@ -621,7 +622,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
     pfl->chip_len = chip_len;
     if (pfl->blk) {
         /* read the initial flash content */
-        ret = blk_pread(pfl->blk, 0, pfl->storage, chip_len);
+        ret = blk_read(pfl->blk, 0, pfl->storage, chip_len >> 9);
         if (ret < 0) {
             vmstate_unregister_ram(&pfl->orig_mem, DEVICE(pfl));
             error_setg(errp, "failed to read the initial flash content");
index 1d9f7ee..7909d50 100644 (file)
@@ -45,7 +45,7 @@ static void init_dev(tc58128_dev * dev, const char *filename)
             }
        } else {
            /* Build first block with number of blocks */
-            blocks = DIV_ROUND_UP(ret, 528 * 32);
+           blocks = (ret + 528 * 32 - 1) / (528 * 32);
            dev->flash_contents[0] = blocks & 0xff;
            dev->flash_contents[1] = (blocks >> 8) & 0xff;
            dev->flash_contents[2] = (blocks >> 16) & 0xff;
diff --git a/hw/block/trace-events b/hw/block/trace-events
deleted file mode 100644 (file)
index d0dd94f..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/block/virtio-blk.c
-virtio_blk_req_complete(void *req, int status) "req %p status %d"
-virtio_blk_rw_complete(void *req, int ret) "req %p ret %d"
-virtio_blk_handle_write(void *req, uint64_t sector, size_t nsectors) "req %p sector %"PRIu64" nsectors %zu"
-virtio_blk_handle_read(void *req, uint64_t sector, size_t nsectors) "req %p sector %"PRIu64" nsectors %zu"
-virtio_blk_submit_multireq(void *mrb, int start, int num_reqs, uint64_t offset, size_t size, bool is_write) "mrb %p start %d num_reqs %d offset %"PRIu64" size %zu is_write %d"
-
-# hw/block/dataplane/virtio-blk.c
-virtio_blk_data_plane_start(void *s) "dataplane %p"
-virtio_blk_data_plane_stop(void *s) "dataplane %p"
-virtio_blk_data_plane_process_request(void *s, unsigned int out_num, unsigned int in_num, unsigned int head) "dataplane %p out_num %u in_num %u head %u"
-
-# hw/block/hd-geometry.c
-hd_geometry_lchs_guess(void *blk, int cyls, int heads, int secs) "blk %p LCHS %d %d %d"
-hd_geometry_guess(void *blk, uint32_t cyls, uint32_t heads, uint32_t secs, int trans) "blk %p CHS %u %u %u trans %d"
index 331d766..3f88f8c 100644 (file)
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/virtio-access.h"
 
-void virtio_blk_init_request(VirtIOBlock *s, VirtQueue *vq,
-                             VirtIOBlockReq *req)
+void virtio_blk_init_request(VirtIOBlock *s, VirtIOBlockReq *req)
 {
     req->dev = s;
-    req->vq = vq;
     req->qiov.size = 0;
     req->in_len = 0;
     req->next = NULL;
@@ -55,11 +53,11 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
     trace_virtio_blk_req_complete(req, status);
 
     stb_p(&req->in->status, status);
-    virtqueue_push(req->vq, &req->elem, req->in_len);
+    virtqueue_push(s->vq, &req->elem, req->in_len);
     if (s->dataplane_started && !s->dataplane_disabled) {
-        virtio_blk_data_plane_notify(s->dataplane, req->vq);
+        virtio_blk_data_plane_notify(s->dataplane);
     } else {
-        virtio_notify(vdev, req->vq);
+        virtio_notify(vdev, s->vq);
     }
 }
 
@@ -189,12 +187,12 @@ out:
 
 #endif
 
-static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s, VirtQueue *vq)
+static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s)
 {
-    VirtIOBlockReq *req = virtqueue_pop(vq, sizeof(VirtIOBlockReq));
+    VirtIOBlockReq *req = virtqueue_pop(s->vq, sizeof(VirtIOBlockReq));
 
     if (req) {
-        virtio_blk_init_request(s, vq, req);
+        virtio_blk_init_request(s, req);
     }
     return req;
 }
@@ -324,6 +322,7 @@ static inline void submit_requests(BlockBackend *blk, MultiReqBuffer *mrb,
 {
     QEMUIOVector *qiov = &mrb->reqs[start]->qiov;
     int64_t sector_num = mrb->reqs[start]->sector_num;
+    int nb_sectors = mrb->reqs[start]->qiov.size / BDRV_SECTOR_SIZE;
     bool is_write = mrb->is_write;
 
     if (num_reqs > 1) {
@@ -332,7 +331,7 @@ static inline void submit_requests(BlockBackend *blk, MultiReqBuffer *mrb,
         int tmp_niov = qiov->niov;
 
         /* mrb->reqs[start]->qiov was initialized from external so we can't
-         * modify it here. We need to initialize it locally and then add the
+         * modifiy it here. We need to initialize it locally and then add the
          * external iovecs. */
         qemu_iovec_init(qiov, niov);
 
@@ -344,22 +343,23 @@ static inline void submit_requests(BlockBackend *blk, MultiReqBuffer *mrb,
             qemu_iovec_concat(qiov, &mrb->reqs[i]->qiov, 0,
                               mrb->reqs[i]->qiov.size);
             mrb->reqs[i - 1]->mr_next = mrb->reqs[i];
+            nb_sectors += mrb->reqs[i]->qiov.size / BDRV_SECTOR_SIZE;
         }
+        assert(nb_sectors == qiov->size / BDRV_SECTOR_SIZE);
 
-        trace_virtio_blk_submit_multireq(mrb, start, num_reqs,
-                                         sector_num << BDRV_SECTOR_BITS,
-                                         qiov->size, is_write);
+        trace_virtio_blk_submit_multireq(mrb, start, num_reqs, sector_num,
+                                         nb_sectors, is_write);
         block_acct_merge_done(blk_get_stats(blk),
                               is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ,
                               num_reqs - 1);
     }
 
     if (is_write) {
-        blk_aio_pwritev(blk, sector_num << BDRV_SECTOR_BITS, qiov, 0,
-                        virtio_blk_rw_complete, mrb->reqs[start]);
-    } else {
-        blk_aio_preadv(blk, sector_num << BDRV_SECTOR_BITS, qiov, 0,
+        blk_aio_writev(blk, sector_num, qiov, nb_sectors,
                        virtio_blk_rw_complete, mrb->reqs[start]);
+    } else {
+        blk_aio_readv(blk, sector_num, qiov, nb_sectors,
+                      virtio_blk_rw_complete, mrb->reqs[start]);
     }
 }
 
@@ -384,7 +384,7 @@ static int multireq_compare(const void *a, const void *b)
 void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb)
 {
     int i = 0, start = 0, num_reqs = 0, niov = 0, nb_sectors = 0;
-    uint32_t max_transfer;
+    int max_xfer_len = 0;
     int64_t sector_num = 0;
 
     if (mrb->num_reqs == 1) {
@@ -393,7 +393,8 @@ void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb)
         return;
     }
 
-    max_transfer = blk_get_max_transfer(mrb->reqs[0]->dev->blk);
+    max_xfer_len = blk_get_max_transfer_length(mrb->reqs[0]->dev->blk);
+    max_xfer_len = MIN_NON_ZERO(max_xfer_len, BDRV_REQUEST_MAX_SECTORS);
 
     qsort(mrb->reqs, mrb->num_reqs, sizeof(*mrb->reqs),
           &multireq_compare);
@@ -409,9 +410,8 @@ void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb)
              */
             if (sector_num + nb_sectors != req->sector_num ||
                 niov > blk_get_max_iov(blk) - req->qiov.niov ||
-                req->qiov.size > max_transfer ||
-                nb_sectors > (max_transfer -
-                              req->qiov.size) / BDRV_SECTOR_SIZE) {
+                req->qiov.size / BDRV_SECTOR_SIZE > max_xfer_len ||
+                nb_sectors > max_xfer_len - req->qiov.size / BDRV_SECTOR_SIZE) {
                 submit_requests(blk, mrb, start, num_reqs, niov);
                 num_reqs = 0;
             }
@@ -585,7 +585,7 @@ void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq)
 
     blk_io_plug(s->blk);
 
-    while ((req = virtio_blk_get_request(s, vq))) {
+    while ((req = virtio_blk_get_request(s))) {
         virtio_blk_handle_request(req, &mrb);
     }
 
@@ -654,20 +654,15 @@ static void virtio_blk_reset(VirtIODevice *vdev)
 {
     VirtIOBlock *s = VIRTIO_BLK(vdev);
     AioContext *ctx;
-    VirtIOBlockReq *req;
 
+    /*
+     * This should cancel pending requests, but can't do nicely until there
+     * are per-device request lists.
+     */
     ctx = blk_get_aio_context(s->blk);
     aio_context_acquire(ctx);
     blk_drain(s->blk);
 
-    /* We drop queued requests after blk_drain() because blk_drain() itself can
-     * produce them. */
-    while (s->rq) {
-        req = s->rq;
-        s->rq = req->next;
-        virtio_blk_free_request(req);
-    }
-
     if (s->dataplane) {
         virtio_blk_data_plane_stop(s->dataplane);
     }
@@ -715,7 +710,6 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
     blkcfg.physical_block_exp = get_physical_block_exp(conf);
     blkcfg.alignment_offset = 0;
     blkcfg.wce = blk_enable_write_cache(s->blk);
-    virtio_stw_p(vdev, &blkcfg.num_queues, s->conf.num_queues);
     memcpy(config, &blkcfg, sizeof(struct virtio_blk_config));
 }
 
@@ -759,9 +753,6 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features,
     if (blk_is_read_only(s->blk)) {
         virtio_add_feature(&features, VIRTIO_BLK_F_RO);
     }
-    if (s->conf.num_queues > 1) {
-        virtio_add_feature(&features, VIRTIO_BLK_F_MQ);
-    }
 
     return features;
 }
@@ -803,9 +794,14 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
     }
 }
 
-static void virtio_blk_save(QEMUFile *f, void *opaque, size_t size)
+static void virtio_blk_save(QEMUFile *f, void *opaque)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
+    VirtIOBlock *s = VIRTIO_BLK(vdev);
+
+    if (s->dataplane) {
+        virtio_blk_data_plane_stop(s->dataplane);
+    }
 
     virtio_save(vdev, f);
 }
@@ -817,23 +813,21 @@ static void virtio_blk_save_device(VirtIODevice *vdev, QEMUFile *f)
 
     while (req) {
         qemu_put_sbyte(f, 1);
-
-        if (s->conf.num_queues > 1) {
-            qemu_put_be32(f, virtio_get_queue_index(req->vq));
-        }
-
         qemu_put_virtqueue_element(f, &req->elem);
         req = req->next;
     }
     qemu_put_sbyte(f, 0);
 }
 
-static int virtio_blk_load(QEMUFile *f, void *opaque, size_t size)
+static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
 {
     VirtIOBlock *s = opaque;
     VirtIODevice *vdev = VIRTIO_DEVICE(s);
 
-    return virtio_load(vdev, f, 2);
+    if (version_id != 2)
+        return -EINVAL;
+
+    return virtio_load(vdev, f, version_id);
 }
 
 static int virtio_blk_load_device(VirtIODevice *vdev, QEMUFile *f,
@@ -842,22 +836,9 @@ static int virtio_blk_load_device(VirtIODevice *vdev, QEMUFile *f,
     VirtIOBlock *s = VIRTIO_BLK(vdev);
 
     while (qemu_get_sbyte(f)) {
-        unsigned nvqs = s->conf.num_queues;
-        unsigned vq_idx = 0;
         VirtIOBlockReq *req;
-
-        if (nvqs > 1) {
-            vq_idx = qemu_get_be32(f);
-
-            if (vq_idx >= nvqs) {
-                error_report("Invalid virtqueue index in request list: %#x",
-                             vq_idx);
-                return -EINVAL;
-            }
-        }
-
         req = qemu_get_virtqueue_element(f, sizeof(VirtIOBlockReq));
-        virtio_blk_init_request(s, virtio_get_queue(vdev, vq_idx), req);
+        virtio_blk_init_request(s, req);
         req->next = s->rq;
         s->rq = req;
     }
@@ -882,7 +863,7 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
     VirtIOBlock *s = VIRTIO_BLK(dev);
     VirtIOBlkConf *conf = &s->conf;
     Error *err = NULL;
-    unsigned i;
+    static int virtio_blk_id;
 
     if (!conf->conf.blk) {
         error_setg(errp, "drive property not set");
@@ -892,13 +873,8 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
         error_setg(errp, "Device needs media, but drive is empty");
         return;
     }
-    if (!conf->num_queues) {
-        error_setg(errp, "num-queues property must be larger than 0");
-        return;
-    }
 
     blkconf_serial(&conf->conf, &conf->serial);
-    blkconf_apply_backend_options(&conf->conf);
     s->original_wce = blk_enable_write_cache(conf->conf.blk);
     blkconf_geometry(&conf->conf, NULL, 65535, 255, 255, &err);
     if (err) {
@@ -914,9 +890,7 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
     s->rq = NULL;
     s->sector_mask = (s->conf.conf.logical_block_size / BDRV_SECTOR_SIZE) - 1;
 
-    for (i = 0; i < conf->num_queues; i++) {
-        virtio_add_queue_aio(vdev, 128, virtio_blk_handle_output);
-    }
+    s->vq = virtio_add_queue(vdev, 128, virtio_blk_handle_output);
     virtio_blk_data_plane_create(vdev, conf, &s->dataplane, &err);
     if (err != NULL) {
         error_propagate(errp, err);
@@ -925,6 +899,8 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
     }
 
     s->change = qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
+    register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
+                    virtio_blk_save, virtio_blk_load, s);
     blk_set_dev_ops(s->blk, &virtio_block_ops, s);
     blk_set_guest_block_size(s->blk, s->conf.conf.logical_block_size);
 
@@ -939,6 +915,7 @@ static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
     virtio_blk_data_plane_destroy(s->dataplane);
     s->dataplane = NULL;
     qemu_del_vm_change_state_handler(s->change);
+    unregister_savevm(dev, "virtio-blk", s);
     blockdev_mark_auto_del(s->blk);
     virtio_cleanup(vdev);
 }
@@ -956,11 +933,8 @@ static void virtio_blk_instance_init(Object *obj)
                                   DEVICE(obj), NULL);
 }
 
-VMSTATE_VIRTIO_DEVICE(blk, 2, virtio_blk_load, virtio_blk_save);
-
 static Property virtio_blk_properties[] = {
     DEFINE_BLOCK_PROPERTIES(VirtIOBlock, conf.conf),
-    DEFINE_BLOCK_ERROR_PROPERTIES(VirtIOBlock, conf.conf),
     DEFINE_BLOCK_CHS_PROPERTIES(VirtIOBlock, conf.conf),
     DEFINE_PROP_STRING("serial", VirtIOBlock, conf.serial),
     DEFINE_PROP_BIT("config-wce", VirtIOBlock, conf.config_wce, 0, true),
@@ -969,7 +943,6 @@ static Property virtio_blk_properties[] = {
 #endif
     DEFINE_PROP_BIT("request-merging", VirtIOBlock, conf.request_merging, 0,
                     true),
-    DEFINE_PROP_UINT16("num-queues", VirtIOBlock, conf.num_queues, 1),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -979,7 +952,6 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data)
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
 
     dc->props = virtio_blk_properties;
-    dc->vmsd = &vmstate_virtio_blk;
     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
     vdc->realize = virtio_blk_device_realize;
     vdc->unrealize = virtio_blk_device_unrealize;
index 3300b6f..c68487c 100644 (file)
@@ -1,45 +1,35 @@
-#ifndef XEN_BLKIF_H
-#define XEN_BLKIF_H
+#ifndef __XEN_BLKIF_H__
+#define __XEN_BLKIF_H__
 
 #include <xen/io/ring.h>
 #include <xen/io/blkif.h>
 #include <xen/io/protocols.h>
 
-/*
- * Not a real protocol.  Used to generate ring structs which contain
+/* Not a real protocol.  Used to generate ring structs which contain
  * the elements common to all protocols only.  This way we get a
  * compiler-checkable way to use common struct elements, so we can
- * avoid using switch(protocol) in a number of places.
- */
+ * avoid using switch(protocol) in a number of places.  */
 struct blkif_common_request {
-    char dummy;
+       char dummy;
 };
 struct blkif_common_response {
-    char dummy;
+       char dummy;
 };
 
 /* i386 protocol version */
 #pragma pack(push, 4)
 struct blkif_x86_32_request {
-    uint8_t        operation;        /* BLKIF_OP_???                         */
-    uint8_t        nr_segments;      /* number of segments                   */
-    blkif_vdev_t   handle;           /* only for read/write requests         */
-    uint64_t       id;               /* private guest value, echoed in resp  */
-    blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
-    struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-};
-struct blkif_x86_32_request_discard {
-    uint8_t        operation;        /* BLKIF_OP_DISCARD                     */
-    uint8_t        flag;             /* nr_segments in request struct        */
-    blkif_vdev_t   handle;           /* only for read/write requests         */
-    uint64_t       id;               /* private guest value, echoed in resp  */
-    blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
-    uint64_t       nr_sectors;       /* # of contiguous sectors to discard   */
+       uint8_t        operation;    /* BLKIF_OP_???                         */
+       uint8_t        nr_segments;  /* number of segments                   */
+       blkif_vdev_t   handle;       /* only for read/write requests         */
+       uint64_t       id;           /* private guest value, echoed in resp  */
+       blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
+       struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 };
 struct blkif_x86_32_response {
-    uint64_t        id;              /* copied from request */
-    uint8_t         operation;       /* copied from request */
-    int16_t         status;          /* BLKIF_RSP_???       */
+       uint64_t        id;              /* copied from request */
+       uint8_t         operation;       /* copied from request */
+       int16_t         status;          /* BLKIF_RSP_???       */
 };
 typedef struct blkif_x86_32_request blkif_x86_32_request_t;
 typedef struct blkif_x86_32_response blkif_x86_32_response_t;
@@ -47,100 +37,83 @@ typedef struct blkif_x86_32_response blkif_x86_32_response_t;
 
 /* x86_64 protocol version */
 struct blkif_x86_64_request {
-    uint8_t        operation;        /* BLKIF_OP_???                         */
-    uint8_t        nr_segments;      /* number of segments                   */
-    blkif_vdev_t   handle;           /* only for read/write requests         */
-    uint64_t       __attribute__((__aligned__(8))) id;
-    blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
-    struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-};
-struct blkif_x86_64_request_discard {
-    uint8_t        operation;        /* BLKIF_OP_DISCARD                     */
-    uint8_t        flag;             /* nr_segments in request struct        */
-    blkif_vdev_t   handle;           /* only for read/write requests         */
-    uint64_t       __attribute__((__aligned__(8))) id;
-    blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
-    uint64_t       nr_sectors;       /* # of contiguous sectors to discard   */
+       uint8_t        operation;    /* BLKIF_OP_???                         */
+       uint8_t        nr_segments;  /* number of segments                   */
+       blkif_vdev_t   handle;       /* only for read/write requests         */
+       uint64_t       __attribute__((__aligned__(8))) id;
+       blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
+       struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 };
 struct blkif_x86_64_response {
-    uint64_t       __attribute__((__aligned__(8))) id;
-    uint8_t         operation;       /* copied from request */
-    int16_t         status;          /* BLKIF_RSP_???       */
+       uint64_t       __attribute__((__aligned__(8))) id;
+       uint8_t         operation;       /* copied from request */
+       int16_t         status;          /* BLKIF_RSP_???       */
 };
 typedef struct blkif_x86_64_request blkif_x86_64_request_t;
 typedef struct blkif_x86_64_response blkif_x86_64_response_t;
 
-DEFINE_RING_TYPES(blkif_common, struct blkif_common_request,
-                  struct blkif_common_response);
-DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request,
-                  struct blkif_x86_32_response);
-DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request,
-                  struct blkif_x86_64_response);
+DEFINE_RING_TYPES(blkif_common, struct blkif_common_request, struct blkif_common_response);
+DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request, struct blkif_x86_32_response);
+DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request, struct blkif_x86_64_response);
 
 union blkif_back_rings {
-    blkif_back_ring_t        native;
-    blkif_common_back_ring_t common;
-    blkif_x86_32_back_ring_t x86_32_part;
-    blkif_x86_64_back_ring_t x86_64_part;
+       blkif_back_ring_t        native;
+       blkif_common_back_ring_t common;
+        blkif_x86_32_back_ring_t x86_32_part;
+        blkif_x86_64_back_ring_t x86_64_part;
 };
 typedef union blkif_back_rings blkif_back_rings_t;
 
 enum blkif_protocol {
-    BLKIF_PROTOCOL_NATIVE = 1,
-    BLKIF_PROTOCOL_X86_32 = 2,
-    BLKIF_PROTOCOL_X86_64 = 3,
+       BLKIF_PROTOCOL_NATIVE = 1,
+       BLKIF_PROTOCOL_X86_32 = 2,
+       BLKIF_PROTOCOL_X86_64 = 3,
 };
 
-static inline void blkif_get_x86_32_req(blkif_request_t *dst,
-                                        blkif_x86_32_request_t *src)
+static inline void blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_request_t *src)
 {
-    int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
+       int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
 
-    dst->operation = src->operation;
-    dst->nr_segments = src->nr_segments;
-    dst->handle = src->handle;
-    dst->id = src->id;
-    dst->sector_number = src->sector_number;
-    /* Prevent the compiler from using src->... instead. */
-    barrier();
-    if (dst->operation == BLKIF_OP_DISCARD) {
-        struct blkif_x86_32_request_discard *s = (void *)src;
-        struct blkif_request_discard *d = (void *)dst;
-        d->nr_sectors = s->nr_sectors;
-        return;
-    }
-    if (n > dst->nr_segments) {
-        n = dst->nr_segments;
-    }
-    for (i = 0; i < n; i++) {
-        dst->seg[i] = src->seg[i];
-    }
+       dst->operation = src->operation;
+       dst->nr_segments = src->nr_segments;
+       dst->handle = src->handle;
+       dst->id = src->id;
+       dst->sector_number = src->sector_number;
+       if (src->operation == BLKIF_OP_DISCARD) {
+               struct blkif_request_discard *s = (void *)src;
+               struct blkif_request_discard *d = (void *)dst;
+               d->nr_sectors = s->nr_sectors;
+               return;
+       }
+       /* prevent the compiler from optimizing the code and using src->nr_segments instead */
+       barrier();
+       if (n > dst->nr_segments)
+               n = dst->nr_segments;
+       for (i = 0; i < n; i++)
+               dst->seg[i] = src->seg[i];
 }
 
-static inline void blkif_get_x86_64_req(blkif_request_t *dst,
-                                        blkif_x86_64_request_t *src)
+static inline void blkif_get_x86_64_req(blkif_request_t *dst, blkif_x86_64_request_t *src)
 {
-    int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
+       int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
 
-    dst->operation = src->operation;
-    dst->nr_segments = src->nr_segments;
-    dst->handle = src->handle;
-    dst->id = src->id;
-    dst->sector_number = src->sector_number;
-    /* Prevent the compiler from using src->... instead. */
-    barrier();
-    if (dst->operation == BLKIF_OP_DISCARD) {
-        struct blkif_x86_64_request_discard *s = (void *)src;
-        struct blkif_request_discard *d = (void *)dst;
-        d->nr_sectors = s->nr_sectors;
-        return;
-    }
-    if (n > dst->nr_segments) {
-        n = dst->nr_segments;
-    }
-    for (i = 0; i < n; i++) {
-        dst->seg[i] = src->seg[i];
-    }
+       dst->operation = src->operation;
+       dst->nr_segments = src->nr_segments;
+       dst->handle = src->handle;
+       dst->id = src->id;
+       dst->sector_number = src->sector_number;
+       if (src->operation == BLKIF_OP_DISCARD) {
+               struct blkif_request_discard *s = (void *)src;
+               struct blkif_request_discard *d = (void *)dst;
+               d->nr_sectors = s->nr_sectors;
+               return;
+       }
+       /* prevent the compiler from optimizing the code and using src->nr_segments instead */
+       barrier();
+       if (n > dst->nr_segments)
+               n = dst->nr_segments;
+       for (i = 0; i < n; i++)
+               dst->seg[i] = src->seg[i];
 }
 
-#endif /* XEN_BLKIF_H */
+#endif /* __XEN_BLKIF_H__ */
index 3b8ad33..d4ce380 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "qemu/osdep.h"
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 #include <sys/uio.h>
 
 #include "hw/hw.h"
@@ -553,8 +554,9 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct,
                          ioreq->v.size, BLOCK_ACCT_READ);
         ioreq->aio_inflight++;
-        blk_aio_preadv(blkdev->blk, ioreq->start, &ioreq->v, 0,
-                       qemu_aio_complete, ioreq);
+        blk_aio_readv(blkdev->blk, ioreq->start / BLOCK_SIZE,
+                      &ioreq->v, ioreq->v.size / BLOCK_SIZE,
+                      qemu_aio_complete, ioreq);
         break;
     case BLKIF_OP_WRITE:
     case BLKIF_OP_FLUSH_DISKCACHE:
@@ -567,17 +569,17 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
                          ioreq->req.operation == BLKIF_OP_WRITE ?
                          BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH);
         ioreq->aio_inflight++;
-        blk_aio_pwritev(blkdev->blk, ioreq->start, &ioreq->v, 0,
-                        qemu_aio_complete, ioreq);
+        blk_aio_writev(blkdev->blk, ioreq->start / BLOCK_SIZE,
+                       &ioreq->v, ioreq->v.size / BLOCK_SIZE,
+                       qemu_aio_complete, ioreq);
         break;
     case BLKIF_OP_DISCARD:
     {
         struct blkif_request_discard *discard_req = (void *)&ioreq->req;
         ioreq->aio_inflight++;
-        blk_aio_pdiscard(blkdev->blk,
-                         discard_req->sector_number << BDRV_SECTOR_BITS,
-                         discard_req->nr_sectors << BDRV_SECTOR_BITS,
-                         qemu_aio_complete, ioreq);
+        blk_aio_discard(blkdev->blk,
+                        discard_req->sector_number, discard_req->nr_sectors,
+                        qemu_aio_complete, ioreq);
         break;
     }
     default:
@@ -679,8 +681,6 @@ static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq, RING_I
                              RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc));
         break;
     }
-    /* Prevent the compiler from accessing the on-ring fields instead. */
-    barrier();
     return 0;
 }
 
index d688372..2e970b6 100644 (file)
@@ -22,7 +22,6 @@
 #include "qemu-common.h"
 #include "sysemu/char.h"
 #include "qemu/timer.h"
-#include "qemu/bswap.h"
 #include "hw/irq.h"
 #include "sysemu/bt.h"
 #include "hw/bt.h"
@@ -39,14 +38,9 @@ struct csrhci_s {
     int out_size;
     uint8_t outfifo[FIFO_LEN * 2];
     uint8_t inpkt[FIFO_LEN];
-    enum {
-        CSR_HDR_LEN,
-        CSR_DATA_LEN,
-        CSR_DATA
-    } in_state;
     int in_len;
     int in_hdr;
-    int in_needed;
+    int in_data;
     QEMUTimer *out_tm;
     int64_t baud_delay;
 
@@ -301,60 +295,38 @@ static int csrhci_data_len(const uint8_t *pkt)
     exit(-1);
 }
 
-static void csrhci_ready_for_next_inpkt(struct csrhci_s *s)
-{
-    s->in_state = CSR_HDR_LEN;
-    s->in_len = 0;
-    s->in_needed = 2;
-    s->in_hdr = INT_MAX;
-}
-
 static int csrhci_write(struct CharDriverState *chr,
                 const uint8_t *buf, int len)
 {
     struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
-    int total = 0;
+    int plen = s->in_len;
 
     if (!s->enable)
         return 0;
 
-    for (;;) {
-        int cnt = MIN(len, s->in_needed - s->in_len);
-        if (cnt) {
-            memcpy(s->inpkt + s->in_len, buf, cnt);
-            s->in_len += cnt;
-            buf += cnt;
-            len -= cnt;
-            total += cnt;
-        }
-
-        if (s->in_len < s->in_needed) {
-            break;
-        }
+    s->in_len += len;
+    memcpy(s->inpkt + plen, buf, len);
 
-        if (s->in_state == CSR_HDR_LEN) {
+    while (1) {
+        if (s->in_len >= 2 && plen < 2)
             s->in_hdr = csrhci_header_len(s->inpkt) + 1;
-            assert(s->in_hdr >= s->in_needed);
-            s->in_needed = s->in_hdr;
-            s->in_state = CSR_DATA_LEN;
-            continue;
-        }
 
-        if (s->in_state == CSR_DATA_LEN) {
-            s->in_needed += csrhci_data_len(s->inpkt);
-            /* hci_acl_hdr could specify more than 4096 bytes, so assert.  */
-            assert(s->in_needed <= sizeof(s->inpkt));
-            s->in_state = CSR_DATA;
-            continue;
-        }
+        if (s->in_len >= s->in_hdr && plen < s->in_hdr)
+            s->in_data = csrhci_data_len(s->inpkt) + s->in_hdr;
 
-        if (s->in_state == CSR_DATA) {
+        if (s->in_len >= s->in_data) {
             csrhci_in_packet(s, s->inpkt);
-            csrhci_ready_for_next_inpkt(s);
-        }
+
+            memmove(s->inpkt, s->inpkt + s->in_len, s->in_len - s->in_data);
+            s->in_len -= s->in_data;
+            s->in_hdr = INT_MAX;
+            s->in_data = INT_MAX;
+            plen = 0;
+        } else
+            break;
     }
 
-    return total;
+    return len;
 }
 
 static void csrhci_out_hci_packet_event(void *opaque,
@@ -416,9 +388,11 @@ static void csrhci_reset(struct csrhci_s *s)
 {
     s->out_len = 0;
     s->out_size = FIFO_LEN;
-    csrhci_ready_for_next_inpkt(s);
+    s->in_len = 0;
     s->baud_delay = NANOSECONDS_PER_SECOND;
     s->enable = 0;
+    s->in_hdr = INT_MAX;
+    s->in_data = INT_MAX;
 
     s->modem_state = 0;
     /* After a while... (but sooner than 10ms) */
index 351123f..7d52205 100644 (file)
@@ -426,7 +426,11 @@ static void bt_submit_raw_acl(struct bt_piconet_s *net, int length, uint8_t *dat
  * be continuously allocated.  We do it though, to preserve similar
  * behaviour between hosts.  Some things, like the BD_ADDR cannot be
  * preserved though (for example if a real hci is used).  */
-#define HNDL(raw) cpu_to_le16(raw)
+#ifdef HOST_WORDS_BIGENDIAN
+# define HNDL(raw)     bswap16(raw)
+#else
+# define HNDL(raw)     (raw)
+#endif
 
 static const uint8_t bt_event_reserved_mask[8] = {
     0xff, 0x9f, 0xfb, 0xff, 0x07, 0x18, 0x00, 0x00,
@@ -1500,8 +1504,8 @@ static void bt_submit_hci(struct HCIInfo *info,
         return;
 
 #define PARAM(cmd, param)      (((cmd##_cp *) data)->param)
-#define PARAM16(cmd, param) lduw_le_p(&PARAM(cmd, param))
-#define PARAMHANDLE(cmd) PARAM16(cmd, handle)
+#define PARAM16(cmd, param)    le16_to_cpup(&PARAM(cmd, param))
+#define PARAMHANDLE(cmd)       HNDL(PARAM(cmd, handle))
 #define LENGTH_CHECK(cmd)      if (length < sizeof(cmd##_cp)) goto short_hci
     /* Note: the supported commands bitmask in bt_hci_read_local_commands_rp
      * needs to be updated every time a command is implemented here!  */
index e342045..8065251 100644 (file)
@@ -20,7 +20,6 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qemu/timer.h"
-#include "qemu/bswap.h"
 #include "hw/bt.h"
 
 #define L2CAP_CID_MAX  0x100   /* Between 0x40 and 0x10000 */
@@ -526,9 +525,9 @@ static int l2cap_channel_config(struct l2cap_instance_s *l2cap,
             }
 
             /* MTU */
-            val = lduw_le_p(opt->val);
+            val = le16_to_cpup((void *) opt->val);
             if (val < ch->min_mtu) {
-                stw_le_p(opt->val, ch->min_mtu);
+                cpu_to_le16w((void *) opt->val, ch->min_mtu);
                 result = L2CAP_CONF_UNACCEPT;
                 break;
             }
@@ -543,7 +542,7 @@ static int l2cap_channel_config(struct l2cap_instance_s *l2cap,
             }
 
             /* Flush Timeout */
-            val = lduw_le_p(opt->val);
+            val = le16_to_cpup((void *) opt->val);
             if (val < 0x0001) {
                 opt->val[0] = 0xff;
                 opt->val[1] = 0xff;
@@ -987,7 +986,7 @@ static void l2cap_bframe_in(struct l2cap_chan_s *ch, uint16_t cid,
 static void l2cap_iframe_in(struct l2cap_chan_s *ch, uint16_t cid,
                 const l2cap_hdr *hdr, int len)
 {
-    uint16_t fcs = lduw_le_p(hdr->data + len - 2);
+    uint16_t fcs = le16_to_cpup((void *) (hdr->data + len - 2));
 
     if (len < 4)
         goto len_error;
@@ -1002,7 +1001,7 @@ static void l2cap_iframe_in(struct l2cap_chan_s *ch, uint16_t cid,
             /* TODO: Signal an error? */
             return;
         }
-        l2cap_sframe_in(ch, lduw_le_p(hdr->data));
+        l2cap_sframe_in(ch, le16_to_cpup((void *) hdr->data));
         return;
     }
 
@@ -1022,7 +1021,7 @@ static void l2cap_iframe_in(struct l2cap_chan_s *ch, uint16_t cid,
         if (len - 6 > ch->mps)
             goto len_error;
 
-        ch->len_total = lduw_le_p(hdr->data + 2);
+        ch->len_total = le16_to_cpup((void *) (hdr->data + 2));
         if (len >= 6 + ch->len_total)
             goto seg_error;
 
index f67b3b8..be26009 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "qemu/host-utils.h"
 #include "hw/bt.h"
 
 struct bt_l2cap_sdp_state_s {
index 319f165..0394d11 100644 (file)
@@ -22,7 +22,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/char/bcm2835_aux.h"
-#include "qemu/log.h"
 
 #define AUX_IRQ         0x0
 #define AUX_ENABLES     0x4
index e3bc52f..7977878 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "hw/sysbus.h"
-#include "sysemu/char.h"
-#include "qemu/timer.h"
-#include "qemu/log.h"
 #include "hw/char/cadence_uart.h"
 
 #ifdef CADENCE_UART_ERR_DEBUG
@@ -288,19 +284,13 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond,
     }
 
     ret = qemu_chr_fe_write(s->chr, s->tx_fifo, s->tx_count);
-
-    if (ret >= 0) {
-        s->tx_count -= ret;
-        memmove(s->tx_fifo, s->tx_fifo + ret, s->tx_count);
-    }
+    s->tx_count -= ret;
+    memmove(s->tx_fifo, s->tx_fifo + ret, s->tx_count);
 
     if (s->tx_count) {
-        guint r = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
-                                        cadence_uart_xmit, s);
-        if (!r) {
-            s->tx_count = 0;
-            return FALSE;
-        }
+        int r = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
+                                      cadence_uart_xmit, s);
+        assert(r);
     }
 
     uart_update_status(s);
@@ -474,6 +464,9 @@ static void cadence_uart_realize(DeviceState *dev, Error **errp)
     s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                           fifo_trigger_update, s);
 
+    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
+    s->chr = qemu_char_get_next_serial();
+
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, uart_can_receive, uart_receive,
                               uart_event, s);
@@ -520,11 +513,6 @@ static const VMStateDescription vmstate_cadence_uart = {
     }
 };
 
-static Property cadence_uart_properties[] = {
-    DEFINE_PROP_CHR("chardev", CadenceUARTState, chr),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 static void cadence_uart_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -532,8 +520,9 @@ static void cadence_uart_class_init(ObjectClass *klass, void *data)
     dc->realize = cadence_uart_realize;
     dc->vmsd = &vmstate_cadence_uart;
     dc->reset = cadence_uart_reset;
-    dc->props = cadence_uart_properties;
-  }
+    /* Reason: realize() method uses qemu_char_get_next_serial() */
+    dc->cannot_instantiate_with_device_add_yet = true;
+}
 
 static const TypeInfo cadence_uart_info = {
     .name          = TYPE_CADENCE_UART,
index c7604e6..d3bc533 100644 (file)
@@ -30,7 +30,6 @@
 #include "hw/hw.h"
 #include "hw/sysbus.h"
 #include "sysemu/char.h"
-#include "qemu/log.h"
 
 #include "hw/char/digic-uart.h"
 
@@ -145,6 +144,8 @@ static void digic_uart_realize(DeviceState *dev, Error **errp)
 {
     DigicUartState *s = DIGIC_UART(dev);
 
+    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
+    s->chr = qemu_char_get_next_serial();
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
     }
@@ -170,11 +171,6 @@ static const VMStateDescription vmstate_digic_uart = {
     }
 };
 
-static Property digic_uart_properties[] = {
-    DEFINE_PROP_CHR("chardev", DigicUartState, chr),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 static void digic_uart_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -182,7 +178,8 @@ static void digic_uart_class_init(ObjectClass *klass, void *data)
     dc->realize = digic_uart_realize;
     dc->reset = digic_uart_reset;
     dc->vmsd = &vmstate_digic_uart;
-    dc->props = digic_uart_properties;
+    /* Reason: realize() method uses qemu_char_get_next_serial() */
+    dc->cannot_instantiate_with_device_add_yet = true;
 }
 
 static const TypeInfo digic_uart_info = {
index 31a5f90..7bf09a0 100644 (file)
@@ -983,40 +983,28 @@ void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
     sysbus_mmio_map(s, 0, base);
 }
 
-static void escc_init1(Object *obj)
-{
-    ESCCState *s = ESCC(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
-    unsigned int i;
-
-    for (i = 0; i < 2; i++) {
-        sysbus_init_irq(dev, &s->chn[i].irq);
-        s->chn[i].chn = 1 - i;
-    }
-    s->chn[0].otherchn = &s->chn[1];
-    s->chn[1].otherchn = &s->chn[0];
-
-    sysbus_init_mmio(dev, &s->mmio);
-}
-
-static void escc_realize(DeviceState *dev, Error **errp)
+static int escc_init1(SysBusDevice *dev)
 {
     ESCCState *s = ESCC(dev);
     unsigned int i;
 
     s->chn[0].disabled = s->disabled;
     s->chn[1].disabled = s->disabled;
-
-    memory_region_init_io(&s->mmio, OBJECT(dev), &escc_mem_ops, s, "escc",
-                          ESCC_SIZE << s->it_shift);
-
     for (i = 0; i < 2; i++) {
+        sysbus_init_irq(dev, &s->chn[i].irq);
+        s->chn[i].chn = 1 - i;
+        s->chn[i].clock = s->frequency / 2;
         if (s->chn[i].chr) {
-            s->chn[i].clock = s->frequency / 2;
             qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
                                   serial_receive1, serial_event, &s->chn[i]);
         }
     }
+    s->chn[0].otherchn = &s->chn[1];
+    s->chn[1].otherchn = &s->chn[0];
+
+    memory_region_init_io(&s->mmio, OBJECT(s), &escc_mem_ops, s, "escc",
+                          ESCC_SIZE << s->it_shift);
+    sysbus_init_mmio(dev, &s->mmio);
 
     if (s->chn[0].type == mouse) {
         qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
@@ -1026,6 +1014,8 @@ static void escc_realize(DeviceState *dev, Error **errp)
         s->chn[1].hs = qemu_input_handler_register((DeviceState *)(&s->chn[1]),
                                                    &sunkbd_handler);
     }
+
+    return 0;
 }
 
 static Property escc_properties[] = {
@@ -1042,9 +1032,10 @@ static Property escc_properties[] = {
 static void escc_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = escc_init1;
     dc->reset = escc_reset;
-    dc->realize = escc_realize;
     dc->vmsd = &vmstate_escc;
     dc->props = escc_properties;
     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
@@ -1054,7 +1045,6 @@ static const TypeInfo escc_info = {
     .name          = TYPE_ESCC,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(ESCCState),
-    .instance_init = escc_init1,
     .class_init    = escc_class_init,
 };
 
index 04ca04f..146b387 100644 (file)
@@ -159,11 +159,6 @@ static const MemoryRegionOps ser_ops = {
     }
 };
 
-static Property etraxfs_ser_properties[] = {
-    DEFINE_PROP_CHR("chardev", ETRAXSerial, chr),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 static void serial_receive(void *opaque, const uint8_t *buf, int size)
 {
     ETRAXSerial *s = opaque;
@@ -214,42 +209,40 @@ static void etraxfs_ser_reset(DeviceState *d)
 
 }
 
-static void etraxfs_ser_init(Object *obj)
+static int etraxfs_ser_init(SysBusDevice *dev)
 {
-    ETRAXSerial *s = ETRAX_SERIAL(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    ETRAXSerial *s = ETRAX_SERIAL(dev);
 
     sysbus_init_irq(dev, &s->irq);
-    memory_region_init_io(&s->mmio, obj, &ser_ops, s,
+    memory_region_init_io(&s->mmio, OBJECT(s), &ser_ops, s,
                           "etraxfs-serial", R_MAX * 4);
     sysbus_init_mmio(dev, &s->mmio);
-}
-
-static void etraxfs_ser_realize(DeviceState *dev, Error **errp)
-{
-    ETRAXSerial *s = ETRAX_SERIAL(dev);
 
+    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
+    s->chr = qemu_char_get_next_serial();
     if (s->chr) {
         qemu_chr_add_handlers(s->chr,
                               serial_can_receive, serial_receive,
                               serial_event, s);
     }
+    return 0;
 }
 
 static void etraxfs_ser_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = etraxfs_ser_init;
     dc->reset = etraxfs_ser_reset;
-    dc->props = etraxfs_ser_properties;
-    dc->realize = etraxfs_ser_realize;
+    /* Reason: init() method uses qemu_char_get_next_serial() */
+    dc->cannot_instantiate_with_device_add_yet = true;
 }
 
 static const TypeInfo etraxfs_ser_info = {
     .name          = TYPE_ETRAX_FS_SERIAL,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(ETRAXSerial),
-    .instance_init = etraxfs_ser_init,
     .class_init    = etraxfs_ser_class_init,
 };
 
index 44856d6..6df74ac 100644 (file)
@@ -22,7 +22,6 @@
 #include "hw/char/imx_serial.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/char.h"
-#include "qemu/log.h"
 
 #ifndef DEBUG_IMX_UART
 #define DEBUG_IMX_UART 0
index 9ead32a..bc0ae49 100644 (file)
@@ -2,7 +2,7 @@
  * QEMU GE IP-Octal 232 IndustryPack emulation
  *
  * Copyright (C) 2012 Igalia, S.L.
- * Author: Alberto Garcia <berto@igalia.com>
+ * Author: Alberto Garcia <agarcia@igalia.com>
  *
  * This code is licensed under the GNU GPL v2 or (at your option) any
  * later version.
index 28c2cf7..5bf8acf 100644 (file)
@@ -114,13 +114,17 @@ static void juart_reset(DeviceState *d)
     s->jrx = 0;
 }
 
-static void lm32_juart_realize(DeviceState *dev, Error **errp)
+static int lm32_juart_init(SysBusDevice *dev)
 {
     LM32JuartState *s = LM32_JUART(dev);
 
+    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
+    s->chr = qemu_char_get_next_serial();
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, juart_can_rx, juart_rx, juart_event, s);
     }
+
+    return 0;
 }
 
 static const VMStateDescription vmstate_lm32_juart = {
@@ -134,19 +138,16 @@ static const VMStateDescription vmstate_lm32_juart = {
     }
 };
 
-static Property lm32_juart_properties[] = {
-    DEFINE_PROP_CHR("chardev", LM32JuartState, chr),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 static void lm32_juart_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = lm32_juart_init;
     dc->reset = juart_reset;
     dc->vmsd = &vmstate_lm32_juart;
-    dc->props = lm32_juart_properties;
-    dc->realize = lm32_juart_realize;
+    /* Reason: init() method uses qemu_char_get_next_serial() */
+    dc->cannot_instantiate_with_device_add_yet = true;
 }
 
 static const TypeInfo lm32_juart_info = {
index b5c760d..036813d 100644 (file)
@@ -249,25 +249,23 @@ static void uart_reset(DeviceState *d)
     s->regs[R_LSR] = LSR_THRE | LSR_TEMT;
 }
 
-static void lm32_uart_init(Object *obj)
+static int lm32_uart_init(SysBusDevice *dev)
 {
-    LM32UartState *s = LM32_UART(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    LM32UartState *s = LM32_UART(dev);
 
     sysbus_init_irq(dev, &s->irq);
 
-    memory_region_init_io(&s->iomem, obj, &uart_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &uart_ops, s,
                           "uart", R_MAX * 4);
     sysbus_init_mmio(dev, &s->iomem);
-}
-
-static void lm32_uart_realize(DeviceState *dev, Error **errp)
-{
-    LM32UartState *s = LM32_UART(dev);
 
+    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
+    s->chr = qemu_char_get_next_serial();
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
     }
+
+    return 0;
 }
 
 static const VMStateDescription vmstate_lm32_uart = {
@@ -280,26 +278,22 @@ static const VMStateDescription vmstate_lm32_uart = {
     }
 };
 
-static Property lm32_uart_properties[] = {
-    DEFINE_PROP_CHR("chardev", LM32UartState, chr),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 static void lm32_uart_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = lm32_uart_init;
     dc->reset = uart_reset;
     dc->vmsd = &vmstate_lm32_uart;
-    dc->props = lm32_uart_properties;
-    dc->realize = lm32_uart_realize;
+    /* Reason: init() method uses qemu_char_get_next_serial() */
+    dc->cannot_instantiate_with_device_add_yet = true;
 }
 
 static const TypeInfo lm32_uart_info = {
     .name          = TYPE_LM32_UART,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(LM32UartState),
-    .instance_init = lm32_uart_init,
     .class_init    = lm32_uart_class_init,
 };
 
index baddb37..03b36b2 100644 (file)
@@ -18,7 +18,7 @@
  *
  *
  * Specification available at:
- *   http://milkymist.walle.cc/socdoc/uart.pdf
+ *   http://www.milkymist.org/socdoc/uart.pdf
  */
 
 #include "qemu/osdep.h"
@@ -200,6 +200,8 @@ static void milkymist_uart_realize(DeviceState *dev, Error **errp)
 {
     MilkymistUartState *s = MILKYMIST_UART(dev);
 
+    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
+    s->chr = qemu_char_get_next_serial();
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
     }
@@ -227,11 +229,6 @@ static const VMStateDescription vmstate_milkymist_uart = {
     }
 };
 
-static Property milkymist_uart_properties[] = {
-    DEFINE_PROP_CHR("chardev", MilkymistUartState, chr),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 static void milkymist_uart_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -239,7 +236,8 @@ static void milkymist_uart_class_init(ObjectClass *klass, void *data)
     dc->realize = milkymist_uart_realize;
     dc->reset = milkymist_uart_reset;
     dc->vmsd = &vmstate_milkymist_uart;
-    dc->props = milkymist_uart_properties;
+    /* Reason: realize() method uses qemu_char_get_next_serial() */
+    dc->cannot_instantiate_with_device_add_yet = true;
 }
 
 static const TypeInfo milkymist_uart_info = {
index c0fbf8a..210c87b 100644 (file)
@@ -10,7 +10,6 @@
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
 #include "sysemu/char.h"
-#include "qemu/log.h"
 
 #define TYPE_PL011 "pl011"
 #define PL011(obj) OBJECT_CHECK(PL011State, (obj), TYPE_PL011)
@@ -274,11 +273,6 @@ static const VMStateDescription vmstate_pl011 = {
     }
 };
 
-static Property pl011_properties[] = {
-    DEFINE_PROP_CHR("chardev", PL011State, chr),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 static void pl011_init(Object *obj)
 {
     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
@@ -300,6 +294,9 @@ static void pl011_realize(DeviceState *dev, Error **errp)
 {
     PL011State *s = PL011(dev);
 
+    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
+    s->chr = qemu_char_get_next_serial();
+
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive,
                               pl011_event, s);
@@ -312,7 +309,8 @@ static void pl011_class_init(ObjectClass *oc, void *data)
 
     dc->realize = pl011_realize;
     dc->vmsd = &vmstate_pl011;
-    dc->props = pl011_properties;
+    /* Reason: realize() method uses qemu_char_get_next_serial() */
+    dc->cannot_instantiate_with_device_add_yet = true;
 }
 
 static const TypeInfo pl011_arm_info = {
index a22ad8d..7d4ff81 100644 (file)
@@ -44,10 +44,6 @@ typedef struct SCLPConsoleLM {
     uint8_t buf[SIZE_CONSOLE_BUFFER];
 } SCLPConsoleLM;
 
-#define TYPE_SCLPLM_CONSOLE "sclplmconsole"
-#define SCLPLM_CONSOLE(obj) \
-    OBJECT_CHECK(SCLPConsoleLM, (obj), TYPE_SCLPLM_CONSOLE)
-
 /*
 *  Character layer call-back functions
  *
@@ -120,7 +116,7 @@ static int get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size,
 {
     int len;
 
-    SCLPConsoleLM *cons = SCLPLM_CONSOLE(event);
+    SCLPConsoleLM *cons = DO_UPCAST(SCLPConsoleLM, event, event);
 
     len = cons->length;
     /* data need to fit into provided SCLP buffer */
@@ -194,7 +190,7 @@ static int write_console_data(SCLPEvent *event, const uint8_t *buf, int len)
     int ret = 0;
     const uint8_t *buf_offset;
 
-    SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);
+    SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event);
 
     if (!scon->chr) {
         /* If there's no backend, we can just say we consumed all data. */
@@ -248,7 +244,7 @@ static int write_event_data(SCLPEvent *event, EventBufferHeader *ebh)
     int errors = 0;
     MDBO *mdbo;
     SclpMsg *data = (SclpMsg *) ebh;
-    SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);
+    SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event);
 
     len = be16_to_cpu(data->mdb.header.length);
     if (len < sizeof(data->mdb.header)) {
@@ -317,7 +313,7 @@ static int console_init(SCLPEvent *event)
 {
     static bool console_available;
 
-    SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);
+    SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event);
 
     if (console_available) {
         error_report("Multiple line-mode operator consoles are not supported");
@@ -340,7 +336,7 @@ static int console_exit(SCLPEvent *event)
 static void console_reset(DeviceState *dev)
 {
    SCLPEvent *event = SCLP_EVENT(dev);
-   SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);
+   SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event);
 
    event->event_pending = false;
    scon->length = 0;
index d224648..45997ff 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "hw/qdev.h"
+#include <hw/qdev.h>
 #include "qemu/thread.h"
 #include "qemu/error-report.h"
 
@@ -40,10 +40,6 @@ typedef struct SCLPConsole {
     bool notify;            /* qemu_notify_event() req'd if true           */
 } SCLPConsole;
 
-#define TYPE_SCLP_CONSOLE "sclpconsole"
-#define SCLP_CONSOLE(obj) \
-    OBJECT_CHECK(SCLPConsole, (obj), TYPE_SCLP_CONSOLE)
-
 /* character layer call-back functions */
 
 /* Return number of bytes that fit into iov buffer */
@@ -99,7 +95,7 @@ static unsigned int receive_mask(void)
 static void get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size,
                              int avail)
 {
-    SCLPConsole *cons = SCLP_CONSOLE(event);
+    SCLPConsole *cons = DO_UPCAST(SCLPConsole, event, event);
 
     /* first byte is hex 0 saying an ascii string follows */
     *buf++ = '\0';
@@ -161,7 +157,7 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
 static ssize_t write_console_data(SCLPEvent *event, const uint8_t *buf,
                                   size_t len)
 {
-    SCLPConsole *scon = SCLP_CONSOLE(event);
+    SCLPConsole *scon = DO_UPCAST(SCLPConsole, event, event);
 
     if (!scon->chr) {
         /* If there's no backend, we can just say we consumed all data. */
@@ -218,7 +214,7 @@ static int console_init(SCLPEvent *event)
 {
     static bool console_available;
 
-    SCLPConsole *scon = SCLP_CONSOLE(event);
+    SCLPConsole *scon = DO_UPCAST(SCLPConsole, event, event);
 
     if (console_available) {
         error_report("Multiple VT220 operator consoles are not supported");
@@ -236,7 +232,7 @@ static int console_init(SCLPEvent *event)
 static void console_reset(DeviceState *dev)
 {
    SCLPEvent *event = SCLP_EVENT(dev);
-   SCLPConsole *scon = SCLP_CONSOLE(event);
+   SCLPConsole *scon = DO_UPCAST(SCLPConsole, event, event);
 
    event->event_pending = false;
    scon->iov_sclp = 0;
index 3442f47..6d815b5 100644 (file)
@@ -106,7 +106,6 @@ do {} while (0)
 #endif
 
 static void serial_receive1(void *opaque, const uint8_t *buf, int size);
-static void serial_xmit(SerialState *s);
 
 static inline void recv_fifo_put(SerialState *s, uint8_t chr)
 {
@@ -224,20 +223,13 @@ static void serial_update_msl(SerialState *s)
     }
 }
 
-static gboolean serial_watch_cb(GIOChannel *chan, GIOCondition cond,
-                                void *opaque)
+static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)
 {
     SerialState *s = opaque;
-    s->watch_tag = 0;
-    serial_xmit(s);
-    return FALSE;
-}
 
-static void serial_xmit(SerialState *s)
-{
     do {
         assert(!(s->lsr & UART_LSR_TEMT));
-        if (s->tsr_retry == 0) {
+        if (s->tsr_retry <= 0) {
             assert(!(s->lsr & UART_LSR_THRE));
 
             if (s->fcr & UART_FCR_FE) {
@@ -259,17 +251,17 @@ static void serial_xmit(SerialState *s)
         if (s->mcr & UART_MCR_LOOP) {
             /* in loopback mode, say that we just received a char */
             serial_receive1(s, &s->tsr, 1);
-        } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1 &&
-                   s->tsr_retry < MAX_XMIT_RETRY) {
-            assert(s->watch_tag == 0);
-            s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
-                                                 serial_watch_cb, s);
-            if (s->watch_tag > 0) {
+        } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) {
+            if (s->tsr_retry >= 0 && s->tsr_retry < MAX_XMIT_RETRY &&
+                qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
+                                      serial_xmit, s) > 0) {
                 s->tsr_retry++;
-                return;
+                return FALSE;
             }
+            s->tsr_retry = 0;
+        } else {
+            s->tsr_retry = 0;
         }
-        s->tsr_retry = 0;
 
         /* Transmit another byte if it is already available. It is only
            possible when FIFO is enabled and not empty. */
@@ -277,8 +269,11 @@ static void serial_xmit(SerialState *s)
 
     s->last_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     s->lsr |= UART_LSR_TEMT;
+
+    return FALSE;
 }
 
+
 /* Setter for FCR.
    is_load flag means, that value is set while loading VM state
    and interrupt should not be invoked */
@@ -335,8 +330,8 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
             s->lsr &= ~UART_LSR_THRE;
             s->lsr &= ~UART_LSR_TEMT;
             serial_update_irq(s);
-            if (s->tsr_retry == 0) {
-                serial_xmit(s);
+            if (s->tsr_retry <= 0) {
+                serial_xmit(NULL, G_IO_OUT, s);
             }
         }
         break;
@@ -644,31 +639,6 @@ static int serial_post_load(void *opaque, int version_id)
     if (s->thr_ipending == -1) {
         s->thr_ipending = ((s->iir & UART_IIR_ID) == UART_IIR_THRI);
     }
-
-    if (s->tsr_retry > 0) {
-        /* tsr_retry > 0 implies LSR.TEMT = 0 (transmitter not empty).  */
-        if (s->lsr & UART_LSR_TEMT) {
-            error_report("inconsistent state in serial device "
-                         "(tsr empty, tsr_retry=%d", s->tsr_retry);
-            return -1;
-        }
-
-        if (s->tsr_retry > MAX_XMIT_RETRY) {
-            s->tsr_retry = MAX_XMIT_RETRY;
-        }
-
-        assert(s->watch_tag == 0);
-        s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
-                                             serial_watch_cb, s);
-    } else {
-        /* tsr_retry == 0 implies LSR.TEMT = 1 (transmitter empty).  */
-        if (!(s->lsr & UART_LSR_TEMT)) {
-            error_report("inconsistent state in serial device "
-                         "(tsr not empty, tsr_retry=0");
-            return -1;
-        }
-    }
-
     s->last_break_enable = (s->lcr >> 6) & 1;
     /* Initialize fcr via setter to perform essential side-effects */
     serial_write_fcr(s, s->fcr_vmstate);
@@ -715,7 +685,7 @@ static const VMStateDescription vmstate_serial_tsr = {
     .minimum_version_id = 1,
     .needed = serial_tsr_needed,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT32(tsr_retry, SerialState),
+        VMSTATE_INT32(tsr_retry, SerialState),
         VMSTATE_UINT8(thr, SerialState),
         VMSTATE_UINT8(tsr, SerialState),
         VMSTATE_END_OF_LIST()
@@ -845,11 +815,6 @@ static void serial_reset(void *opaque)
 {
     SerialState *s = opaque;
 
-    if (s->watch_tag > 0) {
-        g_source_remove(s->watch_tag);
-        s->watch_tag = 0;
-    }
-
     s->rbr = 0;
     s->ier = 0;
     s->iir = UART_IIR_NO_INT;
index 15657ab..a94d61c 100644 (file)
@@ -24,7 +24,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/char/stm32f2xx_usart.h"
-#include "qemu/log.h"
 
 #ifndef STM_USART_ERR_DEBUG
 #define STM_USART_ERR_DEBUG 0
@@ -190,11 +189,6 @@ static const MemoryRegionOps stm32f2xx_usart_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static Property stm32f2xx_usart_properties[] = {
-    DEFINE_PROP_CHR("chardev", STM32F2XXUsartState, chr),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 static void stm32f2xx_usart_init(Object *obj)
 {
     STM32F2XXUsartState *s = STM32F2XX_USART(obj);
@@ -204,11 +198,9 @@ static void stm32f2xx_usart_init(Object *obj)
     memory_region_init_io(&s->mmio, obj, &stm32f2xx_usart_ops, s,
                           TYPE_STM32F2XX_USART, 0x2000);
     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
-}
 
-static void stm32f2xx_usart_realize(DeviceState *dev, Error **errp)
-{
-    STM32F2XXUsartState *s = STM32F2XX_USART(dev);
+    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
+    s->chr = qemu_char_get_next_serial();
 
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, stm32f2xx_usart_can_receive,
@@ -221,8 +213,8 @@ static void stm32f2xx_usart_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->reset = stm32f2xx_usart_reset;
-    dc->props = stm32f2xx_usart_properties;
-    dc->realize = stm32f2xx_usart_realize;
+    /* Reason: instance_init() method uses qemu_char_get_next_serial() */
+    dc->cannot_instantiate_with_device_add_yet = true;
 }
 
 static const TypeInfo stm32f2xx_usart_info = {
diff --git a/hw/char/trace-events b/hw/char/trace-events
deleted file mode 100644 (file)
index d53577c..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/char/virtio-serial-bus.c
-virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t value) "port %u, event %u, value %u"
-virtio_serial_throttle_port(unsigned int port, bool throttle) "port %u, throttle %d"
-virtio_serial_handle_control_message(uint16_t event, uint16_t value) "event %u, value %u"
-virtio_serial_handle_control_message_port(unsigned int port) "port %u"
-
-# hw/char/virtio-console.c
-virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret) "port %u, in_len %zu, out_len %zd"
-virtio_console_chr_read(unsigned int port, int size) "port %u, size %d"
-virtio_console_chr_event(unsigned int port, int event) "port %u, event %d"
-
-# hw/char/grlib_apbuart.c
-grlib_apbuart_event(int event) "event:%d"
-grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
-grlib_apbuart_readl_unknown(uint64_t addr) "addr 0x%"PRIx64
-
-# hw/char/lm32_juart.c
-lm32_juart_get_jtx(uint32_t value) "jtx 0x%08x"
-lm32_juart_set_jtx(uint32_t value) "jtx 0x%08x"
-lm32_juart_get_jrx(uint32_t value) "jrx 0x%08x"
-lm32_juart_set_jrx(uint32_t value) "jrx 0x%08x"
-
-# hw/char/lm32_uart.c
-lm32_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-lm32_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-lm32_uart_irq_state(int level) "irq state %d"
-
-# hw/char/milkymist-uart.c
-milkymist_uart_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_uart_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_uart_raise_irq(void) "Raise IRQ"
-milkymist_uart_lower_irq(void) "Lower IRQ"
-
-# hw/char/escc.c
-escc_put_queue(char channel, int b) "channel %c put: 0x%02x"
-escc_get_queue(char channel, int val) "channel %c get 0x%02x"
-escc_update_irq(int irq) "IRQ = %d"
-escc_update_parameters(char channel, int speed, int parity, int data_bits, int stop_bits) "channel %c: speed=%d parity=%c data=%d stop=%d"
-escc_mem_writeb_ctrl(char channel, uint32_t reg, uint32_t val) "Write channel %c, reg[%d] = %2.2x"
-escc_mem_writeb_data(char channel, uint32_t val) "Write channel %c, ch %d"
-escc_mem_readb_ctrl(char channel, uint32_t reg, uint8_t val) "Read channel %c, reg[%d] = %2.2x"
-escc_mem_readb_data(char channel, uint32_t ret) "Read channel %c, ch %d"
-escc_serial_receive_byte(char channel, int ch) "channel %c put ch %d"
-escc_sunkbd_event_in(int ch, const char *name, int down) "QKeyCode 0x%2.2x [%s], down %d"
-escc_sunkbd_event_out(int ch) "Translated keycode 0x%2.2x"
-escc_kbd_command(int val) "Command %d"
-escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=%01x"
index 4f0e03d..2e36481 100644 (file)
@@ -85,9 +85,8 @@ static void set_guest_connected(VirtIOSerialPort *port, int guest_connected)
 {
     VirtConsole *vcon = VIRTIO_CONSOLE(port);
     DeviceState *dev = DEVICE(port);
-    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
 
-    if (vcon->chr && !k->is_console) {
+    if (vcon->chr) {
         qemu_chr_fe_set_open(vcon->chr, guest_connected);
     }
 
@@ -157,25 +156,9 @@ static void virtconsole_realize(DeviceState *dev, Error **errp)
     }
 
     if (vcon->chr) {
-        /*
-         * For consoles we don't block guest data transfer just
-         * because nothing is connected - we'll just let it go
-         * whetherever the chardev wants - /dev/null probably.
-         *
-         * For serial ports we need 100% reliable data transfer
-         * so we use the opened/closed signals from chardev to
-         * trigger open/close of the device
-         */
-        if (k->is_console) {
-            vcon->chr->explicit_fe_open = 0;
-            qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read,
-                                  NULL, vcon);
-            virtio_serial_open(port);
-        } else {
-            vcon->chr->explicit_fe_open = 1;
-            qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read,
-                                  chr_event, vcon);
-        }
+        vcon->chr->explicit_fe_open = 1;
+        qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
+                              vcon);
     }
 }
 
index db57a38..6e5de6d 100644 (file)
@@ -594,6 +594,12 @@ static void vser_reset(VirtIODevice *vdev)
     guest_reset(vser);
 }
 
+static void virtio_serial_save(QEMUFile *f, void *opaque)
+{
+    /* The virtio device */
+    virtio_save(VIRTIO_DEVICE(opaque), f);
+}
+
 static void virtio_serial_save_device(VirtIODevice *vdev, QEMUFile *f)
 {
     VirtIOSerial *s = VIRTIO_SERIAL(vdev);
@@ -679,7 +685,7 @@ static void virtio_serial_post_load_timer_cb(void *opaque)
     s->post_load = NULL;
 }
 
-static int fetch_active_ports_list(QEMUFile *f,
+static int fetch_active_ports_list(QEMUFile *f, int version_id,
                                    VirtIOSerial *s, uint32_t nr_active_ports)
 {
     uint32_t i;
@@ -696,7 +702,6 @@ static int fetch_active_ports_list(QEMUFile *f,
     /* Items in struct VirtIOSerialPort */
     for (i = 0; i < nr_active_ports; i++) {
         VirtIOSerialPort *port;
-        uint32_t elem_popped;
         uint32_t id;
 
         id = qemu_get_be32(f);
@@ -709,29 +714,37 @@ static int fetch_active_ports_list(QEMUFile *f,
         s->post_load->connected[i].port = port;
         s->post_load->connected[i].host_connected = qemu_get_byte(f);
 
-        qemu_get_be32s(f, &elem_popped);
-        if (elem_popped) {
-            qemu_get_be32s(f, &port->iov_idx);
-            qemu_get_be64s(f, &port->iov_offset);
+        if (version_id > 2) {
+            uint32_t elem_popped;
 
-            port->elem =
-                qemu_get_virtqueue_element(f, sizeof(VirtQueueElement));
+            qemu_get_be32s(f, &elem_popped);
+            if (elem_popped) {
+                qemu_get_be32s(f, &port->iov_idx);
+                qemu_get_be64s(f, &port->iov_offset);
 
-            /*
-             *  Port was throttled on source machine.  Let's
-             *  unthrottle it here so data starts flowing again.
-             */
-            virtio_serial_throttle_port(port, false);
+                port->elem =
+                    qemu_get_virtqueue_element(f, sizeof(VirtQueueElement));
+
+                /*
+                 *  Port was throttled on source machine.  Let's
+                 *  unthrottle it here so data starts flowing again.
+                 */
+                virtio_serial_throttle_port(port, false);
+            }
         }
     }
     timer_mod(s->post_load->timer, 1);
     return 0;
 }
 
-static int virtio_serial_load(QEMUFile *f, void *opaque, size_t size)
+static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
 {
+    if (version_id > 3) {
+        return -EINVAL;
+    }
+
     /* The virtio device */
-    return virtio_load(VIRTIO_DEVICE(opaque), f, 3);
+    return virtio_load(VIRTIO_DEVICE(opaque), f, version_id);
 }
 
 static int virtio_serial_load_device(VirtIODevice *vdev, QEMUFile *f,
@@ -743,6 +756,10 @@ static int virtio_serial_load_device(VirtIODevice *vdev, QEMUFile *f,
     int ret;
     uint32_t tmp;
 
+    if (version_id < 2) {
+        return 0;
+    }
+
     /* Unused */
     qemu_get_be16s(f, (uint16_t *) &tmp);
     qemu_get_be16s(f, (uint16_t *) &tmp);
@@ -764,7 +781,7 @@ static int virtio_serial_load_device(VirtIODevice *vdev, QEMUFile *f,
     qemu_get_be32s(f, &nr_active_ports);
 
     if (nr_active_ports) {
-        ret = fetch_active_ports_list(f, s, nr_active_ports);
+        ret = fetch_active_ports_list(f, version_id, s, nr_active_ports);
         if (ret) {
             return ret;
         }
@@ -1032,6 +1049,13 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
 
     vser->post_load = NULL;
 
+    /*
+     * Register for the savevm section with the virtio-console name
+     * to preserve backward compat
+     */
+    register_savevm(dev, "virtio-console", -1, 3, virtio_serial_save,
+                    virtio_serial_load, vser);
+
     QLIST_INSERT_HEAD(&vserdevices.devices, vser, next);
 }
 
@@ -1062,6 +1086,8 @@ static void virtio_serial_device_unrealize(DeviceState *dev, Error **errp)
 
     QLIST_REMOVE(vser, next);
 
+    unregister_savevm(dev, "virtio-console", vser);
+
     g_free(vser->ivqs);
     g_free(vser->ovqs);
     g_free(vser->ports_map);
@@ -1074,9 +1100,6 @@ static void virtio_serial_device_unrealize(DeviceState *dev, Error **errp)
     virtio_cleanup(vdev);
 }
 
-/* Note: 'console' is used for backwards compatibility */
-VMSTATE_VIRTIO_DEVICE(console, 3, virtio_serial_load, virtio_vmstate_save);
-
 static Property virtio_serial_properties[] = {
     DEFINE_PROP_UINT32("max_ports", VirtIOSerial, serial.max_virtserial_ports,
                                                   31),
@@ -1092,7 +1115,6 @@ static void virtio_serial_class_init(ObjectClass *klass, void *data)
     QLIST_INIT(&vserdevices.devices);
 
     dc->props = virtio_serial_properties;
-    dc->vmsd = &vmstate_virtio_console;
     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
     vdc->realize = virtio_serial_device_realize;
     vdc->unrealize = virtio_serial_device_unrealize;
index 83108b0..cbf1dcc 100644 (file)
@@ -22,6 +22,7 @@
 #include "qemu/osdep.h"
 #include <sys/select.h>
 #include <termios.h>
+#include <sys/mman.h>
 
 #include "hw/hw.h"
 #include "sysemu/char.h"
index 4847efb..911af4a 100644 (file)
@@ -172,11 +172,6 @@ static const MemoryRegionOps uart_ops = {
     }
 };
 
-static Property xilinx_uartlite_properties[] = {
-    DEFINE_PROP_CHR("chardev", XilinxUARTLite, chr),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 static void uart_rx(void *opaque, const uint8_t *buf, int size)
 {
     XilinxUARTLite *s = opaque;
@@ -211,6 +206,8 @@ static void xilinx_uartlite_realize(DeviceState *dev, Error **errp)
 {
     XilinxUARTLite *s = XILINX_UARTLITE(dev);
 
+    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
+    s->chr = qemu_char_get_next_serial();
     if (s->chr)
         qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
 }
@@ -232,7 +229,8 @@ static void xilinx_uartlite_class_init(ObjectClass *klass, void *data)
 
     dc->reset = xilinx_uartlite_reset;
     dc->realize = xilinx_uartlite_realize;
-    dc->props = xilinx_uartlite_properties;
+    /* Reason: realize() method uses qemu_char_get_next_serial() */
+    dc->cannot_instantiate_with_device_add_yet = true;
 }
 
 static const TypeInfo xilinx_uartlite_info = {
index cfd4840..abb3560 100644 (file)
@@ -1,11 +1,10 @@
 # core qdev-related obj files, also used by *-user:
 common-obj-y += qdev.o qdev-properties.o
-common-obj-y += bus.o
 common-obj-y += fw-path-provider.o
 # irq.o needed for qdev GPIO handling:
 common-obj-y += irq.o
 common-obj-y += hotplug.o
-obj-y += nmi.o
+common-obj-y += nmi.o
 
 common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
 common-obj-$(CONFIG_XILINX_AXI) += stream.o
@@ -15,5 +14,4 @@ common-obj-$(CONFIG_SOFTMMU) += machine.o
 common-obj-$(CONFIG_SOFTMMU) += null-machine.o
 common-obj-$(CONFIG_SOFTMMU) += loader.o
 common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
-common-obj-$(CONFIG_SOFTMMU) += register.o
 common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
diff --git a/hw/core/bus.c b/hw/core/bus.c
deleted file mode 100644 (file)
index 3e3f8ac..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- *  Dynamic device configuration and creation -- buses.
- *
- *  Copyright (c) 2009 CodeSourcery
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "hw/qdev.h"
-#include "qapi/error.h"
-
-static void qbus_set_hotplug_handler_internal(BusState *bus, Object *handler,
-                                              Error **errp)
-{
-
-    object_property_set_link(OBJECT(bus), OBJECT(handler),
-                             QDEV_HOTPLUG_HANDLER_PROPERTY, errp);
-}
-
-void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, Error **errp)
-{
-    qbus_set_hotplug_handler_internal(bus, OBJECT(handler), errp);
-}
-
-void qbus_set_bus_hotplug_handler(BusState *bus, Error **errp)
-{
-    qbus_set_hotplug_handler_internal(bus, OBJECT(bus), errp);
-}
-
-int qbus_walk_children(BusState *bus,
-                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
-                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
-                       void *opaque)
-{
-    BusChild *kid;
-    int err;
-
-    if (pre_busfn) {
-        err = pre_busfn(bus, opaque);
-        if (err) {
-            return err;
-        }
-    }
-
-    QTAILQ_FOREACH(kid, &bus->children, sibling) {
-        err = qdev_walk_children(kid->child,
-                                 pre_devfn, pre_busfn,
-                                 post_devfn, post_busfn, opaque);
-        if (err < 0) {
-            return err;
-        }
-    }
-
-    if (post_busfn) {
-        err = post_busfn(bus, opaque);
-        if (err) {
-            return err;
-        }
-    }
-
-    return 0;
-}
-
-static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
-{
-    const char *typename = object_get_typename(OBJECT(bus));
-    BusClass *bc;
-    char *buf;
-    int i, len, bus_id;
-
-    bus->parent = parent;
-
-    if (name) {
-        bus->name = g_strdup(name);
-    } else if (bus->parent && bus->parent->id) {
-        /* parent device has id -> use it plus parent-bus-id for bus name */
-        bus_id = bus->parent->num_child_bus;
-
-        len = strlen(bus->parent->id) + 16;
-        buf = g_malloc(len);
-        snprintf(buf, len, "%s.%d", bus->parent->id, bus_id);
-        bus->name = buf;
-    } else {
-        /* no id -> use lowercase bus type plus global bus-id for bus name */
-        bc = BUS_GET_CLASS(bus);
-        bus_id = bc->automatic_ids++;
-
-        len = strlen(typename) + 16;
-        buf = g_malloc(len);
-        len = snprintf(buf, len, "%s.%d", typename, bus_id);
-        for (i = 0; i < len; i++) {
-            buf[i] = qemu_tolower(buf[i]);
-        }
-        bus->name = buf;
-    }
-
-    if (bus->parent) {
-        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
-        bus->parent->num_child_bus++;
-        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
-        object_unref(OBJECT(bus));
-    } else if (bus != sysbus_get_default()) {
-        /* TODO: once all bus devices are qdevified,
-           only reset handler for main_system_bus should be registered here. */
-        qemu_register_reset(qbus_reset_all_fn, bus);
-    }
-}
-
-static void bus_unparent(Object *obj)
-{
-    BusState *bus = BUS(obj);
-    BusChild *kid;
-
-    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
-        DeviceState *dev = kid->child;
-        object_unparent(OBJECT(dev));
-    }
-    if (bus->parent) {
-        QLIST_REMOVE(bus, sibling);
-        bus->parent->num_child_bus--;
-        bus->parent = NULL;
-    } else {
-        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
-        qemu_unregister_reset(qbus_reset_all_fn, bus);
-    }
-}
-
-void qbus_create_inplace(void *bus, size_t size, const char *typename,
-                         DeviceState *parent, const char *name)
-{
-    object_initialize(bus, size, typename);
-    qbus_realize(bus, parent, name);
-}
-
-BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
-{
-    BusState *bus;
-
-    bus = BUS(object_new(typename));
-    qbus_realize(bus, parent, name);
-
-    return bus;
-}
-
-static bool bus_get_realized(Object *obj, Error **errp)
-{
-    BusState *bus = BUS(obj);
-
-    return bus->realized;
-}
-
-static void bus_set_realized(Object *obj, bool value, Error **errp)
-{
-    BusState *bus = BUS(obj);
-    BusClass *bc = BUS_GET_CLASS(bus);
-    BusChild *kid;
-    Error *local_err = NULL;
-
-    if (value && !bus->realized) {
-        if (bc->realize) {
-            bc->realize(bus, &local_err);
-        }
-
-        /* TODO: recursive realization */
-    } else if (!value && bus->realized) {
-        QTAILQ_FOREACH(kid, &bus->children, sibling) {
-            DeviceState *dev = kid->child;
-            object_property_set_bool(OBJECT(dev), false, "realized",
-                                     &local_err);
-            if (local_err != NULL) {
-                break;
-            }
-        }
-        if (bc->unrealize && local_err == NULL) {
-            bc->unrealize(bus, &local_err);
-        }
-    }
-
-    if (local_err != NULL) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    bus->realized = value;
-}
-
-static void qbus_initfn(Object *obj)
-{
-    BusState *bus = BUS(obj);
-
-    QTAILQ_INIT(&bus->children);
-    object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
-                             TYPE_HOTPLUG_HANDLER,
-                             (Object **)&bus->hotplug_handler,
-                             object_property_allow_set_link,
-                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
-                             NULL);
-    object_property_add_bool(obj, "realized",
-                             bus_get_realized, bus_set_realized, NULL);
-}
-
-static char *default_bus_get_fw_dev_path(DeviceState *dev)
-{
-    return g_strdup(object_get_typename(OBJECT(dev)));
-}
-
-static void bus_class_init(ObjectClass *class, void *data)
-{
-    BusClass *bc = BUS_CLASS(class);
-
-    class->unparent = bus_unparent;
-    bc->get_fw_dev_path = default_bus_get_fw_dev_path;
-}
-
-static void qbus_finalize(Object *obj)
-{
-    BusState *bus = BUS(obj);
-
-    g_free((char *)bus->name);
-}
-
-static const TypeInfo bus_info = {
-    .name = TYPE_BUS,
-    .parent = TYPE_OBJECT,
-    .instance_size = sizeof(BusState),
-    .abstract = true,
-    .class_size = sizeof(BusClass),
-    .instance_init = qbus_initfn,
-    .instance_finalize = qbus_finalize,
-    .class_init = bus_class_init,
-};
-
-static void bus_register_types(void)
-{
-    type_register_static(&bus_info);
-}
-
-type_init(bus_register_types)
index 17ac986..645cfca 100644 (file)
 #include "hw/hotplug.h"
 #include "qemu/module.h"
 
-void hotplug_handler_pre_plug(HotplugHandler *plug_handler,
-                              DeviceState *plugged_dev,
-                              Error **errp)
-{
-    HotplugHandlerClass *hdc = HOTPLUG_HANDLER_GET_CLASS(plug_handler);
-
-    if (hdc->pre_plug) {
-        hdc->pre_plug(plug_handler, plugged_dev, errp);
-    }
-}
-
 void hotplug_handler_plug(HotplugHandler *plug_handler,
                           DeviceState *plugged_dev,
                           Error **errp)
index 53e0e41..c049957 100644 (file)
@@ -914,16 +914,10 @@ int rom_add_file(const char *file, const char *fw_dir,
 err:
     if (fd != -1)
         close(fd);
-
     g_free(rom->data);
     g_free(rom->path);
     g_free(rom->name);
-    if (fw_dir) {
-        g_free(rom->fw_dir);
-        g_free(rom->fw_file);
-    }
     g_free(rom);
-
     return -1;
 }
 
index e5a456f..6dbbc85 100644 (file)
@@ -65,9 +65,6 @@ static void machine_set_kernel_irqchip(Object *obj, Visitor *v,
             ms->kernel_irqchip_split = true;
             break;
         default:
-            /* The value was checked in visit_type_OnOffSplit() above. If
-             * we get here, then something is wrong in QEMU.
-             */
             abort();
         }
     }
@@ -260,47 +257,47 @@ static void machine_set_usb(Object *obj, bool value, Error **errp)
     ms->usb_disabled = !value;
 }
 
-static bool machine_get_graphics(Object *obj, Error **errp)
+static bool machine_get_igd_gfx_passthru(Object *obj, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
-    return ms->enable_graphics;
+    return ms->igd_gfx_passthru;
 }
 
-static void machine_set_graphics(Object *obj, bool value, Error **errp)
+static void machine_set_igd_gfx_passthru(Object *obj, bool value, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
-    ms->enable_graphics = value;
+    ms->igd_gfx_passthru = value;
 }
 
-static bool machine_get_igd_gfx_passthru(Object *obj, Error **errp)
+static char *machine_get_firmware(Object *obj, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
-    return ms->igd_gfx_passthru;
+    return g_strdup(ms->firmware);
 }
 
-static void machine_set_igd_gfx_passthru(Object *obj, bool value, Error **errp)
+static void machine_set_firmware(Object *obj, const char *value, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
-    ms->igd_gfx_passthru = value;
+    g_free(ms->firmware);
+    ms->firmware = g_strdup(value);
 }
 
-static char *machine_get_firmware(Object *obj, Error **errp)
+static bool machine_get_iommu(Object *obj, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
-    return g_strdup(ms->firmware);
+    return ms->iommu;
 }
 
-static void machine_set_firmware(Object *obj, const char *value, Error **errp)
+static void machine_set_iommu(Object *obj, bool value, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
-    g_free(ms->firmware);
-    ms->firmware = g_strdup(value);
+    ms->iommu = value;
 }
 
 static void machine_set_suppress_vmdesc(Object *obj, bool value, Error **errp)
@@ -385,7 +382,6 @@ static void machine_initfn(Object *obj)
     ms->kvm_shadow_mem = -1;
     ms->dump_guest_core = true;
     ms->mem_merge = true;
-    ms->enable_graphics = true;
 
     object_property_add_str(obj, "accel",
                             machine_get_accel, machine_set_accel, NULL);
@@ -464,12 +460,6 @@ static void machine_initfn(Object *obj)
     object_property_set_description(obj, "usb",
                                     "Set on/off to enable/disable usb",
                                     NULL);
-    object_property_add_bool(obj, "graphics",
-                             machine_get_graphics,
-                             machine_set_graphics, NULL);
-    object_property_set_description(obj, "graphics",
-                                    "Set on/off to enable/disable graphics emulation",
-                                    NULL);
     object_property_add_bool(obj, "igd-passthru",
                              machine_get_igd_gfx_passthru,
                              machine_set_igd_gfx_passthru, NULL);
@@ -482,6 +472,12 @@ static void machine_initfn(Object *obj)
     object_property_set_description(obj, "firmware",
                                     "Firmware image",
                                     NULL);
+    object_property_add_bool(obj, "iommu",
+                             machine_get_iommu,
+                             machine_set_iommu, NULL);
+    object_property_set_description(obj, "iommu",
+                                    "Set on/off to enable/disable Intel IOMMU (VT-d)",
+                                    NULL);
     object_property_add_bool(obj, "suppress-vmdesc",
                              machine_get_suppress_vmdesc,
                              machine_set_suppress_vmdesc, NULL);
@@ -554,33 +550,6 @@ bool machine_mem_merge(MachineState *machine)
     return machine->mem_merge;
 }
 
-static void machine_class_finalize(ObjectClass *klass, void *data)
-{
-    MachineClass *mc = MACHINE_CLASS(klass);
-
-    if (mc->compat_props) {
-        g_array_free(mc->compat_props, true);
-    }
-}
-
-void machine_register_compat_props(MachineState *machine)
-{
-    MachineClass *mc = MACHINE_GET_CLASS(machine);
-    int i;
-    GlobalProperty *p;
-
-    if (!mc->compat_props) {
-        return;
-    }
-
-    for (i = 0; i < mc->compat_props->len; i++) {
-        p = g_array_index(mc->compat_props, GlobalProperty *, i);
-        /* Machine compat_props must never cause errors: */
-        p->errp = &error_abort;
-        qdev_prop_register_global(p);
-    }
-}
-
 static const TypeInfo machine_info = {
     .name = TYPE_MACHINE,
     .parent = TYPE_OBJECT,
@@ -588,7 +557,6 @@ static const TypeInfo machine_info = {
     .class_size = sizeof(MachineClass),
     .class_init    = machine_class_init,
     .class_base_init = machine_class_base_init,
-    .class_finalize = machine_class_finalize,
     .instance_size = sizeof(MachineState),
     .instance_init = machine_initfn,
     .instance_finalize = machine_finalize,
index bfd0896..e8bcc41 100644 (file)
@@ -73,6 +73,25 @@ void nmi_monitor_handle(int cpu_index, Error **errp)
     }
 }
 
+void inject_nmi(void)
+{
+#if defined(TARGET_I386)
+    CPUState *cs;
+
+    CPU_FOREACH(cs) {
+        X86CPU *cpu = X86_CPU(cs);
+
+        if (!cpu->apic_state) {
+            cpu_interrupt(cs, CPU_INTERRUPT_NMI);
+        } else {
+            apic_deliver_nmi(cpu->apic_state);
+        }
+    }
+#else
+    nmi_monitor_handle(0, NULL);
+#endif
+}
+
 static const TypeInfo nmi_info = {
     .name          = TYPE_NMI,
     .parent        = TYPE_INTERFACE,
index 30829ee..153c835 100644 (file)
@@ -35,9 +35,6 @@ static void ptimer_trigger(ptimer_state *s)
 
 static void ptimer_reload(ptimer_state *s)
 {
-    uint32_t period_frac = s->period_frac;
-    uint64_t period = s->period;
-
     if (s->delta == 0) {
         ptimer_trigger(s);
         s->delta = s->limit;
@@ -48,24 +45,10 @@ static void ptimer_reload(ptimer_state *s)
         return;
     }
 
-    /*
-     * Artificially limit timeout rate to something
-     * achievable under QEMU.  Otherwise, QEMU spends all
-     * its time generating timer interrupts, and there
-     * is no forward progress.
-     * About ten microseconds is the fastest that really works
-     * on the current generation of host machines.
-     */
-
-    if (s->enabled == 1 && (s->delta * period < 10000) && !use_icount) {
-        period = 10000 / s->delta;
-        period_frac = 0;
-    }
-
     s->last_event = s->next_event;
-    s->next_event = s->last_event + s->delta * period;
-    if (period_frac) {
-        s->next_event += ((int64_t)period_frac * s->delta) >> 32;
+    s->next_event = s->last_event + s->delta * s->period;
+    if (s->period_frac) {
+        s->next_event += ((int64_t)s->period_frac * s->delta) >> 32;
     }
     timer_mod(s->timer, s->next_event);
 }
@@ -84,16 +67,14 @@ static void ptimer_tick(void *opaque)
 
 uint64_t ptimer_get_count(ptimer_state *s)
 {
+    int64_t now;
     uint64_t counter;
 
     if (s->enabled) {
-        int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-        int64_t next = s->next_event;
-        bool expired = (now - next >= 0);
-        bool oneshot = (s->enabled == 2);
-
+        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         /* Figure out the current counter value.  */
-        if (expired) {
+        if (now - s->next_event > 0
+            || s->period == 0) {
             /* Prevent timer underflowing if it should already have
                triggered.  */
             counter = 0;
@@ -102,13 +83,6 @@ uint64_t ptimer_get_count(ptimer_state *s)
             uint64_t div;
             int clz1, clz2;
             int shift;
-            uint32_t period_frac = s->period_frac;
-            uint64_t period = s->period;
-
-            if (!oneshot && (s->delta * period < 10000) && !use_icount) {
-                period = 10000 / s->delta;
-                period_frac = 0;
-            }
 
             /* We need to divide time by period, where time is stored in
                rem (64-bit integer) and period is stored in period/period_frac
@@ -120,8 +94,8 @@ uint64_t ptimer_get_count(ptimer_state *s)
                backwards.
             */
 
-            rem = next - now;
-            div = period;
+            rem = s->next_event - now;
+            div = s->period;
 
             clz1 = clz64(rem);
             clz2 = clz64(div);
@@ -130,13 +104,13 @@ uint64_t ptimer_get_count(ptimer_state *s)
             rem <<= shift;
             div <<= shift;
             if (shift >= 32) {
-                div |= ((uint64_t)period_frac << (shift - 32));
+                div |= ((uint64_t)s->period_frac << (shift - 32));
             } else {
                 if (shift != 0)
-                    div |= (period_frac >> (32 - shift));
+                    div |= (s->period_frac >> (32 - shift));
                 /* Look at remaining bits of period_frac and round div up if 
                    necessary.  */
-                if ((uint32_t)(period_frac << shift))
+                if ((uint32_t)(s->period_frac << shift))
                     div += 1;
             }
             counter = rem / div;
@@ -158,17 +132,16 @@ void ptimer_set_count(ptimer_state *s, uint64_t count)
 
 void ptimer_run(ptimer_state *s, int oneshot)
 {
-    bool was_disabled = !s->enabled;
-
-    if (was_disabled && s->period == 0) {
+    if (s->enabled) {
+        return;
+    }
+    if (s->period == 0) {
         fprintf(stderr, "Timer with period zero, disabling\n");
         return;
     }
     s->enabled = oneshot ? 2 : 1;
-    if (was_disabled) {
-        s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-        ptimer_reload(s);
-    }
+    s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    ptimer_reload(s);
 }
 
 /* Pause a timer.  Note that this may cause it to "lose" time, even if it
@@ -186,7 +159,6 @@ void ptimer_stop(ptimer_state *s)
 /* Set counter increment interval in nanoseconds.  */
 void ptimer_set_period(ptimer_state *s, int64_t period)
 {
-    s->delta = ptimer_get_count(s);
     s->period = period;
     s->period_frac = 0;
     if (s->enabled) {
@@ -198,7 +170,6 @@ void ptimer_set_period(ptimer_state *s, int64_t period)
 /* Set counter frequency in Hz.  */
 void ptimer_set_freq(ptimer_state *s, uint32_t freq)
 {
-    s->delta = ptimer_get_count(s);
     s->period = 1000000000ll / freq;
     s->period_frac = (1000000000ll << 32) / freq;
     if (s->enabled) {
@@ -211,6 +182,19 @@ void ptimer_set_freq(ptimer_state *s, uint32_t freq)
    count = limit.  */
 void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
 {
+    /*
+     * Artificially limit timeout rate to something
+     * achievable under QEMU.  Otherwise, QEMU spends all
+     * its time generating timer interrupts, and there
+     * is no forward progress.
+     * About ten microseconds is the fastest that really works
+     * on the current generation of host machines.
+     */
+
+    if (!use_icount && limit * s->period < 10000 && s->period) {
+        limit = 10000 / s->period;
+    }
+
     s->limit = limit;
     if (reload)
         s->delta = limit;
@@ -220,11 +204,6 @@ void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
     }
 }
 
-uint64_t ptimer_get_limit(ptimer_state *s)
-{
-    return s->limit;
-}
-
 const VMStateDescription vmstate_ptimer = {
     .name = "ptimer",
     .version_id = 1,
index e55afe6..891219a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * qdev property parsing
+ * qdev property parsing and global properties
  * (parts specific for qemu-system-*)
  *
  * This file is based on code from hw/qdev-properties.c from
@@ -72,26 +72,17 @@ static void parse_drive(DeviceState *dev, const char *str, void **ptr,
                         const char *propname, Error **errp)
 {
     BlockBackend *blk;
-    bool blk_created = false;
 
     blk = blk_by_name(str);
     if (!blk) {
-        BlockDriverState *bs = bdrv_lookup_bs(NULL, str, NULL);
-        if (bs) {
-            blk = blk_new();
-            blk_insert_bs(blk, bs);
-            blk_created = true;
-        }
-    }
-    if (!blk) {
         error_setg(errp, "Property '%s.%s' can't find value '%s'",
                    object_get_typename(OBJECT(dev)), propname, str);
-        goto fail;
+        return;
     }
     if (blk_attach_dev(blk, dev) < 0) {
         DriveInfo *dinfo = blk_legacy_dinfo(blk);
 
-        if (dinfo && dinfo->type != IF_NONE) {
+        if (dinfo->type != IF_NONE) {
             error_setg(errp, "Drive '%s' is already in use because "
                        "it has been automatically connected to another "
                        "device (did you need 'if=none' in the drive options?)",
@@ -100,16 +91,9 @@ static void parse_drive(DeviceState *dev, const char *str, void **ptr,
             error_setg(errp, "Drive '%s' is already in use by another device",
                        str);
         }
-        goto fail;
+        return;
     }
-
     *ptr = blk;
-
-fail:
-    if (blk_created) {
-        /* If we need to keep a reference, blk_attach_dev() took it */
-        blk_unref(blk);
-    }
 }
 
 static void release_drive(Object *obj, const char *name, void *opaque)
@@ -119,23 +103,14 @@ static void release_drive(Object *obj, const char *name, void *opaque)
     BlockBackend **ptr = qdev_get_prop_ptr(dev, prop);
 
     if (*ptr) {
-        blockdev_auto_del(*ptr);
         blk_detach_dev(*ptr, dev);
+        blockdev_auto_del(*ptr);
     }
 }
 
 static char *print_drive(void *ptr)
 {
-    const char *name;
-
-    name = blk_name(ptr);
-    if (!*name) {
-        BlockDriverState *bs = blk_bs(ptr);
-        if (bs) {
-            name = bdrv_get_node_name(bs);
-        }
-    }
-    return g_strdup(name);
+    return g_strdup(blk_name(ptr));
 }
 
 static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
@@ -152,7 +127,7 @@ static void set_drive(Object *obj, Visitor *v, const char *name, void *opaque,
 
 PropertyInfo qdev_prop_drive = {
     .name  = "str",
-    .description = "Node name or ID of a block device to use as a backend",
+    .description = "ID of a drive to use as a backend",
     .get   = get_drive,
     .set   = set_drive,
     .release = release_drive,
@@ -256,7 +231,7 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
     }
 
     queues = qemu_find_net_clients_except(str, peers,
-                                          NET_CLIENT_DRIVER_NIC,
+                                          NET_CLIENT_OPTIONS_KIND_NIC,
                                           MAX_QUEUE_NUM);
     if (queues == 0) {
         err = -ENOENT;
@@ -387,19 +362,8 @@ PropertyInfo qdev_prop_vlan = {
 void qdev_prop_set_drive(DeviceState *dev, const char *name,
                          BlockBackend *value, Error **errp)
 {
-    const char *ref = "";
-
-    if (value) {
-        ref = blk_name(value);
-        if (!*ref) {
-            BlockDriverState *bs = blk_bs(value);
-            if (bs) {
-                ref = bdrv_get_node_name(bs);
-            }
-        }
-    }
-
-    object_property_set_str(OBJECT(dev), ref, name, errp);
+    object_property_set_str(OBJECT(dev), value ? blk_name(value) : "",
+                            name, errp);
 }
 
 void qdev_prop_set_chr(DeviceState *dev, const char *name,
@@ -430,3 +394,22 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
     }
     nd->instantiated = 1;
 }
+
+static int qdev_add_one_global(void *opaque, QemuOpts *opts, Error **errp)
+{
+    GlobalProperty *g;
+
+    g = g_malloc0(sizeof(*g));
+    g->driver   = qemu_opt_get(opts, "driver");
+    g->property = qemu_opt_get(opts, "property");
+    g->value    = qemu_opt_get(opts, "value");
+    g->user_provided = true;
+    qdev_prop_register_global(g);
+    return 0;
+}
+
+void qemu_add_globals(void)
+{
+    qemu_opts_foreach(qemu_find_opts("global"),
+                      qdev_add_one_global, NULL, NULL);
+}
index 311af6d..737d29c 100644 (file)
@@ -539,19 +539,6 @@ PropertyInfo qdev_prop_losttickpolicy = {
     .set   = set_enum,
 };
 
-/* --- Block device error handling policy --- */
-
-QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));
-
-PropertyInfo qdev_prop_blockdev_on_error = {
-    .name = "BlockdevOnError",
-    .description = "Error handling policy, "
-                   "report/ignore/enospc/stop/auto",
-    .enum_table = BlockdevOnError_lookup,
-    .get = get_enum,
-    .set = set_enum,
-};
-
 /* --- BIOS CHS translation */
 
 QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
@@ -1033,11 +1020,12 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
     *ptr = value;
 }
 
-static GList *global_props;
+static QTAILQ_HEAD(, GlobalProperty) global_props =
+        QTAILQ_HEAD_INITIALIZER(global_props);
 
 void qdev_prop_register_global(GlobalProperty *prop)
 {
-    global_props = g_list_append(global_props, prop);
+    QTAILQ_INSERT_TAIL(&global_props, prop, next);
 }
 
 void qdev_prop_register_global_list(GlobalProperty *props)
@@ -1051,11 +1039,10 @@ void qdev_prop_register_global_list(GlobalProperty *props)
 
 int qdev_prop_check_globals(void)
 {
-    GList *l;
+    GlobalProperty *prop;
     int ret = 0;
 
-    for (l = global_props; l; l = l->next) {
-        GlobalProperty *prop = l->data;
+    QTAILQ_FOREACH(prop, &global_props, next) {
         ObjectClass *oc;
         DeviceClass *dc;
         if (prop->used) {
@@ -1084,12 +1071,11 @@ int qdev_prop_check_globals(void)
 }
 
 static void qdev_prop_set_globals_for_type(DeviceState *dev,
-                                           const char *typename)
+                                const char *typename)
 {
-    GList *l;
+    GlobalProperty *prop;
 
-    for (l = global_props; l; l = l->next) {
-        GlobalProperty *prop = l->data;
+    QTAILQ_FOREACH(prop, &global_props, next) {
         Error *err = NULL;
 
         if (strcmp(typename, prop->driver) != 0) {
@@ -1098,14 +1084,10 @@ static void qdev_prop_set_globals_for_type(DeviceState *dev,
         prop->used = true;
         object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
         if (err != NULL) {
-            error_prepend(&err, "can't apply global %s.%s=%s: ",
-                          prop->driver, prop->property, prop->value);
-            if (!dev->hotplugged && prop->errp) {
-                error_propagate(prop->errp, err);
-            } else {
-                assert(prop->user_provided);
-                error_reportf_err(err, "Warning: ");
-            }
+            assert(prop->user_provided);
+            error_reportf_err(err, "Warning: global %s.%s=%s ignored: ",
+                              prop->driver, prop->property, prop->value);
+            return;
         }
     }
 }
index 5783442..db41aa1 100644 (file)
@@ -35,7 +35,6 @@
 #include "qemu/error-report.h"
 #include "hw/hotplug.h"
 #include "hw/boards.h"
-#include "hw/sysbus.h"
 #include "qapi-event.h"
 
 int qdev_hotplug = 0;
@@ -59,6 +58,9 @@ const char *qdev_fw_name(DeviceState *dev)
     return object_get_typename(OBJECT(dev));
 }
 
+static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
+                                     Error **errp);
+
 static void bus_remove_child(BusState *bus, DeviceState *child)
 {
     BusChild *kid;
@@ -107,6 +109,24 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
     bus_add_child(bus, dev);
 }
 
+static void qbus_set_hotplug_handler_internal(BusState *bus, Object *handler,
+                                              Error **errp)
+{
+
+    object_property_set_link(OBJECT(bus), OBJECT(handler),
+                             QDEV_HOTPLUG_HANDLER_PROPERTY, errp);
+}
+
+void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, Error **errp)
+{
+    qbus_set_hotplug_handler_internal(bus, OBJECT(handler), errp);
+}
+
+void qbus_set_bus_hotplug_handler(BusState *bus, Error **errp)
+{
+    qbus_set_hotplug_handler_internal(bus, OBJECT(bus), errp);
+}
+
 /* Create a new device.  This only initializes the device state
    structure and allows properties to be set.  The device still needs
    to be realized.  See qdev-core.h.  */
@@ -141,12 +161,6 @@ DeviceState *qdev_try_create(BusState *bus, const char *type)
     }
 
     if (!bus) {
-        /* Assert that the device really is a SysBusDevice before
-         * we put it onto the sysbus. Non-sysbus devices which aren't
-         * being put onto a bus should be created with object_new(TYPE_FOO),
-         * not qdev_create(NULL, TYPE_FOO).
-         */
-        g_assert(object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE));
         bus = sysbus_get_default();
     }
 
@@ -354,14 +368,12 @@ void qdev_init_nofail(DeviceState *dev)
 
     assert(!dev->realized);
 
-    object_ref(OBJECT(dev));
     object_property_set_bool(OBJECT(dev), true, "realized", &err);
     if (err) {
         error_reportf_err(err, "Initialization of device %s failed: ",
                           object_get_typename(OBJECT(dev)));
         exit(1);
     }
-    object_unref(OBJECT(dev));
 }
 
 void qdev_machine_creation_done(void)
@@ -583,6 +595,40 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
     return NULL;
 }
 
+int qbus_walk_children(BusState *bus,
+                       qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
+                       qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
+                       void *opaque)
+{
+    BusChild *kid;
+    int err;
+
+    if (pre_busfn) {
+        err = pre_busfn(bus, opaque);
+        if (err) {
+            return err;
+        }
+    }
+
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        err = qdev_walk_children(kid->child,
+                                 pre_devfn, pre_busfn,
+                                 post_devfn, post_busfn, opaque);
+        if (err < 0) {
+            return err;
+        }
+    }
+
+    if (post_busfn) {
+        err = post_busfn(bus, opaque);
+        if (err) {
+            return err;
+        }
+    }
+
+    return 0;
+}
+
 int qdev_walk_children(DeviceState *dev,
                        qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
                        qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
@@ -639,6 +685,129 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id)
     return NULL;
 }
 
+static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
+{
+    const char *typename = object_get_typename(OBJECT(bus));
+    BusClass *bc;
+    char *buf;
+    int i, len, bus_id;
+
+    bus->parent = parent;
+
+    if (name) {
+        bus->name = g_strdup(name);
+    } else if (bus->parent && bus->parent->id) {
+        /* parent device has id -> use it plus parent-bus-id for bus name */
+        bus_id = bus->parent->num_child_bus;
+
+        len = strlen(bus->parent->id) + 16;
+        buf = g_malloc(len);
+        snprintf(buf, len, "%s.%d", bus->parent->id, bus_id);
+        bus->name = buf;
+    } else {
+        /* no id -> use lowercase bus type plus global bus-id for bus name */
+        bc = BUS_GET_CLASS(bus);
+        bus_id = bc->automatic_ids++;
+
+        len = strlen(typename) + 16;
+        buf = g_malloc(len);
+        len = snprintf(buf, len, "%s.%d", typename, bus_id);
+        for (i = 0; i < len; i++) {
+            buf[i] = qemu_tolower(buf[i]);
+        }
+        bus->name = buf;
+    }
+
+    if (bus->parent) {
+        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
+        bus->parent->num_child_bus++;
+        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
+        object_unref(OBJECT(bus));
+    } else if (bus != sysbus_get_default()) {
+        /* TODO: once all bus devices are qdevified,
+           only reset handler for main_system_bus should be registered here. */
+        qemu_register_reset(qbus_reset_all_fn, bus);
+    }
+}
+
+static void bus_unparent(Object *obj)
+{
+    BusState *bus = BUS(obj);
+    BusChild *kid;
+
+    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
+        DeviceState *dev = kid->child;
+        object_unparent(OBJECT(dev));
+    }
+    if (bus->parent) {
+        QLIST_REMOVE(bus, sibling);
+        bus->parent->num_child_bus--;
+        bus->parent = NULL;
+    } else {
+        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
+        qemu_unregister_reset(qbus_reset_all_fn, bus);
+    }
+}
+
+static bool bus_get_realized(Object *obj, Error **errp)
+{
+    BusState *bus = BUS(obj);
+
+    return bus->realized;
+}
+
+static void bus_set_realized(Object *obj, bool value, Error **errp)
+{
+    BusState *bus = BUS(obj);
+    BusClass *bc = BUS_GET_CLASS(bus);
+    BusChild *kid;
+    Error *local_err = NULL;
+
+    if (value && !bus->realized) {
+        if (bc->realize) {
+            bc->realize(bus, &local_err);
+        }
+
+        /* TODO: recursive realization */
+    } else if (!value && bus->realized) {
+        QTAILQ_FOREACH(kid, &bus->children, sibling) {
+            DeviceState *dev = kid->child;
+            object_property_set_bool(OBJECT(dev), false, "realized",
+                                     &local_err);
+            if (local_err != NULL) {
+                break;
+            }
+        }
+        if (bc->unrealize && local_err == NULL) {
+            bc->unrealize(bus, &local_err);
+        }
+    }
+
+    if (local_err != NULL) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    bus->realized = value;
+}
+
+void qbus_create_inplace(void *bus, size_t size, const char *typename,
+                         DeviceState *parent, const char *name)
+{
+    object_initialize(bus, size, typename);
+    qbus_realize(bus, parent, name);
+}
+
+BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
+{
+    BusState *bus;
+
+    bus = BUS(object_new(typename));
+    qbus_realize(bus, parent, name);
+
+    return bus;
+}
+
 static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
 {
     BusClass *bc = BUS_GET_CLASS(bus);
@@ -739,20 +908,13 @@ static void qdev_get_legacy_property(Object *obj, Visitor *v,
 }
 
 /**
- * qdev_property_add_legacy:
- * @dev: Device to add the property to.
- * @prop: The qdev property definition.
- * @errp: location to store error information.
+ * @qdev_add_legacy_property - adds a legacy property
  *
- * Add a legacy QOM property to @dev for qdev property @prop.
- * On error, store error in @errp.
+ * Do not use this is new code!  Properties added through this interface will
+ * be given names and types in the "legacy" namespace.
  *
- * Legacy properties are string versions of QOM properties.  The format of
- * the string depends on the property type.  Legacy properties are only
- * needed for "info qtree".
- *
- * Do not use this is new code!  QOM Properties added through this interface
- * will be given names in the "legacy" namespace.
+ * Legacy properties are string versions of other OOM properties.  The format
+ * of the string depends on the property type.
  */
 static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                                      Error **errp)
@@ -775,14 +937,10 @@ static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
 }
 
 /**
- * qdev_property_add_static:
- * @dev: Device to add the property to.
- * @prop: The qdev property definition.
- * @errp: location to store error information.
+ * @qdev_property_add_static - add a @Property to a device.
  *
- * Add a static QOM property to @dev for qdev property @prop.
- * On error, store error in @errp.  Static properties access data in a struct.
- * The type of the QOM property is derived from prop->info.
+ * Static properties access data in a struct.  The actual type of the
+ * property and the field depends on the property type.
  */
 void qdev_property_add_static(DeviceState *dev, Property *prop,
                               Error **errp)
@@ -887,8 +1045,6 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
     HotplugHandler *hotplug_ctrl;
     BusState *bus;
     Error *local_err = NULL;
-    bool unattached_parent = false;
-    static int unattached_count;
 
     if (dev->hotplugged && !dc->hotpluggable) {
         error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
@@ -897,23 +1053,15 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
 
     if (value && !dev->realized) {
         if (!obj->parent) {
+            static int unattached_count;
             gchar *name = g_strdup_printf("device[%d]", unattached_count++);
 
             object_property_add_child(container_get(qdev_get_machine(),
                                                     "/unattached"),
                                       name, obj, &error_abort);
-            unattached_parent = true;
             g_free(name);
         }
 
-        hotplug_ctrl = qdev_get_hotplug_handler(dev);
-        if (hotplug_ctrl) {
-            hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err);
-            if (local_err != NULL) {
-                goto fail;
-            }
-        }
-
         if (dc->realize) {
             dc->realize(dev, &local_err);
         }
@@ -924,6 +1072,7 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
 
         DEVICE_LISTENER_CALL(realize, Forward, dev);
 
+        hotplug_ctrl = qdev_get_hotplug_handler(dev);
         if (hotplug_ctrl) {
             hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
         }
@@ -991,10 +1140,6 @@ post_realize_fail:
 
 fail:
     error_propagate(errp, local_err);
-    if (unattached_parent) {
-        object_unparent(OBJECT(dev));
-        unattached_count--;
-    }
 }
 
 static bool device_get_hotpluggable(Object *obj, Error **errp)
@@ -1170,8 +1315,55 @@ static const TypeInfo device_type_info = {
     .class_size = sizeof(DeviceClass),
 };
 
+static void qbus_initfn(Object *obj)
+{
+    BusState *bus = BUS(obj);
+
+    QTAILQ_INIT(&bus->children);
+    object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
+                             TYPE_HOTPLUG_HANDLER,
+                             (Object **)&bus->hotplug_handler,
+                             object_property_allow_set_link,
+                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
+                             NULL);
+    object_property_add_bool(obj, "realized",
+                             bus_get_realized, bus_set_realized, NULL);
+}
+
+static char *default_bus_get_fw_dev_path(DeviceState *dev)
+{
+    return g_strdup(object_get_typename(OBJECT(dev)));
+}
+
+static void bus_class_init(ObjectClass *class, void *data)
+{
+    BusClass *bc = BUS_CLASS(class);
+
+    class->unparent = bus_unparent;
+    bc->get_fw_dev_path = default_bus_get_fw_dev_path;
+}
+
+static void qbus_finalize(Object *obj)
+{
+    BusState *bus = BUS(obj);
+
+    g_free((char *)bus->name);
+}
+
+static const TypeInfo bus_info = {
+    .name = TYPE_BUS,
+    .parent = TYPE_OBJECT,
+    .instance_size = sizeof(BusState),
+    .abstract = true,
+    .class_size = sizeof(BusClass),
+    .instance_init = qbus_initfn,
+    .instance_finalize = qbus_finalize,
+    .class_init = bus_class_init,
+};
+
 static void qdev_register_types(void)
 {
+    type_register_static(&bus_info);
     type_register_static(&device_type_info);
 }
 
diff --git a/hw/core/register.c b/hw/core/register.c
deleted file mode 100644 (file)
index 4bfbc50..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Register Definition API
- *
- * Copyright (c) 2016 Xilinx Inc.
- * Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include "qemu/osdep.h"
-#include "hw/register.h"
-#include "hw/qdev.h"
-#include "qemu/log.h"
-
-static inline void register_write_val(RegisterInfo *reg, uint64_t val)
-{
-    g_assert(reg->data);
-
-    switch (reg->data_size) {
-    case 1:
-        *(uint8_t *)reg->data = val;
-        break;
-    case 2:
-        *(uint16_t *)reg->data = val;
-        break;
-    case 4:
-        *(uint32_t *)reg->data = val;
-        break;
-    case 8:
-        *(uint64_t *)reg->data = val;
-        break;
-    default:
-        g_assert_not_reached();
-    }
-}
-
-static inline uint64_t register_read_val(RegisterInfo *reg)
-{
-    switch (reg->data_size) {
-    case 1:
-        return *(uint8_t *)reg->data;
-    case 2:
-        return *(uint16_t *)reg->data;
-    case 4:
-        return *(uint32_t *)reg->data;
-    case 8:
-        return *(uint64_t *)reg->data;
-    default:
-        g_assert_not_reached();
-    }
-    return 0; /* unreachable */
-}
-
-void register_write(RegisterInfo *reg, uint64_t val, uint64_t we,
-                    const char *prefix, bool debug)
-{
-    uint64_t old_val, new_val, test, no_w_mask;
-    const RegisterAccessInfo *ac;
-
-    assert(reg);
-
-    ac = reg->access;
-
-    if (!ac || !ac->name) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: write to undefined device state "
-                      "(written value: %#" PRIx64 ")\n", prefix, val);
-        return;
-    }
-
-    old_val = reg->data ? register_read_val(reg) : ac->reset;
-
-    test = (old_val ^ val) & ac->rsvd;
-    if (test) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: change of value in reserved bit"
-                      "fields: %#" PRIx64 ")\n", prefix, test);
-    }
-
-    test = val & ac->unimp;
-    if (test) {
-        qemu_log_mask(LOG_UNIMP,
-                      "%s:%s writing %#" PRIx64 " to unimplemented bits:" \
-                      " %#" PRIx64 "",
-                      prefix, reg->access->name, val, ac->unimp);
-    }
-
-    /* Create the no write mask based on the read only, write to clear and
-     * reserved bit masks.
-     */
-    no_w_mask = ac->ro | ac->w1c | ac->rsvd | ~we;
-    new_val = (val & ~no_w_mask) | (old_val & no_w_mask);
-    new_val &= ~(val & ac->w1c);
-
-    if (ac->pre_write) {
-        new_val = ac->pre_write(reg, new_val);
-    }
-
-    if (debug) {
-        qemu_log("%s:%s: write of value %#" PRIx64 "\n", prefix, ac->name,
-                 new_val);
-    }
-
-    register_write_val(reg, new_val);
-
-    if (ac->post_write) {
-        ac->post_write(reg, new_val);
-    }
-}
-
-uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix,
-                       bool debug)
-{
-    uint64_t ret;
-    const RegisterAccessInfo *ac;
-
-    assert(reg);
-
-    ac = reg->access;
-    if (!ac || !ac->name) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: read from undefined device state\n",
-                      prefix);
-        return 0;
-    }
-
-    ret = reg->data ? register_read_val(reg) : ac->reset;
-
-    register_write_val(reg, ret & ~(ac->cor & re));
-
-    /* Mask based on the read enable size */
-    ret &= re;
-
-    if (ac->post_read) {
-        ret = ac->post_read(reg, ret);
-    }
-
-    if (debug) {
-        qemu_log("%s:%s: read of value %#" PRIx64 "\n", prefix,
-                 ac->name, ret);
-    }
-
-    return ret;
-}
-
-void register_reset(RegisterInfo *reg)
-{
-    g_assert(reg);
-
-    if (!reg->data || !reg->access) {
-        return;
-    }
-
-    register_write_val(reg, reg->access->reset);
-}
-
-void register_init(RegisterInfo *reg)
-{
-    assert(reg);
-
-    if (!reg->data || !reg->access) {
-        return;
-    }
-
-    object_initialize((void *)reg, sizeof(*reg), TYPE_REGISTER);
-}
-
-void register_write_memory(void *opaque, hwaddr addr,
-                           uint64_t value, unsigned size)
-{
-    RegisterInfoArray *reg_array = opaque;
-    RegisterInfo *reg = NULL;
-    uint64_t we;
-    int i;
-
-    for (i = 0; i < reg_array->num_elements; i++) {
-        if (reg_array->r[i]->access->addr == addr) {
-            reg = reg_array->r[i];
-            break;
-        }
-    }
-
-    if (!reg) {
-        qemu_log_mask(LOG_GUEST_ERROR, "Write to unimplemented register at " \
-                      "address: %#" PRIx64 "\n", addr);
-        return;
-    }
-
-    /* Generate appropriate write enable mask */
-    if (reg->data_size < size) {
-        we = MAKE_64BIT_MASK(0, reg->data_size * 8);
-    } else {
-        we = MAKE_64BIT_MASK(0, size * 8);
-    }
-
-    register_write(reg, value, we, reg_array->prefix,
-                   reg_array->debug);
-}
-
-uint64_t register_read_memory(void *opaque, hwaddr addr,
-                              unsigned size)
-{
-    RegisterInfoArray *reg_array = opaque;
-    RegisterInfo *reg = NULL;
-    uint64_t read_val;
-    int i;
-
-    for (i = 0; i < reg_array->num_elements; i++) {
-        if (reg_array->r[i]->access->addr == addr) {
-            reg = reg_array->r[i];
-            break;
-        }
-    }
-
-    if (!reg) {
-        qemu_log_mask(LOG_GUEST_ERROR, "Read to unimplemented register at " \
-                      "address: %#" PRIx64 "\n", addr);
-        return 0;
-    }
-
-    read_val = register_read(reg, size * 8, reg_array->prefix,
-                             reg_array->debug);
-
-    return extract64(read_val, 0, size * 8);
-}
-
-RegisterInfoArray *register_init_block32(DeviceState *owner,
-                                         const RegisterAccessInfo *rae,
-                                         int num, RegisterInfo *ri,
-                                         uint32_t *data,
-                                         const MemoryRegionOps *ops,
-                                         bool debug_enabled,
-                                         uint64_t memory_size)
-{
-    const char *device_prefix = object_get_typename(OBJECT(owner));
-    RegisterInfoArray *r_array = g_new0(RegisterInfoArray, 1);
-    int i;
-
-    r_array->r = g_new0(RegisterInfo *, num);
-    r_array->num_elements = num;
-    r_array->debug = debug_enabled;
-    r_array->prefix = device_prefix;
-
-    for (i = 0; i < num; i++) {
-        int index = rae[i].addr / 4;
-        RegisterInfo *r = &ri[index];
-
-        *r = (RegisterInfo) {
-            .data = &data[index],
-            .data_size = sizeof(uint32_t),
-            .access = &rae[i],
-            .opaque = owner,
-        };
-        register_init(r);
-
-        r_array->r[i] = r;
-    }
-
-    memory_region_init_io(&r_array->mem, OBJECT(owner), ops, r_array,
-                          device_prefix, memory_size);
-
-    return r_array;
-}
-
-void register_finalize_block(RegisterInfoArray *r_array)
-{
-    object_unparent(OBJECT(&r_array->mem));
-    g_free(r_array->r);
-    g_free(r_array);
-}
-
-static const TypeInfo register_info = {
-    .name  = TYPE_REGISTER,
-    .parent = TYPE_DEVICE,
-};
-
-static void register_register_types(void)
-{
-    type_register_static(&register_info);
-}
-
-type_init(register_register_types)
index c0f560b..a7dbe2b 100644 (file)
@@ -190,9 +190,9 @@ MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n)
     return dev->mmio[n].memory;
 }
 
-void sysbus_init_ioports(SysBusDevice *dev, uint32_t ioport, uint32_t size)
+void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size)
 {
-    uint32_t i;
+    pio_addr_t i;
 
     for (i = 0; i < size; i++) {
         assert(dev->num_pio < QDEV_MAX_PIO);
index 34c11a7..9fc2760 100644 (file)
@@ -26,8 +26,8 @@
  ********************************************************************
  */
 
-#ifndef UBOOT_IMAGE_H
-#define UBOOT_IMAGE_H
+#ifndef __UBOOT_IMAGE_H__
+#define __UBOOT_IMAGE_H__
 
 /*
  * Operating System Codes
@@ -155,4 +155,4 @@ typedef struct uboot_image_header {
 } uboot_image_header_t;
 
 
-#endif /* UBOOT_IMAGE_H */
+#endif /* __IMAGE_H__ */
index 942a4bb..0954a18 100644 (file)
@@ -2,5 +2,4 @@ obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o
 obj-$(CONFIG_REALVIEW) += realview_mpcore.o
 obj-$(CONFIG_A9MPCORE) += a9mpcore.o
 obj-$(CONFIG_A15MPCORE) += a15mpcore.o
-obj-y += core.o
 
index f17f292..5459ae8 100644 (file)
@@ -11,7 +11,6 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/cpu/a9mpcore.h"
-#include "qom/cpu.h"
 
 static void a9mp_priv_set_irq(void *opaque, int irq, int level)
 {
diff --git a/hw/cpu/core.c b/hw/cpu/core.c
deleted file mode 100644 (file)
index eff90c1..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * CPU core abstract device
- *
- * Copyright (C) 2016 Bharata B Rao <bharata@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#include "hw/cpu/core.h"
-#include "qapi/visitor.h"
-#include "qapi/error.h"
-#include "sysemu/cpus.h"
-
-static void core_prop_get_core_id(Object *obj, Visitor *v, const char *name,
-                                  void *opaque, Error **errp)
-{
-    CPUCore *core = CPU_CORE(obj);
-    int64_t value = core->core_id;
-
-    visit_type_int(v, name, &value, errp);
-}
-
-static void core_prop_set_core_id(Object *obj, Visitor *v, const char *name,
-                                  void *opaque, Error **errp)
-{
-    CPUCore *core = CPU_CORE(obj);
-    Error *local_err = NULL;
-    int64_t value;
-
-    visit_type_int(v, name, &value, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    core->core_id = value;
-}
-
-static void core_prop_get_nr_threads(Object *obj, Visitor *v, const char *name,
-                                     void *opaque, Error **errp)
-{
-    CPUCore *core = CPU_CORE(obj);
-    int64_t value = core->nr_threads;
-
-    visit_type_int(v, name, &value, errp);
-}
-
-static void core_prop_set_nr_threads(Object *obj, Visitor *v, const char *name,
-                                     void *opaque, Error **errp)
-{
-    CPUCore *core = CPU_CORE(obj);
-    Error *local_err = NULL;
-    int64_t value;
-
-    visit_type_int(v, name, &value, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    core->nr_threads = value;
-}
-
-static void cpu_core_instance_init(Object *obj)
-{
-    CPUCore *core = CPU_CORE(obj);
-
-    object_property_add(obj, "core-id", "int", core_prop_get_core_id,
-                        core_prop_set_core_id, NULL, NULL, NULL);
-    object_property_add(obj, "nr-threads", "int", core_prop_get_nr_threads,
-                        core_prop_set_nr_threads, NULL, NULL, NULL);
-    core->nr_threads = smp_threads;
-}
-
-static const TypeInfo cpu_core_type_info = {
-    .name = TYPE_CPU_CORE,
-    .parent = TYPE_DEVICE,
-    .abstract = true,
-    .instance_size = sizeof(CPUCore),
-    .instance_init = cpu_core_instance_init,
-};
-
-static void cpu_core_register_types(void)
-{
-    type_register_static(&cpu_core_type_info);
-}
-
-type_init(cpu_core_register_types)
index 60df887..9f58658 100644 (file)
@@ -37,7 +37,6 @@
 #include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
-#include "sysemu/sysemu.h"
 
 #define D(x)
 #define DNAND(x)
@@ -342,7 +341,8 @@ void axisdev88_init(MachineState *machine)
     sysbus_create_varargs("etraxfs,timer", 0x3005e000, irq[0x1b], nmi[1], NULL);
 
     for (i = 0; i < 4; i++) {
-        etraxfs_ser_create(0x30026000 + i * 0x2000, irq[0x14 + i], serial_hds[i]);
+        sysbus_create_simple("etraxfs,serial", 0x30026000 + i * 0x2000,
+                             irq[0x14 + i]);
     }
 
     if (kernel_filename) {
index 218854e..c4d3fa6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef HW_CRIS_BOOT_H
-#define HW_CRIS_BOOT_H
+#ifndef _CRIS_BOOT_H
+#define HW_CRIS_BOOT_H 1
 
 struct cris_load_info
 {
index 063889b..d99780e 100644 (file)
@@ -43,5 +43,3 @@ virtio-gpu.o-cflags := $(VIRGL_CFLAGS)
 virtio-gpu.o-libs += $(VIRGL_LIBS)
 virtio-gpu-3d.o-cflags := $(VIRGL_CFLAGS)
 virtio-gpu-3d.o-libs += $(VIRGL_LIBS)
-obj-$(CONFIG_DPCD) += dpcd.o
-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx_dp.o
index 166edad..05aa2d1 100644 (file)
@@ -133,7 +133,7 @@ static const VMStateDescription vmstate_ads7846 = {
     }
 };
 
-static void ads7846_realize(SSISlave *d, Error **errp)
+static int ads7846_init(SSISlave *d)
 {
     DeviceState *dev = DEVICE(d);
     ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, d);
@@ -152,13 +152,14 @@ static void ads7846_realize(SSISlave *d, Error **errp)
     ads7846_int_update(s);
 
     vmstate_register(NULL, -1, &vmstate_ads7846, s);
+    return 0;
 }
 
 static void ads7846_class_init(ObjectClass *klass, void *data)
 {
     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 
-    k->realize = ads7846_realize;
+    k->init = ads7846_init;
     k->transfer = ads7846_transfer;
 }
 
index 7eab927..506f1d3 100644 (file)
@@ -29,7 +29,6 @@
 #include "hw/display/framebuffer.h"
 #include "ui/pixel_ops.h"
 #include "hw/misc/bcm2835_mbox_defs.h"
-#include "qemu/log.h"
 
 #define DEFAULT_VCRAM_SIZE 0x4000000
 #define BCM2835_FB_OFFSET  0x00100000
index cbf07d1..c231960 100644 (file)
@@ -925,83 +925,16 @@ static void blizzard_update_display(void *opaque)
     s->my[1] = 0;
 }
 
-static void blizzard_draw_line16_32(uint32_t *dest,
-                                    const uint16_t *src, unsigned int width)
-{
-    uint16_t data;
-    unsigned int r, g, b;
-    const uint16_t *end = (const void *) src + width;
-    while (src < end) {
-        data = *src ++;
-        b = (data & 0x1f) << 3;
-        data >>= 5;
-        g = (data & 0x3f) << 2;
-        data >>= 6;
-        r = (data & 0x1f) << 3;
-        data >>= 5;
-        *dest++ = rgb_to_pixel32(r, g, b);
-    }
-}
-
-static void blizzard_draw_line24mode1_32(uint32_t *dest,
-                                         const uint8_t *src, unsigned int width)
-{
-    /* TODO: check if SDL 24-bit planes are not in the same format and
-     * if so, use memcpy */
-    unsigned int r[2], g[2], b[2];
-    const uint8_t *end = src + width;
-    while (src < end) {
-        g[0] = *src ++;
-        r[0] = *src ++;
-        r[1] = *src ++;
-        b[0] = *src ++;
-        *dest++ = rgb_to_pixel32(r[0], g[0], b[0]);
-        b[1] = *src ++;
-        g[1] = *src ++;
-        *dest++ = rgb_to_pixel32(r[1], g[1], b[1]);
-    }
-}
-
-static void blizzard_draw_line24mode2_32(uint32_t *dest,
-                                         const uint8_t *src, unsigned int width)
-{
-    unsigned int r, g, b;
-    const uint8_t *end = src + width;
-    while (src < end) {
-        r = *src ++;
-        src ++;
-        b = *src ++;
-        g = *src ++;
-        *dest++ = rgb_to_pixel32(r, g, b);
-    }
-}
-
-/* No rotation */
-static blizzard_fn_t blizzard_draw_fn_32[0x10] = {
-    NULL,
-    /* RGB 5:6:5*/
-    (blizzard_fn_t) blizzard_draw_line16_32,
-    /* RGB 6:6:6 mode 1 */
-    (blizzard_fn_t) blizzard_draw_line24mode1_32,
-    /* RGB 8:8:8 mode 1 */
-    (blizzard_fn_t) blizzard_draw_line24mode1_32,
-    NULL, NULL,
-    /* RGB 6:6:6 mode 2 */
-    (blizzard_fn_t) blizzard_draw_line24mode2_32,
-    /* RGB 8:8:8 mode 2 */
-    (blizzard_fn_t) blizzard_draw_line24mode2_32,
-    /* YUV 4:2:2 */
-    NULL,
-    /* YUV 4:2:0 */
-    NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL,
-};
-
-/* 90deg, 180deg and 270deg rotation */
-static blizzard_fn_t blizzard_draw_fn_r_32[0x10] = {
-    /* TODO */
-    [0 ... 0xf] = NULL,
-};
+#define DEPTH 8
+#include "blizzard_template.h"
+#define DEPTH 15
+#include "blizzard_template.h"
+#define DEPTH 16
+#include "blizzard_template.h"
+#define DEPTH 24
+#include "blizzard_template.h"
+#define DEPTH 32
+#include "blizzard_template.h"
 
 static const GraphicHwOps blizzard_ops = {
     .invalidate  = blizzard_invalidate_display,
@@ -1018,10 +951,35 @@ void *s1d13745_init(qemu_irq gpio_int)
     s->con = graphic_console_init(NULL, 0, &blizzard_ops, s);
     surface = qemu_console_surface(s->con);
 
-    assert(surface_bits_per_pixel(surface) == 32);
-
-    s->line_fn_tab[0] = blizzard_draw_fn_32;
-    s->line_fn_tab[1] = blizzard_draw_fn_r_32;
+    switch (surface_bits_per_pixel(surface)) {
+    case 0:
+        s->line_fn_tab[0] = s->line_fn_tab[1] =
+                g_malloc0(sizeof(blizzard_fn_t) * 0x10);
+        break;
+    case 8:
+        s->line_fn_tab[0] = blizzard_draw_fn_8;
+        s->line_fn_tab[1] = blizzard_draw_fn_r_8;
+        break;
+    case 15:
+        s->line_fn_tab[0] = blizzard_draw_fn_15;
+        s->line_fn_tab[1] = blizzard_draw_fn_r_15;
+        break;
+    case 16:
+        s->line_fn_tab[0] = blizzard_draw_fn_16;
+        s->line_fn_tab[1] = blizzard_draw_fn_r_16;
+        break;
+    case 24:
+        s->line_fn_tab[0] = blizzard_draw_fn_24;
+        s->line_fn_tab[1] = blizzard_draw_fn_r_24;
+        break;
+    case 32:
+        s->line_fn_tab[0] = blizzard_draw_fn_32;
+        s->line_fn_tab[1] = blizzard_draw_fn_r_32;
+        break;
+    default:
+        fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__);
+        exit(1);
+    }
 
     blizzard_reset(s);
 
diff --git a/hw/display/blizzard_template.h b/hw/display/blizzard_template.h
new file mode 100644 (file)
index 0000000..b7ef27c
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * QEMU Epson S1D13744/S1D13745 templates
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Written by Andrzej Zaborowski <andrew@openedhand.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define SKIP_PIXEL(to)         (to += deststep)
+#if DEPTH == 8
+# define PIXEL_TYPE            uint8_t
+# define COPY_PIXEL(to, from)  do { *to = from; SKIP_PIXEL(to); } while (0)
+# define COPY_PIXEL1(to, from) (*to++ = from)
+#elif DEPTH == 15 || DEPTH == 16
+# define PIXEL_TYPE            uint16_t
+# define COPY_PIXEL(to, from)  do { *to = from; SKIP_PIXEL(to); } while (0)
+# define COPY_PIXEL1(to, from) (*to++ = from)
+#elif DEPTH == 24
+# define PIXEL_TYPE            uint8_t
+# define COPY_PIXEL(to, from) \
+    do {                      \
+        to[0] = from;         \
+        to[1] = (from) >> 8;  \
+        to[2] = (from) >> 16; \
+        SKIP_PIXEL(to);       \
+    } while (0)
+
+# define COPY_PIXEL1(to, from) \
+    do {                       \
+        *to++ = from;          \
+        *to++ = (from) >> 8;   \
+        *to++ = (from) >> 16;  \
+    } while (0)
+#elif DEPTH == 32
+# define PIXEL_TYPE            uint32_t
+# define COPY_PIXEL(to, from)  do { *to = from; SKIP_PIXEL(to); } while (0)
+# define COPY_PIXEL1(to, from) (*to++ = from)
+#else
+# error unknown bit depth
+#endif
+
+#ifdef HOST_WORDS_BIGENDIAN
+# define SWAP_WORDS    1
+#endif
+
+static void glue(blizzard_draw_line16_, DEPTH)(PIXEL_TYPE *dest,
+                const uint16_t *src, unsigned int width)
+{
+#if !defined(SWAP_WORDS) && DEPTH == 16
+    memcpy(dest, src, width);
+#else
+    uint16_t data;
+    unsigned int r, g, b;
+    const uint16_t *end = (const void *) src + width;
+    while (src < end) {
+        data = *src ++;
+        b = (data & 0x1f) << 3;
+        data >>= 5;
+        g = (data & 0x3f) << 2;
+        data >>= 6;
+        r = (data & 0x1f) << 3;
+        data >>= 5;
+        COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b));
+    }
+#endif
+}
+
+static void glue(blizzard_draw_line24mode1_, DEPTH)(PIXEL_TYPE *dest,
+                const uint8_t *src, unsigned int width)
+{
+    /* TODO: check if SDL 24-bit planes are not in the same format and
+     * if so, use memcpy */
+    unsigned int r[2], g[2], b[2];
+    const uint8_t *end = src + width;
+    while (src < end) {
+        g[0] = *src ++;
+        r[0] = *src ++;
+        r[1] = *src ++;
+        b[0] = *src ++;
+        COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r[0], g[0], b[0]));
+        b[1] = *src ++;
+        g[1] = *src ++;
+        COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r[1], g[1], b[1]));
+    }
+}
+
+static void glue(blizzard_draw_line24mode2_, DEPTH)(PIXEL_TYPE *dest,
+                const uint8_t *src, unsigned int width)
+{
+    unsigned int r, g, b;
+    const uint8_t *end = src + width;
+    while (src < end) {
+        r = *src ++;
+        src ++;
+        b = *src ++;
+        g = *src ++;
+        COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b));
+    }
+}
+
+/* No rotation */
+static blizzard_fn_t glue(blizzard_draw_fn_, DEPTH)[0x10] = {
+    NULL,
+    /* RGB 5:6:5*/
+    (blizzard_fn_t) glue(blizzard_draw_line16_, DEPTH),
+    /* RGB 6:6:6 mode 1 */
+    (blizzard_fn_t) glue(blizzard_draw_line24mode1_, DEPTH),
+    /* RGB 8:8:8 mode 1 */
+    (blizzard_fn_t) glue(blizzard_draw_line24mode1_, DEPTH),
+    NULL, NULL,
+    /* RGB 6:6:6 mode 2 */
+    (blizzard_fn_t) glue(blizzard_draw_line24mode2_, DEPTH),
+    /* RGB 8:8:8 mode 2 */
+    (blizzard_fn_t) glue(blizzard_draw_line24mode2_, DEPTH),
+    /* YUV 4:2:2 */
+    NULL,
+    /* YUV 4:2:0 */
+    NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
+/* 90deg, 180deg and 270deg rotation */
+static blizzard_fn_t glue(blizzard_draw_fn_r_, DEPTH)[0x10] = {
+    /* TODO */
+    [0 ... 0xf] = NULL,
+};
+
+#undef DEPTH
+#undef SKIP_PIXEL
+#undef COPY_PIXEL
+#undef COPY_PIXEL1
+#undef PIXEL_TYPE
+
+#undef SWAP_WORDS
index 1174220..fc0d97f 100644 (file)
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "qemu/error-report.h"
 #include "ui/console.h"
 #include "hw/sysbus.h"
 #include "hw/loader.h"
-#include "qemu/log.h"
 
 /* Change to 1 to enable debugging */
 #define DEBUG_CG3 0
diff --git a/hw/display/dpcd.c b/hw/display/dpcd.c
deleted file mode 100644 (file)
index ce92ff6..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * dpcd.c
- *
- *  Copyright (C) 2015 : GreenSocs Ltd
- *      http://www.greensocs.com/ , email: info@greensocs.com
- *
- *  Developed by :
- *  Frederic Konrad   <fred.konrad@greensocs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option)any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/*
- * This is a simple AUX slave which emulates a connected screen.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "hw/misc/auxbus.h"
-#include "hw/display/dpcd.h"
-
-#ifndef DEBUG_DPCD
-#define DEBUG_DPCD 0
-#endif
-
-#define DPRINTF(fmt, ...) do {                                                 \
-    if (DEBUG_DPCD) {                                                          \
-        qemu_log("dpcd: " fmt, ## __VA_ARGS__);                                \
-    }                                                                          \
-} while (0);
-
-#define DPCD_READABLE_AREA                      0x600
-
-struct DPCDState {
-    /*< private >*/
-    AUXSlave parent_obj;
-
-    /*< public >*/
-    /*
-     * The DCPD is 0x7FFFF length but read as 0 after offset 0x5FF.
-     */
-    uint8_t dpcd_info[DPCD_READABLE_AREA];
-
-    MemoryRegion iomem;
-};
-
-static uint64_t dpcd_read(void *opaque, hwaddr offset, unsigned size)
-{
-    uint8_t ret;
-    DPCDState *e = DPCD(opaque);
-
-    if (offset < DPCD_READABLE_AREA) {
-        ret = e->dpcd_info[offset];
-    } else {
-        qemu_log_mask(LOG_GUEST_ERROR, "dpcd: Bad offset 0x%" HWADDR_PRIX "\n",
-                                       offset);
-        ret = 0;
-    }
-
-    DPRINTF("read 0x%" PRIX8 " @0x%" HWADDR_PRIX "\n", ret, offset);
-    return ret;
-}
-
-static void dpcd_write(void *opaque, hwaddr offset, uint64_t value,
-                       unsigned size)
-{
-    DPCDState *e = DPCD(opaque);
-
-    DPRINTF("write 0x%" PRIX8 " @0x%" HWADDR_PRIX "\n", (uint8_t)value, offset);
-
-    if (offset < DPCD_READABLE_AREA) {
-        e->dpcd_info[offset] = value;
-    } else {
-        qemu_log_mask(LOG_GUEST_ERROR, "dpcd: Bad offset 0x%" HWADDR_PRIX "\n",
-                                       offset);
-    }
-}
-
-static const MemoryRegionOps aux_ops = {
-    .read = dpcd_read,
-    .write = dpcd_write,
-    .valid = {
-        .min_access_size = 1,
-        .max_access_size = 1,
-    },
-    .impl = {
-        .min_access_size = 1,
-        .max_access_size = 1,
-    },
-};
-
-static void dpcd_reset(DeviceState *dev)
-{
-    DPCDState *s = DPCD(dev);
-
-    memset(&(s->dpcd_info), 0, sizeof(s->dpcd_info));
-
-    s->dpcd_info[DPCD_REVISION] = DPCD_REV_1_0;
-    s->dpcd_info[DPCD_MAX_LINK_RATE] = DPCD_5_4GBPS;
-    s->dpcd_info[DPCD_MAX_LANE_COUNT] = DPCD_FOUR_LANES;
-    s->dpcd_info[DPCD_RECEIVE_PORT0_CAP_0] = DPCD_EDID_PRESENT;
-    /* buffer size */
-    s->dpcd_info[DPCD_RECEIVE_PORT0_CAP_1] = 0xFF;
-
-    s->dpcd_info[DPCD_LANE0_1_STATUS] = DPCD_LANE0_CR_DONE
-                                      | DPCD_LANE0_CHANNEL_EQ_DONE
-                                      | DPCD_LANE0_SYMBOL_LOCKED
-                                      | DPCD_LANE1_CR_DONE
-                                      | DPCD_LANE1_CHANNEL_EQ_DONE
-                                      | DPCD_LANE1_SYMBOL_LOCKED;
-    s->dpcd_info[DPCD_LANE2_3_STATUS] = DPCD_LANE2_CR_DONE
-                                      | DPCD_LANE2_CHANNEL_EQ_DONE
-                                      | DPCD_LANE2_SYMBOL_LOCKED
-                                      | DPCD_LANE3_CR_DONE
-                                      | DPCD_LANE3_CHANNEL_EQ_DONE
-                                      | DPCD_LANE3_SYMBOL_LOCKED;
-
-    s->dpcd_info[DPCD_LANE_ALIGN_STATUS_UPDATED] = DPCD_INTERLANE_ALIGN_DONE;
-    s->dpcd_info[DPCD_SINK_STATUS] = DPCD_RECEIVE_PORT_0_STATUS;
-}
-
-static void dpcd_init(Object *obj)
-{
-    DPCDState *s = DPCD(obj);
-
-    memory_region_init_io(&s->iomem, obj, &aux_ops, s, TYPE_DPCD, 0x7FFFF);
-    aux_init_mmio(AUX_SLAVE(obj), &s->iomem);
-}
-
-static const VMStateDescription vmstate_dpcd = {
-    .name = TYPE_DPCD,
-    .version_id = 0,
-    .minimum_version_id = 0,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT8_ARRAY_V(dpcd_info, DPCDState, DPCD_READABLE_AREA, 0),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static void dpcd_class_init(ObjectClass *oc, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(oc);
-
-    dc->reset = dpcd_reset;
-    dc->vmsd = &vmstate_dpcd;
-}
-
-static const TypeInfo dpcd_info = {
-    .name          = TYPE_DPCD,
-    .parent        = TYPE_AUX_SLAVE,
-    .instance_size = sizeof(DPCDState),
-    .class_init    = dpcd_class_init,
-    .instance_init = dpcd_init,
-};
-
-static void dpcd_register_types(void)
-{
-    type_register_static(&dpcd_info);
-}
-
-type_init(dpcd_register_types)
index e5be713..728eb21 100644 (file)
@@ -1909,10 +1909,9 @@ static const GraphicHwOps exynos4210_fimd_ops = {
     .gfx_update  = exynos4210_fimd_update,
 };
 
-static void exynos4210_fimd_init(Object *obj)
+static int exynos4210_fimd_init(SysBusDevice *dev)
 {
-    Exynos4210fimdState *s = EXYNOS4210_FIMD(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    Exynos4210fimdState *s = EXYNOS4210_FIMD(dev);
 
     s->ifb = NULL;
 
@@ -1920,32 +1919,28 @@ static void exynos4210_fimd_init(Object *obj)
     sysbus_init_irq(dev, &s->irq[1]);
     sysbus_init_irq(dev, &s->irq[2]);
 
-    memory_region_init_io(&s->iomem, obj, &exynos4210_fimd_mmio_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &exynos4210_fimd_mmio_ops, s,
             "exynos4210.fimd", FIMD_REGS_SIZE);
     sysbus_init_mmio(dev, &s->iomem);
-}
-
-static void exynos4210_fimd_realize(DeviceState *dev, Error **errp)
-{
-    Exynos4210fimdState *s = EXYNOS4210_FIMD(dev);
+    s->console = graphic_console_init(DEVICE(dev), 0, &exynos4210_fimd_ops, s);
 
-    s->console = graphic_console_init(dev, 0, &exynos4210_fimd_ops, s);
+    return 0;
 }
 
 static void exynos4210_fimd_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     dc->vmsd = &exynos4210_fimd_vmstate;
     dc->reset = exynos4210_fimd_reset;
-    dc->realize = exynos4210_fimd_realize;
+    k->init = exynos4210_fimd_init;
 }
 
 static const TypeInfo exynos4210_fimd_info = {
     .name = TYPE_EXYNOS4210_FIMD,
     .parent = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(Exynos4210fimdState),
-    .instance_init = exynos4210_fimd_init,
     .class_init = exynos4210_fimd_class_init,
 };
 
index b72fdb1..09dcdb4 100644 (file)
@@ -267,20 +267,16 @@ static const GraphicHwOps jazz_led_ops = {
     .text_update = jazz_led_text_update,
 };
 
-static void jazz_led_init(Object *obj)
+static int jazz_led_init(SysBusDevice *dev)
 {
-    LedState *s = JAZZ_LED(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    LedState *s = JAZZ_LED(dev);
 
-    memory_region_init_io(&s->iomem, obj, &led_ops, s, "led", 1);
+    memory_region_init_io(&s->iomem, OBJECT(s), &led_ops, s, "led", 1);
     sysbus_init_mmio(dev, &s->iomem);
-}
 
-static void jazz_led_realize(DeviceState *dev, Error **errp)
-{
-    LedState *s = JAZZ_LED(dev);
+    s->con = graphic_console_init(DEVICE(dev), 0, &jazz_led_ops, s);
 
-    s->con = graphic_console_init(dev, 0, &jazz_led_ops, s);
+    return 0;
 }
 
 static void jazz_led_reset(DeviceState *d)
@@ -295,18 +291,18 @@ static void jazz_led_reset(DeviceState *d)
 static void jazz_led_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = jazz_led_init;
     dc->desc = "Jazz LED display",
     dc->vmsd = &vmstate_jazz_led;
     dc->reset = jazz_led_reset;
-    dc->realize = jazz_led_realize;
 }
 
 static const TypeInfo jazz_led_info = {
     .name          = TYPE_JAZZ_LED,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(LedState),
-    .instance_init = jazz_led_init,
     .class_init    = jazz_led_class_init,
 };
 
index 9c00184..9bc88f9 100644 (file)
@@ -20,7 +20,7 @@
  *
  *
  * Specification available at:
- *   http://milkymist.walle.cc/socdoc/tmu2.pdf
+ *   http://www.milkymist.org/socdoc/tmu2.pdf
  *
  */
 
@@ -29,7 +29,6 @@
 #include "hw/sysbus.h"
 #include "trace.h"
 #include "qemu/error-report.h"
-#include "qapi/error.h"
 
 #include <X11/Xlib.h>
 #include <epoxy/gl.h>
@@ -444,25 +443,21 @@ static void milkymist_tmu2_reset(DeviceState *d)
     }
 }
 
-static void milkymist_tmu2_init(Object *obj)
+static int milkymist_tmu2_init(SysBusDevice *dev)
 {
-    MilkymistTMU2State *s = MILKYMIST_TMU2(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    MilkymistTMU2State *s = MILKYMIST_TMU2(dev);
+
+    if (tmu2_glx_init(s)) {
+        return 1;
+    }
 
     sysbus_init_irq(dev, &s->irq);
 
-    memory_region_init_io(&s->regs_region, obj, &tmu2_mmio_ops, s,
+    memory_region_init_io(&s->regs_region, OBJECT(s), &tmu2_mmio_ops, s,
             "milkymist-tmu2", R_MAX * 4);
     sysbus_init_mmio(dev, &s->regs_region);
-}
 
-static void milkymist_tmu2_realize(DeviceState *dev, Error **errp)
-{
-    MilkymistTMU2State *s = MILKYMIST_TMU2(dev);
-
-    if (tmu2_glx_init(s)) {
-        error_setg(errp, "tmu2_glx_init failed");
-    }
+    return 0;
 }
 
 static const VMStateDescription vmstate_milkymist_tmu2 = {
@@ -478,8 +473,9 @@ static const VMStateDescription vmstate_milkymist_tmu2 = {
 static void milkymist_tmu2_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    dc->realize = milkymist_tmu2_realize;
+    k->init = milkymist_tmu2_init;
     dc->reset = milkymist_tmu2_reset;
     dc->vmsd = &vmstate_milkymist_tmu2;
 }
@@ -488,7 +484,6 @@ static const TypeInfo milkymist_tmu2_info = {
     .name          = TYPE_MILKYMIST_TMU2,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(MilkymistTMU2State),
-    .instance_init = milkymist_tmu2_init,
     .class_init    = milkymist_tmu2_class_init,
 };
 
index 177fdac..19ca256 100644 (file)
@@ -19,7 +19,7 @@
  *
  *
  * Specification available at:
- *   http://milkymist.walle.cc/socdoc/vgafb.pdf
+ *   http://www.milkymist.org/socdoc/vgafb.pdf
  */
 
 #include "qemu/osdep.h"
@@ -292,21 +292,17 @@ static const GraphicHwOps vgafb_ops = {
     .gfx_update  = vgafb_update_display,
 };
 
-static void milkymist_vgafb_init(Object *obj)
+static int milkymist_vgafb_init(SysBusDevice *dev)
 {
-    MilkymistVgafbState *s = MILKYMIST_VGAFB(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    MilkymistVgafbState *s = MILKYMIST_VGAFB(dev);
 
     memory_region_init_io(&s->regs_region, OBJECT(s), &vgafb_mmio_ops, s,
             "milkymist-vgafb", R_MAX * 4);
     sysbus_init_mmio(dev, &s->regs_region);
-}
 
-static void milkymist_vgafb_realize(DeviceState *dev, Error **errp)
-{
-    MilkymistVgafbState *s = MILKYMIST_VGAFB(dev);
+    s->con = graphic_console_init(DEVICE(dev), 0, &vgafb_ops, s);
 
-    s->con = graphic_console_init(dev, 0, &vgafb_ops, s);
+    return 0;
 }
 
 static int vgafb_post_load(void *opaque, int version_id)
@@ -335,18 +331,18 @@ static Property milkymist_vgafb_properties[] = {
 static void milkymist_vgafb_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = milkymist_vgafb_init;
     dc->reset = milkymist_vgafb_reset;
     dc->vmsd = &vmstate_milkymist_vgafb;
     dc->props = milkymist_vgafb_properties;
-    dc->realize = milkymist_vgafb_realize;
 }
 
 static const TypeInfo milkymist_vgafb_info = {
     .name          = TYPE_MILKYMIST_VGAFB,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(MilkymistVgafbState),
-    .instance_init = milkymist_vgafb_init,
     .class_init    = milkymist_vgafb_class_init,
 };
 
index 1025ff3..f0ce71f 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#if DEPTH == 32
+#if DEPTH == 8
+# define BPP 1
+# define PIXEL_TYPE uint8_t
+#elif DEPTH == 15 || DEPTH == 16
+# define BPP 2
+# define PIXEL_TYPE uint16_t
+#elif DEPTH == 32
 # define BPP 4
 # define PIXEL_TYPE uint32_t
 #else
@@ -146,7 +152,7 @@ static void glue(draw_line12_, DEPTH)(void *opaque,
 static void glue(draw_line16_, DEPTH)(void *opaque,
                 uint8_t *d, const uint8_t *s, int width, int deststep)
 {
-#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
+#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
     memcpy(d, s, width * 2);
 #else
     uint16_t v;
index 07a5eff..ce1058b 100644 (file)
@@ -71,9 +71,47 @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
 
 #define draw_line_func drawfn
 
+#define DEPTH 8
+#include "omap_lcd_template.h"
+#define DEPTH 15
+#include "omap_lcd_template.h"
+#define DEPTH 16
+#include "omap_lcd_template.h"
 #define DEPTH 32
 #include "omap_lcd_template.h"
 
+static draw_line_func draw_line_table2[33] = {
+    [0 ... 32] = NULL,
+    [8]                = draw_line2_8,
+    [15]       = draw_line2_15,
+    [16]       = draw_line2_16,
+    [32]       = draw_line2_32,
+}, draw_line_table4[33] = {
+    [0 ... 32] = NULL,
+    [8]                = draw_line4_8,
+    [15]       = draw_line4_15,
+    [16]       = draw_line4_16,
+    [32]       = draw_line4_32,
+}, draw_line_table8[33] = {
+    [0 ... 32] = NULL,
+    [8]                = draw_line8_8,
+    [15]       = draw_line8_15,
+    [16]       = draw_line8_16,
+    [32]       = draw_line8_32,
+}, draw_line_table12[33] = {
+    [0 ... 32] = NULL,
+    [8]                = draw_line12_8,
+    [15]       = draw_line12_15,
+    [16]       = draw_line12_16,
+    [32]       = draw_line12_32,
+}, draw_line_table16[33] = {
+    [0 ... 32] = NULL,
+    [8]                = draw_line16_8,
+    [15]       = draw_line16_15,
+    [16]       = draw_line16_16,
+    [32]       = draw_line16_32,
+};
+
 static void omap_update_display(void *opaque)
 {
     struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
@@ -105,25 +143,25 @@ static void omap_update_display(void *opaque)
     /* Colour depth */
     switch ((omap_lcd->palette[0] >> 12) & 7) {
     case 1:
-        draw_line = draw_line2_32;
+        draw_line = draw_line_table2[surface_bits_per_pixel(surface)];
         bpp = 2;
         break;
 
     case 2:
-        draw_line = draw_line4_32;
+        draw_line = draw_line_table4[surface_bits_per_pixel(surface)];
         bpp = 4;
         break;
 
     case 3:
-        draw_line = draw_line8_32;
+        draw_line = draw_line_table8[surface_bits_per_pixel(surface)];
         bpp = 8;
         break;
 
     case 4 ... 7:
         if (!omap_lcd->tft)
-            draw_line = draw_line12_32;
+            draw_line = draw_line_table12[surface_bits_per_pixel(surface)];
         else
-            draw_line = draw_line16_32;
+            draw_line = draw_line_table16[surface_bits_per_pixel(surface)];
         bpp = 16;
         break;
 
index c069c0b..d589959 100644 (file)
@@ -12,7 +12,6 @@
 #include "ui/console.h"
 #include "framebuffer.h"
 #include "ui/pixel_ops.h"
-#include "qemu/log.h"
 
 #define PL110_CR_EN   0x001
 #define PL110_CR_BGR  0x100
index 0e2682d..919dc5c 100644 (file)
@@ -504,7 +504,6 @@ static void interface_set_compression_level(QXLInstance *sin, int level)
     qxl_rom_set_dirty(qxl);
 }
 
-#if SPICE_NEEDS_SET_MM_TIME
 static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
 {
     PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
@@ -518,7 +517,6 @@ static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
     qxl->rom->mm_clock = cpu_to_le32(mm_time);
     qxl_rom_set_dirty(qxl);
 }
-#endif
 
 static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
 {
@@ -895,8 +893,7 @@ static void interface_update_area_complete(QXLInstance *sin,
     int qxl_i;
 
     qemu_mutex_lock(&qxl->ssd.lock);
-    if (surface_id != 0 || !num_updated_rects ||
-        !qxl->render_update_cookie_num) {
+    if (surface_id != 0 || !qxl->render_update_cookie_num) {
         qemu_mutex_unlock(&qxl->ssd.lock);
         return;
     }
@@ -1071,9 +1068,7 @@ static const QXLInterface qxl_interface = {
 
     .attache_worker          = interface_attach_worker,
     .set_compression_level   = interface_set_compression_level,
-#if SPICE_NEEDS_SET_MM_TIME
     .set_mm_time             = interface_set_mm_time,
-#endif
     .get_init_info           = interface_get_init_info,
 
     /* the callbacks below are called from spice server thread context */
@@ -1248,7 +1243,6 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
     int pci_region;
     pcibus_t pci_start;
     pcibus_t pci_end;
-    MemoryRegion *mr;
     intptr_t virt_start;
     QXLDevMemSlot memslot;
     int i;
@@ -1295,11 +1289,11 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
 
     switch (pci_region) {
     case QXL_RAM_RANGE_INDEX:
-        mr = &d->vga.vram;
+        virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram);
         break;
     case QXL_VRAM_RANGE_INDEX:
     case 4 /* vram 64bit */:
-        mr = &d->vram_bar;
+        virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar);
         break;
     default:
         /* should not happen */
@@ -1307,7 +1301,6 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
         return 1;
     }
 
-    virt_start = (intptr_t)memory_region_get_ram_ptr(mr);
     memslot.slot_id = slot_id;
     memslot.slot_group_id = MEMSLOT_GROUP_GUEST; /* guest group */
     memslot.virt_start = virt_start + (guest_start - pci_start);
@@ -1317,8 +1310,7 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
     qxl_rom_set_dirty(d);
 
     qemu_spice_add_memslot(&d->ssd, &memslot, async);
-    d->guest_slots[slot_id].mr = mr;
-    d->guest_slots[slot_id].offset = memslot.virt_start - virt_start;
+    d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
     d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
     d->guest_slots[slot_id].delta = delta;
     d->guest_slots[slot_id].active = 1;
@@ -1345,60 +1337,39 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
 }
 
 /* can be also called from spice server thread context */
-static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
-                                      uint32_t *s, uint64_t *o)
+void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
 {
     uint64_t phys   = le64_to_cpu(pqxl);
     uint32_t slot   = (phys >> (64 -  8)) & 0xff;
     uint64_t offset = phys & 0xffffffffffff;
 
-    if (slot >= NUM_MEMSLOTS) {
-        qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot,
-                          NUM_MEMSLOTS);
-        return false;
-    }
-    if (!qxl->guest_slots[slot].active) {
-        qxl_set_guest_bug(qxl, "inactive slot %d\n", slot);
-        return false;
-    }
-    if (offset < qxl->guest_slots[slot].delta) {
-        qxl_set_guest_bug(qxl,
-                          "slot %d offset %"PRIu64" < delta %"PRIu64"\n",
-                          slot, offset, qxl->guest_slots[slot].delta);
-        return false;
-    }
-    offset -= qxl->guest_slots[slot].delta;
-    if (offset > qxl->guest_slots[slot].size) {
-        qxl_set_guest_bug(qxl,
-                          "slot %d offset %"PRIu64" > size %"PRIu64"\n",
-                          slot, offset, qxl->guest_slots[slot].size);
-        return false;
-    }
-
-    *s = slot;
-    *o = offset;
-    return true;
-}
-
-/* can be also called from spice server thread context */
-void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
-{
-    uint64_t offset;
-    uint32_t slot;
-    void *ptr;
-
     switch (group_id) {
     case MEMSLOT_GROUP_HOST:
-        offset = le64_to_cpu(pqxl) & 0xffffffffffff;
         return (void *)(intptr_t)offset;
     case MEMSLOT_GROUP_GUEST:
-        if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset)) {
+        if (slot >= NUM_MEMSLOTS) {
+            qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot,
+                              NUM_MEMSLOTS);
+            return NULL;
+        }
+        if (!qxl->guest_slots[slot].active) {
+            qxl_set_guest_bug(qxl, "inactive slot %d\n", slot);
             return NULL;
         }
-        ptr = memory_region_get_ram_ptr(qxl->guest_slots[slot].mr);
-        ptr += qxl->guest_slots[slot].offset;
-        ptr += offset;
-        return ptr;
+        if (offset < qxl->guest_slots[slot].delta) {
+            qxl_set_guest_bug(qxl,
+                          "slot %d offset %"PRIu64" < delta %"PRIu64"\n",
+                          slot, offset, qxl->guest_slots[slot].delta);
+            return NULL;
+        }
+        offset -= qxl->guest_slots[slot].delta;
+        if (offset > qxl->guest_slots[slot].size) {
+            qxl_set_guest_bug(qxl,
+                          "slot %d offset %"PRIu64" > size %"PRIu64"\n",
+                          slot, offset, qxl->guest_slots[slot].size);
+            return NULL;
+        }
+        return qxl->guest_slots[slot].ptr + offset;
     }
     return NULL;
 }
@@ -1813,24 +1784,9 @@ static void qxl_hw_update(void *opaque)
     qxl_render_update(qxl);
 }
 
-static void qxl_dirty_one_surface(PCIQXLDevice *qxl, QXLPHYSICAL pqxl,
-                                  uint32_t height, int32_t stride)
-{
-    uint64_t offset, size;
-    uint32_t slot;
-    bool rc;
-
-    rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset);
-    assert(rc == true);
-    size = (uint64_t)height * abs(stride);
-    trace_qxl_surfaces_dirty(qxl->id, offset, size);
-    qxl_set_dirty(qxl->guest_slots[slot].mr,
-                  qxl->guest_slots[slot].offset + offset,
-                  qxl->guest_slots[slot].offset + offset + size);
-}
-
 static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
 {
+    uintptr_t vram_start;
     int i;
 
     if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) {
@@ -1838,13 +1794,16 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
     }
 
     /* dirty the primary surface */
-    qxl_dirty_one_surface(qxl, qxl->guest_primary.surface.mem,
-                          qxl->guest_primary.surface.height,
-                          qxl->guest_primary.surface.stride);
+    qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
+                  qxl->shadow_rom.surface0_area_size);
+
+    vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
 
     /* dirty the off-screen surfaces */
     for (i = 0; i < qxl->ssd.num_surfaces; i++) {
         QXLSurfaceCmd *cmd;
+        intptr_t surface_offset;
+        int surface_size;
 
         if (qxl->guest_surfaces.cmds[i] == 0) {
             continue;
@@ -1854,9 +1813,15 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
                             MEMSLOT_GROUP_GUEST);
         assert(cmd);
         assert(cmd->type == QXL_SURFACE_CMD_CREATE);
-        qxl_dirty_one_surface(qxl, cmd->u.surface_create.data,
-                              cmd->u.surface_create.height,
-                              cmd->u.surface_create.stride);
+        surface_offset = (intptr_t)qxl_phys2virt(qxl,
+                                                 cmd->u.surface_create.data,
+                                                 MEMSLOT_GROUP_GUEST);
+        assert(surface_offset);
+        surface_offset -= vram_start;
+        surface_size = cmd->u.surface_create.height *
+                       abs(cmd->u.surface_create.stride);
+        trace_qxl_surfaces_dirty(qxl->id, i, (int)surface_offset, surface_size);
+        qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);
     }
 }
 
@@ -1949,7 +1914,7 @@ static void qxl_init_ramsize(PCIQXLDevice *qxl)
 
     /* vram (surfaces, 64bit, bar 4+5) */
     if (qxl->vram_size_mb != -1) {
-        qxl->vram_size = (uint64_t)qxl->vram_size_mb * 1024 * 1024;
+        qxl->vram_size = qxl->vram_size_mb * 1024 * 1024;
     }
     if (qxl->vram_size < qxl->vram32_size) {
         qxl->vram_size = qxl->vram32_size;
@@ -2055,9 +2020,9 @@ static void qxl_realize_common(PCIQXLDevice *qxl, Error **errp)
     dprint(qxl, 1, "ram/%s: %d MB [region 0]\n",
            qxl->id == 0 ? "pri" : "sec",
            qxl->vga.vram_size / (1024*1024));
-    dprint(qxl, 1, "vram/32: %" PRIx64 "d MB [region 1]\n",
+    dprint(qxl, 1, "vram/32: %d MB [region 1]\n",
            qxl->vram32_size / (1024*1024));
-    dprint(qxl, 1, "vram/64: %" PRIx64 "d MB %s\n",
+    dprint(qxl, 1, "vram/64: %d MB %s\n",
            qxl->vram_size / (1024*1024),
            qxl->vram32_size < qxl->vram_size ? "[region 4]" : "[unmapped]");
 
@@ -2311,7 +2276,7 @@ static VMStateDescription qxl_vmstate = {
 static Property qxl_properties[] = {
         DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size,
                            64 * 1024 * 1024),
-        DEFINE_PROP_UINT64("vram_size", PCIQXLDevice, vram32_size,
+        DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram32_size,
                            64 * 1024 * 1024),
         DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision,
                            QXL_DEFAULT_REVISION),
index d2d49dd..2ddf065 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef HW_QXL_H
-#define HW_QXL_H
+#define HW_QXL_H 1
 
 #include "qemu-common.h"
 
@@ -53,8 +53,7 @@ typedef struct PCIQXLDevice {
 
     struct guest_slots {
         QXLMemSlot     slot;
-        MemoryRegion   *mr;
-        uint64_t       offset;
+        void           *ptr;
         uint64_t       size;
         uint64_t       delta;
         uint32_t       active;
@@ -105,9 +104,9 @@ typedef struct PCIQXLDevice {
 #endif
 
     /* vram pci bar */
-    uint64_t           vram_size;
+    uint32_t           vram_size;
     MemoryRegion       vram_bar;
-    uint64_t           vram32_size;
+    uint32_t           vram32_size;
     MemoryRegion       vram32_bar;
 
     /* io bar */
index 6d1faf4..14c1bf3 100644 (file)
@@ -361,7 +361,7 @@ static const GraphicHwOps ssd0323_ops = {
     .gfx_update  = ssd0323_update_display,
 };
 
-static void ssd0323_realize(SSISlave *d, Error **errp)
+static int ssd0323_init(SSISlave *d)
 {
     DeviceState *dev = DEVICE(d);
     ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, d);
@@ -375,13 +375,14 @@ static void ssd0323_realize(SSISlave *d, Error **errp)
 
     register_savevm(dev, "ssd0323_oled", -1, 1,
                     ssd0323_save, ssd0323_load, s);
+    return 0;
 }
 
 static void ssd0323_class_init(ObjectClass *klass, void *data)
 {
     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 
-    k->realize = ssd0323_realize;
+    k->init = ssd0323_init;
     k->transfer = ssd0323_transfer;
     k->cs_polarity = SSI_CS_HIGH;
 }
index 92f7120..da3cece 100644 (file)
@@ -12,7 +12,6 @@
  */
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qemu/host-utils.h"
 #include "hw/hw.h"
 #include "hw/devices.h"
 #include "hw/block/flash.h"
diff --git a/hw/display/trace-events b/hw/display/trace-events
deleted file mode 100644 (file)
index 332abab..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/display/jazz_led.c
-jazz_led_read(uint64_t addr, uint8_t val) "read addr=0x%"PRIx64": 0x%x"
-jazz_led_write(uint64_t addr, uint8_t new) "write addr=0x%"PRIx64": 0x%x"
-
-# hw/display/xenfb.c
-xenfb_mouse_event(void *opaque, int dx, int dy, int dz, int button_state, int abs_pointer_wanted) "%p x %d y %d z %d bs %#x abs %d"
-xenfb_input_connected(void *xendev, int abs_pointer_wanted) "%p abs %d"
-
-# hw/display/g364fb.c
-g364fb_read(uint64_t addr, uint32_t val) "read addr=0x%"PRIx64": 0x%x"
-g364fb_write(uint64_t addr, uint32_t new) "write addr=0x%"PRIx64": 0x%x"
-
-# hw/display/milkymist-tmu2.c
-milkymist_tmu2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_tmu2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_tmu2_start(void) "Start TMU"
-milkymist_tmu2_pulse_irq(void) "Pulse IRQ"
-
-# hw/display/milkymist-vgafb.c
-milkymist_vgafb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_vgafb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-
-# hw/display/vmware_vga.c
-vmware_value_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
-vmware_value_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
-vmware_palette_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
-vmware_palette_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
-vmware_scratch_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
-vmware_scratch_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
-vmware_setmode(uint32_t w, uint32_t h, uint32_t bpp) "%dx%d @ %d bpp"
-
-# hw/display/virtio-gpu.c
-virtio_gpu_features(bool virgl) "virgl %d"
-virtio_gpu_cmd_get_display_info(void) ""
-virtio_gpu_cmd_get_caps(void) ""
-virtio_gpu_cmd_set_scanout(uint32_t id, uint32_t res, uint32_t w, uint32_t h, uint32_t x, uint32_t y) "id %d, res 0x%x, w %d, h %d, x %d, y %d"
-virtio_gpu_cmd_res_create_2d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h) "res 0x%x, fmt 0x%x, w %d, h %d"
-virtio_gpu_cmd_res_create_3d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h, uint32_t d) "res 0x%x, fmt 0x%x, w %d, h %d, d %d"
-virtio_gpu_cmd_res_unref(uint32_t res) "res 0x%x"
-virtio_gpu_cmd_res_back_attach(uint32_t res) "res 0x%x"
-virtio_gpu_cmd_res_back_detach(uint32_t res) "res 0x%x"
-virtio_gpu_cmd_res_xfer_toh_2d(uint32_t res) "res 0x%x"
-virtio_gpu_cmd_res_xfer_toh_3d(uint32_t res) "res 0x%x"
-virtio_gpu_cmd_res_xfer_fromh_3d(uint32_t res) "res 0x%x"
-virtio_gpu_cmd_res_flush(uint32_t res, uint32_t w, uint32_t h, uint32_t x, uint32_t y) "res 0x%x, w %d, h %d, x %d, y %d"
-virtio_gpu_cmd_ctx_create(uint32_t ctx, const char *name) "ctx 0x%x, name %s"
-virtio_gpu_cmd_ctx_destroy(uint32_t ctx) "ctx 0x%x"
-virtio_gpu_cmd_ctx_res_attach(uint32_t ctx, uint32_t res) "ctx 0x%x, res 0x%x"
-virtio_gpu_cmd_ctx_res_detach(uint32_t ctx, uint32_t res) "ctx 0x%x, res 0x%x"
-virtio_gpu_cmd_ctx_submit(uint32_t ctx, uint32_t size) "ctx 0x%x, size %d"
-virtio_gpu_update_cursor(uint32_t scanout, uint32_t x, uint32_t y, const char *type, uint32_t res) "scanout %d, x %d, y %d, %s, res 0x%x"
-virtio_gpu_fence_ctrl(uint64_t fence, uint32_t type) "fence 0x%" PRIx64 ", type 0x%x"
-virtio_gpu_fence_resp(uint64_t fence) "fence 0x%" PRIx64
-
-# hw/display/qxl.c
-disable qxl_interface_set_mm_time(int qid, uint32_t mm_time) "%d %d"
-disable qxl_io_write_vga(int qid, const char *mode, uint32_t addr, uint32_t val) "%d %s addr=%u val=%u"
-qxl_create_guest_primary(int qid, uint32_t width, uint32_t height, uint64_t mem, uint32_t format, uint32_t position) "%d %ux%u mem=%" PRIx64 " %u,%u"
-qxl_create_guest_primary_rest(int qid, int32_t stride, uint32_t type, uint32_t flags) "%d %d,%d,%d"
-qxl_destroy_primary(int qid) "%d"
-qxl_enter_vga_mode(int qid) "%d"
-qxl_exit_vga_mode(int qid) "%d"
-qxl_hard_reset(int qid, int64_t loadvm) "%d loadvm=%"PRId64
-qxl_interface_async_complete_io(int qid, uint32_t current_async, void *cookie) "%d current=%d cookie=%p"
-qxl_interface_attach_worker(int qid) "%d"
-qxl_interface_get_init_info(int qid) "%d"
-qxl_interface_set_compression_level(int qid, int64_t level) "%d %"PRId64
-qxl_interface_update_area_complete(int qid, uint32_t surface_id, uint32_t dirty_left, uint32_t dirty_right, uint32_t dirty_top, uint32_t dirty_bottom) "%d surface=%d [%d,%d,%d,%d]"
-qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d #=%d"
-qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d"
-qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) "%d #dirty=%d"
-qxl_io_destroy_primary_ignored(int qid, const char *mode) "%d %s"
-qxl_io_log(int qid, const uint8_t *log_buf) "%d %s"
-qxl_io_read_unexpected(int qid) "%d"
-qxl_io_unexpected_vga_mode(int qid, uint64_t addr, uint64_t val, const char *desc) "%d 0x%"PRIx64"=%"PRIu64" (%s)"
-qxl_io_write(int qid, const char *mode, uint64_t addr, const char *aname, uint64_t val, unsigned size, int async) "%d %s addr=%"PRIu64 " (%s) val=%"PRIu64" size=%u async=%d"
-qxl_memslot_add_guest(int qid, uint32_t slot_id, uint64_t guest_start, uint64_t guest_end) "%d %u: guest phys 0x%"PRIx64 " - 0x%" PRIx64
-qxl_post_load(int qid, const char *mode) "%d %s"
-qxl_pre_load(int qid) "%d"
-qxl_pre_save(int qid) "%d"
-qxl_reset_surfaces(int qid) "%d"
-qxl_ring_command_check(int qid, const char *mode) "%d %s"
-qxl_ring_command_get(int qid, const char *mode) "%d %s"
-qxl_ring_command_req_notification(int qid) "%d"
-qxl_ring_cursor_check(int qid, const char *mode) "%d %s"
-qxl_ring_cursor_get(int qid, const char *mode) "%d %s"
-qxl_ring_cursor_req_notification(int qid) "%d"
-qxl_ring_res_push(int qid, const char *mode, uint32_t surface_count, uint32_t free_res, void *last_release, const char *notify) "%d %s s#=%d res#=%d last=%p notify=%s"
-qxl_ring_res_push_rest(int qid, uint32_t ring_has, uint32_t ring_size, uint32_t prod, uint32_t cons) "%d ring %d/%d [%d,%d]"
-qxl_ring_res_put(int qid, uint32_t free_res) "%d #res=%d"
-qxl_set_mode(int qid, int modenr, uint32_t x_res, uint32_t y_res, uint32_t bits, uint64_t devmem) "%d mode=%d [ x=%d y=%d @ bpp=%d devmem=0x%" PRIx64 " ]"
-qxl_soft_reset(int qid) "%d"
-qxl_spice_destroy_surfaces_complete(int qid) "%d"
-qxl_spice_destroy_surfaces(int qid, int async) "%d async=%d"
-qxl_spice_destroy_surface_wait_complete(int qid, uint32_t id) "%d sid=%d"
-qxl_spice_destroy_surface_wait(int qid, uint32_t id, int async) "%d sid=%d async=%d"
-qxl_spice_flush_surfaces_async(int qid, uint32_t surface_count, uint32_t num_free_res) "%d s#=%d, res#=%d"
-qxl_spice_monitors_config(int qid) "%d"
-qxl_spice_loadvm_commands(int qid, void *ext, uint32_t count) "%d ext=%p count=%d"
-qxl_spice_oom(int qid) "%d"
-qxl_spice_reset_cursor(int qid) "%d"
-qxl_spice_reset_image_cache(int qid) "%d"
-qxl_spice_reset_memslots(int qid) "%d"
-qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "%d sid=%d [%d,%d,%d,%d]"
-qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d"
-qxl_surfaces_dirty(int qid, uint64_t offset, uint64_t size) "%d offset=0x%"PRIx64" size=0x%"PRIx64
-qxl_send_events(int qid, uint32_t events) "%d %d"
-qxl_send_events_vm_stopped(int qid, uint32_t events) "%d %d"
-qxl_set_guest_bug(int qid) "%d"
-qxl_interrupt_client_monitors_config(int qid, int num_heads, void *heads) "%d %d %p"
-qxl_client_monitors_config_unsupported_by_guest(int qid, uint32_t int_mask, void *client_monitors_config) "%d %X %p"
-qxl_client_monitors_config_unsupported_by_device(int qid, int revision) "%d revision=%d"
-qxl_client_monitors_config_capped(int qid, int requested, int limit) "%d %d %d"
-qxl_client_monitors_config_crc(int qid, unsigned size, uint32_t crc32) "%d %u %u"
-qxl_set_client_capabilities_unsupported_by_revision(int qid, int revision) "%d revision=%d"
-
-# hw/display/qxl-render.c
-qxl_render_blit(int32_t stride, int32_t left, int32_t right, int32_t top, int32_t bottom) "stride=%d [%d, %d, %d, %d]"
-qxl_render_guest_primary_resized(int32_t width, int32_t height, int32_t stride, int32_t bytes_pp, int32_t bits_pp) "%dx%d, stride %d, bpp %d, depth %d"
-qxl_render_update_area_done(void *cookie) "%p"
index 2a88b3c..9ebc54f 100644 (file)
@@ -700,7 +700,9 @@ static void vbe_update_vgaregs(VGACommonState *s)
 static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
 {
     VGACommonState *s = opaque;
-    return s->vbe_index;
+    uint32_t val;
+    val = s->vbe_index;
+    return val;
 }
 
 uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
index 16886f5..d917046 100644 (file)
@@ -14,8 +14,8 @@
  *
  */
 
-#ifndef LINUX_VIDEO_VGA_H
-#define LINUX_VIDEO_VGA_H
+#ifndef __linux_video_vga_h__
+#define __linux_video_vga_h__
 
 /* Some of the code below is taken from SVGAlib.  The original,
    unmodified copyright notice for that code is below. */
 /* VGA graphics controller bit masks */
 #define VGA_GR06_GRAPHICS_MODE  0x01
 
-#endif /* LINUX_VIDEO_VGA_H */
+#endif /* __linux_video_vga_h__ */
index dd6c958..3ce5544 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
 #ifndef HW_VGA_INT_H
-#define HW_VGA_INT_H
+#define HW_VGA_INT_H 1
 
-#include "hw/hw.h"
+#include <hw/hw.h>
 #include "exec/memory.h"
 
 #define ST01_V_RETRACE      0x08
index 758d33a..fa19294 100644 (file)
 #include "trace.h"
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/virtio-gpu.h"
-#include "qapi/error.h"
 
 #ifdef CONFIG_VIRGL
 
-#include <virglrenderer.h>
+#include "virglrenderer.h"
 
 static struct virgl_renderer_callbacks virtio_gpu_3d_cbs;
 
@@ -128,7 +127,7 @@ static void virgl_cmd_resource_flush(VirtIOGPU *g,
     trace_virtio_gpu_cmd_res_flush(rf.resource_id,
                                    rf.r.width, rf.r.height, rf.r.x, rf.r.y);
 
-    for (i = 0; i < g->conf.max_outputs; i++) {
+    for (i = 0; i < VIRTIO_GPU_MAX_SCANOUT; i++) {
         if (g->scanout[i].resource_id != rf.resource_id) {
             continue;
         }
@@ -147,7 +146,7 @@ static void virgl_cmd_set_scanout(VirtIOGPU *g,
     trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,
                                      ss.r.width, ss.r.height, ss.r.x, ss.r.y);
 
-    if (ss.scanout_id >= g->conf.max_outputs) {
+    if (ss.scanout_id >= VIRTIO_GPU_MAX_SCANOUT) {
         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
                       __func__, ss.scanout_id);
         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
@@ -171,14 +170,13 @@ static void virgl_cmd_set_scanout(VirtIOGPU *g,
         virgl_renderer_force_ctx_0();
         dpy_gl_scanout(g->scanout[ss.scanout_id].con, info.tex_id,
                        info.flags & 1 /* FIXME: Y_0_TOP */,
-                       info.width, info.height,
                        ss.r.x, ss.r.y, ss.r.width, ss.r.height);
     } else {
         if (ss.scanout_id != 0) {
             dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, NULL);
         }
         dpy_gl_scanout(g->scanout[ss.scanout_id].con, 0, false,
-                       0, 0, 0, 0, 0, 0);
+                       0, 0, 0, 0);
     }
     g->scanout[ss.scanout_id].resource_id = ss.resource_id;
 }
@@ -285,7 +283,7 @@ static void virgl_resource_attach_backing(VirtIOGPU *g,
     VIRTIO_GPU_FILL_CMD(att_rb);
     trace_virtio_gpu_cmd_res_back_attach(att_rb.resource_id);
 
-    ret = virtio_gpu_create_mapping_iov(&att_rb, cmd, NULL, &res_iovs);
+    ret = virtio_gpu_create_mapping_iov(&att_rb, cmd, &res_iovs);
     if (ret != 0) {
         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
         return;
@@ -581,7 +579,7 @@ void virtio_gpu_virgl_reset(VirtIOGPU *g)
         if (i != 0) {
             dpy_gfx_replace_surface(g->scanout[i].con, NULL);
         }
-        dpy_gl_scanout(g->scanout[i].con, 0, false, 0, 0, 0, 0, 0, 0);
+        dpy_gl_scanout(g->scanout[i].con, 0, false, 0, 0, 0, 0);
     }
 }
 
index 34a724c..a71b230 100644 (file)
@@ -30,7 +30,9 @@ static void virtio_gpu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
     int i;
 
     qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    virtio_pci_force_virtio_1(vpci_dev);
+    /* force virtio-1.0 */
+    vpci_dev->flags &= ~VIRTIO_PCI_FLAG_DISABLE_MODERN;
+    vpci_dev->flags |= VIRTIO_PCI_FLAG_DISABLE_LEGACY;
     object_property_set_bool(OBJECT(vdev), true, "realized", errp);
 
     for (i = 0; i < g->conf.max_outputs; i++) {
index 7fe6ed8..c181fb3 100644 (file)
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/virtio-gpu.h"
 #include "hw/virtio/virtio-bus.h"
-#include "migration/migration.h"
-#include "qemu/log.h"
-#include "qapi/error.h"
-
-#define VIRTIO_GPU_VM_VERSION 1
 
 static struct virtio_gpu_simple_resource*
 virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
 
 #ifdef CONFIG_VIRGL
-#include <virglrenderer.h>
+#include "virglrenderer.h"
 #define VIRGL(_g, _virgl, _simple, ...)                     \
     do {                                                    \
         if (_g->use_virgl_renderer) {                       \
@@ -97,7 +92,7 @@ static void update_cursor_data_virgl(VirtIOGPU *g,
 static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor)
 {
     struct virtio_gpu_scanout *s;
-    bool move = cursor->hdr.type == VIRTIO_GPU_CMD_MOVE_CURSOR;
+    bool move = cursor->hdr.type != VIRTIO_GPU_CMD_MOVE_CURSOR;
 
     if (cursor->pos.scanout_id >= g->conf.max_outputs) {
         return;
@@ -110,7 +105,7 @@ static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor)
                                    move ? "move" : "update",
                                    cursor->resource_id);
 
-    if (!move) {
+    if (move) {
         if (!s->current_cursor) {
             s->current_cursor = cursor_alloc(64, 64);
         }
@@ -123,11 +118,6 @@ static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor)
                   g, s, cursor->resource_id);
         }
         dpy_cursor_define(s->con, s->current_cursor);
-
-        s->cursor = *cursor;
-    } else {
-        s->cursor.pos.x = cursor->pos.x;
-        s->cursor.pos.y = cursor->pos.y;
     }
     dpy_mouse_set(s->con, cursor->pos.x, cursor->pos.y,
                   cursor->resource_id ? 1 : 0);
@@ -474,7 +464,7 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
 
     pixman_region_init_rect(&flush_region,
                             rf.r.x, rf.r.y, rf.r.width, rf.r.height);
-    for (i = 0; i < g->conf.max_outputs; i++) {
+    for (i = 0; i < VIRTIO_GPU_MAX_SCANOUT; i++) {
         struct virtio_gpu_scanout *scanout;
         pixman_region16_t region, finalregion;
         pixman_box16_t *extents;
@@ -503,11 +493,6 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
     pixman_region_fini(&flush_region);
 }
 
-static void virtio_unref_resource(pixman_image_t *image, void *data)
-{
-    pixman_image_unref(data);
-}
-
 static void virtio_gpu_set_scanout(VirtIOGPU *g,
                                    struct virtio_gpu_ctrl_command *cmd)
 {
@@ -522,13 +507,6 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
     trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,
                                      ss.r.width, ss.r.height, ss.r.x, ss.r.y);
 
-    if (ss.scanout_id >= g->conf.max_outputs) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
-                      __func__, ss.scanout_id);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
-        return;
-    }
-
     g->enable = 1;
     if (ss.resource_id == 0) {
         scanout = &g->scanout[ss.scanout_id];
@@ -538,7 +516,8 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
                 res->scanout_bitmask &= ~(1 << ss.scanout_id);
             }
         }
-        if (ss.scanout_id == 0) {
+        if (ss.scanout_id == 0 ||
+            ss.scanout_id >= g->conf.max_outputs) {
             qemu_log_mask(LOG_GUEST_ERROR,
                           "%s: illegal scanout id specified %d",
                           __func__, ss.scanout_id);
@@ -553,6 +532,14 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
     }
 
     /* create a surface for this scanout */
+    if (ss.scanout_id >= VIRTIO_GPU_MAX_SCANOUT ||
+        ss.scanout_id >= g->conf.max_outputs) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
+                      __func__, ss.scanout_id);
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
+        return;
+    }
+
     res = virtio_gpu_find_resource(g, ss.resource_id);
     if (!res) {
         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
@@ -584,15 +571,8 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
         != ((uint8_t *)pixman_image_get_data(res->image) + offset) ||
         scanout->width != ss.r.width ||
         scanout->height != ss.r.height) {
-        pixman_image_t *rect;
-        void *ptr = (uint8_t *)pixman_image_get_data(res->image) + offset;
-        rect = pixman_image_create_bits(format, ss.r.width, ss.r.height, ptr,
-                                        pixman_image_get_stride(res->image));
-        pixman_image_ref(res->image);
-        pixman_image_set_destroy_function(rect, virtio_unref_resource,
-                                          res->image);
         /* realloc the surface ptr */
-        scanout->ds = qemu_create_displaysurface_pixman(rect);
+        scanout->ds = qemu_create_displaysurface_pixman(res->image);
         if (!scanout->ds) {
             cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
             return;
@@ -610,7 +590,7 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
 
 int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab,
                                   struct virtio_gpu_ctrl_command *cmd,
-                                  uint64_t **addr, struct iovec **iov)
+                                  struct iovec **iov)
 {
     struct virtio_gpu_mem_entry *ents;
     size_t esize, s;
@@ -636,16 +616,10 @@ int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab,
     }
 
     *iov = g_malloc0(sizeof(struct iovec) * ab->nr_entries);
-    if (addr) {
-        *addr = g_malloc0(sizeof(uint64_t) * ab->nr_entries);
-    }
     for (i = 0; i < ab->nr_entries; i++) {
         hwaddr len = ents[i].length;
         (*iov)[i].iov_len = ents[i].length;
         (*iov)[i].iov_base = cpu_physical_memory_map(ents[i].addr, &len, 1);
-        if (addr) {
-            (*addr)[i] = ents[i].addr;
-        }
         if (!(*iov)[i].iov_base || len != ents[i].length) {
             qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for"
                           " resource %d element %d\n",
@@ -653,10 +627,6 @@ int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab,
             virtio_gpu_cleanup_mapping_iov(*iov, i);
             g_free(ents);
             *iov = NULL;
-            if (addr) {
-                g_free(*addr);
-                *addr = NULL;
-            }
             return -1;
         }
     }
@@ -680,8 +650,6 @@ static void virtio_gpu_cleanup_mapping(struct virtio_gpu_simple_resource *res)
     virtio_gpu_cleanup_mapping_iov(res->iov, res->iov_cnt);
     res->iov = NULL;
     res->iov_cnt = 0;
-    g_free(res->addrs);
-    res->addrs = NULL;
 }
 
 static void
@@ -703,7 +671,7 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g,
         return;
     }
 
-    ret = virtio_gpu_create_mapping_iov(&ab, cmd, &res->addrs, &res->iov);
+    ret = virtio_gpu_create_mapping_iov(&ab, cmd, &res->iov);
     if (ret != 0) {
         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
         return;
@@ -911,7 +879,7 @@ static int virtio_gpu_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
 {
     VirtIOGPU *g = opaque;
 
-    if (idx >= g->conf.max_outputs) {
+    if (idx > g->conf.max_outputs) {
         return -1;
     }
 
@@ -935,14 +903,8 @@ static void virtio_gpu_gl_block(void *opaque, bool block)
 {
     VirtIOGPU *g = opaque;
 
-    if (block) {
-        g->renderer_blocked++;
-    } else {
-        g->renderer_blocked--;
-    }
-    assert(g->renderer_blocked >= 0);
-
-    if (g->renderer_blocked == 0) {
+    g->renderer_blocked = block;
+    if (!block) {
         virtio_gpu_process_cmdq(g);
     }
 }
@@ -955,154 +917,11 @@ const GraphicHwOps virtio_gpu_ops = {
     .gl_block = virtio_gpu_gl_block,
 };
 
-static const VMStateDescription vmstate_virtio_gpu_scanout = {
-    .name = "virtio-gpu-one-scanout",
-    .version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT32(resource_id, struct virtio_gpu_scanout),
-        VMSTATE_UINT32(width, struct virtio_gpu_scanout),
-        VMSTATE_UINT32(height, struct virtio_gpu_scanout),
-        VMSTATE_INT32(x, struct virtio_gpu_scanout),
-        VMSTATE_INT32(y, struct virtio_gpu_scanout),
-        VMSTATE_UINT32(cursor.resource_id, struct virtio_gpu_scanout),
-        VMSTATE_UINT32(cursor.hot_x, struct virtio_gpu_scanout),
-        VMSTATE_UINT32(cursor.hot_y, struct virtio_gpu_scanout),
-        VMSTATE_UINT32(cursor.pos.x, struct virtio_gpu_scanout),
-        VMSTATE_UINT32(cursor.pos.y, struct virtio_gpu_scanout),
-        VMSTATE_END_OF_LIST()
-    },
+static const VMStateDescription vmstate_virtio_gpu_unmigratable = {
+    .name = "virtio-gpu",
+    .unmigratable = 1,
 };
 
-static const VMStateDescription vmstate_virtio_gpu_scanouts = {
-    .name = "virtio-gpu-scanouts",
-    .version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_INT32(enable, struct VirtIOGPU),
-        VMSTATE_UINT32_EQUAL(conf.max_outputs, struct VirtIOGPU),
-        VMSTATE_STRUCT_VARRAY_UINT32(scanout, struct VirtIOGPU,
-                                     conf.max_outputs, 1,
-                                     vmstate_virtio_gpu_scanout,
-                                     struct virtio_gpu_scanout),
-        VMSTATE_END_OF_LIST()
-    },
-};
-
-static void virtio_gpu_save(QEMUFile *f, void *opaque, size_t size)
-{
-    VirtIOGPU *g = opaque;
-    VirtIODevice *vdev = VIRTIO_DEVICE(g);
-    struct virtio_gpu_simple_resource *res;
-    int i;
-
-    virtio_save(vdev, f);
-
-    /* in 2d mode we should never find unprocessed commands here */
-    assert(QTAILQ_EMPTY(&g->cmdq));
-
-    QTAILQ_FOREACH(res, &g->reslist, next) {
-        qemu_put_be32(f, res->resource_id);
-        qemu_put_be32(f, res->width);
-        qemu_put_be32(f, res->height);
-        qemu_put_be32(f, res->format);
-        qemu_put_be32(f, res->iov_cnt);
-        for (i = 0; i < res->iov_cnt; i++) {
-            qemu_put_be64(f, res->addrs[i]);
-            qemu_put_be32(f, res->iov[i].iov_len);
-        }
-        qemu_put_buffer(f, (void *)pixman_image_get_data(res->image),
-                        pixman_image_get_stride(res->image) * res->height);
-    }
-    qemu_put_be32(f, 0); /* end of list */
-
-    vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL);
-}
-
-static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size)
-{
-    VirtIOGPU *g = opaque;
-    VirtIODevice *vdev = VIRTIO_DEVICE(g);
-    struct virtio_gpu_simple_resource *res;
-    struct virtio_gpu_scanout *scanout;
-    uint32_t resource_id, pformat;
-    int i, ret;
-
-    ret = virtio_load(vdev, f, VIRTIO_GPU_VM_VERSION);
-    if (ret) {
-        return ret;
-    }
-
-    resource_id = qemu_get_be32(f);
-    while (resource_id != 0) {
-        res = g_new0(struct virtio_gpu_simple_resource, 1);
-        res->resource_id = resource_id;
-        res->width = qemu_get_be32(f);
-        res->height = qemu_get_be32(f);
-        res->format = qemu_get_be32(f);
-        res->iov_cnt = qemu_get_be32(f);
-
-        /* allocate */
-        pformat = get_pixman_format(res->format);
-        if (!pformat) {
-            return -EINVAL;
-        }
-        res->image = pixman_image_create_bits(pformat,
-                                              res->width, res->height,
-                                              NULL, 0);
-        if (!res->image) {
-            return -EINVAL;
-        }
-
-        res->addrs = g_new(uint64_t, res->iov_cnt);
-        res->iov = g_new(struct iovec, res->iov_cnt);
-
-        /* read data */
-        for (i = 0; i < res->iov_cnt; i++) {
-            res->addrs[i] = qemu_get_be64(f);
-            res->iov[i].iov_len = qemu_get_be32(f);
-        }
-        qemu_get_buffer(f, (void *)pixman_image_get_data(res->image),
-                        pixman_image_get_stride(res->image) * res->height);
-
-        /* restore mapping */
-        for (i = 0; i < res->iov_cnt; i++) {
-            hwaddr len = res->iov[i].iov_len;
-            res->iov[i].iov_base =
-                cpu_physical_memory_map(res->addrs[i], &len, 1);
-            if (!res->iov[i].iov_base || len != res->iov[i].iov_len) {
-                return -EINVAL;
-            }
-        }
-
-        QTAILQ_INSERT_HEAD(&g->reslist, res, next);
-
-        resource_id = qemu_get_be32(f);
-    }
-
-    /* load & apply scanout state */
-    vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1);
-    for (i = 0; i < g->conf.max_outputs; i++) {
-        scanout = &g->scanout[i];
-        if (!scanout->resource_id) {
-            continue;
-        }
-        res = virtio_gpu_find_resource(g, scanout->resource_id);
-        if (!res) {
-            return -EINVAL;
-        }
-        scanout->ds = qemu_create_displaysurface_pixman(res->image);
-        if (!scanout->ds) {
-            return -EINVAL;
-        }
-
-        dpy_gfx_replace_surface(scanout->con, scanout->ds);
-        dpy_gfx_update(scanout->con, 0, 0, scanout->width, scanout->height);
-        update_cursor(g, &scanout->cursor);
-        res->scanout_bitmask |= (1 << i);
-    }
-
-    return 0;
-}
-
 static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
@@ -1110,11 +929,6 @@ static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
     bool have_virgl;
     int i;
 
-    if (g->conf.max_outputs > VIRTIO_GPU_MAX_SCANOUTS) {
-        error_setg(errp, "invalid max_outputs > %d", VIRTIO_GPU_MAX_SCANOUTS);
-        return;
-    }
-
     g->config_size = sizeof(struct virtio_gpu_config);
     g->virtio_config.num_scanouts = g->conf.max_outputs;
     virtio_init(VIRTIO_DEVICE(g), "virtio-gpu", VIRTIO_ID_GPU,
@@ -1160,19 +974,7 @@ static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
         }
     }
 
-    if (virtio_gpu_virgl_enabled(g->conf)) {
-        error_setg(&g->migration_blocker, "virgl is not yet migratable");
-        migrate_add_blocker(g->migration_blocker);
-    }
-}
-
-static void virtio_gpu_device_unrealize(DeviceState *qdev, Error **errp)
-{
-    VirtIOGPU *g = VIRTIO_GPU(qdev);
-    if (g->migration_blocker) {
-        migrate_del_blocker(g->migration_blocker);
-        error_free(g->migration_blocker);
-    }
+    vmstate_register(qdev, -1, &vmstate_virtio_gpu_unmigratable, g);
 }
 
 static void virtio_gpu_instance_init(Object *obj)
@@ -1219,9 +1021,6 @@ static void virtio_gpu_reset(VirtIODevice *vdev)
 #endif
 }
 
-VMSTATE_VIRTIO_DEVICE(gpu, VIRTIO_GPU_VM_VERSION, virtio_gpu_load,
-                      virtio_gpu_save);
-
 static Property virtio_gpu_properties[] = {
     DEFINE_PROP_UINT32("max_outputs", VirtIOGPU, conf.max_outputs, 1),
 #ifdef CONFIG_VIRGL
@@ -1239,7 +1038,6 @@ static void virtio_gpu_class_init(ObjectClass *klass, void *data)
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
 
     vdc->realize = virtio_gpu_device_realize;
-    vdc->unrealize = virtio_gpu_device_unrealize;
     vdc->get_config = virtio_gpu_get_config;
     vdc->set_config = virtio_gpu_set_config;
     vdc->get_features = virtio_gpu_get_features;
@@ -1248,7 +1046,6 @@ static void virtio_gpu_class_init(ObjectClass *klass, void *data)
     vdc->reset = virtio_gpu_reset;
 
     dc->props = virtio_gpu_properties;
-    dc->vmsd = &vmstate_virtio_gpu;
 }
 
 static const TypeInfo virtio_gpu_info = {
index 5b510a1..e58b165 100644 (file)
@@ -4,7 +4,6 @@
 #include "ui/console.h"
 #include "vga_int.h"
 #include "hw/virtio/virtio-pci.h"
-#include "qapi/error.h"
 
 /*
  * virtio-vga: This extends VirtioPCIProxy.
@@ -84,24 +83,12 @@ static const GraphicHwOps virtio_vga_ops = {
     .gl_block = virtio_vga_gl_block,
 };
 
-static const VMStateDescription vmstate_virtio_vga = {
-    .name = "virtio-vga",
-    .version_id = 2,
-    .minimum_version_id = 2,
-    .fields = (VMStateField[]) {
-        /* no pci stuff here, saving the virtio device will handle that */
-        VMSTATE_STRUCT(vga, VirtIOVGA, 0, vmstate_vga_common, VGACommonState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
 /* VGA device wrapper around PCI device around virtio GPU */
 static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
 {
     VirtIOVGA *vvga = VIRTIO_VGA(vpci_dev);
     VirtIOGPU *g = &vvga->vdev;
     VGACommonState *vga = &vvga->vga;
-    Error *err = NULL;
     uint32_t offset;
     int i;
 
@@ -134,12 +121,10 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
 
     /* init virtio bits */
     qdev_set_parent_bus(DEVICE(g), BUS(&vpci_dev->bus));
-    virtio_pci_force_virtio_1(vpci_dev);
-    object_property_set_bool(OBJECT(g), true, "realized", &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
+    /* force virtio-1.0 */
+    vpci_dev->flags &= ~VIRTIO_PCI_FLAG_DISABLE_MODERN;
+    vpci_dev->flags |= VIRTIO_PCI_FLAG_DISABLE_LEGACY;
+    object_property_set_bool(OBJECT(g), true, "realized", errp);
 
     /* add stdvga mmio regions */
     pci_std_vga_mmio_region_init(vga, &vpci_dev->modern_bar,
@@ -177,7 +162,6 @@ static void virtio_vga_class_init(ObjectClass *klass, void *data)
     set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
     dc->props = virtio_vga_properties;
     dc->reset = virtio_vga_reset;
-    dc->vmsd = &vmstate_virtio_vga;
     dc->hotpluggable = false;
 
     k->realize = virtio_vga_realize;
index 46b7d5e..9866dfd 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <sys/mman.h>
 
 #include "hw/hw.h"
 #include "ui/console.h"
@@ -471,9 +472,9 @@ static int xenfb_map_fb(struct XenFB *xenfb)
         xenfb->pixels = NULL;
     }
 
-    xenfb->fbpages = DIV_ROUND_UP(xenfb->fb_len, XC_PAGE_SIZE);
+    xenfb->fbpages = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
     n_fbdirs = xenfb->fbpages * mode / 8;
-    n_fbdirs = DIV_ROUND_UP(n_fbdirs, XC_PAGE_SIZE);
+    n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
 
     pgmfns = g_malloc0(sizeof(xen_pfn_t) * n_fbdirs);
     fbmfns = g_malloc0(sizeof(xen_pfn_t) * xenfb->fbpages);
diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
deleted file mode 100644 (file)
index f43eb09..0000000
+++ /dev/null
@@ -1,1338 +0,0 @@
-/*
- * xlnx_dp.c
- *
- *  Copyright (C) 2015 : GreenSocs Ltd
- *      http://www.greensocs.com/ , email: info@greensocs.com
- *
- *  Developed by :
- *  Frederic Konrad   <fred.konrad@greensocs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option)any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "hw/display/xlnx_dp.h"
-
-#ifndef DEBUG_DP
-#define DEBUG_DP 0
-#endif
-
-#define DPRINTF(fmt, ...) do {                                                 \
-    if (DEBUG_DP) {                                                            \
-        qemu_log("xlnx_dp: " fmt , ## __VA_ARGS__);                            \
-    }                                                                          \
-} while (0);
-
-/*
- * Register offset for DP.
- */
-#define DP_LINK_BW_SET                      (0x0000 >> 2)
-#define DP_LANE_COUNT_SET                   (0x0004 >> 2)
-#define DP_ENHANCED_FRAME_EN                (0x0008 >> 2)
-#define DP_TRAINING_PATTERN_SET             (0x000C >> 2)
-#define DP_LINK_QUAL_PATTERN_SET            (0x0010 >> 2)
-#define DP_SCRAMBLING_DISABLE               (0x0014 >> 2)
-#define DP_DOWNSPREAD_CTRL                  (0x0018 >> 2)
-#define DP_SOFTWARE_RESET                   (0x001C >> 2)
-#define DP_TRANSMITTER_ENABLE               (0x0080 >> 2)
-#define DP_MAIN_STREAM_ENABLE               (0x0084 >> 2)
-#define DP_FORCE_SCRAMBLER_RESET            (0x00C0 >> 2)
-#define DP_VERSION_REGISTER                 (0x00F8 >> 2)
-#define DP_CORE_ID                          (0x00FC >> 2)
-
-#define DP_AUX_COMMAND_REGISTER             (0x0100 >> 2)
-#define AUX_ADDR_ONLY_MASK                  (0x1000)
-#define AUX_COMMAND_MASK                    (0x0F00)
-#define AUX_COMMAND_SHIFT                   (8)
-#define AUX_COMMAND_NBYTES                  (0x000F)
-
-#define DP_AUX_WRITE_FIFO                   (0x0104 >> 2)
-#define DP_AUX_ADDRESS                      (0x0108 >> 2)
-#define DP_AUX_CLOCK_DIVIDER                (0x010C >> 2)
-#define DP_TX_USER_FIFO_OVERFLOW            (0x0110 >> 2)
-#define DP_INTERRUPT_SIGNAL_STATE           (0x0130 >> 2)
-#define DP_AUX_REPLY_DATA                   (0x0134 >> 2)
-#define DP_AUX_REPLY_CODE                   (0x0138 >> 2)
-#define DP_AUX_REPLY_COUNT                  (0x013C >> 2)
-#define DP_REPLY_DATA_COUNT                 (0x0148 >> 2)
-#define DP_REPLY_STATUS                     (0x014C >> 2)
-#define DP_HPD_DURATION                     (0x0150 >> 2)
-#define DP_MAIN_STREAM_HTOTAL               (0x0180 >> 2)
-#define DP_MAIN_STREAM_VTOTAL               (0x0184 >> 2)
-#define DP_MAIN_STREAM_POLARITY             (0x0188 >> 2)
-#define DP_MAIN_STREAM_HSWIDTH              (0x018C >> 2)
-#define DP_MAIN_STREAM_VSWIDTH              (0x0190 >> 2)
-#define DP_MAIN_STREAM_HRES                 (0x0194 >> 2)
-#define DP_MAIN_STREAM_VRES                 (0x0198 >> 2)
-#define DP_MAIN_STREAM_HSTART               (0x019C >> 2)
-#define DP_MAIN_STREAM_VSTART               (0x01A0 >> 2)
-#define DP_MAIN_STREAM_MISC0                (0x01A4 >> 2)
-#define DP_MAIN_STREAM_MISC1                (0x01A8 >> 2)
-#define DP_MAIN_STREAM_M_VID                (0x01AC >> 2)
-#define DP_MSA_TRANSFER_UNIT_SIZE           (0x01B0 >> 2)
-#define DP_MAIN_STREAM_N_VID                (0x01B4 >> 2)
-#define DP_USER_DATA_COUNT_PER_LANE         (0x01BC >> 2)
-#define DP_MIN_BYTES_PER_TU                 (0x01C4 >> 2)
-#define DP_FRAC_BYTES_PER_TU                (0x01C8 >> 2)
-#define DP_INIT_WAIT                        (0x01CC >> 2)
-#define DP_PHY_RESET                        (0x0200 >> 2)
-#define DP_PHY_VOLTAGE_DIFF_LANE_0          (0x0220 >> 2)
-#define DP_PHY_VOLTAGE_DIFF_LANE_1          (0x0224 >> 2)
-#define DP_TRANSMIT_PRBS7                   (0x0230 >> 2)
-#define DP_PHY_CLOCK_SELECT                 (0x0234 >> 2)
-#define DP_TX_PHY_POWER_DOWN                (0x0238 >> 2)
-#define DP_PHY_PRECURSOR_LANE_0             (0x023C >> 2)
-#define DP_PHY_PRECURSOR_LANE_1             (0x0240 >> 2)
-#define DP_PHY_POSTCURSOR_LANE_0            (0x024C >> 2)
-#define DP_PHY_POSTCURSOR_LANE_1            (0x0250 >> 2)
-#define DP_PHY_STATUS                       (0x0280 >> 2)
-
-#define DP_TX_AUDIO_CONTROL                 (0x0300 >> 2)
-#define DP_TX_AUD_CTRL                      (1)
-
-#define DP_TX_AUDIO_CHANNELS                (0x0304 >> 2)
-#define DP_TX_AUDIO_INFO_DATA(n)            ((0x0308 + 4 * n) >> 2)
-#define DP_TX_M_AUD                         (0x0328 >> 2)
-#define DP_TX_N_AUD                         (0x032C >> 2)
-#define DP_TX_AUDIO_EXT_DATA(n)             ((0x0330 + 4 * n) >> 2)
-#define DP_INT_STATUS                       (0x03A0 >> 2)
-#define DP_INT_MASK                         (0x03A4 >> 2)
-#define DP_INT_EN                           (0x03A8 >> 2)
-#define DP_INT_DS                           (0x03AC >> 2)
-
-/*
- * Registers offset for Audio Video Buffer configuration.
- */
-#define V_BLEND_OFFSET                      (0xA000)
-#define V_BLEND_BG_CLR_0                    (0x0000 >> 2)
-#define V_BLEND_BG_CLR_1                    (0x0004 >> 2)
-#define V_BLEND_BG_CLR_2                    (0x0008 >> 2)
-#define V_BLEND_SET_GLOBAL_ALPHA_REG        (0x000C >> 2)
-#define V_BLEND_OUTPUT_VID_FORMAT           (0x0014 >> 2)
-#define V_BLEND_LAYER0_CONTROL              (0x0018 >> 2)
-#define V_BLEND_LAYER1_CONTROL              (0x001C >> 2)
-
-#define V_BLEND_RGB2YCBCR_COEFF(n)          ((0x0020 + 4 * n) >> 2)
-#define V_BLEND_IN1CSC_COEFF(n)             ((0x0044 + 4 * n) >> 2)
-
-#define V_BLEND_LUMA_IN1CSC_OFFSET          (0x0068 >> 2)
-#define V_BLEND_CR_IN1CSC_OFFSET            (0x006C >> 2)
-#define V_BLEND_CB_IN1CSC_OFFSET            (0x0070 >> 2)
-#define V_BLEND_LUMA_OUTCSC_OFFSET          (0x0074 >> 2)
-#define V_BLEND_CR_OUTCSC_OFFSET            (0x0078 >> 2)
-#define V_BLEND_CB_OUTCSC_OFFSET            (0x007C >> 2)
-
-#define V_BLEND_IN2CSC_COEFF(n)             ((0x0080 + 4 * n) >> 2)
-
-#define V_BLEND_LUMA_IN2CSC_OFFSET          (0x00A4 >> 2)
-#define V_BLEND_CR_IN2CSC_OFFSET            (0x00A8 >> 2)
-#define V_BLEND_CB_IN2CSC_OFFSET            (0x00AC >> 2)
-#define V_BLEND_CHROMA_KEY_ENABLE           (0x01D0 >> 2)
-#define V_BLEND_CHROMA_KEY_COMP1            (0x01D4 >> 2)
-#define V_BLEND_CHROMA_KEY_COMP2            (0x01D8 >> 2)
-#define V_BLEND_CHROMA_KEY_COMP3            (0x01DC >> 2)
-
-/*
- * Registers offset for Audio Video Buffer configuration.
- */
-#define AV_BUF_MANAGER_OFFSET               (0xB000)
-#define AV_BUF_FORMAT                       (0x0000 >> 2)
-#define AV_BUF_NON_LIVE_LATENCY             (0x0008 >> 2)
-#define AV_CHBUF0                           (0x0010 >> 2)
-#define AV_CHBUF1                           (0x0014 >> 2)
-#define AV_CHBUF2                           (0x0018 >> 2)
-#define AV_CHBUF3                           (0x001C >> 2)
-#define AV_CHBUF4                           (0x0020 >> 2)
-#define AV_CHBUF5                           (0x0024 >> 2)
-#define AV_BUF_STC_CONTROL                  (0x002C >> 2)
-#define AV_BUF_STC_INIT_VALUE0              (0x0030 >> 2)
-#define AV_BUF_STC_INIT_VALUE1              (0x0034 >> 2)
-#define AV_BUF_STC_ADJ                      (0x0038 >> 2)
-#define AV_BUF_STC_VIDEO_VSYNC_TS_REG0      (0x003C >> 2)
-#define AV_BUF_STC_VIDEO_VSYNC_TS_REG1      (0x0040 >> 2)
-#define AV_BUF_STC_EXT_VSYNC_TS_REG0        (0x0044 >> 2)
-#define AV_BUF_STC_EXT_VSYNC_TS_REG1        (0x0048 >> 2)
-#define AV_BUF_STC_CUSTOM_EVENT_TS_REG0     (0x004C >> 2)
-#define AV_BUF_STC_CUSTOM_EVENT_TS_REG1     (0x0050 >> 2)
-#define AV_BUF_STC_CUSTOM_EVENT2_TS_REG0    (0x0054 >> 2)
-#define AV_BUF_STC_CUSTOM_EVENT2_TS_REG1    (0x0058 >> 2)
-#define AV_BUF_STC_SNAPSHOT0                (0x0060 >> 2)
-#define AV_BUF_STC_SNAPSHOT1                (0x0064 >> 2)
-#define AV_BUF_OUTPUT_AUDIO_VIDEO_SELECT    (0x0070 >> 2)
-#define AV_BUF_HCOUNT_VCOUNT_INT0           (0x0074 >> 2)
-#define AV_BUF_HCOUNT_VCOUNT_INT1           (0x0078 >> 2)
-#define AV_BUF_DITHER_CONFIG                (0x007C >> 2)
-#define AV_BUF_DITHER_CONFIG_MAX            (0x008C >> 2)
-#define AV_BUF_DITHER_CONFIG_MIN            (0x0090 >> 2)
-#define AV_BUF_PATTERN_GEN_SELECT           (0x0100 >> 2)
-#define AV_BUF_AUD_VID_CLK_SOURCE           (0x0120 >> 2)
-#define AV_BUF_SRST_REG                     (0x0124 >> 2)
-#define AV_BUF_AUDIO_RDY_INTERVAL           (0x0128 >> 2)
-#define AV_BUF_AUDIO_CH_CONFIG              (0x012C >> 2)
-
-#define AV_BUF_GRAPHICS_COMP_SCALE_FACTOR(n)((0x0200 + 4 * n) >> 2)
-
-#define AV_BUF_VIDEO_COMP_SCALE_FACTOR(n)   ((0x020C + 4 * n) >> 2)
-
-#define AV_BUF_LIVE_VIDEO_COMP_SF(n)        ((0x0218 + 4 * n) >> 2)
-
-#define AV_BUF_LIVE_VID_CONFIG              (0x0224 >> 2)
-
-#define AV_BUF_LIVE_GFX_COMP_SF(n)          ((0x0228 + 4 * n) >> 2)
-
-#define AV_BUF_LIVE_GFX_CONFIG              (0x0234 >> 2)
-
-#define AUDIO_MIXER_REGISTER_OFFSET         (0xC000)
-#define AUDIO_MIXER_VOLUME_CONTROL          (0x0000 >> 2)
-#define AUDIO_MIXER_META_DATA               (0x0004 >> 2)
-#define AUD_CH_STATUS_REG(n)                ((0x0008 + 4 * n) >> 2)
-#define AUD_CH_A_DATA_REG(n)                ((0x0020 + 4 * n) >> 2)
-#define AUD_CH_B_DATA_REG(n)                ((0x0038 + 4 * n) >> 2)
-
-#define DP_AUDIO_DMA_CHANNEL(n)             (4 + n)
-#define DP_GRAPHIC_DMA_CHANNEL              (3)
-#define DP_VIDEO_DMA_CHANNEL                (0)
-
-enum DPGraphicFmt {
-    DP_GRAPHIC_RGBA8888 = 0 << 8,
-    DP_GRAPHIC_ABGR8888 = 1 << 8,
-    DP_GRAPHIC_RGB888 = 2 << 8,
-    DP_GRAPHIC_BGR888 = 3 << 8,
-    DP_GRAPHIC_RGBA5551 = 4 << 8,
-    DP_GRAPHIC_RGBA4444 = 5 << 8,
-    DP_GRAPHIC_RGB565 = 6 << 8,
-    DP_GRAPHIC_8BPP = 7 << 8,
-    DP_GRAPHIC_4BPP = 8 << 8,
-    DP_GRAPHIC_2BPP = 9 << 8,
-    DP_GRAPHIC_1BPP = 10 << 8,
-    DP_GRAPHIC_MASK = 0xF << 8
-};
-
-enum DPVideoFmt {
-    DP_NL_VID_CB_Y0_CR_Y1 = 0,
-    DP_NL_VID_CR_Y0_CB_Y1 = 1,
-    DP_NL_VID_Y0_CR_Y1_CB = 2,
-    DP_NL_VID_Y0_CB_Y1_CR = 3,
-    DP_NL_VID_YV16 = 4,
-    DP_NL_VID_YV24 = 5,
-    DP_NL_VID_YV16CL = 6,
-    DP_NL_VID_MONO = 7,
-    DP_NL_VID_YV16CL2 = 8,
-    DP_NL_VID_YUV444 = 9,
-    DP_NL_VID_RGB888 = 10,
-    DP_NL_VID_RGBA8880 = 11,
-    DP_NL_VID_RGB888_10BPC = 12,
-    DP_NL_VID_YUV444_10BPC = 13,
-    DP_NL_VID_YV16CL2_10BPC = 14,
-    DP_NL_VID_YV16CL_10BPC = 15,
-    DP_NL_VID_YV16_10BPC = 16,
-    DP_NL_VID_YV24_10BPC = 17,
-    DP_NL_VID_Y_ONLY_10BPC = 18,
-    DP_NL_VID_YV16_420 = 19,
-    DP_NL_VID_YV16CL_420 = 20,
-    DP_NL_VID_YV16CL2_420 = 21,
-    DP_NL_VID_YV16_420_10BPC = 22,
-    DP_NL_VID_YV16CL_420_10BPC = 23,
-    DP_NL_VID_YV16CL2_420_10BPC = 24,
-    DP_NL_VID_FMT_MASK = 0x1F
-};
-
-typedef enum DPGraphicFmt DPGraphicFmt;
-typedef enum DPVideoFmt DPVideoFmt;
-
-static const VMStateDescription vmstate_dp = {
-    .name = TYPE_XLNX_DP,
-    .version_id = 1,
-    .fields = (VMStateField[]){
-        VMSTATE_UINT32_ARRAY(core_registers, XlnxDPState,
-                             DP_CORE_REG_ARRAY_SIZE),
-        VMSTATE_UINT32_ARRAY(avbufm_registers, XlnxDPState,
-                             DP_AVBUF_REG_ARRAY_SIZE),
-        VMSTATE_UINT32_ARRAY(vblend_registers, XlnxDPState,
-                             DP_VBLEND_REG_ARRAY_SIZE),
-        VMSTATE_UINT32_ARRAY(audio_registers, XlnxDPState,
-                             DP_AUDIO_REG_ARRAY_SIZE),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static void xlnx_dp_update_irq(XlnxDPState *s);
-
-static uint64_t xlnx_dp_audio_read(void *opaque, hwaddr offset, unsigned size)
-{
-    XlnxDPState *s = XLNX_DP(opaque);
-
-    offset = offset >> 2;
-    return s->audio_registers[offset];
-}
-
-static void xlnx_dp_audio_write(void *opaque, hwaddr offset, uint64_t value,
-                                unsigned size)
-{
-    XlnxDPState *s = XLNX_DP(opaque);
-
-    offset = offset >> 2;
-
-    switch (offset) {
-    case AUDIO_MIXER_META_DATA:
-        s->audio_registers[offset] = value & 0x00000001;
-        break;
-    default:
-        s->audio_registers[offset] = value;
-        break;
-    }
-}
-
-static const MemoryRegionOps audio_ops = {
-    .read = xlnx_dp_audio_read,
-    .write = xlnx_dp_audio_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static inline uint32_t xlnx_dp_audio_get_volume(XlnxDPState *s,
-                                                uint8_t channel)
-{
-    switch (channel) {
-    case 0:
-        return extract32(s->audio_registers[AUDIO_MIXER_VOLUME_CONTROL], 0, 16);
-    case 1:
-        return extract32(s->audio_registers[AUDIO_MIXER_VOLUME_CONTROL], 16,
-                                                                         16);
-    default:
-        return 0;
-    }
-}
-
-static inline void xlnx_dp_audio_activate(XlnxDPState *s)
-{
-    bool activated = ((s->core_registers[DP_TX_AUDIO_CONTROL]
-                   & DP_TX_AUD_CTRL) != 0);
-    AUD_set_active_out(s->amixer_output_stream, activated);
-    xlnx_dpdma_set_host_data_location(s->dpdma, DP_AUDIO_DMA_CHANNEL(0),
-                                      &s->audio_buffer_0);
-    xlnx_dpdma_set_host_data_location(s->dpdma, DP_AUDIO_DMA_CHANNEL(1),
-                                      &s->audio_buffer_1);
-}
-
-static inline void xlnx_dp_audio_mix_buffer(XlnxDPState *s)
-{
-    /*
-     * Audio packets are signed and have this shape:
-     * | 16 | 16 | 16 | 16 | 16 | 16 | 16 | 16 |
-     * | R3 | L3 | R2 | L2 | R1 | L1 | R0 | L0 |
-     *
-     * Output audio is 16bits saturated.
-     */
-    int i;
-
-    if ((s->audio_data_available[0]) && (xlnx_dp_audio_get_volume(s, 0))) {
-        for (i = 0; i < s->audio_data_available[0] / 2; i++) {
-            s->temp_buffer[i] = (int64_t)(s->audio_buffer_0[i])
-                              * xlnx_dp_audio_get_volume(s, 0) / 8192;
-        }
-        s->byte_left = s->audio_data_available[0];
-    } else {
-        memset(s->temp_buffer, 0, s->audio_data_available[1] / 2);
-    }
-
-    if ((s->audio_data_available[1]) && (xlnx_dp_audio_get_volume(s, 1))) {
-        if ((s->audio_data_available[0] == 0)
-        || (s->audio_data_available[1] == s->audio_data_available[0])) {
-            for (i = 0; i < s->audio_data_available[1] / 2; i++) {
-                s->temp_buffer[i] += (int64_t)(s->audio_buffer_1[i])
-                                   * xlnx_dp_audio_get_volume(s, 1) / 8192;
-            }
-            s->byte_left = s->audio_data_available[1];
-        }
-    }
-
-    for (i = 0; i < s->byte_left / 2; i++) {
-        s->out_buffer[i] = MAX(-32767, MIN(s->temp_buffer[i], 32767));
-    }
-
-    s->data_ptr = 0;
-}
-
-static void xlnx_dp_audio_callback(void *opaque, int avail)
-{
-    /*
-     * Get some data from the DPDMA and compute these datas.
-     * Then wait for QEMU's audio subsystem to call this callback.
-     */
-    XlnxDPState *s = XLNX_DP(opaque);
-    size_t written = 0;
-
-    /* If there are already some data don't get more data. */
-    if (s->byte_left == 0) {
-        s->audio_data_available[0] = xlnx_dpdma_start_operation(s->dpdma, 4,
-                                                                  true);
-        s->audio_data_available[1] = xlnx_dpdma_start_operation(s->dpdma, 5,
-                                                                  true);
-        xlnx_dp_audio_mix_buffer(s);
-    }
-
-    /* Send the buffer through the audio. */
-    if (s->byte_left <= MAX_QEMU_BUFFER_SIZE) {
-        if (s->byte_left != 0) {
-            written = AUD_write(s->amixer_output_stream,
-                                &s->out_buffer[s->data_ptr], s->byte_left);
-        } else {
-            /*
-             * There is nothing to play.. We don't have any data! Fill the
-             * buffer with zero's and send it.
-             */
-            written = 0;
-            memset(s->out_buffer, 0, 1024);
-            AUD_write(s->amixer_output_stream, s->out_buffer, 1024);
-        }
-    } else {
-        written = AUD_write(s->amixer_output_stream,
-                            &s->out_buffer[s->data_ptr], MAX_QEMU_BUFFER_SIZE);
-    }
-    s->byte_left -= written;
-    s->data_ptr += written;
-}
-
-/*
- * AUX channel related function.
- */
-static void xlnx_dp_aux_clear_rx_fifo(XlnxDPState *s)
-{
-    fifo8_reset(&s->rx_fifo);
-}
-
-static void xlnx_dp_aux_push_rx_fifo(XlnxDPState *s, uint8_t *buf, size_t len)
-{
-    DPRINTF("Push %u data in rx_fifo\n", (unsigned)len);
-    fifo8_push_all(&s->rx_fifo, buf, len);
-}
-
-static uint8_t xlnx_dp_aux_pop_rx_fifo(XlnxDPState *s)
-{
-    uint8_t ret;
-
-    if (fifo8_is_empty(&s->rx_fifo)) {
-        DPRINTF("rx_fifo underflow..\n");
-        abort();
-    }
-    ret = fifo8_pop(&s->rx_fifo);
-    DPRINTF("pop 0x%" PRIX8 " from rx_fifo.\n", ret);
-    return ret;
-}
-
-static void xlnx_dp_aux_clear_tx_fifo(XlnxDPState *s)
-{
-    fifo8_reset(&s->tx_fifo);
-}
-
-static void xlnx_dp_aux_push_tx_fifo(XlnxDPState *s, uint8_t *buf, size_t len)
-{
-    DPRINTF("Push %u data in tx_fifo\n", (unsigned)len);
-    fifo8_push_all(&s->tx_fifo, buf, len);
-}
-
-static uint8_t xlnx_dp_aux_pop_tx_fifo(XlnxDPState *s)
-{
-    uint8_t ret;
-
-    if (fifo8_is_empty(&s->tx_fifo)) {
-        DPRINTF("tx_fifo underflow..\n");
-        abort();
-    }
-    ret = fifo8_pop(&s->tx_fifo);
-    DPRINTF("pop 0x%2.2X from tx_fifo.\n", ret);
-    return ret;
-}
-
-static uint32_t xlnx_dp_aux_get_address(XlnxDPState *s)
-{
-    return s->core_registers[DP_AUX_ADDRESS];
-}
-
-/*
- * Get command from the register.
- */
-static void xlnx_dp_aux_set_command(XlnxDPState *s, uint32_t value)
-{
-    bool address_only = (value & AUX_ADDR_ONLY_MASK) != 0;
-    AUXCommand cmd = (value & AUX_COMMAND_MASK) >> AUX_COMMAND_SHIFT;
-    uint8_t nbytes = (value & AUX_COMMAND_NBYTES) + 1;
-    uint8_t buf[16];
-    int i;
-
-    /*
-     * When an address_only command is executed nothing happen to the fifo, so
-     * just make nbytes = 0.
-     */
-    if (address_only) {
-        nbytes = 0;
-    }
-
-    switch (cmd) {
-    case READ_AUX:
-    case READ_I2C:
-    case READ_I2C_MOT:
-        s->core_registers[DP_AUX_REPLY_CODE] = aux_request(s->aux_bus, cmd,
-                                               xlnx_dp_aux_get_address(s),
-                                               nbytes, buf);
-        s->core_registers[DP_REPLY_DATA_COUNT] = nbytes;
-
-        if (s->core_registers[DP_AUX_REPLY_CODE] == AUX_I2C_ACK) {
-            xlnx_dp_aux_push_rx_fifo(s, buf, nbytes);
-        }
-        break;
-    case WRITE_AUX:
-    case WRITE_I2C:
-    case WRITE_I2C_MOT:
-        for (i = 0; i < nbytes; i++) {
-            buf[i] = xlnx_dp_aux_pop_tx_fifo(s);
-        }
-        s->core_registers[DP_AUX_REPLY_CODE] = aux_request(s->aux_bus, cmd,
-                                               xlnx_dp_aux_get_address(s),
-                                               nbytes, buf);
-        xlnx_dp_aux_clear_tx_fifo(s);
-        break;
-    case WRITE_I2C_STATUS:
-        qemu_log_mask(LOG_UNIMP, "xlnx_dp: Write i2c status not implemented\n");
-        break;
-    default:
-        abort();
-    }
-
-    s->core_registers[DP_INTERRUPT_SIGNAL_STATE] |= 0x04;
-}
-
-static void xlnx_dp_set_dpdma(Object *obj, const char *name, Object *val,
-                              Error **errp)
-{
-    XlnxDPState *s = XLNX_DP(obj);
-    if (s->console) {
-        DisplaySurface *surface = qemu_console_surface(s->console);
-        XlnxDPDMAState *dma = XLNX_DPDMA(val);
-        xlnx_dpdma_set_host_data_location(dma, DP_GRAPHIC_DMA_CHANNEL,
-                                          surface_data(surface));
-    }
-}
-
-static inline uint8_t xlnx_dp_global_alpha_value(XlnxDPState *s)
-{
-    return (s->vblend_registers[V_BLEND_SET_GLOBAL_ALPHA_REG] & 0x1FE) >> 1;
-}
-
-static inline bool xlnx_dp_global_alpha_enabled(XlnxDPState *s)
-{
-    /*
-     * If the alpha is totally opaque (255) we consider the alpha is disabled to
-     * reduce CPU consumption.
-     */
-    return ((xlnx_dp_global_alpha_value(s) != 0xFF) &&
-           ((s->vblend_registers[V_BLEND_SET_GLOBAL_ALPHA_REG] & 0x01) != 0));
-}
-
-static void xlnx_dp_recreate_surface(XlnxDPState *s)
-{
-    /*
-     * Two possibilities, if blending is enabled the console displays
-     * bout_plane, if not g_plane is displayed.
-     */
-    uint16_t width = s->core_registers[DP_MAIN_STREAM_HRES];
-    uint16_t height = s->core_registers[DP_MAIN_STREAM_VRES];
-    DisplaySurface *current_console_surface = qemu_console_surface(s->console);
-
-    if ((width != 0) && (height != 0)) {
-        /*
-         * As dpy_gfx_replace_surface calls qemu_free_displaysurface on the
-         * surface we need to be carefull and don't free the surface associated
-         * to the console or double free will happen.
-         */
-        if (s->bout_plane.surface != current_console_surface) {
-            qemu_free_displaysurface(s->bout_plane.surface);
-        }
-        if (s->v_plane.surface != current_console_surface) {
-            qemu_free_displaysurface(s->v_plane.surface);
-        }
-        if (s->g_plane.surface != current_console_surface) {
-            qemu_free_displaysurface(s->g_plane.surface);
-        }
-
-        s->g_plane.surface
-                = qemu_create_displaysurface_from(width, height,
-                                                  s->g_plane.format, 0, NULL);
-        s->v_plane.surface
-                = qemu_create_displaysurface_from(width, height,
-                                                  s->v_plane.format, 0, NULL);
-        if (xlnx_dp_global_alpha_enabled(s)) {
-            s->bout_plane.surface =
-                            qemu_create_displaysurface_from(width,
-                                                            height,
-                                                            s->g_plane.format,
-                                                            0, NULL);
-            dpy_gfx_replace_surface(s->console, s->bout_plane.surface);
-        } else {
-            s->bout_plane.surface = NULL;
-            dpy_gfx_replace_surface(s->console, s->g_plane.surface);
-        }
-
-        xlnx_dpdma_set_host_data_location(s->dpdma, DP_GRAPHIC_DMA_CHANNEL,
-                                            surface_data(s->g_plane.surface));
-        xlnx_dpdma_set_host_data_location(s->dpdma, DP_VIDEO_DMA_CHANNEL,
-                                            surface_data(s->v_plane.surface));
-    }
-}
-
-/*
- * Change the graphic format of the surface.
- */
-static void xlnx_dp_change_graphic_fmt(XlnxDPState *s)
-{
-    switch (s->avbufm_registers[AV_BUF_FORMAT] & DP_GRAPHIC_MASK) {
-    case DP_GRAPHIC_RGBA8888:
-        s->g_plane.format = PIXMAN_r8g8b8a8;
-        break;
-    case DP_GRAPHIC_ABGR8888:
-        s->g_plane.format = PIXMAN_a8b8g8r8;
-        break;
-    case DP_GRAPHIC_RGB565:
-        s->g_plane.format = PIXMAN_r5g6b5;
-        break;
-    case DP_GRAPHIC_RGB888:
-        s->g_plane.format = PIXMAN_r8g8b8;
-        break;
-    case DP_GRAPHIC_BGR888:
-        s->g_plane.format = PIXMAN_b8g8r8;
-        break;
-    default:
-        DPRINTF("error: unsupported graphic format %u.\n",
-                s->avbufm_registers[AV_BUF_FORMAT] & DP_GRAPHIC_MASK);
-        abort();
-    }
-
-    switch (s->avbufm_registers[AV_BUF_FORMAT] & DP_NL_VID_FMT_MASK) {
-    case 0:
-        s->v_plane.format = PIXMAN_x8b8g8r8;
-        break;
-    case DP_NL_VID_RGBA8880:
-        s->v_plane.format = PIXMAN_x8b8g8r8;
-        break;
-    default:
-        DPRINTF("error: unsupported video format %u.\n",
-                s->avbufm_registers[AV_BUF_FORMAT] & DP_NL_VID_FMT_MASK);
-        abort();
-    }
-
-    xlnx_dp_recreate_surface(s);
-}
-
-static void xlnx_dp_update_irq(XlnxDPState *s)
-{
-    uint32_t flags;
-
-    flags = s->core_registers[DP_INT_STATUS] & ~s->core_registers[DP_INT_MASK];
-    DPRINTF("update IRQ value = %" PRIx32 "\n", flags);
-    qemu_set_irq(s->irq, flags != 0);
-}
-
-static uint64_t xlnx_dp_read(void *opaque, hwaddr offset, unsigned size)
-{
-    XlnxDPState *s = XLNX_DP(opaque);
-    uint64_t ret = 0;
-
-    offset = offset >> 2;
-
-    switch (offset) {
-    case DP_TX_USER_FIFO_OVERFLOW:
-        /* This register is cleared after a read */
-        ret = s->core_registers[DP_TX_USER_FIFO_OVERFLOW];
-        s->core_registers[DP_TX_USER_FIFO_OVERFLOW] = 0;
-        break;
-    case DP_AUX_REPLY_DATA:
-        ret = xlnx_dp_aux_pop_rx_fifo(s);
-        break;
-    case DP_INTERRUPT_SIGNAL_STATE:
-        /*
-         * XXX: Not sure it is the right thing to do actually.
-         * The register is not written by the device driver so it's stuck
-         * to 0x04.
-         */
-        ret = s->core_registers[DP_INTERRUPT_SIGNAL_STATE];
-        s->core_registers[DP_INTERRUPT_SIGNAL_STATE] &= ~0x04;
-        break;
-    case DP_AUX_WRITE_FIFO:
-    case DP_TX_AUDIO_INFO_DATA(0):
-    case DP_TX_AUDIO_INFO_DATA(1):
-    case DP_TX_AUDIO_INFO_DATA(2):
-    case DP_TX_AUDIO_INFO_DATA(3):
-    case DP_TX_AUDIO_INFO_DATA(4):
-    case DP_TX_AUDIO_INFO_DATA(5):
-    case DP_TX_AUDIO_INFO_DATA(6):
-    case DP_TX_AUDIO_INFO_DATA(7):
-    case DP_TX_AUDIO_EXT_DATA(0):
-    case DP_TX_AUDIO_EXT_DATA(1):
-    case DP_TX_AUDIO_EXT_DATA(2):
-    case DP_TX_AUDIO_EXT_DATA(3):
-    case DP_TX_AUDIO_EXT_DATA(4):
-    case DP_TX_AUDIO_EXT_DATA(5):
-    case DP_TX_AUDIO_EXT_DATA(6):
-    case DP_TX_AUDIO_EXT_DATA(7):
-    case DP_TX_AUDIO_EXT_DATA(8):
-        /* write only registers */
-        ret = 0;
-        break;
-    default:
-        assert(offset <= (0x3AC >> 2));
-        ret = s->core_registers[offset];
-        break;
-    }
-
-    DPRINTF("core read @%" PRIx64 " = 0x%8.8" PRIX64 "\n", offset << 2, ret);
-    return ret;
-}
-
-static void xlnx_dp_write(void *opaque, hwaddr offset, uint64_t value,
-                          unsigned size)
-{
-    XlnxDPState *s = XLNX_DP(opaque);
-
-    DPRINTF("core write @%" PRIx64 " = 0x%8.8" PRIX64 "\n", offset, value);
-
-    offset = offset >> 2;
-
-    switch (offset) {
-    /*
-     * Only special write case are handled.
-     */
-    case DP_LINK_BW_SET:
-        s->core_registers[offset] = value & 0x000000FF;
-        break;
-    case DP_LANE_COUNT_SET:
-    case DP_MAIN_STREAM_MISC0:
-        s->core_registers[offset] = value & 0x0000000F;
-        break;
-    case DP_TRAINING_PATTERN_SET:
-    case DP_LINK_QUAL_PATTERN_SET:
-    case DP_MAIN_STREAM_POLARITY:
-    case DP_PHY_VOLTAGE_DIFF_LANE_0:
-    case DP_PHY_VOLTAGE_DIFF_LANE_1:
-        s->core_registers[offset] = value & 0x00000003;
-        break;
-    case DP_ENHANCED_FRAME_EN:
-    case DP_SCRAMBLING_DISABLE:
-    case DP_DOWNSPREAD_CTRL:
-    case DP_MAIN_STREAM_ENABLE:
-    case DP_TRANSMIT_PRBS7:
-        s->core_registers[offset] = value & 0x00000001;
-        break;
-    case DP_PHY_CLOCK_SELECT:
-        s->core_registers[offset] = value & 0x00000007;
-        break;
-    case DP_SOFTWARE_RESET:
-        /*
-         * No need to update this bit as it's read '0'.
-         */
-        /*
-         * TODO: reset IP.
-         */
-        break;
-    case DP_TRANSMITTER_ENABLE:
-        s->core_registers[offset] = value & 0x01;
-        break;
-    case DP_FORCE_SCRAMBLER_RESET:
-        /*
-         * No need to update this bit as it's read '0'.
-         */
-        /*
-         * TODO: force a scrambler reset??
-         */
-        break;
-    case DP_AUX_COMMAND_REGISTER:
-        s->core_registers[offset] = value & 0x00001F0F;
-        xlnx_dp_aux_set_command(s, s->core_registers[offset]);
-        break;
-    case DP_MAIN_STREAM_HTOTAL:
-    case DP_MAIN_STREAM_VTOTAL:
-    case DP_MAIN_STREAM_HSTART:
-    case DP_MAIN_STREAM_VSTART:
-        s->core_registers[offset] = value & 0x0000FFFF;
-        break;
-    case DP_MAIN_STREAM_HRES:
-    case DP_MAIN_STREAM_VRES:
-        s->core_registers[offset] = value & 0x0000FFFF;
-        xlnx_dp_recreate_surface(s);
-        break;
-    case DP_MAIN_STREAM_HSWIDTH:
-    case DP_MAIN_STREAM_VSWIDTH:
-        s->core_registers[offset] = value & 0x00007FFF;
-        break;
-    case DP_MAIN_STREAM_MISC1:
-        s->core_registers[offset] = value & 0x00000086;
-        break;
-    case DP_MAIN_STREAM_M_VID:
-    case DP_MAIN_STREAM_N_VID:
-        s->core_registers[offset] = value & 0x00FFFFFF;
-        break;
-    case DP_MSA_TRANSFER_UNIT_SIZE:
-    case DP_MIN_BYTES_PER_TU:
-    case DP_INIT_WAIT:
-        s->core_registers[offset] = value & 0x00000007;
-        break;
-    case DP_USER_DATA_COUNT_PER_LANE:
-        s->core_registers[offset] = value & 0x0003FFFF;
-        break;
-    case DP_FRAC_BYTES_PER_TU:
-        s->core_registers[offset] = value & 0x000003FF;
-        break;
-    case DP_PHY_RESET:
-        s->core_registers[offset] = value & 0x00010003;
-        /*
-         * TODO: Reset something?
-         */
-        break;
-    case DP_TX_PHY_POWER_DOWN:
-        s->core_registers[offset] = value & 0x0000000F;
-        /*
-         * TODO: Power down things?
-         */
-        break;
-    case DP_AUX_WRITE_FIFO: {
-        uint8_t c = value;
-        xlnx_dp_aux_push_tx_fifo(s, &c, 1);
-        break;
-    }
-    case DP_AUX_CLOCK_DIVIDER:
-        break;
-    case DP_AUX_REPLY_COUNT:
-        /*
-         * Writing to this register clear the counter.
-         */
-        s->core_registers[offset] = 0x00000000;
-        break;
-    case DP_AUX_ADDRESS:
-        s->core_registers[offset] = value & 0x000FFFFF;
-        break;
-    case DP_VERSION_REGISTER:
-    case DP_CORE_ID:
-    case DP_TX_USER_FIFO_OVERFLOW:
-    case DP_AUX_REPLY_DATA:
-    case DP_AUX_REPLY_CODE:
-    case DP_REPLY_DATA_COUNT:
-    case DP_REPLY_STATUS:
-    case DP_HPD_DURATION:
-        /*
-         * Write to read only location..
-         */
-        break;
-    case DP_TX_AUDIO_CONTROL:
-        s->core_registers[offset] = value & 0x00000001;
-        xlnx_dp_audio_activate(s);
-        break;
-    case DP_TX_AUDIO_CHANNELS:
-        s->core_registers[offset] = value & 0x00000007;
-        xlnx_dp_audio_activate(s);
-        break;
-    case DP_INT_STATUS:
-        s->core_registers[DP_INT_STATUS] &= ~value;
-        xlnx_dp_update_irq(s);
-        break;
-    case DP_INT_EN:
-        s->core_registers[DP_INT_MASK] &= ~value;
-        xlnx_dp_update_irq(s);
-        break;
-    case DP_INT_DS:
-        s->core_registers[DP_INT_MASK] |= ~value;
-        xlnx_dp_update_irq(s);
-        break;
-    default:
-        assert(offset <= (0x504C >> 2));
-        s->core_registers[offset] = value;
-        break;
-    }
-}
-
-static const MemoryRegionOps dp_ops = {
-    .read = xlnx_dp_read,
-    .write = xlnx_dp_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-    .impl = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-};
-
-/*
- * This is to handle Read/Write to the Video Blender.
- */
-static void xlnx_dp_vblend_write(void *opaque, hwaddr offset,
-                                 uint64_t value, unsigned size)
-{
-    XlnxDPState *s = XLNX_DP(opaque);
-    bool alpha_was_enabled;
-
-    DPRINTF("vblend: write @0x%" HWADDR_PRIX " = 0x%" PRIX32 "\n", offset,
-                                                               (uint32_t)value);
-    offset = offset >> 2;
-
-    switch (offset) {
-    case V_BLEND_BG_CLR_0:
-    case V_BLEND_BG_CLR_1:
-    case V_BLEND_BG_CLR_2:
-        s->vblend_registers[offset] = value & 0x00000FFF;
-        break;
-    case V_BLEND_SET_GLOBAL_ALPHA_REG:
-        /*
-         * A write to this register can enable or disable blending. Thus we need
-         * to recreate the surfaces.
-         */
-        alpha_was_enabled = xlnx_dp_global_alpha_enabled(s);
-        s->vblend_registers[offset] = value & 0x000001FF;
-        if (xlnx_dp_global_alpha_enabled(s) != alpha_was_enabled) {
-            xlnx_dp_recreate_surface(s);
-        }
-        break;
-    case V_BLEND_OUTPUT_VID_FORMAT:
-        s->vblend_registers[offset] = value & 0x00000017;
-        break;
-    case V_BLEND_LAYER0_CONTROL:
-    case V_BLEND_LAYER1_CONTROL:
-        s->vblend_registers[offset] = value & 0x00000103;
-        break;
-    case V_BLEND_RGB2YCBCR_COEFF(0):
-    case V_BLEND_RGB2YCBCR_COEFF(1):
-    case V_BLEND_RGB2YCBCR_COEFF(2):
-    case V_BLEND_RGB2YCBCR_COEFF(3):
-    case V_BLEND_RGB2YCBCR_COEFF(4):
-    case V_BLEND_RGB2YCBCR_COEFF(5):
-    case V_BLEND_RGB2YCBCR_COEFF(6):
-    case V_BLEND_RGB2YCBCR_COEFF(7):
-    case V_BLEND_RGB2YCBCR_COEFF(8):
-    case V_BLEND_IN1CSC_COEFF(0):
-    case V_BLEND_IN1CSC_COEFF(1):
-    case V_BLEND_IN1CSC_COEFF(2):
-    case V_BLEND_IN1CSC_COEFF(3):
-    case V_BLEND_IN1CSC_COEFF(4):
-    case V_BLEND_IN1CSC_COEFF(5):
-    case V_BLEND_IN1CSC_COEFF(6):
-    case V_BLEND_IN1CSC_COEFF(7):
-    case V_BLEND_IN1CSC_COEFF(8):
-    case V_BLEND_IN2CSC_COEFF(0):
-    case V_BLEND_IN2CSC_COEFF(1):
-    case V_BLEND_IN2CSC_COEFF(2):
-    case V_BLEND_IN2CSC_COEFF(3):
-    case V_BLEND_IN2CSC_COEFF(4):
-    case V_BLEND_IN2CSC_COEFF(5):
-    case V_BLEND_IN2CSC_COEFF(6):
-    case V_BLEND_IN2CSC_COEFF(7):
-    case V_BLEND_IN2CSC_COEFF(8):
-        s->vblend_registers[offset] = value & 0x0000FFFF;
-        break;
-    case V_BLEND_LUMA_IN1CSC_OFFSET:
-    case V_BLEND_CR_IN1CSC_OFFSET:
-    case V_BLEND_CB_IN1CSC_OFFSET:
-    case V_BLEND_LUMA_IN2CSC_OFFSET:
-    case V_BLEND_CR_IN2CSC_OFFSET:
-    case V_BLEND_CB_IN2CSC_OFFSET:
-    case V_BLEND_LUMA_OUTCSC_OFFSET:
-    case V_BLEND_CR_OUTCSC_OFFSET:
-    case V_BLEND_CB_OUTCSC_OFFSET:
-        s->vblend_registers[offset] = value & 0x3FFF7FFF;
-        break;
-    case V_BLEND_CHROMA_KEY_ENABLE:
-        s->vblend_registers[offset] = value & 0x00000003;
-        break;
-    case V_BLEND_CHROMA_KEY_COMP1:
-    case V_BLEND_CHROMA_KEY_COMP2:
-    case V_BLEND_CHROMA_KEY_COMP3:
-        s->vblend_registers[offset] = value & 0x0FFF0FFF;
-        break;
-    default:
-        s->vblend_registers[offset] = value;
-        break;
-    }
-}
-
-static uint64_t xlnx_dp_vblend_read(void *opaque, hwaddr offset,
-                                    unsigned size)
-{
-    XlnxDPState *s = XLNX_DP(opaque);
-
-    DPRINTF("vblend: read @0x%" HWADDR_PRIX " = 0x%" PRIX32 "\n", offset,
-            s->vblend_registers[offset >> 2]);
-    return s->vblend_registers[offset >> 2];
-}
-
-static const MemoryRegionOps vblend_ops = {
-    .read = xlnx_dp_vblend_read,
-    .write = xlnx_dp_vblend_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-    .impl = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-};
-
-/*
- * This is to handle Read/Write to the Audio Video buffer manager.
- */
-static void xlnx_dp_avbufm_write(void *opaque, hwaddr offset, uint64_t value,
-                                 unsigned size)
-{
-    XlnxDPState *s = XLNX_DP(opaque);
-
-    DPRINTF("avbufm: write @0x%" HWADDR_PRIX " = 0x%" PRIX32 "\n", offset,
-                                                               (uint32_t)value);
-    offset = offset >> 2;
-
-    switch (offset) {
-    case AV_BUF_FORMAT:
-        s->avbufm_registers[offset] = value & 0x00000FFF;
-        xlnx_dp_change_graphic_fmt(s);
-        break;
-    case AV_CHBUF0:
-    case AV_CHBUF1:
-    case AV_CHBUF2:
-    case AV_CHBUF3:
-    case AV_CHBUF4:
-    case AV_CHBUF5:
-        s->avbufm_registers[offset] = value & 0x0000007F;
-        break;
-    case AV_BUF_OUTPUT_AUDIO_VIDEO_SELECT:
-        s->avbufm_registers[offset] = value & 0x0000007F;
-        break;
-    case AV_BUF_DITHER_CONFIG:
-        s->avbufm_registers[offset] = value & 0x000007FF;
-        break;
-    case AV_BUF_DITHER_CONFIG_MAX:
-    case AV_BUF_DITHER_CONFIG_MIN:
-        s->avbufm_registers[offset] = value & 0x00000FFF;
-        break;
-    case AV_BUF_PATTERN_GEN_SELECT:
-        s->avbufm_registers[offset] = value & 0xFFFFFF03;
-        break;
-    case AV_BUF_AUD_VID_CLK_SOURCE:
-        s->avbufm_registers[offset] = value & 0x00000007;
-        break;
-    case AV_BUF_SRST_REG:
-        s->avbufm_registers[offset] = value & 0x00000002;
-        break;
-    case AV_BUF_AUDIO_CH_CONFIG:
-        s->avbufm_registers[offset] = value & 0x00000003;
-        break;
-    case AV_BUF_GRAPHICS_COMP_SCALE_FACTOR(0):
-    case AV_BUF_GRAPHICS_COMP_SCALE_FACTOR(1):
-    case AV_BUF_GRAPHICS_COMP_SCALE_FACTOR(2):
-    case AV_BUF_VIDEO_COMP_SCALE_FACTOR(0):
-    case AV_BUF_VIDEO_COMP_SCALE_FACTOR(1):
-    case AV_BUF_VIDEO_COMP_SCALE_FACTOR(2):
-        s->avbufm_registers[offset] = value & 0x0000FFFF;
-        break;
-    case AV_BUF_LIVE_VIDEO_COMP_SF(0):
-    case AV_BUF_LIVE_VIDEO_COMP_SF(1):
-    case AV_BUF_LIVE_VIDEO_COMP_SF(2):
-    case AV_BUF_LIVE_VID_CONFIG:
-    case AV_BUF_LIVE_GFX_COMP_SF(0):
-    case AV_BUF_LIVE_GFX_COMP_SF(1):
-    case AV_BUF_LIVE_GFX_COMP_SF(2):
-    case AV_BUF_LIVE_GFX_CONFIG:
-    case AV_BUF_NON_LIVE_LATENCY:
-    case AV_BUF_STC_CONTROL:
-    case AV_BUF_STC_INIT_VALUE0:
-    case AV_BUF_STC_INIT_VALUE1:
-    case AV_BUF_STC_ADJ:
-    case AV_BUF_STC_VIDEO_VSYNC_TS_REG0:
-    case AV_BUF_STC_VIDEO_VSYNC_TS_REG1:
-    case AV_BUF_STC_EXT_VSYNC_TS_REG0:
-    case AV_BUF_STC_EXT_VSYNC_TS_REG1:
-    case AV_BUF_STC_CUSTOM_EVENT_TS_REG0:
-    case AV_BUF_STC_CUSTOM_EVENT_TS_REG1:
-    case AV_BUF_STC_CUSTOM_EVENT2_TS_REG0:
-    case AV_BUF_STC_CUSTOM_EVENT2_TS_REG1:
-    case AV_BUF_STC_SNAPSHOT0:
-    case AV_BUF_STC_SNAPSHOT1:
-    case AV_BUF_HCOUNT_VCOUNT_INT0:
-    case AV_BUF_HCOUNT_VCOUNT_INT1:
-        qemu_log_mask(LOG_UNIMP, "avbufm: unimplmented");
-        break;
-    default:
-        s->avbufm_registers[offset] = value;
-        break;
-    }
-}
-
-static uint64_t xlnx_dp_avbufm_read(void *opaque, hwaddr offset,
-                                    unsigned size)
-{
-    XlnxDPState *s = XLNX_DP(opaque);
-
-    offset = offset >> 2;
-    return s->avbufm_registers[offset];
-}
-
-static const MemoryRegionOps avbufm_ops = {
-    .read = xlnx_dp_avbufm_read,
-    .write = xlnx_dp_avbufm_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-    .impl = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-};
-
-/*
- * This is a global alpha blending using pixman.
- * Both graphic and video planes are multiplied with the global alpha
- * coefficient and added.
- */
-static inline void xlnx_dp_blend_surface(XlnxDPState *s)
-{
-    pixman_fixed_t alpha1[] = { pixman_double_to_fixed(1),
-                                pixman_double_to_fixed(1),
-                                pixman_double_to_fixed(1.0) };
-    pixman_fixed_t alpha2[] = { pixman_double_to_fixed(1),
-                                pixman_double_to_fixed(1),
-                                pixman_double_to_fixed(1.0) };
-
-    if ((surface_width(s->g_plane.surface)
-         != surface_width(s->v_plane.surface)) ||
-        (surface_height(s->g_plane.surface)
-         != surface_height(s->v_plane.surface))) {
-        return;
-    }
-
-    alpha1[2] = pixman_double_to_fixed((double)(xlnx_dp_global_alpha_value(s))
-                                       / 256.0);
-    alpha2[2] = pixman_double_to_fixed((255.0
-                                    - (double)xlnx_dp_global_alpha_value(s))
-                                       / 256.0);
-
-    pixman_image_set_filter(s->g_plane.surface->image,
-                            PIXMAN_FILTER_CONVOLUTION, alpha1, 3);
-    pixman_image_composite(PIXMAN_OP_SRC, s->g_plane.surface->image, 0,
-                           s->bout_plane.surface->image, 0, 0, 0, 0, 0, 0,
-                           surface_width(s->g_plane.surface),
-                           surface_height(s->g_plane.surface));
-    pixman_image_set_filter(s->v_plane.surface->image,
-                            PIXMAN_FILTER_CONVOLUTION, alpha2, 3);
-    pixman_image_composite(PIXMAN_OP_ADD, s->v_plane.surface->image, 0,
-                           s->bout_plane.surface->image, 0, 0, 0, 0, 0, 0,
-                           surface_width(s->g_plane.surface),
-                           surface_height(s->g_plane.surface));
-}
-
-static void xlnx_dp_update_display(void *opaque)
-{
-    XlnxDPState *s = XLNX_DP(opaque);
-
-    if ((s->core_registers[DP_TRANSMITTER_ENABLE] & 0x01) == 0) {
-        return;
-    }
-
-    s->core_registers[DP_INT_STATUS] |= (1 << 13);
-    xlnx_dp_update_irq(s);
-
-    xlnx_dpdma_trigger_vsync_irq(s->dpdma);
-
-    /*
-     * Trigger the DMA channel.
-     */
-    if (!xlnx_dpdma_start_operation(s->dpdma, 3, false)) {
-        /*
-         * An error occured don't do anything with the data..
-         * Trigger an underflow interrupt.
-         */
-        s->core_registers[DP_INT_STATUS] |= (1 << 21);
-        xlnx_dp_update_irq(s);
-        return;
-    }
-
-    if (xlnx_dp_global_alpha_enabled(s)) {
-        if (!xlnx_dpdma_start_operation(s->dpdma, 0, false)) {
-            s->core_registers[DP_INT_STATUS] |= (1 << 21);
-            xlnx_dp_update_irq(s);
-            return;
-        }
-        xlnx_dp_blend_surface(s);
-    }
-
-    /*
-     * XXX: We might want to update only what changed.
-     */
-    dpy_gfx_update(s->console, 0, 0, surface_width(s->g_plane.surface),
-                                     surface_height(s->g_plane.surface));
-}
-
-static const GraphicHwOps xlnx_dp_gfx_ops = {
-    .gfx_update  = xlnx_dp_update_display,
-};
-
-static void xlnx_dp_init(Object *obj)
-{
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
-    XlnxDPState *s = XLNX_DP(obj);
-
-    memory_region_init(&s->container, obj, TYPE_XLNX_DP, 0xC050);
-
-    memory_region_init_io(&s->core_iomem, obj, &dp_ops, s, TYPE_XLNX_DP
-                          ".core", 0x3AF);
-    memory_region_add_subregion(&s->container, 0x0000, &s->core_iomem);
-
-    memory_region_init_io(&s->vblend_iomem, obj, &vblend_ops, s, TYPE_XLNX_DP
-                          ".v_blend", 0x1DF);
-    memory_region_add_subregion(&s->container, 0xA000, &s->vblend_iomem);
-
-    memory_region_init_io(&s->avbufm_iomem, obj, &avbufm_ops, s, TYPE_XLNX_DP
-                          ".av_buffer_manager", 0x238);
-    memory_region_add_subregion(&s->container, 0xB000, &s->avbufm_iomem);
-
-    memory_region_init_io(&s->audio_iomem, obj, &audio_ops, s, TYPE_XLNX_DP
-                          ".audio", sizeof(s->audio_registers));
-    memory_region_add_subregion(&s->container, 0xC000, &s->audio_iomem);
-
-    sysbus_init_mmio(sbd, &s->container);
-    sysbus_init_irq(sbd, &s->irq);
-
-    object_property_add_link(obj, "dpdma", TYPE_XLNX_DPDMA,
-                             (Object **) &s->dpdma,
-                             xlnx_dp_set_dpdma,
-                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
-                             &error_abort);
-
-    /*
-     * Initialize AUX Bus.
-     */
-    s->aux_bus = aux_init_bus(DEVICE(obj), "aux");
-
-    /*
-     * Initialize DPCD and EDID..
-     */
-    s->dpcd = DPCD(aux_create_slave(s->aux_bus, "dpcd", 0x00000));
-    s->edid = I2CDDC(qdev_create(BUS(aux_get_i2c_bus(s->aux_bus)), "i2c-ddc"));
-    i2c_set_slave_address(I2C_SLAVE(s->edid), 0x50);
-
-    fifo8_create(&s->rx_fifo, 16);
-    fifo8_create(&s->tx_fifo, 16);
-}
-
-static void xlnx_dp_realize(DeviceState *dev, Error **errp)
-{
-    XlnxDPState *s = XLNX_DP(dev);
-    DisplaySurface *surface;
-    struct audsettings as;
-
-    s->console = graphic_console_init(dev, 0, &xlnx_dp_gfx_ops, s);
-    surface = qemu_console_surface(s->console);
-    xlnx_dpdma_set_host_data_location(s->dpdma, DP_GRAPHIC_DMA_CHANNEL,
-                                      surface_data(surface));
-
-    as.freq = 44100;
-    as.nchannels = 2;
-    as.fmt = AUD_FMT_S16;
-    as.endianness = 0;
-
-    AUD_register_card("xlnx_dp.audio", &s->aud_card);
-
-    s->amixer_output_stream = AUD_open_out(&s->aud_card,
-                                           s->amixer_output_stream,
-                                           "xlnx_dp.audio.out",
-                                           s,
-                                           xlnx_dp_audio_callback,
-                                           &as);
-    AUD_set_volume_out(s->amixer_output_stream, 0, 255, 255);
-    xlnx_dp_audio_activate(s);
-}
-
-static void xlnx_dp_reset(DeviceState *dev)
-{
-    XlnxDPState *s = XLNX_DP(dev);
-
-    memset(s->core_registers, 0, sizeof(s->core_registers));
-    s->core_registers[DP_VERSION_REGISTER] = 0x04010000;
-    s->core_registers[DP_CORE_ID] = 0x01020000;
-    s->core_registers[DP_REPLY_STATUS] = 0x00000010;
-    s->core_registers[DP_MSA_TRANSFER_UNIT_SIZE] = 0x00000040;
-    s->core_registers[DP_INIT_WAIT] = 0x00000020;
-    s->core_registers[DP_PHY_RESET] = 0x00010003;
-    s->core_registers[DP_INT_MASK] = 0xFFFFF03F;
-    s->core_registers[DP_PHY_STATUS] = 0x00000043;
-    s->core_registers[DP_INTERRUPT_SIGNAL_STATE] = 0x00000001;
-
-    s->vblend_registers[V_BLEND_RGB2YCBCR_COEFF(0)] = 0x00001000;
-    s->vblend_registers[V_BLEND_RGB2YCBCR_COEFF(4)] = 0x00001000;
-    s->vblend_registers[V_BLEND_RGB2YCBCR_COEFF(8)] = 0x00001000;
-    s->vblend_registers[V_BLEND_IN1CSC_COEFF(0)] = 0x00001000;
-    s->vblend_registers[V_BLEND_IN1CSC_COEFF(4)] = 0x00001000;
-    s->vblend_registers[V_BLEND_IN1CSC_COEFF(8)] = 0x00001000;
-    s->vblend_registers[V_BLEND_IN2CSC_COEFF(0)] = 0x00001000;
-    s->vblend_registers[V_BLEND_IN2CSC_COEFF(4)] = 0x00001000;
-    s->vblend_registers[V_BLEND_IN2CSC_COEFF(8)] = 0x00001000;
-
-    s->avbufm_registers[AV_BUF_NON_LIVE_LATENCY] = 0x00000180;
-    s->avbufm_registers[AV_BUF_OUTPUT_AUDIO_VIDEO_SELECT] = 0x00000008;
-    s->avbufm_registers[AV_BUF_DITHER_CONFIG_MAX] = 0x00000FFF;
-    s->avbufm_registers[AV_BUF_GRAPHICS_COMP_SCALE_FACTOR(0)] = 0x00010101;
-    s->avbufm_registers[AV_BUF_GRAPHICS_COMP_SCALE_FACTOR(1)] = 0x00010101;
-    s->avbufm_registers[AV_BUF_GRAPHICS_COMP_SCALE_FACTOR(2)] = 0x00010101;
-    s->avbufm_registers[AV_BUF_VIDEO_COMP_SCALE_FACTOR(0)] = 0x00010101;
-    s->avbufm_registers[AV_BUF_VIDEO_COMP_SCALE_FACTOR(1)] = 0x00010101;
-    s->avbufm_registers[AV_BUF_VIDEO_COMP_SCALE_FACTOR(2)] = 0x00010101;
-    s->avbufm_registers[AV_BUF_LIVE_VIDEO_COMP_SF(0)] = 0x00010101;
-    s->avbufm_registers[AV_BUF_LIVE_VIDEO_COMP_SF(1)] = 0x00010101;
-    s->avbufm_registers[AV_BUF_LIVE_VIDEO_COMP_SF(2)] = 0x00010101;
-    s->avbufm_registers[AV_BUF_LIVE_GFX_COMP_SF(0)] = 0x00010101;
-    s->avbufm_registers[AV_BUF_LIVE_GFX_COMP_SF(1)] = 0x00010101;
-    s->avbufm_registers[AV_BUF_LIVE_GFX_COMP_SF(2)] = 0x00010101;
-
-    memset(s->audio_registers, 0, sizeof(s->audio_registers));
-    s->byte_left = 0;
-
-    xlnx_dp_aux_clear_rx_fifo(s);
-    xlnx_dp_change_graphic_fmt(s);
-    xlnx_dp_update_irq(s);
-}
-
-static void xlnx_dp_class_init(ObjectClass *oc, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(oc);
-
-    dc->realize = xlnx_dp_realize;
-    dc->vmsd = &vmstate_dp;
-    dc->reset = xlnx_dp_reset;
-}
-
-static const TypeInfo xlnx_dp_info = {
-    .name          = TYPE_XLNX_DP,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(XlnxDPState),
-    .instance_init = xlnx_dp_init,
-    .class_init    = xlnx_dp_class_init,
-};
-
-static void xlnx_dp_register_types(void)
-{
-    type_register_static(&xlnx_dp_info);
-}
-
-type_init(xlnx_dp_register_types)
index 087c8e6..a1abbcf 100644 (file)
@@ -5,11 +5,9 @@ common-obj-$(CONFIG_PL330) += pl330.o
 common-obj-$(CONFIG_I82374) += i82374.o
 common-obj-$(CONFIG_I8257) += i8257.o
 common-obj-$(CONFIG_XILINX_AXI) += xilinx_axidma.o
-common-obj-$(CONFIG_ZYNQ_DEVCFG) += xlnx-zynq-devcfg.o
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_dma.o
 common-obj-$(CONFIG_STP2000) += sparc32_dma.o
 common-obj-$(CONFIG_SUN4M) += sun4m_iommu.o
-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx_dpdma.o
 
 obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
 obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
index 5d144a2..5421175 100644 (file)
@@ -6,7 +6,6 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/dma/bcm2835_dma.h"
-#include "qemu/log.h"
 
 /* DMA CS Control and Status bits */
 #define BCM2708_DMA_ACTIVE      (1 << 0)
index 3bed5c3..9318108 100644 (file)
@@ -10,7 +10,6 @@
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
-#include "qemu/log.h"
 
 #define PL080_MAX_CHANNELS 8
 #define PL080_CONF_E    0x1
index c0bd9fe..ea89ecb 100644 (file)
@@ -19,7 +19,6 @@
 #include "qapi/error.h"
 #include "qemu/timer.h"
 #include "sysemu/dma.h"
-#include "qemu/log.h"
 
 #ifndef PL330_ERR_DEBUG
 #define PL330_ERR_DEBUG 0
index 634a432..2306abc 100644 (file)
@@ -12,7 +12,6 @@
 #include "hw/hw.h"
 #include "hw/arm/pxa.h"
 #include "hw/sysbus.h"
-#include "qapi/error.h"
 
 #define PXA255_DMA_NUM_CHANNELS 16
 #define PXA27X_DMA_NUM_CHANNELS 32
@@ -451,36 +450,31 @@ static void pxa2xx_dma_request(void *opaque, int req_num, int on)
     }
 }
 
-static void pxa2xx_dma_init(Object *obj)
-{
-    DeviceState *dev = DEVICE(obj);
-    PXA2xxDMAState *s = PXA2XX_DMA(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
-
-    memset(s->req, 0, sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS);
-
-    qdev_init_gpio_in(dev, pxa2xx_dma_request, PXA2XX_DMA_NUM_REQUESTS);
-
-    memory_region_init_io(&s->iomem, obj, &pxa2xx_dma_ops, s,
-                          "pxa2xx.dma", 0x00010000);
-    sysbus_init_mmio(sbd, &s->iomem);
-    sysbus_init_irq(sbd, &s->irq);
-}
-
-static void pxa2xx_dma_realize(DeviceState *dev, Error **errp)
+static int pxa2xx_dma_init(SysBusDevice *sbd)
 {
+    DeviceState *dev = DEVICE(sbd);
     PXA2xxDMAState *s = PXA2XX_DMA(dev);
     int i;
 
     if (s->channels <= 0) {
-        error_setg(errp, "channels value invalid");
-        return;
+        return -1;
     }
 
     s->chan = g_new0(PXA2xxDMAChannel, s->channels);
 
     for (i = 0; i < s->channels; i ++)
         s->chan[i].state = DCSR_STOPINTR;
+
+    memset(s->req, 0, sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS);
+
+    qdev_init_gpio_in(dev, pxa2xx_dma_request, PXA2XX_DMA_NUM_REQUESTS);
+
+    memory_region_init_io(&s->iomem, OBJECT(s), &pxa2xx_dma_ops, s,
+                          "pxa2xx.dma", 0x00010000);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(sbd, &s->irq);
+
+    return 0;
 }
 
 DeviceState *pxa27x_dma_init(hwaddr base, qemu_irq irq)
@@ -559,18 +553,18 @@ static Property pxa2xx_dma_properties[] = {
 static void pxa2xx_dma_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = pxa2xx_dma_init;
     dc->desc = "PXA2xx DMA controller";
     dc->vmsd = &vmstate_pxa2xx_dma;
     dc->props = pxa2xx_dma_properties;
-    dc->realize = pxa2xx_dma_realize;
 }
 
 static const TypeInfo pxa2xx_dma_info = {
     .name          = TYPE_PXA2XX_DMA,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(PXA2xxDMAState),
-    .instance_init = pxa2xx_dma_init,
     .class_init    = pxa2xx_dma_class_init,
 };
 
index 2f2576f..a06c235 100644 (file)
@@ -27,7 +27,6 @@
 #include "hw/mips/mips.h"
 #include "hw/sysbus.h"
 #include "qemu/timer.h"
-#include "qemu/log.h"
 #include "exec/address-spaces.h"
 #include "trace.h"
 
diff --git a/hw/dma/trace-events b/hw/dma/trace-events
deleted file mode 100644 (file)
index 22878df..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/dma/rc4030.c
-jazzio_read(uint64_t addr, uint32_t ret) "read reg[0x%"PRIx64"] = 0x%x"
-jazzio_write(uint64_t addr, uint32_t val) "write reg[0x%"PRIx64"] = 0x%x"
-rc4030_read(uint64_t addr, uint32_t ret) "read reg[0x%"PRIx64"] = 0x%x"
-rc4030_write(uint64_t addr, uint32_t val) "write reg[0x%"PRIx64"] = 0x%x"
-
-# hw/dma/sparc32_dma.c
-ledma_memory_read(uint64_t addr) "DMA read addr 0x%"PRIx64
-ledma_memory_write(uint64_t addr) "DMA write addr 0x%"PRIx64
-sparc32_dma_set_irq_raise(void) "Raise IRQ"
-sparc32_dma_set_irq_lower(void) "Lower IRQ"
-espdma_memory_read(uint32_t addr) "DMA read addr 0x%08x"
-espdma_memory_write(uint32_t addr) "DMA write addr 0x%08x"
-sparc32_dma_mem_readl(uint64_t addr, uint32_t ret) "read dmareg %"PRIx64": 0x%08x"
-sparc32_dma_mem_writel(uint64_t addr, uint32_t old, uint32_t val) "write dmareg %"PRIx64": 0x%08x -> 0x%08x"
-sparc32_dma_enable_raise(void) "Raise DMA enable"
-sparc32_dma_enable_lower(void) "Lower DMA enable"
-
-# hw/dma/sun4m_iommu.c
-sun4m_iommu_mem_readl(uint64_t addr, uint32_t ret) "read reg[%"PRIx64"] = %x"
-sun4m_iommu_mem_writel(uint64_t addr, uint32_t val) "write reg[%"PRIx64"] = %x"
-sun4m_iommu_mem_writel_ctrl(uint64_t iostart) "iostart = %"PRIx64
-sun4m_iommu_mem_writel_tlbflush(uint32_t val) "tlb flush %x"
-sun4m_iommu_mem_writel_pgflush(uint32_t val) "page flush %x"
-sun4m_iommu_page_get_flags(uint64_t pa, uint64_t iopte, uint32_t ret) "get flags addr %"PRIx64" => pte %"PRIx64", *pte = %x"
-sun4m_iommu_translate_pa(uint64_t addr, uint64_t pa, uint32_t iopte) "xlate dva %"PRIx64" => pa %"PRIx64" iopte = %x"
-sun4m_iommu_bad_addr(uint64_t addr) "bad addr %"PRIx64
-
-# hw/dma/i8257.c
-i8257_unregistered_dma(int nchan, int dma_pos, int dma_len) "unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d"
diff --git a/hw/dma/xlnx-zynq-devcfg.c b/hw/dma/xlnx-zynq-devcfg.c
deleted file mode 100644 (file)
index 3b10523..0000000
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * QEMU model of the Xilinx Zynq Devcfg Interface
- *
- * (C) 2011 PetaLogix Pty Ltd
- * (C) 2014 Xilinx Inc.
- * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "hw/dma/xlnx-zynq-devcfg.h"
-#include "qemu/bitops.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/dma.h"
-#include "qemu/log.h"
-
-#define FREQ_HZ 900000000
-
-#define BTT_MAX 0x400
-
-#ifndef XLNX_ZYNQ_DEVCFG_ERR_DEBUG
-#define XLNX_ZYNQ_DEVCFG_ERR_DEBUG 0
-#endif
-
-#define DB_PRINT(fmt, args...) do { \
-    if (XLNX_ZYNQ_DEVCFG_ERR_DEBUG) { \
-        qemu_log("%s: " fmt, __func__, ## args); \
-    } \
-} while (0);
-
-REG32(CTRL, 0x00)
-    FIELD(CTRL,     FORCE_RST,          31,  1) /* Not supported, wr ignored */
-    FIELD(CTRL,     PCAP_PR,            27,  1) /* Forced to 0 on bad unlock */
-    FIELD(CTRL,     PCAP_MODE,          26,  1)
-    FIELD(CTRL,     MULTIBOOT_EN,       24,  1)
-    FIELD(CTRL,     USER_MODE,          15,  1)
-    FIELD(CTRL,     PCFG_AES_FUSE,      12,  1)
-    FIELD(CTRL,     PCFG_AES_EN,         9,  3)
-    FIELD(CTRL,     SEU_EN,              8,  1)
-    FIELD(CTRL,     SEC_EN,              7,  1)
-    FIELD(CTRL,     SPNIDEN,             6,  1)
-    FIELD(CTRL,     SPIDEN,              5,  1)
-    FIELD(CTRL,     NIDEN,               4,  1)
-    FIELD(CTRL,     DBGEN,               3,  1)
-    FIELD(CTRL,     DAP_EN,              0,  3)
-
-REG32(LOCK, 0x04)
-#define AES_FUSE_LOCK        4
-#define AES_EN_LOCK          3
-#define SEU_LOCK             2
-#define SEC_LOCK             1
-#define DBG_LOCK             0
-
-/* mapping bits in R_LOCK to what they lock in R_CTRL */
-static const uint32_t lock_ctrl_map[] = {
-    [AES_FUSE_LOCK] = R_CTRL_PCFG_AES_FUSE_MASK,
-    [AES_EN_LOCK]   = R_CTRL_PCFG_AES_EN_MASK,
-    [SEU_LOCK]      = R_CTRL_SEU_EN_MASK,
-    [SEC_LOCK]      = R_CTRL_SEC_EN_MASK,
-    [DBG_LOCK]      = R_CTRL_SPNIDEN_MASK | R_CTRL_SPIDEN_MASK |
-                      R_CTRL_NIDEN_MASK   | R_CTRL_DBGEN_MASK  |
-                      R_CTRL_DAP_EN_MASK,
-};
-
-REG32(CFG, 0x08)
-    FIELD(CFG,      RFIFO_TH,           10,  2)
-    FIELD(CFG,      WFIFO_TH,            8,  2)
-    FIELD(CFG,      RCLK_EDGE,           7,  1)
-    FIELD(CFG,      WCLK_EDGE,           6,  1)
-    FIELD(CFG,      DISABLE_SRC_INC,     5,  1)
-    FIELD(CFG,      DISABLE_DST_INC,     4,  1)
-#define R_CFG_RESET 0x50B
-
-REG32(INT_STS, 0x0C)
-    FIELD(INT_STS,  PSS_GTS_USR_B,      31,  1)
-    FIELD(INT_STS,  PSS_FST_CFG_B,      30,  1)
-    FIELD(INT_STS,  PSS_CFG_RESET_B,    27,  1)
-    FIELD(INT_STS,  RX_FIFO_OV,         18,  1)
-    FIELD(INT_STS,  WR_FIFO_LVL,        17,  1)
-    FIELD(INT_STS,  RD_FIFO_LVL,        16,  1)
-    FIELD(INT_STS,  DMA_CMD_ERR,        15,  1)
-    FIELD(INT_STS,  DMA_Q_OV,           14,  1)
-    FIELD(INT_STS,  DMA_DONE,           13,  1)
-    FIELD(INT_STS,  DMA_P_DONE,         12,  1)
-    FIELD(INT_STS,  P2D_LEN_ERR,        11,  1)
-    FIELD(INT_STS,  PCFG_DONE,           2,  1)
-#define R_INT_STS_RSVD       ((0x7 << 24) | (0x1 << 19) | (0xF < 7))
-
-REG32(INT_MASK, 0x10)
-
-REG32(STATUS, 0x14)
-    FIELD(STATUS,   DMA_CMD_Q_F,        31,  1)
-    FIELD(STATUS,   DMA_CMD_Q_E,        30,  1)
-    FIELD(STATUS,   DMA_DONE_CNT,       28,  2)
-    FIELD(STATUS,   RX_FIFO_LVL,        20,  5)
-    FIELD(STATUS,   TX_FIFO_LVL,        12,  7)
-    FIELD(STATUS,   PSS_GTS_USR_B,      11,  1)
-    FIELD(STATUS,   PSS_FST_CFG_B,      10,  1)
-    FIELD(STATUS,   PSS_CFG_RESET_B,     5,  1)
-
-REG32(DMA_SRC_ADDR, 0x18)
-REG32(DMA_DST_ADDR, 0x1C)
-REG32(DMA_SRC_LEN, 0x20)
-REG32(DMA_DST_LEN, 0x24)
-REG32(ROM_SHADOW, 0x28)
-REG32(SW_ID, 0x30)
-REG32(UNLOCK, 0x34)
-
-#define R_UNLOCK_MAGIC 0x757BDF0D
-
-REG32(MCTRL, 0x80)
-    FIELD(MCTRL,    PS_VERSION,         28,  4)
-    FIELD(MCTRL,    PCFG_POR_B,          8,  1)
-    FIELD(MCTRL,    INT_PCAP_LPBK,       4,  1)
-    FIELD(MCTRL,    QEMU,                3,  1)
-
-static void xlnx_zynq_devcfg_update_ixr(XlnxZynqDevcfg *s)
-{
-    qemu_set_irq(s->irq, ~s->regs[R_INT_MASK] & s->regs[R_INT_STS]);
-}
-
-static void xlnx_zynq_devcfg_reset(DeviceState *dev)
-{
-    XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(dev);
-    int i;
-
-    for (i = 0; i < XLNX_ZYNQ_DEVCFG_R_MAX; ++i) {
-        register_reset(&s->regs_info[i]);
-    }
-}
-
-static void xlnx_zynq_devcfg_dma_go(XlnxZynqDevcfg *s)
-{
-    do {
-        uint8_t buf[BTT_MAX];
-        XlnxZynqDevcfgDMACmd *dmah = s->dma_cmd_fifo;
-        uint32_t btt = BTT_MAX;
-        bool loopback = s->regs[R_MCTRL] & R_MCTRL_INT_PCAP_LPBK_MASK;
-
-        btt = MIN(btt, dmah->src_len);
-        if (loopback) {
-            btt = MIN(btt, dmah->dest_len);
-        }
-        DB_PRINT("reading %x bytes from %x\n", btt, dmah->src_addr);
-        dma_memory_read(&address_space_memory, dmah->src_addr, buf, btt);
-        dmah->src_len -= btt;
-        dmah->src_addr += btt;
-        if (loopback && (dmah->src_len || dmah->dest_len)) {
-            DB_PRINT("writing %x bytes from %x\n", btt, dmah->dest_addr);
-            dma_memory_write(&address_space_memory, dmah->dest_addr, buf, btt);
-            dmah->dest_len -= btt;
-            dmah->dest_addr += btt;
-        }
-        if (!dmah->src_len && !dmah->dest_len) {
-            DB_PRINT("dma operation finished\n");
-            s->regs[R_INT_STS] |= R_INT_STS_DMA_DONE_MASK |
-                                  R_INT_STS_DMA_P_DONE_MASK;
-            s->dma_cmd_fifo_num--;
-            memmove(s->dma_cmd_fifo, &s->dma_cmd_fifo[1],
-                    sizeof(s->dma_cmd_fifo) - sizeof(s->dma_cmd_fifo[0]));
-        }
-        xlnx_zynq_devcfg_update_ixr(s);
-    } while (s->dma_cmd_fifo_num);
-}
-
-static void r_ixr_post_write(RegisterInfo *reg, uint64_t val)
-{
-    XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
-
-    xlnx_zynq_devcfg_update_ixr(s);
-}
-
-static uint64_t r_ctrl_pre_write(RegisterInfo *reg, uint64_t val)
-{
-    XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(lock_ctrl_map); ++i) {
-        if (s->regs[R_LOCK] & 1 << i) {
-            val &= ~lock_ctrl_map[i];
-            val |= lock_ctrl_map[i] & s->regs[R_CTRL];
-        }
-    }
-    return val;
-}
-
-static void r_ctrl_post_write(RegisterInfo *reg, uint64_t val)
-{
-    const char *device_prefix = object_get_typename(OBJECT(reg->opaque));
-    uint32_t aes_en = FIELD_EX32(val, CTRL, PCFG_AES_EN);
-
-    if (aes_en != 0 && aes_en != 7) {
-        qemu_log_mask(LOG_UNIMP, "%s: warning, aes-en bits inconsistent,"
-                      "unimplemented security reset should happen!\n",
-                      device_prefix);
-    }
-}
-
-static void r_unlock_post_write(RegisterInfo *reg, uint64_t val)
-{
-    XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
-    const char *device_prefix = object_get_typename(OBJECT(s));
-
-    if (val == R_UNLOCK_MAGIC) {
-        DB_PRINT("successful unlock\n");
-        s->regs[R_CTRL] |= R_CTRL_PCAP_PR_MASK;
-        s->regs[R_CTRL] |= R_CTRL_PCFG_AES_EN_MASK;
-        memory_region_set_enabled(&s->iomem, true);
-    } else { /* bad unlock attempt */
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: failed unlock\n", device_prefix);
-        s->regs[R_CTRL] &= ~R_CTRL_PCAP_PR_MASK;
-        s->regs[R_CTRL] &= ~R_CTRL_PCFG_AES_EN_MASK;
-        /* core becomes inaccessible */
-        memory_region_set_enabled(&s->iomem, false);
-    }
-}
-
-static uint64_t r_lock_pre_write(RegisterInfo *reg, uint64_t val)
-{
-    XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
-
-    /* once bits are locked they stay locked */
-    return s->regs[R_LOCK] | val;
-}
-
-static void r_dma_dst_len_post_write(RegisterInfo *reg, uint64_t val)
-{
-    XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
-
-    s->dma_cmd_fifo[s->dma_cmd_fifo_num] = (XlnxZynqDevcfgDMACmd) {
-            .src_addr = s->regs[R_DMA_SRC_ADDR] & ~0x3UL,
-            .dest_addr = s->regs[R_DMA_DST_ADDR] & ~0x3UL,
-            .src_len = s->regs[R_DMA_SRC_LEN] << 2,
-            .dest_len = s->regs[R_DMA_DST_LEN] << 2,
-    };
-    s->dma_cmd_fifo_num++;
-    DB_PRINT("dma transfer started; %d total transfers pending\n",
-             s->dma_cmd_fifo_num);
-    xlnx_zynq_devcfg_dma_go(s);
-}
-
-static const RegisterAccessInfo xlnx_zynq_devcfg_regs_info[] = {
-    {   .name = "CTRL",                 .addr = A_CTRL,
-        .reset = R_CTRL_PCAP_PR_MASK | R_CTRL_PCAP_MODE_MASK | 0x3 << 13,
-        .rsvd = 0x1 << 28 | 0x3ff << 13 | 0x3 << 13,
-        .pre_write = r_ctrl_pre_write,
-        .post_write = r_ctrl_post_write,
-    },
-    {   .name = "LOCK",                 .addr = A_LOCK,
-        .rsvd = MAKE_64BIT_MASK(5, 64 - 5),
-        .pre_write = r_lock_pre_write,
-    },
-    {   .name = "CFG",                  .addr = A_CFG,
-        .reset = R_CFG_RESET,
-        .rsvd = 0xfffff00f,
-    },
-    {   .name = "INT_STS",              .addr = A_INT_STS,
-        .w1c = ~R_INT_STS_RSVD,
-        .reset = R_INT_STS_PSS_GTS_USR_B_MASK   |
-                 R_INT_STS_PSS_CFG_RESET_B_MASK |
-                 R_INT_STS_WR_FIFO_LVL_MASK,
-        .rsvd = R_INT_STS_RSVD,
-        .post_write = r_ixr_post_write,
-    },
-    {   .name = "INT_MASK",            .addr = A_INT_MASK,
-        .reset = ~0,
-        .rsvd = R_INT_STS_RSVD,
-        .post_write = r_ixr_post_write,
-    },
-    {   .name = "STATUS",               .addr = A_STATUS,
-        .reset = R_STATUS_DMA_CMD_Q_E_MASK      |
-                 R_STATUS_PSS_GTS_USR_B_MASK    |
-                 R_STATUS_PSS_CFG_RESET_B_MASK,
-        .ro = ~0,
-    },
-    {   .name = "DMA_SRC_ADDR",         .addr = A_DMA_SRC_ADDR, },
-    {   .name = "DMA_DST_ADDR",         .addr = A_DMA_DST_ADDR, },
-    {   .name = "DMA_SRC_LEN",          .addr = A_DMA_SRC_LEN,
-        .ro = MAKE_64BIT_MASK(27, 64 - 27) },
-    {   .name = "DMA_DST_LEN",          .addr = A_DMA_DST_LEN,
-        .ro = MAKE_64BIT_MASK(27, 64 - 27),
-        .post_write = r_dma_dst_len_post_write,
-    },
-    {   .name = "ROM_SHADOW",           .addr = A_ROM_SHADOW,
-        .rsvd = ~0ull,
-    },
-    {   .name = "SW_ID",                .addr = A_SW_ID, },
-    {   .name = "UNLOCK",               .addr = A_UNLOCK,
-        .post_write = r_unlock_post_write,
-    },
-    {   .name = "MCTRL",                .addr = R_MCTRL * 4,
-       /* Silicon 3.0 for version field, the mysterious reserved bit 23
-        * and QEMU platform identifier.
-        */
-       .reset = 0x2 << R_MCTRL_PS_VERSION_SHIFT | 1 << 23 | R_MCTRL_QEMU_MASK,
-       .ro = ~R_MCTRL_INT_PCAP_LPBK_MASK,
-       .rsvd = 0x00f00303,
-    },
-};
-
-static const MemoryRegionOps xlnx_zynq_devcfg_reg_ops = {
-    .read = register_read_memory,
-    .write = register_write_memory,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    }
-};
-
-static const VMStateDescription vmstate_xlnx_zynq_devcfg_dma_cmd = {
-    .name = "xlnx_zynq_devcfg_dma_cmd",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT32(src_addr, XlnxZynqDevcfgDMACmd),
-        VMSTATE_UINT32(dest_addr, XlnxZynqDevcfgDMACmd),
-        VMSTATE_UINT32(src_len, XlnxZynqDevcfgDMACmd),
-        VMSTATE_UINT32(dest_len, XlnxZynqDevcfgDMACmd),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static const VMStateDescription vmstate_xlnx_zynq_devcfg = {
-    .name = "xlnx_zynq_devcfg",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_STRUCT_ARRAY(dma_cmd_fifo, XlnxZynqDevcfg,
-                             XLNX_ZYNQ_DEVCFG_DMA_CMD_FIFO_LEN, 0,
-                             vmstate_xlnx_zynq_devcfg_dma_cmd,
-                             XlnxZynqDevcfgDMACmd),
-        VMSTATE_UINT8(dma_cmd_fifo_num, XlnxZynqDevcfg),
-        VMSTATE_UINT32_ARRAY(regs, XlnxZynqDevcfg, XLNX_ZYNQ_DEVCFG_R_MAX),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static void xlnx_zynq_devcfg_init(Object *obj)
-{
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
-    XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(obj);
-    RegisterInfoArray *reg_array;
-
-    sysbus_init_irq(sbd, &s->irq);
-
-    memory_region_init(&s->iomem, obj, "devcfg", XLNX_ZYNQ_DEVCFG_R_MAX * 4);
-    reg_array =
-        register_init_block32(DEVICE(obj), xlnx_zynq_devcfg_regs_info,
-                              ARRAY_SIZE(xlnx_zynq_devcfg_regs_info),
-                              s->regs_info, s->regs,
-                              &xlnx_zynq_devcfg_reg_ops,
-                              XLNX_ZYNQ_DEVCFG_ERR_DEBUG,
-                              XLNX_ZYNQ_DEVCFG_R_MAX);
-    memory_region_add_subregion(&s->iomem,
-                                A_CTRL,
-                                &reg_array->mem);
-
-    sysbus_init_mmio(sbd, &s->iomem);
-}
-
-static void xlnx_zynq_devcfg_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-
-    dc->reset = xlnx_zynq_devcfg_reset;
-    dc->vmsd = &vmstate_xlnx_zynq_devcfg;
-}
-
-static const TypeInfo xlnx_zynq_devcfg_info = {
-    .name           = TYPE_XLNX_ZYNQ_DEVCFG,
-    .parent         = TYPE_SYS_BUS_DEVICE,
-    .instance_size  = sizeof(XlnxZynqDevcfg),
-    .instance_init  = xlnx_zynq_devcfg_init,
-    .class_init     = xlnx_zynq_devcfg_class_init,
-};
-
-static void xlnx_zynq_devcfg_register_types(void)
-{
-    type_register_static(&xlnx_zynq_devcfg_info);
-}
-
-type_init(xlnx_zynq_devcfg_register_types)
diff --git a/hw/dma/xlnx_dpdma.c b/hw/dma/xlnx_dpdma.c
deleted file mode 100644 (file)
index 8ceb21d..0000000
+++ /dev/null
@@ -1,786 +0,0 @@
-/*
- * xlnx_dpdma.c
- *
- *  Copyright (C) 2015 : GreenSocs Ltd
- *      http://www.greensocs.com/ , email: info@greensocs.com
- *
- *  Developed by :
- *  Frederic Konrad   <fred.konrad@greensocs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "hw/dma/xlnx_dpdma.h"
-
-#ifndef DEBUG_DPDMA
-#define DEBUG_DPDMA 0
-#endif
-
-#define DPRINTF(fmt, ...) do {                                                 \
-    if (DEBUG_DPDMA) {                                                         \
-        qemu_log("xlnx_dpdma: " fmt , ## __VA_ARGS__);                         \
-    }                                                                          \
-} while (0);
-
-/*
- * Registers offset for DPDMA.
- */
-#define DPDMA_ERR_CTRL                        (0x0000)
-#define DPDMA_ISR                             (0x0004 >> 2)
-#define DPDMA_IMR                             (0x0008 >> 2)
-#define DPDMA_IEN                             (0x000C >> 2)
-#define DPDMA_IDS                             (0x0010 >> 2)
-#define DPDMA_EISR                            (0x0014 >> 2)
-#define DPDMA_EIMR                            (0x0018 >> 2)
-#define DPDMA_EIEN                            (0x001C >> 2)
-#define DPDMA_EIDS                            (0x0020 >> 2)
-#define DPDMA_CNTL                            (0x0100 >> 2)
-
-#define DPDMA_GBL                             (0x0104 >> 2)
-#define DPDMA_GBL_TRG_CH(n)                   (1 << n)
-#define DPDMA_GBL_RTRG_CH(n)                  (1 << 6 << n)
-
-#define DPDMA_ALC0_CNTL                       (0x0108 >> 2)
-#define DPDMA_ALC0_STATUS                     (0x010C >> 2)
-#define DPDMA_ALC0_MAX                        (0x0110 >> 2)
-#define DPDMA_ALC0_MIN                        (0x0114 >> 2)
-#define DPDMA_ALC0_ACC                        (0x0118 >> 2)
-#define DPDMA_ALC0_ACC_TRAN                   (0x011C >> 2)
-#define DPDMA_ALC1_CNTL                       (0x0120 >> 2)
-#define DPDMA_ALC1_STATUS                     (0x0124 >> 2)
-#define DPDMA_ALC1_MAX                        (0x0128 >> 2)
-#define DPDMA_ALC1_MIN                        (0x012C >> 2)
-#define DPDMA_ALC1_ACC                        (0x0130 >> 2)
-#define DPDMA_ALC1_ACC_TRAN                   (0x0134 >> 2)
-
-#define DPDMA_DSCR_STRT_ADDRE_CH(n)           ((0x0200 + n * 0x100) >> 2)
-#define DPDMA_DSCR_STRT_ADDR_CH(n)            ((0x0204 + n * 0x100) >> 2)
-#define DPDMA_DSCR_NEXT_ADDRE_CH(n)           ((0x0208 + n * 0x100) >> 2)
-#define DPDMA_DSCR_NEXT_ADDR_CH(n)            ((0x020C + n * 0x100) >> 2)
-#define DPDMA_PYLD_CUR_ADDRE_CH(n)            ((0x0210 + n * 0x100) >> 2)
-#define DPDMA_PYLD_CUR_ADDR_CH(n)             ((0x0214 + n * 0x100) >> 2)
-
-#define DPDMA_CNTL_CH(n)                      ((0x0218 + n * 0x100) >> 2)
-#define DPDMA_CNTL_CH_EN                      (1)
-#define DPDMA_CNTL_CH_PAUSED                  (1 << 1)
-
-#define DPDMA_STATUS_CH(n)                    ((0x021C + n * 0x100) >> 2)
-#define DPDMA_STATUS_BURST_TYPE               (1 << 4)
-#define DPDMA_STATUS_MODE                     (1 << 5)
-#define DPDMA_STATUS_EN_CRC                   (1 << 6)
-#define DPDMA_STATUS_LAST_DSCR                (1 << 7)
-#define DPDMA_STATUS_LDSCR_FRAME              (1 << 8)
-#define DPDMA_STATUS_IGNR_DONE                (1 << 9)
-#define DPDMA_STATUS_DSCR_DONE                (1 << 10)
-#define DPDMA_STATUS_EN_DSCR_UP               (1 << 11)
-#define DPDMA_STATUS_EN_DSCR_INTR             (1 << 12)
-#define DPDMA_STATUS_PREAMBLE_OFF             (13)
-
-#define DPDMA_VDO_CH(n)                       ((0x0220 + n * 0x100) >> 2)
-#define DPDMA_PYLD_SZ_CH(n)                   ((0x0224 + n * 0x100) >> 2)
-#define DPDMA_DSCR_ID_CH(n)                   ((0x0228 + n * 0x100) >> 2)
-
-/*
- * Descriptor control field.
- */
-#define CONTROL_PREAMBLE_VALUE                0xA5
-
-#define DSCR_CTRL_PREAMBLE                    0xFF
-#define DSCR_CTRL_EN_DSCR_DONE_INTR           (1 << 8)
-#define DSCR_CTRL_EN_DSCR_UPDATE              (1 << 9)
-#define DSCR_CTRL_IGNORE_DONE                 (1 << 10)
-#define DSCR_CTRL_AXI_BURST_TYPE              (1 << 11)
-#define DSCR_CTRL_AXCACHE                     (0x0F << 12)
-#define DSCR_CTRL_AXPROT                      (0x2 << 16)
-#define DSCR_CTRL_DESCRIPTOR_MODE             (1 << 18)
-#define DSCR_CTRL_LAST_DESCRIPTOR             (1 << 19)
-#define DSCR_CTRL_ENABLE_CRC                  (1 << 20)
-#define DSCR_CTRL_LAST_DESCRIPTOR_OF_FRAME    (1 << 21)
-
-/*
- * Descriptor timestamp field.
- */
-#define STATUS_DONE                           (1 << 31)
-
-#define DPDMA_FRAG_MAX_SZ                     (4096)
-
-enum DPDMABurstType {
-    DPDMA_INCR = 0,
-    DPDMA_FIXED = 1
-};
-
-enum DPDMAMode {
-    DPDMA_CONTIGOUS = 0,
-    DPDMA_FRAGMENTED = 1
-};
-
-struct DPDMADescriptor {
-    uint32_t control;
-    uint32_t descriptor_id;
-    /* transfer size in byte. */
-    uint32_t xfer_size;
-    uint32_t line_size_stride;
-    uint32_t timestamp_lsb;
-    uint32_t timestamp_msb;
-    /* contains extension for both descriptor and source. */
-    uint32_t address_extension;
-    uint32_t next_descriptor;
-    uint32_t source_address;
-    uint32_t address_extension_23;
-    uint32_t address_extension_45;
-    uint32_t source_address2;
-    uint32_t source_address3;
-    uint32_t source_address4;
-    uint32_t source_address5;
-    uint32_t crc;
-};
-
-typedef enum DPDMABurstType DPDMABurstType;
-typedef enum DPDMAMode DPDMAMode;
-typedef struct DPDMADescriptor DPDMADescriptor;
-
-static bool xlnx_dpdma_desc_is_last(DPDMADescriptor *desc)
-{
-    return ((desc->control & DSCR_CTRL_LAST_DESCRIPTOR) != 0);
-}
-
-static bool xlnx_dpdma_desc_is_last_of_frame(DPDMADescriptor *desc)
-{
-    return ((desc->control & DSCR_CTRL_LAST_DESCRIPTOR_OF_FRAME) != 0);
-}
-
-static uint64_t xlnx_dpdma_desc_get_source_address(DPDMADescriptor *desc,
-                                                     uint8_t frag)
-{
-    uint64_t addr = 0;
-    assert(frag < 5);
-
-    switch (frag) {
-    case 0:
-        addr = desc->source_address
-            + (extract32(desc->address_extension, 16, 12) << 20);
-        break;
-    case 1:
-        addr = desc->source_address2
-            + (extract32(desc->address_extension_23, 0, 12) << 8);
-        break;
-    case 2:
-        addr = desc->source_address3
-            + (extract32(desc->address_extension_23, 16, 12) << 20);
-        break;
-    case 3:
-        addr = desc->source_address4
-            + (extract32(desc->address_extension_45, 0, 12) << 8);
-        break;
-    case 4:
-        addr = desc->source_address5
-            + (extract32(desc->address_extension_45, 16, 12) << 20);
-        break;
-    default:
-        addr = 0;
-        break;
-    }
-
-    return addr;
-}
-
-static uint32_t xlnx_dpdma_desc_get_transfer_size(DPDMADescriptor *desc)
-{
-    return desc->xfer_size;
-}
-
-static uint32_t xlnx_dpdma_desc_get_line_size(DPDMADescriptor *desc)
-{
-    return extract32(desc->line_size_stride, 0, 18);
-}
-
-static uint32_t xlnx_dpdma_desc_get_line_stride(DPDMADescriptor *desc)
-{
-    return extract32(desc->line_size_stride, 18, 14) * 16;
-}
-
-static inline bool xlnx_dpdma_desc_crc_enabled(DPDMADescriptor *desc)
-{
-    return (desc->control & DSCR_CTRL_ENABLE_CRC) != 0;
-}
-
-static inline bool xlnx_dpdma_desc_check_crc(DPDMADescriptor *desc)
-{
-    uint32_t *p = (uint32_t *)desc;
-    uint32_t crc = 0;
-    uint8_t i;
-
-    /*
-     * CRC is calculated on the whole descriptor except the last 32bits word
-     * using 32bits addition.
-     */
-    for (i = 0; i < 15; i++) {
-        crc += p[i];
-    }
-
-    return crc == desc->crc;
-}
-
-static inline bool xlnx_dpdma_desc_completion_interrupt(DPDMADescriptor *desc)
-{
-    return (desc->control & DSCR_CTRL_EN_DSCR_DONE_INTR) != 0;
-}
-
-static inline bool xlnx_dpdma_desc_is_valid(DPDMADescriptor *desc)
-{
-    return (desc->control & DSCR_CTRL_PREAMBLE) == CONTROL_PREAMBLE_VALUE;
-}
-
-static inline bool xlnx_dpdma_desc_is_contiguous(DPDMADescriptor *desc)
-{
-    return (desc->control & DSCR_CTRL_DESCRIPTOR_MODE) == 0;
-}
-
-static inline bool xlnx_dpdma_desc_update_enabled(DPDMADescriptor *desc)
-{
-    return (desc->control & DSCR_CTRL_EN_DSCR_UPDATE) != 0;
-}
-
-static inline void xlnx_dpdma_desc_set_done(DPDMADescriptor *desc)
-{
-    desc->timestamp_msb |= STATUS_DONE;
-}
-
-static inline bool xlnx_dpdma_desc_is_already_done(DPDMADescriptor *desc)
-{
-    return (desc->timestamp_msb & STATUS_DONE) != 0;
-}
-
-static inline bool xlnx_dpdma_desc_ignore_done_bit(DPDMADescriptor *desc)
-{
-    return (desc->control & DSCR_CTRL_IGNORE_DONE) != 0;
-}
-
-static const VMStateDescription vmstate_xlnx_dpdma = {
-    .name = TYPE_XLNX_DPDMA,
-    .version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT32_ARRAY(registers, XlnxDPDMAState,
-                             XLNX_DPDMA_REG_ARRAY_SIZE),
-        VMSTATE_BOOL_ARRAY(operation_finished, XlnxDPDMAState, 6),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static void xlnx_dpdma_update_irq(XlnxDPDMAState *s)
-{
-    bool flags;
-
-    flags = ((s->registers[DPDMA_ISR] & (~s->registers[DPDMA_IMR]))
-          || (s->registers[DPDMA_EISR] & (~s->registers[DPDMA_EIMR])));
-    qemu_set_irq(s->irq, flags);
-}
-
-static uint64_t xlnx_dpdma_descriptor_start_address(XlnxDPDMAState *s,
-                                                      uint8_t channel)
-{
-    return (s->registers[DPDMA_DSCR_STRT_ADDRE_CH(channel)] << 16)
-          + s->registers[DPDMA_DSCR_STRT_ADDR_CH(channel)];
-}
-
-static uint64_t xlnx_dpdma_descriptor_next_address(XlnxDPDMAState *s,
-                                                     uint8_t channel)
-{
-    return ((uint64_t)s->registers[DPDMA_DSCR_NEXT_ADDRE_CH(channel)] << 32)
-           + s->registers[DPDMA_DSCR_NEXT_ADDR_CH(channel)];
-}
-
-static bool xlnx_dpdma_is_channel_enabled(XlnxDPDMAState *s,
-                                            uint8_t channel)
-{
-    return (s->registers[DPDMA_CNTL_CH(channel)] & DPDMA_CNTL_CH_EN) != 0;
-}
-
-static bool xlnx_dpdma_is_channel_paused(XlnxDPDMAState *s,
-                                           uint8_t channel)
-{
-    return (s->registers[DPDMA_CNTL_CH(channel)] & DPDMA_CNTL_CH_PAUSED) != 0;
-}
-
-static inline bool xlnx_dpdma_is_channel_retriggered(XlnxDPDMAState *s,
-                                                       uint8_t channel)
-{
-    /* Clear the retriggered bit after reading it. */
-    bool channel_is_retriggered = s->registers[DPDMA_GBL]
-                                & DPDMA_GBL_RTRG_CH(channel);
-    s->registers[DPDMA_GBL] &= ~DPDMA_GBL_RTRG_CH(channel);
-    return channel_is_retriggered;
-}
-
-static inline bool xlnx_dpdma_is_channel_triggered(XlnxDPDMAState *s,
-                                                     uint8_t channel)
-{
-    return s->registers[DPDMA_GBL] & DPDMA_GBL_TRG_CH(channel);
-}
-
-static void xlnx_dpdma_update_desc_info(XlnxDPDMAState *s, uint8_t channel,
-                                          DPDMADescriptor *desc)
-{
-    s->registers[DPDMA_DSCR_NEXT_ADDRE_CH(channel)] =
-                                extract32(desc->address_extension, 0, 16);
-    s->registers[DPDMA_DSCR_NEXT_ADDR_CH(channel)] = desc->next_descriptor;
-    s->registers[DPDMA_PYLD_CUR_ADDRE_CH(channel)] =
-                                extract32(desc->address_extension, 16, 16);
-    s->registers[DPDMA_PYLD_CUR_ADDR_CH(channel)] = desc->source_address;
-    s->registers[DPDMA_VDO_CH(channel)] =
-                                extract32(desc->line_size_stride, 18, 14)
-                                + (extract32(desc->line_size_stride, 0, 18)
-                                  << 14);
-    s->registers[DPDMA_PYLD_SZ_CH(channel)] = desc->xfer_size;
-    s->registers[DPDMA_DSCR_ID_CH(channel)] = desc->descriptor_id;
-
-    /* Compute the status register with the descriptor information. */
-    s->registers[DPDMA_STATUS_CH(channel)] =
-                                extract32(desc->control, 0, 8) << 13;
-    if ((desc->control & DSCR_CTRL_EN_DSCR_DONE_INTR) != 0) {
-        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_EN_DSCR_INTR;
-    }
-    if ((desc->control & DSCR_CTRL_EN_DSCR_UPDATE) != 0) {
-        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_EN_DSCR_UP;
-    }
-    if ((desc->timestamp_msb & STATUS_DONE) != 0) {
-        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_DSCR_DONE;
-    }
-    if ((desc->control & DSCR_CTRL_IGNORE_DONE) != 0) {
-        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_IGNR_DONE;
-    }
-    if ((desc->control & DSCR_CTRL_LAST_DESCRIPTOR_OF_FRAME) != 0) {
-        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_LDSCR_FRAME;
-    }
-    if ((desc->control & DSCR_CTRL_LAST_DESCRIPTOR) != 0) {
-        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_LAST_DSCR;
-    }
-    if ((desc->control & DSCR_CTRL_ENABLE_CRC) != 0) {
-        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_EN_CRC;
-    }
-    if ((desc->control & DSCR_CTRL_DESCRIPTOR_MODE) != 0) {
-        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_MODE;
-    }
-    if ((desc->control & DSCR_CTRL_AXI_BURST_TYPE) != 0) {
-        s->registers[DPDMA_STATUS_CH(channel)] |= DPDMA_STATUS_BURST_TYPE;
-    }
-}
-
-static void xlnx_dpdma_dump_descriptor(DPDMADescriptor *desc)
-{
-    if (DEBUG_DPDMA) {
-        qemu_log("DUMP DESCRIPTOR:\n");
-        qemu_hexdump((char *)desc, stdout, "", sizeof(DPDMADescriptor));
-    }
-}
-
-static uint64_t xlnx_dpdma_read(void *opaque, hwaddr offset,
-                                unsigned size)
-{
-    XlnxDPDMAState *s = XLNX_DPDMA(opaque);
-
-    DPRINTF("read @%" HWADDR_PRIx "\n", offset);
-    offset = offset >> 2;
-
-    switch (offset) {
-    /*
-     * Trying to read a write only register.
-     */
-    case DPDMA_GBL:
-        return 0;
-    default:
-        assert(offset <= (0xFFC >> 2));
-        return s->registers[offset];
-    }
-    return 0;
-}
-
-static void xlnx_dpdma_write(void *opaque, hwaddr offset,
-                               uint64_t value, unsigned size)
-{
-    XlnxDPDMAState *s = XLNX_DPDMA(opaque);
-
-    DPRINTF("write @%" HWADDR_PRIx " = %" PRIx64 "\n", offset, value);
-    offset = offset >> 2;
-
-    switch (offset) {
-    case DPDMA_ISR:
-        s->registers[DPDMA_ISR] &= ~value;
-        xlnx_dpdma_update_irq(s);
-        break;
-    case DPDMA_IEN:
-        s->registers[DPDMA_IMR] &= ~value;
-        break;
-    case DPDMA_IDS:
-        s->registers[DPDMA_IMR] |= value;
-        break;
-    case DPDMA_EISR:
-        s->registers[DPDMA_EISR] &= ~value;
-        xlnx_dpdma_update_irq(s);
-        break;
-    case DPDMA_EIEN:
-        s->registers[DPDMA_EIMR] &= ~value;
-        break;
-    case DPDMA_EIDS:
-        s->registers[DPDMA_EIMR] |= value;
-        break;
-    case DPDMA_IMR:
-    case DPDMA_EIMR:
-    case DPDMA_DSCR_NEXT_ADDRE_CH(0):
-    case DPDMA_DSCR_NEXT_ADDRE_CH(1):
-    case DPDMA_DSCR_NEXT_ADDRE_CH(2):
-    case DPDMA_DSCR_NEXT_ADDRE_CH(3):
-    case DPDMA_DSCR_NEXT_ADDRE_CH(4):
-    case DPDMA_DSCR_NEXT_ADDRE_CH(5):
-    case DPDMA_DSCR_NEXT_ADDR_CH(0):
-    case DPDMA_DSCR_NEXT_ADDR_CH(1):
-    case DPDMA_DSCR_NEXT_ADDR_CH(2):
-    case DPDMA_DSCR_NEXT_ADDR_CH(3):
-    case DPDMA_DSCR_NEXT_ADDR_CH(4):
-    case DPDMA_DSCR_NEXT_ADDR_CH(5):
-    case DPDMA_PYLD_CUR_ADDRE_CH(0):
-    case DPDMA_PYLD_CUR_ADDRE_CH(1):
-    case DPDMA_PYLD_CUR_ADDRE_CH(2):
-    case DPDMA_PYLD_CUR_ADDRE_CH(3):
-    case DPDMA_PYLD_CUR_ADDRE_CH(4):
-    case DPDMA_PYLD_CUR_ADDRE_CH(5):
-    case DPDMA_PYLD_CUR_ADDR_CH(0):
-    case DPDMA_PYLD_CUR_ADDR_CH(1):
-    case DPDMA_PYLD_CUR_ADDR_CH(2):
-    case DPDMA_PYLD_CUR_ADDR_CH(3):
-    case DPDMA_PYLD_CUR_ADDR_CH(4):
-    case DPDMA_PYLD_CUR_ADDR_CH(5):
-    case DPDMA_STATUS_CH(0):
-    case DPDMA_STATUS_CH(1):
-    case DPDMA_STATUS_CH(2):
-    case DPDMA_STATUS_CH(3):
-    case DPDMA_STATUS_CH(4):
-    case DPDMA_STATUS_CH(5):
-    case DPDMA_VDO_CH(0):
-    case DPDMA_VDO_CH(1):
-    case DPDMA_VDO_CH(2):
-    case DPDMA_VDO_CH(3):
-    case DPDMA_VDO_CH(4):
-    case DPDMA_VDO_CH(5):
-    case DPDMA_PYLD_SZ_CH(0):
-    case DPDMA_PYLD_SZ_CH(1):
-    case DPDMA_PYLD_SZ_CH(2):
-    case DPDMA_PYLD_SZ_CH(3):
-    case DPDMA_PYLD_SZ_CH(4):
-    case DPDMA_PYLD_SZ_CH(5):
-    case DPDMA_DSCR_ID_CH(0):
-    case DPDMA_DSCR_ID_CH(1):
-    case DPDMA_DSCR_ID_CH(2):
-    case DPDMA_DSCR_ID_CH(3):
-    case DPDMA_DSCR_ID_CH(4):
-    case DPDMA_DSCR_ID_CH(5):
-        /*
-         * Trying to write to a read only register..
-         */
-        break;
-    case DPDMA_GBL:
-        /*
-         * This is a write only register so it's read as zero in the read
-         * callback.
-         * We store the value anyway so we can know if the channel is
-         * enabled.
-         */
-        s->registers[offset] |= value & 0x00000FFF;
-        break;
-    case DPDMA_DSCR_STRT_ADDRE_CH(0):
-    case DPDMA_DSCR_STRT_ADDRE_CH(1):
-    case DPDMA_DSCR_STRT_ADDRE_CH(2):
-    case DPDMA_DSCR_STRT_ADDRE_CH(3):
-    case DPDMA_DSCR_STRT_ADDRE_CH(4):
-    case DPDMA_DSCR_STRT_ADDRE_CH(5):
-        value &= 0x0000FFFF;
-        s->registers[offset] = value;
-        break;
-    case DPDMA_CNTL_CH(0):
-        s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(0);
-        value &= 0x3FFFFFFF;
-        s->registers[offset] = value;
-        break;
-    case DPDMA_CNTL_CH(1):
-        s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(1);
-        value &= 0x3FFFFFFF;
-        s->registers[offset] = value;
-        break;
-    case DPDMA_CNTL_CH(2):
-        s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(2);
-        value &= 0x3FFFFFFF;
-        s->registers[offset] = value;
-        break;
-    case DPDMA_CNTL_CH(3):
-        s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(3);
-        value &= 0x3FFFFFFF;
-        s->registers[offset] = value;
-        break;
-    case DPDMA_CNTL_CH(4):
-        s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(4);
-        value &= 0x3FFFFFFF;
-        s->registers[offset] = value;
-        break;
-    case DPDMA_CNTL_CH(5):
-        s->registers[DPDMA_GBL] &= ~DPDMA_GBL_TRG_CH(5);
-        value &= 0x3FFFFFFF;
-        s->registers[offset] = value;
-        break;
-    default:
-        assert(offset <= (0xFFC >> 2));
-        s->registers[offset] = value;
-        break;
-    }
-}
-
-static const MemoryRegionOps dma_ops = {
-    .read = xlnx_dpdma_read,
-    .write = xlnx_dpdma_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-    .impl = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-};
-
-static void xlnx_dpdma_init(Object *obj)
-{
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
-    XlnxDPDMAState *s = XLNX_DPDMA(obj);
-
-    memory_region_init_io(&s->iomem, obj, &dma_ops, s,
-                          TYPE_XLNX_DPDMA, 0x1000);
-    sysbus_init_mmio(sbd, &s->iomem);
-    sysbus_init_irq(sbd, &s->irq);
-}
-
-static void xlnx_dpdma_reset(DeviceState *dev)
-{
-    XlnxDPDMAState *s = XLNX_DPDMA(dev);
-    size_t i;
-
-    memset(s->registers, 0, sizeof(s->registers));
-    s->registers[DPDMA_IMR] =  0x07FFFFFF;
-    s->registers[DPDMA_EIMR] = 0xFFFFFFFF;
-    s->registers[DPDMA_ALC0_MIN] = 0x0000FFFF;
-    s->registers[DPDMA_ALC1_MIN] = 0x0000FFFF;
-
-    for (i = 0; i < 6; i++) {
-        s->data[i] = NULL;
-        s->operation_finished[i] = true;
-    }
-}
-
-static void xlnx_dpdma_class_init(ObjectClass *oc, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(oc);
-
-    dc->vmsd = &vmstate_xlnx_dpdma;
-    dc->reset = xlnx_dpdma_reset;
-}
-
-static const TypeInfo xlnx_dpdma_info = {
-    .name          = TYPE_XLNX_DPDMA,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(XlnxDPDMAState),
-    .instance_init = xlnx_dpdma_init,
-    .class_init    = xlnx_dpdma_class_init,
-};
-
-static void xlnx_dpdma_register_types(void)
-{
-    type_register_static(&xlnx_dpdma_info);
-}
-
-size_t xlnx_dpdma_start_operation(XlnxDPDMAState *s, uint8_t channel,
-                                    bool one_desc)
-{
-    uint64_t desc_addr;
-    uint64_t source_addr[6];
-    DPDMADescriptor desc;
-    bool done = false;
-    size_t ptr = 0;
-
-    assert(channel <= 5);
-
-    DPRINTF("start dpdma channel 0x%" PRIX8 "\n", channel);
-
-    if (!xlnx_dpdma_is_channel_triggered(s, channel)) {
-        DPRINTF("Channel isn't triggered..\n");
-        return 0;
-    }
-
-    if (!xlnx_dpdma_is_channel_enabled(s, channel)) {
-        DPRINTF("Channel isn't enabled..\n");
-        return 0;
-    }
-
-    if (xlnx_dpdma_is_channel_paused(s, channel)) {
-        DPRINTF("Channel is paused..\n");
-        return 0;
-    }
-
-    do {
-        if ((s->operation_finished[channel])
-          || xlnx_dpdma_is_channel_retriggered(s, channel)) {
-            desc_addr = xlnx_dpdma_descriptor_start_address(s, channel);
-            s->operation_finished[channel] = false;
-        } else {
-            desc_addr = xlnx_dpdma_descriptor_next_address(s, channel);
-        }
-
-        if (dma_memory_read(&address_space_memory, desc_addr, &desc,
-                            sizeof(DPDMADescriptor))) {
-            s->registers[DPDMA_EISR] |= ((1 << 1) << channel);
-            xlnx_dpdma_update_irq(s);
-            s->operation_finished[channel] = true;
-            DPRINTF("Can't get the descriptor.\n");
-            break;
-        }
-
-        xlnx_dpdma_update_desc_info(s, channel, &desc);
-
-#ifdef DEBUG_DPDMA
-        xlnx_dpdma_dump_descriptor(&desc);
-#endif
-
-        DPRINTF("location of the descriptor: %" PRIx64 "\n", desc_addr);
-        if (!xlnx_dpdma_desc_is_valid(&desc)) {
-            s->registers[DPDMA_EISR] |= ((1 << 7) << channel);
-            xlnx_dpdma_update_irq(s);
-            s->operation_finished[channel] = true;
-            DPRINTF("Invalid descriptor..\n");
-            break;
-        }
-
-        if (xlnx_dpdma_desc_crc_enabled(&desc)
-            && !xlnx_dpdma_desc_check_crc(&desc)) {
-            s->registers[DPDMA_EISR] |= ((1 << 13) << channel);
-            xlnx_dpdma_update_irq(s);
-            s->operation_finished[channel] = true;
-            DPRINTF("Bad CRC for descriptor..\n");
-            break;
-        }
-
-        if (xlnx_dpdma_desc_is_already_done(&desc)
-            && !xlnx_dpdma_desc_ignore_done_bit(&desc)) {
-            /* We are trying to process an already processed descriptor. */
-            s->registers[DPDMA_EISR] |= ((1 << 25) << channel);
-            xlnx_dpdma_update_irq(s);
-            s->operation_finished[channel] = true;
-            DPRINTF("Already processed descriptor..\n");
-            break;
-        }
-
-        done = xlnx_dpdma_desc_is_last(&desc)
-             || xlnx_dpdma_desc_is_last_of_frame(&desc);
-
-        s->operation_finished[channel] = done;
-        if (s->data[channel]) {
-            int64_t transfer_len = xlnx_dpdma_desc_get_transfer_size(&desc);
-            uint32_t line_size = xlnx_dpdma_desc_get_line_size(&desc);
-            uint32_t line_stride = xlnx_dpdma_desc_get_line_stride(&desc);
-            if (xlnx_dpdma_desc_is_contiguous(&desc)) {
-                source_addr[0] = xlnx_dpdma_desc_get_source_address(&desc, 0);
-                while (transfer_len != 0) {
-                    if (dma_memory_read(&address_space_memory,
-                                        source_addr[0],
-                                        &s->data[channel][ptr],
-                                        line_size)) {
-                        s->registers[DPDMA_ISR] |= ((1 << 12) << channel);
-                        xlnx_dpdma_update_irq(s);
-                        DPRINTF("Can't get data.\n");
-                        break;
-                    }
-                    ptr += line_size;
-                    transfer_len -= line_size;
-                    source_addr[0] += line_stride;
-                }
-            } else {
-                DPRINTF("Source address:\n");
-                int frag;
-                for (frag = 0; frag < 5; frag++) {
-                    source_addr[frag] =
-                          xlnx_dpdma_desc_get_source_address(&desc, frag);
-                    DPRINTF("Fragment %u: %" PRIx64 "\n", frag + 1,
-                            source_addr[frag]);
-                }
-
-                frag = 0;
-                while ((transfer_len < 0) && (frag < 5)) {
-                    size_t fragment_len = DPDMA_FRAG_MAX_SZ
-                                    - (source_addr[frag] % DPDMA_FRAG_MAX_SZ);
-
-                    if (dma_memory_read(&address_space_memory,
-                                        source_addr[frag],
-                                        &(s->data[channel][ptr]),
-                                        fragment_len)) {
-                        s->registers[DPDMA_ISR] |= ((1 << 12) << channel);
-                        xlnx_dpdma_update_irq(s);
-                        DPRINTF("Can't get data.\n");
-                        break;
-                    }
-                    ptr += fragment_len;
-                    transfer_len -= fragment_len;
-                    frag += 1;
-                }
-            }
-        }
-
-        if (xlnx_dpdma_desc_update_enabled(&desc)) {
-            /* The descriptor need to be updated when it's completed. */
-            DPRINTF("update the descriptor with the done flag set.\n");
-            xlnx_dpdma_desc_set_done(&desc);
-            dma_memory_write(&address_space_memory, desc_addr, &desc,
-                             sizeof(DPDMADescriptor));
-        }
-
-        if (xlnx_dpdma_desc_completion_interrupt(&desc)) {
-            DPRINTF("completion interrupt enabled!\n");
-            s->registers[DPDMA_ISR] |= (1 << channel);
-            xlnx_dpdma_update_irq(s);
-        }
-
-    } while (!done && !one_desc);
-
-    return ptr;
-}
-
-void xlnx_dpdma_set_host_data_location(XlnxDPDMAState *s, uint8_t channel,
-                                         void *p)
-{
-    if (!s) {
-        qemu_log_mask(LOG_UNIMP, "DPDMA client not attached to valid DPDMA"
-                      " instance\n");
-        return;
-    }
-
-    assert(channel <= 5);
-    s->data[channel] = p;
-}
-
-void xlnx_dpdma_trigger_vsync_irq(XlnxDPDMAState *s)
-{
-    s->registers[DPDMA_ISR] |= (1 << 27);
-    xlnx_dpdma_update_irq(s);
-}
-
-type_init(xlnx_dpdma_register_types)
index b34aa49..ef28772 100644 (file)
@@ -24,7 +24,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
-#include "qemu/timer.h"
 
 #define TYPE_GPIOKEY "gpio-key"
 #define GPIOKEY(obj) OBJECT_CHECK(GPIOKEYState, (obj), TYPE_GPIOKEY)
index f3574aa..ed7e247 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/gpio/imx_gpio.h"
-#include "qemu/log.h"
 
 #ifndef DEBUG_IMX_GPIO
 #define DEBUG_IMX_GPIO 0
index dabef4a..9b1b004 100644 (file)
@@ -23,7 +23,6 @@
 #include "hw/arm/omap.h"
 #include "hw/sysbus.h"
 #include "qemu/error-report.h"
-#include "qapi/error.h"
 
 struct omap_gpio_s {
     qemu_irq irq;
@@ -679,46 +678,48 @@ static const MemoryRegionOps omap2_gpif_top_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void omap_gpio_init(Object *obj)
+static int omap_gpio_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    struct omap_gpif_s *s = OMAP1_GPIO(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    struct omap_gpif_s *s = OMAP1_GPIO(dev);
 
+    if (!s->clk) {
+        error_report("omap-gpio: clk not connected");
+        return -1;
+    }
     qdev_init_gpio_in(dev, omap_gpio_set, 16);
     qdev_init_gpio_out(dev, s->omap1.handler, 16);
     sysbus_init_irq(sbd, &s->omap1.irq);
-    memory_region_init_io(&s->iomem, obj, &omap_gpio_ops, &s->omap1,
+    memory_region_init_io(&s->iomem, OBJECT(s), &omap_gpio_ops, &s->omap1,
                           "omap.gpio", 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
+    return 0;
 }
 
-static void omap_gpio_realize(DeviceState *dev, Error **errp)
-{
-    struct omap_gpif_s *s = OMAP1_GPIO(dev);
-
-    if (!s->clk) {
-        error_setg(errp, "omap-gpio: clk not connected");
-    }
-}
-
-static void omap2_gpio_realize(DeviceState *dev, Error **errp)
+static int omap2_gpio_init(SysBusDevice *sbd)
 {
+    DeviceState *dev = DEVICE(sbd);
     struct omap2_gpif_s *s = OMAP2_GPIO(dev);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     int i;
 
     if (!s->iclk) {
-        error_setg(errp, "omap2-gpio: iclk not connected");
-        return;
+        error_report("omap2-gpio: iclk not connected");
+        return -1;
     }
 
     s->modulecount = s->mpu_model < omap2430 ? 4
-        : s->mpu_model < omap3430 ? 5
-        : 6;
+                   : s->mpu_model < omap3430 ? 5
+                   : 6;
+
+    for (i = 0; i < s->modulecount; i++) {
+        if (!s->fclk[i]) {
+            error_report("omap2-gpio: fclk%d not connected", i);
+            return -1;
+        }
+    }
 
     if (s->mpu_model < omap3430) {
-        memory_region_init_io(&s->iomem, OBJECT(dev), &omap2_gpif_top_ops, s,
+        memory_region_init_io(&s->iomem, OBJECT(s), &omap2_gpif_top_ops, s,
                               "omap2.gpio", 0x1000);
         sysbus_init_mmio(sbd, &s->iomem);
     }
@@ -731,20 +732,17 @@ static void omap2_gpio_realize(DeviceState *dev, Error **errp)
     for (i = 0; i < s->modulecount; i++) {
         struct omap2_gpio_s *m = &s->modules[i];
 
-        if (!s->fclk[i]) {
-            error_setg(errp, "omap2-gpio: fclk%d not connected", i);
-            return;
-        }
-
         m->revision = (s->mpu_model < omap3430) ? 0x18 : 0x25;
         m->handler = &s->handler[i * 32];
         sysbus_init_irq(sbd, &m->irq[0]); /* mpu irq */
         sysbus_init_irq(sbd, &m->irq[1]); /* dsp irq */
         sysbus_init_irq(sbd, &m->wkup);
-        memory_region_init_io(&m->iomem, OBJECT(dev), &omap2_gpio_module_ops, m,
+        memory_region_init_io(&m->iomem, OBJECT(s), &omap2_gpio_module_ops, m,
                               "omap.gpio-module", 0x1000);
         sysbus_init_mmio(sbd, &m->iomem);
     }
+
+    return 0;
 }
 
 /* Using qdev pointer properties for the clocks is not ideal.
@@ -768,8 +766,9 @@ static Property omap_gpio_properties[] = {
 static void omap_gpio_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    dc->realize = omap_gpio_realize;
+    k->init = omap_gpio_init;
     dc->reset = omap_gpif_reset;
     dc->props = omap_gpio_properties;
     /* Reason: pointer property "clk" */
@@ -780,7 +779,6 @@ static const TypeInfo omap_gpio_info = {
     .name          = TYPE_OMAP1_GPIO,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(struct omap_gpif_s),
-    .instance_init = omap_gpio_init,
     .class_init    = omap_gpio_class_init,
 };
 
@@ -799,8 +797,9 @@ static Property omap2_gpio_properties[] = {
 static void omap2_gpio_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    dc->realize = omap2_gpio_realize;
+    k->init = omap2_gpio_init;
     dc->reset = omap2_gpif_reset;
     dc->props = omap2_gpio_properties;
     /* Reason: pointer properties "iclk", "fclk0", ..., "fclk5" */
index 4ae2aa1..29dc7fc 100644 (file)
@@ -10,7 +10,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
-#include "qemu/log.h"
 
 //#define DEBUG_PL061 1
 
@@ -341,6 +340,20 @@ static const MemoryRegionOps pl061_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+static int pl061_initfn(SysBusDevice *sbd)
+{
+    DeviceState *dev = DEVICE(sbd);
+    PL061State *s = PL061(dev);
+
+    memory_region_init_io(&s->iomem, OBJECT(s), &pl061_ops, s, "pl061", 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(sbd, &s->irq);
+    qdev_init_gpio_in(dev, pl061_set_irq, 8);
+    qdev_init_gpio_out(dev, s->out, 8);
+
+    return 0;
+}
+
 static void pl061_luminary_init(Object *obj)
 {
     PL061State *s = PL061(obj);
@@ -352,23 +365,17 @@ static void pl061_luminary_init(Object *obj)
 static void pl061_init(Object *obj)
 {
     PL061State *s = PL061(obj);
-    DeviceState *dev = DEVICE(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 
     s->id = pl061_id;
     s->rsvd_start = 0x424;
-
-    memory_region_init_io(&s->iomem, obj, &pl061_ops, s, "pl061", 0x1000);
-    sysbus_init_mmio(sbd, &s->iomem);
-    sysbus_init_irq(sbd, &s->irq);
-    qdev_init_gpio_in(dev, pl061_set_irq, 8);
-    qdev_init_gpio_out(dev, s->out, 8);
 }
 
 static void pl061_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = pl061_initfn;
     dc->vmsd = &vmstate_pl061;
     dc->reset = &pl061_reset;
 }
index 15865e1..555da28 100644 (file)
@@ -167,18 +167,19 @@ static void scoop_gpio_set(void *opaque, int line, int level)
         s->gpio_level &= ~(1 << line);
 }
 
-static void scoop_init(Object *obj)
+static int scoop_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    ScoopInfo *s = SCOOP(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    ScoopInfo *s = SCOOP(dev);
 
     s->status = 0x02;
     qdev_init_gpio_out(dev, s->handler, 16);
     qdev_init_gpio_in(dev, scoop_gpio_set, 16);
-    memory_region_init_io(&s->iomem, obj, &scoop_ops, s, "scoop", 0x1000);
+    memory_region_init_io(&s->iomem, OBJECT(s), &scoop_ops, s, "scoop", 0x1000);
 
     sysbus_init_mmio(sbd, &s->iomem);
+
+    return 0;
 }
 
 static int scoop_post_load(void *opaque, int version_id)
@@ -238,7 +239,9 @@ static const VMStateDescription vmstate_scoop_regs = {
 static void scoop_sysbus_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = scoop_init;
     dc->desc = "Scoop2 Sharp custom ASIC";
     dc->vmsd = &vmstate_scoop_regs;
 }
@@ -247,7 +250,6 @@ static const TypeInfo scoop_sysbus_info = {
     .name          = TYPE_SCOOP,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(ScoopInfo),
-    .instance_init = scoop_init,
     .class_init    = scoop_sysbus_class_init,
 };
 
index a081b8e..aeb8f38 100644 (file)
@@ -1,10 +1,8 @@
 common-obj-y += core.o smbus.o smbus_eeprom.o
-common-obj-$(CONFIG_DDC) += i2c-ddc.o
 common-obj-$(CONFIG_VERSATILE_I2C) += versatile_i2c.o
 common-obj-$(CONFIG_ACPI_X86) += smbus_ich9.o
 common-obj-$(CONFIG_APM) += pm_smbus.o
 common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o
 common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
 common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
-common-obj-$(CONFIG_ASPEED_SOC) += aspeed_i2c.o
 obj-$(CONFIG_OMAP) += omap_i2c.o
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
deleted file mode 100644 (file)
index ce5b1f0..0000000
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * ARM Aspeed I2C controller
- *
- * Copyright (C) 2016 IBM Corp.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "hw/sysbus.h"
-#include "qemu/log.h"
-#include "hw/i2c/aspeed_i2c.h"
-
-/* I2C Global Register */
-
-#define I2C_CTRL_STATUS         0x00        /* Device Interrupt Status */
-#define I2C_CTRL_ASSIGN         0x08        /* Device Interrupt Target
-                                               Assignment */
-
-/* I2C Device (Bus) Register */
-
-#define I2CD_FUN_CTRL_REG       0x00       /* I2CD Function Control  */
-#define   I2CD_BUFF_SEL_MASK               (0x7 << 20)
-#define   I2CD_BUFF_SEL(x)                 (x << 20)
-#define   I2CD_M_SDA_LOCK_EN               (0x1 << 16)
-#define   I2CD_MULTI_MASTER_DIS            (0x1 << 15)
-#define   I2CD_M_SCL_DRIVE_EN              (0x1 << 14)
-#define   I2CD_MSB_STS                     (0x1 << 9)
-#define   I2CD_SDA_DRIVE_1T_EN             (0x1 << 8)
-#define   I2CD_M_SDA_DRIVE_1T_EN           (0x1 << 7)
-#define   I2CD_M_HIGH_SPEED_EN             (0x1 << 6)
-#define   I2CD_DEF_ADDR_EN                 (0x1 << 5)
-#define   I2CD_DEF_ALERT_EN                (0x1 << 4)
-#define   I2CD_DEF_ARP_EN                  (0x1 << 3)
-#define   I2CD_DEF_GCALL_EN                (0x1 << 2)
-#define   I2CD_SLAVE_EN                    (0x1 << 1)
-#define   I2CD_MASTER_EN                   (0x1)
-
-#define I2CD_AC_TIMING_REG1     0x04       /* Clock and AC Timing Control #1 */
-#define I2CD_AC_TIMING_REG2     0x08       /* Clock and AC Timing Control #1 */
-#define I2CD_INTR_CTRL_REG      0x0c       /* I2CD Interrupt Control */
-#define I2CD_INTR_STS_REG       0x10       /* I2CD Interrupt Status */
-#define   I2CD_INTR_SDA_DL_TIMEOUT         (0x1 << 14)
-#define   I2CD_INTR_BUS_RECOVER_DONE       (0x1 << 13)
-#define   I2CD_INTR_SMBUS_ALERT            (0x1 << 12) /* Bus [0-3] only */
-#define   I2CD_INTR_SMBUS_ARP_ADDR         (0x1 << 11) /* Removed */
-#define   I2CD_INTR_SMBUS_DEV_ALERT_ADDR   (0x1 << 10) /* Removed */
-#define   I2CD_INTR_SMBUS_DEF_ADDR         (0x1 << 9)  /* Removed */
-#define   I2CD_INTR_GCALL_ADDR             (0x1 << 8)  /* Removed */
-#define   I2CD_INTR_SLAVE_MATCH            (0x1 << 7)  /* use RX_DONE */
-#define   I2CD_INTR_SCL_TIMEOUT            (0x1 << 6)
-#define   I2CD_INTR_ABNORMAL               (0x1 << 5)
-#define   I2CD_INTR_NORMAL_STOP            (0x1 << 4)
-#define   I2CD_INTR_ARBIT_LOSS             (0x1 << 3)
-#define   I2CD_INTR_RX_DONE                (0x1 << 2)
-#define   I2CD_INTR_TX_NAK                 (0x1 << 1)
-#define   I2CD_INTR_TX_ACK                 (0x1 << 0)
-
-#define I2CD_CMD_REG            0x14       /* I2CD Command/Status */
-#define   I2CD_SDA_OE                      (0x1 << 28)
-#define   I2CD_SDA_O                       (0x1 << 27)
-#define   I2CD_SCL_OE                      (0x1 << 26)
-#define   I2CD_SCL_O                       (0x1 << 25)
-#define   I2CD_TX_TIMING                   (0x1 << 24)
-#define   I2CD_TX_STATUS                   (0x1 << 23)
-
-#define   I2CD_TX_STATE_SHIFT              19 /* Tx State Machine */
-#define   I2CD_TX_STATE_MASK                  0xf
-#define     I2CD_IDLE                         0x0
-#define     I2CD_MACTIVE                      0x8
-#define     I2CD_MSTART                       0x9
-#define     I2CD_MSTARTR                      0xa
-#define     I2CD_MSTOP                        0xb
-#define     I2CD_MTXD                         0xc
-#define     I2CD_MRXACK                       0xd
-#define     I2CD_MRXD                         0xe
-#define     I2CD_MTXACK                       0xf
-#define     I2CD_SWAIT                        0x1
-#define     I2CD_SRXD                         0x4
-#define     I2CD_STXACK                       0x5
-#define     I2CD_STXD                         0x6
-#define     I2CD_SRXACK                       0x7
-#define     I2CD_RECOVER                      0x3
-
-#define   I2CD_SCL_LINE_STS                (0x1 << 18)
-#define   I2CD_SDA_LINE_STS                (0x1 << 17)
-#define   I2CD_BUS_BUSY_STS                (0x1 << 16)
-#define   I2CD_SDA_OE_OUT_DIR              (0x1 << 15)
-#define   I2CD_SDA_O_OUT_DIR               (0x1 << 14)
-#define   I2CD_SCL_OE_OUT_DIR              (0x1 << 13)
-#define   I2CD_SCL_O_OUT_DIR               (0x1 << 12)
-#define   I2CD_BUS_RECOVER_CMD_EN          (0x1 << 11)
-#define   I2CD_S_ALT_EN                    (0x1 << 10)
-#define   I2CD_RX_DMA_ENABLE               (0x1 << 9)
-#define   I2CD_TX_DMA_ENABLE               (0x1 << 8)
-
-/* Command Bit */
-#define   I2CD_M_STOP_CMD                  (0x1 << 5)
-#define   I2CD_M_S_RX_CMD_LAST             (0x1 << 4)
-#define   I2CD_M_RX_CMD                    (0x1 << 3)
-#define   I2CD_S_TX_CMD                    (0x1 << 2)
-#define   I2CD_M_TX_CMD                    (0x1 << 1)
-#define   I2CD_M_START_CMD                 (0x1)
-
-#define I2CD_DEV_ADDR_REG       0x18       /* Slave Device Address */
-#define I2CD_BUF_CTRL_REG       0x1c       /* Pool Buffer Control */
-#define I2CD_BYTE_BUF_REG       0x20       /* Transmit/Receive Byte Buffer */
-#define   I2CD_BYTE_BUF_TX_SHIFT           0
-#define   I2CD_BYTE_BUF_TX_MASK            0xff
-#define   I2CD_BYTE_BUF_RX_SHIFT           8
-#define   I2CD_BYTE_BUF_RX_MASK            0xff
-
-
-static inline bool aspeed_i2c_bus_is_master(AspeedI2CBus *bus)
-{
-    return bus->ctrl & I2CD_MASTER_EN;
-}
-
-static inline bool aspeed_i2c_bus_is_enabled(AspeedI2CBus *bus)
-{
-    return bus->ctrl & (I2CD_MASTER_EN | I2CD_SLAVE_EN);
-}
-
-static inline void aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus)
-{
-    bus->intr_status &= bus->intr_ctrl;
-    if (bus->intr_status) {
-        bus->controller->intr_status |= 1 << bus->id;
-        qemu_irq_raise(bus->controller->irq);
-    }
-}
-
-static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
-                                    unsigned size)
-{
-    AspeedI2CBus *bus = opaque;
-
-    switch (offset) {
-    case I2CD_FUN_CTRL_REG:
-        return bus->ctrl;
-    case I2CD_AC_TIMING_REG1:
-        return bus->timing[0];
-    case I2CD_AC_TIMING_REG2:
-        return bus->timing[1];
-    case I2CD_INTR_CTRL_REG:
-        return bus->intr_ctrl;
-    case I2CD_INTR_STS_REG:
-        return bus->intr_status;
-    case I2CD_BYTE_BUF_REG:
-        return bus->buf;
-    case I2CD_CMD_REG:
-        return bus->cmd | (i2c_bus_busy(bus->bus) << 16);
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
-        return -1;
-    }
-}
-
-static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
-{
-    bus->cmd |= value & 0xFFFF;
-    bus->intr_status = 0;
-
-    if (bus->cmd & I2CD_M_START_CMD) {
-        if (i2c_start_transfer(bus->bus, extract32(bus->buf, 1, 7),
-                               extract32(bus->buf, 0, 1))) {
-            bus->intr_status |= I2CD_INTR_TX_NAK;
-        } else {
-            bus->intr_status |= I2CD_INTR_TX_ACK;
-        }
-
-    } else if (bus->cmd & I2CD_M_TX_CMD) {
-        if (i2c_send(bus->bus, bus->buf)) {
-            bus->intr_status |= (I2CD_INTR_TX_NAK | I2CD_INTR_ABNORMAL);
-            i2c_end_transfer(bus->bus);
-        } else {
-            bus->intr_status |= I2CD_INTR_TX_ACK;
-        }
-
-    } else if (bus->cmd & I2CD_M_RX_CMD) {
-        int ret = i2c_recv(bus->bus);
-        if (ret < 0) {
-            qemu_log_mask(LOG_GUEST_ERROR, "%s: read failed\n", __func__);
-            ret = 0xff;
-        } else {
-            bus->intr_status |= I2CD_INTR_RX_DONE;
-        }
-        bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
-    }
-
-    if (bus->cmd & (I2CD_M_STOP_CMD | I2CD_M_S_RX_CMD_LAST)) {
-        if (!i2c_bus_busy(bus->bus)) {
-            bus->intr_status |= I2CD_INTR_ABNORMAL;
-        } else {
-            i2c_end_transfer(bus->bus);
-            bus->intr_status |= I2CD_INTR_NORMAL_STOP;
-        }
-    }
-
-    /* command is handled, reset it and check for interrupts  */
-    bus->cmd &= ~0xFFFF;
-    aspeed_i2c_bus_raise_interrupt(bus);
-}
-
-static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
-                                 uint64_t value, unsigned size)
-{
-    AspeedI2CBus *bus = opaque;
-
-    switch (offset) {
-    case I2CD_FUN_CTRL_REG:
-        if (value & I2CD_SLAVE_EN) {
-            qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
-                          __func__);
-            break;
-        }
-        bus->ctrl = value & 0x0071C3FF;
-        break;
-    case I2CD_AC_TIMING_REG1:
-        bus->timing[0] = value & 0xFFFFF0F;
-        break;
-    case I2CD_AC_TIMING_REG2:
-        bus->timing[1] = value & 0x7;
-        break;
-    case I2CD_INTR_CTRL_REG:
-        bus->intr_ctrl = value & 0x7FFF;
-        break;
-    case I2CD_INTR_STS_REG:
-        bus->intr_status &= ~(value & 0x7FFF);
-        bus->controller->intr_status &= ~(1 << bus->id);
-        qemu_irq_lower(bus->controller->irq);
-        break;
-    case I2CD_DEV_ADDR_REG:
-        qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
-                      __func__);
-        break;
-    case I2CD_BYTE_BUF_REG:
-        bus->buf = (value & I2CD_BYTE_BUF_TX_MASK) << I2CD_BYTE_BUF_TX_SHIFT;
-        break;
-    case I2CD_CMD_REG:
-        if (!aspeed_i2c_bus_is_enabled(bus)) {
-            break;
-        }
-
-        if (!aspeed_i2c_bus_is_master(bus)) {
-            qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
-                          __func__);
-            break;
-        }
-
-        aspeed_i2c_bus_handle_cmd(bus, value);
-        break;
-
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
-                      __func__, offset);
-    }
-}
-
-static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
-                                   unsigned size)
-{
-    AspeedI2CState *s = opaque;
-
-    switch (offset) {
-    case I2C_CTRL_STATUS:
-        return s->intr_status;
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
-                      __func__, offset);
-        break;
-    }
-
-    return -1;
-}
-
-static void aspeed_i2c_ctrl_write(void *opaque, hwaddr offset,
-                                  uint64_t value, unsigned size)
-{
-    switch (offset) {
-    case I2C_CTRL_STATUS:
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
-                      __func__, offset);
-        break;
-    }
-}
-
-static const MemoryRegionOps aspeed_i2c_bus_ops = {
-    .read = aspeed_i2c_bus_read,
-    .write = aspeed_i2c_bus_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static const MemoryRegionOps aspeed_i2c_ctrl_ops = {
-    .read = aspeed_i2c_ctrl_read,
-    .write = aspeed_i2c_ctrl_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static const VMStateDescription aspeed_i2c_bus_vmstate = {
-    .name = TYPE_ASPEED_I2C,
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT8(id, AspeedI2CBus),
-        VMSTATE_UINT32(ctrl, AspeedI2CBus),
-        VMSTATE_UINT32_ARRAY(timing, AspeedI2CBus, 2),
-        VMSTATE_UINT32(intr_ctrl, AspeedI2CBus),
-        VMSTATE_UINT32(intr_status, AspeedI2CBus),
-        VMSTATE_UINT32(cmd, AspeedI2CBus),
-        VMSTATE_UINT32(buf, AspeedI2CBus),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static const VMStateDescription aspeed_i2c_vmstate = {
-    .name = TYPE_ASPEED_I2C,
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT32(intr_status, AspeedI2CState),
-        VMSTATE_STRUCT_ARRAY(busses, AspeedI2CState,
-                             ASPEED_I2C_NR_BUSSES, 1, aspeed_i2c_bus_vmstate,
-                             AspeedI2CBus),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static void aspeed_i2c_reset(DeviceState *dev)
-{
-    int i;
-    AspeedI2CState *s = ASPEED_I2C(dev);
-
-    s->intr_status = 0;
-
-    for (i = 0; i < ASPEED_I2C_NR_BUSSES; i++) {
-        s->busses[i].intr_ctrl = 0;
-        s->busses[i].intr_status = 0;
-        s->busses[i].cmd = 0;
-        s->busses[i].buf = 0;
-        i2c_end_transfer(s->busses[i].bus);
-    }
-}
-
-/*
- * Address Definitions
- *
- *   0x000 ... 0x03F: Global Register
- *   0x040 ... 0x07F: Device 1
- *   0x080 ... 0x0BF: Device 2
- *   0x0C0 ... 0x0FF: Device 3
- *   0x100 ... 0x13F: Device 4
- *   0x140 ... 0x17F: Device 5
- *   0x180 ... 0x1BF: Device 6
- *   0x1C0 ... 0x1FF: Device 7
- *   0x200 ... 0x2FF: Buffer Pool  (unused in linux driver)
- *   0x300 ... 0x33F: Device 8
- *   0x340 ... 0x37F: Device 9
- *   0x380 ... 0x3BF: Device 10
- *   0x3C0 ... 0x3FF: Device 11
- *   0x400 ... 0x43F: Device 12
- *   0x440 ... 0x47F: Device 13
- *   0x480 ... 0x4BF: Device 14
- *   0x800 ... 0xFFF: Buffer Pool  (unused in linux driver)
- */
-static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
-{
-    int i;
-    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-    AspeedI2CState *s = ASPEED_I2C(dev);
-
-    sysbus_init_irq(sbd, &s->irq);
-    memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_i2c_ctrl_ops, s,
-                          "aspeed.i2c", 0x1000);
-    sysbus_init_mmio(sbd, &s->iomem);
-
-    for (i = 0; i < ASPEED_I2C_NR_BUSSES; i++) {
-        char name[16];
-        int offset = i < 7 ? 1 : 5;
-        snprintf(name, sizeof(name), "aspeed.i2c.%d", i);
-        s->busses[i].controller = s;
-        s->busses[i].id = i;
-        s->busses[i].bus = i2c_init_bus(dev, name);
-        memory_region_init_io(&s->busses[i].mr, OBJECT(dev),
-                              &aspeed_i2c_bus_ops, &s->busses[i], name, 0x40);
-        memory_region_add_subregion(&s->iomem, 0x40 * (i + offset),
-                                    &s->busses[i].mr);
-    }
-}
-
-static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-
-    dc->vmsd = &aspeed_i2c_vmstate;
-    dc->reset = aspeed_i2c_reset;
-    dc->realize = aspeed_i2c_realize;
-    dc->desc = "Aspeed I2C Controller";
-}
-
-static const TypeInfo aspeed_i2c_info = {
-    .name          = TYPE_ASPEED_I2C,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(AspeedI2CState),
-    .class_init    = aspeed_i2c_class_init,
-};
-
-static void aspeed_i2c_register_types(void)
-{
-    type_register_static(&aspeed_i2c_info);
-}
-
-type_init(aspeed_i2c_register_types)
-
-
-I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr)
-{
-    AspeedI2CState *s = ASPEED_I2C(dev);
-    I2CBus *bus = NULL;
-
-    if (busnr >= 0 && busnr < ASPEED_I2C_NR_BUSSES) {
-        bus = s->busses[busnr].bus;
-    }
-
-    return bus;
-}
index d3a2989..6ed2060 100644 (file)
@@ -210,14 +210,13 @@ static void bitbang_i2c_gpio_set(void *opaque, int irq, int level)
     }
 }
 
-static void gpio_i2c_init(Object *obj)
+static int gpio_i2c_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    GPIOI2CState *s = GPIO_I2C(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    GPIOI2CState *s = GPIO_I2C(dev);
     I2CBus *bus;
 
-    memory_region_init(&s->dummy_iomem, obj, "gpio_i2c", 0);
+    memory_region_init(&s->dummy_iomem, OBJECT(s), "gpio_i2c", 0);
     sysbus_init_mmio(sbd, &s->dummy_iomem);
 
     bus = i2c_init_bus(dev, "i2c");
@@ -225,12 +224,16 @@ static void gpio_i2c_init(Object *obj)
 
     qdev_init_gpio_in(dev, bitbang_i2c_gpio_set, 2);
     qdev_init_gpio_out(dev, &s->out, 1);
+
+    return 0;
 }
 
 static void gpio_i2c_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = gpio_i2c_init;
     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
     dc->desc = "Virtual GPIO to I2C bridge";
 }
@@ -239,7 +242,6 @@ static const TypeInfo gpio_i2c_info = {
     .name          = TYPE_GPIO_I2C,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(GPIOI2CState),
-    .instance_init = gpio_i2c_init,
     .class_init    = gpio_i2c_class_init,
 };
 
index 4afbe0b..ba22104 100644 (file)
 #include "qemu/osdep.h"
 #include "hw/i2c/i2c.h"
 
-typedef struct I2CNode I2CNode;
-
-struct I2CNode {
-    I2CSlave *elt;
-    QLIST_ENTRY(I2CNode) next;
-};
-
-#define I2C_BROADCAST 0x00
-
 struct I2CBus
 {
     BusState qbus;
-    QLIST_HEAD(, I2CNode) current_devs;
+    I2CSlave *current_dev;
+    I2CSlave *dev;
     uint8_t saved_address;
-    bool broadcast;
 };
 
 static Property i2c_props[] = {
@@ -45,14 +36,17 @@ static void i2c_bus_pre_save(void *opaque)
 {
     I2CBus *bus = opaque;
 
-    bus->saved_address = -1;
-    if (!QLIST_EMPTY(&bus->current_devs)) {
-        if (!bus->broadcast) {
-            bus->saved_address = QLIST_FIRST(&bus->current_devs)->elt->address;
-        } else {
-            bus->saved_address = I2C_BROADCAST;
-        }
-    }
+    bus->saved_address = bus->current_dev ? bus->current_dev->address : -1;
+}
+
+static int i2c_bus_post_load(void *opaque, int version_id)
+{
+    I2CBus *bus = opaque;
+
+    /* The bus is loaded before attached devices, so load and save the
+       current device id.  Devices will check themselves as loaded.  */
+    bus->current_dev = NULL;
+    return 0;
 }
 
 static const VMStateDescription vmstate_i2c_bus = {
@@ -60,6 +54,7 @@ static const VMStateDescription vmstate_i2c_bus = {
     .version_id = 1,
     .minimum_version_id = 1,
     .pre_save = i2c_bus_pre_save,
+    .post_load = i2c_bus_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_UINT8(saved_address, I2CBus),
         VMSTATE_END_OF_LIST()
@@ -72,7 +67,6 @@ I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
     I2CBus *bus;
 
     bus = I2C_BUS(qbus_create(TYPE_I2C_BUS, parent, name));
-    QLIST_INIT(&bus->current_devs);
     vmstate_register(NULL, -1, &vmstate_i2c_bus, bus);
     return bus;
 }
@@ -85,7 +79,7 @@ void i2c_set_slave_address(I2CSlave *dev, uint8_t address)
 /* Return nonzero if bus is busy.  */
 int i2c_bus_busy(I2CBus *bus)
 {
-    return !QLIST_EMPTY(&bus->current_devs);
+    return bus->current_dev != NULL;
 }
 
 /* Returns non-zero if the address is not valid.  */
@@ -93,127 +87,95 @@ int i2c_bus_busy(I2CBus *bus)
 int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
 {
     BusChild *kid;
+    I2CSlave *slave = NULL;
     I2CSlaveClass *sc;
-    I2CNode *node;
-
-    if (address == I2C_BROADCAST) {
-        /*
-         * This is a broadcast, the current_devs will be all the devices of the
-         * bus.
-         */
-        bus->broadcast = true;
-    }
 
     QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
         DeviceState *qdev = kid->child;
         I2CSlave *candidate = I2C_SLAVE(qdev);
-        if ((candidate->address == address) || (bus->broadcast)) {
-            node = g_malloc(sizeof(struct I2CNode));
-            node->elt = candidate;
-            QLIST_INSERT_HEAD(&bus->current_devs, node, next);
-            if (!bus->broadcast) {
-                break;
-            }
+        if (candidate->address == address) {
+            slave = candidate;
+            break;
         }
     }
 
-    if (QLIST_EMPTY(&bus->current_devs)) {
+    if (!slave) {
         return 1;
     }
 
-    QLIST_FOREACH(node, &bus->current_devs, next) {
-        sc = I2C_SLAVE_GET_CLASS(node->elt);
-        /* If the bus is already busy, assume this is a repeated
-           start condition.  */
-        if (sc->event) {
-            sc->event(node->elt, recv ? I2C_START_RECV : I2C_START_SEND);
-        }
+    sc = I2C_SLAVE_GET_CLASS(slave);
+    /* If the bus is already busy, assume this is a repeated
+       start condition.  */
+    bus->current_dev = slave;
+    if (sc->event) {
+        sc->event(slave, recv ? I2C_START_RECV : I2C_START_SEND);
     }
     return 0;
 }
 
 void i2c_end_transfer(I2CBus *bus)
 {
+    I2CSlave *dev = bus->current_dev;
     I2CSlaveClass *sc;
-    I2CNode *node, *next;
 
-    if (QLIST_EMPTY(&bus->current_devs)) {
+    if (!dev) {
         return;
     }
 
-    QLIST_FOREACH_SAFE(node, &bus->current_devs, next, next) {
-        sc = I2C_SLAVE_GET_CLASS(node->elt);
-        if (sc->event) {
-            sc->event(node->elt, I2C_FINISH);
-        }
-        QLIST_REMOVE(node, next);
-        g_free(node);
+    sc = I2C_SLAVE_GET_CLASS(dev);
+    if (sc->event) {
+        sc->event(dev, I2C_FINISH);
     }
-    bus->broadcast = false;
+
+    bus->current_dev = NULL;
 }
 
-int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send)
+int i2c_send(I2CBus *bus, uint8_t data)
 {
+    I2CSlave *dev = bus->current_dev;
     I2CSlaveClass *sc;
-    I2CNode *node;
-    int ret = 0;
-
-    if (send) {
-        QLIST_FOREACH(node, &bus->current_devs, next) {
-            sc = I2C_SLAVE_GET_CLASS(node->elt);
-            if (sc->send) {
-                ret = ret || sc->send(node->elt, *data);
-            } else {
-                ret = -1;
-            }
-        }
-        return ret ? -1 : 0;
-    } else {
-        if ((QLIST_EMPTY(&bus->current_devs)) || (bus->broadcast)) {
-            return -1;
-        }
 
-        sc = I2C_SLAVE_GET_CLASS(QLIST_FIRST(&bus->current_devs)->elt);
-        if (sc->recv) {
-            ret = sc->recv(QLIST_FIRST(&bus->current_devs)->elt);
-            if (ret < 0) {
-                return ret;
-            } else {
-                *data = ret;
-                return 0;
-            }
-        }
+    if (!dev) {
         return -1;
     }
-}
 
-int i2c_send(I2CBus *bus, uint8_t data)
-{
-    return i2c_send_recv(bus, &data, true);
+    sc = I2C_SLAVE_GET_CLASS(dev);
+    if (sc->send) {
+        return sc->send(dev, data);
+    }
+
+    return -1;
 }
 
 int i2c_recv(I2CBus *bus)
 {
-    uint8_t data;
-    int ret = i2c_send_recv(bus, &data, false);
+    I2CSlave *dev = bus->current_dev;
+    I2CSlaveClass *sc;
+
+    if (!dev) {
+        return -1;
+    }
 
-    return ret < 0 ? ret : data;
+    sc = I2C_SLAVE_GET_CLASS(dev);
+    if (sc->recv) {
+        return sc->recv(dev);
+    }
+
+    return -1;
 }
 
 void i2c_nack(I2CBus *bus)
 {
+    I2CSlave *dev = bus->current_dev;
     I2CSlaveClass *sc;
-    I2CNode *node;
 
-    if (QLIST_EMPTY(&bus->current_devs)) {
+    if (!dev) {
         return;
     }
 
-    QLIST_FOREACH(node, &bus->current_devs, next) {
-        sc = I2C_SLAVE_GET_CLASS(node->elt);
-        if (sc->event) {
-            sc->event(node->elt, I2C_NACK);
-        }
+    sc = I2C_SLAVE_GET_CLASS(dev);
+    if (sc->event) {
+        sc->event(dev, I2C_NACK);
     }
 }
 
@@ -221,14 +183,9 @@ static int i2c_slave_post_load(void *opaque, int version_id)
 {
     I2CSlave *dev = opaque;
     I2CBus *bus;
-    I2CNode *node;
-
     bus = I2C_BUS(qdev_get_parent_bus(DEVICE(dev)));
-    if ((bus->saved_address == dev->address) ||
-        (bus->saved_address == I2C_BROADCAST)) {
-        node = g_malloc(sizeof(struct I2CNode));
-        node->elt = dev;
-        QLIST_INSERT_HEAD(&bus->current_devs, node, next);
+    if (bus->saved_address == dev->address) {
+        bus->current_dev = dev;
     }
     return 0;
 }
index c96fa7d..8c2a2c1 100644 (file)
@@ -299,32 +299,33 @@ static void exynos4210_i2c_reset(DeviceState *d)
     s->scl_free = true;
 }
 
-static void exynos4210_i2c_init(Object *obj)
+static int exynos4210_i2c_realize(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    Exynos4210I2CState *s = EXYNOS4_I2C(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    Exynos4210I2CState *s = EXYNOS4_I2C(dev);
 
-    memory_region_init_io(&s->iomem, obj, &exynos4210_i2c_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &exynos4210_i2c_ops, s,
                           TYPE_EXYNOS4_I2C, EXYNOS4_I2C_MEM_SIZE);
     sysbus_init_mmio(sbd, &s->iomem);
     sysbus_init_irq(sbd, &s->irq);
     s->bus = i2c_init_bus(dev, "i2c");
+    return 0;
 }
 
 static void exynos4210_i2c_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *sbdc = SYS_BUS_DEVICE_CLASS(klass);
 
     dc->vmsd = &exynos4210_i2c_vmstate;
     dc->reset = exynos4210_i2c_reset;
+    sbdc->init = exynos4210_i2c_realize;
 }
 
 static const TypeInfo exynos4210_i2c_type_info = {
     .name = TYPE_EXYNOS4_I2C,
     .parent = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(Exynos4210I2CState),
-    .instance_init = exynos4210_i2c_init,
     .class_init = exynos4210_i2c_class_init,
 };
 
diff --git a/hw/i2c/i2c-ddc.c b/hw/i2c/i2c-ddc.c
deleted file mode 100644 (file)
index 1227212..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-/* A simple I2C slave for returning monitor EDID data via DDC.
- *
- * Copyright (c) 2011 Linaro Limited
- * Written by Peter Maydell
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "hw/i2c/i2c.h"
-#include "hw/i2c/i2c-ddc.h"
-
-#ifndef DEBUG_I2CDDC
-#define DEBUG_I2CDDC 0
-#endif
-
-#define DPRINTF(fmt, ...) do {                                                 \
-    if (DEBUG_I2CDDC) {                                                        \
-        qemu_log("i2c-ddc: " fmt , ## __VA_ARGS__);                            \
-    }                                                                          \
-} while (0);
-
-/* Structure defining a monitor's characteristics in a
- * readable format: this should be passed to build_edid_blob()
- * to convert it into the 128 byte binary EDID blob.
- * Not all bits of the EDID are customisable here.
- */
-struct EDIDData {
-    char manuf_id[3]; /* three upper case letters */
-    uint16_t product_id;
-    uint32_t serial_no;
-    uint8_t manuf_week;
-    int manuf_year;
-    uint8_t h_cm;
-    uint8_t v_cm;
-    uint8_t gamma;
-    char monitor_name[14];
-    char serial_no_string[14];
-    /* Range limits */
-    uint8_t vmin; /* Hz */
-    uint8_t vmax; /* Hz */
-    uint8_t hmin; /* kHz */
-    uint8_t hmax; /* kHz */
-    uint8_t pixclock; /* MHz / 10 */
-    uint8_t timing_data[18];
-};
-
-typedef struct EDIDData EDIDData;
-
-/* EDID data for a simple LCD monitor */
-static const EDIDData lcd_edid = {
-    /* The manuf_id ought really to be an assigned EISA ID */
-    .manuf_id = "QMU",
-    .product_id = 0,
-    .serial_no = 1,
-    .manuf_week = 1,
-    .manuf_year = 2011,
-    .h_cm = 40,
-    .v_cm = 30,
-    .gamma = 0x78,
-    .monitor_name = "QEMU monitor",
-    .serial_no_string = "1",
-    .vmin = 40,
-    .vmax = 120,
-    .hmin = 30,
-    .hmax = 100,
-    .pixclock = 18,
-    .timing_data = {
-        /* Borrowed from a 21" LCD */
-        0x48, 0x3f, 0x40, 0x30, 0x62, 0xb0, 0x32, 0x40, 0x40,
-        0xc0, 0x13, 0x00, 0x98, 0x32, 0x11, 0x00, 0x00, 0x1e
-    }
-};
-
-static uint8_t manuf_char_to_int(char c)
-{
-    return (c - 'A') & 0x1f;
-}
-
-static void write_ascii_descriptor_block(uint8_t *descblob, uint8_t blocktype,
-                                         const char *string)
-{
-    /* Write an EDID Descriptor Block of the "ascii string" type */
-    int i;
-    descblob[0] = descblob[1] = descblob[2] = descblob[4] = 0;
-    descblob[3] = blocktype;
-    /* The rest is 13 bytes of ASCII; if less then the rest must
-     * be filled with newline then spaces
-     */
-    for (i = 5; i < 19; i++) {
-        descblob[i] = string[i - 5];
-        if (!descblob[i]) {
-            break;
-        }
-    }
-    if (i < 19) {
-        descblob[i++] = '\n';
-    }
-    for ( ; i < 19; i++) {
-        descblob[i] = ' ';
-    }
-}
-
-static void write_range_limits_descriptor(const EDIDData *edid,
-                                          uint8_t *descblob)
-{
-    int i;
-    descblob[0] = descblob[1] = descblob[2] = descblob[4] = 0;
-    descblob[3] = 0xfd;
-    descblob[5] = edid->vmin;
-    descblob[6] = edid->vmax;
-    descblob[7] = edid->hmin;
-    descblob[8] = edid->hmax;
-    descblob[9] = edid->pixclock;
-    descblob[10] = 0;
-    descblob[11] = 0xa;
-    for (i = 12; i < 19; i++) {
-        descblob[i] = 0x20;
-    }
-}
-
-static void build_edid_blob(const EDIDData *edid, uint8_t *blob)
-{
-    /* Write an EDID 1.3 format blob (128 bytes) based
-     * on the EDIDData structure.
-     */
-    int i;
-    uint8_t cksum;
-
-    /* 00-07 : header */
-    blob[0] = blob[7] = 0;
-    for (i = 1 ; i < 7; i++) {
-        blob[i] = 0xff;
-    }
-    /* 08-09 : manufacturer ID */
-    blob[8] = (manuf_char_to_int(edid->manuf_id[0]) << 2)
-        | (manuf_char_to_int(edid->manuf_id[1]) >> 3);
-    blob[9] = (manuf_char_to_int(edid->manuf_id[1]) << 5)
-        | manuf_char_to_int(edid->manuf_id[2]);
-    /* 10-11 : product ID code */
-    blob[10] = edid->product_id;
-    blob[11] = edid->product_id >> 8;
-    blob[12] = edid->serial_no;
-    blob[13] = edid->serial_no >> 8;
-    blob[14] = edid->serial_no >> 16;
-    blob[15] = edid->serial_no >> 24;
-    /* 16 : week of manufacture */
-    blob[16] = edid->manuf_week;
-    /* 17 : year of manufacture - 1990 */
-    blob[17] = edid->manuf_year - 1990;
-    /* 18, 19 : EDID version and revision */
-    blob[18] = 1;
-    blob[19] = 3;
-    /* 20 - 24 : basic display parameters */
-    /* We are always a digital display */
-    blob[20] = 0x80;
-    /* 21, 22 : max h/v size in cm */
-    blob[21] = edid->h_cm;
-    blob[22] = edid->v_cm;
-    /* 23 : gamma (divide by 100 then add 1 for actual value) */
-    blob[23] = edid->gamma;
-    /* 24 feature support: no power management, RGB, preferred timing mode,
-     * standard colour space
-     */
-    blob[24] = 0x0e;
-    /* 25 - 34 : chromaticity coordinates. These are the
-     * standard sRGB chromaticity values
-     */
-    blob[25] = 0xee;
-    blob[26] = 0x91;
-    blob[27] = 0xa3;
-    blob[28] = 0x54;
-    blob[29] = 0x4c;
-    blob[30] = 0x99;
-    blob[31] = 0x26;
-    blob[32] = 0x0f;
-    blob[33] = 0x50;
-    blob[34] = 0x54;
-    /* 35, 36 : Established timings: claim to support everything */
-    blob[35] = blob[36] = 0xff;
-    /* 37 : manufacturer's reserved timing: none */
-    blob[37] = 0;
-    /* 38 - 53 : standard timing identification
-     * don't claim anything beyond what the 'established timings'
-     * already provide. Unused slots must be (0x1, 0x1)
-     */
-    for (i = 38; i < 54; i++) {
-        blob[i] = 0x1;
-    }
-    /* 54 - 71 : descriptor block 1 : must be preferred timing data */
-    memcpy(blob + 54, edid->timing_data, 18);
-    /* 72 - 89, 90 - 107, 108 - 125 : descriptor block 2, 3, 4
-     * Order not important, but we must have a monitor name and a
-     * range limits descriptor.
-     */
-    write_range_limits_descriptor(edid, blob + 72);
-    write_ascii_descriptor_block(blob + 90, 0xfc, edid->monitor_name);
-    write_ascii_descriptor_block(blob + 108, 0xff, edid->serial_no_string);
-
-    /* 126 : extension flag */
-    blob[126] = 0;
-
-    cksum = 0;
-    for (i = 0; i < 127; i++) {
-        cksum += blob[i];
-    }
-    /* 127 : checksum */
-    blob[127] = -cksum;
-    if (DEBUG_I2CDDC) {
-        qemu_hexdump((char *)blob, stdout, "", 128);
-    }
-}
-
-static void i2c_ddc_reset(DeviceState *ds)
-{
-    I2CDDCState *s = I2CDDC(ds);
-
-    s->firstbyte = false;
-    s->reg = 0;
-}
-
-static void i2c_ddc_event(I2CSlave *i2c, enum i2c_event event)
-{
-    I2CDDCState *s = I2CDDC(i2c);
-
-    if (event == I2C_START_SEND) {
-        s->firstbyte = true;
-    }
-}
-
-static int i2c_ddc_rx(I2CSlave *i2c)
-{
-    I2CDDCState *s = I2CDDC(i2c);
-
-    int value;
-    value = s->edid_blob[s->reg];
-    s->reg++;
-    return value;
-}
-
-static int i2c_ddc_tx(I2CSlave *i2c, uint8_t data)
-{
-    I2CDDCState *s = I2CDDC(i2c);
-    if (s->firstbyte) {
-        s->reg = data;
-        s->firstbyte = false;
-        DPRINTF("[EDID] Written new pointer: %u\n", data);
-        return 1;
-    }
-
-    /* Ignore all writes */
-    s->reg++;
-    return 1;
-}
-
-static void i2c_ddc_init(Object *obj)
-{
-    I2CDDCState *s = I2CDDC(obj);
-    build_edid_blob(&lcd_edid, s->edid_blob);
-}
-
-static const VMStateDescription vmstate_i2c_ddc = {
-    .name = TYPE_I2CDDC,
-    .version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_BOOL(firstbyte, I2CDDCState),
-        VMSTATE_UINT8(reg, I2CDDCState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static void i2c_ddc_class_init(ObjectClass *oc, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(oc);
-    I2CSlaveClass *isc = I2C_SLAVE_CLASS(oc);
-
-    dc->reset = i2c_ddc_reset;
-    dc->vmsd = &vmstate_i2c_ddc;
-    isc->event = i2c_ddc_event;
-    isc->recv = i2c_ddc_rx;
-    isc->send = i2c_ddc_tx;
-}
-
-static TypeInfo i2c_ddc_info = {
-    .name = TYPE_I2CDDC,
-    .parent = TYPE_I2C_SLAVE,
-    .instance_size = sizeof(I2CDDCState),
-    .instance_init = i2c_ddc_init,
-    .class_init = i2c_ddc_class_init
-};
-
-static void ddc_register_devices(void)
-{
-    type_register_static(&i2c_ddc_info);
-}
-
-type_init(ddc_register_devices);
index 37e5a62..e19d4fa 100644 (file)
@@ -21,7 +21,6 @@
 #include "qemu/osdep.h"
 #include "hw/i2c/imx_i2c.h"
 #include "hw/i2c/i2c.h"
-#include "qemu/log.h"
 
 #ifndef DEBUG_IMX_I2C
 #define DEBUG_IMX_I2C 0
index f7c92ea..67fbbff 100644 (file)
@@ -22,7 +22,6 @@
 #include "hw/arm/omap.h"
 #include "hw/sysbus.h"
 #include "qemu/error-report.h"
-#include "qapi/error.h"
 
 #define TYPE_OMAP_I2C "omap_i2c"
 #define OMAP_I2C(obj) OBJECT_CHECK(OMAPI2CState, (obj), TYPE_OMAP_I2C)
@@ -446,35 +445,29 @@ static const MemoryRegionOps omap_i2c_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void omap_i2c_init(Object *obj)
-{
-    DeviceState *dev = DEVICE(obj);
-    OMAPI2CState *s = OMAP_I2C(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
-
-    sysbus_init_irq(sbd, &s->irq);
-    sysbus_init_irq(sbd, &s->drq[0]);
-    sysbus_init_irq(sbd, &s->drq[1]);
-    sysbus_init_mmio(sbd, &s->iomem);
-    s->bus = i2c_init_bus(dev, NULL);
-}
-
-static void omap_i2c_realize(DeviceState *dev, Error **errp)
+static int omap_i2c_init(SysBusDevice *sbd)
 {
+    DeviceState *dev = DEVICE(sbd);
     OMAPI2CState *s = OMAP_I2C(dev);
 
-    memory_region_init_io(&s->iomem, OBJECT(dev), &omap_i2c_ops, s, "omap.i2c",
-                          (s->revision < OMAP2_INTR_REV) ? 0x800 : 0x1000);
-
     if (!s->fclk) {
-        error_setg(errp, "omap_i2c: fclk not connected");
-        return;
+        error_report("omap_i2c: fclk not connected");
+        return -1;
     }
     if (s->revision >= OMAP2_INTR_REV && !s->iclk) {
         /* Note that OMAP1 doesn't have a separate interface clock */
-        error_setg(errp, "omap_i2c: iclk not connected");
-        return;
+        error_report("omap_i2c: iclk not connected");
+        return -1;
     }
+
+    sysbus_init_irq(sbd, &s->irq);
+    sysbus_init_irq(sbd, &s->drq[0]);
+    sysbus_init_irq(sbd, &s->drq[1]);
+    memory_region_init_io(&s->iomem, OBJECT(s), &omap_i2c_ops, s, "omap.i2c",
+                          (s->revision < OMAP2_INTR_REV) ? 0x800 : 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+    s->bus = i2c_init_bus(dev, NULL);
+    return 0;
 }
 
 static Property omap_i2c_properties[] = {
@@ -487,19 +480,18 @@ static Property omap_i2c_properties[] = {
 static void omap_i2c_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+    k->init = omap_i2c_init;
     dc->props = omap_i2c_properties;
     dc->reset = omap_i2c_reset;
     /* Reason: pointer properties "iclk", "fclk" */
     dc->cannot_instantiate_with_device_add_yet = true;
-    dc->realize = omap_i2c_realize;
 }
 
 static const TypeInfo omap_i2c_info = {
     .name = TYPE_OMAP_I2C,
     .parent = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(OMAPI2CState),
-    .instance_init = omap_i2c_init,
     .class_init = omap_i2c_class_init,
 };
 
index 48fab22..498f03e 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "hw/i386/ich9.h"
 
+#define TYPE_ICH9_SMB_DEVICE "ICH9 SMB"
 #define ICH9_SMB_DEVICE(obj) \
      OBJECT_CHECK(ICH9SMBState, (obj), TYPE_ICH9_SMB_DEVICE)
 
index da9f298..fee3bc7 100644 (file)
@@ -24,7 +24,6 @@
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
 #include "bitbang_i2c.h"
-#include "qemu/log.h"
 
 #define TYPE_VERSATILE_I2C "versatile_i2c"
 #define VERSATILE_I2C(obj) \
@@ -79,25 +78,32 @@ static const MemoryRegionOps versatile_i2c_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void versatile_i2c_init(Object *obj)
+static int versatile_i2c_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    VersatileI2CState *s = VERSATILE_I2C(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    VersatileI2CState *s = VERSATILE_I2C(dev);
     I2CBus *bus;
 
     bus = i2c_init_bus(dev, "i2c");
     s->bitbang = bitbang_i2c_init(bus);
-    memory_region_init_io(&s->iomem, obj, &versatile_i2c_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &versatile_i2c_ops, s,
                           "versatile_i2c", 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
+    return 0;
+}
+
+static void versatile_i2c_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = versatile_i2c_init;
 }
 
 static const TypeInfo versatile_i2c_info = {
     .name          = TYPE_VERSATILE_I2C,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(VersatileI2CState),
-    .instance_init = versatile_i2c_init,
+    .class_init    = versatile_i2c_class_init,
 };
 
 static void versatile_i2c_register_types(void)
index 90e94ff..b52d5b8 100644 (file)
@@ -2,7 +2,7 @@ obj-$(CONFIG_KVM) += kvm/
 obj-y += multiboot.o
 obj-y += pc.o pc_piix.o pc_q35.o
 obj-y += pc_sysfw.o
-obj-y += x86-iommu.o intel_iommu.o
+obj-y += intel_iommu.o
 obj-$(CONFIG_XEN) += ../xenpv/ xen/
 
 obj-y += kvmvapic.o
index a26a4bb..6477003 100644 (file)
@@ -23,6 +23,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "acpi-build.h"
+#include <glib.h>
 #include "qemu-common.h"
 #include "qemu/bitmap.h"
 #include "qemu/error-report.h"
@@ -33,7 +34,6 @@
 #include "hw/timer/hpet.h"
 #include "hw/acpi/acpi-defs.h"
 #include "hw/acpi/acpi.h"
-#include "hw/acpi/cpu.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/acpi/bios-linker-loader.h"
 #include "hw/loader.h"
@@ -44,7 +44,6 @@
 #include "hw/acpi/tpm.h"
 #include "sysemu/tpm_backend.h"
 #include "hw/timer/mc146818rtc_regs.h"
-#include "sysemu/numa.h"
 
 /* Supported chipsets: */
 #include "hw/acpi/piix4.h"
 #include "hw/i386/ich9.h"
 #include "hw/pci/pci_bus.h"
 #include "hw/pci-host/q35.h"
-#include "hw/i386/x86-iommu.h"
+#include "hw/i386/intel_iommu.h"
 #include "hw/timer/hpet.h"
 
 #include "hw/acpi/aml-build.h"
 
 #include "qapi/qmp/qint.h"
 #include "qom/qom-qobject.h"
-#include "hw/i386/x86-iommu.h"
-
-#include "hw/acpi/ipmi.h"
 
 /* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
  * -M pc-i440fx-2.0.  Even if the actual amount of AML generated grows
@@ -81,9 +77,6 @@
 #define ACPI_BUILD_DPRINTF(fmt, ...)
 #endif
 
-/* Default IOAPIC ID */
-#define ACPI_BUILD_IOAPIC_ID 0x0
-
 typedef struct AcpiMcfgInfo {
     uint64_t mcfg_base;
     uint32_t mcfg_size;
@@ -101,6 +94,7 @@ typedef struct AcpiPmInfo {
     uint32_t gpe0_blk_len;
     uint32_t io_base;
     uint16_t cpu_hp_io_base;
+    uint16_t cpu_hp_io_len;
     uint16_t mem_hp_io_base;
     uint16_t mem_hp_io_len;
     uint16_t pcihp_io_base;
@@ -148,6 +142,7 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
     }
     assert(obj);
 
+    pm->cpu_hp_io_len = ACPI_GPE_PROC_LEN;
     pm->mem_hp_io_base = ACPI_MEMORY_HOTPLUG_BASE;
     pm->mem_hp_io_len = ACPI_MEMORY_HOTPLUG_IO_LEN;
 
@@ -233,27 +228,26 @@ static Object *acpi_get_i386_pci_host(void)
     return OBJECT(host);
 }
 
-static void acpi_get_pci_holes(Range *hole, Range *hole64)
+static void acpi_get_pci_info(PcPciInfo *info)
 {
     Object *pci_host;
 
+
     pci_host = acpi_get_i386_pci_host();
     g_assert(pci_host);
 
-    range_set_bounds1(hole,
-                      object_property_get_int(pci_host,
+    info->w32.begin = object_property_get_int(pci_host,
                                               PCI_HOST_PROP_PCI_HOLE_START,
-                                              NULL),
-                      object_property_get_int(pci_host,
-                                              PCI_HOST_PROP_PCI_HOLE_END,
-                                              NULL));
-    range_set_bounds1(hole64,
-                      object_property_get_int(pci_host,
+                                              NULL);
+    info->w32.end = object_property_get_int(pci_host,
+                                            PCI_HOST_PROP_PCI_HOLE_END,
+                                            NULL);
+    info->w64.begin = object_property_get_int(pci_host,
                                               PCI_HOST_PROP_PCI_HOLE64_START,
-                                              NULL),
-                      object_property_get_int(pci_host,
-                                              PCI_HOST_PROP_PCI_HOLE64_END,
-                                              NULL));
+                                              NULL);
+    info->w64.end = object_property_get_int(pci_host,
+                                            PCI_HOST_PROP_PCI_HOLE64_END,
+                                            NULL);
 }
 
 #define ACPI_PORT_SMI_CMD           0x00b2 /* TODO: this is APM_CNT_IOPORT */
@@ -268,7 +262,7 @@ static void acpi_align_size(GArray *blob, unsigned align)
 
 /* FACS */
 static void
-build_facs(GArray *table_data, BIOSLinker *linker)
+build_facs(GArray *table_data, GArray *linker)
 {
     AcpiFacsDescriptorRev1 *facs = acpi_data_push(table_data, sizeof *facs);
     memcpy(&facs->signature, "FACS", 4);
@@ -313,61 +307,38 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
 
 /* FADT */
 static void
-build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
-           unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
+build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
+           unsigned facs, unsigned dsdt,
            const char *oem_id, const char *oem_table_id)
 {
     AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
-    unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
-    unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
 
+    fadt->firmware_ctrl = cpu_to_le32(facs);
     /* FACS address to be filled by Guest linker */
-    bios_linker_loader_add_pointer(linker,
-        ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->firmware_ctrl),
-        ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
+    bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+                                   ACPI_BUILD_TABLE_FILE,
+                                   table_data, &fadt->firmware_ctrl,
+                                   sizeof fadt->firmware_ctrl);
 
+    fadt->dsdt = cpu_to_le32(dsdt);
     /* DSDT address to be filled by Guest linker */
+    bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+                                   ACPI_BUILD_TABLE_FILE,
+                                   table_data, &fadt->dsdt,
+                                   sizeof fadt->dsdt);
+
     fadt_setup(fadt, pm);
-    bios_linker_loader_add_pointer(linker,
-        ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
-        ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
 
     build_header(linker, table_data,
                  (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
 }
 
-void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
-                       CPUArchIdList *apic_ids, GArray *entry)
-{
-    int apic_id;
-    AcpiMadtProcessorApic *apic = acpi_data_push(entry, sizeof *apic);
-
-    apic_id = apic_ids->cpus[uid].arch_id;
-    apic->type = ACPI_APIC_PROCESSOR;
-    apic->length = sizeof(*apic);
-    apic->processor_id = uid;
-    apic->local_apic_id = apic_id;
-    if (apic_ids->cpus[uid].cpu != NULL) {
-        apic->flags = cpu_to_le32(1);
-    } else {
-        /* ACPI spec says that LAPIC entry for non present
-         * CPU may be omitted from MADT or it must be marked
-         * as disabled. However omitting non present CPU from
-         * MADT breaks hotplug on linux. So possible CPUs
-         * should be put in MADT but kept disabled.
-         */
-        apic->flags = cpu_to_le32(0);
-    }
-}
-
 static void
-build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms)
+build_madt(GArray *table_data, GArray *linker, PCMachineState *pcms)
 {
     MachineClass *mc = MACHINE_GET_CLASS(pcms);
     CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(pcms));
     int madt_start = table_data->len;
-    AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(pcms->acpi_dev);
-    AcpiDeviceIf *adev = ACPI_DEVICE_IF(pcms->acpi_dev);
 
     AcpiMultipleApicTable *madt;
     AcpiMadtIoApic *io_apic;
@@ -380,13 +351,31 @@ build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms)
     madt->flags = cpu_to_le32(1);
 
     for (i = 0; i < apic_ids->len; i++) {
-        adevc->madt_cpu(adev, i, apic_ids, table_data);
+        AcpiMadtProcessorApic *apic = acpi_data_push(table_data, sizeof *apic);
+        int apic_id = apic_ids->cpus[i].arch_id;
+
+        apic->type = ACPI_APIC_PROCESSOR;
+        apic->length = sizeof(*apic);
+        apic->processor_id = apic_id;
+        apic->local_apic_id = apic_id;
+        if (apic_ids->cpus[i].cpu != NULL) {
+            apic->flags = cpu_to_le32(1);
+        } else {
+            /* ACPI spec says that LAPIC entry for non present
+             * CPU may be omitted from MADT or it must be marked
+             * as disabled. However omitting non present CPU from
+             * MADT breaks hotplug on linux. So possible CPUs
+             * should be put in MADT but kept disabled.
+             */
+            apic->flags = cpu_to_le32(0);
+        }
     }
     g_free(apic_ids);
 
     io_apic = acpi_data_push(table_data, sizeof *io_apic);
     io_apic->type = ACPI_APIC_IO;
     io_apic->length = sizeof(*io_apic);
+#define ACPI_BUILD_IOAPIC_ID 0x0
     io_apic->io_apic_id = ACPI_BUILD_IOAPIC_ID;
     io_apic->address = cpu_to_le32(IO_APIC_DEFAULT_ADDRESS);
     io_apic->interrupt = cpu_to_le32(0);
@@ -600,10 +589,6 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
         QLIST_FOREACH(sec, &bus->child, sibling) {
             int32_t devfn = sec->parent_dev->devfn;
 
-            if (pci_bus_is_root(sec) || pci_bus_is_express(sec)) {
-                continue;
-            }
-
             aml_append(method, aml_name("^S%.02X.PCNT", devfn));
         }
     }
@@ -751,27 +736,6 @@ static void crs_range_free(gpointer data)
     g_free(entry);
 }
 
-typedef struct CrsRangeSet {
-    GPtrArray *io_ranges;
-    GPtrArray *mem_ranges;
-    GPtrArray *mem_64bit_ranges;
- } CrsRangeSet;
-
-static void crs_range_set_init(CrsRangeSet *range_set)
-{
-    range_set->io_ranges = g_ptr_array_new_with_free_func(crs_range_free);
-    range_set->mem_ranges = g_ptr_array_new_with_free_func(crs_range_free);
-    range_set->mem_64bit_ranges =
-            g_ptr_array_new_with_free_func(crs_range_free);
-}
-
-static void crs_range_set_free(CrsRangeSet *range_set)
-{
-    g_ptr_array_free(range_set->io_ranges, true);
-    g_ptr_array_free(range_set->mem_ranges, true);
-    g_ptr_array_free(range_set->mem_64bit_ranges, true);
-}
-
 static gint crs_range_compare(gconstpointer a, gconstpointer b)
 {
      CrsRangeEntry *entry_a = *(CrsRangeEntry **)a;
@@ -856,17 +820,18 @@ static void crs_range_merge(GPtrArray *range)
     g_ptr_array_free(tmp, true);
 }
 
-static Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set)
+static Aml *build_crs(PCIHostState *host,
+                      GPtrArray *io_ranges, GPtrArray *mem_ranges)
 {
     Aml *crs = aml_resource_template();
-    CrsRangeSet temp_range_set;
+    GPtrArray *host_io_ranges = g_ptr_array_new_with_free_func(crs_range_free);
+    GPtrArray *host_mem_ranges = g_ptr_array_new_with_free_func(crs_range_free);
     CrsRangeEntry *entry;
     uint8_t max_bus = pci_bus_num(host->bus);
     uint8_t type;
     int devfn;
     int i;
 
-    crs_range_set_init(&temp_range_set);
     for (devfn = 0; devfn < ARRAY_SIZE(host->bus->devices); devfn++) {
         uint64_t range_base, range_limit;
         PCIDevice *dev = host->bus->devices[devfn];
@@ -890,11 +855,9 @@ static Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set)
             }
 
             if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
-                crs_range_insert(temp_range_set.io_ranges,
-                                 range_base, range_limit);
+                crs_range_insert(host_io_ranges, range_base, range_limit);
             } else { /* "memory" */
-                crs_range_insert(temp_range_set.mem_ranges,
-                                 range_base, range_limit);
+                crs_range_insert(host_mem_ranges, range_base, range_limit);
             }
         }
 
@@ -913,8 +876,7 @@ static Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set)
              * that do not support multiple root buses
              */
             if (range_base && range_base <= range_limit) {
-                crs_range_insert(temp_range_set.io_ranges,
-                                 range_base, range_limit);
+                crs_range_insert(host_io_ranges, range_base, range_limit);
             }
 
             range_base =
@@ -927,14 +889,7 @@ static Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set)
              * that do not support multiple root buses
              */
             if (range_base && range_base <= range_limit) {
-                uint64_t length = range_limit - range_base + 1;
-                if (range_limit <= UINT32_MAX && length <= UINT32_MAX) {
-                    crs_range_insert(temp_range_set.mem_ranges,
-                                     range_base, range_limit);
-                } else {
-                    crs_range_insert(temp_range_set.mem_64bit_ranges,
-                                     range_base, range_limit);
-                }
+                crs_range_insert(host_mem_ranges, range_base, range_limit);
             }
 
             range_base =
@@ -947,55 +902,35 @@ static Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set)
              * that do not support multiple root buses
              */
             if (range_base && range_base <= range_limit) {
-                uint64_t length = range_limit - range_base + 1;
-                if (range_limit <= UINT32_MAX && length <= UINT32_MAX) {
-                    crs_range_insert(temp_range_set.mem_ranges,
-                                     range_base, range_limit);
-                } else {
-                    crs_range_insert(temp_range_set.mem_64bit_ranges,
-                                     range_base, range_limit);
-                }
+                crs_range_insert(host_mem_ranges, range_base, range_limit);
             }
         }
     }
 
-    crs_range_merge(temp_range_set.io_ranges);
-    for (i = 0; i < temp_range_set.io_ranges->len; i++) {
-        entry = g_ptr_array_index(temp_range_set.io_ranges, i);
+    crs_range_merge(host_io_ranges);
+    for (i = 0; i < host_io_ranges->len; i++) {
+        entry = g_ptr_array_index(host_io_ranges, i);
         aml_append(crs,
                    aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED,
                                AML_POS_DECODE, AML_ENTIRE_RANGE,
                                0, entry->base, entry->limit, 0,
                                entry->limit - entry->base + 1));
-        crs_range_insert(range_set->io_ranges, entry->base, entry->limit);
+        crs_range_insert(io_ranges, entry->base, entry->limit);
     }
+    g_ptr_array_free(host_io_ranges, true);
 
-    crs_range_merge(temp_range_set.mem_ranges);
-    for (i = 0; i < temp_range_set.mem_ranges->len; i++) {
-        entry = g_ptr_array_index(temp_range_set.mem_ranges, i);
+    crs_range_merge(host_mem_ranges);
+    for (i = 0; i < host_mem_ranges->len; i++) {
+        entry = g_ptr_array_index(host_mem_ranges, i);
         aml_append(crs,
                    aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED,
                                     AML_MAX_FIXED, AML_NON_CACHEABLE,
                                     AML_READ_WRITE,
                                     0, entry->base, entry->limit, 0,
                                     entry->limit - entry->base + 1));
-        crs_range_insert(range_set->mem_ranges, entry->base, entry->limit);
-    }
-
-    crs_range_merge(temp_range_set.mem_64bit_ranges);
-    for (i = 0; i < temp_range_set.mem_64bit_ranges->len; i++) {
-        entry = g_ptr_array_index(temp_range_set.mem_64bit_ranges, i);
-        aml_append(crs,
-                   aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED,
-                                    AML_MAX_FIXED, AML_NON_CACHEABLE,
-                                    AML_READ_WRITE,
-                                    0, entry->base, entry->limit, 0,
-                                    entry->limit - entry->base + 1));
-        crs_range_insert(range_set->mem_64bit_ranges,
-                         entry->base, entry->limit);
+        crs_range_insert(mem_ranges, entry->base, entry->limit);
     }
-
-    crs_range_set_free(&temp_range_set);
+    g_ptr_array_free(host_mem_ranges, true);
 
     aml_append(crs,
         aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
@@ -1008,6 +943,114 @@ static Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set)
     return crs;
 }
 
+static void build_processor_devices(Aml *sb_scope, MachineState *machine,
+                                    AcpiPmInfo *pm)
+{
+    int i, apic_idx;
+    Aml *dev;
+    Aml *crs;
+    Aml *pkg;
+    Aml *field;
+    Aml *ifctx;
+    Aml *method;
+    MachineClass *mc = MACHINE_GET_CLASS(machine);
+    CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine);
+    PCMachineState *pcms = PC_MACHINE(machine);
+
+    /* The current AML generator can cover the APIC ID range [0..255],
+     * inclusive, for VCPU hotplug. */
+    QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256);
+    g_assert(pcms->apic_id_limit <= ACPI_CPU_HOTPLUG_ID_LIMIT);
+
+    /* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */
+    dev = aml_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE));
+    aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A06")));
+    aml_append(dev,
+        aml_name_decl("_UID", aml_string("CPU Hotplug resources"))
+    );
+    /* device present, functioning, decoding, not shown in UI */
+    aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+    crs = aml_resource_template();
+    aml_append(crs,
+        aml_io(AML_DECODE16, pm->cpu_hp_io_base, pm->cpu_hp_io_base, 1,
+               pm->cpu_hp_io_len)
+    );
+    aml_append(dev, aml_name_decl("_CRS", crs));
+    aml_append(sb_scope, dev);
+    /* declare CPU hotplug MMIO region and PRS field to access it */
+    aml_append(sb_scope, aml_operation_region(
+        "PRST", AML_SYSTEM_IO, aml_int(pm->cpu_hp_io_base), pm->cpu_hp_io_len));
+    field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
+    aml_append(field, aml_named_field("PRS", 256));
+    aml_append(sb_scope, field);
+
+    /* build Processor object for each processor */
+    for (i = 0; i < apic_ids->len; i++) {
+        int apic_id = apic_ids->cpus[i].arch_id;
+
+        assert(apic_id < ACPI_CPU_HOTPLUG_ID_LIMIT);
+
+        dev = aml_processor(apic_id, 0, 0, "CP%.02X", apic_id);
+
+        method = aml_method("_MAT", 0, AML_NOTSERIALIZED);
+        aml_append(method,
+            aml_return(aml_call1(CPU_MAT_METHOD, aml_int(apic_id))));
+        aml_append(dev, method);
+
+        method = aml_method("_STA", 0, AML_NOTSERIALIZED);
+        aml_append(method,
+            aml_return(aml_call1(CPU_STATUS_METHOD, aml_int(apic_id))));
+        aml_append(dev, method);
+
+        method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
+        aml_append(method,
+            aml_return(aml_call2(CPU_EJECT_METHOD, aml_int(apic_id),
+                aml_arg(0)))
+        );
+        aml_append(dev, method);
+
+        aml_append(sb_scope, dev);
+    }
+
+    /* build this code:
+     *   Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}
+     */
+    /* Arg0 = Processor ID = APIC ID */
+    method = aml_method(AML_NOTIFY_METHOD, 2, AML_NOTSERIALIZED);
+    for (i = 0; i < apic_ids->len; i++) {
+        int apic_id = apic_ids->cpus[i].arch_id;
+
+        ifctx = aml_if(aml_equal(aml_arg(0), aml_int(apic_id)));
+        aml_append(ifctx,
+            aml_notify(aml_name("CP%.02X", apic_id), aml_arg(1))
+        );
+        aml_append(method, ifctx);
+    }
+    aml_append(sb_scope, method);
+
+    /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
+     *
+     * Note: The ability to create variable-sized packages was first
+     * introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages
+     * ith up to 255 elements. Windows guests up to win2k8 fail when
+     * VarPackageOp is used.
+     */
+    pkg = pcms->apic_id_limit <= 255 ? aml_package(pcms->apic_id_limit) :
+                                       aml_varpackage(pcms->apic_id_limit);
+
+    for (i = 0, apic_idx = 0; i < apic_ids->len; i++) {
+        int apic_id = apic_ids->cpus[i].arch_id;
+
+        for (; apic_idx < apic_id; apic_idx++) {
+            aml_append(pkg, aml_int(0));
+        }
+        aml_append(pkg, aml_int(apic_ids->cpus[i].cpu ? 1 : 0));
+        apic_idx = apic_id + 1;
+    }
+    aml_append(sb_scope, aml_name_decl(CPU_ON_BITMAP, pkg));
+    g_free(apic_ids);
+}
+
 static void build_memory_devices(Aml *sb_scope, int nr_mem,
                                  uint16_t io_base, uint16_t io_len)
 {
@@ -1405,10 +1448,8 @@ static Aml *build_com_device_aml(uint8_t uid)
 static void build_isa_devices_aml(Aml *table)
 {
     ISADevice *fdc = pc_find_fdc0();
-    bool ambiguous;
 
     Aml *scope = aml_scope("_SB.PCI0.ISA");
-    Object *obj = object_resolve_path_type("", TYPE_ISA_BUS, &ambiguous);
 
     aml_append(scope, build_rtc_device_aml());
     aml_append(scope, build_kbd_device_aml());
@@ -1420,14 +1461,6 @@ static void build_isa_devices_aml(Aml *table)
     aml_append(scope, build_com_device_aml(1));
     aml_append(scope, build_com_device_aml(2));
 
-    if (ambiguous) {
-        error_report("Multiple ISA busses, unable to define IPMI ACPI data");
-    } else if (!obj) {
-        error_report("No ISA bus, unable to define IPMI ACPI data");
-    } else {
-        build_acpi_ipmi_devices(scope, BUS(obj));
-    }
-
     aml_append(table, scope);
 }
 
@@ -1946,15 +1979,15 @@ static Aml *build_q35_osc_method(void)
 }
 
 static void
-build_dsdt(GArray *table_data, BIOSLinker *linker,
+build_dsdt(GArray *table_data, GArray *linker,
            AcpiPmInfo *pm, AcpiMiscInfo *misc,
-           Range *pci_hole, Range *pci_hole64, MachineState *machine)
+           PcPciInfo *pci, MachineState *machine)
 {
     CrsRangeEntry *entry;
     Aml *dsdt, *sb_scope, *scope, *dev, *method, *field, *pkg, *crs;
-    CrsRangeSet crs_range_set;
+    GPtrArray *mem_ranges = g_ptr_array_new_with_free_func(crs_range_free);
+    GPtrArray *io_ranges = g_ptr_array_new_with_free_func(crs_range_free);
     PCMachineState *pcms = PC_MACHINE(machine);
-    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
     uint32_t nr_mem = machine->ram_slots;
     int root_bus_limit = 0xFF;
     PCIBus *bus = NULL;
@@ -2010,15 +2043,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
         build_q35_pci0_int(dsdt);
     }
 
-    if (pcmc->legacy_cpu_hotplug) {
-        build_legacy_cpu_hotplug_aml(dsdt, machine, pm->cpu_hp_io_base);
-    } else {
-        CPUHotplugFeatures opts = {
-            .apci_1_compatible = true, .has_legacy_cphp = true
-        };
-        build_cpus_aml(dsdt, machine, opts, pm->cpu_hp_io_base,
-                       "\\_SB.PCI0", "\\_GPE._E02");
-    }
+    build_cpu_hotplug_aml(dsdt);
     build_memory_hotplug_aml(dsdt, nr_mem, pm->mem_hp_io_base,
                              pm->mem_hp_io_len);
 
@@ -2026,6 +2051,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
     {
         aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006")));
 
+        aml_append(scope, aml_method("_L00", 0, AML_NOTSERIALIZED));
+
         if (misc->is_piix4) {
             method = aml_method("_E01", 0, AML_NOTSERIALIZED);
             aml_append(method,
@@ -2033,15 +2060,33 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
             aml_append(method, aml_call0("\\_SB.PCI0.PCNT"));
             aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK")));
             aml_append(scope, method);
+        } else {
+            aml_append(scope, aml_method("_L01", 0, AML_NOTSERIALIZED));
         }
 
+        method = aml_method("_E02", 0, AML_NOTSERIALIZED);
+        aml_append(method, aml_call0("\\_SB." CPU_SCAN_METHOD));
+        aml_append(scope, method);
+
         method = aml_method("_E03", 0, AML_NOTSERIALIZED);
         aml_append(method, aml_call0(MEMORY_HOTPLUG_HANDLER_PATH));
         aml_append(scope, method);
+
+        aml_append(scope, aml_method("_L04", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L05", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L06", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L07", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L08", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L09", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L0A", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L0B", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L0C", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L0D", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L0E", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L0F", 0, AML_NOTSERIALIZED));
     }
     aml_append(dsdt, scope);
 
-    crs_range_set_init(&crs_range_set);
     bus = PC_MACHINE(machine)->bus;
     if (bus) {
         QLIST_FOREACH(bus, &bus->child, sibling) {
@@ -2068,7 +2113,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
             }
 
             aml_append(dev, build_prt(false));
-            crs = build_crs(PCI_HOST_BRIDGE(BUS(bus)->parent), &crs_range_set);
+            crs = build_crs(PCI_HOST_BRIDGE(BUS(bus)->parent),
+                            io_ranges, mem_ranges);
             aml_append(dev, aml_name_decl("_CRS", crs));
             aml_append(scope, dev);
             aml_append(dsdt, scope);
@@ -2089,9 +2135,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
                     AML_POS_DECODE, AML_ENTIRE_RANGE,
                     0x0000, 0x0000, 0x0CF7, 0x0000, 0x0CF8));
 
-    crs_replace_with_free_ranges(crs_range_set.io_ranges, 0x0D00, 0xFFFF);
-    for (i = 0; i < crs_range_set.io_ranges->len; i++) {
-        entry = g_ptr_array_index(crs_range_set.io_ranges, i);
+    crs_replace_with_free_ranges(io_ranges, 0x0D00, 0xFFFF);
+    for (i = 0; i < io_ranges->len; i++) {
+        entry = g_ptr_array_index(io_ranges, i);
         aml_append(crs,
             aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED,
                         AML_POS_DECODE, AML_ENTIRE_RANGE,
@@ -2104,11 +2150,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
                          AML_CACHEABLE, AML_READ_WRITE,
                          0, 0x000A0000, 0x000BFFFF, 0, 0x00020000));
 
-    crs_replace_with_free_ranges(crs_range_set.mem_ranges,
-                                 range_lob(pci_hole),
-                                 range_upb(pci_hole));
-    for (i = 0; i < crs_range_set.mem_ranges->len; i++) {
-        entry = g_ptr_array_index(crs_range_set.mem_ranges, i);
+    crs_replace_with_free_ranges(mem_ranges, pci->w32.begin, pci->w32.end - 1);
+    for (i = 0; i < mem_ranges->len; i++) {
+        entry = g_ptr_array_index(mem_ranges, i);
         aml_append(crs,
             aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
                              AML_NON_CACHEABLE, AML_READ_WRITE,
@@ -2116,19 +2160,12 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
                              0, entry->limit - entry->base + 1));
     }
 
-    if (!range_is_empty(pci_hole64)) {
-        crs_replace_with_free_ranges(crs_range_set.mem_64bit_ranges,
-                                     range_lob(pci_hole64),
-                                     range_upb(pci_hole64));
-        for (i = 0; i < crs_range_set.mem_64bit_ranges->len; i++) {
-            entry = g_ptr_array_index(crs_range_set.mem_64bit_ranges, i);
-            aml_append(crs,
-                       aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED,
-                                        AML_MAX_FIXED,
-                                        AML_CACHEABLE, AML_READ_WRITE,
-                                        0, entry->base, entry->limit,
-                                        0, entry->limit - entry->base + 1));
-        }
+    if (pci->w64.begin) {
+        aml_append(crs,
+            aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
+                             AML_CACHEABLE, AML_READ_WRITE,
+                             0, pci->w64.begin, pci->w64.end - 1, 0,
+                             pci->w64.end - pci->w64.begin));
     }
 
     if (misc->tpm_version != TPM_VERSION_UNSPEC) {
@@ -2150,7 +2187,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
     aml_append(dev, aml_name_decl("_CRS", crs));
     aml_append(scope, dev);
 
-    crs_range_set_free(&crs_range_set);
+    g_ptr_array_free(io_ranges, true);
+    g_ptr_array_free(mem_ranges, true);
 
     /* reserve PCIHP resources */
     if (pm->pcihp_io_len) {
@@ -2284,6 +2322,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 
     sb_scope = aml_scope("\\_SB");
     {
+        build_processor_devices(sb_scope, machine, pm);
+
         build_memory_devices(sb_scope, nr_mem, pm->mem_hp_io_base,
                              pm->mem_hp_io_len);
 
@@ -2333,7 +2373,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 }
 
 static void
-build_hpet(GArray *table_data, BIOSLinker *linker)
+build_hpet(GArray *table_data, GArray *linker)
 {
     Acpi20Hpet *hpet;
 
@@ -2348,31 +2388,32 @@ build_hpet(GArray *table_data, BIOSLinker *linker)
 }
 
 static void
-build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog)
+build_tpm_tcpa(GArray *table_data, GArray *linker, GArray *tcpalog)
 {
     Acpi20Tcpa *tcpa = acpi_data_push(table_data, sizeof *tcpa);
-    unsigned log_addr_size = sizeof(tcpa->log_area_start_address);
-    unsigned log_addr_offset =
-        (char *)&tcpa->log_area_start_address - table_data->data;
+    uint64_t log_area_start_address = acpi_data_len(tcpalog);
 
     tcpa->platform_class = cpu_to_le16(TPM_TCPA_ACPI_CLASS_CLIENT);
     tcpa->log_area_minimum_length = cpu_to_le32(TPM_LOG_AREA_MINIMUM_SIZE);
-    acpi_data_push(tcpalog, le32_to_cpu(tcpa->log_area_minimum_length));
+    tcpa->log_area_start_address = cpu_to_le64(log_area_start_address);
 
-    bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, tcpalog, 1,
+    bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, 1,
                              false /* high memory */);
 
     /* log area start address to be filled by Guest linker */
-    bios_linker_loader_add_pointer(linker,
-        ACPI_BUILD_TABLE_FILE, log_addr_offset, log_addr_size,
-        ACPI_BUILD_TPMLOG_FILE, 0);
+    bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+                                   ACPI_BUILD_TPMLOG_FILE,
+                                   table_data, &tcpa->log_area_start_address,
+                                   sizeof(tcpa->log_area_start_address));
 
     build_header(linker, table_data,
                  (void *)tcpa, "TCPA", sizeof(*tcpa), 2, NULL, NULL);
+
+    acpi_data_push(tcpalog, TPM_LOG_AREA_MINIMUM_SIZE);
 }
 
 static void
-build_tpm2(GArray *table_data, BIOSLinker *linker)
+build_tpm2(GArray *table_data, GArray *linker)
 {
     Acpi20TPM2 *tpm2_ptr;
 
@@ -2386,14 +2427,35 @@ build_tpm2(GArray *table_data, BIOSLinker *linker)
                  (void *)tpm2_ptr, "TPM2", sizeof(*tpm2_ptr), 4, NULL, NULL);
 }
 
+typedef enum {
+    MEM_AFFINITY_NOFLAGS      = 0,
+    MEM_AFFINITY_ENABLED      = (1 << 0),
+    MEM_AFFINITY_HOTPLUGGABLE = (1 << 1),
+    MEM_AFFINITY_NON_VOLATILE = (1 << 2),
+} MemoryAffinityFlags;
+
+static void
+acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
+                       uint64_t len, int node, MemoryAffinityFlags flags)
+{
+    numamem->type = ACPI_SRAT_MEMORY;
+    numamem->length = sizeof(*numamem);
+    memset(numamem->proximity, 0, 4);
+    numamem->proximity[0] = node;
+    numamem->flags = cpu_to_le32(flags);
+    numamem->base_addr = cpu_to_le64(base);
+    numamem->range_length = cpu_to_le64(len);
+}
+
 static void
-build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
+build_srat(GArray *table_data, GArray *linker, MachineState *machine)
 {
     AcpiSystemResourceAffinityTable *srat;
     AcpiSratProcessorAffinity *core;
     AcpiSratMemoryAffinity *numamem;
 
     int i;
+    uint64_t curnode;
     int srat_start, numa_start, slots;
     uint64_t mem_len, mem_base, next_base;
     MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -2409,19 +2471,14 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
     srat->reserved1 = cpu_to_le32(1);
 
     for (i = 0; i < apic_ids->len; i++) {
-        int j;
         int apic_id = apic_ids->cpus[i].arch_id;
 
         core = acpi_data_push(table_data, sizeof *core);
-        core->type = ACPI_SRAT_PROCESSOR_APIC;
+        core->type = ACPI_SRAT_PROCESSOR;
         core->length = sizeof(*core);
         core->local_apic_id = apic_id;
-        for (j = 0; j < nb_numa_nodes; j++) {
-            if (test_bit(i, numa_info[j].node_cpu)) {
-                core->proximity_lo = j;
-                break;
-            }
-        }
+        curnode = pcms->node_cpu[apic_id];
+        core->proximity_lo = curnode;
         memset(core->proximity_hi, 0, 3);
         core->local_sapic_eid = 0;
         core->flags = cpu_to_le32(1);
@@ -2435,7 +2492,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
     numa_start = table_data->len;
 
     numamem = acpi_data_push(table_data, sizeof *numamem);
-    build_srat_memory(numamem, 0, 640 * 1024, 0, MEM_AFFINITY_ENABLED);
+    acpi_build_srat_memory(numamem, 0, 640*1024, 0, MEM_AFFINITY_ENABLED);
     next_base = 1024 * 1024;
     for (i = 1; i < pcms->numa_nodes + 1; ++i) {
         mem_base = next_base;
@@ -2451,21 +2508,21 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
             mem_len -= next_base - pcms->below_4g_mem_size;
             if (mem_len > 0) {
                 numamem = acpi_data_push(table_data, sizeof *numamem);
-                build_srat_memory(numamem, mem_base, mem_len, i - 1,
-                                  MEM_AFFINITY_ENABLED);
+                acpi_build_srat_memory(numamem, mem_base, mem_len, i - 1,
+                                       MEM_AFFINITY_ENABLED);
             }
             mem_base = 1ULL << 32;
             mem_len = next_base - pcms->below_4g_mem_size;
             next_base += (1ULL << 32) - pcms->below_4g_mem_size;
         }
         numamem = acpi_data_push(table_data, sizeof *numamem);
-        build_srat_memory(numamem, mem_base, mem_len, i - 1,
-                          MEM_AFFINITY_ENABLED);
+        acpi_build_srat_memory(numamem, mem_base, mem_len, i - 1,
+                               MEM_AFFINITY_ENABLED);
     }
     slots = (table_data->len - numa_start) / sizeof *numamem;
     for (; slots < pcms->numa_nodes + 2; slots++) {
         numamem = acpi_data_push(table_data, sizeof *numamem);
-        build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
+        acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
     }
 
     /*
@@ -2475,9 +2532,10 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
      */
     if (hotplugabble_address_space_size) {
         numamem = acpi_data_push(table_data, sizeof *numamem);
-        build_srat_memory(numamem, pcms->hotplug_memory.base,
-                          hotplugabble_address_space_size, 0,
-                          MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
+        acpi_build_srat_memory(numamem, pcms->hotplug_memory.base,
+                               hotplugabble_address_space_size, 0,
+                               MEM_AFFINITY_HOTPLUGGABLE |
+                               MEM_AFFINITY_ENABLED);
     }
 
     build_header(linker, table_data,
@@ -2488,7 +2546,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
 }
 
 static void
-build_mcfg_q35(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info)
+build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
 {
     AcpiTableMcfg *mcfg;
     const char *sig;
@@ -2516,75 +2574,51 @@ build_mcfg_q35(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info)
     build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL, NULL);
 }
 
-/*
- * VT-d spec 8.1 DMA Remapping Reporting Structure
- * (version Oct. 2014 or later)
- */
 static void
-build_dmar_q35(GArray *table_data, BIOSLinker *linker)
+build_dmar_q35(GArray *table_data, GArray *linker)
 {
     int dmar_start = table_data->len;
 
     AcpiTableDmar *dmar;
     AcpiDmarHardwareUnit *drhd;
-    uint8_t dmar_flags = 0;
-    X86IOMMUState *iommu = x86_iommu_get_default();
-    AcpiDmarDeviceScope *scope = NULL;
-    /* Root complex IOAPIC use one path[0] only */
-    size_t ioapic_scope_size = sizeof(*scope) + sizeof(scope->path[0]);
-
-    assert(iommu);
-    if (iommu->intr_supported) {
-        dmar_flags |= 0x1;      /* Flags: 0x1: INT_REMAP */
-    }
 
     dmar = acpi_data_push(table_data, sizeof(*dmar));
     dmar->host_address_width = VTD_HOST_ADDRESS_WIDTH - 1;
-    dmar->flags = dmar_flags;
+    dmar->flags = 0;    /* No intr_remap for now */
 
     /* DMAR Remapping Hardware Unit Definition structure */
-    drhd = acpi_data_push(table_data, sizeof(*drhd) + ioapic_scope_size);
+    drhd = acpi_data_push(table_data, sizeof(*drhd));
     drhd->type = cpu_to_le16(ACPI_DMAR_TYPE_HARDWARE_UNIT);
-    drhd->length = cpu_to_le16(sizeof(*drhd) + ioapic_scope_size);
+    drhd->length = cpu_to_le16(sizeof(*drhd));   /* No device scope now */
     drhd->flags = ACPI_DMAR_INCLUDE_PCI_ALL;
     drhd->pci_segment = cpu_to_le16(0);
     drhd->address = cpu_to_le64(Q35_HOST_BRIDGE_IOMMU_ADDR);
 
-    /* Scope definition for the root-complex IOAPIC. See VT-d spec
-     * 8.3.1 (version Oct. 2014 or later). */
-    scope = &drhd->scope[0];
-    scope->entry_type = 0x03;   /* Type: 0x03 for IOAPIC */
-    scope->length = ioapic_scope_size;
-    scope->enumeration_id = ACPI_BUILD_IOAPIC_ID;
-    scope->bus = Q35_PSEUDO_BUS_PLATFORM;
-    scope->path[0] = cpu_to_le16(Q35_PSEUDO_DEVFN_IOAPIC);
-
     build_header(linker, table_data, (void *)(table_data->data + dmar_start),
                  "DMAR", table_data->len - dmar_start, 1, NULL, NULL);
 }
 
 static GArray *
-build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
+build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
 {
     AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
-    unsigned rsdt_pa_size = sizeof(rsdp->rsdt_physical_address);
-    unsigned rsdt_pa_offset =
-        (char *)&rsdp->rsdt_physical_address - rsdp_table->data;
 
-    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,
+    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16,
                              true /* fseg memory */);
 
     memcpy(&rsdp->signature, "RSD PTR ", 8);
     memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, 6);
+    rsdp->rsdt_physical_address = cpu_to_le32(rsdt);
     /* Address to be filled by Guest linker */
-    bios_linker_loader_add_pointer(linker,
-        ACPI_BUILD_RSDP_FILE, rsdt_pa_offset, rsdt_pa_size,
-        ACPI_BUILD_TABLE_FILE, rsdt_tbl_offset);
-
+    bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
+                                   ACPI_BUILD_TABLE_FILE,
+                                   rsdp_table, &rsdp->rsdt_physical_address,
+                                   sizeof rsdp->rsdt_physical_address);
+    rsdp->checksum = 0;
     /* Checksum to be filled by Guest linker */
     bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
-        (char *)rsdp - rsdp_table->data, sizeof *rsdp,
-        (char *)&rsdp->checksum - rsdp_table->data);
+                                    rsdp_table, rsdp, sizeof *rsdp,
+                                    &rsdp->checksum);
 
     return rsdp_table;
 }
@@ -2624,7 +2658,12 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
 
 static bool acpi_has_iommu(void)
 {
-    return !!x86_iommu_get_default();
+    bool ambiguous;
+    Object *intel_iommu;
+
+    intel_iommu = object_resolve_path_type("", TYPE_INTEL_IOMMU_DEVICE,
+                                           &ambiguous);
+    return intel_iommu && !ambiguous;
 }
 
 static
@@ -2637,7 +2676,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
     AcpiPmInfo pm;
     AcpiMiscInfo misc;
     AcpiMcfgInfo mcfg;
-    Range pci_hole, pci_hole64;
+    PcPciInfo pci;
     uint8_t *u;
     size_t aml_len = 0;
     GArray *tables_blob = tables->table_data;
@@ -2645,15 +2684,14 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
 
     acpi_get_pm_info(&pm);
     acpi_get_misc_info(&misc);
-    acpi_get_pci_holes(&pci_hole, &pci_hole64);
+    acpi_get_pci_info(&pci);
     acpi_get_slic_oem(&slic_oem);
 
     table_offsets = g_array_new(false, true /* clear */,
                                         sizeof(uint32_t));
     ACPI_BUILD_DPRINTF("init ACPI tables\n");
 
-    bios_linker_loader_alloc(tables->linker,
-                             ACPI_BUILD_TABLE_FILE, tables_blob,
+    bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
                              64 /* Ensure FACS is aligned */,
                              false /* high memory */);
 
@@ -2667,8 +2705,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
 
     /* DSDT is pointed to by FADT */
     dsdt = tables_blob->len;
-    build_dsdt(tables_blob, tables->linker, &pm, &misc,
-               &pci_hole, &pci_hole64, machine);
+    build_dsdt(tables_blob, tables->linker, &pm, &misc, &pci, machine);
 
     /* Count the size of the DSDT and SSDT, we will need it for legacy
      * sizing of ACPI tables.
@@ -2711,8 +2748,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
         build_dmar_q35(tables_blob, tables->linker);
     }
     if (pcms->acpi_nvdimm_state.is_enabled) {
-        nvdimm_build_acpi(table_offsets, tables_blob, tables->linker,
-                          pcms->acpi_nvdimm_state.dsm_mem);
+        nvdimm_build_acpi(table_offsets, tables_blob, tables->linker);
     }
 
     /* Add tables supplied by user (if any) */
@@ -2775,7 +2811,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
         acpi_align_size(tables_blob, ACPI_BUILD_TABLE_SIZE);
     }
 
-    acpi_align_size(tables->linker->cmd_blob, ACPI_BUILD_ALIGN_SIZE);
+    acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE);
 
     /* Cleanup memory that's no longer used. */
     g_array_free(table_offsets, true);
@@ -2815,7 +2851,7 @@ static void acpi_build_update(void *build_opaque)
         acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
     }
 
-    acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob);
+    acpi_ram_update(build_state->linker_mr, tables.linker);
     acpi_build_tables_cleanup(&tables, true);
 }
 
@@ -2879,8 +2915,7 @@ void acpi_setup(void)
     assert(build_state->table_mr != NULL);
 
     build_state->linker_mr =
-        acpi_add_rom_blob(build_state, tables.linker->cmd_blob,
-                          "etc/table-loader", 0);
+        acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);
 
     fw_cfg_add_file(pcms->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
                     tables.tcpalog->data, acpi_data_len(tables.tcpalog));
index 28c31a2..347718f 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "qemu/error-report.h"
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
 #include "intel_iommu_internal.h"
 #include "hw/pci/pci.h"
-#include "hw/pci/pci_bus.h"
-#include "hw/i386/pc.h"
-#include "hw/boards.h"
-#include "hw/i386/x86-iommu.h"
-#include "hw/pci-host/q35.h"
-#include "sysemu/kvm.h"
 
 /*#define DEBUG_INTEL_IOMMU*/
 #ifdef DEBUG_INTEL_IOMMU
 enum {
     DEBUG_GENERAL, DEBUG_CSR, DEBUG_INV, DEBUG_MMU, DEBUG_FLOG,
-    DEBUG_CACHE, DEBUG_IR,
+    DEBUG_CACHE,
 };
 #define VTD_DBGBIT(x)   (1 << DEBUG_##x)
 static int vtd_dbgflags = VTD_DBGBIT(GENERAL) | VTD_DBGBIT(CSR);
@@ -197,7 +190,7 @@ static void vtd_reset_context_cache(IntelIOMMUState *s)
 
     VTD_DPRINTF(CACHE, "global context_cache_gen=1");
     while (g_hash_table_iter_next (&bus_it, NULL, (void**)&vtd_bus)) {
-        for (devfn_it = 0; devfn_it < X86_IOMMU_PCI_DEVFN_MAX; ++devfn_it) {
+        for (devfn_it = 0; devfn_it < VTD_PCI_DEVFN_MAX; ++devfn_it) {
             vtd_as = vtd_bus->dev_as[devfn_it];
             if (!vtd_as) {
                 continue;
@@ -906,27 +899,6 @@ static void vtd_root_table_setup(IntelIOMMUState *s)
                 (s->root_extended ? "(extended)" : ""));
 }
 
-static void vtd_iec_notify_all(IntelIOMMUState *s, bool global,
-                               uint32_t index, uint32_t mask)
-{
-    x86_iommu_iec_notify_all(X86_IOMMU_DEVICE(s), global, index, mask);
-}
-
-static void vtd_interrupt_remap_table_setup(IntelIOMMUState *s)
-{
-    uint64_t value = 0;
-    value = vtd_get_quad_raw(s, DMAR_IRTA_REG);
-    s->intr_size = 1UL << ((value & VTD_IRTA_SIZE_MASK) + 1);
-    s->intr_root = value & VTD_IRTA_ADDR_MASK;
-    s->intr_eime = value & VTD_IRTA_EIME;
-
-    /* Notify global invalidation */
-    vtd_iec_notify_all(s, true, 0, 0);
-
-    VTD_DPRINTF(CSR, "int remap table addr 0x%"PRIx64 " size %"PRIu32,
-                s->intr_root, s->intr_size);
-}
-
 static void vtd_context_global_invalidate(IntelIOMMUState *s)
 {
     s->context_cache_gen++;
@@ -990,7 +962,7 @@ static void vtd_context_device_invalidate(IntelIOMMUState *s,
     vtd_bus = vtd_find_as_from_bus_num(s, VTD_SID_TO_BUS(source_id));
     if (vtd_bus) {
         devfn = VTD_SID_TO_DEVFN(source_id);
-        for (devfn_it = 0; devfn_it < X86_IOMMU_PCI_DEVFN_MAX; ++devfn_it) {
+        for (devfn_it = 0; devfn_it < VTD_PCI_DEVFN_MAX; ++devfn_it) {
             vtd_as = vtd_bus->dev_as[devfn_it];
             if (vtd_as && ((devfn_it & mask) == (devfn & mask))) {
                 VTD_DPRINTF(INV, "invalidate context-cahce of devfn 0x%"PRIx16,
@@ -1165,16 +1137,6 @@ static void vtd_handle_gcmd_srtp(IntelIOMMUState *s)
     vtd_set_clear_mask_long(s, DMAR_GSTS_REG, 0, VTD_GSTS_RTPS);
 }
 
-/* Set Interrupt Remap Table Pointer */
-static void vtd_handle_gcmd_sirtp(IntelIOMMUState *s)
-{
-    VTD_DPRINTF(CSR, "set Interrupt Remap Table Pointer");
-
-    vtd_interrupt_remap_table_setup(s);
-    /* Ok - report back to driver */
-    vtd_set_clear_mask_long(s, DMAR_GSTS_REG, 0, VTD_GSTS_IRTPS);
-}
-
 /* Handle Translation Enable/Disable */
 static void vtd_handle_gcmd_te(IntelIOMMUState *s, bool en)
 {
@@ -1194,22 +1156,6 @@ static void vtd_handle_gcmd_te(IntelIOMMUState *s, bool en)
     }
 }
 
-/* Handle Interrupt Remap Enable/Disable */
-static void vtd_handle_gcmd_ire(IntelIOMMUState *s, bool en)
-{
-    VTD_DPRINTF(CSR, "Interrupt Remap Enable %s", (en ? "on" : "off"));
-
-    if (en) {
-        s->intr_enabled = true;
-        /* Ok - report back to driver */
-        vtd_set_clear_mask_long(s, DMAR_GSTS_REG, 0, VTD_GSTS_IRES);
-    } else {
-        s->intr_enabled = false;
-        /* Ok - report back to driver */
-        vtd_set_clear_mask_long(s, DMAR_GSTS_REG, VTD_GSTS_IRES, 0);
-    }
-}
-
 /* Handle write to Global Command Register */
 static void vtd_handle_gcmd_write(IntelIOMMUState *s)
 {
@@ -1230,14 +1176,6 @@ static void vtd_handle_gcmd_write(IntelIOMMUState *s)
         /* Queued Invalidation Enable */
         vtd_handle_gcmd_qie(s, val & VTD_GCMD_QIE);
     }
-    if (val & VTD_GCMD_SIRTP) {
-        /* Set/update the interrupt remapping root-table pointer */
-        vtd_handle_gcmd_sirtp(s);
-    }
-    if (changed & VTD_GCMD_IRE) {
-        /* Interrupt remap enable/disable */
-        vtd_handle_gcmd_ire(s, val & VTD_GCMD_IRE);
-    }
 }
 
 /* Handle write to Context Command Register */
@@ -1423,21 +1361,6 @@ static bool vtd_process_iotlb_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc)
     return true;
 }
 
-static bool vtd_process_inv_iec_desc(IntelIOMMUState *s,
-                                     VTDInvDesc *inv_desc)
-{
-    VTD_DPRINTF(INV, "inv ir glob %d index %d mask %d",
-                inv_desc->iec.granularity,
-                inv_desc->iec.index,
-                inv_desc->iec.index_mask);
-
-    vtd_iec_notify_all(s, !inv_desc->iec.granularity,
-                       inv_desc->iec.index,
-                       inv_desc->iec.index_mask);
-
-    return true;
-}
-
 static bool vtd_process_inv_desc(IntelIOMMUState *s)
 {
     VTDInvDesc inv_desc;
@@ -1477,15 +1400,6 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s)
         }
         break;
 
-    case VTD_INV_DESC_IEC:
-        VTD_DPRINTF(INV, "Invalidation Interrupt Entry Cache "
-                    "Descriptor hi 0x%"PRIx64 " lo 0x%"PRIx64,
-                    inv_desc.hi, inv_desc.lo);
-        if (!vtd_process_inv_iec_desc(s, &inv_desc)) {
-            return false;
-        }
-        break;
-
     default:
         VTD_DPRINTF(GENERAL, "error: unkonw Invalidation Descriptor type "
                     "hi 0x%"PRIx64 " lo 0x%"PRIx64 " type %"PRIu8,
@@ -1914,23 +1828,6 @@ static void vtd_mem_write(void *opaque, hwaddr addr,
         vtd_update_fsts_ppf(s);
         break;
 
-    case DMAR_IRTA_REG:
-        VTD_DPRINTF(IR, "DMAR_IRTA_REG write addr 0x%"PRIx64
-                    ", size %d, val 0x%"PRIx64, addr, size, val);
-        if (size == 4) {
-            vtd_set_long(s, addr, val);
-        } else {
-            vtd_set_quad(s, addr, val);
-        }
-        break;
-
-    case DMAR_IRTA_REG_HI:
-        VTD_DPRINTF(IR, "DMAR_IRTA_REG_HI write addr 0x%"PRIx64
-                    ", size %d, val 0x%"PRIx64, addr, size, val);
-        assert(size == 4);
-        vtd_set_long(s, addr, val);
-        break;
-
     default:
         VTD_DPRINTF(GENERAL, "error: unhandled reg write addr 0x%"PRIx64
                     ", size %d, val 0x%"PRIx64, addr, size, val);
@@ -1974,16 +1871,6 @@ static IOMMUTLBEntry vtd_iommu_translate(MemoryRegion *iommu, hwaddr addr,
     return ret;
 }
 
-static void vtd_iommu_notify_started(MemoryRegion *iommu)
-{
-    VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
-
-    hw_error("Device at bus %s addr %02x.%d requires iommu notifier which "
-             "is currently not supported by intel-iommu emulation",
-             vtd_as->bus->qbus.name, PCI_SLOT(vtd_as->devfn),
-             PCI_FUNC(vtd_as->devfn));
-}
-
 static const VMStateDescription vtd_vmstate = {
     .name = "iommu-intel",
     .unmigratable = 1,
@@ -2008,295 +1895,6 @@ static Property vtd_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-/* Read IRTE entry with specific index */
-static int vtd_irte_get(IntelIOMMUState *iommu, uint16_t index,
-                        VTD_IR_TableEntry *entry, uint16_t sid)
-{
-    static const uint16_t vtd_svt_mask[VTD_SQ_MAX] = \
-        {0xffff, 0xfffb, 0xfff9, 0xfff8};
-    dma_addr_t addr = 0x00;
-    uint16_t mask, source_id;
-    uint8_t bus, bus_max, bus_min;
-
-    addr = iommu->intr_root + index * sizeof(*entry);
-    if (dma_memory_read(&address_space_memory, addr, entry,
-                        sizeof(*entry))) {
-        VTD_DPRINTF(GENERAL, "error: fail to access IR root at 0x%"PRIx64
-                    " + %"PRIu16, iommu->intr_root, index);
-        return -VTD_FR_IR_ROOT_INVAL;
-    }
-
-    if (!entry->irte.present) {
-        VTD_DPRINTF(GENERAL, "error: present flag not set in IRTE"
-                    " entry index %u value 0x%"PRIx64 " 0x%"PRIx64,
-                    index, le64_to_cpu(entry->data[1]),
-                    le64_to_cpu(entry->data[0]));
-        return -VTD_FR_IR_ENTRY_P;
-    }
-
-    if (entry->irte.__reserved_0 || entry->irte.__reserved_1 ||
-        entry->irte.__reserved_2) {
-        VTD_DPRINTF(GENERAL, "error: IRTE entry index %"PRIu16
-                    " reserved fields non-zero: 0x%"PRIx64 " 0x%"PRIx64,
-                    index, le64_to_cpu(entry->data[1]),
-                    le64_to_cpu(entry->data[0]));
-        return -VTD_FR_IR_IRTE_RSVD;
-    }
-
-    if (sid != X86_IOMMU_SID_INVALID) {
-        /* Validate IRTE SID */
-        source_id = le32_to_cpu(entry->irte.source_id);
-        switch (entry->irte.sid_vtype) {
-        case VTD_SVT_NONE:
-            VTD_DPRINTF(IR, "No SID validation for IRTE index %d", index);
-            break;
-
-        case VTD_SVT_ALL:
-            mask = vtd_svt_mask[entry->irte.sid_q];
-            if ((source_id & mask) != (sid & mask)) {
-                VTD_DPRINTF(GENERAL, "SID validation for IRTE index "
-                            "%d failed (reqid 0x%04x sid 0x%04x)", index,
-                            sid, source_id);
-                return -VTD_FR_IR_SID_ERR;
-            }
-            break;
-
-        case VTD_SVT_BUS:
-            bus_max = source_id >> 8;
-            bus_min = source_id & 0xff;
-            bus = sid >> 8;
-            if (bus > bus_max || bus < bus_min) {
-                VTD_DPRINTF(GENERAL, "SID validation for IRTE index %d "
-                            "failed (bus %d outside %d-%d)", index, bus,
-                            bus_min, bus_max);
-                return -VTD_FR_IR_SID_ERR;
-            }
-            break;
-
-        default:
-            VTD_DPRINTF(GENERAL, "Invalid SVT bits (0x%x) in IRTE index "
-                        "%d", entry->irte.sid_vtype, index);
-            /* Take this as verification failure. */
-            return -VTD_FR_IR_SID_ERR;
-            break;
-        }
-    }
-
-    return 0;
-}
-
-/* Fetch IRQ information of specific IR index */
-static int vtd_remap_irq_get(IntelIOMMUState *iommu, uint16_t index,
-                             VTDIrq *irq, uint16_t sid)
-{
-    VTD_IR_TableEntry irte = {};
-    int ret = 0;
-
-    ret = vtd_irte_get(iommu, index, &irte, sid);
-    if (ret) {
-        return ret;
-    }
-
-    irq->trigger_mode = irte.irte.trigger_mode;
-    irq->vector = irte.irte.vector;
-    irq->delivery_mode = irte.irte.delivery_mode;
-    irq->dest = le32_to_cpu(irte.irte.dest_id);
-    if (!iommu->intr_eime) {
-#define  VTD_IR_APIC_DEST_MASK         (0xff00ULL)
-#define  VTD_IR_APIC_DEST_SHIFT        (8)
-        irq->dest = (irq->dest & VTD_IR_APIC_DEST_MASK) >>
-            VTD_IR_APIC_DEST_SHIFT;
-    }
-    irq->dest_mode = irte.irte.dest_mode;
-    irq->redir_hint = irte.irte.redir_hint;
-
-    VTD_DPRINTF(IR, "remapping interrupt index %d: trig:%u,vec:%u,"
-                "deliver:%u,dest:%u,dest_mode:%u", index,
-                irq->trigger_mode, irq->vector, irq->delivery_mode,
-                irq->dest, irq->dest_mode);
-
-    return 0;
-}
-
-/* Generate one MSI message from VTDIrq info */
-static void vtd_generate_msi_message(VTDIrq *irq, MSIMessage *msg_out)
-{
-    VTD_MSIMessage msg = {};
-
-    /* Generate address bits */
-    msg.dest_mode = irq->dest_mode;
-    msg.redir_hint = irq->redir_hint;
-    msg.dest = irq->dest;
-    msg.__addr_head = cpu_to_le32(0xfee);
-    /* Keep this from original MSI address bits */
-    msg.__not_used = irq->msi_addr_last_bits;
-
-    /* Generate data bits */
-    msg.vector = irq->vector;
-    msg.delivery_mode = irq->delivery_mode;
-    msg.level = 1;
-    msg.trigger_mode = irq->trigger_mode;
-
-    msg_out->address = msg.msi_addr;
-    msg_out->data = msg.msi_data;
-}
-
-/* Interrupt remapping for MSI/MSI-X entry */
-static int vtd_interrupt_remap_msi(IntelIOMMUState *iommu,
-                                   MSIMessage *origin,
-                                   MSIMessage *translated,
-                                   uint16_t sid)
-{
-    int ret = 0;
-    VTD_IR_MSIAddress addr;
-    uint16_t index;
-    VTDIrq irq = {};
-
-    assert(origin && translated);
-
-    if (!iommu || !iommu->intr_enabled) {
-        goto do_not_translate;
-    }
-
-    if (origin->address & VTD_MSI_ADDR_HI_MASK) {
-        VTD_DPRINTF(GENERAL, "error: MSI addr high 32 bits nonzero"
-                    " during interrupt remapping: 0x%"PRIx32,
-                    (uint32_t)((origin->address & VTD_MSI_ADDR_HI_MASK) >> \
-                    VTD_MSI_ADDR_HI_SHIFT));
-        return -VTD_FR_IR_REQ_RSVD;
-    }
-
-    addr.data = origin->address & VTD_MSI_ADDR_LO_MASK;
-    if (le16_to_cpu(addr.addr.__head) != 0xfee) {
-        VTD_DPRINTF(GENERAL, "error: MSI addr low 32 bits invalid: "
-                    "0x%"PRIx32, addr.data);
-        return -VTD_FR_IR_REQ_RSVD;
-    }
-
-    /* This is compatible mode. */
-    if (addr.addr.int_mode != VTD_IR_INT_FORMAT_REMAP) {
-        goto do_not_translate;
-    }
-
-    index = addr.addr.index_h << 15 | le16_to_cpu(addr.addr.index_l);
-
-#define  VTD_IR_MSI_DATA_SUBHANDLE       (0x0000ffff)
-#define  VTD_IR_MSI_DATA_RESERVED        (0xffff0000)
-
-    if (addr.addr.sub_valid) {
-        /* See VT-d spec 5.1.2.2 and 5.1.3 on subhandle */
-        index += origin->data & VTD_IR_MSI_DATA_SUBHANDLE;
-    }
-
-    ret = vtd_remap_irq_get(iommu, index, &irq, sid);
-    if (ret) {
-        return ret;
-    }
-
-    if (addr.addr.sub_valid) {
-        VTD_DPRINTF(IR, "received MSI interrupt");
-        if (origin->data & VTD_IR_MSI_DATA_RESERVED) {
-            VTD_DPRINTF(GENERAL, "error: MSI data bits non-zero for "
-                        "interrupt remappable entry: 0x%"PRIx32,
-                        origin->data);
-            return -VTD_FR_IR_REQ_RSVD;
-        }
-    } else {
-        uint8_t vector = origin->data & 0xff;
-        VTD_DPRINTF(IR, "received IOAPIC interrupt");
-        /* IOAPIC entry vector should be aligned with IRTE vector
-         * (see vt-d spec 5.1.5.1). */
-        if (vector != irq.vector) {
-            VTD_DPRINTF(GENERAL, "IOAPIC vector inconsistent: "
-                        "entry: %d, IRTE: %d, index: %d",
-                        vector, irq.vector, index);
-        }
-    }
-
-    /*
-     * We'd better keep the last two bits, assuming that guest OS
-     * might modify it. Keep it does not hurt after all.
-     */
-    irq.msi_addr_last_bits = addr.addr.__not_care;
-
-    /* Translate VTDIrq to MSI message */
-    vtd_generate_msi_message(&irq, translated);
-
-    VTD_DPRINTF(IR, "mapping MSI 0x%"PRIx64":0x%"PRIx32 " -> "
-                "0x%"PRIx64":0x%"PRIx32, origin->address, origin->data,
-                translated->address, translated->data);
-    return 0;
-
-do_not_translate:
-    memcpy(translated, origin, sizeof(*origin));
-    return 0;
-}
-
-static int vtd_int_remap(X86IOMMUState *iommu, MSIMessage *src,
-                         MSIMessage *dst, uint16_t sid)
-{
-    return vtd_interrupt_remap_msi(INTEL_IOMMU_DEVICE(iommu),
-                                   src, dst, sid);
-}
-
-static MemTxResult vtd_mem_ir_read(void *opaque, hwaddr addr,
-                                   uint64_t *data, unsigned size,
-                                   MemTxAttrs attrs)
-{
-    return MEMTX_OK;
-}
-
-static MemTxResult vtd_mem_ir_write(void *opaque, hwaddr addr,
-                                    uint64_t value, unsigned size,
-                                    MemTxAttrs attrs)
-{
-    int ret = 0;
-    MSIMessage from = {}, to = {};
-    uint16_t sid = X86_IOMMU_SID_INVALID;
-
-    from.address = (uint64_t) addr + VTD_INTERRUPT_ADDR_FIRST;
-    from.data = (uint32_t) value;
-
-    if (!attrs.unspecified) {
-        /* We have explicit Source ID */
-        sid = attrs.requester_id;
-    }
-
-    ret = vtd_interrupt_remap_msi(opaque, &from, &to, sid);
-    if (ret) {
-        /* TODO: report error */
-        VTD_DPRINTF(GENERAL, "int remap fail for addr 0x%"PRIx64
-                    " data 0x%"PRIx32, from.address, from.data);
-        /* Drop this interrupt */
-        return MEMTX_ERROR;
-    }
-
-    VTD_DPRINTF(IR, "delivering MSI 0x%"PRIx64":0x%"PRIx32
-                " for device sid 0x%04x",
-                to.address, to.data, sid);
-
-    if (dma_memory_write(&address_space_memory, to.address,
-                         &to.data, size)) {
-        VTD_DPRINTF(GENERAL, "error: fail to write 0x%"PRIx64
-                    " value 0x%"PRIx32, to.address, to.data);
-    }
-
-    return MEMTX_OK;
-}
-
-static const MemoryRegionOps vtd_mem_ir_ops = {
-    .read_with_attrs = vtd_mem_ir_read,
-    .write_with_attrs = vtd_mem_ir_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-    .impl = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-};
 
 VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
 {
@@ -2306,8 +1904,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
 
     if (!vtd_bus) {
         /* No corresponding free() */
-        vtd_bus = g_malloc0(sizeof(VTDBus) + sizeof(VTDAddressSpace *) * \
-                            X86_IOMMU_PCI_DEVFN_MAX);
+        vtd_bus = g_malloc0(sizeof(VTDBus) + sizeof(VTDAddressSpace *) * VTD_PCI_DEVFN_MAX);
         vtd_bus->bus = bus;
         key = (uintptr_t)bus;
         g_hash_table_insert(s->vtd_as_by_busptr, &key, vtd_bus);
@@ -2324,11 +1921,6 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
         vtd_dev_as->context_cache_entry.context_cache_gen = 0;
         memory_region_init_iommu(&vtd_dev_as->iommu, OBJECT(s),
                                  &s->iommu_ops, "intel_iommu", UINT64_MAX);
-        memory_region_init_io(&vtd_dev_as->iommu_ir, OBJECT(s),
-                              &vtd_mem_ir_ops, s, "intel_iommu_ir",
-                              VTD_INTERRUPT_ADDR_SIZE);
-        memory_region_add_subregion(&vtd_dev_as->iommu, VTD_INTERRUPT_ADDR_FIRST,
-                                    &vtd_dev_as->iommu_ir);
         address_space_init(&vtd_dev_as->as,
                            &vtd_dev_as->iommu, "intel_iommu");
     }
@@ -2340,15 +1932,12 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
  */
 static void vtd_init(IntelIOMMUState *s)
 {
-    X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
-
     memset(s->csr, 0, DMAR_REG_SIZE);
     memset(s->wmask, 0, DMAR_REG_SIZE);
     memset(s->w1cmask, 0, DMAR_REG_SIZE);
     memset(s->womask, 0, DMAR_REG_SIZE);
 
     s->iommu_ops.translate = vtd_iommu_translate;
-    s->iommu_ops.notify_started = vtd_iommu_notify_started;
     s->root = 0;
     s->root_extended = false;
     s->dmar_enabled = false;
@@ -2363,10 +1952,6 @@ static void vtd_init(IntelIOMMUState *s)
              VTD_CAP_SAGAW | VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS;
     s->ecap = VTD_ECAP_QI | VTD_ECAP_IRO;
 
-    if (x86_iommu->intr_supported) {
-        s->ecap |= VTD_ECAP_IR | VTD_ECAP_EIM | VTD_ECAP_MHMV;
-    }
-
     vtd_reset_context_cache(s);
     vtd_reset_iotlb(s);
 
@@ -2416,11 +2001,6 @@ static void vtd_init(IntelIOMMUState *s)
     /* Fault Recording Registers, 128-bit */
     vtd_define_quad(s, DMAR_FRCD_REG_0_0, 0, 0, 0);
     vtd_define_quad(s, DMAR_FRCD_REG_0_2, 0, 0, 0x8000000000000000ULL);
-
-    /*
-     * Interrupt remapping registers.
-     */
-    vtd_define_quad(s, DMAR_IRTA_REG, 0, 0xfffffffffffff80fULL, 0);
 }
 
 /* Should not reset address_spaces when reset because devices will still use
@@ -2434,23 +2014,9 @@ static void vtd_reset(DeviceState *dev)
     vtd_init(s);
 }
 
-static AddressSpace *vtd_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
-{
-    IntelIOMMUState *s = opaque;
-    VTDAddressSpace *vtd_as;
-
-    assert(0 <= devfn && devfn <= X86_IOMMU_PCI_DEVFN_MAX);
-
-    vtd_as = vtd_find_add_as(s, bus, devfn);
-    return &vtd_as->as;
-}
-
 static void vtd_realize(DeviceState *dev, Error **errp)
 {
-    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
-    PCIBus *bus = pcms->bus;
     IntelIOMMUState *s = INTEL_IOMMU_DEVICE(dev);
-    X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
 
     VTD_DPRINTF(GENERAL, "");
     memset(s->vtd_as_by_bus_num, 0, sizeof(s->vtd_as_by_bus_num));
@@ -2463,36 +2029,21 @@ static void vtd_realize(DeviceState *dev, Error **errp)
     s->vtd_as_by_busptr = g_hash_table_new_full(vtd_uint64_hash, vtd_uint64_equal,
                                               g_free, g_free);
     vtd_init(s);
-    sysbus_mmio_map(SYS_BUS_DEVICE(s), 0, Q35_HOST_BRIDGE_IOMMU_ADDR);
-    pci_setup_iommu(bus, vtd_host_dma_iommu, dev);
-    /* Pseudo address space under root PCI bus. */
-    pcms->ioapic_as = vtd_host_dma_iommu(bus, s, Q35_PSEUDO_DEVFN_IOAPIC);
-
-    /* Currently Intel IOMMU IR only support "kernel-irqchip={off|split}" */
-    if (x86_iommu->intr_supported && kvm_irqchip_in_kernel() &&
-        !kvm_irqchip_is_split()) {
-        error_report("Intel Interrupt Remapping cannot work with "
-                     "kernel-irqchip=on, please use 'split|off'.");
-        exit(1);
-    }
 }
 
 static void vtd_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    X86IOMMUClass *x86_class = X86_IOMMU_CLASS(klass);
 
     dc->reset = vtd_reset;
+    dc->realize = vtd_realize;
     dc->vmsd = &vtd_vmstate;
     dc->props = vtd_properties;
-    dc->hotpluggable = false;
-    x86_class->realize = vtd_realize;
-    x86_class->int_remap = vtd_int_remap;
 }
 
 static const TypeInfo vtd_info = {
     .name          = TYPE_INTEL_IOMMU_DEVICE,
-    .parent        = TYPE_X86_IOMMU_DEVICE,
+    .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(IntelIOMMUState),
     .class_init    = vtd_class_init,
 };
index 0829a50..e5f514c 100644 (file)
 /* Interrupt Address Range */
 #define VTD_INTERRUPT_ADDR_FIRST    0xfee00000ULL
 #define VTD_INTERRUPT_ADDR_LAST     0xfeefffffULL
-#define VTD_INTERRUPT_ADDR_SIZE     (VTD_INTERRUPT_ADDR_LAST - \
-                                     VTD_INTERRUPT_ADDR_FIRST + 1)
 
 /* The shift of source_id in the key of IOTLB hash table */
 #define VTD_IOTLB_SID_SHIFT         36
 #define VTD_RTADDR_RTT              (1ULL << 11)
 #define VTD_RTADDR_ADDR_MASK        (VTD_HAW_MASK ^ 0xfffULL)
 
-/* IRTA_REG */
-#define VTD_IRTA_ADDR_MASK          (VTD_HAW_MASK ^ 0xfffULL)
-#define VTD_IRTA_EIME               (1ULL << 11)
-#define VTD_IRTA_SIZE_MASK          (0xfULL)
-
 /* ECAP_REG */
 /* (offset >> 4) << 8 */
 #define VTD_ECAP_IRO                (DMAR_IOTLB_REG_OFFSET << 4)
 #define VTD_ECAP_QI                 (1ULL << 1)
-/* Interrupt Remapping support */
-#define VTD_ECAP_IR                 (1ULL << 3)
-#define VTD_ECAP_EIM                (1ULL << 4)
-#define VTD_ECAP_MHMV               (15ULL << 20)
 
 /* CAP_REG */
 /* (offset >> 4) << 24 */
@@ -276,19 +265,6 @@ typedef enum VTDFaultReason {
      * context-entry.
      */
     VTD_FR_CONTEXT_ENTRY_TT,
-
-    /* Interrupt remapping transition faults */
-    VTD_FR_IR_REQ_RSVD = 0x20, /* One or more IR request reserved
-                                * fields set */
-    VTD_FR_IR_INDEX_OVER = 0x21, /* Index value greater than max */
-    VTD_FR_IR_ENTRY_P = 0x22,    /* Present (P) not set in IRTE */
-    VTD_FR_IR_ROOT_INVAL = 0x23, /* IR Root table invalid */
-    VTD_FR_IR_IRTE_RSVD = 0x24,  /* IRTE Rsvd field non-zero with
-                                  * Present flag set */
-    VTD_FR_IR_REQ_COMPAT = 0x25, /* Encountered compatible IR
-                                  * request while disabled */
-    VTD_FR_IR_SID_ERR = 0x26,   /* Invalid Source-ID */
-
     /* This is not a normal fault reason. We use this to indicate some faults
      * that are not referenced by the VT-d specification.
      * Fault event with such reason should not be recorded.
@@ -299,35 +275,17 @@ typedef enum VTDFaultReason {
 
 #define VTD_CONTEXT_CACHE_GEN_MAX       0xffffffffUL
 
-/* Interrupt Entry Cache Invalidation Descriptor: VT-d 6.5.2.7. */
-struct VTDInvDescIEC {
-    uint32_t type:4;            /* Should always be 0x4 */
-    uint32_t granularity:1;     /* If set, it's global IR invalidation */
-    uint32_t resved_1:22;
-    uint32_t index_mask:5;      /* 2^N for continuous int invalidation */
-    uint32_t index:16;          /* Start index to invalidate */
-    uint32_t reserved_2:16;
-};
-typedef struct VTDInvDescIEC VTDInvDescIEC;
-
 /* Queued Invalidation Descriptor */
-union VTDInvDesc {
-    struct {
-        uint64_t lo;
-        uint64_t hi;
-    };
-    union {
-        VTDInvDescIEC iec;
-    };
+struct VTDInvDesc {
+    uint64_t lo;
+    uint64_t hi;
 };
-typedef union VTDInvDesc VTDInvDesc;
+typedef struct VTDInvDesc VTDInvDesc;
 
 /* Masks for struct VTDInvDesc */
 #define VTD_INV_DESC_TYPE               0xf
 #define VTD_INV_DESC_CC                 0x1 /* Context-cache Invalidate Desc */
 #define VTD_INV_DESC_IOTLB              0x2
-#define VTD_INV_DESC_IEC                0x4 /* Interrupt Entry Cache
-                                               Invalidate Descriptor */
 #define VTD_INV_DESC_WAIT               0x5 /* Invalidation Wait Descriptor */
 #define VTD_INV_DESC_NONE               0   /* Not an Invalidate Descriptor */
 
index 2bd0de8..3c7c8fa 100644 (file)
@@ -10,8 +10,6 @@
  * See the COPYING file in the top-level directory.
  */
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "hw/i386/apic_internal.h"
 #include "hw/pci/msi.h"
 #include "sysemu/kvm.h"
@@ -184,24 +182,19 @@ static void kvm_apic_realize(DeviceState *dev, Error **errp)
 {
     APICCommonState *s = APIC_COMMON(dev);
 
-    memory_region_init_io(&s->io_memory, OBJECT(s), &kvm_apic_io_ops, s,
-                          "kvm-apic-msi", APIC_SPACE_SIZE);
+    memory_region_init_io(&s->io_memory, NULL, &kvm_apic_io_ops, s, "kvm-apic-msi",
+                          APIC_SPACE_SIZE);
 
     if (kvm_has_gsi_routing()) {
         msi_nonbroken = true;
     }
 }
 
-static void kvm_apic_unrealize(DeviceState *dev, Error **errp)
-{
-}
-
 static void kvm_apic_class_init(ObjectClass *klass, void *data)
 {
     APICCommonClass *k = APIC_COMMON_CLASS(klass);
 
     k->realize = kvm_apic_realize;
-    k->unrealize = kvm_apic_unrealize;
     k->reset = kvm_apic_reset;
     k->set_base = kvm_apic_set_base;
     k->set_tpr = kvm_apic_set_tpr;
index 0f75dd3..a3b300c 100644 (file)
@@ -15,7 +15,6 @@
 
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "qemu/host-utils.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
index 521a584..a4462e5 100644 (file)
@@ -22,9 +22,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
 #include "qemu/osdep.h"
-#include <linux/kvm.h>
 #include "qapi/error.h"
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
index 8238fbc..8abce52 100644 (file)
  *  Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com)
  *  Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com)
  */
-
 #include "qemu/osdep.h"
-#include <linux/kvm.h>
 #include "qapi/error.h"
+#include <sys/mman.h>
 #include "hw/hw.h"
 #include "hw/i386/pc.h"
 #include "qemu/error-report.h"
@@ -37,6 +36,8 @@
 #include "kvm_i386.h"
 #include "hw/pci/pci-assign.h"
 
+#define MSIX_PAGE_SIZE 0x1000
+
 /* From linux/ioport.h */
 #define IORESOURCE_IO       0x00000100  /* Resource type */
 #define IORESOURCE_MEM      0x00000200
@@ -121,7 +122,6 @@ typedef struct AssignedDevice {
     int *msi_virq;
     MSIXTableEntry *msix_table;
     hwaddr msix_table_addr;
-    uint16_t msix_table_size;
     uint16_t msix_max;
     MemoryRegion mmio;
     char *configfd_name;
@@ -974,9 +974,10 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev)
     }
 
     if (ctrl_byte & PCI_MSI_FLAGS_ENABLE) {
+        MSIMessage msg = msi_get_message(pci_dev, 0);
         int virq;
 
-        virq = kvm_irqchip_add_msi_route(kvm_state, 0, pci_dev);
+        virq = kvm_irqchip_add_msi_route(kvm_state, msg, pci_dev);
         if (virq < 0) {
             perror("assigned_dev_update_msi: kvm_irqchip_add_msi_route");
             return;
@@ -1015,7 +1016,6 @@ static void assigned_dev_update_msi_msg(PCIDevice *pci_dev)
 
     kvm_irqchip_update_msi_route(kvm_state, assigned_dev->msi_virq[0],
                                  msi_get_message(pci_dev, 0), pci_dev);
-    kvm_irqchip_commit_routes(kvm_state);
 }
 
 static bool assigned_dev_msix_masked(MSIXTableEntry *entry)
@@ -1042,6 +1042,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
     uint16_t entries_nr = 0;
     int i, r = 0;
     MSIXTableEntry *entry = adev->msix_table;
+    MSIMessage msg;
 
     /* Get the usable entry number for allocating */
     for (i = 0; i < adev->msix_max; i++, entry++) {
@@ -1078,7 +1079,9 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
             continue;
         }
 
-        r = kvm_irqchip_add_msi_route(kvm_state, i, pci_dev);
+        msg.address = entry->addr_lo | ((uint64_t)entry->addr_hi << 32);
+        msg.data = entry->data;
+        r = kvm_irqchip_add_msi_route(kvm_state, msg, pci_dev);
         if (r < 0) {
             return r;
         }
@@ -1307,7 +1310,6 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
         bar_nr = msix_table_entry & PCI_MSIX_FLAGS_BIRMASK;
         msix_table_entry &= ~PCI_MSIX_FLAGS_BIRMASK;
         dev->msix_table_addr = pci_region[bar_nr].base_addr + msix_table_entry;
-        dev->msix_table_size = msix_max * sizeof(MSIXTableEntry);
         dev->msix_max = msix_max;
     }
 
@@ -1479,7 +1481,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
          * error bits, leave the rest. */
         status = pci_get_long(pci_dev->config + pos + PCI_X_STATUS);
         status &= ~(PCI_X_STATUS_BUS | PCI_X_STATUS_DEVFN);
-        status |= pci_get_bdf(pci_dev);
+        status |= pci_requester_id(pci_dev);
         status &= ~(PCI_X_STATUS_SPL_DISC | PCI_X_STATUS_UNX_SPL |
                     PCI_X_STATUS_SPL_ERR);
         pci_set_long(pci_dev->config + pos + PCI_X_STATUS, status);
@@ -1603,7 +1605,6 @@ static void assigned_dev_msix_mmio_write(void *opaque, hwaddr addr,
                 if (ret) {
                     error_report("Error updating irq routing entry (%d)", ret);
                 }
-                kvm_irqchip_commit_routes(kvm_state);
             }
         }
     }
@@ -1632,7 +1633,7 @@ static void assigned_dev_msix_reset(AssignedDevice *dev)
         return;
     }
 
-    memset(dev->msix_table, 0, dev->msix_table_size);
+    memset(dev->msix_table, 0, MSIX_PAGE_SIZE);
 
     for (i = 0, entry = dev->msix_table; i < dev->msix_max; i++, entry++) {
         entry->ctrl = cpu_to_le32(0x1); /* Masked */
@@ -1641,8 +1642,8 @@ static void assigned_dev_msix_reset(AssignedDevice *dev)
 
 static void assigned_dev_register_msix_mmio(AssignedDevice *dev, Error **errp)
 {
-    dev->msix_table = mmap(NULL, dev->msix_table_size, PROT_READ | PROT_WRITE,
-                           MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
+    dev->msix_table = mmap(NULL, MSIX_PAGE_SIZE, PROT_READ|PROT_WRITE,
+                           MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
     if (dev->msix_table == MAP_FAILED) {
         error_setg_errno(errp, errno, "failed to allocate msix_table");
         dev->msix_table = NULL;
@@ -1652,7 +1653,7 @@ static void assigned_dev_register_msix_mmio(AssignedDevice *dev, Error **errp)
     assigned_dev_msix_reset(dev);
 
     memory_region_init_io(&dev->mmio, OBJECT(dev), &assigned_dev_msix_mmio_ops,
-                          dev, "assigned-dev-msix", dev->msix_table_size);
+                          dev, "assigned-dev-msix", MSIX_PAGE_SIZE);
 }
 
 static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev)
@@ -1661,7 +1662,7 @@ static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev)
         return;
     }
 
-    if (munmap(dev->msix_table, dev->msix_table_size) == -1) {
+    if (munmap(dev->msix_table, MSIX_PAGE_SIZE) == -1) {
         error_report("error unmapping msix_table! %s", strerror(errno));
     }
     dev->msix_table = NULL;
index 3bf1ddd..ff1e31a 100644 (file)
@@ -9,9 +9,6 @@
  * top-level directory.
  */
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/cpus.h"
 #include "sysemu/kvm.h"
@@ -400,7 +397,7 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
     uint32_t imm32 = 0;
     target_ulong current_pc = 0;
     target_ulong current_cs_base = 0;
-    uint32_t current_flags = 0;
+    int current_flags = 0;
 
     if (smp_cpus == 1) {
         handlers = &s->rom_state.up;
@@ -449,8 +446,9 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
     resume_all_vcpus();
 
     if (!kvm_enabled()) {
+        cs->current_tb = NULL;
         tb_gen_code(cs, current_pc, current_cs_base, current_flags, 1);
-        cpu_loop_exit_noexc(cs);
+        cpu_resume_from_signal(cs, NULL);
     }
 }
 
index 022dd1b..99437e0 100644 (file)
@@ -67,7 +67,6 @@
 #include "qapi/visitor.h"
 #include "qapi-visit.h"
 #include "qom/cpu.h"
-#include "hw/nmi.h"
 
 /* debug PC/ISA interrupts */
 //#define DEBUG_IRQ
@@ -381,7 +380,7 @@ ISADevice *pc_find_fdc0(void)
         error_report("warning: multiple floppy disk controllers with "
                      "iobase=0x3f0 have been found");
         error_printf("the one being picked for CMOS setup might not reflect "
-                     "your intent\n");
+                     "your intent");
     }
 
     return state.floppy;
@@ -471,6 +470,9 @@ void pc_cmos_init(PCMachineState *pcms,
     rtc_set_memory(s, 0x5c, val >> 8);
     rtc_set_memory(s, 0x5d, val >> 16);
 
+    /* set the number of CPU */
+    rtc_set_memory(s, 0x5f, smp_cpus - 1);
+
     object_property_add_link(OBJECT(pcms), "rtc_state",
                              TYPE_ISA_DEVICE,
                              (Object **)&pcms->rtc,
@@ -502,7 +504,7 @@ typedef struct Port92State {
 
     MemoryRegion io;
     uint8_t outport;
-    qemu_irq a20_out;
+    qemu_irq *a20_out;
 } Port92State;
 
 static void port92_write(void *opaque, hwaddr addr, uint64_t val,
@@ -513,7 +515,7 @@ static void port92_write(void *opaque, hwaddr addr, uint64_t val,
 
     DPRINTF("port92: write 0x%02" PRIx64 "\n", val);
     s->outport = val;
-    qemu_set_irq(s->a20_out, (val >> 1) & 1);
+    qemu_set_irq(*s->a20_out, (val >> 1) & 1);
     if ((val & 1) && !(oldval & 1)) {
         qemu_system_reset_request();
     }
@@ -532,7 +534,9 @@ static uint64_t port92_read(void *opaque, hwaddr addr,
 
 static void port92_init(ISADevice *dev, qemu_irq *a20_out)
 {
-    qdev_connect_gpio_out_named(DEVICE(dev), PORT92_A20_LINE, 0, *a20_out);
+    Port92State *s = PORT92(dev);
+
+    s->a20_out = a20_out;
 }
 
 static const VMStateDescription vmstate_port92_isa = {
@@ -569,8 +573,6 @@ static void port92_initfn(Object *obj)
     memory_region_init_io(&s->io, OBJECT(s), &port92_ops, s, "port92", 1);
 
     s->outport = 0;
-
-    qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, PORT92_A20_LINE, 1);
 }
 
 static void port92_realizefn(DeviceState *dev, Error **errp)
@@ -762,6 +764,8 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms)
                      acpi_tables, acpi_tables_len);
     fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, kvm_allows_irq0_override());
 
+    pc_build_smbios(fw_cfg);
+
     fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE,
                      &e820_reserve, sizeof(e820_reserve));
     fw_cfg_add_file(fw_cfg, "etc/e820", e820_table,
@@ -809,26 +813,11 @@ static long get_file_size(FILE *f)
     return size;
 }
 
-/* setup_data types */
-#define SETUP_NONE     0
-#define SETUP_E820_EXT 1
-#define SETUP_DTB      2
-#define SETUP_PCI      3
-#define SETUP_EFI      4
-
-struct setup_data {
-    uint64_t next;
-    uint32_t type;
-    uint32_t len;
-    uint8_t data[0];
-} __attribute__((packed));
-
 static void load_linux(PCMachineState *pcms,
                        FWCfgState *fw_cfg)
 {
     uint16_t protocol;
     int setup_size, kernel_size, initrd_size = 0, cmdline_size;
-    int dtb_size, setup_data_offset;
     uint32_t initrd_max;
     uint8_t header[8192], *setup, *kernel, *initrd_data;
     hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0;
@@ -836,10 +825,8 @@ static void load_linux(PCMachineState *pcms,
     char *vmode;
     MachineState *machine = MACHINE(pcms);
     PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
-    struct setup_data *setup_data;
     const char *kernel_filename = machine->kernel_filename;
     const char *initrd_filename = machine->initrd_filename;
-    const char *dtb_filename = machine->dtb;
     const char *kernel_cmdline = machine->kernel_cmdline;
 
     /* Align to 16 bytes as a paranoia measure */
@@ -1002,35 +989,6 @@ static void load_linux(PCMachineState *pcms,
         exit(1);
     }
     fclose(f);
-
-    /* append dtb to kernel */
-    if (dtb_filename) {
-        if (protocol < 0x209) {
-            fprintf(stderr, "qemu: Linux kernel too old to load a dtb\n");
-            exit(1);
-        }
-
-        dtb_size = get_image_size(dtb_filename);
-        if (dtb_size <= 0) {
-            fprintf(stderr, "qemu: error reading dtb %s: %s\n",
-                    dtb_filename, strerror(errno));
-            exit(1);
-        }
-
-        setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16);
-        kernel_size = setup_data_offset + sizeof(struct setup_data) + dtb_size;
-        kernel = g_realloc(kernel, kernel_size);
-
-        stq_p(header+0x250, prot_addr + setup_data_offset);
-
-        setup_data = (struct setup_data *)(kernel + setup_data_offset);
-        setup_data->next = 0;
-        setup_data->type = cpu_to_le32(SETUP_DTB);
-        setup_data->len = cpu_to_le32(dtb_size);
-
-        load_image_size(dtb_filename, setup_data->data, dtb_size);
-    }
-
     memcpy(setup, header, MIN(sizeof(header), setup_size));
 
     fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
@@ -1041,13 +999,8 @@ static void load_linux(PCMachineState *pcms,
     fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size);
     fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size);
 
-    if (fw_cfg_dma_enabled(fw_cfg)) {
-        option_rom[nb_option_roms].name = "linuxboot_dma.bin";
-        option_rom[nb_option_roms].bootindex = 0;
-    } else {
-        option_rom[nb_option_roms].name = "linuxboot.bin";
-        option_rom[nb_option_roms].bootindex = 0;
-    }
+    option_rom[nb_option_roms].name = "linuxboot.bin";
+    option_rom[nb_option_roms].bootindex = 0;
     nb_option_roms++;
 }
 
@@ -1087,28 +1040,21 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level)
     }
 }
 
-static int pc_present_cpus_count(PCMachineState *pcms)
-{
-    int i, boot_cpus = 0;
-    for (i = 0; i < pcms->possible_cpus->len; i++) {
-        if (pcms->possible_cpus->cpus[i].cpu) {
-            boot_cpus++;
-        }
-    }
-    return boot_cpus;
-}
-
-static X86CPU *pc_new_cpu(const char *typename, int64_t apic_id,
+static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id,
                           Error **errp)
 {
     X86CPU *cpu = NULL;
     Error *local_err = NULL;
 
-    cpu = X86_CPU(object_new(typename));
+    cpu = cpu_x86_create(cpu_model, &local_err);
+    if (local_err != NULL) {
+        goto out;
+    }
 
     object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err);
     object_property_set_bool(OBJECT(cpu), true, "realized", &local_err);
 
+out:
     if (local_err) {
         error_propagate(errp, local_err);
         object_unref(OBJECT(cpu));
@@ -1120,8 +1066,7 @@ static X86CPU *pc_new_cpu(const char *typename, int64_t apic_id,
 void pc_hot_add_cpu(const int64_t id, Error **errp)
 {
     X86CPU *cpu;
-    ObjectClass *oc;
-    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
+    MachineState *machine = MACHINE(qdev_get_machine());
     int64_t apic_id = x86_cpu_apic_id_from_index(id);
     Error *local_err = NULL;
 
@@ -1130,6 +1075,18 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
         return;
     }
 
+    if (cpu_exists(apic_id)) {
+        error_setg(errp, "Unable to add CPU: %" PRIi64
+                   ", it already exists", id);
+        return;
+    }
+
+    if (id >= max_cpus) {
+        error_setg(errp, "Unable to add CPU: %" PRIi64
+                   ", max allowed: %d", id, max_cpus - 1);
+        return;
+    }
+
     if (apic_id >= ACPI_CPU_HOTPLUG_ID_LIMIT) {
         error_setg(errp, "Unable to add CPU: %" PRIi64
                    ", resulting APIC ID (%" PRIi64 ") is too large",
@@ -1137,9 +1094,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
         return;
     }
 
-    assert(pcms->possible_cpus->cpus[0].cpu); /* BSP is always present */
-    oc = OBJECT_CLASS(CPU_GET_CLASS(pcms->possible_cpus->cpus[0].cpu));
-    cpu = pc_new_cpu(object_class_get_name(oc), apic_id, &local_err);
+    cpu = pc_new_cpu(machine->cpu_model, apic_id, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
@@ -1150,10 +1105,6 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
 void pc_cpus_init(PCMachineState *pcms)
 {
     int i;
-    CPUClass *cc;
-    ObjectClass *oc;
-    const char *typename;
-    gchar **model_pieces;
     X86CPU *cpu = NULL;
     MachineState *machine = MACHINE(pcms);
 
@@ -1166,22 +1117,6 @@ void pc_cpus_init(PCMachineState *pcms)
 #endif
     }
 
-    model_pieces = g_strsplit(machine->cpu_model, ",", 2);
-    if (!model_pieces[0]) {
-        error_report("Invalid/empty CPU model name");
-        exit(1);
-    }
-
-    oc = cpu_class_by_name(TYPE_X86_CPU, model_pieces[0]);
-    if (oc == NULL) {
-        error_report("Unable to find CPU definition: %s", model_pieces[0]);
-        exit(1);
-    }
-    typename = object_class_get_name(oc);
-    cc = CPU_CLASS(oc);
-    cc->parse_features(typename, model_pieces[1], &error_fatal);
-    g_strfreev(model_pieces);
-
     /* Calculates the limit to CPU APIC ID values
      *
      * Limit for the APIC ID value, so that all
@@ -1202,8 +1137,9 @@ void pc_cpus_init(PCMachineState *pcms)
         pcms->possible_cpus->cpus[i].arch_id = x86_cpu_apic_id_from_index(i);
         pcms->possible_cpus->len++;
         if (i < smp_cpus) {
-            cpu = pc_new_cpu(typename, x86_cpu_apic_id_from_index(i),
+            cpu = pc_new_cpu(machine->cpu_model, x86_cpu_apic_id_from_index(i),
                              &error_fatal);
+            pcms->possible_cpus->cpus[i].cpu = CPU(cpu);
             object_unref(OBJECT(cpu));
         }
     }
@@ -1212,33 +1148,13 @@ void pc_cpus_init(PCMachineState *pcms)
     smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
 }
 
-static void pc_build_feature_control_file(PCMachineState *pcms)
-{
-    X86CPU *cpu = X86_CPU(pcms->possible_cpus->cpus[0].cpu);
-    CPUX86State *env = &cpu->env;
-    uint32_t unused, ecx, edx;
-    uint64_t feature_control_bits = 0;
-    uint64_t *val;
-
-    cpu_x86_cpuid(env, 1, 0, &unused, &unused, &ecx, &edx);
-    if (ecx & CPUID_EXT_VMX) {
-        feature_control_bits |= FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
-    }
-
-    if ((edx & (CPUID_EXT2_MCE | CPUID_EXT2_MCA)) ==
-        (CPUID_EXT2_MCE | CPUID_EXT2_MCA) &&
-        (env->mcg_cap & MCG_LMCE_P)) {
-        feature_control_bits |= FEATURE_CONTROL_LMCE;
-    }
-
-    if (!feature_control_bits) {
-        return;
-    }
-
-    val = g_malloc(sizeof(*val));
-    *val = cpu_to_le64(feature_control_bits | FEATURE_CONTROL_LOCKED);
-    fw_cfg_add_file(pcms->fw_cfg, "etc/msr_feature_control", val, sizeof(*val));
-}
+/* pci-info ROM file. Little endian format */
+typedef struct PcRomPciInfo {
+    uint64_t w32_min;
+    uint64_t w32_max;
+    uint64_t w64_min;
+    uint64_t w64_max;
+} PcRomPciInfo;
 
 static
 void pc_machine_done(Notifier *notifier, void *data)
@@ -1247,9 +1163,6 @@ void pc_machine_done(Notifier *notifier, void *data)
                                         PCMachineState, machine_done);
     PCIBus *bus = pcms->bus;
 
-    /* set the number of CPUs */
-    rtc_set_memory(pcms->rtc, 0x5f, pc_present_cpus_count(pcms) - 1);
-
     if (bus) {
         int extra_hosts = 0;
 
@@ -1268,15 +1181,11 @@ void pc_machine_done(Notifier *notifier, void *data)
     }
 
     acpi_setup();
-    if (pcms->fw_cfg) {
-        pc_build_smbios(pcms->fw_cfg);
-        pc_build_feature_control_file(pcms);
-    }
 }
 
 void pc_guest_info_init(PCMachineState *pcms)
 {
-    int i;
+    int i, j;
 
     pcms->apic_xrupt_override = kvm_allows_irq0_override();
     pcms->numa_nodes = nb_numa_nodes;
@@ -1286,6 +1195,20 @@ void pc_guest_info_init(PCMachineState *pcms)
         pcms->node_mem[i] = numa_info[i].node_mem;
     }
 
+    pcms->node_cpu = g_malloc0(pcms->apic_id_limit *
+                                     sizeof *pcms->node_cpu);
+
+    for (i = 0; i < max_cpus; i++) {
+        unsigned int apic_id = x86_cpu_apic_id_from_index(i);
+        assert(apic_id < pcms->apic_id_limit);
+        for (j = 0; j < nb_numa_nodes; j++) {
+            if (test_bit(i, numa_info[j].node_cpu)) {
+                pcms->node_cpu[apic_id] = j;
+                break;
+            }
+        }
+    }
+
     pcms->machine_done.notify = pc_machine_done;
     qemu_add_machine_init_done_notifier(&pcms->machine_done);
 }
@@ -1340,7 +1263,6 @@ void xen_load_linux(PCMachineState *pcms)
     load_linux(pcms, fw_cfg);
     for (i = 0; i < nb_option_roms; i++) {
         assert(!strcmp(option_rom[i].name, "linuxboot.bin") ||
-               !strcmp(option_rom[i].name, "linuxboot_dma.bin") ||
                !strcmp(option_rom[i].name, "multiboot.bin"));
         rom_add_option(option_rom[i].name, option_rom[i].bootindex);
     }
@@ -1473,9 +1395,6 @@ void pc_memory_init(PCMachineState *pcms,
         rom_add_option(option_rom[i].name, option_rom[i].bootindex);
     }
     pcms->fw_cfg = fw_cfg;
-
-    /* Init default IOAPIC address space */
-    pcms->ioapic_as = &address_space_memory;
 }
 
 qemu_irq pc_allocate_cpu_irq(void)
@@ -1757,204 +1676,44 @@ static int pc_apic_cmp(const void *a, const void *b)
    return apic_a->arch_id - apic_b->arch_id;
 }
 
-/* returns pointer to CPUArchId descriptor that matches CPU's apic_id
- * in pcms->possible_cpus->cpus, if pcms->possible_cpus->cpus has no
- * entry correponding to CPU's apic_id returns NULL.
- */
-static CPUArchId *pc_find_cpu_slot(PCMachineState *pcms, CPUState *cpu,
-                                   int *idx)
-{
-    CPUClass *cc = CPU_GET_CLASS(cpu);
-    CPUArchId apic_id, *found_cpu;
-
-    apic_id.arch_id = cc->get_arch_id(CPU(cpu));
-    found_cpu = bsearch(&apic_id, pcms->possible_cpus->cpus,
-        pcms->possible_cpus->len, sizeof(*pcms->possible_cpus->cpus),
-        pc_apic_cmp);
-    if (found_cpu && idx) {
-        *idx = found_cpu - pcms->possible_cpus->cpus;
-    }
-    return found_cpu;
-}
-
 static void pc_cpu_plug(HotplugHandler *hotplug_dev,
                         DeviceState *dev, Error **errp)
 {
-    CPUArchId *found_cpu;
-    HotplugHandlerClass *hhc;
-    Error *local_err = NULL;
-    PCMachineState *pcms = PC_MACHINE(hotplug_dev);
-
-    if (pcms->acpi_dev) {
-        hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
-        hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
-        if (local_err) {
-            goto out;
-        }
-    }
-
-    if (dev->hotplugged) {
-        /* increment the number of CPUs */
-        rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1);
-    }
-
-    found_cpu = pc_find_cpu_slot(pcms, CPU(dev), NULL);
-    found_cpu->cpu = CPU(dev);
-out:
-    error_propagate(errp, local_err);
-}
-static void pc_cpu_unplug_request_cb(HotplugHandler *hotplug_dev,
-                                     DeviceState *dev, Error **errp)
-{
-    int idx = -1;
+    CPUClass *cc = CPU_GET_CLASS(dev);
+    CPUArchId apic_id, *found_cpu;
     HotplugHandlerClass *hhc;
     Error *local_err = NULL;
     PCMachineState *pcms = PC_MACHINE(hotplug_dev);
 
-    pc_find_cpu_slot(pcms, CPU(dev), &idx);
-    assert(idx != -1);
-    if (idx == 0) {
-        error_setg(&local_err, "Boot CPU is unpluggable");
+    if (!dev->hotplugged) {
         goto out;
     }
 
-    hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
-    hhc->unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
-
-    if (local_err) {
+    if (!pcms->acpi_dev) {
+        error_setg(&local_err,
+                   "cpu hotplug is not enabled: missing acpi device");
         goto out;
     }
 
- out:
-    error_propagate(errp, local_err);
-
-}
-
-static void pc_cpu_unplug_cb(HotplugHandler *hotplug_dev,
-                             DeviceState *dev, Error **errp)
-{
-    CPUArchId *found_cpu;
-    HotplugHandlerClass *hhc;
-    Error *local_err = NULL;
-    PCMachineState *pcms = PC_MACHINE(hotplug_dev);
-
     hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
-    hhc->unplug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
-
+    hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
     if (local_err) {
         goto out;
     }
 
-    found_cpu = pc_find_cpu_slot(pcms, CPU(dev), NULL);
-    found_cpu->cpu = NULL;
-    object_unparent(OBJECT(dev));
+    /* increment the number of CPUs */
+    rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1);
 
-    rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) - 1);
- out:
+    apic_id.arch_id = cc->get_arch_id(CPU(dev));
+    found_cpu = bsearch(&apic_id, pcms->possible_cpus->cpus,
+        pcms->possible_cpus->len, sizeof(*pcms->possible_cpus->cpus),
+        pc_apic_cmp);
+    assert(found_cpu);
+    found_cpu->cpu = CPU(dev);
+out:
     error_propagate(errp, local_err);
 }
 
-static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
-                            DeviceState *dev, Error **errp)
-{
-    int idx;
-    CPUState *cs;
-    CPUArchId *cpu_slot;
-    X86CPUTopoInfo topo;
-    X86CPU *cpu = X86_CPU(dev);
-    PCMachineState *pcms = PC_MACHINE(hotplug_dev);
-
-    /* if APIC ID is not set, set it based on socket/core/thread properties */
-    if (cpu->apic_id == UNASSIGNED_APIC_ID) {
-        int max_socket = (max_cpus - 1) / smp_threads / smp_cores;
-
-        if (cpu->socket_id < 0) {
-            error_setg(errp, "CPU socket-id is not set");
-            return;
-        } else if (cpu->socket_id > max_socket) {
-            error_setg(errp, "Invalid CPU socket-id: %u must be in range 0:%u",
-                       cpu->socket_id, max_socket);
-            return;
-        }
-        if (cpu->core_id < 0) {
-            error_setg(errp, "CPU core-id is not set");
-            return;
-        } else if (cpu->core_id > (smp_cores - 1)) {
-            error_setg(errp, "Invalid CPU core-id: %u must be in range 0:%u",
-                       cpu->core_id, smp_cores - 1);
-            return;
-        }
-        if (cpu->thread_id < 0) {
-            error_setg(errp, "CPU thread-id is not set");
-            return;
-        } else if (cpu->thread_id > (smp_threads - 1)) {
-            error_setg(errp, "Invalid CPU thread-id: %u must be in range 0:%u",
-                       cpu->thread_id, smp_threads - 1);
-            return;
-        }
-
-        topo.pkg_id = cpu->socket_id;
-        topo.core_id = cpu->core_id;
-        topo.smt_id = cpu->thread_id;
-        cpu->apic_id = apicid_from_topo_ids(smp_cores, smp_threads, &topo);
-    }
-
-    cpu_slot = pc_find_cpu_slot(pcms, CPU(dev), &idx);
-    if (!cpu_slot) {
-        x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);
-        error_setg(errp, "Invalid CPU [socket: %u, core: %u, thread: %u] with"
-                  " APIC ID %" PRIu32 ", valid index range 0:%d",
-                   topo.pkg_id, topo.core_id, topo.smt_id, cpu->apic_id,
-                   pcms->possible_cpus->len - 1);
-        return;
-    }
-
-    if (cpu_slot->cpu) {
-        error_setg(errp, "CPU[%d] with APIC ID %" PRIu32 " exists",
-                   idx, cpu->apic_id);
-        return;
-    }
-
-    /* if 'address' properties socket-id/core-id/thread-id are not set, set them
-     * so that query_hotpluggable_cpus would show correct values
-     */
-    /* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn()
-     * once -smp refactoring is complete and there will be CPU private
-     * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */
-    x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);
-    if (cpu->socket_id != -1 && cpu->socket_id != topo.pkg_id) {
-        error_setg(errp, "property socket-id: %u doesn't match set apic-id:"
-            " 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, topo.pkg_id);
-        return;
-    }
-    cpu->socket_id = topo.pkg_id;
-
-    if (cpu->core_id != -1 && cpu->core_id != topo.core_id) {
-        error_setg(errp, "property core-id: %u doesn't match set apic-id:"
-            " 0x%x (core-id: %u)", cpu->core_id, cpu->apic_id, topo.core_id);
-        return;
-    }
-    cpu->core_id = topo.core_id;
-
-    if (cpu->thread_id != -1 && cpu->thread_id != topo.smt_id) {
-        error_setg(errp, "property thread-id: %u doesn't match set apic-id:"
-            " 0x%x (thread-id: %u)", cpu->thread_id, cpu->apic_id, topo.smt_id);
-        return;
-    }
-    cpu->thread_id = topo.smt_id;
-
-    cs = CPU(cpu);
-    cs->cpu_index = idx;
-}
-
-static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
-                                          DeviceState *dev, Error **errp)
-{
-    if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
-        pc_cpu_pre_plug(hotplug_dev, dev, errp);
-    }
-}
-
 static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
                                       DeviceState *dev, Error **errp)
 {
@@ -1970,8 +1729,6 @@ static void pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
 {
     if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
         pc_dimm_unplug_request(hotplug_dev, dev, errp);
-    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
-        pc_cpu_unplug_request_cb(hotplug_dev, dev, errp);
     } else {
         error_setg(errp, "acpi: device unplug request for not supported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
@@ -1983,8 +1740,6 @@ static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
 {
     if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
         pc_dimm_unplug(hotplug_dev, dev, errp);
-    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
-        pc_cpu_unplug_cb(hotplug_dev, dev, errp);
     } else {
         error_setg(errp, "acpi: device unplug for not supported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
@@ -2137,7 +1892,7 @@ static void pc_machine_initfn(Object *obj)
                         pc_machine_get_hotplug_memory_region_size,
                         NULL, NULL, NULL, &error_abort);
 
-    pcms->max_ram_below_4g = 0; /* use default */
+    pcms->max_ram_below_4g = 1ULL << 32; /* 4G */
     object_property_add(obj, PC_MACHINE_MAX_RAM_BELOW_4G, "size",
                         pc_machine_get_max_ram_below_4g,
                         pc_machine_set_max_ram_below_4g,
@@ -2208,72 +1963,11 @@ static CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *machine)
     return list;
 }
 
-static HotpluggableCPUList *pc_query_hotpluggable_cpus(MachineState *machine)
-{
-    int i;
-    CPUState *cpu;
-    HotpluggableCPUList *head = NULL;
-    PCMachineState *pcms = PC_MACHINE(machine);
-    const char *cpu_type;
-
-    cpu = pcms->possible_cpus->cpus[0].cpu;
-    assert(cpu); /* BSP is always present */
-    cpu_type = object_class_get_name(OBJECT_CLASS(CPU_GET_CLASS(cpu)));
-
-    for (i = 0; i < pcms->possible_cpus->len; i++) {
-        X86CPUTopoInfo topo;
-        HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1);
-        HotpluggableCPU *cpu_item = g_new0(typeof(*cpu_item), 1);
-        CpuInstanceProperties *cpu_props = g_new0(typeof(*cpu_props), 1);
-        const uint32_t apic_id = pcms->possible_cpus->cpus[i].arch_id;
-
-        x86_topo_ids_from_apicid(apic_id, smp_cores, smp_threads, &topo);
-
-        cpu_item->type = g_strdup(cpu_type);
-        cpu_item->vcpus_count = 1;
-        cpu_props->has_socket_id = true;
-        cpu_props->socket_id = topo.pkg_id;
-        cpu_props->has_core_id = true;
-        cpu_props->core_id = topo.core_id;
-        cpu_props->has_thread_id = true;
-        cpu_props->thread_id = topo.smt_id;
-        cpu_item->props = cpu_props;
-
-        cpu = pcms->possible_cpus->cpus[i].cpu;
-        if (cpu) {
-            cpu_item->has_qom_path = true;
-            cpu_item->qom_path = object_get_canonical_path(OBJECT(cpu));
-        }
-
-        list_item->value = cpu_item;
-        list_item->next = head;
-        head = list_item;
-    }
-    return head;
-}
-
-static void x86_nmi(NMIState *n, int cpu_index, Error **errp)
-{
-    /* cpu index isn't used */
-    CPUState *cs;
-
-    CPU_FOREACH(cs) {
-        X86CPU *cpu = X86_CPU(cs);
-
-        if (!cpu->apic_state) {
-            cpu_interrupt(cs, CPU_INTERRUPT_NMI);
-        } else {
-            apic_deliver_nmi(cpu->apic_state);
-        }
-    }
-}
-
 static void pc_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
     PCMachineClass *pcmc = PC_MACHINE_CLASS(oc);
     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
-    NMIClass *nc = NMI_CLASS(oc);
 
     pcmc->get_hotplug_handler = mc->get_hotplug_handler;
     pcmc->pci_enabled = true;
@@ -2292,16 +1986,13 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
     mc->get_hotplug_handler = pc_get_hotpug_handler;
     mc->cpu_index_to_socket_id = pc_cpu_index_to_socket_id;
     mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
-    mc->query_hotpluggable_cpus = pc_query_hotpluggable_cpus;
     mc->default_boot_order = "cad";
     mc->hot_add_cpu = pc_hot_add_cpu;
     mc->max_cpus = 255;
     mc->reset = pc_machine_reset;
-    hc->pre_plug = pc_machine_device_pre_plug_cb;
     hc->plug = pc_machine_device_plug_cb;
     hc->unplug_request = pc_machine_device_unplug_request_cb;
     hc->unplug = pc_machine_device_unplug_cb;
-    nc->nmi_monitor_handler = x86_nmi;
 }
 
 static const TypeInfo pc_machine_info = {
@@ -2314,7 +2005,6 @@ static const TypeInfo pc_machine_info = {
     .class_init = pc_machine_class_init,
     .interfaces = (InterfaceInfo[]) {
          { TYPE_HOTPLUG_HANDLER },
-         { TYPE_NMI },
          { }
     },
 };
index a07dc81..7f50116 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "hw/hw.h"
 #include "hw/loader.h"
@@ -86,65 +87,42 @@ static void pc_init1(MachineState *machine,
     MemoryRegion *rom_memory;
     ram_addr_t lowmem;
 
-    /*
-     * Calculate ram split, for memory below and above 4G.  It's a bit
-     * complicated for backward compatibility reasons ...
-     *
-     *  - Traditional split is 3.5G (lowmem = 0xe0000000).  This is the
-     *    default value for max_ram_below_4g now.
-     *
-     *  - Then, to gigabyte align the memory, we move the split to 3G
-     *    (lowmem = 0xc0000000).  But only in case we have to split in
-     *    the first place, i.e. ram_size is larger than (traditional)
-     *    lowmem.  And for new machine types (gigabyte_align = true)
-     *    only, for live migration compatibility reasons.
-     *
-     *  - Next the max-ram-below-4g option was added, which allowed to
-     *    reduce lowmem to a smaller value, to allow a larger PCI I/O
-     *    window below 4G.  qemu doesn't enforce gigabyte alignment here,
-     *    but prints a warning.
-     *
-     *  - Finally max-ram-below-4g got updated to also allow raising lowmem,
-     *    so legacy non-PAE guests can get as much memory as possible in
-     *    the 32bit address space below 4G.
-     *
-     *  - Note that Xen has its own ram setp code in xen_ram_init(),
-     *    called via xen_hvm_init().
-     *
-     * Examples:
-     *    qemu -M pc-1.7 -m 4G    (old default)    -> 3584M low,  512M high
-     *    qemu -M pc -m 4G        (new default)    -> 3072M low, 1024M high
-     *    qemu -M pc,max-ram-below-4g=2G -m 4G     -> 2048M low, 2048M high
-     *    qemu -M pc,max-ram-below-4g=4G -m 3968M  -> 3968M low (=4G-128M)
+    /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory).
+     * If it doesn't, we need to split it in chunks below and above 4G.
+     * In any case, try to make sure that guest addresses aligned at
+     * 1G boundaries get mapped to host addresses aligned at 1G boundaries.
+     * For old machine types, use whatever split we used historically to avoid
+     * breaking migration.
      */
-    if (xen_enabled()) {
-        xen_hvm_init(pcms, &ram_memory);
+    if (machine->ram_size >= 0xe0000000) {
+        lowmem = pcmc->gigabyte_align ? 0xc0000000 : 0xe0000000;
     } else {
-        if (!pcms->max_ram_below_4g) {
-            pcms->max_ram_below_4g = 0xe0000000; /* default: 3.5G */
-        }
+        lowmem = 0xe0000000;
+    }
+
+    /* Handle the machine opt max-ram-below-4g.  It is basically doing
+     * min(qemu limit, user limit).
+     */
+    if (lowmem > pcms->max_ram_below_4g) {
         lowmem = pcms->max_ram_below_4g;
-        if (machine->ram_size >= pcms->max_ram_below_4g) {
-            if (pcmc->gigabyte_align) {
-                if (lowmem > 0xc0000000) {
-                    lowmem = 0xc0000000;
-                }
-                if (lowmem & ((1ULL << 30) - 1)) {
-                    error_report("Warning: Large machine and max_ram_below_4g "
-                                 "(%" PRIu64 ") not a multiple of 1G; "
-                                 "possible bad performance.",
-                                 pcms->max_ram_below_4g);
-                }
-            }
+        if (machine->ram_size - lowmem > lowmem &&
+            lowmem & ((1ULL << 30) - 1)) {
+            error_report("Warning: Large machine and max_ram_below_4g(%"PRIu64
+                         ") not a multiple of 1G; possible bad performance.",
+                         pcms->max_ram_below_4g);
         }
+    }
 
-        if (machine->ram_size >= lowmem) {
-            pcms->above_4g_mem_size = machine->ram_size - lowmem;
-            pcms->below_4g_mem_size = lowmem;
-        } else {
-            pcms->above_4g_mem_size = 0;
-            pcms->below_4g_mem_size = machine->ram_size;
-        }
+    if (machine->ram_size >= lowmem) {
+        pcms->above_4g_mem_size = machine->ram_size - lowmem;
+        pcms->below_4g_mem_size = lowmem;
+    } else {
+        pcms->above_4g_mem_size = 0;
+        pcms->below_4g_mem_size = machine->ram_size;
+    }
+
+    if (xen_enabled()) {
+        xen_hvm_init(pcms, &ram_memory);
     }
 
     pc_cpus_init(pcms);
@@ -268,7 +246,7 @@ static void pc_init1(MachineState *machine,
 
     pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state);
 
-    if (pcmc->pci_enabled && machine_usb(machine)) {
+    if (pcmc->pci_enabled && usb_enabled()) {
         pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci");
     }
 
@@ -438,27 +416,13 @@ static void pc_i440fx_machine_options(MachineClass *m)
     m->default_display = "std";
 }
 
-static void pc_i440fx_2_7_machine_options(MachineClass *m)
+static void pc_i440fx_2_6_machine_options(MachineClass *m)
 {
     pc_i440fx_machine_options(m);
     m->alias = "pc";
     m->is_default = 1;
 }
 
-DEFINE_I440FX_MACHINE(v2_7, "pc-i440fx-2.7", NULL,
-                      pc_i440fx_2_7_machine_options);
-
-
-static void pc_i440fx_2_6_machine_options(MachineClass *m)
-{
-    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
-    pc_i440fx_2_7_machine_options(m);
-    m->is_default = 0;
-    m->alias = NULL;
-    pcmc->legacy_cpu_hotplug = true;
-    SET_MACHINE_COMPAT(m, PC_COMPAT_2_6);
-}
-
 DEFINE_I440FX_MACHINE(v2_6, "pc-i440fx-2.6", NULL,
                       pc_i440fx_2_6_machine_options);
 
@@ -467,6 +431,8 @@ static void pc_i440fx_2_5_machine_options(MachineClass *m)
 {
     PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
     pc_i440fx_2_6_machine_options(m);
+    m->alias = NULL;
+    m->is_default = 0;
     pcmc->save_tsc_khz = false;
     m->legacy_fw_cfg_order = 1;
     SET_MACHINE_COMPAT(m, PC_COMPAT_2_5);
@@ -616,7 +582,7 @@ DEFINE_I440FX_MACHINE(v1_4, "pc-i440fx-1.4", pc_compat_1_4,
 
 
 #define PC_COMPAT_1_3 \
-        PC_CPU_MODEL_IDS("1.3.0") \
+        PC_COMPAT_1_4 \
         {\
             .driver   = "usb-tablet",\
             .property = "usb_version",\
@@ -648,7 +614,7 @@ DEFINE_I440FX_MACHINE(v1_3, "pc-1.3", pc_compat_1_3,
 
 
 #define PC_COMPAT_1_2 \
-        PC_CPU_MODEL_IDS("1.2.0") \
+        PC_COMPAT_1_3 \
         {\
             .driver   = "nec-usb-xhci",\
             .property = "msi",\
@@ -687,7 +653,7 @@ DEFINE_I440FX_MACHINE(v1_2, "pc-1.2", pc_compat_1_2,
 
 
 #define PC_COMPAT_1_1 \
-        PC_CPU_MODEL_IDS("1.1.0") \
+        PC_COMPAT_1_2 \
         {\
             .driver   = "virtio-scsi-pci",\
             .property = "hotplug",\
@@ -730,7 +696,7 @@ DEFINE_I440FX_MACHINE(v1_1, "pc-1.1", pc_compat_1_2,
 
 
 #define PC_COMPAT_1_0 \
-        PC_CPU_MODEL_IDS("1.0") \
+        PC_COMPAT_1_1 \
         {\
             .driver   = TYPE_ISA_FDC,\
             .property = "check_media_rate",\
@@ -761,7 +727,7 @@ DEFINE_I440FX_MACHINE(v1_0, "pc-1.0", pc_compat_1_2,
 
 
 #define PC_COMPAT_0_15 \
-        PC_CPU_MODEL_IDS("0.15")
+        PC_COMPAT_1_0
 
 static void pc_i440fx_0_15_machine_options(MachineClass *m)
 {
@@ -775,7 +741,7 @@ DEFINE_I440FX_MACHINE(v0_15, "pc-0.15", pc_compat_1_2,
 
 
 #define PC_COMPAT_0_14 \
-        PC_CPU_MODEL_IDS("0.14") \
+        PC_COMPAT_0_15 \
         {\
             .driver   = "virtio-blk-pci",\
             .property = "event_idx",\
@@ -814,7 +780,7 @@ DEFINE_I440FX_MACHINE(v0_14, "pc-0.14", pc_compat_1_2,
 
 
 #define PC_COMPAT_0_13 \
-        PC_CPU_MODEL_IDS("0.13") \
+        PC_COMPAT_0_14 \
         {\
             .driver   = TYPE_PCI_DEVICE,\
             .property = "command_serr_enable",\
@@ -851,7 +817,7 @@ DEFINE_I440FX_MACHINE(v0_13, "pc-0.13", pc_compat_0_13,
 
 
 #define PC_COMPAT_0_12 \
-        PC_CPU_MODEL_IDS("0.12") \
+        PC_COMPAT_0_13 \
         {\
             .driver   = "virtio-serial-pci",\
             .property = "max_ports",\
@@ -886,7 +852,7 @@ DEFINE_I440FX_MACHINE(v0_12, "pc-0.12", pc_compat_0_13,
 
 
 #define PC_COMPAT_0_11 \
-        PC_CPU_MODEL_IDS("0.11") \
+        PC_COMPAT_0_12 \
         {\
             .driver   = "virtio-blk-pci",\
             .property = "vectors",\
@@ -917,7 +883,7 @@ DEFINE_I440FX_MACHINE(v0_11, "pc-0.11", pc_compat_0_13,
 
 
 #define PC_COMPAT_0_10 \
-    PC_CPU_MODEL_IDS("0.10") \
+    PC_COMPAT_0_11 \
     {\
         .driver   = "virtio-blk-pci",\
         .property = "class",\
index c0b9961..04aae89 100644 (file)
@@ -60,7 +60,6 @@ static void pc_q35_init(MachineState *machine)
     PCIHostState *phb;
     PCIBus *host_bus;
     PCIDevice *lpc;
-    DeviceState *lpc_dev;
     BusState *idebus[MAX_SATA_PORTS];
     ISADevice *rtc_state;
     MemoryRegion *system_io = get_system_io();
@@ -94,9 +93,6 @@ static void pc_q35_init(MachineState *machine)
     /* Handle the machine opt max-ram-below-4g.  It is basically doing
      * min(qemu limit, user limit).
      */
-    if (!pcms->max_ram_below_4g) {
-        pcms->max_ram_below_4g = 1ULL << 32; /* default: 4G */;
-    }
     if (lowmem > pcms->max_ram_below_4g) {
         lowmem = pcms->max_ram_below_4g;
         if (machine->ram_size - lowmem > lowmem &&
@@ -163,22 +159,17 @@ static void pc_q35_init(MachineState *machine)
     q35_host = Q35_HOST_DEVICE(qdev_create(NULL, TYPE_Q35_HOST_DEVICE));
 
     object_property_add_child(qdev_get_machine(), "q35", OBJECT(q35_host), NULL);
-    object_property_set_link(OBJECT(q35_host), OBJECT(ram_memory),
-                             MCH_HOST_PROP_RAM_MEM, NULL);
-    object_property_set_link(OBJECT(q35_host), OBJECT(pci_memory),
-                             MCH_HOST_PROP_PCI_MEM, NULL);
-    object_property_set_link(OBJECT(q35_host), OBJECT(get_system_memory()),
-                             MCH_HOST_PROP_SYSTEM_MEM, NULL);
-    object_property_set_link(OBJECT(q35_host), OBJECT(system_io),
-                             MCH_HOST_PROP_IO_MEM, NULL);
-    object_property_set_int(OBJECT(q35_host), pcms->below_4g_mem_size,
-                            PCI_HOST_BELOW_4G_MEM_SIZE, NULL);
-    object_property_set_int(OBJECT(q35_host), pcms->above_4g_mem_size,
-                            PCI_HOST_ABOVE_4G_MEM_SIZE, NULL);
+    q35_host->mch.ram_memory = ram_memory;
+    q35_host->mch.pci_address_space = pci_memory;
+    q35_host->mch.system_memory = get_system_memory();
+    q35_host->mch.address_space_io = system_io;
+    q35_host->mch.below_4g_mem_size = pcms->below_4g_mem_size;
+    q35_host->mch.above_4g_mem_size = pcms->above_4g_mem_size;
     /* pci */
     qdev_init_nofail(DEVICE(q35_host));
     phb = PCI_HOST_BRIDGE(q35_host);
     host_bus = phb->bus;
+    pcms->bus = phb->bus;
     /* create ISA bus */
     lpc = pci_create_simple_multifunction(host_bus, PCI_DEVFN(ICH9_LPC_DEV,
                                           ICH9_LPC_FUNC), true,
@@ -193,15 +184,16 @@ static void pc_q35_init(MachineState *machine)
                              PC_MACHINE_ACPI_DEVICE_PROP, &error_abort);
 
     ich9_lpc = ICH9_LPC_DEVICE(lpc);
-    lpc_dev = DEVICE(lpc);
-    for (i = 0; i < GSI_NUM_PINS; i++) {
-        qdev_connect_gpio_out_named(lpc_dev, ICH9_GPIO_GSI, i, gsi[i]);
-    }
+    ich9_lpc->pic = gsi;
+    ich9_lpc->ioapic = gsi_state->ioapic_irq;
     pci_bus_irqs(host_bus, ich9_lpc_set_irq, ich9_lpc_map_irq, ich9_lpc,
                  ICH9_LPC_NB_PIRQS);
     pci_bus_set_route_irq_fn(host_bus, ich9_route_intx_pin_to_irq);
     isa_bus = ich9_lpc->isa_bus;
 
+    /*end early*/
+    isa_bus_irqs(isa_bus, gsi);
+
     if (kvm_pic_in_kernel()) {
         i8259 = kvm_i8259_init(isa_bus);
     } else if (xen_enabled()) {
@@ -242,7 +234,7 @@ static void pc_q35_init(MachineState *machine)
     ide_drive_get(hd, ICH_AHCI(ahci)->ahci.ports);
     ahci_ide_create_devs(ahci, hd);
 
-    if (machine_usb(machine)) {
+    if (usb_enabled()) {
         /* Should we create 6 UHCI according to ich9 spec? */
         ehci_create_ich9_with_companions(host_bus, 0x1d);
     }
@@ -289,27 +281,14 @@ static void pc_q35_machine_options(MachineClass *m)
     m->default_machine_opts = "firmware=bios-256k.bin";
     m->default_display = "std";
     m->no_floppy = 1;
-    m->has_dynamic_sysbus = true;
 }
 
-static void pc_q35_2_7_machine_options(MachineClass *m)
+static void pc_q35_2_6_machine_options(MachineClass *m)
 {
     pc_q35_machine_options(m);
     m->alias = "q35";
 }
 
-DEFINE_Q35_MACHINE(v2_7, "pc-q35-2.7", NULL,
-                   pc_q35_2_7_machine_options);
-
-static void pc_q35_2_6_machine_options(MachineClass *m)
-{
-    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
-    pc_q35_2_7_machine_options(m);
-    m->alias = NULL;
-    pcmc->legacy_cpu_hotplug = true;
-    SET_MACHINE_COMPAT(m, PC_COMPAT_2_6);
-}
-
 DEFINE_Q35_MACHINE(v2_6, "pc-q35-2.6", NULL,
                    pc_q35_2_6_machine_options);
 
@@ -317,6 +296,7 @@ static void pc_q35_2_5_machine_options(MachineClass *m)
 {
     PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
     pc_q35_2_6_machine_options(m);
+    m->alias = NULL;
     pcmc->save_tsc_khz = false;
     m->legacy_fw_cfg_order = 1;
     SET_MACHINE_COMPAT(m, PC_COMPAT_2_5);
diff --git a/hw/i386/trace-events b/hw/i386/trace-events
deleted file mode 100644 (file)
index 7735e46..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/i386/xen/xen_platform.c
-xen_platform_log(char *s) "xen platform: %s"
-
-# hw/i386/xen/xen_pvdevice.c
-xen_pv_mmio_read(uint64_t addr) "WARNING: read from Xen PV Device MMIO space (address %"PRIx64")"
-xen_pv_mmio_write(uint64_t addr) "WARNING: write to Xen PV Device MMIO space (address %"PRIx64")"
-
-# hw/i386/pc.c
-mhp_pc_dimm_assigned_slot(int slot) "0x%d"
-mhp_pc_dimm_assigned_address(uint64_t addr) "0x%"PRIx64
-
-# hw/i386/x86-iommu.c
-x86_iommu_iec_notify(bool global, uint32_t index, uint32_t mask) "Notify IEC invalidation: global=%d index=%" PRIu32 " mask=%" PRIu32
diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c
deleted file mode 100644 (file)
index ce26b2a..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * QEMU emulation of common X86 IOMMU
- *
- * Copyright (C) 2016 Peter Xu, Red Hat <peterx@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "hw/sysbus.h"
-#include "hw/boards.h"
-#include "hw/i386/x86-iommu.h"
-#include "qemu/error-report.h"
-#include "trace.h"
-
-void x86_iommu_iec_register_notifier(X86IOMMUState *iommu,
-                                     iec_notify_fn fn, void *data)
-{
-    IEC_Notifier *notifier = g_new0(IEC_Notifier, 1);
-
-    notifier->iec_notify = fn;
-    notifier->private = data;
-
-    QLIST_INSERT_HEAD(&iommu->iec_notifiers, notifier, list);
-}
-
-void x86_iommu_iec_notify_all(X86IOMMUState *iommu, bool global,
-                              uint32_t index, uint32_t mask)
-{
-    IEC_Notifier *notifier;
-
-    trace_x86_iommu_iec_notify(global, index, mask);
-
-    QLIST_FOREACH(notifier, &iommu->iec_notifiers, list) {
-        if (notifier->iec_notify) {
-            notifier->iec_notify(notifier->private, global,
-                                 index, mask);
-        }
-    }
-}
-
-/* Default X86 IOMMU device */
-static X86IOMMUState *x86_iommu_default = NULL;
-
-static void x86_iommu_set_default(X86IOMMUState *x86_iommu)
-{
-    assert(x86_iommu);
-
-    if (x86_iommu_default) {
-        error_report("QEMU does not support multiple vIOMMUs "
-                     "for x86 yet.");
-        exit(1);
-    }
-
-    x86_iommu_default = x86_iommu;
-}
-
-X86IOMMUState *x86_iommu_get_default(void)
-{
-    return x86_iommu_default;
-}
-
-static void x86_iommu_realize(DeviceState *dev, Error **errp)
-{
-    X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
-    X86IOMMUClass *x86_class = X86_IOMMU_GET_CLASS(dev);
-    QLIST_INIT(&x86_iommu->iec_notifiers);
-    if (x86_class->realize) {
-        x86_class->realize(dev, errp);
-    }
-    x86_iommu_set_default(X86_IOMMU_DEVICE(dev));
-}
-
-static void x86_iommu_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    dc->realize = x86_iommu_realize;
-}
-
-static bool x86_iommu_intremap_prop_get(Object *o, Error **errp)
-{
-    X86IOMMUState *s = X86_IOMMU_DEVICE(o);
-    return s->intr_supported;
-}
-
-static void x86_iommu_intremap_prop_set(Object *o, bool value, Error **errp)
-{
-    X86IOMMUState *s = X86_IOMMU_DEVICE(o);
-    s->intr_supported = value;
-}
-
-static void x86_iommu_instance_init(Object *o)
-{
-    X86IOMMUState *s = X86_IOMMU_DEVICE(o);
-
-    /* By default, do not support IR */
-    s->intr_supported = false;
-    object_property_add_bool(o, "intremap", x86_iommu_intremap_prop_get,
-                             x86_iommu_intremap_prop_set, NULL);
-}
-
-static const TypeInfo x86_iommu_info = {
-    .name          = TYPE_X86_IOMMU_DEVICE,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_init = x86_iommu_instance_init,
-    .instance_size = sizeof(X86IOMMUState),
-    .class_init    = x86_iommu_class_init,
-    .class_size    = sizeof(X86IOMMUClass),
-    .abstract      = true,
-};
-
-static void x86_iommu_register_types(void)
-{
-    type_register_static(&x86_iommu_info);
-}
-
-type_init(x86_iommu_register_types)
index f3438ad..a1e6516 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/pci/msi.h"
-#include "hw/i386/pc.h"
-#include "hw/pci/pci.h"
+#include <hw/hw.h>
+#include <hw/pci/msi.h>
+#include <hw/i386/pc.h>
+#include <hw/pci/pci.h>
 
 #include "qemu/error-report.h"
 #include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
-#include "hw/ide/internal.h"
-#include "hw/ide/pci.h"
-#include "hw/ide/ahci.h"
+#include "internal.h"
+#include <hw/ide/pci.h>
+#include <hw/ide/ahci.h>
 
 #define DEBUG_AHCI 0
 
@@ -1007,8 +1007,7 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
         dma_acct_start(ide_state->blk, &ncq_tfs->acct,
                        &ncq_tfs->sglist, BLOCK_ACCT_READ);
         ncq_tfs->aiocb = dma_blk_read(ide_state->blk, &ncq_tfs->sglist,
-                                      ncq_tfs->lba << BDRV_SECTOR_BITS,
-                                      ncq_cb, ncq_tfs);
+                                      ncq_tfs->lba, ncq_cb, ncq_tfs);
         break;
     case WRITE_FPDMA_QUEUED:
         DPRINTF(port, "NCQ writing %d sectors to LBA %"PRId64", tag %d\n",
@@ -1020,8 +1019,7 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
         dma_acct_start(ide_state->blk, &ncq_tfs->acct,
                        &ncq_tfs->sglist, BLOCK_ACCT_WRITE);
         ncq_tfs->aiocb = dma_blk_write(ide_state->blk, &ncq_tfs->sglist,
-                                       ncq_tfs->lba << BDRV_SECTOR_BITS,
-                                       ncq_cb, ncq_tfs);
+                                       ncq_tfs->lba, ncq_cb, ncq_tfs);
         break;
     default:
         DPRINTF(port, "error: unsupported NCQ command (0x%02x) received\n",
similarity index 99%
rename from include/hw/ide/ahci.h
rename to hw/ide/ahci.h
index 0ca7c65..bc777ed 100644 (file)
@@ -24,7 +24,7 @@
 #ifndef HW_IDE_AHCI_H
 #define HW_IDE_AHCI_H
 
-#include "hw/sysbus.h"
+#include <hw/sysbus.h>
 
 #define AHCI_MEM_BAR_SIZE         0x1000
 #define AHCI_MAX_PORTS            32
index 6189675..8592a4a 100644 (file)
@@ -28,9 +28,6 @@
 #include "hw/scsi/scsi.h"
 #include "sysemu/block-backend.h"
 
-#define ATAPI_SECTOR_BITS (2 + BDRV_SECTOR_BITS)
-#define ATAPI_SECTOR_SIZE (1 << ATAPI_SECTOR_BITS)
-
 static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
 
 static void padstr8(uint8_t *buf, int buf_size, const char *src)
@@ -114,7 +111,7 @@ cd_read_sector_sync(IDEState *s)
 {
     int ret;
     block_acct_start(blk_get_stats(s->blk), &s->acct,
-                     ATAPI_SECTOR_SIZE, BLOCK_ACCT_READ);
+                     4 * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
 
 #ifdef DEBUG_IDE_ATAPI
     printf("cd_read_sector_sync: lba=%d\n", s->lba);
@@ -122,12 +119,12 @@ cd_read_sector_sync(IDEState *s)
 
     switch (s->cd_sector_size) {
     case 2048:
-        ret = blk_pread(s->blk, (int64_t)s->lba << ATAPI_SECTOR_BITS,
-                        s->io_buffer, ATAPI_SECTOR_SIZE);
+        ret = blk_read(s->blk, (int64_t)s->lba << 2,
+                       s->io_buffer, 4);
         break;
     case 2352:
-        ret = blk_pread(s->blk, (int64_t)s->lba << ATAPI_SECTOR_BITS,
-                        s->io_buffer + 16, ATAPI_SECTOR_SIZE);
+        ret = blk_read(s->blk, (int64_t)s->lba << 2,
+                       s->io_buffer + 16, 4);
         if (ret >= 0) {
             cd_data_to_raw(s->io_buffer, s->lba);
         }
@@ -185,7 +182,7 @@ static int cd_read_sector(IDEState *s)
     s->iov.iov_base = (s->cd_sector_size == 2352) ?
                       s->io_buffer + 16 : s->io_buffer;
 
-    s->iov.iov_len = ATAPI_SECTOR_SIZE;
+    s->iov.iov_len = 4 * BDRV_SECTOR_SIZE;
     qemu_iovec_init_external(&s->qiov, &s->iov, 1);
 
 #ifdef DEBUG_IDE_ATAPI
@@ -193,7 +190,7 @@ static int cd_read_sector(IDEState *s)
 #endif
 
     block_acct_start(blk_get_stats(s->blk), &s->acct,
-                     ATAPI_SECTOR_SIZE, BLOCK_ACCT_READ);
+                     4 * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
 
     ide_buffered_readv(s, (int64_t)s->lba << 2, &s->qiov, 4,
                        cd_read_sector_cb, s);
@@ -439,7 +436,7 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
 #endif
 
     s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
-    s->bus->dma->iov.iov_len = n * ATAPI_SECTOR_SIZE;
+    s->bus->dma->iov.iov_len = n * 4 * 512;
     qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
 
     s->bus->dma->aiocb = ide_buffered_readv(s, (int64_t)s->lba << 2,
index 9ebb8d4..49294a5 100644 (file)
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/pci/pci.h"
-#include "hw/isa/isa.h"
+#include <hw/hw.h>
+#include <hw/i386/pc.h>
+#include <hw/pci/pci.h>
+#include <hw/isa/isa.h>
 #include "sysemu/block-backend.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/dma.h"
 
-#include "hw/ide/pci.h"
+#include <hw/ide/pci.h>
 
 /* CMD646 specific */
 #define CFR            0x50
index 45b6df1..aa11f13 100644 (file)
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/pci/pci.h"
-#include "hw/isa/isa.h"
+#include <hw/hw.h>
+#include <hw/i386/pc.h>
+#include <hw/pci/pci.h>
+#include <hw/isa/isa.h>
 #include "qemu/error-report.h"
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
@@ -35,7 +35,7 @@
 #include "sysemu/block-backend.h"
 #include "qemu/cutils.h"
 
-#include "hw/ide/internal.h"
+#include <hw/ide/internal.h>
 
 /* These values were based on a Seagate ST3500418AS but have been modified
    to make more sense in QEMU */
@@ -423,10 +423,8 @@ static void ide_issue_trim_cb(void *opaque, int ret)
                 }
 
                 /* Got an entry! Submit and exit.  */
-                iocb->aiocb = blk_aio_pdiscard(iocb->blk,
-                                               sector << BDRV_SECTOR_BITS,
-                                               count << BDRV_SECTOR_BITS,
-                                               ide_issue_trim_cb, opaque);
+                iocb->aiocb = blk_aio_discard(iocb->blk, sector, count,
+                                              ide_issue_trim_cb, opaque);
                 return;
             }
 
@@ -443,14 +441,13 @@ static void ide_issue_trim_cb(void *opaque, int ret)
     }
 }
 
-BlockAIOCB *ide_issue_trim(
-        int64_t offset, QEMUIOVector *qiov,
-        BlockCompletionFunc *cb, void *cb_opaque, void *opaque)
+BlockAIOCB *ide_issue_trim(BlockBackend *blk,
+        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+        BlockCompletionFunc *cb, void *opaque)
 {
-    BlockBackend *blk = opaque;
     TrimAIOCB *iocb;
 
-    iocb = blk_aio_get(&trim_aiocb_info, blk, cb, cb_opaque);
+    iocb = blk_aio_get(&trim_aiocb_info, blk, cb, opaque);
     iocb->blk = blk;
     iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
     iocb->ret = 0;
@@ -468,20 +465,6 @@ void ide_abort_command(IDEState *s)
     s->error = ABRT_ERR;
 }
 
-static void ide_set_retry(IDEState *s)
-{
-    s->bus->retry_unit = s->unit;
-    s->bus->retry_sector_num = ide_get_sector(s);
-    s->bus->retry_nsector = s->nsector;
-}
-
-static void ide_clear_retry(IDEState *s)
-{
-    s->bus->retry_unit = -1;
-    s->bus->retry_sector_num = 0;
-    s->bus->retry_nsector = 0;
-}
-
 /* prepare data transfer and tell what to do after */
 void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
                         EndTransferFunc *end_transfer_func)
@@ -489,7 +472,6 @@ void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
     s->end_transfer_func = end_transfer_func;
     s->data_ptr = buf;
     s->data_end = buf + size;
-    ide_set_retry(s);
     if (!(s->status & ERR_STAT)) {
         s->status |= DRQ_STAT;
     }
@@ -634,8 +616,8 @@ BlockAIOCB *ide_buffered_readv(IDEState *s, int64_t sector_num,
     req->iov.iov_len = iov->size;
     qemu_iovec_init_external(&req->qiov, &req->iov, 1);
 
-    aioreq = blk_aio_preadv(s->blk, sector_num << BDRV_SECTOR_BITS,
-                            &req->qiov, 0, ide_buffered_readv_cb, req);
+    aioreq = blk_aio_readv(s->blk, sector_num, &req->qiov, nb_sectors,
+                           ide_buffered_readv_cb, req);
 
     QLIST_INSERT_HEAD(&s->buffered_requests, req, list);
     return aioreq;
@@ -773,7 +755,9 @@ void dma_buf_commit(IDEState *s, uint32_t tx_bytes)
 void ide_set_inactive(IDEState *s, bool more)
 {
     s->bus->dma->aiocb = NULL;
-    ide_clear_retry(s);
+    s->bus->retry_unit = -1;
+    s->bus->retry_sector_num = 0;
+    s->bus->retry_nsector = 0;
     if (s->bus->dma->ops->set_inactive) {
         s->bus->dma->ops->set_inactive(s->bus->dma, more);
     }
@@ -815,7 +799,6 @@ static void ide_dma_cb(void *opaque, int ret)
     IDEState *s = opaque;
     int n;
     int64_t sector_num;
-    uint64_t offset;
     bool stay_active = false;
 
     if (ret == -ECANCELED) {
@@ -878,20 +861,18 @@ static void ide_dma_cb(void *opaque, int ret)
         return;
     }
 
-    offset = sector_num << BDRV_SECTOR_BITS;
     switch (s->dma_cmd) {
     case IDE_DMA_READ:
-        s->bus->dma->aiocb = dma_blk_read(s->blk, &s->sg, offset,
+        s->bus->dma->aiocb = dma_blk_read(s->blk, &s->sg, sector_num,
                                           ide_dma_cb, s);
         break;
     case IDE_DMA_WRITE:
-        s->bus->dma->aiocb = dma_blk_write(s->blk, &s->sg, offset,
+        s->bus->dma->aiocb = dma_blk_write(s->blk, &s->sg, sector_num,
                                            ide_dma_cb, s);
         break;
     case IDE_DMA_TRIM:
-        s->bus->dma->aiocb = dma_blk_io(blk_get_aio_context(s->blk),
-                                        &s->sg, offset,
-                                        ide_issue_trim, s->blk, ide_dma_cb, s,
+        s->bus->dma->aiocb = dma_blk_io(s->blk, &s->sg, sector_num,
+                                        ide_issue_trim, ide_dma_cb, s,
                                         DMA_DIRECTION_TO_DEVICE);
         break;
     default:
@@ -931,7 +912,9 @@ static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
 void ide_start_dma(IDEState *s, BlockCompletionFunc *cb)
 {
     s->io_buffer_index = 0;
-    ide_set_retry(s);
+    s->bus->retry_unit = s->unit;
+    s->bus->retry_sector_num = ide_get_sector(s);
+    s->bus->retry_nsector = s->nsector;
     if (s->bus->dma->ops->start_dma) {
         s->bus->dma->ops->start_dma(s->bus->dma, s, cb);
     }
@@ -1025,8 +1008,8 @@ static void ide_sector_write(IDEState *s)
 
     block_acct_start(blk_get_stats(s->blk), &s->acct,
                      n * BDRV_SECTOR_SIZE, BLOCK_ACCT_WRITE);
-    s->pio_aiocb = blk_aio_pwritev(s->blk, sector_num << BDRV_SECTOR_BITS,
-                                   &s->qiov, 0, ide_sector_write_cb, s);
+    s->pio_aiocb = blk_aio_writev(s->blk, sector_num, &s->qiov, n,
+                                  ide_sector_write_cb, s);
 }
 
 static void ide_flush_cb(void *opaque, int ret)
@@ -1061,7 +1044,6 @@ static void ide_flush_cache(IDEState *s)
     }
 
     s->status |= BUSY_STAT;
-    ide_set_retry(s);
     block_acct_start(blk_get_stats(s->blk), &s->acct, 0, BLOCK_ACCT_FLUSH);
     s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s);
 }
index 4599169..0a13334 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/pci/msi.h"
-#include "hw/i386/pc.h"
-#include "hw/pci/pci.h"
-#include "hw/isa/isa.h"
+#include <hw/hw.h>
+#include <hw/pci/msi.h>
+#include <hw/i386/pc.h>
+#include <hw/pci/pci.h>
+#include <hw/isa/isa.h>
 #include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
-#include "hw/ide/pci.h"
-#include "hw/ide/ahci.h"
+
+#include <hw/ide/pci.h>
+#include <hw/ide/ahci.h>
 
 #define ICH9_MSI_CAP_OFFSET     0x80
 #define ICH9_SATA_CAP_OFFSET    0xA8
@@ -110,7 +111,6 @@ static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp)
     int sata_cap_offset;
     uint8_t *sata_cap;
     d = ICH_AHCI(dev);
-    int ret;
 
     ahci_realize(&d->ahci, DEVICE(dev), pci_get_address_space(dev), 6);
 
@@ -146,10 +146,7 @@ static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp)
     /* Although the AHCI 1.3 specification states that the first capability
      * should be PMCAP, the Intel ICH9 data sheet specifies that the ICH9
      * AHCI device puts the MSI capability first, pointing to 0x80. */
-    ret = msi_init(dev, ICH9_MSI_CAP_OFFSET, 1, true, false, NULL);
-    /* Any error other than -ENOTSUP(board's MSI support is broken)
-     * is a programming error.  Fall back to INTx silently on -ENOTSUP */
-    assert(!ret || ret == -ENOTSUP);
+    msi_init(dev, ICH9_MSI_CAP_OFFSET, 1, true, false);
 }
 
 static void pci_ich9_uninit(PCIDevice *dev)
similarity index 99%
rename from include/hw/ide/internal.h
rename to hw/ide/internal.h
index 7824bc3..d2c458f 100644 (file)
@@ -6,8 +6,8 @@
  * only files in hw/ide/ are supposed to include this file.
  * non-internal declarations are in hw/ide.h
  */
-#include "hw/ide.h"
-#include "hw/isa/isa.h"
+#include <hw/ide.h>
+#include <hw/isa/isa.h>
 #include "sysemu/dma.h"
 #include "sysemu/sysemu.h"
 #include "hw/block/block.h"
@@ -613,9 +613,9 @@ void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
                         EndTransferFunc *end_transfer_func);
 void ide_transfer_stop(IDEState *s);
 void ide_set_inactive(IDEState *s, bool more);
-BlockAIOCB *ide_issue_trim(
-        int64_t offset, QEMUIOVector *qiov,
-        BlockCompletionFunc *cb, void *cb_opaque, void *opaque);
+BlockAIOCB *ide_issue_trim(BlockBackend *blk,
+        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+        BlockCompletionFunc *cb, void *opaque);
 BlockAIOCB *ide_buffered_readv(IDEState *s, int64_t sector_num,
                                QEMUIOVector *iov, int nb_sectors,
                                BlockCompletionFunc *cb, void *opaque);
index 40213d6..eba567c 100644 (file)
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/isa/isa.h"
+#include <hw/hw.h>
+#include <hw/i386/pc.h>
+#include <hw/isa/isa.h>
 #include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
 
-#include "hw/ide/internal.h"
+#include <hw/ide/internal.h>
 
 /***********************************************************/
 /* ISA IDE definitions */
index 76f97c2..664328d 100644 (file)
@@ -29,7 +29,7 @@
 #include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
 
-#include "hw/ide/internal.h"
+#include <hw/ide/internal.h>
 
 /* debug MACIO */
 // #define DEBUG_MACIO
@@ -55,8 +55,8 @@ static const int debug_macio = 0;
 /*
  * Unaligned DMA read/write access functions required for OS X/Darwin which
  * don't perform DMA transactions on sector boundaries. These functions are
- * modelled on bdrv_co_preadv()/bdrv_co_pwritev() and so should be easy to
- * remove if the unaligned block APIs are ever exposed.
+ * modelled on bdrv_co_do_preadv()/bdrv_co_do_pwritev() and so should be
+ * easy to remove if the unaligned block APIs are ever exposed.
  */
 
 static void pmac_dma_read(BlockBackend *blk,
@@ -66,7 +66,8 @@ static void pmac_dma_read(BlockBackend *blk,
     DBDMA_io *io = opaque;
     MACIOIDEState *m = io->opaque;
     IDEState *s = idebus_active_if(&m->bus);
-    dma_addr_t dma_addr;
+    dma_addr_t dma_addr, dma_len;
+    void *mem;
     int64_t sector_num;
     int nsector;
     uint64_t align = BDRV_SECTOR_SIZE;
@@ -83,10 +84,9 @@ static void pmac_dma_read(BlockBackend *blk,
                   sector_num, nsector);
 
     dma_addr = io->addr;
-    io->dir = DMA_DIRECTION_FROM_DEVICE;
-    io->dma_len = io->len;
-    io->dma_mem = dma_memory_map(&address_space_memory, dma_addr, &io->dma_len,
-                                 io->dir);
+    dma_len = io->len;
+    mem = dma_memory_map(&address_space_memory, dma_addr, &dma_len,
+                         DMA_DIRECTION_FROM_DEVICE);
 
     if (offset & (align - 1)) {
         head_bytes = offset & (align - 1);
@@ -100,7 +100,7 @@ static void pmac_dma_read(BlockBackend *blk,
         offset = offset & ~(align - 1);
     }
 
-    qemu_iovec_add(&io->iov, io->dma_mem, io->len);
+    qemu_iovec_add(&io->iov, mem, io->len);
 
     if ((offset + bytes) & (align - 1)) {
         tail_bytes = (offset + bytes) & (align - 1);
@@ -120,7 +120,8 @@ static void pmac_dma_read(BlockBackend *blk,
     MACIO_DPRINTF("--- Block read transfer - sector_num: %" PRIx64 "  "
                   "nsector: %x\n", (offset >> 9), (bytes >> 9));
 
-    s->bus->dma->aiocb = blk_aio_preadv(blk, offset, &io->iov, 0, cb, io);
+    s->bus->dma->aiocb = blk_aio_readv(blk, (offset >> 9), &io->iov,
+                             (bytes >> 9), cb, io);
 }
 
 static void pmac_dma_write(BlockBackend *blk,
@@ -130,7 +131,8 @@ static void pmac_dma_write(BlockBackend *blk,
     DBDMA_io *io = opaque;
     MACIOIDEState *m = io->opaque;
     IDEState *s = idebus_active_if(&m->bus);
-    dma_addr_t dma_addr;
+    dma_addr_t dma_addr, dma_len;
+    void *mem;
     int64_t sector_num;
     int nsector;
     uint64_t align = BDRV_SECTOR_SIZE;
@@ -148,10 +150,9 @@ static void pmac_dma_write(BlockBackend *blk,
                   sector_num, nsector);
 
     dma_addr = io->addr;
-    io->dir = DMA_DIRECTION_TO_DEVICE;
-    io->dma_len = io->len;
-    io->dma_mem = dma_memory_map(&address_space_memory, dma_addr, &io->dma_len,
-                                 io->dir);
+    dma_len = io->len;
+    mem = dma_memory_map(&address_space_memory, dma_addr, &dma_len,
+                         DMA_DIRECTION_TO_DEVICE);
 
     if (offset & (align - 1)) {
         head_bytes = offset & (align - 1);
@@ -163,7 +164,7 @@ static void pmac_dma_write(BlockBackend *blk,
         blk_pread(s->blk, (sector_num << 9), &io->head_remainder, align);
 
         qemu_iovec_add(&io->iov, &io->head_remainder, head_bytes);
-        qemu_iovec_add(&io->iov, io->dma_mem, io->len);
+        qemu_iovec_add(&io->iov, mem, io->len);
 
         bytes += offset & (align - 1);
         offset = offset & ~(align - 1);
@@ -181,7 +182,7 @@ static void pmac_dma_write(BlockBackend *blk,
         blk_pread(s->blk, (sector_num << 9), &io->tail_remainder, align);
 
         if (!unaligned_head) {
-            qemu_iovec_add(&io->iov, io->dma_mem, io->len);
+            qemu_iovec_add(&io->iov, mem, io->len);
         }
 
         qemu_iovec_add(&io->iov, &io->tail_remainder + tail_bytes,
@@ -193,7 +194,7 @@ static void pmac_dma_write(BlockBackend *blk,
     }
 
     if (!unaligned_head && !unaligned_tail) {
-        qemu_iovec_add(&io->iov, io->dma_mem, io->len);
+        qemu_iovec_add(&io->iov, mem, io->len);
     }
 
     s->io_buffer_size -= io->len;
@@ -204,7 +205,8 @@ static void pmac_dma_write(BlockBackend *blk,
     MACIO_DPRINTF("--- Block write transfer - sector_num: %" PRIx64 "  "
                   "nsector: %x\n", (offset >> 9), (bytes >> 9));
 
-    s->bus->dma->aiocb = blk_aio_pwritev(blk, offset, &io->iov, 0, cb, io);
+    s->bus->dma->aiocb = blk_aio_writev(blk, (offset >> 9), &io->iov,
+                             (bytes >> 9), cb, io);
 }
 
 static void pmac_dma_trim(BlockBackend *blk,
@@ -214,23 +216,24 @@ static void pmac_dma_trim(BlockBackend *blk,
     DBDMA_io *io = opaque;
     MACIOIDEState *m = io->opaque;
     IDEState *s = idebus_active_if(&m->bus);
-    dma_addr_t dma_addr;
+    dma_addr_t dma_addr, dma_len;
+    void *mem;
 
     qemu_iovec_destroy(&io->iov);
     qemu_iovec_init(&io->iov, io->len / MACIO_PAGE_SIZE + 1);
 
     dma_addr = io->addr;
-    io->dir = DMA_DIRECTION_TO_DEVICE;
-    io->dma_len = io->len;
-    io->dma_mem = dma_memory_map(&address_space_memory, dma_addr, &io->dma_len,
-                                 io->dir);
+    dma_len = io->len;
+    mem = dma_memory_map(&address_space_memory, dma_addr, &dma_len,
+                         DMA_DIRECTION_TO_DEVICE);
 
-    qemu_iovec_add(&io->iov, io->dma_mem, io->len);
+    qemu_iovec_add(&io->iov, mem, io->len);
     s->io_buffer_size -= io->len;
     s->io_buffer_index += io->len;
     io->len = 0;
 
-    s->bus->dma->aiocb = ide_issue_trim(offset, &io->iov, cb, io, blk);
+    s->bus->dma->aiocb = ide_issue_trim(blk, (offset >> 9), &io->iov,
+                             (bytes >> 9), cb, io);
 }
 
 static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
@@ -271,8 +274,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
     if (s->lba == -1) {
         /* Non-block ATAPI transfer - just copy to RAM */
         s->io_buffer_size = MIN(s->io_buffer_size, io->len);
-        dma_memory_write(&address_space_memory, io->addr, s->io_buffer,
-                         s->io_buffer_size);
+        cpu_physical_memory_write(io->addr, s->io_buffer, s->io_buffer_size);
         io->len = 0;
         ide_atapi_cmd_ok(s);
         m->dma_active = false;
@@ -286,9 +288,6 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
     return;
 
 done:
-    dma_memory_unmap(&address_space_memory, io->dma_mem, io->dma_len,
-                     io->dir, io->dma_len);
-
     if (ret < 0) {
         block_acct_failed(blk_get_stats(s->blk), &s->acct);
     } else {
@@ -355,9 +354,6 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
     return;
 
 done:
-    dma_memory_unmap(&address_space_memory, io->dma_mem, io->dma_len,
-                     io->dir, io->dma_len);
-
     if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
         if (ret < 0) {
             block_acct_failed(blk_get_stats(s->blk), &s->acct);
@@ -407,7 +403,7 @@ static void pmac_ide_flush(DBDMA_io *io)
     IDEState *s = idebus_active_if(&m->bus);
 
     if (s->bus->dma->aiocb) {
-        blk_drain(s->blk);
+        blk_drain_all();
     }
 }
 
index e3fd30e..5c9db80 100644 (file)
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/pcmcia.h"
+#include <hw/hw.h>
+#include <hw/i386/pc.h>
+#include <hw/pcmcia.h>
 #include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
 
-#include "hw/ide/internal.h"
+#include <hw/ide/internal.h>
 
 #define TYPE_MICRODRIVE "microdrive"
 #define MICRODRIVE(obj) OBJECT_CHECK(MicroDriveState, (obj), TYPE_MICRODRIVE)
index 6f12f45..493f65a 100644 (file)
@@ -28,7 +28,7 @@
 #include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
 
-#include "hw/ide/internal.h"
+#include <hw/ide/internal.h>
 
 /***********************************************************/
 /* MMIO based ide port
index 3cfb510..8d56a00 100644 (file)
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/pci/pci.h"
-#include "hw/isa/isa.h"
+#include <hw/hw.h>
+#include <hw/i386/pc.h>
+#include <hw/pci/pci.h>
+#include <hw/isa/isa.h>
 #include "sysemu/block-backend.h"
 #include "sysemu/dma.h"
 #include "qemu/error-report.h"
-#include "hw/ide/pci.h"
+#include <hw/ide/pci.h>
 
 #define BMDMA_PAGE_SIZE 4096
 
similarity index 98%
rename from include/hw/ide/pci.h
rename to hw/ide/pci.h
index dbc6a03..0f2d4b9 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef HW_IDE_PCI_H
 #define HW_IDE_PCI_H
 
-#include "hw/ide/internal.h"
+#include <hw/ide/internal.h>
 
 #define BM_STATUS_DMAING 0x01
 #define BM_STATUS_ERROR  0x02
index c190fca..6d76ce9 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/pci/pci.h"
-#include "hw/isa/isa.h"
+#include <hw/hw.h>
+#include <hw/i386/pc.h>
+#include <hw/pci/pci.h>
+#include <hw/isa/isa.h>
 #include "sysemu/block-backend.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/dma.h"
 
-#include "hw/ide/pci.h"
+#include <hw/ide/pci.h>
 
 static uint64_t bmdma_read(void *opaque, hwaddr addr, unsigned size)
 {
index 67c76bf..4bc74a3 100644 (file)
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "qemu/osdep.h"
-#include "hw/hw.h"
+#include <hw/hw.h>
 #include "sysemu/dma.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
-#include "hw/ide/internal.h"
+#include <hw/ide/internal.h>
 #include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/block/block.h"
@@ -180,7 +180,6 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
             return -1;
         }
     }
-    blkconf_apply_backend_options(&dev->conf);
 
     if (ide_init_drive(s, dev->conf.blk, kind,
                        dev->version, dev->serial, dev->model, dev->wwn,
@@ -234,7 +233,9 @@ static void ide_dev_set_bootindex(Object *obj, Visitor *v, const char *name,
                              d->unit ? "/disk@1" : "/disk@0");
     }
 out:
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
 }
 
 static void ide_dev_instance_init(Object *obj)
@@ -264,7 +265,6 @@ static int ide_drive_initfn(IDEDevice *dev)
 
 #define DEFINE_IDE_DEV_PROPERTIES()                     \
     DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),        \
-    DEFINE_BLOCK_ERROR_PROPERTIES(IDEDrive, dev.conf),  \
     DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),  \
     DEFINE_PROP_UINT64("wwn",  IDEDrive, dev.wwn, 0),    \
     DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial),\
index 5b32ecb..d3f7226 100644 (file)
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/pci/pci.h"
-#include "hw/isa/isa.h"
+#include <hw/hw.h>
+#include <hw/i386/pc.h>
+#include <hw/pci/pci.h>
+#include <hw/isa/isa.h>
 #include "sysemu/block-backend.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/dma.h"
 
-#include "hw/ide/pci.h"
+#include <hw/ide/pci.h>
 
 static uint64_t bmdma_read(void *opaque, hwaddr addr,
                            unsigned size)
index 5e2850e..d92c746 100644 (file)
@@ -27,7 +27,6 @@
 #include "ui/console.h"
 #include "qemu/timer.h"
 #include "hw/input/hid.h"
-#include "trace.h"
 
 #define HID_USAGE_ERROR_ROLLOVER        0x01
 #define HID_USAGE_POSTFAIL              0x02
@@ -235,7 +234,7 @@ static void hid_keyboard_event(DeviceState *dev, QemuConsole *src,
                                              key->down,
                                              scancodes);
     if (hs->n + count > QUEUE_LENGTH) {
-        trace_hid_kbd_queue_full();
+        fprintf(stderr, "usb-kbd: warning: key event queue full\n");
         return;
     }
     for (i = 0; i < count; i++) {
index dc57e2c..1d932ec 100644 (file)
@@ -146,7 +146,7 @@ typedef struct KBDState {
 
     qemu_irq irq_kbd;
     qemu_irq irq_mouse;
-    qemu_irq a20_out;
+    qemu_irq *a20_out;
     hwaddr mask;
 } KBDState;
 
@@ -224,7 +224,9 @@ static void outport_write(KBDState *s, uint32_t val)
 {
     DPRINTF("kbd: write outport=0x%02x\n", val);
     s->outport = val;
-    qemu_set_irq(s->a20_out, (val >> 1) & 1);
+    if (s->a20_out) {
+        qemu_set_irq(*s->a20_out, (val >> 1) & 1);
+    }
     if (!(val & 1)) {
         qemu_system_reset_request();
     }
@@ -293,11 +295,15 @@ static void kbd_write_command(void *opaque, hwaddr addr,
         kbd_queue(s, s->outport, 0);
         break;
     case KBD_CCMD_ENABLE_A20:
-        qemu_irq_raise(s->a20_out);
+        if (s->a20_out) {
+            qemu_irq_raise(*s->a20_out);
+        }
         s->outport |= KBD_OUT_A20;
         break;
     case KBD_CCMD_DISABLE_A20:
-        qemu_irq_lower(s->a20_out);
+        if (s->a20_out) {
+            qemu_irq_lower(*s->a20_out);
+        }
         s->outport &= ~KBD_OUT_A20;
         break;
     case KBD_CCMD_RESET:
@@ -501,7 +507,10 @@ void i8042_isa_mouse_fake_event(void *opaque)
 
 void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out)
 {
-    qdev_connect_gpio_out_named(DEVICE(dev), I8042_A20_LINE, 0, *a20_out);
+    ISAKBDState *isa = I8042(dev);
+    KBDState *s = &isa->kbd;
+
+    s->a20_out = a20_out;
 }
 
 static const VMStateDescription vmstate_kbd_isa = {
@@ -543,8 +552,6 @@ static void i8042_initfn(Object *obj)
                           "i8042-data", 1);
     memory_region_init_io(isa_s->io + 1, obj, &i8042_cmd_ops, s,
                           "i8042-cmd", 1);
-
-    qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, I8042_A20_LINE, 1);
 }
 
 static void i8042_realizefn(DeviceState *dev, Error **errp)
index be9cd57..3092b0f 100644 (file)
@@ -10,7 +10,6 @@
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
 #include "hw/input/ps2.h"
-#include "qemu/log.h"
 
 #define TYPE_PL050 "pl050"
 #define PL050(obj) OBJECT_CHECK(PL050State, (obj), TYPE_PL050)
diff --git a/hw/input/trace-events b/hw/input/trace-events
deleted file mode 100644 (file)
index 8c4003f..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/input/ps2.c
-ps2_put_keycode(void *opaque, int keycode) "%p keycode %d"
-ps2_read_data(void *opaque) "%p"
-ps2_set_ledstate(void *s, int ledstate) "%p ledstate %d"
-ps2_reset_keyboard(void *s) "%p"
-ps2_write_keyboard(void *opaque, int val) "%p val %d"
-ps2_keyboard_set_translation(void *opaque, int mode) "%p mode %d"
-ps2_mouse_send_packet(void *s, int dx1, int dy1, int dz1, int b) "%p x %d y %d z %d bs %#x"
-ps2_mouse_event_disabled(void *opaque, int dx, int dy, int dz, int buttons_state, int mouse_dx, int mouse_dy, int mouse_dz) "%p x %d y %d z %d bs %#x mx %d my %d mz %d "
-ps2_mouse_event(void *opaque, int dx, int dy, int dz, int buttons_state, int mouse_dx, int mouse_dy, int mouse_dz) "%p x %d y %d z %d bs %#x mx %d my %d mz %d "
-ps2_mouse_fake_event(void *opaque) "%p"
-ps2_write_mouse(void *opaque, int val) "%p val %d"
-ps2_kbd_reset(void *opaque) "%p"
-ps2_mouse_reset(void *opaque) "%p"
-ps2_kbd_init(void *s) "%p"
-ps2_mouse_init(void *s) "%p"
-
-# hw/input/milkymist-softusb.c
-milkymist_softusb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_softusb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_softusb_mevt(uint8_t m) "m %d"
-milkymist_softusb_kevt(uint8_t m) "m %d"
-milkymist_softusb_pulse_irq(void) "Pulse IRQ"
-
-# hw/input/hid.c
-hid_kbd_queue_full(void) "queue full"
-
-# hw/input/virtio
-virtio_input_queue_full(void) "queue full"
index ccdf730..f59749a 100644 (file)
@@ -7,7 +7,6 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu/iov.h"
-#include "trace.h"
 
 #include "hw/qdev.h"
 #include "hw/virtio/virtio.h"
@@ -48,7 +47,7 @@ void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
     virtqueue_get_avail_bytes(vinput->evt, &have, NULL, need, 0);
     if (have < need) {
         vinput->qindex = 0;
-        trace_virtio_input_queue_full();
+        fprintf(stderr, "%s: ENOSPC in vq, dropping events\n", __func__);
         return;
     }
 
@@ -217,14 +216,26 @@ static void virtio_input_reset(VirtIODevice *vdev)
     }
 }
 
-static int virtio_input_load(QEMUFile *f, void *opaque, size_t size)
+static void virtio_input_save(QEMUFile *f, void *opaque)
+{
+    VirtIOInput *vinput = opaque;
+    VirtIODevice *vdev = VIRTIO_DEVICE(vinput);
+
+    virtio_save(vdev, f);
+}
+
+static int virtio_input_load(QEMUFile *f, void *opaque, int version_id)
 {
     VirtIOInput *vinput = opaque;
     VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vinput);
     VirtIODevice *vdev = VIRTIO_DEVICE(vinput);
     int ret;
 
-    ret = virtio_load(vdev, f, VIRTIO_INPUT_VM_VERSION);
+    if (version_id != VIRTIO_INPUT_VM_VERSION) {
+        return -EINVAL;
+    }
+
+    ret = virtio_load(vdev, f, version_id);
     if (ret) {
         return ret;
     }
@@ -268,24 +279,20 @@ static void virtio_input_device_realize(DeviceState *dev, Error **errp)
                 vinput->cfg_size);
     vinput->evt = virtio_add_queue(vdev, 64, virtio_input_handle_evt);
     vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts);
-}
-
-static void virtio_input_finalize(Object *obj)
-{
-    VirtIOInput *vinput = VIRTIO_INPUT(obj);
-    VirtIOInputConfig *cfg, *next;
 
-    QTAILQ_FOREACH_SAFE(cfg, &vinput->cfg_list, node, next) {
-        QTAILQ_REMOVE(&vinput->cfg_list, cfg, node);
-        g_free(cfg);
-    }
+    register_savevm(dev, "virtio-input", -1, VIRTIO_INPUT_VM_VERSION,
+                    virtio_input_save, virtio_input_load, vinput);
 }
+
 static void virtio_input_device_unrealize(DeviceState *dev, Error **errp)
 {
     VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev);
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    VirtIOInput *vinput = VIRTIO_INPUT(dev);
     Error *local_err = NULL;
 
+    unregister_savevm(dev, "virtio-input", vinput);
+
     if (vic->unrealize) {
         vic->unrealize(dev, &local_err);
         if (local_err) {
@@ -296,9 +303,6 @@ static void virtio_input_device_unrealize(DeviceState *dev, Error **errp)
     virtio_cleanup(vdev);
 }
 
-VMSTATE_VIRTIO_DEVICE(input, VIRTIO_INPUT_VM_VERSION, virtio_input_load,
-                      virtio_vmstate_save);
-
 static Property virtio_input_properties[] = {
     DEFINE_PROP_STRING("serial", VirtIOInput, serial),
     DEFINE_PROP_END_OF_LIST(),
@@ -310,7 +314,6 @@ static void virtio_input_class_init(ObjectClass *klass, void *data)
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
 
     dc->props          = virtio_input_properties;
-    dc->vmsd           = &vmstate_virtio_input;
     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
     vdc->realize      = virtio_input_device_realize;
     vdc->unrealize    = virtio_input_device_unrealize;
@@ -328,7 +331,6 @@ static const TypeInfo virtio_input_info = {
     .class_size    = sizeof(VirtIOInputClass),
     .class_init    = virtio_input_class_init,
     .abstract      = true,
-    .instance_finalize = virtio_input_finalize,
 };
 
 /* ----------------------------------------------------------------- */
index 05ec21b..0e47f0f 100644 (file)
@@ -13,9 +13,6 @@ common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o
 common-obj-$(CONFIG_ARM_GIC) += arm_gic.o
 common-obj-$(CONFIG_ARM_GIC) += arm_gicv2m.o
 common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_common.o
-common-obj-$(CONFIG_ARM_GIC) += arm_gicv3.o
-common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_dist.o
-common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_redist.o
 common-obj-$(CONFIG_OPENPIC) += openpic.o
 
 obj-$(CONFIG_APIC) += apic.o apic_common.o
@@ -30,11 +27,8 @@ obj-$(CONFIG_OPENPIC_KVM) += openpic_kvm.o
 obj-$(CONFIG_RASPI) += bcm2835_ic.o bcm2836_control.o
 obj-$(CONFIG_SH4) += sh_intc.o
 obj-$(CONFIG_XICS) += xics.o
-obj-$(CONFIG_XICS_SPAPR) += xics_spapr.o
 obj-$(CONFIG_XICS_KVM) += xics_kvm.o
 obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o
 obj-$(CONFIG_S390_FLIC) += s390_flic.o
 obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_vic.o
-obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o
-obj-$(CONFIG_MIPS_CPS) += mips_gic.o
index 11f1366..dc971a1 100644 (file)
@@ -20,7 +20,6 @@
 #include "hw/devices.h"
 #include "sysemu/sysemu.h"
 #include "hw/intc/allwinner-a10-pic.h"
-#include "qemu/log.h"
 
 static void aw_a10_pic_update(AwA10PICState *s)
 {
index 45887d9..28c2ea5 100644 (file)
@@ -17,8 +17,6 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>
  */
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "qemu/thread.h"
 #include "hw/i386/apic_internal.h"
 #include "hw/i386/apic.h"
@@ -28,9 +26,7 @@
 #include "trace.h"
 #include "hw/i386/pc.h"
 #include "hw/i386/apic-msidef.h"
-#include "qapi/error.h"
 
-#define MAX_APICS 255
 #define MAX_APIC_WORDS 8
 
 #define SYNC_FROM_VAPIC                 0x1
@@ -421,7 +417,7 @@ static int apic_find_dest(uint8_t dest)
     int i;
 
     if (apic && apic->id == dest)
-        return dest;  /* shortcut in case apic->id == local_apics[dest]->id */
+        return dest;  /* shortcut in case apic->id == apic->idx */
 
     for (i = 0; i < MAX_APICS; i++) {
         apic = local_apics[i];
@@ -504,14 +500,14 @@ static void apic_deliver(DeviceState *dev, uint8_t dest, uint8_t dest_mode,
         break;
     case 1:
         memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask));
-        apic_set_bit(deliver_bitmask, s->id);
+        apic_set_bit(deliver_bitmask, s->idx);
         break;
     case 2:
         memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
         break;
     case 3:
         memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
-        apic_reset_bit(deliver_bitmask, s->id);
+        apic_reset_bit(deliver_bitmask, s->idx);
         break;
     }
 
@@ -872,36 +868,20 @@ static void apic_realize(DeviceState *dev, Error **errp)
 {
     APICCommonState *s = APIC_COMMON(dev);
 
-    if (s->id >= MAX_APICS) {
-        error_setg(errp, "%s initialization failed. APIC ID %d is invalid",
-                   object_get_typename(OBJECT(dev)), s->id);
-        return;
-    }
-
     memory_region_init_io(&s->io_memory, OBJECT(s), &apic_io_ops, s, "apic-msi",
                           APIC_SPACE_SIZE);
 
     s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, apic_timer, s);
-    local_apics[s->id] = s;
+    local_apics[s->idx] = s;
 
     msi_nonbroken = true;
 }
 
-static void apic_unrealize(DeviceState *dev, Error **errp)
-{
-    APICCommonState *s = APIC_COMMON(dev);
-
-    timer_del(s->timer);
-    timer_free(s->timer);
-    local_apics[s->id] = NULL;
-}
-
 static void apic_class_init(ObjectClass *klass, void *data)
 {
     APICCommonClass *k = APIC_COMMON_CLASS(klass);
 
     k->realize = apic_realize;
-    k->unrealize = apic_unrealize;
     k->set_base = apic_set_base;
     k->set_tpr = apic_set_tpr;
     k->get_tpr = apic_get_tpr;
index 14ac43c..4abe145 100644 (file)
@@ -19,8 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "hw/i386/apic.h"
 #include "hw/i386/apic_internal.h"
 #include "trace.h"
@@ -294,14 +292,19 @@ static int apic_load_old(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static const VMStateDescription vmstate_apic_common;
-
 static void apic_common_realize(DeviceState *dev, Error **errp)
 {
     APICCommonState *s = APIC_COMMON(dev);
     APICCommonClass *info;
     static DeviceState *vapic;
-    int instance_id = s->id;
+    static int apic_no;
+
+    if (apic_no >= MAX_APICS) {
+        error_setg(errp, "%s initialization failed.",
+                   object_get_typename(OBJECT(dev)));
+        return;
+    }
+    s->idx = apic_no++;
 
     info = APIC_COMMON_GET_CLASS(s);
     info->realize(dev, errp);
@@ -316,24 +319,6 @@ static void apic_common_realize(DeviceState *dev, Error **errp)
         info->enable_tpr_reporting(s, true);
     }
 
-    if (s->legacy_instance_id) {
-        instance_id = -1;
-    }
-    vmstate_register_with_alias_id(NULL, instance_id, &vmstate_apic_common,
-                                   s, -1, 0);
-}
-
-static void apic_common_unrealize(DeviceState *dev, Error **errp)
-{
-    APICCommonState *s = APIC_COMMON(dev);
-    APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
-
-    vmstate_unregister(NULL, &vmstate_apic_common, s);
-    info->unrealize(dev, errp);
-
-    if (apic_report_tpr_access && info->enable_tpr_reporting) {
-        info->enable_tpr_reporting(s, false);
-    }
 }
 
 static int apic_pre_load(void *opaque)
@@ -431,8 +416,6 @@ static Property apic_properties_common[] = {
     DEFINE_PROP_UINT8("version", APICCommonState, version, 0x14),
     DEFINE_PROP_BIT("vapic", APICCommonState, vapic_control, VAPIC_ENABLE_BIT,
                     true),
-    DEFINE_PROP_BOOL("legacy-instance-id", APICCommonState, legacy_instance_id,
-                     false),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -440,10 +423,10 @@ static void apic_common_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
+    dc->vmsd = &vmstate_apic_common;
     dc->reset = apic_reset_common;
     dc->props = apic_properties_common;
     dc->realize = apic_common_realize;
-    dc->unrealize = apic_common_unrealize;
     /*
      * Reason: APIC and CPU need to be wired up by
      * x86_cpu_apic_create()
index b30cc91..f551241 100644 (file)
@@ -23,8 +23,6 @@
 #include "gic_internal.h"
 #include "qapi/error.h"
 #include "qom/cpu.h"
-#include "qemu/log.h"
-#include "trace.h"
 
 //#define DEBUG_GIC
 
@@ -95,11 +93,6 @@ void gic_update(GICState *s)
             }
         }
 
-        if (best_irq != 1023) {
-            trace_gic_update_bestirq(cpu, best_irq, best_prio,
-                s->priority_mask[cpu], s->running_priority[cpu]);
-        }
-
         irq_level = fiq_level = 0;
 
         if (best_prio < s->priority_mask[cpu]) {
@@ -113,12 +106,10 @@ void gic_update(GICState *s)
                         DPRINTF("Raised pending FIQ %d (cpu %d)\n",
                                 best_irq, cpu);
                         fiq_level = 1;
-                        trace_gic_update_set_irq(cpu, "fiq", fiq_level);
                     } else {
                         DPRINTF("Raised pending IRQ %d (cpu %d)\n",
                                 best_irq, cpu);
                         irq_level = 1;
-                        trace_gic_update_set_irq(cpu, "irq", irq_level);
                     }
                 }
             }
@@ -206,7 +197,6 @@ static void gic_set_irq(void *opaque, int irq, int level)
     } else {
         gic_set_irq_generic(s, irq, level, cm, target);
     }
-    trace_gic_set_irq(irq, level, cm, target);
 
     gic_update(s);
 }
@@ -342,7 +332,6 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs)
      * is in the wrong group.
      */
     irq = gic_get_current_pending_irq(s, cpu, attrs);
-    trace_gic_acknowledge_irq(cpu, irq);
 
     if (irq >= GIC_MAXIRQ) {
         DPRINTF("ACK, no pending interrupt or it is hidden: %d\n", irq);
@@ -661,11 +650,6 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs)
             goto bad_reg;
         res = 0;
         for (i = 0; i < 8; i++) {
-            if (s->security_extn && !attrs.secure &&
-                !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
-                continue; /* Ignore Non-secure access of Group0 IRQ */
-            }
-
             if (GIC_TEST_ENABLED(irq + i, cm)) {
                 res |= (1 << i);
             }
@@ -682,11 +666,6 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs)
         res = 0;
         mask = (irq < GIC_INTERNAL) ?  cm : ALL_CPU_MASK;
         for (i = 0; i < 8; i++) {
-            if (s->security_extn && !attrs.secure &&
-                !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
-                continue; /* Ignore Non-secure access of Group0 IRQ */
-            }
-
             if (gic_test_pending(s, irq + i, mask)) {
                 res |= (1 << i);
             }
@@ -699,11 +678,6 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs)
         res = 0;
         mask = (irq < GIC_INTERNAL) ?  cm : ALL_CPU_MASK;
         for (i = 0; i < 8; i++) {
-            if (s->security_extn && !attrs.secure &&
-                !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
-                continue; /* Ignore Non-secure access of Group0 IRQ */
-            }
-
             if (GIC_TEST_ACTIVE(irq + i, mask)) {
                 res |= (1 << i);
             }
@@ -737,11 +711,6 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs)
             goto bad_reg;
         res = 0;
         for (i = 0; i < 4; i++) {
-            if (s->security_extn && !attrs.secure &&
-                !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
-                continue; /* Ignore Non-secure access of Group0 IRQ */
-            }
-
             if (GIC_TEST_MODEL(irq + i))
                 res |= (1 << (i * 2));
             if (GIC_TEST_EDGE_TRIGGER(irq + i))
@@ -762,12 +731,7 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs)
             /* GICD_SPENDSGIRn */
         }
 
-        if (s->security_extn && !attrs.secure &&
-            !GIC_TEST_GROUP(irq, 1 << cpu)) {
-            res = 0; /* Ignore Non-secure access of Group0 IRQ */
-        } else {
-            res = s->sgi_pending[irq][cpu];
-        }
+        res = s->sgi_pending[irq][cpu];
     } else if (offset < 0xfd0) {
         goto bad_reg;
     } else if (offset < 0x1000) {
@@ -887,14 +851,8 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
                     (irq < GIC_INTERNAL) ? (1 << cpu) : GIC_TARGET(irq + i);
                 int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
 
-                if (s->security_extn && !attrs.secure &&
-                    !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
-                    continue; /* Ignore Non-secure access of Group0 IRQ */
-                }
-
                 if (!GIC_TEST_ENABLED(irq + i, cm)) {
                     DPRINTF("Enabled IRQ %d\n", irq + i);
-                    trace_gic_enable_irq(irq + i);
                 }
                 GIC_SET_ENABLED(irq + i, cm);
                 /* If a raised level triggered IRQ enabled then mark
@@ -919,14 +877,8 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
             if (value & (1 << i)) {
                 int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
 
-                if (s->security_extn && !attrs.secure &&
-                    !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
-                    continue; /* Ignore Non-secure access of Group0 IRQ */
-                }
-
                 if (GIC_TEST_ENABLED(irq + i, cm)) {
                     DPRINTF("Disabled IRQ %d\n", irq + i);
-                    trace_gic_disable_irq(irq + i);
                 }
                 GIC_CLEAR_ENABLED(irq + i, cm);
             }
@@ -942,11 +894,6 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
 
         for (i = 0; i < 8; i++) {
             if (value & (1 << i)) {
-                if (s->security_extn && !attrs.secure &&
-                    !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
-                    continue; /* Ignore Non-secure access of Group0 IRQ */
-                }
-
                 GIC_SET_PENDING(irq + i, GIC_TARGET(irq + i));
             }
         }
@@ -960,11 +907,6 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
         }
 
         for (i = 0; i < 8; i++) {
-            if (s->security_extn && !attrs.secure &&
-                !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
-                continue; /* Ignore Non-secure access of Group0 IRQ */
-            }
-
             /* ??? This currently clears the pending bit for all CPUs, even
                for per-CPU interrupts.  It's unclear whether this is the
                corect behavior.  */
@@ -1005,11 +947,6 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
         if (irq < GIC_NR_SGIS)
             value |= 0xaa;
         for (i = 0; i < 4; i++) {
-            if (s->security_extn && !attrs.secure &&
-                !GIC_TEST_GROUP(irq + i, 1 << cpu)) {
-                continue; /* Ignore Non-secure access of Group0 IRQ */
-            }
-
             if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
                 if (value & (1 << (i * 2))) {
                     GIC_SET_MODEL(irq + i);
@@ -1033,12 +970,9 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
         }
         irq = (offset - 0xf10);
 
-        if (!s->security_extn || attrs.secure ||
-            GIC_TEST_GROUP(irq, 1 << cpu)) {
-            s->sgi_pending[irq][cpu] &= ~value;
-            if (s->sgi_pending[irq][cpu] == 0) {
-                GIC_CLEAR_PENDING(irq, 1 << cpu);
-            }
+        s->sgi_pending[irq][cpu] &= ~value;
+        if (s->sgi_pending[irq][cpu] == 0) {
+            GIC_CLEAR_PENDING(irq, 1 << cpu);
         }
     } else if (offset < 0xf30) {
         /* GICD_SPENDSGIRn */
@@ -1047,11 +981,8 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
         }
         irq = (offset - 0xf20);
 
-        if (!s->security_extn || attrs.secure ||
-            GIC_TEST_GROUP(irq, 1 << cpu)) {
-            GIC_SET_PENDING(irq, 1 << cpu);
-            s->sgi_pending[irq][cpu] |= value;
-        }
+        GIC_SET_PENDING(irq, 1 << cpu);
+        s->sgi_pending[irq][cpu] |= value;
     } else {
         goto bad_reg;
     }
index 5593cdb..bc85ab7 100644 (file)
@@ -21,8 +21,6 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "hw/sysbus.h"
 #include "migration/migration.h"
 #include "sysemu/kvm.h"
index 3922fbc..e8b5177 100644 (file)
@@ -29,8 +29,6 @@
 #include "qapi/error.h"
 #include "hw/sysbus.h"
 #include "hw/pci/msi.h"
-#include "sysemu/kvm.h"
-#include "qemu/log.h"
 
 #define TYPE_ARM_GICV2M "arm-gicv2m"
 #define ARM_GICV2M(obj) OBJECT_CHECK(ARMGICv2mState, (obj), TYPE_ARM_GICV2M)
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
deleted file mode 100644 (file)
index 8a6c647..0000000
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * ARM Generic Interrupt Controller v3
- *
- * Copyright (c) 2015 Huawei.
- * Copyright (c) 2016 Linaro Limited
- * Written by Shlomo Pongratz, Peter Maydell
- *
- * This code is licensed under the GPL, version 2 or (at your option)
- * any later version.
- */
-
-/* This file contains implementation code for an interrupt controller
- * which implements the GICv3 architecture. Specifically this is where
- * the device class itself and the functions for handling interrupts
- * coming in and going out live.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/sysbus.h"
-#include "hw/intc/arm_gicv3.h"
-#include "gicv3_internal.h"
-
-static bool irqbetter(GICv3CPUState *cs, int irq, uint8_t prio)
-{
-    /* Return true if this IRQ at this priority should take
-     * precedence over the current recorded highest priority
-     * pending interrupt for this CPU. We also return true if
-     * the current recorded highest priority pending interrupt
-     * is the same as this one (a property which the calling code
-     * relies on).
-     */
-    if (prio < cs->hppi.prio) {
-        return true;
-    }
-    /* If multiple pending interrupts have the same priority then it is an
-     * IMPDEF choice which of them to signal to the CPU. We choose to
-     * signal the one with the lowest interrupt number.
-     */
-    if (prio == cs->hppi.prio && irq <= cs->hppi.irq) {
-        return true;
-    }
-    return false;
-}
-
-static uint32_t gicd_int_pending(GICv3State *s, int irq)
-{
-    /* Recalculate which distributor interrupts are actually pending
-     * in the group of 32 interrupts starting at irq (which should be a multiple
-     * of 32), and return a 32-bit integer which has a bit set for each
-     * interrupt that is eligible to be signaled to the CPU interface.
-     *
-     * An interrupt is pending if:
-     *  + the PENDING latch is set OR it is level triggered and the input is 1
-     *  + its ENABLE bit is set
-     *  + the GICD enable bit for its group is set
-     * Conveniently we can bulk-calculate this with bitwise operations.
-     */
-    uint32_t pend, grpmask;
-    uint32_t pending = *gic_bmp_ptr32(s->pending, irq);
-    uint32_t edge_trigger = *gic_bmp_ptr32(s->edge_trigger, irq);
-    uint32_t level = *gic_bmp_ptr32(s->level, irq);
-    uint32_t group = *gic_bmp_ptr32(s->group, irq);
-    uint32_t grpmod = *gic_bmp_ptr32(s->grpmod, irq);
-    uint32_t enable = *gic_bmp_ptr32(s->enabled, irq);
-
-    pend = pending | (~edge_trigger & level);
-    pend &= enable;
-
-    if (s->gicd_ctlr & GICD_CTLR_DS) {
-        grpmod = 0;
-    }
-
-    grpmask = 0;
-    if (s->gicd_ctlr & GICD_CTLR_EN_GRP1NS) {
-        grpmask |= group;
-    }
-    if (s->gicd_ctlr & GICD_CTLR_EN_GRP1S) {
-        grpmask |= (~group & grpmod);
-    }
-    if (s->gicd_ctlr & GICD_CTLR_EN_GRP0) {
-        grpmask |= (~group & ~grpmod);
-    }
-    pend &= grpmask;
-
-    return pend;
-}
-
-static uint32_t gicr_int_pending(GICv3CPUState *cs)
-{
-    /* Recalculate which redistributor interrupts are actually pending,
-     * and return a 32-bit integer which has a bit set for each interrupt
-     * that is eligible to be signaled to the CPU interface.
-     *
-     * An interrupt is pending if:
-     *  + the PENDING latch is set OR it is level triggered and the input is 1
-     *  + its ENABLE bit is set
-     *  + the GICD enable bit for its group is set
-     * Conveniently we can bulk-calculate this with bitwise operations.
-     */
-    uint32_t pend, grpmask, grpmod;
-
-    pend = cs->gicr_ipendr0 | (~cs->edge_trigger & cs->level);
-    pend &= cs->gicr_ienabler0;
-
-    if (cs->gic->gicd_ctlr & GICD_CTLR_DS) {
-        grpmod = 0;
-    } else {
-        grpmod = cs->gicr_igrpmodr0;
-    }
-
-    grpmask = 0;
-    if (cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP1NS) {
-        grpmask |= cs->gicr_igroupr0;
-    }
-    if (cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP1S) {
-        grpmask |= (~cs->gicr_igroupr0 & grpmod);
-    }
-    if (cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP0) {
-        grpmask |= (~cs->gicr_igroupr0 & ~grpmod);
-    }
-    pend &= grpmask;
-
-    return pend;
-}
-
-/* Update the interrupt status after state in a redistributor
- * or CPU interface has changed, but don't tell the CPU i/f.
- */
-static void gicv3_redist_update_noirqset(GICv3CPUState *cs)
-{
-    /* Find the highest priority pending interrupt among the
-     * redistributor interrupts (SGIs and PPIs).
-     */
-    bool seenbetter = false;
-    uint8_t prio;
-    int i;
-    uint32_t pend;
-
-    /* Find out which redistributor interrupts are eligible to be
-     * signaled to the CPU interface.
-     */
-    pend = gicr_int_pending(cs);
-
-    if (pend) {
-        for (i = 0; i < GIC_INTERNAL; i++) {
-            if (!(pend & (1 << i))) {
-                continue;
-            }
-            prio = cs->gicr_ipriorityr[i];
-            if (irqbetter(cs, i, prio)) {
-                cs->hppi.irq = i;
-                cs->hppi.prio = prio;
-                seenbetter = true;
-            }
-        }
-    }
-
-    if (seenbetter) {
-        cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq);
-    }
-
-    /* If the best interrupt we just found would preempt whatever
-     * was the previous best interrupt before this update, then
-     * we know it's definitely the best one now.
-     * If we didn't find an interrupt that would preempt the previous
-     * best, and the previous best is outside our range (or there was no
-     * previous pending interrupt at all), then that is still valid, and
-     * we leave it as the best.
-     * Otherwise, we need to do a full update (because the previous best
-     * interrupt has reduced in priority and any other interrupt could
-     * now be the new best one).
-     */
-    if (!seenbetter && cs->hppi.prio != 0xff && cs->hppi.irq < GIC_INTERNAL) {
-        gicv3_full_update_noirqset(cs->gic);
-    }
-}
-
-/* Update the GIC status after state in a redistributor or
- * CPU interface has changed, and inform the CPU i/f of
- * its new highest priority pending interrupt.
- */
-void gicv3_redist_update(GICv3CPUState *cs)
-{
-    gicv3_redist_update_noirqset(cs);
-    gicv3_cpuif_update(cs);
-}
-
-/* Update the GIC status after state in the distributor has
- * changed affecting @len interrupts starting at @start,
- * but don't tell the CPU i/f.
- */
-static void gicv3_update_noirqset(GICv3State *s, int start, int len)
-{
-    int i;
-    uint8_t prio;
-    uint32_t pend = 0;
-
-    assert(start >= GIC_INTERNAL);
-    assert(len > 0);
-
-    for (i = 0; i < s->num_cpu; i++) {
-        s->cpu[i].seenbetter = false;
-    }
-
-    /* Find the highest priority pending interrupt in this range. */
-    for (i = start; i < start + len; i++) {
-        GICv3CPUState *cs;
-
-        if (i == start || (i & 0x1f) == 0) {
-            /* Calculate the next 32 bits worth of pending status */
-            pend = gicd_int_pending(s, i & ~0x1f);
-        }
-
-        if (!(pend & (1 << (i & 0x1f)))) {
-            continue;
-        }
-        cs = s->gicd_irouter_target[i];
-        if (!cs) {
-            /* Interrupts targeting no implemented CPU should remain pending
-             * and not be forwarded to any CPU.
-             */
-            continue;
-        }
-        prio = s->gicd_ipriority[i];
-        if (irqbetter(cs, i, prio)) {
-            cs->hppi.irq = i;
-            cs->hppi.prio = prio;
-            cs->seenbetter = true;
-        }
-    }
-
-    /* If the best interrupt we just found would preempt whatever
-     * was the previous best interrupt before this update, then
-     * we know it's definitely the best one now.
-     * If we didn't find an interrupt that would preempt the previous
-     * best, and the previous best is outside our range (or there was
-     * no previous pending interrupt at all), then that
-     * is still valid, and we leave it as the best.
-     * Otherwise, we need to do a full update (because the previous best
-     * interrupt has reduced in priority and any other interrupt could
-     * now be the new best one).
-     */
-    for (i = 0; i < s->num_cpu; i++) {
-        GICv3CPUState *cs = &s->cpu[i];
-
-        if (cs->seenbetter) {
-            cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq);
-        }
-
-        if (!cs->seenbetter && cs->hppi.prio != 0xff &&
-            cs->hppi.irq >= start && cs->hppi.irq < start + len) {
-            gicv3_full_update_noirqset(s);
-            break;
-        }
-    }
-}
-
-void gicv3_update(GICv3State *s, int start, int len)
-{
-    int i;
-
-    gicv3_update_noirqset(s, start, len);
-    for (i = 0; i < s->num_cpu; i++) {
-        gicv3_cpuif_update(&s->cpu[i]);
-    }
-}
-
-void gicv3_full_update_noirqset(GICv3State *s)
-{
-    /* Completely recalculate the GIC status from scratch, but
-     * don't update any outbound IRQ lines.
-     */
-    int i;
-
-    for (i = 0; i < s->num_cpu; i++) {
-        s->cpu[i].hppi.prio = 0xff;
-    }
-
-    /* Note that we can guarantee that these functions will not
-     * recursively call back into gicv3_full_update(), because
-     * at each point the "previous best" is always outside the
-     * range we ask them to update.
-     */
-    gicv3_update_noirqset(s, GIC_INTERNAL, s->num_irq - GIC_INTERNAL);
-
-    for (i = 0; i < s->num_cpu; i++) {
-        gicv3_redist_update_noirqset(&s->cpu[i]);
-    }
-}
-
-void gicv3_full_update(GICv3State *s)
-{
-    /* Completely recalculate the GIC status from scratch, including
-     * updating outbound IRQ lines.
-     */
-    int i;
-
-    gicv3_full_update_noirqset(s);
-    for (i = 0; i < s->num_cpu; i++) {
-        gicv3_cpuif_update(&s->cpu[i]);
-    }
-}
-
-/* Process a change in an external IRQ input. */
-static void gicv3_set_irq(void *opaque, int irq, int level)
-{
-    /* Meaning of the 'irq' parameter:
-     *  [0..N-1] : external interrupts
-     *  [N..N+31] : PPI (internal) interrupts for CPU 0
-     *  [N+32..N+63] : PPI (internal interrupts for CPU 1
-     *  ...
-     */
-    GICv3State *s = opaque;
-
-    if (irq < (s->num_irq - GIC_INTERNAL)) {
-        /* external interrupt (SPI) */
-        gicv3_dist_set_irq(s, irq + GIC_INTERNAL, level);
-    } else {
-        /* per-cpu interrupt (PPI) */
-        int cpu;
-
-        irq -= (s->num_irq - GIC_INTERNAL);
-        cpu = irq / GIC_INTERNAL;
-        irq %= GIC_INTERNAL;
-        assert(cpu < s->num_cpu);
-        /* Raising SGIs via this function would be a bug in how the board
-         * model wires up interrupts.
-         */
-        assert(irq >= GIC_NR_SGIS);
-        gicv3_redist_set_irq(&s->cpu[cpu], irq, level);
-    }
-}
-
-static void arm_gicv3_post_load(GICv3State *s)
-{
-    /* Recalculate our cached idea of the current highest priority
-     * pending interrupt, but don't set IRQ or FIQ lines.
-     */
-    gicv3_full_update_noirqset(s);
-    /* Repopulate the cache of GICv3CPUState pointers for target CPUs */
-    gicv3_cache_all_target_cpustates(s);
-}
-
-static const MemoryRegionOps gic_ops[] = {
-    {
-        .read_with_attrs = gicv3_dist_read,
-        .write_with_attrs = gicv3_dist_write,
-        .endianness = DEVICE_NATIVE_ENDIAN,
-    },
-    {
-        .read_with_attrs = gicv3_redist_read,
-        .write_with_attrs = gicv3_redist_write,
-        .endianness = DEVICE_NATIVE_ENDIAN,
-    }
-};
-
-static void arm_gic_realize(DeviceState *dev, Error **errp)
-{
-    /* Device instance realize function for the GIC sysbus device */
-    GICv3State *s = ARM_GICV3(dev);
-    ARMGICv3Class *agc = ARM_GICV3_GET_CLASS(s);
-    Error *local_err = NULL;
-
-    agc->parent_realize(dev, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops);
-
-    gicv3_init_cpuif(s);
-}
-
-static void arm_gicv3_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    ARMGICv3CommonClass *agcc = ARM_GICV3_COMMON_CLASS(klass);
-    ARMGICv3Class *agc = ARM_GICV3_CLASS(klass);
-
-    agcc->post_load = arm_gicv3_post_load;
-    agc->parent_realize = dc->realize;
-    dc->realize = arm_gic_realize;
-}
-
-static const TypeInfo arm_gicv3_info = {
-    .name = TYPE_ARM_GICV3,
-    .parent = TYPE_ARM_GICV3_COMMON,
-    .instance_size = sizeof(GICv3State),
-    .class_init = arm_gicv3_class_init,
-    .class_size = sizeof(ARMGICv3Class),
-};
-
-static void arm_gicv3_register_types(void)
-{
-    type_register_static(&arm_gicv3_info);
-}
-
-type_init(arm_gicv3_register_types)
index 0f8c4b8..b9d3824 100644 (file)
@@ -3,9 +3,8 @@
  *
  * Copyright (c) 2012 Linaro Limited
  * Copyright (c) 2015 Huawei.
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
  * Written by Peter Maydell
- * Reworked for GICv3 by Shlomo Pongratz and Pavel Fedin
+ * Extended to 64 cores by Shlomo Pongratz
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qom/cpu.h"
 #include "hw/intc/arm_gicv3_common.h"
-#include "gicv3_internal.h"
-#include "hw/arm/linux-boot-if.h"
 
 static void gicv3_pre_save(void *opaque)
 {
@@ -49,59 +45,11 @@ static int gicv3_post_load(void *opaque, int version_id)
     return 0;
 }
 
-static const VMStateDescription vmstate_gicv3_cpu = {
-    .name = "arm_gicv3_cpu",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT32(level, GICv3CPUState),
-        VMSTATE_UINT32(gicr_ctlr, GICv3CPUState),
-        VMSTATE_UINT32_ARRAY(gicr_statusr, GICv3CPUState, 2),
-        VMSTATE_UINT32(gicr_waker, GICv3CPUState),
-        VMSTATE_UINT64(gicr_propbaser, GICv3CPUState),
-        VMSTATE_UINT64(gicr_pendbaser, GICv3CPUState),
-        VMSTATE_UINT32(gicr_igroupr0, GICv3CPUState),
-        VMSTATE_UINT32(gicr_ienabler0, GICv3CPUState),
-        VMSTATE_UINT32(gicr_ipendr0, GICv3CPUState),
-        VMSTATE_UINT32(gicr_iactiver0, GICv3CPUState),
-        VMSTATE_UINT32(edge_trigger, GICv3CPUState),
-        VMSTATE_UINT32(gicr_igrpmodr0, GICv3CPUState),
-        VMSTATE_UINT32(gicr_nsacr, GICv3CPUState),
-        VMSTATE_UINT8_ARRAY(gicr_ipriorityr, GICv3CPUState, GIC_INTERNAL),
-        VMSTATE_UINT64_ARRAY(icc_ctlr_el1, GICv3CPUState, 2),
-        VMSTATE_UINT64(icc_pmr_el1, GICv3CPUState),
-        VMSTATE_UINT64_ARRAY(icc_bpr, GICv3CPUState, 3),
-        VMSTATE_UINT64_2DARRAY(icc_apr, GICv3CPUState, 3, 4),
-        VMSTATE_UINT64_ARRAY(icc_igrpen, GICv3CPUState, 3),
-        VMSTATE_UINT64(icc_ctlr_el3, GICv3CPUState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
 static const VMStateDescription vmstate_gicv3 = {
     .name = "arm_gicv3",
-    .version_id = 1,
-    .minimum_version_id = 1,
+    .unmigratable = 1,
     .pre_save = gicv3_pre_save,
     .post_load = gicv3_post_load,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT32(gicd_ctlr, GICv3State),
-        VMSTATE_UINT32_ARRAY(gicd_statusr, GICv3State, 2),
-        VMSTATE_UINT32_ARRAY(group, GICv3State, GICV3_BMP_SIZE),
-        VMSTATE_UINT32_ARRAY(grpmod, GICv3State, GICV3_BMP_SIZE),
-        VMSTATE_UINT32_ARRAY(enabled, GICv3State, GICV3_BMP_SIZE),
-        VMSTATE_UINT32_ARRAY(pending, GICv3State, GICV3_BMP_SIZE),
-        VMSTATE_UINT32_ARRAY(active, GICv3State, GICV3_BMP_SIZE),
-        VMSTATE_UINT32_ARRAY(level, GICv3State, GICV3_BMP_SIZE),
-        VMSTATE_UINT32_ARRAY(edge_trigger, GICv3State, GICV3_BMP_SIZE),
-        VMSTATE_UINT8_ARRAY(gicd_ipriority, GICv3State, GICV3_MAXIRQ),
-        VMSTATE_UINT64_ARRAY(gicd_irouter, GICv3State, GICV3_MAXIRQ),
-        VMSTATE_UINT32_ARRAY(gicd_nsacr, GICv3State,
-                             DIV_ROUND_UP(GICV3_MAXIRQ, 16)),
-        VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, GICv3State, num_cpu,
-                                             vmstate_gicv3_cpu, GICv3CPUState),
-        VMSTATE_END_OF_LIST()
-    }
 };
 
 void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
@@ -120,11 +68,14 @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
     i = s->num_irq - GIC_INTERNAL + GIC_INTERNAL * s->num_cpu;
     qdev_init_gpio_in(DEVICE(s), handler, i);
 
+    s->parent_irq = g_malloc(s->num_cpu * sizeof(qemu_irq));
+    s->parent_fiq = g_malloc(s->num_cpu * sizeof(qemu_irq));
+
     for (i = 0; i < s->num_cpu; i++) {
-        sysbus_init_irq(sbd, &s->cpu[i].parent_irq);
+        sysbus_init_irq(sbd, &s->parent_irq[i]);
     }
     for (i = 0; i < s->num_cpu; i++) {
-        sysbus_init_irq(sbd, &s->cpu[i].parent_fiq);
+        sysbus_init_irq(sbd, &s->parent_fiq[i]);
     }
 
     memory_region_init_io(&s->iomem_dist, OBJECT(s), ops, s,
@@ -139,7 +90,6 @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
 static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
 {
     GICv3State *s = ARM_GICV3_COMMON(dev);
-    int i;
 
     /* revision property is actually reserved and currently used only in order
      * to keep the interface compatible with GICv2 code, avoiding extra
@@ -150,164 +100,11 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
         error_setg(errp, "unsupported GIC revision %d", s->revision);
         return;
     }
-
-    if (s->num_irq > GICV3_MAXIRQ) {
-        error_setg(errp,
-                   "requested %u interrupt lines exceeds GIC maximum %d",
-                   s->num_irq, GICV3_MAXIRQ);
-        return;
-    }
-    if (s->num_irq < GIC_INTERNAL) {
-        error_setg(errp,
-                   "requested %u interrupt lines is below GIC minimum %d",
-                   s->num_irq, GIC_INTERNAL);
-        return;
-    }
-
-    /* ITLinesNumber is represented as (N / 32) - 1, so this is an
-     * implementation imposed restriction, not an architectural one,
-     * so we don't have to deal with bitfields where only some of the
-     * bits in a 32-bit word should be valid.
-     */
-    if (s->num_irq % 32) {
-        error_setg(errp,
-                   "%d interrupt lines unsupported: not divisible by 32",
-                   s->num_irq);
-        return;
-    }
-
-    s->cpu = g_new0(GICv3CPUState, s->num_cpu);
-
-    for (i = 0; i < s->num_cpu; i++) {
-        CPUState *cpu = qemu_get_cpu(i);
-        uint64_t cpu_affid;
-        int last;
-
-        s->cpu[i].cpu = cpu;
-        s->cpu[i].gic = s;
-
-        /* Pre-construct the GICR_TYPER:
-         * For our implementation:
-         *  Top 32 bits are the affinity value of the associated CPU
-         *  CommonLPIAff == 01 (redistributors with same Aff3 share LPI table)
-         *  Processor_Number == CPU index starting from 0
-         *  DPGS == 0 (GICR_CTLR.DPG* not supported)
-         *  Last == 1 if this is the last redistributor in a series of
-         *            contiguous redistributor pages
-         *  DirectLPI == 0 (direct injection of LPIs not supported)
-         *  VLPIS == 0 (virtual LPIs not supported)
-         *  PLPIS == 0 (physical LPIs not supported)
-         */
-        cpu_affid = object_property_get_int(OBJECT(cpu), "mp-affinity", NULL);
-        last = (i == s->num_cpu - 1);
-
-        /* The CPU mp-affinity property is in MPIDR register format; squash
-         * the affinity bytes into 32 bits as the GICR_TYPER has them.
-         */
-        cpu_affid = (cpu_affid & 0xFF00000000ULL >> 8) | (cpu_affid & 0xFFFFFF);
-        s->cpu[i].gicr_typer = (cpu_affid << 32) |
-            (1 << 24) |
-            (i << 8) |
-            (last << 4);
-    }
 }
 
 static void arm_gicv3_common_reset(DeviceState *dev)
 {
-    GICv3State *s = ARM_GICV3_COMMON(dev);
-    int i;
-
-    for (i = 0; i < s->num_cpu; i++) {
-        GICv3CPUState *cs = &s->cpu[i];
-
-        cs->level = 0;
-        cs->gicr_ctlr = 0;
-        cs->gicr_statusr[GICV3_S] = 0;
-        cs->gicr_statusr[GICV3_NS] = 0;
-        cs->gicr_waker = GICR_WAKER_ProcessorSleep | GICR_WAKER_ChildrenAsleep;
-        cs->gicr_propbaser = 0;
-        cs->gicr_pendbaser = 0;
-        /* If we're resetting a TZ-aware GIC as if secure firmware
-         * had set it up ready to start a kernel in non-secure, we
-         * need to set interrupts to group 1 so the kernel can use them.
-         * Otherwise they reset to group 0 like the hardware.
-         */
-        if (s->irq_reset_nonsecure) {
-            cs->gicr_igroupr0 = 0xffffffff;
-        } else {
-            cs->gicr_igroupr0 = 0;
-        }
-
-        cs->gicr_ienabler0 = 0;
-        cs->gicr_ipendr0 = 0;
-        cs->gicr_iactiver0 = 0;
-        cs->edge_trigger = 0xffff;
-        cs->gicr_igrpmodr0 = 0;
-        cs->gicr_nsacr = 0;
-        memset(cs->gicr_ipriorityr, 0, sizeof(cs->gicr_ipriorityr));
-
-        cs->hppi.prio = 0xff;
-
-        /* State in the CPU interface must *not* be reset here, because it
-         * is part of the CPU's reset domain, not the GIC device's.
-         */
-    }
-
-    /* For our implementation affinity routing is always enabled */
-    if (s->security_extn) {
-        s->gicd_ctlr = GICD_CTLR_ARE_S | GICD_CTLR_ARE_NS;
-    } else {
-        s->gicd_ctlr = GICD_CTLR_DS | GICD_CTLR_ARE;
-    }
-
-    s->gicd_statusr[GICV3_S] = 0;
-    s->gicd_statusr[GICV3_NS] = 0;
-
-    memset(s->group, 0, sizeof(s->group));
-    memset(s->grpmod, 0, sizeof(s->grpmod));
-    memset(s->enabled, 0, sizeof(s->enabled));
-    memset(s->pending, 0, sizeof(s->pending));
-    memset(s->active, 0, sizeof(s->active));
-    memset(s->level, 0, sizeof(s->level));
-    memset(s->edge_trigger, 0, sizeof(s->edge_trigger));
-    memset(s->gicd_ipriority, 0, sizeof(s->gicd_ipriority));
-    memset(s->gicd_irouter, 0, sizeof(s->gicd_irouter));
-    memset(s->gicd_nsacr, 0, sizeof(s->gicd_nsacr));
-    /* GICD_IROUTER are UNKNOWN at reset so in theory the guest must
-     * write these to get sane behaviour and we need not populate the
-     * pointer cache here; however having the cache be different for
-     * "happened to be 0 from reset" and "guest wrote 0" would be
-     * too confusing.
-     */
-    gicv3_cache_all_target_cpustates(s);
-
-    if (s->irq_reset_nonsecure) {
-        /* If we're resetting a TZ-aware GIC as if secure firmware
-         * had set it up ready to start a kernel in non-secure, we
-         * need to set interrupts to group 1 so the kernel can use them.
-         * Otherwise they reset to group 0 like the hardware.
-         */
-        for (i = GIC_INTERNAL; i < s->num_irq; i++) {
-            gicv3_gicd_group_set(s, i);
-        }
-    }
-}
-
-static void arm_gic_common_linux_init(ARMLinuxBootIf *obj,
-                                      bool secure_boot)
-{
-    GICv3State *s = ARM_GICV3_COMMON(obj);
-
-    if (s->security_extn && !secure_boot) {
-        /* We're directly booting a kernel into NonSecure. If this GIC
-         * implements the security extensions then we must configure it
-         * to have all the interrupts be NonSecure (this is a job that
-         * is done by the Secure boot firmware in real hardware, and in
-         * this mode QEMU is acting as a minimalist firmware-and-bootloader
-         * equivalent).
-         */
-        s->irq_reset_nonsecure = true;
-    }
+    /* TODO */
 }
 
 static Property arm_gicv3_common_properties[] = {
@@ -321,13 +118,11 @@ static Property arm_gicv3_common_properties[] = {
 static void arm_gicv3_common_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ARMLinuxBootIfClass *albifc = ARM_LINUX_BOOT_IF_CLASS(klass);
 
     dc->reset = arm_gicv3_common_reset;
     dc->realize = arm_gicv3_common_realize;
     dc->props = arm_gicv3_common_properties;
     dc->vmsd = &vmstate_gicv3;
-    albifc->arm_linux_init = arm_gic_common_linux_init;
 }
 
 static const TypeInfo arm_gicv3_common_type = {
@@ -337,10 +132,6 @@ static const TypeInfo arm_gicv3_common_type = {
     .class_size = sizeof(ARMGICv3CommonClass),
     .class_init = arm_gicv3_common_class_init,
     .abstract = true,
-    .interfaces = (InterfaceInfo []) {
-        { TYPE_ARM_LINUX_BOOT_IF },
-        { },
-    },
 };
 
 static void register_types(void)
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
deleted file mode 100644 (file)
index 4633172..0000000
+++ /dev/null
@@ -1,1348 +0,0 @@
-/*
- * ARM Generic Interrupt Controller v3
- *
- * Copyright (c) 2016 Linaro Limited
- * Written by Peter Maydell
- *
- * This code is licensed under the GPL, version 2 or (at your option)
- * any later version.
- */
-
-/* This file contains the code for the system register interface
- * portions of the GICv3.
- */
-
-#include "qemu/osdep.h"
-#include "trace.h"
-#include "gicv3_internal.h"
-#include "cpu.h"
-
-static GICv3CPUState *icc_cs_from_env(CPUARMState *env)
-{
-    /* Given the CPU, find the right GICv3CPUState struct.
-     * Since we registered the CPU interface with the EL change hook as
-     * the opaque pointer, we can just directly get from the CPU to it.
-     */
-    return arm_get_el_change_hook_opaque(arm_env_get_cpu(env));
-}
-
-static bool gicv3_use_ns_bank(CPUARMState *env)
-{
-    /* Return true if we should use the NonSecure bank for a banked GIC
-     * CPU interface register. Note that this differs from the
-     * access_secure_reg() function because GICv3 banked registers are
-     * banked even for AArch64, unlike the other CPU system registers.
-     */
-    return !arm_is_secure_below_el3(env);
-}
-
-static int icc_highest_active_prio(GICv3CPUState *cs)
-{
-    /* Calculate the current running priority based on the set bits
-     * in the Active Priority Registers.
-     */
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(cs->icc_apr[0]); i++) {
-        uint32_t apr = cs->icc_apr[GICV3_G0][i] |
-            cs->icc_apr[GICV3_G1][i] | cs->icc_apr[GICV3_G1NS][i];
-
-        if (!apr) {
-            continue;
-        }
-        return (i * 32 + ctz32(apr)) << (GIC_MIN_BPR + 1);
-    }
-    /* No current active interrupts: return idle priority */
-    return 0xff;
-}
-
-static uint32_t icc_gprio_mask(GICv3CPUState *cs, int group)
-{
-    /* Return a mask word which clears the subpriority bits from
-     * a priority value for an interrupt in the specified group.
-     * This depends on the BPR value:
-     *  a BPR of 0 means the group priority bits are [7:1];
-     *  a BPR of 1 means they are [7:2], and so on down to
-     *  a BPR of 7 meaning no group priority bits at all.
-     * Which BPR to use depends on the group of the interrupt and
-     * the current ICC_CTLR.CBPR settings.
-     */
-    if ((group == GICV3_G1 && cs->icc_ctlr_el1[GICV3_S] & ICC_CTLR_EL1_CBPR) ||
-        (group == GICV3_G1NS &&
-         cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_CBPR)) {
-        group = GICV3_G0;
-    }
-
-    return ~0U << ((cs->icc_bpr[group] & 7) + 1);
-}
-
-static bool icc_no_enabled_hppi(GICv3CPUState *cs)
-{
-    /* Return true if there is no pending interrupt, or the
-     * highest priority pending interrupt is in a group which has been
-     * disabled at the CPU interface by the ICC_IGRPEN* register enable bits.
-     */
-    return cs->hppi.prio == 0xff || (cs->icc_igrpen[cs->hppi.grp] == 0);
-}
-
-static bool icc_hppi_can_preempt(GICv3CPUState *cs)
-{
-    /* Return true if we have a pending interrupt of sufficient
-     * priority to preempt.
-     */
-    int rprio;
-    uint32_t mask;
-
-    if (icc_no_enabled_hppi(cs)) {
-        return false;
-    }
-
-    if (cs->hppi.prio >= cs->icc_pmr_el1) {
-        /* Priority mask masks this interrupt */
-        return false;
-    }
-
-    rprio = icc_highest_active_prio(cs);
-    if (rprio == 0xff) {
-        /* No currently running interrupt so we can preempt */
-        return true;
-    }
-
-    mask = icc_gprio_mask(cs, cs->hppi.grp);
-
-    /* We only preempt a running interrupt if the pending interrupt's
-     * group priority is sufficient (the subpriorities are not considered).
-     */
-    if ((cs->hppi.prio & mask) < (rprio & mask)) {
-        return true;
-    }
-
-    return false;
-}
-
-void gicv3_cpuif_update(GICv3CPUState *cs)
-{
-    /* Tell the CPU about its highest priority pending interrupt */
-    int irqlevel = 0;
-    int fiqlevel = 0;
-    ARMCPU *cpu = ARM_CPU(cs->cpu);
-    CPUARMState *env = &cpu->env;
-
-    trace_gicv3_cpuif_update(gicv3_redist_affid(cs), cs->hppi.irq,
-                             cs->hppi.grp, cs->hppi.prio);
-
-    if (cs->hppi.grp == GICV3_G1 && !arm_feature(env, ARM_FEATURE_EL3)) {
-        /* If a Security-enabled GIC sends a G1S interrupt to a
-         * Security-disabled CPU, we must treat it as if it were G0.
-         */
-        cs->hppi.grp = GICV3_G0;
-    }
-
-    if (icc_hppi_can_preempt(cs)) {
-        /* We have an interrupt: should we signal it as IRQ or FIQ?
-         * This is described in the GICv3 spec section 4.6.2.
-         */
-        bool isfiq;
-
-        switch (cs->hppi.grp) {
-        case GICV3_G0:
-            isfiq = true;
-            break;
-        case GICV3_G1:
-            isfiq = (!arm_is_secure(env) ||
-                     (arm_current_el(env) == 3 && arm_el_is_aa64(env, 3)));
-            break;
-        case GICV3_G1NS:
-            isfiq = arm_is_secure(env);
-            break;
-        default:
-            g_assert_not_reached();
-        }
-
-        if (isfiq) {
-            fiqlevel = 1;
-        } else {
-            irqlevel = 1;
-        }
-    }
-
-    trace_gicv3_cpuif_set_irqs(gicv3_redist_affid(cs), fiqlevel, irqlevel);
-
-    qemu_set_irq(cs->parent_fiq, fiqlevel);
-    qemu_set_irq(cs->parent_irq, irqlevel);
-}
-
-static uint64_t icc_pmr_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    uint32_t value = cs->icc_pmr_el1;
-
-    if (arm_feature(env, ARM_FEATURE_EL3) && !arm_is_secure(env) &&
-        (env->cp15.scr_el3 & SCR_FIQ)) {
-        /* NS access and Group 0 is inaccessible to NS: return the
-         * NS view of the current priority
-         */
-        if (value & 0x80) {
-            /* Secure priorities not visible to NS */
-            value = 0;
-        } else if (value != 0xff) {
-            value = (value << 1) & 0xff;
-        }
-    }
-
-    trace_gicv3_icc_pmr_read(gicv3_redist_affid(cs), value);
-
-    return value;
-}
-
-static void icc_pmr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                          uint64_t value)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-
-    trace_gicv3_icc_pmr_write(gicv3_redist_affid(cs), value);
-
-    value &= 0xff;
-
-    if (arm_feature(env, ARM_FEATURE_EL3) && !arm_is_secure(env) &&
-        (env->cp15.scr_el3 & SCR_FIQ)) {
-        /* NS access and Group 0 is inaccessible to NS: return the
-         * NS view of the current priority
-         */
-        if (!(cs->icc_pmr_el1 & 0x80)) {
-            /* Current PMR in the secure range, don't allow NS to change it */
-            return;
-        }
-        value = (value >> 1) & 0x80;
-    }
-    cs->icc_pmr_el1 = value;
-    gicv3_cpuif_update(cs);
-}
-
-static void icc_activate_irq(GICv3CPUState *cs, int irq)
-{
-    /* Move the interrupt from the Pending state to Active, and update
-     * the Active Priority Registers
-     */
-    uint32_t mask = icc_gprio_mask(cs, cs->hppi.grp);
-    int prio = cs->hppi.prio & mask;
-    int aprbit = prio >> 1;
-    int regno = aprbit / 32;
-    int regbit = aprbit % 32;
-
-    cs->icc_apr[cs->hppi.grp][regno] |= (1 << regbit);
-
-    if (irq < GIC_INTERNAL) {
-        cs->gicr_iactiver0 = deposit32(cs->gicr_iactiver0, irq, 1, 1);
-        cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 0);
-        gicv3_redist_update(cs);
-    } else {
-        gicv3_gicd_active_set(cs->gic, irq);
-        gicv3_gicd_pending_clear(cs->gic, irq);
-        gicv3_update(cs->gic, irq, 1);
-    }
-}
-
-static uint64_t icc_hppir0_value(GICv3CPUState *cs, CPUARMState *env)
-{
-    /* Return the highest priority pending interrupt register value
-     * for group 0.
-     */
-    bool irq_is_secure;
-
-    if (cs->hppi.prio == 0xff) {
-        return INTID_SPURIOUS;
-    }
-
-    /* Check whether we can return the interrupt or if we should return
-     * a special identifier, as per the CheckGroup0ForSpecialIdentifiers
-     * pseudocode. (We can simplify a little because for us ICC_SRE_EL1.RM
-     * is always zero.)
-     */
-    irq_is_secure = (!(cs->gic->gicd_ctlr & GICD_CTLR_DS) &&
-                     (cs->hppi.grp != GICV3_G1NS));
-
-    if (cs->hppi.grp != GICV3_G0 && !arm_is_el3_or_mon(env)) {
-        return INTID_SPURIOUS;
-    }
-    if (irq_is_secure && !arm_is_secure(env)) {
-        /* Secure interrupts not visible to Nonsecure */
-        return INTID_SPURIOUS;
-    }
-
-    if (cs->hppi.grp != GICV3_G0) {
-        /* Indicate to EL3 that there's a Group 1 interrupt for the other
-         * state pending.
-         */
-        return irq_is_secure ? INTID_SECURE : INTID_NONSECURE;
-    }
-
-    return cs->hppi.irq;
-}
-
-static uint64_t icc_hppir1_value(GICv3CPUState *cs, CPUARMState *env)
-{
-    /* Return the highest priority pending interrupt register value
-     * for group 1.
-     */
-    bool irq_is_secure;
-
-    if (cs->hppi.prio == 0xff) {
-        return INTID_SPURIOUS;
-    }
-
-    /* Check whether we can return the interrupt or if we should return
-     * a special identifier, as per the CheckGroup1ForSpecialIdentifiers
-     * pseudocode. (We can simplify a little because for us ICC_SRE_EL1.RM
-     * is always zero.)
-     */
-    irq_is_secure = (!(cs->gic->gicd_ctlr & GICD_CTLR_DS) &&
-                     (cs->hppi.grp != GICV3_G1NS));
-
-    if (cs->hppi.grp == GICV3_G0) {
-        /* Group 0 interrupts not visible via HPPIR1 */
-        return INTID_SPURIOUS;
-    }
-    if (irq_is_secure) {
-        if (!arm_is_secure(env)) {
-            /* Secure interrupts not visible in Non-secure */
-            return INTID_SPURIOUS;
-        }
-    } else if (!arm_is_el3_or_mon(env) && arm_is_secure(env)) {
-        /* Group 1 non-secure interrupts not visible in Secure EL1 */
-        return INTID_SPURIOUS;
-    }
-
-    return cs->hppi.irq;
-}
-
-static uint64_t icc_iar0_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    uint64_t intid;
-
-    if (!icc_hppi_can_preempt(cs)) {
-        intid = INTID_SPURIOUS;
-    } else {
-        intid = icc_hppir0_value(cs, env);
-    }
-
-    if (!(intid >= INTID_SECURE && intid <= INTID_SPURIOUS)) {
-        icc_activate_irq(cs, intid);
-    }
-
-    trace_gicv3_icc_iar0_read(gicv3_redist_affid(cs), intid);
-    return intid;
-}
-
-static uint64_t icc_iar1_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    uint64_t intid;
-
-    if (!icc_hppi_can_preempt(cs)) {
-        intid = INTID_SPURIOUS;
-    } else {
-        intid = icc_hppir1_value(cs, env);
-    }
-
-    if (!(intid >= INTID_SECURE && intid <= INTID_SPURIOUS)) {
-        icc_activate_irq(cs, intid);
-    }
-
-    trace_gicv3_icc_iar1_read(gicv3_redist_affid(cs), intid);
-    return intid;
-}
-
-static void icc_drop_prio(GICv3CPUState *cs, int grp)
-{
-    /* Drop the priority of the currently active interrupt in
-     * the specified group.
-     *
-     * Note that we can guarantee (because of the requirement to nest
-     * ICC_IAR reads [which activate an interrupt and raise priority]
-     * with ICC_EOIR writes [which drop the priority for the interrupt])
-     * that the interrupt we're being called for is the highest priority
-     * active interrupt, meaning that it has the lowest set bit in the
-     * APR registers.
-     *
-     * If the guest does not honour the ordering constraints then the
-     * behaviour of the GIC is UNPREDICTABLE, which for us means that
-     * the values of the APR registers might become incorrect and the
-     * running priority will be wrong, so interrupts that should preempt
-     * might not do so, and interrupts that should not preempt might do so.
-     */
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(cs->icc_apr[grp]); i++) {
-        uint64_t *papr = &cs->icc_apr[grp][i];
-
-        if (!*papr) {
-            continue;
-        }
-        /* Clear the lowest set bit */
-        *papr &= *papr - 1;
-        break;
-    }
-
-    /* running priority change means we need an update for this cpu i/f */
-    gicv3_cpuif_update(cs);
-}
-
-static bool icc_eoi_split(CPUARMState *env, GICv3CPUState *cs)
-{
-    /* Return true if we should split priority drop and interrupt
-     * deactivation, ie whether the relevant EOIMode bit is set.
-     */
-    if (arm_is_el3_or_mon(env)) {
-        return cs->icc_ctlr_el3 & ICC_CTLR_EL3_EOIMODE_EL3;
-    }
-    if (arm_is_secure_below_el3(env)) {
-        return cs->icc_ctlr_el1[GICV3_S] & ICC_CTLR_EL1_EOIMODE;
-    } else {
-        return cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_EOIMODE;
-    }
-}
-
-static int icc_highest_active_group(GICv3CPUState *cs)
-{
-    /* Return the group with the highest priority active interrupt.
-     * We can do this by just comparing the APRs to see which one
-     * has the lowest set bit.
-     * (If more than one group is active at the same priority then
-     * we're in UNPREDICTABLE territory.)
-     */
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(cs->icc_apr[0]); i++) {
-        int g0ctz = ctz32(cs->icc_apr[GICV3_G0][i]);
-        int g1ctz = ctz32(cs->icc_apr[GICV3_G1][i]);
-        int g1nsctz = ctz32(cs->icc_apr[GICV3_G1NS][i]);
-
-        if (g1nsctz < g0ctz && g1nsctz < g1ctz) {
-            return GICV3_G1NS;
-        }
-        if (g1ctz < g0ctz) {
-            return GICV3_G1;
-        }
-        if (g0ctz < 32) {
-            return GICV3_G0;
-        }
-    }
-    /* No set active bits? UNPREDICTABLE; return -1 so the caller
-     * ignores the spurious EOI attempt.
-     */
-    return -1;
-}
-
-static void icc_deactivate_irq(GICv3CPUState *cs, int irq)
-{
-    if (irq < GIC_INTERNAL) {
-        cs->gicr_iactiver0 = deposit32(cs->gicr_iactiver0, irq, 1, 0);
-        gicv3_redist_update(cs);
-    } else {
-        gicv3_gicd_active_clear(cs->gic, irq);
-        gicv3_update(cs->gic, irq, 1);
-    }
-}
-
-static void icc_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                           uint64_t value)
-{
-    /* End of Interrupt */
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    int irq = value & 0xffffff;
-    int grp;
-
-    trace_gicv3_icc_eoir_write(gicv3_redist_affid(cs), value);
-
-    if (ri->crm == 8) {
-        /* EOIR0 */
-        grp = GICV3_G0;
-    } else {
-        /* EOIR1 */
-        if (arm_is_secure(env)) {
-            grp = GICV3_G1;
-        } else {
-            grp = GICV3_G1NS;
-        }
-    }
-
-    if (irq >= cs->gic->num_irq) {
-        /* This handles two cases:
-         * 1. If software writes the ID of a spurious interrupt [ie 1020-1023]
-         * to the GICC_EOIR, the GIC ignores that write.
-         * 2. If software writes the number of a non-existent interrupt
-         * this must be a subcase of "value written does not match the last
-         * valid interrupt value read from the Interrupt Acknowledge
-         * register" and so this is UNPREDICTABLE. We choose to ignore it.
-         */
-        return;
-    }
-
-    if (icc_highest_active_group(cs) != grp) {
-        return;
-    }
-
-    icc_drop_prio(cs, grp);
-
-    if (!icc_eoi_split(env, cs)) {
-        /* Priority drop and deactivate not split: deactivate irq now */
-        icc_deactivate_irq(cs, irq);
-    }
-}
-
-static uint64_t icc_hppir0_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    uint64_t value = icc_hppir0_value(cs, env);
-
-    trace_gicv3_icc_hppir0_read(gicv3_redist_affid(cs), value);
-    return value;
-}
-
-static uint64_t icc_hppir1_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    uint64_t value = icc_hppir1_value(cs, env);
-
-    trace_gicv3_icc_hppir1_read(gicv3_redist_affid(cs), value);
-    return value;
-}
-
-static uint64_t icc_bpr_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    int grp = (ri->crm == 8) ? GICV3_G0 : GICV3_G1;
-    bool satinc = false;
-    uint64_t bpr;
-
-    if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
-        grp = GICV3_G1NS;
-    }
-
-    if (grp == GICV3_G1 && !arm_is_el3_or_mon(env) &&
-        (cs->icc_ctlr_el1[GICV3_S] & ICC_CTLR_EL1_CBPR)) {
-        /* CBPR_EL1S means secure EL1 or AArch32 EL3 !Mon BPR1 accesses
-         * modify BPR0
-         */
-        grp = GICV3_G0;
-    }
-
-    if (grp == GICV3_G1NS && arm_current_el(env) < 3 &&
-        (cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_CBPR)) {
-        /* reads return bpr0 + 1 sat to 7, writes ignored */
-        grp = GICV3_G0;
-        satinc = true;
-    }
-
-    bpr = cs->icc_bpr[grp];
-    if (satinc) {
-        bpr++;
-        bpr = MIN(bpr, 7);
-    }
-
-    trace_gicv3_icc_bpr_read(gicv3_redist_affid(cs), bpr);
-
-    return bpr;
-}
-
-static void icc_bpr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                          uint64_t value)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    int grp = (ri->crm == 8) ? GICV3_G0 : GICV3_G1;
-
-    trace_gicv3_icc_pmr_write(gicv3_redist_affid(cs), value);
-
-    if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
-        grp = GICV3_G1NS;
-    }
-
-    if (grp == GICV3_G1 && !arm_is_el3_or_mon(env) &&
-        (cs->icc_ctlr_el1[GICV3_S] & ICC_CTLR_EL1_CBPR)) {
-        /* CBPR_EL1S means secure EL1 or AArch32 EL3 !Mon BPR1 accesses
-         * modify BPR0
-         */
-        grp = GICV3_G0;
-    }
-
-    if (grp == GICV3_G1NS && arm_current_el(env) < 3 &&
-        (cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_CBPR)) {
-        /* reads return bpr0 + 1 sat to 7, writes ignored */
-        return;
-    }
-
-    cs->icc_bpr[grp] = value & 7;
-    gicv3_cpuif_update(cs);
-}
-
-static uint64_t icc_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    uint64_t value;
-
-    int regno = ri->opc2 & 3;
-    int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
-
-    if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
-        grp = GICV3_G1NS;
-    }
-
-    value = cs->icc_apr[grp][regno];
-
-    trace_gicv3_icc_ap_read(regno, gicv3_redist_affid(cs), value);
-    return value;
-}
-
-static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                         uint64_t value)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-
-    int regno = ri->opc2 & 3;
-    int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
-
-    trace_gicv3_icc_ap_write(regno, gicv3_redist_affid(cs), value);
-
-    if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
-        grp = GICV3_G1NS;
-    }
-
-    /* It's not possible to claim that a Non-secure interrupt is active
-     * at a priority outside the Non-secure range (128..255), since this
-     * would otherwise allow malicious NS code to block delivery of S interrupts
-     * by writing a bad value to these registers.
-     */
-    if (grp == GICV3_G1NS && regno < 2 && arm_feature(env, ARM_FEATURE_EL3)) {
-        return;
-    }
-
-    cs->icc_apr[grp][regno] = value & 0xFFFFFFFFU;
-    gicv3_cpuif_update(cs);
-}
-
-static void icc_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                          uint64_t value)
-{
-    /* Deactivate interrupt */
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    int irq = value & 0xffffff;
-    bool irq_is_secure, single_sec_state, irq_is_grp0;
-    bool route_fiq_to_el3, route_irq_to_el3, route_fiq_to_el2, route_irq_to_el2;
-
-    trace_gicv3_icc_dir_write(gicv3_redist_affid(cs), value);
-
-    if (irq >= cs->gic->num_irq) {
-        /* Also catches special interrupt numbers and LPIs */
-        return;
-    }
-
-    if (!icc_eoi_split(env, cs)) {
-        return;
-    }
-
-    int grp = gicv3_irq_group(cs->gic, cs, irq);
-
-    single_sec_state = cs->gic->gicd_ctlr & GICD_CTLR_DS;
-    irq_is_secure = !single_sec_state && (grp != GICV3_G1NS);
-    irq_is_grp0 = grp == GICV3_G0;
-
-    /* Check whether we're allowed to deactivate this interrupt based
-     * on its group and the current CPU state.
-     * These checks are laid out to correspond to the spec's pseudocode.
-     */
-    route_fiq_to_el3 = env->cp15.scr_el3 & SCR_FIQ;
-    route_irq_to_el3 = env->cp15.scr_el3 & SCR_IRQ;
-    /* No need to include !IsSecure in route_*_to_el2 as it's only
-     * tested in cases where we know !IsSecure is true.
-     */
-    route_fiq_to_el2 = env->cp15.hcr_el2 & HCR_FMO;
-    route_irq_to_el2 = env->cp15.hcr_el2 & HCR_FMO;
-
-    switch (arm_current_el(env)) {
-    case 3:
-        break;
-    case 2:
-        if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) {
-            break;
-        }
-        if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) {
-            break;
-        }
-        return;
-    case 1:
-        if (!arm_is_secure_below_el3(env)) {
-            if (single_sec_state && irq_is_grp0 &&
-                !route_fiq_to_el3 && !route_fiq_to_el2) {
-                break;
-            }
-            if (!irq_is_secure && !irq_is_grp0 &&
-                !route_irq_to_el3 && !route_irq_to_el2) {
-                break;
-            }
-        } else {
-            if (irq_is_grp0 && !route_fiq_to_el3) {
-                break;
-            }
-            if (!irq_is_grp0 &&
-                (!irq_is_secure || !single_sec_state) &&
-                !route_irq_to_el3) {
-                break;
-            }
-        }
-        return;
-    default:
-        g_assert_not_reached();
-    }
-
-    icc_deactivate_irq(cs, irq);
-}
-
-static uint64_t icc_rpr_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    int prio = icc_highest_active_prio(cs);
-
-    if (arm_feature(env, ARM_FEATURE_EL3) &&
-        !arm_is_secure(env) && (env->cp15.scr_el3 & SCR_FIQ)) {
-        /* NS GIC access and Group 0 is inaccessible to NS */
-        if (prio & 0x80) {
-            /* NS mustn't see priorities in the Secure half of the range */
-            prio = 0;
-        } else if (prio != 0xff) {
-            /* Non-idle priority: show the Non-secure view of it */
-            prio = (prio << 1) & 0xff;
-        }
-    }
-
-    trace_gicv3_icc_rpr_read(gicv3_redist_affid(cs), prio);
-    return prio;
-}
-
-static void icc_generate_sgi(CPUARMState *env, GICv3CPUState *cs,
-                             uint64_t value, int grp, bool ns)
-{
-    GICv3State *s = cs->gic;
-
-    /* Extract Aff3/Aff2/Aff1 and shift into the bottom 24 bits */
-    uint64_t aff = extract64(value, 48, 8) << 16 |
-        extract64(value, 32, 8) << 8 |
-        extract64(value, 16, 8);
-    uint32_t targetlist = extract64(value, 0, 16);
-    uint32_t irq = extract64(value, 24, 4);
-    bool irm = extract64(value, 40, 1);
-    int i;
-
-    if (grp == GICV3_G1 && s->gicd_ctlr & GICD_CTLR_DS) {
-        /* If GICD_CTLR.DS == 1, the Distributor treats Secure Group 1
-         * interrupts as Group 0 interrupts and must send Secure Group 0
-         * interrupts to the target CPUs.
-         */
-        grp = GICV3_G0;
-    }
-
-    trace_gicv3_icc_generate_sgi(gicv3_redist_affid(cs), irq, irm,
-                                 aff, targetlist);
-
-    for (i = 0; i < s->num_cpu; i++) {
-        GICv3CPUState *ocs = &s->cpu[i];
-
-        if (irm) {
-            /* IRM == 1 : route to all CPUs except self */
-            if (cs == ocs) {
-                continue;
-            }
-        } else {
-            /* IRM == 0 : route to Aff3.Aff2.Aff1.n for all n in [0..15]
-             * where the corresponding bit is set in targetlist
-             */
-            int aff0;
-
-            if (ocs->gicr_typer >> 40 != aff) {
-                continue;
-            }
-            aff0 = extract64(ocs->gicr_typer, 32, 8);
-            if (aff0 > 15 || extract32(targetlist, aff0, 1) == 0) {
-                continue;
-            }
-        }
-
-        /* The redistributor will check against its own GICR_NSACR as needed */
-        gicv3_redist_send_sgi(ocs, grp, irq, ns);
-    }
-}
-
-static void icc_sgi0r_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                           uint64_t value)
-{
-    /* Generate Secure Group 0 SGI. */
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    bool ns = !arm_is_secure(env);
-
-    icc_generate_sgi(env, cs, value, GICV3_G0, ns);
-}
-
-static void icc_sgi1r_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                           uint64_t value)
-{
-    /* Generate Group 1 SGI for the current Security state */
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    int grp;
-    bool ns = !arm_is_secure(env);
-
-    grp = ns ? GICV3_G1NS : GICV3_G1;
-    icc_generate_sgi(env, cs, value, grp, ns);
-}
-
-static void icc_asgi1r_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                             uint64_t value)
-{
-    /* Generate Group 1 SGI for the Security state that is not
-     * the current state
-     */
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    int grp;
-    bool ns = !arm_is_secure(env);
-
-    grp = ns ? GICV3_G1 : GICV3_G1NS;
-    icc_generate_sgi(env, cs, value, grp, ns);
-}
-
-static uint64_t icc_igrpen_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    int grp = ri->opc2 & 1 ? GICV3_G1 : GICV3_G0;
-    uint64_t value;
-
-    if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
-        grp = GICV3_G1NS;
-    }
-
-    value = cs->icc_igrpen[grp];
-    trace_gicv3_icc_igrpen_read(gicv3_redist_affid(cs), value);
-    return value;
-}
-
-static void icc_igrpen_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                             uint64_t value)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    int grp = ri->opc2 & 1 ? GICV3_G1 : GICV3_G0;
-
-    trace_gicv3_icc_igrpen_write(gicv3_redist_affid(cs), value);
-
-    if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
-        grp = GICV3_G1NS;
-    }
-
-    cs->icc_igrpen[grp] = value & ICC_IGRPEN_ENABLE;
-    gicv3_cpuif_update(cs);
-}
-
-static uint64_t icc_igrpen1_el3_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-
-    /* IGRPEN1_EL3 bits 0 and 1 are r/w aliases into IGRPEN1_EL1 NS and S */
-    return cs->icc_igrpen[GICV3_G1NS] | (cs->icc_igrpen[GICV3_G1] << 1);
-}
-
-static void icc_igrpen1_el3_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                                  uint64_t value)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-
-    trace_gicv3_icc_igrpen1_el3_write(gicv3_redist_affid(cs), value);
-
-    /* IGRPEN1_EL3 bits 0 and 1 are r/w aliases into IGRPEN1_EL1 NS and S */
-    cs->icc_igrpen[GICV3_G1NS] = extract32(value, 0, 1);
-    cs->icc_igrpen[GICV3_G1] = extract32(value, 1, 1);
-    gicv3_cpuif_update(cs);
-}
-
-static uint64_t icc_ctlr_el1_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    int bank = gicv3_use_ns_bank(env) ? GICV3_NS : GICV3_S;
-    uint64_t value;
-
-    value = cs->icc_ctlr_el1[bank];
-    trace_gicv3_icc_ctlr_read(gicv3_redist_affid(cs), value);
-    return value;
-}
-
-static void icc_ctlr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                               uint64_t value)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    int bank = gicv3_use_ns_bank(env) ? GICV3_NS : GICV3_S;
-    uint64_t mask;
-
-    trace_gicv3_icc_ctlr_write(gicv3_redist_affid(cs), value);
-
-    /* Only CBPR and EOIMODE can be RW;
-     * for us PMHE is RAZ/WI (we don't implement 1-of-N interrupts or
-     * the asseciated priority-based routing of them);
-     * if EL3 is implemented and GICD_CTLR.DS == 0, then PMHE and CBPR are RO.
-     */
-    if (arm_feature(env, ARM_FEATURE_EL3) &&
-        ((cs->gic->gicd_ctlr & GICD_CTLR_DS) == 0)) {
-        mask = ICC_CTLR_EL1_EOIMODE;
-    } else {
-        mask = ICC_CTLR_EL1_CBPR | ICC_CTLR_EL1_EOIMODE;
-    }
-
-    cs->icc_ctlr_el1[bank] &= ~mask;
-    cs->icc_ctlr_el1[bank] |= (value & mask);
-    gicv3_cpuif_update(cs);
-}
-
-
-static uint64_t icc_ctlr_el3_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    uint64_t value;
-
-    value = cs->icc_ctlr_el3;
-    if (cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_EOIMODE) {
-        value |= ICC_CTLR_EL3_EOIMODE_EL1NS;
-    }
-    if (cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_CBPR) {
-        value |= ICC_CTLR_EL3_CBPR_EL1NS;
-    }
-    if (cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_EOIMODE) {
-        value |= ICC_CTLR_EL3_EOIMODE_EL1S;
-    }
-    if (cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_CBPR) {
-        value |= ICC_CTLR_EL3_CBPR_EL1S;
-    }
-
-    trace_gicv3_icc_ctlr_el3_read(gicv3_redist_affid(cs), value);
-    return value;
-}
-
-static void icc_ctlr_el3_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                               uint64_t value)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-    uint64_t mask;
-
-    trace_gicv3_icc_ctlr_el3_write(gicv3_redist_affid(cs), value);
-
-    /* *_EL1NS and *_EL1S bits are aliases into the ICC_CTLR_EL1 bits. */
-    cs->icc_ctlr_el1[GICV3_NS] &= (ICC_CTLR_EL1_CBPR | ICC_CTLR_EL1_EOIMODE);
-    if (value & ICC_CTLR_EL3_EOIMODE_EL1NS) {
-        cs->icc_ctlr_el1[GICV3_NS] |= ICC_CTLR_EL1_EOIMODE;
-    }
-    if (value & ICC_CTLR_EL3_CBPR_EL1NS) {
-        cs->icc_ctlr_el1[GICV3_NS] |= ICC_CTLR_EL1_CBPR;
-    }
-
-    cs->icc_ctlr_el1[GICV3_S] &= (ICC_CTLR_EL1_CBPR | ICC_CTLR_EL1_EOIMODE);
-    if (value & ICC_CTLR_EL3_EOIMODE_EL1S) {
-        cs->icc_ctlr_el1[GICV3_S] |= ICC_CTLR_EL1_EOIMODE;
-    }
-    if (value & ICC_CTLR_EL3_CBPR_EL1S) {
-        cs->icc_ctlr_el1[GICV3_S] |= ICC_CTLR_EL1_CBPR;
-    }
-
-    /* The only bit stored in icc_ctlr_el3 which is writeable is EOIMODE_EL3: */
-    mask = ICC_CTLR_EL3_EOIMODE_EL3;
-
-    cs->icc_ctlr_el3 &= ~mask;
-    cs->icc_ctlr_el3 |= (value & mask);
-    gicv3_cpuif_update(cs);
-}
-
-static CPAccessResult gicv3_irqfiq_access(CPUARMState *env,
-                                          const ARMCPRegInfo *ri, bool isread)
-{
-    CPAccessResult r = CP_ACCESS_OK;
-
-    if ((env->cp15.scr_el3 & (SCR_FIQ | SCR_IRQ)) == (SCR_FIQ | SCR_IRQ)) {
-        switch (arm_current_el(env)) {
-        case 1:
-            if (arm_is_secure_below_el3(env) ||
-                ((env->cp15.hcr_el2 & (HCR_IMO | HCR_FMO)) == 0)) {
-                r = CP_ACCESS_TRAP_EL3;
-            }
-            break;
-        case 2:
-            r = CP_ACCESS_TRAP_EL3;
-            break;
-        case 3:
-            if (!is_a64(env) && !arm_is_el3_or_mon(env)) {
-                r = CP_ACCESS_TRAP_EL3;
-            }
-            break;
-        default:
-            g_assert_not_reached();
-        }
-    }
-
-    if (r == CP_ACCESS_TRAP_EL3 && !arm_el_is_aa64(env, 3)) {
-        r = CP_ACCESS_TRAP;
-    }
-    return r;
-}
-
-static CPAccessResult gicv3_fiq_access(CPUARMState *env,
-                                       const ARMCPRegInfo *ri, bool isread)
-{
-    CPAccessResult r = CP_ACCESS_OK;
-
-    if (env->cp15.scr_el3 & SCR_FIQ) {
-        switch (arm_current_el(env)) {
-        case 1:
-            if (arm_is_secure_below_el3(env) ||
-                ((env->cp15.hcr_el2 & HCR_FMO) == 0)) {
-                r = CP_ACCESS_TRAP_EL3;
-            }
-            break;
-        case 2:
-            r = CP_ACCESS_TRAP_EL3;
-            break;
-        case 3:
-            if (!is_a64(env) && !arm_is_el3_or_mon(env)) {
-                r = CP_ACCESS_TRAP_EL3;
-            }
-            break;
-        default:
-            g_assert_not_reached();
-        }
-    }
-
-    if (r == CP_ACCESS_TRAP_EL3 && !arm_el_is_aa64(env, 3)) {
-        r = CP_ACCESS_TRAP;
-    }
-    return r;
-}
-
-static CPAccessResult gicv3_irq_access(CPUARMState *env,
-                                       const ARMCPRegInfo *ri, bool isread)
-{
-    CPAccessResult r = CP_ACCESS_OK;
-
-    if (env->cp15.scr_el3 & SCR_IRQ) {
-        switch (arm_current_el(env)) {
-        case 1:
-            if (arm_is_secure_below_el3(env) ||
-                ((env->cp15.hcr_el2 & HCR_IMO) == 0)) {
-                r = CP_ACCESS_TRAP_EL3;
-            }
-            break;
-        case 2:
-            r = CP_ACCESS_TRAP_EL3;
-            break;
-        case 3:
-            if (!is_a64(env) && !arm_is_el3_or_mon(env)) {
-                r = CP_ACCESS_TRAP_EL3;
-            }
-            break;
-        default:
-            g_assert_not_reached();
-        }
-    }
-
-    if (r == CP_ACCESS_TRAP_EL3 && !arm_el_is_aa64(env, 3)) {
-        r = CP_ACCESS_TRAP;
-    }
-    return r;
-}
-
-static void icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    GICv3CPUState *cs = icc_cs_from_env(env);
-
-    cs->icc_ctlr_el1[GICV3_S] = ICC_CTLR_EL1_A3V |
-        (1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
-        (7 << ICC_CTLR_EL1_PRIBITS_SHIFT);
-    cs->icc_ctlr_el1[GICV3_NS] = ICC_CTLR_EL1_A3V |
-        (1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
-        (7 << ICC_CTLR_EL1_PRIBITS_SHIFT);
-    cs->icc_pmr_el1 = 0;
-    cs->icc_bpr[GICV3_G0] = GIC_MIN_BPR;
-    cs->icc_bpr[GICV3_G1] = GIC_MIN_BPR;
-    if (arm_feature(env, ARM_FEATURE_EL3)) {
-        cs->icc_bpr[GICV3_G1NS] = GIC_MIN_BPR_NS;
-    } else {
-        cs->icc_bpr[GICV3_G1NS] = GIC_MIN_BPR;
-    }
-    memset(cs->icc_apr, 0, sizeof(cs->icc_apr));
-    memset(cs->icc_igrpen, 0, sizeof(cs->icc_igrpen));
-    cs->icc_ctlr_el3 = ICC_CTLR_EL3_NDS | ICC_CTLR_EL3_A3V |
-        (1 << ICC_CTLR_EL3_IDBITS_SHIFT) |
-        (7 << ICC_CTLR_EL3_PRIBITS_SHIFT);
-}
-
-static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
-    { .name = "ICC_PMR_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 6, .opc2 = 0,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_irqfiq_access,
-      .readfn = icc_pmr_read,
-      .writefn = icc_pmr_write,
-      /* We hang the whole cpu interface reset routine off here
-       * rather than parcelling it out into one little function
-       * per register
-       */
-      .resetfn = icc_reset,
-    },
-    { .name = "ICC_IAR0_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 0,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_R, .accessfn = gicv3_fiq_access,
-      .readfn = icc_iar0_read,
-    },
-    { .name = "ICC_EOIR0_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 1,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_fiq_access,
-      .writefn = icc_eoir_write,
-    },
-    { .name = "ICC_HPPIR0_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 2,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_R, .accessfn = gicv3_fiq_access,
-      .readfn = icc_hppir0_read,
-    },
-    { .name = "ICC_BPR0_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 3,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_fiq_access,
-      .fieldoffset = offsetof(GICv3CPUState, icc_bpr[GICV3_G0]),
-      .writefn = icc_bpr_write,
-    },
-    { .name = "ICC_AP0R0_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 4,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_fiq_access,
-      .fieldoffset = offsetof(GICv3CPUState, icc_apr[GICV3_G0][0]),
-      .writefn = icc_ap_write,
-    },
-    { .name = "ICC_AP0R1_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 5,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_fiq_access,
-      .fieldoffset = offsetof(GICv3CPUState, icc_apr[GICV3_G0][1]),
-      .writefn = icc_ap_write,
-    },
-    { .name = "ICC_AP0R2_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 6,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_fiq_access,
-      .fieldoffset = offsetof(GICv3CPUState, icc_apr[GICV3_G0][2]),
-      .writefn = icc_ap_write,
-    },
-    { .name = "ICC_AP0R3_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 7,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_fiq_access,
-      .fieldoffset = offsetof(GICv3CPUState, icc_apr[GICV3_G0][3]),
-      .writefn = icc_ap_write,
-    },
-    /* All the ICC_AP1R*_EL1 registers are banked */
-    { .name = "ICC_AP1R0_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 0,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_irq_access,
-      .readfn = icc_ap_read,
-      .writefn = icc_ap_write,
-    },
-    { .name = "ICC_AP1R1_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 1,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_irq_access,
-      .readfn = icc_ap_read,
-      .writefn = icc_ap_write,
-    },
-    { .name = "ICC_AP1R2_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 2,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_irq_access,
-      .readfn = icc_ap_read,
-      .writefn = icc_ap_write,
-    },
-    { .name = "ICC_AP1R3_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 9, .opc2 = 3,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_irq_access,
-      .readfn = icc_ap_read,
-      .writefn = icc_ap_write,
-    },
-    { .name = "ICC_DIR_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 1,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
-      .writefn = icc_dir_write,
-    },
-    { .name = "ICC_RPR_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 3,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_R, .accessfn = gicv3_irqfiq_access,
-      .readfn = icc_rpr_read,
-    },
-    { .name = "ICC_SGI1R_EL1", .state = ARM_CP_STATE_AA64,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 5,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
-      .writefn = icc_sgi1r_write,
-    },
-    { .name = "ICC_SGI1R",
-      .cp = 15, .opc1 = 0, .crm = 12,
-      .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
-      .writefn = icc_sgi1r_write,
-    },
-    { .name = "ICC_ASGI1R_EL1", .state = ARM_CP_STATE_AA64,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 6,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
-      .writefn = icc_asgi1r_write,
-    },
-    { .name = "ICC_ASGI1R",
-      .cp = 15, .opc1 = 1, .crm = 12,
-      .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
-      .writefn = icc_asgi1r_write,
-    },
-    { .name = "ICC_SGI0R_EL1", .state = ARM_CP_STATE_AA64,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 7,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
-      .writefn = icc_sgi0r_write,
-    },
-    { .name = "ICC_SGI0R",
-      .cp = 15, .opc1 = 2, .crm = 12,
-      .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
-      .writefn = icc_sgi0r_write,
-    },
-    { .name = "ICC_IAR1_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 0,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_R, .accessfn = gicv3_irq_access,
-      .readfn = icc_iar1_read,
-    },
-    { .name = "ICC_EOIR1_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 1,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irq_access,
-      .writefn = icc_eoir_write,
-    },
-    { .name = "ICC_HPPIR1_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 2,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_R, .accessfn = gicv3_irq_access,
-      .readfn = icc_hppir1_read,
-    },
-    /* This register is banked */
-    { .name = "ICC_BPR1_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 3,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_irq_access,
-      .readfn = icc_bpr_read,
-      .writefn = icc_bpr_write,
-    },
-    /* This register is banked */
-    { .name = "ICC_CTLR_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 4,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_irqfiq_access,
-      .readfn = icc_ctlr_el1_read,
-      .writefn = icc_ctlr_el1_write,
-    },
-    { .name = "ICC_SRE_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 5,
-      .type = ARM_CP_NO_RAW | ARM_CP_CONST,
-      .access = PL1_RW,
-      /* We don't support IRQ/FIQ bypass and system registers are
-       * always enabled, so all our bits are RAZ/WI or RAO/WI.
-       * This register is banked but since it's constant we don't
-       * need to do anything special.
-       */
-      .resetvalue = 0x7,
-    },
-    { .name = "ICC_IGRPEN0_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 6,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_fiq_access,
-      .fieldoffset = offsetof(GICv3CPUState, icc_igrpen[GICV3_G0]),
-      .writefn = icc_igrpen_write,
-    },
-    /* This register is banked */
-    { .name = "ICC_IGRPEN1_EL1", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 7,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_RW, .accessfn = gicv3_irq_access,
-      .readfn = icc_igrpen_read,
-      .writefn = icc_igrpen_write,
-    },
-    { .name = "ICC_SRE_EL2", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 5,
-      .type = ARM_CP_NO_RAW | ARM_CP_CONST,
-      .access = PL2_RW,
-      /* We don't support IRQ/FIQ bypass and system registers are
-       * always enabled, so all our bits are RAZ/WI or RAO/WI.
-       */
-      .resetvalue = 0xf,
-    },
-    { .name = "ICC_CTLR_EL3", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 12, .opc2 = 4,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL3_RW,
-      .fieldoffset = offsetof(GICv3CPUState, icc_ctlr_el3),
-      .readfn = icc_ctlr_el3_read,
-      .writefn = icc_ctlr_el3_write,
-    },
-    { .name = "ICC_SRE_EL3", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 12, .opc2 = 5,
-      .type = ARM_CP_NO_RAW | ARM_CP_CONST,
-      .access = PL3_RW,
-      /* We don't support IRQ/FIQ bypass and system registers are
-       * always enabled, so all our bits are RAZ/WI or RAO/WI.
-       */
-      .resetvalue = 0xf,
-    },
-    { .name = "ICC_IGRPEN1_EL3", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 12, .opc2 = 7,
-      .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL3_RW,
-      .readfn = icc_igrpen1_el3_read,
-      .writefn = icc_igrpen1_el3_write,
-    },
-    REGINFO_SENTINEL
-};
-
-static void gicv3_cpuif_el_change_hook(ARMCPU *cpu, void *opaque)
-{
-    GICv3CPUState *cs = opaque;
-
-    gicv3_cpuif_update(cs);
-}
-
-void gicv3_init_cpuif(GICv3State *s)
-{
-    /* Called from the GICv3 realize function; register our system
-     * registers with the CPU
-     */
-    int i;
-
-    for (i = 0; i < s->num_cpu; i++) {
-        ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));
-        GICv3CPUState *cs = &s->cpu[i];
-
-        /* Note that we can't just use the GICv3CPUState as an opaque pointer
-         * in define_arm_cp_regs_with_opaque(), because when we're called back
-         * it might be with code translated by CPU 0 but run by CPU 1, in
-         * which case we'd get the wrong value.
-         * So instead we define the regs with no ri->opaque info, and
-         * get back to the GICv3CPUState from the ARMCPU by reading back
-         * the opaque pointer from the el_change_hook, which we're going
-         * to need to register anyway.
-         */
-        define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
-        arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs);
-    }
-}
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
deleted file mode 100644 (file)
index 3ea3dd0..0000000
+++ /dev/null
@@ -1,880 +0,0 @@
-/*
- * ARM GICv3 emulation: Distributor
- *
- * Copyright (c) 2015 Huawei.
- * Copyright (c) 2016 Linaro Limited.
- * Written by Shlomo Pongratz, Peter Maydell
- *
- * This code is licensed under the GPL, version 2 or (at your option)
- * any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "trace.h"
-#include "gicv3_internal.h"
-
-/* The GICD_NSACR registers contain a two bit field for each interrupt which
- * allows the guest to give NonSecure code access to registers controlling
- * Secure interrupts:
- *  0b00: no access (NS accesses to bits for Secure interrupts will RAZ/WI)
- *  0b01: NS r/w accesses permitted to ISPENDR, SETSPI_NSR, SGIR
- *  0b10: as 0b01, and also r/w to ICPENDR, r/o to ISACTIVER/ICACTIVER,
- *        and w/o to CLRSPI_NSR
- *  0b11: as 0b10, and also r/w to IROUTER and ITARGETSR
- *
- * Given a (multiple-of-32) interrupt number, these mask functions return
- * a mask word where each bit is 1 if the NSACR settings permit access
- * to the interrupt. The mask returned can then be ORed with the GICD_GROUP
- * word for this set of interrupts to give an overall mask.
- */
-
-typedef uint32_t maskfn(GICv3State *s, int irq);
-
-static uint32_t mask_nsacr_ge1(GICv3State *s, int irq)
-{
-    /* Return a mask where each bit is set if the NSACR field is >= 1 */
-    uint64_t raw_nsacr = s->gicd_nsacr[irq / 16 + 1];
-
-    raw_nsacr = raw_nsacr << 32 | s->gicd_nsacr[irq / 16];
-    raw_nsacr = (raw_nsacr >> 1) | raw_nsacr;
-    return half_unshuffle64(raw_nsacr);
-}
-
-static uint32_t mask_nsacr_ge2(GICv3State *s, int irq)
-{
-    /* Return a mask where each bit is set if the NSACR field is >= 2 */
-    uint64_t raw_nsacr = s->gicd_nsacr[irq / 16 + 1];
-
-    raw_nsacr = raw_nsacr << 32 | s->gicd_nsacr[irq / 16];
-    raw_nsacr = raw_nsacr >> 1;
-    return half_unshuffle64(raw_nsacr);
-}
-
-/* We don't need a mask_nsacr_ge3() because IROUTER<n> isn't a bitmap register,
- * but it would be implemented using:
- *  raw_nsacr = (raw_nsacr >> 1) & raw_nsacr;
- */
-
-static uint32_t mask_group_and_nsacr(GICv3State *s, MemTxAttrs attrs,
-                                     maskfn *maskfn, int irq)
-{
-    /* Return a 32-bit mask which should be applied for this set of 32
-     * interrupts; each bit is 1 if access is permitted by the
-     * combination of attrs.secure, GICD_GROUPR and GICD_NSACR.
-     */
-    uint32_t mask;
-
-    if (!attrs.secure && !(s->gicd_ctlr & GICD_CTLR_DS)) {
-        /* bits for Group 0 or Secure Group 1 interrupts are RAZ/WI
-         * unless the NSACR bits permit access.
-         */
-        mask = *gic_bmp_ptr32(s->group, irq);
-        if (maskfn) {
-            mask |= maskfn(s, irq);
-        }
-        return mask;
-    }
-    return 0xFFFFFFFFU;
-}
-
-static int gicd_ns_access(GICv3State *s, int irq)
-{
-    /* Return the 2 bit NS_access<x> field from GICD_NSACR<n> for the
-     * specified interrupt.
-     */
-    if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-        return 0;
-    }
-    return extract32(s->gicd_nsacr[irq / 16], (irq % 16) * 2, 2);
-}
-
-static void gicd_write_set_bitmap_reg(GICv3State *s, MemTxAttrs attrs,
-                                      uint32_t *bmp,
-                                      maskfn *maskfn,
-                                      int offset, uint32_t val)
-{
-    /* Helper routine to implement writing to a "set-bitmap" register
-     * (GICD_ISENABLER, GICD_ISPENDR, etc).
-     * Semantics implemented here:
-     * RAZ/WI for SGIs, PPIs, unimplemented IRQs
-     * Bits corresponding to Group 0 or Secure Group 1 interrupts RAZ/WI.
-     * Writing 1 means "set bit in bitmap"; writing 0 is ignored.
-     * offset should be the offset in bytes of the register from the start
-     * of its group.
-     */
-    int irq = offset * 8;
-
-    if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-        return;
-    }
-    val &= mask_group_and_nsacr(s, attrs, maskfn, irq);
-    *gic_bmp_ptr32(bmp, irq) |= val;
-    gicv3_update(s, irq, 32);
-}
-
-static void gicd_write_clear_bitmap_reg(GICv3State *s, MemTxAttrs attrs,
-                                        uint32_t *bmp,
-                                        maskfn *maskfn,
-                                        int offset, uint32_t val)
-{
-    /* Helper routine to implement writing to a "clear-bitmap" register
-     * (GICD_ICENABLER, GICD_ICPENDR, etc).
-     * Semantics implemented here:
-     * RAZ/WI for SGIs, PPIs, unimplemented IRQs
-     * Bits corresponding to Group 0 or Secure Group 1 interrupts RAZ/WI.
-     * Writing 1 means "clear bit in bitmap"; writing 0 is ignored.
-     * offset should be the offset in bytes of the register from the start
-     * of its group.
-     */
-    int irq = offset * 8;
-
-    if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-        return;
-    }
-    val &= mask_group_and_nsacr(s, attrs, maskfn, irq);
-    *gic_bmp_ptr32(bmp, irq) &= ~val;
-    gicv3_update(s, irq, 32);
-}
-
-static uint32_t gicd_read_bitmap_reg(GICv3State *s, MemTxAttrs attrs,
-                                     uint32_t *bmp,
-                                     maskfn *maskfn,
-                                     int offset)
-{
-    /* Helper routine to implement reading a "set/clear-bitmap" register
-     * (GICD_ICENABLER, GICD_ISENABLER, GICD_ICPENDR, etc).
-     * Semantics implemented here:
-     * RAZ/WI for SGIs, PPIs, unimplemented IRQs
-     * Bits corresponding to Group 0 or Secure Group 1 interrupts RAZ/WI.
-     * offset should be the offset in bytes of the register from the start
-     * of its group.
-     */
-    int irq = offset * 8;
-    uint32_t val;
-
-    if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-        return 0;
-    }
-    val = *gic_bmp_ptr32(bmp, irq);
-    if (bmp == s->pending) {
-        /* The PENDING register is a special case -- for level triggered
-         * interrupts, the PENDING state is the logical OR of the state of
-         * the PENDING latch with the input line level.
-         */
-        uint32_t edge = *gic_bmp_ptr32(s->edge_trigger, irq);
-        uint32_t level = *gic_bmp_ptr32(s->level, irq);
-        val |= (~edge & level);
-    }
-    val &= mask_group_and_nsacr(s, attrs, maskfn, irq);
-    return val;
-}
-
-static uint8_t gicd_read_ipriorityr(GICv3State *s, MemTxAttrs attrs, int irq)
-{
-    /* Read the value of GICD_IPRIORITYR<n> for the specified interrupt,
-     * honouring security state (these are RAZ/WI for Group 0 or Secure
-     * Group 1 interrupts).
-     */
-    uint32_t prio;
-
-    if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-        return 0;
-    }
-
-    prio = s->gicd_ipriority[irq];
-
-    if (!attrs.secure && !(s->gicd_ctlr & GICD_CTLR_DS)) {
-        if (!gicv3_gicd_group_test(s, irq)) {
-            /* Fields for Group 0 or Secure Group 1 interrupts are RAZ/WI */
-            return 0;
-        }
-        /* NS view of the interrupt priority */
-        prio = (prio << 1) & 0xff;
-    }
-    return prio;
-}
-
-static void gicd_write_ipriorityr(GICv3State *s, MemTxAttrs attrs, int irq,
-                                  uint8_t value)
-{
-    /* Write the value of GICD_IPRIORITYR<n> for the specified interrupt,
-     * honouring security state (these are RAZ/WI for Group 0 or Secure
-     * Group 1 interrupts).
-     */
-    if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-        return;
-    }
-
-    if (!attrs.secure && !(s->gicd_ctlr & GICD_CTLR_DS)) {
-        if (!gicv3_gicd_group_test(s, irq)) {
-            /* Fields for Group 0 or Secure Group 1 interrupts are RAZ/WI */
-            return;
-        }
-        /* NS view of the interrupt priority */
-        value = 0x80 | (value >> 1);
-    }
-    s->gicd_ipriority[irq] = value;
-}
-
-static uint64_t gicd_read_irouter(GICv3State *s, MemTxAttrs attrs, int irq)
-{
-    /* Read the value of GICD_IROUTER<n> for the specified interrupt,
-     * honouring security state.
-     */
-    if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-        return 0;
-    }
-
-    if (!attrs.secure && !(s->gicd_ctlr & GICD_CTLR_DS)) {
-        /* RAZ/WI for NS accesses to secure interrupts */
-        if (!gicv3_gicd_group_test(s, irq)) {
-            if (gicd_ns_access(s, irq) != 3) {
-                return 0;
-            }
-        }
-    }
-
-    return s->gicd_irouter[irq];
-}
-
-static void gicd_write_irouter(GICv3State *s, MemTxAttrs attrs, int irq,
-                               uint64_t val)
-{
-    /* Write the value of GICD_IROUTER<n> for the specified interrupt,
-     * honouring security state.
-     */
-    if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-        return;
-    }
-
-    if (!attrs.secure && !(s->gicd_ctlr & GICD_CTLR_DS)) {
-        /* RAZ/WI for NS accesses to secure interrupts */
-        if (!gicv3_gicd_group_test(s, irq)) {
-            if (gicd_ns_access(s, irq) != 3) {
-                return;
-            }
-        }
-    }
-
-    s->gicd_irouter[irq] = val;
-    gicv3_cache_target_cpustate(s, irq);
-    gicv3_update(s, irq, 1);
-}
-
-static MemTxResult gicd_readb(GICv3State *s, hwaddr offset,
-                              uint64_t *data, MemTxAttrs attrs)
-{
-    /* Most GICv3 distributor registers do not support byte accesses. */
-    switch (offset) {
-    case GICD_CPENDSGIR ... GICD_CPENDSGIR + 0xf:
-    case GICD_SPENDSGIR ... GICD_SPENDSGIR + 0xf:
-    case GICD_ITARGETSR ... GICD_ITARGETSR + 0x3ff:
-        /* This GIC implementation always has affinity routing enabled,
-         * so these registers are all RAZ/WI.
-         */
-        return MEMTX_OK;
-    case GICD_IPRIORITYR ... GICD_IPRIORITYR + 0x3ff:
-        *data = gicd_read_ipriorityr(s, attrs, offset - GICD_IPRIORITYR);
-        return MEMTX_OK;
-    default:
-        return MEMTX_ERROR;
-    }
-}
-
-static MemTxResult gicd_writeb(GICv3State *s, hwaddr offset,
-                               uint64_t value, MemTxAttrs attrs)
-{
-    /* Most GICv3 distributor registers do not support byte accesses. */
-    switch (offset) {
-    case GICD_CPENDSGIR ... GICD_CPENDSGIR + 0xf:
-    case GICD_SPENDSGIR ... GICD_SPENDSGIR + 0xf:
-    case GICD_ITARGETSR ... GICD_ITARGETSR + 0x3ff:
-        /* This GIC implementation always has affinity routing enabled,
-         * so these registers are all RAZ/WI.
-         */
-        return MEMTX_OK;
-    case GICD_IPRIORITYR ... GICD_IPRIORITYR + 0x3ff:
-    {
-        int irq = offset - GICD_IPRIORITYR;
-
-        if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-            return MEMTX_OK;
-        }
-        gicd_write_ipriorityr(s, attrs, irq, value);
-        gicv3_update(s, irq, 1);
-        return MEMTX_OK;
-    }
-    default:
-        return MEMTX_ERROR;
-    }
-}
-
-static MemTxResult gicd_readw(GICv3State *s, hwaddr offset,
-                              uint64_t *data, MemTxAttrs attrs)
-{
-    /* Only GICD_SETSPI_NSR, GICD_CLRSPI_NSR, GICD_SETSPI_SR and GICD_SETSPI_NSR
-     * support 16 bit accesses, and those registers are all part of the
-     * optional message-based SPI feature which this GIC does not currently
-     * implement (ie for us GICD_TYPER.MBIS == 0), so for us they are
-     * reserved.
-     */
-    return MEMTX_ERROR;
-}
-
-static MemTxResult gicd_writew(GICv3State *s, hwaddr offset,
-                               uint64_t value, MemTxAttrs attrs)
-{
-    /* Only GICD_SETSPI_NSR, GICD_CLRSPI_NSR, GICD_SETSPI_SR and GICD_SETSPI_NSR
-     * support 16 bit accesses, and those registers are all part of the
-     * optional message-based SPI feature which this GIC does not currently
-     * implement (ie for us GICD_TYPER.MBIS == 0), so for us they are
-     * reserved.
-     */
-    return MEMTX_ERROR;
-}
-
-static MemTxResult gicd_readl(GICv3State *s, hwaddr offset,
-                              uint64_t *data, MemTxAttrs attrs)
-{
-    /* Almost all GICv3 distributor registers are 32-bit.
-     * Note that WO registers must return an UNKNOWN value on reads,
-     * not an abort.
-     */
-
-    switch (offset) {
-    case GICD_CTLR:
-        if (!attrs.secure && !(s->gicd_ctlr & GICD_CTLR_DS)) {
-            /* The NS view of the GICD_CTLR sees only certain bits:
-             * + bit [31] (RWP) is an alias of the Secure bit [31]
-             * + bit [4] (ARE_NS) is an alias of Secure bit [5]
-             * + bit [1] (EnableGrp1A) is an alias of Secure bit [1] if
-             *   NS affinity routing is enabled, otherwise RES0
-             * + bit [0] (EnableGrp1) is an alias of Secure bit [1] if
-             *   NS affinity routing is not enabled, otherwise RES0
-             * Since for QEMU affinity routing is always enabled
-             * for both S and NS this means that bits [4] and [5] are
-             * both always 1, and we can simply make the NS view
-             * be bits 31, 4 and 1 of the S view.
-             */
-            *data = s->gicd_ctlr & (GICD_CTLR_ARE_S |
-                                    GICD_CTLR_EN_GRP1NS |
-                                    GICD_CTLR_RWP);
-        } else {
-            *data = s->gicd_ctlr;
-        }
-        return MEMTX_OK;
-    case GICD_TYPER:
-    {
-        /* For this implementation:
-         * No1N == 1 (1-of-N SPI interrupts not supported)
-         * A3V == 1 (non-zero values of Affinity level 3 supported)
-         * IDbits == 0xf (we support 16-bit interrupt identifiers)
-         * DVIS == 0 (Direct virtual LPI injection not supported)
-         * LPIS == 0 (LPIs not supported)
-         * MBIS == 0 (message-based SPIs not supported)
-         * SecurityExtn == 1 if security extns supported
-         * CPUNumber == 0 since for us ARE is always 1
-         * ITLinesNumber == (num external irqs / 32) - 1
-         */
-        int itlinesnumber = ((s->num_irq - GIC_INTERNAL) / 32) - 1;
-
-        *data = (1 << 25) | (1 << 24) | (s->security_extn << 10) |
-            (0xf << 19) | itlinesnumber;
-        return MEMTX_OK;
-    }
-    case GICD_IIDR:
-        /* We claim to be an ARM r0p0 with a zero ProductID.
-         * This is the same as an r0p0 GIC-500.
-         */
-        *data = gicv3_iidr();
-        return MEMTX_OK;
-    case GICD_STATUSR:
-        /* RAZ/WI for us (this is an optional register and our implementation
-         * does not track RO/WO/reserved violations to report them to the guest)
-         */
-        *data = 0;
-        return MEMTX_OK;
-    case GICD_IGROUPR ... GICD_IGROUPR + 0x7f:
-    {
-        int irq;
-
-        if (!attrs.secure && !(s->gicd_ctlr & GICD_CTLR_DS)) {
-            *data = 0;
-            return MEMTX_OK;
-        }
-        /* RAZ/WI for SGIs, PPIs, unimplemented irqs */
-        irq = (offset - GICD_IGROUPR) * 8;
-        if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-            *data = 0;
-            return MEMTX_OK;
-        }
-        *data = *gic_bmp_ptr32(s->group, irq);
-        return MEMTX_OK;
-    }
-    case GICD_ISENABLER ... GICD_ISENABLER + 0x7f:
-        *data = gicd_read_bitmap_reg(s, attrs, s->enabled, NULL,
-                                     offset - GICD_ISENABLER);
-        return MEMTX_OK;
-    case GICD_ICENABLER ... GICD_ICENABLER + 0x7f:
-        *data = gicd_read_bitmap_reg(s, attrs, s->enabled, NULL,
-                                     offset - GICD_ICENABLER);
-        return MEMTX_OK;
-    case GICD_ISPENDR ... GICD_ISPENDR + 0x7f:
-        *data = gicd_read_bitmap_reg(s, attrs, s->pending, mask_nsacr_ge1,
-                                     offset - GICD_ISPENDR);
-        return MEMTX_OK;
-    case GICD_ICPENDR ... GICD_ICPENDR + 0x7f:
-        *data = gicd_read_bitmap_reg(s, attrs, s->pending, mask_nsacr_ge2,
-                                     offset - GICD_ICPENDR);
-        return MEMTX_OK;
-    case GICD_ISACTIVER ... GICD_ISACTIVER + 0x7f:
-        *data = gicd_read_bitmap_reg(s, attrs, s->active, mask_nsacr_ge2,
-                                     offset - GICD_ISACTIVER);
-        return MEMTX_OK;
-    case GICD_ICACTIVER ... GICD_ICACTIVER + 0x7f:
-        *data = gicd_read_bitmap_reg(s, attrs, s->active, mask_nsacr_ge2,
-                                     offset - GICD_ICACTIVER);
-        return MEMTX_OK;
-    case GICD_IPRIORITYR ... GICD_IPRIORITYR + 0x3ff:
-    {
-        int i, irq = offset - GICD_IPRIORITYR;
-        uint32_t value = 0;
-
-        for (i = irq + 3; i >= irq; i--, value <<= 8) {
-            value |= gicd_read_ipriorityr(s, attrs, i);
-        }
-        *data = value;
-        return MEMTX_OK;
-    }
-    case GICD_ITARGETSR ... GICD_ITARGETSR + 0x3ff:
-        /* RAZ/WI since affinity routing is always enabled */
-        *data = 0;
-        return MEMTX_OK;
-    case GICD_ICFGR ... GICD_ICFGR + 0xff:
-    {
-        /* Here only the even bits are used; odd bits are RES0 */
-        int irq = (offset - GICD_ICFGR) * 4;
-        uint32_t value = 0;
-
-        if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-            *data = 0;
-            return MEMTX_OK;
-        }
-
-        /* Since our edge_trigger bitmap is one bit per irq, we only need
-         * half of the 32-bit word, which we can then spread out
-         * into the odd bits.
-         */
-        value = *gic_bmp_ptr32(s->edge_trigger, irq & ~0x1f);
-        value &= mask_group_and_nsacr(s, attrs, NULL, irq & ~0x1f);
-        value = extract32(value, (irq & 0x1f) ? 16 : 0, 16);
-        value = half_shuffle32(value) << 1;
-        *data = value;
-        return MEMTX_OK;
-    }
-    case GICD_IGRPMODR ... GICD_IGRPMODR + 0xff:
-    {
-        int irq;
-
-        if ((s->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
-            /* RAZ/WI if security disabled, or if
-             * security enabled and this is an NS access
-             */
-            *data = 0;
-            return MEMTX_OK;
-        }
-        /* RAZ/WI for SGIs, PPIs, unimplemented irqs */
-        irq = (offset - GICD_IGRPMODR) * 8;
-        if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-            *data = 0;
-            return MEMTX_OK;
-        }
-        *data = *gic_bmp_ptr32(s->grpmod, irq);
-        return MEMTX_OK;
-    }
-    case GICD_NSACR ... GICD_NSACR + 0xff:
-    {
-        /* Two bits per interrupt */
-        int irq = (offset - GICD_NSACR) * 4;
-
-        if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-            *data = 0;
-            return MEMTX_OK;
-        }
-
-        if ((s->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
-            /* RAZ/WI if security disabled, or if
-             * security enabled and this is an NS access
-             */
-            *data = 0;
-            return MEMTX_OK;
-        }
-
-        *data = s->gicd_nsacr[irq / 16];
-        return MEMTX_OK;
-    }
-    case GICD_CPENDSGIR ... GICD_CPENDSGIR + 0xf:
-    case GICD_SPENDSGIR ... GICD_SPENDSGIR + 0xf:
-        /* RAZ/WI since affinity routing is always enabled */
-        *data = 0;
-        return MEMTX_OK;
-    case GICD_IROUTER ... GICD_IROUTER + 0x1fdf:
-    {
-        uint64_t r;
-        int irq = (offset - GICD_IROUTER) / 8;
-
-        r = gicd_read_irouter(s, attrs, irq);
-        if (offset & 7) {
-            *data = r >> 32;
-        } else {
-            *data = (uint32_t)r;
-        }
-        return MEMTX_OK;
-    }
-    case GICD_IDREGS ... GICD_IDREGS + 0x1f:
-        /* ID registers */
-        *data = gicv3_idreg(offset - GICD_IDREGS);
-        return MEMTX_OK;
-    case GICD_SGIR:
-        /* WO registers, return unknown value */
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: invalid guest read from WO register at offset "
-                      TARGET_FMT_plx "\n", __func__, offset);
-        *data = 0;
-        return MEMTX_OK;
-    default:
-        return MEMTX_ERROR;
-    }
-}
-
-static MemTxResult gicd_writel(GICv3State *s, hwaddr offset,
-                               uint64_t value, MemTxAttrs attrs)
-{
-    /* Almost all GICv3 distributor registers are 32-bit. Note that
-     * RO registers must ignore writes, not abort.
-     */
-
-    switch (offset) {
-    case GICD_CTLR:
-    {
-        uint32_t mask;
-        /* GICv3 5.3.20 */
-        if (s->gicd_ctlr & GICD_CTLR_DS) {
-            /* With only one security state, E1NWF is RAZ/WI, DS is RAO/WI,
-             * ARE is RAO/WI (affinity routing always on), and only
-             * bits 0 and 1 (group enables) are writable.
-             */
-            mask = GICD_CTLR_EN_GRP0 | GICD_CTLR_EN_GRP1NS;
-        } else {
-            if (attrs.secure) {
-                /* for secure access:
-                 * ARE_NS and ARE_S are RAO/WI (affinity routing always on)
-                 * E1NWF is RAZ/WI (we don't support enable-1-of-n-wakeup)
-                 *
-                 * We can only modify bits[2:0] (the group enables).
-                 */
-                mask = GICD_CTLR_DS | GICD_CTLR_EN_GRP0 | GICD_CTLR_EN_GRP1_ALL;
-            } else {
-                /* For non secure access ARE_NS is RAO/WI and EnableGrp1
-                 * is RES0. The only writable bit is [1] (EnableGrp1A), which
-                 * is an alias of the Secure bit [1].
-                 */
-                mask = GICD_CTLR_EN_GRP1NS;
-            }
-        }
-        s->gicd_ctlr = (s->gicd_ctlr & ~mask) | (value & mask);
-        if (value & mask & GICD_CTLR_DS) {
-            /* We just set DS, so the ARE_NS and EnG1S bits are now RES0.
-             * Note that this is a one-way transition because if DS is set
-             * then it's not writeable, so it can only go back to 0 with a
-             * hardware reset.
-             */
-            s->gicd_ctlr &= ~(GICD_CTLR_EN_GRP1S | GICD_CTLR_ARE_NS);
-        }
-        gicv3_full_update(s);
-        return MEMTX_OK;
-    }
-    case GICD_STATUSR:
-        /* RAZ/WI for our implementation */
-        return MEMTX_OK;
-    case GICD_IGROUPR ... GICD_IGROUPR + 0x7f:
-    {
-        int irq;
-
-        if (!attrs.secure && !(s->gicd_ctlr & GICD_CTLR_DS)) {
-            return MEMTX_OK;
-        }
-        /* RAZ/WI for SGIs, PPIs, unimplemented irqs */
-        irq = (offset - GICD_IGROUPR) * 8;
-        if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-            return MEMTX_OK;
-        }
-        *gic_bmp_ptr32(s->group, irq) = value;
-        gicv3_update(s, irq, 32);
-        return MEMTX_OK;
-    }
-    case GICD_ISENABLER ... GICD_ISENABLER + 0x7f:
-        gicd_write_set_bitmap_reg(s, attrs, s->enabled, NULL,
-                                  offset - GICD_ISENABLER, value);
-        return MEMTX_OK;
-    case GICD_ICENABLER ... GICD_ICENABLER + 0x7f:
-        gicd_write_clear_bitmap_reg(s, attrs, s->enabled, NULL,
-                                    offset - GICD_ICENABLER, value);
-        return MEMTX_OK;
-    case GICD_ISPENDR ... GICD_ISPENDR + 0x7f:
-        gicd_write_set_bitmap_reg(s, attrs, s->pending, mask_nsacr_ge1,
-                                  offset - GICD_ISPENDR, value);
-        return MEMTX_OK;
-    case GICD_ICPENDR ... GICD_ICPENDR + 0x7f:
-        gicd_write_clear_bitmap_reg(s, attrs, s->pending, mask_nsacr_ge2,
-                                    offset - GICD_ICPENDR, value);
-        return MEMTX_OK;
-    case GICD_ISACTIVER ... GICD_ISACTIVER + 0x7f:
-        gicd_write_set_bitmap_reg(s, attrs, s->active, NULL,
-                                  offset - GICD_ISACTIVER, value);
-        return MEMTX_OK;
-    case GICD_ICACTIVER ... GICD_ICACTIVER + 0x7f:
-        gicd_write_clear_bitmap_reg(s, attrs, s->active, NULL,
-                                    offset - GICD_ICACTIVER, value);
-        return MEMTX_OK;
-    case GICD_IPRIORITYR ... GICD_IPRIORITYR + 0x3ff:
-    {
-        int i, irq = offset - GICD_IPRIORITYR;
-
-        if (irq < GIC_INTERNAL || irq + 3 >= s->num_irq) {
-            return MEMTX_OK;
-        }
-
-        for (i = irq; i < irq + 4; i++, value >>= 8) {
-            gicd_write_ipriorityr(s, attrs, i, value);
-        }
-        gicv3_update(s, irq, 4);
-        return MEMTX_OK;
-    }
-    case GICD_ITARGETSR ... GICD_ITARGETSR + 0x3ff:
-        /* RAZ/WI since affinity routing is always enabled */
-        return MEMTX_OK;
-    case GICD_ICFGR ... GICD_ICFGR + 0xff:
-    {
-        /* Here only the odd bits are used; even bits are RES0 */
-        int irq = (offset - GICD_ICFGR) * 4;
-        uint32_t mask, oldval;
-
-        if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-            return MEMTX_OK;
-        }
-
-        /* Since our edge_trigger bitmap is one bit per irq, our input
-         * 32-bits will compress down into 16 bits which we need
-         * to write into the bitmap.
-         */
-        value = half_unshuffle32(value >> 1);
-        mask = mask_group_and_nsacr(s, attrs, NULL, irq & ~0x1f);
-        if (irq & 0x1f) {
-            value <<= 16;
-            mask &= 0xffff0000U;
-        } else {
-            mask &= 0xffff;
-        }
-        oldval = *gic_bmp_ptr32(s->edge_trigger, (irq & ~0x1f));
-        value = (oldval & ~mask) | (value & mask);
-        *gic_bmp_ptr32(s->edge_trigger, irq & ~0x1f) = value;
-        return MEMTX_OK;
-    }
-    case GICD_IGRPMODR ... GICD_IGRPMODR + 0xff:
-    {
-        int irq;
-
-        if ((s->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
-            /* RAZ/WI if security disabled, or if
-             * security enabled and this is an NS access
-             */
-            return MEMTX_OK;
-        }
-        /* RAZ/WI for SGIs, PPIs, unimplemented irqs */
-        irq = (offset - GICD_IGRPMODR) * 8;
-        if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-            return MEMTX_OK;
-        }
-        *gic_bmp_ptr32(s->grpmod, irq) = value;
-        gicv3_update(s, irq, 32);
-        return MEMTX_OK;
-    }
-    case GICD_NSACR ... GICD_NSACR + 0xff:
-    {
-        /* Two bits per interrupt */
-        int irq = (offset - GICD_NSACR) * 4;
-
-        if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-            return MEMTX_OK;
-        }
-
-        if ((s->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
-            /* RAZ/WI if security disabled, or if
-             * security enabled and this is an NS access
-             */
-            return MEMTX_OK;
-        }
-
-        s->gicd_nsacr[irq / 16] = value;
-        /* No update required as this only affects access permission checks */
-        return MEMTX_OK;
-    }
-    case GICD_SGIR:
-        /* RES0 if affinity routing is enabled */
-        return MEMTX_OK;
-    case GICD_CPENDSGIR ... GICD_CPENDSGIR + 0xf:
-    case GICD_SPENDSGIR ... GICD_SPENDSGIR + 0xf:
-        /* RAZ/WI since affinity routing is always enabled */
-        return MEMTX_OK;
-    case GICD_IROUTER ... GICD_IROUTER + 0x1fdf:
-    {
-        uint64_t r;
-        int irq = (offset - GICD_IROUTER) / 8;
-
-        if (irq < GIC_INTERNAL || irq >= s->num_irq) {
-            return MEMTX_OK;
-        }
-
-        /* Write half of the 64-bit register */
-        r = gicd_read_irouter(s, attrs, irq);
-        r = deposit64(r, (offset & 7) ? 32 : 0, 32, value);
-        gicd_write_irouter(s, attrs, irq, r);
-        return MEMTX_OK;
-    }
-    case GICD_IDREGS ... GICD_IDREGS + 0x1f:
-    case GICD_TYPER:
-    case GICD_IIDR:
-        /* RO registers, ignore the write */
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: invalid guest write to RO register at offset "
-                      TARGET_FMT_plx "\n", __func__, offset);
-        return MEMTX_OK;
-    default:
-        return MEMTX_ERROR;
-    }
-}
-
-static MemTxResult gicd_writell(GICv3State *s, hwaddr offset,
-                                uint64_t value, MemTxAttrs attrs)
-{
-    /* Our only 64-bit registers are GICD_IROUTER<n> */
-    int irq;
-
-    switch (offset) {
-    case GICD_IROUTER ... GICD_IROUTER + 0x1fdf:
-        irq = (offset - GICD_IROUTER) / 8;
-        gicd_write_irouter(s, attrs, irq, value);
-        return MEMTX_OK;
-    default:
-        return MEMTX_ERROR;
-    }
-}
-
-static MemTxResult gicd_readll(GICv3State *s, hwaddr offset,
-                               uint64_t *data, MemTxAttrs attrs)
-{
-    /* Our only 64-bit registers are GICD_IROUTER<n> */
-    int irq;
-
-    switch (offset) {
-    case GICD_IROUTER ... GICD_IROUTER + 0x1fdf:
-        irq = (offset - GICD_IROUTER) / 8;
-        *data = gicd_read_irouter(s, attrs, irq);
-        return MEMTX_OK;
-    default:
-        return MEMTX_ERROR;
-    }
-}
-
-MemTxResult gicv3_dist_read(void *opaque, hwaddr offset, uint64_t *data,
-                            unsigned size, MemTxAttrs attrs)
-{
-    GICv3State *s = (GICv3State *)opaque;
-    MemTxResult r;
-
-    switch (size) {
-    case 1:
-        r = gicd_readb(s, offset, data, attrs);
-        break;
-    case 2:
-        r = gicd_readw(s, offset, data, attrs);
-        break;
-    case 4:
-        r = gicd_readl(s, offset, data, attrs);
-        break;
-    case 8:
-        r = gicd_readll(s, offset, data, attrs);
-        break;
-    default:
-        r = MEMTX_ERROR;
-        break;
-    }
-
-    if (r == MEMTX_ERROR) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: invalid guest read at offset " TARGET_FMT_plx
-                      "size %u\n", __func__, offset, size);
-        trace_gicv3_dist_badread(offset, size, attrs.secure);
-    } else {
-        trace_gicv3_dist_read(offset, *data, size, attrs.secure);
-    }
-    return r;
-}
-
-MemTxResult gicv3_dist_write(void *opaque, hwaddr offset, uint64_t data,
-                             unsigned size, MemTxAttrs attrs)
-{
-    GICv3State *s = (GICv3State *)opaque;
-    MemTxResult r;
-
-    switch (size) {
-    case 1:
-        r = gicd_writeb(s, offset, data, attrs);
-        break;
-    case 2:
-        r = gicd_writew(s, offset, data, attrs);
-        break;
-    case 4:
-        r = gicd_writel(s, offset, data, attrs);
-        break;
-    case 8:
-        r = gicd_writell(s, offset, data, attrs);
-        break;
-    default:
-        r = MEMTX_ERROR;
-        break;
-    }
-
-    if (r == MEMTX_ERROR) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: invalid guest write at offset " TARGET_FMT_plx
-                      "size %u\n", __func__, offset, size);
-        trace_gicv3_dist_badwrite(offset, data, size, attrs.secure);
-    } else {
-        trace_gicv3_dist_write(offset, data, size, attrs.secure);
-    }
-    return r;
-}
-
-void gicv3_dist_set_irq(GICv3State *s, int irq, int level)
-{
-    /* Update distributor state for a change in an external SPI input line */
-    if (level == gicv3_gicd_level_test(s, irq)) {
-        return;
-    }
-
-    trace_gicv3_dist_set_irq(irq, level);
-
-    gicv3_gicd_level_replace(s, irq, level);
-
-    if (level) {
-        /* 0->1 edges latch the pending bit for edge-triggered interrupts */
-        if (gicv3_gicd_edge_trigger_test(s, irq)) {
-            gicv3_gicd_pending_set(s, irq);
-        }
-    }
-
-    gicv3_update(s, irq, 1);
-}
index 711fde3..acc1730 100644 (file)
@@ -26,7 +26,6 @@
 #include "sysemu/kvm.h"
 #include "kvm_arm.h"
 #include "vgic_common.h"
-#include "migration/migration.h"
 
 #ifdef DEBUG_GICV3_KVM
 #define DPRINTF(fmt, ...) \
@@ -120,13 +119,6 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
                             KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd);
     kvm_arm_register_device(&s->iomem_redist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
                             KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd);
-
-    /* Block migration of a KVM GICv3 device: the API for saving and restoring
-     * the state in the kernel is not yet finalised in the kernel or
-     * implemented in QEMU.
-     */
-    error_setg(&s->migration_blocker, "vGICv3 migration is not implemented");
-    migrate_add_blocker(s->migration_blocker);
 }
 
 static void kvm_arm_gicv3_class_init(ObjectClass *klass, void *data)
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
deleted file mode 100644 (file)
index 77e5cfa..0000000
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * ARM GICv3 emulation: Redistributor
- *
- * Copyright (c) 2015 Huawei.
- * Copyright (c) 2016 Linaro Limited.
- * Written by Shlomo Pongratz, Peter Maydell
- *
- * This code is licensed under the GPL, version 2 or (at your option)
- * any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "trace.h"
-#include "gicv3_internal.h"
-
-static uint32_t mask_group(GICv3CPUState *cs, MemTxAttrs attrs)
-{
-    /* Return a 32-bit mask which should be applied for this set of 32
-     * interrupts; each bit is 1 if access is permitted by the
-     * combination of attrs.secure and GICR_GROUPR. (GICR_NSACR does
-     * not affect config register accesses, unlike GICD_NSACR.)
-     */
-    if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
-        /* bits for Group 0 or Secure Group 1 interrupts are RAZ/WI */
-        return cs->gicr_igroupr0;
-    }
-    return 0xFFFFFFFFU;
-}
-
-static int gicr_ns_access(GICv3CPUState *cs, int irq)
-{
-    /* Return the 2 bit NSACR.NS_access field for this SGI */
-    assert(irq < 16);
-    return extract32(cs->gicr_nsacr, irq * 2, 2);
-}
-
-static void gicr_write_set_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs,
-                                      uint32_t *reg, uint32_t val)
-{
-    /* Helper routine to implement writing to a "set-bitmap" register */
-    val &= mask_group(cs, attrs);
-    *reg |= val;
-    gicv3_redist_update(cs);
-}
-
-static void gicr_write_clear_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs,
-                                        uint32_t *reg, uint32_t val)
-{
-    /* Helper routine to implement writing to a "clear-bitmap" register */
-    val &= mask_group(cs, attrs);
-    *reg &= ~val;
-    gicv3_redist_update(cs);
-}
-
-static uint32_t gicr_read_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs,
-                                     uint32_t reg)
-{
-    reg &= mask_group(cs, attrs);
-    return reg;
-}
-
-static uint8_t gicr_read_ipriorityr(GICv3CPUState *cs, MemTxAttrs attrs,
-                                    int irq)
-{
-    /* Read the value of GICR_IPRIORITYR<n> for the specified interrupt,
-     * honouring security state (these are RAZ/WI for Group 0 or Secure
-     * Group 1 interrupts).
-     */
-    uint32_t prio;
-
-    prio = cs->gicr_ipriorityr[irq];
-
-    if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
-        if (!(cs->gicr_igroupr0 & (1U << irq))) {
-            /* Fields for Group 0 or Secure Group 1 interrupts are RAZ/WI */
-            return 0;
-        }
-        /* NS view of the interrupt priority */
-        prio = (prio << 1) & 0xff;
-    }
-    return prio;
-}
-
-static void gicr_write_ipriorityr(GICv3CPUState *cs, MemTxAttrs attrs, int irq,
-                                  uint8_t value)
-{
-    /* Write the value of GICD_IPRIORITYR<n> for the specified interrupt,
-     * honouring security state (these are RAZ/WI for Group 0 or Secure
-     * Group 1 interrupts).
-     */
-    if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
-        if (!(cs->gicr_igroupr0 & (1U << irq))) {
-            /* Fields for Group 0 or Secure Group 1 interrupts are RAZ/WI */
-            return;
-        }
-        /* NS view of the interrupt priority */
-        value = 0x80 | (value >> 1);
-    }
-    cs->gicr_ipriorityr[irq] = value;
-}
-
-static MemTxResult gicr_readb(GICv3CPUState *cs, hwaddr offset,
-                              uint64_t *data, MemTxAttrs attrs)
-{
-    switch (offset) {
-    case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f:
-        *data = gicr_read_ipriorityr(cs, attrs, offset - GICR_IPRIORITYR);
-        return MEMTX_OK;
-    default:
-        return MEMTX_ERROR;
-    }
-}
-
-static MemTxResult gicr_writeb(GICv3CPUState *cs, hwaddr offset,
-                               uint64_t value, MemTxAttrs attrs)
-{
-    switch (offset) {
-    case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f:
-        gicr_write_ipriorityr(cs, attrs, offset - GICR_IPRIORITYR, value);
-        gicv3_redist_update(cs);
-        return MEMTX_OK;
-    default:
-        return MEMTX_ERROR;
-    }
-}
-
-static MemTxResult gicr_readl(GICv3CPUState *cs, hwaddr offset,
-                              uint64_t *data, MemTxAttrs attrs)
-{
-    switch (offset) {
-    case GICR_CTLR:
-        *data = cs->gicr_ctlr;
-        return MEMTX_OK;
-    case GICR_IIDR:
-        *data = gicv3_iidr();
-        return MEMTX_OK;
-    case GICR_TYPER:
-        *data = extract64(cs->gicr_typer, 0, 32);
-        return MEMTX_OK;
-    case GICR_TYPER + 4:
-        *data = extract64(cs->gicr_typer, 32, 32);
-        return MEMTX_OK;
-    case GICR_STATUSR:
-        /* RAZ/WI for us (this is an optional register and our implementation
-         * does not track RO/WO/reserved violations to report them to the guest)
-         */
-        *data = 0;
-        return MEMTX_OK;
-    case GICR_WAKER:
-        *data = cs->gicr_waker;
-        return MEMTX_OK;
-    case GICR_PROPBASER:
-        *data = extract64(cs->gicr_propbaser, 0, 32);
-        return MEMTX_OK;
-    case GICR_PROPBASER + 4:
-        *data = extract64(cs->gicr_propbaser, 32, 32);
-        return MEMTX_OK;
-    case GICR_PENDBASER:
-        *data = extract64(cs->gicr_pendbaser, 0, 32);
-        return MEMTX_OK;
-    case GICR_PENDBASER + 4:
-        *data = extract64(cs->gicr_pendbaser, 32, 32);
-        return MEMTX_OK;
-    case GICR_IGROUPR0:
-        if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
-            *data = 0;
-            return MEMTX_OK;
-        }
-        *data = cs->gicr_igroupr0;
-        return MEMTX_OK;
-    case GICR_ISENABLER0:
-    case GICR_ICENABLER0:
-        *data = gicr_read_bitmap_reg(cs, attrs, cs->gicr_ienabler0);
-        return MEMTX_OK;
-    case GICR_ISPENDR0:
-    case GICR_ICPENDR0:
-    {
-        /* The pending register reads as the logical OR of the pending
-         * latch and the input line level for level-triggered interrupts.
-         */
-        uint32_t val = cs->gicr_ipendr0 | (~cs->edge_trigger & cs->level);
-        *data = gicr_read_bitmap_reg(cs, attrs, val);
-        return MEMTX_OK;
-    }
-    case GICR_ISACTIVER0:
-    case GICR_ICACTIVER0:
-        *data = gicr_read_bitmap_reg(cs, attrs, cs->gicr_iactiver0);
-        return MEMTX_OK;
-    case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f:
-    {
-        int i, irq = offset - GICR_IPRIORITYR;
-        uint32_t value = 0;
-
-        for (i = irq + 3; i >= irq; i--, value <<= 8) {
-            value |= gicr_read_ipriorityr(cs, attrs, i);
-        }
-        *data = value;
-        return MEMTX_OK;
-    }
-    case GICR_ICFGR0:
-    case GICR_ICFGR1:
-    {
-        /* Our edge_trigger bitmap is one bit per irq; take the correct
-         * half of it, and spread it out into the odd bits.
-         */
-        uint32_t value;
-
-        value = cs->edge_trigger & mask_group(cs, attrs);
-        value = extract32(value, (offset == GICR_ICFGR1) ? 16 : 0, 16);
-        value = half_shuffle32(value) << 1;
-        *data = value;
-        return MEMTX_OK;
-    }
-    case GICR_IGRPMODR0:
-        if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
-            /* RAZ/WI if security disabled, or if
-             * security enabled and this is an NS access
-             */
-            *data = 0;
-            return MEMTX_OK;
-        }
-        *data = cs->gicr_igrpmodr0;
-        return MEMTX_OK;
-    case GICR_NSACR:
-        if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
-            /* RAZ/WI if security disabled, or if
-             * security enabled and this is an NS access
-             */
-            *data = 0;
-            return MEMTX_OK;
-        }
-        *data = cs->gicr_nsacr;
-        return MEMTX_OK;
-    case GICR_IDREGS ... GICR_IDREGS + 0x1f:
-        *data = gicv3_idreg(offset - GICR_IDREGS);
-        return MEMTX_OK;
-    default:
-        return MEMTX_ERROR;
-    }
-}
-
-static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
-                               uint64_t value, MemTxAttrs attrs)
-{
-    switch (offset) {
-    case GICR_CTLR:
-        /* For our implementation, GICR_TYPER.DPGS is 0 and so all
-         * the DPG bits are RAZ/WI. We don't do anything asynchronously,
-         * so UWP and RWP are RAZ/WI. And GICR_TYPER.LPIS is 0 (we don't
-         * implement LPIs) so Enable_LPIs is RES0. So there are no writable
-         * bits for us.
-         */
-        return MEMTX_OK;
-    case GICR_STATUSR:
-        /* RAZ/WI for our implementation */
-        return MEMTX_OK;
-    case GICR_WAKER:
-        /* Only the ProcessorSleep bit is writeable. When the guest sets
-         * it it requests that we transition the channel between the
-         * redistributor and the cpu interface to quiescent, and that
-         * we set the ChildrenAsleep bit once the inteface has reached the
-         * quiescent state.
-         * Setting the ProcessorSleep to 0 reverses the quiescing, and
-         * ChildrenAsleep is cleared once the transition is complete.
-         * Since our interface is not asynchronous, we complete these
-         * transitions instantaneously, so we set ChildrenAsleep to the
-         * same value as ProcessorSleep here.
-         */
-        value &= GICR_WAKER_ProcessorSleep;
-        if (value & GICR_WAKER_ProcessorSleep) {
-            value |= GICR_WAKER_ChildrenAsleep;
-        }
-        cs->gicr_waker = value;
-        return MEMTX_OK;
-    case GICR_PROPBASER:
-        cs->gicr_propbaser = deposit64(cs->gicr_propbaser, 0, 32, value);
-        return MEMTX_OK;
-    case GICR_PROPBASER + 4:
-        cs->gicr_propbaser = deposit64(cs->gicr_propbaser, 32, 32, value);
-        return MEMTX_OK;
-    case GICR_PENDBASER:
-        cs->gicr_pendbaser = deposit64(cs->gicr_pendbaser, 0, 32, value);
-        return MEMTX_OK;
-    case GICR_PENDBASER + 4:
-        cs->gicr_pendbaser = deposit64(cs->gicr_pendbaser, 32, 32, value);
-        return MEMTX_OK;
-    case GICR_IGROUPR0:
-        if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
-            return MEMTX_OK;
-        }
-        cs->gicr_igroupr0 = value;
-        gicv3_redist_update(cs);
-        return MEMTX_OK;
-    case GICR_ISENABLER0:
-        gicr_write_set_bitmap_reg(cs, attrs, &cs->gicr_ienabler0, value);
-        return MEMTX_OK;
-    case GICR_ICENABLER0:
-        gicr_write_clear_bitmap_reg(cs, attrs, &cs->gicr_ienabler0, value);
-        return MEMTX_OK;
-    case GICR_ISPENDR0:
-        gicr_write_set_bitmap_reg(cs, attrs, &cs->gicr_ipendr0, value);
-        return MEMTX_OK;
-    case GICR_ICPENDR0:
-        gicr_write_clear_bitmap_reg(cs, attrs, &cs->gicr_ipendr0, value);
-        return MEMTX_OK;
-    case GICR_ISACTIVER0:
-        gicr_write_set_bitmap_reg(cs, attrs, &cs->gicr_iactiver0, value);
-        return MEMTX_OK;
-    case GICR_ICACTIVER0:
-        gicr_write_clear_bitmap_reg(cs, attrs, &cs->gicr_iactiver0, value);
-        return MEMTX_OK;
-    case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f:
-    {
-        int i, irq = offset - GICR_IPRIORITYR;
-
-        for (i = irq; i < irq + 4; i++, value >>= 8) {
-            gicr_write_ipriorityr(cs, attrs, i, value);
-        }
-        gicv3_redist_update(cs);
-        return MEMTX_OK;
-    }
-    case GICR_ICFGR0:
-        /* Register is all RAZ/WI or RAO/WI bits */
-        return MEMTX_OK;
-    case GICR_ICFGR1:
-    {
-        uint32_t mask;
-
-        /* Since our edge_trigger bitmap is one bit per irq, our input
-         * 32-bits will compress down into 16 bits which we need
-         * to write into the bitmap.
-         */
-        value = half_unshuffle32(value >> 1) << 16;
-        mask = mask_group(cs, attrs) & 0xffff0000U;
-
-        cs->edge_trigger &= ~mask;
-        cs->edge_trigger |= (value & mask);
-
-        gicv3_redist_update(cs);
-        return MEMTX_OK;
-    }
-    case GICR_IGRPMODR0:
-        if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
-            /* RAZ/WI if security disabled, or if
-             * security enabled and this is an NS access
-             */
-            return MEMTX_OK;
-        }
-        cs->gicr_igrpmodr0 = value;
-        gicv3_redist_update(cs);
-        return MEMTX_OK;
-    case GICR_NSACR:
-        if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
-            /* RAZ/WI if security disabled, or if
-             * security enabled and this is an NS access
-             */
-            return MEMTX_OK;
-        }
-        cs->gicr_nsacr = value;
-        /* no update required as this only affects access permission checks */
-        return MEMTX_OK;
-    case GICR_IIDR:
-    case GICR_TYPER:
-    case GICR_IDREGS ... GICR_IDREGS + 0x1f:
-        /* RO registers, ignore the write */
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: invalid guest write to RO register at offset "
-                      TARGET_FMT_plx "\n", __func__, offset);
-        return MEMTX_OK;
-    default:
-        return MEMTX_ERROR;
-    }
-}
-
-static MemTxResult gicr_readll(GICv3CPUState *cs, hwaddr offset,
-                               uint64_t *data, MemTxAttrs attrs)
-{
-    switch (offset) {
-    case GICR_TYPER:
-        *data = cs->gicr_typer;
-        return MEMTX_OK;
-    case GICR_PROPBASER:
-        *data = cs->gicr_propbaser;
-        return MEMTX_OK;
-    case GICR_PENDBASER:
-        *data = cs->gicr_pendbaser;
-        return MEMTX_OK;
-    default:
-        return MEMTX_ERROR;
-    }
-}
-
-static MemTxResult gicr_writell(GICv3CPUState *cs, hwaddr offset,
-                                uint64_t value, MemTxAttrs attrs)
-{
-    switch (offset) {
-    case GICR_PROPBASER:
-        cs->gicr_propbaser = value;
-        return MEMTX_OK;
-    case GICR_PENDBASER:
-        cs->gicr_pendbaser = value;
-        return MEMTX_OK;
-    case GICR_TYPER:
-        /* RO register, ignore the write */
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: invalid guest write to RO register at offset "
-                      TARGET_FMT_plx "\n", __func__, offset);
-        return MEMTX_OK;
-    default:
-        return MEMTX_ERROR;
-    }
-}
-
-MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
-                              unsigned size, MemTxAttrs attrs)
-{
-    GICv3State *s = opaque;
-    GICv3CPUState *cs;
-    MemTxResult r;
-    int cpuidx;
-
-    assert((offset & (size - 1)) == 0);
-
-    /* This region covers all the redistributor pages; there are
-     * (for GICv3) two 64K pages per CPU. At the moment they are
-     * all contiguous (ie in this one region), though we might later
-     * want to allow splitting of redistributor pages into several
-     * blocks so we can support more CPUs.
-     */
-    cpuidx = offset / 0x20000;
-    offset %= 0x20000;
-    assert(cpuidx < s->num_cpu);
-
-    cs = &s->cpu[cpuidx];
-
-    switch (size) {
-    case 1:
-        r = gicr_readb(cs, offset, data, attrs);
-        break;
-    case 4:
-        r = gicr_readl(cs, offset, data, attrs);
-        break;
-    case 8:
-        r = gicr_readll(cs, offset, data, attrs);
-        break;
-    default:
-        r = MEMTX_ERROR;
-        break;
-    }
-
-    if (r == MEMTX_ERROR) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: invalid guest read at offset " TARGET_FMT_plx
-                      "size %u\n", __func__, offset, size);
-        trace_gicv3_redist_badread(gicv3_redist_affid(cs), offset,
-                                   size, attrs.secure);
-    } else {
-        trace_gicv3_redist_read(gicv3_redist_affid(cs), offset, *data,
-                                size, attrs.secure);
-    }
-    return r;
-}
-
-MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
-                               unsigned size, MemTxAttrs attrs)
-{
-    GICv3State *s = opaque;
-    GICv3CPUState *cs;
-    MemTxResult r;
-    int cpuidx;
-
-    assert((offset & (size - 1)) == 0);
-
-    /* This region covers all the redistributor pages; there are
-     * (for GICv3) two 64K pages per CPU. At the moment they are
-     * all contiguous (ie in this one region), though we might later
-     * want to allow splitting of redistributor pages into several
-     * blocks so we can support more CPUs.
-     */
-    cpuidx = offset / 0x20000;
-    offset %= 0x20000;
-    assert(cpuidx < s->num_cpu);
-
-    cs = &s->cpu[cpuidx];
-
-    switch (size) {
-    case 1:
-        r = gicr_writeb(cs, offset, data, attrs);
-        break;
-    case 4:
-        r = gicr_writel(cs, offset, data, attrs);
-        break;
-    case 8:
-        r = gicr_writell(cs, offset, data, attrs);
-        break;
-    default:
-        r = MEMTX_ERROR;
-        break;
-    }
-
-    if (r == MEMTX_ERROR) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: invalid guest write at offset " TARGET_FMT_plx
-                      "size %u\n", __func__, offset, size);
-        trace_gicv3_redist_badwrite(gicv3_redist_affid(cs), offset, data,
-                                    size, attrs.secure);
-    } else {
-        trace_gicv3_redist_write(gicv3_redist_affid(cs), offset, data,
-                                 size, attrs.secure);
-    }
-    return r;
-}
-
-void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)
-{
-    /* Update redistributor state for a change in an external PPI input line */
-    if (level == extract32(cs->level, irq, 1)) {
-        return;
-    }
-
-    trace_gicv3_redist_set_irq(gicv3_redist_affid(cs), irq, level);
-
-    cs->level = deposit32(cs->level, irq, 1, level);
-
-    if (level) {
-        /* 0->1 edges latch the pending bit for edge-triggered interrupts */
-        if (extract32(cs->edge_trigger, irq, 1)) {
-            cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 1);
-        }
-    }
-
-    gicv3_redist_update(cs);
-}
-
-void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns)
-{
-    /* Update redistributor state for a generated SGI */
-    int irqgrp = gicv3_irq_group(cs->gic, cs, irq);
-
-    /* If we are asked for a Secure Group 1 SGI and it's actually
-     * configured as Secure Group 0 this is OK (subject to the usual
-     * NSACR checks).
-     */
-    if (grp == GICV3_G1 && irqgrp == GICV3_G0) {
-        grp = GICV3_G0;
-    }
-
-    if (grp != irqgrp) {
-        return;
-    }
-
-    if (ns && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
-        /* If security is enabled we must test the NSACR bits */
-        int nsaccess = gicr_ns_access(cs, irq);
-
-        if ((irqgrp == GICV3_G0 && nsaccess < 1) ||
-            (irqgrp == GICV3_G1 && nsaccess < 2)) {
-            return;
-        }
-    }
-
-    /* OK, we can accept the SGI */
-    trace_gicv3_redist_send_sgi(gicv3_redist_affid(cs), irq);
-    cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 1);
-    gicv3_redist_update(cs);
-}
index 06d8db6..669e82a 100644 (file)
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "hw/sysbus.h"
 #include "qemu/timer.h"
 #include "hw/arm/arm.h"
 #include "exec/address-spaces.h"
 #include "gic_internal.h"
-#include "qemu/log.h"
 
 typedef struct {
     GICState gic;
@@ -187,11 +185,11 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
     case 0x1c: /* SysTick Calibration Value.  */
         return 10000;
     case 0xd00: /* CPUID Base.  */
-        cpu = ARM_CPU(qemu_get_cpu(0));
+        cpu = ARM_CPU(current_cpu);
         return cpu->midr;
     case 0xd04: /* Interrupt Control State.  */
         /* VECTACTIVE */
-        cpu = ARM_CPU(qemu_get_cpu(0));
+        cpu = ARM_CPU(current_cpu);
         val = cpu->env.v7m.exception;
         if (val == 1023) {
             val = 0;
@@ -222,7 +220,7 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
             val |= (1 << 31);
         return val;
     case 0xd08: /* Vector Table Offset.  */
-        cpu = ARM_CPU(qemu_get_cpu(0));
+        cpu = ARM_CPU(current_cpu);
         return cpu->env.v7m.vecbase;
     case 0xd0c: /* Application Interrupt/Reset Control.  */
         return 0xfa050000;
@@ -349,7 +347,7 @@ static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)
         }
         break;
     case 0xd08: /* Vector Table Offset.  */
-        cpu = ARM_CPU(qemu_get_cpu(0));
+        cpu = ARM_CPU(current_cpu);
         cpu->env.v7m.vecbase = value & 0xffffff80;
         break;
     case 0xd0c: /* Application Interrupt/Reset Control.  */
index 2370e74..19a0ff7 100644 (file)
@@ -28,9 +28,9 @@
  */
 
 #include "qemu/osdep.h"
+#include <inttypes.h>
 #include "hw/intc/aspeed_vic.h"
 #include "qemu/bitops.h"
-#include "qemu/log.h"
 #include "trace.h"
 
 #define AVIC_NEW_BASE_OFFSET 0x80
index 00d2530..80513b2 100644 (file)
@@ -14,7 +14,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/intc/bcm2835_ic.h"
-#include "qemu/log.h"
 
 #define GPU_IRQS 64
 #define ARM_IRQS 8
index cfa5bc7..d027181 100644 (file)
@@ -15,7 +15,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/intc/bcm2836_control.h"
-#include "qemu/log.h"
 
 #define REG_GPU_ROUTE           0x0c
 #define REG_TIMERCONTROL        0x40
index 64a6f4b..48f9477 100644 (file)
@@ -146,19 +146,19 @@ static void irq_handler(void *opaque, int irq, int level)
     pic_update(fs);
 }
 
-static void etraxfs_pic_init(Object *obj)
+static int etraxfs_pic_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    struct etrax_pic *s = ETRAX_FS_PIC(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    struct etrax_pic *s = ETRAX_FS_PIC(dev);
 
     qdev_init_gpio_in(dev, irq_handler, 32);
     sysbus_init_irq(sbd, &s->parent_irq);
     sysbus_init_irq(sbd, &s->parent_nmi);
 
-    memory_region_init_io(&s->mmio, obj, &pic_ops, s,
+    memory_region_init_io(&s->mmio, OBJECT(s), &pic_ops, s,
                           "etraxfs-pic", R_MAX * 4);
     sysbus_init_mmio(sbd, &s->mmio);
+    return 0;
 }
 
 static Property etraxfs_pic_properties[] = {
@@ -169,7 +169,9 @@ static Property etraxfs_pic_properties[] = {
 static void etraxfs_pic_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = etraxfs_pic_init;
     dc->props = etraxfs_pic_properties;
     /*
      * Note: pointer property "interrupt_vector" may remain null, thus
@@ -181,7 +183,6 @@ static const TypeInfo etraxfs_pic_info = {
     .name          = TYPE_ETRAX_FS_PIC,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(struct etrax_pic),
-    .instance_init = etraxfs_pic_init,
     .class_init    = etraxfs_pic_class_init,
 };
 
index f19a706..dc0c903 100644 (file)
@@ -406,11 +406,10 @@ static const MemoryRegionOps exynos4210_combiner_ops = {
 /*
  * Internal Combiner initialization.
  */
-static void exynos4210_combiner_init(Object *obj)
+static int exynos4210_combiner_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    Exynos4210CombinerState *s = EXYNOS4210_COMBINER(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    Exynos4210CombinerState *s = EXYNOS4210_COMBINER(dev);
     unsigned int i;
 
     /* Allocate general purpose input signals and connect a handler to each of
@@ -422,9 +421,11 @@ static void exynos4210_combiner_init(Object *obj)
         sysbus_init_irq(sbd, &s->output_irq[i]);
     }
 
-    memory_region_init_io(&s->iomem, obj, &exynos4210_combiner_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &exynos4210_combiner_ops, s,
                           "exynos4210-combiner", IIC_REGION_SIZE);
     sysbus_init_mmio(sbd, &s->iomem);
+
+    return 0;
 }
 
 static Property exynos4210_combiner_properties[] = {
@@ -435,7 +436,9 @@ static Property exynos4210_combiner_properties[] = {
 static void exynos4210_combiner_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = exynos4210_combiner_init;
     dc->reset = exynos4210_combiner_reset;
     dc->props = exynos4210_combiner_properties;
     dc->vmsd = &vmstate_exynos4210_combiner;
@@ -445,7 +448,6 @@ static const TypeInfo exynos4210_combiner_info = {
     .name          = TYPE_EXYNOS4210_COMBINER,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(Exynos4210CombinerState),
-    .instance_init = exynos4210_combiner_init,
     .class_init    = exynos4210_combiner_class_init,
 };
 
index fd7a8f3..4f7e89f 100644 (file)
@@ -281,11 +281,10 @@ static void exynos4210_gic_set_irq(void *opaque, int irq, int level)
     qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
 }
 
-static void exynos4210_gic_init(Object *obj)
+static int exynos4210_gic_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    Exynos4210GicState *s = EXYNOS4210_GIC(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    Exynos4210GicState *s = EXYNOS4210_GIC(dev);
     uint32_t i;
     const char cpu_prefix[] = "exynos4210-gic-alias_cpu";
     const char dist_prefix[] = "exynos4210-gic-alias_dist";
@@ -306,15 +305,15 @@ static void exynos4210_gic_init(Object *obj)
     qdev_init_gpio_in(dev, exynos4210_gic_set_irq,
                       EXYNOS4210_GIC_NIRQ - 32);
 
-    memory_region_init(&s->cpu_container, obj, "exynos4210-cpu-container",
+    memory_region_init(&s->cpu_container, OBJECT(s), "exynos4210-cpu-container",
             EXYNOS4210_EXT_GIC_CPU_REGION_SIZE);
-    memory_region_init(&s->dist_container, obj, "exynos4210-dist-container",
+    memory_region_init(&s->dist_container, OBJECT(s), "exynos4210-dist-container",
             EXYNOS4210_EXT_GIC_DIST_REGION_SIZE);
 
     for (i = 0; i < s->num_cpu; i++) {
         /* Map CPU interface per SMP Core */
         sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
-        memory_region_init_alias(&s->cpu_alias[i], obj,
+        memory_region_init_alias(&s->cpu_alias[i], OBJECT(s),
                                  cpu_alias_name,
                                  sysbus_mmio_get_region(busdev, 1),
                                  0,
@@ -324,7 +323,7 @@ static void exynos4210_gic_init(Object *obj)
 
         /* Map Distributor per SMP Core */
         sprintf(dist_alias_name, "%s%x", dist_prefix, i);
-        memory_region_init_alias(&s->dist_alias[i], obj,
+        memory_region_init_alias(&s->dist_alias[i], OBJECT(s),
                                  dist_alias_name,
                                  sysbus_mmio_get_region(busdev, 0),
                                  0,
@@ -335,6 +334,8 @@ static void exynos4210_gic_init(Object *obj)
 
     sysbus_init_mmio(sbd, &s->cpu_container);
     sysbus_init_mmio(sbd, &s->dist_container);
+
+    return 0;
 }
 
 static Property exynos4210_gic_properties[] = {
@@ -345,7 +346,9 @@ static Property exynos4210_gic_properties[] = {
 static void exynos4210_gic_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = exynos4210_gic_init;
     dc->props = exynos4210_gic_properties;
 }
 
@@ -353,7 +356,6 @@ static const TypeInfo exynos4210_gic_info = {
     .name          = TYPE_EXYNOS4210_GIC,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(Exynos4210GicState),
-    .instance_init = exynos4210_gic_init,
     .class_init    = exynos4210_gic_class_init,
 };
 
@@ -428,16 +430,9 @@ static void exynos4210_irq_gate_reset(DeviceState *d)
 /*
  * IRQ Gate initialization.
  */
-static void exynos4210_irq_gate_init(Object *obj)
-{
-    Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
-
-    sysbus_init_irq(sbd, &s->out);
-}
-
-static void exynos4210_irq_gate_realize(DeviceState *dev, Error **errp)
+static int exynos4210_irq_gate_init(SysBusDevice *sbd)
 {
+    DeviceState *dev = DEVICE(sbd);
     Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(dev);
 
     /* Allocate general purpose input signals and connect a handler to each of
@@ -445,23 +440,27 @@ static void exynos4210_irq_gate_realize(DeviceState *dev, Error **errp)
     qdev_init_gpio_in(dev, exynos4210_irq_gate_handler, s->n_in);
 
     s->level = g_malloc0(s->n_in * sizeof(*s->level));
+
+    sysbus_init_irq(sbd, &s->out);
+
+    return 0;
 }
 
 static void exynos4210_irq_gate_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = exynos4210_irq_gate_init;
     dc->reset = exynos4210_irq_gate_reset;
     dc->vmsd = &vmstate_exynos4210_irq_gate;
     dc->props = exynos4210_irq_gate_properties;
-    dc->realize = exynos4210_irq_gate_realize;
 }
 
 static const TypeInfo exynos4210_irq_gate_info = {
     .name          = TYPE_EXYNOS4210_IRQ_GATE,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(Exynos4210IRQGateState),
-    .instance_init = exynos4210_irq_gate_init,
     .class_init    = exynos4210_irq_gate_class_init,
 };
 
index 3f31174..20c1e8a 100644 (file)
@@ -100,4 +100,4 @@ static inline bool gic_test_pending(GICState *s, int irq, int cm)
     }
 }
 
-#endif /* QEMU_ARM_GIC_INTERNAL_H */
+#endif /* !QEMU_ARM_GIC_INTERNAL_H */
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
deleted file mode 100644 (file)
index 8f3567e..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * ARM GICv3 support - internal interfaces
- *
- * Copyright (c) 2012 Linaro Limited
- * Copyright (c) 2015 Huawei.
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- * Written by Peter Maydell
- * Reworked for GICv3 by Shlomo Pongratz and Pavel Fedin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef QEMU_ARM_GICV3_INTERNAL_H
-#define QEMU_ARM_GICV3_INTERNAL_H
-
-#include "hw/intc/arm_gicv3_common.h"
-
-/* Distributor registers, as offsets from the distributor base address */
-#define GICD_CTLR            0x0000
-#define GICD_TYPER           0x0004
-#define GICD_IIDR            0x0008
-#define GICD_STATUSR         0x0010
-#define GICD_SETSPI_NSR      0x0040
-#define GICD_CLRSPI_NSR      0x0048
-#define GICD_SETSPI_SR       0x0050
-#define GICD_CLRSPI_SR       0x0058
-#define GICD_SEIR            0x0068
-#define GICD_IGROUPR         0x0080
-#define GICD_ISENABLER       0x0100
-#define GICD_ICENABLER       0x0180
-#define GICD_ISPENDR         0x0200
-#define GICD_ICPENDR         0x0280
-#define GICD_ISACTIVER       0x0300
-#define GICD_ICACTIVER       0x0380
-#define GICD_IPRIORITYR      0x0400
-#define GICD_ITARGETSR       0x0800
-#define GICD_ICFGR           0x0C00
-#define GICD_IGRPMODR        0x0D00
-#define GICD_NSACR           0x0E00
-#define GICD_SGIR            0x0F00
-#define GICD_CPENDSGIR       0x0F10
-#define GICD_SPENDSGIR       0x0F20
-#define GICD_IROUTER         0x6000
-#define GICD_IDREGS          0xFFD0
-
-/* GICD_CTLR fields  */
-#define GICD_CTLR_EN_GRP0           (1U << 0)
-#define GICD_CTLR_EN_GRP1NS         (1U << 1) /* GICv3 5.3.20 */
-#define GICD_CTLR_EN_GRP1S          (1U << 2)
-#define GICD_CTLR_EN_GRP1_ALL       (GICD_CTLR_EN_GRP1NS | GICD_CTLR_EN_GRP1S)
-/* Bit 4 is ARE if the system doesn't support TrustZone, ARE_S otherwise */
-#define GICD_CTLR_ARE               (1U << 4)
-#define GICD_CTLR_ARE_S             (1U << 4)
-#define GICD_CTLR_ARE_NS            (1U << 5)
-#define GICD_CTLR_DS                (1U << 6)
-#define GICD_CTLR_E1NWF             (1U << 7)
-#define GICD_CTLR_RWP               (1U << 31)
-
-/*
- * Redistributor frame offsets from RD_base
- */
-#define GICR_SGI_OFFSET 0x10000
-
-/*
- * Redistributor registers, offsets from RD_base
- */
-#define GICR_CTLR             0x0000
-#define GICR_IIDR             0x0004
-#define GICR_TYPER            0x0008
-#define GICR_STATUSR          0x0010
-#define GICR_WAKER            0x0014
-#define GICR_SETLPIR          0x0040
-#define GICR_CLRLPIR          0x0048
-#define GICR_PROPBASER        0x0070
-#define GICR_PENDBASER        0x0078
-#define GICR_INVLPIR          0x00A0
-#define GICR_INVALLR          0x00B0
-#define GICR_SYNCR            0x00C0
-#define GICR_IDREGS           0xFFD0
-
-/* SGI and PPI Redistributor registers, offsets from RD_base */
-#define GICR_IGROUPR0         (GICR_SGI_OFFSET + 0x0080)
-#define GICR_ISENABLER0       (GICR_SGI_OFFSET + 0x0100)
-#define GICR_ICENABLER0       (GICR_SGI_OFFSET + 0x0180)
-#define GICR_ISPENDR0         (GICR_SGI_OFFSET + 0x0200)
-#define GICR_ICPENDR0         (GICR_SGI_OFFSET + 0x0280)
-#define GICR_ISACTIVER0       (GICR_SGI_OFFSET + 0x0300)
-#define GICR_ICACTIVER0       (GICR_SGI_OFFSET + 0x0380)
-#define GICR_IPRIORITYR       (GICR_SGI_OFFSET + 0x0400)
-#define GICR_ICFGR0           (GICR_SGI_OFFSET + 0x0C00)
-#define GICR_ICFGR1           (GICR_SGI_OFFSET + 0x0C04)
-#define GICR_IGRPMODR0        (GICR_SGI_OFFSET + 0x0D00)
-#define GICR_NSACR            (GICR_SGI_OFFSET + 0x0E00)
-
-#define GICR_CTLR_ENABLE_LPIS        (1U << 0)
-#define GICR_CTLR_RWP                (1U << 3)
-#define GICR_CTLR_DPG0               (1U << 24)
-#define GICR_CTLR_DPG1NS             (1U << 25)
-#define GICR_CTLR_DPG1S              (1U << 26)
-#define GICR_CTLR_UWP                (1U << 31)
-
-#define GICR_TYPER_PLPIS             (1U << 0)
-#define GICR_TYPER_VLPIS             (1U << 1)
-#define GICR_TYPER_DIRECTLPI         (1U << 3)
-#define GICR_TYPER_LAST              (1U << 4)
-#define GICR_TYPER_DPGS              (1U << 5)
-#define GICR_TYPER_PROCNUM           (0xFFFFU << 8)
-#define GICR_TYPER_COMMONLPIAFF      (0x3 << 24)
-#define GICR_TYPER_AFFINITYVALUE     (0xFFFFFFFFULL << 32)
-
-#define GICR_WAKER_ProcessorSleep    (1U << 1)
-#define GICR_WAKER_ChildrenAsleep    (1U << 2)
-
-#define GICR_PROPBASER_OUTER_CACHEABILITY_MASK (7ULL << 56)
-#define GICR_PROPBASER_ADDR_MASK               (0xfffffffffULL << 12)
-#define GICR_PROPBASER_SHAREABILITY_MASK       (3U << 10)
-#define GICR_PROPBASER_CACHEABILITY_MASK       (7U << 7)
-#define GICR_PROPBASER_IDBITS_MASK             (0x1f)
-
-#define GICR_PENDBASER_PTZ                     (1ULL << 62)
-#define GICR_PENDBASER_OUTER_CACHEABILITY_MASK (7ULL << 56)
-#define GICR_PENDBASER_ADDR_MASK               (0xffffffffULL << 16)
-#define GICR_PENDBASER_SHAREABILITY_MASK       (3U << 10)
-#define GICR_PENDBASER_CACHEABILITY_MASK       (7U << 7)
-
-#define ICC_CTLR_EL1_CBPR           (1U << 0)
-#define ICC_CTLR_EL1_EOIMODE        (1U << 1)
-#define ICC_CTLR_EL1_PMHE           (1U << 6)
-#define ICC_CTLR_EL1_PRIBITS_SHIFT 8
-#define ICC_CTLR_EL1_IDBITS_SHIFT 11
-#define ICC_CTLR_EL1_SEIS           (1U << 14)
-#define ICC_CTLR_EL1_A3V            (1U << 15)
-
-#define ICC_PMR_PRIORITY_MASK    0xff
-#define ICC_BPR_BINARYPOINT_MASK 0x07
-#define ICC_IGRPEN_ENABLE        0x01
-
-#define ICC_CTLR_EL3_CBPR_EL1S (1U << 0)
-#define ICC_CTLR_EL3_CBPR_EL1NS (1U << 1)
-#define ICC_CTLR_EL3_EOIMODE_EL3 (1U << 2)
-#define ICC_CTLR_EL3_EOIMODE_EL1S (1U << 3)
-#define ICC_CTLR_EL3_EOIMODE_EL1NS (1U << 4)
-#define ICC_CTLR_EL3_RM (1U << 5)
-#define ICC_CTLR_EL3_PMHE (1U << 6)
-#define ICC_CTLR_EL3_PRIBITS_SHIFT 8
-#define ICC_CTLR_EL3_IDBITS_SHIFT 11
-#define ICC_CTLR_EL3_SEIS (1U << 14)
-#define ICC_CTLR_EL3_A3V (1U << 15)
-#define ICC_CTLR_EL3_NDS (1U << 17)
-
-/* Special interrupt IDs */
-#define INTID_SECURE 1020
-#define INTID_NONSECURE 1021
-#define INTID_SPURIOUS 1023
-
-/* Functions internal to the emulated GICv3 */
-
-/**
- * gicv3_redist_update:
- * @cs: GICv3CPUState for this redistributor
- *
- * Recalculate the highest priority pending interrupt after a
- * change to redistributor state, and inform the CPU accordingly.
- */
-void gicv3_redist_update(GICv3CPUState *cs);
-
-/**
- * gicv3_update:
- * @s: GICv3State
- * @start: first interrupt whose state changed
- * @len: length of the range of interrupts whose state changed
- *
- * Recalculate the highest priority pending interrupts after a
- * change to the distributor state affecting @len interrupts
- * starting at @start, and inform the CPUs accordingly.
- */
-void gicv3_update(GICv3State *s, int start, int len);
-
-/**
- * gicv3_full_update_noirqset:
- * @s: GICv3State
- *
- * Recalculate the cached information about highest priority
- * pending interrupts, but don't inform the CPUs. This should be
- * called after an incoming migration has loaded new state.
- */
-void gicv3_full_update_noirqset(GICv3State *s);
-
-/**
- * gicv3_full_update:
- * @s: GICv3State
- *
- * Recalculate the highest priority pending interrupts after
- * a change that could affect the status of all interrupts,
- * and inform the CPUs accordingly.
- */
-void gicv3_full_update(GICv3State *s);
-MemTxResult gicv3_dist_read(void *opaque, hwaddr offset, uint64_t *data,
-                            unsigned size, MemTxAttrs attrs);
-MemTxResult gicv3_dist_write(void *opaque, hwaddr addr, uint64_t data,
-                             unsigned size, MemTxAttrs attrs);
-MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
-                              unsigned size, MemTxAttrs attrs);
-MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
-                               unsigned size, MemTxAttrs attrs);
-void gicv3_dist_set_irq(GICv3State *s, int irq, int level);
-void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level);
-void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
-void gicv3_init_cpuif(GICv3State *s);
-
-/**
- * gicv3_cpuif_update:
- * @cs: GICv3CPUState for the CPU to update
- *
- * Recalculate whether to assert the IRQ or FIQ lines after a change
- * to the current highest priority pending interrupt, the CPU's
- * current running priority or the CPU's current exception level or
- * security state.
- */
-void gicv3_cpuif_update(GICv3CPUState *cs);
-
-static inline uint32_t gicv3_iidr(void)
-{
-    /* Return the Implementer Identification Register value
-     * for the emulated GICv3, as reported in GICD_IIDR and GICR_IIDR.
-     *
-     * We claim to be an ARM r0p0 with a zero ProductID.
-     * This is the same as an r0p0 GIC-500.
-     */
-    return 0x43b;
-}
-
-static inline uint32_t gicv3_idreg(int regoffset)
-{
-    /* Return the value of the CoreSight ID register at the specified
-     * offset from the first ID register (as found in the distributor
-     * and redistributor register banks).
-     * These values indicate an ARM implementation of a GICv3.
-     */
-    static const uint8_t gicd_ids[] = {
-        0x44, 0x00, 0x00, 0x00, 0x92, 0xB4, 0x3B, 0x00, 0x0D, 0xF0, 0x05, 0xB1
-    };
-    return gicd_ids[regoffset / 4];
-}
-
-/**
- * gicv3_irq_group:
- *
- * Return the group which this interrupt is configured as (GICV3_G0,
- * GICV3_G1 or GICV3_G1NS).
- */
-static inline int gicv3_irq_group(GICv3State *s, GICv3CPUState *cs, int irq)
-{
-    bool grpbit, grpmodbit;
-
-    if (irq < GIC_INTERNAL) {
-        grpbit = extract32(cs->gicr_igroupr0, irq, 1);
-        grpmodbit = extract32(cs->gicr_igrpmodr0, irq, 1);
-    } else {
-        grpbit = gicv3_gicd_group_test(s, irq);
-        grpmodbit = gicv3_gicd_grpmod_test(s, irq);
-    }
-    if (grpbit) {
-        return GICV3_G1NS;
-    }
-    if (s->gicd_ctlr & GICD_CTLR_DS) {
-        return GICV3_G0;
-    }
-    return grpmodbit ? GICV3_G1 : GICV3_G0;
-}
-
-/**
- * gicv3_redist_affid:
- *
- * Return the 32-bit affinity ID of the CPU connected to this redistributor
- */
-static inline uint32_t gicv3_redist_affid(GICv3CPUState *cs)
-{
-    return cs->gicr_typer >> 32;
-}
-
-/**
- * gicv3_cache_target_cpustate:
- *
- * Update the cached CPU state corresponding to the target for this interrupt
- * (which is kept in s->gicd_irouter_target[]).
- */
-static inline void gicv3_cache_target_cpustate(GICv3State *s, int irq)
-{
-    GICv3CPUState *cs = NULL;
-    int i;
-    uint32_t tgtaff = extract64(s->gicd_irouter[irq], 0, 24) |
-        extract64(s->gicd_irouter[irq], 32, 8) << 24;
-
-    for (i = 0; i < s->num_cpu; i++) {
-        if (s->cpu[i].gicr_typer >> 32 == tgtaff) {
-            cs = &s->cpu[i];
-            break;
-        }
-    }
-
-    s->gicd_irouter_target[irq] = cs;
-}
-
-/**
- * gicv3_cache_all_target_cpustates:
- *
- * Populate the entire cache of CPU state pointers for interrupt targets
- * (eg after inbound migration or CPU reset)
- */
-static inline void gicv3_cache_all_target_cpustates(GICv3State *s)
-{
-    int irq;
-
-    for (irq = GIC_INTERNAL; irq < GICV3_MAXIRQ; irq++) {
-        gicv3_cache_target_cpustate(s, irq);
-    }
-}
-
-#endif /* QEMU_ARM_GICV3_INTERNAL_H */
index ac7e63f..f5ca8f7 100644 (file)
@@ -31,7 +31,6 @@
 #include "hw/sparc/grlib.h"
 
 #include "trace.h"
-#include "qapi/error.h"
 
 #define IRQMP_MAX_CPU 16
 #define IRQMP_REG_SIZE 256      /* Size of memory mapped registers */
@@ -324,27 +323,23 @@ static void grlib_irqmp_reset(DeviceState *d)
     irqmp->state->parent = irqmp;
 }
 
-static void grlib_irqmp_init(Object *obj)
+static int grlib_irqmp_init(SysBusDevice *dev)
 {
-    IRQMP *irqmp = GRLIB_IRQMP(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    IRQMP *irqmp = GRLIB_IRQMP(dev);
+
+    /* Check parameters */
+    if (irqmp->set_pil_in == NULL) {
+        return -1;
+    }
 
-    memory_region_init_io(&irqmp->iomem, obj, &grlib_irqmp_ops, irqmp,
+    memory_region_init_io(&irqmp->iomem, OBJECT(dev), &grlib_irqmp_ops, irqmp,
                           "irqmp", IRQMP_REG_SIZE);
 
     irqmp->state = g_malloc0(sizeof *irqmp->state);
 
     sysbus_init_mmio(dev, &irqmp->iomem);
-}
 
-static void grlib_irqmp_realize(DeviceState *dev, Error **errp)
-{
-    IRQMP *irqmp = GRLIB_IRQMP(dev);
-
-        /* Check parameters */
-    if (irqmp->set_pil_in == NULL) {
-        error_setg(errp, "set_pil_in cannot be NULL.");
-    }
+    return 0;
 }
 
 static Property grlib_irqmp_properties[] = {
@@ -356,19 +351,19 @@ static Property grlib_irqmp_properties[] = {
 static void grlib_irqmp_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = grlib_irqmp_init;
     dc->reset = grlib_irqmp_reset;
     dc->props = grlib_irqmp_properties;
     /* Reason: pointer properties "set_pil_in", "set_pil_in_opaque" */
     dc->cannot_instantiate_with_device_add_yet = true;
-    dc->realize = grlib_irqmp_realize;
 }
 
 static const TypeInfo grlib_irqmp_info = {
     .name          = TYPE_GRLIB_IRQMP,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(IRQMP),
-    .instance_init = grlib_irqmp_init,
     .class_init    = grlib_irqmp_class_init,
 };
 
index c2607a5..bb43669 100644 (file)
@@ -27,7 +27,6 @@
 #include "hw/isa/isa.h"
 #include "monitor/monitor.h"
 #include "qemu/timer.h"
-#include "qemu/log.h"
 #include "hw/isa/i8259_internal.h"
 
 /* debug PIC */
index 813e587..7027655 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/intc/imx_avic.h"
-#include "qemu/log.h"
 
 #ifndef DEBUG_IMX_AVIC
 #define DEBUG_IMX_AVIC 0
@@ -322,26 +321,28 @@ static void imx_avic_reset(DeviceState *dev)
     memset(s->prio, 0, sizeof s->prio);
 }
 
-static void imx_avic_init(Object *obj)
+static int imx_avic_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    IMXAVICState *s = IMX_AVIC(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    IMXAVICState *s = IMX_AVIC(dev);
 
-    memory_region_init_io(&s->iomem, obj, &imx_avic_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &imx_avic_ops, s,
                           TYPE_IMX_AVIC, 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
 
     qdev_init_gpio_in(dev, imx_avic_set_irq, IMX_AVIC_NUM_IRQS);
     sysbus_init_irq(sbd, &s->irq);
     sysbus_init_irq(sbd, &s->fiq);
+
+    return 0;
 }
 
 
 static void imx_avic_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+    k->init = imx_avic_init;
     dc->vmsd = &vmstate_imx_avic;
     dc->reset = imx_avic_reset;
     dc->desc = "i.MX Advanced Vector Interrupt Controller";
@@ -351,7 +352,6 @@ static const TypeInfo imx_avic_info = {
     .name = TYPE_IMX_AVIC,
     .parent = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(IMXAVICState),
-    .instance_init = imx_avic_init,
     .class_init = imx_avic_class_init,
 };
 
index 31791b0..378e663 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "qemu/error-report.h"
 #include "monitor/monitor.h"
 #include "hw/hw.h"
 #include "hw/i386/pc.h"
-#include "hw/i386/apic.h"
 #include "hw/i386/ioapic.h"
 #include "hw/i386/ioapic_internal.h"
 #include "include/hw/pci/msi.h"
 #include "sysemu/kvm.h"
-#include "target-i386/cpu.h"
-#include "hw/i386/apic-msidef.h"
-#include "hw/i386/x86-iommu.h"
 
 //#define DEBUG_IOAPIC
 
@@ -52,56 +47,16 @@ static IOAPICCommonState *ioapics[MAX_IOAPICS];
 /* global variable from ioapic_common.c */
 extern int ioapic_no;
 
-struct ioapic_entry_info {
-    /* fields parsed from IOAPIC entries */
-    uint8_t masked;
-    uint8_t trig_mode;
-    uint16_t dest_idx;
-    uint8_t dest_mode;
-    uint8_t delivery_mode;
-    uint8_t vector;
-
-    /* MSI message generated from above parsed fields */
-    uint32_t addr;
-    uint32_t data;
-};
-
-static void ioapic_entry_parse(uint64_t entry, struct ioapic_entry_info *info)
-{
-    memset(info, 0, sizeof(*info));
-    info->masked = (entry >> IOAPIC_LVT_MASKED_SHIFT) & 1;
-    info->trig_mode = (entry >> IOAPIC_LVT_TRIGGER_MODE_SHIFT) & 1;
-    /*
-     * By default, this would be dest_id[8] + reserved[8]. When IR
-     * is enabled, this would be interrupt_index[15] +
-     * interrupt_format[1]. This field never means anything, but
-     * only used to generate corresponding MSI.
-     */
-    info->dest_idx = (entry >> IOAPIC_LVT_DEST_IDX_SHIFT) & 0xffff;
-    info->dest_mode = (entry >> IOAPIC_LVT_DEST_MODE_SHIFT) & 1;
-    info->delivery_mode = (entry >> IOAPIC_LVT_DELIV_MODE_SHIFT) \
-        & IOAPIC_DM_MASK;
-    if (info->delivery_mode == IOAPIC_DM_EXTINT) {
-        info->vector = pic_read_irq(isa_pic);
-    } else {
-        info->vector = entry & IOAPIC_VECTOR_MASK;
-    }
-
-    info->addr = APIC_DEFAULT_ADDRESS | \
-        (info->dest_idx << MSI_ADDR_DEST_IDX_SHIFT) | \
-        (info->dest_mode << MSI_ADDR_DEST_MODE_SHIFT);
-    info->data = (info->vector << MSI_DATA_VECTOR_SHIFT) | \
-        (info->trig_mode << MSI_DATA_TRIGGER_SHIFT) | \
-        (info->delivery_mode << MSI_DATA_DELIVERY_MODE_SHIFT);
-}
-
 static void ioapic_service(IOAPICCommonState *s)
 {
-    AddressSpace *ioapic_as = PC_MACHINE(qdev_get_machine())->ioapic_as;
-    struct ioapic_entry_info info;
     uint8_t i;
+    uint8_t trig_mode;
+    uint8_t vector;
+    uint8_t delivery_mode;
     uint32_t mask;
     uint64_t entry;
+    uint8_t dest;
+    uint8_t dest_mode;
 
     for (i = 0; i < IOAPIC_NUM_PINS; i++) {
         mask = 1 << i;
@@ -109,39 +64,40 @@ static void ioapic_service(IOAPICCommonState *s)
             int coalesce = 0;
 
             entry = s->ioredtbl[i];
-            ioapic_entry_parse(entry, &info);
-            if (!info.masked) {
-                if (info.trig_mode == IOAPIC_TRIGGER_EDGE) {
+            if (!(entry & IOAPIC_LVT_MASKED)) {
+                trig_mode = ((entry >> IOAPIC_LVT_TRIGGER_MODE_SHIFT) & 1);
+                dest = entry >> IOAPIC_LVT_DEST_SHIFT;
+                dest_mode = (entry >> IOAPIC_LVT_DEST_MODE_SHIFT) & 1;
+                delivery_mode =
+                    (entry >> IOAPIC_LVT_DELIV_MODE_SHIFT) & IOAPIC_DM_MASK;
+                if (trig_mode == IOAPIC_TRIGGER_EDGE) {
                     s->irr &= ~mask;
                 } else {
                     coalesce = s->ioredtbl[i] & IOAPIC_LVT_REMOTE_IRR;
                     s->ioredtbl[i] |= IOAPIC_LVT_REMOTE_IRR;
                 }
-
-                if (coalesce) {
-                    /* We are level triggered interrupts, and the
-                     * guest should be still working on previous one,
-                     * so skip it. */
-                    continue;
+                if (delivery_mode == IOAPIC_DM_EXTINT) {
+                    vector = pic_read_irq(isa_pic);
+                } else {
+                    vector = entry & IOAPIC_VECTOR_MASK;
                 }
-
 #ifdef CONFIG_KVM
                 if (kvm_irqchip_is_split()) {
-                    if (info.trig_mode == IOAPIC_TRIGGER_EDGE) {
+                    if (trig_mode == IOAPIC_TRIGGER_EDGE) {
                         kvm_set_irq(kvm_state, i, 1);
                         kvm_set_irq(kvm_state, i, 0);
                     } else {
-                        kvm_set_irq(kvm_state, i, 1);
+                        if (!coalesce) {
+                            kvm_set_irq(kvm_state, i, 1);
+                        }
                     }
                     continue;
                 }
+#else
+                (void)coalesce;
 #endif
-
-                /* No matter whether IR is enabled, we translate
-                 * the IOAPIC message into a MSI one, and its
-                 * address space will decide whether we need a
-                 * translation. */
-                stl_le_phys(ioapic_as, info.addr, info.data);
+                apic_deliver_irq(dest, dest_mode, delivery_mode, vector,
+                                 trig_mode);
             }
         }
     }
@@ -192,11 +148,30 @@ static void ioapic_update_kvm_routes(IOAPICCommonState *s)
 
     if (kvm_irqchip_is_split()) {
         for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+            uint64_t entry = s->ioredtbl[i];
+            uint8_t trig_mode;
+            uint8_t delivery_mode;
+            uint8_t dest;
+            uint8_t dest_mode;
+            uint64_t pin_polarity;
             MSIMessage msg;
-            struct ioapic_entry_info info;
-            ioapic_entry_parse(s->ioredtbl[i], &info);
-            msg.address = info.addr;
-            msg.data = info.data;
+
+            trig_mode = ((entry >> IOAPIC_LVT_TRIGGER_MODE_SHIFT) & 1);
+            dest = entry >> IOAPIC_LVT_DEST_SHIFT;
+            dest_mode = (entry >> IOAPIC_LVT_DEST_MODE_SHIFT) & 1;
+            pin_polarity = (entry >> IOAPIC_LVT_TRIGGER_MODE_SHIFT) & 1;
+            delivery_mode =
+                (entry >> IOAPIC_LVT_DELIV_MODE_SHIFT) & IOAPIC_DM_MASK;
+
+            msg.address = APIC_DEFAULT_ADDRESS;
+            msg.address |= dest_mode << 2;
+            msg.address |= dest << 12;
+
+            msg.data = entry & IOAPIC_VECTOR_MASK;
+            msg.data |= delivery_mode << APIC_DELIVERY_MODE_SHIFT;
+            msg.data |= pin_polarity << APIC_POLARITY_SHIFT;
+            msg.data |= trig_mode << APIC_TRIG_MODE_SHIFT;
+
             kvm_irqchip_update_msi_route(kvm_state, i, msg, NULL);
         }
         kvm_irqchip_commit_routes(kvm_state);
@@ -204,16 +179,6 @@ static void ioapic_update_kvm_routes(IOAPICCommonState *s)
 #endif
 }
 
-#ifdef CONFIG_KVM
-static void ioapic_iec_notifier(void *private, bool global,
-                                uint32_t index, uint32_t mask)
-{
-    IOAPICCommonState *s = (IOAPICCommonState *)private;
-    /* For simplicity, we just update all the routes */
-    ioapic_update_kvm_routes(s);
-}
-#endif
-
 void ioapic_eoi_broadcast(int vector)
 {
     IOAPICCommonState *s;
@@ -270,7 +235,7 @@ ioapic_mem_read(void *opaque, hwaddr addr, unsigned int size)
             val = s->id << IOAPIC_ID_SHIFT;
             break;
         case IOAPIC_REG_VER:
-            val = s->version |
+            val = IOAPIC_VERSION |
                 ((IOAPIC_NUM_PINS - 1) << IOAPIC_VER_ENTRIES_SHIFT);
             break;
         default:
@@ -289,34 +254,6 @@ ioapic_mem_read(void *opaque, hwaddr addr, unsigned int size)
     return val;
 }
 
-/*
- * This is to satisfy the hack in Linux kernel. One hack of it is to
- * simulate clearing the Remote IRR bit of IOAPIC entry using the
- * following:
- *
- * "For IO-APIC's with EOI register, we use that to do an explicit EOI.
- * Otherwise, we simulate the EOI message manually by changing the trigger
- * mode to edge and then back to level, with RTE being masked during
- * this."
- *
- * (See linux kernel __eoi_ioapic_pin() comment in commit c0205701)
- *
- * This is based on the assumption that, Remote IRR bit will be
- * cleared by IOAPIC hardware when configured as edge-triggered
- * interrupts.
- *
- * Without this, level-triggered interrupts in IR mode might fail to
- * work correctly.
- */
-static inline void
-ioapic_fix_edge_remote_irr(uint64_t *entry)
-{
-    if (!(*entry & IOAPIC_LVT_TRIGGER_MODE)) {
-        /* Edge-triggered interrupts, make sure remote IRR is zero */
-        *entry &= ~((uint64_t)IOAPIC_LVT_REMOTE_IRR);
-    }
-}
-
 static void
 ioapic_mem_write(void *opaque, hwaddr addr, uint64_t val,
                  unsigned int size)
@@ -343,7 +280,6 @@ ioapic_mem_write(void *opaque, hwaddr addr, uint64_t val,
         default:
             index = (s->ioregsel - IOAPIC_REG_REDTBL_BASE) >> 1;
             if (index >= 0 && index < IOAPIC_NUM_PINS) {
-                uint64_t ro_bits = s->ioredtbl[index] & IOAPIC_RO_BITS;
                 if (s->ioregsel & 1) {
                     s->ioredtbl[index] &= 0xffffffff;
                     s->ioredtbl[index] |= (uint64_t)val << 32;
@@ -351,21 +287,10 @@ ioapic_mem_write(void *opaque, hwaddr addr, uint64_t val,
                     s->ioredtbl[index] &= ~0xffffffffULL;
                     s->ioredtbl[index] |= val;
                 }
-                /* restore RO bits */
-                s->ioredtbl[index] &= IOAPIC_RW_BITS;
-                s->ioredtbl[index] |= ro_bits;
-                ioapic_fix_edge_remote_irr(&s->ioredtbl[index]);
                 ioapic_service(s);
             }
         }
         break;
-    case IOAPIC_EOI:
-        /* Explicit EOI is only supported for IOAPIC version 0x20 */
-        if (size != 4 || s->version != 0x20) {
-            break;
-        }
-        ioapic_eoi_broadcast(val);
-        break;
     }
 
     ioapic_update_kvm_routes(s);
@@ -377,49 +302,18 @@ static const MemoryRegionOps ioapic_io_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void ioapic_machine_done_notify(Notifier *notifier, void *data)
-{
-#ifdef CONFIG_KVM
-    IOAPICCommonState *s = container_of(notifier, IOAPICCommonState,
-                                        machine_done);
-
-    if (kvm_irqchip_is_split()) {
-        X86IOMMUState *iommu = x86_iommu_get_default();
-        if (iommu) {
-            /* Register this IOAPIC with IOMMU IEC notifier, so that
-             * when there are IR invalidates, we can be notified to
-             * update kernel IR cache. */
-            x86_iommu_iec_register_notifier(iommu, ioapic_iec_notifier, s);
-        }
-    }
-#endif
-}
-
 static void ioapic_realize(DeviceState *dev, Error **errp)
 {
     IOAPICCommonState *s = IOAPIC_COMMON(dev);
 
-    if (s->version != 0x11 && s->version != 0x20) {
-        error_report("IOAPIC only supports version 0x11 or 0x20 "
-                     "(default: 0x11).");
-        exit(1);
-    }
-
     memory_region_init_io(&s->io_memory, OBJECT(s), &ioapic_io_ops, s,
                           "ioapic", 0x1000);
 
     qdev_init_gpio_in(dev, ioapic_set_irq, IOAPIC_NUM_PINS);
 
     ioapics[ioapic_no] = s;
-    s->machine_done.notify = ioapic_machine_done_notify;
-    qemu_add_machine_init_done_notifier(&s->machine_done);
 }
 
-static Property ioapic_properties[] = {
-    DEFINE_PROP_UINT8("version", IOAPICCommonState, version, 0x11),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 static void ioapic_class_init(ObjectClass *klass, void *data)
 {
     IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
@@ -427,7 +321,6 @@ static void ioapic_class_init(ObjectClass *klass, void *data)
 
     k->realize = ioapic_realize;
     dc->reset = ioapic_reset_common;
-    dc->props = ioapic_properties;
 }
 
 static const TypeInfo ioapic_info = {
index 3dad01c..edc08f1 100644 (file)
@@ -152,16 +152,17 @@ static void pic_reset(DeviceState *d)
     }
 }
 
-static void lm32_pic_init(Object *obj)
+static int lm32_pic_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    LM32PicState *s = LM32_PIC(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    LM32PicState *s = LM32_PIC(dev);
 
     qdev_init_gpio_in(dev, irq_handler, 32);
     sysbus_init_irq(sbd, &s->parent_irq);
 
     pic = s;
+
+    return 0;
 }
 
 static const VMStateDescription vmstate_lm32_pic = {
@@ -180,7 +181,9 @@ static const VMStateDescription vmstate_lm32_pic = {
 static void lm32_pic_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = lm32_pic_init;
     dc->reset = pic_reset;
     dc->vmsd = &vmstate_lm32_pic;
 }
@@ -189,7 +192,6 @@ static const TypeInfo lm32_pic_info = {
     .name          = TYPE_LM32_PIC,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(LM32PicState),
-    .instance_init = lm32_pic_init,
     .class_init    = lm32_pic_class_init,
 };
 
diff --git a/hw/intc/mips_gic.c b/hw/intc/mips_gic.c
deleted file mode 100644 (file)
index 6e25773..0000000
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
- * Authors: Sanjay Lal <sanjayl@kymasys.com>
- *
- * Copyright (C) 2016 Imagination Technologies
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "qapi/error.h"
-#include "hw/hw.h"
-#include "hw/sysbus.h"
-#include "exec/memory.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/kvm.h"
-#include "kvm_mips.h"
-#include "hw/intc/mips_gic.h"
-
-static void mips_gic_set_vp_irq(MIPSGICState *gic, int vp, int pin, int level)
-{
-    int ored_level = level;
-    int i;
-
-    /* ORing pending registers sharing same pin */
-    if (!ored_level) {
-        for (i = 0; i < gic->num_irq; i++) {
-            if ((gic->irq_state[i].map_pin & GIC_MAP_MSK) == pin &&
-                    gic->irq_state[i].map_vp == vp &&
-                    gic->irq_state[i].enabled) {
-                ored_level |= gic->irq_state[i].pending;
-            }
-            if (ored_level) {
-                /* no need to iterate all interrupts */
-                break;
-            }
-        }
-        if (((gic->vps[vp].compare_map & GIC_MAP_MSK) == pin) &&
-                (gic->vps[vp].mask & GIC_VP_MASK_CMP_MSK)) {
-            /* ORing with local pending register (count/compare) */
-            ored_level |= (gic->vps[vp].pend & GIC_VP_MASK_CMP_MSK) >>
-                          GIC_VP_MASK_CMP_SHF;
-        }
-    }
-    if (kvm_enabled())  {
-        kvm_mips_set_ipi_interrupt(mips_env_get_cpu(gic->vps[vp].env),
-                                   pin + GIC_CPU_PIN_OFFSET,
-                                   ored_level);
-    } else {
-        qemu_set_irq(gic->vps[vp].env->irq[pin + GIC_CPU_PIN_OFFSET],
-                     ored_level);
-    }
-}
-
-static void gic_set_irq(void *opaque, int n_IRQ, int level)
-{
-    MIPSGICState *gic = (MIPSGICState *) opaque;
-    int vp = gic->irq_state[n_IRQ].map_vp;
-    int pin = gic->irq_state[n_IRQ].map_pin & GIC_MAP_MSK;
-
-    gic->irq_state[n_IRQ].pending = (uint8_t) level;
-    if (!gic->irq_state[n_IRQ].enabled) {
-        /* GIC interrupt source disabled */
-        return;
-    }
-    if (vp < 0 || vp >= gic->num_vps) {
-        return;
-    }
-    mips_gic_set_vp_irq(gic, vp, pin, level);
-}
-
-#define OFFSET_CHECK(c)                         \
-    do {                                        \
-        if (!(c)) {                             \
-            goto bad_offset;                    \
-        }                                       \
-    } while (0)
-
-/* GIC Read VP Local/Other Registers */
-static uint64_t gic_read_vp(MIPSGICState *gic, uint32_t vp_index, hwaddr addr,
-                            unsigned size)
-{
-    switch (addr) {
-    case GIC_VP_CTL_OFS:
-        return gic->vps[vp_index].ctl;
-    case GIC_VP_PEND_OFS:
-        mips_gictimer_get_sh_count(gic->gic_timer);
-        return gic->vps[vp_index].pend;
-    case GIC_VP_MASK_OFS:
-        return gic->vps[vp_index].mask;
-    case GIC_VP_COMPARE_MAP_OFS:
-        return gic->vps[vp_index].compare_map;
-    case GIC_VP_OTHER_ADDR_OFS:
-        return gic->vps[vp_index].other_addr;
-    case GIC_VP_IDENT_OFS:
-        return vp_index;
-    case GIC_VP_COMPARE_LO_OFS:
-        return mips_gictimer_get_vp_compare(gic->gic_timer, vp_index);
-    case GIC_VP_COMPARE_HI_OFS:
-        return 0;
-    default:
-        qemu_log_mask(LOG_UNIMP, "Read %d bytes at GIC offset LOCAL/OTHER 0x%"
-                      PRIx64 "\n", size, addr);
-        break;
-    }
-    return 0;
-}
-
-static uint64_t gic_read(void *opaque, hwaddr addr, unsigned size)
-{
-    MIPSGICState *gic = (MIPSGICState *) opaque;
-    uint32_t vp_index = current_cpu->cpu_index;
-    uint64_t ret = 0;
-    int i, base, irq_src;
-    uint32_t other_index;
-
-    switch (addr) {
-    case GIC_SH_CONFIG_OFS:
-        ret = gic->sh_config | (mips_gictimer_get_countstop(gic->gic_timer) <<
-                               GIC_SH_CONFIG_COUNTSTOP_SHF);
-        break;
-    case GIC_SH_COUNTERLO_OFS:
-        ret = mips_gictimer_get_sh_count(gic->gic_timer);
-        break;
-    case GIC_SH_COUNTERHI_OFS:
-        ret = 0;
-        break;
-    case GIC_SH_PEND_OFS ... GIC_SH_PEND_LAST_OFS:
-        /* each bit represents pending status for an interrupt pin */
-        base = (addr - GIC_SH_PEND_OFS) * 8;
-        OFFSET_CHECK((base + size * 8) <= gic->num_irq);
-        for (i = 0; i < size * 8; i++) {
-            ret |= (uint64_t) (gic->irq_state[base + i].pending) << i;
-        }
-        break;
-    case GIC_SH_MASK_OFS ... GIC_SH_MASK_LAST_OFS:
-        /* each bit represents status for an interrupt pin */
-        base = (addr - GIC_SH_MASK_OFS) * 8;
-        OFFSET_CHECK((base + size * 8) <= gic->num_irq);
-        for (i = 0; i < size * 8; i++) {
-            ret |= (uint64_t) (gic->irq_state[base + i].enabled) << i;
-        }
-        break;
-    case GIC_SH_MAP0_PIN_OFS ... GIC_SH_MAP255_PIN_OFS:
-        /* 32 bits per a pin */
-        irq_src = (addr - GIC_SH_MAP0_PIN_OFS) / 4;
-        OFFSET_CHECK(irq_src < gic->num_irq);
-        ret = gic->irq_state[irq_src].map_pin;
-        break;
-    case GIC_SH_MAP0_VP_OFS ... GIC_SH_MAP255_VP_LAST_OFS:
-        /* up to 32 bytes per a pin */
-        irq_src = (addr - GIC_SH_MAP0_VP_OFS) / 32;
-        OFFSET_CHECK(irq_src < gic->num_irq);
-        if ((gic->irq_state[irq_src].map_vp) >= 0) {
-            ret = (uint64_t) 1 << (gic->irq_state[irq_src].map_vp);
-        } else {
-            ret = 0;
-        }
-        break;
-    /* VP-Local Register */
-    case VP_LOCAL_SECTION_OFS ... (VP_LOCAL_SECTION_OFS + GIC_VL_BRK_GROUP):
-        ret = gic_read_vp(gic, vp_index, addr - VP_LOCAL_SECTION_OFS, size);
-        break;
-    /* VP-Other Register */
-    case VP_OTHER_SECTION_OFS ... (VP_OTHER_SECTION_OFS + GIC_VL_BRK_GROUP):
-        other_index = gic->vps[vp_index].other_addr;
-        ret = gic_read_vp(gic, other_index, addr - VP_OTHER_SECTION_OFS, size);
-        break;
-    /* User-Mode Visible section */
-    case USM_VISIBLE_SECTION_OFS + GIC_USER_MODE_COUNTERLO:
-        ret = mips_gictimer_get_sh_count(gic->gic_timer);
-        break;
-    case USM_VISIBLE_SECTION_OFS + GIC_USER_MODE_COUNTERHI:
-        ret = 0;
-        break;
-    default:
-        qemu_log_mask(LOG_UNIMP, "Read %d bytes at GIC offset 0x%" PRIx64 "\n",
-                      size, addr);
-        break;
-    }
-    return ret;
-bad_offset:
-    qemu_log_mask(LOG_GUEST_ERROR, "Wrong GIC offset at 0x%" PRIx64 "\n", addr);
-    return 0;
-}
-
-static void gic_timer_expire_cb(void *opaque, uint32_t vp_index)
-{
-    MIPSGICState *gic = opaque;
-
-    gic->vps[vp_index].pend |= (1 << GIC_LOCAL_INT_COMPARE);
-    if (gic->vps[vp_index].pend &
-            (gic->vps[vp_index].mask & GIC_VP_MASK_CMP_MSK)) {
-        if (gic->vps[vp_index].compare_map & GIC_MAP_TO_PIN_MSK) {
-            /* it is safe to set the irq high regardless of other GIC IRQs */
-            uint32_t pin = (gic->vps[vp_index].compare_map & GIC_MAP_MSK);
-            qemu_irq_raise(gic->vps[vp_index].env->irq
-                           [pin + GIC_CPU_PIN_OFFSET]);
-        }
-    }
-}
-
-static void gic_timer_store_vp_compare(MIPSGICState *gic, uint32_t vp_index,
-                                       uint64_t compare)
-{
-    gic->vps[vp_index].pend &= ~(1 << GIC_LOCAL_INT_COMPARE);
-    if (gic->vps[vp_index].compare_map & GIC_MAP_TO_PIN_MSK) {
-        uint32_t pin = (gic->vps[vp_index].compare_map & GIC_MAP_MSK);
-        mips_gic_set_vp_irq(gic, vp_index, pin, 0);
-    }
-    mips_gictimer_store_vp_compare(gic->gic_timer, vp_index, compare);
-}
-
-/* GIC Write VP Local/Other Registers */
-static void gic_write_vp(MIPSGICState *gic, uint32_t vp_index, hwaddr addr,
-                              uint64_t data, unsigned size)
-{
-    switch (addr) {
-    case GIC_VP_CTL_OFS:
-        /* EIC isn't supported */
-        break;
-    case GIC_VP_RMASK_OFS:
-        gic->vps[vp_index].mask &= ~(data & GIC_VP_SET_RESET_MSK) &
-                                   GIC_VP_SET_RESET_MSK;
-        break;
-    case GIC_VP_SMASK_OFS:
-        gic->vps[vp_index].mask |= data & GIC_VP_SET_RESET_MSK;
-        break;
-    case GIC_VP_COMPARE_MAP_OFS:
-        /* EIC isn't supported */
-        OFFSET_CHECK((data & GIC_MAP_MSK) <= GIC_CPU_INT_MAX);
-        gic->vps[vp_index].compare_map = data & GIC_MAP_TO_PIN_REG_MSK;
-        break;
-    case GIC_VP_OTHER_ADDR_OFS:
-        OFFSET_CHECK(data < gic->num_vps);
-        gic->vps[vp_index].other_addr = data;
-        break;
-    case GIC_VP_COMPARE_LO_OFS:
-        gic_timer_store_vp_compare(gic, vp_index, data);
-        break;
-    default:
-        qemu_log_mask(LOG_UNIMP, "Write %d bytes at GIC offset LOCAL/OTHER "
-                      "0x%" PRIx64" 0x%08" PRIx64 "\n", size, addr, data);
-        break;
-    }
-    return;
-bad_offset:
-    qemu_log_mask(LOG_GUEST_ERROR, "Wrong GIC offset at 0x%" PRIx64 "\n", addr);
-    return;
-}
-
-static void gic_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
-{
-    int intr;
-    MIPSGICState *gic = (MIPSGICState *) opaque;
-    uint32_t vp_index = current_cpu->cpu_index;
-    int i, base, irq_src;
-    uint32_t other_index;
-
-    switch (addr) {
-    case GIC_SH_CONFIG_OFS:
-        {
-            uint32_t pre_cntstop = mips_gictimer_get_countstop(gic->gic_timer);
-            uint32_t new_cntstop = (data & GIC_SH_CONFIG_COUNTSTOP_MSK) >>
-                                   GIC_SH_CONFIG_COUNTSTOP_SHF;
-            if (pre_cntstop != new_cntstop) {
-                if (new_cntstop == 1) {
-                    mips_gictimer_stop_count(gic->gic_timer);
-                } else {
-                    mips_gictimer_start_count(gic->gic_timer);
-                }
-            }
-        }
-        break;
-    case GIC_SH_COUNTERLO_OFS:
-        if (mips_gictimer_get_countstop(gic->gic_timer)) {
-            mips_gictimer_store_sh_count(gic->gic_timer, data);
-        }
-        break;
-    case GIC_SH_RMASK_OFS ... GIC_SH_RMASK_LAST_OFS:
-        /* up to 64 bits per a pin */
-        base = (addr - GIC_SH_RMASK_OFS) * 8;
-        OFFSET_CHECK((base + size * 8) <= gic->num_irq);
-        for (i = 0; i < size * 8; i++) {
-            gic->irq_state[base + i].enabled &= !((data >> i) & 1);
-        }
-        break;
-    case GIC_SH_WEDGE_OFS:
-        /* Figure out which VP/HW Interrupt this maps to */
-        intr = data & ~GIC_SH_WEDGE_RW_MSK;
-        /* Mask/Enabled Checks */
-        OFFSET_CHECK(intr < gic->num_irq);
-        if (data & GIC_SH_WEDGE_RW_MSK) {
-            gic_set_irq(gic, intr, 1);
-        } else {
-            gic_set_irq(gic, intr, 0);
-        }
-        break;
-    case GIC_SH_SMASK_OFS ... GIC_SH_SMASK_LAST_OFS:
-        /* up to 64 bits per a pin */
-        base = (addr - GIC_SH_SMASK_OFS) * 8;
-        OFFSET_CHECK((base + size * 8) <= gic->num_irq);
-        for (i = 0; i < size * 8; i++) {
-            gic->irq_state[base + i].enabled |= (data >> i) & 1;
-        }
-        break;
-    case GIC_SH_MAP0_PIN_OFS ... GIC_SH_MAP255_PIN_OFS:
-        /* 32 bits per a pin */
-        irq_src = (addr - GIC_SH_MAP0_PIN_OFS) / 4;
-        OFFSET_CHECK(irq_src < gic->num_irq);
-        /* EIC isn't supported */
-        OFFSET_CHECK((data & GIC_MAP_MSK) <= GIC_CPU_INT_MAX);
-        gic->irq_state[irq_src].map_pin = data & GIC_MAP_TO_PIN_REG_MSK;
-        break;
-    case GIC_SH_MAP0_VP_OFS ... GIC_SH_MAP255_VP_LAST_OFS:
-        /* up to 32 bytes per a pin */
-        irq_src = (addr - GIC_SH_MAP0_VP_OFS) / 32;
-        OFFSET_CHECK(irq_src < gic->num_irq);
-        data = data ? ctz64(data) : -1;
-        OFFSET_CHECK(data < gic->num_vps);
-        gic->irq_state[irq_src].map_vp = data;
-        break;
-    case VP_LOCAL_SECTION_OFS ... (VP_LOCAL_SECTION_OFS + GIC_VL_BRK_GROUP):
-        gic_write_vp(gic, vp_index, addr - VP_LOCAL_SECTION_OFS, data, size);
-        break;
-    case VP_OTHER_SECTION_OFS ... (VP_OTHER_SECTION_OFS + GIC_VL_BRK_GROUP):
-        other_index = gic->vps[vp_index].other_addr;
-        gic_write_vp(gic, other_index, addr - VP_OTHER_SECTION_OFS, data, size);
-        break;
-    case USM_VISIBLE_SECTION_OFS + GIC_USER_MODE_COUNTERLO:
-    case USM_VISIBLE_SECTION_OFS + GIC_USER_MODE_COUNTERHI:
-        /* do nothing. Read-only section */
-        break;
-    default:
-        qemu_log_mask(LOG_UNIMP, "Write %d bytes at GIC offset 0x%" PRIx64
-                      " 0x%08" PRIx64 "\n", size, addr, data);
-        break;
-    }
-    return;
-bad_offset:
-    qemu_log_mask(LOG_GUEST_ERROR, "Wrong GIC offset at 0x%" PRIx64 "\n", addr);
-}
-
-static void gic_reset(void *opaque)
-{
-    int i;
-    MIPSGICState *gic = (MIPSGICState *) opaque;
-    int numintrs = (gic->num_irq / 8) - 1;
-
-    gic->sh_config = /* COUNTSTOP = 0 it is accessible via MIPSGICTimer*/
-                     /* CounterHi not implemented */
-                     (0            << GIC_SH_CONFIG_COUNTBITS_SHF) |
-                     (numintrs     << GIC_SH_CONFIG_NUMINTRS_SHF)  |
-                     (gic->num_vps << GIC_SH_CONFIG_PVPS_SHF);
-    for (i = 0; i < gic->num_vps; i++) {
-        gic->vps[i].ctl         = 0x0;
-        gic->vps[i].pend        = 0x0;
-        /* PERFCNT, TIMER and WD not implemented */
-        gic->vps[i].mask        = 0x32;
-        gic->vps[i].compare_map = GIC_MAP_TO_PIN_MSK;
-        mips_gictimer_store_vp_compare(gic->gic_timer, i, 0xffffffff);
-        gic->vps[i].other_addr  = 0x0;
-    }
-    for (i = 0; i < gic->num_irq; i++) {
-        gic->irq_state[i].enabled = 0;
-        gic->irq_state[i].pending = 0;
-        gic->irq_state[i].map_pin = GIC_MAP_TO_PIN_MSK;
-        gic->irq_state[i].map_vp  = -1;
-    }
-    mips_gictimer_store_sh_count(gic->gic_timer, 0);
-    /* COUNTSTOP = 0 */
-    mips_gictimer_start_count(gic->gic_timer);
-}
-
-static const MemoryRegionOps gic_ops = {
-    .read = gic_read,
-    .write = gic_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .impl = {
-        .max_access_size = 8,
-    },
-};
-
-static void mips_gic_init(Object *obj)
-{
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
-    MIPSGICState *s = MIPS_GIC(obj);
-
-    memory_region_init_io(&s->mr, OBJECT(s), &gic_ops, s,
-                          "mips-gic", GIC_ADDRSPACE_SZ);
-    sysbus_init_mmio(sbd, &s->mr);
-    qemu_register_reset(gic_reset, s);
-}
-
-static void mips_gic_realize(DeviceState *dev, Error **errp)
-{
-    MIPSGICState *s = MIPS_GIC(dev);
-    CPUState *cs = first_cpu;
-    int i;
-
-    if (s->num_vps > GIC_MAX_VPS) {
-        error_setg(errp, "Exceeded maximum CPUs %d", s->num_vps);
-        return;
-    }
-    if ((s->num_irq > GIC_MAX_INTRS) || (s->num_irq % 8) || (s->num_irq <= 0)) {
-        error_setg(errp, "GIC supports up to %d external interrupts in "
-                   "multiples of 8 : %d", GIC_MAX_INTRS, s->num_irq);
-        return;
-    }
-    s->vps = g_new(MIPSGICVPState, s->num_vps);
-    s->irq_state = g_new(MIPSGICIRQState, s->num_irq);
-    /* Register the env for all VPs with the GIC */
-    for (i = 0; i < s->num_vps; i++) {
-        if (cs != NULL) {
-            s->vps[i].env = cs->env_ptr;
-            cs = CPU_NEXT(cs);
-        } else {
-            error_setg(errp,
-               "Unable to initialize GIC, CPUState for CPU#%d not valid.", i);
-            return;
-        }
-    }
-    s->gic_timer = mips_gictimer_init(s, s->num_vps, gic_timer_expire_cb);
-    qdev_init_gpio_in(dev, gic_set_irq, s->num_irq);
-    for (i = 0; i < s->num_irq; i++) {
-        s->irq_state[i].irq = qdev_get_gpio_in(dev, i);
-    }
-}
-
-static Property mips_gic_properties[] = {
-    DEFINE_PROP_INT32("num-vp", MIPSGICState, num_vps, 1),
-    DEFINE_PROP_INT32("num-irq", MIPSGICState, num_irq, 256),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void mips_gic_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-
-    dc->props = mips_gic_properties;
-    dc->realize = mips_gic_realize;
-}
-
-static const TypeInfo mips_gic_info = {
-    .name          = TYPE_MIPS_GIC,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(MIPSGICState),
-    .instance_init = mips_gic_init,
-    .class_init    = mips_gic_class_init,
-};
-
-static void mips_gic_register_types(void)
-{
-    type_register_static(&mips_gic_info);
-}
-
-type_init(mips_gic_register_types)
index 877be67..3368825 100644 (file)
@@ -22,7 +22,6 @@
 #include "hw/arm/omap.h"
 #include "hw/sysbus.h"
 #include "qemu/error-report.h"
-#include "qapi/error.h"
 
 /* Interrupt Handlers */
 struct omap_intr_handler_bank_s {
@@ -364,28 +363,23 @@ static void omap_inth_reset(DeviceState *dev)
     qemu_set_irq(s->parent_intr[1], 0);
 }
 
-static void omap_intc_init(Object *obj)
+static int omap_intc_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    struct omap_intr_handler_s *s = OMAP_INTC(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    struct omap_intr_handler_s *s = OMAP_INTC(dev);
 
+    if (!s->iclk) {
+        error_report("omap-intc: clk not connected");
+        return -1;
+    }
     s->nbanks = 1;
     sysbus_init_irq(sbd, &s->parent_intr[0]);
     sysbus_init_irq(sbd, &s->parent_intr[1]);
     qdev_init_gpio_in(dev, omap_set_intr, s->nbanks * 32);
-    memory_region_init_io(&s->mmio, obj, &omap_inth_mem_ops, s,
+    memory_region_init_io(&s->mmio, OBJECT(s), &omap_inth_mem_ops, s,
                           "omap-intc", s->size);
     sysbus_init_mmio(sbd, &s->mmio);
-}
-
-static void omap_intc_realize(DeviceState *dev, Error **errp)
-{
-    struct omap_intr_handler_s *s = OMAP_INTC(dev);
-
-    if (!s->iclk) {
-        error_setg(errp, "omap-intc: clk not connected");
-    }
+    return 0;
 }
 
 static Property omap_intc_properties[] = {
@@ -397,18 +391,18 @@ static Property omap_intc_properties[] = {
 static void omap_intc_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = omap_intc_init;
     dc->reset = omap_inth_reset;
     dc->props = omap_intc_properties;
     /* Reason: pointer property "clk" */
     dc->cannot_instantiate_with_device_add_yet = true;
-    dc->realize = omap_intc_realize;
 }
 
 static const TypeInfo omap_intc_info = {
     .name          = "omap-intc",
     .parent        = TYPE_OMAP_INTC,
-    .instance_init = omap_intc_init,
     .class_init    = omap_intc_class_init,
 };
 
@@ -611,34 +605,28 @@ static const MemoryRegionOps omap2_inth_mem_ops = {
     },
 };
 
-static void omap2_intc_init(Object *obj)
+static int omap2_intc_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    struct omap_intr_handler_s *s = OMAP_INTC(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    struct omap_intr_handler_s *s = OMAP_INTC(dev);
 
+    if (!s->iclk) {
+        error_report("omap2-intc: iclk not connected");
+        return -1;
+    }
+    if (!s->fclk) {
+        error_report("omap2-intc: fclk not connected");
+        return -1;
+    }
     s->level_only = 1;
     s->nbanks = 3;
     sysbus_init_irq(sbd, &s->parent_intr[0]);
     sysbus_init_irq(sbd, &s->parent_intr[1]);
     qdev_init_gpio_in(dev, omap_set_intr_noedge, s->nbanks * 32);
-    memory_region_init_io(&s->mmio, obj, &omap2_inth_mem_ops, s,
+    memory_region_init_io(&s->mmio, OBJECT(s), &omap2_inth_mem_ops, s,
                           "omap2-intc", 0x1000);
     sysbus_init_mmio(sbd, &s->mmio);
-}
-
-static void omap2_intc_realize(DeviceState *dev, Error **errp)
-{
-    struct omap_intr_handler_s *s = OMAP_INTC(dev);
-
-    if (!s->iclk) {
-        error_setg(errp, "omap2-intc: iclk not connected");
-        return;
-    }
-    if (!s->fclk) {
-        error_setg(errp, "omap2-intc: fclk not connected");
-        return;
-    }
+    return 0;
 }
 
 static Property omap2_intc_properties[] = {
@@ -652,18 +640,18 @@ static Property omap2_intc_properties[] = {
 static void omap2_intc_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = omap2_intc_init;
     dc->reset = omap_inth_reset;
     dc->props = omap2_intc_properties;
     /* Reason: pointer property "iclk", "fclk" */
     dc->cannot_instantiate_with_device_add_yet = true;
-    dc->realize = omap2_intc_realize;
 }
 
 static const TypeInfo omap2_intc_info = {
     .name          = "omap2-intc",
     .parent        = TYPE_OMAP_INTC,
-    .instance_init = omap2_intc_init,
     .class_init    = omap2_intc_class_init,
 };
 
index 4349e45..2d37693 100644 (file)
@@ -44,7 +44,6 @@
 #include "qapi/error.h"
 #include "qemu/bitops.h"
 #include "qapi/qmp/qerror.h"
-#include "qemu/log.h"
 
 //#define DEBUG_OPENPIC
 
index 0518e01..e47e94f 100644 (file)
@@ -24,8 +24,6 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include <sys/ioctl.h>
 #include "exec/address-spaces.h"
 #include "hw/hw.h"
index 55ea15d..5ecbc4a 100644 (file)
@@ -9,7 +9,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
-#include "qemu/log.h"
 
 /* The number of virtual priority levels.  16 user vectors plus the
    unvectored IRQ.  Chained interrupts would require an additional level
@@ -237,17 +236,17 @@ static void pl190_reset(DeviceState *d)
     pl190_update_vectors(s);
 }
 
-static void pl190_init(Object *obj)
+static int pl190_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    PL190State *s = PL190(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    PL190State *s = PL190(dev);
 
-    memory_region_init_io(&s->iomem, obj, &pl190_ops, s, "pl190", 0x1000);
+    memory_region_init_io(&s->iomem, OBJECT(s), &pl190_ops, s, "pl190", 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
     qdev_init_gpio_in(dev, pl190_set_irq, 32);
     sysbus_init_irq(sbd, &s->irq);
     sysbus_init_irq(sbd, &s->fiq);
+    return 0;
 }
 
 static const VMStateDescription vmstate_pl190 = {
@@ -272,7 +271,9 @@ static const VMStateDescription vmstate_pl190 = {
 static void pl190_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = pl190_init;
     dc->reset = pl190_reset;
     dc->vmsd = &vmstate_pl190;
 }
@@ -281,7 +282,6 @@ static const TypeInfo pl190_info = {
     .name          = TYPE_PL190,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(PL190State),
-    .instance_init = pl190_init,
     .class_init    = pl190_class_init,
 };
 
index 6ab29ef..bc75fa7 100644 (file)
@@ -67,13 +67,6 @@ static void qemu_s390_release_adapter_routes(S390FLICState *fs,
 {
 }
 
-static int qemu_s390_clear_io_flic(S390FLICState *fs, uint16_t subchannel_id,
-                           uint16_t subchannel_nr)
-{
-    /* Fixme TCG */
-    return -ENOSYS;
-}
-
 static void qemu_s390_flic_class_init(ObjectClass *oc, void *data)
 {
     S390FLICStateClass *fsc = S390_FLIC_COMMON_CLASS(oc);
@@ -82,7 +75,6 @@ static void qemu_s390_flic_class_init(ObjectClass *oc, void *data)
     fsc->io_adapter_map = qemu_s390_io_adapter_map;
     fsc->add_adapter_routes = qemu_s390_add_adapter_routes;
     fsc->release_adapter_routes = qemu_s390_release_adapter_routes;
-    fsc->clear_io_irq = qemu_s390_clear_io_flic;
 }
 
 static const TypeInfo qemu_s390_flic_info = {
index fef8080..02449b3 100644 (file)
@@ -11,8 +11,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include <sys/ioctl.h>
 #include "qemu/error-report.h"
 #include "hw/sysbus.h"
@@ -30,7 +28,6 @@ typedef struct KVMS390FLICState {
     S390FLICState parent_obj;
 
     uint32_t fd;
-    bool clear_io_supported;
 } KVMS390FLICState;
 
 DeviceState *s390_flic_kvm_create(void)
@@ -131,24 +128,6 @@ int kvm_s390_inject_flic(struct kvm_s390_irq *irq)
     return flic_enqueue_irqs(irq, sizeof(*irq), flic);
 }
 
-static int kvm_s390_clear_io_flic(S390FLICState *fs, uint16_t subchannel_id,
-                           uint16_t subchannel_nr)
-{
-    KVMS390FLICState *flic = KVM_S390_FLIC(fs);
-    int rc;
-    uint32_t sid = subchannel_id << 16 | subchannel_nr;
-    struct kvm_device_attr attr = {
-        .group = KVM_DEV_FLIC_CLEAR_IO_IRQ,
-        .addr = (uint64_t) &sid,
-        .attr = sizeof(sid),
-    };
-    if (unlikely(!flic->clear_io_supported)) {
-        return -ENOSYS;
-    }
-    rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
-    return rc ? -errno : 0;
-}
-
 /**
  * __get_all_irqs - store all pending irqs in buffer
  * @flic: pointer to flic device state
@@ -195,7 +174,7 @@ static int kvm_s390_register_io_adapter(S390FLICState *fs, uint32_t id,
         .swap = swap,
     };
     KVMS390FLICState *flic = KVM_S390_FLIC(fs);
-    int r;
+    int r, ret;
     struct kvm_device_attr attr = {
         .group = KVM_DEV_FLIC_ADAPTER_REGISTER,
         .addr = (uint64_t)&adapter,
@@ -208,7 +187,8 @@ static int kvm_s390_register_io_adapter(S390FLICState *fs, uint32_t id,
 
     r = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
 
-    return r ? -errno : 0;
+    ret = r ? -errno : 0;
+    return ret;
 }
 
 static int kvm_s390_io_adapter_map(S390FLICState *fs, uint32_t id,
@@ -376,7 +356,6 @@ static void kvm_s390_flic_realize(DeviceState *dev, Error **errp)
 {
     KVMS390FLICState *flic_state = KVM_S390_FLIC(dev);
     struct kvm_create_device cd = {0};
-    struct kvm_device_attr test_attr = {0};
     int ret;
 
     flic_state->fd = -1;
@@ -393,11 +372,6 @@ static void kvm_s390_flic_realize(DeviceState *dev, Error **errp)
     }
     flic_state->fd = cd.fd;
 
-    /* Check clear_io_irq support */
-    test_attr.group = KVM_DEV_FLIC_CLEAR_IO_IRQ;
-    flic_state->clear_io_supported = !ioctl(flic_state->fd,
-                                            KVM_HAS_DEVICE_ATTR, test_attr);
-
     /* Register savevm handler for floating interrupts */
     register_savevm(NULL, "s390-flic", 0, 1, kvm_flic_save,
                     kvm_flic_load, (void *) flic_state);
@@ -444,7 +418,6 @@ static void kvm_s390_flic_class_init(ObjectClass *oc, void *data)
     fsc->io_adapter_map = kvm_s390_io_adapter_map;
     fsc->add_adapter_routes = kvm_s390_add_adapter_routes;
     fsc->release_adapter_routes = kvm_s390_release_adapter_routes;
-    fsc->clear_io_irq = kvm_s390_clear_io_flic;
 }
 
 static const TypeInfo kvm_s390_flic_info = {
index e82e893..c9486ed 100644 (file)
@@ -418,16 +418,15 @@ static void slavio_intctl_reset(DeviceState *d)
     slavio_check_interrupts(s, 0);
 }
 
-static void slavio_intctl_init(Object *obj)
+static int slavio_intctl_init1(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    SLAVIO_INTCTLState *s = SLAVIO_INTCTL(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    SLAVIO_INTCTLState *s = SLAVIO_INTCTL(dev);
     unsigned int i, j;
     char slave_name[45];
 
     qdev_init_gpio_in(dev, slavio_set_irq_all, 32 + MAX_CPUS);
-    memory_region_init_io(&s->iomem, obj, &slavio_intctlm_mem_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &slavio_intctlm_mem_ops, s,
                           "master-interrupt-controller", INTCTLM_SIZE);
     sysbus_init_mmio(sbd, &s->iomem);
 
@@ -444,12 +443,16 @@ static void slavio_intctl_init(Object *obj)
         s->slaves[i].cpu = i;
         s->slaves[i].master = s;
     }
+
+    return 0;
 }
 
 static void slavio_intctl_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = slavio_intctl_init1;
     dc->reset = slavio_intctl_reset;
     dc->vmsd = &vmstate_intctl;
 }
@@ -458,7 +461,6 @@ static const TypeInfo slavio_intctl_info = {
     .name          = TYPE_SLAVIO_INTCTL,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(SLAVIO_INTCTLState),
-    .instance_init = slavio_intctl_init,
     .class_init    = slavio_intctl_class_init,
 };
 
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
deleted file mode 100644 (file)
index f12192c..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/intc/apic_common.c
-cpu_set_apic_base(uint64_t val) "%016"PRIx64
-cpu_get_apic_base(uint64_t val) "%016"PRIx64
-# coalescing
-apic_report_irq_delivered(int apic_irq_delivered) "coalescing %d"
-apic_reset_irq_delivered(int apic_irq_delivered) "old coalescing %d"
-apic_get_irq_delivered(int apic_irq_delivered) "returning coalescing %d"
-
-# hw/intc/apic.c
-apic_local_deliver(int vector, uint32_t lvt) "vector %d delivery mode %d"
-apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, uint8_t trigger_mode) "dest %d dest_mode %d delivery_mode %d vector %d trigger_mode %d"
-apic_mem_readl(uint64_t addr, uint32_t val)  "%"PRIx64" = %08x"
-apic_mem_writel(uint64_t addr, uint32_t val) "%"PRIx64" = %08x"
-
-# hw/intc/slavio_intctl.c
-slavio_intctl_mem_readl(uint32_t cpu, uint64_t addr, uint32_t ret) "read cpu %d reg 0x%"PRIx64" = %x"
-slavio_intctl_mem_writel(uint32_t cpu, uint64_t addr, uint32_t val) "write cpu %d reg 0x%"PRIx64" = %x"
-slavio_intctl_mem_writel_clear(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Cleared cpu %d irq mask %x, curmask %x"
-slavio_intctl_mem_writel_set(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Set cpu %d irq mask %x, curmask %x"
-slavio_intctlm_mem_readl(uint64_t addr, uint32_t ret) "read system reg 0x%"PRIx64" = %x"
-slavio_intctlm_mem_writel(uint64_t addr, uint32_t val) "write system reg 0x%"PRIx64" = %x"
-slavio_intctlm_mem_writel_enable(uint32_t val, uint32_t intregm_disabled) "Enabled master irq mask %x, curmask %x"
-slavio_intctlm_mem_writel_disable(uint32_t val, uint32_t intregm_disabled) "Disabled master irq mask %x, curmask %x"
-slavio_intctlm_mem_writel_target(uint32_t cpu) "Set master irq cpu %d"
-slavio_check_interrupts(uint32_t pending, uint32_t intregm_disabled) "pending %x disabled %x"
-slavio_set_irq(uint32_t target_cpu, int irq, uint32_t pil, int level) "Set cpu %d irq %d -> pil %d level %d"
-slavio_set_timer_irq_cpu(int cpu, int level) "Set cpu %d local timer level %d"
-
-# hw/intc/grlib_irqmp.c
-grlib_irqmp_check_irqs(uint32_t pend, uint32_t force, uint32_t mask, uint32_t lvl1, uint32_t lvl2) "pend:0x%04x force:0x%04x mask:0x%04x lvl1:0x%04x lvl0:0x%04x"
-grlib_irqmp_ack(int intno) "interrupt:%d"
-grlib_irqmp_set_irq(int irq) "Raise CPU IRQ %d"
-grlib_irqmp_readl_unknown(uint64_t addr) "addr 0x%"PRIx64
-grlib_irqmp_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
-
-# hw/intc/lm32_pic.c
-lm32_pic_raise_irq(void) "Raise CPU interrupt"
-lm32_pic_lower_irq(void) "Lower CPU interrupt"
-lm32_pic_interrupt(int irq, int level) "Set IRQ%d %d"
-lm32_pic_set_im(uint32_t im) "im 0x%08x"
-lm32_pic_set_ip(uint32_t ip) "ip 0x%08x"
-lm32_pic_get_im(uint32_t im) "im 0x%08x"
-lm32_pic_get_ip(uint32_t ip) "ip 0x%08x"
-
-# hw/intc/xics.c
-xics_icp_check_ipi(int server, uint8_t mfrr) "CPU %d can take IPI mfrr=%#x"
-xics_icp_accept(uint32_t old_xirr, uint32_t new_xirr) "icp_accept: XIRR %#"PRIx32"->%#"PRIx32
-xics_icp_eoi(int server, uint32_t xirr, uint32_t new_xirr) "icp_eoi: server %d given XIRR %#"PRIx32" new XIRR %#"PRIx32
-xics_icp_irq(int server, int nr, uint8_t priority) "cpu %d trying to deliver irq %#"PRIx32" priority %#x"
-xics_icp_raise(uint32_t xirr, uint8_t pending_priority) "raising IRQ new XIRR=%#x new pending priority=%#x"
-xics_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq %#x]"
-xics_masked_pending(void) "set_irq_msi: masked pending"
-xics_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq %#x]"
-xics_ics_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_xive: irq %#x [src %d] server %#x prio %#x"
-xics_ics_reject(int nr, int srcno) "reject irq %#x [src %d]"
-xics_ics_eoi(int nr) "ics_eoi: irq %#x"
-xics_alloc(int src, int irq) "source#%d, irq %d"
-xics_alloc_block(int src, int first, int num, bool lsi, int align) "source#%d, first irq %d, %d irqs, lsi=%d, alignnum %d"
-xics_ics_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs"
-xics_ics_free_warn(int src, int irq) "Source#%d, irq %d is already free"
-
-# hw/intc/s390_flic_kvm.c
-flic_create_device(int err) "flic: create device failed %d"
-flic_no_device_api(int err) "flic: no Device Contral API support %d"
-flic_reset_failed(int err) "flic: reset failed %d"
-
-# hw/intc/aspeed_vic.c
-aspeed_vic_set_irq(int irq, int level) "Enabling IRQ %d: %d"
-aspeed_vic_update_fiq(int flags) "Raising FIQ: %d"
-aspeed_vic_update_irq(int flags) "Raising IRQ: %d"
-aspeed_vic_read(uint64_t offset, unsigned size, uint32_t value) "From 0x%" PRIx64 " of size %u: 0x%" PRIx32
-aspeed_vic_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
-
-# hw/intc/arm_gic.c
-gic_enable_irq(int irq) "irq %d enabled"
-gic_disable_irq(int irq) "irq %d disabled"
-gic_set_irq(int irq, int level, int cpumask, int target) "irq %d level %d cpumask 0x%x target 0x%x"
-gic_update_bestirq(int cpu, int irq, int prio, int priority_mask, int running_priority) "cpu %d irq %d priority %d cpu priority mask %d cpu running priority %d"
-gic_update_set_irq(int cpu, const char *name, int level) "cpu[%d]: %s = %d"
-gic_acknowledge_irq(int cpu, int irq) "cpu %d acknowledged irq %d"
-
-# hw/intc/arm_gicv3_cpuif.c
-gicv3_icc_pmr_read(uint32_t cpu, uint64_t val) "GICv3 ICC_PMR read cpu %x value 0x%" PRIx64
-gicv3_icc_pmr_write(uint32_t cpu, uint64_t val) "GICv3 ICC_PMR write cpu %x value 0x%" PRIx64
-gicv3_icc_bpr_read(uint32_t cpu, uint64_t val) "GICv3 ICC_BPR read cpu %x value 0x%" PRIx64
-gicv3_icc_bpr_write(uint32_t cpu, uint64_t val) "GICv3 ICC_BPR write cpu %x value 0x%" PRIx64
-gicv3_icc_ap_read(int regno, uint32_t cpu, uint64_t val) "GICv3 ICC_AP%dR read cpu %x value 0x%" PRIx64
-gicv3_icc_ap_write(int regno, uint32_t cpu, uint64_t val) "GICv3 ICC_AP%dR write cpu %x value 0x%" PRIx64
-gicv3_icc_igrpen_read(uint32_t cpu, uint64_t val) "GICv3 ICC_IGRPEN read cpu %x value 0x%" PRIx64
-gicv3_icc_igrpen_write(uint32_t cpu, uint64_t val) "GICv3 ICC_IGRPEN write cpu %x value 0x%" PRIx64
-gicv3_icc_igrpen1_el3_read(uint32_t cpu, uint64_t val) "GICv3 ICC_IGRPEN1_EL3 read cpu %x value 0x%" PRIx64
-gicv3_icc_igrpen1_el3_write(uint32_t cpu, uint64_t val) "GICv3 ICC_IGRPEN1_EL3 write cpu %x value 0x%" PRIx64
-gicv3_icc_ctlr_read(uint32_t cpu, uint64_t val) "GICv3 ICC_CTLR read cpu %x value 0x%" PRIx64
-gicv3_icc_ctlr_write(uint32_t cpu, uint64_t val) "GICv3 ICC_CTLR write cpu %x value 0x%" PRIx64
-gicv3_icc_ctlr_el3_read(uint32_t cpu, uint64_t val) "GICv3 ICC_CTLR_EL3 read cpu %x value 0x%" PRIx64
-gicv3_icc_ctlr_el3_write(uint32_t cpu, uint64_t val) "GICv3 ICC_CTLR_EL3 write cpu %x value 0x%" PRIx64
-gicv3_cpuif_update(uint32_t cpuid, int irq, int grp, int prio) "GICv3 CPU i/f %x HPPI update: irq %d group %d prio %d"
-gicv3_cpuif_set_irqs(uint32_t cpuid, int fiqlevel, int irqlevel) "GICv3 CPU i/f %x HPPI update: setting FIQ %d IRQ %d"
-gicv3_icc_generate_sgi(uint32_t cpuid, int irq, int irm, uint32_t aff, uint32_t targetlist) "GICv3 CPU i/f %x generating SGI %d IRM %d target affinity 0x%xxx targetlist 0x%x"
-gicv3_icc_iar0_read(uint32_t cpu, uint64_t val) "GICv3 ICC_IAR0 read cpu %x value 0x%" PRIx64
-gicv3_icc_iar1_read(uint32_t cpu, uint64_t val) "GICv3 ICC_IAR1 read cpu %x value 0x%" PRIx64
-gicv3_icc_eoir_write(uint32_t cpu, uint64_t val) "GICv3 ICC_EOIR write cpu %x value 0x%" PRIx64
-gicv3_icc_hppir0_read(uint32_t cpu, uint64_t val) "GICv3 ICC_HPPIR0 read cpu %x value 0x%" PRIx64
-gicv3_icc_hppir1_read(uint32_t cpu, uint64_t val) "GICv3 ICC_HPPIR1 read cpu %x value 0x%" PRIx64
-gicv3_icc_dir_write(uint32_t cpu, uint64_t val) "GICv3 ICC_DIR write cpu %x value 0x%" PRIx64
-gicv3_icc_rpr_read(uint32_t cpu, uint64_t val) "GICv3 ICC_RPR read cpu %x value 0x%" PRIx64
-
-# hw/intc/arm_gicv3_dist.c
-gicv3_dist_read(uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 distributor read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d"
-gicv3_dist_badread(uint64_t offset, unsigned size, bool secure) "GICv3 distributor read: offset 0x%" PRIx64 " size %u secure %d: error"
-gicv3_dist_write(uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 distributor write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d"
-gicv3_dist_badwrite(uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 distributor write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d: error"
-gicv3_dist_set_irq(int irq, int level) "GICv3 distributor interrupt %d level changed to %d"
-
-# hw/intc/arm_gicv3_redist.c
-gicv3_redist_read(uint32_t cpu, uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 redistributor %x read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d"
-gicv3_redist_badread(uint32_t cpu, uint64_t offset, unsigned size, bool secure) "GICv3 redistributor %x read: offset 0x%" PRIx64 " size %u secure %d: error"
-gicv3_redist_write(uint32_t cpu, uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 redistributor %x write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d"
-gicv3_redist_badwrite(uint32_t cpu, uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 redistributor %x write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d: error"
-gicv3_redist_set_irq(uint32_t cpu, int irq, int level) "GICv3 redistributor %x interrupt %d level changed to %d"
-gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 redistributor %x pending SGI %d"
index cd48f42..8659be0 100644 (file)
 #include "hw/hw.h"
 #include "trace.h"
 #include "qemu/timer.h"
+#include "hw/ppc/spapr.h"
 #include "hw/ppc/xics.h"
 #include "qemu/error-report.h"
 #include "qapi/visitor.h"
 
-int xics_get_cpu_index_by_dt_id(int cpu_dt_id)
+static int get_cpu_index_by_dt_id(int cpu_dt_id)
 {
     PowerPCCPU *cpu = ppc_get_vcpu_by_dt_id(cpu_dt_id);
 
@@ -47,31 +48,17 @@ int xics_get_cpu_index_by_dt_id(int cpu_dt_id)
     return -1;
 }
 
-void xics_cpu_destroy(XICSState *xics, PowerPCCPU *cpu)
-{
-    CPUState *cs = CPU(cpu);
-    ICPState *ss = &xics->ss[cs->cpu_index];
-
-    assert(cs->cpu_index < xics->nr_servers);
-    assert(cs == ss->cs);
-
-    ss->output = NULL;
-    ss->cs = NULL;
-}
-
-void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
+void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
-    ICPState *ss = &xics->ss[cs->cpu_index];
-    XICSStateClass *info = XICS_COMMON_GET_CLASS(xics);
+    ICPState *ss = &icp->ss[cs->cpu_index];
+    XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
 
-    assert(cs->cpu_index < xics->nr_servers);
-
-    ss->cs = cs;
+    assert(cs->cpu_index < icp->nr_servers);
 
     if (info->cpu_setup) {
-        info->cpu_setup(xics, cpu);
+        info->cpu_setup(icp, cpu);
     }
 
     switch (PPC_INPUT(env)) {
@@ -95,21 +82,21 @@ void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
  */
 static void xics_common_reset(DeviceState *d)
 {
-    XICSState *xics = XICS_COMMON(d);
+    XICSState *icp = XICS_COMMON(d);
     int i;
 
-    for (i = 0; i < xics->nr_servers; i++) {
-        device_reset(DEVICE(&xics->ss[i]));
+    for (i = 0; i < icp->nr_servers; i++) {
+        device_reset(DEVICE(&icp->ss[i]));
     }
 
-    device_reset(DEVICE(xics->ics));
+    device_reset(DEVICE(icp->ics));
 }
 
 static void xics_prop_get_nr_irqs(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
 {
-    XICSState *xics = XICS_COMMON(obj);
-    int64_t value = xics->nr_irqs;
+    XICSState *icp = XICS_COMMON(obj);
+    int64_t value = icp->nr_irqs;
 
     visit_type_int(v, name, &value, errp);
 }
@@ -117,8 +104,8 @@ static void xics_prop_get_nr_irqs(Object *obj, Visitor *v, const char *name,
 static void xics_prop_set_nr_irqs(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
 {
-    XICSState *xics = XICS_COMMON(obj);
-    XICSStateClass *info = XICS_COMMON_GET_CLASS(xics);
+    XICSState *icp = XICS_COMMON(obj);
+    XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
     Error *error = NULL;
     int64_t value;
 
@@ -127,23 +114,23 @@ static void xics_prop_set_nr_irqs(Object *obj, Visitor *v, const char *name,
         error_propagate(errp, error);
         return;
     }
-    if (xics->nr_irqs) {
+    if (icp->nr_irqs) {
         error_setg(errp, "Number of interrupts is already set to %u",
-                   xics->nr_irqs);
+                   icp->nr_irqs);
         return;
     }
 
     assert(info->set_nr_irqs);
-    assert(xics->ics);
-    info->set_nr_irqs(xics, value, errp);
+    assert(icp->ics);
+    info->set_nr_irqs(icp, value, errp);
 }
 
 static void xics_prop_get_nr_servers(Object *obj, Visitor *v,
                                      const char *name, void *opaque,
                                      Error **errp)
 {
-    XICSState *xics = XICS_COMMON(obj);
-    int64_t value = xics->nr_servers;
+    XICSState *icp = XICS_COMMON(obj);
+    int64_t value = icp->nr_servers;
 
     visit_type_int(v, name, &value, errp);
 }
@@ -152,8 +139,8 @@ static void xics_prop_set_nr_servers(Object *obj, Visitor *v,
                                      const char *name, void *opaque,
                                      Error **errp)
 {
-    XICSState *xics = XICS_COMMON(obj);
-    XICSStateClass *info = XICS_COMMON_GET_CLASS(xics);
+    XICSState *icp = XICS_COMMON(obj);
+    XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
     Error *error = NULL;
     int64_t value;
 
@@ -162,14 +149,14 @@ static void xics_prop_set_nr_servers(Object *obj, Visitor *v,
         error_propagate(errp, error);
         return;
     }
-    if (xics->nr_servers) {
+    if (icp->nr_servers) {
         error_setg(errp, "Number of servers is already set to %u",
-                   xics->nr_servers);
+                   icp->nr_servers);
         return;
     }
 
     assert(info->set_nr_servers);
-    info->set_nr_servers(xics, value, errp);
+    info->set_nr_servers(icp, value, errp);
 }
 
 static void xics_common_initfn(Object *obj)
@@ -212,9 +199,9 @@ static void ics_reject(ICSState *ics, int nr);
 static void ics_resend(ICSState *ics);
 static void ics_eoi(ICSState *ics, int nr);
 
-static void icp_check_ipi(XICSState *xics, int server)
+static void icp_check_ipi(XICSState *icp, int server)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = icp->ss + server;
 
     if (XISR(ss) && (ss->pending_priority <= ss->mfrr)) {
         return;
@@ -223,7 +210,7 @@ static void icp_check_ipi(XICSState *xics, int server)
     trace_xics_icp_check_ipi(server, ss->mfrr);
 
     if (XISR(ss)) {
-        ics_reject(xics->ics, XISR(ss));
+        ics_reject(icp->ics, XISR(ss));
     }
 
     ss->xirr = (ss->xirr & ~XISR_MASK) | XICS_IPI;
@@ -231,19 +218,19 @@ static void icp_check_ipi(XICSState *xics, int server)
     qemu_irq_raise(ss->output);
 }
 
-static void icp_resend(XICSState *xics, int server)
+static void icp_resend(XICSState *icp, int server)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = icp->ss + server;
 
     if (ss->mfrr < CPPR(ss)) {
-        icp_check_ipi(xics, server);
+        icp_check_ipi(icp, server);
     }
-    ics_resend(xics->ics);
+    ics_resend(icp->ics);
 }
 
-void icp_set_cppr(XICSState *xics, int server, uint8_t cppr)
+static void icp_set_cppr(XICSState *icp, int server, uint8_t cppr)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = icp->ss + server;
     uint8_t old_cppr;
     uint32_t old_xisr;
 
@@ -256,26 +243,26 @@ void icp_set_cppr(XICSState *xics, int server, uint8_t cppr)
             ss->xirr &= ~XISR_MASK; /* Clear XISR */
             ss->pending_priority = 0xff;
             qemu_irq_lower(ss->output);
-            ics_reject(xics->ics, old_xisr);
+            ics_reject(icp->ics, old_xisr);
         }
     } else {
         if (!XISR(ss)) {
-            icp_resend(xics, server);
+            icp_resend(icp, server);
         }
     }
 }
 
-void icp_set_mfrr(XICSState *xics, int server, uint8_t mfrr)
+static void icp_set_mfrr(XICSState *icp, int server, uint8_t mfrr)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = icp->ss + server;
 
     ss->mfrr = mfrr;
     if (mfrr < CPPR(ss)) {
-        icp_check_ipi(xics, server);
+        icp_check_ipi(icp, server);
     }
 }
 
-uint32_t icp_accept(ICPState *ss)
+static uint32_t icp_accept(ICPState *ss)
 {
     uint32_t xirr = ss->xirr;
 
@@ -288,39 +275,31 @@ uint32_t icp_accept(ICPState *ss)
     return xirr;
 }
 
-uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr)
-{
-    if (mfrr) {
-        *mfrr = ss->mfrr;
-    }
-    return ss->xirr;
-}
-
-void icp_eoi(XICSState *xics, int server, uint32_t xirr)
+static void icp_eoi(XICSState *icp, int server, uint32_t xirr)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = icp->ss + server;
 
     /* Send EOI -> ICS */
     ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
     trace_xics_icp_eoi(server, xirr, ss->xirr);
-    ics_eoi(xics->ics, xirr & XISR_MASK);
+    ics_eoi(icp->ics, xirr & XISR_MASK);
     if (!XISR(ss)) {
-        icp_resend(xics, server);
+        icp_resend(icp, server);
     }
 }
 
-static void icp_irq(XICSState *xics, int server, int nr, uint8_t priority)
+static void icp_irq(XICSState *icp, int server, int nr, uint8_t priority)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = icp->ss + server;
 
     trace_xics_icp_irq(server, nr, priority);
 
     if ((priority >= CPPR(ss))
         || (XISR(ss) && (ss->pending_priority <= priority))) {
-        ics_reject(xics->ics, nr);
+        ics_reject(icp->ics, nr);
     } else {
         if (XISR(ss)) {
-            ics_reject(xics->ics, XISR(ss));
+            ics_reject(icp->ics, XISR(ss));
         }
         ss->xirr = (ss->xirr & ~XISR_MASK) | (nr & XISR_MASK);
         ss->pending_priority = priority;
@@ -397,6 +376,12 @@ static const TypeInfo icp_info = {
 /*
  * ICS: Source layer
  */
+static int ics_valid_irq(ICSState *ics, uint32_t nr)
+{
+    return (nr >= ics->offset)
+        && (nr < (ics->offset + ics->nr_irqs));
+}
+
 static void resend_msi(ICSState *ics, int srcno)
 {
     ICSIRQState *irq = ics->irqs + srcno;
@@ -405,7 +390,7 @@ static void resend_msi(ICSState *ics, int srcno)
     if (irq->status & XICS_STATUS_REJECTED) {
         irq->status &= ~XICS_STATUS_REJECTED;
         if (irq->priority != 0xff) {
-            icp_irq(ics->xics, irq->server, srcno + ics->offset,
+            icp_irq(ics->icp, irq->server, srcno + ics->offset,
                     irq->priority);
         }
     }
@@ -419,7 +404,7 @@ static void resend_lsi(ICSState *ics, int srcno)
         && (irq->status & XICS_STATUS_ASSERTED)
         && !(irq->status & XICS_STATUS_SENT)) {
         irq->status |= XICS_STATUS_SENT;
-        icp_irq(ics->xics, irq->server, srcno + ics->offset, irq->priority);
+        icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
     }
 }
 
@@ -434,7 +419,7 @@ static void set_irq_msi(ICSState *ics, int srcno, int val)
             irq->status |= XICS_STATUS_MASKED_PENDING;
             trace_xics_masked_pending();
         } else  {
-            icp_irq(ics->xics, irq->server, srcno + ics->offset, irq->priority);
+            icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
         }
     }
 }
@@ -473,7 +458,7 @@ static void write_xive_msi(ICSState *ics, int srcno)
     }
 
     irq->status &= ~XICS_STATUS_MASKED_PENDING;
-    icp_irq(ics->xics, irq->server, srcno + ics->offset, irq->priority);
+    icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
 }
 
 static void write_xive_lsi(ICSState *ics, int srcno)
@@ -481,8 +466,8 @@ static void write_xive_lsi(ICSState *ics, int srcno)
     resend_lsi(ics, srcno);
 }
 
-void ics_write_xive(ICSState *ics, int nr, int server,
-                    uint8_t priority, uint8_t saved_priority)
+static void ics_write_xive(ICSState *ics, int nr, int server,
+                           uint8_t priority, uint8_t saved_priority)
 {
     int srcno = nr - ics->offset;
     ICSIRQState *irq = ics->irqs + srcno;
@@ -558,8 +543,8 @@ static int ics_post_load(ICSState *ics, int version_id)
 {
     int i;
 
-    for (i = 0; i < ics->xics->nr_servers; i++) {
-        icp_resend(ics->xics, i);
+    for (i = 0; i < ics->icp->nr_servers; i++) {
+        icp_resend(ics->icp, i);
     }
 
     return 0;
@@ -659,14 +644,14 @@ static const TypeInfo ics_info = {
 /*
  * Exported functions
  */
-int xics_find_source(XICSState *xics, int irq)
+static int xics_find_source(XICSState *icp, int irq)
 {
     int sources = 1;
     int src;
 
     /* FIXME: implement multiple sources */
     for (src = 0; src < sources; ++src) {
-        ICSState *ics = &xics->ics[src];
+        ICSState *ics = &icp->ics[src];
         if (ics_valid_irq(ics, irq)) {
             return src;
         }
@@ -675,19 +660,19 @@ int xics_find_source(XICSState *xics, int irq)
     return -1;
 }
 
-qemu_irq xics_get_qirq(XICSState *xics, int irq)
+qemu_irq xics_get_qirq(XICSState *icp, int irq)
 {
-    int src = xics_find_source(xics, irq);
+    int src = xics_find_source(icp, irq);
 
     if (src >= 0) {
-        ICSState *ics = &xics->ics[src];
+        ICSState *ics = &icp->ics[src];
         return ics->qirqs[irq - ics->offset];
     }
 
     return NULL;
 }
 
-void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
+static void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
 {
     assert(!(ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK));
 
@@ -695,9 +680,412 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
         lsi ? XICS_FLAGS_IRQ_LSI : XICS_FLAGS_IRQ_MSI;
 }
 
+void xics_set_irq_type(XICSState *icp, int irq, bool lsi)
+{
+    int src = xics_find_source(icp, irq);
+    ICSState *ics;
+
+    assert(src >= 0);
+
+    ics = &icp->ics[src];
+    ics_set_irq_type(ics, irq - ics->offset, lsi);
+}
+
+#define ICS_IRQ_FREE(ics, srcno)   \
+    (!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK)))
+
+static int ics_find_free_block(ICSState *ics, int num, int alignnum)
+{
+    int first, i;
+
+    for (first = 0; first < ics->nr_irqs; first += alignnum) {
+        if (num > (ics->nr_irqs - first)) {
+            return -1;
+        }
+        for (i = first; i < first + num; ++i) {
+            if (!ICS_IRQ_FREE(ics, i)) {
+                break;
+            }
+        }
+        if (i == (first + num)) {
+            return first;
+        }
+    }
+
+    return -1;
+}
+
+int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi, Error **errp)
+{
+    ICSState *ics = &icp->ics[src];
+    int irq;
+
+    if (irq_hint) {
+        assert(src == xics_find_source(icp, irq_hint));
+        if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
+            error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint);
+            return -1;
+        }
+        irq = irq_hint;
+    } else {
+        irq = ics_find_free_block(ics, 1, 1);
+        if (irq < 0) {
+            error_setg(errp, "can't allocate IRQ: no IRQ left");
+            return -1;
+        }
+        irq += ics->offset;
+    }
+
+    ics_set_irq_type(ics, irq - ics->offset, lsi);
+    trace_xics_alloc(src, irq);
+
+    return irq;
+}
+
+/*
+ * Allocate block of consecutive IRQs, and return the number of the first IRQ in the block.
+ * If align==true, aligns the first IRQ number to num.
+ */
+int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align,
+                     Error **errp)
+{
+    int i, first = -1;
+    ICSState *ics = &icp->ics[src];
+
+    assert(src == 0);
+    /*
+     * MSIMesage::data is used for storing VIRQ so
+     * it has to be aligned to num to support multiple
+     * MSI vectors. MSI-X is not affected by this.
+     * The hint is used for the first IRQ, the rest should
+     * be allocated continuously.
+     */
+    if (align) {
+        assert((num == 1) || (num == 2) || (num == 4) ||
+               (num == 8) || (num == 16) || (num == 32));
+        first = ics_find_free_block(ics, num, num);
+    } else {
+        first = ics_find_free_block(ics, num, 1);
+    }
+    if (first < 0) {
+        error_setg(errp, "can't find a free %d-IRQ block", num);
+        return -1;
+    }
+
+    if (first >= 0) {
+        for (i = first; i < first + num; ++i) {
+            ics_set_irq_type(ics, i, lsi);
+        }
+    }
+    first += ics->offset;
+
+    trace_xics_alloc_block(src, first, num, lsi, align);
+
+    return first;
+}
+
+static void ics_free(ICSState *ics, int srcno, int num)
+{
+    int i;
+
+    for (i = srcno; i < srcno + num; ++i) {
+        if (ICS_IRQ_FREE(ics, i)) {
+            trace_xics_ics_free_warn(ics - ics->icp->ics, i + ics->offset);
+        }
+        memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
+    }
+}
+
+void xics_free(XICSState *icp, int irq, int num)
+{
+    int src = xics_find_source(icp, irq);
+
+    if (src >= 0) {
+        ICSState *ics = &icp->ics[src];
+
+        /* FIXME: implement multiple sources */
+        assert(src == 0);
+
+        trace_xics_ics_free(ics - icp->ics, irq, num);
+        ics_free(ics, irq - ics->offset, num);
+    }
+}
+
+/*
+ * Guest interfaces
+ */
+
+static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+                           target_ulong opcode, target_ulong *args)
+{
+    CPUState *cs = CPU(cpu);
+    target_ulong cppr = args[0];
+
+    icp_set_cppr(spapr->icp, cs->cpu_index, cppr);
+    return H_SUCCESS;
+}
+
+static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+                          target_ulong opcode, target_ulong *args)
+{
+    target_ulong server = get_cpu_index_by_dt_id(args[0]);
+    target_ulong mfrr = args[1];
+
+    if (server >= spapr->icp->nr_servers) {
+        return H_PARAMETER;
+    }
+
+    icp_set_mfrr(spapr->icp, server, mfrr);
+    return H_SUCCESS;
+}
+
+static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+                           target_ulong opcode, target_ulong *args)
+{
+    CPUState *cs = CPU(cpu);
+    uint32_t xirr = icp_accept(spapr->icp->ss + cs->cpu_index);
+
+    args[0] = xirr;
+    return H_SUCCESS;
+}
+
+static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+                             target_ulong opcode, target_ulong *args)
+{
+    CPUState *cs = CPU(cpu);
+    ICPState *ss = &spapr->icp->ss[cs->cpu_index];
+    uint32_t xirr = icp_accept(ss);
+
+    args[0] = xirr;
+    args[1] = cpu_get_host_ticks();
+    return H_SUCCESS;
+}
+
+static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+                          target_ulong opcode, target_ulong *args)
+{
+    CPUState *cs = CPU(cpu);
+    target_ulong xirr = args[0];
+
+    icp_eoi(spapr->icp, cs->cpu_index, xirr);
+    return H_SUCCESS;
+}
+
+static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+                            target_ulong opcode, target_ulong *args)
+{
+    CPUState *cs = CPU(cpu);
+    ICPState *ss = &spapr->icp->ss[cs->cpu_index];
+
+    args[0] = ss->xirr;
+    args[1] = ss->mfrr;
+
+    return H_SUCCESS;
+}
+
+static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+                          uint32_t token,
+                          uint32_t nargs, target_ulong args,
+                          uint32_t nret, target_ulong rets)
+{
+    ICSState *ics = spapr->icp->ics;
+    uint32_t nr, server, priority;
+
+    if ((nargs != 3) || (nret != 1)) {
+        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+        return;
+    }
+
+    nr = rtas_ld(args, 0);
+    server = get_cpu_index_by_dt_id(rtas_ld(args, 1));
+    priority = rtas_ld(args, 2);
+
+    if (!ics_valid_irq(ics, nr) || (server >= ics->icp->nr_servers)
+        || (priority > 0xff)) {
+        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+        return;
+    }
+
+    ics_write_xive(ics, nr, server, priority, priority);
+
+    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+}
+
+static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+                          uint32_t token,
+                          uint32_t nargs, target_ulong args,
+                          uint32_t nret, target_ulong rets)
+{
+    ICSState *ics = spapr->icp->ics;
+    uint32_t nr;
+
+    if ((nargs != 1) || (nret != 3)) {
+        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+        return;
+    }
+
+    nr = rtas_ld(args, 0);
+
+    if (!ics_valid_irq(ics, nr)) {
+        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+        return;
+    }
+
+    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+    rtas_st(rets, 1, ics->irqs[nr - ics->offset].server);
+    rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
+}
+
+static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+                         uint32_t token,
+                         uint32_t nargs, target_ulong args,
+                         uint32_t nret, target_ulong rets)
+{
+    ICSState *ics = spapr->icp->ics;
+    uint32_t nr;
+
+    if ((nargs != 1) || (nret != 1)) {
+        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+        return;
+    }
+
+    nr = rtas_ld(args, 0);
+
+    if (!ics_valid_irq(ics, nr)) {
+        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+        return;
+    }
+
+    ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server, 0xff,
+                   ics->irqs[nr - ics->offset].priority);
+
+    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+}
+
+static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+                        uint32_t token,
+                        uint32_t nargs, target_ulong args,
+                        uint32_t nret, target_ulong rets)
+{
+    ICSState *ics = spapr->icp->ics;
+    uint32_t nr;
+
+    if ((nargs != 1) || (nret != 1)) {
+        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+        return;
+    }
+
+    nr = rtas_ld(args, 0);
+
+    if (!ics_valid_irq(ics, nr)) {
+        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+        return;
+    }
+
+    ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server,
+                   ics->irqs[nr - ics->offset].saved_priority,
+                   ics->irqs[nr - ics->offset].saved_priority);
+
+    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+}
+
+/*
+ * XICS
+ */
+
+static void xics_set_nr_irqs(XICSState *icp, uint32_t nr_irqs, Error **errp)
+{
+    icp->nr_irqs = icp->ics->nr_irqs = nr_irqs;
+}
+
+static void xics_set_nr_servers(XICSState *icp, uint32_t nr_servers,
+                                Error **errp)
+{
+    int i;
+
+    icp->nr_servers = nr_servers;
+
+    icp->ss = g_malloc0(icp->nr_servers*sizeof(ICPState));
+    for (i = 0; i < icp->nr_servers; i++) {
+        char buffer[32];
+        object_initialize(&icp->ss[i], sizeof(icp->ss[i]), TYPE_ICP);
+        snprintf(buffer, sizeof(buffer), "icp[%d]", i);
+        object_property_add_child(OBJECT(icp), buffer, OBJECT(&icp->ss[i]),
+                                  errp);
+    }
+}
+
+static void xics_realize(DeviceState *dev, Error **errp)
+{
+    XICSState *icp = XICS(dev);
+    Error *error = NULL;
+    int i;
+
+    if (!icp->nr_servers) {
+        error_setg(errp, "Number of servers needs to be greater 0");
+        return;
+    }
+
+    /* Registration of global state belongs into realize */
+    spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
+    spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);
+    spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_int_off);
+    spapr_rtas_register(RTAS_IBM_INT_ON, "ibm,int-on", rtas_int_on);
+
+    spapr_register_hypercall(H_CPPR, h_cppr);
+    spapr_register_hypercall(H_IPI, h_ipi);
+    spapr_register_hypercall(H_XIRR, h_xirr);
+    spapr_register_hypercall(H_XIRR_X, h_xirr_x);
+    spapr_register_hypercall(H_EOI, h_eoi);
+    spapr_register_hypercall(H_IPOLL, h_ipoll);
+
+    object_property_set_bool(OBJECT(icp->ics), true, "realized", &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
+
+    for (i = 0; i < icp->nr_servers; i++) {
+        object_property_set_bool(OBJECT(&icp->ss[i]), true, "realized", &error);
+        if (error) {
+            error_propagate(errp, error);
+            return;
+        }
+    }
+}
+
+static void xics_initfn(Object *obj)
+{
+    XICSState *xics = XICS(obj);
+
+    xics->ics = ICS(object_new(TYPE_ICS));
+    object_property_add_child(obj, "ics", OBJECT(xics->ics), NULL);
+    xics->ics->icp = xics;
+}
+
+static void xics_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    XICSStateClass *xsc = XICS_CLASS(oc);
+
+    dc->realize = xics_realize;
+    xsc->set_nr_irqs = xics_set_nr_irqs;
+    xsc->set_nr_servers = xics_set_nr_servers;
+}
+
+static const TypeInfo xics_info = {
+    .name          = TYPE_XICS,
+    .parent        = TYPE_XICS_COMMON,
+    .instance_size = sizeof(XICSState),
+    .class_size = sizeof(XICSStateClass),
+    .class_init    = xics_class_init,
+    .instance_init = xics_initfn,
+};
+
 static void xics_register_types(void)
 {
     type_register_static(&xics_common_info);
+    type_register_static(&xics_info);
     type_register_static(&ics_info);
     type_register_static(&icp_info);
 }
index edbd62f..9029d9e 100644 (file)
@@ -31,7 +31,6 @@
 #include "cpu.h"
 #include "hw/hw.h"
 #include "trace.h"
-#include "sysemu/kvm.h"
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/xics.h"
 #include "kvm_ppc.h"
@@ -114,10 +113,8 @@ static void icp_kvm_reset(DeviceState *dev)
     icp->pending_priority = 0xff;
     icp->mfrr = 0xff;
 
-    /* Make all outputs as deasserted only if the CPU thread is in use */
-    if (icp->output) {
-        qemu_set_irq(icp->output, 0);
-    }
+    /* Make all outputs are deasserted */
+    qemu_set_irq(icp->output, 0);
 
     icp_set_kvm_state(icp, 1);
 }
@@ -145,7 +142,7 @@ static const TypeInfo icp_kvm_info = {
  */
 static void ics_get_kvm_state(ICSState *ics)
 {
-    KVMXICSState *xicskvm = XICS_SPAPR_KVM(ics->xics);
+    KVMXICSState *icpkvm = KVM_XICS(ics->icp);
     uint64_t state;
     struct kvm_device_attr attr = {
         .flags = 0,
@@ -160,7 +157,7 @@ static void ics_get_kvm_state(ICSState *ics)
 
         attr.attr = i + ics->offset;
 
-        ret = ioctl(xicskvm->kernel_xics_fd, KVM_GET_DEVICE_ATTR, &attr);
+        ret = ioctl(icpkvm->kernel_xics_fd, KVM_GET_DEVICE_ATTR, &attr);
         if (ret != 0) {
             error_report("Unable to retrieve KVM interrupt controller state"
                     " for IRQ %d: %s", i + ics->offset, strerror(errno));
@@ -204,7 +201,7 @@ static void ics_get_kvm_state(ICSState *ics)
 
 static int ics_set_kvm_state(ICSState *ics, int version_id)
 {
-    KVMXICSState *xicskvm = XICS_SPAPR_KVM(ics->xics);
+    KVMXICSState *icpkvm = KVM_XICS(ics->icp);
     uint64_t state;
     struct kvm_device_attr attr = {
         .flags = 0,
@@ -238,7 +235,7 @@ static int ics_set_kvm_state(ICSState *ics, int version_id)
             }
         }
 
-        ret = ioctl(xicskvm->kernel_xics_fd, KVM_SET_DEVICE_ATTR, &attr);
+        ret = ioctl(icpkvm->kernel_xics_fd, KVM_SET_DEVICE_ATTR, &attr);
         if (ret != 0) {
             error_report("Unable to restore KVM interrupt controller state"
                     " for IRQs %d: %s", i + ics->offset, strerror(errno));
@@ -324,17 +321,17 @@ static const TypeInfo ics_kvm_info = {
 /*
  * XICS-KVM
  */
-static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
+static void xics_kvm_cpu_setup(XICSState *icp, PowerPCCPU *cpu)
 {
     CPUState *cs;
     ICPState *ss;
-    KVMXICSState *xicskvm = XICS_SPAPR_KVM(xics);
+    KVMXICSState *icpkvm = KVM_XICS(icp);
 
     cs = CPU(cpu);
-    ss = &xics->ss[cs->cpu_index];
+    ss = &icp->ss[cs->cpu_index];
 
-    assert(cs->cpu_index < xics->nr_servers);
-    if (xicskvm->kernel_xics_fd == -1) {
+    assert(cs->cpu_index < icp->nr_servers);
+    if (icpkvm->kernel_xics_fd == -1) {
         abort();
     }
 
@@ -347,12 +344,13 @@ static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
         return;
     }
 
-    if (xicskvm->kernel_xics_fd != -1) {
+    if (icpkvm->kernel_xics_fd != -1) {
         int ret;
 
+        ss->cs = cs;
+
         ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0,
-                                  xicskvm->kernel_xics_fd,
-                                  kvm_arch_vcpu_id(cs));
+                                  icpkvm->kernel_xics_fd, kvm_arch_vcpu_id(cs));
         if (ret < 0) {
             error_report("Unable to connect CPU%ld to kernel XICS: %s",
                     kvm_arch_vcpu_id(cs), strerror(errno));
@@ -362,25 +360,24 @@ static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
     }
 }
 
-static void xics_kvm_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
-                                 Error **errp)
+static void xics_kvm_set_nr_irqs(XICSState *icp, uint32_t nr_irqs, Error **errp)
 {
-    xics->nr_irqs = xics->ics->nr_irqs = nr_irqs;
+    icp->nr_irqs = icp->ics->nr_irqs = nr_irqs;
 }
 
-static void xics_kvm_set_nr_servers(XICSState *xics, uint32_t nr_servers,
+static void xics_kvm_set_nr_servers(XICSState *icp, uint32_t nr_servers,
                                     Error **errp)
 {
     int i;
 
-    xics->nr_servers = nr_servers;
+    icp->nr_servers = nr_servers;
 
-    xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
-    for (i = 0; i < xics->nr_servers; i++) {
+    icp->ss = g_malloc0(icp->nr_servers*sizeof(ICPState));
+    for (i = 0; i < icp->nr_servers; i++) {
         char buffer[32];
-        object_initialize(&xics->ss[i], sizeof(xics->ss[i]), TYPE_KVM_ICP);
+        object_initialize(&icp->ss[i], sizeof(icp->ss[i]), TYPE_KVM_ICP);
         snprintf(buffer, sizeof(buffer), "icp[%d]", i);
-        object_property_add_child(OBJECT(xics), buffer, OBJECT(&xics->ss[i]),
+        object_property_add_child(OBJECT(icp), buffer, OBJECT(&icp->ss[i]),
                                   errp);
     }
 }
@@ -396,8 +393,8 @@ static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 
 static void xics_kvm_realize(DeviceState *dev, Error **errp)
 {
-    KVMXICSState *xicskvm = XICS_SPAPR_KVM(dev);
-    XICSState *xics = XICS_COMMON(dev);
+    KVMXICSState *icpkvm = KVM_XICS(dev);
+    XICSState *icp = XICS_COMMON(dev);
     int i, rc;
     Error *error = NULL;
     struct kvm_create_device xics_create_device = {
@@ -447,18 +444,17 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp)
         goto fail;
     }
 
-    xicskvm->kernel_xics_fd = xics_create_device.fd;
+    icpkvm->kernel_xics_fd = xics_create_device.fd;
 
-    object_property_set_bool(OBJECT(xics->ics), true, "realized", &error);
+    object_property_set_bool(OBJECT(icp->ics), true, "realized", &error);
     if (error) {
         error_propagate(errp, error);
         goto fail;
     }
 
-    assert(xics->nr_servers);
-    for (i = 0; i < xics->nr_servers; i++) {
-        object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
-                                 &error);
+    assert(icp->nr_servers);
+    for (i = 0; i < icp->nr_servers; i++) {
+        object_property_set_bool(OBJECT(&icp->ss[i]), true, "realized", &error);
         if (error) {
             error_propagate(errp, error);
             goto fail;
@@ -484,7 +480,7 @@ static void xics_kvm_initfn(Object *obj)
 
     xics->ics = ICS(object_new(TYPE_KVM_ICS));
     object_property_add_child(obj, "ics", OBJECT(xics->ics), NULL);
-    xics->ics->xics = xics;
+    xics->ics->icp = xics;
 }
 
 static void xics_kvm_class_init(ObjectClass *oc, void *data)
@@ -498,8 +494,8 @@ static void xics_kvm_class_init(ObjectClass *oc, void *data)
     xsc->set_nr_servers = xics_kvm_set_nr_servers;
 }
 
-static const TypeInfo xics_spapr_kvm_info = {
-    .name          = TYPE_XICS_SPAPR_KVM,
+static const TypeInfo xics_kvm_info = {
+    .name          = TYPE_KVM_XICS,
     .parent        = TYPE_XICS_COMMON,
     .instance_size = sizeof(KVMXICSState),
     .class_init    = xics_kvm_class_init,
@@ -508,7 +504,7 @@ static const TypeInfo xics_spapr_kvm_info = {
 
 static void xics_kvm_register_types(void)
 {
-    type_register_static(&xics_spapr_kvm_info);
+    type_register_static(&xics_kvm_info);
     type_register_static(&ics_kvm_info);
     type_register_static(&icp_kvm_info);
 }
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
deleted file mode 100644 (file)
index 618826d..0000000
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
- *
- * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
- *
- * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "hw/hw.h"
-#include "trace.h"
-#include "qemu/timer.h"
-#include "hw/ppc/spapr.h"
-#include "hw/ppc/xics.h"
-#include "qapi/visitor.h"
-#include "qapi/error.h"
-
-/*
- * Guest interfaces
- */
-
-static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
-                           target_ulong opcode, target_ulong *args)
-{
-    CPUState *cs = CPU(cpu);
-    target_ulong cppr = args[0];
-
-    icp_set_cppr(spapr->xics, cs->cpu_index, cppr);
-    return H_SUCCESS;
-}
-
-static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
-                          target_ulong opcode, target_ulong *args)
-{
-    target_ulong server = xics_get_cpu_index_by_dt_id(args[0]);
-    target_ulong mfrr = args[1];
-
-    if (server >= spapr->xics->nr_servers) {
-        return H_PARAMETER;
-    }
-
-    icp_set_mfrr(spapr->xics, server, mfrr);
-    return H_SUCCESS;
-}
-
-static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
-                           target_ulong opcode, target_ulong *args)
-{
-    CPUState *cs = CPU(cpu);
-    uint32_t xirr = icp_accept(spapr->xics->ss + cs->cpu_index);
-
-    args[0] = xirr;
-    return H_SUCCESS;
-}
-
-static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
-                             target_ulong opcode, target_ulong *args)
-{
-    CPUState *cs = CPU(cpu);
-    ICPState *ss = &spapr->xics->ss[cs->cpu_index];
-    uint32_t xirr = icp_accept(ss);
-
-    args[0] = xirr;
-    args[1] = cpu_get_host_ticks();
-    return H_SUCCESS;
-}
-
-static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
-                          target_ulong opcode, target_ulong *args)
-{
-    CPUState *cs = CPU(cpu);
-    target_ulong xirr = args[0];
-
-    icp_eoi(spapr->xics, cs->cpu_index, xirr);
-    return H_SUCCESS;
-}
-
-static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
-                            target_ulong opcode, target_ulong *args)
-{
-    CPUState *cs = CPU(cpu);
-    uint32_t mfrr;
-    uint32_t xirr = icp_ipoll(spapr->xics->ss + cs->cpu_index, &mfrr);
-
-    args[0] = xirr;
-    args[1] = mfrr;
-
-    return H_SUCCESS;
-}
-
-static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
-                          uint32_t token,
-                          uint32_t nargs, target_ulong args,
-                          uint32_t nret, target_ulong rets)
-{
-    ICSState *ics = spapr->xics->ics;
-    uint32_t nr, server, priority;
-
-    if ((nargs != 3) || (nret != 1)) {
-        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
-        return;
-    }
-
-    nr = rtas_ld(args, 0);
-    server = xics_get_cpu_index_by_dt_id(rtas_ld(args, 1));
-    priority = rtas_ld(args, 2);
-
-    if (!ics_valid_irq(ics, nr) || (server >= ics->xics->nr_servers)
-        || (priority > 0xff)) {
-        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
-        return;
-    }
-
-    ics_write_xive(ics, nr, server, priority, priority);
-
-    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
-}
-
-static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
-                          uint32_t token,
-                          uint32_t nargs, target_ulong args,
-                          uint32_t nret, target_ulong rets)
-{
-    ICSState *ics = spapr->xics->ics;
-    uint32_t nr;
-
-    if ((nargs != 1) || (nret != 3)) {
-        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
-        return;
-    }
-
-    nr = rtas_ld(args, 0);
-
-    if (!ics_valid_irq(ics, nr)) {
-        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
-        return;
-    }
-
-    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
-    rtas_st(rets, 1, ics->irqs[nr - ics->offset].server);
-    rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
-}
-
-static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
-                         uint32_t token,
-                         uint32_t nargs, target_ulong args,
-                         uint32_t nret, target_ulong rets)
-{
-    ICSState *ics = spapr->xics->ics;
-    uint32_t nr;
-
-    if ((nargs != 1) || (nret != 1)) {
-        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
-        return;
-    }
-
-    nr = rtas_ld(args, 0);
-
-    if (!ics_valid_irq(ics, nr)) {
-        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
-        return;
-    }
-
-    ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server, 0xff,
-                   ics->irqs[nr - ics->offset].priority);
-
-    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
-}
-
-static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
-                        uint32_t token,
-                        uint32_t nargs, target_ulong args,
-                        uint32_t nret, target_ulong rets)
-{
-    ICSState *ics = spapr->xics->ics;
-    uint32_t nr;
-
-    if ((nargs != 1) || (nret != 1)) {
-        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
-        return;
-    }
-
-    nr = rtas_ld(args, 0);
-
-    if (!ics_valid_irq(ics, nr)) {
-        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
-        return;
-    }
-
-    ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server,
-                   ics->irqs[nr - ics->offset].saved_priority,
-                   ics->irqs[nr - ics->offset].saved_priority);
-
-    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
-}
-
-static void xics_spapr_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
-                                   Error **errp)
-{
-    xics->nr_irqs = xics->ics->nr_irqs = nr_irqs;
-}
-
-static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
-                                      Error **errp)
-{
-    int i;
-
-    xics->nr_servers = nr_servers;
-
-    xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
-    for (i = 0; i < xics->nr_servers; i++) {
-        char buffer[32];
-        object_initialize(&xics->ss[i], sizeof(xics->ss[i]), TYPE_ICP);
-        snprintf(buffer, sizeof(buffer), "icp[%d]", i);
-        object_property_add_child(OBJECT(xics), buffer, OBJECT(&xics->ss[i]),
-                                  errp);
-    }
-}
-
-static void xics_spapr_realize(DeviceState *dev, Error **errp)
-{
-    XICSState *xics = XICS_SPAPR(dev);
-    Error *error = NULL;
-    int i;
-
-    if (!xics->nr_servers) {
-        error_setg(errp, "Number of servers needs to be greater 0");
-        return;
-    }
-
-    /* Registration of global state belongs into realize */
-    spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
-    spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);
-    spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_int_off);
-    spapr_rtas_register(RTAS_IBM_INT_ON, "ibm,int-on", rtas_int_on);
-
-    spapr_register_hypercall(H_CPPR, h_cppr);
-    spapr_register_hypercall(H_IPI, h_ipi);
-    spapr_register_hypercall(H_XIRR, h_xirr);
-    spapr_register_hypercall(H_XIRR_X, h_xirr_x);
-    spapr_register_hypercall(H_EOI, h_eoi);
-    spapr_register_hypercall(H_IPOLL, h_ipoll);
-
-    object_property_set_bool(OBJECT(xics->ics), true, "realized", &error);
-    if (error) {
-        error_propagate(errp, error);
-        return;
-    }
-
-    for (i = 0; i < xics->nr_servers; i++) {
-        object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
-                                 &error);
-        if (error) {
-            error_propagate(errp, error);
-            return;
-        }
-    }
-}
-
-static void xics_spapr_initfn(Object *obj)
-{
-    XICSState *xics = XICS_SPAPR(obj);
-
-    xics->ics = ICS(object_new(TYPE_ICS));
-    object_property_add_child(obj, "ics", OBJECT(xics->ics), NULL);
-    xics->ics->xics = xics;
-}
-
-static void xics_spapr_class_init(ObjectClass *oc, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(oc);
-    XICSStateClass *xsc = XICS_SPAPR_CLASS(oc);
-
-    dc->realize = xics_spapr_realize;
-    xsc->set_nr_irqs = xics_spapr_set_nr_irqs;
-    xsc->set_nr_servers = xics_spapr_set_nr_servers;
-}
-
-static const TypeInfo xics_spapr_info = {
-    .name          = TYPE_XICS_SPAPR,
-    .parent        = TYPE_XICS_COMMON,
-    .instance_size = sizeof(XICSState),
-    .class_size = sizeof(XICSStateClass),
-    .class_init    = xics_spapr_class_init,
-    .instance_init = xics_spapr_initfn,
-};
-
-#define ICS_IRQ_FREE(ics, srcno)   \
-    (!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK)))
-
-static int ics_find_free_block(ICSState *ics, int num, int alignnum)
-{
-    int first, i;
-
-    for (first = 0; first < ics->nr_irqs; first += alignnum) {
-        if (num > (ics->nr_irqs - first)) {
-            return -1;
-        }
-        for (i = first; i < first + num; ++i) {
-            if (!ICS_IRQ_FREE(ics, i)) {
-                break;
-            }
-        }
-        if (i == (first + num)) {
-            return first;
-        }
-    }
-
-    return -1;
-}
-
-int xics_spapr_alloc(XICSState *xics, int src, int irq_hint, bool lsi,
-                     Error **errp)
-{
-    ICSState *ics = &xics->ics[src];
-    int irq;
-
-    if (irq_hint) {
-        assert(src == xics_find_source(xics, irq_hint));
-        if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
-            error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint);
-            return -1;
-        }
-        irq = irq_hint;
-    } else {
-        irq = ics_find_free_block(ics, 1, 1);
-        if (irq < 0) {
-            error_setg(errp, "can't allocate IRQ: no IRQ left");
-            return -1;
-        }
-        irq += ics->offset;
-    }
-
-    ics_set_irq_type(ics, irq - ics->offset, lsi);
-    trace_xics_alloc(src, irq);
-
-    return irq;
-}
-
-/*
- * Allocate block of consecutive IRQs, and return the number of the first IRQ in
- * the block. If align==true, aligns the first IRQ number to num.
- */
-int xics_spapr_alloc_block(XICSState *xics, int src, int num, bool lsi,
-                           bool align, Error **errp)
-{
-    int i, first = -1;
-    ICSState *ics = &xics->ics[src];
-
-    assert(src == 0);
-    /*
-     * MSIMesage::data is used for storing VIRQ so
-     * it has to be aligned to num to support multiple
-     * MSI vectors. MSI-X is not affected by this.
-     * The hint is used for the first IRQ, the rest should
-     * be allocated continuously.
-     */
-    if (align) {
-        assert((num == 1) || (num == 2) || (num == 4) ||
-               (num == 8) || (num == 16) || (num == 32));
-        first = ics_find_free_block(ics, num, num);
-    } else {
-        first = ics_find_free_block(ics, num, 1);
-    }
-    if (first < 0) {
-        error_setg(errp, "can't find a free %d-IRQ block", num);
-        return -1;
-    }
-
-    if (first >= 0) {
-        for (i = first; i < first + num; ++i) {
-            ics_set_irq_type(ics, i, lsi);
-        }
-    }
-    first += ics->offset;
-
-    trace_xics_alloc_block(src, first, num, lsi, align);
-
-    return first;
-}
-
-static void ics_free(ICSState *ics, int srcno, int num)
-{
-    int i;
-
-    for (i = srcno; i < srcno + num; ++i) {
-        if (ICS_IRQ_FREE(ics, i)) {
-            trace_xics_ics_free_warn(ics - ics->xics->ics, i + ics->offset);
-        }
-        memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
-    }
-}
-
-void xics_spapr_free(XICSState *xics, int irq, int num)
-{
-    int src = xics_find_source(xics, irq);
-
-    if (src >= 0) {
-        ICSState *ics = &xics->ics[src];
-
-        /* FIXME: implement multiple sources */
-        assert(src == 0);
-
-        trace_xics_ics_free(ics - xics->ics, irq, num);
-        ics_free(ics, irq - ics->offset, num);
-    }
-}
-
-static void xics_spapr_register_types(void)
-{
-    type_register_static(&xics_spapr_info);
-}
-
-type_init(xics_spapr_register_types)
index 6021e6d..5f99ed9 100644 (file)
@@ -2,7 +2,7 @@
  * QEMU IndustryPack emulation
  *
  * Copyright (C) 2012 Igalia, S.L.
- * Author: Alberto Garcia <berto@igalia.com>
+ * Author: Alberto Garcia <agarcia@igalia.com>
  *
  * This code is licensed under the GNU GPL v2 or (at your option) any
  * later version.
index 4dfa6b3..fdda6f4 100644 (file)
@@ -2,7 +2,7 @@
  * QEMU TEWS TPCI200 IndustryPack carrier emulation
  *
  * Copyright (C) 2012 Igalia, S.L.
- * Author: Alberto Garcia <berto@igalia.com>
+ * Author: Alberto Garcia <agarcia@igalia.com>
  *
  * This code is licensed under the GNU GPL v2 or (at your option) any
  * later version.
index f09f217..6adec1e 100644 (file)
 #include "qom/object_interfaces.h"
 #include "qapi/visitor.h"
 
-static uint32_t ipmi_current_uuid = 1;
-
-uint32_t ipmi_next_uuid(void)
-{
-    return ipmi_current_uuid++;
-}
-
 static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly)
 {
     switch (op) {
@@ -129,3 +122,30 @@ static void ipmi_register_types(void)
 }
 
 type_init(ipmi_register_types)
+
+static IPMIFwInfo *ipmi_fw_info;
+static unsigned int ipmi_fw_info_len;
+
+static uint32_t current_uuid = 1;
+
+void ipmi_add_fwinfo(IPMIFwInfo *info, Error **errp)
+{
+    info->uuid = current_uuid++;
+    ipmi_fw_info = g_realloc(ipmi_fw_info,
+                             sizeof(*ipmi_fw_info) * (ipmi_fw_info_len + 1));
+    ipmi_fw_info[ipmi_fw_info_len] = *info;
+}
+
+IPMIFwInfo *ipmi_first_fwinfo(void)
+{
+    return ipmi_fw_info;
+}
+
+IPMIFwInfo *ipmi_next_fwinfo(IPMIFwInfo *current)
+{
+    current++;
+    if (current >= &ipmi_fw_info[ipmi_fw_info_len]) {
+        return NULL;
+    }
+    return current;
+}
index 157879e..fe12112 100644 (file)
@@ -190,7 +190,7 @@ static void ipmi_bmc_extern_handle_command(IPMIBmc *b,
     if (ibe->outlen) {
         /* We already have a command queued.  Shouldn't ever happen. */
         fprintf(stderr, "IPMI KCS: Got command when not finished with the"
-                " previous command\n");
+                " previous commmand\n");
         abort();
     }
 
index f036617..aaea12e 100644 (file)
@@ -390,6 +390,16 @@ static void ipmi_bt_init(IPMIInterface *ii, Error **errp)
     memory_region_init_io(&ib->io, NULL, &ipmi_bt_io_ops, ii, "ipmi-bt", 3);
 }
 
+static void ipmi_bt_class_init(IPMIInterfaceClass *iic)
+{
+    iic->init = ipmi_bt_init;
+    iic->set_atn = ipmi_bt_set_atn;
+    iic->handle_rsp = ipmi_bt_handle_rsp;
+    iic->handle_if_event = ipmi_bt_handle_event;
+    iic->set_irq_enable = ipmi_bt_set_irq_enable;
+    iic->reset = ipmi_bt_handle_reset;
+}
+
 
 #define TYPE_ISA_IPMI_BT "isa-ipmi-bt"
 #define ISA_IPMI_BT(obj) OBJECT_CHECK(ISAIPMIBTDevice, (obj), \
@@ -399,38 +409,9 @@ typedef struct ISAIPMIBTDevice {
     ISADevice dev;
     int32_t isairq;
     IPMIBT bt;
-    uint32_t uuid;
+    IPMIFwInfo fwinfo;
 } ISAIPMIBTDevice;
 
-static void ipmi_bt_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info)
-{
-    ISAIPMIBTDevice *iib = ISA_IPMI_BT(ii);
-
-    info->interface_name = "bt";
-    info->interface_type = IPMI_SMBIOS_BT;
-    info->ipmi_spec_major_revision = 2;
-    info->ipmi_spec_minor_revision = 0;
-    info->base_address = iib->bt.io_base;
-    info->register_length = iib->bt.io_length;
-    info->register_spacing = 1;
-    info->memspace = IPMI_MEMSPACE_IO;
-    info->irq_type = IPMI_LEVEL_IRQ;
-    info->interrupt_number = iib->isairq;
-    info->i2c_slave_address = iib->bt.bmc->slave_addr;
-    info->uuid = iib->uuid;
-}
-
-static void ipmi_bt_class_init(IPMIInterfaceClass *iic)
-{
-    iic->init = ipmi_bt_init;
-    iic->set_atn = ipmi_bt_set_atn;
-    iic->handle_rsp = ipmi_bt_handle_rsp;
-    iic->handle_if_event = ipmi_bt_handle_event;
-    iic->set_irq_enable = ipmi_bt_set_irq_enable;
-    iic->reset = ipmi_bt_handle_reset;
-    iic->get_fwinfo = ipmi_bt_get_fwinfo;
-}
-
 static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
 {
     ISADevice *isadev = ISA_DEVICE(dev);
@@ -443,8 +424,6 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    iib->uuid = ipmi_next_uuid();
-
     iib->bt.bmc->intf = ii;
 
     iic->init(ii, errp);
@@ -459,6 +438,20 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
     qdev_set_legacy_instance_id(dev, iib->bt.io_base, iib->bt.io_length);
 
     isa_register_ioport(isadev, &iib->bt.io, iib->bt.io_base);
+
+    iib->fwinfo.interface_name = "bt";
+    iib->fwinfo.interface_type = IPMI_SMBIOS_BT;
+    iib->fwinfo.ipmi_spec_major_revision = 2;
+    iib->fwinfo.ipmi_spec_minor_revision = 0;
+    iib->fwinfo.base_address = iib->bt.io_base;
+    iib->fwinfo.register_length = iib->bt.io_length;
+    iib->fwinfo.register_spacing = 1;
+    iib->fwinfo.memspace = IPMI_MEMSPACE_IO;
+    iib->fwinfo.irq_type = IPMI_LEVEL_IRQ;
+    iib->fwinfo.interrupt_number = iib->isairq;
+    iib->fwinfo.acpi_parent = "\\_SB.PCI0.ISA";
+    iib->fwinfo.i2c_slave_address = iib->bt.bmc->slave_addr;
+    ipmi_add_fwinfo(&iib->fwinfo, errp);
 }
 
 static const VMStateDescription vmstate_ISAIPMIBTDevice = {
index 9a38f8a..2742ce0 100644 (file)
@@ -354,6 +354,16 @@ static void ipmi_kcs_init(IPMIInterface *ii, Error **errp)
     memory_region_init_io(&ik->io, NULL, &ipmi_kcs_io_ops, ii, "ipmi-kcs", 2);
 }
 
+static void ipmi_kcs_class_init(IPMIInterfaceClass *iic)
+{
+    iic->init = ipmi_kcs_init;
+    iic->set_atn = ipmi_kcs_set_atn;
+    iic->handle_rsp = ipmi_kcs_handle_rsp;
+    iic->handle_if_event = ipmi_kcs_handle_event;
+    iic->set_irq_enable = ipmi_kcs_set_irq_enable;
+}
+
+
 #define TYPE_ISA_IPMI_KCS "isa-ipmi-kcs"
 #define ISA_IPMI_KCS(obj) OBJECT_CHECK(ISAIPMIKCSDevice, (obj), \
                                        TYPE_ISA_IPMI_KCS)
@@ -362,37 +372,9 @@ typedef struct ISAIPMIKCSDevice {
     ISADevice dev;
     int32_t isairq;
     IPMIKCS kcs;
-    uint32_t uuid;
+    IPMIFwInfo fwinfo;
 } ISAIPMIKCSDevice;
 
-static void ipmi_kcs_get_fwinfo(IPMIInterface *ii, IPMIFwInfo *info)
-{
-    ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(ii);
-
-    info->interface_name = "kcs";
-    info->interface_type = IPMI_SMBIOS_KCS;
-    info->ipmi_spec_major_revision = 2;
-    info->ipmi_spec_minor_revision = 0;
-    info->base_address = iik->kcs.io_base;
-    info->i2c_slave_address = iik->kcs.bmc->slave_addr;
-    info->register_length = iik->kcs.io_length;
-    info->register_spacing = 1;
-    info->memspace = IPMI_MEMSPACE_IO;
-    info->irq_type = IPMI_LEVEL_IRQ;
-    info->interrupt_number = iik->isairq;
-    info->uuid = iik->uuid;
-}
-
-static void ipmi_kcs_class_init(IPMIInterfaceClass *iic)
-{
-    iic->init = ipmi_kcs_init;
-    iic->set_atn = ipmi_kcs_set_atn;
-    iic->handle_rsp = ipmi_kcs_handle_rsp;
-    iic->handle_if_event = ipmi_kcs_handle_event;
-    iic->set_irq_enable = ipmi_kcs_set_irq_enable;
-    iic->get_fwinfo = ipmi_kcs_get_fwinfo;
-}
-
 static void ipmi_isa_realize(DeviceState *dev, Error **errp)
 {
     ISADevice *isadev = ISA_DEVICE(dev);
@@ -405,8 +387,6 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    iik->uuid = ipmi_next_uuid();
-
     iik->kcs.bmc->intf = ii;
 
     iic->init(ii, errp);
@@ -421,6 +401,20 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp)
     qdev_set_legacy_instance_id(dev, iik->kcs.io_base, iik->kcs.io_length);
 
     isa_register_ioport(isadev, &iik->kcs.io, iik->kcs.io_base);
+
+    iik->fwinfo.interface_name = "kcs";
+    iik->fwinfo.interface_type = IPMI_SMBIOS_KCS;
+    iik->fwinfo.ipmi_spec_major_revision = 2;
+    iik->fwinfo.ipmi_spec_minor_revision = 0;
+    iik->fwinfo.base_address = iik->kcs.io_base;
+    iik->fwinfo.i2c_slave_address = iik->kcs.bmc->slave_addr;
+    iik->fwinfo.register_length = iik->kcs.io_length;
+    iik->fwinfo.register_spacing = 1;
+    iik->fwinfo.memspace = IPMI_MEMSPACE_IO;
+    iik->fwinfo.irq_type = IPMI_LEVEL_IRQ;
+    iik->fwinfo.interrupt_number = iik->isairq;
+    iik->fwinfo.acpi_parent = "\\_SB.PCI0.ISA";
+    ipmi_add_fwinfo(&iik->fwinfo, errp);
 }
 
 const VMStateDescription vmstate_ISAIPMIKCSDevice = {
index ce74db2..7aa115c 100644 (file)
@@ -97,13 +97,6 @@ void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq)
     dev->nirqs++;
 }
 
-void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, int isairq)
-{
-    qemu_irq irq;
-    isa_init_irq(isadev, &irq, isairq);
-    qdev_connect_gpio_out(DEVICE(isadev), gpioirq, irq);
-}
-
 void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16)
 {
     assert(bus && dma8 && dma16);
index 10d1ee8..99cd3ba 100644 (file)
@@ -47,7 +47,8 @@
 #include "hw/pci/pci_bus.h"
 #include "exec/address-spaces.h"
 #include "sysemu/sysemu.h"
-#include "qom/cpu.h"
+
+static int ich9_lpc_sci_irq(ICH9LPCState *lpc);
 
 /*****************************************************************************/
 /* ICH9 LPC PCI to ISA bridge */
@@ -95,8 +96,8 @@ static void ich9_cc_update(ICH9LPCState *lpc)
 
     /*
      * D30: DMI2PCI bridge
-     * It is arbitrarily decided how INTx lines of PCI devices behind
-     * the bridge are connected to pirq lines. Our choice is PIRQ[E-H].
+     * It is arbitrarily decided how INTx lines of PCI devicesbehind the bridge
+     * are connected to pirq lines. Our choice is PIRQ[E-H].
      * INT[A-D] are connected to PIRQ[E-H]
      */
     for (pci_intx = 0; pci_intx < PCI_NUM_PINS; pci_intx++) {
@@ -202,28 +203,41 @@ static void ich9_lpc_pic_irq(ICH9LPCState *lpc, int pirq_num,
     abort();
 }
 
-/* gsi: i8259+ioapic irq 0-15, otherwise assert */
-static void ich9_lpc_update_pic(ICH9LPCState *lpc, int gsi)
+/* pic_irq: i8254 irq 0-15 */
+static void ich9_lpc_update_pic(ICH9LPCState *lpc, int pic_irq)
 {
     int i, pic_level;
 
-    assert(gsi < ICH9_LPC_PIC_NUM_PINS);
-
     /* The pic level is the logical OR of all the PCI irqs mapped to it */
     pic_level = 0;
     for (i = 0; i < ICH9_LPC_NB_PIRQS; i++) {
         int tmp_irq;
         int tmp_dis;
         ich9_lpc_pic_irq(lpc, i, &tmp_irq, &tmp_dis);
-        if (!tmp_dis && tmp_irq == gsi) {
+        if (!tmp_dis && pic_irq == tmp_irq) {
             pic_level |= pci_bus_get_irq_level(lpc->d.bus, i);
         }
     }
-    if (gsi == lpc->sci_gsi) {
+    if (pic_irq == ich9_lpc_sci_irq(lpc)) {
         pic_level |= lpc->sci_level;
     }
 
-    qemu_set_irq(lpc->gsi[gsi], pic_level);
+    qemu_set_irq(lpc->pic[pic_irq], pic_level);
+}
+
+/* pirq: pirq[A-H] 0-7*/
+static void ich9_lpc_update_by_pirq(ICH9LPCState *lpc, int pirq)
+{
+    int pic_irq;
+    int pic_dis;
+
+    ich9_lpc_pic_irq(lpc, pirq, &pic_irq, &pic_dis);
+    assert(pic_irq < ICH9_LPC_PIC_NUM_PINS);
+    if (pic_dis) {
+        return;
+    }
+
+    ich9_lpc_update_pic(lpc, pic_irq);
 }
 
 /* APIC mode: GSIx: PIRQ[A-H] -> GSI 16, ... no pirq shares same APIC pins. */
@@ -237,32 +251,29 @@ static int ich9_gsi_to_pirq(int gsi)
     return gsi - ICH9_LPC_PIC_NUM_PINS;
 }
 
-/* gsi: ioapic irq 16-23, otherwise assert */
 static void ich9_lpc_update_apic(ICH9LPCState *lpc, int gsi)
 {
     int level = 0;
 
-    assert(gsi >= ICH9_LPC_PIC_NUM_PINS);
-
-    level |= pci_bus_get_irq_level(lpc->d.bus, ich9_gsi_to_pirq(gsi));
-    if (gsi == lpc->sci_gsi) {
+    if (gsi >= ICH9_LPC_PIC_NUM_PINS) {
+        level |= pci_bus_get_irq_level(lpc->d.bus, ich9_gsi_to_pirq(gsi));
+    }
+    if (gsi == ich9_lpc_sci_irq(lpc)) {
         level |= lpc->sci_level;
     }
 
-    qemu_set_irq(lpc->gsi[gsi], level);
+    qemu_set_irq(lpc->ioapic[gsi], level);
 }
 
 void ich9_lpc_set_irq(void *opaque, int pirq, int level)
 {
     ICH9LPCState *lpc = opaque;
-    int pic_irq, pic_dis;
 
     assert(0 <= pirq);
     assert(pirq < ICH9_LPC_NB_PIRQS);
 
     ich9_lpc_update_apic(lpc, ich9_pirq_to_gsi(pirq));
-    ich9_lpc_pic_irq(lpc, pirq, &pic_irq, &pic_dis);
-    ich9_lpc_update_pic(lpc, pic_irq);
+    ich9_lpc_update_by_pirq(lpc, pirq);
 }
 
 /* return the pirq number (PIRQ[A-H]:0-7) corresponding to
@@ -348,14 +359,13 @@ static void ich9_set_sci(void *opaque, int irq_num, int level)
     }
     lpc->sci_level = level;
 
-    irq = lpc->sci_gsi;
+    irq = ich9_lpc_sci_irq(lpc);
     if (irq < 0) {
         return;
     }
 
-    if (irq >= ICH9_LPC_PIC_NUM_PINS) {
-        ich9_lpc_update_apic(lpc, irq);
-    } else {
+    ich9_lpc_update_apic(lpc, irq);
+    if (irq < ICH9_LPC_PIC_NUM_PINS) {
         ich9_lpc_update_pic(lpc, irq);
     }
 }
@@ -392,27 +402,12 @@ static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
 
 /* config:PMBASE */
 static void
-ich9_lpc_pmbase_sci_update(ICH9LPCState *lpc)
+ich9_lpc_pmbase_update(ICH9LPCState *lpc)
 {
     uint32_t pm_io_base = pci_get_long(lpc->d.config + ICH9_LPC_PMBASE);
-    uint8_t acpi_cntl = pci_get_long(lpc->d.config + ICH9_LPC_ACPI_CTRL);
-    uint8_t new_gsi;
-
-    if (acpi_cntl & ICH9_LPC_ACPI_CTRL_ACPI_EN) {
-        pm_io_base &= ICH9_LPC_PMBASE_BASE_ADDRESS_MASK;
-    } else {
-        pm_io_base = 0;
-    }
+    pm_io_base &= ICH9_LPC_PMBASE_BASE_ADDRESS_MASK;
 
     ich9_pm_iospace_update(&lpc->pm, pm_io_base);
-
-    new_gsi = ich9_lpc_sci_irq(lpc);
-    if (lpc->sci_level && new_gsi != lpc->sci_gsi) {
-        qemu_set_irq(lpc->pm.irq, 0);
-        lpc->sci_gsi = new_gsi;
-        qemu_set_irq(lpc->pm.irq, 1);
-    }
-    lpc->sci_gsi = new_gsi;
 }
 
 /* config:RCBA */
@@ -449,7 +444,7 @@ static int ich9_lpc_post_load(void *opaque, int version_id)
 {
     ICH9LPCState *lpc = opaque;
 
-    ich9_lpc_pmbase_sci_update(lpc);
+    ich9_lpc_pmbase_update(lpc);
     ich9_lpc_rcba_update(lpc, 0 /* disabled ICH9_LPC_RCBA_EN */);
     ich9_lpc_pmcon_update(lpc);
     return 0;
@@ -462,9 +457,8 @@ static void ich9_lpc_config_write(PCIDevice *d,
     uint32_t rcba_old = pci_get_long(d->config + ICH9_LPC_RCBA);
 
     pci_default_write_config(d, addr, val, len);
-    if (ranges_overlap(addr, len, ICH9_LPC_PMBASE, 4) ||
-        ranges_overlap(addr, len, ICH9_LPC_ACPI_CTRL, 1)) {
-        ich9_lpc_pmbase_sci_update(lpc);
+    if (ranges_overlap(addr, len, ICH9_LPC_PMBASE, 4)) {
+        ich9_lpc_pmbase_update(lpc);
     }
     if (ranges_overlap(addr, len, ICH9_LPC_RCBA, 4)) {
         ich9_lpc_rcba_update(lpc, rcba_old);
@@ -502,7 +496,7 @@ static void ich9_lpc_reset(DeviceState *qdev)
 
     ich9_cc_reset(lpc);
 
-    ich9_lpc_pmbase_sci_update(lpc);
+    ich9_lpc_pmbase_update(lpc);
     ich9_lpc_rcba_update(lpc, rcba_old);
 
     lpc->sci_level = 0;
@@ -582,7 +576,7 @@ static void ich9_lpc_get_sci_int(Object *obj, Visitor *v, const char *name,
                                  void *opaque, Error **errp)
 {
     ICH9LPCState *lpc = ICH9_LPC_DEVICE(obj);
-    uint32_t value = lpc->sci_gsi;
+    uint32_t value = ich9_lpc_sci_irq(lpc);
 
     visit_type_uint32(v, name, &value, errp);
 }
@@ -613,7 +607,6 @@ static void ich9_lpc_initfn(Object *obj)
 static void ich9_lpc_realize(PCIDevice *d, Error **errp)
 {
     ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
-    DeviceState *dev = DEVICE(d);
     ISABus *isa_bus;
 
     isa_bus = isa_bus_new(DEVICE(d), get_system_memory(), get_system_io(),
@@ -624,9 +617,6 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp)
 
     pci_set_long(d->wmask + ICH9_LPC_PMBASE,
                  ICH9_LPC_PMBASE_BASE_ADDRESS_MASK);
-    pci_set_byte(d->wmask + ICH9_LPC_PMBASE,
-                 ICH9_LPC_ACPI_CTRL_ACPI_EN |
-                 ICH9_LPC_ACPI_CTRL_SCI_IRQ_SEL_MASK);
 
     memory_region_init_io(&lpc->rcrb_mem, OBJECT(d), &rcrb_mmio_ops, lpc,
                           "lpc-rcrb-mmio", ICH9_CC_SIZE);
@@ -644,10 +634,30 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp)
     memory_region_add_subregion_overlap(pci_address_space_io(d),
                                         ICH9_RST_CNT_IOPORT, &lpc->rst_cnt_mem,
                                         1);
+}
+
+static void ich9_device_plug_cb(HotplugHandler *hotplug_dev,
+                                DeviceState *dev, Error **errp)
+{
+    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
+
+    ich9_pm_device_plug_cb(&lpc->pm, dev, errp);
+}
 
-    qdev_init_gpio_out_named(dev, lpc->gsi, ICH9_GPIO_GSI, GSI_NUM_PINS);
+static void ich9_device_unplug_request_cb(HotplugHandler *hotplug_dev,
+                                          DeviceState *dev, Error **errp)
+{
+    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
+
+    ich9_pm_device_unplug_request_cb(&lpc->pm, dev, errp);
+}
+
+static void ich9_device_unplug_cb(HotplugHandler *hotplug_dev,
+                                  DeviceState *dev, Error **errp)
+{
+    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
 
-    isa_bus_irqs(isa_bus, lpc->gsi);
+    ich9_pm_device_unplug_cb(&lpc->pm, dev, errp);
 }
 
 static bool ich9_rst_cnt_needed(void *opaque)
@@ -692,13 +702,6 @@ static Property ich9_lpc_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static void ich9_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
-{
-    ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
-
-    acpi_send_gpe_event(&s->pm.acpi_regs, s->pm.irq, ev);
-}
-
 static void ich9_lpc_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -722,12 +725,10 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
      * pc_q35_init()
      */
     dc->cannot_instantiate_with_device_add_yet = true;
-    hc->plug = ich9_pm_device_plug_cb;
-    hc->unplug_request = ich9_pm_device_unplug_request_cb;
-    hc->unplug = ich9_pm_device_unplug_cb;
+    hc->plug = ich9_device_plug_cb;
+    hc->unplug_request = ich9_device_unplug_request_cb;
+    hc->unplug = ich9_device_unplug_cb;
     adevc->ospm_status = ich9_pm_ospm_status;
-    adevc->send_event = ich9_send_gpe;
-    adevc->madt_cpu = pc_madt_cpu_entry;
 }
 
 static const TypeInfo ich9_lpc_info = {
diff --git a/hw/isa/trace-events b/hw/isa/trace-events
deleted file mode 100644 (file)
index 9faca41..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/isa/pc87312.c
-pc87312_io_read(uint32_t addr, uint32_t val) "read addr=%x val=%x"
-pc87312_io_write(uint32_t addr, uint32_t val) "write addr=%x val=%x"
-pc87312_info_floppy(uint32_t base) "base 0x%x"
-pc87312_info_ide(uint32_t base) "base 0x%x"
-pc87312_info_parallel(uint32_t base, uint32_t irq) "base 0x%x, irq %u"
-pc87312_info_serial(int n, uint32_t base, uint32_t irq) "id=%d, base 0x%x, irq %u"
index db9eb29..18aa6fd 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef HW_LM32_H
-#define HW_LM32_H
+#define HW_LM32_H 1
 
 #include "hw/char/lm32_juart.h"
 
@@ -16,31 +16,14 @@ static inline DeviceState *lm32_pic_init(qemu_irq cpu_irq)
     return dev;
 }
 
-static inline DeviceState *lm32_juart_init(CharDriverState *chr)
+static inline DeviceState *lm32_juart_init(void)
 {
     DeviceState *dev;
 
     dev = qdev_create(NULL, TYPE_LM32_JUART);
-    qdev_prop_set_chr(dev, "chardev", chr);
     qdev_init_nofail(dev);
 
     return dev;
 }
 
-static inline DeviceState *lm32_uart_create(hwaddr addr,
-                                            qemu_irq irq,
-                                            CharDriverState *chr)
-{
-    DeviceState *dev;
-    SysBusDevice *s;
-
-    dev = qdev_create(NULL, "lm32-uart");
-    s = SYS_BUS_DEVICE(dev);
-    qdev_prop_set_chr(dev, "chardev", chr);
-    qdev_init_nofail(dev);
-    sysbus_mmio_map(s, 0, addr);
-    sysbus_connect_irq(s, 0, irq);
-    return dev;
-}
-
 #endif
index 8f0c307..c029056 100644 (file)
@@ -31,7 +31,6 @@
 #include "lm32_hwsetup.h"
 #include "lm32.h"
 #include "exec/address-spaces.h"
-#include "sysemu/sysemu.h"
 
 typedef struct {
     LM32CPU *cpu;
@@ -132,12 +131,12 @@ static void lm32_evr_init(MachineState *machine)
         irq[i] = qdev_get_gpio_in(env->pic_state, i);
     }
 
-    lm32_uart_create(uart0_base, irq[uart0_irq], serial_hds[0]);
+    sysbus_create_simple("lm32-uart", uart0_base, irq[uart0_irq]);
     sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]);
     sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]);
 
     /* make sure juart isn't the first chardev */
-    env->juart_state = lm32_juart_init(serial_hds[1]);
+    env->juart_state = lm32_juart_init();
 
     reset_info->bootstrap_pc = flash_base;
 
@@ -233,13 +232,13 @@ static void lm32_uclinux_init(MachineState *machine)
         irq[i] = qdev_get_gpio_in(env->pic_state, i);
     }
 
-    lm32_uart_create(uart0_base, irq[uart0_irq], serial_hds[0]);
+    sysbus_create_simple("lm32-uart", uart0_base, irq[uart0_irq]);
     sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]);
     sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]);
     sysbus_create_simple("lm32-timer", timer2_base, irq[timer2_irq]);
 
     /* make sure juart isn't the first chardev */
-    env->juart_state = lm32_juart_init(serial_hds[1]);
+    env->juart_state = lm32_juart_init();
 
     reset_info->bootstrap_pc = flash_base;
 
index 4418b44..c8dfb4d 100644 (file)
@@ -1,17 +1,15 @@
-#ifndef QEMU_HW_MILKYMIST_HW_H
-#define QEMU_HW_MILKYMIST_HW_H
+#ifndef QEMU_HW_MILKYMIST_H
+#define QEMU_HW_MILKYMIST_H
 
 #include "hw/qdev.h"
 #include "net/net.h"
 
 static inline DeviceState *milkymist_uart_create(hwaddr base,
-                                                 qemu_irq irq,
-                                                 CharDriverState *chr)
+        qemu_irq irq)
 {
     DeviceState *dev;
 
     dev = qdev_create(NULL, "milkymist-uart");
-    qdev_prop_set_chr(dev, "chardev", chr);
     qdev_init_nofail(dev);
     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
@@ -110,6 +108,10 @@ static inline DeviceState *milkymist_tmu2_create(hwaddr base,
     int nelements;
     int ver_major, ver_minor;
 
+    if (display_type == DT_NOGRAPHIC) {
+        return NULL;
+    }
+
     /* check that GLX will work */
     d = XOpenDisplay(NULL);
     if (d == NULL) {
@@ -203,4 +205,4 @@ static inline DeviceState *milkymist_softusb_create(hwaddr base,
     return dev;
 }
 
-#endif /* QEMU_HW_MILKYMIST_HW_H */
+#endif /* QEMU_HW_MILKYMIST_H */
index 5cae0f1..96e6f4d 100644 (file)
@@ -159,7 +159,7 @@ milkymist_init(MachineState *machine)
     }
     g_free(bios_filename);
 
-    milkymist_uart_create(0x60000000, irq[0], serial_hds[0]);
+    milkymist_uart_create(0x60000000, irq[0]);
     milkymist_sysctl_create(0x60001000, irq[1], irq[2], irq[3],
             80000000, 0x10014d31, 0x0000041f, 0x00000001);
     milkymist_hpdmc_create(0x60002000);
@@ -167,15 +167,13 @@ milkymist_init(MachineState *machine)
     milkymist_memcard_create(0x60004000);
     milkymist_ac97_create(0x60005000, irq[4], irq[5], irq[6], irq[7]);
     milkymist_pfpu_create(0x60006000, irq[8]);
-    if (machine->enable_graphics) {
-        milkymist_tmu2_create(0x60007000, irq[9]);
-    }
+    milkymist_tmu2_create(0x60007000, irq[9]);
     milkymist_minimac2_create(0x60008000, 0x30000000, irq[10], irq[11]);
     milkymist_softusb_create(0x6000f000, irq[15],
             0x20000000, 0x1000, 0x20020000, 0x2000);
 
     /* make sure juart isn't the first chardev */
-    env->juart_state = lm32_juart_init(serial_hds[1]);
+    env->juart_state = lm32_juart_init();
 
     if (kernel_filename) {
         uint64_t entry;
index 7895805..0a602f2 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qapi/visitor.h"
 #include "hw/mem/nvdimm.h"
 
-static void nvdimm_get_label_size(Object *obj, Visitor *v, const char *name,
-                                  void *opaque, Error **errp)
-{
-    NVDIMMDevice *nvdimm = NVDIMM(obj);
-    uint64_t value = nvdimm->label_size;
-
-    visit_type_size(v, name, &value, errp);
-}
-
-static void nvdimm_set_label_size(Object *obj, Visitor *v, const char *name,
-                                  void *opaque, Error **errp)
-{
-    NVDIMMDevice *nvdimm = NVDIMM(obj);
-    Error *local_err = NULL;
-    uint64_t value;
-
-    if (memory_region_size(&nvdimm->nvdimm_mr)) {
-        error_setg(&local_err, "cannot change property value");
-        goto out;
-    }
-
-    visit_type_size(v, name, &value, &local_err);
-    if (local_err) {
-        goto out;
-    }
-    if (value < MIN_NAMESPACE_LABEL_SIZE) {
-        error_setg(&local_err, "Property '%s.%s' (0x%" PRIx64 ") is required"
-                   " at least 0x%lx", object_get_typename(obj),
-                   name, value, MIN_NAMESPACE_LABEL_SIZE);
-        goto out;
-    }
-
-    nvdimm->label_size = value;
-out:
-    error_propagate(errp, local_err);
-}
-
-static void nvdimm_init(Object *obj)
-{
-    object_property_add(obj, "label-size", "int",
-                        nvdimm_get_label_size, nvdimm_set_label_size, NULL,
-                        NULL, NULL);
-}
-
-static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm)
-{
-    NVDIMMDevice *nvdimm = NVDIMM(dimm);
-
-    return &nvdimm->nvdimm_mr;
-}
-
-static void nvdimm_realize(PCDIMMDevice *dimm, Error **errp)
-{
-    MemoryRegion *mr = host_memory_backend_get_memory(dimm->hostmem, errp);
-    NVDIMMDevice *nvdimm = NVDIMM(dimm);
-    uint64_t align, pmem_size, size = memory_region_size(mr);
-
-    align = memory_region_get_alignment(mr);
-
-    pmem_size = size - nvdimm->label_size;
-    nvdimm->label_data = memory_region_get_ram_ptr(mr) + pmem_size;
-    pmem_size = QEMU_ALIGN_DOWN(pmem_size, align);
-
-    if (size <= nvdimm->label_size || !pmem_size) {
-        HostMemoryBackend *hostmem = dimm->hostmem;
-        char *path = object_get_canonical_path_component(OBJECT(hostmem));
-
-        error_setg(errp, "the size of memdev %s (0x%" PRIx64 ") is too "
-                   "small to contain nvdimm label (0x%" PRIx64 ") and "
-                   "aligned PMEM (0x%" PRIx64 ")",
-                   path, memory_region_size(mr), nvdimm->label_size, align);
-        g_free(path);
-        return;
-    }
-
-    memory_region_init_alias(&nvdimm->nvdimm_mr, OBJECT(dimm),
-                             "nvdimm-memory", mr, 0, pmem_size);
-    nvdimm->nvdimm_mr.align = align;
-}
-
-/*
- * the caller should check the input parameters before calling
- * label read/write functions.
- */
-static void nvdimm_validate_rw_label_data(NVDIMMDevice *nvdimm, uint64_t size,
-                                        uint64_t offset)
-{
-    assert((nvdimm->label_size >= size + offset) && (offset + size > offset));
-}
-
-static void nvdimm_read_label_data(NVDIMMDevice *nvdimm, void *buf,
-                                   uint64_t size, uint64_t offset)
-{
-    nvdimm_validate_rw_label_data(nvdimm, size, offset);
-
-    memcpy(buf, nvdimm->label_data + offset, size);
-}
-
-static void nvdimm_write_label_data(NVDIMMDevice *nvdimm, const void *buf,
-                                    uint64_t size, uint64_t offset)
-{
-    MemoryRegion *mr;
-    PCDIMMDevice *dimm = PC_DIMM(nvdimm);
-    uint64_t backend_offset;
-
-    nvdimm_validate_rw_label_data(nvdimm, size, offset);
-
-    memcpy(nvdimm->label_data + offset, buf, size);
-
-    mr = host_memory_backend_get_memory(dimm->hostmem, &error_abort);
-    backend_offset = memory_region_size(mr) - nvdimm->label_size + offset;
-    memory_region_set_dirty(mr, backend_offset, size);
-}
-
-static MemoryRegion *nvdimm_get_vmstate_memory_region(PCDIMMDevice *dimm)
-{
-    return host_memory_backend_get_memory(dimm->hostmem, &error_abort);
-}
-
 static void nvdimm_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
-    PCDIMMDeviceClass *ddc = PC_DIMM_CLASS(oc);
-    NVDIMMClass *nvc = NVDIMM_CLASS(oc);
 
     /* nvdimm hotplug has not been supported yet. */
     dc->hotpluggable = false;
-
-    ddc->realize = nvdimm_realize;
-    ddc->get_memory_region = nvdimm_get_memory_region;
-    ddc->get_vmstate_memory_region = nvdimm_get_vmstate_memory_region;
-
-    nvc->read_label_data = nvdimm_read_label_data;
-    nvc->write_label_data = nvdimm_write_label_data;
 }
 
 static TypeInfo nvdimm_info = {
     .name          = TYPE_NVDIMM,
     .parent        = TYPE_PC_DIMM,
-    .class_size    = sizeof(NVDIMMClass),
     .class_init    = nvdimm_class_init,
-    .instance_size = sizeof(NVDIMMDevice),
-    .instance_init = nvdimm_init,
 };
 
 static void nvdimm_register_types(void)
index 9e8dab0..9e7de56 100644 (file)
@@ -40,8 +40,6 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
     int slot;
     MachineState *machine = MACHINE(qdev_get_machine());
     PCDIMMDevice *dimm = PC_DIMM(dev);
-    PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
-    MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm);
     Error *local_err = NULL;
     uint64_t existing_dimms_capacity = 0;
     uint64_t addr;
@@ -107,7 +105,7 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
     }
 
     memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr);
-    vmstate_register_ram(vmstate_mr, dev);
+    vmstate_register_ram(mr, dev);
     numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);
 
 out:
@@ -118,12 +116,10 @@ void pc_dimm_memory_unplug(DeviceState *dev, MemoryHotplugState *hpms,
                            MemoryRegion *mr)
 {
     PCDIMMDevice *dimm = PC_DIMM(dev);
-    PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
-    MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm);
 
     numa_unset_mem_node_id(dimm->addr, memory_region_size(mr), dimm->node);
     memory_region_del_subregion(&hpms->mr, mr);
-    vmstate_unregister_ram(vmstate_mr, dev);
+    vmstate_unregister_ram(mr, dev);
 }
 
 static int pc_existing_dimms_capacity_internal(Object *obj, void *opaque)
@@ -358,9 +354,8 @@ static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name,
     int64_t value;
     MemoryRegion *mr;
     PCDIMMDevice *dimm = PC_DIMM(obj);
-    PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(obj);
 
-    mr = ddc->get_memory_region(dimm);
+    mr = host_memory_backend_get_memory(dimm->hostmem, errp);
     value = memory_region_size(mr);
 
     visit_type_int(v, name, &value, errp);
@@ -369,9 +364,14 @@ static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name,
 static void pc_dimm_check_memdev_is_busy(Object *obj, const char *name,
                                       Object *val, Error **errp)
 {
+    MemoryRegion *mr;
     Error *local_err = NULL;
 
-    if (host_memory_backend_is_mapped(MEMORY_BACKEND(val))) {
+    mr = host_memory_backend_get_memory(MEMORY_BACKEND(val), &local_err);
+    if (local_err) {
+        goto out;
+    }
+    if (memory_region_is_mapped(mr)) {
         char *path = object_get_canonical_path_component(val);
         error_setg(&local_err, "can't use already busy memdev: %s", path);
         g_free(path);
@@ -379,6 +379,7 @@ static void pc_dimm_check_memdev_is_busy(Object *obj, const char *name,
         qdev_prop_allow_set_link_before_realize(obj, name, val, &local_err);
     }
 
+out:
     error_propagate(errp, local_err);
 }
 
@@ -398,7 +399,6 @@ static void pc_dimm_init(Object *obj)
 static void pc_dimm_realize(DeviceState *dev, Error **errp)
 {
     PCDIMMDevice *dimm = PC_DIMM(dev);
-    PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
 
     if (!dimm->hostmem) {
         error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property is not set");
@@ -411,19 +411,6 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp)
                    dimm->node, nb_numa_nodes ? nb_numa_nodes : 1);
         return;
     }
-
-    if (ddc->realize) {
-        ddc->realize(dimm, errp);
-    }
-
-    host_memory_backend_set_mapped(dimm->hostmem, true);
-}
-
-static void pc_dimm_unrealize(DeviceState *dev, Error **errp)
-{
-    PCDIMMDevice *dimm = PC_DIMM(dev);
-
-    host_memory_backend_set_mapped(dimm->hostmem, false);
 }
 
 static MemoryRegion *pc_dimm_get_memory_region(PCDIMMDevice *dimm)
@@ -431,23 +418,16 @@ static MemoryRegion *pc_dimm_get_memory_region(PCDIMMDevice *dimm)
     return host_memory_backend_get_memory(dimm->hostmem, &error_abort);
 }
 
-static MemoryRegion *pc_dimm_get_vmstate_memory_region(PCDIMMDevice *dimm)
-{
-    return host_memory_backend_get_memory(dimm->hostmem, &error_abort);
-}
-
 static void pc_dimm_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
     PCDIMMDeviceClass *ddc = PC_DIMM_CLASS(oc);
 
     dc->realize = pc_dimm_realize;
-    dc->unrealize = pc_dimm_unrealize;
     dc->props = pc_dimm_properties;
     dc->desc = "DIMM memory module";
 
     ddc->get_memory_region = pc_dimm_get_memory_region;
-    ddc->get_vmstate_memory_region = pc_dimm_get_vmstate_memory_region;
 }
 
 static TypeInfo pc_dimm_info = {
index dd1090d..0eb7f8e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef MICROBLAZE_BOOT_H
-#define MICROBLAZE_BOOT_H
+#ifndef __MICROBLAZE_BOOT__
+#define __MICROBLAZE_BOOT__
 
 #include "hw/hw.h"
 
@@ -9,4 +9,4 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
                             const char *dtb_filename,
                             void (*machine_cpu_reset)(MicroBlazeCPU *));
 
-#endif /* MICROBLAZE_BOOT_H */
+#endif /* __MICROBLAZE_BOOT __ */
index 4968bdb..07527b6 100644 (file)
@@ -191,16 +191,9 @@ petalogix_ml605_init(MachineState *machine)
         spi = (SSIBus *)qdev_get_child_bus(dev, "spi");
 
         for (i = 0; i < NUM_SPI_FLASHES; i++) {
-            DriveInfo *dinfo = drive_get_next(IF_MTD);
             qemu_irq cs_line;
 
-            dev = ssi_create_slave_no_init(spi, "n25q128");
-            if (dinfo) {
-                qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo),
-                                    &error_fatal);
-            }
-            qdev_init_nofail(dev);
-
+            dev = ssi_create_slave(spi, "n25q128");
             cs_line = qdev_get_gpio_in_named(dev, SSI_GPIO_CS, 0);
             sysbus_connect_irq(busdev, i+1, cs_line);
         }
index 423bcd7..f821e1c 100644 (file)
@@ -36,7 +36,6 @@
 #include "hw/boards.h"
 #include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
-#include "hw/char/xilinx_uartlite.h"
 
 #include "boot.h"
 
@@ -104,8 +103,8 @@ petalogix_s3adsp1800_init(MachineState *machine)
         irq[i] = qdev_get_gpio_in(dev, i);
     }
 
-    xilinx_uartlite_create(UARTLITE_BASEADDR, irq[UARTLITE_IRQ],
-                           serial_hds[0]);
+    sysbus_create_simple("xlnx.xps-uartlite", UARTLITE_BASEADDR,
+                         irq[UARTLITE_IRQ]);
 
     /* 2 timers at irq 2 @ 62 Mhz.  */
     dev = qdev_create(NULL, "xlnx.xps-timer");
index 4ef337d..1bafbbb 100644 (file)
 
 qemu_irq get_cps_irq(MIPSCPSState *s, int pin_number)
 {
+    MIPSCPU *cpu = MIPS_CPU(first_cpu);
+    CPUMIPSState *env = &cpu->env;
+
     assert(pin_number < s->num_irq);
-    return s->gic.irq_state[pin_number].irq;
+
+    /* TODO: return GIC pins once implemented */
+    return env->irq[pin_number];
 }
 
 static void mips_cps_init(Object *obj)
@@ -73,15 +78,14 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
     for (i = 0; i < s->num_vp; i++) {
         cpu = cpu_mips_init(s->cpu_model);
         if (cpu == NULL) {
-            error_setg(errp, "%s: CPU initialization failed",  __func__);
+            error_setg(errp, "%s: CPU initialization failed\n",  __func__);
             return;
         }
+        env = &cpu->env;
 
         /* Init internal devices */
-        cpu_mips_irq_init_cpu(cpu);
-        cpu_mips_clock_init(cpu);
-
-        env = &cpu->env;
+        cpu_mips_irq_init_cpu(env);
+        cpu_mips_clock_init(env);
         if (cpu_mips_itu_supported(env)) {
             itu_present = true;
             /* Attach ITC Tag to the VP */
@@ -125,21 +129,6 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
     memory_region_add_subregion(&s->container, 0,
                             sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpc), 0));
 
-    /* Global Interrupt Controller */
-    object_initialize(&s->gic, sizeof(s->gic), TYPE_MIPS_GIC);
-    qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
-
-    object_property_set_int(OBJECT(&s->gic), s->num_vp, "num-vp", &err);
-    object_property_set_int(OBJECT(&s->gic), 128, "num-irq", &err);
-    object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
-    if (err != NULL) {
-        error_propagate(errp, err);
-        return;
-    }
-
-    memory_region_add_subregion(&s->container, 0,
-                            sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gic), 0));
-
     /* Global Configuration Registers */
     gcr_base = env->CP0_CMGCRBase << 4;
 
@@ -149,7 +138,6 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
     object_property_set_int(OBJECT(&s->gcr), s->num_vp, "num-vp", &err);
     object_property_set_int(OBJECT(&s->gcr), 0x800, "gcr-rev", &err);
     object_property_set_int(OBJECT(&s->gcr), gcr_base, "gcr-base", &err);
-    object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->gic.mr), "gic", &err);
     object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->cpc.mr), "cpc", &err);
     object_property_set_bool(OBJECT(&s->gcr), true, "realized", &err);
     if (err != NULL) {
@@ -163,7 +151,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 
 static Property mips_cps_properties[] = {
     DEFINE_PROP_UINT32("num-vp", MIPSCPSState, num_vp, 1),
-    DEFINE_PROP_UINT32("num-irq", MIPSCPSState, num_irq, 256),
+    DEFINE_PROP_UINT32("num-irq", MIPSCPSState, num_irq, 8),
     DEFINE_PROP_STRING("cpu-model", MIPSCPSState, cpu_model),
     DEFINE_PROP_END_OF_LIST()
 };
index 8a166b3..efb227d 100644 (file)
@@ -151,10 +151,8 @@ static void mips_timer_cb (void *opaque)
     env->CP0_Count--;
 }
 
-void cpu_mips_clock_init (MIPSCPU *cpu)
+void cpu_mips_clock_init (CPUMIPSState *env)
 {
-    CPUMIPSState *env = &cpu->env;
-
     /*
      * If we're in KVM mode, don't create the periodic timer, that is handled in
      * kernel.
index 4811843..3f4523d 100644 (file)
@@ -1167,6 +1167,7 @@ PCIBus *gt64120_register(qemu_irq *pic)
     DeviceState *dev;
 
     dev = qdev_create(NULL, TYPE_GT64120_PCI_HOST_BRIDGE);
+    qdev_init_nofail(dev);
     d = GT64120_PCI_HOST_BRIDGE(dev);
     phb = PCI_HOST_BRIDGE(dev);
     memory_region_init(&d->pci0_mem, OBJECT(dev), "pci0-mem", UINT32_MAX);
@@ -1177,7 +1178,6 @@ PCIBus *gt64120_register(qemu_irq *pic)
                                 &d->pci0_mem,
                                 get_system_io(),
                                 PCI_DEVFN(18, 0), 4, TYPE_PCI_BUS);
-    qdev_init_nofail(dev);
     memory_region_init_io(&d->ISD_mem, OBJECT(dev), &isd_mem_ops, d, "isd-mem", 0x1000);
 
     pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci");
index 889cdc7..bdb716e 100644 (file)
@@ -334,8 +334,8 @@ static void mips_fulong2e_init(MachineState *machine)
     }
 
     /* Init internal devices */
-    cpu_mips_irq_init_cpu(cpu);
-    cpu_mips_clock_init(cpu);
+    cpu_mips_irq_init_cpu(env);
+    cpu_mips_clock_init(env);
 
     /* North bridge, Bonito --> IP2 */
     pci_bus = bonito_init((qemu_irq *)&(env->irq[2]));
index 48192d2..59081f9 100644 (file)
@@ -58,9 +58,8 @@ static void cpu_mips_irq_request(void *opaque, int irq, int level)
     }
 }
 
-void cpu_mips_irq_init_cpu(MIPSCPU *cpu)
+void cpu_mips_irq_init_cpu(CPUMIPSState *env)
 {
-    CPUMIPSState *env = &cpu->env;
     qemu_irq *qi;
     int i;
 
index 73f6c9f..ac7c641 100644 (file)
@@ -201,8 +201,8 @@ static void mips_jazz_init(MachineState *machine,
     }
 
     /* Init CPU internal devices */
-    cpu_mips_irq_init_cpu(cpu);
-    cpu_mips_clock_init(cpu);
+    cpu_mips_irq_init_cpu(env);
+    cpu_mips_clock_init(env);
 
     /* Chipset */
     rc4030 = rc4030_init(&dmas, &rc4030_dma_mr);
index e90857e..fa769e5 100644 (file)
@@ -727,7 +727,7 @@ static void write_bootloader(uint8_t *base, int64_t run_addr,
     stl_p(p++, 0x00000000);                                     /* nop */
     stl_p(p++, 0x0ff0021c);                                     /* jal 870 */
     stl_p(p++, 0x00000000);                                     /* nop */
-    stl_p(p++, 0x1000fff9);                                     /* b 814 */
+    stl_p(p++, 0x08000205);                                     /* j 814 */
     stl_p(p++, 0x00000000);                                     /* nop */
     stl_p(p++, 0x01a00009);                                     /* jalr t5 */
     stl_p(p++, 0x01602021);                                     /* move a0,t3 */
@@ -923,10 +923,11 @@ static void create_cpu_without_cps(const char *cpu_model,
             fprintf(stderr, "Unable to find CPU definition\n");
             exit(1);
         }
+        env = &cpu->env;
 
         /* Init internal devices */
-        cpu_mips_irq_init_cpu(cpu);
-        cpu_mips_clock_init(cpu);
+        cpu_mips_irq_init_cpu(env);
+        cpu_mips_clock_init(env);
         qemu_register_reset(main_cpu_reset, cpu);
     }
 
@@ -955,7 +956,9 @@ static void create_cps(MaltaState *s, const char *cpu_model,
 
     sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1);
 
-    *i8259_irq = get_cps_irq(s->cps, 3);
+    /* FIXME: When GIC is present then we should use GIC's IRQ 3.
+       Until then CPS exposes CPU's IRQs thus use the default IRQ 2. */
+    *i8259_irq = get_cps_irq(s->cps, 2);
     *cbus_irq = NULL;
 }
 
index 1b91195..a2c2a16 100644 (file)
@@ -216,8 +216,8 @@ mips_mipssim_init(MachineState *machine)
     }
 
     /* Init CPU internal devices. */
-    cpu_mips_irq_init_cpu(cpu);
-    cpu_mips_clock_init(cpu);
+    cpu_mips_irq_init_cpu(env);
+    cpu_mips_clock_init(env);
 
     /* Register 64 KB of ISA IO space at 0x1fd00000. */
     memory_region_init_alias(isa, NULL, "isa_mmio",
index 16a59c7..21aca98 100644 (file)
@@ -267,8 +267,8 @@ void mips_r4k_init(MachineState *machine)
     }
 
     /* Init CPU internal devices */
-    cpu_mips_irq_init_cpu(cpu);
-    cpu_mips_clock_init(cpu);
+    cpu_mips_irq_init_cpu(env);
+    cpu_mips_clock_init(env);
 
     /* ISA bus: IO space at 0x14000000, mem space at 0x10000000 */
     memory_region_init_alias(isa_io, NULL, "isa-io",
index 4cfbd10..93f9528 100644 (file)
@@ -29,7 +29,6 @@ obj-$(CONFIG_IMX) += imx_ccm.o
 obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_IMX) += imx6_ccm.o
-obj-$(CONFIG_IMX) += imx6_src.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
@@ -51,5 +50,3 @@ obj-$(CONFIG_MIPS_ITU) += mips_itu.o
 obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_EDU) += edu.o
 obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
-obj-$(CONFIG_AUX) += auxbus.o
-obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o
index 7042ce1..5e54b49 100644 (file)
@@ -10,7 +10,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/misc/arm11scu.h"
-#include "qemu/log.h"
 
 static uint64_t mpcore_scu_read(void *opaque, hwaddr offset,
                                 unsigned size)
index 8a5f295..902605f 100644 (file)
@@ -19,7 +19,6 @@
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
 #include "hw/misc/arm_integrator_debug.h"
-#include "qemu/log.h"
 
 #define INTEGRATOR_DEBUG(obj) \
     OBJECT_CHECK(IntegratorDebugState, (obj), TYPE_INTEGRATOR_DEBUG)
index 66a0787..7e179f1 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
-#include "qemu/log.h"
 
 /* L2C-310 r3p2 */
 #define CACHE_ID 0x410000c8
@@ -159,14 +158,14 @@ static const MemoryRegionOps l2x0_mem_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
  };
 
-static void l2x0_priv_init(Object *obj)
+static int l2x0_priv_init(SysBusDevice *dev)
 {
-    L2x0State *s = ARM_L2X0(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    L2x0State *s = ARM_L2X0(dev);
 
-    memory_region_init_io(&s->iomem, obj, &l2x0_mem_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(dev), &l2x0_mem_ops, s,
                           "l2x0_cc", 0x1000);
     sysbus_init_mmio(dev, &s->iomem);
+    return 0;
 }
 
 static Property l2x0_properties[] = {
@@ -176,8 +175,10 @@ static Property l2x0_properties[] = {
 
 static void l2x0_class_init(ObjectClass *klass, void *data)
 {
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
+    k->init = l2x0_priv_init;
     dc->vmsd = &vmstate_l2x0;
     dc->props = l2x0_properties;
     dc->reset = l2x0_priv_reset;
@@ -187,7 +188,6 @@ static const TypeInfo l2x0_info = {
     .name = TYPE_ARM_L2X0,
     .parent = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(L2x0State),
-    .instance_init = l2x0_priv_init,
     .class_init = l2x0_class_init,
 };
 
index 8524008..34d90d5 100644 (file)
@@ -14,7 +14,6 @@
 #include "hw/sysbus.h"
 #include "hw/arm/primecell.h"
 #include "sysemu/sysemu.h"
-#include "qemu/log.h"
 
 #define LOCK_VALUE 0xa05f
 
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
deleted file mode 100644 (file)
index c7e2c82..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * ASPEED System Control Unit
- *
- * Andrew Jeffery <andrew@aj.id.au>
- *
- * Copyright 2016 IBM Corp.
- *
- * This code is licensed under the GPL version 2 or later.  See
- * the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "hw/misc/aspeed_scu.h"
-#include "hw/qdev-properties.h"
-#include "qapi/error.h"
-#include "qapi/visitor.h"
-#include "qemu/bitops.h"
-#include "qemu/log.h"
-#include "trace.h"
-
-#define TO_REG(offset) ((offset) >> 2)
-
-#define PROT_KEY             TO_REG(0x00)
-#define SYS_RST_CTRL         TO_REG(0x04)
-#define CLK_SEL              TO_REG(0x08)
-#define CLK_STOP_CTRL        TO_REG(0x0C)
-#define FREQ_CNTR_CTRL       TO_REG(0x10)
-#define FREQ_CNTR_EVAL       TO_REG(0x14)
-#define IRQ_CTRL             TO_REG(0x18)
-#define D2PLL_PARAM          TO_REG(0x1C)
-#define MPLL_PARAM           TO_REG(0x20)
-#define HPLL_PARAM           TO_REG(0x24)
-#define FREQ_CNTR_RANGE      TO_REG(0x28)
-#define MISC_CTRL1           TO_REG(0x2C)
-#define PCI_CTRL1            TO_REG(0x30)
-#define PCI_CTRL2            TO_REG(0x34)
-#define PCI_CTRL3            TO_REG(0x38)
-#define SYS_RST_STATUS       TO_REG(0x3C)
-#define SOC_SCRATCH1         TO_REG(0x40)
-#define SOC_SCRATCH2         TO_REG(0x44)
-#define MAC_CLK_DELAY        TO_REG(0x48)
-#define MISC_CTRL2           TO_REG(0x4C)
-#define VGA_SCRATCH1         TO_REG(0x50)
-#define VGA_SCRATCH2         TO_REG(0x54)
-#define VGA_SCRATCH3         TO_REG(0x58)
-#define VGA_SCRATCH4         TO_REG(0x5C)
-#define VGA_SCRATCH5         TO_REG(0x60)
-#define VGA_SCRATCH6         TO_REG(0x64)
-#define VGA_SCRATCH7         TO_REG(0x68)
-#define VGA_SCRATCH8         TO_REG(0x6C)
-#define HW_STRAP1            TO_REG(0x70)
-#define RNG_CTRL             TO_REG(0x74)
-#define RNG_DATA             TO_REG(0x78)
-#define SILICON_REV          TO_REG(0x7C)
-#define PINMUX_CTRL1         TO_REG(0x80)
-#define PINMUX_CTRL2         TO_REG(0x84)
-#define PINMUX_CTRL3         TO_REG(0x88)
-#define PINMUX_CTRL4         TO_REG(0x8C)
-#define PINMUX_CTRL5         TO_REG(0x90)
-#define PINMUX_CTRL6         TO_REG(0x94)
-#define WDT_RST_CTRL         TO_REG(0x9C)
-#define PINMUX_CTRL7         TO_REG(0xA0)
-#define PINMUX_CTRL8         TO_REG(0xA4)
-#define PINMUX_CTRL9         TO_REG(0xA8)
-#define WAKEUP_EN            TO_REG(0xC0)
-#define WAKEUP_CTRL          TO_REG(0xC4)
-#define HW_STRAP2            TO_REG(0xD0)
-#define FREE_CNTR4           TO_REG(0xE0)
-#define FREE_CNTR4_EXT       TO_REG(0xE4)
-#define CPU2_CTRL            TO_REG(0x100)
-#define CPU2_BASE_SEG1       TO_REG(0x104)
-#define CPU2_BASE_SEG2       TO_REG(0x108)
-#define CPU2_BASE_SEG3       TO_REG(0x10C)
-#define CPU2_BASE_SEG4       TO_REG(0x110)
-#define CPU2_BASE_SEG5       TO_REG(0x114)
-#define CPU2_CACHE_CTRL      TO_REG(0x118)
-#define UART_HPLL_CLK        TO_REG(0x160)
-#define PCIE_CTRL            TO_REG(0x180)
-#define BMC_MMIO_CTRL        TO_REG(0x184)
-#define RELOC_DECODE_BASE1   TO_REG(0x188)
-#define RELOC_DECODE_BASE2   TO_REG(0x18C)
-#define MAILBOX_DECODE_BASE  TO_REG(0x190)
-#define SRAM_DECODE_BASE1    TO_REG(0x194)
-#define SRAM_DECODE_BASE2    TO_REG(0x198)
-#define BMC_REV              TO_REG(0x19C)
-#define BMC_DEV_ID           TO_REG(0x1A4)
-
-#define PROT_KEY_UNLOCK 0x1688A8A8
-#define SCU_IO_REGION_SIZE 0x20000
-
-static const uint32_t ast2400_a0_resets[ASPEED_SCU_NR_REGS] = {
-     [SYS_RST_CTRL]    = 0xFFCFFEDCU,
-     [CLK_SEL]         = 0xF3F40000U,
-     [CLK_STOP_CTRL]   = 0x19FC3E8BU,
-     [D2PLL_PARAM]     = 0x00026108U,
-     [MPLL_PARAM]      = 0x00030291U,
-     [HPLL_PARAM]      = 0x00000291U,
-     [MISC_CTRL1]      = 0x00000010U,
-     [PCI_CTRL1]       = 0x20001A03U,
-     [PCI_CTRL2]       = 0x20001A03U,
-     [PCI_CTRL3]       = 0x04000030U,
-     [SYS_RST_STATUS]  = 0x00000001U,
-     [SOC_SCRATCH1]    = 0x000000C0U, /* SoC completed DRAM init */
-     [MISC_CTRL2]      = 0x00000023U,
-     [RNG_CTRL]        = 0x0000000EU,
-     [PINMUX_CTRL2]    = 0x0000F000U,
-     [PINMUX_CTRL3]    = 0x01000000U,
-     [PINMUX_CTRL4]    = 0x000000FFU,
-     [PINMUX_CTRL5]    = 0x0000A000U,
-     [WDT_RST_CTRL]    = 0x003FFFF3U,
-     [PINMUX_CTRL8]    = 0xFFFF0000U,
-     [PINMUX_CTRL9]    = 0x000FFFFFU,
-     [FREE_CNTR4]      = 0x000000FFU,
-     [FREE_CNTR4_EXT]  = 0x000000FFU,
-     [CPU2_BASE_SEG1]  = 0x80000000U,
-     [CPU2_BASE_SEG4]  = 0x1E600000U,
-     [CPU2_BASE_SEG5]  = 0xC0000000U,
-     [UART_HPLL_CLK]   = 0x00001903U,
-     [PCIE_CTRL]       = 0x0000007BU,
-     [BMC_DEV_ID]      = 0x00002402U
-};
-
-static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
-{
-    AspeedSCUState *s = ASPEED_SCU(opaque);
-    int reg = TO_REG(offset);
-
-    if (reg >= ARRAY_SIZE(s->regs)) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
-                      __func__, offset);
-        return 0;
-    }
-
-    switch (reg) {
-    case WAKEUP_EN:
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: Read of write-only offset 0x%" HWADDR_PRIx "\n",
-                      __func__, offset);
-        break;
-    }
-
-    return s->regs[reg];
-}
-
-static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
-                             unsigned size)
-{
-    AspeedSCUState *s = ASPEED_SCU(opaque);
-    int reg = TO_REG(offset);
-
-    if (reg >= ARRAY_SIZE(s->regs)) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
-                      __func__, offset);
-        return;
-    }
-
-    if (reg > PROT_KEY && reg < CPU2_BASE_SEG1 &&
-            s->regs[PROT_KEY] != PROT_KEY_UNLOCK) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: SCU is locked!\n", __func__);
-        return;
-    }
-
-    trace_aspeed_scu_write(offset, size, data);
-
-    switch (reg) {
-    case FREQ_CNTR_EVAL:
-    case VGA_SCRATCH1 ... VGA_SCRATCH8:
-    case RNG_DATA:
-    case SILICON_REV:
-    case FREE_CNTR4:
-    case FREE_CNTR4_EXT:
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
-                      __func__, offset);
-        return;
-    }
-
-    s->regs[reg] = data;
-}
-
-static const MemoryRegionOps aspeed_scu_ops = {
-    .read = aspeed_scu_read,
-    .write = aspeed_scu_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-    .valid.min_access_size = 4,
-    .valid.max_access_size = 4,
-    .valid.unaligned = false,
-};
-
-static void aspeed_scu_reset(DeviceState *dev)
-{
-    AspeedSCUState *s = ASPEED_SCU(dev);
-    const uint32_t *reset;
-
-    switch (s->silicon_rev) {
-    case AST2400_A0_SILICON_REV:
-        reset = ast2400_a0_resets;
-        break;
-    default:
-        g_assert_not_reached();
-    }
-
-    memcpy(s->regs, reset, sizeof(s->regs));
-    s->regs[SILICON_REV] = s->silicon_rev;
-    s->regs[HW_STRAP1] = s->hw_strap1;
-    s->regs[HW_STRAP2] = s->hw_strap2;
-}
-
-static uint32_t aspeed_silicon_revs[] = { AST2400_A0_SILICON_REV, };
-
-bool is_supported_silicon_rev(uint32_t silicon_rev)
-{
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(aspeed_silicon_revs); i++) {
-        if (silicon_rev == aspeed_silicon_revs[i]) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-static void aspeed_scu_realize(DeviceState *dev, Error **errp)
-{
-    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-    AspeedSCUState *s = ASPEED_SCU(dev);
-
-    if (!is_supported_silicon_rev(s->silicon_rev)) {
-        error_setg(errp, "Unknown silicon revision: 0x%" PRIx32,
-                s->silicon_rev);
-        return;
-    }
-
-    memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_scu_ops, s,
-                          TYPE_ASPEED_SCU, SCU_IO_REGION_SIZE);
-
-    sysbus_init_mmio(sbd, &s->iomem);
-}
-
-static const VMStateDescription vmstate_aspeed_scu = {
-    .name = "aspeed.scu",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT32_ARRAY(regs, AspeedSCUState, ASPEED_SCU_NR_REGS),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static Property aspeed_scu_properties[] = {
-    DEFINE_PROP_UINT32("silicon-rev", AspeedSCUState, silicon_rev, 0),
-    DEFINE_PROP_UINT32("hw-strap1", AspeedSCUState, hw_strap1, 0),
-    DEFINE_PROP_UINT32("hw-strap2", AspeedSCUState, hw_strap2, 0),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void aspeed_scu_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    dc->realize = aspeed_scu_realize;
-    dc->reset = aspeed_scu_reset;
-    dc->desc = "ASPEED System Control Unit";
-    dc->vmsd = &vmstate_aspeed_scu;
-    dc->props = aspeed_scu_properties;
-}
-
-static const TypeInfo aspeed_scu_info = {
-    .name = TYPE_ASPEED_SCU,
-    .parent = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(AspeedSCUState),
-    .class_init = aspeed_scu_class_init,
-};
-
-static void aspeed_scu_register_types(void)
-{
-    type_register_static(&aspeed_scu_info);
-}
-
-type_init(aspeed_scu_register_types);
diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
deleted file mode 100644 (file)
index e4a7ba4..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * auxbus.c
- *
- *  Copyright 2015 : GreenSocs Ltd
- *      http://www.greensocs.com/ , email: info@greensocs.com
- *
- *  Developed by :
- *  Frederic Konrad   <fred.konrad@greensocs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option)any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/*
- * This is an implementation of the AUX bus for VESA Display Port v1.1a.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "hw/misc/auxbus.h"
-#include "hw/i2c/i2c.h"
-#include "monitor/monitor.h"
-
-#ifndef DEBUG_AUX
-#define DEBUG_AUX 0
-#endif
-
-#define DPRINTF(fmt, ...) do {                                                 \
-    if (DEBUG_AUX) {                                                           \
-        qemu_log("aux: " fmt , ## __VA_ARGS__);                                \
-    }                                                                          \
-} while (0);
-
-#define TYPE_AUXTOI2C "aux-to-i2c-bridge"
-#define AUXTOI2C(obj) OBJECT_CHECK(AUXTOI2CState, (obj), TYPE_AUXTOI2C)
-
-static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent);
-static inline I2CBus *aux_bridge_get_i2c_bus(AUXTOI2CState *bridge);
-
-/* aux-bus implementation (internal not public) */
-static void aux_bus_class_init(ObjectClass *klass, void *data)
-{
-    BusClass *k = BUS_CLASS(klass);
-
-    /* AUXSlave has an MMIO so we need to change the way we print information
-     * in monitor.
-     */
-    k->print_dev = aux_slave_dev_print;
-}
-
-AUXBus *aux_init_bus(DeviceState *parent, const char *name)
-{
-    AUXBus *bus;
-
-    bus = AUX_BUS(qbus_create(TYPE_AUX_BUS, parent, name));
-    bus->bridge = AUXTOI2C(qdev_create(BUS(bus), TYPE_AUXTOI2C));
-
-    /* Memory related. */
-    bus->aux_io = g_malloc(sizeof(*bus->aux_io));
-    memory_region_init(bus->aux_io, OBJECT(bus), "aux-io", (1 << 20));
-    address_space_init(&bus->aux_addr_space, bus->aux_io, "aux-io");
-    return bus;
-}
-
-static void aux_bus_map_device(AUXBus *bus, AUXSlave *dev, hwaddr addr)
-{
-    memory_region_add_subregion(bus->aux_io, addr, dev->mmio);
-}
-
-static bool aux_bus_is_bridge(AUXBus *bus, DeviceState *dev)
-{
-    return (dev == DEVICE(bus->bridge));
-}
-
-I2CBus *aux_get_i2c_bus(AUXBus *bus)
-{
-    return aux_bridge_get_i2c_bus(bus->bridge);
-}
-
-AUXReply aux_request(AUXBus *bus, AUXCommand cmd, uint32_t address,
-                      uint8_t len, uint8_t *data)
-{
-    AUXReply ret = AUX_NACK;
-    I2CBus *i2c_bus = aux_get_i2c_bus(bus);
-    size_t i;
-    bool is_write = false;
-
-    DPRINTF("request at address 0x%" PRIX32 ", command %u, len %u\n", address,
-            cmd, len);
-
-    switch (cmd) {
-    /*
-     * Forward the request on the AUX bus..
-     */
-    case WRITE_AUX:
-    case READ_AUX:
-        is_write = cmd == READ_AUX ? false : true;
-        for (i = 0; i < len; i++) {
-            if (!address_space_rw(&bus->aux_addr_space, address++,
-                                  MEMTXATTRS_UNSPECIFIED, data++, 1,
-                                  is_write)) {
-                ret = AUX_I2C_ACK;
-            } else {
-                ret = AUX_NACK;
-                break;
-            }
-        }
-        break;
-    /*
-     * Classic I2C transactions..
-     */
-    case READ_I2C:
-    case WRITE_I2C:
-        is_write = cmd == READ_I2C ? false : true;
-        if (i2c_bus_busy(i2c_bus)) {
-            i2c_end_transfer(i2c_bus);
-        }
-
-        if (i2c_start_transfer(i2c_bus, address, is_write)) {
-            ret = AUX_I2C_NACK;
-            break;
-        }
-
-        ret = AUX_I2C_ACK;
-        while (len > 0) {
-            if (i2c_send_recv(i2c_bus, data++, is_write) < 0) {
-                ret = AUX_I2C_NACK;
-                break;
-            }
-            len--;
-        }
-        i2c_end_transfer(i2c_bus);
-        break;
-    /*
-     * I2C MOT transactions.
-     *
-     * Here we send a start when:
-     *  - We didn't start transaction yet.
-     *  - We had a READ and we do a WRITE.
-     *  - We changed the address.
-     */
-    case WRITE_I2C_MOT:
-    case READ_I2C_MOT:
-        is_write = cmd == READ_I2C_MOT ? false : true;
-        ret = AUX_I2C_NACK;
-        if (!i2c_bus_busy(i2c_bus)) {
-            /*
-             * No transactions started..
-             */
-            if (i2c_start_transfer(i2c_bus, address, is_write)) {
-                break;
-            }
-        } else if ((address != bus->last_i2c_address) ||
-                   (bus->last_transaction != cmd)) {
-            /*
-             * Transaction started but we need to restart..
-             */
-            i2c_end_transfer(i2c_bus);
-            if (i2c_start_transfer(i2c_bus, address, is_write)) {
-                break;
-            }
-        }
-
-        bus->last_transaction = cmd;
-        bus->last_i2c_address = address;
-        while (len > 0) {
-            if (i2c_send_recv(i2c_bus, data++, is_write) < 0) {
-                i2c_end_transfer(i2c_bus);
-                break;
-            }
-            len--;
-        }
-        if (len == 0) {
-            ret = AUX_I2C_ACK;
-        }
-        break;
-    default:
-        DPRINTF("Not implemented!\n");
-        return AUX_NACK;
-    }
-
-    DPRINTF("reply: %u\n", ret);
-    return ret;
-}
-
-static const TypeInfo aux_bus_info = {
-    .name = TYPE_AUX_BUS,
-    .parent = TYPE_BUS,
-    .instance_size = sizeof(AUXBus),
-    .class_init = aux_bus_class_init
-};
-
-/* aux-i2c implementation (internal not public) */
-struct AUXTOI2CState {
-    /*< private >*/
-    DeviceState parent_obj;
-
-    /*< public >*/
-    I2CBus *i2c_bus;
-};
-
-static void aux_bridge_init(Object *obj)
-{
-    AUXTOI2CState *s = AUXTOI2C(obj);
-
-    s->i2c_bus = i2c_init_bus(DEVICE(obj), "aux-i2c");
-}
-
-static inline I2CBus *aux_bridge_get_i2c_bus(AUXTOI2CState *bridge)
-{
-    return bridge->i2c_bus;
-}
-
-static const TypeInfo aux_to_i2c_type_info = {
-    .name = TYPE_AUXTOI2C,
-    .parent = TYPE_DEVICE,
-    .instance_size = sizeof(AUXTOI2CState),
-    .instance_init = aux_bridge_init
-};
-
-/* aux-slave implementation */
-static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent)
-{
-    AUXBus *bus = AUX_BUS(qdev_get_parent_bus(dev));
-    AUXSlave *s;
-
-    /* Don't print anything if the device is I2C "bridge". */
-    if (aux_bus_is_bridge(bus, dev)) {
-        return;
-    }
-
-    s = AUX_SLAVE(dev);
-
-    monitor_printf(mon, "%*smemory " TARGET_FMT_plx "/" TARGET_FMT_plx "\n",
-                   indent, "",
-                   object_property_get_int(OBJECT(s->mmio), "addr", NULL),
-                   memory_region_size(s->mmio));
-}
-
-DeviceState *aux_create_slave(AUXBus *bus, const char *type, uint32_t addr)
-{
-    DeviceState *dev;
-
-    dev = DEVICE(object_new(type));
-    assert(dev);
-    qdev_set_parent_bus(dev, &bus->qbus);
-    qdev_init_nofail(dev);
-    aux_bus_map_device(AUX_BUS(qdev_get_parent_bus(dev)), AUX_SLAVE(dev), addr);
-    return dev;
-}
-
-void aux_init_mmio(AUXSlave *aux_slave, MemoryRegion *mmio)
-{
-    assert(!aux_slave->mmio);
-    aux_slave->mmio = mmio;
-}
-
-static void aux_slave_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *k = DEVICE_CLASS(klass);
-
-    set_bit(DEVICE_CATEGORY_MISC, k->categories);
-    k->bus_type = TYPE_AUX_BUS;
-}
-
-static const TypeInfo aux_slave_type_info = {
-    .name = TYPE_AUX_SLAVE,
-    .parent = TYPE_DEVICE,
-    .instance_size = sizeof(AUXSlave),
-    .abstract = true,
-    .class_init = aux_slave_class_init,
-};
-
-static void aux_register_types(void)
-{
-    type_register_static(&aux_bus_info);
-    type_register_static(&aux_slave_type_info);
-    type_register_static(&aux_to_i2c_type_info);
-}
-
-type_init(aux_register_types)
index e97cc81..263280f 100644 (file)
@@ -11,7 +11,6 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/misc/bcm2835_mbox.h"
-#include "qemu/log.h"
 
 #define MAIL0_PEEK   0x90
 #define MAIL0_SENDER 0x94
index 70eaafd..530411f 100644 (file)
@@ -8,7 +8,6 @@
 #include "hw/misc/bcm2835_property.h"
 #include "hw/misc/bcm2835_mbox_defs.h"
 #include "sysemu/dma.h"
-#include "qemu/log.h"
 
 /* https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface */
 
@@ -22,8 +21,6 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
     int n;
     uint32_t offset, length, color;
     uint32_t xres, yres, xoffset, yoffset, bpp, pixo, alpha;
-    uint32_t tmp_xres, tmp_yres, tmp_xoffset, tmp_yoffset;
-    uint32_t tmp_bpp, tmp_pixo, tmp_alpha;
     uint32_t *newxres = NULL, *newyres = NULL, *newxoffset = NULL,
         *newyoffset = NULL, *newbpp = NULL, *newpixo = NULL, *newalpha = NULL;
 
@@ -142,11 +139,7 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
 
         case 0x00040001: /* Allocate buffer */
             stl_le_phys(&s->dma_as, value + 12, s->fbdev->base);
-            tmp_xres = newxres != NULL ? *newxres : s->fbdev->xres;
-            tmp_yres = newyres != NULL ? *newyres : s->fbdev->yres;
-            tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->bpp;
-            stl_le_phys(&s->dma_as, value + 16,
-                        tmp_xres * tmp_yres * tmp_bpp / 8);
+            stl_le_phys(&s->dma_as, value + 16, s->fbdev->size);
             resplen = 8;
             break;
         case 0x00048001: /* Release buffer */
@@ -157,10 +150,8 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
             break;
         case 0x00040003: /* Get display width/height */
         case 0x00040004:
-            tmp_xres = newxres != NULL ? *newxres : s->fbdev->xres;
-            tmp_yres = newyres != NULL ? *newyres : s->fbdev->yres;
-            stl_le_phys(&s->dma_as, value + 12, tmp_xres);
-            stl_le_phys(&s->dma_as, value + 16, tmp_yres);
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->xres);
+            stl_le_phys(&s->dma_as, value + 16, s->fbdev->yres);
             resplen = 8;
             break;
         case 0x00044003: /* Test display width/height */
@@ -176,8 +167,7 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
             resplen = 8;
             break;
         case 0x00040005: /* Get depth */
-            tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->bpp;
-            stl_le_phys(&s->dma_as, value + 12, tmp_bpp);
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->bpp);
             resplen = 4;
             break;
         case 0x00044005: /* Test depth */
@@ -189,8 +179,7 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
             resplen = 4;
             break;
         case 0x00040006: /* Get pixel order */
-            tmp_pixo = newpixo != NULL ? *newpixo : s->fbdev->pixo;
-            stl_le_phys(&s->dma_as, value + 12, tmp_pixo);
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->pixo);
             resplen = 4;
             break;
         case 0x00044006: /* Test pixel order */
@@ -202,8 +191,7 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
             resplen = 4;
             break;
         case 0x00040007: /* Get alpha */
-            tmp_alpha = newalpha != NULL ? *newalpha : s->fbdev->alpha;
-            stl_le_phys(&s->dma_as, value + 12, tmp_alpha);
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->alpha);
             resplen = 4;
             break;
         case 0x00044007: /* Test pixel alpha */
@@ -215,16 +203,12 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
             resplen = 4;
             break;
         case 0x00040008: /* Get pitch */
-            tmp_xres = newxres != NULL ? *newxres : s->fbdev->xres;
-            tmp_bpp = newbpp != NULL ? *newbpp : s->fbdev->bpp;
-            stl_le_phys(&s->dma_as, value + 12, tmp_xres * tmp_bpp / 8);
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->pitch);
             resplen = 4;
             break;
         case 0x00040009: /* Get virtual offset */
-            tmp_xoffset = newxoffset != NULL ? *newxoffset : s->fbdev->xoffset;
-            tmp_yoffset = newyoffset != NULL ? *newyoffset : s->fbdev->yoffset;
-            stl_le_phys(&s->dma_as, value + 12, tmp_xoffset);
-            stl_le_phys(&s->dma_as, value + 16, tmp_yoffset);
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->xoffset);
+            stl_le_phys(&s->dma_as, value + 16, s->fbdev->yoffset);
             resplen = 8;
             break;
         case 0x00044009: /* Test virtual offset */
index e30dbc7..889abad 100644 (file)
@@ -457,15 +457,15 @@ static void exynos4210_pmu_reset(DeviceState *dev)
     }
 }
 
-static void exynos4210_pmu_init(Object *obj)
+static int exynos4210_pmu_init(SysBusDevice *dev)
 {
-    Exynos4210PmuState *s = EXYNOS4210_PMU(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    Exynos4210PmuState *s = EXYNOS4210_PMU(dev);
 
     /* memory mapping */
-    memory_region_init_io(&s->iomem, obj, &exynos4210_pmu_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(dev), &exynos4210_pmu_ops, s,
                           "exynos4210.pmu", EXYNOS4210_PMU_REGS_MEM_SIZE);
     sysbus_init_mmio(dev, &s->iomem);
+    return 0;
 }
 
 static const VMStateDescription exynos4210_pmu_vmstate = {
@@ -481,7 +481,9 @@ static const VMStateDescription exynos4210_pmu_vmstate = {
 static void exynos4210_pmu_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = exynos4210_pmu_init;
     dc->reset = exynos4210_pmu_reset;
     dc->vmsd = &exynos4210_pmu_vmstate;
 }
@@ -490,7 +492,6 @@ static const TypeInfo exynos4210_pmu_info = {
     .name          = TYPE_EXYNOS4210_PMU,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(Exynos4210PmuState),
-    .instance_init = exynos4210_pmu_init,
     .class_init    = exynos4210_pmu_class_init,
 };
 
index 6cae9e9..1883fd7 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include <linux/kvm.h>
 #include "hw/hw.h"
 #include "hw/qdev.h"
 #include "hw/isa/isa.h"
 #include "sysemu/kvm.h"
+#include "linux/kvm.h"
 #include "target-i386/hyperv.h"
 #include "kvm_i386.h"
 
index 5cd8c0a..225604d 100644 (file)
@@ -13,7 +13,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/misc/imx25_ccm.h"
-#include "qemu/log.h"
 
 #ifndef DEBUG_IMX25_CCM
 #define DEBUG_IMX25_CCM 0
index 1c03e52..80c1647 100644 (file)
@@ -13,7 +13,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/misc/imx31_ccm.h"
-#include "qemu/log.h"
 
 #define CKIH_FREQ 26000000 /* 26MHz crystal input */
 
index 17e15d4..4e1d49d 100644 (file)
@@ -12,7 +12,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/misc/imx6_ccm.h"
-#include "qemu/log.h"
 
 #ifndef DEBUG_IMX6_CCM
 #define DEBUG_IMX6_CCM 0
@@ -371,12 +370,6 @@ static uint32_t imx6_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
     case CLK_32k:
         freq = CKIL_FREQ;
         break;
-    case CLK_HIGH:
-        freq = 24000000;
-        break;
-    case CLK_HIGH_DIV:
-        freq = 24000000 / 8;
-        break;
     default:
         qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
                       TYPE_IMX6_CCM, __func__, clock);
diff --git a/hw/misc/imx6_src.c b/hw/misc/imx6_src.c
deleted file mode 100644 (file)
index 8bb6829..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * IMX6 System Reset Controller
- *
- * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "hw/misc/imx6_src.h"
-#include "sysemu/sysemu.h"
-#include "qemu/bitops.h"
-#include "qemu/log.h"
-#include "arm-powerctl.h"
-
-#ifndef DEBUG_IMX6_SRC
-#define DEBUG_IMX6_SRC 0
-#endif
-
-#define DPRINTF(fmt, args...) \
-    do { \
-        if (DEBUG_IMX6_SRC) { \
-            fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX6_SRC, \
-                                             __func__, ##args); \
-        } \
-    } while (0)
-
-static char const *imx6_src_reg_name(uint32_t reg)
-{
-    static char unknown[20];
-
-    switch (reg) {
-    case SRC_SCR:
-        return "SRC_SCR";
-    case SRC_SBMR1:
-        return "SRC_SBMR1";
-    case SRC_SRSR:
-        return "SRC_SRSR";
-    case SRC_SISR:
-        return "SRC_SISR";
-    case SRC_SIMR:
-        return "SRC_SIMR";
-    case SRC_SBMR2:
-        return "SRC_SBMR2";
-    case SRC_GPR1:
-        return "SRC_GPR1";
-    case SRC_GPR2:
-        return "SRC_GPR2";
-    case SRC_GPR3:
-        return "SRC_GPR3";
-    case SRC_GPR4:
-        return "SRC_GPR4";
-    case SRC_GPR5:
-        return "SRC_GPR5";
-    case SRC_GPR6:
-        return "SRC_GPR6";
-    case SRC_GPR7:
-        return "SRC_GPR7";
-    case SRC_GPR8:
-        return "SRC_GPR8";
-    case SRC_GPR9:
-        return "SRC_GPR9";
-    case SRC_GPR10:
-        return "SRC_GPR10";
-    default:
-        sprintf(unknown, "%d ?", reg);
-        return unknown;
-    }
-}
-
-static const VMStateDescription vmstate_imx6_src = {
-    .name = TYPE_IMX6_SRC,
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT32_ARRAY(regs, IMX6SRCState, SRC_MAX),
-        VMSTATE_END_OF_LIST()
-    },
-};
-
-static void imx6_src_reset(DeviceState *dev)
-{
-    IMX6SRCState *s = IMX6_SRC(dev);
-
-    DPRINTF("\n");
-
-    memset(s->regs, 0, sizeof(s->regs));
-
-    /* Set reset values */
-    s->regs[SRC_SCR] = 0x521;
-    s->regs[SRC_SRSR] = 0x1;
-    s->regs[SRC_SIMR] = 0x1F;
-}
-
-static uint64_t imx6_src_read(void *opaque, hwaddr offset, unsigned size)
-{
-    uint32_t value = 0;
-    IMX6SRCState *s = (IMX6SRCState *)opaque;
-    uint32_t index = offset >> 2;
-
-    if (index < SRC_MAX) {
-        value = s->regs[index];
-    } else {
-        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
-                      HWADDR_PRIx "\n", TYPE_IMX6_SRC, __func__, offset);
-
-    }
-
-    DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx6_src_reg_name(index), value);
-
-    return value;
-}
-
-static void imx6_src_write(void *opaque, hwaddr offset, uint64_t value,
-                           unsigned size)
-{
-    IMX6SRCState *s = (IMX6SRCState *)opaque;
-    uint32_t index = offset >> 2;
-    unsigned long change_mask;
-    unsigned long current_value = value;
-
-    if (index >=  SRC_MAX) {
-        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
-                      HWADDR_PRIx "\n", TYPE_IMX6_SRC, __func__, offset);
-        return;
-    }
-
-    DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx6_src_reg_name(index),
-            (uint32_t)current_value);
-
-    change_mask = s->regs[index] ^ (uint32_t)current_value;
-
-    switch (index) {
-    case SRC_SCR:
-        /*
-         * On real hardware when the system reset controller starts a
-         * secondary CPU it runs through some boot ROM code which reads
-         * the SRC_GPRX registers controlling the start address and branches
-         * to it.
-         * Here we are taking a short cut and branching directly to the
-         * requested address (we don't want to run the boot ROM code inside
-         * QEMU)
-         */
-        if (EXTRACT(change_mask, CORE3_ENABLE)) {
-            if (EXTRACT(current_value, CORE3_ENABLE)) {
-                /* CORE 3 is brought up */
-                arm_set_cpu_on(3, s->regs[SRC_GPR7], s->regs[SRC_GPR8],
-                               3, false);
-            } else {
-                /* CORE 3 is shut down */
-                arm_set_cpu_off(3);
-            }
-            /* We clear the reset bits as the processor changed state */
-            clear_bit(CORE3_RST_SHIFT, &current_value);
-            clear_bit(CORE3_RST_SHIFT, &change_mask);
-        }
-        if (EXTRACT(change_mask, CORE2_ENABLE)) {
-            if (EXTRACT(current_value, CORE2_ENABLE)) {
-                /* CORE 2 is brought up */
-                arm_set_cpu_on(2, s->regs[SRC_GPR5], s->regs[SRC_GPR6],
-                               3, false);
-            } else {
-                /* CORE 3 is shut down */
-                arm_set_cpu_off(2);
-            }
-            /* We clear the reset bits as the processor changed state */
-            clear_bit(CORE2_RST_SHIFT, &current_value);
-            clear_bit(CORE2_RST_SHIFT, &change_mask);
-        }
-        if (EXTRACT(change_mask, CORE1_ENABLE)) {
-            if (EXTRACT(current_value, CORE1_ENABLE)) {
-                /* CORE 1 is brought up */
-                arm_set_cpu_on(1, s->regs[SRC_GPR3], s->regs[SRC_GPR4],
-                               3, false);
-            } else {
-                /* CORE 3 is shut down */
-                arm_set_cpu_off(1);
-            }
-            /* We clear the reset bits as the processor changed state */
-            clear_bit(CORE1_RST_SHIFT, &current_value);
-            clear_bit(CORE1_RST_SHIFT, &change_mask);
-        }
-        if (EXTRACT(change_mask, CORE0_RST)) {
-            arm_reset_cpu(0);
-            clear_bit(CORE0_RST_SHIFT, &current_value);
-        }
-        if (EXTRACT(change_mask, CORE1_RST)) {
-            arm_reset_cpu(1);
-            clear_bit(CORE1_RST_SHIFT, &current_value);
-        }
-        if (EXTRACT(change_mask, CORE2_RST)) {
-            arm_reset_cpu(2);
-            clear_bit(CORE2_RST_SHIFT, &current_value);
-        }
-        if (EXTRACT(change_mask, CORE3_RST)) {
-            arm_reset_cpu(3);
-            clear_bit(CORE3_RST_SHIFT, &current_value);
-        }
-        if (EXTRACT(change_mask, SW_IPU2_RST)) {
-            /* We pretend the IPU2 is reset */
-            clear_bit(SW_IPU2_RST_SHIFT, &current_value);
-        }
-        if (EXTRACT(change_mask, SW_IPU1_RST)) {
-            /* We pretend the IPU1 is reset */
-            clear_bit(SW_IPU1_RST_SHIFT, &current_value);
-        }
-        s->regs[index] = current_value;
-        break;
-    default:
-        s->regs[index] = current_value;
-        break;
-    }
-}
-
-static const struct MemoryRegionOps imx6_src_ops = {
-    .read = imx6_src_read,
-    .write = imx6_src_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .valid = {
-        /*
-         * Our device would not work correctly if the guest was doing
-         * unaligned access. This might not be a limitation on the real
-         * device but in practice there is no reason for a guest to access
-         * this device unaligned.
-         */
-        .min_access_size = 4,
-        .max_access_size = 4,
-        .unaligned = false,
-    },
-};
-
-static void imx6_src_realize(DeviceState *dev, Error **errp)
-{
-    IMX6SRCState *s = IMX6_SRC(dev);
-
-    memory_region_init_io(&s->iomem, OBJECT(dev), &imx6_src_ops, s,
-                          TYPE_IMX6_SRC, 0x1000);
-    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
-}
-
-static void imx6_src_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-
-    dc->realize = imx6_src_realize;
-    dc->reset = imx6_src_reset;
-    dc->vmsd = &vmstate_imx6_src;
-    dc->desc = "i.MX6 System Reset Controller";
-}
-
-static const TypeInfo imx6_src_info = {
-    .name          = TYPE_IMX6_SRC,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(IMX6SRCState),
-    .class_init    = imx6_src_class_init,
-};
-
-static void imx6_src_register_types(void)
-{
-    type_register_static(&imx6_src_info);
-}
-
-type_init(imx6_src_register_types)
index 7f239a4..986d890 100644 (file)
@@ -13,7 +13,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/misc/imx_ccm.h"
-#include "qemu/log.h"
 
 #ifndef DEBUG_IMX_CCM
 #define DEBUG_IMX_CCM 0
index 40a2ebc..e40f23b 100644 (file)
 #include "sysemu/hostmem.h"
 #include "sysemu/qtest.h"
 #include "qapi/visitor.h"
+#include "exec/ram_addr.h"
 
 #include "hw/misc/ivshmem.h"
 
+#include <sys/mman.h>
+
 #define PCI_VENDOR_ID_IVSHMEM   PCI_VENDOR_ID_REDHAT_QUMRANET
 #define PCI_DEVICE_ID_IVSHMEM   0x1110
 
@@ -322,7 +325,6 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned vector,
     if (ret < 0) {
         return ret;
     }
-    kvm_irqchip_commit_routes(kvm_state);
 
     return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq);
 }
@@ -442,12 +444,13 @@ static void ivshmem_add_kvm_msi_virq(IVShmemState *s, int vector,
                                      Error **errp)
 {
     PCIDevice *pdev = PCI_DEVICE(s);
+    MSIMessage msg = msix_get_message(pdev, vector);
     int ret;
 
     IVSHMEM_DPRINTF("ivshmem_add_kvm_msi_virq vector:%d\n", vector);
     assert(!s->msi_vectors[vector].pdev);
 
-    ret = kvm_irqchip_add_msi_route(kvm_state, vector, pdev);
+    ret = kvm_irqchip_add_msi_route(kvm_state, msg, pdev);
     if (ret < 0) {
         error_setg(errp, "kvm_irqchip_add_msi_route failed");
         return;
@@ -530,7 +533,7 @@ static void process_msg_shmem(IVShmemState *s, int fd, Error **errp)
     }
     memory_region_init_ram_ptr(&s->server_bar2, OBJECT(s),
                                "ivshmem.bar2", size, ptr);
-    memory_region_set_fd(&s->server_bar2, fd);
+    qemu_set_ram_fd(memory_region_get_ram_addr(&s->server_bar2), fd);
     s->ivshmem_bar2 = &s->server_bar2;
 }
 
@@ -937,7 +940,7 @@ static void ivshmem_exit(PCIDevice *dev)
                              strerror(errno));
             }
 
-            fd = memory_region_get_fd(s->ivshmem_bar2);
+            fd = qemu_get_ram_fd(memory_region_get_ram_addr(s->ivshmem_bar2));
             close(fd);
         }
 
@@ -1008,7 +1011,10 @@ static const TypeInfo ivshmem_common_info = {
 static void ivshmem_check_memdev_is_busy(Object *obj, const char *name,
                                          Object *val, Error **errp)
 {
-    if (host_memory_backend_is_mapped(MEMORY_BACKEND(val))) {
+    MemoryRegion *mr;
+
+    mr = host_memory_backend_get_memory(MEMORY_BACKEND(val), &error_abort);
+    if (memory_region_is_mapped(mr)) {
         char *path = object_get_canonical_path_component(val);
         error_setg(errp, "can't use already busy memdev: %s", path);
         g_free(path);
@@ -1057,14 +1063,6 @@ static void ivshmem_plain_realize(PCIDevice *dev, Error **errp)
     }
 
     ivshmem_common_realize(dev, errp);
-    host_memory_backend_set_mapped(s->hostmem, true);
-}
-
-static void ivshmem_plain_exit(PCIDevice *pci_dev)
-{
-    IVShmemState *s = IVSHMEM_COMMON(pci_dev);
-
-    host_memory_backend_set_mapped(s->hostmem, false);
 }
 
 static void ivshmem_plain_class_init(ObjectClass *klass, void *data)
@@ -1073,7 +1071,6 @@ static void ivshmem_plain_class_init(ObjectClass *klass, void *data)
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->realize = ivshmem_plain_realize;
-    k->exit = ivshmem_plain_exit;
     dc->props = ivshmem_plain_properties;
     dc->vmsd = &ivshmem_plain_vmsd;
 }
index 05c02fb..f15f301 100644 (file)
@@ -29,7 +29,6 @@
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
 #include "qemu/cutils.h"
-#include "qemu/log.h"
 
 /* XXX: implement all timer modes */
 
index 15452b9..6051f17 100644 (file)
 #include "hw/isa/isa.h"
 #include "hw/ppc/mac_dbdma.h"
 #include "qemu/main-loop.h"
-#include "qemu/log.h"
-#include "sysemu/dma.h"
 
 /* debug DBDMA */
-#define DEBUG_DBDMA 0
-#define DEBUG_DBDMA_CHANMASK ((1ull << DBDMA_CHANNELS) - 1)
-
-#define DBDMA_DPRINTF(fmt, ...) do { \
-    if (DEBUG_DBDMA) { \
-        printf("DBDMA: " fmt , ## __VA_ARGS__); \
-    } \
-} while (0);
-
-#define DBDMA_DPRINTFCH(ch, fmt, ...) do { \
-    if (DEBUG_DBDMA) { \
-        if ((1ul << (ch)->channel) & DEBUG_DBDMA_CHANMASK) { \
-            printf("DBDMA[%02x]: " fmt , (ch)->channel, ## __VA_ARGS__); \
-        } \
-    } \
-} while (0);
+//#define DEBUG_DBDMA
+
+#ifdef DEBUG_DBDMA
+#define DBDMA_DPRINTF(fmt, ...)                                 \
+    do { printf("DBDMA: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DBDMA_DPRINTF(fmt, ...)
+#endif
 
 /*
  */
@@ -70,7 +60,7 @@ static DBDMAState *dbdma_from_ch(DBDMA_channel *ch)
     return container_of(ch, DBDMAState, channels[ch->channel]);
 }
 
-#if DEBUG_DBDMA
+#ifdef DEBUG_DBDMA
 static void dump_dbdma_cmd(dbdma_cmd *cmd)
 {
     printf("dbdma_cmd %p\n", cmd);
@@ -88,26 +78,26 @@ static void dump_dbdma_cmd(dbdma_cmd *cmd)
 #endif
 static void dbdma_cmdptr_load(DBDMA_channel *ch)
 {
-    DBDMA_DPRINTFCH(ch, "dbdma_cmdptr_load 0x%08x\n",
-                    ch->regs[DBDMA_CMDPTR_LO]);
-    dma_memory_read(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO],
-                    &ch->current, sizeof(dbdma_cmd));
+    DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n",
+                  ch->regs[DBDMA_CMDPTR_LO]);
+    cpu_physical_memory_read(ch->regs[DBDMA_CMDPTR_LO],
+                             &ch->current, sizeof(dbdma_cmd));
 }
 
 static void dbdma_cmdptr_save(DBDMA_channel *ch)
 {
-    DBDMA_DPRINTFCH(ch, "dbdma_cmdptr_save 0x%08x\n",
-                    ch->regs[DBDMA_CMDPTR_LO]);
-    DBDMA_DPRINTFCH(ch, "xfer_status 0x%08x res_count 0x%04x\n",
-                    le16_to_cpu(ch->current.xfer_status),
-                    le16_to_cpu(ch->current.res_count));
-    dma_memory_write(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO],
-                     &ch->current, sizeof(dbdma_cmd));
+    DBDMA_DPRINTF("dbdma_cmdptr_save 0x%08x\n",
+                  ch->regs[DBDMA_CMDPTR_LO]);
+    DBDMA_DPRINTF("xfer_status 0x%08x res_count 0x%04x\n",
+                  le16_to_cpu(ch->current.xfer_status),
+                  le16_to_cpu(ch->current.res_count));
+    cpu_physical_memory_write(ch->regs[DBDMA_CMDPTR_LO],
+                              &ch->current, sizeof(dbdma_cmd));
 }
 
 static void kill_channel(DBDMA_channel *ch)
 {
-    DBDMA_DPRINTFCH(ch, "kill_channel\n");
+    DBDMA_DPRINTF("kill_channel\n");
 
     ch->regs[DBDMA_STATUS] |= DEAD;
     ch->regs[DBDMA_STATUS] &= ~ACTIVE;
@@ -123,7 +113,7 @@ static void conditional_interrupt(DBDMA_channel *ch)
     uint32_t status;
     int cond;
 
-    DBDMA_DPRINTFCH(ch, "%s\n", __func__);
+    DBDMA_DPRINTF("%s\n", __func__);
 
     intr = le16_to_cpu(current->command) & INTR_MASK;
 
@@ -132,7 +122,7 @@ static void conditional_interrupt(DBDMA_channel *ch)
         return;
     case INTR_ALWAYS: /* always interrupt */
         qemu_irq_raise(ch->irq);
-        DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
+        DBDMA_DPRINTF("%s: raise\n", __func__);
         return;
     }
 
@@ -147,13 +137,13 @@ static void conditional_interrupt(DBDMA_channel *ch)
     case INTR_IFSET:  /* intr if condition bit is 1 */
         if (cond) {
             qemu_irq_raise(ch->irq);
-            DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
+            DBDMA_DPRINTF("%s: raise\n", __func__);
         }
         return;
     case INTR_IFCLR:  /* intr if condition bit is 0 */
         if (!cond) {
             qemu_irq_raise(ch->irq);
-            DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
+            DBDMA_DPRINTF("%s: raise\n", __func__);
         }
         return;
     }
@@ -167,7 +157,7 @@ static int conditional_wait(DBDMA_channel *ch)
     uint32_t status;
     int cond;
 
-    DBDMA_DPRINTFCH(ch, "conditional_wait\n");
+    DBDMA_DPRINTF("conditional_wait\n");
 
     wait = le16_to_cpu(current->command) & WAIT_MASK;
 
@@ -213,7 +203,7 @@ static void branch(DBDMA_channel *ch)
 {
     dbdma_cmd *current = &ch->current;
 
-    ch->regs[DBDMA_CMDPTR_LO] = le32_to_cpu(current->cmd_dep);
+    ch->regs[DBDMA_CMDPTR_LO] = current->cmd_dep;
     ch->regs[DBDMA_STATUS] |= BT;
     dbdma_cmdptr_load(ch);
 }
@@ -226,7 +216,7 @@ static void conditional_branch(DBDMA_channel *ch)
     uint32_t status;
     int cond;
 
-    DBDMA_DPRINTFCH(ch, "conditional_branch\n");
+    DBDMA_DPRINTF("conditional_branch\n");
 
     /* check if we must branch */
 
@@ -271,7 +261,7 @@ static void dbdma_end(DBDMA_io *io)
     DBDMA_channel *ch = io->channel;
     dbdma_cmd *current = &ch->current;
 
-    DBDMA_DPRINTFCH(ch, "%s\n", __func__);
+    DBDMA_DPRINTF("%s\n", __func__);
 
     if (conditional_wait(ch))
         goto wait;
@@ -297,13 +287,13 @@ wait:
 static void start_output(DBDMA_channel *ch, int key, uint32_t addr,
                         uint16_t req_count, int is_last)
 {
-    DBDMA_DPRINTFCH(ch, "start_output\n");
+    DBDMA_DPRINTF("start_output\n");
 
     /* KEY_REGS, KEY_DEVICE and KEY_STREAM
      * are not implemented in the mac-io chip
      */
 
-    DBDMA_DPRINTFCH(ch, "addr 0x%x key 0x%x\n", addr, key);
+    DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key);
     if (!addr || key > KEY_STREAM3) {
         kill_channel(ch);
         return;
@@ -323,13 +313,13 @@ static void start_output(DBDMA_channel *ch, int key, uint32_t addr,
 static void start_input(DBDMA_channel *ch, int key, uint32_t addr,
                        uint16_t req_count, int is_last)
 {
-    DBDMA_DPRINTFCH(ch, "start_input\n");
+    DBDMA_DPRINTF("start_input\n");
 
     /* KEY_REGS, KEY_DEVICE and KEY_STREAM
      * are not implemented in the mac-io chip
      */
 
-    DBDMA_DPRINTFCH(ch, "addr 0x%x key 0x%x\n", addr, key);
+    DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key);
     if (!addr || key > KEY_STREAM3) {
         kill_channel(ch);
         return;
@@ -350,8 +340,9 @@ static void load_word(DBDMA_channel *ch, int key, uint32_t addr,
                      uint16_t len)
 {
     dbdma_cmd *current = &ch->current;
+    uint32_t val;
 
-    DBDMA_DPRINTFCH(ch, "load_word %d bytes, addr=%08x\n", len, addr);
+    DBDMA_DPRINTF("load_word\n");
 
     /* only implements KEY_SYSTEM */
 
@@ -361,7 +352,14 @@ static void load_word(DBDMA_channel *ch, int key, uint32_t addr,
         return;
     }
 
-    dma_memory_read(&address_space_memory, addr, &current->cmd_dep, len);
+    cpu_physical_memory_read(addr, &val, len);
+
+    if (len == 2)
+        val = (val << 16) | (current->cmd_dep & 0x0000ffff);
+    else if (len == 1)
+        val = (val << 24) | (current->cmd_dep & 0x00ffffff);
+
+    current->cmd_dep = val;
 
     if (conditional_wait(ch))
         goto wait;
@@ -381,9 +379,9 @@ static void store_word(DBDMA_channel *ch, int key, uint32_t addr,
                       uint16_t len)
 {
     dbdma_cmd *current = &ch->current;
+    uint32_t val;
 
-    DBDMA_DPRINTFCH(ch, "store_word %d bytes, addr=%08x pa=%x\n",
-                    len, addr, le32_to_cpu(current->cmd_dep));
+    DBDMA_DPRINTF("store_word\n");
 
     /* only implements KEY_SYSTEM */
 
@@ -393,7 +391,13 @@ static void store_word(DBDMA_channel *ch, int key, uint32_t addr,
         return;
     }
 
-    dma_memory_write(&address_space_memory, addr, &current->cmd_dep, len);
+    val = current->cmd_dep;
+    if (len == 2)
+        val >>= 16;
+    else if (len == 1)
+        val >>= 24;
+
+    cpu_physical_memory_write(addr, &val, len);
 
     if (conditional_wait(ch))
         goto wait;
@@ -440,7 +444,7 @@ static void channel_run(DBDMA_channel *ch)
     uint16_t req_count;
     uint32_t phy_addr;
 
-    DBDMA_DPRINTFCH(ch, "channel_run\n");
+    DBDMA_DPRINTF("channel_run\n");
     dump_dbdma_cmd(current);
 
     /* clear WAKE flag at command fetch */
@@ -534,9 +538,9 @@ static void DBDMA_run_bh(void *opaque)
 {
     DBDMAState *s = opaque;
 
-    DBDMA_DPRINTF("-> DBDMA_run_bh\n");
+    DBDMA_DPRINTF("DBDMA_run_bh\n");
+
     DBDMA_run(s);
-    DBDMA_DPRINTF("<- DBDMA_run_bh\n");
 }
 
 void DBDMA_kick(DBDMAState *dbdma)
@@ -551,7 +555,7 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
     DBDMAState *s = dbdma;
     DBDMA_channel *ch = &s->channels[nchan];
 
-    DBDMA_DPRINTFCH(ch, "DBDMA_register_channel 0x%x\n", nchan);
+    DBDMA_DPRINTF("DBDMA_register_channel 0x%x\n", nchan);
 
     assert(rw);
     assert(flush);
@@ -595,7 +599,7 @@ dbdma_control_write(DBDMA_channel *ch)
         status &= ~FLUSH;
     }
 
-    DBDMA_DPRINTFCH(ch, "    status 0x%08x\n", status);
+    DBDMA_DPRINTF("    status 0x%08x\n", status);
 
     ch->regs[DBDMA_STATUS] = status;
 
@@ -612,10 +616,10 @@ static void dbdma_write(void *opaque, hwaddr addr,
     DBDMA_channel *ch = &s->channels[channel];
     int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;
 
-    DBDMA_DPRINTFCH(ch, "writel 0x" TARGET_FMT_plx " <= 0x%08"PRIx64"\n",
-                    addr, value);
-    DBDMA_DPRINTFCH(ch, "channel 0x%x reg 0x%x\n",
-                    (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
+    DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08"PRIx64"\n",
+                  addr, value);
+    DBDMA_DPRINTF("channel 0x%x reg 0x%x\n",
+                  (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
 
     /* cmdptr cannot be modified if channel is ACTIVE */
 
@@ -666,9 +670,9 @@ static uint64_t dbdma_read(void *opaque, hwaddr addr,
 
     value = ch->regs[reg];
 
-    DBDMA_DPRINTFCH(ch, "readl 0x" TARGET_FMT_plx " => 0x%08x\n", addr, value);
-    DBDMA_DPRINTFCH(ch, "channel 0x%x reg 0x%x\n",
-                    (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
+    DBDMA_DPRINTF("readl 0x" TARGET_FMT_plx " => 0x%08x\n", addr, value);
+    DBDMA_DPRINTF("channel 0x%x reg 0x%x\n",
+                  (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
 
     switch(reg) {
     case DBDMA_CONTROL:
@@ -778,24 +782,13 @@ static void dbdma_unassigned_rw(DBDMA_io *io)
     DBDMA_channel *ch = io->channel;
     qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
                   __func__, ch->channel);
-    ch->io.processing = false;
 }
 
 static void dbdma_unassigned_flush(DBDMA_io *io)
 {
     DBDMA_channel *ch = io->channel;
-    dbdma_cmd *current = &ch->current;
-    uint16_t cmd;
     qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
                   __func__, ch->channel);
-
-    cmd = le16_to_cpu(current->command) & COMMAND_MASK;
-    if (cmd == OUTPUT_MORE || cmd == OUTPUT_LAST ||
-        cmd == INPUT_MORE || cmd == INPUT_LAST) {
-        current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS] | FLUSH);
-        current->res_count = cpu_to_le16(io->len);
-        dbdma_cmdptr_save(ch);
-    }
 }
 
 void* DBDMA_init (MemoryRegion **dbdma_mem)
index 2a277bd..9014f0f 100644 (file)
@@ -147,14 +147,14 @@ static int max111x_init(SSISlave *d, int inputs)
     return 0;
 }
 
-static void max1110_realize(SSISlave *dev, Error **errp)
+static int max1110_init(SSISlave *dev)
 {
-    max111x_init(dev, 8);
+    return max111x_init(dev, 8);
 }
 
-static void max1111_realize(SSISlave *dev, Error **errp)
+static int max1111_init(SSISlave *dev)
 {
-    max111x_init(dev, 4);
+    return max111x_init(dev, 4);
 }
 
 void max111x_set_input(DeviceState *dev, int line, uint8_t value)
@@ -183,7 +183,7 @@ static void max1110_class_init(ObjectClass *klass, void *data)
 {
     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 
-    k->realize = max1110_realize;
+    k->init = max1110_init;
 }
 
 static const TypeInfo max1110_info = {
@@ -196,7 +196,7 @@ static void max1111_class_init(ObjectClass *klass, void *data)
 {
     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 
-    k->realize = max1111_realize;
+    k->init = max1111_init;
 }
 
 static const TypeInfo max1111_info = {
index e6140ee..b97000f 100644 (file)
@@ -18,7 +18,7 @@
  *
  *
  * Specification available at:
- *   http://milkymist.walle.cc/socdoc/hpdmc.pdf
+ *   http://www.milkymist.org/socdoc/hpdmc.pdf
  */
 
 #include "qemu/osdep.h"
index 1da21a6..57acd7b 100644 (file)
@@ -18,7 +18,7 @@
  *
  *
  * Specification available at:
- *   http://milkymist.walle.cc/socdoc/pfpu.pdf
+ *   http://www.milkymist.org/socdoc/pfpu.pdf
  *
  */
 
index b3ba166..37be239 100644 (file)
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qemu/log.h"
 #include "hw/hw.h"
 #include "hw/sysbus.h"
 #include "sysemu/sysemu.h"
 #include "hw/misc/mips_cmgcr.h"
 #include "hw/misc/mips_cpc.h"
-#include "hw/intc/mips_gic.h"
 
 static inline bool is_cpc_connected(MIPSGCRState *s)
 {
     return s->cpc_mr != NULL;
 }
 
-static inline bool is_gic_connected(MIPSGCRState *s)
-{
-    return s->gic_mr != NULL;
-}
-
 static inline void update_cpc_base(MIPSGCRState *gcr, uint64_t val)
 {
     if (is_cpc_connected(gcr)) {
@@ -42,25 +35,10 @@ static inline void update_cpc_base(MIPSGCRState *gcr, uint64_t val)
     }
 }
 
-static inline void update_gic_base(MIPSGCRState *gcr, uint64_t val)
-{
-    if (is_gic_connected(gcr)) {
-        gcr->gic_base = val & GCR_GIC_BASE_MSK;
-        memory_region_transaction_begin();
-        memory_region_set_address(gcr->gic_mr,
-                                  gcr->gic_base & GCR_GIC_BASE_GICBASE_MSK);
-        memory_region_set_enabled(gcr->gic_mr,
-                                  gcr->gic_base & GCR_GIC_BASE_GICEN_MSK);
-        memory_region_transaction_commit();
-    }
-}
-
 /* Read GCR registers */
 static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
 {
     MIPSGCRState *gcr = (MIPSGCRState *) opaque;
-    MIPSGCRVPState *current_vps = &gcr->vps[current_cpu->cpu_index];
-    MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other];
 
     switch (addr) {
     /* Global Control Block Register */
@@ -71,12 +49,8 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
         return gcr->gcr_base;
     case GCR_REV_OFS:
         return gcr->gcr_rev;
-    case GCR_GIC_BASE_OFS:
-        return gcr->gic_base;
     case GCR_CPC_BASE_OFS:
         return gcr->cpc_base;
-    case GCR_GIC_STATUS_OFS:
-        return is_gic_connected(gcr);
     case GCR_CPC_STATUS_OFS:
         return is_cpc_connected(gcr);
     case GCR_L2_CONFIG_OFS:
@@ -87,14 +61,8 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
     case MIPS_COCB_OFS + GCR_CL_CONFIG_OFS:
         /* Set PVP to # of VPs - 1 */
         return gcr->num_vps - 1;
-    case MIPS_CLCB_OFS + GCR_CL_RESETBASE_OFS:
-        return current_vps->reset_base;
-    case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS:
-        return other_vps->reset_base;
     case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS:
-        return current_vps->other;
-    case MIPS_COCB_OFS + GCR_CL_OTHER_OFS:
-        return other_vps->other;
+        return 0;
     default:
         qemu_log_mask(LOG_UNIMP, "Read %d bytes at GCR offset 0x%" HWADDR_PRIx
                       "\n", size, addr);
@@ -103,46 +71,15 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
     return 0;
 }
 
-static inline target_ulong get_exception_base(MIPSGCRVPState *vps)
-{
-    /* TODO: BEV_BASE and SELECT_BEV */
-    return (int32_t)(vps->reset_base & GCR_CL_RESET_BASE_RESETBASE_MSK);
-}
-
 /* Write GCR registers */
 static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
 {
     MIPSGCRState *gcr = (MIPSGCRState *)opaque;
-    MIPSGCRVPState *current_vps = &gcr->vps[current_cpu->cpu_index];
-    MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other];
 
     switch (addr) {
-    case GCR_GIC_BASE_OFS:
-        update_gic_base(gcr, data);
-        break;
     case GCR_CPC_BASE_OFS:
         update_cpc_base(gcr, data);
         break;
-    case MIPS_CLCB_OFS + GCR_CL_RESETBASE_OFS:
-        current_vps->reset_base = data & GCR_CL_RESET_BASE_MSK;
-        cpu_set_exception_base(current_cpu->cpu_index,
-                               get_exception_base(current_vps));
-        break;
-    case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS:
-        other_vps->reset_base = data & GCR_CL_RESET_BASE_MSK;
-        cpu_set_exception_base(current_vps->other,
-                               get_exception_base(other_vps));
-        break;
-    case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS:
-        if ((data & GCR_CL_OTHER_MSK) < gcr->num_vps) {
-            current_vps->other = data & GCR_CL_OTHER_MSK;
-        }
-        break;
-    case MIPS_COCB_OFS + GCR_CL_OTHER_OFS:
-        if ((data & GCR_CL_OTHER_MSK) < gcr->num_vps) {
-            other_vps->other = data & GCR_CL_OTHER_MSK;
-        }
-        break;
     default:
         qemu_log_mask(LOG_UNIMP, "Write %d bytes at GCR offset 0x%" HWADDR_PRIx
                       " 0x%" PRIx64 "\n", size, addr, data);
@@ -164,12 +101,6 @@ static void mips_gcr_init(Object *obj)
     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
     MIPSGCRState *s = MIPS_GCR(obj);
 
-    object_property_add_link(obj, "gic", TYPE_MEMORY_REGION,
-                             (Object **)&s->gic_mr,
-                             qdev_prop_allow_set_link_before_realize,
-                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
-                             &error_abort);
-
     object_property_add_link(obj, "cpc", TYPE_MEMORY_REGION,
                              (Object **)&s->cpc_mr,
                              qdev_prop_allow_set_link_before_realize,
@@ -184,16 +115,8 @@ static void mips_gcr_init(Object *obj)
 static void mips_gcr_reset(DeviceState *dev)
 {
     MIPSGCRState *s = MIPS_GCR(dev);
-    int i;
 
-    update_gic_base(s, 0);
     update_cpc_base(s, 0);
-
-    for (i = 0; i < s->num_vps; i++) {
-        s->vps[i].other = 0;
-        s->vps[i].reset_base = 0xBFC00000 & GCR_CL_RESET_BASE_MSK;
-        cpu_set_exception_base(i, get_exception_base(&s->vps[i]));
-    }
 }
 
 static const VMStateDescription vmstate_mips_gcr = {
@@ -213,21 +136,12 @@ static Property mips_gcr_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static void mips_gcr_realize(DeviceState *dev, Error **errp)
-{
-    MIPSGCRState *s = MIPS_GCR(dev);
-
-    /* Create local set of registers for each VP */
-    s->vps = g_new(MIPSGCRVPState, s->num_vps);
-}
-
 static void mips_gcr_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     dc->props = mips_gcr_properties;
     dc->vmsd = &vmstate_mips_gcr;
     dc->reset = mips_gcr_reset;
-    dc->realize = mips_gcr_realize;
 }
 
 static const TypeInfo mips_gcr_info = {
index 6d34574..d2b8e42 100644 (file)
@@ -19,8 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "cpu.h"
-#include "qemu/log.h"
 #include "hw/sysbus.h"
 
 #include "hw/misc/mips_cpc.h"
@@ -37,7 +35,7 @@ static void cpc_run_vp(MIPSCPCState *cpc, uint64_t vp_run)
     CPU_FOREACH(cs) {
         uint64_t i = 1ULL << cs->cpu_index;
         if (i & vp_run & ~cpc->vp_running) {
-            cpu_reset(cs);
+            cpu_interrupt(cs, CPU_INTERRUPT_WAKE);
             cpc->vp_running |= i;
         }
     }
@@ -50,7 +48,8 @@ static void cpc_stop_vp(MIPSCPCState *cpc, uint64_t vp_stop)
     CPU_FOREACH(cs) {
         uint64_t i = 1ULL << cs->cpu_index;
         if (i & vp_stop & cpc->vp_running) {
-            cpu_interrupt(cs, CPU_INTERRUPT_HALT);
+            cs->halted = 1;
+            cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE);
             cpc->vp_running &= ~i;
         }
     }
index ef935b5..da54550 100644 (file)
@@ -19,9 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "cpu.h"
-#include "qemu/log.h"
-#include "exec/exec-all.h"
 #include "hw/hw.h"
 #include "hw/sysbus.h"
 #include "sysemu/sysemu.h"
index a10f049..48d7dfb 100644 (file)
@@ -200,11 +200,10 @@ static int mst_fpga_post_load(void *opaque, int version_id)
        return 0;
 }
 
-static void mst_fpga_init(Object *obj)
+static int mst_fpga_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    mst_irq_state *s = MAINSTONE_FPGA(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    mst_irq_state *s = MAINSTONE_FPGA(dev);
 
     s->pcmcia0 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;
     s->pcmcia1 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;
@@ -214,9 +213,10 @@ static void mst_fpga_init(Object *obj)
     /* alloc the external 16 irqs */
     qdev_init_gpio_in(dev, mst_fpga_set_irq, MST_NUM_IRQS);
 
-    memory_region_init_io(&s->iomem, obj, &mst_fpga_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &mst_fpga_ops, s,
                           "fpga", 0x00100000);
     sysbus_init_mmio(sbd, &s->iomem);
+    return 0;
 }
 
 static VMStateDescription vmstate_mst_fpga_regs = {
@@ -245,7 +245,9 @@ static VMStateDescription vmstate_mst_fpga_regs = {
 static void mst_fpga_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
+    k->init = mst_fpga_init;
     dc->desc = "Mainstone II FPGA";
     dc->vmsd = &vmstate_mst_fpga_regs;
 }
@@ -254,7 +256,6 @@ static const TypeInfo mst_fpga_info = {
     .name          = TYPE_MAINSTONE_FPGA,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(mst_irq_state),
-    .instance_init = mst_fpga_init,
     .class_init    = mst_fpga_class_init,
 };
 
index b81d820..086893d 100644 (file)
@@ -36,6 +36,9 @@
 */
 
 #include "qemu/osdep.h"
+#if defined(CONFIG_POSIX)
+#include <sys/mman.h>
+#endif
 #include "hw/hw.h"
 #include "hw/qdev.h"
 #include "hw/isa/isa.h"
index 7d59902..2f2e989 100644 (file)
@@ -21,7 +21,6 @@
 #include "hw/hw.h"
 #include "hw/pci/pci.h"
 #include "qemu/event_notifier.h"
-#include "sysemu/kvm.h"
 
 typedef struct PCITestDevHdr {
     uint8_t test;
index 7c45833..d0d7076 100644 (file)
@@ -24,7 +24,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/misc/stm32f2xx_syscfg.h"
-#include "qemu/log.h"
 
 #ifndef STM_SYSCFG_ERR_DEBUG
 #define STM_SYSCFG_ERR_DEBUG 0
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
deleted file mode 100644 (file)
index 0cc556c..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/misc/eccmemctl.c
-ecc_mem_writel_mer(uint32_t val) "Write memory enable %08x"
-ecc_mem_writel_mdr(uint32_t val) "Write memory delay %08x"
-ecc_mem_writel_mfsr(uint32_t val) "Write memory fault status %08x"
-ecc_mem_writel_vcr(uint32_t val) "Write slot configuration %08x"
-ecc_mem_writel_dr(uint32_t val) "Write diagnostic %08x"
-ecc_mem_writel_ecr0(uint32_t val) "Write event count 1 %08x"
-ecc_mem_writel_ecr1(uint32_t val) "Write event count 2 %08x"
-ecc_mem_readl_mer(uint32_t ret) "Read memory enable %08x"
-ecc_mem_readl_mdr(uint32_t ret) "Read memory delay %08x"
-ecc_mem_readl_mfsr(uint32_t ret) "Read memory fault status %08x"
-ecc_mem_readl_vcr(uint32_t ret) "Read slot configuration %08x"
-ecc_mem_readl_mfar0(uint32_t ret) "Read memory fault address 0 %08x"
-ecc_mem_readl_mfar1(uint32_t ret) "Read memory fault address 1 %08x"
-ecc_mem_readl_dr(uint32_t ret) "Read diagnostic %08x"
-ecc_mem_readl_ecr0(uint32_t ret) "Read event count 1 %08x"
-ecc_mem_readl_ecr1(uint32_t ret) "Read event count 2 %08x"
-ecc_diag_mem_writeb(uint64_t addr, uint32_t val) "Write diagnostic %"PRId64" = %02x"
-ecc_diag_mem_readb(uint64_t addr, uint32_t ret) "Read diagnostic %"PRId64"= %02x"
-
-# hw/misc/slavio_misc.c
-slavio_misc_update_irq_raise(void) "Raise IRQ"
-slavio_misc_update_irq_lower(void) "Lower IRQ"
-slavio_set_power_fail(int power_failing, uint8_t config) "Power fail: %d, config: %d"
-slavio_cfg_mem_writeb(uint32_t val) "Write config %02x"
-slavio_cfg_mem_readb(uint32_t ret) "Read config %02x"
-slavio_diag_mem_writeb(uint32_t val) "Write diag %02x"
-slavio_diag_mem_readb(uint32_t ret) "Read diag %02x"
-slavio_mdm_mem_writeb(uint32_t val) "Write modem control %02x"
-slavio_mdm_mem_readb(uint32_t ret) "Read modem control %02x"
-slavio_aux1_mem_writeb(uint32_t val) "Write aux1 %02x"
-slavio_aux1_mem_readb(uint32_t ret) "Read aux1 %02x"
-slavio_aux2_mem_writeb(uint32_t val) "Write aux2 %02x"
-slavio_aux2_mem_readb(uint32_t ret) "Read aux2 %02x"
-apc_mem_writeb(uint32_t val) "Write power management %02x"
-apc_mem_readb(uint32_t ret) "Read power management %02x"
-slavio_sysctrl_mem_writel(uint32_t val) "Write system control %08x"
-slavio_sysctrl_mem_readl(uint32_t ret) "Read system control %08x"
-slavio_led_mem_writew(uint32_t val) "Write diagnostic LED %04x"
-slavio_led_mem_readw(uint32_t ret) "Read diagnostic LED %04x"
-
-# hw/misc/milkymist-hpdmc.c
-milkymist_hpdmc_memory_read(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
-milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
-
-# hw/misc/milkymist-pfpu.c
-milkymist_pfpu_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_pfpu_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_pfpu_vectout(uint32_t a, uint32_t b, uint32_t dma_ptr) "a %08x b %08x dma_ptr %08x"
-milkymist_pfpu_pulse_irq(void) "Pulse IRQ"
-
-# hw/misc/aspeed_scu.c
-aspeed_scu_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
index c763811..6896789 100644 (file)
@@ -36,6 +36,7 @@
 #define VMPORT_ENTRIES 0x2c
 #define VMPORT_MAGIC   0x564D5868
 
+#define TYPE_VMPORT "vmport"
 #define VMPORT(obj) OBJECT_CHECK(VMPortState, (obj), TYPE_VMPORT)
 
 typedef struct VMPortState
index 1490610..71fbccd 100644 (file)
@@ -18,7 +18,6 @@
 #include "hw/misc/zynq-xadc.h"
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
-#include "qemu/log.h"
 
 enum {
     CFG                = 0x000 / 4,
index 7891219..b1b7591 100644 (file)
@@ -19,7 +19,6 @@
 #include "qemu/timer.h"
 #include "hw/sysbus.h"
 #include "sysemu/sysemu.h"
-#include "qemu/log.h"
 
 #ifndef ZYNQ_SLCR_ERR_DEBUG
 #define ZYNQ_SLCR_ERR_DEBUG 0
index 610ed3e..64d0449 100644 (file)
@@ -6,11 +6,9 @@ common-obj-$(CONFIG_NE2000_PCI) += ne2000.o
 common-obj-$(CONFIG_EEPRO100_PCI) += eepro100.o
 common-obj-$(CONFIG_PCNET_PCI) += pcnet-pci.o
 common-obj-$(CONFIG_PCNET_COMMON) += pcnet.o
-common-obj-$(CONFIG_E1000_PCI) += e1000.o e1000x_common.o
-common-obj-$(CONFIG_E1000E_PCI) += net_tx_pkt.o net_rx_pkt.o
-common-obj-$(CONFIG_E1000E_PCI) += e1000e.o e1000e_core.o e1000x_common.o
+common-obj-$(CONFIG_E1000_PCI) += e1000.o
 common-obj-$(CONFIG_RTL8139_PCI) += rtl8139.o
-common-obj-$(CONFIG_VMXNET3_PCI) += net_tx_pkt.o net_rx_pkt.o
+common-obj-$(CONFIG_VMXNET3_PCI) += vmxnet_tx_pkt.o vmxnet_rx_pkt.o
 common-obj-$(CONFIG_VMXNET3_PCI) += vmxnet3.o
 
 common-obj-$(CONFIG_SMC91C111) += smc91c111.o
index 50e8361..16d4b63 100644 (file)
@@ -21,7 +21,6 @@
 #include "net/net.h"
 #include "qemu/fifo8.h"
 #include "hw/net/allwinner_emac.h"
-#include "qemu/log.h"
 #include <zlib.h>
 
 static uint8_t padding[60];
@@ -424,7 +423,7 @@ static const MemoryRegionOps aw_emac_mem_ops = {
 };
 
 static NetClientInfo net_aw_emac_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .can_receive = aw_emac_can_receive,
     .receive = aw_emac_receive,
index db1b301..0346f3e 100644 (file)
@@ -274,11 +274,6 @@ static inline unsigned tx_desc_get_last(unsigned *desc)
     return (desc[1] & DESC_1_TX_LAST) ? 1 : 0;
 }
 
-static inline void tx_desc_set_last(unsigned *desc)
-{
-    desc[1] |= DESC_1_TX_LAST;
-}
-
 static inline unsigned tx_desc_get_length(unsigned *desc)
 {
     return desc[1] & DESC_1_LENGTH;
@@ -669,13 +664,6 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
                  GEM_DMACFG_RBUFSZ_S) * GEM_DMACFG_RBUFSZ_MUL;
     bytes_to_copy = size;
 
-    /* Hardware allows a zero value here but warns against it. To avoid QEMU
-     * indefinite loops we enforce a minimum value here
-     */
-    if (rxbufsize < GEM_DMACFG_RBUFSZ_MUL) {
-        rxbufsize = GEM_DMACFG_RBUFSZ_MUL;
-    }
-
     /* Pad to minimum length. Assume FCS field is stripped, logic
      * below will increment it to the real minimum of 64 when
      * not FCS stripping
@@ -944,7 +932,6 @@ static void gem_transmit(CadenceGEMState *s)
 
         /* read next descriptor */
         if (tx_desc_get_wrap(desc)) {
-            tx_desc_set_last(desc);
             packet_desc_addr = s->regs[GEM_TXQBASE];
         } else {
             packet_desc_addr += 8;
@@ -1207,7 +1194,7 @@ static void gem_set_link(NetClientState *nc)
 }
 
 static NetClientInfo net_gem_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .can_receive = gem_can_receive,
     .receive = gem_receive,
index 17f0338..0fa652c 100644 (file)
@@ -812,7 +812,7 @@ static void dp8393x_reset(DeviceState *dev)
 }
 
 static NetClientInfo net_dp83932_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .can_receive = dp8393x_can_receive,
     .receive = dp8393x_receive,
index 9324949..8e79b55 100644 (file)
@@ -36,7 +36,7 @@
 #include "qemu/iov.h"
 #include "qemu/range.h"
 
-#include "e1000x_common.h"
+#include "e1000_regs.h"
 
 static const uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
@@ -64,6 +64,11 @@ static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL);
 #define PNPMMIO_SIZE      0x20000
 #define MIN_BUF_SIZE      60 /* Min. octets in an ethernet frame sans FCS */
 
+/* this is the size past which hardware will drop packets when setting LPE=0 */
+#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
+/* this is the size past which hardware will drop packets when setting LPE=1 */
+#define MAXIMUM_ETHERNET_LPE_SIZE 16384
+
 #define MAXIMUM_ETHERNET_HDR_LEN (14+4)
 
 /*
@@ -97,9 +102,22 @@ typedef struct E1000State_st {
         unsigned char vlan[4];
         unsigned char data[0x10000];
         uint16_t size;
+        unsigned char sum_needed;
         unsigned char vlan_needed;
-        e1000x_txd_props props;
+        uint8_t ipcss;
+        uint8_t ipcso;
+        uint16_t ipcse;
+        uint8_t tucss;
+        uint8_t tucso;
+        uint16_t tucse;
+        uint8_t hdr_len;
+        uint16_t mss;
+        uint32_t paylen;
         uint16_t tso_frames;
+        char tse;
+        int8_t ip;
+        int8_t tcp;
+        char cptse;     // current packet tse bit
     } tx;
 
     struct {
@@ -144,19 +162,52 @@ typedef struct E1000BaseClass {
 #define E1000_DEVICE_GET_CLASS(obj) \
     OBJECT_GET_CLASS(E1000BaseClass, (obj), TYPE_E1000_BASE)
 
+#define defreg(x)    x = (E1000_##x>>2)
+enum {
+    defreg(CTRL),    defreg(EECD),    defreg(EERD),    defreg(GPRC),
+    defreg(GPTC),    defreg(ICR),     defreg(ICS),     defreg(IMC),
+    defreg(IMS),     defreg(LEDCTL),  defreg(MANC),    defreg(MDIC),
+    defreg(MPC),     defreg(PBA),     defreg(RCTL),    defreg(RDBAH),
+    defreg(RDBAL),   defreg(RDH),     defreg(RDLEN),   defreg(RDT),
+    defreg(STATUS),  defreg(SWSM),    defreg(TCTL),    defreg(TDBAH),
+    defreg(TDBAL),   defreg(TDH),     defreg(TDLEN),   defreg(TDT),
+    defreg(TORH),    defreg(TORL),    defreg(TOTH),    defreg(TOTL),
+    defreg(TPR),     defreg(TPT),     defreg(TXDCTL),  defreg(WUFC),
+    defreg(RA),      defreg(MTA),     defreg(CRCERRS), defreg(VFTA),
+    defreg(VET),     defreg(RDTR),    defreg(RADV),    defreg(TADV),
+    defreg(ITR),     defreg(FCRUC),   defreg(TDFH),    defreg(TDFT),
+    defreg(TDFHS),   defreg(TDFTS),   defreg(TDFPC),   defreg(RDFH),
+    defreg(RDFT),    defreg(RDFHS),   defreg(RDFTS),   defreg(RDFPC),
+    defreg(IPAV),    defreg(WUC),     defreg(WUS),     defreg(AIT),
+    defreg(IP6AT),   defreg(IP4AT),   defreg(FFLT),    defreg(FFMT),
+    defreg(FFVT),    defreg(WUPM),    defreg(PBM),     defreg(SCC),
+    defreg(ECOL),    defreg(MCC),     defreg(LATECOL), defreg(COLC),
+    defreg(DC),      defreg(TNCRS),   defreg(SEC),     defreg(CEXTERR),
+    defreg(RLEC),    defreg(XONRXC),  defreg(XONTXC),  defreg(XOFFRXC),
+    defreg(XOFFTXC), defreg(RFC),     defreg(RJC),     defreg(RNBC),
+    defreg(TSCTFC),  defreg(MGTPRC),  defreg(MGTPDC),  defreg(MGTPTC),
+    defreg(RUC),     defreg(ROC),     defreg(GORCL),   defreg(GORCH),
+    defreg(GOTCL),   defreg(GOTCH),   defreg(BPRC),    defreg(MPRC),
+    defreg(TSCTC),   defreg(PRC64),   defreg(PRC127),  defreg(PRC255),
+    defreg(PRC511),  defreg(PRC1023), defreg(PRC1522), defreg(PTC64),
+    defreg(PTC127),  defreg(PTC255),  defreg(PTC511),  defreg(PTC1023),
+    defreg(PTC1522), defreg(MPTC),    defreg(BPTC)
+};
+
 static void
-e1000_link_up(E1000State *s)
+e1000_link_down(E1000State *s)
 {
-    e1000x_update_regs_on_link_up(s->mac_reg, s->phy_reg);
-
-    /* E1000_STATUS_LU is tested by e1000_can_receive() */
-    qemu_flush_queued_packets(qemu_get_queue(s->nic));
+    s->mac_reg[STATUS] &= ~E1000_STATUS_LU;
+    s->phy_reg[PHY_STATUS] &= ~MII_SR_LINK_STATUS;
+    s->phy_reg[PHY_STATUS] &= ~MII_SR_AUTONEG_COMPLETE;
+    s->phy_reg[PHY_LP_ABILITY] &= ~MII_LPAR_LPACK;
 }
 
 static void
-e1000_autoneg_done(E1000State *s)
+e1000_link_up(E1000State *s)
 {
-    e1000x_update_regs_on_autoneg_done(s->mac_reg, s->phy_reg);
+    s->mac_reg[STATUS] |= E1000_STATUS_LU;
+    s->phy_reg[PHY_STATUS] |= MII_SR_LINK_STATUS;
 
     /* E1000_STATUS_LU is tested by e1000_can_receive() */
     qemu_flush_queued_packets(qemu_get_queue(s->nic));
@@ -182,7 +233,10 @@ set_phy_ctrl(E1000State *s, int index, uint16_t val)
      * down.
      */
     if (have_autoneg(s) && (val & MII_CR_RESTART_AUTO_NEG)) {
-        e1000x_restart_autoneg(s->mac_reg, s->phy_reg, s->autoneg_timer);
+        e1000_link_down(s);
+        DBGOUT(PHY, "Start link auto negotiation\n");
+        timer_mod(s->autoneg_timer,
+                  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);
     }
 }
 
@@ -311,9 +365,11 @@ set_interrupt_cause(E1000State *s, int index, uint32_t val)
              */
             mit_delay = (mit_delay < 500) ? 500 : mit_delay;
 
-            s->mit_timer_on = 1;
-            timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-                      mit_delay * 256);
+            if (mit_delay) {
+                s->mit_timer_on = 1;
+                timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+                          mit_delay * 256);
+            }
             s->mit_ide = 0;
         }
     }
@@ -345,16 +401,43 @@ e1000_autoneg_timer(void *opaque)
 {
     E1000State *s = opaque;
     if (!qemu_get_queue(s->nic)->link_down) {
-        e1000_autoneg_done(s);
+        e1000_link_up(s);
+        s->phy_reg[PHY_LP_ABILITY] |= MII_LPAR_LPACK;
+        s->phy_reg[PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE;
+        DBGOUT(PHY, "Auto negotiation is completed\n");
         set_ics(s, 0, E1000_ICS_LSC); /* signal link status change to guest */
     }
 }
 
+static int
+rxbufsize(uint32_t v)
+{
+    v &= E1000_RCTL_BSEX | E1000_RCTL_SZ_16384 | E1000_RCTL_SZ_8192 |
+         E1000_RCTL_SZ_4096 | E1000_RCTL_SZ_2048 | E1000_RCTL_SZ_1024 |
+         E1000_RCTL_SZ_512 | E1000_RCTL_SZ_256;
+    switch (v) {
+    case E1000_RCTL_BSEX | E1000_RCTL_SZ_16384:
+        return 16384;
+    case E1000_RCTL_BSEX | E1000_RCTL_SZ_8192:
+        return 8192;
+    case E1000_RCTL_BSEX | E1000_RCTL_SZ_4096:
+        return 4096;
+    case E1000_RCTL_SZ_1024:
+        return 1024;
+    case E1000_RCTL_SZ_512:
+        return 512;
+    case E1000_RCTL_SZ_256:
+        return 256;
+    }
+    return 2048;
+}
+
 static void e1000_reset(void *opaque)
 {
     E1000State *d = opaque;
     E1000BaseClass *edc = E1000_DEVICE_GET_CLASS(d);
     uint8_t *macaddr = d->conf.macaddr.a;
+    int i;
 
     timer_del(d->autoneg_timer);
     timer_del(d->mit_timer);
@@ -370,10 +453,17 @@ static void e1000_reset(void *opaque)
     memset(&d->tx, 0, sizeof d->tx);
 
     if (qemu_get_queue(d->nic)->link_down) {
-        e1000x_update_regs_on_link_down(d->mac_reg, d->phy_reg);
+        e1000_link_down(d);
     }
 
-    e1000x_reset_mac_addr(d->nic, d->mac_reg, macaddr);
+    /* Some guests expect pre-initialized RAH/RAL (AddrValid flag + MACaddr) */
+    d->mac_reg[RA] = 0;
+    d->mac_reg[RA + 1] = E1000_RAH_AV;
+    for (i = 0; i < 4; i++) {
+        d->mac_reg[RA] |= macaddr[i] << (8 * i);
+        d->mac_reg[RA + 1] |= (i < 2) ? macaddr[i + 4] << (8 * i) : 0;
+    }
+    qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr);
 }
 
 static void
@@ -387,7 +477,7 @@ static void
 set_rx_control(E1000State *s, int index, uint32_t val)
 {
     s->mac_reg[RCTL] = val;
-    s->rxbuf_size = e1000x_rxbufsize(val);
+    s->rxbuf_size = rxbufsize(val);
     s->rxbuf_min_shift = ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1;
     DBGOUT(RX, "RCTL: %d, mac_reg[RCTL] = 0x%x\n", s->mac_reg[RDT],
            s->mac_reg[RCTL]);
@@ -508,15 +598,89 @@ putsum(uint8_t *data, uint32_t n, uint32_t sloc, uint32_t css, uint32_t cse)
 }
 
 static inline void
+inc_reg_if_not_full(E1000State *s, int index)
+{
+    if (s->mac_reg[index] != 0xffffffff) {
+        s->mac_reg[index]++;
+    }
+}
+
+static inline void
 inc_tx_bcast_or_mcast_count(E1000State *s, const unsigned char *arr)
 {
     if (!memcmp(arr, bcast, sizeof bcast)) {
-        e1000x_inc_reg_if_not_full(s->mac_reg, BPTC);
+        inc_reg_if_not_full(s, BPTC);
     } else if (arr[0] & 1) {
-        e1000x_inc_reg_if_not_full(s->mac_reg, MPTC);
+        inc_reg_if_not_full(s, MPTC);
+    }
+}
+
+static void
+grow_8reg_if_not_full(E1000State *s, int index, int size)
+{
+    uint64_t sum = s->mac_reg[index] | (uint64_t)s->mac_reg[index+1] << 32;
+
+    if (sum + size < sum) {
+        sum = ~0ULL;
+    } else {
+        sum += size;
+    }
+    s->mac_reg[index] = sum;
+    s->mac_reg[index+1] = sum >> 32;
+}
+
+static void
+increase_size_stats(E1000State *s, const int *size_regs, int size)
+{
+    if (size > 1023) {
+        inc_reg_if_not_full(s, size_regs[5]);
+    } else if (size > 511) {
+        inc_reg_if_not_full(s, size_regs[4]);
+    } else if (size > 255) {
+        inc_reg_if_not_full(s, size_regs[3]);
+    } else if (size > 127) {
+        inc_reg_if_not_full(s, size_regs[2]);
+    } else if (size > 64) {
+        inc_reg_if_not_full(s, size_regs[1]);
+    } else if (size == 64) {
+        inc_reg_if_not_full(s, size_regs[0]);
     }
 }
 
+static inline int
+vlan_enabled(E1000State *s)
+{
+    return ((s->mac_reg[CTRL] & E1000_CTRL_VME) != 0);
+}
+
+static inline int
+vlan_rx_filter_enabled(E1000State *s)
+{
+    return ((s->mac_reg[RCTL] & E1000_RCTL_VFE) != 0);
+}
+
+static inline int
+is_vlan_packet(E1000State *s, const uint8_t *buf)
+{
+    return (be16_to_cpup((uint16_t *)(buf + 12)) ==
+                le16_to_cpu(s->mac_reg[VET]));
+}
+
+static inline int
+is_vlan_txd(uint32_t txd_lower)
+{
+    return ((txd_lower & E1000_TXD_CMD_VLE) != 0);
+}
+
+/* FCS aka Ethernet CRC-32. We don't get it from backends and can't
+ * fill it in, just pad descriptor length by 4 bytes unless guest
+ * told us to strip it off the packet. */
+static inline int
+fcs_len(E1000State *s)
+{
+    return (s->mac_reg[RCTL] & E1000_RCTL_SECRC) ? 0 : 4;
+}
+
 static void
 e1000_send_packet(E1000State *s, const uint8_t *buf, int size)
 {
@@ -530,60 +694,55 @@ e1000_send_packet(E1000State *s, const uint8_t *buf, int size)
         qemu_send_packet(nc, buf, size);
     }
     inc_tx_bcast_or_mcast_count(s, buf);
-    e1000x_increase_size_stats(s->mac_reg, PTCregs, size);
+    increase_size_stats(s, PTCregs, size);
 }
 
 static void
 xmit_seg(E1000State *s)
 {
-    uint16_t len;
+    uint16_t len, *sp;
     unsigned int frames = s->tx.tso_frames, css, sofar;
     struct e1000_tx *tp = &s->tx;
 
-    if (tp->props.tse && tp->props.cptse) {
-        css = tp->props.ipcss;
+    if (tp->tse && tp->cptse) {
+        css = tp->ipcss;
         DBGOUT(TXSUM, "frames %d size %d ipcss %d\n",
                frames, tp->size, css);
-        if (tp->props.ip) {    /* IPv4 */
+        if (tp->ip) {    /* IPv4 */
             stw_be_p(tp->data+css+2, tp->size - css);
             stw_be_p(tp->data+css+4,
-                     lduw_be_p(tp->data + css + 4) + frames);
+                     be16_to_cpup((uint16_t *)(tp->data+css+4))+frames);
         } else {         /* IPv6 */
             stw_be_p(tp->data+css+4, tp->size - css);
         }
-        css = tp->props.tucss;
+        css = tp->tucss;
         len = tp->size - css;
-        DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", tp->props.tcp, css, len);
-        if (tp->props.tcp) {
-            sofar = frames * tp->props.mss;
+        DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", tp->tcp, css, len);
+        if (tp->tcp) {
+            sofar = frames * tp->mss;
             stl_be_p(tp->data+css+4, ldl_be_p(tp->data+css+4)+sofar); /* seq */
-            if (tp->props.paylen - sofar > tp->props.mss) {
+            if (tp->paylen - sofar > tp->mss) {
                 tp->data[css + 13] &= ~9;    /* PSH, FIN */
             } else if (frames) {
-                e1000x_inc_reg_if_not_full(s->mac_reg, TSCTC);
+                inc_reg_if_not_full(s, TSCTC);
             }
         } else    /* UDP */
             stw_be_p(tp->data+css+4, len);
-        if (tp->props.sum_needed & E1000_TXD_POPTS_TXSM) {
+        if (tp->sum_needed & E1000_TXD_POPTS_TXSM) {
             unsigned int phsum;
             // add pseudo-header length before checksum calculation
-            void *sp = tp->data + tp->props.tucso;
-
-            phsum = lduw_be_p(sp) + len;
+            sp = (uint16_t *)(tp->data + tp->tucso);
+            phsum = be16_to_cpup(sp) + len;
             phsum = (phsum >> 16) + (phsum & 0xffff);
             stw_be_p(sp, phsum);
         }
         tp->tso_frames++;
     }
 
-    if (tp->props.sum_needed & E1000_TXD_POPTS_TXSM) {
-        putsum(tp->data, tp->size, tp->props.tucso,
-               tp->props.tucss, tp->props.tucse);
-    }
-    if (tp->props.sum_needed & E1000_TXD_POPTS_IXSM) {
-        putsum(tp->data, tp->size, tp->props.ipcso,
-               tp->props.ipcss, tp->props.ipcse);
-    }
+    if (tp->sum_needed & E1000_TXD_POPTS_TXSM)
+        putsum(tp->data, tp->size, tp->tucso, tp->tucss, tp->tucse);
+    if (tp->sum_needed & E1000_TXD_POPTS_IXSM)
+        putsum(tp->data, tp->size, tp->ipcso, tp->ipcss, tp->ipcse);
     if (tp->vlan_needed) {
         memmove(tp->vlan, tp->data, 4);
         memmove(tp->data, tp->data + 4, 8);
@@ -593,8 +752,8 @@ xmit_seg(E1000State *s)
         e1000_send_packet(s, tp->data, tp->size);
     }
 
-    e1000x_inc_reg_if_not_full(s->mac_reg, TPT);
-    e1000x_grow_8reg_if_not_full(s->mac_reg, TOTL, s->tx.size);
+    inc_reg_if_not_full(s, TPT);
+    grow_8reg_if_not_full(s, TOTL, s->tx.size);
     s->mac_reg[GPTC] = s->mac_reg[TPT];
     s->mac_reg[GOTCL] = s->mac_reg[TOTL];
     s->mac_reg[GOTCH] = s->mac_reg[TOTH];
@@ -606,7 +765,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
     PCIDevice *d = PCI_DEVICE(s);
     uint32_t txd_lower = le32_to_cpu(dp->lower.data);
     uint32_t dtype = txd_lower & (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D);
-    unsigned int split_size = txd_lower & 0xffff, bytes, sz;
+    unsigned int split_size = txd_lower & 0xffff, bytes, sz, op;
     unsigned int msh = 0xfffff;
     uint64_t addr;
     struct e1000_context_desc *xp = (struct e1000_context_desc *)dp;
@@ -614,27 +773,38 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
 
     s->mit_ide |= (txd_lower & E1000_TXD_CMD_IDE);
     if (dtype == E1000_TXD_CMD_DEXT) {    /* context descriptor */
-        e1000x_read_tx_ctx_descr(xp, &tp->props);
+        op = le32_to_cpu(xp->cmd_and_length);
+        tp->ipcss = xp->lower_setup.ip_fields.ipcss;
+        tp->ipcso = xp->lower_setup.ip_fields.ipcso;
+        tp->ipcse = le16_to_cpu(xp->lower_setup.ip_fields.ipcse);
+        tp->tucss = xp->upper_setup.tcp_fields.tucss;
+        tp->tucso = xp->upper_setup.tcp_fields.tucso;
+        tp->tucse = le16_to_cpu(xp->upper_setup.tcp_fields.tucse);
+        tp->paylen = op & 0xfffff;
+        tp->hdr_len = xp->tcp_seg_setup.fields.hdr_len;
+        tp->mss = le16_to_cpu(xp->tcp_seg_setup.fields.mss);
+        tp->ip = (op & E1000_TXD_CMD_IP) ? 1 : 0;
+        tp->tcp = (op & E1000_TXD_CMD_TCP) ? 1 : 0;
+        tp->tse = (op & E1000_TXD_CMD_TSE) ? 1 : 0;
         tp->tso_frames = 0;
-        if (tp->props.tucso == 0) {    /* this is probably wrong */
+        if (tp->tucso == 0) {    /* this is probably wrong */
             DBGOUT(TXSUM, "TCP/UDP: cso 0!\n");
-            tp->props.tucso = tp->props.tucss + (tp->props.tcp ? 16 : 6);
+            tp->tucso = tp->tucss + (tp->tcp ? 16 : 6);
         }
         return;
     } else if (dtype == (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D)) {
         // data descriptor
         if (tp->size == 0) {
-            tp->props.sum_needed = le32_to_cpu(dp->upper.data) >> 8;
+            tp->sum_needed = le32_to_cpu(dp->upper.data) >> 8;
         }
-        tp->props.cptse = (txd_lower & E1000_TXD_CMD_TSE) ? 1 : 0;
+        tp->cptse = ( txd_lower & E1000_TXD_CMD_TSE ) ? 1 : 0;
     } else {
         // legacy descriptor
-        tp->props.cptse = 0;
+        tp->cptse = 0;
     }
 
-    if (e1000x_vlan_enabled(s->mac_reg) &&
-        e1000x_is_vlan_txd(txd_lower) &&
-        (tp->props.cptse || txd_lower & E1000_TXD_CMD_EOP)) {
+    if (vlan_enabled(s) && is_vlan_txd(txd_lower) &&
+        (tp->cptse || txd_lower & E1000_TXD_CMD_EOP)) {
         tp->vlan_needed = 1;
         stw_be_p(tp->vlan_header,
                       le16_to_cpu(s->mac_reg[VET]));
@@ -643,8 +813,8 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
     }
 
     addr = le64_to_cpu(dp->buffer_addr);
-    if (tp->props.tse && tp->props.cptse) {
-        msh = tp->props.hdr_len + tp->props.mss;
+    if (tp->tse && tp->cptse) {
+        msh = tp->hdr_len + tp->mss;
         do {
             bytes = split_size;
             if (tp->size + bytes > msh)
@@ -653,19 +823,19 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
             bytes = MIN(sizeof(tp->data) - tp->size, bytes);
             pci_dma_read(d, addr, tp->data + tp->size, bytes);
             sz = tp->size + bytes;
-            if (sz >= tp->props.hdr_len && tp->size < tp->props.hdr_len) {
-                memmove(tp->header, tp->data, tp->props.hdr_len);
+            if (sz >= tp->hdr_len && tp->size < tp->hdr_len) {
+                memmove(tp->header, tp->data, tp->hdr_len);
             }
             tp->size = sz;
             addr += bytes;
             if (sz == msh) {
                 xmit_seg(s);
-                memmove(tp->data, tp->header, tp->props.hdr_len);
-                tp->size = tp->props.hdr_len;
+                memmove(tp->data, tp->header, tp->hdr_len);
+                tp->size = tp->hdr_len;
             }
             split_size -= bytes;
         } while (bytes && split_size);
-    } else if (!tp->props.tse && tp->props.cptse) {
+    } else if (!tp->tse && tp->cptse) {
         // context descriptor TSE is not set, while data descriptor TSE is set
         DBGOUT(TXERR, "TCP segmentation error\n");
     } else {
@@ -676,14 +846,14 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
 
     if (!(txd_lower & E1000_TXD_CMD_EOP))
         return;
-    if (!(tp->props.tse && tp->props.cptse && tp->size < tp->props.hdr_len)) {
+    if (!(tp->tse && tp->cptse && tp->size < tp->hdr_len)) {
         xmit_seg(s);
     }
     tp->tso_frames = 0;
-    tp->props.sum_needed = 0;
+    tp->sum_needed = 0;
     tp->vlan_needed = 0;
     tp->size = 0;
-    tp->props.cptse = 0;
+    tp->cptse = 0;
 }
 
 static uint32_t
@@ -755,14 +925,14 @@ start_xmit(E1000State *s)
 static int
 receive_filter(E1000State *s, const uint8_t *buf, int size)
 {
-    uint32_t rctl = s->mac_reg[RCTL];
+    static const int mta_shift[] = {4, 3, 2, 0};
+    uint32_t f, rctl = s->mac_reg[RCTL], ra[2], *rp;
     int isbcast = !memcmp(buf, bcast, sizeof bcast), ismcast = (buf[0] & 1);
 
-    if (e1000x_is_vlan_packet(buf, le16_to_cpu(s->mac_reg[VET])) &&
-        e1000x_vlan_rx_filter_enabled(s->mac_reg)) {
-        uint16_t vid = lduw_be_p(buf + 14);
-        uint32_t vfta = ldl_le_p((uint32_t*)(s->mac_reg + VFTA) +
-                                 ((vid >> 5) & 0x7f));
+    if (is_vlan_packet(s, buf) && vlan_rx_filter_enabled(s)) {
+        uint16_t vid = be16_to_cpup((uint16_t *)(buf + 14));
+        uint32_t vfta = le32_to_cpup((uint32_t *)(s->mac_reg + VFTA) +
+                                     ((vid >> 5) & 0x7f));
         if ((vfta & (1 << (vid & 0x1f))) == 0)
             return 0;
     }
@@ -772,16 +942,44 @@ receive_filter(E1000State *s, const uint8_t *buf, int size)
     }
 
     if (ismcast && (rctl & E1000_RCTL_MPE)) {          /* promiscuous mcast */
-        e1000x_inc_reg_if_not_full(s->mac_reg, MPRC);
+        inc_reg_if_not_full(s, MPRC);
         return 1;
     }
 
     if (isbcast && (rctl & E1000_RCTL_BAM)) {          /* broadcast enabled */
-        e1000x_inc_reg_if_not_full(s->mac_reg, BPRC);
+        inc_reg_if_not_full(s, BPRC);
+        return 1;
+    }
+
+    for (rp = s->mac_reg + RA; rp < s->mac_reg + RA + 32; rp += 2) {
+        if (!(rp[1] & E1000_RAH_AV))
+            continue;
+        ra[0] = cpu_to_le32(rp[0]);
+        ra[1] = cpu_to_le32(rp[1]);
+        if (!memcmp(buf, (uint8_t *)ra, 6)) {
+            DBGOUT(RXFILTER,
+                   "unicast match[%d]: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                   (int)(rp - s->mac_reg - RA)/2,
+                   buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+            return 1;
+        }
+    }
+    DBGOUT(RXFILTER, "unicast mismatch: %02x:%02x:%02x:%02x:%02x:%02x\n",
+           buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+
+    f = mta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3];
+    f = (((buf[5] << 8) | buf[4]) >> f) & 0xfff;
+    if (s->mac_reg[MTA + (f >> 5)] & (1 << (f & 0x1f))) {
+        inc_reg_if_not_full(s, MPRC);
         return 1;
     }
+    DBGOUT(RXFILTER,
+           "dropping, inexact filter mismatch: %02x:%02x:%02x:%02x:%02x:%02x MO %d MTA[%d] %x\n",
+           buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
+           (rctl >> E1000_RCTL_MO_SHIFT) & 3, f >> 5,
+           s->mac_reg[MTA + (f >> 5)]);
 
-    return e1000x_rx_group_filter(s->mac_reg, buf);
+    return 0;
 }
 
 static void
@@ -791,11 +989,13 @@ e1000_set_link_status(NetClientState *nc)
     uint32_t old_status = s->mac_reg[STATUS];
 
     if (nc->link_down) {
-        e1000x_update_regs_on_link_down(s->mac_reg, s->phy_reg);
+        e1000_link_down(s);
     } else {
         if (have_autoneg(s) &&
             !(s->phy_reg[PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) {
-            e1000x_restart_autoneg(s->mac_reg, s->phy_reg, s->autoneg_timer);
+            /* emulate auto-negotiation if supported */
+            timer_mod(s->autoneg_timer,
+                      qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);
         } else {
             e1000_link_up(s);
         }
@@ -828,7 +1028,9 @@ e1000_can_receive(NetClientState *nc)
 {
     E1000State *s = qemu_get_nic_opaque(nc);
 
-    return e1000x_rx_ready(&s->parent_obj, s->mac_reg) &&
+    return (s->mac_reg[STATUS] & E1000_STATUS_LU) &&
+        (s->mac_reg[RCTL] & E1000_RCTL_EN) &&
+        (s->parent_obj.config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
         e1000_has_rxbufs(s, 1);
 }
 
@@ -859,8 +1061,14 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
     size_t desc_offset;
     size_t desc_size;
     size_t total_size;
+    static const int PRCregs[6] = { PRC64, PRC127, PRC255, PRC511,
+                                    PRC1023, PRC1522 };
+
+    if (!(s->mac_reg[STATUS] & E1000_STATUS_LU)) {
+        return -1;
+    }
 
-    if (!e1000x_hw_rx_enabled(s->mac_reg)) {
+    if (!(s->mac_reg[RCTL] & E1000_RCTL_EN)) {
         return -1;
     }
 
@@ -868,7 +1076,7 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
     if (size < sizeof(min_buf)) {
         iov_to_buf(iov, iovcnt, 0, min_buf, size);
         memset(&min_buf[size], 0, sizeof(min_buf) - size);
-        e1000x_inc_reg_if_not_full(s->mac_reg, RUC);
+        inc_reg_if_not_full(s, RUC);
         min_iov.iov_base = filter_buf = min_buf;
         min_iov.iov_len = size = sizeof(min_buf);
         iovcnt = 1;
@@ -880,7 +1088,11 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
     }
 
     /* Discard oversized packets if !LPE and !SBP. */
-    if (e1000x_is_oversized(s->mac_reg, size)) {
+    if ((size > MAXIMUM_ETHERNET_LPE_SIZE ||
+        (size > MAXIMUM_ETHERNET_VLAN_SIZE
+        && !(s->mac_reg[RCTL] & E1000_RCTL_LPE)))
+        && !(s->mac_reg[RCTL] & E1000_RCTL_SBP)) {
+        inc_reg_if_not_full(s, ROC);
         return size;
     }
 
@@ -888,9 +1100,9 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
         return size;
     }
 
-    if (e1000x_vlan_enabled(s->mac_reg) &&
-        e1000x_is_vlan_packet(filter_buf, le16_to_cpu(s->mac_reg[VET]))) {
-        vlan_special = cpu_to_le16(lduw_be_p(filter_buf + 14));
+    if (vlan_enabled(s) && is_vlan_packet(s, filter_buf)) {
+        vlan_special = cpu_to_le16(be16_to_cpup((uint16_t *)(filter_buf
+                                                                + 14)));
         iov_ofs = 4;
         if (filter_buf == iov->iov_base) {
             memmove(filter_buf + 4, filter_buf, 12);
@@ -907,7 +1119,7 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
 
     rdh_start = s->mac_reg[RDH];
     desc_offset = 0;
-    total_size = size + e1000x_fcs_len(s->mac_reg);
+    total_size = size + fcs_len(s);
     if (!e1000_has_rxbufs(s, total_size)) {
             set_ics(s, 0, E1000_ICS_RXO);
             return -1;
@@ -967,7 +1179,17 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
         }
     } while (desc_offset < total_size);
 
-    e1000x_update_rx_total_stats(s->mac_reg, size, total_size);
+    increase_size_stats(s, PRCregs, total_size);
+    inc_reg_if_not_full(s, TPR);
+    s->mac_reg[GPRC] = s->mac_reg[TPR];
+    /* TOR - Total Octets Received:
+     * This register includes bytes received in a packet from the <Destination
+     * Address> field through the <CRC> field, inclusively.
+     * Always include FCS length (4) in size.
+     */
+    grow_8reg_if_not_full(s, TORL, size+4);
+    s->mac_reg[GORCL] = s->mac_reg[TORL];
+    s->mac_reg[GORCH] = s->mac_reg[TORH];
 
     n = E1000_ICS_RXT0;
     if ((rdt = s->mac_reg[RDT]) < s->mac_reg[RDH])
@@ -1448,20 +1670,20 @@ static const VMStateDescription vmstate_e1000 = {
         VMSTATE_UINT16(eecd_state.bitnum_out, E1000State),
         VMSTATE_UINT16(eecd_state.reading, E1000State),
         VMSTATE_UINT32(eecd_state.old_eecd, E1000State),
-        VMSTATE_UINT8(tx.props.ipcss, E1000State),
-        VMSTATE_UINT8(tx.props.ipcso, E1000State),
-        VMSTATE_UINT16(tx.props.ipcse, E1000State),
-        VMSTATE_UINT8(tx.props.tucss, E1000State),
-        VMSTATE_UINT8(tx.props.tucso, E1000State),
-        VMSTATE_UINT16(tx.props.tucse, E1000State),
-        VMSTATE_UINT32(tx.props.paylen, E1000State),
-        VMSTATE_UINT8(tx.props.hdr_len, E1000State),
-        VMSTATE_UINT16(tx.props.mss, E1000State),
+        VMSTATE_UINT8(tx.ipcss, E1000State),
+        VMSTATE_UINT8(tx.ipcso, E1000State),
+        VMSTATE_UINT16(tx.ipcse, E1000State),
+        VMSTATE_UINT8(tx.tucss, E1000State),
+        VMSTATE_UINT8(tx.tucso, E1000State),
+        VMSTATE_UINT16(tx.tucse, E1000State),
+        VMSTATE_UINT32(tx.paylen, E1000State),
+        VMSTATE_UINT8(tx.hdr_len, E1000State),
+        VMSTATE_UINT16(tx.mss, E1000State),
         VMSTATE_UINT16(tx.size, E1000State),
         VMSTATE_UINT16(tx.tso_frames, E1000State),
-        VMSTATE_UINT8(tx.props.sum_needed, E1000State),
-        VMSTATE_INT8(tx.props.ip, E1000State),
-        VMSTATE_INT8(tx.props.tcp, E1000State),
+        VMSTATE_UINT8(tx.sum_needed, E1000State),
+        VMSTATE_INT8(tx.ip, E1000State),
+        VMSTATE_INT8(tx.tcp, E1000State),
         VMSTATE_BUFFER(tx.header, E1000State),
         VMSTATE_BUFFER(tx.data, E1000State),
         VMSTATE_UINT16_ARRAY(eeprom_data, E1000State, 64),
@@ -1563,7 +1785,7 @@ pci_e1000_uninit(PCIDevice *dev)
 }
 
 static NetClientInfo net_e1000_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .can_receive = e1000_can_receive,
     .receive = e1000_receive,
@@ -1584,11 +1806,15 @@ static void e1000_write_config(PCIDevice *pci_dev, uint32_t address,
     }
 }
 
+
 static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp)
 {
     DeviceState *dev = DEVICE(pci_dev);
     E1000State *d = E1000(pci_dev);
+    PCIDeviceClass *pdc = PCI_DEVICE_GET_CLASS(pci_dev);
     uint8_t *pci_conf;
+    uint16_t checksum = 0;
+    int i;
     uint8_t *macaddr;
 
     pci_dev->config_write = e1000_write_config;
@@ -1606,14 +1832,17 @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp)
 
     pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io);
 
+    memmove(d->eeprom_data, e1000_eeprom_template,
+        sizeof e1000_eeprom_template);
     qemu_macaddr_default_if_unset(&d->conf.macaddr);
     macaddr = d->conf.macaddr.a;
-
-    e1000x_core_prepare_eeprom(d->eeprom_data,
-                               e1000_eeprom_template,
-                               sizeof(e1000_eeprom_template),
-                               PCI_DEVICE_GET_CLASS(pci_dev)->device_id,
-                               macaddr);
+    for (i = 0; i < 3; i++)
+        d->eeprom_data[i] = (macaddr[2*i+1]<<8) | macaddr[2*i];
+    d->eeprom_data[11] = d->eeprom_data[13] = pdc->device_id;
+    for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
+        checksum += d->eeprom_data[i];
+    checksum = (uint16_t) EEPROM_SUM - checksum;
+    d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;
 
     d->nic = qemu_new_nic(&net_e1000_info, &d->conf,
                           object_get_typename(OBJECT(d)), dev->id, d);
index 23eed50..1c40244 100644 (file)
@@ -29,8 +29,9 @@
  * Structures, enums, and macros for the MAC
  */
 
-#ifndef HW_E1000_REGS_H
-#define HW_E1000_REGS_H
+#ifndef _E1000_HW_H_
+#define _E1000_HW_H_
+
 
 /* PCI Device IDs */
 #define E1000_DEV_ID_82542               0x1000
@@ -84,7 +85,6 @@
 #define E1000_DEV_ID_82573E              0x108B
 #define E1000_DEV_ID_82573E_IAMT         0x108C
 #define E1000_DEV_ID_82573L              0x109A
-#define E1000_DEV_ID_82574L              0x10D3
 #define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
 #define E1000_DEV_ID_80003ES2LAN_COPPER_DPT     0x1096
 #define E1000_DEV_ID_80003ES2LAN_SERDES_DPT     0x1098
 #define E1000_PHY_ID2_82544x 0xC30
 #define E1000_PHY_ID2_8254xx_DEFAULT 0xC20 /* 82540x, 82545x, and 82546x */
 #define E1000_PHY_ID2_82573x 0xCC0
-#define E1000_PHY_ID2_82574x 0xCB1
 
 /* Register Set. (82543, 82544)
  *
 #define E1000_ITR      0x000C4  /* Interrupt Throttling Rate - RW */
 #define E1000_ICS      0x000C8  /* Interrupt Cause Set - WO */
 #define E1000_IMS      0x000D0  /* Interrupt Mask Set - RW */
-#define E1000_EIAC     0x000DC  /* Ext. Interrupt Auto Clear - RW */
 #define E1000_IMC      0x000D8  /* Interrupt Mask Clear - WO */
 #define E1000_IAM      0x000E0  /* Interrupt Acknowledge Auto Mask */
-#define E1000_IVAR     0x000E4  /* Interrupt Vector Allocation Register - RW */
-#define E1000_EITR     0x000E8  /* Extended Interrupt Throttling Rate - RW */
 #define E1000_RCTL     0x00100  /* RX Control - RW */
 #define E1000_RDTR1    0x02820  /* RX Delay Timer (1) - RW */
 #define E1000_RDBAL1   0x02900  /* RX Descriptor Base Address Low (1) - RW */
 #define E1000_RDH1     0x02910  /* RX Descriptor Head (1) - RW */
 #define E1000_RDT1     0x02918  /* RX Descriptor Tail (1) - RW */
 #define E1000_FCTTV    0x00170  /* Flow Control Transmit Timer Value - RW */
-#define E1000_FCRTV    0x05F40  /* Flow Control Refresh Timer Value - RW */
 #define E1000_TXCW     0x00178  /* TX Configuration Word - RW */
 #define E1000_RXCW     0x00180  /* RX Configuration Word - RO */
 #define E1000_TCTL     0x00400  /* TX Control - RW */
 #define E1000_PBM      0x10000  /* Packet Buffer Memory - RW */
 #define E1000_PBS      0x01008  /* Packet Buffer Size - RW */
 #define E1000_EEMNGCTL 0x01010  /* MNG EEprom Control */
-#define E1000_EEMNGDATA    0x01014 /* MNG EEPROM Read/Write data */
-#define E1000_FLMNGCTL     0x01018 /* MNG Flash Control */
-#define E1000_FLMNGDATA    0x0101C /* MNG FLASH Read data */
-#define E1000_FLMNGCNT     0x01020 /* MNG FLASH Read Counter */
 #define E1000_FLASH_UPDATES 1000
 #define E1000_EEARBC   0x01024  /* EEPROM Auto Read Bus Control */
 #define E1000_FLASHT   0x01028  /* FLASH Timer Register */
 #define E1000_FLSWDATA 0x01034  /* FLASH data register */
 #define E1000_FLSWCNT  0x01038  /* FLASH Access Counter */
 #define E1000_FLOP     0x0103C  /* FLASH Opcode Register */
-#define E1000_FLOL     0x01050  /* FEEP Auto Load */
 #define E1000_ERT      0x02008  /* Early Rx Threshold - RW */
 #define E1000_FCRTL    0x02160  /* Flow Control Receive Threshold Low - RW */
-#define E1000_FCRTL_A  0x00168  /* Alias to FCRTL */
 #define E1000_FCRTH    0x02168  /* Flow Control Receive Threshold High - RW */
-#define E1000_FCRTH_A  0x00160  /* Alias to FCRTH */
 #define E1000_PSRCTL   0x02170  /* Packet Split Receive Control - RW */
 #define E1000_RDBAL    0x02800  /* RX Descriptor Base Address Low - RW */
 #define E1000_RDBAH    0x02804  /* RX Descriptor Base Address High - RW */
 #define E1000_RDH      0x02810  /* RX Descriptor Head - RW */
 #define E1000_RDT      0x02818  /* RX Descriptor Tail - RW */
 #define E1000_RDTR     0x02820  /* RX Delay Timer - RW */
-#define E1000_RDTR_A   0x00108  /* Alias to RDTR */
 #define E1000_RDBAL0   E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
-#define E1000_RDBAL0_A 0x00110     /* Alias to RDBAL0 */
 #define E1000_RDBAH0   E1000_RDBAH /* RX Desc Base Address High (0) - RW */
-#define E1000_RDBAH0_A 0x00114     /* Alias to RDBAH0 */
 #define E1000_RDLEN0   E1000_RDLEN /* RX Desc Length (0) - RW */
-#define E1000_RDLEN0_A 0x00118     /* Alias to RDLEN0 */
 #define E1000_RDH0     E1000_RDH   /* RX Desc Head (0) - RW */
-#define E1000_RDH0_A   0x00120     /* Alias to RDH0 */
 #define E1000_RDT0     E1000_RDT   /* RX Desc Tail (0) - RW */
-#define E1000_RDT0_A   0x00128     /* Alias to RDT0 */
 #define E1000_RDTR0    E1000_RDTR  /* RX Delay Timer (0) - RW */
 #define E1000_RXDCTL   0x02828  /* RX Descriptor Control queue 0 - RW */
 #define E1000_RXDCTL1  0x02928  /* RX Descriptor Control queue 1 - RW */
 #define E1000_RAID     0x02C08  /* Receive Ack Interrupt Delay - RW */
 #define E1000_TXDMAC   0x03000  /* TX DMA Control - RW */
 #define E1000_KABGTXD  0x03004  /* AFE Band Gap Transmit Ref Data */
-#define E1000_POEMB    0x00F10  /* PHY OEM Bits Register - RW */
 #define E1000_RDFH     0x02410  /* Receive Data FIFO Head Register - RW */
-#define E1000_RDFH_A   0x08000  /* Alias to RDFH */
 #define E1000_RDFT     0x02418  /* Receive Data FIFO Tail Register - RW */
-#define E1000_RDFT_A   0x08008  /* Alias to RDFT */
 #define E1000_RDFHS    0x02420  /* Receive Data FIFO Head Saved Register - RW */
 #define E1000_RDFTS    0x02428  /* Receive Data FIFO Tail Saved Register - RW */
 #define E1000_RDFPC    0x02430  /* Receive Data FIFO Packet Count - RW */
 #define E1000_TDFH     0x03410  /* TX Data FIFO Head - RW */
-#define E1000_TDFH_A   0x08010  /* Alias to TDFH */
 #define E1000_TDFT     0x03418  /* TX Data FIFO Tail - RW */
-#define E1000_TDFT_A   0x08018  /* Alias to TDFT */
 #define E1000_TDFHS    0x03420  /* TX Data FIFO Head Saved - RW */
 #define E1000_TDFTS    0x03428  /* TX Data FIFO Tail Saved - RW */
 #define E1000_TDFPC    0x03430  /* TX Data FIFO Packet Count - RW */
 #define E1000_TDBAL    0x03800  /* TX Descriptor Base Address Low - RW */
-#define E1000_TDBAL_A  0x00420  /* Alias to TDBAL */
 #define E1000_TDBAH    0x03804  /* TX Descriptor Base Address High - RW */
-#define E1000_TDBAH_A  0x00424  /* Alias to TDBAH */
 #define E1000_TDLEN    0x03808  /* TX Descriptor Length - RW */
-#define E1000_TDLEN_A  0x00428  /* Alias to TDLEN */
 #define E1000_TDH      0x03810  /* TX Descriptor Head - RW */
-#define E1000_TDH_A    0x00430  /* Alias to TDH */
 #define E1000_TDT      0x03818  /* TX Descripotr Tail - RW */
-#define E1000_TDT_A    0x00438  /* Alias to TDT */
 #define E1000_TIDV     0x03820  /* TX Interrupt Delay Value - RW */
-#define E1000_TIDV_A   0x00440  /* Alias to TIDV */
 #define E1000_TXDCTL   0x03828  /* TX Descriptor Control - RW */
 #define E1000_TADV     0x0382C  /* TX Interrupt Absolute Delay Val - RW */
 #define E1000_TSPMT    0x03830  /* TCP Segmentation PAD & Min Threshold - RW */
 #define E1000_ICRXOC   0x04124  /* Interrupt Cause Receiver Overrun Count */
 #define E1000_RXCSUM   0x05000  /* RX Checksum Control - RW */
 #define E1000_RFCTL    0x05008  /* Receive Filter Control*/
-#define E1000_MAVTV0   0x05010  /* Management VLAN TAG Value 0 */
-#define E1000_MAVTV1   0x05014  /* Management VLAN TAG Value 1 */
-#define E1000_MAVTV2   0x05018  /* Management VLAN TAG Value 2 */
-#define E1000_MAVTV3   0x0501c  /* Management VLAN TAG Value 3 */
 #define E1000_MTA      0x05200  /* Multicast Table Array - RW Array */
 #define E1000_RA       0x05400  /* Receive Address - RW Array */
-#define E1000_RA_A     0x00040  /* Alias to RA */
 #define E1000_VFTA     0x05600  /* VLAN Filter Table Array - RW Array */
-#define E1000_VFTA_A   0x00600  /* Alias to VFTA */
 #define E1000_WUC      0x05800  /* Wakeup Control - RW */
 #define E1000_WUFC     0x05808  /* Wakeup Filter Control - RW */
 #define E1000_WUS      0x05810  /* Wakeup Status - RO */
 #define E1000_IP6AT    0x05880  /* IPv6 Address Table - RW Array */
 #define E1000_WUPL     0x05900  /* Wakeup Packet Length - RW */
 #define E1000_WUPM     0x05A00  /* Wakeup Packet Memory - RO A */
-#define E1000_MFUTP01  0x05828  /* Management Flex UDP/TCP Ports 0/1 - RW */
-#define E1000_MFUTP23  0x05830  /* Management Flex UDP/TCP Ports 2/3 - RW */
-#define E1000_MFVAL    0x05824  /* Manageability Filters Valid - RW */
-#define E1000_MDEF     0x05890  /* Manageability Decision Filters - RW Array */
 #define E1000_FFLT     0x05F00  /* Flexible Filter Length Table - RW Array */
 #define E1000_HOST_IF  0x08800  /* Host Interface */
 #define E1000_FFMT     0x09000  /* Flexible Filter Mask Table - RW Array */
-#define E1000_FTFT     0x09400  /* Flexible TCO Filter Table - RW Array */
 #define E1000_FFVT     0x09800  /* Flexible Filter Value Table - RW Array */
 
 #define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */
-#define E1000_MDPHYA     0x0003C /* PHY address - RW */
-#define E1000_MANC2H     0x05860 /* Management Control To Host - RW */
+#define E1000_MDPHYA     0x0003C  /* PHY address - RW */
+#define E1000_MANC2H     0x05860  /* Management Control To Host - RW */
 #define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
 
 #define E1000_GCR       0x05B00 /* PCI-Ex Control */
-#define E1000_FUNCTAG   0x05B08 /* Function-Tag Register */
 #define E1000_GSCL_1    0x05B10 /* PCI-Ex Statistic Control #1 */
 #define E1000_GSCL_2    0x05B14 /* PCI-Ex Statistic Control #2 */
 #define E1000_GSCL_3    0x05B18 /* PCI-Ex Statistic Control #3 */
 #define E1000_GSCL_4    0x05B1C /* PCI-Ex Statistic Control #4 */
-#define E1000_GSCN_0    0x05B20 /* 3GIO Statistic Counter Register #0 */
-#define E1000_GSCN_1    0x05B24 /* 3GIO Statistic Counter Register #1 */
-#define E1000_GSCN_2    0x05B28 /* 3GIO Statistic Counter Register #2 */
-#define E1000_GSCN_3    0x05B2C /* 3GIO Statistic Counter Register #3 */
 #define E1000_FACTPS    0x05B30 /* Function Active and Power State to MNG */
 #define E1000_SWSM      0x05B50 /* SW Semaphore */
-#define E1000_GCR2      0x05B64 /* 3GIO Control Register 2 */
 #define E1000_FWSM      0x05B54 /* FW Semaphore */
-#define E1000_PBACLR    0x05B68 /* MSI-X PBA Clear */
 #define E1000_FFLT_DBG  0x05F04 /* Debug Register */
 #define E1000_HICR      0x08F00 /* Host Inteface Control */
 
-#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
-#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
-#define E1000_TIMINCA    0x0B608 /* Increment attributes register - RW */
-#define E1000_RXSTMPL    0x0B624 /* Rx timestamp Low - RO */
-#define E1000_RXSTMPH    0x0B628 /* Rx timestamp High - RO */
-#define E1000_TXSTMPL    0x0B618 /* Tx timestamp value Low - RO */
-#define E1000_TXSTMPH    0x0B61C /* Tx timestamp value High - RO */
-#define E1000_SYSTIML    0x0B600 /* System time register Low - RO */
-#define E1000_SYSTIMH    0x0B604 /* System time register High - RO */
-#define E1000_TIMINCA    0x0B608 /* Increment attributes register - RW */
-#define E1000_RXMTRL     0x0B634 /* Time sync Rx EtherType and Msg Type - RW */
-#define E1000_RXUDP      0x0B638 /* Time Sync Rx UDP Port - RW */
-#define E1000_RXSATRL    0x0B62C /* Rx timestamp attribute low - RO */
-#define E1000_RXSATRH    0x0B630 /* Rx timestamp attribute high - RO */
-#define E1000_TIMADJL    0x0B60C /* Time Adjustment Offset register Low - RW */
-#define E1000_TIMADJH    0x0B610 /* Time Adjustment Offset register High - RW */
-#define E1000_RXCFGL     0x0B634 /* RX Ethertype and Message Type - RW*/
-
 /* RSS registers */
 #define E1000_CPUVEC    0x02C10 /* CPU Vector Register - RW */
 #define E1000_MRQC      0x05818 /* Multiple Receive Control - RW */
 #define E1000_RSSIM     0x05864 /* RSS Interrupt Mask */
 #define E1000_RSSIR     0x05868 /* RSS Interrupt Request */
 
-#define E1000_MRQC_ENABLED(mrqc) (((mrqc) & (BIT(0) | BIT(1))) == BIT(0))
-
-#define E1000_RETA_IDX(hash)        ((hash) & (BIT(7) - 1))
-#define E1000_RETA_VAL(reta, hash)  (((uint8_t *)(reta))[E1000_RETA_IDX(hash)])
-#define E1000_RSS_QUEUE(reta, hash) ((E1000_RETA_VAL(reta, hash) & BIT(7)) >> 7)
-
-#define E1000_MRQC_EN_TCPIPV4(mrqc) ((mrqc) & BIT(16))
-#define E1000_MRQC_EN_IPV4(mrqc)    ((mrqc) & BIT(17))
-#define E1000_MRQC_EN_TCPIPV6(mrqc) ((mrqc) & BIT(18))
-#define E1000_MRQC_EN_IPV6EX(mrqc)  ((mrqc) & BIT(19))
-#define E1000_MRQC_EN_IPV6(mrqc)    ((mrqc) & BIT(20))
-
-#define E1000_MRQ_RSS_TYPE_NONE     (0)
-#define E1000_MRQ_RSS_TYPE_IPV4TCP  (1)
-#define E1000_MRQ_RSS_TYPE_IPV4     (2)
-#define E1000_MRQ_RSS_TYPE_IPV6TCP  (3)
-#define E1000_MRQ_RSS_TYPE_IPV6EX   (4)
-#define E1000_MRQ_RSS_TYPE_IPV6     (5)
-
-#define E1000_ICR_ASSERTED BIT(31)
-#define E1000_EIAC_MASK    0x01F00000
-
-/* [TR]DBAL and [TR]DLEN masks */
-#define E1000_XDBAL_MASK            (~(BIT(4) - 1))
-#define E1000_XDLEN_MASK            ((BIT(20) - 1) & (~(BIT(7) - 1)))
-
-/* IVAR register parsing helpers */
-#define E1000_IVAR_INT_ALLOC_VALID  (0x8)
-
-#define E1000_IVAR_RXQ0_SHIFT       (0)
-#define E1000_IVAR_RXQ1_SHIFT       (4)
-#define E1000_IVAR_TXQ0_SHIFT       (8)
-#define E1000_IVAR_TXQ1_SHIFT       (12)
-#define E1000_IVAR_OTHER_SHIFT      (16)
-
-#define E1000_IVAR_ENTRY_MASK       (0xF)
-#define E1000_IVAR_ENTRY_VALID_MASK E1000_IVAR_INT_ALLOC_VALID
-#define E1000_IVAR_ENTRY_VEC_MASK   (0x7)
-
-#define E1000_IVAR_RXQ0(x)          ((x) >> E1000_IVAR_RXQ0_SHIFT)
-#define E1000_IVAR_RXQ1(x)          ((x) >> E1000_IVAR_RXQ1_SHIFT)
-#define E1000_IVAR_TXQ0(x)          ((x) >> E1000_IVAR_TXQ0_SHIFT)
-#define E1000_IVAR_TXQ1(x)          ((x) >> E1000_IVAR_TXQ1_SHIFT)
-#define E1000_IVAR_OTHER(x)         ((x) >> E1000_IVAR_OTHER_SHIFT)
-
-#define E1000_IVAR_ENTRY_VALID(x)   ((x) & E1000_IVAR_ENTRY_VALID_MASK)
-#define E1000_IVAR_ENTRY_VEC(x)     ((x) & E1000_IVAR_ENTRY_VEC_MASK)
-
-#define E1000_IVAR_TX_INT_EVERY_WB  BIT(31)
-
-/* RFCTL register bits */
-#define E1000_RFCTL_ISCSI_DIS           0x00000001
-#define E1000_RFCTL_NFSW_DIS            0x00000040
-#define E1000_RFCTL_NFSR_DIS            0x00000080
-#define E1000_RFCTL_IPV6_DIS            0x00000400
-#define E1000_RFCTL_IPV6_XSUM_DIS       0x00000800
-#define E1000_RFCTL_ACK_DIS             0x00001000
-#define E1000_RFCTL_ACK_DATA_DIS        0x00002000
-#define E1000_RFCTL_IPFRSP_DIS          0x00004000
-#define E1000_RFCTL_EXTEN               0x00008000
-#define E1000_RFCTL_IPV6_EX_DIS         0x00010000
-#define E1000_RFCTL_NEW_IPV6_EXT_DIS    0x00020000
-
-/* PSRCTL parsing */
-#define E1000_PSRCTL_BSIZE0_MASK   0x0000007F
-#define E1000_PSRCTL_BSIZE1_MASK   0x00003F00
-#define E1000_PSRCTL_BSIZE2_MASK   0x003F0000
-#define E1000_PSRCTL_BSIZE3_MASK   0x3F000000
-
-#define E1000_PSRCTL_BSIZE0_SHIFT  0
-#define E1000_PSRCTL_BSIZE1_SHIFT  8
-#define E1000_PSRCTL_BSIZE2_SHIFT  16
-#define E1000_PSRCTL_BSIZE3_SHIFT  24
-
-#define E1000_PSRCTL_BUFFS_PER_DESC 4
-
-/* TARC* parsing */
-#define E1000_TARC_ENABLE BIT(10)
-
 /* PHY 1000 MII Register/Bit Definitions */
 /* PHY Registers defined by IEEE */
 #define PHY_CTRL         0x00 /* Control Register */
 #define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
 #define PHY_EXT_STATUS   0x0F /* Extended Status Reg */
 
-/* 82574-specific registers */
-#define PHY_COPPER_CTRL1      0x10 /* Copper Specific Control Register 1 */
-#define PHY_COPPER_STAT1      0x11 /* Copper Specific Status Register 1 */
-#define PHY_COPPER_INT_ENABLE 0x12  /* Interrupt Enable Register */
-#define PHY_COPPER_STAT2      0x13 /* Copper Specific Status Register 2 */
-#define PHY_COPPER_CTRL3      0x14 /* Copper Specific Control Register 3 */
-#define PHY_COPPER_CTRL2      0x1A /* Copper Specific Control Register 2 */
-#define PHY_RX_ERR_CNTR       0x15  /* Receive Error Counter */
-#define PHY_PAGE              0x16 /* Page Address (Any page) */
-#define PHY_OEM_BITS          0x19 /* OEM Bits (Page 0) */
-#define PHY_BIAS_1            0x1d /* Bias Setting Register */
-#define PHY_BIAS_2            0x1e /* Bias Setting Register */
-
-/* 82574-specific registers - page 2 */
-#define PHY_MAC_CTRL1         0x10 /* MAC Specific Control Register 1 */
-#define PHY_MAC_INT_ENABLE    0x12 /* MAC Interrupt Enable Register */
-#define PHY_MAC_STAT          0x13 /* MAC Specific Status Register */
-#define PHY_MAC_CTRL2         0x15 /* MAC Specific Control Register 2 */
-
-/* 82574-specific registers - page 3 */
-#define PHY_LED_03_FUNC_CTRL1 0x10 /* LED[3:0] Function Control */
-#define PHY_LED_03_POL_CTRL   0x11 /* LED[3:0] Polarity Control */
-#define PHY_LED_TIMER_CTRL    0x12 /* LED Timer Control */
-#define PHY_LED_45_CTRL       0x13 /* LED[5:4] Function Control and Polarity */
-
-/* 82574-specific registers - page 5 */
-#define PHY_1000T_SKEW        0x14 /* 1000 BASE - T Pair Skew Register */
-#define PHY_1000T_SWAP        0x15 /* 1000 BASE - T Pair Swap and Polarity */
-
-/* 82574-specific registers - page 6 */
-#define PHY_CRC_COUNTERS      0x11 /* CRC Counters */
-
-#define PHY_PAGE_RW_MASK 0x7F /* R/W part of page address register */
-
 #define MAX_PHY_REG_ADDRESS        0x1F  /* 5 bit address bus (0-0x1F) */
 #define MAX_PHY_MULTI_PAGE_REG     0xF   /* Registers equal on all pages */
 
 #define E1000_ICR_DSW           0x00000020 /* FW changed the status of DISSW bit in the FWSM */
 #define E1000_ICR_PHYINT        0x00001000 /* LAN connected device generates an interrupt */
 #define E1000_ICR_EPRST         0x00100000 /* ME handware reset occurs */
-#define E1000_ICR_RXQ0          0x00100000 /* Rx Queue 0 Interrupt */
-#define E1000_ICR_RXQ1          0x00200000 /* Rx Queue 1 Interrupt */
-#define E1000_ICR_TXQ0          0x00400000 /* Tx Queue 0 Interrupt */
-#define E1000_ICR_TXQ1          0x00800000 /* Tx Queue 1 Interrupt */
-#define E1000_ICR_OTHER         0x01000000 /* Other Interrupts */
-
-#define E1000_ICR_OTHER_CAUSES (E1000_ICR_LSC  | \
-                                E1000_ICR_RXO  | \
-                                E1000_ICR_MDAC | \
-                                E1000_ICR_SRPD | \
-                                E1000_ICR_ACK  | \
-                                E1000_ICR_MNG)
 
 /* Interrupt Cause Set */
 #define E1000_ICS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
 #define E1000_IMS_SRPD      E1000_ICR_SRPD
 #define E1000_IMS_ACK       E1000_ICR_ACK       /* Receive Ack frame */
 #define E1000_IMS_MNG       E1000_ICR_MNG       /* Manageability event */
-#define E1000_IMS_RXQ0      E1000_ICR_RXQ0
-#define E1000_IMS_RXQ1      E1000_ICR_RXQ1
-#define E1000_IMS_TXQ0      E1000_ICR_TXQ0
-#define E1000_IMS_TXQ1      E1000_ICR_TXQ1
-#define E1000_IMS_OTHER     E1000_ICR_OTHER
 #define E1000_IMS_DOCK      E1000_ICR_DOCK      /* Dock/Undock */
 #define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
 #define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
 #define E1000_EEPROM_RW_ADDR_SHIFT 8    /* Shift to the address bits */
 #define E1000_EEPROM_POLL_WRITE    1    /* Flag for polling for write complete */
 #define E1000_EEPROM_POLL_READ     0    /* Flag for polling for read complete */
-
-/* 82574 EERD/EEWR registers layout */
-#define E1000_EERW_START        BIT(0)
-#define E1000_EERW_DONE         BIT(1)
-#define E1000_EERW_ADDR_SHIFT   2
-#define E1000_EERW_ADDR_MASK    ((1L << 14) - 1)
-#define E1000_EERW_DATA_SHIFT   16
-#define E1000_EERW_DATA_MASK   ((1L << 16) - 1)
-
 /* Register Bit Masks */
 /* Device Control */
 #define E1000_CTRL_FD       0x00000001  /* Full duplex.0=half; 1=full */
 #define E1000_CTRL_D_UD_EN  0x00002000  /* Dock/Undock enable */
 #define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
 #define E1000_CTRL_FORCE_PHY_RESET 0x00008000 /* Reset both PHY ports, through PHYRST_N pin */
-#define E1000_CTRL_SPD_SHIFT 8          /* Speed Select Shift */
-
-#define E1000_CTRL_EXT_ASDCHK  0x00001000 /* auto speed detection check */
-#define E1000_CTRL_EXT_EE_RST  0x00002000 /* EEPROM reset */
 #define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external LINK_0 and LINK_1 pins */
-#define E1000_CTRL_EXT_EIAME   0x01000000
-#define E1000_CTRL_EXT_IAME    0x08000000 /* Int ACK Auto-mask */
-#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
-#define E1000_CTRL_EXT_INT_TIMERS_CLEAR_ENA 0x20000000
-#define E1000_CTRL_EXT_SPD_BYPS  0x00008000 /* Speed Select Bypass */
-
 #define E1000_CTRL_SWDPIN0  0x00040000  /* SWDPIN 0 value */
 #define E1000_CTRL_SWDPIN1  0x00080000  /* SWDPIN 1 value */
 #define E1000_CTRL_SWDPIN2  0x00100000  /* SWDPIN 2 value */
 #define E1000_CTRL_SWDPIO1  0x00800000  /* SWDPIN 1 input or output */
 #define E1000_CTRL_SWDPIO2  0x01000000  /* SWDPIN 2 input or output */
 #define E1000_CTRL_SWDPIO3  0x02000000  /* SWDPIN 3 input or output */
-#define E1000_CTRL_ADVD3WUC 0x00100000  /* D3 WUC */
 #define E1000_CTRL_RST      0x04000000  /* Global reset */
 #define E1000_CTRL_RFCE     0x08000000  /* Receive Flow Control enable */
 #define E1000_CTRL_TFCE     0x10000000  /* Transmit flow control enable */
 #define E1000_STATUS_LAN_INIT_DONE 0x00000200   /* Lan Init Completion
                                                    by EEPROM/Flash */
 #define E1000_STATUS_ASDV       0x00000300      /* Auto speed detect value */
-#define E1000_STATUS_ASDV_10    0x00000000      /* ASDV 10Mb */
-#define E1000_STATUS_ASDV_100   0x00000100      /* ASDV 100Mb */
-#define E1000_STATUS_ASDV_1000  0x00000200      /* ASDV 1Gb */
 #define E1000_STATUS_DOCK_CI    0x00000800      /* Change in Dock/Undock state. Clear on write '0'. */
 #define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */
 #define E1000_STATUS_MTXCKOK    0x00000400      /* MTX clock running OK */
-#define E1000_STATUS_PHYRA      0x00000400      /* PHY Reset Asserted */
 #define E1000_STATUS_PCI66      0x00000800      /* In 66Mhz slot */
 #define E1000_STATUS_BUS64      0x00001000      /* In 64 bit slot */
 #define E1000_STATUS_PCIX_MODE  0x00002000      /* PCI-X mode */
 #define E1000_STATUS_FUSE_9       0x08000000
 #define E1000_STATUS_SERDES0_DIS  0x10000000 /* SERDES disabled on port 0 */
 #define E1000_STATUS_SERDES1_DIS  0x20000000 /* SERDES disabled on port 1 */
-#define E1000_STATUS_SPEED_SHIFT  6
-#define E1000_STATUS_ASDV_SHIFT   8
 
 /* EEPROM/Flash Control */
 #define E1000_EECD_SK        0x00000001 /* EEPROM Clock */
 #define E1000_EECD_AUPDEN    0x00100000 /* Enable Autonomous FLASH update */
 #define E1000_EECD_SHADV     0x00200000 /* Shadow RAM Data Valid */
 #define E1000_EECD_SEC1VAL   0x00400000 /* Sector One Valid */
-
-
 #define E1000_EECD_SECVAL_SHIFT      22
 #define E1000_STM_OPCODE     0xDB00
 #define E1000_HICR_FW_RESET  0xC0
 #define E1000_MDIC_INT_EN    0x20000000
 #define E1000_MDIC_ERROR     0x40000000
 
-/* Rx Interrupt Delay Timer */
-#define E1000_RDTR_FPD       BIT(31)
-
-/* Tx Interrupt Delay Timer */
-#define E1000_TIDV_FPD       BIT(31)
-
-/* Delay increments in nanoseconds for delayed interrupts registers */
-#define E1000_INTR_DELAY_NS_RES (1024)
-
-/* Delay increments in nanoseconds for interrupt throttling registers */
-#define E1000_INTR_THROTTLING_NS_RES (256)
-
 /* EEPROM Commands - Microwire */
 #define EEPROM_READ_OPCODE_MICROWIRE  0x6  /* EEPROM read opcode */
 #define EEPROM_WRITE_OPCODE_MICROWIRE 0x5  /* EEPROM write opcode */
 #define E1000_EEPROM_CFG_DONE         0x00040000   /* MNG config cycle done */
 #define E1000_EEPROM_CFG_DONE_PORT_1  0x00080000   /* ...for second port */
 
-/* PCI Express Control */
-/* 3GIO Control Register - GCR (0x05B00; RW) */
-#define E1000_L0S_ADJUST              (1 << 9)
-#define E1000_L1_ENTRY_LATENCY_MSB    (1 << 23)
-#define E1000_L1_ENTRY_LATENCY_LSB    (1 << 25 | 1 << 26)
-
-#define E1000_L0S_ADJUST              (1 << 9)
-#define E1000_L1_ENTRY_LATENCY_MSB    (1 << 23)
-#define E1000_L1_ENTRY_LATENCY_LSB    (1 << 25 | 1 << 26)
-
-#define E1000_GCR_RO_BITS             (1 << 23 | 1 << 25 | 1 << 26)
-
-/* MSI-X PBA Clear register */
-#define E1000_PBACLR_VALID_MASK       (BIT(5) - 1)
-
 /* Transmit Descriptor */
 struct e1000_tx_desc {
     uint64_t buffer_addr;       /* Address of the descriptor's data buffer */
@@ -1002,9 +752,7 @@ struct e1000_tx_desc {
 #define E1000_TXD_CMD_TCP    0x01000000 /* TCP packet */
 #define E1000_TXD_CMD_IP     0x02000000 /* IP packet */
 #define E1000_TXD_CMD_TSE    0x04000000 /* TCP Seg enable */
-#define E1000_TXD_CMD_SNAP   0x40000000 /* Update SNAP header */
 #define E1000_TXD_STAT_TC    0x00000004 /* Tx Underrun */
-#define E1000_TXD_EXTCMD_TSTAMP 0x00000010 /* IEEE1588 Timestamp packet */
 
 /* Transmit Control */
 #define E1000_TCTL_RST    0x00000001    /* software reset */
@@ -1019,7 +767,7 @@ struct e1000_tx_desc {
 #define E1000_TCTL_NRTU   0x02000000    /* No Re-transmit on underrun */
 #define E1000_TCTL_MULR   0x10000000    /* Multiple request support */
 
-/* Legacy Receive Descriptor */
+/* Receive Descriptor */
 struct e1000_rx_desc {
     uint64_t buffer_addr; /* Address of the descriptor's data buffer */
     uint16_t length;     /* Length of data DMAed into data buffer */
@@ -1029,78 +777,6 @@ struct e1000_rx_desc {
     uint16_t special;
 };
 
-/* Extended Receive Descriptor */
-union e1000_rx_desc_extended {
-    struct {
-        uint64_t buffer_addr;
-        uint64_t reserved;
-    } read;
-    struct {
-        struct {
-            uint32_t mrq;           /* Multiple Rx Queues */
-            union {
-                uint32_t rss;       /* RSS Hash */
-                struct {
-                    uint16_t ip_id; /* IP id */
-                    uint16_t csum;  /* Packet Checksum */
-                } csum_ip;
-            } hi_dword;
-        } lower;
-        struct {
-            uint32_t status_error;  /* ext status/error */
-            uint16_t length;
-            uint16_t vlan;          /* VLAN tag */
-        } upper;
-    } wb;                           /* writeback */
-};
-
-#define MAX_PS_BUFFERS 4
-
-/* Number of packet split data buffers (not including the header buffer) */
-#define PS_PAGE_BUFFERS    (MAX_PS_BUFFERS - 1)
-
-/* Receive Descriptor - Packet Split */
-union e1000_rx_desc_packet_split {
-    struct {
-        /* one buffer for protocol header(s), three data buffers */
-        uint64_t buffer_addr[MAX_PS_BUFFERS];
-    } read;
-    struct {
-        struct {
-            uint32_t mrq;          /* Multiple Rx Queues */
-            union {
-                uint32_t rss;          /* RSS Hash */
-                struct {
-                    uint16_t ip_id;    /* IP id */
-                    uint16_t csum;     /* Packet Checksum */
-                } csum_ip;
-            } hi_dword;
-        } lower;
-        struct {
-            uint32_t status_error;     /* ext status/error */
-            uint16_t length0;      /* length of buffer 0 */
-            uint16_t vlan;         /* VLAN tag */
-        } middle;
-        struct {
-            uint16_t header_status;
-            /* length of buffers 1-3 */
-            uint16_t length[PS_PAGE_BUFFERS];
-        } upper;
-        uint64_t reserved;
-    } wb; /* writeback */
-};
-
-/* Receive Checksum Control bits */
-#define E1000_RXCSUM_IPOFLD     0x100   /* IP Checksum Offload Enable */
-#define E1000_RXCSUM_TUOFLD     0x200   /* TCP/UDP Checksum Offload Enable */
-#define E1000_RXCSUM_PCSD       0x2000  /* Packet Checksum Disable */
-
-#define E1000_RING_DESC_LEN       (16)
-#define E1000_RING_DESC_LEN_SHIFT (4)
-
-#define E1000_MIN_RX_DESC_LEN   E1000_RING_DESC_LEN
-#define E1000_MAX_RX_DESC_LEN   (sizeof(union e1000_rx_desc_packet_split))
-
 /* Receive Descriptor bit definitions */
 #define E1000_RXD_STAT_DD       0x01    /* Descriptor Done */
 #define E1000_RXD_STAT_EOP      0x02    /* End of Packet */
@@ -1126,15 +802,6 @@ union e1000_rx_desc_packet_split {
 #define E1000_RXD_SPC_CFI_MASK  0x1000  /* CFI is bit 12 */
 #define E1000_RXD_SPC_CFI_SHIFT 12
 
-/* RX packet types */
-#define E1000_RXD_PKT_MAC       (0)
-#define E1000_RXD_PKT_IP4       (1)
-#define E1000_RXD_PKT_IP4_XDP   (2)
-#define E1000_RXD_PKT_IP6       (5)
-#define E1000_RXD_PKT_IP6_XDP   (6)
-
-#define E1000_RXD_PKT_TYPE(t) ((t) << 16)
-
 #define E1000_RXDEXT_STATERR_CE    0x01000000
 #define E1000_RXDEXT_STATERR_SE    0x02000000
 #define E1000_RXDEXT_STATERR_SEQ   0x04000000
@@ -1212,8 +879,6 @@ struct e1000_data_desc {
 #define E1000_MANC_NEIGHBOR_EN   0x00004000 /* Enable Neighbor Discovery
                                              * Filtering */
 #define E1000_MANC_ARP_RES_EN    0x00008000 /* Enable ARP response Filtering */
-#define E1000_MANC_DIS_IP_CHK_ARP  0x10000000 /* Disable IP address chacking */
-                                              /*for ARP packets - in 82574 */
 #define E1000_MANC_TCO_RESET     0x00010000 /* TCO Reset Occurred */
 #define E1000_MANC_RCV_TCO_EN    0x00020000 /* Receive TCO Packets Enabled */
 #define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
@@ -1237,14 +902,7 @@ struct e1000_data_desc {
 #define E1000_MANC_SMB_DATA_OUT_SHIFT  28 /* SMBus Data Out Shift */
 #define E1000_MANC_SMB_CLK_OUT_SHIFT   29 /* SMBus Clock Out Shift */
 
-/* FACTPS Control */
-#define E1000_FACTPS_LAN0_ON     0x00000004 /* Lan 0 enable */
-
 /* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
 #define EEPROM_SUM 0xBABA
 
-/* I/O-Mapped Access to Internal Registers, Memories, and Flash */
-#define E1000_IOADDR 0x00
-#define E1000_IODATA 0x04
-
-#endif /* HW_E1000_REGS_H */
+#endif /* _E1000_HW_H_ */
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
deleted file mode 100644 (file)
index bad43f4..0000000
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
-* QEMU INTEL 82574 GbE NIC emulation
-*
-* Software developer's manuals:
-* http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf
-*
-* Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
-* Developed by Daynix Computing LTD (http://www.daynix.com)
-*
-* Authors:
-* Dmitry Fleytman <dmitry@daynix.com>
-* Leonid Bloch <leonid@daynix.com>
-* Yan Vugenfirer <yan@daynix.com>
-*
-* Based on work done by:
-* Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
-* Copyright (c) 2008 Qumranet
-* Based on work done by:
-* Copyright (c) 2007 Dan Aloni
-* Copyright (c) 2004 Antony T Curtis
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 2 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "qemu/osdep.h"
-#include "net/net.h"
-#include "net/tap.h"
-#include "qemu/range.h"
-#include "sysemu/sysemu.h"
-#include "hw/pci/msi.h"
-#include "hw/pci/msix.h"
-
-#include "hw/net/e1000_regs.h"
-
-#include "e1000x_common.h"
-#include "e1000e_core.h"
-
-#include "trace.h"
-
-#define TYPE_E1000E "e1000e"
-#define E1000E(obj) OBJECT_CHECK(E1000EState, (obj), TYPE_E1000E)
-
-typedef struct E1000EState {
-    PCIDevice parent_obj;
-    NICState *nic;
-    NICConf conf;
-
-    MemoryRegion mmio;
-    MemoryRegion flash;
-    MemoryRegion io;
-    MemoryRegion msix;
-
-    uint32_t ioaddr;
-
-    uint16_t subsys_ven;
-    uint16_t subsys;
-
-    uint16_t subsys_ven_used;
-    uint16_t subsys_used;
-
-    bool disable_vnet;
-
-    E1000ECore core;
-
-} E1000EState;
-
-#define E1000E_MMIO_IDX     0
-#define E1000E_FLASH_IDX    1
-#define E1000E_IO_IDX       2
-#define E1000E_MSIX_IDX     3
-
-#define E1000E_MMIO_SIZE    (128 * 1024)
-#define E1000E_FLASH_SIZE   (128 * 1024)
-#define E1000E_IO_SIZE      (32)
-#define E1000E_MSIX_SIZE    (16 * 1024)
-
-#define E1000E_MSIX_TABLE   (0x0000)
-#define E1000E_MSIX_PBA     (0x2000)
-
-static uint64_t
-e1000e_mmio_read(void *opaque, hwaddr addr, unsigned size)
-{
-    E1000EState *s = opaque;
-    return e1000e_core_read(&s->core, addr, size);
-}
-
-static void
-e1000e_mmio_write(void *opaque, hwaddr addr,
-                   uint64_t val, unsigned size)
-{
-    E1000EState *s = opaque;
-    e1000e_core_write(&s->core, addr, val, size);
-}
-
-static bool
-e1000e_io_get_reg_index(E1000EState *s, uint32_t *idx)
-{
-    if (s->ioaddr < 0x1FFFF) {
-        *idx = s->ioaddr;
-        return true;
-    }
-
-    if (s->ioaddr < 0x7FFFF) {
-        trace_e1000e_wrn_io_addr_undefined(s->ioaddr);
-        return false;
-    }
-
-    if (s->ioaddr < 0xFFFFF) {
-        trace_e1000e_wrn_io_addr_flash(s->ioaddr);
-        return false;
-    }
-
-    trace_e1000e_wrn_io_addr_unknown(s->ioaddr);
-    return false;
-}
-
-static uint64_t
-e1000e_io_read(void *opaque, hwaddr addr, unsigned size)
-{
-    E1000EState *s = opaque;
-    uint32_t idx = 0;
-    uint64_t val;
-
-    switch (addr) {
-    case E1000_IOADDR:
-        trace_e1000e_io_read_addr(s->ioaddr);
-        return s->ioaddr;
-    case E1000_IODATA:
-        if (e1000e_io_get_reg_index(s, &idx)) {
-            val = e1000e_core_read(&s->core, idx, sizeof(val));
-            trace_e1000e_io_read_data(idx, val);
-            return val;
-        }
-        return 0;
-    default:
-        trace_e1000e_wrn_io_read_unknown(addr);
-        return 0;
-    }
-}
-
-static void
-e1000e_io_write(void *opaque, hwaddr addr,
-                uint64_t val, unsigned size)
-{
-    E1000EState *s = opaque;
-    uint32_t idx = 0;
-
-    switch (addr) {
-    case E1000_IOADDR:
-        trace_e1000e_io_write_addr(val);
-        s->ioaddr = (uint32_t) val;
-        return;
-    case E1000_IODATA:
-        if (e1000e_io_get_reg_index(s, &idx)) {
-            trace_e1000e_io_write_data(idx, val);
-            e1000e_core_write(&s->core, idx, val, sizeof(val));
-        }
-        return;
-    default:
-        trace_e1000e_wrn_io_write_unknown(addr);
-        return;
-    }
-}
-
-static const MemoryRegionOps mmio_ops = {
-    .read = e1000e_mmio_read,
-    .write = e1000e_mmio_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-    .impl = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-};
-
-static const MemoryRegionOps io_ops = {
-    .read = e1000e_io_read,
-    .write = e1000e_io_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-    .impl = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-};
-
-static int
-e1000e_nc_can_receive(NetClientState *nc)
-{
-    E1000EState *s = qemu_get_nic_opaque(nc);
-    return e1000e_can_receive(&s->core);
-}
-
-static ssize_t
-e1000e_nc_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
-{
-    E1000EState *s = qemu_get_nic_opaque(nc);
-    return e1000e_receive_iov(&s->core, iov, iovcnt);
-}
-
-static ssize_t
-e1000e_nc_receive(NetClientState *nc, const uint8_t *buf, size_t size)
-{
-    E1000EState *s = qemu_get_nic_opaque(nc);
-    return e1000e_receive(&s->core, buf, size);
-}
-
-static void
-e1000e_set_link_status(NetClientState *nc)
-{
-    E1000EState *s = qemu_get_nic_opaque(nc);
-    e1000e_core_set_link_status(&s->core);
-}
-
-static NetClientInfo net_e1000e_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
-    .size = sizeof(NICState),
-    .can_receive = e1000e_nc_can_receive,
-    .receive = e1000e_nc_receive,
-    .receive_iov = e1000e_nc_receive_iov,
-    .link_status_changed = e1000e_set_link_status,
-};
-
-/*
-* EEPROM (NVM) contents documented in Table 36, section 6.1
-* and generally 6.1.2 Software accessed words.
-*/
-static const uint16_t e1000e_eeprom_template[64] = {
-  /*        Address        |    Compat.    | ImVer |   Compat.     */
-    0x0000, 0x0000, 0x0000, 0x0420, 0xf746, 0x2010, 0xffff, 0xffff,
-  /*      PBA      |ICtrl1 | SSID  | SVID  | DevID |-------|ICtrl2 */
-    0x0000, 0x0000, 0x026b, 0x0000, 0x8086, 0x0000, 0x0000, 0x8058,
-  /*    NVM words 1,2,3    |-------------------------------|PCI-EID*/
-    0x0000, 0x2001, 0x7e7c, 0xffff, 0x1000, 0x00c8, 0x0000, 0x2704,
-  /* PCIe Init. Conf 1,2,3 |PCICtrl|PHY|LD1|-------| RevID | LD0,2 */
-    0x6cc9, 0x3150, 0x070e, 0x460b, 0x2d84, 0x0100, 0xf000, 0x0706,
-  /* FLPAR |FLANADD|LAN-PWR|FlVndr |ICtrl3 |APTSMBA|APTRxEP|APTSMBC*/
-    0x6000, 0x0080, 0x0f04, 0x7fff, 0x4f01, 0xc600, 0x0000, 0x20ff,
-  /* APTIF | APTMC |APTuCP |LSWFWID|MSWFWID|NC-SIMC|NC-SIC | VPDP  */
-    0x0028, 0x0003, 0x0000, 0x0000, 0x0000, 0x0003, 0x0000, 0xffff,
-  /*                            SW Section                         */
-    0x0100, 0xc000, 0x121c, 0xc007, 0xffff, 0xffff, 0xffff, 0xffff,
-  /*                      SW Section                       |CHKSUM */
-    0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0120, 0xffff, 0x0000,
-};
-
-static void e1000e_core_realize(E1000EState *s)
-{
-    s->core.owner = &s->parent_obj;
-    s->core.owner_nic = s->nic;
-}
-
-static void
-e1000e_unuse_msix_vectors(E1000EState *s, int num_vectors)
-{
-    int i;
-    for (i = 0; i < num_vectors; i++) {
-        msix_vector_unuse(PCI_DEVICE(s), i);
-    }
-}
-
-static bool
-e1000e_use_msix_vectors(E1000EState *s, int num_vectors)
-{
-    int i;
-    for (i = 0; i < num_vectors; i++) {
-        int res = msix_vector_use(PCI_DEVICE(s), i);
-        if (res < 0) {
-            trace_e1000e_msix_use_vector_fail(i, res);
-            e1000e_unuse_msix_vectors(s, i);
-            return false;
-        }
-    }
-    return true;
-}
-
-static void
-e1000e_init_msix(E1000EState *s)
-{
-    PCIDevice *d = PCI_DEVICE(s);
-    int res = msix_init(PCI_DEVICE(s), E1000E_MSIX_VEC_NUM,
-                        &s->msix,
-                        E1000E_MSIX_IDX, E1000E_MSIX_TABLE,
-                        &s->msix,
-                        E1000E_MSIX_IDX, E1000E_MSIX_PBA,
-                        0xA0);
-
-    if (res < 0) {
-        trace_e1000e_msix_init_fail(res);
-    } else {
-        if (!e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM)) {
-            msix_uninit(d, &s->msix, &s->msix);
-        }
-    }
-}
-
-static void
-e1000e_cleanup_msix(E1000EState *s)
-{
-    if (msix_enabled(PCI_DEVICE(s))) {
-        e1000e_unuse_msix_vectors(s, E1000E_MSIX_VEC_NUM);
-        msix_uninit(PCI_DEVICE(s), &s->msix, &s->msix);
-    }
-}
-
-static void
-e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, uint8_t *macaddr)
-{
-    DeviceState *dev = DEVICE(pci_dev);
-    NetClientState *nc;
-    int i;
-
-    s->nic = qemu_new_nic(&net_e1000e_info, &s->conf,
-        object_get_typename(OBJECT(s)), dev->id, s);
-
-    s->core.max_queue_num = s->conf.peers.queues - 1;
-
-    trace_e1000e_mac_set_permanent(MAC_ARG(macaddr));
-    memcpy(s->core.permanent_mac, macaddr, sizeof(s->core.permanent_mac));
-
-    qemu_format_nic_info_str(qemu_get_queue(s->nic), macaddr);
-
-    /* Setup virtio headers */
-    if (s->disable_vnet) {
-        s->core.has_vnet = false;
-        trace_e1000e_cfg_support_virtio(false);
-        return;
-    } else {
-        s->core.has_vnet = true;
-    }
-
-    for (i = 0; i < s->conf.peers.queues; i++) {
-        nc = qemu_get_subqueue(s->nic, i);
-        if (!nc->peer || !qemu_has_vnet_hdr(nc->peer)) {
-            s->core.has_vnet = false;
-            trace_e1000e_cfg_support_virtio(false);
-            return;
-        }
-    }
-
-    trace_e1000e_cfg_support_virtio(true);
-
-    for (i = 0; i < s->conf.peers.queues; i++) {
-        nc = qemu_get_subqueue(s->nic, i);
-        qemu_set_vnet_hdr_len(nc->peer, sizeof(struct virtio_net_hdr));
-        qemu_using_vnet_hdr(nc->peer, true);
-    }
-}
-
-static inline uint64_t
-e1000e_gen_dsn(uint8_t *mac)
-{
-    return (uint64_t)(mac[5])        |
-           (uint64_t)(mac[4])  << 8  |
-           (uint64_t)(mac[3])  << 16 |
-           (uint64_t)(0x00FF)  << 24 |
-           (uint64_t)(0x00FF)  << 32 |
-           (uint64_t)(mac[2])  << 40 |
-           (uint64_t)(mac[1])  << 48 |
-           (uint64_t)(mac[0])  << 56;
-}
-
-static int
-e1000e_add_pm_capability(PCIDevice *pdev, uint8_t offset, uint16_t pmc)
-{
-    int ret = pci_add_capability(pdev, PCI_CAP_ID_PM, offset, PCI_PM_SIZEOF);
-
-    if (ret >= 0) {
-        pci_set_word(pdev->config + offset + PCI_PM_PMC,
-                     PCI_PM_CAP_VER_1_1 |
-                     pmc);
-
-        pci_set_word(pdev->wmask + offset + PCI_PM_CTRL,
-                     PCI_PM_CTRL_STATE_MASK |
-                     PCI_PM_CTRL_PME_ENABLE |
-                     PCI_PM_CTRL_DATA_SEL_MASK);
-
-        pci_set_word(pdev->w1cmask + offset + PCI_PM_CTRL,
-                     PCI_PM_CTRL_PME_STATUS);
-    }
-
-    return ret;
-}
-
-static void e1000e_write_config(PCIDevice *pci_dev, uint32_t address,
-                                uint32_t val, int len)
-{
-    E1000EState *s = E1000E(pci_dev);
-
-    pci_default_write_config(pci_dev, address, val, len);
-
-    if (range_covers_byte(address, len, PCI_COMMAND) &&
-        (pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
-        qemu_flush_queued_packets(qemu_get_queue(s->nic));
-    }
-}
-
-static void e1000e_pci_realize(PCIDevice *pci_dev, Error **errp)
-{
-    static const uint16_t e1000e_pmrb_offset = 0x0C8;
-    static const uint16_t e1000e_pcie_offset = 0x0E0;
-    static const uint16_t e1000e_aer_offset =  0x100;
-    static const uint16_t e1000e_dsn_offset =  0x140;
-    E1000EState *s = E1000E(pci_dev);
-    uint8_t *macaddr;
-    int ret;
-
-    trace_e1000e_cb_pci_realize();
-
-    pci_dev->config_write = e1000e_write_config;
-
-    pci_dev->config[PCI_CACHE_LINE_SIZE] = 0x10;
-    pci_dev->config[PCI_INTERRUPT_PIN] = 1;
-
-    pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID, s->subsys_ven);
-    pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, s->subsys);
-
-    s->subsys_ven_used = s->subsys_ven;
-    s->subsys_used = s->subsys;
-
-    /* Define IO/MMIO regions */
-    memory_region_init_io(&s->mmio, OBJECT(s), &mmio_ops, s,
-                          "e1000e-mmio", E1000E_MMIO_SIZE);
-    pci_register_bar(pci_dev, E1000E_MMIO_IDX,
-                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
-
-    /*
-     * We provide a dummy implementation for the flash BAR
-     * for drivers that may theoretically probe for its presence.
-     */
-    memory_region_init(&s->flash, OBJECT(s),
-                       "e1000e-flash", E1000E_FLASH_SIZE);
-    pci_register_bar(pci_dev, E1000E_FLASH_IDX,
-                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->flash);
-
-    memory_region_init_io(&s->io, OBJECT(s), &io_ops, s,
-                          "e1000e-io", E1000E_IO_SIZE);
-    pci_register_bar(pci_dev, E1000E_IO_IDX,
-                     PCI_BASE_ADDRESS_SPACE_IO, &s->io);
-
-    memory_region_init(&s->msix, OBJECT(s), "e1000e-msix",
-                       E1000E_MSIX_SIZE);
-    pci_register_bar(pci_dev, E1000E_MSIX_IDX,
-                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->msix);
-
-    /* Create networking backend */
-    qemu_macaddr_default_if_unset(&s->conf.macaddr);
-    macaddr = s->conf.macaddr.a;
-
-    e1000e_init_msix(s);
-
-    if (pcie_endpoint_cap_v1_init(pci_dev, e1000e_pcie_offset) < 0) {
-        hw_error("Failed to initialize PCIe capability");
-    }
-
-    ret = msi_init(PCI_DEVICE(s), 0xD0, 1, true, false, NULL);
-    if (ret) {
-        trace_e1000e_msi_init_fail(ret);
-    }
-
-    if (e1000e_add_pm_capability(pci_dev, e1000e_pmrb_offset,
-                                  PCI_PM_CAP_DSI) < 0) {
-        hw_error("Failed to initialize PM capability");
-    }
-
-    if (pcie_aer_init(pci_dev, e1000e_aer_offset, PCI_ERR_SIZEOF) < 0) {
-        hw_error("Failed to initialize AER capability");
-    }
-
-    pcie_dev_ser_num_init(pci_dev, e1000e_dsn_offset,
-                          e1000e_gen_dsn(macaddr));
-
-    e1000e_init_net_peer(s, pci_dev, macaddr);
-
-    /* Initialize core */
-    e1000e_core_realize(s);
-
-    e1000e_core_pci_realize(&s->core,
-                            e1000e_eeprom_template,
-                            sizeof(e1000e_eeprom_template),
-                            macaddr);
-}
-
-static void e1000e_pci_uninit(PCIDevice *pci_dev)
-{
-    E1000EState *s = E1000E(pci_dev);
-
-    trace_e1000e_cb_pci_uninit();
-
-    e1000e_core_pci_uninit(&s->core);
-
-    pcie_aer_exit(pci_dev);
-    pcie_cap_exit(pci_dev);
-
-    qemu_del_nic(s->nic);
-
-    e1000e_cleanup_msix(s);
-    msi_uninit(pci_dev);
-}
-
-static void e1000e_qdev_reset(DeviceState *dev)
-{
-    E1000EState *s = E1000E(dev);
-
-    trace_e1000e_cb_qdev_reset();
-
-    e1000e_core_reset(&s->core);
-}
-
-static void e1000e_pre_save(void *opaque)
-{
-    E1000EState *s = opaque;
-
-    trace_e1000e_cb_pre_save();
-
-    e1000e_core_pre_save(&s->core);
-}
-
-static int e1000e_post_load(void *opaque, int version_id)
-{
-    E1000EState *s = opaque;
-
-    trace_e1000e_cb_post_load();
-
-    if ((s->subsys != s->subsys_used) ||
-        (s->subsys_ven != s->subsys_ven_used)) {
-        fprintf(stderr,
-            "ERROR: Cannot migrate while device properties "
-            "(subsys/subsys_ven) differ");
-        return -1;
-    }
-
-    return e1000e_core_post_load(&s->core);
-}
-
-static const VMStateDescription e1000e_vmstate_tx = {
-    .name = "e1000e-tx",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT8(props.sum_needed, struct e1000e_tx),
-        VMSTATE_UINT8(props.ipcss, struct e1000e_tx),
-        VMSTATE_UINT8(props.ipcso, struct e1000e_tx),
-        VMSTATE_UINT16(props.ipcse, struct e1000e_tx),
-        VMSTATE_UINT8(props.tucss, struct e1000e_tx),
-        VMSTATE_UINT8(props.tucso, struct e1000e_tx),
-        VMSTATE_UINT16(props.tucse, struct e1000e_tx),
-        VMSTATE_UINT8(props.hdr_len, struct e1000e_tx),
-        VMSTATE_UINT16(props.mss, struct e1000e_tx),
-        VMSTATE_UINT32(props.paylen, struct e1000e_tx),
-        VMSTATE_INT8(props.ip, struct e1000e_tx),
-        VMSTATE_INT8(props.tcp, struct e1000e_tx),
-        VMSTATE_BOOL(props.tse, struct e1000e_tx),
-        VMSTATE_BOOL(props.cptse, struct e1000e_tx),
-        VMSTATE_BOOL(skip_cp, struct e1000e_tx),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static const VMStateDescription e1000e_vmstate_intr_timer = {
-    .name = "e1000e-intr-timer",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_TIMER_PTR(timer, E1000IntrDelayTimer),
-        VMSTATE_BOOL(running, E1000IntrDelayTimer),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-#define VMSTATE_E1000E_INTR_DELAY_TIMER(_f, _s)                     \
-    VMSTATE_STRUCT(_f, _s, 0,                                       \
-                   e1000e_vmstate_intr_timer, E1000IntrDelayTimer)
-
-#define VMSTATE_E1000E_INTR_DELAY_TIMER_ARRAY(_f, _s, _num)         \
-    VMSTATE_STRUCT_ARRAY(_f, _s, _num, 0,                           \
-                         e1000e_vmstate_intr_timer, E1000IntrDelayTimer)
-
-static const VMStateDescription e1000e_vmstate = {
-    .name = "e1000e",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .pre_save = e1000e_pre_save,
-    .post_load = e1000e_post_load,
-    .fields = (VMStateField[]) {
-        VMSTATE_PCIE_DEVICE(parent_obj, E1000EState),
-        VMSTATE_MSIX(parent_obj, E1000EState),
-
-        VMSTATE_UINT32(ioaddr, E1000EState),
-        VMSTATE_UINT32(core.rxbuf_min_shift, E1000EState),
-        VMSTATE_UINT8(core.rx_desc_len, E1000EState),
-        VMSTATE_UINT32_ARRAY(core.rxbuf_sizes, E1000EState,
-                             E1000_PSRCTL_BUFFS_PER_DESC),
-        VMSTATE_UINT32(core.rx_desc_buf_size, E1000EState),
-        VMSTATE_UINT16_ARRAY(core.eeprom, E1000EState, E1000E_EEPROM_SIZE),
-        VMSTATE_UINT16_2DARRAY(core.phy, E1000EState,
-                               E1000E_PHY_PAGES, E1000E_PHY_PAGE_SIZE),
-        VMSTATE_UINT32_ARRAY(core.mac, E1000EState, E1000E_MAC_SIZE),
-        VMSTATE_UINT8_ARRAY(core.permanent_mac, E1000EState, ETH_ALEN),
-
-        VMSTATE_UINT32(core.delayed_causes, E1000EState),
-
-        VMSTATE_UINT16(subsys, E1000EState),
-        VMSTATE_UINT16(subsys_ven, E1000EState),
-
-        VMSTATE_E1000E_INTR_DELAY_TIMER(core.rdtr, E1000EState),
-        VMSTATE_E1000E_INTR_DELAY_TIMER(core.radv, E1000EState),
-        VMSTATE_E1000E_INTR_DELAY_TIMER(core.raid, E1000EState),
-        VMSTATE_E1000E_INTR_DELAY_TIMER(core.tadv, E1000EState),
-        VMSTATE_E1000E_INTR_DELAY_TIMER(core.tidv, E1000EState),
-
-        VMSTATE_E1000E_INTR_DELAY_TIMER(core.itr, E1000EState),
-        VMSTATE_BOOL(core.itr_intr_pending, E1000EState),
-
-        VMSTATE_E1000E_INTR_DELAY_TIMER_ARRAY(core.eitr, E1000EState,
-                                              E1000E_MSIX_VEC_NUM),
-        VMSTATE_BOOL_ARRAY(core.eitr_intr_pending, E1000EState,
-                           E1000E_MSIX_VEC_NUM),
-
-        VMSTATE_UINT32(core.itr_guest_value, E1000EState),
-        VMSTATE_UINT32_ARRAY(core.eitr_guest_value, E1000EState,
-                             E1000E_MSIX_VEC_NUM),
-
-        VMSTATE_UINT16(core.vet, E1000EState),
-
-        VMSTATE_STRUCT_ARRAY(core.tx, E1000EState, E1000E_NUM_QUEUES, 0,
-                             e1000e_vmstate_tx, struct e1000e_tx),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static PropertyInfo e1000e_prop_disable_vnet,
-                    e1000e_prop_subsys_ven,
-                    e1000e_prop_subsys;
-
-static Property e1000e_properties[] = {
-    DEFINE_NIC_PROPERTIES(E1000EState, conf),
-    DEFINE_PROP_DEFAULT("disable_vnet_hdr", E1000EState, disable_vnet, false,
-                        e1000e_prop_disable_vnet, bool),
-    DEFINE_PROP_DEFAULT("subsys_ven", E1000EState, subsys_ven,
-                        PCI_VENDOR_ID_INTEL,
-                        e1000e_prop_subsys_ven, uint16_t),
-    DEFINE_PROP_DEFAULT("subsys", E1000EState, subsys, 0,
-                        e1000e_prop_subsys, uint16_t),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void e1000e_class_init(ObjectClass *class, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(class);
-    PCIDeviceClass *c = PCI_DEVICE_CLASS(class);
-
-    c->realize = e1000e_pci_realize;
-    c->exit = e1000e_pci_uninit;
-    c->vendor_id = PCI_VENDOR_ID_INTEL;
-    c->device_id = E1000_DEV_ID_82574L;
-    c->revision = 0;
-    c->romfile = "efi-e1000e.rom";
-    c->class_id = PCI_CLASS_NETWORK_ETHERNET;
-    c->is_express = 1;
-
-    dc->desc = "Intel 82574L GbE Controller";
-    dc->reset = e1000e_qdev_reset;
-    dc->vmsd = &e1000e_vmstate;
-    dc->props = e1000e_properties;
-
-    e1000e_prop_disable_vnet = qdev_prop_uint8;
-    e1000e_prop_disable_vnet.description = "Do not use virtio headers, "
-                                           "perform SW offloads emulation "
-                                           "instead";
-
-    e1000e_prop_subsys_ven = qdev_prop_uint16;
-    e1000e_prop_subsys_ven.description = "PCI device Subsystem Vendor ID";
-
-    e1000e_prop_subsys = qdev_prop_uint16;
-    e1000e_prop_subsys.description = "PCI device Subsystem ID";
-
-    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
-}
-
-static void e1000e_instance_init(Object *obj)
-{
-    E1000EState *s = E1000E(obj);
-    device_add_bootindex_property(obj, &s->conf.bootindex,
-                                  "bootindex", "/ethernet-phy@0",
-                                  DEVICE(obj), NULL);
-}
-
-static const TypeInfo e1000e_info = {
-    .name = TYPE_E1000E,
-    .parent = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(E1000EState),
-    .class_init = e1000e_class_init,
-    .instance_init = e1000e_instance_init,
-};
-
-static void e1000e_register_types(void)
-{
-    type_register_static(&e1000e_info);
-}
-
-type_init(e1000e_register_types)
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
deleted file mode 100644 (file)
index badb1fe..0000000
+++ /dev/null
@@ -1,3483 +0,0 @@
-/*
-* Core code for QEMU e1000e emulation
-*
-* Software developer's manuals:
-* http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf
-*
-* Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
-* Developed by Daynix Computing LTD (http://www.daynix.com)
-*
-* Authors:
-* Dmitry Fleytman <dmitry@daynix.com>
-* Leonid Bloch <leonid@daynix.com>
-* Yan Vugenfirer <yan@daynix.com>
-*
-* Based on work done by:
-* Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
-* Copyright (c) 2008 Qumranet
-* Based on work done by:
-* Copyright (c) 2007 Dan Aloni
-* Copyright (c) 2004 Antony T Curtis
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 2 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "qemu/osdep.h"
-#include "sysemu/sysemu.h"
-#include "net/net.h"
-#include "net/tap.h"
-#include "hw/pci/msi.h"
-#include "hw/pci/msix.h"
-
-#include "net_tx_pkt.h"
-#include "net_rx_pkt.h"
-
-#include "e1000x_common.h"
-#include "e1000e_core.h"
-
-#include "trace.h"
-
-#define E1000E_MIN_XITR     (500) /* No more then 7813 interrupts per
-                                     second according to spec 10.2.4.2 */
-#define E1000E_MAX_TX_FRAGS (64)
-
-static void
-e1000e_set_interrupt_cause(E1000ECore *core, uint32_t val);
-
-static inline void
-e1000e_process_ts_option(E1000ECore *core, struct e1000_tx_desc *dp)
-{
-    if (le32_to_cpu(dp->upper.data) & E1000_TXD_EXTCMD_TSTAMP) {
-        trace_e1000e_wrn_no_ts_support();
-    }
-}
-
-static inline void
-e1000e_process_snap_option(E1000ECore *core, uint32_t cmd_and_length)
-{
-    if (cmd_and_length & E1000_TXD_CMD_SNAP) {
-        trace_e1000e_wrn_no_snap_support();
-    }
-}
-
-static inline void
-e1000e_raise_legacy_irq(E1000ECore *core)
-{
-    trace_e1000e_irq_legacy_notify(true);
-    e1000x_inc_reg_if_not_full(core->mac, IAC);
-    pci_set_irq(core->owner, 1);
-}
-
-static inline void
-e1000e_lower_legacy_irq(E1000ECore *core)
-{
-    trace_e1000e_irq_legacy_notify(false);
-    pci_set_irq(core->owner, 0);
-}
-
-static inline void
-e1000e_intrmgr_rearm_timer(E1000IntrDelayTimer *timer)
-{
-    int64_t delay_ns = (int64_t) timer->core->mac[timer->delay_reg] *
-                                 timer->delay_resolution_ns;
-
-    trace_e1000e_irq_rearm_timer(timer->delay_reg << 2, delay_ns);
-
-    timer_mod(timer->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + delay_ns);
-
-    timer->running = true;
-}
-
-static void
-e1000e_intmgr_timer_resume(E1000IntrDelayTimer *timer)
-{
-    if (timer->running) {
-        e1000e_intrmgr_rearm_timer(timer);
-    }
-}
-
-static void
-e1000e_intmgr_timer_pause(E1000IntrDelayTimer *timer)
-{
-    if (timer->running) {
-        timer_del(timer->timer);
-    }
-}
-
-static inline void
-e1000e_intrmgr_stop_timer(E1000IntrDelayTimer *timer)
-{
-    if (timer->running) {
-        timer_del(timer->timer);
-        timer->running = false;
-    }
-}
-
-static inline void
-e1000e_intrmgr_fire_delayed_interrupts(E1000ECore *core)
-{
-    trace_e1000e_irq_fire_delayed_interrupts();
-    e1000e_set_interrupt_cause(core, 0);
-}
-
-static void
-e1000e_intrmgr_on_timer(void *opaque)
-{
-    E1000IntrDelayTimer *timer = opaque;
-
-    trace_e1000e_irq_throttling_timer(timer->delay_reg << 2);
-
-    timer->running = false;
-    e1000e_intrmgr_fire_delayed_interrupts(timer->core);
-}
-
-static void
-e1000e_intrmgr_on_throttling_timer(void *opaque)
-{
-    E1000IntrDelayTimer *timer = opaque;
-
-    assert(!msix_enabled(timer->core->owner));
-
-    timer->running = false;
-
-    if (!timer->core->itr_intr_pending) {
-        trace_e1000e_irq_throttling_no_pending_interrupts();
-        return;
-    }
-
-    if (msi_enabled(timer->core->owner)) {
-        trace_e1000e_irq_msi_notify_postponed();
-        e1000e_set_interrupt_cause(timer->core, 0);
-    } else {
-        trace_e1000e_irq_legacy_notify_postponed();
-        e1000e_set_interrupt_cause(timer->core, 0);
-    }
-}
-
-static void
-e1000e_intrmgr_on_msix_throttling_timer(void *opaque)
-{
-    E1000IntrDelayTimer *timer = opaque;
-    int idx = timer - &timer->core->eitr[0];
-
-    assert(msix_enabled(timer->core->owner));
-
-    timer->running = false;
-
-    if (!timer->core->eitr_intr_pending[idx]) {
-        trace_e1000e_irq_throttling_no_pending_vec(idx);
-        return;
-    }
-
-    trace_e1000e_irq_msix_notify_postponed_vec(idx);
-    msix_notify(timer->core->owner, idx);
-}
-
-static void
-e1000e_intrmgr_initialize_all_timers(E1000ECore *core, bool create)
-{
-    int i;
-
-    core->radv.delay_reg = RADV;
-    core->rdtr.delay_reg = RDTR;
-    core->raid.delay_reg = RAID;
-    core->tadv.delay_reg = TADV;
-    core->tidv.delay_reg = TIDV;
-
-    core->radv.delay_resolution_ns = E1000_INTR_DELAY_NS_RES;
-    core->rdtr.delay_resolution_ns = E1000_INTR_DELAY_NS_RES;
-    core->raid.delay_resolution_ns = E1000_INTR_DELAY_NS_RES;
-    core->tadv.delay_resolution_ns = E1000_INTR_DELAY_NS_RES;
-    core->tidv.delay_resolution_ns = E1000_INTR_DELAY_NS_RES;
-
-    core->radv.core = core;
-    core->rdtr.core = core;
-    core->raid.core = core;
-    core->tadv.core = core;
-    core->tidv.core = core;
-
-    core->itr.core = core;
-    core->itr.delay_reg = ITR;
-    core->itr.delay_resolution_ns = E1000_INTR_THROTTLING_NS_RES;
-
-    for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) {
-        core->eitr[i].core = core;
-        core->eitr[i].delay_reg = EITR + i;
-        core->eitr[i].delay_resolution_ns = E1000_INTR_THROTTLING_NS_RES;
-    }
-
-    if (!create) {
-        return;
-    }
-
-    core->radv.timer =
-        timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->radv);
-    core->rdtr.timer =
-        timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->rdtr);
-    core->raid.timer =
-        timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->raid);
-
-    core->tadv.timer =
-        timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->tadv);
-    core->tidv.timer =
-        timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->tidv);
-
-    core->itr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
-                                   e1000e_intrmgr_on_throttling_timer,
-                                   &core->itr);
-
-    for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) {
-        core->eitr[i].timer =
-            timer_new_ns(QEMU_CLOCK_VIRTUAL,
-                         e1000e_intrmgr_on_msix_throttling_timer,
-                         &core->eitr[i]);
-    }
-}
-
-static inline void
-e1000e_intrmgr_stop_delay_timers(E1000ECore *core)
-{
-    e1000e_intrmgr_stop_timer(&core->radv);
-    e1000e_intrmgr_stop_timer(&core->rdtr);
-    e1000e_intrmgr_stop_timer(&core->raid);
-    e1000e_intrmgr_stop_timer(&core->tidv);
-    e1000e_intrmgr_stop_timer(&core->tadv);
-}
-
-static bool
-e1000e_intrmgr_delay_rx_causes(E1000ECore *core, uint32_t *causes)
-{
-    uint32_t delayable_causes;
-    uint32_t rdtr = core->mac[RDTR];
-    uint32_t radv = core->mac[RADV];
-    uint32_t raid = core->mac[RAID];
-
-    if (msix_enabled(core->owner)) {
-        return false;
-    }
-
-    delayable_causes = E1000_ICR_RXQ0 |
-                       E1000_ICR_RXQ1 |
-                       E1000_ICR_RXT0;
-
-    if (!(core->mac[RFCTL] & E1000_RFCTL_ACK_DIS)) {
-        delayable_causes |= E1000_ICR_ACK;
-    }
-
-    /* Clean up all causes that may be delayed */
-    core->delayed_causes |= *causes & delayable_causes;
-    *causes &= ~delayable_causes;
-
-    /* Check if delayed RX interrupts disabled by client
-       or if there are causes that cannot be delayed */
-    if ((rdtr == 0) || (*causes != 0)) {
-        return false;
-    }
-
-    /* Check if delayed RX ACK interrupts disabled by client
-       and there is an ACK packet received */
-    if ((raid == 0) && (core->delayed_causes & E1000_ICR_ACK)) {
-        return false;
-    }
-
-    /* All causes delayed */
-    e1000e_intrmgr_rearm_timer(&core->rdtr);
-
-    if (!core->radv.running && (radv != 0)) {
-        e1000e_intrmgr_rearm_timer(&core->radv);
-    }
-
-    if (!core->raid.running && (core->delayed_causes & E1000_ICR_ACK)) {
-        e1000e_intrmgr_rearm_timer(&core->raid);
-    }
-
-    return true;
-}
-
-static bool
-e1000e_intrmgr_delay_tx_causes(E1000ECore *core, uint32_t *causes)
-{
-    static const uint32_t delayable_causes = E1000_ICR_TXQ0 |
-                                             E1000_ICR_TXQ1 |
-                                             E1000_ICR_TXQE |
-                                             E1000_ICR_TXDW;
-
-    if (msix_enabled(core->owner)) {
-        return false;
-    }
-
-    /* Clean up all causes that may be delayed */
-    core->delayed_causes |= *causes & delayable_causes;
-    *causes &= ~delayable_causes;
-
-    /* If there are causes that cannot be delayed */
-    if (*causes != 0) {
-        return false;
-    }
-
-    /* All causes delayed */
-    e1000e_intrmgr_rearm_timer(&core->tidv);
-
-    if (!core->tadv.running && (core->mac[TADV] != 0)) {
-        e1000e_intrmgr_rearm_timer(&core->tadv);
-    }
-
-    return true;
-}
-
-static uint32_t
-e1000e_intmgr_collect_delayed_causes(E1000ECore *core)
-{
-    uint32_t res;
-
-    if (msix_enabled(core->owner)) {
-        assert(core->delayed_causes == 0);
-        return 0;
-    }
-
-    res = core->delayed_causes;
-    core->delayed_causes = 0;
-
-    e1000e_intrmgr_stop_delay_timers(core);
-
-    return res;
-}
-
-static void
-e1000e_intrmgr_fire_all_timers(E1000ECore *core)
-{
-    int i;
-    uint32_t val = e1000e_intmgr_collect_delayed_causes(core);
-
-    trace_e1000e_irq_adding_delayed_causes(val, core->mac[ICR]);
-    core->mac[ICR] |= val;
-
-    if (core->itr.running) {
-        timer_del(core->itr.timer);
-        e1000e_intrmgr_on_throttling_timer(&core->itr);
-    }
-
-    for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) {
-        if (core->eitr[i].running) {
-            timer_del(core->eitr[i].timer);
-            e1000e_intrmgr_on_msix_throttling_timer(&core->eitr[i]);
-        }
-    }
-}
-
-static void
-e1000e_intrmgr_resume(E1000ECore *core)
-{
-    int i;
-
-    e1000e_intmgr_timer_resume(&core->radv);
-    e1000e_intmgr_timer_resume(&core->rdtr);
-    e1000e_intmgr_timer_resume(&core->raid);
-    e1000e_intmgr_timer_resume(&core->tidv);
-    e1000e_intmgr_timer_resume(&core->tadv);
-
-    e1000e_intmgr_timer_resume(&core->itr);
-
-    for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) {
-        e1000e_intmgr_timer_resume(&core->eitr[i]);
-    }
-}
-
-static void
-e1000e_intrmgr_pause(E1000ECore *core)
-{
-    int i;
-
-    e1000e_intmgr_timer_pause(&core->radv);
-    e1000e_intmgr_timer_pause(&core->rdtr);
-    e1000e_intmgr_timer_pause(&core->raid);
-    e1000e_intmgr_timer_pause(&core->tidv);
-    e1000e_intmgr_timer_pause(&core->tadv);
-
-    e1000e_intmgr_timer_pause(&core->itr);
-
-    for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) {
-        e1000e_intmgr_timer_pause(&core->eitr[i]);
-    }
-}
-
-static void
-e1000e_intrmgr_reset(E1000ECore *core)
-{
-    int i;
-
-    core->delayed_causes = 0;
-
-    e1000e_intrmgr_stop_delay_timers(core);
-
-    e1000e_intrmgr_stop_timer(&core->itr);
-
-    for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) {
-        e1000e_intrmgr_stop_timer(&core->eitr[i]);
-    }
-}
-
-static void
-e1000e_intrmgr_pci_unint(E1000ECore *core)
-{
-    int i;
-
-    timer_del(core->radv.timer);
-    timer_free(core->radv.timer);
-    timer_del(core->rdtr.timer);
-    timer_free(core->rdtr.timer);
-    timer_del(core->raid.timer);
-    timer_free(core->raid.timer);
-
-    timer_del(core->tadv.timer);
-    timer_free(core->tadv.timer);
-    timer_del(core->tidv.timer);
-    timer_free(core->tidv.timer);
-
-    timer_del(core->itr.timer);
-    timer_free(core->itr.timer);
-
-    for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) {
-        timer_del(core->eitr[i].timer);
-        timer_free(core->eitr[i].timer);
-    }
-}
-
-static void
-e1000e_intrmgr_pci_realize(E1000ECore *core)
-{
-    e1000e_intrmgr_initialize_all_timers(core, true);
-}
-
-static inline bool
-e1000e_rx_csum_enabled(E1000ECore *core)
-{
-    return (core->mac[RXCSUM] & E1000_RXCSUM_PCSD) ? false : true;
-}
-
-static inline bool
-e1000e_rx_use_legacy_descriptor(E1000ECore *core)
-{
-    return (core->mac[RFCTL] & E1000_RFCTL_EXTEN) ? false : true;
-}
-
-static inline bool
-e1000e_rx_use_ps_descriptor(E1000ECore *core)
-{
-    return !e1000e_rx_use_legacy_descriptor(core) &&
-           (core->mac[RCTL] & E1000_RCTL_DTYP_PS);
-}
-
-static inline bool
-e1000e_rss_enabled(E1000ECore *core)
-{
-    return E1000_MRQC_ENABLED(core->mac[MRQC]) &&
-           !e1000e_rx_csum_enabled(core) &&
-           !e1000e_rx_use_legacy_descriptor(core);
-}
-
-typedef struct E1000E_RSSInfo_st {
-    bool enabled;
-    uint32_t hash;
-    uint32_t queue;
-    uint32_t type;
-} E1000E_RSSInfo;
-
-static uint32_t
-e1000e_rss_get_hash_type(E1000ECore *core, struct NetRxPkt *pkt)
-{
-    bool isip4, isip6, isudp, istcp;
-
-    assert(e1000e_rss_enabled(core));
-
-    net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
-
-    if (isip4) {
-        bool fragment = net_rx_pkt_get_ip4_info(pkt)->fragment;
-
-        trace_e1000e_rx_rss_ip4(fragment, istcp, core->mac[MRQC],
-                                E1000_MRQC_EN_TCPIPV4(core->mac[MRQC]),
-                                E1000_MRQC_EN_IPV4(core->mac[MRQC]));
-
-        if (!fragment && istcp && E1000_MRQC_EN_TCPIPV4(core->mac[MRQC])) {
-            return E1000_MRQ_RSS_TYPE_IPV4TCP;
-        }
-
-        if (E1000_MRQC_EN_IPV4(core->mac[MRQC])) {
-            return E1000_MRQ_RSS_TYPE_IPV4;
-        }
-    } else if (isip6) {
-        eth_ip6_hdr_info *ip6info = net_rx_pkt_get_ip6_info(pkt);
-
-        bool ex_dis = core->mac[RFCTL] & E1000_RFCTL_IPV6_EX_DIS;
-        bool new_ex_dis = core->mac[RFCTL] & E1000_RFCTL_NEW_IPV6_EXT_DIS;
-
-        /*
-         * Following two traces must not be combined because resulting
-         * event will have 11 arguments totally and some trace backends
-         * (at least "ust") have limitation of maximum 10 arguments per
-         * event. Events with more arguments fail to compile for
-         * backends like these.
-         */
-        trace_e1000e_rx_rss_ip6_rfctl(core->mac[RFCTL]);
-        trace_e1000e_rx_rss_ip6(ex_dis, new_ex_dis, istcp,
-                                ip6info->has_ext_hdrs,
-                                ip6info->rss_ex_dst_valid,
-                                ip6info->rss_ex_src_valid,
-                                core->mac[MRQC],
-                                E1000_MRQC_EN_TCPIPV6(core->mac[MRQC]),
-                                E1000_MRQC_EN_IPV6EX(core->mac[MRQC]),
-                                E1000_MRQC_EN_IPV6(core->mac[MRQC]));
-
-        if ((!ex_dis || !ip6info->has_ext_hdrs) &&
-            (!new_ex_dis || !(ip6info->rss_ex_dst_valid ||
-                              ip6info->rss_ex_src_valid))) {
-
-            if (istcp && !ip6info->fragment &&
-                E1000_MRQC_EN_TCPIPV6(core->mac[MRQC])) {
-                return E1000_MRQ_RSS_TYPE_IPV6TCP;
-            }
-
-            if (E1000_MRQC_EN_IPV6EX(core->mac[MRQC])) {
-                return E1000_MRQ_RSS_TYPE_IPV6EX;
-            }
-
-        }
-
-        if (E1000_MRQC_EN_IPV6(core->mac[MRQC])) {
-            return E1000_MRQ_RSS_TYPE_IPV6;
-        }
-
-    }
-
-    return E1000_MRQ_RSS_TYPE_NONE;
-}
-
-static uint32_t
-e1000e_rss_calc_hash(E1000ECore *core,
-                     struct NetRxPkt *pkt,
-                     E1000E_RSSInfo *info)
-{
-    NetRxPktRssType type;
-
-    assert(e1000e_rss_enabled(core));
-
-    switch (info->type) {
-    case E1000_MRQ_RSS_TYPE_IPV4:
-        type = NetPktRssIpV4;
-        break;
-    case E1000_MRQ_RSS_TYPE_IPV4TCP:
-        type = NetPktRssIpV4Tcp;
-        break;
-    case E1000_MRQ_RSS_TYPE_IPV6TCP:
-        type = NetPktRssIpV6Tcp;
-        break;
-    case E1000_MRQ_RSS_TYPE_IPV6:
-        type = NetPktRssIpV6;
-        break;
-    case E1000_MRQ_RSS_TYPE_IPV6EX:
-        type = NetPktRssIpV6Ex;
-        break;
-    default:
-        assert(false);
-        return 0;
-    }
-
-    return net_rx_pkt_calc_rss_hash(pkt, type, (uint8_t *) &core->mac[RSSRK]);
-}
-
-static void
-e1000e_rss_parse_packet(E1000ECore *core,
-                        struct NetRxPkt *pkt,
-                        E1000E_RSSInfo *info)
-{
-    trace_e1000e_rx_rss_started();
-
-    if (!e1000e_rss_enabled(core)) {
-        info->enabled = false;
-        info->hash = 0;
-        info->queue = 0;
-        info->type = 0;
-        trace_e1000e_rx_rss_disabled();
-        return;
-    }
-
-    info->enabled = true;
-
-    info->type = e1000e_rss_get_hash_type(core, pkt);
-
-    trace_e1000e_rx_rss_type(info->type);
-
-    if (info->type == E1000_MRQ_RSS_TYPE_NONE) {
-        info->hash = 0;
-        info->queue = 0;
-        return;
-    }
-
-    info->hash = e1000e_rss_calc_hash(core, pkt, info);
-    info->queue = E1000_RSS_QUEUE(&core->mac[RETA], info->hash);
-}
-
-static void
-e1000e_setup_tx_offloads(E1000ECore *core, struct e1000e_tx *tx)
-{
-    if (tx->props.tse && tx->props.cptse) {
-        net_tx_pkt_build_vheader(tx->tx_pkt, true, true, tx->props.mss);
-        net_tx_pkt_update_ip_checksums(tx->tx_pkt);
-        e1000x_inc_reg_if_not_full(core->mac, TSCTC);
-        return;
-    }
-
-    if (tx->props.sum_needed & E1000_TXD_POPTS_TXSM) {
-        net_tx_pkt_build_vheader(tx->tx_pkt, false, true, 0);
-    }
-
-    if (tx->props.sum_needed & E1000_TXD_POPTS_IXSM) {
-        net_tx_pkt_update_ip_hdr_checksum(tx->tx_pkt);
-    }
-}
-
-static bool
-e1000e_tx_pkt_send(E1000ECore *core, struct e1000e_tx *tx, int queue_index)
-{
-    int target_queue = MIN(core->max_queue_num, queue_index);
-    NetClientState *queue = qemu_get_subqueue(core->owner_nic, target_queue);
-
-    e1000e_setup_tx_offloads(core, tx);
-
-    net_tx_pkt_dump(tx->tx_pkt);
-
-    if ((core->phy[0][PHY_CTRL] & MII_CR_LOOPBACK) ||
-        ((core->mac[RCTL] & E1000_RCTL_LBM_MAC) == E1000_RCTL_LBM_MAC)) {
-        return net_tx_pkt_send_loopback(tx->tx_pkt, queue);
-    } else {
-        return net_tx_pkt_send(tx->tx_pkt, queue);
-    }
-}
-
-static void
-e1000e_on_tx_done_update_stats(E1000ECore *core, struct NetTxPkt *tx_pkt)
-{
-    static const int PTCregs[6] = { PTC64, PTC127, PTC255, PTC511,
-                                    PTC1023, PTC1522 };
-
-    size_t tot_len = net_tx_pkt_get_total_len(tx_pkt);
-
-    e1000x_increase_size_stats(core->mac, PTCregs, tot_len);
-    e1000x_inc_reg_if_not_full(core->mac, TPT);
-    e1000x_grow_8reg_if_not_full(core->mac, TOTL, tot_len);
-
-    switch (net_tx_pkt_get_packet_type(tx_pkt)) {
-    case ETH_PKT_BCAST:
-        e1000x_inc_reg_if_not_full(core->mac, BPTC);
-        break;
-    case ETH_PKT_MCAST:
-        e1000x_inc_reg_if_not_full(core->mac, MPTC);
-        break;
-    case ETH_PKT_UCAST:
-        break;
-    default:
-        g_assert_not_reached();
-    }
-
-    core->mac[GPTC] = core->mac[TPT];
-    core->mac[GOTCL] = core->mac[TOTL];
-    core->mac[GOTCH] = core->mac[TOTH];
-}
-
-static void
-e1000e_process_tx_desc(E1000ECore *core,
-                       struct e1000e_tx *tx,
-                       struct e1000_tx_desc *dp,
-                       int queue_index)
-{
-    uint32_t txd_lower = le32_to_cpu(dp->lower.data);
-    uint32_t dtype = txd_lower & (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D);
-    unsigned int split_size = txd_lower & 0xffff;
-    uint64_t addr;
-    struct e1000_context_desc *xp = (struct e1000_context_desc *)dp;
-    bool eop = txd_lower & E1000_TXD_CMD_EOP;
-
-    if (dtype == E1000_TXD_CMD_DEXT) { /* context descriptor */
-        e1000x_read_tx_ctx_descr(xp, &tx->props);
-        e1000e_process_snap_option(core, le32_to_cpu(xp->cmd_and_length));
-        return;
-    } else if (dtype == (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D)) {
-        /* data descriptor */
-        tx->props.sum_needed = le32_to_cpu(dp->upper.data) >> 8;
-        tx->props.cptse = (txd_lower & E1000_TXD_CMD_TSE) ? 1 : 0;
-        e1000e_process_ts_option(core, dp);
-    } else {
-        /* legacy descriptor */
-        e1000e_process_ts_option(core, dp);
-        tx->props.cptse = 0;
-    }
-
-    addr = le64_to_cpu(dp->buffer_addr);
-
-    if (!tx->skip_cp) {
-        if (!net_tx_pkt_add_raw_fragment(tx->tx_pkt, addr, split_size)) {
-            tx->skip_cp = true;
-        }
-    }
-
-    if (eop) {
-        if (!tx->skip_cp && net_tx_pkt_parse(tx->tx_pkt)) {
-            if (e1000x_vlan_enabled(core->mac) &&
-                e1000x_is_vlan_txd(txd_lower)) {
-                net_tx_pkt_setup_vlan_header_ex(tx->tx_pkt,
-                    le16_to_cpu(dp->upper.fields.special), core->vet);
-            }
-            if (e1000e_tx_pkt_send(core, tx, queue_index)) {
-                e1000e_on_tx_done_update_stats(core, tx->tx_pkt);
-            }
-        }
-
-        tx->skip_cp = false;
-        net_tx_pkt_reset(tx->tx_pkt);
-
-        tx->props.sum_needed = 0;
-        tx->props.cptse = 0;
-    }
-}
-
-static inline uint32_t
-e1000e_tx_wb_interrupt_cause(E1000ECore *core, int queue_idx)
-{
-    if (!msix_enabled(core->owner)) {
-        return E1000_ICR_TXDW;
-    }
-
-    return (queue_idx == 0) ? E1000_ICR_TXQ0 : E1000_ICR_TXQ1;
-}
-
-static inline uint32_t
-e1000e_rx_wb_interrupt_cause(E1000ECore *core, int queue_idx,
-                             bool min_threshold_hit)
-{
-    if (!msix_enabled(core->owner)) {
-        return E1000_ICS_RXT0 | (min_threshold_hit ? E1000_ICS_RXDMT0 : 0);
-    }
-
-    return (queue_idx == 0) ? E1000_ICR_RXQ0 : E1000_ICR_RXQ1;
-}
-
-static uint32_t
-e1000e_txdesc_writeback(E1000ECore *core, dma_addr_t base,
-                        struct e1000_tx_desc *dp, bool *ide, int queue_idx)
-{
-    uint32_t txd_upper, txd_lower = le32_to_cpu(dp->lower.data);
-
-    if (!(txd_lower & E1000_TXD_CMD_RS) &&
-        !(core->mac[IVAR] & E1000_IVAR_TX_INT_EVERY_WB)) {
-        return 0;
-    }
-
-    *ide = (txd_lower & E1000_TXD_CMD_IDE) ? true : false;
-
-    txd_upper = le32_to_cpu(dp->upper.data) | E1000_TXD_STAT_DD;
-
-    dp->upper.data = cpu_to_le32(txd_upper);
-    pci_dma_write(core->owner, base + ((char *)&dp->upper - (char *)dp),
-                  &dp->upper, sizeof(dp->upper));
-    return e1000e_tx_wb_interrupt_cause(core, queue_idx);
-}
-
-typedef struct E1000E_RingInfo_st {
-    int dbah;
-    int dbal;
-    int dlen;
-    int dh;
-    int dt;
-    int idx;
-} E1000E_RingInfo;
-
-static inline bool
-e1000e_ring_empty(E1000ECore *core, const E1000E_RingInfo *r)
-{
-    return core->mac[r->dh] == core->mac[r->dt];
-}
-
-static inline uint64_t
-e1000e_ring_base(E1000ECore *core, const E1000E_RingInfo *r)
-{
-    uint64_t bah = core->mac[r->dbah];
-    uint64_t bal = core->mac[r->dbal];
-
-    return (bah << 32) + bal;
-}
-
-static inline uint64_t
-e1000e_ring_head_descr(E1000ECore *core, const E1000E_RingInfo *r)
-{
-    return e1000e_ring_base(core, r) + E1000_RING_DESC_LEN * core->mac[r->dh];
-}
-
-static inline void
-e1000e_ring_advance(E1000ECore *core, const E1000E_RingInfo *r, uint32_t count)
-{
-    core->mac[r->dh] += count;
-
-    if (core->mac[r->dh] * E1000_RING_DESC_LEN >= core->mac[r->dlen]) {
-        core->mac[r->dh] = 0;
-    }
-}
-
-static inline uint32_t
-e1000e_ring_free_descr_num(E1000ECore *core, const E1000E_RingInfo *r)
-{
-    trace_e1000e_ring_free_space(r->idx, core->mac[r->dlen],
-                                 core->mac[r->dh],  core->mac[r->dt]);
-
-    if (core->mac[r->dh] <= core->mac[r->dt]) {
-        return core->mac[r->dt] - core->mac[r->dh];
-    }
-
-    if (core->mac[r->dh] > core->mac[r->dt]) {
-        return core->mac[r->dlen] / E1000_RING_DESC_LEN +
-               core->mac[r->dt] - core->mac[r->dh];
-    }
-
-    g_assert_not_reached();
-    return 0;
-}
-
-static inline bool
-e1000e_ring_enabled(E1000ECore *core, const E1000E_RingInfo *r)
-{
-    return core->mac[r->dlen] > 0;
-}
-
-static inline uint32_t
-e1000e_ring_len(E1000ECore *core, const E1000E_RingInfo *r)
-{
-    return core->mac[r->dlen];
-}
-
-typedef struct E1000E_TxRing_st {
-    const E1000E_RingInfo *i;
-    struct e1000e_tx *tx;
-} E1000E_TxRing;
-
-static inline int
-e1000e_mq_queue_idx(int base_reg_idx, int reg_idx)
-{
-    return (reg_idx - base_reg_idx) / (0x100 >> 2);
-}
-
-static inline void
-e1000e_tx_ring_init(E1000ECore *core, E1000E_TxRing *txr, int idx)
-{
-    static const E1000E_RingInfo i[E1000E_NUM_QUEUES] = {
-        { TDBAH,  TDBAL,  TDLEN,  TDH,  TDT, 0 },
-        { TDBAH1, TDBAL1, TDLEN1, TDH1, TDT1, 1 }
-    };
-
-    assert(idx < ARRAY_SIZE(i));
-
-    txr->i     = &i[idx];
-    txr->tx    = &core->tx[idx];
-}
-
-typedef struct E1000E_RxRing_st {
-    const E1000E_RingInfo *i;
-} E1000E_RxRing;
-
-static inline void
-e1000e_rx_ring_init(E1000ECore *core, E1000E_RxRing *rxr, int idx)
-{
-    static const E1000E_RingInfo i[E1000E_NUM_QUEUES] = {
-        { RDBAH0, RDBAL0, RDLEN0, RDH0, RDT0, 0 },
-        { RDBAH1, RDBAL1, RDLEN1, RDH1, RDT1, 1 }
-    };
-
-    assert(idx < ARRAY_SIZE(i));
-
-    rxr->i      = &i[idx];
-}
-
-static void
-e1000e_start_xmit(E1000ECore *core, const E1000E_TxRing *txr)
-{
-    dma_addr_t base;
-    struct e1000_tx_desc desc;
-    bool ide = false;
-    const E1000E_RingInfo *txi = txr->i;
-    uint32_t cause = E1000_ICS_TXQE;
-
-    if (!(core->mac[TCTL] & E1000_TCTL_EN)) {
-        trace_e1000e_tx_disabled();
-        return;
-    }
-
-    while (!e1000e_ring_empty(core, txi)) {
-        base = e1000e_ring_head_descr(core, txi);
-
-        pci_dma_read(core->owner, base, &desc, sizeof(desc));
-
-        trace_e1000e_tx_descr((void *)(intptr_t)desc.buffer_addr,
-                              desc.lower.data, desc.upper.data);
-
-        e1000e_process_tx_desc(core, txr->tx, &desc, txi->idx);
-        cause |= e1000e_txdesc_writeback(core, base, &desc, &ide, txi->idx);
-
-        e1000e_ring_advance(core, txi, 1);
-    }
-
-    if (!ide || !e1000e_intrmgr_delay_tx_causes(core, &cause)) {
-        e1000e_set_interrupt_cause(core, cause);
-    }
-}
-
-static bool
-e1000e_has_rxbufs(E1000ECore *core, const E1000E_RingInfo *r,
-                  size_t total_size)
-{
-    uint32_t bufs = e1000e_ring_free_descr_num(core, r);
-
-    trace_e1000e_rx_has_buffers(r->idx, bufs, total_size,
-                                core->rx_desc_buf_size);
-
-    return total_size <= bufs / (core->rx_desc_len / E1000_MIN_RX_DESC_LEN) *
-                         core->rx_desc_buf_size;
-}
-
-static inline void
-e1000e_start_recv(E1000ECore *core)
-{
-    int i;
-
-    trace_e1000e_rx_start_recv();
-
-    for (i = 0; i <= core->max_queue_num; i++) {
-        qemu_flush_queued_packets(qemu_get_subqueue(core->owner_nic, i));
-    }
-}
-
-int
-e1000e_can_receive(E1000ECore *core)
-{
-    int i;
-
-    if (!e1000x_rx_ready(core->owner, core->mac)) {
-        return false;
-    }
-
-    for (i = 0; i < E1000E_NUM_QUEUES; i++) {
-        E1000E_RxRing rxr;
-
-        e1000e_rx_ring_init(core, &rxr, i);
-        if (e1000e_ring_enabled(core, rxr.i) &&
-            e1000e_has_rxbufs(core, rxr.i, 1)) {
-            trace_e1000e_rx_can_recv();
-            return true;
-        }
-    }
-
-    trace_e1000e_rx_can_recv_rings_full();
-    return false;
-}
-
-ssize_t
-e1000e_receive(E1000ECore *core, const uint8_t *buf, size_t size)
-{
-    const struct iovec iov = {
-        .iov_base = (uint8_t *)buf,
-        .iov_len = size
-    };
-
-    return e1000e_receive_iov(core, &iov, 1);
-}
-
-static inline bool
-e1000e_rx_l3_cso_enabled(E1000ECore *core)
-{
-    return !!(core->mac[RXCSUM] & E1000_RXCSUM_IPOFLD);
-}
-
-static inline bool
-e1000e_rx_l4_cso_enabled(E1000ECore *core)
-{
-    return !!(core->mac[RXCSUM] & E1000_RXCSUM_TUOFLD);
-}
-
-static bool
-e1000e_receive_filter(E1000ECore *core, const uint8_t *buf, int size)
-{
-    uint32_t rctl = core->mac[RCTL];
-
-    if (e1000x_is_vlan_packet(buf, core->vet) &&
-        e1000x_vlan_rx_filter_enabled(core->mac)) {
-        uint16_t vid = lduw_be_p(buf + 14);
-        uint32_t vfta = ldl_le_p((uint32_t *)(core->mac + VFTA) +
-                                 ((vid >> 5) & 0x7f));
-        if ((vfta & (1 << (vid & 0x1f))) == 0) {
-            trace_e1000e_rx_flt_vlan_mismatch(vid);
-            return false;
-        } else {
-            trace_e1000e_rx_flt_vlan_match(vid);
-        }
-    }
-
-    switch (net_rx_pkt_get_packet_type(core->rx_pkt)) {
-    case ETH_PKT_UCAST:
-        if (rctl & E1000_RCTL_UPE) {
-            return true; /* promiscuous ucast */
-        }
-        break;
-
-    case ETH_PKT_BCAST:
-        if (rctl & E1000_RCTL_BAM) {
-            return true; /* broadcast enabled */
-        }
-        break;
-
-    case ETH_PKT_MCAST:
-        if (rctl & E1000_RCTL_MPE) {
-            return true; /* promiscuous mcast */
-        }
-        break;
-
-    default:
-        g_assert_not_reached();
-    }
-
-    return e1000x_rx_group_filter(core->mac, buf);
-}
-
-static inline void
-e1000e_read_lgcy_rx_descr(E1000ECore *core, uint8_t *desc, hwaddr *buff_addr)
-{
-    struct e1000_rx_desc *d = (struct e1000_rx_desc *) desc;
-    *buff_addr = le64_to_cpu(d->buffer_addr);
-}
-
-static inline void
-e1000e_read_ext_rx_descr(E1000ECore *core, uint8_t *desc, hwaddr *buff_addr)
-{
-    union e1000_rx_desc_extended *d = (union e1000_rx_desc_extended *) desc;
-    *buff_addr = le64_to_cpu(d->read.buffer_addr);
-}
-
-static inline void
-e1000e_read_ps_rx_descr(E1000ECore *core, uint8_t *desc,
-                        hwaddr (*buff_addr)[MAX_PS_BUFFERS])
-{
-    int i;
-    union e1000_rx_desc_packet_split *d =
-        (union e1000_rx_desc_packet_split *) desc;
-
-    for (i = 0; i < MAX_PS_BUFFERS; i++) {
-        (*buff_addr)[i] = le64_to_cpu(d->read.buffer_addr[i]);
-    }
-
-    trace_e1000e_rx_desc_ps_read((*buff_addr)[0], (*buff_addr)[1],
-                                 (*buff_addr)[2], (*buff_addr)[3]);
-}
-
-static inline void
-e1000e_read_rx_descr(E1000ECore *core, uint8_t *desc,
-                     hwaddr (*buff_addr)[MAX_PS_BUFFERS])
-{
-    if (e1000e_rx_use_legacy_descriptor(core)) {
-        e1000e_read_lgcy_rx_descr(core, desc, &(*buff_addr)[0]);
-        (*buff_addr)[1] = (*buff_addr)[2] = (*buff_addr)[3] = 0;
-    } else {
-        if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) {
-            e1000e_read_ps_rx_descr(core, desc, buff_addr);
-        } else {
-            e1000e_read_ext_rx_descr(core, desc, &(*buff_addr)[0]);
-            (*buff_addr)[1] = (*buff_addr)[2] = (*buff_addr)[3] = 0;
-        }
-    }
-}
-
-static void
-e1000e_verify_csum_in_sw(E1000ECore *core,
-                         struct NetRxPkt *pkt,
-                         uint32_t *status_flags,
-                         bool istcp, bool isudp)
-{
-    bool csum_valid;
-    uint32_t csum_error;
-
-    if (e1000e_rx_l3_cso_enabled(core)) {
-        if (!net_rx_pkt_validate_l3_csum(pkt, &csum_valid)) {
-            trace_e1000e_rx_metadata_l3_csum_validation_failed();
-        } else {
-            csum_error = csum_valid ? 0 : E1000_RXDEXT_STATERR_IPE;
-            *status_flags |= E1000_RXD_STAT_IPCS | csum_error;
-        }
-    } else {
-        trace_e1000e_rx_metadata_l3_cso_disabled();
-    }
-
-    if (!e1000e_rx_l4_cso_enabled(core)) {
-        trace_e1000e_rx_metadata_l4_cso_disabled();
-        return;
-    }
-
-    if (!net_rx_pkt_validate_l4_csum(pkt, &csum_valid)) {
-        trace_e1000e_rx_metadata_l4_csum_validation_failed();
-        return;
-    }
-
-    csum_error = csum_valid ? 0 : E1000_RXDEXT_STATERR_TCPE;
-
-    if (istcp) {
-        *status_flags |= E1000_RXD_STAT_TCPCS |
-                         csum_error;
-    } else if (isudp) {
-        *status_flags |= E1000_RXD_STAT_TCPCS |
-                         E1000_RXD_STAT_UDPCS |
-                         csum_error;
-    }
-}
-
-static inline bool
-e1000e_is_tcp_ack(E1000ECore *core, struct NetRxPkt *rx_pkt)
-{
-    if (!net_rx_pkt_is_tcp_ack(rx_pkt)) {
-        return false;
-    }
-
-    if (core->mac[RFCTL] & E1000_RFCTL_ACK_DATA_DIS) {
-        return !net_rx_pkt_has_tcp_data(rx_pkt);
-    }
-
-    return true;
-}
-
-static void
-e1000e_build_rx_metadata(E1000ECore *core,
-                         struct NetRxPkt *pkt,
-                         bool is_eop,
-                         const E1000E_RSSInfo *rss_info,
-                         uint32_t *rss, uint32_t *mrq,
-                         uint32_t *status_flags,
-                         uint16_t *ip_id,
-                         uint16_t *vlan_tag)
-{
-    struct virtio_net_hdr *vhdr;
-    bool isip4, isip6, istcp, isudp;
-    uint32_t pkt_type;
-
-    *status_flags = E1000_RXD_STAT_DD;
-
-    /* No additional metadata needed for non-EOP descriptors */
-    if (!is_eop) {
-        goto func_exit;
-    }
-
-    *status_flags |= E1000_RXD_STAT_EOP;
-
-    net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
-    trace_e1000e_rx_metadata_protocols(isip4, isip6, isudp, istcp);
-
-    /* VLAN state */
-    if (net_rx_pkt_is_vlan_stripped(pkt)) {
-        *status_flags |= E1000_RXD_STAT_VP;
-        *vlan_tag = cpu_to_le16(net_rx_pkt_get_vlan_tag(pkt));
-        trace_e1000e_rx_metadata_vlan(*vlan_tag);
-    }
-
-    /* Packet parsing results */
-    if ((core->mac[RXCSUM] & E1000_RXCSUM_PCSD) != 0) {
-        if (rss_info->enabled) {
-            *rss = cpu_to_le32(rss_info->hash);
-            *mrq = cpu_to_le32(rss_info->type | (rss_info->queue << 8));
-            trace_e1000e_rx_metadata_rss(*rss, *mrq);
-        }
-    } else if (isip4) {
-            *status_flags |= E1000_RXD_STAT_IPIDV;
-            *ip_id = cpu_to_le16(net_rx_pkt_get_ip_id(pkt));
-            trace_e1000e_rx_metadata_ip_id(*ip_id);
-    }
-
-    if (istcp && e1000e_is_tcp_ack(core, pkt)) {
-        *status_flags |= E1000_RXD_STAT_ACK;
-        trace_e1000e_rx_metadata_ack();
-    }
-
-    if (isip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_DIS)) {
-        trace_e1000e_rx_metadata_ipv6_filtering_disabled();
-        pkt_type = E1000_RXD_PKT_MAC;
-    } else if (istcp || isudp) {
-        pkt_type = isip4 ? E1000_RXD_PKT_IP4_XDP : E1000_RXD_PKT_IP6_XDP;
-    } else if (isip4 || isip6) {
-        pkt_type = isip4 ? E1000_RXD_PKT_IP4 : E1000_RXD_PKT_IP6;
-    } else {
-        pkt_type = E1000_RXD_PKT_MAC;
-    }
-
-    *status_flags |= E1000_RXD_PKT_TYPE(pkt_type);
-    trace_e1000e_rx_metadata_pkt_type(pkt_type);
-
-    /* RX CSO information */
-    if (isip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_XSUM_DIS)) {
-        trace_e1000e_rx_metadata_ipv6_sum_disabled();
-        goto func_exit;
-    }
-
-    if (!net_rx_pkt_has_virt_hdr(pkt)) {
-        trace_e1000e_rx_metadata_no_virthdr();
-        e1000e_verify_csum_in_sw(core, pkt, status_flags, istcp, isudp);
-        goto func_exit;
-    }
-
-    vhdr = net_rx_pkt_get_vhdr(pkt);
-
-    if (!(vhdr->flags & VIRTIO_NET_HDR_F_DATA_VALID) &&
-        !(vhdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM)) {
-        trace_e1000e_rx_metadata_virthdr_no_csum_info();
-        e1000e_verify_csum_in_sw(core, pkt, status_flags, istcp, isudp);
-        goto func_exit;
-    }
-
-    if (e1000e_rx_l3_cso_enabled(core)) {
-        *status_flags |= isip4 ? E1000_RXD_STAT_IPCS : 0;
-    } else {
-        trace_e1000e_rx_metadata_l3_cso_disabled();
-    }
-
-    if (e1000e_rx_l4_cso_enabled(core)) {
-        if (istcp) {
-            *status_flags |= E1000_RXD_STAT_TCPCS;
-        } else if (isudp) {
-            *status_flags |= E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS;
-        }
-    } else {
-        trace_e1000e_rx_metadata_l4_cso_disabled();
-    }
-
-    trace_e1000e_rx_metadata_status_flags(*status_flags);
-
-func_exit:
-    *status_flags = cpu_to_le32(*status_flags);
-}
-
-static inline void
-e1000e_write_lgcy_rx_descr(E1000ECore *core, uint8_t *desc,
-                           struct NetRxPkt *pkt,
-                           const E1000E_RSSInfo *rss_info,
-                           uint16_t length)
-{
-    uint32_t status_flags, rss, mrq;
-    uint16_t ip_id;
-
-    struct e1000_rx_desc *d = (struct e1000_rx_desc *) desc;
-
-    memset(d, 0, sizeof(*d));
-
-    assert(!rss_info->enabled);
-
-    d->length = cpu_to_le16(length);
-
-    e1000e_build_rx_metadata(core, pkt, pkt != NULL,
-                             rss_info,
-                             &rss, &mrq,
-                             &status_flags, &ip_id,
-                             &d->special);
-    d->errors = (uint8_t) (le32_to_cpu(status_flags) >> 24);
-    d->status = (uint8_t) le32_to_cpu(status_flags);
-}
-
-static inline void
-e1000e_write_ext_rx_descr(E1000ECore *core, uint8_t *desc,
-                          struct NetRxPkt *pkt,
-                          const E1000E_RSSInfo *rss_info,
-                          uint16_t length)
-{
-    union e1000_rx_desc_extended *d = (union e1000_rx_desc_extended *) desc;
-
-    memset(d, 0, sizeof(*d));
-
-    d->wb.upper.length = cpu_to_le16(length);
-
-    e1000e_build_rx_metadata(core, pkt, pkt != NULL,
-                             rss_info,
-                             &d->wb.lower.hi_dword.rss,
-                             &d->wb.lower.mrq,
-                             &d->wb.upper.status_error,
-                             &d->wb.lower.hi_dword.csum_ip.ip_id,
-                             &d->wb.upper.vlan);
-}
-
-static inline void
-e1000e_write_ps_rx_descr(E1000ECore *core, uint8_t *desc,
-                         struct NetRxPkt *pkt,
-                         const E1000E_RSSInfo *rss_info,
-                         size_t ps_hdr_len,
-                         uint16_t(*written)[MAX_PS_BUFFERS])
-{
-    int i;
-    union e1000_rx_desc_packet_split *d =
-        (union e1000_rx_desc_packet_split *) desc;
-
-    memset(d, 0, sizeof(*d));
-
-    d->wb.middle.length0 = cpu_to_le16((*written)[0]);
-
-    for (i = 0; i < PS_PAGE_BUFFERS; i++) {
-        d->wb.upper.length[i] = cpu_to_le16((*written)[i + 1]);
-    }
-
-    e1000e_build_rx_metadata(core, pkt, pkt != NULL,
-                             rss_info,
-                             &d->wb.lower.hi_dword.rss,
-                             &d->wb.lower.mrq,
-                             &d->wb.middle.status_error,
-                             &d->wb.lower.hi_dword.csum_ip.ip_id,
-                             &d->wb.middle.vlan);
-
-    d->wb.upper.header_status =
-        cpu_to_le16(ps_hdr_len | (ps_hdr_len ? E1000_RXDPS_HDRSTAT_HDRSP : 0));
-
-    trace_e1000e_rx_desc_ps_write((*written)[0], (*written)[1],
-                                  (*written)[2], (*written)[3]);
-}
-
-static inline void
-e1000e_write_rx_descr(E1000ECore *core, uint8_t *desc,
-struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info,
-    size_t ps_hdr_len, uint16_t(*written)[MAX_PS_BUFFERS])
-{
-    if (e1000e_rx_use_legacy_descriptor(core)) {
-        assert(ps_hdr_len == 0);
-        e1000e_write_lgcy_rx_descr(core, desc, pkt, rss_info, (*written)[0]);
-    } else {
-        if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) {
-            e1000e_write_ps_rx_descr(core, desc, pkt, rss_info,
-                                      ps_hdr_len, written);
-        } else {
-            assert(ps_hdr_len == 0);
-            e1000e_write_ext_rx_descr(core, desc, pkt, rss_info,
-                                       (*written)[0]);
-        }
-    }
-}
-
-typedef struct e1000e_ba_state_st {
-    uint16_t written[MAX_PS_BUFFERS];
-    uint8_t cur_idx;
-} e1000e_ba_state;
-
-static inline void
-e1000e_write_hdr_to_rx_buffers(E1000ECore *core,
-                               hwaddr (*ba)[MAX_PS_BUFFERS],
-                               e1000e_ba_state *bastate,
-                               const char *data,
-                               dma_addr_t data_len)
-{
-    assert(data_len <= core->rxbuf_sizes[0] - bastate->written[0]);
-
-    pci_dma_write(core->owner, (*ba)[0] + bastate->written[0], data, data_len);
-    bastate->written[0] += data_len;
-
-    bastate->cur_idx = 1;
-}
-
-static void
-e1000e_write_to_rx_buffers(E1000ECore *core,
-                           hwaddr (*ba)[MAX_PS_BUFFERS],
-                           e1000e_ba_state *bastate,
-                           const char *data,
-                           dma_addr_t data_len)
-{
-    while (data_len > 0) {
-        uint32_t cur_buf_len = core->rxbuf_sizes[bastate->cur_idx];
-        uint32_t cur_buf_bytes_left = cur_buf_len -
-                                      bastate->written[bastate->cur_idx];
-        uint32_t bytes_to_write = MIN(data_len, cur_buf_bytes_left);
-
-        trace_e1000e_rx_desc_buff_write(bastate->cur_idx,
-                                        (*ba)[bastate->cur_idx],
-                                        bastate->written[bastate->cur_idx],
-                                        data,
-                                        bytes_to_write);
-
-        pci_dma_write(core->owner,
-            (*ba)[bastate->cur_idx] + bastate->written[bastate->cur_idx],
-            data, bytes_to_write);
-
-        bastate->written[bastate->cur_idx] += bytes_to_write;
-        data += bytes_to_write;
-        data_len -= bytes_to_write;
-
-        if (bastate->written[bastate->cur_idx] == cur_buf_len) {
-            bastate->cur_idx++;
-        }
-
-        assert(bastate->cur_idx < MAX_PS_BUFFERS);
-    }
-}
-
-static void
-e1000e_update_rx_stats(E1000ECore *core,
-                       size_t data_size,
-                       size_t data_fcs_size)
-{
-    e1000x_update_rx_total_stats(core->mac, data_size, data_fcs_size);
-
-    switch (net_rx_pkt_get_packet_type(core->rx_pkt)) {
-    case ETH_PKT_BCAST:
-        e1000x_inc_reg_if_not_full(core->mac, BPRC);
-        break;
-
-    case ETH_PKT_MCAST:
-        e1000x_inc_reg_if_not_full(core->mac, MPRC);
-        break;
-
-    default:
-        break;
-    }
-}
-
-static inline bool
-e1000e_rx_descr_threshold_hit(E1000ECore *core, const E1000E_RingInfo *rxi)
-{
-    return e1000e_ring_free_descr_num(core, rxi) ==
-           e1000e_ring_len(core, rxi) >> core->rxbuf_min_shift;
-}
-
-static bool
-e1000e_do_ps(E1000ECore *core, struct NetRxPkt *pkt, size_t *hdr_len)
-{
-    bool isip4, isip6, isudp, istcp;
-    bool fragment;
-
-    if (!e1000e_rx_use_ps_descriptor(core)) {
-        return false;
-    }
-
-    net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
-
-    if (isip4) {
-        fragment = net_rx_pkt_get_ip4_info(pkt)->fragment;
-    } else if (isip6) {
-        fragment = net_rx_pkt_get_ip6_info(pkt)->fragment;
-    } else {
-        return false;
-    }
-
-    if (fragment && (core->mac[RFCTL] & E1000_RFCTL_IPFRSP_DIS)) {
-        return false;
-    }
-
-    if (!fragment && (isudp || istcp)) {
-        *hdr_len = net_rx_pkt_get_l5_hdr_offset(pkt);
-    } else {
-        *hdr_len = net_rx_pkt_get_l4_hdr_offset(pkt);
-    }
-
-    if ((*hdr_len > core->rxbuf_sizes[0]) ||
-        (*hdr_len > net_rx_pkt_get_total_len(pkt))) {
-        return false;
-    }
-
-    return true;
-}
-
-static void
-e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
-                             const E1000E_RxRing *rxr,
-                             const E1000E_RSSInfo *rss_info)
-{
-    PCIDevice *d = core->owner;
-    dma_addr_t base;
-    uint8_t desc[E1000_MAX_RX_DESC_LEN];
-    size_t desc_size;
-    size_t desc_offset = 0;
-    size_t iov_ofs = 0;
-
-    struct iovec *iov = net_rx_pkt_get_iovec(pkt);
-    size_t size = net_rx_pkt_get_total_len(pkt);
-    size_t total_size = size + e1000x_fcs_len(core->mac);
-    const E1000E_RingInfo *rxi;
-    size_t ps_hdr_len = 0;
-    bool do_ps = e1000e_do_ps(core, pkt, &ps_hdr_len);
-
-    rxi = rxr->i;
-
-    do {
-        hwaddr ba[MAX_PS_BUFFERS];
-        e1000e_ba_state bastate = { { 0 } };
-        bool is_last = false;
-        bool is_first = true;
-
-        desc_size = total_size - desc_offset;
-
-        if (desc_size > core->rx_desc_buf_size) {
-            desc_size = core->rx_desc_buf_size;
-        }
-
-        base = e1000e_ring_head_descr(core, rxi);
-
-        pci_dma_read(d, base, &desc, core->rx_desc_len);
-
-        trace_e1000e_rx_descr(rxi->idx, base, core->rx_desc_len);
-
-        e1000e_read_rx_descr(core, desc, &ba);
-
-        if (ba[0]) {
-            if (desc_offset < size) {
-                static const uint32_t fcs_pad;
-                size_t iov_copy;
-                size_t copy_size = size - desc_offset;
-                if (copy_size > core->rx_desc_buf_size) {
-                    copy_size = core->rx_desc_buf_size;
-                }
-
-                /* For PS mode copy the packet header first */
-                if (do_ps) {
-                    if (is_first) {
-                        size_t ps_hdr_copied = 0;
-                        do {
-                            iov_copy = MIN(ps_hdr_len - ps_hdr_copied,
-                                           iov->iov_len - iov_ofs);
-
-                            e1000e_write_hdr_to_rx_buffers(core, &ba, &bastate,
-                                                      iov->iov_base, iov_copy);
-
-                            copy_size -= iov_copy;
-                            ps_hdr_copied += iov_copy;
-
-                            iov_ofs += iov_copy;
-                            if (iov_ofs == iov->iov_len) {
-                                iov++;
-                                iov_ofs = 0;
-                            }
-                        } while (ps_hdr_copied < ps_hdr_len);
-
-                        is_first = false;
-                    } else {
-                        /* Leave buffer 0 of each descriptor except first */
-                        /* empty as per spec 7.1.5.1                      */
-                        e1000e_write_hdr_to_rx_buffers(core, &ba, &bastate,
-                                                       NULL, 0);
-                    }
-                }
-
-                /* Copy packet payload */
-                while (copy_size) {
-                    iov_copy = MIN(copy_size, iov->iov_len - iov_ofs);
-
-                    e1000e_write_to_rx_buffers(core, &ba, &bastate,
-                                            iov->iov_base + iov_ofs, iov_copy);
-
-                    copy_size -= iov_copy;
-                    iov_ofs += iov_copy;
-                    if (iov_ofs == iov->iov_len) {
-                        iov++;
-                        iov_ofs = 0;
-                    }
-                }
-
-                if (desc_offset + desc_size >= total_size) {
-                    /* Simulate FCS checksum presence in the last descriptor */
-                    e1000e_write_to_rx_buffers(core, &ba, &bastate,
-                          (const char *) &fcs_pad, e1000x_fcs_len(core->mac));
-                }
-            }
-            desc_offset += desc_size;
-            if (desc_offset >= total_size) {
-                is_last = true;
-            }
-        } else { /* as per intel docs; skip descriptors with null buf addr */
-            trace_e1000e_rx_null_descriptor();
-        }
-
-        e1000e_write_rx_descr(core, desc, is_last ? core->rx_pkt : NULL,
-                           rss_info, do_ps ? ps_hdr_len : 0, &bastate.written);
-        pci_dma_write(d, base, &desc, core->rx_desc_len);
-
-        e1000e_ring_advance(core, rxi,
-                            core->rx_desc_len / E1000_MIN_RX_DESC_LEN);
-
-    } while (desc_offset < total_size);
-
-    e1000e_update_rx_stats(core, size, total_size);
-}
-
-static inline void
-e1000e_rx_fix_l4_csum(E1000ECore *core, struct NetRxPkt *pkt)
-{
-    if (net_rx_pkt_has_virt_hdr(pkt)) {
-        struct virtio_net_hdr *vhdr = net_rx_pkt_get_vhdr(pkt);
-
-        if (vhdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
-            net_rx_pkt_fix_l4_csum(pkt);
-        }
-    }
-}
-
-ssize_t
-e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt)
-{
-    static const int maximum_ethernet_hdr_len = (14 + 4);
-    /* Min. octets in an ethernet frame sans FCS */
-    static const int min_buf_size = 60;
-
-    uint32_t n = 0;
-    uint8_t min_buf[min_buf_size];
-    struct iovec min_iov;
-    uint8_t *filter_buf;
-    size_t size, orig_size;
-    size_t iov_ofs = 0;
-    E1000E_RxRing rxr;
-    E1000E_RSSInfo rss_info;
-    size_t total_size;
-    ssize_t retval;
-    bool rdmts_hit;
-
-    trace_e1000e_rx_receive_iov(iovcnt);
-
-    if (!e1000x_hw_rx_enabled(core->mac)) {
-        return -1;
-    }
-
-    /* Pull virtio header in */
-    if (core->has_vnet) {
-        net_rx_pkt_set_vhdr_iovec(core->rx_pkt, iov, iovcnt);
-        iov_ofs = sizeof(struct virtio_net_hdr);
-    }
-
-    filter_buf = iov->iov_base + iov_ofs;
-    orig_size = iov_size(iov, iovcnt);
-    size = orig_size - iov_ofs;
-
-    /* Pad to minimum Ethernet frame length */
-    if (size < sizeof(min_buf)) {
-        iov_to_buf(iov, iovcnt, iov_ofs, min_buf, size);
-        memset(&min_buf[size], 0, sizeof(min_buf) - size);
-        e1000x_inc_reg_if_not_full(core->mac, RUC);
-        min_iov.iov_base = filter_buf = min_buf;
-        min_iov.iov_len = size = sizeof(min_buf);
-        iovcnt = 1;
-        iov = &min_iov;
-        iov_ofs = 0;
-    } else if (iov->iov_len < maximum_ethernet_hdr_len) {
-        /* This is very unlikely, but may happen. */
-        iov_to_buf(iov, iovcnt, iov_ofs, min_buf, maximum_ethernet_hdr_len);
-        filter_buf = min_buf;
-    }
-
-    /* Discard oversized packets if !LPE and !SBP. */
-    if (e1000x_is_oversized(core->mac, size)) {
-        return orig_size;
-    }
-
-    net_rx_pkt_set_packet_type(core->rx_pkt,
-        get_eth_packet_type(PKT_GET_ETH_HDR(filter_buf)));
-
-    if (!e1000e_receive_filter(core, filter_buf, size)) {
-        trace_e1000e_rx_flt_dropped();
-        return orig_size;
-    }
-
-    net_rx_pkt_attach_iovec_ex(core->rx_pkt, iov, iovcnt, iov_ofs,
-                               e1000x_vlan_enabled(core->mac), core->vet);
-
-    e1000e_rss_parse_packet(core, core->rx_pkt, &rss_info);
-    e1000e_rx_ring_init(core, &rxr, rss_info.queue);
-
-    trace_e1000e_rx_rss_dispatched_to_queue(rxr.i->idx);
-
-    total_size = net_rx_pkt_get_total_len(core->rx_pkt) +
-        e1000x_fcs_len(core->mac);
-
-    if (e1000e_has_rxbufs(core, rxr.i, total_size)) {
-        e1000e_rx_fix_l4_csum(core, core->rx_pkt);
-
-        e1000e_write_packet_to_guest(core, core->rx_pkt, &rxr, &rss_info);
-
-        retval = orig_size;
-
-        /* Perform small receive detection (RSRPD) */
-        if (total_size < core->mac[RSRPD]) {
-            n |= E1000_ICS_SRPD;
-        }
-
-        /* Perform ACK receive detection */
-        if (e1000e_is_tcp_ack(core, core->rx_pkt)) {
-            n |= E1000_ICS_ACK;
-        }
-
-        /* Check if receive descriptor minimum threshold hit */
-        rdmts_hit = e1000e_rx_descr_threshold_hit(core, rxr.i);
-        n |= e1000e_rx_wb_interrupt_cause(core, rxr.i->idx, rdmts_hit);
-
-        trace_e1000e_rx_written_to_guest(n);
-    } else {
-        n |= E1000_ICS_RXO;
-        retval = 0;
-
-        trace_e1000e_rx_not_written_to_guest(n);
-    }
-
-    if (!e1000e_intrmgr_delay_rx_causes(core, &n)) {
-        trace_e1000e_rx_interrupt_set(n);
-        e1000e_set_interrupt_cause(core, n);
-    } else {
-        trace_e1000e_rx_interrupt_delayed(n);
-    }
-
-    return retval;
-}
-
-static inline bool
-e1000e_have_autoneg(E1000ECore *core)
-{
-    return core->phy[0][PHY_CTRL] & MII_CR_AUTO_NEG_EN;
-}
-
-static void e1000e_update_flowctl_status(E1000ECore *core)
-{
-    if (e1000e_have_autoneg(core) &&
-        core->phy[0][PHY_STATUS] & MII_SR_AUTONEG_COMPLETE) {
-        trace_e1000e_link_autoneg_flowctl(true);
-        core->mac[CTRL] |= E1000_CTRL_TFCE | E1000_CTRL_RFCE;
-    } else {
-        trace_e1000e_link_autoneg_flowctl(false);
-    }
-}
-
-static inline void
-e1000e_link_down(E1000ECore *core)
-{
-    e1000x_update_regs_on_link_down(core->mac, core->phy[0]);
-    e1000e_update_flowctl_status(core);
-}
-
-static inline void
-e1000e_set_phy_ctrl(E1000ECore *core, int index, uint16_t val)
-{
-    /* bits 0-5 reserved; MII_CR_[RESTART_AUTO_NEG,RESET] are self clearing */
-    core->phy[0][PHY_CTRL] = val & ~(0x3f |
-                                     MII_CR_RESET |
-                                     MII_CR_RESTART_AUTO_NEG);
-
-    if ((val & MII_CR_RESTART_AUTO_NEG) &&
-        e1000e_have_autoneg(core)) {
-        e1000x_restart_autoneg(core->mac, core->phy[0], core->autoneg_timer);
-    }
-}
-
-static void
-e1000e_set_phy_oem_bits(E1000ECore *core, int index, uint16_t val)
-{
-    core->phy[0][PHY_OEM_BITS] = val & ~BIT(10);
-
-    if (val & BIT(10)) {
-        e1000x_restart_autoneg(core->mac, core->phy[0], core->autoneg_timer);
-    }
-}
-
-static void
-e1000e_set_phy_page(E1000ECore *core, int index, uint16_t val)
-{
-    core->phy[0][PHY_PAGE] = val & PHY_PAGE_RW_MASK;
-}
-
-void
-e1000e_core_set_link_status(E1000ECore *core)
-{
-    NetClientState *nc = qemu_get_queue(core->owner_nic);
-    uint32_t old_status = core->mac[STATUS];
-
-    trace_e1000e_link_status_changed(nc->link_down ? false : true);
-
-    if (nc->link_down) {
-        e1000x_update_regs_on_link_down(core->mac, core->phy[0]);
-    } else {
-        if (e1000e_have_autoneg(core) &&
-            !(core->phy[0][PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) {
-            e1000x_restart_autoneg(core->mac, core->phy[0],
-                                   core->autoneg_timer);
-        } else {
-            e1000x_update_regs_on_link_up(core->mac, core->phy[0]);
-        }
-    }
-
-    if (core->mac[STATUS] != old_status) {
-        e1000e_set_interrupt_cause(core, E1000_ICR_LSC);
-    }
-}
-
-static void
-e1000e_set_ctrl(E1000ECore *core, int index, uint32_t val)
-{
-    trace_e1000e_core_ctrl_write(index, val);
-
-    /* RST is self clearing */
-    core->mac[CTRL] = val & ~E1000_CTRL_RST;
-    core->mac[CTRL_DUP] = core->mac[CTRL];
-
-    trace_e1000e_link_set_params(
-        !!(val & E1000_CTRL_ASDE),
-        (val & E1000_CTRL_SPD_SEL) >> E1000_CTRL_SPD_SHIFT,
-        !!(val & E1000_CTRL_FRCSPD),
-        !!(val & E1000_CTRL_FRCDPX),
-        !!(val & E1000_CTRL_RFCE),
-        !!(val & E1000_CTRL_TFCE));
-
-    if (val & E1000_CTRL_RST) {
-        trace_e1000e_core_ctrl_sw_reset();
-        e1000x_reset_mac_addr(core->owner_nic, core->mac, core->permanent_mac);
-    }
-
-    if (val & E1000_CTRL_PHY_RST) {
-        trace_e1000e_core_ctrl_phy_reset();
-        core->mac[STATUS] |= E1000_STATUS_PHYRA;
-    }
-}
-
-static void
-e1000e_set_rfctl(E1000ECore *core, int index, uint32_t val)
-{
-    trace_e1000e_rx_set_rfctl(val);
-
-    if (!(val & E1000_RFCTL_ISCSI_DIS)) {
-        trace_e1000e_wrn_iscsi_filtering_not_supported();
-    }
-
-    if (!(val & E1000_RFCTL_NFSW_DIS)) {
-        trace_e1000e_wrn_nfsw_filtering_not_supported();
-    }
-
-    if (!(val & E1000_RFCTL_NFSR_DIS)) {
-        trace_e1000e_wrn_nfsr_filtering_not_supported();
-    }
-
-    core->mac[RFCTL] = val;
-}
-
-static void
-e1000e_calc_per_desc_buf_size(E1000ECore *core)
-{
-    int i;
-    core->rx_desc_buf_size = 0;
-
-    for (i = 0; i < ARRAY_SIZE(core->rxbuf_sizes); i++) {
-        core->rx_desc_buf_size += core->rxbuf_sizes[i];
-    }
-}
-
-static void
-e1000e_parse_rxbufsize(E1000ECore *core)
-{
-    uint32_t rctl = core->mac[RCTL];
-
-    memset(core->rxbuf_sizes, 0, sizeof(core->rxbuf_sizes));
-
-    if (rctl & E1000_RCTL_DTYP_MASK) {
-        uint32_t bsize;
-
-        bsize = core->mac[PSRCTL] & E1000_PSRCTL_BSIZE0_MASK;
-        core->rxbuf_sizes[0] = (bsize >> E1000_PSRCTL_BSIZE0_SHIFT) * 128;
-
-        bsize = core->mac[PSRCTL] & E1000_PSRCTL_BSIZE1_MASK;
-        core->rxbuf_sizes[1] = (bsize >> E1000_PSRCTL_BSIZE1_SHIFT) * 1024;
-
-        bsize = core->mac[PSRCTL] & E1000_PSRCTL_BSIZE2_MASK;
-        core->rxbuf_sizes[2] = (bsize >> E1000_PSRCTL_BSIZE2_SHIFT) * 1024;
-
-        bsize = core->mac[PSRCTL] & E1000_PSRCTL_BSIZE3_MASK;
-        core->rxbuf_sizes[3] = (bsize >> E1000_PSRCTL_BSIZE3_SHIFT) * 1024;
-    } else if (rctl & E1000_RCTL_FLXBUF_MASK) {
-        int flxbuf = rctl & E1000_RCTL_FLXBUF_MASK;
-        core->rxbuf_sizes[0] = (flxbuf >> E1000_RCTL_FLXBUF_SHIFT) * 1024;
-    } else {
-        core->rxbuf_sizes[0] = e1000x_rxbufsize(rctl);
-    }
-
-    trace_e1000e_rx_desc_buff_sizes(core->rxbuf_sizes[0], core->rxbuf_sizes[1],
-                                    core->rxbuf_sizes[2], core->rxbuf_sizes[3]);
-
-    e1000e_calc_per_desc_buf_size(core);
-}
-
-static void
-e1000e_calc_rxdesclen(E1000ECore *core)
-{
-    if (e1000e_rx_use_legacy_descriptor(core)) {
-        core->rx_desc_len = sizeof(struct e1000_rx_desc);
-    } else {
-        if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) {
-            core->rx_desc_len = sizeof(union e1000_rx_desc_packet_split);
-        } else {
-            core->rx_desc_len = sizeof(union e1000_rx_desc_extended);
-        }
-    }
-    trace_e1000e_rx_desc_len(core->rx_desc_len);
-}
-
-static void
-e1000e_set_rx_control(E1000ECore *core, int index, uint32_t val)
-{
-    core->mac[RCTL] = val;
-    trace_e1000e_rx_set_rctl(core->mac[RCTL]);
-
-    if (val & E1000_RCTL_EN) {
-        e1000e_parse_rxbufsize(core);
-        e1000e_calc_rxdesclen(core);
-        core->rxbuf_min_shift = ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1 +
-                                E1000_RING_DESC_LEN_SHIFT;
-
-        e1000e_start_recv(core);
-    }
-}
-
-static
-void(*e1000e_phyreg_writeops[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE])
-(E1000ECore *, int, uint16_t) = {
-    [0] = {
-        [PHY_CTRL]     = e1000e_set_phy_ctrl,
-        [PHY_PAGE]     = e1000e_set_phy_page,
-        [PHY_OEM_BITS] = e1000e_set_phy_oem_bits
-    }
-};
-
-static inline void
-e1000e_clear_ims_bits(E1000ECore *core, uint32_t bits)
-{
-    trace_e1000e_irq_clear_ims(bits, core->mac[IMS], core->mac[IMS] & ~bits);
-    core->mac[IMS] &= ~bits;
-}
-
-static inline bool
-e1000e_postpone_interrupt(bool *interrupt_pending,
-                           E1000IntrDelayTimer *timer)
-{
-    if (timer->running) {
-        trace_e1000e_irq_postponed_by_xitr(timer->delay_reg << 2);
-
-        *interrupt_pending = true;
-        return true;
-    }
-
-    if (timer->core->mac[timer->delay_reg] != 0) {
-        e1000e_intrmgr_rearm_timer(timer);
-    }
-
-    return false;
-}
-
-static inline bool
-e1000e_itr_should_postpone(E1000ECore *core)
-{
-    return e1000e_postpone_interrupt(&core->itr_intr_pending, &core->itr);
-}
-
-static inline bool
-e1000e_eitr_should_postpone(E1000ECore *core, int idx)
-{
-    return e1000e_postpone_interrupt(&core->eitr_intr_pending[idx],
-                                     &core->eitr[idx]);
-}
-
-static void
-e1000e_msix_notify_one(E1000ECore *core, uint32_t cause, uint32_t int_cfg)
-{
-    uint32_t effective_eiac;
-
-    if (E1000_IVAR_ENTRY_VALID(int_cfg)) {
-        uint32_t vec = E1000_IVAR_ENTRY_VEC(int_cfg);
-        if (vec < E1000E_MSIX_VEC_NUM) {
-            if (!e1000e_eitr_should_postpone(core, vec)) {
-                trace_e1000e_irq_msix_notify_vec(vec);
-                msix_notify(core->owner, vec);
-            }
-        } else {
-            trace_e1000e_wrn_msix_vec_wrong(cause, int_cfg);
-        }
-    } else {
-        trace_e1000e_wrn_msix_invalid(cause, int_cfg);
-    }
-
-    if (core->mac[CTRL_EXT] & E1000_CTRL_EXT_EIAME) {
-        trace_e1000e_irq_ims_clear_eiame(core->mac[IAM], cause);
-        e1000e_clear_ims_bits(core, core->mac[IAM] & cause);
-    }
-
-    trace_e1000e_irq_icr_clear_eiac(core->mac[ICR], core->mac[EIAC]);
-
-    if (core->mac[EIAC] & E1000_ICR_OTHER) {
-        effective_eiac = (core->mac[EIAC] & E1000_EIAC_MASK) |
-                         E1000_ICR_OTHER_CAUSES;
-    } else {
-        effective_eiac = core->mac[EIAC] & E1000_EIAC_MASK;
-    }
-    core->mac[ICR] &= ~effective_eiac;
-}
-
-static void
-e1000e_msix_notify(E1000ECore *core, uint32_t causes)
-{
-    if (causes & E1000_ICR_RXQ0) {
-        e1000e_msix_notify_one(core, E1000_ICR_RXQ0,
-                               E1000_IVAR_RXQ0(core->mac[IVAR]));
-    }
-
-    if (causes & E1000_ICR_RXQ1) {
-        e1000e_msix_notify_one(core, E1000_ICR_RXQ1,
-                               E1000_IVAR_RXQ1(core->mac[IVAR]));
-    }
-
-    if (causes & E1000_ICR_TXQ0) {
-        e1000e_msix_notify_one(core, E1000_ICR_TXQ0,
-                               E1000_IVAR_TXQ0(core->mac[IVAR]));
-    }
-
-    if (causes & E1000_ICR_TXQ1) {
-        e1000e_msix_notify_one(core, E1000_ICR_TXQ1,
-                               E1000_IVAR_TXQ1(core->mac[IVAR]));
-    }
-
-    if (causes & E1000_ICR_OTHER) {
-        e1000e_msix_notify_one(core, E1000_ICR_OTHER,
-                               E1000_IVAR_OTHER(core->mac[IVAR]));
-    }
-}
-
-static void
-e1000e_msix_clear_one(E1000ECore *core, uint32_t cause, uint32_t int_cfg)
-{
-    if (E1000_IVAR_ENTRY_VALID(int_cfg)) {
-        uint32_t vec = E1000_IVAR_ENTRY_VEC(int_cfg);
-        if (vec < E1000E_MSIX_VEC_NUM) {
-            trace_e1000e_irq_msix_pending_clearing(cause, int_cfg, vec);
-            msix_clr_pending(core->owner, vec);
-        } else {
-            trace_e1000e_wrn_msix_vec_wrong(cause, int_cfg);
-        }
-    } else {
-        trace_e1000e_wrn_msix_invalid(cause, int_cfg);
-    }
-}
-
-static void
-e1000e_msix_clear(E1000ECore *core, uint32_t causes)
-{
-    if (causes & E1000_ICR_RXQ0) {
-        e1000e_msix_clear_one(core, E1000_ICR_RXQ0,
-                              E1000_IVAR_RXQ0(core->mac[IVAR]));
-    }
-
-    if (causes & E1000_ICR_RXQ1) {
-        e1000e_msix_clear_one(core, E1000_ICR_RXQ1,
-                              E1000_IVAR_RXQ1(core->mac[IVAR]));
-    }
-
-    if (causes & E1000_ICR_TXQ0) {
-        e1000e_msix_clear_one(core, E1000_ICR_TXQ0,
-                              E1000_IVAR_TXQ0(core->mac[IVAR]));
-    }
-
-    if (causes & E1000_ICR_TXQ1) {
-        e1000e_msix_clear_one(core, E1000_ICR_TXQ1,
-                              E1000_IVAR_TXQ1(core->mac[IVAR]));
-    }
-
-    if (causes & E1000_ICR_OTHER) {
-        e1000e_msix_clear_one(core, E1000_ICR_OTHER,
-                              E1000_IVAR_OTHER(core->mac[IVAR]));
-    }
-}
-
-static inline void
-e1000e_fix_icr_asserted(E1000ECore *core)
-{
-    core->mac[ICR] &= ~E1000_ICR_ASSERTED;
-    if (core->mac[ICR]) {
-        core->mac[ICR] |= E1000_ICR_ASSERTED;
-    }
-
-    trace_e1000e_irq_fix_icr_asserted(core->mac[ICR]);
-}
-
-static void
-e1000e_send_msi(E1000ECore *core, bool msix)
-{
-    uint32_t causes = core->mac[ICR] & core->mac[IMS] & ~E1000_ICR_ASSERTED;
-
-    if (msix) {
-        e1000e_msix_notify(core, causes);
-    } else {
-        if (!e1000e_itr_should_postpone(core)) {
-            trace_e1000e_irq_msi_notify(causes);
-            msi_notify(core->owner, 0);
-        }
-    }
-}
-
-static void
-e1000e_update_interrupt_state(E1000ECore *core)
-{
-    bool interrupts_pending;
-    bool is_msix = msix_enabled(core->owner);
-
-    /* Set ICR[OTHER] for MSI-X */
-    if (is_msix) {
-        if (core->mac[ICR] & core->mac[IMS] & E1000_ICR_OTHER_CAUSES) {
-            core->mac[ICR] |= E1000_ICR_OTHER;
-            trace_e1000e_irq_add_msi_other(core->mac[ICR]);
-        }
-    }
-
-    e1000e_fix_icr_asserted(core);
-
-    /*
-     * Make sure ICR and ICS registers have the same value.
-     * The spec says that the ICS register is write-only.  However in practice,
-     * on real hardware ICS is readable, and for reads it has the same value as
-     * ICR (except that ICS does not have the clear on read behaviour of ICR).
-     *
-     * The VxWorks PRO/1000 driver uses this behaviour.
-     */
-    core->mac[ICS] = core->mac[ICR];
-
-    interrupts_pending = (core->mac[IMS] & core->mac[ICR]) ? true : false;
-
-    trace_e1000e_irq_pending_interrupts(core->mac[ICR] & core->mac[IMS],
-                                        core->mac[ICR], core->mac[IMS]);
-
-    if (is_msix || msi_enabled(core->owner)) {
-        if (interrupts_pending) {
-            e1000e_send_msi(core, is_msix);
-        }
-    } else {
-        if (interrupts_pending) {
-            if (!e1000e_itr_should_postpone(core)) {
-                e1000e_raise_legacy_irq(core);
-            }
-        } else {
-            e1000e_lower_legacy_irq(core);
-        }
-    }
-}
-
-static inline void
-e1000e_set_interrupt_cause(E1000ECore *core, uint32_t val)
-{
-    trace_e1000e_irq_set_cause_entry(val, core->mac[ICR]);
-
-    val |= e1000e_intmgr_collect_delayed_causes(core);
-    core->mac[ICR] |= val;
-
-    trace_e1000e_irq_set_cause_exit(val, core->mac[ICR]);
-
-    e1000e_update_interrupt_state(core);
-}
-
-static inline void
-e1000e_autoneg_timer(void *opaque)
-{
-    E1000ECore *core = opaque;
-    if (!qemu_get_queue(core->owner_nic)->link_down) {
-        e1000x_update_regs_on_autoneg_done(core->mac, core->phy[0]);
-        e1000e_update_flowctl_status(core);
-        /* signal link status change to the guest */
-        e1000e_set_interrupt_cause(core, E1000_ICR_LSC);
-    }
-}
-
-static inline uint16_t
-e1000e_get_reg_index_with_offset(const uint16_t *mac_reg_access, hwaddr addr)
-{
-    uint16_t index = (addr & 0x1ffff) >> 2;
-    return index + (mac_reg_access[index] & 0xfffe);
-}
-
-static const char e1000e_phy_regcap[E1000E_PHY_PAGES][0x20] = {
-    [0] = {
-        [PHY_CTRL]          = PHY_ANYPAGE | PHY_RW,
-        [PHY_STATUS]        = PHY_ANYPAGE | PHY_R,
-        [PHY_ID1]           = PHY_ANYPAGE | PHY_R,
-        [PHY_ID2]           = PHY_ANYPAGE | PHY_R,
-        [PHY_AUTONEG_ADV]   = PHY_ANYPAGE | PHY_RW,
-        [PHY_LP_ABILITY]    = PHY_ANYPAGE | PHY_R,
-        [PHY_AUTONEG_EXP]   = PHY_ANYPAGE | PHY_R,
-        [PHY_NEXT_PAGE_TX]  = PHY_ANYPAGE | PHY_RW,
-        [PHY_LP_NEXT_PAGE]  = PHY_ANYPAGE | PHY_R,
-        [PHY_1000T_CTRL]    = PHY_ANYPAGE | PHY_RW,
-        [PHY_1000T_STATUS]  = PHY_ANYPAGE | PHY_R,
-        [PHY_EXT_STATUS]    = PHY_ANYPAGE | PHY_R,
-        [PHY_PAGE]          = PHY_ANYPAGE | PHY_RW,
-
-        [PHY_COPPER_CTRL1]      = PHY_RW,
-        [PHY_COPPER_STAT1]      = PHY_R,
-        [PHY_COPPER_CTRL3]      = PHY_RW,
-        [PHY_RX_ERR_CNTR]       = PHY_R,
-        [PHY_OEM_BITS]          = PHY_RW,
-        [PHY_BIAS_1]            = PHY_RW,
-        [PHY_BIAS_2]            = PHY_RW,
-        [PHY_COPPER_INT_ENABLE] = PHY_RW,
-        [PHY_COPPER_STAT2]      = PHY_R,
-        [PHY_COPPER_CTRL2]      = PHY_RW
-    },
-    [2] = {
-        [PHY_MAC_CTRL1]         = PHY_RW,
-        [PHY_MAC_INT_ENABLE]    = PHY_RW,
-        [PHY_MAC_STAT]          = PHY_R,
-        [PHY_MAC_CTRL2]         = PHY_RW
-    },
-    [3] = {
-        [PHY_LED_03_FUNC_CTRL1] = PHY_RW,
-        [PHY_LED_03_POL_CTRL]   = PHY_RW,
-        [PHY_LED_TIMER_CTRL]    = PHY_RW,
-        [PHY_LED_45_CTRL]       = PHY_RW
-    },
-    [5] = {
-        [PHY_1000T_SKEW]        = PHY_R,
-        [PHY_1000T_SWAP]        = PHY_R
-    },
-    [6] = {
-        [PHY_CRC_COUNTERS]      = PHY_R
-    }
-};
-
-static bool
-e1000e_phy_reg_check_cap(E1000ECore *core, uint32_t addr,
-                         char cap, uint8_t *page)
-{
-    *page =
-        (e1000e_phy_regcap[0][addr] & PHY_ANYPAGE) ? 0
-                                                    : core->phy[0][PHY_PAGE];
-
-    if (*page >= E1000E_PHY_PAGES) {
-        return false;
-    }
-
-    return e1000e_phy_regcap[*page][addr] & cap;
-}
-
-static void
-e1000e_phy_reg_write(E1000ECore *core, uint8_t page,
-                     uint32_t addr, uint16_t data)
-{
-    assert(page < E1000E_PHY_PAGES);
-    assert(addr < E1000E_PHY_PAGE_SIZE);
-
-    if (e1000e_phyreg_writeops[page][addr]) {
-        e1000e_phyreg_writeops[page][addr](core, addr, data);
-    } else {
-        core->phy[page][addr] = data;
-    }
-}
-
-static void
-e1000e_set_mdic(E1000ECore *core, int index, uint32_t val)
-{
-    uint32_t data = val & E1000_MDIC_DATA_MASK;
-    uint32_t addr = ((val & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
-    uint8_t page;
-
-    if ((val & E1000_MDIC_PHY_MASK) >> E1000_MDIC_PHY_SHIFT != 1) { /* phy # */
-        val = core->mac[MDIC] | E1000_MDIC_ERROR;
-    } else if (val & E1000_MDIC_OP_READ) {
-        if (!e1000e_phy_reg_check_cap(core, addr, PHY_R, &page)) {
-            trace_e1000e_core_mdic_read_unhandled(page, addr);
-            val |= E1000_MDIC_ERROR;
-        } else {
-            val = (val ^ data) | core->phy[page][addr];
-            trace_e1000e_core_mdic_read(page, addr, val);
-        }
-    } else if (val & E1000_MDIC_OP_WRITE) {
-        if (!e1000e_phy_reg_check_cap(core, addr, PHY_W, &page)) {
-            trace_e1000e_core_mdic_write_unhandled(page, addr);
-            val |= E1000_MDIC_ERROR;
-        } else {
-            trace_e1000e_core_mdic_write(page, addr, data);
-            e1000e_phy_reg_write(core, page, addr, data);
-        }
-    }
-    core->mac[MDIC] = val | E1000_MDIC_READY;
-
-    if (val & E1000_MDIC_INT_EN) {
-        e1000e_set_interrupt_cause(core, E1000_ICR_MDAC);
-    }
-}
-
-static void
-e1000e_set_rdt(E1000ECore *core, int index, uint32_t val)
-{
-    core->mac[index] = val & 0xffff;
-    trace_e1000e_rx_set_rdt(e1000e_mq_queue_idx(RDT0, index), val);
-    e1000e_start_recv(core);
-}
-
-static void
-e1000e_set_status(E1000ECore *core, int index, uint32_t val)
-{
-    if ((val & E1000_STATUS_PHYRA) == 0) {
-        core->mac[index] &= ~E1000_STATUS_PHYRA;
-    }
-}
-
-static void
-e1000e_set_ctrlext(E1000ECore *core, int index, uint32_t val)
-{
-    trace_e1000e_link_set_ext_params(!!(val & E1000_CTRL_EXT_ASDCHK),
-                                     !!(val & E1000_CTRL_EXT_SPD_BYPS));
-
-    /* Zero self-clearing bits */
-    val &= ~(E1000_CTRL_EXT_ASDCHK | E1000_CTRL_EXT_EE_RST);
-    core->mac[CTRL_EXT] = val;
-}
-
-static void
-e1000e_set_pbaclr(E1000ECore *core, int index, uint32_t val)
-{
-    int i;
-
-    core->mac[PBACLR] = val & E1000_PBACLR_VALID_MASK;
-
-    if (msix_enabled(core->owner)) {
-        return;
-    }
-
-    for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) {
-        if (core->mac[PBACLR] & BIT(i)) {
-            msix_clr_pending(core->owner, i);
-        }
-    }
-}
-
-static void
-e1000e_set_fcrth(E1000ECore *core, int index, uint32_t val)
-{
-    core->mac[FCRTH] = val & 0xFFF8;
-}
-
-static void
-e1000e_set_fcrtl(E1000ECore *core, int index, uint32_t val)
-{
-    core->mac[FCRTL] = val & 0x8000FFF8;
-}
-
-static inline void
-e1000e_set_16bit(E1000ECore *core, int index, uint32_t val)
-{
-    core->mac[index] = val & 0xffff;
-}
-
-static void
-e1000e_set_12bit(E1000ECore *core, int index, uint32_t val)
-{
-    core->mac[index] = val & 0xfff;
-}
-
-static void
-e1000e_set_vet(E1000ECore *core, int index, uint32_t val)
-{
-    core->mac[VET] = val & 0xffff;
-    core->vet = le16_to_cpu(core->mac[VET]);
-    trace_e1000e_vlan_vet(core->vet);
-}
-
-static void
-e1000e_set_dlen(E1000ECore *core, int index, uint32_t val)
-{
-    core->mac[index] = val & E1000_XDLEN_MASK;
-}
-
-static void
-e1000e_set_dbal(E1000ECore *core, int index, uint32_t val)
-{
-    core->mac[index] = val & E1000_XDBAL_MASK;
-}
-
-static void
-e1000e_set_tctl(E1000ECore *core, int index, uint32_t val)
-{
-    E1000E_TxRing txr;
-    core->mac[index] = val;
-
-    if (core->mac[TARC0] & E1000_TARC_ENABLE) {
-        e1000e_tx_ring_init(core, &txr, 0);
-        e1000e_start_xmit(core, &txr);
-    }
-
-    if (core->mac[TARC1] & E1000_TARC_ENABLE) {
-        e1000e_tx_ring_init(core, &txr, 1);
-        e1000e_start_xmit(core, &txr);
-    }
-}
-
-static void
-e1000e_set_tdt(E1000ECore *core, int index, uint32_t val)
-{
-    E1000E_TxRing txr;
-    int qidx = e1000e_mq_queue_idx(TDT, index);
-    uint32_t tarc_reg = (qidx == 0) ? TARC0 : TARC1;
-
-    core->mac[index] = val & 0xffff;
-
-    if (core->mac[tarc_reg] & E1000_TARC_ENABLE) {
-        e1000e_tx_ring_init(core, &txr, qidx);
-        e1000e_start_xmit(core, &txr);
-    }
-}
-
-static void
-e1000e_set_ics(E1000ECore *core, int index, uint32_t val)
-{
-    trace_e1000e_irq_write_ics(val);
-    e1000e_set_interrupt_cause(core, val);
-}
-
-static void
-e1000e_set_icr(E1000ECore *core, int index, uint32_t val)
-{
-    if ((core->mac[ICR] & E1000_ICR_ASSERTED) &&
-        (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) {
-        trace_e1000e_irq_icr_process_iame();
-        e1000e_clear_ims_bits(core, core->mac[IAM]);
-    }
-
-    trace_e1000e_irq_icr_write(val, core->mac[ICR], core->mac[ICR] & ~val);
-    core->mac[ICR] &= ~val;
-    e1000e_update_interrupt_state(core);
-}
-
-static void
-e1000e_set_imc(E1000ECore *core, int index, uint32_t val)
-{
-    trace_e1000e_irq_ims_clear_set_imc(val);
-    e1000e_clear_ims_bits(core, val);
-    e1000e_update_interrupt_state(core);
-}
-
-static void
-e1000e_set_ims(E1000ECore *core, int index, uint32_t val)
-{
-    static const uint32_t ims_ext_mask =
-        E1000_IMS_RXQ0 | E1000_IMS_RXQ1 |
-        E1000_IMS_TXQ0 | E1000_IMS_TXQ1 |
-        E1000_IMS_OTHER;
-
-    static const uint32_t ims_valid_mask =
-        E1000_IMS_TXDW      | E1000_IMS_TXQE    | E1000_IMS_LSC  |
-        E1000_IMS_RXDMT0    | E1000_IMS_RXO     | E1000_IMS_RXT0 |
-        E1000_IMS_MDAC      | E1000_IMS_TXD_LOW | E1000_IMS_SRPD |
-        E1000_IMS_ACK       | E1000_IMS_MNG     | E1000_IMS_RXQ0 |
-        E1000_IMS_RXQ1      | E1000_IMS_TXQ0    | E1000_IMS_TXQ1 |
-        E1000_IMS_OTHER;
-
-    uint32_t valid_val = val & ims_valid_mask;
-
-    trace_e1000e_irq_set_ims(val, core->mac[IMS], core->mac[IMS] | valid_val);
-    core->mac[IMS] |= valid_val;
-
-    if ((valid_val & ims_ext_mask) &&
-        (core->mac[CTRL_EXT] & E1000_CTRL_EXT_PBA_CLR) &&
-        msix_enabled(core->owner)) {
-        e1000e_msix_clear(core, valid_val);
-    }
-
-    if ((valid_val == ims_valid_mask) &&
-        (core->mac[CTRL_EXT] & E1000_CTRL_EXT_INT_TIMERS_CLEAR_ENA)) {
-        trace_e1000e_irq_fire_all_timers(val);
-        e1000e_intrmgr_fire_all_timers(core);
-    }
-
-    e1000e_update_interrupt_state(core);
-}
-
-static void
-e1000e_set_rdtr(E1000ECore *core, int index, uint32_t val)
-{
-    e1000e_set_16bit(core, index, val);
-
-    if ((val & E1000_RDTR_FPD) && (core->rdtr.running)) {
-        trace_e1000e_irq_rdtr_fpd_running();
-        e1000e_intrmgr_fire_delayed_interrupts(core);
-    } else {
-        trace_e1000e_irq_rdtr_fpd_not_running();
-    }
-}
-
-static void
-e1000e_set_tidv(E1000ECore *core, int index, uint32_t val)
-{
-    e1000e_set_16bit(core, index, val);
-
-    if ((val & E1000_TIDV_FPD) && (core->tidv.running)) {
-        trace_e1000e_irq_tidv_fpd_running();
-        e1000e_intrmgr_fire_delayed_interrupts(core);
-    } else {
-        trace_e1000e_irq_tidv_fpd_not_running();
-    }
-}
-
-static uint32_t
-e1000e_mac_readreg(E1000ECore *core, int index)
-{
-    return core->mac[index];
-}
-
-static uint32_t
-e1000e_mac_ics_read(E1000ECore *core, int index)
-{
-    trace_e1000e_irq_read_ics(core->mac[ICS]);
-    return core->mac[ICS];
-}
-
-static uint32_t
-e1000e_mac_ims_read(E1000ECore *core, int index)
-{
-    trace_e1000e_irq_read_ims(core->mac[IMS]);
-    return core->mac[IMS];
-}
-
-#define E1000E_LOW_BITS_READ_FUNC(num)                      \
-    static uint32_t                                         \
-    e1000e_mac_low##num##_read(E1000ECore *core, int index) \
-    {                                                       \
-        return core->mac[index] & (BIT(num) - 1);           \
-    }                                                       \
-
-#define E1000E_LOW_BITS_READ(num)                           \
-    e1000e_mac_low##num##_read
-
-E1000E_LOW_BITS_READ_FUNC(4);
-E1000E_LOW_BITS_READ_FUNC(6);
-E1000E_LOW_BITS_READ_FUNC(11);
-E1000E_LOW_BITS_READ_FUNC(13);
-E1000E_LOW_BITS_READ_FUNC(16);
-
-static uint32_t
-e1000e_mac_swsm_read(E1000ECore *core, int index)
-{
-    uint32_t val = core->mac[SWSM];
-    core->mac[SWSM] = val | 1;
-    return val;
-}
-
-static uint32_t
-e1000e_mac_itr_read(E1000ECore *core, int index)
-{
-    return core->itr_guest_value;
-}
-
-static uint32_t
-e1000e_mac_eitr_read(E1000ECore *core, int index)
-{
-    return core->eitr_guest_value[index - EITR];
-}
-
-static uint32_t
-e1000e_mac_icr_read(E1000ECore *core, int index)
-{
-    uint32_t ret = core->mac[ICR];
-    trace_e1000e_irq_icr_read_entry(ret);
-
-    if (core->mac[IMS] == 0) {
-        trace_e1000e_irq_icr_clear_zero_ims();
-        core->mac[ICR] = 0;
-    }
-
-    if ((core->mac[ICR] & E1000_ICR_ASSERTED) &&
-        (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) {
-        trace_e1000e_irq_icr_clear_iame();
-        core->mac[ICR] = 0;
-        trace_e1000e_irq_icr_process_iame();
-        e1000e_clear_ims_bits(core, core->mac[IAM]);
-    }
-
-    trace_e1000e_irq_icr_read_exit(core->mac[ICR]);
-    e1000e_update_interrupt_state(core);
-    return ret;
-}
-
-static uint32_t
-e1000e_mac_read_clr4(E1000ECore *core, int index)
-{
-    uint32_t ret = core->mac[index];
-
-    core->mac[index] = 0;
-    return ret;
-}
-
-static uint32_t
-e1000e_mac_read_clr8(E1000ECore *core, int index)
-{
-    uint32_t ret = core->mac[index];
-
-    core->mac[index] = 0;
-    core->mac[index - 1] = 0;
-    return ret;
-}
-
-static uint32_t
-e1000e_get_ctrl(E1000ECore *core, int index)
-{
-    uint32_t val = core->mac[CTRL];
-
-    trace_e1000e_link_read_params(
-        !!(val & E1000_CTRL_ASDE),
-        (val & E1000_CTRL_SPD_SEL) >> E1000_CTRL_SPD_SHIFT,
-        !!(val & E1000_CTRL_FRCSPD),
-        !!(val & E1000_CTRL_FRCDPX),
-        !!(val & E1000_CTRL_RFCE),
-        !!(val & E1000_CTRL_TFCE));
-
-    return val;
-}
-
-static uint32_t
-e1000e_get_status(E1000ECore *core, int index)
-{
-    uint32_t res = core->mac[STATUS];
-
-    if (!(core->mac[CTRL] & E1000_CTRL_GIO_MASTER_DISABLE)) {
-        res |= E1000_STATUS_GIO_MASTER_ENABLE;
-    }
-
-    if (core->mac[CTRL] & E1000_CTRL_FRCDPX) {
-        res |= (core->mac[CTRL] & E1000_CTRL_FD) ? E1000_STATUS_FD : 0;
-    } else {
-        res |= E1000_STATUS_FD;
-    }
-
-    if ((core->mac[CTRL] & E1000_CTRL_FRCSPD) ||
-        (core->mac[CTRL_EXT] & E1000_CTRL_EXT_SPD_BYPS)) {
-        switch (core->mac[CTRL] & E1000_CTRL_SPD_SEL) {
-        case E1000_CTRL_SPD_10:
-            res |= E1000_STATUS_SPEED_10;
-            break;
-        case E1000_CTRL_SPD_100:
-            res |= E1000_STATUS_SPEED_100;
-            break;
-        case E1000_CTRL_SPD_1000:
-        default:
-            res |= E1000_STATUS_SPEED_1000;
-            break;
-        }
-    } else {
-        res |= E1000_STATUS_SPEED_1000;
-    }
-
-    trace_e1000e_link_status(
-        !!(res & E1000_STATUS_LU),
-        !!(res & E1000_STATUS_FD),
-        (res & E1000_STATUS_SPEED_MASK) >> E1000_STATUS_SPEED_SHIFT,
-        (res & E1000_STATUS_ASDV) >> E1000_STATUS_ASDV_SHIFT);
-
-    return res;
-}
-
-static uint32_t
-e1000e_get_tarc(E1000ECore *core, int index)
-{
-    return core->mac[index] & ((BIT(11) - 1) |
-                                BIT(27)      |
-                                BIT(28)      |
-                                BIT(29)      |
-                                BIT(30));
-}
-
-static void
-e1000e_mac_writereg(E1000ECore *core, int index, uint32_t val)
-{
-    core->mac[index] = val;
-}
-
-static void
-e1000e_mac_setmacaddr(E1000ECore *core, int index, uint32_t val)
-{
-    uint32_t macaddr[2];
-
-    core->mac[index] = val;
-
-    macaddr[0] = cpu_to_le32(core->mac[RA]);
-    macaddr[1] = cpu_to_le32(core->mac[RA + 1]);
-    qemu_format_nic_info_str(qemu_get_queue(core->owner_nic),
-        (uint8_t *) macaddr);
-
-    trace_e1000e_mac_set_sw(MAC_ARG(macaddr));
-}
-
-static void
-e1000e_set_eecd(E1000ECore *core, int index, uint32_t val)
-{
-    static const uint32_t ro_bits = E1000_EECD_PRES          |
-                                    E1000_EECD_AUTO_RD       |
-                                    E1000_EECD_SIZE_EX_MASK;
-
-    core->mac[EECD] = (core->mac[EECD] & ro_bits) | (val & ~ro_bits);
-}
-
-static void
-e1000e_set_eerd(E1000ECore *core, int index, uint32_t val)
-{
-    uint32_t addr = (val >> E1000_EERW_ADDR_SHIFT) & E1000_EERW_ADDR_MASK;
-    uint32_t flags = 0;
-    uint32_t data = 0;
-
-    if ((addr < E1000E_EEPROM_SIZE) && (val & E1000_EERW_START)) {
-        data = core->eeprom[addr];
-        flags = E1000_EERW_DONE;
-    }
-
-    core->mac[EERD] = flags                           |
-                      (addr << E1000_EERW_ADDR_SHIFT) |
-                      (data << E1000_EERW_DATA_SHIFT);
-}
-
-static void
-e1000e_set_eewr(E1000ECore *core, int index, uint32_t val)
-{
-    uint32_t addr = (val >> E1000_EERW_ADDR_SHIFT) & E1000_EERW_ADDR_MASK;
-    uint32_t data = (val >> E1000_EERW_DATA_SHIFT) & E1000_EERW_DATA_MASK;
-    uint32_t flags = 0;
-
-    if ((addr < E1000E_EEPROM_SIZE) && (val & E1000_EERW_START)) {
-        core->eeprom[addr] = data;
-        flags = E1000_EERW_DONE;
-    }
-
-    core->mac[EERD] = flags                           |
-                      (addr << E1000_EERW_ADDR_SHIFT) |
-                      (data << E1000_EERW_DATA_SHIFT);
-}
-
-static void
-e1000e_set_rxdctl(E1000ECore *core, int index, uint32_t val)
-{
-    core->mac[RXDCTL] = core->mac[RXDCTL1] = val;
-}
-
-static void
-e1000e_set_itr(E1000ECore *core, int index, uint32_t val)
-{
-    uint32_t interval = val & 0xffff;
-
-    trace_e1000e_irq_itr_set(val);
-
-    core->itr_guest_value = interval;
-    core->mac[index] = MAX(interval, E1000E_MIN_XITR);
-}
-
-static void
-e1000e_set_eitr(E1000ECore *core, int index, uint32_t val)
-{
-    uint32_t interval = val & 0xffff;
-    uint32_t eitr_num = index - EITR;
-
-    trace_e1000e_irq_eitr_set(eitr_num, val);
-
-    core->eitr_guest_value[eitr_num] = interval;
-    core->mac[index] = MAX(interval, E1000E_MIN_XITR);
-}
-
-static void
-e1000e_set_psrctl(E1000ECore *core, int index, uint32_t val)
-{
-    if ((val & E1000_PSRCTL_BSIZE0_MASK) == 0) {
-        hw_error("e1000e: PSRCTL.BSIZE0 cannot be zero");
-    }
-
-    if ((val & E1000_PSRCTL_BSIZE1_MASK) == 0) {
-        hw_error("e1000e: PSRCTL.BSIZE1 cannot be zero");
-    }
-
-    core->mac[PSRCTL] = val;
-}
-
-static void
-e1000e_update_rx_offloads(E1000ECore *core)
-{
-    int cso_state = e1000e_rx_l4_cso_enabled(core);
-
-    trace_e1000e_rx_set_cso(cso_state);
-
-    if (core->has_vnet) {
-        qemu_set_offload(qemu_get_queue(core->owner_nic)->peer,
-                         cso_state, 0, 0, 0, 0);
-    }
-}
-
-static void
-e1000e_set_rxcsum(E1000ECore *core, int index, uint32_t val)
-{
-    core->mac[RXCSUM] = val;
-    e1000e_update_rx_offloads(core);
-}
-
-static void
-e1000e_set_gcr(E1000ECore *core, int index, uint32_t val)
-{
-    uint32_t ro_bits = core->mac[GCR] & E1000_GCR_RO_BITS;
-    core->mac[GCR] = (val & ~E1000_GCR_RO_BITS) | ro_bits;
-}
-
-#define e1000e_getreg(x)    [x] = e1000e_mac_readreg
-static uint32_t (*e1000e_macreg_readops[])(E1000ECore *, int) = {
-    e1000e_getreg(PBA),
-    e1000e_getreg(WUFC),
-    e1000e_getreg(MANC),
-    e1000e_getreg(TOTL),
-    e1000e_getreg(RDT0),
-    e1000e_getreg(RDBAH0),
-    e1000e_getreg(TDBAL1),
-    e1000e_getreg(RDLEN0),
-    e1000e_getreg(RDH1),
-    e1000e_getreg(LATECOL),
-    e1000e_getreg(SEC),
-    e1000e_getreg(XONTXC),
-    e1000e_getreg(WUS),
-    e1000e_getreg(GORCL),
-    e1000e_getreg(MGTPRC),
-    e1000e_getreg(EERD),
-    e1000e_getreg(EIAC),
-    e1000e_getreg(PSRCTL),
-    e1000e_getreg(MANC2H),
-    e1000e_getreg(RXCSUM),
-    e1000e_getreg(GSCL_3),
-    e1000e_getreg(GSCN_2),
-    e1000e_getreg(RSRPD),
-    e1000e_getreg(RDBAL1),
-    e1000e_getreg(FCAH),
-    e1000e_getreg(FCRTH),
-    e1000e_getreg(FLOP),
-    e1000e_getreg(FLASHT),
-    e1000e_getreg(RXSTMPH),
-    e1000e_getreg(TXSTMPL),
-    e1000e_getreg(TIMADJL),
-    e1000e_getreg(TXDCTL),
-    e1000e_getreg(RDH0),
-    e1000e_getreg(TDT1),
-    e1000e_getreg(TNCRS),
-    e1000e_getreg(RJC),
-    e1000e_getreg(IAM),
-    e1000e_getreg(GSCL_2),
-    e1000e_getreg(RDBAH1),
-    e1000e_getreg(FLSWDATA),
-    e1000e_getreg(RXSATRH),
-    e1000e_getreg(TIPG),
-    e1000e_getreg(FLMNGCTL),
-    e1000e_getreg(FLMNGCNT),
-    e1000e_getreg(TSYNCTXCTL),
-    e1000e_getreg(EXTCNF_SIZE),
-    e1000e_getreg(EXTCNF_CTRL),
-    e1000e_getreg(EEMNGDATA),
-    e1000e_getreg(CTRL_EXT),
-    e1000e_getreg(SYSTIMH),
-    e1000e_getreg(EEMNGCTL),
-    e1000e_getreg(FLMNGDATA),
-    e1000e_getreg(TSYNCRXCTL),
-    e1000e_getreg(TDH),
-    e1000e_getreg(LEDCTL),
-    e1000e_getreg(STATUS),
-    e1000e_getreg(TCTL),
-    e1000e_getreg(TDBAL),
-    e1000e_getreg(TDLEN),
-    e1000e_getreg(TDH1),
-    e1000e_getreg(RADV),
-    e1000e_getreg(ECOL),
-    e1000e_getreg(DC),
-    e1000e_getreg(RLEC),
-    e1000e_getreg(XOFFTXC),
-    e1000e_getreg(RFC),
-    e1000e_getreg(RNBC),
-    e1000e_getreg(MGTPTC),
-    e1000e_getreg(TIMINCA),
-    e1000e_getreg(RXCFGL),
-    e1000e_getreg(MFUTP01),
-    e1000e_getreg(FACTPS),
-    e1000e_getreg(GSCL_1),
-    e1000e_getreg(GSCN_0),
-    e1000e_getreg(GCR2),
-    e1000e_getreg(RDT1),
-    e1000e_getreg(PBACLR),
-    e1000e_getreg(FCTTV),
-    e1000e_getreg(EEWR),
-    e1000e_getreg(FLSWCTL),
-    e1000e_getreg(RXDCTL1),
-    e1000e_getreg(RXSATRL),
-    e1000e_getreg(SYSTIML),
-    e1000e_getreg(RXUDP),
-    e1000e_getreg(TORL),
-    e1000e_getreg(TDLEN1),
-    e1000e_getreg(MCC),
-    e1000e_getreg(WUC),
-    e1000e_getreg(EECD),
-    e1000e_getreg(MFUTP23),
-    e1000e_getreg(RAID),
-    e1000e_getreg(FCRTV),
-    e1000e_getreg(TXDCTL1),
-    e1000e_getreg(RCTL),
-    e1000e_getreg(TDT),
-    e1000e_getreg(MDIC),
-    e1000e_getreg(FCRUC),
-    e1000e_getreg(VET),
-    e1000e_getreg(RDBAL0),
-    e1000e_getreg(TDBAH1),
-    e1000e_getreg(RDTR),
-    e1000e_getreg(SCC),
-    e1000e_getreg(COLC),
-    e1000e_getreg(CEXTERR),
-    e1000e_getreg(XOFFRXC),
-    e1000e_getreg(IPAV),
-    e1000e_getreg(GOTCL),
-    e1000e_getreg(MGTPDC),
-    e1000e_getreg(GCR),
-    e1000e_getreg(IVAR),
-    e1000e_getreg(POEMB),
-    e1000e_getreg(MFVAL),
-    e1000e_getreg(FUNCTAG),
-    e1000e_getreg(GSCL_4),
-    e1000e_getreg(GSCN_3),
-    e1000e_getreg(MRQC),
-    e1000e_getreg(RDLEN1),
-    e1000e_getreg(FCT),
-    e1000e_getreg(FLA),
-    e1000e_getreg(FLOL),
-    e1000e_getreg(RXDCTL),
-    e1000e_getreg(RXSTMPL),
-    e1000e_getreg(TXSTMPH),
-    e1000e_getreg(TIMADJH),
-    e1000e_getreg(FCRTL),
-    e1000e_getreg(TDBAH),
-    e1000e_getreg(TADV),
-    e1000e_getreg(XONRXC),
-    e1000e_getreg(TSCTFC),
-    e1000e_getreg(RFCTL),
-    e1000e_getreg(GSCN_1),
-    e1000e_getreg(FCAL),
-    e1000e_getreg(FLSWCNT),
-
-    [TOTH]    = e1000e_mac_read_clr8,
-    [GOTCH]   = e1000e_mac_read_clr8,
-    [PRC64]   = e1000e_mac_read_clr4,
-    [PRC255]  = e1000e_mac_read_clr4,
-    [PRC1023] = e1000e_mac_read_clr4,
-    [PTC64]   = e1000e_mac_read_clr4,
-    [PTC255]  = e1000e_mac_read_clr4,
-    [PTC1023] = e1000e_mac_read_clr4,
-    [GPRC]    = e1000e_mac_read_clr4,
-    [TPT]     = e1000e_mac_read_clr4,
-    [RUC]     = e1000e_mac_read_clr4,
-    [BPRC]    = e1000e_mac_read_clr4,
-    [MPTC]    = e1000e_mac_read_clr4,
-    [IAC]     = e1000e_mac_read_clr4,
-    [ICR]     = e1000e_mac_icr_read,
-    [RDFH]    = E1000E_LOW_BITS_READ(13),
-    [RDFHS]   = E1000E_LOW_BITS_READ(13),
-    [RDFPC]   = E1000E_LOW_BITS_READ(13),
-    [TDFH]    = E1000E_LOW_BITS_READ(13),
-    [TDFHS]   = E1000E_LOW_BITS_READ(13),
-    [STATUS]  = e1000e_get_status,
-    [TARC0]   = e1000e_get_tarc,
-    [PBS]     = E1000E_LOW_BITS_READ(6),
-    [ICS]     = e1000e_mac_ics_read,
-    [AIT]     = E1000E_LOW_BITS_READ(16),
-    [TORH]    = e1000e_mac_read_clr8,
-    [GORCH]   = e1000e_mac_read_clr8,
-    [PRC127]  = e1000e_mac_read_clr4,
-    [PRC511]  = e1000e_mac_read_clr4,
-    [PRC1522] = e1000e_mac_read_clr4,
-    [PTC127]  = e1000e_mac_read_clr4,
-    [PTC511]  = e1000e_mac_read_clr4,
-    [PTC1522] = e1000e_mac_read_clr4,
-    [GPTC]    = e1000e_mac_read_clr4,
-    [TPR]     = e1000e_mac_read_clr4,
-    [ROC]     = e1000e_mac_read_clr4,
-    [MPRC]    = e1000e_mac_read_clr4,
-    [BPTC]    = e1000e_mac_read_clr4,
-    [TSCTC]   = e1000e_mac_read_clr4,
-    [ITR]     = e1000e_mac_itr_read,
-    [RDFT]    = E1000E_LOW_BITS_READ(13),
-    [RDFTS]   = E1000E_LOW_BITS_READ(13),
-    [TDFPC]   = E1000E_LOW_BITS_READ(13),
-    [TDFT]    = E1000E_LOW_BITS_READ(13),
-    [TDFTS]   = E1000E_LOW_BITS_READ(13),
-    [CTRL]    = e1000e_get_ctrl,
-    [TARC1]   = e1000e_get_tarc,
-    [SWSM]    = e1000e_mac_swsm_read,
-    [IMS]     = e1000e_mac_ims_read,
-
-    [CRCERRS ... MPC]      = e1000e_mac_readreg,
-    [IP6AT ... IP6AT + 3]  = e1000e_mac_readreg,
-    [IP4AT ... IP4AT + 6]  = e1000e_mac_readreg,
-    [RA ... RA + 31]       = e1000e_mac_readreg,
-    [WUPM ... WUPM + 31]   = e1000e_mac_readreg,
-    [MTA ... MTA + 127]    = e1000e_mac_readreg,
-    [VFTA ... VFTA + 127]  = e1000e_mac_readreg,
-    [FFMT ... FFMT + 254]  = E1000E_LOW_BITS_READ(4),
-    [FFVT ... FFVT + 254]  = e1000e_mac_readreg,
-    [MDEF ... MDEF + 7]    = e1000e_mac_readreg,
-    [FFLT ... FFLT + 10]   = E1000E_LOW_BITS_READ(11),
-    [FTFT ... FTFT + 254]  = e1000e_mac_readreg,
-    [PBM ... PBM + 10239]  = e1000e_mac_readreg,
-    [RETA ... RETA + 31]   = e1000e_mac_readreg,
-    [RSSRK ... RSSRK + 31] = e1000e_mac_readreg,
-    [MAVTV0 ... MAVTV3]    = e1000e_mac_readreg,
-    [EITR...EITR + E1000E_MSIX_VEC_NUM - 1] = e1000e_mac_eitr_read
-};
-enum { E1000E_NREADOPS = ARRAY_SIZE(e1000e_macreg_readops) };
-
-#define e1000e_putreg(x)    [x] = e1000e_mac_writereg
-static void (*e1000e_macreg_writeops[])(E1000ECore *, int, uint32_t) = {
-    e1000e_putreg(PBA),
-    e1000e_putreg(SWSM),
-    e1000e_putreg(WUFC),
-    e1000e_putreg(RDBAH1),
-    e1000e_putreg(TDBAH),
-    e1000e_putreg(TXDCTL),
-    e1000e_putreg(RDBAH0),
-    e1000e_putreg(LEDCTL),
-    e1000e_putreg(FCAL),
-    e1000e_putreg(FCRUC),
-    e1000e_putreg(AIT),
-    e1000e_putreg(TDFH),
-    e1000e_putreg(TDFT),
-    e1000e_putreg(TDFHS),
-    e1000e_putreg(TDFTS),
-    e1000e_putreg(TDFPC),
-    e1000e_putreg(WUC),
-    e1000e_putreg(WUS),
-    e1000e_putreg(RDFH),
-    e1000e_putreg(RDFT),
-    e1000e_putreg(RDFHS),
-    e1000e_putreg(RDFTS),
-    e1000e_putreg(RDFPC),
-    e1000e_putreg(IPAV),
-    e1000e_putreg(TDBAH1),
-    e1000e_putreg(TIMINCA),
-    e1000e_putreg(IAM),
-    e1000e_putreg(EIAC),
-    e1000e_putreg(IVAR),
-    e1000e_putreg(TARC0),
-    e1000e_putreg(TARC1),
-    e1000e_putreg(FLSWDATA),
-    e1000e_putreg(POEMB),
-    e1000e_putreg(PBS),
-    e1000e_putreg(MFUTP01),
-    e1000e_putreg(MFUTP23),
-    e1000e_putreg(MANC),
-    e1000e_putreg(MANC2H),
-    e1000e_putreg(MFVAL),
-    e1000e_putreg(EXTCNF_CTRL),
-    e1000e_putreg(FACTPS),
-    e1000e_putreg(FUNCTAG),
-    e1000e_putreg(GSCL_1),
-    e1000e_putreg(GSCL_2),
-    e1000e_putreg(GSCL_3),
-    e1000e_putreg(GSCL_4),
-    e1000e_putreg(GSCN_0),
-    e1000e_putreg(GSCN_1),
-    e1000e_putreg(GSCN_2),
-    e1000e_putreg(GSCN_3),
-    e1000e_putreg(GCR2),
-    e1000e_putreg(MRQC),
-    e1000e_putreg(FLOP),
-    e1000e_putreg(FLOL),
-    e1000e_putreg(FLSWCTL),
-    e1000e_putreg(FLSWCNT),
-    e1000e_putreg(FLA),
-    e1000e_putreg(RXDCTL1),
-    e1000e_putreg(TXDCTL1),
-    e1000e_putreg(TIPG),
-    e1000e_putreg(RXSTMPH),
-    e1000e_putreg(RXSTMPL),
-    e1000e_putreg(RXSATRL),
-    e1000e_putreg(RXSATRH),
-    e1000e_putreg(TXSTMPL),
-    e1000e_putreg(TXSTMPH),
-    e1000e_putreg(SYSTIML),
-    e1000e_putreg(SYSTIMH),
-    e1000e_putreg(TIMADJL),
-    e1000e_putreg(TIMADJH),
-    e1000e_putreg(RXUDP),
-    e1000e_putreg(RXCFGL),
-    e1000e_putreg(TSYNCRXCTL),
-    e1000e_putreg(TSYNCTXCTL),
-    e1000e_putreg(FLSWDATA),
-    e1000e_putreg(EXTCNF_SIZE),
-    e1000e_putreg(EEMNGCTL),
-    e1000e_putreg(RA),
-
-    [TDH1]     = e1000e_set_16bit,
-    [TDT1]     = e1000e_set_tdt,
-    [TCTL]     = e1000e_set_tctl,
-    [TDT]      = e1000e_set_tdt,
-    [MDIC]     = e1000e_set_mdic,
-    [ICS]      = e1000e_set_ics,
-    [TDH]      = e1000e_set_16bit,
-    [RDH0]     = e1000e_set_16bit,
-    [RDT0]     = e1000e_set_rdt,
-    [IMC]      = e1000e_set_imc,
-    [IMS]      = e1000e_set_ims,
-    [ICR]      = e1000e_set_icr,
-    [EECD]     = e1000e_set_eecd,
-    [RCTL]     = e1000e_set_rx_control,
-    [CTRL]     = e1000e_set_ctrl,
-    [RDTR]     = e1000e_set_rdtr,
-    [RADV]     = e1000e_set_16bit,
-    [TADV]     = e1000e_set_16bit,
-    [ITR]      = e1000e_set_itr,
-    [EERD]     = e1000e_set_eerd,
-    [GCR]      = e1000e_set_gcr,
-    [PSRCTL]   = e1000e_set_psrctl,
-    [RXCSUM]   = e1000e_set_rxcsum,
-    [RAID]     = e1000e_set_16bit,
-    [RSRPD]    = e1000e_set_12bit,
-    [TIDV]     = e1000e_set_tidv,
-    [TDLEN1]   = e1000e_set_dlen,
-    [TDLEN]    = e1000e_set_dlen,
-    [RDLEN0]   = e1000e_set_dlen,
-    [RDLEN1]   = e1000e_set_dlen,
-    [TDBAL]    = e1000e_set_dbal,
-    [TDBAL1]   = e1000e_set_dbal,
-    [RDBAL0]   = e1000e_set_dbal,
-    [RDBAL1]   = e1000e_set_dbal,
-    [RDH1]     = e1000e_set_16bit,
-    [RDT1]     = e1000e_set_rdt,
-    [STATUS]   = e1000e_set_status,
-    [PBACLR]   = e1000e_set_pbaclr,
-    [CTRL_EXT] = e1000e_set_ctrlext,
-    [FCAH]     = e1000e_set_16bit,
-    [FCT]      = e1000e_set_16bit,
-    [FCTTV]    = e1000e_set_16bit,
-    [FCRTV]    = e1000e_set_16bit,
-    [FCRTH]    = e1000e_set_fcrth,
-    [FCRTL]    = e1000e_set_fcrtl,
-    [VET]      = e1000e_set_vet,
-    [RXDCTL]   = e1000e_set_rxdctl,
-    [FLASHT]   = e1000e_set_16bit,
-    [EEWR]     = e1000e_set_eewr,
-    [CTRL_DUP] = e1000e_set_ctrl,
-    [RFCTL]    = e1000e_set_rfctl,
-    [RA + 1]   = e1000e_mac_setmacaddr,
-
-    [IP6AT ... IP6AT + 3]    = e1000e_mac_writereg,
-    [IP4AT ... IP4AT + 6]    = e1000e_mac_writereg,
-    [RA + 2 ... RA + 31]     = e1000e_mac_writereg,
-    [WUPM ... WUPM + 31]     = e1000e_mac_writereg,
-    [MTA ... MTA + 127]      = e1000e_mac_writereg,
-    [VFTA ... VFTA + 127]    = e1000e_mac_writereg,
-    [FFMT ... FFMT + 254]    = e1000e_mac_writereg,
-    [FFVT ... FFVT + 254]    = e1000e_mac_writereg,
-    [PBM ... PBM + 10239]    = e1000e_mac_writereg,
-    [MDEF ... MDEF + 7]      = e1000e_mac_writereg,
-    [FFLT ... FFLT + 10]     = e1000e_mac_writereg,
-    [FTFT ... FTFT + 254]    = e1000e_mac_writereg,
-    [RETA ... RETA + 31]     = e1000e_mac_writereg,
-    [RSSRK ... RSSRK + 31]   = e1000e_mac_writereg,
-    [MAVTV0 ... MAVTV3]      = e1000e_mac_writereg,
-    [EITR...EITR + E1000E_MSIX_VEC_NUM - 1] = e1000e_set_eitr
-};
-enum { E1000E_NWRITEOPS = ARRAY_SIZE(e1000e_macreg_writeops) };
-
-enum { MAC_ACCESS_PARTIAL = 1 };
-
-/* The array below combines alias offsets of the index values for the
- * MAC registers that have aliases, with the indication of not fully
- * implemented registers (lowest bit). This combination is possible
- * because all of the offsets are even. */
-static const uint16_t mac_reg_access[E1000E_MAC_SIZE] = {
-    /* Alias index offsets */
-    [FCRTL_A] = 0x07fe, [FCRTH_A] = 0x0802,
-    [RDH0_A]  = 0x09bc, [RDT0_A]  = 0x09bc, [RDTR_A] = 0x09c6,
-    [RDFH_A]  = 0xe904, [RDFT_A]  = 0xe904,
-    [TDH_A]   = 0x0cf8, [TDT_A]   = 0x0cf8, [TIDV_A] = 0x0cf8,
-    [TDFH_A]  = 0xed00, [TDFT_A]  = 0xed00,
-    [RA_A ... RA_A + 31]      = 0x14f0,
-    [VFTA_A ... VFTA_A + 127] = 0x1400,
-    [RDBAL0_A ... RDLEN0_A] = 0x09bc,
-    [TDBAL_A ... TDLEN_A]   = 0x0cf8,
-    /* Access options */
-    [RDFH]  = MAC_ACCESS_PARTIAL,    [RDFT]  = MAC_ACCESS_PARTIAL,
-    [RDFHS] = MAC_ACCESS_PARTIAL,    [RDFTS] = MAC_ACCESS_PARTIAL,
-    [RDFPC] = MAC_ACCESS_PARTIAL,
-    [TDFH]  = MAC_ACCESS_PARTIAL,    [TDFT]  = MAC_ACCESS_PARTIAL,
-    [TDFHS] = MAC_ACCESS_PARTIAL,    [TDFTS] = MAC_ACCESS_PARTIAL,
-    [TDFPC] = MAC_ACCESS_PARTIAL,    [EECD]  = MAC_ACCESS_PARTIAL,
-    [PBM]   = MAC_ACCESS_PARTIAL,    [FLA]   = MAC_ACCESS_PARTIAL,
-    [FCAL]  = MAC_ACCESS_PARTIAL,    [FCAH]  = MAC_ACCESS_PARTIAL,
-    [FCT]   = MAC_ACCESS_PARTIAL,    [FCTTV] = MAC_ACCESS_PARTIAL,
-    [FCRTV] = MAC_ACCESS_PARTIAL,    [FCRTL] = MAC_ACCESS_PARTIAL,
-    [FCRTH] = MAC_ACCESS_PARTIAL,    [TXDCTL] = MAC_ACCESS_PARTIAL,
-    [TXDCTL1] = MAC_ACCESS_PARTIAL,
-    [MAVTV0 ... MAVTV3] = MAC_ACCESS_PARTIAL
-};
-
-void
-e1000e_core_write(E1000ECore *core, hwaddr addr, uint64_t val, unsigned size)
-{
-    uint16_t index = e1000e_get_reg_index_with_offset(mac_reg_access, addr);
-
-    if (index < E1000E_NWRITEOPS && e1000e_macreg_writeops[index]) {
-        if (mac_reg_access[index] & MAC_ACCESS_PARTIAL) {
-            trace_e1000e_wrn_regs_write_trivial(index << 2);
-        }
-        trace_e1000e_core_write(index << 2, size, val);
-        e1000e_macreg_writeops[index](core, index, val);
-    } else if (index < E1000E_NREADOPS && e1000e_macreg_readops[index]) {
-        trace_e1000e_wrn_regs_write_ro(index << 2, size, val);
-    } else {
-        trace_e1000e_wrn_regs_write_unknown(index << 2, size, val);
-    }
-}
-
-uint64_t
-e1000e_core_read(E1000ECore *core, hwaddr addr, unsigned size)
-{
-    uint64_t val;
-    uint16_t index = e1000e_get_reg_index_with_offset(mac_reg_access, addr);
-
-    if (index < E1000E_NREADOPS && e1000e_macreg_readops[index]) {
-        if (mac_reg_access[index] & MAC_ACCESS_PARTIAL) {
-            trace_e1000e_wrn_regs_read_trivial(index << 2);
-        }
-        val = e1000e_macreg_readops[index](core, index);
-        trace_e1000e_core_read(index << 2, size, val);
-        return val;
-    } else {
-        trace_e1000e_wrn_regs_read_unknown(index << 2, size);
-    }
-    return 0;
-}
-
-static inline void
-e1000e_autoneg_pause(E1000ECore *core)
-{
-    timer_del(core->autoneg_timer);
-}
-
-static void
-e1000e_autoneg_resume(E1000ECore *core)
-{
-    if (e1000e_have_autoneg(core) &&
-        !(core->phy[0][PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) {
-        qemu_get_queue(core->owner_nic)->link_down = false;
-        timer_mod(core->autoneg_timer,
-                  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);
-    }
-}
-
-static void
-e1000e_vm_state_change(void *opaque, int running, RunState state)
-{
-    E1000ECore *core = opaque;
-
-    if (running) {
-        trace_e1000e_vm_state_running();
-        e1000e_intrmgr_resume(core);
-        e1000e_autoneg_resume(core);
-    } else {
-        trace_e1000e_vm_state_stopped();
-        e1000e_autoneg_pause(core);
-        e1000e_intrmgr_pause(core);
-    }
-}
-
-void
-e1000e_core_pci_realize(E1000ECore     *core,
-                        const uint16_t *eeprom_templ,
-                        uint32_t        eeprom_size,
-                        const uint8_t  *macaddr)
-{
-    int i;
-
-    core->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
-                                       e1000e_autoneg_timer, core);
-    e1000e_intrmgr_pci_realize(core);
-
-    core->vmstate =
-        qemu_add_vm_change_state_handler(e1000e_vm_state_change, core);
-
-    for (i = 0; i < E1000E_NUM_QUEUES; i++) {
-        net_tx_pkt_init(&core->tx[i].tx_pkt, core->owner,
-                        E1000E_MAX_TX_FRAGS, core->has_vnet);
-    }
-
-    net_rx_pkt_init(&core->rx_pkt, core->has_vnet);
-
-    e1000x_core_prepare_eeprom(core->eeprom,
-                               eeprom_templ,
-                               eeprom_size,
-                               PCI_DEVICE_GET_CLASS(core->owner)->device_id,
-                               macaddr);
-    e1000e_update_rx_offloads(core);
-}
-
-void
-e1000e_core_pci_uninit(E1000ECore *core)
-{
-    int i;
-
-    timer_del(core->autoneg_timer);
-    timer_free(core->autoneg_timer);
-
-    e1000e_intrmgr_pci_unint(core);
-
-    qemu_del_vm_change_state_handler(core->vmstate);
-
-    for (i = 0; i < E1000E_NUM_QUEUES; i++) {
-        net_tx_pkt_reset(core->tx[i].tx_pkt);
-        net_tx_pkt_uninit(core->tx[i].tx_pkt);
-    }
-
-    net_rx_pkt_uninit(core->rx_pkt);
-}
-
-static const uint16_t
-e1000e_phy_reg_init[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE] = {
-    [0] = {
-        [PHY_CTRL] =   MII_CR_SPEED_SELECT_MSB  |
-                       MII_CR_FULL_DUPLEX       |
-                       MII_CR_AUTO_NEG_EN,
-
-        [PHY_STATUS] = MII_SR_EXTENDED_CAPS     |
-                       MII_SR_LINK_STATUS       |
-                       MII_SR_AUTONEG_CAPS      |
-                       MII_SR_PREAMBLE_SUPPRESS |
-                       MII_SR_EXTENDED_STATUS   |
-                       MII_SR_10T_HD_CAPS       |
-                       MII_SR_10T_FD_CAPS       |
-                       MII_SR_100X_HD_CAPS      |
-                       MII_SR_100X_FD_CAPS,
-
-        [PHY_ID1]               = 0x141,
-        [PHY_ID2]               = E1000_PHY_ID2_82574x,
-        [PHY_AUTONEG_ADV]       = 0xde1,
-        [PHY_LP_ABILITY]        = 0x7e0,
-        [PHY_AUTONEG_EXP]       = BIT(2),
-        [PHY_NEXT_PAGE_TX]      = BIT(0) | BIT(13),
-        [PHY_1000T_CTRL]        = BIT(8) | BIT(9) | BIT(10) | BIT(11),
-        [PHY_1000T_STATUS]      = 0x3c00,
-        [PHY_EXT_STATUS]        = BIT(12) | BIT(13),
-
-        [PHY_COPPER_CTRL1]      = BIT(5) | BIT(6) | BIT(8) | BIT(9) |
-                                  BIT(12) | BIT(13),
-        [PHY_COPPER_STAT1]      = BIT(3) | BIT(10) | BIT(11) | BIT(13) | BIT(15)
-    },
-    [2] = {
-        [PHY_MAC_CTRL1]         = BIT(3) | BIT(7),
-        [PHY_MAC_CTRL2]         = BIT(1) | BIT(2) | BIT(6) | BIT(12)
-    },
-    [3] = {
-        [PHY_LED_TIMER_CTRL]    = BIT(0) | BIT(2) | BIT(14)
-    }
-};
-
-static const uint32_t e1000e_mac_reg_init[] = {
-    [PBA]           =     0x00140014,
-    [LEDCTL]        =  BIT(1) | BIT(8) | BIT(9) | BIT(15) | BIT(17) | BIT(18),
-    [EXTCNF_CTRL]   = BIT(3),
-    [EEMNGCTL]      = BIT(31),
-    [FLASHT]        = 0x2,
-    [FLSWCTL]       = BIT(30) | BIT(31),
-    [FLOL]          = BIT(0),
-    [RXDCTL]        = BIT(16),
-    [RXDCTL1]       = BIT(16),
-    [TIPG]          = 0x8 | (0x8 << 10) | (0x6 << 20),
-    [RXCFGL]        = 0x88F7,
-    [RXUDP]         = 0x319,
-    [CTRL]          = E1000_CTRL_FD | E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN0 |
-                      E1000_CTRL_SPD_1000 | E1000_CTRL_SLU |
-                      E1000_CTRL_ADVD3WUC,
-    [STATUS]        =  E1000_STATUS_ASDV_1000 | E1000_STATUS_LU,
-    [PSRCTL]        = (2 << E1000_PSRCTL_BSIZE0_SHIFT) |
-                      (4 << E1000_PSRCTL_BSIZE1_SHIFT) |
-                      (4 << E1000_PSRCTL_BSIZE2_SHIFT),
-    [TARC0]         = 0x3 | E1000_TARC_ENABLE,
-    [TARC1]         = 0x3 | E1000_TARC_ENABLE,
-    [EECD]          = E1000_EECD_AUTO_RD | E1000_EECD_PRES,
-    [EERD]          = E1000_EERW_DONE,
-    [EEWR]          = E1000_EERW_DONE,
-    [GCR]           = E1000_L0S_ADJUST |
-                      E1000_L1_ENTRY_LATENCY_MSB |
-                      E1000_L1_ENTRY_LATENCY_LSB,
-    [TDFH]          = 0x600,
-    [TDFT]          = 0x600,
-    [TDFHS]         = 0x600,
-    [TDFTS]         = 0x600,
-    [POEMB]         = 0x30D,
-    [PBS]           = 0x028,
-    [MANC]          = E1000_MANC_DIS_IP_CHK_ARP,
-    [FACTPS]        = E1000_FACTPS_LAN0_ON | 0x20000000,
-    [SWSM]          = 1,
-    [RXCSUM]        = E1000_RXCSUM_IPOFLD | E1000_RXCSUM_TUOFLD,
-    [ITR]           = E1000E_MIN_XITR,
-    [EITR...EITR + E1000E_MSIX_VEC_NUM - 1] = E1000E_MIN_XITR,
-};
-
-void
-e1000e_core_reset(E1000ECore *core)
-{
-    int i;
-
-    timer_del(core->autoneg_timer);
-
-    e1000e_intrmgr_reset(core);
-
-    memset(core->phy, 0, sizeof core->phy);
-    memmove(core->phy, e1000e_phy_reg_init, sizeof e1000e_phy_reg_init);
-    memset(core->mac, 0, sizeof core->mac);
-    memmove(core->mac, e1000e_mac_reg_init, sizeof e1000e_mac_reg_init);
-
-    core->rxbuf_min_shift = 1 + E1000_RING_DESC_LEN_SHIFT;
-
-    if (qemu_get_queue(core->owner_nic)->link_down) {
-        e1000e_link_down(core);
-    }
-
-    e1000x_reset_mac_addr(core->owner_nic, core->mac, core->permanent_mac);
-
-    for (i = 0; i < ARRAY_SIZE(core->tx); i++) {
-        net_tx_pkt_reset(core->tx[i].tx_pkt);
-        memset(&core->tx[i].props, 0, sizeof(core->tx[i].props));
-        core->tx[i].skip_cp = false;
-    }
-}
-
-void e1000e_core_pre_save(E1000ECore *core)
-{
-    int i;
-    NetClientState *nc = qemu_get_queue(core->owner_nic);
-
-    /*
-    * If link is down and auto-negotiation is supported and ongoing,
-    * complete auto-negotiation immediately. This allows us to look
-    * at MII_SR_AUTONEG_COMPLETE to infer link status on load.
-    */
-    if (nc->link_down && e1000e_have_autoneg(core)) {
-        core->phy[0][PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE;
-        e1000e_update_flowctl_status(core);
-    }
-
-    for (i = 0; i < ARRAY_SIZE(core->tx); i++) {
-        if (net_tx_pkt_has_fragments(core->tx[i].tx_pkt)) {
-            core->tx[i].skip_cp = true;
-        }
-    }
-}
-
-int
-e1000e_core_post_load(E1000ECore *core)
-{
-    NetClientState *nc = qemu_get_queue(core->owner_nic);
-
-    /* nc.link_down can't be migrated, so infer link_down according
-     * to link status bit in core.mac[STATUS].
-     */
-    nc->link_down = (core->mac[STATUS] & E1000_STATUS_LU) == 0;
-
-    return 0;
-}
diff --git a/hw/net/e1000e_core.h b/hw/net/e1000e_core.h
deleted file mode 100644 (file)
index 5f413a9..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
-* Core code for QEMU e1000e emulation
-*
-* Software developer's manuals:
-* http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf
-*
-* Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
-* Developed by Daynix Computing LTD (http://www.daynix.com)
-*
-* Authors:
-* Dmitry Fleytman <dmitry@daynix.com>
-* Leonid Bloch <leonid@daynix.com>
-* Yan Vugenfirer <yan@daynix.com>
-*
-* Based on work done by:
-* Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
-* Copyright (c) 2008 Qumranet
-* Based on work done by:
-* Copyright (c) 2007 Dan Aloni
-* Copyright (c) 2004 Antony T Curtis
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 2 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define E1000E_PHY_PAGE_SIZE    (0x20)
-#define E1000E_PHY_PAGES        (0x07)
-#define E1000E_MAC_SIZE         (0x8000)
-#define E1000E_EEPROM_SIZE      (64)
-#define E1000E_MSIX_VEC_NUM     (5)
-#define E1000E_NUM_QUEUES       (2)
-
-typedef struct E1000Core E1000ECore;
-
-enum { PHY_R = BIT(0),
-       PHY_W = BIT(1),
-       PHY_RW = PHY_R | PHY_W,
-       PHY_ANYPAGE = BIT(2) };
-
-typedef struct E1000IntrDelayTimer_st {
-    QEMUTimer *timer;
-    bool running;
-    uint32_t delay_reg;
-    uint32_t delay_resolution_ns;
-    E1000ECore *core;
-} E1000IntrDelayTimer;
-
-struct E1000Core {
-    uint32_t mac[E1000E_MAC_SIZE];
-    uint16_t phy[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE];
-    uint16_t eeprom[E1000E_EEPROM_SIZE];
-
-    uint32_t rxbuf_sizes[E1000_PSRCTL_BUFFS_PER_DESC];
-    uint32_t rx_desc_buf_size;
-    uint32_t rxbuf_min_shift;
-    uint8_t rx_desc_len;
-
-    QEMUTimer *autoneg_timer;
-
-    struct e1000e_tx {
-        e1000x_txd_props props;
-
-        bool skip_cp;
-        struct NetTxPkt *tx_pkt;
-    } tx[E1000E_NUM_QUEUES];
-
-    struct NetRxPkt *rx_pkt;
-
-    bool has_vnet;
-    int max_queue_num;
-
-    /* Interrupt moderation management */
-    uint32_t delayed_causes;
-
-    E1000IntrDelayTimer radv;
-    E1000IntrDelayTimer rdtr;
-    E1000IntrDelayTimer raid;
-
-    E1000IntrDelayTimer tadv;
-    E1000IntrDelayTimer tidv;
-
-    E1000IntrDelayTimer itr;
-    bool itr_intr_pending;
-
-    E1000IntrDelayTimer eitr[E1000E_MSIX_VEC_NUM];
-    bool eitr_intr_pending[E1000E_MSIX_VEC_NUM];
-
-    VMChangeStateEntry *vmstate;
-
-    uint32_t itr_guest_value;
-    uint32_t eitr_guest_value[E1000E_MSIX_VEC_NUM];
-
-    uint16_t vet;
-
-    uint8_t permanent_mac[ETH_ALEN];
-
-    NICState *owner_nic;
-    PCIDevice *owner;
-    void (*owner_start_recv)(PCIDevice *d);
-};
-
-void
-e1000e_core_write(E1000ECore *core, hwaddr addr, uint64_t val, unsigned size);
-
-uint64_t
-e1000e_core_read(E1000ECore *core, hwaddr addr, unsigned size);
-
-void
-e1000e_core_pci_realize(E1000ECore      *regs,
-                       const uint16_t *eeprom_templ,
-                       uint32_t        eeprom_size,
-                       const uint8_t  *macaddr);
-
-void
-e1000e_core_reset(E1000ECore *core);
-
-void
-e1000e_core_pre_save(E1000ECore *core);
-
-int
-e1000e_core_post_load(E1000ECore *core);
-
-void
-e1000e_core_set_link_status(E1000ECore *core);
-
-void
-e1000e_core_pci_uninit(E1000ECore *core);
-
-int
-e1000e_can_receive(E1000ECore *core);
-
-ssize_t
-e1000e_receive(E1000ECore *core, const uint8_t *buf, size_t size);
-
-ssize_t
-e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt);
diff --git a/hw/net/e1000x_common.c b/hw/net/e1000x_common.c
deleted file mode 100644 (file)
index eb0e097..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
-* QEMU e1000(e) emulation - shared code
-*
-* Copyright (c) 2008 Qumranet
-*
-* Based on work done by:
-* Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
-* Copyright (c) 2007 Dan Aloni
-* Copyright (c) 2004 Antony T Curtis
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 2 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/pci/pci.h"
-#include "net/net.h"
-
-#include "e1000x_common.h"
-
-#include "trace.h"
-
-bool e1000x_rx_ready(PCIDevice *d, uint32_t *mac)
-{
-    bool link_up = mac[STATUS] & E1000_STATUS_LU;
-    bool rx_enabled = mac[RCTL] & E1000_RCTL_EN;
-    bool pci_master = d->config[PCI_COMMAND] & PCI_COMMAND_MASTER;
-
-    if (!link_up || !rx_enabled || !pci_master) {
-        trace_e1000x_rx_can_recv_disabled(link_up, rx_enabled, pci_master);
-        return false;
-    }
-
-    return true;
-}
-
-bool e1000x_is_vlan_packet(const uint8_t *buf, uint16_t vet)
-{
-    uint16_t eth_proto = lduw_be_p(buf + 12);
-    bool res = (eth_proto == vet);
-
-    trace_e1000x_vlan_is_vlan_pkt(res, eth_proto, vet);
-
-    return res;
-}
-
-bool e1000x_rx_group_filter(uint32_t *mac, const uint8_t *buf)
-{
-    static const int mta_shift[] = { 4, 3, 2, 0 };
-    uint32_t f, ra[2], *rp, rctl = mac[RCTL];
-
-    for (rp = mac + RA; rp < mac + RA + 32; rp += 2) {
-        if (!(rp[1] & E1000_RAH_AV)) {
-            continue;
-        }
-        ra[0] = cpu_to_le32(rp[0]);
-        ra[1] = cpu_to_le32(rp[1]);
-        if (!memcmp(buf, (uint8_t *)ra, 6)) {
-            trace_e1000x_rx_flt_ucast_match((int)(rp - mac - RA) / 2,
-                                            MAC_ARG(buf));
-            return true;
-        }
-    }
-    trace_e1000x_rx_flt_ucast_mismatch(MAC_ARG(buf));
-
-    f = mta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3];
-    f = (((buf[5] << 8) | buf[4]) >> f) & 0xfff;
-    if (mac[MTA + (f >> 5)] & (1 << (f & 0x1f))) {
-        e1000x_inc_reg_if_not_full(mac, MPRC);
-        return true;
-    }
-
-    trace_e1000x_rx_flt_inexact_mismatch(MAC_ARG(buf),
-                                         (rctl >> E1000_RCTL_MO_SHIFT) & 3,
-                                         f >> 5,
-                                         mac[MTA + (f >> 5)]);
-
-    return false;
-}
-
-bool e1000x_hw_rx_enabled(uint32_t *mac)
-{
-    if (!(mac[STATUS] & E1000_STATUS_LU)) {
-        trace_e1000x_rx_link_down(mac[STATUS]);
-        return false;
-    }
-
-    if (!(mac[RCTL] & E1000_RCTL_EN)) {
-        trace_e1000x_rx_disabled(mac[RCTL]);
-        return false;
-    }
-
-    return true;
-}
-
-bool e1000x_is_oversized(uint32_t *mac, size_t size)
-{
-    /* this is the size past which hardware will
-       drop packets when setting LPE=0 */
-    static const int maximum_ethernet_vlan_size = 1522;
-    /* this is the size past which hardware will
-       drop packets when setting LPE=1 */
-    static const int maximum_ethernet_lpe_size = 16384;
-
-    if ((size > maximum_ethernet_lpe_size ||
-        (size > maximum_ethernet_vlan_size
-            && !(mac[RCTL] & E1000_RCTL_LPE)))
-        && !(mac[RCTL] & E1000_RCTL_SBP)) {
-        e1000x_inc_reg_if_not_full(mac, ROC);
-        trace_e1000x_rx_oversized(size);
-        return true;
-    }
-
-    return false;
-}
-
-void e1000x_restart_autoneg(uint32_t *mac, uint16_t *phy, QEMUTimer *timer)
-{
-    e1000x_update_regs_on_link_down(mac, phy);
-    trace_e1000x_link_negotiation_start();
-    timer_mod(timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);
-}
-
-void e1000x_reset_mac_addr(NICState *nic, uint32_t *mac_regs,
-                           uint8_t *mac_addr)
-{
-    int i;
-
-    mac_regs[RA] = 0;
-    mac_regs[RA + 1] = E1000_RAH_AV;
-    for (i = 0; i < 4; i++) {
-        mac_regs[RA] |= mac_addr[i] << (8 * i);
-        mac_regs[RA + 1] |=
-            (i < 2) ? mac_addr[i + 4] << (8 * i) : 0;
-    }
-
-    qemu_format_nic_info_str(qemu_get_queue(nic), mac_addr);
-    trace_e1000x_mac_indicate(MAC_ARG(mac_addr));
-}
-
-void e1000x_update_regs_on_autoneg_done(uint32_t *mac, uint16_t *phy)
-{
-    e1000x_update_regs_on_link_up(mac, phy);
-    phy[PHY_LP_ABILITY] |= MII_LPAR_LPACK;
-    phy[PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE;
-    trace_e1000x_link_negotiation_done();
-}
-
-void
-e1000x_core_prepare_eeprom(uint16_t       *eeprom,
-                           const uint16_t *templ,
-                           uint32_t        templ_size,
-                           uint16_t        dev_id,
-                           const uint8_t  *macaddr)
-{
-    uint16_t checksum = 0;
-    int i;
-
-    memmove(eeprom, templ, templ_size);
-
-    for (i = 0; i < 3; i++) {
-        eeprom[i] = (macaddr[2 * i + 1] << 8) | macaddr[2 * i];
-    }
-
-    eeprom[11] = eeprom[13] = dev_id;
-
-    for (i = 0; i < EEPROM_CHECKSUM_REG; i++) {
-        checksum += eeprom[i];
-    }
-
-    checksum = (uint16_t) EEPROM_SUM - checksum;
-
-    eeprom[EEPROM_CHECKSUM_REG] = checksum;
-}
-
-uint32_t
-e1000x_rxbufsize(uint32_t rctl)
-{
-    rctl &= E1000_RCTL_BSEX | E1000_RCTL_SZ_16384 | E1000_RCTL_SZ_8192 |
-        E1000_RCTL_SZ_4096 | E1000_RCTL_SZ_2048 | E1000_RCTL_SZ_1024 |
-        E1000_RCTL_SZ_512 | E1000_RCTL_SZ_256;
-    switch (rctl) {
-    case E1000_RCTL_BSEX | E1000_RCTL_SZ_16384:
-        return 16384;
-    case E1000_RCTL_BSEX | E1000_RCTL_SZ_8192:
-        return 8192;
-    case E1000_RCTL_BSEX | E1000_RCTL_SZ_4096:
-        return 4096;
-    case E1000_RCTL_SZ_1024:
-        return 1024;
-    case E1000_RCTL_SZ_512:
-        return 512;
-    case E1000_RCTL_SZ_256:
-        return 256;
-    }
-    return 2048;
-}
-
-void
-e1000x_update_rx_total_stats(uint32_t *mac,
-                             size_t data_size,
-                             size_t data_fcs_size)
-{
-    static const int PRCregs[6] = { PRC64, PRC127, PRC255, PRC511,
-                                    PRC1023, PRC1522 };
-
-    e1000x_increase_size_stats(mac, PRCregs, data_fcs_size);
-    e1000x_inc_reg_if_not_full(mac, TPR);
-    mac[GPRC] = mac[TPR];
-    /* TOR - Total Octets Received:
-    * This register includes bytes received in a packet from the <Destination
-    * Address> field through the <CRC> field, inclusively.
-    * Always include FCS length (4) in size.
-    */
-    e1000x_grow_8reg_if_not_full(mac, TORL, data_size + 4);
-    mac[GORCL] = mac[TORL];
-    mac[GORCH] = mac[TORH];
-}
-
-void
-e1000x_increase_size_stats(uint32_t *mac, const int *size_regs, int size)
-{
-    if (size > 1023) {
-        e1000x_inc_reg_if_not_full(mac, size_regs[5]);
-    } else if (size > 511) {
-        e1000x_inc_reg_if_not_full(mac, size_regs[4]);
-    } else if (size > 255) {
-        e1000x_inc_reg_if_not_full(mac, size_regs[3]);
-    } else if (size > 127) {
-        e1000x_inc_reg_if_not_full(mac, size_regs[2]);
-    } else if (size > 64) {
-        e1000x_inc_reg_if_not_full(mac, size_regs[1]);
-    } else if (size == 64) {
-        e1000x_inc_reg_if_not_full(mac, size_regs[0]);
-    }
-}
-
-void
-e1000x_read_tx_ctx_descr(struct e1000_context_desc *d,
-                         e1000x_txd_props *props)
-{
-    uint32_t op = le32_to_cpu(d->cmd_and_length);
-
-    props->ipcss = d->lower_setup.ip_fields.ipcss;
-    props->ipcso = d->lower_setup.ip_fields.ipcso;
-    props->ipcse = le16_to_cpu(d->lower_setup.ip_fields.ipcse);
-    props->tucss = d->upper_setup.tcp_fields.tucss;
-    props->tucso = d->upper_setup.tcp_fields.tucso;
-    props->tucse = le16_to_cpu(d->upper_setup.tcp_fields.tucse);
-    props->paylen = op & 0xfffff;
-    props->hdr_len = d->tcp_seg_setup.fields.hdr_len;
-    props->mss = le16_to_cpu(d->tcp_seg_setup.fields.mss);
-    props->ip = (op & E1000_TXD_CMD_IP) ? 1 : 0;
-    props->tcp = (op & E1000_TXD_CMD_TCP) ? 1 : 0;
-    props->tse = (op & E1000_TXD_CMD_TSE) ? 1 : 0;
-}
diff --git a/hw/net/e1000x_common.h b/hw/net/e1000x_common.h
deleted file mode 100644 (file)
index 21bf28e..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
-* QEMU e1000(e) emulation - shared code
-*
-* Copyright (c) 2008 Qumranet
-*
-* Based on work done by:
-* Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
-* Copyright (c) 2007 Dan Aloni
-* Copyright (c) 2004 Antony T Curtis
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 2 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "e1000_regs.h"
-
-#define defreg(x)   x = (E1000_##x >> 2)
-enum {
-    defreg(CTRL),    defreg(EECD),    defreg(EERD),    defreg(GPRC),
-    defreg(GPTC),    defreg(ICR),     defreg(ICS),     defreg(IMC),
-    defreg(IMS),     defreg(LEDCTL),  defreg(MANC),    defreg(MDIC),
-    defreg(MPC),     defreg(PBA),     defreg(RCTL),    defreg(RDBAH0),
-    defreg(RDBAL0),  defreg(RDH0),    defreg(RDLEN0),  defreg(RDT0),
-    defreg(STATUS),  defreg(SWSM),    defreg(TCTL),    defreg(TDBAH),
-    defreg(TDBAL),   defreg(TDH),     defreg(TDLEN),   defreg(TDT),
-    defreg(TDLEN1),  defreg(TDBAL1),  defreg(TDBAH1),  defreg(TDH1),
-    defreg(TDT1),    defreg(TORH),    defreg(TORL),    defreg(TOTH),
-    defreg(TOTL),    defreg(TPR),     defreg(TPT),     defreg(TXDCTL),
-    defreg(WUFC),    defreg(RA),      defreg(MTA),     defreg(CRCERRS),
-    defreg(VFTA),    defreg(VET),     defreg(RDTR),    defreg(RADV),
-    defreg(TADV),    defreg(ITR),     defreg(SCC),     defreg(ECOL),
-    defreg(MCC),     defreg(LATECOL), defreg(COLC),    defreg(DC),
-    defreg(TNCRS),   defreg(SEC),     defreg(CEXTERR), defreg(RLEC),
-    defreg(XONRXC),  defreg(XONTXC),  defreg(XOFFRXC), defreg(XOFFTXC),
-    defreg(FCRUC),   defreg(AIT),     defreg(TDFH),    defreg(TDFT),
-    defreg(TDFHS),   defreg(TDFTS),   defreg(TDFPC),   defreg(WUC),
-    defreg(WUS),     defreg(POEMB),   defreg(PBS),     defreg(RDFH),
-    defreg(RDFT),    defreg(RDFHS),   defreg(RDFTS),   defreg(RDFPC),
-    defreg(PBM),     defreg(IPAV),    defreg(IP4AT),   defreg(IP6AT),
-    defreg(WUPM),    defreg(FFLT),    defreg(FFMT),    defreg(FFVT),
-    defreg(TARC0),   defreg(TARC1),   defreg(IAM),     defreg(EXTCNF_CTRL),
-    defreg(GCR),     defreg(TIMINCA), defreg(EIAC),    defreg(CTRL_EXT),
-    defreg(IVAR),    defreg(MFUTP01), defreg(MFUTP23), defreg(MANC2H),
-    defreg(MFVAL),   defreg(MDEF),    defreg(FACTPS),  defreg(FTFT),
-    defreg(RUC),     defreg(ROC),     defreg(RFC),     defreg(RJC),
-    defreg(PRC64),   defreg(PRC127),  defreg(PRC255),  defreg(PRC511),
-    defreg(PRC1023), defreg(PRC1522), defreg(PTC64),   defreg(PTC127),
-    defreg(PTC255),  defreg(PTC511),  defreg(PTC1023), defreg(PTC1522),
-    defreg(GORCL),   defreg(GORCH),   defreg(GOTCL),   defreg(GOTCH),
-    defreg(RNBC),    defreg(BPRC),    defreg(MPRC),    defreg(RFCTL),
-    defreg(PSRCTL),  defreg(MPTC),    defreg(BPTC),    defreg(TSCTFC),
-    defreg(IAC),     defreg(MGTPRC),  defreg(MGTPDC),  defreg(MGTPTC),
-    defreg(TSCTC),   defreg(RXCSUM),  defreg(FUNCTAG), defreg(GSCL_1),
-    defreg(GSCL_2),  defreg(GSCL_3),  defreg(GSCL_4),  defreg(GSCN_0),
-    defreg(GSCN_1),  defreg(GSCN_2),  defreg(GSCN_3),  defreg(GCR2),
-    defreg(RAID),    defreg(RSRPD),   defreg(TIDV),    defreg(EITR),
-    defreg(MRQC),    defreg(RETA),    defreg(RSSRK),   defreg(RDBAH1),
-    defreg(RDBAL1),  defreg(RDLEN1),  defreg(RDH1),    defreg(RDT1),
-    defreg(PBACLR),  defreg(FCAL),    defreg(FCAH),    defreg(FCT),
-    defreg(FCRTH),   defreg(FCRTL),   defreg(FCTTV),   defreg(FCRTV),
-    defreg(FLA),     defreg(EEWR),    defreg(FLOP),    defreg(FLOL),
-    defreg(FLSWCTL), defreg(FLSWCNT), defreg(RXDCTL),  defreg(RXDCTL1),
-    defreg(MAVTV0),  defreg(MAVTV1),  defreg(MAVTV2),  defreg(MAVTV3),
-    defreg(TXSTMPL), defreg(TXSTMPH), defreg(SYSTIML), defreg(SYSTIMH),
-    defreg(RXCFGL),  defreg(RXUDP),   defreg(TIMADJL), defreg(TIMADJH),
-    defreg(RXSTMPH), defreg(RXSTMPL), defreg(RXSATRL), defreg(RXSATRH),
-    defreg(FLASHT),  defreg(TIPG),    defreg(RDH),     defreg(RDT),
-    defreg(RDLEN),   defreg(RDBAH),   defreg(RDBAL),
-    defreg(TXDCTL1),
-    defreg(FLSWDATA),
-    defreg(CTRL_DUP),
-    defreg(EXTCNF_SIZE),
-    defreg(EEMNGCTL),
-    defreg(EEMNGDATA),
-    defreg(FLMNGCTL),
-    defreg(FLMNGDATA),
-    defreg(FLMNGCNT),
-    defreg(TSYNCRXCTL),
-    defreg(TSYNCTXCTL),
-
-    /* Aliases */
-    defreg(RDH0_A),  defreg(RDT0_A),  defreg(RDTR_A),  defreg(RDFH_A),
-    defreg(RDFT_A),  defreg(TDH_A),   defreg(TDT_A),   defreg(TIDV_A),
-    defreg(TDFH_A),  defreg(TDFT_A),  defreg(RA_A),    defreg(RDBAL0_A),
-    defreg(TDBAL_A), defreg(TDLEN_A), defreg(VFTA_A),  defreg(RDLEN0_A),
-    defreg(FCRTL_A), defreg(FCRTH_A)
-};
-
-static inline void
-e1000x_inc_reg_if_not_full(uint32_t *mac, int index)
-{
-    if (mac[index] != 0xffffffff) {
-        mac[index]++;
-    }
-}
-
-static inline void
-e1000x_grow_8reg_if_not_full(uint32_t *mac, int index, int size)
-{
-    uint64_t sum = mac[index] | (uint64_t)mac[index + 1] << 32;
-
-    if (sum + size < sum) {
-        sum = ~0ULL;
-    } else {
-        sum += size;
-    }
-    mac[index] = sum;
-    mac[index + 1] = sum >> 32;
-}
-
-static inline int
-e1000x_vlan_enabled(uint32_t *mac)
-{
-    return ((mac[CTRL] & E1000_CTRL_VME) != 0);
-}
-
-static inline int
-e1000x_is_vlan_txd(uint32_t txd_lower)
-{
-    return ((txd_lower & E1000_TXD_CMD_VLE) != 0);
-}
-
-static inline int
-e1000x_vlan_rx_filter_enabled(uint32_t *mac)
-{
-    return ((mac[RCTL] & E1000_RCTL_VFE) != 0);
-}
-
-static inline int
-e1000x_fcs_len(uint32_t *mac)
-{
-    /* FCS aka Ethernet CRC-32. We don't get it from backends and can't
-    * fill it in, just pad descriptor length by 4 bytes unless guest
-    * told us to strip it off the packet. */
-    return (mac[RCTL] & E1000_RCTL_SECRC) ? 0 : 4;
-}
-
-static inline void
-e1000x_update_regs_on_link_down(uint32_t *mac, uint16_t *phy)
-{
-    mac[STATUS] &= ~E1000_STATUS_LU;
-    phy[PHY_STATUS] &= ~MII_SR_LINK_STATUS;
-    phy[PHY_STATUS] &= ~MII_SR_AUTONEG_COMPLETE;
-    phy[PHY_LP_ABILITY] &= ~MII_LPAR_LPACK;
-}
-
-static inline void
-e1000x_update_regs_on_link_up(uint32_t *mac, uint16_t *phy)
-{
-    mac[STATUS] |= E1000_STATUS_LU;
-    phy[PHY_STATUS] |= MII_SR_LINK_STATUS;
-}
-
-void e1000x_update_rx_total_stats(uint32_t *mac,
-                                  size_t data_size,
-                                  size_t data_fcs_size);
-
-void e1000x_core_prepare_eeprom(uint16_t       *eeprom,
-                                const uint16_t *templ,
-                                uint32_t        templ_size,
-                                uint16_t        dev_id,
-                                const uint8_t  *macaddr);
-
-uint32_t e1000x_rxbufsize(uint32_t rctl);
-
-bool e1000x_rx_ready(PCIDevice *d, uint32_t *mac);
-
-bool e1000x_is_vlan_packet(const uint8_t *buf, uint16_t vet);
-
-bool e1000x_rx_group_filter(uint32_t *mac, const uint8_t *buf);
-
-bool e1000x_hw_rx_enabled(uint32_t *mac);
-
-bool e1000x_is_oversized(uint32_t *mac, size_t size);
-
-void e1000x_restart_autoneg(uint32_t *mac, uint16_t *phy, QEMUTimer *timer);
-
-void e1000x_reset_mac_addr(NICState *nic, uint32_t *mac_regs,
-                           uint8_t *mac_addr);
-
-void e1000x_update_regs_on_autoneg_done(uint32_t *mac, uint16_t *phy);
-
-void e1000x_increase_size_stats(uint32_t *mac, const int *size_regs, int size);
-
-typedef struct e1000x_txd_props {
-    unsigned char sum_needed;
-    uint8_t ipcss;
-    uint8_t ipcso;
-    uint16_t ipcse;
-    uint8_t tucss;
-    uint8_t tucso;
-    uint16_t tucse;
-    uint32_t paylen;
-    uint8_t hdr_len;
-    uint16_t mss;
-    int8_t ip;
-    int8_t tcp;
-    bool tse;
-    bool cptse;
-} e1000x_txd_props;
-
-void e1000x_read_tx_ctx_descr(struct e1000_context_desc *d,
-                              e1000x_txd_props *props);
index bab4dbf..9b4b9b5 100644 (file)
@@ -352,14 +352,14 @@ static unsigned e100_compute_mcast_idx(const uint8_t *ep)
 static uint16_t e100_read_reg2(EEPRO100State *s, E100RegisterOffset addr)
 {
     assert(!((uintptr_t)&s->mem[addr] & 1));
-    return lduw_le_p(&s->mem[addr]);
+    return le16_to_cpup((uint16_t *)&s->mem[addr]);
 }
 
 /* Read a 32 bit control/status (CSR) register. */
 static uint32_t e100_read_reg4(EEPRO100State *s, E100RegisterOffset addr)
 {
     assert(!((uintptr_t)&s->mem[addr] & 3));
-    return ldl_le_p(&s->mem[addr]);
+    return le32_to_cpup((uint32_t *)&s->mem[addr]);
 }
 
 /* Write a 16 bit control/status (CSR) register. */
@@ -367,7 +367,7 @@ static void e100_write_reg2(EEPRO100State *s, E100RegisterOffset addr,
                             uint16_t val)
 {
     assert(!((uintptr_t)&s->mem[addr] & 1));
-    stw_le_p(&s->mem[addr], val);
+    cpu_to_le16w((uint16_t *)&s->mem[addr], val);
 }
 
 /* Read a 32 bit control/status (CSR) register. */
@@ -375,7 +375,7 @@ static void e100_write_reg4(EEPRO100State *s, E100RegisterOffset addr,
                             uint32_t val)
 {
     assert(!((uintptr_t)&s->mem[addr] & 3));
-    stl_le_p(&s->mem[addr], val);
+    cpu_to_le32w((uint32_t *)&s->mem[addr], val);
 }
 
 #if defined(DEBUG_EEPRO100)
@@ -1848,7 +1848,7 @@ static void pci_nic_uninit(PCIDevice *pci_dev)
 }
 
 static NetClientInfo net_eepro100_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = nic_receive,
 };
index efaa49f..05495ec 100644 (file)
@@ -578,7 +578,7 @@ static const MemoryRegionOps eth_ops = {
 };
 
 static NetClientInfo net_etraxfs_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = eth_receive,
     .link_status_changed = eth_set_link,
index b5c777f..1e35f7f 100644 (file)
@@ -33,7 +33,6 @@
 #include "hw/ptimer.h"
 #include "etsec.h"
 #include "registers.h"
-#include "qemu/log.h"
 
 /* #define HEX_DUMP */
 /* #define DEBUG_REGISTER */
@@ -371,7 +370,7 @@ static void etsec_set_link_status(NetClientState *nc)
 }
 
 static NetClientInfo net_etsec_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = etsec_receive,
     .link_status_changed = etsec_set_link_status,
index 30c828e..e7dc0a4 100644 (file)
@@ -21,9 +21,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
-#ifndef ETSEC_H
-#define ETSEC_H
+#ifndef _ETSEC_H_
+#define _ETSEC_H_
 
 #include "hw/qdev.h"
 #include "hw/sysbus.h"
@@ -174,4 +173,4 @@ void etsec_write_miim(eTSEC          *etsec,
 
 void etsec_miim_link_status(eTSEC *etsec, NetClientState *nc);
 
-#endif /* ETSEC_H */
+#endif /* ! _ETSEC_H_ */
index c4ed2b9..6fb9684 100644 (file)
@@ -21,9 +21,9 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+#ifndef _ETSEC_REGISTERS_H_
+#define _ETSEC_REGISTERS_H_
 
-#ifndef ETSEC_REGISTERS_H
-#define ETSEC_REGISTERS_H
 
 enum eTSEC_Register_Access_Type {
     ACC_RW      = 1,            /* Read/Write */
@@ -316,4 +316,4 @@ extern const eTSEC_Register_Definition eTSEC_registers_def[];
 #define TMR_ETTS2_H  (0xEA8 / 4)
 #define TMR_ETTS2_L  (0xEAC / 4)
 
-#endif /* ETSEC_REGISTERS_H */
+#endif /* ! _ETSEC_REGISTERS_H_ */
index 79d2f14..ed1de7d 100644 (file)
@@ -23,7 +23,7 @@
  */
 #include "qemu/osdep.h"
 #include "net/checksum.h"
-#include "qemu/log.h"
+
 #include "etsec.h"
 #include "registers.h"
 
index 1c415ab..e60e338 100644 (file)
@@ -24,9 +24,6 @@
 #include "qemu/osdep.h"
 #include "hw/net/imx_fec.h"
 #include "sysemu/dma.h"
-#include "qemu/log.h"
-#include "net/checksum.h"
-#include "net/eth.h"
 
 /* For crc32 */
 #include <zlib.h>
         } \
     } while (0)
 
-static const char *imx_default_reg_name(IMXFECState *s, uint32_t index)
-{
-    static char tmp[20];
-    sprintf(tmp, "index %d", index);
-    return tmp;
-}
-
-static const char *imx_fec_reg_name(IMXFECState *s, uint32_t index)
-{
-    switch (index) {
-    case ENET_FRBR:
-        return "FRBR";
-    case ENET_FRSR:
-        return "FRSR";
-    case ENET_MIIGSK_CFGR:
-        return "MIIGSK_CFGR";
-    case ENET_MIIGSK_ENR:
-        return "MIIGSK_ENR";
-    default:
-        return imx_default_reg_name(s, index);
-    }
-}
-
-static const char *imx_enet_reg_name(IMXFECState *s, uint32_t index)
-{
-    switch (index) {
-    case ENET_RSFL:
-        return "RSFL";
-    case ENET_RSEM:
-        return "RSEM";
-    case ENET_RAEM:
-        return "RAEM";
-    case ENET_RAFL:
-        return "RAFL";
-    case ENET_TSEM:
-        return "TSEM";
-    case ENET_TAEM:
-        return "TAEM";
-    case ENET_TAFL:
-        return "TAFL";
-    case ENET_TIPG:
-        return "TIPG";
-    case ENET_FTRL:
-        return "FTRL";
-    case ENET_TACC:
-        return "TACC";
-    case ENET_RACC:
-        return "RACC";
-    case ENET_ATCR:
-        return "ATCR";
-    case ENET_ATVR:
-        return "ATVR";
-    case ENET_ATOFF:
-        return "ATOFF";
-    case ENET_ATPER:
-        return "ATPER";
-    case ENET_ATCOR:
-        return "ATCOR";
-    case ENET_ATINC:
-        return "ATINC";
-    case ENET_ATSTMP:
-        return "ATSTMP";
-    case ENET_TGSR:
-        return "TGSR";
-    case ENET_TCSR0:
-        return "TCSR0";
-    case ENET_TCCR0:
-        return "TCCR0";
-    case ENET_TCSR1:
-        return "TCSR1";
-    case ENET_TCCR1:
-        return "TCCR1";
-    case ENET_TCSR2:
-        return "TCSR2";
-    case ENET_TCCR2:
-        return "TCCR2";
-    case ENET_TCSR3:
-        return "TCSR3";
-    case ENET_TCCR3:
-        return "TCCR3";
-    default:
-        return imx_default_reg_name(s, index);
-    }
-}
-
-static const char *imx_eth_reg_name(IMXFECState *s, uint32_t index)
-{
-    switch (index) {
-    case ENET_EIR:
-        return "EIR";
-    case ENET_EIMR:
-        return "EIMR";
-    case ENET_RDAR:
-        return "RDAR";
-    case ENET_TDAR:
-        return "TDAR";
-    case ENET_ECR:
-        return "ECR";
-    case ENET_MMFR:
-        return "MMFR";
-    case ENET_MSCR:
-        return "MSCR";
-    case ENET_MIBC:
-        return "MIBC";
-    case ENET_RCR:
-        return "RCR";
-    case ENET_TCR:
-        return "TCR";
-    case ENET_PALR:
-        return "PALR";
-    case ENET_PAUR:
-        return "PAUR";
-    case ENET_OPD:
-        return "OPD";
-    case ENET_IAUR:
-        return "IAUR";
-    case ENET_IALR:
-        return "IALR";
-    case ENET_GAUR:
-        return "GAUR";
-    case ENET_GALR:
-        return "GALR";
-    case ENET_TFWR:
-        return "TFWR";
-    case ENET_RDSR:
-        return "RDSR";
-    case ENET_TDSR:
-        return "TDSR";
-    case ENET_MRBR:
-        return "MRBR";
-    default:
-        if (s->is_fec) {
-            return imx_fec_reg_name(s, index);
-        } else {
-            return imx_enet_reg_name(s, index);
-        }
-    }
-}
-
-static const VMStateDescription vmstate_imx_eth = {
+static const VMStateDescription vmstate_imx_fec = {
     .name = TYPE_IMX_FEC,
-    .version_id = 2,
-    .minimum_version_id = 2,
+    .version_id = 1,
+    .minimum_version_id = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
+        VMSTATE_UINT32(irq_state, IMXFECState),
+        VMSTATE_UINT32(eir, IMXFECState),
+        VMSTATE_UINT32(eimr, IMXFECState),
+        VMSTATE_UINT32(rx_enabled, IMXFECState),
         VMSTATE_UINT32(rx_descriptor, IMXFECState),
         VMSTATE_UINT32(tx_descriptor, IMXFECState),
+        VMSTATE_UINT32(ecr, IMXFECState),
+        VMSTATE_UINT32(mmfr, IMXFECState),
+        VMSTATE_UINT32(mscr, IMXFECState),
+        VMSTATE_UINT32(mibc, IMXFECState),
+        VMSTATE_UINT32(rcr, IMXFECState),
+        VMSTATE_UINT32(tcr, IMXFECState),
+        VMSTATE_UINT32(tfwr, IMXFECState),
+        VMSTATE_UINT32(frsr, IMXFECState),
+        VMSTATE_UINT32(erdsr, IMXFECState),
+        VMSTATE_UINT32(etdsr, IMXFECState),
+        VMSTATE_UINT32(emrbr, IMXFECState),
+        VMSTATE_UINT32(miigsk_cfgr, IMXFECState),
+        VMSTATE_UINT32(miigsk_enr, IMXFECState),
 
         VMSTATE_UINT32(phy_status, IMXFECState),
         VMSTATE_UINT32(phy_control, IMXFECState),
@@ -220,7 +94,7 @@ static const VMStateDescription vmstate_imx_eth = {
 #define PHY_INT_PARFAULT            (1 << 2)
 #define PHY_INT_AUTONEG_PAGE        (1 << 1)
 
-static void imx_eth_update(IMXFECState *s);
+static void imx_fec_update(IMXFECState *s);
 
 /*
  * The MII phy could raise a GPIO to the processor which in turn
@@ -230,7 +104,7 @@ static void imx_eth_update(IMXFECState *s);
  */
 static void phy_update_irq(IMXFECState *s)
 {
-    imx_eth_update(s);
+    imx_fec_update(s);
 }
 
 static void phy_update_link(IMXFECState *s)
@@ -249,7 +123,7 @@ static void phy_update_link(IMXFECState *s)
     phy_update_irq(s);
 }
 
-static void imx_eth_set_link(NetClientState *nc)
+static void imx_fec_set_link(NetClientState *nc)
 {
     phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
 }
@@ -375,35 +249,23 @@ static void imx_fec_write_bd(IMXFECBufDesc *bd, dma_addr_t addr)
     dma_memory_write(&address_space_memory, addr, bd, sizeof(*bd));
 }
 
-static void imx_enet_read_bd(IMXENETBufDesc *bd, dma_addr_t addr)
+static void imx_fec_update(IMXFECState *s)
 {
-    dma_memory_read(&address_space_memory, addr, bd, sizeof(*bd));
-}
+    uint32_t active;
+    uint32_t changed;
 
-static void imx_enet_write_bd(IMXENETBufDesc *bd, dma_addr_t addr)
-{
-    dma_memory_write(&address_space_memory, addr, bd, sizeof(*bd));
-}
-
-static void imx_eth_update(IMXFECState *s)
-{
-    if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_TS_TIMER) {
-        qemu_set_irq(s->irq[1], 1);
-    } else {
-        qemu_set_irq(s->irq[1], 0);
-    }
-
-    if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_MAC) {
-        qemu_set_irq(s->irq[0], 1);
-    } else {
-        qemu_set_irq(s->irq[0], 0);
+    active = s->eir & s->eimr;
+    changed = active ^ s->irq_state;
+    if (changed) {
+        qemu_set_irq(s->irq, active);
     }
+    s->irq_state = active;
 }
 
 static void imx_fec_do_tx(IMXFECState *s)
 {
     int frame_size = 0;
-    uint8_t frame[ENET_MAX_FRAME_SIZE];
+    uint8_t frame[FEC_MAX_FRAME_SIZE];
     uint8_t *ptr = frame;
     uint32_t addr = s->tx_descriptor;
 
@@ -414,521 +276,272 @@ static void imx_fec_do_tx(IMXFECState *s)
         imx_fec_read_bd(&bd, addr);
         FEC_PRINTF("tx_bd %x flags %04x len %d data %08x\n",
                    addr, bd.flags, bd.length, bd.data);
-        if ((bd.flags & ENET_BD_R) == 0) {
+        if ((bd.flags & FEC_BD_R) == 0) {
             /* Run out of descriptors to transmit.  */
-            FEC_PRINTF("tx_bd ran out of descriptors to transmit\n");
             break;
         }
         len = bd.length;
-        if (frame_size + len > ENET_MAX_FRAME_SIZE) {
-            len = ENET_MAX_FRAME_SIZE - frame_size;
-            s->regs[ENET_EIR] |= ENET_INT_BABT;
+        if (frame_size + len > FEC_MAX_FRAME_SIZE) {
+            len = FEC_MAX_FRAME_SIZE - frame_size;
+            s->eir |= FEC_INT_BABT;
         }
         dma_memory_read(&address_space_memory, bd.data, ptr, len);
         ptr += len;
         frame_size += len;
-        if (bd.flags & ENET_BD_L) {
+        if (bd.flags & FEC_BD_L) {
             /* Last buffer in frame.  */
             qemu_send_packet(qemu_get_queue(s->nic), frame, len);
             ptr = frame;
             frame_size = 0;
-            s->regs[ENET_EIR] |= ENET_INT_TXF;
+            s->eir |= FEC_INT_TXF;
         }
-        s->regs[ENET_EIR] |= ENET_INT_TXB;
-        bd.flags &= ~ENET_BD_R;
+        s->eir |= FEC_INT_TXB;
+        bd.flags &= ~FEC_BD_R;
         /* Write back the modified descriptor.  */
         imx_fec_write_bd(&bd, addr);
         /* Advance to the next descriptor.  */
-        if ((bd.flags & ENET_BD_W) != 0) {
-            addr = s->regs[ENET_TDSR];
+        if ((bd.flags & FEC_BD_W) != 0) {
+            addr = s->etdsr;
         } else {
-            addr += sizeof(bd);
+            addr += 8;
         }
     }
 
     s->tx_descriptor = addr;
 
-    imx_eth_update(s);
+    imx_fec_update(s);
 }
 
-static void imx_enet_do_tx(IMXFECState *s)
-{
-    int frame_size = 0;
-    uint8_t frame[ENET_MAX_FRAME_SIZE];
-    uint8_t *ptr = frame;
-    uint32_t addr = s->tx_descriptor;
-
-    while (1) {
-        IMXENETBufDesc bd;
-        int len;
-
-        imx_enet_read_bd(&bd, addr);
-        FEC_PRINTF("tx_bd %x flags %04x len %d data %08x option %04x "
-                   "status %04x\n", addr, bd.flags, bd.length, bd.data,
-                   bd.option, bd.status);
-        if ((bd.flags & ENET_BD_R) == 0) {
-            /* Run out of descriptors to transmit.  */
-            break;
-        }
-        len = bd.length;
-        if (frame_size + len > ENET_MAX_FRAME_SIZE) {
-            len = ENET_MAX_FRAME_SIZE - frame_size;
-            s->regs[ENET_EIR] |= ENET_INT_BABT;
-        }
-        dma_memory_read(&address_space_memory, bd.data, ptr, len);
-        ptr += len;
-        frame_size += len;
-        if (bd.flags & ENET_BD_L) {
-            if (bd.option & ENET_BD_PINS) {
-                struct ip_header *ip_hd = PKT_GET_IP_HDR(frame);
-                if (IP_HEADER_VERSION(ip_hd) == 4) {
-                    net_checksum_calculate(frame, frame_size);
-                }
-            }
-            if (bd.option & ENET_BD_IINS) {
-                struct ip_header *ip_hd = PKT_GET_IP_HDR(frame);
-                /* We compute checksum only for IPv4 frames */
-                if (IP_HEADER_VERSION(ip_hd) == 4) {
-                    uint16_t csum;
-                    ip_hd->ip_sum = 0;
-                    csum = net_raw_checksum((uint8_t *)ip_hd, sizeof(*ip_hd));
-                    ip_hd->ip_sum = cpu_to_be16(csum);
-                }
-            }
-            /* Last buffer in frame.  */
-            qemu_send_packet(qemu_get_queue(s->nic), frame, len);
-            ptr = frame;
-            frame_size = 0;
-            if (bd.option & ENET_BD_TX_INT) {
-                s->regs[ENET_EIR] |= ENET_INT_TXF;
-            }
-        }
-        if (bd.option & ENET_BD_TX_INT) {
-            s->regs[ENET_EIR] |= ENET_INT_TXB;
-        }
-        bd.flags &= ~ENET_BD_R;
-        /* Write back the modified descriptor.  */
-        imx_enet_write_bd(&bd, addr);
-        /* Advance to the next descriptor.  */
-        if ((bd.flags & ENET_BD_W) != 0) {
-            addr = s->regs[ENET_TDSR];
-        } else {
-            addr += sizeof(bd);
-        }
-    }
-
-    s->tx_descriptor = addr;
-
-    imx_eth_update(s);
-}
-
-static void imx_eth_do_tx(IMXFECState *s)
-{
-    if (!s->is_fec && (s->regs[ENET_ECR] & ENET_ECR_EN1588)) {
-        imx_enet_do_tx(s);
-    } else {
-        imx_fec_do_tx(s);
-    }
-}
-
-static void imx_eth_enable_rx(IMXFECState *s)
+static void imx_fec_enable_rx(IMXFECState *s)
 {
     IMXFECBufDesc bd;
-    bool tmp;
+    uint32_t tmp;
 
     imx_fec_read_bd(&bd, s->rx_descriptor);
 
-    tmp = ((bd.flags & ENET_BD_E) != 0);
+    tmp = ((bd.flags & FEC_BD_E) != 0);
 
     if (!tmp) {
         FEC_PRINTF("RX buffer full\n");
-    } else if (!s->regs[ENET_RDAR]) {
+    } else if (!s->rx_enabled) {
         qemu_flush_queued_packets(qemu_get_queue(s->nic));
     }
 
-    s->regs[ENET_RDAR] = tmp ? ENET_RDAR_RDAR : 0;
+    s->rx_enabled = tmp;
 }
 
-static void imx_eth_reset(DeviceState *d)
+static void imx_fec_reset(DeviceState *d)
 {
     IMXFECState *s = IMX_FEC(d);
 
-    /* Reset the Device */
-    memset(s->regs, 0, sizeof(s->regs));
-    s->regs[ENET_ECR]   = 0xf0000000;
-    s->regs[ENET_MIBC]  = 0xc0000000;
-    s->regs[ENET_RCR]   = 0x05ee0001;
-    s->regs[ENET_OPD]   = 0x00010000;
-
-    s->regs[ENET_PALR]  = (s->conf.macaddr.a[0] << 24)
-                          | (s->conf.macaddr.a[1] << 16)
-                          | (s->conf.macaddr.a[2] << 8)
-                          | s->conf.macaddr.a[3];
-    s->regs[ENET_PAUR]  = (s->conf.macaddr.a[4] << 24)
-                          | (s->conf.macaddr.a[5] << 16)
-                          | 0x8808;
-
-    if (s->is_fec) {
-        s->regs[ENET_FRBR]  = 0x00000600;
-        s->regs[ENET_FRSR]  = 0x00000500;
-        s->regs[ENET_MIIGSK_ENR]  = 0x00000006;
-    } else {
-        s->regs[ENET_RAEM]  = 0x00000004;
-        s->regs[ENET_RAFL]  = 0x00000004;
-        s->regs[ENET_TAEM]  = 0x00000004;
-        s->regs[ENET_TAFL]  = 0x00000008;
-        s->regs[ENET_TIPG]  = 0x0000000c;
-        s->regs[ENET_FTRL]  = 0x000007ff;
-        s->regs[ENET_ATPER] = 0x3b9aca00;
-    }
-
-    s->rx_descriptor = 0;
-    s->tx_descriptor = 0;
+    /* Reset the FEC */
+    s->eir = 0;
+    s->eimr = 0;
+    s->rx_enabled = 0;
+    s->ecr = 0;
+    s->mscr = 0;
+    s->mibc = 0xc0000000;
+    s->rcr = 0x05ee0001;
+    s->tcr = 0;
+    s->tfwr = 0;
+    s->frsr = 0x500;
+    s->miigsk_cfgr = 0;
+    s->miigsk_enr = 0x6;
 
     /* We also reset the PHY */
     phy_reset(s);
 }
 
-static uint32_t imx_default_read(IMXFECState *s, uint32_t index)
-{
-    qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
-                  PRIx32 "\n", TYPE_IMX_FEC, __func__, index * 4);
-    return 0;
-}
-
-static uint32_t imx_fec_read(IMXFECState *s, uint32_t index)
-{
-    switch (index) {
-    case ENET_FRBR:
-    case ENET_FRSR:
-    case ENET_MIIGSK_CFGR:
-    case ENET_MIIGSK_ENR:
-        return s->regs[index];
-    default:
-        return imx_default_read(s, index);
-    }
-}
-
-static uint32_t imx_enet_read(IMXFECState *s, uint32_t index)
+static uint64_t imx_fec_read(void *opaque, hwaddr addr, unsigned size)
 {
-    switch (index) {
-    case ENET_RSFL:
-    case ENET_RSEM:
-    case ENET_RAEM:
-    case ENET_RAFL:
-    case ENET_TSEM:
-    case ENET_TAEM:
-    case ENET_TAFL:
-    case ENET_TIPG:
-    case ENET_FTRL:
-    case ENET_TACC:
-    case ENET_RACC:
-    case ENET_ATCR:
-    case ENET_ATVR:
-    case ENET_ATOFF:
-    case ENET_ATPER:
-    case ENET_ATCOR:
-    case ENET_ATINC:
-    case ENET_ATSTMP:
-    case ENET_TGSR:
-    case ENET_TCSR0:
-    case ENET_TCCR0:
-    case ENET_TCSR1:
-    case ENET_TCCR1:
-    case ENET_TCSR2:
-    case ENET_TCCR2:
-    case ENET_TCSR3:
-    case ENET_TCCR3:
-        return s->regs[index];
-    default:
-        return imx_default_read(s, index);
-    }
-}
-
-static uint64_t imx_eth_read(void *opaque, hwaddr offset, unsigned size)
-{
-    uint32_t value = 0;
     IMXFECState *s = IMX_FEC(opaque);
-    uint32_t index = offset >> 2;
-
-    switch (index) {
-    case ENET_EIR:
-    case ENET_EIMR:
-    case ENET_RDAR:
-    case ENET_TDAR:
-    case ENET_ECR:
-    case ENET_MMFR:
-    case ENET_MSCR:
-    case ENET_MIBC:
-    case ENET_RCR:
-    case ENET_TCR:
-    case ENET_PALR:
-    case ENET_PAUR:
-    case ENET_OPD:
-    case ENET_IAUR:
-    case ENET_IALR:
-    case ENET_GAUR:
-    case ENET_GALR:
-    case ENET_TFWR:
-    case ENET_RDSR:
-    case ENET_TDSR:
-    case ENET_MRBR:
-        value = s->regs[index];
-        break;
-    default:
-        if (s->is_fec) {
-            value = imx_fec_read(s, index);
-        } else {
-            value = imx_enet_read(s, index);
-        }
-        break;
-    }
-
-    FEC_PRINTF("reg[%s] => 0x%" PRIx32 "\n", imx_eth_reg_name(s, index),
-                                              value);
-
-    return value;
-}
-
-static void imx_default_write(IMXFECState *s, uint32_t index, uint32_t value)
-{
-    qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
-                  PRIx32 "\n", TYPE_IMX_FEC, __func__, index * 4);
-    return;
-}
-
-static void imx_fec_write(IMXFECState *s, uint32_t index, uint32_t value)
-{
-    switch (index) {
-    case ENET_FRBR:
-        /* FRBR is read only */
-        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Register FRBR is read only\n",
-                      TYPE_IMX_FEC, __func__);
-        break;
-    case ENET_FRSR:
-        s->regs[index] = (value & 0x000003fc) | 0x00000400;
-        break;
-    case ENET_MIIGSK_CFGR:
-        s->regs[index] = value & 0x00000053;
-        break;
-    case ENET_MIIGSK_ENR:
-        s->regs[index] = (value & 0x00000002) ? 0x00000006 : 0;
-        break;
-    default:
-        imx_default_write(s, index, value);
-        break;
-    }
-}
 
-static void imx_enet_write(IMXFECState *s, uint32_t index, uint32_t value)
-{
-    switch (index) {
-    case ENET_RSFL:
-    case ENET_RSEM:
-    case ENET_RAEM:
-    case ENET_RAFL:
-    case ENET_TSEM:
-    case ENET_TAEM:
-    case ENET_TAFL:
-        s->regs[index] = value & 0x000001ff;
-        break;
-    case ENET_TIPG:
-        s->regs[index] = value & 0x0000001f;
-        break;
-    case ENET_FTRL:
-        s->regs[index] = value & 0x00003fff;
-        break;
-    case ENET_TACC:
-        s->regs[index] = value & 0x00000019;
-        break;
-    case ENET_RACC:
-        s->regs[index] = value & 0x000000C7;
-        break;
-    case ENET_ATCR:
-        s->regs[index] = value & 0x00002a9d;
-        break;
-    case ENET_ATVR:
-    case ENET_ATOFF:
-    case ENET_ATPER:
-        s->regs[index] = value;
-        break;
-    case ENET_ATSTMP:
-        /* ATSTMP is read only */
-        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Register ATSTMP is read only\n",
-                      TYPE_IMX_FEC, __func__);
-        break;
-    case ENET_ATCOR:
-        s->regs[index] = value & 0x7fffffff;
-        break;
-    case ENET_ATINC:
-        s->regs[index] = value & 0x00007f7f;
-        break;
-    case ENET_TGSR:
-        /* implement clear timer flag */
-        value = value & 0x0000000f;
-        break;
-    case ENET_TCSR0:
-    case ENET_TCSR1:
-    case ENET_TCSR2:
-    case ENET_TCSR3:
-        value = value & 0x000000fd;
-        break;
-    case ENET_TCCR0:
-    case ENET_TCCR1:
-    case ENET_TCCR2:
-    case ENET_TCCR3:
-        s->regs[index] = value;
-        break;
+    FEC_PRINTF("reading from @ 0x%" HWADDR_PRIx "\n", addr);
+
+    switch (addr & 0x3ff) {
+    case 0x004:
+        return s->eir;
+    case 0x008:
+        return s->eimr;
+    case 0x010:
+        return s->rx_enabled ? (1 << 24) : 0;   /* RDAR */
+    case 0x014:
+        return 0;   /* TDAR */
+    case 0x024:
+        return s->ecr;
+    case 0x040:
+        return s->mmfr;
+    case 0x044:
+        return s->mscr;
+    case 0x064:
+        return s->mibc; /* MIBC */
+    case 0x084:
+        return s->rcr;
+    case 0x0c4:
+        return s->tcr;
+    case 0x0e4:     /* PALR */
+        return (s->conf.macaddr.a[0] << 24)
+               | (s->conf.macaddr.a[1] << 16)
+               | (s->conf.macaddr.a[2] << 8)
+               | s->conf.macaddr.a[3];
+        break;
+    case 0x0e8:     /* PAUR */
+        return (s->conf.macaddr.a[4] << 24)
+               | (s->conf.macaddr.a[5] << 16)
+               | 0x8808;
+    case 0x0ec:
+        return 0x10000; /* OPD */
+    case 0x118:
+        return 0;
+    case 0x11c:
+        return 0;
+    case 0x120:
+        return 0;
+    case 0x124:
+        return 0;
+    case 0x144:
+        return s->tfwr;
+    case 0x14c:
+        return 0x600;
+    case 0x150:
+        return s->frsr;
+    case 0x180:
+        return s->erdsr;
+    case 0x184:
+        return s->etdsr;
+    case 0x188:
+        return s->emrbr;
+    case 0x300:
+        return s->miigsk_cfgr;
+    case 0x308:
+        return s->miigsk_enr;
     default:
-        imx_default_write(s, index, value);
-        break;
+        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
+                      HWADDR_PRIx "\n", TYPE_IMX_FEC, __func__, addr);
+        return 0;
     }
 }
 
-static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
-                           unsigned size)
+static void imx_fec_write(void *opaque, hwaddr addr,
+                          uint64_t value, unsigned size)
 {
     IMXFECState *s = IMX_FEC(opaque);
-    uint32_t index = offset >> 2;
 
-    FEC_PRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx_eth_reg_name(s, index),
-                (uint32_t)value);
+    FEC_PRINTF("writing 0x%08x @ 0x%" HWADDR_PRIx "\n", (int)value, addr);
 
-    switch (index) {
-    case ENET_EIR:
-        s->regs[index] &= ~value;
+    switch (addr & 0x3ff) {
+    case 0x004: /* EIR */
+        s->eir &= ~value;
         break;
-    case ENET_EIMR:
-        s->regs[index] = value;
+    case 0x008: /* EIMR */
+        s->eimr = value;
         break;
-    case ENET_RDAR:
-        if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
-            if (!s->regs[index]) {
-                s->regs[index] = ENET_RDAR_RDAR;
-                imx_eth_enable_rx(s);
-            }
-        } else {
-            s->regs[index] = 0;
+    case 0x010: /* RDAR */
+        if ((s->ecr & FEC_EN) && !s->rx_enabled) {
+            imx_fec_enable_rx(s);
         }
         break;
-    case ENET_TDAR:
-        if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
-            s->regs[index] = ENET_TDAR_TDAR;
-            imx_eth_do_tx(s);
+    case 0x014: /* TDAR */
+        if (s->ecr & FEC_EN) {
+            imx_fec_do_tx(s);
         }
-        s->regs[index] = 0;
         break;
-    case ENET_ECR:
-        if (value & ENET_ECR_RESET) {
-            return imx_eth_reset(DEVICE(s));
+    case 0x024: /* ECR */
+        s->ecr = value;
+        if (value & FEC_RESET) {
+            imx_fec_reset(DEVICE(s));
         }
-        s->regs[index] = value;
-        if ((s->regs[index] & ENET_ECR_ETHEREN) == 0) {
-            s->regs[ENET_RDAR] = 0;
-            s->rx_descriptor = s->regs[ENET_RDSR];
-            s->regs[ENET_TDAR] = 0;
-            s->tx_descriptor = s->regs[ENET_TDSR];
+        if ((s->ecr & FEC_EN) == 0) {
+            s->rx_enabled = 0;
         }
         break;
-    case ENET_MMFR:
-        s->regs[index] = value;
-        if (extract32(value, 29, 1)) {
-            /* This is a read operation */
-            s->regs[ENET_MMFR] = deposit32(s->regs[ENET_MMFR], 0, 16,
-                                           do_phy_read(s,
-                                                       extract32(value,
-                                                                 18, 10)));
+    case 0x040: /* MMFR */
+        /* store the value */
+        s->mmfr = value;
+        if (extract32(value, 28, 1)) {
+            do_phy_write(s, extract32(value, 18, 9), extract32(value, 0, 16));
         } else {
-            /* This a write operation */
-            do_phy_write(s, extract32(value, 18, 10), extract32(value, 0, 16));
+            s->mmfr = do_phy_read(s, extract32(value, 18, 9));
         }
         /* raise the interrupt as the PHY operation is done */
-        s->regs[ENET_EIR] |= ENET_INT_MII;
+        s->eir |= FEC_INT_MII;
         break;
-    case ENET_MSCR:
-        s->regs[index] = value & 0xfe;
+    case 0x044: /* MSCR */
+        s->mscr = value & 0xfe;
         break;
-    case ENET_MIBC:
+    case 0x064: /* MIBC */
         /* TODO: Implement MIB.  */
-        s->regs[index] = (value & 0x80000000) ? 0xc0000000 : 0;
+        s->mibc = (value & 0x80000000) ? 0xc0000000 : 0;
         break;
-    case ENET_RCR:
-        s->regs[index] = value & 0x07ff003f;
+    case 0x084: /* RCR */
+        s->rcr = value & 0x07ff003f;
         /* TODO: Implement LOOP mode.  */
         break;
-    case ENET_TCR:
+    case 0x0c4: /* TCR */
         /* We transmit immediately, so raise GRA immediately.  */
-        s->regs[index] = value;
+        s->tcr = value;
         if (value & 1) {
-            s->regs[ENET_EIR] |= ENET_INT_GRA;
+            s->eir |= FEC_INT_GRA;
         }
         break;
-    case ENET_PALR:
-        s->regs[index] = value;
+    case 0x0e4: /* PALR */
         s->conf.macaddr.a[0] = value >> 24;
         s->conf.macaddr.a[1] = value >> 16;
         s->conf.macaddr.a[2] = value >> 8;
         s->conf.macaddr.a[3] = value;
         break;
-    case ENET_PAUR:
-        s->regs[index] = (value | 0x0000ffff) & 0xffff8808;
+    case 0x0e8: /* PAUR */
         s->conf.macaddr.a[4] = value >> 24;
         s->conf.macaddr.a[5] = value >> 16;
         break;
-    case ENET_OPD:
-        s->regs[index] = (value & 0x0000ffff) | 0x00010000;
+    case 0x0ec: /* OPDR */
         break;
-    case ENET_IAUR:
-    case ENET_IALR:
-    case ENET_GAUR:
-    case ENET_GALR:
+    case 0x118: /* IAUR */
+    case 0x11c: /* IALR */
+    case 0x120: /* GAUR */
+    case 0x124: /* GALR */
         /* TODO: implement MAC hash filtering.  */
         break;
-    case ENET_TFWR:
-        if (s->is_fec) {
-            s->regs[index] = value & 0x3;
-        } else {
-            s->regs[index] = value & 0x13f;
-        }
+    case 0x144: /* TFWR */
+        s->tfwr = value & 3;
         break;
-    case ENET_RDSR:
-        if (s->is_fec) {
-            s->regs[index] = value & ~3;
-        } else {
-            s->regs[index] = value & ~7;
-        }
-        s->rx_descriptor = s->regs[index];
+    case 0x14c: /* FRBR */
+        /* FRBR writes ignored.  */
         break;
-    case ENET_TDSR:
-        if (s->is_fec) {
-            s->regs[index] = value & ~3;
-        } else {
-            s->regs[index] = value & ~7;
-        }
-        s->tx_descriptor = s->regs[index];
+    case 0x150: /* FRSR */
+        s->frsr = (value & 0x3fc) | 0x400;
+        break;
+    case 0x180: /* ERDSR */
+        s->erdsr = value & ~3;
+        s->rx_descriptor = s->erdsr;
         break;
-    case ENET_MRBR:
-        s->regs[index] = value & 0x00003ff0;
+    case 0x184: /* ETDSR */
+        s->etdsr = value & ~3;
+        s->tx_descriptor = s->etdsr;
+        break;
+    case 0x188: /* EMRBR */
+        s->emrbr = value & 0x7f0;
+        break;
+    case 0x300: /* MIIGSK_CFGR */
+        s->miigsk_cfgr = value & 0x53;
+        break;
+    case 0x308: /* MIIGSK_ENR */
+        s->miigsk_enr = (value & 0x2) ? 0x6 : 0;
         break;
     default:
-        if (s->is_fec) {
-            imx_fec_write(s, index, value);
-        } else {
-            imx_enet_write(s, index, value);
-        }
-        return;
+        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
+                      HWADDR_PRIx "\n", TYPE_IMX_FEC, __func__, addr);
+        break;
     }
 
-    imx_eth_update(s);
+    imx_fec_update(s);
 }
 
-static int imx_eth_can_receive(NetClientState *nc)
+static int imx_fec_can_receive(NetClientState *nc)
 {
     IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));
 
-    FEC_PRINTF("\n");
-
-    return s->regs[ENET_RDAR] ? 1 : 0;
+    return s->rx_enabled;
 }
 
 static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
@@ -946,7 +559,7 @@ static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
 
     FEC_PRINTF("len %d\n", (int)size);
 
-    if (!s->regs[ENET_RDAR]) {
+    if (!s->rx_enabled) {
         qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Unexpected packet\n",
                       TYPE_IMX_FEC, __func__);
         return 0;
@@ -957,21 +570,21 @@ static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
     crc = cpu_to_be32(crc32(~0, buf, size));
     crc_ptr = (uint8_t *) &crc;
 
-    /* Huge frames are truncated.  */
-    if (size > ENET_MAX_FRAME_SIZE) {
-        size = ENET_MAX_FRAME_SIZE;
-        flags |= ENET_BD_TR | ENET_BD_LG;
+    /* Huge frames are truncted.  */
+    if (size > FEC_MAX_FRAME_SIZE) {
+        size = FEC_MAX_FRAME_SIZE;
+        flags |= FEC_BD_TR | FEC_BD_LG;
     }
 
     /* Frames larger than the user limit just set error flags.  */
-    if (size > (s->regs[ENET_RCR] >> 16)) {
-        flags |= ENET_BD_LG;
+    if (size > (s->rcr >> 16)) {
+        flags |= FEC_BD_LG;
     }
 
     addr = s->rx_descriptor;
     while (size > 0) {
         imx_fec_read_bd(&bd, addr);
-        if ((bd.flags & ENET_BD_E) == 0) {
+        if ((bd.flags & FEC_BD_E) == 0) {
             /* No descriptors available.  Bail out.  */
             /*
              * FIXME: This is wrong. We should probably either
@@ -982,7 +595,7 @@ static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
                           TYPE_IMX_FEC, __func__);
             break;
         }
-        buf_len = (size <= s->regs[ENET_MRBR]) ? size : s->regs[ENET_MRBR];
+        buf_len = (size <= s->emrbr) ? size : s->emrbr;
         bd.length = buf_len;
         size -= buf_len;
 
@@ -1000,232 +613,99 @@ static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
                              crc_ptr, 4 - size);
             crc_ptr += 4 - size;
         }
-        bd.flags &= ~ENET_BD_E;
+        bd.flags &= ~FEC_BD_E;
         if (size == 0) {
             /* Last buffer in frame.  */
-            bd.flags |= flags | ENET_BD_L;
+            bd.flags |= flags | FEC_BD_L;
             FEC_PRINTF("rx frame flags %04x\n", bd.flags);
-            s->regs[ENET_EIR] |= ENET_INT_RXF;
+            s->eir |= FEC_INT_RXF;
         } else {
-            s->regs[ENET_EIR] |= ENET_INT_RXB;
+            s->eir |= FEC_INT_RXB;
         }
         imx_fec_write_bd(&bd, addr);
         /* Advance to the next descriptor.  */
-        if ((bd.flags & ENET_BD_W) != 0) {
-            addr = s->regs[ENET_RDSR];
-        } else {
-            addr += sizeof(bd);
-        }
-    }
-    s->rx_descriptor = addr;
-    imx_eth_enable_rx(s);
-    imx_eth_update(s);
-    return len;
-}
-
-static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
-                                size_t len)
-{
-    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));
-    IMXENETBufDesc bd;
-    uint32_t flags = 0;
-    uint32_t addr;
-    uint32_t crc;
-    uint32_t buf_addr;
-    uint8_t *crc_ptr;
-    unsigned int buf_len;
-    size_t size = len;
-
-    FEC_PRINTF("len %d\n", (int)size);
-
-    if (!s->regs[ENET_RDAR]) {
-        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Unexpected packet\n",
-                      TYPE_IMX_FEC, __func__);
-        return 0;
-    }
-
-    /* 4 bytes for the CRC.  */
-    size += 4;
-    crc = cpu_to_be32(crc32(~0, buf, size));
-    crc_ptr = (uint8_t *) &crc;
-
-    /* Huge frames are truncted.  */
-    if (size > ENET_MAX_FRAME_SIZE) {
-        size = ENET_MAX_FRAME_SIZE;
-        flags |= ENET_BD_TR | ENET_BD_LG;
-    }
-
-    /* Frames larger than the user limit just set error flags.  */
-    if (size > (s->regs[ENET_RCR] >> 16)) {
-        flags |= ENET_BD_LG;
-    }
-
-    addr = s->rx_descriptor;
-    while (size > 0) {
-        imx_enet_read_bd(&bd, addr);
-        if ((bd.flags & ENET_BD_E) == 0) {
-            /* No descriptors available.  Bail out.  */
-            /*
-             * FIXME: This is wrong. We should probably either
-             * save the remainder for when more RX buffers are
-             * available, or flag an error.
-             */
-            qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Lost end of frame\n",
-                          TYPE_IMX_FEC, __func__);
-            break;
-        }
-        buf_len = (size <= s->regs[ENET_MRBR]) ? size : s->regs[ENET_MRBR];
-        bd.length = buf_len;
-        size -= buf_len;
-
-        FEC_PRINTF("rx_bd 0x%x length %d\n", addr, bd.length);
-
-        /* The last 4 bytes are the CRC.  */
-        if (size < 4) {
-            buf_len += size - 4;
-        }
-        buf_addr = bd.data;
-        dma_memory_write(&address_space_memory, buf_addr, buf, buf_len);
-        buf += buf_len;
-        if (size < 4) {
-            dma_memory_write(&address_space_memory, buf_addr + buf_len,
-                             crc_ptr, 4 - size);
-            crc_ptr += 4 - size;
-        }
-        bd.flags &= ~ENET_BD_E;
-        if (size == 0) {
-            /* Last buffer in frame.  */
-            bd.flags |= flags | ENET_BD_L;
-            FEC_PRINTF("rx frame flags %04x\n", bd.flags);
-            if (bd.option & ENET_BD_RX_INT) {
-                s->regs[ENET_EIR] |= ENET_INT_RXF;
-            }
-        } else {
-            if (bd.option & ENET_BD_RX_INT) {
-                s->regs[ENET_EIR] |= ENET_INT_RXB;
-            }
-        }
-        imx_enet_write_bd(&bd, addr);
-        /* Advance to the next descriptor.  */
-        if ((bd.flags & ENET_BD_W) != 0) {
-            addr = s->regs[ENET_RDSR];
+        if ((bd.flags & FEC_BD_W) != 0) {
+            addr = s->erdsr;
         } else {
-            addr += sizeof(bd);
+            addr += 8;
         }
     }
     s->rx_descriptor = addr;
-    imx_eth_enable_rx(s);
-    imx_eth_update(s);
+    imx_fec_enable_rx(s);
+    imx_fec_update(s);
     return len;
 }
 
-static ssize_t imx_eth_receive(NetClientState *nc, const uint8_t *buf,
-                                size_t len)
-{
-    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));
-
-    if (!s->is_fec && (s->regs[ENET_ECR] & ENET_ECR_EN1588)) {
-        return imx_enet_receive(nc, buf, len);
-    } else {
-        return imx_fec_receive(nc, buf, len);
-    }
-}
-
-static const MemoryRegionOps imx_eth_ops = {
-    .read                  = imx_eth_read,
-    .write                 = imx_eth_write,
+static const MemoryRegionOps imx_fec_ops = {
+    .read = imx_fec_read,
+    .write = imx_fec_write,
     .valid.min_access_size = 4,
     .valid.max_access_size = 4,
-    .endianness            = DEVICE_NATIVE_ENDIAN,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void imx_eth_cleanup(NetClientState *nc)
+static void imx_fec_cleanup(NetClientState *nc)
 {
     IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));
 
     s->nic = NULL;
 }
 
-static NetClientInfo imx_eth_net_info = {
-    .type                = NET_CLIENT_DRIVER_NIC,
-    .size                = sizeof(NICState),
-    .can_receive         = imx_eth_can_receive,
-    .receive             = imx_eth_receive,
-    .cleanup             = imx_eth_cleanup,
-    .link_status_changed = imx_eth_set_link,
+static NetClientInfo net_imx_fec_info = {
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .size = sizeof(NICState),
+    .can_receive = imx_fec_can_receive,
+    .receive = imx_fec_receive,
+    .cleanup = imx_fec_cleanup,
+    .link_status_changed = imx_fec_set_link,
 };
 
 
-static void imx_eth_realize(DeviceState *dev, Error **errp)
+static void imx_fec_realize(DeviceState *dev, Error **errp)
 {
     IMXFECState *s = IMX_FEC(dev);
     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
-    memory_region_init_io(&s->iomem, OBJECT(dev), &imx_eth_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(dev), &imx_fec_ops, s,
                           TYPE_IMX_FEC, 0x400);
     sysbus_init_mmio(sbd, &s->iomem);
-    sysbus_init_irq(sbd, &s->irq[0]);
-    sysbus_init_irq(sbd, &s->irq[1]);
-
+    sysbus_init_irq(sbd, &s->irq);
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
     s->conf.peers.ncs[0] = nd_table[0].netdev;
 
-    s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
-                          object_get_typename(OBJECT(dev)),
-                          DEVICE(dev)->id, s);
-
+    s->nic = qemu_new_nic(&net_imx_fec_info, &s->conf,
+                          object_get_typename(OBJECT(dev)), DEVICE(dev)->id,
+                          s);
     qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
 }
 
-static Property imx_eth_properties[] = {
+static Property imx_fec_properties[] = {
     DEFINE_NIC_PROPERTIES(IMXFECState, conf),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static void imx_eth_class_init(ObjectClass *klass, void *data)
+static void imx_fec_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    dc->vmsd    = &vmstate_imx_eth;
-    dc->reset   = imx_eth_reset;
-    dc->props   = imx_eth_properties;
-    dc->realize = imx_eth_realize;
-    dc->desc    = "i.MX FEC/ENET Ethernet Controller";
-}
-
-static void imx_fec_init(Object *obj)
-{
-    IMXFECState *s = IMX_FEC(obj);
-
-    s->is_fec = true;
-}
-
-static void imx_enet_init(Object *obj)
-{
-    IMXFECState *s = IMX_FEC(obj);
-
-    s->is_fec = false;
+    dc->vmsd = &vmstate_imx_fec;
+    dc->reset = imx_fec_reset;
+    dc->props = imx_fec_properties;
+    dc->realize = imx_fec_realize;
+    dc->desc = "i.MX FEC Ethernet Controller";
 }
 
 static const TypeInfo imx_fec_info = {
-    .name          = TYPE_IMX_FEC,
-    .parent        = TYPE_SYS_BUS_DEVICE,
+    .name = TYPE_IMX_FEC,
+    .parent = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(IMXFECState),
-    .instance_init = imx_fec_init,
-    .class_init    = imx_eth_class_init,
-};
-
-static const TypeInfo imx_enet_info = {
-    .name          = TYPE_IMX_ENET,
-    .parent        = TYPE_IMX_FEC,
-    .instance_init = imx_enet_init,
+    .class_init = imx_fec_class_init,
 };
 
-static void imx_eth_register_types(void)
+static void imx_fec_register_types(void)
 {
     type_register_static(&imx_fec_info);
-    type_register_static(&imx_enet_info);
 }
 
-type_init(imx_eth_register_types)
+type_init(imx_fec_register_types)
index 4615d87..08dc474 100644 (file)
@@ -16,7 +16,6 @@
 #include "hw/devices.h"
 #include "sysemu/sysemu.h"
 #include "hw/ptimer.h"
-#include "qemu/log.h"
 /* For crc32 */
 #include <zlib.h>
 
@@ -1313,7 +1312,7 @@ static const MemoryRegionOps lan9118_16bit_mem_ops = {
 };
 
 static NetClientInfo net_lan9118_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = lan9118_receive,
     .link_status_changed = lan9118_set_link,
index 573d724..6253d21 100644 (file)
@@ -93,7 +93,7 @@ static const MemoryRegionOps lance_mem_ops = {
 };
 
 static NetClientInfo net_lance_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = pcnet_receive,
     .link_status_changed = pcnet_set_link_status,
index 0ee8ad9..7c0398e 100644 (file)
@@ -507,7 +507,7 @@ static const MemoryRegionOps mcf_fec_ops = {
 };
 
 static NetClientInfo net_mcf_fec_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = mcf_fec_receive,
 };
index c3a12e1..1e147c3 100644 (file)
@@ -447,7 +447,7 @@ static void milkymist_minimac2_reset(DeviceState *d)
 }
 
 static NetClientInfo net_milkymist_minimac2_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = minimac2_rx,
 };
index 5a63df7..cf8b823 100644 (file)
@@ -183,12 +183,10 @@ static void mipsnet_ioport_write(void *opaque, hwaddr addr,
         break;
     case MIPSNET_TX_DATA_BUFFER:
         s->tx_buffer[s->tx_written++] = val;
-        if ((s->tx_written >= MAX_ETH_FRAME_SIZE)
-            || (s->tx_written == s->tx_count)) {
+        if (s->tx_written == s->tx_count) {
             /* Send buffer. */
-            trace_mipsnet_send(s->tx_written);
-            qemu_send_packet(qemu_get_queue(s->nic),
-                                s->tx_buffer, s->tx_written);
+            trace_mipsnet_send(s->tx_count);
+            qemu_send_packet(qemu_get_queue(s->nic), s->tx_buffer, s->tx_count);
             s->tx_count = s->tx_written = 0;
             s->intctl |= MIPSNET_INTCTL_TXDONE;
             s->busy = 1;
@@ -224,7 +222,7 @@ static const VMStateDescription vmstate_mipsnet = {
 };
 
 static NetClientInfo net_mipsnet_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = mipsnet_receive,
 };
index f345533..a7f5a94 100644 (file)
@@ -44,7 +44,7 @@ typedef struct ISANE2000State {
 } ISANE2000State;
 
 static NetClientInfo net_ne2000_isa_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = ne2000_receive,
 };
@@ -127,7 +127,9 @@ static void isa_ne2000_set_bootindex(Object *obj, Visitor *v,
     s->c.bootindex = boot_index;
 
 out:
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
 }
 
 static void isa_ne2000_instance_init(Object *obj)
index 798d681..f0feaf9 100644 (file)
@@ -712,7 +712,7 @@ void ne2000_setup_io(NE2000State *s, DeviceState *dev, unsigned size)
 }
 
 static NetClientInfo net_ne2000_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = ne2000_receive,
 };
index d213dcc..d022b28 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef HW_NE2000_H
-#define HW_NE2000_H
+#define HW_NE2000_H 1
 
 #define NE2000_PMEM_SIZE    (32*1024)
 #define NE2000_PMEM_START   (16*1024)
diff --git a/hw/net/net_rx_pkt.c b/hw/net/net_rx_pkt.c
deleted file mode 100644 (file)
index 1019b50..0000000
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * QEMU RX packets abstractions
- *
- * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
- *
- * Developed by Daynix Computing LTD (http://www.daynix.com)
- *
- * Authors:
- * Dmitry Fleytman <dmitry@daynix.com>
- * Tamir Shomer <tamirs@daynix.com>
- * Yan Vugenfirer <yan@daynix.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "trace.h"
-#include "net_rx_pkt.h"
-#include "net/checksum.h"
-#include "net/tap.h"
-
-struct NetRxPkt {
-    struct virtio_net_hdr virt_hdr;
-    uint8_t ehdr_buf[sizeof(struct eth_header)];
-    struct iovec *vec;
-    uint16_t vec_len_total;
-    uint16_t vec_len;
-    uint32_t tot_len;
-    uint16_t tci;
-    bool vlan_stripped;
-    bool has_virt_hdr;
-    eth_pkt_types_e packet_type;
-
-    /* Analysis results */
-    bool isip4;
-    bool isip6;
-    bool isudp;
-    bool istcp;
-
-    size_t l3hdr_off;
-    size_t l4hdr_off;
-    size_t l5hdr_off;
-
-    eth_ip6_hdr_info ip6hdr_info;
-    eth_ip4_hdr_info ip4hdr_info;
-    eth_l4_hdr_info  l4hdr_info;
-};
-
-void net_rx_pkt_init(struct NetRxPkt **pkt, bool has_virt_hdr)
-{
-    struct NetRxPkt *p = g_malloc0(sizeof *p);
-    p->has_virt_hdr = has_virt_hdr;
-    p->vec = NULL;
-    p->vec_len_total = 0;
-    *pkt = p;
-}
-
-void net_rx_pkt_uninit(struct NetRxPkt *pkt)
-{
-    if (pkt->vec_len_total != 0) {
-        g_free(pkt->vec);
-    }
-
-    g_free(pkt);
-}
-
-struct virtio_net_hdr *net_rx_pkt_get_vhdr(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-    return &pkt->virt_hdr;
-}
-
-static inline void
-net_rx_pkt_iovec_realloc(struct NetRxPkt *pkt,
-                            int new_iov_len)
-{
-    if (pkt->vec_len_total < new_iov_len) {
-        g_free(pkt->vec);
-        pkt->vec = g_malloc(sizeof(*pkt->vec) * new_iov_len);
-        pkt->vec_len_total = new_iov_len;
-    }
-}
-
-static void
-net_rx_pkt_pull_data(struct NetRxPkt *pkt,
-                        const struct iovec *iov, int iovcnt,
-                        size_t ploff)
-{
-    if (pkt->vlan_stripped) {
-        net_rx_pkt_iovec_realloc(pkt, iovcnt + 1);
-
-        pkt->vec[0].iov_base = pkt->ehdr_buf;
-        pkt->vec[0].iov_len = sizeof(pkt->ehdr_buf);
-
-        pkt->tot_len =
-            iov_size(iov, iovcnt) - ploff + sizeof(struct eth_header);
-
-        pkt->vec_len = iov_copy(pkt->vec + 1, pkt->vec_len_total - 1,
-                                iov, iovcnt, ploff, pkt->tot_len);
-    } else {
-        net_rx_pkt_iovec_realloc(pkt, iovcnt);
-
-        pkt->tot_len = iov_size(iov, iovcnt) - ploff;
-        pkt->vec_len = iov_copy(pkt->vec, pkt->vec_len_total,
-                                iov, iovcnt, ploff, pkt->tot_len);
-    }
-
-    eth_get_protocols(pkt->vec, pkt->vec_len, &pkt->isip4, &pkt->isip6,
-                      &pkt->isudp, &pkt->istcp,
-                      &pkt->l3hdr_off, &pkt->l4hdr_off, &pkt->l5hdr_off,
-                      &pkt->ip6hdr_info, &pkt->ip4hdr_info, &pkt->l4hdr_info);
-
-    trace_net_rx_pkt_parsed(pkt->isip4, pkt->isip6, pkt->isudp, pkt->istcp,
-                            pkt->l3hdr_off, pkt->l4hdr_off, pkt->l5hdr_off);
-}
-
-void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt,
-                                const struct iovec *iov, int iovcnt,
-                                size_t iovoff, bool strip_vlan)
-{
-    uint16_t tci = 0;
-    uint16_t ploff = iovoff;
-    assert(pkt);
-    pkt->vlan_stripped = false;
-
-    if (strip_vlan) {
-        pkt->vlan_stripped = eth_strip_vlan(iov, iovcnt, iovoff, pkt->ehdr_buf,
-                                            &ploff, &tci);
-    }
-
-    pkt->tci = tci;
-
-    net_rx_pkt_pull_data(pkt, iov, iovcnt, ploff);
-}
-
-void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt,
-                                const struct iovec *iov, int iovcnt,
-                                size_t iovoff, bool strip_vlan,
-                                uint16_t vet)
-{
-    uint16_t tci = 0;
-    uint16_t ploff = iovoff;
-    assert(pkt);
-    pkt->vlan_stripped = false;
-
-    if (strip_vlan) {
-        pkt->vlan_stripped = eth_strip_vlan_ex(iov, iovcnt, iovoff, vet,
-                                               pkt->ehdr_buf,
-                                               &ploff, &tci);
-    }
-
-    pkt->tci = tci;
-
-    net_rx_pkt_pull_data(pkt, iov, iovcnt, ploff);
-}
-
-void net_rx_pkt_dump(struct NetRxPkt *pkt)
-{
-#ifdef NET_RX_PKT_DEBUG
-    NetRxPkt *pkt = (NetRxPkt *)pkt;
-    assert(pkt);
-
-    printf("RX PKT: tot_len: %d, vlan_stripped: %d, vlan_tag: %d\n",
-              pkt->tot_len, pkt->vlan_stripped, pkt->tci);
-#endif
-}
-
-void net_rx_pkt_set_packet_type(struct NetRxPkt *pkt,
-    eth_pkt_types_e packet_type)
-{
-    assert(pkt);
-
-    pkt->packet_type = packet_type;
-
-}
-
-eth_pkt_types_e net_rx_pkt_get_packet_type(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-
-    return pkt->packet_type;
-}
-
-size_t net_rx_pkt_get_total_len(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-
-    return pkt->tot_len;
-}
-
-void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, const void *data,
-                              size_t len)
-{
-    const struct iovec iov = {
-        .iov_base = (void *)data,
-        .iov_len = len
-    };
-
-    assert(pkt);
-
-    eth_get_protocols(&iov, 1, &pkt->isip4, &pkt->isip6,
-                      &pkt->isudp, &pkt->istcp,
-                      &pkt->l3hdr_off, &pkt->l4hdr_off, &pkt->l5hdr_off,
-                      &pkt->ip6hdr_info, &pkt->ip4hdr_info, &pkt->l4hdr_info);
-}
-
-void net_rx_pkt_get_protocols(struct NetRxPkt *pkt,
-                              bool *isip4, bool *isip6,
-                              bool *isudp, bool *istcp)
-{
-    assert(pkt);
-
-    *isip4 = pkt->isip4;
-    *isip6 = pkt->isip6;
-    *isudp = pkt->isudp;
-    *istcp = pkt->istcp;
-}
-
-size_t net_rx_pkt_get_l3_hdr_offset(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-    return pkt->l3hdr_off;
-}
-
-size_t net_rx_pkt_get_l4_hdr_offset(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-    return pkt->l4hdr_off;
-}
-
-size_t net_rx_pkt_get_l5_hdr_offset(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-    return pkt->l5hdr_off;
-}
-
-eth_ip6_hdr_info *net_rx_pkt_get_ip6_info(struct NetRxPkt *pkt)
-{
-    return &pkt->ip6hdr_info;
-}
-
-eth_ip4_hdr_info *net_rx_pkt_get_ip4_info(struct NetRxPkt *pkt)
-{
-    return &pkt->ip4hdr_info;
-}
-
-eth_l4_hdr_info *net_rx_pkt_get_l4_info(struct NetRxPkt *pkt)
-{
-    return &pkt->l4hdr_info;
-}
-
-static inline void
-_net_rx_rss_add_chunk(uint8_t *rss_input, size_t *bytes_written,
-                      void *ptr, size_t size)
-{
-    memcpy(&rss_input[*bytes_written], ptr, size);
-    trace_net_rx_pkt_rss_add_chunk(ptr, size, *bytes_written);
-    *bytes_written += size;
-}
-
-static inline void
-_net_rx_rss_prepare_ip4(uint8_t *rss_input,
-                        struct NetRxPkt *pkt,
-                        size_t *bytes_written)
-{
-    struct ip_header *ip4_hdr = &pkt->ip4hdr_info.ip4_hdr;
-
-    _net_rx_rss_add_chunk(rss_input, bytes_written,
-                          &ip4_hdr->ip_src, sizeof(uint32_t));
-
-    _net_rx_rss_add_chunk(rss_input, bytes_written,
-                          &ip4_hdr->ip_dst, sizeof(uint32_t));
-}
-
-static inline void
-_net_rx_rss_prepare_ip6(uint8_t *rss_input,
-                        struct NetRxPkt *pkt,
-                        bool ipv6ex, size_t *bytes_written)
-{
-    eth_ip6_hdr_info *ip6info = &pkt->ip6hdr_info;
-
-    _net_rx_rss_add_chunk(rss_input, bytes_written,
-           (ipv6ex && ip6info->rss_ex_src_valid) ? &ip6info->rss_ex_src
-                                                 : &ip6info->ip6_hdr.ip6_src,
-           sizeof(struct in6_address));
-
-    _net_rx_rss_add_chunk(rss_input, bytes_written,
-           (ipv6ex && ip6info->rss_ex_dst_valid) ? &ip6info->rss_ex_dst
-                                                 : &ip6info->ip6_hdr.ip6_dst,
-           sizeof(struct in6_address));
-}
-
-static inline void
-_net_rx_rss_prepare_tcp(uint8_t *rss_input,
-                        struct NetRxPkt *pkt,
-                        size_t *bytes_written)
-{
-    struct tcp_header *tcphdr = &pkt->l4hdr_info.hdr.tcp;
-
-    _net_rx_rss_add_chunk(rss_input, bytes_written,
-                          &tcphdr->th_sport, sizeof(uint16_t));
-
-    _net_rx_rss_add_chunk(rss_input, bytes_written,
-                          &tcphdr->th_dport, sizeof(uint16_t));
-}
-
-uint32_t
-net_rx_pkt_calc_rss_hash(struct NetRxPkt *pkt,
-                         NetRxPktRssType type,
-                         uint8_t *key)
-{
-    uint8_t rss_input[36];
-    size_t rss_length = 0;
-    uint32_t rss_hash = 0;
-    net_toeplitz_key key_data;
-
-    switch (type) {
-    case NetPktRssIpV4:
-        assert(pkt->isip4);
-        trace_net_rx_pkt_rss_ip4();
-        _net_rx_rss_prepare_ip4(&rss_input[0], pkt, &rss_length);
-        break;
-    case NetPktRssIpV4Tcp:
-        assert(pkt->isip4);
-        assert(pkt->istcp);
-        trace_net_rx_pkt_rss_ip4_tcp();
-        _net_rx_rss_prepare_ip4(&rss_input[0], pkt, &rss_length);
-        _net_rx_rss_prepare_tcp(&rss_input[0], pkt, &rss_length);
-        break;
-    case NetPktRssIpV6Tcp:
-        assert(pkt->isip6);
-        assert(pkt->istcp);
-        trace_net_rx_pkt_rss_ip6_tcp();
-        _net_rx_rss_prepare_ip6(&rss_input[0], pkt, true, &rss_length);
-        _net_rx_rss_prepare_tcp(&rss_input[0], pkt, &rss_length);
-        break;
-    case NetPktRssIpV6:
-        assert(pkt->isip6);
-        trace_net_rx_pkt_rss_ip6();
-        _net_rx_rss_prepare_ip6(&rss_input[0], pkt, false, &rss_length);
-        break;
-    case NetPktRssIpV6Ex:
-        assert(pkt->isip6);
-        trace_net_rx_pkt_rss_ip6_ex();
-        _net_rx_rss_prepare_ip6(&rss_input[0], pkt, true, &rss_length);
-        break;
-    default:
-        assert(false);
-        break;
-    }
-
-    net_toeplitz_key_init(&key_data, key);
-    net_toeplitz_add(&rss_hash, rss_input, rss_length, &key_data);
-
-    trace_net_rx_pkt_rss_hash(rss_length, rss_hash);
-
-    return rss_hash;
-}
-
-uint16_t net_rx_pkt_get_ip_id(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-
-    if (pkt->isip4) {
-        return be16_to_cpu(pkt->ip4hdr_info.ip4_hdr.ip_id);
-    }
-
-    return 0;
-}
-
-bool net_rx_pkt_is_tcp_ack(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-
-    if (pkt->istcp) {
-        return TCP_HEADER_FLAGS(&pkt->l4hdr_info.hdr.tcp) & TCP_FLAG_ACK;
-    }
-
-    return false;
-}
-
-bool net_rx_pkt_has_tcp_data(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-
-    if (pkt->istcp) {
-        return pkt->l4hdr_info.has_tcp_data;
-    }
-
-    return false;
-}
-
-struct iovec *net_rx_pkt_get_iovec(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-
-    return pkt->vec;
-}
-
-uint16_t net_rx_pkt_get_iovec_len(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-
-    return pkt->vec_len;
-}
-
-void net_rx_pkt_set_vhdr(struct NetRxPkt *pkt,
-                            struct virtio_net_hdr *vhdr)
-{
-    assert(pkt);
-
-    memcpy(&pkt->virt_hdr, vhdr, sizeof pkt->virt_hdr);
-}
-
-void net_rx_pkt_set_vhdr_iovec(struct NetRxPkt *pkt,
-    const struct iovec *iov, int iovcnt)
-{
-    assert(pkt);
-
-    iov_to_buf(iov, iovcnt, 0, &pkt->virt_hdr, sizeof pkt->virt_hdr);
-}
-
-bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-
-    return pkt->vlan_stripped;
-}
-
-bool net_rx_pkt_has_virt_hdr(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-
-    return pkt->has_virt_hdr;
-}
-
-uint16_t net_rx_pkt_get_vlan_tag(struct NetRxPkt *pkt)
-{
-    assert(pkt);
-
-    return pkt->tci;
-}
-
-bool net_rx_pkt_validate_l3_csum(struct NetRxPkt *pkt, bool *csum_valid)
-{
-    uint32_t cntr;
-    uint16_t csum;
-    uint32_t csl;
-
-    trace_net_rx_pkt_l3_csum_validate_entry();
-
-    if (!pkt->isip4) {
-        trace_net_rx_pkt_l3_csum_validate_not_ip4();
-        return false;
-    }
-
-    csl = pkt->l4hdr_off - pkt->l3hdr_off;
-
-    cntr = net_checksum_add_iov(pkt->vec, pkt->vec_len,
-                                pkt->l3hdr_off,
-                                csl, 0);
-
-    csum = net_checksum_finish(cntr);
-
-    *csum_valid = (csum == 0);
-
-    trace_net_rx_pkt_l3_csum_validate_csum(pkt->l3hdr_off, csl,
-                                           cntr, csum, *csum_valid);
-
-    return true;
-}
-
-static uint16_t
-_net_rx_pkt_calc_l4_csum(struct NetRxPkt *pkt)
-{
-    uint32_t cntr;
-    uint16_t csum;
-    uint16_t csl;
-    uint32_t cso;
-
-    trace_net_rx_pkt_l4_csum_calc_entry();
-
-    if (pkt->isip4) {
-        if (pkt->isudp) {
-            csl = be16_to_cpu(pkt->l4hdr_info.hdr.udp.uh_ulen);
-            trace_net_rx_pkt_l4_csum_calc_ip4_udp();
-        } else {
-            csl = be16_to_cpu(pkt->ip4hdr_info.ip4_hdr.ip_len) -
-                  IP_HDR_GET_LEN(&pkt->ip4hdr_info.ip4_hdr);
-            trace_net_rx_pkt_l4_csum_calc_ip4_tcp();
-        }
-
-        cntr = eth_calc_ip4_pseudo_hdr_csum(&pkt->ip4hdr_info.ip4_hdr,
-                                            csl, &cso);
-        trace_net_rx_pkt_l4_csum_calc_ph_csum(cntr, csl);
-    } else {
-        if (pkt->isudp) {
-            csl = be16_to_cpu(pkt->l4hdr_info.hdr.udp.uh_ulen);
-            trace_net_rx_pkt_l4_csum_calc_ip6_udp();
-        } else {
-            struct ip6_header *ip6hdr = &pkt->ip6hdr_info.ip6_hdr;
-            size_t full_ip6hdr_len = pkt->l4hdr_off - pkt->l3hdr_off;
-            size_t ip6opts_len = full_ip6hdr_len - sizeof(struct ip6_header);
-
-            csl = be16_to_cpu(ip6hdr->ip6_ctlun.ip6_un1.ip6_un1_plen) -
-                  ip6opts_len;
-            trace_net_rx_pkt_l4_csum_calc_ip6_tcp();
-        }
-
-        cntr = eth_calc_ip6_pseudo_hdr_csum(&pkt->ip6hdr_info.ip6_hdr, csl,
-                                            pkt->ip6hdr_info.l4proto, &cso);
-        trace_net_rx_pkt_l4_csum_calc_ph_csum(cntr, csl);
-    }
-
-    cntr += net_checksum_add_iov(pkt->vec, pkt->vec_len,
-                                 pkt->l4hdr_off, csl, cso);
-
-    csum = net_checksum_finish(cntr);
-
-    trace_net_rx_pkt_l4_csum_calc_csum(pkt->l4hdr_off, csl, cntr, csum);
-
-    return csum;
-}
-
-bool net_rx_pkt_validate_l4_csum(struct NetRxPkt *pkt, bool *csum_valid)
-{
-    uint16_t csum;
-
-    trace_net_rx_pkt_l4_csum_validate_entry();
-
-    if (!pkt->istcp && !pkt->isudp) {
-        trace_net_rx_pkt_l4_csum_validate_not_xxp();
-        return false;
-    }
-
-    if (pkt->isudp && (pkt->l4hdr_info.hdr.udp.uh_sum == 0)) {
-        trace_net_rx_pkt_l4_csum_validate_udp_with_no_checksum();
-        return false;
-    }
-
-    if (pkt->isip4 && pkt->ip4hdr_info.fragment) {
-        trace_net_rx_pkt_l4_csum_validate_ip4_fragment();
-        return false;
-    }
-
-    csum = _net_rx_pkt_calc_l4_csum(pkt);
-
-    *csum_valid = ((csum == 0) || (csum == 0xFFFF));
-
-    trace_net_rx_pkt_l4_csum_validate_csum(*csum_valid);
-
-    return true;
-}
-
-bool net_rx_pkt_fix_l4_csum(struct NetRxPkt *pkt)
-{
-    uint16_t csum = 0;
-    uint32_t l4_cso;
-
-    trace_net_rx_pkt_l4_csum_fix_entry();
-
-    if (pkt->istcp) {
-        l4_cso = offsetof(struct tcp_header, th_sum);
-        trace_net_rx_pkt_l4_csum_fix_tcp(l4_cso);
-    } else if (pkt->isudp) {
-        if (pkt->l4hdr_info.hdr.udp.uh_sum == 0) {
-            trace_net_rx_pkt_l4_csum_fix_udp_with_no_checksum();
-            return false;
-        }
-        l4_cso = offsetof(struct udp_header, uh_sum);
-        trace_net_rx_pkt_l4_csum_fix_udp(l4_cso);
-    } else {
-        trace_net_rx_pkt_l4_csum_fix_not_xxp();
-        return false;
-    }
-
-    if (pkt->isip4 && pkt->ip4hdr_info.fragment) {
-            trace_net_rx_pkt_l4_csum_fix_ip4_fragment();
-            return false;
-    }
-
-    /* Set zero to checksum word */
-    iov_from_buf(pkt->vec, pkt->vec_len,
-                 pkt->l4hdr_off + l4_cso,
-                 &csum, sizeof(csum));
-
-    /* Calculate L4 checksum */
-    csum = cpu_to_be16(_net_rx_pkt_calc_l4_csum(pkt));
-
-    /* Set calculated checksum to checksum word */
-    iov_from_buf(pkt->vec, pkt->vec_len,
-                 pkt->l4hdr_off + l4_cso,
-                 &csum, sizeof(csum));
-
-    trace_net_rx_pkt_l4_csum_fix_csum(pkt->l4hdr_off + l4_cso, csum);
-
-    return true;
-}
diff --git a/hw/net/net_rx_pkt.h b/hw/net/net_rx_pkt.h
deleted file mode 100644 (file)
index 7adf0fa..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * QEMU RX packets abstraction
- *
- * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
- *
- * Developed by Daynix Computing LTD (http://www.daynix.com)
- *
- * Authors:
- * Dmitry Fleytman <dmitry@daynix.com>
- * Tamir Shomer <tamirs@daynix.com>
- * Yan Vugenfirer <yan@daynix.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef NET_RX_PKT_H
-#define NET_RX_PKT_H
-
-#include "net/eth.h"
-
-/* defines to enable packet dump functions */
-/*#define NET_RX_PKT_DEBUG*/
-
-struct NetRxPkt;
-
-/**
- * Clean all rx packet resources
- *
- * @pkt:            packet
- *
- */
-void net_rx_pkt_uninit(struct NetRxPkt *pkt);
-
-/**
- * Init function for rx packet functionality
- *
- * @pkt:            packet pointer
- * @has_virt_hdr:   device uses virtio header
- *
- */
-void net_rx_pkt_init(struct NetRxPkt **pkt, bool has_virt_hdr);
-
-/**
- * returns total length of data attached to rx context
- *
- * @pkt:            packet
- *
- * Return:  nothing
- *
- */
-size_t net_rx_pkt_get_total_len(struct NetRxPkt *pkt);
-
-/**
- * parse and set packet analysis results
- *
- * @pkt:            packet
- * @data:           pointer to the data buffer to be parsed
- * @len:            data length
- *
- */
-void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, const void *data,
-                              size_t len);
-
-/**
- * fetches packet analysis results
- *
- * @pkt:            packet
- * @isip4:          whether the packet given is IPv4
- * @isip6:          whether the packet given is IPv6
- * @isudp:          whether the packet given is UDP
- * @istcp:          whether the packet given is TCP
- *
- */
-void net_rx_pkt_get_protocols(struct NetRxPkt *pkt,
-                                 bool *isip4, bool *isip6,
-                                 bool *isudp, bool *istcp);
-
-/**
-* fetches L3 header offset
-*
-* @pkt:            packet
-*
-*/
-size_t net_rx_pkt_get_l3_hdr_offset(struct NetRxPkt *pkt);
-
-/**
-* fetches L4 header offset
-*
-* @pkt:            packet
-*
-*/
-size_t net_rx_pkt_get_l4_hdr_offset(struct NetRxPkt *pkt);
-
-/**
-* fetches L5 header offset
-*
-* @pkt:            packet
-*
-*/
-size_t net_rx_pkt_get_l5_hdr_offset(struct NetRxPkt *pkt);
-
-/**
- * fetches IP6 header analysis results
- *
- * Return:  pointer to analysis results structure which is stored in internal
- *          packet area.
- *
- */
-eth_ip6_hdr_info *net_rx_pkt_get_ip6_info(struct NetRxPkt *pkt);
-
-/**
- * fetches IP4 header analysis results
- *
- * Return:  pointer to analysis results structure which is stored in internal
- *          packet area.
- *
- */
-eth_ip4_hdr_info *net_rx_pkt_get_ip4_info(struct NetRxPkt *pkt);
-
-/**
- * fetches L4 header analysis results
- *
- * Return:  pointer to analysis results structure which is stored in internal
- *          packet area.
- *
- */
-eth_l4_hdr_info *net_rx_pkt_get_l4_info(struct NetRxPkt *pkt);
-
-typedef enum {
-    NetPktRssIpV4,
-    NetPktRssIpV4Tcp,
-    NetPktRssIpV6Tcp,
-    NetPktRssIpV6,
-    NetPktRssIpV6Ex
-} NetRxPktRssType;
-
-/**
-* calculates RSS hash for packet
-*
-* @pkt:            packet
-* @type:           RSS hash type
-*
-* Return:  Toeplitz RSS hash.
-*
-*/
-uint32_t
-net_rx_pkt_calc_rss_hash(struct NetRxPkt *pkt,
-                         NetRxPktRssType type,
-                         uint8_t *key);
-
-/**
-* fetches IP identification for the packet
-*
-* @pkt:            packet
-*
-*/
-uint16_t net_rx_pkt_get_ip_id(struct NetRxPkt *pkt);
-
-/**
-* check if given packet is a TCP ACK packet
-*
-* @pkt:            packet
-*
-*/
-bool net_rx_pkt_is_tcp_ack(struct NetRxPkt *pkt);
-
-/**
-* check if given packet contains TCP data
-*
-* @pkt:            packet
-*
-*/
-bool net_rx_pkt_has_tcp_data(struct NetRxPkt *pkt);
-
-/**
- * returns virtio header stored in rx context
- *
- * @pkt:            packet
- * @ret:            virtio header
- *
- */
-struct virtio_net_hdr *net_rx_pkt_get_vhdr(struct NetRxPkt *pkt);
-
-/**
- * returns packet type
- *
- * @pkt:            packet
- * @ret:            packet type
- *
- */
-eth_pkt_types_e net_rx_pkt_get_packet_type(struct NetRxPkt *pkt);
-
-/**
- * returns vlan tag
- *
- * @pkt:            packet
- * @ret:            VLAN tag
- *
- */
-uint16_t net_rx_pkt_get_vlan_tag(struct NetRxPkt *pkt);
-
-/**
- * tells whether vlan was stripped from the packet
- *
- * @pkt:            packet
- * @ret:            VLAN stripped sign
- *
- */
-bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt);
-
-/**
- * notifies caller if the packet has virtio header
- *
- * @pkt:            packet
- * @ret:            true if packet has virtio header, false otherwize
- *
- */
-bool net_rx_pkt_has_virt_hdr(struct NetRxPkt *pkt);
-
-/**
-* attach scatter-gather data to rx packet
-*
-* @pkt:            packet
-* @iov:            received data scatter-gather list
-* @iovcnt          number of elements in iov
-* @iovoff          data start offset in the iov
-* @strip_vlan:     should the module strip vlan from data
-*
-*/
-void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt,
-                                const struct iovec *iov,
-                                int iovcnt, size_t iovoff,
-                                bool strip_vlan);
-
-/**
-* attach scatter-gather data to rx packet
-*
-* @pkt:            packet
-* @iov:            received data scatter-gather list
-* @iovcnt          number of elements in iov
-* @iovoff          data start offset in the iov
-* @strip_vlan:     should the module strip vlan from data
-* @vet:            VLAN tag Ethernet type
-*
-*/
-void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt,
-                                   const struct iovec *iov, int iovcnt,
-                                   size_t iovoff, bool strip_vlan,
-                                   uint16_t vet);
-
-/**
- * attach data to rx packet
- *
- * @pkt:            packet
- * @data:           pointer to the data buffer
- * @len:            data length
- * @strip_vlan:     should the module strip vlan from data
- *
- */
-static inline void
-net_rx_pkt_attach_data(struct NetRxPkt *pkt, const void *data,
-                          size_t len, bool strip_vlan)
-{
-    const struct iovec iov = {
-        .iov_base = (void *) data,
-        .iov_len = len
-    };
-
-    net_rx_pkt_attach_iovec(pkt, &iov, 1, 0, strip_vlan);
-}
-
-/**
- * returns io vector that holds the attached data
- *
- * @pkt:            packet
- * @ret:            pointer to IOVec
- *
- */
-struct iovec *net_rx_pkt_get_iovec(struct NetRxPkt *pkt);
-
-/**
-* returns io vector length that holds the attached data
-*
-* @pkt:            packet
-* @ret:            IOVec length
-*
-*/
-uint16_t net_rx_pkt_get_iovec_len(struct NetRxPkt *pkt);
-
-/**
- * prints rx packet data if debug is enabled
- *
- * @pkt:            packet
- *
- */
-void net_rx_pkt_dump(struct NetRxPkt *pkt);
-
-/**
- * copy passed vhdr data to packet context
- *
- * @pkt:            packet
- * @vhdr:           VHDR buffer
- *
- */
-void net_rx_pkt_set_vhdr(struct NetRxPkt *pkt,
-    struct virtio_net_hdr *vhdr);
-
-/**
-* copy passed vhdr data to packet context
-*
-* @pkt:            packet
-* @iov:            VHDR iov
-* @iovcnt:         VHDR iov array size
-*
-*/
-void net_rx_pkt_set_vhdr_iovec(struct NetRxPkt *pkt,
-    const struct iovec *iov, int iovcnt);
-
-/**
- * save packet type in packet context
- *
- * @pkt:            packet
- * @packet_type:    the packet type
- *
- */
-void net_rx_pkt_set_packet_type(struct NetRxPkt *pkt,
-    eth_pkt_types_e packet_type);
-
-/**
-* validate TCP/UDP checksum of the packet
-*
-* @pkt:            packet
-* @csum_valid:     checksum validation result
-* @ret:            true if validation was performed, false in case packet is
-*                  not TCP/UDP or checksum validation is not possible
-*
-*/
-bool net_rx_pkt_validate_l4_csum(struct NetRxPkt *pkt, bool *csum_valid);
-
-/**
-* validate IPv4 checksum of the packet
-*
-* @pkt:            packet
-* @csum_valid:     checksum validation result
-* @ret:            true if validation was performed, false in case packet is
-*                  not TCP/UDP or checksum validation is not possible
-*
-*/
-bool net_rx_pkt_validate_l3_csum(struct NetRxPkt *pkt, bool *csum_valid);
-
-/**
-* fix IPv4 checksum of the packet
-*
-* @pkt:            packet
-* @ret:            true if checksum was fixed, false in case packet is
-*                  not TCP/UDP or checksum correction is not possible
-*
-*/
-bool net_rx_pkt_fix_l4_csum(struct NetRxPkt *pkt);
-
-#endif
diff --git a/hw/net/net_tx_pkt.h b/hw/net/net_tx_pkt.h
deleted file mode 100644 (file)
index 212ecc6..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * QEMU TX packets abstraction
- *
- * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
- *
- * Developed by Daynix Computing LTD (http://www.daynix.com)
- *
- * Authors:
- * Dmitry Fleytman <dmitry@daynix.com>
- * Tamir Shomer <tamirs@daynix.com>
- * Yan Vugenfirer <yan@daynix.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef NET_TX_PKT_H
-#define NET_TX_PKT_H
-
-#include "net/eth.h"
-#include "exec/hwaddr.h"
-
-/* define to enable packet dump functions */
-/*#define NET_TX_PKT_DEBUG*/
-
-struct NetTxPkt;
-
-/**
- * Init function for tx packet functionality
- *
- * @pkt:            packet pointer
- * @pci_dev:        PCI device processing this packet
- * @max_frags:      max tx ip fragments
- * @has_virt_hdr:   device uses virtio header.
- */
-void net_tx_pkt_init(struct NetTxPkt **pkt, PCIDevice *pci_dev,
-    uint32_t max_frags, bool has_virt_hdr);
-
-/**
- * Clean all tx packet resources.
- *
- * @pkt:            packet.
- */
-void net_tx_pkt_uninit(struct NetTxPkt *pkt);
-
-/**
- * get virtio header
- *
- * @pkt:            packet
- * @ret:            virtio header
- */
-struct virtio_net_hdr *net_tx_pkt_get_vhdr(struct NetTxPkt *pkt);
-
-/**
- * build virtio header (will be stored in module context)
- *
- * @pkt:            packet
- * @tso_enable:     TSO enabled
- * @csum_enable:    CSO enabled
- * @gso_size:       MSS size for TSO
- *
- */
-void net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
-    bool csum_enable, uint32_t gso_size);
-
-/**
-* updates vlan tag, and adds vlan header with custom ethernet type
-* in case it is missing.
-*
-* @pkt:            packet
-* @vlan:           VLAN tag
-* @vlan_ethtype:   VLAN header Ethernet type
-*
-*/
-void net_tx_pkt_setup_vlan_header_ex(struct NetTxPkt *pkt,
-    uint16_t vlan, uint16_t vlan_ethtype);
-
-/**
-* updates vlan tag, and adds vlan header in case it is missing
-*
-* @pkt:            packet
-* @vlan:           VLAN tag
-*
-*/
-static inline void
-net_tx_pkt_setup_vlan_header(struct NetTxPkt *pkt, uint16_t vlan)
-{
-    net_tx_pkt_setup_vlan_header_ex(pkt, vlan, ETH_P_VLAN);
-}
-
-/**
- * populate data fragment into pkt context.
- *
- * @pkt:            packet
- * @pa:             physical address of fragment
- * @len:            length of fragment
- *
- */
-bool net_tx_pkt_add_raw_fragment(struct NetTxPkt *pkt, hwaddr pa,
-    size_t len);
-
-/**
- * Fix ip header fields and calculate IP header and pseudo header checksums.
- *
- * @pkt:            packet
- *
- */
-void net_tx_pkt_update_ip_checksums(struct NetTxPkt *pkt);
-
-/**
- * Calculate the IP header checksum.
- *
- * @pkt:            packet
- *
- */
-void net_tx_pkt_update_ip_hdr_checksum(struct NetTxPkt *pkt);
-
-/**
- * get length of all populated data.
- *
- * @pkt:            packet
- * @ret:            total data length
- *
- */
-size_t net_tx_pkt_get_total_len(struct NetTxPkt *pkt);
-
-/**
- * get packet type
- *
- * @pkt:            packet
- * @ret:            packet type
- *
- */
-eth_pkt_types_e net_tx_pkt_get_packet_type(struct NetTxPkt *pkt);
-
-/**
- * prints packet data if debug is enabled
- *
- * @pkt:            packet
- *
- */
-void net_tx_pkt_dump(struct NetTxPkt *pkt);
-
-/**
- * reset tx packet private context (needed to be called between packets)
- *
- * @pkt:            packet
- *
- */
-void net_tx_pkt_reset(struct NetTxPkt *pkt);
-
-/**
- * Send packet to qemu. handles sw offloads if vhdr is not supported.
- *
- * @pkt:            packet
- * @nc:             NetClientState
- * @ret:            operation result
- *
- */
-bool net_tx_pkt_send(struct NetTxPkt *pkt, NetClientState *nc);
-
-/**
-* Redirect packet directly to receive path (emulate loopback phy).
-* Handles sw offloads if vhdr is not supported.
-*
-* @pkt:            packet
-* @nc:             NetClientState
-* @ret:            operation result
-*
-*/
-bool net_tx_pkt_send_loopback(struct NetTxPkt *pkt, NetClientState *nc);
-
-/**
- * parse raw packet data and analyze offload requirements.
- *
- * @pkt:            packet
- *
- */
-bool net_tx_pkt_parse(struct NetTxPkt *pkt);
-
-/**
-* indicates if there are data fragments held by this packet object.
-*
-* @pkt:            packet
-*
-*/
-bool net_tx_pkt_has_fragments(struct NetTxPkt *pkt);
-
-#endif
index 268d6a7..c6094fb 100644 (file)
@@ -33,7 +33,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/hw.h"
-#include "hw/net/mii.h"
 #include "hw/sysbus.h"
 #include "net/net.h"
 #include "sysemu/sysemu.h"
 
 /* PHY MII registers */
 enum {
+    MII_BMCR,
+    MII_BMSR,
+    MII_PHYIDR1,
+    MII_PHYIDR2,
+    MII_ANAR,
+    MII_ANLPAR,
     MII_REG_MAX = 16,
 };
 
@@ -67,11 +72,10 @@ typedef struct Mii {
 static void mii_set_link(Mii *s, bool link_ok)
 {
     if (link_ok) {
-        s->regs[MII_BMSR] |= MII_BMSR_LINK_ST;
-        s->regs[MII_ANLPAR] |= MII_ANLPAR_TXFD | MII_ANLPAR_TX |
-            MII_ANLPAR_10FD | MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
+        s->regs[MII_BMSR] |= 0x4;
+        s->regs[MII_ANLPAR] |= 0x01e1;
     } else {
-        s->regs[MII_BMSR] &= ~MII_BMSR_LINK_ST;
+        s->regs[MII_BMSR] &= ~0x4;
         s->regs[MII_ANLPAR] &= 0x01ff;
     }
     s->link_ok = link_ok;
@@ -80,14 +84,11 @@ static void mii_set_link(Mii *s, bool link_ok)
 static void mii_reset(Mii *s)
 {
     memset(s->regs, 0, sizeof(s->regs));
-    s->regs[MII_BMCR] = MII_BMCR_AUTOEN;
-    s->regs[MII_BMSR] = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD |
-        MII_BMSR_10T_FD | MII_BMSR_10T_HD | MII_BMSR_MFPS |
-        MII_BMSR_AN_COMP | MII_BMSR_AUTONEG;
-    s->regs[MII_PHYID1] = 0x2000;
-    s->regs[MII_PHYID2] = 0x5c90;
-    s->regs[MII_ANAR] = MII_ANAR_TXFD | MII_ANAR_TX |
-        MII_ANAR_10FD | MII_ANAR_10 | MII_ANAR_CSMACD;
+    s->regs[MII_BMCR] = 0x1000;
+    s->regs[MII_BMSR] = 0x7868; /* no ext regs */
+    s->regs[MII_PHYIDR1] = 0x2000;
+    s->regs[MII_PHYIDR2] = 0x5c90;
+    s->regs[MII_ANAR] = 0x01e1;
     mii_set_link(s, s->link_ok);
 }
 
@@ -97,7 +98,7 @@ static void mii_ro(Mii *s, uint16_t v)
 
 static void mii_write_bmcr(Mii *s, uint16_t v)
 {
-    if (v & MII_BMCR_RESET) {
+    if (v & 0x8000) {
         mii_reset(s);
     } else {
         s->regs[MII_BMCR] = v;
@@ -109,8 +110,8 @@ static void mii_write_host(Mii *s, unsigned idx, uint16_t v)
     static void (*reg_write[MII_REG_MAX])(Mii *s, uint16_t v) = {
         [MII_BMCR] = mii_write_bmcr,
         [MII_BMSR] = mii_ro,
-        [MII_PHYID1] = mii_ro,
-        [MII_PHYID2] = mii_ro,
+        [MII_PHYIDR1] = mii_ro,
+        [MII_PHYIDR2] = mii_ro,
     };
 
     if (idx < MII_REG_MAX) {
@@ -473,7 +474,7 @@ static ssize_t open_eth_receive(NetClientState *nc,
 }
 
 static NetClientInfo net_open_eth_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .can_receive = open_eth_can_receive,
     .receive = open_eth_receive,
@@ -482,8 +483,7 @@ static NetClientInfo net_open_eth_info = {
 
 static void open_eth_start_xmit(OpenEthState *s, desc *tx)
 {
-    uint8_t *buf = NULL;
-    uint8_t buffer[0x600];
+    uint8_t buf[65536];
     unsigned len = GET_FIELD(tx->len_flags, TXD_LEN);
     unsigned tx_len = len;
 
@@ -498,11 +498,6 @@ static void open_eth_start_xmit(OpenEthState *s, desc *tx)
 
     trace_open_eth_start_xmit(tx->buf_ptr, len, tx_len);
 
-    if (tx_len > sizeof(buffer)) {
-        buf = g_new(uint8_t, tx_len);
-    } else {
-        buf = buffer;
-    }
     if (len > tx_len) {
         len = tx_len;
     }
@@ -511,9 +506,6 @@ static void open_eth_start_xmit(OpenEthState *s, desc *tx)
         memset(buf + len, 0, tx_len - len);
     }
     qemu_send_packet(qemu_get_queue(s->nic), buf, tx_len);
-    if (tx_len > sizeof(buffer)) {
-        g_free(buf);
-    }
 
     if (tx->len_flags & TXD_WR) {
         s->tx_desc = 0;
index 0acf8a4..595439a 100644 (file)
@@ -272,7 +272,7 @@ static void pci_pcnet_uninit(PCIDevice *dev)
 }
 
 static NetClientInfo net_pci_pcnet_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = pcnet_receive,
     .link_status_changed = pcnet_set_link_status,
index 40831a7..dec8de8 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef HW_PCNET_H
-#define HW_PCNET_H
+#define HW_PCNET_H 1
 
 #define PCNET_IOPORT_SIZE       0x20
 #define PCNET_PNPMMIO_SIZE      0x20
index 7ae0495..f9c80f8 100644 (file)
@@ -16,8 +16,8 @@
  * GNU General Public License for more details.
  */
 
-#ifndef ROCKER_H
-#define ROCKER_H
+#ifndef _ROCKER_H_
+#define _ROCKER_H_
 
 #include "qemu/sockets.h"
 
@@ -81,4 +81,4 @@ int rx_produce(World *world, uint32_t pport,
 int rocker_port_eg(Rocker *r, uint32_t pport,
                    const struct iovec *iov, int iovcnt);
 
-#endif /* ROCKER_H */
+#endif /* _ROCKER_H_ */
index 1dec335..d4041f5 100644 (file)
@@ -14,8 +14,9 @@
  * GNU General Public License for more details.
  */
 
-#ifndef ROCKER_DESC_H
-#define ROCKER_DESC_H
+
+#ifndef _ROCKER_DESC_H_
+#define _ROCKER_DESC_H_
 
 #include "rocker_hw.h"
 
index 1305ac3..0149899 100644 (file)
@@ -167,7 +167,7 @@ static void fp_port_set_link_status(NetClientState *nc)
 }
 
 static NetClientInfo fp_port_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = fp_port_receive,
     .receive_iov = fp_port_receive_iov,
index dbe1dd3..04592bb 100644 (file)
@@ -14,8 +14,8 @@
  * GNU General Public License for more details.
  */
 
-#ifndef ROCKER_FP_H
-#define ROCKER_FP_H
+#ifndef _ROCKER_FP_H_
+#define _ROCKER_FP_H_
 
 #include "net/net.h"
 #include "qemu/iov.h"
@@ -51,4 +51,4 @@ FpPort *fp_port_alloc(Rocker *r, char *sw_name,
 void fp_port_free(FpPort *port);
 void fp_port_reset(FpPort *port);
 
-#endif /* ROCKER_FP_H */
+#endif /* _ROCKER_FP_H_ */
index 1786323..8c50830 100644 (file)
@@ -6,8 +6,8 @@
  *
  */
 
-#ifndef ROCKER_HW_H
-#define ROCKER_HW_H
+#ifndef _ROCKER_HW_
+#define _ROCKER_HW_
 
 #define __le16 uint16_t
 #define __le32 uint32_t
@@ -490,4 +490,4 @@ enum rocker_of_dpa_overlay_type {
  */
 #define ROCKER_CONTROL_RESET            (1 << 0)
 
-#endif /* ROCKER_HW_H */
+#endif /* _ROCKER_HW_ */
index 9b1e0d2..0a134eb 100644 (file)
@@ -103,8 +103,9 @@ typedef struct of_dpa_flow_key {
 
 /* Width of key which includes field 'f' in u64s, rounded up */
 #define FLOW_KEY_WIDTH(f) \
-    DIV_ROUND_UP(offsetof(OfDpaFlowKey, f) + sizeof(((OfDpaFlowKey *)0)->f), \
-    sizeof(uint64_t))
+    ((offsetof(OfDpaFlowKey, f) + \
+      sizeof(((OfDpaFlowKey *)0)->f) + \
+      sizeof(uint64_t) - 1) / sizeof(uint64_t))
 
 typedef struct of_dpa_flow_action {
     uint32_t goto_tbl;
index 01c7a97..f3f6d77 100644 (file)
@@ -14,9 +14,9 @@
  * GNU General Public License for more details.
  */
 
-#ifndef ROCKER_OF_DPA_H
-#define ROCKER_OF_DPA_H
+#ifndef _ROCKER_OF_DPA_H_
+#define _ROCKER_OF_DPA_H_
 
 World *of_dpa_world_alloc(Rocker *r);
 
-#endif /* ROCKER_OF_DPA_H */
+#endif /* _ROCKER_OF_DPA_H_ */
index dd28d08..e3c4ab6 100644 (file)
@@ -14,8 +14,8 @@
  * GNU General Public License for more details.
  */
 
-#ifndef ROCKER_TLV_H
-#define ROCKER_TLV_H
+#ifndef _ROCKER_TLV_H_
+#define _ROCKER_TLV_H_
 
 #define ROCKER_TLV_ALIGNTO 8U
 #define ROCKER_TLV_ALIGN(len) \
@@ -106,17 +106,17 @@ static inline uint64_t rocker_tlv_get_u64(const RockerTlv *tlv)
 
 static inline uint16_t rocker_tlv_get_le16(const RockerTlv *tlv)
 {
-    return lduw_le_p(rocker_tlv_data(tlv));
+    return le16_to_cpup((uint16_t *) rocker_tlv_data(tlv));
 }
 
 static inline uint32_t rocker_tlv_get_le32(const RockerTlv *tlv)
 {
-    return ldl_le_p(rocker_tlv_data(tlv));
+    return le32_to_cpup((uint32_t *) rocker_tlv_data(tlv));
 }
 
 static inline uint64_t rocker_tlv_get_le64(const RockerTlv *tlv)
 {
-    return ldq_le_p(rocker_tlv_data(tlv));
+    return le64_to_cpup((uint64_t *) rocker_tlv_data(tlv));
 }
 
 static inline void rocker_tlv_parse(RockerTlv **tb, int maxtype,
index 44f1fe3..58ade47 100644 (file)
@@ -14,8 +14,8 @@
  * GNU General Public License for more details.
  */
 
-#ifndef ROCKER_WORLD_H
-#define ROCKER_WORLD_H
+#ifndef _ROCKER_WORLD_H_
+#define _ROCKER_WORLD_H_
 
 #include "rocker_hw.h"
 
@@ -58,4 +58,4 @@ const char *world_name(World *world);
 
 World *rocker_get_world(Rocker *r, enum rocker_world_type type);
 
-#endif /* ROCKER_WORLD_H */
+#endif /* _ROCKER_WORLD_H_ */
index 3345bc6..1e5ec14 100644 (file)
@@ -1013,8 +1013,8 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
         uint32_t rx_space = rxdw0 & CP_RX_BUFFER_SIZE_MASK;
 
         /* write VLAN info to descriptor variables. */
-        if (s->CpCmd & CPlusRxVLAN &&
-            lduw_be_p(&buf[ETH_ALEN * 2]) == ETH_P_VLAN) {
+        if (s->CpCmd & CPlusRxVLAN && be16_to_cpup((uint16_t *)
+                &buf[ETH_ALEN * 2]) == ETH_P_VLAN) {
             dot1q_buf = &buf[ETH_ALEN * 2];
             size -= VLAN_HLEN;
             /* if too small buffer, use the tailroom added duing expansion */
@@ -1024,10 +1024,11 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
 
             rxdw1 &= ~CP_RX_VLAN_TAG_MASK;
             /* BE + ~le_to_cpu()~ + cpu_to_le() = BE */
-            rxdw1 |= CP_RX_TAVA | lduw_le_p(&dot1q_buf[ETHER_TYPE_LEN]);
+            rxdw1 |= CP_RX_TAVA | le16_to_cpup((uint16_t *)
+                &dot1q_buf[ETHER_TYPE_LEN]);
 
             DPRINTF("C+ Rx mode : extracted vlan tag with tci: ""%u\n",
-                lduw_be_p(&dot1q_buf[ETHER_TYPE_LEN]));
+                be16_to_cpup((uint16_t *)&dot1q_buf[ETHER_TYPE_LEN]));
         } else {
             /* reset VLAN tag flag */
             rxdw1 &= ~CP_RX_TAVA;
@@ -1351,6 +1352,29 @@ static void RTL8139TallyCounters_dma_write(RTL8139State *s, dma_addr_t tc_addr)
     pci_dma_write(d, tc_addr + 62,    (uint8_t *)&val16, 2);
 }
 
+/* Loads values of tally counters from VM state file */
+
+static const VMStateDescription vmstate_tally_counters = {
+    .name = "tally_counters",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT64(TxOk, RTL8139TallyCounters),
+        VMSTATE_UINT64(RxOk, RTL8139TallyCounters),
+        VMSTATE_UINT64(TxERR, RTL8139TallyCounters),
+        VMSTATE_UINT32(RxERR, RTL8139TallyCounters),
+        VMSTATE_UINT16(MissPkt, RTL8139TallyCounters),
+        VMSTATE_UINT16(FAE, RTL8139TallyCounters),
+        VMSTATE_UINT32(Tx1Col, RTL8139TallyCounters),
+        VMSTATE_UINT32(TxMCol, RTL8139TallyCounters),
+        VMSTATE_UINT64(RxOkPhy, RTL8139TallyCounters),
+        VMSTATE_UINT64(RxOkBrd, RTL8139TallyCounters),
+        VMSTATE_UINT16(TxAbt, RTL8139TallyCounters),
+        VMSTATE_UINT16(TxUndrn, RTL8139TallyCounters),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static void rtl8139_ChipCmd_write(RTL8139State *s, uint32_t val)
 {
     DeviceState *d = DEVICE(s);
@@ -1843,6 +1867,11 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor)
     return 1;
 }
 
+/* structures and macros for task offloading */
+#define TCP_HEADER_DATA_OFFSET(tcp) (((be16_to_cpu(tcp->th_offset_flags) >> 12)&0xf) << 2)
+#define TCP_FLAGS_ONLY(flags) ((flags)&0x3f)
+#define TCP_HEADER_FLAGS(tcp) TCP_FLAGS_ONLY(be16_to_cpu(tcp->th_offset_flags))
+
 #define TCP_HEADER_CLEAR_FLAGS(tcp, off) ((tcp)->th_offset_flags &= cpu_to_be16(~TCP_FLAGS_ONLY(off)))
 
 /* produces ones' complement sum of data */
@@ -3198,7 +3227,7 @@ static void rtl8139_pre_save(void *opaque)
 
 static const VMStateDescription vmstate_rtl8139 = {
     .name = "rtl8139",
-    .version_id = 5,
+    .version_id = 4,
     .minimum_version_id = 3,
     .post_load = rtl8139_post_load,
     .pre_save  = rtl8139_pre_save,
@@ -3269,19 +3298,8 @@ static const VMStateDescription vmstate_rtl8139 = {
         VMSTATE_UINT32(TimerInt, RTL8139State),
         VMSTATE_INT64(TCTR_base, RTL8139State),
 
-        VMSTATE_UINT64(tally_counters.TxOk, RTL8139State),
-        VMSTATE_UINT64(tally_counters.RxOk, RTL8139State),
-        VMSTATE_UINT64(tally_counters.TxERR, RTL8139State),
-        VMSTATE_UINT32(tally_counters.RxERR, RTL8139State),
-        VMSTATE_UINT16(tally_counters.MissPkt, RTL8139State),
-        VMSTATE_UINT16(tally_counters.FAE, RTL8139State),
-        VMSTATE_UINT32(tally_counters.Tx1Col, RTL8139State),
-        VMSTATE_UINT32(tally_counters.TxMCol, RTL8139State),
-        VMSTATE_UINT64(tally_counters.RxOkPhy, RTL8139State),
-        VMSTATE_UINT64(tally_counters.RxOkBrd, RTL8139State),
-        VMSTATE_UINT32_V(tally_counters.RxOkMul, RTL8139State, 5),
-        VMSTATE_UINT16(tally_counters.TxAbt, RTL8139State),
-        VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State),
+        VMSTATE_STRUCT(tally_counters, RTL8139State, 0,
+                       vmstate_tally_counters, RTL8139TallyCounters),
 
         VMSTATE_UINT32_V(cplus_enabled, RTL8139State, 4),
         VMSTATE_END_OF_LIST()
@@ -3393,7 +3411,7 @@ static void rtl8139_set_link_status(NetClientState *nc)
 }
 
 static NetClientInfo net_rtl8139_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .can_receive = rtl8139_can_receive,
     .receive = rtl8139_receive,
index 3b16dcf..21c1b8f 100644 (file)
@@ -755,7 +755,7 @@ static const MemoryRegionOps smc91c111_mem_ops = {
 };
 
 static NetClientInfo net_smc91c111_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .can_receive = smc91c111_can_receive_nc,
     .receive = smc91c111_receive,
index b273eda..a647f25 100644 (file)
@@ -28,7 +28,6 @@
 #include "qemu-common.h"
 #include "cpu.h"
 #include "hw/hw.h"
-#include "qemu/log.h"
 #include "net/net.h"
 #include "hw/qdev.h"
 #include "hw/ppc/spapr.h"
@@ -107,10 +106,9 @@ typedef struct VIOsPAPRVLANDevice {
     NICConf nicconf;
     NICState *nic;
     bool isopen;
-    hwaddr buf_list;
+    target_ulong buf_list;
     uint32_t add_buf_ptr, use_buf_ptr, rx_bufs;
-    hwaddr rxq_ptr;
-    QEMUTimer *rxp_timer;
+    target_ulong rxq_ptr;
     uint32_t compat_flags;             /* Compatability flags for migration */
     RxBufPool *rx_pool[RX_MAX_POOLS];  /* Receive buffer descriptor pools */
 } VIOsPAPRVLANDevice;
@@ -123,21 +121,6 @@ static int spapr_vlan_can_receive(NetClientState *nc)
 }
 
 /**
- * The last 8 bytes of the receive buffer list page (that has been
- * supplied by the guest with the H_REGISTER_LOGICAL_LAN call) contain
- * a counter for frames that have been dropped because there was no
- * suitable receive buffer available. This function is used to increase
- * this counter by one.
- */
-static void spapr_vlan_record_dropped_rx_frame(VIOsPAPRVLANDevice *dev)
-{
-    uint64_t cnt;
-
-    cnt = vio_ldq(&dev->sdev, dev->buf_list + 4096 - 8);
-    vio_stq(&dev->sdev, dev->buf_list + 4096 - 8, cnt + 1);
-}
-
-/**
  * Get buffer descriptor from one of our receive buffer pools
  */
 static vlan_bd_t spapr_vlan_get_rx_bd_from_pool(VIOsPAPRVLANDevice *dev,
@@ -222,8 +205,7 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
     }
 
     if (!dev->rx_bufs) {
-        spapr_vlan_record_dropped_rx_frame(dev);
-        return 0;
+        return -1;
     }
 
     if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
@@ -232,8 +214,7 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
         bd = spapr_vlan_get_rx_bd_from_page(dev, size);
     }
     if (!bd) {
-        spapr_vlan_record_dropped_rx_frame(dev);
-        return 0;
+        return -1;
     }
 
     dev->rx_bufs--;
@@ -278,19 +259,12 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
 }
 
 static NetClientInfo net_spapr_vlan_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .can_receive = spapr_vlan_can_receive,
     .receive = spapr_vlan_receive,
 };
 
-static void spapr_vlan_flush_rx_queue(void *opaque)
-{
-    VIOsPAPRVLANDevice *dev = opaque;
-
-    qemu_flush_queued_packets(qemu_get_queue(dev->nic));
-}
-
 static void spapr_vlan_reset_rx_pool(RxBufPool *rxp)
 {
     /*
@@ -327,9 +301,6 @@ static void spapr_vlan_realize(VIOsPAPRDevice *sdev, Error **errp)
     dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf,
                             object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
     qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
-
-    dev->rxp_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, spapr_vlan_flush_rx_queue,
-                                  dev);
 }
 
 static void spapr_vlan_instance_init(Object *obj)
@@ -360,11 +331,6 @@ static void spapr_vlan_instance_finalize(Object *obj)
             dev->rx_pool[i] = NULL;
         }
     }
-
-    if (dev->rxp_timer) {
-        timer_del(dev->rxp_timer);
-        timer_free(dev->rxp_timer);
-    }
 }
 
 void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd)
@@ -662,13 +628,7 @@ static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu,
 
     dev->rx_bufs++;
 
-    /*
-     * Give guest some more time to add additional RX buffers before we
-     * flush the receive queue, so that e.g. fragmented IP packets can
-     * be passed to the guest in one go later (instead of passing single
-     * fragments if there is only one receive buffer available).
-     */
-    timer_mod(dev->rxp_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 500);
+    qemu_flush_queued_packets(qemu_get_queue(dev->nic));
 
     return H_SUCCESS;
 }
@@ -805,11 +765,11 @@ static const VMStateDescription vmstate_spapr_llan = {
         VMSTATE_SPAPR_VIO(sdev, VIOsPAPRVLANDevice),
         /* LLAN state */
         VMSTATE_BOOL(isopen, VIOsPAPRVLANDevice),
-        VMSTATE_UINT64(buf_list, VIOsPAPRVLANDevice),
+        VMSTATE_UINTTL(buf_list, VIOsPAPRVLANDevice),
         VMSTATE_UINT32(add_buf_ptr, VIOsPAPRVLANDevice),
         VMSTATE_UINT32(use_buf_ptr, VIOsPAPRVLANDevice),
         VMSTATE_UINT32(rx_bufs, VIOsPAPRVLANDevice),
-        VMSTATE_UINT64(rxq_ptr, VIOsPAPRVLANDevice),
+        VMSTATE_UINTTL(rxq_ptr, VIOsPAPRVLANDevice),
 
         VMSTATE_END_OF_LIST()
     },
index 957730e..6880894 100644 (file)
@@ -460,7 +460,7 @@ static void stellaris_enet_reset(stellaris_enet_state *s)
 }
 
 static NetClientInfo net_stellaris_enet_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = stellaris_enet_receive,
 };
diff --git a/hw/net/trace-events b/hw/net/trace-events
deleted file mode 100644 (file)
index 8d38d77..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/net/lance.c
-lance_mem_readw(uint64_t addr, uint32_t ret) "addr=%"PRIx64"val=0x%04x"
-lance_mem_writew(uint64_t addr, uint32_t val) "addr=%"PRIx64"val=0x%04x"
-
-# hw/net/milkymist-minimac2.c
-milkymist_minimac2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_minimac2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_minimac2_mdio_write(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
-milkymist_minimac2_mdio_read(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
-milkymist_minimac2_tx_frame(uint32_t length) "length %u"
-milkymist_minimac2_rx_frame(const void *buf, uint32_t length) "buf %p length %u"
-milkymist_minimac2_rx_transfer(const void *buf, uint32_t length) "buf %p length %d"
-milkymist_minimac2_raise_irq_rx(void) "Raise IRQ RX"
-milkymist_minimac2_lower_irq_rx(void) "Lower IRQ RX"
-milkymist_minimac2_pulse_irq_tx(void) "Pulse IRQ TX"
-
-# hw/net/mipsnet.c
-mipsnet_send(uint32_t size) "sending len=%u"
-mipsnet_receive(uint32_t size) "receiving len=%u"
-mipsnet_read(uint64_t addr, uint32_t val) "read addr=0x%" PRIx64 " val=0x%x"
-mipsnet_write(uint64_t addr, uint64_t val) "write addr=0x%" PRIx64 " val=0x%" PRIx64
-mipsnet_irq(uint32_t isr, uint32_t intctl) "set irq to %d (%02x)"
-
-# hw/net/opencores_eth.c
-open_eth_mii_write(unsigned idx, uint16_t v) "MII[%02x] <- %04x"
-open_eth_mii_read(unsigned idx, uint16_t v) "MII[%02x] -> %04x"
-open_eth_update_irq(uint32_t v) "IRQ <- %x"
-open_eth_receive(unsigned len) "RX: len: %u"
-open_eth_receive_mcast(unsigned idx, uint32_t h0, uint32_t h1) "MCAST: idx = %u, hash: %08x:%08x"
-open_eth_receive_reject(void) "RX: rejected"
-open_eth_receive_desc(uint32_t addr, uint32_t len_flags) "RX: %08x, len_flags: %08x"
-open_eth_start_xmit(uint32_t addr, unsigned len, unsigned tx_len) "TX: %08x, len: %u, tx_len: %u"
-open_eth_reg_read(uint32_t addr, uint32_t v) "MAC[%02x] -> %08x"
-open_eth_reg_write(uint32_t addr, uint32_t v) "MAC[%02x] <- %08x"
-open_eth_desc_read(uint32_t addr, uint32_t v) "DESC[%04x] -> %08x"
-open_eth_desc_write(uint32_t addr, uint32_t v) "DESC[%04x] <- %08x"
-
-# hw/net/pcnet.c
-pcnet_s_reset(void *s) "s=%p"
-pcnet_user_int(void *s) "s=%p"
-pcnet_isr_change(void *s, uint32_t isr, uint32_t isr_old) "s=%p INTA=%d<=%d"
-pcnet_init(void *s, uint64_t init_addr) "s=%p init_addr=%#"PRIx64
-pcnet_rlen_tlen(void *s, uint32_t rlen, uint32_t tlen) "s=%p rlen=%d tlen=%d"
-pcnet_ss32_rdra_tdra(void *s, uint32_t ss32, uint32_t rdra, uint32_t rcvrl, uint32_t tdra, uint32_t xmtrl) "s=%p ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]"
-
-# hw/net/pcnet-pci.c
-pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val) "opaque=%p addr=0x%08x val=0x%02x"
-pcnet_aprom_readb(void *opaque, uint32_t addr, uint32_t val) "opaque=%p addr=0x%08x val=0x%02x"
-pcnet_ioport_read(void *opaque, uint64_t addr, unsigned size) "opaque=%p addr=%#"PRIx64" size=%d"
-pcnet_ioport_write(void *opaque, uint64_t addr, uint64_t data, unsigned size) "opaque=%p addr=%#"PRIx64" data=%#"PRIx64" size=%d"
-pcnet_mmio_writeb(void *opaque, uint64_t addr, uint32_t val) "opaque=%p addr=%#"PRIx64" val=0x%x"
-pcnet_mmio_writew(void *opaque, uint64_t addr, uint32_t val) "opaque=%p addr=%#"PRIx64" val=0x%x"
-pcnet_mmio_writel(void *opaque, uint64_t addr, uint32_t val) "opaque=%p addr=%#"PRIx64" val=0x%x"
-pcnet_mmio_readb(void *opaque, uint64_t addr, uint32_t val) "opaque=%p addr=%#"PRIx64" val=0x%x"
-pcnet_mmio_readw(void *opaque, uint64_t addr, uint32_t val) "opaque=%p addr=%#"PRIx64" val=0x%x"
-pcnet_mmio_readl(void *opaque, uint64_t addr, uint32_t val) "opaque=%p addr=%#"PRIx64" val=0x%x"
-
-# hw/net/net_rx_pkt.c
-net_rx_pkt_parsed(bool ip4, bool ip6, bool udp, bool tcp, size_t l3o, size_t l4o, size_t l5o) "RX packet parsed: ip4: %d, ip6: %d, udp: %d, tcp: %d, l3 offset: %zu, l4 offset: %zu, l5 offset: %zu"
-net_rx_pkt_l4_csum_validate_entry(void) "Starting L4 checksum validation"
-net_rx_pkt_l4_csum_validate_not_xxp(void) "Not a TCP/UDP packet"
-net_rx_pkt_l4_csum_validate_udp_with_no_checksum(void) "UDP packet without checksum"
-net_rx_pkt_l4_csum_validate_ip4_fragment(void) "IP4 fragment"
-net_rx_pkt_l4_csum_validate_ip4_udp(void) "IP4/UDP packet"
-net_rx_pkt_l4_csum_validate_ip4_tcp(void) "IP4/TCP packet"
-net_rx_pkt_l4_csum_validate_ip6_udp(void) "IP6/UDP packet"
-net_rx_pkt_l4_csum_validate_ip6_tcp(void) "IP6/TCP packet"
-net_rx_pkt_l4_csum_validate_csum(bool csum_valid) "Checksum valid: %d"
-
-net_rx_pkt_l4_csum_calc_entry(void) "Starting L4 checksum calculation"
-net_rx_pkt_l4_csum_calc_ip4_udp(void) "IP4/UDP packet"
-net_rx_pkt_l4_csum_calc_ip4_tcp(void) "IP4/TCP packet"
-net_rx_pkt_l4_csum_calc_ip6_udp(void) "IP6/UDP packet"
-net_rx_pkt_l4_csum_calc_ip6_tcp(void) "IP6/TCP packet"
-net_rx_pkt_l4_csum_calc_ph_csum(uint32_t cntr, uint16_t csl) "Pseudo-header: checksum counter %u, length %u"
-net_rx_pkt_l4_csum_calc_csum(size_t l4hdr_off, uint16_t csl, uint32_t cntr, uint16_t csum) "L4 Checksum: L4 header offset: %zu, length: %u, counter: 0x%X, final checksum: 0x%X"
-
-net_rx_pkt_l4_csum_fix_entry(void) "Starting L4 checksum correction"
-net_rx_pkt_l4_csum_fix_tcp(uint32_t l4_cso) "TCP packet, L4 cso: %u"
-net_rx_pkt_l4_csum_fix_udp(uint32_t l4_cso) "UDP packet, L4 cso: %u"
-net_rx_pkt_l4_csum_fix_not_xxp(void) "Not an IP4 packet"
-net_rx_pkt_l4_csum_fix_ip4_fragment(void) "IP4 fragment"
-net_rx_pkt_l4_csum_fix_udp_with_no_checksum(void) "UDP packet without checksum"
-net_rx_pkt_l4_csum_fix_csum(uint32_t cso, uint16_t csum) "L4 Checksum: Offset: %u, value 0x%X"
-
-net_rx_pkt_l3_csum_validate_entry(void) "Starting L3 checksum validation"
-net_rx_pkt_l3_csum_validate_not_ip4(void) "Not an IP4 packet"
-net_rx_pkt_l3_csum_validate_csum(size_t l3hdr_off, uint32_t csl, uint32_t cntr, uint16_t csum, bool csum_valid) "L3 Checksum: L3 header offset: %zu, length: %u, counter: 0x%X, final checksum: 0x%X, valid: %d"
-
-net_rx_pkt_rss_ip4(void) "Calculating IPv4 RSS  hash"
-net_rx_pkt_rss_ip4_tcp(void) "Calculating IPv4/TCP RSS  hash"
-net_rx_pkt_rss_ip6_tcp(void) "Calculating IPv6/TCP RSS  hash"
-net_rx_pkt_rss_ip6(void) "Calculating IPv6 RSS  hash"
-net_rx_pkt_rss_ip6_ex(void) "Calculating IPv6/EX RSS  hash"
-net_rx_pkt_rss_hash(size_t rss_length, uint32_t rss_hash) "RSS hash for %zu bytes: 0x%X"
-net_rx_pkt_rss_add_chunk(void* ptr, size_t size, size_t input_offset) "Add RSS chunk %p, %zu bytes, RSS input offset %zu bytes"
-
-# hw/net/e1000x_common.c
-e1000x_rx_can_recv_disabled(bool link_up, bool rx_enabled, bool pci_master) "link_up: %d, rx_enabled %d, pci_master %d"
-e1000x_vlan_is_vlan_pkt(bool is_vlan_pkt, uint16_t eth_proto, uint16_t vet) "Is VLAN packet: %d, ETH proto: 0x%X, VET: 0x%X"
-e1000x_rx_flt_ucast_match(uint32_t idx, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5) "unicast match[%d]: %02x:%02x:%02x:%02x:%02x:%02x"
-e1000x_rx_flt_ucast_mismatch(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5) "unicast mismatch: %02x:%02x:%02x:%02x:%02x:%02x"
-e1000x_rx_flt_inexact_mismatch(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint32_t mo, uint32_t mta, uint32_t mta_val) "inexact mismatch: %02x:%02x:%02x:%02x:%02x:%02x MO %d MTA[%d] %x"
-e1000x_rx_link_down(uint32_t status_reg) "Received packet dropped because the link is down STATUS = %u"
-e1000x_rx_disabled(uint32_t rctl_reg) "Received packet dropped because receive is disabled RCTL = %u"
-e1000x_rx_oversized(size_t size) "Received packet dropped because it was oversized (%zu bytes)"
-e1000x_mac_indicate(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5) "Indicating MAC to guest: %02x:%02x:%02x:%02x:%02x:%02x"
-e1000x_link_negotiation_start(void) "Start link auto negotiation"
-e1000x_link_negotiation_done(void) "Auto negotiation is completed"
-
-# hw/net/e1000e_core.c
-e1000e_core_write(uint64_t index, uint32_t size, uint64_t val) "Write to register 0x%"PRIx64", %d byte(s), value: 0x%"PRIx64
-e1000e_core_read(uint64_t index, uint32_t size, uint64_t val) "Read from register 0x%"PRIx64", %d byte(s), value: 0x%"PRIx64
-e1000e_core_mdic_read(uint8_t page, uint32_t addr, uint32_t data) "MDIC READ: PHY[%u][%u] = 0x%x"
-e1000e_core_mdic_read_unhandled(uint8_t page, uint32_t addr) "MDIC READ: PHY[%u][%u] UNHANDLED"
-e1000e_core_mdic_write(uint8_t page, uint32_t addr, uint32_t data) "MDIC WRITE: PHY[%u][%u] = 0x%x"
-e1000e_core_mdic_write_unhandled(uint8_t page, uint32_t addr) "MDIC WRITE: PHY[%u][%u] UNHANDLED"
-e1000e_core_eeeprom_write(uint16_t bit_in, uint16_t bit_out, uint16_t reading) "eeprom bitnum in %d out %d, reading %d"
-e1000e_core_ctrl_write(uint64_t index, uint32_t val) "Write CTRL register 0x%"PRIx64", value: 0x%X"
-e1000e_core_ctrl_sw_reset(void) "Doing SW reset"
-e1000e_core_ctrl_phy_reset(void) "Doing PHY reset"
-
-e1000e_link_autoneg_flowctl(bool enabled) "Auto-negotiated flow control state is %d"
-e1000e_link_set_params(bool autodetect, uint32_t speed, bool force_spd, bool force_dplx, bool rx_fctl, bool tx_fctl) "Set link params: Autodetect: %d, Speed: %d, Force speed: %d, Force duplex: %d, RX flow control %d, TX flow control %d"
-e1000e_link_read_params(bool autodetect, uint32_t speed, bool force_spd, bool force_dplx, bool rx_fctl, bool tx_fctl) "Get link params: Autodetect: %d, Speed: %d, Force speed: %d, Force duplex: %d, RX flow control %d, TX flow control %d"
-e1000e_link_set_ext_params(bool asd_check, bool speed_select_bypass) "Set extended link params: ASD check: %d, Speed select bypass: %d"
-e1000e_link_status(bool link_up, bool full_dplx, uint32_t speed, uint32_t asdv) "Link up: %d, Duplex: %d, Speed: %d, ASDV: %d"
-e1000e_link_status_changed(bool status) "New link status: %d"
-
-e1000e_wrn_regs_write_ro(uint64_t index, uint32_t size, uint64_t val) "WARNING: Write to RO register 0x%"PRIx64", %d byte(s), value: 0x%"PRIx64
-e1000e_wrn_regs_write_unknown(uint64_t index, uint32_t size, uint64_t val) "WARNING: Write to unknown register 0x%"PRIx64", %d byte(s), value: 0x%"PRIx64
-e1000e_wrn_regs_read_unknown(uint64_t index, uint32_t size) "WARNING: Read from unknown register 0x%"PRIx64", %d byte(s)"
-e1000e_wrn_regs_read_trivial(uint32_t index) "WARNING: Reading register at offset: 0x%05x. It is not fully implemented."
-e1000e_wrn_regs_write_trivial(uint32_t index) "WARNING: Writing to register at offset: 0x%05x. It is not fully implemented."
-e1000e_wrn_no_ts_support(void) "WARNING: Guest requested TX timestamping which is not supported"
-e1000e_wrn_no_snap_support(void) "WARNING: Guest requested TX SNAP header update which is not supported"
-e1000e_wrn_iscsi_filtering_not_supported(void) "WARNING: Guest requested iSCSI filtering  which is not supported"
-e1000e_wrn_nfsw_filtering_not_supported(void) "WARNING: Guest requested NFS write filtering  which is not supported"
-e1000e_wrn_nfsr_filtering_not_supported(void) "WARNING: Guest requested NFS read filtering  which is not supported"
-
-e1000e_tx_disabled(void) "TX Disabled"
-e1000e_tx_descr(void *addr, uint32_t lower, uint32_t upper) "%p : %x %x"
-
-e1000e_ring_free_space(int ridx, uint32_t rdlen, uint32_t rdh, uint32_t rdt) "ring #%d: LEN: %u, DH: %u, DT: %u"
-
-e1000e_rx_can_recv_rings_full(void) "Cannot receive: all rings are full"
-e1000e_rx_can_recv(void) "Can receive"
-e1000e_rx_has_buffers(int ridx, uint32_t free_desc, size_t total_size, uint32_t desc_buf_size) "ring #%d: free descr: %u, packet size %zu, descr buffer size %u"
-e1000e_rx_null_descriptor(void) "Null RX descriptor!!"
-e1000e_rx_flt_vlan_mismatch(uint16_t vid) "VID mismatch: 0x%X"
-e1000e_rx_flt_vlan_match(uint16_t vid) "VID match: 0x%X"
-e1000e_rx_desc_ps_read(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3) "buffers: [0x%"PRIx64", 0x%"PRIx64", 0x%"PRIx64", 0x%"PRIx64"]"
-e1000e_rx_desc_ps_write(uint16_t a0, uint16_t a1, uint16_t a2, uint16_t a3) "bytes written: [%u, %u, %u, %u]"
-e1000e_rx_desc_buff_sizes(uint32_t b0, uint32_t b1, uint32_t b2, uint32_t b3) "buffer sizes: [%u, %u, %u, %u]"
-e1000e_rx_desc_len(uint8_t rx_desc_len) "RX descriptor length: %u"
-e1000e_rx_desc_buff_write(uint8_t idx, uint64_t addr, uint16_t offset, const void* source, uint32_t len) "buffer #%u, addr: 0x%"PRIx64", offset: %u, from: %p, length: %u"
-e1000e_rx_descr(int ridx, uint64_t base, uint8_t len) "Next RX descriptor: ring #%d, PA: 0x%"PRIx64", length: %u"
-e1000e_rx_set_rctl(uint32_t rctl) "RCTL = 0x%x"
-e1000e_rx_receive_iov(int iovcnt) "Received vector of %d fragments"
-e1000e_rx_packet_size(size_t full, size_t vhdr, size_t data) "Received packet of %zu bytes total, %zu virt header, %zu data"
-e1000e_rx_flt_dropped(void) "Received packet dropped by RX filter"
-e1000e_rx_written_to_guest(uint32_t causes) "Received packet written to guest (ICR causes %u)"
-e1000e_rx_not_written_to_guest(uint32_t causes) "Received packet NOT written to guest (ICR causes %u)"
-e1000e_rx_interrupt_set(uint32_t causes) "Receive interrupt set (ICR causes %u)"
-e1000e_rx_interrupt_delayed(uint32_t causes) "Receive interrupt delayed (ICR causes %u)"
-e1000e_rx_set_cso(int cso_state) "RX CSO state set to %d"
-e1000e_rx_set_rdt(int queue_idx, uint32_t val) "Setting RDT[%d] = %u"
-e1000e_rx_set_rfctl(uint32_t val) "Setting RFCTL = 0x%X"
-e1000e_rx_start_recv(void)
-
-e1000e_rx_rss_started(void) "Starting RSS processing"
-e1000e_rx_rss_disabled(void) "RSS is disabled"
-e1000e_rx_rss_type(uint32_t type) "RSS type is %u"
-e1000e_rx_rss_ip4(bool isfragment, bool istcp, uint32_t mrqc, bool tcpipv4_enabled, bool ipv4_enabled) "RSS IPv4: fragment %d, tcp %d, mrqc 0x%X, tcpipv4 enabled %d, ipv4 enabled %d"
-e1000e_rx_rss_ip6_rfctl(uint32_t rfctl) "RSS IPv6: rfctl 0x%X"
-e1000e_rx_rss_ip6(bool ex_dis, bool new_ex_dis, bool istcp, bool has_ext_headers, bool ex_dst_valid, bool ex_src_valid, uint32_t mrqc, bool tcpipv6_enabled, bool ipv6ex_enabled, bool ipv6_enabled) "RSS IPv6: ex_dis: %d, new_ex_dis: %d, tcp %d, has_ext_headers %d, ex_dst_valid %d, ex_src_valid %d, mrqc 0x%X, tcpipv6 enabled %d, ipv6ex enabled %d, ipv6 enabled %d"
-e1000e_rx_rss_dispatched_to_queue(int queue_idx) "Packet being dispatched to queue %d"
-
-e1000e_rx_metadata_protocols(bool isip4, bool isip6, bool isudp, bool istcp) "protocols: ip4: %d, ip6: %d, udp: %d, tcp: %d"
-e1000e_rx_metadata_vlan(uint16_t vlan_tag) "VLAN tag is 0x%X"
-e1000e_rx_metadata_rss(uint32_t rss, uint32_t mrq) "RSS data: rss: 0x%X, mrq: 0x%X"
-e1000e_rx_metadata_ip_id(uint16_t ip_id) "the IPv4 ID is 0x%X"
-e1000e_rx_metadata_ack(void) "the packet is TCP ACK"
-e1000e_rx_metadata_pkt_type(uint32_t pkt_type) "the packet type is %u"
-e1000e_rx_metadata_no_virthdr(void) "the packet has no virt-header"
-e1000e_rx_metadata_virthdr_no_csum_info(void) "virt-header does not contain checksum info"
-e1000e_rx_metadata_l3_cso_disabled(void) "IP4 CSO is disabled"
-e1000e_rx_metadata_l4_cso_disabled(void) "TCP/UDP CSO is disabled"
-e1000e_rx_metadata_l3_csum_validation_failed(void) "Cannot validate L3 checksum"
-e1000e_rx_metadata_l4_csum_validation_failed(void) "Cannot validate L4 checksum"
-e1000e_rx_metadata_status_flags(uint32_t status_flags) "status_flags is 0x%X"
-e1000e_rx_metadata_ipv6_sum_disabled(void) "IPv6 RX checksummimg disabled by RFCTL"
-e1000e_rx_metadata_ipv6_filtering_disabled(void) "IPv6 RX filtering disabled by RFCTL"
-
-e1000e_vlan_vet(uint16_t vet) "Setting VLAN ethernet type 0x%X"
-
-e1000e_irq_set_cause(uint32_t cause) "IRQ cause set 0x%x"
-e1000e_irq_msi_notify(uint32_t cause) "MSI notify 0x%x"
-e1000e_irq_throttling_no_pending_interrupts(void) "No pending interrupts to notify"
-e1000e_irq_msi_notify_postponed(void) "Sending MSI postponed by ITR"
-e1000e_irq_legacy_notify_postponed(void) "Raising legacy IRQ postponed by ITR"
-e1000e_irq_throttling_no_pending_vec(int idx) "No pending interrupts for vector %d"
-e1000e_irq_msix_notify_postponed_vec(int idx) "Sending MSI-X postponed by EITR[%d]"
-e1000e_irq_msix_notify(uint32_t cause) "MSI-X notify 0x%x"
-e1000e_irq_legacy_notify(bool level) "IRQ line state: %d"
-e1000e_irq_msix_notify_vec(uint32_t vector) "MSI-X notify vector 0x%x"
-e1000e_irq_postponed_by_xitr(uint32_t reg) "Interrupt postponed by [E]ITR register 0x%x"
-e1000e_irq_clear_ims(uint32_t bits, uint32_t old_ims, uint32_t new_ims) "Clearing IMS bits 0x%x: 0x%x --> 0x%x"
-e1000e_irq_set_ims(uint32_t bits, uint32_t old_ims, uint32_t new_ims) "Setting IMS bits 0x%x: 0x%x --> 0x%x"
-e1000e_irq_fix_icr_asserted(uint32_t new_val) "ICR_ASSERTED bit fixed: 0x%x"
-e1000e_irq_add_msi_other(uint32_t new_val) "ICR_OTHER bit added: 0x%x"
-e1000e_irq_pending_interrupts(uint32_t pending, uint32_t icr, uint32_t ims) "ICR PENDING: 0x%x (ICR: 0x%x, IMS: 0x%x)"
-e1000e_irq_set_cause_entry(uint32_t val, uint32_t icr) "Going to set IRQ cause 0x%x, ICR: 0x%x"
-e1000e_irq_set_cause_exit(uint32_t val, uint32_t icr) "Set IRQ cause 0x%x, ICR: 0x%x"
-e1000e_irq_icr_write(uint32_t bits, uint32_t old_icr, uint32_t new_icr) "Clearing ICR bits 0x%x: 0x%x --> 0x%x"
-e1000e_irq_write_ics(uint32_t val) "Adding ICR bits 0x%x"
-e1000e_irq_icr_process_iame(void) "Clearing IMS bits due to IAME"
-e1000e_irq_read_ics(uint32_t ics) "Current ICS: 0x%x"
-e1000e_irq_read_ims(uint32_t ims) "Current IMS: 0x%x"
-e1000e_irq_icr_read_entry(uint32_t icr) "Starting ICR read. Current ICR: 0x%x"
-e1000e_irq_icr_read_exit(uint32_t icr) "Ending ICR read. Current ICR: 0x%x"
-e1000e_irq_icr_clear_zero_ims(void) "Clearing ICR on read due to zero IMS"
-e1000e_irq_icr_clear_iame(void) "Clearing ICR on read due to IAME"
-e1000e_irq_ims_clear_eiame(uint32_t iam, uint32_t cause) "Clearing IMS due to EIAME, IAM: 0x%X, cause: 0x%X"
-e1000e_irq_icr_clear_eiac(uint32_t icr, uint32_t eiac) "Clearing ICR bits due to EIAC, ICR: 0x%X, EIAC: 0x%X"
-e1000e_irq_ims_clear_set_imc(uint32_t val) "Clearing IMS bits due to IMC write 0x%x"
-e1000e_irq_fire_delayed_interrupts(void) "Firing delayed interrupts"
-e1000e_irq_rearm_timer(uint32_t reg, int64_t delay_ns) "Mitigation timer armed for register 0x%X, delay %"PRId64" ns"
-e1000e_irq_throttling_timer(uint32_t reg) "Mitigation timer shot for register 0x%X"
-e1000e_irq_rdtr_fpd_running(void) "FPD written while RDTR was running"
-e1000e_irq_rdtr_fpd_not_running(void) "FPD written while RDTR was not running"
-e1000e_irq_tidv_fpd_running(void) "FPD written while TIDV was running"
-e1000e_irq_tidv_fpd_not_running(void) "FPD written while TIDV was not running"
-e1000e_irq_eitr_set(uint32_t eitr_num, uint32_t val) "EITR[%u] = %u"
-e1000e_irq_itr_set(uint32_t val) "ITR = %u"
-e1000e_irq_fire_all_timers(uint32_t val) "Firing all delay/throttling timers on all interrupts enable (0x%X written to IMS)"
-e1000e_irq_adding_delayed_causes(uint32_t val, uint32_t icr) "Merging delayed causes 0x%X to ICR 0x%X"
-e1000e_irq_msix_pending_clearing(uint32_t cause, uint32_t int_cfg, uint32_t vec) "Clearing MSI-X pending bit for cause 0x%x, IVAR config 0x%x, vector %u"
-
-e1000e_wrn_msix_vec_wrong(uint32_t cause, uint32_t cfg) "Invalid configuration for cause 0x%x: 0x%x"
-e1000e_wrn_msix_invalid(uint32_t cause, uint32_t cfg) "Invalid entry for cause 0x%x: 0x%x"
-
-e1000e_mac_set_permanent(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5) "Set permanent MAC: %02x:%02x:%02x:%02x:%02x:%02x"
-e1000e_mac_set_sw(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5) "Set SW MAC: %02x:%02x:%02x:%02x:%02x:%02x"
-
-# hw/net/e1000e.c
-e1000e_cb_pci_realize(void) "E1000E PCI realize entry"
-e1000e_cb_pci_uninit(void) "E1000E PCI unit entry"
-e1000e_cb_qdev_reset(void) "E1000E qdev reset entry"
-e1000e_cb_pre_save(void) "E1000E pre save entry"
-e1000e_cb_post_load(void) "E1000E post load entry"
-
-e1000e_io_write_addr(uint64_t addr) "IOADDR write 0x%"PRIx64
-e1000e_io_write_data(uint64_t addr, uint64_t val) "IODATA write 0x%"PRIx64", value: 0x%"PRIx64
-e1000e_io_read_addr(uint64_t addr) "IOADDR read 0x%"PRIx64
-e1000e_io_read_data(uint64_t addr, uint64_t val) "IODATA read 0x%"PRIx64", value: 0x%"PRIx64
-e1000e_wrn_io_write_unknown(uint64_t addr) "IO write unknown address 0x%"PRIx64
-e1000e_wrn_io_read_unknown(uint64_t addr) "IO read unknown address 0x%"PRIx64
-e1000e_wrn_io_addr_undefined(uint64_t addr) "IO undefined register 0x%"PRIx64
-e1000e_wrn_io_addr_flash(uint64_t addr) "IO flash access (0x%"PRIx64") not implemented"
-e1000e_wrn_io_addr_unknown(uint64_t addr) "IO unknown register 0x%"PRIx64
-
-e1000e_msi_init_fail(int32_t res) "Failed to initialize MSI, error %d"
-e1000e_msix_init_fail(int32_t res) "Failed to initialize MSI-X, error %d"
-e1000e_msix_use_vector_fail(uint32_t vec, int32_t res) "Failed to use MSI-X vector %d, error %d"
-
-e1000e_cfg_support_virtio(bool support) "Virtio header supported: %d"
-
-e1000e_vm_state_running(void) "VM state is running"
-e1000e_vm_state_stopped(void) "VM state is stopped"
index f2d49ad..6e1032f 100644 (file)
@@ -88,10 +88,10 @@ static const int *vhost_net_get_feature_bits(struct vhost_net *net)
     const int *feature_bits = 0;
 
     switch (net->nc->info->type) {
-    case NET_CLIENT_DRIVER_TAP:
+    case NET_CLIENT_OPTIONS_KIND_TAP:
         feature_bits = kernel_feature_bits;
         break;
-    case NET_CLIENT_DRIVER_VHOST_USER:
+    case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
         feature_bits = user_feature_bits;
         break;
     default:
@@ -120,15 +120,10 @@ uint64_t vhost_net_get_max_queues(VHostNetState *net)
     return net->dev.max_queues;
 }
 
-uint64_t vhost_net_get_acked_features(VHostNetState *net)
-{
-    return net->dev.acked_features;
-}
-
 static int vhost_net_get_fd(NetClientState *backend)
 {
     switch (backend->info->type) {
-    case NET_CLIENT_DRIVER_TAP:
+    case NET_CLIENT_OPTIONS_KIND_TAP:
         return tap_get_fd(backend);
     default:
         fprintf(stderr, "vhost-net requires tap backend\n");
@@ -140,8 +135,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
 {
     int r;
     bool backend_kernel = options->backend_type == VHOST_BACKEND_TYPE_KERNEL;
-    struct vhost_net *net = g_new0(struct vhost_net, 1);
-    uint64_t features = 0;
+    struct vhost_net *net = g_malloc(sizeof *net);
 
     if (!options->net_backend) {
         fprintf(stderr, "vhost-net requires net backend to be setup\n");
@@ -172,7 +166,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
     }
 
     r = vhost_dev_init(&net->dev, options->opaque,
-                       options->backend_type, options->busyloop_timeout);
+                       options->backend_type);
     if (r < 0) {
         goto fail;
     }
@@ -185,27 +179,14 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
             fprintf(stderr, "vhost lacks feature mask %" PRIu64
                    " for backend\n",
                    (uint64_t)(~net->dev.features & net->dev.backend_features));
+            vhost_dev_cleanup(&net->dev);
             goto fail;
         }
     }
-
     /* Set sane init value. Override when guest acks. */
-    if (net->nc->info->type == NET_CLIENT_DRIVER_VHOST_USER) {
-        features = vhost_user_get_acked_features(net->nc);
-        if (~net->dev.features & features) {
-            fprintf(stderr, "vhost lacks feature mask %" PRIu64
-                    " for backend\n",
-                    (uint64_t)(~net->dev.features & features));
-            goto fail;
-        }
-    }
-
-    vhost_net_ack_features(net, features);
-
+    vhost_net_ack_features(net, 0);
     return net;
-
 fail:
-    vhost_dev_cleanup(&net->dev);
     g_free(net);
     return NULL;
 }
@@ -238,11 +219,12 @@ static int vhost_net_start_one(struct vhost_net *net,
         net->nc->info->poll(net->nc, false);
     }
 
-    if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
+    if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) {
         qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
         file.fd = net->backend;
         for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
-            r = vhost_net_set_backend(&net->dev, &file);
+            const VhostOps *vhost_ops = net->dev.vhost_ops;
+            r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
             if (r < 0) {
                 r = -errno;
                 goto fail;
@@ -252,9 +234,10 @@ static int vhost_net_start_one(struct vhost_net *net,
     return 0;
 fail:
     file.fd = -1;
-    if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
+    if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) {
         while (file.index-- > 0) {
-            int r = vhost_net_set_backend(&net->dev, &file);
+            const VhostOps *vhost_ops = net->dev.vhost_ops;
+            int r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
             assert(r >= 0);
         }
     }
@@ -273,9 +256,10 @@ static void vhost_net_stop_one(struct vhost_net *net,
 {
     struct vhost_vring_file file = { .fd = -1 };
 
-    if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
+    if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) {
         for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
-            int r = vhost_net_set_backend(&net->dev, &file);
+            const VhostOps *vhost_ops = net->dev.vhost_ops;
+            int r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
             assert(r >= 0);
         }
     }
@@ -309,8 +293,8 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
          * because vhost user doesn't interrupt masking/unmasking
          * properly.
          */
-        if (net->nc->info->type == NET_CLIENT_DRIVER_VHOST_USER) {
-            dev->use_guest_notifier_mask = false;
+        if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER) {
+                dev->use_guest_notifier_mask = false;
         }
      }
 
@@ -326,15 +310,6 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
         if (r < 0) {
             goto err_start;
         }
-
-        if (ncs[i].peer->vring_enable) {
-            /* restore vring enable state */
-            r = vhost_set_vring_enable(ncs[i].peer, ncs[i].peer->vring_enable);
-
-            if (r < 0) {
-                goto err_start;
-            }
-        }
     }
 
     return 0;
@@ -375,16 +350,19 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
 void vhost_net_cleanup(struct vhost_net *net)
 {
     vhost_dev_cleanup(&net->dev);
+    g_free(net);
 }
 
 int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
 {
     const VhostOps *vhost_ops = net->dev.vhost_ops;
+    int r = -1;
 
-    assert(vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
-    assert(vhost_ops->vhost_migration_done);
+    if (vhost_ops->vhost_migration_done) {
+        r = vhost_ops->vhost_migration_done(&net->dev, mac_addr);
+    }
 
-    return vhost_ops->vhost_migration_done(&net->dev, mac_addr);
+    return r;
 }
 
 bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
@@ -407,12 +385,11 @@ VHostNetState *get_vhost_net(NetClientState *nc)
     }
 
     switch (nc->info->type) {
-    case NET_CLIENT_DRIVER_TAP:
+    case NET_CLIENT_OPTIONS_KIND_TAP:
         vhost_net = tap_get_vhost_net(nc);
         break;
-    case NET_CLIENT_DRIVER_VHOST_USER:
+    case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
         vhost_net = vhost_user_get_vhost_net(nc);
-        assert(vhost_net);
         break;
     default:
         break;
@@ -426,9 +403,7 @@ int vhost_set_vring_enable(NetClientState *nc, int enable)
     VHostNetState *net = get_vhost_net(nc);
     const VhostOps *vhost_ops = net->dev.vhost_ops;
 
-    nc->vring_enable = enable;
-
-    if (vhost_ops && vhost_ops->vhost_set_vring_enable) {
+    if (vhost_ops->vhost_set_vring_enable) {
         return vhost_ops->vhost_set_vring_enable(&net->dev, enable);
     }
 
@@ -467,16 +442,10 @@ uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features)
 {
     return features;
 }
-
 void vhost_net_ack_features(struct vhost_net *net, uint64_t features)
 {
 }
 
-uint64_t vhost_net_get_acked_features(VHostNetState *net)
-{
-    return 0;
-}
-
 bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
 {
     return false;
index 01f1351..8aaa103 100644 (file)
@@ -468,11 +468,11 @@ static int peer_attach(VirtIONet *n, int index)
         return 0;
     }
 
-    if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) {
+    if (nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER) {
         vhost_set_vring_enable(nc->peer, 1);
     }
 
-    if (nc->peer->info->type != NET_CLIENT_DRIVER_TAP) {
+    if (nc->peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP) {
         return 0;
     }
 
@@ -487,11 +487,11 @@ static int peer_detach(VirtIONet *n, int index)
         return 0;
     }
 
-    if (nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) {
+    if (nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER) {
         vhost_set_vring_enable(nc->peer, 0);
     }
 
-    if (nc->peer->info->type !=  NET_CLIENT_DRIVER_TAP) {
+    if (nc->peer->info->type !=  NET_CLIENT_OPTIONS_KIND_TAP) {
         return 0;
     }
 
@@ -1051,7 +1051,7 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
     ptr += n->host_hdr_len;
 
     if (!memcmp(&ptr[12], vlan, sizeof(vlan))) {
-        int vid = lduw_be_p(ptr + 14) & 0xfff;
+        int vid = be16_to_cpup((uint16_t *)(ptr + 14)) & 0xfff;
         if (!(n->vlans[vid >> 5] & (1U << (vid & 0x1f))))
             return 0;
     }
@@ -1492,7 +1492,7 @@ static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue)
     virtio_net_set_queues(n);
 }
 
-static void virtio_net_save(QEMUFile *f, void *opaque, size_t size)
+static void virtio_net_save(QEMUFile *f, void *opaque)
 {
     VirtIONet *n = opaque;
     VirtIODevice *vdev = VIRTIO_DEVICE(n);
@@ -1538,12 +1538,15 @@ static void virtio_net_save_device(VirtIODevice *vdev, QEMUFile *f)
     }
 }
 
-static int virtio_net_load(QEMUFile *f, void *opaque, size_t size)
+static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
 {
     VirtIONet *n = opaque;
     VirtIODevice *vdev = VIRTIO_DEVICE(n);
 
-    return virtio_load(vdev, f, VIRTIO_NET_VM_VERSION);
+    if (version_id < 2 || version_id > VIRTIO_NET_VM_VERSION)
+        return -EINVAL;
+
+    return virtio_load(vdev, f, version_id);
 }
 
 static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
@@ -1559,49 +1562,68 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
                                virtio_vdev_has_feature(vdev,
                                                        VIRTIO_F_VERSION_1));
 
-    n->status = qemu_get_be16(f);
-
-    n->promisc = qemu_get_byte(f);
-    n->allmulti = qemu_get_byte(f);
+    if (version_id >= 3)
+        n->status = qemu_get_be16(f);
 
-    n->mac_table.in_use = qemu_get_be32(f);
-    /* MAC_TABLE_ENTRIES may be different from the saved image */
-    if (n->mac_table.in_use <= MAC_TABLE_ENTRIES) {
-        qemu_get_buffer(f, n->mac_table.macs,
-                        n->mac_table.in_use * ETH_ALEN);
-    } else {
-        int64_t i;
+    if (version_id >= 4) {
+        if (version_id < 8) {
+            n->promisc = qemu_get_be32(f);
+            n->allmulti = qemu_get_be32(f);
+        } else {
+            n->promisc = qemu_get_byte(f);
+            n->allmulti = qemu_get_byte(f);
+        }
+    }
 
-        /* Overflow detected - can happen if source has a larger MAC table.
-         * We simply set overflow flag so there's no need to maintain the
-         * table of addresses, discard them all.
-         * Note: 64 bit math to avoid integer overflow.
-         */
-        for (i = 0; i < (int64_t)n->mac_table.in_use * ETH_ALEN; ++i) {
-            qemu_get_byte(f);
+    if (version_id >= 5) {
+        n->mac_table.in_use = qemu_get_be32(f);
+        /* MAC_TABLE_ENTRIES may be different from the saved image */
+        if (n->mac_table.in_use <= MAC_TABLE_ENTRIES) {
+            qemu_get_buffer(f, n->mac_table.macs,
+                            n->mac_table.in_use * ETH_ALEN);
+        } else {
+            int64_t i;
+
+            /* Overflow detected - can happen if source has a larger MAC table.
+             * We simply set overflow flag so there's no need to maintain the
+             * table of addresses, discard them all.
+             * Note: 64 bit math to avoid integer overflow.
+             */
+            for (i = 0; i < (int64_t)n->mac_table.in_use * ETH_ALEN; ++i) {
+                qemu_get_byte(f);
+            }
+            n->mac_table.multi_overflow = n->mac_table.uni_overflow = 1;
+            n->mac_table.in_use = 0;
         }
-        n->mac_table.multi_overflow = n->mac_table.uni_overflow = 1;
-        n->mac_table.in_use = 0;
     }
  
-    qemu_get_buffer(f, (uint8_t *)n->vlans, MAX_VLAN >> 3);
+    if (version_id >= 6)
+        qemu_get_buffer(f, (uint8_t *)n->vlans, MAX_VLAN >> 3);
 
-    if (qemu_get_be32(f) && !peer_has_vnet_hdr(n)) {
-        error_report("virtio-net: saved image requires vnet_hdr=on");
-        return -1;
+    if (version_id >= 7) {
+        if (qemu_get_be32(f) && !peer_has_vnet_hdr(n)) {
+            error_report("virtio-net: saved image requires vnet_hdr=on");
+            return -1;
+        }
     }
 
-    n->mac_table.multi_overflow = qemu_get_byte(f);
-    n->mac_table.uni_overflow = qemu_get_byte(f);
+    if (version_id >= 9) {
+        n->mac_table.multi_overflow = qemu_get_byte(f);
+        n->mac_table.uni_overflow = qemu_get_byte(f);
+    }
 
-    n->alluni = qemu_get_byte(f);
-    n->nomulti = qemu_get_byte(f);
-    n->nouni = qemu_get_byte(f);
-    n->nobcast = qemu_get_byte(f);
+    if (version_id >= 10) {
+        n->alluni = qemu_get_byte(f);
+        n->nomulti = qemu_get_byte(f);
+        n->nouni = qemu_get_byte(f);
+        n->nobcast = qemu_get_byte(f);
+    }
 
-    if (qemu_get_byte(f) && !peer_has_ufo(n)) {
-        error_report("virtio-net: saved image requires TUN_F_UFO support");
-        return -1;
+    if (version_id >= 11) {
+        if (qemu_get_byte(f) && !peer_has_ufo(n)) {
+            error_report("virtio-net: saved image requires TUN_F_UFO support");
+            return -1;
+        }
     }
 
     if (n->max_queues > 1) {
@@ -1658,7 +1680,7 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
 }
 
 static NetClientInfo net_virtio_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .can_receive = virtio_net_can_receive,
     .receive = virtio_net_receive,
@@ -1787,6 +1809,8 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
     nc->rxfilter_notify_enabled = 1;
 
     n->qdev = dev;
+    register_savevm(dev, "virtio-net", -1, VIRTIO_NET_VM_VERSION,
+                    virtio_net_save, virtio_net_load, n);
 }
 
 static void virtio_net_device_unrealize(DeviceState *dev, Error **errp)
@@ -1798,6 +1822,8 @@ static void virtio_net_device_unrealize(DeviceState *dev, Error **errp)
     /* This will stop vhost backend if appropriate. */
     virtio_net_set_status(vdev, 0);
 
+    unregister_savevm(dev, "virtio-net", n);
+
     g_free(n->netclient_name);
     n->netclient_name = NULL;
     g_free(n->netclient_type);
@@ -1832,9 +1858,6 @@ static void virtio_net_instance_init(Object *obj)
                                   DEVICE(n), NULL);
 }
 
-VMSTATE_VIRTIO_DEVICE(net, VIRTIO_NET_VM_VERSION, virtio_net_load,
-                      virtio_net_save);
-
 static Property virtio_net_properties[] = {
     DEFINE_PROP_BIT("csum", VirtIONet, host_features, VIRTIO_NET_F_CSUM, true),
     DEFINE_PROP_BIT("guest_csum", VirtIONet, host_features,
@@ -1889,7 +1912,6 @@ static void virtio_net_class_init(ObjectClass *klass, void *data)
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
 
     dc->props = virtio_net_properties;
-    dc->vmsd = &vmstate_virtio_net;
     set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
     vdc->realize = virtio_net_device_realize;
     vdc->unrealize = virtio_net_device_unrealize;
index 5500601..c0dbb2f 100644 (file)
  *
  */
 static inline void
-vmw_shmem_read(PCIDevice *d, hwaddr addr, void *buf, int len)
+vmw_shmem_read(hwaddr addr, void *buf, int len)
 {
     VMW_SHPRN("SHMEM r: %" PRIx64 ", len: %d to %p", addr, len, buf);
-    pci_dma_read(d, addr, buf, len);
+    cpu_physical_memory_read(addr, buf, len);
 }
 
 static inline void
-vmw_shmem_write(PCIDevice *d, hwaddr addr, void *buf, int len)
+vmw_shmem_write(hwaddr addr, void *buf, int len)
 {
     VMW_SHPRN("SHMEM w: %" PRIx64 ", len: %d to %p", addr, len, buf);
-    pci_dma_write(d, addr, buf, len);
+    cpu_physical_memory_write(addr, buf, len);
 }
 
 static inline void
-vmw_shmem_rw(PCIDevice *d, hwaddr addr, void *buf, int len, int is_write)
+vmw_shmem_rw(hwaddr addr, void *buf, int len, int is_write)
 {
     VMW_SHPRN("SHMEM r/w: %" PRIx64 ", len: %d (to %p), is write: %d",
               addr, len, buf, is_write);
 
-    if (is_write)
-        pci_dma_write(d, addr, buf, len);
-    else
-        pci_dma_read(d, addr, buf, len);
+    cpu_physical_memory_rw(addr, buf, len, is_write);
 }
 
 static inline void
-vmw_shmem_set(PCIDevice *d, hwaddr addr, uint8_t val, int len)
+vmw_shmem_set(hwaddr addr, uint8_t val, int len)
 {
     int i;
     VMW_SHPRN("SHMEM set: %" PRIx64 ", len: %d (value 0x%X)", addr, len, val);
 
     for (i = 0; i < len; i++) {
-        pci_dma_write(d, addr + i, &val, 1);
+        cpu_physical_memory_write(addr + i, &val, 1);
     }
 }
 
 static inline uint32_t
-vmw_shmem_ld8(PCIDevice *d, hwaddr addr)
+vmw_shmem_ld8(hwaddr addr)
 {
-    uint8_t res;
-    pci_dma_read(d, addr, &res, 1);
+    uint8_t res = ldub_phys(&address_space_memory, addr);
     VMW_SHPRN("SHMEM load8: %" PRIx64 " (value 0x%X)", addr, res);
     return res;
 }
 
 static inline void
-vmw_shmem_st8(PCIDevice *d, hwaddr addr, uint8_t value)
+vmw_shmem_st8(hwaddr addr, uint8_t value)
 {
     VMW_SHPRN("SHMEM store8: %" PRIx64 " (value 0x%X)", addr, value);
-    pci_dma_write(d, addr, &value, 1);
+    stb_phys(&address_space_memory, addr, value);
 }
 
 static inline uint32_t
-vmw_shmem_ld16(PCIDevice *d, hwaddr addr)
+vmw_shmem_ld16(hwaddr addr)
 {
-    uint16_t res;
-    pci_dma_read(d, addr, &res, 2);
+    uint16_t res = lduw_le_phys(&address_space_memory, addr);
     VMW_SHPRN("SHMEM load16: %" PRIx64 " (value 0x%X)", addr, res);
     return res;
 }
 
 static inline void
-vmw_shmem_st16(PCIDevice *d, hwaddr addr, uint16_t value)
+vmw_shmem_st16(hwaddr addr, uint16_t value)
 {
     VMW_SHPRN("SHMEM store16: %" PRIx64 " (value 0x%X)", addr, value);
-    pci_dma_write(d, addr, &value, 2);
+    stw_le_phys(&address_space_memory, addr, value);
 }
 
 static inline uint32_t
-vmw_shmem_ld32(PCIDevice *d, hwaddr addr)
+vmw_shmem_ld32(hwaddr addr)
 {
-    uint32_t res;
-    pci_dma_read(d, addr, &res, 4);
+    uint32_t res = ldl_le_phys(&address_space_memory, addr);
     VMW_SHPRN("SHMEM load32: %" PRIx64 " (value 0x%X)", addr, res);
     return res;
 }
 
 static inline void
-vmw_shmem_st32(PCIDevice *d, hwaddr addr, uint32_t value)
+vmw_shmem_st32(hwaddr addr, uint32_t value)
 {
     VMW_SHPRN("SHMEM store32: %" PRIx64 " (value 0x%X)", addr, value);
-    pci_dma_write(d, addr, &value, 4);
+    stl_le_phys(&address_space_memory, addr, value);
 }
 
 static inline uint64_t
-vmw_shmem_ld64(PCIDevice *d, hwaddr addr)
+vmw_shmem_ld64(hwaddr addr)
 {
-    uint64_t res;
-    pci_dma_read(d, addr, &res, 8);
+    uint64_t res = ldq_le_phys(&address_space_memory, addr);
     VMW_SHPRN("SHMEM load64: %" PRIx64 " (value %" PRIx64 ")", addr, res);
     return res;
 }
 
 static inline void
-vmw_shmem_st64(PCIDevice *d, hwaddr addr, uint64_t value)
+vmw_shmem_st64(hwaddr addr, uint64_t value)
 {
     VMW_SHPRN("SHMEM store64: %" PRIx64 " (value %" PRIx64 ")", addr, value);
-    pci_dma_write(d, addr, &value, 8);
+    stq_le_phys(&address_space_memory, addr, value);
 }
 
 /* Macros for simplification of operations on array-style registers */
index 90f6943..20f26b7 100644 (file)
@@ -30,8 +30,8 @@
 #include "vmxnet3.h"
 #include "vmxnet_debug.h"
 #include "vmware_utils.h"
-#include "net_tx_pkt.h"
-#include "net_rx_pkt.h"
+#include "vmxnet_tx_pkt.h"
+#include "vmxnet_rx_pkt.h"
 
 #define PCI_DEVICE_ID_VMWARE_VMXNET3_REVISION 0x1
 #define VMXNET3_MSIX_BAR_SIZE 0x2000
 #define VMXNET3_MAX_NMSIX_INTRS   (1)
 
 /* Macros for rings descriptors access */
-#define VMXNET3_READ_TX_QUEUE_DESCR8(_d, dpa, field) \
-    (vmw_shmem_ld8(_d, dpa + offsetof(struct Vmxnet3_TxQueueDesc, field)))
+#define VMXNET3_READ_TX_QUEUE_DESCR8(dpa, field) \
+    (vmw_shmem_ld8(dpa + offsetof(struct Vmxnet3_TxQueueDesc, field)))
 
-#define VMXNET3_WRITE_TX_QUEUE_DESCR8(_d, dpa, field, value) \
-    (vmw_shmem_st8(_d, dpa + offsetof(struct Vmxnet3_TxQueueDesc, field, value)))
+#define VMXNET3_WRITE_TX_QUEUE_DESCR8(dpa, field, value) \
+    (vmw_shmem_st8(dpa + offsetof(struct Vmxnet3_TxQueueDesc, field, value)))
 
-#define VMXNET3_READ_TX_QUEUE_DESCR32(_d, dpa, field) \
-    (vmw_shmem_ld32(_d, dpa + offsetof(struct Vmxnet3_TxQueueDesc, field)))
+#define VMXNET3_READ_TX_QUEUE_DESCR32(dpa, field) \
+    (vmw_shmem_ld32(dpa + offsetof(struct Vmxnet3_TxQueueDesc, field)))
 
-#define VMXNET3_WRITE_TX_QUEUE_DESCR32(_d, dpa, field, value) \
-    (vmw_shmem_st32(_d, dpa + offsetof(struct Vmxnet3_TxQueueDesc, field), value))
+#define VMXNET3_WRITE_TX_QUEUE_DESCR32(dpa, field, value) \
+    (vmw_shmem_st32(dpa + offsetof(struct Vmxnet3_TxQueueDesc, field), value))
 
-#define VMXNET3_READ_TX_QUEUE_DESCR64(_d, dpa, field) \
-    (vmw_shmem_ld64(_d, dpa + offsetof(struct Vmxnet3_TxQueueDesc, field)))
+#define VMXNET3_READ_TX_QUEUE_DESCR64(dpa, field) \
+    (vmw_shmem_ld64(dpa + offsetof(struct Vmxnet3_TxQueueDesc, field)))
 
-#define VMXNET3_WRITE_TX_QUEUE_DESCR64(_d, dpa, field, value) \
-    (vmw_shmem_st64(_d, dpa + offsetof(struct Vmxnet3_TxQueueDesc, field), value))
+#define VMXNET3_WRITE_TX_QUEUE_DESCR64(dpa, field, value) \
+    (vmw_shmem_st64(dpa + offsetof(struct Vmxnet3_TxQueueDesc, field), value))
 
-#define VMXNET3_READ_RX_QUEUE_DESCR64(_d, dpa, field) \
-    (vmw_shmem_ld64(_d, dpa + offsetof(struct Vmxnet3_RxQueueDesc, field)))
+#define VMXNET3_READ_RX_QUEUE_DESCR64(dpa, field) \
+    (vmw_shmem_ld64(dpa + offsetof(struct Vmxnet3_RxQueueDesc, field)))
 
-#define VMXNET3_READ_RX_QUEUE_DESCR32(_d, dpa, field) \
-    (vmw_shmem_ld32(_d, dpa + offsetof(struct Vmxnet3_RxQueueDesc, field)))
+#define VMXNET3_READ_RX_QUEUE_DESCR32(dpa, field) \
+    (vmw_shmem_ld32(dpa + offsetof(struct Vmxnet3_RxQueueDesc, field)))
 
-#define VMXNET3_WRITE_RX_QUEUE_DESCR64(_d, dpa, field, value) \
-    (vmw_shmem_st64(_d, dpa + offsetof(struct Vmxnet3_RxQueueDesc, field), value))
+#define VMXNET3_WRITE_RX_QUEUE_DESCR64(dpa, field, value) \
+    (vmw_shmem_st64(dpa + offsetof(struct Vmxnet3_RxQueueDesc, field), value))
 
-#define VMXNET3_WRITE_RX_QUEUE_DESCR8(_d, dpa, field, value) \
-    (vmw_shmem_st8(_d, dpa + offsetof(struct Vmxnet3_RxQueueDesc, field), value))
+#define VMXNET3_WRITE_RX_QUEUE_DESCR8(dpa, field, value) \
+    (vmw_shmem_st8(dpa + offsetof(struct Vmxnet3_RxQueueDesc, field), value))
 
 /* Macros for guest driver shared area access */
-#define VMXNET3_READ_DRV_SHARED64(_d, shpa, field) \
-    (vmw_shmem_ld64(_d, shpa + offsetof(struct Vmxnet3_DriverShared, field)))
+#define VMXNET3_READ_DRV_SHARED64(shpa, field) \
+    (vmw_shmem_ld64(shpa + offsetof(struct Vmxnet3_DriverShared, field)))
 
-#define VMXNET3_READ_DRV_SHARED32(_d, shpa, field) \
-    (vmw_shmem_ld32(_d, shpa + offsetof(struct Vmxnet3_DriverShared, field)))
+#define VMXNET3_READ_DRV_SHARED32(shpa, field) \
+    (vmw_shmem_ld32(shpa + offsetof(struct Vmxnet3_DriverShared, field)))
 
-#define VMXNET3_WRITE_DRV_SHARED32(_d, shpa, field, val) \
-    (vmw_shmem_st32(_d, shpa + offsetof(struct Vmxnet3_DriverShared, field), val))
+#define VMXNET3_WRITE_DRV_SHARED32(shpa, field, val) \
+    (vmw_shmem_st32(shpa + offsetof(struct Vmxnet3_DriverShared, field), val))
 
-#define VMXNET3_READ_DRV_SHARED16(_d, shpa, field) \
-    (vmw_shmem_ld16(_d, shpa + offsetof(struct Vmxnet3_DriverShared, field)))
+#define VMXNET3_READ_DRV_SHARED16(shpa, field) \
+    (vmw_shmem_ld16(shpa + offsetof(struct Vmxnet3_DriverShared, field)))
 
-#define VMXNET3_READ_DRV_SHARED8(_d, shpa, field) \
-    (vmw_shmem_ld8(_d, shpa + offsetof(struct Vmxnet3_DriverShared, field)))
+#define VMXNET3_READ_DRV_SHARED8(shpa, field) \
+    (vmw_shmem_ld8(shpa + offsetof(struct Vmxnet3_DriverShared, field)))
 
-#define VMXNET3_READ_DRV_SHARED(_d, shpa, field, b, l) \
-    (vmw_shmem_read(_d, shpa + offsetof(struct Vmxnet3_DriverShared, field), b, l))
+#define VMXNET3_READ_DRV_SHARED(shpa, field, b, l) \
+    (vmw_shmem_read(shpa + offsetof(struct Vmxnet3_DriverShared, field), b, l))
 
 #define VMXNET_FLAG_IS_SET(field, flag) (((field) & (flag)) == (flag))
 
@@ -147,8 +147,7 @@ typedef struct {
     uint8_t gen;
 } Vmxnet3Ring;
 
-static inline void vmxnet3_ring_init(PCIDevice *d,
-                                    Vmxnet3Ring *ring,
+static inline void vmxnet3_ring_init(Vmxnet3Ring *ring,
                                      hwaddr pa,
                                      size_t size,
                                      size_t cell_size,
@@ -161,7 +160,7 @@ static inline void vmxnet3_ring_init(PCIDevice *d,
     ring->next = 0;
 
     if (zero_region) {
-        vmw_shmem_set(d, pa, 0, size * cell_size);
+        vmw_shmem_set(pa, 0, size * cell_size);
     }
 }
 
@@ -191,16 +190,14 @@ static inline hwaddr vmxnet3_ring_curr_cell_pa(Vmxnet3Ring *ring)
     return ring->pa + ring->next * ring->cell_size;
 }
 
-static inline void vmxnet3_ring_read_curr_cell(PCIDevice *d, Vmxnet3Ring *ring,
-                                              void *buff)
+static inline void vmxnet3_ring_read_curr_cell(Vmxnet3Ring *ring, void *buff)
 {
-    vmw_shmem_read(d, vmxnet3_ring_curr_cell_pa(ring), buff, ring->cell_size);
+    vmw_shmem_read(vmxnet3_ring_curr_cell_pa(ring), buff, ring->cell_size);
 }
 
-static inline void vmxnet3_ring_write_curr_cell(PCIDevice *d, Vmxnet3Ring *ring,
-                                               void *buff)
+static inline void vmxnet3_ring_write_curr_cell(Vmxnet3Ring *ring, void *buff)
 {
-    vmw_shmem_write(d, vmxnet3_ring_curr_cell_pa(ring), buff, ring->cell_size);
+    vmw_shmem_write(vmxnet3_ring_curr_cell_pa(ring), buff, ring->cell_size);
 }
 
 static inline size_t vmxnet3_ring_curr_cell_idx(Vmxnet3Ring *ring)
@@ -283,6 +280,8 @@ typedef struct {
 
         /* Whether MSI-X support was installed successfully */
         bool msix_used;
+        /* Whether MSI support was installed successfully */
+        bool msi_used;
         hwaddr drv_shmem;
         hwaddr temp_shared_guest_driver_memory;
 
@@ -315,13 +314,13 @@ typedef struct {
         bool peer_has_vhdr;
 
         /* TX packets to QEMU interface */
-        struct NetTxPkt *tx_pkt;
+        struct VmxnetTxPkt *tx_pkt;
         uint32_t offload_mode;
         uint32_t cso_or_gso_size;
         uint16_t tci;
         bool needs_vlan;
 
-        struct NetRxPkt *rx_pkt;
+        struct VmxnetRxPkt *rx_pkt;
 
         bool tx_sop;
         bool skip_current_tx_pkt;
@@ -349,7 +348,7 @@ typedef struct {
 /* Interrupt management */
 
 /*
- * This function returns sign whether interrupt line is in asserted state
+ *This function returns sign whether interrupt line is in asserted state
  * This depends on the type of interrupt used. For INTX interrupt line will
  * be asserted until explicit deassertion, for MSI(X) interrupt line will
  * be deasserted automatically due to notification semantics of the MSI(X)
@@ -364,7 +363,7 @@ static bool _vmxnet3_assert_interrupt_line(VMXNET3State *s, uint32_t int_idx)
         msix_notify(d, int_idx);
         return false;
     }
-    if (msi_enabled(d)) {
+    if (s->msi_used && msi_enabled(d)) {
         VMW_IRPRN("Sending MSI notification for vector %u", int_idx);
         msi_notify(d, int_idx);
         return false;
@@ -388,7 +387,7 @@ static void _vmxnet3_deassert_interrupt_line(VMXNET3State *s, int lidx)
      * This function should never be called for MSI(X) interrupts
      * because deassertion never required for message interrupts
      */
-    assert(!msi_enabled(d));
+    assert(!s->msi_used || !msi_enabled(d));
 
     VMW_IRPRN("Deasserting line for interrupt %u", lidx);
     pci_irq_deassert(d);
@@ -425,7 +424,7 @@ static void vmxnet3_trigger_interrupt(VMXNET3State *s, int lidx)
         goto do_automask;
     }
 
-    if (msi_enabled(d) && s->auto_int_masking) {
+    if (s->msi_used && msi_enabled(d) && s->auto_int_masking) {
         goto do_automask;
     }
 
@@ -457,9 +456,9 @@ vmxnet3_on_interrupt_mask_changed(VMXNET3State *s, int lidx, bool is_masked)
     vmxnet3_update_interrupt_line_state(s, lidx);
 }
 
-static bool vmxnet3_verify_driver_magic(PCIDevice *d, hwaddr dshmem)
+static bool vmxnet3_verify_driver_magic(hwaddr dshmem)
 {
-    return (VMXNET3_READ_DRV_SHARED32(d, dshmem, magic) == VMXNET3_REV1_MAGIC);
+    return (VMXNET3_READ_DRV_SHARED32(dshmem, magic) == VMXNET3_REV1_MAGIC);
 }
 
 #define VMXNET3_GET_BYTE(x, byte_num) (((x) >> (byte_num)*8) & 0xFF)
@@ -475,7 +474,7 @@ static void vmxnet3_set_variable_mac(VMXNET3State *s, uint32_t h, uint32_t l)
     s->conf.macaddr.a[4] = VMXNET3_GET_BYTE(h, 0);
     s->conf.macaddr.a[5] = VMXNET3_GET_BYTE(h, 1);
 
-    VMW_CFPRN("Variable MAC: " MAC_FMT, MAC_ARG(s->conf.macaddr.a));
+    VMW_CFPRN("Variable MAC: " VMXNET_MF, VMXNET_MA(s->conf.macaddr.a));
 
     qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
 }
@@ -527,14 +526,13 @@ vmxnet3_dec_rx_completion_counter(VMXNET3State *s, int qidx)
 static void vmxnet3_complete_packet(VMXNET3State *s, int qidx, uint32_t tx_ridx)
 {
     struct Vmxnet3_TxCompDesc txcq_descr;
-    PCIDevice *d = PCI_DEVICE(s);
 
     VMXNET3_RING_DUMP(VMW_RIPRN, "TXC", qidx, &s->txq_descr[qidx].comp_ring);
 
     txcq_descr.txdIdx = tx_ridx;
     txcq_descr.gen = vmxnet3_ring_curr_gen(&s->txq_descr[qidx].comp_ring);
 
-    vmxnet3_ring_write_curr_cell(d, &s->txq_descr[qidx].comp_ring, &txcq_descr);
+    vmxnet3_ring_write_curr_cell(&s->txq_descr[qidx].comp_ring, &txcq_descr);
 
     /* Flush changes in TX descriptor before changing the counter value */
     smp_wmb();
@@ -548,18 +546,18 @@ vmxnet3_setup_tx_offloads(VMXNET3State *s)
 {
     switch (s->offload_mode) {
     case VMXNET3_OM_NONE:
-        net_tx_pkt_build_vheader(s->tx_pkt, false, false, 0);
+        vmxnet_tx_pkt_build_vheader(s->tx_pkt, false, false, 0);
         break;
 
     case VMXNET3_OM_CSUM:
-        net_tx_pkt_build_vheader(s->tx_pkt, false, true, 0);
+        vmxnet_tx_pkt_build_vheader(s->tx_pkt, false, true, 0);
         VMW_PKPRN("L4 CSO requested\n");
         break;
 
     case VMXNET3_OM_TSO:
-        net_tx_pkt_build_vheader(s->tx_pkt, true, true,
+        vmxnet_tx_pkt_build_vheader(s->tx_pkt, true, true,
             s->cso_or_gso_size);
-        net_tx_pkt_update_ip_checksums(s->tx_pkt);
+        vmxnet_tx_pkt_update_ip_checksums(s->tx_pkt);
         VMW_PKPRN("GSO offload requested.");
         break;
 
@@ -592,12 +590,12 @@ static void
 vmxnet3_on_tx_done_update_stats(VMXNET3State *s, int qidx,
     Vmxnet3PktStatus status)
 {
-    size_t tot_len = net_tx_pkt_get_total_len(s->tx_pkt);
+    size_t tot_len = vmxnet_tx_pkt_get_total_len(s->tx_pkt);
     struct UPT1_TxStats *stats = &s->txq_descr[qidx].txq_stats;
 
     switch (status) {
     case VMXNET3_PKT_STATUS_OK:
-        switch (net_tx_pkt_get_packet_type(s->tx_pkt)) {
+        switch (vmxnet_tx_pkt_get_packet_type(s->tx_pkt)) {
         case ETH_PKT_BCAST:
             stats->bcastPktsTxOK++;
             stats->bcastBytesTxOK += tot_len;
@@ -645,7 +643,7 @@ vmxnet3_on_rx_done_update_stats(VMXNET3State *s,
                                 Vmxnet3PktStatus status)
 {
     struct UPT1_RxStats *stats = &s->rxq_descr[qidx].rxq_stats;
-    size_t tot_len = net_rx_pkt_get_total_len(s->rx_pkt);
+    size_t tot_len = vmxnet_rx_pkt_get_total_len(s->rx_pkt);
 
     switch (status) {
     case VMXNET3_PKT_STATUS_OUT_OF_BUF:
@@ -656,7 +654,7 @@ vmxnet3_on_rx_done_update_stats(VMXNET3State *s,
         stats->pktsRxError++;
         break;
     case VMXNET3_PKT_STATUS_OK:
-        switch (net_rx_pkt_get_packet_type(s->rx_pkt)) {
+        switch (vmxnet_rx_pkt_get_packet_type(s->rx_pkt)) {
         case ETH_PKT_BCAST:
             stats->bcastPktsRxOK++;
             stats->bcastBytesRxOK += tot_len;
@@ -690,14 +688,13 @@ vmxnet3_pop_next_tx_descr(VMXNET3State *s,
                           uint32_t *descr_idx)
 {
     Vmxnet3Ring *ring = &s->txq_descr[qidx].tx_ring;
-    PCIDevice *d = PCI_DEVICE(s);
 
-    vmxnet3_ring_read_curr_cell(d, ring, txd);
+    vmxnet3_ring_read_curr_cell(ring, txd);
     if (txd->gen == vmxnet3_ring_curr_gen(ring)) {
         /* Only read after generation field verification */
         smp_rmb();
         /* Re-read to be sure we got the latest version */
-        vmxnet3_ring_read_curr_cell(d, ring, txd);
+        vmxnet3_ring_read_curr_cell(ring, txd);
         VMXNET3_RING_DUMP(VMW_RIPRN, "TX", qidx, ring);
         *descr_idx = vmxnet3_ring_curr_cell_idx(ring);
         vmxnet3_inc_tx_consumption_counter(s, qidx);
@@ -718,10 +715,10 @@ vmxnet3_send_packet(VMXNET3State *s, uint32_t qidx)
     }
 
     /* debug prints */
-    vmxnet3_dump_virt_hdr(net_tx_pkt_get_vhdr(s->tx_pkt));
-    net_tx_pkt_dump(s->tx_pkt);
+    vmxnet3_dump_virt_hdr(vmxnet_tx_pkt_get_vhdr(s->tx_pkt));
+    vmxnet_tx_pkt_dump(s->tx_pkt);
 
-    if (!net_tx_pkt_send(s->tx_pkt, qemu_get_queue(s->nic))) {
+    if (!vmxnet_tx_pkt_send(s->tx_pkt, qemu_get_queue(s->nic))) {
         status = VMXNET3_PKT_STATUS_DISCARD;
         goto func_exit;
     }
@@ -749,7 +746,7 @@ static void vmxnet3_process_tx_queue(VMXNET3State *s, int qidx)
             data_len = (txd.len > 0) ? txd.len : VMXNET3_MAX_TX_BUF_SIZE;
             data_pa = le64_to_cpu(txd.addr);
 
-            if (!net_tx_pkt_add_raw_fragment(s->tx_pkt,
+            if (!vmxnet_tx_pkt_add_raw_fragment(s->tx_pkt,
                                                 data_pa,
                                                 data_len)) {
                 s->skip_current_tx_pkt = true;
@@ -762,9 +759,9 @@ static void vmxnet3_process_tx_queue(VMXNET3State *s, int qidx)
         }
 
         if (txd.eop) {
-            if (!s->skip_current_tx_pkt && net_tx_pkt_parse(s->tx_pkt)) {
+            if (!s->skip_current_tx_pkt && vmxnet_tx_pkt_parse(s->tx_pkt)) {
                 if (s->needs_vlan) {
-                    net_tx_pkt_setup_vlan_header(s->tx_pkt, s->tci);
+                    vmxnet_tx_pkt_setup_vlan_header(s->tx_pkt, s->tci);
                 }
 
                 vmxnet3_send_packet(s, qidx);
@@ -776,7 +773,7 @@ static void vmxnet3_process_tx_queue(VMXNET3State *s, int qidx)
             vmxnet3_complete_packet(s, qidx, txd_idx);
             s->tx_sop = true;
             s->skip_current_tx_pkt = false;
-            net_tx_pkt_reset(s->tx_pkt);
+            vmxnet_tx_pkt_reset(s->tx_pkt);
         }
     }
 }
@@ -785,11 +782,9 @@ static inline void
 vmxnet3_read_next_rx_descr(VMXNET3State *s, int qidx, int ridx,
                            struct Vmxnet3_RxDesc *dbuf, uint32_t *didx)
 {
-    PCIDevice *d = PCI_DEVICE(s);
-
     Vmxnet3Ring *ring = &s->rxq_descr[qidx].rx_ring[ridx];
     *didx = vmxnet3_ring_curr_cell_idx(ring);
-    vmxnet3_ring_read_curr_cell(d, ring, dbuf);
+    vmxnet3_ring_read_curr_cell(ring, dbuf);
 }
 
 static inline uint8_t
@@ -807,8 +802,7 @@ vmxnet3_pop_rxc_descr(VMXNET3State *s, int qidx, uint32_t *descr_gen)
     hwaddr daddr =
         vmxnet3_ring_curr_cell_pa(&s->rxq_descr[qidx].comp_ring);
 
-    pci_dma_read(PCI_DEVICE(s),
-                 daddr, &rxcd, sizeof(struct Vmxnet3_RxCompDesc));
+    cpu_physical_memory_read(daddr, &rxcd, sizeof(struct Vmxnet3_RxCompDesc));
     ring_gen = vmxnet3_ring_curr_gen(&s->rxq_descr[qidx].comp_ring);
 
     if (rxcd.gen != ring_gen) {
@@ -934,7 +928,7 @@ vmxnet3_get_next_rx_descr(VMXNET3State *s, bool is_head,
  * in the case the host OS performs forwarding, it will forward an
  * incorrectly checksummed packet.
  */
-static void vmxnet3_rx_need_csum_calculate(struct NetRxPkt *pkt,
+static void vmxnet3_rx_need_csum_calculate(struct VmxnetRxPkt *pkt,
                                            const void *pkt_data,
                                            size_t pkt_len)
 {
@@ -943,16 +937,16 @@ static void vmxnet3_rx_need_csum_calculate(struct NetRxPkt *pkt,
     uint8_t *data;
     int len;
 
-    if (!net_rx_pkt_has_virt_hdr(pkt)) {
+    if (!vmxnet_rx_pkt_has_virt_hdr(pkt)) {
         return;
     }
 
-    vhdr = net_rx_pkt_get_vhdr(pkt);
+    vhdr = vmxnet_rx_pkt_get_vhdr(pkt);
     if (!VMXNET_FLAG_IS_SET(vhdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM)) {
         return;
     }
 
-    net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
+    vmxnet_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
     if (!(isip4 || isip6) || !(istcp || isudp)) {
         return;
     }
@@ -976,7 +970,7 @@ static void vmxnet3_rx_need_csum_calculate(struct NetRxPkt *pkt,
     vhdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID;
 }
 
-static void vmxnet3_rx_update_descr(struct NetRxPkt *pkt,
+static void vmxnet3_rx_update_descr(struct VmxnetRxPkt *pkt,
     struct Vmxnet3_RxCompDesc *rxcd)
 {
     int csum_ok, is_gso;
@@ -984,16 +978,16 @@ static void vmxnet3_rx_update_descr(struct NetRxPkt *pkt,
     struct virtio_net_hdr *vhdr;
     uint8_t offload_type;
 
-    if (net_rx_pkt_is_vlan_stripped(pkt)) {
+    if (vmxnet_rx_pkt_is_vlan_stripped(pkt)) {
         rxcd->ts = 1;
-        rxcd->tci = net_rx_pkt_get_vlan_tag(pkt);
+        rxcd->tci = vmxnet_rx_pkt_get_vlan_tag(pkt);
     }
 
-    if (!net_rx_pkt_has_virt_hdr(pkt)) {
+    if (!vmxnet_rx_pkt_has_virt_hdr(pkt)) {
         goto nocsum;
     }
 
-    vhdr = net_rx_pkt_get_vhdr(pkt);
+    vhdr = vmxnet_rx_pkt_get_vhdr(pkt);
     /*
      * Checksum is valid when lower level tell so or when lower level
      * requires checksum offload telling that packet produced/bridged
@@ -1010,7 +1004,7 @@ static void vmxnet3_rx_update_descr(struct NetRxPkt *pkt,
         goto nocsum;
     }
 
-    net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
+    vmxnet_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
     if ((!istcp && !isudp) || (!isip4 && !isip6)) {
         goto nocsum;
     }
@@ -1029,11 +1023,10 @@ nocsum:
 }
 
 static void
-vmxnet3_pci_dma_writev(PCIDevice *pci_dev,
-                       const struct iovec *iov,
-                       size_t start_iov_off,
-                       hwaddr target_addr,
-                       size_t bytes_to_copy)
+vmxnet3_physical_memory_writev(const struct iovec *iov,
+                               size_t start_iov_off,
+                               hwaddr target_addr,
+                               size_t bytes_to_copy)
 {
     size_t curr_off = 0;
     size_t copied = 0;
@@ -1043,9 +1036,9 @@ vmxnet3_pci_dma_writev(PCIDevice *pci_dev,
             size_t chunk_len =
                 MIN((curr_off + iov->iov_len) - start_iov_off, bytes_to_copy);
 
-            pci_dma_write(pci_dev, target_addr + copied,
-                          iov->iov_base + start_iov_off - curr_off,
-                          chunk_len);
+            cpu_physical_memory_write(target_addr + copied,
+                                      iov->iov_base + start_iov_off - curr_off,
+                                      chunk_len);
 
             copied += chunk_len;
             start_iov_off += chunk_len;
@@ -1062,7 +1055,6 @@ static bool
 vmxnet3_indicate_packet(VMXNET3State *s)
 {
     struct Vmxnet3_RxDesc rxd;
-    PCIDevice *d = PCI_DEVICE(s);
     bool is_head = true;
     uint32_t rxd_idx;
     uint32_t rx_ridx = 0;
@@ -1071,13 +1063,13 @@ vmxnet3_indicate_packet(VMXNET3State *s)
     uint32_t new_rxcd_gen = VMXNET3_INIT_GEN;
     hwaddr new_rxcd_pa = 0;
     hwaddr ready_rxcd_pa = 0;
-    struct iovec *data = net_rx_pkt_get_iovec(s->rx_pkt);
+    struct iovec *data = vmxnet_rx_pkt_get_iovec(s->rx_pkt);
     size_t bytes_copied = 0;
-    size_t bytes_left = net_rx_pkt_get_total_len(s->rx_pkt);
+    size_t bytes_left = vmxnet_rx_pkt_get_total_len(s->rx_pkt);
     uint16_t num_frags = 0;
     size_t chunk_size;
 
-    net_rx_pkt_dump(s->rx_pkt);
+    vmxnet_rx_pkt_dump(s->rx_pkt);
 
     while (bytes_left > 0) {
 
@@ -1096,15 +1088,15 @@ vmxnet3_indicate_packet(VMXNET3State *s)
         }
 
         chunk_size = MIN(bytes_left, rxd.len);
-        vmxnet3_pci_dma_writev(d, data, bytes_copied,
-                               le64_to_cpu(rxd.addr), chunk_size);
+        vmxnet3_physical_memory_writev(data, bytes_copied,
+                                       le64_to_cpu(rxd.addr), chunk_size);
         bytes_copied += chunk_size;
         bytes_left -= chunk_size;
 
         vmxnet3_dump_rx_descr(&rxd);
 
         if (ready_rxcd_pa != 0) {
-            pci_dma_write(d, ready_rxcd_pa, &rxcd, sizeof(rxcd));
+            cpu_physical_memory_write(ready_rxcd_pa, &rxcd, sizeof(rxcd));
         }
 
         memset(&rxcd, 0, sizeof(struct Vmxnet3_RxCompDesc));
@@ -1135,8 +1127,7 @@ vmxnet3_indicate_packet(VMXNET3State *s)
     if (ready_rxcd_pa != 0) {
         rxcd.eop = 1;
         rxcd.err = (bytes_left != 0);
-
-        pci_dma_write(d, ready_rxcd_pa, &rxcd, sizeof(rxcd));
+        cpu_physical_memory_write(ready_rxcd_pa, &rxcd, sizeof(rxcd));
 
         /* Flush RX descriptor changes */
         smp_wmb();
@@ -1167,10 +1158,6 @@ vmxnet3_io_bar0_write(void *opaque, hwaddr addr,
 {
     VMXNET3State *s = opaque;
 
-    if (!s->device_active) {
-        return;
-    }
-
     if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_TXPROD,
                         VMXNET3_DEVICE_MAX_TX_QUEUES, VMXNET3_REG_ALIGN)) {
         int tx_queue_idx =
@@ -1232,16 +1219,16 @@ static void vmxnet3_reset_interrupt_states(VMXNET3State *s)
 static void vmxnet3_reset_mac(VMXNET3State *s)
 {
     memcpy(&s->conf.macaddr.a, &s->perm_mac.a, sizeof(s->perm_mac.a));
-    VMW_CFPRN("MAC address set to: " MAC_FMT, MAC_ARG(s->conf.macaddr.a));
+    VMW_CFPRN("MAC address set to: " VMXNET_MF, VMXNET_MA(s->conf.macaddr.a));
 }
 
 static void vmxnet3_deactivate_device(VMXNET3State *s)
 {
     if (s->device_active) {
         VMW_CBPRN("Deactivating vmxnet3...");
-        net_tx_pkt_reset(s->tx_pkt);
-        net_tx_pkt_uninit(s->tx_pkt);
-        net_rx_pkt_uninit(s->rx_pkt);
+        vmxnet_tx_pkt_reset(s->tx_pkt);
+        vmxnet_tx_pkt_uninit(s->tx_pkt);
+        vmxnet_rx_pkt_uninit(s->rx_pkt);
         s->device_active = false;
     }
 }
@@ -1259,9 +1246,7 @@ static void vmxnet3_reset(VMXNET3State *s)
 
 static void vmxnet3_update_rx_mode(VMXNET3State *s)
 {
-    PCIDevice *d = PCI_DEVICE(s);
-
-    s->rx_mode = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem,
+    s->rx_mode = VMXNET3_READ_DRV_SHARED32(s->drv_shmem,
                                            devRead.rxFilterConf.rxMode);
     VMW_CFPRN("RX mode: 0x%08X", s->rx_mode);
 }
@@ -1269,10 +1254,9 @@ static void vmxnet3_update_rx_mode(VMXNET3State *s)
 static void vmxnet3_update_vlan_filters(VMXNET3State *s)
 {
     int i;
-    PCIDevice *d = PCI_DEVICE(s);
 
     /* Copy configuration from shared memory */
-    VMXNET3_READ_DRV_SHARED(d, s->drv_shmem,
+    VMXNET3_READ_DRV_SHARED(s->drv_shmem,
                             devRead.rxFilterConf.vfTable,
                             s->vlan_table,
                             sizeof(s->vlan_table));
@@ -1293,10 +1277,8 @@ static void vmxnet3_update_vlan_filters(VMXNET3State *s)
 
 static void vmxnet3_update_mcast_filters(VMXNET3State *s)
 {
-    PCIDevice *d = PCI_DEVICE(s);
-
     uint16_t list_bytes =
-        VMXNET3_READ_DRV_SHARED16(d, s->drv_shmem,
+        VMXNET3_READ_DRV_SHARED16(s->drv_shmem,
                                   devRead.rxFilterConf.mfTableLen);
 
     s->mcast_list_len = list_bytes / sizeof(s->mcast_list[0]);
@@ -1313,14 +1295,13 @@ static void vmxnet3_update_mcast_filters(VMXNET3State *s)
     } else {
         int i;
         hwaddr mcast_list_pa =
-            VMXNET3_READ_DRV_SHARED64(d, s->drv_shmem,
+            VMXNET3_READ_DRV_SHARED64(s->drv_shmem,
                                       devRead.rxFilterConf.mfTablePA);
 
-        pci_dma_read(d, mcast_list_pa, s->mcast_list, list_bytes);
-
+        cpu_physical_memory_read(mcast_list_pa, s->mcast_list, list_bytes);
         VMW_CFPRN("Current multicast list len is %d:", s->mcast_list_len);
         for (i = 0; i < s->mcast_list_len; i++) {
-            VMW_CFPRN("\t" MAC_FMT, MAC_ARG(s->mcast_list[i].a));
+            VMW_CFPRN("\t" VMXNET_MF, VMXNET_MA(s->mcast_list[i].a));
         }
     }
 }
@@ -1342,32 +1323,28 @@ static uint32_t vmxnet3_get_interrupt_config(VMXNET3State *s)
 static void vmxnet3_fill_stats(VMXNET3State *s)
 {
     int i;
-    PCIDevice *d = PCI_DEVICE(s);
 
     if (!s->device_active)
         return;
 
     for (i = 0; i < s->txq_num; i++) {
-        pci_dma_write(d,
-                      s->txq_descr[i].tx_stats_pa,
-                      &s->txq_descr[i].txq_stats,
-                      sizeof(s->txq_descr[i].txq_stats));
+        cpu_physical_memory_write(s->txq_descr[i].tx_stats_pa,
+                                  &s->txq_descr[i].txq_stats,
+                                  sizeof(s->txq_descr[i].txq_stats));
     }
 
     for (i = 0; i < s->rxq_num; i++) {
-        pci_dma_write(d,
-                      s->rxq_descr[i].rx_stats_pa,
-                      &s->rxq_descr[i].rxq_stats,
-                      sizeof(s->rxq_descr[i].rxq_stats));
+        cpu_physical_memory_write(s->rxq_descr[i].rx_stats_pa,
+                                  &s->rxq_descr[i].rxq_stats,
+                                  sizeof(s->rxq_descr[i].rxq_stats));
     }
 }
 
 static void vmxnet3_adjust_by_guest_type(VMXNET3State *s)
 {
     struct Vmxnet3_GOSInfo gos;
-    PCIDevice *d = PCI_DEVICE(s);
 
-    VMXNET3_READ_DRV_SHARED(d, s->drv_shmem, devRead.misc.driverInfo.gos,
+    VMXNET3_READ_DRV_SHARED(s->drv_shmem, devRead.misc.driverInfo.gos,
                             &gos, sizeof(gos));
     s->rx_packets_compound =
         (gos.gosType == VMXNET3_GOS_TYPE_WIN) ? false : true;
@@ -1387,14 +1364,13 @@ vmxnet3_dump_conf_descr(const char *name,
 static void vmxnet3_update_pm_state(VMXNET3State *s)
 {
     struct Vmxnet3_VariableLenConfDesc pm_descr;
-    PCIDevice *d = PCI_DEVICE(s);
 
     pm_descr.confLen =
-        VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.pmConfDesc.confLen);
+        VMXNET3_READ_DRV_SHARED32(s->drv_shmem, devRead.pmConfDesc.confLen);
     pm_descr.confVer =
-        VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.pmConfDesc.confVer);
+        VMXNET3_READ_DRV_SHARED32(s->drv_shmem, devRead.pmConfDesc.confVer);
     pm_descr.confPA =
-        VMXNET3_READ_DRV_SHARED64(d, s->drv_shmem, devRead.pmConfDesc.confPA);
+        VMXNET3_READ_DRV_SHARED64(s->drv_shmem, devRead.pmConfDesc.confPA);
 
     vmxnet3_dump_conf_descr("PM State", &pm_descr);
 }
@@ -1403,9 +1379,8 @@ static void vmxnet3_update_features(VMXNET3State *s)
 {
     uint32_t guest_features;
     int rxcso_supported;
-    PCIDevice *d = PCI_DEVICE(s);
 
-    guest_features = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem,
+    guest_features = VMXNET3_READ_DRV_SHARED32(s->drv_shmem,
                                                devRead.misc.uptFeatures);
 
     rxcso_supported = VMXNET_FLAG_IS_SET(guest_features, UPT1_F_RXCSUM);
@@ -1427,8 +1402,8 @@ static void vmxnet3_update_features(VMXNET3State *s)
 
 static bool vmxnet3_verify_intx(VMXNET3State *s, int intx)
 {
-    return s->msix_used || msi_enabled(PCI_DEVICE(s))
-        || intx == pci_get_byte(s->parent_obj.config + PCI_INTERRUPT_PIN) - 1;
+    return s->msix_used || s->msi_used || (intx ==
+           (pci_get_byte(s->parent_obj.config + PCI_INTERRUPT_PIN) - 1));
 }
 
 static void vmxnet3_validate_interrupt_idx(bool is_msix, int idx)
@@ -1480,13 +1455,12 @@ static void vmxnet3_activate_device(VMXNET3State *s)
 {
     int i;
     static const uint32_t VMXNET3_DEF_TX_THRESHOLD = 1;
-    PCIDevice *d = PCI_DEVICE(s);
     hwaddr qdescr_table_pa;
     uint64_t pa;
     uint32_t size;
 
     /* Verify configuration consistency */
-    if (!vmxnet3_verify_driver_magic(d, s->drv_shmem)) {
+    if (!vmxnet3_verify_driver_magic(s->drv_shmem)) {
         VMW_ERPRN("Device configuration received from driver is invalid");
         return;
     }
@@ -1502,11 +1476,11 @@ static void vmxnet3_activate_device(VMXNET3State *s)
     vmxnet3_update_pm_state(s);
     vmxnet3_setup_rx_filtering(s);
     /* Cache fields from shared memory */
-    s->mtu = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.misc.mtu);
+    s->mtu = VMXNET3_READ_DRV_SHARED32(s->drv_shmem, devRead.misc.mtu);
     VMW_CFPRN("MTU is %u", s->mtu);
 
     s->max_rx_frags =
-        VMXNET3_READ_DRV_SHARED16(d, s->drv_shmem, devRead.misc.maxNumRxSG);
+        VMXNET3_READ_DRV_SHARED16(s->drv_shmem, devRead.misc.maxNumRxSG);
 
     if (s->max_rx_frags == 0) {
         s->max_rx_frags = 1;
@@ -1515,24 +1489,24 @@ static void vmxnet3_activate_device(VMXNET3State *s)
     VMW_CFPRN("Max RX fragments is %u", s->max_rx_frags);
 
     s->event_int_idx =
-        VMXNET3_READ_DRV_SHARED8(d, s->drv_shmem, devRead.intrConf.eventIntrIdx);
+        VMXNET3_READ_DRV_SHARED8(s->drv_shmem, devRead.intrConf.eventIntrIdx);
     assert(vmxnet3_verify_intx(s, s->event_int_idx));
     VMW_CFPRN("Events interrupt line is %u", s->event_int_idx);
 
     s->auto_int_masking =
-        VMXNET3_READ_DRV_SHARED8(d, s->drv_shmem, devRead.intrConf.autoMask);
+        VMXNET3_READ_DRV_SHARED8(s->drv_shmem, devRead.intrConf.autoMask);
     VMW_CFPRN("Automatic interrupt masking is %d", (int)s->auto_int_masking);
 
     s->txq_num =
-        VMXNET3_READ_DRV_SHARED8(d, s->drv_shmem, devRead.misc.numTxQueues);
+        VMXNET3_READ_DRV_SHARED8(s->drv_shmem, devRead.misc.numTxQueues);
     s->rxq_num =
-        VMXNET3_READ_DRV_SHARED8(d, s->drv_shmem, devRead.misc.numRxQueues);
+        VMXNET3_READ_DRV_SHARED8(s->drv_shmem, devRead.misc.numRxQueues);
 
     VMW_CFPRN("Number of TX/RX queues %u/%u", s->txq_num, s->rxq_num);
     vmxnet3_validate_queues(s);
 
     qdescr_table_pa =
-        VMXNET3_READ_DRV_SHARED64(d, s->drv_shmem, devRead.misc.queueDescPA);
+        VMXNET3_READ_DRV_SHARED64(s->drv_shmem, devRead.misc.queueDescPA);
     VMW_CFPRN("TX queues descriptors table is at 0x%" PRIx64, qdescr_table_pa);
 
     /*
@@ -1548,25 +1522,25 @@ static void vmxnet3_activate_device(VMXNET3State *s)
 
         /* Read interrupt number for this TX queue */
         s->txq_descr[i].intr_idx =
-            VMXNET3_READ_TX_QUEUE_DESCR8(d, qdescr_pa, conf.intrIdx);
+            VMXNET3_READ_TX_QUEUE_DESCR8(qdescr_pa, conf.intrIdx);
         assert(vmxnet3_verify_intx(s, s->txq_descr[i].intr_idx));
 
         VMW_CFPRN("TX Queue %d interrupt: %d", i, s->txq_descr[i].intr_idx);
 
         /* Read rings memory locations for TX queues */
-        pa = VMXNET3_READ_TX_QUEUE_DESCR64(d, qdescr_pa, conf.txRingBasePA);
-        size = VMXNET3_READ_TX_QUEUE_DESCR32(d, qdescr_pa, conf.txRingSize);
+        pa = VMXNET3_READ_TX_QUEUE_DESCR64(qdescr_pa, conf.txRingBasePA);
+        size = VMXNET3_READ_TX_QUEUE_DESCR32(qdescr_pa, conf.txRingSize);
 
-        vmxnet3_ring_init(d, &s->txq_descr[i].tx_ring, pa, size,
+        vmxnet3_ring_init(&s->txq_descr[i].tx_ring, pa, size,
                           sizeof(struct Vmxnet3_TxDesc), false);
         VMXNET3_RING_DUMP(VMW_CFPRN, "TX", i, &s->txq_descr[i].tx_ring);
 
         s->max_tx_frags += size;
 
         /* TXC ring */
-        pa = VMXNET3_READ_TX_QUEUE_DESCR64(d, qdescr_pa, conf.compRingBasePA);
-        size = VMXNET3_READ_TX_QUEUE_DESCR32(d, qdescr_pa, conf.compRingSize);
-        vmxnet3_ring_init(d, &s->txq_descr[i].comp_ring, pa, size,
+        pa = VMXNET3_READ_TX_QUEUE_DESCR64(qdescr_pa, conf.compRingBasePA);
+        size = VMXNET3_READ_TX_QUEUE_DESCR32(qdescr_pa, conf.compRingSize);
+        vmxnet3_ring_init(&s->txq_descr[i].comp_ring, pa, size,
                           sizeof(struct Vmxnet3_TxCompDesc), true);
         VMXNET3_RING_DUMP(VMW_CFPRN, "TXC", i, &s->txq_descr[i].comp_ring);
 
@@ -1577,16 +1551,15 @@ static void vmxnet3_activate_device(VMXNET3State *s)
                sizeof(s->txq_descr[i].txq_stats));
 
         /* Fill device-managed parameters for queues */
-        VMXNET3_WRITE_TX_QUEUE_DESCR32(d, qdescr_pa,
+        VMXNET3_WRITE_TX_QUEUE_DESCR32(qdescr_pa,
                                        ctrl.txThreshold,
                                        VMXNET3_DEF_TX_THRESHOLD);
     }
 
     /* Preallocate TX packet wrapper */
     VMW_CFPRN("Max TX fragments is %u", s->max_tx_frags);
-    net_tx_pkt_init(&s->tx_pkt, PCI_DEVICE(s),
-                    s->max_tx_frags, s->peer_has_vhdr);
-    net_rx_pkt_init(&s->rx_pkt, s->peer_has_vhdr);
+    vmxnet_tx_pkt_init(&s->tx_pkt, s->max_tx_frags, s->peer_has_vhdr);
+    vmxnet_rx_pkt_init(&s->rx_pkt, s->peer_has_vhdr);
 
     /* Read rings memory locations for RX queues */
     for (i = 0; i < s->rxq_num; i++) {
@@ -1597,7 +1570,7 @@ static void vmxnet3_activate_device(VMXNET3State *s)
 
         /* Read interrupt number for this RX queue */
         s->rxq_descr[i].intr_idx =
-            VMXNET3_READ_TX_QUEUE_DESCR8(d, qd_pa, conf.intrIdx);
+            VMXNET3_READ_TX_QUEUE_DESCR8(qd_pa, conf.intrIdx);
         assert(vmxnet3_verify_intx(s, s->rxq_descr[i].intr_idx));
 
         VMW_CFPRN("RX Queue %d interrupt: %d", i, s->rxq_descr[i].intr_idx);
@@ -1605,18 +1578,18 @@ static void vmxnet3_activate_device(VMXNET3State *s)
         /* Read rings memory locations */
         for (j = 0; j < VMXNET3_RX_RINGS_PER_QUEUE; j++) {
             /* RX rings */
-            pa = VMXNET3_READ_RX_QUEUE_DESCR64(d, qd_pa, conf.rxRingBasePA[j]);
-            size = VMXNET3_READ_RX_QUEUE_DESCR32(d, qd_pa, conf.rxRingSize[j]);
-            vmxnet3_ring_init(d, &s->rxq_descr[i].rx_ring[j], pa, size,
+            pa = VMXNET3_READ_RX_QUEUE_DESCR64(qd_pa, conf.rxRingBasePA[j]);
+            size = VMXNET3_READ_RX_QUEUE_DESCR32(qd_pa, conf.rxRingSize[j]);
+            vmxnet3_ring_init(&s->rxq_descr[i].rx_ring[j], pa, size,
                               sizeof(struct Vmxnet3_RxDesc), false);
             VMW_CFPRN("RX queue %d:%d: Base: %" PRIx64 ", Size: %d",
                       i, j, pa, size);
         }
 
         /* RXC ring */
-        pa = VMXNET3_READ_RX_QUEUE_DESCR64(d, qd_pa, conf.compRingBasePA);
-        size = VMXNET3_READ_RX_QUEUE_DESCR32(d, qd_pa, conf.compRingSize);
-        vmxnet3_ring_init(d, &s->rxq_descr[i].comp_ring, pa, size,
+        pa = VMXNET3_READ_RX_QUEUE_DESCR64(qd_pa, conf.compRingBasePA);
+        size = VMXNET3_READ_RX_QUEUE_DESCR32(qd_pa, conf.compRingSize);
+        vmxnet3_ring_init(&s->rxq_descr[i].comp_ring, pa, size,
                           sizeof(struct Vmxnet3_RxCompDesc), true);
         VMW_CFPRN("RXC queue %d: Base: %" PRIx64 ", Size: %d", i, pa, size);
 
@@ -1783,21 +1756,19 @@ static uint64_t vmxnet3_get_command_status(VMXNET3State *s)
 static void vmxnet3_set_events(VMXNET3State *s, uint32_t val)
 {
     uint32_t events;
-    PCIDevice *d = PCI_DEVICE(s);
 
     VMW_CBPRN("Setting events: 0x%x", val);
-    events = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, ecr) | val;
-    VMXNET3_WRITE_DRV_SHARED32(d, s->drv_shmem, ecr, events);
+    events = VMXNET3_READ_DRV_SHARED32(s->drv_shmem, ecr) | val;
+    VMXNET3_WRITE_DRV_SHARED32(s->drv_shmem, ecr, events);
 }
 
 static void vmxnet3_ack_events(VMXNET3State *s, uint32_t val)
 {
-    PCIDevice *d = PCI_DEVICE(s);
     uint32_t events;
 
     VMW_CBPRN("Clearing events: 0x%x", val);
-    events = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, ecr) & ~val;
-    VMXNET3_WRITE_DRV_SHARED32(d, s->drv_shmem, ecr, events);
+    events = VMXNET3_READ_DRV_SHARED32(s->drv_shmem, ecr) & ~val;
+    VMXNET3_WRITE_DRV_SHARED32(s->drv_shmem, ecr, events);
 }
 
 static void
@@ -1994,7 +1965,7 @@ vmxnet3_rx_filter_may_indicate(VMXNET3State *s, const void *data,
         return false;
     }
 
-    switch (net_rx_pkt_get_packet_type(s->rx_pkt)) {
+    switch (vmxnet_rx_pkt_get_packet_type(s->rx_pkt)) {
     case ETH_PKT_UCAST:
         if (!VMXNET_FLAG_IS_SET(s->rx_mode, VMXNET3_RXM_UCAST)) {
             return false;
@@ -2042,7 +2013,7 @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size)
     }
 
     if (s->peer_has_vhdr) {
-        net_rx_pkt_set_vhdr(s->rx_pkt, (struct virtio_net_hdr *)buf);
+        vmxnet_rx_pkt_set_vhdr(s->rx_pkt, (struct virtio_net_hdr *)buf);
         buf += sizeof(struct virtio_net_hdr);
         size -= sizeof(struct virtio_net_hdr);
     }
@@ -2055,13 +2026,13 @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size)
         size = sizeof(min_buf);
     }
 
-    net_rx_pkt_set_packet_type(s->rx_pkt,
+    vmxnet_rx_pkt_set_packet_type(s->rx_pkt,
         get_eth_packet_type(PKT_GET_ETH_HDR(buf)));
 
     if (vmxnet3_rx_filter_may_indicate(s, buf, size)) {
-        net_rx_pkt_set_protocols(s->rx_pkt, buf, size);
+        vmxnet_rx_pkt_set_protocols(s->rx_pkt, buf, size);
         vmxnet3_rx_need_csum_calculate(s->rx_pkt, buf, size);
-        net_rx_pkt_attach_data(s->rx_pkt, buf, size, s->rx_vlan_stripping);
+        vmxnet_rx_pkt_attach_data(s->rx_pkt, buf, size, s->rx_vlan_stripping);
         bytes_indicated = vmxnet3_indicate_packet(s) ? size : -1;
         if (bytes_indicated < size) {
             VMW_PKPRN("RX: %zu of %zu bytes indicated", bytes_indicated, size);
@@ -2091,7 +2062,7 @@ static void vmxnet3_set_link_status(NetClientState *nc)
 }
 
 static NetClientInfo net_vmxnet3_info = {
-        .type = NET_CLIENT_DRIVER_NIC,
+        .type = NET_CLIENT_OPTIONS_KIND_NIC,
         .size = sizeof(NICState),
         .receive = vmxnet3_receive,
         .link_status_changed = vmxnet3_set_link_status,
@@ -2131,7 +2102,7 @@ static void vmxnet3_net_init(VMXNET3State *s)
 
     s->link_status_and_speed = VMXNET3_LINK_SPEED | VMXNET3_LINK_STATUS_UP;
 
-    VMW_CFPRN("Permanent MAC: " MAC_FMT, MAC_ARG(s->perm_mac.a));
+    VMW_CFPRN("Permanent MAC: " VMXNET_MF, VMXNET_MA(s->perm_mac.a));
 
     s->nic = qemu_new_nic(&net_vmxnet3_info, &s->conf,
                           object_get_typename(OBJECT(s)),
@@ -2218,12 +2189,35 @@ vmxnet3_cleanup_msix(VMXNET3State *s)
     }
 }
 
+#define VMXNET3_USE_64BIT         (true)
+#define VMXNET3_PER_VECTOR_MASK   (false)
+
+static bool
+vmxnet3_init_msi(VMXNET3State *s)
+{
+    PCIDevice *d = PCI_DEVICE(s);
+    int res;
+
+    res = msi_init(d, VMXNET3_MSI_OFFSET(s), VMXNET3_MAX_NMSIX_INTRS,
+                   VMXNET3_USE_64BIT, VMXNET3_PER_VECTOR_MASK);
+    if (0 > res) {
+        VMW_WRPRN("Failed to initialize MSI, error %d", res);
+        s->msi_used = false;
+    } else {
+        s->msi_used = true;
+    }
+
+    return s->msi_used;
+}
+
 static void
 vmxnet3_cleanup_msi(VMXNET3State *s)
 {
     PCIDevice *d = PCI_DEVICE(s);
 
-    msi_uninit(d);
+    if (s->msi_used) {
+        msi_uninit(d);
+    }
 }
 
 static void
@@ -2261,9 +2255,9 @@ static const MemoryRegionOps b1_ops = {
     },
 };
 
-static uint64_t vmxnet3_device_serial_num(VMXNET3State *s)
+static uint8_t *vmxnet3_device_serial_num(VMXNET3State *s)
 {
-    uint64_t dsn_payload;
+    static uint64_t dsn_payload;
     uint8_t *dsnp = (uint8_t *)&dsn_payload;
 
     dsnp[0] = 0xfe;
@@ -2274,18 +2268,13 @@ static uint64_t vmxnet3_device_serial_num(VMXNET3State *s)
     dsnp[5] = s->conf.macaddr.a[1];
     dsnp[6] = s->conf.macaddr.a[2];
     dsnp[7] = 0xff;
-    return dsn_payload;
+    return dsnp;
 }
 
-
-#define VMXNET3_USE_64BIT         (true)
-#define VMXNET3_PER_VECTOR_MASK   (false)
-
 static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp)
 {
     DeviceState *dev = DEVICE(pci_dev);
     VMXNET3State *s = VMXNET3(pci_dev);
-    int ret;
 
     VMW_CBPRN("Starting init...");
 
@@ -2309,16 +2298,14 @@ static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp)
     /* Interrupt pin A */
     pci_dev->config[PCI_INTERRUPT_PIN] = 0x01;
 
-    ret = msi_init(pci_dev, VMXNET3_MSI_OFFSET(s), VMXNET3_MAX_NMSIX_INTRS,
-                   VMXNET3_USE_64BIT, VMXNET3_PER_VECTOR_MASK, NULL);
-    /* Any error other than -ENOTSUP(board's MSI support is broken)
-     * is a programming error. Fall back to INTx silently on -ENOTSUP */
-    assert(!ret || ret == -ENOTSUP);
-
     if (!vmxnet3_init_msix(s)) {
         VMW_WRPRN("Failed to initialize MSI-X, configuration is inconsistent.");
     }
 
+    if (!vmxnet3_init_msi(s)) {
+        VMW_WRPRN("Failed to initialize MSI, configuration is inconsistent.");
+    }
+
     vmxnet3_net_init(s);
 
     if (pci_is_express(pci_dev)) {
@@ -2326,8 +2313,10 @@ static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp)
             pcie_endpoint_cap_init(pci_dev, VMXNET3_EXP_EP_OFFSET);
         }
 
-        pcie_dev_ser_num_init(pci_dev, VMXNET3_DSN_OFFSET,
-                              vmxnet3_device_serial_num(s));
+        pcie_add_capability(pci_dev, PCI_EXT_CAP_ID_DSN, 0x1,
+                            VMXNET3_DSN_OFFSET, PCI_EXT_CAP_DSN_SIZEOF);
+        memcpy(pci_dev->config + VMXNET3_DSN_OFFSET + 4,
+               vmxnet3_device_serial_num(s), sizeof(uint64_t));
     }
 
     register_savevm(dev, "vmxnet3-msix", -1, 1,
@@ -2549,9 +2538,8 @@ static int vmxnet3_post_load(void *opaque, int version_id)
     VMXNET3State *s = opaque;
     PCIDevice *d = PCI_DEVICE(s);
 
-    net_tx_pkt_init(&s->tx_pkt, PCI_DEVICE(s),
-                    s->max_tx_frags, s->peer_has_vhdr);
-    net_rx_pkt_init(&s->rx_pkt, s->peer_has_vhdr);
+    vmxnet_tx_pkt_init(&s->tx_pkt, s->max_tx_frags, s->peer_has_vhdr);
+    vmxnet_rx_pkt_init(&s->rx_pkt, s->peer_has_vhdr);
 
     if (s->msix_used) {
         if  (!vmxnet3_use_msix_vectors(s, VMXNET3_MAX_INTRS)) {
@@ -2705,7 +2693,6 @@ static void vmxnet3_class_init(ObjectClass *class, void *data)
     c->vendor_id = PCI_VENDOR_ID_VMWARE;
     c->device_id = PCI_DEVICE_ID_VMWARE_VMXNET3;
     c->revision = PCI_DEVICE_ID_VMWARE_VMXNET3_REVISION;
-    c->romfile = "efi-vmxnet3.rom";
     c->class_id = PCI_CLASS_NETWORK_ETHERNET;
     c->subsystem_vendor_id = PCI_VENDOR_ID_VMWARE;
     c->subsystem_id = PCI_DEVICE_ID_VMWARE_VMXNET3;
index f9352c4..f7006af 100644 (file)
@@ -15,8 +15,8 @@
  *
  */
 
-#ifndef QEMU_VMXNET3_H
-#define QEMU_VMXNET3_H
+#ifndef _QEMU_VMXNET3_H
+#define _QEMU_VMXNET3_H
 
 #define VMXNET3_DEVICE_MAX_TX_QUEUES 8
 #define VMXNET3_DEVICE_MAX_RX_QUEUES 8   /* Keep this value as a power of 2 */
index cb50aa9..96495db 100644 (file)
@@ -15,8 +15,8 @@
  *
  */
 
-#ifndef QEMU_VMXNET_DEBUG_H
-#define QEMU_VMXNET_DEBUG_H
+#ifndef _QEMU_VMXNET_DEBUG_H
+#define _QEMU_VMXNET_DEBUG_H
 
 #define VMXNET_DEVICE_NAME "vmxnet3"
 
         }                                                                     \
     } while (0)
 
-#endif /* QEMU_VMXNET_DEBUG_H */
+#define VMXNET_MF       "%02X:%02X:%02X:%02X:%02X:%02X"
+#define VMXNET_MA(a)    (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+
+#endif /* _QEMU_VMXNET3_DEBUG_H  */
diff --git a/hw/net/vmxnet_rx_pkt.c b/hw/net/vmxnet_rx_pkt.c
new file mode 100644 (file)
index 0000000..21bb46e
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * QEMU VMWARE VMXNET* paravirtual NICs - RX packets abstractions
+ *
+ * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
+ *
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
+ *
+ * Authors:
+ * Dmitry Fleytman <dmitry@daynix.com>
+ * Tamir Shomer <tamirs@daynix.com>
+ * Yan Vugenfirer <yan@daynix.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "vmxnet_rx_pkt.h"
+#include "net/eth.h"
+#include "qemu-common.h"
+#include "qemu/iov.h"
+#include "net/checksum.h"
+#include "net/tap.h"
+
+/*
+ * RX packet may contain up to 2 fragments - rebuilt eth header
+ * in case of VLAN tag stripping
+ * and payload received from QEMU - in any case
+ */
+#define VMXNET_MAX_RX_PACKET_FRAGMENTS (2)
+
+struct VmxnetRxPkt {
+    struct virtio_net_hdr virt_hdr;
+    uint8_t ehdr_buf[ETH_MAX_L2_HDR_LEN];
+    struct iovec vec[VMXNET_MAX_RX_PACKET_FRAGMENTS];
+    uint16_t vec_len;
+    uint32_t tot_len;
+    uint16_t tci;
+    bool vlan_stripped;
+    bool has_virt_hdr;
+    eth_pkt_types_e packet_type;
+
+    /* Analysis results */
+    bool isip4;
+    bool isip6;
+    bool isudp;
+    bool istcp;
+};
+
+void vmxnet_rx_pkt_init(struct VmxnetRxPkt **pkt, bool has_virt_hdr)
+{
+    struct VmxnetRxPkt *p = g_malloc0(sizeof *p);
+    p->has_virt_hdr = has_virt_hdr;
+    *pkt = p;
+}
+
+void vmxnet_rx_pkt_uninit(struct VmxnetRxPkt *pkt)
+{
+    g_free(pkt);
+}
+
+struct virtio_net_hdr *vmxnet_rx_pkt_get_vhdr(struct VmxnetRxPkt *pkt)
+{
+    assert(pkt);
+    return &pkt->virt_hdr;
+}
+
+void vmxnet_rx_pkt_attach_data(struct VmxnetRxPkt *pkt, const void *data,
+                               size_t len, bool strip_vlan)
+{
+    uint16_t tci = 0;
+    uint16_t ploff;
+    assert(pkt);
+    pkt->vlan_stripped = false;
+
+    if (strip_vlan) {
+        pkt->vlan_stripped = eth_strip_vlan(data, pkt->ehdr_buf, &ploff, &tci);
+    }
+
+    if (pkt->vlan_stripped) {
+        pkt->vec[0].iov_base = pkt->ehdr_buf;
+        pkt->vec[0].iov_len = ploff - sizeof(struct vlan_header);
+        pkt->vec[1].iov_base = (uint8_t *) data + ploff;
+        pkt->vec[1].iov_len = len - ploff;
+        pkt->vec_len = 2;
+        pkt->tot_len = len - ploff + sizeof(struct eth_header);
+    } else {
+        pkt->vec[0].iov_base = (void *)data;
+        pkt->vec[0].iov_len = len;
+        pkt->vec_len = 1;
+        pkt->tot_len = len;
+    }
+
+    pkt->tci = tci;
+}
+
+void vmxnet_rx_pkt_dump(struct VmxnetRxPkt *pkt)
+{
+#ifdef VMXNET_RX_PKT_DEBUG
+    VmxnetRxPkt *pkt = (VmxnetRxPkt *)pkt;
+    assert(pkt);
+
+    printf("RX PKT: tot_len: %d, vlan_stripped: %d, vlan_tag: %d\n",
+              pkt->tot_len, pkt->vlan_stripped, pkt->tci);
+#endif
+}
+
+void vmxnet_rx_pkt_set_packet_type(struct VmxnetRxPkt *pkt,
+    eth_pkt_types_e packet_type)
+{
+    assert(pkt);
+
+    pkt->packet_type = packet_type;
+
+}
+
+eth_pkt_types_e vmxnet_rx_pkt_get_packet_type(struct VmxnetRxPkt *pkt)
+{
+    assert(pkt);
+
+    return pkt->packet_type;
+}
+
+size_t vmxnet_rx_pkt_get_total_len(struct VmxnetRxPkt *pkt)
+{
+    assert(pkt);
+
+    return pkt->tot_len;
+}
+
+void vmxnet_rx_pkt_set_protocols(struct VmxnetRxPkt *pkt, const void *data,
+                                 size_t len)
+{
+    assert(pkt);
+
+    eth_get_protocols(data, len, &pkt->isip4, &pkt->isip6,
+        &pkt->isudp, &pkt->istcp);
+}
+
+void vmxnet_rx_pkt_get_protocols(struct VmxnetRxPkt *pkt,
+                                 bool *isip4, bool *isip6,
+                                 bool *isudp, bool *istcp)
+{
+    assert(pkt);
+
+    *isip4 = pkt->isip4;
+    *isip6 = pkt->isip6;
+    *isudp = pkt->isudp;
+    *istcp = pkt->istcp;
+}
+
+struct iovec *vmxnet_rx_pkt_get_iovec(struct VmxnetRxPkt *pkt)
+{
+    assert(pkt);
+
+    return pkt->vec;
+}
+
+void vmxnet_rx_pkt_set_vhdr(struct VmxnetRxPkt *pkt,
+                            struct virtio_net_hdr *vhdr)
+{
+    assert(pkt);
+
+    memcpy(&pkt->virt_hdr, vhdr, sizeof pkt->virt_hdr);
+}
+
+bool vmxnet_rx_pkt_is_vlan_stripped(struct VmxnetRxPkt *pkt)
+{
+    assert(pkt);
+
+    return pkt->vlan_stripped;
+}
+
+bool vmxnet_rx_pkt_has_virt_hdr(struct VmxnetRxPkt *pkt)
+{
+    assert(pkt);
+
+    return pkt->has_virt_hdr;
+}
+
+uint16_t vmxnet_rx_pkt_get_vlan_tag(struct VmxnetRxPkt *pkt)
+{
+    assert(pkt);
+
+    return pkt->tci;
+}
diff --git a/hw/net/vmxnet_rx_pkt.h b/hw/net/vmxnet_rx_pkt.h
new file mode 100644 (file)
index 0000000..0a45c1b
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * QEMU VMWARE VMXNET* paravirtual NICs - RX packets abstraction
+ *
+ * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
+ *
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
+ *
+ * Authors:
+ * Dmitry Fleytman <dmitry@daynix.com>
+ * Tamir Shomer <tamirs@daynix.com>
+ * Yan Vugenfirer <yan@daynix.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef VMXNET_RX_PKT_H
+#define VMXNET_RX_PKT_H
+
+#include "net/eth.h"
+
+/* defines to enable packet dump functions */
+/*#define VMXNET_RX_PKT_DEBUG*/
+
+struct VmxnetRxPkt;
+
+/**
+ * Clean all rx packet resources
+ *
+ * @pkt:            packet
+ *
+ */
+void vmxnet_rx_pkt_uninit(struct VmxnetRxPkt *pkt);
+
+/**
+ * Init function for rx packet functionality
+ *
+ * @pkt:            packet pointer
+ * @has_virt_hdr:   device uses virtio header
+ *
+ */
+void vmxnet_rx_pkt_init(struct VmxnetRxPkt **pkt, bool has_virt_hdr);
+
+/**
+ * returns total length of data attached to rx context
+ *
+ * @pkt:            packet
+ *
+ * Return:  nothing
+ *
+ */
+size_t vmxnet_rx_pkt_get_total_len(struct VmxnetRxPkt *pkt);
+
+/**
+ * parse and set packet analysis results
+ *
+ * @pkt:            packet
+ * @data:           pointer to the data buffer to be parsed
+ * @len:            data length
+ *
+ */
+void vmxnet_rx_pkt_set_protocols(struct VmxnetRxPkt *pkt, const void *data,
+                                 size_t len);
+
+/**
+ * fetches packet analysis results
+ *
+ * @pkt:            packet
+ * @isip4:          whether the packet given is IPv4
+ * @isip6:          whether the packet given is IPv6
+ * @isudp:          whether the packet given is UDP
+ * @istcp:          whether the packet given is TCP
+ *
+ */
+void vmxnet_rx_pkt_get_protocols(struct VmxnetRxPkt *pkt,
+                                 bool *isip4, bool *isip6,
+                                 bool *isudp, bool *istcp);
+
+/**
+ * returns virtio header stored in rx context
+ *
+ * @pkt:            packet
+ * @ret:            virtio header
+ *
+ */
+struct virtio_net_hdr *vmxnet_rx_pkt_get_vhdr(struct VmxnetRxPkt *pkt);
+
+/**
+ * returns packet type
+ *
+ * @pkt:            packet
+ * @ret:            packet type
+ *
+ */
+eth_pkt_types_e vmxnet_rx_pkt_get_packet_type(struct VmxnetRxPkt *pkt);
+
+/**
+ * returns vlan tag
+ *
+ * @pkt:            packet
+ * @ret:            VLAN tag
+ *
+ */
+uint16_t vmxnet_rx_pkt_get_vlan_tag(struct VmxnetRxPkt *pkt);
+
+/**
+ * tells whether vlan was stripped from the packet
+ *
+ * @pkt:            packet
+ * @ret:            VLAN stripped sign
+ *
+ */
+bool vmxnet_rx_pkt_is_vlan_stripped(struct VmxnetRxPkt *pkt);
+
+/**
+ * notifies caller if the packet has virtio header
+ *
+ * @pkt:            packet
+ * @ret:            true if packet has virtio header, false otherwize
+ *
+ */
+bool vmxnet_rx_pkt_has_virt_hdr(struct VmxnetRxPkt *pkt);
+
+/**
+ * attach data to rx packet
+ *
+ * @pkt:            packet
+ * @data:           pointer to the data buffer
+ * @len:            data length
+ * @strip_vlan:     should the module strip vlan from data
+ *
+ */
+void vmxnet_rx_pkt_attach_data(struct VmxnetRxPkt *pkt, const void *data,
+    size_t len, bool strip_vlan);
+
+/**
+ * returns io vector that holds the attached data
+ *
+ * @pkt:            packet
+ * @ret:            pointer to IOVec
+ *
+ */
+struct iovec *vmxnet_rx_pkt_get_iovec(struct VmxnetRxPkt *pkt);
+
+/**
+ * prints rx packet data if debug is enabled
+ *
+ * @pkt:            packet
+ *
+ */
+void vmxnet_rx_pkt_dump(struct VmxnetRxPkt *pkt);
+
+/**
+ * copy passed vhdr data to packet context
+ *
+ * @pkt:            packet
+ * @vhdr:           VHDR buffer
+ *
+ */
+void vmxnet_rx_pkt_set_vhdr(struct VmxnetRxPkt *pkt,
+    struct virtio_net_hdr *vhdr);
+
+/**
+ * save packet type in packet context
+ *
+ * @pkt:            packet
+ * @packet_type:    the packet type
+ *
+ */
+void vmxnet_rx_pkt_set_packet_type(struct VmxnetRxPkt *pkt,
+    eth_pkt_types_e packet_type);
+
+#endif
similarity index 52%
rename from hw/net/net_tx_pkt.c
rename to hw/net/vmxnet_tx_pkt.c
index 20b2549..91e1e08 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * QEMU TX packets abstractions
+ * QEMU VMWARE VMXNET* paravirtual NICs - TX packets abstractions
  *
  * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
  *
  */
 
 #include "qemu/osdep.h"
-#include "net_tx_pkt.h"
+#include "hw/hw.h"
+#include "vmxnet_tx_pkt.h"
 #include "net/eth.h"
+#include "qemu-common.h"
+#include "qemu/iov.h"
 #include "net/checksum.h"
 #include "net/tap.h"
 #include "net/net.h"
-#include "hw/pci/pci.h"
 
 enum {
-    NET_TX_PKT_VHDR_FRAG = 0,
-    NET_TX_PKT_L2HDR_FRAG,
-    NET_TX_PKT_L3HDR_FRAG,
-    NET_TX_PKT_PL_START_FRAG
+    VMXNET_TX_PKT_VHDR_FRAG = 0,
+    VMXNET_TX_PKT_L2HDR_FRAG,
+    VMXNET_TX_PKT_L3HDR_FRAG,
+    VMXNET_TX_PKT_PL_START_FRAG
 };
 
 /* TX packet private context */
-struct NetTxPkt {
-    PCIDevice *pci_dev;
-
+struct VmxnetTxPkt {
     struct virtio_net_hdr virt_hdr;
     bool has_virt_hdr;
 
@@ -44,7 +44,6 @@ struct NetTxPkt {
     struct iovec *vec;
 
     uint8_t l2_hdr[ETH_MAX_L2_HDR_LEN];
-    uint8_t l3_hdr[ETH_MAX_IP_DGRAM_LEN];
 
     uint32_t payload_len;
 
@@ -54,34 +53,32 @@ struct NetTxPkt {
     uint16_t hdr_len;
     eth_pkt_types_e packet_type;
     uint8_t l4proto;
-
-    bool is_loopback;
 };
 
-void net_tx_pkt_init(struct NetTxPkt **pkt, PCIDevice *pci_dev,
-    uint32_t max_frags, bool has_virt_hdr)
+void vmxnet_tx_pkt_init(struct VmxnetTxPkt **pkt, uint32_t max_frags,
+    bool has_virt_hdr)
 {
-    struct NetTxPkt *p = g_malloc0(sizeof *p);
-
-    p->pci_dev = pci_dev;
+    struct VmxnetTxPkt *p = g_malloc0(sizeof *p);
 
-    p->vec = g_new(struct iovec, max_frags + NET_TX_PKT_PL_START_FRAG);
+    p->vec = g_malloc((sizeof *p->vec) *
+        (max_frags + VMXNET_TX_PKT_PL_START_FRAG));
 
-    p->raw = g_new(struct iovec, max_frags);
+    p->raw = g_malloc((sizeof *p->raw) * max_frags);
 
     p->max_payload_frags = max_frags;
     p->max_raw_frags = max_frags;
     p->has_virt_hdr = has_virt_hdr;
-    p->vec[NET_TX_PKT_VHDR_FRAG].iov_base = &p->virt_hdr;
-    p->vec[NET_TX_PKT_VHDR_FRAG].iov_len =
+    p->vec[VMXNET_TX_PKT_VHDR_FRAG].iov_base = &p->virt_hdr;
+    p->vec[VMXNET_TX_PKT_VHDR_FRAG].iov_len =
         p->has_virt_hdr ? sizeof p->virt_hdr : 0;
-    p->vec[NET_TX_PKT_L2HDR_FRAG].iov_base = &p->l2_hdr;
-    p->vec[NET_TX_PKT_L3HDR_FRAG].iov_base = &p->l3_hdr;
+    p->vec[VMXNET_TX_PKT_L2HDR_FRAG].iov_base = &p->l2_hdr;
+    p->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_base = NULL;
+    p->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_len = 0;
 
     *pkt = p;
 }
 
-void net_tx_pkt_uninit(struct NetTxPkt *pkt)
+void vmxnet_tx_pkt_uninit(struct VmxnetTxPkt *pkt)
 {
     if (pkt) {
         g_free(pkt->vec);
@@ -90,63 +87,49 @@ void net_tx_pkt_uninit(struct NetTxPkt *pkt)
     }
 }
 
-void net_tx_pkt_update_ip_hdr_checksum(struct NetTxPkt *pkt)
+void vmxnet_tx_pkt_update_ip_checksums(struct VmxnetTxPkt *pkt)
 {
     uint16_t csum;
+    uint32_t ph_raw_csum;
     assert(pkt);
+    uint8_t gso_type = pkt->virt_hdr.gso_type & ~VIRTIO_NET_HDR_GSO_ECN;
     struct ip_header *ip_hdr;
-    ip_hdr = pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_base;
 
-    ip_hdr->ip_len = cpu_to_be16(pkt->payload_len +
-        pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len);
-
-    ip_hdr->ip_sum = 0;
-    csum = net_raw_checksum((uint8_t *)ip_hdr,
-        pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len);
-    ip_hdr->ip_sum = cpu_to_be16(csum);
-}
+    if (VIRTIO_NET_HDR_GSO_TCPV4 != gso_type &&
+        VIRTIO_NET_HDR_GSO_UDP != gso_type) {
+        return;
+    }
 
-void net_tx_pkt_update_ip_checksums(struct NetTxPkt *pkt)
-{
-    uint16_t csum;
-    uint32_t cntr, cso;
-    assert(pkt);
-    uint8_t gso_type = pkt->virt_hdr.gso_type & ~VIRTIO_NET_HDR_GSO_ECN;
-    void *ip_hdr = pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_base;
+    ip_hdr = pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_base;
 
-    if (pkt->payload_len + pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len >
+    if (pkt->payload_len + pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_len >
         ETH_MAX_IP_DGRAM_LEN) {
         return;
     }
 
-    if (gso_type == VIRTIO_NET_HDR_GSO_TCPV4 ||
-        gso_type == VIRTIO_NET_HDR_GSO_UDP) {
-        /* Calculate IP header checksum */
-        net_tx_pkt_update_ip_hdr_checksum(pkt);
-
-        /* Calculate IP pseudo header checksum */
-        cntr = eth_calc_ip4_pseudo_hdr_csum(ip_hdr, pkt->payload_len, &cso);
-        csum = cpu_to_be16(~net_checksum_finish(cntr));
-    } else if (gso_type == VIRTIO_NET_HDR_GSO_TCPV6) {
-        /* Calculate IP pseudo header checksum */
-        cntr = eth_calc_ip6_pseudo_hdr_csum(ip_hdr, pkt->payload_len,
-                                            IP_PROTO_TCP, &cso);
-        csum = cpu_to_be16(~net_checksum_finish(cntr));
-    } else {
-        return;
-    }
+    ip_hdr->ip_len = cpu_to_be16(pkt->payload_len +
+        pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_len);
 
-    iov_from_buf(&pkt->vec[NET_TX_PKT_PL_START_FRAG], pkt->payload_frags,
+    /* Calculate IP header checksum                    */
+    ip_hdr->ip_sum = 0;
+    csum = net_raw_checksum((uint8_t *)ip_hdr,
+        pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_len);
+    ip_hdr->ip_sum = cpu_to_be16(csum);
+
+    /* Calculate IP pseudo header checksum             */
+    ph_raw_csum = eth_calc_pseudo_hdr_csum(ip_hdr, pkt->payload_len);
+    csum = cpu_to_be16(~net_checksum_finish(ph_raw_csum));
+    iov_from_buf(&pkt->vec[VMXNET_TX_PKT_PL_START_FRAG], pkt->payload_frags,
                  pkt->virt_hdr.csum_offset, &csum, sizeof(csum));
 }
 
-static void net_tx_pkt_calculate_hdr_len(struct NetTxPkt *pkt)
+static void vmxnet_tx_pkt_calculate_hdr_len(struct VmxnetTxPkt *pkt)
 {
-    pkt->hdr_len = pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_len +
-        pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len;
+    pkt->hdr_len = pkt->vec[VMXNET_TX_PKT_L2HDR_FRAG].iov_len +
+        pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_len;
 }
 
-static bool net_tx_pkt_parse_headers(struct NetTxPkt *pkt)
+static bool vmxnet_tx_pkt_parse_headers(struct VmxnetTxPkt *pkt)
 {
     struct iovec *l2_hdr, *l3_hdr;
     size_t bytes_read;
@@ -155,8 +138,8 @@ static bool net_tx_pkt_parse_headers(struct NetTxPkt *pkt)
 
     assert(pkt);
 
-    l2_hdr = &pkt->vec[NET_TX_PKT_L2HDR_FRAG];
-    l3_hdr = &pkt->vec[NET_TX_PKT_L3HDR_FRAG];
+    l2_hdr = &pkt->vec[VMXNET_TX_PKT_L2HDR_FRAG];
+    l3_hdr = &pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG];
 
     bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags, 0, l2_hdr->iov_base,
                             ETH_MAX_L2_HDR_LEN);
@@ -177,19 +160,15 @@ static bool net_tx_pkt_parse_headers(struct NetTxPkt *pkt)
 
     if (bytes_read < l2_hdr->iov_len) {
         l2_hdr->iov_len = 0;
-        l3_hdr->iov_len = 0;
-        pkt->packet_type = ETH_PKT_UCAST;
         return false;
-    } else {
-        l2_hdr->iov_len = ETH_MAX_L2_HDR_LEN;
-        l2_hdr->iov_len = eth_get_l2_hdr_length(l2_hdr->iov_base);
-        pkt->packet_type = get_eth_packet_type(l2_hdr->iov_base);
     }
 
-    l3_proto = eth_get_l3_proto(l2_hdr, 1, l2_hdr->iov_len);
+    l3_proto = eth_get_l3_proto(l2_hdr->iov_base, l2_hdr->iov_len);
 
     switch (l3_proto) {
     case ETH_P_IP:
+        l3_hdr->iov_base = g_malloc(ETH_MAX_IP4_HDR_LEN);
+
         bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags, l2_hdr->iov_len,
                                 l3_hdr->iov_base, sizeof(struct ip_header));
 
@@ -199,45 +178,27 @@ static bool net_tx_pkt_parse_headers(struct NetTxPkt *pkt)
         }
 
         l3_hdr->iov_len = IP_HDR_GET_LEN(l3_hdr->iov_base);
+        pkt->l4proto = ((struct ip_header *) l3_hdr->iov_base)->ip_p;
 
-        if (l3_hdr->iov_len < sizeof(struct ip_header)) {
+        /* copy optional IPv4 header data */
+        bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags,
+                                l2_hdr->iov_len + sizeof(struct ip_header),
+                                l3_hdr->iov_base + sizeof(struct ip_header),
+                                l3_hdr->iov_len - sizeof(struct ip_header));
+        if (bytes_read < l3_hdr->iov_len - sizeof(struct ip_header)) {
             l3_hdr->iov_len = 0;
             return false;
         }
-
-        pkt->l4proto = ((struct ip_header *) l3_hdr->iov_base)->ip_p;
-
-        if (IP_HDR_GET_LEN(l3_hdr->iov_base) != sizeof(struct ip_header)) {
-            /* copy optional IPv4 header data if any*/
-            bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags,
-                                    l2_hdr->iov_len + sizeof(struct ip_header),
-                                    l3_hdr->iov_base + sizeof(struct ip_header),
-                                    l3_hdr->iov_len - sizeof(struct ip_header));
-            if (bytes_read < l3_hdr->iov_len - sizeof(struct ip_header)) {
-                l3_hdr->iov_len = 0;
-                return false;
-            }
-        }
-
         break;
 
     case ETH_P_IPV6:
-    {
-        eth_ip6_hdr_info hdrinfo;
-
         if (!eth_parse_ipv6_hdr(pkt->raw, pkt->raw_frags, l2_hdr->iov_len,
-                                &hdrinfo)) {
+                               &pkt->l4proto, &full_ip6hdr_len)) {
             l3_hdr->iov_len = 0;
             return false;
         }
 
-        pkt->l4proto = hdrinfo.l4proto;
-        full_ip6hdr_len = hdrinfo.full_hdr_len;
-
-        if (full_ip6hdr_len > ETH_MAX_IP_DGRAM_LEN) {
-            l3_hdr->iov_len = 0;
-            return false;
-        }
+        l3_hdr->iov_base = g_malloc(full_ip6hdr_len);
 
         bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags, l2_hdr->iov_len,
                                 l3_hdr->iov_base, full_ip6hdr_len);
@@ -249,62 +210,67 @@ static bool net_tx_pkt_parse_headers(struct NetTxPkt *pkt)
             l3_hdr->iov_len = full_ip6hdr_len;
         }
         break;
-    }
+
     default:
         l3_hdr->iov_len = 0;
         break;
     }
 
-    net_tx_pkt_calculate_hdr_len(pkt);
+    vmxnet_tx_pkt_calculate_hdr_len(pkt);
+    pkt->packet_type = get_eth_packet_type(l2_hdr->iov_base);
     return true;
 }
 
-static void net_tx_pkt_rebuild_payload(struct NetTxPkt *pkt)
+static bool vmxnet_tx_pkt_rebuild_payload(struct VmxnetTxPkt *pkt)
 {
-    pkt->payload_len = iov_size(pkt->raw, pkt->raw_frags) - pkt->hdr_len;
-    pkt->payload_frags = iov_copy(&pkt->vec[NET_TX_PKT_PL_START_FRAG],
+    size_t payload_len = iov_size(pkt->raw, pkt->raw_frags) - pkt->hdr_len;
+
+    pkt->payload_frags = iov_copy(&pkt->vec[VMXNET_TX_PKT_PL_START_FRAG],
                                 pkt->max_payload_frags,
                                 pkt->raw, pkt->raw_frags,
-                                pkt->hdr_len, pkt->payload_len);
-}
+                                pkt->hdr_len, payload_len);
 
-bool net_tx_pkt_parse(struct NetTxPkt *pkt)
-{
-    if (net_tx_pkt_parse_headers(pkt)) {
-        net_tx_pkt_rebuild_payload(pkt);
+    if (pkt->payload_frags != (uint32_t) -1) {
+        pkt->payload_len = payload_len;
         return true;
     } else {
         return false;
     }
 }
 
-struct virtio_net_hdr *net_tx_pkt_get_vhdr(struct NetTxPkt *pkt)
+bool vmxnet_tx_pkt_parse(struct VmxnetTxPkt *pkt)
+{
+    return vmxnet_tx_pkt_parse_headers(pkt) &&
+           vmxnet_tx_pkt_rebuild_payload(pkt);
+}
+
+struct virtio_net_hdr *vmxnet_tx_pkt_get_vhdr(struct VmxnetTxPkt *pkt)
 {
     assert(pkt);
     return &pkt->virt_hdr;
 }
 
-static uint8_t net_tx_pkt_get_gso_type(struct NetTxPkt *pkt,
+static uint8_t vmxnet_tx_pkt_get_gso_type(struct VmxnetTxPkt *pkt,
                                           bool tso_enable)
 {
     uint8_t rc = VIRTIO_NET_HDR_GSO_NONE;
     uint16_t l3_proto;
 
-    l3_proto = eth_get_l3_proto(&pkt->vec[NET_TX_PKT_L2HDR_FRAG], 1,
-        pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_len);
+    l3_proto = eth_get_l3_proto(pkt->vec[VMXNET_TX_PKT_L2HDR_FRAG].iov_base,
+        pkt->vec[VMXNET_TX_PKT_L2HDR_FRAG].iov_len);
 
     if (!tso_enable) {
         goto func_exit;
     }
 
-    rc = eth_get_gso_type(l3_proto, pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_base,
+    rc = eth_get_gso_type(l3_proto, pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_base,
                           pkt->l4proto);
 
 func_exit:
     return rc;
 }
 
-void net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
+void vmxnet_tx_pkt_build_vheader(struct VmxnetTxPkt *pkt, bool tso_enable,
     bool csum_enable, uint32_t gso_size)
 {
     struct tcp_hdr l4hdr;
@@ -313,7 +279,7 @@ void net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
     /* csum has to be enabled if tso is. */
     assert(csum_enable || !tso_enable);
 
-    pkt->virt_hdr.gso_type = net_tx_pkt_get_gso_type(pkt, tso_enable);
+    pkt->virt_hdr.gso_type = vmxnet_tx_pkt_get_gso_type(pkt, tso_enable);
 
     switch (pkt->virt_hdr.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
     case VIRTIO_NET_HDR_GSO_NONE:
@@ -322,16 +288,16 @@ void net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
         break;
 
     case VIRTIO_NET_HDR_GSO_UDP:
-        pkt->virt_hdr.gso_size = gso_size;
+        pkt->virt_hdr.gso_size = IP_FRAG_ALIGN_SIZE(gso_size);
         pkt->virt_hdr.hdr_len = pkt->hdr_len + sizeof(struct udp_header);
         break;
 
     case VIRTIO_NET_HDR_GSO_TCPV4:
     case VIRTIO_NET_HDR_GSO_TCPV6:
-        iov_to_buf(&pkt->vec[NET_TX_PKT_PL_START_FRAG], pkt->payload_frags,
+        iov_to_buf(&pkt->vec[VMXNET_TX_PKT_PL_START_FRAG], pkt->payload_frags,
                    0, &l4hdr, sizeof(l4hdr));
         pkt->virt_hdr.hdr_len = pkt->hdr_len + l4hdr.th_off * sizeof(uint32_t);
-        pkt->virt_hdr.gso_size = gso_size;
+        pkt->virt_hdr.gso_size = IP_FRAG_ALIGN_SIZE(gso_size);
         break;
 
     default:
@@ -356,24 +322,23 @@ void net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
     }
 }
 
-void net_tx_pkt_setup_vlan_header_ex(struct NetTxPkt *pkt,
-    uint16_t vlan, uint16_t vlan_ethtype)
+void vmxnet_tx_pkt_setup_vlan_header(struct VmxnetTxPkt *pkt, uint16_t vlan)
 {
     bool is_new;
     assert(pkt);
 
-    eth_setup_vlan_headers_ex(pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_base,
-        vlan, vlan_ethtype, &is_new);
+    eth_setup_vlan_headers(pkt->vec[VMXNET_TX_PKT_L2HDR_FRAG].iov_base,
+        vlan, &is_new);
 
     /* update l2hdrlen */
     if (is_new) {
         pkt->hdr_len += sizeof(struct vlan_header);
-        pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_len +=
+        pkt->vec[VMXNET_TX_PKT_L2HDR_FRAG].iov_len +=
             sizeof(struct vlan_header);
     }
 }
 
-bool net_tx_pkt_add_raw_fragment(struct NetTxPkt *pkt, hwaddr pa,
+bool vmxnet_tx_pkt_add_raw_fragment(struct VmxnetTxPkt *pkt, hwaddr pa,
     size_t len)
 {
     hwaddr mapped_len = 0;
@@ -388,50 +353,44 @@ bool net_tx_pkt_add_raw_fragment(struct NetTxPkt *pkt, hwaddr pa,
     ventry = &pkt->raw[pkt->raw_frags];
     mapped_len = len;
 
-    ventry->iov_base = pci_dma_map(pkt->pci_dev, pa,
-                                   &mapped_len, DMA_DIRECTION_TO_DEVICE);
+    ventry->iov_base = cpu_physical_memory_map(pa, &mapped_len, false);
+    ventry->iov_len = mapped_len;
+    pkt->raw_frags += !!ventry->iov_base;
 
-    if ((ventry->iov_base != NULL) && (len == mapped_len)) {
-        ventry->iov_len = mapped_len;
-        pkt->raw_frags++;
-        return true;
-    } else {
+    if ((ventry->iov_base == NULL) || (len != mapped_len)) {
         return false;
     }
-}
 
-bool net_tx_pkt_has_fragments(struct NetTxPkt *pkt)
-{
-    return pkt->raw_frags > 0;
+    return true;
 }
 
-eth_pkt_types_e net_tx_pkt_get_packet_type(struct NetTxPkt *pkt)
+eth_pkt_types_e vmxnet_tx_pkt_get_packet_type(struct VmxnetTxPkt *pkt)
 {
     assert(pkt);
 
     return pkt->packet_type;
 }
 
-size_t net_tx_pkt_get_total_len(struct NetTxPkt *pkt)
+size_t vmxnet_tx_pkt_get_total_len(struct VmxnetTxPkt *pkt)
 {
     assert(pkt);
 
     return pkt->hdr_len + pkt->payload_len;
 }
 
-void net_tx_pkt_dump(struct NetTxPkt *pkt)
+void vmxnet_tx_pkt_dump(struct VmxnetTxPkt *pkt)
 {
-#ifdef NET_TX_PKT_DEBUG
+#ifdef VMXNET_TX_PKT_DEBUG
     assert(pkt);
 
     printf("TX PKT: hdr_len: %d, pkt_type: 0x%X, l2hdr_len: %lu, "
         "l3hdr_len: %lu, payload_len: %u\n", pkt->hdr_len, pkt->packet_type,
-        pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_len,
-        pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len, pkt->payload_len);
+        pkt->vec[VMXNET_TX_PKT_L2HDR_FRAG].iov_len,
+        pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_len, pkt->payload_len);
 #endif
 }
 
-void net_tx_pkt_reset(struct NetTxPkt *pkt)
+void vmxnet_tx_pkt_reset(struct VmxnetTxPkt *pkt)
 {
     int i;
 
@@ -442,31 +401,38 @@ void net_tx_pkt_reset(struct NetTxPkt *pkt)
 
     memset(&pkt->virt_hdr, 0, sizeof(pkt->virt_hdr));
 
-    assert(pkt->vec);
+    g_free(pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_base);
+    pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_base = NULL;
 
+    assert(pkt->vec);
+    for (i = VMXNET_TX_PKT_L2HDR_FRAG;
+         i < pkt->payload_frags + VMXNET_TX_PKT_PL_START_FRAG; i++) {
+        pkt->vec[i].iov_len = 0;
+    }
     pkt->payload_len = 0;
     pkt->payload_frags = 0;
 
     assert(pkt->raw);
     for (i = 0; i < pkt->raw_frags; i++) {
         assert(pkt->raw[i].iov_base);
-        pci_dma_unmap(pkt->pci_dev, pkt->raw[i].iov_base, pkt->raw[i].iov_len,
-                      DMA_DIRECTION_TO_DEVICE, 0);
+        cpu_physical_memory_unmap(pkt->raw[i].iov_base, pkt->raw[i].iov_len,
+                                  false, pkt->raw[i].iov_len);
+        pkt->raw[i].iov_len = 0;
     }
     pkt->raw_frags = 0;
 
     pkt->hdr_len = 0;
+    pkt->packet_type = 0;
     pkt->l4proto = 0;
 }
 
-static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt)
+static void vmxnet_tx_pkt_do_sw_csum(struct VmxnetTxPkt *pkt)
 {
-    struct iovec *iov = &pkt->vec[NET_TX_PKT_L2HDR_FRAG];
+    struct iovec *iov = &pkt->vec[VMXNET_TX_PKT_L2HDR_FRAG];
     uint32_t csum_cntr;
     uint16_t csum = 0;
-    uint32_t cso;
     /* num of iovec without vhdr */
-    uint32_t iov_len = pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - 1;
+    uint32_t iov_len = pkt->payload_frags + VMXNET_TX_PKT_PL_START_FRAG - 1;
     uint16_t csl;
     struct ip_header *iphdr;
     size_t csum_offset = pkt->virt_hdr.csum_start + pkt->virt_hdr.csum_offset;
@@ -477,13 +443,12 @@ static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt)
     /* Calculate L4 TCP/UDP checksum */
     csl = pkt->payload_len;
 
-    /* add pseudo header to csum */
-    iphdr = pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_base;
-    csum_cntr = eth_calc_ip4_pseudo_hdr_csum(iphdr, csl, &cso);
-
     /* data checksum */
-    csum_cntr +=
-        net_checksum_add_iov(iov, iov_len, pkt->virt_hdr.csum_start, csl, cso);
+    csum_cntr =
+        net_checksum_add_iov(iov, iov_len, pkt->virt_hdr.csum_start, csl);
+    /* add pseudo header to csum */
+    iphdr = pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_base;
+    csum_cntr += eth_calc_pseudo_hdr_csum(iphdr, csl);
 
     /* Put the checksum obtained into the packet */
     csum = cpu_to_be16(net_checksum_finish(csum_cntr));
@@ -491,37 +456,37 @@ static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt)
 }
 
 enum {
-    NET_TX_PKT_FRAGMENT_L2_HDR_POS = 0,
-    NET_TX_PKT_FRAGMENT_L3_HDR_POS,
-    NET_TX_PKT_FRAGMENT_HEADER_NUM
+    VMXNET_TX_PKT_FRAGMENT_L2_HDR_POS = 0,
+    VMXNET_TX_PKT_FRAGMENT_L3_HDR_POS,
+    VMXNET_TX_PKT_FRAGMENT_HEADER_NUM
 };
 
-#define NET_MAX_FRAG_SG_LIST (64)
+#define VMXNET_MAX_FRAG_SG_LIST (64)
 
-static size_t net_tx_pkt_fetch_fragment(struct NetTxPkt *pkt,
+static size_t vmxnet_tx_pkt_fetch_fragment(struct VmxnetTxPkt *pkt,
     int *src_idx, size_t *src_offset, struct iovec *dst, int *dst_idx)
 {
     size_t fetched = 0;
     struct iovec *src = pkt->vec;
 
-    *dst_idx = NET_TX_PKT_FRAGMENT_HEADER_NUM;
+    *dst_idx = VMXNET_TX_PKT_FRAGMENT_HEADER_NUM;
 
-    while (fetched < IP_FRAG_ALIGN_SIZE(pkt->virt_hdr.gso_size)) {
+    while (fetched < pkt->virt_hdr.gso_size) {
 
         /* no more place in fragment iov */
-        if (*dst_idx == NET_MAX_FRAG_SG_LIST) {
+        if (*dst_idx == VMXNET_MAX_FRAG_SG_LIST) {
             break;
         }
 
         /* no more data in iovec */
-        if (*src_idx == (pkt->payload_frags + NET_TX_PKT_PL_START_FRAG)) {
+        if (*src_idx == (pkt->payload_frags + VMXNET_TX_PKT_PL_START_FRAG)) {
             break;
         }
 
 
         dst[*dst_idx].iov_base = src[*src_idx].iov_base + *src_offset;
         dst[*dst_idx].iov_len = MIN(src[*src_idx].iov_len - *src_offset,
-            IP_FRAG_ALIGN_SIZE(pkt->virt_hdr.gso_size) - fetched);
+            pkt->virt_hdr.gso_size - fetched);
 
         *src_offset += dst[*dst_idx].iov_len;
         fetched += dst[*dst_idx].iov_len;
@@ -537,45 +502,35 @@ static size_t net_tx_pkt_fetch_fragment(struct NetTxPkt *pkt,
     return fetched;
 }
 
-static inline void net_tx_pkt_sendv(struct NetTxPkt *pkt,
-    NetClientState *nc, const struct iovec *iov, int iov_cnt)
-{
-    if (pkt->is_loopback) {
-        nc->info->receive_iov(nc, iov, iov_cnt);
-    } else {
-        qemu_sendv_packet(nc, iov, iov_cnt);
-    }
-}
-
-static bool net_tx_pkt_do_sw_fragmentation(struct NetTxPkt *pkt,
+static bool vmxnet_tx_pkt_do_sw_fragmentation(struct VmxnetTxPkt *pkt,
     NetClientState *nc)
 {
-    struct iovec fragment[NET_MAX_FRAG_SG_LIST];
+    struct iovec fragment[VMXNET_MAX_FRAG_SG_LIST];
     size_t fragment_len = 0;
     bool more_frags = false;
 
     /* some pointers for shorter code */
     void *l2_iov_base, *l3_iov_base;
     size_t l2_iov_len, l3_iov_len;
-    int src_idx =  NET_TX_PKT_PL_START_FRAG, dst_idx;
+    int src_idx =  VMXNET_TX_PKT_PL_START_FRAG, dst_idx;
     size_t src_offset = 0;
     size_t fragment_offset = 0;
 
-    l2_iov_base = pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_base;
-    l2_iov_len = pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_len;
-    l3_iov_base = pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_base;
-    l3_iov_len = pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len;
+    l2_iov_base = pkt->vec[VMXNET_TX_PKT_L2HDR_FRAG].iov_base;
+    l2_iov_len = pkt->vec[VMXNET_TX_PKT_L2HDR_FRAG].iov_len;
+    l3_iov_base = pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_base;
+    l3_iov_len = pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_len;
 
     /* Copy headers */
-    fragment[NET_TX_PKT_FRAGMENT_L2_HDR_POS].iov_base = l2_iov_base;
-    fragment[NET_TX_PKT_FRAGMENT_L2_HDR_POS].iov_len = l2_iov_len;
-    fragment[NET_TX_PKT_FRAGMENT_L3_HDR_POS].iov_base = l3_iov_base;
-    fragment[NET_TX_PKT_FRAGMENT_L3_HDR_POS].iov_len = l3_iov_len;
+    fragment[VMXNET_TX_PKT_FRAGMENT_L2_HDR_POS].iov_base = l2_iov_base;
+    fragment[VMXNET_TX_PKT_FRAGMENT_L2_HDR_POS].iov_len = l2_iov_len;
+    fragment[VMXNET_TX_PKT_FRAGMENT_L3_HDR_POS].iov_base = l3_iov_base;
+    fragment[VMXNET_TX_PKT_FRAGMENT_L3_HDR_POS].iov_len = l3_iov_len;
 
 
     /* Put as much data as possible and send */
     do {
-        fragment_len = net_tx_pkt_fetch_fragment(pkt, &src_idx, &src_offset,
+        fragment_len = vmxnet_tx_pkt_fetch_fragment(pkt, &src_idx, &src_offset,
             fragment, &dst_idx);
 
         more_frags = (fragment_offset + fragment_len < pkt->payload_len);
@@ -585,22 +540,22 @@ static bool net_tx_pkt_do_sw_fragmentation(struct NetTxPkt *pkt,
 
         eth_fix_ip4_checksum(l3_iov_base, l3_iov_len);
 
-        net_tx_pkt_sendv(pkt, nc, fragment, dst_idx);
+        qemu_sendv_packet(nc, fragment, dst_idx);
 
         fragment_offset += fragment_len;
 
-    } while (fragment_len && more_frags);
+    } while (more_frags);
 
     return true;
 }
 
-bool net_tx_pkt_send(struct NetTxPkt *pkt, NetClientState *nc)
+bool vmxnet_tx_pkt_send(struct VmxnetTxPkt *pkt, NetClientState *nc)
 {
     assert(pkt);
 
     if (!pkt->has_virt_hdr &&
         pkt->virt_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
-        net_tx_pkt_do_sw_csum(pkt);
+        vmxnet_tx_pkt_do_sw_csum(pkt);
     }
 
     /*
@@ -610,28 +565,17 @@ bool net_tx_pkt_send(struct NetTxPkt *pkt, NetClientState *nc)
     if (VIRTIO_NET_HDR_GSO_NONE != pkt->virt_hdr.gso_type) {
         if (pkt->payload_len >
             ETH_MAX_IP_DGRAM_LEN -
-            pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len) {
+            pkt->vec[VMXNET_TX_PKT_L3HDR_FRAG].iov_len) {
             return false;
         }
     }
 
     if (pkt->has_virt_hdr ||
         pkt->virt_hdr.gso_type == VIRTIO_NET_HDR_GSO_NONE) {
-        net_tx_pkt_sendv(pkt, nc, pkt->vec,
-            pkt->payload_frags + NET_TX_PKT_PL_START_FRAG);
+        qemu_sendv_packet(nc, pkt->vec,
+            pkt->payload_frags + VMXNET_TX_PKT_PL_START_FRAG);
         return true;
     }
 
-    return net_tx_pkt_do_sw_fragmentation(pkt, nc);
-}
-
-bool net_tx_pkt_send_loopback(struct NetTxPkt *pkt, NetClientState *nc)
-{
-    bool res;
-
-    pkt->is_loopback = true;
-    res = net_tx_pkt_send(pkt, nc);
-    pkt->is_loopback = false;
-
-    return res;
+    return vmxnet_tx_pkt_do_sw_fragmentation(pkt, nc);
 }
diff --git a/hw/net/vmxnet_tx_pkt.h b/hw/net/vmxnet_tx_pkt.h
new file mode 100644 (file)
index 0000000..f51e98a
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * QEMU VMWARE VMXNET* paravirtual NICs - TX packets abstraction
+ *
+ * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
+ *
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
+ *
+ * Authors:
+ * Dmitry Fleytman <dmitry@daynix.com>
+ * Tamir Shomer <tamirs@daynix.com>
+ * Yan Vugenfirer <yan@daynix.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef VMXNET_TX_PKT_H
+#define VMXNET_TX_PKT_H
+
+#include "net/eth.h"
+#include "exec/hwaddr.h"
+
+/* define to enable packet dump functions */
+/*#define VMXNET_TX_PKT_DEBUG*/
+
+struct VmxnetTxPkt;
+
+/**
+ * Init function for tx packet functionality
+ *
+ * @pkt:            packet pointer
+ * @max_frags:      max tx ip fragments
+ * @has_virt_hdr:   device uses virtio header.
+ */
+void vmxnet_tx_pkt_init(struct VmxnetTxPkt **pkt, uint32_t max_frags,
+    bool has_virt_hdr);
+
+/**
+ * Clean all tx packet resources.
+ *
+ * @pkt:            packet.
+ */
+void vmxnet_tx_pkt_uninit(struct VmxnetTxPkt *pkt);
+
+/**
+ * get virtio header
+ *
+ * @pkt:            packet
+ * @ret:            virtio header
+ */
+struct virtio_net_hdr *vmxnet_tx_pkt_get_vhdr(struct VmxnetTxPkt *pkt);
+
+/**
+ * build virtio header (will be stored in module context)
+ *
+ * @pkt:            packet
+ * @tso_enable:     TSO enabled
+ * @csum_enable:    CSO enabled
+ * @gso_size:       MSS size for TSO
+ *
+ */
+void vmxnet_tx_pkt_build_vheader(struct VmxnetTxPkt *pkt, bool tso_enable,
+    bool csum_enable, uint32_t gso_size);
+
+/**
+ * updates vlan tag, and adds vlan header in case it is missing
+ *
+ * @pkt:            packet
+ * @vlan:           VLAN tag
+ *
+ */
+void vmxnet_tx_pkt_setup_vlan_header(struct VmxnetTxPkt *pkt, uint16_t vlan);
+
+/**
+ * populate data fragment into pkt context.
+ *
+ * @pkt:            packet
+ * @pa:             physical address of fragment
+ * @len:            length of fragment
+ *
+ */
+bool vmxnet_tx_pkt_add_raw_fragment(struct VmxnetTxPkt *pkt, hwaddr pa,
+    size_t len);
+
+/**
+ * fix ip header fields and calculate checksums needed.
+ *
+ * @pkt:            packet
+ *
+ */
+void vmxnet_tx_pkt_update_ip_checksums(struct VmxnetTxPkt *pkt);
+
+/**
+ * get length of all populated data.
+ *
+ * @pkt:            packet
+ * @ret:            total data length
+ *
+ */
+size_t vmxnet_tx_pkt_get_total_len(struct VmxnetTxPkt *pkt);
+
+/**
+ * get packet type
+ *
+ * @pkt:            packet
+ * @ret:            packet type
+ *
+ */
+eth_pkt_types_e vmxnet_tx_pkt_get_packet_type(struct VmxnetTxPkt *pkt);
+
+/**
+ * prints packet data if debug is enabled
+ *
+ * @pkt:            packet
+ *
+ */
+void vmxnet_tx_pkt_dump(struct VmxnetTxPkt *pkt);
+
+/**
+ * reset tx packet private context (needed to be called between packets)
+ *
+ * @pkt:            packet
+ *
+ */
+void vmxnet_tx_pkt_reset(struct VmxnetTxPkt *pkt);
+
+/**
+ * Send packet to qemu. handles sw offloads if vhdr is not supported.
+ *
+ * @pkt:            packet
+ * @nc:             NetClientState
+ * @ret:            operation result
+ *
+ */
+bool vmxnet_tx_pkt_send(struct VmxnetTxPkt *pkt, NetClientState *nc);
+
+/**
+ * parse raw packet data and analyze offload requirements.
+ *
+ * @pkt:            packet
+ *
+ */
+bool vmxnet_tx_pkt_parse(struct VmxnetTxPkt *pkt);
+
+#endif
index 6856b52..7281730 100644 (file)
@@ -22,6 +22,7 @@
 #include "qemu/osdep.h"
 #include <sys/socket.h>
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 #include <sys/wait.h>
 
 #include "hw/hw.h"
@@ -269,7 +270,7 @@ static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size
 /* ------------------------------------------------------------- */
 
 static NetClientInfo net_xen_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = net_rx_packet,
 };
index 46b1aa1..0c5f793 100644 (file)
@@ -371,7 +371,7 @@ out:
 }
 
 static NetClientInfo net_xgmac_enet_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = eth_rx,
 };
index b670184..de23ab5 100644 (file)
@@ -935,7 +935,7 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size)
 }
 
 static NetClientInfo net_xilinx_enet_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = eth_rx,
 };
index 35de353..bc846e7 100644 (file)
@@ -197,10 +197,6 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
     }
 
     D(qemu_log("%s %zd rxbase=%x\n", __func__, size, rxbase));
-    if (size > (R_MAX - R_RX_BUF0 - rxbase) * 4) {
-        D(qemu_log("ethlite packet is too big, size=%x\n", size));
-        return -1;
-    }
     memcpy(&s->regs[rxbase + R_RX_BUF0], buf, size);
 
     s->regs[rxbase + R_RX_CTRL0] |= CTRL_S;
@@ -221,7 +217,7 @@ static void xilinx_ethlite_reset(DeviceState *dev)
 }
 
 static NetClientInfo net_xilinx_ethlite_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .can_receive = eth_can_rx,
     .receive = eth_rx,
index 6a68e59..999f480 100644 (file)
@@ -25,7 +25,6 @@
 #include "hw/hw.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/dma.h"
-#include "hw/boards.h"
 #include "hw/isa/isa.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/sysbus.h"
@@ -552,7 +551,7 @@ static bool is_version_1(void *opaque, int version_id)
     return version_id == 1;
 }
 
-bool fw_cfg_dma_enabled(void *opaque)
+static bool fw_cfg_dma_enabled(void *opaque)
 {
     FWCfgState *s = opaque;
 
@@ -729,22 +728,17 @@ static int get_fw_cfg_order(FWCfgState *s, const char *name)
 {
     int i;
 
-    if (s->fw_cfg_order_override > 0) {
-        return s->fw_cfg_order_override;
-    }
+    if (s->fw_cfg_order_override > 0)
+       return s->fw_cfg_order_override;
 
     for (i = 0; i < ARRAY_SIZE(fw_cfg_order); i++) {
-        if (fw_cfg_order[i].name == NULL) {
-            continue;
-        }
-
-        if (strcmp(name, fw_cfg_order[i].name) == 0) {
-            return fw_cfg_order[i].order;
-        }
+       if (fw_cfg_order[i].name == NULL)
+           continue;
+       if (strcmp(name, fw_cfg_order[i].name) == 0)
+           return fw_cfg_order[i].order;
     }
-
     /* Stick unknown stuff at the end. */
-    error_report("warning: Unknown firmware file in legacy mode: %s", name);
+    error_report("warning: Unknown firmware file in legacy mode: %s\n", name);
     return FW_CFG_ORDER_OVERRIDE_LAST;
 }
 
@@ -874,17 +868,16 @@ static void fw_cfg_machine_ready(struct Notifier *n, void *data)
 static void fw_cfg_init1(DeviceState *dev)
 {
     FWCfgState *s = FW_CFG(dev);
-    MachineState *machine = MACHINE(qdev_get_machine());
 
     assert(!object_resolve_path(FW_CFG_PATH, NULL));
 
-    object_property_add_child(OBJECT(machine), FW_CFG_NAME, OBJECT(s), NULL);
+    object_property_add_child(qdev_get_machine(), FW_CFG_NAME, OBJECT(s), NULL);
 
     qdev_init_nofail(dev);
 
     fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (char *)"QEMU", 4);
     fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
-    fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)!machine->enable_graphics);
+    fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)(display_type == DT_NOGRAPHIC));
     fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
     fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);
     fw_cfg_bootsplash(s);
@@ -990,7 +983,6 @@ static void fw_cfg_class_init(ObjectClass *klass, void *data)
 static const TypeInfo fw_cfg_info = {
     .name          = TYPE_FW_CFG,
     .parent        = TYPE_SYS_BUS_DEVICE,
-    .abstract      = true,
     .instance_size = sizeof(FWCfgState),
     .class_init    = fw_cfg_class_init,
 };
index 4de5f70..802636e 100644 (file)
@@ -39,7 +39,6 @@ typedef struct sPAPRNVRAM {
     uint32_t size;
     uint8_t *buf;
     BlockBackend *blk;
-    VMChangeStateEntry *vmstate;
 } sPAPRNVRAM;
 
 #define TYPE_VIO_SPAPR_NVRAM "spapr-nvram"
@@ -125,7 +124,7 @@ static void rtas_nvram_store(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 
     alen = len;
     if (nvram->blk) {
-        alen = blk_pwrite(nvram->blk, offset, membuf, len, 0);
+        alen = blk_pwrite(nvram->blk, offset, membuf, len);
     }
 
     assert(nvram->buf);
@@ -186,25 +185,19 @@ static int spapr_nvram_pre_load(void *opaque)
     return 0;
 }
 
-static void postload_update_cb(void *opaque, int running, RunState state)
-{
-    sPAPRNVRAM *nvram = opaque;
-
-    /* This is called after bdrv_invalidate_cache_all.  */
-
-    qemu_del_vm_change_state_handler(nvram->vmstate);
-    nvram->vmstate = NULL;
-
-    blk_pwrite(nvram->blk, 0, nvram->buf, nvram->size, 0);
-}
-
 static int spapr_nvram_post_load(void *opaque, int version_id)
 {
     sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(opaque);
 
     if (nvram->blk) {
-        nvram->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,
-                                                          nvram);
+        int alen = blk_pwrite(nvram->blk, 0, nvram->buf, nvram->size);
+
+        if (alen < 0) {
+            return alen;
+        }
+        if (alen != nvram->size) {
+            return -1;
+        }
     }
 
     return 0;
diff --git a/hw/nvram/trace-events b/hw/nvram/trace-events
deleted file mode 100644 (file)
index 1f1e05a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/nvram/ds1225y.c
-nvram_read(uint32_t addr, uint32_t ret) "read addr %d: 0x%02x"
-nvram_write(uint32_t addr, uint32_t old, uint32_t val) "write addr %d: 0x%02x -> 0x%02x"
-
-# hw/nvram/fw_cfg.c
-fw_cfg_select(void *s, uint16_t key, int ret) "%p key %d = %d"
-fw_cfg_read(void *s, uint64_t ret) "%p = %"PRIx64
-fw_cfg_add_file(void *s, int index, char *name, size_t len) "%p #%d: %s (%zd bytes)"
index ae17ca7..17dc0c2 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef HW_PCI_BRIDGE_DEC_H
-#define HW_PCI_BRIDGE_DEC_H
+#ifndef DEC_PCI_H
+#define DEC_PCI_H
 
 #include "qemu-common.h"
 
index c8b5ac4..0937fa3 100644 (file)
@@ -25,7 +25,6 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/pcie.h"
 #include "ioh3420.h"
-#include "qapi/error.h"
 
 #define PCI_DEVICE_ID_IOH_EPORT         0x3420  /* D0:F0 express mode */
 #define PCI_DEVICE_ID_IOH_REV           0x2
@@ -98,9 +97,7 @@ static int ioh3420_initfn(PCIDevice *d)
     PCIEPort *p = PCIE_PORT(d);
     PCIESlot *s = PCIE_SLOT(d);
     int rc;
-    Error *err = NULL;
 
-    pci_config_set_interrupt_pin(d->config, 1);
     pci_bridge_initfn(d, TYPE_PCIE_BUS);
     pcie_port_init_reg(d);
 
@@ -109,16 +106,12 @@ static int ioh3420_initfn(PCIDevice *d)
     if (rc < 0) {
         goto err_bridge;
     }
-
     rc = msi_init(d, IOH_EP_MSI_OFFSET, IOH_EP_MSI_NR_VECTOR,
                   IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
-                  IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT, &err);
+                  IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT);
     if (rc < 0) {
-        assert(rc == -ENOTSUP);
-        error_report_err(err);
         goto err_bridge;
     }
-
     rc = pcie_cap_init(d, IOH_EP_EXP_OFFSET, PCI_EXP_TYPE_ROOT_PORT, p->port);
     if (rc < 0) {
         goto err_msi;
@@ -127,21 +120,18 @@ static int ioh3420_initfn(PCIDevice *d)
     pcie_cap_arifwd_init(d);
     pcie_cap_deverr_init(d);
     pcie_cap_slot_init(d, s->slot);
-    pcie_cap_root_init(d);
-
     pcie_chassis_create(s->chassis);
     rc = pcie_chassis_add_slot(s);
     if (rc < 0) {
         goto err_pcie_cap;
     }
-
+    pcie_cap_root_init(d);
     rc = pcie_aer_init(d, IOH_EP_AER_OFFSET, PCI_ERR_SIZEOF);
     if (rc < 0) {
         goto err;
     }
     pcie_aer_root_init(d);
     ioh3420_aer_vector_update(d);
-
     return 0;
 
 err:
@@ -217,3 +207,12 @@ static void ioh3420_register_types(void)
 }
 
 type_init(ioh3420_register_types)
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 8
+ *  indent-tab-mode: nil
+ * End:
+ */
index 5dbd933..7b582e9 100644 (file)
@@ -42,10 +42,9 @@ struct PCIBridgeDev {
 
     MemoryRegion bar;
     uint8_t chassis_nr;
-#define PCI_BRIDGE_DEV_F_SHPC_REQ 0
+#define PCI_BRIDGE_DEV_F_MSI_REQ 0
+#define PCI_BRIDGE_DEV_F_SHPC_REQ 1
     uint32_t flags;
-
-    OnOffAuto msi;
 };
 typedef struct PCIBridgeDev PCIBridgeDev;
 
@@ -54,7 +53,6 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
     PCIBridge *br = PCI_BRIDGE(dev);
     PCIBridgeDev *bridge_dev = PCI_BRIDGE_DEV(dev);
     int err;
-    Error *local_err = NULL;
 
     pci_bridge_initfn(dev, TYPE_PCI_BUS);
 
@@ -68,33 +66,19 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
         }
     } else {
         /* MSI is not applicable without SHPC */
-        bridge_dev->msi = ON_OFF_AUTO_OFF;
+        bridge_dev->flags &= ~(1 << PCI_BRIDGE_DEV_F_MSI_REQ);
     }
-
     err = slotid_cap_init(dev, 0, bridge_dev->chassis_nr, 0);
     if (err) {
         goto slotid_error;
     }
-
-    if (bridge_dev->msi != ON_OFF_AUTO_OFF) {
-        /* it means SHPC exists, because MSI is needed by SHPC */
-
-        err = msi_init(dev, 0, 1, true, true, &local_err);
-        /* Any error other than -ENOTSUP(board's MSI support is broken)
-         * is a programming error */
-        assert(!err || err == -ENOTSUP);
-        if (err && bridge_dev->msi == ON_OFF_AUTO_ON) {
-            /* Can't satisfy user's explicit msi=on request, fail */
-            error_append_hint(&local_err, "You have to use msi=auto (default) "
-                    "or msi=off with this machine type.\n");
-            error_report_err(local_err);
+    if ((bridge_dev->flags & (1 << PCI_BRIDGE_DEV_F_MSI_REQ)) &&
+        msi_nonbroken) {
+        err = msi_init(dev, 0, 1, true, true);
+        if (err < 0) {
             goto msi_error;
         }
-        assert(!local_err || bridge_dev->msi == ON_OFF_AUTO_AUTO);
-        /* With msi=auto, we fall back to MSI off silently */
-        error_free(local_err);
     }
-
     if (shpc_present(dev)) {
         /* TODO: spec recommends using 64 bit prefetcheable BAR.
          * Check whether that works well. */
@@ -102,7 +86,6 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
                          PCI_BASE_ADDRESS_MEM_TYPE_64, &bridge_dev->bar);
     }
     return 0;
-
 msi_error:
     slotid_cap_cleanup(dev);
 slotid_error:
@@ -160,8 +143,8 @@ static Property pci_bridge_dev_properties[] = {
                     /* Note: 0 is not a legal chassis number. */
     DEFINE_PROP_UINT8(PCI_BRIDGE_DEV_PROP_CHASSIS_NR, PCIBridgeDev, chassis_nr,
                       0),
-    DEFINE_PROP_ON_OFF_AUTO(PCI_BRIDGE_DEV_PROP_MSI, PCIBridgeDev, msi,
-                            ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_BIT(PCI_BRIDGE_DEV_PROP_MSI, PCIBridgeDev, flags,
+                    PCI_BRIDGE_DEV_F_MSI_REQ, true),
     DEFINE_PROP_BIT(PCI_BRIDGE_DEV_PROP_SHPC, PCIBridgeDev, flags,
                     PCI_BRIDGE_DEV_F_SHPC_REQ, true),
     DEFINE_PROP_END_OF_LIST(),
index 1cc598f..ba320bd 100644 (file)
@@ -11,7 +11,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "qapi/error.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_host.h"
@@ -150,8 +149,6 @@ static void pxb_host_class_init(ObjectClass *class, void *data)
     PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(class);
 
     dc->fw_name = "pci";
-    /* Reason: Internal part of the pxb/pxb-pcie device, not usable by itself */
-    dc->cannot_instantiate_with_device_add_yet = true;
     sbc->explicit_ofw_unit_address = pxb_host_ofw_unit_address;
     hc->root_bus_path = pxb_host_root_bus_path;
 }
@@ -163,25 +160,30 @@ static const TypeInfo pxb_host_info = {
 };
 
 /*
- * Registers the PXB bus as a child of pci host root bus.
+ * Registers the PXB bus as a child of the i440fx root bus.
+ *
+ * Returns 0 on successs, -1 if i440fx host was not
+ * found or the bus number is already in use.
  */
-static void pxb_register_bus(PCIDevice *dev, PCIBus *pxb_bus, Error **errp)
+static int pxb_register_bus(PCIDevice *dev, PCIBus *pxb_bus)
 {
     PCIBus *bus = dev->bus;
     int pxb_bus_num = pci_bus_num(pxb_bus);
 
     if (bus->parent_dev) {
-        error_setg(errp, "PXB devices can be attached only to root bus");
-        return;
+        error_report("PXB devices can be attached only to root bus.");
+        return -1;
     }
 
     QLIST_FOREACH(bus, &bus->child, sibling) {
         if (pci_bus_num(bus) == pxb_bus_num) {
-            error_setg(errp, "Bus %d is already in use", pxb_bus_num);
-            return;
+            error_report("Bus %d is already in use.", pxb_bus_num);
+            return -1;
         }
     }
     QLIST_INSERT_HEAD(&dev->bus->child, pxb_bus, sibling);
+
+    return 0;
 }
 
 static int pxb_map_irq_fn(PCIDevice *pci_dev, int pin)
@@ -211,18 +213,17 @@ static gint pxb_compare(gconstpointer a, gconstpointer b)
            0;
 }
 
-static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp)
+static int pxb_dev_init_common(PCIDevice *dev, bool pcie)
 {
     PXBDev *pxb = convert_to_pxb(dev);
     DeviceState *ds, *bds = NULL;
     PCIBus *bus;
     const char *dev_name = NULL;
-    Error *local_err = NULL;
 
     if (pxb->numa_node != NUMA_NODE_UNASSIGNED &&
         pxb->numa_node >= nb_numa_nodes) {
-        error_setg(errp, "Illegal numa node %d", pxb->numa_node);
-        return;
+        error_report("Illegal numa node %d.", pxb->numa_node);
+        return -EINVAL;
     }
 
     if (dev->qdev.id && *dev->qdev.id) {
@@ -247,9 +248,7 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp)
 
     PCI_HOST_BRIDGE(ds)->bus = bus;
 
-    pxb_register_bus(dev, bus, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
+    if (pxb_register_bus(dev, bus)) {
         goto err_register_bus;
     }
 
@@ -263,22 +262,23 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp)
     pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_HOST);
 
     pxb_dev_list = g_list_insert_sorted(pxb_dev_list, pxb, pxb_compare);
-    return;
+    return 0;
 
 err_register_bus:
     object_unref(OBJECT(bds));
     object_unparent(OBJECT(bus));
     object_unref(OBJECT(ds));
+    return -EINVAL;
 }
 
-static void pxb_dev_realize(PCIDevice *dev, Error **errp)
+static int pxb_dev_initfn(PCIDevice *dev)
 {
     if (pci_bus_is_express(dev->bus)) {
-        error_setg(errp, "pxb devices cannot reside on a PCIe bus");
-        return;
+        error_report("pxb devices cannot reside on a PCIe bus!");
+        return -EINVAL;
     }
 
-    pxb_dev_realize_common(dev, false, errp);
+    return pxb_dev_init_common(dev, false);
 }
 
 static void pxb_dev_exitfn(PCIDevice *pci_dev)
@@ -300,7 +300,7 @@ static void pxb_dev_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    k->realize = pxb_dev_realize;
+    k->init = pxb_dev_initfn;
     k->exit = pxb_dev_exitfn;
     k->vendor_id = PCI_VENDOR_ID_REDHAT;
     k->device_id = PCI_DEVICE_ID_REDHAT_PXB;
@@ -308,7 +308,6 @@ static void pxb_dev_class_init(ObjectClass *klass, void *data)
 
     dc->desc = "PCI Expander Bridge";
     dc->props = pxb_dev_properties;
-    dc->hotpluggable = false;
     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 }
 
@@ -319,14 +318,14 @@ static const TypeInfo pxb_dev_info = {
     .class_init    = pxb_dev_class_init,
 };
 
-static void pxb_pcie_dev_realize(PCIDevice *dev, Error **errp)
+static int pxb_pcie_dev_initfn(PCIDevice *dev)
 {
     if (!pci_bus_is_express(dev->bus)) {
-        error_setg(errp, "pxb-pcie devices cannot reside on a PCI bus");
-        return;
+        error_report("pxb-pcie devices cannot reside on a PCI bus!");
+        return -EINVAL;
     }
 
-    pxb_dev_realize_common(dev, true, errp);
+    return pxb_dev_init_common(dev, true);
 }
 
 static void pxb_pcie_dev_class_init(ObjectClass *klass, void *data)
@@ -334,7 +333,7 @@ static void pxb_pcie_dev_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    k->realize = pxb_pcie_dev_realize;
+    k->init = pxb_pcie_dev_initfn;
     k->exit = pxb_dev_exitfn;
     k->vendor_id = PCI_VENDOR_ID_REDHAT;
     k->device_id = PCI_DEVICE_ID_REDHAT_PXB_PCIE;
@@ -342,7 +341,6 @@ static void pxb_pcie_dev_class_init(ObjectClass *klass, void *data)
 
     dc->desc = "PCI Express Expander Bridge";
     dc->props = pxb_dev_properties;
-    dc->hotpluggable = false;
     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 }
 
index cef6e13..cf1ee63 100644 (file)
@@ -24,7 +24,6 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/pcie.h"
 #include "xio3130_downstream.h"
-#include "qapi/error.h"
 
 #define PCI_DEVICE_ID_TI_XIO3130D       0x8233  /* downstream port */
 #define XIO3130_REVISION                0x1
@@ -61,26 +60,21 @@ static int xio3130_downstream_initfn(PCIDevice *d)
     PCIEPort *p = PCIE_PORT(d);
     PCIESlot *s = PCIE_SLOT(d);
     int rc;
-    Error *err = NULL;
 
     pci_bridge_initfn(d, TYPE_PCIE_BUS);
     pcie_port_init_reg(d);
 
     rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,
                   XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
-                  XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT, &err);
+                  XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT);
     if (rc < 0) {
-        assert(rc == -ENOTSUP);
-        error_report_err(err);
         goto err_bridge;
     }
-
     rc = pci_bridge_ssvid_init(d, XIO3130_SSVID_OFFSET,
                                XIO3130_SSVID_SVID, XIO3130_SSVID_SSID);
     if (rc < 0) {
         goto err_bridge;
     }
-
     rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, PCI_EXP_TYPE_DOWNSTREAM,
                        p->port);
     if (rc < 0) {
@@ -89,14 +83,12 @@ static int xio3130_downstream_initfn(PCIDevice *d)
     pcie_cap_flr_init(d);
     pcie_cap_deverr_init(d);
     pcie_cap_slot_init(d, s->slot);
-    pcie_cap_arifwd_init(d);
-
     pcie_chassis_create(s->chassis);
     rc = pcie_chassis_add_slot(s);
     if (rc < 0) {
         goto err_pcie_cap;
     }
-
+    pcie_cap_arifwd_init(d);
     rc = pcie_aer_init(d, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF);
     if (rc < 0) {
         goto err;
@@ -203,3 +195,12 @@ static void xio3130_downstream_register_types(void)
 }
 
 type_init(xio3130_downstream_register_types)
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 8
+ *  indent-tab-mode: nil
+ * End:
+ */
index 4ad0440..164ef58 100644 (file)
@@ -24,7 +24,6 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/pcie.h"
 #include "xio3130_upstream.h"
-#include "qapi/error.h"
 
 #define PCI_DEVICE_ID_TI_XIO3130U       0x8232  /* upstream port */
 #define XIO3130_REVISION                0x2
@@ -57,26 +56,21 @@ static int xio3130_upstream_initfn(PCIDevice *d)
 {
     PCIEPort *p = PCIE_PORT(d);
     int rc;
-    Error *err = NULL;
 
     pci_bridge_initfn(d, TYPE_PCIE_BUS);
     pcie_port_init_reg(d);
 
     rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,
                   XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
-                  XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT, &err);
+                  XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT);
     if (rc < 0) {
-        assert(rc == -ENOTSUP);
-        error_report_err(err);
         goto err_bridge;
     }
-
     rc = pci_bridge_ssvid_init(d, XIO3130_SSVID_OFFSET,
                                XIO3130_SSVID_SVID, XIO3130_SSVID_SSID);
     if (rc < 0) {
         goto err_bridge;
     }
-
     rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, PCI_EXP_TYPE_UPSTREAM,
                        p->port);
     if (rc < 0) {
@@ -84,7 +78,6 @@ static int xio3130_upstream_initfn(PCIDevice *d)
     }
     pcie_cap_flr_init(d);
     pcie_cap_deverr_init(d);
-
     rc = pcie_aer_init(d, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF);
     if (rc < 0) {
         goto err;
@@ -174,3 +167,13 @@ static void xio3130_upstream_register_types(void)
 }
 
 type_init(xio3130_upstream_register_types)
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 8
+ *  indent-tab-mode: nil
+ * End:
+ */
index d0ab757..08c1d5f 100644 (file)
@@ -7,4 +7,4 @@ PCIEPort *xio3130_upstream_init(PCIBus *bus, int devfn, bool multifunction,
                                 const char *bus_name, pci_map_irq_fn map_irq,
                                 uint8_t port);
 
-#endif /* QEMU_XIO3130_UPSTREAM_H */
+#endif /* QEMU_XIO3130_H */
index 653e711..aaef7bb 100644 (file)
@@ -36,7 +36,6 @@
 #include "hw/pci-host/apb.h"
 #include "sysemu/sysemu.h"
 #include "exec/address-spaces.h"
-#include "qemu/log.h"
 
 /* debug APB */
 //#define DEBUG_APB
@@ -634,7 +633,7 @@ static void pci_apb_set_irq(void *opaque, int irq_num, int level)
     }
 }
 
-static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp)
+static int apb_pci_bridge_initfn(PCIDevice *dev)
 {
     pci_bridge_initfn(dev, TYPE_PCI_BUS);
 
@@ -652,6 +651,7 @@ static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp)
     pci_set_word(dev->config + PCI_STATUS,
                  PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
                  PCI_STATUS_DEVSEL_MEDIUM);
+    return 0;
 }
 
 PCIBus *pci_apb_init(hwaddr special_base,
@@ -669,13 +669,6 @@ PCIBus *pci_apb_init(hwaddr special_base,
 
     /* Ultrasparc PBM main bus */
     dev = qdev_create(NULL, TYPE_APB);
-    d = APB_DEVICE(dev);
-    phb = PCI_HOST_BRIDGE(dev);
-    phb->bus = pci_register_bus(DEVICE(phb), "pci",
-                                pci_apb_set_irq, pci_pbm_map_irq, d,
-                                &d->pci_mmio,
-                                get_system_io(),
-                                0, 32, TYPE_PCI_BUS);
     qdev_init_nofail(dev);
     s = SYS_BUS_DEVICE(dev);
     /* apb_config */
@@ -684,10 +677,18 @@ PCIBus *pci_apb_init(hwaddr special_base,
     sysbus_mmio_map(s, 1, special_base + 0x1000000ULL);
     /* pci_ioport */
     sysbus_mmio_map(s, 2, special_base + 0x2000000ULL);
+    d = APB_DEVICE(dev);
 
     memory_region_init(&d->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
     memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
 
+    phb = PCI_HOST_BRIDGE(dev);
+    phb->bus = pci_register_bus(DEVICE(phb), "pci",
+                                pci_apb_set_irq, pci_pbm_map_irq, d,
+                                &d->pci_mmio,
+                                get_system_io(),
+                                0, 32, TYPE_PCI_BUS);
+
     *pbm_irqs = d->pbm_irqs;
     d->ivec_irqs = ivec_irqs;
 
@@ -842,7 +843,7 @@ static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    k->realize = apb_pci_bridge_realize;
+    k->init = apb_pci_bridge_initfn;
     k->exit = pci_bridge_exitfn;
     k->vendor_id = PCI_VENDOR_ID_SUN;
     k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
index 2c8acda..8f91216 100644 (file)
@@ -72,6 +72,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
     GrackleState *d;
 
     dev = qdev_create(NULL, TYPE_GRACKLE_PCI_HOST_BRIDGE);
+    qdev_init_nofail(dev);
     s = SYS_BUS_DEVICE(dev);
     phb = PCI_HOST_BRIDGE(dev);
     d = GRACKLE_PCI_HOST_BRIDGE(dev);
@@ -91,7 +92,6 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
                                 0, 4, TYPE_PCI_BUS);
 
     pci_create_simple(phb->bus, 0, "grackle");
-    qdev_init_nofail(dev);
 
     sysbus_mmio_map(s, 0, base);
     sysbus_mmio_map(s, 1, base + 0x00200000);
index f9218aa..df2b0e2 100644 (file)
@@ -48,7 +48,7 @@
 
 typedef struct I440FXState {
     PCIHostState parent_obj;
-    Range pci_hole;
+    PcPciInfo pci_info;
     uint64_t pci_hole64_size;
     uint32_t short_root_bus;
 } I440FXState;
@@ -221,12 +221,8 @@ static void i440fx_pcihost_get_pci_hole_start(Object *obj, Visitor *v,
                                               Error **errp)
 {
     I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
-    uint64_t val64;
-    uint32_t value;
+    uint32_t value = s->pci_info.w32.begin;
 
-    val64 = range_is_empty(&s->pci_hole) ? 0 : range_lob(&s->pci_hole);
-    value = val64;
-    assert(value == val64);
     visit_type_uint32(v, name, &value, errp);
 }
 
@@ -235,12 +231,8 @@ static void i440fx_pcihost_get_pci_hole_end(Object *obj, Visitor *v,
                                             Error **errp)
 {
     I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
-    uint64_t val64;
-    uint32_t value;
+    uint32_t value = s->pci_info.w32.end;
 
-    val64 = range_is_empty(&s->pci_hole) ? 0 : range_upb(&s->pci_hole) + 1;
-    value = val64;
-    assert(value == val64);
     visit_type_uint32(v, name, &value, errp);
 }
 
@@ -250,11 +242,10 @@ static void i440fx_pcihost_get_pci_hole64_start(Object *obj, Visitor *v,
 {
     PCIHostState *h = PCI_HOST_BRIDGE(obj);
     Range w64;
-    uint64_t value;
 
     pci_bus_get_w64_range(h->bus, &w64);
-    value = range_is_empty(&w64) ? 0 : range_lob(&w64);
-    visit_type_uint64(v, name, &value, errp);
+
+    visit_type_uint64(v, name, &w64.begin, errp);
 }
 
 static void i440fx_pcihost_get_pci_hole64_end(Object *obj, Visitor *v,
@@ -263,16 +254,16 @@ static void i440fx_pcihost_get_pci_hole64_end(Object *obj, Visitor *v,
 {
     PCIHostState *h = PCI_HOST_BRIDGE(obj);
     Range w64;
-    uint64_t value;
 
     pci_bus_get_w64_range(h->bus, &w64);
-    value = range_is_empty(&w64) ? 0 : range_upb(&w64) + 1;
-    visit_type_uint64(v, name, &value, errp);
+
+    visit_type_uint64(v, name, &w64.end, errp);
 }
 
 static void i440fx_pcihost_initfn(Object *obj)
 {
     PCIHostState *s = PCI_HOST_BRIDGE(obj);
+    I440FXState *d = I440FX_PCI_HOST_BRIDGE(obj);
 
     memory_region_init_io(&s->conf_mem, obj, &pci_host_conf_le_ops, s,
                           "pci-conf-idx", 4);
@@ -294,6 +285,8 @@ static void i440fx_pcihost_initfn(Object *obj)
     object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "int",
                         i440fx_pcihost_get_pci_hole64_end,
                         NULL, NULL, NULL, NULL);
+
+    d->pci_info.w32.end = IO_APIC_DEFAULT_ADDRESS;
 }
 
 static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
@@ -354,8 +347,7 @@ PCIBus *i440fx_init(const char *host_type, const char *pci_type,
     f->ram_memory = ram_memory;
 
     i440fx = I440FX_PCI_HOST_BRIDGE(dev);
-    range_set_bounds(&i440fx->pci_hole, below_4g_mem_size,
-                     IO_APIC_DEFAULT_ADDRESS - 1);
+    i440fx->pci_info.w32.begin = below_4g_mem_size;
 
     /* setup pci memory mapping */
     pc_pci_as_mapping_init(OBJECT(f), f->system_memory,
@@ -873,8 +865,6 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
     dc->realize = i440fx_pcihost_realize;
     dc->fw_name = "pci";
     dc->props = i440fx_props;
-    /* Reason: needs to be wired up by pc_init1 */
-    dc->cannot_instantiate_with_device_add_yet = true;
 }
 
 static const TypeInfo i440fx_pcihost_info = {
index 5580293..487e32e 100644 (file)
@@ -247,7 +247,6 @@ static void raven_pcihost_realizefn(DeviceState *d, Error **errp)
     memory_region_add_subregion(address_space_mem, 0xbffffff0, &s->pci_intack);
 
     /* TODO Remove once realize propagates to child devices. */
-    object_property_set_bool(OBJECT(&s->pci_bus), true, "realized", errp);
     object_property_set_bool(OBJECT(&s->pci_dev), true, "realized", errp);
 }
 
index 344f77b..70f897e 100644 (file)
@@ -52,7 +52,6 @@ static void q35_host_realize(DeviceState *dev, Error **errp)
     pci->bus = pci_bus_new(DEVICE(s), "pcie.0",
                            s->mch.pci_address_space, s->mch.address_space_io,
                            0, TYPE_PCIE_BUS);
-    PC_MACHINE(qdev_get_machine())->bus = pci->bus;
     qdev_set_parent_bus(DEVICE(&s->mch), BUS(pci->bus));
     qdev_init_nofail(DEVICE(&s->mch));
 }
@@ -74,13 +73,8 @@ static void q35_host_get_pci_hole_start(Object *obj, Visitor *v,
                                         Error **errp)
 {
     Q35PCIHost *s = Q35_HOST_DEVICE(obj);
-    uint64_t val64;
-    uint32_t value;
+    uint32_t value = s->mch.pci_info.w32.begin;
 
-    val64 = range_is_empty(&s->mch.pci_hole)
-        ? 0 : range_lob(&s->mch.pci_hole);
-    value = val64;
-    assert(value == val64);
     visit_type_uint32(v, name, &value, errp);
 }
 
@@ -89,13 +83,8 @@ static void q35_host_get_pci_hole_end(Object *obj, Visitor *v,
                                       Error **errp)
 {
     Q35PCIHost *s = Q35_HOST_DEVICE(obj);
-    uint64_t val64;
-    uint32_t value;
+    uint32_t value = s->mch.pci_info.w32.end;
 
-    val64 = range_is_empty(&s->mch.pci_hole)
-        ? 0 : range_upb(&s->mch.pci_hole) + 1;
-    value = val64;
-    assert(value == val64);
     visit_type_uint32(v, name, &value, errp);
 }
 
@@ -105,11 +94,10 @@ static void q35_host_get_pci_hole64_start(Object *obj, Visitor *v,
 {
     PCIHostState *h = PCI_HOST_BRIDGE(obj);
     Range w64;
-    uint64_t value;
 
     pci_bus_get_w64_range(h->bus, &w64);
-    value = range_is_empty(&w64) ? 0 : range_lob(&w64);
-    visit_type_uint64(v, name, &value, errp);
+
+    visit_type_uint64(v, name, &w64.begin, errp);
 }
 
 static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v,
@@ -118,11 +106,10 @@ static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v,
 {
     PCIHostState *h = PCI_HOST_BRIDGE(obj);
     Range w64;
-    uint64_t value;
 
     pci_bus_get_w64_range(h->bus, &w64);
-    value = range_is_empty(&w64) ? 0 : range_upb(&w64) + 1;
-    visit_type_uint64(v, name, &value, errp);
+
+    visit_type_uint64(v, name, &w64.end, errp);
 }
 
 static void q35_host_get_mmcfg_size(Object *obj, Visitor *v, const char *name,
@@ -140,10 +127,6 @@ static Property mch_props[] = {
     DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost,
                      mch.pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
     DEFINE_PROP_UINT32("short_root_bus", Q35PCIHost, mch.short_root_bus, 0),
-    DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MEM_SIZE, Q35PCIHost,
-                     mch.below_4g_mem_size, 0),
-    DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, Q35PCIHost,
-                     mch.above_4g_mem_size, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -155,8 +138,6 @@ static void q35_host_class_init(ObjectClass *klass, void *data)
     hc->root_bus_path = q35_host_root_bus_path;
     dc->realize = q35_host_realize;
     dc->props = mch_props;
-    /* Reason: needs to be wired up by pc_q35_init */
-    dc->cannot_instantiate_with_device_add_yet = true;
     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
     dc->fw_name = "pci";
 }
@@ -196,30 +177,14 @@ static void q35_host_initfn(Object *obj)
                         q35_host_get_mmcfg_size,
                         NULL, NULL, NULL, NULL);
 
-    object_property_add_link(obj, MCH_HOST_PROP_RAM_MEM, TYPE_MEMORY_REGION,
-                             (Object **) &s->mch.ram_memory,
-                             qdev_prop_allow_set_link_before_realize, 0, NULL);
-
-    object_property_add_link(obj, MCH_HOST_PROP_PCI_MEM, TYPE_MEMORY_REGION,
-                             (Object **) &s->mch.pci_address_space,
-                             qdev_prop_allow_set_link_before_realize, 0, NULL);
-
-    object_property_add_link(obj, MCH_HOST_PROP_SYSTEM_MEM, TYPE_MEMORY_REGION,
-                             (Object **) &s->mch.system_memory,
-                             qdev_prop_allow_set_link_before_realize, 0, NULL);
-
-    object_property_add_link(obj, MCH_HOST_PROP_IO_MEM, TYPE_MEMORY_REGION,
-                             (Object **) &s->mch.address_space_io,
-                             qdev_prop_allow_set_link_before_realize, 0, NULL);
-
     /* Leave enough space for the biggest MCFG BAR */
     /* TODO: this matches current bios behaviour, but
      * it's not a power of two, which means an MTRR
      * can't cover it exactly.
      */
-    range_set_bounds(&s->mch.pci_hole,
-            MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT + MCH_HOST_BRIDGE_PCIEXBAR_MAX,
-            IO_APIC_DEFAULT_ADDRESS - 1);
+    s->mch.pci_info.w32.begin = MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT +
+        MCH_HOST_BRIDGE_PCIEXBAR_MAX;
+    s->mch.pci_info.w32.end = IO_APIC_DEFAULT_ADDRESS;
 }
 
 static const TypeInfo q35_host_info = {
@@ -287,7 +252,10 @@ static void mch_update_pciexbar(MCHPCIState *mch)
         break;
     case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD:
     default:
+        enable = 0;
+        length = 0;
         abort();
+        break;
     }
     addr = pciexbar & addr_mask;
     pcie_host_mmcfg_update(pehb, enable, addr, length);
@@ -297,13 +265,9 @@ static void mch_update_pciexbar(MCHPCIState *mch)
      * which means an MTRR can't cover it exactly.
      */
     if (enable) {
-        range_set_bounds(&mch->pci_hole,
-                         addr + length,
-                         IO_APIC_DEFAULT_ADDRESS - 1);
+        mch->pci_info.w32.begin = addr + length;
     } else {
-        range_set_bounds(&mch->pci_hole,
-                         MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT,
-                         IO_APIC_DEFAULT_ADDRESS - 1);
+        mch->pci_info.w32.begin = MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT;
     }
 }
 
@@ -460,6 +424,30 @@ static void mch_reset(DeviceState *qdev)
     mch_update(mch);
 }
 
+static AddressSpace *q35_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
+{
+    IntelIOMMUState *s = opaque;
+    VTDAddressSpace *vtd_as;
+
+    assert(0 <= devfn && devfn <= VTD_PCI_DEVFN_MAX);
+
+    vtd_as = vtd_find_add_as(s, bus, devfn);
+    return &vtd_as->as;
+}
+
+static void mch_init_dmar(MCHPCIState *mch)
+{
+    PCIBus *pci_bus = PCI_BUS(qdev_get_parent_bus(DEVICE(mch)));
+
+    mch->iommu = INTEL_IOMMU_DEVICE(qdev_create(NULL, TYPE_INTEL_IOMMU_DEVICE));
+    object_property_add_child(OBJECT(mch), "intel-iommu",
+                              OBJECT(mch->iommu), NULL);
+    qdev_init_nofail(DEVICE(mch->iommu));
+    sysbus_mmio_map(SYS_BUS_DEVICE(mch->iommu), 0, Q35_HOST_BRIDGE_IOMMU_ADDR);
+
+    pci_setup_iommu(pci_bus, q35_host_dma_iommu, mch->iommu);
+}
+
 static void mch_realize(PCIDevice *d, Error **errp)
 {
     int i;
@@ -518,6 +506,10 @@ static void mch_realize(PCIDevice *d, Error **errp)
                  mch->pci_address_space, &mch->pam_regions[i+1],
                  PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE);
     }
+    /* Intel IOMMU (VT-d) */
+    if (object_property_get_bool(qdev_get_machine(), "iommu", NULL)) {
+        mch_init_dmar(mch);
+    }
 }
 
 uint64_t mch_mcfg_base(void)
index 7aac4d6..15b1054 100644 (file)
@@ -62,9 +62,12 @@ typedef struct UNINState {
 
 static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num)
 {
+    int retval;
     int devfn = pci_dev->devfn & 0x00FFFFFF;
 
-    return (((devfn >> 11) & 0x1F) + irq_num) & 3;
+    retval = (((devfn >> 11) & 0x1F) + irq_num) & 3;
+
+    return retval;
 }
 
 static void pci_unin_set_irq(void *opaque, int irq_num, int level)
index 467cbb9..339ec2c 100644 (file)
@@ -13,7 +13,6 @@
 #include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_host.h"
 #include "exec/address-spaces.h"
-#include "qemu/log.h"
 
 /* Old and buggy versions of QEMU used the wrong mapping from
  * PCI IRQs to system interrupt lines. Unfortunately the Linux
@@ -455,7 +454,6 @@ static void pci_vpb_realize(DeviceState *dev, Error **errp)
     }
 
     /* TODO Remove once realize propagates to child devices. */
-    object_property_set_bool(OBJECT(&s->pci_bus), true, "realized", errp);
     object_property_set_bool(OBJECT(&s->pci_dev), true, "realized", errp);
 }
 
index a87b227..a87ef4d 100644 (file)
@@ -22,7 +22,6 @@
 #include "hw/pci/msi.h"
 #include "hw/xen/xen.h"
 #include "qemu/range.h"
-#include "qapi/error.h"
 
 /* PCI_MSI_ADDRESS_LO */
 #define PCI_MSI_ADDRESS_LO_MASK         (~0x3)
@@ -166,25 +165,8 @@ bool msi_enabled(const PCIDevice *dev)
          PCI_MSI_FLAGS_ENABLE);
 }
 
-/*
- * Make PCI device @dev MSI-capable.
- * Non-zero @offset puts capability MSI at that offset in PCI config
- * space.
- * @nr_vectors is the number of MSI vectors (1, 2, 4, 8, 16 or 32).
- * If @msi64bit, make the device capable of sending a 64-bit message
- * address.
- * If @msi_per_vector_mask, make the device support per-vector masking.
- * @errp is for returning errors.
- * Return 0 on success; set @errp and return -errno on error.
- *
- * -ENOTSUP means lacking msi support for a msi-capable platform.
- * -EINVAL means capability overlap, happens when @offset is non-zero,
- *  also means a programming error, except device assignment, which can check
- *  if a real HW is broken.
- */
 int msi_init(struct PCIDevice *dev, uint8_t offset,
-             unsigned int nr_vectors, bool msi64bit,
-             bool msi_per_vector_mask, Error **errp)
+             unsigned int nr_vectors, bool msi64bit, bool msi_per_vector_mask)
 {
     unsigned int vectors_order;
     uint16_t flags;
@@ -192,7 +174,6 @@ int msi_init(struct PCIDevice *dev, uint8_t offset,
     int config_offset;
 
     if (!msi_nonbroken) {
-        error_setg(errp, "MSI is not supported by interrupt controller");
         return -ENOTSUP;
     }
 
@@ -216,8 +197,7 @@ int msi_init(struct PCIDevice *dev, uint8_t offset,
     }
 
     cap_size = msi_cap_sizeof(flags);
-    config_offset = pci_add_capability2(dev, PCI_CAP_ID_MSI, offset,
-                                        cap_size, errp);
+    config_offset = pci_add_capability(dev, PCI_CAP_ID_MSI, offset, cap_size);
     if (config_offset < 0) {
         return config_offset;
     }
@@ -240,8 +220,7 @@ int msi_init(struct PCIDevice *dev, uint8_t offset,
         pci_set_long(dev->wmask + msi_mask_off(dev, msi64bit),
                      0xffffffff >> (PCI_MSI_VECTORS_MAX - nr_vectors));
     }
-
-    return 0;
+    return config_offset;
 }
 
 void msi_uninit(struct PCIDevice *dev)
index 0ec1cb1..b75f0e9 100644 (file)
@@ -72,7 +72,7 @@ void msix_set_pending(PCIDevice *dev, unsigned int vector)
     *msix_pending_byte(dev, vector) |= msix_pending_mask(vector);
 }
 
-void msix_clr_pending(PCIDevice *dev, int vector)
+static void msix_clr_pending(PCIDevice *dev, int vector)
 {
     *msix_pending_byte(dev, vector) &= ~msix_pending_mask(vector);
 }
index 24fae16..616f04c 100644 (file)
@@ -80,37 +80,10 @@ static const VMStateDescription vmstate_pcibus = {
     }
 };
 
-static void pci_init_bus_master(PCIDevice *pci_dev)
-{
-    AddressSpace *dma_as = pci_device_iommu_address_space(pci_dev);
-
-    memory_region_init_alias(&pci_dev->bus_master_enable_region,
-                             OBJECT(pci_dev), "bus master",
-                             dma_as->root, 0, memory_region_size(dma_as->root));
-    memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);
-    address_space_init(&pci_dev->bus_master_as,
-                       &pci_dev->bus_master_enable_region, pci_dev->name);
-}
-
-static void pcibus_machine_done(Notifier *notifier, void *data)
-{
-    PCIBus *bus = container_of(notifier, PCIBus, machine_done);
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
-        if (bus->devices[i]) {
-            pci_init_bus_master(bus->devices[i]);
-        }
-    }
-}
-
 static void pci_bus_realize(BusState *qbus, Error **errp)
 {
     PCIBus *bus = PCI_BUS(qbus);
 
-    bus->machine_done.notify = pcibus_machine_done;
-    qemu_add_machine_init_done_notifier(&bus->machine_done);
-
     vmstate_register(NULL, -1, &vmstate_pcibus, bus);
 }
 
@@ -118,8 +91,6 @@ static void pci_bus_unrealize(BusState *qbus, Error **errp)
 {
     PCIBus *bus = PCI_BUS(qbus);
 
-    qemu_remove_machine_init_done_notifier(&bus->machine_done);
-
     vmstate_unregister(NULL, &vmstate_pcibus, bus);
 }
 
@@ -867,81 +838,6 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
     address_space_destroy(&pci_dev->bus_master_as);
 }
 
-/* Extract PCIReqIDCache into BDF format */
-static uint16_t pci_req_id_cache_extract(PCIReqIDCache *cache)
-{
-    uint8_t bus_n;
-    uint16_t result;
-
-    switch (cache->type) {
-    case PCI_REQ_ID_BDF:
-        result = pci_get_bdf(cache->dev);
-        break;
-    case PCI_REQ_ID_SECONDARY_BUS:
-        bus_n = pci_bus_num(cache->dev->bus);
-        result = PCI_BUILD_BDF(bus_n, 0);
-        break;
-    default:
-        error_printf("Invalid PCI requester ID cache type: %d\n",
-                     cache->type);
-        exit(1);
-        break;
-    }
-
-    return result;
-}
-
-/* Parse bridges up to the root complex and return requester ID
- * cache for specific device.  For full PCIe topology, the cache
- * result would be exactly the same as getting BDF of the device.
- * However, several tricks are required when system mixed up with
- * legacy PCI devices and PCIe-to-PCI bridges.
- *
- * Here we cache the proxy device (and type) not requester ID since
- * bus number might change from time to time.
- */
-static PCIReqIDCache pci_req_id_cache_get(PCIDevice *dev)
-{
-    PCIDevice *parent;
-    PCIReqIDCache cache = {
-        .dev = dev,
-        .type = PCI_REQ_ID_BDF,
-    };
-
-    while (!pci_bus_is_root(dev->bus)) {
-        /* We are under PCI/PCIe bridges */
-        parent = dev->bus->parent_dev;
-        if (pci_is_express(parent)) {
-            if (pcie_cap_get_type(parent) == PCI_EXP_TYPE_PCI_BRIDGE) {
-                /* When we pass through PCIe-to-PCI/PCIX bridges, we
-                 * override the requester ID using secondary bus
-                 * number of parent bridge with zeroed devfn
-                 * (pcie-to-pci bridge spec chap 2.3). */
-                cache.type = PCI_REQ_ID_SECONDARY_BUS;
-                cache.dev = dev;
-            }
-        } else {
-            /* Legacy PCI, override requester ID with the bridge's
-             * BDF upstream.  When the root complex connects to
-             * legacy PCI devices (including buses), it can only
-             * obtain requester ID info from directly attached
-             * devices.  If devices are attached under bridges, only
-             * the requester ID of the bridge that is directly
-             * attached to the root complex can be recognized. */
-            cache.type = PCI_REQ_ID_BDF;
-            cache.dev = parent;
-        }
-        dev = parent;
-    }
-
-    return cache;
-}
-
-uint16_t pci_requester_id(PCIDevice *dev)
-{
-    return pci_req_id_cache_extract(&dev->requester_id_cache);
-}
-
 /* -1 for devfn means auto assign */
 static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
                                          const char *name, int devfn,
@@ -951,6 +847,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
     PCIConfigReadFunc *config_read = pc->config_read;
     PCIConfigWriteFunc *config_write = pc->config_write;
     Error *local_err = NULL;
+    AddressSpace *dma_as;
     DeviceState *dev = DEVICE(pci_dev);
 
     pci_dev->bus = bus;
@@ -990,11 +887,15 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
     }
 
     pci_dev->devfn = devfn;
-    pci_dev->requester_id_cache = pci_req_id_cache_get(pci_dev);
+    dma_as = pci_device_iommu_address_space(pci_dev);
+
+    memory_region_init_alias(&pci_dev->bus_master_enable_region,
+                             OBJECT(pci_dev), "bus master",
+                             dma_as->root, 0, memory_region_size(dma_as->root));
+    memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);
+    address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region,
+                       name);
 
-    if (qdev_hotplug) {
-        pci_init_bus_master(pci_dev);
-    }
     pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
     pci_dev->irq_state = 0;
     pci_config_alloc(pci_dev);
@@ -1076,7 +977,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
                       uint8_t type, MemoryRegion *memory)
 {
     PCIIORegion *r;
-    uint32_t addr; /* offset in pci config space */
+    uint32_t addr;
     uint64_t wmask;
     pcibus_t size = memory_region_size(memory);
 
@@ -1092,20 +993,15 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
     r->addr = PCI_BAR_UNMAPPED;
     r->size = size;
     r->type = type;
-    r->memory = memory;
-    r->address_space = type & PCI_BASE_ADDRESS_SPACE_IO
-                        ? pci_dev->bus->address_space_io
-                        : pci_dev->bus->address_space_mem;
+    r->memory = NULL;
 
     wmask = ~(size - 1);
+    addr = pci_bar(pci_dev, region_num);
     if (region_num == PCI_ROM_SLOT) {
         /* ROM enable bit is writable */
         wmask |= PCI_ROM_ADDRESS_ENABLE;
     }
-
-    addr = pci_bar(pci_dev, region_num);
     pci_set_long(pci_dev->config + addr, type);
-
     if (!(r->type & PCI_BASE_ADDRESS_SPACE_IO) &&
         r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
         pci_set_quad(pci_dev->wmask + addr, wmask);
@@ -1114,6 +1010,11 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
         pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff);
         pci_set_long(pci_dev->cmask + addr, 0xffffffff);
     }
+    pci_dev->io_regions[region_num].memory = memory;
+    pci_dev->io_regions[region_num].address_space
+        = type & PCI_BASE_ADDRESS_SPACE_IO
+        ? pci_dev->bus->address_space_io
+        : pci_dev->bus->address_space_mem;
 }
 
 static void pci_update_vga(PCIDevice *pci_dev)
@@ -2253,8 +2154,10 @@ int pci_add_capability2(PCIDevice *pdev, uint8_t cap_id,
 
     if (!offset) {
         offset = pci_find_space(pdev, size);
-        /* out of PCI config space is programming error */
-        assert(offset);
+        if (!offset) {
+            error_setg(errp, "out of PCI config space");
+            return -ENOSPC;
+        }
     } else {
         /* Verify that capabilities don't overlap.  Note: device assignment
          * depends on this check to verify that the device is not broken.
@@ -2535,13 +2438,13 @@ static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque)
 
         if (limit >= base) {
             Range pref_range;
-            range_set_bounds(&pref_range, base, limit);
+            pref_range.begin = base;
+            pref_range.end = limit + 1;
             range_extend(range, &pref_range);
         }
     }
     for (i = 0; i < PCI_NUM_REGIONS; ++i) {
         PCIIORegion *r = &dev->io_regions[i];
-        pcibus_t lob, upb;
         Range region_range;
 
         if (!r->size ||
@@ -2549,17 +2452,16 @@ static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque)
             !(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64)) {
             continue;
         }
+        region_range.begin = pci_bar_address(dev, i, r->type, r->size);
+        region_range.end = region_range.begin + r->size;
 
-        lob = pci_bar_address(dev, i, r->type, r->size);
-        upb = lob + r->size - 1;
-        if (lob == PCI_BAR_UNMAPPED) {
+        if (region_range.begin == PCI_BAR_UNMAPPED) {
             continue;
         }
 
-        lob = MAX(lob, 0x1ULL << 32);
+        region_range.begin = MAX(region_range.begin, 0x1ULL << 32);
 
-        if (upb >= lob) {
-            range_set_bounds(&region_range, lob, upb);
+        if (region_range.end - 1 >= region_range.begin) {
             range_extend(range, &region_range);
         }
     }
@@ -2567,7 +2469,7 @@ static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque)
 
 void pci_bus_get_w64_range(PCIBus *bus, Range *range)
 {
-    range_make_empty(range);
+    range->begin = range->end = 0;
     pci_for_each_device_under_bus(bus, pci_dev_get_w64, range);
 }
 
@@ -2598,21 +2500,6 @@ PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
     }
 }
 
-MSIMessage pci_get_msi_message(PCIDevice *dev, int vector)
-{
-    MSIMessage msg;
-    if (msix_enabled(dev)) {
-        msg = msix_get_message(dev, vector);
-    } else if (msi_enabled(dev)) {
-        msg = msi_get_message(dev, vector);
-    } else {
-        /* Should never happen */
-        error_report("%s: unknown interrupt type", __func__);
-        abort();
-    }
-    return msg;
-}
-
 static const TypeInfo pci_device_type_info = {
     .name = TYPE_PCI_DEVICE,
     .parent = TYPE_DEVICE,
index 99cfb45..c85b4f7 100644 (file)
 /***************************************************************************
  * pci express capability helper functions
  */
-
-static void
-pcie_cap_v1_fill(PCIDevice *dev, uint8_t port, uint8_t type, uint8_t version)
+int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port)
 {
-    uint8_t *exp_cap = dev->config + dev->exp.exp_cap;
-    uint8_t *cmask = dev->cmask + dev->exp.exp_cap;
+    int pos;
+    uint8_t *exp_cap;
+    uint8_t *cmask;
+
+    assert(pci_is_express(dev));
+
+    pos = pci_add_capability(dev, PCI_CAP_ID_EXP, offset,
+                                 PCI_EXP_VER2_SIZEOF);
+    if (pos < 0) {
+        return pos;
+    }
+    dev->exp.exp_cap = pos;
+    exp_cap = dev->config + pos;
+    cmask = dev->cmask + pos;
 
     /* capability register
-    interrupt message number defaults to 0 */
+       interrupt message number defaults to 0 */
     pci_set_word(exp_cap + PCI_EXP_FLAGS,
                  ((type << PCI_EXP_FLAGS_TYPE_SHIFT) & PCI_EXP_FLAGS_TYPE) |
-                 version);
+                 PCI_EXP_FLAGS_VER2);
 
     /* device capability register
      * table 7-12:
@@ -84,27 +94,7 @@ pcie_cap_v1_fill(PCIDevice *dev, uint8_t port, uint8_t type, uint8_t version)
      * Let's not bother checking.
      */
     pci_set_word(cmask + PCI_EXP_LNKSTA, 0);
-}
 
-int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port)
-{
-    /* PCIe cap v2 init */
-    int pos;
-    uint8_t *exp_cap;
-
-    assert(pci_is_express(dev));
-
-    pos = pci_add_capability(dev, PCI_CAP_ID_EXP, offset, PCI_EXP_VER2_SIZEOF);
-    if (pos < 0) {
-        return pos;
-    }
-    dev->exp.exp_cap = pos;
-    exp_cap = dev->config + pos;
-
-    /* Filling values common with v1 */
-    pcie_cap_v1_fill(dev, port, type, PCI_EXP_FLAGS_VER2);
-
-    /* Filling v2 specific values */
     pci_set_long(exp_cap + PCI_EXP_DEVCAP2,
                  PCI_EXP_DEVCAP2_EFF | PCI_EXP_DEVCAP2_EETLPP);
 
@@ -112,27 +102,7 @@ int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port)
     return pos;
 }
 
-int pcie_cap_v1_init(PCIDevice *dev, uint8_t offset, uint8_t type,
-                     uint8_t port)
-{
-    /* PCIe cap v1 init */
-    int pos;
-
-    assert(pci_is_express(dev));
-
-    pos = pci_add_capability(dev, PCI_CAP_ID_EXP, offset, PCI_EXP_VER1_SIZEOF);
-    if (pos < 0) {
-        return pos;
-    }
-    dev->exp.exp_cap = pos;
-
-    pcie_cap_v1_fill(dev, port, type, PCI_EXP_FLAGS_VER1);
-
-    return pos;
-}
-
-static int
-pcie_endpoint_cap_common_init(PCIDevice *dev, uint8_t offset, uint8_t cap_size)
+int pcie_endpoint_cap_init(PCIDevice *dev, uint8_t offset)
 {
     uint8_t type = PCI_EXP_TYPE_ENDPOINT;
 
@@ -145,19 +115,7 @@ pcie_endpoint_cap_common_init(PCIDevice *dev, uint8_t offset, uint8_t cap_size)
         type = PCI_EXP_TYPE_RC_END;
     }
 
-    return (cap_size == PCI_EXP_VER1_SIZEOF)
-        ? pcie_cap_v1_init(dev, offset, type, 0)
-        : pcie_cap_init(dev, offset, type, 0);
-}
-
-int pcie_endpoint_cap_init(PCIDevice *dev, uint8_t offset)
-{
-    return pcie_endpoint_cap_common_init(dev, offset, PCI_EXP_VER2_SIZEOF);
-}
-
-int pcie_endpoint_cap_v1_init(PCIDevice *dev, uint8_t offset)
-{
-    return pcie_endpoint_cap_common_init(dev, offset, PCI_EXP_VER1_SIZEOF);
+    return pcie_cap_init(dev, offset, type, 0);
 }
 
 void pcie_cap_exit(PCIDevice *dev)
@@ -165,11 +123,6 @@ void pcie_cap_exit(PCIDevice *dev)
     pci_del_capability(dev, PCI_CAP_ID_EXP, PCI_EXP_VER2_SIZEOF);
 }
 
-void pcie_cap_v1_exit(PCIDevice *dev)
-{
-    pci_del_capability(dev, PCI_CAP_ID_EXP, PCI_EXP_VER1_SIZEOF);
-}
-
 uint8_t pcie_cap_get_type(const PCIDevice *dev)
 {
     uint32_t pos = dev->exp.exp_cap;
@@ -707,13 +660,3 @@ void pcie_ari_init(PCIDevice *dev, uint16_t offset, uint16_t nextfn)
                         offset, PCI_ARI_SIZEOF);
     pci_set_long(dev->config + offset + PCI_ARI_CAP, (nextfn & 0xff) << 8);
 }
-
-void pcie_dev_ser_num_init(PCIDevice *dev, uint16_t offset, uint64_t ser_num)
-{
-    static const int pci_dsn_ver = 1;
-    static const int pci_dsn_cap = 4;
-
-    pcie_add_capability(dev, PCI_EXT_CAP_ID_DSN, pci_dsn_ver, offset,
-                        PCI_EXT_CAP_DSN_SIZEOF);
-    pci_set_quad(dev->config + offset + pci_dsn_cap, ser_num);
-}
index 048ce6a..e2d4e68 100644 (file)
@@ -21,7 +21,6 @@
 #include "qemu/osdep.h"
 #include "sysemu/sysemu.h"
 #include "qapi/qmp/types.h"
-#include "qapi/qmp/qjson.h"
 #include "monitor/monitor.h"
 #include "hw/pci/pci_bridge.h"
 #include "hw/pci/pcie.h"
diff --git a/hw/pci/trace-events b/hw/pci/trace-events
deleted file mode 100644 (file)
index 2b9cf24..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/pci/pci.c
-pci_update_mappings_del(void *d, uint32_t bus, uint32_t slot, uint32_t func, int bar, uint64_t addr, uint64_t size) "d=%p %02x:%02x.%x %d,%#"PRIx64"+%#"PRIx64
-pci_update_mappings_add(void *d, uint32_t bus, uint32_t slot, uint32_t func, int bar, uint64_t addr, uint64_t size) "d=%p %02x:%02x.%x %d,%#"PRIx64"+%#"PRIx64
-
-# hw/pci/pci_host.c
-pci_cfg_read(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x -> 0x%x"
-pci_cfg_write(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x <- 0x%x"
index 91a3420..c1ffc77 100644 (file)
@@ -4,11 +4,9 @@ obj-y += ppc.o ppc_booke.o
 obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
 obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
 obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
-obj-$(CONFIG_PSERIES) += spapr_cpu_core.o
 ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
 obj-y += spapr_pci_vfio.o
 endif
-obj-$(CONFIG_PSERIES) += spapr_rtas_ddw.o
 # PowerPC 4xx boards
 obj-y += ppc405_boards.o ppc4xx_devs.o ppc405_uc.o ppc440_bamboo.o
 obj-y += ppc4xx_pci.o
index 0cd534d..ee1c60b 100644 (file)
@@ -601,7 +601,7 @@ static int ppce500_prep_device_tree(MachineState *machine,
 }
 
 /* Create -kernel TLB entries for BookE.  */
-hwaddr booke206_page_size_to_tlb(uint64_t size)
+static inline hwaddr booke206_page_size_to_tlb(uint64_t size)
 {
     return 63 - clz64(size >> 10);
 }
index 70ba1d8..ef224ea 100644 (file)
@@ -26,6 +26,4 @@ typedef struct PPCE500Params {
 
 void ppce500_init(MachineState *machine, PPCE500Params *params);
 
-hwaddr booke206_page_size_to_tlb(uint64_t size);
-
 #endif
index 94b4545..b00565c 100644 (file)
@@ -14,7 +14,6 @@
 #include "e500.h"
 #include "hw/boards.h"
 #include "sysemu/device_tree.h"
-#include "sysemu/kvm.h"
 #include "hw/pci/pci.h"
 #include "hw/ppc/openpic.h"
 #include "kvm_ppc.h"
index 20cbddb..5764b86 100644 (file)
@@ -22,9 +22,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
-#ifndef PPC_MAC_H
-#define PPC_MAC_H
+#if !defined(__PPC_MAC_H__)
+#define __PPC_MAC_H__
 
 #include "exec/memory.h"
 #include "hw/sysbus.h"
@@ -185,4 +184,4 @@ typedef struct MacIONVRAMState {
 } MacIONVRAMState;
 
 void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len);
-#endif /* PPC_MAC_H */
+#endif /* !defined(__PPC_MAC_H__) */
index 7d25106..32e88b3 100644 (file)
@@ -380,7 +380,6 @@ static void ppc_core99_init(MachineState *machine)
         pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io());
         machine_arch = ARCH_MAC99;
     }
-    object_property_set_bool(OBJECT(pci_bus), true, "realized", &error_abort);
 
     machine->usb |= defaults_enabled() && !machine->usb_disabled;
 
index 4479487..a9bb1c2 100644 (file)
@@ -309,7 +309,7 @@ static void ppc_heathrow_init(MachineState *machine)
     dev = qdev_create(adb_bus, TYPE_ADB_MOUSE);
     qdev_init_nofail(dev);
 
-    if (machine_usb(machine)) {
+    if (usb_enabled()) {
         pci_create_simple(pci_bus, -1, "pci-ohci");
     }
 
index 8945869..38ff2e1 100644 (file)
@@ -33,7 +33,6 @@
 #include "hw/timer/m48t59.h"
 #include "qemu/log.h"
 #include "qemu/error-report.h"
-#include "qapi/error.h"
 #include "hw/loader.h"
 #include "sysemu/kvm.h"
 #include "kvm_ppc.h"
@@ -165,9 +164,9 @@ static void ppc6xx_set_irq(void *opaque, int pin, int level)
     }
 }
 
-void ppc6xx_irq_init(PowerPCCPU *cpu)
+void ppc6xx_irq_init(CPUPPCState *env)
 {
-    CPUPPCState *env = &cpu->env;
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
 
     env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, cpu,
                                                   PPC6xx_INPUT_NB);
@@ -252,9 +251,9 @@ static void ppc970_set_irq(void *opaque, int pin, int level)
     }
 }
 
-void ppc970_irq_init(PowerPCCPU *cpu)
+void ppc970_irq_init(CPUPPCState *env)
 {
-    CPUPPCState *env = &cpu->env;
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
 
     env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, cpu,
                                                   PPC970_INPUT_NB);
@@ -288,9 +287,9 @@ static void power7_set_irq(void *opaque, int pin, int level)
     }
 }
 
-void ppcPOWER7_irq_init(PowerPCCPU *cpu)
+void ppcPOWER7_irq_init(CPUPPCState *env)
 {
-    CPUPPCState *env = &cpu->env;
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
 
     env->irq_inputs = (void **)qemu_allocate_irqs(&power7_set_irq, cpu,
                                                   POWER7_INPUT_NB);
@@ -373,9 +372,9 @@ static void ppc40x_set_irq(void *opaque, int pin, int level)
     }
 }
 
-void ppc40x_irq_init(PowerPCCPU *cpu)
+void ppc40x_irq_init(CPUPPCState *env)
 {
-    CPUPPCState *env = &cpu->env;
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
 
     env->irq_inputs = (void **)qemu_allocate_irqs(&ppc40x_set_irq,
                                                   cpu, PPC40x_INPUT_NB);
@@ -437,9 +436,9 @@ static void ppce500_set_irq(void *opaque, int pin, int level)
     }
 }
 
-void ppce500_irq_init(PowerPCCPU *cpu)
+void ppce500_irq_init(CPUPPCState *env)
 {
-    CPUPPCState *env = &cpu->env;
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
 
     env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq,
                                                   cpu, PPCE500_INPUT_NB);
@@ -700,18 +699,9 @@ static inline void cpu_ppc_decr_lower(PowerPCCPU *cpu)
 
 static inline void cpu_ppc_hdecr_excp(PowerPCCPU *cpu)
 {
-    CPUPPCState *env = &cpu->env;
-
     /* Raise it */
-    LOG_TB("raise hv decrementer exception\n");
-
-    /* The architecture specifies that we don't deliver HDEC
-     * interrupts in a PM state. Not only they don't cause a
-     * wakeup but they also get effectively discarded.
-     */
-    if (!env->in_pm_state) {
-        ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 1);
-    }
+    LOG_TB("raise decrementer exception\n");
+    ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 1);
 }
 
 static inline void cpu_ppc_hdecr_lower(PowerPCCPU *cpu)
@@ -890,7 +880,7 @@ static int timebase_post_load(void *opaque, int version_id)
     host_ns = qemu_clock_get_ns(QEMU_CLOCK_HOST);
     ns_diff = MAX(0, host_ns - tb_remote->time_of_the_day_ns);
     migration_duration_ns = MIN(NANOSECONDS_PER_SECOND, ns_diff);
-    migration_duration_tb = muldiv64(freq, migration_duration_ns,
+    migration_duration_tb = muldiv64(migration_duration_ns, freq,
                                      NANOSECONDS_PER_SECOND);
     guest_tb = tb_remote->guest_timebase + MIN(0, migration_duration_tb);
 
@@ -938,7 +928,9 @@ clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq)
     }
     /* Create new timer */
     tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_decr_cb, cpu);
-    if (env->has_hv_mode) {
+    if (0) {
+        /* XXX: find a suitable condition to enable the hypervisor decrementer
+         */
         tb_env->hdecr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_hdecr_cb,
                                                 cpu);
     } else {
@@ -1351,28 +1343,3 @@ PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id)
 
     return NULL;
 }
-
-void ppc_cpu_parse_features(const char *cpu_model)
-{
-    CPUClass *cc;
-    ObjectClass *oc;
-    const char *typename;
-    gchar **model_pieces;
-
-    model_pieces = g_strsplit(cpu_model, ",", 2);
-    if (!model_pieces[0]) {
-        error_report("Invalid/empty CPU model name");
-        exit(1);
-    }
-
-    oc = cpu_class_by_name(TYPE_POWERPC_CPU, model_pieces[0]);
-    if (oc == NULL) {
-        error_report("Unable to find CPU definition: %s", model_pieces[0]);
-        exit(1);
-    }
-
-    typename = object_class_get_name(oc);
-    cc = CPU_CLASS(oc);
-    cc->parse_features(typename, model_pieces[1], &error_fatal);
-    g_strfreev(model_pieces);
-}
index c67febc..1c5f04f 100644 (file)
@@ -22,8 +22,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef PPC405_H
-#define PPC405_H
+#if !defined(PPC_405_H)
+#define PPC_405_H
 
 #include "hw/ppc/ppc4xx.h"
 
@@ -78,4 +78,4 @@ CPUPPCState *ppc_stb025_init (MemoryRegion ram_memories[2],
                            uint32_t sysclk, qemu_irq **picp,
                            ram_addr_t *offsetp);
 
-#endif /* PPC405_H */
+#endif /* !defined(PPC_405_H) */
index e7f413e..7d59018 100644 (file)
@@ -22,7 +22,6 @@
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "cpu.h"
 #include "hw/hw.h"
 #include "hw/ppc/ppc.h"
 #include "hw/ppc/ppc4xx.h"
index 22c584e..76bd78b 100644 (file)
@@ -32,7 +32,6 @@
 #include "sysemu/sysemu.h"
 #include "hw/sysbus.h"
 #include "sysemu/kvm.h"
-#include "e500.h"
 
 #define MAX_CPUS 32
 
@@ -73,6 +72,12 @@ static void spin_reset(void *opaque)
     }
 }
 
+/* Create -kernel TLB entries for BookE, linearly spanning 256MB.  */
+static inline hwaddr booke206_page_size_to_tlb(uint64_t size)
+{
+    return ctz32(size >> 10) >> 1;
+}
+
 static void mmubooke_create_initial_mapping(CPUPPCState *env,
                                      target_ulong va,
                                      hwaddr pa,
@@ -99,7 +104,7 @@ static void spin_kick(void *data)
     hwaddr map_start;
 
     cpu_synchronize_state(cpu);
-    stl_p(&curspin->pir, env->spr[SPR_BOOKE_PIR]);
+    stl_p(&curspin->pir, env->spr[SPR_PIR]);
     env->nip = ldq_p(&curspin->addr) & (map_size - 1);
     env->gpr[3] = ldq_p(&curspin->r3);
     env->gpr[4] = 0;
index 054af1e..3ffb85e 100644 (file)
@@ -22,7 +22,6 @@
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "cpu.h"
 #include "hw/hw.h"
 #include "hw/timer/m48t59.h"
 #include "hw/i386/pc.h"
@@ -649,7 +648,7 @@ static void ppc_prep_init(MachineState *machine)
     memory_region_add_subregion(sysmem, 0xFEFF0000, xcsr);
 #endif
 
-    if (machine_usb(machine)) {
+    if (usb_enabled()) {
         pci_create_simple(pci_bus, -1, "pci-ohci");
     }
 
index 30d6800..b69995e 100644 (file)
@@ -29,7 +29,6 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/numa.h"
 #include "hw/hw.h"
-#include "qemu/log.h"
 #include "hw/fw-path-provider.h"
 #include "elf.h"
 #include "net/net.h"
@@ -66,8 +65,6 @@
 
 #include "hw/compat.h"
 #include "qemu/cutils.h"
-#include "hw/ppc/spapr_cpu_core.h"
-#include "qmp-commands.h"
 
 #include <libfdt.h>
 
@@ -91,6 +88,8 @@
 
 #define MIN_RMA_SLOF            128UL
 
+#define TIMEBASE_FREQ           512000000ULL
+
 #define PHANDLE_XICP            0x00001111
 
 #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
@@ -116,16 +115,15 @@ static XICSState *try_create_xics(const char *type, int nr_servers,
 static XICSState *xics_system_init(MachineState *machine,
                                    int nr_servers, int nr_irqs, Error **errp)
 {
-    XICSState *xics = NULL;
+    XICSState *icp = NULL;
 
     if (kvm_enabled()) {
         Error *err = NULL;
 
         if (machine_kernel_irqchip_allowed(machine)) {
-            xics = try_create_xics(TYPE_XICS_SPAPR_KVM, nr_servers, nr_irqs,
-                                   &err);
+            icp = try_create_xics(TYPE_KVM_XICS, nr_servers, nr_irqs, &err);
         }
-        if (machine_kernel_irqchip_required(machine) && !xics) {
+        if (machine_kernel_irqchip_required(machine) && !icp) {
             error_reportf_err(err,
                               "kernel_irqchip requested but unavailable: ");
         } else {
@@ -133,11 +131,11 @@ static XICSState *xics_system_init(MachineState *machine,
         }
     }
 
-    if (!xics) {
-        xics = try_create_xics(TYPE_XICS_SPAPR, nr_servers, nr_irqs, errp);
+    if (!icp) {
+        icp = try_create_xics(TYPE_XICS, nr_servers, nr_irqs, errp);
     }
 
-    return xics;
+    return icp;
 }
 
 static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu,
@@ -340,9 +338,6 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
     add_str(hypertas, "hcall-splpar");
     add_str(hypertas, "hcall-bulk");
     add_str(hypertas, "hcall-set-mode");
-    add_str(hypertas, "hcall-sprg0");
-    add_str(hypertas, "hcall-copy");
-    add_str(hypertas, "hcall-debug");
     add_str(qemu_hypertas, "hcall-memop1");
 
     fdt = g_malloc0(FDT_MAX_SIZE);
@@ -603,23 +598,12 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
     int index = ppc_get_vcpu_dt_id(cpu);
     uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
                        0xffffffff, 0xffffffff};
-    uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq()
-        : SPAPR_TIMEBASE_FREQ;
+    uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ;
     uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
     uint32_t page_sizes_prop[64];
     size_t page_sizes_prop_size;
     uint32_t vcpus_per_socket = smp_threads * smp_cores;
     uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
-    sPAPRDRConnector *drc;
-    sPAPRDRConnectorClass *drck;
-    int drc_index;
-
-    drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index);
-    if (drc) {
-        drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
-        drc_index = drck->get_index(drc);
-        _FDT((fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index)));
-    }
 
     /* Note: we keep CI large pages off for now because a 64K capable guest
      * provisioned with large pages might otherwise try to map a qemu
@@ -777,17 +761,14 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt)
     int ret, i, offset;
     uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE;
     uint32_t prop_lmb_size[] = {0, cpu_to_be32(lmb_size)};
-    uint32_t hotplug_lmb_start = spapr->hotplug_memory.base / lmb_size;
-    uint32_t nr_lmbs = (spapr->hotplug_memory.base +
-                       memory_region_size(&spapr->hotplug_memory.mr)) /
-                       lmb_size;
+    uint32_t nr_lmbs = (machine->maxram_size - machine->ram_size)/lmb_size;
     uint32_t *int_buf, *cur_index, buf_len;
     int nr_nodes = nb_numa_nodes ? nb_numa_nodes : 1;
 
     /*
-     * Don't create the node if there is no hotpluggable memory
+     * Don't create the node if there are no DR LMBs.
      */
-    if (machine->ram_size == machine->maxram_size) {
+    if (!nr_lmbs) {
         return 0;
     }
 
@@ -821,40 +802,26 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt)
     int_buf[0] = cpu_to_be32(nr_lmbs);
     cur_index++;
     for (i = 0; i < nr_lmbs; i++) {
-        uint64_t addr = i * lmb_size;
+        sPAPRDRConnector *drc;
+        sPAPRDRConnectorClass *drck;
+        uint64_t addr = i * lmb_size + spapr->hotplug_memory.base;;
         uint32_t *dynamic_memory = cur_index;
 
-        if (i >= hotplug_lmb_start) {
-            sPAPRDRConnector *drc;
-            sPAPRDRConnectorClass *drck;
-
-            drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB, i);
-            g_assert(drc);
-            drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
-
-            dynamic_memory[0] = cpu_to_be32(addr >> 32);
-            dynamic_memory[1] = cpu_to_be32(addr & 0xffffffff);
-            dynamic_memory[2] = cpu_to_be32(drck->get_index(drc));
-            dynamic_memory[3] = cpu_to_be32(0); /* reserved */
-            dynamic_memory[4] = cpu_to_be32(numa_get_node(addr, NULL));
-            if (memory_region_present(get_system_memory(), addr)) {
-                dynamic_memory[5] = cpu_to_be32(SPAPR_LMB_FLAGS_ASSIGNED);
-            } else {
-                dynamic_memory[5] = cpu_to_be32(0);
-            }
+        drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB,
+                                       addr/lmb_size);
+        g_assert(drc);
+        drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+
+        dynamic_memory[0] = cpu_to_be32(addr >> 32);
+        dynamic_memory[1] = cpu_to_be32(addr & 0xffffffff);
+        dynamic_memory[2] = cpu_to_be32(drck->get_index(drc));
+        dynamic_memory[3] = cpu_to_be32(0); /* reserved */
+        dynamic_memory[4] = cpu_to_be32(numa_get_node(addr, NULL));
+        if (addr < machine->ram_size ||
+                    memory_region_present(get_system_memory(), addr)) {
+            dynamic_memory[5] = cpu_to_be32(SPAPR_LMB_FLAGS_ASSIGNED);
         } else {
-            /*
-             * LMB information for RMA, boot time RAM and gap b/n RAM and
-             * hotplug memory region -- all these are marked as reserved
-             * and as having no valid DRC.
-             */
-            dynamic_memory[0] = cpu_to_be32(addr >> 32);
-            dynamic_memory[1] = cpu_to_be32(addr & 0xffffffff);
-            dynamic_memory[2] = cpu_to_be32(0);
-            dynamic_memory[3] = cpu_to_be32(0); /* reserved */
-            dynamic_memory[4] = cpu_to_be32(-1);
-            dynamic_memory[5] = cpu_to_be32(SPAPR_LMB_FLAGS_RESERVED |
-                                            SPAPR_LMB_FLAGS_DRC_INVALID);
+            dynamic_memory[5] = cpu_to_be32(0);
         }
 
         cur_index += SPAPR_DR_LMB_LIST_ENTRY_SIZE;
@@ -938,7 +905,6 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr,
                                hwaddr rtas_size)
 {
     MachineState *machine = MACHINE(qdev_get_machine());
-    MachineClass *mc = MACHINE_GET_CLASS(machine);
     sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
     const char *boot_device = machine->boot_order;
     int ret, i;
@@ -1021,16 +987,6 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr,
         _FDT(spapr_drc_populate_dt(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_LMB));
     }
 
-    if (mc->query_hotpluggable_cpus) {
-        int offset = fdt_path_offset(fdt, "/cpus");
-        ret = spapr_drc_populate_dt(fdt, offset, NULL,
-                                    SPAPR_DR_CONNECTOR_TYPE_CPU);
-        if (ret < 0) {
-            error_report("Couldn't set up CPU DR device tree properties");
-            exit(1);
-        }
-    }
-
     _FDT((fdt_pack(fdt)));
 
     if (fdt_totalsize(fdt) > FDT_MAX_SIZE) {
@@ -1224,6 +1180,26 @@ static void ppc_spapr_reset(void)
 
 }
 
+static void spapr_cpu_reset(void *opaque)
+{
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+    PowerPCCPU *cpu = opaque;
+    CPUState *cs = CPU(cpu);
+    CPUPPCState *env = &cpu->env;
+
+    cpu_reset(cs);
+
+    /* All CPUs start halted.  CPU0 is unhalted from the machine level
+     * reset code and the rest are explicitly started up by the guest
+     * using an RTAS call */
+    cs->halted = 1;
+
+    env->spr[SPR_HIOR] = 0;
+
+    ppc_hash64_set_external_hpt(cpu, spapr->htab, spapr->htab_shift,
+                                &error_fatal);
+}
+
 static void spapr_create_nvram(sPAPRMachineState *spapr)
 {
     DeviceState *dev = qdev_create(&spapr->vio_bus->bus, "spapr-nvram");
@@ -1513,6 +1489,7 @@ static int htab_save_complete(QEMUFile *f, void *opaque)
         if (rc < 0) {
             return rc;
         }
+        close_htab_fd(spapr);
     } else {
         if (spapr->htab_first_pass) {
             htab_save_first_pass(f, spapr, -1);
@@ -1614,18 +1591,10 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void htab_cleanup(void *opaque)
-{
-    sPAPRMachineState *spapr = opaque;
-
-    close_htab_fd(spapr);
-}
-
 static SaveVMHandlers savevm_htab_handlers = {
     .save_live_setup = htab_save_setup,
     .save_live_iterate = htab_save_iterate,
     .save_live_complete_precopy = htab_save_complete,
-    .cleanup = htab_cleanup,
     .load_state = htab_load,
 };
 
@@ -1636,6 +1605,32 @@ static void spapr_boot_set(void *opaque, const char *boot_device,
     machine->boot_order = g_strdup(boot_device);
 }
 
+static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
+                           Error **errp)
+{
+    CPUPPCState *env = &cpu->env;
+
+    /* Set time-base frequency to 512 MHz */
+    cpu_ppc_tb_init(env, TIMEBASE_FREQ);
+
+    /* Enable PAPR mode in TCG or KVM */
+    cpu_ppc_set_papr(cpu);
+
+    if (cpu->max_compat) {
+        Error *local_err = NULL;
+
+        ppc_set_compat(cpu, cpu->max_compat, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
+    }
+
+    xics_cpu_setup(spapr->icp, cpu);
+
+    qemu_register_reset(spapr_cpu_reset, cpu);
+}
+
 /*
  * Reset routine for LMB DR devices.
  *
@@ -1713,11 +1708,11 @@ static void spapr_validate_node_memory(MachineState *machine, Error **errp)
 static void ppc_spapr_init(MachineState *machine)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
-    MachineClass *mc = MACHINE_GET_CLASS(machine);
     sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
+    PowerPCCPU *cpu;
     PCIHostState *phb;
     int i;
     MemoryRegion *sysmem = get_system_memory();
@@ -1731,22 +1726,6 @@ static void ppc_spapr_init(MachineState *machine)
     long load_limit, fw_size;
     bool kernel_le = false;
     char *filename;
-    int smt = kvmppc_smt_threads();
-    int spapr_cores = smp_cpus / smp_threads;
-    int spapr_max_cores = max_cpus / smp_threads;
-
-    if (mc->query_hotpluggable_cpus) {
-        if (smp_cpus % smp_threads) {
-            error_report("smp_cpus (%u) must be multiple of threads (%u)",
-                         smp_cpus, smp_threads);
-            exit(1);
-        }
-        if (max_cpus % smp_threads) {
-            error_report("max_cpus (%u) must be multiple of threads (%u)",
-                         max_cpus, smp_threads);
-            exit(1);
-        }
-    }
 
     msi_nonbroken = true;
 
@@ -1780,13 +1759,6 @@ static void ppc_spapr_init(MachineState *machine)
             spapr->vrma_adjust = 1;
             spapr->rma_size = MIN(spapr->rma_size, 0x10000000);
         }
-
-        /* Actually we don't support unbounded RMA anymore since we
-         * added proper emulation of HV mode. The max we can get is
-         * 16G which also happens to be what we configure for PAPR
-         * mode so make sure we don't do anything bigger than that
-         */
-        spapr->rma_size = MIN(spapr->rma_size, 0x400000000ull);
     }
 
     if (spapr->rma_size > node0_size) {
@@ -1799,9 +1771,10 @@ static void ppc_spapr_init(MachineState *machine)
     load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD;
 
     /* Set up Interrupt Controller before we create the VCPUs */
-    spapr->xics = xics_system_init(machine,
-                                   DIV_ROUND_UP(max_cpus * smt, smp_threads),
-                                   XICS_IRQS_SPAPR, &error_fatal);
+    spapr->icp = xics_system_init(machine,
+                                  DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(),
+                                               smp_threads),
+                                  XICS_IRQS, &error_fatal);
 
     if (smc->dr_lmb_enabled) {
         spapr_validate_node_memory(machine, &error_fatal);
@@ -1811,46 +1784,13 @@ static void ppc_spapr_init(MachineState *machine)
     if (machine->cpu_model == NULL) {
         machine->cpu_model = kvm_enabled() ? "host" : "POWER7";
     }
-
-    ppc_cpu_parse_features(machine->cpu_model);
-
-    if (mc->query_hotpluggable_cpus) {
-        char *type = spapr_get_cpu_core_type(machine->cpu_model);
-
-        if (type == NULL) {
-            error_report("Unable to find sPAPR CPU Core definition");
+    for (i = 0; i < smp_cpus; i++) {
+        cpu = cpu_ppc_init(machine->cpu_model);
+        if (cpu == NULL) {
+            error_report("Unable to find PowerPC CPU definition");
             exit(1);
         }
-
-        spapr->cores = g_new0(Object *, spapr_max_cores);
-        for (i = 0; i < spapr_max_cores; i++) {
-            int core_id = i * smp_threads;
-            sPAPRDRConnector *drc =
-                spapr_dr_connector_new(OBJECT(spapr),
-                                       SPAPR_DR_CONNECTOR_TYPE_CPU,
-                                       (core_id / smp_threads) * smt);
-
-            qemu_register_reset(spapr_drc_reset, drc);
-
-            if (i < spapr_cores) {
-                Object *core  = object_new(type);
-                object_property_set_int(core, smp_threads, "nr-threads",
-                                        &error_fatal);
-                object_property_set_int(core, core_id, CPU_CORE_PROP_CORE_ID,
-                                        &error_fatal);
-                object_property_set_bool(core, true, "realized", &error_fatal);
-            }
-        }
-        g_free(type);
-    } else {
-        for (i = 0; i < smp_cpus; i++) {
-            PowerPCCPU *cpu = cpu_ppc_init(machine->cpu_model);
-            if (cpu == NULL) {
-                error_report("Unable to find PowerPC CPU definition");
-                exit(1);
-            }
-            spapr_cpu_init(spapr, cpu, &error_fatal);
-       }
+        spapr_cpu_init(spapr, cpu, &error_fatal);
     }
 
     if (kvm_enabled()) {
@@ -1875,21 +1815,11 @@ static void ppc_spapr_init(MachineState *machine)
     /* initialize hotplug memory address space */
     if (machine->ram_size < machine->maxram_size) {
         ram_addr_t hotplug_mem_size = machine->maxram_size - machine->ram_size;
-        /*
-         * Limit the number of hotpluggable memory slots to half the number
-         * slots that KVM supports, leaving the other half for PCI and other
-         * devices. However ensure that number of slots doesn't drop below 32.
-         */
-        int max_memslots = kvm_enabled() ? kvm_get_max_memslots() / 2 :
-                           SPAPR_MAX_RAM_SLOTS;
 
-        if (max_memslots < SPAPR_MAX_RAM_SLOTS) {
-            max_memslots = SPAPR_MAX_RAM_SLOTS;
-        }
-        if (machine->ram_slots > max_memslots) {
+        if (machine->ram_slots > SPAPR_MAX_RAM_SLOTS) {
             error_report("Specified number of memory slots %"
                          PRIu64" exceeds max supported %d",
-                         machine->ram_slots, max_memslots);
+                         machine->ram_slots, SPAPR_MAX_RAM_SLOTS);
             exit(1);
         }
 
@@ -1911,10 +1841,6 @@ static void ppc_spapr_init(MachineState *machine)
         exit(1);
     }
     spapr->rtas_size = get_image_size(filename);
-    if (spapr->rtas_size < 0) {
-        error_report("Could not get size of LPAR rtas '%s'", filename);
-        exit(1);
-    }
     spapr->rtas_blob = g_malloc(spapr->rtas_size);
     if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {
         error_report("Could not load LPAR rtas '%s'", filename);
@@ -2205,6 +2131,15 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr, uint64_t size,
     int i, fdt_offset, fdt_size;
     void *fdt;
 
+    /*
+     * Check for DRC connectors and send hotplug notification to the
+     * guest only in case of hotplugged memory. This allows cold plugged
+     * memory to be specified at boot time.
+     */
+    if (!dev->hotplugged) {
+        return;
+    }
+
     for (i = 0; i < nr_lmbs; i++) {
         drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB,
                 addr/SPAPR_MEMORY_BLOCK_SIZE);
@@ -2218,12 +2153,7 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr, uint64_t size,
         drck->attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, errp);
         addr += SPAPR_MEMORY_BLOCK_SIZE;
     }
-    /* send hotplug notification to the
-     * guest only in case of hotplugged memory
-     */
-    if (dev->hotplugged) {
-       spapr_hotplug_req_add_by_count(SPAPR_DR_CONNECTOR_TYPE_LMB, nr_lmbs);
-    }
+    spapr_hotplug_req_add_by_count(SPAPR_DR_CONNECTOR_TYPE_LMB, nr_lmbs);
 }
 
 static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
@@ -2261,27 +2191,6 @@ out:
     error_propagate(errp, local_err);
 }
 
-void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset,
-                                    sPAPRMachineState *spapr)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-    DeviceClass *dc = DEVICE_GET_CLASS(cs);
-    int id = ppc_get_vcpu_dt_id(cpu);
-    void *fdt;
-    int offset, fdt_size;
-    char *nodename;
-
-    fdt = create_device_tree(&fdt_size);
-    nodename = g_strdup_printf("%s@%x", dc->fw_name, id);
-    offset = fdt_add_subnode(fdt, 0, nodename);
-
-    spapr_populate_cpu_dt(cs, fdt, offset, spapr);
-    g_free(nodename);
-
-    *fdt_offset = offset;
-    return fdt;
-}
-
 static void spapr_machine_device_plug(HotplugHandler *hotplug_dev,
                                       DeviceState *dev, Error **errp)
 {
@@ -2326,40 +2235,21 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev,
         }
 
         spapr_memory_plug(hotplug_dev, dev, node, errp);
-    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
-        spapr_core_plug(hotplug_dev, dev, errp);
     }
 }
 
 static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev,
                                       DeviceState *dev, Error **errp)
 {
-    MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
-
     if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
         error_setg(errp, "Memory hot unplug not supported by sPAPR");
-    } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
-        if (!mc->query_hotpluggable_cpus) {
-            error_setg(errp, "CPU hot unplug not supported on this machine");
-            return;
-        }
-        spapr_core_unplug(hotplug_dev, dev, errp);
-    }
-}
-
-static void spapr_machine_device_pre_plug(HotplugHandler *hotplug_dev,
-                                          DeviceState *dev, Error **errp)
-{
-    if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
-        spapr_core_pre_plug(hotplug_dev, dev, errp);
     }
 }
 
 static HotplugHandler *spapr_get_hotpug_handler(MachineState *machine,
                                              DeviceState *dev)
 {
-    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
-        object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
+    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
         return HOTPLUG_HANDLER(machine);
     }
     return NULL;
@@ -2372,37 +2262,6 @@ static unsigned spapr_cpu_index_to_socket_id(unsigned cpu_index)
     return cpu_index / smp_threads / smp_cores;
 }
 
-static HotpluggableCPUList *spapr_query_hotpluggable_cpus(MachineState *machine)
-{
-    int i;
-    HotpluggableCPUList *head = NULL;
-    sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
-    int spapr_max_cores = max_cpus / smp_threads;
-
-    for (i = 0; i < spapr_max_cores; i++) {
-        HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1);
-        HotpluggableCPU *cpu_item = g_new0(typeof(*cpu_item), 1);
-        CpuInstanceProperties *cpu_props = g_new0(typeof(*cpu_props), 1);
-
-        cpu_item->type = spapr_get_cpu_core_type(machine->cpu_model);
-        cpu_item->vcpus_count = smp_threads;
-        cpu_props->has_core_id = true;
-        cpu_props->core_id = i * smp_threads;
-        /* TODO: add 'has_node/node' here to describe
-           to which node core belongs */
-
-        cpu_item->props = cpu_props;
-        if (spapr->cores[i]) {
-            cpu_item->has_qom_path = true;
-            cpu_item->qom_path = object_get_canonical_path(spapr->cores[i]);
-        }
-        list_item->value = cpu_item;
-        list_item->next = head;
-        head = list_item;
-    }
-    return head;
-}
-
 static void spapr_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
@@ -2429,13 +2288,11 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     mc->has_dynamic_sysbus = true;
     mc->pci_allow_0_address = true;
     mc->get_hotplug_handler = spapr_get_hotpug_handler;
-    hc->pre_plug = spapr_machine_device_pre_plug;
     hc->plug = spapr_machine_device_plug;
     hc->unplug = spapr_machine_device_unplug;
     mc->cpu_index_to_socket_id = spapr_cpu_index_to_socket_id;
 
     smc->dr_lmb_enabled = true;
-    mc->query_hotpluggable_cpus = spapr_query_hotpluggable_cpus;
     fwc->get_dev_path = spapr_get_fw_dev_path;
     nc->nmi_monitor_handler = spapr_nmi;
 }
@@ -2486,42 +2343,18 @@ static const TypeInfo spapr_machine_info = {
     type_init(spapr_machine_register_##suffix)
 
 /*
- * pseries-2.7
- */
-static void spapr_machine_2_7_instance_options(MachineState *machine)
-{
-}
-
-static void spapr_machine_2_7_class_options(MachineClass *mc)
-{
-    /* Defaults for the latest behaviour inherited from the base class */
-}
-
-DEFINE_SPAPR_MACHINE(2_7, "2.7", true);
-
-/*
  * pseries-2.6
  */
-#define SPAPR_COMPAT_2_6 \
-    HW_COMPAT_2_6 \
-    { \
-        .driver   = TYPE_SPAPR_PCI_HOST_BRIDGE,\
-        .property = "ddw",\
-        .value    = stringify(off),\
-    },
-
 static void spapr_machine_2_6_instance_options(MachineState *machine)
 {
 }
 
 static void spapr_machine_2_6_class_options(MachineClass *mc)
 {
-    spapr_machine_2_7_class_options(mc);
-    mc->query_hotpluggable_cpus = NULL;
-    SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_6);
+    /* Defaults for the latest behaviour inherited from the base class */
 }
 
-DEFINE_SPAPR_MACHINE(2_6, "2.6", false);
+DEFINE_SPAPR_MACHINE(2_6, "2.6", true);
 
 /*
  * pseries-2.5
@@ -2553,6 +2386,7 @@ DEFINE_SPAPR_MACHINE(2_5, "2.5", false);
  * pseries-2.4
  */
 #define SPAPR_COMPAT_2_4 \
+        SPAPR_COMPAT_2_5 \
         HW_COMPAT_2_4
 
 static void spapr_machine_2_4_instance_options(MachineState *machine)
@@ -2575,6 +2409,7 @@ DEFINE_SPAPR_MACHINE(2_4, "2.4", false);
  * pseries-2.3
  */
 #define SPAPR_COMPAT_2_3 \
+        SPAPR_COMPAT_2_4 \
         HW_COMPAT_2_3 \
         {\
             .driver   = "spapr-pci-host-bridge",\
@@ -2602,6 +2437,7 @@ DEFINE_SPAPR_MACHINE(2_3, "2.3", false);
  */
 
 #define SPAPR_COMPAT_2_2 \
+        SPAPR_COMPAT_2_3 \
         HW_COMPAT_2_2 \
         {\
             .driver   = TYPE_SPAPR_PCI_HOST_BRIDGE,\
@@ -2626,6 +2462,7 @@ DEFINE_SPAPR_MACHINE(2_2, "2.2", false);
  * pseries-2.1
  */
 #define SPAPR_COMPAT_2_1 \
+        SPAPR_COMPAT_2_2 \
         HW_COMPAT_2_1
 
 static void spapr_machine_2_1_instance_options(MachineState *machine)
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
deleted file mode 100644 (file)
index bcb483d..0000000
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * sPAPR CPU core device, acts as container of CPU thread devices.
- *
- * Copyright (C) 2016 Bharata B Rao <bharata@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#include "hw/cpu/core.h"
-#include "hw/ppc/spapr_cpu_core.h"
-#include "target-ppc/cpu.h"
-#include "hw/ppc/spapr.h"
-#include "hw/boards.h"
-#include "qapi/error.h"
-#include "sysemu/cpus.h"
-#include "target-ppc/kvm_ppc.h"
-#include "hw/ppc/ppc.h"
-#include "target-ppc/mmu-hash64.h"
-#include "sysemu/numa.h"
-
-static void spapr_cpu_reset(void *opaque)
-{
-    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
-    PowerPCCPU *cpu = opaque;
-    CPUState *cs = CPU(cpu);
-    CPUPPCState *env = &cpu->env;
-
-    cpu_reset(cs);
-
-    /* All CPUs start halted.  CPU0 is unhalted from the machine level
-     * reset code and the rest are explicitly started up by the guest
-     * using an RTAS call */
-    cs->halted = 1;
-
-    env->spr[SPR_HIOR] = 0;
-
-    ppc_hash64_set_external_hpt(cpu, spapr->htab, spapr->htab_shift,
-                                &error_fatal);
-}
-
-static void spapr_cpu_destroy(PowerPCCPU *cpu)
-{
-    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
-
-    xics_cpu_destroy(spapr->xics, cpu);
-    qemu_unregister_reset(spapr_cpu_reset, cpu);
-}
-
-void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu, Error **errp)
-{
-    CPUPPCState *env = &cpu->env;
-    CPUState *cs = CPU(cpu);
-    int i;
-
-    /* Set time-base frequency to 512 MHz */
-    cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
-
-    /* Enable PAPR mode in TCG or KVM */
-    cpu_ppc_set_papr(cpu);
-
-    if (cpu->max_compat) {
-        Error *local_err = NULL;
-
-        ppc_set_compat(cpu, cpu->max_compat, &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            return;
-        }
-    }
-
-    /* Set NUMA node for the added CPUs  */
-    for (i = 0; i < nb_numa_nodes; i++) {
-        if (test_bit(cs->cpu_index, numa_info[i].node_cpu)) {
-            cs->numa_node = i;
-            break;
-        }
-    }
-
-    xics_cpu_setup(spapr->xics, cpu);
-
-    qemu_register_reset(spapr_cpu_reset, cpu);
-    spapr_cpu_reset(cpu);
-}
-
-/*
- * Return the sPAPR CPU core type for @model which essentially is the CPU
- * model specified with -cpu cmdline option.
- */
-char *spapr_get_cpu_core_type(const char *model)
-{
-    char *core_type;
-    gchar **model_pieces = g_strsplit(model, ",", 2);
-
-    core_type = g_strdup_printf("%s-%s", model_pieces[0], TYPE_SPAPR_CPU_CORE);
-    g_strfreev(model_pieces);
-
-    /* Check whether it exists or whether we have to look up an alias name */
-    if (!object_class_by_name(core_type)) {
-        const char *realmodel;
-
-        g_free(core_type);
-        realmodel = ppc_cpu_lookup_alias(model);
-        if (realmodel) {
-            return spapr_get_cpu_core_type(realmodel);
-        }
-        return NULL;
-    }
-
-    return core_type;
-}
-
-static void spapr_core_release(DeviceState *dev, void *opaque)
-{
-    sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
-    const char *typename = object_class_get_name(sc->cpu_class);
-    size_t size = object_type_get_instance_size(typename);
-    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
-    CPUCore *cc = CPU_CORE(dev);
-    int i;
-
-    for (i = 0; i < cc->nr_threads; i++) {
-        void *obj = sc->threads + i * size;
-        DeviceState *dev = DEVICE(obj);
-        CPUState *cs = CPU(dev);
-        PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-        spapr_cpu_destroy(cpu);
-        cpu_remove_sync(cs);
-        object_unparent(obj);
-    }
-
-    spapr->cores[cc->core_id / smp_threads] = NULL;
-
-    g_free(sc->threads);
-    object_unparent(OBJECT(dev));
-}
-
-void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev,
-                       Error **errp)
-{
-    CPUCore *cc = CPU_CORE(dev);
-    int smt = kvmppc_smt_threads();
-    int index = cc->core_id / smp_threads;
-    sPAPRDRConnector *drc =
-        spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index * smt);
-    sPAPRDRConnectorClass *drck;
-    Error *local_err = NULL;
-
-    if (index == 0) {
-        error_setg(errp, "Boot CPU core may not be unplugged");
-        return;
-    }
-
-    g_assert(drc);
-
-    drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
-    drck->detach(drc, dev, spapr_core_release, NULL, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    spapr_hotplug_req_remove_by_index(drc);
-}
-
-void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
-                     Error **errp)
-{
-    sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
-    sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev));
-    CPUCore *cc = CPU_CORE(dev);
-    CPUState *cs = CPU(core->threads);
-    sPAPRDRConnector *drc;
-    sPAPRDRConnectorClass *drck;
-    Error *local_err = NULL;
-    void *fdt = NULL;
-    int fdt_offset = 0;
-    int index = cc->core_id / smp_threads;
-    int smt = kvmppc_smt_threads();
-
-    drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index * smt);
-    spapr->cores[index] = OBJECT(dev);
-
-    g_assert(drc);
-
-    /*
-     * Setup CPU DT entries only for hotplugged CPUs. For boot time or
-     * coldplugged CPUs DT entries are setup in spapr_finalize_fdt().
-     */
-    if (dev->hotplugged) {
-        fdt = spapr_populate_hotplug_cpu_dt(cs, &fdt_offset, spapr);
-    }
-
-    drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
-    drck->attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, &local_err);
-    if (local_err) {
-        g_free(fdt);
-        spapr->cores[index] = NULL;
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    if (dev->hotplugged) {
-        /*
-         * Send hotplug notification interrupt to the guest only in case
-         * of hotplugged CPUs.
-         */
-        spapr_hotplug_req_add_by_index(drc);
-    } else {
-        /*
-         * Set the right DRC states for cold plugged CPU.
-         */
-        drck->set_allocation_state(drc, SPAPR_DR_ALLOCATION_STATE_USABLE);
-        drck->set_isolation_state(drc, SPAPR_DR_ISOLATION_STATE_UNISOLATED);
-    }
-}
-
-void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
-                         Error **errp)
-{
-    MachineState *machine = MACHINE(OBJECT(hotplug_dev));
-    MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
-    sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
-    int spapr_max_cores = max_cpus / smp_threads;
-    int index;
-    Error *local_err = NULL;
-    CPUCore *cc = CPU_CORE(dev);
-    char *base_core_type = spapr_get_cpu_core_type(machine->cpu_model);
-    const char *type = object_get_typename(OBJECT(dev));
-
-    if (!mc->query_hotpluggable_cpus) {
-        error_setg(&local_err, "CPU hotplug not supported for this machine");
-        goto out;
-    }
-
-    if (strcmp(base_core_type, type)) {
-        error_setg(&local_err, "CPU core type should be %s", base_core_type);
-        goto out;
-    }
-
-    if (cc->nr_threads != smp_threads) {
-        error_setg(&local_err, "threads must be %d", smp_threads);
-        goto out;
-    }
-
-    if (cc->core_id % smp_threads) {
-        error_setg(&local_err, "invalid core id %d", cc->core_id);
-        goto out;
-    }
-
-    index = cc->core_id / smp_threads;
-    if (index < 0 || index >= spapr_max_cores) {
-        error_setg(&local_err, "core id %d out of range", cc->core_id);
-        goto out;
-    }
-
-    if (spapr->cores[index]) {
-        error_setg(&local_err, "core %d already populated", cc->core_id);
-        goto out;
-    }
-
-out:
-    g_free(base_core_type);
-    error_propagate(errp, local_err);
-}
-
-static void spapr_cpu_core_realize_child(Object *child, Error **errp)
-{
-    Error *local_err = NULL;
-    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
-    CPUState *cs = CPU(child);
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-    object_property_set_bool(child, true, "realized", &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    spapr_cpu_init(spapr, cpu, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-}
-
-static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
-{
-    sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
-    CPUCore *cc = CPU_CORE(OBJECT(dev));
-    const char *typename = object_class_get_name(sc->cpu_class);
-    size_t size = object_type_get_instance_size(typename);
-    Error *local_err = NULL;
-    void *obj;
-    int i, j;
-
-    sc->threads = g_malloc0(size * cc->nr_threads);
-    for (i = 0; i < cc->nr_threads; i++) {
-        char id[32];
-        CPUState *cs;
-
-        obj = sc->threads + i * size;
-
-        object_initialize(obj, size, typename);
-        cs = CPU(obj);
-        cs->cpu_index = cc->core_id + i;
-        snprintf(id, sizeof(id), "thread[%d]", i);
-        object_property_add_child(OBJECT(sc), id, obj, &local_err);
-        if (local_err) {
-            goto err;
-        }
-        object_unref(obj);
-    }
-
-    for (j = 0; j < cc->nr_threads; j++) {
-        obj = sc->threads + j * size;
-
-        spapr_cpu_core_realize_child(obj, &local_err);
-        if (local_err) {
-            goto err;
-        }
-    }
-    return;
-
-err:
-    while (--i >= 0) {
-        obj = sc->threads + i * size;
-        object_unparent(obj);
-    }
-    g_free(sc->threads);
-    error_propagate(errp, local_err);
-}
-
-static void spapr_cpu_core_class_init(ObjectClass *oc, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(oc);
-    dc->realize = spapr_cpu_core_realize;
-}
-
-/*
- * instance_init routines from different flavours of sPAPR CPU cores.
- */
-#define SPAPR_CPU_CORE_INITFN(_type, _fname) \
-static void glue(glue(spapr_cpu_core_, _fname), _initfn(Object *obj)) \
-{ \
-    sPAPRCPUCore *core = SPAPR_CPU_CORE(obj); \
-    char *name = g_strdup_printf("%s-" TYPE_POWERPC_CPU, stringify(_type)); \
-    ObjectClass *oc = object_class_by_name(name); \
-    g_assert(oc); \
-    g_free((void *)name); \
-    core->cpu_class = oc; \
-}
-
-SPAPR_CPU_CORE_INITFN(970mp_v1.0, 970MP_v10);
-SPAPR_CPU_CORE_INITFN(970mp_v1.1, 970MP_v11);
-SPAPR_CPU_CORE_INITFN(970_v2.2, 970);
-SPAPR_CPU_CORE_INITFN(POWER5+_v2.1, POWER5plus);
-SPAPR_CPU_CORE_INITFN(POWER7_v2.3, POWER7);
-SPAPR_CPU_CORE_INITFN(POWER7+_v2.1, POWER7plus);
-SPAPR_CPU_CORE_INITFN(POWER8_v2.0, POWER8);
-SPAPR_CPU_CORE_INITFN(POWER8E_v2.1, POWER8E);
-SPAPR_CPU_CORE_INITFN(POWER8NVL_v1.0, POWER8NVL);
-
-typedef struct SPAPRCoreInfo {
-    const char *name;
-    void (*initfn)(Object *obj);
-} SPAPRCoreInfo;
-
-static const SPAPRCoreInfo spapr_cores[] = {
-    /* 970 */
-    { .name = "970_v2.2", .initfn = spapr_cpu_core_970_initfn },
-
-    /* 970MP variants */
-    { .name = "970MP_v1.0", .initfn = spapr_cpu_core_970MP_v10_initfn },
-    { .name = "970mp_v1.0", .initfn = spapr_cpu_core_970MP_v10_initfn },
-    { .name = "970MP_v1.1", .initfn = spapr_cpu_core_970MP_v11_initfn },
-    { .name = "970mp_v1.1", .initfn = spapr_cpu_core_970MP_v11_initfn },
-
-    /* POWER5+ */
-    { .name = "POWER5+_v2.1", .initfn = spapr_cpu_core_POWER5plus_initfn },
-
-    /* POWER7 */
-    { .name = "POWER7_v2.3", .initfn = spapr_cpu_core_POWER7_initfn },
-
-    /* POWER7+ */
-    { .name = "POWER7+_v2.1", .initfn = spapr_cpu_core_POWER7plus_initfn },
-
-    /* POWER8 */
-    { .name = "POWER8_v2.0", .initfn = spapr_cpu_core_POWER8_initfn },
-
-    /* POWER8E */
-    { .name = "POWER8E_v2.1", .initfn = spapr_cpu_core_POWER8E_initfn },
-
-    /* POWER8NVL */
-    { .name = "POWER8NVL_v1.0", .initfn = spapr_cpu_core_POWER8NVL_initfn },
-
-    { .name = NULL }
-};
-
-static void spapr_cpu_core_register(const SPAPRCoreInfo *info)
-{
-    TypeInfo type_info = {
-        .parent = TYPE_SPAPR_CPU_CORE,
-        .instance_size = sizeof(sPAPRCPUCore),
-        .instance_init = info->initfn,
-    };
-
-    type_info.name = g_strdup_printf("%s-" TYPE_SPAPR_CPU_CORE, info->name);
-    type_register(&type_info);
-    g_free((void *)type_info.name);
-}
-
-static const TypeInfo spapr_cpu_core_type_info = {
-    .name = TYPE_SPAPR_CPU_CORE,
-    .parent = TYPE_CPU_CORE,
-    .abstract = true,
-    .instance_size = sizeof(sPAPRCPUCore),
-    .class_init = spapr_cpu_core_class_init,
-};
-
-static void spapr_cpu_core_register_types(void)
-{
-    const SPAPRCoreInfo *info = spapr_cores;
-
-    type_register_static(&spapr_cpu_core_type_info);
-    while (info->name) {
-        spapr_cpu_core_register(info);
-        info++;
-    }
-}
-
-type_init(spapr_cpu_core_register_types)
index 26a0679..1f5f1d7 100644 (file)
@@ -140,8 +140,6 @@ static uint32_t set_allocation_state(sPAPRDRConnector *drc,
             DPRINTFN("finalizing device removal");
             drck->detach(drc, DEVICE(drc->dev), drc->detach_cb,
                          drc->detach_cb_opaque, NULL);
-        } else if (drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE) {
-            drc->awaiting_allocation = false;
         }
     }
     return RTAS_OUT_SUCCESS;
@@ -271,7 +269,11 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
     void *fdt;
 
     if (!drc->fdt) {
-        visit_type_null(v, NULL, errp);
+        visit_start_struct(v, name, NULL, 0, &err);
+        if (!err) {
+            visit_end_struct(v, &err);
+        }
+        error_propagate(errp, err);
         return;
     }
 
@@ -299,8 +301,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
         case FDT_END_NODE:
             /* shouldn't ever see an FDT_END_NODE before FDT_BEGIN_NODE */
             g_assert(fdt_depth > 0);
-            visit_check_struct(v, &err);
-            visit_end_struct(v, NULL);
+            visit_end_struct(v, &err);
             if (err) {
                 error_propagate(errp, err);
                 return;
@@ -311,7 +312,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
             int i;
             prop = fdt_get_property_by_offset(fdt, fdt_offset, &prop_len);
             name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
-            visit_start_list(v, name, NULL, 0, &err);
+            visit_start_list(v, name, &err);
             if (err) {
                 error_propagate(errp, err);
                 return;
@@ -323,7 +324,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
                     return;
                 }
             }
-            visit_end_list(v, NULL);
+            visit_end_list(v);
             break;
         }
         default:
@@ -375,10 +376,6 @@ static void attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
     drc->signalled = (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI)
                      ? true : coldplug;
 
-    if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI) {
-        drc->awaiting_allocation = true;
-    }
-
     object_property_add_link(OBJECT(drc), "device",
                              object_get_typename(OBJECT(drc->dev)),
                              (Object **)(&drc->dev),
@@ -427,12 +424,6 @@ static void detach(sPAPRDRConnector *drc, DeviceState *d,
         return;
     }
 
-    if (drc->awaiting_allocation) {
-        drc->awaiting_release = true;
-        DPRINTFN("awaiting allocation to complete before removal");
-        return;
-    }
-
     drc->indicator_state = SPAPR_DR_INDICATOR_STATE_INACTIVE;
 
     if (drc->detach_cb) {
index b0668b3..049fb1b 100644 (file)
@@ -386,7 +386,7 @@ static void spapr_powerdown_req(Notifier *n, void *opaque)
 
     rtas_event_log_queue(RTAS_LOG_TYPE_EPOW, new_epow, true);
 
-    qemu_irq_pulse(xics_get_qirq(spapr->xics, spapr->check_exception_irq));
+    qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq));
 }
 
 static void spapr_hotplug_set_signalled(uint32_t drc_index)
@@ -449,9 +449,6 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
     case SPAPR_DR_CONNECTOR_TYPE_LMB:
         hp->hotplug_type = RTAS_LOG_V6_HP_TYPE_MEMORY;
         break;
-    case SPAPR_DR_CONNECTOR_TYPE_CPU:
-        hp->hotplug_type = RTAS_LOG_V6_HP_TYPE_CPU;
-        break;
     default:
         /* we shouldn't be signaling hotplug events for resources
          * that don't support them
@@ -468,7 +465,7 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
 
     rtas_event_log_queue(RTAS_LOG_TYPE_HOTPLUG, new_hp, true);
 
-    qemu_irq_pulse(xics_get_qirq(spapr->xics, spapr->check_exception_irq));
+    qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq));
 }
 
 void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc)
@@ -551,7 +548,7 @@ static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr,
      * interrupts.
      */
     if (rtas_event_log_contains(mask, true)) {
-        qemu_irq_pulse(xics_get_qirq(spapr->xics, spapr->check_exception_irq));
+        qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq));
     }
 
     return;
@@ -603,7 +600,7 @@ out_no_events:
 void spapr_events_init(sPAPRMachineState *spapr)
 {
     QTAILQ_INIT(&spapr->pending_events);
-    spapr->check_exception_irq = xics_spapr_alloc(spapr->xics, 0, 0, false,
+    spapr->check_exception_irq = xics_alloc(spapr->icp, 0, 0, false,
                                             &error_fatal);
     spapr->epow_notifier.notify = spapr_powerdown_req;
     qemu_register_powerdown_notifier(&spapr->epow_notifier);
index 73af112..8f40602 100644 (file)
@@ -1,15 +1,12 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "sysemu/sysemu.h"
-#include "qemu/log.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "helper_regs.h"
 #include "hw/ppc/spapr.h"
 #include "mmu-hash64.h"
 #include "cpu-models.h"
 #include "trace.h"
-#include "sysemu/kvm.h"
 #include "kvm_ppc.h"
 
 struct SPRSyncState {
@@ -83,12 +80,12 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     target_ulong pte_index = args[1];
     target_ulong pteh = args[2];
     target_ulong ptel = args[3];
-    unsigned apshift;
+    unsigned apshift, spshift;
     target_ulong raddr;
     target_ulong index;
     uint64_t token;
 
-    apshift = ppc_hash64_hpte_page_shift_noslb(cpu, pteh, ptel);
+    apshift = ppc_hash64_hpte_page_shift_noslb(cpu, pteh, ptel, &spshift);
     if (!apshift) {
         /* Bad page size encoding */
         return H_PARAMETER;
@@ -102,15 +99,11 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
             return H_PARAMETER;
         }
     } else {
-        target_ulong wimg_flags;
         /* Looks like an IO address */
         /* FIXME: What WIMG combinations could be sensible for IO?
          * For now we allow WIMG=010x, but are there others? */
         /* FIXME: Should we check against registered IO addresses? */
-        wimg_flags = (ptel & (HPTE64_R_W | HPTE64_R_I | HPTE64_R_M));
-
-        if (wimg_flags != HPTE64_R_I &&
-            wimg_flags != (HPTE64_R_I | HPTE64_R_M)) {
+        if ((ptel & (HPTE64_R_W | HPTE64_R_I | HPTE64_R_M)) != HPTE64_R_I) {
             return H_PARAMETER;
         }
     }
@@ -190,7 +183,6 @@ static RemoveResult remove_hpte(PowerPCCPU *cpu, target_ulong ptex,
 static target_ulong h_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                              target_ulong opcode, target_ulong *args)
 {
-    CPUPPCState *env = &cpu->env;
     target_ulong flags = args[0];
     target_ulong pte_index = args[1];
     target_ulong avpn = args[2];
@@ -201,7 +193,6 @@ static target_ulong h_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 
     switch (ret) {
     case REMOVE_SUCCESS:
-        check_tlb_flush(env);
         return H_SUCCESS;
 
     case REMOVE_NOT_FOUND:
@@ -238,9 +229,7 @@ static target_ulong h_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                   target_ulong opcode, target_ulong *args)
 {
-    CPUPPCState *env = &cpu->env;
     int i;
-    target_ulong rc = H_SUCCESS;
 
     for (i = 0; i < H_BULK_REMOVE_MAX_BATCH; i++) {
         target_ulong *tsh = &args[i*2];
@@ -273,18 +262,14 @@ static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
             break;
 
         case REMOVE_PARM:
-            rc = H_PARAMETER;
-            goto exit;
+            return H_PARAMETER;
 
         case REMOVE_HW:
-            rc = H_HARDWARE;
-            goto exit;
+            return H_HARDWARE;
         }
     }
- exit:
-    check_tlb_flush(env);
 
-    return rc;
+    return H_SUCCESS;
 }
 
 static target_ulong h_protect(PowerPCCPU *cpu, sPAPRMachineState *spapr,
@@ -926,41 +911,6 @@ static void do_set_compat(void *arg)
     ((cpuver) == CPU_POWERPC_LOGICAL_2_06_PLUS) ? 2061 : \
     ((cpuver) == CPU_POWERPC_LOGICAL_2_07) ? 2070 : 0)
 
-static void cas_handle_compat_cpu(PowerPCCPUClass *pcc, uint32_t pvr,
-                                  unsigned max_lvl, unsigned *compat_lvl,
-                                  unsigned *cpu_version)
-{
-    unsigned lvl = get_compat_level(pvr);
-    bool is205, is206, is207;
-
-    if (!lvl) {
-        return;
-    }
-
-    /* If it is a logical PVR, try to determine the highest level */
-    is205 = (pcc->pcr_supported & PCR_COMPAT_2_05) &&
-            (lvl == get_compat_level(CPU_POWERPC_LOGICAL_2_05));
-    is206 = (pcc->pcr_supported & PCR_COMPAT_2_06) &&
-            ((lvl == get_compat_level(CPU_POWERPC_LOGICAL_2_06)) ||
-             (lvl == get_compat_level(CPU_POWERPC_LOGICAL_2_06_PLUS)));
-    is207 = (pcc->pcr_supported & PCR_COMPAT_2_07) &&
-            (lvl == get_compat_level(CPU_POWERPC_LOGICAL_2_07));
-
-    if (is205 || is206 || is207) {
-        if (!max_lvl) {
-            /* User did not set the level, choose the highest */
-            if (*compat_lvl <= lvl) {
-                *compat_lvl = lvl;
-                *cpu_version = pvr;
-            }
-        } else if (max_lvl >= lvl) {
-            /* User chose the level, don't set higher than this */
-            *compat_lvl = lvl;
-            *cpu_version = pvr;
-        }
-    }
-}
-
 #define OV5_DRCONF_MEMORY 0x20
 
 static target_ulong h_client_architecture_support(PowerPCCPU *cpu_,
@@ -970,7 +920,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu_,
 {
     target_ulong list = ppc64_phys_to_real(args[0]);
     target_ulong ov_table, ov5;
-    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu_);
+    PowerPCCPUClass *pcc_ = POWERPC_CPU_GET_CLASS(cpu_);
     CPUState *cs;
     bool cpu_match = false, cpu_update = true, memory_update = false;
     unsigned old_cpu_version = cpu_->cpu_version;
@@ -997,7 +947,29 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu_,
             cpu_match = true;
             cpu_version = cpu_->cpu_version;
         } else if (!cpu_match) {
-            cas_handle_compat_cpu(pcc, pvr, max_lvl, &compat_lvl, &cpu_version);
+            /* If it is a logical PVR, try to determine the highest level */
+            unsigned lvl = get_compat_level(pvr);
+            if (lvl) {
+                bool is205 = (pcc_->pcr_mask & PCR_COMPAT_2_05) &&
+                     (lvl == get_compat_level(CPU_POWERPC_LOGICAL_2_05));
+                bool is206 = (pcc_->pcr_mask & PCR_COMPAT_2_06) &&
+                    ((lvl == get_compat_level(CPU_POWERPC_LOGICAL_2_06)) ||
+                    (lvl == get_compat_level(CPU_POWERPC_LOGICAL_2_06_PLUS)));
+
+                if (is205 || is206) {
+                    if (!max_lvl) {
+                        /* User did not set the level, choose the highest */
+                        if (compat_lvl <= lvl) {
+                            compat_lvl = lvl;
+                            cpu_version = pvr;
+                        }
+                    } else if (max_lvl >= lvl) {
+                        /* User chose the level, don't set higher than this */
+                        compat_lvl = lvl;
+                        cpu_version = pvr;
+                    }
+                }
+            }
         }
         /* Terminator record */
         if (~pvr_mask & pvr) {
@@ -1007,7 +979,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu_,
 
     /* Parsing finished */
     trace_spapr_cas_pvr(cpu_->cpu_version, cpu_match,
-                        cpu_version, pcc->pcr_mask);
+                        cpu_version, pcc_->pcr_mask);
 
     /* Update CPUs */
     if (old_cpu_version != cpu_version) {
index 6bc4d4d..7dd4588 100644 (file)
@@ -17,9 +17,7 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "qemu/osdep.h"
-#include "qemu/error-report.h"
 #include "hw/hw.h"
-#include "qemu/log.h"
 #include "sysemu/kvm.h"
 #include "hw/qdev.h"
 #include "kvm_ppc.h"
@@ -77,37 +75,6 @@ static IOMMUAccessFlags spapr_tce_iommu_access_flags(uint64_t tce)
     }
 }
 
-static uint64_t *spapr_tce_alloc_table(uint32_t liobn,
-                                       uint32_t page_shift,
-                                       uint32_t nb_table,
-                                       int *fd,
-                                       bool need_vfio)
-{
-    uint64_t *table = NULL;
-    uint64_t window_size = (uint64_t)nb_table << page_shift;
-
-    if (kvm_enabled() && !(window_size >> 32)) {
-        table = kvmppc_create_spapr_tce(liobn, window_size, fd, need_vfio);
-    }
-
-    if (!table) {
-        *fd = -1;
-        table = g_malloc0(nb_table * sizeof(uint64_t));
-    }
-
-    trace_spapr_iommu_new_table(liobn, table, *fd);
-
-    return table;
-}
-
-static void spapr_tce_free_table(uint64_t *table, int fd, uint32_t nb_table)
-{
-    if (!kvm_enabled() ||
-        (kvmppc_remove_spapr_tce(table, fd, nb_table) != 0)) {
-        g_free(table);
-    }
-}
-
 /* Called from RCU critical section */
 static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr,
                                                bool is_write)
@@ -138,131 +105,61 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr,
     return ret;
 }
 
-static void spapr_tce_table_pre_save(void *opaque)
-{
-    sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque);
-
-    tcet->mig_table = tcet->table;
-    tcet->mig_nb_table = tcet->nb_table;
-
-    trace_spapr_iommu_pre_save(tcet->liobn, tcet->mig_nb_table,
-                               tcet->bus_offset, tcet->page_shift);
-}
-
-static uint64_t spapr_tce_get_min_page_size(MemoryRegion *iommu)
-{
-    sPAPRTCETable *tcet = container_of(iommu, sPAPRTCETable, iommu);
-
-    return 1ULL << tcet->page_shift;
-}
-
-static void spapr_tce_notify_started(MemoryRegion *iommu)
-{
-    spapr_tce_set_need_vfio(container_of(iommu, sPAPRTCETable, iommu), true);
-}
-
-static void spapr_tce_notify_stopped(MemoryRegion *iommu)
-{
-    spapr_tce_set_need_vfio(container_of(iommu, sPAPRTCETable, iommu), false);
-}
-
 static int spapr_tce_table_post_load(void *opaque, int version_id)
 {
     sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque);
-    uint32_t old_nb_table = tcet->nb_table;
-    uint64_t old_bus_offset = tcet->bus_offset;
-    uint32_t old_page_shift = tcet->page_shift;
 
     if (tcet->vdev) {
         spapr_vio_set_bypass(tcet->vdev, tcet->bypass);
     }
 
-    if (tcet->mig_nb_table != tcet->nb_table) {
-        spapr_tce_table_disable(tcet);
-    }
-
-    if (tcet->mig_nb_table) {
-        if (!tcet->nb_table) {
-            spapr_tce_table_enable(tcet, old_page_shift, old_bus_offset,
-                                   tcet->mig_nb_table);
-        }
-
-        memcpy(tcet->table, tcet->mig_table,
-               tcet->nb_table * sizeof(tcet->table[0]));
-
-        free(tcet->mig_table);
-        tcet->mig_table = NULL;
-    }
-
-    trace_spapr_iommu_post_load(tcet->liobn, old_nb_table, tcet->nb_table,
-                                tcet->bus_offset, tcet->page_shift);
-
     return 0;
 }
 
-static bool spapr_tce_table_ex_needed(void *opaque)
-{
-    sPAPRTCETable *tcet = opaque;
-
-    return tcet->bus_offset || tcet->page_shift != 0xC;
-}
-
-static const VMStateDescription vmstate_spapr_tce_table_ex = {
-    .name = "spapr_iommu_ex",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .needed = spapr_tce_table_ex_needed,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT64(bus_offset, sPAPRTCETable),
-        VMSTATE_UINT32(page_shift, sPAPRTCETable),
-        VMSTATE_END_OF_LIST()
-    },
-};
-
 static const VMStateDescription vmstate_spapr_tce_table = {
     .name = "spapr_iommu",
     .version_id = 2,
     .minimum_version_id = 2,
-    .pre_save = spapr_tce_table_pre_save,
     .post_load = spapr_tce_table_post_load,
     .fields      = (VMStateField []) {
         /* Sanity check */
         VMSTATE_UINT32_EQUAL(liobn, sPAPRTCETable),
+        VMSTATE_UINT32_EQUAL(nb_table, sPAPRTCETable),
 
         /* IOMMU state */
-        VMSTATE_UINT32(mig_nb_table, sPAPRTCETable),
         VMSTATE_BOOL(bypass, sPAPRTCETable),
-        VMSTATE_VARRAY_UINT32_ALLOC(mig_table, sPAPRTCETable, mig_nb_table, 0,
-                                    vmstate_info_uint64, uint64_t),
+        VMSTATE_VARRAY_UINT32(table, sPAPRTCETable, nb_table, 0, vmstate_info_uint64, uint64_t),
 
         VMSTATE_END_OF_LIST()
     },
-    .subsections = (const VMStateDescription*[]) {
-        &vmstate_spapr_tce_table_ex,
-        NULL
-    }
 };
 
 static MemoryRegionIOMMUOps spapr_iommu_ops = {
     .translate = spapr_tce_translate_iommu,
-    .get_min_page_size = spapr_tce_get_min_page_size,
-    .notify_started = spapr_tce_notify_started,
-    .notify_stopped = spapr_tce_notify_stopped,
 };
 
 static int spapr_tce_table_realize(DeviceState *dev)
 {
     sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
-    Object *tcetobj = OBJECT(tcet);
-    char tmp[32];
+    uint64_t window_size = (uint64_t)tcet->nb_table << tcet->page_shift;
 
-    tcet->fd = -1;
-    tcet->need_vfio = false;
-    snprintf(tmp, sizeof(tmp), "tce-root-%x", tcet->liobn);
-    memory_region_init(&tcet->root, tcetobj, tmp, UINT64_MAX);
+    if (kvm_enabled() && !(window_size >> 32)) {
+        tcet->table = kvmppc_create_spapr_tce(tcet->liobn,
+                                              window_size,
+                                              &tcet->fd,
+                                              tcet->need_vfio);
+    }
+
+    if (!tcet->table) {
+        size_t table_size = tcet->nb_table * sizeof(uint64_t);
+        tcet->table = g_malloc0(table_size);
+    }
 
-    snprintf(tmp, sizeof(tmp), "tce-iommu-%x", tcet->liobn);
-    memory_region_init_iommu(&tcet->iommu, tcetobj, &spapr_iommu_ops, tmp, 0);
+    trace_spapr_iommu_new_table(tcet->liobn, tcet, tcet->table, tcet->fd);
+
+    memory_region_init_iommu(&tcet->iommu, OBJECT(dev), &spapr_iommu_ops,
+                             "iommu-spapr",
+                             (uint64_t)tcet->nb_table << tcet->page_shift);
 
     QLIST_INSERT_HEAD(&spapr_tce_tables, tcet, list);
 
@@ -304,10 +201,14 @@ void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio)
     tcet->table = newtable;
 }
 
-sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn)
+sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn,
+                                   uint64_t bus_offset,
+                                   uint32_t page_shift,
+                                   uint32_t nb_table,
+                                   bool need_vfio)
 {
     sPAPRTCETable *tcet;
-    char tmp[32];
+    char tmp[64];
 
     if (spapr_tce_find_by_liobn(liobn)) {
         fprintf(stderr, "Attempted to create TCE table with duplicate"
@@ -315,8 +216,16 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn)
         return NULL;
     }
 
+    if (!nb_table) {
+        return NULL;
+    }
+
     tcet = SPAPR_TCE_TABLE(object_new(TYPE_SPAPR_TCE_TABLE));
     tcet->liobn = liobn;
+    tcet->bus_offset = bus_offset;
+    tcet->page_shift = page_shift;
+    tcet->nb_table = nb_table;
+    tcet->need_vfio = need_vfio;
 
     snprintf(tmp, sizeof(tmp), "tce-table-%x", liobn);
     object_property_add_child(OBJECT(owner), tmp, OBJECT(tcet), NULL);
@@ -326,58 +235,22 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn)
     return tcet;
 }
 
-void spapr_tce_table_enable(sPAPRTCETable *tcet,
-                            uint32_t page_shift, uint64_t bus_offset,
-                            uint32_t nb_table)
-{
-    if (tcet->nb_table) {
-        error_report("Warning: trying to enable already enabled TCE table");
-        return;
-    }
-
-    tcet->bus_offset = bus_offset;
-    tcet->page_shift = page_shift;
-    tcet->nb_table = nb_table;
-    tcet->table = spapr_tce_alloc_table(tcet->liobn,
-                                        tcet->page_shift,
-                                        tcet->nb_table,
-                                        &tcet->fd,
-                                        tcet->need_vfio);
-
-    memory_region_set_size(&tcet->iommu,
-                           (uint64_t)tcet->nb_table << tcet->page_shift);
-    memory_region_add_subregion(&tcet->root, tcet->bus_offset, &tcet->iommu);
-}
-
-void spapr_tce_table_disable(sPAPRTCETable *tcet)
-{
-    if (!tcet->nb_table) {
-        return;
-    }
-
-    memory_region_del_subregion(&tcet->root, &tcet->iommu);
-    memory_region_set_size(&tcet->iommu, 0);
-
-    spapr_tce_free_table(tcet->table, tcet->fd, tcet->nb_table);
-    tcet->fd = -1;
-    tcet->table = NULL;
-    tcet->bus_offset = 0;
-    tcet->page_shift = 0;
-    tcet->nb_table = 0;
-}
-
 static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp)
 {
     sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
 
     QLIST_REMOVE(tcet, list);
 
-    spapr_tce_table_disable(tcet);
+    if (!kvm_enabled() ||
+        (kvmppc_remove_spapr_tce(tcet->table, tcet->fd,
+                                 tcet->nb_table) != 0)) {
+        g_free(tcet->table);
+    }
 }
 
 MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet)
 {
-    return &tcet->root;
+    return &tcet->iommu;
 }
 
 static void spapr_tce_reset(DeviceState *dev)
@@ -385,9 +258,7 @@ static void spapr_tce_reset(DeviceState *dev)
     sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
     size_t table_size = tcet->nb_table * sizeof(uint64_t);
 
-    if (tcet->nb_table) {
-        memset(tcet->table, 0, table_size);
-    }
+    memset(tcet->table, 0, table_size);
 }
 
 static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
@@ -406,7 +277,7 @@ static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
     tcet->table[index] = tce;
 
     entry.target_as = &address_space_memory,
-    entry.iova = (ioba - tcet->bus_offset) & page_mask;
+    entry.iova = ioba & page_mask;
     entry.translated_addr = tce & page_mask;
     entry.addr_mask = ~page_mask;
     entry.perm = spapr_tce_iommu_access_flags(tce);
index 949c44f..573e635 100644 (file)
@@ -35,7 +35,6 @@
 #include "hw/ppc/spapr.h"
 #include "hw/pci-host/spapr.h"
 #include "exec/address-spaces.h"
-#include "exec/ram_addr.h"
 #include <libfdt.h>
 #include "trace.h"
 #include "qemu/error-report.h"
@@ -45,8 +44,6 @@
 #include "hw/pci/pci_bus.h"
 #include "hw/ppc/spapr_drc.h"
 #include "sysemu/device_tree.h"
-#include "sysemu/kvm.h"
-#include "sysemu/hostmem.h"
 
 #include "hw/vfio/vfio.h"
 
@@ -324,7 +321,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
             return;
         }
 
-        xics_spapr_free(spapr->xics, msi->first_irq, msi->num);
+        xics_free(spapr->icp, msi->first_irq, msi->num);
         if (msi_present(pdev)) {
             spapr_msi_setmsg(pdev, 0, false, 0, 0);
         }
@@ -362,7 +359,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     }
 
     /* Allocate MSIs */
-    irq = xics_spapr_alloc_block(spapr->xics, 0, req_num, false,
+    irq = xics_alloc_block(spapr->icp, 0, req_num, false,
                            ret_intr_type == RTAS_TYPE_MSI, &err);
     if (err) {
         error_reportf_err(err, "Can't allocate MSIs for device %x: ",
@@ -373,7 +370,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 
     /* Release previous MSIs */
     if (msi) {
-        xics_spapr_free(spapr->xics, msi->first_irq, msi->num);
+        xics_free(spapr->icp, msi->first_irq, msi->num);
         g_hash_table_remove(phb->msi, &config_addr);
     }
 
@@ -735,7 +732,7 @@ static void spapr_msi_write(void *opaque, hwaddr addr,
 
     trace_spapr_pci_msi_write(addr, data, irq);
 
-    qemu_irq_pulse(xics_get_qirq(spapr->xics, irq));
+    qemu_irq_pulse(xics_get_qirq(spapr->icp, irq));
 }
 
 static const MemoryRegionOps spapr_msi_ops = {
@@ -1089,11 +1086,19 @@ static void spapr_phb_add_pci_device(sPAPRDRConnector *drc,
     void *fdt = NULL;
     int fdt_start_offset = 0, fdt_size;
 
-    fdt = create_device_tree(&fdt_size);
-    fdt_start_offset = spapr_create_pci_child_dt(phb, pdev, fdt, 0);
-    if (!fdt_start_offset) {
-        error_setg(errp, "Failed to create pci child device tree node");
-        goto out;
+    if (object_dynamic_cast(OBJECT(pdev), "vfio-pci")) {
+        sPAPRTCETable *tcet = spapr_tce_find_by_liobn(phb->dma_liobn);
+
+        spapr_tce_set_need_vfio(tcet, true);
+    }
+
+    if (dev->hotplugged) {
+        fdt = create_device_tree(&fdt_size);
+        fdt_start_offset = spapr_create_pci_child_dt(phb, pdev, fdt, 0);
+        if (!fdt_start_offset) {
+            error_setg(errp, "Failed to create pci child device tree node");
+            goto out;
+        }
     }
 
     drck->attach(drc, DEVICE(pdev),
@@ -1306,14 +1311,12 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
     PCIBus *bus;
     uint64_t msi_window_size = 4096;
     sPAPRTCETable *tcet;
-    const unsigned windows_supported =
-        sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1;
+    uint32_t nb_table;
 
     if (sphb->index != (uint32_t)-1) {
         hwaddr windows_base;
 
-        if ((sphb->buid != (uint64_t)-1) || (sphb->dma_liobn[0] != (uint32_t)-1)
-            || (sphb->dma_liobn[1] != (uint32_t)-1 && windows_supported == 2)
+        if ((sphb->buid != (uint64_t)-1) || (sphb->dma_liobn != (uint32_t)-1)
             || (sphb->mem_win_addr != (hwaddr)-1)
             || (sphb->io_win_addr != (hwaddr)-1)) {
             error_setg(errp, "Either \"index\" or other parameters must"
@@ -1328,9 +1331,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
         }
 
         sphb->buid = SPAPR_PCI_BASE_BUID + sphb->index;
-        for (i = 0; i < windows_supported; ++i) {
-            sphb->dma_liobn[i] = SPAPR_PCI_LIOBN(sphb->index, i);
-        }
+        sphb->dma_liobn = SPAPR_PCI_LIOBN(sphb->index, 0);
 
         windows_base = SPAPR_PCI_WINDOW_BASE
             + sphb->index * SPAPR_PCI_WINDOW_SPACING;
@@ -1343,9 +1344,8 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    if ((sphb->dma_liobn[0] == (uint32_t)-1) ||
-        ((sphb->dma_liobn[1] == (uint32_t)-1) && (windows_supported > 1))) {
-        error_setg(errp, "LIOBN(s) not specified for PHB");
+    if (sphb->dma_liobn == (uint32_t)-1) {
+        error_setg(errp, "LIOBN not specified for PHB");
         return;
     }
 
@@ -1444,8 +1444,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
         uint32_t irq;
         Error *local_err = NULL;
 
-        irq = xics_spapr_alloc_block(spapr->xics, 0, 1, true, false,
-                                     &local_err);
+        irq = xics_alloc_block(spapr->icp, 0, 1, true, false, &local_err);
         if (local_err) {
             error_propagate(errp, local_err);
             error_prepend(errp, "can't allocate LSIs: ");
@@ -1464,18 +1463,19 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
         }
     }
 
-    /* DMA setup */
-    for (i = 0; i < windows_supported; ++i) {
-        tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn[i]);
-        if (!tcet) {
-            error_setg(errp, "Creating window#%d failed for %s",
-                       i, sphb->dtbusname);
-            return;
-        }
-        memory_region_add_subregion_overlap(&sphb->iommu_root, 0,
-                                            spapr_tce_get_iommu(tcet), 0);
+    nb_table = sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT;
+    tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn,
+                               0, SPAPR_TCE_PAGE_SHIFT, nb_table, false);
+    if (!tcet) {
+        error_setg(errp, "Unable to create TCE table for %s",
+                   sphb->dtbusname);
+        return;
     }
 
+    /* Register default 32bit DMA window */
+    memory_region_add_subregion(&sphb->iommu_root, sphb->dma_win_addr,
+                                spapr_tce_get_iommu(tcet));
+
     sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
 }
 
@@ -1490,31 +1490,8 @@ static int spapr_phb_children_reset(Object *child, void *opaque)
     return 0;
 }
 
-void spapr_phb_dma_reset(sPAPRPHBState *sphb)
-{
-    int i;
-    sPAPRTCETable *tcet;
-
-    for (i = 0; i < SPAPR_PCI_DMA_MAX_WINDOWS; ++i) {
-        tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[i]);
-
-        if (tcet && tcet->nb_table) {
-            spapr_tce_table_disable(tcet);
-        }
-    }
-
-    /* Register default 32bit DMA window */
-    tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[0]);
-    spapr_tce_table_enable(tcet, SPAPR_TCE_PAGE_SHIFT, sphb->dma_win_addr,
-                           sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT);
-}
-
 static void spapr_phb_reset(DeviceState *qdev)
 {
-    sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev);
-
-    spapr_phb_dma_reset(sphb);
-
     /* Reset the IOMMU state */
     object_child_foreach(OBJECT(qdev), spapr_phb_children_reset, NULL);
 
@@ -1526,8 +1503,7 @@ static void spapr_phb_reset(DeviceState *qdev)
 static Property spapr_phb_properties[] = {
     DEFINE_PROP_UINT32("index", sPAPRPHBState, index, -1),
     DEFINE_PROP_UINT64("buid", sPAPRPHBState, buid, -1),
-    DEFINE_PROP_UINT32("liobn", sPAPRPHBState, dma_liobn[0], -1),
-    DEFINE_PROP_UINT32("liobn64", sPAPRPHBState, dma_liobn[1], -1),
+    DEFINE_PROP_UINT32("liobn", sPAPRPHBState, dma_liobn, -1),
     DEFINE_PROP_UINT64("mem_win_addr", sPAPRPHBState, mem_win_addr, -1),
     DEFINE_PROP_UINT64("mem_win_size", sPAPRPHBState, mem_win_size,
                        SPAPR_PCI_MMIO_WIN_SIZE),
@@ -1539,11 +1515,6 @@ static Property spapr_phb_properties[] = {
     /* Default DMA window is 0..1GB */
     DEFINE_PROP_UINT64("dma_win_addr", sPAPRPHBState, dma_win_addr, 0),
     DEFINE_PROP_UINT64("dma_win_size", sPAPRPHBState, dma_win_size, 0x40000000),
-    DEFINE_PROP_UINT64("dma64_win_addr", sPAPRPHBState, dma64_win_addr,
-                       0x800000000000000ULL),
-    DEFINE_PROP_BOOL("ddw", sPAPRPHBState, ddw_enabled, true),
-    DEFINE_PROP_UINT64("pgsz", sPAPRPHBState, page_size_mask,
-                       (1ULL << 12) | (1ULL << 16)),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -1620,7 +1591,7 @@ static const VMStateDescription vmstate_spapr_pci = {
     .post_load = spapr_pci_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_UINT64_EQUAL(buid, sPAPRPHBState),
-        VMSTATE_UINT32_EQUAL(dma_liobn[0], sPAPRPHBState),
+        VMSTATE_UINT32_EQUAL(dma_liobn, sPAPRPHBState),
         VMSTATE_UINT64_EQUAL(mem_win_addr, sPAPRPHBState),
         VMSTATE_UINT64_EQUAL(mem_win_size, sPAPRPHBState),
         VMSTATE_UINT64_EQUAL(io_win_addr, sPAPRPHBState),
@@ -1654,6 +1625,7 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
     dc->reset = spapr_phb_reset;
     dc->vmsd = &vmstate_spapr_pci;
     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+    dc->cannot_instantiate_with_device_add_yet = false;
     hp->plug = spapr_phb_hot_plug_child;
     hp->unplug = spapr_phb_hot_unplug_child;
 }
@@ -1796,15 +1768,6 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
     uint32_t interrupt_map_mask[] = {
         cpu_to_be32(b_ddddd(-1)|b_fff(0)), 0x0, 0x0, cpu_to_be32(-1)};
     uint32_t interrupt_map[PCI_SLOT_MAX * PCI_NUM_PINS][7];
-    uint32_t ddw_applicable[] = {
-        cpu_to_be32(RTAS_IBM_QUERY_PE_DMA_WINDOW),
-        cpu_to_be32(RTAS_IBM_CREATE_PE_DMA_WINDOW),
-        cpu_to_be32(RTAS_IBM_REMOVE_PE_DMA_WINDOW)
-    };
-    uint32_t ddw_extensions[] = {
-        cpu_to_be32(1),
-        cpu_to_be32(RTAS_IBM_RESET_PE_DMA_WINDOW)
-    };
     sPAPRTCETable *tcet;
     PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus;
     sPAPRFDT s_fdt;
@@ -1827,15 +1790,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
     _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));
-    _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", XICS_IRQS_SPAPR));
-
-    /* Dynamic DMA window */
-    if (phb->ddw_enabled) {
-        _FDT(fdt_setprop(fdt, bus_off, "ibm,ddw-applicable", &ddw_applicable,
-                         sizeof(ddw_applicable)));
-        _FDT(fdt_setprop(fdt, bus_off, "ibm,ddw-extensions",
-                         &ddw_extensions, sizeof(ddw_extensions)));
-    }
+    _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", XICS_IRQS));
 
     /* Build the interrupt-map, this must matches what is done
      * in pci_spapr_map_irq
@@ -1860,7 +1815,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
     _FDT(fdt_setprop(fdt, bus_off, "interrupt-map", &interrupt_map,
                      sizeof(interrupt_map)));
 
-    tcet = spapr_tce_find_by_liobn(phb->dma_liobn[0]);
+    tcet = spapr_tce_find_by_liobn(SPAPR_PCI_LIOBN(phb->index, 0));
     if (!tcet) {
         return -1;
     }
index 8448e0b..cbd3d23 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include <linux/vfio.h>
 #include "qapi/error.h"
 #include "qemu-common.h"
 #include "cpu.h"
 #include "hw/ppc/spapr.h"
 #include "hw/pci-host/spapr.h"
 #include "hw/pci/msix.h"
+#include "linux/vfio.h"
 #include "hw/vfio/vfio.h"
 #include "qemu/error-report.h"
-#include "sysemu/qtest.h"
 
 #define TYPE_SPAPR_PCI_VFIO_HOST_BRIDGE "spapr-pci-vfio-host-bridge"
 
@@ -49,9 +48,7 @@ static Property spapr_phb_vfio_properties[] = {
 
 static void spapr_phb_vfio_instance_init(Object *obj)
 {
-    if (!qtest_enabled()) {
-        error_report("spapr-pci-vfio-host-bridge is deprecated");
-    }
+    error_report("spapr-pci-vfio-host-bridge is deprecated");
 }
 
 bool spapr_phb_eeh_available(sPAPRPHBState *sphb)
index dc058e5..f073258 100644 (file)
  */
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "qemu/log.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/char.h"
 #include "hw/qdev.h"
 #include "sysemu/device_tree.h"
 #include "sysemu/cpus.h"
-#include "sysemu/kvm.h"
 
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/spapr_vio.h"
-#include "hw/ppc/ppc.h"
 #include "qapi-event.h"
 #include "hw/boards.h"
 
@@ -165,27 +162,6 @@ static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
     rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
 }
 
-/*
- * Set the timebase offset of the CPU to that of first CPU.
- * This helps hotplugged CPU to have the correct timebase offset.
- */
-static void spapr_cpu_update_tb_offset(PowerPCCPU *cpu)
-{
-    PowerPCCPU *fcpu = POWERPC_CPU(first_cpu);
-
-    cpu->env.tb_env->tb_offset = fcpu->env.tb_env->tb_offset;
-}
-
-static void spapr_cpu_set_endianness(PowerPCCPU *cpu)
-{
-    PowerPCCPU *fcpu = POWERPC_CPU(first_cpu);
-    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(fcpu);
-
-    if (!pcc->interrupts_big_endian(fcpu)) {
-        cpu->env.spr[SPR_LPCR] |= LPCR_ILE;
-    }
-}
-
 static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
                            uint32_t token, uint32_t nargs,
                            target_ulong args,
@@ -222,8 +198,6 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
         env->nip = start;
         env->gpr[3] = r3;
         cs->halted = 0;
-        spapr_cpu_set_endianness(cpu);
-        spapr_cpu_update_tb_offset(cpu);
 
         qemu_cpu_kick(cs);
 
diff --git a/hw/ppc/spapr_rtas_ddw.c b/hw/ppc/spapr_rtas_ddw.c
deleted file mode 100644 (file)
index 177dcff..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * QEMU sPAPR Dynamic DMA windows support
- *
- * Copyright (c) 2015 Alexey Kardashevskiy, IBM Corporation.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License,
- *  or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "qemu/error-report.h"
-#include "hw/ppc/spapr.h"
-#include "hw/pci-host/spapr.h"
-#include "trace.h"
-
-static int spapr_phb_get_active_win_num_cb(Object *child, void *opaque)
-{
-    sPAPRTCETable *tcet;
-
-    tcet = (sPAPRTCETable *) object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE);
-    if (tcet && tcet->nb_table) {
-        ++*(unsigned *)opaque;
-    }
-    return 0;
-}
-
-static unsigned spapr_phb_get_active_win_num(sPAPRPHBState *sphb)
-{
-    unsigned ret = 0;
-
-    object_child_foreach(OBJECT(sphb), spapr_phb_get_active_win_num_cb, &ret);
-
-    return ret;
-}
-
-static int spapr_phb_get_free_liobn_cb(Object *child, void *opaque)
-{
-    sPAPRTCETable *tcet;
-
-    tcet = (sPAPRTCETable *) object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE);
-    if (tcet && !tcet->nb_table) {
-        *(uint32_t *)opaque = tcet->liobn;
-        return 1;
-    }
-    return 0;
-}
-
-static unsigned spapr_phb_get_free_liobn(sPAPRPHBState *sphb)
-{
-    uint32_t liobn = 0;
-
-    object_child_foreach(OBJECT(sphb), spapr_phb_get_free_liobn_cb, &liobn);
-
-    return liobn;
-}
-
-static uint32_t spapr_page_mask_to_query_mask(uint64_t page_mask)
-{
-    int i;
-    uint32_t mask = 0;
-    const struct { int shift; uint32_t mask; } masks[] = {
-        { 12, RTAS_DDW_PGSIZE_4K },
-        { 16, RTAS_DDW_PGSIZE_64K },
-        { 24, RTAS_DDW_PGSIZE_16M },
-        { 25, RTAS_DDW_PGSIZE_32M },
-        { 26, RTAS_DDW_PGSIZE_64M },
-        { 27, RTAS_DDW_PGSIZE_128M },
-        { 28, RTAS_DDW_PGSIZE_256M },
-        { 34, RTAS_DDW_PGSIZE_16G },
-    };
-
-    for (i = 0; i < ARRAY_SIZE(masks); ++i) {
-        if (page_mask & (1ULL << masks[i].shift)) {
-            mask |= masks[i].mask;
-        }
-    }
-
-    return mask;
-}
-
-static void rtas_ibm_query_pe_dma_window(PowerPCCPU *cpu,
-                                         sPAPRMachineState *spapr,
-                                         uint32_t token, uint32_t nargs,
-                                         target_ulong args,
-                                         uint32_t nret, target_ulong rets)
-{
-    sPAPRPHBState *sphb;
-    uint64_t buid, max_window_size;
-    uint32_t avail, addr, pgmask = 0;
-    MachineState *machine = MACHINE(spapr);
-
-    if ((nargs != 3) || (nret != 5)) {
-        goto param_error_exit;
-    }
-
-    buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
-    addr = rtas_ld(args, 0);
-    sphb = spapr_pci_find_phb(spapr, buid);
-    if (!sphb || !sphb->ddw_enabled) {
-        goto param_error_exit;
-    }
-
-    /* Translate page mask to LoPAPR format */
-    pgmask = spapr_page_mask_to_query_mask(sphb->page_size_mask);
-
-    /*
-     * This is "Largest contiguous block of TCEs allocated specifically
-     * for (that is, are reserved for) this PE".
-     * Return the maximum number as maximum supported RAM size was in 4K pages.
-     */
-    if (machine->ram_size == machine->maxram_size) {
-        max_window_size = machine->ram_size;
-    } else {
-        MemoryHotplugState *hpms = &spapr->hotplug_memory;
-
-        max_window_size = hpms->base + memory_region_size(&hpms->mr);
-    }
-
-    avail = SPAPR_PCI_DMA_MAX_WINDOWS - spapr_phb_get_active_win_num(sphb);
-
-    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
-    rtas_st(rets, 1, avail);
-    rtas_st(rets, 2, max_window_size >> SPAPR_TCE_PAGE_SHIFT);
-    rtas_st(rets, 3, pgmask);
-    rtas_st(rets, 4, 0); /* DMA migration mask, not supported */
-
-    trace_spapr_iommu_ddw_query(buid, addr, avail, max_window_size, pgmask);
-    return;
-
-param_error_exit:
-    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
-}
-
-static void rtas_ibm_create_pe_dma_window(PowerPCCPU *cpu,
-                                          sPAPRMachineState *spapr,
-                                          uint32_t token, uint32_t nargs,
-                                          target_ulong args,
-                                          uint32_t nret, target_ulong rets)
-{
-    sPAPRPHBState *sphb;
-    sPAPRTCETable *tcet = NULL;
-    uint32_t addr, page_shift, window_shift, liobn;
-    uint64_t buid, win_addr;
-    int windows;
-
-    if ((nargs != 5) || (nret != 4)) {
-        goto param_error_exit;
-    }
-
-    buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
-    addr = rtas_ld(args, 0);
-    sphb = spapr_pci_find_phb(spapr, buid);
-    if (!sphb || !sphb->ddw_enabled) {
-        goto param_error_exit;
-    }
-
-    page_shift = rtas_ld(args, 3);
-    window_shift = rtas_ld(args, 4);
-    liobn = spapr_phb_get_free_liobn(sphb);
-    windows = spapr_phb_get_active_win_num(sphb);
-
-    if (!(sphb->page_size_mask & (1ULL << page_shift)) ||
-        (window_shift < page_shift)) {
-        goto param_error_exit;
-    }
-
-    if (!liobn || !sphb->ddw_enabled || windows == SPAPR_PCI_DMA_MAX_WINDOWS) {
-        goto hw_error_exit;
-    }
-
-    tcet = spapr_tce_find_by_liobn(liobn);
-    if (!tcet) {
-        goto hw_error_exit;
-    }
-
-    win_addr = (windows == 0) ? sphb->dma_win_addr : sphb->dma64_win_addr;
-    spapr_tce_table_enable(tcet, page_shift, win_addr,
-                           1ULL << (window_shift - page_shift));
-    if (!tcet->nb_table) {
-        goto hw_error_exit;
-    }
-
-    trace_spapr_iommu_ddw_create(buid, addr, 1ULL << page_shift,
-                                 1ULL << window_shift, tcet->bus_offset, liobn);
-
-    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
-    rtas_st(rets, 1, liobn);
-    rtas_st(rets, 2, tcet->bus_offset >> 32);
-    rtas_st(rets, 3, tcet->bus_offset & ((uint32_t) -1));
-
-    return;
-
-hw_error_exit:
-    rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
-    return;
-
-param_error_exit:
-    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
-}
-
-static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu,
-                                          sPAPRMachineState *spapr,
-                                          uint32_t token, uint32_t nargs,
-                                          target_ulong args,
-                                          uint32_t nret, target_ulong rets)
-{
-    sPAPRPHBState *sphb;
-    sPAPRTCETable *tcet;
-    uint32_t liobn;
-
-    if ((nargs != 1) || (nret != 1)) {
-        goto param_error_exit;
-    }
-
-    liobn = rtas_ld(args, 0);
-    tcet = spapr_tce_find_by_liobn(liobn);
-    if (!tcet) {
-        goto param_error_exit;
-    }
-
-    sphb = SPAPR_PCI_HOST_BRIDGE(OBJECT(tcet)->parent);
-    if (!sphb || !sphb->ddw_enabled || !tcet->nb_table) {
-        goto param_error_exit;
-    }
-
-    spapr_tce_table_disable(tcet);
-    trace_spapr_iommu_ddw_remove(liobn);
-
-    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
-    return;
-
-param_error_exit:
-    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
-}
-
-static void rtas_ibm_reset_pe_dma_window(PowerPCCPU *cpu,
-                                         sPAPRMachineState *spapr,
-                                         uint32_t token, uint32_t nargs,
-                                         target_ulong args,
-                                         uint32_t nret, target_ulong rets)
-{
-    sPAPRPHBState *sphb;
-    uint64_t buid;
-    uint32_t addr;
-
-    if ((nargs != 3) || (nret != 1)) {
-        goto param_error_exit;
-    }
-
-    buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
-    addr = rtas_ld(args, 0);
-    sphb = spapr_pci_find_phb(spapr, buid);
-    if (!sphb || !sphb->ddw_enabled) {
-        goto param_error_exit;
-    }
-
-    spapr_phb_dma_reset(sphb);
-    trace_spapr_iommu_ddw_reset(buid, addr);
-
-    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
-
-    return;
-
-param_error_exit:
-    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
-}
-
-static void spapr_rtas_ddw_init(void)
-{
-    spapr_rtas_register(RTAS_IBM_QUERY_PE_DMA_WINDOW,
-                        "ibm,query-pe-dma-window",
-                        rtas_ibm_query_pe_dma_window);
-    spapr_rtas_register(RTAS_IBM_CREATE_PE_DMA_WINDOW,
-                        "ibm,create-pe-dma-window",
-                        rtas_ibm_create_pe_dma_window);
-    spapr_rtas_register(RTAS_IBM_REMOVE_PE_DMA_WINDOW,
-                        "ibm,remove-pe-dma-window",
-                        rtas_ibm_remove_pe_dma_window);
-    spapr_rtas_register(RTAS_IBM_RESET_PE_DMA_WINDOW,
-                        "ibm,reset-pe-dma-window",
-                        rtas_ibm_reset_pe_dma_window);
-}
-
-type_init(spapr_rtas_ddw_init)
index f93244d..8aa021f 100644 (file)
@@ -22,7 +22,6 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/hw.h"
-#include "qemu/log.h"
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
@@ -57,9 +56,12 @@ static char *spapr_vio_get_dev_name(DeviceState *qdev)
 {
     VIOsPAPRDevice *dev = VIO_SPAPR_DEVICE(qdev);
     VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
+    char *name;
 
     /* Device tree style name device@reg */
-    return g_strdup_printf("%s@%x", pc->dt_name, dev->reg);
+    name = g_strdup_printf("%s@%x", pc->dt_name, dev->reg);
+
+    return name;
 }
 
 static void spapr_vio_bus_class_init(ObjectClass *klass, void *data)
@@ -463,7 +465,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
         dev->qdev.id = id;
     }
 
-    dev->irq = xics_spapr_alloc(spapr->xics, 0, dev->irq, false, &local_err);
+    dev->irq = xics_alloc(spapr->icp, 0, dev->irq, false, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
@@ -480,9 +482,11 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
         memory_region_add_subregion_overlap(&dev->mrroot, 0, &dev->mrbypass, 1);
         address_space_init(&dev->as, &dev->mrroot, qdev->id);
 
-        dev->tcet = spapr_tce_new_table(qdev, liobn);
-        spapr_tce_table_enable(dev->tcet, SPAPR_TCE_PAGE_SHIFT, 0,
-                               pc->rtce_window_size >> SPAPR_TCE_PAGE_SHIFT);
+        dev->tcet = spapr_tce_new_table(qdev, liobn,
+                                        0,
+                                        SPAPR_TCE_PAGE_SHIFT,
+                                        pc->rtce_window_size >>
+                                        SPAPR_TCE_PAGE_SHIFT, false);
         dev->tcet->vdev = dev;
         memory_region_add_subregion_overlap(&dev->mrroot, 0,
                                             spapr_tce_get_iommu(dev->tcet), 2);
@@ -580,7 +584,7 @@ const VMStateDescription vmstate_spapr_vio = {
         VMSTATE_UINT32_EQUAL(irq, VIOsPAPRDevice),
 
         /* General VIO device state */
-        VMSTATE_UINT64(signal_state, VIOsPAPRDevice),
+        VMSTATE_UINTTL(signal_state, VIOsPAPRDevice),
         VMSTATE_UINT64(crq.qladdr, VIOsPAPRDevice),
         VMSTATE_UINT32(crq.qsize, VIOsPAPRDevice),
         VMSTATE_UINT32(crq.qnext, VIOsPAPRDevice),
diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events
deleted file mode 100644 (file)
index dfeab93..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/ppc/spapr_pci.c
-spapr_pci_msi(const char *msg, uint32_t ca) "%s (cfg=%x)"
-spapr_pci_msi_setup(const char *name, unsigned vector, uint64_t addr) "dev\"%s\" vector %u, addr=%"PRIx64
-spapr_pci_rtas_ibm_change_msi(unsigned cfg, unsigned func, unsigned req, unsigned first) "cfgaddr %x func %u, requested %u, first irq %u"
-spapr_pci_rtas_ibm_query_interrupt_source_number(unsigned ioa, unsigned intr) "queries for #%u, IRQ%u"
-spapr_pci_msi_write(uint64_t addr, uint64_t data, uint32_t dt_irq) "@%"PRIx64"<=%"PRIx64" IRQ %u"
-spapr_pci_lsi_set(const char *busname, int pin, uint32_t irq) "%s PIN%d IRQ %u"
-spapr_pci_msi_retry(unsigned config_addr, unsigned req_num, unsigned max_irqs) "Guest device at %x asked %u, have only %u"
-
-# hw/ppc/spapr.c
-spapr_cas_failed(unsigned long n) "DT diff buffer is too small: %ld bytes"
-spapr_cas_continue(unsigned long n) "Copy changes to the guest: %ld bytes"
-
-# hw/ppc/spapr_hcall.c
-spapr_cas_pvr_try(uint32_t pvr) "%x"
-spapr_cas_pvr(uint32_t cur_pvr, bool cpu_match, uint32_t new_pvr, uint64_t pcr) "current=%x, cpu_match=%u, new=%x, compat flags=%"PRIx64
-
-# hw/ppc/spapr_iommu.c
-spapr_iommu_put(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tce=0x%"PRIx64" ret=%"PRId64
-spapr_iommu_get(uint64_t liobn, uint64_t ioba, uint64_t ret, uint64_t tce) "liobn=%"PRIx64" ioba=0x%"PRIx64" ret=%"PRId64" tce=0x%"PRIx64
-spapr_iommu_indirect(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t iobaN, uint64_t tceN, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tcelist=0x%"PRIx64" iobaN=0x%"PRIx64" tceN=0x%"PRIx64" ret=%"PRId64
-spapr_iommu_stuff(uint64_t liobn, uint64_t ioba, uint64_t tce_value, uint64_t npages, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tcevalue=0x%"PRIx64" npages=%"PRId64" ret=%"PRId64
-spapr_iommu_pci_put(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tce=0x%"PRIx64" ret=%"PRId64
-spapr_iommu_pci_get(uint64_t liobn, uint64_t ioba, uint64_t ret, uint64_t tce) "liobn=%"PRIx64" ioba=0x%"PRIx64" ret=%"PRId64" tce=0x%"PRIx64
-spapr_iommu_pci_indirect(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t iobaN, uint64_t tceN, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tcelist=0x%"PRIx64" iobaN=0x%"PRIx64" tceN=0x%"PRIx64" ret=%"PRId64
-spapr_iommu_pci_stuff(uint64_t liobn, uint64_t ioba, uint64_t tce_value, uint64_t npages, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tcevalue=0x%"PRIx64" npages=%"PRId64" ret=%"PRId64
-spapr_iommu_xlate(uint64_t liobn, uint64_t ioba, uint64_t tce, unsigned perm, unsigned pgsize) "liobn=%"PRIx64" 0x%"PRIx64" -> 0x%"PRIx64" perm=%u mask=%x"
-spapr_iommu_new_table(uint64_t liobn, void *table, int fd) "liobn=%"PRIx64" table=%p fd=%d"
-spapr_iommu_pre_save(uint64_t liobn, uint32_t nb, uint64_t offs, uint32_t ps) "liobn=%"PRIx64" %"PRIx32" bus_offset=%"PRIx64" ps=%"PRIu32
-spapr_iommu_post_load(uint64_t liobn, uint32_t pre_nb, uint32_t post_nb, uint64_t offs, uint32_t ps) "liobn=%"PRIx64" %"PRIx32" => %"PRIx32" bus_offset=%"PRIx64" ps=%"PRIu32
-spapr_iommu_ddw_query(uint64_t buid, uint32_t cfgaddr, unsigned wa, uint64_t win_size, uint32_t pgmask) "buid=%"PRIx64" addr=%"PRIx32", %u windows available, max window size=%"PRIx64", mask=%"PRIx32
-spapr_iommu_ddw_create(uint64_t buid, uint32_t cfgaddr, uint64_t pg_size, uint64_t req_size, uint64_t start, uint32_t liobn) "buid=%"PRIx64" addr=%"PRIx32", page size=0x%"PRIx64", requested=0x%"PRIx64", start addr=%"PRIx64", liobn=%"PRIx32
-spapr_iommu_ddw_remove(uint32_t liobn) "liobn=%"PRIx32
-spapr_iommu_ddw_reset(uint64_t buid, uint32_t cfgaddr) "buid=%"PRIx64" addr=%"PRIx32
-
-# hw/ppc/ppc.c
-ppc_tb_adjust(uint64_t offs1, uint64_t offs2, int64_t diff, int64_t seconds) "adjusted from 0x%"PRIx64" to 0x%"PRIx64", diff %"PRId64" (%"PRId64"s)"
-
-# hw/ppc/prep.c
-prep_io_800_writeb(uint32_t addr, uint32_t val) "0x%08" PRIx32 " => 0x%02" PRIx32
-prep_io_800_readb(uint32_t addr, uint32_t retval) "0x%08" PRIx32 " <= 0x%02" PRIx32
index b97d966..b807a08 100644 (file)
@@ -23,7 +23,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "cpu.h"
 #include "hw/sysbus.h"
 #include "hw/hw.h"
 #include "hw/char/serial.h"
index 41ac4ec..2203617 100644 (file)
@@ -8,8 +8,6 @@ obj-y += ipl.o
 obj-y += css.o
 obj-y += s390-virtio-ccw.o
 obj-y += virtio-ccw.o
-obj-y += css-bridge.o
-obj-y += ccw-device.o
 obj-y += s390-pci-bus.o s390-pci-inst.o
 obj-y += s390-skeys.o
 obj-$(CONFIG_KVM) += s390-skeys-kvm.o
diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c
deleted file mode 100644 (file)
index 28ea204..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Common device infrastructure for devices in the virtual css
- *
- * Copyright 2016 IBM Corp.
- * Author(s): Jing Liu <liujbjl@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or (at
- * your option) any later version. See the COPYING file in the top-level
- * directory.
- */
-#include "qemu/osdep.h"
-#include "ccw-device.h"
-
-static const TypeInfo ccw_device_info = {
-    .name = TYPE_CCW_DEVICE,
-    .parent = TYPE_DEVICE,
-    .instance_size = sizeof(CcwDevice),
-    .class_size = sizeof(CCWDeviceClass),
-    .abstract = true,
-};
-
-static void ccw_device_register(void)
-{
-    type_register_static(&ccw_device_info);
-}
-
-type_init(ccw_device_register)
diff --git a/hw/s390x/ccw-device.h b/hw/s390x/ccw-device.h
deleted file mode 100644 (file)
index 59ba01b..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Common device infrastructure for devices in the virtual css
- *
- * Copyright 2016 IBM Corp.
- * Author(s): Jing Liu <liujbjl@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or (at
- * your option) any later version. See the COPYING file in the top-level
- * directory.
- */
-
-#ifndef HW_S390X_CCW_DEVICE_H
-#define HW_S390X_CCW_DEVICE_H
-#include "qom/object.h"
-#include "hw/qdev-core.h"
-#include "hw/s390x/css.h"
-
-typedef struct CcwDevice {
-    DeviceState parent_obj;
-    SubchDev *sch;
-    /* <cssid>.<ssid>.<device number> */
-    CssDevId bus_id;
-} CcwDevice;
-
-typedef struct CCWDeviceClass {
-    DeviceClass parent_class;
-    void (*unplug)(HotplugHandler *, DeviceState *, Error **);
-} CCWDeviceClass;
-
-static inline CcwDevice *to_ccw_dev_fast(DeviceState *d)
-{
-    return container_of(d, CcwDevice, parent_obj);
-}
-
-#define TYPE_CCW_DEVICE "ccw-device"
-
-#define CCW_DEVICE(obj) OBJECT_CHECK(CcwDevice, (obj), TYPE_CCW_DEVICE)
-#define CCW_DEVICE_GET_CLASS(obj) \
-    OBJECT_GET_CLASS(CCWDeviceClass, (obj), TYPE_CCW_DEVICE)
-#define CCW_DEVICE_CLASS(klass) \
-    OBJECT_CLASS_CHECK(CCWDeviceClass, (klass), TYPE_CCW_DEVICE)
-
-#endif
diff --git a/hw/s390x/css-bridge.c b/hw/s390x/css-bridge.c
deleted file mode 100644 (file)
index 9a7f7ee..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * css bridge implementation
- *
- * Copyright 2012,2016 IBM Corp.
- * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
- *            Pierre Morel <pmorel@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or (at
- * your option) any later version. See the COPYING file in the top-level
- * directory.
- */
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/hotplug.h"
-#include "hw/sysbus.h"
-#include "qemu/bitops.h"
-#include "hw/s390x/css.h"
-#include "ccw-device.h"
-#include "hw/s390x/css-bridge.h"
-
-/*
- * Invoke device-specific unplug handler, disable the subchannel
- * (including sending a channel report to the guest) and remove the
- * device from the virtual css bus.
- */
-static void ccw_device_unplug(HotplugHandler *hotplug_dev,
-                              DeviceState *dev, Error **errp)
-{
-    CcwDevice *ccw_dev = CCW_DEVICE(dev);
-    CCWDeviceClass *k = CCW_DEVICE_GET_CLASS(ccw_dev);
-    SubchDev *sch = ccw_dev->sch;
-    Error *err = NULL;
-
-    if (k->unplug) {
-        k->unplug(hotplug_dev, dev, &err);
-        if (err) {
-            error_propagate(errp, err);
-            return;
-        }
-    }
-
-    /*
-     * We should arrive here only for device_del, since we don't support
-     * direct hot(un)plug of channels.
-     */
-    assert(sch != NULL);
-    /* Subchannel is now disabled and no longer valid. */
-    sch->curr_status.pmcw.flags &= ~(PMCW_FLAGS_MASK_ENA |
-                                     PMCW_FLAGS_MASK_DNV);
-
-    css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
-
-    object_unparent(OBJECT(dev));
-}
-
-static void virtual_css_bus_reset(BusState *qbus)
-{
-    /* This should actually be modelled via the generic css */
-    css_reset();
-}
-
-static char *virtual_css_bus_get_dev_path(DeviceState *dev)
-{
-    CcwDevice *ccw_dev = CCW_DEVICE(dev);
-    SubchDev *sch = ccw_dev->sch;
-    VirtualCssBridge *bridge =
-        VIRTUAL_CSS_BRIDGE(qdev_get_parent_bus(dev)->parent);
-
-    /*
-     * We can't provide a dev path for backward compatibility on
-     * older machines, as it is visible in the migration stream.
-     */
-    return bridge->css_dev_path ?
-        g_strdup_printf("/%02x.%1x.%04x", sch->cssid, sch->ssid, sch->devno) :
-        NULL;
-}
-
-static void virtual_css_bus_class_init(ObjectClass *klass, void *data)
-{
-    BusClass *k = BUS_CLASS(klass);
-
-    k->reset = virtual_css_bus_reset;
-    k->get_dev_path = virtual_css_bus_get_dev_path;
-}
-
-static const TypeInfo virtual_css_bus_info = {
-    .name = TYPE_VIRTUAL_CSS_BUS,
-    .parent = TYPE_BUS,
-    .instance_size = sizeof(VirtualCssBus),
-    .class_init = virtual_css_bus_class_init,
-};
-
-VirtualCssBus *virtual_css_bus_init(void)
-{
-    VirtualCssBus *cbus;
-    BusState *bus;
-    DeviceState *dev;
-
-    /* Create bridge device */
-    dev = qdev_create(NULL, TYPE_VIRTUAL_CSS_BRIDGE);
-    qdev_init_nofail(dev);
-
-    /* Create bus on bridge device */
-    bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
-    cbus = VIRTUAL_CSS_BUS(bus);
-
-    /* Enable hotplugging */
-    qbus_set_hotplug_handler(bus, dev, &error_abort);
-
-    return cbus;
- }
-
-/***************** Virtual-css Bus Bridge Device ********************/
-
-static Property virtual_css_bridge_properties[] = {
-    DEFINE_PROP_BOOL("css_dev_path", VirtualCssBridge, css_dev_path,
-                     true),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
-{
-    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
-    DeviceClass *dc = DEVICE_CLASS(klass);
-
-    hc->unplug = ccw_device_unplug;
-    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
-    dc->props = virtual_css_bridge_properties;
-}
-
-static const TypeInfo virtual_css_bridge_info = {
-    .name          = TYPE_VIRTUAL_CSS_BRIDGE,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(VirtualCssBridge),
-    .class_init    = virtual_css_bridge_class_init,
-    .interfaces = (InterfaceInfo[]) {
-        { TYPE_HOTPLUG_HANDLER },
-        { }
-    }
-};
-
-static void virtual_css_register(void)
-{
-    type_register_static(&virtual_css_bridge_info);
-    type_register_static(&virtual_css_bus_info);
-}
-
-type_init(virtual_css_register)
index bb8e4be..3a1d919 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qapi/visitor.h"
-#include "hw/qdev.h"
+#include <hw/qdev.h>
 #include "qemu/bitops.h"
 #include "exec/address-spaces.h"
 #include "cpu.h"
-#include "hw/s390x/ioinst.h"
-#include "hw/s390x/css.h"
+#include "ioinst.h"
+#include "css.h"
 #include "trace.h"
 #include "hw/s390x/s390_flic.h"
 
@@ -194,46 +192,12 @@ out:
     return ret;
 }
 
-static void css_clear_io_interrupt(uint16_t subchannel_id,
-                                   uint16_t subchannel_nr)
-{
-    Error *err = NULL;
-    static bool no_clear_irq;
-    S390FLICState *fs = s390_get_flic();
-    S390FLICStateClass *fsc = S390_FLIC_COMMON_GET_CLASS(fs);
-    int r;
-
-    if (unlikely(no_clear_irq)) {
-        return;
-    }
-    r = fsc->clear_io_irq(fs, subchannel_id, subchannel_nr);
-    switch (r) {
-    case 0:
-        break;
-    case -ENOSYS:
-        no_clear_irq = true;
-        /*
-        * Ignore unavailability, as the user can't do anything
-        * about it anyway.
-        */
-        break;
-    default:
-        error_setg_errno(&err, -r, "unexpected error condition");
-        error_propagate(&error_abort, err);
-    }
-}
-
-static inline uint16_t css_do_build_subchannel_id(uint8_t cssid, uint8_t ssid)
+uint16_t css_build_subchannel_id(SubchDev *sch)
 {
     if (channel_subsys.max_cssid > 0) {
-        return (cssid << 8) | (1 << 3) | (ssid << 1) | 1;
+        return (sch->cssid << 8) | (1 << 3) | (sch->ssid << 1) | 1;
     }
-    return (ssid << 1) | 1;
-}
-
-uint16_t css_build_subchannel_id(SubchDev *sch)
-{
-    return css_do_build_subchannel_id(sch->cssid, sch->ssid);
+    return (sch->ssid << 1) | 1;
 }
 
 static void css_inject_io_interrupt(SubchDev *sch)
@@ -511,7 +475,6 @@ static void sch_handle_start_func(SubchDev *sch, ORB *orb)
     path = 0x80;
 
     if (!(s->ctrl & SCSW_ACTL_SUSP)) {
-        /* Start Function triggered via ssch, i.e. we have an ORB */
         s->cstat = 0;
         s->dstat = 0;
         /* Look at the orb and try to execute the channel program. */
@@ -525,12 +488,9 @@ static void sch_handle_start_func(SubchDev *sch, ORB *orb)
             return;
         }
         sch->ccw_fmt_1 = !!(orb->ctrl0 & ORB_CTRL0_MASK_FMT);
-        s->flags |= (sch->ccw_fmt_1) ? SCSW_FLAGS_MASK_FMT : 0;
         sch->ccw_no_data_cnt = 0;
         suspend_allowed = !!(orb->ctrl0 & ORB_CTRL0_MASK_SPND);
     } else {
-        /* Start Function resumed via rsch, i.e. we don't have an
-         * ORB */
         s->ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND);
         /* The channel program had been suspended before. */
         suspend_allowed = true;
@@ -613,7 +573,6 @@ static void do_subchannel_work(SubchDev *sch, ORB *orb)
     } else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
         sch_handle_halt_func(sch);
     } else if (s->ctrl & SCSW_FCTL_START_FUNC) {
-        /* Triggered by both ssch and rsch. */
         sch_handle_start_func(sch, orb);
     } else {
         /* Cannot happen. */
@@ -1345,116 +1304,6 @@ SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid, uint16_t schid)
     return channel_subsys.css[real_cssid]->sch_set[ssid]->sch[schid];
 }
 
-/**
- * Return free device number in subchannel set.
- *
- * Return index of the first free device number in the subchannel set
- * identified by @p cssid and @p ssid, beginning the search at @p
- * start and wrapping around at MAX_DEVNO. Return a value exceeding
- * MAX_SCHID if there are no free device numbers in the subchannel
- * set.
- */
-static uint32_t css_find_free_devno(uint8_t cssid, uint8_t ssid,
-                                    uint16_t start)
-{
-    uint32_t round;
-
-    for (round = 0; round <= MAX_DEVNO; round++) {
-        uint16_t devno = (start + round) % MAX_DEVNO;
-
-        if (!css_devno_used(cssid, ssid, devno)) {
-            return devno;
-        }
-    }
-    return MAX_DEVNO + 1;
-}
-
-/**
- * Return first free subchannel (id) in subchannel set.
- *
- * Return index of the first free subchannel in the subchannel set
- * identified by @p cssid and @p ssid, if there is any. Return a value
- * exceeding MAX_SCHID if there are no free subchannels in the
- * subchannel set.
- */
-static uint32_t css_find_free_subch(uint8_t cssid, uint8_t ssid)
-{
-    uint32_t schid;
-
-    for (schid = 0; schid <= MAX_SCHID; schid++) {
-        if (!css_find_subch(1, cssid, ssid, schid)) {
-            return schid;
-        }
-    }
-    return MAX_SCHID + 1;
-}
-
-/**
- * Return first free subchannel (id) in subchannel set for a device number
- *
- * Verify the device number @p devno is not used yet in the subchannel
- * set identified by @p cssid and @p ssid. Set @p schid to the index
- * of the first free subchannel in the subchannel set, if there is
- * any. Return true if everything succeeded and false otherwise.
- */
-static bool css_find_free_subch_for_devno(uint8_t cssid, uint8_t ssid,
-                                          uint16_t devno, uint16_t *schid,
-                                          Error **errp)
-{
-    uint32_t free_schid;
-
-    assert(schid);
-    if (css_devno_used(cssid, ssid, devno)) {
-        error_setg(errp, "Device %x.%x.%04x already exists",
-                   cssid, ssid, devno);
-        return false;
-    }
-    free_schid = css_find_free_subch(cssid, ssid);
-    if (free_schid > MAX_SCHID) {
-        error_setg(errp, "No free subchannel found for %x.%x.%04x",
-                   cssid, ssid, devno);
-        return false;
-    }
-    *schid = free_schid;
-    return true;
-}
-
-/**
- * Return first free subchannel (id) and device number
- *
- * Locate the first free subchannel and first free device number in
- * any of the subchannel sets of the channel subsystem identified by
- * @p cssid. Return false if no free subchannel / device number could
- * be found. Otherwise set @p ssid, @p devno and @p schid to identify
- * the available subchannel and device number and return true.
- *
- * May modify @p ssid, @p devno and / or @p schid even if no free
- * subchannel / device number could be found.
- */
-static bool css_find_free_subch_and_devno(uint8_t cssid, uint8_t *ssid,
-                                          uint16_t *devno, uint16_t *schid,
-                                          Error **errp)
-{
-    uint32_t free_schid, free_devno;
-
-    assert(ssid && devno && schid);
-    for (*ssid = 0; *ssid <= MAX_SSID; (*ssid)++) {
-        free_schid = css_find_free_subch(cssid, *ssid);
-        if (free_schid > MAX_SCHID) {
-            continue;
-        }
-        free_devno = css_find_free_devno(cssid, *ssid, free_schid);
-        if (free_devno > MAX_DEVNO) {
-            continue;
-        }
-        *schid = free_schid;
-        *devno = free_devno;
-        return true;
-    }
-    error_setg(errp, "Virtual channel subsystem is full!");
-    return false;
-}
-
 bool css_subch_visible(SubchDev *sch)
 {
     if (sch->ssid > channel_subsys.max_ssid) {
@@ -1580,8 +1429,6 @@ void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
         css_queue_crw(CRW_RSC_SUBCH, CRW_ERC_IPI, 0,
                       (guest_cssid << 8) | (ssid << 4));
     }
-    /* RW_ERC_IPI --> clear pending interrupts */
-    css_clear_io_interrupt(css_do_build_subchannel_id(cssid, ssid), schid);
 }
 
 void css_generate_chp_crws(uint8_t cssid, uint8_t chpid)
@@ -1797,116 +1644,3 @@ void css_reset(void)
     channel_subsys.max_cssid = 0;
     channel_subsys.max_ssid = 0;
 }
-
-static void get_css_devid(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    CssDevId *dev_id = qdev_get_prop_ptr(dev, prop);
-    char buffer[] = "xx.x.xxxx";
-    char *p = buffer;
-    int r;
-
-    if (dev_id->valid) {
-
-        r = snprintf(buffer, sizeof(buffer), "%02x.%1x.%04x", dev_id->cssid,
-                     dev_id->ssid, dev_id->devid);
-        assert(r == sizeof(buffer) - 1);
-
-        /* drop leading zero */
-        if (dev_id->cssid <= 0xf) {
-            p++;
-        }
-    } else {
-        snprintf(buffer, sizeof(buffer), "<unset>");
-    }
-
-    visit_type_str(v, name, &p, errp);
-}
-
-/*
- * parse <cssid>.<ssid>.<devid> and assert valid range for cssid/ssid
- */
-static void set_css_devid(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    CssDevId *dev_id = qdev_get_prop_ptr(dev, prop);
-    Error *local_err = NULL;
-    char *str;
-    int num, n1, n2;
-    unsigned int cssid, ssid, devid;
-
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
-    visit_type_str(v, name, &str, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    num = sscanf(str, "%2x.%1x%n.%4x%n", &cssid, &ssid, &n1, &devid, &n2);
-    if (num != 3 || (n2 - n1) != 5 || strlen(str) != n2) {
-        error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
-        goto out;
-    }
-    if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) {
-        error_setg(errp, "Invalid cssid or ssid: cssid %x, ssid %x",
-                   cssid, ssid);
-        goto out;
-    }
-
-    dev_id->cssid = cssid;
-    dev_id->ssid = ssid;
-    dev_id->devid = devid;
-    dev_id->valid = true;
-
-out:
-    g_free(str);
-}
-
-PropertyInfo css_devid_propinfo = {
-    .name = "str",
-    .description = "Identifier of an I/O device in the channel "
-                   "subsystem, example: fe.1.23ab",
-    .get = get_css_devid,
-    .set = set_css_devid,
-};
-
-SubchDev *css_create_virtual_sch(CssDevId bus_id, Error **errp)
-{
-    uint16_t schid = 0;
-    SubchDev *sch;
-
-    if (bus_id.valid) {
-        /* Enforce use of virtual cssid. */
-        if (bus_id.cssid != VIRTUAL_CSSID) {
-            error_setg(errp, "cssid %hhx not valid for virtual devices",
-                       bus_id.cssid);
-            return NULL;
-        }
-        if (!css_find_free_subch_for_devno(bus_id.cssid, bus_id.ssid,
-                                           bus_id.devid, &schid, errp)) {
-            return NULL;
-        }
-    } else {
-        bus_id.cssid = VIRTUAL_CSSID;
-        if (!css_find_free_subch_and_devno(bus_id.cssid, &bus_id.ssid,
-                                           &bus_id.devid, &schid, errp)) {
-            return NULL;
-        }
-    }
-
-    sch = g_malloc0(sizeof(*sch));
-    sch->cssid = bus_id.cssid;
-    sch->ssid = bus_id.ssid;
-    sch->devno = bus_id.devid;
-    sch->schid = schid;
-    css_subch_assign(sch->cssid, sch->ssid, schid, sch->devno, sch);
-    return sch;
-}
similarity index 61%
rename from include/hw/s390x/css.h
rename to hw/s390x/css.h
index 1da63e3..a320eea 100644 (file)
 
 #include "hw/s390x/adapter.h"
 #include "hw/s390x/s390_flic.h"
-#include "hw/s390x/ioinst.h"
+#include "ioinst.h"
 
 /* Channel subsystem constants. */
-#define MAX_DEVNO 65535
 #define MAX_SCHID 65535
 #define MAX_SSID 3
 #define MAX_CSSID 254 /* 255 is reserved */
@@ -25,8 +24,6 @@
 
 #define MAX_CIWS 62
 
-#define VIRTUAL_CSSID 0xfe
-
 typedef struct CIW {
     uint8_t type;
     uint8_t command;
@@ -70,7 +67,6 @@ typedef struct CMBE {
     uint32_t reserved[7];
 } QEMU_PACKED CMBE;
 
-typedef struct SubchDev SubchDev;
 struct SubchDev {
     /* channel-subsystem related things: */
     uint8_t cssid;
@@ -127,64 +123,4 @@ void css_adapter_interrupt(uint8_t isc);
 #define CSS_IO_ADAPTER_VIRTIO 1
 int css_register_io_adapter(uint8_t type, uint8_t isc, bool swap,
                             bool maskable, uint32_t *id);
-
-#ifndef CONFIG_USER_ONLY
-SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid,
-                         uint16_t schid);
-bool css_subch_visible(SubchDev *sch);
-void css_conditional_io_interrupt(SubchDev *sch);
-int css_do_stsch(SubchDev *sch, SCHIB *schib);
-bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid);
-int css_do_msch(SubchDev *sch, const SCHIB *schib);
-int css_do_xsch(SubchDev *sch);
-int css_do_csch(SubchDev *sch);
-int css_do_hsch(SubchDev *sch);
-int css_do_ssch(SubchDev *sch, ORB *orb);
-int css_do_tsch_get_irb(SubchDev *sch, IRB *irb, int *irb_len);
-void css_do_tsch_update_subch(SubchDev *sch);
-int css_do_stcrw(CRW *crw);
-void css_undo_stcrw(CRW *crw);
-int css_do_tpi(IOIntCode *int_code, int lowcore);
-int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid,
-                         int rfmt, void *buf);
-void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo);
-int css_enable_mcsse(void);
-int css_enable_mss(void);
-int css_do_rsch(SubchDev *sch);
-int css_do_rchp(uint8_t cssid, uint8_t chpid);
-bool css_present(uint8_t cssid);
-#endif
-/*
- * Identify a device within the channel subsystem.
- * Note that this can be used to identify either the subchannel or
- * the attached I/O device, as there's always one I/O device per
- * subchannel.
- */
-typedef struct CssDevId {
-    uint8_t cssid;
-    uint8_t ssid;
-    uint16_t devid;
-    bool valid;
-} CssDevId;
-
-extern PropertyInfo css_devid_propinfo;
-
-#define DEFINE_PROP_CSS_DEV_ID(_n, _s, _f) \
-    DEFINE_PROP(_n, _s, _f, css_devid_propinfo, CssDevId)
-
-/**
- * Create a subchannel for the given bus id.
- *
- * If @p bus_id is valid, verify that it uses the virtual channel
- * subsystem id and is not already in use, and find a free subchannel
- * id for it. If @p bus_id is not valid, find a free subchannel id and
- * device number across all subchannel sets. If either of the former
- * actions succeed, allocate a subchannel structure, initialise it
- * with the bus id, subchannel id and device number, register it with
- * the CSS and return it. Otherwise return NULL.
- *
- * The caller becomes owner of the returned subchannel structure and
- * is responsible for unregistering and freeing it.
- */
-SubchDev *css_create_virtual_sch(CssDevId bus_id, Error **errp);
 #endif
index 2e2664f..3173dcf 100644 (file)
 #define ZIPL_IMAGE_START                0x009000UL
 #define IPL_PSW_MASK                    (PSW_MASK_32 | PSW_MASK_64)
 
-static bool iplb_extended_needed(void *opaque)
-{
-    S390IPLState *ipl = S390_IPL(object_resolve_path(TYPE_S390_IPL, NULL));
-
-    return ipl->iplbext_migration;
-}
-
-static const VMStateDescription vmstate_iplb_extended = {
-    .name = "ipl/iplb_extended",
-    .version_id = 0,
-    .minimum_version_id = 0,
-    .needed = iplb_extended_needed,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT8_ARRAY(reserved_ext, IplParameterBlock, 4096 - 200),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
 static const VMStateDescription vmstate_iplb = {
     .name = "ipl/iplb",
     .version_id = 0,
@@ -57,10 +39,6 @@ static const VMStateDescription vmstate_iplb = {
         VMSTATE_UINT16(devno, IplParameterBlock),
         VMSTATE_UINT8_ARRAY(reserved2, IplParameterBlock, 88),
         VMSTATE_END_OF_LIST()
-    },
-    .subsections = (const VMStateDescription*[]) {
-        &vmstate_iplb_extended,
-        NULL
     }
 };
 
@@ -129,7 +107,7 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
             /* Adjust ELF start address to final location */
             ipl->bios_start_addr += fwbase;
         } else {
-            /* Try to load non-ELF file */
+            /* Try to load non-ELF file (e.g. s390-ccw.img) */
             bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START,
                                             4096);
             ipl->bios_start_addr = ZIPL_IMAGE_START;
@@ -210,52 +188,46 @@ static Property s390_ipl_properties[] = {
     DEFINE_PROP_STRING("cmdline", S390IPLState, cmdline),
     DEFINE_PROP_STRING("firmware", S390IPLState, firmware),
     DEFINE_PROP_BOOL("enforce_bios", S390IPLState, enforce_bios, false),
-    DEFINE_PROP_BOOL("iplbext_migration", S390IPLState, iplbext_migration,
-                     true),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static bool s390_gen_initial_iplb(S390IPLState *ipl)
+/*
+ * In addition to updating the iplstate, this function returns:
+ * - 0 if system was ipled with external kernel
+ * - -1 if no valid boot device was found
+ * - ccw id of the boot device otherwise
+ */
+static uint64_t s390_update_iplstate(S390IPLState *ipl)
 {
     DeviceState *dev_st;
 
+    if (ipl->iplb_valid) {
+        ipl->cssid = 0;
+        ipl->ssid = 0;
+        ipl->devno = ipl->iplb.devno;
+        goto out;
+    }
+
+    if (ipl->kernel) {
+        return 0;
+    }
+
     dev_st = get_boot_device(0);
     if (dev_st) {
-        VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
-            object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
+        VirtioCcwDevice *ccw_dev = (VirtioCcwDevice *) object_dynamic_cast(
+            OBJECT(qdev_get_parent_bus(dev_st)->parent),
                 TYPE_VIRTIO_CCW_DEVICE);
-        SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st),
-                                                            TYPE_SCSI_DEVICE);
-        if (virtio_ccw_dev) {
-            CcwDevice *ccw_dev = CCW_DEVICE(virtio_ccw_dev);
-
-            ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
-            ipl->iplb.blk0_len =
-                cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN);
-            ipl->iplb.pbt = S390_IPL_TYPE_CCW;
-            ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
-            ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
-            return true;
-        } else if (sd) {
-            SCSIBus *bus = scsi_bus_from_device(sd);
-            VirtIOSCSI *vdev = container_of(bus, VirtIOSCSI, bus);
-            VirtIOSCSICcw *scsi_ccw = container_of(vdev, VirtIOSCSICcw, vdev);
-            CcwDevice *ccw_dev = CCW_DEVICE(scsi_ccw);
-
-            ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
-            ipl->iplb.blk0_len =
-                cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN);
-            ipl->iplb.pbt = S390_IPL_TYPE_QEMU_SCSI;
-            ipl->iplb.scsi.lun = cpu_to_be32(sd->lun);
-            ipl->iplb.scsi.target = cpu_to_be16(sd->id);
-            ipl->iplb.scsi.channel = cpu_to_be16(sd->channel);
-            ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
-            ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
-            return true;
+        if (ccw_dev) {
+            ipl->cssid = ccw_dev->sch->cssid;
+            ipl->ssid = ccw_dev->sch->ssid;
+            ipl->devno = ccw_dev->sch->devno;
+            goto out;
         }
     }
 
-    return false;
+    return -1;
+out:
+    return (uint32_t) (ipl->cssid << 24 | ipl->ssid << 16 | ipl->devno);
 }
 
 void s390_ipl_update_diag308(IplParameterBlock *iplb)
@@ -293,9 +265,7 @@ void s390_ipl_prepare_cpu(S390CPU *cpu)
 
     if (!ipl->kernel || ipl->iplb_valid) {
         cpu->env.psw.addr = ipl->bios_start_addr;
-        if (!ipl->iplb_valid) {
-            ipl->iplb_valid = s390_gen_initial_iplb(ipl);
-        }
+        cpu->env.regs[7] = s390_update_iplstate(ipl);
     }
 }
 
@@ -305,7 +275,6 @@ static void s390_ipl_reset(DeviceState *dev)
 
     if (!ipl->reipl_requested) {
         ipl->iplb_valid = false;
-        memset(&ipl->iplb, 0, sizeof(IplParameterBlock));
     }
     ipl->reipl_requested = false;
 }
index c891095..0bfb72b 100644 (file)
 #include "hw/qdev.h"
 #include "cpu.h"
 
-struct IplBlockCcw {
-    uint8_t  reserved0[85];
-    uint8_t  ssid;
-    uint16_t devno;
-    uint8_t  vm_flags;
-    uint8_t  reserved3[3];
-    uint32_t vm_parm_len;
-    uint8_t  nss_name[8];
-    uint8_t  vm_parm[64];
-    uint8_t  reserved4[8];
-} QEMU_PACKED;
-typedef struct IplBlockCcw IplBlockCcw;
-
-struct IplBlockFcp {
-    uint8_t  reserved1[305 - 1];
-    uint8_t  opt;
-    uint8_t  reserved2[3];
-    uint16_t reserved3;
-    uint16_t devno;
-    uint8_t  reserved4[4];
-    uint64_t wwpn;
-    uint64_t lun;
-    uint32_t bootprog;
-    uint8_t  reserved5[12];
-    uint64_t br_lba;
-    uint32_t scp_data_len;
-    uint8_t  reserved6[260];
-    uint8_t  scp_data[];
-} QEMU_PACKED;
-typedef struct IplBlockFcp IplBlockFcp;
-
-struct IplBlockQemuScsi {
-    uint32_t lun;
-    uint16_t target;
-    uint16_t channel;
-    uint8_t  reserved0[77];
-    uint8_t  ssid;
-    uint16_t devno;
-} QEMU_PACKED;
-typedef struct IplBlockQemuScsi IplBlockQemuScsi;
-
-union IplParameterBlock {
-    struct {
-        uint32_t len;
-        uint8_t  reserved0[3];
-        uint8_t  version;
-        uint32_t blk0_len;
-        uint8_t  pbt;
-        uint8_t  flags;
-        uint16_t reserved01;
-        uint8_t  loadparm[8];
-        union {
-            IplBlockCcw ccw;
-            IplBlockFcp fcp;
-            IplBlockQemuScsi scsi;
-        };
-    } QEMU_PACKED;
-    struct {
-        uint8_t  reserved1[110];
-        uint16_t devno;
-        uint8_t  reserved2[88];
-        uint8_t  reserved_ext[4096 - 200];
-    } QEMU_PACKED;
-} QEMU_PACKED;
-typedef union IplParameterBlock IplParameterBlock;
+typedef struct IplParameterBlock {
+      uint8_t  reserved1[110];
+      uint16_t devno;
+      uint8_t  reserved2[88];
+} IplParameterBlock;
 
 void s390_ipl_update_diag308(IplParameterBlock *iplb);
 void s390_ipl_prepare_cpu(S390CPU *cpu);
@@ -109,34 +49,7 @@ struct S390IPLState {
     uint8_t cssid;
     uint8_t ssid;
     uint16_t devno;
-    bool iplbext_migration;
 };
 typedef struct S390IPLState S390IPLState;
 
-#define S390_IPL_TYPE_FCP 0x00
-#define S390_IPL_TYPE_CCW 0x02
-#define S390_IPL_TYPE_QEMU_SCSI 0xff
-
-#define S390_IPLB_HEADER_LEN 8
-#define S390_IPLB_MIN_CCW_LEN 200
-#define S390_IPLB_MIN_FCP_LEN 384
-#define S390_IPLB_MIN_QEMU_SCSI_LEN 200
-
-static inline bool iplb_valid_len(IplParameterBlock *iplb)
-{
-    return be32_to_cpu(iplb->len) <= sizeof(IplParameterBlock);
-}
-
-static inline bool iplb_valid_ccw(IplParameterBlock *iplb)
-{
-    return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN &&
-           iplb->pbt == S390_IPL_TYPE_CCW;
-}
-
-static inline bool iplb_valid_fcp(IplParameterBlock *iplb)
-{
-    return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN &&
-           iplb->pbt == S390_IPL_TYPE_FCP;
-}
-
 #endif
index 9c1c04e..918b585 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qapi/visitor.h"
 #include "qemu-common.h"
 #include "cpu.h"
 #include "s390-pci-bus.h"
-#include "s390-pci-inst.h"
-#include "hw/pci/pci_bus.h"
-#include "hw/pci/msi.h"
-#include "qemu/error-report.h"
+#include <hw/pci/pci_bus.h>
+#include <hw/pci/msi.h>
+#include <qemu/error-report.h>
 
 /* #define DEBUG_S390PCI_BUS */
 #ifdef DEBUG_S390PCI_BUS
     do { } while (0)
 #endif
 
-static S390pciState *s390_get_phb(void)
-{
-    static S390pciState *phb;
-
-    if (!phb) {
-        phb = S390_PCI_HOST_BRIDGE(
-            object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
-        assert(phb != NULL);
-    }
-
-    return phb;
-}
-
 int chsc_sei_nt2_get_event(void *res)
 {
     ChscSeiNt2Res *nt2_res = (ChscSeiNt2Res *)res;
@@ -51,7 +35,12 @@ int chsc_sei_nt2_get_event(void *res)
     PciCcdfErr *eccdf;
     int rc = 1;
     SeiContainer *sei_cont;
-    S390pciState *s = s390_get_phb();
+    S390pciState *s = S390_PCI_HOST_BRIDGE(
+        object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
+
+    if (!s) {
+        return rc;
+    }
 
     sei_cont = QTAILQ_FIRST(&s->pending_sei);
     if (sei_cont) {
@@ -86,40 +75,30 @@ int chsc_sei_nt2_get_event(void *res)
 
 int chsc_sei_nt2_have_event(void)
 {
-    S390pciState *s = s390_get_phb();
-
-    return !QTAILQ_EMPTY(&s->pending_sei);
-}
+    S390pciState *s = S390_PCI_HOST_BRIDGE(
+        object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
 
-S390PCIBusDevice *s390_pci_find_next_avail_dev(S390PCIBusDevice *pbdev)
-{
-    int idx = 0;
-    S390PCIBusDevice *dev = NULL;
-    S390pciState *s = s390_get_phb();
-
-    if (pbdev) {
-        idx = (pbdev->fh & FH_MASK_INDEX) + 1;
-    }
-
-    for (; idx < PCI_SLOT_MAX; idx++) {
-        dev = s->pbdev[idx];
-        if (dev && dev->state != ZPCI_FS_RESERVED) {
-            return dev;
-        }
+    if (!s) {
+        return 0;
     }
 
-    return NULL;
+    return !QTAILQ_EMPTY(&s->pending_sei);
 }
 
 S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid)
 {
     S390PCIBusDevice *pbdev;
     int i;
-    S390pciState *s = s390_get_phb();
+    S390pciState *s = S390_PCI_HOST_BRIDGE(
+        object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
+
+    if (!s) {
+        return NULL;
+    }
 
     for (i = 0; i < PCI_SLOT_MAX; i++) {
-        pbdev = s->pbdev[i];
-        if (pbdev && pbdev->fid == fid) {
+        pbdev = &s->pbdev[i];
+        if ((pbdev->fh != 0) && (pbdev->fid == fid)) {
             return pbdev;
         }
     }
@@ -127,139 +106,82 @@ S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid)
     return NULL;
 }
 
-void s390_pci_sclp_configure(SCCB *sccb)
+void s390_pci_sclp_configure(int configure, SCCB *sccb)
 {
     PciCfgSccb *psccb = (PciCfgSccb *)sccb;
     S390PCIBusDevice *pbdev = s390_pci_find_dev_by_fid(be32_to_cpu(psccb->aid));
     uint16_t rc;
 
-    if (be16_to_cpu(sccb->h.length) < 16) {
-        rc = SCLP_RC_INSUFFICIENT_SCCB_LENGTH;
-        goto out;
-    }
-
-    if (!pbdev) {
-        DPRINTF("sclp config no dev found\n");
+    if (pbdev) {
+        if ((configure == 1 && pbdev->configured == true) ||
+            (configure == 0 && pbdev->configured == false)) {
+            rc = SCLP_RC_NO_ACTION_REQUIRED;
+        } else {
+            pbdev->configured = !pbdev->configured;
+            rc = SCLP_RC_NORMAL_COMPLETION;
+        }
+    } else {
+        DPRINTF("sclp config %d no dev found\n", configure);
         rc = SCLP_RC_ADAPTER_ID_NOT_RECOGNIZED;
-        goto out;
     }
 
-    switch (pbdev->state) {
-    case ZPCI_FS_RESERVED:
-        rc = SCLP_RC_ADAPTER_IN_RESERVED_STATE;
-        break;
-    case ZPCI_FS_STANDBY:
-        pbdev->state = ZPCI_FS_DISABLED;
-        rc = SCLP_RC_NORMAL_COMPLETION;
-        break;
-    default:
-        rc = SCLP_RC_NO_ACTION_REQUIRED;
-    }
-out:
     psccb->header.response_code = cpu_to_be16(rc);
 }
 
-void s390_pci_sclp_deconfigure(SCCB *sccb)
+static uint32_t s390_pci_get_pfid(PCIDevice *pdev)
 {
-    PciCfgSccb *psccb = (PciCfgSccb *)sccb;
-    S390PCIBusDevice *pbdev = s390_pci_find_dev_by_fid(be32_to_cpu(psccb->aid));
-    uint16_t rc;
-
-    if (be16_to_cpu(sccb->h.length) < 16) {
-        rc = SCLP_RC_INSUFFICIENT_SCCB_LENGTH;
-        goto out;
-    }
-
-    if (!pbdev) {
-        DPRINTF("sclp deconfig no dev found\n");
-        rc = SCLP_RC_ADAPTER_ID_NOT_RECOGNIZED;
-        goto out;
-    }
-
-    switch (pbdev->state) {
-    case ZPCI_FS_RESERVED:
-        rc = SCLP_RC_ADAPTER_IN_RESERVED_STATE;
-        break;
-    case ZPCI_FS_STANDBY:
-        rc = SCLP_RC_NO_ACTION_REQUIRED;
-        break;
-    default:
-        if (pbdev->summary_ind) {
-            pci_dereg_irqs(pbdev);
-        }
-        if (pbdev->iommu_enabled) {
-            pci_dereg_ioat(pbdev);
-        }
-        pbdev->state = ZPCI_FS_STANDBY;
-        rc = SCLP_RC_NORMAL_COMPLETION;
-
-        if (pbdev->release_timer) {
-            qdev_unplug(DEVICE(pbdev->pdev), NULL);
-        }
-    }
-out:
-    psccb->header.response_code = cpu_to_be16(rc);
+    return PCI_SLOT(pdev->devfn);
 }
 
-static S390PCIBusDevice *s390_pci_find_dev_by_uid(uint16_t uid)
+static uint32_t s390_pci_get_pfh(PCIDevice *pdev)
 {
-    int i;
-    S390PCIBusDevice *pbdev;
-    S390pciState *s = s390_get_phb();
-
-    for (i = 0; i < PCI_SLOT_MAX; i++) {
-        pbdev = s->pbdev[i];
-        if (!pbdev) {
-            continue;
-        }
-
-        if (pbdev->uid == uid) {
-            return pbdev;
-        }
-    }
-
-    return NULL;
+    return PCI_SLOT(pdev->devfn) | FH_VIRT;
 }
 
-static S390PCIBusDevice *s390_pci_find_dev_by_target(const char *target)
+S390PCIBusDevice *s390_pci_find_dev_by_idx(uint32_t idx)
 {
-    int i;
     S390PCIBusDevice *pbdev;
-    S390pciState *s = s390_get_phb();
+    int i;
+    int j = 0;
+    S390pciState *s = S390_PCI_HOST_BRIDGE(
+        object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
 
-    if (!target) {
+    if (!s) {
         return NULL;
     }
 
     for (i = 0; i < PCI_SLOT_MAX; i++) {
-        pbdev = s->pbdev[i];
-        if (!pbdev) {
+        pbdev = &s->pbdev[i];
+
+        if (pbdev->fh == 0) {
             continue;
         }
 
-        if (!strcmp(pbdev->target, target)) {
+        if (j == idx) {
             return pbdev;
         }
+        j++;
     }
 
     return NULL;
 }
 
-S390PCIBusDevice *s390_pci_find_dev_by_idx(uint32_t idx)
-{
-    S390pciState *s = s390_get_phb();
-
-    return s->pbdev[idx & FH_MASK_INDEX];
-}
-
 S390PCIBusDevice *s390_pci_find_dev_by_fh(uint32_t fh)
 {
-    S390pciState *s = s390_get_phb();
     S390PCIBusDevice *pbdev;
+    int i;
+    S390pciState *s = S390_PCI_HOST_BRIDGE(
+        object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
 
-    pbdev = s->pbdev[fh & FH_MASK_INDEX];
-    if (pbdev && pbdev->fh == fh) {
-        return pbdev;
+    if (!s || !fh) {
+        return NULL;
+    }
+
+    for (i = 0; i < PCI_SLOT_MAX; i++) {
+        pbdev = &s->pbdev[i];
+        if (pbdev->fh == fh) {
+            return pbdev;
+        }
     }
 
     return NULL;
@@ -269,7 +191,12 @@ static void s390_pci_generate_event(uint8_t cc, uint16_t pec, uint32_t fh,
                                     uint32_t fid, uint64_t faddr, uint32_t e)
 {
     SeiContainer *sei_cont;
-    S390pciState *s = s390_get_phb();
+    S390pciState *s = S390_PCI_HOST_BRIDGE(
+        object_resolve_path(TYPE_S390_PCI_HOST_BRIDGE, NULL));
+
+    if (!s) {
+        return;
+    }
 
     sei_cont = g_malloc0(sizeof(SeiContainer));
     sei_cont->fh = fh;
@@ -289,8 +216,9 @@ static void s390_pci_generate_plug_event(uint16_t pec, uint32_t fh,
     s390_pci_generate_event(2, pec, fh, fid, 0, 0);
 }
 
-void s390_pci_generate_error_event(uint16_t pec, uint32_t fh, uint32_t fid,
-                                   uint64_t faddr, uint32_t e)
+static void s390_pci_generate_error_event(uint16_t pec, uint32_t fh,
+                                          uint32_t fid, uint64_t faddr,
+                                          uint32_t e)
 {
     s390_pci_generate_event(1, pec, fh, fid, faddr, e);
 }
@@ -392,14 +320,7 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *iommu, hwaddr addr,
         .perm = IOMMU_NONE,
     };
 
-    switch (pbdev->state) {
-    case ZPCI_FS_ENABLED:
-    case ZPCI_FS_BLOCKED:
-        if (!pbdev->iommu_enabled) {
-            return ret;
-        }
-        break;
-    default:
+    if (!pbdev->configured || !pbdev->pdev || !(pbdev->fh & FH_ENABLED)) {
         return ret;
     }
 
@@ -418,13 +339,30 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *iommu, hwaddr addr,
         return ret;
     }
 
+    if (!pbdev->g_iota) {
+        pbdev->error_state = true;
+        pbdev->lgstg_blocked = true;
+        s390_pci_generate_error_event(ERR_EVENT_INVALAS, pbdev->fh, pbdev->fid,
+                                      addr, 0);
+        return ret;
+    }
+
     if (addr < pbdev->pba || addr > pbdev->pal) {
+        pbdev->error_state = true;
+        pbdev->lgstg_blocked = true;
+        s390_pci_generate_error_event(ERR_EVENT_OORANGE, pbdev->fh, pbdev->fid,
+                                      addr, 0);
         return ret;
     }
 
     pte = s390_guest_io_table_walk(s390_pci_get_table_origin(pbdev->g_iota),
                                    addr);
+
     if (!pte) {
+        pbdev->error_state = true;
+        pbdev->lgstg_blocked = true;
+        s390_pci_generate_error_event(ERR_EVENT_SERR, pbdev->fh, pbdev->fid,
+                                      addr, ERR_EVENT_Q_BIT);
         return ret;
     }
 
@@ -450,7 +388,7 @@ static AddressSpace *s390_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
 {
     S390pciState *s = opaque;
 
-    return &s->iommu[PCI_SLOT(devfn)]->as;
+    return &s->pbdev[PCI_SLOT(devfn)].as;
 }
 
 static uint8_t set_ind_atomic(uint64_t ind_loc, uint8_t to_be_set)
@@ -478,22 +416,22 @@ static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,
 {
     S390PCIBusDevice *pbdev;
     uint32_t io_int_word;
-    uint32_t idx = data >> ZPCI_MSI_VEC_BITS;
+    uint32_t fid = data >> ZPCI_MSI_VEC_BITS;
     uint32_t vec = data & ZPCI_MSI_VEC_MASK;
     uint64_t ind_bit;
     uint32_t sum_bit;
     uint32_t e = 0;
 
-    DPRINTF("write_msix data 0x%" PRIx64 " idx %d vec 0x%x\n", data, idx, vec);
+    DPRINTF("write_msix data 0x%" PRIx64 " fid %d vec 0x%x\n", data, fid, vec);
 
-    pbdev = s390_pci_find_dev_by_idx(idx);
+    pbdev = s390_pci_find_dev_by_fid(fid);
     if (!pbdev) {
         e |= (vec << ERR_EVENT_MVN_OFFSET);
-        s390_pci_generate_error_event(ERR_EVENT_NOMSI, idx, 0, addr, e);
+        s390_pci_generate_error_event(ERR_EVENT_NOMSI, 0, fid, addr, e);
         return;
     }
 
-    if (pbdev->state != ZPCI_FS_ENABLED) {
+    if (!(pbdev->fh & FH_ENABLED)) {
         return;
     }
 
@@ -520,33 +458,32 @@ static const MemoryRegionOps s390_msi_ctrl_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-void s390_pci_iommu_enable(S390PCIBusDevice *pbdev)
+void s390_pcihost_iommu_configure(S390PCIBusDevice *pbdev, bool enable)
 {
-    memory_region_init_iommu(&pbdev->iommu_mr, OBJECT(&pbdev->iommu->mr),
-                             &s390_iommu_ops, "iommu-s390", pbdev->pal + 1);
-    memory_region_add_subregion(&pbdev->iommu->mr, 0, &pbdev->iommu_mr);
-    pbdev->iommu_enabled = true;
-}
+    pbdev->configured = false;
 
-void s390_pci_iommu_disable(S390PCIBusDevice *pbdev)
-{
-    memory_region_del_subregion(&pbdev->iommu->mr, &pbdev->iommu_mr);
-    object_unparent(OBJECT(&pbdev->iommu_mr));
-    pbdev->iommu_enabled = false;
+    if (enable) {
+        uint64_t size = pbdev->pal - pbdev->pba + 1;
+        memory_region_init_iommu(&pbdev->iommu_mr, OBJECT(&pbdev->mr),
+                                 &s390_iommu_ops, "iommu-s390", size);
+        memory_region_add_subregion(&pbdev->mr, pbdev->pba, &pbdev->iommu_mr);
+    } else {
+        memory_region_del_subregion(&pbdev->mr, &pbdev->iommu_mr);
+    }
+
+    pbdev->configured = true;
 }
 
 static void s390_pcihost_init_as(S390pciState *s)
 {
     int i;
-    S390PCIIOMMU *iommu;
+    S390PCIBusDevice *pbdev;
 
     for (i = 0; i < PCI_SLOT_MAX; i++) {
-        iommu = g_malloc0(sizeof(S390PCIIOMMU));
-        memory_region_init(&iommu->mr, OBJECT(s),
+        pbdev = &s->pbdev[i];
+        memory_region_init(&pbdev->mr, OBJECT(s),
                            "iommu-root-s390", UINT64_MAX);
-        address_space_init(&iommu->as, &iommu->mr, "iommu-pci");
-
-        s->iommu[i] = iommu;
+        address_space_init(&pbdev->as, &pbdev->mr, "iommu-pci");
     }
 
     memory_region_init_io(&s->msix_notify_mr, OBJECT(s),
@@ -573,10 +510,6 @@ static int s390_pcihost_init(SysBusDevice *dev)
     bus = BUS(b);
     qbus_set_hotplug_handler(bus, DEVICE(dev), NULL);
     phb->bus = b;
-
-    s->bus = S390_PCI_BUS(qbus_create(TYPE_S390_PCI_BUS, DEVICE(s), NULL));
-    qbus_set_hotplug_handler(BUS(s->bus), DEVICE(s), NULL);
-
     QTAILQ_INIT(&s->pending_sei);
     return 0;
 }
@@ -609,155 +542,51 @@ static int s390_pcihost_setup_msix(S390PCIBusDevice *pbdev)
     return 0;
 }
 
-static S390PCIBusDevice *s390_pci_device_new(const char *target)
-{
-    DeviceState *dev = NULL;
-    S390pciState *s = s390_get_phb();
-
-    dev = qdev_try_create(BUS(s->bus), TYPE_S390_PCI_DEVICE);
-    if (!dev) {
-        return NULL;
-    }
-
-    qdev_prop_set_string(dev, "target", target);
-    qdev_init_nofail(dev);
-
-    return S390_PCI_DEVICE(dev);
-}
-
 static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
                                   DeviceState *dev, Error **errp)
 {
-    PCIDevice *pdev = NULL;
-    S390PCIBusDevice *pbdev = NULL;
-    S390pciState *s = s390_get_phb();
-
-    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
-        pdev = PCI_DEVICE(dev);
-
-        if (!dev->id) {
-            /* In the case the PCI device does not define an id */
-            /* we generate one based on the PCI address         */
-            dev->id = g_strdup_printf("auto_%02x:%02x.%01x",
-                                      pci_bus_num(pdev->bus),
-                                      PCI_SLOT(pdev->devfn),
-                                      PCI_FUNC(pdev->devfn));
-        }
-
-        pbdev = s390_pci_find_dev_by_target(dev->id);
-        if (!pbdev) {
-            pbdev = s390_pci_device_new(dev->id);
-            if (!pbdev) {
-                error_setg(errp, "create zpci device failed");
-            }
-        }
-
-        if (object_dynamic_cast(OBJECT(dev), "vfio-pci")) {
-            pbdev->fh |= FH_SHM_VFIO;
-        } else {
-            pbdev->fh |= FH_SHM_EMUL;
-        }
+    PCIDevice *pci_dev = PCI_DEVICE(dev);
+    S390PCIBusDevice *pbdev;
+    S390pciState *s = S390_PCI_HOST_BRIDGE(pci_device_root_bus(pci_dev)
+                                           ->qbus.parent);
 
-        pbdev->pdev = pdev;
-        pbdev->iommu = s->iommu[PCI_SLOT(pdev->devfn)];
-        pbdev->state = ZPCI_FS_STANDBY;
-        s390_pcihost_setup_msix(pbdev);
+    pbdev = &s->pbdev[PCI_SLOT(pci_dev->devfn)];
 
-        if (dev->hotplugged) {
-            s390_pci_generate_plug_event(HP_EVENT_RESERVED_TO_STANDBY,
-                                         pbdev->fh, pbdev->fid);
-        }
-    } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {
-        int idx;
-
-        pbdev = S390_PCI_DEVICE(dev);
-        for (idx = 0; idx < PCI_SLOT_MAX; idx++) {
-            if (!s->pbdev[idx]) {
-                s->pbdev[idx] = pbdev;
-                pbdev->fh = idx;
-                return;
-            }
-        }
+    pbdev->fid = s390_pci_get_pfid(pci_dev);
+    pbdev->pdev = pci_dev;
+    pbdev->configured = true;
+    pbdev->fh = s390_pci_get_pfh(pci_dev);
 
-        error_setg(errp, "no slot for plugging zpci device");
-    }
-}
-
-static void s390_pcihost_timer_cb(void *opaque)
-{
-    S390PCIBusDevice *pbdev = opaque;
+    s390_pcihost_setup_msix(pbdev);
 
-    if (pbdev->summary_ind) {
-        pci_dereg_irqs(pbdev);
-    }
-    if (pbdev->iommu_enabled) {
-        pci_dereg_ioat(pbdev);
+    if (dev->hotplugged) {
+        s390_pci_generate_plug_event(HP_EVENT_RESERVED_TO_STANDBY,
+                                     pbdev->fh, pbdev->fid);
+        s390_pci_generate_plug_event(HP_EVENT_TO_CONFIGURED,
+                                     pbdev->fh, pbdev->fid);
     }
-
-    pbdev->state = ZPCI_FS_STANDBY;
-    s390_pci_generate_plug_event(HP_EVENT_CONFIGURED_TO_STBRES,
-                                 pbdev->fh, pbdev->fid);
-    qdev_unplug(DEVICE(pbdev), NULL);
 }
 
 static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
                                     DeviceState *dev, Error **errp)
 {
-    int i;
-    PCIDevice *pci_dev = NULL;
-    S390PCIBusDevice *pbdev = NULL;
-    S390pciState *s = s390_get_phb();
-
-    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
-        pci_dev = PCI_DEVICE(dev);
-
-        for (i = 0 ; i < PCI_SLOT_MAX; i++) {
-            if (s->pbdev[i] && s->pbdev[i]->pdev == pci_dev) {
-                pbdev = s->pbdev[i];
-                break;
-            }
-        }
+    PCIDevice *pci_dev = PCI_DEVICE(dev);
+    S390pciState *s = S390_PCI_HOST_BRIDGE(pci_device_root_bus(pci_dev)
+                                           ->qbus.parent);
+    S390PCIBusDevice *pbdev = &s->pbdev[PCI_SLOT(pci_dev->devfn)];
 
-        if (!pbdev) {
-            object_unparent(OBJECT(pci_dev));
-            return;
-        }
-    } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {
-        pbdev = S390_PCI_DEVICE(dev);
-        pci_dev = pbdev->pdev;
-    }
-
-    switch (pbdev->state) {
-    case ZPCI_FS_RESERVED:
-        goto out;
-    case ZPCI_FS_STANDBY:
-        break;
-    default:
-        s390_pci_generate_plug_event(HP_EVENT_DECONFIGURE_REQUEST,
+    if (pbdev->configured) {
+        pbdev->configured = false;
+        s390_pci_generate_plug_event(HP_EVENT_CONFIGURED_TO_STBRES,
                                      pbdev->fh, pbdev->fid);
-        pbdev->release_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
-                                            s390_pcihost_timer_cb,
-                                            pbdev);
-        timer_mod(pbdev->release_timer,
-                  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + HOT_UNPLUG_TIMEOUT);
-        return;
-    }
-
-    if (pbdev->release_timer && timer_pending(pbdev->release_timer)) {
-        timer_del(pbdev->release_timer);
-        timer_free(pbdev->release_timer);
-        pbdev->release_timer = NULL;
     }
 
     s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,
                                  pbdev->fh, pbdev->fid);
-    object_unparent(OBJECT(pci_dev));
-    pbdev->pdev = NULL;
-    pbdev->state = ZPCI_FS_RESERVED;
-out:
+    pbdev->fh = 0;
     pbdev->fid = 0;
-    s->pbdev[pbdev->fh & FH_MASK_INDEX] = NULL;
-    object_unparent(OBJECT(pbdev));
+    pbdev->pdev = NULL;
+    object_unparent(OBJECT(pci_dev));
 }
 
 static void s390_pcihost_class_init(ObjectClass *klass, void *data)
@@ -784,178 +613,9 @@ static const TypeInfo s390_pcihost_info = {
     }
 };
 
-static const TypeInfo s390_pcibus_info = {
-    .name = TYPE_S390_PCI_BUS,
-    .parent = TYPE_BUS,
-    .instance_size = sizeof(S390PCIBus),
-};
-
-static uint16_t s390_pci_generate_uid(void)
-{
-    uint16_t uid = 0;
-
-    do {
-        uid++;
-        if (!s390_pci_find_dev_by_uid(uid)) {
-            return uid;
-        }
-    } while (uid < ZPCI_MAX_UID);
-
-    return UID_UNDEFINED;
-}
-
-static uint32_t s390_pci_generate_fid(Error **errp)
-{
-    uint32_t fid = 0;
-
-    while (fid <= ZPCI_MAX_FID) {
-        if (!s390_pci_find_dev_by_fid(fid)) {
-            return fid;
-        }
-
-        if (fid == ZPCI_MAX_FID) {
-            break;
-        }
-
-        fid++;
-    }
-
-    error_setg(errp, "no free fid could be found");
-    return 0;
-}
-
-static void s390_pci_device_realize(DeviceState *dev, Error **errp)
-{
-    S390PCIBusDevice *zpci = S390_PCI_DEVICE(dev);
-
-    if (!zpci->target) {
-        error_setg(errp, "target must be defined");
-        return;
-    }
-
-    if (s390_pci_find_dev_by_target(zpci->target)) {
-        error_setg(errp, "target %s already has an associated zpci device",
-                   zpci->target);
-        return;
-    }
-
-    if (zpci->uid == UID_UNDEFINED) {
-        zpci->uid = s390_pci_generate_uid();
-        if (!zpci->uid) {
-            error_setg(errp, "no free uid could be found");
-            return;
-        }
-    } else if (s390_pci_find_dev_by_uid(zpci->uid)) {
-        error_setg(errp, "uid %u already in use", zpci->uid);
-        return;
-    }
-
-    if (!zpci->fid_defined) {
-        Error *local_error = NULL;
-
-        zpci->fid = s390_pci_generate_fid(&local_error);
-        if (local_error) {
-            error_propagate(errp, local_error);
-            return;
-        }
-    } else if (s390_pci_find_dev_by_fid(zpci->fid)) {
-        error_setg(errp, "fid %u already in use", zpci->fid);
-        return;
-    }
-
-    zpci->state = ZPCI_FS_RESERVED;
-}
-
-static void s390_pci_device_reset(DeviceState *dev)
-{
-    S390PCIBusDevice *pbdev = S390_PCI_DEVICE(dev);
-
-    switch (pbdev->state) {
-    case ZPCI_FS_RESERVED:
-        return;
-    case ZPCI_FS_STANDBY:
-        break;
-    default:
-        pbdev->fh &= ~FH_MASK_ENABLE;
-        pbdev->state = ZPCI_FS_DISABLED;
-        break;
-    }
-
-    if (pbdev->summary_ind) {
-        pci_dereg_irqs(pbdev);
-    }
-    if (pbdev->iommu_enabled) {
-        pci_dereg_ioat(pbdev);
-    }
-
-    pbdev->fmb_addr = 0;
-}
-
-static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(DEVICE(obj), prop);
-
-    visit_type_uint32(v, name, ptr, errp);
-}
-
-static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
-    Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
-    visit_type_uint32(v, name, ptr, errp);
-    zpci->fid_defined = true;
-}
-
-static PropertyInfo s390_pci_fid_propinfo = {
-    .name = "zpci_fid",
-    .get = s390_pci_get_fid,
-    .set = s390_pci_set_fid,
-};
-
-#define DEFINE_PROP_S390_PCI_FID(_n, _s, _f) \
-    DEFINE_PROP(_n, _s, _f, s390_pci_fid_propinfo, uint32_t)
-
-static Property s390_pci_device_properties[] = {
-    DEFINE_PROP_UINT16("uid", S390PCIBusDevice, uid, UID_UNDEFINED),
-    DEFINE_PROP_S390_PCI_FID("fid", S390PCIBusDevice, fid),
-    DEFINE_PROP_STRING("target", S390PCIBusDevice, target),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void s390_pci_device_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-
-    dc->desc = "zpci device";
-    dc->reset = s390_pci_device_reset;
-    dc->bus_type = TYPE_S390_PCI_BUS;
-    dc->realize = s390_pci_device_realize;
-    dc->props = s390_pci_device_properties;
-}
-
-static const TypeInfo s390_pci_device_info = {
-    .name = TYPE_S390_PCI_DEVICE,
-    .parent = TYPE_DEVICE,
-    .instance_size = sizeof(S390PCIBusDevice),
-    .class_init = s390_pci_device_class_init,
-};
-
 static void s390_pci_register_types(void)
 {
     type_register_static(&s390_pcihost_info);
-    type_register_static(&s390_pcibus_info);
-    type_register_static(&s390_pci_device_info);
 }
 
 type_init(s390_pci_register_types)
index 4f564e0..59fd5c9 100644 (file)
 #ifndef HW_S390_PCI_BUS_H
 #define HW_S390_PCI_BUS_H
 
-#include "hw/pci/pci.h"
-#include "hw/pci/pci_host.h"
+#include <hw/pci/pci.h>
+#include <hw/pci/pci_host.h>
 #include "hw/s390x/sclp.h"
 #include "hw/s390x/s390_flic.h"
 #include "hw/s390x/css.h"
 
 #define TYPE_S390_PCI_HOST_BRIDGE "s390-pcihost"
-#define TYPE_S390_PCI_BUS "s390-pcibus"
-#define TYPE_S390_PCI_DEVICE "zpci"
-#define FH_MASK_ENABLE   0x80000000
-#define FH_MASK_INSTANCE 0x7f000000
-#define FH_MASK_SHM      0x00ff0000
-#define FH_MASK_INDEX    0x0000001f
-#define FH_SHM_VFIO      0x00010000
-#define FH_SHM_EMUL      0x00020000
+#define FH_VIRT 0x00ff0000
+#define ENABLE_BIT_OFFSET 31
+#define FH_ENABLED (1 << ENABLE_BIT_OFFSET)
 #define S390_PCIPT_ADAPTER 2
-#define ZPCI_MAX_FID 0xffffffff
-#define ZPCI_MAX_UID 0xffff
-#define UID_UNDEFINED 0
-#define UID_CHECKING_ENABLED 0x01
-#define HOT_UNPLUG_TIMEOUT (NANOSECONDS_PER_SECOND * 60 * 5)
 
 #define S390_PCI_HOST_BRIDGE(obj) \
     OBJECT_CHECK(S390pciState, (obj), TYPE_S390_PCI_HOST_BRIDGE)
-#define S390_PCI_BUS(obj) \
-    OBJECT_CHECK(S390PCIBus, (obj), TYPE_S390_PCI_BUS)
-#define S390_PCI_DEVICE(obj) \
-    OBJECT_CHECK(S390PCIBusDevice, (obj), TYPE_S390_PCI_DEVICE)
 
 #define HP_EVENT_TO_CONFIGURED        0x0301
 #define HP_EVENT_RESERVED_TO_STANDBY  0x0302
-#define HP_EVENT_DECONFIGURE_REQUEST  0x0303
 #define HP_EVENT_CONFIGURED_TO_STBRES 0x0304
 #define HP_EVENT_STANDBY_TO_RESERVED  0x0308
 
@@ -165,34 +150,6 @@ enum ZpciIoatDtype {
 #define ZPCI_TABLE_VALID_MASK           0x20
 #define ZPCI_TABLE_PROT_MASK            0x200
 
-/* PCI Function States
- *
- * reserved: default; device has just been plugged or is in progress of being
- *           unplugged
- * standby: device is present but not configured; transition from any
- *          configured state/to this state via sclp configure/deconfigure
- *
- * The following states make up the "configured" meta-state:
- * disabled: device is configured but not enabled; transition between this
- *           state and enabled via clp enable/disable
- * enbaled: device is ready for use; transition to disabled via clp disable;
- *          may enter an error state
- * blocked: ignore all DMA and interrupts; transition back to enabled or from
- *          error state via mpcifc
- * error: an error occured; transition back to enabled via mpcifc
- * permanent error: an unrecoverable error occured; transition to standby via
- *                  sclp deconfigure
- */
-typedef enum {
-    ZPCI_FS_RESERVED,
-    ZPCI_FS_STANDBY,
-    ZPCI_FS_DISABLED,
-    ZPCI_FS_ENABLED,
-    ZPCI_FS_BLOCKED,
-    ZPCI_FS_ERROR,
-    ZPCI_FS_PERMANENT_ERROR,
-} ZpciState;
-
 typedef struct SeiContainer {
     QTAILQ_ENTRY(SeiContainer) link;
     uint32_t fid;
@@ -241,11 +198,11 @@ typedef struct ChscSeiNt2Res {
 } QEMU_PACKED ChscSeiNt2Res;
 
 typedef struct PciCfgSccb {
-    SCCBHeader header;
-    uint8_t atype;
-    uint8_t reserved1;
-    uint16_t reserved2;
-    uint32_t aid;
+        SCCBHeader header;
+        uint8_t atype;
+        uint8_t reserved1;
+        uint16_t reserved2;
+        uint32_t aid;
 } QEMU_PACKED PciCfgSccb;
 
 typedef struct S390MsixInfo {
@@ -257,21 +214,13 @@ typedef struct S390MsixInfo {
     uint32_t pba_offset;
 } S390MsixInfo;
 
-typedef struct S390PCIIOMMU {
-    AddressSpace as;
-    MemoryRegion mr;
-} S390PCIIOMMU;
-
 typedef struct S390PCIBusDevice {
-    DeviceState qdev;
     PCIDevice *pdev;
-    ZpciState state;
-    bool iommu_enabled;
-    char *target;
-    uint16_t uid;
+    bool configured;
+    bool error_state;
+    bool lgstg_blocked;
     uint32_t fh;
     uint32_t fid;
-    bool fid_defined;
     uint64_t g_iota;
     uint64_t pba;
     uint64_t pal;
@@ -281,22 +230,16 @@ typedef struct S390PCIBusDevice {
     uint8_t sum;
     S390MsixInfo msix;
     AdapterRoutes routes;
-    S390PCIIOMMU *iommu;
+    AddressSpace as;
+    MemoryRegion mr;
     MemoryRegion iommu_mr;
     IndAddr *summary_ind;
     IndAddr *indicator;
-    QEMUTimer *release_timer;
 } S390PCIBusDevice;
 
-typedef struct S390PCIBus {
-    BusState qbus;
-} S390PCIBus;
-
 typedef struct S390pciState {
     PCIHostState parent_obj;
-    S390PCIBus *bus;
-    S390PCIBusDevice *pbdev[PCI_SLOT_MAX];
-    S390PCIIOMMU *iommu[PCI_SLOT_MAX];
+    S390PCIBusDevice pbdev[PCI_SLOT_MAX];
     AddressSpace msix_notify_as;
     MemoryRegion msix_notify_mr;
     QTAILQ_HEAD(, SeiContainer) pending_sei;
@@ -304,15 +247,10 @@ typedef struct S390pciState {
 
 int chsc_sei_nt2_get_event(void *res);
 int chsc_sei_nt2_have_event(void);
-void s390_pci_sclp_configure(SCCB *sccb);
-void s390_pci_sclp_deconfigure(SCCB *sccb);
-void s390_pci_iommu_enable(S390PCIBusDevice *pbdev);
-void s390_pci_iommu_disable(S390PCIBusDevice *pbdev);
-void s390_pci_generate_error_event(uint16_t pec, uint32_t fh, uint32_t fid,
-                                   uint64_t faddr, uint32_t e);
+void s390_pci_sclp_configure(int configure, SCCB *sccb);
+void s390_pcihost_iommu_configure(S390PCIBusDevice *pbdev, bool enable);
 S390PCIBusDevice *s390_pci_find_dev_by_idx(uint32_t idx);
 S390PCIBusDevice *s390_pci_find_dev_by_fh(uint32_t fh);
 S390PCIBusDevice *s390_pci_find_dev_by_fid(uint32_t fid);
-S390PCIBusDevice *s390_pci_find_next_avail_dev(S390PCIBusDevice *pbdev);
 
 #endif
index f069b11..b28e7d1 100644 (file)
@@ -16,8 +16,8 @@
 #include "cpu.h"
 #include "s390-pci-inst.h"
 #include "s390-pci-bus.h"
-#include "exec/memory-internal.h"
-#include "qemu/error-report.h"
+#include <exec/memory-internal.h>
+#include <qemu/error-report.h>
 
 /* #define DEBUG_S390PCI_INST */
 #ifdef DEBUG_S390PCI_INST
@@ -37,9 +37,9 @@ static void s390_set_status_code(CPUS390XState *env,
 
 static int list_pci(ClpReqRspListPci *rrb, uint8_t *cc)
 {
-    S390PCIBusDevice *pbdev = NULL;
-    uint32_t res_code, initial_l2, g_l2;
-    int rc, i;
+    S390PCIBusDevice *pbdev;
+    uint32_t res_code, initial_l2, g_l2, finish;
+    int rc, idx;
     uint64_t resume_token;
 
     rc = 0;
@@ -56,7 +56,8 @@ static int list_pci(ClpReqRspListPci *rrb, uint8_t *cc)
     }
 
     if ((ldl_p(&rrb->request.fmt) & ~CLP_MASK_FMT) != 0 ||
-        ldq_p(&rrb->request.reserved1) != 0) {
+        ldq_p(&rrb->request.reserved1) != 0 ||
+        ldq_p(&rrb->request.reserved2) != 0) {
         res_code = CLP_RC_RESNOT0;
         rc = -EINVAL;
         goto out;
@@ -71,8 +72,6 @@ static int list_pci(ClpReqRspListPci *rrb, uint8_t *cc)
             rc = -EINVAL;
             goto out;
         }
-    } else {
-        pbdev = s390_pci_find_next_avail_dev(NULL);
     }
 
     if (lduw_p(&rrb->response.hdr.len) < 48) {
@@ -92,40 +91,43 @@ static int list_pci(ClpReqRspListPci *rrb, uint8_t *cc)
 
     stl_p(&rrb->response.fmt, 0);
     stq_p(&rrb->response.reserved1, 0);
-    stl_p(&rrb->response.mdd, FH_MASK_SHM);
+    stq_p(&rrb->response.reserved2, 0);
+    stl_p(&rrb->response.mdd, FH_VIRT);
     stw_p(&rrb->response.max_fn, PCI_MAX_FUNCTIONS);
-    rrb->response.flags = UID_CHECKING_ENABLED;
     rrb->response.entry_size = sizeof(ClpFhListEntry);
-
-    i = 0;
+    finish = 0;
+    idx = resume_token;
     g_l2 = LIST_PCI_HDR_LEN;
-    while (g_l2 < initial_l2 && pbdev) {
-        stw_p(&rrb->response.fh_list[i].device_id,
+    do {
+        pbdev = s390_pci_find_dev_by_idx(idx);
+        if (!pbdev) {
+            finish = 1;
+            break;
+        }
+        stw_p(&rrb->response.fh_list[idx - resume_token].device_id,
             pci_get_word(pbdev->pdev->config + PCI_DEVICE_ID));
-        stw_p(&rrb->response.fh_list[i].vendor_id,
+        stw_p(&rrb->response.fh_list[idx - resume_token].vendor_id,
             pci_get_word(pbdev->pdev->config + PCI_VENDOR_ID));
-        /* Ignore RESERVED devices. */
-        stl_p(&rrb->response.fh_list[i].config,
-            pbdev->state == ZPCI_FS_STANDBY ? 0 : 1 << 31);
-        stl_p(&rrb->response.fh_list[i].fid, pbdev->fid);
-        stl_p(&rrb->response.fh_list[i].fh, pbdev->fh);
+        stl_p(&rrb->response.fh_list[idx - resume_token].config,
+            pbdev->configured << 31);
+        stl_p(&rrb->response.fh_list[idx - resume_token].fid, pbdev->fid);
+        stl_p(&rrb->response.fh_list[idx - resume_token].fh, pbdev->fh);
 
         g_l2 += sizeof(ClpFhListEntry);
         /* Add endian check for DPRINTF? */
         DPRINTF("g_l2 %d vendor id 0x%x device id 0x%x fid 0x%x fh 0x%x\n",
-                g_l2,
-                lduw_p(&rrb->response.fh_list[i].vendor_id),
-                lduw_p(&rrb->response.fh_list[i].device_id),
-                ldl_p(&rrb->response.fh_list[i].fid),
-                ldl_p(&rrb->response.fh_list[i].fh));
-        pbdev = s390_pci_find_next_avail_dev(pbdev);
-        i++;
-    }
-
-    if (!pbdev) {
+            g_l2,
+            lduw_p(&rrb->response.fh_list[idx - resume_token].vendor_id),
+            lduw_p(&rrb->response.fh_list[idx - resume_token].device_id),
+            ldl_p(&rrb->response.fh_list[idx - resume_token].fid),
+            ldl_p(&rrb->response.fh_list[idx - resume_token].fh));
+        idx++;
+    } while (g_l2 < initial_l2);
+
+    if (finish == 1) {
         resume_token = 0;
     } else {
-        resume_token = pbdev->fh & FH_MASK_INDEX;
+        resume_token = idx;
     }
     stq_p(&rrb->response.resume_token, resume_token);
     stw_p(&rrb->response.hdr.len, g_l2);
@@ -210,35 +212,14 @@ int clp_service_call(S390CPU *cpu, uint8_t r2)
 
         switch (reqsetpci->oc) {
         case CLP_SET_ENABLE_PCI_FN:
-            switch (reqsetpci->ndas) {
-            case 0:
-                stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_DMAAS);
-                goto out;
-            case 1:
-                break;
-            default:
-                stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_RES);
-                goto out;
-            }
-
-            if (pbdev->fh & FH_MASK_ENABLE) {
-                stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP);
-                goto out;
-            }
-
-            pbdev->fh |= FH_MASK_ENABLE;
-            pbdev->state = ZPCI_FS_ENABLED;
+            pbdev->fh = pbdev->fh | FH_ENABLED;
             stl_p(&ressetpci->fh, pbdev->fh);
             stw_p(&ressetpci->hdr.rsp, CLP_RC_OK);
             break;
         case CLP_SET_DISABLE_PCI_FN:
-            if (!(pbdev->fh & FH_MASK_ENABLE)) {
-                stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP);
-                goto out;
-            }
-            device_reset(DEVICE(pbdev));
-            pbdev->fh &= ~FH_MASK_ENABLE;
-            pbdev->state = ZPCI_FS_DISABLED;
+            pbdev->fh = pbdev->fh & ~FH_ENABLED;
+            pbdev->error_state = false;
+            pbdev->lgstg_blocked = false;
             stl_p(&ressetpci->fh, pbdev->fh);
             stw_p(&ressetpci->hdr.rsp, CLP_RC_OK);
             break;
@@ -275,10 +256,9 @@ int clp_service_call(S390CPU *cpu, uint8_t r2)
 
         stq_p(&resquery->sdma, ZPCI_SDMA_ADDR);
         stq_p(&resquery->edma, ZPCI_EDMA_ADDR);
-        stl_p(&resquery->fid, pbdev->fid);
         stw_p(&resquery->pchid, 0);
         stw_p(&resquery->ug, 1);
-        stl_p(&resquery->uid, pbdev->uid);
+        stl_p(&resquery->uid, pbdev->fid);
         stw_p(&resquery->hdr.rsp, CLP_RC_OK);
         break;
     }
@@ -337,25 +317,16 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
     offset = env->regs[r2 + 1];
 
     pbdev = s390_pci_find_dev_by_fh(fh);
-    if (!pbdev) {
+    if (!pbdev || !(pbdev->fh & FH_ENABLED)) {
         DPRINTF("pcilg no pci dev\n");
         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
         return 0;
     }
 
-    switch (pbdev->state) {
-    case ZPCI_FS_RESERVED:
-    case ZPCI_FS_STANDBY:
-    case ZPCI_FS_DISABLED:
-    case ZPCI_FS_PERMANENT_ERROR:
-        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
-        return 0;
-    case ZPCI_FS_ERROR:
+    if (pbdev->lgstg_blocked) {
         setcc(cpu, ZPCI_PCI_LS_ERR);
         s390_set_status_code(env, r2, ZPCI_PCI_ST_BLOCKED);
         return 0;
-    default:
-        break;
     }
 
     if (pcias < 6) {
@@ -419,8 +390,7 @@ static void update_msix_table_msg_data(S390PCIBusDevice *pbdev, uint64_t offset,
 
     msg_data = (uint8_t *)data - offset % PCI_MSIX_ENTRY_SIZE +
                PCI_MSIX_ENTRY_VECTOR_CTRL;
-    val = pci_get_long(msg_data) |
-        ((pbdev->fh & FH_MASK_INDEX) << ZPCI_MSI_VEC_BITS);
+    val = pci_get_long(msg_data) | (pbdev->fid << ZPCI_MSI_VEC_BITS);
     pci_set_long(msg_data, val);
     DPRINTF("update msix msg_data to 0x%" PRIx64 "\n", *data);
 }
@@ -464,25 +434,16 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
     offset = env->regs[r2 + 1];
 
     pbdev = s390_pci_find_dev_by_fh(fh);
-    if (!pbdev) {
+    if (!pbdev || !(pbdev->fh & FH_ENABLED)) {
         DPRINTF("pcistg no pci dev\n");
         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
         return 0;
     }
 
-    switch (pbdev->state) {
-    case ZPCI_FS_RESERVED:
-    case ZPCI_FS_STANDBY:
-    case ZPCI_FS_DISABLED:
-    case ZPCI_FS_PERMANENT_ERROR:
-        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
-        return 0;
-    case ZPCI_FS_ERROR:
+    if (pbdev->lgstg_blocked) {
         setcc(cpu, ZPCI_PCI_LS_ERR);
         s390_set_status_code(env, r2, ZPCI_PCI_ST_BLOCKED);
         return 0;
-    default:
-        break;
     }
 
     data = env->regs[r1];
@@ -564,55 +525,18 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2)
     end = start + env->regs[r2 + 1];
 
     pbdev = s390_pci_find_dev_by_fh(fh);
-    if (!pbdev) {
+    if (!pbdev || !(pbdev->fh & FH_ENABLED)) {
         DPRINTF("rpcit no pci dev\n");
         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
         goto out;
     }
 
-    switch (pbdev->state) {
-    case ZPCI_FS_RESERVED:
-    case ZPCI_FS_STANDBY:
-    case ZPCI_FS_DISABLED:
-    case ZPCI_FS_PERMANENT_ERROR:
-        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
-        return 0;
-    case ZPCI_FS_ERROR:
-        setcc(cpu, ZPCI_PCI_LS_ERR);
-        s390_set_status_code(env, r1, ZPCI_MOD_ST_ERROR_RECOVER);
-        return 0;
-    default:
-        break;
-    }
-
-    if (!pbdev->g_iota) {
-        pbdev->state = ZPCI_FS_ERROR;
-        setcc(cpu, ZPCI_PCI_LS_ERR);
-        s390_set_status_code(env, r1, ZPCI_PCI_ST_INSUF_RES);
-        s390_pci_generate_error_event(ERR_EVENT_INVALAS, pbdev->fh, pbdev->fid,
-                                      start, 0);
-        goto out;
-    }
-
-    if (end < pbdev->pba || start > pbdev->pal) {
-        pbdev->state = ZPCI_FS_ERROR;
-        setcc(cpu, ZPCI_PCI_LS_ERR);
-        s390_set_status_code(env, r1, ZPCI_PCI_ST_INSUF_RES);
-        s390_pci_generate_error_event(ERR_EVENT_OORANGE, pbdev->fh, pbdev->fid,
-                                      start, 0);
-        goto out;
-    }
-
     mr = &pbdev->iommu_mr;
     while (start < end) {
         entry = mr->iommu_ops->translate(mr, start, 0);
 
         if (!entry.translated_addr) {
-            pbdev->state = ZPCI_FS_ERROR;
             setcc(cpu, ZPCI_PCI_LS_ERR);
-            s390_set_status_code(env, r1, ZPCI_PCI_ST_INSUF_RES);
-            s390_pci_generate_error_event(ERR_EVENT_SERR, pbdev->fh, pbdev->fid,
-                                          start, ERR_EVENT_Q_BIT);
             goto out;
         }
 
@@ -665,25 +589,16 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
     }
 
     pbdev = s390_pci_find_dev_by_fh(fh);
-    if (!pbdev) {
+    if (!pbdev || !(pbdev->fh & FH_ENABLED)) {
         DPRINTF("pcistb no pci dev fh 0x%x\n", fh);
         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
         return 0;
     }
 
-    switch (pbdev->state) {
-    case ZPCI_FS_RESERVED:
-    case ZPCI_FS_STANDBY:
-    case ZPCI_FS_DISABLED:
-    case ZPCI_FS_PERMANENT_ERROR:
-        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
-        return 0;
-    case ZPCI_FS_ERROR:
+    if (pbdev->lgstg_blocked) {
         setcc(cpu, ZPCI_PCI_LS_ERR);
         s390_set_status_code(env, r1, ZPCI_PCI_ST_BLOCKED);
         return 0;
-    default:
-        break;
     }
 
     mr = pbdev->pdev->io_regions[pcias].memory;
@@ -719,15 +634,8 @@ static int reg_irqs(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib)
     len = BITS_TO_LONGS(FIB_DATA_NOI(ldl_p(&fib.data))) * sizeof(unsigned long);
     pbdev->indicator = get_indicator(ldq_p(&fib.aibv), len);
 
-    ret = map_indicator(&pbdev->routes.adapter, pbdev->summary_ind);
-    if (ret) {
-        goto out;
-    }
-
-    ret = map_indicator(&pbdev->routes.adapter, pbdev->indicator);
-    if (ret) {
-        goto out;
-    }
+    map_indicator(&pbdev->routes.adapter, pbdev->summary_ind);
+    map_indicator(&pbdev->routes.adapter, pbdev->indicator);
 
     pbdev->routes.adapter.summary_addr = ldq_p(&fib.aisb);
     pbdev->routes.adapter.summary_offset = FIB_DATA_AISBO(ldl_p(&fib.data));
@@ -739,15 +647,9 @@ static int reg_irqs(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib)
 
     DPRINTF("reg_irqs adapter id %d\n", pbdev->routes.adapter.adapter_id);
     return 0;
-out:
-    release_indicator(&pbdev->routes.adapter, pbdev->summary_ind);
-    release_indicator(&pbdev->routes.adapter, pbdev->indicator);
-    pbdev->summary_ind = NULL;
-    pbdev->indicator = NULL;
-    return ret;
 }
 
-int pci_dereg_irqs(S390PCIBusDevice *pbdev)
+static int dereg_irqs(S390PCIBusDevice *pbdev)
 {
     release_indicator(&pbdev->routes.adapter, pbdev->summary_ind);
     release_indicator(&pbdev->routes.adapter, pbdev->indicator);
@@ -790,23 +692,24 @@ static int reg_ioat(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib)
     pbdev->pal = pal;
     pbdev->g_iota = g_iota;
 
-    s390_pci_iommu_enable(pbdev);
+    s390_pcihost_iommu_configure(pbdev, true);
 
     return 0;
 }
 
-void pci_dereg_ioat(S390PCIBusDevice *pbdev)
+static void dereg_ioat(S390PCIBusDevice *pbdev)
 {
-    s390_pci_iommu_disable(pbdev);
     pbdev->pba = 0;
     pbdev->pal = 0;
     pbdev->g_iota = 0;
+
+    s390_pcihost_iommu_configure(pbdev, false);
 }
 
 int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
 {
     CPUS390XState *env = &cpu->env;
-    uint8_t oc, dmaas;
+    uint8_t oc;
     uint32_t fh;
     ZpciFib fib;
     S390PCIBusDevice *pbdev;
@@ -818,7 +721,6 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
     }
 
     oc = env->regs[r1] & 0xff;
-    dmaas = (env->regs[r1] >> 16) & 0xff;
     fh = env->regs[r1] >> 32;
 
     if (fiba & 0x7) {
@@ -827,108 +729,45 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
     }
 
     pbdev = s390_pci_find_dev_by_fh(fh);
-    if (!pbdev) {
+    if (!pbdev || !(pbdev->fh & FH_ENABLED)) {
         DPRINTF("mpcifc no pci dev fh 0x%x\n", fh);
         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
         return 0;
     }
 
-    switch (pbdev->state) {
-    case ZPCI_FS_RESERVED:
-    case ZPCI_FS_STANDBY:
-    case ZPCI_FS_DISABLED:
-    case ZPCI_FS_PERMANENT_ERROR:
-        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
-        return 0;
-    default:
-        break;
-    }
-
     if (s390_cpu_virt_mem_read(cpu, fiba, ar, (uint8_t *)&fib, sizeof(fib))) {
         return 0;
     }
 
-    if (fib.fmt != 0) {
-        program_interrupt(env, PGM_OPERAND, 6);
-        return 0;
-    }
-
     switch (oc) {
     case ZPCI_MOD_FC_REG_INT:
-        if (pbdev->summary_ind) {
+        if (reg_irqs(env, pbdev, fib)) {
             cc = ZPCI_PCI_LS_ERR;
-            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
-        } else if (reg_irqs(env, pbdev, fib)) {
-            cc = ZPCI_PCI_LS_ERR;
-            s390_set_status_code(env, r1, ZPCI_MOD_ST_RES_NOT_AVAIL);
         }
         break;
     case ZPCI_MOD_FC_DEREG_INT:
-        if (!pbdev->summary_ind) {
-            cc = ZPCI_PCI_LS_ERR;
-            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
-        } else {
-            pci_dereg_irqs(pbdev);
-        }
+        dereg_irqs(pbdev);
         break;
     case ZPCI_MOD_FC_REG_IOAT:
-        if (dmaas != 0) {
+        if (reg_ioat(env, pbdev, fib)) {
             cc = ZPCI_PCI_LS_ERR;
-            s390_set_status_code(env, r1, ZPCI_MOD_ST_DMAAS_INVAL);
-        } else if (pbdev->iommu_enabled) {
-            cc = ZPCI_PCI_LS_ERR;
-            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
-        } else if (reg_ioat(env, pbdev, fib)) {
-            cc = ZPCI_PCI_LS_ERR;
-            s390_set_status_code(env, r1, ZPCI_MOD_ST_INSUF_RES);
         }
         break;
     case ZPCI_MOD_FC_DEREG_IOAT:
-        if (dmaas != 0) {
-            cc = ZPCI_PCI_LS_ERR;
-            s390_set_status_code(env, r1, ZPCI_MOD_ST_DMAAS_INVAL);
-        } else if (!pbdev->iommu_enabled) {
-            cc = ZPCI_PCI_LS_ERR;
-            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
-        } else {
-            pci_dereg_ioat(pbdev);
-        }
+        dereg_ioat(pbdev);
         break;
     case ZPCI_MOD_FC_REREG_IOAT:
-        if (dmaas != 0) {
+        dereg_ioat(pbdev);
+        if (reg_ioat(env, pbdev, fib)) {
             cc = ZPCI_PCI_LS_ERR;
-            s390_set_status_code(env, r1, ZPCI_MOD_ST_DMAAS_INVAL);
-        } else if (!pbdev->iommu_enabled) {
-            cc = ZPCI_PCI_LS_ERR;
-            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
-        } else {
-            pci_dereg_ioat(pbdev);
-            if (reg_ioat(env, pbdev, fib)) {
-                cc = ZPCI_PCI_LS_ERR;
-                s390_set_status_code(env, r1, ZPCI_MOD_ST_INSUF_RES);
-            }
         }
         break;
     case ZPCI_MOD_FC_RESET_ERROR:
-        switch (pbdev->state) {
-        case ZPCI_FS_BLOCKED:
-        case ZPCI_FS_ERROR:
-            pbdev->state = ZPCI_FS_ENABLED;
-            break;
-        default:
-            cc = ZPCI_PCI_LS_ERR;
-            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
-        }
+        pbdev->error_state = false;
+        pbdev->lgstg_blocked = false;
         break;
     case ZPCI_MOD_FC_RESET_BLOCK:
-        switch (pbdev->state) {
-        case ZPCI_FS_ERROR:
-            pbdev->state = ZPCI_FS_BLOCKED;
-            break;
-        default:
-            cc = ZPCI_PCI_LS_ERR;
-            s390_set_status_code(env, r1, ZPCI_MOD_ST_SEQUENCE);
-        }
+        pbdev->lgstg_blocked = false;
         break;
     case ZPCI_MOD_FC_SET_MEASURE:
         pbdev->fmb_addr = ldq_p(&fib.fmb_addr);
@@ -945,7 +784,6 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
 int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
 {
     CPUS390XState *env = &cpu->env;
-    uint8_t dmaas;
     uint32_t fh;
     ZpciFib fib;
     S390PCIBusDevice *pbdev;
@@ -958,59 +796,19 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
     }
 
     fh = env->regs[r1] >> 32;
-    dmaas = (env->regs[r1] >> 16) & 0xff;
-
-    if (dmaas) {
-        setcc(cpu, ZPCI_PCI_LS_ERR);
-        s390_set_status_code(env, r1, ZPCI_STPCIFC_ST_INVAL_DMAAS);
-        return 0;
-    }
 
     if (fiba & 0x7) {
         program_interrupt(env, PGM_SPECIFICATION, 6);
         return 0;
     }
 
-    pbdev = s390_pci_find_dev_by_idx(fh & FH_MASK_INDEX);
+    pbdev = s390_pci_find_dev_by_fh(fh);
     if (!pbdev) {
         setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
         return 0;
     }
 
     memset(&fib, 0, sizeof(fib));
-
-    switch (pbdev->state) {
-    case ZPCI_FS_RESERVED:
-    case ZPCI_FS_STANDBY:
-        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
-        return 0;
-    case ZPCI_FS_DISABLED:
-        if (fh & FH_MASK_ENABLE) {
-            setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
-            return 0;
-        }
-        goto out;
-    /* BLOCKED bit is set to one coincident with the setting of ERROR bit.
-     * FH Enabled bit is set to one in states of ENABLED, BLOCKED or ERROR. */
-    case ZPCI_FS_ERROR:
-        fib.fc |= 0x20;
-    case ZPCI_FS_BLOCKED:
-        fib.fc |= 0x40;
-    case ZPCI_FS_ENABLED:
-        fib.fc |= 0x80;
-        if (pbdev->iommu_enabled) {
-            fib.fc |= 0x10;
-        }
-        if (!(fh & FH_MASK_ENABLE)) {
-            env->regs[r1] |= 1ULL << 63;
-        }
-        break;
-    case ZPCI_FS_PERMANENT_ERROR:
-        setcc(cpu, ZPCI_PCI_LS_ERR);
-        s390_set_status_code(env, r1, ZPCI_STPCIFC_ST_PERM_ERROR);
-        return 0;
-    }
-
     stq_p(&fib.pba, pbdev->pba);
     stq_p(&fib.pal, pbdev->pal);
     stq_p(&fib.iota, pbdev->g_iota);
@@ -1023,7 +821,22 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
            ((uint32_t)pbdev->sum << 7) | pbdev->routes.adapter.summary_offset;
     stl_p(&fib.data, data);
 
-out:
+    if (pbdev->fh & FH_ENABLED) {
+        fib.fc |= 0x80;
+    }
+
+    if (pbdev->error_state) {
+        fib.fc |= 0x40;
+    }
+
+    if (pbdev->lgstg_blocked) {
+        fib.fc |= 0x20;
+    }
+
+    if (pbdev->g_iota) {
+        fib.fc |= 0x10;
+    }
+
     if (s390_cpu_virt_mem_write(cpu, fiba, ar, (uint8_t *)&fib, sizeof(fib))) {
         return 0;
     }
index 23f4bfa..70fa713 100644 (file)
@@ -14,8 +14,7 @@
 #ifndef HW_S390_PCI_INST_H
 #define HW_S390_PCI_INST_H
 
-#include "s390-pci-bus.h"
-#include "sysemu/dma.h"
+#include <sysemu/dma.h>
 
 /* CLP common request & response block size */
 #define CLP_BLK_SIZE 4096
@@ -104,7 +103,7 @@ typedef struct ClpRspListPci {
     uint64_t resume_token;
     uint32_t mdd;
     uint16_t max_fn;
-    uint8_t flags;
+    uint8_t reserved2;
     uint8_t entry_size;
     ClpFhListEntry fh_list[CLP_FH_LIST_NR_ENTRIES];
 } QEMU_PACKED ClpRspListPci;
@@ -231,14 +230,6 @@ typedef struct ClpReqRspQueryPciGrp {
 #define ZPCI_PCI_LS_BUSY            2
 #define ZPCI_PCI_LS_INVAL_HANDLE    3
 
-/* Modify PCI status codes */
-#define ZPCI_MOD_ST_RES_NOT_AVAIL 4
-#define ZPCI_MOD_ST_INSUF_RES     16
-#define ZPCI_MOD_ST_SEQUENCE      24
-#define ZPCI_MOD_ST_DMAAS_INVAL   28
-#define ZPCI_MOD_ST_FRAME_INVAL   32
-#define ZPCI_MOD_ST_ERROR_RECOVER 40
-
 /* Modify PCI Function Controls */
 #define ZPCI_MOD_FC_REG_INT     2
 #define ZPCI_MOD_FC_DEREG_INT   3
@@ -249,11 +240,6 @@ typedef struct ClpReqRspQueryPciGrp {
 #define ZPCI_MOD_FC_RESET_BLOCK 9
 #define ZPCI_MOD_FC_SET_MEASURE 10
 
-/* Store PCI Function Controls status codes */
-#define ZPCI_STPCIFC_ST_PERM_ERROR    8
-#define ZPCI_STPCIFC_ST_INVAL_DMAAS   28
-#define ZPCI_STPCIFC_ST_ERROR_RECOVER 40
-
 /* FIB function controls */
 #define ZPCI_FIB_FC_ENABLED     0x80
 #define ZPCI_FIB_FC_ERROR       0x40
@@ -291,8 +277,6 @@ typedef struct ZpciFib {
     uint32_t gd;
 } QEMU_PACKED ZpciFib;
 
-int pci_dereg_irqs(S390PCIBusDevice *pbdev);
-void pci_dereg_ioat(S390PCIBusDevice *pbdev);
 int clp_service_call(S390CPU *cpu, uint8_t r2);
 int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
 int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
index e2d4e1a..6528ffe 100644 (file)
@@ -15,7 +15,6 @@
 #include "migration/qemu-file.h"
 #include "hw/s390x/storage-keys.h"
 #include "qemu/error-report.h"
-#include "sysemu/kvm.h"
 
 #define S390_SKEYS_BUFFER_SIZE 131072  /* Room for 128k storage keys */
 #define S390_SKEYS_SAVE_FLAG_EOS 0x01
@@ -47,11 +46,15 @@ void s390_skeys_init(void)
     qdev_init_nofail(DEVICE(obj));
 }
 
-static void write_keys(FILE *f, uint8_t *keys, uint64_t startgfn,
+static void write_keys(QEMUFile *f, uint8_t *keys, uint64_t startgfn,
                        uint64_t count, Error **errp)
 {
     uint64_t curpage = startgfn;
     uint64_t maxpage = curpage + count - 1;
+    const char *fmt = "page=%03" PRIx64 ": key(%d) => ACC=%X, FP=%d, REF=%d,"
+                      " ch=%d, reserved=%d\n";
+    char buf[128];
+    int len;
 
     for (; curpage <= maxpage; curpage++) {
         uint8_t acc = (*keys & 0xF0) >> 4;
@@ -60,9 +63,10 @@ static void write_keys(FILE *f, uint8_t *keys, uint64_t startgfn,
         int ch = (*keys & 0x02);
         int res = (*keys & 0x01);
 
-        fprintf(f, "page=%03" PRIx64 ": key(%d) => ACC=%X, FP=%d, REF=%d,"
-                " ch=%d, reserved=%d\n",
-                curpage, *keys, acc, fp, ref, ch, res);
+        len = snprintf(buf, sizeof(buf), fmt, curpage,
+                       *keys, acc, fp, ref, ch, res);
+        assert(len < sizeof(buf));
+        qemu_put_buffer(f, (uint8_t *)buf, len);
         keys++;
     }
 }
@@ -111,8 +115,7 @@ void qmp_dump_skeys(const char *filename, Error **errp)
     vaddr cur_gfn = 0;
     uint8_t *buf;
     int ret;
-    int fd;
-    FILE *f;
+    QEMUFile *f;
 
     /* Quick check to see if guest is using storage keys*/
     if (!skeyclass->skeys_enabled(ss)) {
@@ -121,14 +124,8 @@ void qmp_dump_skeys(const char *filename, Error **errp)
         return;
     }
 
-    fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
-    if (fd < 0) {
-        error_setg_file_open(errp, errno, filename);
-        return;
-    }
-    f = fdopen(fd, "wb");
+    f = qemu_fopen(filename, "wb");
     if (!f) {
-        close(fd);
         error_setg_file_open(errp, errno, filename);
         return;
     }
@@ -164,7 +161,7 @@ out_free:
     error_propagate(errp, lerr);
     g_free(buf);
 out:
-    fclose(f);
+    qemu_fclose(f);
 }
 
 static void qemu_s390_skeys_init(Object *obj)
index 91d9cef..e3df9c7 100644 (file)
 #include "s390-virtio.h"
 #include "hw/s390x/sclp.h"
 #include "hw/s390x/s390_flic.h"
-#include "hw/s390x/ioinst.h"
-#include "hw/s390x/css.h"
+#include "ioinst.h"
+#include "css.h"
 #include "virtio-ccw.h"
 #include "qemu/config-file.h"
 #include "s390-pci-bus.h"
 #include "hw/s390x/storage-keys.h"
 #include "hw/compat.h"
-#include "ipl.h"
 #include "hw/s390x/s390-virtio-ccw.h"
-#include "hw/s390x/css-bridge.h"
 
 static const char *const reset_dev_types[] = {
-    TYPE_VIRTUAL_CSS_BRIDGE,
+    "virtual-css-bridge",
     "s390-sclp-event-facility",
     "s390-flic",
     "diag288",
@@ -181,8 +179,10 @@ static HotplugHandler *s390_get_hotplug_handler(MachineState *machine,
 static void s390_hot_add_cpu(const int64_t id, Error **errp)
 {
     MachineState *machine = MACHINE(qdev_get_machine());
+    Error *err = NULL;
 
-    s390x_new_cpu(machine->cpu_model, id, errp);
+    s390x_new_cpu(machine->cpu_model, id, &err);
+    error_propagate(errp, err);
 }
 
 static void ccw_machine_class_init(ObjectClass *oc, void *data)
@@ -190,9 +190,7 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data)
     MachineClass *mc = MACHINE_CLASS(oc);
     NMIClass *nc = NMI_CLASS(oc);
     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
-    S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
 
-    s390mc->ri_allowed = true;
     mc->init = ccw_init;
     mc->reset = s390_machine_reset;
     mc->hot_add_cpu = s390_hot_add_cpu;
@@ -203,7 +201,7 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data)
     mc->no_parallel = 1;
     mc->no_sdcard = 1;
     mc->use_sclp = 1;
-    mc->max_cpus = 248;
+    mc->max_cpus = 255;
     mc->get_hotplug_handler = s390_get_hotplug_handler;
     hc->plug = s390_machine_device_plug;
     nc->nmi_monitor_handler = s390_nmi;
@@ -239,20 +237,6 @@ static inline void machine_set_dea_key_wrap(Object *obj, bool value,
     ms->dea_key_wrap = value;
 }
 
-bool ri_allowed(void)
-{
-    if (kvm_enabled()) {
-        MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
-        if (object_class_dynamic_cast(OBJECT_CLASS(mc),
-                                      TYPE_S390_CCW_MACHINE)) {
-            S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
-
-            return s390mc->ri_allowed;
-        }
-    }
-    return 0;
-}
-
 static inline void s390_machine_initfn(Object *obj)
 {
     object_property_add_bool(obj, "aes-key-wrap",
@@ -278,7 +262,6 @@ static const TypeInfo ccw_machine_info = {
     .abstract      = true,
     .instance_size = sizeof(S390CcwMachineState),
     .instance_init = s390_machine_initfn,
-    .class_size = sizeof(S390CcwMachineClass),
     .class_init    = ccw_machine_class_init,
     .interfaces = (InterfaceInfo[]) {
         { TYPE_NMI },
@@ -316,23 +299,11 @@ static const TypeInfo ccw_machine_info = {
     }                                                                         \
     type_init(ccw_machine_register_##suffix)
 
-#define CCW_COMPAT_2_6 \
-        HW_COMPAT_2_6 \
-        {\
-            .driver   = TYPE_S390_IPL,\
-            .property = "iplbext_migration",\
-            .value    = "off",\
-        }, {\
-            .driver   = TYPE_VIRTUAL_CSS_BRIDGE,\
-            .property = "css_dev_path",\
-            .value    = "off",\
-        },
-
 #define CCW_COMPAT_2_5 \
-        CCW_COMPAT_2_6 \
         HW_COMPAT_2_5
 
 #define CCW_COMPAT_2_4 \
+        CCW_COMPAT_2_5 \
         HW_COMPAT_2_4 \
         {\
             .driver   = TYPE_S390_SKEYS,\
@@ -372,38 +343,21 @@ static const TypeInfo ccw_machine_info = {
             .value    = "0",\
         },
 
-static void ccw_machine_2_7_instance_options(MachineState *machine)
-{
-}
-
-static void ccw_machine_2_7_class_options(MachineClass *mc)
-{
-}
-DEFINE_CCW_MACHINE(2_7, "2.7", true);
-
 static void ccw_machine_2_6_instance_options(MachineState *machine)
 {
-    ccw_machine_2_7_instance_options(machine);
 }
 
 static void ccw_machine_2_6_class_options(MachineClass *mc)
 {
-    S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
-
-    s390mc->ri_allowed = false;
-    ccw_machine_2_7_class_options(mc);
-    SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_6);
 }
-DEFINE_CCW_MACHINE(2_6, "2.6", false);
+DEFINE_CCW_MACHINE(2_6, "2.6", true);
 
 static void ccw_machine_2_5_instance_options(MachineState *machine)
 {
-    ccw_machine_2_6_instance_options(machine);
 }
 
 static void ccw_machine_2_5_class_options(MachineClass *mc)
 {
-    ccw_machine_2_6_class_options(mc);
     SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_5);
 }
 DEFINE_CCW_MACHINE(2_5, "2.5", false);
@@ -415,7 +369,6 @@ static void ccw_machine_2_4_instance_options(MachineState *machine)
 
 static void ccw_machine_2_4_class_options(MachineClass *mc)
 {
-    ccw_machine_2_5_class_options(mc);
     SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_4);
 }
 DEFINE_CCW_MACHINE(2_4, "2.4", false);
index f588b80..ffd014c 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #ifndef HW_S390_VIRTIO_H
-#define HW_S390_VIRTIO_H
+#define HW_S390_VIRTIO_H 1
 
 #include "hw/nmi.h"
 #include "standard-headers/asm-s390/kvm_virtio.h"
index fca37f5..85dbe1b 100644 (file)
@@ -357,10 +357,10 @@ static void sclp_execute(SCLPDevice *sclp, SCCB *sccb, uint32_t code)
         sclp_c->unassign_storage(sclp, sccb);
         break;
     case SCLP_CMDW_CONFIGURE_PCI:
-        s390_pci_sclp_configure(sccb);
+        s390_pci_sclp_configure(1, sccb);
         break;
     case SCLP_CMDW_DECONFIGURE_PCI:
-        s390_pci_sclp_deconfigure(sccb);
+        s390_pci_sclp_configure(0, sccb);
         break;
     default:
         efc->command_handler(ef, sccb, code);
index 762cb18..c0ecab9 100644 (file)
@@ -12,7 +12,7 @@
  *
  */
 #include "qemu/osdep.h"
-#include "hw/qdev.h"
+#include <hw/qdev.h>
 #include "sysemu/sysemu.h"
 #include "hw/s390x/sclp.h"
 #include "hw/s390x/event-facility.h"
diff --git a/hw/s390x/trace-events b/hw/s390x/trace-events
deleted file mode 100644 (file)
index 84ea964..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/s390x/css.c
-css_enable_facility(const char *facility) "CSS: enable %s"
-css_crw(uint8_t rsc, uint8_t erc, uint16_t rsid, const char *chained) "CSS: queueing crw: rsc=%x, erc=%x, rsid=%x %s"
-css_chpid_add(uint8_t cssid, uint8_t chpid, uint8_t type) "CSS: add chpid %x.%02x (type %02x)"
-css_new_image(uint8_t cssid, const char *default_cssid) "CSS: add css image %02x %s"
-css_assign_subch(const char *do_assign, uint8_t cssid, uint8_t ssid, uint16_t schid, uint16_t devno) "CSS: %s %x.%x.%04x (devno %04x)"
-css_io_interrupt(int cssid, int ssid, int schid, uint32_t intparm, uint8_t isc, const char *conditional) "CSS: I/O interrupt on sch %x.%x.%04x (intparm %08x, isc %x) %s"
-css_adapter_interrupt(uint8_t isc) "CSS: adapter I/O interrupt (isc %x)"
-
-# hw/s390x/virtio-ccw.c
-virtio_ccw_interpret_ccw(int cssid, int ssid, int schid, int cmd_code) "VIRTIO-CCW: %x.%x.%04x: interpret command %x"
-virtio_ccw_new_device(int cssid, int ssid, int schid, int devno, const char *devno_mode) "VIRTIO-CCW: add subchannel %x.%x.%04x, devno %04x (%s)"
-virtio_ccw_set_ind(uint64_t ind_loc, uint8_t ind_old, uint8_t ind_new) "VIRTIO-CCW: indicator at %" PRIu64 ": %x->%x"
index a554a24..d51642d 100644 (file)
@@ -16,7 +16,6 @@
 #include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/sysemu.h"
-#include "sysemu/kvm.h"
 #include "net/net.h"
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/virtio-serial.h"
 #include "hw/s390x/adapter.h"
 #include "hw/s390x/s390_flic.h"
 
-#include "hw/s390x/ioinst.h"
-#include "hw/s390x/css.h"
+#include "ioinst.h"
+#include "css.h"
 #include "virtio-ccw.h"
 #include "trace.h"
-#include "hw/s390x/css-bridge.h"
 
 static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
                                VirtioCcwDevice *dev);
 
+static void virtual_css_bus_reset(BusState *qbus)
+{
+    /* This should actually be modelled via the generic css */
+    css_reset();
+}
+
+
+static void virtual_css_bus_class_init(ObjectClass *klass, void *data)
+{
+    BusClass *k = BUS_CLASS(klass);
+
+    k->reset = virtual_css_bus_reset;
+}
+
+static const TypeInfo virtual_css_bus_info = {
+    .name = TYPE_VIRTUAL_CSS_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(VirtualCssBus),
+    .class_init = virtual_css_bus_class_init,
+};
+
 VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
 {
     VirtIODevice *vdev = NULL;
@@ -49,59 +68,112 @@ VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
     return vdev;
 }
 
-static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
+static int virtio_ccw_set_guest2host_notifier(VirtioCcwDevice *dev, int n,
+                                              bool assign, bool set_handler)
 {
-    virtio_bus_start_ioeventfd(&dev->bus);
-}
+    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
+    VirtQueue *vq = virtio_get_queue(vdev, n);
+    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
+    int r = 0;
+    SubchDev *sch = dev->sch;
+    uint32_t sch_id = (css_build_subchannel_id(sch) << 16) | sch->schid;
 
-static void virtio_ccw_stop_ioeventfd(VirtioCcwDevice *dev)
-{
-    virtio_bus_stop_ioeventfd(&dev->bus);
+    if (assign) {
+        r = event_notifier_init(notifier, 1);
+        if (r < 0) {
+            error_report("%s: unable to init event notifier: %d", __func__, r);
+            return r;
+        }
+        virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
+        r = s390_assign_subch_ioeventfd(notifier, sch_id, n, assign);
+        if (r < 0) {
+            error_report("%s: unable to assign ioeventfd: %d", __func__, r);
+            virtio_queue_set_host_notifier_fd_handler(vq, false, false);
+            event_notifier_cleanup(notifier);
+            return r;
+        }
+    } else {
+        virtio_queue_set_host_notifier_fd_handler(vq, false, false);
+        s390_assign_subch_ioeventfd(notifier, sch_id, n, assign);
+        event_notifier_cleanup(notifier);
+    }
+    return r;
 }
 
-static bool virtio_ccw_ioeventfd_started(DeviceState *d)
+static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
 {
-    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
-
-    return dev->ioeventfd_started;
-}
+    VirtIODevice *vdev;
+    int n, r;
 
-static void virtio_ccw_ioeventfd_set_started(DeviceState *d, bool started,
-                                             bool err)
-{
-    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
+    if (!(dev->flags & VIRTIO_CCW_FLAG_USE_IOEVENTFD) ||
+        dev->ioeventfd_disabled ||
+        dev->ioeventfd_started) {
+        return;
+    }
+    vdev = virtio_bus_get_device(&dev->bus);
+    for (n = 0; n < VIRTIO_CCW_QUEUE_MAX; n++) {
+        if (!virtio_queue_get_num(vdev, n)) {
+            continue;
+        }
+        r = virtio_ccw_set_guest2host_notifier(dev, n, true, true);
+        if (r < 0) {
+            goto assign_error;
+        }
+    }
+    dev->ioeventfd_started = true;
+    return;
 
-    dev->ioeventfd_started = started;
-    if (err) {
-        /* Disable ioeventfd for this device. */
-        dev->flags &= ~VIRTIO_CCW_FLAG_USE_IOEVENTFD;
+  assign_error:
+    while (--n >= 0) {
+        if (!virtio_queue_get_num(vdev, n)) {
+            continue;
+        }
+        r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
+        assert(r >= 0);
     }
+    dev->ioeventfd_started = false;
+    /* Disable ioeventfd for this device. */
+    dev->flags &= ~VIRTIO_CCW_FLAG_USE_IOEVENTFD;
+    error_report("%s: failed. Fallback to userspace (slower).", __func__);
 }
 
-static bool virtio_ccw_ioeventfd_disabled(DeviceState *d)
+static void virtio_ccw_stop_ioeventfd(VirtioCcwDevice *dev)
 {
-    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
+    VirtIODevice *vdev;
+    int n, r;
 
-    return dev->ioeventfd_disabled ||
-        !(dev->flags & VIRTIO_CCW_FLAG_USE_IOEVENTFD);
+    if (!dev->ioeventfd_started) {
+        return;
+    }
+    vdev = virtio_bus_get_device(&dev->bus);
+    for (n = 0; n < VIRTIO_CCW_QUEUE_MAX; n++) {
+        if (!virtio_queue_get_num(vdev, n)) {
+            continue;
+        }
+        r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
+        assert(r >= 0);
+    }
+    dev->ioeventfd_started = false;
 }
 
-static void virtio_ccw_ioeventfd_set_disabled(DeviceState *d, bool disabled)
+VirtualCssBus *virtual_css_bus_init(void)
 {
-    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
+    VirtualCssBus *cbus;
+    BusState *bus;
+    DeviceState *dev;
 
-    dev->ioeventfd_disabled = disabled;
-}
+    /* Create bridge device */
+    dev = qdev_create(NULL, "virtual-css-bridge");
+    qdev_init_nofail(dev);
 
-static int virtio_ccw_ioeventfd_assign(DeviceState *d, EventNotifier *notifier,
-                                       int n, bool assign)
-{
-    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
-    CcwDevice *ccw_dev = CCW_DEVICE(dev);
-    SubchDev *sch = ccw_dev->sch;
-    uint32_t sch_id = (css_build_subchannel_id(sch) << 16) | sch->schid;
+    /* Create bus on bridge device */
+    bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
+    cbus = VIRTUAL_CSS_BUS(bus);
+
+    /* Enable hotplugging */
+    qbus_set_hotplug_handler(bus, dev, &error_abort);
 
-    return s390_assign_subch_ioeventfd(notifier, sch_id, n, assign);
+    return cbus;
 }
 
 /* Communication blocks used by several channel commands. */
@@ -195,8 +267,6 @@ static int virtio_ccw_set_vqs(SubchDev *sch, VqInfoBlock *info,
 
 static void virtio_ccw_reset_virtio(VirtioCcwDevice *dev, VirtIODevice *vdev)
 {
-    CcwDevice *ccw_dev = CCW_DEVICE(dev);
-
     virtio_ccw_stop_ioeventfd(dev);
     virtio_reset(vdev);
     if (dev->indicators) {
@@ -211,7 +281,7 @@ static void virtio_ccw_reset_virtio(VirtioCcwDevice *dev, VirtIODevice *vdev)
         release_indicator(&dev->routes.adapter, dev->summary_indicator);
         dev->summary_indicator = NULL;
     }
-    ccw_dev->sch->thinint_active = false;
+    dev->sch->thinint_active = false;
 }
 
 static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len,
@@ -666,44 +736,151 @@ static void virtio_sch_disable_cb(SubchDev *sch)
 
 static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
 {
-    VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
-    CcwDevice *ccw_dev = CCW_DEVICE(dev);
-    SubchDev *sch = css_create_virtual_sch(ccw_dev->bus_id, errp);
+    unsigned int cssid = 0;
+    unsigned int ssid = 0;
+    unsigned int schid;
+    unsigned int devno;
+    bool have_devno = false;
+    bool found = false;
+    SubchDev *sch;
+    int num;
     Error *err = NULL;
+    VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
 
-    if (!sch) {
-        return;
-    }
+    sch = g_malloc0(sizeof(SubchDev));
 
     sch->driver_data = dev;
+    dev->sch = sch;
+
+    dev->indicators = NULL;
+
+    /* Initialize subchannel structure. */
+    sch->channel_prog = 0x0;
+    sch->last_cmd_valid = false;
+    sch->thinint_active = false;
+    /*
+     * Use a device number if provided. Otherwise, fall back to subchannel
+     * number.
+     */
+    if (dev->bus_id) {
+        num = sscanf(dev->bus_id, "%x.%x.%04x", &cssid, &ssid, &devno);
+        if (num == 3) {
+            if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) {
+                error_setg(errp, "Invalid cssid or ssid: cssid %x, ssid %x",
+                           cssid, ssid);
+                goto out_err;
+            }
+            /* Enforce use of virtual cssid. */
+            if (cssid != VIRTUAL_CSSID) {
+                error_setg(errp, "cssid %x not valid for virtio devices",
+                           cssid);
+                goto out_err;
+            }
+            if (css_devno_used(cssid, ssid, devno)) {
+                error_setg(errp, "Device %x.%x.%04x already exists",
+                           cssid, ssid, devno);
+                goto out_err;
+            }
+            sch->cssid = cssid;
+            sch->ssid = ssid;
+            sch->devno = devno;
+            have_devno = true;
+        } else {
+            error_setg(errp, "Malformed devno parameter '%s'", dev->bus_id);
+            goto out_err;
+        }
+    }
+
+    /* Find the next free id. */
+    if (have_devno) {
+        for (schid = 0; schid <= MAX_SCHID; schid++) {
+            if (!css_find_subch(1, cssid, ssid, schid)) {
+                sch->schid = schid;
+                css_subch_assign(cssid, ssid, schid, devno, sch);
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            error_setg(errp, "No free subchannel found for %x.%x.%04x",
+                       cssid, ssid, devno);
+            goto out_err;
+        }
+        trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
+                                    "user-configured");
+    } else {
+        cssid = VIRTUAL_CSSID;
+        for (ssid = 0; ssid <= MAX_SSID; ssid++) {
+            for (schid = 0; schid <= MAX_SCHID; schid++) {
+                if (!css_find_subch(1, cssid, ssid, schid)) {
+                    sch->cssid = cssid;
+                    sch->ssid = ssid;
+                    sch->schid = schid;
+                    devno = schid;
+                    /*
+                     * If the devno is already taken, look further in this
+                     * subchannel set.
+                     */
+                    while (css_devno_used(cssid, ssid, devno)) {
+                        if (devno == MAX_SCHID) {
+                            devno = 0;
+                        } else if (devno == schid - 1) {
+                            error_setg(errp, "No free devno found");
+                            goto out_err;
+                        } else {
+                            devno++;
+                        }
+                    }
+                    sch->devno = devno;
+                    css_subch_assign(cssid, ssid, schid, devno, sch);
+                    found = true;
+                    break;
+                }
+            }
+            if (found) {
+                break;
+            }
+        }
+        if (!found) {
+            error_setg(errp, "Virtual channel subsystem is full!");
+            goto out_err;
+        }
+        trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
+                                    "auto-configured");
+    }
+
+    /* Build initial schib. */
+    css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
+
     sch->ccw_cb = virtio_ccw_cb;
     sch->disable_cb = virtio_sch_disable_cb;
+
+    /* Build senseid data. */
+    memset(&sch->id, 0, sizeof(SenseId));
     sch->id.reserved = 0xff;
     sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
-    ccw_dev->sch = sch;
-    dev->indicators = NULL;
-    dev->revision = -1;
-    css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
 
-    trace_virtio_ccw_new_device(
-        sch->cssid, sch->ssid, sch->schid, sch->devno,
-        ccw_dev->bus_id.valid ? "user-configured" : "auto-configured");
+    dev->revision = -1;
 
     if (k->realize) {
         k->realize(dev, &err);
     }
     if (err) {
         error_propagate(errp, err);
-        css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
-        ccw_dev->sch = NULL;
-        g_free(sch);
+        css_subch_assign(cssid, ssid, schid, devno, NULL);
+        goto out_err;
     }
+
+    return;
+
+out_err:
+    dev->sch = NULL;
+    g_free(sch);
 }
 
 static int virtio_ccw_exit(VirtioCcwDevice *dev)
 {
-    CcwDevice *ccw_dev = CCW_DEVICE(dev);
-    SubchDev *sch = ccw_dev->sch;
+    SubchDev *sch = dev->sch;
 
     if (sch) {
         css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
@@ -721,11 +898,15 @@ static void virtio_ccw_net_realize(VirtioCcwDevice *ccw_dev, Error **errp)
     DeviceState *qdev = DEVICE(ccw_dev);
     VirtIONetCcw *dev = VIRTIO_NET_CCW(ccw_dev);
     DeviceState *vdev = DEVICE(&dev->vdev);
+    Error *err = NULL;
 
     virtio_net_set_netclient_name(&dev->vdev, qdev->id,
                                   object_get_typename(OBJECT(qdev)));
     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
-    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+    }
 }
 
 static void virtio_ccw_net_instance_init(Object *obj)
@@ -742,9 +923,13 @@ static void virtio_ccw_blk_realize(VirtioCcwDevice *ccw_dev, Error **errp)
 {
     VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(ccw_dev);
     DeviceState *vdev = DEVICE(&dev->vdev);
+    Error *err = NULL;
 
     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
-    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+    }
 }
 
 static void virtio_ccw_blk_instance_init(Object *obj)
@@ -764,6 +949,7 @@ static void virtio_ccw_serial_realize(VirtioCcwDevice *ccw_dev, Error **errp)
     VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(ccw_dev);
     DeviceState *vdev = DEVICE(&dev->vdev);
     DeviceState *proxy = DEVICE(ccw_dev);
+    Error *err = NULL;
     char *bus_name;
 
     /*
@@ -777,7 +963,10 @@ static void virtio_ccw_serial_realize(VirtioCcwDevice *ccw_dev, Error **errp)
     }
 
     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
-    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+    }
 }
 
 
@@ -793,9 +982,13 @@ static void virtio_ccw_balloon_realize(VirtioCcwDevice *ccw_dev, Error **errp)
 {
     VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(ccw_dev);
     DeviceState *vdev = DEVICE(&dev->vdev);
+    Error *err = NULL;
 
     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
-    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+    }
 }
 
 static void virtio_ccw_balloon_instance_init(Object *obj)
@@ -816,6 +1009,7 @@ static void virtio_ccw_scsi_realize(VirtioCcwDevice *ccw_dev, Error **errp)
     VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(ccw_dev);
     DeviceState *vdev = DEVICE(&dev->vdev);
     DeviceState *qdev = DEVICE(ccw_dev);
+    Error *err = NULL;
     char *bus_name;
 
     /*
@@ -829,7 +1023,10 @@ static void virtio_ccw_scsi_realize(VirtioCcwDevice *ccw_dev, Error **errp)
     }
 
     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
-    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+    }
 }
 
 static void virtio_ccw_scsi_instance_init(Object *obj)
@@ -847,9 +1044,13 @@ static void vhost_ccw_scsi_realize(VirtioCcwDevice *ccw_dev, Error **errp)
 {
     VHostSCSICcw *dev = VHOST_SCSI_CCW(ccw_dev);
     DeviceState *vdev = DEVICE(&dev->vdev);
+    Error *err = NULL;
 
     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
-    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+    }
 }
 
 static void vhost_ccw_scsi_instance_init(Object *obj)
@@ -884,9 +1085,7 @@ static void virtio_ccw_rng_realize(VirtioCcwDevice *ccw_dev, Error **errp)
  */
 static inline VirtioCcwDevice *to_virtio_ccw_dev_fast(DeviceState *d)
 {
-    CcwDevice *ccw_dev = to_ccw_dev_fast(d);
-
-    return container_of(ccw_dev, VirtioCcwDevice, parent_obj);
+    return container_of(d, VirtioCcwDevice, parent_obj);
 }
 
 static uint8_t virtio_set_ind_atomic(SubchDev *sch, uint64_t ind_loc,
@@ -906,7 +1105,6 @@ static uint8_t virtio_set_ind_atomic(SubchDev *sch, uint64_t ind_loc,
         ind_old = *ind_addr;
         ind_new = ind_old | to_be_set;
     } while (atomic_cmpxchg(ind_addr, ind_old, ind_new) != ind_old);
-    trace_virtio_ccw_set_ind(ind_loc, ind_old, ind_new);
     cpu_physical_memory_unmap(ind_addr, len, 1, len);
 
     return ind_old;
@@ -915,8 +1113,7 @@ static uint8_t virtio_set_ind_atomic(SubchDev *sch, uint64_t ind_loc,
 static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
 {
     VirtioCcwDevice *dev = to_virtio_ccw_dev_fast(d);
-    CcwDevice *ccw_dev = to_ccw_dev_fast(d);
-    SubchDev *sch = ccw_dev->sch;
+    SubchDev *sch = dev->sch;
     uint64_t indicators;
 
     /* queue indicators + secondary indicators */
@@ -974,10 +1171,9 @@ static void virtio_ccw_reset(DeviceState *d)
 {
     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
     VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
-    CcwDevice *ccw_dev = CCW_DEVICE(d);
 
     virtio_ccw_reset_virtio(dev, vdev);
-    css_reset_sch(ccw_dev->sch);
+    css_reset_sch(dev->sch);
 }
 
 static void virtio_ccw_vmstate_change(DeviceState *d, bool running)
@@ -993,17 +1189,29 @@ static void virtio_ccw_vmstate_change(DeviceState *d, bool running)
 
 static bool virtio_ccw_query_guest_notifiers(DeviceState *d)
 {
-    CcwDevice *dev = CCW_DEVICE(d);
+    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
 
     return !!(dev->sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA);
 }
 
+static int virtio_ccw_set_host_notifier(DeviceState *d, int n, bool assign)
+{
+    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
+
+    /* Stop using the generic ioeventfd, we are doing eventfd handling
+     * ourselves below */
+    dev->ioeventfd_disabled = assign;
+    if (assign) {
+        virtio_ccw_stop_ioeventfd(dev);
+    }
+    return virtio_ccw_set_guest2host_notifier(dev, n, assign, false);
+}
+
 static int virtio_ccw_get_mappings(VirtioCcwDevice *dev)
 {
     int r;
-    CcwDevice *ccw_dev = CCW_DEVICE(dev);
 
-    if (!ccw_dev->sch->thinint_active) {
+    if (!dev->sch->thinint_active) {
         return -EINVAL;
     }
 
@@ -1125,8 +1333,7 @@ static int virtio_ccw_set_guest_notifiers(DeviceState *d, int nvqs,
 {
     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
     VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
-    CcwDevice *ccw_dev = CCW_DEVICE(d);
-    bool with_irqfd = ccw_dev->sch->thinint_active && kvm_irqfds_enabled();
+    bool with_irqfd = dev->sch->thinint_active && kvm_irqfds_enabled();
     int r, n;
 
     if (with_irqfd && assigned) {
@@ -1185,8 +1392,7 @@ static int virtio_ccw_load_queue(DeviceState *d, int n, QEMUFile *f)
 static void virtio_ccw_save_config(DeviceState *d, QEMUFile *f)
 {
     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
-    CcwDevice *ccw_dev = CCW_DEVICE(d);
-    SubchDev *s = ccw_dev->sch;
+    SubchDev *s = dev->sch;
     VirtIODevice *vdev = virtio_ccw_get_vdev(s);
 
     subch_device_save(s, f);
@@ -1220,8 +1426,7 @@ static void virtio_ccw_save_config(DeviceState *d, QEMUFile *f)
 static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f)
 {
     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
-    CcwDevice *ccw_dev = CCW_DEVICE(d);
-    SubchDev *s = ccw_dev->sch;
+    SubchDev *s = dev->sch;
     VirtIODevice *vdev = virtio_ccw_get_vdev(s);
     int len;
 
@@ -1266,12 +1471,11 @@ static void virtio_ccw_device_plugged(DeviceState *d, Error **errp)
 {
     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
     VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
-    CcwDevice *ccw_dev = CCW_DEVICE(d);
-    SubchDev *sch = ccw_dev->sch;
+    SubchDev *sch = dev->sch;
     int n = virtio_get_num_queues(vdev);
 
     if (virtio_get_num_queues(vdev) > VIRTIO_CCW_QUEUE_MAX) {
-        error_setg(errp, "The number of virtqueues %d "
+        error_setg(errp, "The nubmer of virtqueues %d "
                    "exceeds ccw limit %d", n,
                    VIRTIO_CCW_QUEUE_MAX);
         return;
@@ -1311,7 +1515,7 @@ static void virtio_ccw_device_unplugged(DeviceState *d)
 /**************** Virtio-ccw Bus Device Descriptions *******************/
 
 static Property virtio_ccw_net_properties[] = {
-    DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
+    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
     DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
                     VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
@@ -1340,7 +1544,7 @@ static const TypeInfo virtio_ccw_net = {
 };
 
 static Property virtio_ccw_blk_properties[] = {
-    DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
+    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
     DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
                     VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
@@ -1369,7 +1573,7 @@ static const TypeInfo virtio_ccw_blk = {
 };
 
 static Property virtio_ccw_serial_properties[] = {
-    DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
+    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
     DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
                     VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
@@ -1398,7 +1602,7 @@ static const TypeInfo virtio_ccw_serial = {
 };
 
 static Property virtio_ccw_balloon_properties[] = {
-    DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
+    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
     DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
                     VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
@@ -1427,7 +1631,7 @@ static const TypeInfo virtio_ccw_balloon = {
 };
 
 static Property virtio_ccw_scsi_properties[] = {
-    DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
+    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
     DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
                     VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
@@ -1457,7 +1661,7 @@ static const TypeInfo virtio_ccw_scsi = {
 
 #ifdef CONFIG_VHOST_SCSI
 static Property vhost_ccw_scsi_properties[] = {
-    DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
+    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
     DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
                        VIRTIO_CCW_MAX_REV),
     DEFINE_PROP_END_OF_LIST(),
@@ -1495,7 +1699,7 @@ static void virtio_ccw_rng_instance_init(Object *obj)
 }
 
 static Property virtio_ccw_rng_properties[] = {
-    DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
+    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
     DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
                     VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
@@ -1542,17 +1746,29 @@ static int virtio_ccw_busdev_exit(DeviceState *dev)
 static void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev,
                                      DeviceState *dev, Error **errp)
 {
-    VirtioCcwDevice *_dev = to_virtio_ccw_dev_fast(dev);
+    VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
+    SubchDev *sch = _dev->sch;
 
     virtio_ccw_stop_ioeventfd(_dev);
+
+    /*
+     * We should arrive here only for device_del, since we don't support
+     * direct hot(un)plug of channels, but only through virtio.
+     */
+    assert(sch != NULL);
+    /* Subchannel is now disabled and no longer valid. */
+    sch->curr_status.pmcw.flags &= ~(PMCW_FLAGS_MASK_ENA |
+                                     PMCW_FLAGS_MASK_DNV);
+
+    css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
+
+    object_unparent(OBJECT(dev));
 }
 
 static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    CCWDeviceClass *k = CCW_DEVICE_CLASS(dc);
 
-    k->unplug = virtio_ccw_busdev_unplug;
     dc->realize = virtio_ccw_busdev_realize;
     dc->exit = virtio_ccw_busdev_exit;
     dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
@@ -1560,13 +1776,44 @@ static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
 
 static const TypeInfo virtio_ccw_device_info = {
     .name = TYPE_VIRTIO_CCW_DEVICE,
-    .parent = TYPE_CCW_DEVICE,
+    .parent = TYPE_DEVICE,
     .instance_size = sizeof(VirtioCcwDevice),
     .class_init = virtio_ccw_device_class_init,
     .class_size = sizeof(VirtIOCCWDeviceClass),
     .abstract = true,
 };
 
+/***************** Virtual-css Bus Bridge Device ********************/
+/* Only required to have the virtio bus as child in the system bus */
+
+static int virtual_css_bridge_init(SysBusDevice *dev)
+{
+    /* nothing */
+    return 0;
+}
+
+static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    k->init = virtual_css_bridge_init;
+    hc->unplug = virtio_ccw_busdev_unplug;
+    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+}
+
+static const TypeInfo virtual_css_bridge_info = {
+    .name          = "virtual-css-bridge",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SysBusDevice),
+    .class_init    = virtual_css_bridge_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_HOTPLUG_HANDLER },
+        { }
+    }
+};
+
 /* virtio-ccw-bus */
 
 static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
@@ -1588,6 +1835,7 @@ static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
     k->notify = virtio_ccw_notify;
     k->vmstate_change = virtio_ccw_vmstate_change;
     k->query_guest_notifiers = virtio_ccw_query_guest_notifiers;
+    k->set_host_notifier = virtio_ccw_set_host_notifier;
     k->set_guest_notifiers = virtio_ccw_set_guest_notifiers;
     k->save_queue = virtio_ccw_save_queue;
     k->load_queue = virtio_ccw_load_queue;
@@ -1596,11 +1844,6 @@ static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
     k->device_plugged = virtio_ccw_device_plugged;
     k->post_plugged = virtio_ccw_post_plugged;
     k->device_unplugged = virtio_ccw_device_unplugged;
-    k->ioeventfd_started = virtio_ccw_ioeventfd_started;
-    k->ioeventfd_set_started = virtio_ccw_ioeventfd_set_started;
-    k->ioeventfd_disabled = virtio_ccw_ioeventfd_disabled;
-    k->ioeventfd_set_disabled = virtio_ccw_ioeventfd_set_disabled;
-    k->ioeventfd_assign = virtio_ccw_ioeventfd_assign;
 }
 
 static const TypeInfo virtio_ccw_bus_info = {
@@ -1612,7 +1855,7 @@ static const TypeInfo virtio_ccw_bus_info = {
 
 #ifdef CONFIG_VIRTFS
 static Property virtio_ccw_9p_properties[] = {
-    DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id),
+    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
     DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
             VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
@@ -1624,9 +1867,13 @@ static void virtio_ccw_9p_realize(VirtioCcwDevice *ccw_dev, Error **errp)
 {
     V9fsCCWState *dev = VIRTIO_9P_CCW(ccw_dev);
     DeviceState *vdev = DEVICE(&dev->vdev);
+    Error *err = NULL;
 
     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
-    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+    }
 }
 
 static void virtio_ccw_9p_class_init(ObjectClass *klass, void *data)
@@ -1661,6 +1908,7 @@ static const TypeInfo virtio_ccw_9p_info = {
 static void virtio_ccw_register(void)
 {
     type_register_static(&virtio_ccw_bus_info);
+    type_register_static(&virtual_css_bus_info);
     type_register_static(&virtio_ccw_device_info);
     type_register_static(&virtio_ccw_serial);
     type_register_static(&virtio_ccw_blk);
@@ -1671,6 +1919,7 @@ static void virtio_ccw_register(void)
     type_register_static(&vhost_ccw_scsi);
 #endif
     type_register_static(&virtio_ccw_rng);
+    type_register_static(&virtual_css_bridge_info);
 #ifdef CONFIG_VIRTFS
     type_register_static(&virtio_ccw_9p_info);
 #endif
index 1c6bc86..66c831b 100644 (file)
 #ifndef HW_S390X_VIRTIO_CCW_H
 #define HW_S390X_VIRTIO_CCW_H
 
-#include "hw/virtio/virtio-blk.h"
-#include "hw/virtio/virtio-net.h"
-#include "hw/virtio/virtio-serial.h"
-#include "hw/virtio/virtio-scsi.h"
+#include <hw/virtio/virtio-blk.h>
+#include <hw/virtio/virtio-net.h>
+#include <hw/virtio/virtio-serial.h>
+#include <hw/virtio/virtio-scsi.h>
 #ifdef CONFIG_VHOST_SCSI
-#include "hw/virtio/vhost-scsi.h"
+#include <hw/virtio/vhost-scsi.h>
 #endif
-#include "hw/virtio/virtio-balloon.h"
-#include "hw/virtio/virtio-rng.h"
-#include "hw/virtio/virtio-bus.h"
+#include <hw/virtio/virtio-balloon.h>
+#include <hw/virtio/virtio-rng.h>
+#include <hw/virtio/virtio-bus.h>
 
-#include "hw/s390x/s390_flic.h"
-#include "hw/s390x/css.h"
-#include "ccw-device.h"
-#include "hw/s390x/css-bridge.h"
+#include "css.h"
+
+#define VIRTUAL_CSSID 0xfe
 
 #define VIRTIO_CCW_CU_TYPE 0x3832
 #define VIRTIO_CCW_CHPID_TYPE 0x32
@@ -67,7 +66,7 @@ typedef struct VirtioBusClass VirtioCcwBusClass;
 typedef struct VirtioCcwDevice VirtioCcwDevice;
 
 typedef struct VirtIOCCWDeviceClass {
-    CCWDeviceClass parent_class;
+    DeviceClass parent_class;
     void (*realize)(VirtioCcwDevice *dev, Error **errp);
     int (*exit)(VirtioCcwDevice *dev);
 } VirtIOCCWDeviceClass;
@@ -78,7 +77,9 @@ typedef struct VirtIOCCWDeviceClass {
 #define VIRTIO_CCW_FLAG_USE_IOEVENTFD   (1 << VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT)
 
 struct VirtioCcwDevice {
-    CcwDevice parent_obj;
+    DeviceState parent_obj;
+    SubchDev *sch;
+    char *bus_id;
     int revision;
     uint32_t max_rev;
     VirtioBusState bus;
@@ -101,6 +102,15 @@ static inline int virtio_ccw_rev_max(VirtioCcwDevice *dev)
     return dev->max_rev;
 }
 
+/* virtual css bus type */
+typedef struct VirtualCssBus {
+    BusState parent_obj;
+} VirtualCssBus;
+
+#define TYPE_VIRTUAL_CSS_BUS "virtual-css-bus"
+#define VIRTUAL_CSS_BUS(obj) \
+     OBJECT_CHECK(VirtualCssBus, (obj), TYPE_VIRTUAL_CSS_BUS)
+
 /* virtio-scsi-ccw */
 
 #define TYPE_VIRTIO_SCSI_CCW "virtio-scsi-ccw"
@@ -180,6 +190,7 @@ typedef struct VirtIORNGCcw {
     VirtIORNG vdev;
 } VirtIORNGCcw;
 
+VirtualCssBus *virtual_css_bus_init(void);
 void virtio_ccw_device_update_status(SubchDev *sch);
 VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch);
 
index 1f2f2d3..baa0a2c 100644 (file)
@@ -574,7 +574,7 @@ static bool esp_mem_accepts(void *opaque, hwaddr addr,
 
 const VMStateDescription vmstate_esp = {
     .name ="esp",
-    .version_id = 4,
+    .version_id = 3,
     .minimum_version_id = 3,
     .fields = (VMStateField[]) {
         VMSTATE_BUFFER(rregs, ESPState),
@@ -585,8 +585,7 @@ const VMStateDescription vmstate_esp = {
         VMSTATE_BUFFER(ti_buf, ESPState),
         VMSTATE_UINT32(status, ESPState),
         VMSTATE_UINT32(dma, ESPState),
-        VMSTATE_PARTIAL_BUFFER(cmdbuf, ESPState, 16),
-        VMSTATE_BUFFER_START_MIDDLE_V(cmdbuf, ESPState, 16, 4),
+        VMSTATE_BUFFER(cmdbuf, ESPState),
         VMSTATE_UINT32(cmdlen, ESPState),
         VMSTATE_UINT32(do_cmd, ESPState),
         VMSTATE_UINT32(dma_left, ESPState),
index e968302..a9ffc32 100644 (file)
@@ -29,7 +29,7 @@
 #include "hw/scsi/scsi.h"
 #include "block/scsi.h"
 #include "trace.h"
-#include "qapi/error.h"
+
 #include "mfi.h"
 
 #define MEGASAS_VERSION_GEN1 "1.70"
 
 #define MEGASAS_FLAG_USE_JBOD      0
 #define MEGASAS_MASK_USE_JBOD      (1 << MEGASAS_FLAG_USE_JBOD)
-#define MEGASAS_FLAG_USE_QUEUE64   1
+#define MEGASAS_FLAG_USE_MSI       1
+#define MEGASAS_MASK_USE_MSI       (1 << MEGASAS_FLAG_USE_MSI)
+#define MEGASAS_FLAG_USE_MSIX      2
+#define MEGASAS_MASK_USE_MSIX      (1 << MEGASAS_FLAG_USE_MSIX)
+#define MEGASAS_FLAG_USE_QUEUE64   3
 #define MEGASAS_MASK_USE_QUEUE64   (1 << MEGASAS_FLAG_USE_QUEUE64)
 
 static const char *mfi_frame_desc[] = {
@@ -92,8 +96,6 @@ typedef struct MegasasState {
     int busy;
     int diag;
     int adp_reset;
-    OnOffAuto msi;
-    OnOffAuto msix;
 
     MegasasCmd *event_cmd;
     int event_locale;
@@ -155,9 +157,14 @@ static bool megasas_use_queue64(MegasasState *s)
     return s->flags & MEGASAS_MASK_USE_QUEUE64;
 }
 
+static bool megasas_use_msi(MegasasState *s)
+{
+    return s->flags & MEGASAS_MASK_USE_MSI;
+}
+
 static bool megasas_use_msix(MegasasState *s)
 {
-    return s->msix != ON_OFF_AUTO_OFF;
+    return s->flags & MEGASAS_MASK_USE_MSIX;
 }
 
 static bool megasas_is_jbod(MegasasState *s)
@@ -403,14 +410,17 @@ static void megasas_encode_lba(uint8_t *cdb, uint64_t lba,
 static uint64_t megasas_fw_time(void)
 {
     struct tm curtime;
+    uint64_t bcd_time;
 
     qemu_get_timedate(&curtime, 0);
-    return ((uint64_t)curtime.tm_sec & 0xff) << 48 |
+    bcd_time = ((uint64_t)curtime.tm_sec & 0xff) << 48 |
         ((uint64_t)curtime.tm_min & 0xff)  << 40 |
         ((uint64_t)curtime.tm_hour & 0xff) << 32 |
         ((uint64_t)curtime.tm_mday & 0xff) << 24 |
         ((uint64_t)curtime.tm_mon & 0xff)  << 16 |
         ((uint64_t)(curtime.tm_year + 1900) & 0xffff);
+
+    return bcd_time;
 }
 
 /*
@@ -1981,7 +1991,11 @@ static void megasas_handle_frame(MegasasState *s, uint64_t frame_addr,
         break;
     }
     if (frame_status != MFI_STAT_INVALID_STATUS) {
-        cmd->frame->header.cmd_status = frame_status;
+        if (cmd->frame) {
+            cmd->frame->header.cmd_status = frame_status;
+        } else {
+            megasas_frame_set_cmd_status(s, frame_addr, frame_status);
+        }
         megasas_unmap_frame(s, cmd);
         megasas_complete_frame(s, cmd->context);
     }
@@ -2298,7 +2312,9 @@ static void megasas_scsi_uninit(PCIDevice *d)
     if (megasas_use_msix(s)) {
         msix_uninit(d, &s->mmio_io, &s->mmio_io);
     }
-    msi_uninit(d);
+    if (megasas_use_msi(s)) {
+        msi_uninit(d);
+    }
 }
 
 static const struct SCSIBusInfo megasas_scsi_info = {
@@ -2319,8 +2335,6 @@ static void megasas_scsi_realize(PCIDevice *dev, Error **errp)
     MegasasBaseClass *b = MEGASAS_DEVICE_GET_CLASS(s);
     uint8_t *pci_conf;
     int i, bar_type;
-    Error *err = NULL;
-    int ret;
 
     pci_conf = dev->config;
 
@@ -2329,24 +2343,6 @@ static void megasas_scsi_realize(PCIDevice *dev, Error **errp)
     /* Interrupt pin 1 */
     pci_conf[PCI_INTERRUPT_PIN] = 0x01;
 
-    if (s->msi != ON_OFF_AUTO_OFF) {
-        ret = msi_init(dev, 0x50, 1, true, false, &err);
-        /* Any error other than -ENOTSUP(board's MSI support is broken)
-         * is a programming error */
-        assert(!ret || ret == -ENOTSUP);
-        if (ret && s->msi == ON_OFF_AUTO_ON) {
-            /* Can't satisfy user's explicit msi=on request, fail */
-            error_append_hint(&err, "You have to use msi=auto (default) or "
-                    "msi=off with this machine type.\n");
-            error_propagate(errp, err);
-            return;
-        } else if (ret) {
-            /* With msi=auto, we fall back to MSI off silently */
-            s->msi = ON_OFF_AUTO_OFF;
-            error_free(err);
-        }
-    }
-
     memory_region_init_io(&s->mmio_io, OBJECT(s), &megasas_mmio_ops, s,
                           "megasas-mmio", 0x4000);
     memory_region_init_io(&s->port_io, OBJECT(s), &megasas_port_ops, s,
@@ -2354,10 +2350,14 @@ static void megasas_scsi_realize(PCIDevice *dev, Error **errp)
     memory_region_init_io(&s->queue_io, OBJECT(s), &megasas_queue_ops, s,
                           "megasas-queue", 0x40000);
 
+    if (megasas_use_msi(s) &&
+        msi_init(dev, 0x50, 1, true, false)) {
+        s->flags &= ~MEGASAS_MASK_USE_MSI;
+    }
     if (megasas_use_msix(s) &&
         msix_init(dev, 15, &s->mmio_io, b->mmio_bar, 0x2000,
                   &s->mmio_io, b->mmio_bar, 0x3800, 0x68)) {
-        s->msix = ON_OFF_AUTO_OFF;
+        s->flags &= ~MEGASAS_MASK_USE_MSIX;
     }
     if (pci_is_express(dev)) {
         pcie_endpoint_cap_init(dev, 0xa0);
@@ -2425,8 +2425,10 @@ static Property megasas_properties_gen1[] = {
                        MEGASAS_DEFAULT_FRAMES),
     DEFINE_PROP_STRING("hba_serial", MegasasState, hba_serial),
     DEFINE_PROP_UINT64("sas_address", MegasasState, sas_addr, 0),
-    DEFINE_PROP_ON_OFF_AUTO("msi", MegasasState, msi, ON_OFF_AUTO_AUTO),
-    DEFINE_PROP_ON_OFF_AUTO("msix", MegasasState, msix, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_BIT("use_msi", MegasasState, flags,
+                    MEGASAS_FLAG_USE_MSI, false),
+    DEFINE_PROP_BIT("use_msix", MegasasState, flags,
+                    MEGASAS_FLAG_USE_MSIX, false),
     DEFINE_PROP_BIT("use_jbod", MegasasState, flags,
                     MEGASAS_FLAG_USE_JBOD, false),
     DEFINE_PROP_END_OF_LIST(),
@@ -2439,8 +2441,10 @@ static Property megasas_properties_gen2[] = {
                        MEGASAS_GEN2_DEFAULT_FRAMES),
     DEFINE_PROP_STRING("hba_serial", MegasasState, hba_serial),
     DEFINE_PROP_UINT64("sas_address", MegasasState, sas_addr, 0),
-    DEFINE_PROP_ON_OFF_AUTO("msi", MegasasState, msi, ON_OFF_AUTO_AUTO),
-    DEFINE_PROP_ON_OFF_AUTO("msix", MegasasState, msix, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_BIT("use_msi", MegasasState, flags,
+                    MEGASAS_FLAG_USE_MSI, true),
+    DEFINE_PROP_BIT("use_msix", MegasasState, flags,
+                    MEGASAS_FLAG_USE_MSIX, true),
     DEFINE_PROP_BIT("use_jbod", MegasasState, flags,
                     MEGASAS_FLAG_USE_JBOD, false),
     DEFINE_PROP_END_OF_LIST(),
index e67a5c0..29d4177 100644 (file)
@@ -30,8 +30,8 @@
  * SUCH DAMAGE.
  */
 
-#ifndef SCSI_MFI_H
-#define SCSI_MFI_H
+#ifndef MFI_REG_H
+#define MFI_REG_H
 
 /*
  * MegaRAID SAS MFI firmware definitions
@@ -1269,4 +1269,4 @@ struct mfi_config_data {
 #define MFI_SCSI_MAX_CMDS       8
 #define MFI_SCSI_MAX_CDB_LEN   16
 
-#endif /* SCSI_MFI_H */
+#endif /* MFI_REG_H */
index 0e0a22f..be88e16 100644 (file)
@@ -32,7 +32,7 @@
 #include "hw/scsi/scsi.h"
 #include "block/scsi.h"
 #include "trace.h"
-#include "qapi/error.h"
+
 #include "mptsas.h"
 #include "mpi.h"
 
@@ -63,7 +63,7 @@ static void mptsas_update_interrupt(MPTSASState *s)
     PCIDevice *pci = (PCIDevice *) s;
     uint32_t state = s->intr_status & ~(s->intr_mask | MPI_HIS_IOP_DOORBELL_STATUS);
 
-    if (msi_enabled(pci)) {
+    if (s->msi_in_use && msi_enabled(pci)) {
         if (state) {
             trace_mptsas_irq_msi(s);
             msi_notify(pci, 0);
@@ -1273,32 +1273,10 @@ static void mptsas_scsi_init(PCIDevice *dev, Error **errp)
 {
     DeviceState *d = DEVICE(dev);
     MPTSASState *s = MPT_SAS(dev);
-    Error *err = NULL;
-    int ret;
 
     dev->config[PCI_LATENCY_TIMER] = 0;
     dev->config[PCI_INTERRUPT_PIN] = 0x01;
 
-    if (s->msi != ON_OFF_AUTO_OFF) {
-        ret = msi_init(dev, 0, 1, true, false, &err);
-        /* Any error other than -ENOTSUP(board's MSI support is broken)
-         * is a programming error */
-        assert(!ret || ret == -ENOTSUP);
-        if (ret && s->msi == ON_OFF_AUTO_ON) {
-            /* Can't satisfy user's explicit msi=on request, fail */
-            error_append_hint(&err, "You have to use msi=auto (default) or "
-                    "msi=off with this machine type.\n");
-            error_propagate(errp, err);
-            return;
-        }
-        assert(!err || s->msi == ON_OFF_AUTO_AUTO);
-        /* With msi=auto, we fall back to MSI off silently */
-        error_free(err);
-
-        /* Only used for migration.  */
-        s->msi_in_use = (ret == 0);
-    }
-
     memory_region_init_io(&s->mmio_io, OBJECT(s), &mptsas_mmio_ops, s,
                           "mptsas-mmio", 0x4000);
     memory_region_init_io(&s->port_io, OBJECT(s), &mptsas_port_ops, s,
@@ -1306,6 +1284,11 @@ static void mptsas_scsi_init(PCIDevice *dev, Error **errp)
     memory_region_init_io(&s->diag_io, OBJECT(s), &mptsas_diag_ops, s,
                           "mptsas-diag", 0x10000);
 
+    if (s->msi_available &&
+        msi_init(dev, 0, 1, true, false) >= 0) {
+        s->msi_in_use = true;
+    }
+
     pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->port_io);
     pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY |
                                  PCI_BASE_ADDRESS_MEM_TYPE_32, &s->mmio_io);
@@ -1336,7 +1319,9 @@ static void mptsas_scsi_uninit(PCIDevice *dev)
     MPTSASState *s = MPT_SAS(dev);
 
     qemu_bh_delete(s->request_bh);
-    msi_uninit(dev);
+    if (s->msi_in_use) {
+        msi_uninit(dev);
+    }
 }
 
 static void mptsas_reset(DeviceState *dev)
@@ -1373,6 +1358,7 @@ static const VMStateDescription vmstate_mptsas = {
     .fields      = (VMStateField[]) {
         VMSTATE_PCI_DEVICE(dev, MPTSASState),
         VMSTATE_BOOL(msi_in_use, MPTSASState),
+
         VMSTATE_UINT32(state, MPTSASState),
         VMSTATE_UINT8(who_init, MPTSASState),
         VMSTATE_UINT8(doorbell_state, MPTSASState),
@@ -1417,7 +1403,7 @@ static const VMStateDescription vmstate_mptsas = {
 static Property mptsas_properties[] = {
     DEFINE_PROP_UINT64("sas_address", MPTSASState, sas_addr, 0),
     /* TODO: test MSI support under Windows */
-    DEFINE_PROP_ON_OFF_AUTO("msi", MPTSASState, msi, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_BIT("msi", MPTSASState, msi_available, 0, true),
     DEFINE_PROP_END_OF_LIST(),
 };
 
index 0436a33..595f81f 100644 (file)
@@ -27,8 +27,7 @@ struct MPTSASState {
     MemoryRegion diag_io;
     QEMUBH *request_bh;
 
-    /* properties */
-    OnOffAuto msi;
+    uint32_t msi_available;
     uint64_t sas_addr;
 
     bool msi_in_use;
index 297216d..ad6f398 100644 (file)
@@ -461,14 +461,6 @@ static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
     return true;
 }
 
-static size_t scsi_sense_len(SCSIRequest *req)
-{
-    if (req->dev->type == TYPE_SCANNER)
-        return SCSI_SENSE_LEN_SCANNER;
-    else
-        return SCSI_SENSE_LEN;
-}
-
 static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
 {
     SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
@@ -485,7 +477,7 @@ static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
         }
         break;
     case REQUEST_SENSE:
-        scsi_target_alloc_buf(&r->req, scsi_sense_len(req));
+        scsi_target_alloc_buf(&r->req, SCSI_SENSE_LEN);
         r->len = scsi_device_get_sense(r->req.dev, r->buf,
                                        MIN(req->cmd.xfer, r->buf_len),
                                        (req->cmd.buf[1] & 1) == 0);
@@ -1140,29 +1132,6 @@ static int scsi_req_medium_changer_xfer(SCSICommand *cmd, SCSIDevice *dev, uint8
     return 0;
 }
 
-static int scsi_req_scanner_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
-{
-    switch (buf[0]) {
-    /* Scanner commands */
-    case OBJECT_POSITION:
-        cmd->xfer = 0;
-        break;
-    case SCAN:
-        cmd->xfer = buf[4];
-        break;
-    case READ_10:
-    case SEND:
-    case GET_WINDOW:
-    case SET_WINDOW:
-        cmd->xfer = buf[8] | (buf[7] << 8) | (buf[6] << 16);
-        break;
-    default:
-        /* GET_DATA_BUFFER_STATUS xfer handled by scsi_req_xfer */
-        return scsi_req_xfer(cmd, dev, buf);
-    }
-
-    return 0;
-}
 
 static void scsi_cmd_xfer_mode(SCSICommand *cmd)
 {
@@ -1209,11 +1178,6 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd)
     case SEND_DVD_STRUCTURE:
     case PERSISTENT_RESERVE_OUT:
     case MAINTENANCE_OUT:
-    case SET_WINDOW:
-    case SCAN:
-        /* SCAN conflicts with START_STOP.  START_STOP has cmd->xfer set to 0 for
-         * non-scanner devices, so we only get here for SCAN and not for START_STOP.
-         */
         cmd->mode = SCSI_XFER_TO_DEV;
         break;
     case ATA_PASSTHROUGH_12:
@@ -1294,9 +1258,6 @@ int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf)
     case TYPE_MEDIUM_CHANGER:
         rc = scsi_req_medium_changer_xfer(cmd, dev, buf);
         break;
-    case TYPE_SCANNER:
-        rc = scsi_req_scanner_length(cmd, dev, buf);
-        break;
     default:
         rc = scsi_req_xfer(cmd, dev, buf);
         break;
index 836a155..c3ce54a 100644 (file)
@@ -53,21 +53,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
 #define DEFAULT_MAX_UNMAP_SIZE      (1 << 30)   /* 1 GB */
 #define DEFAULT_MAX_IO_SIZE         INT_MAX     /* 2 GB - 1 block */
 
-#define TYPE_SCSI_DISK_BASE         "scsi-disk-base"
-
-#define SCSI_DISK_BASE(obj) \
-     OBJECT_CHECK(SCSIDiskState, (obj), TYPE_SCSI_DISK_BASE)
-#define SCSI_DISK_BASE_CLASS(klass) \
-     OBJECT_CLASS_CHECK(SCSIDiskClass, (klass), TYPE_SCSI_DISK_BASE)
-#define SCSI_DISK_BASE_GET_CLASS(obj) \
-     OBJECT_GET_CLASS(SCSIDiskClass, (obj), TYPE_SCSI_DISK_BASE)
-
-typedef struct SCSIDiskClass {
-    SCSIDeviceClass parent_class;
-    DMAIOFunc       *dma_readv;
-    DMAIOFunc       *dma_writev;
-    bool            (*need_fua_emulation)(SCSICommand *cmd);
-} SCSIDiskClass;
+typedef struct SCSIDiskState SCSIDiskState;
 
 typedef struct SCSIDiskReq {
     SCSIRequest req;
@@ -76,18 +62,16 @@ typedef struct SCSIDiskReq {
     uint32_t sector_count;
     uint32_t buflen;
     bool started;
-    bool need_fua_emulation;
     struct iovec iov;
     QEMUIOVector qiov;
     BlockAcctCookie acct;
-    unsigned char *status;
 } SCSIDiskReq;
 
 #define SCSI_DISK_F_REMOVABLE             0
 #define SCSI_DISK_F_DPOFUA                1
 #define SCSI_DISK_F_NO_REMOVABLE_DEVOPS   2
 
-typedef struct SCSIDiskState
+struct SCSIDiskState
 {
     SCSIDevice qdev;
     uint32_t features;
@@ -104,7 +88,7 @@ typedef struct SCSIDiskState
     char *product;
     bool tray_open;
     bool tray_locked;
-} SCSIDiskState;
+};
 
 static int scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed);
 
@@ -124,7 +108,7 @@ static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense)
     scsi_req_complete(&r->req, CHECK_CONDITION);
 }
 
-static void scsi_init_iovec(SCSIDiskReq *r, size_t size)
+static uint32_t scsi_init_iovec(SCSIDiskReq *r, size_t size)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
 
@@ -134,6 +118,7 @@ static void scsi_init_iovec(SCSIDiskReq *r, size_t size)
     }
     r->iov.iov_len = MIN(r->sector_count * 512, r->buflen);
     qemu_iovec_init_external(&r->qiov, &r->iov, 1);
+    return r->qiov.size / 512;
 }
 
 static void scsi_disk_save_request(QEMUFile *f, SCSIRequest *req)
@@ -177,29 +162,6 @@ static void scsi_disk_load_request(QEMUFile *f, SCSIRequest *req)
     qemu_iovec_init_external(&r->qiov, &r->iov, 1);
 }
 
-static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed)
-{
-    if (r->req.io_canceled) {
-        scsi_req_cancel_complete(&r->req);
-        return true;
-    }
-
-    if (ret < 0) {
-        return scsi_handle_rw_error(r, -ret, acct_failed);
-    }
-
-    if (r->status && *r->status) {
-        if (acct_failed) {
-            SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-            block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
-        }
-        scsi_req_complete(&r->req, *r->status);
-        return true;
-    }
-
-    return false;
-}
-
 static void scsi_aio_complete(void *opaque, int ret)
 {
     SCSIDiskReq *r = (SCSIDiskReq *)opaque;
@@ -207,10 +169,17 @@ static void scsi_aio_complete(void *opaque, int ret)
 
     assert(r->req.aiocb != NULL);
     r->req.aiocb = NULL;
-    if (scsi_disk_req_check_error(r, ret, true)) {
+    if (r->req.io_canceled) {
+        scsi_req_cancel_complete(&r->req);
         goto done;
     }
 
+    if (ret < 0) {
+        if (scsi_handle_rw_error(r, -ret, true)) {
+            goto done;
+        }
+    }
+
     block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
     scsi_req_complete(&r->req, GOOD);
 
@@ -249,9 +218,13 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
 
     assert(r->req.aiocb == NULL);
-    assert(!r->req.io_canceled);
 
-    if (r->need_fua_emulation) {
+    if (r->req.io_canceled) {
+        scsi_req_cancel_complete(&r->req);
+        goto done;
+    }
+
+    if (scsi_is_cmd_fua(&r->req.cmd)) {
         block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,
                          BLOCK_ACCT_FLUSH);
         r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete, r);
@@ -259,16 +232,26 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
     }
 
     scsi_req_complete(&r->req, GOOD);
+
+done:
     scsi_req_unref(&r->req);
 }
 
 static void scsi_dma_complete_noio(SCSIDiskReq *r, int ret)
 {
     assert(r->req.aiocb == NULL);
-    if (scsi_disk_req_check_error(r, ret, false)) {
+
+    if (r->req.io_canceled) {
+        scsi_req_cancel_complete(&r->req);
         goto done;
     }
 
+    if (ret < 0) {
+        if (scsi_handle_rw_error(r, -ret, false)) {
+            goto done;
+        }
+    }
+
     r->sector += r->sector_count;
     r->sector_count = 0;
     if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
@@ -306,10 +289,17 @@ static void scsi_read_complete(void * opaque, int ret)
 
     assert(r->req.aiocb != NULL);
     r->req.aiocb = NULL;
-    if (scsi_disk_req_check_error(r, ret, true)) {
+    if (r->req.io_canceled) {
+        scsi_req_cancel_complete(&r->req);
         goto done;
     }
 
+    if (ret < 0) {
+        if (scsi_handle_rw_error(r, -ret, true)) {
+            goto done;
+        }
+    }
+
     block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
     DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->qiov.size);
 
@@ -326,29 +316,35 @@ done:
 static void scsi_do_read(SCSIDiskReq *r, int ret)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-    SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
+    uint32_t n;
 
     assert (r->req.aiocb == NULL);
-    if (scsi_disk_req_check_error(r, ret, false)) {
+
+    if (r->req.io_canceled) {
+        scsi_req_cancel_complete(&r->req);
         goto done;
     }
 
+    if (ret < 0) {
+        if (scsi_handle_rw_error(r, -ret, false)) {
+            goto done;
+        }
+    }
+
     /* The request is used as the AIO opaque value, so add a ref.  */
     scsi_req_ref(&r->req);
 
     if (r->req.sg) {
         dma_acct_start(s->qdev.conf.blk, &r->acct, r->req.sg, BLOCK_ACCT_READ);
         r->req.resid -= r->req.sg->size;
-        r->req.aiocb = dma_blk_io(blk_get_aio_context(s->qdev.conf.blk),
-                                  r->req.sg, r->sector << BDRV_SECTOR_BITS,
-                                  sdc->dma_readv, r, scsi_dma_complete, r,
-                                  DMA_DIRECTION_FROM_DEVICE);
+        r->req.aiocb = dma_blk_read(s->qdev.conf.blk, r->req.sg, r->sector,
+                                    scsi_dma_complete, r);
     } else {
-        scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
+        n = scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
         block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
-                         r->qiov.size, BLOCK_ACCT_READ);
-        r->req.aiocb = sdc->dma_readv(r->sector << BDRV_SECTOR_BITS, &r->qiov,
-                                      scsi_read_complete, r, r);
+                         n * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
+        r->req.aiocb = blk_aio_readv(s->qdev.conf.blk, r->sector, &r->qiov, n,
+                                     scsi_read_complete, r);
     }
 
 done:
@@ -403,7 +399,7 @@ static void scsi_read_data(SCSIRequest *req)
 
     first = !r->started;
     r->started = true;
-    if (first && r->need_fua_emulation) {
+    if (first && scsi_is_cmd_fua(&r->req.cmd)) {
         block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,
                          BLOCK_ACCT_FLUSH);
         r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_do_read_cb, r);
@@ -460,10 +456,18 @@ static void scsi_write_complete_noio(SCSIDiskReq *r, int ret)
     uint32_t n;
 
     assert (r->req.aiocb == NULL);
-    if (scsi_disk_req_check_error(r, ret, false)) {
+
+    if (r->req.io_canceled) {
+        scsi_req_cancel_complete(&r->req);
         goto done;
     }
 
+    if (ret < 0) {
+        if (scsi_handle_rw_error(r, -ret, false)) {
+            goto done;
+        }
+    }
+
     n = r->qiov.size / 512;
     r->sector += n;
     r->sector_count -= n;
@@ -500,7 +504,7 @@ static void scsi_write_data(SCSIRequest *req)
 {
     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-    SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
+    uint32_t n;
 
     /* No data transfer may already be in progress */
     assert(r->req.aiocb == NULL);
@@ -537,15 +541,14 @@ static void scsi_write_data(SCSIRequest *req)
     if (r->req.sg) {
         dma_acct_start(s->qdev.conf.blk, &r->acct, r->req.sg, BLOCK_ACCT_WRITE);
         r->req.resid -= r->req.sg->size;
-        r->req.aiocb = dma_blk_io(blk_get_aio_context(s->qdev.conf.blk),
-                                  r->req.sg, r->sector << BDRV_SECTOR_BITS,
-                                  sdc->dma_writev, r, scsi_dma_complete, r,
-                                  DMA_DIRECTION_TO_DEVICE);
+        r->req.aiocb = dma_blk_write(s->qdev.conf.blk, r->req.sg, r->sector,
+                                     scsi_dma_complete, r);
     } else {
+        n = r->qiov.size / 512;
         block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
-                         r->qiov.size, BLOCK_ACCT_WRITE);
-        r->req.aiocb = sdc->dma_writev(r->sector << BDRV_SECTOR_BITS, &r->qiov,
-                                       scsi_write_complete, r, r);
+                         n * BDRV_SECTOR_SIZE, BLOCK_ACCT_WRITE);
+        r->req.aiocb = blk_aio_writev(s->qdev.conf.blk, r->sector, &r->qiov, n,
+                                      scsi_write_complete, r);
     }
 }
 
@@ -1597,10 +1600,18 @@ static void scsi_unmap_complete_noio(UnmapCBData *data, int ret)
     uint32_t nb_sectors;
 
     assert(r->req.aiocb == NULL);
-    if (scsi_disk_req_check_error(r, ret, false)) {
+
+    if (r->req.io_canceled) {
+        scsi_req_cancel_complete(&r->req);
         goto done;
     }
 
+    if (ret < 0) {
+        if (scsi_handle_rw_error(r, -ret, false)) {
+            goto done;
+        }
+    }
+
     if (data->count > 0) {
         sector_num = ldq_be_p(&data->inbuf[0]);
         nb_sectors = ldl_be_p(&data->inbuf[8]) & 0xffffffffULL;
@@ -1609,10 +1620,10 @@ static void scsi_unmap_complete_noio(UnmapCBData *data, int ret)
             goto done;
         }
 
-        r->req.aiocb = blk_aio_pdiscard(s->qdev.conf.blk,
-                                        sector_num * s->qdev.blocksize,
-                                        nb_sectors * s->qdev.blocksize,
-                                        scsi_unmap_complete, data);
+        r->req.aiocb = blk_aio_discard(s->qdev.conf.blk,
+                                       sector_num * (s->qdev.blocksize / 512),
+                                       nb_sectors * (s->qdev.blocksize / 512),
+                                       scsi_unmap_complete, data);
         data->count--;
         data->inbuf += 16;
         return;
@@ -1700,10 +1711,17 @@ static void scsi_write_same_complete(void *opaque, int ret)
 
     assert(r->req.aiocb != NULL);
     r->req.aiocb = NULL;
-    if (scsi_disk_req_check_error(r, ret, true)) {
+    if (r->req.io_canceled) {
+        scsi_req_cancel_complete(&r->req);
         goto done;
     }
 
+    if (ret < 0) {
+        if (scsi_handle_rw_error(r, -ret, true)) {
+            goto done;
+        }
+    }
+
     block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
 
     data->nb_sectors -= data->iov.iov_len / 512;
@@ -1712,13 +1730,13 @@ static void scsi_write_same_complete(void *opaque, int ret)
     if (data->iov.iov_len) {
         block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
                          data->iov.iov_len, BLOCK_ACCT_WRITE);
-        /* Reinitialize qiov, to handle unaligned WRITE SAME request
-         * where final qiov may need smaller size */
+        /* blk_aio_write doesn't like the qiov size being different from
+         * nb_sectors, make sure they match.
+         */
         qemu_iovec_init_external(&data->qiov, &data->iov, 1);
-        r->req.aiocb = blk_aio_pwritev(s->qdev.conf.blk,
-                                       data->sector << BDRV_SECTOR_BITS,
-                                       &data->qiov, 0,
-                                       scsi_write_same_complete, data);
+        r->req.aiocb = blk_aio_writev(s->qdev.conf.blk, data->sector,
+                                      &data->qiov, data->iov.iov_len / 512,
+                                      scsi_write_same_complete, data);
         return;
     }
 
@@ -1762,9 +1780,9 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
         block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
                          nb_sectors * s->qdev.blocksize,
                         BLOCK_ACCT_WRITE);
-        r->req.aiocb = blk_aio_pwrite_zeroes(s->qdev.conf.blk,
-                                r->req.cmd.lba * s->qdev.blocksize,
-                                nb_sectors * s->qdev.blocksize,
+        r->req.aiocb = blk_aio_write_zeroes(s->qdev.conf.blk,
+                                r->req.cmd.lba * (s->qdev.blocksize / 512),
+                                nb_sectors * (s->qdev.blocksize / 512),
                                 flags, scsi_aio_complete, r);
         return;
     }
@@ -1785,10 +1803,9 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
     scsi_req_ref(&r->req);
     block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
                      data->iov.iov_len, BLOCK_ACCT_WRITE);
-    r->req.aiocb = blk_aio_pwritev(s->qdev.conf.blk,
-                                   data->sector << BDRV_SECTOR_BITS,
-                                   &data->qiov, 0,
-                                   scsi_write_same_complete, data);
+    r->req.aiocb = blk_aio_writev(s->qdev.conf.blk, data->sector,
+                                  &data->qiov, data->iov.iov_len / 512,
+                                  scsi_write_same_complete, data);
 }
 
 static void scsi_disk_emulate_write_data(SCSIRequest *req)
@@ -2060,13 +2077,13 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
         }
         break;
     case MODE_SELECT:
-        DPRINTF("Mode Select(6) (len %lu)\n", (unsigned long)r->req.cmd.xfer);
+        DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
         break;
     case MODE_SELECT_10:
-        DPRINTF("Mode Select(10) (len %lu)\n", (unsigned long)r->req.cmd.xfer);
+        DPRINTF("Mode Select(10) (len %lu)\n", (long)r->req.cmd.xfer);
         break;
     case UNMAP:
-        DPRINTF("Unmap (len %lu)\n", (unsigned long)r->req.cmd.xfer);
+        DPRINTF("Unmap (len %lu)\n", (long)r->req.cmd.xfer);
         break;
     case VERIFY_10:
     case VERIFY_12:
@@ -2080,7 +2097,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
     case WRITE_SAME_16:
         DPRINTF("WRITE SAME %d (len %lu)\n",
                 req->cmd.buf[0] == WRITE_SAME_10 ? 10 : 16,
-                (unsigned long)r->req.cmd.xfer);
+                (long)r->req.cmd.xfer);
         break;
     default:
         DPRINTF("Unknown SCSI command (%2.2x=%s)\n", buf[0],
@@ -2120,7 +2137,6 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
 {
     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
-    SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
     uint32_t len;
     uint8_t command;
 
@@ -2179,7 +2195,6 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
         scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
         return 0;
     }
-    r->need_fua_emulation = sdc->need_fua_emulation(&r->req.cmd);
     if (r->sector_count == 0) {
         scsi_req_complete(&r->req, GOOD);
     }
@@ -2309,7 +2324,6 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
             return;
         }
     }
-    blkconf_apply_backend_options(&dev->conf);
 
     if (s->qdev.conf.discard_granularity == -1) {
         s->qdev.conf.discard_granularity =
@@ -2563,145 +2577,16 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
     scsi_generic_read_device_identification(&s->qdev);
 }
 
-typedef struct SCSIBlockReq {
-    SCSIDiskReq req;
-    sg_io_hdr_t io_header;
-
-    /* Selected bytes of the original CDB, copied into our own CDB.  */
-    uint8_t cmd, cdb1, group_number;
-
-    /* CDB passed to SG_IO.  */
-    uint8_t cdb[16];
-} SCSIBlockReq;
-
-static BlockAIOCB *scsi_block_do_sgio(SCSIBlockReq *req,
-                                      int64_t offset, QEMUIOVector *iov,
-                                      int direction,
-                                      BlockCompletionFunc *cb, void *opaque)
-{
-    sg_io_hdr_t *io_header = &req->io_header;
-    SCSIDiskReq *r = &req->req;
-    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-    int nb_logical_blocks;
-    uint64_t lba;
-    BlockAIOCB *aiocb;
-
-    /* This is not supported yet.  It can only happen if the guest does
-     * reads and writes that are not aligned to one logical sectors
-     * _and_ cover multiple MemoryRegions.
-     */
-    assert(offset % s->qdev.blocksize == 0);
-    assert(iov->size % s->qdev.blocksize == 0);
-
-    io_header->interface_id = 'S';
-
-    /* The data transfer comes from the QEMUIOVector.  */
-    io_header->dxfer_direction = direction;
-    io_header->dxfer_len = iov->size;
-    io_header->dxferp = (void *)iov->iov;
-    io_header->iovec_count = iov->niov;
-    assert(io_header->iovec_count == iov->niov); /* no overflow! */
-
-    /* Build a new CDB with the LBA and length patched in, in case
-     * DMA helpers split the transfer in multiple segments.  Do not
-     * build a CDB smaller than what the guest wanted, and only build
-     * a larger one if strictly necessary.
-     */
-    io_header->cmdp = req->cdb;
-    lba = offset / s->qdev.blocksize;
-    nb_logical_blocks = io_header->dxfer_len / s->qdev.blocksize;
-
-    if ((req->cmd >> 5) == 0 && lba <= 0x1ffff) {
-        /* 6-byte CDB */
-        stl_be_p(&req->cdb[0], lba | (req->cmd << 24));
-        req->cdb[4] = nb_logical_blocks;
-        req->cdb[5] = 0;
-        io_header->cmd_len = 6;
-    } else if ((req->cmd >> 5) <= 1 && lba <= 0xffffffffULL) {
-        /* 10-byte CDB */
-        req->cdb[0] = (req->cmd & 0x1f) | 0x20;
-        req->cdb[1] = req->cdb1;
-        stl_be_p(&req->cdb[2], lba);
-        req->cdb[6] = req->group_number;
-        stw_be_p(&req->cdb[7], nb_logical_blocks);
-        req->cdb[9] = 0;
-        io_header->cmd_len = 10;
-    } else if ((req->cmd >> 5) != 4 && lba <= 0xffffffffULL) {
-        /* 12-byte CDB */
-        req->cdb[0] = (req->cmd & 0x1f) | 0xA0;
-        req->cdb[1] = req->cdb1;
-        stl_be_p(&req->cdb[2], lba);
-        stl_be_p(&req->cdb[6], nb_logical_blocks);
-        req->cdb[10] = req->group_number;
-        req->cdb[11] = 0;
-        io_header->cmd_len = 12;
-    } else {
-        /* 16-byte CDB */
-        req->cdb[0] = (req->cmd & 0x1f) | 0x80;
-        req->cdb[1] = req->cdb1;
-        stq_be_p(&req->cdb[2], lba);
-        stl_be_p(&req->cdb[10], nb_logical_blocks);
-        req->cdb[14] = req->group_number;
-        req->cdb[15] = 0;
-        io_header->cmd_len = 16;
-    }
-
-    /* The rest is as in scsi-generic.c.  */
-    io_header->mx_sb_len = sizeof(r->req.sense);
-    io_header->sbp = r->req.sense;
-    io_header->timeout = UINT_MAX;
-    io_header->usr_ptr = r;
-    io_header->flags |= SG_FLAG_DIRECT_IO;
-
-    aiocb = blk_aio_ioctl(s->qdev.conf.blk, SG_IO, io_header, cb, opaque);
-    assert(aiocb != NULL);
-    return aiocb;
-}
-
-static bool scsi_block_no_fua(SCSICommand *cmd)
-{
-    return false;
-}
-
-static BlockAIOCB *scsi_block_dma_readv(int64_t offset,
-                                        QEMUIOVector *iov,
-                                        BlockCompletionFunc *cb, void *cb_opaque,
-                                        void *opaque)
-{
-    SCSIBlockReq *r = opaque;
-    return scsi_block_do_sgio(r, offset, iov,
-                              SG_DXFER_FROM_DEV, cb, cb_opaque);
-}
-
-static BlockAIOCB *scsi_block_dma_writev(int64_t offset,
-                                         QEMUIOVector *iov,
-                                         BlockCompletionFunc *cb, void *cb_opaque,
-                                         void *opaque)
-{
-    SCSIBlockReq *r = opaque;
-    return scsi_block_do_sgio(r, offset, iov,
-                              SG_DXFER_TO_DEV, cb, cb_opaque);
-}
-
 static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
 {
     switch (buf[0]) {
-    case VERIFY_10:
-    case VERIFY_12:
-    case VERIFY_16:
-        /* Check if BYTCHK == 0x01 (data-out buffer contains data
-         * for the number of logical blocks specified in the length
-         * field).  For other modes, do not use scatter/gather operation.
-         */
-        if ((buf[1] & 6) != 2) {
-            return false;
-        }
-        break;
-
     case READ_6:
     case READ_10:
     case READ_12:
     case READ_16:
+    case VERIFY_10:
+    case VERIFY_12:
+    case VERIFY_16:
     case WRITE_6:
     case WRITE_10:
     case WRITE_12:
@@ -2709,8 +2594,21 @@ static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
     case WRITE_VERIFY_10:
     case WRITE_VERIFY_12:
     case WRITE_VERIFY_16:
-        /* MMC writing cannot be done via DMA helpers, because it sometimes
+        /* If we are not using O_DIRECT, we might read stale data from the
+         * host cache if writes were made using other commands than these
+         * ones (such as WRITE SAME or EXTENDED COPY, etc.).  So, without
+         * O_DIRECT everything must go through SG_IO.
+         */
+        if (!(blk_get_flags(s->qdev.conf.blk) & BDRV_O_NOCACHE)) {
+            break;
+        }
+
+        /* MMC writing cannot be done via pread/pwrite, because it sometimes
          * involves writing beyond the maximum LBA or to negative LBA (lead-in).
+         * And once you do these writes, reading from the block device is
+         * unreliable, too.  It is even possible that reads deliver random data
+         * from the host page cache (this is probably a Linux bug).
+         *
          * We might use scsi_disk_dma_reqops as long as no writing commands are
          * seen, but performance usually isn't paramount on optical media.  So,
          * just make scsi-block operate the same as scsi-generic for them.
@@ -2728,55 +2626,6 @@ static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
 }
 
 
-static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf)
-{
-    SCSIBlockReq *r = (SCSIBlockReq *)req;
-    r->cmd = req->cmd.buf[0];
-    switch (r->cmd >> 5) {
-    case 0:
-        /* 6-byte CDB.  */
-        r->cdb1 = r->group_number = 0;
-        break;
-    case 1:
-        /* 10-byte CDB.  */
-        r->cdb1 = req->cmd.buf[1];
-        r->group_number = req->cmd.buf[6];
-        break;
-    case 4:
-        /* 12-byte CDB.  */
-        r->cdb1 = req->cmd.buf[1];
-        r->group_number = req->cmd.buf[10];
-        break;
-    case 5:
-        /* 16-byte CDB.  */
-        r->cdb1 = req->cmd.buf[1];
-        r->group_number = req->cmd.buf[14];
-        break;
-    default:
-        abort();
-    }
-
-    if (r->cdb1 & 0xe0) {
-        /* Protection information is not supported.  */
-        scsi_check_condition(&r->req, SENSE_CODE(INVALID_FIELD));
-        return 0;
-    }
-
-    r->req.status = &r->io_header.status;
-    return scsi_disk_dma_command(req, buf);
-}
-
-static const SCSIReqOps scsi_block_dma_reqops = {
-    .size         = sizeof(SCSIBlockReq),
-    .free_req     = scsi_free_request,
-    .send_command = scsi_block_dma_command,
-    .read_data    = scsi_read_data,
-    .write_data   = scsi_write_data,
-    .get_buf      = scsi_get_buf,
-    .load_request = scsi_disk_load_request,
-    .save_request = scsi_disk_save_request,
-};
-
 static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
                                            uint32_t lun, uint8_t *buf,
                                            void *hba_private)
@@ -2787,7 +2636,7 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
         return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun,
                               hba_private);
     } else {
-        return scsi_req_alloc(&scsi_block_dma_reqops, &s->qdev, tag, lun,
+        return scsi_req_alloc(&scsi_disk_dma_reqops, &s->qdev, tag, lun,
                               hba_private);
     }
 }
@@ -2806,50 +2655,8 @@ static int scsi_block_parse_cdb(SCSIDevice *d, SCSICommand *cmd,
 
 #endif
 
-static
-BlockAIOCB *scsi_dma_readv(int64_t offset, QEMUIOVector *iov,
-                           BlockCompletionFunc *cb, void *cb_opaque,
-                           void *opaque)
-{
-    SCSIDiskReq *r = opaque;
-    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-    return blk_aio_preadv(s->qdev.conf.blk, offset, iov, 0, cb, cb_opaque);
-}
-
-static
-BlockAIOCB *scsi_dma_writev(int64_t offset, QEMUIOVector *iov,
-                            BlockCompletionFunc *cb, void *cb_opaque,
-                            void *opaque)
-{
-    SCSIDiskReq *r = opaque;
-    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-    return blk_aio_pwritev(s->qdev.conf.blk, offset, iov, 0, cb, cb_opaque);
-}
-
-static void scsi_disk_base_class_initfn(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    SCSIDiskClass *sdc = SCSI_DISK_BASE_CLASS(klass);
-
-    dc->fw_name = "disk";
-    dc->reset = scsi_disk_reset;
-    sdc->dma_readv = scsi_dma_readv;
-    sdc->dma_writev = scsi_dma_writev;
-    sdc->need_fua_emulation = scsi_is_cmd_fua;
-}
-
-static const TypeInfo scsi_disk_base_info = {
-    .name          = TYPE_SCSI_DISK_BASE,
-    .parent        = TYPE_SCSI_DEVICE,
-    .class_init    = scsi_disk_base_class_initfn,
-    .instance_size = sizeof(SCSIDiskState),
-    .class_size    = sizeof(SCSIDiskClass),
-    .abstract      = true,
-};
-
 #define DEFINE_SCSI_DISK_PROPERTIES()                                \
     DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf),               \
-    DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf),         \
     DEFINE_PROP_STRING("ver", SCSIDiskState, version),               \
     DEFINE_PROP_STRING("serial", SCSIDiskState, serial),             \
     DEFINE_PROP_STRING("vendor", SCSIDiskState, vendor),             \
@@ -2895,14 +2702,17 @@ static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
     sc->realize      = scsi_hd_realize;
     sc->alloc_req    = scsi_new_request;
     sc->unit_attention_reported = scsi_disk_unit_attention_reported;
+    dc->fw_name = "disk";
     dc->desc = "virtual SCSI disk";
+    dc->reset = scsi_disk_reset;
     dc->props = scsi_hd_properties;
     dc->vmsd  = &vmstate_scsi_disk_state;
 }
 
 static const TypeInfo scsi_hd_info = {
     .name          = "scsi-hd",
-    .parent        = TYPE_SCSI_DISK_BASE,
+    .parent        = TYPE_SCSI_DEVICE,
+    .instance_size = sizeof(SCSIDiskState),
     .class_init    = scsi_hd_class_initfn,
 };
 
@@ -2924,14 +2734,17 @@ static void scsi_cd_class_initfn(ObjectClass *klass, void *data)
     sc->realize      = scsi_cd_realize;
     sc->alloc_req    = scsi_new_request;
     sc->unit_attention_reported = scsi_disk_unit_attention_reported;
+    dc->fw_name = "disk";
     dc->desc = "virtual SCSI CD-ROM";
+    dc->reset = scsi_disk_reset;
     dc->props = scsi_cd_properties;
     dc->vmsd  = &vmstate_scsi_disk_state;
 }
 
 static const TypeInfo scsi_cd_info = {
     .name          = "scsi-cd",
-    .parent        = TYPE_SCSI_DISK_BASE,
+    .parent        = TYPE_SCSI_DEVICE,
+    .instance_size = sizeof(SCSIDiskState),
     .class_init    = scsi_cd_class_initfn,
 };
 
@@ -2945,22 +2758,21 @@ static void scsi_block_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
-    SCSIDiskClass *sdc = SCSI_DISK_BASE_CLASS(klass);
 
     sc->realize      = scsi_block_realize;
     sc->alloc_req    = scsi_block_new_request;
     sc->parse_cdb    = scsi_block_parse_cdb;
-    sdc->dma_readv   = scsi_block_dma_readv;
-    sdc->dma_writev  = scsi_block_dma_writev;
-    sdc->need_fua_emulation = scsi_block_no_fua;
+    dc->fw_name = "disk";
     dc->desc = "SCSI block device passthrough";
+    dc->reset = scsi_disk_reset;
     dc->props = scsi_block_properties;
     dc->vmsd  = &vmstate_scsi_disk_state;
 }
 
 static const TypeInfo scsi_block_info = {
     .name          = "scsi-block",
-    .parent        = TYPE_SCSI_DISK_BASE,
+    .parent        = TYPE_SCSI_DEVICE,
+    .instance_size = sizeof(SCSIDiskState),
     .class_init    = scsi_block_class_initfn,
 };
 #endif
@@ -2998,13 +2810,13 @@ static void scsi_disk_class_initfn(ObjectClass *klass, void *data)
 
 static const TypeInfo scsi_disk_info = {
     .name          = "scsi-disk",
-    .parent        = TYPE_SCSI_DISK_BASE,
+    .parent        = TYPE_SCSI_DEVICE,
+    .instance_size = sizeof(SCSIDiskState),
     .class_init    = scsi_disk_class_initfn,
 };
 
 static void scsi_disk_register_types(void)
 {
-    type_register_static(&scsi_disk_base_info);
     type_register_static(&scsi_hd_info);
     type_register_static(&scsi_cd_info);
 #ifdef __linux__
index 7a588a7..c4ba9a4 100644 (file)
@@ -225,14 +225,14 @@ static void scsi_read_complete(void * opaque, int ret)
     if (s->type == TYPE_DISK &&
         r->req.cmd.buf[0] == INQUIRY &&
         r->req.cmd.buf[2] == 0xb0) {
-        uint32_t max_transfer =
-            blk_get_max_transfer(s->conf.blk) / s->blocksize;
-
-        assert(max_transfer);
-        stl_be_p(&r->buf[8], max_transfer);
-        /* Also take care of the opt xfer len. */
-        if (ldl_be_p(&r->buf[12]) > max_transfer) {
-            stl_be_p(&r->buf[12], max_transfer);
+        uint32_t max_xfer_len = blk_get_max_transfer_length(s->conf.blk) /
+            (s->blocksize / BDRV_SECTOR_SIZE);
+        if (max_xfer_len) {
+            stl_be_p(&r->buf[8], max_xfer_len);
+            /* Also take care of the opt xfer len. */
+            if (ldl_be_p(&r->buf[12]) > max_xfer_len) {
+                stl_be_p(&r->buf[12], max_xfer_len);
+            }
         }
     }
     scsi_req_data(&r->req, len);
@@ -580,7 +580,10 @@ const SCSIReqOps scsi_generic_req_ops = {
 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
                                      uint8_t *buf, void *hba_private)
 {
-    return scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
+    SCSIRequest *req;
+
+    req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
+    return req;
 }
 
 static Property scsi_generic_properties[] = {
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
deleted file mode 100644 (file)
index ed64858..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/scsi/scsi-bus.c
-scsi_req_alloc(int target, int lun, int tag) "target %d lun %d tag %d"
-scsi_req_cancel(int target, int lun, int tag) "target %d lun %d tag %d"
-scsi_req_data(int target, int lun, int tag, int len) "target %d lun %d tag %d len %d"
-scsi_req_data_canceled(int target, int lun, int tag, int len) "target %d lun %d tag %d len %d"
-scsi_req_dequeue(int target, int lun, int tag) "target %d lun %d tag %d"
-scsi_req_continue(int target, int lun, int tag) "target %d lun %d tag %d"
-scsi_req_continue_canceled(int target, int lun, int tag) "target %d lun %d tag %d"
-scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) "target %d lun %d tag %d command %d dir %d length %d"
-scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba) "target %d lun %d tag %d command %d lba %"PRIu64
-scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d tag %d command %d"
-scsi_req_build_sense(int target, int lun, int tag, int key, int asc, int ascq) "target %d lun %d tag %d key %#02x asc %#02x ascq %#02x"
-scsi_device_set_ua(int target, int lun, int key, int asc, int ascq) "target %d lun %d key %#02x asc %#02x ascq %#02x"
-scsi_report_luns(int target, int lun, int tag) "target %d lun %d tag %d"
-scsi_inquiry(int target, int lun, int tag, int cdb1, int cdb2) "target %d lun %d tag %d page %#02x/%#02x"
-scsi_test_unit_ready(int target, int lun, int tag) "target %d lun %d tag %d"
-scsi_request_sense(int target, int lun, int tag) "target %d lun %d tag %d"
-
-# hw/scsi/mptsas.c
-mptsas_command_complete(void *dev, uint32_t ctx, uint32_t status, uint32_t resid) "dev %p context 0x%08x status %x resid %d"
-mptsas_diag_read(void *dev, uint32_t addr, uint32_t val) "dev %p addr 0x%08x value 0x%08x"
-mptsas_diag_write(void *dev, uint32_t addr, uint32_t val) "dev %p addr 0x%08x value 0x%08x"
-mptsas_irq_intx(void *dev, int level) "dev %p level %d"
-mptsas_irq_msi(void *dev) "dev %p "
-mptsas_mmio_read(void *dev, uint32_t addr, uint32_t val) "dev %p addr 0x%08x value 0x%x"
-mptsas_mmio_unhandled_read(void *dev, uint32_t addr) "dev %p addr 0x%08x"
-mptsas_mmio_unhandled_write(void *dev, uint32_t addr, uint32_t val) "dev %p addr 0x%08x value 0x%x"
-mptsas_mmio_write(void *dev, uint32_t addr, uint32_t val) "dev %p addr 0x%08x value 0x%x"
-mptsas_process_message(void *dev, int msg, uint32_t ctx) "dev %p cmd %d context 0x%08x\n"
-mptsas_process_scsi_io_request(void *dev, int bus, int target, int lun, uint64_t len) "dev %p dev %d:%d:%d length %"PRIu64""
-mptsas_reset(void *dev) "dev %p "
-mptsas_scsi_overflow(void *dev, uint32_t ctx, uint64_t req, uint64_t found) "dev %p context 0x%08x: %"PRIu64"/%"PRIu64""
-mptsas_sgl_overflow(void *dev, uint32_t ctx, uint64_t req, uint64_t found) "dev %p context 0x%08x: %"PRIu64"/%"PRIu64""
-mptsas_unhandled_cmd(void *dev, uint32_t ctx, uint8_t msg_cmd) "dev %p context 0x%08x: Unhandled cmd %x"
-mptsas_unhandled_doorbell_cmd(void *dev, int cmd) "dev %p value 0x%08x"
-
-# hw/scsi/mptconfig.c
-mptsas_config_sas_device(void *dev, int address, int port, int phy_handle, int dev_handle, int page) "dev %p address %d (port %d, handles: phy %d dev %d) page %d"
-mptsas_config_sas_phy(void *dev, int address, int port, int phy_handle, int dev_handle, int page) "dev %p address %d (port %d, handles: phy %d dev %d) page %d"
-
-# hw/scsi/megasas.c
-megasas_init_firmware(uint64_t pa) "pa %" PRIx64 " "
-megasas_init_queue(uint64_t queue_pa, int queue_len, uint64_t head, uint64_t tail, uint32_t flags) "queue at %" PRIx64 " len %d head %" PRIx64 " tail %" PRIx64 " flags %x"
-megasas_initq_map_failed(int frame) "scmd %d: failed to map queue"
-megasas_initq_mapped(uint64_t pa) "queue already mapped at %" PRIx64
-megasas_initq_mismatch(int queue_len, int fw_cmds) "queue size %d max fw cmds %d"
-megasas_qf_mapped(unsigned int index) "skip mapped frame %x"
-megasas_qf_new(unsigned int index, uint64_t frame) "frame %x addr %" PRIx64
-megasas_qf_busy(unsigned long pa) "all frames busy for frame %lx"
-megasas_qf_enqueue(unsigned int index, unsigned int count, uint64_t context, unsigned int head, unsigned int tail, int busy) "frame %x count %d context %" PRIx64 " head %x tail %x busy %d"
-megasas_qf_update(unsigned int head, unsigned int tail, unsigned int busy) "head %x tail %x busy %d"
-megasas_qf_map_failed(int cmd, unsigned long frame) "scmd %d: frame %lu"
-megasas_qf_complete_noirq(uint64_t context) "context %" PRIx64 " "
-megasas_qf_complete(uint64_t context, unsigned int head, unsigned int tail, int busy) "context %" PRIx64 " head %x tail %x busy %d"
-megasas_frame_busy(uint64_t addr) "frame %" PRIx64 " busy"
-megasas_unhandled_frame_cmd(int cmd, uint8_t frame_cmd) "scmd %d: MFI cmd %x"
-megasas_handle_scsi(const char *frame, int bus, int dev, int lun, void *sdev, unsigned long size) "%s dev %x/%x/%x sdev %p xfer %lu"
-megasas_scsi_target_not_present(const char *frame, int bus, int dev, int lun) "%s dev %x/%x/%x"
-megasas_scsi_invalid_cdb_len(const char *frame, int bus, int dev, int lun, int len) "%s dev %x/%x/%x invalid cdb len %d"
-megasas_iov_read_overflow(int cmd, int bytes, int len) "scmd %d: %d/%d bytes"
-megasas_iov_write_overflow(int cmd, int bytes, int len) "scmd %d: %d/%d bytes"
-megasas_iov_read_underflow(int cmd, int bytes, int len) "scmd %d: %d/%d bytes"
-megasas_iov_write_underflow(int cmd, int bytes, int len) "scmd %d: %d/%d bytes"
-megasas_scsi_req_alloc_failed(const char *frame, int dev, int lun) "%s dev %x/%x"
-megasas_scsi_read_start(int cmd, int len) "scmd %d: transfer %d bytes of data"
-megasas_scsi_write_start(int cmd, int len) "scmd %d: transfer %d bytes of data"
-megasas_scsi_nodata(int cmd) "scmd %d: no data to be transferred"
-megasas_scsi_complete(int cmd, uint32_t status, int len, int xfer) "scmd %d: status %x, len %u/%u"
-megasas_command_complete(int cmd, uint32_t status, uint32_t resid) "scmd %d: status %x, residual %d"
-megasas_handle_io(int cmd, const char *frame, int dev, int lun, unsigned long lba, unsigned long count) "scmd %d: %s dev %x/%x lba %lx count %lu"
-megasas_io_target_not_present(int cmd, const char *frame, int dev, int lun) "scmd %d: %s dev 1/%x/%x LUN not present"
-megasas_io_read_start(int cmd, unsigned long lba, unsigned long count, unsigned long len) "scmd %d: start LBA %lx %lu blocks (%lu bytes)"
-megasas_io_write_start(int cmd, unsigned long lba, unsigned long count, unsigned long len) "scmd %d: start LBA %lx %lu blocks (%lu bytes)"
-megasas_io_complete(int cmd, uint32_t len) "scmd %d: %d bytes"
-megasas_iovec_sgl_overflow(int cmd, int index, int limit) "scmd %d: iovec count %d limit %d"
-megasas_iovec_sgl_underflow(int cmd, int index) "scmd %d: iovec count %d"
-megasas_iovec_sgl_invalid(int cmd, int index, uint64_t pa, uint32_t len) "scmd %d: element %d pa %" PRIx64 " len %u"
-megasas_iovec_overflow(int cmd, int len, int limit) "scmd %d: len %d limit %d"
-megasas_iovec_underflow(int cmd, int len, int limit) "scmd %d: len %d limit %d"
-megasas_handle_dcmd(int cmd, int opcode) "scmd %d: MFI DCMD opcode %x"
-megasas_finish_dcmd(int cmd, int size) "scmd %d: MFI DCMD wrote %d bytes"
-megasas_dcmd_req_alloc_failed(int cmd, const char *desc) "scmd %d: %s"
-megasas_dcmd_internal_submit(int cmd, const char *desc, int dev) "scmd %d: %s to dev %d"
-megasas_dcmd_internal_finish(int cmd, int opcode, int lun) "scmd %d: cmd %x lun %d"
-megasas_dcmd_internal_invalid(int cmd, int opcode) "scmd %d: DCMD %x"
-megasas_dcmd_unhandled(int cmd, int opcode, int len) "scmd %d: opcode %x, len %d"
-megasas_dcmd_zero_sge(int cmd) "scmd %d: zero DCMD sge count"
-megasas_dcmd_invalid_sge(int cmd, int count) "scmd %d: DCMD sge count %d"
-megasas_dcmd_invalid_xfer_len(int cmd, unsigned long size, unsigned long max) "scmd %d: xfer len %ld, max %ld"
-megasas_dcmd_enter(int cmd, const char *dcmd, int len) "scmd %d: DCMD %s len %d"
-megasas_dcmd_dummy(int cmd, unsigned long size) "scmd %d: xfer len %ld"
-megasas_dcmd_set_fw_time(int cmd, unsigned long time) "scmd %d: Set FW time %lx"
-megasas_dcmd_pd_get_list(int cmd, int num, int max, int offset) "scmd %d: DCMD PD get list: %d / %d PDs, size %d"
-megasas_dcmd_ld_get_list(int cmd, int num, int max) "scmd %d: DCMD LD get list: found %d / %d LDs"
-megasas_dcmd_ld_get_info(int cmd, int ld_id) "scmd %d: dev %d"
-megasas_dcmd_ld_list_query(int cmd, int flags) "scmd %d: query flags %x"
-megasas_dcmd_pd_get_info(int cmd, int pd_id) "scmd %d: dev %d"
-megasas_dcmd_pd_list_query(int cmd, int flags) "scmd %d: query flags %x"
-megasas_dcmd_reset_ld(int cmd, int target_id) "scmd %d: dev %d"
-megasas_dcmd_unsupported(int cmd, unsigned long size) "scmd %d: set properties len %ld"
-megasas_abort_frame(int cmd, int abort_cmd) "scmd %d: frame %x"
-megasas_abort_no_cmd(int cmd, uint64_t context) "scmd %d: no active command for frame context %" PRIx64
-megasas_abort_invalid_context(int cmd, uint64_t context, int abort_cmd) "scmd %d: invalid frame context %" PRIx64 " for abort frame %x"
-megasas_reset(int fw_state) "firmware state %x"
-megasas_init(int sges, int cmds, const char *mode) "Using %d sges, %d cmds, %s mode"
-megasas_msix_raise(int vector) "vector %d"
-megasas_msi_raise(int vector) "vector %d"
-megasas_irq_lower(void) "INTx"
-megasas_irq_raise(void) "INTx"
-megasas_intr_enabled(void) "Interrupts enabled"
-megasas_intr_disabled(void) "Interrupts disabled"
-megasas_msix_enabled(int vector) "vector %d"
-megasas_msi_enabled(int vector) "vector %d"
-megasas_mmio_readl(const char *reg, uint32_t val) "reg %s: 0x%x"
-megasas_mmio_invalid_readl(unsigned long addr) "addr 0x%lx"
-megasas_mmio_writel(const char *reg, uint32_t val) "reg %s: 0x%x"
-megasas_mmio_invalid_writel(uint32_t addr, uint32_t val) "addr 0x%x: 0x%x"
-
-# hw/scsi/vmw_pvscsi.c
-pvscsi_ring_init_data(uint32_t txr_len_log2, uint32_t rxr_len_log2) "TX/RX rings logarithms set to %d/%d"
-pvscsi_ring_init_msg(uint32_t len_log2) "MSG ring logarithm set to %d"
-pvscsi_ring_flush_cmp(uint64_t filled_cmp_ptr) "new production counter of completion ring is 0x%"PRIx64
-pvscsi_ring_flush_msg(uint64_t filled_cmp_ptr) "new production counter of message ring is 0x%"PRIx64
-pvscsi_update_irq_level(bool raise, uint64_t mask, uint64_t status) "interrupt level set to %d (MASK: 0x%"PRIx64", STATUS: 0x%"PRIx64")"
-pvscsi_update_irq_msi(void) "sending MSI notification"
-pvscsi_cmp_ring_put(unsigned long addr) "got completion descriptor 0x%lx"
-pvscsi_msg_ring_put(unsigned long addr) "got message descriptor 0x%lx"
-pvscsi_complete_request(uint64_t context, uint64_t len, uint8_t sense_key) "completion: ctx: 0x%"PRIx64", len: 0x%"PRIx64", sense key: %u"
-pvscsi_get_sg_list(int nsg, size_t size) "get SG list: depth: %u, size: %zu"
-pvscsi_get_next_sg_elem(uint32_t flags) "unknown flags in SG element (val: 0x%x)"
-pvscsi_command_complete_not_found(uint32_t tag) "can't find request for tag 0x%x"
-pvscsi_command_complete_data_run(void) "not all data required for command transferred"
-pvscsi_command_complete_sense_len(int len) "sense information length is %d bytes"
-pvscsi_convert_sglist(uint64_t context, unsigned long addr, uint32_t resid) "element: ctx: 0x%"PRIx64" addr: 0x%lx, len: %ul"
-pvscsi_process_req_descr(uint8_t cmd, uint64_t ctx) "SCSI cmd 0x%x, ctx: 0x%"PRIx64
-pvscsi_process_req_descr_unknown_device(void) "command directed to unknown device rejected"
-pvscsi_process_req_descr_invalid_dir(void) "command with invalid transfer direction rejected"
-pvscsi_process_io(unsigned long addr) "got descriptor 0x%lx"
-pvscsi_on_cmd_noimpl(const char* cmd) "unimplemented command %s ignored"
-pvscsi_on_cmd_reset_dev(uint32_t tgt, int lun, void* dev) "PVSCSI_CMD_RESET_DEVICE[target %u lun %d (dev 0x%p)]"
-pvscsi_on_cmd_arrived(const char* cmd) "command %s arrived"
-pvscsi_on_cmd_abort(uint64_t ctx, uint32_t tgt) "command PVSCSI_CMD_ABORT_CMD for ctx 0x%"PRIx64", target %u"
-pvscsi_on_cmd_unknown(uint64_t cmd_id) "unknown command %"PRIx64
-pvscsi_on_cmd_unknown_data(uint32_t data) "data for unknown command 0x:%x"
-pvscsi_io_write(const char* cmd, uint64_t val) "%s write: %"PRIx64
-pvscsi_io_write_unknown(unsigned long addr, unsigned sz, uint64_t val) "unknown write address: 0x%lx size: %u bytes value: 0x%"PRIx64
-pvscsi_io_read(const char* cmd, uint64_t status) "%s read: 0x%"PRIx64
-pvscsi_io_read_unknown(unsigned long addr, unsigned sz) "unknown read address: 0x%lx size: %u bytes"
-pvscsi_init_msi_fail(int res) "failed to initialize MSI, error %d"
-pvscsi_state(const char* state) "starting %s ..."
-pvscsi_tx_rings_ppn(const char* label, uint64_t ppn) "%s page: %"PRIx64
-pvscsi_tx_rings_num_pages(const char* label, uint32_t num) "Number of %s pages: %u"
-
-# hw/scsi/esp.c
-esp_error_fifo_overrun(void) "FIFO overrun"
-esp_error_unhandled_command(uint32_t val) "unhandled command (%2.2x)"
-esp_error_invalid_write(uint32_t val, uint32_t addr) "invalid write of 0x%02x at [0x%x]"
-esp_raise_irq(void) "Raise IRQ"
-esp_lower_irq(void) "Lower IRQ"
-esp_dma_enable(void) "Raise enable"
-esp_dma_disable(void) "Lower enable"
-esp_get_cmd(uint32_t dmalen, int target) "len %d target %d"
-esp_do_busid_cmd(uint8_t busid) "busid 0x%x"
-esp_handle_satn_stop(uint32_t cmdlen) "cmdlen %d"
-esp_write_response(uint32_t status) "Transfer status (status=%d)"
-esp_do_dma(uint32_t cmdlen, uint32_t len) "command len %d + %d"
-esp_command_complete(void) "SCSI Command complete"
-esp_command_complete_unexpected(void) "SCSI command completed unexpectedly"
-esp_command_complete_fail(void) "Command failed"
-esp_transfer_data(uint32_t dma_left, int32_t ti_size) "transfer %d/%d"
-esp_handle_ti(uint32_t minlen) "Transfer Information len %d"
-esp_handle_ti_cmd(uint32_t cmdlen) "command len %d"
-esp_mem_readb(uint32_t saddr, uint8_t reg) "reg[%d]: 0x%2.2x"
-esp_mem_writeb(uint32_t saddr, uint8_t reg, uint32_t val) "reg[%d]: 0x%2.2x -> 0x%2.2x"
-esp_mem_writeb_cmd_nop(uint32_t val) "NOP (%2.2x)"
-esp_mem_writeb_cmd_flush(uint32_t val) "Flush FIFO (%2.2x)"
-esp_mem_writeb_cmd_reset(uint32_t val) "Chip reset (%2.2x)"
-esp_mem_writeb_cmd_bus_reset(uint32_t val) "Bus reset (%2.2x)"
-esp_mem_writeb_cmd_iccs(uint32_t val) "Initiator Command Complete Sequence (%2.2x)"
-esp_mem_writeb_cmd_msgacc(uint32_t val) "Message Accepted (%2.2x)"
-esp_mem_writeb_cmd_pad(uint32_t val) "Transfer padding (%2.2x)"
-esp_mem_writeb_cmd_satn(uint32_t val) "Set ATN (%2.2x)"
-esp_mem_writeb_cmd_rstatn(uint32_t val) "Reset ATN (%2.2x)"
-esp_mem_writeb_cmd_sel(uint32_t val) "Select without ATN (%2.2x)"
-esp_mem_writeb_cmd_selatn(uint32_t val) "Select with ATN (%2.2x)"
-esp_mem_writeb_cmd_selatns(uint32_t val) "Select with ATN & stop (%2.2x)"
-esp_mem_writeb_cmd_ensel(uint32_t val) "Enable selection (%2.2x)"
-esp_mem_writeb_cmd_dissel(uint32_t val) "Disable selection (%2.2x)"
-
-# hw/scsi/esp-pci.c
-esp_pci_error_invalid_dma_direction(void) "invalid DMA transfer direction"
-esp_pci_error_invalid_read(uint32_t reg) "read access outside bounds (reg 0x%x)"
-esp_pci_error_invalid_write(uint32_t reg) "write access outside bounds (reg 0x%x)"
-esp_pci_error_invalid_write_dma(uint32_t val, uint32_t addr) "invalid write of 0x%02x at [0x%x]"
-esp_pci_dma_read(uint32_t saddr, uint32_t reg) "reg[%d]: 0x%8.8x"
-esp_pci_dma_write(uint32_t saddr, uint32_t reg, uint32_t val) "reg[%d]: 0x%8.8x -> 0x%8.8x"
-esp_pci_dma_idle(uint32_t val) "IDLE (%.8x)"
-esp_pci_dma_blast(uint32_t val) "BLAST (%.8x)"
-esp_pci_dma_abort(uint32_t val) "ABORT (%.8x)"
-esp_pci_dma_start(uint32_t val) "START (%.8x)"
-esp_pci_sbac_read(uint32_t reg) "sbac: 0x%8.8x"
-esp_pci_sbac_write(uint32_t reg, uint32_t val) "sbac: 0x%8.8x -> 0x%8.8x"
index 5b26946..9261d51 100644 (file)
@@ -15,9 +15,8 @@
  */
 
 #include "qemu/osdep.h"
-#include <linux/vhost.h>
-#include <sys/ioctl.h>
 #include "qapi/error.h"
+#include <sys/ioctl.h>
 #include "qemu/error-report.h"
 #include "qemu/queue.h"
 #include "monitor/monitor.h"
@@ -28,6 +27,7 @@
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/virtio-access.h"
 #include "hw/fw-path-provider.h"
+#include "linux/vhost.h"
 #include "qemu/cutils.h"
 
 /* Features supported by host kernel. */
@@ -248,7 +248,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp)
     s->dev.backend_features = 0;
 
     ret = vhost_dev_init(&s->dev, (void *)(uintptr_t)vhostfd,
-                         VHOST_BACKEND_TYPE_KERNEL, 0);
+                         VHOST_BACKEND_TYPE_KERNEL);
     if (ret < 0) {
         error_setg(errp, "vhost-scsi: vhost initialization failed: %s",
                    strerror(-ret));
index b173b94..1a49f1e 100644 (file)
@@ -15,9 +15,9 @@
 #include "hw/virtio/virtio-scsi.h"
 #include "qemu/error-report.h"
 #include "sysemu/block-backend.h"
-#include "hw/scsi/scsi.h"
-#include "block/scsi.h"
-#include "hw/virtio/virtio-bus.h"
+#include <hw/scsi/scsi.h>
+#include <block/scsi.h>
+#include <hw/virtio/virtio-bus.h>
 #include "hw/virtio/virtio-access.h"
 
 /* Context: QEMU global mutex held */
@@ -31,7 +31,7 @@ void virtio_scsi_set_iothread(VirtIOSCSI *s, IOThread *iothread)
     s->ctx = iothread_get_aio_context(vs->conf.iothread);
 
     /* Don't try if transport does not support notifiers. */
-    if (!k->set_guest_notifiers || !k->ioeventfd_started) {
+    if (!k->set_guest_notifiers || !k->set_host_notifier) {
         fprintf(stderr, "virtio-scsi: Failed to set iothread "
                    "(transport does not support notifiers)");
         exit(1);
@@ -69,10 +69,11 @@ static int virtio_scsi_vring_init(VirtIOSCSI *s, VirtQueue *vq, int n,
                                   void (*fn)(VirtIODevice *vdev, VirtQueue *vq))
 {
     BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
+    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
     int rc;
 
     /* Set up virtqueue notify */
-    rc = virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), n, true);
+    rc = k->set_host_notifier(qbus->parent, n, true);
     if (rc != 0) {
         fprintf(stderr, "virtio-scsi: Failed to set host notifier (%d)\n",
                 rc);
@@ -158,7 +159,7 @@ fail_vrings:
     virtio_scsi_clear_aio(s);
     aio_context_release(s->ctx);
     for (i = 0; i < vs->conf.num_queues + 2; i++) {
-        virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
+        k->set_host_notifier(qbus->parent, i, false);
     }
     k->set_guest_notifiers(qbus->parent, vs->conf.num_queues + 2, false);
 fail_guest_notifiers:
@@ -197,7 +198,7 @@ void virtio_scsi_dataplane_stop(VirtIOSCSI *s)
     aio_context_release(s->ctx);
 
     for (i = 0; i < vs->conf.num_queues + 2; i++) {
-        virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
+        k->set_host_notifier(qbus->parent, i, false);
     }
 
     /* Clean up guest notifier (irq) */
index ce57ef6..30415c6 100644 (file)
@@ -20,9 +20,9 @@
 #include "qemu/error-report.h"
 #include "qemu/iov.h"
 #include "sysemu/block-backend.h"
-#include "hw/scsi/scsi.h"
-#include "block/scsi.h"
-#include "hw/virtio/virtio-bus.h"
+#include <hw/scsi/scsi.h>
+#include <block/scsi.h>
+#include <hw/virtio/virtio-bus.h>
 #include "hw/virtio/virtio-access.h"
 
 static inline int virtio_scsi_get_lun(uint8_t *lun)
@@ -185,7 +185,7 @@ static void virtio_scsi_save_request(QEMUFile *f, SCSIRequest *sreq)
 {
     VirtIOSCSIReq *req = sreq->hba_private;
     VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(req->dev);
-    uint32_t n = virtio_get_queue_index(req->vq) - 2;
+    uint32_t n = virtio_queue_get_id(req->vq) - 2;
 
     assert(n < vs->conf.num_queues);
     qemu_put_be32s(f, &n);
@@ -663,17 +663,27 @@ static void virtio_scsi_reset(VirtIODevice *vdev)
 /* The device does not have anything to save beyond the virtio data.
  * Request data is saved with callbacks from SCSI devices.
  */
-static void virtio_scsi_save(QEMUFile *f, void *opaque, size_t size)
+static void virtio_scsi_save(QEMUFile *f, void *opaque)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
+    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
+
+    if (s->dataplane_started) {
+        virtio_scsi_dataplane_stop(s);
+    }
     virtio_save(vdev, f);
 }
 
-static int virtio_scsi_load(QEMUFile *f, void *opaque, size_t size)
+static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
+    int ret;
 
-    return virtio_load(vdev, f, 1);
+    ret = virtio_load(vdev, f, version_id);
+    if (ret) {
+        return ret;
+    }
+    return 0;
 }
 
 void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
@@ -763,6 +773,22 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
     }
 }
 
+static void virtio_scsi_blk_insert_notifier(Notifier *n, void *data)
+{
+    VirtIOSCSIBlkChangeNotifier *cn = DO_UPCAST(VirtIOSCSIBlkChangeNotifier,
+                                                n, n);
+    assert(cn->sd->conf.blk == data);
+    blk_op_block_all(cn->sd->conf.blk, cn->s->blocker);
+}
+
+static void virtio_scsi_blk_remove_notifier(Notifier *n, void *data)
+{
+    VirtIOSCSIBlkChangeNotifier *cn = DO_UPCAST(VirtIOSCSIBlkChangeNotifier,
+                                                n, n);
+    assert(cn->sd->conf.blk == data);
+    blk_op_unblock_all(cn->sd->conf.blk, cn->s->blocker);
+}
+
 static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
                                 Error **errp)
 {
@@ -771,13 +797,29 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
     SCSIDevice *sd = SCSI_DEVICE(dev);
 
     if (s->ctx && !s->dataplane_fenced) {
+        VirtIOSCSIBlkChangeNotifier *insert_notifier, *remove_notifier;
+
         if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
             return;
         }
+        blk_op_block_all(sd->conf.blk, s->blocker);
         aio_context_acquire(s->ctx);
         blk_set_aio_context(sd->conf.blk, s->ctx);
         aio_context_release(s->ctx);
 
+        insert_notifier = g_new0(VirtIOSCSIBlkChangeNotifier, 1);
+        insert_notifier->n.notify = virtio_scsi_blk_insert_notifier;
+        insert_notifier->s = s;
+        insert_notifier->sd = sd;
+        blk_add_insert_bs_notifier(sd->conf.blk, &insert_notifier->n);
+        QTAILQ_INSERT_TAIL(&s->insert_notifiers, insert_notifier, next);
+
+        remove_notifier = g_new0(VirtIOSCSIBlkChangeNotifier, 1);
+        remove_notifier->n.notify = virtio_scsi_blk_remove_notifier;
+        remove_notifier->s = s;
+        remove_notifier->sd = sd;
+        blk_add_remove_bs_notifier(sd->conf.blk, &remove_notifier->n);
+        QTAILQ_INSERT_TAIL(&s->remove_notifiers, remove_notifier, next);
     }
 
     if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
@@ -793,6 +835,7 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
     VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev);
     VirtIOSCSI *s = VIRTIO_SCSI(vdev);
     SCSIDevice *sd = SCSI_DEVICE(dev);
+    VirtIOSCSIBlkChangeNotifier *insert_notifier, *remove_notifier;
 
     if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
         virtio_scsi_push_event(s, sd,
@@ -800,6 +843,28 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
                                VIRTIO_SCSI_EVT_RESET_REMOVED);
     }
 
+    if (s->ctx) {
+        blk_op_unblock_all(sd->conf.blk, s->blocker);
+    }
+
+    QTAILQ_FOREACH(insert_notifier, &s->insert_notifiers, next) {
+        if (insert_notifier->sd == sd) {
+            notifier_remove(&insert_notifier->n);
+            QTAILQ_REMOVE(&s->insert_notifiers, insert_notifier, next);
+            g_free(insert_notifier);
+            break;
+        }
+    }
+
+    QTAILQ_FOREACH(remove_notifier, &s->remove_notifiers, next) {
+        if (remove_notifier->sd == sd) {
+            notifier_remove(&remove_notifier->n);
+            QTAILQ_REMOVE(&s->remove_notifiers, remove_notifier, next);
+            g_free(remove_notifier);
+            break;
+        }
+    }
+
     qdev_simple_device_unplug_cb(hotplug_dev, dev, errp);
 }
 
@@ -819,9 +884,8 @@ static struct SCSIBusInfo virtio_scsi_scsi_info = {
 };
 
 void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
-                                VirtIOHandleOutput ctrl,
-                                VirtIOHandleOutput evt,
-                                VirtIOHandleOutput cmd)
+                                HandleOutput ctrl, HandleOutput evt,
+                                HandleOutput cmd)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
     VirtIOSCSICommon *s = VIRTIO_SCSI_COMMON(dev);
@@ -842,10 +906,13 @@ void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
     s->sense_size = VIRTIO_SCSI_SENSE_DEFAULT_SIZE;
     s->cdb_size = VIRTIO_SCSI_CDB_DEFAULT_SIZE;
 
-    s->ctrl_vq = virtio_add_queue_aio(vdev, VIRTIO_SCSI_VQ_SIZE, ctrl);
-    s->event_vq = virtio_add_queue_aio(vdev, VIRTIO_SCSI_VQ_SIZE, evt);
+    s->ctrl_vq = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
+                                  ctrl);
+    s->event_vq = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
+                                   evt);
     for (i = 0; i < s->conf.num_queues; i++) {
-        s->cmd_vqs[i] = virtio_add_queue_aio(vdev, VIRTIO_SCSI_VQ_SIZE, cmd);
+        s->cmd_vqs[i] = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
+                                         cmd);
     }
 
     if (s->conf.iothread) {
@@ -857,6 +924,7 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
     VirtIOSCSI *s = VIRTIO_SCSI(dev);
+    static int virtio_scsi_id;
     Error *err = NULL;
 
     virtio_scsi_common_realize(dev, &err, virtio_scsi_handle_ctrl,
@@ -879,6 +947,14 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
             return;
         }
     }
+
+    register_savevm(dev, "virtio-scsi", virtio_scsi_id++, 1,
+                    virtio_scsi_save, virtio_scsi_load, s);
+
+    error_setg(&s->blocker, "block device is in use by data plane");
+
+    QTAILQ_INIT(&s->insert_notifiers);
+    QTAILQ_INIT(&s->remove_notifiers);
 }
 
 static void virtio_scsi_instance_init(Object *obj)
@@ -902,6 +978,11 @@ void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp)
 
 static void virtio_scsi_device_unrealize(DeviceState *dev, Error **errp)
 {
+    VirtIOSCSI *s = VIRTIO_SCSI(dev);
+
+    error_free(s->blocker);
+
+    unregister_savevm(dev, "virtio-scsi", s);
     virtio_scsi_common_unrealize(dev, errp);
 }
 
@@ -918,8 +999,6 @@ static Property virtio_scsi_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-VMSTATE_VIRTIO_DEVICE(scsi, 1, virtio_scsi_load, virtio_scsi_save);
-
 static void virtio_scsi_common_class_init(ObjectClass *klass, void *data)
 {
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
@@ -936,7 +1015,6 @@ static void virtio_scsi_class_init(ObjectClass *klass, void *data)
     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
 
     dc->props = virtio_scsi_properties;
-    dc->vmsd = &vmstate_virtio_scsi;
     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
     vdc->realize = virtio_scsi_device_realize;
     vdc->unrealize = virtio_scsi_device_unrealize;
index 5116f4a..2d7528d 100644 (file)
@@ -28,7 +28,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/scsi/scsi.h"
-#include "block/scsi.h"
+#include <block/scsi.h>
 #include "hw/pci/msi.h"
 #include "vmw_pvscsi.h"
 #include "trace.h"
@@ -121,7 +121,8 @@ typedef struct {
     uint8_t msg_ring_info_valid;         /* Whether message ring initialized */
     uint8_t use_msg;                     /* Whether to use message ring      */
 
-    uint8_t msi_used;                    /* For migration compatibility      */
+    uint8_t msi_used;    /* Whether MSI support was installed successfully   */
+
     PVSCSIRingInfo rings;                /* Data transfer rings manager      */
     uint32_t resetting;                  /* Reset in progress                */
 
@@ -361,7 +362,7 @@ pvscsi_update_irq_status(PVSCSIState *s)
     trace_pvscsi_update_irq_level(should_raise, s->reg_interrupt_enabled,
                                   s->reg_interrupt_status);
 
-    if (msi_enabled(d)) {
+    if (s->msi_used && msi_enabled(d)) {
         if (should_raise) {
             trace_pvscsi_update_irq_msi();
             msi_notify(d, PVSCSI_VECTOR_COMPLETION);
@@ -1055,20 +1056,22 @@ pvscsi_io_read(void *opaque, hwaddr addr, unsigned size)
 }
 
 
-static void
+static bool
 pvscsi_init_msi(PVSCSIState *s)
 {
     int res;
     PCIDevice *d = PCI_DEVICE(s);
 
     res = msi_init(d, PVSCSI_MSI_OFFSET(s), PVSCSI_MSIX_NUM_VECTORS,
-                   PVSCSI_USE_64BIT, PVSCSI_PER_VECTOR_MASK, NULL);
+                   PVSCSI_USE_64BIT, PVSCSI_PER_VECTOR_MASK);
     if (res < 0) {
         trace_pvscsi_init_msi_fail(res);
         s->msi_used = false;
     } else {
         s->msi_used = true;
     }
+
+    return s->msi_used;
 }
 
 static void
@@ -1076,7 +1079,9 @@ pvscsi_cleanup_msi(PVSCSIState *s)
 {
     PCIDevice *d = PCI_DEVICE(s);
 
-    msi_uninit(d);
+    if (s->msi_used) {
+        msi_uninit(d);
+    }
 }
 
 static const MemoryRegionOps pvscsi_ops = {
index 1f2f0ed..c04ff02 100644 (file)
@@ -18,7 +18,7 @@
  *
  *
  * Specification available at:
- *   http://milkymist.walle.cc/socdoc/memcard.pdf
+ *   http://www.milkymist.org/socdoc/memcard.pdf
  */
 
 #include "qemu/osdep.h"
index 82c63a4..e87abb2 100644 (file)
@@ -12,8 +12,6 @@
 #include "sysemu/blockdev.h"
 #include "hw/sysbus.h"
 #include "hw/sd/sd.h"
-#include "qemu/log.h"
-#include "qapi/error.h"
 
 //#define DEBUG_PL181 1
 
@@ -482,48 +480,43 @@ static void pl181_reset(DeviceState *d)
     sd_set_cb(s->card, s->cardstatus[0], s->cardstatus[1]);
 }
 
-static void pl181_init(Object *obj)
+static int pl181_init(SysBusDevice *sbd)
 {
-    DeviceState *dev = DEVICE(obj);
-    PL181State *s = PL181(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(sbd);
+    PL181State *s = PL181(dev);
+    DriveInfo *dinfo;
 
-    memory_region_init_io(&s->iomem, obj, &pl181_ops, s, "pl181", 0x1000);
+    memory_region_init_io(&s->iomem, OBJECT(s), &pl181_ops, s, "pl181", 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
     sysbus_init_irq(sbd, &s->irq[0]);
     sysbus_init_irq(sbd, &s->irq[1]);
     qdev_init_gpio_out(dev, s->cardstatus, 2);
-}
-
-static void pl181_realize(DeviceState *dev, Error **errp)
-{
-    PL181State *s = PL181(dev);
-    DriveInfo *dinfo;
-
     /* FIXME use a qdev drive property instead of drive_get_next() */
     dinfo = drive_get_next(IF_SD);
     s->card = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, false);
     if (s->card == NULL) {
-        error_setg(errp, "sd_init failed");
+        return -1;
     }
+
+    return 0;
 }
 
 static void pl181_class_init(ObjectClass *klass, void *data)
 {
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
     DeviceClass *k = DEVICE_CLASS(klass);
 
+    sdc->init = pl181_init;
     k->vmsd = &vmstate_pl181;
     k->reset = pl181_reset;
     /* Reason: init() method uses drive_get_next() */
     k->cannot_instantiate_with_device_add_yet = true;
-    k->realize = pl181_realize;
 }
 
 static const TypeInfo pl181_info = {
     .name          = TYPE_PL181,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(PL181State),
-    .instance_init = pl181_init,
     .class_init    = pl181_class_init,
 };
 
index 87c6dc1..b66e5d2 100644 (file)
@@ -39,7 +39,6 @@
 #include "hw/qdev-properties.h"
 #include "qemu/error-report.h"
 #include "qemu/timer.h"
-#include "qemu/log.h"
 
 //#define DEBUG_SD 1
 
@@ -124,6 +123,7 @@ struct SDState {
     qemu_irq readonly_cb;
     qemu_irq inserted_cb;
     BlockBackend *blk;
+    uint8_t *buf;
 
     bool enable;
 };
@@ -551,7 +551,7 @@ static const VMStateDescription sd_vmstate = {
         VMSTATE_UINT64(data_start, SDState),
         VMSTATE_UINT32(data_offset, SDState),
         VMSTATE_UINT8_ARRAY(data, SDState, 512),
-        VMSTATE_UNUSED_V(1, 512),
+        VMSTATE_BUFFER_POINTER_UNSAFE(buf, SDState, 1, 512),
         VMSTATE_BOOL(enable, SDState),
         VMSTATE_END_OF_LIST()
     },
@@ -1577,17 +1577,57 @@ send_response:
 
 static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len)
 {
+    uint64_t end = addr + len;
+
     DPRINTF("sd_blk_read: addr = 0x%08llx, len = %d\n",
             (unsigned long long) addr, len);
-    if (!sd->blk || blk_pread(sd->blk, addr, sd->data, len) < 0) {
+    if (!sd->blk || blk_read(sd->blk, addr >> 9, sd->buf, 1) < 0) {
         fprintf(stderr, "sd_blk_read: read error on host side\n");
+        return;
     }
+
+    if (end > (addr & ~511) + 512) {
+        memcpy(sd->data, sd->buf + (addr & 511), 512 - (addr & 511));
+
+        if (blk_read(sd->blk, end >> 9, sd->buf, 1) < 0) {
+            fprintf(stderr, "sd_blk_read: read error on host side\n");
+            return;
+        }
+        memcpy(sd->data + 512 - (addr & 511), sd->buf, end & 511);
+    } else
+        memcpy(sd->data, sd->buf + (addr & 511), len);
 }
 
 static void sd_blk_write(SDState *sd, uint64_t addr, uint32_t len)
 {
-    if (!sd->blk || blk_pwrite(sd->blk, addr, sd->data, len, 0) < 0) {
-        fprintf(stderr, "sd_blk_write: write error on host side\n");
+    uint64_t end = addr + len;
+
+    if ((addr & 511) || len < 512)
+        if (!sd->blk || blk_read(sd->blk, addr >> 9, sd->buf, 1) < 0) {
+            fprintf(stderr, "sd_blk_write: read error on host side\n");
+            return;
+        }
+
+    if (end > (addr & ~511) + 512) {
+        memcpy(sd->buf + (addr & 511), sd->data, 512 - (addr & 511));
+        if (blk_write(sd->blk, addr >> 9, sd->buf, 1) < 0) {
+            fprintf(stderr, "sd_blk_write: write error on host side\n");
+            return;
+        }
+
+        if (blk_read(sd->blk, end >> 9, sd->buf, 1) < 0) {
+            fprintf(stderr, "sd_blk_write: read error on host side\n");
+            return;
+        }
+        memcpy(sd->buf, sd->data + 512 - (addr & 511), end & 511);
+        if (blk_write(sd->blk, end >> 9, sd->buf, 1) < 0) {
+            fprintf(stderr, "sd_blk_write: write error on host side\n");
+        }
+    } else {
+        memcpy(sd->buf + (addr & 511), sd->data, len);
+        if (!sd->blk || blk_write(sd->blk, addr >> 9, sd->buf, 1) < 0) {
+            fprintf(stderr, "sd_blk_write: write error on host side\n");
+        }
     }
 }
 
@@ -1885,6 +1925,8 @@ static void sd_realize(DeviceState *dev, Error **errp)
         return;
     }
 
+    sd->buf = blk_blockalign(sd->blk, 512);
+
     if (sd->blk) {
         blk_set_dev_ops(sd->blk, &sd_block_ops, sd);
     }
index 01fbf22..d28b587 100644 (file)
@@ -30,7 +30,6 @@
 #include "qemu/timer.h"
 #include "qemu/bitops.h"
 #include "sdhci-internal.h"
-#include "qemu/log.h"
 
 /* host controller debug messages */
 #ifndef SDHC_DEBUG
index 3ff0886..075e4ed 100644 (file)
@@ -15,7 +15,6 @@
 #include "sysemu/blockdev.h"
 #include "hw/ssi/ssi.h"
 #include "hw/sd/sd.h"
-#include "qapi/error.h"
 
 //#define DEBUG_SSI_SD 1
 
@@ -250,7 +249,7 @@ static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void ssi_sd_realize(SSISlave *d, Error **errp)
+static int ssi_sd_init(SSISlave *d)
 {
     DeviceState *dev = DEVICE(d);
     ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, d);
@@ -261,17 +260,17 @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
     dinfo = drive_get_next(IF_SD);
     s->sd = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, true);
     if (s->sd == NULL) {
-        error_setg(errp, "Device initialization failed.");
-        return;
+        return -1;
     }
     register_savevm(dev, "ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
+    return 0;
 }
 
 static void ssi_sd_class_init(ObjectClass *klass, void *data)
 {
     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 
-    k->realize = ssi_sd_realize;
+    k->init = ssi_sd_init;
     k->transfer = ssi_sd_transfer;
     k->cs_polarity = SSI_CS_LOW;
 }
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
deleted file mode 100644 (file)
index b17e7ba..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/sd/milkymist-memcard.c
-milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
index 3132d55..a1ea760 100644 (file)
@@ -30,7 +30,6 @@
 #include "sh7750_regnames.h"
 #include "hw/sh4/sh_intc.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/address-spaces.h"
 
 #define NB_DEVICES 4
index e3ba886..7463709 100644 (file)
@@ -1,6 +1,6 @@
-#ifndef SH7750_REGNAMES_H
-#define SH7750_REGNAMES_H
+#ifndef _SH7750_REGNAMES_H
+#define _SH7750_REGNAMES_H
 
 const char *regname(uint32_t addr);
 
-#endif /* SH7750_REGNAMES_H */
+#endif                         /* _SH7750_REGNAMES_H */
index 3e4554a..534aa48 100644 (file)
@@ -16,8 +16,8 @@
  * @(#) sh7750_regs.h,v 1.2.4.1 2003/09/04 18:46:00 joel Exp
  */
 
-#ifndef SH7750_REGS_H
-#define SH7750_REGS_H
+#ifndef __SH7750_REGS_H__
+#define __SH7750_REGS_H__
 
 /*
  * All register has 2 addresses: in 0xff000000 - 0xffffffff (P4 address)  and
index 1747628..e820a32 100644 (file)
@@ -55,7 +55,7 @@ static void sh_pci_reg_write (void *p, hwaddr addr, uint64_t val,
 
     switch(addr) {
     case 0 ... 0xfc:
-        stl_le_p(pcic->dev->config + addr, val);
+        cpu_to_le32w((uint32_t*)(pcic->dev->config + addr), val);
         break;
     case 0x1c0:
         pcic->par = val;
@@ -85,7 +85,7 @@ static uint64_t sh_pci_reg_read (void *p, hwaddr addr,
 
     switch(addr) {
     case 0 ... 0xfc:
-        return ldl_le_p(pcic->dev->config + addr);
+        return le32_to_cpup((uint32_t*)(pcic->dev->config + addr));
     case 0x1c0:
         return pcic->par;
     case 0x1c4:
index c3d3753..f69a92f 100644 (file)
@@ -1,2 +1 @@
 common-obj-$(CONFIG_SMBIOS) += smbios.o
-common-obj-$(call land,$(CONFIG_SMBIOS),$(CONFIG_IPMI)) += smbios_type_38.o
index 74c7102..cb8a111 100644 (file)
@@ -24,8 +24,6 @@
 #include "hw/smbios/smbios.h"
 #include "hw/loader.h"
 #include "exec/cpu-common.h"
-#include "smbios_build.h"
-#include "hw/smbios/ipmi.h"
 
 /* legacy structures and constants for <= 2.0 machines */
 struct smbios_header {
@@ -55,10 +53,10 @@ static bool smbios_uuid_encoded = true;
 /* end: legacy structures & constants for <= 2.0 machines */
 
 
-uint8_t *smbios_tables;
-size_t smbios_tables_len;
-unsigned smbios_table_max;
-unsigned smbios_table_cnt;
+static uint8_t *smbios_tables;
+static size_t smbios_tables_len;
+static unsigned smbios_table_max;
+static unsigned smbios_table_cnt;
 static SmbiosEntryPointType smbios_ep_type = SMBIOS_ENTRY_POINT_21;
 
 static SmbiosEntryPoint ep;
@@ -431,7 +429,7 @@ uint8_t *smbios_get_table_legacy(size_t *length)
 /* end: legacy setup functions for <= 2.0 machines */
 
 
-bool smbios_skip_table(uint8_t type, bool required_table)
+static bool smbios_skip_table(uint8_t type, bool required_table)
 {
     if (test_bit(type, have_binfile_bitmap)) {
         return true; /* user provided their own binary blob(s) */
@@ -445,6 +443,65 @@ bool smbios_skip_table(uint8_t type, bool required_table)
     return true;
 }
 
+#define SMBIOS_BUILD_TABLE_PRE(tbl_type, tbl_handle, tbl_required)        \
+    struct smbios_type_##tbl_type *t;                                     \
+    size_t t_off; /* table offset into smbios_tables */                   \
+    int str_index = 0;                                                    \
+    do {                                                                  \
+        /* should we skip building this table ? */                        \
+        if (smbios_skip_table(tbl_type, tbl_required)) {                  \
+            return;                                                       \
+        }                                                                 \
+                                                                          \
+        /* use offset of table t within smbios_tables */                  \
+        /* (pointer must be updated after each realloc) */                \
+        t_off = smbios_tables_len;                                        \
+        smbios_tables_len += sizeof(*t);                                  \
+        smbios_tables = g_realloc(smbios_tables, smbios_tables_len);      \
+        t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off);     \
+                                                                          \
+        t->header.type = tbl_type;                                        \
+        t->header.length = sizeof(*t);                                    \
+        t->header.handle = cpu_to_le16(tbl_handle);                       \
+    } while (0)
+
+#define SMBIOS_TABLE_SET_STR(tbl_type, field, value)                      \
+    do {                                                                  \
+        int len = (value != NULL) ? strlen(value) + 1 : 0;                \
+        if (len > 1) {                                                    \
+            smbios_tables = g_realloc(smbios_tables,                      \
+                                      smbios_tables_len + len);           \
+            memcpy(smbios_tables + smbios_tables_len, value, len);        \
+            smbios_tables_len += len;                                     \
+            /* update pointer post-realloc */                             \
+            t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \
+            t->field = ++str_index;                                       \
+        } else {                                                          \
+            t->field = 0;                                                 \
+        }                                                                 \
+    } while (0)
+
+#define SMBIOS_BUILD_TABLE_POST                                           \
+    do {                                                                  \
+        size_t term_cnt, t_size;                                          \
+                                                                          \
+        /* add '\0' terminator (add two if no strings defined) */         \
+        term_cnt = (str_index == 0) ? 2 : 1;                              \
+        smbios_tables = g_realloc(smbios_tables,                          \
+                                  smbios_tables_len + term_cnt);          \
+        memset(smbios_tables + smbios_tables_len, 0, term_cnt);           \
+        smbios_tables_len += term_cnt;                                    \
+                                                                          \
+        /* update smbios max. element size */                             \
+        t_size = smbios_tables_len - t_off;                               \
+        if (t_size > smbios_table_max) {                                  \
+            smbios_table_max = t_size;                                    \
+        }                                                                 \
+                                                                          \
+        /* update smbios element count */                                 \
+        smbios_table_cnt++;                                               \
+    } while (0)
+
 static void smbios_build_type_0_table(void)
 {
     SMBIOS_BUILD_TABLE_PRE(0, 0x000, false); /* optional, leave up to BIOS */
@@ -849,7 +906,6 @@ void smbios_get_tables(const struct smbios_phys_mem_area *mem_array,
         }
 
         smbios_build_type_32_table();
-        smbios_build_type_38_table();
         smbios_build_type_127_table();
 
         smbios_validate_table();
diff --git a/hw/smbios/smbios_build.h b/hw/smbios/smbios_build.h
deleted file mode 100644 (file)
index 68b8b72..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * SMBIOS Support
- *
- * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
- * Copyright (C) 2013 Red Hat, Inc.
- *
- * Authors:
- *  Alex Williamson <alex.williamson@hp.com>
- *  Markus Armbruster <armbru@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#ifndef QEMU_SMBIOS_BUILD_H
-#define QEMU_SMBIOS_BUILD_H
-
-bool smbios_skip_table(uint8_t type, bool required_table);
-
-extern uint8_t *smbios_tables;
-extern size_t smbios_tables_len;
-extern unsigned smbios_table_max;
-extern unsigned smbios_table_cnt;
-
-#define SMBIOS_BUILD_TABLE_PRE(tbl_type, tbl_handle, tbl_required)        \
-    struct smbios_type_##tbl_type *t;                                     \
-    size_t t_off; /* table offset into smbios_tables */                   \
-    int str_index = 0;                                                    \
-    do {                                                                  \
-        /* should we skip building this table ? */                        \
-        if (smbios_skip_table(tbl_type, tbl_required)) {                  \
-            return;                                                       \
-        }                                                                 \
-                                                                          \
-        /* use offset of table t within smbios_tables */                  \
-        /* (pointer must be updated after each realloc) */                \
-        t_off = smbios_tables_len;                                        \
-        smbios_tables_len += sizeof(*t);                                  \
-        smbios_tables = g_realloc(smbios_tables, smbios_tables_len);      \
-        t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off);     \
-                                                                          \
-        t->header.type = tbl_type;                                        \
-        t->header.length = sizeof(*t);                                    \
-        t->header.handle = cpu_to_le16(tbl_handle);                       \
-    } while (0)
-
-#define SMBIOS_TABLE_SET_STR(tbl_type, field, value)                      \
-    do {                                                                  \
-        int len = (value != NULL) ? strlen(value) + 1 : 0;                \
-        if (len > 1) {                                                    \
-            smbios_tables = g_realloc(smbios_tables,                      \
-                                      smbios_tables_len + len);           \
-            memcpy(smbios_tables + smbios_tables_len, value, len);        \
-            smbios_tables_len += len;                                     \
-            /* update pointer post-realloc */                             \
-            t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \
-            t->field = ++str_index;                                       \
-        } else {                                                          \
-            t->field = 0;                                                 \
-        }                                                                 \
-    } while (0)
-
-#define SMBIOS_BUILD_TABLE_POST                                           \
-    do {                                                                  \
-        size_t term_cnt, t_size;                                          \
-                                                                          \
-        /* add '\0' terminator (add two if no strings defined) */         \
-        term_cnt = (str_index == 0) ? 2 : 1;                              \
-        smbios_tables = g_realloc(smbios_tables,                          \
-                                  smbios_tables_len + term_cnt);          \
-        memset(smbios_tables + smbios_tables_len, 0, term_cnt);           \
-        smbios_tables_len += term_cnt;                                    \
-                                                                          \
-        /* update smbios max. element size */                             \
-        t_size = smbios_tables_len - t_off;                               \
-        if (t_size > smbios_table_max) {                                  \
-            smbios_table_max = t_size;                                    \
-        }                                                                 \
-                                                                          \
-        /* update smbios element count */                                 \
-        smbios_table_cnt++;                                               \
-    } while (0)
-
-#endif /* QEMU_SMBIOS_BUILD_H */
diff --git a/hw/smbios/smbios_type_38.c b/hw/smbios/smbios_type_38.c
deleted file mode 100644 (file)
index 56e8609..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * IPMI SMBIOS firmware handling
- *
- * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "hw/ipmi/ipmi.h"
-#include "hw/smbios/ipmi.h"
-#include "hw/smbios/smbios.h"
-#include "qemu/error-report.h"
-#include "smbios_build.h"
-
-/* SMBIOS type 38 - IPMI */
-struct smbios_type_38 {
-    struct smbios_structure_header header;
-    uint8_t interface_type;
-    uint8_t ipmi_spec_revision;
-    uint8_t i2c_slave_address;
-    uint8_t nv_storage_device_address;
-    uint64_t base_address;
-    uint8_t base_address_modifier;
-    uint8_t interrupt_number;
-} QEMU_PACKED;
-
-static void smbios_build_one_type_38(IPMIFwInfo *info)
-{
-    uint64_t baseaddr = info->base_address;
-    SMBIOS_BUILD_TABLE_PRE(38, 0x3000, true);
-
-    t->interface_type = info->interface_type;
-    t->ipmi_spec_revision = ((info->ipmi_spec_major_revision << 4)
-                             | info->ipmi_spec_minor_revision);
-    t->i2c_slave_address = info->i2c_slave_address;
-    t->nv_storage_device_address = 0;
-
-    assert(info->ipmi_spec_minor_revision <= 15);
-    assert(info->ipmi_spec_major_revision <= 15);
-
-    /* or 1 to set it to I/O space */
-    switch (info->memspace) {
-    case IPMI_MEMSPACE_IO:
-        baseaddr |= 1;
-        break;
-    case IPMI_MEMSPACE_MEM32:
-    case IPMI_MEMSPACE_MEM64:
-        break;
-    case IPMI_MEMSPACE_SMBUS:
-        baseaddr <<= 1;
-        break;
-    }
-
-    t->base_address = cpu_to_le64(baseaddr);
-
-    t->base_address_modifier = 0;
-    if (info->irq_type == IPMI_LEVEL_IRQ) {
-        t->base_address_modifier |= 1;
-    }
-    switch (info->register_spacing) {
-    case 1:
-        break;
-    case 4:
-        t->base_address_modifier |= 1 << 6;
-        break;
-    case 16:
-        t->base_address_modifier |= 2 << 6;
-        break;
-    default:
-        error_report("IPMI register spacing %d is not compatible with"
-                     " SMBIOS, ignoring this entry.", info->register_spacing);
-        return;
-    }
-    t->interrupt_number = info->interrupt_number;
-
-    SMBIOS_BUILD_TABLE_POST;
-}
-
-static void smbios_add_ipmi_devices(BusState *bus)
-{
-    BusChild *kid;
-
-    QTAILQ_FOREACH(kid, &bus->children,  sibling) {
-        DeviceState *dev = kid->child;
-        Object *obj = object_dynamic_cast(OBJECT(dev), TYPE_IPMI_INTERFACE);
-        BusState *childbus;
-
-        if (obj) {
-            IPMIInterface *ii;
-            IPMIInterfaceClass *iic;
-            IPMIFwInfo info;
-
-            ii = IPMI_INTERFACE(obj);
-            iic = IPMI_INTERFACE_GET_CLASS(obj);
-            memset(&info, 0, sizeof(info));
-            iic->get_fwinfo(ii, &info);
-            smbios_build_one_type_38(&info);
-            continue;
-        }
-
-        QLIST_FOREACH(childbus, &dev->child_bus, sibling) {
-            smbios_add_ipmi_devices(childbus);
-        }
-    }
-}
-
-void smbios_build_type_38_table(void)
-{
-    BusState *bus;
-
-    bus = sysbus_get_default();
-    if (bus) {
-        smbios_add_ipmi_devices(bus);
-    }
-}
index 6e16478..dbae41f 100644 (file)
@@ -171,11 +171,7 @@ static void leon3_generic_hw_init(MachineState *machine)
     }
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
 
-    if (filename) {
-        bios_size = get_image_size(filename);
-    } else {
-        bios_size = -1;
-    }
+    bios_size = get_image_size(filename);
 
     if (bios_size > prom_size) {
         fprintf(stderr, "qemu: could not load prom '%s': file too big\n",
index 478fda8..7bfc00a 100644 (file)
@@ -1000,7 +1000,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
     slavio_timer_init_all(hwdef->counter_base, slavio_irq[19], slavio_cpu_irq, smp_cpus);
 
     slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[14],
-                              !machine->enable_graphics, ESCC_CLOCK, 1);
+                              display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
     /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
        Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
     escc_init(hwdef->serial_base, slavio_irq[15], slavio_irq[15],
diff --git a/hw/sparc/trace-events b/hw/sparc/trace-events
deleted file mode 100644 (file)
index 30fb037..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/sparc/sun4m.c
-sun4m_cpu_interrupt(unsigned int level) "Set CPU IRQ %d"
-sun4m_cpu_reset_interrupt(unsigned int level) "Reset CPU IRQ %d"
-sun4m_cpu_set_irq_raise(int level) "Raise CPU IRQ %d"
-sun4m_cpu_set_irq_lower(int level) "Lower CPU IRQ %d"
-
-# hw/sparc/leon3.c
-leon3_set_irq(int intno) "Set CPU IRQ %d"
-leon3_reset_irq(int intno) "Reset CPU IRQ %d"
index c79a8dc..9555825 100644 (file)
@@ -2,7 +2,5 @@ common-obj-$(CONFIG_PL022) += pl022.o
 common-obj-$(CONFIG_SSI) += ssi.o
 common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
-common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
 
 obj-$(CONFIG_OMAP) += omap_spi.o
-obj-$(CONFIG_IMX) += imx_spi.o
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
deleted file mode 100644 (file)
index d319e04..0000000
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * ASPEED AST2400 SMC Controller (SPI Flash Only)
- *
- * Copyright (C) 2016 IBM Corp.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "hw/sysbus.h"
-#include "sysemu/sysemu.h"
-#include "qemu/log.h"
-#include "include/qemu/error-report.h"
-#include "exec/address-spaces.h"
-
-#include "hw/ssi/aspeed_smc.h"
-
-/* CE Type Setting Register */
-#define R_CONF            (0x00 / 4)
-#define   CONF_LEGACY_DISABLE  (1 << 31)
-#define   CONF_ENABLE_W4       20
-#define   CONF_ENABLE_W3       19
-#define   CONF_ENABLE_W2       18
-#define   CONF_ENABLE_W1       17
-#define   CONF_ENABLE_W0       16
-#define   CONF_FLASH_TYPE4     9
-#define   CONF_FLASH_TYPE3     7
-#define   CONF_FLASH_TYPE2     5
-#define   CONF_FLASH_TYPE1     3
-#define   CONF_FLASH_TYPE0     1
-
-/* CE Control Register */
-#define R_CE_CTRL            (0x04 / 4)
-#define   CTRL_EXTENDED4       4  /* 32 bit addressing for SPI */
-#define   CTRL_EXTENDED3       3  /* 32 bit addressing for SPI */
-#define   CTRL_EXTENDED2       2  /* 32 bit addressing for SPI */
-#define   CTRL_EXTENDED1       1  /* 32 bit addressing for SPI */
-#define   CTRL_EXTENDED0       0  /* 32 bit addressing for SPI */
-
-/* Interrupt Control and Status Register */
-#define R_INTR_CTRL       (0x08 / 4)
-#define   INTR_CTRL_DMA_STATUS            (1 << 11)
-#define   INTR_CTRL_CMD_ABORT_STATUS      (1 << 10)
-#define   INTR_CTRL_WRITE_PROTECT_STATUS  (1 << 9)
-#define   INTR_CTRL_DMA_EN                (1 << 3)
-#define   INTR_CTRL_CMD_ABORT_EN          (1 << 2)
-#define   INTR_CTRL_WRITE_PROTECT_EN      (1 << 1)
-
-/* CEx Control Register */
-#define R_CTRL0           (0x10 / 4)
-#define   CTRL_CMD_SHIFT           16
-#define   CTRL_CMD_MASK            0xff
-#define   CTRL_CE_STOP_ACTIVE      (1 << 2)
-#define   CTRL_CMD_MODE_MASK       0x3
-#define     CTRL_READMODE          0x0
-#define     CTRL_FREADMODE         0x1
-#define     CTRL_WRITEMODE         0x2
-#define     CTRL_USERMODE          0x3
-#define R_CTRL1           (0x14 / 4)
-#define R_CTRL2           (0x18 / 4)
-#define R_CTRL3           (0x1C / 4)
-#define R_CTRL4           (0x20 / 4)
-
-/* CEx Segment Address Register */
-#define R_SEG_ADDR0       (0x30 / 4)
-#define   SEG_SIZE_SHIFT       24   /* 8MB units */
-#define   SEG_SIZE_MASK        0x7f
-#define   SEG_START_SHIFT      16   /* address bit [A29-A23] */
-#define   SEG_START_MASK       0x7f
-#define R_SEG_ADDR1       (0x34 / 4)
-#define R_SEG_ADDR2       (0x38 / 4)
-#define R_SEG_ADDR3       (0x3C / 4)
-#define R_SEG_ADDR4       (0x40 / 4)
-
-/* Misc Control Register #1 */
-#define R_MISC_CTRL1      (0x50 / 4)
-
-/* Misc Control Register #2 */
-#define R_MISC_CTRL2      (0x54 / 4)
-
-/* DMA Control/Status Register */
-#define R_DMA_CTRL        (0x80 / 4)
-#define   DMA_CTRL_DELAY_MASK   0xf
-#define   DMA_CTRL_DELAY_SHIFT  8
-#define   DMA_CTRL_FREQ_MASK    0xf
-#define   DMA_CTRL_FREQ_SHIFT   4
-#define   DMA_CTRL_MODE         (1 << 3)
-#define   DMA_CTRL_CKSUM        (1 << 2)
-#define   DMA_CTRL_DIR          (1 << 1)
-#define   DMA_CTRL_EN           (1 << 0)
-
-/* DMA Flash Side Address */
-#define R_DMA_FLASH_ADDR  (0x84 / 4)
-
-/* DMA DRAM Side Address */
-#define R_DMA_DRAM_ADDR   (0x88 / 4)
-
-/* DMA Length Register */
-#define R_DMA_LEN         (0x8C / 4)
-
-/* Checksum Calculation Result */
-#define R_DMA_CHECKSUM    (0x90 / 4)
-
-/* Misc Control Register #2 */
-#define R_TIMINGS         (0x94 / 4)
-
-/* SPI controller registers and bits */
-#define R_SPI_CONF        (0x00 / 4)
-#define   SPI_CONF_ENABLE_W0   0
-#define R_SPI_CTRL0       (0x4 / 4)
-#define R_SPI_MISC_CTRL   (0x10 / 4)
-#define R_SPI_TIMINGS     (0x14 / 4)
-
-/*
- * Default segments mapping addresses and size for each slave per
- * controller. These can be changed when board is initialized with the
- * Segment Address Registers but they don't seem do be used on the
- * field.
- */
-static const AspeedSegments aspeed_segments_legacy[] = {
-    { 0x10000000, 32 * 1024 * 1024 },
-};
-
-static const AspeedSegments aspeed_segments_fmc[] = {
-    { 0x20000000, 64 * 1024 * 1024 },
-    { 0x24000000, 32 * 1024 * 1024 },
-    { 0x26000000, 32 * 1024 * 1024 },
-    { 0x28000000, 32 * 1024 * 1024 },
-    { 0x2A000000, 32 * 1024 * 1024 }
-};
-
-static const AspeedSegments aspeed_segments_spi[] = {
-    { 0x30000000, 64 * 1024 * 1024 },
-};
-
-static const AspeedSMCController controllers[] = {
-    { "aspeed.smc.smc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
-      CONF_ENABLE_W0, 5, aspeed_segments_legacy, 0x6000000 },
-    { "aspeed.smc.fmc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
-      CONF_ENABLE_W0, 5, aspeed_segments_fmc, 0x10000000 },
-    { "aspeed.smc.spi", R_SPI_CONF, 0xff, R_SPI_CTRL0, R_SPI_TIMINGS,
-      SPI_CONF_ENABLE_W0, 1, aspeed_segments_spi, 0x10000000 },
-};
-
-static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
-                                              unsigned size)
-{
-    qemu_log_mask(LOG_GUEST_ERROR, "%s: To 0x%" HWADDR_PRIx " of size %u"
-                  PRIx64 "\n", __func__, addr, size);
-    return 0;
-}
-
-static void aspeed_smc_flash_default_write(void *opaque, hwaddr addr,
-                                           uint64_t data, unsigned size)
-{
-   qemu_log_mask(LOG_GUEST_ERROR, "%s: To 0x%" HWADDR_PRIx " of size %u: 0x%"
-                 PRIx64 "\n", __func__, addr, size, data);
-}
-
-static const MemoryRegionOps aspeed_smc_flash_default_ops = {
-    .read = aspeed_smc_flash_default_read,
-    .write = aspeed_smc_flash_default_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-    .valid = {
-        .min_access_size = 1,
-        .max_access_size = 4,
-    },
-};
-
-static inline int aspeed_smc_flash_mode(const AspeedSMCState *s, int cs)
-{
-    return s->regs[s->r_ctrl0 + cs] & CTRL_CMD_MODE_MASK;
-}
-
-static inline bool aspeed_smc_is_usermode(const AspeedSMCState *s, int cs)
-{
-    return aspeed_smc_flash_mode(s, cs) == CTRL_USERMODE;
-}
-
-static inline bool aspeed_smc_is_writable(const AspeedSMCState *s, int cs)
-{
-    return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + cs));
-}
-
-static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
-{
-    AspeedSMCFlash *fl = opaque;
-    const AspeedSMCState *s = fl->controller;
-    uint64_t ret = 0;
-    int i;
-
-    if (aspeed_smc_is_usermode(s, fl->id)) {
-        for (i = 0; i < size; i++) {
-            ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
-        }
-    } else {
-        qemu_log_mask(LOG_UNIMP, "%s: usermode not implemented\n",
-                      __func__);
-        ret = -1;
-    }
-
-    return ret;
-}
-
-static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data,
-                           unsigned size)
-{
-    AspeedSMCFlash *fl = opaque;
-    const AspeedSMCState *s = fl->controller;
-    int i;
-
-    if (!aspeed_smc_is_writable(s, fl->id)) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: flash is not writable at 0x%"
-                      HWADDR_PRIx "\n", __func__, addr);
-        return;
-    }
-
-    if (!aspeed_smc_is_usermode(s, fl->id)) {
-        qemu_log_mask(LOG_UNIMP, "%s: usermode not implemented\n",
-                      __func__);
-        return;
-    }
-
-    for (i = 0; i < size; i++) {
-        ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
-    }
-}
-
-static const MemoryRegionOps aspeed_smc_flash_ops = {
-    .read = aspeed_smc_flash_read,
-    .write = aspeed_smc_flash_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-    .valid = {
-        .min_access_size = 1,
-        .max_access_size = 4,
-    },
-};
-
-static bool aspeed_smc_is_ce_stop_active(const AspeedSMCState *s, int cs)
-{
-    return s->regs[s->r_ctrl0 + cs] & CTRL_CE_STOP_ACTIVE;
-}
-
-static void aspeed_smc_update_cs(const AspeedSMCState *s)
-{
-    int i;
-
-    for (i = 0; i < s->num_cs; ++i) {
-        qemu_set_irq(s->cs_lines[i], aspeed_smc_is_ce_stop_active(s, i));
-    }
-}
-
-static void aspeed_smc_reset(DeviceState *d)
-{
-    AspeedSMCState *s = ASPEED_SMC(d);
-    int i;
-
-    memset(s->regs, 0, sizeof s->regs);
-
-    /* Pretend DMA is done (u-boot initialization) */
-    s->regs[R_INTR_CTRL] = INTR_CTRL_DMA_STATUS;
-
-    /* Unselect all slaves */
-    for (i = 0; i < s->num_cs; ++i) {
-        s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
-    }
-
-    aspeed_smc_update_cs(s);
-}
-
-static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
-{
-    AspeedSMCState *s = ASPEED_SMC(opaque);
-
-    addr >>= 2;
-
-    if (addr >= ARRAY_SIZE(s->regs)) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: Out-of-bounds read at 0x%" HWADDR_PRIx "\n",
-                      __func__, addr);
-        return 0;
-    }
-
-    if (addr == s->r_conf ||
-        addr == s->r_timings ||
-        addr == s->r_ce_ctrl ||
-        addr == R_INTR_CTRL ||
-        (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs)) {
-        return s->regs[addr];
-    } else {
-        qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
-                      __func__, addr);
-        return 0;
-    }
-}
-
-static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
-                             unsigned int size)
-{
-    AspeedSMCState *s = ASPEED_SMC(opaque);
-    uint32_t value = data;
-
-    addr >>= 2;
-
-    if (addr >= ARRAY_SIZE(s->regs)) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: Out-of-bounds write at 0x%" HWADDR_PRIx "\n",
-                      __func__, addr);
-        return;
-    }
-
-    if (addr == s->r_conf ||
-        addr == s->r_timings ||
-        addr == s->r_ce_ctrl) {
-        s->regs[addr] = value;
-    } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
-        s->regs[addr] = value;
-        aspeed_smc_update_cs(s);
-    } else {
-        qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
-                      __func__, addr);
-        return;
-    }
-}
-
-static const MemoryRegionOps aspeed_smc_ops = {
-    .read = aspeed_smc_read,
-    .write = aspeed_smc_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-    .valid.unaligned = true,
-};
-
-static void aspeed_smc_realize(DeviceState *dev, Error **errp)
-{
-    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-    AspeedSMCState *s = ASPEED_SMC(dev);
-    AspeedSMCClass *mc = ASPEED_SMC_GET_CLASS(s);
-    int i;
-    char name[32];
-    hwaddr offset = 0;
-
-    s->ctrl = mc->ctrl;
-
-    /* keep a copy under AspeedSMCState to speed up accesses */
-    s->r_conf = s->ctrl->r_conf;
-    s->r_ce_ctrl = s->ctrl->r_ce_ctrl;
-    s->r_ctrl0 = s->ctrl->r_ctrl0;
-    s->r_timings = s->ctrl->r_timings;
-    s->conf_enable_w0 = s->ctrl->conf_enable_w0;
-
-    /* Enforce some real HW limits */
-    if (s->num_cs > s->ctrl->max_slaves) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: num_cs cannot exceed: %d\n",
-                      __func__, s->ctrl->max_slaves);
-        s->num_cs = s->ctrl->max_slaves;
-    }
-
-    s->spi = ssi_create_bus(dev, "spi");
-
-    /* Setup cs_lines for slaves */
-    sysbus_init_irq(sbd, &s->irq);
-    s->cs_lines = g_new0(qemu_irq, s->num_cs);
-    ssi_auto_connect_slaves(dev, s->cs_lines, s->spi);
-
-    for (i = 0; i < s->num_cs; ++i) {
-        sysbus_init_irq(sbd, &s->cs_lines[i]);
-    }
-
-    aspeed_smc_reset(dev);
-
-    memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_ops, s,
-                          s->ctrl->name, ASPEED_SMC_R_MAX * 4);
-    sysbus_init_mmio(sbd, &s->mmio);
-
-    /*
-     * Memory region where flash modules are remapped
-     */
-    snprintf(name, sizeof(name), "%s.flash", s->ctrl->name);
-
-    memory_region_init_io(&s->mmio_flash, OBJECT(s),
-                          &aspeed_smc_flash_default_ops, s, name,
-                          s->ctrl->mapping_window_size);
-    sysbus_init_mmio(sbd, &s->mmio_flash);
-
-    s->flashes = g_new0(AspeedSMCFlash, s->num_cs);
-
-    for (i = 0; i < s->num_cs; ++i) {
-        AspeedSMCFlash *fl = &s->flashes[i];
-
-        snprintf(name, sizeof(name), "%s.%d", s->ctrl->name, i);
-
-        fl->id = i;
-        fl->controller = s;
-        fl->size = s->ctrl->segments[i].size;
-        memory_region_init_io(&fl->mmio, OBJECT(s), &aspeed_smc_flash_ops,
-                              fl, name, fl->size);
-        memory_region_add_subregion(&s->mmio_flash, offset, &fl->mmio);
-        offset += fl->size;
-    }
-}
-
-static const VMStateDescription vmstate_aspeed_smc = {
-    .name = "aspeed.smc",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT32_ARRAY(regs, AspeedSMCState, ASPEED_SMC_R_MAX),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static Property aspeed_smc_properties[] = {
-    DEFINE_PROP_UINT32("num-cs", AspeedSMCState, num_cs, 1),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void aspeed_smc_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    AspeedSMCClass *mc = ASPEED_SMC_CLASS(klass);
-
-    dc->realize = aspeed_smc_realize;
-    dc->reset = aspeed_smc_reset;
-    dc->props = aspeed_smc_properties;
-    dc->vmsd = &vmstate_aspeed_smc;
-    mc->ctrl = data;
-}
-
-static const TypeInfo aspeed_smc_info = {
-    .name           = TYPE_ASPEED_SMC,
-    .parent         = TYPE_SYS_BUS_DEVICE,
-    .instance_size  = sizeof(AspeedSMCState),
-    .class_size     = sizeof(AspeedSMCClass),
-    .abstract       = true,
-};
-
-static void aspeed_smc_register_types(void)
-{
-    int i;
-
-    type_register_static(&aspeed_smc_info);
-    for (i = 0; i < ARRAY_SIZE(controllers); ++i) {
-        TypeInfo ti = {
-            .name       = controllers[i].name,
-            .parent     = TYPE_ASPEED_SMC,
-            .class_init = aspeed_smc_class_init,
-            .class_data = (void *)&controllers[i],
-        };
-        type_register(&ti);
-    }
-}
-
-type_init(aspeed_smc_register_types)
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
deleted file mode 100644 (file)
index 4226199..0000000
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * IMX SPI Controller
- *
- * Copyright (c) 2016 Jean-Christophe Dubois <jcd@tribudubois.net>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "hw/ssi/imx_spi.h"
-#include "sysemu/sysemu.h"
-#include "qemu/log.h"
-
-#ifndef DEBUG_IMX_SPI
-#define DEBUG_IMX_SPI 0
-#endif
-
-#define DPRINTF(fmt, args...) \
-    do { \
-        if (DEBUG_IMX_SPI) { \
-            fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_SPI, \
-                                             __func__, ##args); \
-        } \
-    } while (0)
-
-static char const *imx_spi_reg_name(uint32_t reg)
-{
-    static char unknown[20];
-
-    switch (reg) {
-    case ECSPI_RXDATA:
-        return  "ECSPI_RXDATA";
-    case ECSPI_TXDATA:
-        return  "ECSPI_TXDATA";
-    case ECSPI_CONREG:
-        return  "ECSPI_CONREG";
-    case ECSPI_CONFIGREG:
-        return  "ECSPI_CONFIGREG";
-    case ECSPI_INTREG:
-        return  "ECSPI_INTREG";
-    case ECSPI_DMAREG:
-        return  "ECSPI_DMAREG";
-    case ECSPI_STATREG:
-        return  "ECSPI_STATREG";
-    case ECSPI_PERIODREG:
-        return  "ECSPI_PERIODREG";
-    case ECSPI_TESTREG:
-        return  "ECSPI_TESTREG";
-    case ECSPI_MSGDATA:
-        return  "ECSPI_MSGDATA";
-    default:
-        sprintf(unknown, "%d ?", reg);
-        return unknown;
-    }
-}
-
-static const VMStateDescription vmstate_imx_spi = {
-    .name = TYPE_IMX_SPI,
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_FIFO32(tx_fifo, IMXSPIState),
-        VMSTATE_FIFO32(rx_fifo, IMXSPIState),
-        VMSTATE_INT16(burst_length, IMXSPIState),
-        VMSTATE_UINT32_ARRAY(regs, IMXSPIState, ECSPI_MAX),
-        VMSTATE_END_OF_LIST()
-    },
-};
-
-static void imx_spi_txfifo_reset(IMXSPIState *s)
-{
-    fifo32_reset(&s->tx_fifo);
-    s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TE;
-    s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_TF;
-}
-
-static void imx_spi_rxfifo_reset(IMXSPIState *s)
-{
-    fifo32_reset(&s->rx_fifo);
-    s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RR;
-    s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RF;
-    s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RO;
-}
-
-static void imx_spi_update_irq(IMXSPIState *s)
-{
-    int level;
-
-    if (fifo32_is_empty(&s->rx_fifo)) {
-        s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RR;
-    } else {
-        s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RR;
-    }
-
-    if (fifo32_is_full(&s->rx_fifo)) {
-        s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RF;
-    } else {
-        s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RF;
-    }
-
-    if (fifo32_is_empty(&s->tx_fifo)) {
-        s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TE;
-    } else {
-        s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_TE;
-    }
-
-    if (fifo32_is_full(&s->tx_fifo)) {
-        s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TF;
-    } else {
-        s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_TF;
-    }
-
-    level = s->regs[ECSPI_STATREG] & s->regs[ECSPI_INTREG] ? 1 : 0;
-
-    qemu_set_irq(s->irq, level);
-
-    DPRINTF("IRQ level is %d\n", level);
-}
-
-static uint8_t imx_spi_selected_channel(IMXSPIState *s)
-{
-    return EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_CHANNEL_SELECT);
-}
-
-static uint32_t imx_spi_burst_length(IMXSPIState *s)
-{
-    return EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) + 1;
-}
-
-static bool imx_spi_is_enabled(IMXSPIState *s)
-{
-    return s->regs[ECSPI_CONREG] & ECSPI_CONREG_EN;
-}
-
-static bool imx_spi_channel_is_master(IMXSPIState *s)
-{
-    uint8_t mode = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_CHANNEL_MODE);
-
-    return (mode & (1 << imx_spi_selected_channel(s))) ? true : false;
-}
-
-static bool imx_spi_is_multiple_master_burst(IMXSPIState *s)
-{
-    uint8_t wave = EXTRACT(s->regs[ECSPI_CONFIGREG], ECSPI_CONFIGREG_SS_CTL);
-
-    return imx_spi_channel_is_master(s) &&
-           !(s->regs[ECSPI_CONREG] & ECSPI_CONREG_SMC) &&
-           ((wave & (1 << imx_spi_selected_channel(s))) ? true : false);
-}
-
-static void imx_spi_flush_txfifo(IMXSPIState *s)
-{
-    uint32_t tx;
-    uint32_t rx;
-
-    DPRINTF("Begin: TX Fifo Size = %d, RX Fifo Size = %d\n",
-            fifo32_num_used(&s->tx_fifo), fifo32_num_used(&s->rx_fifo));
-
-    while (!fifo32_is_empty(&s->tx_fifo)) {
-        int tx_burst = 0;
-        int index = 0;
-
-        if (s->burst_length <= 0) {
-            s->burst_length = imx_spi_burst_length(s);
-
-            DPRINTF("Burst length = %d\n", s->burst_length);
-
-            if (imx_spi_is_multiple_master_burst(s)) {
-                s->regs[ECSPI_CONREG] |= ECSPI_CONREG_XCH;
-            }
-        }
-
-        tx = fifo32_pop(&s->tx_fifo);
-
-        DPRINTF("data tx:0x%08x\n", tx);
-
-        tx_burst = MIN(s->burst_length, 32);
-
-        rx = 0;
-
-        while (tx_burst) {
-            uint8_t byte = tx & 0xff;
-
-            DPRINTF("writing 0x%02x\n", (uint32_t)byte);
-
-            /* We need to write one byte at a time */
-            byte = ssi_transfer(s->bus, byte);
-
-            DPRINTF("0x%02x read\n", (uint32_t)byte);
-
-            tx = tx >> 8;
-            rx |= (byte << (index * 8));
-
-            /* Remove 8 bits from the actual burst */
-            tx_burst -= 8;
-            s->burst_length -= 8;
-            index++;
-        }
-
-        DPRINTF("data rx:0x%08x\n", rx);
-
-        if (fifo32_is_full(&s->rx_fifo)) {
-            s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RO;
-        } else {
-            fifo32_push(&s->rx_fifo, (uint8_t)rx);
-        }
-
-        if (s->burst_length <= 0) {
-            s->regs[ECSPI_CONREG] &= ~ECSPI_CONREG_XCH;
-
-            if (!imx_spi_is_multiple_master_burst(s)) {
-                s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
-                break;
-            }
-        }
-    }
-
-    if (fifo32_is_empty(&s->tx_fifo)) {
-        s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
-    }
-
-    /* TODO: We should also use TDR and RDR bits */
-
-    DPRINTF("End: TX Fifo Size = %d, RX Fifo Size = %d\n",
-            fifo32_num_used(&s->tx_fifo), fifo32_num_used(&s->rx_fifo));
-}
-
-static void imx_spi_reset(DeviceState *dev)
-{
-    IMXSPIState *s = IMX_SPI(dev);
-
-    DPRINTF("\n");
-
-    memset(s->regs, 0, sizeof(s->regs));
-
-    s->regs[ECSPI_STATREG] = 0x00000003;
-
-    imx_spi_rxfifo_reset(s);
-    imx_spi_txfifo_reset(s);
-
-    imx_spi_update_irq(s);
-
-    s->burst_length = 0;
-}
-
-static uint64_t imx_spi_read(void *opaque, hwaddr offset, unsigned size)
-{
-    uint32_t value = 0;
-    IMXSPIState *s = opaque;
-    uint32_t index = offset >> 2;
-
-    if (index >=  ECSPI_MAX) {
-        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
-                      HWADDR_PRIx "\n", TYPE_IMX_SPI, __func__, offset);
-        return 0;
-    }
-
-    switch (index) {
-    case ECSPI_RXDATA:
-        if (!imx_spi_is_enabled(s)) {
-            value = 0;
-        } else if (fifo32_is_empty(&s->rx_fifo)) {
-            /* value is undefined */
-            value = 0xdeadbeef;
-        } else {
-            /* read from the RX FIFO */
-            value = fifo32_pop(&s->rx_fifo);
-        }
-
-        break;
-    case ECSPI_TXDATA:
-        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read from TX FIFO\n",
-                      TYPE_IMX_SPI, __func__);
-
-        /* Reading from TXDATA gives 0 */
-
-        break;
-    case ECSPI_MSGDATA:
-        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read from MSG FIFO\n",
-                      TYPE_IMX_SPI, __func__);
-
-        /* Reading from MSGDATA gives 0 */
-
-        break;
-    default:
-        value = s->regs[index];
-        break;
-    }
-
-    DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx_spi_reg_name(index), value);
-
-    imx_spi_update_irq(s);
-
-    return (uint64_t)value;
-}
-
-static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value,
-                           unsigned size)
-{
-    IMXSPIState *s = opaque;
-    uint32_t index = offset >> 2;
-    uint32_t change_mask;
-
-    if (index >=  ECSPI_MAX) {
-        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
-                      HWADDR_PRIx "\n", TYPE_IMX_SPI, __func__, offset);
-        return;
-    }
-
-    DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx_spi_reg_name(index),
-            (uint32_t)value);
-
-    change_mask = s->regs[index] ^ value;
-
-    switch (index) {
-    case ECSPI_RXDATA:
-        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to write to RX FIFO\n",
-                      TYPE_IMX_SPI, __func__);
-        break;
-    case ECSPI_TXDATA:
-    case ECSPI_MSGDATA:
-        /* Is there any difference between TXDATA and MSGDATA ? */
-        /* I'll have to look in the linux driver */
-        if (!imx_spi_is_enabled(s)) {
-            /* Ignore writes if device is disabled */
-            break;
-        } else if (fifo32_is_full(&s->tx_fifo)) {
-            /* Ignore writes if queue is full */
-            break;
-        }
-
-        fifo32_push(&s->tx_fifo, (uint32_t)value);
-
-        if (imx_spi_channel_is_master(s) &&
-            (s->regs[ECSPI_CONREG] & ECSPI_CONREG_SMC)) {
-            /*
-             * Start emitting if current channel is master and SMC bit is
-             * set.
-             */
-            imx_spi_flush_txfifo(s);
-        }
-
-        break;
-    case ECSPI_STATREG:
-        /* the RO and TC bits are write-one-to-clear */
-        value &= ECSPI_STATREG_RO | ECSPI_STATREG_TC;
-        s->regs[ECSPI_STATREG] &= ~value;
-
-        break;
-    case ECSPI_CONREG:
-        s->regs[ECSPI_CONREG] = value;
-
-        if (!imx_spi_is_enabled(s)) {
-            /* device is disabled, so this is a reset */
-            imx_spi_reset(DEVICE(s));
-            return;
-        }
-
-        if (imx_spi_channel_is_master(s)) {
-            int i;
-
-            /* We are in master mode */
-
-            for (i = 0; i < 4; i++) {
-                qemu_set_irq(s->cs_lines[i],
-                             i == imx_spi_selected_channel(s) ? 0 : 1);
-            }
-
-            if ((value & change_mask & ECSPI_CONREG_SMC) &&
-                !fifo32_is_empty(&s->tx_fifo)) {
-                /* SMC bit is set and TX FIFO has some slots filled in */
-                imx_spi_flush_txfifo(s);
-            } else if ((value & change_mask & ECSPI_CONREG_XCH) &&
-                !(value & ECSPI_CONREG_SMC)) {
-                /* This is a request to start emitting */
-                imx_spi_flush_txfifo(s);
-            }
-        }
-
-        break;
-    default:
-        s->regs[index] = value;
-
-        break;
-    }
-
-    imx_spi_update_irq(s);
-}
-
-static const struct MemoryRegionOps imx_spi_ops = {
-    .read = imx_spi_read,
-    .write = imx_spi_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .valid = {
-        /*
-         * Our device would not work correctly if the guest was doing
-         * unaligned access. This might not be a limitation on the real
-         * device but in practice there is no reason for a guest to access
-         * this device unaligned.
-         */
-        .min_access_size = 4,
-        .max_access_size = 4,
-        .unaligned = false,
-    },
-};
-
-static void imx_spi_realize(DeviceState *dev, Error **errp)
-{
-    IMXSPIState *s = IMX_SPI(dev);
-    int i;
-
-    s->bus = ssi_create_bus(dev, "spi");
-
-    memory_region_init_io(&s->iomem, OBJECT(dev), &imx_spi_ops, s,
-                          TYPE_IMX_SPI, 0x1000);
-    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
-    sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
-
-    ssi_auto_connect_slaves(dev, s->cs_lines, s->bus);
-
-    for (i = 0; i < 4; ++i) {
-        sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cs_lines[i]);
-    }
-
-    s->burst_length = 0;
-
-    fifo32_create(&s->tx_fifo, ECSPI_FIFO_SIZE);
-    fifo32_create(&s->rx_fifo, ECSPI_FIFO_SIZE);
-}
-
-static void imx_spi_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-
-    dc->realize = imx_spi_realize;
-    dc->vmsd = &vmstate_imx_spi;
-    dc->reset = imx_spi_reset;
-    dc->desc = "i.MX SPI Controller";
-}
-
-static const TypeInfo imx_spi_info = {
-    .name          = TYPE_IMX_SPI,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(IMXSPIState),
-    .class_init    = imx_spi_class_init,
-};
-
-static void imx_spi_register_types(void)
-{
-    type_register_static(&imx_spi_info);
-}
-
-type_init(imx_spi_register_types)
index c136801..564a0d3 100644 (file)
@@ -10,7 +10,6 @@
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
 #include "hw/ssi/ssi.h"
-#include "qemu/log.h"
 
 //#define DEBUG_PL022 1
 
index 7eaaf56..9791c0d 100644 (file)
@@ -54,7 +54,7 @@ static uint32_t ssi_transfer_raw_default(SSISlave *dev, uint32_t val)
     return 0;
 }
 
-static void ssi_slave_realize(DeviceState *dev, Error **errp)
+static int ssi_slave_init(DeviceState *dev)
 {
     SSISlave *s = SSI_SLAVE(dev);
     SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s);
@@ -64,7 +64,7 @@ static void ssi_slave_realize(DeviceState *dev, Error **errp)
         qdev_init_gpio_in_named(dev, ssi_cs_default, SSI_GPIO_CS, 1);
     }
 
-    ssc->realize(s, errp);
+    return ssc->init(s);
 }
 
 static void ssi_slave_class_init(ObjectClass *klass, void *data)
@@ -72,7 +72,7 @@ static void ssi_slave_class_init(ObjectClass *klass, void *data)
     SSISlaveClass *ssc = SSI_SLAVE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    dc->realize = ssi_slave_realize;
+    dc->init = ssi_slave_init;
     dc->bus_type = TYPE_SSI_BUS;
     if (!ssc->transfer_raw) {
         ssc->transfer_raw = ssi_transfer_raw_default;
index 7ba8c23..003c14f 100644 (file)
@@ -26,7 +26,6 @@ obj-$(CONFIG_OMAP) += omap_synctimer.o
 obj-$(CONFIG_PXA2XX) += pxa2xx_timer.o
 obj-$(CONFIG_SH4) += sh_timer.o
 obj-$(CONFIG_DIGIC) += digic-timer.o
-obj-$(CONFIG_MIPS_CPS) += mips_gictimer.o
 
 obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
 
index 3385e5d..51cdc98 100644 (file)
@@ -19,7 +19,6 @@
 #include "hw/sysbus.h"
 #include "sysemu/sysemu.h"
 #include "hw/timer/allwinner-a10-pit.h"
-#include "qemu/log.h"
 
 static void a10_pit_update_irq(AwA10PITState *s)
 {
index 111a16d..f1ede5f 100644 (file)
@@ -14,7 +14,6 @@
 #include "hw/qdev.h"
 #include "hw/ptimer.h"
 #include "qemu/main-loop.h"
-#include "qemu/log.h"
 
 /* Common timer implementation.  */
 
index 9b70ee0..ebec359 100644 (file)
  */
 
 #include "qemu/osdep.h"
+#include "hw/ptimer.h"
 #include "hw/sysbus.h"
 #include "hw/timer/aspeed_timer.h"
 #include "qemu-common.h"
 #include "qemu/bitops.h"
+#include "qemu/main-loop.h"
 #include "qemu/timer.h"
-#include "qemu/log.h"
 #include "trace.h"
 
 #define TIMER_NR_REGS 4
@@ -75,96 +76,21 @@ static inline bool timer_can_pulse(AspeedTimer *t)
     return t->id >= TIMER_FIRST_CAP_PULSE;
 }
 
-static inline bool timer_external_clock(AspeedTimer *t)
-{
-    return timer_ctrl_status(t, op_external_clock);
-}
-
-static uint32_t clock_rates[] = { TIMER_CLOCK_APB_HZ, TIMER_CLOCK_EXT_HZ };
-
-static inline uint32_t calculate_rate(struct AspeedTimer *t)
-{
-    return clock_rates[timer_external_clock(t)];
-}
-
-static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns)
-{
-    uint64_t delta_ns = now_ns - MIN(now_ns, t->start);
-    uint32_t rate = calculate_rate(t);
-    uint64_t ticks = muldiv64(delta_ns, rate, NANOSECONDS_PER_SECOND);
-
-    return t->reload - MIN(t->reload, ticks);
-}
-
-static inline uint64_t calculate_time(struct AspeedTimer *t, uint32_t ticks)
-{
-    uint64_t delta_ns;
-    uint64_t delta_ticks;
-
-    delta_ticks = t->reload - MIN(t->reload, ticks);
-    delta_ns = muldiv64(delta_ticks, NANOSECONDS_PER_SECOND, calculate_rate(t));
-
-    return t->start + delta_ns;
-}
-
-static uint64_t calculate_next(struct AspeedTimer *t)
-{
-    uint64_t next = 0;
-    uint32_t rate = calculate_rate(t);
-
-    while (!next) {
-        /* We don't know the relationship between the values in the match
-         * registers, so sort using MAX/MIN/zero. We sort in that order as the
-         * timer counts down to zero. */
-        uint64_t seq[] = {
-            calculate_time(t, MAX(t->match[0], t->match[1])),
-            calculate_time(t, MIN(t->match[0], t->match[1])),
-            calculate_time(t, 0),
-        };
-        uint64_t reload_ns;
-        uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-
-        if (now < seq[0]) {
-            next = seq[0];
-        } else if (now < seq[1]) {
-            next = seq[1];
-        } else if (now < seq[2]) {
-            next = seq[2];
-        } else {
-            reload_ns = muldiv64(t->reload, NANOSECONDS_PER_SECOND, rate);
-            t->start = now - ((now - t->start) % reload_ns);
-        }
-    }
-
-    return next;
-}
-
 static void aspeed_timer_expire(void *opaque)
 {
     AspeedTimer *t = opaque;
-    bool interrupt = false;
-    uint32_t ticks;
-
-    if (!timer_enabled(t)) {
-        return;
-    }
-
-    ticks = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 
-    if (!ticks) {
-        interrupt = timer_overflow_interrupt(t) || !t->match[0] || !t->match[1];
-    } else if (ticks <= MIN(t->match[0], t->match[1])) {
-        interrupt = true;
-    } else if (ticks <= MAX(t->match[0], t->match[1])) {
-        interrupt = true;
-    }
-
-    if (interrupt) {
+    /* Only support interrupts on match values of zero for the moment - this is
+     * sufficient to boot an aspeed_defconfig Linux kernel.
+     *
+     * TODO: matching on arbitrary values (see e.g. hw/timer/a9gtimer.c)
+     */
+    bool match = !(t->match[0] && t->match[1]);
+    bool interrupt = timer_overflow_interrupt(t) || match;
+    if (timer_enabled(t) && interrupt) {
         t->level = !t->level;
         qemu_set_irq(t->irq, t->level);
     }
-
-    timer_mod(&t->timer, calculate_next(t));
 }
 
 static uint64_t aspeed_timer_get_value(AspeedTimer *t, int reg)
@@ -173,7 +99,7 @@ static uint64_t aspeed_timer_get_value(AspeedTimer *t, int reg)
 
     switch (reg) {
     case TIMER_REG_STATUS:
-        value = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+        value = ptimer_get_count(t->timer);
         break;
     case TIMER_REG_RELOAD:
         value = t->reload;
@@ -233,22 +159,24 @@ static void aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int reg,
     switch (reg) {
     case TIMER_REG_STATUS:
         if (timer_enabled(t)) {
-            uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-            int64_t delta = (int64_t) value - (int64_t) calculate_ticks(t, now);
-            uint32_t rate = calculate_rate(t);
-
-            t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate);
-            timer_mod(&t->timer, calculate_next(t));
+            ptimer_set_count(t->timer, value);
         }
         break;
     case TIMER_REG_RELOAD:
         t->reload = value;
+        ptimer_set_limit(t->timer, value, 1);
         break;
     case TIMER_REG_MATCH_FIRST:
     case TIMER_REG_MATCH_SECOND:
-        t->match[reg - 2] = value;
-        if (timer_enabled(t)) {
-            timer_mod(&t->timer, calculate_next(t));
+        if (value) {
+            /* Non-zero match values are unsupported. As such an interrupt will
+             * always be triggered when the timer reaches zero even if the
+             * overflow interrupt control bit is clear.
+             */
+            qemu_log_mask(LOG_UNIMP, "%s: Match value unsupported by device: "
+                    "0x%" PRIx32 "\n", __func__, value);
+        } else {
+            t->match[reg - 2] = value;
         }
         break;
     default:
@@ -267,16 +195,21 @@ static void aspeed_timer_ctrl_enable(AspeedTimer *t, bool enable)
 {
     trace_aspeed_timer_ctrl_enable(t->id, enable);
     if (enable) {
-        t->start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-        timer_mod(&t->timer, calculate_next(t));
+        ptimer_run(t->timer, 0);
     } else {
-        timer_del(&t->timer);
+        ptimer_stop(t->timer);
+        ptimer_set_limit(t->timer, t->reload, 1);
     }
 }
 
 static void aspeed_timer_ctrl_external_clock(AspeedTimer *t, bool enable)
 {
     trace_aspeed_timer_ctrl_external_clock(t->id, enable);
+    if (enable) {
+        ptimer_set_freq(t->timer, TIMER_CLOCK_EXT_HZ);
+    } else {
+        ptimer_set_freq(t->timer, TIMER_CLOCK_APB_HZ);
+    }
 }
 
 static void aspeed_timer_ctrl_overflow_interrupt(AspeedTimer *t, bool enable)
@@ -417,10 +350,12 @@ static const MemoryRegionOps aspeed_timer_ops = {
 
 static void aspeed_init_one_timer(AspeedTimerCtrlState *s, uint8_t id)
 {
+    QEMUBH *bh;
     AspeedTimer *t = &s->timers[id];
 
     t->id = id;
-    timer_init_ns(&t->timer, QEMU_CLOCK_VIRTUAL, aspeed_timer_expire, t);
+    bh = qemu_bh_new(aspeed_timer_expire, t);
+    t->timer = ptimer_init(bh);
 }
 
 static void aspeed_timer_realize(DeviceState *dev, Error **errp)
@@ -463,12 +398,12 @@ static void aspeed_timer_reset(DeviceState *dev)
 
 static const VMStateDescription vmstate_aspeed_timer = {
     .name = "aspeed.timer",
-    .version_id = 2,
-    .minimum_version_id = 2,
+    .version_id = 1,
+    .minimum_version_id = 1,
     .fields = (VMStateField[]) {
         VMSTATE_UINT8(id, AspeedTimer),
         VMSTATE_INT32(level, AspeedTimer),
-        VMSTATE_TIMER(timer, AspeedTimer),
+        VMSTATE_PTIMER(timer, AspeedTimer),
         VMSTATE_UINT32(reload, AspeedTimer),
         VMSTATE_UINT32_ARRAY(match, AspeedTimer, 2),
         VMSTATE_END_OF_LIST()
@@ -483,7 +418,7 @@ static const VMStateDescription vmstate_aspeed_timer_state = {
         VMSTATE_UINT32(ctrl, AspeedTimerCtrlState),
         VMSTATE_UINT32(ctrl2, AspeedTimerCtrlState),
         VMSTATE_STRUCT_ARRAY(timers, AspeedTimerCtrlState,
-                             ASPEED_TIMER_NR_TIMERS, 2, vmstate_aspeed_timer,
+                             ASPEED_TIMER_NR_TIMERS, 1, vmstate_aspeed_timer,
                              AspeedTimer),
         VMSTATE_END_OF_LIST()
     }
index 0f21faf..5b97e1e 100644 (file)
@@ -30,7 +30,6 @@
 #include "hw/sysbus.h"
 #include "hw/ptimer.h"
 #include "qemu/main-loop.h"
-#include "qemu/log.h"
 
 #include "hw/timer/digic-timer.h"
 
index eddf348..f5836e2 100644 (file)
@@ -16,7 +16,6 @@
 #include "hw/timer/imx_epit.h"
 #include "hw/misc/imx_ccm.h"
 #include "qemu/main-loop.h"
-#include "qemu/log.h"
 
 #ifndef DEBUG_IMX_EPIT
 #define DEBUG_IMX_EPIT 0
index 82bc73c..ab2e213 100644 (file)
@@ -14,8 +14,8 @@
 
 #include "qemu/osdep.h"
 #include "hw/timer/imx_gpt.h"
+#include "hw/misc/imx_ccm.h"
 #include "qemu/main-loop.h"
-#include "qemu/log.h"
 
 #ifndef DEBUG_IMX_GPT
 #define DEBUG_IMX_GPT 0
@@ -80,18 +80,7 @@ static const VMStateDescription vmstate_imx_timer_gpt = {
     }
 };
 
-static const IMXClk imx25_gpt_clocks[] = {
-    CLK_NONE,      /* 000 No clock source */
-    CLK_IPG,       /* 001 ipg_clk, 532MHz*/
-    CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
-    CLK_NONE,      /* 011 not defined */
-    CLK_32k,       /* 100 ipg_clk_32k */
-    CLK_32k,       /* 101 ipg_clk_32k */
-    CLK_32k,       /* 110 ipg_clk_32k */
-    CLK_32k,       /* 111 ipg_clk_32k */
-};
-
-static const IMXClk imx31_gpt_clocks[] = {
+static const IMXClk imx_gpt_clocks[] = {
     CLK_NONE,      /* 000 No clock source */
     CLK_IPG,       /* 001 ipg_clk, 532MHz*/
     CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
@@ -102,23 +91,12 @@ static const IMXClk imx31_gpt_clocks[] = {
     CLK_NONE,      /* 111 not defined */
 };
 
-static const IMXClk imx6_gpt_clocks[] = {
-    CLK_NONE,      /* 000 No clock source */
-    CLK_IPG,       /* 001 ipg_clk, 532MHz*/
-    CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
-    CLK_EXT,       /* 011 External clock */
-    CLK_32k,       /* 100 ipg_clk_32k */
-    CLK_HIGH_DIV,  /* 101 reference clock / 8 */
-    CLK_NONE,      /* 110 not defined */
-    CLK_HIGH,      /* 111 reference clock */
-};
-
 static void imx_gpt_set_freq(IMXGPTState *s)
 {
     uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);
 
     s->freq = imx_ccm_get_clock_frequency(s->ccm,
-                                          s->clocks[clksrc]) / (1 + s->pr);
+                                imx_gpt_clocks[clksrc]) / (1 + s->pr);
 
     DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, s->freq);
 
@@ -474,52 +452,16 @@ static void imx_gpt_class_init(ObjectClass *klass, void *data)
     dc->desc = "i.MX general timer";
 }
 
-static void imx25_gpt_init(Object *obj)
-{
-    IMXGPTState *s = IMX_GPT(obj);
-
-    s->clocks = imx25_gpt_clocks;
-}
-
-static void imx31_gpt_init(Object *obj)
-{
-    IMXGPTState *s = IMX_GPT(obj);
-
-    s->clocks = imx31_gpt_clocks;
-}
-
-static void imx6_gpt_init(Object *obj)
-{
-    IMXGPTState *s = IMX_GPT(obj);
-
-    s->clocks = imx6_gpt_clocks;
-}
-
-static const TypeInfo imx25_gpt_info = {
-    .name = TYPE_IMX25_GPT,
+static const TypeInfo imx_gpt_info = {
+    .name = TYPE_IMX_GPT,
     .parent = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(IMXGPTState),
-    .instance_init = imx25_gpt_init,
     .class_init = imx_gpt_class_init,
 };
 
-static const TypeInfo imx31_gpt_info = {
-    .name = TYPE_IMX31_GPT,
-    .parent = TYPE_IMX25_GPT,
-    .instance_init = imx31_gpt_init,
-};
-
-static const TypeInfo imx6_gpt_info = {
-    .name = TYPE_IMX6_GPT,
-    .parent = TYPE_IMX25_GPT,
-    .instance_init = imx6_gpt_init,
-};
-
 static void imx_gpt_register_types(void)
 {
-    type_register_static(&imx25_gpt_info);
-    type_register_static(&imx31_gpt_info);
-    type_register_static(&imx6_gpt_info);
+    type_register_static(&imx_gpt_info);
 }
 
 type_init(imx_gpt_register_types)
index e45a65b..3198355 100644 (file)
@@ -176,26 +176,21 @@ static void timer_reset(DeviceState *d)
     ptimer_stop(s->ptimer);
 }
 
-static void lm32_timer_init(Object *obj)
+static int lm32_timer_init(SysBusDevice *dev)
 {
-    LM32TimerState *s = LM32_TIMER(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    LM32TimerState *s = LM32_TIMER(dev);
 
     sysbus_init_irq(dev, &s->irq);
 
     s->bh = qemu_bh_new(timer_hit, s);
     s->ptimer = ptimer_init(s->bh);
+    ptimer_set_freq(s->ptimer, s->freq_hz);
 
-    memory_region_init_io(&s->iomem, obj, &timer_ops, s,
+    memory_region_init_io(&s->iomem, OBJECT(s), &timer_ops, s,
                           "timer", R_MAX * 4);
     sysbus_init_mmio(dev, &s->iomem);
-}
 
-static void lm32_timer_realize(DeviceState *dev, Error **errp)
-{
-    LM32TimerState *s = LM32_TIMER(dev);
-
-    ptimer_set_freq(s->ptimer, s->freq_hz);
+    return 0;
 }
 
 static const VMStateDescription vmstate_lm32_timer = {
@@ -218,8 +213,9 @@ static Property lm32_timer_properties[] = {
 static void lm32_timer_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    dc->realize = lm32_timer_realize;
+    k->init = lm32_timer_init;
     dc->reset = timer_reset;
     dc->vmsd = &vmstate_lm32_timer;
     dc->props = lm32_timer_properties;
@@ -229,7 +225,6 @@ static const TypeInfo lm32_timer_info = {
     .name          = TYPE_LM32_TIMER,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(LM32TimerState),
-    .instance_init = lm32_timer_init,
     .class_init    = lm32_timer_class_init,
 };
 
index ea625f2..2ac0fd3 100644 (file)
@@ -22,6 +22,7 @@
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
+#include "config-target.h"
 #include "qemu/cutils.h"
 #include "qemu/bcd.h"
 #include "hw/hw.h"
@@ -105,10 +106,12 @@ static inline bool rtc_running(RTCState *s)
 
 static uint64_t get_guest_rtc_ns(RTCState *s)
 {
+    uint64_t guest_rtc;
     uint64_t guest_clock = qemu_clock_get_ns(rtc_clock);
 
-    return s->base_rtc * NANOSECONDS_PER_SECOND +
+    guest_rtc = s->base_rtc * NANOSECONDS_PER_SECOND +
         guest_clock - s->last_update + s->offset;
+    return guest_rtc;
 }
 
 #ifdef TARGET_I386
@@ -906,8 +909,6 @@ static void rtc_realizefn(DeviceState *dev, Error **errp)
 
     object_property_add_alias(qdev_get_machine(), "rtc-time",
                               OBJECT(s), "date", NULL);
-
-    qdev_init_gpio_out(dev, &s->irq, 1);
 }
 
 ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
@@ -922,9 +923,9 @@ ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
     qdev_prop_set_int32(dev, "base_year", base_year);
     qdev_init_nofail(dev);
     if (intercept_irq) {
-        qdev_connect_gpio_out(dev, 0, intercept_irq);
+        s->irq = intercept_irq;
     } else {
-        isa_connect_gpio_out(isadev, 0, RTC_ISA_IRQ);
+        isa_init_irq(isadev, &s->irq, RTC_ISA_IRQ);
     }
     QLIST_INSERT_HEAD(&rtc_devices, s, link);
 
index 2194832..5f29480 100644 (file)
@@ -18,7 +18,7 @@
  *
  *
  * Specification available at:
- *   http://milkymist.walle.cc/socdoc/sysctl.pdf
+ *   http://www.milkymist.org/socdoc/sysctl.pdf
  */
 
 #include "qemu/osdep.h"
@@ -270,10 +270,9 @@ static void milkymist_sysctl_reset(DeviceState *d)
     s->regs[R_GPIO_IN] = s->strappings;
 }
 
-static void milkymist_sysctl_init(Object *obj)
+static int milkymist_sysctl_init(SysBusDevice *dev)
 {
-    MilkymistSysctlState *s = MILKYMIST_SYSCTL(obj);
-    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
+    MilkymistSysctlState *s = MILKYMIST_SYSCTL(dev);
 
     sysbus_init_irq(dev, &s->gpio_irq);
     sysbus_init_irq(dev, &s->timer0_irq);
@@ -283,18 +282,14 @@ static void milkymist_sysctl_init(Object *obj)
     s->bh1 = qemu_bh_new(timer1_hit, s);
     s->ptimer0 = ptimer_init(s->bh0);
     s->ptimer1 = ptimer_init(s->bh1);
+    ptimer_set_freq(s->ptimer0, s->freq_hz);
+    ptimer_set_freq(s->ptimer1, s->freq_hz);
 
-    memory_region_init_io(&s->regs_region, obj, &sysctl_mmio_ops, s,
+    memory_region_init_io(&s->regs_region, OBJECT(s), &sysctl_mmio_ops, s,
             "milkymist-sysctl", R_MAX * 4);
     sysbus_init_mmio(dev, &s->regs_region);
-}
 
-static void milkymist_sysctl_realize(DeviceState *dev, Error **errp)
-{
-    MilkymistSysctlState *s = MILKYMIST_SYSCTL(dev);
-
-    ptimer_set_freq(s->ptimer0, s->freq_hz);
-    ptimer_set_freq(s->ptimer1, s->freq_hz);
+    return 0;
 }
 
 static const VMStateDescription vmstate_milkymist_sysctl = {
@@ -324,8 +319,9 @@ static Property milkymist_sysctl_properties[] = {
 static void milkymist_sysctl_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    dc->realize = milkymist_sysctl_realize;
+    k->init = milkymist_sysctl_init;
     dc->reset = milkymist_sysctl_reset;
     dc->vmsd = &vmstate_milkymist_sysctl;
     dc->props = milkymist_sysctl_properties;
@@ -335,7 +331,6 @@ static const TypeInfo milkymist_sysctl_info = {
     .name          = TYPE_MILKYMIST_SYSCTL,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(MilkymistSysctlState),
-    .instance_init = milkymist_sysctl_init,
     .class_init    = milkymist_sysctl_class_init,
 };
 
diff --git a/hw/timer/mips_gictimer.c b/hw/timer/mips_gictimer.c
deleted file mode 100644 (file)
index 3698889..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2016 Imagination Technologies
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/sysbus.h"
-#include "qemu/timer.h"
-#include "hw/timer/mips_gictimer.h"
-
-#define TIMER_PERIOD 10 /* 10 ns period for 100 Mhz frequency */
-
-static void gic_vptimer_update(MIPSGICTimerState *gictimer,
-                                   uint32_t vp_index, uint64_t now)
-{
-    uint64_t next;
-    uint32_t wait;
-
-    wait = gictimer->vptimers[vp_index].comparelo - gictimer->sh_counterlo -
-           (uint32_t)(now / TIMER_PERIOD);
-    next = now + (uint64_t)wait * TIMER_PERIOD;
-
-    timer_mod(gictimer->vptimers[vp_index].qtimer, next);
-}
-
-static void gic_vptimer_expire(MIPSGICTimerState *gictimer, uint32_t vp_index,
-                               uint64_t now)
-{
-    if (gictimer->countstop) {
-        /* timer stopped */
-        return;
-    }
-    gictimer->cb(gictimer->opaque, vp_index);
-    gic_vptimer_update(gictimer, vp_index, now);
-}
-
-static void gic_vptimer_cb(void *opaque)
-{
-    MIPSGICTimerVPState *vptimer = opaque;
-    MIPSGICTimerState *gictimer = vptimer->gictimer;
-    gic_vptimer_expire(gictimer, vptimer->vp_index,
-                       qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
-}
-
-uint32_t mips_gictimer_get_sh_count(MIPSGICTimerState *gictimer)
-{
-    int i;
-    if (gictimer->countstop) {
-        return gictimer->sh_counterlo;
-    } else {
-        uint64_t now;
-        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-        for (i = 0; i < gictimer->num_vps; i++) {
-            if (timer_pending(gictimer->vptimers[i].qtimer)
-                && timer_expired(gictimer->vptimers[i].qtimer, now)) {
-                /* The timer has already expired.  */
-                gic_vptimer_expire(gictimer, i, now);
-            }
-        }
-        return gictimer->sh_counterlo + (uint32_t)(now / TIMER_PERIOD);
-    }
-}
-
-void mips_gictimer_store_sh_count(MIPSGICTimerState *gictimer, uint64_t count)
-{
-    int i;
-    uint64_t now;
-
-    if (gictimer->countstop || !gictimer->vptimers[0].qtimer) {
-        gictimer->sh_counterlo = count;
-    } else {
-        /* Store new count register */
-        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-        gictimer->sh_counterlo = count - (uint32_t)(now / TIMER_PERIOD);
-        /* Update timer timer */
-        for (i = 0; i < gictimer->num_vps; i++) {
-            gic_vptimer_update(gictimer, i, now);
-        }
-    }
-}
-
-uint32_t mips_gictimer_get_vp_compare(MIPSGICTimerState *gictimer,
-                                      uint32_t vp_index)
-{
-    return gictimer->vptimers[vp_index].comparelo;
-}
-
-void mips_gictimer_store_vp_compare(MIPSGICTimerState *gictimer,
-                                    uint32_t vp_index, uint64_t compare)
-{
-    gictimer->vptimers[vp_index].comparelo = (uint32_t) compare;
-    gic_vptimer_update(gictimer, vp_index,
-                       qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
-}
-
-uint8_t mips_gictimer_get_countstop(MIPSGICTimerState *gictimer)
-{
-    return gictimer->countstop;
-}
-
-void mips_gictimer_start_count(MIPSGICTimerState *gictimer)
-{
-    gictimer->countstop = 0;
-    mips_gictimer_store_sh_count(gictimer, gictimer->sh_counterlo);
-}
-
-void mips_gictimer_stop_count(MIPSGICTimerState *gictimer)
-{
-    int i;
-
-    gictimer->countstop = 1;
-    /* Store the current value */
-    gictimer->sh_counterlo +=
-        (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / TIMER_PERIOD);
-    for (i = 0; i < gictimer->num_vps; i++) {
-        timer_del(gictimer->vptimers[i].qtimer);
-    }
-}
-
-MIPSGICTimerState *mips_gictimer_init(void *opaque, uint32_t nvps,
-                                      MIPSGICTimerCB *cb)
-{
-    int i;
-    MIPSGICTimerState *gictimer = g_new(MIPSGICTimerState, 1);
-    gictimer->vptimers = g_new(MIPSGICTimerVPState, nvps);
-    gictimer->countstop = 1;
-    gictimer->num_vps = nvps;
-    gictimer->opaque = opaque;
-    gictimer->cb = cb;
-    for (i = 0; i < nvps; i++) {
-        gictimer->vptimers[i].gictimer = gictimer;
-        gictimer->vptimers[i].vp_index = i;
-        gictimer->vptimers[i].qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
-                                            &gic_vptimer_cb,
-                                            &gictimer->vptimers[i]);
-    }
-    return gictimer;
-}
index 5e3e8a6..3a43863 100644 (file)
@@ -133,8 +133,8 @@ static inline void omap_gp_timer_update(struct omap_gp_timer_s *timer)
         timer_mod(timer->timer, timer->time + expires);
 
         if (timer->ce && timer->match_val >= timer->val) {
-            matches = muldiv64(timer->ticks_per_sec,
-                               timer->match_val - timer->val, timer->rate);
+            matches = muldiv64(timer->match_val - timer->val,
+                            timer->ticks_per_sec, timer->rate);
             timer_mod(timer->match, timer->time + matches);
         } else
             timer_del(timer->match);
index dbbeb9b..38e0cb5 100644 (file)
@@ -16,7 +16,6 @@
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
 #include "qemu/cutils.h"
-#include "qemu/log.h"
 
 //#define DEBUG_PL031
 
index bf0fb28..55dacbb 100644 (file)
@@ -24,7 +24,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/timer/stm32f2xx_timer.h"
-#include "qemu/log.h"
 
 #ifndef STM_TIMER_ERR_DEBUG
 #define STM_TIMER_ERR_DEBUG 0
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
deleted file mode 100644 (file)
index 3495c41..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/timer/slavio_timer.c
-slavio_timer_get_out(uint64_t limit, uint32_t counthigh, uint32_t count) "limit %"PRIx64" count %x%08x"
-slavio_timer_irq(uint32_t counthigh, uint32_t count) "callback: count %x%08x"
-slavio_timer_mem_readl_invalid(uint64_t addr) "invalid read address %"PRIx64
-slavio_timer_mem_readl(uint64_t addr, uint32_t ret) "read %"PRIx64" = %08x"
-slavio_timer_mem_writel(uint64_t addr, uint32_t val) "write %"PRIx64" = %08x"
-slavio_timer_mem_writel_limit(unsigned int timer_index, uint64_t count) "processor %d user timer set to %016"PRIx64
-slavio_timer_mem_writel_counter_invalid(void) "not user timer"
-slavio_timer_mem_writel_status_start(unsigned int timer_index) "processor %d user timer started"
-slavio_timer_mem_writel_status_stop(unsigned int timer_index) "processor %d user timer stopped"
-slavio_timer_mem_writel_mode_user(unsigned int timer_index) "processor %d changed from counter to user timer"
-slavio_timer_mem_writel_mode_counter(unsigned int timer_index) "processor %d changed from user timer to counter"
-slavio_timer_mem_writel_mode_invalid(void) "not system timer"
-slavio_timer_mem_writel_invalid(uint64_t addr) "invalid write address %"PRIx64
-
-# hw/timer/grlib_gptimer.c
-grlib_gptimer_enable(int id, uint32_t count) "timer:%d set count 0x%x and run"
-grlib_gptimer_disabled(int id, uint32_t config) "timer:%d Timer disable config 0x%x"
-grlib_gptimer_restart(int id, uint32_t reload) "timer:%d reload val: 0x%x"
-grlib_gptimer_set_scaler(uint32_t scaler, uint32_t freq) "scaler:0x%x freq: 0x%x"
-grlib_gptimer_hit(int id) "timer:%d HIT"
-grlib_gptimer_readl(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
-grlib_gptimer_writel(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
-
-# hw/timer/lm32_timer.c
-lm32_timer_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-lm32_timer_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-lm32_timer_hit(void) "timer hit"
-lm32_timer_irq_state(int level) "irq state %d"
-
-# hw/timer/milkymist-sysctl.c
-milkymist_sysctl_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_sysctl_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-milkymist_sysctl_icap_write(uint32_t value) "value %08x"
-milkymist_sysctl_start_timer0(void) "Start timer0"
-milkymist_sysctl_stop_timer0(void) "Stop timer0"
-milkymist_sysctl_start_timer1(void) "Start timer1"
-milkymist_sysctl_stop_timer1(void) "Stop timer1"
-milkymist_sysctl_pulse_irq_timer0(void) "Pulse IRQ Timer0"
-milkymist_sysctl_pulse_irq_timer1(void) "Pulse IRQ Timer1"
-
-# hw/timer/aspeed_timer.c
-aspeed_timer_ctrl_enable(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
-aspeed_timer_ctrl_external_clock(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
-aspeed_timer_ctrl_overflow_interrupt(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
-aspeed_timer_ctrl_pulse_enable(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
-aspeed_timer_set_ctrl2(uint32_t value) "Value: 0x%" PRIx32
-aspeed_timer_set_value(int timer, int reg, uint32_t value) "Timer %d register %d: 0x%" PRIx32
-aspeed_timer_read(uint64_t offset, unsigned size, uint64_t value) "From 0x%" PRIx64 ": of size %u: 0x%" PRIx64
index df76245..e7f354a 100644 (file)
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>
  */
-
-#ifndef TPM_TPM_UTIL_H
-#define TPM_TPM_UTIL_H
+#ifndef TPM_TPM_UTILS_H
+#define TPM_TPM_UTILS_H
 
 #include "sysemu/tpm_backend.h"
 
 int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version);
 
-#endif /* TPM_TPM_UTIL_H */
+#endif /* TPM_TPM_UTILS_H */
index 98b5c9d..2717027 100644 (file)
@@ -38,7 +38,3 @@ common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
 
 # usb pass-through
 common-obj-y += $(patsubst %,host-%.o,$(HOST_USB))
-
-ifeq ($(CONFIG_USB_LIBUSB),y)
-common-obj-$(CONFIG_XEN_BACKEND) += xen-usb.o
-endif
index 25913ad..16c3461 100644 (file)
@@ -55,9 +55,9 @@ static int usb_device_post_load(void *opaque, int version_id)
     USBDevice *dev = opaque;
 
     if (dev->state == USB_STATE_NOTATTACHED) {
-        dev->attached = false;
+        dev->attached = 0;
     } else {
-        dev->attached = true;
+        dev->attached = 1;
     }
     if (dev->setup_index < 0 ||
         dev->setup_len < 0 ||
@@ -279,13 +279,6 @@ static void usb_qdev_realize(DeviceState *qdev, Error **errp)
 static void usb_qdev_unrealize(DeviceState *qdev, Error **errp)
 {
     USBDevice *dev = USB_DEVICE(qdev);
-    USBDescString *s, *next;
-
-    QLIST_FOREACH_SAFE(s, &dev->strings, next, next) {
-        QLIST_REMOVE(s, next);
-        g_free(s->str);
-        g_free(s);
-    }
 
     if (dev->attached) {
         usb_device_detach(dev);
@@ -540,7 +533,7 @@ void usb_device_attach(USBDevice *dev, Error **errp)
         return;
     }
 
-    dev->attached = true;
+    dev->attached++;
     usb_attach(port);
 }
 
@@ -554,7 +547,7 @@ int usb_device_detach(USBDevice *dev)
     trace_usb_port_detach(bus->busnr, port->path);
 
     usb_detach(port);
-    dev->attached = false;
+    dev->attached--;
     return 0;
 }
 
@@ -743,48 +736,6 @@ USBDevice *usbdevice_create(const char *cmdline)
     return dev;
 }
 
-static bool usb_get_attached(Object *obj, Error **errp)
-{
-    USBDevice *dev = USB_DEVICE(obj);
-
-    return dev->attached;
-}
-
-static void usb_set_attached(Object *obj, bool value, Error **errp)
-{
-    USBDevice *dev = USB_DEVICE(obj);
-    Error *err = NULL;
-
-    if (dev->attached == value) {
-        return;
-    }
-
-    if (value) {
-        usb_device_attach(dev, &err);
-        if (err) {
-            error_propagate(errp, err);
-        }
-    } else {
-        usb_device_detach(dev);
-    }
-}
-
-static void usb_device_instance_init(Object *obj)
-{
-    USBDevice *dev = USB_DEVICE(obj);
-    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
-
-    if (klass->attached_settable) {
-        object_property_add_bool(obj, "attached",
-                                 usb_get_attached, usb_set_attached,
-                                 NULL);
-    } else {
-        object_property_add_bool(obj, "attached",
-                                 usb_get_attached, NULL,
-                                 NULL);
-    }
-}
-
 static void usb_device_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *k = DEVICE_CLASS(klass);
@@ -798,7 +749,6 @@ static const TypeInfo usb_device_type_info = {
     .name = TYPE_USB_DEVICE,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(USBDevice),
-    .instance_init = usb_device_instance_init,
     .abstract = true,
     .class_size = sizeof(USBDeviceClass),
     .class_init = usb_device_class_init,
index 5e0e1d1..adb026e 100644 (file)
@@ -574,7 +574,6 @@ void usb_desc_create_serial(USBDevice *dev)
     }
     dst += snprintf(serial+dst, sizeof(serial)-dst, "-%s", dev->port->path);
     usb_desc_set_string(dev, index, serial);
-    g_free(path);
 }
 
 const char *usb_desc_get_string(USBDevice *dev, uint8_t index)
index 1be85ae..bda84a6 100644 (file)
@@ -788,8 +788,8 @@ static MTPData *usb_mtp_get_device_info(MTPState *s, MTPControl *c)
     trace_usb_mtp_op_get_device_info(s->dev.addr);
 
     usb_mtp_add_u16(d, 100);
-    usb_mtp_add_u32(d, 0x00000006);
-    usb_mtp_add_u16(d, 0x0064);
+    usb_mtp_add_u32(d, 0xffffffff);
+    usb_mtp_add_u16(d, 0x0101);
     usb_mtp_add_wstr(d, L"");
     usb_mtp_add_u16(d, 0x0000);
 
index c0f1193..74306b5 100644 (file)
@@ -670,49 +670,48 @@ static int ndis_query(USBNetState *s, uint32_t oid,
     /* general oids (table 4-1) */
     /* mandatory */
     case OID_GEN_SUPPORTED_LIST:
-        for (i = 0; i < ARRAY_SIZE(oid_supported_list); i++) {
-            stl_le_p(outbuf + (i * sizeof(le32)), oid_supported_list[i]);
-        }
+        for (i = 0; i < ARRAY_SIZE(oid_supported_list); i++)
+            ((le32 *) outbuf)[i] = cpu_to_le32(oid_supported_list[i]);
         return sizeof(oid_supported_list);
 
     /* mandatory */
     case OID_GEN_HARDWARE_STATUS:
-        stl_le_p(outbuf, 0);
+        *((le32 *) outbuf) = cpu_to_le32(0);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_MEDIA_SUPPORTED:
-        stl_le_p(outbuf, s->medium);
+        *((le32 *) outbuf) = cpu_to_le32(s->medium);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_MEDIA_IN_USE:
-        stl_le_p(outbuf, s->medium);
+        *((le32 *) outbuf) = cpu_to_le32(s->medium);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_MAXIMUM_FRAME_SIZE:
-        stl_le_p(outbuf, ETH_FRAME_LEN);
+        *((le32 *) outbuf) = cpu_to_le32(ETH_FRAME_LEN);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_LINK_SPEED:
-        stl_le_p(outbuf, s->speed);
+        *((le32 *) outbuf) = cpu_to_le32(s->speed);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_TRANSMIT_BLOCK_SIZE:
-        stl_le_p(outbuf, ETH_FRAME_LEN);
+        *((le32 *) outbuf) = cpu_to_le32(ETH_FRAME_LEN);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_RECEIVE_BLOCK_SIZE:
-        stl_le_p(outbuf, ETH_FRAME_LEN);
+        *((le32 *) outbuf) = cpu_to_le32(ETH_FRAME_LEN);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_VENDOR_ID:
-        stl_le_p(outbuf, s->vendorid);
+        *((le32 *) outbuf) = cpu_to_le32(s->vendorid);
         return sizeof(le32);
 
     /* mandatory */
@@ -721,57 +720,58 @@ static int ndis_query(USBNetState *s, uint32_t oid,
         return strlen((char *)outbuf) + 1;
 
     case OID_GEN_VENDOR_DRIVER_VERSION:
-        stl_le_p(outbuf, 1);
+        *((le32 *) outbuf) = cpu_to_le32(1);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_CURRENT_PACKET_FILTER:
-        stl_le_p(outbuf, s->filter);
+        *((le32 *) outbuf) = cpu_to_le32(s->filter);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_MAXIMUM_TOTAL_SIZE:
-        stl_le_p(outbuf, RNDIS_MAX_TOTAL_SIZE);
+        *((le32 *) outbuf) = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_MEDIA_CONNECT_STATUS:
-        stl_le_p(outbuf, s->media_state);
+        *((le32 *) outbuf) = cpu_to_le32(s->media_state);
         return sizeof(le32);
 
     case OID_GEN_PHYSICAL_MEDIUM:
-        stl_le_p(outbuf, 0);
+        *((le32 *) outbuf) = cpu_to_le32(0);
         return sizeof(le32);
 
     case OID_GEN_MAC_OPTIONS:
-        stl_le_p(outbuf, NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
-                 NDIS_MAC_OPTION_FULL_DUPLEX);
+        *((le32 *) outbuf) = cpu_to_le32(
+                        NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
+                        NDIS_MAC_OPTION_FULL_DUPLEX);
         return sizeof(le32);
 
     /* statistics OIDs (table 4-2) */
     /* mandatory */
     case OID_GEN_XMIT_OK:
-        stl_le_p(outbuf, 0);
+        *((le32 *) outbuf) = cpu_to_le32(0);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_RCV_OK:
-        stl_le_p(outbuf, 0);
+        *((le32 *) outbuf) = cpu_to_le32(0);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_XMIT_ERROR:
-        stl_le_p(outbuf, 0);
+        *((le32 *) outbuf) = cpu_to_le32(0);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_RCV_ERROR:
-        stl_le_p(outbuf, 0);
+        *((le32 *) outbuf) = cpu_to_le32(0);
         return sizeof(le32);
 
     /* mandatory */
     case OID_GEN_RCV_NO_BUFFER:
-        stl_le_p(outbuf, 0);
+        *((le32 *) outbuf) = cpu_to_le32(0);
         return sizeof(le32);
 
     /* ieee802.3 OIDs (table 4-3) */
@@ -787,12 +787,12 @@ static int ndis_query(USBNetState *s, uint32_t oid,
 
     /* mandatory */
     case OID_802_3_MULTICAST_LIST:
-        stl_le_p(outbuf, 0xe0000000);
+        *((le32 *) outbuf) = cpu_to_le32(0xe0000000);
         return sizeof(le32);
 
     /* mandatory */
     case OID_802_3_MAXIMUM_LIST_SIZE:
-        stl_le_p(outbuf, 1);
+        *((le32 *) outbuf) = cpu_to_le32(1);
         return sizeof(le32);
 
     case OID_802_3_MAC_OPTIONS:
@@ -801,17 +801,17 @@ static int ndis_query(USBNetState *s, uint32_t oid,
     /* ieee802.3 statistics OIDs (table 4-4) */
     /* mandatory */
     case OID_802_3_RCV_ERROR_ALIGNMENT:
-        stl_le_p(outbuf, 0);
+        *((le32 *) outbuf) = cpu_to_le32(0);
         return sizeof(le32);
 
     /* mandatory */
     case OID_802_3_XMIT_ONE_COLLISION:
-        stl_le_p(outbuf, 0);
+        *((le32 *) outbuf) = cpu_to_le32(0);
         return sizeof(le32);
 
     /* mandatory */
     case OID_802_3_XMIT_MORE_COLLISIONS:
-        stl_le_p(outbuf, 0);
+        *((le32 *) outbuf) = cpu_to_le32(0);
         return sizeof(le32);
 
     default:
@@ -826,7 +826,7 @@ static int ndis_set(USBNetState *s, uint32_t oid,
 {
     switch (oid) {
     case OID_GEN_CURRENT_PACKET_FILTER:
-        s->filter = ldl_le_p(inbuf);
+        s->filter = le32_to_cpup((le32 *) inbuf);
         if (s->filter) {
             s->rndis_state = RNDIS_DATA_INITIALIZED;
         } else {
@@ -1026,7 +1026,10 @@ static void usb_net_reset_in_buf(USBNetState *s)
 
 static int rndis_parse(USBNetState *s, uint8_t *data, int length)
 {
-    uint32_t msg_type = ldl_le_p(data);
+    uint32_t msg_type;
+    le32 *tmp = (le32 *) data;
+
+    msg_type = le32_to_cpup(tmp);
 
     switch (msg_type) {
     case RNDIS_INITIALIZE_MSG:
@@ -1334,7 +1337,7 @@ static void usb_net_handle_destroy(USBDevice *dev)
 }
 
 static NetClientInfo net_usbnet_info = {
-    .type = NET_CLIENT_DRIVER_NIC,
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .receive = usbnet_receive,
     .cleanup = usbnet_cleanup,
@@ -1396,7 +1399,7 @@ static USBDevice *usb_net_init(USBBus *bus, const char *cmdline)
     qemu_opt_set(opts, "type", "nic", &error_abort);
     qemu_opt_set(opts, "model", "usb", &error_abort);
 
-    idx = net_client_init(opts, false, &local_err);
+    idx = net_client_init(opts, 0, &local_err);
     if (local_err) {
         error_report_err(local_err);
         return NULL;
index c607f76..248a580 100644 (file)
@@ -556,6 +556,21 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
     }
 }
 
+static void usb_msd_password_cb(void *opaque, int err)
+{
+    MSDState *s = opaque;
+    Error *local_err = NULL;
+
+    if (!err) {
+        usb_device_attach(&s->dev, &local_err);
+    }
+
+    if (local_err) {
+        error_report_err(local_err);
+        qdev_unplug(&s->dev.qdev, NULL);
+    }
+}
+
 static void *usb_msd_load_request(QEMUFile *f, SCSIRequest *req)
 {
     MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
@@ -601,21 +616,37 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
         return;
     }
 
+    if (blk_bs(blk)) {
+        bdrv_add_key(blk_bs(blk), NULL, &err);
+        if (err) {
+            if (monitor_cur_is_qmp()) {
+                error_propagate(errp, err);
+                return;
+            }
+            error_free(err);
+            err = NULL;
+            if (cur_mon) {
+                monitor_read_bdrv_key_start(cur_mon, blk_bs(blk),
+                                            usb_msd_password_cb, s);
+                s->dev.auto_attach = 0;
+            } else {
+                autostart = 0;
+            }
+        }
+    }
+
     blkconf_serial(&s->conf, &dev->serial);
     blkconf_blocksizes(&s->conf);
-    blkconf_apply_backend_options(&s->conf);
 
     /*
      * Hack alert: this pretends to be a block device, but it's really
      * a SCSI bus that can serve only a single device, which it
      * creates automatically.  But first it needs to detach from its
      * blockdev, or else scsi_bus_legacy_add_drive() dies when it
-     * attaches again. We also need to take another reference so that
-     * blk_detach_dev() doesn't free blk while we still need it.
+     * attaches again.
      *
      * The hack is probably a bad idea.
      */
-    blk_ref(blk);
     blk_detach_dev(blk, &s->dev.qdev);
     s->conf.blk = NULL;
 
@@ -626,7 +657,6 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
     scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable,
                                          s->conf.bootindex, dev->serial,
                                          &err);
-    blk_unref(blk);
     if (!scsi_dev) {
         error_propagate(errp, err);
         return;
@@ -638,14 +668,9 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
 static void usb_msd_realize_bot(USBDevice *dev, Error **errp)
 {
     MSDState *s = USB_STORAGE_DEV(dev);
-    DeviceState *d = DEVICE(dev);
 
     usb_desc_create_serial(dev);
     usb_desc_init(dev);
-    if (d->hotplugged) {
-        s->dev.auto_attach = 0;
-    }
-
     scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
                  &usb_msd_scsi_info_bot, NULL);
     usb_msd_handle_reset(dev);
@@ -793,7 +818,9 @@ static void usb_msd_set_bootindex(Object *obj, Visitor *v, const char *name,
     }
 
 out:
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
 }
 
 static const TypeInfo usb_storage_dev_type_info = {
@@ -815,9 +842,10 @@ static void usb_msd_instance_init(Object *obj)
 static void usb_msd_class_initfn_bot(ObjectClass *klass, void *data)
 {
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     uc->realize = usb_msd_realize_bot;
-    uc->attached_settable = true;
+    dc->hotpluggable = false;
 }
 
 static const TypeInfo msd_info = {
index 3a8ff18..0678b1b 100644 (file)
@@ -900,13 +900,9 @@ static void usb_uas_handle_destroy(USBDevice *dev)
 static void usb_uas_realize(USBDevice *dev, Error **errp)
 {
     UASDevice *uas = USB_UAS(dev);
-    DeviceState *d = DEVICE(dev);
 
     usb_desc_create_serial(dev);
     usb_desc_init(dev);
-    if (d->hotplugged) {
-        uas->dev.auto_attach = 0;
-    }
 
     QTAILQ_INIT(&uas->results);
     QTAILQ_INIT(&uas->requests);
@@ -944,7 +940,6 @@ static void usb_uas_class_initfn(ObjectClass *klass, void *data)
     uc->handle_control = usb_uas_handle_control;
     uc->handle_data    = usb_uas_handle_data;
     uc->handle_destroy = usb_uas_handle_destroy;
-    uc->attached_settable = true;
     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
     dc->fw_name = "storage";
     dc->vmsd = &vmstate_usb_uas;
index b093db7..43a8f7a 100644 (file)
@@ -2206,28 +2206,29 @@ static void ehci_advance_periodic_state(EHCIState *ehci)
 
 static void ehci_update_frindex(EHCIState *ehci, int uframes)
 {
+    int i;
+
     if (!ehci_enabled(ehci) && ehci->pstate == EST_INACTIVE) {
         return;
     }
 
-    /* Generate FLR interrupt if frame index rolls over 0x2000 */
-    if ((ehci->frindex % 0x2000) + uframes >= 0x2000) {
-        ehci_raise_irq(ehci, USBSTS_FLR);
-    }
+    for (i = 0; i < uframes; i++) {
+        ehci->frindex++;
 
-    /* How many times will frindex roll over 0x4000 with this frame count?
-     * usbsts_frindex is decremented by 0x4000 on rollover until it reaches 0
-     */
-    int rollovers = (ehci->frindex + uframes) / 0x4000;
-    if (rollovers > 0) {
-        if (ehci->usbsts_frindex >= (rollovers * 0x4000)) {
-            ehci->usbsts_frindex -= 0x4000 * rollovers;
-        } else {
-            ehci->usbsts_frindex = 0;
+        if (ehci->frindex == 0x00002000) {
+            ehci_raise_irq(ehci, USBSTS_FLR);
         }
-    }
 
-    ehci->frindex = (ehci->frindex + uframes) % 0x4000;
+        if (ehci->frindex == 0x00004000) {
+            ehci_raise_irq(ehci, USBSTS_FLR);
+            ehci->frindex = 0;
+            if (ehci->usbsts_frindex >= 0x00004000) {
+                ehci->usbsts_frindex -= 0x00004000;
+            } else {
+                ehci->usbsts_frindex = 0;
+            }
+        }
+    }
 }
 
 static void ehci_frame_timer(void *opaque)
index 3fd7038..3021842 100644 (file)
@@ -14,9 +14,8 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
-
-#ifndef HW_USB_HCD_EHCI_H
-#define HW_USB_HCD_EHCI_H
+#ifndef HW_USB_EHCI_H
+#define HW_USB_EHCI_H 1
 
 #include "hw/hw.h"
 #include "qemu/timer.h"
index fa57038..16d9ff7 100644 (file)
@@ -1474,7 +1474,7 @@ static uint32_t ohci_get_frame_remaining(OHCIState *ohci)
     if (tks >= usb_frame_time)
         return (ohci->frt << 31);
 
-    tks = tks / usb_bit_time;
+    tks = muldiv64(1, tks, usb_bit_time);
     fr = (uint16_t)(ohci->fi - tks);
 
     return (ohci->frt << 31) | fr;
index 188f954..43ba615 100644 (file)
@@ -26,7 +26,6 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
 #include "trace.h"
-#include "qapi/error.h"
 
 //#define DEBUG_XHCI
 //#define DEBUG_DATA
@@ -462,8 +461,6 @@ struct XHCIState {
     uint32_t numslots;
     uint32_t flags;
     uint32_t max_pstreams_mask;
-    OnOffAuto msi;
-    OnOffAuto msix;
 
     /* Operational Registers */
     uint32_t usbcmd;
@@ -501,7 +498,9 @@ typedef struct XHCIEvRingSeg {
 } XHCIEvRingSeg;
 
 enum xhci_flags {
-    XHCI_FLAG_SS_FIRST = 1,
+    XHCI_FLAG_USE_MSI = 1,
+    XHCI_FLAG_USE_MSI_X,
+    XHCI_FLAG_SS_FIRST,
     XHCI_FLAG_FORCE_PCIE_ENDCAP,
     XHCI_FLAG_ENABLE_STREAMS,
 };
@@ -2201,9 +2200,7 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
         xfer->trb_count = length;
 
         for (i = 0; i < length; i++) {
-            TRBType type;
-            type = xhci_ring_fetch(xhci, ring, &xfer->trbs[i], NULL);
-            assert(type);
+            assert(xhci_ring_fetch(xhci, ring, &xfer->trbs[i], NULL));
         }
         xfer->streamid = streamid;
 
@@ -2366,8 +2363,6 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
     slot->uport = uport;
     slot->ctx = octx;
 
-    /* Make sure device is in USB_STATE_DEFAULT state */
-    usb_device_reset(dev);
     if (bsr) {
         slot_ctx[3] = SLOT_DEFAULT << SLOT_STATE_SHIFT;
     } else {
@@ -2375,6 +2370,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
         uint8_t buf[1];
 
         slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slotid;
+        usb_device_reset(dev);
         memset(&p, 0, sizeof(p));
         usb_packet_addbuf(&p, buf, sizeof(buf));
         usb_packet_setup(&p, USB_TOKEN_OUT,
@@ -3585,7 +3581,6 @@ static void usb_xhci_init(XHCIState *xhci)
 static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
 {
     int i, ret;
-    Error *err = NULL;
 
     XHCIState *xhci = XHCI(dev);
 
@@ -3596,23 +3591,6 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
 
     usb_xhci_init(xhci);
 
-    if (xhci->msi != ON_OFF_AUTO_OFF) {
-        ret = msi_init(dev, 0x70, xhci->numintrs, true, false, &err);
-        /* Any error other than -ENOTSUP(board's MSI support is broken)
-         * is a programming error */
-        assert(!ret || ret == -ENOTSUP);
-        if (ret && xhci->msi == ON_OFF_AUTO_ON) {
-            /* Can't satisfy user's explicit msi=on request, fail */
-            error_append_hint(&err, "You have to use msi=auto (default) or "
-                    "msi=off with this machine type.\n");
-            error_propagate(errp, err);
-            return;
-        }
-        assert(!err || xhci->msi == ON_OFF_AUTO_AUTO);
-        /* With msi=auto, we fall back to MSI off silently */
-        error_free(err);
-    }
-
     if (xhci->numintrs > MAXINTRS) {
         xhci->numintrs = MAXINTRS;
     }
@@ -3670,8 +3648,10 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
         assert(ret >= 0);
     }
 
-    if (xhci->msix != ON_OFF_AUTO_OFF) {
-        /* TODO check for errors */
+    if (xhci_get_flag(xhci, XHCI_FLAG_USE_MSI)) {
+        msi_init(dev, 0x70, xhci->numintrs, true, false);
+    }
+    if (xhci_get_flag(xhci, XHCI_FLAG_USE_MSI_X)) {
         msix_init(dev, xhci->numintrs,
                   &xhci->mem, 0, OFF_MSIX_TABLE,
                   &xhci->mem, 0, OFF_MSIX_PBA,
@@ -3892,8 +3872,8 @@ static const VMStateDescription vmstate_xhci = {
 };
 
 static Property xhci_properties[] = {
-    DEFINE_PROP_ON_OFF_AUTO("msi", XHCIState, msi, ON_OFF_AUTO_AUTO),
-    DEFINE_PROP_ON_OFF_AUTO("msix", XHCIState, msix, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_BIT("msi",      XHCIState, flags, XHCI_FLAG_USE_MSI, true),
+    DEFINE_PROP_BIT("msix",     XHCIState, flags, XHCI_FLAG_USE_MSI_X, true),
     DEFINE_PROP_BIT("superspeed-ports-first",
                     XHCIState, flags, XHCI_FLAG_SS_FIRST, true),
     DEFINE_PROP_BIT("force-pcie-endcap", XHCIState, flags,
index e94672c..6458a94 100644 (file)
@@ -34,9 +34,7 @@
  */
 
 #include "qemu/osdep.h"
-#ifndef CONFIG_WIN32
 #include <poll.h>
-#endif
 #include <libusb.h>
 
 #include "qapi/error.h"
@@ -81,7 +79,6 @@ struct USBHostDevice {
     uint32_t                         iso_urb_frames;
     uint32_t                         options;
     uint32_t                         loglevel;
-    bool                             needs_autoscan;
 
     /* state */
     QTAILQ_ENTRY(USBHostDevice)      next;
@@ -207,8 +204,6 @@ static const char *err_names[] = {
 static libusb_context *ctx;
 static uint32_t loglevel;
 
-#ifndef CONFIG_WIN32
-
 static void usb_host_handle_fd(void *opaque)
 {
     struct timeval tv = { 0, 0 };
@@ -228,14 +223,10 @@ static void usb_host_del_fd(int fd, void *user_data)
     qemu_set_fd_handler(fd, NULL, NULL, NULL);
 }
 
-#endif /* !CONFIG_WIN32 */
-
 static int usb_host_init(void)
 {
-#ifndef CONFIG_WIN32
     const struct libusb_pollfd **poll;
-#endif
-    int rc;
+    int i, rc;
 
     if (ctx) {
         return 0;
@@ -245,21 +236,17 @@ static int usb_host_init(void)
         return -1;
     }
     libusb_set_debug(ctx, loglevel);
-#ifdef CONFIG_WIN32
-    /* FIXME: add support for Windows. */
-#else
+
     libusb_set_pollfd_notifiers(ctx, usb_host_add_fd,
                                 usb_host_del_fd,
                                 ctx);
     poll = libusb_get_pollfds(ctx);
     if (poll) {
-        int i;
         for (i = 0; poll[i] != NULL; i++) {
             usb_host_add_fd(poll[i]->fd, poll[i]->events, ctx);
         }
     }
     free(poll);
-#endif
     return 0;
 }
 
@@ -359,7 +346,7 @@ static USBHostRequest *usb_host_req_find(USBHostDevice *s, USBPacket *p)
     return NULL;
 }
 
-static void LIBUSB_CALL usb_host_req_complete_ctrl(struct libusb_transfer *xfer)
+static void usb_host_req_complete_ctrl(struct libusb_transfer *xfer)
 {
     USBHostRequest *r = xfer->user_data;
     USBHostDevice  *s = r->host;
@@ -392,7 +379,7 @@ out:
     }
 }
 
-static void LIBUSB_CALL usb_host_req_complete_data(struct libusb_transfer *xfer)
+static void usb_host_req_complete_data(struct libusb_transfer *xfer)
 {
     USBHostRequest *r = xfer->user_data;
     USBHostDevice  *s = r->host;
@@ -448,8 +435,7 @@ static void usb_host_req_abort(USBHostRequest *r)
 
 /* ------------------------------------------------------------------------ */
 
-static void LIBUSB_CALL
-usb_host_req_complete_iso(struct libusb_transfer *transfer)
+static void usb_host_req_complete_iso(struct libusb_transfer *transfer)
 {
     USBHostIsoXfer *xfer = transfer->user_data;
 
@@ -977,32 +963,9 @@ static void usb_host_exit_notifier(struct Notifier *n, void *data)
     }
 }
 
-static libusb_device *usb_host_find_ref(int bus, int addr)
-{
-    libusb_device **devs = NULL;
-    libusb_device *ret = NULL;
-    int i, n;
-
-    if (usb_host_init() != 0) {
-        return NULL;
-    }
-    n = libusb_get_device_list(ctx, &devs);
-    for (i = 0; i < n; i++) {
-        if (libusb_get_bus_number(devs[i]) == bus &&
-            libusb_get_device_address(devs[i]) == addr) {
-            ret = libusb_ref_device(devs[i]);
-            break;
-        }
-    }
-    libusb_free_device_list(devs, 1);
-    return ret;
-}
-
 static void usb_host_realize(USBDevice *udev, Error **errp)
 {
     USBHostDevice *s = USB_HOST_DEVICE(udev);
-    libusb_device *ldev;
-    int rc;
 
     if (s->match.vendor_id > 0xffff) {
         error_setg(errp, "vendorid out of range");
@@ -1023,33 +986,11 @@ static void usb_host_realize(USBDevice *udev, Error **errp)
     QTAILQ_INIT(&s->requests);
     QTAILQ_INIT(&s->isorings);
 
-    if (s->match.addr && s->match.bus_num &&
-        !s->match.vendor_id &&
-        !s->match.product_id &&
-        !s->match.port) {
-        s->needs_autoscan = false;
-        ldev = usb_host_find_ref(s->match.bus_num,
-                                 s->match.addr);
-        if (!ldev) {
-            error_setg(errp, "failed to find host usb device %d:%d",
-                       s->match.bus_num, s->match.addr);
-            return;
-        }
-        rc = usb_host_open(s, ldev);
-        libusb_unref_device(ldev);
-        if (rc < 0) {
-            error_setg(errp, "failed to open host usb device %d:%d",
-                       s->match.bus_num, s->match.addr);
-            return;
-        }
-    } else {
-        s->needs_autoscan = true;
-        QTAILQ_INSERT_TAIL(&hostdevs, s, next);
-        usb_host_auto_check(NULL);
-    }
-
     s->exit.notify = usb_host_exit_notifier;
     qemu_add_exit_notifier(&s->exit);
+
+    QTAILQ_INSERT_TAIL(&hostdevs, s, next);
+    usb_host_auto_check(NULL);
 }
 
 static void usb_host_instance_init(Object *obj)
@@ -1067,9 +1008,7 @@ static void usb_host_handle_destroy(USBDevice *udev)
     USBHostDevice *s = USB_HOST_DEVICE(udev);
 
     qemu_remove_exit_notifier(&s->exit);
-    if (s->needs_autoscan) {
-        QTAILQ_REMOVE(&hostdevs, s, next);
-    }
+    QTAILQ_REMOVE(&hostdevs, s, next);
     usb_host_close(s);
 }
 
index 444672a..8d80540 100644 (file)
@@ -109,7 +109,6 @@ struct USBRedirDevice {
     uint8_t debug;
     char *filter_str;
     int32_t bootindex;
-    bool enable_streams;
     /* Data passed from chardev the fd_read cb to the usbredirparser read cb */
     const uint8_t *read_buf;
     int read_buf_size;
@@ -543,9 +542,9 @@ static void usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
             start_iso.pkts_per_urb = 32;
         }
 
-        start_iso.no_urbs = DIV_ROUND_UP(
-                                     dev->endpoint[EP2I(ep)].bufpq_target_size,
-                                     start_iso.pkts_per_urb);
+        start_iso.no_urbs = (dev->endpoint[EP2I(ep)].bufpq_target_size +
+                             start_iso.pkts_per_urb - 1) /
+                            start_iso.pkts_per_urb;
         /* Output endpoints pre-fill only 1/2 of the packets, keeping the rest
            as overflow buffer. Also see the usbredir protocol documentation */
         if (!(ep & USB_DIR_IN)) {
@@ -1230,9 +1229,7 @@ static void usbredir_create_parser(USBRedirDevice *dev)
     usbredirparser_caps_set_cap(caps, usb_redir_cap_32bits_bulk_length);
     usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_receiving);
 #if USBREDIR_VERSION >= 0x000700
-    if (dev->enable_streams) {
-        usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_streams);
-    }
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_streams);
 #endif
 
     if (runstate_check(RUN_STATE_INMIGRATE)) {
@@ -2479,7 +2476,6 @@ static Property usbredir_properties[] = {
     DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
     DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, usbredirparser_warning),
     DEFINE_PROP_STRING("filter", USBRedirDevice, filter_str),
-    DEFINE_PROP_BOOL("streams", USBRedirDevice, enable_streams, true),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/usb/trace-events b/hw/usb/trace-events
deleted file mode 100644 (file)
index 2d42fd4..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/usb/core.c
-usb_packet_state_change(int bus, const char *port, int ep, void *p, const char *o, const char *n) "bus %d, port %s, ep %d, packet %p, state %s -> %s"
-usb_packet_state_fault(int bus, const char *port, int ep, void *p, const char *o, const char *n) "bus %d, port %s, ep %d, packet %p, state %s, expected %s"
-
-# hw/usb/bus.c
-usb_port_claim(int bus, const char *port) "bus %d, port %s"
-usb_port_attach(int bus, const char *port, const char *devspeed, const char *portspeed) "bus %d, port %s, devspeed %s, portspeed %s"
-usb_port_detach(int bus, const char *port) "bus %d, port %s"
-usb_port_release(int bus, const char *port) "bus %d, port %s"
-
-# hw/usb/hcd-ohci.c
-usb_ohci_iso_td_read_failed(uint32_t addr) "ISO_TD read error at %x"
-usb_ohci_iso_td_head(uint32_t head, uint32_t tail, uint32_t flags, uint32_t bp, uint32_t next, uint32_t be, uint32_t framenum, uint32_t startframe, uint32_t framecount, int rel_frame_num) "ISO_TD ED head 0x%.8x tailp 0x%.8x\n0x%.8x 0x%.8x 0x%.8x 0x%.8x\nframe_number 0x%.8x starting_frame 0x%.8x\nframe_count  0x%.8x relative %d"
-usb_ohci_iso_td_head_offset(uint32_t o0, uint32_t o1, uint32_t o2, uint32_t o3, uint32_t o4, uint32_t o5, uint32_t o6, uint32_t o7) "0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x"
-usb_ohci_iso_td_relative_frame_number_neg(int rel) "ISO_TD R=%d < 0"
-usb_ohci_iso_td_relative_frame_number_big(int rel, int count) "ISO_TD R=%d > FC=%d"
-usb_ohci_iso_td_bad_direction(int dir) "Bad direction %d"
-usb_ohci_iso_td_bad_bp_be(uint32_t bp, uint32_t be) "ISO_TD bp 0x%.8x be 0x%.8x"
-usb_ohci_iso_td_bad_cc_not_accessed(uint32_t start, uint32_t next) "ISO_TD cc != not accessed 0x%.8x 0x%.8x"
-usb_ohci_iso_td_bad_cc_overrun(uint32_t start, uint32_t next) "ISO_TD start_offset=0x%.8x > next_offset=0x%.8x"
-usb_ohci_iso_td_so(uint32_t so, uint32_t eo, uint32_t s, uint32_t e, const char *str, ssize_t len, int ret) "0x%.8x eo 0x%.8x\nsa 0x%.8x ea 0x%.8x\ndir %s len %zu ret %d"
-usb_ohci_iso_td_data_overrun(int ret, ssize_t len) "DataOverrun %d > %zu"
-usb_ohci_iso_td_data_underrun(int ret) "DataUnderrun %d"
-usb_ohci_iso_td_nak(int ret) "got NAK/STALL %d"
-usb_ohci_iso_td_bad_response(int ret) "Bad device response %d"
-usb_ohci_port_attach(int index) "port #%d"
-usb_ohci_port_detach(int index) "port #%d"
-usb_ohci_port_wakeup(int index) "port #%d"
-usb_ohci_port_suspend(int index) "port #%d"
-usb_ohci_port_reset(int index) "port #%d"
-usb_ohci_remote_wakeup(const char *s) "%s: SUSPEND->RESUME"
-usb_ohci_reset(const char *s) "%s"
-usb_ohci_start(const char *s) "%s: USB Operational"
-usb_ohci_resume(const char *s) "%s: USB Resume"
-usb_ohci_stop(const char *s) "%s: USB Suspended"
-usb_ohci_exit(const char *s) "%s"
-usb_ohci_set_ctl(const char *s, uint32_t new_state) "%s: new state 0x%x"
-usb_ohci_td_underrun(void) ""
-usb_ohci_td_dev_error(void) ""
-usb_ohci_td_nak(void) ""
-usb_ohci_td_stall(void) ""
-usb_ohci_td_babble(void) ""
-usb_ohci_td_bad_device_response(int rc) "%d"
-usb_ohci_td_read_error(uint32_t addr) "TD read error at %x"
-usb_ohci_td_bad_direction(int dir) "Bad direction %d"
-usb_ohci_td_skip_async(void) ""
-usb_ohci_td_pkt_hdr(uint32_t addr, int64_t pktlen, int64_t len, const char *s, int flag_r, uint32_t cbp, uint32_t be) " TD @ 0x%.8x %" PRId64 " of %" PRId64 " bytes %s r=%d cbp=0x%.8x be=0x%.8x"
-usb_ohci_td_pkt_short(const char *dir, const char *buf) "%s data: %s"
-usb_ohci_td_pkt_full(const char *dir, const char *buf) "%s data: %s"
-usb_ohci_td_too_many_pending(void) ""
-usb_ohci_td_packet_status(int status) "status=%d"
-usb_ohci_ed_read_error(uint32_t addr) "ED read error at %x"
-usb_ohci_ed_pkt(uint32_t cur, int h, int c, uint32_t head, uint32_t tail, uint32_t next) "ED @ 0x%.8x h=%u c=%u\n  head=0x%.8x tailp=0x%.8x next=0x%.8x"
-usb_ohci_ed_pkt_flags(uint32_t fa, uint32_t en, uint32_t d, int s, int k, int f, uint32_t mps) "fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u"
-usb_ohci_hcca_read_error(uint32_t addr) "HCCA read error at %x"
-usb_ohci_mem_read_unaligned(uint32_t addr) "at %x"
-usb_ohci_mem_read_bad_offset(uint32_t addr) "%x"
-usb_ohci_mem_write_unaligned(uint32_t addr) "at %x"
-usb_ohci_mem_write_bad_offset(uint32_t addr) "%x"
-usb_ohci_process_lists(uint32_t head, uint32_t cur) "head %x, cur %x"
-usb_ohci_bus_eof_timer_failed(const char *name) "%s: timer_new_ns failed"
-usb_ohci_set_frame_interval(const char *name, uint16_t fi_x, uint16_t fi_u) "%s: FrameInterval = 0x%x (%u)"
-usb_ohci_hub_power_up(void) "powered up all ports"
-usb_ohci_hub_power_down(void) "powered down all ports"
-usb_ohci_init_time(int64_t frametime, int64_t bittime) "usb_bit_time=%" PRId64 " usb_frame_time=%" PRId64
-usb_ohci_die(void) ""
-usb_ohci_async_complete(void) ""
-
-# hw/usb/hcd-ehci.c
-usb_ehci_reset(void) "=== RESET ==="
-usb_ehci_unrealize(void) "=== UNREALIZE ==="
-usb_ehci_opreg_read(uint32_t addr, const char *str, uint32_t val) "rd mmio %04x [%s] = %x"
-usb_ehci_opreg_write(uint32_t addr, const char *str, uint32_t val) "wr mmio %04x [%s] = %x"
-usb_ehci_opreg_change(uint32_t addr, const char *str, uint32_t new, uint32_t old) "ch mmio %04x [%s] = %x (old: %x)"
-usb_ehci_portsc_read(uint32_t addr, uint32_t port, uint32_t val) "rd mmio %04x [port %d] = %x"
-usb_ehci_portsc_write(uint32_t addr, uint32_t port, uint32_t val) "wr mmio %04x [port %d] = %x"
-usb_ehci_portsc_change(uint32_t addr, uint32_t port, uint32_t new, uint32_t old) "ch mmio %04x [port %d] = %x (old: %x)"
-usb_ehci_usbsts(const char *sts, int state) "usbsts %s %d"
-usb_ehci_state(const char *schedule, const char *state) "%s schedule %s"
-usb_ehci_qh_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t c_qtd, uint32_t n_qtd, uint32_t a_qtd) "q %p - QH @ %08x: next %08x qtds %08x,%08x,%08x"
-usb_ehci_qh_fields(uint32_t addr, int rl, int mplen, int eps, int ep, int devaddr) "QH @ %08x - rl %d, mplen %d, eps %d, ep %d, dev %d"
-usb_ehci_qh_bits(uint32_t addr, int c, int h, int dtc, int i) "QH @ %08x - c %d, h %d, dtc %d, i %d"
-usb_ehci_qtd_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t altnext) "q %p - QTD @ %08x: next %08x altnext %08x"
-usb_ehci_qtd_fields(uint32_t addr, int tbytes, int cpage, int cerr, int pid) "QTD @ %08x - tbytes %d, cpage %d, cerr %d, pid %d"
-usb_ehci_qtd_bits(uint32_t addr, int ioc, int active, int halt, int babble, int xacterr) "QTD @ %08x - ioc %d, active %d, halt %d, babble %d, xacterr %d"
-usb_ehci_itd(uint32_t addr, uint32_t nxt, uint32_t mplen, uint32_t mult, uint32_t ep, uint32_t devaddr) "ITD @ %08x: next %08x - mplen %d, mult %d, ep %d, dev %d"
-usb_ehci_sitd(uint32_t addr, uint32_t nxt, uint32_t active) "ITD @ %08x: next %08x - active %d"
-usb_ehci_port_attach(uint32_t port, const char *owner, const char *device) "attach port #%d, owner %s, device %s"
-usb_ehci_port_detach(uint32_t port, const char *owner) "detach port #%d, owner %s"
-usb_ehci_port_reset(uint32_t port, int enable) "reset port #%d - %d"
-usb_ehci_port_suspend(uint32_t port) "port #%d"
-usb_ehci_port_wakeup(uint32_t port) "port #%d"
-usb_ehci_port_resume(uint32_t port) "port #%d"
-usb_ehci_queue_action(void *q, const char *action) "q %p: %s"
-usb_ehci_packet_action(void *q, void *p, const char *action) "q %p p %p: %s"
-usb_ehci_irq(uint32_t level, uint32_t frindex, uint32_t sts, uint32_t mask) "level %d, frindex 0x%04x, sts 0x%x, mask 0x%x"
-usb_ehci_guest_bug(const char *reason) "%s"
-usb_ehci_doorbell_ring(void) ""
-usb_ehci_doorbell_ack(void) ""
-usb_ehci_dma_error(void) ""
-
-# hw/usb/hcd-uhci.c
-usb_uhci_reset(void) "=== RESET ==="
-usb_uhci_exit(void) "=== EXIT ==="
-usb_uhci_schedule_start(void) ""
-usb_uhci_schedule_stop(void) ""
-usb_uhci_frame_start(uint32_t num) "nr %d"
-usb_uhci_frame_stop_bandwidth(void) ""
-usb_uhci_frame_loop_stop_idle(void) ""
-usb_uhci_frame_loop_continue(void) ""
-usb_uhci_mmio_readw(uint32_t addr, uint32_t val) "addr 0x%04x, ret 0x%04x"
-usb_uhci_mmio_writew(uint32_t addr, uint32_t val) "addr 0x%04x, val 0x%04x"
-usb_uhci_queue_add(uint32_t token) "token 0x%x"
-usb_uhci_queue_del(uint32_t token, const char *reason) "token 0x%x: %s"
-usb_uhci_packet_add(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
-usb_uhci_packet_link_async(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
-usb_uhci_packet_unlink_async(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
-usb_uhci_packet_cancel(uint32_t token, uint32_t addr, int done) "token 0x%x, td 0x%x, done %d"
-usb_uhci_packet_complete_success(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
-usb_uhci_packet_complete_shortxfer(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
-usb_uhci_packet_complete_stall(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
-usb_uhci_packet_complete_babble(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
-usb_uhci_packet_complete_error(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
-usb_uhci_packet_del(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
-usb_uhci_qh_load(uint32_t qh) "qh 0x%x"
-usb_uhci_td_load(uint32_t qh, uint32_t td, uint32_t ctrl, uint32_t token) "qh 0x%x, td 0x%x, ctrl 0x%x, token 0x%x"
-usb_uhci_td_queue(uint32_t td, uint32_t ctrl, uint32_t token) "td 0x%x, ctrl 0x%x, token 0x%x"
-usb_uhci_td_nextqh(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x"
-usb_uhci_td_async(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x"
-usb_uhci_td_complete(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x"
-
-# hw/usb/hcd-xhci.c
-usb_xhci_reset(void) "=== RESET ==="
-usb_xhci_exit(void) "=== EXIT ==="
-usb_xhci_run(void) ""
-usb_xhci_stop(void) ""
-usb_xhci_cap_read(uint32_t off, uint32_t val) "off 0x%04x, ret 0x%08x"
-usb_xhci_oper_read(uint32_t off, uint32_t val) "off 0x%04x, ret 0x%08x"
-usb_xhci_port_read(uint32_t port, uint32_t off, uint32_t val) "port %d, off 0x%04x, ret 0x%08x"
-usb_xhci_runtime_read(uint32_t off, uint32_t val) "off 0x%04x, ret 0x%08x"
-usb_xhci_doorbell_read(uint32_t off, uint32_t val) "off 0x%04x, ret 0x%08x"
-usb_xhci_oper_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
-usb_xhci_port_write(uint32_t port, uint32_t off, uint32_t val) "port %d, off 0x%04x, val 0x%08x"
-usb_xhci_runtime_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
-usb_xhci_doorbell_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
-usb_xhci_irq_intx(uint32_t level) "level %d"
-usb_xhci_irq_msi(uint32_t nr) "nr %d"
-usb_xhci_irq_msix(uint32_t nr) "nr %d"
-usb_xhci_irq_msix_use(uint32_t nr) "nr %d"
-usb_xhci_irq_msix_unuse(uint32_t nr) "nr %d"
-usb_xhci_queue_event(uint32_t vector, uint32_t idx, const char *trb, const char *evt, uint64_t param, uint32_t status, uint32_t control) "v %d, idx %d, %s, %s, p %016" PRIx64 ", s %08x, c 0x%08x"
-usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x"
-usb_xhci_port_reset(uint32_t port, bool warm) "port %d, warm %d"
-usb_xhci_port_link(uint32_t port, uint32_t pls) "port %d, pls %d"
-usb_xhci_port_notify(uint32_t port, uint32_t pls) "port %d, bits %x"
-usb_xhci_slot_enable(uint32_t slotid) "slotid %d"
-usb_xhci_slot_disable(uint32_t slotid) "slotid %d"
-usb_xhci_slot_address(uint32_t slotid, const char *port) "slotid %d, port %s"
-usb_xhci_slot_configure(uint32_t slotid) "slotid %d"
-usb_xhci_slot_evaluate(uint32_t slotid) "slotid %d"
-usb_xhci_slot_reset(uint32_t slotid) "slotid %d"
-usb_xhci_ep_enable(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
-usb_xhci_ep_disable(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
-usb_xhci_ep_set_dequeue(uint32_t slotid, uint32_t epid, uint32_t streamid, uint64_t param) "slotid %d, epid %d, streamid %d, ptr %016" PRIx64
-usb_xhci_ep_kick(uint32_t slotid, uint32_t epid, uint32_t streamid) "slotid %d, epid %d, streamid %d"
-usb_xhci_ep_stop(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
-usb_xhci_ep_reset(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
-usb_xhci_ep_state(uint32_t slotid, uint32_t epid, const char *os, const char *ns) "slotid %d, epid %d, %s -> %s"
-usb_xhci_xfer_start(void *xfer, uint32_t slotid, uint32_t epid, uint32_t streamid) "%p: slotid %d, epid %d, streamid %d"
-usb_xhci_xfer_async(void *xfer) "%p"
-usb_xhci_xfer_nak(void *xfer) "%p"
-usb_xhci_xfer_retry(void *xfer) "%p"
-usb_xhci_xfer_success(void *xfer, uint32_t bytes) "%p: len %d"
-usb_xhci_xfer_error(void *xfer, uint32_t ret) "%p: ret %d"
-usb_xhci_unimplemented(const char *item, int nr) "%s (0x%x)"
-
-# hw/usb/desc.c
-usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
-usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d"
-usb_desc_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
-usb_desc_other_speed_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
-usb_desc_string(int addr, int index, int len, int ret) "dev %d query string %d, len %d, ret %d"
-usb_desc_bos(int addr, int len, int ret) "dev %d bos, len %d, ret %d"
-usb_desc_msos(int addr, int index, int len, int ret) "dev %d msos, index 0x%x, len %d, ret %d"
-usb_set_addr(int addr) "dev %d"
-usb_set_config(int addr, int config, int ret) "dev %d, config %d, ret %d"
-usb_set_interface(int addr, int iface, int alt, int ret) "dev %d, interface %d, altsetting %d, ret %d"
-usb_clear_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
-usb_set_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
-
-# hw/usb/dev-hub.c
-usb_hub_reset(int addr) "dev %d"
-usb_hub_control(int addr, int request, int value, int index, int length) "dev %d, req 0x%x, value %d, index %d, langth %d"
-usb_hub_get_port_status(int addr, int nr, int status, int changed) "dev %d, port %d, status 0x%x, changed 0x%x"
-usb_hub_set_port_feature(int addr, int nr, const char *f) "dev %d, port %d, feature %s"
-usb_hub_clear_port_feature(int addr, int nr, const char *f) "dev %d, port %d, feature %s"
-usb_hub_attach(int addr, int nr) "dev %d, port %d"
-usb_hub_detach(int addr, int nr) "dev %d, port %d"
-usb_hub_status_report(int addr, int status) "dev %d, status 0x%x"
-
-# hw/usb/dev-uas.c
-usb_uas_reset(int addr) "dev %d"
-usb_uas_command(int addr, uint16_t tag, int lun, uint32_t lun64_1, uint32_t lun64_2) "dev %d, tag 0x%x, lun %d, lun64 %08x-%08x"
-usb_uas_response(int addr, uint16_t tag, uint8_t code) "dev %d, tag 0x%x, code 0x%x"
-usb_uas_sense(int addr, uint16_t tag, uint8_t status) "dev %d, tag 0x%x, status 0x%x"
-usb_uas_read_ready(int addr, uint16_t tag) "dev %d, tag 0x%x"
-usb_uas_write_ready(int addr, uint16_t tag) "dev %d, tag 0x%x"
-usb_uas_xfer_data(int addr, uint16_t tag, uint32_t copy, uint32_t uoff, uint32_t usize, uint32_t soff, uint32_t ssize) "dev %d, tag 0x%x, copy %d, usb-pkt %d/%d, scsi-buf %d/%d"
-usb_uas_scsi_data(int addr, uint16_t tag, uint32_t bytes) "dev %d, tag 0x%x, bytes %d"
-usb_uas_scsi_complete(int addr, uint16_t tag, uint32_t status, uint32_t resid) "dev %d, tag 0x%x, status 0x%x, residue %d"
-usb_uas_tmf_abort_task(int addr, uint16_t tag, uint16_t task_tag) "dev %d, tag 0x%x, task-tag 0x%x"
-usb_uas_tmf_logical_unit_reset(int addr, uint16_t tag, int lun) "dev %d, tag 0x%x, lun %d"
-usb_uas_tmf_unsupported(int addr, uint16_t tag, uint32_t function) "dev %d, tag 0x%x, function 0x%x"
-
-# hw/usb/dev-mtp.c
-usb_mtp_reset(int addr) "dev %d"
-usb_mtp_command(int dev, uint16_t code, uint32_t trans, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4) "dev %d, code 0x%x, trans 0x%x, args 0x%x, 0x%x, 0x%x, 0x%x, 0x%x"
-usb_mtp_success(int dev, uint32_t trans, uint32_t arg0, uint32_t arg1) "dev %d, trans 0x%x, args 0x%x, 0x%x"
-usb_mtp_error(int dev, uint16_t code, uint32_t trans, uint32_t arg0, uint32_t arg1) "dev %d, code 0x%x, trans 0x%x, args 0x%x, 0x%x"
-usb_mtp_data_in(int dev, uint32_t trans, uint32_t len) "dev %d, trans 0x%x, len %d"
-usb_mtp_xfer(int dev, uint32_t ep, uint32_t dlen, uint32_t plen) "dev %d, ep %d, %d/%d"
-usb_mtp_nak(int dev, uint32_t ep) "dev %d, ep %d"
-usb_mtp_stall(int dev, const char *reason) "dev %d, reason: %s"
-usb_mtp_op_get_device_info(int dev) "dev %d"
-usb_mtp_op_open_session(int dev) "dev %d"
-usb_mtp_op_close_session(int dev) "dev %d"
-usb_mtp_op_get_storage_ids(int dev) "dev %d"
-usb_mtp_op_get_storage_info(int dev) "dev %d"
-usb_mtp_op_get_num_objects(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
-usb_mtp_op_get_object_handles(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
-usb_mtp_op_get_object_info(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
-usb_mtp_op_get_object(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
-usb_mtp_op_get_partial_object(int dev, uint32_t handle, const char *path, uint32_t offset, uint32_t length) "dev %d, handle 0x%x, path %s, off %d, len %d"
-usb_mtp_op_unknown(int dev, uint32_t code) "dev %d, command code 0x%x"
-usb_mtp_object_alloc(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
-usb_mtp_object_free(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
-usb_mtp_add_child(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
-usb_mtp_inotify_event(int dev, const char *path, uint32_t mask, const char *s) "dev %d, path %s mask 0x%x event %s"
-
-# hw/usb/host-libusb.c
-usb_host_open_started(int bus, int addr) "dev %d:%d"
-usb_host_open_success(int bus, int addr) "dev %d:%d"
-usb_host_open_failure(int bus, int addr) "dev %d:%d"
-usb_host_close(int bus, int addr) "dev %d:%d"
-usb_host_attach_kernel(int bus, int addr, int interface) "dev %d:%d, if %d"
-usb_host_detach_kernel(int bus, int addr, int interface) "dev %d:%d, if %d"
-usb_host_set_address(int bus, int addr, int config) "dev %d:%d, address %d"
-usb_host_set_config(int bus, int addr, int config) "dev %d:%d, config %d"
-usb_host_set_interface(int bus, int addr, int interface, int alt) "dev %d:%d, interface %d, alt %d"
-usb_host_claim_interface(int bus, int addr, int config, int interface) "dev %d:%d, config %d, if %d"
-usb_host_release_interface(int bus, int addr, int interface) "dev %d:%d, if %d"
-usb_host_req_control(int bus, int addr, void *p, int req, int value, int index) "dev %d:%d, packet %p, req 0x%x, value %d, index %d"
-usb_host_req_data(int bus, int addr, void *p, int in, int ep, int size) "dev %d:%d, packet %p, in %d, ep %d, size %d"
-usb_host_req_complete(int bus, int addr, void *p, int status, int length) "dev %d:%d, packet %p, status %d, length %d"
-usb_host_req_emulated(int bus, int addr, void *p, int status) "dev %d:%d, packet %p, status %d"
-usb_host_req_canceled(int bus, int addr, void *p) "dev %d:%d, packet %p"
-usb_host_iso_start(int bus, int addr, int ep) "dev %d:%d, ep %d"
-usb_host_iso_stop(int bus, int addr, int ep) "dev %d:%d, ep %d"
-usb_host_iso_out_of_bufs(int bus, int addr, int ep) "dev %d:%d, ep %d"
-usb_host_reset(int bus, int addr) "dev %d:%d"
-usb_host_auto_scan_enabled(void)
-usb_host_auto_scan_disabled(void)
-usb_host_parse_config(int bus, int addr, int value, int active) "dev %d:%d, value %d, active %d"
-usb_host_parse_interface(int bus, int addr, int num, int alt, int active) "dev %d:%d, num %d, alt %d, active %d"
-usb_host_parse_endpoint(int bus, int addr, int ep, const char *dir, const char *type, int active) "dev %d:%d, ep %d, %s, %s, active %d"
-usb_host_parse_error(int bus, int addr, const char *errmsg) "dev %d:%d, msg %s"
diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
deleted file mode 100644 (file)
index 174d715..0000000
+++ /dev/null
@@ -1,1107 +0,0 @@
-/*
- *  xen paravirt usb device backend
- *
- *  (c) Juergen Gross <jgross@suse.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; under version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- *  Contributions after 2012-01-13 are licensed under the terms of the
- *  GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include <libusb.h>
-#include <sys/user.h>
-
-#include "qemu-common.h"
-#include "qemu/config-file.h"
-#include "hw/sysbus.h"
-#include "hw/usb.h"
-#include "hw/xen/xen_backend.h"
-#include "monitor/qdev.h"
-#include "qapi/qmp/qbool.h"
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qstring.h"
-
-#include <xen/io/ring.h>
-#include <xen/io/usbif.h>
-
-/*
- * Check for required support of usbif.h: USBIF_SHORT_NOT_OK was the last
- * macro added we rely on.
- */
-#ifdef USBIF_SHORT_NOT_OK
-
-#define TR(xendev, lvl, fmt, args...)                               \
-    {                                                               \
-        struct timeval tv;                                          \
-                                                                    \
-        gettimeofday(&tv, NULL);                                    \
-        xen_be_printf(xendev, lvl, "%8ld.%06ld xen-usb(%s):" fmt,   \
-                      tv.tv_sec, tv.tv_usec, __func__, ##args);     \
-    }
-#define TR_BUS(xendev, fmt, args...) TR(xendev, 2, fmt, ##args)
-#define TR_REQ(xendev, fmt, args...) TR(xendev, 3, fmt, ##args)
-
-#define USBBACK_MAXPORTS        USBIF_PIPE_PORT_MASK
-#define USB_DEV_ADDR_SIZE       (USBIF_PIPE_DEV_MASK + 1)
-
-/* USB wire protocol: structure describing control request parameter. */
-struct usbif_ctrlrequest {
-    uint8_t    bRequestType;
-    uint8_t    bRequest;
-    uint16_t   wValue;
-    uint16_t   wIndex;
-    uint16_t   wLength;
-};
-
-struct usbback_info;
-struct usbback_req;
-
-struct usbback_stub {
-    USBDevice     *dev;
-    USBPort       port;
-    unsigned int  speed;
-    bool          attached;
-    QTAILQ_HEAD(submit_q_head, usbback_req) submit_q;
-};
-
-struct usbback_req {
-    struct usbback_info      *usbif;
-    struct usbback_stub      *stub;
-    struct usbif_urb_request req;
-    USBPacket                packet;
-
-    unsigned int             nr_buffer_segs; /* # of transfer_buffer segments */
-    unsigned int             nr_extra_segs;  /* # of iso_frame_desc segments  */
-
-    QTAILQ_ENTRY(usbback_req) q;
-
-    void                     *buffer;
-    void                     *isoc_buffer;
-    struct libusb_transfer   *xfer;
-
-    bool                     cancelled;
-};
-
-struct usbback_hotplug {
-    QSIMPLEQ_ENTRY(usbback_hotplug) q;
-    unsigned                 port;
-};
-
-struct usbback_info {
-    struct XenDevice         xendev;  /* must be first */
-    USBBus                   bus;
-    void                     *urb_sring;
-    void                     *conn_sring;
-    struct usbif_urb_back_ring urb_ring;
-    struct usbif_conn_back_ring conn_ring;
-    int                      num_ports;
-    int                      usb_ver;
-    bool                     ring_error;
-    QTAILQ_HEAD(req_free_q_head, usbback_req) req_free_q;
-    QSIMPLEQ_HEAD(hotplug_q_head, usbback_hotplug) hotplug_q;
-    struct usbback_stub      ports[USBBACK_MAXPORTS];
-    struct usbback_stub      *addr_table[USB_DEV_ADDR_SIZE];
-    QEMUBH                   *bh;
-};
-
-static struct usbback_req *usbback_get_req(struct usbback_info *usbif)
-{
-    struct usbback_req *usbback_req;
-
-    if (QTAILQ_EMPTY(&usbif->req_free_q)) {
-        usbback_req = g_new0(struct usbback_req, 1);
-    } else {
-        usbback_req = QTAILQ_FIRST(&usbif->req_free_q);
-        QTAILQ_REMOVE(&usbif->req_free_q, usbback_req, q);
-    }
-    return usbback_req;
-}
-
-static void usbback_put_req(struct usbback_req *usbback_req)
-{
-    struct usbback_info *usbif;
-
-    usbif = usbback_req->usbif;
-    memset(usbback_req, 0, sizeof(*usbback_req));
-    QTAILQ_INSERT_HEAD(&usbif->req_free_q, usbback_req, q);
-}
-
-static int usbback_gnttab_map(struct usbback_req *usbback_req)
-{
-    unsigned int nr_segs, i, prot;
-    uint32_t ref[USBIF_MAX_SEGMENTS_PER_REQUEST];
-    struct usbback_info *usbif = usbback_req->usbif;
-    struct XenDevice *xendev = &usbif->xendev;
-    struct usbif_request_segment *seg;
-    void *addr;
-
-    nr_segs = usbback_req->nr_buffer_segs + usbback_req->nr_extra_segs;
-    if (!nr_segs) {
-        return 0;
-    }
-
-    if (nr_segs > USBIF_MAX_SEGMENTS_PER_REQUEST) {
-        xen_be_printf(xendev, 0, "bad number of segments in request (%d)\n",
-                      nr_segs);
-        return -EINVAL;
-    }
-
-    for (i = 0; i < nr_segs; i++) {
-        if ((unsigned)usbback_req->req.seg[i].offset +
-            (unsigned)usbback_req->req.seg[i].length > PAGE_SIZE) {
-            xen_be_printf(xendev, 0, "segment crosses page boundary\n");
-            return -EINVAL;
-        }
-    }
-
-    if (usbback_req->nr_buffer_segs) {
-        prot = PROT_READ;
-        if (usbif_pipein(usbback_req->req.pipe)) {
-                prot |= PROT_WRITE;
-        }
-        for (i = 0; i < usbback_req->nr_buffer_segs; i++) {
-            ref[i] = usbback_req->req.seg[i].gref;
-        }
-        usbback_req->buffer = xengnttab_map_domain_grant_refs(xendev->gnttabdev,
-            usbback_req->nr_buffer_segs, xendev->dom, ref, prot);
-
-        if (!usbback_req->buffer) {
-            return -ENOMEM;
-        }
-
-        for (i = 0; i < usbback_req->nr_buffer_segs; i++) {
-            seg = usbback_req->req.seg + i;
-            addr = usbback_req->buffer + i * PAGE_SIZE + seg->offset;
-            qemu_iovec_add(&usbback_req->packet.iov, addr, seg->length);
-        }
-    }
-
-    if (!usbif_pipeisoc(usbback_req->req.pipe)) {
-        return 0;
-    }
-
-    /*
-     * Right now isoc requests are not supported.
-     * Prepare supporting those by doing the work needed on the guest
-     * interface side.
-     */
-
-    if (!usbback_req->nr_extra_segs) {
-        xen_be_printf(xendev, 0, "iso request without descriptor segments\n");
-        return -EINVAL;
-    }
-
-    prot = PROT_READ | PROT_WRITE;
-    for (i = 0; i < usbback_req->nr_extra_segs; i++) {
-        ref[i] = usbback_req->req.seg[i + usbback_req->req.nr_buffer_segs].gref;
-    }
-    usbback_req->isoc_buffer = xengnttab_map_domain_grant_refs(
-         xendev->gnttabdev, usbback_req->nr_extra_segs, xendev->dom, ref, prot);
-
-    if (!usbback_req->isoc_buffer) {
-        return -ENOMEM;
-    }
-
-    return 0;
-}
-
-static int usbback_init_packet(struct usbback_req *usbback_req)
-{
-    struct XenDevice *xendev = &usbback_req->usbif->xendev;
-    USBPacket *packet = &usbback_req->packet;
-    USBDevice *dev = usbback_req->stub->dev;
-    USBEndpoint *ep;
-    unsigned int pid, ep_nr;
-    bool sok;
-    int ret = 0;
-
-    qemu_iovec_init(&packet->iov, USBIF_MAX_SEGMENTS_PER_REQUEST);
-    pid = usbif_pipein(usbback_req->req.pipe) ? USB_TOKEN_IN : USB_TOKEN_OUT;
-    ep_nr = usbif_pipeendpoint(usbback_req->req.pipe);
-    sok = !!(usbback_req->req.transfer_flags & USBIF_SHORT_NOT_OK);
-    if (usbif_pipectrl(usbback_req->req.pipe)) {
-        ep_nr = 0;
-        sok = false;
-    }
-    ep = usb_ep_get(dev, pid, ep_nr);
-    usb_packet_setup(packet, pid, ep, 0, 1, sok, true);
-
-    switch (usbif_pipetype(usbback_req->req.pipe)) {
-    case USBIF_PIPE_TYPE_ISOC:
-        TR_REQ(xendev, "iso transfer %s: buflen: %x, %d frames\n",
-               (pid == USB_TOKEN_IN) ? "in" : "out",
-               usbback_req->req.buffer_length,
-               usbback_req->req.u.isoc.nr_frame_desc_segs);
-        ret = -EINVAL;  /* isoc not implemented yet */
-        break;
-
-    case USBIF_PIPE_TYPE_INT:
-        TR_REQ(xendev, "int transfer %s: buflen: %x\n",
-               (pid == USB_TOKEN_IN) ? "in" : "out",
-               usbback_req->req.buffer_length);
-        break;
-
-    case USBIF_PIPE_TYPE_CTRL:
-        packet->parameter = *(uint64_t *)usbback_req->req.u.ctrl;
-        TR_REQ(xendev, "ctrl parameter: %"PRIx64", buflen: %x\n",
-               packet->parameter,
-               usbback_req->req.buffer_length);
-        break;
-
-    case USBIF_PIPE_TYPE_BULK:
-        TR_REQ(xendev, "bulk transfer %s: buflen: %x\n",
-               (pid == USB_TOKEN_IN) ? "in" : "out",
-               usbback_req->req.buffer_length);
-        break;
-    default:
-        ret = -EINVAL;
-        break;
-    }
-
-    return ret;
-}
-
-static void usbback_do_response(struct usbback_req *usbback_req, int32_t status,
-                                int32_t actual_length, int32_t error_count)
-{
-    struct usbback_info *usbif;
-    struct usbif_urb_response *res;
-    struct XenDevice *xendev;
-    unsigned int notify;
-
-    usbif = usbback_req->usbif;
-    xendev = &usbif->xendev;
-
-    TR_REQ(xendev, "id %d, status %d, length %d, errcnt %d\n",
-           usbback_req->req.id, status, actual_length, error_count);
-
-    if (usbback_req->packet.iov.iov) {
-        qemu_iovec_destroy(&usbback_req->packet.iov);
-    }
-
-    if (usbback_req->buffer) {
-        xengnttab_unmap(xendev->gnttabdev, usbback_req->buffer,
-                        usbback_req->nr_buffer_segs);
-        usbback_req->buffer = NULL;
-    }
-
-    if (usbback_req->isoc_buffer) {
-        xengnttab_unmap(xendev->gnttabdev, usbback_req->isoc_buffer,
-                        usbback_req->nr_extra_segs);
-        usbback_req->isoc_buffer = NULL;
-    }
-
-    if (usbif->urb_sring) {
-        res = RING_GET_RESPONSE(&usbif->urb_ring, usbif->urb_ring.rsp_prod_pvt);
-        res->id = usbback_req->req.id;
-        res->status = status;
-        res->actual_length = actual_length;
-        res->error_count = error_count;
-        res->start_frame = 0;
-        usbif->urb_ring.rsp_prod_pvt++;
-        RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&usbif->urb_ring, notify);
-
-        if (notify) {
-            xen_be_send_notify(xendev);
-        }
-    }
-
-    if (!usbback_req->cancelled)
-        usbback_put_req(usbback_req);
-}
-
-static void usbback_do_response_ret(struct usbback_req *usbback_req,
-                                    int32_t status)
-{
-    usbback_do_response(usbback_req, status, 0, 0);
-}
-
-static int32_t usbback_xlat_status(int status)
-{
-    switch (status) {
-    case USB_RET_SUCCESS:
-        return 0;
-    case USB_RET_NODEV:
-        return -ENODEV;
-    case USB_RET_STALL:
-        return -EPIPE;
-    case USB_RET_BABBLE:
-        return -EOVERFLOW;
-    case USB_RET_IOERROR:
-        return -EPROTO;
-    }
-
-    return -ESHUTDOWN;
-}
-
-static void usbback_packet_complete(USBPacket *packet)
-{
-    struct usbback_req *usbback_req;
-    int32_t status;
-
-    usbback_req = container_of(packet, struct usbback_req, packet);
-
-    QTAILQ_REMOVE(&usbback_req->stub->submit_q, usbback_req, q);
-
-    status = usbback_xlat_status(packet->status);
-    usbback_do_response(usbback_req, status, packet->actual_length, 0);
-}
-
-static void usbback_set_address(struct usbback_info *usbif,
-                                struct usbback_stub *stub,
-                                unsigned int cur_addr, unsigned int new_addr)
-{
-    if (cur_addr) {
-        usbif->addr_table[cur_addr] = NULL;
-    }
-    if (new_addr) {
-        usbif->addr_table[new_addr] = stub;
-    }
-}
-
-static void usbback_cancel_req(struct usbback_req *usbback_req)
-{
-    if (usb_packet_is_inflight(&usbback_req->packet)) {
-        usb_cancel_packet(&usbback_req->packet);
-        QTAILQ_REMOVE(&usbback_req->stub->submit_q, usbback_req, q);
-        usbback_req->cancelled = true;
-        usbback_do_response_ret(usbback_req, -EPROTO);
-    }
-}
-
-static void usbback_process_unlink_req(struct usbback_req *usbback_req)
-{
-    struct usbback_info *usbif;
-    struct usbback_req *unlink_req;
-    unsigned int id, devnum;
-    int ret;
-
-    usbif = usbback_req->usbif;
-    ret = 0;
-    id = usbback_req->req.u.unlink.unlink_id;
-    TR_REQ(&usbif->xendev, "unlink id %d\n", id);
-    devnum = usbif_pipedevice(usbback_req->req.pipe);
-    if (unlikely(devnum == 0)) {
-        usbback_req->stub = usbif->ports +
-                            usbif_pipeportnum(usbback_req->req.pipe) - 1;
-        if (unlikely(!usbback_req->stub)) {
-            ret = -ENODEV;
-            goto fail_response;
-        }
-    } else {
-        if (unlikely(!usbif->addr_table[devnum])) {
-            ret = -ENODEV;
-            goto fail_response;
-        }
-        usbback_req->stub = usbif->addr_table[devnum];
-    }
-
-    QTAILQ_FOREACH(unlink_req, &usbback_req->stub->submit_q, q) {
-        if (unlink_req->req.id == id) {
-            usbback_cancel_req(unlink_req);
-            break;
-        }
-    }
-
-fail_response:
-    usbback_do_response_ret(usbback_req, ret);
-}
-
-/*
- * Checks whether a request can be handled at once or should be forwarded
- * to the usb framework.
- * Return value is:
- * 0 in case of usb framework is needed
- * 1 in case of local handling (no error)
- * The request response has been queued already if return value not 0.
- */
-static int usbback_check_and_submit(struct usbback_req *usbback_req)
-{
-    struct usbback_info *usbif;
-    unsigned int devnum;
-    struct usbback_stub *stub;
-    struct usbif_ctrlrequest *ctrl;
-    int ret;
-    uint16_t wValue;
-
-    usbif = usbback_req->usbif;
-    stub = NULL;
-    devnum = usbif_pipedevice(usbback_req->req.pipe);
-    ctrl = (struct usbif_ctrlrequest *)usbback_req->req.u.ctrl;
-    wValue = le16_to_cpu(ctrl->wValue);
-
-    /*
-     * When the device is first connected or resetted, USB device has no
-     * address. In this initial state, following requests are sent to device
-     * address (#0),
-     *
-     *  1. GET_DESCRIPTOR (with Descriptor Type is "DEVICE") is sent,
-     *     and OS knows what device is connected to.
-     *
-     *  2. SET_ADDRESS is sent, and then device has its address.
-     *
-     * In the next step, SET_CONFIGURATION is sent to addressed device, and
-     * then the device is finally ready to use.
-     */
-    if (unlikely(devnum == 0)) {
-        stub = usbif->ports + usbif_pipeportnum(usbback_req->req.pipe) - 1;
-        if (!stub->dev || !stub->attached) {
-            ret = -ENODEV;
-            goto do_response;
-        }
-
-        switch (ctrl->bRequest) {
-        case USB_REQ_GET_DESCRIPTOR:
-            /*
-             * GET_DESCRIPTOR request to device #0.
-             * through normal transfer.
-             */
-            TR_REQ(&usbif->xendev, "devnum 0 GET_DESCRIPTOR\n");
-            usbback_req->stub = stub;
-            return 0;
-        case USB_REQ_SET_ADDRESS:
-            /*
-             * SET_ADDRESS request to device #0.
-             * add attached device to addr_table.
-             */
-            TR_REQ(&usbif->xendev, "devnum 0 SET_ADDRESS\n");
-            usbback_set_address(usbif, stub, 0, wValue);
-            ret = 0;
-            break;
-        default:
-            ret = -EINVAL;
-            break;
-        }
-        goto do_response;
-    }
-
-    if (unlikely(!usbif->addr_table[devnum])) {
-            ret = -ENODEV;
-            goto do_response;
-    }
-    usbback_req->stub = usbif->addr_table[devnum];
-
-    /*
-     * Check special request
-     */
-    if (ctrl->bRequest != USB_REQ_SET_ADDRESS) {
-        return 0;
-    }
-
-    /*
-     * SET_ADDRESS request to addressed device.
-     * change addr or remove from addr_table.
-     */
-    usbback_set_address(usbif, usbback_req->stub, devnum, wValue);
-    ret = 0;
-
-do_response:
-    usbback_do_response_ret(usbback_req, ret);
-    return 1;
-}
-
-static void usbback_dispatch(struct usbback_req *usbback_req)
-{
-    int ret;
-    unsigned int devnum;
-    struct usbback_info *usbif;
-
-    usbif = usbback_req->usbif;
-
-    TR_REQ(&usbif->xendev, "start req_id %d pipe %08x\n", usbback_req->req.id,
-           usbback_req->req.pipe);
-
-    /* unlink request */
-    if (unlikely(usbif_pipeunlink(usbback_req->req.pipe))) {
-        usbback_process_unlink_req(usbback_req);
-        return;
-    }
-
-    if (usbif_pipectrl(usbback_req->req.pipe)) {
-        if (usbback_check_and_submit(usbback_req)) {
-            return;
-        }
-    } else {
-        devnum = usbif_pipedevice(usbback_req->req.pipe);
-        usbback_req->stub = usbif->addr_table[devnum];
-
-        if (!usbback_req->stub || !usbback_req->stub->attached) {
-            ret = -ENODEV;
-            goto fail_response;
-        }
-    }
-
-    QTAILQ_INSERT_TAIL(&usbback_req->stub->submit_q, usbback_req, q);
-
-    usbback_req->nr_buffer_segs = usbback_req->req.nr_buffer_segs;
-    usbback_req->nr_extra_segs = usbif_pipeisoc(usbback_req->req.pipe) ?
-                                 usbback_req->req.u.isoc.nr_frame_desc_segs : 0;
-
-    ret = usbback_init_packet(usbback_req);
-    if (ret) {
-        xen_be_printf(&usbif->xendev, 0, "invalid request\n");
-        ret = -ESHUTDOWN;
-        goto fail_free_urb;
-    }
-
-    ret = usbback_gnttab_map(usbback_req);
-    if (ret) {
-        xen_be_printf(&usbif->xendev, 0, "invalid buffer, ret=%d\n", ret);
-        ret = -ESHUTDOWN;
-        goto fail_free_urb;
-    }
-
-    usb_handle_packet(usbback_req->stub->dev, &usbback_req->packet);
-    if (usbback_req->packet.status != USB_RET_ASYNC) {
-        usbback_packet_complete(&usbback_req->packet);
-    }
-    return;
-
-fail_free_urb:
-    QTAILQ_REMOVE(&usbback_req->stub->submit_q, usbback_req, q);
-
-fail_response:
-    usbback_do_response_ret(usbback_req, ret);
-}
-
-static void usbback_hotplug_notify(struct usbback_info *usbif)
-{
-    struct usbif_conn_back_ring *ring = &usbif->conn_ring;
-    struct usbif_conn_request req;
-    struct usbif_conn_response *res;
-    struct usbback_hotplug *usb_hp;
-    unsigned int notify;
-
-    if (!usbif->conn_sring) {
-        return;
-    }
-
-    /* Check for full ring. */
-    if ((RING_SIZE(ring) - ring->rsp_prod_pvt - ring->req_cons) == 0) {
-        xen_be_send_notify(&usbif->xendev);
-        return;
-    }
-
-    usb_hp = QSIMPLEQ_FIRST(&usbif->hotplug_q);
-    QSIMPLEQ_REMOVE_HEAD(&usbif->hotplug_q, q);
-
-    RING_COPY_REQUEST(ring, ring->req_cons, &req);
-    ring->req_cons++;
-    ring->sring->req_event = ring->req_cons + 1;
-
-    res = RING_GET_RESPONSE(ring, ring->rsp_prod_pvt);
-    res->id = req.id;
-    res->portnum = usb_hp->port;
-    res->speed = usbif->ports[usb_hp->port - 1].speed;
-    ring->rsp_prod_pvt++;
-    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(ring, notify);
-
-    if (notify) {
-        xen_be_send_notify(&usbif->xendev);
-    }
-
-    TR_BUS(&usbif->xendev, "hotplug port %d speed %d\n", usb_hp->port,
-           res->speed);
-
-    g_free(usb_hp);
-
-    if (!QSIMPLEQ_EMPTY(&usbif->hotplug_q)) {
-        qemu_bh_schedule(usbif->bh);
-    }
-}
-
-static void usbback_bh(void *opaque)
-{
-    struct usbback_info *usbif;
-    struct usbif_urb_back_ring *urb_ring;
-    struct usbback_req *usbback_req;
-    RING_IDX rc, rp;
-    unsigned int more_to_do;
-
-    usbif = opaque;
-    if (usbif->ring_error) {
-        return;
-    }
-
-    if (!QSIMPLEQ_EMPTY(&usbif->hotplug_q)) {
-        usbback_hotplug_notify(usbif);
-    }
-
-    urb_ring = &usbif->urb_ring;
-    rc = urb_ring->req_cons;
-    rp = urb_ring->sring->req_prod;
-    xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
-
-    if (RING_REQUEST_PROD_OVERFLOW(urb_ring, rp)) {
-        rc = urb_ring->rsp_prod_pvt;
-        xen_be_printf(&usbif->xendev, 0, "domU provided bogus ring requests "
-                      "(%#x - %#x = %u). Halting ring processing.\n",
-                      rp, rc, rp - rc);
-        usbif->ring_error = true;
-        return;
-    }
-
-    while (rc != rp) {
-        if (RING_REQUEST_CONS_OVERFLOW(urb_ring, rc)) {
-            break;
-        }
-        usbback_req = usbback_get_req(usbif);
-
-        RING_COPY_REQUEST(urb_ring, rc, &usbback_req->req);
-        usbback_req->usbif = usbif;
-
-        usbback_dispatch(usbback_req);
-
-        urb_ring->req_cons = ++rc;
-    }
-
-    RING_FINAL_CHECK_FOR_REQUESTS(urb_ring, more_to_do);
-    if (more_to_do) {
-        qemu_bh_schedule(usbif->bh);
-    }
-}
-
-static void usbback_hotplug_enq(struct usbback_info *usbif, unsigned port)
-{
-    struct usbback_hotplug *usb_hp;
-
-    usb_hp = g_new0(struct usbback_hotplug, 1);
-    usb_hp->port = port;
-    QSIMPLEQ_INSERT_TAIL(&usbif->hotplug_q, usb_hp, q);
-    usbback_hotplug_notify(usbif);
-}
-
-static void usbback_portid_drain(struct usbback_info *usbif, unsigned port)
-{
-    struct usbback_req *req, *tmp;
-    bool sched = false;
-
-    QTAILQ_FOREACH_SAFE(req, &usbif->ports[port - 1].submit_q, q, tmp) {
-        usbback_cancel_req(req);
-        sched = true;
-    }
-
-    if (sched) {
-        qemu_bh_schedule(usbif->bh);
-    }
-}
-
-static void usbback_portid_detach(struct usbback_info *usbif, unsigned port)
-{
-    if (!usbif->ports[port - 1].attached) {
-        return;
-    }
-
-    usbif->ports[port - 1].speed = USBIF_SPEED_NONE;
-    usbif->ports[port - 1].attached = false;
-    usbback_portid_drain(usbif, port);
-    usbback_hotplug_enq(usbif, port);
-}
-
-static void usbback_portid_remove(struct usbback_info *usbif, unsigned port)
-{
-    USBPort *p;
-
-    if (!usbif->ports[port - 1].dev) {
-        return;
-    }
-
-    p = &(usbif->ports[port - 1].port);
-    snprintf(p->path, sizeof(p->path), "%d", 99);
-
-    object_unparent(OBJECT(usbif->ports[port - 1].dev));
-    usbif->ports[port - 1].dev = NULL;
-    usbback_portid_detach(usbif, port);
-
-    TR_BUS(&usbif->xendev, "port %d removed\n", port);
-}
-
-static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
-                               char *busid)
-{
-    unsigned speed;
-    char *portname;
-    USBPort *p;
-    Error *local_err = NULL;
-    QDict *qdict;
-    QemuOpts *opts;
-
-    if (usbif->ports[port - 1].dev) {
-        return;
-    }
-
-    portname = strchr(busid, '-');
-    if (!portname) {
-        xen_be_printf(&usbif->xendev, 0, "device %s illegal specification\n",
-                      busid);
-        return;
-    }
-    portname++;
-    p = &(usbif->ports[port - 1].port);
-    snprintf(p->path, sizeof(p->path), "%s", portname);
-
-    qdict = qdict_new();
-    qdict_put(qdict, "driver", qstring_from_str("usb-host"));
-    qdict_put(qdict, "hostbus", qint_from_int(atoi(busid)));
-    qdict_put(qdict, "hostport", qstring_from_str(portname));
-    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
-    if (local_err) {
-        goto err;
-    }
-    usbif->ports[port - 1].dev = USB_DEVICE(qdev_device_add(opts, &local_err));
-    if (!usbif->ports[port - 1].dev) {
-        goto err;
-    }
-    QDECREF(qdict);
-    snprintf(p->path, sizeof(p->path), "%d", port);
-    speed = usbif->ports[port - 1].dev->speed;
-    switch (speed) {
-    case USB_SPEED_LOW:
-        speed = USBIF_SPEED_LOW;
-        break;
-    case USB_SPEED_FULL:
-        speed = USBIF_SPEED_FULL;
-        break;
-    case USB_SPEED_HIGH:
-        speed = (usbif->usb_ver < USB_VER_USB20) ?
-                USBIF_SPEED_NONE : USBIF_SPEED_HIGH;
-        break;
-    default:
-        speed = USBIF_SPEED_NONE;
-        break;
-    }
-    if (speed == USBIF_SPEED_NONE) {
-        xen_be_printf(&usbif->xendev, 0, "device %s wrong speed\n", busid);
-        object_unparent(OBJECT(usbif->ports[port - 1].dev));
-        usbif->ports[port - 1].dev = NULL;
-        return;
-    }
-    usb_device_reset(usbif->ports[port - 1].dev);
-    usbif->ports[port - 1].speed = speed;
-    usbif->ports[port - 1].attached = true;
-    QTAILQ_INIT(&usbif->ports[port - 1].submit_q);
-    usbback_hotplug_enq(usbif, port);
-
-    TR_BUS(&usbif->xendev, "port %d attached\n", port);
-    return;
-
-err:
-    QDECREF(qdict);
-    snprintf(p->path, sizeof(p->path), "%d", 99);
-    xen_be_printf(&usbif->xendev, 0, "device %s could not be opened\n", busid);
-}
-
-static void usbback_process_port(struct usbback_info *usbif, unsigned port)
-{
-    char node[8];
-    char *busid;
-
-    snprintf(node, sizeof(node), "port/%d", port);
-    busid = xenstore_read_be_str(&usbif->xendev, node);
-    if (busid == NULL) {
-        xen_be_printf(&usbif->xendev, 0, "xenstore_read %s failed\n", node);
-        return;
-    }
-
-    /* Remove portid, if the port is not connected.  */
-    if (strlen(busid) == 0) {
-        usbback_portid_remove(usbif, port);
-    } else {
-        usbback_portid_add(usbif, port, busid);
-    }
-
-    g_free(busid);
-}
-
-static void usbback_disconnect(struct XenDevice *xendev)
-{
-    struct usbback_info *usbif;
-    unsigned int i;
-
-    TR_BUS(xendev, "start\n");
-
-    usbif = container_of(xendev, struct usbback_info, xendev);
-
-    xen_be_unbind_evtchn(xendev);
-
-    if (usbif->urb_sring) {
-        xengnttab_unmap(xendev->gnttabdev, usbif->urb_sring, 1);
-        usbif->urb_sring = NULL;
-    }
-    if (usbif->conn_sring) {
-        xengnttab_unmap(xendev->gnttabdev, usbif->conn_sring, 1);
-        usbif->conn_sring = NULL;
-    }
-
-    for (i = 0; i < usbif->num_ports; i++) {
-        if (usbif->ports[i].dev) {
-            usbback_portid_drain(usbif, i + 1);
-        }
-    }
-
-    TR_BUS(xendev, "finished\n");
-}
-
-static int usbback_connect(struct XenDevice *xendev)
-{
-    struct usbback_info *usbif;
-    struct usbif_urb_sring *urb_sring;
-    struct usbif_conn_sring *conn_sring;
-    int urb_ring_ref;
-    int conn_ring_ref;
-    unsigned int i;
-
-    TR_BUS(xendev, "start\n");
-
-    usbif = container_of(xendev, struct usbback_info, xendev);
-
-    if (xenstore_read_fe_int(xendev, "urb-ring-ref", &urb_ring_ref)) {
-        xen_be_printf(xendev, 0, "error reading urb-ring-ref\n");
-        return -1;
-    }
-    if (xenstore_read_fe_int(xendev, "conn-ring-ref", &conn_ring_ref)) {
-        xen_be_printf(xendev, 0, "error reading conn-ring-ref\n");
-        return -1;
-    }
-    if (xenstore_read_fe_int(xendev, "event-channel", &xendev->remote_port)) {
-        xen_be_printf(xendev, 0, "error reading event-channel\n");
-        return -1;
-    }
-
-    usbif->urb_sring = xengnttab_map_grant_ref(xendev->gnttabdev, xendev->dom,
-                                               urb_ring_ref,
-                                               PROT_READ | PROT_WRITE);
-    usbif->conn_sring = xengnttab_map_grant_ref(xendev->gnttabdev, xendev->dom,
-                                                conn_ring_ref,
-                                                PROT_READ | PROT_WRITE);
-    if (!usbif->urb_sring || !usbif->conn_sring) {
-        xen_be_printf(xendev, 0, "error mapping rings\n");
-        usbback_disconnect(xendev);
-        return -1;
-    }
-
-    urb_sring = usbif->urb_sring;
-    conn_sring = usbif->conn_sring;
-    BACK_RING_INIT(&usbif->urb_ring, urb_sring, XC_PAGE_SIZE);
-    BACK_RING_INIT(&usbif->conn_ring, conn_sring, XC_PAGE_SIZE);
-
-    xen_be_bind_evtchn(xendev);
-
-    xen_be_printf(xendev, 1, "urb-ring-ref %d, conn-ring-ref %d, "
-                  "remote port %d, local port %d\n", urb_ring_ref,
-                  conn_ring_ref, xendev->remote_port, xendev->local_port);
-
-    for (i = 1; i <= usbif->num_ports; i++) {
-        if (usbif->ports[i - 1].dev) {
-            usbback_hotplug_enq(usbif, i);
-        }
-    }
-
-    return 0;
-}
-
-static void usbback_backend_changed(struct XenDevice *xendev, const char *node)
-{
-    struct usbback_info *usbif;
-    unsigned int i;
-
-    TR_BUS(xendev, "path %s\n", node);
-
-    usbif = container_of(xendev, struct usbback_info, xendev);
-    for (i = 1; i <= usbif->num_ports; i++) {
-        usbback_process_port(usbif, i);
-    }
-}
-
-static int usbback_init(struct XenDevice *xendev)
-{
-    struct usbback_info *usbif;
-
-    TR_BUS(xendev, "start\n");
-
-    usbif = container_of(xendev, struct usbback_info, xendev);
-
-    if (xenstore_read_be_int(xendev, "num-ports", &usbif->num_ports) ||
-        usbif->num_ports < 1 || usbif->num_ports > USBBACK_MAXPORTS) {
-        xen_be_printf(xendev, 0, "num-ports not readable or out of bounds\n");
-        return -1;
-    }
-    if (xenstore_read_be_int(xendev, "usb-ver", &usbif->usb_ver) ||
-        (usbif->usb_ver != USB_VER_USB11 && usbif->usb_ver != USB_VER_USB20)) {
-        xen_be_printf(xendev, 0, "usb-ver not readable or out of bounds\n");
-        return -1;
-    }
-
-    usbback_backend_changed(xendev, "port");
-
-    TR_BUS(xendev, "finished\n");
-
-    return 0;
-}
-
-static void xen_bus_attach(USBPort *port)
-{
-    struct usbback_info *usbif;
-
-    usbif = port->opaque;
-    TR_BUS(&usbif->xendev, "\n");
-    usbif->ports[port->index].attached = true;
-    usbback_hotplug_enq(usbif, port->index + 1);
-}
-
-static void xen_bus_detach(USBPort *port)
-{
-    struct usbback_info *usbif;
-
-    usbif = port->opaque;
-    TR_BUS(&usbif->xendev, "\n");
-    usbback_portid_detach(usbif, port->index + 1);
-}
-
-static void xen_bus_child_detach(USBPort *port, USBDevice *child)
-{
-    struct usbback_info *usbif;
-
-    usbif = port->opaque;
-    TR_BUS(&usbif->xendev, "\n");
-}
-
-static void xen_bus_complete(USBPort *port, USBPacket *packet)
-{
-    struct usbback_req *usbback_req;
-    struct usbback_info *usbif;
-
-    usbback_req = container_of(packet, struct usbback_req, packet);
-    if (usbback_req->cancelled) {
-        g_free(usbback_req);
-        return;
-    }
-
-    usbif = usbback_req->usbif;
-    TR_REQ(&usbif->xendev, "\n");
-    usbback_packet_complete(packet);
-}
-
-static USBPortOps xen_usb_port_ops = {
-    .attach = xen_bus_attach,
-    .detach = xen_bus_detach,
-    .child_detach = xen_bus_child_detach,
-    .complete = xen_bus_complete,
-};
-
-static USBBusOps xen_usb_bus_ops = {
-};
-
-static void usbback_alloc(struct XenDevice *xendev)
-{
-    struct usbback_info *usbif;
-    USBPort *p;
-    unsigned int i, max_grants;
-
-    usbif = container_of(xendev, struct usbback_info, xendev);
-
-    usb_bus_new(&usbif->bus, sizeof(usbif->bus), &xen_usb_bus_ops, xen_sysdev);
-    for (i = 0; i < USBBACK_MAXPORTS; i++) {
-        p = &(usbif->ports[i].port);
-        usb_register_port(&usbif->bus, p, usbif, i, &xen_usb_port_ops,
-                          USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL |
-                          USB_SPEED_MASK_HIGH);
-        snprintf(p->path, sizeof(p->path), "%d", 99);
-    }
-
-    QTAILQ_INIT(&usbif->req_free_q);
-    QSIMPLEQ_INIT(&usbif->hotplug_q);
-    usbif->bh = qemu_bh_new(usbback_bh, usbif);
-
-    /* max_grants: for each request and for the rings (request and connect). */
-    max_grants = USBIF_MAX_SEGMENTS_PER_REQUEST * USB_URB_RING_SIZE + 2;
-    if (xengnttab_set_max_grants(xendev->gnttabdev, max_grants) < 0) {
-        xen_be_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n",
-                      strerror(errno));
-    }
-}
-
-static int usbback_free(struct XenDevice *xendev)
-{
-    struct usbback_info *usbif;
-    struct usbback_req *usbback_req;
-    struct usbback_hotplug *usb_hp;
-    unsigned int i;
-
-    TR_BUS(xendev, "start\n");
-
-    usbback_disconnect(xendev);
-    usbif = container_of(xendev, struct usbback_info, xendev);
-    for (i = 1; i <= usbif->num_ports; i++) {
-        usbback_portid_remove(usbif, i);
-    }
-
-    while (!QTAILQ_EMPTY(&usbif->req_free_q)) {
-        usbback_req = QTAILQ_FIRST(&usbif->req_free_q);
-        QTAILQ_REMOVE(&usbif->req_free_q, usbback_req, q);
-        g_free(usbback_req);
-    }
-    while (!QSIMPLEQ_EMPTY(&usbif->hotplug_q)) {
-        usb_hp = QSIMPLEQ_FIRST(&usbif->hotplug_q);
-        QSIMPLEQ_REMOVE_HEAD(&usbif->hotplug_q, q);
-        g_free(usb_hp);
-    }
-
-    qemu_bh_delete(usbif->bh);
-
-    for (i = 0; i < USBBACK_MAXPORTS; i++) {
-        usb_unregister_port(&usbif->bus, &(usbif->ports[i].port));
-    }
-
-    usb_bus_release(&usbif->bus);
-    object_unparent(OBJECT(&usbif->bus));
-
-    TR_BUS(xendev, "finished\n");
-
-    return 0;
-}
-
-static void usbback_event(struct XenDevice *xendev)
-{
-    struct usbback_info *usbif;
-
-    usbif = container_of(xendev, struct usbback_info, xendev);
-    qemu_bh_schedule(usbif->bh);
-}
-
-struct XenDevOps xen_usb_ops = {
-    .size            = sizeof(struct usbback_info),
-    .flags           = DEVOPS_FLAG_NEED_GNTDEV,
-    .init            = usbback_init,
-    .alloc           = usbback_alloc,
-    .free            = usbback_free,
-    .backend_changed = usbback_backend_changed,
-    .initialise      = usbback_connect,
-    .disconnect      = usbback_disconnect,
-    .event           = usbback_event,
-};
-
-#else /* USBIF_SHORT_NOT_OK */
-
-static int usbback_not_supported(void)
-{
-    return -EINVAL;
-}
-
-struct XenDevOps xen_usb_ops = {
-    .backend_register = usbback_not_supported,
-};
-
-#endif
index c25e32b..ceddbb8 100644 (file)
@@ -4,5 +4,4 @@ obj-$(CONFIG_PCI) += pci.o pci-quirks.o
 obj-$(CONFIG_SOFTMMU) += platform.o
 obj-$(CONFIG_SOFTMMU) += calxeda-xgmac.o
 obj-$(CONFIG_SOFTMMU) += amd-xgbe.o
-obj-$(CONFIG_SOFTMMU) += spapr.o
 endif
index b313e7c..e1927a5 100644 (file)
@@ -20,9 +20,7 @@
 
 #include "qemu/osdep.h"
 #include <sys/ioctl.h>
-#ifdef CONFIG_KVM
-#include <linux/kvm.h>
-#endif
+#include <sys/mman.h>
 #include <linux/vfio.h>
 
 #include "hw/vfio/vfio-common.h"
@@ -31,7 +29,6 @@
 #include "exec/memory.h"
 #include "hw/hw.h"
 #include "qemu/error-report.h"
-#include "qemu/range.h"
 #include "sysemu/kvm.h"
 #include "trace.h"
 
@@ -242,44 +239,6 @@ static int vfio_dma_map(VFIOContainer *container, hwaddr iova,
     return -errno;
 }
 
-static void vfio_host_win_add(VFIOContainer *container,
-                              hwaddr min_iova, hwaddr max_iova,
-                              uint64_t iova_pgsizes)
-{
-    VFIOHostDMAWindow *hostwin;
-
-    QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) {
-        if (ranges_overlap(hostwin->min_iova,
-                           hostwin->max_iova - hostwin->min_iova + 1,
-                           min_iova,
-                           max_iova - min_iova + 1)) {
-            hw_error("%s: Overlapped IOMMU are not enabled", __func__);
-        }
-    }
-
-    hostwin = g_malloc0(sizeof(*hostwin));
-
-    hostwin->min_iova = min_iova;
-    hostwin->max_iova = max_iova;
-    hostwin->iova_pgsizes = iova_pgsizes;
-    QLIST_INSERT_HEAD(&container->hostwin_list, hostwin, hostwin_next);
-}
-
-static int vfio_host_win_del(VFIOContainer *container, hwaddr min_iova,
-                             hwaddr max_iova)
-{
-    VFIOHostDMAWindow *hostwin;
-
-    QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) {
-        if (hostwin->min_iova == min_iova && hostwin->max_iova == max_iova) {
-            QLIST_REMOVE(hostwin, hostwin_next);
-            return 0;
-        }
-    }
-
-    return -1;
-}
-
 static bool vfio_listener_skipped_section(MemoryRegionSection *section)
 {
     return (!memory_region_is_ram(section->mr) &&
@@ -298,20 +257,14 @@ static void vfio_iommu_map_notify(Notifier *n, void *data)
     VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n);
     VFIOContainer *container = giommu->container;
     IOMMUTLBEntry *iotlb = data;
-    hwaddr iova = iotlb->iova + giommu->iommu_offset;
     MemoryRegion *mr;
     hwaddr xlat;
     hwaddr len = iotlb->addr_mask + 1;
     void *vaddr;
     int ret;
 
-    trace_vfio_iommu_map_notify(iova, iova + iotlb->addr_mask);
-
-    if (iotlb->target_as != &address_space_memory) {
-        error_report("Wrong target AS \"%s\", only system memory is allowed",
-                     iotlb->target_as->name ? iotlb->target_as->name : "none");
-        return;
-    }
+    trace_vfio_iommu_map_notify(iotlb->iova,
+                                iotlb->iova + iotlb->addr_mask);
 
     /*
      * The IOMMU TLB entry we have just covers translation through
@@ -338,21 +291,21 @@ static void vfio_iommu_map_notify(Notifier *n, void *data)
 
     if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
         vaddr = memory_region_get_ram_ptr(mr) + xlat;
-        ret = vfio_dma_map(container, iova,
+        ret = vfio_dma_map(container, iotlb->iova,
                            iotlb->addr_mask + 1, vaddr,
                            !(iotlb->perm & IOMMU_WO) || mr->readonly);
         if (ret) {
             error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", "
                          "0x%"HWADDR_PRIx", %p) = %d (%m)",
-                         container, iova,
+                         container, iotlb->iova,
                          iotlb->addr_mask + 1, vaddr, ret);
         }
     } else {
-        ret = vfio_dma_unmap(container, iova, iotlb->addr_mask + 1);
+        ret = vfio_dma_unmap(container, iotlb->iova, iotlb->addr_mask + 1);
         if (ret) {
             error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", "
                          "0x%"HWADDR_PRIx") = %d (%m)",
-                         container, iova,
+                         container, iotlb->iova,
                          iotlb->addr_mask + 1, ret);
         }
     }
@@ -360,6 +313,11 @@ out:
     rcu_read_unlock();
 }
 
+static hwaddr vfio_container_granularity(VFIOContainer *container)
+{
+    return (hwaddr)1 << ctz64(container->iova_pgsizes);
+}
+
 static void vfio_listener_region_add(MemoryListener *listener,
                                      MemoryRegionSection *section)
 {
@@ -368,8 +326,6 @@ static void vfio_listener_region_add(MemoryListener *listener,
     Int128 llend, llsize;
     void *vaddr;
     int ret;
-    VFIOHostDMAWindow *hostwin;
-    bool hostwin_found;
 
     if (vfio_listener_skipped_section(section)) {
         trace_vfio_listener_region_add_skip(
@@ -395,40 +351,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
     }
     end = int128_get64(int128_sub(llend, int128_one()));
 
-    if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) {
-        VFIOHostDMAWindow *hostwin;
-        hwaddr pgsize = 0;
-
-        /* For now intersections are not allowed, we may relax this later */
-        QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) {
-            if (ranges_overlap(hostwin->min_iova,
-                               hostwin->max_iova - hostwin->min_iova + 1,
-                               section->offset_within_address_space,
-                               int128_get64(section->size))) {
-                ret = -1;
-                goto fail;
-            }
-        }
-
-        ret = vfio_spapr_create_window(container, section, &pgsize);
-        if (ret) {
-            goto fail;
-        }
-
-        vfio_host_win_add(container, section->offset_within_address_space,
-                          section->offset_within_address_space +
-                          int128_get64(section->size) - 1, pgsize);
-    }
-
-    hostwin_found = false;
-    QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) {
-        if (hostwin->min_iova <= iova && end <= hostwin->max_iova) {
-            hostwin_found = true;
-            break;
-        }
-    }
-
-    if (!hostwin_found) {
+    if ((iova < container->min_iova) || (end > container->max_iova)) {
         error_report("vfio: IOMMU container %p can't map guest IOVA region"
                      " 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx,
                      container, iova, end);
@@ -443,6 +366,10 @@ static void vfio_listener_region_add(MemoryListener *listener,
 
         trace_vfio_listener_region_add_iommu(iova, end);
         /*
+         * FIXME: We should do some checking to see if the
+         * capabilities of the host VFIO IOMMU are adequate to model
+         * the guest IOMMU
+         *
          * FIXME: For VFIO iommu types which have KVM acceleration to
          * avoid bouncing all map/unmaps through qemu this way, this
          * would be the right place to wire that up (tell the KVM
@@ -450,14 +377,14 @@ static void vfio_listener_region_add(MemoryListener *listener,
          */
         giommu = g_malloc0(sizeof(*giommu));
         giommu->iommu = section->mr;
-        giommu->iommu_offset = section->offset_within_address_space -
-                               section->offset_within_region;
         giommu->container = container;
         giommu->n.notify = vfio_iommu_map_notify;
         QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next);
 
         memory_region_register_iommu_notifier(giommu->iommu, &giommu->n);
-        memory_region_iommu_replay(giommu->iommu, &giommu->n, false);
+        memory_region_iommu_replay(giommu->iommu, &giommu->n,
+                                   vfio_container_granularity(container),
+                                   false);
 
         return;
     }
@@ -503,7 +430,6 @@ static void vfio_listener_region_del(MemoryListener *listener,
 {
     VFIOContainer *container = container_of(listener, VFIOContainer, listener);
     hwaddr iova, end;
-    Int128 llend, llsize;
     int ret;
 
     if (vfio_listener_skipped_section(section)) {
@@ -525,8 +451,7 @@ static void vfio_listener_region_del(MemoryListener *listener,
 
         QLIST_FOREACH(giommu, &container->giommu_list, giommu_next) {
             if (giommu->iommu == section->mr) {
-                memory_region_unregister_iommu_notifier(giommu->iommu,
-                                                        &giommu->n);
+                memory_region_unregister_iommu_notifier(&giommu->n);
                 QLIST_REMOVE(giommu, giommu_next);
                 g_free(giommu);
                 break;
@@ -543,37 +468,21 @@ static void vfio_listener_region_del(MemoryListener *listener,
     }
 
     iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
-    llend = int128_make64(section->offset_within_address_space);
-    llend = int128_add(llend, section->size);
-    llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
+    end = (section->offset_within_address_space + int128_get64(section->size)) &
+          TARGET_PAGE_MASK;
 
-    if (int128_ge(int128_make64(iova), llend)) {
+    if (iova >= end) {
         return;
     }
-    end = int128_get64(int128_sub(llend, int128_one()));
-
-    llsize = int128_sub(llend, int128_make64(iova));
 
-    trace_vfio_listener_region_del(iova, end);
+    trace_vfio_listener_region_del(iova, end - 1);
 
-    ret = vfio_dma_unmap(container, iova, int128_get64(llsize));
+    ret = vfio_dma_unmap(container, iova, end - iova);
     memory_region_unref(section->mr);
     if (ret) {
         error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", "
                      "0x%"HWADDR_PRIx") = %d (%m)",
-                     container, iova, int128_get64(llsize), ret);
-    }
-
-    if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) {
-        vfio_spapr_remove_window(container,
-                                 section->offset_within_address_space);
-        if (vfio_host_win_del(container,
-                              section->offset_within_address_space,
-                              section->offset_within_address_space +
-                              int128_get64(section->size) - 1) < 0) {
-            hw_error("%s: Cannot delete missing window at %"HWADDR_PRIx,
-                     __func__, section->offset_within_address_space);
-        }
+                     container, iova, end - iova, ret);
     }
 }
 
@@ -585,57 +494,6 @@ static const MemoryListener vfio_memory_listener = {
 static void vfio_listener_release(VFIOContainer *container)
 {
     memory_listener_unregister(&container->listener);
-    if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) {
-        memory_listener_unregister(&container->prereg_listener);
-    }
-}
-
-static struct vfio_info_cap_header *
-vfio_get_region_info_cap(struct vfio_region_info *info, uint16_t id)
-{
-    struct vfio_info_cap_header *hdr;
-    void *ptr = info;
-
-    if (!(info->flags & VFIO_REGION_INFO_FLAG_CAPS)) {
-        return NULL;
-    }
-
-    for (hdr = ptr + info->cap_offset; hdr != ptr; hdr = ptr + hdr->next) {
-        if (hdr->id == id) {
-            return hdr;
-        }
-    }
-
-    return NULL;
-}
-
-static void vfio_setup_region_sparse_mmaps(VFIORegion *region,
-                                           struct vfio_region_info *info)
-{
-    struct vfio_info_cap_header *hdr;
-    struct vfio_region_info_cap_sparse_mmap *sparse;
-    int i;
-
-    hdr = vfio_get_region_info_cap(info, VFIO_REGION_INFO_CAP_SPARSE_MMAP);
-    if (!hdr) {
-        return;
-    }
-
-    sparse = container_of(hdr, struct vfio_region_info_cap_sparse_mmap, header);
-
-    trace_vfio_region_sparse_mmap_header(region->vbasedev->name,
-                                         region->nr, sparse->nr_areas);
-
-    region->nr_mmaps = sparse->nr_areas;
-    region->mmaps = g_new0(VFIOMmap, region->nr_mmaps);
-
-    for (i = 0; i < region->nr_mmaps; i++) {
-        region->mmaps[i].offset = sparse->areas[i].offset;
-        region->mmaps[i].size = sparse->areas[i].size;
-        trace_vfio_region_sparse_mmap_entry(i, region->mmaps[i].offset,
-                                            region->mmaps[i].offset +
-                                            region->mmaps[i].size);
-    }
 }
 
 int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region,
@@ -664,14 +522,11 @@ int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region,
             region->flags & VFIO_REGION_INFO_FLAG_MMAP &&
             !(region->size & ~qemu_real_host_page_mask)) {
 
-            vfio_setup_region_sparse_mmaps(region, info);
+            region->nr_mmaps = 1;
+            region->mmaps = g_new0(VFIOMmap, region->nr_mmaps);
 
-            if (!region->nr_mmaps) {
-                region->nr_mmaps = 1;
-                region->mmaps = g_new0(VFIOMmap, region->nr_mmaps);
-                region->mmaps[0].offset = 0;
-                region->mmaps[0].size = region->size;
-            }
+            region->mmaps[0].offset = 0;
+            region->mmaps[0].size = region->size;
         }
     }
 
@@ -946,8 +801,8 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
             goto free_container_exit;
         }
 
-        container->iommu_type = v2 ? VFIO_TYPE1v2_IOMMU : VFIO_TYPE1_IOMMU;
-        ret = ioctl(fd, VFIO_SET_IOMMU, container->iommu_type);
+        ret = ioctl(fd, VFIO_SET_IOMMU,
+                    v2 ? VFIO_TYPE1v2_IOMMU : VFIO_TYPE1_IOMMU);
         if (ret) {
             error_report("vfio: failed to set iommu for container: %m");
             ret = -errno;
@@ -961,18 +816,19 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
          * existing Type1 IOMMUs generally support any IOVA we're
          * going to actually try in practice.
          */
+        container->min_iova = 0;
+        container->max_iova = (hwaddr)-1;
+
+        /* Assume just 4K IOVA page size */
+        container->iova_pgsizes = 0x1000;
         info.argsz = sizeof(info);
         ret = ioctl(fd, VFIO_IOMMU_GET_INFO, &info);
         /* Ignore errors */
-        if (ret || !(info.flags & VFIO_IOMMU_INFO_PGSIZES)) {
-            /* Assume 4k IOVA page size */
-            info.iova_pgsizes = 4096;
+        if ((ret == 0) && (info.flags & VFIO_IOMMU_INFO_PGSIZES)) {
+            container->iova_pgsizes = info.iova_pgsizes;
         }
-        vfio_host_win_add(container, 0, (hwaddr)-1, info.iova_pgsizes);
-    } else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_IOMMU) ||
-               ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_v2_IOMMU)) {
+    } else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_IOMMU)) {
         struct vfio_iommu_spapr_tce_info info;
-        bool v2 = !!ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_v2_IOMMU);
 
         ret = ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &fd);
         if (ret) {
@@ -980,9 +836,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
             ret = -errno;
             goto free_container_exit;
         }
-        container->iommu_type =
-            v2 ? VFIO_SPAPR_TCE_v2_IOMMU : VFIO_SPAPR_TCE_IOMMU;
-        ret = ioctl(fd, VFIO_SET_IOMMU, container->iommu_type);
+        ret = ioctl(fd, VFIO_SET_IOMMU, VFIO_SPAPR_TCE_IOMMU);
         if (ret) {
             error_report("vfio: failed to set iommu for container: %m");
             ret = -errno;
@@ -994,54 +848,30 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
          * when container fd is closed so we do not call it explicitly
          * in this file.
          */
-        if (!v2) {
-            ret = ioctl(fd, VFIO_IOMMU_ENABLE);
-            if (ret) {
-                error_report("vfio: failed to enable container: %m");
-                ret = -errno;
-                goto free_container_exit;
-            }
-        } else {
-            container->prereg_listener = vfio_prereg_listener;
-
-            memory_listener_register(&container->prereg_listener,
-                                     &address_space_memory);
-            if (container->error) {
-                memory_listener_unregister(&container->prereg_listener);
-                error_report("vfio: RAM memory listener initialization failed for container");
-                goto free_container_exit;
-            }
+        ret = ioctl(fd, VFIO_IOMMU_ENABLE);
+        if (ret) {
+            error_report("vfio: failed to enable container: %m");
+            ret = -errno;
+            goto free_container_exit;
         }
 
+        /*
+         * This only considers the host IOMMU's 32-bit window.  At
+         * some point we need to add support for the optional 64-bit
+         * window and dynamic windows
+         */
         info.argsz = sizeof(info);
         ret = ioctl(fd, VFIO_IOMMU_SPAPR_TCE_GET_INFO, &info);
         if (ret) {
             error_report("vfio: VFIO_IOMMU_SPAPR_TCE_GET_INFO failed: %m");
             ret = -errno;
-            if (v2) {
-                memory_listener_unregister(&container->prereg_listener);
-            }
             goto free_container_exit;
         }
+        container->min_iova = info.dma32_window_start;
+        container->max_iova = container->min_iova + info.dma32_window_size - 1;
 
-        if (v2) {
-            /*
-             * There is a default window in just created container.
-             * To make region_add/del simpler, we better remove this
-             * window now and let those iommu_listener callbacks
-             * create/remove them when needed.
-             */
-            ret = vfio_spapr_remove_window(container, info.dma32_window_start);
-            if (ret) {
-                goto free_container_exit;
-            }
-        } else {
-            /* The default table uses 4K pages */
-            vfio_host_win_add(container, info.dma32_window_start,
-                              info.dma32_window_start +
-                              info.dma32_window_size - 1,
-                              0x1000);
-        }
+        /* Assume just 4K IOVA pages for now */
+        container->iova_pgsizes = 0x1000;
     } else {
         error_report("vfio: No available IOMMU models");
         ret = -EINVAL;
@@ -1102,7 +932,7 @@ static void vfio_disconnect_container(VFIOGroup *group)
         QLIST_REMOVE(container, next);
 
         QLIST_FOREACH_SAFE(giommu, &container->giommu_list, giommu_next, tmp) {
-            memory_region_unregister_iommu_notifier(giommu->iommu, &giommu->n);
+            memory_region_unregister_iommu_notifier(&giommu->n);
             QLIST_REMOVE(giommu, giommu_next);
             g_free(giommu);
         }
@@ -1256,60 +1086,16 @@ int vfio_get_region_info(VFIODevice *vbasedev, int index,
     *info = g_malloc0(argsz);
 
     (*info)->index = index;
-retry:
     (*info)->argsz = argsz;
 
     if (ioctl(vbasedev->fd, VFIO_DEVICE_GET_REGION_INFO, *info)) {
         g_free(*info);
-        *info = NULL;
         return -errno;
     }
 
-    if ((*info)->argsz > argsz) {
-        argsz = (*info)->argsz;
-        *info = g_realloc(*info, argsz);
-
-        goto retry;
-    }
-
     return 0;
 }
 
-int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type,
-                             uint32_t subtype, struct vfio_region_info **info)
-{
-    int i;
-
-    for (i = 0; i < vbasedev->num_regions; i++) {
-        struct vfio_info_cap_header *hdr;
-        struct vfio_region_info_cap_type *cap_type;
-
-        if (vfio_get_region_info(vbasedev, i, info)) {
-            continue;
-        }
-
-        hdr = vfio_get_region_info_cap(*info, VFIO_REGION_INFO_CAP_TYPE);
-        if (!hdr) {
-            g_free(*info);
-            continue;
-        }
-
-        cap_type = container_of(hdr, struct vfio_region_info_cap_type, header);
-
-        trace_vfio_get_dev_region(vbasedev->name, i,
-                                  cap_type->type, cap_type->subtype);
-
-        if (cap_type->type == type && cap_type->subtype == subtype) {
-            return 0;
-        }
-
-        g_free(*info);
-    }
-
-    *info = NULL;
-    return -ENODEV;
-}
-
 /*
  * Interfaces for IBM EEH (Enhanced Error Handling)
  */
index bec694c..6624905 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "qemu/error-report.h"
-#include "qemu/range.h"
-#include "qapi/error.h"
-#include "hw/nvram/fw_cfg.h"
 #include "pci.h"
 #include "trace.h"
+#include "qemu/range.h"
 
 /* Use uin32_t for vendor & device so PCI_ANY_ID expands and cannot match hw */
 static bool vfio_pci_is(VFIOPCIDevice *vdev, uint32_t vendor, uint32_t device)
@@ -965,643 +962,6 @@ static void vfio_probe_rtl8168_bar2_quirk(VFIOPCIDevice *vdev, int nr)
 }
 
 /*
- * Intel IGD support
- *
- * Obviously IGD is not a discrete device, this is evidenced not only by it
- * being integrated into the CPU, but by the various chipset and BIOS
- * dependencies that it brings along with it.  Intel is trying to move away
- * from this and Broadwell and newer devices can run in what Intel calls
- * "Universal Pass-Through" mode, or UPT.  Theoretically in UPT mode, nothing
- * more is required beyond assigning the IGD device to a VM.  There are
- * however support limitations to this mode.  It only supports IGD as a
- * secondary graphics device in the VM and it doesn't officially support any
- * physical outputs.
- *
- * The code here attempts to enable what we'll call legacy mode assignment,
- * IGD retains most of the capabilities we expect for it to have on bare
- * metal.  To enable this mode, the IGD device must be assigned to the VM
- * at PCI address 00:02.0, it must have a ROM, it very likely needs VGA
- * support, we must have VM BIOS support for reserving and populating some
- * of the required tables, and we need to tweak the chipset with revisions
- * and IDs and an LPC/ISA bridge device.  The intention is to make all of
- * this happen automatically by installing the device at the correct VM PCI
- * bus address.  If any of the conditions are not met, we cross our fingers
- * and hope the user knows better.
- *
- * NB - It is possible to enable physical outputs in UPT mode by supplying
- * an OpRegion table.  We don't do this by default because the guest driver
- * behaves differently if an OpRegion is provided and no monitor is attached
- * vs no OpRegion and a monitor being attached or not.  Effectively, if a
- * headless setup is desired, the OpRegion gets in the way of that.
- */
-
-/*
- * This presumes the device is already known to be an Intel VGA device, so we
- * take liberties in which device ID bits match which generation.  This should
- * not be taken as an indication that all the devices are supported, or even
- * supportable, some of them don't even support VT-d.
- * See linux:include/drm/i915_pciids.h for IDs.
- */
-static int igd_gen(VFIOPCIDevice *vdev)
-{
-    if ((vdev->device_id & 0xfff) == 0xa84) {
-        return 8; /* Broxton */
-    }
-
-    switch (vdev->device_id & 0xff00) {
-    /* Old, untested, unavailable, unknown */
-    case 0x0000:
-    case 0x2500:
-    case 0x2700:
-    case 0x2900:
-    case 0x2a00:
-    case 0x2e00:
-    case 0x3500:
-    case 0xa000:
-        return -1;
-    /* SandyBridge, IvyBridge, ValleyView, Haswell */
-    case 0x0100:
-    case 0x0400:
-    case 0x0a00:
-    case 0x0c00:
-    case 0x0d00:
-    case 0x0f00:
-        return 6;
-    /* BroadWell, CherryView, SkyLake, KabyLake */
-    case 0x1600:
-    case 0x1900:
-    case 0x2200:
-    case 0x5900:
-        return 8;
-    }
-
-    return 8; /* Assume newer is compatible */
-}
-
-typedef struct VFIOIGDQuirk {
-    struct VFIOPCIDevice *vdev;
-    uint32_t index;
-} VFIOIGDQuirk;
-
-#define IGD_GMCH 0x50 /* Graphics Control Register */
-#define IGD_BDSM 0x5c /* Base Data of Stolen Memory */
-#define IGD_ASLS 0xfc /* ASL Storage Register */
-
-/*
- * The OpRegion includes the Video BIOS Table, which seems important for
- * telling the driver what sort of outputs it has.  Without this, the device
- * may work in the guest, but we may not get output.  This also requires BIOS
- * support to reserve and populate a section of guest memory sufficient for
- * the table and to write the base address of that memory to the ASLS register
- * of the IGD device.
- */
-int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
-                               struct vfio_region_info *info)
-{
-    int ret;
-
-    vdev->igd_opregion = g_malloc0(info->size);
-    ret = pread(vdev->vbasedev.fd, vdev->igd_opregion,
-                info->size, info->offset);
-    if (ret != info->size) {
-        error_report("vfio: Error reading IGD OpRegion");
-        g_free(vdev->igd_opregion);
-        vdev->igd_opregion = NULL;
-        return -EINVAL;
-    }
-
-    /*
-     * Provide fw_cfg with a copy of the OpRegion which the VM firmware is to
-     * allocate 32bit reserved memory for, copy these contents into, and write
-     * the reserved memory base address to the device ASLS register at 0xFC.
-     * Alignment of this reserved region seems flexible, but using a 4k page
-     * alignment seems to work well.  This interface assumes a single IGD
-     * device, which may be at VM address 00:02.0 in legacy mode or another
-     * address in UPT mode.
-     *
-     * NB, there may be future use cases discovered where the VM should have
-     * direct interaction with the host OpRegion, in which case the write to
-     * the ASLS register would trigger MemoryRegion setup to enable that.
-     */
-    fw_cfg_add_file(fw_cfg_find(), "etc/igd-opregion",
-                    vdev->igd_opregion, info->size);
-
-    trace_vfio_pci_igd_opregion_enabled(vdev->vbasedev.name);
-
-    pci_set_long(vdev->pdev.config + IGD_ASLS, 0);
-    pci_set_long(vdev->pdev.wmask + IGD_ASLS, ~0);
-    pci_set_long(vdev->emulated_config_bits + IGD_ASLS, ~0);
-
-    return 0;
-}
-
-/*
- * The rather short list of registers that we copy from the host devices.
- * The LPC/ISA bridge values are definitely needed to support the vBIOS, the
- * host bridge values may or may not be needed depending on the guest OS.
- * Since we're only munging revision and subsystem values on the host bridge,
- * we don't require our own device.  The LPC/ISA bridge needs to be our very
- * own though.
- */
-typedef struct {
-    uint8_t offset;
-    uint8_t len;
-} IGDHostInfo;
-
-static const IGDHostInfo igd_host_bridge_infos[] = {
-    {PCI_REVISION_ID,         2},
-    {PCI_SUBSYSTEM_VENDOR_ID, 2},
-    {PCI_SUBSYSTEM_ID,        2},
-};
-
-static const IGDHostInfo igd_lpc_bridge_infos[] = {
-    {PCI_VENDOR_ID,           2},
-    {PCI_DEVICE_ID,           2},
-    {PCI_REVISION_ID,         2},
-    {PCI_SUBSYSTEM_VENDOR_ID, 2},
-    {PCI_SUBSYSTEM_ID,        2},
-};
-
-static int vfio_pci_igd_copy(VFIOPCIDevice *vdev, PCIDevice *pdev,
-                             struct vfio_region_info *info,
-                             const IGDHostInfo *list, int len)
-{
-    int i, ret;
-
-    for (i = 0; i < len; i++) {
-        ret = pread(vdev->vbasedev.fd, pdev->config + list[i].offset,
-                    list[i].len, info->offset + list[i].offset);
-        if (ret != list[i].len) {
-            error_report("IGD copy failed: %m");
-            return -errno;
-        }
-    }
-
-    return 0;
-}
-
-/*
- * Stuff a few values into the host bridge.
- */
-static int vfio_pci_igd_host_init(VFIOPCIDevice *vdev,
-                                  struct vfio_region_info *info)
-{
-    PCIBus *bus;
-    PCIDevice *host_bridge;
-    int ret;
-
-    bus = pci_device_root_bus(&vdev->pdev);
-    host_bridge = pci_find_device(bus, 0, PCI_DEVFN(0, 0));
-
-    if (!host_bridge) {
-        error_report("Can't find host bridge");
-        return -ENODEV;
-    }
-
-    ret = vfio_pci_igd_copy(vdev, host_bridge, info, igd_host_bridge_infos,
-                            ARRAY_SIZE(igd_host_bridge_infos));
-    if (!ret) {
-        trace_vfio_pci_igd_host_bridge_enabled(vdev->vbasedev.name);
-    }
-
-    return ret;
-}
-
-/*
- * IGD LPC/ISA bridge support code.  The vBIOS needs this, but we can't write
- * arbitrary values into just any bridge, so we must create our own.  We try
- * to handle if the user has created it for us, which they might want to do
- * to enable multifuction so we don't occupy the whole PCI slot.
- */
-static void vfio_pci_igd_lpc_bridge_realize(PCIDevice *pdev, Error **errp)
-{
-    if (pdev->devfn != PCI_DEVFN(0x1f, 0)) {
-        error_setg(errp, "VFIO dummy ISA/LPC bridge must have address 1f.0");
-    }
-}
-
-static void vfio_pci_igd_lpc_bridge_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    dc->desc = "VFIO dummy ISA/LPC bridge for IGD assignment";
-    dc->hotpluggable = false;
-    k->realize = vfio_pci_igd_lpc_bridge_realize;
-    k->class_id = PCI_CLASS_BRIDGE_ISA;
-}
-
-static TypeInfo vfio_pci_igd_lpc_bridge_info = {
-    .name = "vfio-pci-igd-lpc-bridge",
-    .parent = TYPE_PCI_DEVICE,
-    .class_init = vfio_pci_igd_lpc_bridge_class_init,
-};
-
-static void vfio_pci_igd_register_types(void)
-{
-    type_register_static(&vfio_pci_igd_lpc_bridge_info);
-}
-
-type_init(vfio_pci_igd_register_types)
-
-static int vfio_pci_igd_lpc_init(VFIOPCIDevice *vdev,
-                                 struct vfio_region_info *info)
-{
-    PCIDevice *lpc_bridge;
-    int ret;
-
-    lpc_bridge = pci_find_device(pci_device_root_bus(&vdev->pdev),
-                                 0, PCI_DEVFN(0x1f, 0));
-    if (!lpc_bridge) {
-        lpc_bridge = pci_create_simple(pci_device_root_bus(&vdev->pdev),
-                                 PCI_DEVFN(0x1f, 0), "vfio-pci-igd-lpc-bridge");
-    }
-
-    ret = vfio_pci_igd_copy(vdev, lpc_bridge, info, igd_lpc_bridge_infos,
-                            ARRAY_SIZE(igd_lpc_bridge_infos));
-    if (!ret) {
-        trace_vfio_pci_igd_lpc_bridge_enabled(vdev->vbasedev.name);
-    }
-
-    return ret;
-}
-
-/*
- * IGD Gen8 and newer support up to 8MB for the GTT and use a 64bit PTE
- * entry, older IGDs use 2MB and 32bit.  Each PTE maps a 4k page.  Therefore
- * we either have 2M/4k * 4 = 2k or 8M/4k * 8 = 16k as the maximum iobar index
- * for programming the GTT.
- *
- * See linux:include/drm/i915_drm.h for shift and mask values.
- */
-static int vfio_igd_gtt_max(VFIOPCIDevice *vdev)
-{
-    uint32_t gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, sizeof(gmch));
-    int ggms, gen = igd_gen(vdev);
-
-    gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, sizeof(gmch));
-    ggms = (gmch >> (gen < 8 ? 8 : 6)) & 0x3;
-    if (gen > 6) {
-        ggms = 1 << ggms;
-    }
-
-    ggms *= 1024 * 1024;
-
-    return (ggms / (4 * 1024)) * (gen < 8 ? 4 : 8);
-}
-
-/*
- * The IGD ROM will make use of stolen memory (GGMS) for support of VESA modes.
- * Somehow the host stolen memory range is used for this, but how the ROM gets
- * it is a mystery, perhaps it's hardcoded into the ROM.  Thankfully though, it
- * reprograms the GTT through the IOBAR where we can trap it and transpose the
- * programming to the VM allocated buffer.  That buffer gets reserved by the VM
- * firmware via the fw_cfg entry added below.  Here we're just monitoring the
- * IOBAR address and data registers to detect a write sequence targeting the
- * GTTADR.  This code is developed by observed behavior and doesn't have a
- * direct spec reference, unfortunately.
- */
-static uint64_t vfio_igd_quirk_data_read(void *opaque,
-                                         hwaddr addr, unsigned size)
-{
-    VFIOIGDQuirk *igd = opaque;
-    VFIOPCIDevice *vdev = igd->vdev;
-
-    igd->index = ~0;
-
-    return vfio_region_read(&vdev->bars[4].region, addr + 4, size);
-}
-
-static void vfio_igd_quirk_data_write(void *opaque, hwaddr addr,
-                                      uint64_t data, unsigned size)
-{
-    VFIOIGDQuirk *igd = opaque;
-    VFIOPCIDevice *vdev = igd->vdev;
-    uint64_t val = data;
-    int gen = igd_gen(vdev);
-
-    /*
-     * Programming the GGMS starts at index 0x1 and uses every 4th index (ie.
-     * 0x1, 0x5, 0x9, 0xd,...).  For pre-Gen8 each 4-byte write is a whole PTE
-     * entry, with 0th bit enable set.  For Gen8 and up, PTEs are 64bit, so
-     * entries 0x5 & 0xd are the high dword, in our case zero.  Each PTE points
-     * to a 4k page, which we translate to a page from the VM allocated region,
-     * pointed to by the BDSM register.  If this is not set, we fail.
-     *
-     * We trap writes to the full configured GTT size, but we typically only
-     * see the vBIOS writing up to (nearly) the 1MB barrier.  In fact it often
-     * seems to miss the last entry for an even 1MB GTT.  Doing a gratuitous
-     * write of that last entry does work, but is hopefully unnecessary since
-     * we clear the previous GTT on initialization.
-     */
-    if ((igd->index % 4 == 1) && igd->index < vfio_igd_gtt_max(vdev)) {
-        if (gen < 8 || (igd->index % 8 == 1)) {
-            uint32_t base;
-
-            base = pci_get_long(vdev->pdev.config + IGD_BDSM);
-            if (!base) {
-                hw_error("vfio-igd: Guest attempted to program IGD GTT before "
-                         "BIOS reserved stolen memory.  Unsupported BIOS?");
-            }
-
-            val = base | (data & ((1 << 20) - 1));
-        } else {
-            val = 0; /* upper 32bits of pte, we only enable below 4G PTEs */
-        }
-
-        trace_vfio_pci_igd_bar4_write(vdev->vbasedev.name,
-                                      igd->index, data, val);
-    }
-
-    vfio_region_write(&vdev->bars[4].region, addr + 4, val, size);
-
-    igd->index = ~0;
-}
-
-static const MemoryRegionOps vfio_igd_data_quirk = {
-    .read = vfio_igd_quirk_data_read,
-    .write = vfio_igd_quirk_data_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static uint64_t vfio_igd_quirk_index_read(void *opaque,
-                                          hwaddr addr, unsigned size)
-{
-    VFIOIGDQuirk *igd = opaque;
-    VFIOPCIDevice *vdev = igd->vdev;
-
-    igd->index = ~0;
-
-    return vfio_region_read(&vdev->bars[4].region, addr, size);
-}
-
-static void vfio_igd_quirk_index_write(void *opaque, hwaddr addr,
-                                       uint64_t data, unsigned size)
-{
-    VFIOIGDQuirk *igd = opaque;
-    VFIOPCIDevice *vdev = igd->vdev;
-
-    igd->index = data;
-
-    vfio_region_write(&vdev->bars[4].region, addr, data, size);
-}
-
-static const MemoryRegionOps vfio_igd_index_quirk = {
-    .read = vfio_igd_quirk_index_read,
-    .write = vfio_igd_quirk_index_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
-{
-    struct vfio_region_info *rom = NULL, *opregion = NULL,
-                            *host = NULL, *lpc = NULL;
-    VFIOQuirk *quirk;
-    VFIOIGDQuirk *igd;
-    PCIDevice *lpc_bridge;
-    int i, ret, ggms_mb, gms_mb = 0, gen;
-    uint64_t *bdsm_size;
-    uint32_t gmch;
-    uint16_t cmd_orig, cmd;
-
-    /*
-     * This must be an Intel VGA device at address 00:02.0 for us to even
-     * consider enabling legacy mode.  The vBIOS has dependencies on the
-     * PCI bus address.
-     */
-    if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
-        !vfio_is_vga(vdev) || nr != 4 ||
-        &vdev->pdev != pci_find_device(pci_device_root_bus(&vdev->pdev),
-                                       0, PCI_DEVFN(0x2, 0))) {
-        return;
-    }
-
-    /*
-     * We need to create an LPC/ISA bridge at PCI bus address 00:1f.0 that we
-     * can stuff host values into, so if there's already one there and it's not
-     * one we can hack on, legacy mode is no-go.  Sorry Q35.
-     */
-    lpc_bridge = pci_find_device(pci_device_root_bus(&vdev->pdev),
-                                 0, PCI_DEVFN(0x1f, 0));
-    if (lpc_bridge && !object_dynamic_cast(OBJECT(lpc_bridge),
-                                           "vfio-pci-igd-lpc-bridge")) {
-        error_report("IGD device %s cannot support legacy mode due to existing "
-                     "devices at address 1f.0", vdev->vbasedev.name);
-        return;
-    }
-
-    /*
-     * IGD is not a standard, they like to change their specs often.  We
-     * only attempt to support back to SandBridge and we hope that newer
-     * devices maintain compatibility with generation 8.
-     */
-    gen = igd_gen(vdev);
-    if (gen != 6 && gen != 8) {
-        error_report("IGD device %s is unsupported in legacy mode, "
-                     "try SandyBridge or newer", vdev->vbasedev.name);
-        return;
-    }
-
-    /*
-     * Most of what we're doing here is to enable the ROM to run, so if
-     * there's no ROM, there's no point in setting up this quirk.
-     * NB. We only seem to get BIOS ROMs, so a UEFI VM would need CSM support.
-     */
-    ret = vfio_get_region_info(&vdev->vbasedev,
-                               VFIO_PCI_ROM_REGION_INDEX, &rom);
-    if ((ret || !rom->size) && !vdev->pdev.romfile) {
-        error_report("IGD device %s has no ROM, legacy mode disabled",
-                     vdev->vbasedev.name);
-        goto out;
-    }
-
-    /*
-     * Ignore the hotplug corner case, mark the ROM failed, we can't
-     * create the devices we need for legacy mode in the hotplug scenario.
-     */
-    if (vdev->pdev.qdev.hotplugged) {
-        error_report("IGD device %s hotplugged, ROM disabled, "
-                     "legacy mode disabled", vdev->vbasedev.name);
-        vdev->rom_read_failed = true;
-        goto out;
-    }
-
-    /*
-     * Check whether we have all the vfio device specific regions to
-     * support legacy mode (added in Linux v4.6).  If not, bail.
-     */
-    ret = vfio_get_dev_region_info(&vdev->vbasedev,
-                        VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,
-                        VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION, &opregion);
-    if (ret) {
-        error_report("IGD device %s does not support OpRegion access,"
-                     "legacy mode disabled", vdev->vbasedev.name);
-        goto out;
-    }
-
-    ret = vfio_get_dev_region_info(&vdev->vbasedev,
-                        VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,
-                        VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG, &host);
-    if (ret) {
-        error_report("IGD device %s does not support host bridge access,"
-                     "legacy mode disabled", vdev->vbasedev.name);
-        goto out;
-    }
-
-    ret = vfio_get_dev_region_info(&vdev->vbasedev,
-                        VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,
-                        VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG, &lpc);
-    if (ret) {
-        error_report("IGD device %s does not support LPC bridge access,"
-                     "legacy mode disabled", vdev->vbasedev.name);
-        goto out;
-    }
-
-    gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4);
-
-    /*
-     * If IGD VGA Disable is clear (expected) and VGA is not already enabled,
-     * try to enable it.  Probably shouldn't be using legacy mode without VGA,
-     * but also no point in us enabling VGA if disabled in hardware.
-     */
-    if (!(gmch & 0x2) && !vdev->vga && vfio_populate_vga(vdev)) {
-        error_report("IGD device %s failed to enable VGA access, "
-                     "legacy mode disabled", vdev->vbasedev.name);
-        goto out;
-    }
-
-    /* Create our LPC/ISA bridge */
-    ret = vfio_pci_igd_lpc_init(vdev, lpc);
-    if (ret) {
-        error_report("IGD device %s failed to create LPC bridge, "
-                     "legacy mode disabled", vdev->vbasedev.name);
-        goto out;
-    }
-
-    /* Stuff some host values into the VM PCI host bridge */
-    ret = vfio_pci_igd_host_init(vdev, host);
-    if (ret) {
-        error_report("IGD device %s failed to modify host bridge, "
-                     "legacy mode disabled", vdev->vbasedev.name);
-        goto out;
-    }
-
-    /* Setup OpRegion access */
-    ret = vfio_pci_igd_opregion_init(vdev, opregion);
-    if (ret) {
-        error_report("IGD device %s failed to setup OpRegion, "
-                     "legacy mode disabled", vdev->vbasedev.name);
-        goto out;
-    }
-
-    /* Setup our quirk to munge GTT addresses to the VM allocated buffer */
-    quirk = g_malloc0(sizeof(*quirk));
-    quirk->mem = g_new0(MemoryRegion, 2);
-    quirk->nr_mem = 2;
-    igd = quirk->data = g_malloc0(sizeof(*igd));
-    igd->vdev = vdev;
-    igd->index = ~0;
-
-    memory_region_init_io(&quirk->mem[0], OBJECT(vdev), &vfio_igd_index_quirk,
-                          igd, "vfio-igd-index-quirk", 4);
-    memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
-                                        0, &quirk->mem[0], 1);
-
-    memory_region_init_io(&quirk->mem[1], OBJECT(vdev), &vfio_igd_data_quirk,
-                          igd, "vfio-igd-data-quirk", 4);
-    memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
-                                        4, &quirk->mem[1], 1);
-
-    QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
-
-    /* Determine the size of stolen memory needed for GTT */
-    ggms_mb = (gmch >> (gen < 8 ? 8 : 6)) & 0x3;
-    if (gen > 6) {
-        ggms_mb = 1 << ggms_mb;
-    }
-
-    /*
-     * Assume we have no GMS memory, but allow it to be overrided by device
-     * option (experimental).  The spec doesn't actually allow zero GMS when
-     * when IVD (IGD VGA Disable) is clear, but the claim is that it's unused,
-     * so let's not waste VM memory for it.
-     */
-    gmch &= ~((gen < 8 ? 0x1f : 0xff) << (gen < 8 ? 3 : 8));
-
-    if (vdev->igd_gms) {
-        if (vdev->igd_gms <= 0x10) {
-            gms_mb = vdev->igd_gms * 32;
-            gmch |= vdev->igd_gms << (gen < 8 ? 3 : 8);
-        } else {
-            error_report("Unsupported IGD GMS value 0x%x", vdev->igd_gms);
-            vdev->igd_gms = 0;
-        }
-    }
-
-    /*
-     * Request reserved memory for stolen memory via fw_cfg.  VM firmware
-     * must allocate a 1MB aligned reserved memory region below 4GB with
-     * the requested size (in bytes) for use by the Intel PCI class VGA
-     * device at VM address 00:02.0.  The base address of this reserved
-     * memory region must be written to the device BDSM regsiter at PCI
-     * config offset 0x5C.
-     */
-    bdsm_size = g_malloc(sizeof(*bdsm_size));
-    *bdsm_size = cpu_to_le64((ggms_mb + gms_mb) * 1024 * 1024);
-    fw_cfg_add_file(fw_cfg_find(), "etc/igd-bdsm-size",
-                    bdsm_size, sizeof(*bdsm_size));
-
-    /* GMCH is read-only, emulated */
-    pci_set_long(vdev->pdev.config + IGD_GMCH, gmch);
-    pci_set_long(vdev->pdev.wmask + IGD_GMCH, 0);
-    pci_set_long(vdev->emulated_config_bits + IGD_GMCH, ~0);
-
-    /* BDSM is read-write, emulated.  The BIOS needs to be able to write it */
-    pci_set_long(vdev->pdev.config + IGD_BDSM, 0);
-    pci_set_long(vdev->pdev.wmask + IGD_BDSM, ~0);
-    pci_set_long(vdev->emulated_config_bits + IGD_BDSM, ~0);
-
-    /*
-     * This IOBAR gives us access to GTTADR, which allows us to write to
-     * the GTT itself.  So let's go ahead and write zero to all the GTT
-     * entries to avoid spurious DMA faults.  Be sure I/O access is enabled
-     * before talking to the device.
-     */
-    if (pread(vdev->vbasedev.fd, &cmd_orig, sizeof(cmd_orig),
-              vdev->config_offset + PCI_COMMAND) != sizeof(cmd_orig)) {
-        error_report("IGD device %s - failed to read PCI command register",
-                     vdev->vbasedev.name);
-    }
-
-    cmd = cmd_orig | PCI_COMMAND_IO;
-
-    if (pwrite(vdev->vbasedev.fd, &cmd, sizeof(cmd),
-               vdev->config_offset + PCI_COMMAND) != sizeof(cmd)) {
-        error_report("IGD device %s - failed to write PCI command register",
-                     vdev->vbasedev.name);
-    }
-
-    for (i = 1; i < vfio_igd_gtt_max(vdev); i += 4) {
-        vfio_region_write(&vdev->bars[4].region, 0, i, 4);
-        vfio_region_write(&vdev->bars[4].region, 4, 0, 4);
-    }
-
-    if (pwrite(vdev->vbasedev.fd, &cmd_orig, sizeof(cmd_orig),
-               vdev->config_offset + PCI_COMMAND) != sizeof(cmd_orig)) {
-        error_report("IGD device %s - failed to restore PCI command register",
-                     vdev->vbasedev.name);
-    }
-
-    trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, ggms_mb + gms_mb);
-
-out:
-    g_free(rom);
-    g_free(opregion);
-    g_free(host);
-    g_free(lpc);
-}
-
-/*
  * Common quirk probe entry points.
  */
 void vfio_vga_quirk_setup(VFIOPCIDevice *vdev)
@@ -1650,7 +1010,6 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr)
     vfio_probe_nvidia_bar5_quirk(vdev, nr);
     vfio_probe_nvidia_bar0_quirk(vdev, nr);
     vfio_probe_rtl8168_bar2_quirk(vdev, nr);
-    vfio_probe_igd_bar4_quirk(vdev, nr);
 }
 
 void vfio_bar_quirk_exit(VFIOPCIDevice *vdev, int nr)
index 7bfa17c..d091d8c 100644 (file)
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include <linux/vfio.h>
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
@@ -31,7 +32,6 @@
 #include "sysemu/sysemu.h"
 #include "pci.h"
 #include "trace.h"
-#include "qapi/error.h"
 
 #define MSIX_CAP_LENGTH 12
 
@@ -417,11 +417,11 @@ static int vfio_enable_vectors(VFIOPCIDevice *vdev, bool msix)
 }
 
 static void vfio_add_kvm_msi_virq(VFIOPCIDevice *vdev, VFIOMSIVector *vector,
-                                  int vector_n, bool msix)
+                                  MSIMessage *msg, bool msix)
 {
     int virq;
 
-    if ((msix && vdev->no_kvm_msix) || (!msix && vdev->no_kvm_msi)) {
+    if ((msix && vdev->no_kvm_msix) || (!msix && vdev->no_kvm_msi) || !msg) {
         return;
     }
 
@@ -429,7 +429,7 @@ static void vfio_add_kvm_msi_virq(VFIOPCIDevice *vdev, VFIOMSIVector *vector,
         return;
     }
 
-    virq = kvm_irqchip_add_msi_route(kvm_state, vector_n, &vdev->pdev);
+    virq = kvm_irqchip_add_msi_route(kvm_state, *msg, &vdev->pdev);
     if (virq < 0) {
         event_notifier_cleanup(&vector->kvm_interrupt);
         return;
@@ -458,7 +458,6 @@ static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg,
                                      PCIDevice *pdev)
 {
     kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg, pdev);
-    kvm_irqchip_commit_routes(kvm_state);
 }
 
 static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
@@ -496,7 +495,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
             vfio_update_kvm_msi_virq(vector, *msg, pdev);
         }
     } else {
-        vfio_add_kvm_msi_virq(vdev, vector, nr, true);
+        vfio_add_kvm_msi_virq(vdev, vector, msg, true);
     }
 
     /*
@@ -640,6 +639,7 @@ retry:
 
     for (i = 0; i < vdev->nr_vectors; i++) {
         VFIOMSIVector *vector = &vdev->msi_vectors[i];
+        MSIMessage msg = msi_get_message(&vdev->pdev, i);
 
         vector->vdev = vdev;
         vector->virq = -1;
@@ -656,7 +656,7 @@ retry:
          * Attempt to enable route through KVM irqchip,
          * default to userspace handling if unavailable.
          */
-        vfio_add_kvm_msi_virq(vdev, vector, i, false);
+        vfio_add_kvm_msi_virq(vdev, vector, &msg, false);
     }
 
     /* Set interrupt type prior to possible interrupts */
@@ -1171,7 +1171,6 @@ static int vfio_msi_setup(VFIOPCIDevice *vdev, int pos)
     uint16_t ctrl;
     bool msi_64bit, msi_maskbit;
     int ret, entries;
-    Error *err = NULL;
 
     if (pread(vdev->vbasedev.fd, &ctrl, sizeof(ctrl),
               vdev->config_offset + pos + PCI_CAP_FLAGS) != sizeof(ctrl)) {
@@ -1185,13 +1184,12 @@ static int vfio_msi_setup(VFIOPCIDevice *vdev, int pos)
 
     trace_vfio_msi_setup(vdev->vbasedev.name, pos);
 
-    ret = msi_init(&vdev->pdev, pos, entries, msi_64bit, msi_maskbit, &err);
+    ret = msi_init(&vdev->pdev, pos, entries, msi_64bit, msi_maskbit);
     if (ret < 0) {
         if (ret == -ENOTSUP) {
             return 0;
         }
-        error_prepend(&err, "vfio: msi_init failed: ");
-        error_report_err(err);
+        error_report("vfio: msi_init failed");
         return ret;
     }
     vdev->msi_cap_size = 0xa + (msi_maskbit ? 0xa : 0) + (msi_64bit ? 0x4 : 0);
@@ -1442,6 +1440,8 @@ static void vfio_bar_setup(VFIOPCIDevice *vdev, int nr)
                      vdev->vbasedev.name, nr);
     }
 
+    vfio_bar_quirk_setup(vdev, nr);
+
     pci_register_bar(&vdev->pdev, nr, type, bar->region.mem);
 }
 
@@ -1452,6 +1452,29 @@ static void vfio_bars_setup(VFIOPCIDevice *vdev)
     for (i = 0; i < PCI_ROM_SLOT; i++) {
         vfio_bar_setup(vdev, i);
     }
+
+    if (vdev->vga) {
+        memory_region_init_io(&vdev->vga->region[QEMU_PCI_VGA_MEM].mem,
+                              OBJECT(vdev), &vfio_vga_ops,
+                              &vdev->vga->region[QEMU_PCI_VGA_MEM],
+                              "vfio-vga-mmio@0xa0000",
+                              QEMU_PCI_VGA_MEM_SIZE);
+        memory_region_init_io(&vdev->vga->region[QEMU_PCI_VGA_IO_LO].mem,
+                              OBJECT(vdev), &vfio_vga_ops,
+                              &vdev->vga->region[QEMU_PCI_VGA_IO_LO],
+                              "vfio-vga-io@0x3b0",
+                              QEMU_PCI_VGA_IO_LO_SIZE);
+        memory_region_init_io(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem,
+                              OBJECT(vdev), &vfio_vga_ops,
+                              &vdev->vga->region[QEMU_PCI_VGA_IO_HI],
+                              "vfio-vga-io@0x3c0",
+                              QEMU_PCI_VGA_IO_HI_SIZE);
+
+        pci_register_vga(&vdev->pdev, &vdev->vga->region[QEMU_PCI_VGA_MEM].mem,
+                         &vdev->vga->region[QEMU_PCI_VGA_IO_LO].mem,
+                         &vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem);
+        vfio_vga_quirk_setup(vdev);
+    }
 }
 
 static void vfio_bars_exit(VFIOPCIDevice *vdev)
@@ -1505,21 +1528,6 @@ static uint8_t vfio_std_cap_max_size(PCIDevice *pdev, uint8_t pos)
     return next - pos;
 }
 
-
-static uint16_t vfio_ext_cap_max_size(const uint8_t *config, uint16_t pos)
-{
-    uint16_t tmp, next = PCIE_CONFIG_SPACE_SIZE;
-
-    for (tmp = PCI_CONFIG_SPACE_SIZE; tmp;
-        tmp = PCI_EXT_CAP_NEXT(pci_get_long(config + tmp))) {
-        if (tmp > pos && tmp < next) {
-            next = tmp;
-        }
-    }
-
-    return next - pos;
-}
-
 static void vfio_set_word_bits(uint8_t *buf, uint16_t val, uint16_t mask)
 {
     pci_set_word(buf, (pci_get_word(buf) & ~mask) | val);
@@ -1767,101 +1775,16 @@ static int vfio_add_std_cap(VFIOPCIDevice *vdev, uint8_t pos)
     return 0;
 }
 
-static int vfio_add_ext_cap(VFIOPCIDevice *vdev)
-{
-    PCIDevice *pdev = &vdev->pdev;
-    uint32_t header;
-    uint16_t cap_id, next, size;
-    uint8_t cap_ver;
-    uint8_t *config;
-
-    /* Only add extended caps if we have them and the guest can see them */
-    if (!pci_is_express(pdev) || !pci_bus_is_express(pdev->bus) ||
-        !pci_get_long(pdev->config + PCI_CONFIG_SPACE_SIZE)) {
-        return 0;
-    }
-
-    /*
-     * pcie_add_capability always inserts the new capability at the tail
-     * of the chain.  Therefore to end up with a chain that matches the
-     * physical device, we cache the config space to avoid overwriting
-     * the original config space when we parse the extended capabilities.
-     */
-    config = g_memdup(pdev->config, vdev->config_size);
-
-    /*
-     * Extended capabilities are chained with each pointing to the next, so we
-     * can drop anything other than the head of the chain simply by modifying
-     * the previous next pointer.  For the head of the chain, we can modify the
-     * capability ID to something that cannot match a valid capability.  ID
-     * 0 is reserved for this since absence of capabilities is indicated by
-     * 0 for the ID, version, AND next pointer.  However, pcie_add_capability()
-     * uses ID 0 as reserved for list management and will incorrectly match and
-     * assert if we attempt to pre-load the head of the chain with with this
-     * ID.  Use ID 0xFFFF temporarily since it is also seems to be reserved in
-     * part for identifying absence of capabilities in a root complex register
-     * block.  If the ID still exists after adding capabilities, switch back to
-     * zero.  We'll mark this entire first dword as emulated for this purpose.
-     */
-    pci_set_long(pdev->config + PCI_CONFIG_SPACE_SIZE,
-                 PCI_EXT_CAP(0xFFFF, 0, 0));
-    pci_set_long(pdev->wmask + PCI_CONFIG_SPACE_SIZE, 0);
-    pci_set_long(vdev->emulated_config_bits + PCI_CONFIG_SPACE_SIZE, ~0);
-
-    for (next = PCI_CONFIG_SPACE_SIZE; next;
-         next = PCI_EXT_CAP_NEXT(pci_get_long(config + next))) {
-        header = pci_get_long(config + next);
-        cap_id = PCI_EXT_CAP_ID(header);
-        cap_ver = PCI_EXT_CAP_VER(header);
-
-        /*
-         * If it becomes important to configure extended capabilities to their
-         * actual size, use this as the default when it's something we don't
-         * recognize. Since QEMU doesn't actually handle many of the config
-         * accesses, exact size doesn't seem worthwhile.
-         */
-        size = vfio_ext_cap_max_size(config, next);
-
-        /* Use emulated next pointer to allow dropping extended caps */
-        pci_long_test_and_set_mask(vdev->emulated_config_bits + next,
-                                   PCI_EXT_CAP_NEXT_MASK);
-
-        switch (cap_id) {
-        case PCI_EXT_CAP_ID_SRIOV: /* Read-only VF BARs confuse OVMF */
-        case PCI_EXT_CAP_ID_ARI: /* XXX Needs next function virtualization */
-            trace_vfio_add_ext_cap_dropped(vdev->vbasedev.name, cap_id, next);
-            break;
-        default:
-            pcie_add_capability(pdev, cap_id, cap_ver, next, size);
-        }
-
-    }
-
-    /* Cleanup chain head ID if necessary */
-    if (pci_get_word(pdev->config + PCI_CONFIG_SPACE_SIZE) == 0xFFFF) {
-        pci_set_word(pdev->config + PCI_CONFIG_SPACE_SIZE, 0);
-    }
-
-    g_free(config);
-    return 0;
-}
-
 static int vfio_add_capabilities(VFIOPCIDevice *vdev)
 {
     PCIDevice *pdev = &vdev->pdev;
-    int ret;
 
     if (!(pdev->config[PCI_STATUS] & PCI_STATUS_CAP_LIST) ||
         !pdev->config[PCI_CAPABILITY_LIST]) {
         return 0; /* Nothing to add */
     }
 
-    ret = vfio_add_std_cap(vdev, pdev->config[PCI_CAPABILITY_LIST]);
-    if (ret) {
-        return ret;
-    }
-
-    return vfio_add_ext_cap(vdev);
+    return vfio_add_std_cap(vdev, pdev->config[PCI_CAPABILITY_LIST]);
 }
 
 static void vfio_pci_pre_reset(VFIOPCIDevice *vdev)
@@ -2138,61 +2061,42 @@ int vfio_populate_vga(VFIOPCIDevice *vdev)
     struct vfio_region_info *reg_info;
     int ret;
 
-    ret = vfio_get_region_info(vbasedev, VFIO_PCI_VGA_REGION_INDEX, &reg_info);
-    if (ret) {
-        return ret;
-    }
-
-    if (!(reg_info->flags & VFIO_REGION_INFO_FLAG_READ) ||
-        !(reg_info->flags & VFIO_REGION_INFO_FLAG_WRITE) ||
-        reg_info->size < 0xbffff + 1) {
-        error_report("vfio: Unexpected VGA info, flags 0x%lx, size 0x%lx",
-                     (unsigned long)reg_info->flags,
-                     (unsigned long)reg_info->size);
-        g_free(reg_info);
-        return -EINVAL;
-    }
-
-    vdev->vga = g_new0(VFIOVGA, 1);
-
-    vdev->vga->fd_offset = reg_info->offset;
-    vdev->vga->fd = vdev->vbasedev.fd;
-
-    g_free(reg_info);
+    if (vbasedev->num_regions > VFIO_PCI_VGA_REGION_INDEX) {
+        ret = vfio_get_region_info(vbasedev,
+                                   VFIO_PCI_VGA_REGION_INDEX, &reg_info);
+        if (ret) {
+            return ret;
+        }
 
-    vdev->vga->region[QEMU_PCI_VGA_MEM].offset = QEMU_PCI_VGA_MEM_BASE;
-    vdev->vga->region[QEMU_PCI_VGA_MEM].nr = QEMU_PCI_VGA_MEM;
-    QLIST_INIT(&vdev->vga->region[QEMU_PCI_VGA_MEM].quirks);
+        if (!(reg_info->flags & VFIO_REGION_INFO_FLAG_READ) ||
+            !(reg_info->flags & VFIO_REGION_INFO_FLAG_WRITE) ||
+            reg_info->size < 0xbffff + 1) {
+            error_report("vfio: Unexpected VGA info, flags 0x%lx, size 0x%lx",
+                         (unsigned long)reg_info->flags,
+                         (unsigned long)reg_info->size);
+            g_free(reg_info);
+            return -EINVAL;
+        }
 
-    memory_region_init_io(&vdev->vga->region[QEMU_PCI_VGA_MEM].mem,
-                          OBJECT(vdev), &vfio_vga_ops,
-                          &vdev->vga->region[QEMU_PCI_VGA_MEM],
-                          "vfio-vga-mmio@0xa0000",
-                          QEMU_PCI_VGA_MEM_SIZE);
+        vdev->vga = g_new0(VFIOVGA, 1);
 
-    vdev->vga->region[QEMU_PCI_VGA_IO_LO].offset = QEMU_PCI_VGA_IO_LO_BASE;
-    vdev->vga->region[QEMU_PCI_VGA_IO_LO].nr = QEMU_PCI_VGA_IO_LO;
-    QLIST_INIT(&vdev->vga->region[QEMU_PCI_VGA_IO_LO].quirks);
+        vdev->vga->fd_offset = reg_info->offset;
+        vdev->vga->fd = vdev->vbasedev.fd;
 
-    memory_region_init_io(&vdev->vga->region[QEMU_PCI_VGA_IO_LO].mem,
-                          OBJECT(vdev), &vfio_vga_ops,
-                          &vdev->vga->region[QEMU_PCI_VGA_IO_LO],
-                          "vfio-vga-io@0x3b0",
-                          QEMU_PCI_VGA_IO_LO_SIZE);
+        g_free(reg_info);
 
-    vdev->vga->region[QEMU_PCI_VGA_IO_HI].offset = QEMU_PCI_VGA_IO_HI_BASE;
-    vdev->vga->region[QEMU_PCI_VGA_IO_HI].nr = QEMU_PCI_VGA_IO_HI;
-    QLIST_INIT(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].quirks);
+        vdev->vga->region[QEMU_PCI_VGA_MEM].offset = QEMU_PCI_VGA_MEM_BASE;
+        vdev->vga->region[QEMU_PCI_VGA_MEM].nr = QEMU_PCI_VGA_MEM;
+        QLIST_INIT(&vdev->vga->region[QEMU_PCI_VGA_MEM].quirks);
 
-    memory_region_init_io(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem,
-                          OBJECT(vdev), &vfio_vga_ops,
-                          &vdev->vga->region[QEMU_PCI_VGA_IO_HI],
-                          "vfio-vga-io@0x3c0",
-                          QEMU_PCI_VGA_IO_HI_SIZE);
+        vdev->vga->region[QEMU_PCI_VGA_IO_LO].offset = QEMU_PCI_VGA_IO_LO_BASE;
+        vdev->vga->region[QEMU_PCI_VGA_IO_LO].nr = QEMU_PCI_VGA_IO_LO;
+        QLIST_INIT(&vdev->vga->region[QEMU_PCI_VGA_IO_LO].quirks);
 
-    pci_register_vga(&vdev->pdev, &vdev->vga->region[QEMU_PCI_VGA_MEM].mem,
-                     &vdev->vga->region[QEMU_PCI_VGA_IO_LO].mem,
-                     &vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem);
+        vdev->vga->region[QEMU_PCI_VGA_IO_HI].offset = QEMU_PCI_VGA_IO_HI_BASE;
+        vdev->vga->region[QEMU_PCI_VGA_IO_HI].nr = QEMU_PCI_VGA_IO_HI;
+        QLIST_INIT(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].quirks);
+    }
 
     return 0;
 }
@@ -2494,7 +2398,7 @@ static int vfio_initfn(PCIDevice *pdev)
     ssize_t len;
     struct stat st;
     int groupid;
-    int i, ret;
+    int ret;
 
     if (!vdev->vbasedev.sysfsdev) {
         vdev->vbasedev.sysfsdev =
@@ -2656,43 +2560,6 @@ static int vfio_initfn(PCIDevice *pdev)
         goto out_teardown;
     }
 
-    if (vdev->vga) {
-        vfio_vga_quirk_setup(vdev);
-    }
-
-    for (i = 0; i < PCI_ROM_SLOT; i++) {
-        vfio_bar_quirk_setup(vdev, i);
-    }
-
-    if (!vdev->igd_opregion &&
-        vdev->features & VFIO_FEATURE_ENABLE_IGD_OPREGION) {
-        struct vfio_region_info *opregion;
-
-        if (vdev->pdev.qdev.hotplugged) {
-            error_report("Cannot support IGD OpRegion feature on hotplugged "
-                         "device %s", vdev->vbasedev.name);
-            ret = -EINVAL;
-            goto out_teardown;
-        }
-
-        ret = vfio_get_dev_region_info(&vdev->vbasedev,
-                        VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,
-                        VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION, &opregion);
-        if (ret) {
-            error_report("Device %s does not support requested IGD OpRegion "
-                         "feature", vdev->vbasedev.name);
-            goto out_teardown;
-        }
-
-        ret = vfio_pci_igd_opregion_init(vdev, opregion);
-        g_free(opregion);
-        if (ret) {
-            error_report("Device %s IGD OpRegion initialization failed",
-                         vdev->vbasedev.name);
-            goto out_teardown;
-        }
-    }
-
     /* QEMU emulates all of MSI & MSIX */
     if (pdev->cap_present & QEMU_PCI_CAP_MSIX) {
         memset(vdev->emulated_config_bits + pdev->msix_cap, 0xff,
@@ -2736,13 +2603,6 @@ static void vfio_instance_finalize(Object *obj)
     vfio_bars_finalize(vdev);
     g_free(vdev->emulated_config_bits);
     g_free(vdev->rom);
-    /*
-     * XXX Leaking igd_opregion is not an oversight, we can't remove the
-     * fw_cfg entry therefore leaking this allocation seems like the safest
-     * option.
-     *
-     * g_free(vdev->igd_opregion);
-     */
     vfio_put_device(vdev);
     vfio_put_group(group);
 }
@@ -2817,8 +2677,6 @@ static Property vfio_pci_dev_properties[] = {
                     VFIO_FEATURE_ENABLE_VGA_BIT, false),
     DEFINE_PROP_BIT("x-req", VFIOPCIDevice, features,
                     VFIO_FEATURE_ENABLE_REQ_BIT, true),
-    DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features,
-                    VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
     DEFINE_PROP_BOOL("x-no-mmap", VFIOPCIDevice, vbasedev.no_mmap, false),
     DEFINE_PROP_BOOL("x-no-kvm-intx", VFIOPCIDevice, no_kvm_intx, false),
     DEFINE_PROP_BOOL("x-no-kvm-msi", VFIOPCIDevice, no_kvm_msi, false),
@@ -2829,7 +2687,6 @@ static Property vfio_pci_dev_properties[] = {
                        sub_vendor_id, PCI_ANY_ID),
     DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
                        sub_device_id, PCI_ANY_ID),
-    DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
     /*
      * TODO - support passed fds... is this necessary?
      * DEFINE_PROP_STRING("vfiofd", VFIOPCIDevice, vfiofd_name),
index 7d482d9..72174b3 100644 (file)
@@ -115,7 +115,6 @@ typedef struct VFIOPCIDevice {
     int interrupt; /* Current interrupt type */
     VFIOBAR bars[PCI_NUM_REGIONS - 1]; /* No ROM */
     VFIOVGA *vga; /* 0xa0000, 0x3b0, 0x3c0 */
-    void *igd_opregion;
     PCIHostDeviceAddress host;
     EventNotifier err_notifier;
     EventNotifier req_notifier;
@@ -129,11 +128,7 @@ typedef struct VFIOPCIDevice {
 #define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT)
 #define VFIO_FEATURE_ENABLE_REQ_BIT 1
 #define VFIO_FEATURE_ENABLE_REQ (1 << VFIO_FEATURE_ENABLE_REQ_BIT)
-#define VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT 2
-#define VFIO_FEATURE_ENABLE_IGD_OPREGION \
-                                (1 << VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT)
     int32_t bootindex;
-    uint32_t igd_gms;
     uint8_t pm_cap;
     bool pci_aer;
     bool req_enabled;
@@ -163,7 +158,4 @@ void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev);
 
 int vfio_populate_vga(VFIOPCIDevice *vdev);
 
-int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
-                               struct vfio_region_info *info);
-
 #endif /* HW_VFIO_VFIO_PCI_H */
index a559e7b..1798a00 100644 (file)
@@ -496,7 +496,7 @@ static int vfio_populate_device(VFIODevice *vbasedev)
         irq.index = i;
         ret = ioctl(vbasedev->fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
         if (ret) {
-            error_report("vfio: error getting device %s irq info",
+            error_printf("vfio: error getting device %s irq info",
                          vbasedev->name);
             goto irq_err;
         } else {
diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c
deleted file mode 100644 (file)
index 7443d34..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * DMA memory preregistration
- *
- * Authors:
- *  Alexey Kardashevskiy <aik@ozlabs.ru>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include <sys/ioctl.h>
-#include <linux/vfio.h>
-
-#include "hw/vfio/vfio-common.h"
-#include "hw/hw.h"
-#include "qemu/error-report.h"
-#include "trace.h"
-
-static bool vfio_prereg_listener_skipped_section(MemoryRegionSection *section)
-{
-    if (memory_region_is_iommu(section->mr)) {
-        hw_error("Cannot possibly preregister IOMMU memory");
-    }
-
-    return !memory_region_is_ram(section->mr) ||
-            memory_region_is_skip_dump(section->mr);
-}
-
-static void *vfio_prereg_gpa_to_vaddr(MemoryRegionSection *section, hwaddr gpa)
-{
-    return memory_region_get_ram_ptr(section->mr) +
-        section->offset_within_region +
-        (gpa - section->offset_within_address_space);
-}
-
-static void vfio_prereg_listener_region_add(MemoryListener *listener,
-                                            MemoryRegionSection *section)
-{
-    VFIOContainer *container = container_of(listener, VFIOContainer,
-                                            prereg_listener);
-    const hwaddr gpa = section->offset_within_address_space;
-    hwaddr end;
-    int ret;
-    hwaddr page_mask = qemu_real_host_page_mask;
-    struct vfio_iommu_spapr_register_memory reg = {
-        .argsz = sizeof(reg),
-        .flags = 0,
-    };
-
-    if (vfio_prereg_listener_skipped_section(section)) {
-        trace_vfio_prereg_listener_region_add_skip(
-                section->offset_within_address_space,
-                section->offset_within_address_space +
-                int128_get64(int128_sub(section->size, int128_one())));
-        return;
-    }
-
-    if (unlikely((section->offset_within_address_space & ~page_mask) ||
-                 (section->offset_within_region & ~page_mask) ||
-                 (int128_get64(section->size) & ~page_mask))) {
-        error_report("%s received unaligned region", __func__);
-        return;
-    }
-
-    end = section->offset_within_address_space + int128_get64(section->size);
-    if (gpa >= end) {
-        return;
-    }
-
-    memory_region_ref(section->mr);
-
-    reg.vaddr = (uintptr_t) vfio_prereg_gpa_to_vaddr(section, gpa);
-    reg.size = end - gpa;
-
-    ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_REGISTER_MEMORY, &reg);
-    trace_vfio_prereg_register(reg.vaddr, reg.size, ret ? -errno : 0);
-    if (ret) {
-        /*
-         * On the initfn path, store the first error in the container so we
-         * can gracefully fail.  Runtime, there's not much we can do other
-         * than throw a hardware error.
-         */
-        if (!container->initialized) {
-            if (!container->error) {
-                container->error = ret;
-            }
-        } else {
-            hw_error("vfio: Memory registering failed, unable to continue");
-        }
-    }
-}
-
-static void vfio_prereg_listener_region_del(MemoryListener *listener,
-                                            MemoryRegionSection *section)
-{
-    VFIOContainer *container = container_of(listener, VFIOContainer,
-                                            prereg_listener);
-    const hwaddr gpa = section->offset_within_address_space;
-    hwaddr end;
-    int ret;
-    hwaddr page_mask = qemu_real_host_page_mask;
-    struct vfio_iommu_spapr_register_memory reg = {
-        .argsz = sizeof(reg),
-        .flags = 0,
-    };
-
-    if (vfio_prereg_listener_skipped_section(section)) {
-        trace_vfio_prereg_listener_region_del_skip(
-                section->offset_within_address_space,
-                section->offset_within_address_space +
-                int128_get64(int128_sub(section->size, int128_one())));
-        return;
-    }
-
-    if (unlikely((section->offset_within_address_space & ~page_mask) ||
-                 (section->offset_within_region & ~page_mask) ||
-                 (int128_get64(section->size) & ~page_mask))) {
-        error_report("%s received unaligned region", __func__);
-        return;
-    }
-
-    end = section->offset_within_address_space + int128_get64(section->size);
-    if (gpa >= end) {
-        return;
-    }
-
-    reg.vaddr = (uintptr_t) vfio_prereg_gpa_to_vaddr(section, gpa);
-    reg.size = end - gpa;
-
-    ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_UNREGISTER_MEMORY, &reg);
-    trace_vfio_prereg_unregister(reg.vaddr, reg.size, ret ? -errno : 0);
-}
-
-const MemoryListener vfio_prereg_listener = {
-    .region_add = vfio_prereg_listener_region_add,
-    .region_del = vfio_prereg_listener_region_del,
-};
-
-int vfio_spapr_create_window(VFIOContainer *container,
-                             MemoryRegionSection *section,
-                             hwaddr *pgsize)
-{
-    int ret;
-    unsigned pagesize = memory_region_iommu_get_min_page_size(section->mr);
-    unsigned entries, pages;
-    struct vfio_iommu_spapr_tce_create create = { .argsz = sizeof(create) };
-
-    /*
-     * FIXME: For VFIO iommu types which have KVM acceleration to
-     * avoid bouncing all map/unmaps through qemu this way, this
-     * would be the right place to wire that up (tell the KVM
-     * device emulation the VFIO iommu handles to use).
-     */
-    create.window_size = int128_get64(section->size);
-    create.page_shift = ctz64(pagesize);
-    /*
-     * SPAPR host supports multilevel TCE tables, there is some
-     * heuristic to decide how many levels we want for our table:
-     * 0..64 = 1; 65..4096 = 2; 4097..262144 = 3; 262145.. = 4
-     */
-    entries = create.window_size >> create.page_shift;
-    pages = MAX((entries * sizeof(uint64_t)) / getpagesize(), 1);
-    pages = MAX(pow2ceil(pages) - 1, 1); /* Round up */
-    create.levels = ctz64(pages) / 6 + 1;
-
-    ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create);
-    if (ret) {
-        error_report("Failed to create a window, ret = %d (%m)", ret);
-        return -errno;
-    }
-
-    if (create.start_addr != section->offset_within_address_space) {
-        vfio_spapr_remove_window(container, create.start_addr);
-
-        error_report("Host doesn't support DMA window at %"HWADDR_PRIx", must be %"PRIx64,
-                     section->offset_within_address_space,
-                     (uint64_t)create.start_addr);
-        return -EINVAL;
-    }
-    trace_vfio_spapr_create_window(create.page_shift,
-                                   create.window_size,
-                                   create.start_addr);
-    *pgsize = pagesize;
-
-    return 0;
-}
-
-int vfio_spapr_remove_window(VFIOContainer *container,
-                             hwaddr offset_within_address_space)
-{
-    struct vfio_iommu_spapr_tce_remove remove = {
-        .argsz = sizeof(remove),
-        .start_addr = offset_within_address_space,
-    };
-    int ret;
-
-    ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_REMOVE, &remove);
-    if (ret) {
-        error_report("Failed to remove window at %"PRIx64,
-                     (uint64_t)remove.start_addr);
-        return -errno;
-    }
-
-    trace_vfio_spapr_remove_window(offset_within_address_space);
-
-    return 0;
-}
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
deleted file mode 100644 (file)
index da13322..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/vfio/pci.c
-vfio_intx_interrupt(const char *name, char line) " (%s) Pin %c"
-vfio_intx_eoi(const char *name) " (%s) EOI"
-vfio_intx_enable_kvm(const char *name) " (%s) KVM INTx accel enabled"
-vfio_intx_disable_kvm(const char *name) " (%s) KVM INTx accel disabled"
-vfio_intx_update(const char *name, int new_irq, int target_irq) " (%s) IRQ moved %d -> %d"
-vfio_intx_enable(const char *name) " (%s)"
-vfio_intx_disable(const char *name) " (%s)"
-vfio_msi_interrupt(const char *name, int index, uint64_t addr, int data) " (%s) vector %d 0x%"PRIx64"/0x%x"
-vfio_msix_vector_do_use(const char *name, int index) " (%s) vector %d used"
-vfio_msix_vector_release(const char *name, int index) " (%s) vector %d released"
-vfio_msix_enable(const char *name) " (%s)"
-vfio_msix_pba_disable(const char *name) " (%s)"
-vfio_msix_pba_enable(const char *name) " (%s)"
-vfio_msix_disable(const char *name) " (%s)"
-vfio_msix_fixup(const char *name, int bar, uint64_t start, uint64_t end) " (%s) MSI-X region %d mmap fixup [0x%"PRIx64" - 0x%"PRIx64"]"
-vfio_msi_enable(const char *name, int nr_vectors) " (%s) Enabled %d MSI vectors"
-vfio_msi_disable(const char *name) " (%s)"
-vfio_pci_load_rom(const char *name, unsigned long size, unsigned long offset, unsigned long flags) "Device %s ROM:\n  size: 0x%lx, offset: 0x%lx, flags: 0x%lx"
-vfio_rom_read(const char *name, uint64_t addr, int size, uint64_t data) " (%s, 0x%"PRIx64", 0x%x) = 0x%"PRIx64
-vfio_pci_size_rom(const char *name, int size) "%s ROM size 0x%x"
-vfio_vga_write(uint64_t addr, uint64_t data, int size) " (0x%"PRIx64", 0x%"PRIx64", %d)"
-vfio_vga_read(uint64_t addr, int size, uint64_t data) " (0x%"PRIx64", %d) = 0x%"PRIx64
-vfio_pci_read_config(const char *name, int addr, int len, int val) " (%s, @0x%x, len=0x%x) %x"
-vfio_pci_write_config(const char *name, int addr, int val, int len) " (%s, @0x%x, 0x%x, len=0x%x)"
-vfio_msi_setup(const char *name, int pos) "%s PCI MSI CAP @0x%x"
-vfio_msix_early_setup(const char *name, int pos, int table_bar, int offset, int entries) "%s PCI MSI-X CAP @0x%x, BAR %d, offset 0x%x, entries %d"
-vfio_check_pcie_flr(const char *name) "%s Supports FLR via PCIe cap"
-vfio_check_pm_reset(const char *name) "%s Supports PM reset"
-vfio_check_af_flr(const char *name) "%s Supports FLR via AF cap"
-vfio_pci_hot_reset(const char *name, const char *type) " (%s) %s"
-vfio_pci_hot_reset_has_dep_devices(const char *name) "%s: hot reset dependent devices:"
-vfio_pci_hot_reset_dep_devices(int domain, int bus, int slot, int function, int group_id) "\t%04x:%02x:%02x.%x group %d"
-vfio_pci_hot_reset_result(const char *name, const char *result) "%s hot reset: %s"
-vfio_populate_device_config(const char *name, unsigned long size, unsigned long offset, unsigned long flags) "Device %s config:\n  size: 0x%lx, offset: 0x%lx, flags: 0x%lx"
-vfio_populate_device_get_irq_info_failure(void) "VFIO_DEVICE_GET_IRQ_INFO failure: %m"
-vfio_initfn(const char *name, int group_id) " (%s) group %d"
-vfio_add_ext_cap_dropped(const char *name, uint16_t cap, uint16_t offset) "%s %x@%x"
-vfio_pci_reset(const char *name) " (%s)"
-vfio_pci_reset_flr(const char *name) "%s FLR/VFIO_DEVICE_RESET"
-vfio_pci_reset_pm(const char *name) "%s PCI PM Reset"
-vfio_pci_emulated_vendor_id(const char *name, uint16_t val) "%s %04x"
-vfio_pci_emulated_device_id(const char *name, uint16_t val) "%s %04x"
-vfio_pci_emulated_sub_vendor_id(const char *name, uint16_t val) "%s %04x"
-vfio_pci_emulated_sub_device_id(const char *name, uint16_t val) "%s %04x"
-
-# hw/vfio/pci-quirks.
-vfio_quirk_rom_blacklisted(const char *name, uint16_t vid, uint16_t did) "%s %04x:%04x"
-vfio_quirk_generic_window_address_write(const char *name, const char * region_name, uint64_t data) "%s %s 0x%"PRIx64
-vfio_quirk_generic_window_data_read(const char *name, const char * region_name, uint64_t data) "%s %s 0x%"PRIx64
-vfio_quirk_generic_window_data_write(const char *name, const char * region_name, uint64_t data) "%s %s 0x%"PRIx64
-vfio_quirk_generic_mirror_read(const char *name, const char * region_name, uint64_t addr, uint64_t data) "%s %s 0x%"PRIx64": 0x%"PRIx64
-vfio_quirk_generic_mirror_write(const char *name, const char * region_name, uint64_t addr, uint64_t data) "%s %s 0x%"PRIx64": 0x%"PRIx64
-vfio_quirk_ati_3c3_read(const char *name, uint64_t data) "%s 0x%"PRIx64
-vfio_quirk_ati_3c3_probe(const char *name) "%s"
-vfio_quirk_ati_bar4_probe(const char *name) "%s"
-vfio_quirk_ati_bar2_probe(const char *name) "%s"
-vfio_quirk_nvidia_3d0_state(const char *name, const char *state) "%s %s"
-vfio_quirk_nvidia_3d0_read(const char *name, uint8_t offset, unsigned size, uint64_t val) " (%s, @0x%x, len=0x%x) %"PRIx64
-vfio_quirk_nvidia_3d0_write(const char *name, uint8_t offset, uint64_t data, unsigned size) "(%s, @0x%x, 0x%"PRIx64", len=0x%x)"
-vfio_quirk_nvidia_3d0_probe(const char *name) "%s"
-vfio_quirk_nvidia_bar5_state(const char *name, const char *state) "%s %s"
-vfio_quirk_nvidia_bar5_probe(const char *name) "%s"
-vfio_quirk_nvidia_bar0_msi_ack(const char *name) "%s"
-vfio_quirk_nvidia_bar0_probe(const char *name) "%s"
-vfio_quirk_rtl8168_fake_latch(const char *name, uint64_t val) "%s 0x%"PRIx64
-vfio_quirk_rtl8168_msix_write(const char *name, uint16_t offset, uint64_t val) "%s MSI-X table write[0x%x]: 0x%"PRIx64
-vfio_quirk_rtl8168_msix_read(const char *name, uint16_t offset, uint64_t val) "%s MSI-X table read[0x%x]: 0x%"PRIx64
-vfio_quirk_rtl8168_probe(const char *name) "%s"
-
-vfio_quirk_ati_bonaire_reset_skipped(const char *name) "%s"
-vfio_quirk_ati_bonaire_reset_no_smc(const char *name) "%s"
-vfio_quirk_ati_bonaire_reset_timeout(const char *name) "%s"
-vfio_quirk_ati_bonaire_reset_done(const char *name) "%s"
-vfio_quirk_ati_bonaire_reset(const char *name) "%s"
-vfio_pci_igd_bar4_write(const char *name, uint32_t index, uint32_t data, uint32_t base) "%s [%03x] %08x -> %08x"
-vfio_pci_igd_bdsm_enabled(const char *name, int size) "%s %dMB"
-vfio_pci_igd_opregion_enabled(const char *name) "%s"
-vfio_pci_igd_host_bridge_enabled(const char *name) "%s"
-vfio_pci_igd_lpc_bridge_enabled(const char *name) "%s"
-
-# hw/vfio/common.c
-vfio_region_write(const char *name, int index, uint64_t addr, uint64_t data, unsigned size) " (%s:region%d+0x%"PRIx64", 0x%"PRIx64 ", %d)"
-vfio_region_read(char *name, int index, uint64_t addr, unsigned size, uint64_t data) " (%s:region%d+0x%"PRIx64", %d) = 0x%"PRIx64
-vfio_iommu_map_notify(uint64_t iova_start, uint64_t iova_end) "iommu map @ %"PRIx64" - %"PRIx64
-vfio_listener_region_add_skip(uint64_t start, uint64_t end) "SKIPPING region_add %"PRIx64" - %"PRIx64
-vfio_listener_region_add_iommu(uint64_t start, uint64_t end) "region_add [iommu] %"PRIx64" - %"PRIx64
-vfio_listener_region_add_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] %"PRIx64" - %"PRIx64" [%p]"
-vfio_listener_region_del_skip(uint64_t start, uint64_t end) "SKIPPING region_del %"PRIx64" - %"PRIx64
-vfio_listener_region_del(uint64_t start, uint64_t end) "region_del %"PRIx64" - %"PRIx64
-vfio_disconnect_container(int fd) "close container->fd=%d"
-vfio_put_group(int fd) "close group->fd=%d"
-vfio_get_device(const char * name, unsigned int flags, unsigned int num_regions, unsigned int num_irqs) "Device %s flags: %u, regions: %u, irqs: %u"
-vfio_put_base_device(int fd) "close vdev->fd=%d"
-vfio_region_setup(const char *dev, int index, const char *name, unsigned long flags, unsigned long offset, unsigned long size) "Device %s, region %d \"%s\", flags: %lx, offset: %lx, size: %lx"
-vfio_region_mmap_fault(const char *name, int index, unsigned long offset, unsigned long size, int fault) "Region %s mmaps[%d], [%lx - %lx], fault: %d"
-vfio_region_mmap(const char *name, unsigned long offset, unsigned long end) "Region %s [%lx - %lx]"
-vfio_region_exit(const char *name, int index) "Device %s, region %d"
-vfio_region_finalize(const char *name, int index) "Device %s, region %d"
-vfio_region_mmaps_set_enabled(const char *name, bool enabled) "Region %s mmaps enabled: %d"
-vfio_region_sparse_mmap_header(const char *name, int index, int nr_areas) "Device %s region %d: %d sparse mmap entries"
-vfio_region_sparse_mmap_entry(int i, unsigned long start, unsigned long end) "sparse entry %d [0x%lx - 0x%lx]"
-vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%0x8"
-
-# hw/vfio/platform.c
-vfio_platform_base_device_init(char *name, int groupid) "%s belongs to group #%d"
-vfio_platform_realize(char *name, char *compat) "vfio device %s, compat = %s"
-vfio_platform_eoi(int pin, int fd) "EOI IRQ pin %d (fd=%d)"
-vfio_platform_intp_mmap_enable(int pin) "IRQ #%d still active, stay in slow path"
-vfio_platform_intp_interrupt(int pin, int fd) "Inject IRQ #%d (fd = %d)"
-vfio_platform_intp_inject_pending_lockheld(int pin, int fd) "Inject pending IRQ #%d (fd = %d)"
-vfio_platform_populate_interrupts(int pin, int count, int flags) "- IRQ index %d: count %d, flags=0x%x"
-vfio_intp_interrupt_set_pending(int index) "irq %d is set PENDING"
-vfio_platform_start_level_irqfd_injection(int index, int fd, int resamplefd) "IRQ index=%d, fd = %d, resamplefd = %d"
-vfio_platform_start_edge_irqfd_injection(int index, int fd) "IRQ index=%d, fd = %d"
-
-# hw/vfio/spapr.c
-vfio_prereg_listener_region_add_skip(uint64_t start, uint64_t end) "%"PRIx64" - %"PRIx64
-vfio_prereg_listener_region_del_skip(uint64_t start, uint64_t end) "%"PRIx64" - %"PRIx64
-vfio_prereg_register(uint64_t va, uint64_t size, int ret) "va=%"PRIx64" size=%"PRIx64" ret=%d"
-vfio_prereg_unregister(uint64_t va, uint64_t size, int ret) "va=%"PRIx64" size=%"PRIx64" ret=%d"
-vfio_spapr_create_window(int ps, uint64_t ws, uint64_t off) "pageshift=0x%x winsize=0x%"PRIx64" offset=0x%"PRIx64
-vfio_spapr_remove_window(uint64_t off) "offset=%"PRIx64
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
deleted file mode 100644 (file)
index 55184d3..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/virtio/virtio.c
-virtqueue_fill(void *vq, const void *elem, unsigned int len, unsigned int idx) "vq %p elem %p len %u idx %u"
-virtqueue_flush(void *vq, unsigned int count) "vq %p count %u"
-virtqueue_pop(void *vq, void *elem, unsigned int in_num, unsigned int out_num) "vq %p elem %p in_num %u out_num %u"
-virtio_queue_notify(void *vdev, int n, void *vq) "vdev %p n %d vq %p"
-virtio_irq(void *vq) "vq %p"
-virtio_notify(void *vdev, void *vq) "vdev %p vq %p"
-virtio_set_status(void *vdev, uint8_t val) "vdev %p val %u"
-
-# hw/virtio/virtio-rng.c
-virtio_rng_guest_not_ready(void *rng) "rng %p: guest not ready"
-virtio_rng_pushed(void *rng, size_t len) "rng %p: %zd bytes pushed"
-virtio_rng_request(void *rng, size_t size, unsigned quota) "rng %p: %zd bytes requested, %u bytes quota left"
-
index 7681f15..b358902 100644 (file)
@@ -9,11 +9,12 @@
  */
 
 #include "qemu/osdep.h"
-#include <linux/vhost.h>
-#include <sys/ioctl.h>
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-backend.h"
 #include "qemu/error-report.h"
+#include "linux/vhost.h"
+
+#include <sys/ioctl.h>
 
 static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request,
                              void *arg)
@@ -137,12 +138,6 @@ static int vhost_kernel_set_vring_call(struct vhost_dev *dev,
     return vhost_kernel_call(dev, VHOST_SET_VRING_CALL, file);
 }
 
-static int vhost_kernel_set_vring_busyloop_timeout(struct vhost_dev *dev,
-                                                   struct vhost_vring_state *s)
-{
-    return vhost_kernel_call(dev, VHOST_SET_VRING_BUSYLOOP_TIMEOUT, s);
-}
-
 static int vhost_kernel_set_features(struct vhost_dev *dev,
                                      uint64_t features)
 {
@@ -190,8 +185,6 @@ static const VhostOps kernel_ops = {
         .vhost_get_vring_base = vhost_kernel_get_vring_base,
         .vhost_set_vring_kick = vhost_kernel_set_vring_kick,
         .vhost_set_vring_call = vhost_kernel_set_vring_call,
-        .vhost_set_vring_busyloop_timeout =
-                                vhost_kernel_set_vring_busyloop_timeout,
         .vhost_set_features = vhost_kernel_set_features,
         .vhost_get_features = vhost_kernel_get_features,
         .vhost_set_owner = vhost_kernel_set_owner,
index b57454a..5914e85 100644 (file)
@@ -17,6 +17,7 @@
 #include "sysemu/kvm.h"
 #include "qemu/error-report.h"
 #include "qemu/sockets.h"
+#include "exec/ram_addr.h"
 #include "migration/migration.h"
 
 #include <sys/ioctl.h>
@@ -31,7 +32,6 @@ enum VhostUserProtocolFeature {
     VHOST_USER_PROTOCOL_F_MQ = 0,
     VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
     VHOST_USER_PROTOCOL_F_RARP = 2,
-    VHOST_USER_PROTOCOL_F_REPLY_ACK = 3,
 
     VHOST_USER_PROTOCOL_F_MAX
 };
@@ -85,7 +85,6 @@ typedef struct VhostUserMsg {
 
 #define VHOST_USER_VERSION_MASK     (0x3)
 #define VHOST_USER_REPLY_MASK       (0x1<<2)
-#define VHOST_USER_NEED_REPLY_MASK  (0x1 << 3)
     uint32_t flags;
     uint32_t size; /* the following payload size */
     union {
@@ -160,25 +159,6 @@ fail:
     return -1;
 }
 
-static int process_message_reply(struct vhost_dev *dev,
-                                 VhostUserRequest request)
-{
-    VhostUserMsg msg;
-
-    if (vhost_user_read(dev, &msg) < 0) {
-        return -1;
-    }
-
-    if (msg.request != request) {
-        error_report("Received unexpected msg type."
-                     "Expected %d received %d",
-                     request, msg.request);
-        return -1;
-    }
-
-    return msg.payload.u64 ? -1 : 0;
-}
-
 static bool vhost_user_one_time_request(VhostUserRequest request)
 {
     switch (request) {
@@ -197,7 +177,7 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
                             int *fds, int fd_num)
 {
     CharDriverState *chr = dev->opaque;
-    int ret, size = VHOST_USER_HDR_SIZE + msg->size;
+    int size = VHOST_USER_HDR_SIZE + msg->size;
 
     /*
      * For non-vring specific requests, like VHOST_USER_SET_MEM_TABLE,
@@ -208,19 +188,12 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
         return 0;
     }
 
-    if (qemu_chr_fe_set_msgfds(chr, fds, fd_num) < 0) {
-        error_report("Failed to set msg fds.");
-        return -1;
-    }
-
-    ret = qemu_chr_fe_write_all(chr, (const uint8_t *) msg, size);
-    if (ret != size) {
-        error_report("Failed to write msg."
-                     " Wrote %d instead of %d.", ret, size);
-        return -1;
+    if (fd_num) {
+        qemu_chr_fe_set_msgfds(chr, fds, fd_num);
     }
 
-    return 0;
+    return qemu_chr_fe_write_all(chr, (const uint8_t *) msg, size) == size ?
+            0 : -1;
 }
 
 static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,
@@ -242,14 +215,12 @@ static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,
         fds[fd_num++] = log->fd;
     }
 
-    if (vhost_user_write(dev, &msg, fds, fd_num) < 0) {
-        return -1;
-    }
+    vhost_user_write(dev, &msg, fds, fd_num);
 
     if (shmfd) {
         msg.size = 0;
         if (vhost_user_read(dev, &msg) < 0) {
-            return -1;
+            return 0;
         }
 
         if (msg.request != VHOST_USER_SET_LOG_BASE) {
@@ -269,32 +240,25 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
     int fds[VHOST_MEMORY_MAX_NREGIONS];
     int i, fd;
     size_t fd_num = 0;
-    bool reply_supported = virtio_has_feature(dev->protocol_features,
-                                              VHOST_USER_PROTOCOL_F_REPLY_ACK);
-
     VhostUserMsg msg = {
         .request = VHOST_USER_SET_MEM_TABLE,
         .flags = VHOST_USER_VERSION,
     };
 
-    if (reply_supported) {
-        msg.flags |= VHOST_USER_NEED_REPLY_MASK;
-    }
-
     for (i = 0; i < dev->mem->nregions; ++i) {
         struct vhost_memory_region *reg = dev->mem->regions + i;
-        ram_addr_t offset;
-        MemoryRegion *mr;
+        ram_addr_t ram_addr;
 
         assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
-        mr = memory_region_from_host((void *)(uintptr_t)reg->userspace_addr,
-                                     &offset);
-        fd = memory_region_get_fd(mr);
+        qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr,
+                                &ram_addr);
+        fd = qemu_get_ram_fd(ram_addr);
         if (fd > 0) {
             msg.payload.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
             msg.payload.memory.regions[fd_num].memory_size  = reg->memory_size;
             msg.payload.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
-            msg.payload.memory.regions[fd_num].mmap_offset = offset;
+            msg.payload.memory.regions[fd_num].mmap_offset = reg->userspace_addr -
+                (uintptr_t) qemu_get_ram_block_host_ptr(ram_addr);
             assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
             fds[fd_num++] = fd;
         }
@@ -312,13 +276,7 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
     msg.size += sizeof(msg.payload.memory.padding);
     msg.size += fd_num * sizeof(VhostUserMemoryRegion);
 
-    if (vhost_user_write(dev, &msg, fds, fd_num) < 0) {
-        return -1;
-    }
-
-    if (reply_supported) {
-        return process_message_reply(dev, msg.request);
-    }
+    vhost_user_write(dev, &msg, fds, fd_num);
 
     return 0;
 }
@@ -333,9 +291,7 @@ static int vhost_user_set_vring_addr(struct vhost_dev *dev,
         .size = sizeof(msg.payload.addr),
     };
 
-    if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
-        return -1;
-    }
+    vhost_user_write(dev, &msg, NULL, 0);
 
     return 0;
 }
@@ -358,9 +314,7 @@ static int vhost_set_vring(struct vhost_dev *dev,
         .size = sizeof(msg.payload.state),
     };
 
-    if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
-        return -1;
-    }
+    vhost_user_write(dev, &msg, NULL, 0);
 
     return 0;
 }
@@ -407,12 +361,10 @@ static int vhost_user_get_vring_base(struct vhost_dev *dev,
         .size = sizeof(msg.payload.state),
     };
 
-    if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
-        return -1;
-    }
+    vhost_user_write(dev, &msg, NULL, 0);
 
     if (vhost_user_read(dev, &msg) < 0) {
-        return -1;
+        return 0;
     }
 
     if (msg.request != VHOST_USER_GET_VRING_BASE) {
@@ -450,9 +402,7 @@ static int vhost_set_vring_file(struct vhost_dev *dev,
         msg.payload.u64 |= VHOST_USER_VRING_NOFD_MASK;
     }
 
-    if (vhost_user_write(dev, &msg, fds, fd_num) < 0) {
-        return -1;
-    }
+    vhost_user_write(dev, &msg, fds, fd_num);
 
     return 0;
 }
@@ -478,9 +428,7 @@ static int vhost_user_set_u64(struct vhost_dev *dev, int request, uint64_t u64)
         .size = sizeof(msg.payload.u64),
     };
 
-    if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
-        return -1;
-    }
+    vhost_user_write(dev, &msg, NULL, 0);
 
     return 0;
 }
@@ -508,12 +456,10 @@ static int vhost_user_get_u64(struct vhost_dev *dev, int request, uint64_t *u64)
         return 0;
     }
 
-    if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
-        return -1;
-    }
+    vhost_user_write(dev, &msg, NULL, 0);
 
     if (vhost_user_read(dev, &msg) < 0) {
-        return -1;
+        return 0;
     }
 
     if (msg.request != request) {
@@ -544,9 +490,7 @@ static int vhost_user_set_owner(struct vhost_dev *dev)
         .flags = VHOST_USER_VERSION,
     };
 
-    if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
-        return -1;
-    }
+    vhost_user_write(dev, &msg, NULL, 0);
 
     return 0;
 }
@@ -558,9 +502,7 @@ static int vhost_user_reset_device(struct vhost_dev *dev)
         .flags = VHOST_USER_VERSION,
     };
 
-    if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
-        return -1;
-    }
+    vhost_user_write(dev, &msg, NULL, 0);
 
     return 0;
 }
@@ -647,6 +589,7 @@ static bool vhost_user_requires_shm_log(struct vhost_dev *dev)
 static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr)
 {
     VhostUserMsg msg = { 0 };
+    int err;
 
     assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
 
@@ -663,7 +606,8 @@ static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr)
         memcpy((char *)&msg.payload.u64, mac_addr, 6);
         msg.size = sizeof(msg.payload.u64);
 
-        return vhost_user_write(dev, &msg, NULL, 0);
+        err = vhost_user_write(dev, &msg, NULL, 0);
+        return err;
     }
     return -1;
 }
@@ -672,15 +616,17 @@ static bool vhost_user_can_merge(struct vhost_dev *dev,
                                  uint64_t start1, uint64_t size1,
                                  uint64_t start2, uint64_t size2)
 {
-    ram_addr_t offset;
+    ram_addr_t ram_addr;
     int mfd, rfd;
     MemoryRegion *mr;
 
-    mr = memory_region_from_host((void *)(uintptr_t)start1, &offset);
-    mfd = memory_region_get_fd(mr);
+    mr = qemu_ram_addr_from_host((void *)(uintptr_t)start1, &ram_addr);
+    assert(mr);
+    mfd = qemu_get_ram_fd(ram_addr);
 
-    mr = memory_region_from_host((void *)(uintptr_t)start2, &offset);
-    rfd = memory_region_get_fd(mr);
+    mr = qemu_ram_addr_from_host((void *)(uintptr_t)start2, &ram_addr);
+    assert(mr);
+    rfd = qemu_get_ram_fd(ram_addr);
 
     return mfd == rfd;
 }
index 3d0c807..4400718 100644 (file)
 #include "hw/virtio/virtio-access.h"
 #include "migration/migration.h"
 
-/* enabled until disconnected backend stabilizes */
-#define _VHOST_DEBUG 1
-
-#ifdef _VHOST_DEBUG
-#define VHOST_OPS_DEBUG(fmt, ...) \
-    do { error_report(fmt ": %s (%d)", ## __VA_ARGS__, \
-                      strerror(errno), errno); } while (0)
-#else
-#define VHOST_OPS_DEBUG(fmt, ...) \
-    do { } while (0)
-#endif
-
 static struct vhost_log *vhost_log;
 static struct vhost_log *vhost_log_shm;
 
@@ -374,8 +362,6 @@ static void vhost_log_put(struct vhost_dev *dev, bool sync)
     if (!log) {
         return;
     }
-    dev->log = NULL;
-    dev->log_size = 0;
 
     --log->refcnt;
     if (log->refcnt == 0) {
@@ -412,10 +398,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size)
     /* inform backend of log switching, this must be done before
        releasing the current log, to ensure no logging is lost */
     r = dev->vhost_ops->vhost_set_log_base(dev, log_base, log);
-    if (r < 0) {
-        VHOST_OPS_DEBUG("vhost_set_log_base failed");
-    }
-
+    assert(r >= 0);
     vhost_log_put(dev, true);
     dev->log = log;
     dev->log_size = size;
@@ -439,11 +422,11 @@ static int vhost_verify_ring_mappings(struct vhost_dev *dev,
         l = vq->ring_size;
         p = cpu_physical_memory_map(vq->ring_phys, &l, 1);
         if (!p || l != vq->ring_size) {
-            error_report("Unable to map ring buffer for ring %d", i);
+            fprintf(stderr, "Unable to map ring buffer for ring %d\n", i);
             r = -ENOMEM;
         }
         if (p != vq->ring) {
-            error_report("Ring buffer relocated for ring %d", i);
+            fprintf(stderr, "Ring buffer relocated for ring %d\n", i);
             r = -EBUSY;
         }
         cpu_physical_memory_unmap(p, l, 0, 0);
@@ -582,9 +565,7 @@ static void vhost_commit(MemoryListener *listener)
 
     if (!dev->log_enabled) {
         r = dev->vhost_ops->vhost_set_mem_table(dev, dev->mem);
-        if (r < 0) {
-            VHOST_OPS_DEBUG("vhost_set_mem_table failed");
-        }
+        assert(r >= 0);
         dev->memory_changed = false;
         return;
     }
@@ -597,9 +578,7 @@ static void vhost_commit(MemoryListener *listener)
         vhost_dev_log_resize(dev, log_size + VHOST_LOG_BUFFER);
     }
     r = dev->vhost_ops->vhost_set_mem_table(dev, dev->mem);
-    if (r < 0) {
-        VHOST_OPS_DEBUG("vhost_set_mem_table failed");
-    }
+    assert(r >= 0);
     /* To log less, can only decrease log size after table update. */
     if (dev->log_size > log_size + VHOST_LOG_BUFFER) {
         vhost_dev_log_resize(dev, log_size);
@@ -668,7 +647,6 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
     };
     int r = dev->vhost_ops->vhost_set_vring_addr(dev, &addr);
     if (r < 0) {
-        VHOST_OPS_DEBUG("vhost_set_vring_addr failed");
         return -errno;
     }
     return 0;
@@ -682,15 +660,12 @@ static int vhost_dev_set_features(struct vhost_dev *dev, bool enable_log)
         features |= 0x1ULL << VHOST_F_LOG_ALL;
     }
     r = dev->vhost_ops->vhost_set_features(dev, features);
-    if (r < 0) {
-        VHOST_OPS_DEBUG("vhost_set_features failed");
-    }
     return r < 0 ? -errno : 0;
 }
 
 static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log)
 {
-    int r, i, idx;
+    int r, t, i, idx;
     r = vhost_dev_set_features(dev, enable_log);
     if (r < 0) {
         goto err_features;
@@ -707,10 +682,12 @@ static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log)
 err_vq:
     for (; i >= 0; --i) {
         idx = dev->vhost_ops->vhost_get_vq_index(dev, dev->vq_index + i);
-        vhost_virtqueue_set_addr(dev, dev->vqs + i, idx,
-                                 dev->log_enabled);
+        t = vhost_virtqueue_set_addr(dev, dev->vqs + i, idx,
+                                     dev->log_enabled);
+        assert(t >= 0);
     }
-    vhost_dev_set_features(dev, dev->log_enabled);
+    t = vhost_dev_set_features(dev, dev->log_enabled);
+    assert(t >= 0);
 err_features:
     return r;
 }
@@ -733,6 +710,8 @@ static int vhost_migration_log(MemoryListener *listener, int enable)
             return r;
         }
         vhost_log_put(dev, false);
+        dev->log = NULL;
+        dev->log_size = 0;
     } else {
         vhost_dev_log_resize(dev, vhost_get_log_size(dev));
         r = vhost_dev_set_log(dev, true);
@@ -788,11 +767,15 @@ static inline bool vhost_needs_vring_endian(VirtIODevice *vdev)
     if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
         return false;
     }
+#ifdef TARGET_IS_BIENDIAN
 #ifdef HOST_WORDS_BIGENDIAN
     return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_LITTLE;
 #else
     return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
 #endif
+#else
+    return false;
+#endif
 }
 
 static int vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev,
@@ -808,7 +791,6 @@ static int vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev,
         return 0;
     }
 
-    VHOST_OPS_DEBUG("vhost_set_vring_endian failed");
     if (errno == ENOTTY) {
         error_report("vhost does not support cross-endian");
         return -ENOSYS;
@@ -837,14 +819,12 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
     vq->num = state.num = virtio_queue_get_num(vdev, idx);
     r = dev->vhost_ops->vhost_set_vring_num(dev, &state);
     if (r) {
-        VHOST_OPS_DEBUG("vhost_set_vring_num failed");
         return -errno;
     }
 
     state.num = virtio_queue_get_last_avail_idx(vdev, idx);
     r = dev->vhost_ops->vhost_set_vring_base(dev, &state);
     if (r) {
-        VHOST_OPS_DEBUG("vhost_set_vring_base failed");
         return -errno;
     }
 
@@ -896,7 +876,6 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
     file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq));
     r = dev->vhost_ops->vhost_set_vring_kick(dev, &file);
     if (r) {
-        VHOST_OPS_DEBUG("vhost_set_vring_kick failed");
         r = -errno;
         goto fail_kick;
     }
@@ -944,21 +923,25 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
 
     r = dev->vhost_ops->vhost_get_vring_base(dev, &state);
     if (r < 0) {
-        VHOST_OPS_DEBUG("vhost VQ %d ring restore failed: %d", idx, r);
-    } else {
-        virtio_queue_set_last_avail_idx(vdev, idx, state.num);
+        fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r);
+        fflush(stderr);
     }
+    virtio_queue_set_last_avail_idx(vdev, idx, state.num);
     virtio_queue_invalidate_signalled_used(vdev, idx);
 
     /* In the cross-endian case, we need to reset the vring endianness to
      * native as legacy devices expect so by default.
      */
     if (vhost_needs_vring_endian(vdev)) {
-        vhost_virtqueue_set_vring_endian_legacy(dev,
-                                                !virtio_is_big_endian(vdev),
-                                                vhost_vq_index);
+        r = vhost_virtqueue_set_vring_endian_legacy(dev,
+                                                    !virtio_is_big_endian(vdev),
+                                                    vhost_vq_index);
+        if (r < 0) {
+            error_report("failed to reset vring endianness");
+        }
     }
 
+    assert (r >= 0);
     cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
                               0, virtio_queue_get_ring_size(vdev, idx));
     cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx),
@@ -981,29 +964,6 @@ static void vhost_eventfd_del(MemoryListener *listener,
 {
 }
 
-static int vhost_virtqueue_set_busyloop_timeout(struct vhost_dev *dev,
-                                                int n, uint32_t timeout)
-{
-    int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, n);
-    struct vhost_vring_state state = {
-        .index = vhost_vq_index,
-        .num = timeout,
-    };
-    int r;
-
-    if (!dev->vhost_ops->vhost_set_vring_busyloop_timeout) {
-        return -EINVAL;
-    }
-
-    r = dev->vhost_ops->vhost_set_vring_busyloop_timeout(dev, &state);
-    if (r) {
-        VHOST_OPS_DEBUG("vhost_set_vring_busyloop_timeout failed");
-        return r;
-    }
-
-    return 0;
-}
-
 static int vhost_virtqueue_init(struct vhost_dev *dev,
                                 struct vhost_virtqueue *vq, int n)
 {
@@ -1019,7 +979,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
     file.fd = event_notifier_get_fd(&vq->masked_notifier);
     r = dev->vhost_ops->vhost_set_vring_call(dev, &file);
     if (r) {
-        VHOST_OPS_DEBUG("vhost_set_vring_call failed");
         r = -errno;
         goto fail_call;
     }
@@ -1035,57 +994,47 @@ static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq)
 }
 
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
-                   VhostBackendType backend_type, uint32_t busyloop_timeout)
+                   VhostBackendType backend_type)
 {
     uint64_t features;
-    int i, r, n_initialized_vqs = 0;
+    int i, r;
 
     hdev->migration_blocker = NULL;
 
-    r = vhost_set_backend_type(hdev, backend_type);
-    assert(r >= 0);
+    if (vhost_set_backend_type(hdev, backend_type) < 0) {
+        close((uintptr_t)opaque);
+        return -1;
+    }
 
-    r = hdev->vhost_ops->vhost_backend_init(hdev, opaque);
-    if (r < 0) {
-        goto fail;
+    if (hdev->vhost_ops->vhost_backend_init(hdev, opaque) < 0) {
+        close((uintptr_t)opaque);
+        return -errno;
     }
 
     if (used_memslots > hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) {
-        error_report("vhost backend memory slots limit is less"
-                " than current number of present memory slots");
-        r = -1;
-        goto fail;
+        fprintf(stderr, "vhost backend memory slots limit is less"
+                " than current number of present memory slots\n");
+        close((uintptr_t)opaque);
+        return -1;
     }
+    QLIST_INSERT_HEAD(&vhost_devices, hdev, entry);
 
     r = hdev->vhost_ops->vhost_set_owner(hdev);
     if (r < 0) {
-        VHOST_OPS_DEBUG("vhost_set_owner failed");
         goto fail;
     }
 
     r = hdev->vhost_ops->vhost_get_features(hdev, &features);
     if (r < 0) {
-        VHOST_OPS_DEBUG("vhost_get_features failed");
         goto fail;
     }
 
-    for (i = 0; i < hdev->nvqs; ++i, ++n_initialized_vqs) {
+    for (i = 0; i < hdev->nvqs; ++i) {
         r = vhost_virtqueue_init(hdev, hdev->vqs + i, hdev->vq_index + i);
         if (r < 0) {
-            goto fail;
-        }
-    }
-
-    if (busyloop_timeout) {
-        for (i = 0; i < hdev->nvqs; ++i) {
-            r = vhost_virtqueue_set_busyloop_timeout(hdev, hdev->vq_index + i,
-                                                     busyloop_timeout);
-            if (r < 0) {
-                goto fail_busyloop;
-            }
+            goto fail_vq;
         }
     }
-
     hdev->features = features;
 
     hdev->memory_listener = (MemoryListener) {
@@ -1127,43 +1076,33 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
     hdev->started = false;
     hdev->memory_changed = false;
     memory_listener_register(&hdev->memory_listener, &address_space_memory);
-    QLIST_INSERT_HEAD(&vhost_devices, hdev, entry);
     return 0;
-
-fail_busyloop:
+fail_vq:
     while (--i >= 0) {
-        vhost_virtqueue_set_busyloop_timeout(hdev, hdev->vq_index + i, 0);
+        vhost_virtqueue_cleanup(hdev->vqs + i);
     }
 fail:
-    hdev->nvqs = n_initialized_vqs;
-    vhost_dev_cleanup(hdev);
+    r = -errno;
+    hdev->vhost_ops->vhost_backend_cleanup(hdev);
+    QLIST_REMOVE(hdev, entry);
     return r;
 }
 
 void vhost_dev_cleanup(struct vhost_dev *hdev)
 {
     int i;
-
     for (i = 0; i < hdev->nvqs; ++i) {
         vhost_virtqueue_cleanup(hdev->vqs + i);
     }
-    if (hdev->mem) {
-        /* those are only safe after successful init */
-        memory_listener_unregister(&hdev->memory_listener);
-        QLIST_REMOVE(hdev, entry);
-    }
+    memory_listener_unregister(&hdev->memory_listener);
     if (hdev->migration_blocker) {
         migrate_del_blocker(hdev->migration_blocker);
         error_free(hdev->migration_blocker);
     }
     g_free(hdev->mem);
     g_free(hdev->mem_sections);
-    if (hdev->vhost_ops) {
-        hdev->vhost_ops->vhost_backend_cleanup(hdev);
-    }
-    assert(!hdev->log);
-
-    memset(hdev, 0, sizeof(struct vhost_dev));
+    hdev->vhost_ops->vhost_backend_cleanup(hdev);
+    QLIST_REMOVE(hdev, entry);
 }
 
 /* Stop processing guest IO notifications in qemu.
@@ -1175,18 +1114,16 @@ int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
     VirtioBusState *vbus = VIRTIO_BUS(qbus);
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
     int i, r, e;
-
-    if (!k->ioeventfd_started) {
-        error_report("binding does not support host notifiers");
+    if (!k->set_host_notifier) {
+        fprintf(stderr, "binding does not support host notifiers\n");
         r = -ENOSYS;
         goto fail;
     }
 
     for (i = 0; i < hdev->nvqs; ++i) {
-        r = virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), hdev->vq_index + i,
-                                         true);
+        r = k->set_host_notifier(qbus->parent, hdev->vq_index + i, true);
         if (r < 0) {
-            error_report("vhost VQ %d notifier binding failed: %d", i, -r);
+            fprintf(stderr, "vhost VQ %d notifier binding failed: %d\n", i, -r);
             goto fail_vq;
         }
     }
@@ -1194,10 +1131,10 @@ int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
     return 0;
 fail_vq:
     while (--i >= 0) {
-        e = virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), hdev->vq_index + i,
-                                         false);
+        e = k->set_host_notifier(qbus->parent, hdev->vq_index + i, false);
         if (e < 0) {
-            error_report("vhost VQ %d notifier cleanup error: %d", i, -r);
+            fprintf(stderr, "vhost VQ %d notifier cleanup error: %d\n", i, -r);
+            fflush(stderr);
         }
         assert (e >= 0);
     }
@@ -1213,13 +1150,15 @@ fail:
 void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
 {
     BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+    VirtioBusState *vbus = VIRTIO_BUS(qbus);
+    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
     int i, r;
 
     for (i = 0; i < hdev->nvqs; ++i) {
-        r = virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), hdev->vq_index + i,
-                                         false);
+        r = k->set_host_notifier(qbus->parent, hdev->vq_index + i, false);
         if (r < 0) {
-            error_report("vhost VQ %d notifier cleanup failed: %d", i, -r);
+            fprintf(stderr, "vhost VQ %d notifier cleanup failed: %d\n", i, -r);
+            fflush(stderr);
         }
         assert (r >= 0);
     }
@@ -1243,9 +1182,6 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
     int r, index = n - hdev->vq_index;
     struct vhost_vring_file file;
 
-    /* should only be called after backend is connected */
-    assert(hdev->vhost_ops);
-
     if (mask) {
         assert(vdev->use_guest_notifier_mask);
         file.fd = event_notifier_get_fd(&hdev->vqs[index].masked_notifier);
@@ -1255,9 +1191,7 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
 
     file.index = hdev->vhost_ops->vhost_get_vq_index(hdev, n);
     r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file);
-    if (r < 0) {
-        VHOST_OPS_DEBUG("vhost_set_vring_call failed");
-    }
+    assert(r >= 0);
 }
 
 uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
@@ -1292,9 +1226,6 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
 {
     int i, r;
 
-    /* should only be called after backend is connected */
-    assert(hdev->vhost_ops);
-
     hdev->started = true;
 
     r = vhost_dev_set_features(hdev, hdev->log_enabled);
@@ -1303,7 +1234,6 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
     }
     r = hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem);
     if (r < 0) {
-        VHOST_OPS_DEBUG("vhost_set_mem_table failed");
         r = -errno;
         goto fail_mem;
     }
@@ -1328,7 +1258,6 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
                                                 hdev->log_size ? log_base : 0,
                                                 hdev->log);
         if (r < 0) {
-            VHOST_OPS_DEBUG("vhost_set_log_base failed");
             r = -errno;
             goto fail_log;
         }
@@ -1357,9 +1286,6 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
 {
     int i;
 
-    /* should only be called after backend is connected */
-    assert(hdev->vhost_ops);
-
     for (i = 0; i < hdev->nvqs; ++i) {
         vhost_virtqueue_stop(hdev,
                              vdev,
@@ -1369,14 +1295,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
 
     vhost_log_put(hdev, true);
     hdev->started = false;
+    hdev->log = NULL;
+    hdev->log_size = 0;
 }
 
-int vhost_net_set_backend(struct vhost_dev *hdev,
-                          struct vhost_vring_file *file)
-{
-    if (hdev->vhost_ops->vhost_net_set_backend) {
-        return hdev->vhost_ops->vhost_net_set_backend(hdev, file);
-    }
-
-    return -1;
-}
index 5af429a..9dbe681 100644 (file)
 #include "qapi-event.h"
 #include "trace.h"
 
+#if defined(__linux__)
+#include <sys/mman.h>
+#endif
+
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/virtio-access.h"
 
@@ -134,18 +138,17 @@ static void balloon_stats_get_all(Object *obj, Visitor *v, const char *name,
     for (i = 0; i < VIRTIO_BALLOON_S_NR; i++) {
         visit_type_uint64(v, balloon_stat_names[i], &s->stats[i], &err);
         if (err) {
-            goto out_nested;
+            break;
         }
     }
-    visit_check_struct(v, &err);
-out_nested:
-    visit_end_struct(v, NULL);
+    error_propagate(errp, err);
+    err = NULL;
+    visit_end_struct(v, &err);
 
-    if (!err) {
-        visit_check_struct(v, &err);
-    }
 out_end:
-    visit_end_struct(v, NULL);
+    error_propagate(errp, err);
+    err = NULL;
+    visit_end_struct(v, &err);
 out:
     error_propagate(errp, err);
 }
@@ -396,6 +399,11 @@ static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
     trace_virtio_balloon_to_target(target, dev->num_pages);
 }
 
+static void virtio_balloon_save(QEMUFile *f, void *opaque)
+{
+    virtio_save(VIRTIO_DEVICE(opaque), f);
+}
+
 static void virtio_balloon_save_device(VirtIODevice *vdev, QEMUFile *f)
 {
     VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
@@ -404,9 +412,12 @@ static void virtio_balloon_save_device(VirtIODevice *vdev, QEMUFile *f)
     qemu_put_be32(f, s->actual);
 }
 
-static int virtio_balloon_load(QEMUFile *f, void *opaque, size_t size)
+static int virtio_balloon_load(QEMUFile *f, void *opaque, int version_id)
 {
-    return virtio_load(VIRTIO_DEVICE(opaque), f, 1);
+    if (version_id != 1)
+        return -EINVAL;
+
+    return virtio_load(VIRTIO_DEVICE(opaque), f, version_id);
 }
 
 static int virtio_balloon_load_device(VirtIODevice *vdev, QEMUFile *f,
@@ -446,6 +457,9 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp)
     s->svq = virtio_add_queue(vdev, 128, virtio_balloon_receive_stats);
 
     reset_stats(s);
+
+    register_savevm(dev, "virtio-balloon", -1, 1,
+                    virtio_balloon_save, virtio_balloon_load, s);
 }
 
 static void virtio_balloon_device_unrealize(DeviceState *dev, Error **errp)
@@ -455,6 +469,7 @@ static void virtio_balloon_device_unrealize(DeviceState *dev, Error **errp)
 
     balloon_stats_destroy_timer(s);
     qemu_remove_balloon_handler(s);
+    unregister_savevm(dev, "virtio-balloon", s);
     virtio_cleanup(vdev);
 }
 
@@ -481,8 +496,6 @@ static void virtio_balloon_instance_init(Object *obj)
                         NULL, s, NULL);
 }
 
-VMSTATE_VIRTIO_DEVICE(balloon, 1, virtio_balloon_load, virtio_vmstate_save);
-
 static Property virtio_balloon_properties[] = {
     DEFINE_PROP_BIT("deflate-on-oom", VirtIOBalloon, host_features,
                     VIRTIO_BALLOON_F_DEFLATE_ON_OOM, false),
@@ -495,7 +508,6 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data)
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
 
     dc->props = virtio_balloon_properties;
-    dc->vmsd = &vmstate_virtio_balloon;
     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
     vdc->realize = virtio_balloon_device_realize;
     vdc->unrealize = virtio_balloon_device_unrealize;
index a85b7c8..574f0e2 100644 (file)
@@ -146,132 +146,6 @@ void virtio_bus_set_vdev_config(VirtioBusState *bus, uint8_t *config)
     }
 }
 
-/*
- * This function handles both assigning the ioeventfd handler and
- * registering it with the kernel.
- * assign: register/deregister ioeventfd with the kernel
- * set_handler: use the generic ioeventfd handler
- */
-static int set_host_notifier_internal(DeviceState *proxy, VirtioBusState *bus,
-                                      int n, bool assign, bool set_handler)
-{
-    VirtIODevice *vdev = virtio_bus_get_device(bus);
-    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(bus);
-    VirtQueue *vq = virtio_get_queue(vdev, n);
-    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
-    int r = 0;
-
-    if (assign) {
-        r = event_notifier_init(notifier, 1);
-        if (r < 0) {
-            error_report("%s: unable to init event notifier: %d", __func__, r);
-            return r;
-        }
-        virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
-        r = k->ioeventfd_assign(proxy, notifier, n, assign);
-        if (r < 0) {
-            error_report("%s: unable to assign ioeventfd: %d", __func__, r);
-            virtio_queue_set_host_notifier_fd_handler(vq, false, false);
-            event_notifier_cleanup(notifier);
-            return r;
-        }
-    } else {
-        k->ioeventfd_assign(proxy, notifier, n, assign);
-        virtio_queue_set_host_notifier_fd_handler(vq, false, false);
-        event_notifier_cleanup(notifier);
-    }
-    return r;
-}
-
-void virtio_bus_start_ioeventfd(VirtioBusState *bus)
-{
-    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(bus);
-    DeviceState *proxy = DEVICE(BUS(bus)->parent);
-    VirtIODevice *vdev;
-    int n, r;
-
-    if (!k->ioeventfd_started || k->ioeventfd_started(proxy)) {
-        return;
-    }
-    if (k->ioeventfd_disabled(proxy)) {
-        return;
-    }
-    vdev = virtio_bus_get_device(bus);
-    for (n = 0; n < VIRTIO_QUEUE_MAX; n++) {
-        if (!virtio_queue_get_num(vdev, n)) {
-            continue;
-        }
-        r = set_host_notifier_internal(proxy, bus, n, true, true);
-        if (r < 0) {
-            goto assign_error;
-        }
-    }
-    k->ioeventfd_set_started(proxy, true, false);
-    return;
-
-assign_error:
-    while (--n >= 0) {
-        if (!virtio_queue_get_num(vdev, n)) {
-            continue;
-        }
-
-        r = set_host_notifier_internal(proxy, bus, n, false, false);
-        assert(r >= 0);
-    }
-    k->ioeventfd_set_started(proxy, false, true);
-    error_report("%s: failed. Fallback to userspace (slower).", __func__);
-}
-
-void virtio_bus_stop_ioeventfd(VirtioBusState *bus)
-{
-    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(bus);
-    DeviceState *proxy = DEVICE(BUS(bus)->parent);
-    VirtIODevice *vdev;
-    int n, r;
-
-    if (!k->ioeventfd_started || !k->ioeventfd_started(proxy)) {
-        return;
-    }
-    vdev = virtio_bus_get_device(bus);
-    for (n = 0; n < VIRTIO_QUEUE_MAX; n++) {
-        if (!virtio_queue_get_num(vdev, n)) {
-            continue;
-        }
-        r = set_host_notifier_internal(proxy, bus, n, false, false);
-        assert(r >= 0);
-    }
-    k->ioeventfd_set_started(proxy, false, false);
-}
-
-/*
- * This function switches from/to the generic ioeventfd handler.
- * assign==false means 'use generic ioeventfd handler'.
- */
-int virtio_bus_set_host_notifier(VirtioBusState *bus, int n, bool assign)
-{
-    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(bus);
-    DeviceState *proxy = DEVICE(BUS(bus)->parent);
-
-    if (!k->ioeventfd_started) {
-        return -ENOSYS;
-    }
-    k->ioeventfd_set_disabled(proxy, assign);
-    if (assign) {
-        /*
-         * Stop using the generic ioeventfd, we are doing eventfd handling
-         * ourselves below
-         *
-         * FIXME: We should just switch the handler and not deassign the
-         * ioeventfd.
-         * Otherwise, there's a window where we don't have an
-         * ioeventfd and we may end up with a notification where
-         * we don't expect one.
-         */
-        virtio_bus_stop_ioeventfd(bus);
-    }
-    return set_host_notifier_internal(proxy, bus, n, assign, false);
-}
-
 static char *virtio_bus_get_dev_path(DeviceState *dev)
 {
     BusState *bus = qdev_get_parent_bus(dev);
index 13798b3..d4cd91f 100644 (file)
@@ -91,62 +91,92 @@ typedef struct {
     VirtioBusState bus;
     bool ioeventfd_disabled;
     bool ioeventfd_started;
-    bool format_transport_address;
 } VirtIOMMIOProxy;
 
-static bool virtio_mmio_ioeventfd_started(DeviceState *d)
+static int virtio_mmio_set_host_notifier_internal(VirtIOMMIOProxy *proxy,
+                                                  int n, bool assign,
+                                                  bool set_handler)
 {
-    VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
-
-    return proxy->ioeventfd_started;
-}
-
-static void virtio_mmio_ioeventfd_set_started(DeviceState *d, bool started,
-                                              bool err)
-{
-    VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
-
-    proxy->ioeventfd_started = started;
-}
-
-static bool virtio_mmio_ioeventfd_disabled(DeviceState *d)
-{
-    VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
-
-    return !kvm_eventfds_enabled() || proxy->ioeventfd_disabled;
-}
-
-static void virtio_mmio_ioeventfd_set_disabled(DeviceState *d, bool disabled)
-{
-    VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
-
-    proxy->ioeventfd_disabled = disabled;
-}
-
-static int virtio_mmio_ioeventfd_assign(DeviceState *d,
-                                        EventNotifier *notifier,
-                                        int n, bool assign)
-{
-    VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+    VirtQueue *vq = virtio_get_queue(vdev, n);
+    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
+    int r = 0;
 
     if (assign) {
+        r = event_notifier_init(notifier, 1);
+        if (r < 0) {
+            error_report("%s: unable to init event notifier: %d",
+                         __func__, r);
+            return r;
+        }
+        virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
         memory_region_add_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUENOTIFY, 4,
                                   true, n, notifier);
     } else {
         memory_region_del_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUENOTIFY, 4,
                                   true, n, notifier);
+        virtio_queue_set_host_notifier_fd_handler(vq, false, false);
+        event_notifier_cleanup(notifier);
     }
-    return 0;
+    return r;
 }
 
 static void virtio_mmio_start_ioeventfd(VirtIOMMIOProxy *proxy)
 {
-    virtio_bus_start_ioeventfd(&proxy->bus);
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+    int n, r;
+
+    if (!kvm_eventfds_enabled() ||
+        proxy->ioeventfd_disabled ||
+        proxy->ioeventfd_started) {
+        return;
+    }
+
+    for (n = 0; n < VIRTIO_QUEUE_MAX; n++) {
+        if (!virtio_queue_get_num(vdev, n)) {
+            continue;
+        }
+
+        r = virtio_mmio_set_host_notifier_internal(proxy, n, true, true);
+        if (r < 0) {
+            goto assign_error;
+        }
+    }
+    proxy->ioeventfd_started = true;
+    return;
+
+assign_error:
+    while (--n >= 0) {
+        if (!virtio_queue_get_num(vdev, n)) {
+            continue;
+        }
+
+        r = virtio_mmio_set_host_notifier_internal(proxy, n, false, false);
+        assert(r >= 0);
+    }
+    proxy->ioeventfd_started = false;
+    error_report("%s: failed. Fallback to a userspace (slower).", __func__);
 }
 
 static void virtio_mmio_stop_ioeventfd(VirtIOMMIOProxy *proxy)
 {
-    virtio_bus_stop_ioeventfd(&proxy->bus);
+    int r;
+    int n;
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+
+    if (!proxy->ioeventfd_started) {
+        return;
+    }
+
+    for (n = 0; n < VIRTIO_QUEUE_MAX; n++) {
+        if (!virtio_queue_get_num(vdev, n)) {
+            continue;
+        }
+
+        r = virtio_mmio_set_host_notifier_internal(proxy, n, false, false);
+        assert(r >= 0);
+    }
+    proxy->ioeventfd_started = false;
 }
 
 static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size)
@@ -468,13 +498,26 @@ assign_error:
     return r;
 }
 
-/* virtio-mmio device */
+static int virtio_mmio_set_host_notifier(DeviceState *opaque, int n,
+                                         bool assign)
+{
+    VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
 
-static Property virtio_mmio_properties[] = {
-    DEFINE_PROP_BOOL("format_transport_address", VirtIOMMIOProxy,
-                     format_transport_address, true),
-    DEFINE_PROP_END_OF_LIST(),
-};
+    /* Stop using ioeventfd for virtqueue kick if the device starts using host
+     * notifiers.  This makes it easy to avoid stepping on each others' toes.
+     */
+    proxy->ioeventfd_disabled = assign;
+    if (assign) {
+        virtio_mmio_stop_ioeventfd(proxy);
+    }
+    /* We don't need to start here: it's not needed because backend
+     * currently only stops on status change away from ok,
+     * reset, vmstop and such. If we do add code to start here,
+     * need to check vmstate, device state etc. */
+    return virtio_mmio_set_host_notifier_internal(proxy, n, assign, false);
+}
+
+/* virtio-mmio device */
 
 static void virtio_mmio_realizefn(DeviceState *d, Error **errp)
 {
@@ -496,7 +539,6 @@ static void virtio_mmio_class_init(ObjectClass *klass, void *data)
     dc->realize = virtio_mmio_realizefn;
     dc->reset = virtio_mmio_reset;
     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
-    dc->props = virtio_mmio_properties;
 }
 
 static const TypeInfo virtio_mmio_info = {
@@ -508,46 +550,6 @@ static const TypeInfo virtio_mmio_info = {
 
 /* virtio-mmio-bus. */
 
-static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
-{
-    BusState *virtio_mmio_bus;
-    VirtIOMMIOProxy *virtio_mmio_proxy;
-    char *proxy_path;
-    SysBusDevice *proxy_sbd;
-    char *path;
-
-    virtio_mmio_bus = qdev_get_parent_bus(dev);
-    virtio_mmio_proxy = VIRTIO_MMIO(virtio_mmio_bus->parent);
-    proxy_path = qdev_get_dev_path(DEVICE(virtio_mmio_proxy));
-
-    /*
-     * If @format_transport_address is false, then we just perform the same as
-     * virtio_bus_get_dev_path(): we delegate the address formatting for the
-     * device on the virtio-mmio bus to the bus that the virtio-mmio proxy
-     * (i.e., the device that implements the virtio-mmio bus) resides on. In
-     * this case the base address of the virtio-mmio transport will be
-     * invisible.
-     */
-    if (!virtio_mmio_proxy->format_transport_address) {
-        return proxy_path;
-    }
-
-    /* Otherwise, we append the base address of the transport. */
-    proxy_sbd = SYS_BUS_DEVICE(virtio_mmio_proxy);
-    assert(proxy_sbd->num_mmio == 1);
-    assert(proxy_sbd->mmio[0].memory == &virtio_mmio_proxy->iomem);
-
-    if (proxy_path) {
-        path = g_strdup_printf("%s/virtio-mmio@" TARGET_FMT_plx, proxy_path,
-                               proxy_sbd->mmio[0].addr);
-    } else {
-        path = g_strdup_printf("virtio-mmio@" TARGET_FMT_plx,
-                               proxy_sbd->mmio[0].addr);
-    }
-    g_free(proxy_path);
-    return path;
-}
-
 static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data)
 {
     BusClass *bus_class = BUS_CLASS(klass);
@@ -556,15 +558,10 @@ static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data)
     k->notify = virtio_mmio_update_irq;
     k->save_config = virtio_mmio_save_config;
     k->load_config = virtio_mmio_load_config;
+    k->set_host_notifier = virtio_mmio_set_host_notifier;
     k->set_guest_notifiers = virtio_mmio_set_guest_notifiers;
-    k->ioeventfd_started = virtio_mmio_ioeventfd_started;
-    k->ioeventfd_set_started = virtio_mmio_ioeventfd_set_started;
-    k->ioeventfd_disabled = virtio_mmio_ioeventfd_disabled;
-    k->ioeventfd_set_disabled = virtio_mmio_ioeventfd_set_disabled;
-    k->ioeventfd_assign = virtio_mmio_ioeventfd_assign;
     k->has_variable_vring_alignment = true;
     bus_class->max_dev = 1;
-    bus_class->get_dev_path = virtio_mmio_bus_get_dev_path;
 }
 
 static const TypeInfo virtio_mmio_bus_info = {
index 755f921..bfedbbf 100644 (file)
@@ -161,7 +161,7 @@ static bool virtio_pci_modern_state_needed(void *opaque)
 {
     VirtIOPCIProxy *proxy = opaque;
 
-    return virtio_pci_modern(proxy);
+    return !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_MODERN);
 }
 
 static const VMStateDescription vmstate_virtio_pci_modern_state = {
@@ -262,46 +262,16 @@ static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f)
     return 0;
 }
 
-static bool virtio_pci_ioeventfd_started(DeviceState *d)
-{
-    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
-
-    return proxy->ioeventfd_started;
-}
-
-static void virtio_pci_ioeventfd_set_started(DeviceState *d, bool started,
-                                             bool err)
-{
-    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
-
-    proxy->ioeventfd_started = started;
-}
-
-static bool virtio_pci_ioeventfd_disabled(DeviceState *d)
-{
-    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
-
-    return proxy->ioeventfd_disabled ||
-        !(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD);
-}
-
-static void virtio_pci_ioeventfd_set_disabled(DeviceState *d, bool disabled)
-{
-    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
-
-    proxy->ioeventfd_disabled = disabled;
-}
-
 #define QEMU_VIRTIO_PCI_QUEUE_MEM_MULT 0x1000
 
-static int virtio_pci_ioeventfd_assign(DeviceState *d, EventNotifier *notifier,
-                                       int n, bool assign)
+static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
+                                                 int n, bool assign, bool set_handler)
 {
-    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
     VirtQueue *vq = virtio_get_queue(vdev, n);
-    bool legacy = virtio_pci_legacy(proxy);
-    bool modern = virtio_pci_modern(proxy);
+    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
+    bool legacy = !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_LEGACY);
+    bool modern = !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_MODERN);
     bool fast_mmio = kvm_ioeventfd_any_length_enabled();
     bool modern_pio = proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY;
     MemoryRegion *modern_mr = &proxy->notify.mr;
@@ -310,8 +280,16 @@ static int virtio_pci_ioeventfd_assign(DeviceState *d, EventNotifier *notifier,
     hwaddr modern_addr = QEMU_VIRTIO_PCI_QUEUE_MEM_MULT *
                          virtio_get_queue_index(vq);
     hwaddr legacy_addr = VIRTIO_PCI_QUEUE_NOTIFY;
+    int r = 0;
 
     if (assign) {
+        r = event_notifier_init(notifier, 1);
+        if (r < 0) {
+            error_report("%s: unable to init event notifier: %d",
+                         __func__, r);
+            return r;
+        }
+        virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
         if (modern) {
             if (fast_mmio) {
                 memory_region_add_eventfd(modern_mr, modern_addr, 0,
@@ -347,18 +325,68 @@ static int virtio_pci_ioeventfd_assign(DeviceState *d, EventNotifier *notifier,
             memory_region_del_eventfd(legacy_mr, legacy_addr, 2,
                                       true, n, notifier);
         }
+        virtio_queue_set_host_notifier_fd_handler(vq, false, false);
+        event_notifier_cleanup(notifier);
     }
-    return 0;
+    return r;
 }
 
 static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
 {
-    virtio_bus_start_ioeventfd(&proxy->bus);
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+    int n, r;
+
+    if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) ||
+        proxy->ioeventfd_disabled ||
+        proxy->ioeventfd_started) {
+        return;
+    }
+
+    for (n = 0; n < VIRTIO_QUEUE_MAX; n++) {
+        if (!virtio_queue_get_num(vdev, n)) {
+            continue;
+        }
+
+        r = virtio_pci_set_host_notifier_internal(proxy, n, true, true);
+        if (r < 0) {
+            goto assign_error;
+        }
+    }
+    proxy->ioeventfd_started = true;
+    return;
+
+assign_error:
+    while (--n >= 0) {
+        if (!virtio_queue_get_num(vdev, n)) {
+            continue;
+        }
+
+        r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
+        assert(r >= 0);
+    }
+    proxy->ioeventfd_started = false;
+    error_report("%s: failed. Fallback to a userspace (slower).", __func__);
 }
 
 static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
 {
-    virtio_bus_stop_ioeventfd(&proxy->bus);
+    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+    int r;
+    int n;
+
+    if (!proxy->ioeventfd_started) {
+        return;
+    }
+
+    for (n = 0; n < VIRTIO_QUEUE_MAX; n++) {
+        if (!virtio_queue_get_num(vdev, n)) {
+            continue;
+        }
+
+        r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
+        assert(r >= 0);
+    }
+    proxy->ioeventfd_started = false;
 }
 
 static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
@@ -699,13 +727,14 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev,
 
 static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
                                         unsigned int queue_no,
-                                        unsigned int vector)
+                                        unsigned int vector,
+                                        MSIMessage msg)
 {
     VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
     int ret;
 
     if (irqfd->users == 0) {
-        ret = kvm_irqchip_add_msi_route(kvm_state, vector, &proxy->pci_dev);
+        ret = kvm_irqchip_add_msi_route(kvm_state, msg, &proxy->pci_dev);
         if (ret < 0) {
             return ret;
         }
@@ -732,7 +761,9 @@ static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
     VirtQueue *vq = virtio_get_queue(vdev, queue_no);
     EventNotifier *n = virtio_queue_get_guest_notifier(vq);
-    return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq);
+    int ret;
+    ret = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq);
+    return ret;
 }
 
 static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
@@ -756,6 +787,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
     unsigned int vector;
     int ret, queue_no;
+    MSIMessage msg;
 
     for (queue_no = 0; queue_no < nvqs; queue_no++) {
         if (!virtio_queue_get_num(vdev, queue_no)) {
@@ -765,7 +797,8 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
         if (vector >= msix_nr_vectors_allocated(dev)) {
             continue;
         }
-        ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector);
+        msg = msix_get_message(dev, vector);
+        ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector, msg);
         if (ret < 0) {
             goto undo;
         }
@@ -842,7 +875,6 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
             if (ret < 0) {
                 return ret;
             }
-            kvm_irqchip_commit_routes(kvm_state);
         }
     }
 
@@ -1080,6 +1112,24 @@ assign_error:
     return r;
 }
 
+static int virtio_pci_set_host_notifier(DeviceState *d, int n, bool assign)
+{
+    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
+
+    /* Stop using ioeventfd for virtqueue kick if the device starts using host
+     * notifiers.  This makes it easy to avoid stepping on each others' toes.
+     */
+    proxy->ioeventfd_disabled = assign;
+    if (assign) {
+        virtio_pci_stop_ioeventfd(proxy);
+    }
+    /* We don't need to start here: it's not needed because backend
+     * currently only stops on status change away from ok,
+     * reset, vmstop and such. If we do add code to start here,
+     * need to check vmstate, device state etc. */
+    return virtio_pci_set_host_notifier_internal(proxy, n, assign, false);
+}
+
 static void virtio_pci_vmstate_change(DeviceState *d, bool running)
 {
     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
@@ -1574,8 +1624,8 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
 {
     VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
     VirtioBusState *bus = &proxy->bus;
-    bool legacy = virtio_pci_legacy(proxy);
-    bool modern = virtio_pci_modern(proxy);
+    bool legacy = !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_LEGACY);
+    bool modern = !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_MODERN);
     bool modern_pio = proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY;
     uint8_t *config;
     uint32_t size;
@@ -1694,7 +1744,7 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
 static void virtio_pci_device_unplugged(DeviceState *d)
 {
     VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
-    bool modern = virtio_pci_modern(proxy);
+    bool modern = !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_MODERN);
     bool modern_pio = proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY;
 
     virtio_pci_stop_ioeventfd(proxy);
@@ -1714,8 +1764,6 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
 {
     VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
     VirtioPCIClass *k = VIRTIO_PCI_GET_CLASS(pci_dev);
-    bool pcie_port = pci_bus_is_express(pci_dev->bus) &&
-                     !pci_bus_is_root(pci_dev->bus);
 
     /*
      * virtio pci bar layout used by default.
@@ -1766,11 +1814,8 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
 
     address_space_init(&proxy->modern_as, &proxy->modern_cfg, "virtio-pci-cfg-as");
 
-    if (proxy->disable_legacy == ON_OFF_AUTO_AUTO) {
-        proxy->disable_legacy = pcie_port ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
-    }
-
-    if (pcie_port && pci_is_express(pci_dev)) {
+    if (pci_is_express(pci_dev) && pci_bus_is_express(pci_dev->bus) &&
+        !pci_bus_is_root(pci_dev->bus)) {
         int pos;
 
         pos = pcie_endpoint_cap_init(pci_dev, 0);
@@ -1824,9 +1869,10 @@ static void virtio_pci_reset(DeviceState *qdev)
 static Property virtio_pci_properties[] = {
     DEFINE_PROP_BIT("virtio-pci-bus-master-bug-migration", VirtIOPCIProxy, flags,
                     VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT, false),
-    DEFINE_PROP_ON_OFF_AUTO("disable-legacy", VirtIOPCIProxy, disable_legacy,
-                            ON_OFF_AUTO_AUTO),
-    DEFINE_PROP_BOOL("disable-modern", VirtIOPCIProxy, disable_modern, false),
+    DEFINE_PROP_BIT("disable-legacy", VirtIOPCIProxy, flags,
+                    VIRTIO_PCI_FLAG_DISABLE_LEGACY_BIT, false),
+    DEFINE_PROP_BIT("disable-modern", VirtIOPCIProxy, flags,
+                    VIRTIO_PCI_FLAG_DISABLE_MODERN_BIT, true),
     DEFINE_PROP_BIT("migrate-extra", VirtIOPCIProxy, flags,
                     VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT, true),
     DEFINE_PROP_BIT("modern-pio-notify", VirtIOPCIProxy, flags,
@@ -1843,7 +1889,7 @@ static void virtio_pci_dc_realize(DeviceState *qdev, Error **errp)
     PCIDevice *pci_dev = &proxy->pci_dev;
 
     if (!(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_PCIE) &&
-        virtio_pci_modern(proxy)) {
+        !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_MODERN)) {
         pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
     }
 
@@ -2305,7 +2351,9 @@ static void virtio_input_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
     DeviceState *vdev = DEVICE(&vinput->vdev);
 
     qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    virtio_pci_force_virtio_1(vpci_dev);
+    /* force virtio-1.0 */
+    vpci_dev->flags &= ~VIRTIO_PCI_FLAG_DISABLE_MODERN;
+    vpci_dev->flags |= VIRTIO_PCI_FLAG_DISABLE_LEGACY;
     object_property_set_bool(OBJECT(vdev), true, "realized", errp);
 }
 
@@ -2442,16 +2490,12 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
     k->load_extra_state = virtio_pci_load_extra_state;
     k->has_extra_state = virtio_pci_has_extra_state;
     k->query_guest_notifiers = virtio_pci_query_guest_notifiers;
+    k->set_host_notifier = virtio_pci_set_host_notifier;
     k->set_guest_notifiers = virtio_pci_set_guest_notifiers;
     k->vmstate_change = virtio_pci_vmstate_change;
     k->device_plugged = virtio_pci_device_plugged;
     k->device_unplugged = virtio_pci_device_unplugged;
     k->query_nvectors = virtio_pci_query_nvectors;
-    k->ioeventfd_started = virtio_pci_ioeventfd_started;
-    k->ioeventfd_set_started = virtio_pci_ioeventfd_set_started;
-    k->ioeventfd_disabled = virtio_pci_ioeventfd_disabled;
-    k->ioeventfd_set_disabled = virtio_pci_ioeventfd_set_disabled;
-    k->ioeventfd_assign = virtio_pci_ioeventfd_assign;
 }
 
 static const TypeInfo virtio_pci_bus_info = {
index 25fbf8a..e4548c2 100644 (file)
@@ -61,6 +61,8 @@ typedef struct VirtioBusClass VirtioPCIBusClass;
 enum {
     VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT,
     VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT,
+    VIRTIO_PCI_FLAG_DISABLE_LEGACY_BIT,
+    VIRTIO_PCI_FLAG_DISABLE_MODERN_BIT,
     VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT,
     VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT,
     VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT,
@@ -75,6 +77,8 @@ enum {
 #define VIRTIO_PCI_FLAG_USE_IOEVENTFD   (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT)
 
 /* virtio version flags */
+#define VIRTIO_PCI_FLAG_DISABLE_LEGACY (1 << VIRTIO_PCI_FLAG_DISABLE_LEGACY_BIT)
+#define VIRTIO_PCI_FLAG_DISABLE_MODERN (1 << VIRTIO_PCI_FLAG_DISABLE_MODERN_BIT)
 #define VIRTIO_PCI_FLAG_DISABLE_PCIE (1 << VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT)
 
 /* migrate extra state */
@@ -140,8 +144,6 @@ struct VirtIOPCIProxy {
     uint32_t modern_mem_bar;
     int config_cap;
     uint32_t flags;
-    bool disable_modern;
-    OnOffAuto disable_legacy;
     uint32_t class_code;
     uint32_t nvectors;
     uint32_t dfselect;
@@ -156,21 +158,6 @@ struct VirtIOPCIProxy {
     VirtioBusState bus;
 };
 
-static inline bool virtio_pci_modern(VirtIOPCIProxy *proxy)
-{
-    return !proxy->disable_modern;
-}
-
-static inline bool virtio_pci_legacy(VirtIOPCIProxy *proxy)
-{
-    return proxy->disable_legacy == ON_OFF_AUTO_OFF;
-}
-
-static inline void virtio_pci_force_virtio_1(VirtIOPCIProxy *proxy)
-{
-    proxy->disable_modern = false;
-    proxy->disable_legacy = ON_OFF_AUTO_ON;
-}
 
 /*
  * virtio-scsi-pci: This extends VirtioPCIProxy.
index cd8ca10..6b991a7 100644 (file)
@@ -120,12 +120,22 @@ static uint64_t get_features(VirtIODevice *vdev, uint64_t f, Error **errp)
     return f;
 }
 
-static int virtio_rng_load(QEMUFile *f, void *opaque, size_t size)
+static void virtio_rng_save(QEMUFile *f, void *opaque)
+{
+    VirtIODevice *vdev = opaque;
+
+    virtio_save(vdev, f);
+}
+
+static int virtio_rng_load(QEMUFile *f, void *opaque, int version_id)
 {
     VirtIORNG *vrng = opaque;
     int ret;
 
-    ret = virtio_load(VIRTIO_DEVICE(vrng), f, 1);
+    if (version_id != 1) {
+        return -EINVAL;
+    }
+    ret = virtio_load(VIRTIO_DEVICE(vrng), f, version_id);
     if (ret != 0) {
         return ret;
     }
@@ -204,6 +214,8 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp)
     vrng->rate_limit_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
                                                check_rate_limit, vrng);
     vrng->activate_timer = true;
+    register_savevm(dev, "virtio-rng", -1, 1, virtio_rng_save,
+                    virtio_rng_load, vrng);
 }
 
 static void virtio_rng_device_unrealize(DeviceState *dev, Error **errp)
@@ -213,11 +225,10 @@ static void virtio_rng_device_unrealize(DeviceState *dev, Error **errp)
 
     timer_del(vrng->rate_limit_timer);
     timer_free(vrng->rate_limit_timer);
+    unregister_savevm(dev, "virtio-rng", vrng);
     virtio_cleanup(vdev);
 }
 
-VMSTATE_VIRTIO_DEVICE(rng, 1, virtio_rng_load, virtio_vmstate_save);
-
 static Property virtio_rng_properties[] = {
     /* Set a default rate limit of 2^47 bytes per minute or roughly 2TB/s.  If
      * you have an entropy source capable of generating more entropy than this
@@ -235,7 +246,6 @@ static void virtio_rng_class_init(ObjectClass *klass, void *data)
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
 
     dc->props = virtio_rng_properties;
-    dc->vmsd = &vmstate_virtio_rng;
     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
     vdc->realize = virtio_rng_device_realize;
     vdc->unrealize = virtio_rng_device_unrealize;
index 74c085c..8ed260a 100644 (file)
@@ -95,9 +95,8 @@ struct VirtQueue
     int inuse;
 
     uint16_t vector;
-    VirtIOHandleOutput handle_output;
-    VirtIOHandleOutput handle_aio_output;
-    bool use_aio;
+    void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
+    void (*handle_aio_output)(VirtIODevice *vdev, VirtQueue *vq);
     VirtIODevice *vdev;
     EventNotifier guest_notifier;
     EventNotifier host_notifier;
@@ -268,7 +267,6 @@ void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
                        unsigned int len)
 {
     vq->last_avail_idx--;
-    vq->inuse--;
     virtqueue_unmap_sg(vq, elem, len);
 }
 
@@ -459,11 +457,6 @@ static void virtqueue_map_desc(unsigned int *p_num_sg, hwaddr *addr, struct iove
     unsigned num_sg = *p_num_sg;
     assert(num_sg <= max_num_sg);
 
-    if (!sz) {
-        error_report("virtio: zero sized buffers are not allowed");
-        exit(1);
-    }
-
     while (sz) {
         hwaddr len = sz;
 
@@ -1074,6 +1067,13 @@ int virtio_get_num_queues(VirtIODevice *vdev)
     return i;
 }
 
+int virtio_queue_get_id(VirtQueue *vq)
+{
+    VirtIODevice *vdev = vq->vdev;
+    assert(vq >= &vdev->vq[0] && vq < &vdev->vq[VIRTIO_QUEUE_MAX]);
+    return vq - &vdev->vq[0];
+}
+
 void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
 {
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
@@ -1142,9 +1142,8 @@ void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector)
     }
 }
 
-static VirtQueue *virtio_add_queue_internal(VirtIODevice *vdev, int queue_size,
-                                            VirtIOHandleOutput handle_output,
-                                            bool use_aio)
+VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
+                            void (*handle_output)(VirtIODevice *, VirtQueue *))
 {
     int i;
 
@@ -1161,28 +1160,10 @@ static VirtQueue *virtio_add_queue_internal(VirtIODevice *vdev, int queue_size,
     vdev->vq[i].vring.align = VIRTIO_PCI_VRING_ALIGN;
     vdev->vq[i].handle_output = handle_output;
     vdev->vq[i].handle_aio_output = NULL;
-    vdev->vq[i].use_aio = use_aio;
 
     return &vdev->vq[i];
 }
 
-/* Add a virt queue and mark AIO.
- * An AIO queue will use the AioContext based event interface instead of the
- * default IOHandler and EventNotifier interface.
- */
-VirtQueue *virtio_add_queue_aio(VirtIODevice *vdev, int queue_size,
-                                VirtIOHandleOutput handle_output)
-{
-    return virtio_add_queue_internal(vdev, queue_size, handle_output, true);
-}
-
-/* Add a normal virt queue (on the contrary to the AIO version above. */
-VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
-                            VirtIOHandleOutput handle_output)
-{
-    return virtio_add_queue_internal(vdev, queue_size, handle_output, false);
-}
-
 void virtio_del_queue(VirtIODevice *vdev, int n)
 {
     if (n < 0 || n >= VIRTIO_QUEUE_MAX) {
@@ -1475,12 +1456,6 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
     vmstate_save_state(f, &vmstate_virtio, vdev, NULL);
 }
 
-/* A wrapper for use as a VMState .put function */
-void virtio_vmstate_save(QEMUFile *f, void *opaque, size_t size)
-{
-    virtio_save(VIRTIO_DEVICE(opaque), f);
-}
-
 static int virtio_set_features_nocheck(VirtIODevice *vdev, uint64_t val)
 {
     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
@@ -1649,21 +1624,6 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
             }
             vdev->vq[i].used_idx = vring_used_idx(&vdev->vq[i]);
             vdev->vq[i].shadow_avail_idx = vring_avail_idx(&vdev->vq[i]);
-
-            /*
-             * Some devices migrate VirtQueueElements that have been popped
-             * from the avail ring but not yet returned to the used ring.
-             */
-            vdev->vq[i].inuse = vdev->vq[i].last_avail_idx -
-                                vdev->vq[i].used_idx;
-            if (vdev->vq[i].inuse > vdev->vq[i].vring.num) {
-                error_report("VQ %d size 0x%x < last_avail_idx 0x%x - "
-                             "used_idx 0x%x",
-                             i, vdev->vq[i].vring.num,
-                             vdev->vq[i].last_avail_idx,
-                             vdev->vq[i].used_idx);
-                return -1;
-            }
         }
     }
 
@@ -1856,7 +1816,8 @@ static void virtio_queue_host_notifier_aio_read(EventNotifier *n)
 }
 
 void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
-                                                VirtIOHandleOutput handle_output)
+                                                void (*handle_output)(VirtIODevice *,
+                                                                      VirtQueue *))
 {
     if (handle_output) {
         vq->handle_aio_output = handle_output;
@@ -1882,21 +1843,11 @@ static void virtio_queue_host_notifier_read(EventNotifier *n)
 void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
                                                bool set_handler)
 {
-    AioContext *ctx = qemu_get_aio_context();
     if (assign && set_handler) {
-        if (vq->use_aio) {
-            aio_set_event_notifier(ctx, &vq->host_notifier, true,
+        event_notifier_set_handler(&vq->host_notifier, true,
                                    virtio_queue_host_notifier_read);
-        } else {
-            event_notifier_set_handler(&vq->host_notifier, true,
-                                       virtio_queue_host_notifier_read);
-        }
     } else {
-        if (vq->use_aio) {
-            aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL);
-        } else {
-            event_notifier_set_handler(&vq->host_notifier, true, NULL);
-        }
+        event_notifier_set_handler(&vq->host_notifier, true, NULL);
     }
     if (!assign) {
         /* Test and clear notifier before after disabling event,
index 2aeaf1f..bbf3646 100644 (file)
@@ -143,7 +143,7 @@ void watchdog_perform_action(void)
     case WDT_NMI:
         qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_INJECT_NMI,
                                  &error_abort);
-        nmi_monitor_handle(0, NULL);
+        inject_nmi();
         break;
     }
 }
index a7b64e2..f54a35a 100644 (file)
@@ -16,7 +16,6 @@
 #include "hw/sysbus.h"
 #include "qemu/timer.h"
 #include "hw/watchdog/wdt_diag288.h"
-#include "qemu/log.h"
 
 static WatchdogTimerModel model = {
     .wdt_name = TYPE_WDT_DIAG288,
index 4d8d34e..6acf36e 100644 (file)
@@ -55,4 +55,4 @@ int xen_host_pci_set_block(XenHostPCIDevice *d, int pos, uint8_t *buf,
 
 int xen_host_pci_find_ext_cap_offset(XenHostPCIDevice *s, uint32_t cap);
 
-#endif /* XEN_HOST_PCI_DEVICE_H */
+#endif /* !XEN_HOST_PCI_DEVICE_H_ */
index 69a2388..60575ad 100644 (file)
  */
 
 #include "qemu/osdep.h"
+#include <sys/mman.h>
 #include <sys/signal.h>
 
 #include "hw/hw.h"
-#include "hw/sysbus.h"
 #include "sysemu/char.h"
 #include "qemu/log.h"
 #include "hw/xen/xen_backend.h"
 
 #include <xen/grant_table.h>
 
-#define TYPE_XENSYSDEV "xensysdev"
-
-DeviceState *xen_sysdev;
-
 /* ------------------------------------------------------------- */
 
 /* public */
@@ -46,36 +42,11 @@ struct xs_handle *xenstore = NULL;
 const char *xen_protocol;
 
 /* private */
-struct xs_dirs {
-    char *xs_dir;
-    QTAILQ_ENTRY(xs_dirs) list;
-};
-static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup =
-    QTAILQ_HEAD_INITIALIZER(xs_cleanup);
-
 static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = QTAILQ_HEAD_INITIALIZER(xendevs);
 static int debug = 0;
 
 /* ------------------------------------------------------------- */
 
-static void xenstore_cleanup_dir(char *dir)
-{
-    struct xs_dirs *d;
-
-    d = g_malloc(sizeof(*d));
-    d->xs_dir = dir;
-    QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
-}
-
-void xen_config_cleanup(void)
-{
-    struct xs_dirs *d;
-
-    QTAILQ_FOREACH(d, &xs_cleanup, list) {
-        xs_rm(xenstore, 0, d->xs_dir);
-    }
-}
-
 int xenstore_write_str(const char *base, const char *node, const char *val)
 {
     char abspath[XEN_BUFSIZE];
@@ -104,30 +75,6 @@ char *xenstore_read_str(const char *base, const char *node)
     return ret;
 }
 
-int xenstore_mkdir(char *path, int p)
-{
-    struct xs_permissions perms[2] = {
-        {
-            .id    = 0, /* set owner: dom0 */
-        }, {
-            .id    = xen_domid,
-            .perms = p,
-        }
-    };
-
-    if (!xs_mkdir(xenstore, 0, path)) {
-        xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", path);
-        return -1;
-    }
-    xenstore_cleanup_dir(g_strdup(path));
-
-    if (!xs_set_permissions(xenstore, 0, path, perms, 2)) {
-        xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", path);
-        return -1;
-    }
-    return 0;
-}
-
 int xenstore_write_int(const char *base, const char *node, int ival)
 {
     char val[12];
@@ -321,28 +268,48 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
 /*
  * release xen backend device.
  */
-static void xen_be_del_xendev(struct XenDevice *xendev)
+static struct XenDevice *xen_be_del_xendev(int dom, int dev)
 {
-    if (xendev->ops->free) {
-        xendev->ops->free(xendev);
-    }
+    struct XenDevice *xendev, *xnext;
 
-    if (xendev->fe) {
-        char token[XEN_BUFSIZE];
-        snprintf(token, sizeof(token), "fe:%p", xendev);
-        xs_unwatch(xenstore, xendev->fe, token);
-        g_free(xendev->fe);
-    }
+    /*
+     * This is pretty much like QTAILQ_FOREACH(xendev, &xendevs, next) but
+     * we save the next pointer in xnext because we might free xendev.
+     */
+    xnext = xendevs.tqh_first;
+    while (xnext) {
+        xendev = xnext;
+        xnext = xendev->next.tqe_next;
 
-    if (xendev->evtchndev != NULL) {
-        xenevtchn_close(xendev->evtchndev);
-    }
-    if (xendev->gnttabdev != NULL) {
-        xengnttab_close(xendev->gnttabdev);
-    }
+        if (xendev->dom != dom) {
+            continue;
+        }
+        if (xendev->dev != dev && dev != -1) {
+            continue;
+        }
+
+        if (xendev->ops->free) {
+            xendev->ops->free(xendev);
+        }
 
-    QTAILQ_REMOVE(&xendevs, xendev, next);
-    g_free(xendev);
+        if (xendev->fe) {
+            char token[XEN_BUFSIZE];
+            snprintf(token, sizeof(token), "fe:%p", xendev);
+            xs_unwatch(xenstore, xendev->fe, token);
+            g_free(xendev->fe);
+        }
+
+        if (xendev->evtchndev != NULL) {
+            xenevtchn_close(xendev->evtchndev);
+        }
+        if (xendev->gnttabdev != NULL) {
+            xengnttab_close(xendev->gnttabdev);
+        }
+
+        QTAILQ_REMOVE(&xendevs, xendev, next);
+        g_free(xendev);
+    }
+    return NULL;
 }
 
 /*
@@ -662,7 +629,7 @@ static void xenstore_update_be(char *watch, char *type, int dom,
     if (xendev != NULL) {
         bepath = xs_read(xenstore, 0, xendev->be, &len);
         if (bepath == NULL) {
-            xen_be_del_xendev(xendev);
+            xen_be_del_xendev(dom, dev);
         } else {
             free(bepath);
             xen_be_backend_changed(xendev, path);
@@ -747,10 +714,6 @@ int xen_be_init(void)
         /* Check if xen_init() have been called */
         goto err;
     }
-
-    xen_sysdev = qdev_create(NULL, TYPE_XENSYSDEV);
-    qdev_init_nofail(xen_sysdev);
-
     return 0;
 
 err:
@@ -763,33 +726,9 @@ err:
 
 int xen_be_register(const char *type, struct XenDevOps *ops)
 {
-    char path[50];
-    int rc;
-
-    if (ops->backend_register) {
-        rc = ops->backend_register();
-        if (rc) {
-            return rc;
-        }
-    }
-
-    snprintf(path, sizeof(path), "device-model/%u/backends/%s", xen_domid,
-             type);
-    xenstore_mkdir(path, XS_PERM_NONE);
-
     return xenstore_scan(type, xen_domid, ops);
 }
 
-void xen_be_register_common(void)
-{
-    xen_be_register("console", &xen_console_ops);
-    xen_be_register("vkbd", &xen_kbdmouse_ops);
-    xen_be_register("qdisk", &xen_blkdev_ops);
-#ifdef CONFIG_USB_LIBUSB
-    xen_be_register("qusb", &xen_usb_ops);
-#endif
-}
-
 int xen_be_bind_evtchn(struct XenDevice *xendev)
 {
     if (xendev->local_port != -1) {
@@ -861,35 +800,3 @@ void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ...
     }
     qemu_log_flush();
 }
-
-static int xen_sysdev_init(SysBusDevice *dev)
-{
-    return 0;
-}
-
-static Property xen_sysdev_properties[] = {
-    {/* end of property list */},
-};
-
-static void xen_sysdev_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
-    k->init = xen_sysdev_init;
-    dc->props = xen_sysdev_properties;
-}
-
-static const TypeInfo xensysdev_info = {
-    .name          = TYPE_XENSYSDEV,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(SysBusDevice),
-    .class_init    = xen_sysdev_class_init,
-};
-
-static void xenbe_register_types(void)
-{
-    type_register_static(&xensysdev_info);
-}
-
-type_init(xenbe_register_types);
index b7d290d..1f30fe4 100644 (file)
@@ -5,6 +5,54 @@
 
 /* ------------------------------------------------------------- */
 
+struct xs_dirs {
+    char *xs_dir;
+    QTAILQ_ENTRY(xs_dirs) list;
+};
+static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup = QTAILQ_HEAD_INITIALIZER(xs_cleanup);
+
+static void xen_config_cleanup_dir(char *dir)
+{
+    struct xs_dirs *d;
+
+    d = g_malloc(sizeof(*d));
+    d->xs_dir = dir;
+    QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
+}
+
+void xen_config_cleanup(void)
+{
+    struct xs_dirs *d;
+
+    QTAILQ_FOREACH(d, &xs_cleanup, list) {
+       xs_rm(xenstore, 0, d->xs_dir);
+    }
+}
+
+/* ------------------------------------------------------------- */
+
+static int xen_config_dev_mkdir(char *dev, int p)
+{
+    struct xs_permissions perms[2] = {{
+            .id    = 0, /* set owner: dom0 */
+        },{
+            .id    = xen_domid,
+            .perms = p,
+        }};
+
+    if (!xs_mkdir(xenstore, 0, dev)) {
+       xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", dev);
+       return -1;
+    }
+    xen_config_cleanup_dir(g_strdup(dev));
+
+    if (!xs_set_permissions(xenstore, 0, dev, perms, 2)) {
+       xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", dev);
+       return -1;
+    }
+    return 0;
+}
+
 static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev,
                               char *fe, char *be, int len)
 {
@@ -18,8 +66,8 @@ static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev,
     snprintf(be, len, "%s/backend/%s/%d/%d", dom, btype, xen_domid, vdev);
     free(dom);
 
-    xenstore_mkdir(fe, XS_PERM_READ | XS_PERM_WRITE);
-    xenstore_mkdir(be, XS_PERM_READ);
+    xen_config_dev_mkdir(fe, XS_PERM_READ | XS_PERM_WRITE);
+    xen_config_dev_mkdir(be, XS_PERM_READ);
     return 0;
 }
 
index 191d9ca..c2f8e1f 100644 (file)
@@ -332,4 +332,4 @@ int xen_pt_register_vga_regions(XenHostPCIDevice *dev);
 int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev);
 void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev,
                      Error **errp);
-#endif /* XEN_PT_H */
+#endif /* !XEN_PT_H */
index 6f18366..9869ffd 100644 (file)
@@ -2049,8 +2049,9 @@ void xen_pt_config_init(XenPCIPassthroughState *s, Error **errp)
                 for (j = 0; regs->size != 0; j++, regs++) {
                     xen_pt_config_reg_init(s, reg_grp_entry, regs, &err);
                     if (err) {
-                        error_append_hint(&err, "Failed to init register %d"
-                                " offsets 0x%x in grp_type = 0x%x (%d/%zu)", j,
+                        error_append_hint(&err, "Failed to initialize %d/%zu"
+                                " reg 0x%x in grp_type = 0x%x (%d/%zu)",
+                                j, ARRAY_SIZE(xen_pt_emu_reg_grps[i].emu_regs),
                                 regs->offset, xen_pt_emu_reg_grps[i].grp_type,
                                 i, ARRAY_SIZE(xen_pt_emu_reg_grps));
                         error_propagate(errp, err);
index 62add06..9a16f2b 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <sys/mman.h>
 
 #include "hw/xen/xen_backend.h"
 #include "xen_pt.h"
index 652d9b4..29a91ea 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef QEMU_HW_XEN_DOMAINBUILD_H
-#define QEMU_HW_XEN_DOMAINBUILD_H
+#define QEMU_HW_XEN_DOMAINBUILD_H 1
 
 #include "hw/xen/xen_common.h"
 
index 79aef4e..fc13535 100644 (file)
@@ -67,8 +67,10 @@ static void xen_init_pv(MachineState *machine)
         break;
     }
 
-    xen_be_register_common();
+    xen_be_register("console", &xen_console_ops);
+    xen_be_register("vkbd", &xen_kbdmouse_ops);
     xen_be_register("vfb", &xen_framebuffer_ops);
+    xen_be_register("qdisk", &xen_blkdev_ops);
     xen_be_register("qnic", &xen_netdev_ops);
 
     /* configure framebuffer */
index ade7891..955f4e8 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef HW_XTENSA_BOOTPARAM_H
-#define HW_XTENSA_BOOTPARAM_H
+#ifndef HW_XTENSA_BOOTPARAM
+#define HW_XTENSA_BOOTPARAM
 
 #define BP_TAG_COMMAND_LINE     0x1001  /* command line (0-terminated string)*/
 #define BP_TAG_INITRD           0x1002  /* ramdisk addr and size (bp_meminfo) */
index 2bed64f..c835bd0 100644 (file)
@@ -26,7 +26,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "cpu.h"
 #include "hw/hw.h"
 #include "qemu/log.h"
 #include "qemu/timer.h"
@@ -122,8 +121,8 @@ void xtensa_rearm_ccompare_timer(CPUXtensaState *env)
     }
     env->wake_ccount = wake_ccount;
     timer_mod(env->ccompare_timer, env->halt_clock +
-            (uint64_t)(wake_ccount - env->sregs[CCOUNT]) *
-            1000000 / env->config->clock_freq_khz);
+            muldiv64(wake_ccount - env->sregs[CCOUNT],
+                1000000, env->config->clock_freq_khz));
 }
 
 static void xtensa_ccompare_cb(void *opaque)
index ac75949..2d11736 100644 (file)
@@ -165,7 +165,7 @@ static pflash_t *xtfpga_flash_init(MemoryRegion *address_space,
     qdev_prop_set_uint32(dev, "num-blocks",
                          board->flash_size / board->flash_sector_size);
     qdev_prop_set_uint64(dev, "sector-length", board->flash_sector_size);
-    qdev_prop_set_uint8(dev, "width", 2);
+    qdev_prop_set_uint8(dev, "width", 4);
     qdev_prop_set_bit(dev, "big-endian", be);
     qdev_prop_set_string(dev, "name", "lx60.io.flash");
     qdev_init_nofail(dev);
index 173c1ed..88a64ee 100644 (file)
@@ -47,9 +47,6 @@ typedef struct AioHandler AioHandler;
 typedef void QEMUBHFunc(void *opaque);
 typedef void IOHandler(void *opaque);
 
-struct ThreadPool;
-struct LinuxAioState;
-
 struct AioContext {
     GSource source;
 
@@ -74,7 +71,7 @@ struct AioContext {
      * event_notifier_set necessary.
      *
      * Bit 0 is reserved for GSource usage of the AioContext, and is 1
-     * between a call to aio_ctx_prepare and the next call to aio_ctx_check.
+     * between a call to aio_ctx_check and the next call to aio_ctx_dispatch.
      * Bits 1-31 simply count the number of active calls to aio_poll
      * that are in the prepare or poll phase.
      *
@@ -122,13 +119,6 @@ struct AioContext {
     /* Thread pool for performing work and receiving completion callbacks */
     struct ThreadPool *thread_pool;
 
-#ifdef CONFIG_LINUX_AIO
-    /* State for native Linux AIO.  Uses aio_context_acquire/release for
-     * locking.
-     */
-    struct LinuxAioState *linux_aio;
-#endif
-
     /* TimerLists for calling timers - one per clock type */
     QEMUTimerListGroup tlg;
 
@@ -345,9 +335,6 @@ GSource *aio_get_g_source(AioContext *ctx);
 /* Return the ThreadPool bound to this AioContext */
 struct ThreadPool *aio_get_thread_pool(AioContext *ctx);
 
-/* Return the LinuxAioState bound to this AioContext */
-struct LinuxAioState *aio_get_linux_aio(AioContext *ctx);
-
 /**
  * aio_timer_new:
  * @ctx: the aio context
@@ -452,6 +439,6 @@ static inline bool aio_node_check(AioContext *ctx, bool is_external)
  *
  * Initialize the aio context.
  */
-void aio_context_setup(AioContext *ctx);
+void aio_context_setup(AioContext *ctx, Error **errp);
 
 #endif
index 11c162d..3a73137 100644 (file)
@@ -33,7 +33,7 @@ typedef struct BlockDriverInfo {
      * True if the driver can optimize writing zeroes by unmapping
      * sectors. This is equivalent to the BLKDISCARDZEROES ioctl in Linux
      * with the difference that in qemu a discard is allowed to silently
-     * fail. Therefore we have to use bdrv_pwrite_zeroes with the
+     * fail. Therefore we have to use bdrv_write_zeroes with the
      * BDRV_REQ_MAY_UNMAP flag for an optimized zero write with unmapping.
      * After this call the driver has to guarantee that the contents read
      * back as zero. It is additionally required that the block device is
@@ -65,9 +65,6 @@ typedef enum {
     BDRV_REQ_MAY_UNMAP          = 0x4,
     BDRV_REQ_NO_SERIALISING     = 0x8,
     BDRV_REQ_FUA                = 0x10,
-
-    /* Mask of valid flags */
-    BDRV_REQ_MASK               = 0x1f,
 } BdrvRequestFlags;
 
 typedef struct BlockSizes {
@@ -190,6 +187,10 @@ void bdrv_stats_print(Monitor *mon, const QObject *data);
 void bdrv_info_stats(Monitor *mon, QObject **ret_data);
 
 /* disk I/O throttling */
+void bdrv_io_limits_enable(BlockDriverState *bs, const char *group);
+void bdrv_io_limits_disable(BlockDriverState *bs);
+void bdrv_io_limits_update_group(BlockDriverState *bs, const char *group);
+
 void bdrv_init(void);
 void bdrv_init_with_whitelist(void);
 bool bdrv_uses_whitelist(void);
@@ -200,6 +201,7 @@ BlockDriver *bdrv_find_format(const char *format_name);
 int bdrv_create(BlockDriver *drv, const char* filename,
                 QemuOpts *opts, Error **errp);
 int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
+BlockDriverState *bdrv_new_root(void);
 BlockDriverState *bdrv_new(void);
 void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top);
 void bdrv_replace_in_backing_chain(BlockDriverState *old,
@@ -215,8 +217,8 @@ BdrvChild *bdrv_open_child(const char *filename,
 void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd);
 int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
                            const char *bdref_key, Error **errp);
-BlockDriverState *bdrv_open(const char *filename, const char *reference,
-                            QDict *options, int flags, Error **errp);
+int bdrv_open(BlockDriverState **pbs, const char *filename,
+              const char *reference, QDict *options, int flags, Error **errp);
 BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
                                     BlockDriverState *bs,
                                     QDict *options, int flags);
@@ -226,31 +228,39 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
                         BlockReopenQueue *queue, Error **errp);
 void bdrv_reopen_commit(BDRVReopenState *reopen_state);
 void bdrv_reopen_abort(BDRVReopenState *reopen_state);
-int bdrv_read(BdrvChild *child, int64_t sector_num,
+int bdrv_read(BlockDriverState *bs, int64_t sector_num,
               uint8_t *buf, int nb_sectors);
-int bdrv_write(BdrvChild *child, int64_t sector_num,
+int bdrv_write(BlockDriverState *bs, int64_t sector_num,
                const uint8_t *buf, int nb_sectors);
-int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,
-                       int count, BdrvRequestFlags flags);
-int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags);
-int bdrv_pread(BdrvChild *child, int64_t offset, void *buf, int bytes);
-int bdrv_preadv(BdrvChild *child, int64_t offset, QEMUIOVector *qiov);
-int bdrv_pwrite(BdrvChild *child, int64_t offset, const void *buf, int bytes);
-int bdrv_pwritev(BdrvChild *child, int64_t offset, QEMUIOVector *qiov);
-int bdrv_pwrite_sync(BdrvChild *child, int64_t offset,
-                     const void *buf, int count);
-int coroutine_fn bdrv_co_readv(BdrvChild *child, int64_t sector_num,
-                               int nb_sectors, QEMUIOVector *qiov);
-int coroutine_fn bdrv_co_writev(BdrvChild *child, int64_t sector_num,
-                               int nb_sectors, QEMUIOVector *qiov);
+int bdrv_write_zeroes(BlockDriverState *bs, int64_t sector_num,
+               int nb_sectors, BdrvRequestFlags flags);
+BlockAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs, int64_t sector_num,
+                                  int nb_sectors, BdrvRequestFlags flags,
+                                  BlockCompletionFunc *cb, void *opaque);
+int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags);
+int bdrv_pread(BlockDriverState *bs, int64_t offset,
+               void *buf, int count);
+int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
+                const void *buf, int count);
+int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov);
+int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
+    const void *buf, int count);
+int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
+    int nb_sectors, QEMUIOVector *qiov);
+int coroutine_fn bdrv_co_copy_on_readv(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
+int coroutine_fn bdrv_co_readv_no_serialising(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
+int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
+    int nb_sectors, QEMUIOVector *qiov);
 /*
  * Efficiently zero a region of the disk image.  Note that this is a regular
  * I/O request like read or write and should have a reasonable size.  This
  * function is not suitable for zeroing the entire image in a single request
  * because it may allocate memory for the entire region.
  */
-int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
-                                       int count, BdrvRequestFlags flags);
+int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,
+    int nb_sectors, BdrvRequestFlags flags);
 BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
     const char *backing_file);
 int bdrv_get_backing_file_depth(BlockDriverState *bs);
@@ -308,20 +318,44 @@ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
                                         const char *node_name, Error **errp);
 
 /* async block I/O */
-BlockAIOCB *bdrv_aio_readv(BdrvChild *child, int64_t sector_num,
+BlockAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
                            QEMUIOVector *iov, int nb_sectors,
                            BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *bdrv_aio_writev(BdrvChild *child, int64_t sector_num,
+BlockAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
                             QEMUIOVector *iov, int nb_sectors,
                             BlockCompletionFunc *cb, void *opaque);
 BlockAIOCB *bdrv_aio_flush(BlockDriverState *bs,
                            BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *bdrv_aio_pdiscard(BlockDriverState *bs,
-                              int64_t offset, int count,
-                              BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *bdrv_aio_discard(BlockDriverState *bs,
+                             int64_t sector_num, int nb_sectors,
+                             BlockCompletionFunc *cb, void *opaque);
 void bdrv_aio_cancel(BlockAIOCB *acb);
 void bdrv_aio_cancel_async(BlockAIOCB *acb);
 
+typedef struct BlockRequest {
+    /* Fields to be filled by multiwrite caller */
+    union {
+        struct {
+            int64_t sector;
+            int nb_sectors;
+            int flags;
+            QEMUIOVector *qiov;
+        };
+        struct {
+            int req;
+            void *buf;
+        };
+    };
+    BlockCompletionFunc *cb;
+    void *opaque;
+
+    /* Filled by multiwrite implementation */
+    int error;
+} BlockRequest;
+
+int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs,
+    int num_reqs);
+
 /* sg packet commands */
 int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf);
 BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
@@ -341,8 +375,8 @@ void bdrv_drain(BlockDriverState *bs);
 void coroutine_fn bdrv_co_drain(BlockDriverState *bs);
 void bdrv_drain_all(void);
 
-int bdrv_pdiscard(BlockDriverState *bs, int64_t offset, int count);
-int bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset, int count);
+int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
+int bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
 int bdrv_has_zero_init_1(BlockDriverState *bs);
 int bdrv_has_zero_init(BlockDriverState *bs);
 bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs);
@@ -360,8 +394,8 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
 int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
                             int64_t sector_num, int nb_sectors, int *pnum);
 
-bool bdrv_is_read_only(BlockDriverState *bs);
-bool bdrv_is_sg(BlockDriverState *bs);
+int bdrv_is_read_only(BlockDriverState *bs);
+int bdrv_is_sg(BlockDriverState *bs);
 bool bdrv_is_inserted(BlockDriverState *bs);
 int bdrv_media_changed(BlockDriverState *bs);
 void bdrv_lock_medium(BlockDriverState *bs, bool locked);
@@ -374,22 +408,10 @@ BlockDriverState *bdrv_lookup_bs(const char *device,
                                  Error **errp);
 bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base);
 BlockDriverState *bdrv_next_node(BlockDriverState *bs);
-
-typedef struct BdrvNextIterator {
-    enum {
-        BDRV_NEXT_BACKEND_ROOTS,
-        BDRV_NEXT_MONITOR_OWNED,
-    } phase;
-    BlockBackend *blk;
-    BlockDriverState *bs;
-} BdrvNextIterator;
-
-BlockDriverState *bdrv_first(BdrvNextIterator *it);
-BlockDriverState *bdrv_next(BdrvNextIterator *it);
-
+BlockDriverState *bdrv_next(BlockDriverState *bs);
 BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs);
-bool bdrv_is_encrypted(BlockDriverState *bs);
-bool bdrv_key_required(BlockDriverState *bs);
+int bdrv_is_encrypted(BlockDriverState *bs);
+int bdrv_key_required(BlockDriverState *bs);
 int bdrv_set_key(BlockDriverState *bs, const char *key);
 void bdrv_add_key(BlockDriverState *bs, const char *key, Error **errp);
 int bdrv_query_missing_keys(void);
@@ -403,14 +425,10 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
                           const uint8_t *buf, int nb_sectors);
 int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
 ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs);
-void bdrv_round_sectors_to_clusters(BlockDriverState *bs,
-                                    int64_t sector_num, int nb_sectors,
-                                    int64_t *cluster_sector_num,
-                                    int *cluster_nb_sectors);
 void bdrv_round_to_clusters(BlockDriverState *bs,
-                            int64_t offset, unsigned int bytes,
-                            int64_t *cluster_offset,
-                            unsigned int *cluster_bytes);
+                            int64_t sector_num, int nb_sectors,
+                            int64_t *cluster_sector_num,
+                            int *cluster_nb_sectors);
 
 const char *bdrv_get_encrypted_filename(BlockDriverState *bs);
 void bdrv_get_backing_filename(BlockDriverState *bs,
@@ -429,7 +447,6 @@ void path_combine(char *dest, int dest_size,
                   const char *base_path,
                   const char *filename);
 
-int bdrv_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
 int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
 int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
                       int64_t pos, int size);
@@ -459,10 +476,6 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs);
 void bdrv_ref(BlockDriverState *bs);
 void bdrv_unref(BlockDriverState *bs);
 void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child);
-BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
-                             BlockDriverState *child_bs,
-                             const char *child_name,
-                             const BdrvChildRole *child_role);
 
 bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp);
 void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason);
@@ -507,8 +520,7 @@ int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo);
 
 void bdrv_io_plug(BlockDriverState *bs);
 void bdrv_io_unplug(BlockDriverState *bs);
-void bdrv_io_unplugged_begin(BlockDriverState *bs);
-void bdrv_io_unplugged_end(BlockDriverState *bs);
+void bdrv_flush_io_queue(BlockDriverState *bs);
 
 /**
  * bdrv_drained_begin:
@@ -529,8 +541,4 @@ void bdrv_drained_begin(BlockDriverState *bs);
  */
 void bdrv_drained_end(BlockDriverState *bs);
 
-void bdrv_add_child(BlockDriverState *parent, BlockDriverState *child,
-                    Error **errp);
-void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp);
-
 #endif
index 1e939de..10d8759 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "block/accounting.h"
 #include "block/block.h"
+#include "block/throttle-groups.h"
 #include "qemu/option.h"
 #include "qemu/queue.h"
 #include "qemu/coroutine.h"
 #include "qemu/throttle.h"
 
 #define BLOCK_FLAG_ENCRYPT          1
+#define BLOCK_FLAG_COMPAT6          4
 #define BLOCK_FLAG_LAZY_REFCOUNTS   8
 
 #define BLOCK_OPT_SIZE              "size"
 #define BLOCK_OPT_ENCRYPT           "encryption"
 #define BLOCK_OPT_COMPAT6           "compat6"
-#define BLOCK_OPT_HWVERSION         "hwversion"
 #define BLOCK_OPT_BACKING_FILE      "backing_file"
 #define BLOCK_OPT_BACKING_FMT       "backing_fmt"
 #define BLOCK_OPT_CLUSTER_SIZE      "cluster_size"
@@ -126,6 +127,10 @@ struct BlockDriver {
                      Error **errp);
     int (*bdrv_file_open)(BlockDriverState *bs, QDict *options, int flags,
                           Error **errp);
+    int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
+                     uint8_t *buf, int nb_sectors);
+    int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num,
+                      const uint8_t *buf, int nb_sectors);
     void (*bdrv_close)(BlockDriverState *bs);
     int (*bdrv_create)(const char *filename, QemuOpts *opts, Error **errp);
     int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
@@ -142,31 +147,29 @@ struct BlockDriver {
         BlockCompletionFunc *cb, void *opaque);
     BlockAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
         BlockCompletionFunc *cb, void *opaque);
-    BlockAIOCB *(*bdrv_aio_pdiscard)(BlockDriverState *bs,
-        int64_t offset, int count,
+    BlockAIOCB *(*bdrv_aio_discard)(BlockDriverState *bs,
+        int64_t sector_num, int nb_sectors,
         BlockCompletionFunc *cb, void *opaque);
 
     int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
-    int coroutine_fn (*bdrv_co_preadv)(BlockDriverState *bs,
-        uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags);
     int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
     int coroutine_fn (*bdrv_co_writev_flags)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int flags);
-    int coroutine_fn (*bdrv_co_pwritev)(BlockDriverState *bs,
-        uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags);
+
+    int supported_write_flags;
 
     /*
      * Efficiently zero a region of the disk image.  Typically an image format
      * would use a compact metadata representation to implement this.  This
-     * function pointer may be NULL or return -ENOSUP and .bdrv_co_writev()
-     * will be called instead.
+     * function pointer may be NULL and .bdrv_co_writev() will be called
+     * instead.
      */
-    int coroutine_fn (*bdrv_co_pwrite_zeroes)(BlockDriverState *bs,
-        int64_t offset, int count, BdrvRequestFlags flags);
-    int coroutine_fn (*bdrv_co_pdiscard)(BlockDriverState *bs,
-        int64_t offset, int count);
+    int coroutine_fn (*bdrv_co_write_zeroes)(BlockDriverState *bs,
+        int64_t sector_num, int nb_sectors, BdrvRequestFlags flags);
+    int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs,
+        int64_t sector_num, int nb_sectors);
     int64_t coroutine_fn (*bdrv_co_get_block_status)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, int *pnum,
         BlockDriverState **file);
@@ -224,12 +227,10 @@ struct BlockDriver {
     int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
     ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs);
 
-    int coroutine_fn (*bdrv_save_vmstate)(BlockDriverState *bs,
-                                          QEMUIOVector *qiov,
-                                          int64_t pos);
-    int coroutine_fn (*bdrv_load_vmstate)(BlockDriverState *bs,
-                                          QEMUIOVector *qiov,
-                                          int64_t pos);
+    int (*bdrv_save_vmstate)(BlockDriverState *bs, QEMUIOVector *qiov,
+                             int64_t pos);
+    int (*bdrv_load_vmstate)(BlockDriverState *bs, uint8_t *buf,
+                             int64_t pos, int size);
 
     int (*bdrv_change_backing_file)(BlockDriverState *bs,
         const char *backing_file, const char *backing_fmt);
@@ -293,6 +294,7 @@ struct BlockDriver {
     /* io queue for linux-aio */
     void (*bdrv_io_plug)(BlockDriverState *bs);
     void (*bdrv_io_unplug)(BlockDriverState *bs);
+    void (*bdrv_flush_io_queue)(BlockDriverState *bs);
 
     /**
      * Try to get @bs's logical and physical block size.
@@ -315,60 +317,32 @@ struct BlockDriver {
      */
     void (*bdrv_drain)(BlockDriverState *bs);
 
-    void (*bdrv_add_child)(BlockDriverState *parent, BlockDriverState *child,
-                           Error **errp);
-    void (*bdrv_del_child)(BlockDriverState *parent, BdrvChild *child,
-                           Error **errp);
-
     QLIST_ENTRY(BlockDriver) list;
 };
 
 typedef struct BlockLimits {
-    /* Alignment requirement, in bytes, for offset/length of I/O
-     * requests. Must be a power of 2 less than INT_MAX; defaults to
-     * 1 for drivers with modern byte interfaces, and to 512
-     * otherwise. */
-    uint32_t request_alignment;
-
-    /* Maximum number of bytes that can be discarded at once (since it
-     * is signed, it must be < 2G, if set). Must be multiple of
-     * pdiscard_alignment, but need not be power of 2. May be 0 if no
-     * inherent 32-bit limit */
-    int32_t max_pdiscard;
-
-    /* Optimal alignment for discard requests in bytes. A power of 2
-     * is best but not mandatory.  Must be a multiple of
-     * bl.request_alignment, and must be less than max_pdiscard if
-     * that is set. May be 0 if bl.request_alignment is good enough */
-    uint32_t pdiscard_alignment;
-
-    /* Maximum number of bytes that can zeroized at once (since it is
-     * signed, it must be < 2G, if set). Must be multiple of
-     * pwrite_zeroes_alignment. May be 0 if no inherent 32-bit limit */
-    int32_t max_pwrite_zeroes;
-
-    /* Optimal alignment for write zeroes requests in bytes. A power
-     * of 2 is best but not mandatory.  Must be a multiple of
-     * bl.request_alignment, and must be less than max_pwrite_zeroes
-     * if that is set. May be 0 if bl.request_alignment is good
-     * enough */
-    uint32_t pwrite_zeroes_alignment;
-
-    /* Optimal transfer length in bytes.  A power of 2 is best but not
-     * mandatory.  Must be a multiple of bl.request_alignment, or 0 if
-     * no preferred size */
-    uint32_t opt_transfer;
-
-    /* Maximal transfer length in bytes.  Need not be power of 2, but
-     * must be multiple of opt_transfer and bl.request_alignment, or 0
-     * for no 32-bit limit.  For now, anything larger than INT_MAX is
-     * clamped down. */
-    uint32_t max_transfer;
-
-    /* memory alignment, in bytes so that no bounce buffer is needed */
+    /* maximum number of sectors that can be discarded at once */
+    int max_discard;
+
+    /* optimal alignment for discard requests in sectors */
+    int64_t discard_alignment;
+
+    /* maximum number of sectors that can zeroized at once */
+    int max_write_zeroes;
+
+    /* optimal alignment for write zeroes requests in sectors */
+    int64_t write_zeroes_alignment;
+
+    /* optimal transfer length in sectors */
+    int opt_transfer_length;
+
+    /* maximal transfer length in sectors */
+    int max_transfer_length;
+
+    /* memory alignment so that no bounce buffer is needed */
     size_t min_mem_alignment;
 
-    /* memory alignment, in bytes, for bounce buffer */
+    /* memory alignment for bounce buffer */
     size_t opt_mem_alignment;
 
     /* maximum number of iovec elements */
@@ -382,7 +356,6 @@ typedef struct BdrvAioNotifier {
     void (*detach_aio_context)(void *opaque);
 
     void *opaque;
-    bool deleted;
 
     QLIST_ENTRY(BdrvAioNotifier) list;
 } BdrvAioNotifier;
@@ -390,25 +363,6 @@ typedef struct BdrvAioNotifier {
 struct BdrvChildRole {
     void (*inherit_options)(int *child_flags, QDict *child_options,
                             int parent_flags, QDict *parent_options);
-
-    void (*change_media)(BdrvChild *child, bool load);
-    void (*resize)(BdrvChild *child);
-
-    /* Returns a name that is supposedly more useful for human users than the
-     * node name for identifying the node in question (in particular, a BB
-     * name), or NULL if the parent can't provide a better name. */
-    const char* (*get_name)(BdrvChild *child);
-
-    /*
-     * If this pair of functions is implemented, the parent doesn't issue new
-     * requests after returning from .drained_begin() until .drained_end() is
-     * called.
-     *
-     * Note that this can be nested. If drained_begin() was called twice, new
-     * I/O is allowed only after drained_end() was called twice, too.
-     */
-    void (*drained_begin)(BdrvChild *child);
-    void (*drained_end)(BdrvChild *child);
 };
 
 extern const BdrvChildRole child_file;
@@ -418,7 +372,6 @@ struct BdrvChild {
     BlockDriverState *bs;
     char *name;
     const BdrvChildRole *role;
-    void *opaque;
     QLIST_ENTRY(BdrvChild) next;
     QLIST_ENTRY(BdrvChild) next_parent;
 };
@@ -432,30 +385,25 @@ struct BdrvChild {
 struct BlockDriverState {
     int64_t total_sectors; /* if we are reading a disk image, give its
                               size in sectors */
+    int read_only; /* if true, the media is read only */
     int open_flags; /* flags used to open the file, re-used for re-open */
-    bool read_only; /* if true, the media is read only */
-    bool encrypted; /* if true, the media is encrypted */
-    bool valid_key; /* if true, a valid encryption key has been set */
-    bool sg;        /* if true, the device is a /dev/sg* */
-    bool probed;    /* if true, format was probed rather than specified */
-
-    int copy_on_read; /* if nonzero, copy read backing sectors into image.
+    int encrypted; /* if true, the media is encrypted */
+    int valid_key; /* if true, a valid encryption key has been set */
+    int sg;        /* if true, the device is a /dev/sg* */
+    int copy_on_read; /* if true, copy read backing sectors into image
                          note this is a reference count */
-
-    CoQueue flush_queue;            /* Serializing flush queue */
-    BdrvTrackedRequest *active_flush_req; /* Flush request in flight */
-    unsigned int write_gen;         /* Current data generation */
-    unsigned int flushed_gen;       /* Flushed write generation */
+    bool probed;
 
     BlockDriver *drv; /* NULL means no media */
     void *opaque;
 
+    BlockBackend *blk;          /* owning backend, if any */
+
     AioContext *aio_context; /* event loop used for fd handlers, timers, etc */
     /* long-running tasks intended to always use the same AioContext as this
      * BDS may register themselves in this list to be notified of changes
      * regarding this BDS's context */
     QLIST_HEAD(, BdrvAioNotifier) aio_notifiers;
-    bool walking_aio_notifiers; /* to make removal during iteration safe */
 
     char filename[PATH_MAX];
     char backing_file[PATH_MAX]; /* if non zero, the image is a diff of
@@ -474,17 +422,30 @@ struct BlockDriverState {
     /* number of in-flight serialising requests */
     unsigned int serialising_in_flight;
 
+    /* I/O throttling.
+     * throttle_state tells us if this BDS has I/O limits configured.
+     * io_limits_enabled tells us if they are currently being
+     * enforced, but it can be temporarily set to false */
+    CoQueue      throttled_reqs[2];
+    bool         io_limits_enabled;
+    /* The following fields are protected by the ThrottleGroup lock.
+     * See the ThrottleGroup documentation for details. */
+    ThrottleState *throttle_state;
+    ThrottleTimers throttle_timers;
+    unsigned       pending_reqs[2];
+    QLIST_ENTRY(BlockDriverState) round_robin;
+
     /* Offset after the highest byte written to */
     uint64_t wr_highest_offset;
 
     /* I/O Limits */
     BlockLimits bl;
 
-    /* Flags honored during pwrite (so far: BDRV_REQ_FUA) */
-    unsigned int supported_write_flags;
-    /* Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA,
-     * BDRV_REQ_MAY_UNMAP) */
-    unsigned int supported_zero_flags;
+    /* Whether produces zeros when read beyond eof */
+    bool zero_beyond_eof;
+
+    /* Alignment requirement for offset/length of I/O requests */
+    unsigned int request_alignment;
 
     /* the following member gives a name to every node on the bs graph. */
     char node_name[32];
@@ -523,10 +484,6 @@ struct BlockDriverState {
     uint64_t write_threshold_offset;
     NotifierWithReturn write_threshold_notifier;
 
-    /* counters for nested bdrv_io_plug and bdrv_io_unplugged_begin */
-    unsigned io_plugged;
-    unsigned io_plug_disabled;
-
     int quiesce_counter;
 };
 
@@ -534,21 +491,10 @@ struct BlockBackendRootState {
     int open_flags;
     bool read_only;
     BlockdevDetectZeroesOptions detect_zeroes;
-};
 
-typedef enum BlockMirrorBackingMode {
-    /* Reuse the existing backing chain from the source for the target.
-     * - sync=full: Set backing BDS to NULL.
-     * - sync=top:  Use source's backing BDS.
-     * - sync=none: Use source as the backing BDS. */
-    MIRROR_SOURCE_BACKING_CHAIN,
-
-    /* Open the target's backing chain completely anew */
-    MIRROR_OPEN_BACKING_CHAIN,
-
-    /* Do not change the target's backing BDS after job completion */
-    MIRROR_LEAVE_BACKING_CHAIN,
-} BlockMirrorBackingMode;
+    char *throttle_group;
+    ThrottleState *throttle_state;
+};
 
 static inline BlockDriverState *backing_bs(BlockDriverState *bs)
 {
@@ -571,10 +517,10 @@ extern BlockDriver bdrv_qcow2;
  */
 void bdrv_setup_io_funcs(BlockDriver *bdrv);
 
-int coroutine_fn bdrv_co_preadv(BdrvChild *child,
+int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs,
     int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
     BdrvRequestFlags flags);
-int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
+int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
     int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
     BdrvRequestFlags flags);
 
@@ -582,6 +528,9 @@ int get_tmp_filename(char *filename, int size);
 BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
                             const char *filename);
 
+void bdrv_set_io_limits(BlockDriverState *bs,
+                        ThrottleConfig *cfg);
+
 
 /**
  * bdrv_add_before_write_notifier:
@@ -647,13 +596,11 @@ int is_windows_drive(const char *filename);
 
 /**
  * stream_start:
- * @job_id: The id of the newly-created job, or %NULL to use the
- * device name of @bs.
  * @bs: Block device to operate on.
  * @base: Block device that will become the new base, or %NULL to
  * flatten the whole backing file chain onto @bs.
- * @backing_file_str: The file name that will be written to @bs as the
- * the new backing file if the job completes. Ignored if @base is %NULL.
+ * @base_id: The file name that will be written to @bs as the new
+ * backing file if the job completes.  Ignored if @base is %NULL.
  * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
  * @on_error: The action to take upon error.
  * @cb: Completion function for the job.
@@ -664,18 +611,15 @@ int is_windows_drive(const char *filename);
  * in @bs, but allocated in any image between @base and @bs (both
  * exclusive) will be written to @bs.  At the end of a successful
  * streaming job, the backing file of @bs will be changed to
- * @backing_file_str in the written image and to @base in the live
- * BlockDriverState.
+ * @base_id in the written image and to @base in the live BlockDriverState.
  */
-void stream_start(const char *job_id, BlockDriverState *bs,
-                  BlockDriverState *base, const char *backing_file_str,
-                  int64_t speed, BlockdevOnError on_error,
-                  BlockCompletionFunc *cb, void *opaque, Error **errp);
+void stream_start(BlockDriverState *bs, BlockDriverState *base,
+                  const char *base_id, int64_t speed, BlockdevOnError on_error,
+                  BlockCompletionFunc *cb,
+                  void *opaque, Error **errp);
 
 /**
  * commit_start:
- * @job_id: The id of the newly-created job, or %NULL to use the
- * device name of @bs.
  * @bs: Active block device.
  * @top: Top block device to be committed.
  * @base: Block device that will be written into, and become the new top.
@@ -687,14 +631,12 @@ void stream_start(const char *job_id, BlockDriverState *bs,
  * @errp: Error object.
  *
  */
-void commit_start(const char *job_id, BlockDriverState *bs,
-                  BlockDriverState *base, BlockDriverState *top, int64_t speed,
-                  BlockdevOnError on_error, BlockCompletionFunc *cb,
-                  void *opaque, const char *backing_file_str, Error **errp);
+void commit_start(BlockDriverState *bs, BlockDriverState *base,
+                 BlockDriverState *top, int64_t speed,
+                 BlockdevOnError on_error, BlockCompletionFunc *cb,
+                 void *opaque, const char *backing_file_str, Error **errp);
 /**
  * commit_active_start:
- * @job_id: The id of the newly-created job, or %NULL to use the
- * device name of @bs.
  * @bs: Active block device to be committed.
  * @base: Block device that will be written into, and become the new top.
  * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
@@ -704,15 +646,13 @@ void commit_start(const char *job_id, BlockDriverState *bs,
  * @errp: Error object.
  *
  */
-void commit_active_start(const char *job_id, BlockDriverState *bs,
-                         BlockDriverState *base, int64_t speed,
+void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
+                         int64_t speed,
                          BlockdevOnError on_error,
                          BlockCompletionFunc *cb,
                          void *opaque, Error **errp);
 /*
  * mirror_start:
- * @job_id: The id of the newly-created job, or %NULL to use the
- * device name of @bs.
  * @bs: Block device to operate on.
  * @target: Block device to write to.
  * @replaces: Block graph node name to replace once the mirror is done. Can
@@ -721,7 +661,6 @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
  * @granularity: The chosen granularity for the dirty bitmap.
  * @buf_size: The amount of data that can be in flight at one time.
  * @mode: Whether to collapse all images in the chain to the target.
- * @backing_mode: How to establish the target's backing chain after completion.
  * @on_source_error: The action to take upon error reading from the source.
  * @on_target_error: The action to take upon error writing to the target.
  * @unmap: Whether to unmap target where source sectors only contain zeroes.
@@ -734,11 +673,10 @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
  * manually completed.  At the end of a successful mirroring job,
  * @bs will be switched to read from @target.
  */
-void mirror_start(const char *job_id, BlockDriverState *bs,
-                  BlockDriverState *target, const char *replaces,
+void mirror_start(BlockDriverState *bs, BlockDriverState *target,
+                  const char *replaces,
                   int64_t speed, uint32_t granularity, int64_t buf_size,
-                  MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
-                  BlockdevOnError on_source_error,
+                  MirrorSyncMode mode, BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
                   bool unmap,
                   BlockCompletionFunc *cb,
@@ -746,8 +684,6 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
 
 /*
  * backup_start:
- * @job_id: The id of the newly-created job, or %NULL to use the
- * device name of @bs.
  * @bs: Block device to operate on.
  * @target: Block device to write to.
  * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
@@ -762,9 +698,9 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
  * Start a backup operation on @bs.  Clusters in @bs are written to @target
  * until the job is cancelled or manually completed.
  */
-void backup_start(const char *job_id, BlockDriverState *bs,
-                  BlockDriverState *target, int64_t speed,
-                  MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
+void backup_start(BlockDriverState *bs, BlockDriverState *target,
+                  int64_t speed, MirrorSyncMode sync_mode,
+                  BdrvDirtyBitmap *sync_bitmap,
                   BlockdevOnError on_source_error,
                   BlockdevOnError on_target_error,
                   BlockCompletionFunc *cb, void *opaque,
@@ -774,19 +710,18 @@ void hmp_drive_add_node(Monitor *mon, const char *optstr);
 
 BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
                                   const char *child_name,
-                                  const BdrvChildRole *child_role,
-                                  void *opaque);
+                                  const BdrvChildRole *child_role);
 void bdrv_root_unref_child(BdrvChild *child);
 
-const char *bdrv_get_parent_name(const BlockDriverState *bs);
 void blk_dev_change_media_cb(BlockBackend *blk, bool load);
 bool blk_dev_has_removable_media(BlockBackend *blk);
 bool blk_dev_has_tray(BlockBackend *blk);
 void blk_dev_eject_request(BlockBackend *blk, bool force);
 bool blk_dev_is_tray_open(BlockBackend *blk);
 bool blk_dev_is_medium_locked(BlockBackend *blk);
+void blk_dev_resize_cb(BlockBackend *blk);
 
-void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int64_t nr_sect);
+void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors);
 bool bdrv_requests_pending(BlockDriverState *bs);
 
 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out);
index 4ddb4ae..8bedc49 100644 (file)
@@ -22,9 +22,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
 #ifndef BLOCKJOB_H
-#define BLOCKJOB_H
+#define BLOCKJOB_H 1
 
 #include "block/block.h"
 
@@ -71,27 +70,6 @@ typedef struct BlockJobDriver {
      * never both.
      */
     void (*abort)(BlockJob *job);
-
-    /**
-     * If the callback is not NULL, it will be invoked when the job transitions
-     * into the paused state.  Paused jobs must not perform any asynchronous
-     * I/O or event loop activity.  This callback is used to quiesce jobs.
-     */
-    void coroutine_fn (*pause)(BlockJob *job);
-
-    /**
-     * If the callback is not NULL, it will be invoked when the job transitions
-     * out of the paused state.  Any asynchronous I/O or event loop activity
-     * should be restarted from this callback.
-     */
-    void coroutine_fn (*resume)(BlockJob *job);
-
-    /*
-     * If the callback is not NULL, it will be invoked before the job is
-     * resumed in a new AioContext.  This is the place to move any resources
-     * besides job->blk to the new AioContext.
-     */
-    void (*attached_aio_context)(BlockJob *job, AioContext *new_context);
 } BlockJobDriver;
 
 /**
@@ -104,10 +82,13 @@ struct BlockJob {
     const BlockJobDriver *driver;
 
     /** The block device on which the job is operating.  */
-    BlockBackend *blk;
+    BlockDriverState *bs;
 
     /**
-     * The ID of the block job.
+     * The ID of the block job. Currently the BlockBackend name of the BDS
+     * owning the job at the time when the job is started.
+     *
+     * TODO Decouple block job IDs from BlockBackend names
      */
     char *id;
 
@@ -138,19 +119,13 @@ struct BlockJob {
     bool user_paused;
 
     /**
-     * Set to false by the job while the coroutine has yielded and may be
-     * re-entered by block_job_enter().  There may still be I/O or event loop
-     * activity pending.
+     * Set to false by the job while it is in a quiescent state, where
+     * no I/O is pending and the job has yielded on any condition
+     * that is not detected by #aio_poll, such as a timer.
      */
     bool busy;
 
     /**
-     * Set to true by the job while it is in a quiescent state, where
-     * no I/O or event loop activity is pending.
-     */
-    bool paused;
-
-    /**
      * Set to true when the job is ready to be completed.
      */
     bool ready;
@@ -160,9 +135,6 @@ struct BlockJob {
      */
     bool deferred_to_main_loop;
 
-    /** Element of the list of block jobs */
-    QLIST_ENTRY(BlockJob) job_list;
-
     /** Status that is published by the query-block-jobs QMP API */
     BlockDeviceIoStatus iostatus;
 
@@ -201,30 +173,7 @@ struct BlockJob {
 };
 
 /**
- * block_job_next:
- * @job: A block job, or %NULL.
- *
- * Get the next element from the list of block jobs after @job, or the
- * first one if @job is %NULL.
- *
- * Returns the requested job, or %NULL if there are no more jobs left.
- */
-BlockJob *block_job_next(BlockJob *job);
-
-/**
- * block_job_get:
- * @id: The id of the block job.
- *
- * Get the block job identified by @id (which must not be %NULL).
- *
- * Returns the requested job, or %NULL if it doesn't exist.
- */
-BlockJob *block_job_get(const char *id);
-
-/**
  * block_job_create:
- * @job_id: The id of the newly-created job, or %NULL to have one
- * generated automatically.
  * @job_type: The class object for the newly-created job.
  * @bs: The block
  * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
@@ -241,9 +190,9 @@ BlockJob *block_job_get(const char *id);
  * This function is not part of the public job interface; it should be
  * called from a wrapper that is specific to the job type.
  */
-void *block_job_create(const char *job_id, const BlockJobDriver *driver,
-                       BlockDriverState *bs, int64_t speed,
-                       BlockCompletionFunc *cb, void *opaque, Error **errp);
+void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
+                       int64_t speed, BlockCompletionFunc *cb,
+                       void *opaque, Error **errp);
 
 /**
  * block_job_sleep_ns:
@@ -336,15 +285,6 @@ bool block_job_is_cancelled(BlockJob *job);
 BlockJobInfo *block_job_query(BlockJob *job);
 
 /**
- * block_job_pause_point:
- * @job: The job that is ready to pause.
- *
- * Pause now if block_job_pause() has been called.  Block jobs that perform
- * lots of I/O must call this between requests so that the job can be paused.
- */
-void coroutine_fn block_job_pause_point(BlockJob *job);
-
-/**
  * block_job_pause:
  * @job: The job to be paused.
  *
@@ -394,6 +334,15 @@ void block_job_event_completed(BlockJob *job, const char *msg);
 void block_job_event_ready(BlockJob *job);
 
 /**
+ * block_job_is_paused:
+ * @job: The job being queried.
+ *
+ * Returns whether the job is currently paused, or will pause
+ * as soon as it reaches a sleeping point.
+ */
+bool block_job_is_paused(BlockJob *job);
+
+/**
  * block_job_cancel_sync:
  * @job: The job to be canceled.
  *
@@ -408,13 +357,6 @@ void block_job_event_ready(BlockJob *job);
 int block_job_cancel_sync(BlockJob *job);
 
 /**
- * block_job_cancel_sync_all:
- *
- * Synchronously cancels all jobs using block_job_cancel_sync().
- */
-void block_job_cancel_sync_all(void);
-
-/**
  * block_job_complete_sync:
  * @job: The job to be completed.
  * @errp: Error object which may be set by block_job_complete(); this is not
@@ -434,13 +376,14 @@ int block_job_complete_sync(BlockJob *job, Error **errp);
  * @job: The job whose I/O status should be reset.
  *
  * Reset I/O status on @job and on BlockDriverState objects it uses,
- * other than job->blk.
+ * other than job->bs.
  */
 void block_job_iostatus_reset(BlockJob *job);
 
 /**
  * block_job_error_action:
  * @job: The job to signal an error for.
+ * @bs: The block device on which to set an I/O error.
  * @on_err: The error action setting.
  * @is_read: Whether the operation was a read.
  * @error: The error that was reported.
@@ -448,7 +391,8 @@ void block_job_iostatus_reset(BlockJob *job);
  * Report an I/O error for a block job and possibly stop the VM.  Return the
  * action that was selected based on @on_err and @error.
  */
-BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
+BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs,
+                                        BlockdevOnError on_err,
                                         int is_read, int error);
 
 typedef void BlockJobDeferToMainLoopFn(BlockJob *job, void *opaque);
index ee3388f..80afe60 100644 (file)
@@ -33,9 +33,9 @@ DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap);
 int bdrv_get_dirty(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
                    int64_t sector);
 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
-                           int64_t cur_sector, int64_t nr_sectors);
+                           int64_t cur_sector, int nr_sectors);
 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
-                             int64_t cur_sector, int64_t nr_sectors);
+                             int64_t cur_sector, int nr_sectors);
 void bdrv_dirty_iter_init(BdrvDirtyBitmap *bitmap, struct HBitmapIter *hbi);
 void bdrv_set_dirty_iter(struct HBitmapIter *hbi, int64_t offset);
 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
index 1897557..fde4421 100644 (file)
 #include "io/channel-socket.h"
 #include "crypto/tlscreds.h"
 
-/* Note: these are _NOT_ the same as the network representation of an NBD
- * request and reply!
- */
 struct nbd_request {
+    uint32_t magic;
+    uint32_t type;
     uint64_t handle;
     uint64_t from;
     uint32_t len;
-    uint32_t type;
-};
+} QEMU_PACKED;
 
 struct nbd_reply {
-    uint64_t handle;
+    uint32_t magic;
     uint32_t error;
-};
+    uint64_t handle;
+} QEMU_PACKED;
 
 #define NBD_FLAG_HAS_FLAGS      (1 << 0)        /* Flags are there */
 #define NBD_FLAG_READ_ONLY      (1 << 1)        /* Device is read-only */
@@ -77,17 +76,12 @@ enum {
 
 /* Maximum size of a single READ/WRITE data buffer */
 #define NBD_MAX_BUFFER_SIZE (32 * 1024 * 1024)
-
-/* Maximum size of an export name. The NBD spec requires 256 and
- * suggests that servers support up to 4096, but we stick to only the
- * required size so that we can stack-allocate the names, and because
- * going larger would require an audit of more code to make sure we
- * aren't overflowing some other buffer. */
-#define NBD_MAX_NAME_SIZE 256
+#define NBD_MAX_SECTORS (NBD_MAX_BUFFER_SIZE / BDRV_SECTOR_SIZE)
 
 ssize_t nbd_wr_syncv(QIOChannel *ioc,
                      struct iovec *iov,
                      size_t niov,
+                     size_t offset,
                      size_t length,
                      bool do_read);
 int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags,
index cdf0a58..a311341 100644 (file)
@@ -19,9 +19,8 @@
  * This header file contains public constants and structures used by
  * the scsi code for linux.
  */
-
-#ifndef BLOCK_SCSI_H
-#define BLOCK_SCSI_H
+#ifndef HW_SCSI_DEFS_H
+#define HW_SCSI_DEFS_H 1
 
 /*
  *      SCSI opcodes
 #define ERASE                 0x19
 #define MODE_SENSE            0x1a
 #define LOAD_UNLOAD           0x1b
-#define SCAN                  0x1b
 #define START_STOP            0x1b
 #define RECEIVE_DIAGNOSTIC    0x1c
 #define SEND_DIAGNOSTIC       0x1d
 #define ALLOW_MEDIUM_REMOVAL  0x1e
-#define SET_WINDOW            0x24
 #define READ_CAPACITY_10      0x25
-#define GET_WINDOW            0x25
 #define READ_10               0x28
 #define WRITE_10              0x2a
-#define SEND                  0x2a
 #define SEEK_10               0x2b
 #define LOCATE_10             0x2b
 #define POSITION_TO_ELEMENT   0x2b
 #define VERIFY_10             0x2f
 #define SEARCH_HIGH           0x30
 #define SEARCH_EQUAL          0x31
-#define OBJECT_POSITION       0x31
 #define SEARCH_LOW            0x32
 #define SET_LIMITS            0x33
 #define PRE_FETCH             0x34
 #define READ_POSITION         0x34
-#define GET_DATA_BUFFER_STATUS 0x34
 #define SYNCHRONIZE_CACHE     0x35
 #define LOCK_UNLOCK_CACHE     0x36
 #define INITIALIZE_ELEMENT_STATUS_WITH_RANGE 0x37
index 7dd7d73..42eb5e8 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef QEMU_THREAD_POOL_H
-#define QEMU_THREAD_POOL_H
+#define QEMU_THREAD_POOL_H 1
 
 #include "block/block.h"
 
index d983d34..aba28f3 100644 (file)
 #include "qemu/throttle.h"
 #include "block/block_int.h"
 
-const char *throttle_group_get_name(BlockBackend *blk);
+const char *throttle_group_get_name(BlockDriverState *bs);
 
 ThrottleState *throttle_group_incref(const char *name);
 void throttle_group_unref(ThrottleState *ts);
 
-void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg);
-void throttle_group_get_config(BlockBackend *blk, ThrottleConfig *cfg);
+void throttle_group_config(BlockDriverState *bs, ThrottleConfig *cfg);
+void throttle_group_get_config(BlockDriverState *bs, ThrottleConfig *cfg);
 
-void throttle_group_register_blk(BlockBackend *blk, const char *groupname);
-void throttle_group_unregister_blk(BlockBackend *blk);
-void throttle_group_restart_blk(BlockBackend *blk);
+void throttle_group_register_bs(BlockDriverState *bs, const char *groupname);
+void throttle_group_unregister_bs(BlockDriverState *bs);
 
-void coroutine_fn throttle_group_co_io_limits_intercept(BlockBackend *blk,
+void coroutine_fn throttle_group_co_io_limits_intercept(BlockDriverState *bs,
                                                         unsigned int bytes,
                                                         bool is_write);
 
index 12fb321..a006da2 100644 (file)
@@ -10,13 +10,14 @@ struct aes_key_st {
 };
 typedef struct aes_key_st AES_KEY;
 
-/* FreeBSD/OpenSSL have their own AES functions with the same names in -lcrypto
- * (which might be pulled in via curl), so redefine to avoid conflicts. */
+/* FreeBSD has its own AES_set_decrypt_key in -lcrypto, avoid conflicts */
+#ifdef __FreeBSD__
 #define AES_set_encrypt_key QEMU_AES_set_encrypt_key
 #define AES_set_decrypt_key QEMU_AES_set_decrypt_key
 #define AES_encrypt QEMU_AES_encrypt
 #define AES_decrypt QEMU_AES_decrypt
 #define AES_cbc_encrypt QEMU_AES_cbc_encrypt
+#endif
 
 int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
        AES_KEY *key);
index 7dd21f0..4cc4ca4 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_AFSPLIT_H
-#define QCRYPTO_AFSPLIT_H
+#ifndef QCRYPTO_AFSPLIT_H__
+#define QCRYPTO_AFSPLIT_H__
 
 #include "crypto/hash.h"
 
@@ -132,4 +132,4 @@ int qcrypto_afsplit_decode(QCryptoHashAlgorithm hash,
                            uint8_t *out,
                            Error **errp);
 
-#endif /* QCRYPTO_AFSPLIT_H */
+#endif /* QCRYPTO_AFSPLIT_H__ */
index b6971de..a21e11f 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_BLOCK_H
-#define QCRYPTO_BLOCK_H
+#ifndef QCRYPTO_BLOCK_H__
+#define QCRYPTO_BLOCK_H__
 
 #include "crypto/cipher.h"
 #include "crypto/ivgen.h"
@@ -138,22 +138,6 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
                                    void *opaque,
                                    Error **errp);
 
-
-/**
- * qcrypto_block_get_info:
- * @block: the block encryption object
- * @errp: pointer to a NULL-initialized error object
- *
- * Get information about the configuration options for the
- * block encryption object. This includes details such as
- * the cipher algorithms, modes, and initialization vector
- * generators.
- *
- * Returns: a block encryption info object, or NULL on error
- */
-QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
-                                         Error **errp);
-
 /**
  * @qcrypto_block_decrypt:
  * @block: the block encryption object
@@ -245,4 +229,4 @@ uint64_t qcrypto_block_get_payload_offset(QCryptoBlock *block);
  */
 void qcrypto_block_free(QCryptoBlock *block);
 
-#endif /* QCRYPTO_BLOCK_H */
+#endif /* QCRYPTO_BLOCK_H__ */
index 376654d..d770c48 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_CIPHER_H
-#define QCRYPTO_CIPHER_H
+#ifndef QCRYPTO_CIPHER_H__
+#define QCRYPTO_CIPHER_H__
 
 #include "qapi-types.h"
 
@@ -230,4 +230,4 @@ int qcrypto_cipher_setiv(QCryptoCipher *cipher,
                          const uint8_t *iv, size_t niv,
                          Error **errp);
 
-#endif /* QCRYPTO_CIPHER_H */
+#endif /* QCRYPTO_CIPHER_H__ */
index 7ca596c..773667e 100644 (file)
@@ -9,9 +9,8 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
-
-#ifndef QCRYPTO_DESRFB_H
-#define QCRYPTO_DESRFB_H
+#ifndef D3DES_H
+#define D3DES_H 1
 
 /* d3des.h -
  *
index ca3267f..f38caed 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_HASH_H
-#define QCRYPTO_HASH_H
+#ifndef QCRYPTO_HASH_H__
+#define QCRYPTO_HASH_H__
 
 #include "qapi-types.h"
 
@@ -189,4 +189,4 @@ int qcrypto_hash_base64(QCryptoHashAlgorithm alg,
                         char **base64,
                         Error **errp);
 
-#endif /* QCRYPTO_HASH_H */
+#endif /* QCRYPTO_HASH_H__ */
index 04c1edf..2513ed0 100644 (file)
@@ -18,9 +18,9 @@
  *
  */
 
-#ifndef QCRYPTO_INIT_H
-#define QCRYPTO_INIT_H
+#ifndef QCRYPTO_INIT_H__
+#define QCRYPTO_INIT_H__
 
 int qcrypto_init(Error **errp);
 
-#endif /* QCRYPTO_INIT_H */
+#endif /* QCRYPTO_INIT_H__ */
index 0350cd2..09cdb6f 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_IVGEN_H
-#define QCRYPTO_IVGEN_H
+#ifndef QCRYPTO_IVGEN_H__
+#define QCRYPTO_IVGEN_H__
 
 #include "crypto/cipher.h"
 #include "crypto/hash.h"
@@ -203,4 +203,4 @@ QCryptoHashAlgorithm qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen);
  */
 void qcrypto_ivgen_free(QCryptoIVGen *ivgen);
 
-#endif /* QCRYPTO_IVGEN_H */
+#endif /* QCRYPTO_IVGEN_H__ */
index e9e4cec..58a1fe6 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_PBKDF_H
-#define QCRYPTO_PBKDF_H
+#ifndef QCRYPTO_PBKDF_H__
+#define QCRYPTO_PBKDF_H__
 
 #include "crypto/hash.h"
 
@@ -149,4 +149,4 @@ int qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash,
                                const uint8_t *salt, size_t nsalt,
                                Error **errp);
 
-#endif /* QCRYPTO_PBKDF_H */
+#endif /* QCRYPTO_PBKDF_H__ */
index a101353..f9308f4 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_RANDOM_H
-#define QCRYPTO_RANDOM_H
+#ifndef QCRYPTO_RANDOM_H__
+#define QCRYPTO_RANDOM_H__
 
 #include "qemu-common.h"
 #include "qapi/error.h"
@@ -41,4 +41,4 @@ int qcrypto_random_bytes(uint8_t *buf,
                          Error **errp);
 
 
-#endif /* QCRYPTO_RANDOM_H */
+#endif /* QCRYPTO_RANDOM_H__ */
index 07a963e..b7392c6 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_SECRET_H
-#define QCRYPTO_SECRET_H
+#ifndef QCRYPTO_SECRET_H__
+#define QCRYPTO_SECRET_H__
 
 #include "qom/object.h"
 
@@ -143,4 +143,4 @@ extern char *qcrypto_secret_lookup_as_utf8(const char *secretid,
 extern char *qcrypto_secret_lookup_as_base64(const char *secretid,
                                              Error **errp);
 
-#endif /* QCRYPTO_SECRET_H */
+#endif /* QCRYPTO_SECRET_H__ */
index ad47d88..8e2babd 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_TLSCREDS_H
-#define QCRYPTO_TLSCREDS_H
+#ifndef QCRYPTO_TLSCRED_H__
+#define QCRYPTO_TLSCRED_H__
 
 #include "qom/object.h"
 
@@ -54,7 +54,6 @@ struct QCryptoTLSCreds {
     gnutls_dh_params_t dh_params;
 #endif
     bool verifyPeer;
-    char *priority;
 };
 
 
@@ -63,4 +62,5 @@ struct QCryptoTLSCredsClass {
 };
 
 
-#endif /* QCRYPTO_TLSCREDS_H */
+#endif /* QCRYPTO_TLSCRED_H__ */
+
index 4d6b7e4..d3976b8 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_TLSCREDSANON_H
-#define QCRYPTO_TLSCREDSANON_H
+#ifndef QCRYPTO_TLSCRED_ANON_H__
+#define QCRYPTO_TLSCRED_ANON_H__
 
 #include "crypto/tlscreds.h"
 
@@ -108,4 +108,5 @@ struct QCryptoTLSCredsAnonClass {
 };
 
 
-#endif /* QCRYPTO_TLSCREDSANON_H */
+#endif /* QCRYPTO_TLSCRED_H__ */
+
index 66ad6a7..25796d7 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_TLSCREDSX509_H
-#define QCRYPTO_TLSCREDSX509_H
+#ifndef QCRYPTO_TLSCRED_X509_H__
+#define QCRYPTO_TLSCRED_X509_H__
 
 #include "crypto/tlscreds.h"
 
@@ -110,4 +110,5 @@ struct QCryptoTLSCredsX509Class {
 };
 
 
-#endif /* QCRYPTO_TLSCREDSX509_H */
+#endif /* QCRYPTO_TLSCRED_X509_H__ */
+
index 1c7414e..c1bad9e 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QCRYPTO_TLSSESSION_H
-#define QCRYPTO_TLSSESSION_H
+#ifndef QCRYPTO_TLS_SESSION_H__
+#define QCRYPTO_TLS_SESSION_H__
 
 #include "crypto/tlscreds.h"
 
@@ -319,4 +319,4 @@ int qcrypto_tls_session_get_key_size(QCryptoTLSSession *sess,
  */
 char *qcrypto_tls_session_get_peer_name(QCryptoTLSSession *sess);
 
-#endif /* QCRYPTO_TLSSESSION_H */
+#endif /* QCRYPTO_TLS_SESSION_H__ */
index da32ab8..c2924d8 100644 (file)
@@ -23,8 +23,9 @@
  *
  */
 
-#ifndef QCRYPTO_XTS_H
-#define QCRYPTO_XTS_H
+
+#ifndef QCRYPTO_XTS_H_
+#define QCRYPTO_XTS_H_
 
 #include "qemu-common.h"
 #include "qapi/error.h"
@@ -82,4 +83,4 @@ void xts_encrypt(const void *datactx,
                  const uint8_t *src);
 
 
-#endif /* QCRYPTO_XTS_H */
+#endif /* QCRYPTO_XTS_H_ */
index 8a3488c..a112e9c 100644 (file)
@@ -6,10 +6,10 @@
    interface, for making instruction-processing programs more independent
    of the instruction set being processed.  */
 
-#ifndef DISAS_BFD_H
-#define DISAS_BFD_H
+#ifndef DIS_ASM_H
+#define DIS_ASM_H
 
-#include "qemu/fprintf-fn.h"
+#include "qemu-common.h"
 
 typedef void *PTR;
 typedef uint64_t bfd_vma;
@@ -477,9 +477,8 @@ int generic_symbol_at_address(bfd_vma, struct disassemble_info *);
   (INFO).disassembler_options = NULL, \
   (INFO).insn_info_valid = 0
 
-#ifndef ATTRIBUTE_UNUSED
+#define _(x) x
 #define ATTRIBUTE_UNUSED __attribute__((unused))
-#endif
 
 /* from libbfd */
 
@@ -490,4 +489,4 @@ bfd_vma bfd_getl16 (const bfd_byte *addr);
 bfd_vma bfd_getb16 (const bfd_byte *addr);
 typedef bool bfd_boolean;
 
-#endif /* DISAS_BFD_H */
+#endif /* ! defined (DIS_ASM_H) */
index e549ca2..2b9293b 100644 (file)
@@ -1,11 +1,9 @@
-#ifndef QEMU_DISAS_H
-#define QEMU_DISAS_H
+#ifndef _QEMU_DISAS_H
+#define _QEMU_DISAS_H
 
 #include "qemu-common.h"
 
 #ifdef NEED_CPU_H
-#include "cpu.h"
-
 /* Disassemble this for me please... (debugging). */
 void disas(FILE *out, void *code, unsigned long size);
 void target_disas(FILE *out, CPUState *cpu, target_ulong code,
@@ -42,4 +40,4 @@ struct syminfo {
 /* Filled in by elfload.c.  Simplistic, but will do for now. */
 extern struct syminfo *syminfos;
 
-#endif /* QEMU_DISAS_H */
+#endif /* _QEMU_DISAS_H */
index 1c2975d..28d448b 100644 (file)
@@ -1,5 +1,6 @@
-#ifndef QEMU_ELF_H
-#define QEMU_ELF_H
+#ifndef _QEMU_ELF_H
+#define _QEMU_ELF_H
+
 
 /* 32-bit ELF base types. */
 typedef uint32_t Elf32_Addr;
@@ -52,8 +53,6 @@ typedef int64_t  Elf64_Sxword;
 #define EF_MIPS_OPTIONS_FIRST  0x00000080
 #define EF_MIPS_32BITMODE      0x00000100
 #define EF_MIPS_ABI            0x0000f000
-#define EF_MIPS_FP64      0x00000200
-#define EF_MIPS_NAN2008   0x00000400
 #define EF_MIPS_ARCH      0xf0000000
 
 /* These constants define the different elf file types */
@@ -478,19 +477,6 @@ typedef struct {
 #define PPC_FEATURE_TRUE_LE             0x00000002
 #define PPC_FEATURE_PPC_LE              0x00000001
 
-/* Bits present in AT_HWCAP2 for PowerPC.  */
-
-#define PPC_FEATURE2_ARCH_2_07          0x80000000
-#define PPC_FEATURE2_HAS_HTM            0x40000000
-#define PPC_FEATURE2_HAS_DSCR           0x20000000
-#define PPC_FEATURE2_HAS_EBB            0x10000000
-#define PPC_FEATURE2_HAS_ISEL           0x08000000
-#define PPC_FEATURE2_HAS_TAR            0x04000000
-#define PPC_FEATURE2_HAS_VEC_CRYPTO     0x02000000
-#define PPC_FEATURE2_HTM_NOSC           0x01000000
-#define PPC_FEATURE2_ARCH_3_00          0x00800000
-#define PPC_FEATURE2_HAS_IEEE128        0x00400000
-
 /* Bits present in AT_HWCAP for Sparc.  */
 
 #define HWCAP_SPARC_FLUSH               0x00000001
@@ -1572,4 +1558,4 @@ struct elf32_fdpic_loadmap {
 #endif /* ELF_CLASS */
 
 
-#endif /* QEMU_ELF_H */
+#endif /* _QEMU_ELF_H */
index db8bfa9..3d12cdd 100644 (file)
@@ -11,8 +11,8 @@
  *
  */
 
-#ifndef EXEC_ADDRESS_SPACES_H
-#define EXEC_ADDRESS_SPACES_H
+#ifndef EXEC_MEMORY_H
+#define EXEC_MEMORY_H
 
 /*
  * Internal interfaces between memory.c/exec.c/vl.c.  Do not #include unless
index b6a7059..08e5093 100644 (file)
 
 /* some important defines:
  *
+ * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
+ * memory accesses.
+ *
  * HOST_WORDS_BIGENDIAN : if defined, the host cpu is big endian and
  * otherwise little endian.
  *
+ * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
+ *
  * TARGET_WORDS_BIGENDIAN : same for target cpu
  */
 
@@ -160,31 +165,6 @@ extern unsigned long reserved_va;
 
 #define GUEST_ADDR_MAX (reserved_va ? reserved_va : \
                                     (1ul << TARGET_VIRT_ADDR_SPACE_BITS) - 1)
-#else
-
-#include "exec/hwaddr.h"
-uint32_t lduw_phys(AddressSpace *as, hwaddr addr);
-uint32_t ldl_phys(AddressSpace *as, hwaddr addr);
-uint64_t ldq_phys(AddressSpace *as, hwaddr addr);
-void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val);
-void stw_phys(AddressSpace *as, hwaddr addr, uint32_t val);
-void stl_phys(AddressSpace *as, hwaddr addr, uint32_t val);
-void stq_phys(AddressSpace *as, hwaddr addr, uint64_t val);
-
-uint32_t address_space_lduw(AddressSpace *as, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint32_t address_space_ldl(AddressSpace *as, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-uint64_t address_space_ldq(AddressSpace *as, hwaddr addr,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stl_notdirty(AddressSpace *as, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stw(AddressSpace *as, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stl(AddressSpace *as, hwaddr addr, uint32_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
-void address_space_stq(AddressSpace *as, hwaddr addr, uint64_t val,
-                            MemTxAttrs attrs, MemTxResult *result);
 #endif
 
 /* page related stuff */
@@ -288,22 +268,14 @@ CPUArchState *cpu_copy(CPUArchState *env);
 #if !defined(CONFIG_USER_ONLY)
 
 /* Flags stored in the low bits of the TLB virtual address.  These are
- * defined so that fast path ram access is all zeros.
- * The flags all must be between TARGET_PAGE_BITS and
- * maximum address alignment bit.
- */
+   defined so that fast path ram access is all zeros.  */
 /* Zero if TLB entry is valid.  */
-#define TLB_INVALID_MASK    (1 << (TARGET_PAGE_BITS - 1))
+#define TLB_INVALID_MASK   (1 << 3)
 /* Set if TLB entry references a clean RAM page.  The iotlb entry will
    contain the page physical address.  */
-#define TLB_NOTDIRTY        (1 << (TARGET_PAGE_BITS - 2))
+#define TLB_NOTDIRTY    (1 << 4)
 /* Set if TLB entry is an IO callback.  */
-#define TLB_MMIO            (1 << (TARGET_PAGE_BITS - 3))
-
-/* Use this mask to check interception with an alignment mask
- * in a TCG backend.
- */
-#define TLB_FLAGS_MASK  (TLB_INVALID_MASK | TLB_NOTDIRTY | TLB_MMIO)
+#define TLB_MMIO        (1 << 5)
 
 void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
 void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf);
@@ -312,6 +284,4 @@ void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf);
 int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
                         uint8_t *buf, int len, int is_write);
 
-int cpu_exec(CPUState *cpu);
-
 #endif /* CPU_ALL_H */
index 952bcfe..9e839e5 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef CPU_COMMON_H
-#define CPU_COMMON_H
+#define CPU_COMMON_H 1
 
 /* CPU interfaces that are target independent.  */
 
@@ -7,6 +7,10 @@
 #include "exec/hwaddr.h"
 #endif
 
+#ifndef NEED_CPU_H
+#include "exec/poison.h"
+#endif
+
 #include "qemu/bswap.h"
 #include "qemu/queue.h"
 #include "qemu/fprintf-fn.h"
@@ -23,6 +27,12 @@ typedef struct CPUListState {
     FILE *file;
 } CPUListState;
 
+typedef enum MMUAccessType {
+    MMU_DATA_LOAD  = 0,
+    MMU_DATA_STORE = 1,
+    MMU_INST_FETCH = 2
+} MMUAccessType;
+
 #if !defined(CONFIG_USER_ONLY)
 
 enum device_endian {
@@ -51,12 +61,12 @@ typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
 
 void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
 /* This should not be used by devices.  */
-ram_addr_t qemu_ram_addr_from_host(void *ptr);
+MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
 RAMBlock *qemu_ram_block_by_name(const char *name);
 RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
-                                   ram_addr_t *offset);
-void qemu_ram_set_idstr(RAMBlock *block, const char *name, DeviceState *dev);
-void qemu_ram_unset_idstr(RAMBlock *block);
+                                   ram_addr_t *ram_addr, ram_addr_t *offset);
+void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev);
+void qemu_ram_unset_idstr(ram_addr_t addr);
 const char *qemu_ram_get_idstr(RAMBlock *rb);
 
 void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
@@ -103,6 +113,16 @@ void stl_be_phys(AddressSpace *as, hwaddr addr, uint32_t val);
 void stq_le_phys(AddressSpace *as, hwaddr addr, uint64_t val);
 void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val);
 
+#ifdef NEED_CPU_H
+uint32_t lduw_phys(AddressSpace *as, hwaddr addr);
+uint32_t ldl_phys(AddressSpace *as, hwaddr addr);
+uint64_t ldq_phys(AddressSpace *as, hwaddr addr);
+void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val);
+void stw_phys(AddressSpace *as, hwaddr addr, uint32_t val);
+void stl_phys(AddressSpace *as, hwaddr addr, uint32_t val);
+void stq_phys(AddressSpace *as, hwaddr addr, uint64_t val);
+#endif
+
 void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr,
                                    const uint8_t *buf, int len);
 void cpu_flush_icache_range(hwaddr start, int len);
@@ -117,4 +137,4 @@ int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque);
 
 #endif
 
-#endif /* CPU_COMMON_H */
+#endif /* !CPU_COMMON_H */
index 5f4e303..854e7e3 100644 (file)
@@ -23,7 +23,6 @@
 #error cpu.h included from common code
 #endif
 
-#include "qemu/host-utils.h"
 #include "qemu/queue.h"
 #include "tcg-target.h"
 #ifndef CONFIG_USER_ONLY
index eaf69a1..3091c00 100644 (file)
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-
-#if !defined(SOFTMMU_CODE_ACCESS)
-#include "trace.h"
-#endif
-
-#include "trace/mem.h"
-
 #if DATA_SIZE == 8
 #define SUFFIX q
 #define USUFFIX q
@@ -87,12 +80,6 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
     int mmu_idx;
     TCGMemOpIdx oi;
 
-#if !defined(SOFTMMU_CODE_ACCESS)
-    trace_guest_mem_before_exec(
-        ENV_GET_CPU(env), ptr,
-        trace_mem_build_info(SHIFT, false, MO_TE, false));
-#endif
-
     addr = ptr;
     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     mmu_idx = CPU_MMU_INDEX;
@@ -125,12 +112,6 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
     int mmu_idx;
     TCGMemOpIdx oi;
 
-#if !defined(SOFTMMU_CODE_ACCESS)
-    trace_guest_mem_before_exec(
-        ENV_GET_CPU(env), ptr,
-        trace_mem_build_info(SHIFT, true, MO_TE, false));
-#endif
-
     addr = ptr;
     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     mmu_idx = CPU_MMU_INDEX;
@@ -167,12 +148,6 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
     int mmu_idx;
     TCGMemOpIdx oi;
 
-#if !defined(SOFTMMU_CODE_ACCESS)
-    trace_guest_mem_before_exec(
-        ENV_GET_CPU(env), ptr,
-        trace_mem_build_info(SHIFT, false, MO_TE, true));
-#endif
-
     addr = ptr;
     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     mmu_idx = CPU_MMU_INDEX;
index b1378bf..040b147 100644 (file)
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-
-#if !defined(CODE_ACCESS)
-#include "trace.h"
-#endif
-
-#include "trace/mem.h"
-
 #if DATA_SIZE == 8
 #define SUFFIX q
 #define USUFFIX q
 static inline RES_TYPE
 glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
 {
-#if !defined(CODE_ACCESS)
-    trace_guest_mem_before_exec(
-        ENV_GET_CPU(env), ptr,
-        trace_mem_build_info(DATA_SIZE, false, MO_TE, false));
-#endif
     return glue(glue(ld, USUFFIX), _p)(g2h(ptr));
 }
 
@@ -80,11 +68,6 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
 static inline int
 glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
 {
-#if !defined(CODE_ACCESS)
-    trace_guest_mem_before_exec(
-        ENV_GET_CPU(env), ptr,
-        trace_mem_build_info(DATA_SIZE, true, MO_TE, false));
-#endif
     return glue(glue(lds, SUFFIX), _p)(g2h(ptr));
 }
 
@@ -102,11 +85,6 @@ static inline void
 glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
                                       RES_TYPE v)
 {
-#if !defined(CODE_ACCESS)
-    trace_guest_mem_before_exec(
-        ENV_GET_CPU(env), ptr,
-        trace_mem_build_info(DATA_SIZE, false, MO_TE, true));
-#endif
     glue(glue(st, SUFFIX), _p)(g2h(ptr), v);
 }
 
index d008296..7362095 100644 (file)
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef EXEC_ALL_H
-#define EXEC_ALL_H
+#ifndef _EXEC_ALL_H_
+#define _EXEC_ALL_H_
 
 #include "qemu-common.h"
-#include "exec/tb-context.h"
 
 /* allow to see translation results - the slowdown should be negligible, so we leave it */
 #define DEBUG_DISAS
@@ -41,6 +40,30 @@ typedef ram_addr_t tb_page_addr_t;
 #define DISAS_UPDATE  2 /* cpu state was modified dynamically */
 #define DISAS_TB_JUMP 3 /* only pc was modified statically */
 
+struct TranslationBlock;
+typedef struct TranslationBlock TranslationBlock;
+
+/* XXX: make safe guess about sizes */
+#define MAX_OP_PER_INSTR 266
+
+#if HOST_LONG_BITS == 32
+#define MAX_OPC_PARAM_PER_ARG 2
+#else
+#define MAX_OPC_PARAM_PER_ARG 1
+#endif
+#define MAX_OPC_PARAM_IARGS 5
+#define MAX_OPC_PARAM_OARGS 1
+#define MAX_OPC_PARAM_ARGS (MAX_OPC_PARAM_IARGS + MAX_OPC_PARAM_OARGS)
+
+/* A Call op needs up to 4 + 2N parameters on 32-bit archs,
+ * and up to 4 + N parameters on 64-bit archs
+ * (N = number of input arguments + output arguments).  */
+#define MAX_OPC_PARAM (4 + (MAX_OPC_PARAM_PER_ARG * MAX_OPC_PARAM_ARGS))
+#define OPC_BUF_SIZE 640
+#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
+
+#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM)
+
 #include "qemu/log.h"
 
 void gen_intermediate_code(CPUArchState *env, struct TranslationBlock *tb);
@@ -50,24 +73,11 @@ void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
 void cpu_gen_init(void);
 bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc);
 
-void QEMU_NORETURN cpu_loop_exit_noexc(CPUState *cpu);
+void QEMU_NORETURN cpu_resume_from_signal(CPUState *cpu, void *puc);
 void QEMU_NORETURN cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
 TranslationBlock *tb_gen_code(CPUState *cpu,
-                              target_ulong pc, target_ulong cs_base,
-                              uint32_t flags,
+                              target_ulong pc, target_ulong cs_base, int flags,
                               int cflags);
-#if defined(CONFIG_USER_ONLY)
-void cpu_list_lock(void);
-void cpu_list_unlock(void);
-#else
-static inline void cpu_list_unlock(void)
-{
-}
-static inline void cpu_list_lock(void)
-{
-}
-#endif
-
 void cpu_exec_init(CPUState *cpu, Error **errp);
 void QEMU_NORETURN cpu_loop_exit(CPUState *cpu);
 void QEMU_NORETURN cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc);
@@ -93,6 +103,15 @@ void cpu_reloading_memory_map(void);
  * Note that with KVM only one address space is supported.
  */
 void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx);
+/**
+ * cpu_get_address_space:
+ * @cpu: CPU to get address space from
+ * @asidx: index identifying which address space to get
+ *
+ * Return the requested address space of this CPU. @asidx
+ * specifies which address space to read.
+ */
+AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx);
 /* cputlb.c */
 /**
  * tlb_flush_page:
@@ -192,6 +211,9 @@ static inline void tlb_flush_by_mmuidx(CPUState *cpu, ...)
 
 #define CODE_GEN_ALIGN           16 /* must be >= of the size of a icache line */
 
+#define CODE_GEN_PHYS_HASH_BITS     15
+#define CODE_GEN_PHYS_HASH_SIZE     (1 << CODE_GEN_PHYS_HASH_BITS)
+
 /* Estimated block size for TB allocation.  */
 /* ??? The following is based on a 2015 survey of x86_64 host output.
    Better would seem to be some sort of dynamically sized TB array,
@@ -207,14 +229,13 @@ static inline void tlb_flush_by_mmuidx(CPUState *cpu, ...)
     || defined(__sparc__) || defined(__aarch64__) \
     || defined(__s390x__) || defined(__mips__) \
     || defined(CONFIG_TCG_INTERPRETER)
-/* NOTE: Direct jump patching must be atomic to be thread-safe. */
 #define USE_DIRECT_JUMP
 #endif
 
 struct TranslationBlock {
     target_ulong pc;   /* simulated PC corresponding to this block (EIP + CS base) */
     target_ulong cs_base; /* CS base for this block */
-    uint32_t flags; /* flags defining in which context the code was generated */
+    uint64_t flags; /* flags defining in which context the code was generated */
     uint16_t size;      /* size of target code for this block (1 <=
                            size <= TARGET_PAGE_SIZE) */
     uint16_t icount;
@@ -227,6 +248,8 @@ struct TranslationBlock {
 
     void *tc_ptr;    /* pointer to the translated code */
     uint8_t *tc_search;  /* pointer to search data */
+    /* next matching tb for physical address. */
+    struct TranslationBlock *phys_hash_next;
     /* original tb when cflags has CF_NOCACHE */
     struct TranslationBlock *orig_tb;
     /* first and second physical page containing code. The lower bit
@@ -234,34 +257,39 @@ struct TranslationBlock {
     struct TranslationBlock *page_next[2];
     tb_page_addr_t page_addr[2];
 
-    /* The following data are used to directly call another TB from
-     * the code of this one. This can be done either by emitting direct or
-     * indirect native jump instructions. These jumps are reset so that the TB
-     * just continue its execution. The TB can be linked to another one by
-     * setting one of the jump targets (or patching the jump instruction). Only
-     * two of such jumps are supported.
-     */
-    uint16_t jmp_reset_offset[2]; /* offset of original jump target */
-#define TB_JMP_RESET_OFFSET_INVALID 0xffff /* indicates no jump generated */
+    /* the following data are used to directly call another TB from
+       the code of this one. */
+    uint16_t tb_next_offset[2]; /* offset of original jump target */
 #ifdef USE_DIRECT_JUMP
-    uint16_t jmp_insn_offset[2]; /* offset of native jump instruction */
+    uint16_t tb_jmp_offset[2]; /* offset of jump instruction */
 #else
-    uintptr_t jmp_target_addr[2]; /* target address for indirect jump */
+    uintptr_t tb_next[2]; /* address of jump generated code */
 #endif
-    /* Each TB has an assosiated circular list of TBs jumping to this one.
-     * jmp_list_first points to the first TB jumping to this one.
-     * jmp_list_next is used to point to the next TB in a list.
-     * Since each TB can have two jumps, it can participate in two lists.
-     * jmp_list_first and jmp_list_next are 4-byte aligned pointers to a
-     * TranslationBlock structure, but the two least significant bits of
-     * them are used to encode which data field of the pointed TB should
-     * be used to traverse the list further from that TB:
-     * 0 => jmp_list_next[0], 1 => jmp_list_next[1], 2 => jmp_list_first.
-     * In other words, 0/1 tells which jump is used in the pointed TB,
-     * and 2 means that this is a pointer back to the target TB of this list.
-     */
-    uintptr_t jmp_list_next[2];
-    uintptr_t jmp_list_first;
+    /* list of TBs jumping to this one. This is a circular list using
+       the two least significant bits of the pointers to tell what is
+       the next pointer: 0 = jmp_next[0], 1 = jmp_next[1], 2 =
+       jmp_first */
+    struct TranslationBlock *jmp_next[2];
+    struct TranslationBlock *jmp_first;
+};
+
+#include "qemu/thread.h"
+
+typedef struct TBContext TBContext;
+
+struct TBContext {
+
+    TranslationBlock *tbs;
+    TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
+    int nb_tbs;
+    /* any access to the tbs or the page table must use this lock */
+    QemuMutex tb_lock;
+
+    /* statistics */
+    int tb_flush_count;
+    int tb_phys_invalidate_count;
+
+    int tb_invalidated_flag;
 };
 
 void tb_free(TranslationBlock *tb);
@@ -274,7 +302,7 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
 static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
 {
     /* patch the branch destination */
-    atomic_set((int32_t *)jmp_addr, addr - (jmp_addr + 4));
+    *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
     /* no need to flush icache explicitly */
 }
 #elif defined(_ARCH_PPC)
@@ -284,7 +312,7 @@ void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr);
 static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
 {
     /* patch the branch destination */
-    atomic_set((int32_t *)jmp_addr, addr - (jmp_addr + 4));
+    stl_le_p((void*)jmp_addr, addr - (jmp_addr + 4));
     /* no need to flush icache explicitly */
 }
 #elif defined(__s390x__)
@@ -292,15 +320,36 @@ static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
 {
     /* patch the branch destination */
     intptr_t disp = addr - (jmp_addr - 2);
-    atomic_set((int32_t *)jmp_addr, disp / 2);
+    stl_be_p((void*)jmp_addr, disp / 2);
     /* no need to flush icache explicitly */
 }
 #elif defined(__aarch64__)
 void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr);
 #define tb_set_jmp_target1 aarch64_tb_set_jmp_target
 #elif defined(__arm__)
-void arm_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr);
-#define tb_set_jmp_target1 arm_tb_set_jmp_target
+static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
+{
+#if !QEMU_GNUC_PREREQ(4, 1)
+    register unsigned long _beg __asm ("a1");
+    register unsigned long _end __asm ("a2");
+    register unsigned long _flg __asm ("a3");
+#endif
+
+    /* we could use a ldr pc, [pc, #-4] kind of branch and avoid the flush */
+    *(uint32_t *)jmp_addr =
+        (*(uint32_t *)jmp_addr & ~0xffffff)
+        | (((addr - (jmp_addr + 8)) >> 2) & 0xffffff);
+
+#if QEMU_GNUC_PREREQ(4, 1)
+    __builtin___clear_cache((char *) jmp_addr, (char *) jmp_addr + 4);
+#else
+    /* flush icache */
+    _beg = jmp_addr;
+    _end = jmp_addr + 4;
+    _flg = 0;
+    __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
+#endif
+}
 #elif defined(__sparc__) || defined(__mips__)
 void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr);
 #else
@@ -310,7 +359,7 @@ void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr);
 static inline void tb_set_jmp_target(TranslationBlock *tb,
                                      int n, uintptr_t addr)
 {
-    uint16_t offset = tb->jmp_insn_offset[n];
+    uint16_t offset = tb->tb_jmp_offset[n];
     tb_set_jmp_target1((uintptr_t)(tb->tc_ptr + offset), addr);
 }
 
@@ -320,7 +369,7 @@ static inline void tb_set_jmp_target(TranslationBlock *tb,
 static inline void tb_set_jmp_target(TranslationBlock *tb,
                                      int n, uintptr_t addr)
 {
-    tb->jmp_target_addr[n] = addr;
+    tb->tb_next[n] = addr;
 }
 
 #endif
@@ -328,23 +377,20 @@ static inline void tb_set_jmp_target(TranslationBlock *tb,
 static inline void tb_add_jump(TranslationBlock *tb, int n,
                                TranslationBlock *tb_next)
 {
-    if (tb->jmp_list_next[n]) {
-        /* Another thread has already done this while we were
-         * outside of the lock; nothing to do in this case */
-        return;
+    /* NOTE: this test is only needed for thread safety */
+    if (!tb->jmp_next[n]) {
+        qemu_log_mask_and_addr(CPU_LOG_EXEC, tb->pc,
+                               "Linking TBs %p [" TARGET_FMT_lx
+                               "] index %d -> %p [" TARGET_FMT_lx "]\n",
+                               tb->tc_ptr, tb->pc, n,
+                               tb_next->tc_ptr, tb_next->pc);
+        /* patch the native jump address */
+        tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr);
+
+        /* add in TB jmp circular list */
+        tb->jmp_next[n] = tb_next->jmp_first;
+        tb_next->jmp_first = (TranslationBlock *)((uintptr_t)(tb) | (n));
     }
-    qemu_log_mask_and_addr(CPU_LOG_EXEC, tb->pc,
-                           "Linking TBs %p [" TARGET_FMT_lx
-                           "] index %d -> %p [" TARGET_FMT_lx "]\n",
-                           tb->tc_ptr, tb->pc, n,
-                           tb_next->tc_ptr, tb_next->pc);
-
-    /* patch the native jump address */
-    tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr);
-
-    /* add in TB jmp circular list */
-    tb->jmp_list_next[n] = tb_next->jmp_list_first;
-    tb_next->jmp_list_first = (uintptr_t)tb | n;
 }
 
 /* GETRA is the true target of the return instruction that we'll execute,
@@ -373,8 +419,8 @@ extern uintptr_t tci_tb_ptr;
 struct MemoryRegion *iotlb_to_region(CPUState *cpu,
                                      hwaddr index, MemTxAttrs attrs);
 
-void tlb_fill(CPUState *cpu, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr);
+void tlb_fill(CPUState *cpu, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr);
 
 #endif
 
index f9708bb..d9e8cf7 100644 (file)
@@ -11,8 +11,6 @@
 #define GDB_WATCHPOINT_ACCESS    4
 
 #ifdef NEED_CPU_H
-#include "cpu.h"
-
 typedef void (*gdb_syscall_complete_cb)(CPUState *cpu,
                                         target_ulong ret, target_ulong err);
 
@@ -48,6 +46,7 @@ int use_gdb_syscalls(void);
 void gdb_set_stop_cpu(CPUState *cpu);
 void gdb_exit(CPUArchState *, int);
 #ifdef CONFIG_USER_ONLY
+int gdb_queuesig (void);
 int gdb_handlesig(CPUState *, int);
 void gdb_signalled(CPUArchState *, int);
 void gdbserver_fork(CPUState *);
index 050de59..05d89d3 100644 (file)
@@ -1,17 +1,18 @@
 #ifndef GEN_ICOUNT_H
-#define GEN_ICOUNT_H
+#define GEN_ICOUNT_H 1
 
 #include "qemu/timer.h"
 
 /* Helpers for instruction counting code generation.  */
 
-static int icount_start_insn_idx;
+static TCGArg *icount_arg;
 static TCGLabel *icount_label;
 static TCGLabel *exitreq_label;
 
 static inline void gen_tb_start(TranslationBlock *tb)
 {
     TCGv_i32 count, flag, imm;
+    int i;
 
     exitreq_label = gen_new_label();
     flag = tcg_temp_new_i32();
@@ -30,12 +31,13 @@ static inline void gen_tb_start(TranslationBlock *tb)
                    -ENV_OFFSET + offsetof(CPUState, icount_decr.u32));
 
     imm = tcg_temp_new_i32();
-    /* We emit a movi with a dummy immediate argument. Keep the insn index
-     * of the movi so that we later (when we know the actual insn count)
-     * can update the immediate argument with the actual insn count.  */
-    icount_start_insn_idx = tcg_op_buf_count();
     tcg_gen_movi_i32(imm, 0xdeadbeef);
 
+    /* This is a horrid hack to allow fixing up the value later.  */
+    i = tcg_ctx.gen_last_op_idx;
+    i = tcg_ctx.gen_op_buf[i].args;
+    icount_arg = &tcg_ctx.gen_opparam_buf[i + 1];
+
     tcg_gen_sub_i32(count, count, imm);
     tcg_temp_free_i32(imm);
 
@@ -51,15 +53,13 @@ static void gen_tb_end(TranslationBlock *tb, int num_insns)
     tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_REQUESTED);
 
     if (tb->cflags & CF_USE_ICOUNT) {
-        /* Update the num_insn immediate parameter now that we know
-         * the actual insn count.  */
-        tcg_set_insn_param(icount_start_insn_idx, 1, num_insns);
+        *icount_arg = num_insns;
         gen_set_label(icount_label);
         tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_ICOUNT_EXPIRED);
     }
 
     /* Terminate the linked list.  */
-    tcg_ctx.gen_op_buf[tcg_ctx.gen_op_buf[0].prev].next = 0;
+    tcg_ctx.gen_op_buf[tcg_ctx.gen_last_op_idx].next = -1;
 }
 
 static inline void gen_io_start(void)
index 8239ffc..0d0da3a 100644 (file)
@@ -2,9 +2,9 @@
    This one expands generation functions for tcg opcodes.  */
 
 #ifndef HELPER_GEN_H
-#define HELPER_GEN_H
+#define HELPER_GEN_H 1
 
-#include "exec/helper-head.h"
+#include <exec/helper-head.h>
 
 #define DEF_HELPER_FLAGS_0(name, flags, ret)                            \
 static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret))        \
index 1cfc43b..ec79043 100644 (file)
@@ -15,8 +15,9 @@
     GEN_HELPER 2 to do runtime registration helper functions.
  */
 
-#ifndef EXEC_HELPER_HEAD_H
-#define EXEC_HELPER_HEAD_H
+#ifndef DEF_HELPER_H
+#define DEF_HELPER_H 1
+
 
 #define HELPER(name) glue(helper_, name)
 
 #define dh_alias_s64 i64
 #define dh_alias_f32 i32
 #define dh_alias_f64 i64
+#ifdef TARGET_LONG_BITS
+# if TARGET_LONG_BITS == 32
+#  define dh_alias_tl i32
+# else
+#  define dh_alias_tl i64
+# endif
+#endif
 #define dh_alias_ptr ptr
 #define dh_alias_void void
 #define dh_alias_noreturn noreturn
+#define dh_alias_env ptr
 #define dh_alias(t) glue(dh_alias_, t)
 
 #define dh_ctype_i32 uint32_t
 #define dh_ctype_s64 int64_t
 #define dh_ctype_f32 float32
 #define dh_ctype_f64 float64
+#define dh_ctype_tl target_ulong
 #define dh_ctype_ptr void *
 #define dh_ctype_void void
 #define dh_ctype_noreturn void QEMU_NORETURN
+#define dh_ctype_env CPUArchState *
 #define dh_ctype(t) dh_ctype_##t
 
-#ifdef NEED_CPU_H
-# ifdef TARGET_LONG_BITS
-#  if TARGET_LONG_BITS == 32
-#   define dh_alias_tl i32
-#  else
-#   define dh_alias_tl i64
-#  endif
-# endif
-# define dh_alias_env ptr
-# define dh_ctype_tl target_ulong
-# define dh_ctype_env CPUArchState *
-#endif
-
 /* We can't use glue() here because it falls foul of C preprocessor
    recursive expansion rules.  */
 #define dh_retvar_decl0_void void
 
 /* MAX_OPC_PARAM_IARGS must be set to n if last entry is DEF_HELPER_FLAGS_n. */
 
-#endif /* EXEC_HELPER_HEAD_H */
+#endif /* DEF_HELPER_H */
index 954bef8..effdd43 100644 (file)
@@ -2,9 +2,9 @@
    This one expands prototypes for the helper functions.  */
 
 #ifndef HELPER_PROTO_H
-#define HELPER_PROTO_H
+#define HELPER_PROTO_H 1
 
-#include "exec/helper-head.h"
+#include <exec/helper-head.h>
 
 #define DEF_HELPER_FLAGS_0(name, flags, ret) \
 dh_ctype(ret) HELPER(name) (void);
index bb92877..79fa3c8 100644 (file)
@@ -2,9 +2,9 @@
    This one defines data structures private to tcg.c.  */
 
 #ifndef HELPER_TCG_H
-#define HELPER_TCG_H
+#define HELPER_TCG_H 1
 
-#include "exec/helper-head.h"
+#include <exec/helper-head.h>
 
 #define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) \
   { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
index a71c93c..c9eb78f 100644 (file)
@@ -3,7 +3,6 @@
 #ifndef HWADDR_H
 #define HWADDR_H
 
-
 #define HWADDR_BITS 64
 /* hwaddr is the type of a physical address (its size can
    be different from 'target_ulong').  */
index a298b89..3bd6722 100644 (file)
 #ifndef IOPORT_H
 #define IOPORT_H
 
+#include "qemu-common.h"
+#include "qom/object.h"
+#include "exec/memory.h"
+
+typedef uint32_t pio_addr_t;
+#define FMT_pioaddr     PRIx32
+
 #define MAX_IOPORTS     (64 * 1024)
 #define IOPORTS_MASK    (MAX_IOPORTS - 1)
 
@@ -42,12 +49,12 @@ typedef struct MemoryRegionPortio {
 extern const MemoryRegionOps unassigned_io_ops;
 #endif
 
-void cpu_outb(uint32_t addr, uint8_t val);
-void cpu_outw(uint32_t addr, uint16_t val);
-void cpu_outl(uint32_t addr, uint32_t val);
-uint8_t cpu_inb(uint32_t addr);
-uint16_t cpu_inw(uint32_t addr);
-uint32_t cpu_inl(uint32_t addr);
+void cpu_outb(pio_addr_t addr, uint8_t val);
+void cpu_outw(pio_addr_t addr, uint16_t val);
+void cpu_outl(pio_addr_t addr, uint32_t val);
+uint8_t cpu_inb(pio_addr_t addr);
+uint16_t cpu_inw(pio_addr_t addr);
+uint32_t cpu_inl(pio_addr_t addr);
 
 typedef struct PortioList {
     const struct MemoryRegionPortio *ports;
index 3e4d416..e2a3e99 100644 (file)
@@ -32,8 +32,6 @@
 #include "qom/object.h"
 #include "qemu/rcu.h"
 
-#define RAM_ADDR_INVALID (~(ram_addr_t)0)
-
 #define MAX_PHYS_ADDR_SPACE_BITS 62
 #define MAX_PHYS_ADDR            (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1)
 
@@ -151,12 +149,6 @@ typedef struct MemoryRegionIOMMUOps MemoryRegionIOMMUOps;
 struct MemoryRegionIOMMUOps {
     /* Return a TLB entry that contains a given address. */
     IOMMUTLBEntry (*translate)(MemoryRegion *iommu, hwaddr addr, bool is_write);
-    /* Returns minimum supported page size */
-    uint64_t (*get_min_page_size)(MemoryRegion *iommu);
-    /* Called when the first notifier is set */
-    void (*notify_started)(MemoryRegion *iommu);
-    /* Called when the last notifier is removed */
-    void (*notify_stopped)(MemoryRegion *iommu);
 };
 
 typedef struct CoalescedMemoryRange CoalescedMemoryRange;
@@ -195,6 +187,7 @@ struct MemoryRegion {
     MemoryRegion *alias;
     hwaddr alias_offset;
     int32_t priority;
+    bool may_overlap;
     QTAILQ_HEAD(subregions, MemoryRegion) subregions;
     QTAILQ_ENTRY(MemoryRegion) subregions_link;
     QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
@@ -445,31 +438,15 @@ void memory_region_init_alias(MemoryRegion *mr,
                               uint64_t size);
 
 /**
- * memory_region_init_rom: Initialize a ROM memory region.
- *
- * This has the same effect as calling memory_region_init_ram()
- * and then marking the resulting region read-only with
- * memory_region_set_readonly().
- *
- * @mr: the #MemoryRegion to be initialized.
- * @owner: the object that tracks the region's reference count
- * @name: the name of the region.
- * @size: size of the region.
- * @errp: pointer to Error*, to store an error if it happens.
- */
-void memory_region_init_rom(MemoryRegion *mr,
-                            struct Object *owner,
-                            const char *name,
-                            uint64_t size,
-                            Error **errp);
-
-/**
  * memory_region_init_rom_device:  Initialize a ROM memory region.  Writes are
  *                                 handled via callbacks.
  *
+ * If NULL callbacks pointer is given, then I/O space is not supposed to be
+ * handled by QEMU itself. Any access via the memory API will cause an abort().
+ *
  * @mr: the #MemoryRegion to be initialized.
  * @owner: the object that tracks the region's reference count
- * @ops: callbacks for write access handling (must not be NULL).
+ * @ops: callbacks for write access handling.
  * @name: the name of the region.
  * @size: size of the region.
  * @errp: pointer to Error*, to store an error if it happens.
@@ -595,16 +572,6 @@ static inline bool memory_region_is_iommu(MemoryRegion *mr)
 
 
 /**
- * memory_region_iommu_get_min_page_size: get minimum supported page size
- * for an iommu
- *
- * Returns minimum supported page size for an iommu.
- *
- * @mr: the memory region being queried
- */
-uint64_t memory_region_iommu_get_min_page_size(MemoryRegion *mr);
-
-/**
  * memory_region_notify_iommu: notify a change in an IOMMU translation entry.
  *
  * @mr: the memory region that was changed
@@ -628,25 +595,24 @@ void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n);
 
 /**
  * memory_region_iommu_replay: replay existing IOMMU translations to
- * a notifier with the minimum page granularity returned by
- * mr->iommu_ops->get_page_size().
+ * a notifier
  *
  * @mr: the memory region to observe
  * @n: the notifier to which to replay iommu mappings
+ * @granularity: Minimum page granularity to replay notifications for
  * @is_write: Whether to treat the replay as a translate "write"
  *     through the iommu
  */
-void memory_region_iommu_replay(MemoryRegion *mr, Notifier *n, bool is_write);
+void memory_region_iommu_replay(MemoryRegion *mr, Notifier *n,
+                                hwaddr granularity, bool is_write);
 
 /**
  * memory_region_unregister_iommu_notifier: unregister a notifier for
  * changes to IOMMU translation entries.
  *
- * @mr: the memory region which was observed and for which notity_stopped()
- *      needs to be called
  * @n: the notifier to be removed.
  */
-void memory_region_unregister_iommu_notifier(MemoryRegion *mr, Notifier *n);
+void memory_region_unregister_iommu_notifier(Notifier *n);
 
 /**
  * memory_region_name: get a memory region's name
@@ -702,35 +668,6 @@ static inline bool memory_region_is_rom(MemoryRegion *mr)
 int memory_region_get_fd(MemoryRegion *mr);
 
 /**
- * memory_region_set_fd: Mark a RAM memory region as backed by a
- * file descriptor.
- *
- * This function is typically used after memory_region_init_ram_ptr().
- *
- * @mr: the memory region being queried.
- * @fd: the file descriptor that backs @mr.
- */
-void memory_region_set_fd(MemoryRegion *mr, int fd);
-
-/**
- * memory_region_from_host: Convert a pointer into a RAM memory region
- * and an offset within it.
- *
- * Given a host pointer inside a RAM memory region (created with
- * memory_region_init_ram() or memory_region_init_ram_ptr()), return
- * the MemoryRegion and the offset within it.
- *
- * Use with care; by the time this function returns, the returned pointer is
- * not protected by RCU anymore.  If the caller is not within an RCU critical
- * section and does not hold the iothread lock, it must have other means of
- * protecting the pointer, such as a reference to the region that includes
- * the incoming ram_addr_t.
- *
- * @mr: the memory region being queried.
- */
-MemoryRegion *memory_region_from_host(void *ptr, ram_addr_t *offset);
-
-/**
  * memory_region_get_ram_ptr: Get a pointer into a RAM memory region.
  *
  * Returns a host pointer to a RAM memory region (created with
@@ -1355,6 +1292,23 @@ void address_space_stq_le(AddressSpace *as, hwaddr addr, uint64_t val,
 void address_space_stq_be(AddressSpace *as, hwaddr addr, uint64_t val,
                             MemTxAttrs attrs, MemTxResult *result);
 
+#ifdef NEED_CPU_H
+uint32_t address_space_lduw(AddressSpace *as, hwaddr addr,
+                            MemTxAttrs attrs, MemTxResult *result);
+uint32_t address_space_ldl(AddressSpace *as, hwaddr addr,
+                            MemTxAttrs attrs, MemTxResult *result);
+uint64_t address_space_ldq(AddressSpace *as, hwaddr addr,
+                            MemTxAttrs attrs, MemTxResult *result);
+void address_space_stl_notdirty(AddressSpace *as, hwaddr addr, uint32_t val,
+                            MemTxAttrs attrs, MemTxResult *result);
+void address_space_stw(AddressSpace *as, hwaddr addr, uint32_t val,
+                            MemTxAttrs attrs, MemTxResult *result);
+void address_space_stl(AddressSpace *as, hwaddr addr, uint32_t val,
+                            MemTxAttrs attrs, MemTxResult *result);
+void address_space_stq(AddressSpace *as, hwaddr addr, uint64_t val,
+                            MemTxAttrs attrs, MemTxResult *result);
+#endif
+
 /* address_space_translate: translate an address range into an address space
  * into a MemoryRegion and an address range into that section.  Should be
  * called from an RCU critical section, to avoid that the last reference
@@ -1426,7 +1380,7 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
                                        MemoryRegion *mr);
 MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
                                     MemTxAttrs attrs, uint8_t *buf, int len);
-void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
+void *qemu_get_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
 
 static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
 {
@@ -1464,7 +1418,8 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
             l = len;
             mr = address_space_translate(as, addr, &addr1, &l, false);
             if (len == l && memory_access_is_direct(mr, false)) {
-                ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+                addr1 += memory_region_get_ram_addr(mr);
+                ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
                 memcpy(buf, ptr, len);
             } else {
                 result = address_space_read_continue(as, addr, attrs, buf, len,
index 3ca7929..a4b1eca 100644 (file)
 
 #pragma GCC poison CPUArchState
 
+#pragma GCC poison lduw_phys
+#pragma GCC poison ldl_phys
+#pragma GCC poison ldq_phys
+#pragma GCC poison stl_phys_notdirty
+#pragma GCC poison stw_phys
+#pragma GCC poison stl_phys
+#pragma GCC poison stq_phys
+
 #pragma GCC poison CPU_INTERRUPT_HARD
 #pragma GCC poison CPU_INTERRUPT_EXITTB
 #pragma GCC poison CPU_INTERRUPT_HALT
index 2a9465d..5adf7a4 100644 (file)
@@ -105,9 +105,12 @@ RAMBlock *qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t max_size,
                                                     uint64_t length,
                                                     void *host),
                                     MemoryRegion *mr, Error **errp);
+int qemu_get_ram_fd(ram_addr_t addr);
+void qemu_set_ram_fd(ram_addr_t addr, int fd);
+void *qemu_get_ram_block_host_ptr(ram_addr_t addr);
 void qemu_ram_free(RAMBlock *block);
 
-int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
+int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp);
 
 #define DIRTY_CLIENTS_ALL     ((1 << DIRTY_MEMORY_NUM) - 1)
 #define DIRTY_CLIENTS_NOCODE  (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE))
index 7eefad8..3a58c3f 100644 (file)
@@ -6,9 +6,8 @@
  *
  * This code is licensed under the GPL
  */
-
 #ifndef SOFTMMU_SEMI_H
-#define SOFTMMU_SEMI_H
+#define SOFTMMU_SEMI_H 1
 
 static inline uint64_t softmmu_tget64(CPUArchState *env, target_ulong addr)
 {
diff --git a/include/exec/tb-context.h b/include/exec/tb-context.h
deleted file mode 100644 (file)
index dce95d9..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Internal structs that QEMU exports to TCG
- *
- *  Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef QEMU_TB_CONTEXT_H
-#define QEMU_TB_CONTEXT_H
-
-#include "qemu/thread.h"
-#include "qemu/qht.h"
-
-#define CODE_GEN_HTABLE_BITS     15
-#define CODE_GEN_HTABLE_SIZE     (1 << CODE_GEN_HTABLE_BITS)
-
-typedef struct TranslationBlock TranslationBlock;
-typedef struct TBContext TBContext;
-
-struct TBContext {
-
-    TranslationBlock *tbs;
-    struct qht htable;
-    int nb_tbs;
-    /* any access to the tbs or the page table must use this lock */
-    QemuMutex tb_lock;
-
-    /* statistics */
-    int tb_flush_count;
-    int tb_phys_invalidate_count;
-};
-
-#endif
diff --git a/include/exec/tb-hash-xx.h b/include/exec/tb-hash-xx.h
deleted file mode 100644 (file)
index 2c40b5c..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * xxHash - Fast Hash algorithm
- * Copyright (C) 2012-2016, Yann Collet
- *
- * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * + Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * + Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You can contact the author at :
- * - xxHash source repository : https://github.com/Cyan4973/xxHash
- */
-
-#ifndef EXEC_TB_HASH_XX_H
-#define EXEC_TB_HASH_XX_H
-
-#include "qemu/bitops.h"
-
-#define PRIME32_1   2654435761U
-#define PRIME32_2   2246822519U
-#define PRIME32_3   3266489917U
-#define PRIME32_4    668265263U
-#define PRIME32_5    374761393U
-
-#define TB_HASH_XX_SEED 1
-
-/*
- * xxhash32, customized for input variables that are not guaranteed to be
- * contiguous in memory.
- */
-static inline
-uint32_t tb_hash_func5(uint64_t a0, uint64_t b0, uint32_t e)
-{
-    uint32_t v1 = TB_HASH_XX_SEED + PRIME32_1 + PRIME32_2;
-    uint32_t v2 = TB_HASH_XX_SEED + PRIME32_2;
-    uint32_t v3 = TB_HASH_XX_SEED + 0;
-    uint32_t v4 = TB_HASH_XX_SEED - PRIME32_1;
-    uint32_t a = a0 >> 32;
-    uint32_t b = a0;
-    uint32_t c = b0 >> 32;
-    uint32_t d = b0;
-    uint32_t h32;
-
-    v1 += a * PRIME32_2;
-    v1 = rol32(v1, 13);
-    v1 *= PRIME32_1;
-
-    v2 += b * PRIME32_2;
-    v2 = rol32(v2, 13);
-    v2 *= PRIME32_1;
-
-    v3 += c * PRIME32_2;
-    v3 = rol32(v3, 13);
-    v3 *= PRIME32_1;
-
-    v4 += d * PRIME32_2;
-    v4 = rol32(v4, 13);
-    v4 *= PRIME32_1;
-
-    h32 = rol32(v1, 1) + rol32(v2, 7) + rol32(v3, 12) + rol32(v4, 18);
-    h32 += 20;
-
-    h32 += e * PRIME32_3;
-    h32  = rol32(h32, 17) * PRIME32_4;
-
-    h32 ^= h32 >> 15;
-    h32 *= PRIME32_2;
-    h32 ^= h32 >> 13;
-    h32 *= PRIME32_3;
-    h32 ^= h32 >> 16;
-
-    return h32;
-}
-
-#endif /* EXEC_TB_HASH_XX_H */
index 2c27490..0f4e8a0 100644 (file)
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef EXEC_TB_HASH_H
-#define EXEC_TB_HASH_H
-
-#include "exec/tb-hash-xx.h"
+#ifndef EXEC_TB_HASH
+#define EXEC_TB_HASH
 
 /* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for
    addresses on the same page.  The top bits are the same.  This allows
@@ -45,10 +43,9 @@ static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
            | (tmp & TB_JMP_ADDR_MASK));
 }
 
-static inline
-uint32_t tb_hash_func(tb_page_addr_t phys_pc, target_ulong pc, uint32_t flags)
+static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc)
 {
-    return tb_hash_func5(phys_pc, pc, flags);
+    return (pc >> 2) & (CODE_GEN_PHYS_HASH_SIZE - 1);
 }
 
 #endif
index ba18860..80eedac 100644 (file)
@@ -1,6 +1,5 @@
-#ifndef EXEC_USER_ABITYPES_H
-#define EXEC_USER_ABITYPES_H
-
+#ifndef QEMU_TYPES_H
+#define QEMU_TYPES_H
 #include "cpu.h"
 
 #ifdef TARGET_ABI32
 #define ABI_LLONG_ALIGNMENT 2
 #endif
 
-#if defined(TARGET_I386) && !defined(TARGET_X86_64)
-#define ABI_LLONG_ALIGNMENT 4
-#endif
-
 #ifndef ABI_SHORT_ALIGNMENT
 #define ABI_SHORT_ALIGNMENT 2
 #endif
index f19ef4b..ad1d602 100644 (file)
@@ -60,10 +60,10 @@ typedef struct {
 
 /* Translation table for bitmasks... */
 typedef struct bitmask_transtbl {
-    unsigned int target_mask;
-    unsigned int target_bits;
-    unsigned int host_mask;
-    unsigned int host_bits;
+       unsigned int    x86_mask;
+       unsigned int    x86_bits;
+       unsigned int    alpha_mask;
+       unsigned int    alpha_bits;
 } bitmask_transtbl;
 
 void thunk_register_struct(int id, const char *name, const argtype *types);
@@ -71,6 +71,7 @@ void thunk_register_struct_direct(int id, const char *name,
                                   const StructEntry *se1);
 const argtype *thunk_convert(void *dst, const void *src,
                              const argtype *type_ptr, int to_host);
+#ifndef NO_THUNK_TYPE_SIZE
 
 extern StructEntry *struct_entries;
 
@@ -177,9 +178,11 @@ static inline int thunk_type_align(const argtype *type_ptr, int is_host)
     }
 }
 
-unsigned int target_to_host_bitmask(unsigned int target_mask,
+#endif /* NO_THUNK_TYPE_SIZE */
+
+unsigned int target_to_host_bitmask(unsigned int x86_mask,
                                     const bitmask_transtbl * trans_tbl);
-unsigned int host_to_target_bitmask(unsigned int host_mask,
+unsigned int host_to_target_bitmask(unsigned int alpha_mask,
                                     const bitmask_transtbl * trans_tbl);
 
 void thunk_init(unsigned int max_structs);
index 1bde349..c937062 100644 (file)
@@ -198,14 +198,13 @@ enum {
 typedef struct float_status {
     signed char float_detect_tininess;
     signed char float_rounding_mode;
-    uint8_t     float_exception_flags;
+    signed char float_exception_flags;
     signed char floatx80_rounding_precision;
     /* should denormalised results go to zero and set the inexact flag? */
     flag flush_to_zero;
     /* should denormalised inputs go to zero and set the input_denormal flag? */
     flag flush_inputs_to_zero;
     flag default_nan_mode;
-    flag snan_bit_is_one;
 } float_status;
 
 static inline void set_float_detect_tininess(int val, float_status *status)
@@ -237,10 +236,6 @@ static inline void set_default_nan_mode(flag val, float_status *status)
 {
     status->default_nan_mode = val;
 }
-static inline void set_snan_bit_is_one(flag val, float_status *status)
-{
-    status->snan_bit_is_one = val;
-}
 static inline int get_float_detect_tininess(float_status *status)
 {
     return status->float_detect_tininess;
@@ -274,7 +269,7 @@ static inline flag get_default_nan_mode(float_status *status)
 | Routine to raise any or all of the software IEC/IEEE floating-point
 | exception flags.
 *----------------------------------------------------------------------------*/
-void float_raise(uint8_t flags, float_status *status);
+void float_raise(int8_t flags, float_status *status);
 
 /*----------------------------------------------------------------------------
 | If `a' is denormal and we are in flush-to-zero mode then set the
@@ -347,9 +342,9 @@ float64 float16_to_float64(float16 a, flag ieee, float_status *status);
 /*----------------------------------------------------------------------------
 | Software half-precision operations.
 *----------------------------------------------------------------------------*/
-int float16_is_quiet_nan(float16, float_status *status);
-int float16_is_signaling_nan(float16, float_status *status);
-float16 float16_maybe_silence_nan(float16, float_status *status);
+int float16_is_quiet_nan( float16 );
+int float16_is_signaling_nan( float16 );
+float16 float16_maybe_silence_nan( float16 );
 
 static inline int float16_is_any_nan(float16 a)
 {
@@ -359,7 +354,7 @@ static inline int float16_is_any_nan(float16 a)
 /*----------------------------------------------------------------------------
 | The pattern for a default generated half-precision NaN.
 *----------------------------------------------------------------------------*/
-float16 float16_default_nan(float_status *status);
+extern const float16 float16_default_nan;
 
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE single-precision conversion routines.
@@ -409,9 +404,9 @@ float32 float32_minnum(float32, float32, float_status *status);
 float32 float32_maxnum(float32, float32, float_status *status);
 float32 float32_minnummag(float32, float32, float_status *status);
 float32 float32_maxnummag(float32, float32, float_status *status);
-int float32_is_quiet_nan(float32, float_status *status);
-int float32_is_signaling_nan(float32, float_status *status);
-float32 float32_maybe_silence_nan(float32, float_status *status);
+int float32_is_quiet_nan( float32 );
+int float32_is_signaling_nan( float32 );
+float32 float32_maybe_silence_nan( float32 );
 float32 float32_scalbn(float32, int, float_status *status);
 
 static inline float32 float32_abs(float32 a)
@@ -471,7 +466,7 @@ static inline float32 float32_set_sign(float32 a, int sign)
 /*----------------------------------------------------------------------------
 | The pattern for a default generated single-precision NaN.
 *----------------------------------------------------------------------------*/
-float32 float32_default_nan(float_status *status);
+extern const float32 float32_default_nan;
 
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE double-precision conversion routines.
@@ -521,9 +516,9 @@ float64 float64_minnum(float64, float64, float_status *status);
 float64 float64_maxnum(float64, float64, float_status *status);
 float64 float64_minnummag(float64, float64, float_status *status);
 float64 float64_maxnummag(float64, float64, float_status *status);
-int float64_is_quiet_nan(float64 a, float_status *status);
-int float64_is_signaling_nan(float64, float_status *status);
-float64 float64_maybe_silence_nan(float64, float_status *status);
+int float64_is_quiet_nan( float64 a );
+int float64_is_signaling_nan( float64 );
+float64 float64_maybe_silence_nan( float64 );
 float64 float64_scalbn(float64, int, float_status *status);
 
 static inline float64 float64_abs(float64 a)
@@ -583,7 +578,7 @@ static inline float64 float64_set_sign(float64 a, int sign)
 /*----------------------------------------------------------------------------
 | The pattern for a default generated double-precision NaN.
 *----------------------------------------------------------------------------*/
-float64 float64_default_nan(float_status *status);
+extern const float64 float64_default_nan;
 
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE extended double-precision conversion routines.
@@ -616,9 +611,9 @@ int floatx80_lt_quiet(floatx80, floatx80, float_status *status);
 int floatx80_unordered_quiet(floatx80, floatx80, float_status *status);
 int floatx80_compare(floatx80, floatx80, float_status *status);
 int floatx80_compare_quiet(floatx80, floatx80, float_status *status);
-int floatx80_is_quiet_nan(floatx80, float_status *status);
-int floatx80_is_signaling_nan(floatx80, float_status *status);
-floatx80 floatx80_maybe_silence_nan(floatx80, float_status *status);
+int floatx80_is_quiet_nan( floatx80 );
+int floatx80_is_signaling_nan( floatx80 );
+floatx80 floatx80_maybe_silence_nan( floatx80 );
 floatx80 floatx80_scalbn(floatx80, int, float_status *status);
 
 static inline floatx80 floatx80_abs(floatx80 a)
@@ -668,7 +663,7 @@ static inline int floatx80_is_any_nan(floatx80 a)
 /*----------------------------------------------------------------------------
 | The pattern for a default generated extended double-precision NaN.
 *----------------------------------------------------------------------------*/
-floatx80 floatx80_default_nan(float_status *status);
+extern const floatx80 floatx80_default_nan;
 
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE quadruple-precision conversion routines.
@@ -701,9 +696,9 @@ int float128_lt_quiet(float128, float128, float_status *status);
 int float128_unordered_quiet(float128, float128, float_status *status);
 int float128_compare(float128, float128, float_status *status);
 int float128_compare_quiet(float128, float128, float_status *status);
-int float128_is_quiet_nan(float128, float_status *status);
-int float128_is_signaling_nan(float128, float_status *status);
-float128 float128_maybe_silence_nan(float128, float_status *status);
+int float128_is_quiet_nan( float128 );
+int float128_is_signaling_nan( float128 );
+float128 float128_maybe_silence_nan( float128 );
 float128 float128_scalbn(float128, int, float_status *status);
 
 static inline float128 float128_abs(float128 a)
@@ -749,6 +744,6 @@ static inline int float128_is_any_nan(float128 a)
 /*----------------------------------------------------------------------------
 | The pattern for a default generated quadruple-precision NaN.
 *----------------------------------------------------------------------------*/
-float128 float128_default_nan(float_status *status);
+extern const float128 float128_default_nan;
 
-#endif /* SOFTFLOAT_H */
+#endif /* !SOFTFLOAT_H */
index 8d5a7f3..03d8b12 100644 (file)
@@ -48,26 +48,6 @@ static inline gint64 qemu_g_get_monotonic_time(void)
 gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout);
 #endif
 
-#if !GLIB_CHECK_VERSION(2, 30, 0)
-/* Not a 100% compatible implementation, but good enough for most
- * cases. Placeholders are only supported at the end of the
- * template. */
-static inline gchar *qemu_g_dir_make_tmp(gchar const *tmpl, GError **error)
-{
-    gchar *path = g_build_filename(g_get_tmp_dir(), tmpl ?: ".XXXXXX", NULL);
-
-    if (mkdtemp(path) != NULL) {
-        return path;
-    }
-    /* Error occurred, clean up. */
-    g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno),
-                "mkdtemp() failed");
-    g_free(path);
-    return NULL;
-}
-#define g_dir_make_tmp(tmpl, error) qemu_g_dir_make_tmp(tmpl, error)
-#endif /* glib 2.30 */
-
 #if !GLIB_CHECK_VERSION(2, 31, 0)
 /* before glib-2.31, GMutex and GCond was dynamic-only (there was a separate
  * GStaticMutex, but it didn't work with condition variables).
@@ -169,32 +149,6 @@ static inline void (g_cond_signal)(CompatGCond *cond)
 }
 #undef g_cond_signal
 
-static inline gboolean (g_cond_timed_wait)(CompatGCond *cond,
-                                           CompatGMutex *mutex,
-                                           GTimeVal *time)
-{
-    g_assert(mutex->once.status != G_ONCE_STATUS_PROGRESS);
-    g_once(&cond->once, do_g_cond_new, NULL);
-    return g_cond_timed_wait((GCond *) cond->once.retval,
-                             (GMutex *) mutex->once.retval, time);
-}
-#undef g_cond_timed_wait
-
-/* This is not a macro, because it didn't exist until 2.32.  */
-static inline gboolean g_cond_wait_until(CompatGCond *cond, CompatGMutex *mutex,
-                                         gint64 end_time)
-{
-    GTimeVal time;
-
-    /* Convert from monotonic to CLOCK_REALTIME.  */
-    end_time -= g_get_monotonic_time();
-    g_get_current_time(&time);
-    end_time += time.tv_sec * G_TIME_SPAN_SECOND + time.tv_usec;
-
-    time.tv_sec = end_time / G_TIME_SPAN_SECOND;
-    time.tv_usec = end_time % G_TIME_SPAN_SECOND;
-    return g_cond_timed_wait(cond, mutex, &time);
-}
 
 /* before 2.31 there was no g_thread_new() */
 static inline GThread *g_thread_new(const char *name,
index 41c1d95..c7a03d4 100644 (file)
@@ -367,9 +367,7 @@ struct AcpiMadtGenericDistributor {
     uint32_t gic_id;
     uint64_t base_address;
     uint32_t global_irq_base;
-    /* ACPI 5.1 Errata 1228 Present GIC version in MADT table */
-    uint8_t version;
-    uint8_t reserved2[3];
+    uint32_t reserved2;
 } QEMU_PACKED;
 
 typedef struct AcpiMadtGenericDistributor AcpiMadtGenericDistributor;
@@ -457,10 +455,8 @@ struct AcpiSystemResourceAffinityTable
 } QEMU_PACKED;
 typedef struct AcpiSystemResourceAffinityTable AcpiSystemResourceAffinityTable;
 
-#define ACPI_SRAT_PROCESSOR_APIC     0
+#define ACPI_SRAT_PROCESSOR          0
 #define ACPI_SRAT_MEMORY             1
-#define ACPI_SRAT_PROCESSOR_x2APIC   2
-#define ACPI_SRAT_PROCESSOR_GICC     3
 
 struct AcpiSratProcessorAffinity
 {
@@ -477,7 +473,7 @@ typedef struct AcpiSratProcessorAffinity AcpiSratProcessorAffinity;
 struct AcpiSratMemoryAffinity
 {
     ACPI_SUB_HEADER_DEF
-    uint32_t    proximity;
+    uint8_t     proximity[4];
     uint16_t    reserved1;
     uint64_t    base_addr;
     uint64_t    range_length;
@@ -487,17 +483,6 @@ struct AcpiSratMemoryAffinity
 } QEMU_PACKED;
 typedef struct AcpiSratMemoryAffinity AcpiSratMemoryAffinity;
 
-struct AcpiSratProcessorGiccAffinity
-{
-    ACPI_SUB_HEADER_DEF
-    uint32_t    proximity;
-    uint32_t    acpi_processor_uid;
-    uint32_t    flags;
-    uint32_t    clock_domain;
-} QEMU_PACKED;
-
-typedef struct AcpiSratProcessorGiccAffinity AcpiSratProcessorGiccAffinity;
-
 /* PCI fw r3.0 MCFG table. */
 /* Subtable */
 struct AcpiMcfgAllocation {
@@ -571,18 +556,6 @@ enum {
 /*
  * Sub-structures for DMAR
  */
-
-/* Device scope structure for DRHD. */
-struct AcpiDmarDeviceScope {
-    uint8_t entry_type;
-    uint8_t length;
-    uint16_t reserved;
-    uint8_t enumeration_id;
-    uint8_t bus;
-    uint16_t path[0];           /* list of dev:func pairs */
-} QEMU_PACKED;
-typedef struct AcpiDmarDeviceScope AcpiDmarDeviceScope;
-
 /* Type 0: Hardware Unit Definition */
 struct AcpiDmarHardwareUnit {
     uint16_t type;
@@ -591,7 +564,6 @@ struct AcpiDmarHardwareUnit {
     uint8_t reserved;
     uint16_t pci_segment;   /* The PCI Segment associated with this unit */
     uint64_t address;   /* Base address of remapping hardware register-set */
-    AcpiDmarDeviceScope scope[0];
 } QEMU_PACKED;
 typedef struct AcpiDmarHardwareUnit AcpiDmarHardwareUnit;
 
index 7b3d93c..e0978c8 100644 (file)
@@ -1,6 +1,5 @@
 #ifndef QEMU_HW_ACPI_H
 #define QEMU_HW_ACPI_H
-
 /*
  *  Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
  *                     VA Linux Systems Japan K.K.
@@ -24,7 +23,6 @@
 #include "qemu/option.h"
 #include "exec/memory.h"
 #include "hw/irq.h"
-#include "hw/acpi/acpi_dev_interface.h"
 
 /*
  * current device naming scheme supports up to 256 memory devices
 /* PM2_CNT */
 #define ACPI_BITMASK_ARB_DISABLE                0x0001
 
+/* These values are part of guest ABI, and can not be changed */
+typedef enum {
+    ACPI_PCI_HOTPLUG_STATUS = 2,
+    ACPI_CPU_HOTPLUG_STATUS = 4,
+    ACPI_MEMORY_HOTPLUG_STATUS = 8,
+} AcpiGPEStatusBits;
+
 /* structs */
 typedef struct ACPIPMTimer ACPIPMTimer;
 typedef struct ACPIPM1EVT ACPIPM1EVT;
@@ -145,6 +150,13 @@ void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
                       MemoryRegion *parent);
 void acpi_pm_tmr_reset(ACPIREGS *ar);
 
+#include "qemu/timer.h"
+static inline int64_t acpi_pm_tmr_get_clock(void)
+{
+    return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY,
+                    NANOSECONDS_PER_SECOND);
+}
+
 /* PM1a_EVT: piix and ich9 don't implement PM1b. */
 uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar);
 void acpi_pm1_evt_power_down(ACPIREGS *ar);
@@ -167,7 +179,7 @@ void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val);
 uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr);
 
 void acpi_send_gpe_event(ACPIREGS *ar, qemu_irq irq,
-                         AcpiEventStatusBits status);
+                         AcpiGPEStatusBits status);
 
 void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq);
 
@@ -189,4 +201,4 @@ struct AcpiSlicOem {
 };
 int acpi_get_slic_oem(AcpiSlicOem *oem);
 
-#endif /* QEMU_HW_ACPI_H */
+#endif /* !QEMU_HW_ACPI_H */
index da4ef7f..f245f8d 100644 (file)
@@ -3,14 +3,6 @@
 
 #include "qom/object.h"
 #include "qapi-types.h"
-#include "hw/boards.h"
-
-/* These values are part of guest ABI, and can not be changed */
-typedef enum {
-    ACPI_PCI_HOTPLUG_STATUS = 2,
-    ACPI_CPU_HOTPLUG_STATUS = 4,
-    ACPI_MEMORY_HOTPLUG_STATUS = 8,
-} AcpiEventStatusBits;
 
 #define TYPE_ACPI_DEVICE_IF "acpi-device-interface"
 
@@ -30,18 +22,11 @@ typedef struct AcpiDeviceIf {
     Object Parent;
 } AcpiDeviceIf;
 
-void acpi_send_event(DeviceState *dev, AcpiEventStatusBits event);
-
 /**
  * AcpiDeviceIfClass:
  *
  * ospm_status: returns status of ACPI device objects, reported
  *              via _OST method if device supports it.
- * send_event: inject a specified event into guest
- * madt_cpu: fills @entry with Interrupt Controller Structure
- *           for CPU indexed by @uid in @apic_ids array,
- *           returned structure types are:
- *           0 - Local APIC, 9 - Local x2APIC, 0xB - GICC
  *
  * Interface is designed for providing unified interface
  * to generic ACPI functionality that could be used without
@@ -54,8 +39,5 @@ typedef struct AcpiDeviceIfClass {
 
     /* <public> */
     void (*ospm_status)(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
-    void (*send_event)(AcpiDeviceIf *adev, AcpiEventStatusBits ev);
-    void (*madt_cpu)(AcpiDeviceIf *adev, int uid,
-                     CPUArchIdList *apic_ids, GArray *entry);
 } AcpiDeviceIfClass;
 #endif
index e5f0878..2c994b3 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef HW_ACPI_AML_BUILD_H
-#define HW_ACPI_AML_BUILD_H
+#ifndef HW_ACPI_GEN_UTILS_H
+#define HW_ACPI_GEN_UTILS_H
 
+#include <glib.h>
 #include "hw/acpi/acpi-defs.h"
-#include "hw/acpi/bios-linker-loader.h"
 
 /* Reserve RAM space for tables: add another order of magnitude. */
 #define ACPI_BUILD_TABLE_MAX_SIZE         0x200000
@@ -198,19 +198,12 @@ typedef enum {
     AML_PULL_NONE = 3,
 } AmlPinConfig;
 
-typedef enum {
-    MEM_AFFINITY_NOFLAGS      = 0,
-    MEM_AFFINITY_ENABLED      = (1 << 0),
-    MEM_AFFINITY_HOTPLUGGABLE = (1 << 1),
-    MEM_AFFINITY_NON_VOLATILE = (1 << 2),
-} MemoryAffinityFlags;
-
 typedef
 struct AcpiBuildTables {
     GArray *table_data;
     GArray *rsdp;
     GArray *tcpalog;
-    BIOSLinker *linker;
+    GArray *linker;
 } AcpiBuildTables;
 
 /**
@@ -252,7 +245,6 @@ void aml_append(Aml *parent_ctx, Aml *child);
 /* non block AML object primitives */
 Aml *aml_name(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
 Aml *aml_name_decl(const char *name, Aml *val);
-Aml *aml_debug(void);
 Aml *aml_return(Aml *val);
 Aml *aml_int(const uint64_t val);
 Aml *aml_arg(int pos);
@@ -277,8 +269,6 @@ Aml *aml_call1(const char *method, Aml *arg1);
 Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2);
 Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3);
 Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4);
-Aml *aml_call5(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4,
-               Aml *arg5);
 Aml *aml_gpio_int(AmlConsumerAndProducer con_and_pro,
                   AmlLevelAndEdge edge_level,
                   AmlActiveHighAndLow active_level, AmlShared shared,
@@ -361,14 +351,12 @@ Aml *aml_create_qword_field(Aml *srcbuf, Aml *index, const char *name);
 Aml *aml_varpackage(uint32_t num_elements);
 Aml *aml_touuid(const char *uuid);
 Aml *aml_unicode(const char *str);
-Aml *aml_refof(Aml *arg);
 Aml *aml_derefof(Aml *arg);
 Aml *aml_sizeof(Aml *arg);
 Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target);
-Aml *aml_object_type(Aml *object);
 
 void
-build_header(BIOSLinker *linker, GArray *table_data,
+build_header(GArray *linker, GArray *table_data,
              AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
              const char *oem_id, const char *oem_table_id);
 void *acpi_data_push(GArray *table_data, unsigned size);
@@ -377,14 +365,11 @@ void acpi_add_table(GArray *table_offsets, GArray *table_data);
 void acpi_build_tables_init(AcpiBuildTables *tables);
 void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre);
 void
-build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
+build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets,
            const char *oem_id, const char *oem_table_id);
 
 int
 build_append_named_dword(GArray *array, const char *name_format, ...)
 GCC_FMT_ATTR(2, 3);
 
-void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
-                       uint64_t len, int node, MemoryAffinityFlags flags);
-
 #endif
index fa1e5d1..82f1af6 100644 (file)
@@ -1,30 +1,25 @@
 #ifndef BIOS_LINKER_LOADER_H
 #define BIOS_LINKER_LOADER_H
 
+#include <glib.h>
 
-typedef struct BIOSLinker {
-    GArray *cmd_blob;
-    GArray *file_list;
-} BIOSLinker;
+GArray *bios_linker_loader_init(void);
 
-BIOSLinker *bios_linker_loader_init(void);
-
-void bios_linker_loader_alloc(BIOSLinker *linker,
-                              const char *file_name,
-                              GArray *file_blob,
+void bios_linker_loader_alloc(GArray *linker,
+                              const char *file,
                               uint32_t alloc_align,
                               bool alloc_fseg);
 
-void bios_linker_loader_add_checksum(BIOSLinker *linker, const char *file,
-                                     unsigned start_offset, unsigned size,
-                                     unsigned checksum_offset);
+void bios_linker_loader_add_checksum(GArray *linker, const char *file,
+                                     GArray *table,
+                                     void *start, unsigned size,
+                                     uint8_t *checksum);
 
-void bios_linker_loader_add_pointer(BIOSLinker *linker,
+void bios_linker_loader_add_pointer(GArray *linker,
                                     const char *dest_file,
-                                    uint32_t dst_patched_offset,
-                                    uint8_t dst_patched_size,
                                     const char *src_file,
-                                    uint32_t src_offset);
+                                    GArray *table, void *pointer,
+                                    uint8_t pointer_size);
 
-void bios_linker_loader_cleanup(BIOSLinker *linker);
+void *bios_linker_loader_cleanup(GArray *linker);
 #endif
diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
deleted file mode 100644 (file)
index 89ce172..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * QEMU ACPI hotplug utilities
- *
- * Copyright (C) 2016 Red Hat Inc
- *
- * Authors:
- *   Igor Mammedov <imammedo@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#ifndef ACPI_CPU_H
-#define ACPI_CPU_H
-
-#include "hw/qdev-core.h"
-#include "hw/acpi/acpi.h"
-#include "hw/acpi/aml-build.h"
-#include "hw/hotplug.h"
-
-typedef struct AcpiCpuStatus {
-    struct CPUState *cpu;
-    uint64_t arch_id;
-    bool is_inserting;
-    bool is_removing;
-    uint32_t ost_event;
-    uint32_t ost_status;
-} AcpiCpuStatus;
-
-typedef struct CPUHotplugState {
-    MemoryRegion ctrl_reg;
-    uint32_t selector;
-    uint8_t command;
-    uint32_t dev_count;
-    AcpiCpuStatus *devs;
-} CPUHotplugState;
-
-void acpi_cpu_plug_cb(HotplugHandler *hotplug_dev,
-                      CPUHotplugState *cpu_st, DeviceState *dev, Error **errp);
-
-void acpi_cpu_unplug_request_cb(HotplugHandler *hotplug_dev,
-                                CPUHotplugState *cpu_st,
-                                DeviceState *dev, Error **errp);
-
-void acpi_cpu_unplug_cb(CPUHotplugState *cpu_st,
-                        DeviceState *dev, Error **errp);
-
-void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
-                         CPUHotplugState *state, hwaddr base_addr);
-
-typedef struct CPUHotplugFeatures {
-    bool apci_1_compatible;
-    bool has_legacy_cphp;
-} CPUHotplugFeatures;
-
-void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-                    hwaddr io_base,
-                    const char *res_root,
-                    const char *event_handler_method);
-
-void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list);
-
-extern const VMStateDescription vmstate_cpu_hotplug;
-#define VMSTATE_CPU_HOTPLUG(cpuhp, state) \
-    VMSTATE_STRUCT(cpuhp, state, 1, \
-                   vmstate_cpu_hotplug, CPUHotplugState)
-
-#endif
index 3b932ab..f22640e 100644 (file)
@@ -9,32 +9,30 @@
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
-
-#ifndef HW_ACPI_CPU_HOTPLUG_H
-#define HW_ACPI_CPU_HOTPLUG_H
+#ifndef ACPI_HOTPLUG_H
+#define ACPI_HOTPLUG_H
 
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/pc-hotplug.h"
 #include "hw/acpi/aml-build.h"
-#include "hw/hotplug.h"
-#include "hw/acpi/cpu.h"
 
 typedef struct AcpiCpuHotplug {
-    Object *device;
     MemoryRegion io;
     uint8_t sts[ACPI_GPE_PROC_LEN];
 } AcpiCpuHotplug;
 
-void legacy_acpi_cpu_plug_cb(HotplugHandler *hotplug_dev,
-                             AcpiCpuHotplug *g, DeviceState *dev, Error **errp);
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+                      AcpiCpuHotplug *g, DeviceState *dev, Error **errp);
 
-void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
-                                  AcpiCpuHotplug *gpe_cpu, uint16_t base);
+void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+                           AcpiCpuHotplug *gpe_cpu, uint16_t base);
 
-void acpi_switch_to_modern_cphp(AcpiCpuHotplug *gpe_cpu,
-                                CPUHotplugState *cpuhp_state,
-                                uint16_t io_port);
+#define CPU_EJECT_METHOD "CPEJ"
+#define CPU_MAT_METHOD "CPMA"
+#define CPU_ON_BITMAP "CPON"
+#define CPU_STATUS_METHOD "CPST"
+#define CPU_STATUS_MAP "PRS"
+#define CPU_SCAN_METHOD "PRSC"
 
-void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState *machine,
-                                  uint16_t io_base);
+void build_cpu_hotplug_aml(Aml *ctx);
 #endif
index a352c94..63fa198 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/cpu_hotplug.h"
-#include "hw/acpi/cpu.h"
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/acpi/tco.h"
@@ -49,9 +48,7 @@ typedef struct ICH9LPCPMRegs {
     uint32_t pm_io_base;
     Notifier powerdown_notifier;
 
-    bool cpu_hotplug_legacy;
     AcpiCpuHotplug gpe_cpu;
-    CPUHotplugState cpuhp_state;
 
     MemHotplugState acpi_memory_hotplug;
 
@@ -72,11 +69,10 @@ extern const VMStateDescription vmstate_ich9_pm;
 
 void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp);
 
-void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
-                            Error **errp);
-void ich9_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev,
-                                      DeviceState *dev, Error **errp);
-void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp);
+void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev,
+                                      Error **errp);
+void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev,
                               Error **errp);
 
 void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
diff --git a/include/hw/acpi/ipmi.h b/include/hw/acpi/ipmi.h
deleted file mode 100644 (file)
index ab2bb29..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * QEMU IPMI ACPI handling
- *
- * Copyright (c) 2015,2016 Corey Minyard <cminyard@mvista.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#ifndef HW_ACPI_IPMI_H
-#define HW_ACPI_IPMI_H
-
-#include "qemu/osdep.h"
-#include "hw/acpi/aml-build.h"
-
-/*
- * Add ACPI IPMI entries for all registered IPMI devices whose parent
- * bus matches the given bus.  The resource is the ACPI resource that
- * contains the IPMI device, this is required for the I2C CRS.
- */
-void build_acpi_ipmi_devices(Aml *table, BusState *bus);
-
-#endif /* HW_ACPI_IPMI_H */
index d2c7452..3a646b1 100644 (file)
@@ -32,9 +32,9 @@ typedef struct MemHotplugState {
 void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
                               MemHotplugState *state);
 
-void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st,
+void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
                          DeviceState *dev, Error **errp);
-void acpi_memory_unplug_request_cb(HotplugHandler *hotplug_dev,
+void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq,
                                    MemHotplugState *mem_st,
                                    DeviceState *dev, Error **errp);
 void acpi_memory_unplug_cb(MemHotplugState *mem_st,
index 04528b7..79a4392 100644 (file)
@@ -29,7 +29,6 @@
 
 #include "hw/acpi/acpi.h"
 #include "migration/vmstate.h"
-#include "hw/hotplug.h"
 
 #define ACPI_PCIHP_IO_BASE_PROP "acpi-pcihp-io-base"
 #define ACPI_PCIHP_IO_LEN_PROP "acpi-pcihp-io-len"
@@ -57,9 +56,9 @@ typedef struct AcpiPciHpState {
 void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
                      MemoryRegion *address_space_io, bool bridges_enabled);
 
-void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
+void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s,
                                DeviceState *dev, Error **errp);
-void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
+void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s,
                                  DeviceState *dev, Error **errp);
 
 /* Called on reset */
index aeeebfe..b2517f9 100644 (file)
@@ -8,13 +8,13 @@
  *
  */
 
-#ifndef HW_ARM_H
-#define HW_ARM_H
+#ifndef ARM_MISC_H
+#define ARM_MISC_H 1
 
 #include "exec/memory.h"
-#include "target-arm/cpu-qom.h"
 #include "hw/irq.h"
 #include "qemu/notify.h"
+#include "cpu.h"
 
 typedef enum {
     ARM_ENDIANNESS_UNKNOWN = 0,
@@ -140,4 +140,4 @@ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
    ticks.  */
 extern int system_clock_scale;
 
-#endif /* HW_ARM_H */
+#endif /* !ARM_MISC_H */
index 7833bc7..f16a1ed 100644 (file)
 
 #include "hw/arm/arm.h"
 #include "hw/intc/aspeed_vic.h"
-#include "hw/misc/aspeed_scu.h"
 #include "hw/timer/aspeed_timer.h"
-#include "hw/i2c/aspeed_i2c.h"
-#include "hw/ssi/aspeed_smc.h"
 
 typedef struct AST2400State {
     /*< private >*/
@@ -28,10 +25,6 @@ typedef struct AST2400State {
     MemoryRegion iomem;
     AspeedVICState vic;
     AspeedTimerCtrlState timerctrl;
-    AspeedI2CState i2c;
-    AspeedSCUState scu;
-    AspeedSMCState smc;
-    AspeedSMCState spi;
 } AST2400State;
 
 #define TYPE_AST2400 "ast2400"
index 63785ba..a739d6a 100644 (file)
@@ -19,6 +19,7 @@
 #define HW_ARM_DIGIC_H
 
 #include "cpu.h"
+
 #include "hw/timer/digic-timer.h"
 #include "hw/char/digic-uart.h"
 
index 29fef8b..5c1820f 100644 (file)
  *
  */
 
-#ifndef EXYNOS4210_H
-#define EXYNOS4210_H
+
+#ifndef EXYNOS4210_H_
+#define EXYNOS4210_H_
 
 #include "qemu-common.h"
 #include "exec/memory.h"
-#include "target-arm/cpu-qom.h"
 
 #define EXYNOS4210_NCPUS                    2
 
@@ -134,4 +134,4 @@ DeviceState *exynos4210_uart_create(hwaddr addr,
                                     CharDriverState *chr,
                                     qemu_irq irq);
 
-#endif /* EXYNOS4210_H */
+#endif /* EXYNOS4210_H_ */
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
deleted file mode 100644 (file)
index ec6c509..0000000
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Freescale i.MX31 SoC emulation
- *
- * Copyright (C) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#ifndef FSL_IMX6_H
-#define FSL_IMX6_H
-
-#include "hw/arm/arm.h"
-#include "hw/cpu/a9mpcore.h"
-#include "hw/misc/imx6_ccm.h"
-#include "hw/misc/imx6_src.h"
-#include "hw/char/imx_serial.h"
-#include "hw/timer/imx_gpt.h"
-#include "hw/timer/imx_epit.h"
-#include "hw/i2c/imx_i2c.h"
-#include "hw/gpio/imx_gpio.h"
-#include "hw/sd/sdhci.h"
-#include "hw/ssi/imx_spi.h"
-#include "hw/net/imx_fec.h"
-#include "exec/memory.h"
-#include "cpu.h"
-
-#define TYPE_FSL_IMX6 "fsl,imx6"
-#define FSL_IMX6(obj) OBJECT_CHECK(FslIMX6State, (obj), TYPE_FSL_IMX6)
-
-#define FSL_IMX6_NUM_CPUS 4
-#define FSL_IMX6_NUM_UARTS 5
-#define FSL_IMX6_NUM_EPITS 2
-#define FSL_IMX6_NUM_I2CS 3
-#define FSL_IMX6_NUM_GPIOS 7
-#define FSL_IMX6_NUM_ESDHCS 4
-#define FSL_IMX6_NUM_ECSPIS 5
-
-typedef struct FslIMX6State {
-    /*< private >*/
-    DeviceState parent_obj;
-
-    /*< public >*/
-    ARMCPU         cpu[FSL_IMX6_NUM_CPUS];
-    A9MPPrivState  a9mpcore;
-    IMX6CCMState   ccm;
-    IMX6SRCState   src;
-    IMXSerialState uart[FSL_IMX6_NUM_UARTS];
-    IMXGPTState    gpt;
-    IMXEPITState   epit[FSL_IMX6_NUM_EPITS];
-    IMXI2CState    i2c[FSL_IMX6_NUM_I2CS];
-    IMXGPIOState   gpio[FSL_IMX6_NUM_GPIOS];
-    SDHCIState     esdhc[FSL_IMX6_NUM_ESDHCS];
-    IMXSPIState    spi[FSL_IMX6_NUM_ECSPIS];
-    IMXFECState    eth;
-    MemoryRegion   rom;
-    MemoryRegion   caam;
-    MemoryRegion   ocram;
-    MemoryRegion   ocram_alias;
-} FslIMX6State;
-
-
-#define FSL_IMX6_MMDC_ADDR 0x10000000
-#define FSL_IMX6_MMDC_SIZE 0xF0000000
-#define FSL_IMX6_EIM_MEM_ADDR 0x08000000
-#define FSL_IMX6_EIM_MEM_SIZE 0x8000000
-#define FSL_IMX6_IPU_2_ADDR 0x02800000
-#define FSL_IMX6_IPU_2_SIZE 0x400000
-#define FSL_IMX6_IPU_1_ADDR 0x02400000
-#define FSL_IMX6_IPU_1_SIZE 0x400000
-#define FSL_IMX6_MIPI_HSI_ADDR 0x02208000
-#define FSL_IMX6_MIPI_HSI_SIZE 0x4000
-#define FSL_IMX6_OPENVG_ADDR 0x02204000
-#define FSL_IMX6_OPENVG_SIZE 0x4000
-#define FSL_IMX6_SATA_ADDR 0x02200000
-#define FSL_IMX6_SATA_SIZE 0x4000
-#define FSL_IMX6_AIPS_2_ADDR 0x02100000
-#define FSL_IMX6_AIPS_2_SIZE 0x100000
-/* AIPS2 */
-#define FSL_IMX6_UART5_ADDR 0x021F4000
-#define FSL_IMX6_UART5_SIZE 0x4000
-#define FSL_IMX6_UART4_ADDR 0x021F0000
-#define FSL_IMX6_UART4_SIZE 0x4000
-#define FSL_IMX6_UART3_ADDR 0x021EC000
-#define FSL_IMX6_UART3_SIZE 0x4000
-#define FSL_IMX6_UART2_ADDR 0x021E8000
-#define FSL_IMX6_UART2_SIZE 0x4000
-#define FSL_IMX6_VDOA_ADDR 0x021E4000
-#define FSL_IMX6_VDOA_SIZE 0x4000
-#define FSL_IMX6_MIPI_DSI_ADDR 0x021E0000
-#define FSL_IMX6_MIPI_DSI_SIZE 0x4000
-#define FSL_IMX6_MIPI_CSI_ADDR 0x021DC000
-#define FSL_IMX6_MIPI_CSI_SIZE 0x4000
-#define FSL_IMX6_AUDMUX_ADDR 0x021D8000
-#define FSL_IMX6_AUDMUX_SIZE 0x4000
-#define FSL_IMX6_TZASC2_ADDR 0x021D4000
-#define FSL_IMX6_TZASC2_SIZE 0x4000
-#define FSL_IMX6_TZASC1_ADDR 0x021D0000
-#define FSL_IMX6_TZASC1_SIZE 0x4000
-#define FSL_IMX6_CSU_ADDR 0x021C0000
-#define FSL_IMX6_CSU_SIZE 0x4000
-#define FSL_IMX6_OCOTPCTRL_ADDR 0x021BC000
-#define FSL_IMX6_OCOTPCTRL_SIZE 0x4000
-#define FSL_IMX6_EIM_ADDR 0x021B8000
-#define FSL_IMX6_EIM_SIZE 0x4000
-#define FSL_IMX6_MMDC1_ADDR 0x021B4000
-#define FSL_IMX6_MMDC1_SIZE 0x4000
-#define FSL_IMX6_MMDC0_ADDR 0x021B0000
-#define FSL_IMX6_MMDC0_SIZE 0x4000
-#define FSL_IMX6_ROMCP_ADDR 0x021AC000
-#define FSL_IMX6_ROMCP_SIZE 0x4000
-#define FSL_IMX6_I2C3_ADDR 0x021A8000
-#define FSL_IMX6_I2C3_SIZE 0x4000
-#define FSL_IMX6_I2C2_ADDR 0x021A4000
-#define FSL_IMX6_I2C2_SIZE 0x4000
-#define FSL_IMX6_I2C1_ADDR 0x021A0000
-#define FSL_IMX6_I2C1_SIZE 0x4000
-#define FSL_IMX6_uSDHC4_ADDR 0x0219C000
-#define FSL_IMX6_uSDHC4_SIZE 0x4000
-#define FSL_IMX6_uSDHC3_ADDR 0x02198000
-#define FSL_IMX6_uSDHC3_SIZE 0x4000
-#define FSL_IMX6_uSDHC2_ADDR 0x02194000
-#define FSL_IMX6_uSDHC2_SIZE 0x4000
-#define FSL_IMX6_uSDHC1_ADDR 0x02190000
-#define FSL_IMX6_uSDHC1_SIZE 0x4000
-#define FSL_IMX6_MLB150_ADDR 0x0218C000
-#define FSL_IMX6_MLB150_SIZE 0x4000
-#define FSL_IMX6_ENET_ADDR 0x02188000
-#define FSL_IMX6_ENET_SIZE 0x4000
-#define FSL_IMX6_USBOH3_USB_ADDR 0x02184000
-#define FSL_IMX6_USBOH3_USB_SIZE 0x4000
-#define FSL_IMX6_AIPS2_CFG_ADDR 0x0217C000
-#define FSL_IMX6_AIPS2_CFG_SIZE 0x4000
-/* DAP */
-#define FSL_IMX6_PTF_CTRL_ADDR 0x02160000
-#define FSL_IMX6_PTF_CTRL_SIZE 0x1000
-#define FSL_IMX6_PTM3_ADDR 0x0215F000
-#define FSL_IMX6_PTM3_SIZE 0x1000
-#define FSL_IMX6_PTM2_ADDR 0x0215E000
-#define FSL_IMX6_PTM2_SIZE 0x1000
-#define FSL_IMX6_PTM1_ADDR 0x0215D000
-#define FSL_IMX6_PTM1_SIZE 0x1000
-#define FSL_IMX6_PTM0_ADDR 0x0215C000
-#define FSL_IMX6_PTM0_SIZE 0x1000
-#define FSL_IMX6_CTI3_ADDR 0x0215B000
-#define FSL_IMX6_CTI3_SIZE 0x1000
-#define FSL_IMX6_CTI2_ADDR 0x0215A000
-#define FSL_IMX6_CTI2_SIZE 0x1000
-#define FSL_IMX6_CTI1_ADDR 0x02159000
-#define FSL_IMX6_CTI1_SIZE 0x1000
-#define FSL_IMX6_CTI0_ADDR 0x02158000
-#define FSL_IMX6_CTI0_SIZE 0x1000
-#define FSL_IMX6_CPU3_PMU_ADDR 0x02157000
-#define FSL_IMX6_CPU3_PMU_SIZE 0x1000
-#define FSL_IMX6_CPU3_DEBUG_IF_ADDR 0x02156000
-#define FSL_IMX6_CPU3_DEBUG_IF_SIZE 0x1000
-#define FSL_IMX6_CPU2_PMU_ADDR 0x02155000
-#define FSL_IMX6_CPU2_PMU_SIZE 0x1000
-#define FSL_IMX6_CPU2_DEBUG_IF_ADDR 0x02154000
-#define FSL_IMX6_CPU2_DEBUG_IF_SIZE 0x1000
-#define FSL_IMX6_CPU1_PMU_ADDR 0x02153000
-#define FSL_IMX6_CPU1_PMU_SIZE 0x1000
-#define FSL_IMX6_CPU1_DEBUG_IF_ADDR 0x02152000
-#define FSL_IMX6_CPU1_DEBUG_IF_SIZE 0x1000
-#define FSL_IMX6_CPU0_PMU_ADDR 0x02151000
-#define FSL_IMX6_CPU0_PMU_SIZE 0x1000
-#define FSL_IMX6_CPU0_DEBUG_IF_ADDR 0x02150000
-#define FSL_IMX6_CPU0_DEBUG_IF_SIZE 0x1000
-#define FSL_IMX6_CA9_INTEG_ADDR 0x0214F000
-#define FSL_IMX6_CA9_INTEG_SIZE 0x1000
-#define FSL_IMX6_FUNNEL_ADDR 0x02144000
-#define FSL_IMX6_FUNNEL_SIZE 0x1000
-#define FSL_IMX6_TPIU_ADDR 0x02143000
-#define FSL_IMX6_TPIU_SIZE 0x1000
-#define FSL_IMX6_EXT_CTI_ADDR 0x02142000
-#define FSL_IMX6_EXT_CTI_SIZE 0x1000
-#define FSL_IMX6_ETB_ADDR 0x02141000
-#define FSL_IMX6_ETB_SIZE 0x1000
-#define FSL_IMX6_DAP_ROM_TABLE_ADDR 0x02140000
-#define FSL_IMX6_DAP_ROM_TABLE_SIZE 0x1000
-/* DAP end */
-#define FSL_IMX6_CAAM_ADDR 0x02100000
-#define FSL_IMX6_CAAM_SIZE 0x10000
-/* AIPS2 end */
-#define FSL_IMX6_AIPS_1_ADDR 0x02000000
-#define FSL_IMX6_AIPS_1_SIZE 0x100000
-/* AIPS1 */
-#define FSL_IMX6_SDMA_ADDR 0x020EC000
-#define FSL_IMX6_SDMA_SIZE 0x4000
-#define FSL_IMX6_DCIC2_ADDR 0x020E8000
-#define FSL_IMX6_DCIC2_SIZE 0x4000
-#define FSL_IMX6_DCIC1_ADDR 0x020E4000
-#define FSL_IMX6_DCIC1_SIZE 0x4000
-#define FSL_IMX6_IOMUXC_ADDR 0x020E0000
-#define FSL_IMX6_IOMUXC_SIZE 0x4000
-#define FSL_IMX6_PGCARM_ADDR 0x020DCA00
-#define FSL_IMX6_PGCARM_SIZE 0x20
-#define FSL_IMX6_PGCPU_ADDR 0x020DC260
-#define FSL_IMX6_PGCPU_SIZE 0x20
-#define FSL_IMX6_GPC_ADDR 0x020DC000
-#define FSL_IMX6_GPC_SIZE 0x4000
-#define FSL_IMX6_SRC_ADDR 0x020D8000
-#define FSL_IMX6_SRC_SIZE 0x4000
-#define FSL_IMX6_EPIT2_ADDR 0x020D4000
-#define FSL_IMX6_EPIT2_SIZE 0x4000
-#define FSL_IMX6_EPIT1_ADDR 0x020D0000
-#define FSL_IMX6_EPIT1_SIZE 0x4000
-#define FSL_IMX6_SNVSHP_ADDR 0x020CC000
-#define FSL_IMX6_SNVSHP_SIZE 0x4000
-#define FSL_IMX6_USBPHY2_ADDR 0x020CA000
-#define FSL_IMX6_USBPHY2_SIZE 0x1000
-#define FSL_IMX6_USBPHY1_ADDR 0x020C9000
-#define FSL_IMX6_USBPHY1_SIZE 0x1000
-#define FSL_IMX6_ANALOG_ADDR 0x020C8000
-#define FSL_IMX6_ANALOG_SIZE 0x1000
-#define FSL_IMX6_CCM_ADDR 0x020C4000
-#define FSL_IMX6_CCM_SIZE 0x4000
-#define FSL_IMX6_WDOG2_ADDR 0x020C0000
-#define FSL_IMX6_WDOG2_SIZE 0x4000
-#define FSL_IMX6_WDOG1_ADDR 0x020BC000
-#define FSL_IMX6_WDOG1_SIZE 0x4000
-#define FSL_IMX6_KPP_ADDR 0x020B8000
-#define FSL_IMX6_KPP_SIZE 0x4000
-#define FSL_IMX6_GPIO7_ADDR 0x020B4000
-#define FSL_IMX6_GPIO7_SIZE 0x4000
-#define FSL_IMX6_GPIO6_ADDR 0x020B0000
-#define FSL_IMX6_GPIO6_SIZE 0x4000
-#define FSL_IMX6_GPIO5_ADDR 0x020AC000
-#define FSL_IMX6_GPIO5_SIZE 0x4000
-#define FSL_IMX6_GPIO4_ADDR 0x020A8000
-#define FSL_IMX6_GPIO4_SIZE 0x4000
-#define FSL_IMX6_GPIO3_ADDR 0x020A4000
-#define FSL_IMX6_GPIO3_SIZE 0x4000
-#define FSL_IMX6_GPIO2_ADDR 0x020A0000
-#define FSL_IMX6_GPIO2_SIZE 0x4000
-#define FSL_IMX6_GPIO1_ADDR 0x0209C000
-#define FSL_IMX6_GPIO1_SIZE 0x4000
-#define FSL_IMX6_GPT_ADDR 0x02098000
-#define FSL_IMX6_GPT_SIZE 0x4000
-#define FSL_IMX6_CAN2_ADDR 0x02094000
-#define FSL_IMX6_CAN2_SIZE 0x4000
-#define FSL_IMX6_CAN1_ADDR 0x02090000
-#define FSL_IMX6_CAN1_SIZE 0x4000
-#define FSL_IMX6_PWM4_ADDR 0x0208C000
-#define FSL_IMX6_PWM4_SIZE 0x4000
-#define FSL_IMX6_PWM3_ADDR 0x02088000
-#define FSL_IMX6_PWM3_SIZE 0x4000
-#define FSL_IMX6_PWM2_ADDR 0x02084000
-#define FSL_IMX6_PWM2_SIZE 0x4000
-#define FSL_IMX6_PWM1_ADDR 0x02080000
-#define FSL_IMX6_PWM1_SIZE 0x4000
-#define FSL_IMX6_AIPS1_CFG_ADDR 0x0207C000
-#define FSL_IMX6_AIPS1_CFG_SIZE 0x4000
-#define FSL_IMX6_VPU_ADDR 0x02040000
-#define FSL_IMX6_VPU_SIZE 0x3C000
-#define FSL_IMX6_AIPS1_SPBA_ADDR 0x0203C000
-#define FSL_IMX6_AIPS1_SPBA_SIZE 0x4000
-#define FSL_IMX6_ASRC_ADDR 0x02034000
-#define FSL_IMX6_ASRC_SIZE 0x4000
-#define FSL_IMX6_SSI3_ADDR 0x02030000
-#define FSL_IMX6_SSI3_SIZE 0x4000
-#define FSL_IMX6_SSI2_ADDR 0x0202C000
-#define FSL_IMX6_SSI2_SIZE 0x4000
-#define FSL_IMX6_SSI1_ADDR 0x02028000
-#define FSL_IMX6_SSI1_SIZE 0x4000
-#define FSL_IMX6_ESAI_ADDR 0x02024000
-#define FSL_IMX6_ESAI_SIZE 0x4000
-#define FSL_IMX6_UART1_ADDR 0x02020000
-#define FSL_IMX6_UART1_SIZE 0x4000
-#define FSL_IMX6_eCSPI5_ADDR 0x02018000
-#define FSL_IMX6_eCSPI5_SIZE 0x4000
-#define FSL_IMX6_eCSPI4_ADDR 0x02014000
-#define FSL_IMX6_eCSPI4_SIZE 0x4000
-#define FSL_IMX6_eCSPI3_ADDR 0x02010000
-#define FSL_IMX6_eCSPI3_SIZE 0x4000
-#define FSL_IMX6_eCSPI2_ADDR 0x0200C000
-#define FSL_IMX6_eCSPI2_SIZE 0x4000
-#define FSL_IMX6_eCSPI1_ADDR 0x02008000
-#define FSL_IMX6_eCSPI1_SIZE 0x4000
-#define FSL_IMX6_SPDIF_ADDR 0x02004000
-#define FSL_IMX6_SPDIF_SIZE 0x4000
-/* AIPS1 end */
-#define FSL_IMX6_PCIe_REG_ADDR 0x01FFC000
-#define FSL_IMX6_PCIe_REG_SIZE 0x4000
-#define FSL_IMX6_PCIe_ADDR 0x01000000
-#define FSL_IMX6_PCIe_SIZE 0xFFC000
-#define FSL_IMX6_GPV_1_PL301_CFG_ADDR 0x00C00000
-#define FSL_IMX6_GPV_1_PL301_CFG_SIZE 0x100000
-#define FSL_IMX6_GPV_0_PL301_CFG_ADDR 0x00B00000
-#define FSL_IMX6_GPV_0_PL301_CFG_SIZE 0x100000
-#define FSL_IMX6_PL310_ADDR 0x00A02000
-#define FSL_IMX6_PL310_SIZE 0x1000
-#define FSL_IMX6_A9MPCORE_ADDR 0x00A00000
-#define FSL_IMX6_A9MPCORE_SIZE 0x2000
-#define FSL_IMX6_OCRAM_ALIAS_ADDR 0x00940000
-#define FSL_IMX6_OCRAM_ALIAS_SIZE 0xC0000
-#define FSL_IMX6_OCRAM_ADDR 0x00900000
-#define FSL_IMX6_OCRAM_SIZE 0x40000
-#define FSL_IMX6_GPV_4_PL301_CFG_ADDR 0x00800000
-#define FSL_IMX6_GPV_4_PL301_CFG_SIZE 0x100000
-#define FSL_IMX6_GPV_3_PL301_CFG_ADDR 0x00300000
-#define FSL_IMX6_GPV_3_PL301_CFG_SIZE 0x100000
-#define FSL_IMX6_GPV_2_PL301_CFG_ADDR 0x00200000
-#define FSL_IMX6_GPV_2_PL301_CFG_SIZE 0x100000
-#define FSL_IMX6_DTCP_ADDR 0x00138000
-#define FSL_IMX6_DTCP_SIZE 0x4000
-#define FSL_IMX6_GPU_2D_ADDR 0x00134000
-#define FSL_IMX6_GPU_2D_SIZE 0x4000
-#define FSL_IMX6_GPU_3D_ADDR 0x00130000
-#define FSL_IMX6_GPU_3D_SIZE 0x4000
-#define FSL_IMX6_HDMI_ADDR 0x00120000
-#define FSL_IMX6_HDMI_SIZE 0x9000
-#define FSL_IMX6_BCH_ADDR 0x00114000
-#define FSL_IMX6_BCH_SIZE 0x4000
-#define FSL_IMX6_GPMI_ADDR 0x00112000
-#define FSL_IMX6_GPMI_SIZE 0x2000
-#define FSL_IMX6_APBH_BRIDGE_DMA_ADDR 0x00110000
-#define FSL_IMX6_APBH_BRIDGE_DMA_SIZE 0x2000
-#define FSL_IMX6_CAAM_MEM_ADDR 0x00100000
-#define FSL_IMX6_CAAM_MEM_SIZE 0x4000
-#define FSL_IMX6_ROM_ADDR 0x00000000
-#define FSL_IMX6_ROM_SIZE 0x18000
-
-#define FSL_IMX6_IOMUXC_IRQ 0
-#define FSL_IMX6_DAP_IRQ 1
-#define FSL_IMX6_SDMA_IRQ 2
-#define FSL_IMX6_VPU_JPEG_IRQ 3
-#define FSL_IMX6_SNVS_PMIC_IRQ 4
-#define FSL_IMX6_IPU1_ERROR_IRQ 5
-#define FSL_IMX6_IPU1_SYNC_IRQ 6
-#define FSL_IMX6_IPU2_ERROR_IRQ 7
-#define FSL_IMX6_IPU2_SYNC_IRQ 8
-#define FSL_IMX6_GPU3D_IRQ 9
-#define FSL_IMX6_R2D_IRQ 10
-#define FSL_IMX6_V2D_IRQ 11
-#define FSL_IMX6_VPU_IRQ 12
-#define FSL_IMX6_APBH_BRIDGE_DMA_IRQ 13
-#define FSL_IMX6_EIM_IRQ 14
-#define FSL_IMX6_BCH_IRQ 15
-#define FSL_IMX6_GPMI_IRQ 16
-#define FSL_IMX6_DTCP_IRQ 17
-#define FSL_IMX6_VDOA_IRQ 18
-#define FSL_IMX6_SNVS_CONS_IRQ 19
-#define FSL_IMX6_SNVS_SEC_IRQ 20
-#define FSL_IMX6_CSU_IRQ 21
-#define FSL_IMX6_uSDHC1_IRQ 22
-#define FSL_IMX6_uSDHC2_IRQ 23
-#define FSL_IMX6_uSDHC3_IRQ 24
-#define FSL_IMX6_uSDHC4_IRQ 25
-#define FSL_IMX6_UART1_IRQ 26
-#define FSL_IMX6_UART2_IRQ 27
-#define FSL_IMX6_UART3_IRQ 28
-#define FSL_IMX6_UART4_IRQ 29
-#define FSL_IMX6_UART5_IRQ 30
-#define FSL_IMX6_ECSPI1_IRQ 31
-#define FSL_IMX6_ECSPI2_IRQ 32
-#define FSL_IMX6_ECSPI3_IRQ 33
-#define FSL_IMX6_ECSPI4_IRQ 34
-#define FSL_IMX6_ECSPI5_IRQ 35
-#define FSL_IMX6_I2C1_IRQ 36
-#define FSL_IMX6_I2C2_IRQ 37
-#define FSL_IMX6_I2C3_IRQ 38
-#define FSL_IMX6_SATA_IRQ 39
-#define FSL_IMX6_USB_HOST1_IRQ 40
-#define FSL_IMX6_USB_HOST2_IRQ 41
-#define FSL_IMX6_USB_HOST3_IRQ 42
-#define FSL_IMX6_USB_OTG_IRQ 43
-#define FSL_IMX6_USB_PHY_UTMI0_IRQ 44
-#define FSL_IMX6_USB_PHY_UTMI1_IRQ 45
-#define FSL_IMX6_SSI1_IRQ 46
-#define FSL_IMX6_SSI2_IRQ 47
-#define FSL_IMX6_SSI3_IRQ 48
-#define FSL_IMX6_TEMP_IRQ 49
-#define FSL_IMX6_ASRC_IRQ 50
-#define FSL_IMX6_ESAI_IRQ 51
-#define FSL_IMX6_SPDIF_IRQ 52
-#define FSL_IMX6_MLB150_IRQ 53
-#define FSL_IMX6_PMU1_IRQ 54
-#define FSL_IMX6_GPT_IRQ 55
-#define FSL_IMX6_EPIT1_IRQ 56
-#define FSL_IMX6_EPIT2_IRQ 57
-#define FSL_IMX6_GPIO1_INT7_IRQ 58
-#define FSL_IMX6_GPIO1_INT6_IRQ 59
-#define FSL_IMX6_GPIO1_INT5_IRQ 60
-#define FSL_IMX6_GPIO1_INT4_IRQ 61
-#define FSL_IMX6_GPIO1_INT3_IRQ 62
-#define FSL_IMX6_GPIO1_INT2_IRQ 63
-#define FSL_IMX6_GPIO1_INT1_IRQ 64
-#define FSL_IMX6_GPIO1_INT0_IRQ 65
-#define FSL_IMX6_GPIO1_LOW_IRQ 66
-#define FSL_IMX6_GPIO1_HIGH_IRQ 67
-#define FSL_IMX6_GPIO2_LOW_IRQ 68
-#define FSL_IMX6_GPIO2_HIGH_IRQ 69
-#define FSL_IMX6_GPIO3_LOW_IRQ 70
-#define FSL_IMX6_GPIO3_HIGH_IRQ 71
-#define FSL_IMX6_GPIO4_LOW_IRQ 72
-#define FSL_IMX6_GPIO4_HIGH_IRQ 73
-#define FSL_IMX6_GPIO5_LOW_IRQ 74
-#define FSL_IMX6_GPIO5_HIGH_IRQ 75
-#define FSL_IMX6_GPIO6_LOW_IRQ 76
-#define FSL_IMX6_GPIO6_HIGH_IRQ 77
-#define FSL_IMX6_GPIO7_LOW_IRQ 78
-#define FSL_IMX6_GPIO7_HIGH_IRQ 79
-#define FSL_IMX6_WDOG1_IRQ 80
-#define FSL_IMX6_WDOG2_IRQ 81
-#define FSL_IMX6_KPP_IRQ 82
-#define FSL_IMX6_PWM1_IRQ 83
-#define FSL_IMX6_PWM2_IRQ 84
-#define FSL_IMX6_PWM3_IRQ 85
-#define FSL_IMX6_PWM4_IRQ 86
-#define FSL_IMX6_CCM1_IRQ 87
-#define FSL_IMX6_CCM2_IRQ 88
-#define FSL_IMX6_GPC_IRQ 89
-#define FSL_IMX6_SRC_IRQ 91
-#define FSL_IMX6_CPU_L2_IRQ 92
-#define FSL_IMX6_CPU_PARITY_IRQ 93
-#define FSL_IMX6_CPU_PERF_IRQ 94
-#define FSL_IMX6_CPU_CTI_IRQ 95
-#define FSL_IMX6_SRC_COMB_IRQ 96
-#define FSL_IMX6_MIPI_CSI1_IRQ 100
-#define FSL_IMX6_MIPI_CSI2_IRQ 101
-#define FSL_IMX6_MIPI_DSI_IRQ 102
-#define FSL_IMX6_MIPI_HSI_IRQ 103
-#define FSL_IMX6_SJC_IRQ 104
-#define FSL_IMX6_CAAM0_IRQ 105
-#define FSL_IMX6_CAAM1_IRQ 106
-#define FSL_IMX6_ASC1_IRQ 108
-#define FSL_IMX6_ASC2_IRQ 109
-#define FSL_IMX6_FLEXCAN1_IRQ 110
-#define FSL_IMX6_FLEXCAN2_IRQ 111
-#define FSL_IMX6_HDMI_MASTER_IRQ 115
-#define FSL_IMX6_HDMI_CEC_IRQ 116
-#define FSL_IMX6_MLB150_LOW_IRQ 117
-#define FSL_IMX6_ENET_MAC_1588_IRQ 118
-#define FSL_IMX6_ENET_MAC_IRQ 119
-#define FSL_IMX6_PCIE1_IRQ 120
-#define FSL_IMX6_PCIE2_IRQ 121
-#define FSL_IMX6_PCIE3_IRQ 122
-#define FSL_IMX6_PCIE4_IRQ 123
-#define FSL_IMX6_DCIC1_IRQ 124
-#define FSL_IMX6_DCIC2_IRQ 125
-#define FSL_IMX6_MLB150_HIGH_IRQ 126
-#define FSL_IMX6_PMU2_IRQ 127
-#define FSL_IMX6_MAX_IRQ 128
-
-#endif /* FSL_IMX6_H */
index f026c8d..0ad5fb8 100644 (file)
@@ -20,7 +20,6 @@
 #include "exec/memory.h"
 # define hw_omap_h             "omap.h"
 #include "hw/irq.h"
-#include "target-arm/cpu-qom.h"
 
 # define OMAP_EMIFS_BASE       0x00000000
 # define OMAP2_Q0_BASE         0x00000000
index dd1a48b..259b852 100644 (file)
@@ -6,12 +6,10 @@
  *
  * This code is licensed under the GNU GPL v2.
  */
-
 #ifndef PXA_H
-#define PXA_H
+# define PXA_H                 "pxa.h"
 
 #include "exec/memory.h"
-#include "target-arm/cpu-qom.h"
 
 /* Interrupt numbers */
 # define PXA2XX_PIC_SSP3       0
@@ -190,4 +188,4 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space, unsigned int sdram_size,
                          const char *revision);
 PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size);
 
-#endif /* PXA_H */
+#endif /* PXA_H */
index fae3229..7379731 100644 (file)
@@ -19,7 +19,8 @@
  */
 
 #ifndef HW_SOC_DMA_H
-#define HW_SOC_DMA_H
+#define HW_SOC_DMA_H 1
+
 
 #include "exec/memory.h"
 #include "hw/irq.h"
index 779b5da..0390eff 100644 (file)
@@ -22,8 +22,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef HW_ARM_STM32F205_SOC_H
-#define HW_ARM_STM32F205_SOC_H
+#ifndef HW_ARM_STM32F205SOC_H
+#define HW_ARM_STM32F205SOC_H
 
 #include "hw/misc/stm32f2xx_syscfg.h"
 #include "hw/timer/stm32f2xx_timer.h"
index e43330a..7d3700e 100644 (file)
@@ -22,7 +22,6 @@
 
 #include "qemu-common.h"
 #include "hw/arm/virt.h"
-#include "qemu/notify.h"
 
 #define ACPI_GICC_ENABLED 1
 
index 9650193..ecd8589 100644 (file)
@@ -31,7 +31,6 @@
 #define QEMU_ARM_VIRT_H
 
 #include "qemu-common.h"
-#include "exec/hwaddr.h"
 
 #define NUM_GICV2M_SPIS       64
 #define NUM_VIRTIO_TRANSPORTS 32
 #define ARCH_TIMER_NS_EL1_IRQ 14
 #define ARCH_TIMER_NS_EL2_IRQ 10
 
-#define VIRTUAL_PMU_IRQ 7
-
-#define PPI(irq) ((irq) + 16)
-
 enum {
     VIRT_FLASH,
     VIRT_MEM,
index c2931bf..2332596 100644 (file)
@@ -26,8 +26,6 @@
 #include "hw/ide/ahci.h"
 #include "hw/sd/sdhci.h"
 #include "hw/ssi/xilinx_spips.h"
-#include "hw/dma/xlnx_dpdma.h"
-#include "hw/display/xlnx_dp.h"
 
 #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
 #define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \
@@ -83,16 +81,9 @@ typedef struct XlnxZynqMPState {
     SysbusAHCIState sata;
     SDHCIState sdhci[XLNX_ZYNQMP_NUM_SDHCI];
     XilinxSPIPS spi[XLNX_ZYNQMP_NUM_SPIS];
-    XlnxDPState dp;
-    XlnxDPDMAState dpdma;
 
     char *boot_cpu;
     ARMCPU *boot_cpu_ptr;
-
-    /* Has the ARM Security extensions?  */
-    bool secure;
-    /* Has the RPU subsystem?  */
-    bool has_rpu;
 }  XlnxZynqMPState;
 
 #define XLNX_ZYNQMP_H
index 55d40f7..b28abdd 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef HW_AUDIO_H
-#define HW_AUDIO_H
+#ifndef HW_AUDIODEV_H
+#define HW_AUDIODEV_H 1
 
 void isa_register_soundhw(const char *name, const char *descr,
                           int (*init_isa)(ISABus *bus));
index 172afbf..ef95dd1 100644 (file)
@@ -38,10 +38,10 @@ static inline ISADevice *pcspk_init(ISABus *bus, ISADevice *pit)
     isadev = isa_create(bus, TYPE_PC_SPEAKER);
     dev = DEVICE(isadev);
     qdev_prop_set_uint32(dev, "iobase", 0x61);
-    object_property_set_link(OBJECT(dev), OBJECT(pit), "pit", NULL);
+    qdev_prop_set_ptr(dev, "pit", pit);
     qdev_init_nofail(dev);
 
     return isadev;
 }
 
-#endif /* HW_PCSPK_H */
+#endif /* !HW_PCSPK_H */
index df9d207..984660e 100644 (file)
@@ -8,8 +8,8 @@
  * later.  See the COPYING file in the top-level directory.
  */
 
-#ifndef HW_BLOCK_H
-#define HW_BLOCK_H
+#ifndef HW_BLOCK_COMMON_H
+#define HW_BLOCK_COMMON_H
 
 #include "qemu-common.h"
 
@@ -25,9 +25,6 @@ typedef struct BlockConf {
     uint32_t discard_granularity;
     /* geometry, not all devices use this */
     uint32_t cyls, heads, secs;
-    OnOffAuto wce;
-    BlockdevOnError rerror;
-    BlockdevOnError werror;
 } BlockConf;
 
 static inline unsigned int get_physical_block_exp(BlockConf *conf)
@@ -52,20 +49,13 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
     DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0),  \
     DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0),    \
     DEFINE_PROP_UINT32("discard_granularity", _state, \
-                       _conf.discard_granularity, -1), \
-    DEFINE_PROP_ON_OFF_AUTO("write-cache", _state, _conf.wce, ON_OFF_AUTO_AUTO)
+                       _conf.discard_granularity, -1)
 
 #define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf)      \
     DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0),  \
     DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0), \
     DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0)
 
-#define DEFINE_BLOCK_ERROR_PROPERTIES(_state, _conf)                    \
-    DEFINE_PROP_BLOCKDEV_ON_ERROR("rerror", _state, _conf.rerror,       \
-                                  BLOCKDEV_ON_ERROR_AUTO),              \
-    DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror,       \
-                                  BLOCKDEV_ON_ERROR_AUTO)
-
 /* Configuration helpers */
 
 void blkconf_serial(BlockConf *conf, char **serial);
@@ -73,7 +63,6 @@ void blkconf_geometry(BlockConf *conf, int *trans,
                       unsigned cyls_max, unsigned heads_max, unsigned secs_max,
                       Error **errp);
 void blkconf_blocksizes(BlockConf *conf);
-void blkconf_apply_backend_options(BlockConf *conf);
 
 /* Hard disk geometry */
 
index 67c3aa3..50ccbbc 100644 (file)
@@ -1,13 +1,10 @@
 #ifndef HW_FLASH_H
-#define HW_FLASH_H
+#define HW_FLASH_H 1
 
 /* NOR flash devices */
 
 #include "exec/memory.h"
 
-#define TYPE_CFI_PFLASH01 "cfi.pflash01"
-#define TYPE_CFI_PFLASH02 "cfi.pflash02"
-
 typedef struct pflash_t pflash_t;
 
 /* pflash_cfi01.c */
index 3e69eca..8d4fe56 100644 (file)
@@ -40,7 +40,6 @@ int machine_kvm_shadow_mem(MachineState *machine);
 int machine_phandle_start(MachineState *machine);
 bool machine_dump_guest_core(MachineState *machine);
 bool machine_mem_merge(MachineState *machine);
-void machine_register_compat_props(MachineState *machine);
 
 /**
  * CPUArchId:
@@ -82,10 +81,6 @@ typedef struct {
  *    Returns an array of @CPUArchId architecture-dependent CPU IDs
  *    which includes CPU IDs for present and possible to hotplug CPUs.
  *    Caller is responsible for freeing returned list.
- * @query_hotpluggable_cpus:
- *    Returns a @HotpluggableCPUList, which describes CPUs objects which
- *    could be added with -device/device_add.
- *    Caller is responsible for freeing returned list.
  */
 struct MachineClass {
     /*< private >*/
@@ -119,7 +114,7 @@ struct MachineClass {
     const char *default_machine_opts;
     const char *default_boot_order;
     const char *default_display;
-    GArray *compat_props;
+    GlobalProperty *compat_props;
     const char *hw_version;
     ram_addr_t default_ram_size;
     bool option_rom_has_mr;
@@ -129,7 +124,6 @@ struct MachineClass {
                                            DeviceState *dev);
     unsigned (*cpu_index_to_socket_id)(unsigned cpu_index);
     CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine);
-    HotpluggableCPUList *(*query_hotpluggable_cpus)(MachineState *machine);
 };
 
 /**
@@ -160,7 +154,6 @@ struct MachineState {
     bool iommu;
     bool suppress_vmdesc;
     bool enforce_config_section;
-    bool enable_graphics;
 
     ram_addr_t ram_size;
     ram_addr_t maxram_size;
@@ -192,18 +185,11 @@ struct MachineState {
 
 #define SET_MACHINE_COMPAT(m, COMPAT) \
     do {                              \
-        int i;                        \
         static GlobalProperty props[] = {       \
             COMPAT                              \
             { /* end of list */ }               \
         };                                      \
-        if (!m->compat_props) { \
-            m->compat_props = g_array_new(false, false, sizeof(void *)); \
-        } \
-        for (i = 0; props[i].driver != NULL; i++) {    \
-            GlobalProperty *prop = &props[i];          \
-            g_array_append_val(m->compat_props, prop); \
-        }                                              \
+        (m)->compat_props = props;              \
     } while (0)
 
 #endif
index 185e79d..c7c7909 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #ifndef HW_BT_H
-#define HW_BT_H
+#define HW_BT_H 1
 
 #include "hw/irq.h"
 
index a12773c..6310f52 100644 (file)
@@ -49,22 +49,5 @@ typedef struct {
     QEMUTimer *fifo_trigger_handle;
 } CadenceUARTState;
 
-static inline DeviceState *cadence_uart_create(hwaddr addr,
-                                        qemu_irq irq,
-                                        CharDriverState *chr)
-{
-    DeviceState *dev;
-    SysBusDevice *s;
-
-    dev = qdev_create(NULL, TYPE_CADENCE_UART);
-    s = SYS_BUS_DEVICE(dev);
-    qdev_prop_set_chr(dev, "chardev", chr);
-    qdev_init_nofail(dev);
-    sysbus_mmio_map(s, 0, addr);
-    sysbus_connect_irq(s, 0, irq);
-
-    return dev;
-}
-
 #define CADENCE_UART_H
 #endif
index 297e2eb..2742d70 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef HW_ESCC_H
-#define HW_ESCC_H
+#define HW_ESCC_H 1
 
 /* escc.c */
 #define TYPE_ESCC "escc"
index e7c6fb5..70dc416 100644 (file)
@@ -10,4 +10,4 @@ uint32_t lm32_juart_get_jrx(DeviceState *d);
 void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx);
 void lm32_juart_set_jrx(DeviceState *d, uint32_t jrx);
 
-#endif /* QEMU_HW_CHAR_LM32_JUART_H */
+#endif /* QEMU_HW_LM32_JUART_H */
diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h
deleted file mode 100644 (file)
index 0ca7c19..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2 or later, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef HW_PL011_H
-#define HW_PL011_H
-
-static inline DeviceState *pl011_create(hwaddr addr,
-                                        qemu_irq irq,
-                                        CharDriverState *chr)
-{
-    DeviceState *dev;
-    SysBusDevice *s;
-
-    dev = qdev_create(NULL, "pl011");
-    s = SYS_BUS_DEVICE(dev);
-    qdev_prop_set_chr(dev, "chardev", chr);
-    qdev_init_nofail(dev);
-    sysbus_mmio_map(s, 0, addr);
-    sysbus_connect_irq(s, 0, irq);
-
-    return dev;
-}
-
-static inline DeviceState *pl011_luminary_create(hwaddr addr,
-                                                 qemu_irq irq,
-                                                 CharDriverState *chr)
-{
-    DeviceState *dev;
-    SysBusDevice *s;
-
-    dev = qdev_create(NULL, "pl011_luminary");
-    s = SYS_BUS_DEVICE(dev);
-    qdev_prop_set_chr(dev, "chardev", chr);
-    qdev_init_nofail(dev);
-    sysbus_mmio_map(s, 0, addr);
-    sysbus_connect_irq(s, 0, irq);
-
-    return dev;
-}
-
-#endif
index a4fd3d5..15beb6b 100644 (file)
@@ -22,9 +22,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
 #ifndef HW_SERIAL_H
-#define HW_SERIAL_H
+#define HW_SERIAL_H 1
 
 #include "hw/hw.h"
 #include "sysemu/sysemu.h"
@@ -56,8 +55,7 @@ struct SerialState {
     int last_break_enable;
     int it_shift;
     int baudbase;
-    uint32_t tsr_retry;
-    guint watch_tag;
+    int tsr_retry;
     uint32_t wakeup;
 
     /* Time when the last byte was successfully sent out of the tsr */
diff --git a/include/hw/char/xilinx_uartlite.h b/include/hw/char/xilinx_uartlite.h
deleted file mode 100644 (file)
index 8b4fc54..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2 or later, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef XILINX_UARTLITE_H
-#define XILINX_UARTLITE_H
-
-static inline DeviceState *xilinx_uartlite_create(hwaddr addr,
-                                        qemu_irq irq,
-                                        CharDriverState *chr)
-{
-    DeviceState *dev;
-    SysBusDevice *s;
-
-    dev = qdev_create(NULL, "xlnx.xps-uartlite");
-    s = SYS_BUS_DEVICE(dev);
-    qdev_prop_set_chr(dev, "chardev", chr);
-    qdev_init_nofail(dev);
-    sysbus_mmio_map(s, 0, addr);
-    sysbus_connect_irq(s, 0, irq);
-
-    return dev;
-}
-
-#endif
index 7ee7299..81fc19b 100644 (file)
@@ -1,21 +1,6 @@
 #ifndef HW_COMPAT_H
 #define HW_COMPAT_H
 
-#define HW_COMPAT_2_6 \
-    {\
-        .driver   = "virtio-mmio",\
-        .property = "format_transport_address",\
-        .value    = "off",\
-    },{\
-        .driver   = "virtio-pci",\
-        .property = "disable-modern",\
-        .value    = "on",\
-    },{\
-        .driver   = "virtio-pci",\
-        .property = "disable-legacy",\
-        .value    = "off",\
-    },
-
 #define HW_COMPAT_2_5 \
     {\
         .driver   = "isa-fdc",\
diff --git a/include/hw/cpu/core.h b/include/hw/cpu/core.h
deleted file mode 100644 (file)
index 79ac79c..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * CPU core abstract device
- *
- * Copyright (C) 2016 Bharata B Rao <bharata@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#ifndef HW_CPU_CORE_H
-#define HW_CPU_CORE_H
-
-#include "qemu/osdep.h"
-#include "hw/qdev.h"
-
-#define TYPE_CPU_CORE "cpu-core"
-
-#define CPU_CORE(obj) \
-    OBJECT_CHECK(CPUCore, (obj), TYPE_CPU_CORE)
-
-typedef struct CPUCore {
-    /*< private >*/
-    DeviceState parent_obj;
-
-    /*< public >*/
-    int core_id;
-    int nr_threads;
-} CPUCore;
-
-/* Note: topology field names need to be kept in sync with
- * 'CpuInstanceProperties' */
-
-#define CPU_CORE_PROP_CORE_ID "core-id"
-
-#endif
index 723a275..73a6134 100644 (file)
@@ -22,8 +22,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef HW_ETRAXFS_H
-#define HW_ETRAXFS_H
+#ifndef HW_EXTRAXFS_H
+#define HW_EXTRAXFS_H 1
 
 #include "net/net.h"
 #include "hw/cris/etraxfs_dma.h"
@@ -46,20 +46,4 @@ etraxfs_eth_init(NICInfo *nd, hwaddr base, int phyaddr,
     return dev;
 }
 
-static inline DeviceState *etraxfs_ser_create(hwaddr addr,
-                                              qemu_irq irq,
-                                              CharDriverState *chr)
-{
-    DeviceState *dev;
-    SysBusDevice *s;
-
-    dev = qdev_create(NULL, "etraxfs,serial");
-    s = SYS_BUS_DEVICE(dev);
-    qdev_prop_set_chr(dev, "chardev", chr);
-    qdev_init_nofail(dev);
-    sysbus_mmio_map(s, 0, addr);
-    sysbus_connect_irq(s, 0, irq);
-    return dev;
-}
-
 #endif
index f6f33e0..38104a6 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef HW_ETRAXFS_DMA_H
-#define HW_ETRAXFS_DMA_H
+#define HW_ETRAXFS_DMA_H 1
 
 struct dma_context_metadata {
        /* data descriptor md */
diff --git a/include/hw/display/dpcd.h b/include/hw/display/dpcd.h
deleted file mode 100644 (file)
index 6880ee3..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * dpcd.h
- *
- *  Copyright (C)2015 : GreenSocs Ltd
- *      http://www.greensocs.com/ , email: info@greensocs.com
- *
- *  Developed by :
- *  Frederic Konrad   <fred.konrad@greensocs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option)any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef DPCD_H
-#define DPCD_H
-
-typedef struct DPCDState DPCDState;
-
-#define TYPE_DPCD "dpcd"
-#define DPCD(obj) OBJECT_CHECK(DPCDState, (obj), TYPE_DPCD)
-
-/* DCPD Revision. */
-#define DPCD_REVISION                           0x00
-#define DPCD_REV_1_0                            0x10
-#define DPCD_REV_1_1                            0x11
-
-/* DCPD Max Link Rate. */
-#define DPCD_MAX_LINK_RATE                      0x01
-#define DPCD_1_62GBPS                           0x06
-#define DPCD_2_7GBPS                            0x0A
-#define DPCD_5_4GBPS                            0x14
-
-#define DPCD_MAX_LANE_COUNT                     0x02
-#define DPCD_ONE_LANE                           0x01
-#define DPCD_TWO_LANES                          0x02
-#define DPCD_FOUR_LANES                         0x04
-
-/* DCPD Max down spread. */
-#define DPCD_UP_TO_0_5                          0x01
-#define DPCD_NO_AUX_HANDSHAKE_LINK_TRAINING     0x40
-
-/* DCPD Downstream port type. */
-#define DPCD_DISPLAY_PORT                       0x00
-#define DPCD_ANALOG                             0x02
-#define DPCD_DVI_HDMI                           0x04
-#define DPCD_OTHER                              0x06
-
-/* DPCD Format conversion. */
-#define DPCD_FORMAT_CONVERSION                  0x08
-
-/* Main link channel coding. */
-#define DPCD_ANSI_8B_10B                        0x01
-
-/* Down stream port count. */
-#define DPCD_OUI_SUPPORTED                      0x80
-
-/* Receiver port capability. */
-#define DPCD_RECEIVE_PORT0_CAP_0                0x08
-#define DPCD_RECEIVE_PORT0_CAP_1                0x09
-#define DPCD_EDID_PRESENT                       0x02
-#define DPCD_ASSOCIATED_TO_PRECEDING_PORT       0x04
-
-/* Down stream port capability. */
-#define DPCD_CAP_DISPLAY_PORT                   0x000
-#define DPCD_CAP_ANALOG_VGA                     0x001
-#define DPCD_CAP_DVI                            0x002
-#define DPCD_CAP_HDMI                           0x003
-#define DPCD_CAP_OTHER                          0x100
-
-#define DPCD_LANE0_1_STATUS                     0x202
-#define DPCD_LANE0_CR_DONE                      (1 << 0)
-#define DPCD_LANE0_CHANNEL_EQ_DONE              (1 << 1)
-#define DPCD_LANE0_SYMBOL_LOCKED                (1 << 2)
-#define DPCD_LANE1_CR_DONE                      (1 << 4)
-#define DPCD_LANE1_CHANNEL_EQ_DONE              (1 << 5)
-#define DPCD_LANE1_SYMBOL_LOCKED                (1 << 6)
-
-#define DPCD_LANE2_3_STATUS                     0x203
-#define DPCD_LANE2_CR_DONE                      (1 << 0)
-#define DPCD_LANE2_CHANNEL_EQ_DONE              (1 << 1)
-#define DPCD_LANE2_SYMBOL_LOCKED                (1 << 2)
-#define DPCD_LANE3_CR_DONE                      (1 << 4)
-#define DPCD_LANE3_CHANNEL_EQ_DONE              (1 << 5)
-#define DPCD_LANE3_SYMBOL_LOCKED                (1 << 6)
-
-#define DPCD_LANE_ALIGN_STATUS_UPDATED          0x204
-#define DPCD_INTERLANE_ALIGN_DONE               0x01
-#define DPCD_DOWNSTREAM_PORT_STATUS_CHANGED     0x40
-#define DPCD_LINK_STATUS_UPDATED                0x80
-
-#define DPCD_SINK_STATUS                        0x205
-#define DPCD_RECEIVE_PORT_0_STATUS              0x01
-
-#endif /* DPCD_H */
diff --git a/include/hw/display/xlnx_dp.h b/include/hw/display/xlnx_dp.h
deleted file mode 100644 (file)
index ee046a5..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * xlnx_dp.h
- *
- *  Copyright (C) 2015 : GreenSocs Ltd
- *      http://www.greensocs.com/ , email: info@greensocs.com
- *
- *  Developed by :
- *  Frederic Konrad   <fred.konrad@greensocs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "hw/sysbus.h"
-#include "ui/console.h"
-#include "hw/misc/auxbus.h"
-#include "hw/i2c/i2c.h"
-#include "hw/display/dpcd.h"
-#include "hw/i2c/i2c-ddc.h"
-#include "qemu/fifo8.h"
-#include "hw/dma/xlnx_dpdma.h"
-#include "audio/audio.h"
-
-#ifndef XLNX_DP_H
-#define XLNX_DP_H
-
-#define AUD_CHBUF_MAX_DEPTH                 32768
-#define MAX_QEMU_BUFFER_SIZE                4096
-
-#define DP_CORE_REG_ARRAY_SIZE              (0x3AF >> 2)
-#define DP_AVBUF_REG_ARRAY_SIZE             (0x238 >> 2)
-#define DP_VBLEND_REG_ARRAY_SIZE            (0x1DF >> 2)
-#define DP_AUDIO_REG_ARRAY_SIZE             (0x50 >> 2)
-
-struct PixmanPlane {
-    pixman_format_code_t format;
-    DisplaySurface *surface;
-};
-
-typedef struct XlnxDPState {
-    /*< private >*/
-    SysBusDevice parent_obj;
-
-    /* < public >*/
-    MemoryRegion container;
-
-    uint32_t core_registers[DP_CORE_REG_ARRAY_SIZE];
-    MemoryRegion core_iomem;
-
-    uint32_t avbufm_registers[DP_AVBUF_REG_ARRAY_SIZE];
-    MemoryRegion avbufm_iomem;
-
-    uint32_t vblend_registers[DP_VBLEND_REG_ARRAY_SIZE];
-    MemoryRegion vblend_iomem;
-
-    uint32_t audio_registers[DP_AUDIO_REG_ARRAY_SIZE];
-    MemoryRegion audio_iomem;
-
-    QemuConsole *console;
-
-    /*
-     * This is the planes used to display in console. When the blending is
-     * enabled bout_plane is displayed in console else it's g_plane.
-     */
-    struct PixmanPlane g_plane;
-    struct PixmanPlane v_plane;
-    struct PixmanPlane bout_plane;
-
-    QEMUSoundCard aud_card;
-    SWVoiceOut *amixer_output_stream;
-    int16_t audio_buffer_0[AUD_CHBUF_MAX_DEPTH];
-    int16_t audio_buffer_1[AUD_CHBUF_MAX_DEPTH];
-    size_t audio_data_available[2];
-    int64_t temp_buffer[AUD_CHBUF_MAX_DEPTH];
-    int16_t out_buffer[AUD_CHBUF_MAX_DEPTH];
-    size_t byte_left; /* byte available in out_buffer. */
-    size_t data_ptr;  /* next byte to be sent to QEMU. */
-
-    /* Associated DPDMA controller. */
-    XlnxDPDMAState *dpdma;
-
-    qemu_irq irq;
-
-    AUXBus *aux_bus;
-    Fifo8 rx_fifo;
-    Fifo8 tx_fifo;
-
-    /*
-     * XXX: This should be in an other module.
-     */
-    DPCDState *dpcd;
-    I2CDDCState *edid;
-} XlnxDPState;
-
-#define TYPE_XLNX_DP "xlnx.v-dp"
-#define XLNX_DP(obj) OBJECT_CHECK(XlnxDPState, (obj), TYPE_XLNX_DP)
-
-#endif /* !XLNX_DP_H */
diff --git a/include/hw/dma/xlnx_dpdma.h b/include/hw/dma/xlnx_dpdma.h
deleted file mode 100644 (file)
index 664df28..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * xlnx_dpdma.h
- *
- *  Copyright (C) 2015 : GreenSocs Ltd
- *      http://www.greensocs.com/ , email: info@greensocs.com
- *
- *  Developed by :
- *  Frederic Konrad   <fred.konrad@greensocs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef XLNX_DPDMA_H
-#define XLNX_DPDMA_H
-
-#include "hw/sysbus.h"
-#include "ui/console.h"
-#include "sysemu/dma.h"
-
-#define XLNX_DPDMA_REG_ARRAY_SIZE (0x1000 >> 2)
-
-struct XlnxDPDMAState {
-    /*< private >*/
-    SysBusDevice parent_obj;
-    /*< public >*/
-    MemoryRegion iomem;
-    uint32_t registers[XLNX_DPDMA_REG_ARRAY_SIZE];
-    uint8_t *data[6];
-    bool operation_finished[6];
-    qemu_irq irq;
-};
-
-typedef struct XlnxDPDMAState XlnxDPDMAState;
-
-#define TYPE_XLNX_DPDMA "xlnx.dpdma"
-#define XLNX_DPDMA(obj) OBJECT_CHECK(XlnxDPDMAState, (obj), TYPE_XLNX_DPDMA)
-
-/*
- * xlnx_dpdma_start_operation: Start the operation on the specified channel. The
- *                             DPDMA gets the current descriptor and retrieves
- *                             data to the buffer specified by
- *                             dpdma_set_host_data_location().
- *
- * Returns The number of bytes transfered by the DPDMA or 0 if an error occured.
- *
- * @s The DPDMA state.
- * @channel The channel to start.
- */
-size_t xlnx_dpdma_start_operation(XlnxDPDMAState *s, uint8_t channel,
-                                  bool one_desc);
-
-/*
- * xlnx_dpdma_set_host_data_location: Set the location in the host memory where
- *                                    to store the data out from the dma
- *                                    channel.
- *
- * @s The DPDMA state.
- * @channel The channel associated to the pointer.
- * @p The buffer where to store the data.
- */
-/* XXX: add a maximum size arg and send an interrupt in case of overflow. */
-void xlnx_dpdma_set_host_data_location(XlnxDPDMAState *s, uint8_t channel,
-                                       void *p);
-
-/*
- * xlnx_dpdma_trigger_vsync_irq: Trigger a VSYNC IRQ when the display is
- *                               updated.
- *
- * @s The DPDMA state.
- */
-void xlnx_dpdma_trigger_vsync_irq(XlnxDPDMAState *s);
-
-#endif /* XLNX_DPDMA_H */
index 123a9f8..6079602 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef HW_EMPTY_SLOT_H
-#define HW_EMPTY_SLOT_H
+#define HW_EMPTY_SLOT_H 1
 
 /* empty_slot.c */
 void empty_slot_init(hwaddr addr, uint64_t slot_size);
index 050cb05..7afaec0 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef FW_PATH_PROVIDER_H
-#define FW_PATH_PROVIDER_H
+#define FW_PATH_PROVIDER_H 1
 
 #include "qemu-common.h"
 #include "qom/object.h"
index ffab437..b15a09f 100644 (file)
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef IMX_GPIO_H
-#define IMX_GPIO_H
+#ifndef __IMX_GPIO_H_
+#define __IMX_GPIO_H_
 
-#include "hw/sysbus.h"
+#include <hw/sysbus.h>
 
 #define TYPE_IMX_GPIO "imx.gpio"
 #define IMX_GPIO(obj) OBJECT_CHECK(IMXGPIOState, (obj), TYPE_IMX_GPIO)
@@ -60,4 +60,4 @@ typedef struct IMXGPIOState {
     qemu_irq output[IMX_GPIO_PIN_COUNT];
 } IMXGPIOState;
 
-#endif /* IMX_GPIO_H */
+#endif /* __IMX_GPIO_H_ */
index c0db869..da1d0e4 100644 (file)
@@ -45,8 +45,7 @@ typedef void (*hotplug_fn)(HotplugHandler *plug_handler,
  * hardware (un)plug functions.
  *
  * @parent: Opaque parent interface.
- * @pre_plug: pre plug callback called at start of device.realize(true)
- * @plug: plug callback called at end of device.realize(true).
+ * @plug: plug callback.
  * @unplug_request: unplug request callback.
  *                  Used as a means to initiate device unplug for devices that
  *                  require asynchronous unplug handling.
@@ -59,7 +58,6 @@ typedef struct HotplugHandlerClass {
     InterfaceClass parent;
 
     /* <public> */
-    hotplug_fn pre_plug;
     hotplug_fn plug;
     hotplug_fn unplug_request;
     hotplug_fn unplug;
@@ -75,16 +73,6 @@ void hotplug_handler_plug(HotplugHandler *plug_handler,
                           Error **errp);
 
 /**
- * hotplug_handler_pre_plug:
- *
- * Call #HotplugHandlerClass.pre_plug callback of @plug_handler.
- */
-void hotplug_handler_pre_plug(HotplugHandler *plug_handler,
-                              DeviceState *plugged_dev,
-                              Error **errp);
-
-
-/**
  * hotplug_handler_unplug_request:
  *
  * Calls #HotplugHandlerClass.unplug_request callback of @plug_handler.
index 3669ebd..2cb69d5 100644 (file)
@@ -2,17 +2,40 @@
 #ifndef QEMU_HW_H
 #define QEMU_HW_H
 
-#ifdef CONFIG_USER_ONLY
-#error Cannot include hw/hw.h from user emulation
-#endif
 
+#if !defined(CONFIG_USER_ONLY) && !defined(NEED_CPU_H)
 #include "exec/cpu-common.h"
-#include "qom/object.h"
-#include "exec/memory.h"
+#endif
+
+#include "exec/ioport.h"
 #include "hw/irq.h"
+#include "block/aio.h"
 #include "migration/vmstate.h"
+#include "qemu/log.h"
 #include "qemu/module.h"
 
+#ifdef NEED_CPU_H
+#if TARGET_LONG_BITS == 64
+#define qemu_put_betl qemu_put_be64
+#define qemu_get_betl qemu_get_be64
+#define qemu_put_betls qemu_put_be64s
+#define qemu_get_betls qemu_get_be64s
+#define qemu_put_sbetl qemu_put_sbe64
+#define qemu_get_sbetl qemu_get_sbe64
+#define qemu_put_sbetls qemu_put_sbe64s
+#define qemu_get_sbetls qemu_get_sbe64s
+#else
+#define qemu_put_betl qemu_put_be32
+#define qemu_get_betl qemu_get_be32
+#define qemu_put_betls qemu_put_be32s
+#define qemu_get_betls qemu_get_be32s
+#define qemu_put_sbetl qemu_put_sbe32
+#define qemu_get_sbetl qemu_get_sbe32
+#define qemu_put_sbetls qemu_put_sbe32s
+#define qemu_get_sbetls qemu_get_sbe32s
+#endif
+#endif
+
 typedef void QEMUResetHandler(void *opaque);
 
 void qemu_register_reset(QEMUResetHandler *func, void *opaque);
@@ -20,4 +43,31 @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
 
 void QEMU_NORETURN hw_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
 
+#ifdef NEED_CPU_H
+#if TARGET_LONG_BITS == 64
+#define VMSTATE_UINTTL_V(_f, _s, _v)                                  \
+    VMSTATE_UINT64_V(_f, _s, _v)
+#define VMSTATE_UINTTL_EQUAL_V(_f, _s, _v)                            \
+    VMSTATE_UINT64_EQUAL_V(_f, _s, _v)
+#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v)                        \
+    VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v)
+#define vmstate_info_uinttl vmstate_info_uint64
+#else
+#define VMSTATE_UINTTL_V(_f, _s, _v)                                  \
+    VMSTATE_UINT32_V(_f, _s, _v)
+#define VMSTATE_UINTTL_EQUAL_V(_f, _s, _v)                            \
+    VMSTATE_UINT32_EQUAL_V(_f, _s, _v)
+#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v)                        \
+    VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v)
+#define vmstate_info_uinttl vmstate_info_uint32
+#endif
+#define VMSTATE_UINTTL(_f, _s)                                        \
+    VMSTATE_UINTTL_V(_f, _s, 0)
+#define VMSTATE_UINTTL_EQUAL(_f, _s)                                  \
+    VMSTATE_UINTTL_EQUAL_V(_f, _s, 0)
+#define VMSTATE_UINTTL_ARRAY(_f, _s, _n)                              \
+    VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, 0)
+
+#endif
+
 #endif
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
deleted file mode 100644 (file)
index f9020ac..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  ASPEED AST2400 I2C Controller
- *
- *  Copyright (C) 2016 IBM Corp.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef ASPEED_I2C_H
-#define ASPEED_I2C_H
-
-#include "hw/i2c/i2c.h"
-
-#define TYPE_ASPEED_I2C "aspeed.i2c"
-#define ASPEED_I2C(obj) \
-    OBJECT_CHECK(AspeedI2CState, (obj), TYPE_ASPEED_I2C)
-
-#define ASPEED_I2C_NR_BUSSES 14
-
-struct AspeedI2CState;
-
-typedef struct AspeedI2CBus {
-    struct AspeedI2CState *controller;
-
-    MemoryRegion mr;
-
-    I2CBus *bus;
-    uint8_t id;
-
-    uint32_t ctrl;
-    uint32_t timing[2];
-    uint32_t intr_ctrl;
-    uint32_t intr_status;
-    uint32_t cmd;
-    uint32_t buf;
-} AspeedI2CBus;
-
-typedef struct AspeedI2CState {
-    SysBusDevice parent_obj;
-
-    MemoryRegion iomem;
-    qemu_irq irq;
-
-    uint32_t intr_status;
-
-    AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
-} AspeedI2CState;
-
-I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
-
-#endif /* ASPEED_I2C_H */
diff --git a/include/hw/i2c/i2c-ddc.h b/include/hw/i2c/i2c-ddc.h
deleted file mode 100644 (file)
index d9b5f33..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* A simple I2C slave for returning monitor EDID data via DDC.
- *
- * Copyright (c) 2011 Linaro Limited
- * Written by Peter Maydell
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef I2C_DDC_H
-#define I2C_DDC_H
-
-/* A simple I2C slave which just returns the contents of its EDID blob. */
-
-struct I2CDDCState {
-    /*< private >*/
-    I2CSlave i2c;
-    /*< public >*/
-    bool firstbyte;
-    uint8_t reg;
-    uint8_t edid_blob[128];
-};
-
-typedef struct I2CDDCState I2CDDCState;
-
-#define TYPE_I2CDDC "i2c-ddc"
-#define I2CDDC(obj) OBJECT_CHECK(I2CDDCState, (obj), TYPE_I2CDDC)
-
-#endif /* I2C_DDC_H */
index c4085aa..4986ebc 100644 (file)
@@ -56,7 +56,6 @@ int i2c_bus_busy(I2CBus *bus);
 int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv);
 void i2c_end_transfer(I2CBus *bus);
 void i2c_nack(I2CBus *bus);
-int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send);
 int i2c_send(I2CBus *bus, uint8_t data);
 int i2c_recv(I2CBus *bus);
 
index 7c73a1f..e2ee8ea 100644 (file)
  *
  */
 
-#ifndef IMX_I2C_H
-#define IMX_I2C_H
+#ifndef __IMX_I2C_H_
+#define __IMX_I2C_H_
 
-#include "hw/sysbus.h"
+#include <hw/sysbus.h>
 
 #define TYPE_IMX_I2C "imx.i2c"
 #define IMX_I2C(obj) OBJECT_CHECK(IMXI2CState, (obj), TYPE_IMX_I2C)
@@ -84,4 +84,4 @@ typedef struct IMXI2CState {
     uint16_t i2dr_write;
 } IMXI2CState;
 
-#endif /* IMX_I2C_H */
+#endif /* __IMX_I2C_H_ */
index 2a837af..926603f 100644 (file)
@@ -17,4 +17,4 @@ typedef struct PMSMBus {
 
 void pm_smbus_init(DeviceState *parent, PMSMBus *smb);
 
-#endif /* PM_SMBUS_H */
+#endif /* !PM_SMBUS_H */
index 8b4d4cc..6e2eb71 100644 (file)
@@ -25,7 +25,6 @@
 #define MSI_ADDR_REDIRECTION_SHIFT      3
 
 #define MSI_ADDR_DEST_ID_SHIFT          12
-#define MSI_ADDR_DEST_IDX_SHIFT         4
 #define  MSI_ADDR_DEST_ID_MASK          0x00ffff0
 
 #endif /* HW_APIC_MSIDEF_H */
index ea48ea9..51eb6d3 100644 (file)
@@ -18,10 +18,15 @@ void cpu_set_apic_tpr(DeviceState *s, uint8_t val);
 uint8_t cpu_get_apic_tpr(DeviceState *s);
 void apic_init_reset(DeviceState *s);
 void apic_sipi(DeviceState *s);
+void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
+                                   TPRAccess access);
 void apic_poll_irq(DeviceState *d);
 void apic_designate_bsp(DeviceState *d, bool bsp);
 
 /* pc.c */
 DeviceState *cpu_get_current_apic(void);
 
+/* cpu.c */
+bool cpu_is_bsp(X86CPU *cpu);
+
 #endif
index 06c4e9f..74fe935 100644 (file)
@@ -17,7 +17,6 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>
  */
-
 #ifndef QEMU_APIC_INTERNAL_H
 #define QEMU_APIC_INTERNAL_H
 
 #define VAPIC_ENABLE_BIT                0
 #define VAPIC_ENABLE_MASK               (1 << VAPIC_ENABLE_BIT)
 
+#define MAX_APICS 255
+
 typedef struct APICCommonState APICCommonState;
 
 #define TYPE_APIC_COMMON "apic-common"
@@ -136,7 +137,6 @@ typedef struct APICCommonClass
     DeviceClass parent_class;
 
     DeviceRealize realize;
-    DeviceUnrealize unrealize;
     void (*set_base)(APICCommonState *s, uint64_t val);
     void (*set_tpr)(APICCommonState *s, uint8_t val);
     uint8_t (*get_tpr)(APICCommonState *s);
@@ -175,6 +175,7 @@ struct APICCommonState {
     uint32_t initial_count;
     int64_t initial_count_load_time;
     int64_t next_time;
+    int idx;
     QEMUTimer *timer;
     int64_t timer_expiry;
     int sipi_vector;
@@ -183,7 +184,6 @@ struct APICCommonState {
     uint32_t vapic_control;
     DeviceState *vapic;
     hwaddr vapic_paddr; /* note: persistence via kvmvapic */
-    bool legacy_instance_id;
 };
 
 typedef struct VAPICState {
@@ -222,4 +222,4 @@ static inline int apic_get_bit(uint32_t *tab, int index)
     return !!(tab[i] & mask);
 }
 
-#endif /* QEMU_APIC_INTERNAL_H */
+#endif /* !QEMU_APIC_INTERNAL_H */
index 5fd7e97..d04dcdc 100644 (file)
@@ -35,7 +35,7 @@ typedef struct ICH9LPCState {
 
     /* (pci device, intx) -> pirq
      * In real chipset case, the unused slots are never used
-     * as ICH9 supports only D25-D31 irq routing.
+     * as ICH9 supports only D25-D32 irq routing.
      * On the other hand in qemu case, any slot/function can be populated
      * via command line option.
      * So fallback interrupt routing for any devices in any slots is necessary.
@@ -45,7 +45,6 @@ typedef struct ICH9LPCState {
     APMState apm;
     ICH9LPCPMRegs pm;
     uint32_t sci_level; /* track sci level */
-    uint8_t sci_gsi;
 
     /* 2.24 Pin Straps */
     struct {
@@ -69,7 +68,8 @@ typedef struct ICH9LPCState {
     MemoryRegion rcrb_mem; /* root complex register block */
     Notifier machine_ready;
 
-    qemu_irq gsi[GSI_NUM_PINS];
+    qemu_irq *pic;
+    qemu_irq *ioapic;
 } ICH9LPCState;
 
 Object *ich9_lpc_find(void);
@@ -177,13 +177,11 @@ Object *ich9_lpc_find(void);
 #define ICH9_LPC_PIC_NUM_PINS                   16
 #define ICH9_LPC_IOAPIC_NUM_PINS                24
 
-#define ICH9_GPIO_GSI "gsi"
-
 /* D31:F2 SATA Controller #1 */
 #define ICH9_SATA1_DEV                          31
 #define ICH9_SATA1_FUNC                         2
 
-/* D31:F0 power management I/O registers
+/* D30:F1 power management I/O registers
    offset from the address ICH9_LPC_PMBASE */
 
 /* ICH9 LPC PM I/O registers are 128 ports and 128-aligned */
@@ -210,8 +208,6 @@ Object *ich9_lpc_find(void);
 
 
 /* D31:F3 SMBus controller */
-#define TYPE_ICH9_SMB_DEVICE "ICH9 SMB"
-
 #define ICH9_A2_SMB_REVISION                    0x02
 #define ICH9_SMB_PI                             0x00
 
index a42dbd7..b024ffa 100644 (file)
 #define INTEL_IOMMU_H
 #include "hw/qdev.h"
 #include "sysemu/dma.h"
-#include "hw/i386/x86-iommu.h"
-#include "hw/i386/ioapic.h"
-#include "hw/pci/msi.h"
-#include "hw/sysbus.h"
 
 #define TYPE_INTEL_IOMMU_DEVICE "intel-iommu"
 #define INTEL_IOMMU_DEVICE(obj) \
@@ -38,6 +34,7 @@
 #define VTD_PCI_BUS_MAX             256
 #define VTD_PCI_SLOT_MAX            32
 #define VTD_PCI_FUNC_MAX            8
+#define VTD_PCI_DEVFN_MAX           256
 #define VTD_PCI_SLOT(devfn)         (((devfn) >> 3) & 0x1f)
 #define VTD_PCI_FUNC(devfn)         ((devfn) & 0x07)
 #define VTD_SID_TO_BUS(sid)         (((sid) >> 8) & 0xff)
 #define VTD_HOST_ADDRESS_WIDTH      39
 #define VTD_HAW_MASK                ((1ULL << VTD_HOST_ADDRESS_WIDTH) - 1)
 
-#define DMAR_REPORT_F_INTR          (1)
-
-#define  VTD_MSI_ADDR_HI_MASK        (0xffffffff00000000ULL)
-#define  VTD_MSI_ADDR_HI_SHIFT       (32)
-#define  VTD_MSI_ADDR_LO_MASK        (0x00000000ffffffffULL)
-
 typedef struct VTDContextEntry VTDContextEntry;
 typedef struct VTDContextCacheEntry VTDContextCacheEntry;
 typedef struct IntelIOMMUState IntelIOMMUState;
 typedef struct VTDAddressSpace VTDAddressSpace;
 typedef struct VTDIOTLBEntry VTDIOTLBEntry;
 typedef struct VTDBus VTDBus;
-typedef union VTD_IR_TableEntry VTD_IR_TableEntry;
-typedef union VTD_IR_MSIAddress VTD_IR_MSIAddress;
-typedef struct VTDIrq VTDIrq;
-typedef struct VTD_MSIMessage VTD_MSIMessage;
 
 /* Context-Entry */
 struct VTDContextEntry {
@@ -83,7 +70,6 @@ struct VTDAddressSpace {
     uint8_t devfn;
     AddressSpace as;
     MemoryRegion iommu;
-    MemoryRegion iommu_ir;      /* Interrupt region: 0xfeeXXXXX */
     IntelIOMMUState *iommu_state;
     VTDContextCacheEntry context_cache_entry;
 };
@@ -102,155 +88,9 @@ struct VTDIOTLBEntry {
     bool write_flags;
 };
 
-/* VT-d Source-ID Qualifier types */
-enum {
-    VTD_SQ_FULL = 0x00,     /* Full SID verification */
-    VTD_SQ_IGN_3 = 0x01,    /* Ignore bit 3 */
-    VTD_SQ_IGN_2_3 = 0x02,  /* Ignore bits 2 & 3 */
-    VTD_SQ_IGN_1_3 = 0x03,  /* Ignore bits 1-3 */
-    VTD_SQ_MAX,
-};
-
-/* VT-d Source Validation Types */
-enum {
-    VTD_SVT_NONE = 0x00,    /* No validation */
-    VTD_SVT_ALL = 0x01,     /* Do full validation */
-    VTD_SVT_BUS = 0x02,     /* Validate bus range */
-    VTD_SVT_MAX,
-};
-
-/* Interrupt Remapping Table Entry Definition */
-union VTD_IR_TableEntry {
-    struct {
-#ifdef HOST_WORDS_BIGENDIAN
-        uint32_t dest_id:32;         /* Destination ID */
-        uint32_t __reserved_1:8;     /* Reserved 1 */
-        uint32_t vector:8;           /* Interrupt Vector */
-        uint32_t irte_mode:1;        /* IRTE Mode */
-        uint32_t __reserved_0:3;     /* Reserved 0 */
-        uint32_t __avail:4;          /* Available spaces for software */
-        uint32_t delivery_mode:3;    /* Delivery Mode */
-        uint32_t trigger_mode:1;     /* Trigger Mode */
-        uint32_t redir_hint:1;       /* Redirection Hint */
-        uint32_t dest_mode:1;        /* Destination Mode */
-        uint32_t fault_disable:1;    /* Fault Processing Disable */
-        uint32_t present:1;          /* Whether entry present/available */
-#else
-        uint32_t present:1;          /* Whether entry present/available */
-        uint32_t fault_disable:1;    /* Fault Processing Disable */
-        uint32_t dest_mode:1;        /* Destination Mode */
-        uint32_t redir_hint:1;       /* Redirection Hint */
-        uint32_t trigger_mode:1;     /* Trigger Mode */
-        uint32_t delivery_mode:3;    /* Delivery Mode */
-        uint32_t __avail:4;          /* Available spaces for software */
-        uint32_t __reserved_0:3;     /* Reserved 0 */
-        uint32_t irte_mode:1;        /* IRTE Mode */
-        uint32_t vector:8;           /* Interrupt Vector */
-        uint32_t __reserved_1:8;     /* Reserved 1 */
-        uint32_t dest_id:32;         /* Destination ID */
-#endif
-        uint16_t source_id:16;       /* Source-ID */
-#ifdef HOST_WORDS_BIGENDIAN
-        uint64_t __reserved_2:44;    /* Reserved 2 */
-        uint64_t sid_vtype:2;        /* Source-ID Validation Type */
-        uint64_t sid_q:2;            /* Source-ID Qualifier */
-#else
-        uint64_t sid_q:2;            /* Source-ID Qualifier */
-        uint64_t sid_vtype:2;        /* Source-ID Validation Type */
-        uint64_t __reserved_2:44;    /* Reserved 2 */
-#endif
-    } QEMU_PACKED irte;
-    uint64_t data[2];
-};
-
-#define VTD_IR_INT_FORMAT_COMPAT     (0) /* Compatible Interrupt */
-#define VTD_IR_INT_FORMAT_REMAP      (1) /* Remappable Interrupt */
-
-/* Programming format for MSI/MSI-X addresses */
-union VTD_IR_MSIAddress {
-    struct {
-#ifdef HOST_WORDS_BIGENDIAN
-        uint32_t __head:12;          /* Should always be: 0x0fee */
-        uint32_t index_l:15;         /* Interrupt index bit 14-0 */
-        uint32_t int_mode:1;         /* Interrupt format */
-        uint32_t sub_valid:1;        /* SHV: Sub-Handle Valid bit */
-        uint32_t index_h:1;          /* Interrupt index bit 15 */
-        uint32_t __not_care:2;
-#else
-        uint32_t __not_care:2;
-        uint32_t index_h:1;          /* Interrupt index bit 15 */
-        uint32_t sub_valid:1;        /* SHV: Sub-Handle Valid bit */
-        uint32_t int_mode:1;         /* Interrupt format */
-        uint32_t index_l:15;         /* Interrupt index bit 14-0 */
-        uint32_t __head:12;          /* Should always be: 0x0fee */
-#endif
-    } QEMU_PACKED addr;
-    uint32_t data;
-};
-
-/* Generic IRQ entry information */
-struct VTDIrq {
-    /* Used by both IOAPIC/MSI interrupt remapping */
-    uint8_t trigger_mode;
-    uint8_t vector;
-    uint8_t delivery_mode;
-    uint32_t dest;
-    uint8_t dest_mode;
-
-    /* only used by MSI interrupt remapping */
-    uint8_t redir_hint;
-    uint8_t msi_addr_last_bits;
-};
-
-struct VTD_MSIMessage {
-    union {
-        struct {
-#ifdef HOST_WORDS_BIGENDIAN
-            uint32_t __addr_head:12; /* 0xfee */
-            uint32_t dest:8;
-            uint32_t __reserved:8;
-            uint32_t redir_hint:1;
-            uint32_t dest_mode:1;
-            uint32_t __not_used:2;
-#else
-            uint32_t __not_used:2;
-            uint32_t dest_mode:1;
-            uint32_t redir_hint:1;
-            uint32_t __reserved:8;
-            uint32_t dest:8;
-            uint32_t __addr_head:12; /* 0xfee */
-#endif
-            uint32_t __addr_hi:32;
-        } QEMU_PACKED;
-        uint64_t msi_addr;
-    };
-    union {
-        struct {
-#ifdef HOST_WORDS_BIGENDIAN
-            uint16_t trigger_mode:1;
-            uint16_t level:1;
-            uint16_t __resved:3;
-            uint16_t delivery_mode:3;
-            uint16_t vector:8;
-#else
-            uint16_t vector:8;
-            uint16_t delivery_mode:3;
-            uint16_t __resved:3;
-            uint16_t level:1;
-            uint16_t trigger_mode:1;
-#endif
-            uint16_t __resved1:16;
-        } QEMU_PACKED;
-        uint32_t msi_data;
-    };
-};
-
-/* When IR is enabled, all MSI/MSI-X data bits should be zero */
-#define VTD_IR_MSI_DATA          (0)
-
 /* The iommu (DMAR) device state struct */
 struct IntelIOMMUState {
-    X86IOMMUState x86_iommu;
+    SysBusDevice busdev;
     MemoryRegion csrmem;
     uint8_t csr[DMAR_REG_SIZE];     /* register values */
     uint8_t wmask[DMAR_REG_SIZE];   /* R/W bytes */
@@ -283,12 +123,6 @@ struct IntelIOMMUState {
     MemoryRegionIOMMUOps iommu_ops;
     GHashTable *vtd_as_by_busptr;   /* VTDBus objects indexed by PCIBus* reference */
     VTDBus *vtd_as_by_bus_num[VTD_PCI_BUS_MAX]; /* VTDBus objects indexed by bus number */
-
-    /* interrupt remapping */
-    bool intr_enabled;              /* Whether guest enabled IR */
-    dma_addr_t intr_root;           /* Interrupt remapping table pointer */
-    uint32_t intr_size;             /* Number of IR table entries */
-    bool intr_eime;                 /* Extended interrupt mode enabled */
 };
 
 /* Find the VTD Address space associated with the given bus pointer,
index 9c8816f..6245388 100644 (file)
@@ -25,4 +25,4 @@
 
 void ioapic_eoi_broadcast(int vector);
 
-#endif /* HW_IOAPIC_H */
+#endif /* !HW_IOAPIC_H */
index a11d86d..797ed47 100644 (file)
 #include "hw/hw.h"
 #include "exec/memory.h"
 #include "hw/sysbus.h"
-#include "qemu/notify.h"
 
 #define MAX_IOAPICS                     1
 
+#define IOAPIC_VERSION                  0x11
+
 #define IOAPIC_LVT_DEST_SHIFT           56
-#define IOAPIC_LVT_DEST_IDX_SHIFT       48
 #define IOAPIC_LVT_MASKED_SHIFT         16
 #define IOAPIC_LVT_TRIGGER_MODE_SHIFT   15
 #define IOAPIC_LVT_REMOTE_IRR_SHIFT     14
 #define IOAPIC_LVT_DEST_MODE            (1 << IOAPIC_LVT_DEST_MODE_SHIFT)
 #define IOAPIC_LVT_DELIV_MODE           (7 << IOAPIC_LVT_DELIV_MODE_SHIFT)
 
-/* Bits that are read-only for IOAPIC entry */
-#define IOAPIC_RO_BITS                  (IOAPIC_LVT_REMOTE_IRR | \
-                                         IOAPIC_LVT_DELIV_STATUS)
-#define IOAPIC_RW_BITS                  (~(uint64_t)IOAPIC_RO_BITS)
-
 #define IOAPIC_TRIGGER_EDGE             0
 #define IOAPIC_TRIGGER_LEVEL            1
 
@@ -69,7 +64,6 @@
 
 #define IOAPIC_IOREGSEL                 0x00
 #define IOAPIC_IOWIN                    0x10
-#define IOAPIC_EOI                      0x40
 
 #define IOAPIC_REG_ID                   0x00
 #define IOAPIC_REG_VER                  0x01
@@ -107,12 +101,10 @@ struct IOAPICCommonState {
     uint8_t ioregsel;
     uint32_t irr;
     uint64_t ioredtbl[IOAPIC_NUM_PINS];
-    Notifier machine_done;
-    uint8_t version;
 };
 
 void ioapic_reset_common(DeviceState *dev);
 
 void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s);
 
-#endif /* QEMU_IOAPIC_INTERNAL_H */
+#endif /* !QEMU_IOAPIC_INTERNAL_H */
index 74c175c..96f0b66 100644 (file)
@@ -17,7 +17,6 @@
 #include "hw/compat.h"
 #include "hw/mem/pc-dimm.h"
 #include "hw/mem/nvdimm.h"
-#include "hw/acpi/acpi_dev_interface.h"
 
 #define HPET_INTCAP "hpet-intcap"
 
@@ -72,10 +71,7 @@ struct PCMachineState {
     /* NUMA information: */
     uint64_t numa_nodes;
     uint64_t *node_mem;
-
-    /* Address space used by IOAPIC device. All IOAPIC interrupts
-     * will be translated to MSI messages in the address space. */
-    AddressSpace *ioapic_as;
+    uint64_t *node_cpu;
 };
 
 #define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device"
@@ -140,8 +136,6 @@ struct PCMachineClass {
 
     /* TSC rate migration: */
     bool save_tsc_khz;
-    /* generate legacy CPU hotplug AML */
-    bool legacy_cpu_hotplug;
 };
 
 #define TYPE_PC_MACHINE "generic-pc-machine"
@@ -154,6 +148,11 @@ struct PCMachineClass {
 
 /* PC-style peripherals (also used by other machines).  */
 
+typedef struct PcPciInfo {
+    Range w32;
+    Range w64;
+} PcPciInfo;
+
 #define ACPI_PM_PROP_S3_DISABLED "disable_s3"
 #define ACPI_PM_PROP_S4_DISABLED "disable_s4"
 #define ACPI_PM_PROP_S4_VAL "s4_val"
@@ -200,12 +199,11 @@ typedef struct GSIState {
 void gsi_handler(void *opaque, int n, int level);
 
 /* vmport.c */
-#define TYPE_VMPORT "vmport"
 typedef uint32_t (VMPortReadFunc)(void *opaque, uint32_t address);
 
 static inline void vmport_init(ISABus *bus)
 {
-    isa_create_simple(bus, TYPE_VMPORT);
+    isa_create_simple(bus, "vmport");
 }
 
 void vmport_register(unsigned char command, VMPortReadFunc *func, void *opaque);
@@ -213,7 +211,6 @@ void vmmouse_get_data(uint32_t *data);
 void vmmouse_set_data(const uint32_t *data);
 
 /* pckbd.c */
-#define I8042_A20_LINE "a20"
 
 void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base);
 void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
@@ -240,8 +237,6 @@ void pc_guest_info_init(PCMachineState *pcms);
 #define PCI_HOST_PROP_PCI_HOLE64_START "pci-hole64-start"
 #define PCI_HOST_PROP_PCI_HOLE64_END   "pci-hole64-end"
 #define PCI_HOST_PROP_PCI_HOLE64_SIZE  "pci-hole64-size"
-#define PCI_HOST_BELOW_4G_MEM_SIZE     "below-4g-mem-size"
-#define PCI_HOST_ABOVE_4G_MEM_SIZE     "above-4g-mem-size"
 #define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL)
 
 
@@ -276,8 +271,6 @@ int cmos_get_fd_drive_type(FloppyDriveType fd0);
 
 #define FW_CFG_IO_BASE     0x510
 
-#define PORT92_A20_LINE "a20"
-
 /* acpi_piix.c */
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
@@ -352,10 +345,6 @@ void pc_system_firmware_init(MemoryRegion *rom_memory,
 /* pvpanic.c */
 uint16_t pvpanic_port(void);
 
-/* acpi-build.c */
-void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
-                       CPUArchIdList *apic_ids, GArray *entry);
-
 /* e820 types */
 #define E820_RAM        1
 #define E820_RESERVED   2
@@ -367,59 +356,12 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
 int e820_get_num_entries(void);
 bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
 
-#define PC_COMPAT_2_6 \
-    HW_COMPAT_2_6 \
-    {\
-        .driver   = "fw_cfg_io",\
-        .property = "dma_enabled",\
-        .value    = "off",\
-    },{\
-        .driver   = TYPE_X86_CPU,\
-        .property = "cpuid-0xb",\
-        .value    = "off",\
-    },{\
-        .driver   = "vmxnet3",\
-        .property = "romfile",\
-        .value    = "",\
-    },\
-    {\
-        .driver = TYPE_X86_CPU,\
-        .property = "fill-mtrr-mask",\
-        .value = "off",\
-    },\
-    {\
-        .driver   = "apic-common",\
-        .property = "legacy-instance-id",\
-        .value    = "on",\
-    },
-
 #define PC_COMPAT_2_5 \
-    PC_COMPAT_2_6 \
     HW_COMPAT_2_5
 
-/* Helper for setting model-id for CPU models that changed model-id
- * depending on QEMU versions up to QEMU 2.4.
- */
-#define PC_CPU_MODEL_IDS(v) \
-    {\
-        .driver   = "qemu32-" TYPE_X86_CPU,\
-        .property = "model-id",\
-        .value    = "QEMU Virtual CPU version " v,\
-    },\
-    {\
-        .driver   = "qemu64-" TYPE_X86_CPU,\
-        .property = "model-id",\
-        .value    = "QEMU Virtual CPU version " v,\
-    },\
-    {\
-        .driver   = "athlon-" TYPE_X86_CPU,\
-        .property = "model-id",\
-        .value    = "QEMU Virtual CPU version " v,\
-    },
-
 #define PC_COMPAT_2_4 \
+    PC_COMPAT_2_5 \
     HW_COMPAT_2_4 \
-    PC_CPU_MODEL_IDS("2.4.0") \
     {\
         .driver   = "Haswell-" TYPE_X86_CPU,\
         .property = "abm",\
@@ -489,8 +431,8 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
 
 
 #define PC_COMPAT_2_3 \
+    PC_COMPAT_2_4 \
     HW_COMPAT_2_3 \
-    PC_CPU_MODEL_IDS("2.3.0") \
     {\
         .driver   = TYPE_X86_CPU,\
         .property = "arat",\
@@ -570,8 +512,8 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_2_2 \
+    PC_COMPAT_2_3 \
     HW_COMPAT_2_2 \
-    PC_CPU_MODEL_IDS("2.3.0") \
     {\
         .driver = "kvm64" "-" TYPE_X86_CPU,\
         .property = "vme",\
@@ -664,8 +606,8 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_2_1 \
+    PC_COMPAT_2_2 \
     HW_COMPAT_2_1 \
-    PC_CPU_MODEL_IDS("2.1.0") \
     {\
         .driver = "coreduo" "-" TYPE_X86_CPU,\
         .property = "vmx",\
@@ -678,7 +620,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_2_0 \
-    PC_CPU_MODEL_IDS("2.0.0") \
+    PC_COMPAT_2_1 \
     {\
         .driver   = "virtio-scsi-pci",\
         .property = "any_layout",\
@@ -738,7 +680,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_1_7 \
-    PC_CPU_MODEL_IDS("1.7.0") \
+    PC_COMPAT_2_0 \
     {\
         .driver   = TYPE_USB_DEVICE,\
         .property = "msos-desc",\
@@ -756,7 +698,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_1_6 \
-    PC_CPU_MODEL_IDS("1.6.0") \
+    PC_COMPAT_1_7 \
     {\
         .driver   = "e1000",\
         .property = "mitigation",\
@@ -780,7 +722,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_1_5 \
-    PC_CPU_MODEL_IDS("1.5.0") \
+    PC_COMPAT_1_6 \
     {\
         .driver   = "Conroe-" TYPE_X86_CPU,\
         .property = "model",\
@@ -824,7 +766,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_1_4 \
-    PC_CPU_MODEL_IDS("1.4.0") \
+    PC_COMPAT_1_5 \
     {\
         .driver   = "scsi-hd",\
         .property = "discard_granularity",\
index 1ebaee0..fc95572 100644 (file)
@@ -117,21 +117,6 @@ static inline void x86_topo_ids_from_idx(unsigned nr_cores,
     topo->pkg_id = core_index / nr_cores;
 }
 
-/* Calculate thread/core/package IDs for a specific topology,
- * based on APIC ID
- */
-static inline void x86_topo_ids_from_apicid(apic_id_t apicid,
-                                            unsigned nr_cores,
-                                            unsigned nr_threads,
-                                            X86CPUTopoInfo *topo)
-{
-    topo->smt_id = apicid &
-                   ~(0xFFFFFFFFUL << apicid_smt_width(nr_cores, nr_threads));
-    topo->core_id = (apicid >> apicid_core_offset(nr_cores, nr_threads)) &
-                   ~(0xFFFFFFFFUL << apicid_core_width(nr_cores, nr_threads));
-    topo->pkg_id = apicid >> apicid_pkg_offset(nr_cores, nr_threads);
-}
-
 /* Make APIC ID for the CPU 'cpu_index'
  *
  * 'cpu_index' is a sequential, contiguous ID for the CPU.
diff --git a/include/hw/i386/x86-iommu.h b/include/hw/i386/x86-iommu.h
deleted file mode 100644 (file)
index c48e8dd..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Common IOMMU interface for X86 platform
- *
- * Copyright (C) 2016 Peter Xu, Red Hat <peterx@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef IOMMU_COMMON_H
-#define IOMMU_COMMON_H
-
-#include "hw/sysbus.h"
-#include "hw/pci/pci.h"
-
-#define  TYPE_X86_IOMMU_DEVICE  ("x86-iommu")
-#define  X86_IOMMU_DEVICE(obj) \
-    OBJECT_CHECK(X86IOMMUState, (obj), TYPE_X86_IOMMU_DEVICE)
-#define  X86_IOMMU_CLASS(klass) \
-    OBJECT_CLASS_CHECK(X86IOMMUClass, (klass), TYPE_X86_IOMMU_DEVICE)
-#define  X86_IOMMU_GET_CLASS(obj) \
-    OBJECT_GET_CLASS(X86IOMMUClass, obj, TYPE_X86_IOMMU_DEVICE)
-
-#define X86_IOMMU_PCI_DEVFN_MAX           256
-#define X86_IOMMU_SID_INVALID             (0xffff)
-
-typedef struct X86IOMMUState X86IOMMUState;
-typedef struct X86IOMMUClass X86IOMMUClass;
-
-struct X86IOMMUClass {
-    SysBusDeviceClass parent;
-    /* Intel/AMD specific realize() hook */
-    DeviceRealize realize;
-    /* MSI-based interrupt remapping */
-    int (*int_remap)(X86IOMMUState *iommu, MSIMessage *src,
-                     MSIMessage *dst, uint16_t sid);
-};
-
-/**
- * iec_notify_fn - IEC (Interrupt Entry Cache) notifier hook,
- *                 triggered when IR invalidation happens.
- * @private: private data
- * @global: whether this is a global IEC invalidation
- * @index: IRTE index to invalidate (start from)
- * @mask: invalidation mask
- */
-typedef void (*iec_notify_fn)(void *private, bool global,
-                              uint32_t index, uint32_t mask);
-
-struct IEC_Notifier {
-    iec_notify_fn iec_notify;
-    void *private;
-    QLIST_ENTRY(IEC_Notifier) list;
-};
-typedef struct IEC_Notifier IEC_Notifier;
-
-struct X86IOMMUState {
-    SysBusDevice busdev;
-    bool intr_supported;        /* Whether vIOMMU supports IR */
-    QLIST_HEAD(, IEC_Notifier) iec_notifiers; /* IEC notify list */
-};
-
-/**
- * x86_iommu_get_default - get default IOMMU device
- * @return: pointer to default IOMMU device
- */
-X86IOMMUState *x86_iommu_get_default(void);
-
-/**
- * x86_iommu_iec_register_notifier - register IEC (Interrupt Entry
- *                                   Cache) notifiers
- * @iommu: IOMMU device to register
- * @fn: IEC notifier hook function
- * @data: notifier private data
- */
-void x86_iommu_iec_register_notifier(X86IOMMUState *iommu,
-                                     iec_notify_fn fn, void *data);
-
-/**
- * x86_iommu_iec_notify_all - Notify IEC invalidations
- * @iommu: IOMMU device that sends the notification
- * @global: whether this is a global invalidation. If true, @index
- *          and @mask are undefined.
- * @index: starting index of interrupt entry to invalidate
- * @mask: index mask for the invalidation
- */
-void x86_iommu_iec_notify_all(X86IOMMUState *iommu, bool global,
-                              uint32_t index, uint32_t mask);
-
-#endif
index 3ae8445..db51d03 100644 (file)
@@ -23,8 +23,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef ADB_H
-#define ADB_H
+#if !defined(__ADB_H__)
+#define __ADB_H__
 
 #include "hw/qdev.h"
 
@@ -84,4 +84,4 @@ int adb_poll(ADBBusState *s, uint8_t *buf_out, uint16_t poll_mask);
 #define TYPE_ADB_KEYBOARD "adb-keyboard"
 #define TYPE_ADB_MOUSE "adb-mouse"
 
-#endif /* ADB_H */
+#endif /* !defined(__ADB_H__) */
index b9ceee4..7c45ce7 100644 (file)
@@ -35,4 +35,4 @@ void ps2_queue(void *, int b);
 void ps2_keyboard_set_translation(void *opaque, int mode);
 void ps2_mouse_fake_event(void *opaque);
 
-#endif /* HW_PS2_H */
+#endif /* !HW_PS2_H */
index 1d314a7..5721b2e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ALLWINNER_A10_PIC_H
-#define ALLWINNER_A10_PIC_H
+#ifndef AW_A10_PIC_H
+#define AW_A10_PIC_H
 
 #define TYPE_AW_A10_PIC  "allwinner-a10-pic"
 #define AW_A10_PIC(obj) OBJECT_CHECK(AwA10PICState, (obj), TYPE_AW_A10_PIC)
index 42bb535..0971e37 100644 (file)
@@ -23,9 +23,6 @@
 
 #include "arm_gic_common.h"
 
-/* Number of SGI target-list bits */
-#define GIC_TARGETLIST_BITS 8
-
 #define TYPE_ARM_GIC "arm_gic"
 #define ARM_GIC(obj) \
      OBJECT_CHECK(GICState, (obj), TYPE_ARM_GIC)
diff --git a/include/hw/intc/arm_gicv3.h b/include/hw/intc/arm_gicv3.h
deleted file mode 100644 (file)
index 4a6fd85..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * ARM Generic Interrupt Controller v3
- *
- * Copyright (c) 2015 Huawei.
- * Copyright (c) 2016 Linaro Limited
- * Written by Shlomo Pongratz, Peter Maydell
- *
- * This code is licensed under the GPL, version 2 or (at your option)
- * any later version.
- */
-
-#ifndef HW_ARM_GICV3_H
-#define HW_ARM_GICV3_H
-
-#include "arm_gicv3_common.h"
-
-#define TYPE_ARM_GICV3 "arm-gicv3"
-#define ARM_GICV3(obj) OBJECT_CHECK(GICv3State, (obj), TYPE_ARM_GICV3)
-#define ARM_GICV3_CLASS(klass) \
-     OBJECT_CLASS_CHECK(ARMGICv3Class, (klass), TYPE_ARM_GICV3)
-#define ARM_GICV3_GET_CLASS(obj) \
-     OBJECT_GET_CLASS(ARMGICv3Class, (obj), TYPE_ARM_GICV3)
-
-typedef struct ARMGICv3Class {
-    /*< private >*/
-    ARMGICv3CommonClass parent_class;
-    /*< public >*/
-
-    DeviceRealize parent_realize;
-} ARMGICv3Class;
-
-#endif
index 341a311..c2fd8da 100644 (file)
@@ -3,9 +3,8 @@
  *
  * Copyright (c) 2012 Linaro Limited
  * Copyright (c) 2015 Huawei.
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
  * Written by Peter Maydell
- * Reworked for GICv3 by Shlomo Pongratz and Pavel Fedin
+ * Extended to 64 cores by Shlomo Pongratz
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include "hw/sysbus.h"
 #include "hw/intc/arm_gic_common.h"
 
-/*
- * Maximum number of possible interrupts, determined by the GIC architecture.
- * Note that this does not include LPIs. When implemented, these should be
- * dealt with separately.
- */
-#define GICV3_MAXIRQ 1020
-#define GICV3_MAXSPI (GICV3_MAXIRQ - GIC_INTERNAL)
-
-/* Number of SGI target-list bits */
-#define GICV3_TARGETLIST_BITS 16
-
-/* Minimum BPR for Secure, or when security not enabled */
-#define GIC_MIN_BPR 0
-/* Minimum BPR for Nonsecure when security is enabled */
-#define GIC_MIN_BPR_NS (GIC_MIN_BPR + 1)
-
-/* For some distributor fields we want to model the array of 32-bit
- * register values which hold various bitmaps corresponding to enabled,
- * pending, etc bits. These macros and functions facilitate that; the
- * APIs are generally modelled on the generic bitmap.h functions
- * (which are unsuitable here because they use 'unsigned long' as the
- * underlying storage type, which is very awkward when you need to
- * access the data as 32-bit values.)
- * Each bitmap contains a bit for each interrupt. Although there is
- * space for the PPIs and SGIs, those bits (the first 32) are never
- * used as that state lives in the redistributor. The unused bits are
- * provided purely so that interrupt X's state is always in bit X; this
- * avoids bugs where we forget to subtract GIC_INTERNAL from an
- * interrupt number.
- */
-#define GICV3_BMP_SIZE (DIV_ROUND_UP(GICV3_MAXIRQ, 32))
-
-#define GIC_DECLARE_BITMAP(name) \
-    uint32_t name[GICV3_BMP_SIZE]
-
-#define GIC_BIT_MASK(nr) (1U << ((nr) % 32))
-#define GIC_BIT_WORD(nr) ((nr) / 32)
-
-static inline void gic_bmp_set_bit(int nr, uint32_t *addr)
-{
-    uint32_t mask = GIC_BIT_MASK(nr);
-    uint32_t *p = addr + GIC_BIT_WORD(nr);
-
-    *p |= mask;
-}
-
-static inline void gic_bmp_clear_bit(int nr, uint32_t *addr)
-{
-    uint32_t mask = GIC_BIT_MASK(nr);
-    uint32_t *p = addr + GIC_BIT_WORD(nr);
-
-    *p &= ~mask;
-}
-
-static inline int gic_bmp_test_bit(int nr, const uint32_t *addr)
-{
-    return 1U & (addr[GIC_BIT_WORD(nr)] >> (nr & 31));
-}
-
-static inline void gic_bmp_replace_bit(int nr, uint32_t *addr, int val)
-{
-    uint32_t mask = GIC_BIT_MASK(nr);
-    uint32_t *p = addr + GIC_BIT_WORD(nr);
-
-    *p &= ~mask;
-    *p |= (val & 1U) << (nr % 32);
-}
-
-/* Return a pointer to the 32-bit word containing the specified bit. */
-static inline uint32_t *gic_bmp_ptr32(uint32_t *addr, int nr)
-{
-    return addr + GIC_BIT_WORD(nr);
-}
-
-typedef struct GICv3State GICv3State;
-typedef struct GICv3CPUState GICv3CPUState;
-
-/* Some CPU interface registers come in three flavours:
- * Group0, Group1 (Secure) and Group1 (NonSecure)
- * (where the latter two are exposed as a single banked system register).
- * In the state struct they are implemented as a 3-element array which
- * can be indexed into by the GICV3_G0, GICV3_G1 and GICV3_G1NS constants.
- * If the CPU doesn't support EL3 then the G1 element is unused.
- *
- * These constants are also used to communicate the group to use for
- * an interrupt or SGI when it is passed between the cpu interface and
- * the redistributor or distributor. For those purposes the receiving end
- * must be prepared to cope with a Group 1 Secure interrupt even if it does
- * not have security support enabled, because security can be disabled
- * independently in the CPU and in the GIC. In that case the receiver should
- * treat an incoming Group 1 Secure interrupt as if it were Group 0.
- * (This architectural requirement is why the _G1 element is the unused one
- * in a no-EL3 CPU:  we would otherwise have to translate back and forth
- * between (G0, G1NS) from the distributor and (G0, G1) in the CPU i/f.)
- */
-#define GICV3_G0 0
-#define GICV3_G1 1
-#define GICV3_G1NS 2
-
-/* ICC_CTLR_EL1, GICD_STATUSR and GICR_STATUSR are banked but not
- * group-related, so those indices are just 0 for S and 1 for NS.
- * (If the CPU or the GIC, respectively, don't support the Security
- * extensions then the S element is unused.)
- */
-#define GICV3_S 0
-#define GICV3_NS 1
-
-typedef struct {
-    int irq;
-    uint8_t prio;
-    int grp;
-} PendingIrq;
-
-struct GICv3CPUState {
-    GICv3State *gic;
-    CPUState *cpu;
-    qemu_irq parent_irq;
-    qemu_irq parent_fiq;
-
-    /* Redistributor */
-    uint32_t level;                  /* Current IRQ level */
-    /* RD_base page registers */
-    uint32_t gicr_ctlr;
-    uint64_t gicr_typer;
-    uint32_t gicr_statusr[2];
-    uint32_t gicr_waker;
-    uint64_t gicr_propbaser;
-    uint64_t gicr_pendbaser;
-    /* SGI_base page registers */
-    uint32_t gicr_igroupr0;
-    uint32_t gicr_ienabler0;
-    uint32_t gicr_ipendr0;
-    uint32_t gicr_iactiver0;
-    uint32_t edge_trigger; /* ICFGR0 and ICFGR1 even bits */
-    uint32_t gicr_igrpmodr0;
-    uint32_t gicr_nsacr;
-    uint8_t gicr_ipriorityr[GIC_INTERNAL];
-
-    /* CPU interface */
-    uint64_t icc_ctlr_el1[2];
-    uint64_t icc_pmr_el1;
-    uint64_t icc_bpr[3];
-    uint64_t icc_apr[3][4];
-    uint64_t icc_igrpen[3];
-    uint64_t icc_ctlr_el3;
-
-    /* Current highest priority pending interrupt for this CPU.
-     * This is cached information that can be recalculated from the
-     * real state above; it doesn't need to be migrated.
-     */
-    PendingIrq hppi;
-    /* This is temporary working state, to avoid a malloc in gicv3_update() */
-    bool seenbetter;
-};
-
-struct GICv3State {
+typedef struct GICv3State {
     /*< private >*/
     SysBusDevice parent_obj;
     /*< public >*/
 
+    qemu_irq *parent_irq;
+    qemu_irq *parent_fiq;
+
     MemoryRegion iomem_dist; /* Distributor */
     MemoryRegion iomem_redist; /* Redistributors */
 
@@ -194,62 +41,9 @@ struct GICv3State {
     uint32_t num_irq;
     uint32_t revision;
     bool security_extn;
-    bool irq_reset_nonsecure;
 
     int dev_fd; /* kvm device fd if backed by kvm vgic support */
-    Error *migration_blocker;
-
-    /* Distributor */
-
-    /* for a GIC with the security extensions the NS banked version of this
-     * register is just an alias of bit 1 of the S banked version.
-     */
-    uint32_t gicd_ctlr;
-    uint32_t gicd_statusr[2];
-    GIC_DECLARE_BITMAP(group);        /* GICD_IGROUPR */
-    GIC_DECLARE_BITMAP(grpmod);       /* GICD_IGRPMODR */
-    GIC_DECLARE_BITMAP(enabled);      /* GICD_ISENABLER */
-    GIC_DECLARE_BITMAP(pending);      /* GICD_ISPENDR */
-    GIC_DECLARE_BITMAP(active);       /* GICD_ISACTIVER */
-    GIC_DECLARE_BITMAP(level);        /* Current level */
-    GIC_DECLARE_BITMAP(edge_trigger); /* GICD_ICFGR even bits */
-    uint8_t gicd_ipriority[GICV3_MAXIRQ];
-    uint64_t gicd_irouter[GICV3_MAXIRQ];
-    /* Cached information: pointer to the cpu i/f for the CPUs specified
-     * in the IROUTER registers
-     */
-    GICv3CPUState *gicd_irouter_target[GICV3_MAXIRQ];
-    uint32_t gicd_nsacr[DIV_ROUND_UP(GICV3_MAXIRQ, 16)];
-
-    GICv3CPUState *cpu;
-};
-
-#define GICV3_BITMAP_ACCESSORS(BMP)                                     \
-    static inline void gicv3_gicd_##BMP##_set(GICv3State *s, int irq)   \
-    {                                                                   \
-        gic_bmp_set_bit(irq, s->BMP);                                   \
-    }                                                                   \
-    static inline int gicv3_gicd_##BMP##_test(GICv3State *s, int irq)   \
-    {                                                                   \
-        return gic_bmp_test_bit(irq, s->BMP);                           \
-    }                                                                   \
-    static inline void gicv3_gicd_##BMP##_clear(GICv3State *s, int irq) \
-    {                                                                   \
-        gic_bmp_clear_bit(irq, s->BMP);                                 \
-    }                                                                   \
-    static inline void gicv3_gicd_##BMP##_replace(GICv3State *s,        \
-                                                  int irq, int value)   \
-    {                                                                   \
-        gic_bmp_replace_bit(irq, s->BMP, value);                        \
-    }
-
-GICV3_BITMAP_ACCESSORS(group)
-GICV3_BITMAP_ACCESSORS(grpmod)
-GICV3_BITMAP_ACCESSORS(enabled)
-GICV3_BITMAP_ACCESSORS(pending)
-GICV3_BITMAP_ACCESSORS(active)
-GICV3_BITMAP_ACCESSORS(level)
-GICV3_BITMAP_ACCESSORS(edge_trigger)
+} GICv3State;
 
 #define TYPE_ARM_GICV3_COMMON "arm-gicv3-common"
 #define ARM_GICV3_COMMON(obj) \
diff --git a/include/hw/intc/mips_gic.h b/include/hw/intc/mips_gic.h
deleted file mode 100644 (file)
index b98d500..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000, 07 MIPS Technologies, Inc.
- * Copyright (C) 2016 Imagination Technologies
- *
- */
-
-#ifndef MIPS_GIC_H
-#define MIPS_GIC_H
-
-#include "hw/timer/mips_gictimer.h"
-#include "cpu.h"
-/*
- * GIC Specific definitions
- */
-
-/* The MIPS default location */
-#define GIC_BASE_ADDR           0x1bdc0000ULL
-#define GIC_ADDRSPACE_SZ        (128 * 1024)
-
-/* Constants */
-#define GIC_POL_POS     1
-#define GIC_POL_NEG     0
-#define GIC_TRIG_EDGE   1
-#define GIC_TRIG_LEVEL  0
-
-#define MSK(n)              ((1ULL << (n)) - 1)
-
-/* GIC Address Space */
-#define SHARED_SECTION_OFS          0x0000
-#define SHARED_SECTION_SIZE         0x8000
-#define VP_LOCAL_SECTION_OFS        0x8000
-#define VP_LOCAL_SECTION_SIZE       0x4000
-#define VP_OTHER_SECTION_OFS        0xc000
-#define VP_OTHER_SECTION_SIZE       0x4000
-#define USM_VISIBLE_SECTION_OFS     0x10000
-#define USM_VISIBLE_SECTION_SIZE    0x10000
-
-/* Register Map for Shared Section */
-
-#define GIC_SH_CONFIG_OFS           0x0000
-
-/* Shared Global Counter */
-#define GIC_SH_COUNTERLO_OFS        0x0010
-#define GIC_SH_COUNTERHI_OFS        0x0014
-#define GIC_SH_REVISIONID_OFS       0x0020
-
-/* Set/Clear corresponding bit in Edge Detect Register */
-#define GIC_SH_WEDGE_OFS            0x0280
-
-/* Reset Mask - Disables Interrupt */
-#define GIC_SH_RMASK_OFS            0x0300
-#define GIC_SH_RMASK_LAST_OFS       0x031c
-
-/* Set Mask (WO) - Enables Interrupt */
-#define GIC_SH_SMASK_OFS            0x0380
-#define GIC_SH_SMASK_LAST_OFS       0x039c
-
-/* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */
-#define GIC_SH_MASK_OFS             0x0400
-#define GIC_SH_MASK_LAST_OFS        0x041c
-
-/* Pending Global Interrupts (RO) */
-#define GIC_SH_PEND_OFS             0x0480
-#define GIC_SH_PEND_LAST_OFS        0x049c
-
-#define GIC_SH_MAP0_PIN_OFS         0x0500
-#define GIC_SH_MAP255_PIN_OFS       0x08fc
-
-#define GIC_SH_MAP0_VP_OFS          0x2000
-#define GIC_SH_MAP255_VP_LAST_OFS   0x3fe4
-
-/* Register Map for Local Section */
-#define GIC_VP_CTL_OFS              0x0000
-#define GIC_VP_PEND_OFS             0x0004
-#define GIC_VP_MASK_OFS             0x0008
-#define GIC_VP_RMASK_OFS            0x000c
-#define GIC_VP_SMASK_OFS            0x0010
-#define GIC_VP_WD_MAP_OFS           0x0040
-#define GIC_VP_COMPARE_MAP_OFS      0x0044
-#define GIC_VP_TIMER_MAP_OFS        0x0048
-#define GIC_VP_FDC_MAP_OFS          0x004c
-#define GIC_VP_PERFCTR_MAP_OFS      0x0050
-#define GIC_VP_SWINT0_MAP_OFS       0x0054
-#define GIC_VP_SWINT1_MAP_OFS       0x0058
-#define GIC_VP_OTHER_ADDR_OFS       0x0080
-#define GIC_VP_IDENT_OFS            0x0088
-#define GIC_VP_WD_CONFIG0_OFS       0x0090
-#define GIC_VP_WD_COUNT0_OFS        0x0094
-#define GIC_VP_WD_INITIAL0_OFS      0x0098
-#define GIC_VP_COMPARE_LO_OFS       0x00a0
-#define GIC_VP_COMPARE_HI_OFS       0x00a4
-#define GIC_VL_BRK_GROUP            0x3080
-
-/* User-Mode Visible Section Register */
-/* Read-only alias for GIC Shared CounterLo */
-#define GIC_USER_MODE_COUNTERLO     0x0000
-/* Read-only alias for GIC Shared CounterHi */
-#define GIC_USER_MODE_COUNTERHI     0x0004
-
-/* Masks */
-#define GIC_SH_CONFIG_COUNTSTOP_SHF     28
-#define GIC_SH_CONFIG_COUNTSTOP_MSK     (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF)
-#define GIC_SH_CONFIG_COUNTBITS_SHF     24
-#define GIC_SH_CONFIG_COUNTBITS_MSK     (MSK(4) << GIC_SH_CONFIG_COUNTBITS_SHF)
-#define GIC_SH_CONFIG_NUMINTRS_SHF      16
-#define GIC_SH_CONFIG_NUMINTRS_MSK      (MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF)
-#define GIC_SH_CONFIG_PVPS_SHF          0
-#define GIC_SH_CONFIG_PVPS_MSK          (MSK(8) << GIC_SH_CONFIG_NUMVPS_SHF)
-
-#define GIC_SH_WEDGE_RW_SHF             31
-#define GIC_SH_WEDGE_RW_MSK             (MSK(1) << GIC_SH_WEDGE_RW_SHF)
-
-#define GIC_MAP_TO_PIN_SHF              31
-#define GIC_MAP_TO_PIN_MSK              (MSK(1) << GIC_MAP_TO_PIN_SHF)
-#define GIC_MAP_TO_NMI_SHF              30
-#define GIC_MAP_TO_NMI_MSK              (MSK(1) << GIC_MAP_TO_NMI_SHF)
-#define GIC_MAP_TO_YQ_SHF               29
-#define GIC_MAP_TO_YQ_MSK               (MSK(1) << GIC_MAP_TO_YQ_SHF)
-#define GIC_MAP_SHF                     0
-#define GIC_MAP_MSK                     (MSK(6) << GIC_MAP_SHF)
-#define GIC_MAP_TO_PIN_REG_MSK          \
-    (GIC_MAP_TO_PIN_MSK | GIC_MAP_TO_NMI_MSK | GIC_MAP_TO_YQ_MSK | GIC_MAP_MSK)
-
-/* GIC_VP_CTL Masks */
-#define GIC_VP_CTL_FDC_RTBL_SHF         4
-#define GIC_VP_CTL_FDC_RTBL_MSK         (MSK(1) << GIC_VP_CTL_FDC_RTBL_SHF)
-#define GIC_VP_CTL_SWINT_RTBL_SHF       3
-#define GIC_VP_CTL_SWINT_RTBL_MSK       (MSK(1) << GIC_VP_CTL_SWINT_RTBL_SHF)
-#define GIC_VP_CTL_PERFCNT_RTBL_SHF     2
-#define GIC_VP_CTL_PERFCNT_RTBL_MSK     (MSK(1) << GIC_VP_CTL_PERFCNT_RTBL_SHF)
-#define GIC_VP_CTL_TIMER_RTBL_SHF       1
-#define GIC_VP_CTL_TIMER_RTBL_MSK       (MSK(1) << GIC_VP_CTL_TIMER_RTBL_SHF)
-#define GIC_VP_CTL_EIC_MODE_SHF         0
-#define GIC_VP_CTL_EIC_MODE_MSK         (MSK(1) << GIC_VP_CTL_EIC_MODE_SHF)
-
-/* GIC_VP_MASK Masks */
-#define GIC_VP_MASK_FDC_SHF         6
-#define GIC_VP_MASK_FDC_MSK         (MSK(1) << GIC_VP_MASK_FDC_SHF)
-#define GIC_VP_MASK_SWINT1_SHF      5
-#define GIC_VP_MASK_SWINT1_MSK      (MSK(1) << GIC_VP_MASK_SWINT1_SHF)
-#define GIC_VP_MASK_SWINT0_SHF      4
-#define GIC_VP_MASK_SWINT0_MSK      (MSK(1) << GIC_VP_MASK_SWINT0_SHF)
-#define GIC_VP_MASK_PERFCNT_SHF     3
-#define GIC_VP_MASK_PERFCNT_MSK     (MSK(1) << GIC_VP_MASK_PERFCNT_SHF)
-#define GIC_VP_MASK_TIMER_SHF       2
-#define GIC_VP_MASK_TIMER_MSK       (MSK(1) << GIC_VP_MASK_TIMER_SHF)
-#define GIC_VP_MASK_CMP_SHF         1
-#define GIC_VP_MASK_CMP_MSK         (MSK(1) << GIC_VP_MASK_CMP_SHF)
-#define GIC_VP_MASK_WD_SHF          0
-#define GIC_VP_MASK_WD_MSK          (MSK(1) << GIC_VP_MASK_WD_SHF)
-#define GIC_VP_SET_RESET_MSK        (MSK(7) << GIC_VP_MASK_WD_SHF)
-
-#define GIC_CPU_INT_MAX             5 /* Core Interrupt 7 */
-#define GIC_CPU_PIN_OFFSET          2
-
-/* Local GIC interrupts. */
-#define GIC_NUM_LOCAL_INTRS     7
-#define GIC_LOCAL_INT_FDC       6 /* CPU fast debug channel */
-#define GIC_LOCAL_INT_SWINT1    5 /* CPU software interrupt 1 */
-#define GIC_LOCAL_INT_SWINT0    4 /* CPU software interrupt 0 */
-#define GIC_LOCAL_INT_PERFCTR   3 /* CPU performance counter */
-#define GIC_LOCAL_INT_TIMER     2 /* CPU timer interrupt */
-#define GIC_LOCAL_INT_COMPARE   1 /* GIC count and compare timer */
-#define GIC_LOCAL_INT_WD        0 /* GIC watchdog */
-
-#define TYPE_MIPS_GIC "mips-gic"
-#define MIPS_GIC(obj) OBJECT_CHECK(MIPSGICState, (obj), TYPE_MIPS_GIC)
-
-/* Support up to 32 VPs and 256 IRQs */
-#define GIC_MAX_VPS             32
-#define GIC_MAX_INTRS           256
-
-typedef struct MIPSGICState MIPSGICState;
-typedef struct MIPSGICIRQState MIPSGICIRQState;
-typedef struct MIPSGICVPState MIPSGICVPState;
-
-struct MIPSGICIRQState {
-    uint8_t enabled;
-    uint8_t pending;
-    uint32_t map_pin;
-    int32_t map_vp;
-    qemu_irq irq;
-};
-
-struct MIPSGICVPState {
-    uint32_t ctl;
-    uint32_t pend;
-    uint32_t mask;
-    uint32_t compare_map;
-    uint32_t other_addr;
-    CPUMIPSState *env;
-};
-
-struct MIPSGICState {
-    SysBusDevice parent_obj;
-    MemoryRegion mr;
-
-    /* Shared Section Registers */
-    uint32_t sh_config;
-    MIPSGICIRQState *irq_state;
-
-    /* VP Local/Other Section Registers */
-    MIPSGICVPState *vps;
-
-    /* GIC VP Timer */
-    MIPSGICTimerState *gic_timer;
-
-    int32_t num_vps;
-    int32_t num_irq;
-};
-
-#endif /* MIPS_GIC_H */
index e33e032..e95ffe8 100644 (file)
@@ -2,7 +2,7 @@
  * QEMU IndustryPack emulation
  *
  * Copyright (C) 2012 Igalia, S.L.
- * Author: Alberto Garcia <berto@igalia.com>
+ * Author: Alberto Garcia <agarcia@igalia.com>
  *
  * This code is licensed under the GNU GPL v2 or (at your option) any
  * later version.
index 91b83b5..74a2b5a 100644 (file)
@@ -65,40 +65,6 @@ enum ipmi_op {
 #define IPMI_SMBIOS_BT          0x03
 #define IPMI_SMBIOS_SSIF        0x04
 
-/*
- * Used for transferring information to interfaces that add
- * entries to firmware tables.
- */
-typedef struct IPMIFwInfo {
-    const char *interface_name;
-    int interface_type;
-    uint8_t ipmi_spec_major_revision;
-    uint8_t ipmi_spec_minor_revision;
-    uint8_t i2c_slave_address;
-    uint32_t uuid;
-
-    uint64_t base_address;
-    uint64_t register_length;
-    uint8_t register_spacing;
-    enum {
-        IPMI_MEMSPACE_IO,
-        IPMI_MEMSPACE_MEM32,
-        IPMI_MEMSPACE_MEM64,
-        IPMI_MEMSPACE_SMBUS
-    } memspace;
-
-    int interrupt_number;
-    enum {
-        IPMI_LEVEL_IRQ,
-        IPMI_EDGE_IRQ
-    } irq_type;
-} IPMIFwInfo;
-
-/*
- * Called by each instantiated IPMI interface device to get it's uuid.
- */
-uint32_t ipmi_next_uuid(void);
-
 /* IPMI Interface types (KCS, SMIC, BT) are prefixed with this */
 #define TYPE_IPMI_INTERFACE_PREFIX "ipmi-interface-"
 
@@ -161,11 +127,6 @@ typedef struct IPMIInterfaceClass {
      * Set by the owner to hold the backend data for the interface.
      */
     void *(*get_backend_data)(struct IPMIInterface *s);
-
-    /*
-     * Return the firmware info for a device.
-     */
-    void (*get_fwinfo)(struct IPMIInterface *s, IPMIFwInfo *info);
 } IPMIInterfaceClass;
 
 /*
@@ -207,6 +168,41 @@ typedef struct IPMIBmcClass {
  */
 void ipmi_bmc_find_and_link(Object *obj, Object **bmc);
 
+/*
+ * Used for transferring information to interfaces that add
+ * entries to firmware tables.
+ */
+typedef struct IPMIFwInfo {
+    const char *interface_name;
+    int interface_type;
+    uint8_t ipmi_spec_major_revision;
+    uint8_t ipmi_spec_minor_revision;
+    uint8_t i2c_slave_address;
+    uint32_t uuid;
+
+    uint64_t base_address;
+    uint64_t register_length;
+    uint8_t register_spacing;
+    enum {
+        IPMI_MEMSPACE_IO,
+        IPMI_MEMSPACE_MEM32,
+        IPMI_MEMSPACE_MEM64,
+        IPMI_MEMSPACE_SMBUS
+    } memspace;
+
+    int interrupt_number;
+    enum {
+        IPMI_LEVEL_IRQ,
+        IPMI_EDGE_IRQ
+    } irq_type;
+
+    const char *acpi_parent;
+} IPMIFwInfo;
+
+void ipmi_add_fwinfo(IPMIFwInfo *info, Error **errp);
+IPMIFwInfo *ipmi_first_fwinfo(void);
+IPMIFwInfo *ipmi_next_fwinfo(IPMIFwInfo *current);
+
 #ifdef IPMI_DEBUG
 #define ipmi_debug(fs, ...) \
     fprintf(stderr, "IPMI (%s): " fs, __func__, ##__VA_ARGS__)
index aa211c0..8c44d36 100644 (file)
@@ -39,3 +39,4 @@ typedef struct I8257State {
 } I8257State;
 
 #endif
+
index 6954b6e..cded509 100644 (file)
@@ -80,4 +80,4 @@ void pic_reset_common(PICCommonState *s);
 ISADevice *i8259_init_chip(const char *name, ISABus *bus, bool master);
 
 
-#endif /* QEMU_I8259_INTERNAL_H */
+#endif /* !QEMU_I8259_INTERNAL_H */
index 7693ac5..ffb2ea7 100644 (file)
@@ -3,8 +3,8 @@
 
 /* ISA bus */
 
-#include "exec/memory.h"
 #include "exec/ioport.h"
+#include "exec/memory.h"
 #include "hw/qdev.h"
 
 #define ISA_NUM_IRQS 16
@@ -102,7 +102,6 @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space,
 void isa_bus_irqs(ISABus *bus, qemu_irq *irqs);
 qemu_irq isa_get_irq(ISADevice *dev, int isairq);
 void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq);
-void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, int isairq);
 void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16);
 IsaDma *isa_get_dma(ISABus *bus, int nchan);
 MemoryRegion *isa_address_space(ISADevice *dev);
index 0f0d228..fbc8dc2 100644 (file)
@@ -2,8 +2,6 @@
 #define HW_MCF_H
 /* Motorola ColdFire device prototypes.  */
 
-#include "target-m68k/cpu-qom.h"
-
 struct MemoryRegion;
 
 /* mcf_uart.c */
index 1cfe9e0..517de9c 100644 (file)
@@ -24,7 +24,6 @@
 #define QEMU_NVDIMM_H
 
 #include "hw/mem/pc-dimm.h"
-#include "hw/acpi/bios-linker-loader.h"
 
 #define NVDIMM_DEBUG 0
 #define nvdimm_debug(fmt, ...)                                \
         }                                                     \
     } while (0)
 
-/*
- * The minimum label data size is required by NVDIMM Namespace
- * specification, see the chapter 2 Namespaces:
- *   "NVDIMMs following the NVDIMM Block Mode Specification use an area
- *    at least 128KB in size, which holds around 1000 labels."
- */
-#define MIN_NAMESPACE_LABEL_SIZE      (128UL << 10)
-
-#define TYPE_NVDIMM      "nvdimm"
-#define NVDIMM(obj)      OBJECT_CHECK(NVDIMMDevice, (obj), TYPE_NVDIMM)
-#define NVDIMM_CLASS(oc) OBJECT_CLASS_CHECK(NVDIMMClass, (oc), TYPE_NVDIMM)
-#define NVDIMM_GET_CLASS(obj) OBJECT_GET_CLASS(NVDIMMClass, (obj), \
-                                               TYPE_NVDIMM)
-struct NVDIMMDevice {
-    /* private */
-    PCDIMMDevice parent_obj;
-
-    /* public */
-
-    /*
-     * the size of label data in NVDIMM device which is presented to
-     * guest via __DSM "Get Namespace Label Size" function.
-     */
-    uint64_t label_size;
-
-    /*
-     * the address of label data which is read by __DSM "Get Namespace
-     * Label Data" function and written by __DSM "Set Namespace Label
-     * Data" function.
-     */
-    void *label_data;
-
-    /*
-     * it's the PMEM region in NVDIMM device, which is presented to
-     * guest via ACPI NFIT and _FIT method if NVDIMM hotplug is supported.
-     */
-    MemoryRegion nvdimm_mr;
-};
-typedef struct NVDIMMDevice NVDIMMDevice;
-
-struct NVDIMMClass {
-    /* private */
-    PCDIMMDeviceClass parent_class;
-
-    /* public */
-
-    /* read @size bytes from NVDIMM label data at @offset into @buf. */
-    void (*read_label_data)(NVDIMMDevice *nvdimm, void *buf,
-                            uint64_t size, uint64_t offset);
-    /* write @size bytes from @buf to NVDIMM label data at @offset. */
-    void (*write_label_data)(NVDIMMDevice *nvdimm, const void *buf,
-                             uint64_t size, uint64_t offset);
-};
-typedef struct NVDIMMClass NVDIMMClass;
+#define TYPE_NVDIMM             "nvdimm"
 
 #define NVDIMM_DSM_MEM_FILE     "etc/acpi/nvdimm-mem"
 
@@ -112,5 +58,5 @@ typedef struct AcpiNVDIMMState AcpiNVDIMMState;
 void nvdimm_init_acpi_state(AcpiNVDIMMState *state, MemoryRegion *io,
                             FWCfgState *fw_cfg, Object *owner);
 void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data,
-                       BIOSLinker *linker, GArray *dsm_dma_arrea);
+                       GArray *linker);
 #endif
index 1e483f2..218dfb0 100644 (file)
@@ -20,6 +20,8 @@
 #include "sysemu/hostmem.h"
 #include "hw/qdev.h"
 
+#define DEFAULT_PC_DIMMSIZE (1024*1024*1024)
+
 #define TYPE_PC_DIMM "pc-dimm"
 #define PC_DIMM(obj) \
     OBJECT_CHECK(PCDIMMDevice, (obj), TYPE_PC_DIMM)
@@ -58,26 +60,19 @@ typedef struct PCDIMMDevice {
 
 /**
  * PCDIMMDeviceClass:
- * @realize: called after common dimm is realized so that the dimm based
- * devices get the chance to do specified operations.
- * @get_memory_region: returns #MemoryRegion associated with @dimm which
- * is directly mapped into the physical address space of guest.
- * @get_vmstate_memory_region: returns #MemoryRegion which indicates the
- * memory of @dimm should be kept during live migration.
+ * @get_memory_region: returns #MemoryRegion associated with @dimm
  */
 typedef struct PCDIMMDeviceClass {
     /* private */
     DeviceClass parent_class;
 
     /* public */
-    void (*realize)(PCDIMMDevice *dimm, Error **errp);
     MemoryRegion *(*get_memory_region)(PCDIMMDevice *dimm);
-    MemoryRegion *(*get_vmstate_memory_region)(PCDIMMDevice *dimm);
 } PCDIMMDeviceClass;
 
 /**
  * MemoryHotplugState:
- * @base: address in guest physical address space where hotplug memory
+ * @base: address in guest RAM address space where hotplug memory
  * address space begins.
  * @mr: hotplug memory address space container
  */
index 526b8d0..4dbae9c 100644 (file)
@@ -22,7 +22,6 @@
 
 #include "hw/sysbus.h"
 #include "hw/misc/mips_cmgcr.h"
-#include "hw/intc/mips_gic.h"
 #include "hw/misc/mips_cpc.h"
 #include "hw/misc/mips_itu.h"
 
@@ -38,7 +37,6 @@ typedef struct MIPSCPSState {
 
     MemoryRegion container;
     MIPSGCRState gcr;
-    MIPSGICState gic;
     MIPSCPCState cpc;
     MIPSITUState itu;
 } MIPSCPSState;
index 8673daa..b2626f2 100644 (file)
@@ -1,8 +1,5 @@
 #ifndef HW_MIPS_CPUDEVS_H
 #define HW_MIPS_CPUDEVS_H
-
-#include "target-mips/cpu-qom.h"
-
 /* Definitions for MIPS CPU internal devices.  */
 
 /* mips_addr.c */
@@ -12,9 +9,9 @@ uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr);
 
 
 /* mips_int.c */
-void cpu_mips_irq_init_cpu(MIPSCPU *cpu);
+void cpu_mips_irq_init_cpu(CPUMIPSState *env);
 
 /* mips_timer.c */
-void cpu_mips_clock_init(MIPSCPU *cpu);
+void cpu_mips_clock_init(CPUMIPSState *);
 
 #endif
index 0077dac..37789b6 100644 (file)
@@ -10,9 +10,8 @@
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
-
-#ifndef ARM_INTEGRATOR_DEBUG_H
-#define ARM_INTEGRATOR_DEBUG_H
+#ifndef QEMU_INTEGRATOR_DEBUG_H
+#define QEMU_INTEGRATOR_DEBUG_H
 
 #define TYPE_INTEGRATOR_DEBUG "integrator_debug"
 
diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
deleted file mode 100644 (file)
index fdfd982..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * ASPEED System Control Unit
- *
- * Andrew Jeffery <andrew@aj.id.au>
- *
- * Copyright 2016 IBM Corp.
- *
- * This code is licensed under the GPL version 2 or later.  See
- * the COPYING file in the top-level directory.
- */
-#ifndef ASPEED_SCU_H
-#define ASPEED_SCU_H
-
-#include "hw/sysbus.h"
-
-#define TYPE_ASPEED_SCU "aspeed.scu"
-#define ASPEED_SCU(obj) OBJECT_CHECK(AspeedSCUState, (obj), TYPE_ASPEED_SCU)
-
-#define ASPEED_SCU_NR_REGS (0x1A8 >> 2)
-
-typedef struct AspeedSCUState {
-    /*< private >*/
-    SysBusDevice parent_obj;
-
-    /*< public >*/
-    MemoryRegion iomem;
-
-    uint32_t regs[ASPEED_SCU_NR_REGS];
-    uint32_t silicon_rev;
-    uint32_t hw_strap1;
-    uint32_t hw_strap2;
-} AspeedSCUState;
-
-#define AST2400_A0_SILICON_REV   0x02000303U
-#define AST2500_A0_SILICON_REV   0x04000303U
-
-extern bool is_supported_silicon_rev(uint32_t silicon_rev);
-
-#endif /* ASPEED_SCU_H */
diff --git a/include/hw/misc/auxbus.h b/include/hw/misc/auxbus.h
deleted file mode 100644 (file)
index 68ade8a..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * auxbus.h
- *
- *  Copyright (C)2014 : GreenSocs Ltd
- *      http://www.greensocs.com/ , email: info@greensocs.com
- *
- *  Developed by :
- *  Frederic Konrad   <fred.konrad@greensocs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option)any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef HW_MISC_AUXBUS_H
-#define HW_MISC_AUXBUS_H
-
-#include "hw/qdev.h"
-
-typedef struct AUXBus AUXBus;
-typedef struct AUXSlave AUXSlave;
-typedef enum AUXCommand AUXCommand;
-typedef enum AUXReply AUXReply;
-typedef struct AUXTOI2CState AUXTOI2CState;
-
-enum AUXCommand {
-    WRITE_I2C = 0,
-    READ_I2C = 1,
-    WRITE_I2C_STATUS = 2,
-    WRITE_I2C_MOT = 4,
-    READ_I2C_MOT = 5,
-    WRITE_AUX = 8,
-    READ_AUX = 9
-};
-
-enum AUXReply {
-    AUX_I2C_ACK = 0,
-    AUX_NACK = 1,
-    AUX_DEFER = 2,
-    AUX_I2C_NACK = 4,
-    AUX_I2C_DEFER = 8
-};
-
-#define TYPE_AUX_BUS "aux-bus"
-#define AUX_BUS(obj) OBJECT_CHECK(AUXBus, (obj), TYPE_AUX_BUS)
-
-struct AUXBus {
-    /* < private > */
-    BusState qbus;
-
-    /* < public > */
-    AUXSlave *current_dev;
-    AUXSlave *dev;
-    uint32_t last_i2c_address;
-    AUXCommand last_transaction;
-
-    AUXTOI2CState *bridge;
-
-    MemoryRegion *aux_io;
-    AddressSpace aux_addr_space;
-};
-
-#define TYPE_AUX_SLAVE "aux-slave"
-#define AUX_SLAVE(obj) \
-     OBJECT_CHECK(AUXSlave, (obj), TYPE_AUX_SLAVE)
-
-struct AUXSlave {
-    /* < private > */
-    DeviceState parent_obj;
-
-    /* < public > */
-    MemoryRegion *mmio;
-};
-
-/**
- * aux_init_bus: Initialize an AUX bus.
- *
- * Returns the new AUX bus created.
- *
- * @parent The device where this bus is located.
- * @name The name of the bus.
- */
-AUXBus *aux_init_bus(DeviceState *parent, const char *name);
-
-/*
- * aux_request: Make a request on the bus.
- *
- * Returns the reply of the request.
- *
- * @bus Ths bus where the request happen.
- * @cmd The command requested.
- * @address The 20bits address of the slave.
- * @len The length of the read or write.
- * @data The data array which will be filled or read during transfer.
- */
-AUXReply aux_request(AUXBus *bus, AUXCommand cmd, uint32_t address,
-                              uint8_t len, uint8_t *data);
-
-/*
- * aux_get_i2c_bus: Get the i2c bus for I2C over AUX command.
- *
- * Returns the i2c bus associated to this AUX bus.
- *
- * @bus The AUX bus.
- */
-I2CBus *aux_get_i2c_bus(AUXBus *bus);
-
-/*
- * aux_init_mmio: Init an mmio for an AUX slave.
- *
- * @aux_slave The AUX slave.
- * @mmio The mmio to be registered.
- */
-void aux_init_mmio(AUXSlave *aux_slave, MemoryRegion *mmio);
-
-DeviceState *aux_create_slave(AUXBus *bus, const char *name, uint32_t addr);
-
-#endif /* HW_MISC_AUXBUS_H */
diff --git a/include/hw/misc/imx6_src.h b/include/hw/misc/imx6_src.h
deleted file mode 100644 (file)
index eb36407..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * IMX6 System Reset Controller
- *
- * Copyright (C) 2012 NICTA
- * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef IMX6_SRC_H
-#define IMX6_SRC_H
-
-#include "hw/sysbus.h"
-#include "qemu/bitops.h"
-
-#define SRC_SCR 0
-#define SRC_SBMR1 1
-#define SRC_SRSR 2
-#define SRC_SISR 5
-#define SRC_SIMR 6
-#define SRC_SBMR2 7
-#define SRC_GPR1 8
-#define SRC_GPR2 9
-#define SRC_GPR3 10
-#define SRC_GPR4 11
-#define SRC_GPR5 12
-#define SRC_GPR6 13
-#define SRC_GPR7 14
-#define SRC_GPR8 15
-#define SRC_GPR9 16
-#define SRC_GPR10 17
-#define SRC_MAX 18
-
-/* SRC_SCR */
-#define CORE3_ENABLE_SHIFT     24
-#define CORE3_ENABLE_LENGTH    1
-#define CORE2_ENABLE_SHIFT     23
-#define CORE2_ENABLE_LENGTH    1
-#define CORE1_ENABLE_SHIFT     22
-#define CORE1_ENABLE_LENGTH    1
-#define CORE3_RST_SHIFT        16
-#define CORE3_RST_LENGTH       1
-#define CORE2_RST_SHIFT        15
-#define CORE2_RST_LENGTH       1
-#define CORE1_RST_SHIFT        14
-#define CORE1_RST_LENGTH       1
-#define CORE0_RST_SHIFT        13
-#define CORE0_RST_LENGTH       1
-#define SW_IPU1_RST_SHIFT      3
-#define SW_IPU1_RST_LENGTH     1
-#define SW_IPU2_RST_SHIFT      12
-#define SW_IPU2_RST_LENGTH     1
-#define WARM_RST_ENABLE_SHIFT  0
-#define WARM_RST_ENABLE_LENGTH 1
-
-#define EXTRACT(value, name) extract32(value, name##_SHIFT, name##_LENGTH)
-
-#define TYPE_IMX6_SRC "imx6.src"
-#define IMX6_SRC(obj) OBJECT_CHECK(IMX6SRCState, (obj), TYPE_IMX6_SRC)
-
-typedef struct IMX6SRCState {
-    /* <private> */
-    SysBusDevice parent_obj;
-
-    /* <public> */
-    MemoryRegion iomem;
-
-    uint32_t regs[SRC_MAX];
-
-} IMX6SRCState;
-
-#endif /* IMX6_SRC_H */
index 33cbc09..48a7afa 100644 (file)
@@ -46,10 +46,7 @@ typedef enum  {
     CLK_NONE,
     CLK_IPG,
     CLK_IPG_HIGH,
-    CLK_32k,
-    CLK_EXT,
-    CLK_HIGH_DIV,
-    CLK_HIGH,
+    CLK_32k
 } IMXClk;
 
 typedef struct IMXCCMClass {
index a209d91..cc60eef 100644 (file)
@@ -7,8 +7,8 @@
  *
  */
 
-#ifndef MIPS_CMGCR_H
-#define MIPS_CMGCR_H
+#ifndef _MIPS_GCR_H
+#define _MIPS_GCR_H
 
 #define TYPE_MIPS_GCR "mips-gcr"
 #define MIPS_GCR(obj) OBJECT_CHECK(MIPSGCRState, (obj), TYPE_MIPS_GCR)
 #define GCR_CONFIG_OFS      0x0000
 #define GCR_BASE_OFS        0x0008
 #define GCR_REV_OFS         0x0030
-#define GCR_GIC_BASE_OFS    0x0080
 #define GCR_CPC_BASE_OFS    0x0088
-#define GCR_GIC_STATUS_OFS  0x00D0
 #define GCR_CPC_STATUS_OFS  0x00F0
 #define GCR_L2_CONFIG_OFS   0x0130
 
 /* Core Local and Core Other Block Register Map */
 #define GCR_CL_CONFIG_OFS   0x0010
 #define GCR_CL_OTHER_OFS    0x0018
-#define GCR_CL_RESETBASE_OFS 0x0020
 
 /* GCR_L2_CONFIG register fields */
 #define GCR_L2_CONFIG_BYPASS_SHF    20
 #define GCR_L2_CONFIG_BYPASS_MSK    ((0x1ULL) << GCR_L2_CONFIG_BYPASS_SHF)
 
-/* GCR_GIC_BASE register fields */
-#define GCR_GIC_BASE_GICEN_MSK   1
-#define GCR_GIC_BASE_GICBASE_MSK 0xFFFFFFFE0000ULL
-#define GCR_GIC_BASE_MSK (GCR_GIC_BASE_GICEN_MSK | GCR_GIC_BASE_GICBASE_MSK)
-
 /* GCR_CPC_BASE register fields */
 #define GCR_CPC_BASE_CPCEN_MSK   1
 #define GCR_CPC_BASE_CPCBASE_MSK 0xFFFFFFFF8000ULL
 #define GCR_CPC_BASE_MSK (GCR_CPC_BASE_CPCEN_MSK | GCR_CPC_BASE_CPCBASE_MSK)
 
-/* GCR_CL_OTHER_OFS register fields */
-#define GCR_CL_OTHER_VPOTHER_MSK 0x7
-#define GCR_CL_OTHER_MSK GCR_CL_OTHER_VPOTHER_MSK
-
-/* GCR_CL_RESETBASE_OFS register fields */
-#define GCR_CL_RESET_BASE_RESETBASE_MSK 0xFFFFF000U
-#define GCR_CL_RESET_BASE_MSK GCR_CL_RESET_BASE_RESETBASE_MSK
-
-typedef struct MIPSGCRVPState MIPSGCRVPState;
-struct MIPSGCRVPState {
-    uint32_t other;
-    uint64_t reset_base;
-};
-
 typedef struct MIPSGCRState MIPSGCRState;
 struct MIPSGCRState {
     SysBusDevice parent_obj;
@@ -74,13 +52,8 @@ struct MIPSGCRState {
     hwaddr gcr_base;
     MemoryRegion iomem;
     MemoryRegion *cpc_mr;
-    MemoryRegion *gic_mr;
 
     uint64_t cpc_base;
-    uint64_t gic_base;
-
-    /* VP Local/Other Registers */
-    MIPSGCRVPState *vps;
 };
 
-#endif /* MIPS_CMGCR_H */
+#endif /* _MIPS_GCR_H */
index ef015ee..9b55aba 100644 (file)
@@ -11,9 +11,8 @@
  * This work is licensed under the terms of the GNU GPL, version 2 or
  * later. See the COPYING file in the top-level directory.
  */
-
-#ifndef TMP105_REGS_H
-#define TMP105_REGS_H
+#ifndef QEMU_TMP105_MSGS_H
+#define QEMU_TMP105_MSGS_H
 
 /**
  * TMP105Reg:
index 4cc8aab..9f21aa7 100644 (file)
@@ -19,9 +19,8 @@
  * GNU General Public License for more details.
  *
  */
-
-#ifndef ALLWINNER_EMAC_H
-#define ALLWINNER_EMAC_H
+#ifndef AW_EMAC_H
+#define AW_EMAC_H
 
 #include "net/net.h"
 #include "qemu/fifo8.h"
index 62ad473..cbf8650 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * i.MX FEC/ENET Ethernet Controller emulation.
+ * i.MX Fast Ethernet Controller emulation.
  *
  * Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
  *
 #define TYPE_IMX_FEC "imx.fec"
 #define IMX_FEC(obj) OBJECT_CHECK(IMXFECState, (obj), TYPE_IMX_FEC)
 
-#define TYPE_IMX_ENET "imx.enet"
-
 #include "hw/sysbus.h"
 #include "net/net.h"
 
-#define ENET_EIR               1
-#define ENET_EIMR              2
-#define ENET_RDAR              4
-#define ENET_TDAR              5
-#define ENET_ECR               9
-#define ENET_MMFR              16
-#define ENET_MSCR              17
-#define ENET_MIBC              25
-#define ENET_RCR               33
-#define ENET_TCR               49
-#define ENET_PALR              57
-#define ENET_PAUR              58
-#define ENET_OPD               59
-#define ENET_IAUR              70
-#define ENET_IALR              71
-#define ENET_GAUR              72
-#define ENET_GALR              73
-#define ENET_TFWR              81
-#define ENET_FRBR              83
-#define ENET_FRSR              84
-#define ENET_RDSR              96
-#define ENET_TDSR              97
-#define ENET_MRBR              98
-#define ENET_RSFL              100
-#define ENET_RSEM              101
-#define ENET_RAEM              102
-#define ENET_RAFL              103
-#define ENET_TSEM              104
-#define ENET_TAEM              105
-#define ENET_TAFL              106
-#define ENET_TIPG              107
-#define ENET_FTRL              108
-#define ENET_TACC              112
-#define ENET_RACC              113
-#define ENET_MIIGSK_CFGR       192
-#define ENET_MIIGSK_ENR        194
-#define ENET_ATCR              256
-#define ENET_ATVR              257
-#define ENET_ATOFF             258
-#define ENET_ATPER             259
-#define ENET_ATCOR             260
-#define ENET_ATINC             261
-#define ENET_ATSTMP            262
-#define ENET_TGSR              385
-#define ENET_TCSR0             386
-#define ENET_TCCR0             387
-#define ENET_TCSR1             388
-#define ENET_TCCR1             389
-#define ENET_TCSR2             390
-#define ENET_TCCR2             391
-#define ENET_TCSR3             392
-#define ENET_TCCR3             393
-#define ENET_MAX               400
-
-#define ENET_MAX_FRAME_SIZE    2032
-
-/* EIR and EIMR */
-#define ENET_INT_HB            (1 << 31)
-#define ENET_INT_BABR          (1 << 30)
-#define ENET_INT_BABT          (1 << 29)
-#define ENET_INT_GRA           (1 << 28)
-#define ENET_INT_TXF           (1 << 27)
-#define ENET_INT_TXB           (1 << 26)
-#define ENET_INT_RXF           (1 << 25)
-#define ENET_INT_RXB           (1 << 24)
-#define ENET_INT_MII           (1 << 23)
-#define ENET_INT_EBERR         (1 << 22)
-#define ENET_INT_LC            (1 << 21)
-#define ENET_INT_RL            (1 << 20)
-#define ENET_INT_UN            (1 << 19)
-#define ENET_INT_PLR           (1 << 18)
-#define ENET_INT_WAKEUP        (1 << 17)
-#define ENET_INT_TS_AVAIL      (1 << 16)
-#define ENET_INT_TS_TIMER      (1 << 15)
-
-#define ENET_INT_MAC           (ENET_INT_HB | ENET_INT_BABR | ENET_INT_BABT | \
-                                ENET_INT_GRA | ENET_INT_TXF | ENET_INT_TXB | \
-                                ENET_INT_RXF | ENET_INT_RXB | ENET_INT_MII | \
-                                ENET_INT_EBERR | ENET_INT_LC | ENET_INT_RL | \
-                                ENET_INT_UN | ENET_INT_PLR | ENET_INT_WAKEUP | \
-                                ENET_INT_TS_AVAIL)
-
-/* RDAR */
-#define ENET_RDAR_RDAR         (1 << 24)
-
-/* TDAR */
-#define ENET_TDAR_TDAR         (1 << 24)
-
-/* ECR */
-#define ENET_ECR_RESET         (1 << 0)
-#define ENET_ECR_ETHEREN       (1 << 1)
-#define ENET_ECR_MAGICEN       (1 << 2)
-#define ENET_ECR_SLEEP         (1 << 3)
-#define ENET_ECR_EN1588        (1 << 4)
-#define ENET_ECR_SPEED         (1 << 5)
-#define ENET_ECR_DBGEN         (1 << 6)
-#define ENET_ECR_STOPEN        (1 << 7)
-#define ENET_ECR_DSBWP         (1 << 8)
-
-/* MIBC */
-#define ENET_MIBC_MIB_DIS      (1 << 31)
-#define ENET_MIBC_MIB_IDLE     (1 << 30)
-#define ENET_MIBC_MIB_CLEAR    (1 << 29)
-
-/* RCR */
-#define ENET_RCR_LOOP          (1 << 0)
-#define ENET_RCR_DRT           (1 << 1)
-#define ENET_RCR_MII_MODE      (1 << 2)
-#define ENET_RCR_PROM          (1 << 3)
-#define ENET_RCR_BC_REJ        (1 << 4)
-#define ENET_RCR_FCE           (1 << 5)
-#define ENET_RCR_RGMII_EN      (1 << 6)
-#define ENET_RCR_RMII_MODE     (1 << 8)
-#define ENET_RCR_RMII_10T      (1 << 9)
-#define ENET_RCR_PADEN         (1 << 12)
-#define ENET_RCR_PAUFWD        (1 << 13)
-#define ENET_RCR_CRCFWD        (1 << 14)
-#define ENET_RCR_CFEN          (1 << 15)
-#define ENET_RCR_MAX_FL_SHIFT  (16)
-#define ENET_RCR_MAX_FL_LENGTH (14)
-#define ENET_RCR_NLC           (1 << 30)
-#define ENET_RCR_GRS           (1 << 31)
-
-/* TCR */
-#define ENET_TCR_GTS           (1 << 0)
-#define ENET_TCR_FDEN          (1 << 2)
-#define ENET_TCR_TFC_PAUSE     (1 << 3)
-#define ENET_TCR_RFC_PAUSE     (1 << 4)
-#define ENET_TCR_ADDSEL_SHIFT  (5)
-#define ENET_TCR_ADDSEL_LENGTH (3)
-#define ENET_TCR_CRCFWD        (1 << 9)
-
-/* RDSR */
-#define ENET_TWFR_TFWR_SHIFT   (0)
-#define ENET_TWFR_TFWR_LENGTH  (6)
-#define ENET_TWFR_STRFWD       (1 << 8)
+#define FEC_MAX_FRAME_SIZE 2032
+
+#define FEC_INT_HB      (1 << 31)
+#define FEC_INT_BABR    (1 << 30)
+#define FEC_INT_BABT    (1 << 29)
+#define FEC_INT_GRA     (1 << 28)
+#define FEC_INT_TXF     (1 << 27)
+#define FEC_INT_TXB     (1 << 26)
+#define FEC_INT_RXF     (1 << 25)
+#define FEC_INT_RXB     (1 << 24)
+#define FEC_INT_MII     (1 << 23)
+#define FEC_INT_EBERR   (1 << 22)
+#define FEC_INT_LC      (1 << 21)
+#define FEC_INT_RL      (1 << 20)
+#define FEC_INT_UN      (1 << 19)
+
+#define FEC_EN      2
+#define FEC_RESET   1
 
 /* Buffer Descriptor.  */
 typedef struct {
@@ -176,60 +56,22 @@ typedef struct {
     uint32_t data;
 } IMXFECBufDesc;
 
-#define ENET_BD_R              (1 << 15)
-#define ENET_BD_E              (1 << 15)
-#define ENET_BD_O1             (1 << 14)
-#define ENET_BD_W              (1 << 13)
-#define ENET_BD_O2             (1 << 12)
-#define ENET_BD_L              (1 << 11)
-#define ENET_BD_TC             (1 << 10)
-#define ENET_BD_ABC            (1 << 9)
-#define ENET_BD_M              (1 << 8)
-#define ENET_BD_BC             (1 << 7)
-#define ENET_BD_MC             (1 << 6)
-#define ENET_BD_LG             (1 << 5)
-#define ENET_BD_NO             (1 << 4)
-#define ENET_BD_CR             (1 << 2)
-#define ENET_BD_OV             (1 << 1)
-#define ENET_BD_TR             (1 << 0)
-
-typedef struct {
-    uint16_t length;
-    uint16_t flags;
-    uint32_t data;
-    uint16_t status;
-    uint16_t option;
-    uint16_t checksum;
-    uint16_t head_proto;
-    uint32_t last_buffer;
-    uint32_t timestamp;
-    uint32_t reserved[2];
-} IMXENETBufDesc;
-
-#define ENET_BD_ME             (1 << 15)
-#define ENET_BD_TX_INT         (1 << 14)
-#define ENET_BD_TS             (1 << 13)
-#define ENET_BD_PINS           (1 << 12)
-#define ENET_BD_IINS           (1 << 11)
-#define ENET_BD_PE             (1 << 10)
-#define ENET_BD_CE             (1 << 9)
-#define ENET_BD_UC             (1 << 8)
-#define ENET_BD_RX_INT         (1 << 7)
-
-#define ENET_BD_TXE            (1 << 15)
-#define ENET_BD_UE             (1 << 13)
-#define ENET_BD_EE             (1 << 12)
-#define ENET_BD_FE             (1 << 11)
-#define ENET_BD_LCE            (1 << 10)
-#define ENET_BD_OE             (1 << 9)
-#define ENET_BD_TSE            (1 << 8)
-#define ENET_BD_ICE            (1 << 5)
-#define ENET_BD_PCR            (1 << 4)
-#define ENET_BD_VLAN           (1 << 2)
-#define ENET_BD_IPV6           (1 << 1)
-#define ENET_BD_FRAG           (1 << 0)
-
-#define ENET_BD_BDU            (1 << 31)
+#define FEC_BD_R    (1 << 15)
+#define FEC_BD_E    (1 << 15)
+#define FEC_BD_O1   (1 << 14)
+#define FEC_BD_W    (1 << 13)
+#define FEC_BD_O2   (1 << 12)
+#define FEC_BD_L    (1 << 11)
+#define FEC_BD_TC   (1 << 10)
+#define FEC_BD_ABC  (1 << 9)
+#define FEC_BD_M    (1 << 8)
+#define FEC_BD_BC   (1 << 7)
+#define FEC_BD_MC   (1 << 6)
+#define FEC_BD_LG   (1 << 5)
+#define FEC_BD_NO   (1 << 4)
+#define FEC_BD_CR   (1 << 2)
+#define FEC_BD_OV   (1 << 1)
+#define FEC_BD_TR   (1 << 0)
 
 typedef struct IMXFECState {
     /*< private >*/
@@ -238,20 +80,34 @@ typedef struct IMXFECState {
     /*< public >*/
     NICState *nic;
     NICConf conf;
-    qemu_irq irq[2];
+    qemu_irq irq;
     MemoryRegion iomem;
 
-    uint32_t regs[ENET_MAX];
+    uint32_t irq_state;
+    uint32_t eir;
+    uint32_t eimr;
+    uint32_t rx_enabled;
     uint32_t rx_descriptor;
     uint32_t tx_descriptor;
+    uint32_t ecr;
+    uint32_t mmfr;
+    uint32_t mscr;
+    uint32_t mibc;
+    uint32_t rcr;
+    uint32_t tcr;
+    uint32_t tfwr;
+    uint32_t frsr;
+    uint32_t erdsr;
+    uint32_t etdsr;
+    uint32_t emrbr;
+    uint32_t miigsk_cfgr;
+    uint32_t miigsk_enr;
 
     uint32_t phy_status;
     uint32_t phy_control;
     uint32_t phy_advertise;
     uint32_t phy_int;
     uint32_t phy_int_mask;
-
-    bool is_fec;
 } IMXFECState;
 
 #endif
index d092c68..f4cec62 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 #ifndef NMI_H
-#define NMI_H
+#define NMI_H 1
 
 #include "qemu-common.h"
 #include "qom/object.h"
@@ -45,5 +45,6 @@ typedef struct NMIClass {
 } NMIClass;
 
 void nmi_monitor_handle(int cpu_index, Error **errp);
+void inject_nmi(void);
 
 #endif /* NMI_H */
index 5c27a1f..d008112 100644 (file)
@@ -182,6 +182,5 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
                                  hwaddr dma_addr, AddressSpace *dma_as);
 
 FWCfgState *fw_cfg_find(void);
-bool fw_cfg_dma_enabled(void *opaque);
 
 #endif
index 74cfd56..c66ee22 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef OPENBIOS_FIRMWARE_ABI_H
-#define OPENBIOS_FIRMWARE_ABI_H
+#ifndef FIRMWARE_ABI_H
+#define FIRMWARE_ABI_H
 
 /* OpenBIOS NVRAM partition */
 struct OpenBIOS_nvpart_v1 {
@@ -72,4 +72,4 @@ Sun_init_header(struct Sun_nvram *header, const uint8_t *macaddr, int machine_id
 
     header->checksum = tmp;
 }
-#endif /* OPENBIOS_FIRMWARE_ABI_H */
+#endif /* FIRMWARE_ABI_H */
index b19bd55..736db61 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef PCI_HOST_APB_H
-#define PCI_HOST_APB_H
+#ifndef APB_PCI_H
+#define APB_PCI_H
 
 #include "qemu-common.h"
 
index e3a3742..61f773e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef PCI_HOST_PPCE500_H
-#define PCI_HOST_PPCE500_H
+#ifndef PPCE500_PCI_H
+#define PPCE500_PCI_H
 
 static inline int ppce500_pci_map_irq_slot(int devno, int irq_num)
 {
index 94486fd..c5c073d 100644 (file)
@@ -55,11 +55,12 @@ typedef struct MCHPCIState {
     MemoryRegion smram_region, open_high_smram;
     MemoryRegion smram, low_smram, high_smram;
     MemoryRegion tseg_blackhole, tseg_window;
-    Range pci_hole;
-    uint64_t below_4g_mem_size;
-    uint64_t above_4g_mem_size;
+    PcPciInfo pci_info;
+    ram_addr_t below_4g_mem_size;
+    ram_addr_t above_4g_mem_size;
     uint64_t pci_hole64_size;
     uint32_t short_root_bus;
+    IntelIOMMUState *iommu;
 } MCHPCIState;
 
 typedef struct Q35PCIHost {
@@ -77,11 +78,6 @@ typedef struct Q35PCIHost {
  * gmch part
  */
 
-#define MCH_HOST_PROP_RAM_MEM "ram-mem"
-#define MCH_HOST_PROP_PCI_MEM "pci-mem"
-#define MCH_HOST_PROP_SYSTEM_MEM "system-mem"
-#define MCH_HOST_PROP_IO_MEM "io-mem"
-
 /* PCI configuration */
 #define MCH_HOST_BRIDGE                        "MCH"
 
@@ -179,12 +175,4 @@ typedef struct Q35PCIHost {
 
 uint64_t mch_mcfg_base(void);
 
-/*
- * Arbitary but unique BNF number for IOAPIC device.
- *
- * TODO: make sure there would have no conflict with real PCI bus
- */
-#define Q35_PSEUDO_BUS_PLATFORM         (0xff)
-#define Q35_PSEUDO_DEVFN_IOAPIC         (0x00)
-
 #endif /* HW_Q35_H */
index 5adc603..03ee006 100644 (file)
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
+#if !defined(__HW_SPAPR_H__)
+#error Please include spapr.h before this file!
+#endif
 
-#ifndef PCI_HOST_SPAPR_H
-#define PCI_HOST_SPAPR_H
+#if !defined(__HW_SPAPR_PCI_H__)
+#define __HW_SPAPR_PCI_H__
 
-#include "hw/ppc/spapr.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_host.h"
 #include "hw/ppc/xics.h"
@@ -30,8 +32,6 @@
 #define SPAPR_PCI_HOST_BRIDGE(obj) \
     OBJECT_CHECK(sPAPRPHBState, (obj), TYPE_SPAPR_PCI_HOST_BRIDGE)
 
-#define SPAPR_PCI_DMA_MAX_WINDOWS    2
-
 typedef struct sPAPRPHBState sPAPRPHBState;
 
 typedef struct spapr_pci_msi {
@@ -56,7 +56,7 @@ struct sPAPRPHBState {
     hwaddr mem_win_addr, mem_win_size, io_win_addr, io_win_size;
     MemoryRegion memwindow, iowindow, msiwindow;
 
-    uint32_t dma_liobn[SPAPR_PCI_DMA_MAX_WINDOWS];
+    uint32_t dma_liobn;
     hwaddr dma_win_addr, dma_win_size;
     AddressSpace iommu_as;
     MemoryRegion iommu_root;
@@ -71,10 +71,6 @@ struct sPAPRPHBState {
     spapr_pci_msi_mig *msi_devs;
 
     QLIST_ENTRY(sPAPRPHBState) list;
-
-    bool ddw_enabled;
-    uint64_t page_size_mask;
-    uint64_t dma64_win_addr;
 };
 
 #define SPAPR_PCI_MAX_INDEX          255
@@ -97,7 +93,7 @@ static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 
-    return xics_get_qirq(spapr->xics, phb->lsi_table[pin].irq);
+    return xics_get_qirq(spapr->icp, phb->lsi_table[pin].irq);
 }
 
 PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index);
@@ -151,6 +147,4 @@ static inline void spapr_phb_vfio_reset(DeviceState *qdev)
 }
 #endif
 
-void spapr_phb_dma_reset(sPAPRPHBState *sphb);
-
-#endif /* PCI_HOST_SPAPR_H */
+#endif /* __HW_SPAPR_PCI_H__ */
index 4837bcf..8124908 100644 (file)
@@ -35,8 +35,7 @@ void msi_set_message(PCIDevice *dev, MSIMessage msg);
 MSIMessage msi_get_message(PCIDevice *dev, unsigned int vector);
 bool msi_enabled(const PCIDevice *dev);
 int msi_init(struct PCIDevice *dev, uint8_t offset,
-             unsigned int nr_vectors, bool msi64bit,
-             bool msi_per_vector_mask, Error **errp);
+             unsigned int nr_vectors, bool msi64bit, bool msi_per_vector_mask);
 void msi_uninit(struct PCIDevice *dev);
 void msi_reset(PCIDevice *dev);
 void msi_notify(PCIDevice *dev, unsigned int vector);
index 048a29d..72e5f93 100644 (file)
@@ -29,7 +29,6 @@ int msix_present(PCIDevice *dev);
 
 bool msix_is_masked(PCIDevice *dev, unsigned vector);
 void msix_set_pending(PCIDevice *dev, unsigned vector);
-void msix_clr_pending(PCIDevice *dev, int vector);
 
 int msix_vector_use(PCIDevice *dev, unsigned vector);
 void msix_vector_unuse(PCIDevice *dev, unsigned vector);
index 929ec2f..e7f2df5 100644 (file)
@@ -15,7 +15,6 @@
 #define PCI_DEVFN(slot, func)   ((((slot) & 0x1f) << 3) | ((func) & 0x07))
 #define PCI_SLOT(devfn)         (((devfn) >> 3) & 0x1f)
 #define PCI_FUNC(devfn)         ((devfn) & 0x07)
-#define PCI_BUILD_BDF(bus, devfn)     ((bus << 8) | (devfn))
 #define PCI_SLOT_MAX            32
 #define PCI_FUNC_MAX            8
 
@@ -234,20 +233,6 @@ typedef void (*MSIVectorPollNotifier)(PCIDevice *dev,
                                       unsigned int vector_start,
                                       unsigned int vector_end);
 
-enum PCIReqIDType {
-    PCI_REQ_ID_INVALID = 0,
-    PCI_REQ_ID_BDF,
-    PCI_REQ_ID_SECONDARY_BUS,
-    PCI_REQ_ID_MAX,
-};
-typedef enum PCIReqIDType PCIReqIDType;
-
-struct PCIReqIDCache {
-    PCIDevice *dev;
-    PCIReqIDType type;
-};
-typedef struct PCIReqIDCache PCIReqIDCache;
-
 struct PCIDevice {
     DeviceState qdev;
 
@@ -270,11 +255,6 @@ struct PCIDevice {
     /* the following fields are read only */
     PCIBus *bus;
     int32_t devfn;
-    /* Cached device to fetch requester ID from, to avoid the PCI
-     * tree walking every time we invoke PCI request (e.g.,
-     * MSI). For conventional PCI root complex, this field is
-     * meaningless. */
-    PCIReqIDCache requester_id_cache;
     char name[64];
     PCIIORegion io_regions[PCI_NUM_REGIONS];
     AddressSpace bus_master_as;
@@ -488,23 +468,16 @@ pci_get_long(const uint8_t *config)
     return ldl_le_p(config);
 }
 
-/*
- * PCI capabilities and/or their fields
- * are generally DWORD aligned only so
- * mechanism used by pci_set/get_quad()
- * must be tolerant to unaligned pointers
- *
- */
 static inline void
 pci_set_quad(uint8_t *config, uint64_t val)
 {
-    stq_le_p(config, val);
+    cpu_to_le64w((uint64_t *)config, val);
 }
 
 static inline uint64_t
 pci_get_quad(const uint8_t *config)
 {
-    return ldq_le_p(config);
+    return le64_to_cpup((const uint64_t *)config);
 }
 
 static inline void
@@ -715,13 +688,11 @@ static inline uint32_t pci_config_size(const PCIDevice *d)
     return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE;
 }
 
-static inline uint16_t pci_get_bdf(PCIDevice *dev)
+static inline uint16_t pci_requester_id(PCIDevice *dev)
 {
-    return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn);
+    return (pci_bus_num(dev->bus) << 8) | dev->devfn;
 }
 
-uint16_t pci_requester_id(PCIDevice *dev);
-
 /* DMA access functions */
 static inline AddressSpace *pci_get_address_space(PCIDevice *dev)
 {
@@ -808,6 +779,4 @@ extern const VMStateDescription vmstate_pci_device;
     .offset     = vmstate_offset_pointer(_state, _field, PCIDevice), \
 }
 
-MSIMessage pci_get_msi_message(PCIDevice *dev, int vector);
-
 #endif
index 847fd7d..ed4aff6 100644 (file)
@@ -67,4 +67,4 @@ void pci_bridge_map_irq(PCIBridge *br, const char* bus_name,
 #define  PCI_BRIDGE_CTL_DISCARD_STATUS 0x400   /* Discard timer status */
 #define  PCI_BRIDGE_CTL_DISCARD_SERR   0x800   /* Discard timer SERR# enable */
 
-#endif /* QEMU_PCI_BRIDGE_H */
+#endif  /* QEMU_PCI_BRIDGE_H */
index 5484a9b..403fec6 100644 (file)
@@ -39,8 +39,6 @@ struct PCIBus {
        Keep a count of the number of devices with raised IRQs.  */
     int nirq;
     int *irq_count;
-
-    Notifier machine_done;
 };
 
 typedef struct PCIBridgeWindows PCIBridgeWindows;
index d77ca60..db85afa 100644 (file)
@@ -7,9 +7,8 @@
  *
  *      QEMU-specific definitions belong in pci.h
  */
-
 #ifndef HW_PCI_IDS_H
-#define HW_PCI_IDS_H
+#define HW_PCI_IDS_H 1
 
 /* Device classes and subclasses */
 
index 7a83142..ba8cbe9 100644 (file)
@@ -1,3 +1 @@
 #include "standard-headers/linux/pci_regs.h"
-
-#define  PCI_PM_CAP_VER_1_1     0x0002  /* PCI PM spec ver. 1.1 */
index 056d25e..b48a7a2 100644 (file)
@@ -80,12 +80,8 @@ struct PCIExpressDevice {
 
 /* PCI express capability helper functions */
 int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port);
-int pcie_cap_v1_init(PCIDevice *dev, uint8_t offset,
-                     uint8_t type, uint8_t port);
 int pcie_endpoint_cap_init(PCIDevice *dev, uint8_t offset);
 void pcie_cap_exit(PCIDevice *dev);
-int pcie_endpoint_cap_v1_init(PCIDevice *dev, uint8_t offset);
-void pcie_cap_v1_exit(PCIDevice *dev);
 uint8_t pcie_cap_get_type(const PCIDevice *dev);
 void pcie_cap_flags_set_vector(PCIDevice *dev, uint8_t vector);
 uint8_t pcie_cap_flags_get_vector(PCIDevice *dev);
@@ -119,7 +115,6 @@ void pcie_add_capability(PCIDevice *dev,
                          uint16_t offset, uint16_t size);
 
 void pcie_ari_init(PCIDevice *dev, uint16_t offset, uint16_t nextfn);
-void pcie_dev_ser_num_init(PCIDevice *dev, uint16_t offset, uint64_t ser_num);
 
 extern const VMStateDescription vmstate_pcie_device;
 
index a95522a..6a28b33 100644 (file)
@@ -11,7 +11,6 @@
 
 /* express capability */
 
-#define PCI_EXP_VER1_SIZEOF             0x14 /* express capability of ver. 1 */
 #define PCI_EXP_VER2_SIZEOF             0x3c /* express capability of ver. 2 */
 #define PCI_EXT_CAP_VER_SHIFT           16
 #define PCI_EXT_CAP_NEXT_SHIFT          20
     (((x) + PCI_EXT_CAP_ALIGN - 1) & ~(PCI_EXT_CAP_ALIGN - 1))
 
 /* PCI_EXP_FLAGS */
-#define PCI_EXP_FLAGS_VER1              1
-#define PCI_EXP_FLAGS_VER2              2
+#define PCI_EXP_FLAGS_VER2              2 /* for now, supports only ver. 2 */
 #define PCI_EXP_FLAGS_IRQ_SHIFT         ctz32(PCI_EXP_FLAGS_IRQ)
 #define PCI_EXP_FLAGS_TYPE_SHIFT        ctz32(PCI_EXP_FLAGS_TYPE)
 
+
 /* PCI_EXP_LINK{CAP, STA} */
 /* link speed */
 #define PCI_EXP_LNK_LS_25               1
index 79cac9c..98406ff 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef HW_PCMCIA_H
-#define HW_PCMCIA_H
+#define HW_PCMCIA_H 1
 
 /* PCMCIA/Cardbus */
 
index a00775c..bd42b83 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef HW_PLATFORM_BUS_H
-#define HW_PLATFORM_BUS_H
+#define HW_PLATFORM_BUS_H 1
 
 /*
  *  Platform Bus device to support dynamic Sysbus devices
@@ -54,4 +54,4 @@ int platform_bus_get_irqn(PlatformBusDevice *platform_bus, SysBusDevice *sbdev,
 hwaddr platform_bus_get_mmio_addr(PlatformBusDevice *pbus, SysBusDevice *sbdev,
                                   int n);
 
-#endif /* HW_PLATFORM_BUS_H */
+#endif /* !HW_PLATFORM_BUS_H */
index a860387..0cce4e8 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
 #ifndef HW_MAC_DBDMA_H
-#define HW_MAC_DBDMA_H
+#define HW_MAC_DBDMA_H 1
 
 #include "exec/memory.h"
 #include "qemu/iov.h"
-#include "sysemu/dma.h"
 
 typedef struct DBDMA_io DBDMA_io;
 
@@ -46,10 +44,6 @@ struct DBDMA_io {
     uint8_t head_remainder[0x200];
     uint8_t tail_remainder[0x200];
     QEMUIOVector iov;
-    /* DMA request */
-    void *dma_mem;
-    dma_addr_t dma_len;
-    DMADirection dir;
 };
 
 /*
index 6137e2d..ee67098 100644 (file)
@@ -1,9 +1,8 @@
-#ifndef OPENPIC_H
-#define OPENPIC_H
+#if !defined(__OPENPIC_H__)
+#define __OPENPIC_H__
 
 #include "qemu-common.h"
-#include "hw/qdev-core.h"
-#include "qom/cpu.h"
+#include "hw/qdev.h"
 
 #define TYPE_OPENPIC "openpic"
 
@@ -30,4 +29,4 @@ enum {
 #define TYPE_KVM_OPENPIC "kvm-openpic"
 int kvm_openpic_connect_vcpu(DeviceState *d, CPUState *cs);
 
-#endif /* OPENPIC_H */
+#endif /* __OPENPIC_H__ */
index 00c1fb1..14efd0c 100644 (file)
@@ -1,7 +1,5 @@
 #ifndef HW_PPC_H
-#define HW_PPC_H
-
-#include "target-ppc/cpu-qom.h"
+#define HW_PPC_H 1
 
 void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level);
 
@@ -66,21 +64,17 @@ clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, uint32_t freq,
 void ppc40x_core_reset(PowerPCCPU *cpu);
 void ppc40x_chip_reset(PowerPCCPU *cpu);
 void ppc40x_system_reset(PowerPCCPU *cpu);
+void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);
+
+extern CPUWriteMemoryFunc * const PPC_io_write[];
+extern CPUReadMemoryFunc * const PPC_io_read[];
 void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val);
 
-#if defined(CONFIG_USER_ONLY)
-static inline void ppc40x_irq_init(PowerPCCPU *cpu) {}
-static inline void ppc6xx_irq_init(PowerPCCPU *cpu) {}
-static inline void ppc970_irq_init(PowerPCCPU *cpu) {}
-static inline void ppcPOWER7_irq_init(PowerPCCPU *cpu) {}
-static inline void ppce500_irq_init(PowerPCCPU *cpu) {}
-#else
-void ppc40x_irq_init(PowerPCCPU *cpu);
-void ppce500_irq_init(PowerPCCPU *cpu);
-void ppc6xx_irq_init(PowerPCCPU *cpu);
-void ppc970_irq_init(PowerPCCPU *cpu);
-void ppcPOWER7_irq_init(PowerPCCPU *cpu);
-#endif
+void ppc40x_irq_init (CPUPPCState *env);
+void ppce500_irq_init (CPUPPCState *env);
+void ppc6xx_irq_init (CPUPPCState *env);
+void ppc970_irq_init (CPUPPCState *env);
+void ppcPOWER7_irq_init (CPUPPCState *env);
 
 /* PPC machines for OpenBIOS */
 enum {
@@ -106,5 +100,4 @@ enum {
 /* ppc_booke.c */
 void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags);
 
-void ppc_cpu_parse_features(const char *cpu_model);
 #endif
index 3b01ae8..91d84ba 100644 (file)
@@ -22,8 +22,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef PPC4XX_H
-#define PPC4XX_H
+#if !defined(PPC_4XX_H)
+#define PPC_4XX_H
 
 #include "hw/pci/pci.h"
 
@@ -61,4 +61,4 @@ PCIBus *ppc4xx_pci_init(CPUPPCState *env, qemu_irq pci_irqs[4],
                         hwaddr special_cycle,
                         hwaddr registers);
 
-#endif /* PPC4XX_H */
+#endif /* !defined(PPC_4XX_H) */
index caf7be9..815d5ee 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef HW_SPAPR_H
-#define HW_SPAPR_H
+#if !defined(__HW_SPAPR_H__)
+#define __HW_SPAPR_H__
 
 #include "sysemu/dma.h"
 #include "hw/boards.h"
@@ -16,8 +16,6 @@ typedef struct sPAPREventLogEntry sPAPREventLogEntry;
 #define HPTE64_V_HPTE_DIRTY     0x0000000000000040ULL
 #define SPAPR_ENTRY_POINT       0x100
 
-#define SPAPR_TIMEBASE_FREQ     512000000ULL
-
 typedef struct sPAPRMachineClass sPAPRMachineClass;
 typedef struct sPAPRMachineState sPAPRMachineState;
 
@@ -51,7 +49,7 @@ struct sPAPRMachineState {
     struct VIOsPAPRBus *vio_bus;
     QLIST_HEAD(, sPAPRPHBState) phbs;
     struct sPAPRNVRAM *nvram;
-    XICSState *xics;
+    XICSState *icp;
     DeviceState *rtc;
 
     void *htab;
@@ -81,7 +79,6 @@ struct sPAPRMachineState {
     /*< public >*/
     char *kvm_type;
     MemoryHotplugState hotplug_memory;
-    Object **cores;
 };
 
 #define H_SUCCESS         0
@@ -415,16 +412,6 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi);
 #define RTAS_OUT_NOT_AUTHORIZED                 -9002
 #define RTAS_OUT_SYSPARM_PARAM_ERROR            -9999
 
-/* DDW pagesize mask values from ibm,query-pe-dma-window */
-#define RTAS_DDW_PGSIZE_4K       0x01
-#define RTAS_DDW_PGSIZE_64K      0x02
-#define RTAS_DDW_PGSIZE_16M      0x04
-#define RTAS_DDW_PGSIZE_32M      0x08
-#define RTAS_DDW_PGSIZE_64M      0x10
-#define RTAS_DDW_PGSIZE_128M     0x20
-#define RTAS_DDW_PGSIZE_256M     0x40
-#define RTAS_DDW_PGSIZE_16G      0x80
-
 /* RTAS tokens */
 #define RTAS_TOKEN_BASE      0x2000
 
@@ -466,12 +453,8 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi);
 #define RTAS_IBM_SET_SLOT_RESET                 (RTAS_TOKEN_BASE + 0x23)
 #define RTAS_IBM_CONFIGURE_PE                   (RTAS_TOKEN_BASE + 0x24)
 #define RTAS_IBM_SLOT_ERROR_DETAIL              (RTAS_TOKEN_BASE + 0x25)
-#define RTAS_IBM_QUERY_PE_DMA_WINDOW            (RTAS_TOKEN_BASE + 0x26)
-#define RTAS_IBM_CREATE_PE_DMA_WINDOW           (RTAS_TOKEN_BASE + 0x27)
-#define RTAS_IBM_REMOVE_PE_DMA_WINDOW           (RTAS_TOKEN_BASE + 0x28)
-#define RTAS_IBM_RESET_PE_DMA_WINDOW            (RTAS_TOKEN_BASE + 0x29)
 
-#define RTAS_TOKEN_MAX                          (RTAS_TOKEN_BASE + 0x2A)
+#define RTAS_TOKEN_MAX                          (RTAS_TOKEN_BASE + 0x26)
 
 /* RTAS ibm,get-system-parameter token values */
 #define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS      20
@@ -556,12 +539,10 @@ struct sPAPRTCETable {
     uint64_t bus_offset;
     uint32_t page_shift;
     uint64_t *table;
-    uint32_t mig_nb_table;
-    uint64_t *mig_table;
     bool bypass;
     bool need_vfio;
     int fd;
-    MemoryRegion root, iommu;
+    MemoryRegion iommu;
     struct VIOsPAPRDevice *vdev; /* for @bypass migration compatibility only */
     QLIST_ENTRY(sPAPRTCETable) list;
 };
@@ -580,11 +561,11 @@ void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq);
 int spapr_h_cas_compose_response(sPAPRMachineState *sm,
                                  target_ulong addr, target_ulong size,
                                  bool cpu_update, bool memory_update);
-sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn);
-void spapr_tce_table_enable(sPAPRTCETable *tcet,
-                            uint32_t page_shift, uint64_t bus_offset,
-                            uint32_t nb_table);
-void spapr_tce_table_disable(sPAPRTCETable *tcet);
+sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn,
+                                   uint64_t bus_offset,
+                                   uint32_t page_shift,
+                                   uint32_t nb_table,
+                                   bool need_vfio);
 void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio);
 
 MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet);
@@ -599,9 +580,6 @@ void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type,
                                        uint32_t count);
 void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type,
                                           uint32_t count);
-void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu, Error **errp);
-void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset,
-                                    sPAPRMachineState *spapr);
 
 /* rtas-configure-connector state */
 struct sPAPRConfigureConnectorState {
@@ -640,11 +618,9 @@ int spapr_rng_populate_dt(void *fdt);
 #define SPAPR_DR_LMB_LIST_ENTRY_SIZE 6
 
 /*
- * Defines for flag value in ibm,dynamic-memory property under
- * ibm,dynamic-reconfiguration-memory node.
+ * This flag value defines the LMB as assigned in ibm,dynamic-memory
+ * property under ibm,dynamic-reconfiguration-memory node.
  */
 #define SPAPR_LMB_FLAGS_ASSIGNED 0x00000008
-#define SPAPR_LMB_FLAGS_DRC_INVALID 0x00000020
-#define SPAPR_LMB_FLAGS_RESERVED 0x00000080
 
-#endif /* HW_SPAPR_H */
+#endif /* !defined (__HW_SPAPR_H__) */
diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h
deleted file mode 100644 (file)
index 1c9b319..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * sPAPR CPU core device.
- *
- * Copyright (C) 2016 Bharata B Rao <bharata@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#ifndef HW_SPAPR_CPU_CORE_H
-#define HW_SPAPR_CPU_CORE_H
-
-#include "hw/qdev.h"
-#include "hw/cpu/core.h"
-#include "target-ppc/cpu-qom.h"
-
-#define TYPE_SPAPR_CPU_CORE "spapr-cpu-core"
-#define SPAPR_CPU_CORE(obj) \
-    OBJECT_CHECK(sPAPRCPUCore, (obj), TYPE_SPAPR_CPU_CORE)
-
-typedef struct sPAPRCPUCore {
-    /*< private >*/
-    CPUCore parent_obj;
-
-    /*< public >*/
-    void *threads;
-    ObjectClass *cpu_class;
-} sPAPRCPUCore;
-
-void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
-                         Error **errp);
-char *spapr_get_cpu_core_type(const char *model);
-void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
-                     Error **errp);
-void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev,
-                       Error **errp);
-#endif
index fa531d5..fa21ba0 100644 (file)
@@ -9,13 +9,12 @@
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
+#if !defined(__HW_SPAPR_DRC_H__)
+#define __HW_SPAPR_DRC_H__
 
-#ifndef HW_SPAPR_DRC_H
-#define HW_SPAPR_DRC_H
-
-#include <libfdt.h>
 #include "qom/object.h"
 #include "hw/qdev.h"
+#include "libfdt.h"
 
 #define TYPE_SPAPR_DR_CONNECTOR "spapr-dr-connector"
 #define SPAPR_DR_CONNECTOR_GET_CLASS(obj) \
@@ -153,7 +152,6 @@ typedef struct sPAPRDRConnector {
 
     bool awaiting_release;
     bool signalled;
-    bool awaiting_allocation;
 
     /* device pointer, via link property */
     DeviceState *dev;
@@ -203,4 +201,4 @@ sPAPRDRConnector *spapr_dr_connector_by_id(sPAPRDRConnectorType type,
 int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
                           uint32_t drc_type_mask);
 
-#endif /* HW_SPAPR_DRC_H */
+#endif /* __HW_SPAPR_DRC_H__ */
index d4a1e2c..c9733e7 100644 (file)
@@ -1,6 +1,5 @@
-#ifndef HW_SPAPR_VIO_H
-#define HW_SPAPR_VIO_H
-
+#ifndef _HW_SPAPR_VIO_H
+#define _HW_SPAPR_VIO_H
 /*
  * QEMU sPAPR VIO bus definitions
  *
@@ -62,7 +61,7 @@ struct VIOsPAPRDevice {
     DeviceState qdev;
     uint32_t reg;
     uint32_t irq;
-    uint64_t signal_state;
+    target_ulong signal_state;
     VIOsPAPR_CRQ crq;
     AddressSpace as;
     MemoryRegion mrroot;
@@ -91,7 +90,7 @@ static inline qemu_irq spapr_vio_qirq(VIOsPAPRDevice *dev)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 
-    return xics_get_qirq(spapr->xics, dev->irq);
+    return xics_get_qirq(spapr->icp, dev->irq);
 }
 
 static inline bool spapr_vio_dma_valid(VIOsPAPRDevice *dev, uint64_t taddr,
@@ -146,4 +145,4 @@ extern const VMStateDescription vmstate_spapr_vio;
 
 void spapr_vio_set_bypass(VIOsPAPRDevice *dev, bool bypass);
 
-#endif /* HW_SPAPR_VIO_H */
+#endif /* _HW_SPAPR_VIO_H */
index 2db9f93..f60b06a 100644 (file)
  * THE SOFTWARE.
  *
  */
-
-#ifndef XICS_H
-#define XICS_H
+#if !defined(__XICS_H__)
+#define __XICS_H__
 
 #include "hw/sysbus.h"
 
 #define TYPE_XICS_COMMON "xics-common"
 #define XICS_COMMON(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_COMMON)
 
-/*
- * Retain xics as the type name to be compatible for migration. Rest all the
- * functions, class and variables are renamed as xics_spapr.
- */
-#define TYPE_XICS_SPAPR "xics"
-#define XICS_SPAPR(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_SPAPR)
+#define TYPE_XICS "xics"
+#define XICS(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS)
 
-#define TYPE_XICS_SPAPR_KVM "xics-spapr-kvm"
-#define XICS_SPAPR_KVM(obj) \
-     OBJECT_CHECK(KVMXICSState, (obj), TYPE_XICS_SPAPR_KVM)
+#define TYPE_KVM_XICS "xics-kvm"
+#define KVM_XICS(obj) OBJECT_CHECK(KVMXICSState, (obj), TYPE_KVM_XICS)
 
 #define XICS_COMMON_CLASS(klass) \
      OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_COMMON)
-#define XICS_SPAPR_CLASS(klass) \
-     OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_SPAPR)
+#define XICS_CLASS(klass) \
+     OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS)
 #define XICS_COMMON_GET_CLASS(obj) \
      OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_COMMON)
-#define XICS_SPAPR_GET_CLASS(obj) \
-     OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_SPAPR)
+#define XICS_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS)
 
 #define XICS_IPI        0x2
 #define XICS_BUID       0x1
@@ -144,15 +138,9 @@ struct ICSState {
     uint32_t offset;
     qemu_irq *qirqs;
     ICSIRQState *irqs;
-    XICSState *xics;
+    XICSState *icp;
 };
 
-static inline bool ics_valid_irq(ICSState *ics, uint32_t nr)
-{
-    return (nr >= ics->offset)
-        && (nr < (ics->offset + ics->nr_irqs));
-}
-
 struct ICSIRQState {
     uint32_t server;
     uint8_t priority;
@@ -169,32 +157,15 @@ struct ICSIRQState {
     uint8_t flags;
 };
 
-#define XICS_IRQS_SPAPR               1024
+#define XICS_IRQS               1024
 
 qemu_irq xics_get_qirq(XICSState *icp, int irq);
-int xics_spapr_alloc(XICSState *icp, int src, int irq_hint, bool lsi,
+void xics_set_irq_type(XICSState *icp, int irq, bool lsi);
+int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi, Error **errp);
+int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align,
                      Error **errp);
-int xics_spapr_alloc_block(XICSState *icp, int src, int num, bool lsi,
-                           bool align, Error **errp);
-void xics_spapr_free(XICSState *icp, int irq, int num);
+void xics_free(XICSState *icp, int irq, int num);
 
 void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
-void xics_cpu_destroy(XICSState *icp, PowerPCCPU *cpu);
-
-/* Internal XICS interfaces */
-int xics_get_cpu_index_by_dt_id(int cpu_dt_id);
-
-void icp_set_cppr(XICSState *icp, int server, uint8_t cppr);
-void icp_set_mfrr(XICSState *icp, int server, uint8_t mfrr);
-uint32_t icp_accept(ICPState *ss);
-uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr);
-void icp_eoi(XICSState *icp, int server, uint32_t xirr);
-
-void ics_write_xive(ICSState *ics, int nr, int server,
-                    uint8_t priority, uint8_t saved_priority);
-
-void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
-
-int xics_find_source(XICSState *icp, int irq);
 
-#endif /* XICS_H */
+#endif /* __XICS_H__ */
index e397db5..8ebacbb 100644 (file)
@@ -19,7 +19,6 @@ typedef void (*ptimer_cb)(void *opaque);
 ptimer_state *ptimer_init(QEMUBH *bh);
 void ptimer_set_period(ptimer_state *s, int64_t period);
 void ptimer_set_freq(ptimer_state *s, uint32_t freq);
-uint64_t ptimer_get_limit(ptimer_state *s);
 void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload);
 uint64_t ptimer_get_count(ptimer_state *s);
 void ptimer_set_count(ptimer_state *s, uint64_t count);
index 4b4b33b..1ce02b2 100644 (file)
@@ -259,11 +259,6 @@ struct PropertyInfo {
  * @user_provided: Set to true if property comes from user-provided config
  * (command-line or config file).
  * @used: Set to true if property was used when initializing a device.
- * @errp: Error destination, used like first argument of error_setg()
- *        in case property setting fails later. If @errp is NULL, we
- *        print warnings instead of ignoring errors silently. For
- *        hotplugged devices, errp is always ignored and warnings are
- *        printed instead.
  */
 typedef struct GlobalProperty {
     const char *driver;
@@ -271,7 +266,7 @@ typedef struct GlobalProperty {
     const char *value;
     bool user_provided;
     bool used;
-    Error **errp;
+    QTAILQ_ENTRY(GlobalProperty) next;
 } GlobalProperty;
 
 /*** Board API.  This should go away once we have a machine config file.  ***/
index 2a9d2f9..0586cac 100644 (file)
@@ -20,7 +20,6 @@ extern PropertyInfo qdev_prop_ptr;
 extern PropertyInfo qdev_prop_macaddr;
 extern PropertyInfo qdev_prop_on_off_auto;
 extern PropertyInfo qdev_prop_losttickpolicy;
-extern PropertyInfo qdev_prop_blockdev_on_error;
 extern PropertyInfo qdev_prop_bios_chs_trans;
 extern PropertyInfo qdev_prop_fdc_drive_type;
 extern PropertyInfo qdev_prop_drive;
@@ -162,9 +161,6 @@ extern PropertyInfo qdev_prop_arraylen;
 #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
     DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
                         LostTickPolicy)
-#define DEFINE_PROP_BLOCKDEV_ON_ERROR(_n, _s, _f, _d) \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blockdev_on_error, \
-                        BlockdevOnError)
 #define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \
     DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int)
 #define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \
@@ -201,14 +197,8 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
                                     Property *prop, const char *value);
 
 /**
- * qdev_property_add_static:
- * @dev: Device to add the property to.
- * @prop: The qdev property definition.
- * @errp: location to store error information.
- *
- * Add a static QOM property to @dev for qdev property @prop.
- * On error, store error in @errp.  Static properties access data in a struct.
- * The type of the QOM property is derived from prop->info.
+ * @qdev_property_add_static - add a @Property to a device referencing a
+ * field in a struct.
  */
 void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp);
 
diff --git a/include/hw/register.h b/include/hw/register.h
deleted file mode 100644 (file)
index 8c12233..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Register Definition API
- *
- * Copyright (c) 2016 Xilinx Inc.
- * Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- */
-
-#ifndef REGISTER_H
-#define REGISTER_H
-
-#include "hw/qdev-core.h"
-#include "exec/memory.h"
-
-typedef struct RegisterInfo RegisterInfo;
-typedef struct RegisterAccessInfo RegisterAccessInfo;
-typedef struct RegisterInfoArray RegisterInfoArray;
-
-/**
- * Access description for a register that is part of guest accessible device
- * state.
- *
- * @name: String name of the register
- * @ro: whether or not the bit is read-only
- * @w1c: bits with the common write 1 to clear semantic.
- * @reset: reset value.
- * @cor: Bits that are clear on read
- * @rsvd: Bits that are reserved and should not be changed
- *
- * @pre_write: Pre write callback. Passed the value that's to be written,
- * immediately before the actual write. The returned value is what is written,
- * giving the handler a chance to modify the written value.
- * @post_write: Post write callback. Passed the written value. Most write side
- * effects should be implemented here.
- *
- * @post_read: Post read callback. Passes the value that is about to be returned
- * for a read. The return value from this function is what is ultimately read,
- * allowing this function to modify the value before return to the client.
- */
-
-struct RegisterAccessInfo {
-    const char *name;
-    uint64_t ro;
-    uint64_t w1c;
-    uint64_t reset;
-    uint64_t cor;
-    uint64_t rsvd;
-    uint64_t unimp;
-
-    uint64_t (*pre_write)(RegisterInfo *reg, uint64_t val);
-    void (*post_write)(RegisterInfo *reg, uint64_t val);
-
-    uint64_t (*post_read)(RegisterInfo *reg, uint64_t val);
-
-    hwaddr addr;
-};
-
-/**
- * A register that is part of guest accessible state
- * @data: pointer to the register data. Will be cast
- * to the relevant uint type depending on data_size.
- * @data_size: Size of the register in bytes. Must be
- * 1, 2, 4 or 8
- *
- * @access: Access description of this register
- *
- * @debug: Whether or not verbose debug is enabled
- * @prefix: String prefix for log and debug messages
- *
- * @opaque: Opaque data for the register
- */
-
-struct RegisterInfo {
-    /* <private> */
-    DeviceState parent_obj;
-
-    /* <public> */
-    void *data;
-    int data_size;
-
-    const RegisterAccessInfo *access;
-
-    void *opaque;
-};
-
-#define TYPE_REGISTER "qemu,register"
-#define REGISTER(obj) OBJECT_CHECK(RegisterInfo, (obj), TYPE_REGISTER)
-
-/**
- * This structure is used to group all of the individual registers which are
- * modeled using the RegisterInfo structure.
- *
- * @r is an aray containing of all the relevent RegisterInfo structures.
- *
- * @num_elements is the number of elements in the array r
- *
- * @mem: optional Memory region for the register
- */
-
-struct RegisterInfoArray {
-    MemoryRegion mem;
-
-    int num_elements;
-    RegisterInfo **r;
-
-    bool debug;
-    const char *prefix;
-};
-
-/**
- * write a value to a register, subject to its restrictions
- * @reg: register to write to
- * @val: value to write
- * @we: write enable mask
- * @prefix: The device prefix that should be printed before the register name
- * @debug: Should the write operation debug information be printed?
- */
-
-void register_write(RegisterInfo *reg, uint64_t val, uint64_t we,
-                    const char *prefix, bool debug);
-
-/**
- * read a value from a register, subject to its restrictions
- * @reg: register to read from
- * @re: read enable mask
- * @prefix: The device prefix that should be printed before the register name
- * @debug: Should the read operation debug information be printed?
- * returns: value read
- */
-
-uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix,
-                       bool debug);
-
-/**
- * reset a register
- * @reg: register to reset
- */
-
-void register_reset(RegisterInfo *reg);
-
-/**
- * Initialize a register.
- * @reg: Register to initialize
- */
-
-void register_init(RegisterInfo *reg);
-
-/**
- * Memory API MMIO write handler that will write to a Register API register.
- * @opaque: RegisterInfo to write to
- * @addr: Address to write
- * @value: Value to write
- * @size: Number of bytes to write
- */
-
-void register_write_memory(void *opaque, hwaddr addr, uint64_t value,
-                           unsigned size);
-
-/**
- * Memory API MMIO read handler that will read from a Register API register.
- * @opaque: RegisterInfo to read from
- * @addr: Address to read
- * @size: Number of bytes to read
- * returns: Value read from register
- */
-
-uint64_t register_read_memory(void *opaque, hwaddr addr, unsigned size);
-
-/**
- * Init a block of registers into a container MemoryRegion. A
- * number of constant register definitions are parsed to create a corresponding
- * array of RegisterInfo's.
- *
- * @owner: device owning the registers
- * @rae: Register definitions to init
- * @num: number of registers to init (length of @rae)
- * @ri: Register array to init, must already be allocated
- * @data: Array to use for register data, must already be allocated
- * @ops: Memory region ops to access registers.
- * @debug enabled: turn on/off verbose debug information
- * returns: A structure containing all of the registers and an initialized
- *          memory region (r_array->mem) the caller should add to a container.
- */
-
-RegisterInfoArray *register_init_block32(DeviceState *owner,
-                                         const RegisterAccessInfo *rae,
-                                         int num, RegisterInfo *ri,
-                                         uint32_t *data,
-                                         const MemoryRegionOps *ops,
-                                         bool debug_enabled,
-                                         uint64_t memory_size);
-
-/**
- * This function should be called to cleanup the registers that were initialized
- * when calling register_init_block32(). This function should only be called
- * from the device's instance_finalize function.
- *
- * Any memory operations that the device performed that require cleanup (such
- * as creating subregions) need to be called before calling this function.
- *
- * @r_array: A structure containing all of the registers, as returned by
- *           register_init_block32()
- */
-
-void register_finalize_block(RegisterInfoArray *r_array);
-
-/* Define constants for a 32 bit register */
-
-/* This macro will define A_FOO, for the byte address of a register
- * as well as R_FOO for the uint32_t[] register number (A_FOO / 4).
- */
-#define REG32(reg, addr)                                                  \
-    enum { A_ ## reg = (addr) };                                          \
-    enum { R_ ## reg = (addr) / 4 };
-
-/* Define SHIFT, LENGTH and MASK constants for a field within a register */
-
-/* This macro will define FOO_BAR_MASK, FOO_BAR_SHIFT and FOO_BAR_LENGTH 
- * constants for field BAR in register FOO.
- */
-#define FIELD(reg, field, shift, length)                                  \
-    enum { R_ ## reg ## _ ## field ## _SHIFT = (shift)};                  \
-    enum { R_ ## reg ## _ ## field ## _LENGTH = (length)};                \
-    enum { R_ ## reg ## _ ## field ## _MASK =                             \
-                                        MAKE_64BIT_MASK(shift, length)};
-
-/* Extract a field from a register */
-#define FIELD_EX32(storage, reg, field)                                   \
-    extract32((storage), R_ ## reg ## _ ## field ## _SHIFT,               \
-              R_ ## reg ## _ ## field ## _LENGTH)
-
-/* Extract a field from an array of registers */
-#define ARRAY_FIELD_EX32(regs, reg, field)                                \
-    FIELD_EX32((regs)[R_ ## reg], reg, field)
-
-/* Deposit a register field.
- * Assigning values larger then the target field will result in
- * compilation warnings.
- */
-#define FIELD_DP32(storage, reg, field, val) ({                           \
-    struct {                                                              \
-        unsigned int v:R_ ## reg ## _ ## field ## _LENGTH;                \
-    } v = { .v = val };                                                   \
-    uint32_t d;                                                           \
-    d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT,           \
-                  R_ ## reg ## _ ## field ## _LENGTH, v.v);               \
-    d; })
-
-/* Deposit a field to array of registers.  */
-#define ARRAY_FIELD_DP32(regs, reg, field, val)                           \
-    (regs)[R_ ## reg] = FIELD_DP32((regs)[R_ ## reg], reg, field, val);
-
-#endif
diff --git a/include/hw/s390x/css-bridge.h b/include/hw/s390x/css-bridge.h
deleted file mode 100644 (file)
index 5a0203b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * virtual css bridge definition
- *
- * Copyright 2012,2016 IBM Corp.
- * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
- *            Pierre Morel <pmorel@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or (at
- * your option) any later version. See the COPYING file in the top-level
- * directory.
- */
-
-#ifndef HW_S390X_CSS_BRIDGE_H
-#define HW_S390X_CSS_BRIDGE_H
-#include "qom/object.h"
-#include "hw/qdev-core.h"
-
-/* virtual css bridge */
-typedef struct VirtualCssBridge {
-    SysBusDevice sysbus_dev;
-    bool css_dev_path;
-} VirtualCssBridge;
-
-#define TYPE_VIRTUAL_CSS_BRIDGE "virtual-css-bridge"
-#define VIRTUAL_CSS_BRIDGE(obj) \
-    OBJECT_CHECK(VirtualCssBridge, (obj), TYPE_VIRTUAL_CSS_BRIDGE)
-
-/* virtual css bus type */
-typedef struct VirtualCssBus {
-    BusState parent_obj;
-} VirtualCssBus;
-
-#define TYPE_VIRTUAL_CSS_BUS "virtual-css-bus"
-#define VIRTUAL_CSS_BUS(obj) \
-     OBJECT_CHECK(VirtualCssBus, (obj), TYPE_VIRTUAL_CSS_BUS)
-VirtualCssBus *virtual_css_bus_init(void);
-
-#endif
index 69a04ca..1d6fde9 100644 (file)
@@ -9,8 +9,8 @@
  *
  */
 
-#ifndef EBCDIC_H
-#define EBCDIC_H
+#ifndef EBCDIC_H_
+#define EBCDIC_H_
 
 /* EBCDIC handling */
 static const uint8_t ebcdic2ascii[] = {
@@ -101,4 +101,4 @@ static inline void ascii_put(uint8_t *p, const char *ebcdic, int len)
     }
 }
 
-#endif /* EBCDIC_H */
+#endif /* EBCDIC_H_ */
index def1bb0..dd88818 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef HW_S390_SCLP_EVENT_FACILITY_H
 #define HW_S390_SCLP_EVENT_FACILITY_H
 
-#include "hw/qdev.h"
+#include <hw/qdev.h>
 #include "qemu/thread.h"
 #include "hw/s390x/sclp.h"
 
index a0c1fc8..ab08332 100644 (file)
@@ -35,10 +35,6 @@ typedef struct S390CcwMachineClass {
     MachineClass parent_class;
 
     /*< public >*/
-    bool ri_allowed;
 } S390CcwMachineClass;
 
-/* runtime-instrumentation allowed by the machine */
-bool ri_allowed(void);
-
 #endif
index 9094eda..200e7e9 100644 (file)
@@ -10,8 +10,8 @@
  * directory.
  */
 
-#ifndef HW_S390_FLIC_H
-#define HW_S390_FLIC_H
+#ifndef __HW_S390_FLIC_H
+#define __HW_S390_FLIC_H
 
 #include "hw/sysbus.h"
 #include "hw/s390x/adapter.h"
@@ -49,8 +49,6 @@ typedef struct S390FLICStateClass {
                           bool do_map);
     int (*add_adapter_routes)(S390FLICState *fs, AdapterRoutes *routes);
     void (*release_adapter_routes)(S390FLICState *fs, AdapterRoutes *routes);
-    int (*clear_io_irq)(S390FLICState *fs, uint16_t subchannel_id,
-                        uint16_t subchannel_nr);
 } S390FLICStateClass;
 
 #define TYPE_KVM_S390_FLIC "s390-flic-kvm"
@@ -78,4 +76,4 @@ static inline DeviceState *s390_flic_kvm_create(void)
 }
 #endif
 
-#endif /* HW_S390_FLIC_H */
+#endif /* __HW_S390_FLIC_H */
index ba28d1d..b0c71b5 100644 (file)
@@ -14,8 +14,8 @@
 #ifndef HW_S390_SCLP_H
 #define HW_S390_SCLP_H
 
-#include "hw/sysbus.h"
-#include "hw/qdev.h"
+#include <hw/sysbus.h>
+#include <hw/qdev.h>
 
 #define SCLP_CMD_CODE_MASK                      0xffff00ff
 
@@ -58,7 +58,6 @@
 #define SCLP_RC_CONTAINED_EQUIPMENT_CHECK       0x0340
 #define SCLP_RC_INSUFFICIENT_SCCB_LENGTH        0x0300
 #define SCLP_RC_STANDBY_READ_COMPLETION         0x0410
-#define SCLP_RC_ADAPTER_IN_RESERVED_STATE       0x05f0
 #define SCLP_RC_ADAPTER_ID_NOT_RECOGNIZED       0x09f0
 #define SCLP_RC_INVALID_FUNCTION                0x40f0
 #define SCLP_RC_NO_EVENT_BUFFERS_STORED         0x60f0
index 62df48e..72b850c 100644 (file)
@@ -9,10 +9,10 @@
  * directory.
  */
 
-#ifndef S390_STORAGE_KEYS_H
-#define S390_STORAGE_KEYS_H
+#ifndef __S390_STORAGE_KEYS_H
+#define __S390_STORAGE_KEYS_H
 
-#include "hw/qdev.h"
+#include <hw/qdev.h>
 #include "monitor/monitor.h"
 
 #define TYPE_S390_SKEYS "s390-skeys"
@@ -57,4 +57,4 @@ S390SKeysState *s390_get_skeys_device(void);
 void hmp_dump_skeys(Monitor *mon, const QDict *qdict);
 void hmp_info_skeys(Monitor *mon, const QDict *qdict);
 
-#endif /* S390_STORAGE_KEYS_H */
+#endif /* __S390_STORAGE_KEYS_H */
index 94d7868..8acd3fa 100644 (file)
@@ -8,10 +8,9 @@
 
 #define MAX_SCSI_DEVS  255
 
-#define SCSI_CMD_BUF_SIZE      16
-#define SCSI_SENSE_LEN         18
-#define SCSI_SENSE_LEN_SCANNER 32
-#define SCSI_INQUIRY_LEN       36
+#define SCSI_CMD_BUF_SIZE     16
+#define SCSI_SENSE_LEN      18
+#define SCSI_INQUIRY_LEN    36
 
 typedef struct SCSIBus SCSIBus;
 typedef struct SCSIBusInfo SCSIBusInfo;
index 79909b2..d5d273a 100644 (file)
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
-#ifndef HW_SD_H
-#define HW_SD_H
-
-#include "hw/qdev.h"
+#ifndef __hw_sd_h
+#define __hw_sd_h              1
 
 #define OUT_OF_RANGE           (1 << 31)
 #define ADDRESS_ERROR          (1 << 30)
@@ -145,4 +142,4 @@ bool sdbus_get_readonly(SDBus *sd);
 void sdbus_set_inserted(SDBus *sd, bool inserted);
 void sdbus_set_readonly(SDBus *sd, bool inserted);
 
-#endif /* HW_SD_H */
+#endif /* __hw_sd_h */
index 070312d..e61de9a 100644 (file)
@@ -3,7 +3,6 @@
 /* Definitions for SH board emulation.  */
 
 #include "hw/sh4/sh_intc.h"
-#include "target-sh4/cpu-qom.h"
 
 #define A7ADDR(x) ((x) & 0x1fffffff)
 #define P4ADDR(x) ((x) | 0xe0000000)
index 7913bc4..b7ddcb0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef SH_INTC_H
-#define SH_INTC_H
+#ifndef __SH_INTC_H__
+#define __SH_INTC_H__
 
 #include "qemu-common.h"
 #include "hw/irq.h"
@@ -80,4 +80,4 @@ int sh_intc_init(MemoryRegion *sysmem,
 
 void sh_intc_set_irl(void *opaque, int n, int level);
 
-#endif /* SH_INTC_H */
+#endif /* __SH_INTC_H__ */
diff --git a/include/hw/smbios/ipmi.h b/include/hw/smbios/ipmi.h
deleted file mode 100644 (file)
index 1c9aae3..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * IPMI SMBIOS firmware handling
- *
- * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef QEMU_SMBIOS_IPMI_H
-#define QEMU_SMBIOS_IPMI_H
-
-void smbios_build_type_38_table(void);
-
-#endif /* QEMU_SMBIOS_IPMI_H */
index 1cd53cc..76ccf70 100644 (file)
@@ -1,6 +1,5 @@
 #ifndef QEMU_SMBIOS_H
 #define QEMU_SMBIOS_H
-
 /*
  * SMBIOS Support
  *
@@ -34,7 +33,7 @@ typedef enum SmbiosEntryPointType {
 
 /* SMBIOS Entry Point
  * There are two types of entry points defined in the SMBIOS specification
- * (see below). BIOS must place the entry point(s) at a 16-byte-aligned
+ * (see below). BIOS must place the entry point(s) at a 16-bit-aligned
  * address between 0xf0000 and 0xfffff. Note that either entry point type
  * can be used in a 64-bit target system, except that SMBIOS 2.1 entry point
  * only allows the SMBIOS struct table to reside below 4GB address space.
@@ -267,4 +266,4 @@ void smbios_get_tables(const struct smbios_phys_mem_area *mem_array,
                        const unsigned int mem_array_size,
                        uint8_t **tables, size_t *tables_len,
                        uint8_t **anchor, size_t *anchor_len);
-#endif /* QEMU_SMBIOS_H */
+#endif /*QEMU_SMBIOS_H */
index afbb9bc..9a0db7b 100644 (file)
@@ -22,8 +22,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef GRLIB_H
-#define GRLIB_H
+#ifndef _GRLIB_H_
+#define _GRLIB_H_
 
 #include "hw/qdev.h"
 #include "hw/sysbus.h"
@@ -117,4 +117,4 @@ DeviceState *grlib_apbuart_create(hwaddr  base,
     return dev;
 }
 
-#endif /* GRLIB_H */
+#endif /* ! _GRLIB_H_ */
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
deleted file mode 100644 (file)
index def3b45..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * ASPEED AST2400 SMC Controller (SPI Flash Only)
- *
- * Copyright (C) 2016 IBM Corp.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef ASPEED_SMC_H
-#define ASPEED_SMC_H
-
-#include "hw/ssi/ssi.h"
-
-typedef struct AspeedSegments {
-    hwaddr addr;
-    uint32_t size;
-} AspeedSegments;
-
-struct AspeedSMCState;
-typedef struct AspeedSMCController {
-    const char *name;
-    uint8_t r_conf;
-    uint8_t r_ce_ctrl;
-    uint8_t r_ctrl0;
-    uint8_t r_timings;
-    uint8_t conf_enable_w0;
-    uint8_t max_slaves;
-    const AspeedSegments *segments;
-    uint32_t mapping_window_size;
-} AspeedSMCController;
-
-typedef struct AspeedSMCFlash {
-    const struct AspeedSMCState *controller;
-
-    uint8_t id;
-    uint32_t size;
-
-    MemoryRegion mmio;
-    DeviceState *flash;
-} AspeedSMCFlash;
-
-#define TYPE_ASPEED_SMC "aspeed.smc"
-#define ASPEED_SMC(obj) OBJECT_CHECK(AspeedSMCState, (obj), TYPE_ASPEED_SMC)
-#define ASPEED_SMC_CLASS(klass) \
-     OBJECT_CLASS_CHECK(AspeedSMCClass, (klass), TYPE_ASPEED_SMC)
-#define ASPEED_SMC_GET_CLASS(obj) \
-     OBJECT_GET_CLASS(AspeedSMCClass, (obj), TYPE_ASPEED_SMC)
-
-typedef struct  AspeedSMCClass {
-    SysBusDevice parent_obj;
-    const AspeedSMCController *ctrl;
-}  AspeedSMCClass;
-
-#define ASPEED_SMC_R_MAX        (0x100 / 4)
-
-typedef struct AspeedSMCState {
-    SysBusDevice parent_obj;
-
-    const AspeedSMCController *ctrl;
-
-    MemoryRegion mmio;
-    MemoryRegion mmio_flash;
-
-    qemu_irq irq;
-    int irqline;
-
-    uint32_t num_cs;
-    qemu_irq *cs_lines;
-
-    SSIBus *spi;
-
-    uint32_t regs[ASPEED_SMC_R_MAX];
-
-    /* depends on the controller type */
-    uint8_t r_conf;
-    uint8_t r_ce_ctrl;
-    uint8_t r_ctrl0;
-    uint8_t r_timings;
-    uint8_t conf_enable_w0;
-
-    AspeedSMCFlash *flashes;
-} AspeedSMCState;
-
-#endif /* ASPEED_SMC_H */
diff --git a/include/hw/ssi/imx_spi.h b/include/hw/ssi/imx_spi.h
deleted file mode 100644 (file)
index 7103953..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * IMX SPI Controller
- *
- * Copyright 2016 Jean-Christophe Dubois <jcd@tribudubois.net>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef IMX_SPI_H
-#define IMX_SPI_H
-
-#include "hw/sysbus.h"
-#include "hw/ssi/ssi.h"
-#include "qemu/bitops.h"
-#include "qemu/fifo32.h"
-
-#define ECSPI_FIFO_SIZE 64
-
-#define ECSPI_RXDATA 0
-#define ECSPI_TXDATA 1
-#define ECSPI_CONREG 2
-#define ECSPI_CONFIGREG 3
-#define ECSPI_INTREG 4
-#define ECSPI_DMAREG 5
-#define ECSPI_STATREG 6
-#define ECSPI_PERIODREG 7
-#define ECSPI_TESTREG 8
-#define ECSPI_MSGDATA 16
-#define ECSPI_MAX 17
-
-/* ECSPI_CONREG */
-#define ECSPI_CONREG_EN (1 << 0)
-#define ECSPI_CONREG_HT (1 << 1)
-#define ECSPI_CONREG_XCH (1 << 2)
-#define ECSPI_CONREG_SMC (1 << 3)
-#define ECSPI_CONREG_CHANNEL_MODE_SHIFT 4
-#define ECSPI_CONREG_CHANNEL_MODE_LENGTH 4
-#define ECSPI_CONREG_DRCTL_SHIFT 16
-#define ECSPI_CONREG_DRCTL_LENGTH 2
-#define ECSPI_CONREG_CHANNEL_SELECT_SHIFT 18
-#define ECSPI_CONREG_CHANNEL_SELECT_LENGTH 2
-#define ECSPI_CONREG_BURST_LENGTH_SHIFT 20
-#define ECSPI_CONREG_BURST_LENGTH_LENGTH 12
-
-/* ECSPI_CONFIGREG */
-#define ECSPI_CONFIGREG_SS_CTL_SHIFT 8
-#define ECSPI_CONFIGREG_SS_CTL_LENGTH 4
-
-/* ECSPI_INTREG */
-#define ECSPI_INTREG_TEEN (1 << 0)
-#define ECSPI_INTREG_TDREN (1 << 1)
-#define ECSPI_INTREG_TFEN (1 << 2)
-#define ECSPI_INTREG_RREN (1 << 3)
-#define ECSPI_INTREG_RDREN (1 << 4)
-#define ECSPI_INTREG_RFEN (1 << 5)
-#define ECSPI_INTREG_ROEN (1 << 6)
-#define ECSPI_INTREG_TCEN (1 << 7)
-
-/* ECSPI_DMAREG */
-#define ECSPI_DMAREG_RXTDEN (1 << 31)
-#define ECSPI_DMAREG_RXDEN (1 << 23)
-#define ECSPI_DMAREG_TEDEN (1 << 7)
-#define ECSPI_DMAREG_RX_THRESHOLD_SHIFT 16
-#define ECSPI_DMAREG_RX_THRESHOLD_LENGTH 6
-
-/* ECSPI_STATREG */
-#define ECSPI_STATREG_TE (1 << 0)
-#define ECSPI_STATREG_TDR (1 << 1)
-#define ECSPI_STATREG_TF (1 << 2)
-#define ECSPI_STATREG_RR (1 << 3)
-#define ECSPI_STATREG_RDR (1 << 4)
-#define ECSPI_STATREG_RF (1 << 5)
-#define ECSPI_STATREG_RO (1 << 6)
-#define ECSPI_STATREG_TC (1 << 7)
-
-#define EXTRACT(value, name) extract32(value, name##_SHIFT, name##_LENGTH)
-
-#define TYPE_IMX_SPI "imx.spi"
-#define IMX_SPI(obj) OBJECT_CHECK(IMXSPIState, (obj), TYPE_IMX_SPI)
-
-typedef struct IMXSPIState {
-    /* <private> */
-    SysBusDevice parent_obj;
-
-    /* <public> */
-    MemoryRegion iomem;
-
-    qemu_irq irq;
-
-    qemu_irq cs_lines[4];
-
-    SSIBus *bus;
-
-    uint32_t regs[ECSPI_MAX];
-
-    Fifo32 rx_fifo;
-    Fifo32 tx_fifo;
-
-    int16_t burst_length;
-} IMXSPIState;
-
-#endif /* IMX_SPI_H */
index 6a0c3c3..4a0a539 100644 (file)
@@ -37,7 +37,7 @@ enum SSICSMode {
 struct SSISlaveClass {
     DeviceClass parent_class;
 
-    void (*realize)(SSISlave *dev, Error **errp);
+    int (*init)(SSISlave *dev);
 
     /* if you have standard or no CS behaviour, just override transfer.
      * This is called when the device cs is active (true by default).
index 06aa096..dbb9eef 100644 (file)
@@ -22,8 +22,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef XILINX_SPIPS_H
-#define XILINX_SPIPS_H
+#ifndef XLNX_SPIPS_H
+#define XLNX_SPIPS_H
 
 #include "hw/ssi/ssi.h"
 #include "qemu/fifo8.h"
@@ -69,4 +69,4 @@ struct XilinxSPIPS {
 #define XILINX_QSPIPS(obj) \
      OBJECT_CHECK(XilinxQSPIPS, (obj), TYPE_XILINX_QSPIPS)
 
-#endif /* XILINX_SPIPS_H */
+#endif /* XLNX_SPIPS_H */
index c370ba0..30ccc56 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef STREAM_H
-#define STREAM_H
+#define STREAM_H 1
 
 #include "qemu-common.h"
 #include "qom/object.h"
index e73a5b2..cc1dba4 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef HW_SYSBUS_H
-#define HW_SYSBUS_H
+#define HW_SYSBUS_H 1
 
 /* Devices attached directly to the main system bus.  */
 
@@ -72,7 +72,7 @@ struct SysBusDevice {
         MemoryRegion *memory;
     } mmio[QDEV_MAX_MMIO];
     int num_pio;
-    uint32_t pio[QDEV_MAX_PIO];
+    pio_addr_t pio[QDEV_MAX_PIO];
 };
 
 typedef int FindSysbusDeviceFunc(SysBusDevice *sbdev, void *opaque);
@@ -81,7 +81,7 @@ void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory);
 MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n);
 void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p);
 void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target);
-void sysbus_init_ioports(SysBusDevice *dev, uint32_t ioport, uint32_t size);
+void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);
 
 
 bool sysbus_has_irq(SysBusDevice *dev, int n);
@@ -118,4 +118,4 @@ static inline DeviceState *sysbus_try_create_simple(const char *name,
     return sysbus_try_create_varargs(name, addr, irq, NULL);
 }
 
-#endif /* HW_SYSBUS_H */
+#endif /* !HW_SYSBUS_H */
index 81c4388..98d8e0a 100644 (file)
@@ -20,8 +20,8 @@
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef A9GTIMER_H
-#define A9GTIMER_H
+#ifndef HW_TIMER_A9_GTIMER_H_H
+#define HW_TIMER_A9_GTIMER_H_H
 
 #include "hw/sysbus.h"
 
@@ -94,4 +94,4 @@ typedef struct A9GTimerUpdate {
     uint64_t new;
 } A9GTimerUpdate;
 
-#endif /* A9GTIMER_H */
+#endif /* #ifdef HW_TIMER_A9_GTIMER_H_H */
index c0cc3e2..770bdc0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ALLWINNER_A10_PIT_H
-#define ALLWINNER_A10_PIT_H
+#ifndef AW_A10_PIT_H
+#define AW_A10_PIT_H
 
 #include "hw/ptimer.h"
 
index bd6c1a7..44dc2f8 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef ASPEED_TIMER_H
 #define ASPEED_TIMER_H
 
-#include "qemu/timer.h"
+#include "hw/ptimer.h"
 
 #define ASPEED_TIMER(obj) \
     OBJECT_CHECK(AspeedTimerCtrlState, (obj), TYPE_ASPEED_TIMER);
@@ -33,16 +33,15 @@ typedef struct AspeedTimer {
     qemu_irq irq;
 
     uint8_t id;
-    QEMUTimer timer;
 
     /**
      * Track the line level as the ASPEED timers implement edge triggered
      * interrupts, signalling with both the rising and falling edge.
      */
     int32_t level;
+    ptimer_state *timer;
     uint32_t reload;
     uint32_t match[2];
-    uint64_t start;
 } AspeedTimer;
 
 typedef struct AspeedTimerCtrlState {
index f04c4d3..f38bcfe 100644 (file)
@@ -10,9 +10,8 @@
  * the COPYING file in the top-level directory.
  *
  */
-
-#ifndef HW_HPET_H
-#define HW_HPET_H
+#ifndef QEMU_HPET_EMUL_H
+#define QEMU_HPET_EMUL_H
 
 #include "qom/object.h"
 
index 5adae9f..4349033 100644 (file)
@@ -37,14 +37,6 @@ typedef struct PITChannelInfo {
     int out;
 } PITChannelInfo;
 
-#define TYPE_PIT_COMMON "pit-common"
-#define PIT_COMMON(obj) \
-     OBJECT_CHECK(PITCommonState, (obj), TYPE_PIT_COMMON)
-#define PIT_COMMON_CLASS(klass) \
-     OBJECT_CLASS_CHECK(PITCommonClass, (klass), TYPE_PIT_COMMON)
-#define PIT_COMMON_GET_CLASS(obj) \
-     OBJECT_GET_CLASS(PITCommonClass, (obj), TYPE_PIT_COMMON)
-
 #define TYPE_I8254 "isa-pit"
 #define TYPE_KVM_I8254 "kvm-pit"
 
@@ -80,4 +72,4 @@ static inline ISADevice *kvm_pit_init(ISABus *bus, int base)
 void pit_set_gate(ISADevice *dev, int channel, int val);
 void pit_get_channel_info(ISADevice *dev, int channel, PITChannelInfo *info);
 
-#endif /* HW_I8254_H */
+#endif /* !HW_I8254_H */
index dc09cc0..61a1bfb 100644 (file)
@@ -57,6 +57,14 @@ typedef struct PITCommonState {
     PITChannelState channels[3];
 } PITCommonState;
 
+#define TYPE_PIT_COMMON "pit-common"
+#define PIT_COMMON(obj) \
+     OBJECT_CHECK(PITCommonState, (obj), TYPE_PIT_COMMON)
+#define PIT_COMMON_CLASS(klass) \
+     OBJECT_CLASS_CHECK(PITCommonClass, (klass), TYPE_PIT_COMMON)
+#define PIT_COMMON_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(PITCommonClass, (obj), TYPE_PIT_COMMON)
+
 typedef struct PITCommonClass {
     ISADeviceClass parent_class;
 
@@ -73,4 +81,4 @@ void pit_get_channel_info_common(PITCommonState *s, PITChannelState *sc,
                                  PITChannelInfo *info);
 void pit_reset_common(PITCommonState *s);
 
-#endif /* QEMU_I8254_INTERNAL_H */
+#endif /* !QEMU_I8254_INTERNAL_H */
index eac59b2..461adbe 100644 (file)
 #define GPT_IR_OF3IE  (1 << 2)
 #define GPT_IR_ROVIE  (1 << 5)
 
-#define TYPE_IMX25_GPT "imx25.gpt"
-#define TYPE_IMX31_GPT "imx31.gpt"
-#define TYPE_IMX6_GPT "imx6.gpt"
-
-#define TYPE_IMX_GPT TYPE_IMX25_GPT
-
+#define TYPE_IMX_GPT "imx.gpt"
 #define IMX_GPT(obj) OBJECT_CHECK(IMXGPTState, (obj), TYPE_IMX_GPT)
 
 typedef struct IMXGPTState{
@@ -108,8 +103,6 @@ typedef struct IMXGPTState{
     uint32_t freq;
 
     qemu_irq irq;
-
-    const IMXClk *clocks;
 } IMXGPTState;
 
 #endif /* IMX_GPT_H */
index db5e43a..3367923 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef HW_M48T59_H
-#define HW_M48T59_H
+#ifndef NVRAM_H
+#define NVRAM_H
 
 #include "qemu-common.h"
 #include "qom/object.h"
@@ -31,4 +31,4 @@ Nvram *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
                    uint32_t io_base, uint16_t size, int base_year,
                    int type);
 
-#endif /* HW_M48T59_H */
+#endif /* !NVRAM_H */
index 7c8e64b..eaf6497 100644 (file)
@@ -10,4 +10,4 @@ ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq);
 void rtc_set_memory(ISADevice *dev, int addr, int val);
 int rtc_get_memory(ISADevice *dev, int addr);
 
-#endif /* MC146818RTC_H */
+#endif /* !MC146818RTC_H */
index 6ede6c8..ccdee42 100644 (file)
@@ -21,9 +21,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
-#ifndef MC146818RTC_REGS_H
-#define MC146818RTC_REGS_H
+#ifndef RTC_REGS_H
+#define RTC_REGS_H
 
 #define RTC_ISA_IRQ 8
 
diff --git a/include/hw/timer/mips_gictimer.h b/include/hw/timer/mips_gictimer.h
deleted file mode 100644 (file)
index c8bc5d2..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2016 Imagination Technologies
- *
- */
-
-#ifndef MIPS_GICTIMER_H
-#define MIPS_GICTIMER_H
-
-typedef struct MIPSGICTimerVPState MIPSGICTimerVPState;
-typedef struct MIPSGICTimerState MIPSGICTimerState;
-
-typedef void MIPSGICTimerCB(void *opaque, uint32_t vp_index);
-
-struct MIPSGICTimerVPState {
-    QEMUTimer *qtimer;
-    uint32_t vp_index;
-    uint32_t comparelo;
-    MIPSGICTimerState *gictimer;
-};
-
-struct MIPSGICTimerState {
-    void *opaque;
-    uint8_t countstop;
-    uint32_t sh_counterlo;
-    int32_t num_vps;
-    MIPSGICTimerVPState *vptimers;
-    MIPSGICTimerCB *cb;
-};
-
-uint32_t mips_gictimer_get_sh_count(MIPSGICTimerState *gic);
-void mips_gictimer_store_sh_count(MIPSGICTimerState *gic, uint64_t count);
-uint32_t mips_gictimer_get_vp_compare(MIPSGICTimerState *gictimer,
-                                      uint32_t vp_index);
-void mips_gictimer_store_vp_compare(MIPSGICTimerState *gic, uint32_t vp_index,
-                                    uint64_t compare);
-uint8_t mips_gictimer_get_countstop(MIPSGICTimerState *gic);
-void mips_gictimer_start_count(MIPSGICTimerState *gic);
-void mips_gictimer_stop_count(MIPSGICTimerState *gic);
-MIPSGICTimerState *mips_gictimer_init(void *opaque, uint32_t nvps,
-                                      MIPSGICTimerCB *cb);
-
-#endif /* MIPS_GICTIMER_H */
index 89ef922..5f13252 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef HW_TRICORE_H
-#define HW_TRICORE_H
+#ifndef TRICORE_MISC_H
+#define TRICORE_MISC_H 1
 
 #include "exec/memory.h"
 #include "hw/irq.h"
index 5a4839f..f37adcb 100644 (file)
@@ -8,7 +8,6 @@
  * published by the Free Software Foundation, or any later version.
  * See the COPYING file in the top-level directory.
  */
-
 #ifndef QEMU_HW_PUV3_H
 #define QEMU_HW_PUV3_H
 
@@ -47,4 +46,4 @@
 #define DPRINTF(fmt, ...) do {} while (0)
 #endif
 
-#endif /* QEMU_HW_PUV3_H */
+#endif /* !QEMU_HW_PUV3_H */
index 847c9de..163fe04 100644 (file)
@@ -235,7 +235,7 @@ struct USBDevice {
     uint8_t addr;
     char product_desc[32];
     int auto_attach;
-    bool attached;
+    int attached;
 
     int32_t state;
     uint8_t setup_buf[8];
@@ -347,7 +347,6 @@ typedef struct USBDeviceClass {
 
     const char *product_desc;
     const USBDesc *usb_desc;
-    bool attached_settable;
 } USBDeviceClass;
 
 typedef struct USBPortOps {
index 3e91b8e..616f1b8 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef HW_USB_EHCI_REGS_H
-#define HW_USB_EHCI_REGS_H
+#define HW_USB_EHCI_REGS_H 1
 
 /* Capability Registers Base Address - section 2.2 */
 #define CAPLENGTH        0x0000  /* 1-byte, 0x0001 reserved */
index fd45d29..c7315c5 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef HW_USB_UHCI_REGS_H
-#define HW_USB_UHCI_REGS_H
+#define HW_USB_UHCI_REGS_H 1
 
 #define UHCI_CMD_FGR      (1 << 4)
 #define UHCI_CMD_EGSM     (1 << 3)
index 94dfae3..eb0e1b0 100644 (file)
@@ -17,7 +17,6 @@
  *  Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com)
  *  Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com)
  */
-
 #ifndef HW_VFIO_VFIO_COMMON_H
 #define HW_VFIO_VFIO_COMMON_H
 
@@ -74,8 +73,6 @@ typedef struct VFIOContainer {
     VFIOAddressSpace *space;
     int fd; /* /dev/vfio/vfio, empowered by the attached groups */
     MemoryListener listener;
-    MemoryListener prereg_listener;
-    unsigned iommu_type;
     int error;
     bool initialized;
     /*
@@ -83,8 +80,9 @@ typedef struct VFIOContainer {
      * contiguous IOVA window.  We may need to generalize that in
      * future
      */
+    hwaddr min_iova, max_iova;
+    uint64_t iova_pgsizes;
     QLIST_HEAD(, VFIOGuestIOMMU) giommu_list;
-    QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list;
     QLIST_HEAD(, VFIOGroup) group_list;
     QLIST_ENTRY(VFIOContainer) next;
 } VFIOContainer;
@@ -92,18 +90,10 @@ typedef struct VFIOContainer {
 typedef struct VFIOGuestIOMMU {
     VFIOContainer *container;
     MemoryRegion *iommu;
-    hwaddr iommu_offset;
     Notifier n;
     QLIST_ENTRY(VFIOGuestIOMMU) giommu_next;
 } VFIOGuestIOMMU;
 
-typedef struct VFIOHostDMAWindow {
-    hwaddr min_iova;
-    hwaddr max_iova;
-    uint64_t iova_pgsizes;
-    QLIST_ENTRY(VFIOHostDMAWindow) hostwin_next;
-} VFIOHostDMAWindow;
-
 typedef struct VFIODeviceOps VFIODeviceOps;
 
 typedef struct VFIODevice {
@@ -164,15 +154,5 @@ extern QLIST_HEAD(vfio_as_head, VFIOAddressSpace) vfio_address_spaces;
 #ifdef CONFIG_LINUX
 int vfio_get_region_info(VFIODevice *vbasedev, int index,
                          struct vfio_region_info **info);
-int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type,
-                             uint32_t subtype, struct vfio_region_info **info);
 #endif
-extern const MemoryListener vfio_prereg_listener;
-
-int vfio_spapr_create_window(VFIOContainer *container,
-                             MemoryRegionSection *section,
-                             hwaddr *pgsize);
-int vfio_spapr_remove_window(VFIOContainer *container,
-                             hwaddr offset_within_address_space);
-
-#endif /* HW_VFIO_VFIO_COMMON_H */
+#endif /* !HW_VFIO_VFIO_COMMON_H */
index 9baaa2d..b468f80 100644 (file)
@@ -74,4 +74,4 @@ typedef struct VFIOPlatformDeviceClass {
 #define VFIO_PLATFORM_DEVICE_GET_CLASS(obj) \
      OBJECT_GET_CLASS(VFIOPlatformDeviceClass, (obj), TYPE_VFIO_PLATFORM)
 
-#endif /* HW_VFIO_VFIO_PLATFORM_H */
+#endif /*HW_VFIO_VFIO_PLATFORM_H*/
index 86248f5..f27d599 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef HW_VFIO_H
-#define HW_VFIO_H
+#ifndef VFIO_API_H
+#define VFIO_API_H
 
 bool vfio_eeh_as_ok(AddressSpace *as);
 int vfio_eeh_as_op(AddressSpace *as, uint32_t op);
index cf7f0b5..95fcc96 100644 (file)
@@ -8,8 +8,9 @@
  *
  */
 
-#ifndef VHOST_BACKEND_H
-#define VHOST_BACKEND_H
+#ifndef VHOST_BACKEND_H_
+#define VHOST_BACKEND_H_
+
 
 typedef enum VhostBackendType {
     VHOST_BACKEND_TYPE_NONE = 0,
@@ -56,8 +57,6 @@ typedef int (*vhost_set_vring_kick_op)(struct vhost_dev *dev,
                                        struct vhost_vring_file *file);
 typedef int (*vhost_set_vring_call_op)(struct vhost_dev *dev,
                                        struct vhost_vring_file *file);
-typedef int (*vhost_set_vring_busyloop_timeout_op)(struct vhost_dev *dev,
-                                                   struct vhost_vring_state *r);
 typedef int (*vhost_set_features_op)(struct vhost_dev *dev,
                                      uint64_t features);
 typedef int (*vhost_get_features_op)(struct vhost_dev *dev,
@@ -92,7 +91,6 @@ typedef struct VhostOps {
     vhost_get_vring_base_op vhost_get_vring_base;
     vhost_set_vring_kick_op vhost_set_vring_kick;
     vhost_set_vring_call_op vhost_set_vring_call;
-    vhost_set_vring_busyloop_timeout_op vhost_set_vring_busyloop_timeout;
     vhost_set_features_op vhost_set_features;
     vhost_get_features_op vhost_get_features;
     vhost_set_owner_op vhost_set_owner;
@@ -109,4 +107,4 @@ extern const VhostOps user_ops;
 int vhost_set_backend_type(struct vhost_dev *dev,
                            VhostBackendType backend_type);
 
-#endif /* VHOST_BACKEND_H */
+#endif /* VHOST_BACKEND_H_ */
index e433089..b60d758 100644 (file)
@@ -64,8 +64,7 @@ struct vhost_dev {
 };
 
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
-                   VhostBackendType backend_type,
-                   uint32_t busyloop_timeout);
+                   VhostBackendType backend_type);
 void vhost_dev_cleanup(struct vhost_dev *hdev);
 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
 void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
@@ -86,8 +85,4 @@ uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
 void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
                         uint64_t features);
 bool vhost_has_free_slot(void);
-
-int vhost_net_set_backend(struct vhost_dev *hdev,
-                          struct vhost_vring_file *file);
-
 #endif
index 440b455..8dc84f5 100644 (file)
  * (at your option) any later version.
  *
  */
-
-#ifndef QEMU_VIRTIO_ACCESS_H
-#define QEMU_VIRTIO_ACCESS_H
-
+#ifndef _QEMU_VIRTIO_ACCESS_H
+#define _QEMU_VIRTIO_ACCESS_H
 #include "hw/virtio/virtio.h"
 #include "exec/address-spaces.h"
 
-#if defined(TARGET_PPC64) || defined(TARGET_ARM)
-#define LEGACY_VIRTIO_IS_BIENDIAN 1
-#endif
-
 static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
 {
-#if defined(LEGACY_VIRTIO_IS_BIENDIAN)
+#if defined(TARGET_IS_BIENDIAN)
     return virtio_is_big_endian(vdev);
 #elif defined(TARGET_WORDS_BIGENDIAN)
     if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
@@ -177,4 +171,4 @@ static inline void virtio_tswap64s(VirtIODevice *vdev, uint64_t *s)
 {
     *s = virtio_tswap64(vdev, *s);
 }
-#endif /* QEMU_VIRTIO_ACCESS_H */
+#endif /* _QEMU_VIRTIO_ACCESS_H */
index 1ea13bd..35f62ac 100644 (file)
@@ -12,8 +12,8 @@
  *
  */
 
-#ifndef QEMU_VIRTIO_BALLOON_H
-#define QEMU_VIRTIO_BALLOON_H
+#ifndef _QEMU_VIRTIO_BALLOON_H
+#define _QEMU_VIRTIO_BALLOON_H
 
 #include "standard-headers/linux/virtio_balloon.h"
 #include "hw/virtio/virtio.h"
index 180bd8d..8f2b056 100644 (file)
@@ -11,8 +11,8 @@
  *
  */
 
-#ifndef QEMU_VIRTIO_BLK_H
-#define QEMU_VIRTIO_BLK_H
+#ifndef _QEMU_VIRTIO_BLK_H
+#define _QEMU_VIRTIO_BLK_H
 
 #include "standard-headers/linux/virtio_blk.h"
 #include "hw/virtio/virtio.h"
@@ -38,7 +38,6 @@ struct VirtIOBlkConf
     uint32_t scsi;
     uint32_t config_wce;
     uint32_t request_merging;
-    uint16_t num_queues;
 };
 
 struct VirtIOBlockDataPlane;
@@ -47,6 +46,7 @@ struct VirtIOBlockReq;
 typedef struct VirtIOBlock {
     VirtIODevice parent_obj;
     BlockBackend *blk;
+    VirtQueue *vq;
     void *rq;
     QEMUBH *bh;
     VirtIOBlkConf conf;
@@ -62,7 +62,6 @@ typedef struct VirtIOBlockReq {
     VirtQueueElement elem;
     int64_t sector_num;
     VirtIOBlock *dev;
-    VirtQueue *vq;
     struct virtio_blk_inhdr *in;
     struct virtio_blk_outhdr out;
     QEMUIOVector qiov;
@@ -80,8 +79,7 @@ typedef struct MultiReqBuffer {
     bool is_write;
 } MultiReqBuffer;
 
-void virtio_blk_init_request(VirtIOBlock *s, VirtQueue *vq,
-                             VirtIOBlockReq *req);
+void virtio_blk_init_request(VirtIOBlock *s, VirtIOBlockReq *req);
 void virtio_blk_free_request(VirtIOBlockReq *req);
 
 void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb);
index f3e5ef3..3f2c136 100644 (file)
@@ -52,6 +52,7 @@ typedef struct VirtioBusClass {
     bool (*has_extra_state)(DeviceState *d);
     bool (*query_guest_notifiers)(DeviceState *d);
     int (*set_guest_notifiers)(DeviceState *d, int nvqs, bool assign);
+    int (*set_host_notifier)(DeviceState *d, int n, bool assigned);
     void (*vmstate_change)(DeviceState *d, bool running);
     /*
      * transport independent init function.
@@ -70,29 +71,6 @@ typedef struct VirtioBusClass {
     void (*device_unplugged)(DeviceState *d);
     int (*query_nvectors)(DeviceState *d);
     /*
-     * ioeventfd handling: if the transport implements ioeventfd_started,
-     * it must implement the other ioeventfd callbacks as well
-     */
-    /* Returns true if the ioeventfd has been started for the device. */
-    bool (*ioeventfd_started)(DeviceState *d);
-    /*
-     * Sets the 'ioeventfd started' state after the ioeventfd has been
-     * started/stopped for the device. err signifies whether an error
-     * had occurred.
-     */
-    void (*ioeventfd_set_started)(DeviceState *d, bool started, bool err);
-    /* Returns true if the ioeventfd has been disabled for the device. */
-    bool (*ioeventfd_disabled)(DeviceState *d);
-    /* Sets the 'ioeventfd disabled' state for the device. */
-    void (*ioeventfd_set_disabled)(DeviceState *d, bool disabled);
-    /*
-     * Assigns/deassigns the ioeventfd backing for the transport on
-     * the device for queue number n. Returns an error value on
-     * failure.
-     */
-    int (*ioeventfd_assign)(DeviceState *d, EventNotifier *notifier,
-                            int n, bool assign);
-    /*
      * Does the transport have variable vring alignment?
      * (ie can it ever call virtio_queue_set_align()?)
      * Note that changing this will break migration for this transport.
@@ -133,11 +111,4 @@ static inline VirtIODevice *virtio_bus_get_device(VirtioBusState *bus)
     return (VirtIODevice *)qdev;
 }
 
-/* Start the ioeventfd. */
-void virtio_bus_start_ioeventfd(VirtioBusState *bus);
-/* Stop the ioeventfd. */
-void virtio_bus_stop_ioeventfd(VirtioBusState *bus);
-/* Switch from/to the generic ioeventfd handler */
-int virtio_bus_set_host_notifier(VirtioBusState *bus, int n, bool assign);
-
 #endif /* VIRTIO_BUS_H */
index 20d1cd6..13b0ab0 100644 (file)
  * See the COPYING file in the top-level directory.
  */
 
-#ifndef HW_VIRTIO_GPU_H
-#define HW_VIRTIO_GPU_H
+#ifndef _QEMU_VIRTIO_VGA_H
+#define _QEMU_VIRTIO_VGA_H
 
 #include "qemu/queue.h"
 #include "ui/qemu-pixman.h"
 #include "ui/console.h"
 #include "hw/virtio/virtio.h"
 #include "hw/pci/pci.h"
-#include "qemu/log.h"
 
 #include "standard-headers/linux/virtio_gpu.h"
 #define TYPE_VIRTIO_GPU "virtio-gpu-device"
 
 #define VIRTIO_ID_GPU 16
 
+#define VIRTIO_GPU_MAX_SCANOUT 4
+
 struct virtio_gpu_simple_resource {
     uint32_t resource_id;
     uint32_t width;
     uint32_t height;
     uint32_t format;
-    uint64_t *addrs;
     struct iovec *iov;
     unsigned int iov_cnt;
     uint32_t scanout_bitmask;
@@ -48,7 +48,6 @@ struct virtio_gpu_scanout {
     int x, y;
     int invalidate;
     uint32_t resource_id;
-    struct virtio_gpu_update_cursor cursor;
     QEMUCursor *current_cursor;
 };
 
@@ -99,8 +98,8 @@ typedef struct VirtIOGPU {
     QTAILQ_HEAD(, virtio_gpu_ctrl_command) cmdq;
     QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq;
 
-    struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
-    struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUTS];
+    struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUT];
+    struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUT];
 
     struct virtio_gpu_conf conf;
     int enabled_output_bitmask;
@@ -108,7 +107,7 @@ typedef struct VirtIOGPU {
 
     bool use_virgl_renderer;
     bool renderer_inited;
-    int renderer_blocked;
+    bool renderer_blocked;
     QEMUTimer *fence_poll;
     QEMUTimer *print_stats;
 
@@ -119,8 +118,6 @@ typedef struct VirtIOGPU {
         uint32_t req_3d;
         uint32_t bytes_3d;
     } stats;
-
-    Error *migration_blocker;
 } VirtIOGPU;
 
 extern const GraphicHwOps virtio_gpu_ops;
@@ -155,7 +152,7 @@ void virtio_gpu_get_display_info(VirtIOGPU *g,
                                  struct virtio_gpu_ctrl_command *cmd);
 int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab,
                                   struct virtio_gpu_ctrl_command *cmd,
-                                  uint64_t **addr, struct iovec **iov);
+                                  struct iovec **iov);
 void virtio_gpu_cleanup_mapping_iov(struct iovec *iov, uint32_t count);
 void virtio_gpu_process_cmdq(VirtIOGPU *g);
 
index 55db310..bddbd4b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef QEMU_VIRTIO_INPUT_H
-#define QEMU_VIRTIO_INPUT_H
+#ifndef _QEMU_VIRTIO_INPUT_H
+#define _QEMU_VIRTIO_INPUT_H
 
 #include "ui/input.h"
 
@@ -105,4 +105,4 @@ void virtio_input_add_config(VirtIOInput *vinput,
 void virtio_input_idstr_config(VirtIOInput *vinput,
                                uint8_t select, const char *string);
 
-#endif /* QEMU_VIRTIO_INPUT_H */
+#endif /* _QEMU_VIRTIO_INPUT_H */
index 91ed97c..0cabdb6 100644 (file)
@@ -11,8 +11,8 @@
  *
  */
 
-#ifndef QEMU_VIRTIO_NET_H
-#define QEMU_VIRTIO_NET_H
+#ifndef _QEMU_VIRTIO_NET_H
+#define _QEMU_VIRTIO_NET_H
 
 #include "standard-headers/linux/virtio_net.h"
 #include "hw/virtio/virtio.h"
index 2d40abd..3f07de7 100644 (file)
@@ -9,8 +9,8 @@
  * top-level directory.
  */
 
-#ifndef QEMU_VIRTIO_RNG_H
-#define QEMU_VIRTIO_RNG_H
+#ifndef _QEMU_VIRTIO_RNG_H
+#define _QEMU_VIRTIO_RNG_H
 
 #include "sysemu/rng.h"
 #include "sysemu/rng-random.h"
@@ -26,7 +26,7 @@ struct VirtIORNGConf {
     RngBackend *rng;
     uint64_t max_bytes;
     uint32_t period_ms;
-    RngRandom *default_backend;
+    RndRandom *default_backend;
 };
 
 typedef struct VirtIORNG {
index a1e0cfb..ba2f5ce 100644 (file)
@@ -11,8 +11,8 @@
  *
  */
 
-#ifndef QEMU_VIRTIO_SCSI_H
-#define QEMU_VIRTIO_SCSI_H
+#ifndef _QEMU_VIRTIO_SCSI_H
+#define _QEMU_VIRTIO_SCSI_H
 
 /* Override CDB/sense data size: they are dynamic (guest controlled) in QEMU */
 #define VIRTIO_SCSI_CDB_SIZE 0
@@ -68,6 +68,13 @@ typedef struct VirtIOSCSICommon {
     VirtQueue **cmd_vqs;
 } VirtIOSCSICommon;
 
+typedef struct VirtIOSCSIBlkChangeNotifier {
+    Notifier n;
+    struct VirtIOSCSI *s;
+    SCSIDevice *sd;
+    QTAILQ_ENTRY(VirtIOSCSIBlkChangeNotifier) next;
+} VirtIOSCSIBlkChangeNotifier;
+
 typedef struct VirtIOSCSI {
     VirtIOSCSICommon parent_obj;
 
@@ -78,10 +85,14 @@ typedef struct VirtIOSCSI {
     /* Fields for dataplane below */
     AioContext *ctx; /* one iothread per virtio-scsi-pci for now */
 
+    QTAILQ_HEAD(, VirtIOSCSIBlkChangeNotifier) insert_notifiers;
+    QTAILQ_HEAD(, VirtIOSCSIBlkChangeNotifier) remove_notifiers;
+
     bool dataplane_started;
     bool dataplane_starting;
     bool dataplane_stopping;
     bool dataplane_fenced;
+    Error *blocker;
     uint32_t host_features;
 } VirtIOSCSI;
 
@@ -121,9 +132,11 @@ typedef struct VirtIOSCSIReq {
     } req;
 } VirtIOSCSIReq;
 
+typedef void (*HandleOutput)(VirtIODevice *, VirtQueue *);
+
 void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
-                                VirtIOHandleOutput ctrl, VirtIOHandleOutput evt,
-                                VirtIOHandleOutput cmd);
+                                HandleOutput ctrl, HandleOutput evt,
+                                HandleOutput cmd);
 
 void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp);
 void virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq);
@@ -139,4 +152,4 @@ void virtio_scsi_dataplane_start(VirtIOSCSI *s);
 void virtio_scsi_dataplane_stop(VirtIOSCSI *s);
 void virtio_scsi_dataplane_notify(VirtIODevice *vdev, VirtIOSCSIReq *req);
 
-#endif /* QEMU_VIRTIO_SCSI_H */
+#endif /* _QEMU_VIRTIO_SCSI_H */
index 730c88d..12a55a1 100644 (file)
@@ -12,9 +12,8 @@
  * the COPYING file in the top-level directory.
  *
  */
-
-#ifndef QEMU_VIRTIO_SERIAL_H
-#define QEMU_VIRTIO_SERIAL_H
+#ifndef _QEMU_VIRTIO_SERIAL_H
+#define _QEMU_VIRTIO_SERIAL_H
 
 #include "standard-headers/linux/virtio_console.h"
 #include "hw/qdev.h"
index d2490c1..6a37065 100644 (file)
@@ -11,8 +11,8 @@
  *
  */
 
-#ifndef QEMU_VIRTIO_H
-#define QEMU_VIRTIO_H
+#ifndef _QEMU_VIRTIO_H
+#define _QEMU_VIRTIO_H
 
 #include "hw/hw.h"
 #include "net/net.h"
@@ -138,13 +138,9 @@ void virtio_cleanup(VirtIODevice *vdev);
 /* Set the child bus name. */
 void virtio_device_set_child_bus_name(VirtIODevice *vdev, char *bus_name);
 
-typedef void (*VirtIOHandleOutput)(VirtIODevice *, VirtQueue *);
-
 VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
-                            VirtIOHandleOutput handle_output);
-
-VirtQueue *virtio_add_queue_aio(VirtIODevice *vdev, int queue_size,
-                                VirtIOHandleOutput handle_output);
+                            void (*handle_output)(VirtIODevice *,
+                                                  VirtQueue *));
 
 void virtio_del_queue(VirtIODevice *vdev, int n);
 
@@ -171,26 +167,6 @@ bool virtio_should_notify(VirtIODevice *vdev, VirtQueue *vq);
 void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
 
 void virtio_save(VirtIODevice *vdev, QEMUFile *f);
-void virtio_vmstate_save(QEMUFile *f, void *opaque, size_t size);
-
-#define VMSTATE_VIRTIO_DEVICE(devname, v, getf, putf) \
-    static const VMStateDescription vmstate_virtio_ ## devname = { \
-        .name = "virtio-" #devname ,          \
-        .minimum_version_id = v,              \
-        .version_id = v,                      \
-        .fields = (VMStateField[]) {          \
-            {                                 \
-                .name = "virtio",             \
-                .info = &(const VMStateInfo) {\
-                        .name = "virtio",     \
-                        .get = getf,          \
-                        .put = putf,          \
-                    },                        \
-                .flags = VMS_SINGLE,          \
-            },                                \
-            VMSTATE_END_OF_LIST()             \
-        }                                     \
-    }
 
 int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id);
 
@@ -267,6 +243,7 @@ void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx);
 void virtio_queue_invalidate_signalled_used(VirtIODevice *vdev, int n);
 VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n);
 uint16_t virtio_get_queue_index(VirtQueue *vq);
+int virtio_queue_get_id(VirtQueue *vq);
 EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq);
 void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
                                                 bool with_irqfd);
index 706d96b..7f3fd45 100644 (file)
@@ -33,4 +33,4 @@ typedef struct DIAG288Class {
                         uint64_t func, uint64_t timeout);
 } DIAG288Class;
 
-#endif /* WDT_DIAG288_H */
+#endif  /* WDT_DIAG288_H */
index a8f3afb..6eb815a 100644 (file)
@@ -1,6 +1,5 @@
 #ifndef QEMU_HW_XEN_H
-#define QEMU_HW_XEN_H
-
+#define QEMU_HW_XEN_H 1
 /*
  * public xen header
  *   stuff needed outside xen-*.c, i.e. interfaces to qemu.
@@ -8,9 +7,8 @@
  *   /usr/include/xen, so it can be included unconditionally.
  */
 
-#include "qemu-common.h"
-#include "exec/cpu-common.h"
 #include "hw/irq.h"
+#include "qemu-common.h"
 
 /* xen-machine.c */
 enum xen_mode {
@@ -39,11 +37,12 @@ qemu_irq *xen_interrupt_controller_init(void);
 
 void xenstore_store_pv_console_info(int i, struct CharDriverState *chr);
 
+#if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY)
 void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory);
-
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
                    struct MemoryRegion *mr, Error **errp);
 void xen_modified_memory(ram_addr_t start, ram_addr_t length);
+#endif
 
 void xen_register_framebuffer(struct MemoryRegion *mr);
 
index 0df282a..c839eeb 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef QEMU_HW_XEN_BACKEND_H
-#define QEMU_HW_XEN_BACKEND_H
+#define QEMU_HW_XEN_BACKEND_H 1
 
 #include "hw/xen/xen_common.h"
 #include "sysemu/sysemu.h"
@@ -28,7 +28,6 @@ struct XenDevOps {
     int       (*free)(struct XenDevice *xendev);
     void      (*backend_changed)(struct XenDevice *xendev, const char *node);
     void      (*frontend_changed)(struct XenDevice *xendev, const char *node);
-    int       (*backend_register)(void);
 };
 
 struct XenDevice {
@@ -61,10 +60,8 @@ extern xc_interface *xen_xc;
 extern xenforeignmemory_handle *xen_fmem;
 extern struct xs_handle *xenstore;
 extern const char *xen_protocol;
-extern DeviceState *xen_sysdev;
 
 /* xenstore helper functions */
-int xenstore_mkdir(char *path, int p);
 int xenstore_write_str(const char *base, const char *node, const char *val);
 int xenstore_write_int(const char *base, const char *node, int ival);
 int xenstore_write_int64(const char *base, const char *node, int64_t ival);
@@ -87,7 +84,6 @@ void xen_be_check_state(struct XenDevice *xendev);
 
 /* xen backend driver bits */
 int xen_be_init(void);
-void xen_be_register_common(void);
 int xen_be_register(const char *type, struct XenDevOps *ops);
 int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state);
 int xen_be_bind_evtchn(struct XenDevice *xendev);
@@ -102,9 +98,6 @@ extern struct XenDevOps xen_kbdmouse_ops;     /* xen_framebuffer.c */
 extern struct XenDevOps xen_framebuffer_ops;  /* xen_framebuffer.c */
 extern struct XenDevOps xen_blkdev_ops;       /* xen_disk.c        */
 extern struct XenDevOps xen_netdev_ops;       /* xen_nic.c         */
-#ifdef CONFIG_USB_LIBUSB
-extern struct XenDevOps xen_usb_ops;          /* xen-usb.c         */
-#endif
 
 void xen_init_display(int domid);
 
index bd39287..7b52e8f 100644 (file)
@@ -1,5 +1,7 @@
 #ifndef QEMU_HW_XEN_COMMON_H
-#define QEMU_HW_XEN_COMMON_H
+#define QEMU_HW_XEN_COMMON_H 1
+
+
 
 /*
  * If we have new enough libxenctrl then we do not want/need these compat
@@ -47,8 +49,6 @@ typedef xc_gnttab xengnttab_handle;
 #define xengnttab_unmap(h, a, n) xc_gnttab_munmap(h, a, n)
 #define xengnttab_map_grant_refs(h, c, d, r, p) \
     xc_gnttab_map_grant_refs(h, c, d, r, p)
-#define xengnttab_map_domain_grant_refs(h, c, d, r, p) \
-    xc_gnttab_map_domain_grant_refs(h, c, d, r, p)
 
 #define xenforeignmemory_open(l, f) xen_xc
 
@@ -107,44 +107,6 @@ static inline int xen_get_vmport_regs_pfn(xc_interface *xc, domid_t dom,
 
 #endif
 
-static inline int xen_get_default_ioreq_server_info(xc_interface *xc,
-                                                    domid_t dom,
-                                                    xen_pfn_t *ioreq_pfn,
-                                                    xen_pfn_t *bufioreq_pfn,
-                                                    evtchn_port_t
-                                                        *bufioreq_evtchn)
-{
-    unsigned long param;
-    int rc;
-
-    rc = xc_get_hvm_param(xc, dom, HVM_PARAM_IOREQ_PFN, &param);
-    if (rc < 0) {
-        fprintf(stderr, "failed to get HVM_PARAM_IOREQ_PFN\n");
-        return -1;
-    }
-
-    *ioreq_pfn = param;
-
-    rc = xc_get_hvm_param(xc, dom, HVM_PARAM_BUFIOREQ_PFN, &param);
-    if (rc < 0) {
-        fprintf(stderr, "failed to get HVM_PARAM_BUFIOREQ_PFN\n");
-        return -1;
-    }
-
-    *bufioreq_pfn = param;
-
-    rc = xc_get_hvm_param(xc, dom, HVM_PARAM_BUFIOREQ_EVTCHN,
-                          &param);
-    if (rc < 0) {
-        fprintf(stderr, "failed to get HVM_PARAM_BUFIOREQ_EVTCHN\n");
-        return -1;
-    }
-
-    *bufioreq_evtchn = param;
-
-    return 0;
-}
-
 /* Xen before 4.5 */
 #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 450
 
@@ -192,9 +154,10 @@ static inline void xen_unmap_pcidev(xc_interface *xc, domid_t dom,
 {
 }
 
-static inline void xen_create_ioreq_server(xc_interface *xc, domid_t dom,
-                                           ioservid_t *ioservid)
+static inline int xen_create_ioreq_server(xc_interface *xc, domid_t dom,
+                                          ioservid_t *ioservid)
 {
+    return 0;
 }
 
 static inline void xen_destroy_ioreq_server(xc_interface *xc, domid_t dom,
@@ -208,8 +171,35 @@ static inline int xen_get_ioreq_server_info(xc_interface *xc, domid_t dom,
                                             xen_pfn_t *bufioreq_pfn,
                                             evtchn_port_t *bufioreq_evtchn)
 {
-    return xen_get_default_ioreq_server_info(xc, dom, ioreq_pfn, bufioreq_pfn,
-                                             bufioreq_evtchn);
+    unsigned long param;
+    int rc;
+
+    rc = xc_get_hvm_param(xc, dom, HVM_PARAM_IOREQ_PFN, &param);
+    if (rc < 0) {
+        fprintf(stderr, "failed to get HVM_PARAM_IOREQ_PFN\n");
+        return -1;
+    }
+
+    *ioreq_pfn = param;
+
+    rc = xc_get_hvm_param(xc, dom, HVM_PARAM_BUFIOREQ_PFN, &param);
+    if (rc < 0) {
+        fprintf(stderr, "failed to get HVM_PARAM_BUFIOREQ_PFN\n");
+        return -1;
+    }
+
+    *bufioreq_pfn = param;
+
+    rc = xc_get_hvm_param(xc, dom, HVM_PARAM_BUFIOREQ_EVTCHN,
+                          &param);
+    if (rc < 0) {
+        fprintf(stderr, "failed to get HVM_PARAM_BUFIOREQ_EVTCHN\n");
+        return -1;
+    }
+
+    *bufioreq_evtchn = param;
+
+    return 0;
 }
 
 static inline int xen_set_ioreq_server_state(xc_interface *xc, domid_t dom,
@@ -222,8 +212,6 @@ static inline int xen_set_ioreq_server_state(xc_interface *xc, domid_t dom,
 /* Xen 4.5 */
 #else
 
-static bool use_default_ioreq_server;
-
 static inline void xen_map_memory_section(xc_interface *xc, domid_t dom,
                                           ioservid_t ioservid,
                                           MemoryRegionSection *section)
@@ -232,10 +220,6 @@ static inline void xen_map_memory_section(xc_interface *xc, domid_t dom,
     ram_addr_t size = int128_get64(section->size);
     hwaddr end_addr = start_addr + size - 1;
 
-    if (use_default_ioreq_server) {
-        return;
-    }
-
     trace_xen_map_mmio_range(ioservid, start_addr, end_addr);
     xc_hvm_map_io_range_to_ioreq_server(xc, dom, ioservid, 1,
                                         start_addr, end_addr);
@@ -249,11 +233,6 @@ static inline void xen_unmap_memory_section(xc_interface *xc, domid_t dom,
     ram_addr_t size = int128_get64(section->size);
     hwaddr end_addr = start_addr + size - 1;
 
-    if (use_default_ioreq_server) {
-        return;
-    }
-
-
     trace_xen_unmap_mmio_range(ioservid, start_addr, end_addr);
     xc_hvm_unmap_io_range_from_ioreq_server(xc, dom, ioservid, 1,
                                             start_addr, end_addr);
@@ -267,11 +246,6 @@ static inline void xen_map_io_section(xc_interface *xc, domid_t dom,
     ram_addr_t size = int128_get64(section->size);
     hwaddr end_addr = start_addr + size - 1;
 
-    if (use_default_ioreq_server) {
-        return;
-    }
-
-
     trace_xen_map_portio_range(ioservid, start_addr, end_addr);
     xc_hvm_map_io_range_to_ioreq_server(xc, dom, ioservid, 0,
                                         start_addr, end_addr);
@@ -285,10 +259,6 @@ static inline void xen_unmap_io_section(xc_interface *xc, domid_t dom,
     ram_addr_t size = int128_get64(section->size);
     hwaddr end_addr = start_addr + size - 1;
 
-    if (use_default_ioreq_server) {
-        return;
-    }
-
     trace_xen_unmap_portio_range(ioservid, start_addr, end_addr);
     xc_hvm_unmap_io_range_from_ioreq_server(xc, dom, ioservid, 0,
                                             start_addr, end_addr);
@@ -298,10 +268,6 @@ static inline void xen_map_pcidev(xc_interface *xc, domid_t dom,
                                   ioservid_t ioservid,
                                   PCIDevice *pci_dev)
 {
-    if (use_default_ioreq_server) {
-        return;
-    }
-
     trace_xen_map_pcidev(ioservid, pci_bus_num(pci_dev->bus),
                          PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
     xc_hvm_map_pcidev_to_ioreq_server(xc, dom, ioservid,
@@ -314,10 +280,6 @@ static inline void xen_unmap_pcidev(xc_interface *xc, domid_t dom,
                                     ioservid_t ioservid,
                                     PCIDevice *pci_dev)
 {
-    if (use_default_ioreq_server) {
-        return;
-    }
-
     trace_xen_unmap_pcidev(ioservid, pci_bus_num(pci_dev->bus),
                            PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
     xc_hvm_unmap_pcidev_from_ioreq_server(xc, dom, ioservid,
@@ -326,29 +288,22 @@ static inline void xen_unmap_pcidev(xc_interface *xc, domid_t dom,
                                           PCI_FUNC(pci_dev->devfn));
 }
 
-static inline void xen_create_ioreq_server(xc_interface *xc, domid_t dom,
-                                           ioservid_t *ioservid)
+static inline int xen_create_ioreq_server(xc_interface *xc, domid_t dom,
+                                          ioservid_t *ioservid)
 {
     int rc = xc_hvm_create_ioreq_server(xc, dom, HVM_IOREQSRV_BUFIOREQ_ATOMIC,
                                         ioservid);
 
     if (rc == 0) {
         trace_xen_ioreq_server_create(*ioservid);
-        return;
     }
 
-    *ioservid = 0;
-    use_default_ioreq_server = true;
-    trace_xen_default_ioreq_server();
+    return rc;
 }
 
 static inline void xen_destroy_ioreq_server(xc_interface *xc, domid_t dom,
                                             ioservid_t ioservid)
 {
-    if (use_default_ioreq_server) {
-        return;
-    }
-
     trace_xen_ioreq_server_destroy(ioservid);
     xc_hvm_destroy_ioreq_server(xc, dom, ioservid);
 }
@@ -359,12 +314,6 @@ static inline int xen_get_ioreq_server_info(xc_interface *xc, domid_t dom,
                                             xen_pfn_t *bufioreq_pfn,
                                             evtchn_port_t *bufioreq_evtchn)
 {
-    if (use_default_ioreq_server) {
-        return xen_get_default_ioreq_server_info(xc, dom, ioreq_pfn,
-                                                 bufioreq_pfn,
-                                                 bufioreq_evtchn);
-    }
-
     return xc_hvm_get_ioreq_server_info(xc, dom, ioservid,
                                         ioreq_pfn, bufioreq_pfn,
                                         bufioreq_evtchn);
@@ -374,10 +323,6 @@ static inline int xen_set_ioreq_server_state(xc_interface *xc, domid_t dom,
                                              ioservid_t ioservid,
                                              bool enable)
 {
-    if (use_default_ioreq_server) {
-        return 0;
-    }
-
     trace_xen_ioreq_server_state(ioservid, enable);
     return xc_hvm_set_ioreq_server_state(xc, dom, ioservid, enable);
 }
index 3f4b3f2..65c498b 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QIO_CHANNEL_BUFFER_H
-#define QIO_CHANNEL_BUFFER_H
+#ifndef QIO_CHANNEL_BUFFER_H__
+#define QIO_CHANNEL_BUFFER_H__
 
 #include "io/channel.h"
 
@@ -57,4 +57,4 @@ struct QIOChannelBuffer {
 QIOChannelBuffer *
 qio_channel_buffer_new(size_t capacity);
 
-#endif /* QIO_CHANNEL_BUFFER_H */
+#endif /* QIO_CHANNEL_BUFFER_H__ */
index 336d47f..cfc177e 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QIO_CHANNEL_COMMAND_H
-#define QIO_CHANNEL_COMMAND_H
+#ifndef QIO_CHANNEL_COMMAND_H__
+#define QIO_CHANNEL_COMMAND_H__
 
 #include "io/channel.h"
 
@@ -88,4 +88,4 @@ qio_channel_command_new_spawn(const char *const argv[],
                               Error **errp);
 
 
-#endif /* QIO_CHANNEL_COMMAND_H */
+#endif /* QIO_CHANNEL_COMMAND_H__ */
index d2462c2..308e6d4 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QIO_CHANNEL_FILE_H
-#define QIO_CHANNEL_FILE_H
+#ifndef QIO_CHANNEL_FILE_H__
+#define QIO_CHANNEL_FILE_H__
 
 #include "io/channel.h"
 
@@ -90,4 +90,4 @@ qio_channel_file_new_path(const char *path,
                           mode_t mode,
                           Error **errp);
 
-#endif /* QIO_CHANNEL_FILE_H */
+#endif /* QIO_CHANNEL_FILE_H__ */
index 711f8bf..70d06b4 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QIO_CHANNEL_SOCKET_H
-#define QIO_CHANNEL_SOCKET_H
+#ifndef QIO_CHANNEL_SOCKET_H__
+#define QIO_CHANNEL_SOCKET_H__
 
 #include "io/channel.h"
 #include "io/task.h"
@@ -248,4 +248,4 @@ qio_channel_socket_accept(QIOChannelSocket *ioc,
                           Error **errp);
 
 
-#endif /* QIO_CHANNEL_SOCKET_H */
+#endif /* QIO_CHANNEL_SOCKET_H__ */
index d157eb1..322eccb 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QIO_CHANNEL_TLS_H
-#define QIO_CHANNEL_TLS_H
+#ifndef QIO_CHANNEL_TLS_H__
+#define QIO_CHANNEL_TLS_H__
 
 #include "io/channel.h"
 #include "io/task.h"
@@ -139,4 +139,4 @@ void qio_channel_tls_handshake(QIOChannelTLS *ioc,
 QCryptoTLSSession *
 qio_channel_tls_get_session(QIOChannelTLS *ioc);
 
-#endif /* QIO_CHANNEL_TLS_H */
+#endif /* QIO_CHANNEL_TLS_H__ */
index c0b79cf..c93af82 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QIO_CHANNEL_UTIL_H
-#define QIO_CHANNEL_UTIL_H
+#ifndef QIO_CHANNEL_UTIL_H__
+#define QIO_CHANNEL_UTIL_H__
 
 #include "io/channel.h"
 
@@ -49,4 +49,4 @@
 QIOChannel *qio_channel_new_fd(int fd,
                                Error **errp);
 
-#endif /* QIO_CHANNEL_UTIL_H */
+#endif /* QIO_CHANNEL_UTIL_H__ */
index 63bc4ae..76d7642 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QIO_CHANNEL_WATCH_H
-#define QIO_CHANNEL_WATCH_H
+#ifndef QIO_CHANNEL_WATCH_H__
+#define QIO_CHANNEL_WATCH_H__
 
 #include "io/channel.h"
 
@@ -87,4 +87,4 @@ GSource *qio_channel_create_fd_pair_watch(QIOChannel *ioc,
                                           int fdwrite,
                                           GIOCondition condition);
 
-#endif /* QIO_CHANNEL_WATCH_H */
+#endif /* QIO_CHANNEL_WATCH_H__ */
index 3c9ff84..0dc21cc 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QIO_CHANNEL_WEBSOCK_H
-#define QIO_CHANNEL_WEBSOCK_H
+#ifndef QIO_CHANNEL_WEBSOCK_H__
+#define QIO_CHANNEL_WEBSOCK_H__
 
 #include "io/channel.h"
 #include "qemu/buffer.h"
@@ -105,4 +105,4 @@ void qio_channel_websock_handshake(QIOChannelWebsock *ioc,
                                    gpointer opaque,
                                    GDestroyNotify destroy);
 
-#endif /* QIO_CHANNEL_WEBSOCK_H */
+#endif /* QIO_CHANNEL_WEBSOCK_H__ */
index 752e89f..d37acd2 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QIO_CHANNEL_H
-#define QIO_CHANNEL_H
+#ifndef QIO_CHANNEL_H__
+#define QIO_CHANNEL_H__
 
 #include "qemu-common.h"
 #include "qom/object.h"
@@ -42,7 +42,6 @@ typedef enum QIOChannelFeature QIOChannelFeature;
 enum QIOChannelFeature {
     QIO_CHANNEL_FEATURE_FD_PASS  = (1 << 0),
     QIO_CHANNEL_FEATURE_SHUTDOWN = (1 << 1),
-    QIO_CHANNEL_FEATURE_LISTEN   = (1 << 2),
 };
 
 
@@ -502,4 +501,4 @@ void qio_channel_yield(QIOChannel *ioc,
 void qio_channel_wait(QIOChannel *ioc,
                       GIOCondition condition);
 
-#endif /* QIO_CHANNEL_H */
+#endif /* QIO_CHANNEL_H__ */
index 42028cb..a993212 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QIO_TASK_H
-#define QIO_TASK_H
+#ifndef QIO_TASK_H__
+#define QIO_TASK_H__
 
 #include "qemu-common.h"
 #include "qom/object.h"
@@ -159,7 +159,7 @@ typedef int (*QIOTaskWorker)(QIOTask *task,
  *      QIOTask *task;
  *      SocketAddress *addrCopy;
  *
- *      addrCopy = QAPI_CLONE(SocketAddress, addr);
+ *      qapi_copy_SocketAddress(&addrCopy, addr);
  *      task = qio_task_new(OBJECT(obj), func, opaque, notify);
  *
  *      qio_task_run_in_thread(task, myobject_listen_worker,
@@ -252,4 +252,4 @@ void qio_task_abort(QIOTask *task,
  */
 Object *qio_task_get_source(QIOTask *task);
 
-#endif /* QIO_TASK_H */
+#endif /* QIO_TASK_H__ */
index cea6e42..01365e2 100644 (file)
@@ -50,9 +50,8 @@
 /*                                                                   */
 /* ------------------------------------------------------------------ */
 
-#ifndef DECCONTEXT_H
-#define DECCONTEXT_H
-
+#if !defined(DECCONTEXT)
+  #define DECCONTEXT
   #define DECCNAME     "decContext"                    /* Short name */
   #define DECCFULLNAME "Decimal Context Descriptor"   /* Verbose name */
   #define DECCAUTHOR   "Mike Cowlishaw"                      /* Who to blame */
index aa115fe..9fa4e6a 100644 (file)
 /* Decimal Number arithmetic module header                           */
 /* ------------------------------------------------------------------ */
 
-#ifndef DECNUMBER_H
-#define DECNUMBER_H
-
+#if !defined(DECNUMBER)
+  #define DECNUMBER
   #define DECNAME     "decNumber"                      /* Short name */
   #define DECFULLNAME "Decimal Number Module"        /* Verbose name */
   #define DECAUTHOR   "Mike Cowlishaw"               /* Who to blame */
 
-  #include "libdecnumber/decContext.h"
+  #if !defined(DECCONTEXT)
+    #include "libdecnumber/decContext.h"
+  #endif
 
   /* Bit settings for decNumber.bits                                 */
   #define DECNEG    0x80      /* Sign; 1=negative, 0=positive or zero */
index 12cf1d8..94fb512 100644 (file)
@@ -37,9 +37,8 @@
 /* decNumber.h or one of decDouble (etc.) must be included first.     */
 /* ------------------------------------------------------------------ */
 
-#ifndef DECNUMBERLOCAL_H
-#define DECNUMBERLOCAL_H
-
+#if !defined(DECNUMBERLOC)
+  #define DECNUMBERLOC
   #define DECVERSION   "decNumber 3.53" /* Package Version [16 max.] */
   #define DECNLAUTHOR  "Mike Cowlishaw"              /* Who to blame */
 
   /* [end of format-dependent macros and constants]                  */
   #endif
 
+#else
+  #error decNumberLocal included more than once
 #endif
index aff261e..7d9ee24 100644 (file)
@@ -32,9 +32,8 @@
 /* Decimal 128-bit format module header                                      */
 /* ------------------------------------------------------------------ */
 
-#ifndef DECIMAL128_H
-#define DECIMAL128_H
-
+#if !defined(DECIMAL128)
+  #define DECIMAL128
   #define DEC128NAME    "decimal128"                 /* Short name   */
   #define DEC128FULLNAME "Decimal 128-bit Number"     /* Verbose name */
   #define DEC128AUTHOR  "Mike Cowlishaw"             /* Who to blame */
@@ -60,7 +59,9 @@
   #ifndef DECNUMDIGITS
     #define DECNUMDIGITS DECIMAL128_Pmax /* size if not already defined*/
   #endif
-  #include "libdecnumber/decNumber.h"
+  #ifndef DECNUMBER
+    #include "libdecnumber/decNumber.h"
+  #endif
 
   /* Decimal 128-bit type, accessible by bytes                       */
   typedef struct {
index 6cb9e43..de313e0 100644 (file)
@@ -32,9 +32,8 @@
 /* Decimal 32-bit format module header                               */
 /* ------------------------------------------------------------------ */
 
-#ifndef DECIMAL32_H
-#define DECIMAL32_H
-
+#if !defined(DECIMAL32)
+  #define DECIMAL32
   #define DEC32NAME    "decimal32"                   /* Short name   */
   #define DEC32FULLNAME "Decimal 32-bit Number"              /* Verbose name */
   #define DEC32AUTHOR  "Mike Cowlishaw"              /* Who to blame */
@@ -60,7 +59,9 @@
   #ifndef DECNUMDIGITS
     #define DECNUMDIGITS DECIMAL32_Pmax /* size if not already defined*/
   #endif
-  #include "libdecnumber/decNumber.h"
+  #ifndef DECNUMBER
+    #include "libdecnumber/decNumber.h"
+  #endif
 
   /* Decimal 32-bit type, accessible by bytes */
   typedef struct {
index f29e570..2f6c049 100644 (file)
@@ -32,9 +32,8 @@
 /* Decimal 64-bit format module header                               */
 /* ------------------------------------------------------------------ */
 
-#ifndef DECIMAL64_H
-#define DECIMAL64_H
-
+#if !defined(DECIMAL64)
+  #define DECIMAL64
   #define DEC64NAME    "decimal64"                   /* Short name   */
   #define DEC64FULLNAME "Decimal 64-bit Number"              /* Verbose name */
   #define DEC64AUTHOR  "Mike Cowlishaw"              /* Who to blame */
@@ -62,7 +61,9 @@
   #ifndef DECNUMDIGITS
     #define DECNUMDIGITS DECIMAL64_Pmax /* size if not already defined*/
   #endif
-  #include "libdecnumber/decNumber.h"
+  #ifndef DECNUMBER
+    #include "libdecnumber/decNumber.h"
+  #endif
 
   /* Decimal 64-bit type, accessible by bytes                        */
   typedef struct {
index 41a1ac8..ffa8ac0 100644 (file)
@@ -11,8 +11,8 @@
  *
  */
 
-#ifndef MIGRATION_BLOCK_H
-#define MIGRATION_BLOCK_H
+#ifndef BLOCK_MIGRATION_H
+#define BLOCK_MIGRATION_H
 
 void blk_mig_init(void);
 int blk_mig_active(void);
@@ -20,4 +20,4 @@ uint64_t blk_mig_bytes_transferred(void);
 uint64_t blk_mig_bytes_remaining(void);
 uint64_t blk_mig_bytes_total(void);
 
-#endif /* MIGRATION_BLOCK_H */
+#endif /* BLOCK_MIGRATION_H */
diff --git a/include/migration/cpu.h b/include/migration/cpu.h
deleted file mode 100644 (file)
index f3abbab..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Declarations for use for CPU state serialization.  */
-#ifndef MIGRATION_CPU_H
-#define MIGRATION_CPU_H
-
-#if TARGET_LONG_BITS == 64
-#define qemu_put_betl qemu_put_be64
-#define qemu_get_betl qemu_get_be64
-#define qemu_put_betls qemu_put_be64s
-#define qemu_get_betls qemu_get_be64s
-#define qemu_put_sbetl qemu_put_sbe64
-#define qemu_get_sbetl qemu_get_sbe64
-#define qemu_put_sbetls qemu_put_sbe64s
-#define qemu_get_sbetls qemu_get_sbe64s
-
-#define VMSTATE_UINTTL_V(_f, _s, _v)                                  \
-    VMSTATE_UINT64_V(_f, _s, _v)
-#define VMSTATE_UINTTL_EQUAL_V(_f, _s, _v)                            \
-    VMSTATE_UINT64_EQUAL_V(_f, _s, _v)
-#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v)                        \
-    VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v)
-#define vmstate_info_uinttl vmstate_info_uint64
-#else
-#define qemu_put_betl qemu_put_be32
-#define qemu_get_betl qemu_get_be32
-#define qemu_put_betls qemu_put_be32s
-#define qemu_get_betls qemu_get_be32s
-#define qemu_put_sbetl qemu_put_sbe32
-#define qemu_get_sbetl qemu_get_sbe32
-#define qemu_put_sbetls qemu_put_sbe32s
-#define qemu_get_sbetls qemu_get_sbe32s
-
-#define VMSTATE_UINTTL_V(_f, _s, _v)                                  \
-    VMSTATE_UINT32_V(_f, _s, _v)
-#define VMSTATE_UINTTL_EQUAL_V(_f, _s, _v)                            \
-    VMSTATE_UINT32_EQUAL_V(_f, _s, _v)
-#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v)                        \
-    VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v)
-#define vmstate_info_uinttl vmstate_info_uint32
-#endif
-
-#define VMSTATE_UINTTL(_f, _s)                                        \
-    VMSTATE_UINTTL_V(_f, _s, 0)
-#define VMSTATE_UINTTL_EQUAL(_f, _s)                                  \
-    VMSTATE_UINTTL_EQUAL_V(_f, _s, 0)
-#define VMSTATE_UINTTL_ARRAY(_f, _s, _n)                              \
-    VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, 0)
-
-#endif
index 3c96623..9e36a97 100644 (file)
@@ -135,12 +135,9 @@ struct MigrationState
     QemuThread thread;
     QEMUBH *cleanup_bh;
     QEMUFile *to_dst_file;
-
-    /* New style params from 'migrate-set-parameters' */
-    MigrationParameters parameters;
+    int parameters[MIGRATION_PARAMETER__MAX];
 
     int state;
-    /* Old style params from 'migrate' command */
     MigrationParams params;
 
     /* State related to return path */
@@ -160,8 +157,6 @@ struct MigrationState
     int64_t xbzrle_cache_size;
     int64_t setup_time;
     int64_t dirty_sync_count;
-    /* Count of requests incoming from destination */
-    int64_t postcopy_requests;
 
     /* Flag set once the migration has been asked to enter postcopy */
     bool start_postcopy;
@@ -176,33 +171,14 @@ struct MigrationState
     QSIMPLEQ_HEAD(src_page_requests, MigrationSrcPageRequest) src_page_requests;
     /* The RAMBlock used in the last src_page_request */
     RAMBlock *last_req_rb;
-
-    /* The last error that occurred */
-    Error *error;
 };
 
 void migrate_set_state(int *state, int old_state, int new_state);
 
-void migration_fd_process_incoming(QEMUFile *f);
+void process_incoming_migration(QEMUFile *f);
 
 void qemu_start_incoming_migration(const char *uri, Error **errp);
 
-void migration_channel_process_incoming(MigrationState *s,
-                                        QIOChannel *ioc);
-
-void migration_tls_channel_process_incoming(MigrationState *s,
-                                            QIOChannel *ioc,
-                                            Error **errp);
-
-void migration_channel_connect(MigrationState *s,
-                               QIOChannel *ioc,
-                               const char *hostname);
-
-void migration_tls_channel_connect(MigrationState *s,
-                                   QIOChannel *ioc,
-                                   const char *hostname,
-                                   Error **errp);
-
 uint64_t migrate_max_downtime(void);
 
 void exec_start_incoming_migration(const char *host_port, Error **errp);
@@ -225,7 +201,7 @@ void rdma_start_outgoing_migration(void *opaque, const char *host_port, Error **
 
 void rdma_start_incoming_migration(const char *host_port, Error **errp);
 
-void migrate_fd_error(MigrationState *s, const Error *error);
+void migrate_fd_error(MigrationState *s);
 
 void migrate_fd_connect(MigrationState *s);
 
index abedd46..3f6b4ed 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
 #ifndef QEMU_FILE_H
-#define QEMU_FILE_H
-
-#include "qemu-common.h"
+#define QEMU_FILE_H 1
 #include "exec/cpu-common.h"
-#include "io/channel.h"
 
 
+/* This function writes a chunk of data to a file at the given position.
+ * The pos argument can be ignored if the file is only being used for
+ * streaming.  The handler should try to write all of the data it can.
+ */
+typedef ssize_t (QEMUFilePutBufferFunc)(void *opaque, const uint8_t *buf,
+                                        int64_t pos, size_t size);
+
 /* Read a chunk of data from a file at the given position.  The pos argument
  * can be ignored if the file is only be used for streaming.  The number of
  * bytes actually read should be returned.
@@ -50,13 +53,8 @@ typedef int (QEMUFileCloseFunc)(void *opaque);
  */
 typedef int (QEMUFileGetFD)(void *opaque);
 
-/* Called to change the blocking mode of the file
- */
-typedef int (QEMUFileSetBlocking)(void *opaque, bool enabled);
-
 /*
- * This function writes an iovec to file. The handler must write all
- * of the data or return a negative errno value.
+ * This function writes an iovec to file.
  */
 typedef ssize_t (QEMUFileWritevBufferFunc)(void *opaque, struct iovec *iov,
                                            int iovcnt, int64_t pos);
@@ -103,25 +101,32 @@ typedef QEMUFile *(QEMURetPathFunc)(void *opaque);
 typedef int (QEMUFileShutdownFunc)(void *opaque, bool rd, bool wr);
 
 typedef struct QEMUFileOps {
+    QEMUFilePutBufferFunc *put_buffer;
     QEMUFileGetBufferFunc *get_buffer;
     QEMUFileCloseFunc *close;
-    QEMUFileSetBlocking *set_blocking;
+    QEMUFileGetFD *get_fd;
     QEMUFileWritevBufferFunc *writev_buffer;
-    QEMURetPathFunc *get_return_path;
-    QEMUFileShutdownFunc *shut_down;
-} QEMUFileOps;
-
-typedef struct QEMUFileHooks {
     QEMURamHookFunc *before_ram_iterate;
     QEMURamHookFunc *after_ram_iterate;
     QEMURamHookFunc *hook_ram_load;
     QEMURamSaveFunc *save_page;
-} QEMUFileHooks;
+    QEMURetPathFunc *get_return_path;
+    QEMUFileShutdownFunc *shut_down;
+} QEMUFileOps;
+
+struct QEMUSizedBuffer {
+    struct iovec *iov;
+    size_t n_iov;
+    size_t size; /* total allocated size in all iov's */
+    size_t used; /* number of used bytes */
+};
 
 QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops);
-QEMUFile *qemu_fopen_channel_input(QIOChannel *ioc);
-QEMUFile *qemu_fopen_channel_output(QIOChannel *ioc);
-void qemu_file_set_hooks(QEMUFile *f, const QEMUFileHooks *hooks);
+QEMUFile *qemu_fopen(const char *filename, const char *mode);
+QEMUFile *qemu_fdopen(int fd, const char *mode);
+QEMUFile *qemu_fopen_socket(int fd, const char *mode);
+QEMUFile *qemu_popen_cmd(const char *command, const char *mode);
+QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer *input);
 int qemu_get_fd(QEMUFile *f);
 int qemu_fclose(QEMUFile *f);
 int64_t qemu_ftell(QEMUFile *f);
@@ -136,6 +141,20 @@ void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, size_t size);
 bool qemu_file_mode_is_not_valid(const char *mode);
 bool qemu_file_is_writable(QEMUFile *f);
 
+QEMUSizedBuffer *qsb_create(const uint8_t *buffer, size_t len);
+void qsb_free(QEMUSizedBuffer *);
+size_t qsb_set_length(QEMUSizedBuffer *qsb, size_t length);
+size_t qsb_get_length(const QEMUSizedBuffer *qsb);
+ssize_t qsb_get_buffer(const QEMUSizedBuffer *, off_t start, size_t count,
+                       uint8_t *buf);
+ssize_t qsb_write_at(QEMUSizedBuffer *qsb, const uint8_t *buf,
+                     off_t pos, size_t count);
+
+
+/*
+ * For use on files opened with qemu_bufopen
+ */
+const QEMUSizedBuffer *qemu_buf_get(QEMUFile *f);
 
 static inline void qemu_put_ubyte(QEMUFile *f, unsigned int v)
 {
index 1638ee5..84ee355 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
 #ifndef QEMU_VMSTATE_H
-#define QEMU_VMSTATE_H
+#define QEMU_VMSTATE_H 1
 
 #ifndef CONFIG_USER_ONLY
-#include "migration/qemu-file.h"
+#include <migration/qemu-file.h>
 #endif
-#include "migration/qjson.h"
+#include <qjson.h>
 
 typedef void SaveStateHandler(QEMUFile *f, void *opaque);
 typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
@@ -387,16 +386,6 @@ extern const VMStateInfo vmstate_info_bitmap;
     .offset     = vmstate_offset_pointer(_state, _field, _type),     \
 }
 
-#define VMSTATE_VARRAY_UINT32_ALLOC(_field, _state, _field_num, _version, _info, _type) {\
-    .name       = (stringify(_field)),                               \
-    .version_id = (_version),                                        \
-    .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\
-    .info       = &(_info),                                          \
-    .size       = sizeof(_type),                                     \
-    .flags      = VMS_VARRAY_UINT32|VMS_POINTER|VMS_ALLOC,           \
-    .offset     = vmstate_offset_pointer(_state, _field, _type),     \
-}
-
 #define VMSTATE_VARRAY_UINT16_UNSAFE(_field, _state, _field_num, _version, _info, _type) {\
     .name       = (stringify(_field)),                               \
     .version_id = (_version),                                        \
@@ -857,12 +846,6 @@ extern const VMStateInfo vmstate_info_bitmap;
 #define VMSTATE_UINT64_ARRAY(_f, _s, _n)                              \
     VMSTATE_UINT64_ARRAY_V(_f, _s, _n, 0)
 
-#define VMSTATE_UINT64_2DARRAY(_f, _s, _n1, _n2)                      \
-    VMSTATE_UINT64_2DARRAY_V(_f, _s, _n1, _n2, 0)
-
-#define VMSTATE_UINT64_2DARRAY_V(_f, _s, _n1, _n2, _v)                 \
-    VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint64, uint64_t)
-
 #define VMSTATE_INT16_ARRAY_V(_f, _s, _n, _v)                         \
     VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int16, int16_t)
 
@@ -905,11 +888,8 @@ extern const VMStateInfo vmstate_info_bitmap;
 #define VMSTATE_PARTIAL_BUFFER(_f, _s, _size)                         \
     VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, 0, _size)
 
-#define VMSTATE_BUFFER_START_MIDDLE_V(_f, _s, _start, _v) \
-    VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, _start, sizeof(typeof_field(_s, _f)))
-
 #define VMSTATE_BUFFER_START_MIDDLE(_f, _s, _start) \
-    VMSTATE_BUFFER_START_MIDDLE_V(_f, _s, _start, 0)
+    VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, _start, sizeof(typeof_field(_s, _f)))
 
 #define VMSTATE_PARTIAL_VBUFFER(_f, _s, _size)                        \
     VMSTATE_VBUFFER(_f, _s, 0, NULL, 0, _size)
index 454e8ed..bc2c9c0 100644 (file)
@@ -21,9 +21,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
-#ifndef MONITOR_HMP_TARGET_H
-#define MONITOR_HMP_TARGET_H
+#ifndef MONITOR_COMMON_H
+#define MONITOR_COMMON_H
 
 #define MD_TLONG 0
 #define MD_I32   1
@@ -47,4 +46,4 @@ void hmp_mce(Monitor *mon, const QDict *qdict);
 void hmp_info_local_apic(Monitor *mon, const QDict *qdict);
 void hmp_info_io_apic(Monitor *mon, const QDict *qdict);
 
-#endif /* MONITOR_HMP_TARGET_H */
+#endif /* MONITOR_COMMON */
index a714d8e..aa0f373 100644 (file)
@@ -17,7 +17,6 @@ extern Monitor *cur_mon;
 bool monitor_cur_is_qmp(void);
 
 void monitor_init(CharDriverState *chr, int flags);
-void monitor_cleanup(void);
 
 int monitor_suspend(Monitor *mon);
 void monitor_resume(Monitor *mon);
@@ -52,4 +51,4 @@ int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd);
 void monitor_fdset_dup_fd_remove(int dup_fd);
 int monitor_fdset_dup_fd_find(int dup_fd);
 
-#endif /* MONITOR_H */
+#endif /* !MONITOR_H */
index 8e504bc..c4b8a05 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef MONITOR_QDEV_H
-#define MONITOR_QDEV_H
+#ifndef QEMU_QDEV_MONITOR_H
+#define QEMU_QDEV_MONITOR_H
 
 #include "hw/qdev-core.h"
 
index 7df472c..7de1acb 100644 (file)
@@ -18,7 +18,6 @@
 #ifndef QEMU_NET_CHECKSUM_H
 #define QEMU_NET_CHECKSUM_H
 
-#include "qemu/bswap.h"
 struct iovec;
 
 uint32_t net_checksum_add_cont(int len, uint8_t *buf, int seq);
@@ -46,55 +45,9 @@ net_raw_checksum(uint8_t *data, int length)
  * @iov_cnt: number of array elements
  * @iov_off: starting iov offset for checksumming
  * @size: length of data to be checksummed
- * @csum_offset: offset of the checksum chunk
  */
 uint32_t net_checksum_add_iov(const struct iovec *iov,
                               const unsigned int iov_cnt,
-                              uint32_t iov_off, uint32_t size,
-                              uint32_t csum_offset);
-
-typedef struct toeplitz_key_st {
-    uint32_t leftmost_32_bits;
-    uint8_t *next_byte;
-} net_toeplitz_key;
-
-static inline
-void net_toeplitz_key_init(net_toeplitz_key *key, uint8_t *key_bytes)
-{
-    key->leftmost_32_bits = be32_to_cpu(*(uint32_t *)key_bytes);
-    key->next_byte = key_bytes + sizeof(uint32_t);
-}
-
-static inline
-void net_toeplitz_add(uint32_t *result,
-                      uint8_t *input,
-                      uint32_t len,
-                      net_toeplitz_key *key)
-{
-    register uint32_t accumulator = *result;
-    register uint32_t leftmost_32_bits = key->leftmost_32_bits;
-    register uint32_t byte;
-
-    for (byte = 0; byte < len; byte++) {
-        register uint8_t input_byte = input[byte];
-        register uint8_t key_byte = *(key->next_byte++);
-        register uint8_t bit;
-
-        for (bit = 0; bit < 8; bit++) {
-            if (input_byte & (1 << 7)) {
-                accumulator ^= leftmost_32_bits;
-            }
-
-            leftmost_32_bits =
-                (leftmost_32_bits << 1) | ((key_byte & (1 << 7)) >> 7);
-
-            input_byte <<= 1;
-            key_byte <<= 1;
-        }
-    }
-
-    key->leftmost_32_bits = leftmost_32_bits;
-    *result = accumulator;
-}
+                              uint32_t iov_off, uint32_t size);
 
 #endif /* QEMU_NET_CHECKSUM_H */
index 2013175..18d0be3 100644 (file)
@@ -67,16 +67,6 @@ typedef struct tcp_header {
     uint16_t th_urp;            /* urgent pointer */
 } tcp_header;
 
-#define TCP_FLAGS_ONLY(flags) ((flags) & 0x3f)
-
-#define TCP_HEADER_FLAGS(tcp) \
-    TCP_FLAGS_ONLY(be16_to_cpu((tcp)->th_offset_flags))
-
-#define TCP_FLAG_ACK  0x10
-
-#define TCP_HEADER_DATA_OFFSET(tcp) \
-    (((be16_to_cpu((tcp)->th_offset_flags) >> 12) & 0xf) << 2)
-
 typedef struct udp_header {
     uint16_t uh_sport; /* source port */
     uint16_t uh_dport; /* destination port */
@@ -118,34 +108,11 @@ struct ip6_header {
     struct in6_address ip6_dst;    /* destination address */
 };
 
-typedef struct ip6_pseudo_header {
-    struct in6_address ip6_src;
-    struct in6_address ip6_dst;
-    uint32_t           len;
-    uint8_t            zero[3];
-    uint8_t            next_hdr;
-} ip6_pseudo_header;
-
 struct ip6_ext_hdr {
     uint8_t        ip6r_nxt;   /* next header */
     uint8_t        ip6r_len;   /* length in units of 8 octets */
 };
 
-struct ip6_ext_hdr_routing {
-    uint8_t     nxt;
-    uint8_t     len;
-    uint8_t     rtype;
-    uint8_t     segleft;
-    uint8_t     rsvd[4];
-};
-
-struct ip6_option_hdr {
-#define IP6_OPT_PAD1   (0x00)
-#define IP6_OPT_HOME   (0xC9)
-    uint8_t type;
-    uint8_t len;
-};
-
 struct udp_hdr {
   uint16_t uh_sport;           /* source port */
   uint16_t uh_dport;           /* destination port */
@@ -194,22 +161,19 @@ struct tcp_hdr {
 #define PKT_GET_IP_HDR(p)         \
     ((struct ip_header *)(((uint8_t *)(p)) + eth_get_l2_hdr_length(p)))
 #define IP_HDR_GET_LEN(p)         \
-    ((((struct ip_header *)(p))->ip_ver_len & 0x0F) << 2)
+    ((((struct ip_header *)p)->ip_ver_len & 0x0F) << 2)
 #define PKT_GET_IP_HDR_LEN(p)     \
     (IP_HDR_GET_LEN(PKT_GET_IP_HDR(p)))
 #define PKT_GET_IP6_HDR(p)        \
     ((struct ip6_header *) (((uint8_t *)(p)) + eth_get_l2_hdr_length(p)))
 #define IP_HEADER_VERSION(ip)     \
-    (((ip)->ip_ver_len >> 4) & 0xf)
-#define IP4_IS_FRAGMENT(ip) \
-    ((be16_to_cpu((ip)->ip_off) & (IP_OFFMASK | IP_MF)) != 0)
+    ((ip->ip_ver_len >> 4)&0xf)
 
 #define ETH_P_IP                  (0x0800)      /* Internet Protocol packet  */
 #define ETH_P_ARP                 (0x0806)      /* Address Resolution packet */
 #define ETH_P_IPV6                (0x86dd)
 #define ETH_P_VLAN                (0x8100)
 #define ETH_P_DVLAN               (0x88a8)
-#define ETH_P_UNKNOWN             (0xffff)
 #define VLAN_VID_MASK             0x0fff
 #define IP_HEADER_VERSION_4       (4)
 #define IP_HEADER_VERSION_6       (6)
@@ -294,7 +258,7 @@ eth_get_l2_hdr_length(const void *p)
     case ETH_P_VLAN:
         return sizeof(struct eth_header) + sizeof(struct vlan_header);
     case ETH_P_DVLAN:
-        if (be16_to_cpu(hvlan->h_proto) == ETH_P_VLAN) {
+        if (hvlan->h_proto == ETH_P_VLAN) {
             return sizeof(struct eth_header) + 2 * sizeof(struct vlan_header);
         } else {
             return sizeof(struct eth_header) + sizeof(struct vlan_header);
@@ -304,19 +268,6 @@ eth_get_l2_hdr_length(const void *p)
     }
 }
 
-static inline uint32_t
-eth_get_l2_hdr_length_iov(const struct iovec *iov, int iovcnt)
-{
-    uint8_t p[sizeof(struct eth_header) + sizeof(struct vlan_header)];
-    size_t copied = iov_to_buf(iov, iovcnt, 0, p, ARRAY_SIZE(p));
-
-    if (copied < ARRAY_SIZE(p)) {
-        return copied;
-    }
-
-    return eth_get_l2_hdr_length(p);
-}
-
 static inline uint16_t
 eth_get_pkt_tci(const void *p)
 {
@@ -331,67 +282,51 @@ eth_get_pkt_tci(const void *p)
     }
 }
 
-bool
-eth_strip_vlan(const struct iovec *iov, int iovcnt, size_t iovoff,
-               uint8_t *new_ehdr_buf,
-               uint16_t *payload_offset, uint16_t *tci);
-
-bool
-eth_strip_vlan_ex(const struct iovec *iov, int iovcnt, size_t iovoff,
-                  uint16_t vet, uint8_t *new_ehdr_buf,
-                  uint16_t *payload_offset, uint16_t *tci);
-
-uint16_t
-eth_get_l3_proto(const struct iovec *l2hdr_iov, int iovcnt, size_t l2hdr_len);
+static inline bool
+eth_strip_vlan(const void *p, uint8_t *new_ehdr_buf,
+               uint16_t *payload_offset, uint16_t *tci)
+{
+    uint16_t proto = be16_to_cpu(PKT_GET_ETH_HDR(p)->h_proto);
+    struct vlan_header *hvlan = PKT_GET_VLAN_HDR(p);
+    struct eth_header *new_ehdr = (struct eth_header *) new_ehdr_buf;
 
-void eth_setup_vlan_headers_ex(struct eth_header *ehdr, uint16_t vlan_tag,
-    uint16_t vlan_ethtype, bool *is_new);
+    switch (proto) {
+    case ETH_P_VLAN:
+    case ETH_P_DVLAN:
+        memcpy(new_ehdr->h_source, PKT_GET_ETH_HDR(p)->h_source, ETH_ALEN);
+        memcpy(new_ehdr->h_dest, PKT_GET_ETH_HDR(p)->h_dest, ETH_ALEN);
+        new_ehdr->h_proto = hvlan->h_proto;
+        *tci = be16_to_cpu(hvlan->h_tci);
+        *payload_offset =
+            sizeof(struct eth_header) + sizeof(struct vlan_header);
+        if (be16_to_cpu(new_ehdr->h_proto) == ETH_P_VLAN) {
+            memcpy(PKT_GET_VLAN_HDR(new_ehdr),
+                   PKT_GET_DVLAN_HDR(p),
+                   sizeof(struct vlan_header));
+            *payload_offset += sizeof(struct vlan_header);
+        }
+        return true;
+    default:
+        return false;
+    }
+}
 
-static inline void
-eth_setup_vlan_headers(struct eth_header *ehdr, uint16_t vlan_tag,
-    bool *is_new)
+static inline uint16_t
+eth_get_l3_proto(const void *l2hdr, size_t l2hdr_len)
 {
-    eth_setup_vlan_headers_ex(ehdr, vlan_tag, ETH_P_VLAN, is_new);
+    uint8_t *proto_ptr = (uint8_t *) l2hdr + l2hdr_len - sizeof(uint16_t);
+    return be16_to_cpup((uint16_t *)proto_ptr);
 }
 
+void eth_setup_vlan_headers(struct eth_header *ehdr, uint16_t vlan_tag,
+    bool *is_new);
 
 uint8_t eth_get_gso_type(uint16_t l3_proto, uint8_t *l3_hdr, uint8_t l4proto);
 
-typedef struct eth_ip6_hdr_info_st {
-    uint8_t l4proto;
-    size_t  full_hdr_len;
-    struct  ip6_header ip6_hdr;
-    bool    has_ext_hdrs;
-    bool    rss_ex_src_valid;
-    struct  in6_address rss_ex_src;
-    bool    rss_ex_dst_valid;
-    struct  in6_address rss_ex_dst;
-    bool    fragment;
-} eth_ip6_hdr_info;
-
-typedef struct eth_ip4_hdr_info_st {
-    struct ip_header ip4_hdr;
-    bool   fragment;
-} eth_ip4_hdr_info;
-
-typedef struct eth_l4_hdr_info_st {
-    union {
-        struct tcp_header tcp;
-        struct udp_header udp;
-    } hdr;
-
-    bool has_tcp_data;
-} eth_l4_hdr_info;
-
-void eth_get_protocols(const struct iovec *iov, int iovcnt,
+void eth_get_protocols(const uint8_t *headers,
+                       uint32_t hdr_length,
                        bool *isip4, bool *isip6,
-                       bool *isudp, bool *istcp,
-                       size_t *l3hdr_off,
-                       size_t *l4hdr_off,
-                       size_t *l5hdr_off,
-                       eth_ip6_hdr_info *ip6hdr_info,
-                       eth_ip4_hdr_info *ip4hdr_info,
-                       eth_l4_hdr_info  *l4hdr_info);
+                       bool *isudp, bool *istcp);
 
 void eth_setup_ip4_fragmentation(const void *l2hdr, size_t l2hdr_len,
                                  void *l3hdr, size_t l3hdr_len,
@@ -402,18 +337,11 @@ void
 eth_fix_ip4_checksum(void *l3hdr, size_t l3hdr_len);
 
 uint32_t
-eth_calc_ip4_pseudo_hdr_csum(struct ip_header *iphdr,
-                             uint16_t csl,
-                             uint32_t *cso);
-
-uint32_t
-eth_calc_ip6_pseudo_hdr_csum(struct ip6_header *iphdr,
-                             uint16_t csl,
-                             uint8_t l4_proto,
-                             uint32_t *cso);
+eth_calc_pseudo_hdr_csum(struct ip_header *iphdr, uint16_t csl);
 
 bool
-eth_parse_ipv6_hdr(const struct iovec *pkt, int pkt_frags,
-                   size_t ip6hdr_off, eth_ip6_hdr_info *info);
+eth_parse_ipv6_hdr(struct iovec *pkt, int pkt_frags,
+                   size_t ip6hdr_off, uint8_t *l4proto,
+                   size_t *full_hdr_len);
 
 #endif
index e8d9e9e..73e4c46 100644 (file)
@@ -9,11 +9,6 @@
 #include "migration/vmstate.h"
 #include "qapi-types.h"
 
-#define MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
-#define MAC_ARG(x) ((uint8_t *)(x))[0], ((uint8_t *)(x))[1], \
-                   ((uint8_t *)(x))[2], ((uint8_t *)(x))[3], \
-                   ((uint8_t *)(x))[4], ((uint8_t *)(x))[5]
-
 #define MAX_QUEUE_NUM 1024
 
 /* Maximum GSO packet size (64k) plus plenty of room for
@@ -62,11 +57,9 @@ typedef void (SetOffload)(NetClientState *, int, int, int, int, int);
 typedef void (SetVnetHdrLen)(NetClientState *, int);
 typedef int (SetVnetLE)(NetClientState *, bool);
 typedef int (SetVnetBE)(NetClientState *, bool);
-typedef struct SocketReadState SocketReadState;
-typedef void (SocketReadStateFinalize)(SocketReadState *rs);
 
 typedef struct NetClientInfo {
-    NetClientDriver type;
+    NetClientOptionsKind type;
     size_t size;
     NetReceive *receive;
     NetReceive *receive_raw;
@@ -99,7 +92,6 @@ struct NetClientState {
     NetClientDestructor *destructor;
     unsigned int queue_index;
     unsigned rxfilter_notify_enabled:1;
-    int vring_enable;
     QTAILQ_HEAD(NetFilterHead, NetFilterState) filters;
 };
 
@@ -110,19 +102,10 @@ typedef struct NICState {
     bool peer_deleted;
 } NICState;
 
-struct SocketReadState {
-    int state; /* 0 = getting length, 1 = getting data */
-    uint32_t index;
-    uint32_t packet_len;
-    uint8_t buf[NET_BUFSIZE];
-    SocketReadStateFinalize *finalize;
-};
-
-int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size);
 char *qemu_mac_strdup_printf(const uint8_t *macaddr);
 NetClientState *qemu_find_netdev(const char *id);
 int qemu_find_net_clients_except(const char *id, NetClientState **ncs,
-                                 NetClientDriver type, int max);
+                                 NetClientOptionsKind type, int max);
 NetClientState *qemu_new_net_client(NetClientInfo *info,
                                     NetClientState *peer,
                                     const char *model,
@@ -177,8 +160,6 @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
 
 void print_net_client(Monitor *mon, NetClientState *nc);
 void hmp_info_network(Monitor *mon, const QDict *qdict);
-void net_socket_rs_init(SocketReadState *rs,
-                        SocketReadStateFinalize *finalize);
 
 /* NIC info */
 
@@ -197,13 +178,14 @@ struct NICInfo {
 
 extern int nb_nics;
 extern NICInfo nd_table[MAX_NICS];
+extern int default_net;
 extern const char *host_net_devices[];
 
 /* from net.c */
 extern const char *legacy_tftp_prefix;
 extern const char *legacy_bootp_filename;
 
-int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp);
+int net_client_init(QemuOpts *opts, int is_netdev, Error **errp);
 int net_client_parse(QemuOptsList *opts_list, const char *str);
 int net_init_clients(void);
 void net_check_clients(void);
index 5bcd8a6..85109f6 100644 (file)
@@ -8,11 +8,10 @@
  *
  */
 
-#ifndef VHOST_USER_H
-#define VHOST_USER_H
+#ifndef VHOST_USER_H_
+#define VHOST_USER_H_
 
 struct vhost_net;
 struct vhost_net *vhost_user_get_vhost_net(NetClientState *nc);
-uint64_t vhost_user_get_acked_features(NetClientState *nc);
 
-#endif /* VHOST_USER_H */
+#endif /* VHOST_USER_H_ */
index 5a08eff..3389b41 100644 (file)
@@ -10,7 +10,6 @@ typedef struct vhost_net VHostNetState;
 typedef struct VhostNetOptions {
     VhostBackendType backend_type;
     NetClientState *net_backend;
-    uint32_t busyloop_timeout;
     void *opaque;
 } VhostNetOptions;
 
@@ -32,7 +31,4 @@ int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr);
 VHostNetState *get_vhost_net(NetClientState *nc);
 
 int vhost_set_vring_enable(NetClientState * nc, int enable);
-
-uint64_t vhost_net_get_acked_features(VHostNetState *net);
-
 #endif
diff --git a/include/qapi/clone-visitor.h b/include/qapi/clone-visitor.h
deleted file mode 100644 (file)
index b16177e..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Clone Visitor
- *
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QAPI_CLONE_VISITOR_H
-#define QAPI_CLONE_VISITOR_H
-
-#include "qemu/typedefs.h"
-#include "qapi/visitor.h"
-#include "qapi-visit.h"
-
-/*
- * The clone visitor is for direct use only by the QAPI_CLONE() macro;
- * it requires that the root visit occur on an object, list, or
- * alternate, and is not usable directly on built-in QAPI types.
- */
-typedef struct QapiCloneVisitor QapiCloneVisitor;
-
-void *qapi_clone(const void *src, void (*visit_type)(Visitor *, const char *,
-                                                     void **, Error **));
-
-/*
- * Deep-clone QAPI object @src of the given @type, and return the result.
- *
- * Not usable on QAPI scalars (integers, strings, enums), nor on a
- * QAPI object that references the 'any' type.  Safe when @src is NULL.
- */
-#define QAPI_CLONE(type, src)                                           \
-    ((type *)qapi_clone(src,                                            \
-                        (void (*)(Visitor *, const char *, void**,      \
-                                  Error **))visit_type_ ## type))
-
-#endif
index b3e5c85..cf4c36d 100644 (file)
 
 typedef struct QapiDeallocVisitor QapiDeallocVisitor;
 
-/*
- * The dealloc visitor is primarly used only by generated
- * qapi_free_FOO() functions, and is the only visitor designed to work
- * correctly in the face of a partially-constructed QAPI tree.
- */
-Visitor *qapi_dealloc_visitor_new(void);
+QapiDeallocVisitor *qapi_dealloc_visitor_new(void);
+void qapi_dealloc_visitor_cleanup(QapiDeallocVisitor *d);
+
+Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v);
 
 #endif
index 0576659..11be232 100644 (file)
@@ -134,7 +134,7 @@ typedef enum ErrorClass {
 /*
  * Get @err's human-readable error message.
  */
-const char *error_get_pretty(const Error *err);
+const char *error_get_pretty(Error *err);
 
 /*
  * Get @err's error class.
index 6462c96..fd48c14 100644 (file)
@@ -29,12 +29,9 @@ typedef struct OptsVisitor OptsVisitor;
  * - string representations of negative numbers yield negative values,
  * - values below INT64_MIN or LLONG_MIN are rejected,
  * - values above INT64_MAX or LLONG_MAX are rejected.
- *
- * The Opts input visitor does not implement support for visiting QAPI
- * alternates, numbers (other than integers), null, or arbitrary
- * QTypes.  It also requires a non-null list argument to
- * visit_start_list().
  */
-Visitor *opts_visitor_new(const QemuOpts *opts);
+OptsVisitor *opts_visitor_new(const QemuOpts *opts);
+void opts_visitor_cleanup(OptsVisitor *nv);
+Visitor *opts_get_visitor(OptsVisitor *nv);
 
 #endif
index f3ff5f3..3ed499c 100644 (file)
 
 typedef struct QmpInputVisitor QmpInputVisitor;
 
-/*
- * Return a new input visitor that converts QMP to QAPI.
- *
- * Set @strict to reject a parse that doesn't consume all keys of a
- * dictionary; otherwise excess input is ignored.
- */
-Visitor *qmp_input_visitor_new(QObject *obj, bool strict);
+QmpInputVisitor *qmp_input_visitor_new(QObject *obj);
+QmpInputVisitor *qmp_input_visitor_new_strict(QObject *obj);
+
+void qmp_input_visitor_cleanup(QmpInputVisitor *v);
+
+Visitor *qmp_input_get_visitor(QmpInputVisitor *v);
 
 #endif
index 040fdda..2266770 100644 (file)
 
 typedef struct QmpOutputVisitor QmpOutputVisitor;
 
-/*
- * Create a new QMP output visitor.
- *
- * If everything else succeeds, pass @result to visit_complete() to
- * collect the result of the visit.
- */
-Visitor *qmp_output_visitor_new(QObject **result);
+QmpOutputVisitor *qmp_output_visitor_new(void);
+void qmp_output_visitor_cleanup(QmpOutputVisitor *v);
+
+QObject *qmp_output_get_qobject(QmpOutputVisitor *v);
+Visitor *qmp_output_get_visitor(QmpOutputVisitor *v);
 
 #endif
index 48c11b6..4955209 100644 (file)
  *
  */
 
-#ifndef QAPI_QMP_DISPATCH_H
-#define QAPI_QMP_DISPATCH_H
+#ifndef QMP_CORE_H
+#define QMP_CORE_H
 
 #include "qapi/qmp/qobject.h"
 #include "qapi/qmp/qdict.h"
 
 typedef void (QmpCommandFunc)(QDict *, QObject **, Error **);
 
+typedef enum QmpCommandType
+{
+    QCT_NORMAL,
+} QmpCommandType;
+
 typedef enum QmpCommandOptions
 {
     QCO_NO_OPTIONS = 0x0,
@@ -28,6 +33,7 @@ typedef enum QmpCommandOptions
 typedef struct QmpCommand
 {
     const char *name;
+    QmpCommandType type;
     QmpCommandFunc *fn;
     QmpCommandOptions options;
     QTAILQ_ENTRY(QmpCommand) node;
@@ -48,3 +54,4 @@ typedef void (*qmp_cmd_callback_fn)(QmpCommand *cmd, void *opaque);
 void qmp_for_each_command(qmp_cmd_callback_fn fn, void *opaque);
 
 #endif
+
index 6586c9f..d08652a 100644 (file)
@@ -19,6 +19,9 @@
 #define QERR_BASE_NOT_FOUND \
     "Base '%s' not found"
 
+#define QERR_BLOCK_JOB_NOT_READY \
+    "The active block job for device '%s' cannot be completed"
+
 #define QERR_BUS_NO_HOTPLUG \
     "Bus '%s' does not support hotplugging"
 
index 27cfbd8..7782ec5 100644 (file)
@@ -10,8 +10,8 @@
  * See the COPYING.LIB file in the top-level directory.
  */
 
-#ifndef QAPI_QMP_TYPES_H
-#define QAPI_QMP_TYPES_H
+#ifndef QEMU_OBJECTS_H
+#define QEMU_OBJECTS_H
 
 #include "qapi/qmp/qobject.h"
 #include "qapi/qmp/qint.h"
@@ -20,5 +20,6 @@
 #include "qapi/qmp/qstring.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qjson.h"
 
-#endif /* QAPI_QMP_TYPES_H */
+#endif /* QEMU_OBJECTS_H */
index 3355134..089243c 100644 (file)
 
 typedef struct StringInputVisitor StringInputVisitor;
 
-/*
- * The string input visitor does not implement support for visiting
- * QAPI structs, alternates, null, or arbitrary QTypes.  It also
- * requires a non-null list argument to visit_start_list().
- */
-Visitor *string_input_visitor_new(const char *str);
+StringInputVisitor *string_input_visitor_new(const char *str);
+void string_input_visitor_cleanup(StringInputVisitor *v);
+
+Visitor *string_input_get_visitor(StringInputVisitor *v);
 
 #endif
index 268dfe9..d99717f 100644 (file)
 
 typedef struct StringOutputVisitor StringOutputVisitor;
 
-/*
- * Create a new string output visitor.
- *
- * Using @human creates output that is a bit easier for humans to read
- * (for example, showing integer values in both decimal and hex).
- *
- * If everything else succeeds, pass @result to visit_complete() to
- * collect the result of the visit.
- *
- * The string output visitor does not implement support for visiting
- * QAPI structs, alternates, null, or arbitrary QTypes.  It also
- * requires a non-null list argument to visit_start_list().
- */
-Visitor *string_output_visitor_new(bool human, char **result);
+StringOutputVisitor *string_output_visitor_new(bool human);
+void string_output_visitor_cleanup(StringOutputVisitor *v);
+
+char *string_output_get_string(StringOutputVisitor *v);
+Visitor *string_output_get_visitor(StringOutputVisitor *v);
 
 #endif
index 8bd47ee..2bd8f29 100644 (file)
 
 #include "qapi/visitor.h"
 
-/*
- * This file describes the callback interface for implementing a QAPI
- * visitor.  For the client interface, see visitor.h.  When
- * implementing the callbacks, it is easiest to declare a struct with
- * 'Visitor visitor;' as the first member.  A callback's contract
- * matches the corresponding public functions' contract unless stated
- * otherwise.  In the comments below, some callbacks are marked "must
- * be set for $TYPE visits to work"; if a visitor implementation omits
- * that callback, it should also document that it is only useful for a
- * subset of QAPI.
- */
-
-/*
- * There are four classes of visitors; setting the class determines
- * how QAPI enums are visited, as well as what additional restrictions
- * can be asserted.  The values are intentionally chosen so as to
- * permit some assertions based on whether a given bit is set (that
- * is, some assertions apply to input and clone visitors, some
- * assertions apply to output and clone visitors).
- */
-typedef enum VisitorType {
-    VISITOR_INPUT = 1,
-    VISITOR_OUTPUT = 2,
-    VISITOR_CLONE = 3,
-    VISITOR_DEALLOC = 4,
-} VisitorType;
-
 struct Visitor
 {
-    /* Must be set to visit structs */
+    /* Must be set */
     void (*start_struct)(Visitor *v, const char *name, void **obj,
                          size_t size, Error **errp);
+    void (*end_struct)(Visitor *v, Error **errp);
 
-    /* Optional; intended for input visitors */
-    void (*check_struct)(Visitor *v, Error **errp);
-
-    /* Must be set to visit structs */
-    void (*end_struct)(Visitor *v, void **obj);
-
-    /* Must be set; implementations may require @list to be non-null,
-     * but must document it. */
-    void (*start_list)(Visitor *v, const char *name, GenericList **list,
-                       size_t size, Error **errp);
-
+    void (*start_list)(Visitor *v, const char *name, Error **errp);
     /* Must be set */
-    GenericList *(*next_list)(Visitor *v, GenericList *tail, size_t size);
-
+    GenericList *(*next_list)(Visitor *v, GenericList **list, size_t size);
     /* Must be set */
-    void (*end_list)(Visitor *v, void **list);
+    void (*end_list)(Visitor *v);
 
-    /* Must be set by input and dealloc visitors to visit alternates;
-     * optional for output visitors. */
+    /* Optional, needed for input and dealloc visitors.  */
     void (*start_alternate)(Visitor *v, const char *name,
                             GenericAlternate **obj, size_t size,
                             bool promote_int, Error **errp);
 
-    /* Optional, needed for dealloc visitor */
-    void (*end_alternate)(Visitor *v, void **obj);
+    /* Optional, needed for dealloc visitor */
+    void (*end_alternate)(Visitor *v);
 
-    /* Must be set */
+    /* Must be set. */
+    void (*type_enum)(Visitor *v, const char *name, int *obj,
+                      const char *const strings[], Error **errp);
+
+    /* Must be set. */
     void (*type_int64)(Visitor *v, const char *name, int64_t *obj,
                        Error **errp);
-
-    /* Must be set */
+    /* Must be set. */
     void (*type_uint64)(Visitor *v, const char *name, uint64_t *obj,
                         Error **errp);
-
-    /* Optional; fallback is type_uint64() */
+    /* Optional; fallback is type_uint64().  */
     void (*type_size)(Visitor *v, const char *name, uint64_t *obj,
                       Error **errp);
-
-    /* Must be set */
+    /* Must be set. */
     void (*type_bool)(Visitor *v, const char *name, bool *obj, Error **errp);
-
-    /* Must be set */
     void (*type_str)(Visitor *v, const char *name, char **obj, Error **errp);
-
-    /* Must be set to visit numbers */
     void (*type_number)(Visitor *v, const char *name, double *obj,
                         Error **errp);
-
-    /* Must be set to visit arbitrary QTypes */
     void (*type_any)(Visitor *v, const char *name, QObject **obj,
                      Error **errp);
 
-    /* Must be set to visit explicit null values.  */
-    void (*type_null)(Visitor *v, const char *name, Error **errp);
-
-    /* Must be set for input visitors, optional otherwise.  The core
-     * takes care of the return type in the public interface. */
+    /* May be NULL; most useful for input visitors. */
     void (*optional)(Visitor *v, const char *name, bool *present);
-
-    /* Must be set */
-    VisitorType type;
-
-    /* Must be set for output visitors, optional otherwise. */
-    void (*complete)(Visitor *v, void *opaque);
-
-    /* Must be set */
-    void (*free)(Visitor *v);
 };
 
+void input_type_enum(Visitor *v, const char *name, int *obj,
+                     const char *const strings[], Error **errp);
+void output_type_enum(Visitor *v, const char *name, int *obj,
+                      const char *const strings[], Error **errp);
+
 #endif
index 6c77a91..9a8d010 100644 (file)
  * See the COPYING.LIB file in the top-level directory.
  *
  */
-
-#ifndef QAPI_VISITOR_H
-#define QAPI_VISITOR_H
+#ifndef QAPI_VISITOR_CORE_H
+#define QAPI_VISITOR_CORE_H
 
 #include "qapi/qmp/qobject.h"
 
-/*
- * The QAPI schema defines both a set of C data types, and a QMP wire
- * format.  QAPI objects can contain references to other QAPI objects,
- * resulting in a directed acyclic graph.  QAPI also generates visitor
- * functions to walk these graphs.  This file represents the interface
- * for doing work at each node of a QAPI graph; it can also be used
- * for a virtual walk, where there is no actual QAPI C struct.
- *
- * There are four kinds of visitor classes: input visitors (QMP,
- * string, and QemuOpts) parse an external representation and build
- * the corresponding QAPI graph, output visitors (QMP and string) take
- * a completed QAPI graph and generate an external representation, the
- * dealloc visitor can take a QAPI graph (possibly partially
- * constructed) and recursively free its resources, and the clone
- * visitor performs a deep clone of one QAPI object to another.  While
- * the dealloc and QMP input/output visitors are general, the string,
- * QemuOpts, and clone visitors have some implementation limitations;
- * see the documentation for each visitor for more details on what it
- * supports.  Also, see visitor-impl.h for the callback contracts
- * implemented by each visitor, and docs/qapi-code-gen.txt for more
- * about the QAPI code generator.
- *
- * All of the visitors are created via:
- *
- * Visitor *subtype_visitor_new(parameters...);
- *
- * A visitor should be used for exactly one top-level visit_type_FOO()
- * or virtual walk; if that is successful, the caller can optionally
- * call visit_complete() (for now, useful only for output visits, but
- * safe to call on all visits).  Then, regardless of success or
- * failure, the user should call visit_free() to clean up resources.
- * It is okay to free the visitor without completing the visit, if
- * some other error is detected in the meantime.
- *
- * All QAPI types have a corresponding function with a signature
- * roughly compatible with this:
- *
- * void visit_type_FOO(Visitor *v, const char *name, T obj, Error **errp);
- *
- * where T is FOO for scalar types, and FOO * otherwise.  The scalar
- * visitors are declared here; the remaining visitors are generated in
- * qapi-visit.h.
- *
- * The @name parameter of visit_type_FOO() describes the relation
- * between this QAPI value and its parent container.  When visiting
- * the root of a tree, @name is ignored; when visiting a member of an
- * object, @name is the key associated with the value; and when
- * visiting a member of a list, @name is NULL.
- *
- * FIXME: Clients must pass NULL for @name when visiting a member of a
- * list, but this leads to poor error messages; it might be nicer to
- * require a non-NULL name such as "key.0" for '{ "key": [ "value" ]
- * }' if an error is encountered on "value" (or to have the visitor
- * core auto-generate the nicer name).
- *
- * The visit_type_FOO() functions expect a non-null @obj argument;
- * they allocate *@obj during input visits, leave it unchanged on
- * output visits, and recursively free any resources during a dealloc
- * visit.  Each function also takes the customary @errp argument (see
- * qapi/error.h for details), for reporting any errors (such as if a
- * member @name is not present, or is present but not the specified
- * type).
- *
- * If an error is detected during visit_type_FOO() with an input
- * visitor, then *@obj will be NULL for pointer types, and left
- * unchanged for scalar types.  Using an output or clone visitor with
- * an incomplete object has undefined behavior (other than a special
- * case for visit_type_str() treating NULL like ""), while the dealloc
- * visitor safely handles incomplete objects.  Since input visitors
- * never produce an incomplete object, such an object is possible only
- * by manual construction.
- *
- * For the QAPI object types (structs, unions, and alternates), there
- * is an additional generated function in qapi-visit.h compatible
- * with:
- *
- * void visit_type_FOO_members(Visitor *v, FOO *obj, Error **errp);
- *
- * for visiting the members of a type without also allocating the QAPI
- * struct.
- *
- * Additionally, in qapi-types.h, all QAPI pointer types (structs,
- * unions, alternates, and lists) have a generated function compatible
- * with:
- *
- * void qapi_free_FOO(FOO *obj);
- *
- * where behaves like free() in that @obj may be NULL.  Such objects
- * may also be used with the following macro, provided alongside the
- * clone visitor:
- *
- * Type *QAPI_CLONE(Type, src);
- *
- * in order to perform a deep clone of @src.  Because of the generated
- * qapi_free functions and the QAPI_CLONE() macro, the clone and
- * dealloc visitor should not be used directly outside of QAPI code.
- *
- * QAPI types can also inherit from a base class; when this happens, a
- * function is generated for easily going from the derived type to the
- * base type:
- *
- * BASE *qapi_CHILD_base(CHILD *obj);
- *
- * For a real QAPI struct, typical input usage involves:
- *
- * <example>
- *  Foo *f;
- *  Error *err = NULL;
- *  Visitor *v;
- *
- *  v = FOO_visitor_new(...);
- *  visit_type_Foo(v, NULL, &f, &err);
- *  if (err) {
- *      ...handle error...
- *  } else {
- *      ...use f...
- *  }
- *  visit_free(v);
- *  qapi_free_Foo(f);
- * </example>
- *
- * For a list, it is:
- * <example>
- *  FooList *l;
- *  Error *err = NULL;
- *  Visitor *v;
- *
- *  v = FOO_visitor_new(...);
- *  visit_type_FooList(v, NULL, &l, &err);
- *  if (err) {
- *      ...handle error...
- *  } else {
- *      for ( ; l; l = l->next) {
- *          ...use l->value...
- *      }
- *  }
- *  visit_free(v);
- *  qapi_free_FooList(l);
- * </example>
- *
- * Similarly, typical output usage is:
- *
- * <example>
- *  Foo *f = ...obtain populated object...
- *  Error *err = NULL;
- *  Visitor *v;
- *  Type *result;
- *
- *  v = FOO_visitor_new(..., &result);
- *  visit_type_Foo(v, NULL, &f, &err);
- *  if (err) {
- *      ...handle error...
- *  } else {
- *      visit_complete(v, &result);
- *      ...use result...
- *  }
- *  visit_free(v);
- * </example>
- *
- * When visiting a real QAPI struct, this file provides several
- * helpers that rely on in-tree information to control the walk:
- * visit_optional() for the 'has_member' field associated with
- * optional 'member' in the C struct; and visit_next_list() for
- * advancing through a FooList linked list.  Similarly, the
- * visit_is_input() helper makes it possible to write code that is
- * visitor-agnostic everywhere except for cleanup.  Only the generated
- * visit_type functions need to use these helpers.
- *
- * It is also possible to use the visitors to do a virtual walk, where
- * no actual QAPI struct is present.  In this situation, decisions
- * about what needs to be walked are made by the calling code, and
- * structured visits are split between pairs of start and end methods
- * (where the end method must be called if the start function
- * succeeded, even if an intermediate visit encounters an error).
- * Thus, a virtual walk corresponding to '{ "list": [1, 2] }' looks
- * like:
- *
- * <example>
- *  Visitor *v;
- *  Error *err = NULL;
- *  int value;
- *
- *  v = FOO_visitor_new(...);
- *  visit_start_struct(v, NULL, NULL, 0, &err);
- *  if (err) {
- *      goto out;
- *  }
- *  visit_start_list(v, "list", NULL, 0, &err);
- *  if (err) {
- *      goto outobj;
- *  }
- *  value = 1;
- *  visit_type_int(v, NULL, &value, &err);
- *  if (err) {
- *      goto outlist;
- *  }
- *  value = 2;
- *  visit_type_int(v, NULL, &value, &err);
- *  if (err) {
- *      goto outlist;
- *  }
- * outlist:
- *  visit_end_list(v, NULL);
- *  if (!err) {
- *      visit_check_struct(v, &err);
- *  }
- * outobj:
- *  visit_end_struct(v, NULL);
- * out:
- *  error_propagate(errp, err);
- *  visit_free(v);
- * </example>
- */
-
-/*** Useful types ***/
-
 /* This struct is layout-compatible with all other *List structs
- * created by the QAPI generator.  It is used as a typical
+ * created by the qapi generator.  It is used as a typical
  * singly-linked list. */
 typedef struct GenericList {
     struct GenericList *next;
@@ -242,170 +25,35 @@ typedef struct GenericList {
 } GenericList;
 
 /* This struct is layout-compatible with all Alternate types
- * created by the QAPI generator. */
+ * created by the qapi generator. */
 typedef struct GenericAlternate {
     QType type;
     char padding[];
 } GenericAlternate;
 
-/*** Visitor cleanup ***/
-
-/*
- * Complete the visit, collecting any output.
- *
- * May only be called only once after a successful top-level
- * visit_type_FOO() or visit_end_ITEM(), and marks the end of the
- * visit.  The @opaque pointer should match the output parameter
- * passed to the subtype_visitor_new() used to create an output
- * visitor, or NULL for any other visitor.  Needed for output
- * visitors, but may also be called with other visitors.
- */
-void visit_complete(Visitor *v, void *opaque);
-
-/*
- * Free @v and any resources it has tied up.
- *
- * May be called whether or not the visit has been successfully
- * completed, but should not be called until a top-level
- * visit_type_FOO() or visit_start_ITEM() has been performed on the
- * visitor.  Safe if @v is NULL.
- */
-void visit_free(Visitor *v);
-
-
-/*** Visiting structures ***/
-
-/*
- * Start visiting an object @obj (struct or union).
- *
- * @name expresses the relationship of this object to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL for a real walk, in which case @size
- * determines how much memory an input or clone visitor will allocate
- * into *@obj.  @obj may also be NULL for a virtual walk, in which
- * case @size is ignored.
- *
- * @errp obeys typical error usage, and reports failures such as a
- * member @name is not present, or present but not an object.  On
- * error, input visitors set *@obj to NULL.
- *
- * After visit_start_struct() succeeds, the caller may visit its
- * members one after the other, passing the member's name and address
- * within the struct.  Finally, visit_end_struct() needs to be called
- * with the same @obj to clean up, even if intermediate visits fail.
- * See the examples above.
- *
- * FIXME Should this be named visit_start_object, since it is also
- * used for QAPI unions, and maps to JSON objects?
- */
 void visit_start_struct(Visitor *v, const char *name, void **obj,
                         size_t size, Error **errp);
+void visit_end_struct(Visitor *v, Error **errp);
 
-/*
- * Prepare for completing an object visit.
- *
- * @errp obeys typical error usage, and reports failures such as
- * unparsed keys remaining in the input stream.
- *
- * Should be called prior to visit_end_struct() if all other
- * intermediate visit steps were successful, to allow the visitor one
- * last chance to report errors.  May be skipped on a cleanup path,
- * where there is no need to check for further errors.
- */
-void visit_check_struct(Visitor *v, Error **errp);
-
-/*
- * Complete an object visit started earlier.
- *
- * @obj must match what was passed to the paired visit_start_struct().
- *
- * Must be called after any successful use of visit_start_struct(),
- * even if intermediate processing was skipped due to errors, to allow
- * the backend to release any resources.  Destroying the visitor early
- * with visit_free() behaves as if this was implicitly called.
- */
-void visit_end_struct(Visitor *v, void **obj);
-
-
-/*** Visiting lists ***/
-
-/*
- * Start visiting a list.
- *
- * @name expresses the relationship of this list to its parent
- * container; see the general description of @name above.
- *
- * @list must be non-NULL for a real walk, in which case @size
- * determines how much memory an input or clone visitor will allocate
- * into *@list (at least sizeof(GenericList)).  Some visitors also
- * allow @list to be NULL for a virtual walk, in which case @size is
- * ignored.
- *
- * @errp obeys typical error usage, and reports failures such as a
- * member @name is not present, or present but not a list.  On error,
- * input visitors set *@list to NULL.
- *
- * After visit_start_list() succeeds, the caller may visit its members
- * one after the other.  A real visit (where @obj is non-NULL) uses
- * visit_next_list() for traversing the linked list, while a virtual
- * visit (where @obj is NULL) uses other means.  For each list
- * element, call the appropriate visit_type_FOO() with name set to
- * NULL and obj set to the address of the value member of the list
- * element.  Finally, visit_end_list() needs to be called with the
- * same @list to clean up, even if intermediate visits fail.  See the
- * examples above.
- */
-void visit_start_list(Visitor *v, const char *name, GenericList **list,
-                      size_t size, Error **errp);
-
-/*
- * Iterate over a GenericList during a non-virtual list visit.
- *
- * @size represents the size of a linked list node (at least
- * sizeof(GenericList)).
- *
- * @tail must not be NULL; on the first call, @tail is the value of
- * *list after visit_start_list(), and on subsequent calls @tail must
- * be the previously returned value.  Should be called in a loop until
- * a NULL return or error occurs; for each non-NULL return, the caller
- * then calls the appropriate visit_type_*() for the element type of
- * the list, with that function's name parameter set to NULL and obj
- * set to the address of @tail->value.
- */
-GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size);
-
-/*
- * Complete a list visit started earlier.
- *
- * @list must match what was passed to the paired visit_start_list().
- *
- * Must be called after any successful use of visit_start_list(), even
- * if intermediate processing was skipped due to errors, to allow the
- * backend to release any resources.  Destroying the visitor early
- * with visit_free() behaves as if this was implicitly called.
- */
-void visit_end_list(Visitor *v, void **list);
-
-
-/*** Visiting alternates ***/
+void visit_start_list(Visitor *v, const char *name, Error **errp);
+GenericList *visit_next_list(Visitor *v, GenericList **list, size_t size);
+void visit_end_list(Visitor *v);
 
 /*
- * Start the visit of an alternate @obj.
+ * Start the visit of an alternate @obj with the given @size.
  *
- * @name expresses the relationship of this alternate to its parent
- * container; see the general description of @name above.
+ * @name specifies the relationship to the containing struct (ignored
+ * for a top level visit, the name of the key if this alternate is
+ * part of an object, or NULL if this alternate is part of a list).
  *
- * @obj must not be NULL. Input and clone visitors use @size to
- * determine how much memory to allocate into *@obj, then determine
- * the qtype of the next thing to be visited, stored in (*@obj)->type.
- * Other visitors will leave @obj unchanged.
+ * @obj must not be NULL. Input visitors will allocate @obj and
+ * determine the qtype of the next thing to be visited, stored in
+ * (*@obj)->type.  Other visitors will leave @obj unchanged.
  *
  * If @promote_int, treat integers as QTYPE_FLOAT.
  *
- * If successful, this must be paired with visit_end_alternate() with
- * the same @obj to clean up, even if visiting the contents of the
- * alternate fails.
+ * If successful, this must be paired with visit_end_alternate(), even
+ * if visiting the contents of the alternate fails.
  */
 void visit_start_alternate(Visitor *v, const char *name,
                            GenericAlternate **obj, size_t size,
@@ -414,203 +62,46 @@ void visit_start_alternate(Visitor *v, const char *name,
 /*
  * Finish visiting an alternate type.
  *
- * @obj must match what was passed to the paired visit_start_alternate().
- *
- * Must be called after any successful use of visit_start_alternate(),
- * even if intermediate processing was skipped due to errors, to allow
- * the backend to release any resources.  Destroying the visitor early
- * with visit_free() behaves as if this was implicitly called.
+ * Must be called after a successful visit_start_alternate(), even if
+ * an error occurred in the meantime.
  *
+ * TODO: Should all the visit_end_* interfaces take obj parameter, so
+ * that dealloc visitor need not track what was passed in visit_start?
  */
-void visit_end_alternate(Visitor *v, void **obj);
+void visit_end_alternate(Visitor *v);
 
-
-/*** Other helpers ***/
-
-/*
- * Does optional struct member @name need visiting?
- *
- * @name must not be NULL.  This function is only useful between
- * visit_start_struct() and visit_end_struct(), since only objects
- * have optional keys.
- *
- * @present points to the address of the optional member's has_ flag.
- *
- * Input visitors set *@present according to input; other visitors
- * leave it unchanged.  In either case, return *@present for
- * convenience.
+/**
+ * Check if an optional member @name of an object needs visiting.
+ * For input visitors, set *@present according to whether the
+ * corresponding visit_type_*() needs calling; for other visitors,
+ * leave *@present unchanged.  Return *@present for convenience.
  */
 bool visit_optional(Visitor *v, const char *name, bool *present);
 
-/*
- * Visit an enum value.
- *
- * @name expresses the relationship of this enum to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL.  Input visitors parse input and set *@obj to
- * the enumeration value, leaving @obj unchanged on error; other
- * visitors use *@obj but leave it unchanged.
- *
- * Currently, all input visitors parse text input, and all output
- * visitors produce text output.  The mapping between enumeration
- * values and strings is done by the visitor core, using @strings; it
- * should be the ENUM_lookup array from visit-types.h.
- *
- * May call visit_type_str() under the hood, and the enum visit may
- * fail even if the corresponding string visit succeeded; this implies
- * that visit_type_str() must have no unwelcome side effects.
- */
 void visit_type_enum(Visitor *v, const char *name, int *obj,
                      const char *const strings[], Error **errp);
-
-/*
- * Check if visitor is an input visitor.
- */
-bool visit_is_input(Visitor *v);
-
-/*** Visiting built-in types ***/
-
-/*
- * Visit an integer value.
- *
- * @name expresses the relationship of this integer to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL.  Input visitors set *@obj to the value;
- * other visitors will leave *@obj unchanged.
- */
 void visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp);
-
-/*
- * Visit a uint8_t value.
- * Like visit_type_int(), except clamps the value to uint8_t range.
- */
 void visit_type_uint8(Visitor *v, const char *name, uint8_t *obj,
                       Error **errp);
-
-/*
- * Visit a uint16_t value.
- * Like visit_type_int(), except clamps the value to uint16_t range.
- */
 void visit_type_uint16(Visitor *v, const char *name, uint16_t *obj,
                        Error **errp);
-
-/*
- * Visit a uint32_t value.
- * Like visit_type_int(), except clamps the value to uint32_t range.
- */
 void visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
                        Error **errp);
-
-/*
- * Visit a uint64_t value.
- * Like visit_type_int(), except clamps the value to uint64_t range,
- * that is, ensures it is unsigned.
- */
 void visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
                        Error **errp);
-
-/*
- * Visit an int8_t value.
- * Like visit_type_int(), except clamps the value to int8_t range.
- */
 void visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp);
-
-/*
- * Visit an int16_t value.
- * Like visit_type_int(), except clamps the value to int16_t range.
- */
 void visit_type_int16(Visitor *v, const char *name, int16_t *obj,
                       Error **errp);
-
-/*
- * Visit an int32_t value.
- * Like visit_type_int(), except clamps the value to int32_t range.
- */
 void visit_type_int32(Visitor *v, const char *name, int32_t *obj,
                       Error **errp);
-
-/*
- * Visit an int64_t value.
- * Identical to visit_type_int().
- */
 void visit_type_int64(Visitor *v, const char *name, int64_t *obj,
                       Error **errp);
-
-/*
- * Visit a uint64_t value.
- * Like visit_type_uint64(), except that some visitors may choose to
- * recognize additional syntax, such as suffixes for easily scaling
- * values.
- */
 void visit_type_size(Visitor *v, const char *name, uint64_t *obj,
                      Error **errp);
-
-/*
- * Visit a boolean value.
- *
- * @name expresses the relationship of this boolean to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL.  Input visitors set *@obj to the value;
- * other visitors will leave *@obj unchanged.
- */
 void visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp);
-
-/*
- * Visit a string value.
- *
- * @name expresses the relationship of this string to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL.  Input and clone visitors set *@obj to the
- * value (always using "" rather than NULL for an empty string).
- * Other visitors leave *@obj unchanged, and commonly treat NULL like
- * "".
- *
- * It is safe to cast away const when preparing a (const char *) value
- * into @obj for use by an output visitor.
- *
- * FIXME: Callers that try to output NULL *obj should not be allowed.
- */
 void visit_type_str(Visitor *v, const char *name, char **obj, Error **errp);
-
-/*
- * Visit a number (i.e. double) value.
- *
- * @name expresses the relationship of this number to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL.  Input visitors set *@obj to the value;
- * other visitors will leave *@obj unchanged.  Visitors should
- * document if infinity or NaN are not permitted.
- */
 void visit_type_number(Visitor *v, const char *name, double *obj,
                        Error **errp);
-
-/*
- * Visit an arbitrary value.
- *
- * @name expresses the relationship of this value to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL.  Input visitors set *@obj to the value;
- * other visitors will leave *@obj unchanged.  *@obj must be non-NULL
- * for output visitors.
- */
 void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp);
 
-/*
- * Visit a JSON null value.
- *
- * @name expresses the relationship of the null value to its parent
- * container; see the general description of @name above.
- *
- * Unlike all other visit_type_* functions, no obj parameter is
- * needed; rather, this is a witness that an explicit null value is
- * expected rather than any other type.
- */
-void visit_type_null(Visitor *v, const char *name, Error **errp);
-
 #endif
index 9e8b0bd..163bcbb 100644 (file)
 
 #include "qemu/fprintf-fn.h"
 
+#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__ia64__)
+#define WORDS_ALIGNED
+#endif
+
 #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
 #include "qemu/option.h"
+#include "qemu/host-utils.h"
+
+void cpu_ticks_init(void);
+
+/* icount */
+void configure_icount(QemuOpts *opts, Error **errp);
+extern int use_icount;
+extern int icount_align_option;
+/* drift information for info jit command */
+extern int64_t max_delay;
+extern int64_t max_advance;
+void dump_drift_info(FILE *f, fprintf_function cpu_fprintf);
 
-/* Copyright string for -version arguments, About dialogs, etc */
-#define QEMU_COPYRIGHT "Copyright (c) 2003-2016 " \
-    "Fabrice Bellard and the QEMU Project developers"
+#include "qemu/bswap.h"
+
+/* FIXME: Remove NEED_CPU_H.  */
+#ifdef NEED_CPU_H
+#include "cpu.h"
+#endif /* !defined(NEED_CPU_H) */
 
 /* main function, renamed */
 #if defined(CONFIG_COCOA)
@@ -81,6 +100,19 @@ bool tcg_enabled(void);
 
 void cpu_exec_init_all(void);
 
+/* Unblock cpu */
+void qemu_cpu_kick_self(void);
+
+/* work queue */
+struct qemu_work_item {
+    struct qemu_work_item *next;
+    void (*func)(void *data);
+    void *data;
+    int done;
+    bool free;
+};
+
+
 /**
  * Sends a (part of) iovec down a socket, yielding when the socket is full, or
  * Receives data into a (part of) iovec from a socket,
index 7c44119..116487e 100644 (file)
@@ -22,8 +22,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef QEMU_ACL_H
-#define QEMU_ACL_H
+#ifndef __QEMU_ACL_H__
+#define __QEMU_ACL_H__
 
 #include "qemu/queue.h"
 
@@ -63,4 +63,12 @@ int qemu_acl_insert(qemu_acl *acl,
 int qemu_acl_remove(qemu_acl *acl,
                    const char *match);
 
-#endif /* QEMU_ACL_H */
+#endif /* __QEMU_ACL_H__ */
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 8
+ * End:
+ */
index 43b0645..5bc4d6c 100644 (file)
  * atomic primitive is meant to provide.
  */
 
-#ifndef QEMU_ATOMIC_H
-#define QEMU_ATOMIC_H
+#ifndef __QEMU_ATOMIC_H
+#define __QEMU_ATOMIC_H 1
+
+
 
 /* Compiler barrier */
 #define barrier()   ({ asm volatile("" ::: "memory"); (void)0; })
 
-/* The variable that receives the old value of an atomically-accessed
- * variable must be non-qualified, because atomic builtins return values
- * through a pointer-type argument as in __atomic_load(&var, &old, MODEL).
- *
- * This macro has to handle types smaller than int manually, because of
- * implicit promotion.  int and larger types, as well as pointers, can be
- * converted to a non-qualified type just by applying a binary operator.
- */
-#define typeof_strip_qual(expr)                                                    \
-  typeof(                                                                          \
-    __builtin_choose_expr(                                                         \
-      __builtin_types_compatible_p(typeof(expr), bool) ||                          \
-        __builtin_types_compatible_p(typeof(expr), const bool) ||                  \
-        __builtin_types_compatible_p(typeof(expr), volatile bool) ||               \
-        __builtin_types_compatible_p(typeof(expr), const volatile bool),           \
-        (bool)1,                                                                   \
-    __builtin_choose_expr(                                                         \
-      __builtin_types_compatible_p(typeof(expr), signed char) ||                   \
-        __builtin_types_compatible_p(typeof(expr), const signed char) ||           \
-        __builtin_types_compatible_p(typeof(expr), volatile signed char) ||        \
-        __builtin_types_compatible_p(typeof(expr), const volatile signed char),    \
-        (signed char)1,                                                            \
-    __builtin_choose_expr(                                                         \
-      __builtin_types_compatible_p(typeof(expr), unsigned char) ||                 \
-        __builtin_types_compatible_p(typeof(expr), const unsigned char) ||         \
-        __builtin_types_compatible_p(typeof(expr), volatile unsigned char) ||      \
-        __builtin_types_compatible_p(typeof(expr), const volatile unsigned char),  \
-        (unsigned char)1,                                                          \
-    __builtin_choose_expr(                                                         \
-      __builtin_types_compatible_p(typeof(expr), signed short) ||                  \
-        __builtin_types_compatible_p(typeof(expr), const signed short) ||          \
-        __builtin_types_compatible_p(typeof(expr), volatile signed short) ||       \
-        __builtin_types_compatible_p(typeof(expr), const volatile signed short),   \
-        (signed short)1,                                                           \
-    __builtin_choose_expr(                                                         \
-      __builtin_types_compatible_p(typeof(expr), unsigned short) ||                \
-        __builtin_types_compatible_p(typeof(expr), const unsigned short) ||        \
-        __builtin_types_compatible_p(typeof(expr), volatile unsigned short) ||     \
-        __builtin_types_compatible_p(typeof(expr), const volatile unsigned short), \
-        (unsigned short)1,                                                         \
-      (expr)+0))))))
-
 #ifdef __ATOMIC_RELAXED
 /* For C11 atomic ops */
 
 #define smp_wmb()   ({ barrier(); __atomic_thread_fence(__ATOMIC_RELEASE); barrier(); })
 #define smp_rmb()   ({ barrier(); __atomic_thread_fence(__ATOMIC_ACQUIRE); barrier(); })
 
-/* Most compilers currently treat consume and acquire the same, but really
- * no processors except Alpha need a barrier here.  Leave it in if
- * using Thread Sanitizer to avoid warnings, otherwise optimize it away.
- */
-#if defined(__SANITIZE_THREAD__)
 #define smp_read_barrier_depends() ({ barrier(); __atomic_thread_fence(__ATOMIC_CONSUME); barrier(); })
-#elsif defined(__alpha__)
-#define smp_read_barrier_depends()   asm volatile("mb":::"memory")
-#else
-#define smp_read_barrier_depends()   barrier()
-#endif
-
 
 /* Weak atomic operations prevent the compiler moving other
  * loads/stores past the atomic operation load/store. However there is
@@ -96,7 +45,7 @@
 #define atomic_read(ptr)                              \
     ({                                                \
     QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
-    typeof_strip_qual(*ptr) _val;                     \
+    typeof(*ptr) _val;                                \
      __atomic_load(ptr, &_val, __ATOMIC_RELAXED);     \
     _val;                                             \
     })
     __atomic_store(ptr, &_val, __ATOMIC_RELAXED);     \
 } while(0)
 
-/* See above: most compilers currently treat consume and acquire the
- * same, but this slows down atomic_rcu_read unnecessarily.
- */
-#ifdef __SANITIZE_THREAD__
-#define atomic_rcu_read__nocheck(ptr, valptr)           \
-    __atomic_load(ptr, valptr, __ATOMIC_CONSUME);
-#else
-#define atomic_rcu_read__nocheck(ptr, valptr)           \
-    __atomic_load(ptr, valptr, __ATOMIC_RELAXED);       \
-    smp_read_barrier_depends();
-#endif
+/* Atomic RCU operations imply weak memory barriers */
 
 #define atomic_rcu_read(ptr)                          \
     ({                                                \
     QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
-    typeof_strip_qual(*ptr) _val;                     \
-    atomic_rcu_read__nocheck(ptr, &_val);             \
+    typeof(*ptr) _val;                                \
+    __atomic_load(ptr, &_val, __ATOMIC_CONSUME);      \
     _val;                                             \
     })
 
 #define atomic_mb_read(ptr)                             \
     ({                                                  \
     QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *));   \
-    typeof_strip_qual(*ptr) _val;                       \
+    typeof(*ptr) _val;                                  \
      __atomic_load(ptr, &_val, __ATOMIC_RELAXED);       \
      smp_rmb();                                         \
     _val;                                               \
 #define atomic_mb_read(ptr)                             \
     ({                                                  \
     QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *));   \
-    typeof_strip_qual(*ptr) _val;                       \
+    typeof(*ptr) _val;                                  \
     __atomic_load(ptr, &_val, __ATOMIC_SEQ_CST);        \
     _val;                                               \
     })
 
 #define atomic_xchg(ptr, i)    ({                           \
     QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *));       \
-    typeof_strip_qual(*ptr) _new = (i), _old;               \
+    typeof(*ptr) _new = (i), _old;                          \
     __atomic_exchange(ptr, &_new, &_old, __ATOMIC_SEQ_CST); \
     _old;                                                   \
 })
 #define atomic_cmpxchg(ptr, old, new)                                   \
     ({                                                                  \
     QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *));                   \
-    typeof_strip_qual(*ptr) _old = (old), _new = (new);                 \
+    typeof(*ptr) _old = (old), _new = (new);                            \
     __atomic_compare_exchange(ptr, &_old, &_new, false,                 \
                               __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);      \
     _old;                                                               \
 #define atomic_or(ptr, n)      ((void) __sync_fetch_and_or(ptr, n))
 
 #endif /* __ATOMIC_RELAXED */
-#endif /* QEMU_ATOMIC_H */
+#endif /* __QEMU_ATOMIC_H */
index 815d852..793708d 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QEMU_BASE64_H
-#define QEMU_BASE64_H
+#ifndef QEMU_BASE64_H__
+#define QEMU_BASE64_H__
 
 #include "qemu-common.h"
 
@@ -55,4 +55,4 @@ uint8_t *qbase64_decode(const char *input,
                         Error **errp);
 
 
-#endif /* QEMU_BASE64_H */
+#endif /* QEMU_BUFFER_H__ */
index dfebacf..b4c9b64 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef QEMU_BCD_H
-#define QEMU_BCD_H
+#define QEMU_BCD_H 1
 
 /* Convert a byte between binary and BCD.  */
 static inline uint8_t to_bcd(uint8_t val)
index ec5146f..0e33fa5 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef BITMAP_H
 #define BITMAP_H
 
+#include <glib.h>
 
 #include "qemu/bitops.h"
 
index 98fb005..755fdd1 100644 (file)
@@ -24,9 +24,6 @@
 #define BIT_WORD(nr)            ((nr) / BITS_PER_LONG)
 #define BITS_TO_LONGS(nr)       DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
 
-#define MAKE_64BIT_MASK(shift, length) \
-    (((~0ULL) >> (64 - (length))) << (shift))
-
 /**
  * set_bit - Set a bit in memory
  * @nr: the bit to set
@@ -431,112 +428,4 @@ static inline uint64_t deposit64(uint64_t value, int start, int length,
     return (value & ~mask) | ((fieldval << start) & mask);
 }
 
-/**
- * half_shuffle32:
- * @value: 32-bit value (of which only the bottom 16 bits are of interest)
- *
- * Given an input value:
- *  xxxx xxxx xxxx xxxx ABCD EFGH IJKL MNOP
- * return the value where the bottom 16 bits are spread out into
- * the odd bits in the word, and the even bits are zeroed:
- *  0A0B 0C0D 0E0F 0G0H 0I0J 0K0L 0M0N 0O0P
- *
- * Any bits set in the top half of the input are ignored.
- *
- * Returns: the shuffled bits.
- */
-static inline uint32_t half_shuffle32(uint32_t x)
-{
-    /* This algorithm is from _Hacker's Delight_ section 7-2 "Shuffling Bits".
-     * It ignores any bits set in the top half of the input.
-     */
-    x = ((x & 0xFF00) << 8) | (x & 0x00FF);
-    x = ((x << 4) | x) & 0x0F0F0F0F;
-    x = ((x << 2) | x) & 0x33333333;
-    x = ((x << 1) | x) & 0x55555555;
-    return x;
-}
-
-/**
- * half_shuffle64:
- * @value: 64-bit value (of which only the bottom 32 bits are of interest)
- *
- * Given an input value:
- *  xxxx xxxx xxxx .... xxxx xxxx ABCD EFGH IJKL MNOP QRST UVWX YZab cdef
- * return the value where the bottom 32 bits are spread out into
- * the odd bits in the word, and the even bits are zeroed:
- *  0A0B 0C0D 0E0F 0G0H 0I0J 0K0L 0M0N .... 0U0V 0W0X 0Y0Z 0a0b 0c0d 0e0f
- *
- * Any bits set in the top half of the input are ignored.
- *
- * Returns: the shuffled bits.
- */
-static inline uint64_t half_shuffle64(uint64_t x)
-{
-    /* This algorithm is from _Hacker's Delight_ section 7-2 "Shuffling Bits".
-     * It ignores any bits set in the top half of the input.
-     */
-    x = ((x & 0xFFFF0000ULL) << 16) | (x & 0xFFFF);
-    x = ((x << 8) | x) & 0x00FF00FF00FF00FFULL;
-    x = ((x << 4) | x) & 0x0F0F0F0F0F0F0F0FULL;
-    x = ((x << 2) | x) & 0x3333333333333333ULL;
-    x = ((x << 1) | x) & 0x5555555555555555ULL;
-    return x;
-}
-
-/**
- * half_unshuffle32:
- * @value: 32-bit value (of which only the odd bits are of interest)
- *
- * Given an input value:
- *  xAxB xCxD xExF xGxH xIxJ xKxL xMxN xOxP
- * return the value where all the odd bits are compressed down
- * into the low half of the word, and the high half is zeroed:
- *  0000 0000 0000 0000 ABCD EFGH IJKL MNOP
- *
- * Any even bits set in the input are ignored.
- *
- * Returns: the unshuffled bits.
- */
-static inline uint32_t half_unshuffle32(uint32_t x)
-{
-    /* This algorithm is from _Hacker's Delight_ section 7-2 "Shuffling Bits".
-     * where it is called an inverse half shuffle.
-     */
-    x &= 0x55555555;
-    x = ((x >> 1) | x) & 0x33333333;
-    x = ((x >> 2) | x) & 0x0F0F0F0F;
-    x = ((x >> 4) | x) & 0x00FF00FF;
-    x = ((x >> 8) | x) & 0x0000FFFF;
-    return x;
-}
-
-/**
- * half_unshuffle64:
- * @value: 64-bit value (of which only the odd bits are of interest)
- *
- * Given an input value:
- *  xAxB xCxD xExF xGxH xIxJ xKxL xMxN .... xUxV xWxX xYxZ xaxb xcxd xexf
- * return the value where all the odd bits are compressed down
- * into the low half of the word, and the high half is zeroed:
- *  0000 0000 0000 .... 0000 0000 ABCD EFGH IJKL MNOP QRST UVWX YZab cdef
- *
- * Any even bits set in the input are ignored.
- *
- * Returns: the unshuffled bits.
- */
-static inline uint64_t half_unshuffle64(uint64_t x)
-{
-    /* This algorithm is from _Hacker's Delight_ section 7-2 "Shuffling Bits".
-     * where it is called an inverse half shuffle.
-     */
-    x &= 0x5555555555555555ULL;
-    x = ((x >> 1) | x) & 0x3333333333333333ULL;
-    x = ((x >> 2) | x) & 0x0F0F0F0F0F0F0F0FULL;
-    x = ((x >> 4) | x) & 0x00FF00FF00FF00FFULL;
-    x = ((x >> 8) | x) & 0x0000FFFF0000FFFFULL;
-    x = ((x >> 16) | x) & 0x00000000FFFFFFFFULL;
-    return x;
-}
-
 #endif
index 09c78fd..ce3c42e 100644 (file)
@@ -80,64 +80,6 @@ static inline void bswap64s(uint64_t *s)
 #define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
 #endif
 
-/**
- * Endianness conversion functions between host cpu and specified endianness.
- * (We list the complete set of prototypes produced by the macros below
- * to assist people who search the headers to find their definitions.)
- *
- * uint16_t le16_to_cpu(uint16_t v);
- * uint32_t le32_to_cpu(uint32_t v);
- * uint64_t le64_to_cpu(uint64_t v);
- * uint16_t be16_to_cpu(uint16_t v);
- * uint32_t be32_to_cpu(uint32_t v);
- * uint64_t be64_to_cpu(uint64_t v);
- *
- * Convert the value @v from the specified format to the native
- * endianness of the host CPU by byteswapping if necessary, and
- * return the converted value.
- *
- * uint16_t cpu_to_le16(uint16_t v);
- * uint32_t cpu_to_le32(uint32_t v);
- * uint64_t cpu_to_le64(uint64_t v);
- * uint16_t cpu_to_be16(uint16_t v);
- * uint32_t cpu_to_be32(uint32_t v);
- * uint64_t cpu_to_be64(uint64_t v);
- *
- * Convert the value @v from the native endianness of the host CPU to
- * the specified format by byteswapping if necessary, and return
- * the converted value.
- *
- * void le16_to_cpus(uint16_t *v);
- * void le32_to_cpus(uint32_t *v);
- * void le64_to_cpus(uint64_t *v);
- * void be16_to_cpus(uint16_t *v);
- * void be32_to_cpus(uint32_t *v);
- * void be64_to_cpus(uint64_t *v);
- *
- * Do an in-place conversion of the value pointed to by @v from the
- * specified format to the native endianness of the host CPU.
- *
- * void cpu_to_le16s(uint16_t *v);
- * void cpu_to_le32s(uint32_t *v);
- * void cpu_to_le64s(uint64_t *v);
- * void cpu_to_be16s(uint16_t *v);
- * void cpu_to_be32s(uint32_t *v);
- * void cpu_to_be64s(uint64_t *v);
- *
- * Do an in-place conversion of the value pointed to by @v from the
- * native endianness of the host CPU to the specified format.
- *
- * Both X_to_cpu() and cpu_to_X() perform the same operation; you
- * should use whichever one is better documenting of the function your
- * code is performing.
- *
- * Do not use these functions for conversion of values which are in guest
- * memory, since the data may not be sufficiently aligned for the host CPU's
- * load and store instructions. Instead you should use the ld*_p() and
- * st*_p() functions, which perform loads and stores of data of any
- * required size and endianness and handle possible misalignment.
- */
-
 #define CPU_CONVERT(endian, size, type)\
 static inline type endian ## size ## _to_cpu(type v)\
 {\
@@ -157,6 +99,16 @@ static inline void endian ## size ## _to_cpus(type *p)\
 static inline void cpu_to_ ## endian ## size ## s(type *p)\
 {\
     glue(endian, _bswaps)(p, size);\
+}\
+\
+static inline type endian ## size ## _to_cpup(const type *p)\
+{\
+    return glue(glue(endian, size), _to_cpu)(*p);\
+}\
+\
+static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
+{\
+    *p = glue(glue(cpu_to_, endian), size)(v);\
 }
 
 CPU_CONVERT(be, 16, uint16_t)
@@ -174,7 +126,7 @@ static inline uint32_t qemu_bswap_len(uint32_t value, int len)
 }
 
 /*
- * Same as cpu_to_le{16,32}, except that gcc will figure the result is
+ * Same as cpu_to_le{16,23}, except that gcc will figure the result is
  * a compile-time constant if you pass in a constant.  So this can be
  * used to initialize static variables.
  */
index b2ead1f..dead9b7 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef QEMU_BUFFER_H
-#define QEMU_BUFFER_H
+#ifndef QEMU_BUFFER_H__
+#define QEMU_BUFFER_H__
 
 #include "qemu-common.h"
 
@@ -158,4 +158,4 @@ void buffer_move_empty(Buffer *to, Buffer *from);
  */
 void buffer_move(Buffer *to, Buffer *from);
 
-#endif /* QEMU_BUFFER_H */
+#endif /* QEMU_BUFFER_H__ */
index 338d3a6..8f1cc7b 100644 (file)
@@ -3,9 +3,6 @@
 #ifndef COMPILER_H
 #define COMPILER_H
 
-#if defined __clang_analyzer__ || defined __COVERITY__
-#define QEMU_STATIC_ANALYSIS 1
-#endif
 
 /*----------------------------------------------------------------------------
 | The macro QEMU_GNUC_PREREQ tests for minimum version of the GNU C compiler.
@@ -44,8 +41,6 @@
 # define QEMU_PACKED __attribute__((packed))
 #endif
 
-#define QEMU_ALIGNED(X) __attribute__((aligned(X)))
-
 #ifndef glue
 #define xglue(x, y) x ## y
 #define glue(x, y) xglue(x, y)
index 8d4b2b6..3b8ecb0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef QEMU_CONFIG_FILE_H
-#define QEMU_CONFIG_FILE_H
+#ifndef QEMU_CONFIG_H
+#define QEMU_CONFIG_H
 
 #include "qemu/option.h"
 #include "qapi/qmp/qdict.h"
@@ -12,6 +12,7 @@ void qemu_add_opts(QemuOptsList *list);
 void qemu_add_drive_opts(QemuOptsList *list);
 int qemu_set_option(const char *str);
 int qemu_global_option(const char *str);
+void qemu_add_globals(void);
 
 void qemu_config_write(FILE *fp);
 int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname);
@@ -27,4 +28,4 @@ void qemu_config_parse_qdict(QDict *options, QemuOptsList **lists,
  */
 int qemu_read_default_config_files(bool userconfig);
 
-#endif /* QEMU_CONFIG_FILE_H */
+#endif /* QEMU_CONFIG_H */
index ac8d4c9..305fe76 100644 (file)
@@ -61,14 +61,16 @@ typedef void coroutine_fn CoroutineEntry(void *opaque);
  * Create a new coroutine
  *
  * Use qemu_coroutine_enter() to actually transfer control to the coroutine.
- * The opaque argument is passed as the argument to the entry point.
  */
-Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque);
+Coroutine *qemu_coroutine_create(CoroutineEntry *entry);
 
 /**
  * Transfer control to a coroutine
+ *
+ * The opaque argument is passed as the argument to the entry point when
+ * entering the coroutine for the first time.  It is subsequently ignored.
  */
-void qemu_coroutine_enter(Coroutine *coroutine);
+void qemu_coroutine_enter(Coroutine *coroutine, void *opaque);
 
 /**
  * Transfer control back to a coroutine's caller
@@ -100,7 +102,7 @@ bool qemu_in_coroutine(void);
  * are built.
  */
 typedef struct CoQueue {
-    QSIMPLEQ_HEAD(, Coroutine) entries;
+    QTAILQ_HEAD(, Coroutine) entries;
 } CoQueue;
 
 /**
index 581a7f5..42d6838 100644 (file)
@@ -41,8 +41,8 @@ struct Coroutine {
     QSLIST_ENTRY(Coroutine) pool_next;
 
     /* Coroutines that should be woken up when we yield or terminate */
-    QSIMPLEQ_HEAD(, Coroutine) co_queue_wakeup;
-    QSIMPLEQ_ENTRY(Coroutine) co_queue_next;
+    QTAILQ_HEAD(, Coroutine) co_queue_wakeup;
+    QTAILQ_ENTRY(Coroutine) co_queue_next;
 };
 
 Coroutine *qemu_coroutine_new(void);
index 3e4ea23..db7adad 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef QEMU_CUTILS_H
-#define QEMU_CUTILS_H
+#define QEMU_CUTILS_H 1
 
 #include "qemu/fprintf-fn.h"
 
index 499ec8b..7a2a363 100644 (file)
@@ -10,8 +10,9 @@
  * See the COPYING file in the top-level directory.
  */
 
-#ifndef QEMU_ERROR_REPORT_H
-#define QEMU_ERROR_REPORT_H
+#ifndef QEMU_ERROR_H
+#define QEMU_ERROR_H
+
 
 typedef struct Location {
     /* all members are private to qemu-error.c */
diff --git a/include/qemu/fifo32.h b/include/qemu/fifo32.h
deleted file mode 100644 (file)
index 4e9fd1b..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Generic FIFO32 component, based on FIFO8.
- *
- * Copyright (c) 2016 Jean-Christophe Dubois
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef FIFO32_H
-#define FIFO32_H
-
-#include "qemu/fifo8.h"
-
-typedef struct {
-    Fifo8 fifo;
-} Fifo32;
-
-/**
- * fifo32_create:
- * @fifo: struct Fifo32 to initialise with new FIFO
- * @capacity: capacity of the newly created FIFO expressed in 32 bit words
- *
- * Create a FIFO of the specified size. Clients should call fifo32_destroy()
- * when finished using the fifo. The FIFO is initially empty.
- */
-
-static inline void fifo32_create(Fifo32 *fifo, uint32_t capacity)
-{
-    fifo8_create(&fifo->fifo, capacity * sizeof(uint32_t));
-}
-
-/**
- * fifo32_destroy:
- * @fifo: FIFO to cleanup
- *
- * Cleanup a FIFO created with fifo32_create(). Frees memory created for FIFO
- * storage. The FIFO is no longer usable after this has been called.
- */
-
-static inline void fifo32_destroy(Fifo32 *fifo)
-{
-    fifo8_destroy(&fifo->fifo);
-}
-
-/**
- * fifo32_num_free:
- * @fifo: FIFO to check
- *
- * Return the number of free uint32_t slots in the FIFO.
- *
- * Returns: Number of free 32 bit words.
- */
-
-static inline uint32_t fifo32_num_free(Fifo32 *fifo)
-{
-    return DIV_ROUND_UP(fifo8_num_free(&fifo->fifo), sizeof(uint32_t));
-}
-
-/**
- * fifo32_num_used:
- * @fifo: FIFO to check
- *
- * Return the number of used uint32_t slots in the FIFO.
- *
- * Returns: Number of used 32 bit words.
- */
-
-static inline uint32_t fifo32_num_used(Fifo32 *fifo)
-{
-    return DIV_ROUND_UP(fifo8_num_used(&fifo->fifo), sizeof(uint32_t));
-}
-
-/**
- * fifo32_push:
- * @fifo: FIFO to push to
- * @data: 32 bits data word to push
- *
- * Push a 32 bits data word to the FIFO. Behaviour is undefined if the FIFO
- * is full. Clients are responsible for checking for fullness using
- * fifo32_is_full().
- */
-
-static inline void fifo32_push(Fifo32 *fifo, uint32_t data)
-{
-    int i;
-
-    for (i = 0; i < sizeof(data); i++) {
-        fifo8_push(&fifo->fifo, data & 0xff);
-        data >>= 8;
-    }
-}
-
-/**
- * fifo32_push_all:
- * @fifo: FIFO to push to
- * @data: data to push
- * @size: number of 32 bit words to push
- *
- * Push a 32 bit word array to the FIFO. Behaviour is undefined if the FIFO
- * is full. Clients are responsible for checking the space left in the FIFO
- * using fifo32_num_free().
- */
-
-static inline void fifo32_push_all(Fifo32 *fifo, const uint32_t *data,
-                                   uint32_t num)
-{
-    int i;
-
-    for (i = 0; i < num; i++) {
-        fifo32_push(fifo, data[i]);
-    }
-}
-
-/**
- * fifo32_pop:
- * @fifo: fifo to pop from
- *
- * Pop a 32 bits data word from the FIFO. Behaviour is undefined if the FIFO
- * is empty. Clients are responsible for checking for emptiness using
- * fifo32_is_empty().
- *
- * Returns: The popped 32 bits data word.
- */
-
-static inline uint32_t fifo32_pop(Fifo32 *fifo)
-{
-    uint32_t ret = 0;
-    int i;
-
-    for (i = 0; i < sizeof(uint32_t); i++) {
-        ret |= (fifo8_pop(&fifo->fifo) << (i * 8));
-    }
-
-    return ret;
-}
-
-/**
- * There is no fifo32_pop_buf() because the data is not stored in the buffer
- * as a set of native-order words.
- */
-
-/**
- * fifo32_reset:
- * @fifo: FIFO to reset
- *
- * Reset a FIFO. All data is discarded and the FIFO is emptied.
- */
-
-static inline void fifo32_reset(Fifo32 *fifo)
-{
-    fifo8_reset(&fifo->fifo);
-}
-
-/**
- * fifo32_is_empty:
- * @fifo: FIFO to check
- *
- * Check if a FIFO is empty.
- *
- * Returns: True if the fifo is empty, false otherwise.
- */
-
-static inline bool fifo32_is_empty(Fifo32 *fifo)
-{
-    return fifo8_is_empty(&fifo->fifo);
-}
-
-/**
- * fifo32_is_full:
- * @fifo: FIFO to check
- *
- * Check if a FIFO is full.
- *
- * Returns: True if the fifo is full, false otherwise.
- */
-
-static inline bool fifo32_is_full(Fifo32 *fifo)
-{
-    return fifo8_num_free(&fifo->fifo) < sizeof(uint32_t);
-}
-
-#define VMSTATE_FIFO32(_field, _state) VMSTATE_FIFO8(_field.fifo, _state)
-
-#endif /* FIFO32_H */
index 24b3644..8820780 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef QEMU_FIFO8_H
-#define QEMU_FIFO8_H
+#ifndef FIFO_H
+#define FIFO_H
 
 #include "migration/vmstate.h"
 
@@ -157,4 +157,4 @@ extern const VMStateDescription vmstate_fifo8;
     .offset     = vmstate_offset_value(_state, _field, Fifo8),       \
 }
 
-#endif /* QEMU_FIFO8_H */
+#endif /* FIFO_H */
index 9068a96..b6bad35 100644 (file)
@@ -6,7 +6,8 @@
  */
 
 #ifndef QEMU_FPRINTF_FN_H
-#define QEMU_FPRINTF_FN_H
+#define QEMU_FPRINTF_FN_H 1
+
 
 typedef int (*fprintf_function)(FILE *f, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
index 8ab721e..e29188c 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #ifndef HBITMAP_H
-#define HBITMAP_H
+#define HBITMAP_H 1
 
 #include "bitops.h"
 #include "host-utils.h"
index 328d2a8..e39a66e 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef QEMU_HELP_OPTION_H
-#define QEMU_HELP_OPTION_H
+#define QEMU_HELP_OPTION_H 1
 
 /**
  * is_help_option:
index 46187bb..1cdae0d 100644 (file)
@@ -22,9 +22,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
 #ifndef HOST_UTILS_H
-#define HOST_UTILS_H
+#define HOST_UTILS_H 1
 
 #include "qemu/bswap.h"
 
@@ -487,7 +486,7 @@ static inline uint64_t revbit64(uint64_t x)
 static inline bool is_power_of_2(uint64_t value)
 {
     if (!value) {
-        return false;
+        return 0;
     }
 
     return !(value & (value - 1));
index 40c7010..7d90335 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef QEMU_ID_H
-#define QEMU_ID_H
+#define QEMU_ID_H 1
 
 typedef enum IdSubSystems {
     ID_QDEV,
index 00bf37f..c52f136 100644 (file)
@@ -42,7 +42,6 @@ static inline bool qemu_log_separate(void)
 #define CPU_LOG_TB_NOCHAIN (1 << 13)
 #define CPU_LOG_PAGE       (1 << 14)
 #define LOG_TRACE          (1 << 15)
-#define CPU_LOG_TB_OP_IND  (1 << 16)
 
 /* Returns true if a bit is set in the current loglevel mask
  */
@@ -55,7 +54,7 @@ static inline bool qemu_loglevel_mask(int mask)
 
 /* main logging function
  */
-int GCC_FMT_ATTR(1, 2) qemu_log(const char *fmt, ...);
+void GCC_FMT_ATTR(1, 2) qemu_log(const char *fmt, ...);
 
 /* vfprintf-like logging function
  */
@@ -105,10 +104,23 @@ typedef struct QEMULogItem {
 
 extern const QEMULogItem qemu_log_items[];
 
-void qemu_set_log(int log_flags);
-void qemu_log_needs_buffers(void);
-void qemu_set_log_filename(const char *filename, Error **errp);
-void qemu_set_dfilter_ranges(const char *ranges, Error **errp);
+/* This is the function that actually does the work of
+ * changing the log level; it should only be accessed via
+ * the qemu_set_log() wrapper.
+ */
+void do_qemu_set_log(int log_flags, bool use_own_buffers);
+
+static inline void qemu_set_log(int log_flags)
+{
+#ifdef CONFIG_USER_ONLY
+    do_qemu_set_log(log_flags, true);
+#else
+    do_qemu_set_log(log_flags, false);
+#endif
+}
+
+void qemu_set_log_filename(const char *filename);
+void qemu_set_dfilter_ranges(const char *ranges);
 bool qemu_log_in_addr_range(uint64_t addr);
 int qemu_str_to_log_mask(const char *str);
 
index 470f600..19b5de3 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #ifndef QEMU_MAIN_LOOP_H
-#define QEMU_MAIN_LOOP_H
+#define QEMU_MAIN_LOOP_H 1
 
 #include "block/aio.h"
 
@@ -64,11 +64,11 @@ int qemu_init_main_loop(Error **errp);
  *
  *     void enter_co_bh(void *opaque) {
  *         QEMUCoroutine *co = opaque;
- *         qemu_coroutine_enter(co);
+ *         qemu_coroutine_enter(co, NULL);
  *     }
  *
  *     ...
- *     QEMUCoroutine *co = qemu_coroutine_create(coroutine_entry, NULL);
+ *     QEMUCoroutine *co = qemu_coroutine_create(coroutine_entry);
  *     QEMUBH *start_bh = qemu_bh_new(enter_co_bh, co);
  *     qemu_bh_schedule(start_bh);
  *     while (...) {
index 933c024..0899b2f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef QEMU_MMAP_ALLOC_H
-#define QEMU_MMAP_ALLOC_H
+#ifndef QEMU_MMAP_ALLOC
+#define QEMU_MMAP_ALLOC
 
 #include "qemu-common.h"
 
index 1f9e3f9..8542d2d 100644 (file)
@@ -23,8 +23,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef QEMU_OPTION_H
-#define QEMU_OPTION_H
+#ifndef QEMU_OPTIONS_H
+#define QEMU_OPTIONS_H
 
 #include "qemu/queue.h"
 #include "qapi/qmp/qdict.h"
index 26b1d9e..6432c1a 100644 (file)
@@ -23,8 +23,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef QEMU_OPTION_INT_H
-#define QEMU_OPTION_INT_H
+#ifndef QEMU_OPTIONS_INTERNAL_H
+#define QEMU_OPTIONS_INTERNAL_H
 
 #include "qemu/option.h"
 #include "qemu/error-report.h"
index 9e9fa61..af83b1a 100644 (file)
@@ -30,8 +30,6 @@
 #include "config-host.h"
 #ifdef NEED_CPU_H
 #include "config-target.h"
-#else
-#include "exec/poison.h"
 #endif
 #include "qemu/compiler.h"
 
@@ -158,27 +156,9 @@ extern int daemon(int, int);
 /* Round number down to multiple */
 #define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m))
 
-/* Round number up to multiple. Safe when m is not a power of 2 (see
- * ROUND_UP for a faster version when a power of 2 is guaranteed) */
+/* Round number up to multiple */
 #define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m))
 
-/* Check if n is a multiple of m */
-#define QEMU_IS_ALIGNED(n, m) (((n) % (m)) == 0)
-
-/* n-byte align pointer down */
-#define QEMU_ALIGN_PTR_DOWN(p, n) \
-    ((typeof(p))QEMU_ALIGN_DOWN((uintptr_t)(p), (n)))
-
-/* n-byte align pointer up */
-#define QEMU_ALIGN_PTR_UP(p, n) \
-    ((typeof(p))QEMU_ALIGN_UP((uintptr_t)(p), (n)))
-
-/* Check if pointer p is n-bytes aligned */
-#define QEMU_PTR_IS_ALIGNED(p, n) QEMU_IS_ALIGNED((uintptr_t)(p), (n))
-
-/* Round number up to multiple. Requires that d be a power of 2 (see
- * QEMU_ALIGN_UP for a safer but slower version on arbitrary
- * numbers) */
 #ifndef ROUND_UP
 #define ROUND_UP(n,d) (((n) + (d) - 1) & -(d))
 #endif
@@ -202,6 +182,8 @@ void qemu_anon_ram_free(void *ptr, size_t size);
 
 #if defined(CONFIG_MADVISE)
 
+#include <sys/mman.h>
+
 #define QEMU_MADV_WILLNEED  MADV_WILLNEED
 #define QEMU_MADV_DONTNEED  MADV_DONTNEED
 #ifdef MADV_DONTFORK
@@ -283,9 +265,6 @@ int qemu_madvise(void *addr, size_t len, int advice);
 
 int qemu_open(const char *name, int flags, ...);
 int qemu_close(int fd);
-#ifndef _WIN32
-int qemu_dup(int fd);
-#endif
 
 #if defined(__HAIKU__) && defined(__i386__)
 #define FMT_pid "%ld"
@@ -333,15 +312,6 @@ static inline void qemu_timersub(const struct timeval *val1,
 
 void qemu_set_cloexec(int fd);
 
-/* Starting on QEMU 2.5, qemu_hw_version() returns "2.5+" by default
- * instead of QEMU_VERSION, so setting hw_version on MachineClass
- * is no longer mandatory.
- *
- * Do NOT change this string, or it will break compatibility on all
- * machine classes that don't set hw_version.
- */
-#define QEMU_HW_VERSION "2.5+"
-
 /* QEMU "hardware version" setting. Used to replace code that exposed
  * QEMU_VERSION to guests in the past and need to keep compatibility.
  * Do not use qemu_hw_version() in new code.
@@ -383,7 +353,7 @@ unsigned long qemu_getauxval(unsigned long type);
 
 void qemu_set_tty_echo(int fd, bool echo);
 
-void os_mem_prealloc(int fd, char *area, size_t sz, Error **errp);
+void os_mem_prealloc(int fd, char *area, size_t sz);
 
 int qemu_read_password(char *buf, int buf_size);
 
index c6292a9..ed5fee0 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef QEMU_PATH_H
-#define QEMU_PATH_H
+#define QEMU_PATH_H 1
 
 void init_paths(const char *prefix);
 const char *path(const char *pathname);
diff --git a/include/qemu/processor.h b/include/qemu/processor.h
deleted file mode 100644 (file)
index 8b25702..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016, Emilio G. Cota <cota@braap.org>
- *
- * License: GNU GPL, version 2.
- *   See the COPYING file in the top-level directory.
- */
-#ifndef QEMU_PROCESSOR_H
-#define QEMU_PROCESSOR_H
-
-#include "qemu/atomic.h"
-
-#if defined(__i386__) || defined(__x86_64__)
-# define cpu_relax() asm volatile("rep; nop" ::: "memory")
-
-#elif defined(__ia64__)
-# define cpu_relax() asm volatile("hint @pause" ::: "memory")
-
-#elif defined(__aarch64__)
-# define cpu_relax() asm volatile("yield" ::: "memory")
-
-#elif defined(__powerpc64__)
-/* set Hardware Multi-Threading (HMT) priority to low; then back to medium */
-# define cpu_relax() asm volatile("or 1, 1, 1;" \
-                                  "or 2, 2, 2;" ::: "memory")
-
-#else
-# define cpu_relax() barrier()
-#endif
-
-#endif /* QEMU_PROCESSOR_H */
diff --git a/include/qemu/qdist.h b/include/qemu/qdist.h
deleted file mode 100644 (file)
index 54ece76..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2016, Emilio G. Cota <cota@braap.org>
- *
- * License: GNU GPL, version 2 or later.
- *   See the COPYING file in the top-level directory.
- */
-#ifndef QEMU_QDIST_H
-#define QEMU_QDIST_H
-
-#include "qemu-common.h"
-#include "qemu/bitops.h"
-
-/*
- * Samples with the same 'x value' end up in the same qdist_entry,
- * e.g. inc(0.1) and inc(0.1) end up as {x=0.1, count=2}.
- *
- * Binning happens only at print time, so that we retain the flexibility to
- * choose the binning. This might not be ideal for workloads that do not care
- * much about precision and insert many samples all with different x values;
- * in that case, pre-binning (e.g. entering both 0.115 and 0.097 as 0.1)
- * should be considered.
- */
-struct qdist_entry {
-    double x;
-    unsigned long count;
-};
-
-struct qdist {
-    struct qdist_entry *entries;
-    size_t n;
-    size_t size;
-};
-
-#define QDIST_PR_BORDER     BIT(0)
-#define QDIST_PR_LABELS     BIT(1)
-/* the remaining options only work if PR_LABELS is set */
-#define QDIST_PR_NODECIMAL  BIT(2)
-#define QDIST_PR_PERCENT    BIT(3)
-#define QDIST_PR_100X       BIT(4)
-#define QDIST_PR_NOBINRANGE BIT(5)
-
-void qdist_init(struct qdist *dist);
-void qdist_destroy(struct qdist *dist);
-
-void qdist_add(struct qdist *dist, double x, long count);
-void qdist_inc(struct qdist *dist, double x);
-double qdist_xmin(const struct qdist *dist);
-double qdist_xmax(const struct qdist *dist);
-double qdist_avg(const struct qdist *dist);
-unsigned long qdist_sample_count(const struct qdist *dist);
-size_t qdist_unique_entries(const struct qdist *dist);
-
-/* callers must free the returned string with g_free() */
-char *qdist_pr_plain(const struct qdist *dist, size_t n_groups);
-
-/* callers must free the returned string with g_free() */
-char *qdist_pr(const struct qdist *dist, size_t n_groups, uint32_t opt);
-
-/* Only qdist code and test code should ever call this function */
-void qdist_bin__internal(struct qdist *to, const struct qdist *from, size_t n);
-
-#endif /* QEMU_QDIST_H */
diff --git a/include/qemu/qht.h b/include/qemu/qht.h
deleted file mode 100644 (file)
index 311139b..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2016, Emilio G. Cota <cota@braap.org>
- *
- * License: GNU GPL, version 2 or later.
- *   See the COPYING file in the top-level directory.
- */
-#ifndef QEMU_QHT_H
-#define QEMU_QHT_H
-
-#include "qemu/seqlock.h"
-#include "qemu/thread.h"
-#include "qemu/qdist.h"
-
-struct qht {
-    struct qht_map *map;
-    QemuMutex lock; /* serializes setters of ht->map */
-    unsigned int mode;
-};
-
-/**
- * struct qht_stats - Statistics of a QHT
- * @head_buckets: number of head buckets
- * @used_head_buckets: number of non-empty head buckets
- * @entries: total number of entries
- * @chain: frequency distribution representing the number of buckets in each
- *         chain, excluding empty chains.
- * @occupancy: frequency distribution representing chain occupancy rate.
- *             Valid range: from 0.0 (empty) to 1.0 (full occupancy).
- *
- * An entry is a pointer-hash pair.
- * Each bucket can host several entries.
- * Chains are chains of buckets, whose first link is always a head bucket.
- */
-struct qht_stats {
-    size_t head_buckets;
-    size_t used_head_buckets;
-    size_t entries;
-    struct qdist chain;
-    struct qdist occupancy;
-};
-
-typedef bool (*qht_lookup_func_t)(const void *obj, const void *userp);
-typedef void (*qht_iter_func_t)(struct qht *ht, void *p, uint32_t h, void *up);
-
-#define QHT_MODE_AUTO_RESIZE 0x1 /* auto-resize when heavily loaded */
-
-/**
- * qht_init - Initialize a QHT
- * @ht: QHT to be initialized
- * @n_elems: number of entries the hash table should be optimized for.
- * @mode: bitmask with OR'ed QHT_MODE_*
- */
-void qht_init(struct qht *ht, size_t n_elems, unsigned int mode);
-
-/**
- * qht_destroy - destroy a previously initialized QHT
- * @ht: QHT to be destroyed
- *
- * Call only when there are no readers/writers left.
- */
-void qht_destroy(struct qht *ht);
-
-/**
- * qht_insert - Insert a pointer into the hash table
- * @ht: QHT to insert to
- * @p: pointer to be inserted
- * @hash: hash corresponding to @p
- *
- * Attempting to insert a NULL @p is a bug.
- * Inserting the same pointer @p with different @hash values is a bug.
- *
- * In case of successful operation, smp_wmb() is implied before the pointer is
- * inserted into the hash table.
- *
- * Returns true on sucess.
- * Returns false if the @p-@hash pair already exists in the hash table.
- */
-bool qht_insert(struct qht *ht, void *p, uint32_t hash);
-
-/**
- * qht_lookup - Look up a pointer in a QHT
- * @ht: QHT to be looked up
- * @func: function to compare existing pointers against @userp
- * @userp: pointer to pass to @func
- * @hash: hash of the pointer to be looked up
- *
- * Needs to be called under an RCU read-critical section.
- *
- * smp_read_barrier_depends() is implied before the call to @func.
- *
- * The user-provided @func compares pointers in QHT against @userp.
- * If the function returns true, a match has been found.
- *
- * Returns the corresponding pointer when a match is found.
- * Returns NULL otherwise.
- */
-void *qht_lookup(struct qht *ht, qht_lookup_func_t func, const void *userp,
-                 uint32_t hash);
-
-/**
- * qht_remove - remove a pointer from the hash table
- * @ht: QHT to remove from
- * @p: pointer to be removed
- * @hash: hash corresponding to @p
- *
- * Attempting to remove a NULL @p is a bug.
- *
- * Just-removed @p pointers cannot be immediately freed; they need to remain
- * valid until the end of the RCU grace period in which qht_remove() is called.
- * This guarantees that concurrent lookups will always compare against valid
- * data.
- *
- * Returns true on success.
- * Returns false if the @p-@hash pair was not found.
- */
-bool qht_remove(struct qht *ht, const void *p, uint32_t hash);
-
-/**
- * qht_reset - reset a QHT
- * @ht: QHT to be reset
- *
- * All entries in the hash table are reset. No resizing is performed.
- *
- * If concurrent readers may exist, the objects pointed to by the hash table
- * must remain valid for the existing RCU grace period -- see qht_remove().
- * See also: qht_reset_size()
- */
-void qht_reset(struct qht *ht);
-
-/**
- * qht_reset_size - reset and resize a QHT
- * @ht: QHT to be reset and resized
- * @n_elems: number of entries the resized hash table should be optimized for.
- *
- * Returns true if the resize was necessary and therefore performed.
- * Returns false otherwise.
- *
- * If concurrent readers may exist, the objects pointed to by the hash table
- * must remain valid for the existing RCU grace period -- see qht_remove().
- * See also: qht_reset(), qht_resize().
- */
-bool qht_reset_size(struct qht *ht, size_t n_elems);
-
-/**
- * qht_resize - resize a QHT
- * @ht: QHT to be resized
- * @n_elems: number of entries the resized hash table should be optimized for
- *
- * Returns true on success.
- * Returns false if the resize was not necessary and therefore not performed.
- * See also: qht_reset_size().
- */
-bool qht_resize(struct qht *ht, size_t n_elems);
-
-/**
- * qht_iter - Iterate over a QHT
- * @ht: QHT to be iterated over
- * @func: function to be called for each entry in QHT
- * @userp: additional pointer to be passed to @func
- *
- * Each time it is called, user-provided @func is passed a pointer-hash pair,
- * plus @userp.
- */
-void qht_iter(struct qht *ht, qht_iter_func_t func, void *userp);
-
-/**
- * qht_statistics_init - Gather statistics from a QHT
- * @ht: QHT to gather statistics from
- * @stats: pointer to a struct qht_stats to be filled in
- *
- * Does NOT need to be called under an RCU read-critical section,
- * since it does not dereference any pointers stored in the hash table.
- *
- * When done with @stats, pass the struct to qht_statistics_destroy().
- * Failing to do this will leak memory.
- */
-void qht_statistics_init(struct qht *ht, struct qht_stats *stats);
-
-/**
- * qht_statistics_destroy - Destroy a struct qht_stats
- * @stats: stuct qht_stats to be destroyed
- *
- * See also: qht_statistics_init().
- */
-void qht_statistics_destroy(struct qht_stats *stats);
-
-#endif /* QEMU_QHT_H */
index c2b6c81..f781aa2 100644 (file)
@@ -37,8 +37,8 @@
  *      @(#)queue.h     8.5 (Berkeley) 8/20/94
  */
 
-#ifndef QEMU_SYS_QUEUE_H
-#define QEMU_SYS_QUEUE_H
+#ifndef QEMU_SYS_QUEUE_H_
+#define QEMU_SYS_QUEUE_H_
 
 /*
  * This file defines four types of data structures: singly-linked lists,
@@ -436,4 +436,4 @@ struct {                                                                \
 #define QTAILQ_PREV(elm, headname, field) \
         (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
 
-#endif /* QEMU_SYS_QUEUE_H */
+#endif  /* !QEMU_SYS_QUEUE_H_ */
index f28f0c1..c903eb5 100644 (file)
@@ -1,23 +1,3 @@
-/*
- * QEMU 64-bit address ranges
- *
- * Copyright (c) 2015-2016 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
 #ifndef QEMU_RANGE_H
 #define QEMU_RANGE_H
 
 /*
  * Operations on 64 bit address ranges.
  * Notes:
- * - Ranges must not wrap around 0, but can include UINT64_MAX.
+ *   - ranges must not wrap around 0, but can include the last byte ~0x0LL.
+ *   - this can not represent a full 0 to ~0x0LL range.
  */
 
+/* A structure representing a range of addresses. */
 struct Range {
-    /*
-     * Do not access members directly, use the functions!
-     * A non-empty range has @lob <= @upb.
-     * An empty range has @lob == @upb + 1.
-     */
-    uint64_t lob;        /* inclusive lower bound */
-    uint64_t upb;        /* inclusive upper bound */
+    uint64_t begin; /* First byte of the range, or 0 if empty. */
+    uint64_t end;   /* 1 + the last byte. 0 if range empty or ends at ~0x0LL. */
 };
 
-static inline void range_invariant(Range *range)
-{
-    assert(range->lob <= range->upb || range->lob == range->upb + 1);
-}
-
-/* Compound literal encoding the empty range */
-#define range_empty ((Range){ .lob = 1, .upb = 0 })
-
-/* Is @range empty? */
-static inline bool range_is_empty(Range *range)
-{
-    range_invariant(range);
-    return range->lob > range->upb;
-}
-
-/* Does @range contain @val? */
-static inline bool range_contains(Range *range, uint64_t val)
-{
-    return val >= range->lob && val <= range->upb;
-}
-
-/* Initialize @range to the empty range */
-static inline void range_make_empty(Range *range)
-{
-    *range = range_empty;
-    assert(range_is_empty(range));
-}
-
-/*
- * Initialize @range to span the interval [@lob,@upb].
- * Both bounds are inclusive.
- * The interval must not be empty, i.e. @lob must be less than or
- * equal @upb.
- */
-static inline void range_set_bounds(Range *range, uint64_t lob, uint64_t upb)
-{
-    range->lob = lob;
-    range->upb = upb;
-    assert(!range_is_empty(range));
-}
-
-/*
- * Initialize @range to span the interval [@lob,@upb_plus1).
- * The lower bound is inclusive, the upper bound is exclusive.
- * Zero @upb_plus1 is special: if @lob is also zero, set @range to the
- * empty range.  Else, set @range to [@lob,UINT64_MAX].
- */
-static inline void range_set_bounds1(Range *range,
-                                     uint64_t lob, uint64_t upb_plus1)
-{
-    if (!lob && !upb_plus1) {
-        *range = range_empty;
-    } else {
-        range->lob = lob;
-        range->upb = upb_plus1 - 1;
-    }
-    range_invariant(range);
-}
-
-/* Return @range's lower bound.  @range must not be empty. */
-static inline uint64_t range_lob(Range *range)
-{
-    assert(!range_is_empty(range));
-    return range->lob;
-}
-
-/* Return @range's upper bound.  @range must not be empty. */
-static inline uint64_t range_upb(Range *range)
-{
-    assert(!range_is_empty(range));
-    return range->upb;
-}
-
-/*
- * Extend @range to the smallest interval that includes @extend_by, too.
- */
 static inline void range_extend(Range *range, Range *extend_by)
 {
-    if (range_is_empty(extend_by)) {
+    if (!extend_by->begin && !extend_by->end) {
         return;
     }
-    if (range_is_empty(range)) {
+    if (!range->begin && !range->end) {
         *range = *extend_by;
         return;
     }
-    if (range->lob > extend_by->lob) {
-        range->lob = extend_by->lob;
+    if (range->begin > extend_by->begin) {
+        range->begin = extend_by->begin;
     }
-    if (range->upb < extend_by->upb) {
-        range->upb = extend_by->upb;
+    /* Compare last byte in case region ends at ~0x0LL */
+    if (range->end - 1 < extend_by->end - 1) {
+        range->end = extend_by->end;
     }
-    range_invariant(range);
 }
 
 /* Get last byte of a range from offset + length.
@@ -158,6 +59,75 @@ static inline int ranges_overlap(uint64_t first1, uint64_t len1,
     return !(last2 < first1 || last1 < first2);
 }
 
-GList *range_list_insert(GList *list, Range *data);
+/* 0,1 can merge with 1,2 but don't overlap */
+static inline bool ranges_can_merge(Range *range1, Range *range2)
+{
+    return !(range1->end < range2->begin || range2->end < range1->begin);
+}
+
+static inline int range_merge(Range *range1, Range *range2)
+{
+    if (ranges_can_merge(range1, range2)) {
+        if (range1->end < range2->end) {
+            range1->end = range2->end;
+        }
+        if (range1->begin > range2->begin) {
+            range1->begin = range2->begin;
+        }
+        return 0;
+    }
+
+    return -1;
+}
+
+static inline GList *g_list_insert_sorted_merged(GList *list,
+                                                 gpointer data,
+                                                 GCompareFunc func)
+{
+    GList *l, *next = NULL;
+    Range *r, *nextr;
+
+    if (!list) {
+        list = g_list_insert_sorted(list, data, func);
+        return list;
+    }
+
+    nextr = data;
+    l = list;
+    while (l && l != next && nextr) {
+        r = l->data;
+        if (ranges_can_merge(r, nextr)) {
+            range_merge(r, nextr);
+            l = g_list_remove_link(l, next);
+            next = g_list_next(l);
+            if (next) {
+                nextr = next->data;
+            } else {
+                nextr = NULL;
+            }
+        } else {
+            l = g_list_next(l);
+        }
+    }
+
+    if (!l) {
+        list = g_list_insert_sorted(list, data, func);
+    }
+
+    return list;
+}
+
+static inline gint range_compare(gconstpointer a, gconstpointer b)
+{
+    Range *ra = (Range *)a, *rb = (Range *)b;
+    if (ra->begin == rb->begin && ra->end == rb->end) {
+        return 0;
+    } else if (range_get_last(ra->begin, ra->end) <
+               range_get_last(rb->begin, rb->end)) {
+        return -1;
+    } else {
+        return 1;
+    }
+}
 
 #endif
index 8da1232..d413a4a 100644 (file)
  */
 
 #ifndef QEMU_RATELIMIT_H
-#define QEMU_RATELIMIT_H
+#define QEMU_RATELIMIT_H 1
 
 typedef struct {
-    int64_t slice_start_time;
-    int64_t slice_end_time;
+    int64_t next_slice_time;
     uint64_t slice_quota;
     uint64_t slice_ns;
     uint64_t dispatched;
 } RateLimit;
 
-/** Calculate and return delay for next request in ns
- *
- * Record that we sent @p n data units. If we may send more data units
- * in the current time slice, return 0 (i.e. no delay). Otherwise
- * return the amount of time (in ns) until the start of the next time
- * slice that will permit sending the next chunk of data.
- *
- * Recording sent data units even after exceeding the quota is
- * permitted; the time slice will be extended accordingly.
- */
 static inline int64_t ratelimit_calculate_delay(RateLimit *limit, uint64_t n)
 {
     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
-    uint64_t delay_slices;
 
-    assert(limit->slice_quota && limit->slice_ns);
-
-    if (limit->slice_end_time < now) {
-        /* Previous, possibly extended, time slice finished; reset the
-         * accounting. */
-        limit->slice_start_time = now;
-        limit->slice_end_time = now + limit->slice_ns;
+    if (limit->next_slice_time < now) {
+        limit->next_slice_time = now + limit->slice_ns;
         limit->dispatched = 0;
     }
-
-    limit->dispatched += n;
-    if (limit->dispatched < limit->slice_quota) {
-        /* We may send further data within the current time slice, no
-         * need to delay the next request. */
+    if (limit->dispatched == 0 || limit->dispatched + n <= limit->slice_quota) {
+        limit->dispatched += n;
         return 0;
+    } else {
+        limit->dispatched = n;
+        return limit->next_slice_time - now;
     }
-
-    /* Quota exceeded. Calculate the next time slice we may start
-     * sending data again. */
-    delay_slices = (limit->dispatched + limit->slice_quota - 1) /
-        limit->slice_quota;
-    limit->slice_end_time = limit->slice_start_time +
-        delay_slices * limit->slice_ns;
-    return limit->slice_end_time - now;
 }
 
 static inline void ratelimit_set_speed(RateLimit *limit, uint64_t speed,
                                        uint64_t slice_ns)
 {
     limit->slice_ns = slice_ns;
-    limit->slice_quota = MAX(((double)speed * slice_ns) / 1000000000ULL, 1);
+    limit->slice_quota = ((double)speed * slice_ns)/1000000000ULL;
 }
 
 #endif
index 83ae280..56d3a68 100644 (file)
@@ -23,6 +23,7 @@
  * IBM's contributions to this file may be relicensed under LGPLv2 or later.
  */
 
+#include <glib.h>
 
 #include "qemu/thread.h"
 #include "qemu/queue.h"
index 01be774..3aca7a5 100644 (file)
@@ -131,4 +131,4 @@ extern "C" {
 #ifdef __cplusplus
 }
 #endif
-#endif /* QEMU_RCU_QUEUE_H */
+#endif /* QEMU_RCU_QUEUE.H */
index c08cf74..49efe4e 100644 (file)
@@ -60,4 +60,4 @@ ReadLineState *readline_init(ReadLinePrintfFunc *printf_func,
                              void *opaque,
                              ReadLineCompletionFunc *completion_finder);
 
-#endif /* READLINE_H */
+#endif /* !READLINE_H */
index 2e2be4c..70b01fd 100644 (file)
  * See the COPYING file in the top-level directory.
  *
  */
-
 #ifndef QEMU_SEQLOCK_H
-#define QEMU_SEQLOCK_H
+#define QEMU_SEQLOCK_H 1
 
-#include "qemu/atomic.h"
-#include "qemu/thread.h"
+#include <qemu/atomic.h>
+#include <qemu/thread.h>
 
 typedef struct QemuSeqLock QemuSeqLock;
 
 struct QemuSeqLock {
+    QemuMutex *mutex;
     unsigned sequence;
 };
 
-static inline void seqlock_init(QemuSeqLock *sl)
+static inline void seqlock_init(QemuSeqLock *sl, QemuMutex *mutex)
 {
+    sl->mutex = mutex;
     sl->sequence = 0;
 }
 
 /* Lock out other writers and update the count.  */
-static inline void seqlock_write_begin(QemuSeqLock *sl)
+static inline void seqlock_write_lock(QemuSeqLock *sl)
 {
+    if (sl->mutex) {
+        qemu_mutex_lock(sl->mutex);
+    }
     ++sl->sequence;
 
     /* Write sequence before updating other fields.  */
     smp_wmb();
 }
 
-static inline void seqlock_write_end(QemuSeqLock *sl)
+static inline void seqlock_write_unlock(QemuSeqLock *sl)
 {
     /* Write other fields before finalizing sequence.  */
     smp_wmb();
 
     ++sl->sequence;
+    if (sl->mutex) {
+        qemu_mutex_unlock(sl->mutex);
+    }
 }
 
 static inline unsigned seqlock_read_begin(QemuSeqLock *sl)
index 9eb2470..1bd9218 100644 (file)
@@ -1,7 +1,6 @@
 /* headers to use the BSD sockets */
-
-#ifndef QEMU_SOCKETS_H
-#define QEMU_SOCKETS_H
+#ifndef QEMU_SOCKET_H
+#define QEMU_SOCKET_H
 
 #ifdef _WIN32
 
@@ -33,18 +32,25 @@ int socket_set_fast_reuse(int fd);
 typedef void NonBlockingConnectHandler(int fd, Error *err, void *opaque);
 
 InetSocketAddress *inet_parse(const char *str, Error **errp);
+int inet_listen(const char *str, char *ostr, int olen,
+                int socktype, int port_offset, Error **errp);
 int inet_connect(const char *str, Error **errp);
+int inet_nonblocking_connect(const char *str,
+                             NonBlockingConnectHandler *callback,
+                             void *opaque, Error **errp);
 
 NetworkAddressFamily inet_netfamily(int family);
 
 int unix_listen(const char *path, char *ostr, int olen, Error **errp);
 int unix_connect(const char *path, Error **errp);
+int unix_nonblocking_connect(const char *str,
+                             NonBlockingConnectHandler *callback,
+                             void *opaque, Error **errp);
 
 SocketAddress *socket_parse(const char *str, Error **errp);
 int socket_connect(SocketAddress *addr, Error **errp,
                    NonBlockingConnectHandler *callback, void *opaque);
 int socket_listen(SocketAddress *addr, Error **errp);
-void socket_listen_cleanup(int fd, Error **errp);
 int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp);
 
 /* Old, ipv4 only bits.  Don't use for new code. */
@@ -100,19 +106,8 @@ SocketAddress *socket_local_address(int fd, Error **errp);
  */
 SocketAddress *socket_remote_address(int fd, Error **errp);
 
-/**
- * socket_address_to_string:
- * @addr: the socket address struct
- * @errp: pointer to uninitialized error object
- *
- * Get the string representation of the socket
- * address. A pointer to the char array containing
- * string format will be returned, the caller is
- * required to release the returned value when no
- * longer required with g_free.
- *
- * Returns: the socket address in string format, or NULL on error
- */
-char *socket_address_to_string(struct SocketAddress *addr, Error **errp);
 
-#endif /* QEMU_SOCKETS_H */
+void qapi_copy_SocketAddress(SocketAddress **p_dest,
+                             SocketAddress *src);
+
+#endif /* QEMU_SOCKET_H */
index aa03567..eb5c7a1 100644 (file)
@@ -1,7 +1,6 @@
-#ifndef QEMU_THREAD_POSIX_H
-#define QEMU_THREAD_POSIX_H
-
-#include <pthread.h>
+#ifndef __QEMU_THREAD_POSIX_H
+#define __QEMU_THREAD_POSIX_H 1
+#include "pthread.h"
 #include <semaphore.h>
 
 struct QemuMutex {
index c7ce8dc..385ff5f 100644 (file)
@@ -1,7 +1,6 @@
-#ifndef QEMU_THREAD_WIN32_H
-#define QEMU_THREAD_WIN32_H
-
-#include <windows.h>
+#ifndef __QEMU_THREAD_WIN32_H
+#define __QEMU_THREAD_WIN32_H 1
+#include "windows.h"
 
 struct QemuMutex {
     CRITICAL_SECTION lock;
index 31237e9..bdae6df 100644 (file)
@@ -1,8 +1,6 @@
-#ifndef QEMU_THREAD_H
-#define QEMU_THREAD_H
+#ifndef __QEMU_THREAD_H
+#define __QEMU_THREAD_H 1
 
-#include "qemu/processor.h"
-#include "qemu/atomic.h"
 
 typedef struct QemuMutex QemuMutex;
 typedef struct QemuCond QemuCond;
@@ -62,37 +60,4 @@ struct Notifier;
 void qemu_thread_atexit_add(struct Notifier *notifier);
 void qemu_thread_atexit_remove(struct Notifier *notifier);
 
-typedef struct QemuSpin {
-    int value;
-} QemuSpin;
-
-static inline void qemu_spin_init(QemuSpin *spin)
-{
-    __sync_lock_release(&spin->value);
-}
-
-static inline void qemu_spin_lock(QemuSpin *spin)
-{
-    while (unlikely(__sync_lock_test_and_set(&spin->value, true))) {
-        while (atomic_read(&spin->value)) {
-            cpu_relax();
-        }
-    }
-}
-
-static inline bool qemu_spin_trylock(QemuSpin *spin)
-{
-    return __sync_lock_test_and_set(&spin->value, true);
-}
-
-static inline bool qemu_spin_locked(QemuSpin *spin)
-{
-    return atomic_read(&spin->value);
-}
-
-static inline void qemu_spin_unlock(QemuSpin *spin)
-{
-    __sync_lock_release(&spin->value);
-}
-
 #endif
index 309f3d0..471969a 100644 (file)
@@ -4,7 +4,6 @@
 #include "qemu-common.h"
 #include "qemu/notify.h"
 #include "qemu/host-utils.h"
-#include "sysemu/cpus.h"
 
 #define NANOSECONDS_PER_SECOND 1000000000LL
 
index b113fcf..1dcf6f5 100644 (file)
@@ -82,6 +82,7 @@ typedef struct QemuOpt QemuOpt;
 typedef struct QemuOpts QemuOpts;
 typedef struct QemuOptsList QemuOptsList;
 typedef struct QEMUSGList QEMUSGList;
+typedef struct QEMUSizedBuffer QEMUSizedBuffer;
 typedef struct QEMUTimer QEMUTimer;
 typedef struct QEMUTimerListGroup QEMUTimerListGroup;
 typedef struct QObject QObject;
index 71c72db..d873165 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef QEMU_UNICODE_H
-#define QEMU_UNICODE_H
+#define QEMU_UNICODE_H 1
 
 int mod_utf8_codepoint(const char *s, size_t n, char **end);
 
similarity index 95%
rename from include/migration/qjson.h
rename to include/qjson.h
index 2978b5f..7c54fdf 100644 (file)
 #ifndef QEMU_QJSON_H
 #define QEMU_QJSON_H
 
+#define TYPE_QJSON "QJSON"
 typedef struct QJSON QJSON;
 
 QJSON *qjson_new(void);
-void qjson_destroy(QJSON *json);
 void json_prop_str(QJSON *json, const char *name, const char *str);
 void json_prop_int(QJSON *json, const char *name, int64_t val);
 void json_end_array(QJSON *json);
index ce0c406..b7a10f7 100644 (file)
 #include "disas/bfd.h"
 #include "exec/hwaddr.h"
 #include "exec/memattrs.h"
-#include "qemu/bitmap.h"
 #include "qemu/queue.h"
 #include "qemu/thread.h"
-#include "trace/generated-events.h"
 
 typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
                                      void *opaque);
@@ -62,12 +60,6 @@ typedef uint64_t vaddr;
 #define CPU_CLASS(class) OBJECT_CLASS_CHECK(CPUClass, (class), TYPE_CPU)
 #define CPU_GET_CLASS(obj) OBJECT_GET_CLASS(CPUClass, (obj), TYPE_CPU)
 
-typedef enum MMUAccessType {
-    MMU_DATA_LOAD  = 0,
-    MMU_DATA_STORE = 1,
-    MMU_INST_FETCH = 2
-} MMUAccessType;
-
 typedef struct CPUWatchpoint CPUWatchpoint;
 
 typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
@@ -142,7 +134,7 @@ typedef struct CPUClass {
     /*< public >*/
 
     ObjectClass *(*class_by_name)(const char *cpu_model);
-    void (*parse_features)(const char *typename, char *str, Error **errp);
+    void (*parse_features)(CPUState *cpu, char *str, Error **errp);
 
     void (*reset)(CPUState *cpu);
     int reset_dump_flags;
@@ -150,8 +142,7 @@ typedef struct CPUClass {
     void (*do_interrupt)(CPUState *cpu);
     CPUUnassignedAccess do_unassigned_access;
     void (*do_unaligned_access)(CPUState *cpu, vaddr addr,
-                                MMUAccessType access_type,
-                                int mmu_idx, uintptr_t retaddr);
+                                int is_write, int is_user, uintptr_t retaddr);
     bool (*virtio_is_big_endian)(CPUState *cpu);
     int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
                            uint8_t *buf, int len, bool is_write);
@@ -231,15 +222,6 @@ struct kvm_run;
 #define TB_JMP_CACHE_BITS 12
 #define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
 
-/* work queue */
-struct qemu_work_item {
-    struct qemu_work_item *next;
-    void (*func)(void *data);
-    void *data;
-    int done;
-    bool free;
-};
-
 /**
  * CPUState:
  * @cpu_index: CPU index (informative).
@@ -253,11 +235,9 @@ struct qemu_work_item {
  * @halted: Nonzero if the CPU is in suspended state.
  * @stop: Indicates a pending stop request.
  * @stopped: Indicates the CPU has been artificially stopped.
- * @unplug: Indicates a pending CPU unplug request.
  * @crash_occurred: Indicates the OS reported a crash (panic) for this CPU
  * @tcg_exit_req: Set to force TCG to stop executing linked TBs for this
  *           CPU and return to its top level loop.
- * @tb_flushed: Indicates the translation buffer has been flushed.
  * @singlestep_enabled: Flags for single-stepping.
  * @icount_extra: Instructions until next timer event.
  * @icount_decr: Number of cycles left, with interrupt flag in high bit.
@@ -272,6 +252,7 @@ struct qemu_work_item {
  * @as: Pointer to the first AddressSpace, for the convenience of targets which
  *      only have a single AddressSpace
  * @env_ptr: Pointer to subclass-specific CPUArchState field.
+ * @current_tb: Currently executing TB.
  * @gdb_regs: Additional GDB registers.
  * @gdb_num_regs: Number of total registers accessible to GDB.
  * @gdb_num_g_regs: Number of registers in GDB 'g' packets.
@@ -282,7 +263,6 @@ struct qemu_work_item {
  * @kvm_fd: vCPU file descriptor for KVM.
  * @work_mutex: Lock to prevent multiple access to queued_work_*.
  * @queued_work_first: First asynchronous work pending.
- * @trace_dstate: Dynamic tracing state of events for this vCPU (bitmask).
  *
  * State of one CPU core or thread.
  */
@@ -307,10 +287,8 @@ struct CPUState {
     bool created;
     bool stop;
     bool stopped;
-    bool unplug;
     bool crash_occurred;
     bool exit_request;
-    bool tb_flushed;
     uint32_t interrupt_request;
     int singlestep_enabled;
     int64_t icount_extra;
@@ -325,6 +303,7 @@ struct CPUState {
     MemoryRegion *memory;
 
     void *env_ptr; /* CPUArchState */
+    struct TranslationBlock *current_tb;
     struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];
     struct GDBRegisterState *gdb_regs;
     int gdb_num_regs;
@@ -350,9 +329,6 @@ struct CPUState {
     struct KVMState *kvm_state;
     struct kvm_run *kvm_run;
 
-    /* Used for events with 'vcpu' and *without* the 'disabled' properties */
-    DECLARE_BITMAP(trace_dstate, TRACE_VCPU_EVENT_COUNT);
-
     /* TODO Move common fields from CPUArchState here. */
     int cpu_index; /* used by alpha TCG */
     uint32_t halted; /* used by alpha, cris, ppc TCG */
@@ -729,12 +705,12 @@ static inline void cpu_unassigned_access(CPUState *cpu, hwaddr addr,
 }
 
 static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr,
-                                        MMUAccessType access_type,
-                                        int mmu_idx, uintptr_t retaddr)
+                                        int is_write, int is_user,
+                                        uintptr_t retaddr)
 {
     CPUClass *cc = CPU_GET_CLASS(cpu);
 
-    cc->do_unaligned_access(cpu, addr, access_type, mmu_idx, retaddr);
+    cc->do_unaligned_access(cpu, addr, is_write, is_user, retaddr);
 }
 #endif
 
@@ -778,22 +754,6 @@ void cpu_exit(CPUState *cpu);
 void cpu_resume(CPUState *cpu);
 
 /**
- * cpu_remove:
- * @cpu: The CPU to remove.
- *
- * Requests the CPU to be removed.
- */
-void cpu_remove(CPUState *cpu);
-
- /**
- * cpu_remove_sync:
- * @cpu: The CPU to remove.
- *
- * Requests the CPU to be removed and waits till it is removed.
- */
-void cpu_remove_sync(CPUState *cpu);
-
-/**
  * qemu_init_vcpu:
  * @cpu: The vCPU to initialize.
  *
@@ -855,16 +815,6 @@ int cpu_watchpoint_remove(CPUState *cpu, vaddr addr,
 void cpu_watchpoint_remove_by_ref(CPUState *cpu, CPUWatchpoint *watchpoint);
 void cpu_watchpoint_remove_all(CPUState *cpu, int mask);
 
-/**
- * cpu_get_address_space:
- * @cpu: CPU to get address space from
- * @asidx: index identifying which address space to get
- *
- * Return the requested address space of this CPU. @asidx
- * specifies which address space to read.
- */
-AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx);
-
 void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 void cpu_exec_exit(CPUState *cpu);
@@ -883,6 +833,4 @@ extern const struct VMStateDescription vmstate_cpu_common;
     .offset = 0,                                                            \
 }
 
-#define UNASSIGNED_CPU_INDEX -1
-
 #endif
index 5ecc2d1..21bb5ff 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef QEMU_OBJECT_H
 #define QEMU_OBJECT_H
 
+#include <glib.h>
 #include "qapi-types.h"
 #include "qemu/queue.h"
 
@@ -901,7 +902,7 @@ GSList *object_class_get_list(const char *implements_type,
 void object_ref(Object *obj);
 
 /**
- * object_unref:
+ * qdef_unref:
  * @obj: the object
  *
  * Decrease the reference count of a object.  A object cannot be freed as long
@@ -1607,11 +1608,5 @@ int object_child_foreach_recursive(Object *obj,
  */
 Object *container_get(Object *root, const char *path);
 
-/**
- * object_type_get_instance_size:
- * @typename: Name of the Type whose instance_size is required
- *
- * Returns the instance_size of the given @typename.
- */
-size_t object_type_get_instance_size(const char *typename);
+
 #endif
index 4040951..1becea8 100644 (file)
 #define PCI_EXT_CAP_ID_SECPCI  0x19    /* Secondary PCIe Capability */
 #define PCI_EXT_CAP_ID_PMUX    0x1A    /* Protocol Multiplexing */
 #define PCI_EXT_CAP_ID_PASID   0x1B    /* Process Address Space ID */
-#define PCI_EXT_CAP_ID_DPC     0x1D    /* Downstream Port Containment */
-#define PCI_EXT_CAP_ID_MAX     PCI_EXT_CAP_ID_DPC
+#define PCI_EXT_CAP_ID_MAX     PCI_EXT_CAP_ID_PASID
 
 #define PCI_EXT_CAP_DSN_SIZEOF 12
 #define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40
 #define PCI_TPH_CAP_ST_SHIFT   16      /* st table shift */
 #define PCI_TPH_BASE_SIZEOF    12      /* size with no st table */
 
-/* Downstream Port Containment */
-#define PCI_EXP_DPC_CAP                        4       /* DPC Capability */
-#define  PCI_EXP_DPC_CAP_RP_EXT                0x20    /* Root Port Extensions for DPC */
-#define  PCI_EXP_DPC_CAP_POISONED_TLP  0x40    /* Poisoned TLP Egress Blocking Supported */
-#define  PCI_EXP_DPC_CAP_SW_TRIGGER    0x80    /* Software Triggering Supported */
-#define  PCI_EXP_DPC_CAP_DL_ACTIVE     0x1000  /* ERR_COR signal on DL_Active supported */
-
-#define PCI_EXP_DPC_CTL                        6       /* DPC control */
-#define  PCI_EXP_DPC_CTL_EN_NONFATAL   0x02    /* Enable trigger on ERR_NONFATAL message */
-#define  PCI_EXP_DPC_CTL_INT_EN        0x08    /* DPC Interrupt Enable */
-
-#define PCI_EXP_DPC_STATUS             8       /* DPC Status */
-#define  PCI_EXP_DPC_STATUS_TRIGGER    0x01    /* Trigger Status */
-#define  PCI_EXP_DPC_STATUS_INTERRUPT  0x08    /* Interrupt Status */
-
-#define PCI_EXP_DPC_SOURCE_ID          10      /* DPC Source Identifier */
-
 #endif /* LINUX_PCI_REGS_H */
index b30d0cb..bcc445b 100644 (file)
@@ -40,8 +40,6 @@
 #define VIRTIO_CONFIG_S_DRIVER_OK      4
 /* Driver has finished configuring features */
 #define VIRTIO_CONFIG_S_FEATURES_OK    8
-/* Device entered invalid state, driver must reset it */
-#define VIRTIO_CONFIG_S_NEEDS_RESET    0x40
 /* We've given up on this device. */
 #define VIRTIO_CONFIG_S_FAILED         0x80
 
index 15944c1..a74b2fa 100644 (file)
@@ -56,6 +56,6 @@ typedef struct AccelClass {
 
 extern int tcg_tb_size;
 
-void configure_accelerator(MachineState *ms);
+int configure_accelerator(MachineState *ms);
 
 #endif
index d690dfa..c38892f 100644 (file)
@@ -30,6 +30,7 @@ extern const uint32_t arch_type;
 void select_soundhw(const char *optarg);
 void do_acpitable_option(const QemuOpts *opts);
 void do_smbios_option(QemuOpts *opts);
+void cpudef_init(void);
 void audio_init(void);
 int kvm_available(void);
 int xen_available(void);
index af49e19..3f976b4 100644 (file)
@@ -11,8 +11,8 @@
  *
  */
 
-#ifndef QEMU_BALLOON_H
-#define QEMU_BALLOON_H
+#ifndef _QEMU_BALLOON_H
+#define _QEMU_BALLOON_H
 
 #include "qapi-types.h"
 
index 2da4905..c62b6fe 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * QEMU Block backends
  *
- * Copyright (C) 2014-2016 Red Hat, Inc.
+ * Copyright (C) 2014 Red Hat, Inc.
  *
  * Authors:
  *  Markus Armbruster <armbru@redhat.com>,
@@ -14,7 +14,6 @@
 #define BLOCK_BACKEND_H
 
 #include "qemu/iov.h"
-#include "block/throttle-groups.h"
 
 /*
  * TODO Have to include block/block.h for a bunch of block layer
@@ -60,25 +59,8 @@ typedef struct BlockDevOps {
     void (*resize_cb)(void *opaque);
 } BlockDevOps;
 
-/* This struct is embedded in (the private) BlockBackend struct and contains
- * fields that must be public. This is in particular for QLIST_ENTRY() and
- * friends so that BlockBackends can be kept in lists outside block-backend.c */
-typedef struct BlockBackendPublic {
-    /* I/O throttling.
-     * throttle_state tells us if this BlockBackend has I/O limits configured.
-     * io_limits_disabled tells us if they are currently being enforced */
-    CoQueue      throttled_reqs[2];
-    unsigned int io_limits_disabled;
-
-    /* The following fields are protected by the ThrottleGroup lock.
-     * See the ThrottleGroup documentation for details. */
-    ThrottleState *throttle_state;
-    ThrottleTimers throttle_timers;
-    unsigned       pending_reqs[2];
-    QLIST_ENTRY(BlockBackendPublic) round_robin;
-} BlockBackendPublic;
-
-BlockBackend *blk_new(void);
+BlockBackend *blk_new(Error **errp);
+BlockBackend *blk_new_with_bs(Error **errp);
 BlockBackend *blk_new_open(const char *filename, const char *reference,
                            QDict *options, int flags, Error **errp);
 int blk_get_refcnt(BlockBackend *blk);
@@ -88,16 +70,13 @@ void blk_remove_all_bs(void);
 const char *blk_name(BlockBackend *blk);
 BlockBackend *blk_by_name(const char *name);
 BlockBackend *blk_next(BlockBackend *blk);
+BlockDriverState *blk_next_root_bs(BlockDriverState *bs);
 bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp);
 void monitor_remove_blk(BlockBackend *blk);
 
-BlockBackendPublic *blk_get_public(BlockBackend *blk);
-BlockBackend *blk_by_public(BlockBackendPublic *public);
-
 BlockDriverState *blk_bs(BlockBackend *blk);
 void blk_remove_bs(BlockBackend *blk);
 void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs);
-bool bdrv_has_blk(BlockDriverState *bs);
 
 void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow);
 void blk_iostatus_enable(BlockBackend *blk);
@@ -111,42 +90,40 @@ void blk_attach_dev_nofail(BlockBackend *blk, void *dev);
 void blk_detach_dev(BlockBackend *blk, void *dev);
 void *blk_get_attached_dev(BlockBackend *blk);
 void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
-int blk_pread_unthrottled(BlockBackend *blk, int64_t offset, uint8_t *buf,
-                          int count);
-int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
-                               unsigned int bytes, QEMUIOVector *qiov,
-                               BdrvRequestFlags flags);
-int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
-                               unsigned int bytes, QEMUIOVector *qiov,
-                               BdrvRequestFlags flags);
-int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
-                      int count, BdrvRequestFlags flags);
-BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
-                                  int count, BdrvRequestFlags flags,
-                                  BlockCompletionFunc *cb, void *opaque);
-int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags);
+int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
+             int nb_sectors);
+int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
+                         int nb_sectors);
+int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf,
+              int nb_sectors);
+int blk_write_zeroes(BlockBackend *blk, int64_t sector_num,
+                     int nb_sectors, BdrvRequestFlags flags);
+BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t sector_num,
+                                 int nb_sectors, BdrvRequestFlags flags,
+                                 BlockCompletionFunc *cb, void *opaque);
 int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count);
-int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count,
-               BdrvRequestFlags flags);
+int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count);
 int64_t blk_getlength(BlockBackend *blk);
 void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr);
 int64_t blk_nb_sectors(BlockBackend *blk);
-BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
-                           QEMUIOVector *qiov, BdrvRequestFlags flags,
+BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num,
+                          QEMUIOVector *iov, int nb_sectors,
+                          BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t sector_num,
+                           QEMUIOVector *iov, int nb_sectors,
                            BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
-                            QEMUIOVector *qiov, BdrvRequestFlags flags,
-                            BlockCompletionFunc *cb, void *opaque);
 BlockAIOCB *blk_aio_flush(BlockBackend *blk,
                           BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, int64_t offset, int count,
-                             BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_discard(BlockBackend *blk,
+                            int64_t sector_num, int nb_sectors,
+                            BlockCompletionFunc *cb, void *opaque);
 void blk_aio_cancel(BlockAIOCB *acb);
 void blk_aio_cancel_async(BlockAIOCB *acb);
+int blk_aio_multiwrite(BlockBackend *blk, BlockRequest *reqs, int num_reqs);
 int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
 BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
                           BlockCompletionFunc *cb, void *opaque);
-int blk_co_pdiscard(BlockBackend *blk, int64_t offset, int count);
+int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors);
 int blk_co_flush(BlockBackend *blk);
 int blk_flush(BlockBackend *blk);
 int blk_flush_all(void);
@@ -170,7 +147,7 @@ bool blk_is_available(BlockBackend *blk);
 void blk_lock_medium(BlockBackend *blk, bool locked);
 void blk_eject(BlockBackend *blk, bool eject_flag);
 int blk_get_flags(BlockBackend *blk);
-uint32_t blk_get_max_transfer(BlockBackend *blk);
+int blk_get_max_transfer_length(BlockBackend *blk);
 int blk_get_max_iov(BlockBackend *blk);
 void blk_set_guest_block_size(BlockBackend *blk, int align);
 void *blk_try_blockalign(BlockBackend *blk, size_t size);
@@ -201,12 +178,12 @@ int blk_get_open_flags_from_root_state(BlockBackend *blk);
 
 void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
                   BlockCompletionFunc *cb, void *opaque);
-int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
-                                      int count, BdrvRequestFlags flags);
+int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t sector_num,
+                                     int nb_sectors, BdrvRequestFlags flags);
 int blk_write_compressed(BlockBackend *blk, int64_t sector_num,
                          const uint8_t *buf, int nb_sectors);
 int blk_truncate(BlockBackend *blk, int64_t offset);
-int blk_pdiscard(BlockBackend *blk, int64_t offset, int count);
+int blk_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors);
 int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
                      int64_t pos, int size);
 int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size);
@@ -216,9 +193,4 @@ BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
                                   BlockCompletionFunc *cb,
                                   void *opaque, int ret);
 
-void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg);
-void blk_io_limits_disable(BlockBackend *blk);
-void blk_io_limits_enable(BlockBackend *blk, const char *group);
-void blk_io_limits_update_group(BlockBackend *blk, const char *group);
-
 #endif
index ddb05cd..2bc6d53 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef SYSEMU_BT_H
-#define SYSEMU_BT_H
+#ifndef BT_HOST_H
+#define BT_HOST_H
 
 /* BT HCI info */
 
index ee7e554..307fd8f 100644 (file)
@@ -70,13 +70,11 @@ struct CharDriverState {
     int (*get_msgfds)(struct CharDriverState *s, int* fds, int num);
     int (*set_msgfds)(struct CharDriverState *s, int *fds, int num);
     int (*chr_add_client)(struct CharDriverState *chr, int fd);
-    int (*chr_wait_connected)(struct CharDriverState *chr, Error **errp);
     IOEventHandler *chr_event;
     IOCanReadHandler *chr_can_read;
     IOReadHandler *chr_read;
     void *handler_opaque;
     void (*chr_close)(struct CharDriverState *chr);
-    void (*chr_disconnect)(struct CharDriverState *chr);
     void (*chr_accept_input)(struct CharDriverState *chr);
     void (*chr_set_echo)(struct CharDriverState *chr, bool echo);
     void (*chr_set_fe_open)(struct CharDriverState *chr, int fe_open);
@@ -145,26 +143,6 @@ void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend);
  */
 CharDriverState *qemu_chr_new(const char *label, const char *filename,
                               void (*init)(struct CharDriverState *s));
-/**
- * @qemu_chr_disconnect:
- *
- * Close a fd accpeted by character backend.
- */
-void qemu_chr_disconnect(CharDriverState *chr);
-
-/**
- * @qemu_chr_cleanup:
- *
- * Delete all chardevs (when leaving qemu)
- */
-void qemu_chr_cleanup(void);
-
-/**
- * @qemu_chr_wait_connected:
- *
- * Wait for characted backend to be connected.
- */
-int qemu_chr_wait_connected(CharDriverState *chr, Error **errp);
 
 /**
  * @qemu_chr_new_noreplay:
@@ -236,20 +214,8 @@ void qemu_chr_fe_event(CharDriverState *s, int event);
 void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 
-/**
- * @qemu_chr_fe_add_watch:
- *
- * If the backend is connected, create and add a #GSource that fires
- * when the given condition (typically G_IO_OUT|G_IO_HUP or G_IO_HUP)
- * is active; return the #GSource's tag.  If it is disconnected,
- * return 0.
- *
- * @cond the condition to poll for
- * @func the function to call when the condition happens
- * @user_data the opaque pointer to pass to @func
- */
-guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
-                            GIOFunc func, void *user_data);
+int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
+                          GIOFunc func, void *user_data);
 
 /**
  * @qemu_chr_fe_write:
@@ -437,6 +403,7 @@ void register_char_driver(const char *name, ChardevBackendKind kind,
 
 extern int term_escape_char;
 
+CharDriverState *qemu_char_get_next_serial(void);
 
 /* console.c */
 typedef CharDriverState *(VcHandler)(ChardevVC *vc, Error **errp);
index fe992a8..3d1e5ba 100644 (file)
@@ -7,19 +7,6 @@ void qemu_init_cpu_loop(void);
 void resume_all_vcpus(void);
 void pause_all_vcpus(void);
 void cpu_stop_current(void);
-void cpu_ticks_init(void);
-
-void configure_icount(QemuOpts *opts, Error **errp);
-extern int use_icount;
-extern int icount_align_option;
-
-/* drift information for info jit command */
-extern int64_t max_delay;
-extern int64_t max_advance;
-void dump_drift_info(FILE *f, fprintf_function cpu_fprintf);
-
-/* Unblock cpu */
-void qemu_cpu_kick_self(void);
 
 void cpu_synchronize_all_states(void);
 void cpu_synchronize_all_post_reset(void);
index e22e5be..705650a 100644 (file)
@@ -11,8 +11,8 @@
  *
  */
 
-#ifndef DEVICE_TREE_H
-#define DEVICE_TREE_H
+#ifndef __DEVICE_TREE_H__
+#define __DEVICE_TREE_H__
 
 void *create_device_tree(int *sizep);
 void *load_device_tree(const char *filename_path, int *sizep);
@@ -168,4 +168,4 @@ int qemu_fdt_setprop_sized_cells_from_array(void *fdt,
 #define FDT_PCI_RANGE_IOPORT               0x01000000
 #define FDT_PCI_RANGE_CONFIG               0x00000000
 
-#endif /* DEVICE_TREE_H */
+#endif /* __DEVICE_TREE_H__ */
index 34c8eaf..b0fbb9b 100644 (file)
@@ -15,6 +15,7 @@
 #include "hw/hw.h"
 #include "block/block.h"
 #include "block/accounting.h"
+#include "sysemu/kvm.h"
 
 typedef struct ScatterGatherEntry ScatterGatherEntry;
 
@@ -66,7 +67,9 @@ static inline void dma_barrier(AddressSpace *as, DMADirection dir)
      * use lighter barriers based on the direction of the
      * transfer, the DMA context, etc...
      */
-    smp_mb();
+    if (kvm_enabled()) {
+        smp_mb();
+    }
 }
 
 /* Checks that the given range of addresses is valid for DMA.  This is
@@ -194,19 +197,19 @@ void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len);
 void qemu_sglist_destroy(QEMUSGList *qsg);
 #endif
 
-typedef BlockAIOCB *DMAIOFunc(int64_t offset, QEMUIOVector *iov,
-                              BlockCompletionFunc *cb, void *cb_opaque,
-                              void *opaque);
+typedef BlockAIOCB *DMAIOFunc(BlockBackend *blk, int64_t sector_num,
+                              QEMUIOVector *iov, int nb_sectors,
+                              BlockCompletionFunc *cb, void *opaque);
 
-BlockAIOCB *dma_blk_io(AioContext *ctx,
-                       QEMUSGList *sg, uint64_t offset,
-                       DMAIOFunc *io_func, void *io_func_opaque,
-                       BlockCompletionFunc *cb, void *opaque, DMADirection dir);
+BlockAIOCB *dma_blk_io(BlockBackend *blk,
+                       QEMUSGList *sg, uint64_t sector_num,
+                       DMAIOFunc *io_func, BlockCompletionFunc *cb,
+                       void *opaque, DMADirection dir);
 BlockAIOCB *dma_blk_read(BlockBackend *blk,
-                         QEMUSGList *sg, uint64_t offset,
+                         QEMUSGList *sg, uint64_t sector,
                          BlockCompletionFunc *cb, void *opaque);
 BlockAIOCB *dma_blk_write(BlockBackend *blk,
-                          QEMUSGList *sg, uint64_t offset,
+                          QEMUSGList *sg, uint64_t sector,
                           BlockCompletionFunc *cb, void *opaque);
 uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg);
 uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg);
index 678232a..a19801d 100644 (file)
@@ -9,9 +9,8 @@
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
-
-#ifndef SYSEMU_HOSTMEM_H
-#define SYSEMU_HOSTMEM_H
+#ifndef QEMU_RAM_H
+#define QEMU_RAM_H
 
 #include "sysemu/sysemu.h" /* for MAX_NODES */
 #include "qom/object.h"
@@ -45,6 +44,7 @@ struct HostMemoryBackendClass {
  *
  * @parent: opaque parent object container
  * @size: amount of memory backend provides
+ * @id: unique identification string in memdev namespace
  * @mr: MemoryRegion representing host memory belonging to backend
  */
 struct HostMemoryBackend {
@@ -54,7 +54,7 @@ struct HostMemoryBackend {
     /* protected */
     uint64_t size;
     bool merge, dump;
-    bool prealloc, force_prealloc, is_mapped;
+    bool prealloc, force_prealloc;
     DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
     HostMemPolicy policy;
 
@@ -64,6 +64,4 @@ struct HostMemoryBackend {
 MemoryRegion *host_memory_backend_get_memory(HostMemoryBackend *backend,
                                              Error **errp);
 
-void host_memory_backend_set_mapped(HostMemoryBackend *backend, bool mapped);
-bool host_memory_backend_is_mapped(HostMemoryBackend *backend);
 #endif
index c9c2436..0e18f15 100644 (file)
@@ -216,10 +216,8 @@ int kvm_has_intx_set_mask(void);
 
 int kvm_init_vcpu(CPUState *cpu);
 int kvm_cpu_exec(CPUState *cpu);
-int kvm_destroy_vcpu(CPUState *cpu);
 
 #ifdef NEED_CPU_H
-#include "cpu.h"
 
 void kvm_setup_guest_memory(void *start, size_t size);
 void kvm_flush_coalesced_mmio_buffer(void);
@@ -346,8 +344,6 @@ int kvm_arch_init(MachineState *ms, KVMState *s);
 
 int kvm_arch_init_vcpu(CPUState *cpu);
 
-bool kvm_vcpu_id_is_valid(int vcpu_id);
-
 /* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */
 unsigned long kvm_arch_vcpu_id(CPUState *cpu);
 
@@ -359,18 +355,13 @@ void kvm_arch_init_irq_routing(KVMState *s);
 int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
                              uint64_t address, uint32_t data, PCIDevice *dev);
 
-/* Notify arch about newly added MSI routes */
-int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
-                                int vector, PCIDevice *dev);
-/* Notify arch about released MSI routes */
-int kvm_arch_release_virq_post(int virq);
-
 int kvm_arch_msi_data_to_gsi(uint32_t data);
 
 int kvm_set_irq(KVMState *s, int irq, int level);
 int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
 
 void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin);
+void kvm_irqchip_commit_routes(KVMState *s);
 
 void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
 void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
@@ -479,21 +470,9 @@ static inline void cpu_synchronize_post_init(CPUState *cpu)
     }
 }
 
-/**
- * kvm_irqchip_add_msi_route - Add MSI route for specific vector
- * @s:      KVM state
- * @vector: which vector to add. This can be either MSI/MSIX
- *          vector. The function will automatically detect whether
- *          MSI/MSIX is enabled, and fetch corresponding MSI
- *          message.
- * @dev:    Owner PCI device to add the route. If @dev is specified
- *          as @NULL, an empty MSI message will be inited.
- * @return: virq (>=0) when success, errno (<0) when failed.
- */
-int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev);
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev);
 int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
                                  PCIDevice *dev);
-void kvm_irqchip_commit_routes(KVMState *s);
 void kvm_irqchip_release_virq(KVMState *s, int virq);
 
 int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter);
@@ -544,5 +523,4 @@ int kvm_set_one_reg(CPUState *cs, uint64_t id, void *source);
  * Returns: 0 on success, or a negative errno on failure.
  */
 int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target);
-int kvm_get_max_memslots(void);
 #endif
index 9c7dfdf..07e3e5a 100644 (file)
@@ -26,7 +26,6 @@
 #ifndef QEMU_OS_POSIX_H
 #define QEMU_OS_POSIX_H
 
-#include <sys/mman.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
index 38186fe..4332772 100644 (file)
@@ -15,8 +15,8 @@
 #include "qom/object.h"
 
 #define TYPE_RNG_RANDOM "rng-random"
-#define RNG_RANDOM(obj) OBJECT_CHECK(RngRandom, (obj), TYPE_RNG_RANDOM)
+#define RNG_RANDOM(obj) OBJECT_CHECK(RndRandom, (obj), TYPE_RNG_RANDOM)
 
-typedef struct RngRandom RngRandom;
+typedef struct RndRandom RndRandom;
 
 #endif
index ee7c760..38fb3ca 100644 (file)
@@ -75,7 +75,6 @@ void qemu_add_exit_notifier(Notifier *notify);
 void qemu_remove_exit_notifier(Notifier *notify);
 
 void qemu_add_machine_init_done_notifier(Notifier *notify);
-void qemu_remove_machine_init_done_notifier(Notifier *notify);
 
 void hmp_savevm(Monitor *mon, const QDict *qdict);
 int load_vmstate(const char *name);
@@ -120,7 +119,7 @@ void qemu_savevm_command_send(QEMUFile *f, enum qemu_vm_cmd command,
                               uint16_t len, uint8_t *data);
 void qemu_savevm_send_ping(QEMUFile *f, uint32_t value);
 void qemu_savevm_send_open_return_path(QEMUFile *f);
-int qemu_savevm_send_packaged(QEMUFile *f, const uint8_t *buf, size_t len);
+int qemu_savevm_send_packaged(QEMUFile *f, const QEMUSizedBuffer *qsb);
 void qemu_savevm_send_postcopy_advise(QEMUFile *f);
 void qemu_savevm_send_postcopy_listen(QEMUFile *f);
 void qemu_savevm_send_postcopy_run(QEMUFile *f);
@@ -132,12 +131,21 @@ void qemu_savevm_send_postcopy_ram_discard(QEMUFile *f, const char *name,
 
 int qemu_loadvm_state(QEMUFile *f);
 
+typedef enum DisplayType
+{
+    DT_DEFAULT,
+    DT_CURSES,
+    DT_SDL,
+    DT_GTK,
+    DT_NOGRAPHIC,
+    DT_NONE,
+} DisplayType;
+
 extern int autostart;
 
 typedef enum {
     VGA_NONE, VGA_STD, VGA_CIRRUS, VGA_VMWARE, VGA_XENFB, VGA_QXL,
     VGA_TCX, VGA_CG3, VGA_DEVICE, VGA_VIRTIO,
-    VGA_TYPE_MAX,
 } VGAInterfaceType;
 
 extern int vga_interface_type;
@@ -146,6 +154,7 @@ extern int vga_interface_type;
 extern int graphic_width;
 extern int graphic_height;
 extern int graphic_depth;
+extern DisplayType display_type;
 extern int display_opengl;
 extern const char *keyboard_layout;
 extern int win2k_install_hack;
@@ -234,6 +243,7 @@ void qemu_boot_set(const char *boot_order, Error **errp);
 QemuOpts *qemu_get_machine_opts(void);
 
 bool defaults_enabled(void);
+bool usb_enabled(void);
 
 extern QemuOptsList qemu_legacy_drive_opts;
 extern QemuOptsList qemu_common_drive_opts;
index b58f52d..e3ec800 100644 (file)
@@ -10,8 +10,8 @@
  * See the COPYING file in the top-level directory.
  */
 
-#ifndef TPM_BACKEND_H
-#define TPM_BACKEND_H
+#ifndef _QEMU_TPM_H
+#define _QEMU_TPM_H
 
 #include "qom/object.h"
 #include "qemu-common.h"
index 00639dd..40f693a 100644 (file)
  * License along with this library; if not, see <http://www.gnu.org/licenses/>
  */
 
-#ifndef TPM_BACKEND_INT_H
-#define TPM_BACKEND_INT_H
+#ifndef TPM_TPM_BACKEND_H
+#define TPM_TPM_BACKEND_H
+
+#include <glib.h>
 
 typedef struct TPMBackendThread {
     GThreadPool *pool;
@@ -38,4 +40,4 @@ typedef enum TPMBackendCmd {
     TPM_BACKEND_CMD_TPM_RESET,
 } TPMBackendCmd;
 
-#endif /* TPM_BACKEND_INT_H */
+#endif /* TPM_TPM_BACKEND_H */
index b8c93b9..c849489 100644 (file)
@@ -9,6 +9,7 @@
 #ifndef XEN_MAPCACHE_H
 #define XEN_MAPCACHE_H
 
+
 typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr start_addr,
                                                      ram_addr_t size,
                                                      void *opaque);
@@ -51,4 +52,4 @@ static inline void xen_invalidate_map_cache(void)
 
 #endif
 
-#endif /* XEN_MAPCACHE_H */
+#endif /* !XEN_MAPCACHE_H */
index edab4b1..6f6bdbb 100644 (file)
@@ -4,4 +4,4 @@
 #include "trace/generated-tcg-tracers.h"
 #include "trace/generated-events.h"
 
-#endif /* TRACE_TCG_H */
+#endif  /* TRACE_TCG_H */
index 9a01e44..44a1f1f 100644 (file)
@@ -4,4 +4,4 @@
 #include "trace/generated-tracers.h"
 #include "trace/generated-events.h"
 
-#endif /* TRACE_H */
+#endif  /* TRACE_H */
index 2703a3a..d5a88d9 100644 (file)
@@ -6,8 +6,6 @@
 #include "qapi/qmp/qdict.h"
 #include "qemu/notify.h"
 #include "qapi-types.h"
-#include "qemu/error-report.h"
-#include "qapi/error.h"
 
 #ifdef CONFIG_OPENGL
 # include <epoxy/gl.h>
@@ -217,7 +215,6 @@ typedef struct DisplayChangeListenerOps {
 
     void (*dpy_gl_scanout)(DisplayChangeListener *dcl,
                            uint32_t backing_id, bool backing_y_0_top,
-                           uint32_t backing_width, uint32_t backing_height,
                            uint32_t x, uint32_t y, uint32_t w, uint32_t h);
     void (*dpy_gl_update)(DisplayChangeListener *dcl,
                           uint32_t x, uint32_t y, uint32_t w, uint32_t h);
@@ -286,7 +283,6 @@ bool dpy_gfx_check_format(QemuConsole *con,
 
 void dpy_gl_scanout(QemuConsole *con,
                     uint32_t backing_id, bool backing_y_0_top,
-                    uint32_t backing_width, uint32_t backing_height,
                     uint32_t x, uint32_t y, uint32_t w, uint32_t h);
 void dpy_gl_update(QemuConsole *con,
                    uint32_t x, uint32_t y, uint32_t w, uint32_t h);
@@ -424,41 +420,17 @@ void surface_gl_setup_viewport(ConsoleGLState *gls,
 #endif
 
 /* sdl.c */
-#ifdef CONFIG_SDL
 void sdl_display_early_init(int opengl);
 void sdl_display_init(DisplayState *ds, int full_screen, int no_frame);
-#else
-static inline void sdl_display_early_init(int opengl)
-{
-    /* This must never be called if CONFIG_SDL is disabled */
-    error_report("SDL support is disabled");
-    abort();
-}
-static inline void sdl_display_init(DisplayState *ds, int full_screen,
-                                    int no_frame)
-{
-    /* This must never be called if CONFIG_SDL is disabled */
-    error_report("SDL support is disabled");
-    abort();
-}
-#endif
 
 /* cocoa.m */
-#ifdef CONFIG_COCOA
 void cocoa_display_init(DisplayState *ds, int full_screen);
-#else
-static inline void cocoa_display_init(DisplayState *ds, int full_screen)
-{
-    /* This must never be called if CONFIG_COCOA is disabled */
-    error_report("Cocoa support is disabled");
-    abort();
-}
-#endif
 
 /* vnc.c */
 void vnc_display_init(const char *id);
 void vnc_display_open(const char *id, Error **errp);
 void vnc_display_add_client(const char *id, int csock, bool skipauth);
+char *vnc_display_local_addr(const char *id);
 #ifdef CONFIG_VNC
 int vnc_display_password(const char *id, const char *password);
 int vnc_display_pw_expire(const char *id, time_t expires);
@@ -473,52 +445,16 @@ static inline int vnc_display_pw_expire(const char *id, time_t expires)
 {
     return -ENODEV;
 };
-static inline QemuOpts *vnc_parse(const char *str, Error **errp)
-{
-    error_setg(errp, "VNC support is disabled");
-    return NULL;
-}
-static inline int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
-{
-    error_setg(errp, "VNC support is disabled");
-    return -1;
-}
 #endif
 
 /* curses.c */
-#ifdef CONFIG_CURSES
 void curses_display_init(DisplayState *ds, int full_screen);
-#else
-static inline void curses_display_init(DisplayState *ds, int full_screen)
-{
-    /* This must never be called if CONFIG_CURSES is disabled */
-    error_report("curses support is disabled");
-    abort();
-}
-#endif
 
 /* input.c */
 int index_from_key(const char *key, size_t key_length);
 
 /* gtk.c */
-#ifdef CONFIG_GTK
 void early_gtk_display_init(int opengl);
 void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover);
-#else
-static inline void gtk_display_init(DisplayState *ds, bool full_screen,
-                                    bool grab_on_hover)
-{
-    /* This must never be called if CONFIG_GTK is disabled */
-    error_report("GTK support is disabled");
-    abort();
-}
-
-static inline void early_gtk_display_init(int opengl)
-{
-    /* This must never be called if CONFIG_GTK is disabled */
-    error_report("GTK support is disabled");
-    abort();
-}
-#endif
 
 #endif
index 42ca0fe..2bf60f3 100644 (file)
@@ -101,7 +101,6 @@ QEMUGLContext gd_egl_create_context(DisplayChangeListener *dcl,
                                     QEMUGLParams *params);
 void gd_egl_scanout(DisplayChangeListener *dcl,
                     uint32_t backing_id, bool backing_y_0_top,
-                    uint32_t backing_width, uint32_t backing_height,
                     uint32_t x, uint32_t y,
                     uint32_t w, uint32_t h);
 void gd_egl_scanout_flush(DisplayChangeListener *dcl,
@@ -124,7 +123,6 @@ void gd_gl_area_destroy_context(DisplayChangeListener *dcl,
                                 QEMUGLContext ctx);
 void gd_gl_area_scanout(DisplayChangeListener *dcl,
                         uint32_t backing_id, bool backing_y_0_top,
-                        uint32_t backing_width, uint32_t backing_height,
                         uint32_t x, uint32_t y,
                         uint32_t w, uint32_t h);
 void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
index 75e1239..aa24363 100644 (file)
@@ -42,12 +42,6 @@ int qemu_spice_set_pw_expire(time_t expires);
 int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
                             const char *subject);
 
-#if !defined(SPICE_SERVER_VERSION) || (SPICE_SERVER_VERSION < 0xc06)
-#define SPICE_NEEDS_SET_MM_TIME 1
-#else
-#define SPICE_NEEDS_SET_MM_TIME 0
-#endif
-
 #if SPICE_SERVER_VERSION >= 0x000c02
 void qemu_spice_register_ports(void);
 #else
@@ -57,8 +51,6 @@ static inline CharDriverState *qemu_chr_open_spice_port(const char *name)
 
 #else  /* CONFIG_SPICE */
 
-#include "qemu/error-report.h"
-
 #define using_spice 0
 #define spice_displays 0
 static inline int qemu_spice_set_passwd(const char *passwd,
@@ -83,17 +75,6 @@ static inline int qemu_spice_display_add_client(int csock, int skipauth,
     return -1;
 }
 
-static inline void qemu_spice_display_init(void)
-{
-    /* This must never be called if CONFIG_SPICE is disabled */
-    error_report("spice support is disabled");
-    abort();
-}
-
-static inline void qemu_spice_init(void)
-{
-}
-
 #endif /* CONFIG_SPICE */
 
 static inline bool qemu_using_spice(Error **errp)
index 683bb6a..3f0b57b 100644 (file)
@@ -64,7 +64,6 @@ QEMUGLContext sdl2_gl_get_current_context(DisplayChangeListener *dcl);
 
 void sdl2_gl_scanout(DisplayChangeListener *dcl,
                      uint32_t backing_id, bool backing_y_0_top,
-                     uint32_t backing_width, uint32_t backing_height,
                      uint32_t x, uint32_t y,
                      uint32_t w, uint32_t h);
 void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
index 43d7959..3e5117b 100644 (file)
@@ -140,7 +140,6 @@ static int qio_channel_buffer_close(QIOChannel *ioc,
     QIOChannelBuffer *bioc = QIO_CHANNEL_BUFFER(ioc);
 
     g_free(bioc->data);
-    bioc->data = NULL;
     bioc->capacity = bioc->usage = bioc->offset = 0;
 
     return 0;
index 196a4f1..ca8bc20 100644 (file)
@@ -23,7 +23,6 @@
 #include "io/channel-socket.h"
 #include "io/channel-watch.h"
 #include "trace.h"
-#include "qapi/clone-visitor.h"
 
 #define SOCKET_MAX_FDS 16
 
@@ -72,9 +71,6 @@ qio_channel_socket_set_fd(QIOChannelSocket *sioc,
                           int fd,
                           Error **errp)
 {
-    int val;
-    socklen_t len = sizeof(val);
-
     if (sioc->fd != -1) {
         error_setg(errp, "Socket is already open");
         return -1;
@@ -110,10 +106,6 @@ qio_channel_socket_set_fd(QIOChannelSocket *sioc,
         ioc->features |= (1 << QIO_CHANNEL_FEATURE_FD_PASS);
     }
 #endif /* WIN32 */
-    if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &val, &len) == 0 && val) {
-        QIOChannel *ioc = QIO_CHANNEL(sioc);
-        ioc->features |= (1 << QIO_CHANNEL_FEATURE_LISTEN);
-    }
 
     return 0;
 
@@ -190,7 +182,7 @@ void qio_channel_socket_connect_async(QIOChannelSocket *ioc,
         OBJECT(ioc), callback, opaque, destroy);
     SocketAddress *addrCopy;
 
-    addrCopy = QAPI_CLONE(SocketAddress, addr);
+    qapi_copy_SocketAddress(&addrCopy, addr);
 
     /* socket_connect() does a non-blocking connect(), but it
      * still blocks in DNS lookups, so we must use a thread */
@@ -252,7 +244,7 @@ void qio_channel_socket_listen_async(QIOChannelSocket *ioc,
         OBJECT(ioc), callback, opaque, destroy);
     SocketAddress *addrCopy;
 
-    addrCopy = QAPI_CLONE(SocketAddress, addr);
+    qapi_copy_SocketAddress(&addrCopy, addr);
 
     /* socket_listen() blocks in DNS lookups, so we must use a thread */
     trace_qio_channel_socket_listen_async(ioc, addr);
@@ -332,8 +324,8 @@ void qio_channel_socket_dgram_async(QIOChannelSocket *ioc,
     struct QIOChannelSocketDGramWorkerData *data = g_new0(
         struct QIOChannelSocketDGramWorkerData, 1);
 
-    data->localAddr = QAPI_CLONE(SocketAddress, localAddr);
-    data->remoteAddr = QAPI_CLONE(SocketAddress, remoteAddr);
+    qapi_copy_SocketAddress(&data->localAddr, localAddr);
+    qapi_copy_SocketAddress(&data->remoteAddr, remoteAddr);
 
     trace_qio_channel_socket_dgram_async(ioc, localAddr, remoteAddr);
     qio_task_run_in_thread(task,
@@ -401,17 +393,7 @@ static void qio_channel_socket_init(Object *obj)
 static void qio_channel_socket_finalize(Object *obj)
 {
     QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(obj);
-
     if (ioc->fd != -1) {
-        if (QIO_CHANNEL(ioc)->features & QIO_CHANNEL_FEATURE_LISTEN) {
-            Error *err = NULL;
-
-            socket_listen_cleanup(ioc->fd, &err);
-            if (err) {
-                error_report_err(err);
-                err = NULL;
-            }
-        }
 #ifdef WIN32
         WSAEventSelect(ioc->fd, NULL, 0);
 #endif
index 533bd4b..d5a4ed3 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qemu/bswap.h"
 #include "io/channel-websock.h"
 #include "crypto/hash.h"
 #include "trace.h"
index 923c465..692eb17 100644 (file)
@@ -218,7 +218,7 @@ static gboolean qio_channel_yield_enter(QIOChannel *ioc,
                                         gpointer opaque)
 {
     QIOChannelYieldData *data = opaque;
-    qemu_coroutine_enter(data->co);
+    qemu_coroutine_enter(data->co, NULL);
     return FALSE;
 }
 
diff --git a/io/trace-events b/io/trace-events
deleted file mode 100644 (file)
index d064665..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# io/buffer.c
-buffer_resize(const char *buf, size_t olen, size_t len) "%s: old %zd, new %zd"
-buffer_move_empty(const char *buf, size_t len, const char *from) "%s: %zd bytes from %s"
-buffer_move(const char *buf, size_t len, const char *from) "%s: %zd bytes from %s"
-buffer_free(const char *buf, size_t len) "%s: capacity %zd"
-
-# io/task.c
-qio_task_new(void *task, void *source, void *func, void *opaque) "Task new task=%p source=%p func=%p opaque=%p"
-qio_task_complete(void *task) "Task complete task=%p"
-qio_task_abort(void *task) "Task abort task=%p"
-qio_task_thread_start(void *task, void *worker, void *opaque) "Task thread start task=%p worker=%p opaque=%p"
-qio_task_thread_run(void *task) "Task thread run task=%p"
-qio_task_thread_exit(void *task) "Task thread exit task=%p"
-qio_task_thread_result(void *task) "Task thread result task=%p"
-
-# io/channel-socket.c
-qio_channel_socket_new(void *ioc) "Socket new ioc=%p"
-qio_channel_socket_new_fd(void *ioc, int fd) "Socket new ioc=%p fd=%d"
-qio_channel_socket_connect_sync(void *ioc, void *addr) "Socket connect sync ioc=%p addr=%p"
-qio_channel_socket_connect_async(void *ioc, void *addr) "Socket connect async ioc=%p addr=%p"
-qio_channel_socket_connect_fail(void *ioc) "Socket connect fail ioc=%p"
-qio_channel_socket_connect_complete(void *ioc, int fd) "Socket connect complete ioc=%p fd=%d"
-qio_channel_socket_listen_sync(void *ioc, void *addr) "Socket listen sync ioc=%p addr=%p"
-qio_channel_socket_listen_async(void *ioc, void *addr) "Socket listen async ioc=%p addr=%p"
-qio_channel_socket_listen_fail(void *ioc) "Socket listen fail ioc=%p"
-qio_channel_socket_listen_complete(void *ioc, int fd) "Socket listen complete ioc=%p fd=%d"
-qio_channel_socket_dgram_sync(void *ioc, void *localAddr, void *remoteAddr) "Socket dgram sync ioc=%p localAddr=%p remoteAddr=%p"
-qio_channel_socket_dgram_async(void *ioc, void *localAddr, void *remoteAddr) "Socket dgram async ioc=%p localAddr=%p remoteAddr=%p"
-qio_channel_socket_dgram_fail(void *ioc) "Socket dgram fail ioc=%p"
-qio_channel_socket_dgram_complete(void *ioc, int fd) "Socket dgram complete ioc=%p fd=%d"
-qio_channel_socket_accept(void *ioc) "Socket accept start ioc=%p"
-qio_channel_socket_accept_fail(void *ioc) "Socket accept fail ioc=%p"
-qio_channel_socket_accept_complete(void *ioc, void *cioc, int fd) "Socket accept complete ioc=%p cioc=%p fd=%d"
-
-# io/channel-file.c
-qio_channel_file_new_fd(void *ioc, int fd) "File new fd ioc=%p fd=%d"
-qio_channel_file_new_path(void *ioc, const char *path, int flags, int mode, int fd) "File new fd ioc=%p path=%s flags=%d mode=%d fd=%d"
-
-# io/channel-tls.c
-qio_channel_tls_new_client(void *ioc, void *master, void *creds, const char *hostname) "TLS new client ioc=%p master=%p creds=%p hostname=%s"
-qio_channel_tls_new_server(void *ioc, void *master, void *creds, const char *aclname) "TLS new client ioc=%p master=%p creds=%p acltname=%s"
-qio_channel_tls_handshake_start(void *ioc) "TLS handshake start ioc=%p"
-qio_channel_tls_handshake_pending(void *ioc, int status) "TLS handshake pending ioc=%p status=%d"
-qio_channel_tls_handshake_fail(void *ioc) "TLS handshake fail ioc=%p"
-qio_channel_tls_handshake_complete(void *ioc) "TLS handshake complete ioc=%p"
-qio_channel_tls_credentials_allow(void *ioc) "TLS credentials allow ioc=%p"
-qio_channel_tls_credentials_deny(void *ioc) "TLS credentials deny ioc=%p"
-
-# io/channel-websock.c
-qio_channel_websock_new_server(void *ioc, void *master) "Websock new client ioc=%p master=%p"
-qio_channel_websock_handshake_start(void *ioc) "Websock handshake start ioc=%p"
-qio_channel_websock_handshake_pending(void *ioc, int status) "Websock handshake pending ioc=%p status=%d"
-qio_channel_websock_handshake_reply(void *ioc) "Websock handshake reply ioc=%p"
-qio_channel_websock_handshake_fail(void *ioc) "Websock handshake fail ioc=%p"
-qio_channel_websock_handshake_complete(void *ioc) "Websock handshake complete ioc=%p"
-
-# io/channel-command.c
-qio_channel_command_new_pid(void *ioc, int writefd, int readfd, int pid) "Command new pid ioc=%p writefd=%d readfd=%d pid=%d"
-qio_channel_command_new_spawn(void *ioc, const char *binary, int flags) "Command new spawn ioc=%p binary=%s flags=%d"
-qio_channel_command_abort(void *ioc, int pid) "Command abort ioc=%p pid=%d"
-qio_channel_command_wait(void *ioc, int pid, int ret, int status) "Command abort ioc=%p pid=%d ret=%d status=%d"
index 94e08ab..7a84d54 100644 (file)
--- a/ioport.c
+++ b/ioport.c
@@ -26,8 +26,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "exec/ioport.h"
 #include "trace.h"
 #include "exec/memory.h"
@@ -55,14 +53,14 @@ const MemoryRegionOps unassigned_io_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-void cpu_outb(uint32_t addr, uint8_t val)
+void cpu_outb(pio_addr_t addr, uint8_t val)
 {
     trace_cpu_out(addr, 'b', val);
     address_space_write(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED,
                         &val, 1);
 }
 
-void cpu_outw(uint32_t addr, uint16_t val)
+void cpu_outw(pio_addr_t addr, uint16_t val)
 {
     uint8_t buf[2];
 
@@ -72,7 +70,7 @@ void cpu_outw(uint32_t addr, uint16_t val)
                         buf, 2);
 }
 
-void cpu_outl(uint32_t addr, uint32_t val)
+void cpu_outl(pio_addr_t addr, uint32_t val)
 {
     uint8_t buf[4];
 
@@ -82,7 +80,7 @@ void cpu_outl(uint32_t addr, uint32_t val)
                         buf, 4);
 }
 
-uint8_t cpu_inb(uint32_t addr)
+uint8_t cpu_inb(pio_addr_t addr)
 {
     uint8_t val;
 
@@ -92,7 +90,7 @@ uint8_t cpu_inb(uint32_t addr)
     return val;
 }
 
-uint16_t cpu_inw(uint32_t addr)
+uint16_t cpu_inw(pio_addr_t addr)
 {
     uint8_t buf[2];
     uint16_t val;
@@ -103,7 +101,7 @@ uint16_t cpu_inw(uint32_t addr)
     return val;
 }
 
-uint32_t cpu_inl(uint32_t addr)
+uint32_t cpu_inl(pio_addr_t addr)
 {
     uint8_t buf[4];
     uint32_t val;
index ebf35b0..f9ae8f9 100644 (file)
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -15,6 +15,7 @@
 
 #include "qemu/osdep.h"
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 
 #include <linux/kvm.h>
 
@@ -25,7 +26,6 @@
 #include "qemu/error-report.h"
 #include "hw/hw.h"
 #include "hw/pci/msi.h"
-#include "hw/pci/msix.h"
 #include "hw/s390x/adapter.h"
 #include "exec/gdbstub.h"
 #include "sysemu/kvm_int.h"
 
 #define KVM_MSI_HASHTAB_SIZE    256
 
-struct KVMParkedVcpu {
-    unsigned long vcpu_id;
-    int kvm_fd;
-    QLIST_ENTRY(KVMParkedVcpu) node;
-};
-
 struct KVMState
 {
     AccelState parent_obj;
@@ -100,7 +94,6 @@ struct KVMState
     QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
 #endif
     KVMMemoryListener memory_listener;
-    QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
 };
 
 KVMState *kvm_state;
@@ -126,13 +119,6 @@ static const KVMCapabilityInfo kvm_required_capabilites[] = {
     KVM_CAP_LAST_INFO
 };
 
-int kvm_get_max_memslots(void)
-{
-    KVMState *s = KVM_STATE(current_machine->accelerator);
-
-    return s->nr_slots;
-}
-
 static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
 {
     KVMState *s = kvm_state;
@@ -251,53 +237,6 @@ static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot)
     return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
 }
 
-int kvm_destroy_vcpu(CPUState *cpu)
-{
-    KVMState *s = kvm_state;
-    long mmap_size;
-    struct KVMParkedVcpu *vcpu = NULL;
-    int ret = 0;
-
-    DPRINTF("kvm_destroy_vcpu\n");
-
-    mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
-    if (mmap_size < 0) {
-        ret = mmap_size;
-        DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n");
-        goto err;
-    }
-
-    ret = munmap(cpu->kvm_run, mmap_size);
-    if (ret < 0) {
-        goto err;
-    }
-
-    vcpu = g_malloc0(sizeof(*vcpu));
-    vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
-    vcpu->kvm_fd = cpu->kvm_fd;
-    QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
-err:
-    return ret;
-}
-
-static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
-{
-    struct KVMParkedVcpu *cpu;
-
-    QLIST_FOREACH(cpu, &s->kvm_parked_vcpus, node) {
-        if (cpu->vcpu_id == vcpu_id) {
-            int kvm_fd;
-
-            QLIST_REMOVE(cpu, node);
-            kvm_fd = cpu->kvm_fd;
-            g_free(cpu);
-            return kvm_fd;
-        }
-    }
-
-    return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
-}
-
 int kvm_init_vcpu(CPUState *cpu)
 {
     KVMState *s = kvm_state;
@@ -306,7 +245,7 @@ int kvm_init_vcpu(CPUState *cpu)
 
     DPRINTF("kvm_init_vcpu\n");
 
-    ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));
+    ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)kvm_arch_vcpu_id(cpu));
     if (ret < 0) {
         DPRINTF("kvm_create_vcpu failed\n");
         goto err;
@@ -1047,16 +986,7 @@ void kvm_irqchip_commit_routes(KVMState *s)
 {
     int ret;
 
-    if (kvm_gsi_direct_mapping()) {
-        return;
-    }
-
-    if (!kvm_gsi_routing_enabled()) {
-        return;
-    }
-
     s->irq_routes->flags = 0;
-    trace_kvm_irqchip_commit_routes();
     ret = kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes);
     assert(ret == 0);
 }
@@ -1103,6 +1033,8 @@ static int kvm_update_routing_entry(KVMState *s,
 
         *entry = *new_entry;
 
+        kvm_irqchip_commit_routes(s);
+
         return 0;
     }
 
@@ -1140,7 +1072,6 @@ void kvm_irqchip_release_virq(KVMState *s, int virq)
         }
     }
     clear_gsi(s, virq);
-    kvm_arch_release_virq_post(virq);
 }
 
 static unsigned int kvm_hash_msi(uint32_t data)
@@ -1246,15 +1177,10 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
     return kvm_set_irq(s, route->kroute.gsi, 1);
 }
 
-int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev)
 {
     struct kvm_irq_routing_entry kroute = {};
     int virq;
-    MSIMessage msg = {0, 0};
-
-    if (dev) {
-        msg = pci_get_msi_message(dev, vector);
-    }
 
     if (kvm_gsi_direct_mapping()) {
         return kvm_arch_msi_data_to_gsi(msg.data);
@@ -1280,10 +1206,7 @@ int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
         return -EINVAL;
     }
 
-    trace_kvm_irqchip_add_msi_route(virq);
-
     kvm_add_routing_entry(s, &kroute);
-    kvm_arch_add_msi_route_post(&kroute, vector, dev);
     kvm_irqchip_commit_routes(s);
 
     return virq;
@@ -1312,8 +1235,6 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
         return -EINVAL;
     }
 
-    trace_kvm_irqchip_update_msi_route(virq);
-
     return kvm_update_routing_entry(s, &kroute);
 }
 
@@ -1409,7 +1330,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
     abort();
 }
 
-int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
 {
     return -ENOSYS;
 }
@@ -1538,18 +1459,6 @@ static int kvm_max_vcpus(KVMState *s)
     return (ret) ? ret : kvm_recommended_vcpus(s);
 }
 
-static int kvm_max_vcpu_id(KVMState *s)
-{
-    int ret = kvm_check_extension(s, KVM_CAP_MAX_VCPU_ID);
-    return (ret) ? ret : kvm_max_vcpus(s);
-}
-
-bool kvm_vcpu_id_is_valid(int vcpu_id)
-{
-    KVMState *s = KVM_STATE(current_machine->accelerator);
-    return vcpu_id >= 0 && vcpu_id < kvm_max_vcpu_id(s);
-}
-
 static int kvm_init(MachineState *ms)
 {
     MachineClass *mc = MACHINE_GET_CLASS(ms);
@@ -1586,7 +1495,6 @@ static int kvm_init(MachineState *ms)
 #ifdef KVM_CAP_SET_GUEST_DEBUG
     QTAILQ_INIT(&s->kvm_sw_breakpoints);
 #endif
-    QLIST_INIT(&s->kvm_parked_vcpus);
     s->vmfd = -1;
     s->fd = qemu_open("/dev/kvm", O_RDWR);
     if (s->fd == -1) {
@@ -2143,7 +2051,7 @@ void kvm_device_access(int fd, int group, uint64_t attr,
     if (err < 0) {
         error_report("KVM_%s_DEVICE_ATTR failed: %s",
                      write ? "SET" : "GET", strerror(-err));
-        error_printf("Group %d attr 0x%016" PRIx64 "\n", group, attr);
+        error_printf("Group %d attr 0x%016" PRIx64, group, attr);
         abort();
     }
 }
index 64e23f6..b962b24 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu-common.h"
+#include "hw/hw.h"
 #include "cpu.h"
 #include "sysemu/kvm.h"
 
@@ -32,11 +33,6 @@ bool kvm_allowed;
 bool kvm_readonly_mem_allowed;
 bool kvm_ioeventfd_any_length_allowed;
 
-int kvm_destroy_vcpu(CPUState *cpu)
-{
-    return -ENOSYS;
-}
-
 int kvm_init_vcpu(CPUState *cpu)
 {
     return -ENOSYS;
@@ -116,7 +112,7 @@ int kvm_on_sigbus(int code, void *addr)
 }
 
 #ifndef CONFIG_USER_ONLY
-int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev)
 {
     return -ENOSYS;
 }
@@ -135,10 +131,6 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
     return -ENOSYS;
 }
 
-void kvm_irqchip_commit_routes(KVMState *s)
-{
-}
-
 int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter)
 {
     return -ENOSYS;
index ceb5450..3f6f727 100644 (file)
 #define __NR_membarrier                        (__NR_SYSCALL_BASE+389)
 #define __NR_mlock2                    (__NR_SYSCALL_BASE+390)
 #define __NR_copy_file_range           (__NR_SYSCALL_BASE+391)
-#define __NR_preadv2                   (__NR_SYSCALL_BASE+392)
-#define __NR_pwritev2                  (__NR_SYSCALL_BASE+393)
 
 /*
  * The following SWIs are ARM private.
index 043d17a..1caadc2 100644 (file)
@@ -13,7 +13,4 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-
-#define __ARCH_WANT_RENAMEAT
-
 #include <asm-generic/unistd.h>
index 1e66eba..cd92d98 100644 (file)
 #define __NR_membarrier                365
 #define __NR_mlock2            378
 #define __NR_copy_file_range   379
-#define __NR_preadv2           380
-#define __NR_pwritev2          381
 
 #endif /* _ASM_POWERPC_UNISTD_H_ */
index 09ae5dc..a59499b 100644 (file)
@@ -25,7 +25,6 @@
 #define KVM_DEV_FLIC_APF_DISABLE_WAIT  5
 #define KVM_DEV_FLIC_ADAPTER_REGISTER  6
 #define KVM_DEV_FLIC_ADAPTER_MODIFY    7
-#define KVM_DEV_FLIC_CLEAR_IO_IRQ      8
 /*
  * We can have up to 4*64k pending subchannels + 8 adapter interrupts,
  * as well as up  to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts.
index 8a404fd..885837e 100644 (file)
 #define __NR_shutdown          373
 #define __NR_mlock2            374
 #define __NR_copy_file_range   375
-#define __NR_preadv2           376
-#define __NR_pwritev2          377
-#define NR_syscalls 378
+#define NR_syscalls 376
 
 /* 
  * There are some system calls that are not present on 64 bit, some
index 739c0c5..cd54147 100644 (file)
@@ -216,9 +216,9 @@ struct kvm_cpuid_entry2 {
        __u32 padding[3];
 };
 
-#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX                (1 << 0)
-#define KVM_CPUID_FLAG_STATEFUL_FUNC           (1 << 1)
-#define KVM_CPUID_FLAG_STATE_READ_NEXT         (1 << 2)
+#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX                BIT(0)
+#define KVM_CPUID_FLAG_STATEFUL_FUNC           BIT(1)
+#define KVM_CPUID_FLAG_STATE_READ_NEXT         BIT(2)
 
 /* for KVM_SET_CPUID2 */
 struct kvm_cpuid2 {
index 0230779..8f77ee8 100644 (file)
 #define __NR_vmsplice (__X32_SYSCALL_BIT + 532)
 #define __NR_move_pages (__X32_SYSCALL_BIT + 533)
 #define __NR_preadv (__X32_SYSCALL_BIT + 534)
-#define __NR_preadv2 (__X32_SYSCALL_BIT + 534)
 #define __NR_pwritev (__X32_SYSCALL_BIT + 535)
-#define __NR_pwritev2 (__X32_SYSCALL_BIT + 535)
 #define __NR_rt_tgsigqueueinfo (__X32_SYSCALL_BIT + 536)
 #define __NR_recvmmsg (__X32_SYSCALL_BIT + 537)
 #define __NR_sendmmsg (__X32_SYSCALL_BIT + 538)
index e60e21b..3bae71a 100644 (file)
@@ -865,7 +865,6 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_SPAPR_TCE_64 125
 #define KVM_CAP_ARM_PMU_V3 126
 #define KVM_CAP_VCPU_ATTRIBUTES 127
-#define KVM_CAP_MAX_VCPU_ID 128
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
index 8c93058..fd50217 100644 (file)
@@ -1,6 +1,5 @@
 obj-y = main.o syscall.o strace.o mmap.o signal.o \
-       elfload.o linuxload.o uaccess.o uname.o \
-       safe-syscall.o
+       elfload.o linuxload.o uaccess.o uname.o
 
 obj-$(TARGET_HAS_BFLT) += flatload.o
 obj-$(TARGET_I386) += vm86.o
index a3c9a3b..59511d8 100644 (file)
@@ -86,7 +86,8 @@
 #define TARGET_NR_sync 81
 #define TARGET_NR_fsync 82
 #define TARGET_NR_fdatasync 83
-#define TARGET_NR_sync_file_range 84
+#define TARGET_NR_sync_file_range2 84
+/* #define TARGET_NR_sync_file_range 84 */
 #define TARGET_NR_timerfd_create 85
 #define TARGET_NR_timerfd_settime 86
 #define TARGET_NR_timerfd_gettime 87
index 777ce29..b5593dc 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef AARCH64_TARGET_CPU_H
-#define AARCH64_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
 {
index e66367c..e8c677d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef AARCH64_TARGET_SIGNAL_H
-#define AARCH64_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -26,4 +26,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUARMState *state)
    return state->xregs[31];
 }
 
-#endif /* AARCH64_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index a4998a7..21c1f2c 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef AARCH64_TARGET_STRUCTS_H
-#define AARCH64_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index 1b62953..f458018 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef AARCH64_TARGET_SYSCALL_H
-#define AARCH64_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 struct target_pt_regs {
     uint64_t        regs[31];
@@ -15,4 +15,4 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
-#endif /* AARCH64_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index ad124da..4256245 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef ALPHA_TARGET_CPU_H
-#define ALPHA_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUAlphaState *env, target_ulong newsp)
 {
index f1ed00d..d3822da 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ALPHA_TARGET_SIGNAL_H
-#define ALPHA_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -27,7 +27,6 @@ static inline abi_ulong get_sp_from_cpustate(CPUAlphaState *state)
     return state->ir[IR_SP];
 }
 
-
 /* From <asm/gentrap.h>.  */
 #define TARGET_GEN_INTOVF      -1      /* integer overflow */
 #define TARGET_GEN_INTDIV      -2      /* integer division by zero */
@@ -55,4 +54,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUAlphaState *state)
 #define TARGET_GEN_SUBRNG6     -24
 #define TARGET_GEN_SUBRNG7     -25
 
-#endif /* ALPHA_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index db2bfe2..50e7708 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef ALPHA_TARGET_STRUCTS_H
-#define ALPHA_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index b580fc5..3db4b16 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ALPHA_TARGET_SYSCALL_H
-#define ALPHA_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 /* default linux values for the selectors */
 #define __USER_DS      (1)
@@ -259,4 +259,4 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT     0x2000
 #define TARGET_MLOCKALL_MCL_FUTURE      0x4000
 
-#endif /* ALPHA_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index d459c5d..0b07284 100644 (file)
     along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef FPA11_H
-#define FPA11_H
+#ifndef __FPA11_H__
+#define __FPA11_H__
 
-#include "cpu.h"
+
+#include <cpu.h>
 
 #define GET_FPA11() (qemufpa)
 
index 06cd909..1b1137f 100644 (file)
@@ -18,8 +18,8 @@
     along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef FPOPCODE_H
-#define FPOPCODE_H
+#ifndef __FPOPCODE_H__
+#define __FPOPCODE_H__
 
 /*
 ARM Floating Point Instruction Classes
index 8c978f0..859dcd5 100644 (file)
@@ -18,8 +18,8 @@
     along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef FPSR_H
-#define FPSR_H
+#ifndef __FPSR_H__
+#define __FPSR_H__
 
 /*
 The FPSR is a 32 bit register consisting of 4 parts, each exactly
index d888219..6832262 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef ARM_TARGET_CPU_H
-#define ARM_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
 {
index cbbeb09..2b32813 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ARM_TARGET_SIGNAL_H
-#define ARM_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -26,5 +26,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUARMState *state)
    return state->regs[13];
 }
 
-
-#endif /* ARM_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index 0bf034c..f3c85d4 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef ARM_TARGET_STRUCTS_H
-#define ARM_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index cd021ff..ea863db 100644 (file)
@@ -1,14 +1,32 @@
-#ifndef ARM_TARGET_SYSCALL_H
-#define ARM_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 /* this struct defines the way the registers are stored on the
    stack during a system call. */
 
-/* uregs[0..15] are r0 to r15; uregs[16] is CPSR; uregs[17] is ORIG_r0 */
 struct target_pt_regs {
     abi_long uregs[18];
 };
 
+#define ARM_cpsr       uregs[16]
+#define ARM_pc         uregs[15]
+#define ARM_lr         uregs[14]
+#define ARM_sp         uregs[13]
+#define ARM_ip         uregs[12]
+#define ARM_fp         uregs[11]
+#define ARM_r10                uregs[10]
+#define ARM_r9         uregs[9]
+#define ARM_r8         uregs[8]
+#define ARM_r7         uregs[7]
+#define ARM_r6         uregs[6]
+#define ARM_r5         uregs[5]
+#define ARM_r4         uregs[4]
+#define ARM_r3         uregs[3]
+#define ARM_r2         uregs[2]
+#define ARM_r1         uregs[1]
+#define ARM_r0         uregs[0]
+#define ARM_ORIG_r0    uregs[17]
+
 #define ARM_SYSCALL_BASE       0x900000
 #define ARM_THUMB_SYSCALL      0
 
@@ -33,4 +51,4 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
-#endif /* ARM_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index c43aac6..4d787e5 100644 (file)
@@ -17,8 +17,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef CRIS_TARGET_CPU_H
-#define CRIS_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUCRISState *env, target_ulong newsp)
 {
index 664621b..5611840 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef CRIS_TARGET_SIGNAL_H
-#define CRIS_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -26,5 +26,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUCRISState *state)
     return state->regs[14];
 }
 
-
-#endif /* CRIS_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index 76f9653..e4a1ffb 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef CRIS_TARGET_STRUCTS_H
-#define CRIS_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index 29d6900..2957b0d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef CRIS_TARGET_SYSCALL_H
-#define CRIS_TARGET_SYSCALL_H
+#ifndef CRIS_SYSCALL_H
+#define CRIS_SYSCALL_H 1
 
 #define UNAME_MACHINE "cris"
 #define UNAME_MINIMUM_RELEASE "2.6.32"
index f807baf..e47caff 100644 (file)
@@ -2,6 +2,7 @@
 #include "qemu/osdep.h"
 #include <sys/param.h>
 
+#include <sys/mman.h>
 #include <sys/resource.h>
 
 #include "qemu.h"
@@ -273,20 +274,19 @@ static inline void init_thread(struct target_pt_regs *regs,
     abi_long stack = infop->start_stack;
     memset(regs, 0, sizeof(*regs));
 
-    regs->uregs[16] = ARM_CPU_MODE_USR;
-    if (infop->entry & 1) {
-        regs->uregs[16] |= CPSR_T;
-    }
-    regs->uregs[15] = infop->entry & 0xfffffffe;
-    regs->uregs[13] = infop->start_stack;
+    regs->ARM_cpsr = 0x10;
+    if (infop->entry & 1)
+        regs->ARM_cpsr |= CPSR_T;
+    regs->ARM_pc = infop->entry & 0xfffffffe;
+    regs->ARM_sp = infop->start_stack;
     /* FIXME - what to for failure of get_user()? */
-    get_user_ual(regs->uregs[2], stack + 8); /* envp */
-    get_user_ual(regs->uregs[1], stack + 4); /* envp */
+    get_user_ual(regs->ARM_r2, stack + 8); /* envp */
+    get_user_ual(regs->ARM_r1, stack + 4); /* envp */
     /* XXX: it seems that r0 is zeroed after ! */
-    regs->uregs[0] = 0;
+    regs->ARM_r0 = 0;
     /* For uClinux PIC binaries.  */
     /* XXX: Linux does this only on ARM with no MMU (do we care ?) */
-    regs->uregs[10] = infop->start_data;
+    regs->ARM_r10 = infop->start_data;
 }
 
 #define ELF_NREG    18
index 65522c4..8a1cf76 100644 (file)
 /* for robust mutexes */
 #define TARGET_EOWNERDEAD      130     /* Owner died */
 #define TARGET_ENOTRECOVERABLE 131     /* State not recoverable */
-
-/* QEMU internal, not visible to the guest. This is returned when a
- * system call should be restarted, to tell the main loop that it
- * should wind the guest PC backwards so it will re-execute the syscall
- * after handling any pending signals. They match with the ones the guest
- * kernel uses for the same purpose.
- */
-#define TARGET_ERESTARTSYS     512     /* Restart system call (if SA_RESTART) */
-
-/* QEMU internal, not visible to the guest. This is returned by the
- * do_sigreturn() code after a successful sigreturn syscall, to indicate
- * that it has correctly set the guest registers and so the main loop
- * should not touch them. We use the value the guest would use for
- * ERESTART_NOINTR (which is kernel internal) to guarantee that we won't
- * clash with a valid guest errno now or in the future.
- */
-#define TARGET_QEMU_ESIGRETURN 513     /* Return from signal */
index 42d1079..f9139c3 100644 (file)
 /****************************************************************************/
 
 #include "qemu/osdep.h"
+#include <sys/mman.h>
 
 #include "qemu.h"
 #include "flat.h"
-#include "target_flat.h"
+#include <target_flat.h>
 
 //#define DEBUG
 
diff --git a/linux-user/host/aarch64/hostdep.h b/linux-user/host/aarch64/hostdep.h
deleted file mode 100644 (file)
index 64f75ce..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- *  * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef AARCH64_HOSTDEP_H
-#define AARCH64_HOSTDEP_H
-
-/* We have a safe-syscall.inc.S */
-#define HAVE_SAFE_SYSCALL
-
-#ifndef __ASSEMBLER__
-
-/* These are defined by the safe-syscall.inc.S file */
-extern char safe_syscall_start[];
-extern char safe_syscall_end[];
-
-/* Adjust the signal context to rewind out of safe-syscall if we're in it */
-static inline void rewind_if_in_safe_syscall(void *puc)
-{
-    struct ucontext *uc = puc;
-    __u64 *pcreg = &uc->uc_mcontext.pc;
-
-    if (*pcreg > (uintptr_t)safe_syscall_start
-        && *pcreg < (uintptr_t)safe_syscall_end) {
-        *pcreg = (uintptr_t)safe_syscall_start;
-    }
-}
-
-#endif /* __ASSEMBLER__ */
-
-#endif
diff --git a/linux-user/host/aarch64/safe-syscall.inc.S b/linux-user/host/aarch64/safe-syscall.inc.S
deleted file mode 100644 (file)
index 58a2329..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * safe-syscall.inc.S : host-specific assembly fragment
- * to handle signals occurring at the same time as system calls.
- * This is intended to be included by linux-user/safe-syscall.S
- *
- * Written by Richard Henderson <rth@twiddle.net>
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-       .global safe_syscall_base
-       .global safe_syscall_start
-       .global safe_syscall_end
-       .type   safe_syscall_base, #function
-       .type   safe_syscall_start, #function
-       .type   safe_syscall_end, #function
-
-       /* This is the entry point for making a system call. The calling
-        * convention here is that of a C varargs function with the
-        * first argument an 'int *' to the signal_pending flag, the
-        * second one the system call number (as a 'long'), and all further
-        * arguments being syscall arguments (also 'long').
-        * We return a long which is the syscall's return value, which
-        * may be negative-errno on failure. Conversion to the
-        * -1-and-errno-set convention is done by the calling wrapper.
-        */
-safe_syscall_base:
-       .cfi_startproc
-       /* The syscall calling convention isn't the same as the
-        * C one:
-        * we enter with x0 == *signal_pending
-        *               x1 == syscall number
-        *               x2 ... x7, (stack) == syscall arguments
-        *               and return the result in x0
-        * and the syscall instruction needs
-        *               x8 == syscall number
-        *               x0 ... x7 == syscall arguments
-        *               and returns the result in x0
-        * Shuffle everything around appropriately.
-        */
-       mov     x9, x0          /* signal_pending pointer */
-       mov     x8, x1          /* syscall number */
-       mov     x0, x2          /* syscall arguments */
-       mov     x1, x3
-       mov     x2, x4
-       mov     x3, x5
-       mov     x4, x6
-       mov     x6, x7
-       ldr     x7, [sp]
-
-       /* This next sequence of code works in conjunction with the
-        * rewind_if_safe_syscall_function(). If a signal is taken
-        * and the interrupted PC is anywhere between 'safe_syscall_start'
-        * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
-        * The code sequence must therefore be able to cope with this, and
-        * the syscall instruction must be the final one in the sequence.
-        */
-safe_syscall_start:
-       /* if signal_pending is non-zero, don't do the call */
-       ldr     w10, [x9]
-       cbnz    w10, 0f 
-       svc     0x0
-safe_syscall_end:
-       /* code path for having successfully executed the syscall */
-       ret
-
-0:
-       /* code path when we didn't execute the syscall */
-       mov     x0, #-TARGET_ERESTARTSYS
-       ret
-       .cfi_endproc
-
-       .size   safe_syscall_base, .-safe_syscall_base
diff --git a/linux-user/host/arm/hostdep.h b/linux-user/host/arm/hostdep.h
deleted file mode 100644 (file)
index 5c1ae60..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- *  * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef ARM_HOSTDEP_H
-#define ARM_HOSTDEP_H
-
-/* We have a safe-syscall.inc.S */
-#define HAVE_SAFE_SYSCALL
-
-#ifndef __ASSEMBLER__
-
-/* These are defined by the safe-syscall.inc.S file */
-extern char safe_syscall_start[];
-extern char safe_syscall_end[];
-
-/* Adjust the signal context to rewind out of safe-syscall if we're in it */
-static inline void rewind_if_in_safe_syscall(void *puc)
-{
-    struct ucontext *uc = puc;
-    unsigned long *pcreg = &uc->uc_mcontext.arm_pc;
-
-    if (*pcreg > (uintptr_t)safe_syscall_start
-        && *pcreg < (uintptr_t)safe_syscall_end) {
-        *pcreg = (uintptr_t)safe_syscall_start;
-    }
-}
-
-#endif /* __ASSEMBLER__ */
-
-#endif
diff --git a/linux-user/host/arm/safe-syscall.inc.S b/linux-user/host/arm/safe-syscall.inc.S
deleted file mode 100644 (file)
index 88c4958..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * safe-syscall.inc.S : host-specific assembly fragment
- * to handle signals occurring at the same time as system calls.
- * This is intended to be included by linux-user/safe-syscall.S
- *
- * Written by Richard Henderson <rth@twiddle.net>
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-       .global safe_syscall_base
-       .global safe_syscall_start
-       .global safe_syscall_end
-       .type   safe_syscall_base, %function
-
-       .cfi_sections   .debug_frame
-
-       .text
-       .syntax unified
-       .arm
-       .align 2
-
-       /* This is the entry point for making a system call. The calling
-        * convention here is that of a C varargs function with the
-        * first argument an 'int *' to the signal_pending flag, the
-        * second one the system call number (as a 'long'), and all further
-        * arguments being syscall arguments (also 'long').
-        * We return a long which is the syscall's return value, which
-        * may be negative-errno on failure. Conversion to the
-        * -1-and-errno-set convention is done by the calling wrapper.
-        */
-safe_syscall_base:
-       .fnstart
-       .cfi_startproc
-       mov     r12, sp                 /* save entry stack */
-       push    { r4, r5, r6, r7, r8, lr }
-       .save   { r4, r5, r6, r7, r8, lr }
-       .cfi_adjust_cfa_offset 24
-       .cfi_rel_offset r4, 0
-       .cfi_rel_offset r5, 4
-       .cfi_rel_offset r6, 8
-       .cfi_rel_offset r7, 12
-       .cfi_rel_offset r8, 16
-       .cfi_rel_offset lr, 20
-
-       /* The syscall calling convention isn't the same as the C one:
-        * we enter with r0 == *signal_pending
-        *               r1 == syscall number
-        *               r2, r3, [sp+0] ... [sp+12] == syscall arguments
-        *               and return the result in r0
-        * and the syscall instruction needs
-        *               r7 == syscall number
-        *               r0 ... r6 == syscall arguments
-        *               and returns the result in r0
-        * Shuffle everything around appropriately.
-        * Note the 16 bytes that we pushed to save registers.
-        */
-       mov     r8, r0                  /* copy signal_pending */
-       mov     r7, r1                  /* syscall number */
-       mov     r0, r2                  /* syscall args */
-       mov     r1, r3
-       ldm     r12, { r2, r3, r4, r5, r6 }
-
-       /* This next sequence of code works in conjunction with the
-        * rewind_if_safe_syscall_function(). If a signal is taken
-        * and the interrupted PC is anywhere between 'safe_syscall_start'
-        * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
-        * The code sequence must therefore be able to cope with this, and
-        * the syscall instruction must be the final one in the sequence.
-        */
-safe_syscall_start:
-       /* if signal_pending is non-zero, don't do the call */
-       ldr     r12, [r8]               /* signal_pending */
-       tst     r12, r12
-       bne     1f
-       swi     0
-safe_syscall_end:
-       /* code path for having successfully executed the syscall */
-       pop     { r4, r5, r6, r7, r8, pc }
-
-1:
-       /* code path when we didn't execute the syscall */
-       ldr     r0, =-TARGET_ERESTARTSYS
-       pop     { r4, r5, r6, r7, r8, pc }
-       .fnend
-       .cfi_endproc
-
-       .size   safe_syscall_base, .-safe_syscall_base
diff --git a/linux-user/host/i386/hostdep.h b/linux-user/host/i386/hostdep.h
deleted file mode 100644 (file)
index d834bd8..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- *  * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef I386_HOSTDEP_H
-#define I386_HOSTDEP_H
-
-/* We have a safe-syscall.inc.S */
-#define HAVE_SAFE_SYSCALL
-
-#ifndef __ASSEMBLER__
-
-/* These are defined by the safe-syscall.inc.S file */
-extern char safe_syscall_start[];
-extern char safe_syscall_end[];
-
-/* Adjust the signal context to rewind out of safe-syscall if we're in it */
-static inline void rewind_if_in_safe_syscall(void *puc)
-{
-    struct ucontext *uc = puc;
-    greg_t *pcreg = &uc->uc_mcontext.gregs[REG_EIP];
-
-    if (*pcreg > (uintptr_t)safe_syscall_start
-        && *pcreg < (uintptr_t)safe_syscall_end) {
-        *pcreg = (uintptr_t)safe_syscall_start;
-    }
-}
-
-#endif /* __ASSEMBLER__ */
-
-#endif
diff --git a/linux-user/host/i386/safe-syscall.inc.S b/linux-user/host/i386/safe-syscall.inc.S
deleted file mode 100644 (file)
index 9e58fc6..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * safe-syscall.inc.S : host-specific assembly fragment
- * to handle signals occurring at the same time as system calls.
- * This is intended to be included by linux-user/safe-syscall.S
- *
- * Written by Richard Henderson <rth@twiddle.net>
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-       .global safe_syscall_base
-       .global safe_syscall_start
-       .global safe_syscall_end
-       .type   safe_syscall_base, @function
-
-       /* This is the entry point for making a system call. The calling
-        * convention here is that of a C varargs function with the
-        * first argument an 'int *' to the signal_pending flag, the
-        * second one the system call number (as a 'long'), and all further
-        * arguments being syscall arguments (also 'long').
-        * We return a long which is the syscall's return value, which
-        * may be negative-errno on failure. Conversion to the
-        * -1-and-errno-set convention is done by the calling wrapper.
-        */
-safe_syscall_base:
-       .cfi_startproc
-       push    %ebp
-       .cfi_adjust_cfa_offset 4
-       .cfi_rel_offset ebp, 0
-       push    %esi
-       .cfi_adjust_cfa_offset 4
-       .cfi_rel_offset esi, 0
-       push    %edi
-       .cfi_adjust_cfa_offset 4
-       .cfi_rel_offset edi, 0
-       push    %ebx
-       .cfi_adjust_cfa_offset 4
-       .cfi_rel_offset ebx, 0
-
-       /* The syscall calling convention isn't the same as the C one:
-        * we enter with 0(%esp) == return address
-        *               4(%esp) == *signal_pending
-        *               8(%esp) == syscall number
-        *               12(%esp) ... 32(%esp) == syscall arguments
-        *               and return the result in eax
-        * and the syscall instruction needs
-        *               eax == syscall number
-        *               ebx, ecx, edx, esi, edi, ebp == syscall arguments
-        *               and returns the result in eax
-        * Shuffle everything around appropriately.
-        * Note the 16 bytes that we pushed to save registers.
-        */
-       mov     12+16(%esp), %ebx       /* the syscall arguments */
-       mov     16+16(%esp), %ecx
-       mov     20+16(%esp), %edx
-       mov     24+16(%esp), %esi
-       mov     28+16(%esp), %edi
-       mov     32+16(%esp), %ebp
-
-       /* This next sequence of code works in conjunction with the
-        * rewind_if_safe_syscall_function(). If a signal is taken
-        * and the interrupted PC is anywhere between 'safe_syscall_start'
-        * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
-        * The code sequence must therefore be able to cope with this, and
-        * the syscall instruction must be the final one in the sequence.
-        */
-safe_syscall_start:
-       /* if signal_pending is non-zero, don't do the call */
-       mov     4+16(%esp), %eax        /* signal_pending */
-       cmpl    $0, (%eax)
-       jnz     1f
-       mov     8+16(%esp), %eax        /* syscall number */
-       int     $0x80
-safe_syscall_end:
-       /* code path for having successfully executed the syscall */
-       pop     %ebx
-       .cfi_remember_state
-       .cfi_adjust_cfa_offset -4
-       .cfi_restore ebx
-       pop     %edi
-       .cfi_adjust_cfa_offset -4
-       .cfi_restore edi
-       pop     %esi
-       .cfi_adjust_cfa_offset -4
-       .cfi_restore esi
-       pop     %ebp
-       .cfi_adjust_cfa_offset -4
-       .cfi_restore ebp
-       ret
-
-1:
-       /* code path when we didn't execute the syscall */
-       .cfi_restore_state
-       mov     $-TARGET_ERESTARTSYS, %eax
-       jmp     safe_syscall_end
-       .cfi_endproc
-
-       .size   safe_syscall_base, .-safe_syscall_base
diff --git a/linux-user/host/ia64/hostdep.h b/linux-user/host/ia64/hostdep.h
deleted file mode 100644 (file)
index 263bf76..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- *  * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef IA64_HOSTDEP_H
-#define IA64_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/mips/hostdep.h b/linux-user/host/mips/hostdep.h
deleted file mode 100644 (file)
index ba111d7..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- *  * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef MIPS_HOSTDEP_H
-#define MIPS_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/ppc/hostdep.h b/linux-user/host/ppc/hostdep.h
deleted file mode 100644 (file)
index 23d8bd9..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- *  * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef PPC_HOSTDEP_H
-#define PPC_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/ppc64/hostdep.h b/linux-user/host/ppc64/hostdep.h
deleted file mode 100644 (file)
index 0b0f5f7..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- *  * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef PPC64_HOSTDEP_H
-#define PPC64_HOSTDEP_H
-
-/* We have a safe-syscall.inc.S */
-#define HAVE_SAFE_SYSCALL
-
-#ifndef __ASSEMBLER__
-
-/* These are defined by the safe-syscall.inc.S file */
-extern char safe_syscall_start[];
-extern char safe_syscall_end[];
-
-/* Adjust the signal context to rewind out of safe-syscall if we're in it */
-static inline void rewind_if_in_safe_syscall(void *puc)
-{
-    struct ucontext *uc = puc;
-    unsigned long *pcreg = &uc->uc_mcontext.gp_regs[PT_NIP];
-
-    if (*pcreg > (uintptr_t)safe_syscall_start
-        && *pcreg < (uintptr_t)safe_syscall_end) {
-        *pcreg = (uintptr_t)safe_syscall_start;
-    }
-}
-
-#endif /* __ASSEMBLER__ */
-
-#endif
diff --git a/linux-user/host/ppc64/safe-syscall.inc.S b/linux-user/host/ppc64/safe-syscall.inc.S
deleted file mode 100644 (file)
index d30050a..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * safe-syscall.inc.S : host-specific assembly fragment
- * to handle signals occurring at the same time as system calls.
- * This is intended to be included by linux-user/safe-syscall.S
- *
- * Written by Richard Henderson <rth@twiddle.net>
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-       .global safe_syscall_base
-       .global safe_syscall_start
-       .global safe_syscall_end
-       .type   safe_syscall_base, @function
-
-       .text
-
-       /* This is the entry point for making a system call. The calling
-        * convention here is that of a C varargs function with the
-        * first argument an 'int *' to the signal_pending flag, the
-        * second one the system call number (as a 'long'), and all further
-        * arguments being syscall arguments (also 'long').
-        * We return a long which is the syscall's return value, which
-        * may be negative-errno on failure. Conversion to the
-        * -1-and-errno-set convention is done by the calling wrapper.
-        */
-#if _CALL_ELF == 2
-safe_syscall_base:
-       .cfi_startproc
-       .localentry safe_syscall_base,0
-#else
-       .section ".opd","aw"
-       .align  3
-safe_syscall_base:
-       .quad   .L.safe_syscall_base,.TOC.@tocbase,0
-       .previous
-.L.safe_syscall_base:
-       .cfi_startproc
-#endif
-       /* We enter with r3 == *signal_pending
-        *               r4 == syscall number
-        *               r5 ... r10 == syscall arguments
-        *               and return the result in r3
-        * and the syscall instruction needs
-        *               r0 == syscall number
-        *               r3 ... r8 == syscall arguments
-        *               and returns the result in r3
-        * Shuffle everything around appropriately.
-        */
-       mr      11, 3   /* signal_pending */
-       mr      0, 4    /* syscall number */
-       mr      3, 5    /* syscall arguments */
-       mr      4, 6
-       mr      5, 7
-       mr      6, 8
-       mr      7, 9
-       mr      8, 10
-
-       /* This next sequence of code works in conjunction with the
-        * rewind_if_safe_syscall_function(). If a signal is taken
-        * and the interrupted PC is anywhere between 'safe_syscall_start'
-        * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
-        * The code sequence must therefore be able to cope with this, and
-        * the syscall instruction must be the final one in the sequence.
-        */
-safe_syscall_start:
-       /* if signal_pending is non-zero, don't do the call */
-       lwz     12, 0(11)
-       cmpwi   0, 12, 0
-       bne-    0f
-       sc
-safe_syscall_end:
-       /* code path when we did execute the syscall */
-       bnslr+
-
-       /* syscall failed; return negative errno */
-       neg     3, 3
-       blr
-
-       /* code path when we didn't execute the syscall */
-0:     addi    3, 0, -TARGET_ERESTARTSYS
-       blr
-       .cfi_endproc
-
-#if _CALL_ELF == 2
-       .size   safe_syscall_base, .-safe_syscall_base
-#else
-       .size   safe_syscall_base, .-.L.safe_syscall_base
-       .size   .L.safe_syscall_base, .-.L.safe_syscall_base
-#endif
diff --git a/linux-user/host/s390/hostdep.h b/linux-user/host/s390/hostdep.h
deleted file mode 100644 (file)
index afcba5a..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- *  * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef S390_HOSTDEP_H
-#define S390_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/s390x/hostdep.h b/linux-user/host/s390x/hostdep.h
deleted file mode 100644 (file)
index 6f9da9c..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- *  * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef S390X_HOSTDEP_H
-#define S390X_HOSTDEP_H
-
-/* We have a safe-syscall.inc.S */
-#define HAVE_SAFE_SYSCALL
-
-#ifndef __ASSEMBLER__
-
-/* These are defined by the safe-syscall.inc.S file */
-extern char safe_syscall_start[];
-extern char safe_syscall_end[];
-
-/* Adjust the signal context to rewind out of safe-syscall if we're in it */
-static inline void rewind_if_in_safe_syscall(void *puc)
-{
-    struct ucontext *uc = puc;
-    unsigned long *pcreg = &uc->uc_mcontext.psw.addr;
-
-    if (*pcreg > (uintptr_t)safe_syscall_start
-        && *pcreg < (uintptr_t)safe_syscall_end) {
-        *pcreg = (uintptr_t)safe_syscall_start;
-    }
-}
-
-#endif /* __ASSEMBLER__ */
-
-#endif
diff --git a/linux-user/host/s390x/safe-syscall.inc.S b/linux-user/host/s390x/safe-syscall.inc.S
deleted file mode 100644 (file)
index f1b446a..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * safe-syscall.inc.S : host-specific assembly fragment
- * to handle signals occurring at the same time as system calls.
- * This is intended to be included by linux-user/safe-syscall.S
- *
- * Written by Richard Henderson <rth@twiddle.net>
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-       .global safe_syscall_base
-       .global safe_syscall_start
-       .global safe_syscall_end
-       .type   safe_syscall_base, @function
-
-       /* This is the entry point for making a system call. The calling
-        * convention here is that of a C varargs function with the
-        * first argument an 'int *' to the signal_pending flag, the
-        * second one the system call number (as a 'long'), and all further
-        * arguments being syscall arguments (also 'long').
-        * We return a long which is the syscall's return value, which
-        * may be negative-errno on failure. Conversion to the
-        * -1-and-errno-set convention is done by the calling wrapper.
-        */
-safe_syscall_base:
-       .cfi_startproc
-       stmg    %r6,%r15,48(%r15)       /* save all call-saved registers */
-       .cfi_offset %r15,-40
-       .cfi_offset %r14,-48
-       .cfi_offset %r13,-56
-       .cfi_offset %r12,-64
-       .cfi_offset %r11,-72
-       .cfi_offset %r10,-80
-       .cfi_offset %r9,-88
-       .cfi_offset %r8,-96
-       .cfi_offset %r7,-104
-       .cfi_offset %r6,-112
-       lgr     %r1,%r15
-       lg      %r0,8(%r15)             /* load eos */
-       aghi    %r15,-160
-       .cfi_adjust_cfa_offset 160
-       stg     %r1,0(%r15)             /* store back chain */
-       stg     %r0,8(%r15)             /* store eos */
-
-       /* The syscall calling convention isn't the same as the
-        * C one:
-        * we enter with r2 == *signal_pending
-        *               r3 == syscall number
-        *               r4, r5, r6, (stack) == syscall arguments
-        *               and return the result in r2
-        * and the syscall instruction needs
-        *               r1 == syscall number
-        *               r2 ... r7 == syscall arguments
-        *               and returns the result in r2
-        * Shuffle everything around appropriately.
-        */
-       lgr     %r8,%r2                 /* signal_pending pointer */
-       lgr     %r1,%r3                 /* syscall number */
-       lgr     %r2,%r4                 /* syscall args */
-       lgr     %r3,%r5
-       lgr     %r4,%r6
-       lmg     %r5,%r7,320(%r15)
-
-       /* This next sequence of code works in conjunction with the
-        * rewind_if_safe_syscall_function(). If a signal is taken
-        * and the interrupted PC is anywhere between 'safe_syscall_start'
-        * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
-        * The code sequence must therefore be able to cope with this, and
-        * the syscall instruction must be the final one in the sequence.
-        */
-safe_syscall_start:
-       /* if signal_pending is non-zero, don't do the call */
-       lt      %r0,0(%r8)
-       jne     2f
-       svc     0
-safe_syscall_end:
-
-1:     lg      %r15,0(%r15)            /* load back chain */
-       .cfi_remember_state
-       .cfi_adjust_cfa_offset -160
-       lmg     %r6,%r15,48(%r15)       /* load saved registers */
-       br      %r14
-       .cfi_restore_state
-2:     lghi    %r2, -TARGET_ERESTARTSYS
-       j       1b
-       .cfi_endproc
-
-       .size   safe_syscall_base, .-safe_syscall_base
diff --git a/linux-user/host/sparc/hostdep.h b/linux-user/host/sparc/hostdep.h
deleted file mode 100644 (file)
index 391ad92..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- *  * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef SPARC_HOSTDEP_H
-#define SPARC_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/sparc64/hostdep.h b/linux-user/host/sparc64/hostdep.h
deleted file mode 100644 (file)
index ce3968f..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- *  * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef SPARC64_HOSTDEP_H
-#define SPARC64_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/x32/hostdep.h b/linux-user/host/x32/hostdep.h
deleted file mode 100644 (file)
index 2c2d6d3..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- *  * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef X32_HOSTDEP_H
-#define X32_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/x86_64/hostdep.h b/linux-user/host/x86_64/hostdep.h
deleted file mode 100644 (file)
index 3b42596..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- *  * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef X86_64_HOSTDEP_H
-#define X86_64_HOSTDEP_H
-
-/* We have a safe-syscall.inc.S */
-#define HAVE_SAFE_SYSCALL
-
-#ifndef __ASSEMBLER__
-
-/* These are defined by the safe-syscall.inc.S file */
-extern char safe_syscall_start[];
-extern char safe_syscall_end[];
-
-/* Adjust the signal context to rewind out of safe-syscall if we're in it */
-static inline void rewind_if_in_safe_syscall(void *puc)
-{
-    struct ucontext *uc = puc;
-    greg_t *pcreg = &uc->uc_mcontext.gregs[REG_RIP];
-
-    if (*pcreg > (uintptr_t)safe_syscall_start
-        && *pcreg < (uintptr_t)safe_syscall_end) {
-        *pcreg = (uintptr_t)safe_syscall_start;
-    }
-}
-
-#endif /* __ASSEMBLER__ */
-
-#endif
diff --git a/linux-user/host/x86_64/safe-syscall.inc.S b/linux-user/host/x86_64/safe-syscall.inc.S
deleted file mode 100644 (file)
index f36992d..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * safe-syscall.inc.S : host-specific assembly fragment
- * to handle signals occurring at the same time as system calls.
- * This is intended to be included by linux-user/safe-syscall.S
- *
- * Copyright (C) 2015 Timothy Edward Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-        .global safe_syscall_base
-        .global safe_syscall_start
-        .global safe_syscall_end
-        .type   safe_syscall_base, @function
-
-        /* This is the entry point for making a system call. The calling
-         * convention here is that of a C varargs function with the
-         * first argument an 'int *' to the signal_pending flag, the
-         * second one the system call number (as a 'long'), and all further
-         * arguments being syscall arguments (also 'long').
-         * We return a long which is the syscall's return value, which
-         * may be negative-errno on failure. Conversion to the
-         * -1-and-errno-set convention is done by the calling wrapper.
-         */
-safe_syscall_base:
-        .cfi_startproc
-        /* This saves a frame pointer and aligns the stack for the syscall.
-         * (It's unclear if the syscall ABI has the same stack alignment
-         * requirements as the userspace function call ABI, but better safe than
-         * sorry. Appendix A2 of http://www.x86-64.org/documentation/abi.pdf
-         * does not list any ABI differences regarding stack alignment.)
-         */
-        push    %rbp
-        .cfi_adjust_cfa_offset 8
-        .cfi_rel_offset rbp, 0
-
-        /* The syscall calling convention isn't the same as the
-         * C one:
-         * we enter with rdi == *signal_pending
-         *               rsi == syscall number
-         *               rdx, rcx, r8, r9, (stack), (stack) == syscall arguments
-         *               and return the result in rax
-         * and the syscall instruction needs
-         *               rax == syscall number
-         *               rdi, rsi, rdx, r10, r8, r9 == syscall arguments
-         *               and returns the result in rax
-         * Shuffle everything around appropriately.
-         * Note that syscall will trash rcx and r11.
-         */
-        mov     %rsi, %rax /* syscall number */
-        mov     %rdi, %rbp /* signal_pending pointer */
-        /* and the syscall arguments */
-        mov     %rdx, %rdi
-        mov     %rcx, %rsi
-        mov     %r8,  %rdx
-        mov     %r9,  %r10
-        mov     16(%rsp), %r8
-        mov     24(%rsp), %r9
-
-        /* This next sequence of code works in conjunction with the
-         * rewind_if_safe_syscall_function(). If a signal is taken
-         * and the interrupted PC is anywhere between 'safe_syscall_start'
-         * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
-         * The code sequence must therefore be able to cope with this, and
-         * the syscall instruction must be the final one in the sequence.
-         */
-safe_syscall_start:
-        /* if signal_pending is non-zero, don't do the call */
-        cmpl   $0, (%rbp)
-        jnz     1f
-        syscall
-safe_syscall_end:
-        /* code path for having successfully executed the syscall */
-        pop     %rbp
-        .cfi_remember_state
-        .cfi_def_cfa_offset 8
-        .cfi_restore rbp
-        ret
-
-1:
-        /* code path when we didn't execute the syscall */
-        .cfi_restore_state
-        mov     $-TARGET_ERESTARTSYS, %rax
-        pop     %rbp
-        .cfi_def_cfa_offset 8
-        .cfi_restore rbp
-        ret
-        .cfi_endproc
-
-        .size   safe_syscall_base, .-safe_syscall_base
index 7fbcf9b..58f8645 100644 (file)
@@ -17,8 +17,8 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef I386_TARGET_CPU_H
-#define I386_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp)
 {
@@ -45,4 +45,4 @@ static inline void cpu_set_tls(CPUX86State *env, target_ulong newtls)
 }
 #endif /* defined(TARGET_ABI32) */
 
-#endif /* I386_TARGET_CPU_H */
+#endif /* !defined(TARGET_CPU_H) */
index 837e90f..9baf7fb 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef I386_TARGET_SIGNAL_H
-#define I386_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -26,4 +26,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
     return state->regs[R_ESP];
 }
 
-#endif /* I386_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index 25388a7..65f535e 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef I386_TARGET_STRUCTS_H
-#define I386_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index b4e895f..0ac84dc 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef I386_TARGET_SYSCALL_H
-#define I386_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 /* default linux values for the selectors */
 #define __USER_CS      (0x23)
@@ -154,4 +154,4 @@ struct target_vm86plus_struct {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
-#endif /* I386_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index 7e2c133..e672655 100644 (file)
      IOCTL(BLKFLSBUF, 0, TYPE_NULL)
      IOCTL(BLKRASET, 0, TYPE_INT)
      IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
-     IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_INT))
+     IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
      IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
      IOCTL_SPECIAL(BLKPG, IOC_W, do_ioctl_blkpg,
                    MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
-
-#ifdef BLKDISCARD
-     IOCTL(BLKDISCARD, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2)))
-#endif
-#ifdef BLKIOMIN
-     IOCTL(BLKIOMIN, IOC_R, MK_PTR(TYPE_INT))
-#endif
-#ifdef BLKIOOPT
-     IOCTL(BLKIOOPT, IOC_R, MK_PTR(TYPE_INT))
-#endif
-#ifdef BLKALIGNOFF
-     IOCTL(BLKALIGNOFF, IOC_R, MK_PTR(TYPE_INT))
-#endif
-#ifdef BLKPBSZGET
-     IOCTL(BLKPBSZGET, IOC_R, MK_PTR(TYPE_INT))
-#endif
-#ifdef BLKDISCARDZEROES
-     IOCTL(BLKDISCARDZEROES, IOC_R, MK_PTR(TYPE_INT))
-#endif
-#ifdef BLKSECDISCARD
-     IOCTL(BLKSECDISCARD, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2)))
-#endif
-#ifdef BLKROTATIONAL
-     IOCTL(BLKROTATIONAL, IOC_R, MK_PTR(TYPE_SHORT))
-#endif
-#ifdef BLKZEROOUT
-     IOCTL(BLKZEROOUT, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2)))
-#endif
-
 #ifdef FIBMAP
      IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
 #endif
                    MK_PTR(MK_STRUCT(STRUCT_fiemap)))
 #endif
 
-  IOCTL(SIOCATMARK, IOC_R, MK_PTR(TYPE_INT))
+  IOCTL(SIOCATMARK, 0, TYPE_NULL)
   IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
   IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
   IOCTL(SIOCSIFFLAGS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
   IOCTL(LOOP_SET_FD, 0, TYPE_INT)
   IOCTL(LOOP_CLR_FD, 0, TYPE_INT)
   IOCTL(LOOP_SET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
-  IOCTL(LOOP_GET_STATUS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
+  IOCTL(LOOP_GET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
   IOCTL(LOOP_SET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
-  IOCTL(LOOP_GET_STATUS64, IOC_R, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
+  IOCTL(LOOP_GET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
   IOCTL(LOOP_CHANGE_FD, 0, TYPE_INT)
 
-  IOCTL(LOOP_CTL_ADD, 0, TYPE_INT)
-  IOCTL(LOOP_CTL_REMOVE, 0, TYPE_INT)
-  IOCTL(LOOP_CTL_GET_FREE, 0, TYPE_NULL)
-
   IOCTL(MTIOCTOP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_mtop)))
   IOCTL(MTIOCGET, IOC_R, MK_PTR(MK_STRUCT(STRUCT_mtget)))
   IOCTL(MTIOCPOS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_mtpos)))
index c69fea1..8974caa 100644 (file)
@@ -1,9 +1,6 @@
-/* Copied from 2.6.25 kernel headers to avoid problems on older hosts,
- * and subsequently updated to match newer additions to the API.
- */
-
-#ifndef LINUX_LOOP_H
-#define LINUX_LOOP_H
+/* Copied from 2.6.25 kernel headers to avoid problems on older hosts.  */
+#ifndef _LINUX_LOOP_H
+#define _LINUX_LOOP_H
 
 /*
  * include/linux/loop.h
@@ -94,12 +91,5 @@ struct loop_info64 {
 #define LOOP_SET_STATUS64      0x4C04
 #define LOOP_GET_STATUS64      0x4C05
 #define LOOP_CHANGE_FD         0x4C06
-#define LOOP_SET_CAPACITY       0x4C07
-#define LOOP_SET_DIRECT_IO      0x4C08
-
-/* /dev/loop-control interface */
-#define LOOP_CTL_ADD            0x4C80
-#define LOOP_CTL_REMOVE         0x4C81
-#define LOOP_CTL_GET_FREE       0x4C82
 
 #endif
index cc0bfc2..bb4d3fa 100644 (file)
@@ -18,8 +18,8 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef M68K_TARGET_CPU_H
-#define M68K_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUM68KState *env, target_ulong newsp)
 {
index 9d2d734..479758a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef M68K_TARGET_SIGNAL_H
-#define M68K_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -26,5 +26,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUM68KState *state)
     return state->aregs[7];
 }
 
-
-#endif /* M68K_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index a003676..de257c9 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef M68K_TARGET_STRUCTS_H
-#define M68K_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index db2be4f..97a4cc0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef M68K_TARGET_SYSCALL_H
-#define M68K_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 /* this struct defines the way the registers are stored on the
    stack during a system call. */
@@ -26,4 +26,4 @@ struct target_pt_regs {
 
 void do_m68k_simcall(CPUM68KState *, int);
 
-#endif /* M68K_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index f2f4d2f..5f3ec97 100644 (file)
  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "qemu/osdep.h"
-#include "qemu-version.h"
+#include <sys/mman.h>
 #include <sys/syscall.h>
 #include <sys/resource.h>
 
-#include "qapi/error.h"
 #include "qemu.h"
 #include "qemu/path.h"
-#include "qemu/config-file.h"
 #include "qemu/cutils.h"
 #include "qemu/help_option.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "tcg.h"
 #include "qemu/timer.h"
 #include "qemu/envlist.h"
 #include "elf.h"
 #include "exec/log.h"
-#include "trace/control.h"
-#include "glib-compat.h"
 
 char *exec_path;
 
@@ -134,7 +129,7 @@ void fork_end(int child)
            Discard information about the parent threads.  */
         CPU_FOREACH_SAFE(cpu, next_cpu) {
             if (cpu != thread_cpu) {
-                QTAILQ_REMOVE(&cpus, cpu, node);
+                QTAILQ_REMOVE(&cpus, thread_cpu, node);
             }
         }
         pending_cpus = 0;
@@ -160,7 +155,7 @@ static inline void exclusive_idle(void)
 }
 
 /* Start an exclusive operation.
-   Must only be called from outside cpu_exec.   */
+   Must only be called from outside cpu_arm_exec.   */
 static inline void start_exclusive(void)
 {
     CPUState *other_cpu;
@@ -289,48 +284,37 @@ void cpu_loop(CPUX86State *env)
     CPUState *cs = CPU(x86_env_get_cpu(env));
     int trapnr;
     abi_ulong pc;
-    abi_ulong ret;
     target_siginfo_t info;
 
     for(;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_x86_exec(cs);
         cpu_exec_end(cs);
         switch(trapnr) {
         case 0x80:
             /* linux syscall from int $0x80 */
-            ret = do_syscall(env,
-                             env->regs[R_EAX],
-                             env->regs[R_EBX],
-                             env->regs[R_ECX],
-                             env->regs[R_EDX],
-                             env->regs[R_ESI],
-                             env->regs[R_EDI],
-                             env->regs[R_EBP],
-                             0, 0);
-            if (ret == -TARGET_ERESTARTSYS) {
-                env->eip -= 2;
-            } else if (ret != -TARGET_QEMU_ESIGRETURN) {
-                env->regs[R_EAX] = ret;
-            }
+            env->regs[R_EAX] = do_syscall(env,
+                                          env->regs[R_EAX],
+                                          env->regs[R_EBX],
+                                          env->regs[R_ECX],
+                                          env->regs[R_EDX],
+                                          env->regs[R_ESI],
+                                          env->regs[R_EDI],
+                                          env->regs[R_EBP],
+                                          0, 0);
             break;
 #ifndef TARGET_ABI32
         case EXCP_SYSCALL:
             /* linux syscall from syscall instruction */
-            ret = do_syscall(env,
-                             env->regs[R_EAX],
-                             env->regs[R_EDI],
-                             env->regs[R_ESI],
-                             env->regs[R_EDX],
-                             env->regs[10],
-                             env->regs[8],
-                             env->regs[9],
-                             0, 0);
-            if (ret == -TARGET_ERESTARTSYS) {
-                env->eip -= 2;
-            } else if (ret != -TARGET_QEMU_ESIGRETURN) {
-                env->regs[R_EAX] = ret;
-            }
+            env->regs[R_EAX] = do_syscall(env,
+                                          env->regs[R_EAX],
+                                          env->regs[R_EDI],
+                                          env->regs[R_ESI],
+                                          env->regs[R_EDX],
+                                          env->regs[10],
+                                          env->regs[8],
+                                          env->regs[9],
+                                          0, 0);
             break;
 #endif
         case EXCP0B_NOSEG:
@@ -731,11 +715,10 @@ void cpu_loop(CPUARMState *env)
     unsigned int n, insn;
     target_siginfo_t info;
     uint32_t addr;
-    abi_ulong ret;
 
     for(;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_arm_exec(cs);
         cpu_exec_end(cs);
         switch(trapnr) {
         case EXCP_UDEF:
@@ -870,20 +853,15 @@ void cpu_loop(CPUARMState *env)
                             break;
                         }
                     } else {
-                        ret = do_syscall(env,
-                                         n,
-                                         env->regs[0],
-                                         env->regs[1],
-                                         env->regs[2],
-                                         env->regs[3],
-                                         env->regs[4],
-                                         env->regs[5],
-                                         0, 0);
-                        if (ret == -TARGET_ERESTARTSYS) {
-                            env->regs[15] -= env->thumb ? 2 : 4;
-                        } else if (ret != -TARGET_QEMU_ESIGRETURN) {
-                            env->regs[0] = ret;
-                        }
+                        env->regs[0] = do_syscall(env,
+                                                  n,
+                                                  env->regs[0],
+                                                  env->regs[1],
+                                                  env->regs[2],
+                                                  env->regs[3],
+                                                  env->regs[4],
+                                                  env->regs[5],
+                                                  0, 0);
                     }
                 } else {
                     goto error;
@@ -1066,30 +1044,24 @@ void cpu_loop(CPUARMState *env)
 {
     CPUState *cs = CPU(arm_env_get_cpu(env));
     int trapnr, sig;
-    abi_long ret;
     target_siginfo_t info;
 
     for (;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_arm_exec(cs);
         cpu_exec_end(cs);
 
         switch (trapnr) {
         case EXCP_SWI:
-            ret = do_syscall(env,
-                             env->xregs[8],
-                             env->xregs[0],
-                             env->xregs[1],
-                             env->xregs[2],
-                             env->xregs[3],
-                             env->xregs[4],
-                             env->xregs[5],
-                             0, 0);
-            if (ret == -TARGET_ERESTARTSYS) {
-                env->pc -= 4;
-            } else if (ret != -TARGET_QEMU_ESIGRETURN) {
-                env->xregs[0] = ret;
-            }
+            env->xregs[0] = do_syscall(env,
+                                       env->xregs[8],
+                                       env->xregs[0],
+                                       env->xregs[1],
+                                       env->xregs[2],
+                                       env->xregs[3],
+                                       env->xregs[4],
+                                       env->xregs[5],
+                                       0, 0);
             break;
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
@@ -1159,7 +1131,7 @@ void cpu_loop(CPUUniCore32State *env)
 
     for (;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = uc32_cpu_exec(cs);
         cpu_exec_end(cs);
         switch (trapnr) {
         case UC32_EXCP_PRIV:
@@ -1175,7 +1147,7 @@ void cpu_loop(CPUUniCore32State *env)
                             cpu_set_tls(env, env->regs[0]);
                             env->regs[0] = 0;
                     } else {
-                        abi_long ret = do_syscall(env,
+                        env->regs[0] = do_syscall(env,
                                                   n,
                                                   env->regs[0],
                                                   env->regs[1],
@@ -1184,11 +1156,6 @@ void cpu_loop(CPUUniCore32State *env)
                                                   env->regs[4],
                                                   env->regs[5],
                                                   0, 0);
-                        if (ret == -TARGET_ERESTARTSYS) {
-                            env->regs[31] -= 4;
-                        } else if (ret != -TARGET_QEMU_ESIGRETURN) {
-                            env->regs[0] = ret;
-                        }
                     }
                 } else {
                     goto error;
@@ -1364,7 +1331,7 @@ void cpu_loop (CPUSPARCState *env)
 
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_sparc_exec(cs);
         cpu_exec_end(cs);
 
         /* Compute PSR before exposing state.  */
@@ -1385,9 +1352,6 @@ void cpu_loop (CPUSPARCState *env)
                               env->regwptr[2], env->regwptr[3],
                               env->regwptr[4], env->regwptr[5],
                               0, 0);
-            if (ret == -TARGET_ERESTARTSYS || ret == -TARGET_QEMU_ESIGRETURN) {
-                break;
-            }
             if ((abi_ulong)ret >= (abi_ulong)(-515)) {
 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
                 env->xcc |= PSR_CARRY;
@@ -1636,7 +1600,7 @@ void cpu_loop(CPUPPCState *env)
 
     for(;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_ppc_exec(cs);
         cpu_exec_end(cs);
         switch(trapnr) {
         case POWERPC_EXCP_NONE:
@@ -1724,7 +1688,6 @@ void cpu_loop(CPUPPCState *env)
             queue_signal(env, info.si_signo, &info);
             break;
         case POWERPC_EXCP_PROGRAM:  /* Program exception                     */
-        case POWERPC_EXCP_HV_EMU:   /* HV emulation                          */
             /* XXX: check this */
             switch (env->error_code & ~0xF) {
             case POWERPC_EXCP_FP:
@@ -2000,10 +1963,6 @@ void cpu_loop(CPUPPCState *env)
             ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
                              env->gpr[5], env->gpr[6], env->gpr[7],
                              env->gpr[8], 0, 0);
-            if (ret == -TARGET_ERESTARTSYS) {
-                env->nip -= 4;
-                break;
-            }
             if (ret == (target_ulong)(-TARGET_QEMU_ESIGRETURN)) {
                 /* Returning from a successful sigreturn syscall.
                    Avoid corrupting register state.  */
@@ -2493,7 +2452,7 @@ void cpu_loop(CPUMIPSState *env)
 
     for(;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_mips_exec(cs);
         cpu_exec_end(cs);
         switch(trapnr) {
         case EXCP_SYSCALL:
@@ -2545,10 +2504,6 @@ done_syscall:
                              env->active_tc.gpr[8], env->active_tc.gpr[9],
                              env->active_tc.gpr[10], env->active_tc.gpr[11]);
 # endif /* O32 */
-            if (ret == -TARGET_ERESTARTSYS) {
-                env->active_tc.PC -= 4;
-                break;
-            }
             if (ret == -TARGET_QEMU_ESIGRETURN) {
                 /* Returning from a successful sigreturn syscall.
                    Avoid clobbering register state.  */
@@ -2729,11 +2684,10 @@ void cpu_loop(CPUOpenRISCState *env)
 {
     CPUState *cs = CPU(openrisc_env_get_cpu(env));
     int trapnr, gdbsig;
-    abi_long ret;
 
     for (;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_openrisc_exec(cs);
         cpu_exec_end(cs);
         gdbsig = 0;
 
@@ -2775,19 +2729,14 @@ void cpu_loop(CPUOpenRISCState *env)
             break;
         case EXCP_SYSCALL:
             env->pc += 4;   /* 0xc00; */
-            ret = do_syscall(env,
-                             env->gpr[11], /* return value       */
-                             env->gpr[3],  /* r3 - r7 are params */
-                             env->gpr[4],
-                             env->gpr[5],
-                             env->gpr[6],
-                             env->gpr[7],
-                             env->gpr[8], 0, 0);
-            if (ret == -TARGET_ERESTARTSYS) {
-                env->pc -= 4;
-            } else if (ret != -TARGET_QEMU_ESIGRETURN) {
-                env->gpr[11] = ret;
-            }
+            env->gpr[11] = do_syscall(env,
+                                      env->gpr[11], /* return value       */
+                                      env->gpr[3],  /* r3 - r7 are params */
+                                      env->gpr[4],
+                                      env->gpr[5],
+                                      env->gpr[6],
+                                      env->gpr[7],
+                                      env->gpr[8], 0, 0);
             break;
         case EXCP_FPE:
             qemu_log_mask(CPU_LOG_INT, "\nFloating point error\n");
@@ -2827,7 +2776,7 @@ void cpu_loop(CPUSH4State *env)
 
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_sh4_exec(cs);
         cpu_exec_end(cs);
 
         switch (trapnr) {
@@ -2842,11 +2791,7 @@ void cpu_loop(CPUSH4State *env)
                              env->gregs[0],
                              env->gregs[1],
                              0, 0);
-            if (ret == -TARGET_ERESTARTSYS) {
-                env->pc -= 2;
-            } else if (ret != -TARGET_QEMU_ESIGRETURN) {
-                env->gregs[0] = ret;
-            }
+            env->gregs[0] = ret;
             break;
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
@@ -2893,7 +2838,7 @@ void cpu_loop(CPUCRISState *env)
     
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_cris_exec(cs);
         cpu_exec_end(cs);
         switch (trapnr) {
         case 0xaa:
@@ -2919,11 +2864,7 @@ void cpu_loop(CPUCRISState *env)
                              env->pregs[7], 
                              env->pregs[11],
                              0, 0);
-            if (ret == -TARGET_ERESTARTSYS) {
-                env->pc -= 2;
-            } else if (ret != -TARGET_QEMU_ESIGRETURN) {
-                env->regs[10] = ret;
-            }
+            env->regs[10] = ret;
             break;
         case EXCP_DEBUG:
             {
@@ -2958,7 +2899,7 @@ void cpu_loop(CPUMBState *env)
     
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_mb_exec(cs);
         cpu_exec_end(cs);
         switch (trapnr) {
         case 0xaa:
@@ -2987,19 +2928,7 @@ void cpu_loop(CPUMBState *env)
                              env->regs[9], 
                              env->regs[10],
                              0, 0);
-            if (ret == -TARGET_ERESTARTSYS) {
-                /* Wind back to before the syscall. */
-                env->sregs[SR_PC] -= 4;
-            } else if (ret != -TARGET_QEMU_ESIGRETURN) {
-                env->regs[3] = ret;
-            }
-            /* All syscall exits result in guest r14 being equal to the
-             * PC we return to, because the kernel syscall exit "rtbd" does
-             * this. (This is true even for sigreturn(); note that r14 is
-             * not a userspace-usable register, as the kernel may clobber it
-             * at any point.)
-             */
-            env->regs[14] = env->sregs[SR_PC];
+            env->regs[3] = ret;
             break;
         case EXCP_HW_EXCP:
             env->regs[17] = env->sregs[SR_PC] + 4;
@@ -3075,7 +3004,7 @@ void cpu_loop(CPUM68KState *env)
 
     for(;;) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_m68k_exec(cs);
         cpu_exec_end(cs);
         switch(trapnr) {
         case EXCP_ILLEGAL:
@@ -3107,24 +3036,18 @@ void cpu_loop(CPUM68KState *env)
             break;
         case EXCP_TRAP0:
             {
-                abi_long ret;
                 ts->sim_syscalls = 0;
                 n = env->dregs[0];
                 env->pc += 2;
-                ret = do_syscall(env,
-                                 n,
-                                 env->dregs[1],
-                                 env->dregs[2],
-                                 env->dregs[3],
-                                 env->dregs[4],
-                                 env->dregs[5],
-                                 env->aregs[0],
-                                 0, 0);
-                if (ret == -TARGET_ERESTARTSYS) {
-                    env->pc -= 2;
-                } else if (ret != -TARGET_QEMU_ESIGRETURN) {
-                    env->dregs[0] = ret;
-                }
+                env->dregs[0] = do_syscall(env,
+                                          n,
+                                          env->dregs[1],
+                                          env->dregs[2],
+                                          env->dregs[3],
+                                          env->dregs[4],
+                                          env->dregs[5],
+                                          env->aregs[0],
+                                          0, 0);
             }
             break;
         case EXCP_INTERRUPT:
@@ -3218,7 +3141,7 @@ void cpu_loop(CPUAlphaState *env)
 
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_alpha_exec(cs);
         cpu_exec_end(cs);
 
         /* All of the traps imply a transition through PALcode, which
@@ -3305,11 +3228,8 @@ void cpu_loop(CPUAlphaState *env)
                                     env->ir[IR_A2], env->ir[IR_A3],
                                     env->ir[IR_A4], env->ir[IR_A5],
                                     0, 0);
-                if (sysret == -TARGET_ERESTARTSYS) {
-                    env->pc -= 4;
-                    break;
-                }
-                if (sysret == -TARGET_QEMU_ESIGRETURN) {
+                if (trapnr == TARGET_NR_sigreturn
+                    || trapnr == TARGET_NR_rt_sigreturn) {
                     break;
                 }
                 /* Syscall writes 0 to V0 to bypass error check, similar
@@ -3406,11 +3326,10 @@ void cpu_loop(CPUS390XState *env)
     int trapnr, n, sig;
     target_siginfo_t info;
     target_ulong addr;
-    abi_long ret;
 
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_s390x_exec(cs);
         cpu_exec_end(cs);
         switch (trapnr) {
         case EXCP_INTERRUPT:
@@ -3424,14 +3343,9 @@ void cpu_loop(CPUS390XState *env)
                 n = env->regs[1];
             }
             env->psw.addr += env->int_svc_ilen;
-            ret = do_syscall(env, n, env->regs[2], env->regs[3],
-                             env->regs[4], env->regs[5],
-                             env->regs[6], env->regs[7], 0, 0);
-            if (ret == -TARGET_ERESTARTSYS) {
-                env->psw.addr -= env->int_svc_ilen;
-            } else if (ret != -TARGET_QEMU_ESIGRETURN) {
-                env->regs[2] = ret;
-            }
+            env->regs[2] = do_syscall(env, n, env->regs[2], env->regs[3],
+                                      env->regs[4], env->regs[5],
+                                      env->regs[6], env->regs[7], 0, 0);
             break;
 
         case EXCP_DEBUG:
@@ -3719,24 +3633,19 @@ void cpu_loop(CPUTLGState *env)
 
     while (1) {
         cpu_exec_start(cs);
-        trapnr = cpu_exec(cs);
+        trapnr = cpu_tilegx_exec(cs);
         cpu_exec_end(cs);
         switch (trapnr) {
         case TILEGX_EXCP_SYSCALL:
-        {
-            abi_ulong ret = do_syscall(env, env->regs[TILEGX_R_NR],
-                                       env->regs[0], env->regs[1],
-                                       env->regs[2], env->regs[3],
-                                       env->regs[4], env->regs[5],
-                                       env->regs[6], env->regs[7]);
-            if (ret == -TARGET_ERESTARTSYS) {
-                env->pc -= 8;
-            } else if (ret != -TARGET_QEMU_ESIGRETURN) {
-                env->regs[TILEGX_R_RE] = ret;
-                env->regs[TILEGX_R_ERR] = TILEGX_IS_ERRNO(ret) ? -ret : 0;
-            }
+            env->regs[TILEGX_R_RE] = do_syscall(env, env->regs[TILEGX_R_NR],
+                                                env->regs[0], env->regs[1],
+                                                env->regs[2], env->regs[3],
+                                                env->regs[4], env->regs[5],
+                                                env->regs[6], env->regs[7]);
+            env->regs[TILEGX_R_ERR] = TILEGX_IS_ERRNO(env->regs[TILEGX_R_RE])
+                                                      ? - env->regs[TILEGX_R_RE]
+                                                      : 0;
             break;
-        }
         case TILEGX_EXCP_OPCODE_EXCH:
             do_exch(env, true, false);
             break;
@@ -3799,7 +3708,14 @@ void stop_all_tasks(void)
 /* Assumes contents are already zeroed.  */
 void init_task_state(TaskState *ts)
 {
+    int i;
     ts->used = 1;
+    ts->first_free = ts->sigqueue_table;
+    for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) {
+        ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1];
+    }
+    ts->sigqueue_table[i].next = NULL;
 }
 
 CPUArchState *cpu_copy(CPUArchState *env)
@@ -3844,13 +3760,12 @@ static void handle_arg_log(const char *arg)
         qemu_print_log_usage(stdout);
         exit(EXIT_FAILURE);
     }
-    qemu_log_needs_buffers();
     qemu_set_log(mask);
 }
 
 static void handle_arg_log_filename(const char *arg)
 {
-    qemu_set_log_filename(arg, &error_fatal);
+    qemu_set_log_filename(arg);
 }
 
 static void handle_arg_set_env(const char *arg)
@@ -4000,17 +3915,10 @@ static void handle_arg_strace(const char *arg)
 static void handle_arg_version(const char *arg)
 {
     printf("qemu-" TARGET_NAME " version " QEMU_VERSION QEMU_PKGVERSION
-           ", " QEMU_COPYRIGHT "\n");
+           ", Copyright (c) 2003-2008 Fabrice Bellard\n");
     exit(EXIT_SUCCESS);
 }
 
-static char *trace_file;
-static void handle_arg_trace(const char *arg)
-{
-    g_free(trace_file);
-    trace_file = trace_opt_parse(arg);
-}
-
 struct qemu_argument {
     const char *argv;
     const char *env;
@@ -4058,8 +3966,6 @@ static const struct qemu_argument arg_table[] = {
      "",           "log system calls"},
     {"seed",       "QEMU_RAND_SEED",   true,  handle_arg_randseed,
      "",           "Seed for pseudo-random number generator"},
-    {"trace",      "QEMU_TRACE",       true,  handle_arg_trace,
-     "",           "[[enable=]<pattern>][,events=<file>][,file=<file>]"},
     {"version",    "QEMU_VERSION",     false, handle_arg_version,
      "",           "display version information and exit"},
     {NULL, NULL, false, NULL, NULL, NULL}
@@ -4246,18 +4152,14 @@ int main(int argc, char **argv, char **envp)
     }
 
     cpu_model = NULL;
+#if defined(cpudef_setup)
+    cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
+#endif
 
     srand(time(NULL));
 
-    qemu_add_opts(&qemu_trace_opts);
-
     optind = parse_args(argc, argv);
 
-    if (!trace_init_backends()) {
-        exit(1);
-    }
-    trace_init_file(trace_file);
-
     /* Zero out regs */
     memset(regs, 0, sizeof(struct target_pt_regs));
 
@@ -4706,20 +4608,6 @@ int main(int argc, char **argv, char **envp)
         if (regs->cp0_epc & 1) {
             env->hflags |= MIPS_HFLAG_M16;
         }
-        if (((info->elf_flags & EF_MIPS_NAN2008) != 0) !=
-            ((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) {
-            if ((env->active_fpu.fcr31_rw_bitmask &
-                  (1 << FCR31_NAN2008)) == 0) {
-                fprintf(stderr, "ELF binary's NaN mode not supported by CPU\n");
-                exit(1);
-            }
-            if ((info->elf_flags & EF_MIPS_NAN2008) != 0) {
-                env->active_fpu.fcr31 |= (1 << FCR31_NAN2008);
-            } else {
-                env->active_fpu.fcr31 &= ~(1 << FCR31_NAN2008);
-            }
-            restore_snan_bit_mode(env);
-        }
     }
 #elif defined(TARGET_OPENRISC)
     {
@@ -4810,7 +4698,6 @@ int main(int argc, char **argv, char **envp)
         }
         gdb_handlesig(cpu, 0);
     }
-    trace_init_vcpu_events();
     cpu_loop(env);
     /* never exits */
     return 0;
index 7dd979f..c6386ea 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef MICROBLAZE_TARGET_CPU_H
-#define MICROBLAZE_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUMBState *env, target_ulong newsp)
 {
index de2b0f4..3d1f7a7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef MICROBLAZE_TARGET_SIGNAL_H
-#define MICROBLAZE_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -26,5 +26,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUMBState *state)
     return state->regs[14];
 }
 
-
-#endif /* MICROBLAZE_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index 70dbdb6..325e2f6 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef MICROBLAZE_TARGET_STRUCTS_H
-#define MICROBLAZE_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index 0b6980c..3c1ed27 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef MICROBLAZE_TARGET_SYSCALL_H
-#define MICROBLAZE_TARGET_SYSCALL_H
+#ifndef MICROBLAZE_SYSCALLS_H
+#define MICROBLAZE_SYSCALLS_H 1
 
 #define UNAME_MACHINE "microblaze"
 #define UNAME_MINIMUM_RELEASE "2.6.32"
index 2002920..19b8855 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef MIPS_TARGET_CPU_H
-#define MIPS_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUMIPSState *env, target_ulong newsp)
 {
index 8dd27ce..6e1dc8b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef MIPS_TARGET_SIGNAL_H
-#define MIPS_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -26,5 +26,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state)
     return state->active_tc.gpr[29];
 }
 
-
-#endif /* MIPS_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index fbd9955..16021e8 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef MIPS_TARGET_STRUCTS_H
-#define MIPS_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index 2b4f390..68db160 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef MIPS_TARGET_SYSCALL_H
-#define MIPS_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 /* this struct defines the way the registers are stored on the
    stack during a system call. */
@@ -222,6 +222,10 @@ struct target_pt_regs {
 #define TARGET_ENOTRECOVERABLE 166     /* State not recoverable */
 
 
+
+/* Nasty hack: define a fake errno value for use by sigreturn.  */
+#define TARGET_QEMU_ESIGRETURN 255
+
 #define UNAME_MACHINE "mips"
 #define UNAME_MINIMUM_RELEASE "2.6.32"
 
@@ -230,4 +234,4 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
-#endif /* MIPS_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index 67ef5a1..5fb6a2c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef MIPS64_TARGET_SIGNAL_H
-#define MIPS64_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -26,5 +26,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state)
     return state->active_tc.gpr[29];
 }
 
-
-#endif /* MIPS64_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index 8da9c1f..0e0c2d2 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef MIPS64_TARGET_SYSCALL_H
-#define MIPS64_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 /* this struct defines the way the registers are stored on the
    stack during a system call. */
@@ -219,6 +219,10 @@ struct target_pt_regs {
 #define TARGET_ENOTRECOVERABLE 166     /* State not recoverable */
 
 
+
+/* Nasty hack: define a fake errno value for use by sigreturn. */
+#define TARGET_QEMU_ESIGRETURN 255
+
 #define UNAME_MACHINE "mips64"
 #define UNAME_MINIMUM_RELEASE "2.6.32"
 
@@ -227,4 +231,4 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
-#endif /* MIPS64_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index c4371d9..3519147 100644 (file)
@@ -17,6 +17,7 @@
  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "qemu/osdep.h"
+#include <sys/mman.h>
 #include <linux/mman.h>
 #include <linux/unistd.h>
 
index a21ed1a..32a46ac 100644 (file)
@@ -17,8 +17,8 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef OPENRISC_TARGET_CPU_H
-#define OPENRISC_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp)
 {
index 9f2c493..964aed6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef OPENRISC_TARGET_SIGNAL_H
-#define OPENRISC_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -23,5 +23,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUOpenRISCState *state)
     return state->gpr[1];
 }
 
-
-#endif /* OPENRISC_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index afbb7ad..f4d560f 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef OPENRISC_TARGET_STRUCTS_H
-#define OPENRISC_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index 9d3380f..19aeffc 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef OPENRISC_TARGET_SYSCALL_H
-#define OPENRISC_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 struct target_pt_regs {
     union {
@@ -31,4 +31,4 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
-#endif /* OPENRISC_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index 3aab3d1..26f4ba2 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef PPC_TARGET_CPU_H
-#define PPC_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
 {
index 865c52f..a93b5cf 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef PPC_TARGET_SIGNAL_H
-#define PPC_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -26,5 +26,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUPPCState *state)
     return state->gpr[1];
 }
 
-
-#endif /* PPC_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index 6b1f579..2b87613 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef PPC_TARGET_STRUCTS_H
-#define PPC_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index a8662f4..35cab59 100644 (file)
@@ -17,8 +17,8 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef PPC_TARGET_SYSCALL_H
-#define PPC_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 /* XXX: ABSOLUTELY BUGGY:
  * for now, this is quite just a cut-and-paste from i386 target...
@@ -53,6 +53,8 @@ struct target_revectored_struct {
        abi_ulong __map[8];                     /* 256 bits */
 };
 
+/* Nasty hack: define a fake errno value for use by sigreturn.  */
+#define TARGET_QEMU_ESIGRETURN 255
 
 /*
  * flags masks
@@ -75,4 +77,4 @@ struct target_revectored_struct {
 #define TARGET_MLOCKALL_MCL_CURRENT 0x2000
 #define TARGET_MLOCKALL_MCL_FUTURE  0x4000
 
-#endif /* PPC_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index bef465d..26b0ba2 100644 (file)
@@ -1,9 +1,8 @@
 #ifndef QEMU_H
 #define QEMU_H
 
-#include "hostdep.h"
+
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 #undef DEBUG_REMAP
 
 #define THREAD __thread
 
-/* This is the size of the host kernel's sigset_t, needed where we make
- * direct system calls that take a sigset_t pointer and a size.
- */
-#define SIGSET_T_SIZE (_NSIG / 8)
-
 /* This struct is used to hold certain information about the image.
  * Basically, it replicates in user space what would be certain
  * task_struct fields in the kernel
@@ -83,9 +77,16 @@ struct vm86_saved_state {
 
 #define MAX_SIGQUEUE_SIZE 1024
 
+struct sigqueue {
+    struct sigqueue *next;
+    target_siginfo_t info;
+};
+
 struct emulated_sigtable {
     int pending; /* true if signal is pending */
-    target_siginfo_t info;
+    struct sigqueue *first;
+    struct sigqueue info; /* in order to always have memory for the
+                             first signal, we put it here */
 };
 
 /* NOTE: we force a big alignment so that the stack stored after is
@@ -116,37 +117,19 @@ typedef struct TaskState {
 #endif
 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
     /* Extra fields for semihosted binaries.  */
-    abi_ulong heap_base;
-    abi_ulong heap_limit;
+    uint32_t heap_base;
+    uint32_t heap_limit;
 #endif
-    abi_ulong stack_base;
+    uint32_t stack_base;
     int used; /* non zero if used */
+    bool sigsegv_blocked; /* SIGSEGV blocked by guest */
     struct image_info *info;
     struct linux_binprm *bprm;
 
-    struct emulated_sigtable sync_signal;
     struct emulated_sigtable sigtab[TARGET_NSIG];
-    /* This thread's signal mask, as requested by the guest program.
-     * The actual signal mask of this thread may differ:
-     *  + we don't let SIGSEGV and SIGBUS be blocked while running guest code
-     *  + sometimes we block all signals to avoid races
-     */
-    sigset_t signal_mask;
-    /* The signal mask imposed by a guest sigsuspend syscall, if we are
-     * currently in the middle of such a syscall
-     */
-    sigset_t sigsuspend_mask;
-    /* Nonzero if we're leaving a sigsuspend and sigsuspend_mask is valid. */
-    int in_sigsuspend;
-
-    /* Nonzero if process_pending_signals() needs to do something (either
-     * handle a pending signal or unblock signals).
-     * This flag is written from a signal handler so should be accessed via
-     * the atomic_read() and atomic_write() functions. (It is not accessed
-     * from multiple threads.)
-     */
-    int signal_pending;
-
+    struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
+    struct sigqueue *first_free; /* first free siginfo queue entry */
+    int signal_pending; /* non zero if a signal may be pending */
 } __attribute__((aligned(16))) TaskState;
 
 extern char *exec_path;
@@ -200,7 +183,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
 extern THREAD CPUState *thread_cpu;
 void cpu_loop(CPUArchState *env);
-const char *target_strerror(int err);
+char *target_strerror(int err);
 int get_osversion(void);
 void init_qemu_uname_release(void);
 void fork_start(void);
@@ -221,139 +204,6 @@ unsigned long init_guest_space(unsigned long host_start,
 
 #include "qemu/log.h"
 
-/* safe_syscall.S */
-
-/**
- * safe_syscall:
- * @int number: number of system call to make
- * ...: arguments to the system call
- *
- * Call a system call if guest signal not pending.
- * This has the same API as the libc syscall() function, except that it
- * may return -1 with errno == TARGET_ERESTARTSYS if a signal was pending.
- *
- * Returns: the system call result, or -1 with an error code in errno
- * (Errnos are host errnos; we rely on TARGET_ERESTARTSYS not clashing
- * with any of the host errno values.)
- */
-
-/* A guide to using safe_syscall() to handle interactions between guest
- * syscalls and guest signals:
- *
- * Guest syscalls come in two flavours:
- *
- * (1) Non-interruptible syscalls
- *
- * These are guest syscalls that never get interrupted by signals and
- * so never return EINTR. They can be implemented straightforwardly in
- * QEMU: just make sure that if the implementation code has to make any
- * blocking calls that those calls are retried if they return EINTR.
- * It's also OK to implement these with safe_syscall, though it will be
- * a little less efficient if a signal is delivered at the 'wrong' moment.
- *
- * Some non-interruptible syscalls need to be handled using block_signals()
- * to block signals for the duration of the syscall. This mainly applies
- * to code which needs to modify the data structures used by the
- * host_signal_handler() function and the functions it calls, including
- * all syscalls which change the thread's signal mask.
- *
- * (2) Interruptible syscalls
- *
- * These are guest syscalls that can be interrupted by signals and
- * for which we need to either return EINTR or arrange for the guest
- * syscall to be restarted. This category includes both syscalls which
- * always restart (and in the kernel return -ERESTARTNOINTR), ones
- * which only restart if there is no handler (kernel returns -ERESTARTNOHAND
- * or -ERESTART_RESTARTBLOCK), and the most common kind which restart
- * if the handler was registered with SA_RESTART (kernel returns
- * -ERESTARTSYS). System calls which are only interruptible in some
- * situations (like 'open') also need to be handled this way.
- *
- * Here it is important that the host syscall is made
- * via this safe_syscall() function, and *not* via the host libc.
- * If the host libc is used then the implementation will appear to work
- * most of the time, but there will be a race condition where a
- * signal could arrive just before we make the host syscall inside libc,
- * and then then guest syscall will not correctly be interrupted.
- * Instead the implementation of the guest syscall can use the safe_syscall
- * function but otherwise just return the result or errno in the usual
- * way; the main loop code will take care of restarting the syscall
- * if appropriate.
- *
- * (If the implementation needs to make multiple host syscalls this is
- * OK; any which might really block must be via safe_syscall(); for those
- * which are only technically blocking (ie which we know in practice won't
- * stay in the host kernel indefinitely) it's OK to use libc if necessary.
- * You must be able to cope with backing out correctly if some safe_syscall
- * you make in the implementation returns either -TARGET_ERESTARTSYS or
- * EINTR though.)
- *
- * block_signals() cannot be used for interruptible syscalls.
- *
- *
- * How and why the safe_syscall implementation works:
- *
- * The basic setup is that we make the host syscall via a known
- * section of host native assembly. If a signal occurs, our signal
- * handler checks the interrupted host PC against the addresse of that
- * known section. If the PC is before or at the address of the syscall
- * instruction then we change the PC to point at a "return
- * -TARGET_ERESTARTSYS" code path instead, and then exit the signal handler
- * (causing the safe_syscall() call to immediately return that value).
- * Then in the main.c loop if we see this magic return value we adjust
- * the guest PC to wind it back to before the system call, and invoke
- * the guest signal handler as usual.
- *
- * This winding-back will happen in two cases:
- * (1) signal came in just before we took the host syscall (a race);
- *   in this case we'll take the guest signal and have another go
- *   at the syscall afterwards, and this is indistinguishable for the
- *   guest from the timing having been different such that the guest
- *   signal really did win the race
- * (2) signal came in while the host syscall was blocking, and the
- *   host kernel decided the syscall should be restarted;
- *   in this case we want to restart the guest syscall also, and so
- *   rewinding is the right thing. (Note that "restart" semantics mean
- *   "first call the signal handler, then reattempt the syscall".)
- * The other situation to consider is when a signal came in while the
- * host syscall was blocking, and the host kernel decided that the syscall
- * should not be restarted; in this case QEMU's host signal handler will
- * be invoked with the PC pointing just after the syscall instruction,
- * with registers indicating an EINTR return; the special code in the
- * handler will not kick in, and we will return EINTR to the guest as
- * we should.
- *
- * Notice that we can leave the host kernel to make the decision for
- * us about whether to do a restart of the syscall or not; we do not
- * need to check SA_RESTART flags in QEMU or distinguish the various
- * kinds of restartability.
- */
-#ifdef HAVE_SAFE_SYSCALL
-/* The core part of this function is implemented in assembly */
-extern long safe_syscall_base(int *pending, long number, ...);
-
-#define safe_syscall(...)                                               \
-    ({                                                                  \
-        long ret_;                                                      \
-        int *psp_ = &((TaskState *)thread_cpu->opaque)->signal_pending; \
-        ret_ = safe_syscall_base(psp_, __VA_ARGS__);                    \
-        if (is_error(ret_)) {                                           \
-            errno = -ret_;                                              \
-            ret_ = -1;                                                  \
-        }                                                               \
-        ret_;                                                           \
-    })
-
-#else
-
-/* Fallback for architectures which don't yet provide a safe-syscall assembly
- * fragment; note that this is racy!
- * This should go away when all host architectures have been updated.
- */
-#define safe_syscall syscall
-
-#endif
-
 /* syscall.c */
 int host_to_target_waitstatus(int status);
 
@@ -376,25 +226,6 @@ long do_sigreturn(CPUArchState *env);
 long do_rt_sigreturn(CPUArchState *env);
 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
 int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
-/**
- * block_signals: block all signals while handling this guest syscall
- *
- * Block all signals, and arrange that the signal mask is returned to
- * its correct value for the guest before we resume execution of guest code.
- * If this function returns non-zero, then the caller should immediately
- * return -TARGET_ERESTARTSYS to the main loop, which will take the pending
- * signal and restart execution of the syscall.
- * If block_signals() returns zero, then the caller can continue with
- * emulation of the system call knowing that no signals can be taken
- * (and therefore that no race conditions will result).
- * This should only be called once, because if it is called a second time
- * it will always return non-zero. (Think of it like a mutex that can't
- * be recursively locked.)
- * Signals will be unblocked again by process_pending_signals().
- *
- * Return value: non-zero if there was a pending signal, zero if not.
- */
-int block_signals(void); /* Returns non zero if signal pending */
 
 #ifdef TARGET_I386
 /* vm86.c */
@@ -419,6 +250,8 @@ int target_msync(abi_ulong start, abi_ulong len, int flags);
 extern unsigned long last_brk;
 extern abi_ulong mmap_next_start;
 abi_ulong mmap_find_vma(abi_ulong, abi_ulong);
+void cpu_list_lock(void);
+void cpu_list_unlock(void);
 void mmap_fork_start(void);
 void mmap_fork_end(int child);
 
index 87ea4d2..f10abe8 100644 (file)
@@ -19,8 +19,8 @@
  * You should have received a copy of the GNU (Lesser) General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef S390X_TARGET_CPU_H
-#define S390X_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUS390XState *env, target_ulong newsp)
 {
index 6f7b6ab..b4816b0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef S390X_TARGET_SIGNAL_H
-#define S390X_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -23,5 +23,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUS390XState *state)
    return state->regs[15];
 }
 
-
-#endif /* S390X_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index cadff6d..6b6f5b5 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef S390X_TARGET_STRUCTS_H
-#define S390X_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 
 struct target_ipc_perm {
index 8d4f609..02061ef 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef S390X_TARGET_SYSCALL_H
-#define S390X_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 /* this typedef defines how a Program Status Word looks like */
 typedef struct {
@@ -31,4 +31,4 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
-#endif /* S390X_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
diff --git a/linux-user/safe-syscall.S b/linux-user/safe-syscall.S
deleted file mode 100644 (file)
index b5df625..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * safe-syscall.S : include the host-specific assembly fragment
- * to handle signals occurring at the same time as system calls.
- *
- * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "hostdep.h"
-#include "errno_defs.h"
-
-/* We have the correct host directory on our include path
- * so that this will pull in the right fragment for the architecture.
- */
-#ifdef HAVE_SAFE_SYSCALL
-#include "safe-syscall.inc.S"
-#endif
-
-/* We must specifically say that we're happy for the stack to not be
- * executable, otherwise the toolchain will default to assuming our
- * assembly needs an executable stack and the whole QEMU binary will
- * needlessly end up with one. This should be the last thing in this file.
- */
-#if defined(__linux__) && defined(__ELF__)
-.section        .note.GNU-stack, "", %progbits
-#endif
index 9d305d2..141856f 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef SH4_TARGET_CPU_H
-#define SH4_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUSH4State *env, target_ulong newsp)
 {
index cbf23b6..e148da0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef SH4_TARGET_SIGNAL_H
-#define SH4_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -26,5 +26,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUSH4State *state)
     return state->gregs[15];
 }
 
-
-#endif /* SH4_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index 3e832bf..32b235e 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef SH4_TARGET_STRUCTS_H
-#define SH4_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index 78d5557..9f3381b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef SH4_TARGET_SYSCALL_H
-#define SH4_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 struct target_pt_regs {
         unsigned long regs[16];
@@ -19,4 +19,4 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
-#endif /* SH4_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index 9a4d894..96e86c0 100644 (file)
@@ -17,7 +17,6 @@
  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "qemu/osdep.h"
-#include "qemu/bitops.h"
 #include <sys/ucontext.h>
 #include <sys/resource.h>
 
@@ -158,7 +157,7 @@ static void target_to_host_sigset_internal(sigset_t *d,
         if (target_sigismember(s, i)) {
             sigaddset(d, target_to_host_signal(i));
         }
-    }
+     }
 }
 
 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
@@ -191,80 +190,54 @@ void target_to_host_old_sigset(sigset_t *sigset,
     target_to_host_sigset(sigset, &d);
 }
 
-int block_signals(void)
-{
-    TaskState *ts = (TaskState *)thread_cpu->opaque;
-    sigset_t set;
-
-    /* It's OK to block everything including SIGSEGV, because we won't
-     * run any further guest code before unblocking signals in
-     * process_pending_signals().
-     */
-    sigfillset(&set);
-    sigprocmask(SIG_SETMASK, &set, 0);
-
-    return atomic_xchg(&ts->signal_pending, 1);
-}
-
 /* Wrapper for sigprocmask function
  * Emulates a sigprocmask in a safe way for the guest. Note that set and oldset
- * are host signal set, not guest ones. Returns -TARGET_ERESTARTSYS if
- * a signal was already pending and the syscall must be restarted, or
- * 0 on success.
- * If set is NULL, this is guaranteed not to fail.
+ * are host signal set, not guest ones. This wraps the sigprocmask host calls
+ * that should be protected (calls originated from guest)
  */
 int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
 {
-    TaskState *ts = (TaskState *)thread_cpu->opaque;
-
-    if (oldset) {
-        *oldset = ts->signal_mask;
-    }
+    int ret;
+    sigset_t val;
+    sigset_t *temp = NULL;
+    CPUState *cpu = thread_cpu;
+    TaskState *ts = (TaskState *)cpu->opaque;
+    bool segv_was_blocked = ts->sigsegv_blocked;
 
     if (set) {
-        int i;
+        bool has_sigsegv = sigismember(set, SIGSEGV);
+        val = *set;
+        temp = &val;
 
-        if (block_signals()) {
-            return -TARGET_ERESTARTSYS;
-        }
+        sigdelset(temp, SIGSEGV);
 
         switch (how) {
         case SIG_BLOCK:
-            sigorset(&ts->signal_mask, &ts->signal_mask, set);
+            if (has_sigsegv) {
+                ts->sigsegv_blocked = true;
+            }
             break;
         case SIG_UNBLOCK:
-            for (i = 1; i <= NSIG; ++i) {
-                if (sigismember(set, i)) {
-                    sigdelset(&ts->signal_mask, i);
-                }
+            if (has_sigsegv) {
+                ts->sigsegv_blocked = false;
             }
             break;
         case SIG_SETMASK:
-            ts->signal_mask = *set;
+            ts->sigsegv_blocked = has_sigsegv;
             break;
         default:
             g_assert_not_reached();
         }
-
-        /* Silently ignore attempts to change blocking status of KILL or STOP */
-        sigdelset(&ts->signal_mask, SIGKILL);
-        sigdelset(&ts->signal_mask, SIGSTOP);
     }
-    return 0;
-}
 
-#if !defined(TARGET_OPENRISC) && !defined(TARGET_UNICORE32) && \
-    !defined(TARGET_X86_64)
-/* Just set the guest's signal mask to the specified value; the
- * caller is assumed to have called block_signals() already.
- */
-static void set_sigmask(const sigset_t *set)
-{
-    TaskState *ts = (TaskState *)thread_cpu->opaque;
+    ret = sigprocmask(how, temp, oldset);
 
-    ts->signal_mask = *set;
+    if (oldset && segv_was_blocked) {
+        sigaddset(oldset, SIGSEGV);
+    }
+
+    return ret;
 }
-#endif
 
 /* siginfo conversion */
 
@@ -272,160 +245,87 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
                                                  const siginfo_t *info)
 {
     int sig = host_to_target_signal(info->si_signo);
-    int si_code = info->si_code;
-    int si_type;
     tinfo->si_signo = sig;
     tinfo->si_errno = 0;
     tinfo->si_code = info->si_code;
 
-    /* This memset serves two purposes:
-     * (1) ensure we don't leak random junk to the guest later
-     * (2) placate false positives from gcc about fields
-     *     being used uninitialized if it chooses to inline both this
-     *     function and tswap_siginfo() into host_to_target_siginfo().
-     */
-    memset(tinfo->_sifields._pad, 0, sizeof(tinfo->_sifields._pad));
-
-    /* This is awkward, because we have to use a combination of
-     * the si_code and si_signo to figure out which of the union's
-     * members are valid. (Within the host kernel it is always possible
-     * to tell, but the kernel carefully avoids giving userspace the
-     * high 16 bits of si_code, so we don't have the information to
-     * do this the easy way...) We therefore make our best guess,
-     * bearing in mind that a guest can spoof most of the si_codes
-     * via rt_sigqueueinfo() if it likes.
-     *
-     * Once we have made our guess, we record it in the top 16 bits of
-     * the si_code, so that tswap_siginfo() later can use it.
-     * tswap_siginfo() will strip these top bits out before writing
-     * si_code to the guest (sign-extending the lower bits).
-     */
-
-    switch (si_code) {
-    case SI_USER:
-    case SI_TKILL:
-    case SI_KERNEL:
-        /* Sent via kill(), tkill() or tgkill(), or direct from the kernel.
-         * These are the only unspoofable si_code values.
-         */
-        tinfo->_sifields._kill._pid = info->si_pid;
-        tinfo->_sifields._kill._uid = info->si_uid;
-        si_type = QEMU_SI_KILL;
-        break;
-    default:
-        /* Everything else is spoofable. Make best guess based on signal */
-        switch (sig) {
-        case TARGET_SIGCHLD:
-            tinfo->_sifields._sigchld._pid = info->si_pid;
-            tinfo->_sifields._sigchld._uid = info->si_uid;
-            tinfo->_sifields._sigchld._status
-                = host_to_target_waitstatus(info->si_status);
-            tinfo->_sifields._sigchld._utime = info->si_utime;
-            tinfo->_sifields._sigchld._stime = info->si_stime;
-            si_type = QEMU_SI_CHLD;
-            break;
-        case TARGET_SIGIO:
-            tinfo->_sifields._sigpoll._band = info->si_band;
-            tinfo->_sifields._sigpoll._fd = info->si_fd;
-            si_type = QEMU_SI_POLL;
-            break;
-        default:
-            /* Assume a sigqueue()/mq_notify()/rt_sigqueueinfo() source. */
-            tinfo->_sifields._rt._pid = info->si_pid;
-            tinfo->_sifields._rt._uid = info->si_uid;
-            /* XXX: potential problem if 64 bit */
-            tinfo->_sifields._rt._sigval.sival_ptr
-                = (abi_ulong)(unsigned long)info->si_value.sival_ptr;
-            si_type = QEMU_SI_RT;
-            break;
-        }
-        break;
+    if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
+        || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {
+        /* Should never come here, but who knows. The information for
+           the target is irrelevant.  */
+        tinfo->_sifields._sigfault._addr = 0;
+    } else if (sig == TARGET_SIGIO) {
+        tinfo->_sifields._sigpoll._band = info->si_band;
+       tinfo->_sifields._sigpoll._fd = info->si_fd;
+    } else if (sig == TARGET_SIGCHLD) {
+        tinfo->_sifields._sigchld._pid = info->si_pid;
+        tinfo->_sifields._sigchld._uid = info->si_uid;
+        tinfo->_sifields._sigchld._status
+            = host_to_target_waitstatus(info->si_status);
+        tinfo->_sifields._sigchld._utime = info->si_utime;
+        tinfo->_sifields._sigchld._stime = info->si_stime;
+    } else if (sig >= TARGET_SIGRTMIN) {
+        tinfo->_sifields._rt._pid = info->si_pid;
+        tinfo->_sifields._rt._uid = info->si_uid;
+        /* XXX: potential problem if 64 bit */
+        tinfo->_sifields._rt._sigval.sival_ptr
+            = (abi_ulong)(unsigned long)info->si_value.sival_ptr;
     }
-
-    tinfo->si_code = deposit32(si_code, 16, 16, si_type);
 }
 
 static void tswap_siginfo(target_siginfo_t *tinfo,
                           const target_siginfo_t *info)
 {
-    int si_type = extract32(info->si_code, 16, 16);
-    int si_code = sextract32(info->si_code, 0, 16);
-
-    __put_user(info->si_signo, &tinfo->si_signo);
-    __put_user(info->si_errno, &tinfo->si_errno);
-    __put_user(si_code, &tinfo->si_code);
-
-    /* We can use our internal marker of which fields in the structure
-     * are valid, rather than duplicating the guesswork of
-     * host_to_target_siginfo_noswap() here.
-     */
-    switch (si_type) {
-    case QEMU_SI_KILL:
-        __put_user(info->_sifields._kill._pid, &tinfo->_sifields._kill._pid);
-        __put_user(info->_sifields._kill._uid, &tinfo->_sifields._kill._uid);
-        break;
-    case QEMU_SI_TIMER:
-        __put_user(info->_sifields._timer._timer1,
-                   &tinfo->_sifields._timer._timer1);
-        __put_user(info->_sifields._timer._timer2,
-                   &tinfo->_sifields._timer._timer2);
-        break;
-    case QEMU_SI_POLL:
-        __put_user(info->_sifields._sigpoll._band,
-                   &tinfo->_sifields._sigpoll._band);
-        __put_user(info->_sifields._sigpoll._fd,
-                   &tinfo->_sifields._sigpoll._fd);
-        break;
-    case QEMU_SI_FAULT:
-        __put_user(info->_sifields._sigfault._addr,
-                   &tinfo->_sifields._sigfault._addr);
-        break;
-    case QEMU_SI_CHLD:
-        __put_user(info->_sifields._sigchld._pid,
-                   &tinfo->_sifields._sigchld._pid);
-        __put_user(info->_sifields._sigchld._uid,
-                   &tinfo->_sifields._sigchld._uid);
-        __put_user(info->_sifields._sigchld._status,
-                   &tinfo->_sifields._sigchld._status);
-        __put_user(info->_sifields._sigchld._utime,
-                   &tinfo->_sifields._sigchld._utime);
-        __put_user(info->_sifields._sigchld._stime,
-                   &tinfo->_sifields._sigchld._stime);
-        break;
-    case QEMU_SI_RT:
-        __put_user(info->_sifields._rt._pid, &tinfo->_sifields._rt._pid);
-        __put_user(info->_sifields._rt._uid, &tinfo->_sifields._rt._uid);
-        __put_user(info->_sifields._rt._sigval.sival_ptr,
-                   &tinfo->_sifields._rt._sigval.sival_ptr);
-        break;
-    default:
-        g_assert_not_reached();
+    int sig = info->si_signo;
+    tinfo->si_signo = tswap32(sig);
+    tinfo->si_errno = tswap32(info->si_errno);
+    tinfo->si_code = tswap32(info->si_code);
+
+    if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
+        || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {
+        tinfo->_sifields._sigfault._addr
+            = tswapal(info->_sifields._sigfault._addr);
+    } else if (sig == TARGET_SIGIO) {
+        tinfo->_sifields._sigpoll._band
+            = tswap32(info->_sifields._sigpoll._band);
+        tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
+    } else if (sig == TARGET_SIGCHLD) {
+        tinfo->_sifields._sigchld._pid
+            = tswap32(info->_sifields._sigchld._pid);
+        tinfo->_sifields._sigchld._uid
+            = tswap32(info->_sifields._sigchld._uid);
+        tinfo->_sifields._sigchld._status
+            = tswap32(info->_sifields._sigchld._status);
+        tinfo->_sifields._sigchld._utime
+            = tswapal(info->_sifields._sigchld._utime);
+        tinfo->_sifields._sigchld._stime
+            = tswapal(info->_sifields._sigchld._stime);
+    } else if (sig >= TARGET_SIGRTMIN) {
+        tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
+        tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
+        tinfo->_sifields._rt._sigval.sival_ptr
+            = tswapal(info->_sifields._rt._sigval.sival_ptr);
     }
 }
 
+
 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
 {
-    target_siginfo_t tgt_tmp;
-    host_to_target_siginfo_noswap(&tgt_tmp, info);
-    tswap_siginfo(tinfo, &tgt_tmp);
+    host_to_target_siginfo_noswap(tinfo, info);
+    tswap_siginfo(tinfo, tinfo);
 }
 
 /* XXX: we support only POSIX RT signals are used. */
 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
 {
-    /* This conversion is used only for the rt_sigqueueinfo syscall,
-     * and so we know that the _rt fields are the valid ones.
-     */
-    abi_ulong sival_ptr;
-
-    __get_user(info->si_signo, &tinfo->si_signo);
-    __get_user(info->si_errno, &tinfo->si_errno);
-    __get_user(info->si_code, &tinfo->si_code);
-    __get_user(info->si_pid, &tinfo->_sifields._rt._pid);
-    __get_user(info->si_uid, &tinfo->_sifields._rt._uid);
-    __get_user(sival_ptr, &tinfo->_sifields._rt._sigval.sival_ptr);
-    info->si_value.sival_ptr = (void *)(long)sival_ptr;
+    info->si_signo = tswap32(tinfo->si_signo);
+    info->si_errno = tswap32(tinfo->si_errno);
+    info->si_code = tswap32(tinfo->si_code);
+    info->si_pid = tswap32(tinfo->_sifields._rt._pid);
+    info->si_uid = tswap32(tinfo->_sifields._rt._uid);
+    info->si_value.sival_ptr =
+            (void *)(long)tswapal(tinfo->_sifields._rt._sigval.sival_ptr);
 }
 
 static int fatal_signal (int sig)
@@ -467,7 +367,6 @@ static int core_dump_signal(int sig)
 
 void signal_init(void)
 {
-    TaskState *ts = (TaskState *)thread_cpu->opaque;
     struct sigaction act;
     struct sigaction oact;
     int i, j;
@@ -483,9 +382,6 @@ void signal_init(void)
         target_to_host_signal_table[j] = i;
     }
 
-    /* Set the signal mask from the host mask. */
-    sigprocmask(0, 0, &ts->signal_mask);
-
     /* set all host signal handlers. ALL signals are blocked during
        the handlers to serialize them. */
     memset(sigact_table, 0, sizeof(sigact_table));
@@ -512,6 +408,27 @@ void signal_init(void)
     }
 }
 
+/* signal queue handling */
+
+static inline struct sigqueue *alloc_sigqueue(CPUArchState *env)
+{
+    CPUState *cpu = ENV_GET_CPU(env);
+    TaskState *ts = cpu->opaque;
+    struct sigqueue *q = ts->first_free;
+    if (!q)
+        return NULL;
+    ts->first_free = q->next;
+    return q;
+}
+
+static inline void free_sigqueue(CPUArchState *env, struct sigqueue *q)
+{
+    CPUState *cpu = ENV_GET_CPU(env);
+    TaskState *ts = cpu->opaque;
+
+    q->next = ts->first_free;
+    ts->first_free = q;
+}
 
 /* abort execution with signal */
 static void QEMU_NORETURN force_sig(int target_sig)
@@ -573,41 +490,83 @@ int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
 {
     CPUState *cpu = ENV_GET_CPU(env);
     TaskState *ts = cpu->opaque;
+    struct emulated_sigtable *k;
+    struct sigqueue *q, **pq;
+    abi_ulong handler;
+    int queue;
 
     trace_user_queue_signal(env, sig);
+    k = &ts->sigtab[sig - 1];
+    queue = gdb_queuesig ();
+    handler = sigact_table[sig - 1]._sa_handler;
+
+    if (ts->sigsegv_blocked && sig == TARGET_SIGSEGV) {
+        /* Guest has blocked SIGSEGV but we got one anyway. Assume this
+         * is a forced SIGSEGV (ie one the kernel handles via force_sig_info
+         * because it got a real MMU fault). A blocked SIGSEGV in that
+         * situation is treated as if using the default handler. This is
+         * not correct if some other process has randomly sent us a SIGSEGV
+         * via kill(), but that is not easy to distinguish at this point,
+         * so we assume it doesn't happen.
+         */
+        handler = TARGET_SIG_DFL;
+    }
 
-    /* Currently all callers define siginfo structures which
-     * use the _sifields._sigfault union member, so we can
-     * set the type here. If that changes we should push this
-     * out so the si_type is passed in by callers.
-     */
-    info->si_code = deposit32(info->si_code, 16, 16, QEMU_SI_FAULT);
-
-    ts->sync_signal.info = *info;
-    ts->sync_signal.pending = sig;
-    /* signal that a new signal is pending */
-    atomic_set(&ts->signal_pending, 1);
-    return 1; /* indicates that the signal was queued */
-}
-
-#ifndef HAVE_SAFE_SYSCALL
-static inline void rewind_if_in_safe_syscall(void *puc)
-{
-    /* Default version: never rewind */
+    if (!queue && handler == TARGET_SIG_DFL) {
+        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
+            kill(getpid(),SIGSTOP);
+            return 0;
+        } else
+        /* default handler : ignore some signal. The other are fatal */
+        if (sig != TARGET_SIGCHLD &&
+            sig != TARGET_SIGURG &&
+            sig != TARGET_SIGWINCH &&
+            sig != TARGET_SIGCONT) {
+            force_sig(sig);
+        } else {
+            return 0; /* indicate ignored */
+        }
+    } else if (!queue && handler == TARGET_SIG_IGN) {
+        /* ignore signal */
+        return 0;
+    } else if (!queue && handler == TARGET_SIG_ERR) {
+        force_sig(sig);
+    } else {
+        pq = &k->first;
+        if (sig < TARGET_SIGRTMIN) {
+            /* if non real time signal, we queue exactly one signal */
+            if (!k->pending)
+                q = &k->info;
+            else
+                return 0;
+        } else {
+            if (!k->pending) {
+                /* first signal */
+                q = &k->info;
+            } else {
+                q = alloc_sigqueue(env);
+                if (!q)
+                    return -EAGAIN;
+                while (*pq != NULL)
+                    pq = &(*pq)->next;
+            }
+        }
+        *pq = q;
+        q->info = *info;
+        q->next = NULL;
+        k->pending = 1;
+        /* signal that a new signal is pending */
+        ts->signal_pending = 1;
+        return 1; /* indicates that the signal was queued */
+    }
 }
-#endif
 
 static void host_signal_handler(int host_signum, siginfo_t *info,
                                 void *puc)
 {
     CPUArchState *env = thread_cpu->env_ptr;
-    CPUState *cpu = ENV_GET_CPU(env);
-    TaskState *ts = cpu->opaque;
-
     int sig;
     target_siginfo_t tinfo;
-    ucontext_t *uc = puc;
-    struct emulated_sigtable *k;
 
     /* the CPU emulator uses some host signals to detect exceptions,
        we forward to it some signals */
@@ -622,35 +581,11 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
     if (sig < 1 || sig > TARGET_NSIG)
         return;
     trace_user_host_signal(env, host_signum, sig);
-
-    rewind_if_in_safe_syscall(puc);
-
     host_to_target_siginfo_noswap(&tinfo, info);
-    k = &ts->sigtab[sig - 1];
-    k->info = tinfo;
-    k->pending = sig;
-    ts->signal_pending = 1;
-
-    /* Block host signals until target signal handler entered. We
-     * can't block SIGSEGV or SIGBUS while we're executing guest
-     * code in case the guest code provokes one in the window between
-     * now and it getting out to the main loop. Signals will be
-     * unblocked again in process_pending_signals().
-     *
-     * WARNING: we cannot use sigfillset() here because the uc_sigmask
-     * field is a kernel sigset_t, which is much smaller than the
-     * libc sigset_t which sigfillset() operates on. Using sigfillset()
-     * would write 0xff bytes off the end of the structure and trash
-     * data on the struct.
-     * We can't use sizeof(uc->uc_sigmask) either, because the libc
-     * headers define the struct field with the wrong (too large) type.
-     */
-    memset(&uc->uc_sigmask, 0xff, SIGSET_T_SIZE);
-    sigdelset(&uc->uc_sigmask, SIGSEGV);
-    sigdelset(&uc->uc_sigmask, SIGBUS);
-
-    /* interrupt the virtual CPU as soon as possible */
-    cpu_exit(thread_cpu);
+    if (queue_signal(env, sig, &tinfo) == 1) {
+        /* interrupt the virtual CPU as soon as possible */
+        cpu_exit(thread_cpu);
+    }
 }
 
 /* do_sigaltstack() returns target values and errnos. */
@@ -726,7 +661,7 @@ out:
     return ret;
 }
 
-/* do_sigaction() return target values and host errnos */
+/* do_sigaction() return host values and errnos */
 int do_sigaction(int sig, const struct target_sigaction *act,
                  struct target_sigaction *oact)
 {
@@ -735,14 +670,8 @@ int do_sigaction(int sig, const struct target_sigaction *act,
     int host_sig;
     int ret = 0;
 
-    if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP) {
-        return -TARGET_EINVAL;
-    }
-
-    if (block_signals()) {
-        return -TARGET_ERESTARTSYS;
-    }
-
+    if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
+        return -EINVAL;
     k = &sigact_table[sig - 1];
     if (oact) {
         __put_user(k->_sa_handler, &oact->_sa_handler);
@@ -794,75 +723,75 @@ int do_sigaction(int sig, const struct target_sigaction *act,
 /* from the Linux kernel */
 
 struct target_fpreg {
-    uint16_t significand[4];
-    uint16_t exponent;
+       uint16_t significand[4];
+       uint16_t exponent;
 };
 
 struct target_fpxreg {
-    uint16_t significand[4];
-    uint16_t exponent;
-    uint16_t padding[3];
+       uint16_t significand[4];
+       uint16_t exponent;
+       uint16_t padding[3];
 };
 
 struct target_xmmreg {
-    abi_ulong element[4];
+       abi_ulong element[4];
 };
 
 struct target_fpstate {
-    /* Regular FPU environment */
-    abi_ulong cw;
-    abi_ulong sw;
-    abi_ulong tag;
-    abi_ulong ipoff;
-    abi_ulong cssel;
-    abi_ulong dataoff;
-    abi_ulong datasel;
-    struct target_fpreg _st[8];
-    uint16_t  status;
-    uint16_t  magic;          /* 0xffff = regular FPU data only */
-
-    /* FXSR FPU environment */
-    abi_ulong _fxsr_env[6];   /* FXSR FPU env is ignored */
-    abi_ulong mxcsr;
-    abi_ulong reserved;
-    struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
-    struct target_xmmreg _xmm[8];
-    abi_ulong padding[56];
+       /* Regular FPU environment */
+        abi_ulong       cw;
+        abi_ulong       sw;
+        abi_ulong       tag;
+        abi_ulong       ipoff;
+        abi_ulong       cssel;
+        abi_ulong       dataoff;
+        abi_ulong       datasel;
+       struct target_fpreg     _st[8];
+       uint16_t        status;
+       uint16_t        magic;          /* 0xffff = regular FPU data only */
+
+       /* FXSR FPU environment */
+        abi_ulong       _fxsr_env[6];   /* FXSR FPU env is ignored */
+        abi_ulong       mxcsr;
+        abi_ulong       reserved;
+       struct target_fpxreg    _fxsr_st[8];    /* FXSR FPU reg data is ignored */
+       struct target_xmmreg    _xmm[8];
+        abi_ulong       padding[56];
 };
 
 #define X86_FXSR_MAGIC         0x0000
 
 struct target_sigcontext {
-    uint16_t gs, __gsh;
-    uint16_t fs, __fsh;
-    uint16_t es, __esh;
-    uint16_t ds, __dsh;
-    abi_ulong edi;
-    abi_ulong esi;
-    abi_ulong ebp;
-    abi_ulong esp;
-    abi_ulong ebx;
-    abi_ulong edx;
-    abi_ulong ecx;
-    abi_ulong eax;
-    abi_ulong trapno;
-    abi_ulong err;
-    abi_ulong eip;
-    uint16_t cs, __csh;
-    abi_ulong eflags;
-    abi_ulong esp_at_signal;
-    uint16_t ss, __ssh;
-    abi_ulong fpstate; /* pointer */
-    abi_ulong oldmask;
-    abi_ulong cr2;
+       uint16_t gs, __gsh;
+       uint16_t fs, __fsh;
+       uint16_t es, __esh;
+       uint16_t ds, __dsh;
+        abi_ulong edi;
+        abi_ulong esi;
+        abi_ulong ebp;
+        abi_ulong esp;
+        abi_ulong ebx;
+        abi_ulong edx;
+        abi_ulong ecx;
+        abi_ulong eax;
+        abi_ulong trapno;
+        abi_ulong err;
+        abi_ulong eip;
+       uint16_t cs, __csh;
+        abi_ulong eflags;
+        abi_ulong esp_at_signal;
+       uint16_t ss, __ssh;
+        abi_ulong fpstate; /* pointer */
+        abi_ulong oldmask;
+        abi_ulong cr2;
 };
 
 struct target_ucontext {
-    abi_ulong         tuc_flags;
-    abi_ulong         tuc_link;
-    target_stack_t    tuc_stack;
-    struct target_sigcontext tuc_mcontext;
-    target_sigset_t   tuc_sigmask;  /* mask last for extensibility */
+        abi_ulong         tuc_flags;
+        abi_ulong         tuc_link;
+       target_stack_t    tuc_stack;
+       struct target_sigcontext tuc_mcontext;
+       target_sigset_t   tuc_sigmask;  /* mask last for extensibility */
 };
 
 struct sigframe
@@ -899,7 +828,7 @@ static void setup_sigcontext(struct target_sigcontext *sc,
     CPUState *cs = CPU(x86_env_get_cpu(env));
     uint16_t magic;
 
-    /* already locked in setup_frame() */
+       /* already locked in setup_frame() */
     __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
     __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
     __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
@@ -920,13 +849,13 @@ static void setup_sigcontext(struct target_sigcontext *sc,
     __put_user(env->regs[R_ESP], &sc->esp_at_signal);
     __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
 
-    cpu_x86_fsave(env, fpstate_addr, 1);
-    fpstate->status = fpstate->sw;
-    magic = 0xffff;
+        cpu_x86_fsave(env, fpstate_addr, 1);
+        fpstate->status = fpstate->sw;
+        magic = 0xffff;
     __put_user(magic, &fpstate->magic);
     __put_user(fpstate_addr, &sc->fpstate);
 
-    /* non-iBCS2 extensions.. */
+       /* non-iBCS2 extensions.. */
     __put_user(mask, &sc->oldmask);
     __put_user(env->cr[2], &sc->cr2);
 }
@@ -938,112 +867,110 @@ static void setup_sigcontext(struct target_sigcontext *sc,
 static inline abi_ulong
 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
 {
-    unsigned long esp;
+       unsigned long esp;
 
-    /* Default to using normal stack */
-    esp = env->regs[R_ESP];
-    /* This is the X/Open sanctioned signal stack switching.  */
-    if (ka->sa_flags & TARGET_SA_ONSTACK) {
-        if (sas_ss_flags(esp) == 0) {
-            esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+       /* Default to using normal stack */
+       esp = env->regs[R_ESP];
+       /* This is the X/Open sanctioned signal stack switching.  */
+        if (ka->sa_flags & TARGET_SA_ONSTACK) {
+            if (sas_ss_flags(esp) == 0)
+                esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
         }
-    } else {
 
-        /* This is the legacy signal stack switching. */
+       /* This is the legacy signal stack switching. */
+       else
         if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
-                !(ka->sa_flags & TARGET_SA_RESTORER) &&
-                ka->sa_restorer) {
+            !(ka->sa_flags & TARGET_SA_RESTORER) &&
+            ka->sa_restorer) {
             esp = (unsigned long) ka->sa_restorer;
-        }
-    }
-    return (esp - frame_size) & -8ul;
+       }
+        return (esp - frame_size) & -8ul;
 }
 
 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
 static void setup_frame(int sig, struct target_sigaction *ka,
-                        target_sigset_t *set, CPUX86State *env)
+                       target_sigset_t *set, CPUX86State *env)
 {
-    abi_ulong frame_addr;
-    struct sigframe *frame;
-    int i;
+       abi_ulong frame_addr;
+       struct sigframe *frame;
+       int i;
 
-    frame_addr = get_sigframe(ka, env, sizeof(*frame));
-    trace_user_setup_frame(env, frame_addr);
+       frame_addr = get_sigframe(ka, env, sizeof(*frame));
+        trace_user_setup_frame(env, frame_addr);
 
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
-        goto give_sigsegv;
+       if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+               goto give_sigsegv;
 
     __put_user(sig, &frame->sig);
 
-    setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
-            frame_addr + offsetof(struct sigframe, fpstate));
+       setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
+                         frame_addr + offsetof(struct sigframe, fpstate));
 
     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
         __put_user(set->sig[i], &frame->extramask[i - 1]);
     }
 
-    /* Set up to return from userspace.  If provided, use a stub
-       already in userspace.  */
-    if (ka->sa_flags & TARGET_SA_RESTORER) {
+       /* Set up to return from userspace.  If provided, use a stub
+          already in userspace.  */
+       if (ka->sa_flags & TARGET_SA_RESTORER) {
         __put_user(ka->sa_restorer, &frame->pretcode);
-    } else {
-        uint16_t val16;
-        abi_ulong retcode_addr;
-        retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
+       } else {
+                uint16_t val16;
+                abi_ulong retcode_addr;
+                retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
         __put_user(retcode_addr, &frame->pretcode);
-        /* This is popl %eax ; movl $,%eax ; int $0x80 */
-        val16 = 0xb858;
+               /* This is popl %eax ; movl $,%eax ; int $0x80 */
+                val16 = 0xb858;
         __put_user(val16, (uint16_t *)(frame->retcode+0));
         __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
-        val16 = 0x80cd;
+                val16 = 0x80cd;
         __put_user(val16, (uint16_t *)(frame->retcode+6));
-    }
+       }
 
 
-    /* Set up registers for signal handler */
-    env->regs[R_ESP] = frame_addr;
-    env->eip = ka->_sa_handler;
+       /* Set up registers for signal handler */
+       env->regs[R_ESP] = frame_addr;
+       env->eip = ka->_sa_handler;
 
-    cpu_x86_load_seg(env, R_DS, __USER_DS);
-    cpu_x86_load_seg(env, R_ES, __USER_DS);
-    cpu_x86_load_seg(env, R_SS, __USER_DS);
-    cpu_x86_load_seg(env, R_CS, __USER_CS);
-    env->eflags &= ~TF_MASK;
+        cpu_x86_load_seg(env, R_DS, __USER_DS);
+        cpu_x86_load_seg(env, R_ES, __USER_DS);
+        cpu_x86_load_seg(env, R_SS, __USER_DS);
+        cpu_x86_load_seg(env, R_CS, __USER_CS);
+       env->eflags &= ~TF_MASK;
 
-    unlock_user_struct(frame, frame_addr, 1);
+       unlock_user_struct(frame, frame_addr, 1);
 
-    return;
+       return;
 
 give_sigsegv:
-    if (sig == TARGET_SIGSEGV) {
-        ka->_sa_handler = TARGET_SIG_DFL;
-    }
-    force_sig(TARGET_SIGSEGV /* , current */);
+       if (sig == TARGET_SIGSEGV)
+               ka->_sa_handler = TARGET_SIG_DFL;
+       force_sig(TARGET_SIGSEGV /* , current */);
 }
 
 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
 static void setup_rt_frame(int sig, struct target_sigaction *ka,
                            target_siginfo_t *info,
-                           target_sigset_t *set, CPUX86State *env)
+                          target_sigset_t *set, CPUX86State *env)
 {
-    abi_ulong frame_addr, addr;
-    struct rt_sigframe *frame;
-    int i;
+        abi_ulong frame_addr, addr;
+       struct rt_sigframe *frame;
+       int i;
 
-    frame_addr = get_sigframe(ka, env, sizeof(*frame));
-    trace_user_setup_rt_frame(env, frame_addr);
+       frame_addr = get_sigframe(ka, env, sizeof(*frame));
+        trace_user_setup_rt_frame(env, frame_addr);
 
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
-        goto give_sigsegv;
+       if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+               goto give_sigsegv;
 
     __put_user(sig, &frame->sig);
-    addr = frame_addr + offsetof(struct rt_sigframe, info);
+        addr = frame_addr + offsetof(struct rt_sigframe, info);
     __put_user(addr, &frame->pinfo);
-    addr = frame_addr + offsetof(struct rt_sigframe, uc);
+        addr = frame_addr + offsetof(struct rt_sigframe, uc);
     __put_user(addr, &frame->puc);
     tswap_siginfo(&frame->info, info);
 
-    /* Create the ucontext.  */
+       /* Create the ucontext.  */
     __put_user(0, &frame->uc.tuc_flags);
     __put_user(0, &frame->uc.tuc_link);
     __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
@@ -1058,82 +985,81 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
         __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
     }
 
-    /* Set up to return from userspace.  If provided, use a stub
-       already in userspace.  */
-    if (ka->sa_flags & TARGET_SA_RESTORER) {
+       /* Set up to return from userspace.  If provided, use a stub
+          already in userspace.  */
+       if (ka->sa_flags & TARGET_SA_RESTORER) {
         __put_user(ka->sa_restorer, &frame->pretcode);
-    } else {
-        uint16_t val16;
-        addr = frame_addr + offsetof(struct rt_sigframe, retcode);
+       } else {
+                uint16_t val16;
+                addr = frame_addr + offsetof(struct rt_sigframe, retcode);
         __put_user(addr, &frame->pretcode);
-        /* This is movl $,%eax ; int $0x80 */
+               /* This is movl $,%eax ; int $0x80 */
         __put_user(0xb8, (char *)(frame->retcode+0));
         __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
-        val16 = 0x80cd;
+                val16 = 0x80cd;
         __put_user(val16, (uint16_t *)(frame->retcode+5));
-    }
+       }
 
-    /* Set up registers for signal handler */
-    env->regs[R_ESP] = frame_addr;
-    env->eip = ka->_sa_handler;
+       /* Set up registers for signal handler */
+       env->regs[R_ESP] = frame_addr;
+       env->eip = ka->_sa_handler;
 
-    cpu_x86_load_seg(env, R_DS, __USER_DS);
-    cpu_x86_load_seg(env, R_ES, __USER_DS);
-    cpu_x86_load_seg(env, R_SS, __USER_DS);
-    cpu_x86_load_seg(env, R_CS, __USER_CS);
-    env->eflags &= ~TF_MASK;
+        cpu_x86_load_seg(env, R_DS, __USER_DS);
+        cpu_x86_load_seg(env, R_ES, __USER_DS);
+        cpu_x86_load_seg(env, R_SS, __USER_DS);
+        cpu_x86_load_seg(env, R_CS, __USER_CS);
+       env->eflags &= ~TF_MASK;
 
-    unlock_user_struct(frame, frame_addr, 1);
+       unlock_user_struct(frame, frame_addr, 1);
 
-    return;
+       return;
 
 give_sigsegv:
-    if (sig == TARGET_SIGSEGV) {
-        ka->_sa_handler = TARGET_SIG_DFL;
-    }
-    force_sig(TARGET_SIGSEGV /* , current */);
+       if (sig == TARGET_SIGSEGV)
+               ka->_sa_handler = TARGET_SIG_DFL;
+       force_sig(TARGET_SIGSEGV /* , current */);
 }
 
 static int
-restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc)
-{
-    unsigned int err = 0;
-    abi_ulong fpstate_addr;
-    unsigned int tmpflags;
-
-    cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
-    cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
-    cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
-    cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
-
-    env->regs[R_EDI] = tswapl(sc->edi);
-    env->regs[R_ESI] = tswapl(sc->esi);
-    env->regs[R_EBP] = tswapl(sc->ebp);
-    env->regs[R_ESP] = tswapl(sc->esp);
-    env->regs[R_EBX] = tswapl(sc->ebx);
-    env->regs[R_EDX] = tswapl(sc->edx);
-    env->regs[R_ECX] = tswapl(sc->ecx);
-    env->regs[R_EAX] = tswapl(sc->eax);
-    env->eip = tswapl(sc->eip);
-
-    cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3);
-    cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3);
-
-    tmpflags = tswapl(sc->eflags);
-    env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
-    //         regs->orig_eax = -1;            /* disable syscall checks */
-
-    fpstate_addr = tswapl(sc->fpstate);
-    if (fpstate_addr != 0) {
-        if (!access_ok(VERIFY_READ, fpstate_addr,
-                       sizeof(struct target_fpstate)))
-            goto badframe;
-        cpu_x86_frstor(env, fpstate_addr, 1);
-    }
+restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
+{
+       unsigned int err = 0;
+        abi_ulong fpstate_addr;
+        unsigned int tmpflags;
+
+        cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
+        cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
+        cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
+        cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
+
+        env->regs[R_EDI] = tswapl(sc->edi);
+        env->regs[R_ESI] = tswapl(sc->esi);
+        env->regs[R_EBP] = tswapl(sc->ebp);
+        env->regs[R_ESP] = tswapl(sc->esp);
+        env->regs[R_EBX] = tswapl(sc->ebx);
+        env->regs[R_EDX] = tswapl(sc->edx);
+        env->regs[R_ECX] = tswapl(sc->ecx);
+        env->eip = tswapl(sc->eip);
+
+        cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3);
+        cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3);
+
+        tmpflags = tswapl(sc->eflags);
+        env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
+        //             regs->orig_eax = -1;            /* disable syscall checks */
+
+        fpstate_addr = tswapl(sc->fpstate);
+       if (fpstate_addr != 0) {
+                if (!access_ok(VERIFY_READ, fpstate_addr, 
+                               sizeof(struct target_fpstate)))
+                        goto badframe;
+                cpu_x86_frstor(env, fpstate_addr, 1);
+       }
 
-    return err;
+        *peax = tswapl(sc->eax);
+       return err;
 badframe:
-    return 1;
+       return 1;
 }
 
 long do_sigreturn(CPUX86State *env)
@@ -1142,7 +1068,7 @@ long do_sigreturn(CPUX86State *env)
     abi_ulong frame_addr = env->regs[R_ESP] - 8;
     target_sigset_t target_set;
     sigset_t set;
-    int i;
+    int eax, i;
 
     trace_user_do_sigreturn(env, frame_addr);
     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
@@ -1154,13 +1080,13 @@ long do_sigreturn(CPUX86State *env)
     }
 
     target_to_host_sigset_internal(&set, &target_set);
-    set_sigmask(&set);
+    do_sigprocmask(SIG_SETMASK, &set, NULL);
 
     /* restore registers */
-    if (restore_sigcontext(env, &frame->sc))
+    if (restore_sigcontext(env, &frame->sc, &eax))
         goto badframe;
     unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+    return eax;
 
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
@@ -1170,33 +1096,32 @@ badframe:
 
 long do_rt_sigreturn(CPUX86State *env)
 {
-    abi_ulong frame_addr;
-    struct rt_sigframe *frame;
-    sigset_t set;
+        abi_ulong frame_addr;
+       struct rt_sigframe *frame;
+        sigset_t set;
+       int eax;
 
-    frame_addr = env->regs[R_ESP] - 4;
-    trace_user_do_rt_sigreturn(env, frame_addr);
-    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
-        goto badframe;
-    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
-    set_sigmask(&set);
+        frame_addr = env->regs[R_ESP] - 4;
+        trace_user_do_rt_sigreturn(env, frame_addr);
+        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
+                goto badframe;
+        target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
+        do_sigprocmask(SIG_SETMASK, &set, NULL);
 
-    if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
-        goto badframe;
-    }
+       if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
+               goto badframe;
 
-    if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
-                       get_sp_from_cpustate(env)) == -EFAULT) {
-        goto badframe;
-    }
+       if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0, 
+                           get_sp_from_cpustate(env)) == -EFAULT)
+               goto badframe;
 
-    unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+        unlock_user_struct(frame, frame_addr, 0);
+       return eax;
 
 badframe:
-    unlock_user_struct(frame, frame_addr, 0);
-    force_sig(TARGET_SIGSEGV);
-    return 0;
+        unlock_user_struct(frame, frame_addr, 0);
+        force_sig(TARGET_SIGSEGV);
+       return 0;
 }
 
 #elif defined(TARGET_AARCH64)
@@ -1319,7 +1244,7 @@ static int target_restore_sigframe(CPUARMState *env,
     uint64_t pstate;
 
     target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
-    set_sigmask(&set);
+    do_sigprocmask(SIG_SETMASK, &set, NULL);
 
     for (i = 0; i < 31; i++) {
         __get_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
@@ -1461,7 +1386,7 @@ long do_rt_sigreturn(CPUARMState *env)
     }
 
     unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+    return env->xregs[0];
 
  badframe:
     unlock_user_struct(frame, frame_addr, 0);
@@ -1477,27 +1402,27 @@ long do_sigreturn(CPUARMState *env)
 #elif defined(TARGET_ARM)
 
 struct target_sigcontext {
-    abi_ulong trap_no;
-    abi_ulong error_code;
-    abi_ulong oldmask;
-    abi_ulong arm_r0;
-    abi_ulong arm_r1;
-    abi_ulong arm_r2;
-    abi_ulong arm_r3;
-    abi_ulong arm_r4;
-    abi_ulong arm_r5;
-    abi_ulong arm_r6;
-    abi_ulong arm_r7;
-    abi_ulong arm_r8;
-    abi_ulong arm_r9;
-    abi_ulong arm_r10;
-    abi_ulong arm_fp;
-    abi_ulong arm_ip;
-    abi_ulong arm_sp;
-    abi_ulong arm_lr;
-    abi_ulong arm_pc;
-    abi_ulong arm_cpsr;
-    abi_ulong fault_address;
+       abi_ulong trap_no;
+       abi_ulong error_code;
+       abi_ulong oldmask;
+       abi_ulong arm_r0;
+       abi_ulong arm_r1;
+       abi_ulong arm_r2;
+       abi_ulong arm_r3;
+       abi_ulong arm_r4;
+       abi_ulong arm_r5;
+       abi_ulong arm_r6;
+       abi_ulong arm_r7;
+       abi_ulong arm_r8;
+       abi_ulong arm_r9;
+       abi_ulong arm_r10;
+       abi_ulong arm_fp;
+       abi_ulong arm_ip;
+       abi_ulong arm_sp;
+       abi_ulong arm_lr;
+       abi_ulong arm_pc;
+       abi_ulong arm_cpsr;
+       abi_ulong fault_address;
 };
 
 struct target_ucontext_v1 {
@@ -1656,7 +1581,7 @@ get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
 
 static void
 setup_return(CPUARMState *env, struct target_sigaction *ka,
-             abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
+            abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
 {
     abi_ulong handler = ka->_sa_handler;
     abi_ulong retcode;
@@ -1766,44 +1691,42 @@ static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
 static void setup_frame_v1(int usig, struct target_sigaction *ka,
                            target_sigset_t *set, CPUARMState *regs)
 {
-    struct sigframe_v1 *frame;
-    abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
-    int i;
+       struct sigframe_v1 *frame;
+       abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
+       int i;
 
-    trace_user_setup_frame(regs, frame_addr);
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        return;
-    }
+        trace_user_setup_frame(regs, frame_addr);
+       if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+               return;
 
-    setup_sigcontext(&frame->sc, regs, set->sig[0]);
+       setup_sigcontext(&frame->sc, regs, set->sig[0]);
 
     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
         __put_user(set->sig[i], &frame->extramask[i - 1]);
     }
 
-    setup_return(regs, ka, &frame->retcode, frame_addr, usig,
-                 frame_addr + offsetof(struct sigframe_v1, retcode));
+        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
+                     frame_addr + offsetof(struct sigframe_v1, retcode));
 
-    unlock_user_struct(frame, frame_addr, 1);
+       unlock_user_struct(frame, frame_addr, 1);
 }
 
 static void setup_frame_v2(int usig, struct target_sigaction *ka,
                            target_sigset_t *set, CPUARMState *regs)
 {
-    struct sigframe_v2 *frame;
-    abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
+       struct sigframe_v2 *frame;
+       abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
 
-    trace_user_setup_frame(regs, frame_addr);
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        return;
-    }
+        trace_user_setup_frame(regs, frame_addr);
+       if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+               return;
 
-    setup_sigframe_v2(&frame->uc, set, regs);
+        setup_sigframe_v2(&frame->uc, set, regs);
 
-    setup_return(regs, ka, &frame->retcode, frame_addr, usig,
-                 frame_addr + offsetof(struct sigframe_v2, retcode));
+        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
+                     frame_addr + offsetof(struct sigframe_v2, retcode));
 
-    unlock_user_struct(frame, frame_addr, 1);
+       unlock_user_struct(frame, frame_addr, 1);
 }
 
 static void setup_frame(int usig, struct target_sigaction *ka,
@@ -1821,72 +1744,70 @@ static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
                               target_siginfo_t *info,
                               target_sigset_t *set, CPUARMState *env)
 {
-    struct rt_sigframe_v1 *frame;
-    abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
-    struct target_sigaltstack stack;
-    int i;
-    abi_ulong info_addr, uc_addr;
+       struct rt_sigframe_v1 *frame;
+       abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
+       struct target_sigaltstack stack;
+       int i;
+        abi_ulong info_addr, uc_addr;
 
-    trace_user_setup_rt_frame(env, frame_addr);
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        return /* 1 */;
-    }
+        trace_user_setup_rt_frame(env, frame_addr);
+       if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+            return /* 1 */;
 
-    info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
-    __put_user(info_addr, &frame->pinfo);
-    uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
-    __put_user(uc_addr, &frame->puc);
-    tswap_siginfo(&frame->info, info);
+        info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
+       __put_user(info_addr, &frame->pinfo);
+        uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
+       __put_user(uc_addr, &frame->puc);
+        tswap_siginfo(&frame->info, info);
 
-    /* Clear all the bits of the ucontext we don't use.  */
-    memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
+       /* Clear all the bits of the ucontext we don't use.  */
+       memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
 
-    memset(&stack, 0, sizeof(stack));
-    __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
-    __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
-    __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
-    memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
+        memset(&stack, 0, sizeof(stack));
+        __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
+        __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
+        __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
+        memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
 
-    setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
-    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
-        __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
-    }
+       setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
+        for(i = 0; i < TARGET_NSIG_WORDS; i++) {
+            __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
+        }
 
-    setup_return(env, ka, &frame->retcode, frame_addr, usig,
-                 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
+        setup_return(env, ka, &frame->retcode, frame_addr, usig,
+                     frame_addr + offsetof(struct rt_sigframe_v1, retcode));
 
-    env->regs[1] = info_addr;
-    env->regs[2] = uc_addr;
+        env->regs[1] = info_addr;
+        env->regs[2] = uc_addr;
 
-    unlock_user_struct(frame, frame_addr, 1);
+       unlock_user_struct(frame, frame_addr, 1);
 }
 
 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
                               target_siginfo_t *info,
                               target_sigset_t *set, CPUARMState *env)
 {
-    struct rt_sigframe_v2 *frame;
-    abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
-    abi_ulong info_addr, uc_addr;
+       struct rt_sigframe_v2 *frame;
+       abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
+        abi_ulong info_addr, uc_addr;
 
-    trace_user_setup_rt_frame(env, frame_addr);
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        return /* 1 */;
-    }
+        trace_user_setup_rt_frame(env, frame_addr);
+       if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+            return /* 1 */;
 
-    info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
-    uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
-    tswap_siginfo(&frame->info, info);
+        info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
+        uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
+        tswap_siginfo(&frame->info, info);
 
-    setup_sigframe_v2(&frame->uc, set, env);
+        setup_sigframe_v2(&frame->uc, set, env);
 
-    setup_return(env, ka, &frame->retcode, frame_addr, usig,
-                 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
+        setup_return(env, ka, &frame->retcode, frame_addr, usig,
+                     frame_addr + offsetof(struct rt_sigframe_v2, retcode));
 
-    env->regs[1] = info_addr;
-    env->regs[2] = uc_addr;
+        env->regs[1] = info_addr;
+        env->regs[2] = uc_addr;
 
-    unlock_user_struct(frame, frame_addr, 1);
+       unlock_user_struct(frame, frame_addr, 1);
 }
 
 static void setup_rt_frame(int usig, struct target_sigaction *ka,
@@ -1903,8 +1824,8 @@ static void setup_rt_frame(int usig, struct target_sigaction *ka,
 static int
 restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
 {
-    int err = 0;
-    uint32_t cpsr;
+       int err = 0;
+        uint32_t cpsr;
 
     __get_user(env->regs[0], &sc->arm_r0);
     __get_user(env->regs[1], &sc->arm_r1);
@@ -1927,57 +1848,55 @@ restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
     cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC, CPSRWriteByInstr);
 #endif
 
-    err |= !valid_user_regs(env);
+       err |= !valid_user_regs(env);
 
-    return err;
+       return err;
 }
 
 static long do_sigreturn_v1(CPUARMState *env)
 {
-    abi_ulong frame_addr;
-    struct sigframe_v1 *frame = NULL;
-    target_sigset_t set;
-    sigset_t host_set;
-    int i;
+        abi_ulong frame_addr;
+        struct sigframe_v1 *frame = NULL;
+       target_sigset_t set;
+        sigset_t host_set;
+        int i;
 
-    /*
-     * Since we stacked the signal on a 64-bit boundary,
-     * then 'sp' should be word aligned here.  If it's
-     * not, then the user is trying to mess with us.
-     */
-    frame_addr = env->regs[13];
-    trace_user_do_sigreturn(env, frame_addr);
-    if (frame_addr & 7) {
-        goto badframe;
-    }
+       /*
+        * Since we stacked the signal on a 64-bit boundary,
+        * then 'sp' should be word aligned here.  If it's
+        * not, then the user is trying to mess with us.
+        */
+        frame_addr = env->regs[13];
+        trace_user_do_sigreturn(env, frame_addr);
+        if (frame_addr & 7) {
+            goto badframe;
+        }
 
-    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
-        goto badframe;
-    }
+       if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
+                goto badframe;
 
     __get_user(set.sig[0], &frame->sc.oldmask);
     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
         __get_user(set.sig[i], &frame->extramask[i - 1]);
     }
 
-    target_to_host_sigset_internal(&host_set, &set);
-    set_sigmask(&host_set);
+        target_to_host_sigset_internal(&host_set, &set);
+        do_sigprocmask(SIG_SETMASK, &host_set, NULL);
 
-    if (restore_sigcontext(env, &frame->sc)) {
-        goto badframe;
-    }
+       if (restore_sigcontext(env, &frame->sc))
+               goto badframe;
 
 #if 0
-    /* Send SIGTRAP if we're single-stepping */
-    if (ptrace_cancel_bpt(current))
-        send_sig(SIGTRAP, current, 1);
+       /* Send SIGTRAP if we're single-stepping */
+       if (ptrace_cancel_bpt(current))
+               send_sig(SIGTRAP, current, 1);
 #endif
-    unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+       unlock_user_struct(frame, frame_addr, 0);
+        return env->regs[0];
 
 badframe:
-    force_sig(TARGET_SIGSEGV /* , current */);
-    return 0;
+        force_sig(TARGET_SIGSEGV /* , current */);
+       return 0;
 }
 
 static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
@@ -2042,7 +1961,7 @@ static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
     abi_ulong *regspace;
 
     target_to_host_sigset(&host_set, &uc->tuc_sigmask);
-    set_sigmask(&host_set);
+    do_sigprocmask(SIG_SETMASK, &host_set, NULL);
 
     if (restore_sigcontext(env, &uc->tuc_mcontext))
         return 1;
@@ -2068,7 +1987,7 @@ static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
 #if 0
     /* Send SIGTRAP if we're single-stepping */
     if (ptrace_cancel_bpt(current))
-        send_sig(SIGTRAP, current, 1);
+            send_sig(SIGTRAP, current, 1);
 #endif
 
     return 0;
@@ -2076,35 +1995,33 @@ static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
 
 static long do_sigreturn_v2(CPUARMState *env)
 {
-    abi_ulong frame_addr;
-    struct sigframe_v2 *frame = NULL;
-
-    /*
-     * Since we stacked the signal on a 64-bit boundary,
-     * then 'sp' should be word aligned here.  If it's
-     * not, then the user is trying to mess with us.
-     */
-    frame_addr = env->regs[13];
-    trace_user_do_sigreturn(env, frame_addr);
-    if (frame_addr & 7) {
-        goto badframe;
-    }
+        abi_ulong frame_addr;
+        struct sigframe_v2 *frame = NULL;
+
+       /*
+        * Since we stacked the signal on a 64-bit boundary,
+        * then 'sp' should be word aligned here.  If it's
+        * not, then the user is trying to mess with us.
+        */
+        frame_addr = env->regs[13];
+        trace_user_do_sigreturn(env, frame_addr);
+        if (frame_addr & 7) {
+            goto badframe;
+        }
 
-    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
-        goto badframe;
-    }
+       if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
+                goto badframe;
 
-    if (do_sigframe_return_v2(env, frame_addr, &frame->uc)) {
-        goto badframe;
-    }
+        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
+                goto badframe;
 
-    unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+       unlock_user_struct(frame, frame_addr, 0);
+       return env->regs[0];
 
 badframe:
-    unlock_user_struct(frame, frame_addr, 0);
-    force_sig(TARGET_SIGSEGV /* , current */);
-    return 0;
+       unlock_user_struct(frame, frame_addr, 0);
+        force_sig(TARGET_SIGSEGV /* , current */);
+       return 0;
 }
 
 long do_sigreturn(CPUARMState *env)
@@ -2118,80 +2035,76 @@ long do_sigreturn(CPUARMState *env)
 
 static long do_rt_sigreturn_v1(CPUARMState *env)
 {
-    abi_ulong frame_addr;
-    struct rt_sigframe_v1 *frame = NULL;
-    sigset_t host_set;
-
-    /*
-     * Since we stacked the signal on a 64-bit boundary,
-     * then 'sp' should be word aligned here.  If it's
-     * not, then the user is trying to mess with us.
-     */
-    frame_addr = env->regs[13];
-    trace_user_do_rt_sigreturn(env, frame_addr);
-    if (frame_addr & 7) {
-        goto badframe;
-    }
+        abi_ulong frame_addr;
+        struct rt_sigframe_v1 *frame = NULL;
+        sigset_t host_set;
+
+       /*
+        * Since we stacked the signal on a 64-bit boundary,
+        * then 'sp' should be word aligned here.  If it's
+        * not, then the user is trying to mess with us.
+        */
+        frame_addr = env->regs[13];
+        trace_user_do_rt_sigreturn(env, frame_addr);
+        if (frame_addr & 7) {
+            goto badframe;
+        }
 
-    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
-        goto badframe;
-    }
+       if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
+                goto badframe;
 
-    target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
-    set_sigmask(&host_set);
+        target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
+        do_sigprocmask(SIG_SETMASK, &host_set, NULL);
 
-    if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
-        goto badframe;
-    }
+       if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
+               goto badframe;
 
-    if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
-        goto badframe;
+       if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
+               goto badframe;
 
 #if 0
-    /* Send SIGTRAP if we're single-stepping */
-    if (ptrace_cancel_bpt(current))
-        send_sig(SIGTRAP, current, 1);
+       /* Send SIGTRAP if we're single-stepping */
+       if (ptrace_cancel_bpt(current))
+               send_sig(SIGTRAP, current, 1);
 #endif
-    unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+       unlock_user_struct(frame, frame_addr, 0);
+       return env->regs[0];
 
 badframe:
-    unlock_user_struct(frame, frame_addr, 0);
-    force_sig(TARGET_SIGSEGV /* , current */);
-    return 0;
+       unlock_user_struct(frame, frame_addr, 0);
+        force_sig(TARGET_SIGSEGV /* , current */);
+       return 0;
 }
 
 static long do_rt_sigreturn_v2(CPUARMState *env)
 {
-    abi_ulong frame_addr;
-    struct rt_sigframe_v2 *frame = NULL;
-
-    /*
-     * Since we stacked the signal on a 64-bit boundary,
-     * then 'sp' should be word aligned here.  If it's
-     * not, then the user is trying to mess with us.
-     */
-    frame_addr = env->regs[13];
-    trace_user_do_rt_sigreturn(env, frame_addr);
-    if (frame_addr & 7) {
-        goto badframe;
-    }
+        abi_ulong frame_addr;
+        struct rt_sigframe_v2 *frame = NULL;
+
+       /*
+        * Since we stacked the signal on a 64-bit boundary,
+        * then 'sp' should be word aligned here.  If it's
+        * not, then the user is trying to mess with us.
+        */
+        frame_addr = env->regs[13];
+        trace_user_do_rt_sigreturn(env, frame_addr);
+        if (frame_addr & 7) {
+            goto badframe;
+        }
 
-    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
-        goto badframe;
-    }
+       if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
+                goto badframe;
 
-    if (do_sigframe_return_v2(env, frame_addr, &frame->uc)) {
-        goto badframe;
-    }
+        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
+                goto badframe;
 
-    unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+       unlock_user_struct(frame, frame_addr, 0);
+       return env->regs[0];
 
 badframe:
-    unlock_user_struct(frame, frame_addr, 0);
-    force_sig(TARGET_SIGSEGV /* , current */);
-    return 0;
+       unlock_user_struct(frame, frame_addr, 0);
+        force_sig(TARGET_SIGSEGV /* , current */);
+       return 0;
 }
 
 long do_rt_sigreturn(CPUARMState *env)
@@ -2209,83 +2122,83 @@ long do_rt_sigreturn(CPUARMState *env)
 
 /* This is what SunOS does, so shall I. */
 struct target_sigcontext {
-    abi_ulong sigc_onstack;      /* state to restore */
+        abi_ulong sigc_onstack;      /* state to restore */
 
-    abi_ulong sigc_mask;         /* sigmask to restore */
-    abi_ulong sigc_sp;           /* stack pointer */
-    abi_ulong sigc_pc;           /* program counter */
-    abi_ulong sigc_npc;          /* next program counter */
-    abi_ulong sigc_psr;          /* for condition codes etc */
-    abi_ulong sigc_g1;           /* User uses these two registers */
-    abi_ulong sigc_o0;           /* within the trampoline code. */
+        abi_ulong sigc_mask;         /* sigmask to restore */
+        abi_ulong sigc_sp;           /* stack pointer */
+        abi_ulong sigc_pc;           /* program counter */
+        abi_ulong sigc_npc;          /* next program counter */
+        abi_ulong sigc_psr;          /* for condition codes etc */
+        abi_ulong sigc_g1;           /* User uses these two registers */
+        abi_ulong sigc_o0;           /* within the trampoline code. */
 
-    /* Now comes information regarding the users window set
+        /* Now comes information regarding the users window set
          * at the time of the signal.
          */
-    abi_ulong sigc_oswins;       /* outstanding windows */
+        abi_ulong sigc_oswins;       /* outstanding windows */
 
-    /* stack ptrs for each regwin buf */
-    char *sigc_spbuf[__SUNOS_MAXWIN];
+        /* stack ptrs for each regwin buf */
+        char *sigc_spbuf[__SUNOS_MAXWIN];
 
-    /* Windows to restore after signal */
-    struct {
-        abi_ulong locals[8];
-        abi_ulong ins[8];
-    } sigc_wbuf[__SUNOS_MAXWIN];
+        /* Windows to restore after signal */
+        struct {
+                abi_ulong locals[8];
+                abi_ulong ins[8];
+        } sigc_wbuf[__SUNOS_MAXWIN];
 };
 /* A Sparc stack frame */
 struct sparc_stackf {
-    abi_ulong locals[8];
-    abi_ulong ins[8];
-    /* It's simpler to treat fp and callers_pc as elements of ins[]
+        abi_ulong locals[8];
+        abi_ulong ins[8];
+        /* It's simpler to treat fp and callers_pc as elements of ins[]
          * since we never need to access them ourselves.
          */
-    char *structptr;
-    abi_ulong xargs[6];
-    abi_ulong xxargs[1];
+        char *structptr;
+        abi_ulong xargs[6];
+        abi_ulong xxargs[1];
 };
 
 typedef struct {
-    struct {
-        abi_ulong psr;
-        abi_ulong pc;
-        abi_ulong npc;
-        abi_ulong y;
-        abi_ulong u_regs[16]; /* globals and ins */
-    }               si_regs;
-    int             si_mask;
+        struct {
+                abi_ulong psr;
+                abi_ulong pc;
+                abi_ulong npc;
+                abi_ulong y;
+                abi_ulong u_regs[16]; /* globals and ins */
+        }               si_regs;
+        int             si_mask;
 } __siginfo_t;
 
 typedef struct {
-    abi_ulong  si_float_regs[32];
-    unsigned   long si_fsr;
-    unsigned   long si_fpqdepth;
-    struct {
-        unsigned long *insn_addr;
-        unsigned long insn;
-    } si_fpqueue [16];
+        abi_ulong       si_float_regs[32];
+        unsigned   long si_fsr;
+        unsigned   long si_fpqdepth;
+        struct {
+                unsigned long *insn_addr;
+                unsigned long insn;
+        } si_fpqueue [16];
 } qemu_siginfo_fpu_t;
 
 
 struct target_signal_frame {
-    struct sparc_stackf ss;
-    __siginfo_t         info;
-    abi_ulong           fpu_save;
-    abi_ulong           insns[2] __attribute__ ((aligned (8)));
-    abi_ulong           extramask[TARGET_NSIG_WORDS - 1];
-    abi_ulong           extra_size; /* Should be 0 */
-    qemu_siginfo_fpu_t fpu_state;
+       struct sparc_stackf     ss;
+       __siginfo_t             info;
+       abi_ulong               fpu_save;
+       abi_ulong               insns[2] __attribute__ ((aligned (8)));
+       abi_ulong               extramask[TARGET_NSIG_WORDS - 1];
+       abi_ulong               extra_size; /* Should be 0 */
+       qemu_siginfo_fpu_t      fpu_state;
 };
 struct target_rt_signal_frame {
-    struct sparc_stackf ss;
-    siginfo_t           info;
-    abi_ulong           regs[20];
-    sigset_t            mask;
-    abi_ulong           fpu_save;
-    unsigned int        insns[2];
-    stack_t             stack;
-    unsigned int        extra_size; /* Should be 0 */
-    qemu_siginfo_fpu_t  fpu_state;
+       struct sparc_stackf     ss;
+       siginfo_t               info;
+       abi_ulong               regs[20];
+       sigset_t                mask;
+       abi_ulong               fpu_save;
+       unsigned int            insns[2];
+       stack_t                 stack;
+       unsigned int            extra_size; /* Should be 0 */
+       qemu_siginfo_fpu_t      fpu_state;
 };
 
 #define UREG_O0        16
@@ -2306,37 +2219,36 @@ static inline abi_ulong get_sigframe(struct target_sigaction *sa,
                                      CPUSPARCState *env,
                                      unsigned long framesize)
 {
-    abi_ulong sp;
+       abi_ulong sp;
 
-    sp = env->regwptr[UREG_FP];
+       sp = env->regwptr[UREG_FP];
 
-    /* This is the X/Open sanctioned signal stack switching.  */
-    if (sa->sa_flags & TARGET_SA_ONSTACK) {
-        if (!on_sig_stack(sp)
-                && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7)) {
-            sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
-        }
-    }
-    return sp - framesize;
+       /* This is the X/Open sanctioned signal stack switching.  */
+       if (sa->sa_flags & TARGET_SA_ONSTACK) {
+            if (!on_sig_stack(sp)
+                && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
+                sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+       }
+       return sp - framesize;
 }
 
 static int
 setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
 {
-    int err = 0, i;
+       int err = 0, i;
 
     __put_user(env->psr, &si->si_regs.psr);
     __put_user(env->pc, &si->si_regs.pc);
     __put_user(env->npc, &si->si_regs.npc);
     __put_user(env->y, &si->si_regs.y);
-    for (i=0; i < 8; i++) {
+       for (i=0; i < 8; i++) {
         __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
-    }
-    for (i=0; i < 8; i++) {
+       }
+       for (i=0; i < 8; i++) {
         __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
-    }
+       }
     __put_user(mask, &si->si_mask);
-    return err;
+       return err;
 }
 
 #if 0
@@ -2344,7 +2256,7 @@ static int
 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
                  CPUSPARCState *env, unsigned long mask)
 {
-    int err = 0;
+       int err = 0;
 
     __put_user(mask, &sc->sigc_mask);
     __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
@@ -2354,7 +2266,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
     __put_user(env->gregs[1], &sc->sigc_g1);
     __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
 
-    return err;
+       return err;
 }
 #endif
 #define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
@@ -2362,90 +2274,90 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
 static void setup_frame(int sig, struct target_sigaction *ka,
                         target_sigset_t *set, CPUSPARCState *env)
 {
-    abi_ulong sf_addr;
-    struct target_signal_frame *sf;
-    int sigframe_size, err, i;
+        abi_ulong sf_addr;
+       struct target_signal_frame *sf;
+       int sigframe_size, err, i;
 
-    /* 1. Make sure everything is clean */
-    //synchronize_user_stack();
+       /* 1. Make sure everything is clean */
+       //synchronize_user_stack();
 
-    sigframe_size = NF_ALIGNEDSZ;
-    sf_addr = get_sigframe(ka, env, sigframe_size);
-    trace_user_setup_frame(env, sf_addr);
+        sigframe_size = NF_ALIGNEDSZ;
+       sf_addr = get_sigframe(ka, env, sigframe_size);
+        trace_user_setup_frame(env, sf_addr);
 
-    sf = lock_user(VERIFY_WRITE, sf_addr,
-                   sizeof(struct target_signal_frame), 0);
-    if (!sf) {
-        goto sigsegv;
-    }
+        sf = lock_user(VERIFY_WRITE, sf_addr, 
+                       sizeof(struct target_signal_frame), 0);
+        if (!sf)
+               goto sigsegv;
+                
 #if 0
-    if (invalid_frame_pointer(sf, sigframe_size))
-        goto sigill_and_return;
+       if (invalid_frame_pointer(sf, sigframe_size))
+               goto sigill_and_return;
 #endif
-    /* 2. Save the current process state */
-    err = setup___siginfo(&sf->info, env, set->sig[0]);
+       /* 2. Save the current process state */
+       err = setup___siginfo(&sf->info, env, set->sig[0]);
     __put_user(0, &sf->extra_size);
 
-    //save_fpu_state(regs, &sf->fpu_state);
-    //__put_user(&sf->fpu_state, &sf->fpu_save);
+       //save_fpu_state(regs, &sf->fpu_state);
+       //__put_user(&sf->fpu_state, &sf->fpu_save);
 
     __put_user(set->sig[0], &sf->info.si_mask);
-    for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
+       for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
         __put_user(set->sig[i + 1], &sf->extramask[i]);
-    }
+       }
 
-    for (i = 0; i < 8; i++) {
+       for (i = 0; i < 8; i++) {
         __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
-    }
-    for (i = 0; i < 8; i++) {
+       }
+       for (i = 0; i < 8; i++) {
         __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
-    }
-    if (err)
-        goto sigsegv;
-
-    /* 3. signal handler back-trampoline and parameters */
-    env->regwptr[UREG_FP] = sf_addr;
-    env->regwptr[UREG_I0] = sig;
-    env->regwptr[UREG_I1] = sf_addr +
-            offsetof(struct target_signal_frame, info);
-    env->regwptr[UREG_I2] = sf_addr +
-            offsetof(struct target_signal_frame, info);
-
-    /* 4. signal handler */
-    env->pc = ka->_sa_handler;
-    env->npc = (env->pc + 4);
-    /* 5. return to kernel instructions */
-    if (ka->sa_restorer) {
-        env->regwptr[UREG_I7] = ka->sa_restorer;
-    } else {
-        uint32_t val32;
-
-        env->regwptr[UREG_I7] = sf_addr +
-                offsetof(struct target_signal_frame, insns) - 2 * 4;
-
-        /* mov __NR_sigreturn, %g1 */
-        val32 = 0x821020d8;
+       }
+       if (err)
+               goto sigsegv;
+
+       /* 3. signal handler back-trampoline and parameters */
+       env->regwptr[UREG_FP] = sf_addr;
+       env->regwptr[UREG_I0] = sig;
+       env->regwptr[UREG_I1] = sf_addr + 
+                offsetof(struct target_signal_frame, info);
+       env->regwptr[UREG_I2] = sf_addr + 
+                offsetof(struct target_signal_frame, info);
+
+       /* 4. signal handler */
+       env->pc = ka->_sa_handler;
+       env->npc = (env->pc + 4);
+       /* 5. return to kernel instructions */
+       if (ka->sa_restorer)
+               env->regwptr[UREG_I7] = ka->sa_restorer;
+       else {
+                uint32_t val32;
+
+               env->regwptr[UREG_I7] = sf_addr + 
+                        offsetof(struct target_signal_frame, insns) - 2 * 4;
+
+               /* mov __NR_sigreturn, %g1 */
+                val32 = 0x821020d8;
         __put_user(val32, &sf->insns[0]);
 
-        /* t 0x10 */
-        val32 = 0x91d02010;
+               /* t 0x10 */
+                val32 = 0x91d02010;
         __put_user(val32, &sf->insns[1]);
-        if (err)
-            goto sigsegv;
+               if (err)
+                       goto sigsegv;
 
-        /* Flush instruction space. */
-        // flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
-        // tb_flush(env);
-    }
-    unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
-    return;
+               /* Flush instruction space. */
+               //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
+                //             tb_flush(CPU(sparc_env_get_cpu(env)));
+       }
+        unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
+       return;
 #if 0
 sigill_and_return:
-    force_sig(TARGET_SIGILL);
+       force_sig(TARGET_SIGILL);
 #endif
 sigsegv:
-    unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
-    force_sig(TARGET_SIGSEGV);
+        unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
+       force_sig(TARGET_SIGSEGV);
 }
 
 static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -2457,74 +2369,71 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
 long do_sigreturn(CPUSPARCState *env)
 {
-    abi_ulong sf_addr;
-    struct target_signal_frame *sf;
-    uint32_t up_psr, pc, npc;
-    target_sigset_t set;
-    sigset_t host_set;
-    int err=0, i;
+        abi_ulong sf_addr;
+        struct target_signal_frame *sf;
+        uint32_t up_psr, pc, npc;
+        target_sigset_t set;
+        sigset_t host_set;
+        int err=0, i;
 
-    sf_addr = env->regwptr[UREG_FP];
-    trace_user_do_sigreturn(env, sf_addr);
-    if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1)) {
-        goto segv_and_exit;
-    }
+        sf_addr = env->regwptr[UREG_FP];
+        trace_user_do_sigreturn(env, sf_addr);
+        if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
+                goto segv_and_exit;
 
-    /* 1. Make sure we are not getting garbage from the user */
+        /* 1. Make sure we are not getting garbage from the user */
 
-    if (sf_addr & 3)
-        goto segv_and_exit;
+        if (sf_addr & 3)
+                goto segv_and_exit;
 
-    __get_user(pc,  &sf->info.si_regs.pc);
-    __get_user(npc, &sf->info.si_regs.npc);
+        __get_user(pc,  &sf->info.si_regs.pc);
+        __get_user(npc, &sf->info.si_regs.npc);
 
-    if ((pc | npc) & 3) {
-        goto segv_and_exit;
-    }
+        if ((pc | npc) & 3)
+                goto segv_and_exit;
 
-    /* 2. Restore the state */
-    __get_user(up_psr, &sf->info.si_regs.psr);
+        /* 2. Restore the state */
+        __get_user(up_psr, &sf->info.si_regs.psr);
 
-    /* User can only change condition codes and FPU enabling in %psr. */
-    env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
-            | (env->psr & ~(PSR_ICC /* | PSR_EF */));
+        /* User can only change condition codes and FPU enabling in %psr. */
+        env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
+                  | (env->psr & ~(PSR_ICC /* | PSR_EF */));
 
-    env->pc = pc;
-    env->npc = npc;
-    __get_user(env->y, &sf->info.si_regs.y);
-    for (i=0; i < 8; i++) {
-        __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
-    }
-    for (i=0; i < 8; i++) {
-        __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
-    }
+       env->pc = pc;
+       env->npc = npc;
+        __get_user(env->y, &sf->info.si_regs.y);
+       for (i=0; i < 8; i++) {
+               __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
+       }
+       for (i=0; i < 8; i++) {
+               __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
+       }
 
-    /* FIXME: implement FPU save/restore:
+        /* FIXME: implement FPU save/restore:
          * __get_user(fpu_save, &sf->fpu_save);
          * if (fpu_save)
          *        err |= restore_fpu_state(env, fpu_save);
          */
 
-    /* This is pretty much atomic, no amount locking would prevent
+        /* This is pretty much atomic, no amount locking would prevent
          * the races which exist anyways.
          */
-    __get_user(set.sig[0], &sf->info.si_mask);
-    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
-        __get_user(set.sig[i], &sf->extramask[i - 1]);
-    }
+        __get_user(set.sig[0], &sf->info.si_mask);
+        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
+            __get_user(set.sig[i], &sf->extramask[i - 1]);
+        }
 
-    target_to_host_sigset_internal(&host_set, &set);
-    set_sigmask(&host_set);
+        target_to_host_sigset_internal(&host_set, &set);
+        do_sigprocmask(SIG_SETMASK, &host_set, NULL);
 
-    if (err) {
-        goto segv_and_exit;
-    }
-    unlock_user_struct(sf, sf_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+        if (err)
+                goto segv_and_exit;
+        unlock_user_struct(sf, sf_addr, 0);
+        return env->regwptr[0];
 
 segv_and_exit:
-    unlock_user_struct(sf, sf_addr, 0);
-    force_sig(TARGET_SIGSEGV);
+        unlock_user_struct(sf, sf_addr, 0);
+       force_sig(TARGET_SIGSEGV);
 }
 
 long do_rt_sigreturn(CPUSPARCState *env)
@@ -2613,15 +2522,13 @@ void sparc64_set_context(CPUSPARCState *env)
     unsigned int i;
 
     ucp_addr = env->regwptr[UREG_I0];
-    if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1)) {
+    if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
         goto do_sigsegv;
-    }
     grp  = &ucp->tuc_mcontext.mc_gregs;
     __get_user(pc, &((*grp)[MC_PC]));
     __get_user(npc, &((*grp)[MC_NPC]));
-    if ((pc | npc) & 3) {
+    if ((pc | npc) & 3)
         goto do_sigsegv;
-    }
     if (env->regwptr[UREG_I1]) {
         target_sigset_t target_set;
         sigset_t set;
@@ -2637,7 +2544,7 @@ void sparc64_set_context(CPUSPARCState *env)
             }
         }
         target_to_host_sigset_internal(&set, &target_set);
-        set_sigmask(&set);
+        do_sigprocmask(SIG_SETMASK, &set, NULL);
     }
     env->pc = pc;
     env->npc = npc;
@@ -2666,14 +2573,12 @@ void sparc64_set_context(CPUSPARCState *env)
     __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
 
     w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
-    if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
-                 abi_ulong) != 0) {
+    if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
+                 abi_ulong) != 0)
         goto do_sigsegv;
-    }
-    if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
-                 abi_ulong) != 0) {
+    if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
+                 abi_ulong) != 0)
         goto do_sigsegv;
-    }
     /* FIXME this does not match how the kernel handles the FPU in
      * its sparc64_set_context implementation. In particular the FPU
      * is only restored if fenab is non-zero in:
@@ -2696,7 +2601,7 @@ void sparc64_set_context(CPUSPARCState *env)
                &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
     unlock_user_struct(ucp, ucp_addr, 0);
     return;
-do_sigsegv:
+ do_sigsegv:
     unlock_user_struct(ucp, ucp_addr, 0);
     force_sig(TARGET_SIGSEGV);
 }
@@ -2714,9 +2619,8 @@ void sparc64_get_context(CPUSPARCState *env)
     sigset_t set;
 
     ucp_addr = env->regwptr[UREG_I0];
-    if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0)) {
+    if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
         goto do_sigsegv;
-    }
     
     mcp = &ucp->tuc_mcontext;
     grp = &mcp->mc_gregs;
@@ -2725,13 +2629,9 @@ void sparc64_get_context(CPUSPARCState *env)
     env->pc = env->npc;
     env->npc += 4;
 
-    /* If we're only reading the signal mask then do_sigprocmask()
-     * is guaranteed not to fail, which is important because we don't
-     * have any way to signal a failure or restart this operation since
-     * this is not a normal syscall.
-     */
-    err = do_sigprocmask(0, NULL, &set);
-    assert(err == 0);
+    err = 0;
+
+    do_sigprocmask(0, NULL, &set);
     host_to_target_sigset_internal(&target_set, &set);
     if (TARGET_NSIG_WORDS == 1) {
         __put_user(target_set.sig[0],
@@ -2770,14 +2670,12 @@ void sparc64_get_context(CPUSPARCState *env)
 
     w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
     fp = i7 = 0;
-    if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
-                 abi_ulong) != 0) {
+    if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
+                 abi_ulong) != 0)
         goto do_sigsegv;
-    }
-    if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
-                 abi_ulong) != 0) {
+    if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
+                 abi_ulong) != 0)
         goto do_sigsegv;
-    }
     __put_user(fp, &(mcp->mc_fp));
     __put_user(i7, &(mcp->mc_i7));
 
@@ -2799,7 +2697,7 @@ void sparc64_get_context(CPUSPARCState *env)
         goto do_sigsegv;
     unlock_user_struct(ucp, ucp_addr, 1);
     return;
-do_sigsegv:
+ do_sigsegv:
     unlock_user_struct(ucp, ucp_addr, 1);
     force_sig(TARGET_SIGSEGV);
 }
@@ -2889,7 +2787,7 @@ static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
 }
 
 static inline void setup_sigcontext(CPUMIPSState *regs,
-                                    struct target_sigcontext *sc)
+        struct target_sigcontext *sc)
 {
     int i;
 
@@ -3001,9 +2899,8 @@ static void setup_frame(int sig, struct target_sigaction * ka,
 
     frame_addr = get_sigframe(ka, regs, sizeof(*frame));
     trace_user_setup_frame(regs, frame_addr);
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        goto give_sigsegv;
-    }
+    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+       goto give_sigsegv;
 
     install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
 
@@ -3051,14 +2948,14 @@ long do_sigreturn(CPUMIPSState *regs)
     frame_addr = regs->active_tc.gpr[29];
     trace_user_do_sigreturn(regs, frame_addr);
     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
-        goto badframe;
+       goto badframe;
 
     for(i = 0; i < TARGET_NSIG_WORDS; i++) {
         __get_user(target_set.sig[i], &frame->sf_mask.sig[i]);
     }
 
     target_to_host_sigset_internal(&blocked, &target_set);
-    set_sigmask(&blocked);
+    do_sigprocmask(SIG_SETMASK, &blocked, NULL);
 
     restore_sigcontext(regs, &frame->sf_sc);
 
@@ -3097,9 +2994,8 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
     frame_addr = get_sigframe(ka, env, sizeof(*frame));
     trace_user_setup_rt_frame(env, frame_addr);
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        goto give_sigsegv;
-    }
+    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+       goto give_sigsegv;
 
     install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
 
@@ -3157,18 +3053,17 @@ long do_rt_sigreturn(CPUMIPSState *env)
 
     frame_addr = env->active_tc.gpr[29];
     trace_user_do_rt_sigreturn(env, frame_addr);
-    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
-        goto badframe;
-    }
+    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
+       goto badframe;
 
     target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
-    set_sigmask(&blocked);
+    do_sigprocmask(SIG_SETMASK, &blocked, NULL);
 
     restore_sigcontext(env, &frame->rs_uc.tuc_mcontext);
 
     if (do_sigaltstack(frame_addr +
-                       offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
-                       0, get_sp_from_cpustate(env)) == -EFAULT)
+                      offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
+                      0, get_sp_from_cpustate(env)) == -EFAULT)
         goto badframe;
 
     env->active_tc.PC = env->CP0_EPC;
@@ -3239,7 +3134,7 @@ struct target_rt_sigframe
 #define TRAP_NOARG 0xc310         /* Syscall w/no args (NR in R3) SH3/4 */
 
 static abi_ulong get_sigframe(struct target_sigaction *ka,
-                              unsigned long sp, size_t frame_size)
+                         unsigned long sp, size_t frame_size)
 {
     if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
         sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
@@ -3249,7 +3144,7 @@ static abi_ulong get_sigframe(struct target_sigaction *ka,
 }
 
 static void setup_sigcontext(struct target_sigcontext *sc,
-                             CPUSH4State *regs, unsigned long mask)
+                            CPUSH4State *regs, unsigned long mask)
 {
     int i;
 
@@ -3277,12 +3172,13 @@ static void setup_sigcontext(struct target_sigcontext *sc,
     __put_user(mask, &sc->oldmask);
 }
 
-static void restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc)
+static void restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc,
+                              target_ulong *r0_p)
 {
     int i;
 
 #define COPY(x)         __get_user(regs->x, &sc->sc_##x)
-    COPY(gregs[0]); COPY(gregs[1]);
+    COPY(gregs[1]);
     COPY(gregs[2]); COPY(gregs[3]);
     COPY(gregs[4]); COPY(gregs[5]);
     COPY(gregs[6]); COPY(gregs[7]);
@@ -3302,6 +3198,7 @@ static void restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc)
     __get_user(regs->fpul, &sc->sc_fpul);
 
     regs->tra = -1;         /* disable syscall checks */
+    __get_user(*r0_p, &sc->sc_gregs[0]);
 }
 
 static void setup_frame(int sig, struct target_sigaction *ka,
@@ -3313,9 +3210,8 @@ static void setup_frame(int sig, struct target_sigaction *ka,
 
     frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
     trace_user_setup_frame(regs, frame_addr);
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        goto give_sigsegv;
-    }
+    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+       goto give_sigsegv;
 
     setup_sigcontext(&frame->sc, regs, set->sig[0]);
 
@@ -3362,9 +3258,8 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
     frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
     trace_user_setup_rt_frame(regs, frame_addr);
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        goto give_sigsegv;
-    }
+    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+       goto give_sigsegv;
 
     tswap_siginfo(&frame->info, info);
 
@@ -3378,7 +3273,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
     __put_user(target_sigaltstack_used.ss_size,
                &frame->uc.tuc_stack.ss_size);
     setup_sigcontext(&frame->uc.tuc_mcontext,
-                     regs, set->sig[0]);
+                           regs, set->sig[0]);
     for(i = 0; i < TARGET_NSIG_WORDS; i++) {
         __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
     }
@@ -3418,14 +3313,14 @@ long do_sigreturn(CPUSH4State *regs)
     abi_ulong frame_addr;
     sigset_t blocked;
     target_sigset_t target_set;
+    target_ulong r0;
     int i;
     int err = 0;
 
     frame_addr = regs->gregs[15];
     trace_user_do_sigreturn(regs, frame_addr);
-    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
-        goto badframe;
-    }
+    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
+       goto badframe;
 
     __get_user(target_set.sig[0], &frame->sc.oldmask);
     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
@@ -3436,12 +3331,12 @@ long do_sigreturn(CPUSH4State *regs)
         goto badframe;
 
     target_to_host_sigset_internal(&blocked, &target_set);
-    set_sigmask(&blocked);
+    do_sigprocmask(SIG_SETMASK, &blocked, NULL);
 
-    restore_sigcontext(regs, &frame->sc);
+    restore_sigcontext(regs, &frame->sc, &r0);
 
     unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+    return r0;
 
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
@@ -3454,26 +3349,25 @@ long do_rt_sigreturn(CPUSH4State *regs)
     struct target_rt_sigframe *frame;
     abi_ulong frame_addr;
     sigset_t blocked;
+    target_ulong r0;
 
     frame_addr = regs->gregs[15];
     trace_user_do_rt_sigreturn(regs, frame_addr);
-    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
-        goto badframe;
-    }
+    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
+       goto badframe;
 
     target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
-    set_sigmask(&blocked);
+    do_sigprocmask(SIG_SETMASK, &blocked, NULL);
 
-    restore_sigcontext(regs, &frame->uc.tuc_mcontext);
+    restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0);
 
     if (do_sigaltstack(frame_addr +
-                       offsetof(struct target_rt_sigframe, uc.tuc_stack),
-                       0, get_sp_from_cpustate(regs)) == -EFAULT) {
+                      offsetof(struct target_rt_sigframe, uc.tuc_stack),
+                      0, get_sp_from_cpustate(regs)) == -EFAULT)
         goto badframe;
-    }
 
     unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+    return r0;
 
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
@@ -3638,8 +3532,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
 
         /* Return from sighandler will jump to the tramp.
            Negative 8 offset because return is rtsd r15, 8 */
-        env->regs[15] = frame_addr + offsetof(struct target_signal_frame, tramp)
-                                   - 8;
+        env->regs[15] = ((unsigned long)frame->tramp) - 8;
     }
 
     /* Set up registers for signal handler */
@@ -3655,7 +3548,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
 
     unlock_user_struct(frame, frame_addr, 1);
     return;
-badframe:
+  badframe:
     force_sig(TARGET_SIGSEGV);
 }
 
@@ -3683,19 +3576,19 @@ long do_sigreturn(CPUMBState *env)
     /* Restore blocked signals */
     __get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask);
     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
-        __get_user(target_set.sig[i], &frame->extramask[i - 1]);
+       __get_user(target_set.sig[i], &frame->extramask[i - 1]);
     }
     target_to_host_sigset_internal(&set, &target_set);
-    set_sigmask(&set);
+    do_sigprocmask(SIG_SETMASK, &set, NULL);
 
     restore_sigcontext(&frame->uc.tuc_mcontext, env);
     /* We got here through a sigreturn syscall, our path back is via an
        rtb insn so setup r14 for that.  */
     env->regs[14] = env->sregs[SR_PC];
-
     unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
-badframe:
+    return env->regs[10];
+  badframe:
     force_sig(TARGET_SIGSEGV);
 }
 
@@ -3709,124 +3602,124 @@ long do_rt_sigreturn(CPUMBState *env)
 #elif defined(TARGET_CRIS)
 
 struct target_sigcontext {
-    struct target_pt_regs regs;  /* needs to be first */
-    uint32_t oldmask;
-    uint32_t usp;    /* usp before stacking this gunk on it */
+        struct target_pt_regs regs;  /* needs to be first */
+        uint32_t oldmask;
+        uint32_t usp;    /* usp before stacking this gunk on it */
 };
 
 /* Signal frames. */
 struct target_signal_frame {
-    struct target_sigcontext sc;
-    uint32_t extramask[TARGET_NSIG_WORDS - 1];
-    uint16_t retcode[4];      /* Trampoline code. */
+        struct target_sigcontext sc;
+        uint32_t extramask[TARGET_NSIG_WORDS - 1];
+        uint16_t retcode[4];      /* Trampoline code. */
 };
 
 struct rt_signal_frame {
-    siginfo_t *pinfo;
-    void *puc;
-    siginfo_t info;
-    struct ucontext uc;
-    uint16_t retcode[4];      /* Trampoline code. */
+        siginfo_t *pinfo;
+        void *puc;
+        siginfo_t info;
+        struct ucontext uc;
+        uint16_t retcode[4];      /* Trampoline code. */
 };
 
 static void setup_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
 {
-    __put_user(env->regs[0], &sc->regs.r0);
-    __put_user(env->regs[1], &sc->regs.r1);
-    __put_user(env->regs[2], &sc->regs.r2);
-    __put_user(env->regs[3], &sc->regs.r3);
-    __put_user(env->regs[4], &sc->regs.r4);
-    __put_user(env->regs[5], &sc->regs.r5);
-    __put_user(env->regs[6], &sc->regs.r6);
-    __put_user(env->regs[7], &sc->regs.r7);
-    __put_user(env->regs[8], &sc->regs.r8);
-    __put_user(env->regs[9], &sc->regs.r9);
-    __put_user(env->regs[10], &sc->regs.r10);
-    __put_user(env->regs[11], &sc->regs.r11);
-    __put_user(env->regs[12], &sc->regs.r12);
-    __put_user(env->regs[13], &sc->regs.r13);
-    __put_user(env->regs[14], &sc->usp);
-    __put_user(env->regs[15], &sc->regs.acr);
-    __put_user(env->pregs[PR_MOF], &sc->regs.mof);
-    __put_user(env->pregs[PR_SRP], &sc->regs.srp);
-    __put_user(env->pc, &sc->regs.erp);
+       __put_user(env->regs[0], &sc->regs.r0);
+       __put_user(env->regs[1], &sc->regs.r1);
+       __put_user(env->regs[2], &sc->regs.r2);
+       __put_user(env->regs[3], &sc->regs.r3);
+       __put_user(env->regs[4], &sc->regs.r4);
+       __put_user(env->regs[5], &sc->regs.r5);
+       __put_user(env->regs[6], &sc->regs.r6);
+       __put_user(env->regs[7], &sc->regs.r7);
+       __put_user(env->regs[8], &sc->regs.r8);
+       __put_user(env->regs[9], &sc->regs.r9);
+       __put_user(env->regs[10], &sc->regs.r10);
+       __put_user(env->regs[11], &sc->regs.r11);
+       __put_user(env->regs[12], &sc->regs.r12);
+       __put_user(env->regs[13], &sc->regs.r13);
+       __put_user(env->regs[14], &sc->usp);
+       __put_user(env->regs[15], &sc->regs.acr);
+       __put_user(env->pregs[PR_MOF], &sc->regs.mof);
+       __put_user(env->pregs[PR_SRP], &sc->regs.srp);
+       __put_user(env->pc, &sc->regs.erp);
 }
 
 static void restore_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
 {
-    __get_user(env->regs[0], &sc->regs.r0);
-    __get_user(env->regs[1], &sc->regs.r1);
-    __get_user(env->regs[2], &sc->regs.r2);
-    __get_user(env->regs[3], &sc->regs.r3);
-    __get_user(env->regs[4], &sc->regs.r4);
-    __get_user(env->regs[5], &sc->regs.r5);
-    __get_user(env->regs[6], &sc->regs.r6);
-    __get_user(env->regs[7], &sc->regs.r7);
-    __get_user(env->regs[8], &sc->regs.r8);
-    __get_user(env->regs[9], &sc->regs.r9);
-    __get_user(env->regs[10], &sc->regs.r10);
-    __get_user(env->regs[11], &sc->regs.r11);
-    __get_user(env->regs[12], &sc->regs.r12);
-    __get_user(env->regs[13], &sc->regs.r13);
-    __get_user(env->regs[14], &sc->usp);
-    __get_user(env->regs[15], &sc->regs.acr);
-    __get_user(env->pregs[PR_MOF], &sc->regs.mof);
-    __get_user(env->pregs[PR_SRP], &sc->regs.srp);
-    __get_user(env->pc, &sc->regs.erp);
+       __get_user(env->regs[0], &sc->regs.r0);
+       __get_user(env->regs[1], &sc->regs.r1);
+       __get_user(env->regs[2], &sc->regs.r2);
+       __get_user(env->regs[3], &sc->regs.r3);
+       __get_user(env->regs[4], &sc->regs.r4);
+       __get_user(env->regs[5], &sc->regs.r5);
+       __get_user(env->regs[6], &sc->regs.r6);
+       __get_user(env->regs[7], &sc->regs.r7);
+       __get_user(env->regs[8], &sc->regs.r8);
+       __get_user(env->regs[9], &sc->regs.r9);
+       __get_user(env->regs[10], &sc->regs.r10);
+       __get_user(env->regs[11], &sc->regs.r11);
+       __get_user(env->regs[12], &sc->regs.r12);
+       __get_user(env->regs[13], &sc->regs.r13);
+       __get_user(env->regs[14], &sc->usp);
+       __get_user(env->regs[15], &sc->regs.acr);
+       __get_user(env->pregs[PR_MOF], &sc->regs.mof);
+       __get_user(env->pregs[PR_SRP], &sc->regs.srp);
+       __get_user(env->pc, &sc->regs.erp);
 }
 
 static abi_ulong get_sigframe(CPUCRISState *env, int framesize)
 {
-    abi_ulong sp;
-    /* Align the stack downwards to 4.  */
-    sp = (env->regs[R_SP] & ~3);
-    return sp - framesize;
+       abi_ulong sp;
+       /* Align the stack downwards to 4.  */
+       sp = (env->regs[R_SP] & ~3);
+       return sp - framesize;
 }
 
 static void setup_frame(int sig, struct target_sigaction *ka,
                         target_sigset_t *set, CPUCRISState *env)
 {
-    struct target_signal_frame *frame;
-    abi_ulong frame_addr;
-    int i;
-
-    frame_addr = get_sigframe(env, sizeof *frame);
-    trace_user_setup_frame(env, frame_addr);
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
-        goto badframe;
-
-    /*
-     * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
-     * use this trampoline anymore but it sets it up for GDB.
-     * In QEMU, using the trampoline simplifies things a bit so we use it.
-     *
-     * This is movu.w __NR_sigreturn, r9; break 13;
-     */
+       struct target_signal_frame *frame;
+       abi_ulong frame_addr;
+       int i;
+
+       frame_addr = get_sigframe(env, sizeof *frame);
+        trace_user_setup_frame(env, frame_addr);
+       if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+               goto badframe;
+
+       /*
+        * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
+        * use this trampoline anymore but it sets it up for GDB.
+        * In QEMU, using the trampoline simplifies things a bit so we use it.
+        *
+        * This is movu.w __NR_sigreturn, r9; break 13;
+        */
     __put_user(0x9c5f, frame->retcode+0);
     __put_user(TARGET_NR_sigreturn,
                frame->retcode + 1);
     __put_user(0xe93d, frame->retcode + 2);
 
-    /* Save the mask.  */
+       /* Save the mask.  */
     __put_user(set->sig[0], &frame->sc.oldmask);
 
     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
         __put_user(set->sig[i], &frame->extramask[i - 1]);
     }
 
-    setup_sigcontext(&frame->sc, env);
+       setup_sigcontext(&frame->sc, env);
 
-    /* Move the stack and setup the arguments for the handler.  */
-    env->regs[R_SP] = frame_addr;
-    env->regs[10] = sig;
-    env->pc = (unsigned long) ka->_sa_handler;
-    /* Link SRP so the guest returns through the trampoline.  */
-    env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode);
+       /* Move the stack and setup the arguments for the handler.  */
+       env->regs[R_SP] = frame_addr;
+       env->regs[10] = sig;
+       env->pc = (unsigned long) ka->_sa_handler;
+       /* Link SRP so the guest returns through the trampoline.  */
+       env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode);
 
-    unlock_user_struct(frame, frame_addr, 1);
-    return;
-badframe:
-    force_sig(TARGET_SIGSEGV);
+       unlock_user_struct(frame, frame_addr, 1);
+       return;
+  badframe:
+       force_sig(TARGET_SIGSEGV);
 }
 
 static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -3838,32 +3731,31 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
 long do_sigreturn(CPUCRISState *env)
 {
-    struct target_signal_frame *frame;
-    abi_ulong frame_addr;
-    target_sigset_t target_set;
-    sigset_t set;
-    int i;
+       struct target_signal_frame *frame;
+       abi_ulong frame_addr;
+       target_sigset_t target_set;
+       sigset_t set;
+       int i;
 
-    frame_addr = env->regs[R_SP];
-    trace_user_do_sigreturn(env, frame_addr);
-    /* Make sure the guest isn't playing games.  */
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1)) {
-        goto badframe;
-    }
+       frame_addr = env->regs[R_SP];
+        trace_user_do_sigreturn(env, frame_addr);
+       /* Make sure the guest isn't playing games.  */
+       if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
+               goto badframe;
 
-    /* Restore blocked signals */
+       /* Restore blocked signals */
     __get_user(target_set.sig[0], &frame->sc.oldmask);
-    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
+       for(i = 1; i < TARGET_NSIG_WORDS; i++) {
         __get_user(target_set.sig[i], &frame->extramask[i - 1]);
-    }
-    target_to_host_sigset_internal(&set, &target_set);
-    set_sigmask(&set);
+       }
+       target_to_host_sigset_internal(&set, &target_set);
+        do_sigprocmask(SIG_SETMASK, &set, NULL);
 
-    restore_sigcontext(&frame->sc, env);
-    unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
-badframe:
-    force_sig(TARGET_SIGSEGV);
+       restore_sigcontext(&frame->sc, env);
+       unlock_user_struct(frame, frame_addr, 0);
+       return env->regs[10];
+  badframe:
+       force_sig(TARGET_SIGSEGV);
 }
 
 long do_rt_sigreturn(CPUCRISState *env)
@@ -3949,8 +3841,8 @@ badframe:
 /* Set up a signal frame.  */
 
 static void setup_sigcontext(struct target_sigcontext *sc,
-                             CPUOpenRISCState *regs,
-                             unsigned long mask)
+                            CPUOpenRISCState *regs,
+                            unsigned long mask)
 {
     unsigned long usp = regs->gpr[1];
 
@@ -3970,7 +3862,9 @@ static void setup_sigcontext(struct target_sigcontext *sc,
 
 static inline unsigned long align_sigframe(unsigned long sp)
 {
-    return sp & ~3UL;
+    unsigned long i;
+    i = sp & ~3UL;
+    return i;
 }
 
 static inline abi_ulong get_sigframe(struct target_sigaction *ka,
@@ -4206,7 +4100,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
     frame_addr = get_sigframe(ka, env, sizeof(*frame));
     trace_user_setup_frame(env, frame_addr);
     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        goto give_sigsegv;
+            goto give_sigsegv;
     }
 
     __put_user(set->sig[0], &frame->sc.oldmask[0]);
@@ -4219,13 +4113,13 @@ static void setup_frame(int sig, struct target_sigaction *ka,
     /* Set up to return from userspace.  If provided, use a stub
        already in userspace.  */
     if (ka->sa_flags & TARGET_SA_RESTORER) {
-        env->regs[14] = (unsigned long)
-                ka->sa_restorer | PSW_ADDR_AMODE;
+            env->regs[14] = (unsigned long)
+                    ka->sa_restorer | PSW_ADDR_AMODE;
     } else {
-        env->regs[14] = (frame_addr + offsetof(sigframe, retcode))
-                        | PSW_ADDR_AMODE;
-        __put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
-                   (uint16_t *)(frame->retcode));
+            env->regs[14] = (unsigned long)
+                    frame->retcode | PSW_ADDR_AMODE;
+            __put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
+                       (uint16_t *)(frame->retcode));
     }
 
     /* Set up backchain. */
@@ -4273,12 +4167,12 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
     __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
     __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
     __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
-               &frame->uc.tuc_stack.ss_flags);
+                      &frame->uc.tuc_stack.ss_flags);
     __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
     save_sigregs(env, &frame->uc.tuc_mcontext);
     for (i = 0; i < TARGET_NSIG_WORDS; i++) {
         __put_user((abi_ulong)set->sig[i],
-                   (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
+        (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
     }
 
     /* Set up to return from userspace.  If provided, use a stub
@@ -4347,14 +4241,14 @@ long do_sigreturn(CPUS390XState *env)
     __get_user(target_set.sig[0], &frame->sc.oldmask[0]);
 
     target_to_host_sigset_internal(&set, &target_set);
-    set_sigmask(&set); /* ~_BLOCKABLE? */
+    do_sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
 
     if (restore_sigregs(env, &frame->sregs)) {
         goto badframe;
     }
 
     unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+    return env->regs[2];
 
 badframe:
     force_sig(TARGET_SIGSEGV);
@@ -4373,7 +4267,7 @@ long do_rt_sigreturn(CPUS390XState *env)
     }
     target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
 
-    set_sigmask(&set); /* ~_BLOCKABLE? */
+    do_sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
 
     if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
         goto badframe;
@@ -4384,7 +4278,7 @@ long do_rt_sigreturn(CPUS390XState *env)
         goto badframe;
     }
     unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+    return env->regs[2];
 
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
@@ -4529,15 +4423,15 @@ struct target_sigframe {
 #define TARGET_TRAMP_SIZE 6
 
 struct target_rt_sigframe {
-    /* sys_rt_sigreturn requires the ucontext be the first field */
-    struct target_ucontext uc;
-    target_ulong  _unused[2];
-    uint32_t trampoline[TARGET_TRAMP_SIZE];
-    target_ulong pinfo; /* struct siginfo __user * */
-    target_ulong puc; /* void __user * */
-    struct target_siginfo info;
-    /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
-    char abigap[288];
+        /* sys_rt_sigreturn requires the ucontext be the first field */
+        struct target_ucontext uc;
+        target_ulong  _unused[2];
+        uint32_t trampoline[TARGET_TRAMP_SIZE];
+        target_ulong pinfo; /* struct siginfo __user * */
+        target_ulong puc; /* void __user * */
+        struct target_siginfo info;
+        /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
+        char abigap[288];
 } __attribute__((aligned(16)));
 
 #else
@@ -4567,17 +4461,19 @@ static target_ulong get_sigframe(struct target_sigaction *ka,
                                  CPUPPCState *env,
                                  int frame_size)
 {
-    target_ulong oldsp;
+    target_ulong oldsp, newsp;
 
     oldsp = env->gpr[1];
 
     if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
-            (sas_ss_flags(oldsp) == 0)) {
+        (sas_ss_flags(oldsp) == 0)) {
         oldsp = (target_sigaltstack_used.ss_sp
                  + target_sigaltstack_used.ss_size);
     }
 
-    return (oldsp - frame_size) & ~0xFUL;
+    newsp = (oldsp - frame_size) & ~0xFUL;
+
+    return newsp;
 }
 
 static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame)
@@ -4592,7 +4488,7 @@ static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame)
 
     /* Save general registers.  */
     for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
-        __put_user(env->gpr[i], &frame->mc_gregs[i]);
+       __put_user(env->gpr[i], &frame->mc_gregs[i]);
     }
     __put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP]);
     __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR]);
@@ -4693,7 +4589,7 @@ static void restore_user_regs(CPUPPCState *env,
 
     /* If doing signal return, restore the previous little-endian mode.  */
     if (sig)
-        env->msr = (env->msr & ~(1ull << MSR_LE)) | (msr & (1ull << MSR_LE));
+        env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
 
     /* Restore Altivec registers if necessary.  */
     if (env->insns_flags & PPC_ALTIVEC) {
@@ -4808,7 +4704,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
 #endif
 
     /* Signal handlers are entered in big-endian mode.  */
-    env->msr &= ~(1ull << MSR_LE);
+    env->msr &= ~MSR_LE;
 
     unlock_user_struct(frame, frame_addr, 1);
     return;
@@ -4903,7 +4799,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 #endif
 
     /* Signal handlers are entered in big-endian mode.  */
-    env->msr &= ~(1ull << MSR_LE);
+    env->msr &= ~MSR_LE;
 
     unlock_user_struct(rt_sf, rt_sf_addr, 1);
     return;
@@ -4933,7 +4829,7 @@ long do_sigreturn(CPUPPCState *env)
     __get_user(set.sig[1], &sc->_unused[3]);
 #endif
     target_to_host_sigset_internal(&blocked, &set);
-    set_sigmask(&blocked);
+    do_sigprocmask(SIG_SETMASK, &blocked, NULL);
 
     __get_user(sr_addr, &sc->regs);
     if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
@@ -4974,7 +4870,7 @@ static int do_setcontext(struct target_ucontext *ucp, CPUPPCState *env, int sig)
         return 1;
 
     target_to_host_sigset_internal(&blocked, &set);
-    set_sigmask(&blocked);
+    do_sigprocmask(SIG_SETMASK, &blocked, NULL);
     restore_user_regs(env, mcp, sig);
 
     unlock_user_struct(mcp, mcp_addr, 1);
@@ -5029,7 +4925,7 @@ struct target_sigframe
     abi_ulong extramask[TARGET_NSIG_WORDS-1];
     struct target_sigcontext sc;
 };
-
 typedef int target_greg_t;
 #define TARGET_NGREG 18
 typedef target_greg_t target_gregset_t[TARGET_NGREG];
@@ -5068,7 +4964,7 @@ struct target_rt_sigframe
 };
 
 static void setup_sigcontext(struct target_sigcontext *sc, CPUM68KState *env,
-                             abi_ulong mask)
+        abi_ulong mask)
 {
     __put_user(mask, &sc->sc_mask);
     __put_user(env->aregs[7], &sc->sc_usp);
@@ -5081,18 +4977,19 @@ static void setup_sigcontext(struct target_sigcontext *sc, CPUM68KState *env,
 }
 
 static void
-restore_sigcontext(CPUM68KState *env, struct target_sigcontext *sc)
+restore_sigcontext(CPUM68KState *env, struct target_sigcontext *sc, int *pd0)
 {
     int temp;
 
     __get_user(env->aregs[7], &sc->sc_usp);
-    __get_user(env->dregs[0], &sc->sc_d0);
     __get_user(env->dregs[1], &sc->sc_d1);
     __get_user(env->aregs[0], &sc->sc_a0);
     __get_user(env->aregs[1], &sc->sc_a1);
     __get_user(env->pc, &sc->sc_pc);
     __get_user(temp, &sc->sc_sr);
     env->sr = (env->sr & 0xff00) | (temp & 0xff);
+
+    *pd0 = tswapl(sc->sc_d0);
 }
 
 /*
@@ -5125,9 +5022,8 @@ static void setup_frame(int sig, struct target_sigaction *ka,
 
     frame_addr = get_sigframe(ka, env, sizeof *frame);
     trace_user_setup_frame(env, frame_addr);
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        goto give_sigsegv;
-    }
+    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+       goto give_sigsegv;
 
     __put_user(sig, &frame->sig);
 
@@ -5148,7 +5044,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
     /* moveq #,d0; trap #0 */
 
     __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
-               (uint32_t *)(frame->retcode));
+                      (uint32_t *)(frame->retcode));
 
     /* Set up to return from userspace */
 
@@ -5189,9 +5085,10 @@ static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
 
     return 0;
 }
-
 static inline int target_rt_restore_ucontext(CPUM68KState *env,
-                                             struct target_ucontext *uc)
+                                             struct target_ucontext *uc,
+                                             int *pd0)
 {
     int temp;
     target_greg_t *gregs = uc->tuc_mcontext.gregs;
@@ -5221,6 +5118,7 @@ static inline int target_rt_restore_ucontext(CPUM68KState *env,
     __get_user(temp, &gregs[17]);
     env->sr = (env->sr & 0xff00) | (temp & 0xff);
 
+    *pd0 = env->dregs[0];
     return 0;
 
 badframe:
@@ -5241,9 +5139,8 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
     frame_addr = get_sigframe(ka, env, sizeof *frame);
     trace_user_setup_rt_frame(env, frame_addr);
-    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        goto give_sigsegv;
-    }
+    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+       goto give_sigsegv;
 
     __put_user(sig, &frame->sig);
 
@@ -5262,13 +5159,13 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
     __put_user(target_sigaltstack_used.ss_sp,
                &frame->uc.tuc_stack.ss_sp);
     __put_user(sas_ss_flags(env->aregs[7]),
-            &frame->uc.tuc_stack.ss_flags);
+               &frame->uc.tuc_stack.ss_flags);
     __put_user(target_sigaltstack_used.ss_size,
                &frame->uc.tuc_stack.ss_size);
     err |= target_rt_setup_ucontext(&frame->uc, env);
 
     if (err)
-        goto give_sigsegv;
+            goto give_sigsegv;
 
     for(i = 0; i < TARGET_NSIG_WORDS; i++) {
         __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
@@ -5307,7 +5204,7 @@ long do_sigreturn(CPUM68KState *env)
     abi_ulong frame_addr = env->aregs[7] - 4;
     target_sigset_t target_set;
     sigset_t set;
-    int i;
+    int d0, i;
 
     trace_user_do_sigreturn(env, frame_addr);
     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
@@ -5322,14 +5219,14 @@ long do_sigreturn(CPUM68KState *env)
     }
 
     target_to_host_sigset_internal(&set, &target_set);
-    set_sigmask(&set);
+    do_sigprocmask(SIG_SETMASK, &set, NULL);
 
     /* restore registers */
 
-    restore_sigcontext(env, &frame->sc);
+    restore_sigcontext(env, &frame->sc, &d0);
 
     unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+    return d0;
 
 badframe:
     force_sig(TARGET_SIGSEGV);
@@ -5342,17 +5239,18 @@ long do_rt_sigreturn(CPUM68KState *env)
     abi_ulong frame_addr = env->aregs[7] - 4;
     target_sigset_t target_set;
     sigset_t set;
+    int d0;
 
     trace_user_do_rt_sigreturn(env, frame_addr);
     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
         goto badframe;
 
     target_to_host_sigset_internal(&set, &target_set);
-    set_sigmask(&set);
+    do_sigprocmask(SIG_SETMASK, &set, NULL);
 
     /* restore registers */
 
-    if (target_rt_restore_ucontext(env, &frame->uc))
+    if (target_rt_restore_ucontext(env, &frame->uc, &d0))
         goto badframe;
 
     if (do_sigaltstack(frame_addr +
@@ -5361,7 +5259,7 @@ long do_rt_sigreturn(CPUM68KState *env)
         goto badframe;
 
     unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+    return d0;
 
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
@@ -5418,7 +5316,7 @@ struct target_rt_sigframe {
 #define INSN_CALLSYS            0x00000083
 
 static void setup_sigcontext(struct target_sigcontext *sc, CPUAlphaState *env,
-                             abi_ulong frame_addr, target_sigset_t *set)
+                            abi_ulong frame_addr, target_sigset_t *set)
 {
     int i;
 
@@ -5444,7 +5342,7 @@ static void setup_sigcontext(struct target_sigcontext *sc, CPUAlphaState *env,
 }
 
 static void restore_sigcontext(CPUAlphaState *env,
-                               struct target_sigcontext *sc)
+                              struct target_sigcontext *sc)
 {
     uint64_t fpcr;
     int i;
@@ -5504,7 +5402,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
     unlock_user_struct(frame, frame_addr, 1);
 
     if (err) {
-give_sigsegv:
+    give_sigsegv:
         if (sig == TARGET_SIGSEGV) {
             ka->_sa_handler = TARGET_SIG_DFL;
         }
@@ -5561,8 +5459,8 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
     }
 
     if (err) {
-give_sigsegv:
-        if (sig == TARGET_SIGSEGV) {
+    give_sigsegv:
+       if (sig == TARGET_SIGSEGV) {
             ka->_sa_handler = TARGET_SIG_DFL;
         }
         force_sig(TARGET_SIGSEGV);
@@ -5591,13 +5489,13 @@ long do_sigreturn(CPUAlphaState *env)
     __get_user(target_set.sig[0], &sc->sc_mask);
 
     target_to_host_sigset_internal(&set, &target_set);
-    set_sigmask(&set);
+    do_sigprocmask(SIG_SETMASK, &set, NULL);
 
     restore_sigcontext(env, sc);
     unlock_user_struct(sc, sc_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+    return env->ir[IR_V0];
 
-badframe:
+ badframe:
     force_sig(TARGET_SIGSEGV);
 }
 
@@ -5612,7 +5510,7 @@ long do_rt_sigreturn(CPUAlphaState *env)
         goto badframe;
     }
     target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
-    set_sigmask(&set);
+    do_sigprocmask(SIG_SETMASK, &set, NULL);
 
     restore_sigcontext(env, &frame->uc.tuc_mcontext);
     if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
@@ -5622,10 +5520,10 @@ long do_rt_sigreturn(CPUAlphaState *env)
     }
 
     unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+    return env->ir[IR_V0];
 
 
-badframe:
+ badframe:
     unlock_user_struct(frame, frame_addr, 0);
     force_sig(TARGET_SIGSEGV);
 }
@@ -5661,13 +5559,8 @@ struct target_rt_sigframe {
     unsigned char save_area[16]; /* caller save area */
     struct target_siginfo info;
     struct target_ucontext uc;
-    abi_ulong retcode[2];
 };
 
-#define INSN_MOVELI_R10_139  0x00045fe551483000ULL /* { moveli r10, 139 } */
-#define INSN_SWINT1          0x286b180051485000ULL /* { swint1 } */
-
-
 static void setup_sigcontext(struct target_sigcontext *sc,
                              CPUArchState *env, int signo)
 {
@@ -5743,12 +5636,9 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
     __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
     setup_sigcontext(&frame->uc.tuc_mcontext, env, info->si_signo);
 
+    restorer = (unsigned long) do_rt_sigreturn;
     if (ka->sa_flags & TARGET_SA_RESTORER) {
-        restorer = (unsigned long) ka->sa_restorer;
-    } else {
-        __put_user(INSN_MOVELI_R10_139, &frame->retcode[0]);
-        __put_user(INSN_SWINT1, &frame->retcode[1]);
-        restorer = frame_addr + offsetof(struct target_rt_sigframe, retcode);
+            restorer = (unsigned long) ka->sa_restorer;
     }
     env->pc = (unsigned long) ka->_sa_handler;
     env->regs[TILEGX_R_SP] = (unsigned long) frame;
@@ -5779,7 +5669,7 @@ long do_rt_sigreturn(CPUTLGState *env)
         goto badframe;
     }
     target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
-    set_sigmask(&set);
+    do_sigprocmask(SIG_SETMASK, &set, NULL);
 
     restore_sigcontext(env, &frame->uc.tuc_mcontext);
     if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
@@ -5789,7 +5679,7 @@ long do_rt_sigreturn(CPUTLGState *env)
     }
 
     unlock_user_struct(frame, frame_addr, 0);
-    return -TARGET_QEMU_ESIGRETURN;
+    return env->regs[TILEGX_R_RE];
 
 
  badframe:
@@ -5800,14 +5690,14 @@ long do_rt_sigreturn(CPUTLGState *env)
 #else
 
 static void setup_frame(int sig, struct target_sigaction *ka,
-                        target_sigset_t *set, CPUArchState *env)
+                       target_sigset_t *set, CPUArchState *env)
 {
     fprintf(stderr, "setup_frame: not implemented\n");
 }
 
 static void setup_rt_frame(int sig, struct target_sigaction *ka,
                            target_siginfo_t *info,
-                           target_sigset_t *set, CPUArchState *env)
+                          target_sigset_t *set, CPUArchState *env)
 {
     fprintf(stderr, "setup_rt_frame: not implemented\n");
 }
@@ -5826,19 +5716,39 @@ long do_rt_sigreturn(CPUArchState *env)
 
 #endif
 
-static void handle_pending_signal(CPUArchState *cpu_env, int sig,
-                                  struct emulated_sigtable *k)
+void process_pending_signals(CPUArchState *cpu_env)
 {
     CPUState *cpu = ENV_GET_CPU(cpu_env);
+    int sig;
     abi_ulong handler;
-    sigset_t set;
+    sigset_t set, old_set;
     target_sigset_t target_old_set;
+    struct emulated_sigtable *k;
     struct target_sigaction *sa;
+    struct sigqueue *q;
     TaskState *ts = cpu->opaque;
 
+    if (!ts->signal_pending)
+        return;
+
+    /* FIXME: This is not threadsafe.  */
+    k = ts->sigtab;
+    for(sig = 1; sig <= TARGET_NSIG; sig++) {
+        if (k->pending)
+            goto handle_signal;
+        k++;
+    }
+    /* if no signal is pending, just return */
+    ts->signal_pending = 0;
+    return;
+
+ handle_signal:
     trace_user_handle_signal(cpu_env, sig);
     /* dequeue signal */
-    k->pending = 0;
+    q = k->first;
+    k->first = q->next;
+    if (!k->first)
+        k->pending = 0;
 
     sig = gdb_handlesig(cpu, sig);
     if (!sig) {
@@ -5849,6 +5759,14 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
         handler = sa->_sa_handler;
     }
 
+    if (ts->sigsegv_blocked && sig == TARGET_SIGSEGV) {
+        /* Guest has blocked SIGSEGV but we got one anyway. Assume this
+         * is a forced SIGSEGV (ie one the kernel handles via force_sig_info
+         * because it got a real MMU fault), and treat as if default handler.
+         */
+        handler = TARGET_SIG_DFL;
+    }
+
     if (handler == TARGET_SIG_DFL) {
         /* default handler : ignore some signal. The other are job control or fatal */
         if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
@@ -5865,23 +5783,17 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
         force_sig(sig);
     } else {
         /* compute the blocked signals during the handler execution */
-        sigset_t *blocked_set;
-
         target_to_host_sigset(&set, &sa->sa_mask);
         /* SA_NODEFER indicates that the current signal should not be
            blocked during the handler */
         if (!(sa->sa_flags & TARGET_SA_NODEFER))
             sigaddset(&set, target_to_host_signal(sig));
 
+        /* block signals in the handler using Linux */
+        do_sigprocmask(SIG_BLOCK, &set, &old_set);
         /* save the previous blocked signal state to restore it at the
            end of the signal execution (see do_sigreturn) */
-        host_to_target_sigset_internal(&target_old_set, &ts->signal_mask);
-
-        /* block signals in the handler */
-        blocked_set = ts->in_sigsuspend ?
-            &ts->sigsuspend_mask : &ts->signal_mask;
-        sigorset(&ts->signal_mask, blocked_set, &set);
-        ts->in_sigsuspend = 0;
+        host_to_target_sigset_internal(&target_old_set, &old_set);
 
         /* if the CPU is in VM86 mode, we restore the 32 bit values */
 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
@@ -5895,74 +5807,16 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) \
     || defined(TARGET_OPENRISC) || defined(TARGET_TILEGX)
         /* These targets do not have traditional signals.  */
-        setup_rt_frame(sig, sa, &k->info, &target_old_set, cpu_env);
+        setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
 #else
         if (sa->sa_flags & TARGET_SA_SIGINFO)
-            setup_rt_frame(sig, sa, &k->info, &target_old_set, cpu_env);
+            setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
         else
             setup_frame(sig, sa, &target_old_set, cpu_env);
 #endif
-        if (sa->sa_flags & TARGET_SA_RESETHAND) {
+       if (sa->sa_flags & TARGET_SA_RESETHAND)
             sa->_sa_handler = TARGET_SIG_DFL;
-        }
     }
-}
-
-void process_pending_signals(CPUArchState *cpu_env)
-{
-    CPUState *cpu = ENV_GET_CPU(cpu_env);
-    int sig;
-    TaskState *ts = cpu->opaque;
-    sigset_t set;
-    sigset_t *blocked_set;
-
-    while (atomic_read(&ts->signal_pending)) {
-        /* FIXME: This is not threadsafe.  */
-        sigfillset(&set);
-        sigprocmask(SIG_SETMASK, &set, 0);
-
-        sig = ts->sync_signal.pending;
-        if (sig) {
-            /* Synchronous signals are forced,
-             * see force_sig_info() and callers in Linux
-             * Note that not all of our queue_signal() calls in QEMU correspond
-             * to force_sig_info() calls in Linux (some are send_sig_info()).
-             * However it seems like a kernel bug to me to allow the process
-             * to block a synchronous signal since it could then just end up
-             * looping round and round indefinitely.
-             */
-            if (sigismember(&ts->signal_mask, target_to_host_signal_table[sig])
-                || sigact_table[sig - 1]._sa_handler == TARGET_SIG_IGN) {
-                sigdelset(&ts->signal_mask, target_to_host_signal_table[sig]);
-                sigact_table[sig - 1]._sa_handler = TARGET_SIG_DFL;
-            }
-
-            handle_pending_signal(cpu_env, sig, &ts->sync_signal);
-        }
-
-        for (sig = 1; sig <= TARGET_NSIG; sig++) {
-            blocked_set = ts->in_sigsuspend ?
-                &ts->sigsuspend_mask : &ts->signal_mask;
-
-            if (ts->sigtab[sig - 1].pending &&
-                (!sigismember(blocked_set,
-                              target_to_host_signal_table[sig]))) {
-                handle_pending_signal(cpu_env, sig, &ts->sigtab[sig - 1]);
-                /* Restart scan from the beginning */
-                sig = 1;
-            }
-        }
-
-        /* if no signal is pending, unblock signals and recheck (the act
-         * of unblocking might cause us to take another host signal which
-         * will set signal_pending again).
-         */
-        atomic_set(&ts->signal_pending, 0);
-        ts->in_sigsuspend = 0;
-        set = ts->signal_mask;
-        sigdelset(&set, SIGSEGV);
-        sigdelset(&set, SIGBUS);
-        sigprocmask(SIG_SETMASK, &set, 0);
-    }
-    ts->in_sigsuspend = 0;
+    if (q != &k->info)
+        free_sigqueue(cpu_env, q);
 }
index e713c9d..732b105 100644 (file)
 #define TARGET_NR_readahead          205 /* Linux Specific                              */
 #define TARGET_NR_socketcall         206 /* Linux Specific                              */
 #define TARGET_NR_syslog             207 /* Linux Specific                              */
-#define TARGET_NR_lookup_dcookie     208 /* Linux Specific                              */
-#define TARGET_NR_fadvise64          209 /* Linux Specific                              */
-#define TARGET_NR_fadvise64_64       210 /* Linux Specific                              */
 #define TARGET_NR_tgkill             211 /* Linux Specific                              */
 #define TARGET_NR_waitpid            212 /* Linux Specific                              */
 #define TARGET_NR_swapoff            213 /* Linux Specific                              */
index f2fe526..4944d46 100644 (file)
@@ -17,8 +17,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef SPARC_TARGET_CPU_H
-#define SPARC_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUSPARCState *env, target_ulong newsp)
 {
index e445e2b..c7de300 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef SPARC_TARGET_SIGNAL_H
-#define SPARC_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -33,5 +33,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
     return state->regwptr[UREG_FP];
 }
 
-
-#endif /* SPARC_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index ee24c3b..c139e09 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef SPARC_TARGET_STRUCTS_H
-#define SPARC_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index 326f674..a73fa6d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef SPARC_TARGET_SYSCALL_H
-#define SPARC_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 struct target_pt_regs {
        abi_ulong psr;
@@ -22,4 +22,4 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 0x2000
 #define TARGET_MLOCKALL_MCL_FUTURE  0x4000
 
-#endif /* SPARC_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index 4449457..c7de300 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef SPARC64_TARGET_SIGNAL_H
-#define SPARC64_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -33,5 +33,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
     return state->regwptr[UREG_FP];
 }
 
-
-#endif /* SPARC64_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index 1808132..fc17290 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef SPARC64_TARGET_STRUCTS_H
-#define SPARC64_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index b7e3bf8..eb827fc 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef SPARC64_TARGET_SYSCALL_H
-#define SPARC64_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 struct target_pt_regs {
        abi_ulong u_regs[16];
@@ -23,4 +23,4 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 0x2000
 #define TARGET_MLOCKALL_MCL_FUTURE  0x4000
 
-#endif /* SPARC64_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index cc10dc4..0810c85 100644 (file)
@@ -5,9 +5,7 @@
 #include <sys/shm.h>
 #include <sys/select.h>
 #include <sys/mount.h>
-#include <arpa/inet.h>
-#include <netinet/tcp.h>
-#include <linux/if_packet.h>
+#include <sys/mman.h>
 #include <sched.h>
 #include "qemu.h"
 
@@ -60,15 +58,10 @@ UNUSED static void print_open_flags(abi_long, int);
 UNUSED static void print_syscall_prologue(const struct syscallname *);
 UNUSED static void print_syscall_epilogue(const struct syscallname *);
 UNUSED static void print_string(abi_long, int);
-UNUSED static void print_buf(abi_long addr, abi_long len, int last);
 UNUSED static void print_raw_param(const char *, abi_long, int);
 UNUSED static void print_timeval(abi_ulong, int);
 UNUSED static void print_number(abi_long, int);
 UNUSED static void print_signal(abi_ulong, int);
-UNUSED static void print_sockaddr(abi_ulong addr, abi_long addrlen);
-UNUSED static void print_socket_domain(int domain);
-UNUSED static void print_socket_type(int type);
-UNUSED static void print_socket_protocol(int domain, int type, int protocol);
 
 /*
  * Utility functions
@@ -154,165 +147,6 @@ print_signal(abi_ulong arg, int last)
     gemu_log("%s%s", signal_name, get_comma(last));
 }
 
-static void
-print_sockaddr(abi_ulong addr, abi_long addrlen)
-{
-    struct target_sockaddr *sa;
-    int i;
-    int sa_family;
-
-    sa = lock_user(VERIFY_READ, addr, addrlen, 1);
-    if (sa) {
-        sa_family = tswap16(sa->sa_family);
-        switch (sa_family) {
-        case AF_UNIX: {
-            struct target_sockaddr_un *un = (struct target_sockaddr_un *)sa;
-            int i;
-            gemu_log("{sun_family=AF_UNIX,sun_path=\"");
-            for (i = 0; i < addrlen -
-                            offsetof(struct target_sockaddr_un, sun_path) &&
-                 un->sun_path[i]; i++) {
-                gemu_log("%c", un->sun_path[i]);
-            }
-            gemu_log("\"}");
-            break;
-        }
-        case AF_INET: {
-            struct target_sockaddr_in *in = (struct target_sockaddr_in *)sa;
-            uint8_t *c = (uint8_t *)&in->sin_addr.s_addr;
-            gemu_log("{sin_family=AF_INET,sin_port=htons(%d),",
-                     ntohs(in->sin_port));
-            gemu_log("sin_addr=inet_addr(\"%d.%d.%d.%d\")",
-                     c[0], c[1], c[2], c[3]);
-            gemu_log("}");
-            break;
-        }
-        case AF_PACKET: {
-            struct target_sockaddr_ll *ll = (struct target_sockaddr_ll *)sa;
-            uint8_t *c = (uint8_t *)&ll->sll_addr;
-            gemu_log("{sll_family=AF_PACKET,"
-                     "sll_protocol=htons(0x%04x),if%d,pkttype=",
-                     ntohs(ll->sll_protocol), ll->sll_ifindex);
-            switch (ll->sll_pkttype) {
-            case PACKET_HOST:
-                gemu_log("PACKET_HOST");
-                break;
-            case PACKET_BROADCAST:
-                gemu_log("PACKET_BROADCAST");
-                break;
-            case PACKET_MULTICAST:
-                gemu_log("PACKET_MULTICAST");
-                break;
-            case PACKET_OTHERHOST:
-                gemu_log("PACKET_OTHERHOST");
-                break;
-            case PACKET_OUTGOING:
-                gemu_log("PACKET_OUTGOING");
-                break;
-            default:
-                gemu_log("%d", ll->sll_pkttype);
-                break;
-            }
-            gemu_log(",sll_addr=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
-                     c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
-            gemu_log("}");
-            break;
-        }
-        default:
-            gemu_log("{sa_family=%d, sa_data={", sa->sa_family);
-            for (i = 0; i < 13; i++) {
-                gemu_log("%02x, ", sa->sa_data[i]);
-            }
-            gemu_log("%02x}", sa->sa_data[i]);
-            gemu_log("}");
-            break;
-        }
-        unlock_user(sa, addr, 0);
-    } else {
-        print_raw_param("0x"TARGET_ABI_FMT_lx, addr, 0);
-    }
-    gemu_log(", "TARGET_ABI_FMT_ld, addrlen);
-}
-
-static void
-print_socket_domain(int domain)
-{
-    switch (domain) {
-    case PF_UNIX:
-        gemu_log("PF_UNIX");
-        break;
-    case PF_INET:
-        gemu_log("PF_INET");
-        break;
-    case PF_PACKET:
-        gemu_log("PF_PACKET");
-        break;
-    default:
-        gemu_log("%d", domain);
-        break;
-    }
-}
-
-static void
-print_socket_type(int type)
-{
-    switch (type) {
-    case TARGET_SOCK_DGRAM:
-        gemu_log("SOCK_DGRAM");
-        break;
-    case TARGET_SOCK_STREAM:
-        gemu_log("SOCK_STREAM");
-        break;
-    case TARGET_SOCK_RAW:
-        gemu_log("SOCK_RAW");
-        break;
-    case TARGET_SOCK_RDM:
-        gemu_log("SOCK_RDM");
-        break;
-    case TARGET_SOCK_SEQPACKET:
-        gemu_log("SOCK_SEQPACKET");
-        break;
-    case TARGET_SOCK_PACKET:
-        gemu_log("SOCK_PACKET");
-        break;
-    }
-}
-
-static void
-print_socket_protocol(int domain, int type, int protocol)
-{
-    if (domain == AF_PACKET ||
-        (domain == AF_INET && type == TARGET_SOCK_PACKET)) {
-        switch (protocol) {
-        case 0x0003:
-            gemu_log("ETH_P_ALL");
-            break;
-        default:
-            gemu_log("%d", protocol);
-        }
-        return;
-    }
-
-    switch (protocol) {
-    case IPPROTO_IP:
-        gemu_log("IPPROTO_IP");
-        break;
-    case IPPROTO_TCP:
-        gemu_log("IPPROTO_TCP");
-        break;
-    case IPPROTO_UDP:
-        gemu_log("IPPROTO_UDP");
-        break;
-    case IPPROTO_RAW:
-        gemu_log("IPPROTO_RAW");
-        break;
-    default:
-        gemu_log("%d", protocol);
-        break;
-    }
-}
-
-
 #ifdef TARGET_NR__newselect
 static void
 print_fdset(int n, abi_ulong target_fds_addr)
@@ -447,7 +281,7 @@ print_ipc(const struct syscallname *name,
 static void
 print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
 {
-    const char *errstr = NULL;
+    char *errstr = NULL;
 
     if (ret < 0) {
         errstr = target_strerror(-ret);
@@ -664,26 +498,6 @@ UNUSED static struct flags clone_flags[] = {
     FLAG_END,
 };
 
-UNUSED static struct flags msg_flags[] = {
-    /* send */
-    FLAG_GENERIC(MSG_CONFIRM),
-    FLAG_GENERIC(MSG_DONTROUTE),
-    FLAG_GENERIC(MSG_DONTWAIT),
-    FLAG_GENERIC(MSG_EOR),
-    FLAG_GENERIC(MSG_MORE),
-    FLAG_GENERIC(MSG_NOSIGNAL),
-    FLAG_GENERIC(MSG_OOB),
-    /* recv */
-    FLAG_GENERIC(MSG_CMSG_CLOEXEC),
-    FLAG_GENERIC(MSG_ERRQUEUE),
-    FLAG_GENERIC(MSG_PEEK),
-    FLAG_GENERIC(MSG_TRUNC),
-    FLAG_GENERIC(MSG_WAITALL),
-    /* recvmsg */
-    FLAG_GENERIC(MSG_CTRUNC),
-    FLAG_END,
-};
-
 /*
  * print_xxx utility functions.  These are used to print syscall
  * parameters in certain format.  All of these have parameter
@@ -805,36 +619,6 @@ print_string(abi_long addr, int last)
     }
 }
 
-#define MAX_PRINT_BUF 40
-static void
-print_buf(abi_long addr, abi_long len, int last)
-{
-    uint8_t *s;
-    int i;
-
-    s = lock_user(VERIFY_READ, addr, len, 1);
-    if (s) {
-        gemu_log("\"");
-        for (i = 0; i < MAX_PRINT_BUF && i < len; i++) {
-            if (isprint(s[i])) {
-                gemu_log("%c", s[i]);
-            } else {
-                gemu_log("\\%o", s[i]);
-            }
-        }
-        gemu_log("\"");
-        if (i != len) {
-            gemu_log("...");
-        }
-        if (!last) {
-            gemu_log(",");
-        }
-        unlock_user(s, addr, 0);
-    } else {
-        print_pointer(addr, last);
-    }
-}
-
 /*
  * Prints out raw parameter using given format.  Caller needs
  * to do byte swapping if needed.
@@ -957,31 +741,33 @@ print_chmod(const struct syscallname *name,
 #endif
 
 #ifdef TARGET_NR_clone
-static void do_print_clone(unsigned int flags, abi_ulong newsp,
-                           abi_ulong parent_tidptr, target_ulong newtls,
-                           abi_ulong child_tidptr)
-{
-    print_flags(clone_flags, flags, 0);
-    print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, newsp, 0);
-    print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, parent_tidptr, 0);
-    print_raw_param("tls=0x" TARGET_ABI_FMT_lx, newtls, 0);
-    print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, child_tidptr, 1);
-}
-
 static void
 print_clone(const struct syscallname *name,
-    abi_long arg1, abi_long arg2, abi_long arg3,
-    abi_long arg4, abi_long arg5, abi_long arg6)
+    abi_long arg0, abi_long arg1, abi_long arg2,
+    abi_long arg3, abi_long arg4, abi_long arg5)
 {
     print_syscall_prologue(name);
-#if defined(TARGET_MICROBLAZE)
-    do_print_clone(arg1, arg2, arg4, arg6, arg5);
-#elif defined(TARGET_CLONE_BACKWARDS)
-    do_print_clone(arg1, arg2, arg3, arg4, arg5);
-#elif defined(TARGET_CLONE_BACKWARDS2)
-    do_print_clone(arg2, arg1, arg3, arg5, arg4);
+#if defined(TARGET_M68K)
+    print_flags(clone_flags, arg0, 0);
+    print_raw_param("newsp=0x" TARGET_ABI_FMT_lx, arg1, 1);
+#elif defined(TARGET_SH4) || defined(TARGET_ALPHA)
+    print_flags(clone_flags, arg0, 0);
+    print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0);
+    print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
+    print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg3, 0);
+    print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg4, 1);
+#elif defined(TARGET_CRIS)
+    print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg0, 0);
+    print_flags(clone_flags, arg1, 0);
+    print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
+    print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0);
+    print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1);
 #else
-    do_print_clone(arg1, arg2, arg3, arg5, arg4);
+    print_flags(clone_flags, arg0, 0);
+    print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0);
+    print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
+    print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0);
+    print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1);
 #endif
     print_syscall_epilogue(name);
 }
@@ -1133,13 +919,6 @@ print_fcntl(const struct syscallname *name,
     case TARGET_F_GETLEASE:
         gemu_log("F_GETLEASE");
         break;
-    case TARGET_F_SETPIPE_SZ:
-        gemu_log("F_SETPIPE_SZ,");
-        print_raw_param(TARGET_ABI_FMT_ld, arg2, 1);
-        break;
-    case TARGET_F_GETPIPE_SZ:
-        gemu_log("F_GETPIPE_SZ");
-        break;
     case TARGET_F_DUPFD_CLOEXEC:
         gemu_log("F_DUPFD_CLOEXEC,");
         print_raw_param(TARGET_ABI_FMT_ld, arg2, 1);
@@ -1225,361 +1004,6 @@ print__llseek(const struct syscallname *name,
 }
 #endif
 
-#if defined(TARGET_NR_socket)
-static void
-print_socket(const struct syscallname *name,
-             abi_long arg0, abi_long arg1, abi_long arg2,
-             abi_long arg3, abi_long arg4, abi_long arg5)
-{
-    abi_ulong domain = arg0, type = arg1, protocol = arg2;
-
-    print_syscall_prologue(name);
-    print_socket_domain(domain);
-    gemu_log(",");
-    print_socket_type(type);
-    gemu_log(",");
-    if (domain == AF_PACKET ||
-        (domain == AF_INET && type == TARGET_SOCK_PACKET)) {
-        protocol = tswap16(protocol);
-    }
-    print_socket_protocol(domain, type, protocol);
-    print_syscall_epilogue(name);
-}
-
-#endif
-
-#if defined(TARGET_NR_socketcall)
-
-#define get_user_ualx(x, gaddr, idx) \
-        get_user_ual(x, (gaddr) + (idx) * sizeof(abi_long))
-
-static void do_print_socket(const char *name, abi_long arg1)
-{
-    abi_ulong domain, type, protocol;
-
-    get_user_ualx(domain, arg1, 0);
-    get_user_ualx(type, arg1, 1);
-    get_user_ualx(protocol, arg1, 2);
-    gemu_log("%s(", name);
-    print_socket_domain(domain);
-    gemu_log(",");
-    print_socket_type(type);
-    gemu_log(",");
-    if (domain == AF_PACKET ||
-        (domain == AF_INET && type == TARGET_SOCK_PACKET)) {
-        protocol = tswap16(protocol);
-    }
-    print_socket_protocol(domain, type, protocol);
-    gemu_log(")");
-}
-
-static void do_print_sockaddr(const char *name, abi_long arg1)
-{
-    abi_ulong sockfd, addr, addrlen;
-
-    get_user_ualx(sockfd, arg1, 0);
-    get_user_ualx(addr, arg1, 1);
-    get_user_ualx(addrlen, arg1, 2);
-
-    gemu_log("%s(", name);
-    print_raw_param(TARGET_ABI_FMT_ld, sockfd, 0);
-    print_sockaddr(addr, addrlen);
-    gemu_log(")");
-}
-
-static void do_print_listen(const char *name, abi_long arg1)
-{
-    abi_ulong sockfd, backlog;
-
-    get_user_ualx(sockfd, arg1, 0);
-    get_user_ualx(backlog, arg1, 1);
-
-    gemu_log("%s(", name);
-    print_raw_param(TARGET_ABI_FMT_ld, sockfd, 0);
-    print_raw_param(TARGET_ABI_FMT_ld, backlog, 1);
-    gemu_log(")");
-}
-
-static void do_print_socketpair(const char *name, abi_long arg1)
-{
-    abi_ulong domain, type, protocol, tab;
-
-    get_user_ualx(domain, arg1, 0);
-    get_user_ualx(type, arg1, 1);
-    get_user_ualx(protocol, arg1, 2);
-    get_user_ualx(tab, arg1, 3);
-
-    gemu_log("%s(", name);
-    print_socket_domain(domain);
-    gemu_log(",");
-    print_socket_type(type);
-    gemu_log(",");
-    print_socket_protocol(domain, type, protocol);
-    gemu_log(",");
-    print_raw_param(TARGET_ABI_FMT_lx, tab, 1);
-    gemu_log(")");
-}
-
-static void do_print_sendrecv(const char *name, abi_long arg1)
-{
-    abi_ulong sockfd, msg, len, flags;
-
-    get_user_ualx(sockfd, arg1, 0);
-    get_user_ualx(msg, arg1, 1);
-    get_user_ualx(len, arg1, 2);
-    get_user_ualx(flags, arg1, 3);
-
-    gemu_log("%s(", name);
-    print_raw_param(TARGET_ABI_FMT_ld, sockfd, 0);
-    print_buf(msg, len, 0);
-    print_raw_param(TARGET_ABI_FMT_ld, len, 0);
-    print_flags(msg_flags, flags, 1);
-    gemu_log(")");
-}
-
-static void do_print_msgaddr(const char *name, abi_long arg1)
-{
-    abi_ulong sockfd, msg, len, flags, addr, addrlen;
-
-    get_user_ualx(sockfd, arg1, 0);
-    get_user_ualx(msg, arg1, 1);
-    get_user_ualx(len, arg1, 2);
-    get_user_ualx(flags, arg1, 3);
-    get_user_ualx(addr, arg1, 4);
-    get_user_ualx(addrlen, arg1, 5);
-
-    gemu_log("%s(", name);
-    print_raw_param(TARGET_ABI_FMT_ld, sockfd, 0);
-    print_buf(msg, len, 0);
-    print_raw_param(TARGET_ABI_FMT_ld, len, 0);
-    print_flags(msg_flags, flags, 0);
-    print_sockaddr(addr, addrlen);
-    gemu_log(")");
-}
-
-static void do_print_shutdown(const char *name, abi_long arg1)
-{
-    abi_ulong sockfd, how;
-
-    get_user_ualx(sockfd, arg1, 0);
-    get_user_ualx(how, arg1, 1);
-
-    gemu_log("shutdown(");
-    print_raw_param(TARGET_ABI_FMT_ld, sockfd, 0);
-    switch (how) {
-    case SHUT_RD:
-        gemu_log("SHUT_RD");
-        break;
-    case SHUT_WR:
-        gemu_log("SHUT_WR");
-        break;
-    case SHUT_RDWR:
-        gemu_log("SHUT_RDWR");
-        break;
-    default:
-        print_raw_param(TARGET_ABI_FMT_ld, how, 1);
-        break;
-    }
-    gemu_log(")");
-}
-
-static void do_print_msg(const char *name, abi_long arg1)
-{
-    abi_ulong sockfd, msg, flags;
-
-    get_user_ualx(sockfd, arg1, 0);
-    get_user_ualx(msg, arg1, 1);
-    get_user_ualx(flags, arg1, 2);
-
-    gemu_log("%s(", name);
-    print_raw_param(TARGET_ABI_FMT_ld, sockfd, 0);
-    print_pointer(msg, 0);
-    print_flags(msg_flags, flags, 1);
-    gemu_log(")");
-}
-
-static void do_print_sockopt(const char *name, abi_long arg1)
-{
-    abi_ulong sockfd, level, optname, optval, optlen;
-
-    get_user_ualx(sockfd, arg1, 0);
-    get_user_ualx(level, arg1, 1);
-    get_user_ualx(optname, arg1, 2);
-    get_user_ualx(optval, arg1, 3);
-    get_user_ualx(optlen, arg1, 4);
-
-    gemu_log("%s(", name);
-    print_raw_param(TARGET_ABI_FMT_ld, sockfd, 0);
-    switch (level) {
-    case SOL_TCP:
-        gemu_log("SOL_TCP,");
-        print_raw_param(TARGET_ABI_FMT_ld, optname, 0);
-        print_pointer(optval, 0);
-        break;
-    case SOL_IP:
-        gemu_log("SOL_IP,");
-        print_raw_param(TARGET_ABI_FMT_ld, optname, 0);
-        print_pointer(optval, 0);
-        break;
-    case SOL_RAW:
-        gemu_log("SOL_RAW,");
-        print_raw_param(TARGET_ABI_FMT_ld, optname, 0);
-        print_pointer(optval, 0);
-        break;
-    case TARGET_SOL_SOCKET:
-        gemu_log("SOL_SOCKET,");
-        switch (optname) {
-        case TARGET_SO_DEBUG:
-            gemu_log("SO_DEBUG,");
-print_optint:
-            print_number(optval, 0);
-            break;
-        case TARGET_SO_REUSEADDR:
-            gemu_log("SO_REUSEADDR,");
-            goto print_optint;
-        case TARGET_SO_TYPE:
-            gemu_log("SO_TYPE,");
-            goto print_optint;
-        case TARGET_SO_ERROR:
-            gemu_log("SO_ERROR,");
-            goto print_optint;
-        case TARGET_SO_DONTROUTE:
-            gemu_log("SO_DONTROUTE,");
-            goto print_optint;
-        case TARGET_SO_BROADCAST:
-            gemu_log("SO_BROADCAST,");
-            goto print_optint;
-        case TARGET_SO_SNDBUF:
-            gemu_log("SO_SNDBUF,");
-            goto print_optint;
-        case TARGET_SO_RCVBUF:
-            gemu_log("SO_RCVBUF,");
-            goto print_optint;
-        case TARGET_SO_KEEPALIVE:
-            gemu_log("SO_KEEPALIVE,");
-            goto print_optint;
-        case TARGET_SO_OOBINLINE:
-            gemu_log("SO_OOBINLINE,");
-            goto print_optint;
-        case TARGET_SO_NO_CHECK:
-            gemu_log("SO_NO_CHECK,");
-            goto print_optint;
-        case TARGET_SO_PRIORITY:
-            gemu_log("SO_PRIORITY,");
-            goto print_optint;
-        case TARGET_SO_BSDCOMPAT:
-            gemu_log("SO_BSDCOMPAT,");
-            goto print_optint;
-        case TARGET_SO_PASSCRED:
-            gemu_log("SO_PASSCRED,");
-            goto print_optint;
-        case TARGET_SO_TIMESTAMP:
-            gemu_log("SO_TIMESTAMP,");
-            goto print_optint;
-        case TARGET_SO_RCVLOWAT:
-            gemu_log("SO_RCVLOWAT,");
-            goto print_optint;
-        case TARGET_SO_RCVTIMEO:
-            gemu_log("SO_RCVTIMEO,");
-            print_timeval(optval, 0);
-            break;
-        case TARGET_SO_SNDTIMEO:
-            gemu_log("SO_SNDTIMEO,");
-            print_timeval(optval, 0);
-            break;
-        case TARGET_SO_ATTACH_FILTER: {
-            struct target_sock_fprog *fprog;
-
-            gemu_log("SO_ATTACH_FILTER,");
-
-            if (lock_user_struct(VERIFY_READ, fprog, optval,  0)) {
-                struct target_sock_filter *filter;
-                gemu_log("{");
-                if (lock_user_struct(VERIFY_READ, filter,
-                                     tswapal(fprog->filter),  0)) {
-                    int i;
-                    for (i = 0; i < tswap16(fprog->len) - 1; i++) {
-                        gemu_log("[%d]{0x%x,%d,%d,0x%x},",
-                                 i, tswap16(filter[i].code),
-                                 filter[i].jt, filter[i].jf,
-                                 tswap32(filter[i].k));
-                    }
-                    gemu_log("[%d]{0x%x,%d,%d,0x%x}",
-                             i, tswap16(filter[i].code),
-                             filter[i].jt, filter[i].jf,
-                             tswap32(filter[i].k));
-                } else {
-                    gemu_log(TARGET_ABI_FMT_lx, tswapal(fprog->filter));
-                }
-                gemu_log(",%d},", tswap16(fprog->len));
-                unlock_user(fprog, optval, 0);
-            } else {
-                print_pointer(optval, 0);
-            }
-            break;
-        }
-        default:
-            print_raw_param(TARGET_ABI_FMT_ld, optname, 0);
-            print_pointer(optval, 0);
-            break;
-        }
-        break;
-    default:
-        print_raw_param(TARGET_ABI_FMT_ld, level, 0);
-        print_raw_param(TARGET_ABI_FMT_ld, optname, 0);
-        print_pointer(optval, 0);
-        break;
-    }
-    print_raw_param(TARGET_ABI_FMT_ld, optlen, 1);
-    gemu_log(")");
-}
-
-#define PRINT_SOCKOP(name, func) \
-    [SOCKOP_##name] = { #name, func }
-
-static struct {
-    const char *name;
-    void (*print)(const char *, abi_long);
-} scall[] = {
-    PRINT_SOCKOP(socket, do_print_socket),
-    PRINT_SOCKOP(bind, do_print_sockaddr),
-    PRINT_SOCKOP(connect, do_print_sockaddr),
-    PRINT_SOCKOP(listen, do_print_listen),
-    PRINT_SOCKOP(accept, do_print_sockaddr),
-    PRINT_SOCKOP(getsockname, do_print_sockaddr),
-    PRINT_SOCKOP(getpeername, do_print_sockaddr),
-    PRINT_SOCKOP(socketpair, do_print_socketpair),
-    PRINT_SOCKOP(send, do_print_sendrecv),
-    PRINT_SOCKOP(recv, do_print_sendrecv),
-    PRINT_SOCKOP(sendto, do_print_msgaddr),
-    PRINT_SOCKOP(recvfrom, do_print_msgaddr),
-    PRINT_SOCKOP(shutdown, do_print_shutdown),
-    PRINT_SOCKOP(sendmsg, do_print_msg),
-    PRINT_SOCKOP(recvmsg, do_print_msg),
-    PRINT_SOCKOP(setsockopt, do_print_sockopt),
-    PRINT_SOCKOP(getsockopt, do_print_sockopt),
-};
-
-static void
-print_socketcall(const struct syscallname *name,
-                 abi_long arg0, abi_long arg1, abi_long arg2,
-                 abi_long arg3, abi_long arg4, abi_long arg5)
-{
-    if (arg0 >= 0 && arg0 < ARRAY_SIZE(scall) && scall[arg0].print) {
-        scall[arg0].print(scall[arg0].name, arg1);
-        return;
-    }
-    print_syscall_prologue(name);
-    print_raw_param(TARGET_ABI_FMT_ld, arg0, 0);
-    print_raw_param(TARGET_ABI_FMT_ld, arg1, 0);
-    print_raw_param(TARGET_ABI_FMT_ld, arg2, 0);
-    print_raw_param(TARGET_ABI_FMT_ld, arg3, 0);
-    print_raw_param(TARGET_ABI_FMT_ld, arg4, 0);
-    print_raw_param(TARGET_ABI_FMT_ld, arg5, 0);
-    print_syscall_epilogue(name);
-}
-#endif
-
 #if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) || \
     defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64)
 static void
@@ -2170,7 +1594,7 @@ void
 print_syscall_ret(int num, abi_long ret)
 {
     int i;
-    const char *errstr = NULL;
+    char *errstr = NULL;
 
     for(i=0;i<nsyscalls;i++)
         if( scnames[i].nr == num ) {
index aa967a2..aa0cd73 100644 (file)
 { TARGET_NR_getsockopt, "getsockopt" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_get_thread_area
-{ TARGET_NR_get_thread_area, "get_thread_area", "%s(0x"TARGET_ABI_FMT_lx")",
-  NULL, NULL },
+{ TARGET_NR_get_thread_area, "get_thread_area" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_gettid
 { TARGET_NR_gettid, "gettid" , NULL, NULL, NULL },
 { TARGET_NR_setsockopt, "setsockopt" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_set_thread_area
-{ TARGET_NR_set_thread_area, "set_thread_area", "%s(0x"TARGET_ABI_FMT_lx")",
-  NULL, NULL },
+{ TARGET_NR_set_thread_area, "set_thread_area" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_set_tid_address
 { TARGET_NR_set_tid_address, "set_tid_address" , NULL, NULL, NULL },
 { TARGET_NR_sigsuspend, "sigsuspend" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_socket
-{ TARGET_NR_socket, "socket" , NULL, print_socket, NULL },
+{ TARGET_NR_socket, "socket" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_socketcall
-{ TARGET_NR_socketcall, "socketcall" , NULL, print_socketcall, NULL },
+{ TARGET_NR_socketcall, "socketcall" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_socketpair
 { TARGET_NR_socketpair, "socketpair" , NULL, NULL, NULL },
index ca06943..032d338 100644 (file)
@@ -32,6 +32,7 @@
 #include <sys/personality.h>
 #include <sys/prctl.h>
 #include <sys/resource.h>
+#include <sys/mman.h>
 #include <sys/swap.h>
 #include <linux/capability.h>
 #include <sched.h>
@@ -100,13 +101,6 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #include <linux/route.h>
 #include <linux/filter.h>
 #include <linux/blkpg.h>
-#include <netpacket/packet.h>
-#include <linux/netlink.h>
-#ifdef CONFIG_RTNETLINK
-#include <linux/rtnetlink.h>
-#include <linux/if_bridge.h>
-#endif
-#include <linux/audit.h>
 #include "linux_loop.h"
 #include "uname.h"
 
@@ -116,15 +110,12 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
     CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
 
 //#define DEBUG
-/* Define DEBUG_ERESTARTSYS to force every syscall to be restarted
- * once. This exercises the codepaths for restart.
- */
-//#define DEBUG_ERESTARTSYS
 
 //#include <linux/msdos_fs.h>
 #define        VFAT_IOCTL_READDIR_BOTH         _IOR('r', 1, struct linux_dirent [2])
 #define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
 
+
 #undef _syscall0
 #undef _syscall1
 #undef _syscall2
@@ -187,6 +178,8 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,   \
 #define __NR_sys_getpriority __NR_getpriority
 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
 #define __NR_sys_syslog __NR_syslog
+#define __NR_sys_tgkill __NR_tgkill
+#define __NR_sys_tkill __NR_tkill
 #define __NR_sys_futex __NR_futex
 #define __NR_sys_inotify_init __NR_inotify_init
 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
@@ -224,6 +217,12 @@ _syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
 #endif
 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
+#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
+_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
+#endif
+#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
+_syscall2(int,sys_tkill,int,tid,int,sig)
+#endif
 #ifdef __NR_exit_group
 _syscall1(int,exit_group,int,error_code)
 #endif
@@ -289,161 +288,6 @@ static bitmask_transtbl fcntl_flags_tbl[] = {
   { 0, 0, 0, 0 }
 };
 
-enum {
-    QEMU_IFLA_BR_UNSPEC,
-    QEMU_IFLA_BR_FORWARD_DELAY,
-    QEMU_IFLA_BR_HELLO_TIME,
-    QEMU_IFLA_BR_MAX_AGE,
-    QEMU_IFLA_BR_AGEING_TIME,
-    QEMU_IFLA_BR_STP_STATE,
-    QEMU_IFLA_BR_PRIORITY,
-    QEMU_IFLA_BR_VLAN_FILTERING,
-    QEMU_IFLA_BR_VLAN_PROTOCOL,
-    QEMU_IFLA_BR_GROUP_FWD_MASK,
-    QEMU_IFLA_BR_ROOT_ID,
-    QEMU_IFLA_BR_BRIDGE_ID,
-    QEMU_IFLA_BR_ROOT_PORT,
-    QEMU_IFLA_BR_ROOT_PATH_COST,
-    QEMU_IFLA_BR_TOPOLOGY_CHANGE,
-    QEMU_IFLA_BR_TOPOLOGY_CHANGE_DETECTED,
-    QEMU_IFLA_BR_HELLO_TIMER,
-    QEMU_IFLA_BR_TCN_TIMER,
-    QEMU_IFLA_BR_TOPOLOGY_CHANGE_TIMER,
-    QEMU_IFLA_BR_GC_TIMER,
-    QEMU_IFLA_BR_GROUP_ADDR,
-    QEMU_IFLA_BR_FDB_FLUSH,
-    QEMU_IFLA_BR_MCAST_ROUTER,
-    QEMU_IFLA_BR_MCAST_SNOOPING,
-    QEMU_IFLA_BR_MCAST_QUERY_USE_IFADDR,
-    QEMU_IFLA_BR_MCAST_QUERIER,
-    QEMU_IFLA_BR_MCAST_HASH_ELASTICITY,
-    QEMU_IFLA_BR_MCAST_HASH_MAX,
-    QEMU_IFLA_BR_MCAST_LAST_MEMBER_CNT,
-    QEMU_IFLA_BR_MCAST_STARTUP_QUERY_CNT,
-    QEMU_IFLA_BR_MCAST_LAST_MEMBER_INTVL,
-    QEMU_IFLA_BR_MCAST_MEMBERSHIP_INTVL,
-    QEMU_IFLA_BR_MCAST_QUERIER_INTVL,
-    QEMU_IFLA_BR_MCAST_QUERY_INTVL,
-    QEMU_IFLA_BR_MCAST_QUERY_RESPONSE_INTVL,
-    QEMU_IFLA_BR_MCAST_STARTUP_QUERY_INTVL,
-    QEMU_IFLA_BR_NF_CALL_IPTABLES,
-    QEMU_IFLA_BR_NF_CALL_IP6TABLES,
-    QEMU_IFLA_BR_NF_CALL_ARPTABLES,
-    QEMU_IFLA_BR_VLAN_DEFAULT_PVID,
-    QEMU_IFLA_BR_PAD,
-    QEMU_IFLA_BR_VLAN_STATS_ENABLED,
-    QEMU_IFLA_BR_MCAST_STATS_ENABLED,
-    QEMU___IFLA_BR_MAX,
-};
-
-enum {
-    QEMU_IFLA_UNSPEC,
-    QEMU_IFLA_ADDRESS,
-    QEMU_IFLA_BROADCAST,
-    QEMU_IFLA_IFNAME,
-    QEMU_IFLA_MTU,
-    QEMU_IFLA_LINK,
-    QEMU_IFLA_QDISC,
-    QEMU_IFLA_STATS,
-    QEMU_IFLA_COST,
-    QEMU_IFLA_PRIORITY,
-    QEMU_IFLA_MASTER,
-    QEMU_IFLA_WIRELESS,
-    QEMU_IFLA_PROTINFO,
-    QEMU_IFLA_TXQLEN,
-    QEMU_IFLA_MAP,
-    QEMU_IFLA_WEIGHT,
-    QEMU_IFLA_OPERSTATE,
-    QEMU_IFLA_LINKMODE,
-    QEMU_IFLA_LINKINFO,
-    QEMU_IFLA_NET_NS_PID,
-    QEMU_IFLA_IFALIAS,
-    QEMU_IFLA_NUM_VF,
-    QEMU_IFLA_VFINFO_LIST,
-    QEMU_IFLA_STATS64,
-    QEMU_IFLA_VF_PORTS,
-    QEMU_IFLA_PORT_SELF,
-    QEMU_IFLA_AF_SPEC,
-    QEMU_IFLA_GROUP,
-    QEMU_IFLA_NET_NS_FD,
-    QEMU_IFLA_EXT_MASK,
-    QEMU_IFLA_PROMISCUITY,
-    QEMU_IFLA_NUM_TX_QUEUES,
-    QEMU_IFLA_NUM_RX_QUEUES,
-    QEMU_IFLA_CARRIER,
-    QEMU_IFLA_PHYS_PORT_ID,
-    QEMU_IFLA_CARRIER_CHANGES,
-    QEMU_IFLA_PHYS_SWITCH_ID,
-    QEMU_IFLA_LINK_NETNSID,
-    QEMU_IFLA_PHYS_PORT_NAME,
-    QEMU_IFLA_PROTO_DOWN,
-    QEMU_IFLA_GSO_MAX_SEGS,
-    QEMU_IFLA_GSO_MAX_SIZE,
-    QEMU_IFLA_PAD,
-    QEMU_IFLA_XDP,
-    QEMU___IFLA_MAX
-};
-
-enum {
-    QEMU_IFLA_BRPORT_UNSPEC,
-    QEMU_IFLA_BRPORT_STATE,
-    QEMU_IFLA_BRPORT_PRIORITY,
-    QEMU_IFLA_BRPORT_COST,
-    QEMU_IFLA_BRPORT_MODE,
-    QEMU_IFLA_BRPORT_GUARD,
-    QEMU_IFLA_BRPORT_PROTECT,
-    QEMU_IFLA_BRPORT_FAST_LEAVE,
-    QEMU_IFLA_BRPORT_LEARNING,
-    QEMU_IFLA_BRPORT_UNICAST_FLOOD,
-    QEMU_IFLA_BRPORT_PROXYARP,
-    QEMU_IFLA_BRPORT_LEARNING_SYNC,
-    QEMU_IFLA_BRPORT_PROXYARP_WIFI,
-    QEMU_IFLA_BRPORT_ROOT_ID,
-    QEMU_IFLA_BRPORT_BRIDGE_ID,
-    QEMU_IFLA_BRPORT_DESIGNATED_PORT,
-    QEMU_IFLA_BRPORT_DESIGNATED_COST,
-    QEMU_IFLA_BRPORT_ID,
-    QEMU_IFLA_BRPORT_NO,
-    QEMU_IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
-    QEMU_IFLA_BRPORT_CONFIG_PENDING,
-    QEMU_IFLA_BRPORT_MESSAGE_AGE_TIMER,
-    QEMU_IFLA_BRPORT_FORWARD_DELAY_TIMER,
-    QEMU_IFLA_BRPORT_HOLD_TIMER,
-    QEMU_IFLA_BRPORT_FLUSH,
-    QEMU_IFLA_BRPORT_MULTICAST_ROUTER,
-    QEMU_IFLA_BRPORT_PAD,
-    QEMU___IFLA_BRPORT_MAX
-};
-
-enum {
-    QEMU_IFLA_INFO_UNSPEC,
-    QEMU_IFLA_INFO_KIND,
-    QEMU_IFLA_INFO_DATA,
-    QEMU_IFLA_INFO_XSTATS,
-    QEMU_IFLA_INFO_SLAVE_KIND,
-    QEMU_IFLA_INFO_SLAVE_DATA,
-    QEMU___IFLA_INFO_MAX,
-};
-
-enum {
-    QEMU_IFLA_INET_UNSPEC,
-    QEMU_IFLA_INET_CONF,
-    QEMU___IFLA_INET_MAX,
-};
-
-enum {
-    QEMU_IFLA_INET6_UNSPEC,
-    QEMU_IFLA_INET6_FLAGS,
-    QEMU_IFLA_INET6_CONF,
-    QEMU_IFLA_INET6_STATS,
-    QEMU_IFLA_INET6_MCAST,
-    QEMU_IFLA_INET6_CACHEINFO,
-    QEMU_IFLA_INET6_ICMP6STATS,
-    QEMU_IFLA_INET6_TOKEN,
-    QEMU_IFLA_INET6_ADDR_GEN_MODE,
-    QEMU___IFLA_INET6_MAX
-};
-
 typedef abi_long (*TargetFdDataFunc)(void *, size_t);
 typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t);
 typedef struct TargetFdTrans {
@@ -456,14 +300,6 @@ static TargetFdTrans **target_fd_trans;
 
 static unsigned int target_fd_max;
 
-static TargetFdDataFunc fd_trans_target_to_host_data(int fd)
-{
-    if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
-        return target_fd_trans[fd]->target_to_host_data;
-    }
-    return NULL;
-}
-
 static TargetFdDataFunc fd_trans_host_to_target_data(int fd)
 {
     if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
@@ -519,6 +355,18 @@ static int sys_getcwd1(char *buf, size_t size)
   return strlen(buf)+1;
 }
 
+static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode)
+{
+  /*
+   * open(2) has extra parameter 'mode' when called with
+   * flag O_CREAT.
+   */
+  if ((flags & O_CREAT) != 0) {
+      return (openat(dirfd, pathname, flags, mode));
+  }
+  return (openat(dirfd, pathname, flags));
+}
+
 #ifdef TARGET_NR_utimensat
 #ifdef CONFIG_UTIMENSAT
 static int sys_utimensat(int dirfd, const char *pathname,
@@ -580,6 +428,25 @@ static int sys_inotify_init1(int flags)
 #undef TARGET_NR_inotify_rm_watch
 #endif /* CONFIG_INOTIFY  */
 
+#if defined(TARGET_NR_ppoll)
+#ifndef __NR_ppoll
+# define __NR_ppoll -1
+#endif
+#define __NR_sys_ppoll __NR_ppoll
+_syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
+          struct timespec *, timeout, const sigset_t *, sigmask,
+          size_t, sigsetsize)
+#endif
+
+#if defined(TARGET_NR_pselect6)
+#ifndef __NR_pselect6
+# define __NR_pselect6 -1
+#endif
+#define __NR_sys_pselect6 __NR_pselect6
+_syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
+          fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
+#endif
+
 #if defined(TARGET_NR_prlimit64)
 #ifndef __NR_prlimit64
 # define __NR_prlimit64 -1
@@ -752,19 +619,15 @@ static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
 
 static inline int host_to_target_errno(int err)
 {
-    if (err >= 0 && err < ERRNO_TABLE_SIZE &&
-        host_to_target_errno_table[err]) {
+    if(host_to_target_errno_table[err])
         return host_to_target_errno_table[err];
-    }
     return err;
 }
 
 static inline int target_to_host_errno(int err)
 {
-    if (err >= 0 && err < ERRNO_TABLE_SIZE &&
-        target_to_host_errno_table[err]) {
+    if (target_to_host_errno_table[err])
         return target_to_host_errno_table[err];
-    }
     return err;
 }
 
@@ -781,171 +644,14 @@ static inline int is_error(abi_long ret)
     return (abi_ulong)ret >= (abi_ulong)(-4096);
 }
 
-const char *target_strerror(int err)
+char *target_strerror(int err)
 {
-    if (err == TARGET_ERESTARTSYS) {
-        return "To be restarted";
-    }
-    if (err == TARGET_QEMU_ESIGRETURN) {
-        return "Successful exit from sigreturn";
-    }
-
     if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
         return NULL;
     }
     return strerror(target_to_host_errno(err));
 }
 
-#define safe_syscall0(type, name) \
-static type safe_##name(void) \
-{ \
-    return safe_syscall(__NR_##name); \
-}
-
-#define safe_syscall1(type, name, type1, arg1) \
-static type safe_##name(type1 arg1) \
-{ \
-    return safe_syscall(__NR_##name, arg1); \
-}
-
-#define safe_syscall2(type, name, type1, arg1, type2, arg2) \
-static type safe_##name(type1 arg1, type2 arg2) \
-{ \
-    return safe_syscall(__NR_##name, arg1, arg2); \
-}
-
-#define safe_syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
-static type safe_##name(type1 arg1, type2 arg2, type3 arg3) \
-{ \
-    return safe_syscall(__NR_##name, arg1, arg2, arg3); \
-}
-
-#define safe_syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
-    type4, arg4) \
-static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
-    return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4); \
-}
-
-#define safe_syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
-    type4, arg4, type5, arg5) \
-static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
-    type5 arg5) \
-{ \
-    return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
-}
-
-#define safe_syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
-    type4, arg4, type5, arg5, type6, arg6) \
-static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
-    type5 arg5, type6 arg6) \
-{ \
-    return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
-}
-
-safe_syscall3(ssize_t, read, int, fd, void *, buff, size_t, count)
-safe_syscall3(ssize_t, write, int, fd, const void *, buff, size_t, count)
-safe_syscall4(int, openat, int, dirfd, const char *, pathname, \
-              int, flags, mode_t, mode)
-safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, \
-              struct rusage *, rusage)
-safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \
-              int, options, struct rusage *, rusage)
-safe_syscall3(int, execve, const char *, filename, char **, argv, char **, envp)
-safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, \
-              fd_set *, exceptfds, struct timespec *, timeout, void *, sig)
-safe_syscall5(int, ppoll, struct pollfd *, ufds, unsigned int, nfds,
-              struct timespec *, tsp, const sigset_t *, sigmask,
-              size_t, sigsetsize)
-safe_syscall6(int, epoll_pwait, int, epfd, struct epoll_event *, events,
-              int, maxevents, int, timeout, const sigset_t *, sigmask,
-              size_t, sigsetsize)
-safe_syscall6(int,futex,int *,uaddr,int,op,int,val, \
-              const struct timespec *,timeout,int *,uaddr2,int,val3)
-safe_syscall2(int, rt_sigsuspend, sigset_t *, newset, size_t, sigsetsize)
-safe_syscall2(int, kill, pid_t, pid, int, sig)
-safe_syscall2(int, tkill, int, tid, int, sig)
-safe_syscall3(int, tgkill, int, tgid, int, pid, int, sig)
-safe_syscall3(ssize_t, readv, int, fd, const struct iovec *, iov, int, iovcnt)
-safe_syscall3(ssize_t, writev, int, fd, const struct iovec *, iov, int, iovcnt)
-safe_syscall3(int, connect, int, fd, const struct sockaddr *, addr,
-              socklen_t, addrlen)
-safe_syscall6(ssize_t, sendto, int, fd, const void *, buf, size_t, len,
-              int, flags, const struct sockaddr *, addr, socklen_t, addrlen)
-safe_syscall6(ssize_t, recvfrom, int, fd, void *, buf, size_t, len,
-              int, flags, struct sockaddr *, addr, socklen_t *, addrlen)
-safe_syscall3(ssize_t, sendmsg, int, fd, const struct msghdr *, msg, int, flags)
-safe_syscall3(ssize_t, recvmsg, int, fd, struct msghdr *, msg, int, flags)
-safe_syscall2(int, flock, int, fd, int, operation)
-safe_syscall4(int, rt_sigtimedwait, const sigset_t *, these, siginfo_t *, uinfo,
-              const struct timespec *, uts, size_t, sigsetsize)
-safe_syscall4(int, accept4, int, fd, struct sockaddr *, addr, socklen_t *, len,
-              int, flags)
-safe_syscall2(int, nanosleep, const struct timespec *, req,
-              struct timespec *, rem)
-#ifdef TARGET_NR_clock_nanosleep
-safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
-              const struct timespec *, req, struct timespec *, rem)
-#endif
-#ifdef __NR_msgsnd
-safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
-              int, flags)
-safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz,
-              long, msgtype, int, flags)
-safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
-              unsigned, nsops, const struct timespec *, timeout)
-#else
-/* This host kernel architecture uses a single ipc syscall; fake up
- * wrappers for the sub-operations to hide this implementation detail.
- * Annoyingly we can't include linux/ipc.h to get the constant definitions
- * for the call parameter because some structs in there conflict with the
- * sys/ipc.h ones. So we just define them here, and rely on them being
- * the same for all host architectures.
- */
-#define Q_SEMTIMEDOP 4
-#define Q_MSGSND 11
-#define Q_MSGRCV 12
-#define Q_IPCCALL(VERSION, OP) ((VERSION) << 16 | (OP))
-
-safe_syscall6(int, ipc, int, call, long, first, long, second, long, third,
-              void *, ptr, long, fifth)
-static int safe_msgsnd(int msgid, const void *msgp, size_t sz, int flags)
-{
-    return safe_ipc(Q_IPCCALL(0, Q_MSGSND), msgid, sz, flags, (void *)msgp, 0);
-}
-static int safe_msgrcv(int msgid, void *msgp, size_t sz, long type, int flags)
-{
-    return safe_ipc(Q_IPCCALL(1, Q_MSGRCV), msgid, sz, flags, msgp, type);
-}
-static int safe_semtimedop(int semid, struct sembuf *tsops, unsigned nsops,
-                           const struct timespec *timeout)
-{
-    return safe_ipc(Q_IPCCALL(0, Q_SEMTIMEDOP), semid, nsops, 0, tsops,
-                    (long)timeout);
-}
-#endif
-#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
-safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr,
-              size_t, len, unsigned, prio, const struct timespec *, timeout)
-safe_syscall5(int, mq_timedreceive, int, mqdes, char *, msg_ptr,
-              size_t, len, unsigned *, prio, const struct timespec *, timeout)
-#endif
-/* We do ioctl like this rather than via safe_syscall3 to preserve the
- * "third argument might be integer or pointer or not present" behaviour of
- * the libc function.
- */
-#define safe_ioctl(...) safe_syscall(__NR_ioctl, __VA_ARGS__)
-/* Similarly for fcntl. Note that callers must always:
- *  pass the F_GETLK64 etc constants rather than the unsuffixed F_GETLK
- *  use the flock64 struct rather than unsuffixed flock
- * This will then work and use a 64-bit offset for both 32-bit and 64-bit hosts.
- */
-#ifdef __NR_fcntl64
-#define safe_fcntl(...) safe_syscall(__NR_fcntl64, __VA_ARGS__)
-#else
-#define safe_fcntl(...) safe_syscall(__NR_fcntl, __VA_ARGS__)
-#endif
-
 static inline int host_to_target_sock_type(int host_type)
 {
     int target_type;
@@ -994,7 +700,7 @@ void target_set_brk(abi_ulong new_brk)
 abi_long do_brk(abi_ulong new_brk)
 {
     abi_long mapped_addr;
-    abi_ulong new_alloc_size;
+    int        new_alloc_size;
 
     DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
 
@@ -1075,7 +781,7 @@ static inline abi_long copy_from_user_fdset(fd_set *fds,
     int i, nw, j, k;
     abi_ulong b, *target_fds;
 
-    nw = DIV_ROUND_UP(n, TARGET_ABI_BITS);
+    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
     if (!(target_fds = lock_user(VERIFY_READ,
                                  target_fds_addr,
                                  sizeof(abi_ulong) * nw,
@@ -1122,7 +828,7 @@ static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
     abi_long v;
     abi_ulong *target_fds;
 
-    nw = DIV_ROUND_UP(n, TARGET_ABI_BITS);
+    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
     if (!(target_fds = lock_user(VERIFY_WRITE,
                                  target_fds_addr,
                                  sizeof(abi_ulong) * nw,
@@ -1356,8 +1062,7 @@ static abi_long do_select(int n,
 {
     fd_set rfds, wfds, efds;
     fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
-    struct timeval tv;
-    struct timespec ts, *ts_ptr;
+    struct timeval tv, *tv_ptr;
     abi_long ret;
 
     ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
@@ -1376,15 +1081,12 @@ static abi_long do_select(int n,
     if (target_tv_addr) {
         if (copy_from_user_timeval(&tv, target_tv_addr))
             return -TARGET_EFAULT;
-        ts.tv_sec = tv.tv_sec;
-        ts.tv_nsec = tv.tv_usec * 1000;
-        ts_ptr = &ts;
+        tv_ptr = &tv;
     } else {
-        ts_ptr = NULL;
+        tv_ptr = NULL;
     }
 
-    ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
-                                  ts_ptr, NULL));
+    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
 
     if (!is_error(ret)) {
         if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
@@ -1394,13 +1096,8 @@ static abi_long do_select(int n,
         if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
             return -TARGET_EFAULT;
 
-        if (target_tv_addr) {
-            tv.tv_sec = ts.tv_sec;
-            tv.tv_usec = ts.tv_nsec / 1000;
-            if (copy_to_user_timeval(target_tv_addr, &tv)) {
-                return -TARGET_EFAULT;
-            }
-        }
+        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
+            return -TARGET_EFAULT;
     }
 
     return ret;
@@ -1507,13 +1204,7 @@ static inline abi_long target_to_host_sockaddr(int fd, struct sockaddr *addr,
 
     memcpy(addr, target_saddr, len);
     addr->sa_family = sa_family;
-    if (sa_family == AF_NETLINK) {
-        struct sockaddr_nl *nladdr;
-
-        nladdr = (struct sockaddr_nl *)addr;
-        nladdr->nl_pid = tswap32(nladdr->nl_pid);
-        nladdr->nl_groups = tswap32(nladdr->nl_groups);
-    } else if (sa_family == AF_PACKET) {
+    if (sa_family == AF_PACKET) {
        struct target_sockaddr_ll *lladdr;
 
        lladdr = (struct target_sockaddr_ll *)addr;
@@ -1531,27 +1222,11 @@ static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
 {
     struct target_sockaddr *target_saddr;
 
-    if (len == 0) {
-        return 0;
-    }
-
     target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
     if (!target_saddr)
         return -TARGET_EFAULT;
     memcpy(target_saddr, addr, len);
-    if (len >= offsetof(struct target_sockaddr, sa_family) +
-        sizeof(target_saddr->sa_family)) {
-        target_saddr->sa_family = tswap16(addr->sa_family);
-    }
-    if (addr->sa_family == AF_NETLINK && len >= sizeof(struct sockaddr_nl)) {
-        struct sockaddr_nl *target_nl = (struct sockaddr_nl *)target_saddr;
-        target_nl->nl_pid = tswap32(target_nl->nl_pid);
-        target_nl->nl_groups = tswap32(target_nl->nl_groups);
-    } else if (addr->sa_family == AF_PACKET) {
-        struct sockaddr_ll *target_ll = (struct sockaddr_ll *)target_saddr;
-        target_ll->sll_ifindex = tswap32(target_ll->sll_ifindex);
-        target_ll->sll_hatype = tswap16(target_ll->sll_hatype);
-    }
+    target_saddr->sa_family = tswap16(addr->sa_family);
     unlock_user(target_saddr, target_addr, len);
 
     return 0;
@@ -1783,875 +1458,6 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
     return 0;
 }
 
-static void tswap_nlmsghdr(struct nlmsghdr *nlh)
-{
-    nlh->nlmsg_len = tswap32(nlh->nlmsg_len);
-    nlh->nlmsg_type = tswap16(nlh->nlmsg_type);
-    nlh->nlmsg_flags = tswap16(nlh->nlmsg_flags);
-    nlh->nlmsg_seq = tswap32(nlh->nlmsg_seq);
-    nlh->nlmsg_pid = tswap32(nlh->nlmsg_pid);
-}
-
-static abi_long host_to_target_for_each_nlmsg(struct nlmsghdr *nlh,
-                                              size_t len,
-                                              abi_long (*host_to_target_nlmsg)
-                                                       (struct nlmsghdr *))
-{
-    uint32_t nlmsg_len;
-    abi_long ret;
-
-    while (len > sizeof(struct nlmsghdr)) {
-
-        nlmsg_len = nlh->nlmsg_len;
-        if (nlmsg_len < sizeof(struct nlmsghdr) ||
-            nlmsg_len > len) {
-            break;
-        }
-
-        switch (nlh->nlmsg_type) {
-        case NLMSG_DONE:
-            tswap_nlmsghdr(nlh);
-            return 0;
-        case NLMSG_NOOP:
-            break;
-        case NLMSG_ERROR:
-        {
-            struct nlmsgerr *e = NLMSG_DATA(nlh);
-            e->error = tswap32(e->error);
-            tswap_nlmsghdr(&e->msg);
-            tswap_nlmsghdr(nlh);
-            return 0;
-        }
-        default:
-            ret = host_to_target_nlmsg(nlh);
-            if (ret < 0) {
-                tswap_nlmsghdr(nlh);
-                return ret;
-            }
-            break;
-        }
-        tswap_nlmsghdr(nlh);
-        len -= NLMSG_ALIGN(nlmsg_len);
-        nlh = (struct nlmsghdr *)(((char*)nlh) + NLMSG_ALIGN(nlmsg_len));
-    }
-    return 0;
-}
-
-static abi_long target_to_host_for_each_nlmsg(struct nlmsghdr *nlh,
-                                              size_t len,
-                                              abi_long (*target_to_host_nlmsg)
-                                                       (struct nlmsghdr *))
-{
-    int ret;
-
-    while (len > sizeof(struct nlmsghdr)) {
-        if (tswap32(nlh->nlmsg_len) < sizeof(struct nlmsghdr) ||
-            tswap32(nlh->nlmsg_len) > len) {
-            break;
-        }
-        tswap_nlmsghdr(nlh);
-        switch (nlh->nlmsg_type) {
-        case NLMSG_DONE:
-            return 0;
-        case NLMSG_NOOP:
-            break;
-        case NLMSG_ERROR:
-        {
-            struct nlmsgerr *e = NLMSG_DATA(nlh);
-            e->error = tswap32(e->error);
-            tswap_nlmsghdr(&e->msg);
-            return 0;
-        }
-        default:
-            ret = target_to_host_nlmsg(nlh);
-            if (ret < 0) {
-                return ret;
-            }
-        }
-        len -= NLMSG_ALIGN(nlh->nlmsg_len);
-        nlh = (struct nlmsghdr *)(((char *)nlh) + NLMSG_ALIGN(nlh->nlmsg_len));
-    }
-    return 0;
-}
-
-#ifdef CONFIG_RTNETLINK
-static abi_long host_to_target_for_each_nlattr(struct nlattr *nlattr,
-                                               size_t len, void *context,
-                                               abi_long (*host_to_target_nlattr)
-                                                        (struct nlattr *,
-                                                         void *context))
-{
-    unsigned short nla_len;
-    abi_long ret;
-
-    while (len > sizeof(struct nlattr)) {
-        nla_len = nlattr->nla_len;
-        if (nla_len < sizeof(struct nlattr) ||
-            nla_len > len) {
-            break;
-        }
-        ret = host_to_target_nlattr(nlattr, context);
-        nlattr->nla_len = tswap16(nlattr->nla_len);
-        nlattr->nla_type = tswap16(nlattr->nla_type);
-        if (ret < 0) {
-            return ret;
-        }
-        len -= NLA_ALIGN(nla_len);
-        nlattr = (struct nlattr *)(((char *)nlattr) + NLA_ALIGN(nla_len));
-    }
-    return 0;
-}
-
-static abi_long host_to_target_for_each_rtattr(struct rtattr *rtattr,
-                                               size_t len,
-                                               abi_long (*host_to_target_rtattr)
-                                                        (struct rtattr *))
-{
-    unsigned short rta_len;
-    abi_long ret;
-
-    while (len > sizeof(struct rtattr)) {
-        rta_len = rtattr->rta_len;
-        if (rta_len < sizeof(struct rtattr) ||
-            rta_len > len) {
-            break;
-        }
-        ret = host_to_target_rtattr(rtattr);
-        rtattr->rta_len = tswap16(rtattr->rta_len);
-        rtattr->rta_type = tswap16(rtattr->rta_type);
-        if (ret < 0) {
-            return ret;
-        }
-        len -= RTA_ALIGN(rta_len);
-        rtattr = (struct rtattr *)(((char *)rtattr) + RTA_ALIGN(rta_len));
-    }
-    return 0;
-}
-
-#define NLA_DATA(nla) ((void *)((char *)(nla)) + NLA_HDRLEN)
-
-static abi_long host_to_target_data_bridge_nlattr(struct nlattr *nlattr,
-                                                  void *context)
-{
-    uint16_t *u16;
-    uint32_t *u32;
-    uint64_t *u64;
-
-    switch (nlattr->nla_type) {
-    /* no data */
-    case QEMU_IFLA_BR_FDB_FLUSH:
-        break;
-    /* binary */
-    case QEMU_IFLA_BR_GROUP_ADDR:
-        break;
-    /* uint8_t */
-    case QEMU_IFLA_BR_VLAN_FILTERING:
-    case QEMU_IFLA_BR_TOPOLOGY_CHANGE:
-    case QEMU_IFLA_BR_TOPOLOGY_CHANGE_DETECTED:
-    case QEMU_IFLA_BR_MCAST_ROUTER:
-    case QEMU_IFLA_BR_MCAST_SNOOPING:
-    case QEMU_IFLA_BR_MCAST_QUERY_USE_IFADDR:
-    case QEMU_IFLA_BR_MCAST_QUERIER:
-    case QEMU_IFLA_BR_NF_CALL_IPTABLES:
-    case QEMU_IFLA_BR_NF_CALL_IP6TABLES:
-    case QEMU_IFLA_BR_NF_CALL_ARPTABLES:
-        break;
-    /* uint16_t */
-    case QEMU_IFLA_BR_PRIORITY:
-    case QEMU_IFLA_BR_VLAN_PROTOCOL:
-    case QEMU_IFLA_BR_GROUP_FWD_MASK:
-    case QEMU_IFLA_BR_ROOT_PORT:
-    case QEMU_IFLA_BR_VLAN_DEFAULT_PVID:
-        u16 = NLA_DATA(nlattr);
-        *u16 = tswap16(*u16);
-        break;
-    /* uint32_t */
-    case QEMU_IFLA_BR_FORWARD_DELAY:
-    case QEMU_IFLA_BR_HELLO_TIME:
-    case QEMU_IFLA_BR_MAX_AGE:
-    case QEMU_IFLA_BR_AGEING_TIME:
-    case QEMU_IFLA_BR_STP_STATE:
-    case QEMU_IFLA_BR_ROOT_PATH_COST:
-    case QEMU_IFLA_BR_MCAST_HASH_ELASTICITY:
-    case QEMU_IFLA_BR_MCAST_HASH_MAX:
-    case QEMU_IFLA_BR_MCAST_LAST_MEMBER_CNT:
-    case QEMU_IFLA_BR_MCAST_STARTUP_QUERY_CNT:
-        u32 = NLA_DATA(nlattr);
-        *u32 = tswap32(*u32);
-        break;
-    /* uint64_t */
-    case QEMU_IFLA_BR_HELLO_TIMER:
-    case QEMU_IFLA_BR_TCN_TIMER:
-    case QEMU_IFLA_BR_GC_TIMER:
-    case QEMU_IFLA_BR_TOPOLOGY_CHANGE_TIMER:
-    case QEMU_IFLA_BR_MCAST_LAST_MEMBER_INTVL:
-    case QEMU_IFLA_BR_MCAST_MEMBERSHIP_INTVL:
-    case QEMU_IFLA_BR_MCAST_QUERIER_INTVL:
-    case QEMU_IFLA_BR_MCAST_QUERY_INTVL:
-    case QEMU_IFLA_BR_MCAST_QUERY_RESPONSE_INTVL:
-    case QEMU_IFLA_BR_MCAST_STARTUP_QUERY_INTVL:
-        u64 = NLA_DATA(nlattr);
-        *u64 = tswap64(*u64);
-        break;
-    /* ifla_bridge_id: uin8_t[] */
-    case QEMU_IFLA_BR_ROOT_ID:
-    case QEMU_IFLA_BR_BRIDGE_ID:
-        break;
-    default:
-        gemu_log("Unknown QEMU_IFLA_BR type %d\n", nlattr->nla_type);
-        break;
-    }
-    return 0;
-}
-
-static abi_long host_to_target_slave_data_bridge_nlattr(struct nlattr *nlattr,
-                                                        void *context)
-{
-    uint16_t *u16;
-    uint32_t *u32;
-    uint64_t *u64;
-
-    switch (nlattr->nla_type) {
-    /* uint8_t */
-    case QEMU_IFLA_BRPORT_STATE:
-    case QEMU_IFLA_BRPORT_MODE:
-    case QEMU_IFLA_BRPORT_GUARD:
-    case QEMU_IFLA_BRPORT_PROTECT:
-    case QEMU_IFLA_BRPORT_FAST_LEAVE:
-    case QEMU_IFLA_BRPORT_LEARNING:
-    case QEMU_IFLA_BRPORT_UNICAST_FLOOD:
-    case QEMU_IFLA_BRPORT_PROXYARP:
-    case QEMU_IFLA_BRPORT_LEARNING_SYNC:
-    case QEMU_IFLA_BRPORT_PROXYARP_WIFI:
-    case QEMU_IFLA_BRPORT_TOPOLOGY_CHANGE_ACK:
-    case QEMU_IFLA_BRPORT_CONFIG_PENDING:
-    case QEMU_IFLA_BRPORT_MULTICAST_ROUTER:
-        break;
-    /* uint16_t */
-    case QEMU_IFLA_BRPORT_PRIORITY:
-    case QEMU_IFLA_BRPORT_DESIGNATED_PORT:
-    case QEMU_IFLA_BRPORT_DESIGNATED_COST:
-    case QEMU_IFLA_BRPORT_ID:
-    case QEMU_IFLA_BRPORT_NO:
-        u16 = NLA_DATA(nlattr);
-        *u16 = tswap16(*u16);
-        break;
-    /* uin32_t */
-    case QEMU_IFLA_BRPORT_COST:
-        u32 = NLA_DATA(nlattr);
-        *u32 = tswap32(*u32);
-        break;
-    /* uint64_t */
-    case QEMU_IFLA_BRPORT_MESSAGE_AGE_TIMER:
-    case QEMU_IFLA_BRPORT_FORWARD_DELAY_TIMER:
-    case QEMU_IFLA_BRPORT_HOLD_TIMER:
-        u64 = NLA_DATA(nlattr);
-        *u64 = tswap64(*u64);
-        break;
-    /* ifla_bridge_id: uint8_t[] */
-    case QEMU_IFLA_BRPORT_ROOT_ID:
-    case QEMU_IFLA_BRPORT_BRIDGE_ID:
-        break;
-    default:
-        gemu_log("Unknown QEMU_IFLA_BRPORT type %d\n", nlattr->nla_type);
-        break;
-    }
-    return 0;
-}
-
-struct linkinfo_context {
-    int len;
-    char *name;
-    int slave_len;
-    char *slave_name;
-};
-
-static abi_long host_to_target_data_linkinfo_nlattr(struct nlattr *nlattr,
-                                                    void *context)
-{
-    struct linkinfo_context *li_context = context;
-
-    switch (nlattr->nla_type) {
-    /* string */
-    case QEMU_IFLA_INFO_KIND:
-        li_context->name = NLA_DATA(nlattr);
-        li_context->len = nlattr->nla_len - NLA_HDRLEN;
-        break;
-    case QEMU_IFLA_INFO_SLAVE_KIND:
-        li_context->slave_name = NLA_DATA(nlattr);
-        li_context->slave_len = nlattr->nla_len - NLA_HDRLEN;
-        break;
-    /* stats */
-    case QEMU_IFLA_INFO_XSTATS:
-        /* FIXME: only used by CAN */
-        break;
-    /* nested */
-    case QEMU_IFLA_INFO_DATA:
-        if (strncmp(li_context->name, "bridge",
-                    li_context->len) == 0) {
-            return host_to_target_for_each_nlattr(NLA_DATA(nlattr),
-                                                  nlattr->nla_len,
-                                                  NULL,
-                                             host_to_target_data_bridge_nlattr);
-        } else {
-            gemu_log("Unknown QEMU_IFLA_INFO_KIND %s\n", li_context->name);
-        }
-        break;
-    case QEMU_IFLA_INFO_SLAVE_DATA:
-        if (strncmp(li_context->slave_name, "bridge",
-                    li_context->slave_len) == 0) {
-            return host_to_target_for_each_nlattr(NLA_DATA(nlattr),
-                                                  nlattr->nla_len,
-                                                  NULL,
-                                       host_to_target_slave_data_bridge_nlattr);
-        } else {
-            gemu_log("Unknown QEMU_IFLA_INFO_SLAVE_KIND %s\n",
-                     li_context->slave_name);
-        }
-        break;
-    default:
-        gemu_log("Unknown host QEMU_IFLA_INFO type: %d\n", nlattr->nla_type);
-        break;
-    }
-
-    return 0;
-}
-
-static abi_long host_to_target_data_inet_nlattr(struct nlattr *nlattr,
-                                                void *context)
-{
-    uint32_t *u32;
-    int i;
-
-    switch (nlattr->nla_type) {
-    case QEMU_IFLA_INET_CONF:
-        u32 = NLA_DATA(nlattr);
-        for (i = 0; i < (nlattr->nla_len - NLA_HDRLEN) / sizeof(*u32);
-             i++) {
-            u32[i] = tswap32(u32[i]);
-        }
-        break;
-    default:
-        gemu_log("Unknown host AF_INET type: %d\n", nlattr->nla_type);
-    }
-    return 0;
-}
-
-static abi_long host_to_target_data_inet6_nlattr(struct nlattr *nlattr,
-                                                void *context)
-{
-    uint32_t *u32;
-    uint64_t *u64;
-    struct ifla_cacheinfo *ci;
-    int i;
-
-    switch (nlattr->nla_type) {
-    /* binaries */
-    case QEMU_IFLA_INET6_TOKEN:
-        break;
-    /* uint8_t */
-    case QEMU_IFLA_INET6_ADDR_GEN_MODE:
-        break;
-    /* uint32_t */
-    case QEMU_IFLA_INET6_FLAGS:
-        u32 = NLA_DATA(nlattr);
-        *u32 = tswap32(*u32);
-        break;
-    /* uint32_t[] */
-    case QEMU_IFLA_INET6_CONF:
-        u32 = NLA_DATA(nlattr);
-        for (i = 0; i < (nlattr->nla_len - NLA_HDRLEN) / sizeof(*u32);
-             i++) {
-            u32[i] = tswap32(u32[i]);
-        }
-        break;
-    /* ifla_cacheinfo */
-    case QEMU_IFLA_INET6_CACHEINFO:
-        ci = NLA_DATA(nlattr);
-        ci->max_reasm_len = tswap32(ci->max_reasm_len);
-        ci->tstamp = tswap32(ci->tstamp);
-        ci->reachable_time = tswap32(ci->reachable_time);
-        ci->retrans_time = tswap32(ci->retrans_time);
-        break;
-    /* uint64_t[] */
-    case QEMU_IFLA_INET6_STATS:
-    case QEMU_IFLA_INET6_ICMP6STATS:
-        u64 = NLA_DATA(nlattr);
-        for (i = 0; i < (nlattr->nla_len - NLA_HDRLEN) / sizeof(*u64);
-             i++) {
-            u64[i] = tswap64(u64[i]);
-        }
-        break;
-    default:
-        gemu_log("Unknown host AF_INET6 type: %d\n", nlattr->nla_type);
-    }
-    return 0;
-}
-
-static abi_long host_to_target_data_spec_nlattr(struct nlattr *nlattr,
-                                                    void *context)
-{
-    switch (nlattr->nla_type) {
-    case AF_INET:
-        return host_to_target_for_each_nlattr(NLA_DATA(nlattr), nlattr->nla_len,
-                                              NULL,
-                                             host_to_target_data_inet_nlattr);
-    case AF_INET6:
-        return host_to_target_for_each_nlattr(NLA_DATA(nlattr), nlattr->nla_len,
-                                              NULL,
-                                             host_to_target_data_inet6_nlattr);
-    default:
-        gemu_log("Unknown host AF_SPEC type: %d\n", nlattr->nla_type);
-        break;
-    }
-    return 0;
-}
-
-static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr)
-{
-    uint32_t *u32;
-    struct rtnl_link_stats *st;
-    struct rtnl_link_stats64 *st64;
-    struct rtnl_link_ifmap *map;
-    struct linkinfo_context li_context;
-
-    switch (rtattr->rta_type) {
-    /* binary stream */
-    case QEMU_IFLA_ADDRESS:
-    case QEMU_IFLA_BROADCAST:
-    /* string */
-    case QEMU_IFLA_IFNAME:
-    case QEMU_IFLA_QDISC:
-        break;
-    /* uin8_t */
-    case QEMU_IFLA_OPERSTATE:
-    case QEMU_IFLA_LINKMODE:
-    case QEMU_IFLA_CARRIER:
-    case QEMU_IFLA_PROTO_DOWN:
-        break;
-    /* uint32_t */
-    case QEMU_IFLA_MTU:
-    case QEMU_IFLA_LINK:
-    case QEMU_IFLA_WEIGHT:
-    case QEMU_IFLA_TXQLEN:
-    case QEMU_IFLA_CARRIER_CHANGES:
-    case QEMU_IFLA_NUM_RX_QUEUES:
-    case QEMU_IFLA_NUM_TX_QUEUES:
-    case QEMU_IFLA_PROMISCUITY:
-    case QEMU_IFLA_EXT_MASK:
-    case QEMU_IFLA_LINK_NETNSID:
-    case QEMU_IFLA_GROUP:
-    case QEMU_IFLA_MASTER:
-    case QEMU_IFLA_NUM_VF:
-        u32 = RTA_DATA(rtattr);
-        *u32 = tswap32(*u32);
-        break;
-    /* struct rtnl_link_stats */
-    case QEMU_IFLA_STATS:
-        st = RTA_DATA(rtattr);
-        st->rx_packets = tswap32(st->rx_packets);
-        st->tx_packets = tswap32(st->tx_packets);
-        st->rx_bytes = tswap32(st->rx_bytes);
-        st->tx_bytes = tswap32(st->tx_bytes);
-        st->rx_errors = tswap32(st->rx_errors);
-        st->tx_errors = tswap32(st->tx_errors);
-        st->rx_dropped = tswap32(st->rx_dropped);
-        st->tx_dropped = tswap32(st->tx_dropped);
-        st->multicast = tswap32(st->multicast);
-        st->collisions = tswap32(st->collisions);
-
-        /* detailed rx_errors: */
-        st->rx_length_errors = tswap32(st->rx_length_errors);
-        st->rx_over_errors = tswap32(st->rx_over_errors);
-        st->rx_crc_errors = tswap32(st->rx_crc_errors);
-        st->rx_frame_errors = tswap32(st->rx_frame_errors);
-        st->rx_fifo_errors = tswap32(st->rx_fifo_errors);
-        st->rx_missed_errors = tswap32(st->rx_missed_errors);
-
-        /* detailed tx_errors */
-        st->tx_aborted_errors = tswap32(st->tx_aborted_errors);
-        st->tx_carrier_errors = tswap32(st->tx_carrier_errors);
-        st->tx_fifo_errors = tswap32(st->tx_fifo_errors);
-        st->tx_heartbeat_errors = tswap32(st->tx_heartbeat_errors);
-        st->tx_window_errors = tswap32(st->tx_window_errors);
-
-        /* for cslip etc */
-        st->rx_compressed = tswap32(st->rx_compressed);
-        st->tx_compressed = tswap32(st->tx_compressed);
-        break;
-    /* struct rtnl_link_stats64 */
-    case QEMU_IFLA_STATS64:
-        st64 = RTA_DATA(rtattr);
-        st64->rx_packets = tswap64(st64->rx_packets);
-        st64->tx_packets = tswap64(st64->tx_packets);
-        st64->rx_bytes = tswap64(st64->rx_bytes);
-        st64->tx_bytes = tswap64(st64->tx_bytes);
-        st64->rx_errors = tswap64(st64->rx_errors);
-        st64->tx_errors = tswap64(st64->tx_errors);
-        st64->rx_dropped = tswap64(st64->rx_dropped);
-        st64->tx_dropped = tswap64(st64->tx_dropped);
-        st64->multicast = tswap64(st64->multicast);
-        st64->collisions = tswap64(st64->collisions);
-
-        /* detailed rx_errors: */
-        st64->rx_length_errors = tswap64(st64->rx_length_errors);
-        st64->rx_over_errors = tswap64(st64->rx_over_errors);
-        st64->rx_crc_errors = tswap64(st64->rx_crc_errors);
-        st64->rx_frame_errors = tswap64(st64->rx_frame_errors);
-        st64->rx_fifo_errors = tswap64(st64->rx_fifo_errors);
-        st64->rx_missed_errors = tswap64(st64->rx_missed_errors);
-
-        /* detailed tx_errors */
-        st64->tx_aborted_errors = tswap64(st64->tx_aborted_errors);
-        st64->tx_carrier_errors = tswap64(st64->tx_carrier_errors);
-        st64->tx_fifo_errors = tswap64(st64->tx_fifo_errors);
-        st64->tx_heartbeat_errors = tswap64(st64->tx_heartbeat_errors);
-        st64->tx_window_errors = tswap64(st64->tx_window_errors);
-
-        /* for cslip etc */
-        st64->rx_compressed = tswap64(st64->rx_compressed);
-        st64->tx_compressed = tswap64(st64->tx_compressed);
-        break;
-    /* struct rtnl_link_ifmap */
-    case QEMU_IFLA_MAP:
-        map = RTA_DATA(rtattr);
-        map->mem_start = tswap64(map->mem_start);
-        map->mem_end = tswap64(map->mem_end);
-        map->base_addr = tswap64(map->base_addr);
-        map->irq = tswap16(map->irq);
-        break;
-    /* nested */
-    case QEMU_IFLA_LINKINFO:
-        memset(&li_context, 0, sizeof(li_context));
-        return host_to_target_for_each_nlattr(RTA_DATA(rtattr), rtattr->rta_len,
-                                              &li_context,
-                                           host_to_target_data_linkinfo_nlattr);
-    case QEMU_IFLA_AF_SPEC:
-        return host_to_target_for_each_nlattr(RTA_DATA(rtattr), rtattr->rta_len,
-                                              NULL,
-                                             host_to_target_data_spec_nlattr);
-    default:
-        gemu_log("Unknown host QEMU_IFLA type: %d\n", rtattr->rta_type);
-        break;
-    }
-    return 0;
-}
-
-static abi_long host_to_target_data_addr_rtattr(struct rtattr *rtattr)
-{
-    uint32_t *u32;
-    struct ifa_cacheinfo *ci;
-
-    switch (rtattr->rta_type) {
-    /* binary: depends on family type */
-    case IFA_ADDRESS:
-    case IFA_LOCAL:
-        break;
-    /* string */
-    case IFA_LABEL:
-        break;
-    /* u32 */
-    case IFA_FLAGS:
-    case IFA_BROADCAST:
-        u32 = RTA_DATA(rtattr);
-        *u32 = tswap32(*u32);
-        break;
-    /* struct ifa_cacheinfo */
-    case IFA_CACHEINFO:
-        ci = RTA_DATA(rtattr);
-        ci->ifa_prefered = tswap32(ci->ifa_prefered);
-        ci->ifa_valid = tswap32(ci->ifa_valid);
-        ci->cstamp = tswap32(ci->cstamp);
-        ci->tstamp = tswap32(ci->tstamp);
-        break;
-    default:
-        gemu_log("Unknown host IFA type: %d\n", rtattr->rta_type);
-        break;
-    }
-    return 0;
-}
-
-static abi_long host_to_target_data_route_rtattr(struct rtattr *rtattr)
-{
-    uint32_t *u32;
-    switch (rtattr->rta_type) {
-    /* binary: depends on family type */
-    case RTA_GATEWAY:
-    case RTA_DST:
-    case RTA_PREFSRC:
-        break;
-    /* u32 */
-    case RTA_PRIORITY:
-    case RTA_TABLE:
-    case RTA_OIF:
-        u32 = RTA_DATA(rtattr);
-        *u32 = tswap32(*u32);
-        break;
-    default:
-        gemu_log("Unknown host RTA type: %d\n", rtattr->rta_type);
-        break;
-    }
-    return 0;
-}
-
-static abi_long host_to_target_link_rtattr(struct rtattr *rtattr,
-                                         uint32_t rtattr_len)
-{
-    return host_to_target_for_each_rtattr(rtattr, rtattr_len,
-                                          host_to_target_data_link_rtattr);
-}
-
-static abi_long host_to_target_addr_rtattr(struct rtattr *rtattr,
-                                         uint32_t rtattr_len)
-{
-    return host_to_target_for_each_rtattr(rtattr, rtattr_len,
-                                          host_to_target_data_addr_rtattr);
-}
-
-static abi_long host_to_target_route_rtattr(struct rtattr *rtattr,
-                                         uint32_t rtattr_len)
-{
-    return host_to_target_for_each_rtattr(rtattr, rtattr_len,
-                                          host_to_target_data_route_rtattr);
-}
-
-static abi_long host_to_target_data_route(struct nlmsghdr *nlh)
-{
-    uint32_t nlmsg_len;
-    struct ifinfomsg *ifi;
-    struct ifaddrmsg *ifa;
-    struct rtmsg *rtm;
-
-    nlmsg_len = nlh->nlmsg_len;
-    switch (nlh->nlmsg_type) {
-    case RTM_NEWLINK:
-    case RTM_DELLINK:
-    case RTM_GETLINK:
-        if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*ifi))) {
-            ifi = NLMSG_DATA(nlh);
-            ifi->ifi_type = tswap16(ifi->ifi_type);
-            ifi->ifi_index = tswap32(ifi->ifi_index);
-            ifi->ifi_flags = tswap32(ifi->ifi_flags);
-            ifi->ifi_change = tswap32(ifi->ifi_change);
-            host_to_target_link_rtattr(IFLA_RTA(ifi),
-                                       nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)));
-        }
-        break;
-    case RTM_NEWADDR:
-    case RTM_DELADDR:
-    case RTM_GETADDR:
-        if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*ifa))) {
-            ifa = NLMSG_DATA(nlh);
-            ifa->ifa_index = tswap32(ifa->ifa_index);
-            host_to_target_addr_rtattr(IFA_RTA(ifa),
-                                       nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
-        }
-        break;
-    case RTM_NEWROUTE:
-    case RTM_DELROUTE:
-    case RTM_GETROUTE:
-        if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*rtm))) {
-            rtm = NLMSG_DATA(nlh);
-            rtm->rtm_flags = tswap32(rtm->rtm_flags);
-            host_to_target_route_rtattr(RTM_RTA(rtm),
-                                        nlmsg_len - NLMSG_LENGTH(sizeof(*rtm)));
-        }
-        break;
-    default:
-        return -TARGET_EINVAL;
-    }
-    return 0;
-}
-
-static inline abi_long host_to_target_nlmsg_route(struct nlmsghdr *nlh,
-                                                  size_t len)
-{
-    return host_to_target_for_each_nlmsg(nlh, len, host_to_target_data_route);
-}
-
-static abi_long target_to_host_for_each_rtattr(struct rtattr *rtattr,
-                                               size_t len,
-                                               abi_long (*target_to_host_rtattr)
-                                                        (struct rtattr *))
-{
-    abi_long ret;
-
-    while (len >= sizeof(struct rtattr)) {
-        if (tswap16(rtattr->rta_len) < sizeof(struct rtattr) ||
-            tswap16(rtattr->rta_len) > len) {
-            break;
-        }
-        rtattr->rta_len = tswap16(rtattr->rta_len);
-        rtattr->rta_type = tswap16(rtattr->rta_type);
-        ret = target_to_host_rtattr(rtattr);
-        if (ret < 0) {
-            return ret;
-        }
-        len -= RTA_ALIGN(rtattr->rta_len);
-        rtattr = (struct rtattr *)(((char *)rtattr) +
-                 RTA_ALIGN(rtattr->rta_len));
-    }
-    return 0;
-}
-
-static abi_long target_to_host_data_link_rtattr(struct rtattr *rtattr)
-{
-    switch (rtattr->rta_type) {
-    default:
-        gemu_log("Unknown target QEMU_IFLA type: %d\n", rtattr->rta_type);
-        break;
-    }
-    return 0;
-}
-
-static abi_long target_to_host_data_addr_rtattr(struct rtattr *rtattr)
-{
-    switch (rtattr->rta_type) {
-    /* binary: depends on family type */
-    case IFA_LOCAL:
-    case IFA_ADDRESS:
-        break;
-    default:
-        gemu_log("Unknown target IFA type: %d\n", rtattr->rta_type);
-        break;
-    }
-    return 0;
-}
-
-static abi_long target_to_host_data_route_rtattr(struct rtattr *rtattr)
-{
-    uint32_t *u32;
-    switch (rtattr->rta_type) {
-    /* binary: depends on family type */
-    case RTA_DST:
-    case RTA_SRC:
-    case RTA_GATEWAY:
-        break;
-    /* u32 */
-    case RTA_OIF:
-        u32 = RTA_DATA(rtattr);
-        *u32 = tswap32(*u32);
-        break;
-    default:
-        gemu_log("Unknown target RTA type: %d\n", rtattr->rta_type);
-        break;
-    }
-    return 0;
-}
-
-static void target_to_host_link_rtattr(struct rtattr *rtattr,
-                                       uint32_t rtattr_len)
-{
-    target_to_host_for_each_rtattr(rtattr, rtattr_len,
-                                   target_to_host_data_link_rtattr);
-}
-
-static void target_to_host_addr_rtattr(struct rtattr *rtattr,
-                                     uint32_t rtattr_len)
-{
-    target_to_host_for_each_rtattr(rtattr, rtattr_len,
-                                   target_to_host_data_addr_rtattr);
-}
-
-static void target_to_host_route_rtattr(struct rtattr *rtattr,
-                                     uint32_t rtattr_len)
-{
-    target_to_host_for_each_rtattr(rtattr, rtattr_len,
-                                   target_to_host_data_route_rtattr);
-}
-
-static abi_long target_to_host_data_route(struct nlmsghdr *nlh)
-{
-    struct ifinfomsg *ifi;
-    struct ifaddrmsg *ifa;
-    struct rtmsg *rtm;
-
-    switch (nlh->nlmsg_type) {
-    case RTM_GETLINK:
-        break;
-    case RTM_NEWLINK:
-    case RTM_DELLINK:
-        if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*ifi))) {
-            ifi = NLMSG_DATA(nlh);
-            ifi->ifi_type = tswap16(ifi->ifi_type);
-            ifi->ifi_index = tswap32(ifi->ifi_index);
-            ifi->ifi_flags = tswap32(ifi->ifi_flags);
-            ifi->ifi_change = tswap32(ifi->ifi_change);
-            target_to_host_link_rtattr(IFLA_RTA(ifi), nlh->nlmsg_len -
-                                       NLMSG_LENGTH(sizeof(*ifi)));
-        }
-        break;
-    case RTM_GETADDR:
-    case RTM_NEWADDR:
-    case RTM_DELADDR:
-        if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*ifa))) {
-            ifa = NLMSG_DATA(nlh);
-            ifa->ifa_index = tswap32(ifa->ifa_index);
-            target_to_host_addr_rtattr(IFA_RTA(ifa), nlh->nlmsg_len -
-                                       NLMSG_LENGTH(sizeof(*ifa)));
-        }
-        break;
-    case RTM_GETROUTE:
-        break;
-    case RTM_NEWROUTE:
-    case RTM_DELROUTE:
-        if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*rtm))) {
-            rtm = NLMSG_DATA(nlh);
-            rtm->rtm_flags = tswap32(rtm->rtm_flags);
-            target_to_host_route_rtattr(RTM_RTA(rtm), nlh->nlmsg_len -
-                                        NLMSG_LENGTH(sizeof(*rtm)));
-        }
-        break;
-    default:
-        return -TARGET_EOPNOTSUPP;
-    }
-    return 0;
-}
-
-static abi_long target_to_host_nlmsg_route(struct nlmsghdr *nlh, size_t len)
-{
-    return target_to_host_for_each_nlmsg(nlh, len, target_to_host_data_route);
-}
-#endif /* CONFIG_RTNETLINK */
-
-static abi_long host_to_target_data_audit(struct nlmsghdr *nlh)
-{
-    switch (nlh->nlmsg_type) {
-    default:
-        gemu_log("Unknown host audit message type %d\n",
-                 nlh->nlmsg_type);
-        return -TARGET_EINVAL;
-    }
-    return 0;
-}
-
-static inline abi_long host_to_target_nlmsg_audit(struct nlmsghdr *nlh,
-                                                  size_t len)
-{
-    return host_to_target_for_each_nlmsg(nlh, len, host_to_target_data_audit);
-}
-
-static abi_long target_to_host_data_audit(struct nlmsghdr *nlh)
-{
-    switch (nlh->nlmsg_type) {
-    case AUDIT_USER:
-    case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
-    case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
-        break;
-    default:
-        gemu_log("Unknown target audit message type %d\n",
-                 nlh->nlmsg_type);
-        return -TARGET_EINVAL;
-    }
-
-    return 0;
-}
-
-static abi_long target_to_host_nlmsg_audit(struct nlmsghdr *nlh, size_t len)
-{
-    return target_to_host_for_each_nlmsg(nlh, len, target_to_host_data_audit);
-}
-
 /* do_setsockopt() Must return target values and target errnos. */
 static abi_long do_setsockopt(int sockfd, int level, int optname,
                               abi_ulong optval_addr, socklen_t optlen)
@@ -3302,66 +2108,6 @@ static TargetFdTrans target_packet_trans = {
     .target_to_host_addr = packet_target_to_host_sockaddr,
 };
 
-#ifdef CONFIG_RTNETLINK
-static abi_long netlink_route_target_to_host(void *buf, size_t len)
-{
-    abi_long ret;
-
-    ret = target_to_host_nlmsg_route(buf, len);
-    if (ret < 0) {
-        return ret;
-    }
-
-    return len;
-}
-
-static abi_long netlink_route_host_to_target(void *buf, size_t len)
-{
-    abi_long ret;
-
-    ret = host_to_target_nlmsg_route(buf, len);
-    if (ret < 0) {
-        return ret;
-    }
-
-    return len;
-}
-
-static TargetFdTrans target_netlink_route_trans = {
-    .target_to_host_data = netlink_route_target_to_host,
-    .host_to_target_data = netlink_route_host_to_target,
-};
-#endif /* CONFIG_RTNETLINK */
-
-static abi_long netlink_audit_target_to_host(void *buf, size_t len)
-{
-    abi_long ret;
-
-    ret = target_to_host_nlmsg_audit(buf, len);
-    if (ret < 0) {
-        return ret;
-    }
-
-    return len;
-}
-
-static abi_long netlink_audit_host_to_target(void *buf, size_t len)
-{
-    abi_long ret;
-
-    ret = host_to_target_nlmsg_audit(buf, len);
-    if (ret < 0) {
-        return ret;
-    }
-
-    return len;
-}
-
-static TargetFdTrans target_netlink_audit_trans = {
-    .target_to_host_data = netlink_audit_target_to_host,
-    .host_to_target_data = netlink_audit_host_to_target,
-};
-
 /* do_socket() Must return target values and target errnos. */
 static abi_long do_socket(int domain, int type, int protocol)
 {
@@ -3373,14 +2119,8 @@ static abi_long do_socket(int domain, int type, int protocol)
         return ret;
     }
 
-    if (domain == PF_NETLINK && !(
-#ifdef CONFIG_RTNETLINK
-         protocol == NETLINK_ROUTE ||
-#endif
-         protocol == NETLINK_KOBJECT_UEVENT ||
-         protocol == NETLINK_AUDIT)) {
-        return -EPFNOSUPPORT;
-    }
+    if (domain == PF_NETLINK)
+        return -TARGET_EAFNOSUPPORT;
 
     if (domain == AF_PACKET ||
         (domain == AF_INET && type == SOCK_PACKET)) {
@@ -3395,22 +2135,6 @@ static abi_long do_socket(int domain, int type, int protocol)
              * if socket type is SOCK_PACKET, bind by name
              */
             fd_trans_register(ret, &target_packet_trans);
-        } else if (domain == PF_NETLINK) {
-            switch (protocol) {
-#ifdef CONFIG_RTNETLINK
-            case NETLINK_ROUTE:
-                fd_trans_register(ret, &target_netlink_route_trans);
-                break;
-#endif
-            case NETLINK_KOBJECT_UEVENT:
-                /* nothing to do: messages are strings */
-                break;
-            case NETLINK_AUDIT:
-                fd_trans_register(ret, &target_netlink_audit_trans);
-                break;
-            default:
-                g_assert_not_reached();
-            }
         }
     }
     return ret;
@@ -3453,7 +2177,7 @@ static abi_long do_connect(int sockfd, abi_ulong target_addr,
     if (ret)
         return ret;
 
-    return get_errno(safe_connect(sockfd, addr, addrlen));
+    return get_errno(connect(sockfd, addr, addrlen));
 }
 
 /* do_sendrecvmsg_locked() Must return target values and target errnos. */
@@ -3495,34 +2219,14 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
     msg.msg_iov = vec;
 
     if (send) {
-        if (fd_trans_target_to_host_data(fd)) {
-            void *host_msg;
-
-            host_msg = g_malloc(msg.msg_iov->iov_len);
-            memcpy(host_msg, msg.msg_iov->iov_base, msg.msg_iov->iov_len);
-            ret = fd_trans_target_to_host_data(fd)(host_msg,
-                                                   msg.msg_iov->iov_len);
-            if (ret >= 0) {
-                msg.msg_iov->iov_base = host_msg;
-                ret = get_errno(safe_sendmsg(fd, &msg, flags));
-            }
-            g_free(host_msg);
-        } else {
-            ret = target_to_host_cmsg(&msg, msgp);
-            if (ret == 0) {
-                ret = get_errno(safe_sendmsg(fd, &msg, flags));
-            }
-        }
+        ret = target_to_host_cmsg(&msg, msgp);
+        if (ret == 0)
+            ret = get_errno(sendmsg(fd, &msg, flags));
     } else {
-        ret = get_errno(safe_recvmsg(fd, &msg, flags));
+        ret = get_errno(recvmsg(fd, &msg, flags));
         if (!is_error(ret)) {
             len = ret;
-            if (fd_trans_host_to_target_data(fd)) {
-                ret = fd_trans_host_to_target_data(fd)(msg.msg_iov->iov_base,
-                                                       len);
-            } else {
-                ret = host_to_target_cmsg(msgp, &msg);
-            }
+            ret = host_to_target_cmsg(msgp, &msg);
             if (!is_error(ret)) {
                 msgp->msg_namelen = tswap32(msg.msg_namelen);
                 if (msg.msg_name != NULL) {
@@ -3608,6 +2312,19 @@ static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec,
     return ret;
 }
 
+/* If we don't have a system accept4() then just call accept.
+ * The callsites to do_accept4() will ensure that they don't
+ * pass a non-zero flags argument in this config.
+ */
+#ifndef CONFIG_ACCEPT4
+static inline int accept4(int sockfd, struct sockaddr *addr,
+                          socklen_t *addrlen, int flags)
+{
+    assert(flags == 0);
+    return accept(sockfd, addr, addrlen);
+}
+#endif
+
 /* do_accept4() Must return target values and target errnos. */
 static abi_long do_accept4(int fd, abi_ulong target_addr,
                            abi_ulong target_addrlen_addr, int flags)
@@ -3620,7 +2337,7 @@ static abi_long do_accept4(int fd, abi_ulong target_addr,
     host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
 
     if (target_addr == 0) {
-        return get_errno(safe_accept4(fd, NULL, NULL, host_flags));
+        return get_errno(accept4(fd, NULL, NULL, host_flags));
     }
 
     /* linux returns EINVAL if addrlen pointer is invalid */
@@ -3636,7 +2353,7 @@ static abi_long do_accept4(int fd, abi_ulong target_addr,
 
     addr = alloca(addrlen);
 
-    ret = get_errno(safe_accept4(fd, addr, &addrlen, host_flags));
+    ret = get_errno(accept4(fd, addr, &addrlen, host_flags));
     if (!is_error(ret)) {
         host_to_target_sockaddr(target_addr, addr, addrlen);
         if (put_user_u32(addrlen, target_addrlen_addr))
@@ -3727,7 +2444,6 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
 {
     void *addr;
     void *host_msg;
-    void *copy_msg = NULL;
     abi_long ret;
 
     if ((int)addrlen < 0) {
@@ -3736,30 +2452,17 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
 
     host_msg = lock_user(VERIFY_READ, msg, len, 1);
     if (!host_msg)
-        return -TARGET_EFAULT;
-    if (fd_trans_target_to_host_data(fd)) {
-        copy_msg = host_msg;
-        host_msg = g_malloc(len);
-        memcpy(host_msg, copy_msg, len);
-        ret = fd_trans_target_to_host_data(fd)(host_msg, len);
-        if (ret < 0) {
-            goto fail;
-        }
-    }
+        return -TARGET_EFAULT;
     if (target_addr) {
         addr = alloca(addrlen+1);
         ret = target_to_host_sockaddr(fd, addr, target_addr, addrlen);
         if (ret) {
-            goto fail;
+            unlock_user(host_msg, msg, 0);
+            return ret;
         }
-        ret = get_errno(safe_sendto(fd, host_msg, len, flags, addr, addrlen));
+        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
     } else {
-        ret = get_errno(safe_sendto(fd, host_msg, len, flags, NULL, 0));
-    }
-fail:
-    if (copy_msg) {
-        g_free(host_msg);
-        host_msg = copy_msg;
+        ret = get_errno(send(fd, host_msg, len, flags));
     }
     unlock_user(host_msg, msg, 0);
     return ret;
@@ -3788,16 +2491,12 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
             goto fail;
         }
         addr = alloca(addrlen);
-        ret = get_errno(safe_recvfrom(fd, host_msg, len, flags,
-                                      addr, &addrlen));
+        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
     } else {
         addr = NULL; /* To keep compiler quiet.  */
-        ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, NULL, 0));
+        ret = get_errno(qemu_recv(fd, host_msg, len, flags));
     }
     if (!is_error(ret)) {
-        if (fd_trans_host_to_target_data(fd)) {
-            ret = fd_trans_host_to_target_data(fd)(host_msg, ret);
-        }
         if (target_addr) {
             host_to_target_sockaddr(target_addr, addr, addrlen);
             if (put_user_u32(addrlen, target_addrlen)) {
@@ -3909,30 +2608,27 @@ static struct shm_region {
     bool in_use;
 } shm_regions[N_SHM_REGIONS];
 
-#ifndef TARGET_SEMID64_DS
-/* asm-generic version of this struct */
-struct target_semid64_ds
+struct target_semid_ds
 {
   struct target_ipc_perm sem_perm;
   abi_ulong sem_otime;
-#if TARGET_ABI_BITS == 32
+#if !defined(TARGET_PPC64)
   abi_ulong __unused1;
 #endif
   abi_ulong sem_ctime;
-#if TARGET_ABI_BITS == 32
+#if !defined(TARGET_PPC64)
   abi_ulong __unused2;
 #endif
   abi_ulong sem_nsems;
   abi_ulong __unused3;
   abi_ulong __unused4;
 };
-#endif
 
 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
                                                abi_ulong target_addr)
 {
     struct target_ipc_perm *target_ip;
-    struct target_semid64_ds *target_sd;
+    struct target_semid_ds *target_sd;
 
     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
         return -TARGET_EFAULT;
@@ -3960,7 +2656,7 @@ static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
                                                struct ipc_perm *host_ip)
 {
     struct target_ipc_perm *target_ip;
-    struct target_semid64_ds *target_sd;
+    struct target_semid_ds *target_sd;
 
     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
         return -TARGET_EFAULT;
@@ -3987,7 +2683,7 @@ static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
                                                abi_ulong target_addr)
 {
-    struct target_semid64_ds *target_sd;
+    struct target_semid_ds *target_sd;
 
     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
         return -TARGET_EFAULT;
@@ -4003,7 +2699,7 @@ static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
                                                struct semid_ds *host_sd)
 {
-    struct target_semid64_ds *target_sd;
+    struct target_semid_ds *target_sd;
 
     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
         return -TARGET_EFAULT;
@@ -4236,7 +2932,7 @@ static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
     if (target_to_host_sembuf(sops, ptr, nsops))
         return -TARGET_EFAULT;
 
-    return get_errno(safe_semtimedop(semid, sops, nsops, NULL));
+    return get_errno(semop(semid, sops, nsops));
 }
 
 struct target_msqid_ds
@@ -4391,7 +3087,7 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp,
     }
     host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
     memcpy(host_mb->mtext, target_mb->mtext, msgsz);
-    ret = get_errno(safe_msgsnd(msqid, host_mb, msgsz, msgflg));
+    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
     g_free(host_mb);
     unlock_user_struct(target_mb, msgp, 0);
 
@@ -4399,7 +3095,7 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp,
 }
 
 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
-                                 ssize_t msgsz, abi_long msgtyp,
+                                 unsigned int msgsz, abi_long msgtyp,
                                  int msgflg)
 {
     struct target_msgbuf *target_mb;
@@ -4407,19 +3103,11 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp,
     struct msgbuf *host_mb;
     abi_long ret = 0;
 
-    if (msgsz < 0) {
-        return -TARGET_EINVAL;
-    }
-
     if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
         return -TARGET_EFAULT;
 
-    host_mb = g_try_malloc(msgsz + sizeof(long));
-    if (!host_mb) {
-        ret = -TARGET_ENOMEM;
-        goto end;
-    }
-    ret = get_errno(safe_msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
+    host_mb = g_malloc(msgsz+sizeof(long));
+    ret = get_errno(msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
 
     if (ret > 0) {
         abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
@@ -4835,7 +3523,7 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
         memcpy(fm, buf_temp, sizeof(struct fiemap));
         free_fm = 1;
     }
-    ret = get_errno(safe_ioctl(fd, ie->host_cmd, fm));
+    ret = get_errno(ioctl(fd, ie->host_cmd, fm));
     if (!is_error(ret)) {
         target_size_out = target_size_in;
         /* An extent_count of 0 means we were only counting the extents
@@ -4925,7 +3613,7 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
     host_ifconf->ifc_len = host_ifc_len;
     host_ifconf->ifc_buf = host_ifc_buf;
 
-    ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_ifconf));
+    ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
     if (!is_error(ret)) {
        /* convert host ifc_len to target ifc_len */
 
@@ -5054,7 +3742,7 @@ static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
     }
     unlock_user(argptr, guest_data, 0);
 
-    ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
+    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
     if (!is_error(ret)) {
         guest_data = arg + host_dm->data_start;
         guest_data_size = host_dm->data_size - host_dm->data_start;
@@ -5235,7 +3923,7 @@ static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
 
     /* Swizzle the data pointer to our local copy and call! */
     host_blkpg->data = &host_part;
-    ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_blkpg));
+    ret = get_errno(ioctl(fd, ie->host_cmd, host_blkpg));
 
 out:
     return ret;
@@ -5296,7 +3984,7 @@ static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
     }
     unlock_user(argptr, arg, 0);
 
-    ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
+    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
     if (*host_rt_dev_ptr != 0) {
         unlock_user((void *)*host_rt_dev_ptr,
                     *target_rt_dev_ptr, 0);
@@ -5308,7 +3996,7 @@ static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp,
                                      int fd, int cmd, abi_long arg)
 {
     int sig = target_to_host_signal(arg);
-    return get_errno(safe_ioctl(fd, ie->host_cmd, sig));
+    return get_errno(ioctl(fd, ie->host_cmd, sig));
 }
 
 static IOCTLEntry ioctl_entries[] = {
@@ -5352,18 +4040,18 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
     switch(arg_type[0]) {
     case TYPE_NULL:
         /* no argument */
-        ret = get_errno(safe_ioctl(fd, ie->host_cmd));
+        ret = get_errno(ioctl(fd, ie->host_cmd));
         break;
     case TYPE_PTRVOID:
     case TYPE_INT:
-        ret = get_errno(safe_ioctl(fd, ie->host_cmd, arg));
+        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
         break;
     case TYPE_PTR:
         arg_type++;
         target_size = thunk_type_size(arg_type, 0);
         switch(ie->access) {
         case IOC_R:
-            ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
+            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
             if (!is_error(ret)) {
                 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
                 if (!argptr)
@@ -5378,7 +4066,7 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
                 return -TARGET_EFAULT;
             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
             unlock_user(argptr, arg, 0);
-            ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
+            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
             break;
         default:
         case IOC_RW:
@@ -5387,7 +4075,7 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
                 return -TARGET_EFAULT;
             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
             unlock_user(argptr, arg, 0);
-            ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
+            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
             if (!is_error(ret)) {
                 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
                 if (!argptr)
@@ -5988,7 +4676,6 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
         new_cpu->opaque = ts;
         ts->bprm = parent_ts->bprm;
         ts->info = parent_ts->info;
-        ts->signal_mask = parent_ts->signal_mask;
         nptl_flags = flags;
         flags &= ~CLONE_NPTL_FLAGS2;
 
@@ -6043,11 +4730,6 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
         if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) {
             return -TARGET_EINVAL;
         }
-
-        if (block_signals()) {
-            return -TARGET_ERESTARTSYS;
-        }
-
         fork_start();
         ret = fork();
         if (ret == 0) {
@@ -6088,11 +4770,11 @@ static int target_to_host_fcntl_cmd(int cmd)
        case TARGET_F_SETFL:
             return cmd;
         case TARGET_F_GETLK:
-            return F_GETLK64;
-        case TARGET_F_SETLK:
-            return F_SETLK64;
-        case TARGET_F_SETLKW:
-            return F_SETLKW64;
+           return F_GETLK;
+       case TARGET_F_SETLK:
+           return F_SETLK;
+       case TARGET_F_SETLKW:
+           return F_SETLKW;
        case TARGET_F_GETOWN:
            return F_GETOWN;
        case TARGET_F_SETOWN:
@@ -6127,12 +4809,6 @@ static int target_to_host_fcntl_cmd(int cmd)
        case TARGET_F_SETOWN_EX:
            return F_SETOWN_EX;
 #endif
-#ifdef F_SETPIPE_SZ
-        case TARGET_F_SETPIPE_SZ:
-            return F_SETPIPE_SZ;
-        case TARGET_F_GETPIPE_SZ:
-            return F_GETPIPE_SZ;
-#endif
        default:
             return -TARGET_EINVAL;
     }
@@ -6149,134 +4825,12 @@ static const bitmask_transtbl flock_tbl[] = {
     { 0, 0, 0, 0 }
 };
 
-static inline abi_long copy_from_user_flock(struct flock64 *fl,
-                                            abi_ulong target_flock_addr)
-{
-    struct target_flock *target_fl;
-    short l_type;
-
-    if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
-        return -TARGET_EFAULT;
-    }
-
-    __get_user(l_type, &target_fl->l_type);
-    fl->l_type = target_to_host_bitmask(l_type, flock_tbl);
-    __get_user(fl->l_whence, &target_fl->l_whence);
-    __get_user(fl->l_start, &target_fl->l_start);
-    __get_user(fl->l_len, &target_fl->l_len);
-    __get_user(fl->l_pid, &target_fl->l_pid);
-    unlock_user_struct(target_fl, target_flock_addr, 0);
-    return 0;
-}
-
-static inline abi_long copy_to_user_flock(abi_ulong target_flock_addr,
-                                          const struct flock64 *fl)
-{
-    struct target_flock *target_fl;
-    short l_type;
-
-    if (!lock_user_struct(VERIFY_WRITE, target_fl, target_flock_addr, 0)) {
-        return -TARGET_EFAULT;
-    }
-
-    l_type = host_to_target_bitmask(fl->l_type, flock_tbl);
-    __put_user(l_type, &target_fl->l_type);
-    __put_user(fl->l_whence, &target_fl->l_whence);
-    __put_user(fl->l_start, &target_fl->l_start);
-    __put_user(fl->l_len, &target_fl->l_len);
-    __put_user(fl->l_pid, &target_fl->l_pid);
-    unlock_user_struct(target_fl, target_flock_addr, 1);
-    return 0;
-}
-
-typedef abi_long from_flock64_fn(struct flock64 *fl, abi_ulong target_addr);
-typedef abi_long to_flock64_fn(abi_ulong target_addr, const struct flock64 *fl);
-
-#if defined(TARGET_ARM) && TARGET_ABI_BITS == 32
-static inline abi_long copy_from_user_eabi_flock64(struct flock64 *fl,
-                                                   abi_ulong target_flock_addr)
-{
-    struct target_eabi_flock64 *target_fl;
-    short l_type;
-
-    if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
-        return -TARGET_EFAULT;
-    }
-
-    __get_user(l_type, &target_fl->l_type);
-    fl->l_type = target_to_host_bitmask(l_type, flock_tbl);
-    __get_user(fl->l_whence, &target_fl->l_whence);
-    __get_user(fl->l_start, &target_fl->l_start);
-    __get_user(fl->l_len, &target_fl->l_len);
-    __get_user(fl->l_pid, &target_fl->l_pid);
-    unlock_user_struct(target_fl, target_flock_addr, 0);
-    return 0;
-}
-
-static inline abi_long copy_to_user_eabi_flock64(abi_ulong target_flock_addr,
-                                                 const struct flock64 *fl)
-{
-    struct target_eabi_flock64 *target_fl;
-    short l_type;
-
-    if (!lock_user_struct(VERIFY_WRITE, target_fl, target_flock_addr, 0)) {
-        return -TARGET_EFAULT;
-    }
-
-    l_type = host_to_target_bitmask(fl->l_type, flock_tbl);
-    __put_user(l_type, &target_fl->l_type);
-    __put_user(fl->l_whence, &target_fl->l_whence);
-    __put_user(fl->l_start, &target_fl->l_start);
-    __put_user(fl->l_len, &target_fl->l_len);
-    __put_user(fl->l_pid, &target_fl->l_pid);
-    unlock_user_struct(target_fl, target_flock_addr, 1);
-    return 0;
-}
-#endif
-
-static inline abi_long copy_from_user_flock64(struct flock64 *fl,
-                                              abi_ulong target_flock_addr)
-{
-    struct target_flock64 *target_fl;
-    short l_type;
-
-    if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
-        return -TARGET_EFAULT;
-    }
-
-    __get_user(l_type, &target_fl->l_type);
-    fl->l_type = target_to_host_bitmask(l_type, flock_tbl);
-    __get_user(fl->l_whence, &target_fl->l_whence);
-    __get_user(fl->l_start, &target_fl->l_start);
-    __get_user(fl->l_len, &target_fl->l_len);
-    __get_user(fl->l_pid, &target_fl->l_pid);
-    unlock_user_struct(target_fl, target_flock_addr, 0);
-    return 0;
-}
-
-static inline abi_long copy_to_user_flock64(abi_ulong target_flock_addr,
-                                            const struct flock64 *fl)
-{
-    struct target_flock64 *target_fl;
-    short l_type;
-
-    if (!lock_user_struct(VERIFY_WRITE, target_fl, target_flock_addr, 0)) {
-        return -TARGET_EFAULT;
-    }
-
-    l_type = host_to_target_bitmask(fl->l_type, flock_tbl);
-    __put_user(l_type, &target_fl->l_type);
-    __put_user(fl->l_whence, &target_fl->l_whence);
-    __put_user(fl->l_start, &target_fl->l_start);
-    __put_user(fl->l_len, &target_fl->l_len);
-    __put_user(fl->l_pid, &target_fl->l_pid);
-    unlock_user_struct(target_fl, target_flock_addr, 1);
-    return 0;
-}
-
 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
 {
+    struct flock fl;
+    struct target_flock *target_fl;
     struct flock64 fl64;
+    struct target_flock64 *target_fl64;
 #ifdef F_GETOWN_EX
     struct f_owner_ex fox;
     struct target_f_owner_ex *target_fox;
@@ -6289,60 +4843,94 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
 
     switch(cmd) {
     case TARGET_F_GETLK:
-        ret = copy_from_user_flock(&fl64, arg);
-        if (ret) {
-            return ret;
-        }
-        ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
+        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
+            return -TARGET_EFAULT;
+        fl.l_type =
+                  target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
+        fl.l_whence = tswap16(target_fl->l_whence);
+        fl.l_start = tswapal(target_fl->l_start);
+        fl.l_len = tswapal(target_fl->l_len);
+        fl.l_pid = tswap32(target_fl->l_pid);
+        unlock_user_struct(target_fl, arg, 0);
+        ret = get_errno(fcntl(fd, host_cmd, &fl));
         if (ret == 0) {
-            ret = copy_to_user_flock(arg, &fl64);
+            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
+                return -TARGET_EFAULT;
+            target_fl->l_type =
+                          host_to_target_bitmask(tswap16(fl.l_type), flock_tbl);
+            target_fl->l_whence = tswap16(fl.l_whence);
+            target_fl->l_start = tswapal(fl.l_start);
+            target_fl->l_len = tswapal(fl.l_len);
+            target_fl->l_pid = tswap32(fl.l_pid);
+            unlock_user_struct(target_fl, arg, 1);
         }
         break;
 
     case TARGET_F_SETLK:
     case TARGET_F_SETLKW:
-        ret = copy_from_user_flock(&fl64, arg);
-        if (ret) {
-            return ret;
-        }
-        ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
+        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
+            return -TARGET_EFAULT;
+        fl.l_type =
+                  target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
+        fl.l_whence = tswap16(target_fl->l_whence);
+        fl.l_start = tswapal(target_fl->l_start);
+        fl.l_len = tswapal(target_fl->l_len);
+        fl.l_pid = tswap32(target_fl->l_pid);
+        unlock_user_struct(target_fl, arg, 0);
+        ret = get_errno(fcntl(fd, host_cmd, &fl));
         break;
 
     case TARGET_F_GETLK64:
-        ret = copy_from_user_flock64(&fl64, arg);
-        if (ret) {
-            return ret;
-        }
-        ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
+        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
+            return -TARGET_EFAULT;
+        fl64.l_type =
+           target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
+        fl64.l_whence = tswap16(target_fl64->l_whence);
+        fl64.l_start = tswap64(target_fl64->l_start);
+        fl64.l_len = tswap64(target_fl64->l_len);
+        fl64.l_pid = tswap32(target_fl64->l_pid);
+        unlock_user_struct(target_fl64, arg, 0);
+        ret = get_errno(fcntl(fd, host_cmd, &fl64));
         if (ret == 0) {
-            ret = copy_to_user_flock64(arg, &fl64);
+            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
+                return -TARGET_EFAULT;
+            target_fl64->l_type =
+                   host_to_target_bitmask(tswap16(fl64.l_type), flock_tbl) >> 1;
+            target_fl64->l_whence = tswap16(fl64.l_whence);
+            target_fl64->l_start = tswap64(fl64.l_start);
+            target_fl64->l_len = tswap64(fl64.l_len);
+            target_fl64->l_pid = tswap32(fl64.l_pid);
+            unlock_user_struct(target_fl64, arg, 1);
         }
         break;
     case TARGET_F_SETLK64:
     case TARGET_F_SETLKW64:
-        ret = copy_from_user_flock64(&fl64, arg);
-        if (ret) {
-            return ret;
-        }
-        ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
+        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
+            return -TARGET_EFAULT;
+        fl64.l_type =
+           target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
+        fl64.l_whence = tswap16(target_fl64->l_whence);
+        fl64.l_start = tswap64(target_fl64->l_start);
+        fl64.l_len = tswap64(target_fl64->l_len);
+        fl64.l_pid = tswap32(target_fl64->l_pid);
+        unlock_user_struct(target_fl64, arg, 0);
+        ret = get_errno(fcntl(fd, host_cmd, &fl64));
         break;
 
     case TARGET_F_GETFL:
-        ret = get_errno(safe_fcntl(fd, host_cmd, arg));
+        ret = get_errno(fcntl(fd, host_cmd, arg));
         if (ret >= 0) {
             ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
         }
         break;
 
     case TARGET_F_SETFL:
-        ret = get_errno(safe_fcntl(fd, host_cmd,
-                                   target_to_host_bitmask(arg,
-                                                          fcntl_flags_tbl)));
+        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
         break;
 
 #ifdef F_GETOWN_EX
     case TARGET_F_GETOWN_EX:
-        ret = get_errno(safe_fcntl(fd, host_cmd, &fox));
+        ret = get_errno(fcntl(fd, host_cmd, &fox));
         if (ret >= 0) {
             if (!lock_user_struct(VERIFY_WRITE, target_fox, arg, 0))
                 return -TARGET_EFAULT;
@@ -6360,7 +4948,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
         fox.type = tswap32(target_fox->type);
         fox.pid = tswap32(target_fox->pid);
         unlock_user_struct(target_fox, arg, 0);
-        ret = get_errno(safe_fcntl(fd, host_cmd, &fox));
+        ret = get_errno(fcntl(fd, host_cmd, &fox));
         break;
 #endif
 
@@ -6370,13 +4958,11 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
     case TARGET_F_GETSIG:
     case TARGET_F_SETLEASE:
     case TARGET_F_GETLEASE:
-    case TARGET_F_SETPIPE_SZ:
-    case TARGET_F_GETPIPE_SZ:
-        ret = get_errno(safe_fcntl(fd, host_cmd, arg));
+        ret = get_errno(fcntl(fd, host_cmd, arg));
         break;
 
     default:
-        ret = get_errno(safe_fcntl(fd, cmd, arg));
+        ret = get_errno(fcntl(fd, cmd, arg));
         break;
     }
     return ret;
@@ -6448,40 +5034,6 @@ static inline int tswapid(int id)
 
 #endif /* USE_UID16 */
 
-/* We must do direct syscalls for setting UID/GID, because we want to
- * implement the Linux system call semantics of "change only for this thread",
- * not the libc/POSIX semantics of "change for all threads in process".
- * (See http://ewontfix.com/17/ for more details.)
- * We use the 32-bit version of the syscalls if present; if it is not
- * then either the host architecture supports 32-bit UIDs natively with
- * the standard syscall, or the 16-bit UID is the best we can do.
- */
-#ifdef __NR_setuid32
-#define __NR_sys_setuid __NR_setuid32
-#else
-#define __NR_sys_setuid __NR_setuid
-#endif
-#ifdef __NR_setgid32
-#define __NR_sys_setgid __NR_setgid32
-#else
-#define __NR_sys_setgid __NR_setgid
-#endif
-#ifdef __NR_setresuid32
-#define __NR_sys_setresuid __NR_setresuid32
-#else
-#define __NR_sys_setresuid __NR_setresuid
-#endif
-#ifdef __NR_setresgid32
-#define __NR_sys_setresgid __NR_setresgid32
-#else
-#define __NR_sys_setresgid __NR_setresgid
-#endif
-
-_syscall1(int, sys_setuid, uid_t, uid)
-_syscall1(int, sys_setgid, gid_t, gid)
-_syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
-_syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
-
 void syscall_init(void)
 {
     IOCTLEntry *ie;
@@ -6585,8 +5137,8 @@ static inline abi_long target_to_host_timespec(struct timespec *host_ts,
 
     if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
         return -TARGET_EFAULT;
-    __get_user(host_ts->tv_sec, &target_ts->tv_sec);
-    __get_user(host_ts->tv_nsec, &target_ts->tv_nsec);
+    host_ts->tv_sec = tswapal(target_ts->tv_sec);
+    host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
     unlock_user_struct(target_ts, target_addr, 0);
     return 0;
 }
@@ -6598,8 +5150,8 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr,
 
     if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
         return -TARGET_EFAULT;
-    __put_user(host_ts->tv_sec, &target_ts->tv_sec);
-    __put_user(host_ts->tv_nsec, &target_ts->tv_nsec);
+    target_ts->tv_sec = tswapal(host_ts->tv_sec);
+    target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
     unlock_user_struct(target_ts, target_addr, 1);
     return 0;
 }
@@ -6774,12 +5326,12 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
         } else {
             pts = NULL;
         }
-        return get_errno(safe_futex(g2h(uaddr), op, tswap32(val),
+        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
                          pts, NULL, val3));
     case FUTEX_WAKE:
-        return get_errno(safe_futex(g2h(uaddr), op, val, NULL, NULL, 0));
+        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
     case FUTEX_FD:
-        return get_errno(safe_futex(g2h(uaddr), op, val, NULL, NULL, 0));
+        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
     case FUTEX_REQUEUE:
     case FUTEX_CMP_REQUEUE:
     case FUTEX_WAKE_OP:
@@ -6789,11 +5341,11 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
            to satisfy the compiler.  We do not need to tswap TIMEOUT
            since it's not compared to guest memory.  */
         pts = (struct timespec *)(uintptr_t) timeout;
-        return get_errno(safe_futex(g2h(uaddr), op, val, pts,
-                                    g2h(uaddr2),
-                                    (base_op == FUTEX_CMP_REQUEUE
-                                     ? tswap32(val3)
-                                     : val3)));
+        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
+                                   g2h(uaddr2),
+                                   (base_op == FUTEX_CMP_REQUEUE
+                                    ? tswap32(val3)
+                                    : val3)));
     default:
         return -TARGET_ENOSYS;
     }
@@ -7003,9 +5555,7 @@ static int open_self_cmdline(void *cpu_env, int fd)
 
         nb_read = read(fd_orig, buf, sizeof(buf));
         if (nb_read < 0) {
-            int e = errno;
             fd_orig = close(fd_orig);
-            errno = e;
             return -1;
         } else if (nb_read == 0) {
             break;
@@ -7014,7 +5564,7 @@ static int open_self_cmdline(void *cpu_env, int fd)
         if (!word_skipped) {
             /* Skip the first string, which is the path to qemu-*-static
                instead of the actual command. */
-            cp_buf = memchr(buf, 0, nb_read);
+            cp_buf = memchr(buf, 0, sizeof(buf));
             if (cp_buf) {
                 /* Null byte found, skip one string */
                 cp_buf++;
@@ -7025,9 +5575,7 @@ static int open_self_cmdline(void *cpu_env, int fd)
 
         if (word_skipped) {
             if (write(fd, cp_buf, nb_read) != nb_read) {
-                int e = errno;
                 close(fd_orig);
-                errno = e;
                 return -1;
             }
         }
@@ -7047,7 +5595,7 @@ static int open_self_maps(void *cpu_env, int fd)
 
     fp = fopen("/proc/self/maps", "r");
     if (fp == NULL) {
-        return -1;
+        return -EACCES;
     }
 
     while ((read = getline(&line, &len, fp)) != -1) {
@@ -7191,7 +5739,7 @@ static int open_net_route(void *cpu_env, int fd)
 
     fp = fopen("/proc/net/route", "r");
     if (fp == NULL) {
-        return -1;
+        return -EACCES;
     }
 
     /* read header */
@@ -7241,7 +5789,7 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
 
     if (is_proc_myself(pathname, "exe")) {
         int execfd = qemu_getauxval(AT_EXECFD);
-        return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode);
+        return execfd ? execfd : get_errno(sys_openat(dirfd, exec_path, flags, mode));
     }
 
     for (fake_open = fakes; fake_open->filename; fake_open++) {
@@ -7267,9 +5815,7 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
         unlink(filename);
 
         if ((r = fake_open->fill(cpu_env, fd))) {
-            int e = errno;
             close(fd);
-            errno = e;
             return r;
         }
         lseek(fd, 0, SEEK_SET);
@@ -7277,7 +5823,7 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
         return fd;
     }
 
-    return safe_openat(dirfd, path(pathname), flags, mode);
+    return get_errno(sys_openat(dirfd, path(pathname), flags, mode));
 }
 
 #define TIMER_MAGIC 0x0caf0000
@@ -7315,25 +5861,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     struct statfs stfs;
     void *p;
 
-#if defined(DEBUG_ERESTARTSYS)
-    /* Debug-only code for exercising the syscall-restart code paths
-     * in the per-architecture cpu main loops: restart every syscall
-     * the guest makes once before letting it through.
-     */
-    {
-        static int flag;
-
-        flag = !flag;
-        if (flag) {
-            return -TARGET_ERESTARTSYS;
-        }
-    }
-#endif
-
 #ifdef DEBUG
     gemu_log("syscall %d", num);
 #endif
-    trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
     if(do_strace)
         print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
 
@@ -7343,12 +5873,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
            However in threaded applictions it is used for thread termination,
            and _exit_group is used for application termination.
            Do thread termination if we have more then one thread.  */
-
-        if (block_signals()) {
-            ret = -TARGET_ERESTARTSYS;
-            break;
-        }
-
+        /* FIXME: This probably breaks if a signal arrives.  We should probably
+           be disabling signals.  */
         if (CPU_NEXT(first_cpu)) {
             TaskState *ts;
 
@@ -7381,7 +5907,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         else {
             if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
                 goto efault;
-            ret = get_errno(safe_read(arg1, p, arg3));
+            ret = get_errno(read(arg1, p, arg3));
             if (ret >= 0 &&
                 fd_trans_host_to_target_data(arg1)) {
                 ret = fd_trans_host_to_target_data(arg1)(p, ret);
@@ -7392,7 +5918,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_write:
         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
             goto efault;
-        ret = get_errno(safe_write(arg1, p, arg3));
+        ret = get_errno(write(arg1, p, arg3));
         unlock_user(p, arg2, 0);
         break;
 #ifdef TARGET_NR_open
@@ -7442,7 +5968,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_waitpid:
         {
             int status;
-            ret = get_errno(safe_wait4(arg1, &status, arg3, 0));
+            ret = get_errno(waitpid(arg1, &status, arg3));
             if (!is_error(ret) && arg2 && ret
                 && put_user_s32(host_to_target_waitstatus(status), arg2))
                 goto efault;
@@ -7454,7 +5980,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         {
             siginfo_t info;
             info.si_pid = 0;
-            ret = get_errno(safe_waitid(arg1, arg2, &info, arg4, NULL));
+            ret = get_errno(waitid(arg1, arg2, &info, arg4));
             if (!is_error(ret) && arg3 && info.si_pid != 0) {
                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
                     goto efault;
@@ -7580,17 +6106,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 
             if (!(p = lock_user_string(arg1)))
                 goto execve_efault;
-            /* Although execve() is not an interruptible syscall it is
-             * a special case where we must use the safe_syscall wrapper:
-             * if we allow a signal to happen before we make the host
-             * syscall then we will 'lose' it, because at the point of
-             * execve the process leaves QEMU's control. So we use the
-             * safe syscall wrapper to ensure that we either take the
-             * signal as a guest signal, or else it does not happen
-             * before the execve completes and makes it the other
-             * program's problem.
-             */
-            ret = get_errno(safe_execve(p, argp, envp));
+            ret = get_errno(execve(p, argp, envp));
             unlock_user(p, arg1, 0);
 
             goto execve_end;
@@ -7766,10 +6282,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_pause /* not on alpha */
     case TARGET_NR_pause:
-        if (!block_signals()) {
-            sigsuspend(&((TaskState *)cpu->opaque)->signal_mask);
-        }
-        ret = -TARGET_EINTR;
+        ret = get_errno(pause());
         break;
 #endif
 #ifdef TARGET_NR_utime
@@ -7872,7 +6385,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = 0;
         break;
     case TARGET_NR_kill:
-        ret = get_errno(safe_kill(arg1, target_to_host_signal(arg2)));
+        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
         break;
 #ifdef TARGET_NR_rename
     case TARGET_NR_rename:
@@ -8143,11 +6656,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_ALPHA)
             struct target_sigaction act, oact, *pact = 0;
             struct target_rt_sigaction *rt_act;
-
-            if (arg4 != sizeof(target_sigset_t)) {
-                ret = -TARGET_EINVAL;
-                break;
-            }
+            /* ??? arg4 == sizeof(sigset_t).  */
             if (arg2) {
                 if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
                     goto efault;
@@ -8171,10 +6680,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             struct target_sigaction *act;
             struct target_sigaction *oact;
 
-            if (arg4 != sizeof(target_sigset_t)) {
-                ret = -TARGET_EINVAL;
-                break;
-            }
             if (arg2) {
                 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
                     goto efault;
@@ -8201,11 +6706,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         {
             sigset_t cur_set;
             abi_ulong target_set;
-            ret = do_sigprocmask(0, NULL, &cur_set);
-            if (!ret) {
-                host_to_target_old_sigset(&target_set, &cur_set);
-                ret = target_set;
-            }
+            do_sigprocmask(0, NULL, &cur_set);
+            host_to_target_old_sigset(&target_set, &cur_set);
+            ret = target_set;
         }
         break;
 #endif
@@ -8214,20 +6717,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         {
             sigset_t set, oset, cur_set;
             abi_ulong target_set = arg1;
-            /* We only have one word of the new mask so we must read
-             * the rest of it with do_sigprocmask() and OR in this word.
-             * We are guaranteed that a do_sigprocmask() that only queries
-             * the signal mask will not fail.
-             */
-            ret = do_sigprocmask(0, NULL, &cur_set);
-            assert(!ret);
+            do_sigprocmask(0, NULL, &cur_set);
             target_to_host_old_sigset(&set, &target_set);
             sigorset(&set, &set, &cur_set);
-            ret = do_sigprocmask(SIG_SETMASK, &set, &oset);
-            if (!ret) {
-                host_to_target_old_sigset(&target_set, &oset);
-                ret = target_set;
-            }
+            do_sigprocmask(SIG_SETMASK, &set, &oset);
+            host_to_target_old_sigset(&target_set, &oset);
+            ret = target_set;
         }
         break;
 #endif
@@ -8256,7 +6751,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             mask = arg2;
             target_to_host_old_sigset(&set, &mask);
 
-            ret = do_sigprocmask(how, &set, &oldset);
+            ret = get_errno(do_sigprocmask(how, &set, &oldset));
             if (!is_error(ret)) {
                 host_to_target_old_sigset(&mask, &oldset);
                 ret = mask;
@@ -8290,7 +6785,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 how = 0;
                 set_ptr = NULL;
             }
-            ret = do_sigprocmask(how, set_ptr, &oldset);
+            ret = get_errno(do_sigprocmask(how, set_ptr, &oldset));
             if (!is_error(ret) && arg3) {
                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
                     goto efault;
@@ -8306,11 +6801,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             int how = arg1;
             sigset_t set, oldset, *set_ptr;
 
-            if (arg4 != sizeof(target_sigset_t)) {
-                ret = -TARGET_EINVAL;
-                break;
-            }
-
             if (arg2) {
                 switch(how) {
                 case TARGET_SIG_BLOCK:
@@ -8335,7 +6825,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 how = 0;
                 set_ptr = NULL;
             }
-            ret = do_sigprocmask(how, set_ptr, &oldset);
+            ret = get_errno(do_sigprocmask(how, set_ptr, &oldset));
             if (!is_error(ret) && arg3) {
                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
                     goto efault;
@@ -8361,17 +6851,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_rt_sigpending:
         {
             sigset_t set;
-
-            /* Yes, this check is >, not != like most. We follow the kernel's
-             * logic and it does it like this because it implements
-             * NR_sigpending through the same code path, and in that case
-             * the old_sigset_t is smaller in size.
-             */
-            if (arg2 > sizeof(target_sigset_t)) {
-                ret = -TARGET_EINVAL;
-                break;
-            }
-
             ret = get_errno(sigpending(&set));
             if (!is_error(ret)) {
                 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
@@ -8384,41 +6863,28 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_sigsuspend
     case TARGET_NR_sigsuspend:
         {
-            TaskState *ts = cpu->opaque;
+            sigset_t set;
 #if defined(TARGET_ALPHA)
             abi_ulong mask = arg1;
-            target_to_host_old_sigset(&ts->sigsuspend_mask, &mask);
+            target_to_host_old_sigset(&set, &mask);
 #else
             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
                 goto efault;
-            target_to_host_old_sigset(&ts->sigsuspend_mask, p);
+            target_to_host_old_sigset(&set, p);
             unlock_user(p, arg1, 0);
 #endif
-            ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
-                                               SIGSET_T_SIZE));
-            if (ret != -TARGET_ERESTARTSYS) {
-                ts->in_sigsuspend = 1;
-            }
+            ret = get_errno(sigsuspend(&set));
         }
         break;
 #endif
     case TARGET_NR_rt_sigsuspend:
         {
-            TaskState *ts = cpu->opaque;
-
-            if (arg2 != sizeof(target_sigset_t)) {
-                ret = -TARGET_EINVAL;
-                break;
-            }
+            sigset_t set;
             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
                 goto efault;
-            target_to_host_sigset(&ts->sigsuspend_mask, p);
+            target_to_host_sigset(&set, p);
             unlock_user(p, arg1, 0);
-            ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
-                                               SIGSET_T_SIZE));
-            if (ret != -TARGET_ERESTARTSYS) {
-                ts->in_sigsuspend = 1;
-            }
+            ret = get_errno(sigsuspend(&set));
         }
         break;
     case TARGET_NR_rt_sigtimedwait:
@@ -8427,11 +6893,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             struct timespec uts, *puts;
             siginfo_t uinfo;
 
-            if (arg4 != sizeof(target_sigset_t)) {
-                ret = -TARGET_EINVAL;
-                break;
-            }
-
             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
                 goto efault;
             target_to_host_sigset(&set, p);
@@ -8442,8 +6903,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             } else {
                 puts = NULL;
             }
-            ret = get_errno(safe_rt_sigtimedwait(&set, &uinfo, puts,
-                                                 SIGSET_T_SIZE));
+            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
             if (!is_error(ret)) {
                 if (arg2) {
                     p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t),
@@ -8461,11 +6921,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_rt_sigqueueinfo:
         {
             siginfo_t uinfo;
-
-            p = lock_user(VERIFY_READ, arg3, sizeof(target_siginfo_t), 1);
-            if (!p) {
+            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
                 goto efault;
-            }
             target_to_host_siginfo(&uinfo, p);
             unlock_user(p, arg1, 0);
             ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
@@ -8473,19 +6930,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #ifdef TARGET_NR_sigreturn
     case TARGET_NR_sigreturn:
-        if (block_signals()) {
-            ret = -TARGET_ERESTARTSYS;
-        } else {
-            ret = do_sigreturn(cpu_env);
-        }
+        /* NOTE: ret is eax, so not transcoding must be done */
+        ret = do_sigreturn(cpu_env);
         break;
 #endif
     case TARGET_NR_rt_sigreturn:
-        if (block_signals()) {
-            ret = -TARGET_ERESTARTSYS;
-        } else {
-            ret = do_rt_sigreturn(cpu_env);
-        }
+        /* NOTE: ret is eax, so not transcoding must be done */
+        ret = do_rt_sigreturn(cpu_env);
         break;
     case TARGET_NR_sethostname:
         if (!(p = lock_user_string(arg1)))
@@ -8642,7 +7093,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             /* Extract the two packed args for the sigset */
             if (arg6) {
                 sig_ptr = &sig;
-                sig.size = SIGSET_T_SIZE;
+                sig.size = _NSIG / 8;
 
                 arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
                 if (!arg7) {
@@ -8673,8 +7124,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 sig_ptr = NULL;
             }
 
-            ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
-                                          ts_ptr, sig_ptr));
+            ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
+                                         ts_ptr, sig_ptr));
 
             if (!is_error(ret)) {
                 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
@@ -9015,7 +7466,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_accept4
     case TARGET_NR_accept4:
+#ifdef CONFIG_ACCEPT4
         ret = do_accept4(arg1, arg2, arg3, arg4);
+#else
+        goto unimplemented;
+#endif
         break;
 #endif
 #ifdef TARGET_NR_bind
@@ -9239,7 +7694,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 rusage_ptr = &rusage;
             else
                 rusage_ptr = NULL;
-            ret = get_errno(safe_wait4(arg1, &status, arg3, rusage_ptr));
+            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
             if (!is_error(ret)) {
                 if (status_ptr && ret) {
                     status = host_to_target_waitstatus(status);
@@ -9395,14 +7850,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 goto efault;
             ret = get_errno(sys_uname(buf));
             if (!is_error(ret)) {
-                /* Overwrite the native machine name with whatever is being
+                /* Overrite the native machine name with whatever is being
                    emulated. */
                 strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
                 /* Allow the user to override the reported release.  */
-                if (qemu_uname_release && *qemu_uname_release) {
-                    g_strlcpy(buf->release, qemu_uname_release,
-                              sizeof(buf->release));
-                }
+                if (qemu_uname_release && *qemu_uname_release)
+                  strcpy (buf->release, qemu_uname_release);
             }
             unlock_user_struct(buf, arg1, 1);
         }
@@ -9458,7 +7911,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         {
             int64_t res;
 #if !defined(__NR_llseek)
-            res = lseek(arg1, ((uint64_t)arg2 << 32) | (abi_ulong)arg3, arg5);
+            res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
             if (res == -1) {
                 ret = get_errno(res);
             } else {
@@ -9648,6 +8101,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         {
             struct target_pollfd *target_pfd;
             unsigned int nfds = arg2;
+            int timeout = arg3;
             struct pollfd *pfd;
             unsigned int i;
 
@@ -9667,10 +8121,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 }
             }
 
-            switch (num) {
 # ifdef TARGET_NR_ppoll
-            case TARGET_NR_ppoll:
-            {
+            if (num == TARGET_NR_ppoll) {
                 struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
                 target_sigset_t *target_set;
                 sigset_t _set, *set = &_set;
@@ -9685,12 +8137,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 }
 
                 if (arg4) {
-                    if (arg5 != sizeof(target_sigset_t)) {
-                        unlock_user(target_pfd, arg1, 0);
-                        ret = -TARGET_EINVAL;
-                        break;
-                    }
-
                     target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
                     if (!target_set) {
                         unlock_user(target_pfd, arg1, 0);
@@ -9701,8 +8147,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     set = NULL;
                 }
 
-                ret = get_errno(safe_ppoll(pfd, nfds, timeout_ts,
-                                           set, SIGSET_T_SIZE));
+                ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
 
                 if (!is_error(ret) && arg3) {
                     host_to_target_timespec(arg3, timeout_ts);
@@ -9710,30 +8155,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 if (arg4) {
                     unlock_user(target_set, arg4, 0);
                 }
-                break;
-            }
-# endif
-# ifdef TARGET_NR_poll
-            case TARGET_NR_poll:
-            {
-                struct timespec ts, *pts;
-
-                if (arg3 >= 0) {
-                    /* Convert ms to secs, ns */
-                    ts.tv_sec = arg3 / 1000;
-                    ts.tv_nsec = (arg3 % 1000) * 1000000LL;
-                    pts = &ts;
-                } else {
-                    /* -ve poll() timeout means "infinite" */
-                    pts = NULL;
-                }
-                ret = get_errno(safe_ppoll(pfd, nfds, pts, NULL, 0));
-                break;
-            }
+            } else
 # endif
-            default:
-                g_assert_not_reached();
-            }
+                ret = get_errno(poll(pfd, nfds, timeout));
 
             if (!is_error(ret)) {
                 for(i = 0; i < nfds; i++) {
@@ -9747,13 +8171,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_flock:
         /* NOTE: the flock constant seems to be the same for every
            Linux platform */
-        ret = get_errno(safe_flock(arg1, arg2));
+        ret = get_errno(flock(arg1, arg2));
         break;
     case TARGET_NR_readv:
         {
             struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
             if (vec != NULL) {
-                ret = get_errno(safe_readv(arg1, vec, arg3));
+                ret = get_errno(readv(arg1, vec, arg3));
                 unlock_iovec(vec, arg2, arg3, 1);
             } else {
                 ret = -host_to_target_errno(errno);
@@ -9764,7 +8188,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         {
             struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
             if (vec != NULL) {
-                ret = get_errno(safe_writev(arg1, vec, arg3));
+                ret = get_errno(writev(arg1, vec, arg3));
                 unlock_iovec(vec, arg2, arg3, 0);
             } else {
                 ret = -host_to_target_errno(errno);
@@ -9923,7 +8347,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         {
             struct timespec req, rem;
             target_to_host_timespec(&req, arg1);
-            ret = get_errno(safe_nanosleep(&req, &rem));
+            ret = get_errno(nanosleep(&req, &rem));
             if (is_error(ret) && arg2) {
                 host_to_target_timespec(arg2, &rem);
             }
@@ -10316,9 +8740,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_setresuid
     case TARGET_NR_setresuid:
-        ret = get_errno(sys_setresuid(low2highuid(arg1),
-                                      low2highuid(arg2),
-                                      low2highuid(arg3)));
+        ret = get_errno(setresuid(low2highuid(arg1),
+                                  low2highuid(arg2),
+                                  low2highuid(arg3)));
         break;
 #endif
 #ifdef TARGET_NR_getresuid
@@ -10337,9 +8761,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_getresgid
     case TARGET_NR_setresgid:
-        ret = get_errno(sys_setresgid(low2highgid(arg1),
-                                      low2highgid(arg2),
-                                      low2highgid(arg3)));
+        ret = get_errno(setresgid(low2highgid(arg1),
+                                  low2highgid(arg2),
+                                  low2highgid(arg3)));
         break;
 #endif
 #ifdef TARGET_NR_getresgid
@@ -10365,10 +8789,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #endif
     case TARGET_NR_setuid:
-        ret = get_errno(sys_setuid(low2highuid(arg1)));
+        ret = get_errno(setuid(low2highuid(arg1)));
         break;
     case TARGET_NR_setgid:
-        ret = get_errno(sys_setgid(low2highgid(arg1)));
+        ret = get_errno(setgid(low2highgid(arg1)));
         break;
     case TARGET_NR_setfsuid:
         ret = get_errno(setfsuid(arg1));
@@ -10565,11 +8989,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             }
             mask = arg2;
             target_to_host_old_sigset(&set, &mask);
-            ret = do_sigprocmask(how, &set, &oldset);
-            if (!ret) {
-                host_to_target_old_sigset(&mask, &oldset);
-                ret = mask;
-            }
+            do_sigprocmask(how, &set, &oldset);
+            host_to_target_old_sigset(&mask, &oldset);
+            ret = mask;
         }
         break;
 #endif
@@ -10652,7 +9074,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_setresuid32
     case TARGET_NR_setresuid32:
-        ret = get_errno(sys_setresuid(arg1, arg2, arg3));
+        ret = get_errno(setresuid(arg1, arg2, arg3));
         break;
 #endif
 #ifdef TARGET_NR_getresuid32
@@ -10671,7 +9093,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_setresgid32
     case TARGET_NR_setresgid32:
-        ret = get_errno(sys_setresgid(arg1, arg2, arg3));
+        ret = get_errno(setresgid(arg1, arg2, arg3));
         break;
 #endif
 #ifdef TARGET_NR_getresgid32
@@ -10698,12 +9120,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_setuid32
     case TARGET_NR_setuid32:
-        ret = get_errno(sys_setuid(arg1));
+        ret = get_errno(setuid(arg1));
         break;
 #endif
 #ifdef TARGET_NR_setgid32
     case TARGET_NR_setgid32:
-        ret = get_errno(sys_setgid(arg1));
+        ret = get_errno(setgid(arg1));
         break;
 #endif
 #ifdef TARGET_NR_setfsuid32
@@ -10737,56 +9159,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_arm_fadvise64_64
     case TARGET_NR_arm_fadvise64_64:
-        /* arm_fadvise64_64 looks like fadvise64_64 but
-         * with different argument order: fd, advice, offset, len
-         * rather than the usual fd, offset, len, advice.
-         * Note that offset and len are both 64-bit so appear as
-         * pairs of 32-bit registers.
-         */
-        ret = posix_fadvise(arg1, target_offset64(arg3, arg4),
-                            target_offset64(arg5, arg6), arg2);
-        ret = -host_to_target_errno(ret);
-        break;
-#endif
-
-#if TARGET_ABI_BITS == 32
-
-#ifdef TARGET_NR_fadvise64_64
-    case TARGET_NR_fadvise64_64:
-        /* 6 args: fd, offset (high, low), len (high, low), advice */
-        if (regpairs_aligned(cpu_env)) {
-            /* offset is in (3,4), len in (5,6) and advice in 7 */
-            arg2 = arg3;
-            arg3 = arg4;
-            arg4 = arg5;
-            arg5 = arg6;
-            arg6 = arg7;
-        }
-        ret = -host_to_target_errno(posix_fadvise(arg1,
-                                                  target_offset64(arg2, arg3),
-                                                  target_offset64(arg4, arg5),
-                                                  arg6));
-        break;
-#endif
-
-#ifdef TARGET_NR_fadvise64
-    case TARGET_NR_fadvise64:
-        /* 5 args: fd, offset (high, low), len, advice */
-        if (regpairs_aligned(cpu_env)) {
-            /* offset is in (3,4), len in 5 and advice in 6 */
-            arg2 = arg3;
-            arg3 = arg4;
-            arg4 = arg5;
-            arg5 = arg6;
-        }
-        ret = -host_to_target_errno(posix_fadvise(arg1,
-                                                  target_offset64(arg2, arg3),
-                                                  arg4, arg5));
-        break;
+       {
+               /*
+                * arm_fadvise64_64 looks like fadvise64_64 but
+                * with different argument order
+                */
+               abi_long temp;
+               temp = arg3;
+               arg3 = arg4;
+               arg4 = temp;
+       }
 #endif
-
-#else /* not a 32-bit ABI */
-#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_fadvise64)
+#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
 #ifdef TARGET_NR_fadvise64_64
     case TARGET_NR_fadvise64_64:
 #endif
@@ -10802,11 +9186,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         default: break;
         }
 #endif
-        ret = -host_to_target_errno(posix_fadvise(arg1, arg2, arg3, arg4));
-        break;
+        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
+       break;
 #endif
-#endif /* end of 64-bit ABI fadvise handling */
-
 #ifdef TARGET_NR_madvise
     case TARGET_NR_madvise:
         /* A straight passthrough may not be safe because qemu sometimes
@@ -10821,14 +9203,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     {
        int cmd;
        struct flock64 fl;
-        from_flock64_fn *copyfrom = copy_from_user_flock64;
-        to_flock64_fn *copyto = copy_to_user_flock64;
-
+       struct target_flock64 *target_fl;
 #ifdef TARGET_ARM
-        if (((CPUARMState *)cpu_env)->eabi) {
-            copyfrom = copy_from_user_eabi_flock64;
-            copyto = copy_to_user_eabi_flock64;
-        }
+       struct target_eabi_flock64 *target_efl;
 #endif
 
        cmd = target_to_host_fcntl_cmd(arg2);
@@ -10839,23 +9216,80 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 
         switch(arg2) {
         case TARGET_F_GETLK64:
-            ret = copyfrom(&fl, arg3);
-            if (ret) {
-                break;
+#ifdef TARGET_ARM
+            if (((CPUARMState *)cpu_env)->eabi) {
+                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
+                    goto efault;
+                fl.l_type = tswap16(target_efl->l_type);
+                fl.l_whence = tswap16(target_efl->l_whence);
+                fl.l_start = tswap64(target_efl->l_start);
+                fl.l_len = tswap64(target_efl->l_len);
+                fl.l_pid = tswap32(target_efl->l_pid);
+                unlock_user_struct(target_efl, arg3, 0);
+            } else
+#endif
+            {
+                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
+                    goto efault;
+                fl.l_type = tswap16(target_fl->l_type);
+                fl.l_whence = tswap16(target_fl->l_whence);
+                fl.l_start = tswap64(target_fl->l_start);
+                fl.l_len = tswap64(target_fl->l_len);
+                fl.l_pid = tswap32(target_fl->l_pid);
+                unlock_user_struct(target_fl, arg3, 0);
             }
             ret = get_errno(fcntl(arg1, cmd, &fl));
-            if (ret == 0) {
-                ret = copyto(arg3, &fl);
-            }
+           if (ret == 0) {
+#ifdef TARGET_ARM
+                if (((CPUARMState *)cpu_env)->eabi) {
+                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
+                        goto efault;
+                    target_efl->l_type = tswap16(fl.l_type);
+                    target_efl->l_whence = tswap16(fl.l_whence);
+                    target_efl->l_start = tswap64(fl.l_start);
+                    target_efl->l_len = tswap64(fl.l_len);
+                    target_efl->l_pid = tswap32(fl.l_pid);
+                    unlock_user_struct(target_efl, arg3, 1);
+                } else
+#endif
+                {
+                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
+                        goto efault;
+                    target_fl->l_type = tswap16(fl.l_type);
+                    target_fl->l_whence = tswap16(fl.l_whence);
+                    target_fl->l_start = tswap64(fl.l_start);
+                    target_fl->l_len = tswap64(fl.l_len);
+                    target_fl->l_pid = tswap32(fl.l_pid);
+                    unlock_user_struct(target_fl, arg3, 1);
+                }
+           }
            break;
 
         case TARGET_F_SETLK64:
         case TARGET_F_SETLKW64:
-            ret = copyfrom(&fl, arg3);
-            if (ret) {
-                break;
+#ifdef TARGET_ARM
+            if (((CPUARMState *)cpu_env)->eabi) {
+                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
+                    goto efault;
+                fl.l_type = tswap16(target_efl->l_type);
+                fl.l_whence = tswap16(target_efl->l_whence);
+                fl.l_start = tswap64(target_efl->l_start);
+                fl.l_len = tswap64(target_efl->l_len);
+                fl.l_pid = tswap32(target_efl->l_pid);
+                unlock_user_struct(target_efl, arg3, 0);
+            } else
+#endif
+            {
+                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
+                    goto efault;
+                fl.l_type = tswap16(target_fl->l_type);
+                fl.l_whence = tswap16(target_fl->l_whence);
+                fl.l_start = tswap64(target_fl->l_start);
+                fl.l_len = tswap64(target_fl->l_len);
+                fl.l_pid = tswap32(target_fl->l_pid);
+                unlock_user_struct(target_fl, arg3, 0);
             }
-            ret = get_errno(safe_fcntl(arg1, cmd, &fl));
+            ret = get_errno(fcntl(arg1, cmd, &fl));
            break;
         default:
             ret = do_fcntl(arg1, arg2, arg3);
@@ -11139,15 +9573,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     {
         struct timespec ts;
         target_to_host_timespec(&ts, arg3);
-        ret = get_errno(safe_clock_nanosleep(arg1, arg2,
-                                             &ts, arg4 ? &ts : NULL));
+        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
         if (arg4)
             host_to_target_timespec(arg4, &ts);
 
 #if defined(TARGET_PPC)
         /* clock_nanosleep is odd in that it returns positive errno values.
          * On PPC, CR0 bit 3 should be set in such a situation. */
-        if (ret && ret != -TARGET_ERESTARTSYS) {
+        if (ret) {
             ((CPUPPCState *)cpu_env)->crf[0] |= 1;
         }
 #endif
@@ -11161,14 +9594,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #endif
 
+#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
     case TARGET_NR_tkill:
-        ret = get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2)));
+        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
         break;
+#endif
 
+#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
     case TARGET_NR_tgkill:
-        ret = get_errno(safe_tgkill((int)arg1, (int)arg2,
+       ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
                         target_to_host_signal(arg3)));
-        break;
+       break;
+#endif
 
 #ifdef TARGET_NR_set_robust_list
     case TARGET_NR_set_robust_list:
@@ -11270,11 +9707,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             p = lock_user (VERIFY_READ, arg2, arg3, 1);
             if (arg5 != 0) {
                 target_to_host_timespec(&ts, arg5);
-                ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, &ts));
+                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
                 host_to_target_timespec(arg5, &ts);
-            } else {
-                ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, NULL));
             }
+            else
+                ret = get_errno(mq_send(arg1, p, arg3, arg4));
             unlock_user (p, arg2, arg3);
         }
         break;
@@ -11287,13 +9724,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             p = lock_user (VERIFY_READ, arg2, arg3, 1);
             if (arg5 != 0) {
                 target_to_host_timespec(&ts, arg5);
-                ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
-                                                     &prio, &ts));
+                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
                 host_to_target_timespec(arg5, &ts);
-            } else {
-                ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
-                                                     &prio, NULL));
             }
+            else
+                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
             unlock_user (p, arg2, arg3);
             if (arg4 != 0)
                 put_user_u32(prio, arg4);
@@ -11480,11 +9915,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     }
 #endif
 
-#if defined(TARGET_NR_epoll_wait) || defined(TARGET_NR_epoll_pwait)
+#if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
+#define IMPLEMENT_EPOLL_PWAIT
+#endif
+#if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
 #if defined(TARGET_NR_epoll_wait)
     case TARGET_NR_epoll_wait:
 #endif
-#if defined(TARGET_NR_epoll_pwait)
+#if defined(IMPLEMENT_EPOLL_PWAIT)
     case TARGET_NR_epoll_pwait:
 #endif
     {
@@ -11503,18 +9941,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ep = alloca(maxevents * sizeof(struct epoll_event));
 
         switch (num) {
-#if defined(TARGET_NR_epoll_pwait)
+#if defined(IMPLEMENT_EPOLL_PWAIT)
         case TARGET_NR_epoll_pwait:
         {
             target_sigset_t *target_set;
             sigset_t _set, *set = &_set;
 
             if (arg5) {
-                if (arg6 != sizeof(target_sigset_t)) {
-                    ret = -TARGET_EINVAL;
-                    break;
-                }
-
                 target_set = lock_user(VERIFY_READ, arg5,
                                        sizeof(target_sigset_t), 1);
                 if (!target_set) {
@@ -11527,15 +9960,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 set = NULL;
             }
 
-            ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
-                                             set, SIGSET_T_SIZE));
+            ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
             break;
         }
 #endif
 #if defined(TARGET_NR_epoll_wait)
         case TARGET_NR_epoll_wait:
-            ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
-                                             NULL, 0));
+            ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
             break;
 #endif
         default:
@@ -11824,7 +10255,6 @@ fail:
 #endif
     if(do_strace)
         print_syscall_ret(num, ret);
-    trace_guest_user_syscall_ret(cpu, num, ret);
     return ret;
 efault:
     ret = -TARGET_EFAULT;
index 7835654..9e2b3c2 100644 (file)
@@ -5,7 +5,8 @@
    necessary */
 
 #ifndef SYSCALL_DEFS_H
-#define SYSCALL_DEFS_H
+#define SYSCALL_DEFS_H 1
+
 
 #include "syscall_nr.h"
 
@@ -54,8 +55,7 @@
 #define TARGET_IOC_NRBITS      8
 #define TARGET_IOC_TYPEBITS    8
 
-#if (defined(TARGET_I386) && defined(TARGET_ABI32)) \
-    || (defined(TARGET_ARM) && defined(TARGET_ABI32)) \
+#if defined(TARGET_I386) || (defined(TARGET_ARM) && defined(TARGET_ABI32)) \
     || defined(TARGET_SPARC) \
     || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
     /* 16 bit uid wrappers emulation */
@@ -134,24 +134,6 @@ struct target_sockaddr_ll {
     uint8_t  sll_addr[8];  /* Physical layer address */
 };
 
-struct target_sockaddr_un {
-    uint16_t su_family;
-    uint8_t sun_path[108];
-};
-
-struct target_in_addr {
-    uint32_t s_addr; /* big endian */
-};
-
-struct target_sockaddr_in {
-  uint16_t sin_family;
-  int16_t sin_port; /* big endian */
-  struct target_in_addr sin_addr;
-  uint8_t __pad[sizeof(struct target_sockaddr) -
-                sizeof(uint16_t) - sizeof(int16_t) -
-                sizeof(struct target_in_addr)];
-};
-
 struct target_sock_filter {
     abi_ushort code;
     uint8_t jt;
@@ -164,6 +146,10 @@ struct target_sock_fprog {
     abi_ulong filter;
 };
 
+struct target_in_addr {
+    uint32_t s_addr; /* big endian */
+};
+
 struct target_ip_mreq {
     struct target_in_addr imr_multiaddr;
     struct target_in_addr imr_address;
@@ -686,21 +672,6 @@ typedef struct {
 
 #define TARGET_SI_PAD_SIZE ((TARGET_SI_MAX_SIZE - TARGET_SI_PREAMBLE_SIZE) / sizeof(int))
 
-/* Within QEMU the top 16 bits of si_code indicate which of the parts of
- * the union in target_siginfo is valid. This only applies between
- * host_to_target_siginfo_noswap() and tswap_siginfo(); it does not
- * appear either within host siginfo_t or in target_siginfo structures
- * which we get from the guest userspace program. (The Linux kernel
- * does a similar thing with using the top bits for its own internal
- * purposes but not letting them be visible to userspace.)
- */
-#define QEMU_SI_KILL 0
-#define QEMU_SI_TIMER 1
-#define QEMU_SI_POLL 2
-#define QEMU_SI_FAULT 3
-#define QEMU_SI_CHLD 4
-#define QEMU_SI_RT 5
-
 typedef struct target_siginfo {
 #ifdef TARGET_MIPS
        int si_signo;
@@ -985,17 +956,6 @@ struct target_pollfd {
 #define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,abi_ulong)
                                              /* return device size in bytes
                                                 (u64 *arg) */
-
-#define TARGET_BLKDISCARD TARGET_IO(0x12, 119)
-#define TARGET_BLKIOMIN TARGET_IO(0x12, 120)
-#define TARGET_BLKIOOPT TARGET_IO(0x12, 121)
-#define TARGET_BLKALIGNOFF TARGET_IO(0x12, 122)
-#define TARGET_BLKPBSZGET TARGET_IO(0x12, 123)
-#define TARGET_BLKDISCARDZEROES TARGET_IO(0x12, 124)
-#define TARGET_BLKSECDISCARD TARGET_IO(0x12, 125)
-#define TARGET_BLKROTATIONAL TARGET_IO(0x12, 126)
-#define TARGET_BLKZEROOUT TARGET_IO(0x12, 127)
-
 #define TARGET_FIBMAP     TARGET_IO(0x00,1)  /* bmap access */
 #define TARGET_FIGETBSZ   TARGET_IO(0x00,2)  /* get the block size used for bmap */
 #define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap)
@@ -1128,10 +1088,6 @@ struct target_pollfd {
 #define TARGET_LOOP_GET_STATUS64      0x4C05
 #define TARGET_LOOP_CHANGE_FD         0x4C06
 
-#define TARGET_LOOP_CTL_ADD           0x4C80
-#define TARGET_LOOP_CTL_REMOVE        0x4C81
-#define TARGET_LOOP_CTL_GET_FREE      0x4C82
-
 /* fb ioctls */
 #define TARGET_FBIOGET_VSCREENINFO    0x4600
 #define TARGET_FBIOPUT_VSCREENINFO    0x4601
@@ -2194,8 +2150,6 @@ struct target_statfs64 {
 #define TARGET_F_SETLEASE (TARGET_F_LINUX_SPECIFIC_BASE + 0)
 #define TARGET_F_GETLEASE (TARGET_F_LINUX_SPECIFIC_BASE + 1)
 #define TARGET_F_DUPFD_CLOEXEC (TARGET_F_LINUX_SPECIFIC_BASE + 6)
-#define TARGET_F_SETPIPE_SZ (TARGET_F_LINUX_SPECIFIC_BASE + 7)
-#define TARGET_F_GETPIPE_SZ (TARGET_F_LINUX_SPECIFIC_BASE + 8)
 #define TARGET_F_NOTIFY  (TARGET_F_LINUX_SPECIFIC_BASE+2)
 
 #if defined(TARGET_ALPHA)
@@ -2319,34 +2273,34 @@ struct target_statfs64 {
 #endif
 
 struct target_flock {
-    short l_type;
-    short l_whence;
-    abi_long l_start;
-    abi_long l_len;
-    int l_pid;
+       short l_type;
+       short l_whence;
+       abi_ulong l_start;
+       abi_ulong l_len;
+       int l_pid;
 };
 
 struct target_flock64 {
-    short  l_type;
-    short  l_whence;
+       short  l_type;
+       short  l_whence;
 #if defined(TARGET_PPC) || defined(TARGET_X86_64) || defined(TARGET_MIPS) \
     || defined(TARGET_SPARC) || defined(TARGET_HPPA) \
     || defined(TARGET_MICROBLAZE) || defined(TARGET_TILEGX)
-    int __pad;
+        int __pad;
 #endif
-    abi_llong l_start;
-    abi_llong l_len;
-    int  l_pid;
+       unsigned long long l_start;
+       unsigned long long l_len;
+       int  l_pid;
 } QEMU_PACKED;
 
 #ifdef TARGET_ARM
 struct target_eabi_flock64 {
-    short  l_type;
-    short  l_whence;
-    int __pad;
-    abi_llong l_start;
-    abi_llong l_len;
-    int  l_pid;
+       short  l_type;
+       short  l_whence;
+        int __pad;
+       unsigned long long l_start;
+       unsigned long long l_len;
+       int  l_pid;
 } QEMU_PACKED;
 #endif
 
@@ -2591,6 +2545,8 @@ struct target_ucred {
     uint32_t gid;
 };
 
+#endif
+
 typedef int32_t target_timer_t;
 
 #define TARGET_SIGEV_MAX_SIZE 64
@@ -2632,5 +2588,3 @@ struct target_user_cap_data {
     uint32_t permitted;
     uint32_t inheritable;
 };
-
-#endif
index af79fbf..1fd4ee0 100644 (file)
@@ -103,11 +103,10 @@ STRUCT(loop_info64,
        TYPE_ULONGLONG,           /* lo_inode */
        TYPE_ULONGLONG,           /* lo_rdevice */
        TYPE_ULONGLONG,           /* lo_offset */
-       TYPE_ULONGLONG,           /* lo_sizelimit */
-       TYPE_INT,                 /* lo_number */
-       TYPE_INT,                 /* lo_encrypt_type */
-       TYPE_INT,                 /* lo_encrypt_key_size */
-       TYPE_INT,                 /* lo_flags */
+       TYPE_ULONG,               /* lo_number */
+       TYPE_ULONG,               /* lo_encrypt_type */
+       TYPE_ULONG,               /* lo_encrypt_key_size */
+       TYPE_ULONG,               /* lo_flags */
        MK_ARRAY(TYPE_CHAR, 64),  /* lo_name */
        MK_ARRAY(TYPE_CHAR, 64),  /* lo_crypt_name */
        MK_ARRAY(TYPE_CHAR, 32),  /* lo_encrypt_key */
index 8e30cd1..87fb72c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef TILEGX_SYSCALL_NR_H
-#define TILEGX_SYSCALL_NR_H
+#ifndef TILEGX_SYSCALL_NR
+#define TILEGX_SYSCALL_NR
 
 /*
  * Copy from linux kernel asm-generic/unistd.h, which tilegx uses.
index 4878e01..c96e81d 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef TILEGX_TARGET_CPU_H
-#define TILEGX_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUTLGState *env, target_ulong newsp)
 {
index f64551a..b595f98 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef TILEGX_TARGET_SIGNAL_H
-#define TILEGX_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -25,5 +25,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUTLGState *state)
     return state->regs[TILEGX_R_SP];
 }
 
-
-#endif /* TILEGX_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index de8b1f2..7d3ff78 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef TILEGX_TARGET_STRUCTS_H
-#define TILEGX_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index d731acd..a938d4e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef TILEGX_TARGET_SYSCALL_H
-#define TILEGX_TARGET_SYSCALL_H
+#ifndef TILEGX_SYSCALLS_H
+#define TILEGX_SYSCALLS_H
 
 #define UNAME_MACHINE "tilegx"
 #define UNAME_MINIMUM_RELEASE "3.19"
diff --git a/linux-user/trace-events b/linux-user/trace-events
deleted file mode 100644 (file)
index fc71f91..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# linux-user/signal.c
-user_setup_frame(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64
-user_setup_rt_frame(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64
-user_do_rt_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64
-user_do_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64
-user_force_sig(void *env, int target_sig, int host_sig) "env=%p signal %d (host %d)"
-user_handle_signal(void *env, int target_sig) "env=%p signal %d"
-user_host_signal(void *env, int host_sig, int target_sig) "env=%p signal %d (target %d("
-user_queue_signal(void *env, int target_sig) "env=%p signal %d"
-user_s390x_restore_sigregs(void *env, uint64_t sc_psw_addr, uint64_t env_psw_addr) "env=%p frame psw.addr %"PRIx64 " current psw.addr %"PRIx64
index 4503094..cc62e76 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef UNAME_H
-#define UNAME_H
+#define UNAME_H 1
 
 #include <sys/utsname.h>
 #include <linux/utsname.h>
@@ -7,4 +7,4 @@
 const char *cpu_to_uname_machine(void *cpu_env);
 int sys_uname(struct new_utsname *buf);
 
-#endif /* UNAME_H */
+#endif /* UNAME _H */
index d7d2e7b..fb79087 100644 (file)
@@ -8,8 +8,8 @@
  * published by the Free Software Foundation, or (at your option) any
  * later version. See the COPYING file in the top-level directory.
  */
-#ifndef UNICORE32_TARGET_CPU_H
-#define UNICORE32_TARGET_CPU_H
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUUniCore32State *env, target_ulong newsp)
 {
index c6496fb..7c44238 100644 (file)
@@ -5,8 +5,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#ifndef UNICORE32_TARGET_SIGNAL_H
-#define UNICORE32_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 /* this struct defines a stack used during syscall handling */
 typedef struct target_sigaltstack {
@@ -27,4 +27,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUUniCore32State *state)
 }
 
 
-#endif /* UNICORE32_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index fbd4fa3..7893695 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef UNICORE32_TARGET_STRUCTS_H
-#define UNICORE32_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
index 346b207..385a975 100644 (file)
@@ -5,10 +5,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
-#ifndef UNICORE32_TARGET_SYSCALL_H
-#define UNICORE32_TARGET_SYSCALL_H
-
+#ifndef __UC32_SYSCALL_H__
+#define __UC32_SYSCALL_H__
 struct target_pt_regs {
     abi_ulong uregs[34];
 };
@@ -59,4 +57,4 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
-#endif /* UNICORE32_TARGET_SYSCALL_H */
+#endif /* __UC32_SYSCALL_H__ */
index 1e95f4a..9baf7fb 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef X86_64_TARGET_SIGNAL_H
-#define X86_64_TARGET_SIGNAL_H
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
 
 #include "cpu.h"
 
@@ -26,4 +26,4 @@ static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
     return state->regs[R_ESP];
 }
 
-#endif /* X86_64_TARGET_SIGNAL_H */
+#endif /* TARGET_SIGNAL_H */
index b6e82a8..d934056 100644 (file)
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef X86_64_TARGET_STRUCTS_H
-#define X86_64_TARGET_STRUCTS_H
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
 
 struct target_ipc_perm {
     abi_int __key;                      /* Key.  */
@@ -55,19 +55,4 @@ struct target_shmid_ds {
     abi_ulong __unused5;
 };
 
-/* The x86 definition differs from the generic one in that the
- * two padding fields exist whether the ABI is 32 bits or 64 bits.
- */
-#define TARGET_SEMID64_DS
-struct target_semid64_ds {
-    struct target_ipc_perm sem_perm;
-    abi_ulong sem_otime;
-    abi_ulong __unused1;
-    abi_ulong sem_ctime;
-    abi_ulong __unused2;
-    abi_ulong sem_nsems;
-    abi_ulong __unused3;
-    abi_ulong __unused4;
-};
-
 #endif
index 983fb23..feecd32 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef X86_64_TARGET_SYSCALL_H
-#define X86_64_TARGET_SYSCALL_H
+#ifndef TARGET_SYSCALL_H
+#define TARGET_SYSCALL_H
 
 #define __USER_CS      (0x33)
 #define __USER_DS      (0x2B)
@@ -104,4 +104,4 @@ struct target_msqid64_ds {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
-#endif /* X86_64_TARGET_SYSCALL_H */
+#endif  /* TARGET_SYSCALL_H */
index 387e742..1c3445c 100644 (file)
@@ -209,12 +209,12 @@ struct target_termios {
 #define TARGET_TIOCSBRK        0x5427  /* BSD compatibility */
 #define TARGET_TIOCCBRK        0x5428  /* BSD compatibility */
 #define TARGET_TIOCGSID        0x5429  /* Return the session ID of FD */
-#define TARGET_TCGETS2          TARGET_IOR('T',0x2A, struct termios2)
-#define TARGET_TCSETS2          TARGET_IOW('T',0x2B, struct termios2)
-#define TARGET_TCSETSW2         TARGET_IOW('T',0x2C, struct termios2)
-#define TARGET_TCSETSF2         TARGET_IOW('T',0x2D, struct termios2)
-#define TARGET_TIOCGPTN         TARGET_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TARGET_TIOCSPTLCK       TARGET_IOW('T',0x31, int)  /* Lock/unlock Pty */
+#define TARGET_TCGETS2         _IOR('T',0x2A, struct termios2)
+#define TARGET_TCSETS2         _IOW('T',0x2B, struct termios2)
+#define TARGET_TCSETSW2        _IOW('T',0x2C, struct termios2)
+#define TARGET_TCSETSF2        _IOW('T',0x2D, struct termios2)
+#define TARGET_TIOCGPTN        _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TARGET_TIOCSPTLCK      _IOW('T',0x31, int)  /* Lock/unlock Pty */
 
 #define TARGET_FIONCLEX        0x5450  /* these numbers need to be adjusted. */
 #define TARGET_FIOCLEX         0x5451
index 6a7f8d3..89a6994 100644 (file)
@@ -154,11 +154,11 @@ int qemu_init_main_loop(Error **errp)
     }
 
     qemu_aio_context = aio_context_new(&local_error);
+    qemu_notify_bh = qemu_bh_new(notify_event_cb, NULL);
     if (!qemu_aio_context) {
         error_propagate(errp, local_error);
         return -EMFILE;
     }
-    qemu_notify_bh = qemu_bh_new(notify_event_cb, NULL);
     gpollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
     src = aio_get_g_source(qemu_aio_context);
     g_source_attach(src, NULL);
index 0eb6895..f76f85d 100644 (file)
--- a/memory.c
+++ b/memory.c
@@ -15,8 +15,6 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "exec/memory.h"
 #include "exec/address-spaces.h"
 #include "exec/ioport.h"
@@ -33,6 +31,8 @@
 
 //#define DEBUG_UNASSIGNED
 
+#define RAM_ADDR_INVALID (~(ram_addr_t)0)
+
 static unsigned memory_region_transaction_depth;
 static bool memory_region_update_pending;
 static bool ioeventfd_update_pending;
@@ -1055,6 +1055,13 @@ static void memory_region_get_priority(Object *obj, Visitor *v,
     visit_type_int32(v, name, &value, errp);
 }
 
+static bool memory_region_get_may_overlap(Object *obj, Error **errp)
+{
+    MemoryRegion *mr = MEMORY_REGION(obj);
+
+    return mr->may_overlap;
+}
+
 static void memory_region_get_size(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
@@ -1092,6 +1099,10 @@ static void memory_region_initfn(Object *obj)
                         memory_region_get_priority,
                         NULL, /* memory_region_set_priority */
                         NULL, NULL, &error_abort);
+    object_property_add_bool(OBJECT(mr), "may-overlap",
+                             memory_region_get_may_overlap,
+                             NULL, /* memory_region_set_may_overlap */
+                             &error_abort);
     object_property_add(OBJECT(mr), "size", "uint64",
                         memory_region_get_size,
                         NULL, /* memory_region_set_size, */
@@ -1376,21 +1387,6 @@ void memory_region_init_alias(MemoryRegion *mr,
     mr->alias_offset = offset;
 }
 
-void memory_region_init_rom(MemoryRegion *mr,
-                            struct Object *owner,
-                            const char *name,
-                            uint64_t size,
-                            Error **errp)
-{
-    memory_region_init(mr, owner, name, size);
-    mr->ram = true;
-    mr->readonly = true;
-    mr->terminates = true;
-    mr->destructor = memory_region_destructor_ram;
-    mr->ram_block = qemu_ram_alloc(size, mr, errp);
-    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
-}
-
 void memory_region_init_rom_device(MemoryRegion *mr,
                                    Object *owner,
                                    const MemoryRegionOps *ops,
@@ -1399,7 +1395,6 @@ void memory_region_init_rom_device(MemoryRegion *mr,
                                    uint64_t size,
                                    Error **errp)
 {
-    assert(ops);
     memory_region_init(mr, owner, name, size);
     mr->ops = ops;
     mr->opaque = opaque;
@@ -1515,29 +1510,15 @@ bool memory_region_is_logging(MemoryRegion *mr, uint8_t client)
 
 void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n)
 {
-    if (mr->iommu_ops->notify_started &&
-        QLIST_EMPTY(&mr->iommu_notify.notifiers)) {
-        mr->iommu_ops->notify_started(mr);
-    }
     notifier_list_add(&mr->iommu_notify, n);
 }
 
-uint64_t memory_region_iommu_get_min_page_size(MemoryRegion *mr)
+void memory_region_iommu_replay(MemoryRegion *mr, Notifier *n,
+                                hwaddr granularity, bool is_write)
 {
-    assert(memory_region_is_iommu(mr));
-    if (mr->iommu_ops && mr->iommu_ops->get_min_page_size) {
-        return mr->iommu_ops->get_min_page_size(mr);
-    }
-    return TARGET_PAGE_SIZE;
-}
-
-void memory_region_iommu_replay(MemoryRegion *mr, Notifier *n, bool is_write)
-{
-    hwaddr addr, granularity;
+    hwaddr addr;
     IOMMUTLBEntry iotlb;
 
-    granularity = memory_region_iommu_get_min_page_size(mr);
-
     for (addr = 0; addr < memory_region_size(mr); addr += granularity) {
         iotlb = mr->iommu_ops->translate(mr, addr, is_write);
         if (iotlb.perm != IOMMU_NONE) {
@@ -1552,13 +1533,9 @@ void memory_region_iommu_replay(MemoryRegion *mr, Notifier *n, bool is_write)
     }
 }
 
-void memory_region_unregister_iommu_notifier(MemoryRegion *mr, Notifier *n)
+void memory_region_unregister_iommu_notifier(Notifier *n)
 {
     notifier_remove(n);
-    if (mr->iommu_ops->notify_stopped &&
-        QLIST_EMPTY(&mr->iommu_notify.notifiers)) {
-        mr->iommu_ops->notify_stopped(mr);
-    }
 }
 
 void memory_region_notify_iommu(MemoryRegion *mr,
@@ -1658,26 +1635,13 @@ void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr,
 
 int memory_region_get_fd(MemoryRegion *mr)
 {
-    int fd;
-
-    rcu_read_lock();
-    while (mr->alias) {
-        mr = mr->alias;
+    if (mr->alias) {
+        return memory_region_get_fd(mr->alias);
     }
-    fd = mr->ram_block->fd;
-    rcu_read_unlock();
 
-    return fd;
-}
+    assert(mr->ram_block);
 
-void memory_region_set_fd(MemoryRegion *mr, int fd)
-{
-    rcu_read_lock();
-    while (mr->alias) {
-        mr = mr->alias;
-    }
-    mr->ram_block->fd = fd;
-    rcu_read_unlock();
+    return qemu_get_ram_fd(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK);
 }
 
 void *memory_region_get_ram_ptr(MemoryRegion *mr)
@@ -1691,22 +1655,11 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
         mr = mr->alias;
     }
     assert(mr->ram_block);
-    ptr = qemu_map_ram_ptr(mr->ram_block, offset);
+    ptr = qemu_get_ram_ptr(mr->ram_block,
+                           memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK);
     rcu_read_unlock();
 
-    return ptr;
-}
-
-MemoryRegion *memory_region_from_host(void *ptr, ram_addr_t *offset)
-{
-    RAMBlock *block;
-
-    block = qemu_ram_block_from_host(ptr, false, offset);
-    if (!block) {
-        return NULL;
-    }
-
-    return block->mr;
+    return ptr + offset;
 }
 
 ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr)
@@ -1718,7 +1671,7 @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
 {
     assert(mr->ram_block);
 
-    qemu_ram_resize(mr->ram_block, newsize, errp);
+    qemu_ram_resize(memory_region_get_ram_addr(mr), newsize, errp);
 }
 
 static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as)
@@ -1909,6 +1862,7 @@ void memory_region_del_eventfd(MemoryRegion *mr,
 
 static void memory_region_update_container_subregions(MemoryRegion *subregion)
 {
+    hwaddr offset = subregion->addr;
     MemoryRegion *mr = subregion->container;
     MemoryRegion *other;
 
@@ -1916,6 +1870,27 @@ static void memory_region_update_container_subregions(MemoryRegion *subregion)
 
     memory_region_ref(subregion);
     QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
+        if (subregion->may_overlap || other->may_overlap) {
+            continue;
+        }
+        if (int128_ge(int128_make64(offset),
+                      int128_add(int128_make64(other->addr), other->size))
+            || int128_le(int128_add(int128_make64(offset), subregion->size),
+                         int128_make64(other->addr))) {
+            continue;
+        }
+#if 0
+        printf("warning: subregion collision %llx/%llx (%s) "
+               "vs %llx/%llx (%s)\n",
+               (unsigned long long)offset,
+               (unsigned long long)int128_get64(subregion->size),
+               subregion->name,
+               (unsigned long long)other->addr,
+               (unsigned long long)int128_get64(other->size),
+               other->name);
+#endif
+    }
+    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
         if (subregion->priority >= other->priority) {
             QTAILQ_INSERT_BEFORE(other, subregion, subregions_link);
             goto done;
@@ -1941,6 +1916,7 @@ void memory_region_add_subregion(MemoryRegion *mr,
                                  hwaddr offset,
                                  MemoryRegion *subregion)
 {
+    subregion->may_overlap = false;
     subregion->priority = 0;
     memory_region_add_subregion_common(mr, offset, subregion);
 }
@@ -1950,6 +1926,7 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
                                          MemoryRegion *subregion,
                                          int priority)
 {
+    subregion->may_overlap = true;
     subregion->priority = priority;
     memory_region_add_subregion_common(mr, offset, subregion);
 }
index e3e0d95..2354b2b 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include <glib.h>
 
 #include "qemu-common.h"
 #include "cpu.h"
index 30ad945..0cac6d7 100644 (file)
@@ -1,12 +1,10 @@
-common-obj-y += migration.o socket.o fd.o exec.o
-common-obj-y += tls.o
+common-obj-y += migration.o tcp.o
 common-obj-y += vmstate.o
-common-obj-y += qemu-file.o
-common-obj-y += qemu-file-channel.o
+common-obj-y += qemu-file.o qemu-file-buf.o qemu-file-unix.o qemu-file-stdio.o
 common-obj-y += xbzrle.o postcopy-ram.o
-common-obj-y += qjson.o
 
 common-obj-$(CONFIG_RDMA) += rdma.o
+common-obj-$(CONFIG_POSIX) += exec.o unix.o fd.o
 
 common-obj-y += block.o
 
index ebc10e6..1743317 100644 (file)
@@ -52,8 +52,7 @@
 
 typedef struct BlkMigDevState {
     /* Written during setup phase.  Can be read without a lock.  */
-    BlockBackend *blk;
-    char *blk_name;
+    BlockDriverState *bs;
     int shared_base;
     int64_t total_sectors;
     QSIMPLEQ_ENTRY(BlkMigDevState) entry;
@@ -146,9 +145,9 @@ static void blk_send(QEMUFile *f, BlkMigBlock * blk)
                      | flags);
 
     /* device name */
-    len = strlen(blk->bmds->blk_name);
+    len = strlen(bdrv_get_device_name(blk->bmds->bs));
     qemu_put_byte(f, len);
-    qemu_put_buffer(f, (uint8_t *) blk->bmds->blk_name, len);
+    qemu_put_buffer(f, (uint8_t *)bdrv_get_device_name(blk->bmds->bs), len);
 
     /* if a block is zero we need to flush here since the network
      * bandwidth is now a lot higher than the storage device bandwidth.
@@ -202,7 +201,7 @@ static int bmds_aio_inflight(BlkMigDevState *bmds, int64_t sector)
 {
     int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
 
-    if (sector < blk_nb_sectors(bmds->blk)) {
+    if (sector < bdrv_nb_sectors(bmds->bs)) {
         return !!(bmds->aio_bitmap[chunk / (sizeof(unsigned long) * 8)] &
             (1UL << (chunk % (sizeof(unsigned long) * 8))));
     } else {
@@ -236,10 +235,10 @@ static void bmds_set_aio_inflight(BlkMigDevState *bmds, int64_t sector_num,
 
 static void alloc_aio_bitmap(BlkMigDevState *bmds)
 {
-    BlockBackend *bb = bmds->blk;
+    BlockDriverState *bs = bmds->bs;
     int64_t bitmap_size;
 
-    bitmap_size = blk_nb_sectors(bb) + BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
+    bitmap_size = bdrv_nb_sectors(bs) + BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
     bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
 
     bmds->aio_bitmap = g_malloc0(bitmap_size);
@@ -269,19 +268,19 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds)
 {
     int64_t total_sectors = bmds->total_sectors;
     int64_t cur_sector = bmds->cur_sector;
-    BlockBackend *bb = bmds->blk;
+    BlockDriverState *bs = bmds->bs;
     BlkMigBlock *blk;
     int nr_sectors;
 
     if (bmds->shared_base) {
         qemu_mutex_lock_iothread();
-        aio_context_acquire(blk_get_aio_context(bb));
+        aio_context_acquire(bdrv_get_aio_context(bs));
         while (cur_sector < total_sectors &&
-               !bdrv_is_allocated(blk_bs(bb), cur_sector,
-                                  MAX_IS_ALLOCATED_SEARCH, &nr_sectors)) {
+               !bdrv_is_allocated(bs, cur_sector, MAX_IS_ALLOCATED_SEARCH,
+                                  &nr_sectors)) {
             cur_sector += nr_sectors;
         }
-        aio_context_release(blk_get_aio_context(bb));
+        aio_context_release(bdrv_get_aio_context(bs));
         qemu_mutex_unlock_iothread();
     }
 
@@ -324,12 +323,12 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds)
      * without the need to acquire the AioContext.
      */
     qemu_mutex_lock_iothread();
-    aio_context_acquire(blk_get_aio_context(bmds->blk));
-    blk->aiocb = blk_aio_preadv(bb, cur_sector * BDRV_SECTOR_SIZE, &blk->qiov,
-                                0, blk_mig_read_cb, blk);
+    aio_context_acquire(bdrv_get_aio_context(bmds->bs));
+    blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov,
+                                nr_sectors, blk_mig_read_cb, blk);
 
     bdrv_reset_dirty_bitmap(bmds->dirty_bitmap, cur_sector, nr_sectors);
-    aio_context_release(blk_get_aio_context(bmds->blk));
+    aio_context_release(bdrv_get_aio_context(bmds->bs));
     qemu_mutex_unlock_iothread();
 
     bmds->cur_sector = cur_sector + nr_sectors;
@@ -344,10 +343,10 @@ static int set_dirty_tracking(void)
     int ret;
 
     QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
-        aio_context_acquire(blk_get_aio_context(bmds->blk));
-        bmds->dirty_bitmap = bdrv_create_dirty_bitmap(blk_bs(bmds->blk),
-                                                      BLOCK_SIZE, NULL, NULL);
-        aio_context_release(blk_get_aio_context(bmds->blk));
+        aio_context_acquire(bdrv_get_aio_context(bmds->bs));
+        bmds->dirty_bitmap = bdrv_create_dirty_bitmap(bmds->bs, BLOCK_SIZE,
+                                                      NULL, NULL);
+        aio_context_release(bdrv_get_aio_context(bmds->bs));
         if (!bmds->dirty_bitmap) {
             ret = -errno;
             goto fail;
@@ -358,9 +357,9 @@ static int set_dirty_tracking(void)
 fail:
     QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
         if (bmds->dirty_bitmap) {
-            aio_context_acquire(blk_get_aio_context(bmds->blk));
-            bdrv_release_dirty_bitmap(blk_bs(bmds->blk), bmds->dirty_bitmap);
-            aio_context_release(blk_get_aio_context(bmds->blk));
+            aio_context_acquire(bdrv_get_aio_context(bmds->bs));
+            bdrv_release_dirty_bitmap(bmds->bs, bmds->dirty_bitmap);
+            aio_context_release(bdrv_get_aio_context(bmds->bs));
         }
     }
     return ret;
@@ -373,9 +372,9 @@ static void unset_dirty_tracking(void)
     BlkMigDevState *bmds;
 
     QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
-        aio_context_acquire(blk_get_aio_context(bmds->blk));
-        bdrv_release_dirty_bitmap(blk_bs(bmds->blk), bmds->dirty_bitmap);
-        aio_context_release(blk_get_aio_context(bmds->blk));
+        aio_context_acquire(bdrv_get_aio_context(bmds->bs));
+        bdrv_release_dirty_bitmap(bmds->bs, bmds->dirty_bitmap);
+        aio_context_release(bdrv_get_aio_context(bmds->bs));
     }
 }
 
@@ -384,12 +383,6 @@ static void init_blk_migration(QEMUFile *f)
     BlockDriverState *bs;
     BlkMigDevState *bmds;
     int64_t sectors;
-    BdrvNextIterator it;
-    int i, num_bs = 0;
-    struct {
-        BlkMigDevState *bmds;
-        BlockDriverState *bs;
-    } *bmds_bs;
 
     block_mig_state.submitted = 0;
     block_mig_state.read_done = 0;
@@ -399,32 +392,26 @@ static void init_blk_migration(QEMUFile *f)
     block_mig_state.bulk_completed = 0;
     block_mig_state.zero_blocks = migrate_zero_blocks();
 
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
-        num_bs++;
-    }
-    bmds_bs = g_malloc0(num_bs * sizeof(*bmds_bs));
-
-    for (i = 0, bs = bdrv_first(&it); bs; bs = bdrv_next(&it), i++) {
+    for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
         if (bdrv_is_read_only(bs)) {
             continue;
         }
 
         sectors = bdrv_nb_sectors(bs);
         if (sectors <= 0) {
-            goto out;
+            return;
         }
 
         bmds = g_new0(BlkMigDevState, 1);
-        bmds->blk = blk_new();
-        bmds->blk_name = g_strdup(bdrv_get_device_name(bs));
+        bmds->bs = bs;
         bmds->bulk_completed = 0;
         bmds->total_sectors = sectors;
         bmds->completed_sectors = 0;
         bmds->shared_base = block_mig_state.shared_base;
-
-        assert(i < num_bs);
-        bmds_bs[i].bmds = bmds;
-        bmds_bs[i].bs = bs;
+        alloc_aio_bitmap(bmds);
+        error_setg(&bmds->blocker, "block device is in use by migration");
+        bdrv_op_block_all(bs, bmds->blocker);
+        bdrv_ref(bs);
 
         block_mig_state.total_sector_sum += sectors;
 
@@ -437,24 +424,6 @@ static void init_blk_migration(QEMUFile *f)
 
         QSIMPLEQ_INSERT_TAIL(&block_mig_state.bmds_list, bmds, entry);
     }
-
-    /* Can only insert new BDSes now because doing so while iterating block
-     * devices may end up in a deadlock (iterating the new BDSes, too). */
-    for (i = 0; i < num_bs; i++) {
-        BlkMigDevState *bmds = bmds_bs[i].bmds;
-        BlockDriverState *bs = bmds_bs[i].bs;
-
-        if (bmds) {
-            blk_insert_bs(bmds->blk, bs);
-
-            alloc_aio_bitmap(bmds);
-            error_setg(&bmds->blocker, "block device is in use by migration");
-            bdrv_op_block_all(bs, bmds->blocker);
-        }
-    }
-
-out:
-    g_free(bmds_bs);
 }
 
 /* Called with no lock taken.  */
@@ -511,7 +480,6 @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
                                  int is_async)
 {
     BlkMigBlock *blk;
-    BlockDriverState *bs = blk_bs(bmds->blk);
     int64_t total_sectors = bmds->total_sectors;
     int64_t sector;
     int nr_sectors;
@@ -521,11 +489,11 @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
         blk_mig_lock();
         if (bmds_aio_inflight(bmds, sector)) {
             blk_mig_unlock();
-            blk_drain(bmds->blk);
+            bdrv_drain(bmds->bs);
         } else {
             blk_mig_unlock();
         }
-        if (bdrv_get_dirty(bs, bmds->dirty_bitmap, sector)) {
+        if (bdrv_get_dirty(bmds->bs, bmds->dirty_bitmap, sector)) {
 
             if (total_sectors - sector < BDRV_SECTORS_PER_DIRTY_CHUNK) {
                 nr_sectors = total_sectors - sector;
@@ -543,18 +511,15 @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
                 blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
                 qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);
 
-                blk->aiocb = blk_aio_preadv(bmds->blk,
-                                            sector * BDRV_SECTOR_SIZE,
-                                            &blk->qiov, 0, blk_mig_read_cb,
-                                            blk);
+                blk->aiocb = bdrv_aio_readv(bmds->bs, sector, &blk->qiov,
+                                            nr_sectors, blk_mig_read_cb, blk);
 
                 blk_mig_lock();
                 block_mig_state.submitted++;
                 bmds_set_aio_inflight(bmds, sector, nr_sectors, 1);
                 blk_mig_unlock();
             } else {
-                ret = blk_pread(bmds->blk, sector * BDRV_SECTOR_SIZE, blk->buf,
-                                nr_sectors * BDRV_SECTOR_SIZE);
+                ret = bdrv_read(bmds->bs, sector, blk->buf, nr_sectors);
                 if (ret < 0) {
                     goto error;
                 }
@@ -592,9 +557,9 @@ static int blk_mig_save_dirty_block(QEMUFile *f, int is_async)
     int ret = 1;
 
     QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
-        aio_context_acquire(blk_get_aio_context(bmds->blk));
+        aio_context_acquire(bdrv_get_aio_context(bmds->bs));
         ret = mig_save_device_dirty(f, bmds, is_async);
-        aio_context_release(blk_get_aio_context(bmds->blk));
+        aio_context_release(bdrv_get_aio_context(bmds->bs));
         if (ret <= 0) {
             break;
         }
@@ -652,9 +617,9 @@ static int64_t get_remaining_dirty(void)
     int64_t dirty = 0;
 
     QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
-        aio_context_acquire(blk_get_aio_context(bmds->blk));
+        aio_context_acquire(bdrv_get_aio_context(bmds->bs));
         dirty += bdrv_get_dirty_count(bmds->dirty_bitmap);
-        aio_context_release(blk_get_aio_context(bmds->blk));
+        aio_context_release(bdrv_get_aio_context(bmds->bs));
     }
 
     return dirty << BDRV_SECTOR_BITS;
@@ -674,16 +639,15 @@ static void block_migration_cleanup(void *opaque)
 
     while ((bmds = QSIMPLEQ_FIRST(&block_mig_state.bmds_list)) != NULL) {
         QSIMPLEQ_REMOVE_HEAD(&block_mig_state.bmds_list, entry);
-        bdrv_op_unblock_all(blk_bs(bmds->blk), bmds->blocker);
+        bdrv_op_unblock_all(bmds->bs, bmds->blocker);
         error_free(bmds->blocker);
 
-        /* Save ctx, because bmds->blk can disappear during blk_unref.  */
-        ctx = blk_get_aio_context(bmds->blk);
+        /* Save ctx, because bmds->bs can disappear during bdrv_unref.  */
+        ctx = bdrv_get_aio_context(bmds->bs);
         aio_context_acquire(ctx);
-        blk_unref(bmds->blk);
+        bdrv_unref(bmds->bs);
         aio_context_release(ctx);
 
-        g_free(bmds->blk_name);
         g_free(bmds->aio_bitmap);
         g_free(bmds);
     }
@@ -861,7 +825,8 @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
     int len, flags;
     char device_name[256];
     int64_t addr;
-    BlockBackend *blk, *blk_prev = NULL;;
+    BlockDriverState *bs, *bs_prev = NULL;
+    BlockBackend *blk;
     Error *local_err = NULL;
     uint8_t *buf;
     int64_t total_sectors = 0;
@@ -886,17 +851,23 @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
                         device_name);
                 return -EINVAL;
             }
+            bs = blk_bs(blk);
+            if (!bs) {
+                fprintf(stderr, "Block device %s has no medium\n",
+                        device_name);
+                return -EINVAL;
+            }
 
-            if (blk != blk_prev) {
-                blk_prev = blk;
-                total_sectors = blk_nb_sectors(blk);
+            if (bs != bs_prev) {
+                bs_prev = bs;
+                total_sectors = bdrv_nb_sectors(bs);
                 if (total_sectors <= 0) {
                     error_report("Error getting length of block device %s",
                                  device_name);
                     return -EINVAL;
                 }
 
-                blk_invalidate_cache(blk, &local_err);
+                bdrv_invalidate_cache(bs, &local_err);
                 if (local_err) {
                     error_report_err(local_err);
                     return -EINVAL;
@@ -910,14 +881,12 @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
             }
 
             if (flags & BLK_MIG_FLAG_ZERO_BLOCK) {
-                ret = blk_pwrite_zeroes(blk, addr * BDRV_SECTOR_SIZE,
-                                        nr_sectors * BDRV_SECTOR_SIZE,
+                ret = bdrv_write_zeroes(bs, addr, nr_sectors,
                                         BDRV_REQ_MAY_UNMAP);
             } else {
                 buf = g_malloc(BLOCK_SIZE);
                 qemu_get_buffer(f, buf, BLOCK_SIZE);
-                ret = blk_pwrite(blk, addr * BDRV_SECTOR_SIZE, buf,
-                                 nr_sectors * BDRV_SECTOR_SIZE, 0);
+                ret = bdrv_write(bs, addr, buf, nr_sectors);
                 g_free(buf);
             }
 
index 2af63cc..5594209 100644 (file)
@@ -3,12 +3,10 @@
  *
  * Copyright IBM, Corp. 2008
  * Copyright Dell MessageOne 2008
- * Copyright Red Hat, Inc. 2015-2016
  *
  * Authors:
  *  Anthony Liguori   <aliguori@us.ibm.com>
  *  Charles Duffy     <charles_duffy@messageone.com>
- *  Daniel P. Berrange <berrange@redhat.com>
  *
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
+#include "qemu/sockets.h"
+#include "qemu/main-loop.h"
 #include "migration/migration.h"
-#include "io/channel-command.h"
-#include "trace.h"
+#include "migration/qemu-file.h"
+#include "block/block.h"
+#include <sys/wait.h>
 
+//#define DEBUG_MIGRATION_EXEC
+
+#ifdef DEBUG_MIGRATION_EXEC
+#define DPRINTF(fmt, ...) \
+    do { printf("migration-exec: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+    do { } while (0)
+#endif
 
 void exec_start_outgoing_migration(MigrationState *s, const char *command, Error **errp)
 {
-    QIOChannel *ioc;
-    const char *argv[] = { "/bin/sh", "-c", command, NULL };
-
-    trace_migration_exec_outgoing(command);
-    ioc = QIO_CHANNEL(qio_channel_command_new_spawn(argv,
-                                                    O_WRONLY,
-                                                    errp));
-    if (!ioc) {
+    s->to_dst_file = qemu_popen_cmd(command, "w");
+    if (s->to_dst_file == NULL) {
+        error_setg_errno(errp, errno, "failed to popen the migration target");
         return;
     }
 
-    migration_channel_connect(s, ioc, NULL);
-    object_unref(OBJECT(ioc));
+    migrate_fd_connect(s);
 }
 
-static gboolean exec_accept_incoming_migration(QIOChannel *ioc,
-                                               GIOCondition condition,
-                                               gpointer opaque)
+static void exec_accept_incoming_migration(void *opaque)
 {
-    migration_channel_process_incoming(migrate_get_current(), ioc);
-    object_unref(OBJECT(ioc));
-    return FALSE; /* unregister */
+    QEMUFile *f = opaque;
+
+    qemu_set_fd_handler(qemu_get_fd(f), NULL, NULL, NULL);
+    process_incoming_migration(f);
 }
 
 void exec_start_incoming_migration(const char *command, Error **errp)
 {
-    QIOChannel *ioc;
-    const char *argv[] = { "/bin/sh", "-c", command, NULL };
+    QEMUFile *f;
 
-    trace_migration_exec_incoming(command);
-    ioc = QIO_CHANNEL(qio_channel_command_new_spawn(argv,
-                                                    O_RDONLY,
-                                                    errp));
-    if (!ioc) {
+    DPRINTF("Attempting to start an incoming migration\n");
+    f = qemu_popen_cmd(command, "r");
+    if(f == NULL) {
+        error_setg_errno(errp, errno, "failed to popen the migration source");
         return;
     }
 
-    qio_channel_add_watch(ioc,
-                          G_IO_IN,
-                          exec_accept_incoming_migration,
-                          NULL,
-                          NULL);
+    qemu_set_fd_handler(qemu_get_fd(f), exec_accept_incoming_migration, NULL,
+                        f);
 }
index 84a10fd..3d788bb 100644 (file)
@@ -1,11 +1,10 @@
 /*
  * QEMU live migration via generic fd
  *
- * Copyright Red Hat, Inc. 2009-2016
+ * Copyright Red Hat, Inc. 2009
  *
  * Authors:
  *  Chris Lalancette <clalance@redhat.com>
- *  Daniel P. Berrange <berrange@redhat.com>
  *
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
+#include "qemu/main-loop.h"
+#include "qemu/sockets.h"
 #include "migration/migration.h"
 #include "monitor/monitor.h"
-#include "io/channel-util.h"
-#include "trace.h"
+#include "migration/qemu-file.h"
+#include "block/block.h"
 
+//#define DEBUG_MIGRATION_FD
+
+#ifdef DEBUG_MIGRATION_FD
+#define DPRINTF(fmt, ...) \
+    do { printf("migration-fd: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+    do { } while (0)
+#endif
+
+static bool fd_is_socket(int fd)
+{
+    struct stat stat;
+    int ret = fstat(fd, &stat);
+    if (ret == -1) {
+        /* When in doubt say no */
+        return false;
+    }
+    return S_ISSOCK(stat.st_mode);
+}
 
 void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp)
 {
-    QIOChannel *ioc;
     int fd = monitor_get_fd(cur_mon, fdname, errp);
     if (fd == -1) {
         return;
     }
 
-    trace_migration_fd_outgoing(fd);
-    ioc = qio_channel_new_fd(fd, errp);
-    if (!ioc) {
-        close(fd);
-        return;
+    if (fd_is_socket(fd)) {
+        s->to_dst_file = qemu_fopen_socket(fd, "wb");
+    } else {
+        s->to_dst_file = qemu_fdopen(fd, "wb");
     }
 
-    migration_channel_connect(s, ioc, NULL);
-    object_unref(OBJECT(ioc));
+    migrate_fd_connect(s);
 }
 
-static gboolean fd_accept_incoming_migration(QIOChannel *ioc,
-                                             GIOCondition condition,
-                                             gpointer opaque)
+static void fd_accept_incoming_migration(void *opaque)
 {
-    migration_channel_process_incoming(migrate_get_current(), ioc);
-    object_unref(OBJECT(ioc));
-    return FALSE; /* unregister */
+    QEMUFile *f = opaque;
+
+    qemu_set_fd_handler(qemu_get_fd(f), NULL, NULL, NULL);
+    process_incoming_migration(f);
 }
 
 void fd_start_incoming_migration(const char *infd, Error **errp)
 {
-    QIOChannel *ioc;
     int fd;
+    QEMUFile *f;
 
-    fd = strtol(infd, NULL, 0);
-    trace_migration_fd_incoming(fd);
+    DPRINTF("Attempting to start an incoming migration via fd\n");
 
-    ioc = qio_channel_new_fd(fd, errp);
-    if (!ioc) {
-        close(fd);
+    fd = strtol(infd, NULL, 0);
+    if (fd_is_socket(fd)) {
+        f = qemu_fopen_socket(fd, "rb");
+    } else {
+        f = qemu_fdopen(fd, "rb");
+    }
+    if(f == NULL) {
+        error_setg_errno(errp, errno, "failed to open the source descriptor");
         return;
     }
 
-    qio_channel_add_watch(ioc,
-                          G_IO_IN,
-                          fd_accept_incoming_migration,
-                          NULL,
-                          NULL);
+    qemu_set_fd_handler(fd, fd_accept_incoming_migration, NULL, f);
 }
index 955d5ee..4369e27 100644 (file)
@@ -34,8 +34,6 @@
 #include "qom/cpu.h"
 #include "exec/memory.h"
 #include "exec/address-spaces.h"
-#include "io/channel-buffer.h"
-#include "io/channel-tls.h"
 
 #define MAX_THROTTLE  (32 << 20)      /* Migration transfer speed throttling */
 
@@ -52,8 +50,8 @@
 /*0: means nocompress, 1: best speed, ... 9: best compress ratio */
 #define DEFAULT_MIGRATE_COMPRESS_LEVEL 1
 /* Define default autoconverge cpu throttle migration parameters */
-#define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20
-#define DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT 10
+#define DEFAULT_MIGRATE_X_CPU_THROTTLE_INITIAL 20
+#define DEFAULT_MIGRATE_X_CPU_THROTTLE_INCREMENT 10
 
 /* Migration XBZRLE default cache size */
 #define DEFAULT_MIGRATE_CACHE_SIZE (64 * 1024 * 1024)
@@ -83,13 +81,16 @@ MigrationState *migrate_get_current(void)
         .bandwidth_limit = MAX_THROTTLE,
         .xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE,
         .mbps = -1,
-        .parameters = {
-            .compress_level = DEFAULT_MIGRATE_COMPRESS_LEVEL,
-            .compress_threads = DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT,
-            .decompress_threads = DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT,
-            .cpu_throttle_initial = DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL,
-            .cpu_throttle_increment = DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT,
-        },
+        .parameters[MIGRATION_PARAMETER_COMPRESS_LEVEL] =
+                DEFAULT_MIGRATE_COMPRESS_LEVEL,
+        .parameters[MIGRATION_PARAMETER_COMPRESS_THREADS] =
+                DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT,
+        .parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS] =
+                DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT,
+        .parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL] =
+                DEFAULT_MIGRATE_X_CPU_THROTTLE_INITIAL,
+        .parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT] =
+                DEFAULT_MIGRATE_X_CPU_THROTTLE_INCREMENT,
     };
 
     if (!once) {
@@ -309,12 +310,14 @@ void qemu_start_incoming_migration(const char *uri, Error **errp)
     } else if (strstart(uri, "rdma:", &p)) {
         rdma_start_incoming_migration(p, errp);
 #endif
+#if !defined(WIN32)
     } else if (strstart(uri, "exec:", &p)) {
         exec_start_incoming_migration(p, errp);
     } else if (strstart(uri, "unix:", &p)) {
         unix_start_incoming_migration(p, errp);
     } else if (strstart(uri, "fd:", &p)) {
         fd_start_incoming_migration(p, errp);
+#endif
     } else {
         error_setg(errp, "unknown migration protocol: %s", uri);
     }
@@ -416,63 +419,17 @@ static void process_incoming_migration_co(void *opaque)
     qemu_bh_schedule(mis->bh);
 }
 
-void migration_fd_process_incoming(QEMUFile *f)
+void process_incoming_migration(QEMUFile *f)
 {
-    Coroutine *co = qemu_coroutine_create(process_incoming_migration_co, f);
+    Coroutine *co = qemu_coroutine_create(process_incoming_migration_co);
+    int fd = qemu_get_fd(f);
 
+    assert(fd != -1);
     migrate_decompress_threads_create();
-    qemu_file_set_blocking(f, false);
-    qemu_coroutine_enter(co);
-}
-
-
-void migration_channel_process_incoming(MigrationState *s,
-                                        QIOChannel *ioc)
-{
-    trace_migration_set_incoming_channel(
-        ioc, object_get_typename(OBJECT(ioc)));
-
-    if (s->parameters.tls_creds &&
-        !object_dynamic_cast(OBJECT(ioc),
-                             TYPE_QIO_CHANNEL_TLS)) {
-        Error *local_err = NULL;
-        migration_tls_channel_process_incoming(s, ioc, &local_err);
-        if (local_err) {
-            error_report_err(local_err);
-        }
-    } else {
-        QEMUFile *f = qemu_fopen_channel_input(ioc);
-        migration_fd_process_incoming(f);
-    }
-}
-
-
-void migration_channel_connect(MigrationState *s,
-                               QIOChannel *ioc,
-                               const char *hostname)
-{
-    trace_migration_set_outgoing_channel(
-        ioc, object_get_typename(OBJECT(ioc)), hostname);
-
-    if (s->parameters.tls_creds &&
-        !object_dynamic_cast(OBJECT(ioc),
-                             TYPE_QIO_CHANNEL_TLS)) {
-        Error *local_err = NULL;
-        migration_tls_channel_connect(s, ioc, hostname, &local_err);
-        if (local_err) {
-            migrate_fd_error(s, local_err);
-            error_free(local_err);
-        }
-    } else {
-        QEMUFile *f = qemu_fopen_channel_output(ioc);
-
-        s->to_dst_file = f;
-
-        migrate_fd_connect(s);
-    }
+    qemu_set_nonblock(fd);
+    qemu_coroutine_enter(co, f);
 }
 
-
 /*
  * Send a message on the return channel back to the source
  * of the migration.
@@ -559,13 +516,15 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
     MigrationState *s = migrate_get_current();
 
     params = g_malloc0(sizeof(*params));
-    params->compress_level = s->parameters.compress_level;
-    params->compress_threads = s->parameters.compress_threads;
-    params->decompress_threads = s->parameters.decompress_threads;
-    params->cpu_throttle_initial = s->parameters.cpu_throttle_initial;
-    params->cpu_throttle_increment = s->parameters.cpu_throttle_increment;
-    params->tls_creds = g_strdup(s->parameters.tls_creds);
-    params->tls_hostname = g_strdup(s->parameters.tls_hostname);
+    params->compress_level = s->parameters[MIGRATION_PARAMETER_COMPRESS_LEVEL];
+    params->compress_threads =
+            s->parameters[MIGRATION_PARAMETER_COMPRESS_THREADS];
+    params->decompress_threads =
+            s->parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS];
+    params->x_cpu_throttle_initial =
+            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL];
+    params->x_cpu_throttle_increment =
+            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT];
 
     return params;
 }
@@ -602,26 +561,6 @@ static void get_xbzrle_cache_stats(MigrationInfo *info)
     }
 }
 
-static void populate_ram_info(MigrationInfo *info, MigrationState *s)
-{
-    info->has_ram = true;
-    info->ram = g_malloc0(sizeof(*info->ram));
-    info->ram->transferred = ram_bytes_transferred();
-    info->ram->total = ram_bytes_total();
-    info->ram->duplicate = dup_mig_pages_transferred();
-    info->ram->skipped = skipped_mig_pages_transferred();
-    info->ram->normal = norm_mig_pages_transferred();
-    info->ram->normal_bytes = norm_mig_bytes_transferred();
-    info->ram->mbps = s->mbps;
-    info->ram->dirty_sync_count = s->dirty_sync_count;
-    info->ram->postcopy_requests = s->postcopy_requests;
-
-    if (s->state != MIGRATION_STATUS_COMPLETED) {
-        info->ram->remaining = ram_bytes_remaining();
-        info->ram->dirty_pages_rate = s->dirty_pages_rate;
-    }
-}
-
 MigrationInfo *qmp_query_migrate(Error **errp)
 {
     MigrationInfo *info = g_malloc0(sizeof(*info));
@@ -646,7 +585,18 @@ MigrationInfo *qmp_query_migrate(Error **errp)
         info->has_setup_time = true;
         info->setup_time = s->setup_time;
 
-        populate_ram_info(info, s);
+        info->has_ram = true;
+        info->ram = g_malloc0(sizeof(*info->ram));
+        info->ram->transferred = ram_bytes_transferred();
+        info->ram->remaining = ram_bytes_remaining();
+        info->ram->total = ram_bytes_total();
+        info->ram->duplicate = dup_mig_pages_transferred();
+        info->ram->skipped = skipped_mig_pages_transferred();
+        info->ram->normal = norm_mig_pages_transferred();
+        info->ram->normal_bytes = norm_mig_bytes_transferred();
+        info->ram->dirty_pages_rate = s->dirty_pages_rate;
+        info->ram->mbps = s->mbps;
+        info->ram->dirty_sync_count = s->dirty_sync_count;
 
         if (blk_mig_active()) {
             info->has_disk = true;
@@ -657,8 +607,8 @@ MigrationInfo *qmp_query_migrate(Error **errp)
         }
 
         if (cpu_throttle_active()) {
-            info->has_cpu_throttle_percentage = true;
-            info->cpu_throttle_percentage = cpu_throttle_get_percentage();
+            info->has_x_cpu_throttle_percentage = true;
+            info->x_cpu_throttle_percentage = cpu_throttle_get_percentage();
         }
 
         get_xbzrle_cache_stats(info);
@@ -674,7 +624,18 @@ MigrationInfo *qmp_query_migrate(Error **errp)
         info->has_setup_time = true;
         info->setup_time = s->setup_time;
 
-        populate_ram_info(info, s);
+        info->has_ram = true;
+        info->ram = g_malloc0(sizeof(*info->ram));
+        info->ram->transferred = ram_bytes_transferred();
+        info->ram->remaining = ram_bytes_remaining();
+        info->ram->total = ram_bytes_total();
+        info->ram->duplicate = dup_mig_pages_transferred();
+        info->ram->skipped = skipped_mig_pages_transferred();
+        info->ram->normal = norm_mig_pages_transferred();
+        info->ram->normal_bytes = norm_mig_bytes_transferred();
+        info->ram->dirty_pages_rate = s->dirty_pages_rate;
+        info->ram->mbps = s->mbps;
+        info->ram->dirty_sync_count = s->dirty_sync_count;
 
         if (blk_mig_active()) {
             info->has_disk = true;
@@ -697,14 +658,20 @@ MigrationInfo *qmp_query_migrate(Error **errp)
         info->has_setup_time = true;
         info->setup_time = s->setup_time;
 
-        populate_ram_info(info, s);
+        info->has_ram = true;
+        info->ram = g_malloc0(sizeof(*info->ram));
+        info->ram->transferred = ram_bytes_transferred();
+        info->ram->remaining = 0;
+        info->ram->total = ram_bytes_total();
+        info->ram->duplicate = dup_mig_pages_transferred();
+        info->ram->skipped = skipped_mig_pages_transferred();
+        info->ram->normal = norm_mig_pages_transferred();
+        info->ram->normal_bytes = norm_mig_bytes_transferred();
+        info->ram->mbps = s->mbps;
+        info->ram->dirty_sync_count = s->dirty_sync_count;
         break;
     case MIGRATION_STATUS_FAILED:
         info->has_status = true;
-        if (s->error) {
-            info->has_error_desc = true;
-            info->error_desc = g_strdup(error_get_pretty(s->error));
-        }
         break;
     case MIGRATION_STATUS_CANCELLED:
         info->has_status = true;
@@ -720,7 +687,6 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
 {
     MigrationState *s = migrate_get_current();
     MigrationCapabilityStatusList *cap;
-    bool old_postcopy_cap = migrate_postcopy_ram();
 
     if (migration_is_setup_or_active(s->state)) {
         error_setg(errp, QERR_MIGRATION_ACTIVE);
@@ -743,19 +709,6 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
             s->enabled_capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM] =
                 false;
         }
-        /* This check is reasonably expensive, so only when it's being
-         * set the first time, also it's only the destination that needs
-         * special support.
-         */
-        if (!old_postcopy_cap && runstate_check(RUN_STATE_INMIGRATE) &&
-            !postcopy_ram_supported_by_host()) {
-            /* postcopy_ram_supported_by_host will have emitted a more
-             * detailed message
-             */
-            error_report("Postcopy is not supported");
-            s->enabled_capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM] =
-                false;
-        }
     }
 }
 
@@ -765,15 +718,10 @@ void qmp_migrate_set_parameters(bool has_compress_level,
                                 int64_t compress_threads,
                                 bool has_decompress_threads,
                                 int64_t decompress_threads,
-                                bool has_cpu_throttle_initial,
-                                int64_t cpu_throttle_initial,
-                                bool has_cpu_throttle_increment,
-                                int64_t cpu_throttle_increment,
-                                bool has_tls_creds,
-                                const char *tls_creds,
-                                bool has_tls_hostname,
-                                const char *tls_hostname,
-                                Error **errp)
+                                bool has_x_cpu_throttle_initial,
+                                int64_t x_cpu_throttle_initial,
+                                bool has_x_cpu_throttle_increment,
+                                int64_t x_cpu_throttle_increment, Error **errp)
 {
     MigrationState *s = migrate_get_current();
 
@@ -796,45 +744,40 @@ void qmp_migrate_set_parameters(bool has_compress_level,
                    "is invalid, it should be in the range of 1 to 255");
         return;
     }
-    if (has_cpu_throttle_initial &&
-            (cpu_throttle_initial < 1 || cpu_throttle_initial > 99)) {
+    if (has_x_cpu_throttle_initial &&
+            (x_cpu_throttle_initial < 1 || x_cpu_throttle_initial > 99)) {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-                   "cpu_throttle_initial",
+                   "x_cpu_throttle_initial",
                    "an integer in the range of 1 to 99");
     }
-    if (has_cpu_throttle_increment &&
-            (cpu_throttle_increment < 1 || cpu_throttle_increment > 99)) {
+    if (has_x_cpu_throttle_increment &&
+            (x_cpu_throttle_increment < 1 || x_cpu_throttle_increment > 99)) {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-                   "cpu_throttle_increment",
+                   "x_cpu_throttle_increment",
                    "an integer in the range of 1 to 99");
     }
 
     if (has_compress_level) {
-        s->parameters.compress_level = compress_level;
+        s->parameters[MIGRATION_PARAMETER_COMPRESS_LEVEL] = compress_level;
     }
     if (has_compress_threads) {
-        s->parameters.compress_threads = compress_threads;
+        s->parameters[MIGRATION_PARAMETER_COMPRESS_THREADS] = compress_threads;
     }
     if (has_decompress_threads) {
-        s->parameters.decompress_threads = decompress_threads;
-    }
-    if (has_cpu_throttle_initial) {
-        s->parameters.cpu_throttle_initial = cpu_throttle_initial;
+        s->parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS] =
+                                                    decompress_threads;
     }
-    if (has_cpu_throttle_increment) {
-        s->parameters.cpu_throttle_increment = cpu_throttle_increment;
+    if (has_x_cpu_throttle_initial) {
+        s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL] =
+                                                    x_cpu_throttle_initial;
     }
-    if (has_tls_creds) {
-        g_free(s->parameters.tls_creds);
-        s->parameters.tls_creds = g_strdup(tls_creds);
-    }
-    if (has_tls_hostname) {
-        g_free(s->parameters.tls_hostname);
-        s->parameters.tls_hostname = g_strdup(tls_hostname);
+
+    if (has_x_cpu_throttle_increment) {
+        s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT] =
+                                                    x_cpu_throttle_increment;
     }
 }
 
-
 void qmp_migrate_start_postcopy(Error **errp)
 {
     MigrationState *s = migrate_get_current();
@@ -901,15 +844,12 @@ static void migrate_fd_cleanup(void *opaque)
     notifier_list_notify(&migration_state_notifiers, s);
 }
 
-void migrate_fd_error(MigrationState *s, const Error *error)
+void migrate_fd_error(MigrationState *s)
 {
-    trace_migrate_fd_error(error ? error_get_pretty(error) : "");
+    trace_migrate_fd_error();
     assert(s->to_dst_file == NULL);
     migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
                       MIGRATION_STATUS_FAILED);
-    if (!s->error) {
-        s->error = error_copy(error);
-    }
     notifier_list_notify(&migration_state_notifiers, s);
 }
 
@@ -1006,11 +946,8 @@ MigrationState *migrate_init(const MigrationParams *params)
     s->dirty_sync_count = 0;
     s->start_postcopy = false;
     s->postcopy_after_devices = false;
-    s->postcopy_requests = 0;
     s->migration_thread_running = false;
     s->last_req_rb = NULL;
-    error_free(s->error);
-    s->error = NULL;
 
     migrate_set_state(&s->state, MIGRATION_STATUS_NONE, MIGRATION_STATUS_SETUP);
 
@@ -1103,12 +1040,14 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
     } else if (strstart(uri, "rdma:", &p)) {
         rdma_start_outgoing_migration(s, p, &local_err);
 #endif
+#if !defined(WIN32)
     } else if (strstart(uri, "exec:", &p)) {
         exec_start_outgoing_migration(s, p, &local_err);
     } else if (strstart(uri, "unix:", &p)) {
         unix_start_outgoing_migration(s, p, &local_err);
     } else if (strstart(uri, "fd:", &p)) {
         fd_start_outgoing_migration(s, p, &local_err);
+#endif
     } else {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "uri",
                    "a valid migration protocol");
@@ -1118,7 +1057,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
     }
 
     if (local_err) {
-        migrate_fd_error(s, local_err);
+        migrate_fd_error(s);
         error_propagate(errp, local_err);
         return;
     }
@@ -1231,7 +1170,7 @@ int migrate_compress_level(void)
 
     s = migrate_get_current();
 
-    return s->parameters.compress_level;
+    return s->parameters[MIGRATION_PARAMETER_COMPRESS_LEVEL];
 }
 
 int migrate_compress_threads(void)
@@ -1240,7 +1179,7 @@ int migrate_compress_threads(void)
 
     s = migrate_get_current();
 
-    return s->parameters.compress_threads;
+    return s->parameters[MIGRATION_PARAMETER_COMPRESS_THREADS];
 }
 
 int migrate_decompress_threads(void)
@@ -1249,7 +1188,7 @@ int migrate_decompress_threads(void)
 
     s = migrate_get_current();
 
-    return s->parameters.decompress_threads;
+    return s->parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS];
 }
 
 bool migrate_use_events(void)
@@ -1384,7 +1323,7 @@ static void *source_return_path_thread(void *opaque)
         /* OK, we have the message and the data */
         switch (header_type) {
         case MIG_RP_MSG_SHUT:
-            sibling_error = ldl_be_p(buf);
+            sibling_error = be32_to_cpup((uint32_t *)buf);
             trace_source_return_path_thread_shut(sibling_error);
             if (sibling_error) {
                 error_report("RP: Sibling indicated error %d", sibling_error);
@@ -1398,13 +1337,13 @@ static void *source_return_path_thread(void *opaque)
             goto out;
 
         case MIG_RP_MSG_PONG:
-            tmp32 = ldl_be_p(buf);
+            tmp32 = be32_to_cpup((uint32_t *)buf);
             trace_source_return_path_thread_pong(tmp32);
             break;
 
         case MIG_RP_MSG_REQ_PAGES:
-            start = ldq_be_p(buf);
-            len = ldl_be_p(buf + 8);
+            start = be64_to_cpup((uint64_t *)buf);
+            len = be32_to_cpup((uint32_t *)(buf + 8));
             migrate_handle_rp_req_pages(ms, NULL, start, len);
             break;
 
@@ -1412,8 +1351,8 @@ static void *source_return_path_thread(void *opaque)
             expected_len = 12 + 1; /* header + termination */
 
             if (header_len >= expected_len) {
-                start = ldq_be_p(buf);
-                len = ldl_be_p(buf + 8);
+                start = be64_to_cpup((uint64_t *)buf);
+                len = be32_to_cpup((uint32_t *)(buf + 8));
                 /* Now we expect an idstr */
                 tmp32 = buf[12]; /* Length of the following idstr */
                 buf[13 + tmp32] = '\0';
@@ -1490,8 +1429,7 @@ static int await_return_path_close_on_source(MigrationState *ms)
 static int postcopy_start(MigrationState *ms, bool *old_vm_running)
 {
     int ret;
-    QIOChannelBuffer *bioc;
-    QEMUFile *fb;
+    const QEMUSizedBuffer *qsb;
     int64_t time_at_stop = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
     migrate_set_state(&ms->state, MIGRATION_STATUS_ACTIVE,
                       MIGRATION_STATUS_POSTCOPY_ACTIVE);
@@ -1550,9 +1488,11 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running)
      * So we wrap the device state up in a package with a length at the start;
      * to do this we use a qemu_buf to hold the whole of the device state.
      */
-    bioc = qio_channel_buffer_new(4096);
-    fb = qemu_fopen_channel_output(QIO_CHANNEL(bioc));
-    object_unref(OBJECT(bioc));
+    QEMUFile *fb = qemu_bufopen("w", NULL);
+    if (!fb) {
+        error_report("Failed to create buffered file");
+        goto fail;
+    }
 
     /*
      * Make sure the receiver can get incoming pages before we send the rest
@@ -1566,9 +1506,10 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running)
     qemu_savevm_send_postcopy_run(fb);
 
     /* <><> end of stuff going into the package */
+    qsb = qemu_buf_get(fb);
 
     /* Now send that blob */
-    if (qemu_savevm_send_packaged(ms->to_dst_file, bioc->data, bioc->usage)) {
+    if (qemu_savevm_send_packaged(ms->to_dst_file, qsb)) {
         goto fail_closefb;
     }
     qemu_fclose(fb);
@@ -1837,10 +1778,6 @@ static void *migration_thread(void *opaque)
     } else {
         if (old_vm_running && !entered_postcopy) {
             vm_start();
-        } else {
-            if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
-                runstate_set(RUN_STATE_POSTMIGRATE);
-            }
         }
     }
     qemu_bh_schedule(s->cleanup_bh);
@@ -1856,7 +1793,6 @@ void migrate_fd_connect(MigrationState *s)
     s->expected_downtime = max_downtime/1000000;
     s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s);
 
-    qemu_file_set_blocking(s->to_dst_file, true);
     qemu_file_set_rate_limit(s->to_dst_file,
                              s->bandwidth_limit / XFER_LIMIT_RATIO);
 
index 9b04778..fbd0064 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu-common.h"
 #include "migration/migration.h"
@@ -51,6 +52,7 @@ struct PostcopyDiscardState {
 #if defined(__linux__)
 
 #include <poll.h>
+#include <sys/mman.h>
 #include <sys/ioctl.h>
 #include <sys/syscall.h>
 #include <asm/types.h> /* for __u64 */
@@ -405,6 +407,7 @@ static void *postcopy_ram_fault_thread(void *opaque)
 
     while (true) {
         ram_addr_t rb_offset;
+        ram_addr_t in_raspace;
         struct pollfd pfd[2];
 
         /*
@@ -456,7 +459,7 @@ static void *postcopy_ram_fault_thread(void *opaque)
 
         rb = qemu_ram_block_from_host(
                  (void *)(uintptr_t)msg.arg.pagefault.address,
-                 true, &rb_offset);
+                 true, &in_raspace, &rb_offset);
         if (!rb) {
             error_report("postcopy_ram_fault_thread: Fault outside guest: %"
                          PRIx64, (uint64_t)msg.arg.pagefault.address);
@@ -604,8 +607,7 @@ void *postcopy_get_tmp_page(MigrationIncomingState *mis)
         mis->postcopy_tmp_page = mmap(NULL, getpagesize(),
                              PROT_READ | PROT_WRITE, MAP_PRIVATE |
                              MAP_ANONYMOUS, -1, 0);
-        if (mis->postcopy_tmp_page == MAP_FAILED) {
-            mis->postcopy_tmp_page = NULL;
+        if (!mis->postcopy_tmp_page) {
             error_report("%s: %s", __func__, strerror(errno));
             return NULL;
         }
diff --git a/migration/qemu-file-buf.c b/migration/qemu-file-buf.c
new file mode 100644 (file)
index 0000000..7b8e78e
--- /dev/null
@@ -0,0 +1,464 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * Authors:
+ *  Stefan Berger <stefanb@linux.vnet.ibm.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "qemu/iov.h"
+#include "qemu/sockets.h"
+#include "qemu/coroutine.h"
+#include "migration/migration.h"
+#include "migration/qemu-file.h"
+#include "migration/qemu-file-internal.h"
+#include "trace.h"
+
+#define QSB_CHUNK_SIZE      (1 << 10)
+#define QSB_MAX_CHUNK_SIZE  (16 * QSB_CHUNK_SIZE)
+
+/**
+ * Create a QEMUSizedBuffer
+ * This type of buffer uses scatter-gather lists internally and
+ * can grow to any size. Any data array in the scatter-gather list
+ * can hold different amount of bytes.
+ *
+ * @buffer: Optional buffer to copy into the QSB
+ * @len: size of initial buffer; if @buffer is given, buffer must
+ *       hold at least len bytes
+ *
+ * Returns a pointer to a QEMUSizedBuffer or NULL on allocation failure
+ */
+QEMUSizedBuffer *qsb_create(const uint8_t *buffer, size_t len)
+{
+    QEMUSizedBuffer *qsb;
+    size_t alloc_len, num_chunks, i, to_copy;
+    size_t chunk_size = (len > QSB_MAX_CHUNK_SIZE)
+                        ? QSB_MAX_CHUNK_SIZE
+                        : QSB_CHUNK_SIZE;
+
+    num_chunks = DIV_ROUND_UP(len ? len : QSB_CHUNK_SIZE, chunk_size);
+    alloc_len = num_chunks * chunk_size;
+
+    qsb = g_try_new0(QEMUSizedBuffer, 1);
+    if (!qsb) {
+        return NULL;
+    }
+
+    qsb->iov = g_try_new0(struct iovec, num_chunks);
+    if (!qsb->iov) {
+        g_free(qsb);
+        return NULL;
+    }
+
+    qsb->n_iov = num_chunks;
+
+    for (i = 0; i < num_chunks; i++) {
+        qsb->iov[i].iov_base = g_try_malloc0(chunk_size);
+        if (!qsb->iov[i].iov_base) {
+            /* qsb_free is safe since g_free can cope with NULL */
+            qsb_free(qsb);
+            return NULL;
+        }
+
+        qsb->iov[i].iov_len = chunk_size;
+        if (buffer) {
+            to_copy = (len - qsb->used) > chunk_size
+                      ? chunk_size : (len - qsb->used);
+            memcpy(qsb->iov[i].iov_base, &buffer[qsb->used], to_copy);
+            qsb->used += to_copy;
+        }
+    }
+
+    qsb->size = alloc_len;
+
+    return qsb;
+}
+
+/**
+ * Free the QEMUSizedBuffer
+ *
+ * @qsb: The QEMUSizedBuffer to free
+ */
+void qsb_free(QEMUSizedBuffer *qsb)
+{
+    size_t i;
+
+    if (!qsb) {
+        return;
+    }
+
+    for (i = 0; i < qsb->n_iov; i++) {
+        g_free(qsb->iov[i].iov_base);
+    }
+    g_free(qsb->iov);
+    g_free(qsb);
+}
+
+/**
+ * Get the number of used bytes in the QEMUSizedBuffer
+ *
+ * @qsb: A QEMUSizedBuffer
+ *
+ * Returns the number of bytes currently used in this buffer
+ */
+size_t qsb_get_length(const QEMUSizedBuffer *qsb)
+{
+    return qsb->used;
+}
+
+/**
+ * Set the length of the buffer; the primary usage of this
+ * function is to truncate the number of used bytes in the buffer.
+ * The size will not be extended beyond the current number of
+ * allocated bytes in the QEMUSizedBuffer.
+ *
+ * @qsb: A QEMUSizedBuffer
+ * @new_len: The new length of bytes in the buffer
+ *
+ * Returns the number of bytes the buffer was truncated or extended
+ * to.
+ */
+size_t qsb_set_length(QEMUSizedBuffer *qsb, size_t new_len)
+{
+    if (new_len <= qsb->size) {
+        qsb->used = new_len;
+    } else {
+        qsb->used = qsb->size;
+    }
+    return qsb->used;
+}
+
+/**
+ * Get the iovec that holds the data for a given position @pos.
+ *
+ * @qsb: A QEMUSizedBuffer
+ * @pos: The index of a byte in the buffer
+ * @d_off: Pointer to an offset that this function will indicate
+ *         at what position within the returned iovec the byte
+ *         is to be found
+ *
+ * Returns the index of the iovec that holds the byte at the given
+ * index @pos in the byte stream; a negative number if the iovec
+ * for the given position @pos does not exist.
+ */
+static ssize_t qsb_get_iovec(const QEMUSizedBuffer *qsb,
+                             off_t pos, off_t *d_off)
+{
+    ssize_t i;
+    off_t curr = 0;
+
+    if (pos > qsb->used) {
+        return -1;
+    }
+
+    for (i = 0; i < qsb->n_iov; i++) {
+        if (curr + qsb->iov[i].iov_len > pos) {
+            *d_off = pos - curr;
+            return i;
+        }
+        curr += qsb->iov[i].iov_len;
+    }
+    return -1;
+}
+
+/*
+ * Convert the QEMUSizedBuffer into a flat buffer.
+ *
+ * Note: If at all possible, try to avoid this function since it
+ *       may unnecessarily copy memory around.
+ *
+ * @qsb: pointer to QEMUSizedBuffer
+ * @start: offset to start at
+ * @count: number of bytes to copy
+ * @buf: a pointer to a buffer to write into (at least @count bytes)
+ *
+ * Returns the number of bytes copied into the output buffer
+ */
+ssize_t qsb_get_buffer(const QEMUSizedBuffer *qsb, off_t start,
+                       size_t count, uint8_t *buffer)
+{
+    const struct iovec *iov;
+    size_t to_copy, all_copy;
+    ssize_t index;
+    off_t s_off;
+    off_t d_off = 0;
+    char *s;
+
+    if (start > qsb->used) {
+        return 0;
+    }
+
+    all_copy = qsb->used - start;
+    if (all_copy > count) {
+        all_copy = count;
+    } else {
+        count = all_copy;
+    }
+
+    index = qsb_get_iovec(qsb, start, &s_off);
+    if (index < 0) {
+        return 0;
+    }
+
+    while (all_copy > 0) {
+        iov = &qsb->iov[index];
+
+        s = iov->iov_base;
+
+        to_copy = iov->iov_len - s_off;
+        if (to_copy > all_copy) {
+            to_copy = all_copy;
+        }
+        memcpy(&buffer[d_off], &s[s_off], to_copy);
+
+        d_off += to_copy;
+        all_copy -= to_copy;
+
+        s_off = 0;
+        index++;
+    }
+
+    return count;
+}
+
+/**
+ * Grow the QEMUSizedBuffer to the given size and allocate
+ * memory for it.
+ *
+ * @qsb: A QEMUSizedBuffer
+ * @new_size: The new size of the buffer
+ *
+ * Return:
+ *    a negative error code in case of memory allocation failure
+ * or
+ *    the new size of the buffer. The returned size may be greater or equal
+ *    to @new_size.
+ */
+static ssize_t qsb_grow(QEMUSizedBuffer *qsb, size_t new_size)
+{
+    size_t needed_chunks, i;
+
+    if (qsb->size < new_size) {
+        struct iovec *new_iov;
+        size_t size_diff = new_size - qsb->size;
+        size_t chunk_size = (size_diff > QSB_MAX_CHUNK_SIZE)
+                             ? QSB_MAX_CHUNK_SIZE : QSB_CHUNK_SIZE;
+
+        needed_chunks = DIV_ROUND_UP(size_diff, chunk_size);
+
+        new_iov = g_try_new(struct iovec, qsb->n_iov + needed_chunks);
+        if (new_iov == NULL) {
+            return -ENOMEM;
+        }
+
+        /* Allocate new chunks as needed into new_iov */
+        for (i = qsb->n_iov; i < qsb->n_iov + needed_chunks; i++) {
+            new_iov[i].iov_base = g_try_malloc0(chunk_size);
+            new_iov[i].iov_len = chunk_size;
+            if (!new_iov[i].iov_base) {
+                size_t j;
+
+                /* Free previously allocated new chunks */
+                for (j = qsb->n_iov; j < i; j++) {
+                    g_free(new_iov[j].iov_base);
+                }
+                g_free(new_iov);
+
+                return -ENOMEM;
+            }
+        }
+
+        /*
+         * Now we can't get any allocation errors, copy over to new iov
+         * and switch.
+         */
+        for (i = 0; i < qsb->n_iov; i++) {
+            new_iov[i] = qsb->iov[i];
+        }
+
+        qsb->n_iov += needed_chunks;
+        g_free(qsb->iov);
+        qsb->iov = new_iov;
+        qsb->size += (needed_chunks * chunk_size);
+    }
+
+    return qsb->size;
+}
+
+/**
+ * Write into the QEMUSizedBuffer at a given position and a given
+ * number of bytes. This function will automatically grow the
+ * QEMUSizedBuffer.
+ *
+ * @qsb: A QEMUSizedBuffer
+ * @source: A byte array to copy data from
+ * @pos: The position within the @qsb to write data to
+ * @size: The number of bytes to copy into the @qsb
+ *
+ * Returns @size or a negative error code in case of memory allocation failure,
+ *           or with an invalid 'pos'
+ */
+ssize_t qsb_write_at(QEMUSizedBuffer *qsb, const uint8_t *source,
+                     off_t pos, size_t count)
+{
+    ssize_t rc = qsb_grow(qsb, pos + count);
+    size_t to_copy;
+    size_t all_copy = count;
+    const struct iovec *iov;
+    ssize_t index;
+    char *dest;
+    off_t d_off, s_off = 0;
+
+    if (rc < 0) {
+        return rc;
+    }
+
+    if (pos + count > qsb->used) {
+        qsb->used = pos + count;
+    }
+
+    index = qsb_get_iovec(qsb, pos, &d_off);
+    if (index < 0) {
+        return -EINVAL;
+    }
+
+    while (all_copy > 0) {
+        iov = &qsb->iov[index];
+
+        dest = iov->iov_base;
+
+        to_copy = iov->iov_len - d_off;
+        if (to_copy > all_copy) {
+            to_copy = all_copy;
+        }
+
+        memcpy(&dest[d_off], &source[s_off], to_copy);
+
+        s_off += to_copy;
+        all_copy -= to_copy;
+
+        d_off = 0;
+        index++;
+    }
+
+    return count;
+}
+
+typedef struct QEMUBuffer {
+    QEMUSizedBuffer *qsb;
+    QEMUFile *file;
+    bool qsb_allocated;
+} QEMUBuffer;
+
+static ssize_t buf_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
+                              size_t size)
+{
+    QEMUBuffer *s = opaque;
+    ssize_t len = qsb_get_length(s->qsb) - pos;
+
+    if (len <= 0) {
+        return 0;
+    }
+
+    if (len > size) {
+        len = size;
+    }
+    return qsb_get_buffer(s->qsb, pos, len, buf);
+}
+
+static ssize_t buf_put_buffer(void *opaque, const uint8_t *buf,
+                              int64_t pos, size_t size)
+{
+    QEMUBuffer *s = opaque;
+
+    return qsb_write_at(s->qsb, buf, pos, size);
+}
+
+static int buf_close(void *opaque)
+{
+    QEMUBuffer *s = opaque;
+
+    if (s->qsb_allocated) {
+        qsb_free(s->qsb);
+    }
+
+    g_free(s);
+
+    return 0;
+}
+
+const QEMUSizedBuffer *qemu_buf_get(QEMUFile *f)
+{
+    QEMUBuffer *p;
+
+    qemu_fflush(f);
+
+    p = f->opaque;
+
+    return p->qsb;
+}
+
+static const QEMUFileOps buf_read_ops = {
+    .get_buffer = buf_get_buffer,
+    .close =      buf_close,
+};
+
+static const QEMUFileOps buf_write_ops = {
+    .put_buffer = buf_put_buffer,
+    .close =      buf_close,
+};
+
+QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer *input)
+{
+    QEMUBuffer *s;
+
+    if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') ||
+        mode[1] != '\0') {
+        error_report("qemu_bufopen: Argument validity check failed");
+        return NULL;
+    }
+
+    s = g_new0(QEMUBuffer, 1);
+    s->qsb = input;
+
+    if (s->qsb == NULL) {
+        s->qsb = qsb_create(NULL, 0);
+        s->qsb_allocated = true;
+    }
+    if (!s->qsb) {
+        g_free(s);
+        error_report("qemu_bufopen: qsb_create failed");
+        return NULL;
+    }
+
+
+    if (mode[0] == 'r') {
+        s->file = qemu_fopen_ops(s, &buf_read_ops);
+    } else {
+        s->file = qemu_fopen_ops(s, &buf_write_ops);
+    }
+    return s->file;
+}
diff --git a/migration/qemu-file-channel.c b/migration/qemu-file-channel.c
deleted file mode 100644 (file)
index 45c13f1..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * QEMUFile backend for QIOChannel objects
- *
- * Copyright (c) 2015-2016 Red Hat, Inc
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "migration/qemu-file.h"
-#include "io/channel-socket.h"
-#include "qemu/iov.h"
-
-
-static ssize_t channel_writev_buffer(void *opaque,
-                                     struct iovec *iov,
-                                     int iovcnt,
-                                     int64_t pos)
-{
-    QIOChannel *ioc = QIO_CHANNEL(opaque);
-    ssize_t done = 0;
-    struct iovec *local_iov = g_new(struct iovec, iovcnt);
-    struct iovec *local_iov_head = local_iov;
-    unsigned int nlocal_iov = iovcnt;
-
-    nlocal_iov = iov_copy(local_iov, nlocal_iov,
-                          iov, iovcnt,
-                          0, iov_size(iov, iovcnt));
-
-    while (nlocal_iov > 0) {
-        ssize_t len;
-        len = qio_channel_writev(ioc, local_iov, nlocal_iov, NULL);
-        if (len == QIO_CHANNEL_ERR_BLOCK) {
-            qio_channel_wait(ioc, G_IO_OUT);
-            continue;
-        }
-        if (len < 0) {
-            /* XXX handle Error objects */
-            done = -EIO;
-            goto cleanup;
-        }
-
-        iov_discard_front(&local_iov, &nlocal_iov, len);
-        done += len;
-    }
-
- cleanup:
-    g_free(local_iov_head);
-    return done;
-}
-
-
-static ssize_t channel_get_buffer(void *opaque,
-                                  uint8_t *buf,
-                                  int64_t pos,
-                                  size_t size)
-{
-    QIOChannel *ioc = QIO_CHANNEL(opaque);
-    ssize_t ret;
-
-    do {
-        ret = qio_channel_read(ioc, (char *)buf, size, NULL);
-        if (ret < 0) {
-            if (ret == QIO_CHANNEL_ERR_BLOCK) {
-                qio_channel_yield(ioc, G_IO_IN);
-            } else {
-                /* XXX handle Error * object */
-                return -EIO;
-            }
-        }
-    } while (ret == QIO_CHANNEL_ERR_BLOCK);
-
-    return ret;
-}
-
-
-static int channel_close(void *opaque)
-{
-    QIOChannel *ioc = QIO_CHANNEL(opaque);
-    qio_channel_close(ioc, NULL);
-    object_unref(OBJECT(ioc));
-    return 0;
-}
-
-
-static int channel_shutdown(void *opaque,
-                            bool rd,
-                            bool wr)
-{
-    QIOChannel *ioc = QIO_CHANNEL(opaque);
-
-    if (qio_channel_has_feature(ioc,
-                                QIO_CHANNEL_FEATURE_SHUTDOWN)) {
-        QIOChannelShutdown mode;
-        if (rd && wr) {
-            mode = QIO_CHANNEL_SHUTDOWN_BOTH;
-        } else if (rd) {
-            mode = QIO_CHANNEL_SHUTDOWN_READ;
-        } else {
-            mode = QIO_CHANNEL_SHUTDOWN_WRITE;
-        }
-        if (qio_channel_shutdown(ioc, mode, NULL) < 0) {
-            /* XXX handler Error * object */
-            return -EIO;
-        }
-    }
-    return 0;
-}
-
-
-static int channel_set_blocking(void *opaque,
-                                bool enabled)
-{
-    QIOChannel *ioc = QIO_CHANNEL(opaque);
-
-    if (qio_channel_set_blocking(ioc, enabled, NULL) < 0) {
-        return -1;
-    }
-    return 0;
-}
-
-static QEMUFile *channel_get_input_return_path(void *opaque)
-{
-    QIOChannel *ioc = QIO_CHANNEL(opaque);
-
-    return qemu_fopen_channel_output(ioc);
-}
-
-static QEMUFile *channel_get_output_return_path(void *opaque)
-{
-    QIOChannel *ioc = QIO_CHANNEL(opaque);
-
-    return qemu_fopen_channel_input(ioc);
-}
-
-static const QEMUFileOps channel_input_ops = {
-    .get_buffer = channel_get_buffer,
-    .close = channel_close,
-    .shut_down = channel_shutdown,
-    .set_blocking = channel_set_blocking,
-    .get_return_path = channel_get_input_return_path,
-};
-
-
-static const QEMUFileOps channel_output_ops = {
-    .writev_buffer = channel_writev_buffer,
-    .close = channel_close,
-    .shut_down = channel_shutdown,
-    .set_blocking = channel_set_blocking,
-    .get_return_path = channel_get_output_return_path,
-};
-
-
-QEMUFile *qemu_fopen_channel_input(QIOChannel *ioc)
-{
-    object_ref(OBJECT(ioc));
-    return qemu_fopen_ops(ioc, &channel_input_ops);
-}
-
-QEMUFile *qemu_fopen_channel_output(QIOChannel *ioc)
-{
-    object_ref(OBJECT(ioc));
-    return qemu_fopen_ops(ioc, &channel_output_ops);
-}
similarity index 53%
rename from include/hw/dma/xlnx-zynq-devcfg.h
rename to migration/qemu-file-internal.h
index d40e5c8..d95e853 100644 (file)
@@ -1,9 +1,7 @@
 /*
- * QEMU model of the Xilinx Devcfg Interface
+ * QEMU System Emulator
  *
- * (C) 2011 PetaLogix Pty Ltd
- * (C) 2014 Xilinx Inc.
- * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.com>
+ * Copyright (c) 2003-2008 Fabrice Bellard
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
  * THE SOFTWARE.
  */
 
-#ifndef XLNX_ZYNQ_DEVCFG_H
+#ifndef QEMU_FILE_INTERNAL_H
+#define QEMU_FILE_INTERNAL_H 1
 
-#include "hw/register.h"
-#include "hw/sysbus.h"
+#include "qemu-common.h"
+#include "qemu/iov.h"
 
-#define TYPE_XLNX_ZYNQ_DEVCFG "xlnx.ps7-dev-cfg"
+#define IO_BUF_SIZE 32768
+#define MAX_IOV_SIZE MIN(IOV_MAX, 64)
 
-#define XLNX_ZYNQ_DEVCFG(obj) \
-    OBJECT_CHECK(XlnxZynqDevcfg, (obj), TYPE_XLNX_ZYNQ_DEVCFG)
+struct QEMUFile {
+    const QEMUFileOps *ops;
+    void *opaque;
 
-#define XLNX_ZYNQ_DEVCFG_R_MAX 0x118
+    int64_t bytes_xfer;
+    int64_t xfer_limit;
 
-#define XLNX_ZYNQ_DEVCFG_DMA_CMD_FIFO_LEN 10
+    int64_t pos; /* start of buffer when writing, end of buffer
+                    when reading */
+    int buf_index;
+    int buf_size; /* 0 when writing */
+    uint8_t buf[IO_BUF_SIZE];
 
-typedef struct XlnxZynqDevcfgDMACmd {
-    uint32_t src_addr;
-    uint32_t dest_addr;
-    uint32_t src_len;
-    uint32_t dest_len;
-} XlnxZynqDevcfgDMACmd;
+    struct iovec iov[MAX_IOV_SIZE];
+    unsigned int iovcnt;
 
-typedef struct XlnxZynqDevcfg {
-    SysBusDevice parent_obj;
+    int last_error;
+};
 
-    MemoryRegion iomem;
-    qemu_irq irq;
-
-    XlnxZynqDevcfgDMACmd dma_cmd_fifo[XLNX_ZYNQ_DEVCFG_DMA_CMD_FIFO_LEN];
-    uint8_t dma_cmd_fifo_num;
-
-    uint32_t regs[XLNX_ZYNQ_DEVCFG_R_MAX];
-    RegisterInfo regs_info[XLNX_ZYNQ_DEVCFG_R_MAX];
-} XlnxZynqDevcfg;
-
-#define XLNX_ZYNQ_DEVCFG_H
 #endif
diff --git a/migration/qemu-file-stdio.c b/migration/qemu-file-stdio.c
new file mode 100644 (file)
index 0000000..f402e8f
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/coroutine.h"
+#include "migration/qemu-file.h"
+
+typedef struct QEMUFileStdio {
+    FILE *stdio_file;
+    QEMUFile *file;
+} QEMUFileStdio;
+
+static int stdio_get_fd(void *opaque)
+{
+    QEMUFileStdio *s = opaque;
+
+    return fileno(s->stdio_file);
+}
+
+static ssize_t stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos,
+                                size_t size)
+{
+    QEMUFileStdio *s = opaque;
+    size_t res;
+
+    res = fwrite(buf, 1, size, s->stdio_file);
+
+    if (res != size) {
+        return -errno;
+    }
+    return res;
+}
+
+static ssize_t stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
+                                size_t size)
+{
+    QEMUFileStdio *s = opaque;
+    FILE *fp = s->stdio_file;
+    ssize_t bytes;
+
+    for (;;) {
+        clearerr(fp);
+        bytes = fread(buf, 1, size, fp);
+        if (bytes != 0 || !ferror(fp)) {
+            break;
+        }
+        if (errno == EAGAIN) {
+            yield_until_fd_readable(fileno(fp));
+        } else if (errno != EINTR) {
+            break;
+        }
+    }
+    return bytes;
+}
+
+static int stdio_pclose(void *opaque)
+{
+    QEMUFileStdio *s = opaque;
+    int ret;
+    ret = pclose(s->stdio_file);
+    if (ret == -1) {
+        ret = -errno;
+    } else if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) {
+        /* close succeeded, but non-zero exit code: */
+        ret = -EIO; /* fake errno value */
+    }
+    g_free(s);
+    return ret;
+}
+
+static int stdio_fclose(void *opaque)
+{
+    QEMUFileStdio *s = opaque;
+    int ret = 0;
+
+    if (qemu_file_is_writable(s->file)) {
+        int fd = fileno(s->stdio_file);
+        struct stat st;
+
+        ret = fstat(fd, &st);
+        if (ret == 0 && S_ISREG(st.st_mode)) {
+            /*
+             * If the file handle is a regular file make sure the
+             * data is flushed to disk before signaling success.
+             */
+            ret = fsync(fd);
+            if (ret != 0) {
+                ret = -errno;
+                return ret;
+            }
+        }
+    }
+    if (fclose(s->stdio_file) == EOF) {
+        ret = -errno;
+    }
+    g_free(s);
+    return ret;
+}
+
+static const QEMUFileOps stdio_pipe_read_ops = {
+    .get_fd =     stdio_get_fd,
+    .get_buffer = stdio_get_buffer,
+    .close =      stdio_pclose
+};
+
+static const QEMUFileOps stdio_pipe_write_ops = {
+    .get_fd =     stdio_get_fd,
+    .put_buffer = stdio_put_buffer,
+    .close =      stdio_pclose
+};
+
+QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
+{
+    FILE *stdio_file;
+    QEMUFileStdio *s;
+
+    if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
+        fprintf(stderr, "qemu_popen: Argument validity check failed\n");
+        return NULL;
+    }
+
+    stdio_file = popen(command, mode);
+    if (stdio_file == NULL) {
+        return NULL;
+    }
+
+    s = g_new0(QEMUFileStdio, 1);
+
+    s->stdio_file = stdio_file;
+
+    if (mode[0] == 'r') {
+        s->file = qemu_fopen_ops(s, &stdio_pipe_read_ops);
+    } else {
+        s->file = qemu_fopen_ops(s, &stdio_pipe_write_ops);
+    }
+    return s->file;
+}
+
+static const QEMUFileOps stdio_file_read_ops = {
+    .get_fd =     stdio_get_fd,
+    .get_buffer = stdio_get_buffer,
+    .close =      stdio_fclose
+};
+
+static const QEMUFileOps stdio_file_write_ops = {
+    .get_fd =     stdio_get_fd,
+    .put_buffer = stdio_put_buffer,
+    .close =      stdio_fclose
+};
+
+QEMUFile *qemu_fopen(const char *filename, const char *mode)
+{
+    QEMUFileStdio *s;
+
+    if (qemu_file_mode_is_not_valid(mode)) {
+        return NULL;
+    }
+
+    s = g_new0(QEMUFileStdio, 1);
+
+    s->stdio_file = fopen(filename, mode);
+    if (!s->stdio_file) {
+        goto fail;
+    }
+
+    if (mode[0] == 'w') {
+        s->file = qemu_fopen_ops(s, &stdio_file_write_ops);
+    } else {
+        s->file = qemu_fopen_ops(s, &stdio_file_read_ops);
+    }
+    return s->file;
+fail:
+    g_free(s);
+    return NULL;
+}
diff --git a/migration/qemu-file-unix.c b/migration/qemu-file-unix.c
new file mode 100644 (file)
index 0000000..4474e18
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "qemu/iov.h"
+#include "qemu/sockets.h"
+#include "qemu/coroutine.h"
+#include "migration/qemu-file.h"
+#include "migration/qemu-file-internal.h"
+
+typedef struct QEMUFileSocket {
+    int fd;
+    QEMUFile *file;
+} QEMUFileSocket;
+
+static ssize_t socket_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
+                                    int64_t pos)
+{
+    QEMUFileSocket *s = opaque;
+    ssize_t len;
+    ssize_t size = iov_size(iov, iovcnt);
+    ssize_t offset = 0;
+    int     err;
+
+    while (size > 0) {
+        len = iov_send(s->fd, iov, iovcnt, offset, size);
+
+        if (len > 0) {
+            size -= len;
+            offset += len;
+        }
+
+        if (size > 0) {
+            if (errno != EAGAIN && errno != EWOULDBLOCK) {
+                error_report("socket_writev_buffer: Got err=%d for (%zu/%zu)",
+                             errno, (size_t)size, (size_t)len);
+                /*
+                 * If I've already sent some but only just got the error, I
+                 * could return the amount validly sent so far and wait for the
+                 * next call to report the error, but I'd rather flag the error
+                 * immediately.
+                 */
+                return -errno;
+            }
+
+            /* Emulate blocking */
+            GPollFD pfd;
+
+            pfd.fd = s->fd;
+            pfd.events = G_IO_OUT | G_IO_ERR;
+            pfd.revents = 0;
+            TFR(err = g_poll(&pfd, 1, -1 /* no timeout */));
+            /* Errors other than EINTR intentionally ignored */
+        }
+     }
+
+    return offset;
+}
+
+static int socket_get_fd(void *opaque)
+{
+    QEMUFileSocket *s = opaque;
+
+    return s->fd;
+}
+
+static ssize_t socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
+                                 size_t size)
+{
+    QEMUFileSocket *s = opaque;
+    ssize_t len;
+
+    for (;;) {
+        len = qemu_recv(s->fd, buf, size, 0);
+        if (len != -1) {
+            break;
+        }
+        if (errno == EAGAIN) {
+            yield_until_fd_readable(s->fd);
+        } else if (errno != EINTR) {
+            break;
+        }
+    }
+
+    if (len == -1) {
+        len = -errno;
+    }
+    return len;
+}
+
+static int socket_close(void *opaque)
+{
+    QEMUFileSocket *s = opaque;
+    closesocket(s->fd);
+    g_free(s);
+    return 0;
+}
+
+static int socket_shutdown(void *opaque, bool rd, bool wr)
+{
+    QEMUFileSocket *s = opaque;
+
+    if (shutdown(s->fd, rd ? (wr ? SHUT_RDWR : SHUT_RD) : SHUT_WR)) {
+        return -errno;
+    } else {
+        return 0;
+    }
+}
+
+static int socket_return_close(void *opaque)
+{
+    QEMUFileSocket *s = opaque;
+    /*
+     * Note: We don't close the socket, that should be done by the forward
+     * path.
+     */
+    g_free(s);
+    return 0;
+}
+
+static const QEMUFileOps socket_return_read_ops = {
+    .get_fd          = socket_get_fd,
+    .get_buffer      = socket_get_buffer,
+    .close           = socket_return_close,
+    .shut_down       = socket_shutdown,
+};
+
+static const QEMUFileOps socket_return_write_ops = {
+    .get_fd          = socket_get_fd,
+    .writev_buffer   = socket_writev_buffer,
+    .close           = socket_return_close,
+    .shut_down       = socket_shutdown,
+};
+
+/*
+ * Give a QEMUFile* off the same socket but data in the opposite
+ * direction.
+ */
+static QEMUFile *socket_get_return_path(void *opaque)
+{
+    QEMUFileSocket *forward = opaque;
+    QEMUFileSocket *reverse;
+
+    if (qemu_file_get_error(forward->file)) {
+        /* If the forward file is in error, don't try and open a return */
+        return NULL;
+    }
+
+    reverse = g_malloc0(sizeof(QEMUFileSocket));
+    reverse->fd = forward->fd;
+    /* I don't think there's a better way to tell which direction 'this' is */
+    if (forward->file->ops->get_buffer != NULL) {
+        /* being called from the read side, so we need to be able to write */
+        return qemu_fopen_ops(reverse, &socket_return_write_ops);
+    } else {
+        return qemu_fopen_ops(reverse, &socket_return_read_ops);
+    }
+}
+
+static ssize_t unix_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
+                                  int64_t pos)
+{
+    QEMUFileSocket *s = opaque;
+    ssize_t len, offset;
+    ssize_t size = iov_size(iov, iovcnt);
+    ssize_t total = 0;
+
+    assert(iovcnt > 0);
+    offset = 0;
+    while (size > 0) {
+        /* Find the next start position; skip all full-sized vector elements  */
+        while (offset >= iov[0].iov_len) {
+            offset -= iov[0].iov_len;
+            iov++, iovcnt--;
+        }
+
+        /* skip `offset' bytes from the (now) first element, undo it on exit */
+        assert(iovcnt > 0);
+        iov[0].iov_base += offset;
+        iov[0].iov_len -= offset;
+
+        do {
+            len = writev(s->fd, iov, iovcnt);
+        } while (len == -1 && errno == EINTR);
+        if (len == -1) {
+            return -errno;
+        }
+
+        /* Undo the changes above */
+        iov[0].iov_base -= offset;
+        iov[0].iov_len += offset;
+
+        /* Prepare for the next iteration */
+        offset += len;
+        total += len;
+        size -= len;
+    }
+
+    return total;
+}
+
+static ssize_t unix_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
+                              size_t size)
+{
+    QEMUFileSocket *s = opaque;
+    ssize_t len;
+
+    for (;;) {
+        len = read(s->fd, buf, size);
+        if (len != -1) {
+            break;
+        }
+        if (errno == EAGAIN) {
+            yield_until_fd_readable(s->fd);
+        } else if (errno != EINTR) {
+            break;
+        }
+    }
+
+    if (len == -1) {
+        len = -errno;
+    }
+    return len;
+}
+
+static int unix_close(void *opaque)
+{
+    QEMUFileSocket *s = opaque;
+    close(s->fd);
+    g_free(s);
+    return 0;
+}
+
+static const QEMUFileOps unix_read_ops = {
+    .get_fd =     socket_get_fd,
+    .get_buffer = unix_get_buffer,
+    .close =      unix_close
+};
+
+static const QEMUFileOps unix_write_ops = {
+    .get_fd =     socket_get_fd,
+    .writev_buffer = unix_writev_buffer,
+    .close =      unix_close
+};
+
+QEMUFile *qemu_fdopen(int fd, const char *mode)
+{
+    QEMUFileSocket *s;
+
+    if (mode == NULL ||
+        (mode[0] != 'r' && mode[0] != 'w') ||
+        mode[1] != 'b' || mode[2] != 0) {
+        fprintf(stderr, "qemu_fdopen: Argument validity check failed\n");
+        return NULL;
+    }
+
+    s = g_new0(QEMUFileSocket, 1);
+    s->fd = fd;
+
+    if (mode[0] == 'r') {
+        s->file = qemu_fopen_ops(s, &unix_read_ops);
+    } else {
+        s->file = qemu_fopen_ops(s, &unix_write_ops);
+    }
+    return s->file;
+}
+
+static const QEMUFileOps socket_read_ops = {
+    .get_fd          = socket_get_fd,
+    .get_buffer      = socket_get_buffer,
+    .close           = socket_close,
+    .shut_down       = socket_shutdown,
+    .get_return_path = socket_get_return_path
+};
+
+static const QEMUFileOps socket_write_ops = {
+    .get_fd          = socket_get_fd,
+    .writev_buffer   = socket_writev_buffer,
+    .close           = socket_close,
+    .shut_down       = socket_shutdown,
+    .get_return_path = socket_get_return_path
+};
+
+QEMUFile *qemu_fopen_socket(int fd, const char *mode)
+{
+    QEMUFileSocket *s;
+
+    if (qemu_file_mode_is_not_valid(mode)) {
+        return NULL;
+    }
+
+    s = g_new0(QEMUFileSocket, 1);
+    s->fd = fd;
+    if (mode[0] == 'w') {
+        qemu_set_block(s->fd);
+        s->file = qemu_fopen_ops(s, &socket_write_ops);
+    } else {
+        s->file = qemu_fopen_ops(s, &socket_read_ops);
+    }
+    return s->file;
+}
index e9fae31..6f4a129 100644 (file)
 #include "qemu/coroutine.h"
 #include "migration/migration.h"
 #include "migration/qemu-file.h"
+#include "migration/qemu-file-internal.h"
 #include "trace.h"
 
-#define IO_BUF_SIZE 32768
-#define MAX_IOV_SIZE MIN(IOV_MAX, 64)
-
-struct QEMUFile {
-    const QEMUFileOps *ops;
-    const QEMUFileHooks *hooks;
-    void *opaque;
-
-    int64_t bytes_xfer;
-    int64_t xfer_limit;
-
-    int64_t pos; /* start of buffer when writing, end of buffer
-                    when reading */
-    int buf_index;
-    int buf_size; /* 0 when writing */
-    uint8_t buf[IO_BUF_SIZE];
-
-    struct iovec iov[MAX_IOV_SIZE];
-    unsigned int iovcnt;
-
-    int last_error;
-};
-
 /*
  * Stop a file from being read/written - not all backing files can do this
  * typically only sockets can.
@@ -102,12 +80,6 @@ QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops)
     return f;
 }
 
-
-void qemu_file_set_hooks(QEMUFile *f, const QEMUFileHooks *hooks)
-{
-    f->hooks = hooks;
-}
-
 /*
  * Get last error for stream f
  *
@@ -129,49 +101,48 @@ void qemu_file_set_error(QEMUFile *f, int ret)
 
 bool qemu_file_is_writable(QEMUFile *f)
 {
-    return f->ops->writev_buffer;
+    return f->ops->writev_buffer || f->ops->put_buffer;
 }
 
 /**
  * Flushes QEMUFile buffer
  *
  * If there is writev_buffer QEMUFileOps it uses it otherwise uses
- * put_buffer ops. This will flush all pending data. If data was
- * only partially flushed, it will set an error state.
+ * put_buffer ops.
  */
 void qemu_fflush(QEMUFile *f)
 {
     ssize_t ret = 0;
-    ssize_t expect = 0;
 
     if (!qemu_file_is_writable(f)) {
         return;
     }
 
-    if (f->iovcnt > 0) {
-        expect = iov_size(f->iov, f->iovcnt);
-        ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, f->pos);
+    if (f->ops->writev_buffer) {
+        if (f->iovcnt > 0) {
+            ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, f->pos);
+        }
+    } else {
+        if (f->buf_index > 0) {
+            ret = f->ops->put_buffer(f->opaque, f->buf, f->pos, f->buf_index);
+        }
     }
-
     if (ret >= 0) {
         f->pos += ret;
     }
-    /* We expect the QEMUFile write impl to send the full
-     * data set we requested, so sanity check that.
-     */
-    if (ret != expect) {
-        qemu_file_set_error(f, ret < 0 ? ret : -EIO);
-    }
     f->buf_index = 0;
     f->iovcnt = 0;
+    if (ret < 0) {
+        qemu_file_set_error(f, ret);
+    }
 }
 
 void ram_control_before_iterate(QEMUFile *f, uint64_t flags)
 {
     int ret = 0;
 
-    if (f->hooks && f->hooks->before_ram_iterate) {
-        ret = f->hooks->before_ram_iterate(f, f->opaque, flags, NULL);
+    if (f->ops->before_ram_iterate) {
+        ret = f->ops->before_ram_iterate(f, f->opaque, flags, NULL);
         if (ret < 0) {
             qemu_file_set_error(f, ret);
         }
@@ -182,8 +153,8 @@ void ram_control_after_iterate(QEMUFile *f, uint64_t flags)
 {
     int ret = 0;
 
-    if (f->hooks && f->hooks->after_ram_iterate) {
-        ret = f->hooks->after_ram_iterate(f, f->opaque, flags, NULL);
+    if (f->ops->after_ram_iterate) {
+        ret = f->ops->after_ram_iterate(f, f->opaque, flags, NULL);
         if (ret < 0) {
             qemu_file_set_error(f, ret);
         }
@@ -194,8 +165,8 @@ void ram_control_load_hook(QEMUFile *f, uint64_t flags, void *data)
 {
     int ret = -EINVAL;
 
-    if (f->hooks && f->hooks->hook_ram_load) {
-        ret = f->hooks->hook_ram_load(f, f->opaque, flags, data);
+    if (f->ops->hook_ram_load) {
+        ret = f->ops->hook_ram_load(f, f->opaque, flags, data);
         if (ret < 0) {
             qemu_file_set_error(f, ret);
         }
@@ -214,9 +185,9 @@ size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
                              ram_addr_t offset, size_t size,
                              uint64_t *bytes_sent)
 {
-    if (f->hooks && f->hooks->save_page) {
-        int ret = f->hooks->save_page(f, f->opaque, block_offset,
-                                      offset, size, bytes_sent);
+    if (f->ops->save_page) {
+        int ret = f->ops->save_page(f, f->opaque, block_offset,
+                                    offset, size, bytes_sent);
 
         if (ret != RAM_SAVE_CONTROL_DELAYED) {
             if (bytes_sent && *bytes_sent > 0) {
@@ -268,6 +239,14 @@ static ssize_t qemu_fill_buffer(QEMUFile *f)
     return len;
 }
 
+int qemu_get_fd(QEMUFile *f)
+{
+    if (f->ops->get_fd) {
+        return f->ops->get_fd(f->opaque);
+    }
+    return -1;
+}
+
 void qemu_update_position(QEMUFile *f, size_t size)
 {
     f->pos += size;
@@ -322,6 +301,11 @@ static void add_to_iovec(QEMUFile *f, const uint8_t *buf, size_t size)
 
 void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, size_t size)
 {
+    if (!f->ops->writev_buffer) {
+        qemu_put_buffer(f, buf, size);
+        return;
+    }
+
     if (f->last_error) {
         return;
     }
@@ -345,7 +329,9 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size)
         }
         memcpy(f->buf + f->buf_index, buf, l);
         f->bytes_xfer += l;
-        add_to_iovec(f, f->buf + f->buf_index, l);
+        if (f->ops->writev_buffer) {
+            add_to_iovec(f, f->buf + f->buf_index, l);
+        }
         f->buf_index += l;
         if (f->buf_index == IO_BUF_SIZE) {
             qemu_fflush(f);
@@ -366,7 +352,9 @@ void qemu_put_byte(QEMUFile *f, int v)
 
     f->buf[f->buf_index] = v;
     f->bytes_xfer++;
-    add_to_iovec(f, f->buf + f->buf_index, 1);
+    if (f->ops->writev_buffer) {
+        add_to_iovec(f, f->buf + f->buf_index, 1);
+    }
     f->buf_index++;
     if (f->buf_index == IO_BUF_SIZE) {
         qemu_fflush(f);
@@ -530,8 +518,12 @@ int64_t qemu_ftell_fast(QEMUFile *f)
     int64_t ret = f->pos;
     int i;
 
-    for (i = 0; i < f->iovcnt; i++) {
-        ret += f->iov[i].iov_len;
+    if (f->ops->writev_buffer) {
+        for (i = 0; i < f->iovcnt; i++) {
+            ret += f->iov[i].iov_len;
+        }
+    } else {
+        ret += f->buf_index;
     }
 
     return ret;
@@ -615,14 +607,8 @@ uint64_t qemu_get_be64(QEMUFile *f)
     return v;
 }
 
-/* Compress size bytes of data start at p with specific compression
+/* compress size bytes of data start at p with specific compression
  * level and store the compressed data to the buffer of f.
- *
- * When f is not writable, return -1 if f has no space to save the
- * compressed data.
- * When f is wirtable and it has no space to save the compressed data,
- * do fflush first, if f still has no space to save the compressed
- * data, return -1.
  */
 
 ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size,
@@ -631,14 +617,7 @@ ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size,
     ssize_t blen = IO_BUF_SIZE - f->buf_index - sizeof(int32_t);
 
     if (blen < compressBound(size)) {
-        if (!qemu_file_is_writable(f)) {
-            return -1;
-        }
-        qemu_fflush(f);
-        blen = IO_BUF_SIZE - sizeof(int32_t);
-        if (blen < compressBound(size)) {
-            return -1;
-        }
+        return 0;
     }
     if (compress2(f->buf + f->buf_index + sizeof(int32_t), (uLongf *)&blen,
                   (Bytef *)p, size, level) != Z_OK) {
@@ -646,13 +625,7 @@ ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size,
         return 0;
     }
     qemu_put_be32(f, blen);
-    if (f->ops->writev_buffer) {
-        add_to_iovec(f, f->buf + f->buf_index, blen);
-    }
     f->buf_index += blen;
-    if (f->buf_index == IO_BUF_SIZE) {
-        qemu_fflush(f);
-    }
     return blen + sizeof(int32_t);
 }
 
@@ -668,7 +641,6 @@ int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src)
         len = f_src->buf_index;
         qemu_put_buffer(f_des, f_src->buf, f_src->buf_index);
         f_src->buf_index = 0;
-        f_src->iovcnt = 0;
     }
     return len;
 }
@@ -698,7 +670,9 @@ size_t qemu_get_counted_string(QEMUFile *f, char buf[256])
  */
 void qemu_file_set_blocking(QEMUFile *f, bool block)
 {
-    if (f->ops->set_blocking) {
-        f->ops->set_blocking(f->opaque, block);
+    if (block) {
+        qemu_set_block(qemu_get_fd(f));
+    } else {
+        qemu_set_nonblock(qemu_get_fd(f));
     }
 }
index a3d70c4..88fbffc 100644 (file)
@@ -26,8 +26,6 @@
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include <zlib.h>
 #include "qapi-event.h"
 #include "qemu/cutils.h"
@@ -253,8 +251,8 @@ static struct BitmapRcu {
 } *migration_bitmap_rcu;
 
 struct CompressParam {
+    bool start;
     bool done;
-    bool quit;
     QEMUFile *file;
     QemuMutex mutex;
     QemuCond cond;
@@ -264,8 +262,7 @@ struct CompressParam {
 typedef struct CompressParam CompressParam;
 
 struct DecompressParam {
-    bool done;
-    bool quit;
+    bool start;
     QemuMutex mutex;
     QemuCond cond;
     void *des;
@@ -280,47 +277,45 @@ static QemuThread *compress_threads;
  * one of the compression threads has finished the compression.
  * comp_done_lock is used to co-work with comp_done_cond.
  */
-static QemuMutex comp_done_lock;
-static QemuCond comp_done_cond;
+static QemuMutex *comp_done_lock;
+static QemuCond *comp_done_cond;
 /* The empty QEMUFileOps will be used by file in CompressParam */
 static const QEMUFileOps empty_ops = { };
 
 static bool compression_switch;
+static bool quit_comp_thread;
+static bool quit_decomp_thread;
 static DecompressParam *decomp_param;
 static QemuThread *decompress_threads;
-static QemuMutex decomp_done_lock;
-static QemuCond decomp_done_cond;
 
-static int do_compress_ram_page(QEMUFile *f, RAMBlock *block,
-                                ram_addr_t offset);
+static int do_compress_ram_page(CompressParam *param);
 
 static void *do_data_compress(void *opaque)
 {
     CompressParam *param = opaque;
-    RAMBlock *block;
-    ram_addr_t offset;
-
-    qemu_mutex_lock(&param->mutex);
-    while (!param->quit) {
-        if (param->block) {
-            block = param->block;
-            offset = param->offset;
-            param->block = NULL;
-            qemu_mutex_unlock(&param->mutex);
 
-            do_compress_ram_page(param->file, block, offset);
-
-            qemu_mutex_lock(&comp_done_lock);
-            param->done = true;
-            qemu_cond_signal(&comp_done_cond);
-            qemu_mutex_unlock(&comp_done_lock);
-
-            qemu_mutex_lock(&param->mutex);
-        } else {
+    while (!quit_comp_thread) {
+        qemu_mutex_lock(&param->mutex);
+        /* Re-check the quit_comp_thread in case of
+         * terminate_compression_threads is called just before
+         * qemu_mutex_lock(&param->mutex) and after
+         * while(!quit_comp_thread), re-check it here can make
+         * sure the compression thread terminate as expected.
+         */
+        while (!param->start && !quit_comp_thread) {
             qemu_cond_wait(&param->cond, &param->mutex);
         }
+        if (!quit_comp_thread) {
+            do_compress_ram_page(param);
+        }
+        param->start = false;
+        qemu_mutex_unlock(&param->mutex);
+
+        qemu_mutex_lock(comp_done_lock);
+        param->done = true;
+        qemu_cond_signal(comp_done_cond);
+        qemu_mutex_unlock(comp_done_lock);
     }
-    qemu_mutex_unlock(&param->mutex);
 
     return NULL;
 }
@@ -330,9 +325,9 @@ static inline void terminate_compression_threads(void)
     int idx, thread_count;
 
     thread_count = migrate_compress_threads();
+    quit_comp_thread = true;
     for (idx = 0; idx < thread_count; idx++) {
         qemu_mutex_lock(&comp_param[idx].mutex);
-        comp_param[idx].quit = true;
         qemu_cond_signal(&comp_param[idx].cond);
         qemu_mutex_unlock(&comp_param[idx].mutex);
     }
@@ -353,12 +348,16 @@ void migrate_compress_threads_join(void)
         qemu_mutex_destroy(&comp_param[i].mutex);
         qemu_cond_destroy(&comp_param[i].cond);
     }
-    qemu_mutex_destroy(&comp_done_lock);
-    qemu_cond_destroy(&comp_done_cond);
+    qemu_mutex_destroy(comp_done_lock);
+    qemu_cond_destroy(comp_done_cond);
     g_free(compress_threads);
     g_free(comp_param);
+    g_free(comp_done_cond);
+    g_free(comp_done_lock);
     compress_threads = NULL;
     comp_param = NULL;
+    comp_done_cond = NULL;
+    comp_done_lock = NULL;
 }
 
 void migrate_compress_threads_create(void)
@@ -368,19 +367,21 @@ void migrate_compress_threads_create(void)
     if (!migrate_use_compression()) {
         return;
     }
+    quit_comp_thread = false;
     compression_switch = true;
     thread_count = migrate_compress_threads();
     compress_threads = g_new0(QemuThread, thread_count);
     comp_param = g_new0(CompressParam, thread_count);
-    qemu_cond_init(&comp_done_cond);
-    qemu_mutex_init(&comp_done_lock);
+    comp_done_cond = g_new0(QemuCond, 1);
+    comp_done_lock = g_new0(QemuMutex, 1);
+    qemu_cond_init(comp_done_cond);
+    qemu_mutex_init(comp_done_lock);
     for (i = 0; i < thread_count; i++) {
-        /* comp_param[i].file is just used as a dummy buffer to save data,
-         * set its ops to empty.
+        /* com_param[i].file is just used as a dummy buffer to save data, set
+         * it's ops to empty.
          */
         comp_param[i].file = qemu_fopen_ops(NULL, &empty_ops);
         comp_param[i].done = true;
-        comp_param[i].quit = false;
         qemu_mutex_init(&comp_param[i].mutex);
         qemu_cond_init(&comp_param[i].cond);
         qemu_thread_create(compress_threads + i, "compress",
@@ -426,8 +427,10 @@ static size_t save_page_header(QEMUFile *f, RAMBlock *block, ram_addr_t offset)
 static void mig_throttle_guest_down(void)
 {
     MigrationState *s = migrate_get_current();
-    uint64_t pct_initial = s->parameters.cpu_throttle_initial;
-    uint64_t pct_icrement = s->parameters.cpu_throttle_increment;
+    uint64_t pct_initial =
+            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL];
+    uint64_t pct_icrement =
+            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT];
 
     /* We have not started throttling yet. Let's start it. */
     if (!cpu_throttle_active()) {
@@ -802,27 +805,41 @@ static int ram_save_page(QEMUFile *f, PageSearchStatus *pss,
     return pages;
 }
 
-static int do_compress_ram_page(QEMUFile *f, RAMBlock *block,
-                                ram_addr_t offset)
+static int do_compress_ram_page(CompressParam *param)
 {
     int bytes_sent, blen;
-    uint8_t *p = block->host + (offset & TARGET_PAGE_MASK);
+    uint8_t *p;
+    RAMBlock *block = param->block;
+    ram_addr_t offset = param->offset;
+
+    p = block->host + (offset & TARGET_PAGE_MASK);
 
-    bytes_sent = save_page_header(f, block, offset |
+    bytes_sent = save_page_header(param->file, block, offset |
                                   RAM_SAVE_FLAG_COMPRESS_PAGE);
-    blen = qemu_put_compression_data(f, p, TARGET_PAGE_SIZE,
+    blen = qemu_put_compression_data(param->file, p, TARGET_PAGE_SIZE,
                                      migrate_compress_level());
-    if (blen < 0) {
-        bytes_sent = 0;
-        qemu_file_set_error(migrate_get_current()->to_dst_file, blen);
-        error_report("compressed data failed!");
-    } else {
-        bytes_sent += blen;
-    }
+    bytes_sent += blen;
 
     return bytes_sent;
 }
 
+static inline void start_compression(CompressParam *param)
+{
+    param->done = false;
+    qemu_mutex_lock(&param->mutex);
+    param->start = true;
+    qemu_cond_signal(&param->cond);
+    qemu_mutex_unlock(&param->mutex);
+}
+
+static inline void start_decompression(DecompressParam *param)
+{
+    qemu_mutex_lock(&param->mutex);
+    param->start = true;
+    qemu_cond_signal(&param->cond);
+    qemu_mutex_unlock(&param->mutex);
+}
+
 static uint64_t bytes_transferred;
 
 static void flush_compressed_data(QEMUFile *f)
@@ -833,22 +850,18 @@ static void flush_compressed_data(QEMUFile *f)
         return;
     }
     thread_count = migrate_compress_threads();
-
-    qemu_mutex_lock(&comp_done_lock);
     for (idx = 0; idx < thread_count; idx++) {
-        while (!comp_param[idx].done) {
-            qemu_cond_wait(&comp_done_cond, &comp_done_lock);
+        if (!comp_param[idx].done) {
+            qemu_mutex_lock(comp_done_lock);
+            while (!comp_param[idx].done && !quit_comp_thread) {
+                qemu_cond_wait(comp_done_cond, comp_done_lock);
+            }
+            qemu_mutex_unlock(comp_done_lock);
         }
-    }
-    qemu_mutex_unlock(&comp_done_lock);
-
-    for (idx = 0; idx < thread_count; idx++) {
-        qemu_mutex_lock(&comp_param[idx].mutex);
-        if (!comp_param[idx].quit) {
+        if (!quit_comp_thread) {
             len = qemu_put_qemu_file(f, comp_param[idx].file);
             bytes_transferred += len;
         }
-        qemu_mutex_unlock(&comp_param[idx].mutex);
     }
 }
 
@@ -866,16 +879,13 @@ static int compress_page_with_multi_thread(QEMUFile *f, RAMBlock *block,
     int idx, thread_count, bytes_xmit = -1, pages = -1;
 
     thread_count = migrate_compress_threads();
-    qemu_mutex_lock(&comp_done_lock);
+    qemu_mutex_lock(comp_done_lock);
     while (true) {
         for (idx = 0; idx < thread_count; idx++) {
             if (comp_param[idx].done) {
-                comp_param[idx].done = false;
                 bytes_xmit = qemu_put_qemu_file(f, comp_param[idx].file);
-                qemu_mutex_lock(&comp_param[idx].mutex);
                 set_compress_params(&comp_param[idx], block, offset);
-                qemu_cond_signal(&comp_param[idx].cond);
-                qemu_mutex_unlock(&comp_param[idx].mutex);
+                start_compression(&comp_param[idx]);
                 pages = 1;
                 acct_info.norm_pages++;
                 *bytes_transferred += bytes_xmit;
@@ -885,10 +895,10 @@ static int compress_page_with_multi_thread(QEMUFile *f, RAMBlock *block,
         if (pages > 0) {
             break;
         } else {
-            qemu_cond_wait(&comp_done_cond, &comp_done_lock);
+            qemu_cond_wait(comp_done_cond, comp_done_lock);
         }
     }
-    qemu_mutex_unlock(&comp_done_lock);
+    qemu_mutex_unlock(comp_done_lock);
 
     return pages;
 }
@@ -909,20 +919,24 @@ static int ram_save_compressed_page(QEMUFile *f, PageSearchStatus *pss,
                                     uint64_t *bytes_transferred)
 {
     int pages = -1;
-    uint64_t bytes_xmit = 0;
+    uint64_t bytes_xmit;
     uint8_t *p;
-    int ret, blen;
+    int ret;
     RAMBlock *block = pss->block;
     ram_addr_t offset = pss->offset;
 
     p = block->host + offset;
 
+    bytes_xmit = 0;
     ret = ram_control_save_page(f, block->offset,
                                 offset, TARGET_PAGE_SIZE, &bytes_xmit);
     if (bytes_xmit) {
         *bytes_transferred += bytes_xmit;
         pages = 1;
     }
+    if (block == last_sent_block) {
+        offset |= RAM_SAVE_FLAG_CONTINUE;
+    }
     if (ret != RAM_SAVE_CONTROL_NOT_SUPP) {
         if (ret != RAM_SAVE_CONTROL_DELAYED) {
             if (bytes_xmit > 0) {
@@ -942,22 +956,17 @@ static int ram_save_compressed_page(QEMUFile *f, PageSearchStatus *pss,
             flush_compressed_data(f);
             pages = save_zero_page(f, block, offset, p, bytes_transferred);
             if (pages == -1) {
-                /* Make sure the first page is sent out before other pages */
-                bytes_xmit = save_page_header(f, block, offset |
-                                              RAM_SAVE_FLAG_COMPRESS_PAGE);
-                blen = qemu_put_compression_data(f, p, TARGET_PAGE_SIZE,
-                                                 migrate_compress_level());
-                if (blen > 0) {
-                    *bytes_transferred += bytes_xmit + blen;
-                    acct_info.norm_pages++;
-                    pages = 1;
-                } else {
-                    qemu_file_set_error(f, blen);
-                    error_report("compressed data failed!");
-                }
+                set_compress_params(&comp_param[0], block, offset);
+                /* Use the qemu thread to compress the data to make sure the
+                 * first page is sent out before other pages
+                 */
+                bytes_xmit = do_compress_ram_page(&comp_param[0]);
+                acct_info.norm_pages++;
+                qemu_put_qemu_file(f, comp_param[0].file);
+                *bytes_transferred += bytes_xmit;
+                pages = 1;
             }
         } else {
-            offset |= RAM_SAVE_FLAG_CONTINUE;
             pages = save_zero_page(f, block, offset, p, bytes_transferred);
             if (pages == -1) {
                 pages = compress_page_with_multi_thread(f, block, offset,
@@ -1160,7 +1169,6 @@ int ram_save_queue_pages(MigrationState *ms, const char *rbname,
 {
     RAMBlock *ramblock;
 
-    ms->postcopy_requests++;
     rcu_read_lock();
     if (!rbname) {
         /* Reuse last RAMBlock */
@@ -1549,9 +1557,7 @@ static int postcopy_send_discard_bm_ram(MigrationState *ms,
             } else {
                 discard_length = zero - one;
             }
-            if (discard_length) {
-                postcopy_discard_send_range(ms, pds, one, discard_length);
-            }
+            postcopy_discard_send_range(ms, pds, one, discard_length);
             current = one + discard_length;
         } else {
             current = one;
@@ -2182,59 +2188,29 @@ static void *do_data_decompress(void *opaque)
 {
     DecompressParam *param = opaque;
     unsigned long pagesize;
-    uint8_t *des;
-    int len;
 
-    qemu_mutex_lock(&param->mutex);
-    while (!param->quit) {
-        if (param->des) {
-            des = param->des;
-            len = param->len;
-            param->des = 0;
-            qemu_mutex_unlock(&param->mutex);
-
-            pagesize = TARGET_PAGE_SIZE;
-            /* uncompress() will return failed in some case, especially
-             * when the page is dirted when doing the compression, it's
-             * not a problem because the dirty page will be retransferred
-             * and uncompress() won't break the data in other pages.
-             */
-            uncompress((Bytef *)des, &pagesize,
-                       (const Bytef *)param->compbuf, len);
-
-            qemu_mutex_lock(&decomp_done_lock);
-            param->done = true;
-            qemu_cond_signal(&decomp_done_cond);
-            qemu_mutex_unlock(&decomp_done_lock);
-
-            qemu_mutex_lock(&param->mutex);
-        } else {
+    while (!quit_decomp_thread) {
+        qemu_mutex_lock(&param->mutex);
+        while (!param->start && !quit_decomp_thread) {
             qemu_cond_wait(&param->cond, &param->mutex);
+            pagesize = TARGET_PAGE_SIZE;
+            if (!quit_decomp_thread) {
+                /* uncompress() will return failed in some case, especially
+                 * when the page is dirted when doing the compression, it's
+                 * not a problem because the dirty page will be retransferred
+                 * and uncompress() won't break the data in other pages.
+                 */
+                uncompress((Bytef *)param->des, &pagesize,
+                           (const Bytef *)param->compbuf, param->len);
+            }
+            param->start = false;
         }
+        qemu_mutex_unlock(&param->mutex);
     }
-    qemu_mutex_unlock(&param->mutex);
 
     return NULL;
 }
 
-static void wait_for_decompress_done(void)
-{
-    int idx, thread_count;
-
-    if (!migrate_use_compression()) {
-        return;
-    }
-
-    thread_count = migrate_decompress_threads();
-    qemu_mutex_lock(&decomp_done_lock);
-    for (idx = 0; idx < thread_count; idx++) {
-        while (!decomp_param[idx].done) {
-            qemu_cond_wait(&decomp_done_cond, &decomp_done_lock);
-        }
-    }
-    qemu_mutex_unlock(&decomp_done_lock);
-}
-
 void migrate_decompress_threads_create(void)
 {
     int i, thread_count;
@@ -2242,14 +2218,11 @@ void migrate_decompress_threads_create(void)
     thread_count = migrate_decompress_threads();
     decompress_threads = g_new0(QemuThread, thread_count);
     decomp_param = g_new0(DecompressParam, thread_count);
-    qemu_mutex_init(&decomp_done_lock);
-    qemu_cond_init(&decomp_done_cond);
+    quit_decomp_thread = false;
     for (i = 0; i < thread_count; i++) {
         qemu_mutex_init(&decomp_param[i].mutex);
         qemu_cond_init(&decomp_param[i].cond);
         decomp_param[i].compbuf = g_malloc0(compressBound(TARGET_PAGE_SIZE));
-        decomp_param[i].done = true;
-        decomp_param[i].quit = false;
         qemu_thread_create(decompress_threads + i, "decompress",
                            do_data_decompress, decomp_param + i,
                            QEMU_THREAD_JOINABLE);
@@ -2260,10 +2233,10 @@ void migrate_decompress_threads_join(void)
 {
     int i, thread_count;
 
+    quit_decomp_thread = true;
     thread_count = migrate_decompress_threads();
     for (i = 0; i < thread_count; i++) {
         qemu_mutex_lock(&decomp_param[i].mutex);
-        decomp_param[i].quit = true;
         qemu_cond_signal(&decomp_param[i].cond);
         qemu_mutex_unlock(&decomp_param[i].mutex);
     }
@@ -2285,27 +2258,20 @@ static void decompress_data_with_multi_threads(QEMUFile *f,
     int idx, thread_count;
 
     thread_count = migrate_decompress_threads();
-    qemu_mutex_lock(&decomp_done_lock);
     while (true) {
         for (idx = 0; idx < thread_count; idx++) {
-            if (decomp_param[idx].done) {
-                decomp_param[idx].done = false;
-                qemu_mutex_lock(&decomp_param[idx].mutex);
+            if (!decomp_param[idx].start) {
                 qemu_get_buffer(f, decomp_param[idx].compbuf, len);
                 decomp_param[idx].des = host;
                 decomp_param[idx].len = len;
-                qemu_cond_signal(&decomp_param[idx].cond);
-                qemu_mutex_unlock(&decomp_param[idx].mutex);
+                start_decompression(&decomp_param[idx]);
                 break;
             }
         }
         if (idx < thread_count) {
             break;
-        } else {
-            qemu_cond_wait(&decomp_done_cond, &decomp_done_lock);
         }
     }
-    qemu_mutex_unlock(&decomp_done_lock);
 }
 
 /*
@@ -2356,6 +2322,7 @@ static int ram_load_postcopy(QEMUFile *f)
                 ret = -EINVAL;
                 break;
             }
+            page_buffer = host;
             /*
              * Postcopy requires that we place whole host pages atomically.
              * To make it atomic, the data is read into a temporary page
@@ -2509,7 +2476,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
                     if (length != block->used_length) {
                         Error *local_err = NULL;
 
-                        ret = qemu_ram_resize(block, length,
+                        ret = qemu_ram_resize(block->offset, length,
                                               &local_err);
                         if (local_err) {
                             error_report_err(local_err);
@@ -2571,7 +2538,6 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
         }
     }
 
-    wait_for_decompress_done();
     rcu_read_unlock();
     DPRINTF("Completed load of VM with exit code %d seq iteration "
             "%" PRIu64 "\n", ret, seq_iter);
index 5110ec8..f6a9992 100644 (file)
@@ -2,12 +2,10 @@
  * RDMA protocol and interfaces
  *
  * Copyright IBM, Corp. 2010-2013
- * Copyright Red Hat, Inc. 2015-2016
  *
  * Authors:
  *  Michael R. Hines <mrhines@us.ibm.com>
  *  Jiuxing Liu <jl@us.ibm.com>
- *  Daniel P. Berrange <berrange@redhat.com>
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or
  * later.  See the COPYING file in the top-level directory.
@@ -376,20 +374,14 @@ typedef struct RDMAContext {
     GHashTable *blockmap;
 } RDMAContext;
 
-#define TYPE_QIO_CHANNEL_RDMA "qio-channel-rdma"
-#define QIO_CHANNEL_RDMA(obj)                                     \
-    OBJECT_CHECK(QIOChannelRDMA, (obj), TYPE_QIO_CHANNEL_RDMA)
-
-typedef struct QIOChannelRDMA QIOChannelRDMA;
-
-
-struct QIOChannelRDMA {
-    QIOChannel parent;
+/*
+ * Interface to the rest of the migration call stack.
+ */
+typedef struct QEMUFileRDMA {
     RDMAContext *rdma;
-    QEMUFile *file;
     size_t len;
-    bool blocking; /* XXX we don't actually honour this yet */
-};
+    void *file;
+} QEMUFileRDMA;
 
 /*
  * Main structure for IB Send/Recv control messages.
@@ -1511,7 +1503,7 @@ static int qemu_rdma_block_for_wrid(RDMAContext *rdma, int wrid_requested,
 
     while (1) {
         /*
-         * Coroutine doesn't start until migration_fd_process_incoming()
+         * Coroutine doesn't start until process_incoming_migration()
          * so don't yield unless we know we're running inside of a coroutine.
          */
         if (rdma->migration_started_on_destination) {
@@ -2526,19 +2518,15 @@ static void *qemu_rdma_data_init(const char *host_port, Error **errp)
  * SEND messages for control only.
  * VM's ram is handled with regular RDMA messages.
  */
-static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
-                                       const struct iovec *iov,
-                                       size_t niov,
-                                       int *fds,
-                                       size_t nfds,
-                                       Error **errp)
-{
-    QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(ioc);
-    QEMUFile *f = rioc->file;
-    RDMAContext *rdma = rioc->rdma;
+static ssize_t qemu_rdma_put_buffer(void *opaque, const uint8_t *buf,
+                                    int64_t pos, size_t size)
+{
+    QEMUFileRDMA *r = opaque;
+    QEMUFile *f = r->file;
+    RDMAContext *rdma = r->rdma;
+    size_t remaining = size;
+    uint8_t * data = (void *) buf;
     int ret;
-    ssize_t done = 0;
-    size_t i;
 
     CHECK_ERROR_STATE();
 
@@ -2552,31 +2540,27 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
         return ret;
     }
 
-    for (i = 0; i < niov; i++) {
-        size_t remaining = iov[i].iov_len;
-        uint8_t * data = (void *)iov[i].iov_base;
-        while (remaining) {
-            RDMAControlHeader head;
-
-            rioc->len = MIN(remaining, RDMA_SEND_INCREMENT);
-            remaining -= rioc->len;
+    while (remaining) {
+        RDMAControlHeader head;
 
-            head.len = rioc->len;
-            head.type = RDMA_CONTROL_QEMU_FILE;
+        r->len = MIN(remaining, RDMA_SEND_INCREMENT);
+        remaining -= r->len;
 
-            ret = qemu_rdma_exchange_send(rdma, &head, data, NULL, NULL, NULL);
+        /* Guaranteed to fit due to RDMA_SEND_INCREMENT MIN above */
+        head.len = (uint32_t)r->len;
+        head.type = RDMA_CONTROL_QEMU_FILE;
 
-            if (ret < 0) {
-                rdma->error_state = ret;
-                return ret;
-            }
+        ret = qemu_rdma_exchange_send(rdma, &head, data, NULL, NULL, NULL);
 
-            data += rioc->len;
-            done += rioc->len;
+        if (ret < 0) {
+            rdma->error_state = ret;
+            return ret;
         }
+
+        data += r->len;
     }
 
-    return done;
+    return size;
 }
 
 static size_t qemu_rdma_fill(RDMAContext *rdma, uint8_t *buf,
@@ -2601,74 +2585,41 @@ static size_t qemu_rdma_fill(RDMAContext *rdma, uint8_t *buf,
  * RDMA links don't use bytestreams, so we have to
  * return bytes to QEMUFile opportunistically.
  */
-static ssize_t qio_channel_rdma_readv(QIOChannel *ioc,
-                                      const struct iovec *iov,
-                                      size_t niov,
-                                      int **fds,
-                                      size_t *nfds,
-                                      Error **errp)
-{
-    QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(ioc);
-    RDMAContext *rdma = rioc->rdma;
+static ssize_t qemu_rdma_get_buffer(void *opaque, uint8_t *buf,
+                                    int64_t pos, size_t size)
+{
+    QEMUFileRDMA *r = opaque;
+    RDMAContext *rdma = r->rdma;
     RDMAControlHeader head;
     int ret = 0;
-    ssize_t i;
-    size_t done = 0;
 
     CHECK_ERROR_STATE();
 
-    for (i = 0; i < niov; i++) {
-        size_t want = iov[i].iov_len;
-        uint8_t *data = (void *)iov[i].iov_base;
-
-        /*
-         * First, we hold on to the last SEND message we
-         * were given and dish out the bytes until we run
-         * out of bytes.
-         */
-        ret = qemu_rdma_fill(rioc->rdma, data, want, 0);
-        done += ret;
-        want -= ret;
-        /* Got what we needed, so go to next iovec */
-        if (want == 0) {
-            continue;
-        }
-
-        /* If we got any data so far, then don't wait
-         * for more, just return what we have */
-        if (done > 0) {
-            break;
-        }
-
-
-        /* We've got nothing at all, so lets wait for
-         * more to arrive
-         */
-        ret = qemu_rdma_exchange_recv(rdma, &head, RDMA_CONTROL_QEMU_FILE);
+    /*
+     * First, we hold on to the last SEND message we
+     * were given and dish out the bytes until we run
+     * out of bytes.
+     */
+    r->len = qemu_rdma_fill(r->rdma, buf, size, 0);
+    if (r->len) {
+        return r->len;
+    }
 
-        if (ret < 0) {
-            rdma->error_state = ret;
-            return ret;
-        }
+    /*
+     * Once we run out, we block and wait for another
+     * SEND message to arrive.
+     */
+    ret = qemu_rdma_exchange_recv(rdma, &head, RDMA_CONTROL_QEMU_FILE);
 
-        /*
-         * SEND was received with new bytes, now try again.
-         */
-        ret = qemu_rdma_fill(rioc->rdma, data, want, 0);
-        done += ret;
-        want -= ret;
-
-        /* Still didn't get enough, so lets just return */
-        if (want) {
-            if (done == 0) {
-                return QIO_CHANNEL_ERR_BLOCK;
-            } else {
-                break;
-            }
-        }
+    if (ret < 0) {
+        rdma->error_state = ret;
+        return ret;
     }
-    rioc->len = done;
-    return rioc->len;
+
+    /*
+     * SEND was received with new bytes, now try again.
+     */
+    return qemu_rdma_fill(r->rdma, buf, size, 0);
 }
 
 /*
@@ -2695,122 +2646,15 @@ static int qemu_rdma_drain_cq(QEMUFile *f, RDMAContext *rdma)
     return 0;
 }
 
-
-static int qio_channel_rdma_set_blocking(QIOChannel *ioc,
-                                         bool blocking,
-                                         Error **errp)
-{
-    QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(ioc);
-    /* XXX we should make readv/writev actually honour this :-) */
-    rioc->blocking = blocking;
-    return 0;
-}
-
-
-typedef struct QIOChannelRDMASource QIOChannelRDMASource;
-struct QIOChannelRDMASource {
-    GSource parent;
-    QIOChannelRDMA *rioc;
-    GIOCondition condition;
-};
-
-static gboolean
-qio_channel_rdma_source_prepare(GSource *source,
-                                gint *timeout)
-{
-    QIOChannelRDMASource *rsource = (QIOChannelRDMASource *)source;
-    RDMAContext *rdma = rsource->rioc->rdma;
-    GIOCondition cond = 0;
-    *timeout = -1;
-
-    if (rdma->wr_data[0].control_len) {
-        cond |= G_IO_IN;
-    }
-    cond |= G_IO_OUT;
-
-    return cond & rsource->condition;
-}
-
-static gboolean
-qio_channel_rdma_source_check(GSource *source)
-{
-    QIOChannelRDMASource *rsource = (QIOChannelRDMASource *)source;
-    RDMAContext *rdma = rsource->rioc->rdma;
-    GIOCondition cond = 0;
-
-    if (rdma->wr_data[0].control_len) {
-        cond |= G_IO_IN;
-    }
-    cond |= G_IO_OUT;
-
-    return cond & rsource->condition;
-}
-
-static gboolean
-qio_channel_rdma_source_dispatch(GSource *source,
-                                 GSourceFunc callback,
-                                 gpointer user_data)
-{
-    QIOChannelFunc func = (QIOChannelFunc)callback;
-    QIOChannelRDMASource *rsource = (QIOChannelRDMASource *)source;
-    RDMAContext *rdma = rsource->rioc->rdma;
-    GIOCondition cond = 0;
-
-    if (rdma->wr_data[0].control_len) {
-        cond |= G_IO_IN;
-    }
-    cond |= G_IO_OUT;
-
-    return (*func)(QIO_CHANNEL(rsource->rioc),
-                   (cond & rsource->condition),
-                   user_data);
-}
-
-static void
-qio_channel_rdma_source_finalize(GSource *source)
-{
-    QIOChannelRDMASource *ssource = (QIOChannelRDMASource *)source;
-
-    object_unref(OBJECT(ssource->rioc));
-}
-
-GSourceFuncs qio_channel_rdma_source_funcs = {
-    qio_channel_rdma_source_prepare,
-    qio_channel_rdma_source_check,
-    qio_channel_rdma_source_dispatch,
-    qio_channel_rdma_source_finalize
-};
-
-static GSource *qio_channel_rdma_create_watch(QIOChannel *ioc,
-                                              GIOCondition condition)
-{
-    QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(ioc);
-    QIOChannelRDMASource *ssource;
-    GSource *source;
-
-    source = g_source_new(&qio_channel_rdma_source_funcs,
-                          sizeof(QIOChannelRDMASource));
-    ssource = (QIOChannelRDMASource *)source;
-
-    ssource->rioc = rioc;
-    object_ref(OBJECT(rioc));
-
-    ssource->condition = condition;
-
-    return source;
-}
-
-
-static int qio_channel_rdma_close(QIOChannel *ioc,
-                                  Error **errp)
+static int qemu_rdma_close(void *opaque)
 {
-    QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(ioc);
     trace_qemu_rdma_close();
-    if (rioc->rdma) {
-        qemu_rdma_cleanup(rioc->rdma);
-        g_free(rioc->rdma);
-        rioc->rdma = NULL;
+    QEMUFileRDMA *r = opaque;
+    if (r->rdma) {
+        qemu_rdma_cleanup(r->rdma);
+        g_free(r->rdma);
     }
+    g_free(r);
     return 0;
 }
 
@@ -2852,8 +2696,8 @@ static size_t qemu_rdma_save_page(QEMUFile *f, void *opaque,
                                   ram_addr_t block_offset, ram_addr_t offset,
                                   size_t size, uint64_t *bytes_sent)
 {
-    QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(opaque);
-    RDMAContext *rdma = rioc->rdma;
+    QEMUFileRDMA *rfile = opaque;
+    RDMAContext *rdma = rfile->rdma;
     int ret;
 
     CHECK_ERROR_STATE();
@@ -3107,8 +2951,8 @@ static int qemu_rdma_registration_handle(QEMUFile *f, void *opaque)
                              };
     RDMAControlHeader blocks = { .type = RDMA_CONTROL_RAM_BLOCKS_RESULT,
                                  .repeat = 1 };
-    QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(opaque);
-    RDMAContext *rdma = rioc->rdma;
+    QEMUFileRDMA *rfile = opaque;
+    RDMAContext *rdma = rfile->rdma;
     RDMALocalBlocks *local = &rdma->local_ram_blocks;
     RDMAControlHeader head;
     RDMARegister *reg, *registers;
@@ -3363,10 +3207,9 @@ out:
  * We've already built our local RAMBlock list, but not yet sent the list to
  * the source.
  */
-static int
-rdma_block_notification_handle(QIOChannelRDMA *rioc, const char *name)
+static int rdma_block_notification_handle(QEMUFileRDMA *rfile, const char *name)
 {
-    RDMAContext *rdma = rioc->rdma;
+    RDMAContext *rdma = rfile->rdma;
     int curr;
     int found = -1;
 
@@ -3408,8 +3251,8 @@ static int rdma_load_hook(QEMUFile *f, void *opaque, uint64_t flags, void *data)
 static int qemu_rdma_registration_start(QEMUFile *f, void *opaque,
                                         uint64_t flags, void *data)
 {
-    QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(opaque);
-    RDMAContext *rdma = rioc->rdma;
+    QEMUFileRDMA *rfile = opaque;
+    RDMAContext *rdma = rfile->rdma;
 
     CHECK_ERROR_STATE();
 
@@ -3428,8 +3271,8 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,
                                        uint64_t flags, void *data)
 {
     Error *local_err = NULL, **errp = &local_err;
-    QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(opaque);
-    RDMAContext *rdma = rioc->rdma;
+    QEMUFileRDMA *rfile = opaque;
+    RDMAContext *rdma = rfile->rdma;
     RDMAControlHeader head = { .len = 0, .repeat = 1 };
     int ret = 0;
 
@@ -3525,74 +3368,47 @@ err:
     return ret;
 }
 
-static const QEMUFileHooks rdma_read_hooks = {
+static int qemu_rdma_get_fd(void *opaque)
+{
+    QEMUFileRDMA *rfile = opaque;
+    RDMAContext *rdma = rfile->rdma;
+
+    return rdma->comp_channel->fd;
+}
+
+static const QEMUFileOps rdma_read_ops = {
+    .get_buffer    = qemu_rdma_get_buffer,
+    .get_fd        = qemu_rdma_get_fd,
+    .close         = qemu_rdma_close,
     .hook_ram_load = rdma_load_hook,
 };
 
-static const QEMUFileHooks rdma_write_hooks = {
+static const QEMUFileOps rdma_write_ops = {
+    .put_buffer         = qemu_rdma_put_buffer,
+    .close              = qemu_rdma_close,
     .before_ram_iterate = qemu_rdma_registration_start,
     .after_ram_iterate  = qemu_rdma_registration_stop,
     .save_page          = qemu_rdma_save_page,
 };
 
-
-static void qio_channel_rdma_finalize(Object *obj)
+static void *qemu_fopen_rdma(RDMAContext *rdma, const char *mode)
 {
-    QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(obj);
-    if (rioc->rdma) {
-        qemu_rdma_cleanup(rioc->rdma);
-        g_free(rioc->rdma);
-        rioc->rdma = NULL;
-    }
-}
-
-static void qio_channel_rdma_class_init(ObjectClass *klass,
-                                        void *class_data G_GNUC_UNUSED)
-{
-    QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass);
-
-    ioc_klass->io_writev = qio_channel_rdma_writev;
-    ioc_klass->io_readv = qio_channel_rdma_readv;
-    ioc_klass->io_set_blocking = qio_channel_rdma_set_blocking;
-    ioc_klass->io_close = qio_channel_rdma_close;
-    ioc_klass->io_create_watch = qio_channel_rdma_create_watch;
-}
-
-static const TypeInfo qio_channel_rdma_info = {
-    .parent = TYPE_QIO_CHANNEL,
-    .name = TYPE_QIO_CHANNEL_RDMA,
-    .instance_size = sizeof(QIOChannelRDMA),
-    .instance_finalize = qio_channel_rdma_finalize,
-    .class_init = qio_channel_rdma_class_init,
-};
-
-static void qio_channel_rdma_register_types(void)
-{
-    type_register_static(&qio_channel_rdma_info);
-}
-
-type_init(qio_channel_rdma_register_types);
-
-static QEMUFile *qemu_fopen_rdma(RDMAContext *rdma, const char *mode)
-{
-    QIOChannelRDMA *rioc;
+    QEMUFileRDMA *r;
 
     if (qemu_file_mode_is_not_valid(mode)) {
         return NULL;
     }
 
-    rioc = QIO_CHANNEL_RDMA(object_new(TYPE_QIO_CHANNEL_RDMA));
-    rioc->rdma = rdma;
+    r = g_new0(QEMUFileRDMA, 1);
+    r->rdma = rdma;
 
     if (mode[0] == 'w') {
-        rioc->file = qemu_fopen_channel_output(QIO_CHANNEL(rioc));
-        qemu_file_set_hooks(rioc->file, &rdma_write_hooks);
+        r->file = qemu_fopen_ops(r, &rdma_write_ops);
     } else {
-        rioc->file = qemu_fopen_channel_input(QIO_CHANNEL(rioc));
-        qemu_file_set_hooks(rioc->file, &rdma_read_hooks);
+        r->file = qemu_fopen_ops(r, &rdma_read_ops);
     }
 
-    return rioc->file;
+    return r->file;
 }
 
 static void rdma_accept_incoming_migration(void *opaque)
@@ -3620,7 +3436,7 @@ static void rdma_accept_incoming_migration(void *opaque)
     }
 
     rdma->migration_started_on_destination = 1;
-    migration_fd_process_incoming(f);
+    process_incoming_migration(f);
 }
 
 void rdma_start_incoming_migration(const char *host_port, Error **errp)
@@ -3665,14 +3481,16 @@ void rdma_start_outgoing_migration(void *opaque,
                             const char *host_port, Error **errp)
 {
     MigrationState *s = opaque;
-    RDMAContext *rdma = qemu_rdma_data_init(host_port, errp);
+    Error *local_err = NULL, **temp = &local_err;
+    RDMAContext *rdma = qemu_rdma_data_init(host_port, &local_err);
     int ret = 0;
 
     if (rdma == NULL) {
+        ERROR(temp, "Failed to initialize RDMA data structures! %d", ret);
         goto err;
     }
 
-    ret = qemu_rdma_source_init(rdma, errp,
+    ret = qemu_rdma_source_init(rdma, &local_err,
         s->enabled_capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL]);
 
     if (ret) {
@@ -3680,7 +3498,7 @@ void rdma_start_outgoing_migration(void *opaque,
     }
 
     trace_rdma_start_outgoing_migration_after_rdma_source_init();
-    ret = qemu_rdma_connect(rdma, errp);
+    ret = qemu_rdma_connect(rdma, &local_err);
 
     if (ret) {
         goto err;
@@ -3692,5 +3510,7 @@ void rdma_start_outgoing_migration(void *opaque,
     migrate_fd_connect(s);
     return;
 err:
+    error_propagate(errp, local_err);
     g_free(rdma);
+    migrate_fd_error(s);
 }
index 33a2911..8346649 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "cpu.h"
 #include "hw/boards.h"
 #include "hw/hw.h"
 #include "hw/qdev.h"
-#include "hw/xen/xen.h"
 #include "net/net.h"
 #include "monitor/monitor.h"
 #include "sysemu/sysemu.h"
@@ -52,8 +50,6 @@
 #include "block/snapshot.h"
 #include "block/qapi.h"
 #include "qemu/cutils.h"
-#include "io/channel-buffer.h"
-#include "io/channel-file.h"
 
 #ifndef ETH_P_RARP
 #define ETH_P_RARP 0x8035
@@ -161,6 +157,13 @@ static ssize_t block_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
     return qiov.size;
 }
 
+static ssize_t block_put_buffer(void *opaque, const uint8_t *buf,
+                                int64_t pos, size_t size)
+{
+    bdrv_save_vmstate(opaque, buf, pos, size);
+    return size;
+}
+
 static ssize_t block_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
                                 size_t size)
 {
@@ -178,6 +181,7 @@ static const QEMUFileOps bdrv_read_ops = {
 };
 
 static const QEMUFileOps bdrv_write_ops = {
+    .put_buffer     = block_put_buffer,
     .writev_buffer  = block_writev_buffer,
     .close          = bdrv_fclose
 };
@@ -755,8 +759,10 @@ void qemu_savevm_send_open_return_path(QEMUFile *f)
  *    0 on success
  *    -ve on error
  */
-int qemu_savevm_send_packaged(QEMUFile *f, const uint8_t *buf, size_t len)
+int qemu_savevm_send_packaged(QEMUFile *f, const QEMUSizedBuffer *qsb)
 {
+    size_t cur_iov;
+    size_t len = qsb_get_length(qsb);
     uint32_t tmp;
 
     if (len > MAX_VM_CMD_PACKAGED_SIZE) {
@@ -770,7 +776,18 @@ int qemu_savevm_send_packaged(QEMUFile *f, const uint8_t *buf, size_t len)
     trace_qemu_savevm_send_packaged();
     qemu_savevm_command_send(f, MIG_CMD_PACKAGED, 4, (uint8_t *)&tmp);
 
-    qemu_put_buffer(f, buf, len);
+    /* all the data follows (concatinating the iov's) */
+    for (cur_iov = 0; cur_iov < qsb->n_iov; cur_iov++) {
+        /* The iov entries are partially filled */
+        size_t towrite = MIN(qsb->iov[cur_iov].iov_len, len);
+        len -= towrite;
+
+        if (!towrite) {
+            break;
+        }
+
+        qemu_put_buffer(f, qsb->iov[cur_iov].iov_base, towrite);
+    }
 
     return 0;
 }
@@ -823,9 +840,9 @@ void qemu_savevm_send_postcopy_ram_discard(QEMUFile *f, const char *name,
     buf[tmplen++] = '\0';
 
     for (t = 0; t < len; t++) {
-        stq_be_p(buf + tmplen, start_list[t]);
+        cpu_to_be64w((uint64_t *)(buf + tmplen), start_list[t]);
         tmplen += 8;
-        stq_be_p(buf + tmplen, length_list[t]);
+        cpu_to_be64w((uint64_t *)(buf + tmplen), length_list[t]);
         tmplen += 8;
     }
     qemu_savevm_command_send(f, MIG_CMD_POSTCOPY_RAM_DISCARD, tmplen, buf);
@@ -1097,7 +1114,7 @@ void qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only)
         qemu_put_be32(f, vmdesc_len);
         qemu_put_buffer(f, (uint8_t *)qjson_get_str(vmdesc), vmdesc_len);
     }
-    qjson_destroy(vmdesc);
+    object_unref(OBJECT(vmdesc));
 
     qemu_fflush(f);
 }
@@ -1150,12 +1167,10 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
         .shared = 0
     };
     MigrationState *ms = migrate_init(&params);
-    MigrationStatus status;
     ms->to_dst_file = f;
 
     if (migration_is_blocked(errp)) {
-        ret = -EINVAL;
-        goto done;
+        return -EINVAL;
     }
 
     qemu_mutex_unlock_iothread();
@@ -1178,14 +1193,6 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
     if (ret != 0) {
         error_setg_errno(errp, -ret, "Error while writing VM state");
     }
-
-done:
-    if (ret != 0) {
-        status = MIGRATION_STATUS_FAILED;
-    } else {
-        status = MIGRATION_STATUS_COMPLETED;
-    }
-    migrate_set_state(&ms->state, MIGRATION_STATUS_SETUP, status);
     return ret;
 }
 
@@ -1570,36 +1577,39 @@ static int loadvm_postcopy_handle_run(MigrationIncomingState *mis)
 static int loadvm_handle_cmd_packaged(MigrationIncomingState *mis)
 {
     int ret;
-    size_t length;
-    QIOChannelBuffer *bioc;
+    uint8_t *buffer;
+    uint32_t length;
+    QEMUSizedBuffer *qsb;
 
     length = qemu_get_be32(mis->from_src_file);
     trace_loadvm_handle_cmd_packaged(length);
 
     if (length > MAX_VM_CMD_PACKAGED_SIZE) {
-        error_report("Unreasonably large packaged state: %zu", length);
+        error_report("Unreasonably large packaged state: %u", length);
         return -1;
     }
-
-    bioc = qio_channel_buffer_new(length);
-    ret = qemu_get_buffer(mis->from_src_file,
-                          bioc->data,
-                          length);
+    buffer = g_malloc0(length);
+    ret = qemu_get_buffer(mis->from_src_file, buffer, (int)length);
     if (ret != length) {
-        object_unref(OBJECT(bioc));
-        error_report("CMD_PACKAGED: Buffer receive fail ret=%d length=%zu",
+        g_free(buffer);
+        error_report("CMD_PACKAGED: Buffer receive fail ret=%d length=%d",
                      ret, length);
         return (ret < 0) ? ret : -EAGAIN;
     }
-    bioc->usage += length;
     trace_loadvm_handle_cmd_packaged_received(ret);
 
-    QEMUFile *packf = qemu_fopen_channel_input(QIO_CHANNEL(bioc));
+    /* Setup a dummy QEMUFile that actually reads from the buffer */
+    qsb = qsb_create(buffer, length);
+    g_free(buffer); /* Because qsb_create copies */
+    if (!qsb) {
+        error_report("Unable to create qsb");
+    }
+    QEMUFile *packf = qemu_bufopen("r", qsb);
 
     ret = qemu_loadvm_state_main(packf, mis);
     trace_loadvm_handle_cmd_packaged_main(ret);
     qemu_fclose(packf);
-    object_unref(OBJECT(bioc));
+    qsb_free(qsb);
 
     return ret;
 }
@@ -1765,12 +1775,6 @@ qemu_loadvm_section_start_full(QEMUFile *f, MigrationIncomingState *mis)
         return -EINVAL;
     }
 
-    /* Validate if it is a device's state */
-    if (xen_enabled() && se->is_ram) {
-        error_report("loadvm: %s RAM loading not allowed on Xen", idstr);
-        return -EINVAL;
-    }
-
     /* Add entry */
     le = g_malloc0(sizeof(*le));
 
@@ -2056,7 +2060,6 @@ void hmp_savevm(Monitor *mon, const QDict *qdict)
 void qmp_xen_save_devices_state(const char *filename, Error **errp)
 {
     QEMUFile *f;
-    QIOChannelFile *ioc;
     int saved_vm_running;
     int ret;
 
@@ -2064,11 +2067,11 @@ void qmp_xen_save_devices_state(const char *filename, Error **errp)
     vm_stop(RUN_STATE_SAVE_VM);
     global_state_store_running();
 
-    ioc = qio_channel_file_new_path(filename, O_WRONLY | O_CREAT, 0660, errp);
-    if (!ioc) {
+    f = qemu_fopen(filename, "wb");
+    if (!f) {
+        error_setg_file_open(errp, errno, filename);
         goto the_end;
     }
-    f = qemu_fopen_channel_output(QIO_CHANNEL(ioc));
     ret = qemu_save_device_state(f);
     qemu_fclose(f);
     if (ret < 0) {
@@ -2081,36 +2084,6 @@ void qmp_xen_save_devices_state(const char *filename, Error **errp)
     }
 }
 
-void qmp_xen_load_devices_state(const char *filename, Error **errp)
-{
-    QEMUFile *f;
-    QIOChannelFile *ioc;
-    int ret;
-
-    /* Guest must be paused before loading the device state; the RAM state
-     * will already have been loaded by xc
-     */
-    if (runstate_is_running()) {
-        error_setg(errp, "Cannot update device state while vm is running");
-        return;
-    }
-    vm_stop(RUN_STATE_RESTORE_VM);
-
-    ioc = qio_channel_file_new_path(filename, O_RDONLY | O_BINARY, 0, errp);
-    if (!ioc) {
-        return;
-    }
-    f = qemu_fopen_channel_input(QIO_CHANNEL(ioc));
-
-    migration_incoming_state_new(f);
-    ret = qemu_loadvm_state(f);
-    qemu_fclose(f);
-    if (ret < 0) {
-        error_setg(errp, QERR_IO_ERROR);
-    }
-    migration_incoming_state_destroy();
-}
-
 int load_vmstate(const char *name)
 {
     BlockDriverState *bs, *bs_vm_state;
@@ -2200,31 +2173,12 @@ void hmp_delvm(Monitor *mon, const QDict *qdict)
 void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
 {
     BlockDriverState *bs, *bs1;
-    BdrvNextIterator it1;
     QEMUSnapshotInfo *sn_tab, *sn;
-    bool no_snapshot = true;
     int nb_sns, i;
     int total;
-    int *global_snapshots;
+    int *available_snapshots;
     AioContext *aio_context;
 
-    typedef struct SnapshotEntry {
-        QEMUSnapshotInfo sn;
-        QTAILQ_ENTRY(SnapshotEntry) next;
-    } SnapshotEntry;
-
-    typedef struct ImageEntry {
-        const char *imagename;
-        QTAILQ_ENTRY(ImageEntry) next;
-        QTAILQ_HEAD(, SnapshotEntry) snapshots;
-    } ImageEntry;
-
-    QTAILQ_HEAD(, ImageEntry) image_list =
-        QTAILQ_HEAD_INITIALIZER(image_list);
-
-    ImageEntry *image_entry, *next_ie;
-    SnapshotEntry *snapshot_entry;
-
     bs = bdrv_all_find_vmstate_bs();
     if (!bs) {
         monitor_printf(mon, "No available block device supports snapshots\n");
@@ -2241,114 +2195,46 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
         return;
     }
 
-    for (bs1 = bdrv_first(&it1); bs1; bs1 = bdrv_next(&it1)) {
-        int bs1_nb_sns = 0;
-        ImageEntry *ie;
-        SnapshotEntry *se;
-        AioContext *ctx = bdrv_get_aio_context(bs1);
-
-        aio_context_acquire(ctx);
-        if (bdrv_can_snapshot(bs1)) {
-            sn = NULL;
-            bs1_nb_sns = bdrv_snapshot_list(bs1, &sn);
-            if (bs1_nb_sns > 0) {
-                no_snapshot = false;
-                ie = g_new0(ImageEntry, 1);
-                ie->imagename = bdrv_get_device_name(bs1);
-                QTAILQ_INIT(&ie->snapshots);
-                QTAILQ_INSERT_TAIL(&image_list, ie, next);
-                for (i = 0; i < bs1_nb_sns; i++) {
-                    se = g_new0(SnapshotEntry, 1);
-                    se->sn = sn[i];
-                    QTAILQ_INSERT_TAIL(&ie->snapshots, se, next);
-                }
-            }
-            g_free(sn);
-        }
-        aio_context_release(ctx);
-    }
-
-    if (no_snapshot) {
+    if (nb_sns == 0) {
         monitor_printf(mon, "There is no snapshot available.\n");
         return;
     }
 
-    global_snapshots = g_new0(int, nb_sns);
+    available_snapshots = g_new0(int, nb_sns);
     total = 0;
     for (i = 0; i < nb_sns; i++) {
-        SnapshotEntry *next_sn;
-        if (bdrv_all_find_snapshot(sn_tab[i].name, &bs1) == 0) {
-            global_snapshots[total] = i;
+        if (bdrv_all_find_snapshot(sn_tab[i].id_str, &bs1) == 0) {
+            available_snapshots[total] = i;
             total++;
-            QTAILQ_FOREACH(image_entry, &image_list, next) {
-                QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots,
-                                    next, next_sn) {
-                    if (!strcmp(sn_tab[i].name, snapshot_entry->sn.name)) {
-                        QTAILQ_REMOVE(&image_entry->snapshots, snapshot_entry,
-                                      next);
-                        g_free(snapshot_entry);
-                    }
-                }
-            }
         }
     }
 
-    monitor_printf(mon, "List of snapshots present on all disks:\n");
-
     if (total > 0) {
         bdrv_snapshot_dump((fprintf_function)monitor_printf, mon, NULL);
         monitor_printf(mon, "\n");
         for (i = 0; i < total; i++) {
-            sn = &sn_tab[global_snapshots[i]];
-            /* The ID is not guaranteed to be the same on all images, so
-             * overwrite it.
-             */
-            pstrcpy(sn->id_str, sizeof(sn->id_str), "--");
+            sn = &sn_tab[available_snapshots[i]];
             bdrv_snapshot_dump((fprintf_function)monitor_printf, mon, sn);
             monitor_printf(mon, "\n");
         }
     } else {
-        monitor_printf(mon, "None\n");
+        monitor_printf(mon, "There is no suitable snapshot available\n");
     }
 
-    QTAILQ_FOREACH(image_entry, &image_list, next) {
-        if (QTAILQ_EMPTY(&image_entry->snapshots)) {
-            continue;
-        }
-        monitor_printf(mon,
-                       "\nList of partial (non-loadable) snapshots on '%s':\n",
-                       image_entry->imagename);
-        bdrv_snapshot_dump((fprintf_function)monitor_printf, mon, NULL);
-        monitor_printf(mon, "\n");
-        QTAILQ_FOREACH(snapshot_entry, &image_entry->snapshots, next) {
-            bdrv_snapshot_dump((fprintf_function)monitor_printf, mon,
-                               &snapshot_entry->sn);
-            monitor_printf(mon, "\n");
-        }
-    }
-
-    QTAILQ_FOREACH_SAFE(image_entry, &image_list, next, next_ie) {
-        SnapshotEntry *next_sn;
-        QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, next,
-                            next_sn) {
-            g_free(snapshot_entry);
-        }
-        g_free(image_entry);
-    }
     g_free(sn_tab);
-    g_free(global_snapshots);
+    g_free(available_snapshots);
 
 }
 
 void vmstate_register_ram(MemoryRegion *mr, DeviceState *dev)
 {
-    qemu_ram_set_idstr(mr->ram_block,
+    qemu_ram_set_idstr(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK,
                        memory_region_name(mr), dev);
 }
 
 void vmstate_unregister_ram(MemoryRegion *mr, DeviceState *dev)
 {
-    qemu_ram_unset_idstr(mr->ram_block);
+    qemu_ram_unset_idstr(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK);
 }
 
 void vmstate_register_ram_global(MemoryRegion *mr)
diff --git a/migration/socket.c b/migration/socket.c
deleted file mode 100644 (file)
index 00de1fe..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * QEMU live migration via socket
- *
- * Copyright Red Hat, Inc. 2009-2016
- *
- * Authors:
- *  Chris Lalancette <clalance@redhat.com>
- *  Daniel P. Berrange <berrange@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-
-#include "qemu-common.h"
-#include "qemu/error-report.h"
-#include "qapi/error.h"
-#include "migration/migration.h"
-#include "migration/qemu-file.h"
-#include "io/channel-socket.h"
-#include "trace.h"
-
-
-static SocketAddress *tcp_build_address(const char *host_port, Error **errp)
-{
-    InetSocketAddress *iaddr = inet_parse(host_port, errp);
-    SocketAddress *saddr;
-
-    if (!iaddr) {
-        return NULL;
-    }
-
-    saddr = g_new0(SocketAddress, 1);
-    saddr->type = SOCKET_ADDRESS_KIND_INET;
-    saddr->u.inet.data = iaddr;
-
-    return saddr;
-}
-
-
-static SocketAddress *unix_build_address(const char *path)
-{
-    SocketAddress *saddr;
-
-    saddr = g_new0(SocketAddress, 1);
-    saddr->type = SOCKET_ADDRESS_KIND_UNIX;
-    saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
-    saddr->u.q_unix.data->path = g_strdup(path);
-
-    return saddr;
-}
-
-
-struct SocketConnectData {
-    MigrationState *s;
-    char *hostname;
-};
-
-static void socket_connect_data_free(void *opaque)
-{
-    struct SocketConnectData *data = opaque;
-    if (!data) {
-        return;
-    }
-    g_free(data->hostname);
-    g_free(data);
-}
-
-static void socket_outgoing_migration(Object *src,
-                                      Error *err,
-                                      gpointer opaque)
-{
-    struct SocketConnectData *data = opaque;
-    QIOChannel *sioc = QIO_CHANNEL(src);
-
-    if (err) {
-        trace_migration_socket_outgoing_error(error_get_pretty(err));
-        data->s->to_dst_file = NULL;
-        migrate_fd_error(data->s, err);
-    } else {
-        trace_migration_socket_outgoing_connected(data->hostname);
-        migration_channel_connect(data->s, sioc, data->hostname);
-    }
-    object_unref(src);
-}
-
-static void socket_start_outgoing_migration(MigrationState *s,
-                                            SocketAddress *saddr,
-                                            Error **errp)
-{
-    QIOChannelSocket *sioc = qio_channel_socket_new();
-    struct SocketConnectData *data = g_new0(struct SocketConnectData, 1);
-
-    data->s = s;
-    if (saddr->type == SOCKET_ADDRESS_KIND_INET) {
-        data->hostname = g_strdup(saddr->u.inet.data->host);
-    }
-
-    qio_channel_socket_connect_async(sioc,
-                                     saddr,
-                                     socket_outgoing_migration,
-                                     data,
-                                     socket_connect_data_free);
-    qapi_free_SocketAddress(saddr);
-}
-
-void tcp_start_outgoing_migration(MigrationState *s,
-                                  const char *host_port,
-                                  Error **errp)
-{
-    SocketAddress *saddr = tcp_build_address(host_port, errp);
-    socket_start_outgoing_migration(s, saddr, errp);
-}
-
-void unix_start_outgoing_migration(MigrationState *s,
-                                   const char *path,
-                                   Error **errp)
-{
-    SocketAddress *saddr = unix_build_address(path);
-    socket_start_outgoing_migration(s, saddr, errp);
-}
-
-
-static gboolean socket_accept_incoming_migration(QIOChannel *ioc,
-                                                 GIOCondition condition,
-                                                 gpointer opaque)
-{
-    QIOChannelSocket *sioc;
-    Error *err = NULL;
-
-    sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc),
-                                     &err);
-    if (!sioc) {
-        error_report("could not accept migration connection (%s)",
-                     error_get_pretty(err));
-        goto out;
-    }
-
-    trace_migration_socket_incoming_accepted();
-
-    migration_channel_process_incoming(migrate_get_current(),
-                                       QIO_CHANNEL(sioc));
-    object_unref(OBJECT(sioc));
-
-out:
-    /* Close listening socket as its no longer needed */
-    qio_channel_close(ioc, NULL);
-    return FALSE; /* unregister */
-}
-
-
-static void socket_start_incoming_migration(SocketAddress *saddr,
-                                            Error **errp)
-{
-    QIOChannelSocket *listen_ioc = qio_channel_socket_new();
-
-    if (qio_channel_socket_listen_sync(listen_ioc, saddr, errp) < 0) {
-        object_unref(OBJECT(listen_ioc));
-        qapi_free_SocketAddress(saddr);
-        return;
-    }
-
-    qio_channel_add_watch(QIO_CHANNEL(listen_ioc),
-                          G_IO_IN,
-                          socket_accept_incoming_migration,
-                          listen_ioc,
-                          (GDestroyNotify)object_unref);
-    qapi_free_SocketAddress(saddr);
-}
-
-void tcp_start_incoming_migration(const char *host_port, Error **errp)
-{
-    SocketAddress *saddr = tcp_build_address(host_port, errp);
-    socket_start_incoming_migration(saddr, errp);
-}
-
-void unix_start_incoming_migration(const char *path, Error **errp)
-{
-    SocketAddress *saddr = unix_build_address(path);
-    socket_start_incoming_migration(saddr, errp);
-}
diff --git a/migration/tcp.c b/migration/tcp.c
new file mode 100644 (file)
index 0000000..e1fa7f8
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * QEMU live migration
+ *
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "qemu/sockets.h"
+#include "migration/migration.h"
+#include "migration/qemu-file.h"
+#include "block/block.h"
+#include "qemu/main-loop.h"
+
+//#define DEBUG_MIGRATION_TCP
+
+#ifdef DEBUG_MIGRATION_TCP
+#define DPRINTF(fmt, ...) \
+    do { printf("migration-tcp: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+    do { } while (0)
+#endif
+
+static void tcp_wait_for_connect(int fd, Error *err, void *opaque)
+{
+    MigrationState *s = opaque;
+
+    if (fd < 0) {
+        DPRINTF("migrate connect error: %s\n", error_get_pretty(err));
+        s->to_dst_file = NULL;
+        migrate_fd_error(s);
+    } else {
+        DPRINTF("migrate connect success\n");
+        s->to_dst_file = qemu_fopen_socket(fd, "wb");
+        migrate_fd_connect(s);
+    }
+}
+
+void tcp_start_outgoing_migration(MigrationState *s, const char *host_port, Error **errp)
+{
+    inet_nonblocking_connect(host_port, tcp_wait_for_connect, s, errp);
+}
+
+static void tcp_accept_incoming_migration(void *opaque)
+{
+    struct sockaddr_in addr;
+    socklen_t addrlen = sizeof(addr);
+    int s = (intptr_t)opaque;
+    QEMUFile *f;
+    int c;
+
+    do {
+        c = qemu_accept(s, (struct sockaddr *)&addr, &addrlen);
+    } while (c < 0 && errno == EINTR);
+    qemu_set_fd_handler(s, NULL, NULL, NULL);
+    closesocket(s);
+
+    DPRINTF("accepted migration\n");
+
+    if (c < 0) {
+        error_report("could not accept migration connection (%s)",
+                     strerror(errno));
+        return;
+    }
+
+    f = qemu_fopen_socket(c, "rb");
+    if (f == NULL) {
+        error_report("could not qemu_fopen socket");
+        goto out;
+    }
+
+    process_incoming_migration(f);
+    return;
+
+out:
+    closesocket(c);
+}
+
+void tcp_start_incoming_migration(const char *host_port, Error **errp)
+{
+    int s;
+
+    s = inet_listen(host_port, NULL, 256, SOCK_STREAM, 0, errp);
+    if (s < 0) {
+        return;
+    }
+
+    qemu_set_fd_handler(s, tcp_accept_incoming_migration, NULL,
+                        (void *)(intptr_t)s);
+}
diff --git a/migration/tls.c b/migration/tls.c
deleted file mode 100644 (file)
index 12c053d..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * QEMU migration TLS support
- *
- * Copyright (c) 2015 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "migration/migration.h"
-#include "io/channel-tls.h"
-#include "crypto/tlscreds.h"
-#include "qemu/error-report.h"
-#include "qapi/error.h"
-#include "trace.h"
-
-static QCryptoTLSCreds *
-migration_tls_get_creds(MigrationState *s,
-                        QCryptoTLSCredsEndpoint endpoint,
-                        Error **errp)
-{
-    Object *creds;
-    QCryptoTLSCreds *ret;
-
-    creds = object_resolve_path_component(
-        object_get_objects_root(), s->parameters.tls_creds);
-    if (!creds) {
-        error_setg(errp, "No TLS credentials with id '%s'",
-                   s->parameters.tls_creds);
-        return NULL;
-    }
-    ret = (QCryptoTLSCreds *)object_dynamic_cast(
-        creds, TYPE_QCRYPTO_TLS_CREDS);
-    if (!ret) {
-        error_setg(errp, "Object with id '%s' is not TLS credentials",
-                   s->parameters.tls_creds);
-        return NULL;
-    }
-    if (ret->endpoint != endpoint) {
-        error_setg(errp,
-                   "Expected TLS credentials for a %s endpoint",
-                   endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT ?
-                   "client" : "server");
-        return NULL;
-    }
-
-    object_ref(OBJECT(ret));
-    return ret;
-}
-
-
-static void migration_tls_incoming_handshake(Object *src,
-                                             Error *err,
-                                             gpointer opaque)
-{
-    QIOChannel *ioc = QIO_CHANNEL(src);
-
-    if (err) {
-        trace_migration_tls_incoming_handshake_error(error_get_pretty(err));
-        error_report("%s", error_get_pretty(err));
-    } else {
-        trace_migration_tls_incoming_handshake_complete();
-        migration_channel_process_incoming(migrate_get_current(), ioc);
-    }
-    object_unref(OBJECT(ioc));
-}
-
-void migration_tls_channel_process_incoming(MigrationState *s,
-                                            QIOChannel *ioc,
-                                            Error **errp)
-{
-    QCryptoTLSCreds *creds;
-    QIOChannelTLS *tioc;
-
-    creds = migration_tls_get_creds(
-        s, QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, errp);
-    if (!creds) {
-        return;
-    }
-
-    tioc = qio_channel_tls_new_server(
-        ioc, creds,
-        NULL, /* XXX pass ACL name */
-        errp);
-    if (!tioc) {
-        return;
-    }
-
-    trace_migration_tls_incoming_handshake_start();
-    qio_channel_tls_handshake(tioc,
-                              migration_tls_incoming_handshake,
-                              NULL,
-                              NULL);
-}
-
-
-static void migration_tls_outgoing_handshake(Object *src,
-                                             Error *err,
-                                             gpointer opaque)
-{
-    MigrationState *s = opaque;
-    QIOChannel *ioc = QIO_CHANNEL(src);
-
-    if (err) {
-        trace_migration_tls_outgoing_handshake_error(error_get_pretty(err));
-        s->to_dst_file = NULL;
-        migrate_fd_error(s, err);
-    } else {
-        trace_migration_tls_outgoing_handshake_complete();
-        migration_channel_connect(s, ioc, NULL);
-    }
-    object_unref(OBJECT(ioc));
-}
-
-
-void migration_tls_channel_connect(MigrationState *s,
-                                   QIOChannel *ioc,
-                                   const char *hostname,
-                                   Error **errp)
-{
-    QCryptoTLSCreds *creds;
-    QIOChannelTLS *tioc;
-
-    creds = migration_tls_get_creds(
-        s, QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT, errp);
-    if (!creds) {
-        return;
-    }
-
-    if (s->parameters.tls_hostname) {
-        hostname = s->parameters.tls_hostname;
-    }
-    if (!hostname) {
-        error_setg(errp, "No hostname available for TLS");
-        return;
-    }
-
-    tioc = qio_channel_tls_new_client(
-        ioc, creds, hostname, errp);
-    if (!tioc) {
-        return;
-    }
-
-    trace_migration_tls_outgoing_handshake_start(hostname);
-    qio_channel_tls_handshake(tioc,
-                              migration_tls_outgoing_handshake,
-                              s,
-                              NULL);
-}
diff --git a/migration/trace-events b/migration/trace-events
deleted file mode 100644 (file)
index dfee75a..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# migration/savevm.c
-qemu_loadvm_state_section(unsigned int section_type) "%d"
-qemu_loadvm_state_section_command(int ret) "%d"
-qemu_loadvm_state_section_partend(uint32_t section_id) "%u"
-qemu_loadvm_state_main(void) ""
-qemu_loadvm_state_main_quit_parent(void) ""
-qemu_loadvm_state_post_main(int ret) "%d"
-qemu_loadvm_state_section_startfull(uint32_t section_id, const char *idstr, uint32_t instance_id, uint32_t version_id) "%u(%s) %u %u"
-qemu_savevm_send_packaged(void) ""
-loadvm_handle_cmd_packaged(unsigned int length) "%u"
-loadvm_handle_cmd_packaged_main(int ret) "%d"
-loadvm_handle_cmd_packaged_received(int ret) "%d"
-loadvm_postcopy_handle_advise(void) ""
-loadvm_postcopy_handle_listen(void) ""
-loadvm_postcopy_handle_run(void) ""
-loadvm_postcopy_handle_run_cpu_sync(void) ""
-loadvm_postcopy_handle_run_vmstart(void) ""
-loadvm_postcopy_ram_handle_discard(void) ""
-loadvm_postcopy_ram_handle_discard_end(void) ""
-loadvm_postcopy_ram_handle_discard_header(const char *ramid, uint16_t len) "%s: %ud"
-loadvm_process_command(uint16_t com, uint16_t len) "com=0x%x len=%d"
-loadvm_process_command_ping(uint32_t val) "%x"
-postcopy_ram_listen_thread_exit(void) ""
-postcopy_ram_listen_thread_start(void) ""
-qemu_savevm_send_postcopy_advise(void) ""
-qemu_savevm_send_postcopy_ram_discard(const char *id, uint16_t len) "%s: %ud"
-savevm_command_send(uint16_t command, uint16_t len) "com=0x%x len=%d"
-savevm_section_start(const char *id, unsigned int section_id) "%s, section_id %u"
-savevm_section_end(const char *id, unsigned int section_id, int ret) "%s, section_id %u -> %d"
-savevm_section_skip(const char *id, unsigned int section_id) "%s, section_id %u"
-savevm_send_open_return_path(void) ""
-savevm_send_ping(uint32_t val) "%x"
-savevm_send_postcopy_listen(void) ""
-savevm_send_postcopy_run(void) ""
-savevm_state_begin(void) ""
-savevm_state_header(void) ""
-savevm_state_iterate(void) ""
-savevm_state_cleanup(void) ""
-savevm_state_complete_precopy(void) ""
-vmstate_save(const char *idstr, const char *vmsd_name) "%s, %s"
-vmstate_load(const char *idstr, const char *vmsd_name) "%s, %s"
-qemu_announce_self_iter(const char *mac) "%s"
-
-# migration/vmstate.c
-vmstate_load_field_error(const char *field, int ret) "field \"%s\" load failed, ret = %d"
-vmstate_load_state(const char *name, int version_id) "%s v%d"
-vmstate_load_state_end(const char *name, const char *reason, int val) "%s %s/%d"
-vmstate_load_state_field(const char *name, const char *field) "%s:%s"
-vmstate_n_elems(const char *name, int n_elems) "%s: %d"
-vmstate_subsection_load(const char *parent) "%s"
-vmstate_subsection_load_bad(const char *parent,  const char *sub, const char *sub2) "%s: %s/%s"
-vmstate_subsection_load_good(const char *parent) "%s"
-
-# migration/qemu-file.c
-qemu_file_fclose(void) ""
-
-# migration/ram.c
-get_queued_page(const char *block_name, uint64_t tmp_offset, uint64_t ram_addr) "%s/%" PRIx64 " ram_addr=%" PRIx64
-get_queued_page_not_dirty(const char *block_name, uint64_t tmp_offset, uint64_t ram_addr, int sent) "%s/%" PRIx64 " ram_addr=%" PRIx64 " (sent=%d)"
-migration_bitmap_sync_start(void) ""
-migration_bitmap_sync_end(uint64_t dirty_pages) "dirty_pages %" PRIu64
-migration_throttle(void) ""
-ram_load_postcopy_loop(uint64_t addr, int flags) "@%" PRIx64 " %x"
-ram_postcopy_send_discard_bitmap(void) ""
-ram_save_queue_pages(const char *rbname, size_t start, size_t len) "%s: start: %zx len: %zx"
-
-# migration/migration.c
-await_return_path_close_on_source_close(void) ""
-await_return_path_close_on_source_joining(void) ""
-migrate_set_state(int new_state) "new state %d"
-migrate_fd_cleanup(void) ""
-migrate_fd_error(const char *error_desc) "error=%s"
-migrate_fd_cancel(void) ""
-migrate_handle_rp_req_pages(const char *rbname, size_t start, size_t len) "in %s at %zx len %zx"
-migrate_pending(uint64_t size, uint64_t max, uint64_t post, uint64_t nonpost) "pending size %" PRIu64 " max %" PRIu64 " (post=%" PRIu64 " nonpost=%" PRIu64 ")"
-migrate_send_rp_message(int msg_type, uint16_t len) "%d: len %d"
-migration_completion_file_err(void) ""
-migration_completion_postcopy_end(void) ""
-migration_completion_postcopy_end_after_complete(void) ""
-migration_completion_postcopy_end_before_rp(void) ""
-migration_completion_postcopy_end_after_rp(int rp_error) "%d"
-migration_thread_after_loop(void) ""
-migration_thread_file_err(void) ""
-migration_thread_setup_complete(void) ""
-open_return_path_on_source(void) ""
-open_return_path_on_source_continue(void) ""
-postcopy_start(void) ""
-postcopy_start_set_run(void) ""
-source_return_path_thread_bad_end(void) ""
-source_return_path_thread_end(void) ""
-source_return_path_thread_entry(void) ""
-source_return_path_thread_loop_top(void) ""
-source_return_path_thread_pong(uint32_t val) "%x"
-source_return_path_thread_shut(uint32_t val) "%x"
-migrate_global_state_post_load(const char *state) "loaded state: %s"
-migrate_global_state_pre_save(const char *state) "saved state: %s"
-migration_thread_low_pending(uint64_t pending) "%" PRIu64
-migrate_state_too_big(void) ""
-migrate_transferred(uint64_t tranferred, uint64_t time_spent, double bandwidth, uint64_t size) "transferred %" PRIu64 " time_spent %" PRIu64 " bandwidth %g max_size %" PRId64
-process_incoming_migration_co_end(int ret, int ps) "ret=%d postcopy-state=%d"
-process_incoming_migration_co_postcopy_end_main(void) ""
-migration_set_incoming_channel(void *ioc, const char *ioctype) "ioc=%p ioctype=%s"
-migration_set_outgoing_channel(void *ioc, const char *ioctype, const char *hostname)  "ioc=%p ioctype=%s hostname=%s"
-
-# migration/rdma.c
-qemu_rdma_accept_incoming_migration(void) ""
-qemu_rdma_accept_incoming_migration_accepted(void) ""
-qemu_rdma_accept_pin_state(bool pin) "%d"
-qemu_rdma_accept_pin_verbsc(void *verbs) "Verbs context after listen: %p"
-qemu_rdma_block_for_wrid_miss(const char *wcompstr, int wcomp, const char *gcompstr, uint64_t req) "A Wanted wrid %s (%d) but got %s (%" PRIu64 ")"
-qemu_rdma_block_for_wrid_miss_b(const char *wcompstr, int wcomp, const char *gcompstr, uint64_t req) "B Wanted wrid %s (%d) but got %s (%" PRIu64 ")"
-qemu_rdma_cleanup_disconnect(void) ""
-qemu_rdma_cleanup_waiting_for_disconnect(void) ""
-qemu_rdma_close(void) ""
-qemu_rdma_connect_pin_all_requested(void) ""
-qemu_rdma_connect_pin_all_outcome(bool pin) "%d"
-qemu_rdma_dest_init_trying(const char *host, const char *ip) "%s => %s"
-qemu_rdma_dump_gid(const char *who, const char *src, const char *dst) "%s Source GID: %s, Dest GID: %s"
-qemu_rdma_exchange_get_response_start(const char *desc) "CONTROL: %s receiving..."
-qemu_rdma_exchange_get_response_none(const char *desc, int type) "Surprise: got %s (%d)"
-qemu_rdma_exchange_send_issue_callback(void) ""
-qemu_rdma_exchange_send_waiting(const char *desc) "Waiting for response %s"
-qemu_rdma_exchange_send_received(const char *desc) "Response %s received."
-qemu_rdma_fill(size_t control_len, size_t size) "RDMA %zd of %zd bytes already in buffer"
-qemu_rdma_init_ram_blocks(int blocks) "Allocated %d local ram block structures"
-qemu_rdma_poll_recv(const char *compstr, int64_t comp, int64_t id, int sent) "completion %s #%" PRId64 " received (%" PRId64 ") left %d"
-qemu_rdma_poll_write(const char *compstr, int64_t comp, int left, uint64_t block, uint64_t chunk, void *local, void *remote) "completions %s (%" PRId64 ") left %d, block %" PRIu64 ", chunk: %" PRIu64 " %p %p"
-qemu_rdma_poll_other(const char *compstr, int64_t comp, int left) "other completion %s (%" PRId64 ") received left %d"
-qemu_rdma_post_send_control(const char *desc) "CONTROL: sending %s.."
-qemu_rdma_register_and_get_keys(uint64_t len, void *start) "Registering %" PRIu64 " bytes @ %p"
-qemu_rdma_registration_handle_compress(int64_t length, int index, int64_t offset) "Zapping zero chunk: %" PRId64 " bytes, index %d, offset %" PRId64
-qemu_rdma_registration_handle_finished(void) ""
-qemu_rdma_registration_handle_ram_blocks(void) ""
-qemu_rdma_registration_handle_ram_blocks_loop(const char *name, uint64_t offset, uint64_t length, void *local_host_addr, unsigned int src_index) "%s: @%" PRIx64 "/%" PRIu64 " host:@%p src_index: %u"
-qemu_rdma_registration_handle_register(int requests) "%d requests"
-qemu_rdma_registration_handle_register_loop(int req, int index, uint64_t addr, uint64_t chunks) "Registration request (%d): index %d, current_addr %" PRIu64 " chunks: %" PRIu64
-qemu_rdma_registration_handle_register_rkey(int rkey) "%x"
-qemu_rdma_registration_handle_unregister(int requests) "%d requests"
-qemu_rdma_registration_handle_unregister_loop(int count, int index, uint64_t chunk) "Unregistration request (%d): index %d, chunk %" PRIu64
-qemu_rdma_registration_handle_unregister_success(uint64_t chunk) "%" PRIu64
-qemu_rdma_registration_handle_wait(void) ""
-qemu_rdma_registration_start(uint64_t flags) "%" PRIu64
-qemu_rdma_registration_stop(uint64_t flags) "%" PRIu64
-qemu_rdma_registration_stop_ram(void) ""
-qemu_rdma_resolve_host_trying(const char *host, const char *ip) "Trying %s => %s"
-qemu_rdma_signal_unregister_append(uint64_t chunk, int pos) "Appending unregister chunk %" PRIu64 " at position %d"
-qemu_rdma_signal_unregister_already(uint64_t chunk) "Unregister chunk %" PRIu64 " already in queue"
-qemu_rdma_unregister_waiting_inflight(uint64_t chunk) "Cannot unregister inflight chunk: %" PRIu64
-qemu_rdma_unregister_waiting_proc(uint64_t chunk, int pos) "Processing unregister for chunk: %" PRIu64 " at position %d"
-qemu_rdma_unregister_waiting_send(uint64_t chunk) "Sending unregister for chunk: %" PRIu64
-qemu_rdma_unregister_waiting_complete(uint64_t chunk) "Unregister for chunk: %" PRIu64 " complete."
-qemu_rdma_write_flush(int sent) "sent total: %d"
-qemu_rdma_write_one_block(int count, int block, uint64_t chunk, uint64_t current, uint64_t len, int nb_sent, int nb_chunks) "(%d) Not clobbering: block: %d chunk %" PRIu64 " current %" PRIu64 " len %" PRIu64 " %d %d"
-qemu_rdma_write_one_post(uint64_t chunk, long addr, long remote, uint32_t len) "Posting chunk: %" PRIu64 ", addr: %lx remote: %lx, bytes %" PRIu32
-qemu_rdma_write_one_queue_full(void) ""
-qemu_rdma_write_one_recvregres(int mykey, int theirkey, uint64_t chunk) "Received registration result: my key: %x their key %x, chunk %" PRIu64
-qemu_rdma_write_one_sendreg(uint64_t chunk, int len, int index, int64_t offset) "Sending registration request chunk %" PRIu64 " for %d bytes, index: %d, offset: %" PRId64
-qemu_rdma_write_one_top(uint64_t chunks, uint64_t size) "Writing %" PRIu64 " chunks, (%" PRIu64 " MB)"
-qemu_rdma_write_one_zero(uint64_t chunk, int len, int index, int64_t offset) "Entire chunk is zero, sending compress: %" PRIu64 " for %d bytes, index: %d, offset: %" PRId64
-rdma_add_block(const char *block_name, int block, uint64_t addr, uint64_t offset, uint64_t len, uint64_t end, uint64_t bits, int chunks) "Added Block: '%s':%d, addr: %" PRIu64 ", offset: %" PRIu64 " length: %" PRIu64 " end: %" PRIu64 " bits %" PRIu64 " chunks %d"
-rdma_block_notification_handle(const char *name, int index) "%s at %d"
-rdma_delete_block(void *block, uint64_t addr, uint64_t offset, uint64_t len, uint64_t end, uint64_t bits, int chunks) "Deleted Block: %p, addr: %" PRIu64 ", offset: %" PRIu64 " length: %" PRIu64 " end: %" PRIu64 " bits %" PRIu64 " chunks %d"
-rdma_start_incoming_migration(void) ""
-rdma_start_incoming_migration_after_dest_init(void) ""
-rdma_start_incoming_migration_after_rdma_listen(void) ""
-rdma_start_outgoing_migration_after_rdma_connect(void) ""
-rdma_start_outgoing_migration_after_rdma_source_init(void) ""
-
-# migration/postcopy-ram.c
-postcopy_discard_send_finish(const char *ramblock, int nwords, int ncmds) "%s mask words sent=%d in %d commands"
-postcopy_discard_send_range(const char *ramblock, unsigned long start, unsigned long length) "%s:%lx/%lx"
-postcopy_ram_discard_range(void *start, size_t length) "%p,+%zx"
-postcopy_cleanup_range(const char *ramblock, void *host_addr, size_t offset, size_t length) "%s: %p offset=%zx length=%zx"
-postcopy_init_range(const char *ramblock, void *host_addr, size_t offset, size_t length) "%s: %p offset=%zx length=%zx"
-postcopy_nhp_range(const char *ramblock, void *host_addr, size_t offset, size_t length) "%s: %p offset=%zx length=%zx"
-postcopy_place_page(void *host_addr) "host=%p"
-postcopy_place_page_zero(void *host_addr) "host=%p"
-postcopy_ram_enable_notify(void) ""
-postcopy_ram_fault_thread_entry(void) ""
-postcopy_ram_fault_thread_exit(void) ""
-postcopy_ram_fault_thread_quit(void) ""
-postcopy_ram_fault_thread_request(uint64_t hostaddr, const char *ramblock, size_t offset) "Request for HVA=%" PRIx64 " rb=%s offset=%zx"
-postcopy_ram_incoming_cleanup_closeuf(void) ""
-postcopy_ram_incoming_cleanup_entry(void) ""
-postcopy_ram_incoming_cleanup_exit(void) ""
-postcopy_ram_incoming_cleanup_join(void) ""
-
-# migration/exec.c
-migration_exec_outgoing(const char *cmd) "cmd=%s"
-migration_exec_incoming(const char *cmd) "cmd=%s"
-
-# migration/fd.c
-migration_fd_outgoing(int fd) "fd=%d"
-migration_fd_incoming(int fd) "fd=%d"
-
-# migration/socket.c
-migration_socket_incoming_accepted(void) ""
-migration_socket_outgoing_connected(const char *hostname) "hostname=%s"
-migration_socket_outgoing_error(const char *err) "error=%s"
-
-# migration/tls.c
-migration_tls_outgoing_handshake_start(const char *hostname) "hostname=%s"
-migration_tls_outgoing_handshake_error(const char *err) "err=%s"
-migration_tls_outgoing_handshake_complete(void) ""
-migration_tls_incoming_handshake_start(void) ""
-migration_tls_incoming_handshake_error(const char *err) "err=%s"
-migration_tls_incoming_handshake_complete(void) ""
diff --git a/migration/unix.c b/migration/unix.c
new file mode 100644 (file)
index 0000000..d9aac36
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * QEMU live migration via Unix Domain Sockets
+ *
+ * Copyright Red Hat, Inc. 2009
+ *
+ * Authors:
+ *  Chris Lalancette <clalance@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "qemu/sockets.h"
+#include "qemu/main-loop.h"
+#include "migration/migration.h"
+#include "migration/qemu-file.h"
+#include "block/block.h"
+
+//#define DEBUG_MIGRATION_UNIX
+
+#ifdef DEBUG_MIGRATION_UNIX
+#define DPRINTF(fmt, ...) \
+    do { printf("migration-unix: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+    do { } while (0)
+#endif
+
+static void unix_wait_for_connect(int fd, Error *err, void *opaque)
+{
+    MigrationState *s = opaque;
+
+    if (fd < 0) {
+        DPRINTF("migrate connect error: %s\n", error_get_pretty(err));
+        s->to_dst_file = NULL;
+        migrate_fd_error(s);
+    } else {
+        DPRINTF("migrate connect success\n");
+        s->to_dst_file = qemu_fopen_socket(fd, "wb");
+        migrate_fd_connect(s);
+    }
+}
+
+void unix_start_outgoing_migration(MigrationState *s, const char *path, Error **errp)
+{
+    unix_nonblocking_connect(path, unix_wait_for_connect, s, errp);
+}
+
+static void unix_accept_incoming_migration(void *opaque)
+{
+    struct sockaddr_un addr;
+    socklen_t addrlen = sizeof(addr);
+    int s = (intptr_t)opaque;
+    QEMUFile *f;
+    int c, err;
+
+    do {
+        c = qemu_accept(s, (struct sockaddr *)&addr, &addrlen);
+        err = errno;
+    } while (c < 0 && err == EINTR);
+    qemu_set_fd_handler(s, NULL, NULL, NULL);
+    close(s);
+
+    DPRINTF("accepted migration\n");
+
+    if (c < 0) {
+        error_report("could not accept migration connection (%s)",
+                     strerror(err));
+        return;
+    }
+
+    f = qemu_fopen_socket(c, "rb");
+    if (f == NULL) {
+        error_report("could not qemu_fopen socket");
+        goto out;
+    }
+
+    process_incoming_migration(f);
+    return;
+
+out:
+    close(c);
+}
+
+void unix_start_incoming_migration(const char *path, Error **errp)
+{
+    int s;
+
+    s = unix_listen(path, NULL, 0, errp);
+    if (s < 0) {
+        return;
+    }
+
+    qemu_set_fd_handler(s, unix_accept_incoming_migration, NULL,
+                        (void *)(intptr_t)s);
+}
index fc29acf..bf3d5db 100644 (file)
@@ -6,6 +6,7 @@
 #include "qemu/bitops.h"
 #include "qemu/error-report.h"
 #include "trace.h"
+#include "qjson.h"
 
 static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
                                     void *opaque, QJSON *vmdesc);
@@ -32,7 +33,6 @@ static int vmstate_n_elems(void *opaque, VMStateField *field)
         n_elems *= field->num;
     }
 
-    trace_vmstate_n_elems(field->name, n_elems);
     return n_elems;
 }
 
@@ -382,25 +382,25 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
         len = qemu_peek_byte(f, 1);
         if (len < strlen(vmsd->name) + 1) {
             /* subsection name has be be "section_name/a" */
-            trace_vmstate_subsection_load_bad(vmsd->name, "(short)", "");
+            trace_vmstate_subsection_load_bad(vmsd->name, "(short)");
             return 0;
         }
         size = qemu_peek_buffer(f, (uint8_t **)&idstr_ret, len, 2);
         if (size != len) {
-            trace_vmstate_subsection_load_bad(vmsd->name, "(peek fail)", "");
+            trace_vmstate_subsection_load_bad(vmsd->name, "(peek fail)");
             return 0;
         }
         memcpy(idstr, idstr_ret, size);
         idstr[size] = 0;
 
         if (strncmp(vmsd->name, idstr, strlen(vmsd->name)) != 0) {
-            trace_vmstate_subsection_load_bad(vmsd->name, idstr, "(prefix)");
-            /* it doesn't have a valid subsection name */
+            trace_vmstate_subsection_load_bad(vmsd->name, idstr);
+            /* it don't have a valid subsection name */
             return 0;
         }
         sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr);
         if (sub_vmsd == NULL) {
-            trace_vmstate_subsection_load_bad(vmsd->name, idstr, "(lookup)");
+            trace_vmstate_subsection_load_bad(vmsd->name, "(lookup)");
             return -ENOENT;
         }
         qemu_file_skip(f, 1); /* subsection */
@@ -410,7 +410,7 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
 
         ret = vmstate_load_state(f, sub_vmsd, opaque, version_id);
         if (ret) {
-            trace_vmstate_subsection_load_bad(vmsd->name, idstr, "(child)");
+            trace_vmstate_subsection_load_bad(vmsd->name, "(child)");
             return ret;
         }
     }
index 5c00373..d1c1930 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -23,8 +23,6 @@
  */
 #include "qemu/osdep.h"
 #include <dirent.h>
-#include "qemu-common.h"
-#include "cpu.h"
 #include "hw/hw.h"
 #include "monitor/qdev.h"
 #include "hw/usb.h"
 #include "qemu/acl.h"
 #include "sysemu/tpm.h"
 #include "qapi/qmp/qerror.h"
-#include "qapi/qmp/types.h"
+#include "qapi/qmp/qint.h"
+#include "qapi/qmp/qfloat.h"
+#include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qstring.h"
 #include "qapi/qmp/qjson.h"
 #include "qapi/qmp/json-streamer.h"
 #include "qapi/qmp/json-parser.h"
-#include "qom/object_interfaces.h"
+#include <qom/object_interfaces.h>
 #include "cpu.h"
 #include "trace.h"
 #include "trace/control.h"
@@ -67,8 +69,6 @@
 #include "trace/simple.h"
 #endif
 #include "exec/memory.h"
-#include "exec/exec-all.h"
-#include "qemu/log.h"
 #include "qmp-commands.h"
 #include "hmp.h"
 #include "qemu/thread.h"
@@ -316,7 +316,7 @@ static void monitor_flush_locked(Monitor *mon)
             return;
         }
         if (rc > 0) {
-            /* partial write */
+            /* partinal write */
             QString *tmp = qstring_from_str(buf + rc);
             QDECREF(mon->outbuf);
             mon->outbuf = tmp;
@@ -635,13 +635,6 @@ static void monitor_data_init(Monitor *mon)
 
 static void monitor_data_destroy(Monitor *mon)
 {
-    if (mon->chr) {
-        qemu_chr_add_handlers(mon->chr, NULL, NULL, NULL, NULL);
-    }
-    if (monitor_is_qmp(mon)) {
-        json_message_parser_destroy(&mon->qmp.parser);
-    }
-    g_free(mon->rs);
     QDECREF(mon->outbuf);
     qemu_mutex_destroy(&mon->out_lock);
 }
@@ -911,16 +904,9 @@ static void hmp_trace_event(Monitor *mon, const QDict *qdict)
 {
     const char *tp_name = qdict_get_str(qdict, "name");
     bool new_state = qdict_get_bool(qdict, "option");
-    bool has_vcpu = qdict_haskey(qdict, "vcpu");
-    int vcpu = qdict_get_try_int(qdict, "vcpu", 0);
     Error *local_err = NULL;
 
-    if (vcpu < 0) {
-        monitor_printf(mon, "argument vcpu must be positive");
-        return;
-    }
-
-    qmp_trace_event_set_state(tp_name, new_state, true, true, has_vcpu, vcpu, &local_err);
+    qmp_trace_event_set_state(tp_name, new_state, true, true, &local_err);
     if (local_err) {
         error_report_err(local_err);
     }
@@ -1079,26 +1065,8 @@ static void hmp_info_cpustats(Monitor *mon, const QDict *qdict)
 
 static void hmp_info_trace_events(Monitor *mon, const QDict *qdict)
 {
-    const char *name = qdict_get_try_str(qdict, "name");
-    bool has_vcpu = qdict_haskey(qdict, "vcpu");
-    int vcpu = qdict_get_try_int(qdict, "vcpu", 0);
-    TraceEventInfoList *events;
+    TraceEventInfoList *events = qmp_trace_event_get_state("*", NULL);
     TraceEventInfoList *elem;
-    Error *local_err = NULL;
-
-    if (name == NULL) {
-        name = "*";
-    }
-    if (vcpu < 0) {
-        monitor_printf(mon, "argument vcpu must be positive");
-        return;
-    }
-
-    events = qmp_trace_event_get_state(name, has_vcpu, vcpu, &local_err);
-    if (local_err) {
-        error_report_err(local_err);
-        return;
-    }
 
     for (elem = events; elem != NULL; elem = elem->next) {
         monitor_printf(mon, "%s : state %u\n",
@@ -1139,12 +1107,7 @@ void qmp_client_migrate_info(const char *protocol, const char *hostname,
 
 static void hmp_logfile(Monitor *mon, const QDict *qdict)
 {
-    Error *err = NULL;
-
-    qemu_set_log_filename(qdict_get_str(qdict, "filename"), &err);
-    if (err) {
-        error_report_err(err);
-    }
+    qemu_set_log_filename(qdict_get_str(qdict, "filename"));
 }
 
 static void hmp_log(Monitor *mon, const QDict *qdict)
@@ -3087,8 +3050,8 @@ void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str)
     }
     len = strlen(str);
     readline_set_completion_index(rs, len);
-    for (i = 0; NetClientDriver_lookup[i]; i++) {
-        add_completion_option(rs, str, NetClientDriver_lookup[i]);
+    for (i = 0; NetClientOptionsKind_lookup[i]; i++) {
+        add_completion_option(rs, str, NetClientOptionsKind_lookup[i]);
     }
 }
 
@@ -3288,7 +3251,7 @@ void set_link_completion(ReadLineState *rs, int nb_args, const char *str)
         NetClientState *ncs[MAX_QUEUE_NUM];
         int count, i;
         count = qemu_find_net_clients_except(NULL, ncs,
-                                             NET_CLIENT_DRIVER_NONE,
+                                             NET_CLIENT_OPTIONS_KIND_NONE,
                                              MAX_QUEUE_NUM);
         for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
             const char *name = ncs[i]->name;
@@ -3313,7 +3276,7 @@ void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str)
 
     len = strlen(str);
     readline_set_completion_index(rs, len);
-    count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_DRIVER_NIC,
+    count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_OPTIONS_KIND_NIC,
                                          MAX_QUEUE_NUM);
     for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
         QemuOpts *opts;
@@ -3328,23 +3291,6 @@ void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str)
     }
 }
 
-void info_trace_events_completion(ReadLineState *rs, int nb_args, const char *str)
-{
-    size_t len;
-
-    len = strlen(str);
-    readline_set_completion_index(rs, len);
-    if (nb_args == 2) {
-        TraceEventID id;
-        for (id = 0; id < trace_event_count(); id++) {
-            const char *event_name = trace_event_get_name(trace_event_id(id));
-            if (!strncmp(str, event_name, len)) {
-                readline_add_completion(rs, event_name);
-            }
-        }
-    }
-}
-
 void trace_event_completion(ReadLineState *rs, int nb_args, const char *str)
 {
     size_t len;
@@ -3442,7 +3388,7 @@ void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str)
     readline_set_completion_index(rs, len);
     if (nb_args == 2) {
         count = qemu_find_net_clients_except(NULL, ncs,
-                                             NET_CLIENT_DRIVER_NONE,
+                                             NET_CLIENT_OPTIONS_KIND_NONE,
                                              MAX_QUEUE_NUM);
         for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
             int id;
@@ -3459,13 +3405,13 @@ void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str)
         return;
     } else if (nb_args == 3) {
         count = qemu_find_net_clients_except(NULL, ncs,
-                                             NET_CLIENT_DRIVER_NIC,
+                                             NET_CLIENT_OPTIONS_KIND_NIC,
                                              MAX_QUEUE_NUM);
         for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
             int id;
             const char *name;
 
-            if (ncs[i]->info->type == NET_CLIENT_DRIVER_HUBPORT ||
+            if (ncs[i]->info->type == NET_CLIENT_OPTIONS_KIND_HUBPORT ||
                 net_hub_id_for_client(ncs[i], &id)) {
                 continue;
             }
@@ -3481,13 +3427,11 @@ void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str)
 static void vm_completion(ReadLineState *rs, const char *str)
 {
     size_t len;
-    BlockDriverState *bs;
-    BdrvNextIterator it;
+    BlockDriverState *bs = NULL;
 
     len = strlen(str);
     readline_set_completion_index(rs, len);
-
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+    while ((bs = bdrv_next(bs))) {
         SnapshotInfoList *snapshots, *snapshot;
         AioContext *ctx = bdrv_get_aio_context(bs);
         bool ok = false;
@@ -4142,6 +4086,15 @@ static void sortcmdlist(void)
     qsort((void *)info_cmds, array_num, elem_size, compare_mon_cmd);
 }
 
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 8
+ * End:
+ */
+
 /* These functions just adapt the readline interface in a typesafe way.  We
  * could cast function pointers but that discards compiler checks.
  */
@@ -4203,19 +4156,6 @@ void monitor_init(CharDriverState *chr, int flags)
     qemu_mutex_unlock(&monitor_lock);
 }
 
-void monitor_cleanup(void)
-{
-    Monitor *mon, *next;
-
-    qemu_mutex_lock(&monitor_lock);
-    QLIST_FOREACH_SAFE(mon, &mon_list, entry, next) {
-        QLIST_REMOVE(mon, entry);
-        monitor_data_destroy(mon);
-        g_free(mon);
-    }
-    qemu_mutex_unlock(&monitor_lock);
-}
-
 static void bdrv_password_cb(void *opaque, const char *password,
                              void *readline_opaque)
 {
@@ -4327,16 +4267,3 @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
     return NULL;
 }
 #endif
-
-HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
-{
-    MachineState *ms = MACHINE(qdev_get_machine());
-    MachineClass *mc = MACHINE_GET_CLASS(ms);
-
-    if (!mc->query_hotpluggable_cpus) {
-        error_setg(errp, QERR_FEATURE_DISABLED, "query-hotpluggable-cpus");
-        return NULL;
-    }
-
-    return mc->query_hotpluggable_cpus(ms);
-}
index a92f1e2..1a01b6c 100644 (file)
@@ -33,10 +33,8 @@ static int nbd_errno_to_system_errno(int err)
         return ENOMEM;
     case NBD_ENOSPC:
         return ENOSPC;
-    default:
-        TRACE("Squashing unexpected error %d to EINVAL", err);
-        /* fallthrough */
     case NBD_EINVAL:
+    default:
         return EINVAL;
     }
 }
@@ -210,7 +208,7 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp)
             error_setg(errp, "incorrect option name length");
             return -1;
         }
-        if (namelen > NBD_MAX_NAME_SIZE) {
+        if (namelen > 255) {
             error_setg(errp, "export name length too long %" PRIu32, namelen);
             return -1;
         }
@@ -597,15 +595,9 @@ fail:
 #ifdef __linux__
 int nbd_init(int fd, QIOChannelSocket *sioc, uint16_t flags, off_t size)
 {
-    unsigned long sectors = size / BDRV_SECTOR_SIZE;
-    if (size / BDRV_SECTOR_SIZE != sectors) {
-        LOG("Export size %lld too large for 32-bit kernel", (long long) size);
-        return -E2BIG;
-    }
-
     TRACE("Setting NBD socket");
 
-    if (ioctl(fd, NBD_SET_SOCK, (unsigned long) sioc->fd) < 0) {
+    if (ioctl(fd, NBD_SET_SOCK, sioc->fd) < 0) {
         int serrno = errno;
         LOG("Failed to set NBD socket");
         return -serrno;
@@ -613,25 +605,21 @@ int nbd_init(int fd, QIOChannelSocket *sioc, uint16_t flags, off_t size)
 
     TRACE("Setting block size to %lu", (unsigned long)BDRV_SECTOR_SIZE);
 
-    if (ioctl(fd, NBD_SET_BLKSIZE, (unsigned long)BDRV_SECTOR_SIZE) < 0) {
+    if (ioctl(fd, NBD_SET_BLKSIZE, (size_t)BDRV_SECTOR_SIZE) < 0) {
         int serrno = errno;
         LOG("Failed setting NBD block size");
         return -serrno;
     }
 
-    TRACE("Setting size to %lu block(s)", sectors);
-    if (size % BDRV_SECTOR_SIZE) {
-        TRACE("Ignoring trailing %d bytes of export",
-              (int) (size % BDRV_SECTOR_SIZE));
-    }
+    TRACE("Setting size to %zd block(s)", (size_t)(size / BDRV_SECTOR_SIZE));
 
-    if (ioctl(fd, NBD_SET_SIZE_BLOCKS, sectors) < 0) {
+    if (ioctl(fd, NBD_SET_SIZE_BLOCKS, (size_t)(size / BDRV_SECTOR_SIZE)) < 0) {
         int serrno = errno;
         LOG("Failed setting size (in blocks)");
         return -serrno;
     }
 
-    if (ioctl(fd, NBD_SET_FLAGS, (unsigned long) flags) < 0) {
+    if (ioctl(fd, NBD_SET_FLAGS, flags) < 0) {
         if (errno == ENOTTY) {
             int read_only = (flags & NBD_FLAG_READ_ONLY) != 0;
             TRACE("Setting readonly attribute");
@@ -681,15 +669,6 @@ int nbd_client(int fd)
     errno = serrno;
     return ret;
 }
-
-int nbd_disconnect(int fd)
-{
-    ioctl(fd, NBD_CLEAR_QUE);
-    ioctl(fd, NBD_DISCONNECT);
-    ioctl(fd, NBD_CLEAR_SOCK);
-    return 0;
-}
-
 #else
 int nbd_init(int fd, QIOChannelSocket *ioc, uint16_t flags, off_t size)
 {
@@ -700,10 +679,6 @@ int nbd_client(int fd)
 {
     return -ENOTSUP;
 }
-int nbd_disconnect(int fd)
-{
-    return -ENOTSUP;
-}
 #endif
 
 ssize_t nbd_send_request(QIOChannel *ioc, struct nbd_request *request)
@@ -713,14 +688,14 @@ ssize_t nbd_send_request(QIOChannel *ioc, struct nbd_request *request)
 
     TRACE("Sending request to server: "
           "{ .from = %" PRIu64", .len = %" PRIu32 ", .handle = %" PRIu64
-          ", .type=%" PRIu32 " }",
+          ", .type=%" PRIu16 " }",
           request->from, request->len, request->handle, request->type);
 
-    stl_be_p(buf, NBD_REQUEST_MAGIC);
-    stl_be_p(buf + 4, request->type);
-    stq_be_p(buf + 8, request->handle);
-    stq_be_p(buf + 16, request->from);
-    stl_be_p(buf + 24, request->len);
+    cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC);
+    cpu_to_be32w((uint32_t*)(buf + 4), request->type);
+    cpu_to_be64w((uint64_t*)(buf + 8), request->handle);
+    cpu_to_be64w((uint64_t*)(buf + 16), request->from);
+    cpu_to_be32w((uint32_t*)(buf + 24), request->len);
 
     ret = write_sync(ioc, buf, sizeof(buf));
     if (ret < 0) {
index b583a4f..8ddb2dd 100644 (file)
@@ -23,6 +23,7 @@
 ssize_t nbd_wr_syncv(QIOChannel *ioc,
                      struct iovec *iov,
                      size_t niov,
+                     size_t offset,
                      size_t length,
                      bool do_read)
 {
@@ -32,7 +33,9 @@ ssize_t nbd_wr_syncv(QIOChannel *ioc,
     struct iovec *local_iov_head = local_iov;
     unsigned int nlocal_iov = niov;
 
-    nlocal_iov = iov_copy(local_iov, nlocal_iov, iov, niov, 0, length);
+    nlocal_iov = iov_copy(local_iov, nlocal_iov,
+                          iov, niov,
+                          offset, length);
 
     while (nlocal_iov > 0) {
         ssize_t len;
index 93a6ca8..3791535 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/fs.h>
 #endif
 
-#include "qemu/bswap.h"
 #include "qemu/queue.h"
 #include "qemu/main-loop.h"
 
@@ -101,14 +100,14 @@ static inline ssize_t read_sync(QIOChannel *ioc, void *buffer, size_t size)
      * our request/reply.  Synchronization is done with recv_coroutine, so
      * that this is coroutine-safe.
      */
-    return nbd_wr_syncv(ioc, &iov, 1, size, true);
+    return nbd_wr_syncv(ioc, &iov, 1, 0, size, true);
 }
 
 static inline ssize_t write_sync(QIOChannel *ioc, void *buffer, size_t size)
 {
     struct iovec iov = { .iov_base = buffer, .iov_len = size };
 
-    return nbd_wr_syncv(ioc, &iov, 1, size, false);
+    return nbd_wr_syncv(ioc, &iov, 1, 0, size, false);
 }
 
 struct NBDTLSHandshakeData {
index 80fbb4d..6f83beb 100644 (file)
@@ -52,7 +52,6 @@ struct NBDRequest {
     QSIMPLEQ_ENTRY(NBDRequest) entry;
     NBDClient *client;
     uint8_t *data;
-    bool complete;
 };
 
 struct NBDExport {
@@ -106,7 +105,7 @@ static gboolean nbd_negotiate_continue(QIOChannel *ioc,
                                        GIOCondition condition,
                                        void *opaque)
 {
-    qemu_coroutine_enter(opaque);
+    qemu_coroutine_enter(opaque, NULL);
     return TRUE;
 }
 
@@ -286,13 +285,13 @@ static int nbd_negotiate_handle_list(NBDClient *client, uint32_t length)
 static int nbd_negotiate_handle_export_name(NBDClient *client, uint32_t length)
 {
     int rc = -EINVAL;
-    char name[NBD_MAX_NAME_SIZE + 1];
+    char name[256];
 
     /* Client sends:
         [20 ..  xx]   export name (length bytes)
      */
     TRACE("Checking length");
-    if (length >= sizeof(name)) {
+    if (length > 255) {
         LOG("Bad length received");
         goto fail;
     }
@@ -335,10 +334,7 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
         return NULL;
     }
 
-    if (nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK,
-                               NBD_OPT_STARTTLS) < 0) {
-        return NULL;
-    }
+    nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK, NBD_OPT_STARTTLS);
 
     tioc = qio_channel_tls_new_server(ioc,
                                       client->tlscreds,
@@ -464,11 +460,8 @@ static int nbd_negotiate_options(NBDClient *client)
                 if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
                     return -EIO;
                 }
-                ret = nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_TLS_REQD,
-                                             clientflags);
-                if (ret < 0) {
-                    return ret;
-                }
+                nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_TLS_REQD,
+                                       clientflags);
                 break;
             }
         } else if (fixedNewstyle) {
@@ -492,17 +485,12 @@ static int nbd_negotiate_options(NBDClient *client)
                 }
                 if (client->tlscreds) {
                     TRACE("TLS already enabled");
-                    ret = nbd_negotiate_send_rep(client->ioc,
-                                                 NBD_REP_ERR_INVALID,
-                                                 clientflags);
+                    nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_INVALID,
+                                           clientflags);
                 } else {
                     TRACE("TLS not configured");
-                    ret = nbd_negotiate_send_rep(client->ioc,
-                                                 NBD_REP_ERR_POLICY,
-                                                 clientflags);
-                }
-                if (ret < 0) {
-                    return ret;
+                    nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_POLICY,
+                                           clientflags);
                 }
                 break;
             default:
@@ -510,11 +498,8 @@ static int nbd_negotiate_options(NBDClient *client)
                 if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
                     return -EIO;
                 }
-                ret = nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_UNSUP,
-                                             clientflags);
-                if (ret < 0) {
-                    return ret;
-                }
+                nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_UNSUP,
+                                       clientflags);
                 break;
             }
         } else {
@@ -622,6 +607,24 @@ fail:
     return rc;
 }
 
+#ifdef __linux__
+
+int nbd_disconnect(int fd)
+{
+    ioctl(fd, NBD_CLEAR_QUE);
+    ioctl(fd, NBD_DISCONNECT);
+    ioctl(fd, NBD_CLEAR_SOCK);
+    return 0;
+}
+
+#else
+
+int nbd_disconnect(int fd)
+{
+    return -ENOTSUP;
+}
+#endif
+
 static ssize_t nbd_receive_request(QIOChannel *ioc, struct nbd_request *request)
 {
     uint8_t buf[NBD_REQUEST_SIZE];
@@ -970,13 +973,7 @@ static ssize_t nbd_co_send_reply(NBDRequest *req, struct nbd_reply *reply,
     return rc;
 }
 
-/* Collect a client request.  Return 0 if request looks valid, -EAGAIN
- * to keep trying the collection, -EIO to drop connection right away,
- * and any other negative value to report an error to the client
- * (although the caller may still need to disconnect after reporting
- * the error).  */
-static ssize_t nbd_co_receive_request(NBDRequest *req,
-                                      struct nbd_request *request)
+static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *request)
 {
     NBDClient *client = req->client;
     uint32_t command;
@@ -994,31 +991,16 @@ static ssize_t nbd_co_receive_request(NBDRequest *req,
         goto out;
     }
 
-    TRACE("Decoding type");
-
-    command = request->type & NBD_CMD_MASK_COMMAND;
-    if (command != NBD_CMD_WRITE) {
-        /* No payload, we are ready to read the next request.  */
-        req->complete = true;
-    }
-
-    if (command == NBD_CMD_DISC) {
-        /* Special case: we're going to disconnect without a reply,
-         * whether or not flags, from, or len are bogus */
-        TRACE("Request type is DISCONNECT");
-        rc = -EIO;
-        goto out;
-    }
-
-    /* Check for sanity in the parameters, part 1.  Defer as many
-     * checks as possible until after reading any NBD_CMD_WRITE
-     * payload, so we can try and keep the connection alive.  */
     if ((request->from + request->len) < request->from) {
-        LOG("integer overflow detected, you're probably being attacked");
+        LOG("integer overflow detected! "
+            "you're probably being attacked");
         rc = -EINVAL;
         goto out;
     }
 
+    TRACE("Decoding type");
+
+    command = request->type & NBD_CMD_MASK_COMMAND;
     if (command == NBD_CMD_READ || command == NBD_CMD_WRITE) {
         if (request->len > NBD_MAX_BUFFER_SIZE) {
             LOG("len (%" PRIu32" ) is larger than max len (%u)",
@@ -1041,24 +1023,7 @@ static ssize_t nbd_co_receive_request(NBDRequest *req,
             rc = -EIO;
             goto out;
         }
-        req->complete = true;
     }
-
-    /* Sanity checks, part 2. */
-    if (request->from + request->len > client->exp->size) {
-        LOG("operation past EOF; From: %" PRIu64 ", Len: %" PRIu32
-            ", Size: %" PRIu64, request->from, request->len,
-            (uint64_t)client->exp->size);
-        rc = command == NBD_CMD_WRITE ? -ENOSPC : -EINVAL;
-        goto out;
-    }
-    if (request->type & ~NBD_CMD_MASK_COMMAND & ~NBD_CMD_FLAG_FUA) {
-        LOG("unsupported flags (got 0x%x)",
-            request->type & ~NBD_CMD_MASK_COMMAND);
-        rc = -EINVAL;
-        goto out;
-    }
-
     rc = 0;
 
 out:
@@ -1077,7 +1042,6 @@ static void nbd_trip(void *opaque)
     struct nbd_reply reply;
     ssize_t ret;
     uint32_t command;
-    int flags;
 
     TRACE("Reading request.");
     if (client->closing) {
@@ -1101,6 +1065,14 @@ static void nbd_trip(void *opaque)
         goto error_reply;
     }
     command = request.type & NBD_CMD_MASK_COMMAND;
+    if (command != NBD_CMD_DISC && (request.from + request.len) > exp->size) {
+            LOG("From: %" PRIu64 ", Len: %" PRIu32", Size: %" PRIu64
+                ", Offset: %" PRIu64 "\n",
+                request.from, request.len,
+                (uint64_t)exp->size, (uint64_t)exp->dev_offset);
+        LOG("requested operation past EOF--bad client?");
+        goto invalid_request;
+    }
 
     if (client->closing) {
         /*
@@ -1146,27 +1118,31 @@ static void nbd_trip(void *opaque)
 
         TRACE("Writing to device");
 
-        flags = 0;
-        if (request.type & NBD_CMD_FLAG_FUA) {
-            flags |= BDRV_REQ_FUA;
-        }
         ret = blk_pwrite(exp->blk, request.from + exp->dev_offset,
-                         req->data, request.len, flags);
+                        req->data, request.len);
         if (ret < 0) {
             LOG("writing to file failed");
             reply.error = -ret;
             goto error_reply;
         }
 
+        if (request.type & NBD_CMD_FLAG_FUA) {
+            ret = blk_co_flush(exp->blk);
+            if (ret < 0) {
+                LOG("flush failed");
+                reply.error = -ret;
+                goto error_reply;
+            }
+        }
+
         if (nbd_co_send_reply(req, &reply, 0) < 0) {
             goto out;
         }
         break;
-
     case NBD_CMD_DISC:
-        /* unreachable, thanks to special case in nbd_co_receive_request() */
-        abort();
-
+        TRACE("Request type is DISCONNECT");
+        errno = 0;
+        goto out;
     case NBD_CMD_FLUSH:
         TRACE("Request type is FLUSH");
 
@@ -1181,11 +1157,20 @@ static void nbd_trip(void *opaque)
         break;
     case NBD_CMD_TRIM:
         TRACE("Request type is TRIM");
-        ret = blk_co_pdiscard(exp->blk, request.from + exp->dev_offset,
-                              request.len);
-        if (ret < 0) {
-            LOG("discard failed");
-            reply.error = -ret;
+        /* Ignore unaligned head or tail, until block layer adds byte
+         * interface */
+        if (request.len >= BDRV_SECTOR_SIZE) {
+            request.len -= (request.from + request.len) % BDRV_SECTOR_SIZE;
+            ret = blk_co_discard(exp->blk,
+                                 DIV_ROUND_UP(request.from + exp->dev_offset,
+                                              BDRV_SECTOR_SIZE),
+                                 request.len / BDRV_SECTOR_SIZE);
+            if (ret < 0) {
+                LOG("discard failed");
+                reply.error = -ret;
+            }
+        } else {
+            TRACE("trim request too small, ignoring");
         }
         if (nbd_co_send_reply(req, &reply, 0) < 0) {
             goto out;
@@ -1193,12 +1178,10 @@ static void nbd_trip(void *opaque)
         break;
     default:
         LOG("invalid request type (%" PRIu32 ") received", request.type);
+    invalid_request:
         reply.error = EINVAL;
     error_reply:
-        /* We must disconnect after NBD_CMD_WRITE if we did not
-         * read the payload.
-         */
-        if (nbd_co_send_reply(req, &reply, 0) < 0 || !req->complete) {
+        if (nbd_co_send_reply(req, &reply, 0) < 0) {
             goto out;
         }
         break;
@@ -1220,9 +1203,9 @@ static void nbd_read(void *opaque)
     NBDClient *client = opaque;
 
     if (client->recv_coroutine) {
-        qemu_coroutine_enter(client->recv_coroutine);
+        qemu_coroutine_enter(client->recv_coroutine, NULL);
     } else {
-        qemu_coroutine_enter(qemu_coroutine_create(nbd_trip, client));
+        qemu_coroutine_enter(qemu_coroutine_create(nbd_trip), client);
     }
 }
 
@@ -1230,7 +1213,7 @@ static void nbd_restart_write(void *opaque)
 {
     NBDClient *client = opaque;
 
-    qemu_coroutine_enter(client->send_coroutine);
+    qemu_coroutine_enter(client->send_coroutine, NULL);
 }
 
 static void nbd_set_handlers(NBDClient *client)
@@ -1314,6 +1297,6 @@ void nbd_client_new(NBDExport *exp,
     client->close = close_fn;
 
     data->client = client;
-    data->co = qemu_coroutine_create(nbd_co_client_start, data);
-    qemu_coroutine_enter(data->co);
+    data->co = qemu_coroutine_create(nbd_co_client_start);
+    qemu_coroutine_enter(data->co, data);
 }
index 23323b0..d0fa424 100644 (file)
@@ -18,7 +18,9 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "net/checksum.h"
-#include "net/eth.h"
+
+#define PROTO_TCP  6
+#define PROTO_UDP 17
 
 uint32_t net_checksum_add_cont(int len, uint8_t *buf, int seq)
 {
@@ -55,118 +57,50 @@ uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
 
 void net_checksum_calculate(uint8_t *data, int length)
 {
-    int mac_hdr_len, ip_len;
-    struct ip_header *ip;
-
-    /*
-     * Note: We cannot assume "data" is aligned, so the all code uses
-     * some macros that take care of possible unaligned access for
-     * struct members (just in case).
-     */
+    int hlen, plen, proto, csum_offset;
+    uint16_t csum;
 
-    /* Ensure we have at least an Eth header */
-    if (length < sizeof(struct eth_header)) {
+    /* Ensure data has complete L2 & L3 headers. */
+    if (length < 14 + 20) {
         return;
     }
 
-    /* Handle the optionnal VLAN headers */
-    switch (lduw_be_p(&PKT_GET_ETH_HDR(data)->h_proto)) {
-    case ETH_P_VLAN:
-        mac_hdr_len = sizeof(struct eth_header) +
-                     sizeof(struct vlan_header);
-        break;
-    case ETH_P_DVLAN:
-        if (lduw_be_p(&PKT_GET_VLAN_HDR(data)->h_proto) == ETH_P_VLAN) {
-            mac_hdr_len = sizeof(struct eth_header) +
-                         2 * sizeof(struct vlan_header);
-        } else {
-            mac_hdr_len = sizeof(struct eth_header) +
-                         sizeof(struct vlan_header);
-        }
-        break;
+    if ((data[14] & 0xf0) != 0x40)
+       return; /* not IPv4 */
+    hlen  = (data[14] & 0x0f) * 4;
+    plen  = (data[16] << 8 | data[17]) - hlen;
+    proto = data[23];
+
+    switch (proto) {
+    case PROTO_TCP:
+       csum_offset = 16;
+       break;
+    case PROTO_UDP:
+       csum_offset = 6;
+       break;
     default:
-        mac_hdr_len = sizeof(struct eth_header);
-        break;
+       return;
     }
 
-    length -= mac_hdr_len;
-
-    /* Now check we have an IP header (with an optionnal VLAN header) */
-    if (length < sizeof(struct ip_header)) {
+    if (plen < csum_offset + 2 || 14 + hlen + plen > length) {
         return;
     }
 
-    ip = (struct ip_header *)(data + mac_hdr_len);
-
-    if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
-        return; /* not IPv4 */
-    }
-
-    ip_len = lduw_be_p(&ip->ip_len);
-
-    /* Last, check that we have enough data for the all IP frame */
-    if (length < ip_len) {
-        return;
-    }
-
-    ip_len -= IP_HDR_GET_LEN(ip);
-
-    switch (ip->ip_p) {
-    case IP_PROTO_TCP:
-    {
-        uint16_t csum;
-        tcp_header *tcp = (tcp_header *)(ip + 1);
-
-        if (ip_len < sizeof(tcp_header)) {
-            return;
-        }
-
-        /* Set csum to 0 */
-        stw_he_p(&tcp->th_sum, 0);
-
-        csum = net_checksum_tcpudp(ip_len, ip->ip_p,
-                                   (uint8_t *)&ip->ip_src,
-                                   (uint8_t *)tcp);
-
-        /* Store computed csum */
-        stw_be_p(&tcp->th_sum, csum);
-
-        break;
-    }
-    case IP_PROTO_UDP:
-    {
-        uint16_t csum;
-        udp_header *udp = (udp_header *)(ip + 1);
-
-        if (ip_len < sizeof(udp_header)) {
-            return;
-        }
-
-        /* Set csum to 0 */
-        stw_he_p(&udp->uh_sum, 0);
-
-        csum = net_checksum_tcpudp(ip_len, ip->ip_p,
-                                   (uint8_t *)&ip->ip_src,
-                                   (uint8_t *)udp);
-
-        /* Store computed csum */
-        stw_be_p(&udp->uh_sum, csum);
-
-        break;
-    }
-    default:
-        /* Can't handle any other protocol */
-        break;
-    }
+    data[14+hlen+csum_offset]   = 0;
+    data[14+hlen+csum_offset+1] = 0;
+    csum = net_checksum_tcpudp(plen, proto, data+14+12, data+14+hlen);
+    data[14+hlen+csum_offset]   = csum >> 8;
+    data[14+hlen+csum_offset+1] = csum & 0xff;
 }
 
 uint32_t
 net_checksum_add_iov(const struct iovec *iov, const unsigned int iov_cnt,
-                     uint32_t iov_off, uint32_t size, uint32_t csum_offset)
+                     uint32_t iov_off, uint32_t size)
 {
     size_t iovec_off, buf_off;
     unsigned int i;
     uint32_t res = 0;
+    uint32_t seq = 0;
 
     iovec_off = 0;
     buf_off = 0;
@@ -175,8 +109,8 @@ net_checksum_add_iov(const struct iovec *iov, const unsigned int iov_cnt,
             size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off , size);
             void *chunk_buf = iov[i].iov_base + (iov_off - iovec_off);
 
-            res += net_checksum_add_cont(len, chunk_buf, csum_offset);
-            csum_offset += len;
+            res += net_checksum_add_cont(len, chunk_buf, seq);
+            seq += len;
 
             buf_off += len;
             iov_off += len;
index 5cae479..d47530e 100644 (file)
 #include "net/net.h"
 #include "qapi-types.h"
 
-int net_init_dump(const Netdev *netdev, const char *name,
+int net_init_dump(const NetClientOptions *opts, const char *name,
                   NetClientState *peer, Error **errp);
 
 #ifdef CONFIG_SLIRP
-int net_init_slirp(const Netdev *netdev, const char *name,
+int net_init_slirp(const NetClientOptions *opts, const char *name,
                    NetClientState *peer, Error **errp);
 #endif
 
-int net_init_hubport(const Netdev *netdev, const char *name,
+int net_init_hubport(const NetClientOptions *opts, const char *name,
                      NetClientState *peer, Error **errp);
 
-int net_init_socket(const Netdev *netdev, const char *name,
+int net_init_socket(const NetClientOptions *opts, const char *name,
                     NetClientState *peer, Error **errp);
 
-int net_init_tap(const Netdev *netdev, const char *name,
+int net_init_tap(const NetClientOptions *opts, const char *name,
                  NetClientState *peer, Error **errp);
 
-int net_init_bridge(const Netdev *netdev, const char *name,
+int net_init_bridge(const NetClientOptions *opts, const char *name,
                     NetClientState *peer, Error **errp);
 
-int net_init_l2tpv3(const Netdev *netdev, const char *name,
+int net_init_l2tpv3(const NetClientOptions *opts, const char *name,
                     NetClientState *peer, Error **errp);
 #ifdef CONFIG_VDE
-int net_init_vde(const Netdev *netdev, const char *name,
+int net_init_vde(const NetClientOptions *opts, const char *name,
                  NetClientState *peer, Error **errp);
 #endif
 
 #ifdef CONFIG_NETMAP
-int net_init_netmap(const Netdev *netdev, const char *name,
+int net_init_netmap(const NetClientOptions *opts, const char *name,
                     NetClientState *peer, Error **errp);
 #endif
 
-int net_init_vhost_user(const Netdev *netdev, const char *name,
+int net_init_vhost_user(const NetClientOptions *opts, const char *name,
                         NetClientState *peer, Error **errp);
 
 #endif /* QEMU_NET_CLIENTS_H */
index 89a149b..41f7673 100644 (file)
@@ -172,14 +172,14 @@ static void dumpclient_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_dump_info = {
-    .type = NET_CLIENT_DRIVER_DUMP,
+    .type = NET_CLIENT_OPTIONS_KIND_DUMP,
     .size = sizeof(DumpNetClient),
     .receive = dumpclient_receive,
     .receive_iov = dumpclient_receive_iov,
     .cleanup = dumpclient_cleanup,
 };
 
-int net_init_dump(const Netdev *netdev, const char *name,
+int net_init_dump(const NetClientOptions *opts, const char *name,
                   NetClientState *peer, Error **errp)
 {
     int len, rc;
@@ -189,8 +189,8 @@ int net_init_dump(const Netdev *netdev, const char *name,
     NetClientState *nc;
     DumpNetClient *dnc;
 
-    assert(netdev->type == NET_CLIENT_DRIVER_DUMP);
-    dump = &netdev->u.dump;
+    assert(opts->type == NET_CLIENT_OPTIONS_KIND_DUMP);
+    dump = opts->u.dump.data;
 
     assert(peer);
 
index df81efb..7e32d27 100644 (file)
--- a/net/eth.c
+++ b/net/eth.c
@@ -21,8 +21,8 @@
 #include "qemu-common.h"
 #include "net/tap.h"
 
-void eth_setup_vlan_headers_ex(struct eth_header *ehdr, uint16_t vlan_tag,
-    uint16_t vlan_ethtype, bool *is_new)
+void eth_setup_vlan_headers(struct eth_header *ehdr, uint16_t vlan_tag,
+    bool *is_new)
 {
     struct vlan_header *vhdr = PKT_GET_VLAN_HDR(ehdr);
 
@@ -36,7 +36,7 @@ void eth_setup_vlan_headers_ex(struct eth_header *ehdr, uint16_t vlan_tag,
     default:
         /* No VLAN header, put a new one */
         vhdr->h_proto = ehdr->h_proto;
-        ehdr->h_proto = cpu_to_be16(vlan_ethtype);
+        ehdr->h_proto = cpu_to_be16(ETH_P_VLAN);
         *is_new = true;
         break;
     }
@@ -79,100 +79,26 @@ eth_get_gso_type(uint16_t l3_proto, uint8_t *l3_hdr, uint8_t l4proto)
     return VIRTIO_NET_HDR_GSO_NONE | ecn_state;
 }
 
-uint16_t
-eth_get_l3_proto(const struct iovec *l2hdr_iov, int iovcnt, size_t l2hdr_len)
-{
-    uint16_t proto;
-    size_t copied;
-    size_t size = iov_size(l2hdr_iov, iovcnt);
-    size_t proto_offset = l2hdr_len - sizeof(proto);
-
-    if (size < proto_offset) {
-        return ETH_P_UNKNOWN;
-    }
-
-    copied = iov_to_buf(l2hdr_iov, iovcnt, proto_offset,
-                        &proto, sizeof(proto));
-
-    return (copied == sizeof(proto)) ? be16_to_cpu(proto) : ETH_P_UNKNOWN;
-}
-
-static bool
-_eth_copy_chunk(size_t input_size,
-                const struct iovec *iov, int iovcnt,
-                size_t offset, size_t length,
-                void *buffer)
-{
-    size_t copied;
-
-    if (input_size < offset) {
-        return false;
-    }
-
-    copied = iov_to_buf(iov, iovcnt, offset, buffer, length);
-
-    if (copied < length) {
-        return false;
-    }
-
-    return true;
-}
-
-static bool
-_eth_tcp_has_data(bool is_ip4,
-                  const struct ip_header  *ip4_hdr,
-                  const struct ip6_header *ip6_hdr,
-                  size_t full_ip6hdr_len,
-                  const struct tcp_header *tcp)
-{
-    uint32_t l4len;
-
-    if (is_ip4) {
-        l4len = be16_to_cpu(ip4_hdr->ip_len) - IP_HDR_GET_LEN(ip4_hdr);
-    } else {
-        size_t opts_len = full_ip6hdr_len - sizeof(struct ip6_header);
-        l4len = be16_to_cpu(ip6_hdr->ip6_ctlun.ip6_un1.ip6_un1_plen) - opts_len;
-    }
-
-    return l4len > TCP_HEADER_DATA_OFFSET(tcp);
-}
-
-void eth_get_protocols(const struct iovec *iov, int iovcnt,
+void eth_get_protocols(const uint8_t *headers,
+                       uint32_t hdr_length,
                        bool *isip4, bool *isip6,
-                       bool *isudp, bool *istcp,
-                       size_t *l3hdr_off,
-                       size_t *l4hdr_off,
-                       size_t *l5hdr_off,
-                       eth_ip6_hdr_info *ip6hdr_info,
-                       eth_ip4_hdr_info *ip4hdr_info,
-                       eth_l4_hdr_info  *l4hdr_info)
+                       bool *isudp, bool *istcp)
 {
     int proto;
-    bool fragment = false;
-    size_t l2hdr_len = eth_get_l2_hdr_length_iov(iov, iovcnt);
-    size_t input_size = iov_size(iov, iovcnt);
-    size_t copied;
-
+    size_t l2hdr_len = eth_get_l2_hdr_length(headers);
+    assert(hdr_length >= eth_get_l2_hdr_length(headers));
     *isip4 = *isip6 = *isudp = *istcp = false;
 
-    proto = eth_get_l3_proto(iov, iovcnt, l2hdr_len);
-
-    *l3hdr_off = l2hdr_len;
-
+    proto = eth_get_l3_proto(headers, l2hdr_len);
     if (proto == ETH_P_IP) {
-        struct ip_header *iphdr = &ip4hdr_info->ip4_hdr;
-
-        if (input_size < l2hdr_len) {
-            return;
-        }
+        *isip4 = true;
 
-        copied = iov_to_buf(iov, iovcnt, l2hdr_len, iphdr, sizeof(*iphdr));
+        struct ip_header *iphdr;
 
-        *isip4 = true;
+        assert(hdr_length >=
+            eth_get_l2_hdr_length(headers) + sizeof(struct ip_header));
 
-        if (copied < sizeof(*iphdr)) {
-            return;
-        }
+        iphdr = PKT_GET_IP_HDR(headers);
 
         if (IP_HEADER_VERSION(iphdr) == IP_HEADER_VERSION_4) {
             if (iphdr->ip_p == IP_PROTO_TCP) {
@@ -181,135 +107,24 @@ void eth_get_protocols(const struct iovec *iov, int iovcnt,
                 *isudp = true;
             }
         }
-
-        ip4hdr_info->fragment = IP4_IS_FRAGMENT(iphdr);
-        *l4hdr_off = l2hdr_len + IP_HDR_GET_LEN(iphdr);
-
-        fragment = ip4hdr_info->fragment;
     } else if (proto == ETH_P_IPV6) {
+        uint8_t l4proto;
+        size_t full_ip6hdr_len;
+
+        struct iovec hdr_vec;
+        hdr_vec.iov_base = (void *) headers;
+        hdr_vec.iov_len = hdr_length;
 
         *isip6 = true;
-        if (eth_parse_ipv6_hdr(iov, iovcnt, l2hdr_len,
-                               ip6hdr_info)) {
-            if (ip6hdr_info->l4proto == IP_PROTO_TCP) {
+        if (eth_parse_ipv6_hdr(&hdr_vec, 1, l2hdr_len,
+                              &l4proto, &full_ip6hdr_len)) {
+            if (l4proto == IP_PROTO_TCP) {
                 *istcp = true;
-            } else if (ip6hdr_info->l4proto == IP_PROTO_UDP) {
+            } else if (l4proto == IP_PROTO_UDP) {
                 *isudp = true;
             }
-        } else {
-            return;
-        }
-
-        *l4hdr_off = l2hdr_len + ip6hdr_info->full_hdr_len;
-        fragment = ip6hdr_info->fragment;
-    }
-
-    if (!fragment) {
-        if (*istcp) {
-            *istcp = _eth_copy_chunk(input_size,
-                                     iov, iovcnt,
-                                     *l4hdr_off, sizeof(l4hdr_info->hdr.tcp),
-                                     &l4hdr_info->hdr.tcp);
-
-            if (*istcp) {
-                *l5hdr_off = *l4hdr_off +
-                    TCP_HEADER_DATA_OFFSET(&l4hdr_info->hdr.tcp);
-
-                l4hdr_info->has_tcp_data =
-                    _eth_tcp_has_data(proto == ETH_P_IP,
-                                      &ip4hdr_info->ip4_hdr,
-                                      &ip6hdr_info->ip6_hdr,
-                                      *l4hdr_off - *l3hdr_off,
-                                      &l4hdr_info->hdr.tcp);
-            }
-        } else if (*isudp) {
-            *isudp = _eth_copy_chunk(input_size,
-                                     iov, iovcnt,
-                                     *l4hdr_off, sizeof(l4hdr_info->hdr.udp),
-                                     &l4hdr_info->hdr.udp);
-            *l5hdr_off = *l4hdr_off + sizeof(l4hdr_info->hdr.udp);
-        }
-    }
-}
-
-bool
-eth_strip_vlan(const struct iovec *iov, int iovcnt, size_t iovoff,
-               uint8_t *new_ehdr_buf,
-               uint16_t *payload_offset, uint16_t *tci)
-{
-    struct vlan_header vlan_hdr;
-    struct eth_header *new_ehdr = (struct eth_header *) new_ehdr_buf;
-
-    size_t copied = iov_to_buf(iov, iovcnt, iovoff,
-                               new_ehdr, sizeof(*new_ehdr));
-
-    if (copied < sizeof(*new_ehdr)) {
-        return false;
-    }
-
-    switch (be16_to_cpu(new_ehdr->h_proto)) {
-    case ETH_P_VLAN:
-    case ETH_P_DVLAN:
-        copied = iov_to_buf(iov, iovcnt, iovoff + sizeof(*new_ehdr),
-                            &vlan_hdr, sizeof(vlan_hdr));
-
-        if (copied < sizeof(vlan_hdr)) {
-            return false;
-        }
-
-        new_ehdr->h_proto = vlan_hdr.h_proto;
-
-        *tci = be16_to_cpu(vlan_hdr.h_tci);
-        *payload_offset = iovoff + sizeof(*new_ehdr) + sizeof(vlan_hdr);
-
-        if (be16_to_cpu(new_ehdr->h_proto) == ETH_P_VLAN) {
-
-            copied = iov_to_buf(iov, iovcnt, *payload_offset,
-                                PKT_GET_VLAN_HDR(new_ehdr), sizeof(vlan_hdr));
-
-            if (copied < sizeof(vlan_hdr)) {
-                return false;
-            }
-
-            *payload_offset += sizeof(vlan_hdr);
-        }
-        return true;
-    default:
-        return false;
-    }
-}
-
-bool
-eth_strip_vlan_ex(const struct iovec *iov, int iovcnt, size_t iovoff,
-                  uint16_t vet, uint8_t *new_ehdr_buf,
-                  uint16_t *payload_offset, uint16_t *tci)
-{
-    struct vlan_header vlan_hdr;
-    struct eth_header *new_ehdr = (struct eth_header *) new_ehdr_buf;
-
-    size_t copied = iov_to_buf(iov, iovcnt, iovoff,
-                               new_ehdr, sizeof(*new_ehdr));
-
-    if (copied < sizeof(*new_ehdr)) {
-        return false;
-    }
-
-    if (be16_to_cpu(new_ehdr->h_proto) == vet) {
-        copied = iov_to_buf(iov, iovcnt, iovoff + sizeof(*new_ehdr),
-                            &vlan_hdr, sizeof(vlan_hdr));
-
-        if (copied < sizeof(vlan_hdr)) {
-            return false;
         }
-
-        new_ehdr->h_proto = vlan_hdr.h_proto;
-
-        *tci = be16_to_cpu(vlan_hdr.h_tci);
-        *payload_offset = iovoff + sizeof(*new_ehdr) + sizeof(vlan_hdr);
-        return true;
     }
-
-    return false;
 }
 
 void
@@ -318,12 +133,7 @@ eth_setup_ip4_fragmentation(const void *l2hdr, size_t l2hdr_len,
                             size_t l3payload_len,
                             size_t frag_offset, bool more_frags)
 {
-    const struct iovec l2vec = {
-        .iov_base = (void *) l2hdr,
-        .iov_len = l2hdr_len
-    };
-
-    if (eth_get_l3_proto(&l2vec, 1, l2hdr_len) == ETH_P_IP) {
+    if (eth_get_l3_proto(l2hdr, l2hdr_len) == ETH_P_IP) {
         uint16_t orig_flags;
         struct ip_header *iphdr = (struct ip_header *) l3hdr;
         uint16_t frag_off_units = frag_offset / IP_FRAG_UNIT_SIZE;
@@ -348,9 +158,7 @@ eth_fix_ip4_checksum(void *l3hdr, size_t l3hdr_len)
 }
 
 uint32_t
-eth_calc_ip4_pseudo_hdr_csum(struct ip_header *iphdr,
-                             uint16_t csl,
-                             uint32_t *cso)
+eth_calc_pseudo_hdr_csum(struct ip_header *iphdr, uint16_t csl)
 {
     struct ip_pseudo_header ipph;
     ipph.ip_src = iphdr->ip_src;
@@ -358,26 +166,7 @@ eth_calc_ip4_pseudo_hdr_csum(struct ip_header *iphdr,
     ipph.ip_payload = cpu_to_be16(csl);
     ipph.ip_proto = iphdr->ip_p;
     ipph.zeros = 0;
-    *cso = sizeof(ipph);
-    return net_checksum_add(*cso, (uint8_t *) &ipph);
-}
-
-uint32_t
-eth_calc_ip6_pseudo_hdr_csum(struct ip6_header *iphdr,
-                             uint16_t csl,
-                             uint8_t l4_proto,
-                             uint32_t *cso)
-{
-    struct ip6_pseudo_header ipph;
-    ipph.ip6_src = iphdr->ip6_src;
-    ipph.ip6_dst = iphdr->ip6_dst;
-    ipph.len = cpu_to_be16(csl);
-    ipph.zero[0] = 0;
-    ipph.zero[1] = 0;
-    ipph.zero[2] = 0;
-    ipph.next_hdr = l4_proto;
-    *cso = sizeof(ipph);
-    return net_checksum_add(*cso, (uint8_t *)&ipph);
+    return net_checksum_add(sizeof(ipph), (uint8_t *) &ipph);
 }
 
 static bool
@@ -397,152 +186,33 @@ eth_is_ip6_extension_header_type(uint8_t hdr_type)
     }
 }
 
-static bool
-_eth_get_rss_ex_dst_addr(const struct iovec *pkt, int pkt_frags,
-                        size_t rthdr_offset,
-                        struct ip6_ext_hdr *ext_hdr,
-                        struct in6_address *dst_addr)
-{
-    struct ip6_ext_hdr_routing *rthdr = (struct ip6_ext_hdr_routing *) ext_hdr;
-
-    if ((rthdr->rtype == 2) &&
-        (rthdr->len == sizeof(struct in6_address) / 8) &&
-        (rthdr->segleft == 1)) {
-
-        size_t input_size = iov_size(pkt, pkt_frags);
-        size_t bytes_read;
-
-        if (input_size < rthdr_offset + sizeof(*ext_hdr)) {
-            return false;
-        }
-
-        bytes_read = iov_to_buf(pkt, pkt_frags,
-                                rthdr_offset + sizeof(*ext_hdr),
-                                dst_addr, sizeof(*dst_addr));
-
-        return bytes_read == sizeof(dst_addr);
-    }
-
-    return false;
-}
-
-static bool
-_eth_get_rss_ex_src_addr(const struct iovec *pkt, int pkt_frags,
-                        size_t dsthdr_offset,
-                        struct ip6_ext_hdr *ext_hdr,
-                        struct in6_address *src_addr)
-{
-    size_t bytes_left = (ext_hdr->ip6r_len + 1) * 8 - sizeof(*ext_hdr);
-    struct ip6_option_hdr opthdr;
-    size_t opt_offset = dsthdr_offset + sizeof(*ext_hdr);
-
-    while (bytes_left > sizeof(opthdr)) {
-        size_t input_size = iov_size(pkt, pkt_frags);
-        size_t bytes_read, optlen;
-
-        if (input_size < opt_offset) {
-            return false;
-        }
-
-        bytes_read = iov_to_buf(pkt, pkt_frags, opt_offset,
-                                &opthdr, sizeof(opthdr));
-
-        if (bytes_read != sizeof(opthdr)) {
-            return false;
-        }
-
-        optlen = (opthdr.type == IP6_OPT_PAD1) ? 1
-                                               : (opthdr.len + sizeof(opthdr));
-
-        if (optlen > bytes_left) {
-            return false;
-        }
-
-        if (opthdr.type == IP6_OPT_HOME) {
-            size_t input_size = iov_size(pkt, pkt_frags);
-
-            if (input_size < opt_offset + sizeof(opthdr)) {
-                return false;
-            }
-
-            bytes_read = iov_to_buf(pkt, pkt_frags,
-                                    opt_offset + sizeof(opthdr),
-                                    src_addr, sizeof(*src_addr));
-
-            return bytes_read == sizeof(src_addr);
-        }
-
-        opt_offset += optlen;
-        bytes_left -= optlen;
-    }
-
-    return false;
-}
-
-bool eth_parse_ipv6_hdr(const struct iovec *pkt, int pkt_frags,
-                        size_t ip6hdr_off, eth_ip6_hdr_info *info)
+bool eth_parse_ipv6_hdr(struct iovec *pkt, int pkt_frags,
+                        size_t ip6hdr_off, uint8_t *l4proto,
+                        size_t *full_hdr_len)
 {
+    struct ip6_header ip6_hdr;
     struct ip6_ext_hdr ext_hdr;
     size_t bytes_read;
-    uint8_t curr_ext_hdr_type;
-    size_t input_size = iov_size(pkt, pkt_frags);
-
-    info->rss_ex_dst_valid = false;
-    info->rss_ex_src_valid = false;
-    info->fragment = false;
-
-    if (input_size < ip6hdr_off) {
-        return false;
-    }
 
     bytes_read = iov_to_buf(pkt, pkt_frags, ip6hdr_off,
-                            &info->ip6_hdr, sizeof(info->ip6_hdr));
-    if (bytes_read < sizeof(info->ip6_hdr)) {
+                            &ip6_hdr, sizeof(ip6_hdr));
+    if (bytes_read < sizeof(ip6_hdr)) {
         return false;
     }
 
-    info->full_hdr_len = sizeof(struct ip6_header);
-
-    curr_ext_hdr_type = info->ip6_hdr.ip6_nxt;
+    *full_hdr_len = sizeof(struct ip6_header);
 
-    if (!eth_is_ip6_extension_header_type(curr_ext_hdr_type)) {
-        info->l4proto = info->ip6_hdr.ip6_nxt;
-        info->has_ext_hdrs = false;
+    if (!eth_is_ip6_extension_header_type(ip6_hdr.ip6_nxt)) {
+        *l4proto = ip6_hdr.ip6_nxt;
         return true;
     }
 
-    info->has_ext_hdrs = true;
-
     do {
-        if (input_size < ip6hdr_off + info->full_hdr_len) {
-            return false;
-        }
-
-        bytes_read = iov_to_buf(pkt, pkt_frags, ip6hdr_off + info->full_hdr_len,
+        bytes_read = iov_to_buf(pkt, pkt_frags, ip6hdr_off + *full_hdr_len,
                                 &ext_hdr, sizeof(ext_hdr));
+        *full_hdr_len += (ext_hdr.ip6r_len + 1) * IP6_EXT_GRANULARITY;
+    } while (eth_is_ip6_extension_header_type(ext_hdr.ip6r_nxt));
 
-        if (bytes_read < sizeof(ext_hdr)) {
-            return false;
-        }
-
-        if (curr_ext_hdr_type == IP6_ROUTING) {
-            info->rss_ex_dst_valid =
-                _eth_get_rss_ex_dst_addr(pkt, pkt_frags,
-                                         ip6hdr_off + info->full_hdr_len,
-                                         &ext_hdr, &info->rss_ex_dst);
-        } else if (curr_ext_hdr_type == IP6_DESTINATON) {
-            info->rss_ex_src_valid =
-                _eth_get_rss_ex_src_addr(pkt, pkt_frags,
-                                         ip6hdr_off + info->full_hdr_len,
-                                         &ext_hdr, &info->rss_ex_src);
-        } else if (curr_ext_hdr_type == IP6_FRAGMENT) {
-            info->fragment = true;
-        }
-
-        info->full_hdr_len += (ext_hdr.ip6r_len + 1) * IP6_EXT_GRANULARITY;
-        curr_ext_hdr_type = ext_hdr.ip6r_nxt;
-    } while (eth_is_ip6_extension_header_type(curr_ext_hdr_type));
-
-    info->l4proto = ext_hdr.ip6r_nxt;
+    *l4proto = ext_hdr.ip6r_nxt;
     return true;
 }
index 35df374..c0c4dc6 100644 (file)
@@ -40,7 +40,10 @@ typedef struct MirrorState {
     char *outdev;
     CharDriverState *chr_in;
     CharDriverState *chr_out;
-    SocketReadState rs;
+    int state; /* 0 = getting length, 1 = getting data */
+    unsigned int index;
+    unsigned int packet_len;
+    uint8_t buf[REDIRECTOR_MAX_LEN];
 } MirrorState;
 
 static int filter_mirror_send(CharDriverState *chr_out,
@@ -105,12 +108,51 @@ static void redirector_chr_read(void *opaque, const uint8_t *buf, int size)
 {
     NetFilterState *nf = opaque;
     MirrorState *s = FILTER_REDIRECTOR(nf);
-    int ret;
-
-    ret = net_fill_rstate(&s->rs, buf, size);
-
-    if (ret == -1) {
-        qemu_chr_add_handlers(s->chr_in, NULL, NULL, NULL, NULL);
+    unsigned int l;
+
+    while (size > 0) {
+        /* reassemble a packet from the network */
+        switch (s->state) { /* 0 = getting length, 1 = getting data */
+        case 0:
+            l = 4 - s->index;
+            if (l > size) {
+                l = size;
+            }
+            memcpy(s->buf + s->index, buf, l);
+            buf += l;
+            size -= l;
+            s->index += l;
+            if (s->index == 4) {
+                /* got length */
+                s->packet_len = ntohl(*(uint32_t *)s->buf);
+                s->index = 0;
+                s->state = 1;
+            }
+            break;
+        case 1:
+            l = s->packet_len - s->index;
+            if (l > size) {
+                l = size;
+            }
+            if (s->index + l <= sizeof(s->buf)) {
+                memcpy(s->buf + s->index, buf, l);
+            } else {
+                error_report("serious error: oversized packet received.");
+                s->index = s->state = 0;
+                qemu_chr_add_handlers(s->chr_in, NULL, NULL, NULL, NULL);
+                return;
+            }
+
+            s->index += l;
+            buf += l;
+            size -= l;
+            if (s->index >= s->packet_len) {
+                s->index = 0;
+                s->state = 0;
+                redirector_to_filter(nf, s->buf, s->packet_len);
+            }
+            break;
+        }
     }
 }
 
@@ -216,14 +258,6 @@ static void filter_mirror_setup(NetFilterState *nf, Error **errp)
     }
 }
 
-static void redirector_rs_finalize(SocketReadState *rs)
-{
-    MirrorState *s = container_of(rs, MirrorState, rs);
-    NetFilterState *nf = NETFILTER(s);
-
-    redirector_to_filter(nf, rs->buf, rs->packet_len);
-}
-
 static void filter_redirector_setup(NetFilterState *nf, Error **errp)
 {
     MirrorState *s = FILTER_REDIRECTOR(nf);
@@ -240,7 +274,7 @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
         }
     }
 
-    net_socket_rs_init(&s->rs, redirector_rs_finalize);
+    s->state = s->index = 0;
 
     if (s->indev) {
         s->chr_in = qemu_chr_find(s->indev);
index 888fe6d..8ac79f3 100644 (file)
@@ -201,7 +201,7 @@ static void netfilter_complete(UserCreatable *uc, Error **errp)
     }
 
     queues = qemu_find_net_clients_except(nf->netdev_id, ncs,
-                                          NET_CLIENT_DRIVER_NIC,
+                                          NET_CLIENT_OPTIONS_KIND_NIC,
                                           MAX_QUEUE_NUM);
     if (queues < 1) {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "netdev",
index 32d8cf5..6d90c6e 100644 (file)
--- a/net/hub.c
+++ b/net/hub.c
@@ -131,7 +131,7 @@ static void net_hub_port_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_hub_port_info = {
-    .type = NET_CLIENT_DRIVER_HUBPORT,
+    .type = NET_CLIENT_OPTIONS_KIND_HUBPORT,
     .size = sizeof(NetHubPort),
     .can_receive = net_hub_port_can_receive,
     .receive = net_hub_port_receive,
@@ -266,10 +266,10 @@ int net_hub_id_for_client(NetClientState *nc, int *id)
 {
     NetHubPort *port;
 
-    if (nc->info->type == NET_CLIENT_DRIVER_HUBPORT) {
+    if (nc->info->type == NET_CLIENT_OPTIONS_KIND_HUBPORT) {
         port = DO_UPCAST(NetHubPort, nc, nc);
     } else if (nc->peer != NULL && nc->peer->info->type ==
-            NET_CLIENT_DRIVER_HUBPORT) {
+            NET_CLIENT_OPTIONS_KIND_HUBPORT) {
         port = DO_UPCAST(NetHubPort, nc, nc->peer);
     } else {
         return -ENOENT;
@@ -281,14 +281,14 @@ int net_hub_id_for_client(NetClientState *nc, int *id)
     return 0;
 }
 
-int net_init_hubport(const Netdev *netdev, const char *name,
+int net_init_hubport(const NetClientOptions *opts, const char *name,
                      NetClientState *peer, Error **errp)
 {
     const NetdevHubPortOptions *hubport;
 
-    assert(netdev->type == NET_CLIENT_DRIVER_HUBPORT);
+    assert(opts->type == NET_CLIENT_OPTIONS_KIND_HUBPORT);
     assert(!peer);
-    hubport = &netdev->u.hubport;
+    hubport = opts->u.hubport.data;
 
     net_hub_add_port(hubport->hubid, name);
     return 0;
@@ -315,14 +315,14 @@ void net_hub_check_clients(void)
             }
 
             switch (peer->info->type) {
-            case NET_CLIENT_DRIVER_NIC:
+            case NET_CLIENT_OPTIONS_KIND_NIC:
                 has_nic = 1;
                 break;
-            case NET_CLIENT_DRIVER_USER:
-            case NET_CLIENT_DRIVER_TAP:
-            case NET_CLIENT_DRIVER_SOCKET:
-            case NET_CLIENT_DRIVER_VDE:
-            case NET_CLIENT_DRIVER_VHOST_USER:
+            case NET_CLIENT_OPTIONS_KIND_USER:
+            case NET_CLIENT_OPTIONS_KIND_TAP:
+            case NET_CLIENT_OPTIONS_KIND_SOCKET:
+            case NET_CLIENT_OPTIONS_KIND_VDE:
+            case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
                 has_host_dev = 1;
                 break;
             default:
index 6745b78..5c668f7 100644 (file)
@@ -516,7 +516,7 @@ static void net_l2tpv3_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_l2tpv3_info = {
-    .type = NET_CLIENT_DRIVER_L2TPV3,
+    .type = NET_CLIENT_OPTIONS_KIND_L2TPV3,
     .size = sizeof(NetL2TPV3State),
     .receive = net_l2tpv3_receive_dgram,
     .receive_iov = net_l2tpv3_receive_dgram_iov,
@@ -524,7 +524,7 @@ static NetClientInfo net_l2tpv3_info = {
     .cleanup = net_l2tpv3_cleanup,
 };
 
-int net_init_l2tpv3(const Netdev *netdev,
+int net_init_l2tpv3(const NetClientOptions *opts,
                     const char *name,
                     NetClientState *peer, Error **errp)
 {
@@ -545,8 +545,8 @@ int net_init_l2tpv3(const Netdev *netdev,
     s->queue_tail = 0;
     s->header_mismatch = false;
 
-    assert(netdev->type == NET_CLIENT_DRIVER_L2TPV3);
-    l2tpv3 = &netdev->u.l2tpv3;
+    assert(opts->type == NET_CLIENT_OPTIONS_KIND_L2TPV3);
+    l2tpv3 = opts->u.l2tpv3.data;
 
     if (l2tpv3->has_ipv6 && l2tpv3->ipv6) {
         s->ipv6 = l2tpv3->ipv6;
index d51cb29..6b0b375 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -76,6 +76,8 @@ const char *host_net_devices[] = {
     NULL,
 };
 
+int default_net = 1;
+
 /***********************************************************/
 /* network device redirectors */
 
@@ -289,7 +291,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
     NICState *nic;
     int i, queues = MAX(1, conf->peers.queues);
 
-    assert(info->type == NET_CLIENT_DRIVER_NIC);
+    assert(info->type == NET_CLIENT_OPTIONS_KIND_NIC);
     assert(info->size >= sizeof(NICState));
 
     nic = g_malloc0(info->size + sizeof(NetClientState) * queues);
@@ -360,13 +362,13 @@ void qemu_del_net_client(NetClientState *nc)
     int queues, i;
     NetFilterState *nf, *next;
 
-    assert(nc->info->type != NET_CLIENT_DRIVER_NIC);
+    assert(nc->info->type != NET_CLIENT_OPTIONS_KIND_NIC);
 
     /* If the NetClientState belongs to a multiqueue backend, we will change all
      * other NetClientStates also.
      */
     queues = qemu_find_net_clients_except(nc->name, ncs,
-                                          NET_CLIENT_DRIVER_NIC,
+                                          NET_CLIENT_OPTIONS_KIND_NIC,
                                           MAX_QUEUE_NUM);
     assert(queues != 0);
 
@@ -375,7 +377,7 @@ void qemu_del_net_client(NetClientState *nc)
     }
 
     /* If there is a peer NIC, delete and cleanup client, but do not free. */
-    if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_NIC) {
+    if (nc->peer && nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
         NICState *nic = qemu_get_nic(nc->peer);
         if (nic->peer_deleted) {
             return;
@@ -431,7 +433,7 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
     NetClientState *nc;
 
     QTAILQ_FOREACH(nc, &net_clients, next) {
-        if (nc->info->type == NET_CLIENT_DRIVER_NIC) {
+        if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
             if (nc->queue_index == 0) {
                 func(qemu_get_nic(nc), opaque);
             }
@@ -603,7 +605,7 @@ void qemu_flush_or_purge_queued_packets(NetClientState *nc, bool purge)
 {
     nc->receive_disabled = 0;
 
-    if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_HUBPORT) {
+    if (nc->peer && nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_HUBPORT) {
         if (net_hub_flush(nc->peer)) {
             qemu_notify_event();
         }
@@ -777,7 +779,7 @@ NetClientState *qemu_find_netdev(const char *id)
     NetClientState *nc;
 
     QTAILQ_FOREACH(nc, &net_clients, next) {
-        if (nc->info->type == NET_CLIENT_DRIVER_NIC)
+        if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC)
             continue;
         if (!strcmp(nc->name, id)) {
             return nc;
@@ -788,7 +790,7 @@ NetClientState *qemu_find_netdev(const char *id)
 }
 
 int qemu_find_net_clients_except(const char *id, NetClientState **ncs,
-                                 NetClientDriver type, int max)
+                                 NetClientOptionsKind type, int max)
 {
     NetClientState *nc;
     int ret = 0;
@@ -862,15 +864,15 @@ int qemu_find_nic_model(NICInfo *nd, const char * const *models,
     return -1;
 }
 
-static int net_init_nic(const Netdev *netdev, const char *name,
+static int net_init_nic(const NetClientOptions *opts, const char *name,
                         NetClientState *peer, Error **errp)
 {
     int idx;
     NICInfo *nd;
     const NetLegacyNicOptions *nic;
 
-    assert(netdev->type == NET_CLIENT_DRIVER_NIC);
-    nic = &netdev->u.nic;
+    assert(opts->type == NET_CLIENT_OPTIONS_KIND_NIC);
+    nic = opts->u.nic.data;
 
     idx = nic_get_free_idx();
     if (idx == -1 || nb_nics >= MAX_NICS) {
@@ -930,111 +932,70 @@ static int net_init_nic(const Netdev *netdev, const char *name,
 }
 
 
-static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
-    const Netdev *netdev,
+static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND__MAX])(
+    const NetClientOptions *opts,
     const char *name,
     NetClientState *peer, Error **errp) = {
-        [NET_CLIENT_DRIVER_NIC]       = net_init_nic,
+        [NET_CLIENT_OPTIONS_KIND_NIC]       = net_init_nic,
 #ifdef CONFIG_SLIRP
-        [NET_CLIENT_DRIVER_USER]      = net_init_slirp,
+        [NET_CLIENT_OPTIONS_KIND_USER]      = net_init_slirp,
 #endif
-        [NET_CLIENT_DRIVER_TAP]       = net_init_tap,
-        [NET_CLIENT_DRIVER_SOCKET]    = net_init_socket,
+        [NET_CLIENT_OPTIONS_KIND_TAP]       = net_init_tap,
+        [NET_CLIENT_OPTIONS_KIND_SOCKET]    = net_init_socket,
 #ifdef CONFIG_VDE
-        [NET_CLIENT_DRIVER_VDE]       = net_init_vde,
+        [NET_CLIENT_OPTIONS_KIND_VDE]       = net_init_vde,
 #endif
 #ifdef CONFIG_NETMAP
-        [NET_CLIENT_DRIVER_NETMAP]    = net_init_netmap,
+        [NET_CLIENT_OPTIONS_KIND_NETMAP]    = net_init_netmap,
 #endif
-        [NET_CLIENT_DRIVER_DUMP]      = net_init_dump,
+        [NET_CLIENT_OPTIONS_KIND_DUMP]      = net_init_dump,
 #ifdef CONFIG_NET_BRIDGE
-        [NET_CLIENT_DRIVER_BRIDGE]    = net_init_bridge,
+        [NET_CLIENT_OPTIONS_KIND_BRIDGE]    = net_init_bridge,
 #endif
-        [NET_CLIENT_DRIVER_HUBPORT]   = net_init_hubport,
+        [NET_CLIENT_OPTIONS_KIND_HUBPORT]   = net_init_hubport,
 #ifdef CONFIG_VHOST_NET_USED
-        [NET_CLIENT_DRIVER_VHOST_USER] = net_init_vhost_user,
+        [NET_CLIENT_OPTIONS_KIND_VHOST_USER] = net_init_vhost_user,
 #endif
 #ifdef CONFIG_L2TPV3
-        [NET_CLIENT_DRIVER_L2TPV3]    = net_init_l2tpv3,
+        [NET_CLIENT_OPTIONS_KIND_L2TPV3]    = net_init_l2tpv3,
 #endif
 };
 
 
-static int net_client_init1(const void *object, bool is_netdev, Error **errp)
+static int net_client_init1(const void *object, int is_netdev, Error **errp)
 {
-    Netdev legacy = {0};
-    const Netdev *netdev;
+    const NetClientOptions *opts;
     const char *name;
     NetClientState *peer = NULL;
 
     if (is_netdev) {
-        netdev = object;
+        const Netdev *netdev = object;
+        opts = netdev->opts;
         name = netdev->id;
 
-        if (netdev->type == NET_CLIENT_DRIVER_DUMP ||
-            netdev->type == NET_CLIENT_DRIVER_NIC ||
-            !net_client_init_fun[netdev->type]) {
+        if (opts->type == NET_CLIENT_OPTIONS_KIND_DUMP ||
+            opts->type == NET_CLIENT_OPTIONS_KIND_NIC ||
+            !net_client_init_fun[opts->type]) {
             error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
                        "a netdev backend type");
             return -1;
         }
     } else {
         const NetLegacy *net = object;
-        const NetLegacyOptions *opts = net->opts;
-        legacy.id = net->id;
-        netdev = &legacy;
+        opts = net->opts;
         /* missing optional values have been initialized to "all bits zero" */
         name = net->has_id ? net->id : net->name;
 
-        /* Map the old options to the new flat type */
-        switch (opts->type) {
-        case NET_LEGACY_OPTIONS_KIND_NONE:
+        if (opts->type == NET_CLIENT_OPTIONS_KIND_NONE) {
             return 0; /* nothing to do */
-        case NET_LEGACY_OPTIONS_KIND_NIC:
-            legacy.type = NET_CLIENT_DRIVER_NIC;
-            legacy.u.nic = *opts->u.nic.data;
-            break;
-        case NET_LEGACY_OPTIONS_KIND_USER:
-            legacy.type = NET_CLIENT_DRIVER_USER;
-            legacy.u.user = *opts->u.user.data;
-            break;
-        case NET_LEGACY_OPTIONS_KIND_TAP:
-            legacy.type = NET_CLIENT_DRIVER_TAP;
-            legacy.u.tap = *opts->u.tap.data;
-            break;
-        case NET_LEGACY_OPTIONS_KIND_L2TPV3:
-            legacy.type = NET_CLIENT_DRIVER_L2TPV3;
-            legacy.u.l2tpv3 = *opts->u.l2tpv3.data;
-            break;
-        case NET_LEGACY_OPTIONS_KIND_SOCKET:
-            legacy.type = NET_CLIENT_DRIVER_SOCKET;
-            legacy.u.socket = *opts->u.socket.data;
-            break;
-        case NET_LEGACY_OPTIONS_KIND_VDE:
-            legacy.type = NET_CLIENT_DRIVER_VDE;
-            legacy.u.vde = *opts->u.vde.data;
-            break;
-        case NET_LEGACY_OPTIONS_KIND_DUMP:
-            legacy.type = NET_CLIENT_DRIVER_DUMP;
-            legacy.u.dump = *opts->u.dump.data;
-            break;
-        case NET_LEGACY_OPTIONS_KIND_BRIDGE:
-            legacy.type = NET_CLIENT_DRIVER_BRIDGE;
-            legacy.u.bridge = *opts->u.bridge.data;
-            break;
-        case NET_LEGACY_OPTIONS_KIND_NETMAP:
-            legacy.type = NET_CLIENT_DRIVER_NETMAP;
-            legacy.u.netmap = *opts->u.netmap.data;
-            break;
-        case NET_LEGACY_OPTIONS_KIND_VHOST_USER:
-            legacy.type = NET_CLIENT_DRIVER_VHOST_USER;
-            legacy.u.vhost_user = *opts->u.vhost_user.data;
-            break;
-        default:
-            abort();
+        }
+        if (opts->type == NET_CLIENT_OPTIONS_KIND_HUBPORT) {
+            error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
+                       "a net type");
+            return -1;
         }
 
-        if (!net_client_init_fun[netdev->type]) {
+        if (!net_client_init_fun[opts->type]) {
             error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
                        "a net backend type (maybe it is not compiled "
                        "into this binary)");
@@ -1042,17 +1003,17 @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp)
         }
 
         /* Do not add to a vlan if it's a nic with a netdev= parameter. */
-        if (netdev->type != NET_CLIENT_DRIVER_NIC ||
+        if (opts->type != NET_CLIENT_OPTIONS_KIND_NIC ||
             !opts->u.nic.data->has_netdev) {
             peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL);
         }
     }
 
-    if (net_client_init_fun[netdev->type](netdev, name, peer, errp) < 0) {
+    if (net_client_init_fun[opts->type](opts, name, peer, errp) < 0) {
         /* FIXME drop when all init functions store an Error */
         if (errp && !*errp) {
             error_setg(errp, QERR_DEVICE_INIT_FAILED,
-                       NetClientDriver_lookup[netdev->type]);
+                       NetClientOptionsKind_lookup[opts->type]);
         }
         return -1;
     }
@@ -1060,12 +1021,13 @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp)
 }
 
 
-int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
+int net_client_init(QemuOpts *opts, int is_netdev, Error **errp)
 {
     void *object = NULL;
     Error *err = NULL;
     int ret = -1;
-    Visitor *v = opts_visitor_new(opts);
+    OptsVisitor *ov = opts_visitor_new(opts);
+    Visitor *v = opts_get_visitor(ov);
 
     {
         /* Parse convenience option format ip6-net=fec0::0[/64] */
@@ -1115,7 +1077,7 @@ int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
     }
 
     error_propagate(errp, err);
-    visit_free(v);
+    opts_visitor_cleanup(ov);
     return ret;
 }
 
@@ -1153,7 +1115,7 @@ void hmp_host_net_add(Monitor *mon, const QDict *qdict)
 
     qemu_opt_set(opts, "type", device, &error_abort);
 
-    net_client_init(opts, false, &local_err);
+    net_client_init(opts, 0, &local_err);
     if (local_err) {
         error_report_err(local_err);
         monitor_printf(mon, "adding host network device %s failed\n", device);
@@ -1172,7 +1134,7 @@ void hmp_host_net_remove(Monitor *mon, const QDict *qdict)
                      device, vlan_id);
         return;
     }
-    if (nc->info->type == NET_CLIENT_DRIVER_NIC) {
+    if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
         error_report("invalid host network device '%s'", device);
         return;
     }
@@ -1183,7 +1145,7 @@ void hmp_host_net_remove(Monitor *mon, const QDict *qdict)
 
 void netdev_add(QemuOpts *opts, Error **errp)
 {
-    net_client_init(opts, true, errp);
+    net_client_init(opts, 1, errp);
 }
 
 void qmp_netdev_add(QDict *qdict, QObject **ret, Error **errp)
@@ -1239,7 +1201,7 @@ static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
     char *str;
     ObjectProperty *prop;
     ObjectPropertyIterator iter;
-    Visitor *v;
+    StringOutputVisitor *ov;
 
     /* generate info str */
     object_property_iter_init(&iter, OBJECT(nf));
@@ -1247,10 +1209,11 @@ static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
         if (!strcmp(prop->name, "type")) {
             continue;
         }
-        v = string_output_visitor_new(false, &str);
-        object_property_get(OBJECT(nf), v, prop->name, NULL);
-        visit_complete(v, &str);
-        visit_free(v);
+        ov = string_output_visitor_new(false);
+        object_property_get(OBJECT(nf), string_output_get_visitor(ov),
+                            prop->name, NULL);
+        str = string_output_get_string(ov);
+        string_output_visitor_cleanup(ov);
         monitor_printf(mon, ",%s=%s", prop->name, str);
         g_free(str);
     }
@@ -1263,7 +1226,7 @@ void print_net_client(Monitor *mon, NetClientState *nc)
 
     monitor_printf(mon, "%s: index=%d,type=%s,%s\n", nc->name,
                    nc->queue_index,
-                   NetClientDriver_lookup[nc->info->type],
+                   NetClientOptionsKind_lookup[nc->info->type],
                    nc->info_str);
     if (!QTAILQ_EMPTY(&nc->filters)) {
         monitor_printf(mon, "filters:\n");
@@ -1293,7 +1256,7 @@ RxFilterInfoList *qmp_query_rx_filter(bool has_name, const char *name,
         }
 
         /* only query rx-filter information of NIC */
-        if (nc->info->type != NET_CLIENT_DRIVER_NIC) {
+        if (nc->info->type != NET_CLIENT_OPTIONS_KIND_NIC) {
             if (has_name) {
                 error_setg(errp, "net client(%s) isn't a NIC", name);
                 return NULL;
@@ -1339,7 +1302,7 @@ RxFilterInfoList *qmp_query_rx_filter(bool has_name, const char *name,
 void hmp_info_network(Monitor *mon, const QDict *qdict)
 {
     NetClientState *nc, *peer;
-    NetClientDriver type;
+    NetClientOptionsKind type;
 
     net_hub_info(mon);
 
@@ -1352,10 +1315,10 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
             continue;
         }
 
-        if (!peer || type == NET_CLIENT_DRIVER_NIC) {
+        if (!peer || type == NET_CLIENT_OPTIONS_KIND_NIC) {
             print_net_client(mon, nc);
         } /* else it's a netdev connected to a NIC, printed with the NIC */
-        if (peer && type == NET_CLIENT_DRIVER_NIC) {
+        if (peer && type == NET_CLIENT_OPTIONS_KIND_NIC) {
             monitor_printf(mon, " \\ ");
             print_net_client(mon, peer);
         }
@@ -1369,7 +1332,7 @@ void qmp_set_link(const char *name, bool up, Error **errp)
     int queues, i;
 
     queues = qemu_find_net_clients_except(name, ncs,
-                                          NET_CLIENT_DRIVER__MAX,
+                                          NET_CLIENT_OPTIONS_KIND__MAX,
                                           MAX_QUEUE_NUM);
 
     if (queues == 0) {
@@ -1396,7 +1359,7 @@ void qmp_set_link(const char *name, bool up, Error **errp)
          * multiple clients that can still communicate with each other in
          * disconnected mode. For now maintain this compatibility.
          */
-        if (nc->peer->info->type == NET_CLIENT_DRIVER_NIC) {
+        if (nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
             for (i = 0; i < queues; i++) {
                 ncs[i]->peer->link_down = !up;
             }
@@ -1437,7 +1400,7 @@ void net_cleanup(void)
      */
     while (!QTAILQ_EMPTY(&net_clients)) {
         nc = QTAILQ_FIRST(&net_clients);
-        if (nc->info->type == NET_CLIENT_DRIVER_NIC) {
+        if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
             qemu_del_nic(qemu_get_nic(nc));
         } else {
             qemu_del_net_client(nc);
@@ -1452,12 +1415,24 @@ void net_check_clients(void)
     NetClientState *nc;
     int i;
 
+    /* Don't warn about the default network setup that you get if
+     * no command line -net or -netdev options are specified. There
+     * are two cases that we would otherwise complain about:
+     * (1) board doesn't support a NIC but the implicit "-net nic"
+     * requested one
+     * (2) CONFIG_SLIRP not set, in which case the implicit "-net nic"
+     * sets up a nic that isn't connected to anything.
+     */
+    if (default_net) {
+        return;
+    }
+
     net_hub_check_clients();
 
     QTAILQ_FOREACH(nc, &net_clients, next) {
         if (!nc->peer) {
             fprintf(stderr, "Warning: %s %s has no peer\n",
-                    nc->info->type == NET_CLIENT_DRIVER_NIC ?
+                    nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC ?
                     "nic" : "netdev", nc->name);
         }
     }
@@ -1481,7 +1456,7 @@ static int net_init_client(void *dummy, QemuOpts *opts, Error **errp)
 {
     Error *local_err = NULL;
 
-    net_client_init(opts, false, &local_err);
+    net_client_init(opts, 0, &local_err);
     if (local_err) {
         error_report_err(local_err);
         return -1;
@@ -1495,7 +1470,7 @@ static int net_init_netdev(void *dummy, QemuOpts *opts, Error **errp)
     Error *local_err = NULL;
     int ret;
 
-    ret = net_client_init(opts, true, &local_err);
+    ret = net_client_init(opts, 1, &local_err);
     if (local_err) {
         error_report_err(local_err);
         return -1;
@@ -1508,6 +1483,14 @@ int net_init_clients(void)
 {
     QemuOptsList *net = qemu_find_opts("net");
 
+    if (default_net) {
+        /* if no clients, we use a default config */
+        qemu_opts_set(net, NULL, "type", "nic", &error_abort);
+#ifdef CONFIG_SLIRP
+        qemu_opts_set(net, NULL, "type", "user", &error_abort);
+#endif
+    }
+
     net_change_state_entry =
         qemu_add_vm_change_state_handler(net_vm_change_state_handler, NULL);
 
@@ -1538,6 +1521,7 @@ int net_client_parse(QemuOptsList *opts_list, const char *optarg)
         return -1;
     }
 
+    default_net = 0;
     return 0;
 }
 
@@ -1589,73 +1573,3 @@ QemuOptsList qemu_net_opts = {
         { /* end of list */ }
     },
 };
-
-void net_socket_rs_init(SocketReadState *rs,
-                        SocketReadStateFinalize *finalize)
-{
-    rs->state = 0;
-    rs->index = 0;
-    rs->packet_len = 0;
-    memset(rs->buf, 0, sizeof(rs->buf));
-    rs->finalize = finalize;
-}
-
-/*
- * Returns
- * 0: success
- * -1: error occurs
- */
-int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
-{
-    unsigned int l;
-
-    while (size > 0) {
-        /* reassemble a packet from the network */
-        switch (rs->state) { /* 0 = getting length, 1 = getting data */
-        case 0:
-            l = 4 - rs->index;
-            if (l > size) {
-                l = size;
-            }
-            memcpy(rs->buf + rs->index, buf, l);
-            buf += l;
-            size -= l;
-            rs->index += l;
-            if (rs->index == 4) {
-                /* got length */
-                rs->packet_len = ntohl(*(uint32_t *)rs->buf);
-                rs->index = 0;
-                rs->state = 1;
-            }
-            break;
-        case 1:
-            l = rs->packet_len - rs->index;
-            if (l > size) {
-                l = size;
-            }
-            if (rs->index + l <= sizeof(rs->buf)) {
-                memcpy(rs->buf + rs->index, buf, l);
-            } else {
-                fprintf(stderr, "serious error: oversized packet received,"
-                    "connection terminated.\n");
-                rs->index = rs->state = 0;
-                return -1;
-            }
-
-            rs->index += l;
-            buf += l;
-            size -= l;
-            if (rs->index >= rs->packet_len) {
-                rs->index = 0;
-                rs->state = 0;
-                if (rs->finalize) {
-                    rs->finalize(rs);
-                }
-            }
-            break;
-        }
-    }
-
-    assert(size == 0);
-    return 0;
-}
index 2d11a8f..6cc0db5 100644 (file)
@@ -26,6 +26,7 @@
 #include "qemu/osdep.h"
 #include <sys/ioctl.h>
 #include <net/if.h>
+#include <sys/mman.h>
 #define NETMAP_WITH_LIBS
 #include <net/netmap.h>
 #include <net/netmap_user.h>
@@ -400,7 +401,7 @@ static void netmap_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
 
 /* NetClientInfo methods */
 static NetClientInfo net_netmap_info = {
-    .type = NET_CLIENT_DRIVER_NETMAP,
+    .type = NET_CLIENT_OPTIONS_KIND_NETMAP,
     .size = sizeof(NetmapState),
     .receive = netmap_receive,
     .receive_iov = netmap_receive_iov,
@@ -418,10 +419,10 @@ static NetClientInfo net_netmap_info = {
  *
  * ... -net netmap,ifname="..."
  */
-int net_init_netmap(const Netdev *netdev,
+int net_init_netmap(const NetClientOptions *opts,
                     const char *name, NetClientState *peer, Error **errp)
 {
-    const NetdevNetmapOptions *netmap_opts = &netdev->u.netmap;
+    const NetdevNetmapOptions *netmap_opts = opts->u.netmap.data;
     struct nm_desc *nmd;
     NetClientState *nc;
     Error *err = NULL;
index b60893f..31630f0 100644 (file)
@@ -38,7 +38,6 @@
 #include "slirp/libslirp.h"
 #include "slirp/ip6.h"
 #include "sysemu/char.h"
-#include "sysemu/sysemu.h"
 #include "qemu/cutils.h"
 
 static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
@@ -77,7 +76,6 @@ typedef struct SlirpState {
     NetClientState nc;
     QTAILQ_ENTRY(SlirpState) entry;
     Slirp *slirp;
-    Notifier exit_notifier;
 #ifndef _WIN32
     char smb_dir[128];
 #endif
@@ -120,26 +118,17 @@ static ssize_t net_slirp_receive(NetClientState *nc, const uint8_t *buf, size_t
     return size;
 }
 
-static void slirp_smb_exit(Notifier *n, void *data)
-{
-    SlirpState *s = container_of(n, SlirpState, exit_notifier);
-    slirp_smb_cleanup(s);
-}
-
 static void net_slirp_cleanup(NetClientState *nc)
 {
     SlirpState *s = DO_UPCAST(SlirpState, nc, nc);
 
     slirp_cleanup(s->slirp);
-    if (s->exit_notifier.notify) {
-        qemu_remove_exit_notifier(&s->exit_notifier);
-    }
     slirp_smb_cleanup(s);
     QTAILQ_REMOVE(&slirp_stacks, s, entry);
 }
 
 static NetClientInfo net_slirp_info = {
-    .type = NET_CLIENT_DRIVER_USER,
+    .type = NET_CLIENT_OPTIONS_KIND_USER,
     .size = sizeof(SlirpState),
     .receive = net_slirp_receive,
     .cleanup = net_slirp_cleanup,
@@ -360,8 +349,6 @@ static int net_slirp_init(NetClientState *peer, const char *model,
     }
 #endif
 
-    s->exit_notifier.notify = slirp_smb_exit;
-    qemu_add_exit_notifier(&s->exit_notifier);
     return 0;
 
 error:
@@ -830,7 +817,7 @@ static const char **slirp_dnssearch(const StringList *dnsname)
     return ret;
 }
 
-int net_init_slirp(const Netdev *netdev, const char *name,
+int net_init_slirp(const NetClientOptions *opts, const char *name,
                    NetClientState *peer, Error **errp)
 {
     /* FIXME error_setg(errp, ...) on failure */
@@ -841,8 +828,8 @@ int net_init_slirp(const Netdev *netdev, const char *name,
     const char **dnssearch;
     bool ipv4 = true, ipv6 = true;
 
-    assert(netdev->type == NET_CLIENT_DRIVER_USER);
-    user = &netdev->u.user;
+    assert(opts->type == NET_CLIENT_OPTIONS_KIND_USER);
+    user = opts->u.user.data;
 
     if ((user->has_ipv6 && user->ipv6 && !user->has_ipv4) ||
         (user->has_ipv4 && !user->ipv4)) {
index 3f98eef..9fa2cd8 100644 (file)
@@ -38,8 +38,11 @@ typedef struct NetSocketState {
     NetClientState nc;
     int listen_fd;
     int fd;
-    SocketReadState rs;
+    int state; /* 0 = getting length, 1 = getting data */
+    unsigned int index;
+    unsigned int packet_len;
     unsigned int send_index;      /* number of bytes sent (only SOCK_STREAM) */
+    uint8_t buf[NET_BUFSIZE];
     struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
     IOHandler *send_fn;           /* differs between SOCK_STREAM/SOCK_DGRAM */
     bool read_poll;               /* waiting to receive data? */
@@ -140,22 +143,11 @@ static void net_socket_send_completed(NetClientState *nc, ssize_t len)
     }
 }
 
-static void net_socket_rs_finalize(SocketReadState *rs)
-{
-    NetSocketState *s = container_of(rs, NetSocketState, rs);
-
-    if (qemu_send_packet_async(&s->nc, rs->buf,
-                               rs->packet_len,
-                               net_socket_send_completed) == 0) {
-        net_socket_read_poll(s, false);
-    }
-}
-
 static void net_socket_send(void *opaque)
 {
     NetSocketState *s = opaque;
     int size;
-    int ret;
+    unsigned l;
     uint8_t buf1[NET_BUFSIZE];
     const uint8_t *buf;
 
@@ -174,18 +166,61 @@ static void net_socket_send(void *opaque)
         closesocket(s->fd);
 
         s->fd = -1;
-        net_socket_rs_init(&s->rs, net_socket_rs_finalize);
+        s->state = 0;
+        s->index = 0;
+        s->packet_len = 0;
         s->nc.link_down = true;
+        memset(s->buf, 0, sizeof(s->buf));
         memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
 
         return;
     }
     buf = buf1;
+    while (size > 0) {
+        /* reassemble a packet from the network */
+        switch(s->state) {
+        case 0:
+            l = 4 - s->index;
+            if (l > size)
+                l = size;
+            memcpy(s->buf + s->index, buf, l);
+            buf += l;
+            size -= l;
+            s->index += l;
+            if (s->index == 4) {
+                /* got length */
+                s->packet_len = ntohl(*(uint32_t *)s->buf);
+                s->index = 0;
+                s->state = 1;
+            }
+            break;
+        case 1:
+            l = s->packet_len - s->index;
+            if (l > size)
+                l = size;
+            if (s->index + l <= sizeof(s->buf)) {
+                memcpy(s->buf + s->index, buf, l);
+            } else {
+                fprintf(stderr, "serious error: oversized packet received,"
+                    "connection terminated.\n");
+                s->state = 0;
+                goto eoc;
+            }
 
-    ret = net_fill_rstate(&s->rs, buf, size);
-
-    if (ret == -1) {
-        goto eoc;
+            s->index += l;
+            buf += l;
+            size -= l;
+            if (s->index >= s->packet_len) {
+                s->index = 0;
+                s->state = 0;
+                if (qemu_send_packet_async(&s->nc, s->buf, s->packet_len,
+                                           net_socket_send_completed) == 0) {
+                    net_socket_read_poll(s, false);
+                    break;
+                }
+            }
+            break;
+        }
     }
 }
 
@@ -194,7 +229,7 @@ static void net_socket_send_dgram(void *opaque)
     NetSocketState *s = opaque;
     int size;
 
-    size = qemu_recv(s->fd, s->rs.buf, sizeof(s->rs.buf), 0);
+    size = qemu_recv(s->fd, s->buf, sizeof(s->buf), 0);
     if (size < 0)
         return;
     if (size == 0) {
@@ -203,7 +238,7 @@ static void net_socket_send_dgram(void *opaque)
         net_socket_write_poll(s, false);
         return;
     }
-    if (qemu_send_packet_async(&s->nc, s->rs.buf, size,
+    if (qemu_send_packet_async(&s->nc, s->buf, size,
                                net_socket_send_completed) == 0) {
         net_socket_read_poll(s, false);
     }
@@ -311,7 +346,7 @@ static void net_socket_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_dgram_socket_info = {
-    .type = NET_CLIENT_DRIVER_SOCKET,
+    .type = NET_CLIENT_OPTIONS_KIND_SOCKET,
     .size = sizeof(NetSocketState),
     .receive = net_socket_receive_dgram,
     .cleanup = net_socket_cleanup,
@@ -366,7 +401,6 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
     s->fd = fd;
     s->listen_fd = -1;
     s->send_fn = net_socket_send_dgram;
-    net_socket_rs_init(&s->rs, net_socket_rs_finalize);
     net_socket_read_poll(s, true);
 
     /* mcast: save bound address as dst */
@@ -395,7 +429,7 @@ static void net_socket_connect(void *opaque)
 }
 
 static NetClientInfo net_socket_info = {
-    .type = NET_CLIENT_DRIVER_SOCKET,
+    .type = NET_CLIENT_OPTIONS_KIND_SOCKET,
     .size = sizeof(NetSocketState),
     .receive = net_socket_receive,
     .cleanup = net_socket_cleanup,
@@ -417,7 +451,6 @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
 
     s->fd = fd;
     s->listen_fd = -1;
-    net_socket_rs_init(&s->rs, net_socket_rs_finalize);
 
     /* Disable Nagle algorithm on TCP sockets to reduce latency */
     socket_set_nodelay(fd);
@@ -664,15 +697,15 @@ static int net_socket_udp_init(NetClientState *peer,
     return 0;
 }
 
-int net_init_socket(const Netdev *netdev, const char *name,
+int net_init_socket(const NetClientOptions *opts, const char *name,
                     NetClientState *peer, Error **errp)
 {
     /* FIXME error_setg(errp, ...) on failure */
     Error *err = NULL;
     const NetdevSocketOptions *sock;
 
-    assert(netdev->type == NET_CLIENT_DRIVER_SOCKET);
-    sock = &netdev->u.socket;
+    assert(opts->type == NET_CLIENT_OPTIONS_KIND_SOCKET);
+    sock = opts->u.socket.data;
 
     if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast +
         sock->has_udp != 1) {
index 2f36d10..1dc3a9f 100644 (file)
@@ -50,4 +50,4 @@
 #define TUN_F_TSO_ECN  0x08    /* I can handle TSO with ECN bits. */
 #define TUN_F_UFO      0x10    /* I can handle UFO packets */
 
-#endif /* QEMU_TAP_LINUX_H */
+#endif /* QEMU_TAP_H */
index 662f9b6..f1e142a 100644 (file)
@@ -750,7 +750,7 @@ static void tap_set_vnet_hdr_len(NetClientState *nc, int len)
 }
 
 static NetClientInfo net_tap_win32_info = {
-    .type = NET_CLIENT_DRIVER_TAP,
+    .type = NET_CLIENT_OPTIONS_KIND_TAP,
     .size = sizeof(TAPState),
     .receive = tap_receive,
     .cleanup = tap_cleanup,
@@ -788,14 +788,14 @@ static int tap_win32_init(NetClientState *peer, const char *model,
     return 0;
 }
 
-int net_init_tap(const Netdev *netdev, const char *name,
+int net_init_tap(const NetClientOptions *opts, const char *name,
                  NetClientState *peer, Error **errp)
 {
     /* FIXME error_setg(errp, ...) on failure */
     const NetdevTapOptions *tap;
 
-    assert(netdev->type == NET_CLIENT_DRIVER_TAP);
-    tap = &netdev->u.tap;
+    assert(opts->type == NET_CLIENT_OPTIONS_KIND_TAP);
+    tap = opts->u.tap.data;
 
     if (!tap->has_ifname) {
         error_report("tap: no interface name");
index 6abb962..740e8a2 100644 (file)
--- a/net/tap.c
+++ b/net/tap.c
@@ -58,7 +58,6 @@ typedef struct TAPState {
     bool enabled;
     VHostNetState *vhost_net;
     unsigned host_vnet_hdr_len;
-    Notifier exit;
 } TAPState;
 
 static void launch_script(const char *setup_script, const char *ifname,
@@ -223,7 +222,7 @@ static bool tap_has_ufo(NetClientState *nc)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
-    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
 
     return s->has_ufo;
 }
@@ -232,7 +231,7 @@ static bool tap_has_vnet_hdr(NetClientState *nc)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
-    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
 
     return !!s->host_vnet_hdr_len;
 }
@@ -241,7 +240,7 @@ static bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
-    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
 
     return !!tap_probe_vnet_hdr_len(s->fd, len);
 }
@@ -250,7 +249,7 @@ static void tap_set_vnet_hdr_len(NetClientState *nc, int len)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
-    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
     assert(len == sizeof(struct virtio_net_hdr_mrg_rxbuf) ||
            len == sizeof(struct virtio_net_hdr));
 
@@ -262,7 +261,7 @@ static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
-    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
     assert(!!s->host_vnet_hdr_len == using_vnet_hdr);
 
     s->using_vnet_hdr = using_vnet_hdr;
@@ -293,33 +292,24 @@ static void tap_set_offload(NetClientState *nc, int csum, int tso4,
     tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo);
 }
 
-static void tap_exit_notify(Notifier *notifier, void *data)
-{
-    TAPState *s = container_of(notifier, TAPState, exit);
-    Error *err = NULL;
-
-    if (s->down_script[0]) {
-        launch_script(s->down_script, s->down_script_arg, s->fd, &err);
-        if (err) {
-            error_report_err(err);
-        }
-    }
-}
-
 static void tap_cleanup(NetClientState *nc)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
+    Error *err = NULL;
 
     if (s->vhost_net) {
         vhost_net_cleanup(s->vhost_net);
-        g_free(s->vhost_net);
         s->vhost_net = NULL;
     }
 
     qemu_purge_queued_packets(nc);
 
-    tap_exit_notify(&s->exit, NULL);
-    qemu_remove_exit_notifier(&s->exit);
+    if (s->down_script[0]) {
+        launch_script(s->down_script, s->down_script_arg, s->fd, &err);
+        if (err) {
+            error_report_err(err);
+        }
+    }
 
     tap_read_poll(s, false);
     tap_write_poll(s, false);
@@ -337,14 +327,14 @@ static void tap_poll(NetClientState *nc, bool enable)
 int tap_get_fd(NetClientState *nc)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
-    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
     return s->fd;
 }
 
 /* fd support */
 
 static NetClientInfo net_tap_info = {
-    .type = NET_CLIENT_DRIVER_TAP,
+    .type = NET_CLIENT_OPTIONS_KIND_TAP,
     .size = sizeof(TAPState),
     .receive = tap_receive,
     .receive_raw = tap_receive_raw,
@@ -389,10 +379,6 @@ static TAPState *net_tap_fd_init(NetClientState *peer,
     }
     tap_read_poll(s, true);
     s->vhost_net = NULL;
-
-    s->exit.notify = tap_exit_notify;
-    qemu_add_exit_notifier(&s->exit);
-
     return s;
 }
 
@@ -572,7 +558,7 @@ static int net_bridge_run_helper(const char *helper, const char *bridge,
     }
 }
 
-int net_init_bridge(const Netdev *netdev, const char *name,
+int net_init_bridge(const NetClientOptions *opts, const char *name,
                     NetClientState *peer, Error **errp)
 {
     const NetdevBridgeOptions *bridge;
@@ -580,8 +566,8 @@ int net_init_bridge(const Netdev *netdev, const char *name,
     TAPState *s;
     int fd, vnet_hdr;
 
-    assert(netdev->type == NET_CLIENT_DRIVER_BRIDGE);
-    bridge = &netdev->u.bridge;
+    assert(opts->type == NET_CLIENT_OPTIONS_KIND_BRIDGE);
+    bridge = opts->u.bridge.data;
 
     helper = bridge->has_helper ? bridge->helper : DEFAULT_BRIDGE_HELPER;
     br     = bridge->has_br     ? bridge->br     : DEFAULT_BRIDGE_INTERFACE;
@@ -677,11 +663,6 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
 
         options.backend_type = VHOST_BACKEND_TYPE_KERNEL;
         options.net_backend = &s->nc;
-        if (tap->has_poll_us) {
-            options.busyloop_timeout = tap->poll_us;
-        } else {
-            options.busyloop_timeout = 0;
-        }
 
         if (vhostfdname) {
             vhostfd = monitor_fd_param(cur_mon, vhostfdname, &err);
@@ -706,7 +687,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
             return;
         }
     } else if (vhostfdname) {
-        error_setg(errp, "vhostfd(s)= is not valid without vhost");
+        error_setg(errp, "vhostfd= is not valid without vhost");
     }
 }
 
@@ -736,7 +717,7 @@ static int get_fds(char *str, char *fds[], int max)
     return i;
 }
 
-int net_init_tap(const Netdev *netdev, const char *name,
+int net_init_tap(const NetClientOptions *opts, const char *name,
                  NetClientState *peer, Error **errp)
 {
     const NetdevTapOptions *tap;
@@ -748,8 +729,8 @@ int net_init_tap(const Netdev *netdev, const char *name,
     const char *vhostfdname;
     char ifname[128];
 
-    assert(netdev->type == NET_CLIENT_DRIVER_TAP);
-    tap = &netdev->u.tap;
+    assert(opts->type == NET_CLIENT_OPTIONS_KIND_TAP);
+    tap = opts->u.tap.data;
     queues = tap->has_queues ? tap->queues : 1;
     vhostfdname = tap->has_vhostfd ? tap->vhostfd : NULL;
 
@@ -788,8 +769,8 @@ int net_init_tap(const Netdev *netdev, const char *name,
             return -1;
         }
     } else if (tap->has_fds) {
-        char **fds = g_new0(char *, MAX_TAP_QUEUES);
-        char **vhost_fds = g_new0(char *, MAX_TAP_QUEUES);
+        char *fds[MAX_TAP_QUEUES];
+        char *vhost_fds[MAX_TAP_QUEUES];
         int nfds, nvhosts;
 
         if (tap->has_ifname || tap->has_script || tap->has_downscript ||
@@ -807,7 +788,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
             if (nfds != nvhosts) {
                 error_setg(errp, "The number of fds passed does not match "
                            "the number of vhostfds passed");
-                goto free_fail;
+                return -1;
             }
         }
 
@@ -815,7 +796,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
             fd = monitor_fd_param(cur_mon, fds[i], &err);
             if (fd == -1) {
                 error_propagate(errp, err);
-                goto free_fail;
+                return -1;
             }
 
             fcntl(fd, F_SETFL, O_NONBLOCK);
@@ -825,7 +806,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
             } else if (vnet_hdr != tap_probe_vnet_hdr(fd)) {
                 error_setg(errp,
                            "vnet_hdr not consistent across given tap fds");
-                goto free_fail;
+                return -1;
             }
 
             net_init_tap_one(tap, peer, "tap", name, ifname,
@@ -834,21 +815,9 @@ int net_init_tap(const Netdev *netdev, const char *name,
                              vnet_hdr, fd, &err);
             if (err) {
                 error_propagate(errp, err);
-                goto free_fail;
+                return -1;
             }
         }
-        g_free(fds);
-        g_free(vhost_fds);
-        return 0;
-
-free_fail:
-        for (i = 0; i < nfds; i++) {
-            g_free(fds[i]);
-            g_free(vhost_fds[i]);
-        }
-        g_free(fds);
-        g_free(vhost_fds);
-        return -1;
     } else if (tap->has_helper) {
         if (tap->has_ifname || tap->has_script || tap->has_downscript ||
             tap->has_vnet_hdr || tap->has_queues || tap->has_vhostfds) {
@@ -922,7 +891,7 @@ free_fail:
 VHostNetState *tap_get_vhost_net(NetClientState *nc)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
-    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
     return s->vhost_net;
 }
 
index ae6888f..2378021 100644 (file)
@@ -23,8 +23,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef NET_TAP_INT_H
-#define NET_TAP_INT_H
+#ifndef QEMU_TAP_H
+#define QEMU_TAP_H
 
 #include "qemu-common.h"
 #include "qapi-types.h"
@@ -46,4 +46,4 @@ int tap_fd_enable(int fd);
 int tap_fd_disable(int fd);
 int tap_fd_get_ifname(int fd, char *ifname);
 
-#endif /* NET_TAP_INT_H */
+#endif /* QEMU_TAP_H */
diff --git a/net/trace-events b/net/trace-events
deleted file mode 100644 (file)
index 65c46a4..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# net/vhost-user.c
-vhost_user_event(const char *chr, int event) "chr: %s got event: %d"
index e50e5d6..9427eaa 100644 (file)
--- a/net/vde.c
+++ b/net/vde.c
@@ -68,7 +68,7 @@ static void vde_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_vde_info = {
-    .type = NET_CLIENT_DRIVER_VDE,
+    .type = NET_CLIENT_OPTIONS_KIND_VDE,
     .size = sizeof(VDEState),
     .receive = vde_receive,
     .cleanup = vde_cleanup,
@@ -109,14 +109,14 @@ static int net_vde_init(NetClientState *peer, const char *model,
     return 0;
 }
 
-int net_init_vde(const Netdev *netdev, const char *name,
+int net_init_vde(const NetClientOptions *opts, const char *name,
                  NetClientState *peer, Error **errp)
 {
     /* FIXME error_setg(errp, ...) on failure */
     const NetdevVdeOptions *vde;
 
-    assert(netdev->type == NET_CLIENT_DRIVER_VDE);
-    vde = &netdev->u.vde;
+    assert(opts->type == NET_CLIENT_OPTIONS_KIND_VDE);
+    vde = opts->u.vde.data;
 
     /* missing optional values have been initialized to "all bits zero" */
     if (net_vde_init(peer, "vde", name, vde->sock, vde->port, vde->group,
index b0595f8..1b9e73a 100644 (file)
@@ -22,9 +22,6 @@ typedef struct VhostUserState {
     NetClientState nc;
     CharDriverState *chr;
     VHostNetState *vhost_net;
-    guint watch;
-    uint64_t acked_features;
-    bool started;
 } VhostUserState;
 
 typedef struct VhostUserChardevProps {
@@ -35,15 +32,13 @@ typedef struct VhostUserChardevProps {
 VHostNetState *vhost_user_get_vhost_net(NetClientState *nc)
 {
     VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
-    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_USER);
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
     return s->vhost_net;
 }
 
-uint64_t vhost_user_get_acked_features(NetClientState *nc)
+static int vhost_user_running(VhostUserState *s)
 {
-    VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
-    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_USER);
-    return s->acked_features;
+    return (s->vhost_net) ? 1 : 0;
 }
 
 static void vhost_user_stop(int queues, NetClientState *ncs[])
@@ -52,17 +47,16 @@ static void vhost_user_stop(int queues, NetClientState *ncs[])
     int i;
 
     for (i = 0; i < queues; i++) {
-        assert(ncs[i]->info->type == NET_CLIENT_DRIVER_VHOST_USER);
+        assert (ncs[i]->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
 
         s = DO_UPCAST(VhostUserState, nc, ncs[i]);
+        if (!vhost_user_running(s)) {
+            continue;
+        }
 
         if (s->vhost_net) {
-            /* save acked features */
-            uint64_t features = vhost_net_get_acked_features(s->vhost_net);
-            if (features) {
-                s->acked_features = features;
-            }
             vhost_net_cleanup(s->vhost_net);
+            s->vhost_net = NULL;
         }
     }
 }
@@ -70,7 +64,6 @@ static void vhost_user_stop(int queues, NetClientState *ncs[])
 static int vhost_user_start(int queues, NetClientState *ncs[])
 {
     VhostNetOptions options;
-    struct vhost_net *net = NULL;
     VhostUserState *s;
     int max_queues;
     int i;
@@ -78,42 +71,35 @@ static int vhost_user_start(int queues, NetClientState *ncs[])
     options.backend_type = VHOST_BACKEND_TYPE_USER;
 
     for (i = 0; i < queues; i++) {
-        assert(ncs[i]->info->type == NET_CLIENT_DRIVER_VHOST_USER);
+        assert (ncs[i]->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
 
         s = DO_UPCAST(VhostUserState, nc, ncs[i]);
+        if (vhost_user_running(s)) {
+            continue;
+        }
 
         options.net_backend = ncs[i];
         options.opaque      = s->chr;
-        options.busyloop_timeout = 0;
-        net = vhost_net_init(&options);
-        if (!net) {
+        s->vhost_net = vhost_net_init(&options);
+        if (!s->vhost_net) {
             error_report("failed to init vhost_net for queue %d", i);
             goto err;
         }
 
         if (i == 0) {
-            max_queues = vhost_net_get_max_queues(net);
+            max_queues = vhost_net_get_max_queues(s->vhost_net);
             if (queues > max_queues) {
                 error_report("you are asking more queues than supported: %d",
                              max_queues);
                 goto err;
             }
         }
-
-        if (s->vhost_net) {
-            vhost_net_cleanup(s->vhost_net);
-            g_free(s->vhost_net);
-        }
-        s->vhost_net = net;
     }
 
     return 0;
 
 err:
-    if (net) {
-        vhost_net_cleanup(net);
-    }
-    vhost_user_stop(i, ncs);
+    vhost_user_stop(i + 1, ncs);
     return -1;
 }
 
@@ -152,34 +138,28 @@ static void vhost_user_cleanup(NetClientState *nc)
 
     if (s->vhost_net) {
         vhost_net_cleanup(s->vhost_net);
-        g_free(s->vhost_net);
         s->vhost_net = NULL;
     }
-    if (s->chr) {
-        qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
-        qemu_chr_fe_release(s->chr);
-        s->chr = NULL;
-    }
 
     qemu_purge_queued_packets(nc);
 }
 
 static bool vhost_user_has_vnet_hdr(NetClientState *nc)
 {
-    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_USER);
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
 
     return true;
 }
 
 static bool vhost_user_has_ufo(NetClientState *nc)
 {
-    assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_USER);
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
 
     return true;
 }
 
 static NetClientInfo net_vhost_user_info = {
-        .type = NET_CLIENT_DRIVER_VHOST_USER,
+        .type = NET_CLIENT_OPTIONS_KIND_VHOST_USER,
         .size = sizeof(VhostUserState),
         .receive = vhost_user_receive,
         .cleanup = vhost_user_cleanup,
@@ -187,16 +167,6 @@ static NetClientInfo net_vhost_user_info = {
         .has_ufo = vhost_user_has_ufo,
 };
 
-static gboolean net_vhost_user_watch(GIOChannel *chan, GIOCondition cond,
-                                           void *opaque)
-{
-    VhostUserState *s = opaque;
-
-    qemu_chr_disconnect(s->chr);
-
-    return FALSE;
-}
-
 static void net_vhost_user_event(void *opaque, int event)
 {
     const char *name = opaque;
@@ -206,7 +176,7 @@ static void net_vhost_user_event(void *opaque, int event)
     int queues;
 
     queues = qemu_find_net_clients_except(name, ncs,
-                                          NET_CLIENT_DRIVER_NIC,
+                                          NET_CLIENT_OPTIONS_KIND_NIC,
                                           MAX_QUEUE_NUM);
     assert(queues < MAX_QUEUE_NUM);
 
@@ -214,20 +184,14 @@ static void net_vhost_user_event(void *opaque, int event)
     trace_vhost_user_event(s->chr->label, event);
     switch (event) {
     case CHR_EVENT_OPENED:
-        s->watch = qemu_chr_fe_add_watch(s->chr, G_IO_HUP,
-                                         net_vhost_user_watch, s);
         if (vhost_user_start(queues, ncs) < 0) {
-            qemu_chr_disconnect(s->chr);
-            return;
+            exit(1);
         }
         qmp_set_link(name, true, &err);
-        s->started = true;
         break;
     case CHR_EVENT_CLOSED:
         qmp_set_link(name, false, &err);
         vhost_user_stop(queues, ncs);
-        g_source_remove(s->watch);
-        s->watch = 0;
         break;
     }
 
@@ -240,7 +204,7 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
                                const char *name, CharDriverState *chr,
                                int queues)
 {
-    NetClientState *nc, *nc0 = NULL;
+    NetClientState *nc;
     VhostUserState *s;
     int i;
 
@@ -249,9 +213,6 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
 
     for (i = 0; i < queues; i++) {
         nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);
-        if (!nc0) {
-            nc0 = nc;
-        }
 
         snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s",
                  i, chr->label);
@@ -262,18 +223,7 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
         s->chr = chr;
     }
 
-    s = DO_UPCAST(VhostUserState, nc, nc0);
-    do {
-        Error *err = NULL;
-        if (qemu_chr_wait_connected(chr, &err) < 0) {
-            error_report_err(err);
-            return -1;
-        }
-        qemu_chr_add_handlers(chr, NULL, NULL,
-                              net_vhost_user_event, nc0->name);
-    } while (!s->started);
-
-    assert(s->vhost_net);
+    qemu_chr_add_handlers(chr, NULL, NULL, net_vhost_user_event, nc[0].name);
 
     return 0;
 }
@@ -330,6 +280,7 @@ static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp)
 {
     const char *name = opaque;
     const char *driver, *netdev;
+    const char virtio_name[] = "virtio-net-";
 
     driver = qemu_opt_get(opts, "driver");
     netdev = qemu_opt_get(opts, "netdev");
@@ -339,7 +290,7 @@ static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp)
     }
 
     if (strcmp(netdev, name) == 0 &&
-        !g_str_has_prefix(driver, "virtio-net-")) {
+        strncmp(driver, virtio_name, strlen(virtio_name)) != 0) {
         error_setg(errp, "vhost-user requires frontend driver virtio-net-*");
         return -1;
     }
@@ -347,15 +298,15 @@ static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp)
     return 0;
 }
 
-int net_init_vhost_user(const Netdev *netdev, const char *name,
+int net_init_vhost_user(const NetClientOptions *opts, const char *name,
                         NetClientState *peer, Error **errp)
 {
     int queues;
     const NetdevVhostUserOptions *vhost_user_opts;
     CharDriverState *chr;
 
-    assert(netdev->type == NET_CLIENT_DRIVER_VHOST_USER);
-    vhost_user_opts = &netdev->u.vhost_user;
+    assert(opts->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
+    vhost_user_opts = opts->u.vhost_user.data;
 
     chr = net_vhost_parse_chardev(vhost_user_opts, errp);
     if (!chr) {
diff --git a/numa.c b/numa.c
index 6289f46..572712c 100644 (file)
--- a/numa.c
+++ b/numa.c
@@ -217,20 +217,20 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
     Error *err = NULL;
 
     {
-        Visitor *v = opts_visitor_new(opts);
-        visit_type_NumaOptions(v, NULL, &object, &err);
-        visit_free(v);
+        OptsVisitor *ov = opts_visitor_new(opts);
+        visit_type_NumaOptions(opts_get_visitor(ov), NULL, &object, &err);
+        opts_visitor_cleanup(ov);
     }
 
     if (err) {
-        goto end;
+        goto error;
     }
 
     switch (object->type) {
     case NUMA_OPTIONS_KIND_NODE:
         numa_node_parse(object->u.node.data, opts, &err);
         if (err) {
-            goto end;
+            goto error;
         }
         nb_numa_nodes++;
         break;
@@ -238,14 +238,13 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
         abort();
     }
 
-end:
+    return 0;
+
+error:
+    error_report_err(err);
     qapi_free_NumaOptions(object);
-    if (err) {
-        error_report_err(err);
-        return -1;
-    }
 
-    return 0;
+    return -1;
 }
 
 static char *enumerate_cpus(unsigned long *cpus, int max_cpus)
@@ -464,7 +463,6 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
             exit(1);
         }
 
-        host_memory_backend_set_mapped(backend, true);
         memory_region_add_subregion(mr, addr, seg);
         vmstate_register_ram_global(seg);
         addr += size;
index c6ddb7d..107fde3 100644 (file)
@@ -26,6 +26,7 @@
 #include "qemu/osdep.h"
 #include <sys/wait.h>
 /*needed for MAP_POPULATE before including qemu-options.h */
+#include <sys/mman.h>
 #include <pwd.h>
 #include <grp.h>
 #include <libgen.h>
@@ -89,7 +90,7 @@ char *os_find_datadir(void)
     if (exec_dir == NULL) {
         return NULL;
     }
-    dir = g_path_get_dirname(exec_dir);
+    dir = dirname(exec_dir);
 
     max_len = strlen(dir) +
         MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
@@ -103,7 +104,6 @@ char *os_find_datadir(void)
         }
     }
 
-    g_free(dir);
     g_free(exec_dir);
     return res;
 }
index 5f85787..cb8a69e 100644 (file)
@@ -13,9 +13,9 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu-common.h"
-#include "qemu/host-utils.h"
 #include "migration/page_cache.h"
 
 #ifdef DEBUG_CACHE
@@ -111,8 +111,11 @@ void cache_fini(PageCache *cache)
 static size_t cache_get_cache_pos(const PageCache *cache,
                                   uint64_t address)
 {
+    size_t pos;
+
     g_assert(cache->max_num_items);
-    return (address / cache->page_size) & (cache->max_num_items - 1);
+    pos = (address / cache->page_size) & (cache->max_num_items - 1);
+    return pos;
 }
 
 static CacheItem *cache_get_by_addr(const PageCache *cache, uint64_t addr)
index 57fb4d8..e7a7e72 100644 (file)
Binary files a/pc-bios/bios-256k.bin and b/pc-bios/bios-256k.bin differ
index 8a6869f..b0ae502 100644 (file)
Binary files a/pc-bios/bios.bin and b/pc-bios/bios.bin differ
index 4e61f9b..4bc89a3 100644 (file)
Binary files a/pc-bios/efi-e1000.rom and b/pc-bios/efi-e1000.rom differ
diff --git a/pc-bios/efi-e1000e.rom b/pc-bios/efi-e1000e.rom
deleted file mode 100644 (file)
index 192a437..0000000
Binary files a/pc-bios/efi-e1000e.rom and /dev/null differ
index 66c5226..85b7f9b 100644 (file)
Binary files a/pc-bios/efi-eepro100.rom and b/pc-bios/efi-eepro100.rom differ
index 8c3e5fd..ebafd84 100644 (file)
Binary files a/pc-bios/efi-ne2k_pci.rom and b/pc-bios/efi-ne2k_pci.rom differ
index 802e225..6f19723 100644 (file)
Binary files a/pc-bios/efi-pcnet.rom and b/pc-bios/efi-pcnet.rom differ
index 8827181..086551b 100644 (file)
Binary files a/pc-bios/efi-rtl8139.rom and b/pc-bios/efi-rtl8139.rom differ
index 2fc0497..140c680 100644 (file)
Binary files a/pc-bios/efi-virtio.rom and b/pc-bios/efi-virtio.rom differ
diff --git a/pc-bios/efi-vmxnet3.rom b/pc-bios/efi-vmxnet3.rom
deleted file mode 100644 (file)
index 3d42635..0000000
Binary files a/pc-bios/efi-vmxnet3.rom and /dev/null differ
diff --git a/pc-bios/linuxboot_dma.bin b/pc-bios/linuxboot_dma.bin
deleted file mode 100644 (file)
index 238a195..0000000
Binary files a/pc-bios/linuxboot_dma.bin and /dev/null differ
index d913fd0..ff980ad 100644 (file)
Binary files a/pc-bios/openbios-ppc and b/pc-bios/openbios-ppc differ
index c8c6fcb..e744e89 100644 (file)
Binary files a/pc-bios/openbios-sparc32 and b/pc-bios/openbios-sparc32 differ
index 73f03a0..4d23be3 100644 (file)
Binary files a/pc-bios/openbios-sparc64 and b/pc-bios/openbios-sparc64 differ
index afa48f1..ce4852a 100644 (file)
@@ -9,44 +9,19 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/optionrom)
 
 .PHONY : all clean build-all
 
-# Compiling with no optimization creates ROMs that are too large
-ifeq ($(lastword $(filter -O%, -O0 $(CFLAGS))),-O0)
-override CFLAGS += -O2
-endif
-
-# Drop -fstack-protector and the like
-QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS)) $(CFLAGS_NOPIE) -ffreestanding
-QEMU_CFLAGS += $(call cc-option, $(QEMU_CFLAGS), -fno-stack-protector)
-QEMU_CFLAGS += $(call cc-option, $(QEMU_CFLAGS), -m16)
-ifeq ($(filter -m16, $(QEMU_CFLAGS)),)
-# Attempt to work around compilers that lack -m16 (GCC <= 4.8, clang <= ??)
-# On GCC we add -fno-toplevel-reorder to keep the order of asm blocks with
-# respect to the rest of the code.  clang does not have -fno-toplevel-reorder,
-# but it places all asm blocks at the beginning and we're relying on it for
-# the option ROM header.  So just force clang not to use the integrated
-# assembler, which doesn't support .code16gcc.
-QEMU_CFLAGS += $(call cc-option, $(QEMU_CFLAGS), -fno-toplevel-reorder)
-QEMU_CFLAGS += $(call cc-option, $(QEMU_CFLAGS), -no-integrated-as)
-QEMU_CFLAGS += -m32 -include $(SRC_PATH)/pc-bios/optionrom/code16gcc.h
-endif
-
-QEMU_INCLUDES += -I$(SRC_PATH)
-
-Wa = -Wa,
-ASFLAGS += -32
-QEMU_CFLAGS += $(call cc-c-option, $(QEMU_CFLAGS), $(Wa)-32)
-
-build-all: multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin
+CFLAGS := -Wall -Wstrict-prototypes -Werror -fomit-frame-pointer -fno-builtin
+CFLAGS += -I$(SRC_PATH)
+CFLAGS += $(call cc-option, $(CFLAGS), -fno-stack-protector)
+CFLAGS += $(CFLAGS_NOPIE)
+QEMU_CFLAGS = $(CFLAGS)
+
+build-all: multiboot.bin linuxboot.bin kvmvapic.bin
 
 # suppress auto-removal of intermediate files
 .SECONDARY:
 
-
-%.o: %.S
-       $(call quiet-command,$(CPP) $(QEMU_INCLUDES) $(QEMU_DGFLAGS) -c -o - $< | $(AS) $(ASFLAGS) -o $@,"  AS    $(TARGET_DIR)$@")
-
 %.img: %.o
-       $(call quiet-command,$(LD) $(LDFLAGS_NOPIE) -m $(LD_I386_EMULATION) -T $(SRC_PATH)/pc-bios/optionrom/flat.lds -s -o $@ $<,"  Building $(TARGET_DIR)$@")
+       $(call quiet-command,$(LD) $(LDFLAGS_NOPIE) -Ttext 0 -e _start -s -o $@ $<,"  Building $(TARGET_DIR)$@")
 
 %.raw: %.img
        $(call quiet-command,$(OBJCOPY) -O binary -j .text $< $@,"  Building $(TARGET_DIR)$@")
diff --git a/pc-bios/optionrom/code16gcc.h b/pc-bios/optionrom/code16gcc.h
deleted file mode 100644 (file)
index 9c8d25d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-asm(
-".code16gcc\n"
-);
diff --git a/pc-bios/optionrom/flat.lds b/pc-bios/optionrom/flat.lds
deleted file mode 100644 (file)
index cee2eda..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-SECTIONS
-{
-  . = 0;
-  .text : { *(.text) *(.text.$) }
-}
-ENTRY(_start)
diff --git a/pc-bios/optionrom/linuxboot_dma.c b/pc-bios/optionrom/linuxboot_dma.c
deleted file mode 100644 (file)
index 7549797..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Linux Boot Option ROM for fw_cfg DMA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Copyright (c) 2015-2016 Red Hat Inc.
- *   Authors:
- *     Marc Marí <marc.mari.barcelo@gmail.com>
- *     Richard W.M. Jones <rjones@redhat.com>
- */
-
-asm(
-".text\n"
-".global _start\n"
-"_start:\n"
-"   .short 0xaa55\n"
-"   .byte 3\n" /* desired size in 512 units; signrom.py adds padding */
-"   .byte 0xcb\n" /* far return without prefix */
-"   .org 0x18\n"
-"   .short 0\n"
-"   .short _pnph\n"
-"_pnph:\n"
-"   .ascii \"$PnP\"\n"
-"   .byte 0x01\n"
-"   .byte (_pnph_len / 16)\n"
-"   .short 0x0000\n"
-"   .byte 0x00\n"
-"   .byte 0x00\n"
-"   .long 0x00000000\n"
-"   .short _manufacturer\n"
-"   .short _product\n"
-"   .long 0x00000000\n"
-"   .short 0x0000\n"
-"   .short 0x0000\n"
-"   .short _bev\n"
-"   .short 0x0000\n"
-"   .short 0x0000\n"
-"   .equ _pnph_len, . - _pnph\n"
-"_manufacturer:\n"
-"   .asciz \"QEMU\"\n"
-"_product:\n"
-"   .asciz \"Linux loader DMA\"\n"
-"   .align 4, 0\n"
-"_bev:\n"
-"   cli\n"
-"   cld\n"
-"   jmp load_kernel\n"
-);
-
-#include "../../include/hw/nvram/fw_cfg_keys.h"
-
-/* QEMU_CFG_DMA_CONTROL bits */
-#define BIOS_CFG_DMA_CTL_ERROR   0x01
-#define BIOS_CFG_DMA_CTL_READ    0x02
-#define BIOS_CFG_DMA_CTL_SKIP    0x04
-#define BIOS_CFG_DMA_CTL_SELECT  0x08
-
-#define BIOS_CFG_DMA_ADDR_HIGH 0x514
-#define BIOS_CFG_DMA_ADDR_LOW  0x518
-
-#define uint64_t unsigned long long
-#define uint32_t unsigned int
-#define uint16_t unsigned short
-
-#define barrier() asm("" : : : "memory")
-
-typedef struct FWCfgDmaAccess {
-    uint32_t control;
-    uint32_t length;
-    uint64_t address;
-} __attribute__((packed)) FWCfgDmaAccess;
-
-static inline void outl(uint32_t value, uint16_t port)
-{
-    asm("outl %0, %w1" : : "a"(value), "Nd"(port));
-}
-
-static inline void set_es(void *addr)
-{
-    uint32_t seg = (uint32_t)addr >> 4;
-    asm("movl %0, %%es" : : "r"(seg));
-}
-
-#ifdef __clang__
-#define ADDR32
-#else
-#define ADDR32 "addr32 "
-#endif
-
-static inline uint16_t readw_es(uint16_t offset)
-{
-    uint16_t val;
-    asm(ADDR32 "movw %%es:(%1), %0" : "=r"(val) : "r"((uint32_t)offset));
-    barrier();
-    return val;
-}
-
-static inline uint32_t readl_es(uint16_t offset)
-{
-    uint32_t val;
-    asm(ADDR32 "movl %%es:(%1), %0" : "=r"(val) : "r"((uint32_t)offset));
-    barrier();
-    return val;
-}
-
-static inline void writel_es(uint16_t offset, uint32_t val)
-{
-    barrier();
-    asm(ADDR32 "movl %0, %%es:(%1)" : : "r"(val), "r"((uint32_t)offset));
-}
-
-static inline uint32_t bswap32(uint32_t x)
-{
-    return
-        ((x & 0x000000ffU) << 24) |
-        ((x & 0x0000ff00U) <<  8) |
-        ((x & 0x00ff0000U) >>  8) |
-        ((x & 0xff000000U) >> 24);
-}
-
-static inline uint64_t bswap64(uint64_t x)
-{
-    return
-        ((x & 0x00000000000000ffULL) << 56) |
-        ((x & 0x000000000000ff00ULL) << 40) |
-        ((x & 0x0000000000ff0000ULL) << 24) |
-        ((x & 0x00000000ff000000ULL) <<  8) |
-        ((x & 0x000000ff00000000ULL) >>  8) |
-        ((x & 0x0000ff0000000000ULL) >> 24) |
-        ((x & 0x00ff000000000000ULL) >> 40) |
-        ((x & 0xff00000000000000ULL) >> 56);
-}
-
-static inline uint64_t cpu_to_be64(uint64_t x)
-{
-    return bswap64(x);
-}
-
-static inline uint32_t cpu_to_be32(uint32_t x)
-{
-    return bswap32(x);
-}
-
-static inline uint32_t be32_to_cpu(uint32_t x)
-{
-    return bswap32(x);
-}
-
-/* clang is happy to inline this function, and bloats the
- * ROM.
- */
-static __attribute__((__noinline__))
-void bios_cfg_read_entry(void *buf, uint16_t entry, uint32_t len)
-{
-    FWCfgDmaAccess access;
-    uint32_t control = (entry << 16) | BIOS_CFG_DMA_CTL_SELECT
-                        | BIOS_CFG_DMA_CTL_READ;
-
-    access.address = cpu_to_be64((uint64_t)(uint32_t)buf);
-    access.length = cpu_to_be32(len);
-    access.control = cpu_to_be32(control);
-
-    barrier();
-
-    outl(cpu_to_be32((uint32_t)&access), BIOS_CFG_DMA_ADDR_LOW);
-
-    while (be32_to_cpu(access.control) & ~BIOS_CFG_DMA_CTL_ERROR) {
-        barrier();
-    }
-}
-
-/* Return top of memory using BIOS function E801. */
-static uint32_t get_e801_addr(void)
-{
-    uint16_t ax, bx, cx, dx;
-    uint32_t ret;
-
-    asm("int $0x15\n"
-        : "=a"(ax), "=b"(bx), "=c"(cx), "=d"(dx)
-        : "a"(0xe801), "b"(0), "c"(0), "d"(0));
-
-    /* Not SeaBIOS, but in theory a BIOS could return CX=DX=0 in which
-     * case we need to use the result from AX & BX instead.
-     */
-    if (cx == 0 && dx == 0) {
-        cx = ax;
-        dx = bx;
-    }
-
-    if (dx) {
-        /* DX = extended memory above 16M, in 64K units.
-         * Convert it to bytes and return.
-         */
-        ret = ((uint32_t)dx + 256 /* 16M in 64K units */) << 16;
-    } else {
-        /* This is a fallback path for machines with <= 16MB of RAM,
-         * which probably would never be the case, but deal with it
-         * anyway.
-         *
-         * CX = extended memory between 1M and 16M, in kilobytes
-         * Convert it to bytes and return.
-         */
-        ret = ((uint32_t)cx + 1024 /* 1M in K */) << 10;
-    }
-
-    return ret;
-}
-
-/* Force the asm name without leading underscore, even on Win32. */
-extern void load_kernel(void) asm("load_kernel");
-
-void load_kernel(void)
-{
-    void *setup_addr;
-    void *initrd_addr;
-    void *kernel_addr;
-    void *cmdline_addr;
-    uint32_t setup_size;
-    uint32_t initrd_size;
-    uint32_t kernel_size;
-    uint32_t cmdline_size;
-    uint32_t initrd_end_page, max_allowed_page;
-    uint32_t segment_addr, stack_addr;
-
-    bios_cfg_read_entry(&setup_addr, FW_CFG_SETUP_ADDR, 4);
-    bios_cfg_read_entry(&setup_size, FW_CFG_SETUP_SIZE, 4);
-    bios_cfg_read_entry(setup_addr, FW_CFG_SETUP_DATA, setup_size);
-
-    set_es(setup_addr);
-
-    /* For protocol < 0x203 we don't have initrd_max ... */
-    if (readw_es(0x206) < 0x203) {
-        /* ... so we assume initrd_max = 0x37ffffff. */
-        writel_es(0x22c, 0x37ffffff);
-    }
-
-    bios_cfg_read_entry(&initrd_addr, FW_CFG_INITRD_ADDR, 4);
-    bios_cfg_read_entry(&initrd_size, FW_CFG_INITRD_SIZE, 4);
-
-    initrd_end_page = ((uint32_t)(initrd_addr + initrd_size) & -4096);
-    max_allowed_page = (readl_es(0x22c) & -4096);
-
-    if (initrd_end_page != 0 && max_allowed_page != 0 &&
-        initrd_end_page != max_allowed_page) {
-        /* Initrd at the end of memory. Compute better initrd address
-         * based on e801 data
-         */
-        initrd_addr = (void *)((get_e801_addr() - initrd_size) & -4096);
-        writel_es(0x218, (uint32_t)initrd_addr);
-
-    }
-
-    bios_cfg_read_entry(initrd_addr, FW_CFG_INITRD_DATA, initrd_size);
-
-    bios_cfg_read_entry(&kernel_addr, FW_CFG_KERNEL_ADDR, 4);
-    bios_cfg_read_entry(&kernel_size, FW_CFG_KERNEL_SIZE, 4);
-    bios_cfg_read_entry(kernel_addr, FW_CFG_KERNEL_DATA, kernel_size);
-
-    bios_cfg_read_entry(&cmdline_addr, FW_CFG_CMDLINE_ADDR, 4);
-    bios_cfg_read_entry(&cmdline_size, FW_CFG_CMDLINE_SIZE, 4);
-    bios_cfg_read_entry(cmdline_addr, FW_CFG_CMDLINE_DATA, cmdline_size);
-
-    /* Boot linux */
-    segment_addr = ((uint32_t)setup_addr >> 4);
-    stack_addr = (uint32_t)(cmdline_addr - setup_addr - 16);
-
-    /* As we are changing critical registers, we cannot leave freedom to the
-     * compiler.
-     */
-    asm("movw %%ax, %%ds\n"
-        "movw %%ax, %%es\n"
-        "movw %%ax, %%fs\n"
-        "movw %%ax, %%gs\n"
-        "movw %%ax, %%ss\n"
-        "movl %%ebx, %%esp\n"
-        "addw $0x20, %%ax\n"
-        "pushw %%ax\n" /* CS */
-        "pushw $0\n" /* IP */
-        /* Clear registers and jump to Linux */
-        "xor %%ebx, %%ebx\n"
-        "xor %%ecx, %%ecx\n"
-        "xor %%edx, %%edx\n"
-        "xor %%edi, %%edi\n"
-        "xor %%ebp, %%ebp\n"
-        "lretw\n"
-        : : "a"(segment_addr), "b"(stack_addr));
-}
index 089f6ba..d3978ba 100644 (file)
Binary files a/pc-bios/s390-ccw.img and b/pc-bios/s390-ccw.img differ
index 0ab2538..4208cb4 100644 (file)
@@ -10,10 +10,8 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw)
 .PHONY : all clean build-all
 
 OBJECTS = start.o main.o bootmap.o sclp-ascii.o virtio.o virtio-scsi.o
-QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS))
-QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float
-QEMU_CFLAGS += -march=z900 -fPIE -fno-strict-aliasing
-QEMU_CFLAGS += $(call cc-option, $(QEMU_CFLAGS), -fno-stack-protector)
+CFLAGS += -fPIE -fno-stack-protector -ffreestanding -march=z900
+CFLAGS += -fno-delete-null-pointer-checks -msoft-float
 LDFLAGS += -Wl,-pie -nostdlib
 
 build-all: s390-ccw.img
diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h
deleted file mode 100644 (file)
index 86abc56..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * QEMU S390 IPL Block
- *
- * Copyright 2015 IBM Corp.
- * Author(s): Alexander Yarygin <yarygin@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or (at
- * your option) any later version. See the COPYING file in the top-level
- * directory.
- */
-
-#ifndef IPLB_H
-#define IPLB_H
-
-struct IplBlockCcw {
-    uint8_t  reserved0[85];
-    uint8_t  ssid;
-    uint16_t devno;
-    uint8_t  vm_flags;
-    uint8_t  reserved3[3];
-    uint32_t vm_parm_len;
-    uint8_t  nss_name[8];
-    uint8_t  vm_parm[64];
-    uint8_t  reserved4[8];
-} __attribute__ ((packed));
-typedef struct IplBlockCcw IplBlockCcw;
-
-struct IplBlockFcp {
-    uint8_t  reserved1[305 - 1];
-    uint8_t  opt;
-    uint8_t  reserved2[3];
-    uint16_t reserved3;
-    uint16_t devno;
-    uint8_t  reserved4[4];
-    uint64_t wwpn;
-    uint64_t lun;
-    uint32_t bootprog;
-    uint8_t  reserved5[12];
-    uint64_t br_lba;
-    uint32_t scp_data_len;
-    uint8_t  reserved6[260];
-    uint8_t  scp_data[];
-} __attribute__ ((packed));
-typedef struct IplBlockFcp IplBlockFcp;
-
-struct IplBlockQemuScsi {
-    uint32_t lun;
-    uint16_t target;
-    uint16_t channel;
-    uint8_t  reserved0[77];
-    uint8_t  ssid;
-    uint16_t devno;
-} __attribute__ ((packed));
-typedef struct IplBlockQemuScsi IplBlockQemuScsi;
-
-struct IplParameterBlock {
-    uint32_t len;
-    uint8_t  reserved0[3];
-    uint8_t  version;
-    uint32_t blk0_len;
-    uint8_t  pbt;
-    uint8_t  flags;
-    uint16_t reserved01;
-    uint8_t  loadparm[8];
-    union {
-        IplBlockCcw ccw;
-        IplBlockFcp fcp;
-        IplBlockQemuScsi scsi;
-    };
-} __attribute__ ((packed));
-typedef struct IplParameterBlock IplParameterBlock;
-
-extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
-
-#define S390_IPL_TYPE_FCP 0x00
-#define S390_IPL_TYPE_CCW 0x02
-#define S390_IPL_TYPE_QEMU_SCSI 0xff
-
-static inline bool store_iplb(IplParameterBlock *iplb)
-{
-    register unsigned long addr asm("0") = (unsigned long) iplb;
-    register unsigned long rc asm("1") = 0;
-
-    asm volatile ("diag %0,%2,0x308\n"
-                  : "+d" (addr), "+d" (rc)
-                  : "d" (6)
-                  : "memory", "cc");
-    return rc == 0x01;
-}
-
-#endif /* IPLB_H */
index 345b848..1c9e079 100644 (file)
@@ -12,8 +12,8 @@
 #include "virtio.h"
 
 char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
+uint64_t boot_value;
 static SubChannelId blk_schid = { .one = 1 };
-IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
 
 /*
  * Priniciples of Operations (SA22-7832-09) chapter 17 requires that
@@ -61,7 +61,7 @@ static bool find_dev(Schib *schib, int dev_no)
     return false;
 }
 
-static void virtio_setup(void)
+static void virtio_setup(uint64_t dev_info)
 {
     Schib schib;
     int ssid;
@@ -75,30 +75,12 @@ static void virtio_setup(void)
      */
     enable_mss_facility();
 
-    if (store_iplb(&iplb)) {
-        switch (iplb.pbt) {
-        case S390_IPL_TYPE_CCW:
-            dev_no = iplb.ccw.devno;
-            debug_print_int("device no. ", dev_no);
-            blk_schid.ssid = iplb.ccw.ssid & 0x3;
-            debug_print_int("ssid ", blk_schid.ssid);
-            found = find_dev(&schib, dev_no);
-            break;
-        case S390_IPL_TYPE_QEMU_SCSI:
-        {
-            VDev *vdev = virtio_get_device();
-
-            vdev->scsi_device_selected = true;
-            vdev->selected_scsi_device.channel = iplb.scsi.channel;
-            vdev->selected_scsi_device.target = iplb.scsi.target;
-            vdev->selected_scsi_device.lun = iplb.scsi.lun;
-            blk_schid.ssid = iplb.scsi.ssid & 0x3;
-            found = find_dev(&schib, iplb.scsi.devno);
-            break;
-        }
-        default:
-            panic("List-directed IPL not supported yet!\n");
-        }
+    if (dev_info != -1) {
+        dev_no = dev_info & 0xffff;
+        debug_print_int("device no. ", dev_no);
+        blk_schid.ssid = (dev_info >> 16) & 0x3;
+        debug_print_int("ssid ", blk_schid.ssid);
+        found = find_dev(&schib, dev_no);
     } else {
         for (ssid = 0; ssid < 0x3; ssid++) {
             blk_schid.ssid = ssid;
@@ -119,7 +101,8 @@ static void virtio_setup(void)
 int main(void)
 {
     sclp_setup();
-    virtio_setup();
+    debug_print_int("boot reg[7] ", boot_value);
+    virtio_setup(boot_value);
 
     zipl_load(); /* no return */
 
index ded67bc..616d967 100644 (file)
@@ -44,7 +44,6 @@ typedef unsigned long long __u64;
 #endif
 
 #include "cio.h"
-#include "iplb.h"
 
 typedef struct irb Irb;
 typedef struct ccw1 Ccw1;
@@ -62,6 +61,7 @@ void consume_sclp_int(void);
 void panic(const char *string);
 void write_subsystem_identification(void);
 extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
+extern uint64_t boot_value;
 
 /* sclp-ascii.c */
 void sclp_print(const char *string);
index 43f9bd2..b6dd8c2 100644 (file)
@@ -14,6 +14,8 @@
 _start:
 
 larl   %r15, stack + 0x8000    /* Set up stack */
+larl    %r6, boot_value
+stg     %r7, 0(%r6)     /* save the boot_value before any function calls */
 j      main                    /* And call C */
 
 /*
index d850a8d..3bb48e9 100644 (file)
@@ -204,17 +204,6 @@ static void virtio_scsi_locate_device(VDev *vdev)
     debug_print_int("config.scsi.max_target ", vdev->config.scsi.max_target);
     debug_print_int("config.scsi.max_lun    ", vdev->config.scsi.max_lun);
 
-    if (vdev->scsi_device_selected) {
-        sdev->channel = vdev->selected_scsi_device.channel;
-        sdev->target = vdev->selected_scsi_device.target;
-        sdev->lun = vdev->selected_scsi_device.lun;
-
-        IPL_check(sdev->channel == 0, "non-zero channel requested");
-        IPL_check(sdev->target <= vdev->config.scsi.max_target, "target# high");
-        IPL_check(sdev->lun <= vdev->config.scsi.max_lun, "LUN# high");
-        return;
-    }
-
     for (target = 0; target <= vdev->config.scsi.max_target; target++) {
         sdev->channel = channel;
         sdev->target = target; /* sdev->lun will be 0 here */
index eb35ea5..3c6e915 100644 (file)
@@ -274,8 +274,6 @@ struct VDev {
     uint64_t scsi_last_block;
     uint32_t scsi_dev_cyls;
     uint8_t scsi_dev_heads;
-    bool scsi_device_selected;
-    ScsiDevice selected_scsi_device;
 };
 typedef struct VDev VDev;
 
index 7bab09d..b271f79 100644 (file)
@@ -32,7 +32,7 @@ update: $(SRCS)
 build: $(OBJS)
 
 clean:
-       rm -f $(OBJS)
+       $(RM) $(OBJS)
 
 install: $(OBJS)
        for obj in $(OBJS); do \
diff --git a/po/bg.po b/po/bg.po
deleted file mode 100644 (file)
index 5047861..0000000
--- a/po/bg.po
+++ /dev/null
@@ -1,90 +0,0 @@
-# Bulgarian translation of qemu po-file.
-# Copyright (C) 2016 Alexander Shopov <ash@kambanaria.org>
-# This file is distributed under the same license as the qemu package.
-# Alexander Shopov <ash@kambanaria.org>, 2016.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: QEMU 2.6.50\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-06-26 10:16+0300\n"
-"PO-Revision-Date: 2016-06-09 15:54+0300\n"
-"Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
-"Language-Team: Bulgarian <dict@ludost.net>\n"
-"Language: bg\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: ui/gtk.c:274
-msgid " - Press Ctrl+Alt+G to release grab"
-msgstr " — натиснете Ctrl+Alt+G, за да освободите фокуса"
-
-#: ui/gtk.c:278
-msgid " [Paused]"
-msgstr " [пауза]"
-
-#: ui/gtk.c:1906
-msgid "_Pause"
-msgstr "_Пауза"
-
-#: ui/gtk.c:1912
-msgid "_Reset"
-msgstr "_Рестартиране"
-
-#: ui/gtk.c:1915
-msgid "Power _Down"
-msgstr "_Изключване"
-
-#: ui/gtk.c:1921
-msgid "_Quit"
-msgstr "_Спиране на програмата"
-
-#: ui/gtk.c:2013
-msgid "_Fullscreen"
-msgstr "На _цял екран"
-
-#: ui/gtk.c:2016
-msgid "_Copy"
-msgstr "_Копиране"
-
-#: ui/gtk.c:2032
-msgid "Zoom _In"
-msgstr "_Увеличаване"
-
-#: ui/gtk.c:2039
-msgid "Zoom _Out"
-msgstr "_Намаляване"
-
-#: ui/gtk.c:2046
-msgid "Best _Fit"
-msgstr "По_местване"
-
-#: ui/gtk.c:2053
-msgid "Zoom To _Fit"
-msgstr "Напас_ване"
-
-#: ui/gtk.c:2059
-msgid "Grab On _Hover"
-msgstr "Прихващане при посо_чване"
-
-#: ui/gtk.c:2062
-msgid "_Grab Input"
-msgstr "Прихващане на _фокуса"
-
-#: ui/gtk.c:2091
-msgid "Show _Tabs"
-msgstr "Подпро_зорци"
-
-#: ui/gtk.c:2094
-msgid "Detach Tab"
-msgstr "Към самостоятелен подпрозорец"
-
-#: ui/gtk.c:2106
-msgid "_Machine"
-msgstr "_Машина"
-
-#: ui/gtk.c:2111
-msgid "_View"
-msgstr "_Изглед"
index 5658723..54634c4 100644 (file)
 #
 # @dirty-sync-count: number of times that dirty ram was synchronized (since 2.1)
 #
-# @postcopy-requests: The number of page requests received from the destination
-#        (since 2.7)
-#
 # Since: 0.14.0
 ##
 { 'struct': 'MigrationStats',
   'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' ,
            'duplicate': 'int', 'skipped': 'int', 'normal': 'int',
            'normal-bytes': 'int', 'dirty-pages-rate' : 'int',
-           'mbps' : 'number', 'dirty-sync-count' : 'int',
-           'postcopy-requests' : 'int' } }
+           'mbps' : 'number', 'dirty-sync-count' : 'int' } }
 
 ##
 # @XBZRLECacheStats
 #        may be expensive, but do not actually occur during the iterative
 #        migration rounds themselves. (since 1.6)
 #
-# @cpu-throttle-percentage: #optional percentage of time guest cpus are being
-#        throttled during auto-converge. This is only present when auto-converge
-#        has started throttling guest cpus. (Since 2.7)
-#
-# @error-desc: #optional the human readable error description string, when
-#              @status is 'failed'. Clients should not attempt to parse the
-#              error strings. (Since 2.7)
+# @x-cpu-throttle-percentage: #optional percentage of time guest cpus are being
+#       throttled during auto-converge. This is only present when auto-converge
+#       has started throttling guest cpus. (Since 2.5)
 #
 # Since: 0.14.0
 ##
            '*expected-downtime': 'int',
            '*downtime': 'int',
            '*setup-time': 'int',
-           '*cpu-throttle-percentage': 'int',
-           '*error-desc': 'str'} }
+           '*x-cpu-throttle-percentage': 'int'} }
 
 ##
 # @query-migrate
 #          compression, so set the decompress-threads to the number about 1/4
 #          of compress-threads is adequate.
 #
-# @cpu-throttle-initial: Initial percentage of time guest cpus are throttled
-#                        when migration auto-converge is activated. The
-#                        default value is 20. (Since 2.7)
-#
-# @cpu-throttle-increment: throttle percentage increase each time
-#                          auto-converge detects that migration is not making
-#                          progress. The default value is 10. (Since 2.7)
-#
-# @tls-creds: ID of the 'tls-creds' object that provides credentials for
-#             establishing a TLS connection over the migration data channel.
-#             On the outgoing side of the migration, the credentials must
-#             be for a 'client' endpoint, while for the incoming side the
-#             credentials must be for a 'server' endpoint. Setting this
-#             will enable TLS for all migrations. The default is unset,
-#             resulting in unsecured migration at the QEMU level. (Since 2.7)
-#
-# @tls-hostname: hostname of the target host for the migration. This is
-#                required when using x509 based TLS credentials and the
-#                migration URI does not already include a hostname. For
-#                example if using fd: or exec: based migration, the
-#                hostname must be provided so that the server's x509
-#                certificate identity can be validated. (Since 2.7)
+# @x-cpu-throttle-initial: Initial percentage of time guest cpus are throttled
+#                          when migration auto-converge is activated. The
+#                          default value is 20. (Since 2.5)
 #
+# @x-cpu-throttle-increment: throttle percentage increase each time
+#                            auto-converge detects that migration is not making
+#                            progress. The default value is 10. (Since 2.5)
 # Since: 2.4
 ##
 { 'enum': 'MigrationParameter',
   'data': ['compress-level', 'compress-threads', 'decompress-threads',
-           'cpu-throttle-initial', 'cpu-throttle-increment',
-           'tls-creds', 'tls-hostname'] }
+           'x-cpu-throttle-initial', 'x-cpu-throttle-increment'] }
 
 #
 # @migrate-set-parameters
 #
 # @decompress-threads: decompression thread count
 #
-# @cpu-throttle-initial: Initial percentage of time guest cpus are throttled
-#                        when migration auto-converge is activated. The
-#                        default value is 20. (Since 2.7)
-#
-# @cpu-throttle-increment: throttle percentage increase each time
-#                          auto-converge detects that migration is not making
-#                          progress. The default value is 10. (Since 2.7)
-#
-# @tls-creds: ID of the 'tls-creds' object that provides credentials for
-#             establishing a TLS connection over the migration data channel.
-#             On the outgoing side of the migration, the credentials must
-#             be for a 'client' endpoint, while for the incoming side the
-#             credentials must be for a 'server' endpoint. Setting this
-#             will enable TLS for all migrations. The default is unset,
-#             resulting in unsecured migration at the QEMU level. (Since 2.7)
-#
-# @tls-hostname: hostname of the target host for the migration. This is
-#                required when using x509 based TLS credentials and the
-#                migration URI does not already include a hostname. For
-#                example if using fd: or exec: based migration, the
-#                hostname must be provided so that the server's x509
-#                certificate identity can be validated. (Since 2.7)
+# @x-cpu-throttle-initial: Initial percentage of time guest cpus are throttled
+#                          when migration auto-converge is activated. The
+#                          default value is 20. (Since 2.5)
 #
+# @x-cpu-throttle-increment: throttle percentage increase each time
+#                            auto-converge detects that migration is not making
+#                            progress. The default value is 10. (Since 2.5)
 # Since: 2.4
 ##
 { 'command': 'migrate-set-parameters',
   'data': { '*compress-level': 'int',
             '*compress-threads': 'int',
             '*decompress-threads': 'int',
-            '*cpu-throttle-initial': 'int',
-            '*cpu-throttle-increment': 'int',
-            '*tls-creds': 'str',
-            '*tls-hostname': 'str'} }
+            '*x-cpu-throttle-initial': 'int',
+            '*x-cpu-throttle-increment': 'int'} }
 
 #
 # @MigrationParameters
 #
 # @decompress-threads: decompression thread count
 #
-# @cpu-throttle-initial: Initial percentage of time guest cpus are throttled
-#                        when migration auto-converge is activated. The
-#                        default value is 20. (Since 2.7)
-#
-# @cpu-throttle-increment: throttle percentage increase each time
-#                          auto-converge detects that migration is not making
-#                          progress. The default value is 10. (Since 2.7)
-#
-# @tls-creds: ID of the 'tls-creds' object that provides credentials for
-#             establishing a TLS connection over the migration data channel.
-#             On the outgoing side of the migration, the credentials must
-#             be for a 'client' endpoint, while for the incoming side the
-#             credentials must be for a 'server' endpoint. Setting this
-#             will enable TLS for all migrations. The default is unset,
-#             resulting in unsecured migration at the QEMU level. (Since 2.7)
-#
-# @tls-hostname: hostname of the target host for the migration. This is
-#                required when using x509 based TLS credentials and the
-#                migration URI does not already include a hostname. For
-#                example if using fd: or exec: based migration, the
-#                hostname must be provided so that the server's x509
-#                certificate identity can be validated. (Since 2.7)
+# @x-cpu-throttle-initial: Initial percentage of time guest cpus are throttled
+#                          when migration auto-converge is activated. The
+#                          default value is 20. (Since 2.5)
+#
+# @x-cpu-throttle-increment: throttle percentage increase each time
+#                            auto-converge detects that migration is not making
+#                            progress. The default value is 10. (Since 2.5)
 #
 # Since: 2.4
 ##
   'data': { 'compress-level': 'int',
             'compress-threads': 'int',
             'decompress-threads': 'int',
-            'cpu-throttle-initial': 'int',
-            'cpu-throttle-increment': 'int',
-            'tls-creds': 'str',
-            'tls-hostname': 'str'} }
+            'x-cpu-throttle-initial': 'int',
+            'x-cpu-throttle-increment': 'int'} }
 ##
 # @query-migrate-parameters
 #
 #
 # @queues: #optional number of queues to be created for multiqueue capable tap
 #
-# @poll-us: #optional maximum number of microseconds that could
-# be spent on busy polling for tap (since 2.7)
-#
 # Since 1.2
 ##
 { 'struct': 'NetdevTapOptions',
     '*vhostfd':    'str',
     '*vhostfds':   'str',
     '*vhostforce': 'bool',
-    '*queues':     'uint32',
-    '*poll-us':    'uint32'} }
+    '*queues':     'uint32'} }
 
 ##
 # @NetdevSocketOptions
     '*queues':        'int' } }
 
 ##
-# @NetClientDriver
-#
-# Available netdev drivers.
-#
-# Since 2.7
-##
-{ 'enum': 'NetClientDriver',
-  'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', 'dump',
-            'bridge', 'hubport', 'netmap', 'vhost-user' ] }
-
-##
-# @Netdev
-#
-# Captures the configuration of a network device.
+# @NetClientOptions
 #
-# @id: identifier for monitor commands.
-#
-# @type: Specify the driver used for interpreting remaining arguments.
+# A discriminated record of network device traits.
 #
 # Since 1.2
 #
 # 'l2tpv3' - since 2.1
+#
 ##
-{ 'union': 'Netdev',
-  'base': { 'id': 'str', 'type': 'NetClientDriver' },
-  'discriminator': 'type',
+{ 'union': 'NetClientOptions',
   'data': {
     'none':     'NetdevNoneOptions',
     'nic':      'NetLegacyNicOptions',
     '*vlan': 'int32',
     '*id':   'str',
     '*name': 'str',
-    'opts':  'NetLegacyOptions' } }
+    'opts':  'NetClientOptions' } }
 
 ##
-# @NetLegacyOptions
+# @Netdev
 #
-# Like Netdev, but for use only by the legacy command line options
+# Captures the configuration of a network device.
+#
+# @id: identifier for monitor commands.
+#
+# @opts: device type specific properties
 #
 # Since 1.2
 ##
-{ 'union': 'NetLegacyOptions',
+{ 'struct': 'Netdev',
   'data': {
-    'none':     'NetdevNoneOptions',
-    'nic':      'NetLegacyNicOptions',
-    'user':     'NetdevUserOptions',
-    'tap':      'NetdevTapOptions',
-    'l2tpv3':   'NetdevL2TPv3Options',
-    'socket':   'NetdevSocketOptions',
-    'vde':      'NetdevVdeOptions',
-    'dump':     'NetdevDumpOptions',
-    'bridge':   'NetdevBridgeOptions',
-    'netmap':   'NetdevNetmapOptions',
-    'vhost-user': 'NetdevVhostUserOptions' } }
+    'id':   'str',
+    'opts': 'NetClientOptions' } }
 
 ##
 # @NetFilterDirection
 # @cpu-max: maximum number of CPUs supported by the machine type
 #           (since 1.5.0)
 #
-# @hotpluggable-cpus: cpu hotplug via -device is supported (since 2.7.0)
-#
 # Since: 1.2.0
 ##
 { 'struct': 'MachineInfo',
   'data': { 'name': 'str', '*alias': 'str',
-            '*is-default': 'bool', 'cpu-max': 'int',
-            'hotpluggable-cpus': 'bool'} }
+            '*is-default': 'bool', 'cpu-max': 'int' } }
 
 ##
 # @query-machines:
 ## @ACPISlotType
 #
 # @DIMM: memory slot
-# @CPU: logical CPU slot (since 2.7)
 #
-{ 'enum': 'ACPISlotType', 'data': [ 'DIMM', 'CPU' ] }
+{ 'enum': 'ACPISlotType', 'data': [ 'DIMM' ] }
 
 ## @ACPIOSTInfo
 #
   'data': [ 'none', 'record', 'play' ] }
 
 ##
-# @xen-load-devices-state:
-#
-# Load the state of all devices from file. The RAM and the block devices
-# of the VM are not loaded by this command.
-#
-# @filename: the file to load the state of the devices from as binary
-# data. See xen-save-devices-state.txt for a description of the binary
-# format.
-#
-# Since: 2.7
-##
-{ 'command': 'xen-load-devices-state', 'data': {'filename': 'str'} }
-
-##
 # @GICCapability:
 #
 # The struct describes capability for a specific GIC (Generic
 # Since: 2.6
 ##
 { 'command': 'query-gic-capabilities', 'returns': ['GICCapability'] }
-
-##
-# CpuInstanceProperties
-#
-# List of properties to be used for hotplugging a CPU instance,
-# it should be passed by management with device_add command when
-# a CPU is being hotplugged.
-#
-# Note: currently there are 4 properties that could be present
-# but management should be prepared to pass through other
-# properties with device_add command to allow for future
-# interface extension. This also requires the filed names to be kept in
-# sync with the properties passed to -device/device_add.
-#
-# @node-id: #optional NUMA node ID the CPU belongs to
-# @socket-id: #optional socket number within node/board the CPU belongs to
-# @core-id: #optional core number within socket the CPU belongs to
-# @thread-id: #optional thread number within core the CPU belongs to
-#
-# Since: 2.7
-##
-{ 'struct': 'CpuInstanceProperties',
-  'data': { '*node-id': 'int',
-            '*socket-id': 'int',
-            '*core-id': 'int',
-            '*thread-id': 'int'
-  }
-}
-
-##
-# @HotpluggableCPU
-#
-# @type: CPU object type for usage with device_add command
-# @props: list of properties to be used for hotplugging CPU
-# @vcpus-count: number of logical VCPU threads @HotpluggableCPU provides
-# @qom-path: #optional link to existing CPU object if CPU is present or
-#            omitted if CPU is not present.
-#
-# Since: 2.7
-##
-{ 'struct': 'HotpluggableCPU',
-  'data': { 'type': 'str',
-            'vcpus-count': 'int',
-            'props': 'CpuInstanceProperties',
-            '*qom-path': 'str'
-          }
-}
-
-##
-# @query-hotpluggable-cpus
-#
-# Returns: a list of HotpluggableCPU objects.
-#
-# Since: 2.7
-##
-{ 'command': 'query-hotpluggable-cpus', 'returns': ['HotpluggableCPU'] }
index 7ea4aeb..2278970 100644 (file)
@@ -1,6 +1,6 @@
 util-obj-y = qapi-visit-core.o qapi-dealloc-visitor.o qmp-input-visitor.o
 util-obj-y += qmp-output-visitor.o qmp-registry.o qmp-dispatch.o
 util-obj-y += string-input-visitor.o string-output-visitor.o
-util-obj-y += opts-visitor.o qapi-clone-visitor.o
+util-obj-y += opts-visitor.o
 util-obj-y += qmp-event.o
 util-obj-y += qapi-util.o
index 5e2d7d7..1d09079 100644 (file)
 { 'union': 'ImageInfoSpecific',
   'data': {
       'qcow2': 'ImageInfoSpecificQCow2',
-      'vmdk': 'ImageInfoSpecificVmdk',
-      # If we need to add block driver specific parameters for
-      # LUKS in future, then we'll subclass QCryptoBlockInfoLUKS
-      # to define a ImageInfoSpecificLUKS
-      'luks': 'QCryptoBlockInfoLUKS'
+      'vmdk': 'ImageInfoSpecificVmdk'
   } }
 
 ##
 # @stop: for guest operations, stop the virtual machine;
 #        for jobs, pause the job
 #
-# @auto: inherit the error handling policy of the backend (since: 2.7)
-#
 # Since: 1.3
 ##
 { 'enum': 'BlockdevOnError',
-  'data': ['report', 'ignore', 'enospc', 'stop', 'auto'] }
+  'data': ['report', 'ignore', 'enospc', 'stop'] }
 
 ##
 # @MirrorSyncMode:
 #
 # @type: the job type ('stream' for image streaming)
 #
-# @device: The job identifier. Originally the device name but other
-#          values are allowed since QEMU 2.7
+# @device: the block device name
 #
 # @len: the maximum progress value
 #
 ##
 # @DriveBackup
 #
-# @job-id: #optional identifier for the newly-created block job. If
-#          omitted, the device name will be used. (Since 2.7)
-#
 # @device: the name of the device which should be copied.
 #
 # @target: the target of the new image. If the file exists, or if it
 # Since: 1.6
 ##
 { 'struct': 'DriveBackup',
-  'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
-            '*format': 'str', 'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
+  'data': { 'device': 'str', 'target': 'str', '*format': 'str',
+            'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
             '*speed': 'int', '*bitmap': 'str',
             '*on-source-error': 'BlockdevOnError',
             '*on-target-error': 'BlockdevOnError' } }
 ##
 # @BlockdevBackup
 #
-# @job-id: #optional identifier for the newly-created block job. If
-#          omitted, the device name will be used. (Since 2.7)
-#
 # @device: the name of the device which should be copied.
 #
-# @target: the device name or node-name of the backup target node.
+# @target: the name of the backup target device.
 #
 # @sync: what parts of the disk image should be copied to the destination
 #        (all the disk, only the sectors allocated in the topmost image, or
 # Since: 2.3
 ##
 { 'struct': 'BlockdevBackup',
-  'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
+  'data': { 'device': 'str', 'target': 'str',
             'sync': 'MirrorSyncMode',
             '*speed': 'int',
             '*on-source-error': 'BlockdevOnError',
 # Live commit of data from overlay image nodes into backing nodes - i.e.,
 # writes data between 'top' and 'base' into 'base'.
 #
-# @job-id: #optional identifier for the newly-created block job. If
-#          omitted, the device name will be used. (Since 2.7)
-#
 # @device:  the name of the device
 #
 # @base:   #optional The file name of the backing image to write data into.
 #
 ##
 { 'command': 'block-commit',
-  'data': { '*job-id': 'str', 'device': 'str', '*base': 'str', '*top': 'str',
+  'data': { 'device': 'str', '*base': 'str', '*top': 'str',
             '*backing-file': 'str', '*speed': 'int' } }
 
 ##
 #
 # Start mirroring a block device's writes to a new destination.
 #
-# See DriveMirror for parameter descriptions
-#
-# Returns: nothing on success
-#          If @device is not a valid block device, DeviceNotFound
-#
-# Since 1.3
-##
-{ 'command': 'drive-mirror', 'boxed': true,
-  'data': 'DriveMirror' }
-
-##
-# DriveMirror
-#
-# A set of parameters describing drive mirror setup.
-#
-# @job-id: #optional identifier for the newly-created block job. If
-#          omitted, the device name will be used. (Since 2.7)
-#
 # @device:  the name of the device whose writes should be mirrored.
 #
 # @target: the target of the new image. If the file exists, or if it
 #         written. Both will result in identical contents.
 #         Default is true. (Since 2.4)
 #
+# Returns: nothing on success
+#          If @device is not a valid block device, DeviceNotFound
+#
 # Since 1.3
 ##
-{ 'struct': 'DriveMirror',
-  'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
-            '*format': 'str', '*node-name': 'str', '*replaces': 'str',
+{ 'command': 'drive-mirror',
+  'data': { 'device': 'str', 'target': 'str', '*format': 'str',
+            '*node-name': 'str', '*replaces': 'str',
             'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
             '*speed': 'int', '*granularity': 'uint32',
             '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
 #
 # Start mirroring a block device's writes to a new destination.
 #
-# @job-id: #optional identifier for the newly-created block job. If
-#          omitted, the device name will be used. (Since 2.7)
-#
 # @device: the name of the device whose writes should be mirrored.
 #
 # @target: the id or node-name of the block device to mirror to. This mustn't be
 # Since 2.6
 ##
 { 'command': 'blockdev-mirror',
-  'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
+  'data': { 'device': 'str', 'target': 'str',
             '*replaces': 'str',
             'sync': 'MirrorSyncMode',
             '*speed': 'int', '*granularity': 'uint32',
 # the device will be removed from its group and the rest of its
 # members will not be affected. The 'group' parameter is ignored.
 #
-# See BlockIOThrottle for parameter descriptions.
-#
-# Returns: Nothing on success
-#          If @device is not a valid block device, DeviceNotFound
-#
-# Since: 1.1
-##
-{ 'command': 'block_set_io_throttle', 'boxed': true,
-  'data': 'BlockIOThrottle' }
-
-##
-# BlockIOThrottle
-#
-# A set of parameters describing block throttling.
-#
 # @device: The name of the device
 #
 # @bps: total throughput limit in bytes per second
 #
 # @group: #optional throttle group name (Since 2.4)
 #
+# Returns: Nothing on success
+#          If @device is not a valid block device, DeviceNotFound
+#
 # Since: 1.1
 ##
-{ 'struct': 'BlockIOThrottle',
+{ 'command': 'block_set_io_throttle',
   'data': { 'device': 'str', 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
             'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
             '*bps_max': 'int', '*bps_rd_max': 'int',
 # On successful completion the image file is updated to drop the backing file
 # and the BLOCK_JOB_COMPLETED event is emitted.
 #
-# @job-id: #optional identifier for the newly-created block job. If
-#          omitted, the device name will be used. (Since 2.7)
-#
 # @device: the device name
 #
 # @base:   #optional the common backing file name
 # Since: 1.1
 ##
 { 'command': 'block-stream',
-  'data': { '*job-id': 'str', 'device': 'str', '*base': 'str',
-            '*backing-file': 'str', '*speed': 'int',
-            '*on-error': 'BlockdevOnError' } }
+  'data': { 'device': 'str', '*base': 'str', '*backing-file': 'str',
+            '*speed': 'int', '*on-error': 'BlockdevOnError' } }
 
 ##
 # @block-job-set-speed:
 #
 # Throttling can be disabled by setting the speed to 0.
 #
-# @device: The job identifier. This used to be a device name (hence
-#          the name of the parameter), but since QEMU 2.7 it can have
-#          other values.
+# @device: the device name
 #
 # @speed:  the maximum speed, in bytes per second, or 0 for unlimited.
 #          Defaults to 0.
 # operation can be started at a later time to finish copying all data from the
 # backing file.
 #
-# @device: The job identifier. This used to be a device name (hence
-#          the name of the parameter), but since QEMU 2.7 it can have
-#          other values.
+# @device: the device name
 #
 # @force: #optional whether to allow cancellation of a paused job (default
 #         false).  Since 1.3.
 # the operation is actually paused.  Cancelling a paused job automatically
 # resumes it.
 #
-# @device: The job identifier. This used to be a device name (hence
-#          the name of the parameter), but since QEMU 2.7 it can have
-#          other values.
+# @device: the device name
 #
 # Returns: Nothing on success
 #          If no background operation is active on this device, DeviceNotActive
 #
 # This command also clears the error status of the job.
 #
-# @device: The job identifier. This used to be a device name (hence
-#          the name of the parameter), but since QEMU 2.7 it can have
-#          other values.
+# @device: the device name
 #
 # Returns: Nothing on success
 #          If no background operation is active on this device, DeviceNotActive
 #
 # A cancelled or paused job cannot be completed.
 #
-# @device: The job identifier. This used to be a device name (hence
-#          the name of the parameter), but since QEMU 2.7 it can have
-#          other values.
+# @device: the device name
 #
 # Returns: Nothing on success
 #          If no background operation is active on this device, DeviceNotActive
 # Drivers that are supported in block device operations.
 #
 # @host_device, @host_cdrom: Since 2.1
-# @gluster: Since 2.7
 #
 # Since: 2.0
 ##
 { 'enum': 'BlockdevDriver',
   'data': [ 'archipelago', 'blkdebug', 'blkverify', 'bochs', 'cloop',
-            'dmg', 'file', 'ftp', 'ftps', 'gluster', 'host_cdrom',
-            'host_device', 'http', 'https', 'luks', 'null-aio', 'null-co',
-            'parallels', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'tftp',
-            'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
+            'dmg', 'file', 'ftp', 'ftps', 'host_cdrom', 'host_device',
+            'http', 'https', 'luks', 'null-aio', 'null-co', 'parallels',
+            'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'tftp', 'vdi', 'vhdx',
+            'vmdk', 'vpc', 'vvfat' ] }
 
 ##
 # @BlockdevOptionsFile
 #
 # @config:          #optional filename of the configuration file
 #
-# @align:           #optional required alignment for requests in bytes,
-#                   must be power of 2, or 0 for default
+# @align:           #optional required alignment for requests in bytes
 #
 # @inject-error:    #optional array of error injection descriptions
 #
             '*read-pattern': 'QuorumReadPattern' } }
 
 ##
-# @GlusterTransport
-#
-# An enumeration of Gluster transport types
-#
-# @tcp:   TCP   - Transmission Control Protocol
-#
-# @unix:  UNIX  - Unix domain socket
-#
-# Since: 2.7
-##
-{ 'enum': 'GlusterTransport',
-  'data': [ 'unix', 'tcp' ] }
-
-
-##
-# @GlusterServer
-#
-# Captures the address of a socket
-#
-# Details for connecting to a gluster server
-#
-# @type:       Transport type used for gluster connection
-#
-# @unix:       socket file
-#
-# @tcp:        host address and port number
-#
-# Since: 2.7
-##
-{ 'union': 'GlusterServer',
-  'base': { 'type': 'GlusterTransport' },
-  'discriminator': 'type',
-  'data': { 'unix': 'UnixSocketAddress',
-            'tcp': 'InetSocketAddress' } }
-
-##
-# @BlockdevOptionsGluster
-#
-# Driver specific block device options for Gluster
-#
-# @volume:      name of gluster volume where VM image resides
-#
-# @path:        absolute path to image file in gluster volume
-#
-# @server:      gluster servers description
-#
-# @debug-level: #optional libgfapi log level (default '4' which is Error)
-#
-# Since: 2.7
-##
-{ 'struct': 'BlockdevOptionsGluster',
-  'data': { 'volume': 'str',
-            'path': 'str',
-            'server': ['GlusterServer'],
-            '*debug-level': 'int' } }
-
-##
 # @BlockdevOptions
 #
 # Options for creating a block device.  Many options are available for all
 # @discard:       #optional discard-related options (default: ignore)
 # @cache:         #optional cache-related options
 # @aio:           #optional AIO backend (default: threads)
+# @rerror:        #optional how to handle read errors on the device
+#                 (default: report)
+# @werror:        #optional how to handle write errors on the device
+#                 (default: enospc)
 # @read-only:     #optional whether the block device should be read-only
 #                 (default: false)
+# @stats-account-invalid: #optional whether to include invalid
+#                         operations when computing last access statistics
+#                         (default: true) (Since 2.5)
+# @stats-account-failed: #optional whether to include failed
+#                         operations when computing latency and last
+#                         access statistics (default: true) (Since 2.5)
+# @stats-intervals: #optional list of intervals for collecting I/O
+#                   statistics, in seconds (default: none) (Since 2.5)
 # @detect-zeroes: #optional detect and optimize zero writes (Since 2.1)
 #                 (default: off)
 #
 ##
 { 'union': 'BlockdevOptions',
   'base': { 'driver': 'BlockdevDriver',
-# TODO 'id' is a BB-level option, remove it
             '*id': 'str',
             '*node-name': 'str',
             '*discard': 'BlockdevDiscardOptions',
             '*cache': 'BlockdevCacheOptions',
             '*aio': 'BlockdevAioOptions',
+            '*rerror': 'BlockdevOnError',
+            '*werror': 'BlockdevOnError',
             '*read-only': 'bool',
+            '*stats-account-invalid': 'bool',
+            '*stats-account-failed': 'bool',
+            '*stats-intervals': ['int'],
             '*detect-zeroes': 'BlockdevDetectZeroesOptions' },
   'discriminator': 'driver',
   'data': {
       'file':       'BlockdevOptionsFile',
       'ftp':        'BlockdevOptionsFile',
       'ftps':       'BlockdevOptionsFile',
-      'gluster':    'BlockdevOptionsGluster',
+# TODO gluster: Wait for structured options
       'host_cdrom': 'BlockdevOptionsFile',
       'host_device':'BlockdevOptionsFile',
       'http':       'BlockdevOptionsFile',
 #
 # @type: job type
 #
-# @device: The job identifier. Originally the device name but other
-#          values are allowed since QEMU 2.7
+# @device: device name
 #
 # @len: maximum progress value
 #
 #
 # @type: job type
 #
-# @device: The job identifier. Originally the device name but other
-#          values are allowed since QEMU 2.7
+# @device: device name
 #
 # @len: maximum progress value
 #
 #
 # Emitted when a block job encounters an error
 #
-# @device: The job identifier. Originally the device name but other
-#          values are allowed since QEMU 2.7
+# @device: device name
 #
 # @operation: I/O operation
 #
 #
 # @type: job type
 #
-# @device: The job identifier. Originally the device name but other
-#          values are allowed since QEMU 2.7
+# @device: device name
 #
 # @len: maximum progress value
 #
 ##
 { 'command': 'block-set-write-threshold',
   'data': { 'node-name': 'str', 'write-threshold': 'uint64' } }
-
-##
-# @x-blockdev-change
-#
-# Dynamically reconfigure the block driver state graph. It can be used
-# to add, remove, insert or replace a graph node. Currently only the
-# Quorum driver implements this feature to add or remove its child. This
-# is useful to fix a broken quorum child.
-#
-# If @node is specified, it will be inserted under @parent. @child
-# may not be specified in this case. If both @parent and @child are
-# specified but @node is not, @child will be detached from @parent.
-#
-# @parent: the id or name of the parent node.
-#
-# @child: #optional the name of a child under the given parent node.
-#
-# @node: #optional the name of the node that will be added.
-#
-# Note: this command is experimental, and its API is not stable. It
-# does not support all kinds of operations, all kinds of children, nor
-# all block drivers.
-#
-# Warning: The data in a new quorum child MUST be consistent with that of
-# the rest of the array.
-#
-# Since: 2.7
-##
-{ 'command': 'x-blockdev-change',
-  'data' : { 'parent': 'str',
-             '*child': 'str',
-             '*node': 'str' } }
index 34d2583..760d0c0 100644 (file)
 #
 # @md5: MD5. Should not be used in any new code, legacy compat only
 # @sha1: SHA-1. Should not be used in any new code, legacy compat only
-# @sha224: SHA-224. (since 2.7)
 # @sha256: SHA-256. Current recommended strong hash.
-# @sha384: SHA-384. (since 2.7)
-# @sha512: SHA-512. (since 2.7)
-# @ripemd160: RIPEMD-160. (since 2.7)
 # Since: 2.6
 ##
 { 'enum': 'QCryptoHashAlgorithm',
   'prefix': 'QCRYPTO_HASH_ALG',
-  'data': ['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'ripemd160']}
+  'data': ['md5', 'sha1', 'sha256']}
 
 
 ##
   'discriminator': 'format',
   'data': { 'qcow': 'QCryptoBlockOptionsQCow',
             'luks': 'QCryptoBlockCreateOptionsLUKS' } }
-
-
-##
-# QCryptoBlockInfoBase:
-#
-# The common information that applies to all full disk
-# encryption formats
-#
-# @format: the encryption format
-#
-# Since: 2.7
-##
-{ 'struct': 'QCryptoBlockInfoBase',
-  'data': { 'format': 'QCryptoBlockFormat' }}
-
-
-##
-# QCryptoBlockInfoLUKSSlot:
-#
-# Information about the LUKS block encryption key
-# slot options
-#
-# @active: whether the key slot is currently in use
-# @key-offset: offset to the key material in bytes
-# @iters: #optional number of PBKDF2 iterations for key material
-# @stripes: #optional number of stripes for splitting key material
-#
-# Since: 2.7
-##
-{ 'struct': 'QCryptoBlockInfoLUKSSlot',
-  'data': {'active': 'bool',
-           '*iters': 'int',
-           '*stripes': 'int',
-           'key-offset': 'int' } }
-
-
-##
-# QCryptoBlockInfoLUKS:
-#
-# Information about the LUKS block encryption options
-#
-# @cipher-alg: the cipher algorithm for data encryption
-# @cipher-mode: the cipher mode for data encryption
-# @ivgen-alg: the initialization vector generator
-# @ivgen-hash-alg: #optional the initialization vector generator hash
-# @hash-alg: the master key hash algorithm
-# @payload-offset: offset to the payload data in bytes
-# @master-key-iters: number of PBKDF2 iterations for key material
-# @uuid: unique identifier for the volume
-# @slots: information about each key slot
-#
-# Since: 2.7
-##
-{ 'struct': 'QCryptoBlockInfoLUKS',
-  'data': {'cipher-alg': 'QCryptoCipherAlgorithm',
-           'cipher-mode': 'QCryptoCipherMode',
-           'ivgen-alg': 'QCryptoIVGenAlgorithm',
-           '*ivgen-hash-alg': 'QCryptoHashAlgorithm',
-           'hash-alg': 'QCryptoHashAlgorithm',
-           'payload-offset': 'int',
-           'master-key-iters': 'int',
-           'uuid': 'str',
-           'slots': [ 'QCryptoBlockInfoLUKSSlot' ] }}
-
-##
-# QCryptoBlockInfoQCow:
-#
-# Information about the QCow block encryption options
-#
-# Since: 2.7
-##
-{ 'struct': 'QCryptoBlockInfoQCow',
-  'data': { }}
-
-
-##
-# QCryptoBlockInfo:
-#
-# Information about the block encryption options
-#
-# Since: 2.7
-##
-{ 'union': 'QCryptoBlockInfo',
-  'base': 'QCryptoBlockInfoBase',
-  'discriminator': 'format',
-  'data': { 'qcow': 'QCryptoBlockInfoQCow',
-            'luks': 'QCryptoBlockInfoLUKS' } }
index 1048bbc..602f260 100644 (file)
@@ -23,8 +23,9 @@
 enum ListMode
 {
     LM_NONE,             /* not traversing a list of repeated options */
+    LM_STARTED,          /* opts_start_list() succeeded */
 
-    LM_IN_PROGRESS,      /* opts_next_list() ready to be called.
+    LM_IN_PROGRESS,      /* opts_next_list() has been called.
                           *
                           * Generating the next list link will consume the most
                           * recently parsed QemuOpt instance of the repeated
@@ -132,7 +133,7 @@ opts_start_struct(Visitor *v, const char *name, void **obj,
     const QemuOpt *opt;
 
     if (obj) {
-        *obj = g_malloc0(size);
+        *obj = g_malloc0(size > 0 ? size : 1);
     }
     if (ov->depth++ > 0) {
         return;
@@ -158,13 +159,13 @@ opts_start_struct(Visitor *v, const char *name, void **obj,
 
 
 static void
-opts_check_struct(Visitor *v, Error **errp)
+opts_end_struct(Visitor *v, Error **errp)
 {
     OptsVisitor *ov = to_ov(v);
     GHashTableIter iter;
     GQueue *any;
 
-    if (ov->depth > 0) {
+    if (--ov->depth > 0) {
         return;
     }
 
@@ -176,18 +177,6 @@ opts_check_struct(Visitor *v, Error **errp)
         first = g_queue_peek_head(any);
         error_setg(errp, QERR_INVALID_PARAMETER, first->name);
     }
-}
-
-
-static void
-opts_end_struct(Visitor *v, void **obj)
-{
-    OptsVisitor *ov = to_ov(v);
-
-    if (--ov->depth > 0) {
-        return;
-    }
-
     g_hash_table_destroy(ov->unprocessed_opts);
     ov->unprocessed_opts = NULL;
     if (ov->fake_id_opt) {
@@ -213,33 +202,35 @@ lookup_distinct(const OptsVisitor *ov, const char *name, Error **errp)
 
 
 static void
-opts_start_list(Visitor *v, const char *name, GenericList **list, size_t size,
-                Error **errp)
+opts_start_list(Visitor *v, const char *name, Error **errp)
 {
     OptsVisitor *ov = to_ov(v);
 
     /* we can't traverse a list in a list */
     assert(ov->list_mode == LM_NONE);
-    /* we don't support visits without a list */
-    assert(list);
     ov->repeated_opts = lookup_distinct(ov, name, errp);
-    if (ov->repeated_opts) {
-        ov->list_mode = LM_IN_PROGRESS;
-        *list = g_malloc0(size);
-    } else {
-        *list = NULL;
+    if (ov->repeated_opts != NULL) {
+        ov->list_mode = LM_STARTED;
     }
 }
 
 
 static GenericList *
-opts_next_list(Visitor *v, GenericList *tail, size_t size)
+opts_next_list(Visitor *v, GenericList **list, size_t size)
 {
     OptsVisitor *ov = to_ov(v);
+    GenericList **link;
 
     switch (ov->list_mode) {
+    case LM_STARTED:
+        ov->list_mode = LM_IN_PROGRESS;
+        link = list;
+        break;
+
     case LM_SIGNED_INTERVAL:
     case LM_UNSIGNED_INTERVAL:
+        link = &(*list)->next;
+
         if (ov->list_mode == LM_SIGNED_INTERVAL) {
             if (ov->range_next.s < ov->range_limit.s) {
                 ++ov->range_next.s;
@@ -260,6 +251,7 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
             g_hash_table_remove(ov->unprocessed_opts, opt->name);
             return NULL;
         }
+        link = &(*list)->next;
         break;
     }
 
@@ -267,17 +259,18 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
         abort();
     }
 
-    tail->next = g_malloc0(size);
-    return tail->next;
+    *link = g_malloc0(size);
+    return *link;
 }
 
 
 static void
-opts_end_list(Visitor *v, void **obj)
+opts_end_list(Visitor *v)
 {
     OptsVisitor *ov = to_ov(v);
 
-    assert(ov->list_mode == LM_IN_PROGRESS ||
+    assert(ov->list_mode == LM_STARTED ||
+           ov->list_mode == LM_IN_PROGRESS ||
            ov->list_mode == LM_SIGNED_INTERVAL ||
            ov->list_mode == LM_UNSIGNED_INTERVAL);
     ov->repeated_opts = NULL;
@@ -321,15 +314,9 @@ opts_type_str(Visitor *v, const char *name, char **obj, Error **errp)
 
     opt = lookup_scalar(ov, name, errp);
     if (!opt) {
-        *obj = NULL;
         return;
     }
     *obj = g_strdup(opt->str ? opt->str : "");
-    /* Note that we consume a string even if this is called as part of
-     * an enum visit that later fails because the string is not a
-     * valid enum value; this is harmless because tracking what gets
-     * consumed only matters to visit_end_struct() as the final error
-     * check if there were no other failures during the visit.  */
     processed(ov, name);
 }
 
@@ -513,36 +500,30 @@ opts_optional(Visitor *v, const char *name, bool *present)
 }
 
 
-static void
-opts_free(Visitor *v)
-{
-    OptsVisitor *ov = to_ov(v);
-
-    if (ov->unprocessed_opts != NULL) {
-        g_hash_table_destroy(ov->unprocessed_opts);
-    }
-    g_free(ov->fake_id_opt);
-    g_free(ov);
-}
-
-
-Visitor *
+OptsVisitor *
 opts_visitor_new(const QemuOpts *opts)
 {
     OptsVisitor *ov;
 
     ov = g_malloc0(sizeof *ov);
 
-    ov->visitor.type = VISITOR_INPUT;
-
     ov->visitor.start_struct = &opts_start_struct;
-    ov->visitor.check_struct = &opts_check_struct;
     ov->visitor.end_struct   = &opts_end_struct;
 
     ov->visitor.start_list = &opts_start_list;
     ov->visitor.next_list  = &opts_next_list;
     ov->visitor.end_list   = &opts_end_list;
 
+    /* input_type_enum() covers both "normal" enums and union discriminators.
+     * The union discriminator field is always generated as "type"; it should
+     * match the "type" QemuOpt child of any QemuOpts.
+     *
+     * input_type_enum() will remove the looked-up key from the
+     * "unprocessed_opts" hash even if the lookup fails, because the removal is
+     * done earlier in opts_type_str(). This should be harmless.
+     */
+    ov->visitor.type_enum = &input_type_enum;
+
     ov->visitor.type_int64  = &opts_type_int64;
     ov->visitor.type_uint64 = &opts_type_uint64;
     ov->visitor.type_size   = &opts_type_size;
@@ -553,9 +534,26 @@ opts_visitor_new(const QemuOpts *opts)
      * skip some mandatory methods... */
 
     ov->visitor.optional = &opts_optional;
-    ov->visitor.free = opts_free;
 
     ov->opts_root = opts;
 
+    return ov;
+}
+
+
+void
+opts_visitor_cleanup(OptsVisitor *ov)
+{
+    if (ov->unprocessed_opts != NULL) {
+        g_hash_table_destroy(ov->unprocessed_opts);
+    }
+    g_free(ov->fake_id_opt);
+    g_free(ov);
+}
+
+
+Visitor *
+opts_get_visitor(OptsVisitor *ov)
+{
     return &ov->visitor;
 }
diff --git a/qapi/qapi-clone-visitor.c b/qapi/qapi-clone-visitor.c
deleted file mode 100644 (file)
index 0bb8216..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copy one QAPI object to another
- *
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qapi/clone-visitor.h"
-#include "qapi/visitor-impl.h"
-#include "qapi/error.h"
-
-struct QapiCloneVisitor {
-    Visitor visitor;
-    size_t depth;
-};
-
-static QapiCloneVisitor *to_qcv(Visitor *v)
-{
-    return container_of(v, QapiCloneVisitor, visitor);
-}
-
-static void qapi_clone_start_struct(Visitor *v, const char *name, void **obj,
-                                    size_t size, Error **errp)
-{
-    QapiCloneVisitor *qcv = to_qcv(v);
-
-    if (!obj) {
-        assert(qcv->depth);
-        /* Only possible when visiting an alternate's object
-         * branch. Nothing further to do here, since the earlier
-         * visit_start_alternate() already copied memory. */
-        return;
-    }
-
-    *obj = g_memdup(*obj, size);
-    qcv->depth++;
-}
-
-static void qapi_clone_end(Visitor *v, void **obj)
-{
-    QapiCloneVisitor *qcv = to_qcv(v);
-
-    assert(qcv->depth);
-    if (obj) {
-        qcv->depth--;
-    }
-}
-
-static void qapi_clone_start_list(Visitor *v, const char *name,
-                                  GenericList **listp, size_t size,
-                                  Error **errp)
-{
-    qapi_clone_start_struct(v, name, (void **)listp, size, errp);
-}
-
-static GenericList *qapi_clone_next_list(Visitor *v, GenericList *tail,
-                                         size_t size)
-{
-    QapiCloneVisitor *qcv = to_qcv(v);
-
-    assert(qcv->depth);
-    /* Unshare the tail of the list cloned by g_memdup() */
-    tail->next = g_memdup(tail->next, size);
-    return tail->next;
-}
-
-static void qapi_clone_start_alternate(Visitor *v, const char *name,
-                                       GenericAlternate **obj, size_t size,
-                                       bool promote_int, Error **errp)
-{
-    qapi_clone_start_struct(v, name, (void **)obj, size, errp);
-}
-
-static void qapi_clone_type_int64(Visitor *v, const char *name, int64_t *obj,
-                                   Error **errp)
-{
-    QapiCloneVisitor *qcv = to_qcv(v);
-
-    assert(qcv->depth);
-    /* Value was already cloned by g_memdup() */
-}
-
-static void qapi_clone_type_uint64(Visitor *v, const char *name,
-                                    uint64_t *obj, Error **errp)
-{
-    QapiCloneVisitor *qcv = to_qcv(v);
-
-    assert(qcv->depth);
-    /* Value was already cloned by g_memdup() */
-}
-
-static void qapi_clone_type_bool(Visitor *v, const char *name, bool *obj,
-                                  Error **errp)
-{
-    QapiCloneVisitor *qcv = to_qcv(v);
-
-    assert(qcv->depth);
-    /* Value was already cloned by g_memdup() */
-}
-
-static void qapi_clone_type_str(Visitor *v, const char *name, char **obj,
-                                 Error **errp)
-{
-    QapiCloneVisitor *qcv = to_qcv(v);
-
-    assert(qcv->depth);
-    /*
-     * Pointer was already cloned by g_memdup; create fresh copy.
-     * Note that as long as qmp-output-visitor accepts NULL instead of
-     * "", then we must do likewise. However, we want to obey the
-     * input visitor semantics of never producing NULL when the empty
-     * string is intended.
-     */
-    *obj = g_strdup(*obj ?: "");
-}
-
-static void qapi_clone_type_number(Visitor *v, const char *name, double *obj,
-                                    Error **errp)
-{
-    QapiCloneVisitor *qcv = to_qcv(v);
-
-    assert(qcv->depth);
-    /* Value was already cloned by g_memdup() */
-}
-
-static void qapi_clone_type_null(Visitor *v, const char *name, Error **errp)
-{
-    QapiCloneVisitor *qcv = to_qcv(v);
-
-    assert(qcv->depth);
-    /* Nothing to do */
-}
-
-static void qapi_clone_free(Visitor *v)
-{
-    g_free(v);
-}
-
-static Visitor *qapi_clone_visitor_new(void)
-{
-    QapiCloneVisitor *v;
-
-    v = g_malloc0(sizeof(*v));
-
-    v->visitor.type = VISITOR_CLONE;
-    v->visitor.start_struct = qapi_clone_start_struct;
-    v->visitor.end_struct = qapi_clone_end;
-    v->visitor.start_list = qapi_clone_start_list;
-    v->visitor.next_list = qapi_clone_next_list;
-    v->visitor.end_list = qapi_clone_end;
-    v->visitor.start_alternate = qapi_clone_start_alternate;
-    v->visitor.end_alternate = qapi_clone_end;
-    v->visitor.type_int64 = qapi_clone_type_int64;
-    v->visitor.type_uint64 = qapi_clone_type_uint64;
-    v->visitor.type_bool = qapi_clone_type_bool;
-    v->visitor.type_str = qapi_clone_type_str;
-    v->visitor.type_number = qapi_clone_type_number;
-    v->visitor.type_null = qapi_clone_type_null;
-    v->visitor.free = qapi_clone_free;
-
-    return &v->visitor;
-}
-
-void *qapi_clone(const void *src, void (*visit_type)(Visitor *, const char *,
-                                                     void **, Error **))
-{
-    Visitor *v;
-    void *dst = (void *) src; /* Cast away const */
-
-    if (!src) {
-        return NULL;
-    }
-
-    v = qapi_clone_visitor_new();
-    visit_type(v, NULL, &dst, &error_abort);
-    visit_free(v);
-    return dst;
-}
index e39457b..6922179 100644 (file)
 #include "qapi/qmp/types.h"
 #include "qapi/visitor-impl.h"
 
+typedef struct StackEntry
+{
+    void *value;
+    bool is_list_head;
+    QTAILQ_ENTRY(StackEntry) node;
+} StackEntry;
+
 struct QapiDeallocVisitor
 {
     Visitor visitor;
+    QTAILQ_HEAD(, StackEntry) stack;
 };
 
+static QapiDeallocVisitor *to_qov(Visitor *v)
+{
+    return container_of(v, QapiDeallocVisitor, visitor);
+}
+
+static void qapi_dealloc_push(QapiDeallocVisitor *qov, void *value)
+{
+    StackEntry *e = g_malloc0(sizeof(*e));
+
+    e->value = value;
+
+    /* see if we're just pushing a list head tracker */
+    if (value == NULL) {
+        e->is_list_head = true;
+    }
+    QTAILQ_INSERT_HEAD(&qov->stack, e, node);
+}
+
+static void *qapi_dealloc_pop(QapiDeallocVisitor *qov)
+{
+    StackEntry *e = QTAILQ_FIRST(&qov->stack);
+    QObject *value;
+    QTAILQ_REMOVE(&qov->stack, e, node);
+    value = e->value;
+    g_free(e);
+    return value;
+}
+
 static void qapi_dealloc_start_struct(Visitor *v, const char *name, void **obj,
                                       size_t unused, Error **errp)
 {
+    QapiDeallocVisitor *qov = to_qov(v);
+    qapi_dealloc_push(qov, obj);
 }
 
-static void qapi_dealloc_end_struct(Visitor *v, void **obj)
+static void qapi_dealloc_end_struct(Visitor *v, Error **errp)
 {
+    QapiDeallocVisitor *qov = to_qov(v);
+    void **obj = qapi_dealloc_pop(qov);
     if (obj) {
         g_free(*obj);
     }
@@ -40,31 +80,51 @@ static void qapi_dealloc_start_alternate(Visitor *v, const char *name,
                                          GenericAlternate **obj, size_t size,
                                          bool promote_int, Error **errp)
 {
+    QapiDeallocVisitor *qov = to_qov(v);
+    qapi_dealloc_push(qov, obj);
 }
 
-static void qapi_dealloc_end_alternate(Visitor *v, void **obj)
+static void qapi_dealloc_end_alternate(Visitor *v)
 {
+    QapiDeallocVisitor *qov = to_qov(v);
+    void **obj = qapi_dealloc_pop(qov);
     if (obj) {
         g_free(*obj);
     }
 }
 
-static void qapi_dealloc_start_list(Visitor *v, const char *name,
-                                    GenericList **list, size_t size,
-                                    Error **errp)
+static void qapi_dealloc_start_list(Visitor *v, const char *name, Error **errp)
 {
+    QapiDeallocVisitor *qov = to_qov(v);
+    qapi_dealloc_push(qov, NULL);
 }
 
-static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList *tail,
+static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList **listp,
                                            size_t size)
 {
-    GenericList *next = tail->next;
-    g_free(tail);
-    return next;
+    GenericList *list = *listp;
+    QapiDeallocVisitor *qov = to_qov(v);
+    StackEntry *e = QTAILQ_FIRST(&qov->stack);
+
+    if (e && e->is_list_head) {
+        e->is_list_head = false;
+        return list;
+    }
+
+    if (list) {
+        list = list->next;
+        g_free(*listp);
+        return list;
+    }
+
+    return NULL;
 }
 
-static void qapi_dealloc_end_list(Visitor *v, void **obj)
+static void qapi_dealloc_end_list(Visitor *v)
 {
+    QapiDeallocVisitor *qov = to_qov(v);
+    void *obj = qapi_dealloc_pop(qov);
+    assert(obj == NULL); /* should've been list head tracker with no payload */
 }
 
 static void qapi_dealloc_type_str(Visitor *v, const char *name, char **obj,
@@ -103,22 +163,27 @@ static void qapi_dealloc_type_anything(Visitor *v, const char *name,
     }
 }
 
-static void qapi_dealloc_type_null(Visitor *v, const char *name, Error **errp)
+static void qapi_dealloc_type_enum(Visitor *v, const char *name, int *obj,
+                                   const char * const strings[], Error **errp)
 {
 }
 
-static void qapi_dealloc_free(Visitor *v)
+Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v)
 {
-    g_free(container_of(v, QapiDeallocVisitor, visitor));
+    return &v->visitor;
+}
+
+void qapi_dealloc_visitor_cleanup(QapiDeallocVisitor *v)
+{
+    g_free(v);
 }
 
-Visitor *qapi_dealloc_visitor_new(void)
+QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
 {
     QapiDeallocVisitor *v;
 
     v = g_malloc0(sizeof(*v));
 
-    v->visitor.type = VISITOR_DEALLOC;
     v->visitor.start_struct = qapi_dealloc_start_struct;
     v->visitor.end_struct = qapi_dealloc_end_struct;
     v->visitor.start_alternate = qapi_dealloc_start_alternate;
@@ -126,14 +191,15 @@ Visitor *qapi_dealloc_visitor_new(void)
     v->visitor.start_list = qapi_dealloc_start_list;
     v->visitor.next_list = qapi_dealloc_next_list;
     v->visitor.end_list = qapi_dealloc_end_list;
+    v->visitor.type_enum = qapi_dealloc_type_enum;
     v->visitor.type_int64 = qapi_dealloc_type_int64;
     v->visitor.type_uint64 = qapi_dealloc_type_uint64;
     v->visitor.type_bool = qapi_dealloc_type_bool;
     v->visitor.type_str = qapi_dealloc_type_str;
     v->visitor.type_number = qapi_dealloc_type_number;
     v->visitor.type_any = qapi_dealloc_type_anything;
-    v->visitor.type_null = qapi_dealloc_type_null;
-    v->visitor.free = qapi_dealloc_free;
 
-    return &v->visitor;
+    QTAILQ_INIT(&v->stack);
+
+    return v;
 }
index 55f5876..fa680c9 100644 (file)
 #include "qapi/visitor.h"
 #include "qapi/visitor-impl.h"
 
-void visit_complete(Visitor *v, void *opaque)
-{
-    assert(v->type != VISITOR_OUTPUT || v->complete);
-    if (v->complete) {
-        v->complete(v, opaque);
-    }
-}
-
-void visit_free(Visitor *v)
-{
-    if (v) {
-        v->free(v);
-    }
-}
-
 void visit_start_struct(Visitor *v, const char *name, void **obj,
                         size_t size, Error **errp)
 {
-    Error *err = NULL;
-
-    if (obj) {
-        assert(size);
-        assert(!(v->type & VISITOR_OUTPUT) || *obj);
-    }
-    v->start_struct(v, name, obj, size, &err);
-    if (obj && (v->type & VISITOR_INPUT)) {
-        assert(!err != !*obj);
-    }
-    error_propagate(errp, err);
-}
-
-void visit_check_struct(Visitor *v, Error **errp)
-{
-    if (v->check_struct) {
-        v->check_struct(v, errp);
-    }
+    v->start_struct(v, name, obj, size, errp);
 }
 
-void visit_end_struct(Visitor *v, void **obj)
+void visit_end_struct(Visitor *v, Error **errp)
 {
-    v->end_struct(v, obj);
+    v->end_struct(v, errp);
 }
 
-void visit_start_list(Visitor *v, const char *name, GenericList **list,
-                      size_t size, Error **errp)
+void visit_start_list(Visitor *v, const char *name, Error **errp)
 {
-    Error *err = NULL;
-
-    assert(!list || size >= sizeof(GenericList));
-    v->start_list(v, name, list, size, &err);
-    if (list && (v->type & VISITOR_INPUT)) {
-        assert(!(err && *list));
-    }
-    error_propagate(errp, err);
+    v->start_list(v, name, errp);
 }
 
-GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size)
+GenericList *visit_next_list(Visitor *v, GenericList **list, size_t size)
 {
-    assert(tail && size >= sizeof(GenericList));
-    return v->next_list(v, tail, size);
+    assert(list && size >= sizeof(GenericList));
+    return v->next_list(v, list, size);
 }
 
-void visit_end_list(Visitor *v, void **obj)
+void visit_end_list(Visitor *v)
 {
-    v->end_list(v, obj);
+    v->end_list(v);
 }
 
 void visit_start_alternate(Visitor *v, const char *name,
                            GenericAlternate **obj, size_t size,
                            bool promote_int, Error **errp)
 {
-    Error *err = NULL;
-
     assert(obj && size >= sizeof(GenericAlternate));
-    assert(!(v->type & VISITOR_OUTPUT) || *obj);
     if (v->start_alternate) {
-        v->start_alternate(v, name, obj, size, promote_int, &err);
+        v->start_alternate(v, name, obj, size, promote_int, errp);
     }
-    if (v->type & VISITOR_INPUT) {
-        assert(v->start_alternate && !err != !*obj);
-    }
-    error_propagate(errp, err);
 }
 
-void visit_end_alternate(Visitor *v, void **obj)
+void visit_end_alternate(Visitor *v)
 {
     if (v->end_alternate) {
-        v->end_alternate(v, obj);
+        v->end_alternate(v);
     }
 }
 
@@ -119,14 +72,14 @@ bool visit_optional(Visitor *v, const char *name, bool *present)
     return *present;
 }
 
-bool visit_is_input(Visitor *v)
+void visit_type_enum(Visitor *v, const char *name, int *obj,
+                     const char *const strings[], Error **errp)
 {
-    return v->type == VISITOR_INPUT;
+    v->type_enum(v, name, obj, strings, errp);
 }
 
 void visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp)
 {
-    assert(obj);
     v->type_int64(v, name, obj, errp);
 }
 
@@ -174,7 +127,6 @@ void visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
 void visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
                        Error **errp)
 {
-    assert(obj);
     v->type_uint64(v, name, obj, errp);
 }
 
@@ -222,14 +174,12 @@ void visit_type_int32(Visitor *v, const char *name, int32_t *obj,
 void visit_type_int64(Visitor *v, const char *name, int64_t *obj,
                       Error **errp)
 {
-    assert(obj);
     v->type_int64(v, name, obj, errp);
 }
 
 void visit_type_size(Visitor *v, const char *name, uint64_t *obj,
                      Error **errp)
 {
-    assert(obj);
     if (v->type_size) {
         v->type_size(v, name, obj, errp);
     } else {
@@ -239,58 +189,33 @@ void visit_type_size(Visitor *v, const char *name, uint64_t *obj,
 
 void visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
 {
-    assert(obj);
     v->type_bool(v, name, obj, errp);
 }
 
 void visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
 {
-    Error *err = NULL;
-
-    assert(obj);
-    /* TODO: Fix callers to not pass NULL when they mean "", so that we
-     * can enable:
-    assert(!(v->type & VISITOR_OUTPUT) || *obj);
-     */
-    v->type_str(v, name, obj, &err);
-    if (v->type & VISITOR_INPUT) {
-        assert(!err != !*obj);
-    }
-    error_propagate(errp, err);
+    v->type_str(v, name, obj, errp);
 }
 
 void visit_type_number(Visitor *v, const char *name, double *obj,
                        Error **errp)
 {
-    assert(obj);
     v->type_number(v, name, obj, errp);
 }
 
 void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp)
 {
-    Error *err = NULL;
-
-    assert(obj);
-    assert(v->type != VISITOR_OUTPUT || *obj);
-    v->type_any(v, name, obj, &err);
-    if (v->type == VISITOR_INPUT) {
-        assert(!err != !*obj);
-    }
-    error_propagate(errp, err);
-}
-
-void visit_type_null(Visitor *v, const char *name, Error **errp)
-{
-    v->type_null(v, name, errp);
+    v->type_any(v, name, obj, errp);
 }
 
-static void output_type_enum(Visitor *v, const char *name, int *obj,
-                             const char *const strings[], Error **errp)
+void output_type_enum(Visitor *v, const char *name, int *obj,
+                      const char *const strings[], Error **errp)
 {
     int i = 0;
     int value = *obj;
     char *enum_str;
 
+    assert(strings);
     while (strings[i++] != NULL);
     if (value < 0 || value >= i - 1) {
         error_setg(errp, QERR_INVALID_PARAMETER, name ? name : "null");
@@ -301,13 +226,15 @@ static void output_type_enum(Visitor *v, const char *name, int *obj,
     visit_type_str(v, name, &enum_str, errp);
 }
 
-static void input_type_enum(Visitor *v, const char *name, int *obj,
-                            const char *const strings[], Error **errp)
+void input_type_enum(Visitor *v, const char *name, int *obj,
+                     const char *const strings[], Error **errp)
 {
     Error *local_err = NULL;
     int64_t value = 0;
     char *enum_str;
 
+    assert(strings);
+
     visit_type_str(v, name, &enum_str, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -330,24 +257,3 @@ static void input_type_enum(Visitor *v, const char *name, int *obj,
     g_free(enum_str);
     *obj = value;
 }
-
-void visit_type_enum(Visitor *v, const char *name, int *obj,
-                     const char *const strings[], Error **errp)
-{
-    assert(obj && strings);
-    switch (v->type) {
-    case VISITOR_INPUT:
-        input_type_enum(v, name, obj, strings, errp);
-        break;
-    case VISITOR_OUTPUT:
-        output_type_enum(v, name, obj, strings, errp);
-        break;
-    case VISITOR_CLONE:
-        /* nothing further to do, scalar value was already copied by
-         * g_memdup() during visit_start_*() */
-        break;
-    case VISITOR_DEALLOC:
-        /* nothing to deallocate for a scalar */
-        break;
-    }
-}
index 505eb41..510a1ae 100644 (file)
@@ -16,7 +16,6 @@
 #include "qapi/qmp/types.h"
 #include "qapi/qmp/dispatch.h"
 #include "qapi/qmp/json-parser.h"
-#include "qapi/qmp/qjson.h"
 #include "qapi-types.h"
 #include "qapi/qmp/qerror.h"
 
@@ -95,13 +94,17 @@ static QObject *do_qmp_dispatch(QObject *request, Error **errp)
         QINCREF(args);
     }
 
-    cmd->fn(args, &ret, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-    } else if (cmd->options & QCO_NO_SUCCESS_RESP) {
-        g_assert(!ret);
-    } else if (!ret) {
-        ret = QOBJECT(qdict_new());
+    switch (cmd->type) {
+    case QCT_NORMAL:
+        cmd->fn(args, &ret, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+        } else if (cmd->options & QCO_NO_SUCCESS_RESP) {
+            g_assert(!ret);
+        } else if (!ret) {
+            ret = QOBJECT(qdict_new());
+        }
+        break;
     }
 
     QDECREF(args);
index 64dd392..7cd1b77 100644 (file)
 
 typedef struct StackObject
 {
-    QObject *obj; /* Object being visited */
-    void *qapi; /* sanity check that caller uses same pointer */
-
-    GHashTable *h;           /* If obj is dict: unvisited keys */
-    const QListEntry *entry; /* If obj is list: unvisited tail */
-
-    QSLIST_ENTRY(StackObject) node;
+    QObject *obj;
+    const QListEntry *entry;
+    GHashTable *h;
 } StackObject;
 
 struct QmpInputVisitor
 {
     Visitor visitor;
-
-    /* Root of visit at visitor creation. */
-    QObject *root;
-
-    /* Stack of objects being visited (all entries will be either
-     * QDict or QList). */
-    QSLIST_HEAD(, StackObject) stack;
-
-    /* True to reject parse in visit_end_struct() if unvisited keys remain. */
+    StackObject stack[QIV_STACK_SIZE];
+    int nb_stack;
     bool strict;
 };
 
@@ -58,37 +47,20 @@ static QObject *qmp_input_get_object(QmpInputVisitor *qiv,
                                      const char *name,
                                      bool consume)
 {
-    StackObject *tos;
-    QObject *qobj;
-    QObject *ret;
-
-    if (QSLIST_EMPTY(&qiv->stack)) {
-        /* Starting at root, name is ignored. */
-        return qiv->root;
-    }
+    QObject *qobj = qiv->stack[qiv->nb_stack - 1].obj;
 
-    /* We are in a container; find the next element. */
-    tos = QSLIST_FIRST(&qiv->stack);
-    qobj = tos->obj;
-    assert(qobj);
-
-    if (qobject_type(qobj) == QTYPE_QDICT) {
-        assert(name);
-        ret = qdict_get(qobject_to_qdict(qobj), name);
-        if (tos->h && consume && ret) {
-            bool removed = g_hash_table_remove(tos->h, name);
-            assert(removed);
-        }
-    } else {
-        assert(qobject_type(qobj) == QTYPE_QLIST);
-        assert(!name);
-        ret = qlist_entry_obj(tos->entry);
-        if (consume) {
-            tos->entry = qlist_next(tos->entry);
+    if (qobj) {
+        if (name && qobject_type(qobj) == QTYPE_QDICT) {
+            if (qiv->stack[qiv->nb_stack - 1].h && consume) {
+                g_hash_table_remove(qiv->stack[qiv->nb_stack - 1].h, name);
+            }
+            return qdict_get(qobject_to_qdict(qobj), name);
+        } else if (qiv->stack[qiv->nb_stack - 1].entry) {
+            return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry);
         }
     }
 
-    return ret;
+    return qobj;
 }
 
 static void qdict_add_key(const char *key, QObject *obj, void *opaque)
@@ -97,37 +69,35 @@ static void qdict_add_key(const char *key, QObject *obj, void *opaque)
     g_hash_table_insert(h, (gpointer) key, NULL);
 }
 
-static const QListEntry *qmp_input_push(QmpInputVisitor *qiv, QObject *obj,
-                                        void *qapi, Error **errp)
+static void qmp_input_push(QmpInputVisitor *qiv, QObject *obj, Error **errp)
 {
     GHashTable *h;
-    StackObject *tos = g_new0(StackObject, 1);
 
-    assert(obj);
-    tos->obj = obj;
-    tos->qapi = qapi;
+    if (qiv->nb_stack >= QIV_STACK_SIZE) {
+        error_setg(errp, "An internal buffer overran");
+        return;
+    }
+
+    qiv->stack[qiv->nb_stack].obj = obj;
+    qiv->stack[qiv->nb_stack].entry = NULL;
+    qiv->stack[qiv->nb_stack].h = NULL;
 
     if (qiv->strict && qobject_type(obj) == QTYPE_QDICT) {
         h = g_hash_table_new(g_str_hash, g_str_equal);
         qdict_iter(qobject_to_qdict(obj), qdict_add_key, h);
-        tos->h = h;
-    } else if (qobject_type(obj) == QTYPE_QLIST) {
-        tos->entry = qlist_first(qobject_to_qlist(obj));
+        qiv->stack[qiv->nb_stack].h = h;
     }
 
-    QSLIST_INSERT_HEAD(&qiv->stack, tos, node);
-    return tos->entry;
+    qiv->nb_stack++;
 }
 
 
-static void qmp_input_check_struct(Visitor *v, Error **errp)
+static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp)
 {
-    QmpInputVisitor *qiv = to_qiv(v);
-    StackObject *tos = QSLIST_FIRST(&qiv->stack);
+    assert(qiv->nb_stack > 0);
 
-    assert(tos && !tos->entry);
     if (qiv->strict) {
-        GHashTable *const top_ht = tos->h;
+        GHashTable * const top_ht = qiv->stack[qiv->nb_stack - 1].h;
         if (top_ht) {
             GHashTableIter iter;
             const char *key;
@@ -136,27 +106,11 @@ static void qmp_input_check_struct(Visitor *v, Error **errp)
             if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) {
                 error_setg(errp, QERR_QMP_EXTRA_MEMBER, key);
             }
+            g_hash_table_unref(top_ht);
         }
     }
-}
-
-static void qmp_input_stack_object_free(StackObject *tos)
-{
-    if (tos->h) {
-        g_hash_table_unref(tos->h);
-    }
 
-    g_free(tos);
-}
-
-static void qmp_input_pop(Visitor *v, void **obj)
-{
-    QmpInputVisitor *qiv = to_qiv(v);
-    StackObject *tos = QSLIST_FIRST(&qiv->stack);
-
-    assert(tos && tos->qapi == obj);
-    QSLIST_REMOVE_HEAD(&qiv->stack, node);
-    qmp_input_stack_object_free(tos);
+    qiv->nb_stack--;
 }
 
 static void qmp_input_start_struct(Visitor *v, const char *name, void **obj,
@@ -166,16 +120,13 @@ static void qmp_input_start_struct(Visitor *v, const char *name, void **obj,
     QObject *qobj = qmp_input_get_object(qiv, name, true);
     Error *err = NULL;
 
-    if (obj) {
-        *obj = NULL;
-    }
     if (!qobj || qobject_type(qobj) != QTYPE_QDICT) {
         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
                    "QDict");
         return;
     }
 
-    qmp_input_push(qiv, qobj, obj, &err);
+    qmp_input_push(qiv, qobj, &err);
     if (err) {
         error_propagate(errp, err);
         return;
@@ -186,46 +137,63 @@ static void qmp_input_start_struct(Visitor *v, const char *name, void **obj,
     }
 }
 
+static void qmp_input_end_struct(Visitor *v, Error **errp)
+{
+    QmpInputVisitor *qiv = to_qiv(v);
+
+    qmp_input_pop(qiv, errp);
+}
 
-static void qmp_input_start_list(Visitor *v, const char *name,
-                                 GenericList **list, size_t size, Error **errp)
+static void qmp_input_start_list(Visitor *v, const char *name, Error **errp)
 {
     QmpInputVisitor *qiv = to_qiv(v);
     QObject *qobj = qmp_input_get_object(qiv, name, true);
-    const QListEntry *entry;
 
     if (!qobj || qobject_type(qobj) != QTYPE_QLIST) {
-        if (list) {
-            *list = NULL;
-        }
         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
                    "list");
         return;
     }
 
-    entry = qmp_input_push(qiv, qobj, list, errp);
-    if (list) {
-        if (entry) {
-            *list = g_malloc0(size);
-        } else {
-            *list = NULL;
-        }
-    }
+    qmp_input_push(qiv, qobj, errp);
 }
 
-static GenericList *qmp_input_next_list(Visitor *v, GenericList *tail,
+static GenericList *qmp_input_next_list(Visitor *v, GenericList **list,
                                         size_t size)
 {
     QmpInputVisitor *qiv = to_qiv(v);
-    StackObject *so = QSLIST_FIRST(&qiv->stack);
+    GenericList *entry;
+    StackObject *so = &qiv->stack[qiv->nb_stack - 1];
+    bool first;
 
-    if (!so->entry) {
+    if (so->entry == NULL) {
+        so->entry = qlist_first(qobject_to_qlist(so->obj));
+        first = true;
+    } else {
+        so->entry = qlist_next(so->entry);
+        first = false;
+    }
+
+    if (so->entry == NULL) {
         return NULL;
     }
-    tail->next = g_malloc0(size);
-    return tail->next;
+
+    entry = g_malloc0(size);
+    if (first) {
+        *list = entry;
+    } else {
+        (*list)->next = entry;
+    }
+
+    return entry;
 }
 
+static void qmp_input_end_list(Visitor *v)
+{
+    QmpInputVisitor *qiv = to_qiv(v);
+
+    qmp_input_pop(qiv, &error_abort);
+}
 
 static void qmp_input_start_alternate(Visitor *v, const char *name,
                                       GenericAlternate **obj, size_t size,
@@ -299,7 +267,6 @@ static void qmp_input_type_str(Visitor *v, const char *name, char **obj,
     QString *qstr = qobject_to_qstring(qmp_input_get_object(qiv, name, true));
 
     if (!qstr) {
-        *obj = NULL;
         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
                    "string");
         return;
@@ -342,21 +309,10 @@ static void qmp_input_type_any(Visitor *v, const char *name, QObject **obj,
     *obj = qobj;
 }
 
-static void qmp_input_type_null(Visitor *v, const char *name, Error **errp)
-{
-    QmpInputVisitor *qiv = to_qiv(v);
-    QObject *qobj = qmp_input_get_object(qiv, name, true);
-
-    if (qobject_type(qobj) != QTYPE_QNULL) {
-        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
-                   "null");
-    }
-}
-
 static void qmp_input_optional(Visitor *v, const char *name, bool *present)
 {
     QmpInputVisitor *qiv = to_qiv(v);
-    QObject *qobj = qmp_input_get_object(qiv, name, false);
+    QObject *qobj = qmp_input_get_object(qiv, name, true);
 
     if (!qobj) {
         *present = false;
@@ -366,47 +322,50 @@ static void qmp_input_optional(Visitor *v, const char *name, bool *present)
     *present = true;
 }
 
-static void qmp_input_free(Visitor *v)
+Visitor *qmp_input_get_visitor(QmpInputVisitor *v)
 {
-    QmpInputVisitor *qiv = to_qiv(v);
-    while (!QSLIST_EMPTY(&qiv->stack)) {
-        StackObject *tos = QSLIST_FIRST(&qiv->stack);
-
-        QSLIST_REMOVE_HEAD(&qiv->stack, node);
-        qmp_input_stack_object_free(tos);
-    }
+    return &v->visitor;
+}
 
-    qobject_decref(qiv->root);
-    g_free(qiv);
+void qmp_input_visitor_cleanup(QmpInputVisitor *v)
+{
+    qobject_decref(v->stack[0].obj);
+    g_free(v);
 }
 
-Visitor *qmp_input_visitor_new(QObject *obj, bool strict)
+QmpInputVisitor *qmp_input_visitor_new(QObject *obj)
 {
     QmpInputVisitor *v;
 
     v = g_malloc0(sizeof(*v));
 
-    v->visitor.type = VISITOR_INPUT;
     v->visitor.start_struct = qmp_input_start_struct;
-    v->visitor.check_struct = qmp_input_check_struct;
-    v->visitor.end_struct = qmp_input_pop;
+    v->visitor.end_struct = qmp_input_end_struct;
     v->visitor.start_list = qmp_input_start_list;
     v->visitor.next_list = qmp_input_next_list;
-    v->visitor.end_list = qmp_input_pop;
+    v->visitor.end_list = qmp_input_end_list;
     v->visitor.start_alternate = qmp_input_start_alternate;
+    v->visitor.type_enum = input_type_enum;
     v->visitor.type_int64 = qmp_input_type_int64;
     v->visitor.type_uint64 = qmp_input_type_uint64;
     v->visitor.type_bool = qmp_input_type_bool;
     v->visitor.type_str = qmp_input_type_str;
     v->visitor.type_number = qmp_input_type_number;
     v->visitor.type_any = qmp_input_type_any;
-    v->visitor.type_null = qmp_input_type_null;
     v->visitor.optional = qmp_input_optional;
-    v->visitor.free = qmp_input_free;
-    v->strict = strict;
 
-    v->root = obj;
+    qmp_input_push(v, obj, NULL);
     qobject_incref(obj);
 
-    return &v->visitor;
+    return v;
+}
+
+QmpInputVisitor *qmp_input_visitor_new_strict(QObject *obj)
+{
+    QmpInputVisitor *v;
+
+    v = qmp_input_visitor_new(obj);
+    v->strict = true;
+
+    return v;
 }
index 9e3b67c..d44c676 100644 (file)
 typedef struct QStackEntry
 {
     QObject *value;
-    void *qapi; /* sanity check that caller uses same pointer */
-    QSLIST_ENTRY(QStackEntry) node;
+    bool is_list_head;
+    QTAILQ_ENTRY(QStackEntry) node;
 } QStackEntry;
 
+typedef QTAILQ_HEAD(QStack, QStackEntry) QStack;
+
 struct QmpOutputVisitor
 {
     Visitor visitor;
-    QSLIST_HEAD(, QStackEntry) stack; /* Stack of unfinished containers */
+    QStack stack; /* Stack of containers that haven't yet been finished */
     QObject *root; /* Root of the output visit */
-    QObject **result; /* User's storage location for result */
 };
 
 #define qmp_output_add(qov, name, value) \
     qmp_output_add_obj(qov, name, QOBJECT(value))
-#define qmp_output_push(qov, value, qapi) \
-    qmp_output_push_obj(qov, QOBJECT(value), qapi)
+#define qmp_output_push(qov, value) qmp_output_push_obj(qov, QOBJECT(value))
 
 static QmpOutputVisitor *to_qov(Visitor *v)
 {
@@ -45,27 +45,27 @@ static QmpOutputVisitor *to_qov(Visitor *v)
 }
 
 /* Push @value onto the stack of current QObjects being built */
-static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value,
-                                void *qapi)
+static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value)
 {
     QStackEntry *e = g_malloc0(sizeof(*e));
 
     assert(qov->root);
     assert(value);
     e->value = value;
-    e->qapi = qapi;
-    QSLIST_INSERT_HEAD(&qov->stack, e, node);
+    if (qobject_type(e->value) == QTYPE_QLIST) {
+        e->is_list_head = true;
+    }
+    QTAILQ_INSERT_HEAD(&qov->stack, e, node);
 }
 
 /* Pop a value off the stack of QObjects being built, and return it. */
-static QObject *qmp_output_pop(QmpOutputVisitor *qov, void *qapi)
+static QObject *qmp_output_pop(QmpOutputVisitor *qov)
 {
-    QStackEntry *e = QSLIST_FIRST(&qov->stack);
+    QStackEntry *e = QTAILQ_FIRST(&qov->stack);
     QObject *value;
 
     assert(e);
-    assert(e->qapi == qapi);
-    QSLIST_REMOVE_HEAD(&qov->stack, node);
+    QTAILQ_REMOVE(&qov->stack, e, node);
     value = e->value;
     assert(value);
     g_free(e);
@@ -78,12 +78,13 @@ static QObject *qmp_output_pop(QmpOutputVisitor *qov, void *qapi)
 static void qmp_output_add_obj(QmpOutputVisitor *qov, const char *name,
                                QObject *value)
 {
-    QStackEntry *e = QSLIST_FIRST(&qov->stack);
+    QStackEntry *e = QTAILQ_FIRST(&qov->stack);
     QObject *cur = e ? e->value : NULL;
 
     if (!cur) {
-        /* Don't allow reuse of visitor on more than one root */
-        assert(!qov->root);
+        /* FIXME we should require the user to reset the visitor, rather
+         * than throwing away the previous root */
+        qobject_decref(qov->root);
         qov->root = value;
     } else {
         switch (qobject_type(cur)) {
@@ -92,7 +93,6 @@ static void qmp_output_add_obj(QmpOutputVisitor *qov, const char *name,
             qdict_put_obj(qobject_to_qdict(cur), name, value);
             break;
         case QTYPE_QLIST:
-            assert(!name);
             qlist_append_obj(qobject_to_qlist(cur), value);
             break;
         default:
@@ -108,38 +108,44 @@ static void qmp_output_start_struct(Visitor *v, const char *name, void **obj,
     QDict *dict = qdict_new();
 
     qmp_output_add(qov, name, dict);
-    qmp_output_push(qov, dict, obj);
+    qmp_output_push(qov, dict);
 }
 
-static void qmp_output_end_struct(Visitor *v, void **obj)
+static void qmp_output_end_struct(Visitor *v, Error **errp)
 {
     QmpOutputVisitor *qov = to_qov(v);
-    QObject *value = qmp_output_pop(qov, obj);
-    assert(qobject_type(value) == QTYPE_QDICT);
+    qmp_output_pop(qov);
 }
 
-static void qmp_output_start_list(Visitor *v, const char *name,
-                                  GenericList **listp, size_t size,
-                                  Error **errp)
+static void qmp_output_start_list(Visitor *v, const char *name, Error **errp)
 {
     QmpOutputVisitor *qov = to_qov(v);
     QList *list = qlist_new();
 
     qmp_output_add(qov, name, list);
-    qmp_output_push(qov, list, listp);
+    qmp_output_push(qov, list);
 }
 
-static GenericList *qmp_output_next_list(Visitor *v, GenericList *tail,
+static GenericList *qmp_output_next_list(Visitor *v, GenericList **listp,
                                          size_t size)
 {
-    return tail->next;
+    GenericList *list = *listp;
+    QmpOutputVisitor *qov = to_qov(v);
+    QStackEntry *e = QTAILQ_FIRST(&qov->stack);
+
+    assert(e);
+    if (e->is_list_head) {
+        e->is_list_head = false;
+        return list;
+    }
+
+    return list ? list->next : NULL;
 }
 
-static void qmp_output_end_list(Visitor *v, void **obj)
+static void qmp_output_end_list(Visitor *v)
 {
     QmpOutputVisitor *qov = to_qov(v);
-    QObject *value = qmp_output_pop(qov, obj);
-    assert(qobject_type(value) == QTYPE_QLIST);
+    qmp_output_pop(qov);
 }
 
 static void qmp_output_type_int64(Visitor *v, const char *name, int64_t *obj,
@@ -190,67 +196,58 @@ static void qmp_output_type_any(Visitor *v, const char *name, QObject **obj,
     qmp_output_add_obj(qov, name, *obj);
 }
 
-static void qmp_output_type_null(Visitor *v, const char *name, Error **errp)
+/* Finish building, and return the root object. Will not be NULL. */
+QObject *qmp_output_get_qobject(QmpOutputVisitor *qov)
 {
-    QmpOutputVisitor *qov = to_qov(v);
-    qmp_output_add_obj(qov, name, qnull());
+    /* FIXME: we should require that a visit occurred, and that it is
+     * complete (no starts without a matching end) */
+    QObject *obj = qov->root;
+    if (obj) {
+        qobject_incref(obj);
+    } else {
+        obj = qnull();
+    }
+    return obj;
 }
 
-/* Finish building, and return the root object.
- * The root object is never null. The caller becomes the object's
- * owner, and should use qobject_decref() when done with it.  */
-static void qmp_output_complete(Visitor *v, void *opaque)
+Visitor *qmp_output_get_visitor(QmpOutputVisitor *v)
 {
-    QmpOutputVisitor *qov = to_qov(v);
-
-    /* A visit must have occurred, with each start paired with end.  */
-    assert(qov->root && QSLIST_EMPTY(&qov->stack));
-    assert(opaque == qov->result);
-
-    qobject_incref(qov->root);
-    *qov->result = qov->root;
-    qov->result = NULL;
+    return &v->visitor;
 }
 
-static void qmp_output_free(Visitor *v)
+void qmp_output_visitor_cleanup(QmpOutputVisitor *v)
 {
-    QmpOutputVisitor *qov = to_qov(v);
-    QStackEntry *e;
+    QStackEntry *e, *tmp;
 
-    while (!QSLIST_EMPTY(&qov->stack)) {
-        e = QSLIST_FIRST(&qov->stack);
-        QSLIST_REMOVE_HEAD(&qov->stack, node);
+    QTAILQ_FOREACH_SAFE(e, &v->stack, node, tmp) {
+        QTAILQ_REMOVE(&v->stack, e, node);
         g_free(e);
     }
 
-    qobject_decref(qov->root);
-    g_free(qov);
+    qobject_decref(v->root);
+    g_free(v);
 }
 
-Visitor *qmp_output_visitor_new(QObject **result)
+QmpOutputVisitor *qmp_output_visitor_new(void)
 {
     QmpOutputVisitor *v;
 
     v = g_malloc0(sizeof(*v));
 
-    v->visitor.type = VISITOR_OUTPUT;
     v->visitor.start_struct = qmp_output_start_struct;
     v->visitor.end_struct = qmp_output_end_struct;
     v->visitor.start_list = qmp_output_start_list;
     v->visitor.next_list = qmp_output_next_list;
     v->visitor.end_list = qmp_output_end_list;
+    v->visitor.type_enum = output_type_enum;
     v->visitor.type_int64 = qmp_output_type_int64;
     v->visitor.type_uint64 = qmp_output_type_uint64;
     v->visitor.type_bool = qmp_output_type_bool;
     v->visitor.type_str = qmp_output_type_str;
     v->visitor.type_number = qmp_output_type_number;
     v->visitor.type_any = qmp_output_type_any;
-    v->visitor.type_null = qmp_output_type_null;
-    v->visitor.complete = qmp_output_complete;
-    v->visitor.free = qmp_output_free;
 
-    *result = NULL;
-    v->result = result;
+    QTAILQ_INIT(&v->stack);
 
-    return &v->visitor;
+    return v;
 }
index 68b24c9..4ebfbcc 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qapi/qmp/dispatch.h"
 
 static QTAILQ_HEAD(QmpCommandList, QmpCommand) qmp_commands =
@@ -24,6 +25,7 @@ void qmp_register_command(const char *name, QmpCommandFunc *fn,
     QmpCommand *cmd = g_malloc0(sizeof(*cmd));
 
     cmd->name = name;
+    cmd->type = QCT_NORMAL;
     cmd->fn = fn;
     cmd->enabled = true;
     cmd->options = options;
index 8dfa561..5ea2d77 100644 (file)
@@ -25,12 +25,13 @@ struct StringInputVisitor
 {
     Visitor visitor;
 
+    bool head;
+
     GList *ranges;
     GList *cur_range;
     int64_t cur;
 
     const char *string;
-    void *list; /* Only needed for sanity checking the caller */
 };
 
 static StringInputVisitor *to_siv(Visitor *v)
@@ -43,7 +44,7 @@ static void free_range(void *range, void *dummy)
     g_free(range);
 }
 
-static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
+static void parse_str(StringInputVisitor *siv, Error **errp)
 {
     char *str = (char *) siv->string;
     long long start, end;
@@ -51,7 +52,7 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
     char *endptr;
 
     if (siv->ranges) {
-        return 0;
+        return;
     }
 
     do {
@@ -60,8 +61,10 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
         if (errno == 0 && endptr > str) {
             if (*endptr == '\0') {
                 cur = g_malloc0(sizeof(*cur));
-                range_set_bounds(cur, start, start);
-                siv->ranges = range_list_insert(siv->ranges, cur);
+                cur->begin = start;
+                cur->end = start + 1;
+                siv->ranges = g_list_insert_sorted_merged(siv->ranges, cur,
+                                                          range_compare);
                 cur = NULL;
                 str = NULL;
             } else if (*endptr == '-') {
@@ -73,15 +76,23 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
                      end < start + 65536)) {
                     if (*endptr == '\0') {
                         cur = g_malloc0(sizeof(*cur));
-                        range_set_bounds(cur, start, end);
-                        siv->ranges = range_list_insert(siv->ranges, cur);
+                        cur->begin = start;
+                        cur->end = end + 1;
+                        siv->ranges =
+                            g_list_insert_sorted_merged(siv->ranges,
+                                                        cur,
+                                                        range_compare);
                         cur = NULL;
                         str = NULL;
                     } else if (*endptr == ',') {
                         str = endptr + 1;
                         cur = g_malloc0(sizeof(*cur));
-                        range_set_bounds(cur, start, end);
-                        siv->ranges = range_list_insert(siv->ranges, cur);
+                        cur->begin = start;
+                        cur->end = end + 1;
+                        siv->ranges =
+                            g_list_insert_sorted_merged(siv->ranges,
+                                                        cur,
+                                                        range_compare);
                         cur = NULL;
                     } else {
                         goto error;
@@ -92,8 +103,11 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
             } else if (*endptr == ',') {
                 str = endptr + 1;
                 cur = g_malloc0(sizeof(*cur));
-                range_set_bounds(cur, start, start);
-                siv->ranges = range_list_insert(siv->ranges, cur);
+                cur->begin = start;
+                cur->end = start + 1;
+                siv->ranges = g_list_insert_sorted_merged(siv->ranges,
+                                                          cur,
+                                                          range_compare);
                 cur = NULL;
             } else {
                 goto error;
@@ -103,46 +117,33 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
         }
     } while (str);
 
-    return 0;
+    return;
 error:
     g_list_foreach(siv->ranges, free_range, NULL);
     g_list_free(siv->ranges);
     siv->ranges = NULL;
-    error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
-               "an int64 value or range");
-    return -1;
 }
 
 static void
-start_list(Visitor *v, const char *name, GenericList **list, size_t size,
-           Error **errp)
+start_list(Visitor *v, const char *name, Error **errp)
 {
     StringInputVisitor *siv = to_siv(v);
 
-    /* We don't support visits without a list */
-    assert(list);
-    siv->list = list;
-
-    if (parse_str(siv, name, errp) < 0) {
-        *list = NULL;
-        return;
-    }
+    parse_str(siv, errp);
 
     siv->cur_range = g_list_first(siv->ranges);
     if (siv->cur_range) {
         Range *r = siv->cur_range->data;
         if (r) {
-            siv->cur = range_lob(r);
+            siv->cur = r->begin;
         }
-        *list = g_malloc0(size);
-    } else {
-        *list = NULL;
     }
 }
 
-static GenericList *next_list(Visitor *v, GenericList *tail, size_t size)
+static GenericList *next_list(Visitor *v, GenericList **list, size_t size)
 {
     StringInputVisitor *siv = to_siv(v);
+    GenericList **link;
     Range *r;
 
     if (!siv->ranges || !siv->cur_range) {
@@ -154,7 +155,7 @@ static GenericList *next_list(Visitor *v, GenericList *tail, size_t size)
         return NULL;
     }
 
-    if (!range_contains(r, siv->cur)) {
+    if (siv->cur < r->begin || siv->cur >= r->end) {
         siv->cur_range = g_list_next(siv->cur_range);
         if (!siv->cur_range) {
             return NULL;
@@ -163,18 +164,24 @@ static GenericList *next_list(Visitor *v, GenericList *tail, size_t size)
         if (!r) {
             return NULL;
         }
-        siv->cur = range_lob(r);
+        siv->cur = r->begin;
+    }
+
+    if (siv->head) {
+        link = list;
+        siv->head = false;
+    } else {
+        link = &(*list)->next;
     }
 
-    tail->next = g_malloc0(size);
-    return tail->next;
+    *link = g_malloc0(size);
+    return *link;
 }
 
-static void end_list(Visitor *v, void **obj)
+static void end_list(Visitor *v)
 {
     StringInputVisitor *siv = to_siv(v);
-
-    assert(siv->list == obj);
+    siv->head = true;
 }
 
 static void parse_type_int64(Visitor *v, const char *name, int64_t *obj,
@@ -188,9 +195,7 @@ static void parse_type_int64(Visitor *v, const char *name, int64_t *obj,
         return;
     }
 
-    if (parse_str(siv, name, errp) < 0) {
-        return;
-    }
+    parse_str(siv, errp);
 
     if (!siv->ranges) {
         goto error;
@@ -209,7 +214,7 @@ static void parse_type_int64(Visitor *v, const char *name, int64_t *obj,
             goto error;
         }
 
-        siv->cur = range_lob(r);
+        siv->cur = r->begin;
     }
 
     *obj = siv->cur;
@@ -288,7 +293,6 @@ static void parse_type_str(Visitor *v, const char *name, char **obj,
     if (siv->string) {
         *obj = g_strdup(siv->string);
     } else {
-        *obj = NULL;
         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
                    "string");
     }
@@ -326,22 +330,25 @@ static void parse_optional(Visitor *v, const char *name, bool *present)
     *present = true;
 }
 
-static void string_input_free(Visitor *v)
+Visitor *string_input_get_visitor(StringInputVisitor *v)
 {
-    StringInputVisitor *siv = to_siv(v);
+    return &v->visitor;
+}
 
-    g_list_foreach(siv->ranges, free_range, NULL);
-    g_list_free(siv->ranges);
-    g_free(siv);
+void string_input_visitor_cleanup(StringInputVisitor *v)
+{
+    g_list_foreach(v->ranges, free_range, NULL);
+    g_list_free(v->ranges);
+    g_free(v);
 }
 
-Visitor *string_input_visitor_new(const char *str)
+StringInputVisitor *string_input_visitor_new(const char *str)
 {
     StringInputVisitor *v;
 
     v = g_malloc0(sizeof(*v));
 
-    v->visitor.type = VISITOR_INPUT;
+    v->visitor.type_enum = input_type_enum;
     v->visitor.type_int64 = parse_type_int64;
     v->visitor.type_uint64 = parse_type_uint64;
     v->visitor.type_size = parse_type_size;
@@ -352,8 +359,8 @@ Visitor *string_input_visitor_new(const char *str)
     v->visitor.next_list = next_list;
     v->visitor.end_list = end_list;
     v->visitor.optional = parse_optional;
-    v->visitor.free = string_input_free;
 
     v->string = str;
-    return &v->visitor;
+    v->head = true;
+    return v;
 }
index 94ac821..c2e5c5b 100644 (file)
@@ -20,7 +20,7 @@
 
 enum ListMode {
     LM_NONE,             /* not traversing a list of repeated options */
-    LM_STARTED,          /* next_list() ready to be called */
+    LM_STARTED,          /* start_list() succeeded */
 
     LM_IN_PROGRESS,      /* next_list() has been called.
                           *
@@ -48,7 +48,7 @@ enum ListMode {
 
     LM_UNSIGNED_INTERVAL,/* Same as above, only for an unsigned interval. */
 
-    LM_END,              /* next_list() called, about to see last element. */
+    LM_END
 };
 
 typedef enum ListMode ListMode;
@@ -58,14 +58,13 @@ struct StringOutputVisitor
     Visitor visitor;
     bool human;
     GString *string;
-    char **result;
+    bool head;
     ListMode list_mode;
     union {
         int64_t s;
         uint64_t u;
     } range_start, range_end;
     GList *ranges;
-    void *list; /* Only needed for sanity checking the caller */
 };
 
 static StringOutputVisitor *to_sov(Visitor *v)
@@ -85,37 +84,37 @@ static void string_output_set(StringOutputVisitor *sov, char *string)
 static void string_output_append(StringOutputVisitor *sov, int64_t a)
 {
     Range *r = g_malloc0(sizeof(*r));
-
-    range_set_bounds(r, a, a);
-    sov->ranges = range_list_insert(sov->ranges, r);
+    r->begin = a;
+    r->end = a + 1;
+    sov->ranges = g_list_insert_sorted_merged(sov->ranges, r, range_compare);
 }
 
 static void string_output_append_range(StringOutputVisitor *sov,
                                        int64_t s, int64_t e)
 {
     Range *r = g_malloc0(sizeof(*r));
-
-    range_set_bounds(r, s, e);
-    sov->ranges = range_list_insert(sov->ranges, r);
+    r->begin = s;
+    r->end = e + 1;
+    sov->ranges = g_list_insert_sorted_merged(sov->ranges, r, range_compare);
 }
 
 static void format_string(StringOutputVisitor *sov, Range *r, bool next,
                           bool human)
 {
-    if (range_lob(r) != range_upb(r)) {
+    if (r->end - r->begin > 1) {
         if (human) {
             g_string_append_printf(sov->string, "0x%" PRIx64 "-0x%" PRIx64,
-                                   range_lob(r), range_upb(r));
+                                   r->begin, r->end - 1);
 
         } else {
             g_string_append_printf(sov->string, "%" PRId64 "-%" PRId64,
-                                   range_lob(r), range_upb(r));
+                                   r->begin, r->end - 1);
         }
     } else {
         if (human) {
-            g_string_append_printf(sov->string, "0x%" PRIx64, range_lob(r));
+            g_string_append_printf(sov->string, "0x%" PRIx64, r->begin);
         } else {
-            g_string_append_printf(sov->string, "%" PRId64, range_lob(r));
+            g_string_append_printf(sov->string, "%" PRId64, r->begin);
         }
     }
     if (next) {
@@ -267,52 +266,65 @@ static void print_type_number(Visitor *v, const char *name, double *obj,
 }
 
 static void
-start_list(Visitor *v, const char *name, GenericList **list, size_t size,
-           Error **errp)
+start_list(Visitor *v, const char *name, Error **errp)
 {
     StringOutputVisitor *sov = to_sov(v);
 
     /* we can't traverse a list in a list */
     assert(sov->list_mode == LM_NONE);
-    /* We don't support visits without a list */
-    assert(list);
-    sov->list = list;
-    /* List handling is only needed if there are at least two elements */
-    if (*list && (*list)->next) {
-        sov->list_mode = LM_STARTED;
-    }
+    sov->list_mode = LM_STARTED;
+    sov->head = true;
 }
 
-static GenericList *next_list(Visitor *v, GenericList *tail, size_t size)
+static GenericList *next_list(Visitor *v, GenericList **list, size_t size)
 {
     StringOutputVisitor *sov = to_sov(v);
-    GenericList *ret = tail->next;
+    GenericList *ret = NULL;
+    if (*list) {
+        if (sov->head) {
+            ret = *list;
+        } else {
+            ret = (*list)->next;
+        }
 
-    if (ret && !ret->next) {
-        sov->list_mode = LM_END;
+        if (sov->head) {
+            if (ret && ret->next == NULL) {
+                sov->list_mode = LM_NONE;
+            }
+            sov->head = false;
+        } else {
+            if (ret && ret->next == NULL) {
+                sov->list_mode = LM_END;
+            }
+        }
     }
+
     return ret;
 }
 
-static void end_list(Visitor *v, void **obj)
+static void end_list(Visitor *v)
 {
     StringOutputVisitor *sov = to_sov(v);
 
-    assert(sov->list == obj);
     assert(sov->list_mode == LM_STARTED ||
            sov->list_mode == LM_END ||
            sov->list_mode == LM_NONE ||
            sov->list_mode == LM_IN_PROGRESS);
     sov->list_mode = LM_NONE;
+    sov->head = true;
+
 }
 
-static void string_output_complete(Visitor *v, void *opaque)
+char *string_output_get_string(StringOutputVisitor *sov)
 {
-    StringOutputVisitor *sov = to_sov(v);
-
-    assert(opaque == sov->result);
-    *sov->result = g_string_free(sov->string, false);
+    char *string = g_string_free(sov->string, false);
     sov->string = NULL;
+    return string;
+}
+
+Visitor *string_output_get_visitor(StringOutputVisitor *sov)
+{
+    return &sov->visitor;
 }
 
 static void free_range(void *range, void *dummy)
@@ -320,10 +332,8 @@ static void free_range(void *range, void *dummy)
     g_free(range);
 }
 
-static void string_output_free(Visitor *v)
+void string_output_visitor_cleanup(StringOutputVisitor *sov)
 {
-    StringOutputVisitor *sov = to_sov(v);
-
     if (sov->string) {
         g_string_free(sov->string, true);
     }
@@ -333,7 +343,7 @@ static void string_output_free(Visitor *v)
     g_free(sov);
 }
 
-Visitor *string_output_visitor_new(bool human, char **result)
+StringOutputVisitor *string_output_visitor_new(bool human)
 {
     StringOutputVisitor *v;
 
@@ -341,10 +351,7 @@ Visitor *string_output_visitor_new(bool human, char **result)
 
     v->string = g_string_new(NULL);
     v->human = human;
-    v->result = result;
-    *result = NULL;
-
-    v->visitor.type = VISITOR_OUTPUT;
+    v->visitor.type_enum = output_type_enum;
     v->visitor.type_int64 = print_type_int64;
     v->visitor.type_uint64 = print_type_uint64;
     v->visitor.type_size = print_type_size;
@@ -354,8 +361,6 @@ Visitor *string_output_visitor_new(bool human, char **result)
     v->visitor.start_list = start_list;
     v->visitor.next_list = next_list;
     v->visitor.end_list = end_list;
-    v->visitor.complete = string_output_complete;
-    v->visitor.free = string_output_free;
 
-    return &v->visitor;
+    return v;
 }
index e872146..01b0a52 100644 (file)
@@ -1,6 +1,6 @@
 # -*- mode: python -*-
 #
-# Copyright (C) 2011-2016 Lluís Vilanova <vilanova@ac.upc.edu>
+# Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu>
 #
 # This work is licensed under the terms of the GNU GPL, version 2 or later.
 # See the COPYING file in the top-level directory.
 #
 # @name: Event name.
 # @state: Tracing state.
-# @vcpu: Whether this is a per-vCPU event (since 2.7).
-#
-# An event is per-vCPU if it has the "vcpu" property in the "trace-events"
-# files.
 #
 # Since 2.2
 ##
 { 'struct': 'TraceEventInfo',
-  'data': {'name': 'str', 'state': 'TraceEventState', 'vcpu': 'bool'} }
+  'data': {'name': 'str', 'state': 'TraceEventState'} }
 
 ##
 # @trace-event-get-state:
 # Query the state of events.
 #
 # @name: Event name pattern (case-sensitive glob).
-# @vcpu: #optional The vCPU to query (any by default; since 2.7).
 #
 # Returns: a list of @TraceEventInfo for the matching events
 #
-# An event is returned if:
-# - its name matches the @name pattern, and
-# - if @vcpu is given, the event has the "vcpu" property.
-#
-# Therefore, if @vcpu is given, the operation will only match per-vCPU events,
-# returning their state on the specified vCPU. Special case: if @name is an
-# exact match, @vcpu is given and the event does not have the "vcpu" property,
-# an error is returned.
-#
 # Since 2.2
 ##
 { 'command': 'trace-event-get-state',
-  'data': {'name': 'str', '*vcpu': 'int'},
+  'data': {'name': 'str'},
   'returns': ['TraceEventInfo'] }
 
 ##
 # @name: Event name pattern (case-sensitive glob).
 # @enable: Whether to enable tracing.
 # @ignore-unavailable: #optional Do not match unavailable events with @name.
-# @vcpu: #optional The vCPU to act upon (all by default; since 2.7).
-#
-# An event's state is modified if:
-# - its name matches the @name pattern, and
-# - if @vcpu is given, the event has the "vcpu" property.
-#
-# Therefore, if @vcpu is given, the operation will only match per-vCPU events,
-# setting their state on the specified vCPU. Special case: if @name is an exact
-# match, @vcpu is given and the event does not have the "vcpu" property, an
-# error is returned.
 #
 # Since 2.2
 ##
 { 'command': 'trace-event-set-state',
-  'data': {'name': 'str', 'enable': 'bool', '*ignore-unavailable': 'bool',
-           '*vcpu': 'int'} }
+  'data': {'name': 'str', 'enable': 'bool', '*ignore-unavailable': 'bool'} }
index 5396fbf..830fb9e 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "qemu/osdep.h"
 
+#include <glib.h>
 
 #include <sys/ioctl.h>
 #include <sys/socket.h>
index 5f82ebb..b597ee1 100644 (file)
@@ -32,7 +32,8 @@
 #include "sysemu/char.h"
 #include "hw/usb.h"
 #include "qmp-commands.h"
-#include "qapi/clone-visitor.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/qmp-output-visitor.h"
 #include "qapi-visit.h"
 #include "qemu/base64.h"
 #include "io/channel-socket.h"
@@ -46,6 +47,7 @@
 #include <sys/times.h>
 #include <sys/wait.h>
 #include <termios.h>
+#include <sys/mman.h>
 #include <sys/ioctl.h>
 #include <sys/resource.h>
 #include <sys/socket.h>
@@ -786,13 +788,6 @@ static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond)
     return d->drv->chr_add_watch(d->drv, cond);
 }
 
-static void mux_chr_close(struct CharDriverState *chr)
-{
-    MuxDriver *d = chr->opaque;
-
-    g_free(d);
-}
-
 static CharDriverState *qemu_chr_open_mux(const char *id,
                                           ChardevBackend *backend,
                                           ChardevReturn *ret, Error **errp)
@@ -817,7 +812,6 @@ static CharDriverState *qemu_chr_open_mux(const char *id,
     chr->opaque = d;
     d->drv = drv;
     d->focus = -1;
-    chr->chr_close = mux_chr_close;
     chr->chr_write = mux_chr_write;
     chr->chr_update_read_handler = mux_chr_update_read_handler;
     chr->chr_accept_input = mux_chr_accept_input;
@@ -2768,16 +2762,13 @@ static int tcp_set_msgfds(CharDriverState *chr, int *fds, int num)
 {
     TCPCharDriver *s = chr->opaque;
 
-    /* clear old pending fd array */
-    g_free(s->write_msgfds);
-    s->write_msgfds = NULL;
-    s->write_msgfds_num = 0;
-
-    if (!s->connected ||
-        !qio_channel_has_feature(s->ioc,
+    if (!qio_channel_has_feature(s->ioc,
                                  QIO_CHANNEL_FEATURE_FD_PASS)) {
         return -1;
     }
+    /* clear old pending fd array */
+    g_free(s->write_msgfds);
+    s->write_msgfds = NULL;
 
     if (num) {
         s->write_msgfds = g_new(int, num);
@@ -2852,24 +2843,19 @@ static GSource *tcp_chr_add_watch(CharDriverState *chr, GIOCondition cond)
     return qio_channel_create_watch(s->ioc, cond);
 }
 
-static void tcp_chr_free_connection(CharDriverState *chr)
+static void tcp_chr_disconnect(CharDriverState *chr)
 {
     TCPCharDriver *s = chr->opaque;
-    int i;
 
     if (!s->connected) {
         return;
     }
 
-    if (s->read_msgfds_num) {
-        for (i = 0; i < s->read_msgfds_num; i++) {
-            close(s->read_msgfds[i]);
-        }
-        g_free(s->read_msgfds);
-        s->read_msgfds = NULL;
-        s->read_msgfds_num = 0;
+    s->connected = 0;
+    if (s->listen_ioc) {
+        s->listen_tag = qio_channel_add_watch(
+            QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL);
     }
-
     tcp_set_msgfds(chr, NULL, 0);
     remove_fd_in_watch(chr);
     object_unref(OBJECT(s->sioc));
@@ -2877,24 +2863,6 @@ static void tcp_chr_free_connection(CharDriverState *chr)
     object_unref(OBJECT(s->ioc));
     s->ioc = NULL;
     g_free(chr->filename);
-    chr->filename = NULL;
-    s->connected = 0;
-}
-
-static void tcp_chr_disconnect(CharDriverState *chr)
-{
-    TCPCharDriver *s = chr->opaque;
-
-    if (!s->connected) {
-        return;
-    }
-
-    tcp_chr_free_connection(chr);
-
-    if (s->listen_ioc) {
-        s->listen_tag = qio_channel_add_watch(
-            QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL);
-    }
     chr->filename = SocketAddress_to_str("disconnected:", s->addr,
                                          s->is_listen, s->is_telnet);
     qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
@@ -3171,54 +3139,20 @@ static gboolean tcp_chr_accept(QIOChannel *channel,
     return TRUE;
 }
 
-static int tcp_chr_wait_connected(CharDriverState *chr, Error **errp)
-{
-    TCPCharDriver *s = chr->opaque;
-    QIOChannelSocket *sioc;
-
-    /* It can't wait on s->connected, since it is set asynchronously
-     * in TLS and telnet cases, only wait for an accepted socket */
-    while (!s->ioc) {
-        if (s->is_listen) {
-            fprintf(stderr, "QEMU waiting for connection on: %s\n",
-                    chr->filename);
-            qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), true, NULL);
-            tcp_chr_accept(QIO_CHANNEL(s->listen_ioc), G_IO_IN, chr);
-            qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), false, NULL);
-        } else {
-            sioc = qio_channel_socket_new();
-            if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
-                object_unref(OBJECT(sioc));
-                return -1;
-            }
-            tcp_chr_new_client(chr, sioc);
-            object_unref(OBJECT(sioc));
-        }
-    }
-
-    return 0;
-}
-
-int qemu_chr_wait_connected(CharDriverState *chr, Error **errp)
-{
-    if (chr->chr_wait_connected) {
-        return chr->chr_wait_connected(chr, errp);
-    }
-
-    return 0;
-}
-
 static void tcp_chr_close(CharDriverState *chr)
 {
     TCPCharDriver *s = chr->opaque;
-
-    tcp_chr_free_connection(chr);
+    int i;
 
     if (s->reconnect_timer) {
         g_source_remove(s->reconnect_timer);
         s->reconnect_timer = 0;
     }
     qapi_free_SocketAddress(s->addr);
+    remove_fd_in_watch(chr);
+    if (s->ioc) {
+        object_unref(OBJECT(s->ioc));
+    }
     if (s->listen_tag) {
         g_source_remove(s->listen_tag);
         s->listen_tag = 0;
@@ -3226,9 +3160,18 @@ static void tcp_chr_close(CharDriverState *chr)
     if (s->listen_ioc) {
         object_unref(OBJECT(s->listen_ioc));
     }
+    if (s->read_msgfds_num) {
+        for (i = 0; i < s->read_msgfds_num; i++) {
+            close(s->read_msgfds[i]);
+        }
+        g_free(s->read_msgfds);
+    }
     if (s->tls_creds) {
         object_unref(OBJECT(s->tls_creds));
     }
+    if (s->write_msgfds_num) {
+        g_free(s->write_msgfds);
+    }
     g_free(s);
     qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
 }
@@ -4024,19 +3967,19 @@ void qemu_chr_fe_event(struct CharDriverState *chr, int event)
     }
 }
 
-guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
-                            GIOFunc func, void *user_data)
+int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
+                          GIOFunc func, void *user_data)
 {
     GSource *src;
     guint tag;
 
     if (s->chr_add_watch == NULL) {
-        return 0;
+        return -ENOSYS;
     }
 
     src = s->chr_add_watch(s, cond);
     if (!src) {
-        return 0;
+        return -EINVAL;
     }
 
     g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
@@ -4069,13 +4012,6 @@ void qemu_chr_fe_release(CharDriverState *s)
     s->avail_connections++;
 }
 
-void qemu_chr_disconnect(CharDriverState *chr)
-{
-    if (chr->chr_disconnect) {
-        chr->chr_disconnect(chr);
-    }
-}
-
 static void qemu_chr_free_common(CharDriverState *chr)
 {
     g_free(chr->filename);
@@ -4152,6 +4088,22 @@ CharDriverState *qemu_chr_find(const char *name)
     return NULL;
 }
 
+/* Get a character (serial) device interface.  */
+CharDriverState *qemu_char_get_next_serial(void)
+{
+    static int next_serial;
+    CharDriverState *chr;
+
+    /* FIXME: This function needs to go away: use chardev properties!  */
+
+    while (next_serial < MAX_SERIAL_PORTS && serial_hds[next_serial]) {
+        chr = serial_hds[next_serial++];
+        qemu_chr_fe_claim_no_fail(chr);
+        return chr;
+    }
+    return NULL;
+}
+
 QemuOptsList qemu_chardev_opts = {
     .name = "chardev",
     .implied_opt_name = "backend",
@@ -4256,26 +4208,14 @@ static CharDriverState *qmp_chardev_open_file(const char *id,
     ChardevFile *file = backend->u.file.data;
     ChardevCommon *common = qapi_ChardevFile_base(file);
     HANDLE out;
-    DWORD accessmode;
-    DWORD flags;
 
     if (file->has_in) {
         error_setg(errp, "input file not supported");
         return NULL;
     }
 
-    if (file->has_append && file->append) {
-        /* Append to file if it already exists. */
-        accessmode = FILE_GENERIC_WRITE & ~FILE_WRITE_DATA;
-        flags = OPEN_ALWAYS;
-    } else {
-        /* Truncate file if it already exists. */
-        accessmode = GENERIC_WRITE;
-        flags = CREATE_ALWAYS;
-    }
-
-    out = CreateFile(file->out, accessmode, FILE_SHARE_READ, NULL, flags,
-                     FILE_ATTRIBUTE_NORMAL, NULL);
+    out = CreateFile(file->out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+                     OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
     if (out == INVALID_HANDLE_VALUE) {
         error_setg(errp, "open %s failed", file->out);
         return NULL;
@@ -4459,14 +4399,12 @@ static CharDriverState *qmp_chardev_open_socket(const char *id,
         }
     }
 
-    s->addr = QAPI_CLONE(SocketAddress, sock->addr);
+    qapi_copy_SocketAddress(&s->addr, sock->addr);
 
     chr->opaque = s;
-    chr->chr_wait_connected = tcp_chr_wait_connected;
     chr->chr_write = tcp_chr_write;
     chr->chr_sync_read = tcp_chr_sync_read;
     chr->chr_close = tcp_chr_close;
-    chr->chr_disconnect = tcp_chr_disconnect;
     chr->get_msgfds = tcp_get_msgfds;
     chr->set_msgfds = tcp_set_msgfds;
     chr->chr_add_client = tcp_chr_add_client;
@@ -4486,30 +4424,32 @@ static CharDriverState *qmp_chardev_open_socket(const char *id,
         s->reconnect_time = reconnect;
     }
 
+    sioc = qio_channel_socket_new();
     if (s->reconnect_time) {
-        sioc = qio_channel_socket_new();
         qio_channel_socket_connect_async(sioc, s->addr,
                                          qemu_chr_socket_connected,
                                          chr, NULL);
+    } else if (s->is_listen) {
+        if (qio_channel_socket_listen_sync(sioc, s->addr, errp) < 0) {
+            goto error;
+        }
+        s->listen_ioc = sioc;
+        if (is_waitconnect) {
+            fprintf(stderr, "QEMU waiting for connection on: %s\n",
+                    chr->filename);
+            tcp_chr_accept(QIO_CHANNEL(s->listen_ioc), G_IO_IN, chr);
+        }
+        qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), false, NULL);
+        if (!s->ioc) {
+            s->listen_tag = qio_channel_add_watch(
+                QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL);
+        }
     } else {
-        if (s->is_listen) {
-            sioc = qio_channel_socket_new();
-            if (qio_channel_socket_listen_sync(sioc, s->addr, errp) < 0) {
-                goto error;
-            }
-            s->listen_ioc = sioc;
-            if (is_waitconnect &&
-                qemu_chr_wait_connected(chr, errp) < 0) {
-                goto error;
-            }
-            if (!s->ioc) {
-                s->listen_tag = qio_channel_add_watch(
-                    QIO_CHANNEL(s->listen_ioc), G_IO_IN,
-                    tcp_chr_accept, chr, NULL);
-            }
-        } else if (qemu_chr_wait_connected(chr, errp) < 0) {
+        if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
             goto error;
         }
+        tcp_chr_new_client(chr, sioc);
+        object_unref(OBJECT(sioc));
     }
 
     return chr;
@@ -4618,15 +4558,6 @@ void qmp_chardev_remove(const char *id, Error **errp)
     qemu_chr_delete(chr);
 }
 
-void qemu_chr_cleanup(void)
-{
-    CharDriverState *chr, *tmp;
-
-    QTAILQ_FOREACH_SAFE(chr, &chardevs, next, tmp) {
-        qemu_chr_delete(chr);
-    }
-}
-
 static void register_types(void)
 {
     register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL,
index f37fd31..79141d3 100644 (file)
@@ -693,9 +693,6 @@ Supported options:
 File name of a base image (see @option{create} subcommand).
 @item compat6
 Create a VMDK version 6 image (instead of version 4)
-@item hwversion
-Specify vmdk virtual hardware version. Compat6 flag cannot be enabled
-if hwversion is specified.
 @item subformat
 Specifies which VMDK subformat to use. Valid options are
 @code{monolithicSparse} (default),
index 7e95b2d..e7cded6 100644 (file)
@@ -9,12 +9,6 @@ STEXI
 @table @option
 ETEXI
 
-DEF("bench", img_bench,
-    "bench [-c count] [-d depth] [-f fmt] [--flush-interval=flush_interval] [-n] [--no-drain] [-o offset] [--pattern=pattern] [-q] [-s buffer_size] [-S step_size] [-t cache] [-w] filename")
-STEXI
-@item bench [-c @var{count}] [-d @var{depth}] [-f @var{fmt}] [--flush-interval=@var{flush_interval}] [-n] [--no-drain] [-o @var{offset}] [--pattern=@var{pattern}] [-q] [-s @var{buffer_size}] [-S @var{step_size}] [-t @var{cache}] [-w] @var{filename}
-ETEXI
-
 DEF("check", img_check,
     "check [-q] [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] [-r [leaks | all]] [-T src_cache] filename")
 STEXI
index f204d04..46f2a6d 100644 (file)
@@ -22,7 +22,6 @@
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "qemu-version.h"
 #include "qapi/error.h"
 #include "qapi-visit.h"
 #include "qapi/qmp-output-visitor.h"
@@ -32,7 +31,6 @@
 #include "qemu/config-file.h"
 #include "qemu/option.h"
 #include "qemu/error-report.h"
-#include "qemu/log.h"
 #include "qom/object_interfaces.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/block-backend.h"
 #include "block/blockjob.h"
 #include "block/qapi.h"
 #include "crypto/init.h"
-#include "trace/control.h"
 #include <getopt.h>
 
 #define QEMU_IMG_VERSION "qemu-img version " QEMU_VERSION QEMU_PKGVERSION \
-                          ", " QEMU_COPYRIGHT "\n"
+                          ", Copyright (c) 2004-2008 Fabrice Bellard\n"
 
 typedef struct img_cmd_t {
     const char *name;
@@ -56,9 +53,6 @@ enum {
     OPTION_BACKING_CHAIN = 257,
     OPTION_OBJECT = 258,
     OPTION_IMAGE_OPTS = 259,
-    OPTION_PATTERN = 260,
-    OPTION_FLUSH_INTERVAL = 261,
-    OPTION_NO_DRAIN = 262,
 };
 
 typedef enum OutputFormat {
@@ -93,14 +87,9 @@ static void QEMU_NORETURN help(void)
 {
     const char *help_msg =
            QEMU_IMG_VERSION
-           "usage: qemu-img [standard options] command [command options]\n"
+           "usage: qemu-img command [command options]\n"
            "QEMU disk image utility\n"
            "\n"
-           "    '-h', '--help'       display this help and exit\n"
-           "    '-V', '--version'    output version information and exit\n"
-           "    '-T', '--trace'      [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
-           "                         specify tracing options\n"
-           "\n"
            "Command syntax:\n"
 #define DEF(option, callback, arg_string)        \
            "  " arg_string "\n"
@@ -490,17 +479,18 @@ fail:
 
 static void dump_json_image_check(ImageCheck *check, bool quiet)
 {
+    Error *local_err = NULL;
     QString *str;
+    QmpOutputVisitor *ov = qmp_output_visitor_new();
     QObject *obj;
-    Visitor *v = qmp_output_visitor_new(&obj);
-
-    visit_type_ImageCheck(v, NULL, &check, &error_abort);
-    visit_complete(v, &obj);
+    visit_type_ImageCheck(qmp_output_get_visitor(ov), NULL, &check,
+                          &local_err);
+    obj = qmp_output_get_qobject(ov);
     str = qobject_to_json_pretty(obj);
     assert(str != NULL);
     qprintf(quiet, "%s\n", qstring_get_str(str));
     qobject_decref(obj);
-    visit_free(v);
+    qmp_output_visitor_cleanup(ov);
     QDECREF(str);
 }
 
@@ -785,7 +775,7 @@ static void common_block_job_cb(void *opaque, int ret)
 
 static void run_block_job(BlockJob *job, Error **errp)
 {
-    AioContext *aio_context = blk_get_aio_context(job->blk);
+    AioContext *aio_context = bdrv_get_aio_context(job->bs);
 
     do {
         aio_poll(aio_context, true);
@@ -920,7 +910,7 @@ static int img_commit(int argc, char **argv)
         .bs   = bs,
     };
 
-    commit_active_start("commit", bs, base_bs, 0, BLOCKDEV_ON_ERROR_REPORT,
+    commit_active_start(bs, base_bs, 0, BLOCKDEV_ON_ERROR_REPORT,
                         common_block_job_cb, &cbi, &local_err);
     if (local_err) {
         goto done;
@@ -1098,8 +1088,7 @@ static int check_empty_sectors(BlockBackend *blk, int64_t sect_num,
                                uint8_t *buffer, bool quiet)
 {
     int pnum, ret = 0;
-    ret = blk_pread(blk, sect_num << BDRV_SECTOR_BITS, buffer,
-                    sect_count << BDRV_SECTOR_BITS);
+    ret = blk_read(blk, sect_num, buffer, sect_count);
     if (ret < 0) {
         error_report("Error while reading offset %" PRId64 " of %s: %s",
                      sectors_to_bytes(sect_num), filename, strerror(-ret));
@@ -1312,8 +1301,7 @@ static int img_compare(int argc, char **argv)
             nb_sectors = MIN(pnum1, pnum2);
         } else if (allocated1 == allocated2) {
             if (allocated1) {
-                ret = blk_pread(blk1, sector_num << BDRV_SECTOR_BITS, buf1,
-                                nb_sectors << BDRV_SECTOR_BITS);
+                ret = blk_read(blk1, sector_num, buf1, nb_sectors);
                 if (ret < 0) {
                     error_report("Error while reading offset %" PRId64 " of %s:"
                                  " %s", sectors_to_bytes(sector_num), filename1,
@@ -1321,8 +1309,7 @@ static int img_compare(int argc, char **argv)
                     ret = 4;
                     goto out;
                 }
-                ret = blk_pread(blk2, sector_num << BDRV_SECTOR_BITS, buf2,
-                                nb_sectors << BDRV_SECTOR_BITS);
+                ret = blk_read(blk2, sector_num, buf2, nb_sectors);
                 if (ret < 0) {
                     error_report("Error while reading offset %" PRId64
                                  " of %s: %s", sectors_to_bytes(sector_num),
@@ -1485,21 +1472,10 @@ static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num)
         } else if (!s->target_has_backing) {
             /* Without a target backing file we must copy over the contents of
              * the backing file as well. */
-            /* Check block status of the backing file chain to avoid
+            /* TODO Check block status of the backing file chain to avoid
              * needlessly reading zeroes and limiting the iteration to the
              * buffer size */
-            ret = bdrv_get_block_status_above(blk_bs(s->src[s->src_cur]), NULL,
-                                              sector_num - s->src_cur_offset,
-                                              n, &n, &file);
-            if (ret < 0) {
-                return ret;
-            }
-
-            if (ret & BDRV_BLOCK_ZERO) {
-                s->status = BLK_ZERO;
-            } else {
-                s->status = BLK_DATA;
-            }
+            s->status = BLK_DATA;
         } else {
             s->status = BLK_BACKING_FILE;
         }
@@ -1546,9 +1522,7 @@ static int convert_read(ImgConvertState *s, int64_t sector_num, int nb_sectors,
         bs_sectors = s->src_sectors[s->src_cur];
 
         n = MIN(nb_sectors, bs_sectors - (sector_num - s->src_cur_offset));
-        ret = blk_pread(blk,
-                        (sector_num - s->src_cur_offset) << BDRV_SECTOR_BITS,
-                        buf, n << BDRV_SECTOR_BITS);
+        ret = blk_read(blk, sector_num - s->src_cur_offset, buf, n);
         if (ret < 0) {
             return ret;
         }
@@ -1603,8 +1577,7 @@ static int convert_write(ImgConvertState *s, int64_t sector_num, int nb_sectors,
             if (!s->min_sparse ||
                 is_allocated_sectors_min(buf, n, &n, s->min_sparse))
             {
-                ret = blk_pwrite(s->target, sector_num << BDRV_SECTOR_BITS,
-                                 buf, n << BDRV_SECTOR_BITS, 0);
+                ret = blk_write(s->target, sector_num, buf, n);
                 if (ret < 0) {
                     return ret;
                 }
@@ -1616,8 +1589,7 @@ static int convert_write(ImgConvertState *s, int64_t sector_num, int nb_sectors,
             if (s->has_zero_init) {
                 break;
             }
-            ret = blk_pwrite_zeroes(s->target, sector_num << BDRV_SECTOR_BITS,
-                                    n << BDRV_SECTOR_BITS, 0);
+            ret = blk_write_zeroes(s->target, sector_num, n, 0);
             if (ret < 0) {
                 return ret;
             }
@@ -1647,7 +1619,7 @@ static int convert_do_copy(ImgConvertState *s)
     if (!s->has_zero_init && !s->target_has_backing &&
         bdrv_can_write_zeroes_with_unmap(blk_bs(s->target)))
     {
-        ret = blk_make_zero(s->target, BDRV_REQ_MAY_UNMAP);
+        ret = bdrv_make_zero(blk_bs(s->target), BDRV_REQ_MAY_UNMAP);
         if (ret == 0) {
             s->has_zero_init = true;
         }
@@ -2084,14 +2056,13 @@ static int img_convert(int argc, char **argv)
     }
     out_bs = blk_bs(out_blk);
 
-    /* increase bufsectors from the default 4096 (2M) if opt_transfer
+    /* increase bufsectors from the default 4096 (2M) if opt_transfer_length
      * or discard_alignment of the out_bs is greater. Limit to 32768 (16MB)
      * as maximum. */
     bufsectors = MIN(32768,
-                     MAX(bufsectors,
-                         MAX(out_bs->bl.opt_transfer >> BDRV_SECTOR_BITS,
-                             out_bs->bl.pdiscard_alignment >>
-                             BDRV_SECTOR_BITS)));
+                     MAX(bufsectors, MAX(out_bs->bl.opt_transfer_length,
+                                         out_bs->bl.discard_alignment))
+                    );
 
     if (skip_create) {
         int64_t output_sectors = blk_nb_sectors(out_blk);
@@ -2181,33 +2152,34 @@ static void dump_snapshots(BlockDriverState *bs)
 
 static void dump_json_image_info_list(ImageInfoList *list)
 {
+    Error *local_err = NULL;
     QString *str;
+    QmpOutputVisitor *ov = qmp_output_visitor_new();
     QObject *obj;
-    Visitor *v = qmp_output_visitor_new(&obj);
-
-    visit_type_ImageInfoList(v, NULL, &list, &error_abort);
-    visit_complete(v, &obj);
+    visit_type_ImageInfoList(qmp_output_get_visitor(ov), NULL, &list,
+                             &local_err);
+    obj = qmp_output_get_qobject(ov);
     str = qobject_to_json_pretty(obj);
     assert(str != NULL);
     printf("%s\n", qstring_get_str(str));
     qobject_decref(obj);
-    visit_free(v);
+    qmp_output_visitor_cleanup(ov);
     QDECREF(str);
 }
 
 static void dump_json_image_info(ImageInfo *info)
 {
+    Error *local_err = NULL;
     QString *str;
+    QmpOutputVisitor *ov = qmp_output_visitor_new();
     QObject *obj;
-    Visitor *v = qmp_output_visitor_new(&obj);
-
-    visit_type_ImageInfo(v, NULL, &info, &error_abort);
-    visit_complete(v, &obj);
+    visit_type_ImageInfo(qmp_output_get_visitor(ov), NULL, &info, &local_err);
+    obj = qmp_output_get_qobject(ov);
     str = qobject_to_json_pretty(obj);
     assert(str != NULL);
     printf("%s\n", qstring_get_str(str));
     qobject_decref(obj);
-    visit_free(v);
+    qmp_output_visitor_cleanup(ov);
     QDECREF(str);
 }
 
@@ -3051,8 +3023,7 @@ static int img_rebase(int argc, char **argv)
                     n = old_backing_num_sectors - sector;
                 }
 
-                ret = blk_pread(blk_old_backing, sector << BDRV_SECTOR_BITS,
-                                buf_old, n << BDRV_SECTOR_BITS);
+                ret = blk_read(blk_old_backing, sector, buf_old, n);
                 if (ret < 0) {
                     error_report("error while reading from old backing file");
                     goto out;
@@ -3066,8 +3037,7 @@ static int img_rebase(int argc, char **argv)
                     n = new_backing_num_sectors - sector;
                 }
 
-                ret = blk_pread(blk_new_backing, sector << BDRV_SECTOR_BITS,
-                                buf_new, n << BDRV_SECTOR_BITS);
+                ret = blk_read(blk_new_backing, sector, buf_new, n);
                 if (ret < 0) {
                     error_report("error while reading from new backing file");
                     goto out;
@@ -3083,10 +3053,8 @@ static int img_rebase(int argc, char **argv)
                 if (compare_sectors(buf_old + written * 512,
                     buf_new + written * 512, n - written, &pnum))
                 {
-                    ret = blk_pwrite(blk,
-                                     (sector + written) << BDRV_SECTOR_BITS,
-                                     buf_old + written * 512,
-                                     pnum << BDRV_SECTOR_BITS, 0);
+                    ret = blk_write(blk, sector + written,
+                                    buf_old + written * 512, pnum);
                     if (ret < 0) {
                         error_report("Error while writing to COW image: %s",
                             strerror(-ret));
@@ -3283,7 +3251,7 @@ static int img_resize(int argc, char **argv)
         error_report("Image is read-only");
         break;
     default:
-        error_report("Error resizing image: %s", strerror(-ret));
+        error_report("Error resizing image (%d)", -ret);
         break;
     }
 out:
@@ -3469,332 +3437,6 @@ out_no_progress:
     return 0;
 }
 
-typedef struct BenchData {
-    BlockBackend *blk;
-    uint64_t image_size;
-    bool write;
-    int bufsize;
-    int step;
-    int nrreq;
-    int n;
-    int flush_interval;
-    bool drain_on_flush;
-    uint8_t *buf;
-    QEMUIOVector *qiov;
-
-    int in_flight;
-    bool in_flush;
-    uint64_t offset;
-} BenchData;
-
-static void bench_undrained_flush_cb(void *opaque, int ret)
-{
-    if (ret < 0) {
-        error_report("Failed flush request: %s", strerror(-ret));
-        exit(EXIT_FAILURE);
-    }
-}
-
-static void bench_cb(void *opaque, int ret)
-{
-    BenchData *b = opaque;
-    BlockAIOCB *acb;
-
-    if (ret < 0) {
-        error_report("Failed request: %s", strerror(-ret));
-        exit(EXIT_FAILURE);
-    }
-
-    if (b->in_flush) {
-        /* Just finished a flush with drained queue: Start next requests */
-        assert(b->in_flight == 0);
-        b->in_flush = false;
-    } else if (b->in_flight > 0) {
-        int remaining = b->n - b->in_flight;
-
-        b->n--;
-        b->in_flight--;
-
-        /* Time for flush? Drain queue if requested, then flush */
-        if (b->flush_interval && remaining % b->flush_interval == 0) {
-            if (!b->in_flight || !b->drain_on_flush) {
-                BlockCompletionFunc *cb;
-
-                if (b->drain_on_flush) {
-                    b->in_flush = true;
-                    cb = bench_cb;
-                } else {
-                    cb = bench_undrained_flush_cb;
-                }
-
-                acb = blk_aio_flush(b->blk, cb, b);
-                if (!acb) {
-                    error_report("Failed to issue flush request");
-                    exit(EXIT_FAILURE);
-                }
-            }
-            if (b->drain_on_flush) {
-                return;
-            }
-        }
-    }
-
-    while (b->n > b->in_flight && b->in_flight < b->nrreq) {
-        if (b->write) {
-            acb = blk_aio_pwritev(b->blk, b->offset, b->qiov, 0,
-                                  bench_cb, b);
-        } else {
-            acb = blk_aio_preadv(b->blk, b->offset, b->qiov, 0,
-                                 bench_cb, b);
-        }
-        if (!acb) {
-            error_report("Failed to issue request");
-            exit(EXIT_FAILURE);
-        }
-        b->in_flight++;
-        b->offset += b->step;
-        b->offset %= b->image_size;
-    }
-}
-
-static int img_bench(int argc, char **argv)
-{
-    int c, ret = 0;
-    const char *fmt = NULL, *filename;
-    bool quiet = false;
-    bool image_opts = false;
-    bool is_write = false;
-    int count = 75000;
-    int depth = 64;
-    int64_t offset = 0;
-    size_t bufsize = 4096;
-    int pattern = 0;
-    size_t step = 0;
-    int flush_interval = 0;
-    bool drain_on_flush = true;
-    int64_t image_size;
-    BlockBackend *blk = NULL;
-    BenchData data = {};
-    int flags = 0;
-    bool writethrough = false;
-    struct timeval t1, t2;
-    int i;
-
-    for (;;) {
-        static const struct option long_options[] = {
-            {"help", no_argument, 0, 'h'},
-            {"flush-interval", required_argument, 0, OPTION_FLUSH_INTERVAL},
-            {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
-            {"pattern", required_argument, 0, OPTION_PATTERN},
-            {"no-drain", no_argument, 0, OPTION_NO_DRAIN},
-            {0, 0, 0, 0}
-        };
-        c = getopt_long(argc, argv, "hc:d:f:no:qs:S:t:w", long_options, NULL);
-        if (c == -1) {
-            break;
-        }
-
-        switch (c) {
-        case 'h':
-        case '?':
-            help();
-            break;
-        case 'c':
-        {
-            char *end;
-            errno = 0;
-            count = strtoul(optarg, &end, 0);
-            if (errno || *end || count > INT_MAX) {
-                error_report("Invalid request count specified");
-                return 1;
-            }
-            break;
-        }
-        case 'd':
-        {
-            char *end;
-            errno = 0;
-            depth = strtoul(optarg, &end, 0);
-            if (errno || *end || depth > INT_MAX) {
-                error_report("Invalid queue depth specified");
-                return 1;
-            }
-            break;
-        }
-        case 'f':
-            fmt = optarg;
-            break;
-        case 'n':
-            flags |= BDRV_O_NATIVE_AIO;
-            break;
-        case 'o':
-        {
-            char *end;
-            errno = 0;
-            offset = qemu_strtosz_suffix(optarg, &end,
-                                         QEMU_STRTOSZ_DEFSUFFIX_B);
-            if (offset < 0|| *end) {
-                error_report("Invalid offset specified");
-                return 1;
-            }
-            break;
-        }
-            break;
-        case 'q':
-            quiet = true;
-            break;
-        case 's':
-        {
-            int64_t sval;
-            char *end;
-
-            sval = qemu_strtosz_suffix(optarg, &end, QEMU_STRTOSZ_DEFSUFFIX_B);
-            if (sval < 0 || sval > INT_MAX || *end) {
-                error_report("Invalid buffer size specified");
-                return 1;
-            }
-
-            bufsize = sval;
-            break;
-        }
-        case 'S':
-        {
-            int64_t sval;
-            char *end;
-
-            sval = qemu_strtosz_suffix(optarg, &end, QEMU_STRTOSZ_DEFSUFFIX_B);
-            if (sval < 0 || sval > INT_MAX || *end) {
-                error_report("Invalid step size specified");
-                return 1;
-            }
-
-            step = sval;
-            break;
-        }
-        case 't':
-            ret = bdrv_parse_cache_mode(optarg, &flags, &writethrough);
-            if (ret < 0) {
-                error_report("Invalid cache mode");
-                ret = -1;
-                goto out;
-            }
-            break;
-        case 'w':
-            flags |= BDRV_O_RDWR;
-            is_write = true;
-            break;
-        case OPTION_PATTERN:
-        {
-            char *end;
-            errno = 0;
-            pattern = strtoul(optarg, &end, 0);
-            if (errno || *end || pattern > 0xff) {
-                error_report("Invalid pattern byte specified");
-                return 1;
-            }
-            break;
-        }
-        case OPTION_FLUSH_INTERVAL:
-        {
-            char *end;
-            errno = 0;
-            flush_interval = strtoul(optarg, &end, 0);
-            if (errno || *end || flush_interval > INT_MAX) {
-                error_report("Invalid flush interval specified");
-                return 1;
-            }
-            break;
-        }
-        case OPTION_NO_DRAIN:
-            drain_on_flush = false;
-            break;
-        case OPTION_IMAGE_OPTS:
-            image_opts = true;
-            break;
-        }
-    }
-
-    if (optind != argc - 1) {
-        error_exit("Expecting one image file name");
-    }
-    filename = argv[argc - 1];
-
-    if (!is_write && flush_interval) {
-        error_report("--flush-interval is only available in write tests");
-        ret = -1;
-        goto out;
-    }
-    if (flush_interval && flush_interval < depth) {
-        error_report("Flush interval can't be smaller than depth");
-        ret = -1;
-        goto out;
-    }
-
-    blk = img_open(image_opts, filename, fmt, flags, writethrough, quiet);
-    if (!blk) {
-        ret = -1;
-        goto out;
-    }
-
-    image_size = blk_getlength(blk);
-    if (image_size < 0) {
-        ret = image_size;
-        goto out;
-    }
-
-    data = (BenchData) {
-        .blk            = blk,
-        .image_size     = image_size,
-        .bufsize        = bufsize,
-        .step           = step ?: bufsize,
-        .nrreq          = depth,
-        .n              = count,
-        .offset         = offset,
-        .write          = is_write,
-        .flush_interval = flush_interval,
-        .drain_on_flush = drain_on_flush,
-    };
-    printf("Sending %d %s requests, %d bytes each, %d in parallel "
-           "(starting at offset %" PRId64 ", step size %d)\n",
-           data.n, data.write ? "write" : "read", data.bufsize, data.nrreq,
-           data.offset, data.step);
-    if (flush_interval) {
-        printf("Sending flush every %d requests\n", flush_interval);
-    }
-
-    data.buf = blk_blockalign(blk, data.nrreq * data.bufsize);
-    memset(data.buf, pattern, data.nrreq * data.bufsize);
-
-    data.qiov = g_new(QEMUIOVector, data.nrreq);
-    for (i = 0; i < data.nrreq; i++) {
-        qemu_iovec_init(&data.qiov[i], 1);
-        qemu_iovec_add(&data.qiov[i],
-                       data.buf + i * data.bufsize, data.bufsize);
-    }
-
-    gettimeofday(&t1, NULL);
-    bench_cb(&data, 0);
-
-    while (data.n > 0) {
-        main_loop_wait(false);
-    }
-    gettimeofday(&t2, NULL);
-
-    printf("Run completed in %3.3f seconds.\n",
-           (t2.tv_sec - t1.tv_sec)
-           + ((double)(t2.tv_usec - t1.tv_usec) / 1000000));
-
-out:
-    qemu_vfree(data.buf);
-    blk_unref(blk);
-
-    if (ret) {
-        return 1;
-    }
-    return 0;
-}
-
-
 static const img_cmd_t img_cmds[] = {
 #define DEF(option, callback, arg_string)        \
     { option, callback },
@@ -3809,12 +3451,10 @@ int main(int argc, char **argv)
     const img_cmd_t *cmd;
     const char *cmdname;
     Error *local_error = NULL;
-    char *trace_file = NULL;
     int c;
     static const struct option long_options[] = {
         {"help", no_argument, 0, 'h'},
-        {"version", no_argument, 0, 'V'},
-        {"trace", required_argument, NULL, 'T'},
+        {"version", no_argument, 0, 'v'},
         {0, 0, 0, 0}
     };
 
@@ -3830,54 +3470,36 @@ int main(int argc, char **argv)
         exit(EXIT_FAILURE);
     }
 
-    qcrypto_init(&error_fatal);
+    if (qcrypto_init(&local_error) < 0) {
+        error_reportf_err(local_error, "cannot initialize crypto: ");
+        exit(1);
+    }
 
     module_call_init(MODULE_INIT_QOM);
     bdrv_init();
     if (argc < 2) {
         error_exit("Not enough arguments");
     }
+    cmdname = argv[1];
 
     qemu_add_opts(&qemu_object_opts);
     qemu_add_opts(&qemu_source_opts);
-    qemu_add_opts(&qemu_trace_opts);
 
-    while ((c = getopt_long(argc, argv, "+hVT:", long_options, NULL)) != -1) {
-        switch (c) {
-        case 'h':
-            help();
-            return 0;
-        case 'V':
-            printf(QEMU_IMG_VERSION);
-            return 0;
-        case 'T':
-            g_free(trace_file);
-            trace_file = trace_opt_parse(optarg);
-            break;
+    /* find the command */
+    for (cmd = img_cmds; cmd->name != NULL; cmd++) {
+        if (!strcmp(cmdname, cmd->name)) {
+            return cmd->handler(argc - 1, argv + 1);
         }
     }
 
-    cmdname = argv[optind];
+    c = getopt_long(argc, argv, "h", long_options, NULL);
 
-    /* reset getopt_long scanning */
-    argc -= optind;
-    if (argc < 1) {
-        return 0;
-    }
-    argv += optind;
-    optind = 0;
-
-    if (!trace_init_backends()) {
-        exit(1);
+    if (c == 'h') {
+        help();
     }
-    trace_init_file(trace_file);
-    qemu_set_log(LOG_TRACE);
-
-    /* find the command */
-    for (cmd = img_cmds; cmd->name != NULL; cmd++) {
-        if (!strcmp(cmdname, cmd->name)) {
-            return cmd->handler(argc, argv);
-        }
+    if (c == 'v') {
+        printf(QEMU_IMG_VERSION);
+        return 0;
     }
 
     /* not found */
index 449a19c..afaebdd 100644 (file)
@@ -1,6 +1,6 @@
 @example
 @c man begin SYNOPSIS
-@command{qemu-img} [@var{standard} @var{options}] @var{command} [@var{command} @var{options}]
+@command{qemu-img} @var{command} [@var{command} @var{options}]
 @c man end
 @end example
 
@@ -16,17 +16,6 @@ inconsistent state.
 
 @c man begin OPTIONS
 
-Standard options:
-@table @option
-@item -h, --help
-Display this help and exit
-@item -V, --version
-Display version information and exit
-@item -T, --trace [[enable=]@var{pattern}][,events=@var{file}][,file=@var{file}]
-@findex --trace
-@include qemu-option-trace.texi
-@end table
-
 The following commands are supported:
 
 @include qemu-img-cmds.texi
@@ -142,30 +131,6 @@ Skip the creation of the target volume
 Command description:
 
 @table @option
-@item bench [-c @var{count}] [-d @var{depth}] [-f @var{fmt}] [--flush-interval=@var{flush_interval}] [-n] [--no-drain] [-o @var{offset}] [--pattern=@var{pattern}] [-q] [-s @var{buffer_size}] [-S @var{step_size}] [-t @var{cache}] [-w] @var{filename}
-
-Run a simple sequential I/O benchmark on the specified image. If @code{-w} is
-specified, a write test is performed, otherwise a read test is performed.
-
-A total number of @var{count} I/O requests is performed, each @var{buffer_size}
-bytes in size, and with @var{depth} requests in parallel. The first request
-starts at the position given by @var{offset}, each following request increases
-the current position by @var{step_size}. If @var{step_size} is not given,
-@var{buffer_size} is used for its value.
-
-If @var{flush_interval} is specified for a write test, the request queue is
-drained and a flush is issued before new writes are made whenever the number of
-remaining requests is a multiple of @var{flush_interval}. If additionally
-@code{--no-drain} is specified, a flush is issued without draining the request
-queue first.
-
-If @code{-n} is specified, the native AIO backend is used if possible. On
-Linux, this option only works if @code{-t none} or @code{-t directsync} is
-specified as well.
-
-For write tests, by default a buffer filled with zeros is written. This can be
-overridden with a pattern byte specified by @var{pattern}.
-
 @item check [-f @var{fmt}] [--output=@var{ofmt}] [-r [leaks | all]] [-T @var{src_cache}] @var{filename}
 
 Perform a consistency check on the disk image @var{filename}. The command can
index 25954f5..e34f777 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Command line utility to exercise the QEMU I/O path.
  *
- * Copyright (C) 2009-2016 Red Hat, Inc.
+ * Copyright (C) 2009 Red Hat, Inc.
  * Copyright (c) 2003-2005 Silicon Graphics, Inc.
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
@@ -345,7 +345,7 @@ static void dump_buffer(const void *buffer, int64_t offset, int64_t len)
 }
 
 static void print_report(const char *op, struct timeval *t, int64_t offset,
-                         int64_t count, int64_t total, int cnt, bool Cflag)
+                         int64_t count, int64_t total, int cnt, int Cflag)
 {
     char s1[64], s2[64], ts[64];
 
@@ -389,9 +389,15 @@ create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov,
             goto fail;
         }
 
-        if (len > SIZE_MAX) {
-            printf("Argument '%s' exceeds maximum size %llu\n", arg,
-                   (unsigned long long)SIZE_MAX);
+        /* should be SIZE_T_MAX, but that doesn't exist */
+        if (len > INT_MAX) {
+            printf("Argument '%s' exceeds maximum size %d\n", arg, INT_MAX);
+            goto fail;
+        }
+
+        if (len & 0x1ff) {
+            printf("length argument %" PRId64
+                   " is not sector aligned\n", len);
             goto fail;
         }
 
@@ -413,6 +419,40 @@ fail:
     return buf;
 }
 
+static int do_read(BlockBackend *blk, char *buf, int64_t offset, int64_t count,
+                   int64_t *total)
+{
+    int ret;
+
+    if (count >> 9 > INT_MAX) {
+        return -ERANGE;
+    }
+
+    ret = blk_read(blk, offset >> 9, (uint8_t *)buf, count >> 9);
+    if (ret < 0) {
+        return ret;
+    }
+    *total = count;
+    return 1;
+}
+
+static int do_write(BlockBackend *blk, char *buf, int64_t offset, int64_t count,
+                    int64_t *total)
+{
+    int ret;
+
+    if (count >> 9 > INT_MAX) {
+        return -ERANGE;
+    }
+
+    ret = blk_write(blk, offset >> 9, (uint8_t *)buf, count >> 9);
+    if (ret < 0) {
+        return ret;
+    }
+    *total = count;
+    return 1;
+}
+
 static int do_pread(BlockBackend *blk, char *buf, int64_t offset,
                     int64_t count, int64_t *total)
 {
@@ -428,13 +468,13 @@ static int do_pread(BlockBackend *blk, char *buf, int64_t offset,
 }
 
 static int do_pwrite(BlockBackend *blk, char *buf, int64_t offset,
-                     int64_t count, int flags, int64_t *total)
+                     int64_t count, int64_t *total)
 {
     if (count > INT_MAX) {
         return -ERANGE;
     }
 
-    *total = blk_pwrite(blk, offset, (uint8_t *)buf, count, flags);
+    *total = blk_pwrite(blk, offset, (uint8_t *)buf, count);
     if (*total < 0) {
         return *total;
     }
@@ -446,17 +486,16 @@ typedef struct {
     int64_t offset;
     int64_t count;
     int64_t *total;
-    int flags;
     int ret;
     bool done;
 } CoWriteZeroes;
 
-static void coroutine_fn co_pwrite_zeroes_entry(void *opaque)
+static void coroutine_fn co_write_zeroes_entry(void *opaque)
 {
     CoWriteZeroes *data = opaque;
 
-    data->ret = blk_co_pwrite_zeroes(data->blk, data->offset, data->count,
-                                     data->flags);
+    data->ret = blk_co_write_zeroes(data->blk, data->offset / BDRV_SECTOR_SIZE,
+                                    data->count / BDRV_SECTOR_SIZE, 0);
     data->done = true;
     if (data->ret < 0) {
         *data->total = data->ret;
@@ -466,8 +505,8 @@ static void coroutine_fn co_pwrite_zeroes_entry(void *opaque)
     *data->total = data->count;
 }
 
-static int do_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
-                               int64_t count, int flags, int64_t *total)
+static int do_co_write_zeroes(BlockBackend *blk, int64_t offset, int64_t count,
+                              int64_t *total)
 {
     Coroutine *co;
     CoWriteZeroes data = {
@@ -475,16 +514,15 @@ static int do_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
         .offset = offset,
         .count  = count,
         .total  = total,
-        .flags  = flags,
         .done   = false,
     };
 
-    if (count > INT_MAX) {
+    if (count >> BDRV_SECTOR_BITS > INT_MAX) {
         return -ERANGE;
     }
 
-    co = qemu_coroutine_create(co_pwrite_zeroes_entry, &data);
-    qemu_coroutine_enter(co);
+    co = qemu_coroutine_create(co_write_zeroes_entry);
+    qemu_coroutine_enter(co, &data);
     while (!data.done) {
         aio_poll(blk_get_aio_context(blk), true);
     }
@@ -500,7 +538,7 @@ static int do_write_compressed(BlockBackend *blk, char *buf, int64_t offset,
 {
     int ret;
 
-    if (count >> 9 > BDRV_REQUEST_MAX_SECTORS) {
+    if (count >> 9 > INT_MAX) {
         return -ERANGE;
     }
 
@@ -551,7 +589,8 @@ static int do_aio_readv(BlockBackend *blk, QEMUIOVector *qiov,
 {
     int async_ret = NOT_DONE;
 
-    blk_aio_preadv(blk, offset, qiov, 0, aio_rw_done, &async_ret);
+    blk_aio_readv(blk, offset >> 9, qiov, qiov->size >> 9,
+                  aio_rw_done, &async_ret);
     while (async_ret == NOT_DONE) {
         main_loop_wait(false);
     }
@@ -561,11 +600,12 @@ static int do_aio_readv(BlockBackend *blk, QEMUIOVector *qiov,
 }
 
 static int do_aio_writev(BlockBackend *blk, QEMUIOVector *qiov,
-                         int64_t offset, int flags, int *total)
+                         int64_t offset, int *total)
 {
     int async_ret = NOT_DONE;
 
-    blk_aio_pwritev(blk, offset, qiov, flags, aio_rw_done, &async_ret);
+    blk_aio_writev(blk, offset >> 9, qiov, qiov->size >> 9,
+                   aio_rw_done, &async_ret);
     while (async_ret == NOT_DONE) {
         main_loop_wait(false);
     }
@@ -574,6 +614,49 @@ static int do_aio_writev(BlockBackend *blk, QEMUIOVector *qiov,
     return async_ret < 0 ? async_ret : 1;
 }
 
+struct multiwrite_async_ret {
+    int num_done;
+    int error;
+};
+
+static void multiwrite_cb(void *opaque, int ret)
+{
+    struct multiwrite_async_ret *async_ret = opaque;
+
+    async_ret->num_done++;
+    if (ret < 0) {
+        async_ret->error = ret;
+    }
+}
+
+static int do_aio_multiwrite(BlockBackend *blk, BlockRequest* reqs,
+                             int num_reqs, int *total)
+{
+    int i, ret;
+    struct multiwrite_async_ret async_ret = {
+        .num_done = 0,
+        .error = 0,
+    };
+
+    *total = 0;
+    for (i = 0; i < num_reqs; i++) {
+        reqs[i].cb = multiwrite_cb;
+        reqs[i].opaque = &async_ret;
+        *total += reqs[i].qiov->size;
+    }
+
+    ret = blk_aio_multiwrite(blk, reqs, num_reqs);
+    if (ret < 0) {
+        return ret;
+    }
+
+    while (async_ret.num_done < num_reqs) {
+        main_loop_wait(false);
+    }
+
+    return async_ret.error < 0 ? async_ret.error : 1;
+}
+
 static void read_help(void)
 {
     printf(
@@ -588,7 +671,7 @@ static void read_help(void)
 " -b, -- read from the VM state rather than the virtual disk\n"
 " -C, -- report statistics in a machine parsable format\n"
 " -l, -- length for pattern verification (only with -P)\n"
-" -p, -- ignored for backwards compatibility\n"
+" -p, -- use blk_pread to read the file\n"
 " -P, -- use a pattern to verify read data\n"
 " -q, -- quiet mode, do not show I/O statistics\n"
 " -s, -- start offset for pattern verification (only with -P)\n"
@@ -604,7 +687,7 @@ static const cmdinfo_t read_cmd = {
     .cfunc      = read_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-abCqv] [-P pattern [-s off] [-l len]] off len",
+    .args       = "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
     .oneline    = "reads a number of bytes at a specified offset",
     .help       = read_help,
 };
@@ -612,8 +695,8 @@ static const cmdinfo_t read_cmd = {
 static int read_f(BlockBackend *blk, int argc, char **argv)
 {
     struct timeval t1, t2;
-    bool Cflag = false, qflag = false, vflag = false;
-    bool Pflag = false, sflag = false, lflag = false, bflag = false;
+    int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
+    int Pflag = 0, sflag = 0, lflag = 0, bflag = 0;
     int c, cnt;
     char *buf;
     int64_t offset;
@@ -626,13 +709,13 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
     while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != -1) {
         switch (c) {
         case 'b':
-            bflag = true;
+            bflag = 1;
             break;
         case 'C':
-            Cflag = true;
+            Cflag = 1;
             break;
         case 'l':
-            lflag = true;
+            lflag = 1;
             pattern_count = cvtnum(optarg);
             if (pattern_count < 0) {
                 print_cvtnum_err(pattern_count, optarg);
@@ -640,20 +723,20 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
             }
             break;
         case 'p':
-            /* Ignored for backwards compatibility */
+            pflag = 1;
             break;
         case 'P':
-            Pflag = true;
+            Pflag = 1;
             pattern = parse_pattern(optarg);
             if (pattern < 0) {
                 return 0;
             }
             break;
         case 'q':
-            qflag = true;
+            qflag = 1;
             break;
         case 's':
-            sflag = true;
+            sflag = 1;
             pattern_offset = cvtnum(optarg);
             if (pattern_offset < 0) {
                 print_cvtnum_err(pattern_offset, optarg);
@@ -661,7 +744,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
             }
             break;
         case 'v':
-            vflag = true;
+            vflag = 1;
             break;
         default:
             return qemuio_command_usage(&read_cmd);
@@ -672,6 +755,11 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
         return qemuio_command_usage(&read_cmd);
     }
 
+    if (bflag && pflag) {
+        printf("-b and -p cannot be specified at the same time\n");
+        return 0;
+    }
+
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
         print_cvtnum_err(offset, argv[optind]);
@@ -702,7 +790,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
         return 0;
     }
 
-    if (bflag) {
+    if (!pflag) {
         if (offset & 0x1ff) {
             printf("offset %" PRId64 " is not sector aligned\n",
                    offset);
@@ -718,10 +806,12 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
     buf = qemu_io_alloc(blk, count, 0xab);
 
     gettimeofday(&t1, NULL);
-    if (bflag) {
+    if (pflag) {
+        cnt = do_pread(blk, buf, offset, count, &total);
+    } else if (bflag) {
         cnt = do_load_vmstate(blk, buf, offset, count, &total);
     } else {
-        cnt = do_pread(blk, buf, offset, count, &total);
+        cnt = do_read(blk, buf, offset, count, &total);
     }
     gettimeofday(&t2, NULL);
 
@@ -785,7 +875,7 @@ static const cmdinfo_t readv_cmd = {
     .cfunc      = readv_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-Cqv] [-P pattern] off len [len..]",
+    .args       = "[-Cqv] [-P pattern ] off len [len..]",
     .oneline    = "reads a number of bytes at a specified offset",
     .help       = readv_help,
 };
@@ -793,7 +883,7 @@ static const cmdinfo_t readv_cmd = {
 static int readv_f(BlockBackend *blk, int argc, char **argv)
 {
     struct timeval t1, t2;
-    bool Cflag = false, qflag = false, vflag = false;
+    int Cflag = 0, qflag = 0, vflag = 0;
     int c, cnt;
     char *buf;
     int64_t offset;
@@ -802,25 +892,25 @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
     int nr_iov;
     QEMUIOVector qiov;
     int pattern = 0;
-    bool Pflag = false;
+    int Pflag = 0;
 
     while ((c = getopt(argc, argv, "CP:qv")) != -1) {
         switch (c) {
         case 'C':
-            Cflag = true;
+            Cflag = 1;
             break;
         case 'P':
-            Pflag = true;
+            Pflag = 1;
             pattern = parse_pattern(optarg);
             if (pattern < 0) {
                 return 0;
             }
             break;
         case 'q':
-            qflag = true;
+            qflag = 1;
             break;
         case 'v':
-            vflag = true;
+            vflag = 1;
             break;
         default:
             return qemuio_command_usage(&readv_cmd);
@@ -839,6 +929,12 @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
     }
     optind++;
 
+    if (offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               offset);
+        return 0;
+    }
+
     nr_iov = argc - optind;
     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, 0xab);
     if (buf == NULL) {
@@ -895,13 +991,11 @@ static void write_help(void)
 " filled with a set pattern (0xcdcdcdcd).\n"
 " -b, -- write to the VM state rather than the virtual disk\n"
 " -c, -- write compressed data with blk_write_compressed\n"
-" -f, -- use Force Unit Access semantics\n"
-" -p, -- ignored for backwards compatibility\n"
+" -p, -- use blk_pwrite to write the file\n"
 " -P, -- use different pattern to fill file\n"
 " -C, -- report statistics in a machine parsable format\n"
 " -q, -- quiet mode, do not show I/O statistics\n"
-" -u, -- with -z, allow unmapping\n"
-" -z, -- write zeroes using blk_co_pwrite_zeroes\n"
+" -z, -- write zeroes using blk_co_write_zeroes\n"
 "\n");
 }
 
@@ -913,7 +1007,7 @@ static const cmdinfo_t write_cmd = {
     .cfunc      = write_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-bcCfquz] [-P pattern] off len",
+    .args       = "[-bcCpqz] [-P pattern ] off len",
     .oneline    = "writes a number of bytes at a specified offset",
     .help       = write_help,
 };
@@ -921,9 +1015,8 @@ static const cmdinfo_t write_cmd = {
 static int write_f(BlockBackend *blk, int argc, char **argv)
 {
     struct timeval t1, t2;
-    bool Cflag = false, qflag = false, bflag = false;
-    bool Pflag = false, zflag = false, cflag = false;
-    int flags = 0;
+    int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0;
+    int cflag = 0;
     int c, cnt;
     char *buf = NULL;
     int64_t offset;
@@ -932,38 +1025,32 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
     int64_t total = 0;
     int pattern = 0xcd;
 
-    while ((c = getopt(argc, argv, "bcCfpP:quz")) != -1) {
+    while ((c = getopt(argc, argv, "bcCpP:qz")) != -1) {
         switch (c) {
         case 'b':
-            bflag = true;
+            bflag = 1;
             break;
         case 'c':
-            cflag = true;
+            cflag = 1;
             break;
         case 'C':
-            Cflag = true;
-            break;
-        case 'f':
-            flags |= BDRV_REQ_FUA;
+            Cflag = 1;
             break;
         case 'p':
-            /* Ignored for backwards compatibility */
+            pflag = 1;
             break;
         case 'P':
-            Pflag = true;
+            Pflag = 1;
             pattern = parse_pattern(optarg);
             if (pattern < 0) {
                 return 0;
             }
             break;
         case 'q':
-            qflag = true;
-            break;
-        case 'u':
-            flags |= BDRV_REQ_MAY_UNMAP;
+            qflag = 1;
             break;
         case 'z':
-            zflag = true;
+            zflag = 1;
             break;
         default:
             return qemuio_command_usage(&write_cmd);
@@ -974,18 +1061,8 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
         return qemuio_command_usage(&write_cmd);
     }
 
-    if (bflag && zflag) {
-        printf("-b and -z cannot be specified at the same time\n");
-        return 0;
-    }
-
-    if ((flags & BDRV_REQ_FUA) && (bflag || cflag)) {
-        printf("-f and -b or -c cannot be specified at the same time\n");
-        return 0;
-    }
-
-    if ((flags & BDRV_REQ_MAY_UNMAP) && !zflag) {
-        printf("-u requires -z to be specified\n");
+    if (bflag + pflag + zflag > 1) {
+        printf("-b, -p, or -z cannot be specified at the same time\n");
         return 0;
     }
 
@@ -1011,7 +1088,7 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
         return 0;
     }
 
-    if (bflag || cflag) {
+    if (!pflag) {
         if (offset & 0x1ff) {
             printf("offset %" PRId64 " is not sector aligned\n",
                    offset);
@@ -1030,14 +1107,16 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
     }
 
     gettimeofday(&t1, NULL);
-    if (bflag) {
+    if (pflag) {
+        cnt = do_pwrite(blk, buf, offset, count, &total);
+    } else if (bflag) {
         cnt = do_save_vmstate(blk, buf, offset, count, &total);
     } else if (zflag) {
-        cnt = do_co_pwrite_zeroes(blk, offset, count, flags, &total);
+        cnt = do_co_write_zeroes(blk, offset, count, &total);
     } else if (cflag) {
         cnt = do_write_compressed(blk, buf, offset, count, &total);
     } else {
-        cnt = do_pwrite(blk, buf, offset, count, flags, &total);
+        cnt = do_write(blk, buf, offset, count, &total);
     }
     gettimeofday(&t2, NULL);
 
@@ -1076,7 +1155,6 @@ writev_help(void)
 " filled with a set pattern (0xcdcdcdcd).\n"
 " -P, -- use different pattern to fill file\n"
 " -C, -- report statistics in a machine parsable format\n"
-" -f, -- use Force Unit Access semantics\n"
 " -q, -- quiet mode, do not show I/O statistics\n"
 "\n");
 }
@@ -1088,7 +1166,7 @@ static const cmdinfo_t writev_cmd = {
     .cfunc      = writev_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-Cfq] [-P pattern] off len [len..]",
+    .args       = "[-Cq] [-P pattern ] off len [len..]",
     .oneline    = "writes a number of bytes at a specified offset",
     .help       = writev_help,
 };
@@ -1096,8 +1174,7 @@ static const cmdinfo_t writev_cmd = {
 static int writev_f(BlockBackend *blk, int argc, char **argv)
 {
     struct timeval t1, t2;
-    bool Cflag = false, qflag = false;
-    int flags = 0;
+    int Cflag = 0, qflag = 0;
     int c, cnt;
     char *buf;
     int64_t offset;
@@ -1107,16 +1184,13 @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
     int pattern = 0xcd;
     QEMUIOVector qiov;
 
-    while ((c = getopt(argc, argv, "CfqP:")) != -1) {
+    while ((c = getopt(argc, argv, "CqP:")) != -1) {
         switch (c) {
         case 'C':
-            Cflag = true;
-            break;
-        case 'f':
-            flags |= BDRV_REQ_FUA;
+            Cflag = 1;
             break;
         case 'q':
-            qflag = true;
+            qflag = 1;
             break;
         case 'P':
             pattern = parse_pattern(optarg);
@@ -1140,6 +1214,12 @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
     }
     optind++;
 
+    if (offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               offset);
+        return 0;
+    }
+
     nr_iov = argc - optind;
     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern);
     if (buf == NULL) {
@@ -1147,7 +1227,7 @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
     }
 
     gettimeofday(&t1, NULL);
-    cnt = do_aio_writev(blk, &qiov, offset, flags, &total);
+    cnt = do_aio_writev(blk, &qiov, offset, &total);
     gettimeofday(&t2, NULL);
 
     if (cnt < 0) {
@@ -1168,16 +1248,175 @@ out:
     return 0;
 }
 
+static void multiwrite_help(void)
+{
+    printf(
+"\n"
+" writes a range of bytes from the given offset source from multiple buffers,\n"
+" in a batch of requests that may be merged by qemu\n"
+"\n"
+" Example:\n"
+" 'multiwrite 512 1k 1k ; 4k 1k'\n"
+"  writes 2 kB at 512 bytes and 1 kB at 4 kB into the open file\n"
+"\n"
+" Writes into a segment of the currently open file, using a buffer\n"
+" filled with a set pattern (0xcdcdcdcd). The pattern byte is increased\n"
+" by one for each request contained in the multiwrite command.\n"
+" -P, -- use different pattern to fill file\n"
+" -C, -- report statistics in a machine parsable format\n"
+" -q, -- quiet mode, do not show I/O statistics\n"
+"\n");
+}
+
+static int multiwrite_f(BlockBackend *blk, int argc, char **argv);
+
+static const cmdinfo_t multiwrite_cmd = {
+    .name       = "multiwrite",
+    .cfunc      = multiwrite_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]",
+    .oneline    = "issues multiple write requests at once",
+    .help       = multiwrite_help,
+};
+
+static int multiwrite_f(BlockBackend *blk, int argc, char **argv)
+{
+    struct timeval t1, t2;
+    int Cflag = 0, qflag = 0;
+    int c, cnt;
+    char **buf;
+    int64_t offset, first_offset = 0;
+    /* Some compilers get confused and warn if this is not initialized.  */
+    int total = 0;
+    int nr_iov;
+    int nr_reqs;
+    int pattern = 0xcd;
+    QEMUIOVector *qiovs;
+    int i;
+    BlockRequest *reqs;
+
+    while ((c = getopt(argc, argv, "CqP:")) != -1) {
+        switch (c) {
+        case 'C':
+            Cflag = 1;
+            break;
+        case 'q':
+            qflag = 1;
+            break;
+        case 'P':
+            pattern = parse_pattern(optarg);
+            if (pattern < 0) {
+                return 0;
+            }
+            break;
+        default:
+            return qemuio_command_usage(&writev_cmd);
+        }
+    }
+
+    if (optind > argc - 2) {
+        return qemuio_command_usage(&writev_cmd);
+    }
+
+    nr_reqs = 1;
+    for (i = optind; i < argc; i++) {
+        if (!strcmp(argv[i], ";")) {
+            nr_reqs++;
+        }
+    }
+
+    reqs = g_new0(BlockRequest, nr_reqs);
+    buf = g_new0(char *, nr_reqs);
+    qiovs = g_new(QEMUIOVector, nr_reqs);
+
+    for (i = 0; i < nr_reqs && optind < argc; i++) {
+        int j;
+
+        /* Read the offset of the request */
+        offset = cvtnum(argv[optind]);
+        if (offset < 0) {
+            print_cvtnum_err(offset, argv[optind]);
+            goto out;
+        }
+        optind++;
+
+        if (offset & 0x1ff) {
+            printf("offset %lld is not sector aligned\n",
+                   (long long)offset);
+            goto out;
+        }
+
+        if (i == 0) {
+            first_offset = offset;
+        }
+
+        /* Read lengths for qiov entries */
+        for (j = optind; j < argc; j++) {
+            if (!strcmp(argv[j], ";")) {
+                break;
+            }
+        }
+
+        nr_iov = j - optind;
+
+        /* Build request */
+        buf[i] = create_iovec(blk, &qiovs[i], &argv[optind], nr_iov, pattern);
+        if (buf[i] == NULL) {
+            goto out;
+        }
+
+        reqs[i].qiov = &qiovs[i];
+        reqs[i].sector = offset >> 9;
+        reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
+
+        optind = j + 1;
+
+        pattern++;
+    }
+
+    /* If there were empty requests at the end, ignore them */
+    nr_reqs = i;
+
+    gettimeofday(&t1, NULL);
+    cnt = do_aio_multiwrite(blk, reqs, nr_reqs, &total);
+    gettimeofday(&t2, NULL);
+
+    if (cnt < 0) {
+        printf("aio_multiwrite failed: %s\n", strerror(-cnt));
+        goto out;
+    }
+
+    if (qflag) {
+        goto out;
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, t1);
+    print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);
+out:
+    for (i = 0; i < nr_reqs; i++) {
+        qemu_io_free(buf[i]);
+        if (reqs[i].qiov != NULL) {
+            qemu_iovec_destroy(&qiovs[i]);
+        }
+    }
+    g_free(buf);
+    g_free(reqs);
+    g_free(qiovs);
+    return 0;
+}
+
 struct aio_ctx {
     BlockBackend *blk;
     QEMUIOVector qiov;
     int64_t offset;
     char *buf;
-    bool qflag;
-    bool vflag;
-    bool Cflag;
-    bool Pflag;
-    bool zflag;
+    int qflag;
+    int vflag;
+    int Cflag;
+    int Pflag;
+    int zflag;
     BlockAcctCookie acct;
     int pattern;
     struct timeval t1;
@@ -1274,7 +1513,6 @@ static void aio_read_help(void)
 " used to ensure all outstanding aio requests have been completed.\n"
 " -C, -- report statistics in a machine parsable format\n"
 " -P, -- use a pattern to verify read data\n"
-" -i, -- treat request as invalid, for exercising stats\n"
 " -v, -- dump buffer to standard output\n"
 " -q, -- quiet mode, do not show I/O statistics\n"
 "\n");
@@ -1287,7 +1525,7 @@ static const cmdinfo_t aio_read_cmd = {
     .cfunc      = aio_read_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-Ciqv] [-P pattern] off len [len..]",
+    .args       = "[-Cqv] [-P pattern ] off len [len..]",
     .oneline    = "asynchronously reads a number of bytes",
     .help       = aio_read_help,
 };
@@ -1298,29 +1536,24 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv)
     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
 
     ctx->blk = blk;
-    while ((c = getopt(argc, argv, "CP:iqv")) != -1) {
+    while ((c = getopt(argc, argv, "CP:qv")) != -1) {
         switch (c) {
         case 'C':
-            ctx->Cflag = true;
+            ctx->Cflag = 1;
             break;
         case 'P':
-            ctx->Pflag = true;
+            ctx->Pflag = 1;
             ctx->pattern = parse_pattern(optarg);
             if (ctx->pattern < 0) {
                 g_free(ctx);
                 return 0;
             }
             break;
-        case 'i':
-            printf("injecting invalid read request\n");
-            block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
-            g_free(ctx);
-            return 0;
         case 'q':
-            ctx->qflag = true;
+            ctx->qflag = 1;
             break;
         case 'v':
-            ctx->vflag = true;
+            ctx->vflag = 1;
             break;
         default:
             g_free(ctx);
@@ -1341,6 +1574,14 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv)
     }
     optind++;
 
+    if (ctx->offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               ctx->offset);
+        block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
+        g_free(ctx);
+        return 0;
+    }
+
     nr_iov = argc - optind;
     ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, 0xab);
     if (ctx->buf == NULL) {
@@ -1352,7 +1593,8 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv)
     gettimeofday(&ctx->t1, NULL);
     block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
                      BLOCK_ACCT_READ);
-    blk_aio_preadv(blk, ctx->offset, &ctx->qiov, 0, aio_read_done, ctx);
+    blk_aio_readv(blk, ctx->offset >> 9, &ctx->qiov,
+                  ctx->qiov.size >> 9, aio_read_done, ctx);
     return 0;
 }
 
@@ -1372,11 +1614,8 @@ static void aio_write_help(void)
 " used to ensure all outstanding aio requests have been completed.\n"
 " -P, -- use different pattern to fill file\n"
 " -C, -- report statistics in a machine parsable format\n"
-" -f, -- use Force Unit Access semantics\n"
-" -i, -- treat request as invalid, for exercising stats\n"
 " -q, -- quiet mode, do not show I/O statistics\n"
-" -u, -- with -z, allow unmapping\n"
-" -z, -- write zeroes using blk_aio_pwrite_zeroes\n"
+" -z, -- write zeroes using blk_aio_write_zeroes\n"
 "\n");
 }
 
@@ -1387,7 +1626,7 @@ static const cmdinfo_t aio_write_cmd = {
     .cfunc      = aio_write_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-Cfiquz] [-P pattern] off len [len..]",
+    .args       = "[-Cqz] [-P pattern ] off len [len..]",
     .oneline    = "asynchronously writes a number of bytes",
     .help       = aio_write_help,
 };
@@ -1397,22 +1636,15 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
     int nr_iov, c;
     int pattern = 0xcd;
     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
-    int flags = 0;
 
     ctx->blk = blk;
-    while ((c = getopt(argc, argv, "CfiqP:uz")) != -1) {
+    while ((c = getopt(argc, argv, "CqP:z")) != -1) {
         switch (c) {
         case 'C':
-            ctx->Cflag = true;
-            break;
-        case 'f':
-            flags |= BDRV_REQ_FUA;
+            ctx->Cflag = 1;
             break;
         case 'q':
-            ctx->qflag = true;
-            break;
-        case 'u':
-            flags |= BDRV_REQ_MAY_UNMAP;
+            ctx->qflag = 1;
             break;
         case 'P':
             pattern = parse_pattern(optarg);
@@ -1421,13 +1653,8 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
                 return 0;
             }
             break;
-        case 'i':
-            printf("injecting invalid write request\n");
-            block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
-            g_free(ctx);
-            return 0;
         case 'z':
-            ctx->zflag = true;
+            ctx->zflag = 1;
             break;
         default:
             g_free(ctx);
@@ -1446,12 +1673,6 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
         return 0;
     }
 
-    if ((flags & BDRV_REQ_MAY_UNMAP) && !ctx->zflag) {
-        printf("-u requires -z to be specified\n");
-        g_free(ctx);
-        return 0;
-    }
-
     if (ctx->zflag && ctx->Pflag) {
         printf("-z and -P cannot be specified at the same time\n");
         g_free(ctx);
@@ -1466,17 +1687,24 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
     }
     optind++;
 
+    if (ctx->offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               ctx->offset);
+        block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
+        g_free(ctx);
+        return 0;
+    }
+
     if (ctx->zflag) {
         int64_t count = cvtnum(argv[optind]);
         if (count < 0) {
             print_cvtnum_err(count, argv[optind]);
-            g_free(ctx);
             return 0;
         }
 
         ctx->qiov.size = count;
-        blk_aio_pwrite_zeroes(blk, ctx->offset, count, flags, aio_write_done,
-                              ctx);
+        blk_aio_write_zeroes(blk, ctx->offset >> 9, count >> 9, 0,
+                             aio_write_done, ctx);
     } else {
         nr_iov = argc - optind;
         ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov,
@@ -1491,8 +1719,8 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
         block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
                          BLOCK_ACCT_WRITE);
 
-        blk_aio_pwritev(blk, ctx->offset, &ctx->qiov, flags, aio_write_done,
-                        ctx);
+        blk_aio_writev(blk, ctx->offset >> 9, &ctx->qiov,
+                       ctx->qiov.size >> 9, aio_write_done, ctx);
     }
     return 0;
 }
@@ -1656,17 +1884,17 @@ static const cmdinfo_t discard_cmd = {
 static int discard_f(BlockBackend *blk, int argc, char **argv)
 {
     struct timeval t1, t2;
-    bool Cflag = false, qflag = false;
+    int Cflag = 0, qflag = 0;
     int c, ret;
     int64_t offset, count;
 
     while ((c = getopt(argc, argv, "Cq")) != -1) {
         switch (c) {
         case 'C':
-            Cflag = true;
+            Cflag = 1;
             break;
         case 'q':
-            qflag = true;
+            qflag = 1;
             break;
         default:
             return qemuio_command_usage(&discard_cmd);
@@ -1688,15 +1916,16 @@ static int discard_f(BlockBackend *blk, int argc, char **argv)
     if (count < 0) {
         print_cvtnum_err(count, argv[optind]);
         return 0;
-    } else if (count >> BDRV_SECTOR_BITS > BDRV_REQUEST_MAX_SECTORS) {
+    } else if (count >> BDRV_SECTOR_BITS > INT_MAX) {
         printf("length cannot exceed %"PRIu64", given %s\n",
-               (uint64_t)BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS,
+               (uint64_t)INT_MAX << BDRV_SECTOR_BITS,
                argv[optind]);
         return 0;
     }
 
     gettimeofday(&t1, NULL);
-    ret = blk_pdiscard(blk, offset, count);
+    ret = blk_discard(blk, offset >> BDRV_SECTOR_BITS,
+                      count >> BDRV_SECTOR_BITS);
     gettimeofday(&t2, NULL);
 
     if (ret < 0) {
@@ -2246,6 +2475,7 @@ static void __attribute((constructor)) init_qemuio_commands(void)
     qemuio_add_command(&readv_cmd);
     qemuio_add_command(&write_cmd);
     qemuio_add_command(&writev_cmd);
+    qemuio_add_command(&multiwrite_cmd);
     qemuio_add_command(&aio_read_cmd);
     qemuio_add_command(&aio_write_cmd);
     qemuio_add_command(&aio_flush_cmd);
index db129ea..0598251 100644 (file)
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -18,7 +18,6 @@
 #include "qemu/option.h"
 #include "qemu/config-file.h"
 #include "qemu/readline.h"
-#include "qemu/log.h"
 #include "qapi/qmp/qstring.h"
 #include "qom/object_interfaces.h"
 #include "sysemu/block-backend.h"
@@ -102,15 +101,12 @@ static void open_help(void)
 " opens a new file in the requested mode\n"
 "\n"
 " Example:\n"
-" 'open -n -o driver=raw /tmp/data' - opens raw data file read-write, uncached\n"
+" 'open -Cn /tmp/data' - creates/opens data file read-write and uncached\n"
 "\n"
 " Opens a file for subsequent use by all of the other qemu-io commands.\n"
 " -r, -- open file read-only\n"
 " -s, -- use snapshot file\n"
-" -n, -- disable host cache, short for -t none\n"
-" -k, -- use kernel AIO implementation (on Linux only)\n"
-" -t, -- use the given cache mode for the image\n"
-" -d, -- use the given discard mode for the image\n"
+" -n, -- disable host cache\n"
 " -o, -- options to be given to the block driver"
 "\n");
 }
@@ -124,7 +120,7 @@ static const cmdinfo_t open_cmd = {
     .argmin     = 1,
     .argmax     = -1,
     .flags      = CMD_NOFILE_OK,
-    .args       = "[-rsnk] [-t cache] [-d discard] [-o options] [path]",
+    .args       = "[-Crsn] [-o options] [path]",
     .oneline    = "open the file specified by path",
     .help       = open_help,
 };
@@ -141,14 +137,14 @@ static QemuOptsList empty_opts = {
 
 static int open_f(BlockBackend *blk, int argc, char **argv)
 {
-    int flags = BDRV_O_UNMAP;
+    int flags = 0;
     int readonly = 0;
     bool writethrough = true;
     int c;
     QemuOpts *qopts;
     QDict *opts;
 
-    while ((c = getopt(argc, argv, "snro:kt:d:")) != -1) {
+    while ((c = getopt(argc, argv, "snrgo:")) != -1) {
         switch (c) {
         case 's':
             flags |= BDRV_O_SNAPSHOT;
@@ -160,27 +156,9 @@ static int open_f(BlockBackend *blk, int argc, char **argv)
         case 'r':
             readonly = 1;
             break;
-        case 'k':
-            flags |= BDRV_O_NATIVE_AIO;
-            break;
-        case 't':
-            if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) {
-                error_report("Invalid cache option: %s", optarg);
-                qemu_opts_reset(&empty_opts);
-                return 0;
-            }
-            break;
-        case 'd':
-            if (bdrv_parse_discard_flags(optarg, &flags) < 0) {
-                error_report("Invalid discard option: %s", optarg);
-                qemu_opts_reset(&empty_opts);
-                return 0;
-            }
-            break;
         case 'o':
             if (imageOpts) {
                 printf("--image-opts and 'open -o' are mutually exclusive\n");
-                qemu_opts_reset(&empty_opts);
                 return 0;
             }
             if (!qemu_opts_parse_noisily(&empty_opts, optarg, false)) {
@@ -238,25 +216,21 @@ static const cmdinfo_t quit_cmd = {
 static void usage(const char *name)
 {
     printf(
-"Usage: %s [OPTIONS]... [-c STRING]... [file]\n"
+"Usage: %s [-h] [-V] [-rsnm] [-f FMT] [-c STRING] ... [file]\n"
 "QEMU Disk exerciser\n"
 "\n"
 "  --object OBJECTDEF   define an object such as 'secret' for\n"
 "                       passwords and/or encryption keys\n"
-"  --image-opts         treat file as option string\n"
 "  -c, --cmd STRING     execute command with its arguments\n"
 "                       from the given string\n"
 "  -f, --format FMT     specifies the block driver to use\n"
 "  -r, --read-only      export read-only\n"
 "  -s, --snapshot       use snapshot file\n"
-"  -n, --nocache        disable host cache, short for -t none\n"
+"  -n, --nocache        disable host cache\n"
 "  -m, --misalign       misalign allocations for O_DIRECT\n"
 "  -k, --native-aio     use kernel AIO implementation (on Linux only)\n"
 "  -t, --cache=MODE     use the given cache mode for the image\n"
-"  -d, --discard=MODE   use the given discard mode for the image\n"
-"  -T, --trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
-"                       specify tracing options\n"
-"                       see qemu-img(1) man page for full description\n"
+"  -T, --trace FILE     enable trace events listed in the given file\n"
 "  -h, --help           display this help and exit\n"
 "  -V, --version        output version information and exit\n"
 "\n"
@@ -436,10 +410,11 @@ static QemuOptsList file_opts = {
 int main(int argc, char **argv)
 {
     int readonly = 0;
-    const char *sopt = "hVc:d:f:rsnmkt:T:";
+    const char *sopt = "hVc:d:f:rsnmgkt:T:";
     const struct option lopt[] = {
         { "help", no_argument, NULL, 'h' },
         { "version", no_argument, NULL, 'V' },
+        { "offset", required_argument, NULL, 'o' },
         { "cmd", required_argument, NULL, 'c' },
         { "format", required_argument, NULL, 'f' },
         { "read-only", no_argument, NULL, 'r' },
@@ -461,7 +436,6 @@ int main(int argc, char **argv)
     Error *local_error = NULL;
     QDict *opts = NULL;
     const char *format = NULL;
-    char *trace_file = NULL;
 
 #ifdef CONFIG_POSIX
     signal(SIGPIPE, SIG_IGN);
@@ -470,11 +444,13 @@ int main(int argc, char **argv)
     progname = basename(argv[0]);
     qemu_init_exec_dir(argv[0]);
 
-    qcrypto_init(&error_fatal);
+    if (qcrypto_init(&local_error) < 0) {
+        error_reportf_err(local_error, "cannot initialize crypto: ");
+        exit(1);
+    }
 
     module_call_init(MODULE_INIT_QOM);
     qemu_add_opts(&qemu_object_opts);
-    qemu_add_opts(&qemu_trace_opts);
     bdrv_init();
 
     while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
@@ -514,8 +490,9 @@ int main(int argc, char **argv)
             }
             break;
         case 'T':
-            g_free(trace_file);
-            trace_file = trace_opt_parse(optarg);
+            if (!trace_init_backends()) {
+                exit(1); /* error message will have been printed */
+            }
             break;
         case 'V':
             printf("%s version %s\n", progname, QEMU_VERSION);
@@ -561,12 +538,6 @@ int main(int argc, char **argv)
         exit(1);
     }
 
-    if (!trace_init_backends()) {
-        exit(1);
-    }
-    trace_init_file(trace_file);
-    qemu_set_log(LOG_TRACE);
-
     /* initialize commands */
     qemuio_add_command(&quit_cmd);
     qemuio_add_command(&open_cmd);
index e3571c2..6dea6d6 100644 (file)
 #include "qemu/main-loop.h"
 #include "qemu/error-report.h"
 #include "qemu/config-file.h"
-#include "qemu/bswap.h"
-#include "qemu/log.h"
 #include "block/snapshot.h"
 #include "qapi/util.h"
 #include "qapi/qmp/qstring.h"
 #include "qom/object_interfaces.h"
 #include "io/channel-socket.h"
 #include "crypto/init.h"
-#include "trace/control.h"
 
 #include <getopt.h>
 #include <libgen.h>
@@ -49,8 +46,6 @@
 #define QEMU_NBD_OPT_TLSCREDS      261
 #define QEMU_NBD_OPT_IMAGE_OPTS    262
 
-#define MBR_SIZE 512
-
 static NBDExport *exp;
 static bool newproto;
 static int verbose;
@@ -90,8 +85,6 @@ static void usage(const char *name)
 "General purpose options:\n"
 "  --object type,id=ID,...   define an object such as 'secret' for providing\n"
 "                            passwords and/or encryption keys\n"
-"  -T, --trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
-"                            specify tracing options\n"
 #ifdef __linux__
 "Kernel NBD client support:\n"
 "  -c, --connect=DEV         connect FILE to the local NBD device DEV\n"
@@ -166,13 +159,12 @@ static int find_partition(BlockBackend *blk, int partition,
                           off_t *offset, off_t *size)
 {
     struct partition_record mbr[4];
-    uint8_t data[MBR_SIZE];
+    uint8_t data[512];
     int i;
     int ext_partnum = 4;
     int ret;
 
-    ret = blk_pread(blk, 0, data, sizeof(data));
-    if (ret < 0) {
+    if ((ret = blk_read(blk, 0, data, 1)) < 0) {
         error_report("error while reading: %s", strerror(-ret));
         exit(EXIT_FAILURE);
     }
@@ -190,12 +182,10 @@ static int find_partition(BlockBackend *blk, int partition,
 
         if (mbr[i].system == 0xF || mbr[i].system == 0x5) {
             struct partition_record ext[4];
-            uint8_t data1[MBR_SIZE];
+            uint8_t data1[512];
             int j;
 
-            ret = blk_pread(blk, mbr[i].start_sector_abs * MBR_SIZE,
-                            data1, sizeof(data1));
-            if (ret < 0) {
+            if ((ret = blk_read(blk, mbr[i].start_sector_abs, data1, 1)) < 0) {
                 error_report("error while reading: %s", strerror(-ret));
                 exit(EXIT_FAILURE);
             }
@@ -474,7 +464,7 @@ int main(int argc, char **argv)
     off_t fd_size;
     QemuOpts *sn_opts = NULL;
     const char *sn_id_or_name = NULL;
-    const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:tl:x:T:";
+    const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:tl:x:";
     struct option lopt[] = {
         { "help", no_argument, NULL, 'h' },
         { "version", no_argument, NULL, 'V' },
@@ -502,7 +492,6 @@ int main(int argc, char **argv)
         { "export-name", required_argument, NULL, 'x' },
         { "tls-creds", required_argument, NULL, QEMU_NBD_OPT_TLSCREDS },
         { "image-opts", no_argument, NULL, QEMU_NBD_OPT_IMAGE_OPTS },
-        { "trace", required_argument, NULL, 'T' },
         { NULL, 0, NULL, 0 }
     };
     int ch;
@@ -523,7 +512,6 @@ int main(int argc, char **argv)
     const char *tlscredsid = NULL;
     bool imageOpts = false;
     bool writethrough = true;
-    char *trace_file = NULL;
 
     /* The client thread uses SIGTERM to interrupt the server.  A signal
      * handler ensures that "qemu-nbd -v -c" exits with a nice status code.
@@ -533,11 +521,13 @@ int main(int argc, char **argv)
     sa_sigterm.sa_handler = termsig_handler;
     sigaction(SIGTERM, &sa_sigterm, NULL);
 
-    qcrypto_init(&error_fatal);
+    if (qcrypto_init(&local_err) < 0) {
+        error_reportf_err(local_err, "cannot initialize crypto: ");
+        exit(1);
+    }
 
     module_call_init(MODULE_INIT_QOM);
     qemu_add_opts(&qemu_object_opts);
-    qemu_add_opts(&qemu_trace_opts);
     qemu_init_exec_dir(argv[0]);
 
     while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
@@ -710,10 +700,6 @@ int main(int argc, char **argv)
         case QEMU_NBD_OPT_IMAGE_OPTS:
             imageOpts = true;
             break;
-        case 'T':
-            g_free(trace_file);
-            trace_file = trace_opt_parse(optarg);
-            break;
         }
     }
 
@@ -729,12 +715,6 @@ int main(int argc, char **argv)
         exit(EXIT_FAILURE);
     }
 
-    if (!trace_init_backends()) {
-        exit(1);
-    }
-    trace_init_file(trace_file);
-    qemu_set_log(LOG_TRACE);
-
     if (tlscredsid) {
         if (sockpath) {
             error_report("TLS is only supported with IPv4/IPv6");
index 91ebf04..9f23343 100644 (file)
@@ -92,9 +92,6 @@ Display extra debugging information
 Display this help and exit
 @item -V, --version
 Display version information and exit
-@item -T, --trace [[enable=]@var{pattern}][,events=@var{file}][,file=@var{file}]
-@findex --trace
-@include qemu-option-trace.texi
 @end table
 
 @c man end
diff --git a/qemu-option-trace.texi b/qemu-option-trace.texi
deleted file mode 100644 (file)
index 693ab5a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-Specify tracing options.
-
-@table @option
-@item [enable=]@var{pattern}
-Immediately enable events matching @var{pattern}.
-The file must contain one event name (as listed in the @file{trace-events-all}
-file) per line; globbing patterns are accepted too.  This option is only
-available if QEMU has been compiled with the @var{simple}, @var{stderr}
-or @var{ftrace} tracing backend.  To specify multiple events or patterns,
-specify the @option{-trace} option multiple times.
-
-Use @code{-trace help} to print a list of names of trace points.
-
-@item events=@var{file}
-Immediately enable events listed in @var{file}.
-The file must contain one event name (as listed in the @file{trace-events-all}
-file) per line; globbing patterns are accepted too.  This option is only
-available if QEMU has been compiled with the @var{simple}, @var{stderr} or
-@var{ftrace} tracing backend.
-
-@item file=@var{file}
-Log output traces to @var{file}.
-This option is only available if QEMU has been compiled with
-the @var{simple} tracing backend.
-@end table
index b4ee63c..89a009e 100644 (file)
@@ -25,8 +25,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef QEMU_OPTIONS_H
-#define QEMU_OPTIONS_H
+#ifndef _QEMU_OPTIONS_H_
+#define _QEMU_OPTIONS_H_
 
 enum {
 #define QEMU_OPTIONS_GENERATE_ENUM
index a71aaf8..6106520 100644 (file)
@@ -35,9 +35,10 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
     "                kernel_irqchip=on|off controls accelerated irqchip support\n"
     "                kernel_irqchip=on|off|split controls accelerated irqchip support (default=off)\n"
     "                vmport=on|off|auto controls emulation of vmport (default: auto)\n"
-    "                kvm_shadow_mem=size of KVM shadow MMU in bytes\n"
+    "                kvm_shadow_mem=size of KVM shadow MMU\n"
     "                dump-guest-core=on|off include guest memory in a core dump (default=on)\n"
     "                mem-merge=on|off controls memory merge support (default: on)\n"
+    "                iommu=on|off controls emulated Intel IOMMU (VT-d) support (default=off)\n"
     "                igd-passthru=on|off controls IGD GFX passthrough support (default=off)\n"
     "                aes-key-wrap=on|off controls support for AES key wrapping (default=on)\n"
     "                dea-key-wrap=on|off controls support for DEA key wrapping (default=on)\n"
@@ -72,6 +73,8 @@ Include guest memory in a core dump. The default is on.
 Enables or disables memory merge support. This feature, when supported by
 the host, de-duplicates identical memory pages among VMs instances
 (enabled by default).
+@item iommu=on|off
+Enables or disables emulated Intel IOMMU (VT-d) support. The default is off.
 @item aes-key-wrap=on|off
 Enables or disables AES key wrapping support on s390-ccw hosts. This feature
 controls whether AES wrapping keys will be created to allow
@@ -566,7 +569,7 @@ These options have the same definition as they have in @option{-hdachs}.
 @var{discard} is one of "ignore" (or "off") or "unmap" (or "on") and controls whether @dfn{discard} (also known as @dfn{trim} or @dfn{unmap}) requests are ignored or passed to the filesystem.  Some machine types may not support discard requests.
 @item format=@var{format}
 Specify which disk @var{format} will be used rather than detecting
-the format.  Can be used to specify format=raw to avoid interpreting
+the format.  Can be used to specifiy format=raw to avoid interpreting
 an untrusted format header.
 @item serial=@var{serial}
 This option specifies the serial number to assign to the device.
@@ -891,7 +894,7 @@ mouse. Also overrides the PS/2 mouse emulation when activated.
 
 @item disk:[format=@var{format}]:@var{file}
 Mass storage device based on file. The optional @var{format} argument
-will be used rather than detecting the format. Can be used to specify
+will be used rather than detecting the format. Can be used to specifiy
 @code{format=raw} to avoid interpreting an untrusted format header.
 
 @item host:@var{bus}.@var{addr}
@@ -927,25 +930,10 @@ ETEXI
 
 DEF("display", HAS_ARG, QEMU_OPTION_display,
     "-display sdl[,frame=on|off][,alt_grab=on|off][,ctrl_grab=on|off]\n"
-    "            [,window_close=on|off][,gl=on|off]|curses|none|\n"
-    "-display gtk[,grab_on_hover=on|off][,gl=on|off]|\n"
-    "-display vnc=<display>[,<optargs>]\n"
-    "-display curses\n"
-    "-display none"
-    "                select display type\n"
-    "The default display is equivalent to\n"
-#if defined(CONFIG_GTK)
-            "\t\"-display gtk\"\n"
-#elif defined(CONFIG_SDL)
-            "\t\"-display sdl\"\n"
-#elif defined(CONFIG_COCOA)
-            "\t\"-display cocoa\"\n"
-#elif defined(CONFIG_VNC)
-            "\t\"-vnc localhost:0,to=99,id=default\"\n"
-#else
-            "\t\"-display none\"\n"
-#endif
-    , QEMU_ARCH_ALL)
+    "            [,window_close=on|off]|curses|none|\n"
+    "            gtk[,grab_on_hover=on|off]|\n"
+    "            vnc=<display>[,<optargs>]\n"
+    "                select display type\n", QEMU_ARCH_ALL)
 STEXI
 @item -display @var{type}
 @findex -display
@@ -992,7 +980,7 @@ the console and monitor.
 ETEXI
 
 DEF("curses", 0, QEMU_OPTION_curses,
-    "-curses         shorthand for -display curses\n",
+    "-curses         use a curses/ncurses interface instead of SDL\n",
     QEMU_ARCH_ALL)
 STEXI
 @item -curses
@@ -1042,7 +1030,7 @@ Disable SDL window close capability.
 ETEXI
 
 DEF("sdl", 0, QEMU_OPTION_sdl,
-    "-sdl            shorthand for -display sdl\n", QEMU_ARCH_ALL)
+    "-sdl            enable SDL\n", QEMU_ARCH_ALL)
 STEXI
 @item -sdl
 @findex -sdl
@@ -1239,7 +1227,7 @@ Set the initial graphical resolution and depth (PPC, SPARC only).
 ETEXI
 
 DEF("vnc", HAS_ARG, QEMU_OPTION_vnc ,
-    "-vnc <display>  shorthand for -display vnc=<display>\n", QEMU_ARCH_ALL)
+    "-vnc display    start a VNC server on display\n", QEMU_ARCH_ALL)
 STEXI
 @item -vnc @var{display}[,@var{option}[,@var{option}[,...]]]
 @findex -vnc
@@ -1253,13 +1241,6 @@ syntax for the @var{display} is
 
 @table @option
 
-@item to=@var{L}
-
-With this option, QEMU will try next available VNC @var{display}s, until the
-number @var{L}, if the origianlly defined "-vnc @var{display}" is not
-available, e.g. port 5900+@var{display} is already used by another
-application. By default, to=0.
-
 @item @var{host}:@var{d}
 
 TCP connections will only be allowed from @var{host} on display @var{d}.
@@ -1429,14 +1410,6 @@ everybody else.  'ignore' completely ignores the shared flag and
 allows everybody connect unconditionally.  Doesn't conform to the rfb
 spec but is traditional QEMU behavior.
 
-@item key-delay-ms
-
-Set keyboard delay, for key down and key up events, in milliseconds.
-Default is 1.  Keyboards are low-bandwidth devices, so this slowdown
-can help the device and guest to keep up and not lose events in case
-events are arriving in bulk.  Possible causes for the latter are flaky
-network connections, or scripts for automated testing.
-
 @end table
 ETEXI
 
@@ -1596,7 +1569,6 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
     "-netdev tap,id=str[,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile]\n"
     "         [,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off]\n"
     "         [,vhostfd=h][,vhostfds=x:y:...:z][,vhostforce=on|off][,queues=n]\n"
-    "         [,poll-us=n]\n"
     "                configure a host TAP network backend with ID 'str'\n"
     "                use network scripts 'file' (default=" DEFAULT_NETWORK_SCRIPT ")\n"
     "                to configure it and 'dfile' (default=" DEFAULT_NETWORK_DOWN_SCRIPT ")\n"
@@ -1616,8 +1588,6 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
     "                use 'vhostfd=h' to connect to an already opened vhost net device\n"
     "                use 'vhostfds=x:y:...:z to connect to multiple already opened vhost net devices\n"
     "                use 'queues=n' to specify the number of queues to be created for multiqueue TAP\n"
-    "                use 'poll-us=n' to speciy the maximum number of microseconds that could be\n"
-    "                spent on busy polling for vhost net\n"
     "-netdev bridge,id=str[,br=bridge][,helper=helper]\n"
     "                configure a host TAP network backend with ID 'str' that is\n"
     "                connected to a bridge (default=" DEFAULT_BRIDGE_INTERFACE ")\n"
@@ -3229,8 +3199,6 @@ STEXI
 @item -L  @var{path}
 @findex -L
 Set the directory for the BIOS, VGA BIOS and keymaps.
-
-To list all the data directories, use @code{-L help}.
 ETEXI
 
 DEF("bios", HAS_ARG, QEMU_OPTION_bios, \
@@ -3684,9 +3652,34 @@ DEF("trace", HAS_ARG, QEMU_OPTION_trace,
 STEXI
 HXCOMM This line is not accurate, as some sub-options are backend-specific but
 HXCOMM HX does not support conditional compilation of text.
-@item -trace [[enable=]@var{pattern}][,events=@var{file}][,file=@var{file}]
+@item -trace [events=@var{file}][,file=@var{file}]
 @findex -trace
-@include qemu-option-trace.texi
+
+Specify tracing options.
+
+@table @option
+@item [enable=]@var{pattern}
+Immediately enable events matching @var{pattern}.
+The file must contain one event name (as listed in the @file{trace-events} file)
+per line; globbing patterns are accepted too.  This option is only
+available if QEMU has been compiled with the @var{simple}, @var{stderr}
+or @var{ftrace} tracing backend.  To specify multiple events or patterns,
+specify the @option{-trace} option multiple times.
+
+Use @code{-trace help} to print a list of names of trace points.
+
+@item events=@var{file}
+Immediately enable events listed in @var{file}.
+The file must contain one event name (as listed in the @file{trace-events} file)
+per line; globbing patterns are accepted too.  This option is only
+available if QEMU has been compiled with the @var{simple}, @var{stderr} or
+@var{ftrace} tracing backend.
+
+@item file=@var{file}
+Log output traces to @var{file}.
+This option is only available if QEMU has been compiled with
+the @var{simple} tracing backend.
+@end table
 ETEXI
 
 HXCOMM Internal use
index 9299cdc..a8636cb 100644 (file)
@@ -292,7 +292,7 @@ int qemu_timeout_ns_to_ms(int64_t ns)
     /* Always round up, because it's better to wait too long than to wait too
      * little and effectively busy-wait
      */
-    ms = DIV_ROUND_UP(ns, SCALE_MS);
+    ms = (ns + SCALE_MS - 1) / SCALE_MS;
 
     /* To avoid overflow problems, limit this to 2^31, i.e. approx 25 days */
     if (ms > (int64_t) INT32_MAX) {
index bb65d8b..63458c6 100644 (file)
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <termios.h>
 #include "qapi/error.h"
 #include "qemu/sockets.h"
index 21f9dee..68168d1 100644 (file)
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <windows.h>
 #include <io.h>
 #include "qga/guest-agent-core.h"
index ae8cf0f..3704ea9 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef QGA_CHANNEL_H
 #define QGA_CHANNEL_H
 
+#include <glib.h>
 
 typedef struct GAChannel GAChannel;
 
index ea37c09..2ae3725 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <sys/ioctl.h>
 #include <sys/wait.h>
 #include <dirent.h>
@@ -127,6 +128,7 @@ int64_t qmp_guest_get_time(Error **errp)
 {
    int ret;
    qemu_timeval tq;
+   int64_t time_ns;
 
    ret = qemu_gettimeofday(&tq);
    if (ret < 0) {
@@ -134,7 +136,8 @@ int64_t qmp_guest_get_time(Error **errp)
        return -1;
    }
 
-   return tq.tv_sec * 1000000000LL + tq.tv_usec * 1000;
+   time_ns = tq.tv_sec * 1000000000LL + tq.tv_usec * 1000;
+   return time_ns;
 }
 
 void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
@@ -1239,8 +1242,8 @@ int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
             goto error;
         }
 
-        /* we try to cull filesystems we know won't work in advance, but other
-         * filesystems may not implement fsfreeze for less obvious reasons.
+        /* we try to cull filesytems we know won't work in advance, but other
+         * filesytems may not implement fsfreeze for less obvious reasons.
          * these will report EOPNOTSUPP. we simply ignore these when tallying
          * the number of frozen filesystems.
          *
@@ -1389,10 +1392,10 @@ qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
             continue;
         }
 
-        /* We try to cull filesystems we know won't work in advance, but other
-         * filesystems may not implement fstrim for less obvious reasons.
-         * These will report EOPNOTSUPP; while in some other cases ENOTTY
-         * will be reported (e.g. CD-ROMs).
+        /* We try to cull filesytems we know won't work in advance, but other
+         * filesytems may not implement fstrim for less obvious reasons.  These
+         * will report EOPNOTSUPP; while in some other cases ENOTTY will be
+         * reported (e.g. CD-ROMs).
          * Any other error means an unexpected error.
          */
         r.start = 0;
index 9c9be12..d76327f 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <wtypes.h>
 #include <powrprof.h>
 #include <winsock2.h>
@@ -247,7 +248,9 @@ out:
     if (token) {
         CloseHandle(token);
     }
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
 }
 
 static void execute_async(DWORD WINAPI (*func)(LPVOID), LPVOID opaque,
@@ -880,7 +883,9 @@ static void check_suspend_mode(GuestSuspendMode mode, Error **errp)
     }
 
 out:
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
 }
 
 static DWORD WINAPI do_suspend(LPVOID opaque)
@@ -1150,6 +1155,7 @@ out:
 int64_t qmp_guest_get_time(Error **errp)
 {
     SYSTEMTIME ts = {0};
+    int64_t time_ns;
     FILETIME tf;
 
     GetSystemTime(&ts);
@@ -1163,8 +1169,10 @@ int64_t qmp_guest_get_time(Error **errp)
         return -1;
     }
 
-    return ((((int64_t)tf.dwHighDateTime << 32) | tf.dwLowDateTime)
+    time_ns = ((((int64_t)tf.dwHighDateTime << 32) | tf.dwLowDateTime)
                 - W32_FT_OFFSET) * 100;
+
+    return time_ns;
 }
 
 void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
index 50fd26a..3144464 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qga/guest-agent-core.h"
 #include "qga-qmp-commands.h"
 #include "qapi/qmp/qerror.h"
index 4de229c..20b9b22 100644 (file)
@@ -10,6 +10,7 @@
  * See the COPYING file in the top-level directory.
  */
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qga/guest-agent-core.h"
 
 struct GACommandState {
index 4c3b2c7..c552782 100644 (file)
@@ -11,6 +11,7 @@
  * See the COPYING file in the top-level directory.
  */
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <getopt.h>
 #include <glib/gstdio.h>
 #ifndef _WIN32
index fd434e3..7243758 100644 (file)
@@ -11,6 +11,7 @@
  * See the COPYING file in the top-level directory.
  */
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <windows.h>
 #include "qga/service-win32.h"
 
index 89e99df..3b9e870 100644 (file)
@@ -10,9 +10,8 @@
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
-
-#ifndef QGA_SERVICE_WIN32_H
-#define QGA_SERVICE_WIN32_H
+#ifndef QGA_SERVICE_H
+#define QGA_SERVICE_H
 
 #include <windows.h>
 
index f4160a3..cd9cdb4 100644 (file)
@@ -13,7 +13,8 @@
 #include "qemu/osdep.h"
 
 #include "vss-common.h"
-#include <inc/win2003/vscoordint.h>
+#include "inc/win2003/vscoordint.h"
+
 #include <comadmin.h>
 #include <wbemidl.h>
 #include <comdef.h>
index ef94669..d977393 100644 (file)
@@ -12,8 +12,8 @@
 
 #include "qemu/osdep.h"
 #include "vss-common.h"
-#include <inc/win2003/vscoordint.h>
-#include <inc/win2003/vsprov.h>
+#include "inc/win2003/vscoordint.h"
+#include "inc/win2003/vsprov.h"
 
 #define VSS_TIMEOUT_MSEC (60*1000)
 
index 0cd2f0e..889052d 100644 (file)
@@ -13,8 +13,8 @@
 #include "qemu/osdep.h"
 #include "vss-common.h"
 #include "requester.h"
-#include <inc/win2003/vswriter.h>
-#include <inc/win2003/vsbackup.h>
+#include "inc/win2003/vswriter.h"
+#include "inc/win2003/vsbackup.h"
 
 /* Max wait time for frozen event (VSS can only hold writes for 10 seconds) */
 #define VSS_TIMEOUT_FREEZE_MSEC 10000
index c81a856..91dae0c 100644 (file)
@@ -10,8 +10,8 @@
  * See the COPYING file in the top-level directory.
  */
 
-#ifndef VSS_COMMON_H
-#define VSS_COMMON_H
+#ifndef VSS_WIN32_H
+#define VSS_WIN32_H
 
 #define __MIDL_user_allocate_free_DEFINED__
 #include <windows.h>
@@ -50,7 +50,7 @@
  * VSS headers must be installed from Microsoft VSS SDK 7.2 available at:
  * http://www.microsoft.com/en-us/download/details.aspx?id=23490
  */
-#include <inc/win2003/vss.h>
+#include "inc/win2003/vss.h"
 
 /* Macros to convert char definitions to wchar */
 #define _L(a) L##a
similarity index 70%
rename from migration/qjson.c
rename to qjson.c
index f345904..b65ca6e 100644 (file)
+++ b/qjson.c
@@ -1,5 +1,5 @@
 /*
- * A simple JSON writer
+ * QEMU JSON writer
  *
  * Copyright Alexander Graf
  *
  *
  */
 
-/*
- * Type QJSON lets you build JSON text.  Its interface mirrors (a
- * subset of) abstract JSON syntax.
- *
- * It does *not* detect incorrect use.  It happily produces invalid
- * JSON then.  This is what migration wants.
- *
- * QAPI output visitors also produce JSON text.  However, they do
- * assert their preconditions and invariants, and therefore abort on
- * incorrect use.
- */
-
 #include "qemu/osdep.h"
-#include "qapi/qmp/qstring.h"
-#include "migration/qjson.h"
+#include <qapi/qmp/qstring.h>
+#include <glib.h>
+#include <qjson.h>
+#include <qemu/module.h>
+#include <qom/object.h>
 
 struct QJSON {
+    Object obj;
     QString *str;
     bool omit_comma;
 };
 
+#define QJSON(obj) OBJECT_CHECK(QJSON, (obj), TYPE_QJSON)
+
 static void json_emit_element(QJSON *json, const char *name)
 {
     /* Check whether we need to print a , before an element */
@@ -95,10 +89,7 @@ const char *qjson_get_str(QJSON *json)
 
 QJSON *qjson_new(void)
 {
-    QJSON *json = g_new0(QJSON, 1);
-
-    json->str = qstring_from_str("{ ");
-    json->omit_comma = true;
+    QJSON *json = QJSON(object_new(TYPE_QJSON));
     return json;
 }
 
@@ -107,8 +98,32 @@ void qjson_finish(QJSON *json)
     json_end_object(json);
 }
 
-void qjson_destroy(QJSON *json)
+static void qjson_initfn(Object *obj)
+{
+    QJSON *json = QJSON(obj);
+
+    json->str = qstring_from_str("{ ");
+    json->omit_comma = true;
+}
+
+static void qjson_finalizefn(Object *obj)
 {
-    QDECREF(json->str);
-    g_free(json);
+    QJSON *json = QJSON(obj);
+
+    qobject_decref(QOBJECT(json->str));
 }
+
+static const TypeInfo qjson_type_info = {
+    .name = TYPE_QJSON,
+    .parent = TYPE_OBJECT,
+    .instance_size = sizeof(QJSON),
+    .instance_init = qjson_initfn,
+    .instance_finalize = qjson_finalizefn,
+};
+
+static void qjson_register_types(void)
+{
+    type_register_static(&qjson_type_info);
+}
+
+type_init(qjson_register_types)
index 6866264..de896a5 100644 (file)
@@ -587,33 +587,6 @@ Example:
 EQMP
 
     {
-        .name       = "xen-load-devices-state",
-        .args_type  = "filename:F",
-        .mhandler.cmd_new = qmp_marshal_xen_load_devices_state,
-    },
-
-SQMP
-xen-load-devices-state
-----------------------
-
-Load the state of all devices from file. The RAM and the block devices
-of the VM are not loaded by this command.
-
-Arguments:
-
-- "filename": the file to load the state of the devices from as binary
-data. See xen-save-devices-state.txt for a description of the binary
-format.
-
-Example:
-
--> { "execute": "xen-load-devices-state",
-     "arguments": { "filename": "/tmp/resume" } }
-<- { "return": {} }
-
-EQMP
-
-    {
         .name       = "xen-set-global-dirty-log",
         .args_type  = "enable:b",
         .mhandler.cmd_new = qmp_marshal_xen_set_global_dirty_log,
@@ -1106,7 +1079,7 @@ EQMP
 
     {
         .name       = "block-stream",
-        .args_type  = "job-id:s?,device:B,base:s?,speed:o?,backing-file:s?,on-error:s?",
+        .args_type  = "device:B,base:s?,speed:o?,backing-file:s?,on-error:s?",
         .mhandler.cmd_new = qmp_marshal_block_stream,
     },
 
@@ -1118,8 +1091,6 @@ Copy data from a backing file into a block device.
 
 Arguments:
 
-- "job-id": Identifier for the newly-created block job. If omitted,
-            the device name will be used. (json-string, optional)
 - "device": The device's ID, must be unique (json-string)
 - "base": The file name of the backing image above which copying starts
           (json-string, optional)
@@ -1151,7 +1122,7 @@ EQMP
 
     {
         .name       = "block-commit",
-        .args_type  = "job-id:s?,device:B,base:s?,top:s?,backing-file:s?,speed:o?",
+        .args_type  = "device:B,base:s?,top:s?,backing-file:s?,speed:o?",
         .mhandler.cmd_new = qmp_marshal_block_commit,
     },
 
@@ -1164,8 +1135,6 @@ data between 'top' and 'base' into 'base'.
 
 Arguments:
 
-- "job-id": Identifier for the newly-created block job. If omitted,
-            the device name will be used. (json-string, optional)
 - "device": The device's ID, must be unique (json-string)
 - "base": The file name of the backing image to write data into.
           If not specified, this is the deepest backing image
@@ -1216,8 +1185,8 @@ EQMP
 
     {
         .name       = "drive-backup",
-        .args_type  = "job-id:s?,sync:s,device:B,target:s,speed:i?,mode:s?,"
-                      "format:s?,bitmap:s?,on-source-error:s?,on-target-error:s?",
+        .args_type  = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
+                      "bitmap:s?,on-source-error:s?,on-target-error:s?",
         .mhandler.cmd_new = qmp_marshal_drive_backup,
     },
 
@@ -1233,8 +1202,6 @@ block-job-cancel command.
 
 Arguments:
 
-- "job-id": Identifier for the newly-created block job. If omitted,
-            the device name will be used. (json-string, optional)
 - "device": the name of the device which should be copied.
             (json-string)
 - "target": the target of the new image. If the file exists, or if it is a
@@ -1272,7 +1239,7 @@ EQMP
 
     {
         .name       = "blockdev-backup",
-        .args_type  = "job-id:s?,sync:s,device:B,target:B,speed:i?,"
+        .args_type  = "sync:s,device:B,target:B,speed:i?,"
                       "on-source-error:s?,on-target-error:s?",
         .mhandler.cmd_new = qmp_marshal_blockdev_backup,
     },
@@ -1286,8 +1253,6 @@ as backup target.
 
 Arguments:
 
-- "job-id": Identifier for the newly-created block job. If omitted,
-            the device name will be used. (json-string, optional)
 - "device": the name of the device which should be copied.
             (json-string)
 - "target": the name of the backup target device. (json-string)
@@ -1664,8 +1629,8 @@ EQMP
 
     {
         .name       = "drive-mirror",
-        .args_type  = "job-id:s?,sync:s,device:B,target:s,speed:i?,mode:s?,"
-                      "format:s?,node-name:s?,replaces:s?,"
+        .args_type  = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
+                      "node-name:s?,replaces:s?,"
                       "on-source-error:s?,on-target-error:s?,"
                       "unmap:b?,"
                       "granularity:i?,buf-size:i?",
@@ -1685,8 +1650,6 @@ of the source.
 
 Arguments:
 
-- "job-id": Identifier for the newly-created block job. If omitted,
-            the device name will be used. (json-string, optional)
 - "device": device name to operate on (json-string)
 - "target": name of new image file (json-string)
 - "format": format of new image (json-string, optional)
@@ -1730,7 +1693,7 @@ EQMP
 
     {
         .name       = "blockdev-mirror",
-        .args_type  = "job-id:s?,sync:s,device:B,target:B,replaces:s?,speed:i?,"
+        .args_type  = "sync:s,device:B,target:B,replaces:s?,speed:i?,"
                       "on-source-error:s?,on-target-error:s?,"
                       "granularity:i?,buf-size:i?",
         .mhandler.cmd_new = qmp_marshal_blockdev_mirror,
@@ -1745,8 +1708,6 @@ specifies the target of mirror operation.
 
 Arguments:
 
-- "job-id": Identifier for the newly-created block job. If omitted,
-            the device name will be used. (json-string, optional)
 - "device": device name to operate on (json-string)
 - "target": device name to mirror to (json-string)
 - "replaces": the block driver node name to replace when finished
@@ -3786,10 +3747,10 @@ Set migration parameters
 - "compress-level": set compression level during migration (json-int)
 - "compress-threads": set compression thread count for migration (json-int)
 - "decompress-threads": set decompression thread count for migration (json-int)
-- "cpu-throttle-initial": set initial percentage of time guest cpus are
-                          throttled for auto-converge (json-int)
-- "cpu-throttle-increment": set throttle increasing percentage for
-                            auto-converge (json-int)
+- "x-cpu-throttle-initial": set initial percentage of time guest cpus are
+                           throttled for auto-converge (json-int)
+- "x-cpu-throttle-increment": set throttle increasing percentage for
+                             auto-converge (json-int)
 
 Arguments:
 
@@ -3803,7 +3764,7 @@ EQMP
     {
         .name       = "migrate-set-parameters",
         .args_type  =
-            "compress-level:i?,compress-threads:i?,decompress-threads:i?,cpu-throttle-initial:i?,cpu-throttle-increment:i?",
+            "compress-level:i?,compress-threads:i?,decompress-threads:i?,x-cpu-throttle-initial:i?,x-cpu-throttle-increment:i?",
         .mhandler.cmd_new = qmp_marshal_migrate_set_parameters,
     },
 SQMP
@@ -3816,10 +3777,10 @@ Query current migration parameters
          - "compress-level" : compression level value (json-int)
          - "compress-threads" : compression thread count value (json-int)
          - "decompress-threads" : decompression thread count value (json-int)
-         - "cpu-throttle-initial" : initial percentage of time guest cpus are
-                                    throttled (json-int)
-         - "cpu-throttle-increment" : throttle increasing percentage for
-                                      auto-converge (json-int)
+         - "x-cpu-throttle-initial" : initial percentage of time guest cpus are
+                                      throttled (json-int)
+         - "x-cpu-throttle-increment" : throttle increasing percentage for
+                                        auto-converge (json-int)
 
 Arguments:
 
@@ -3829,10 +3790,10 @@ Example:
 <- {
       "return": {
          "decompress-threads": 2,
-         "cpu-throttle-increment": 10,
+         "x-cpu-throttle-increment": 10,
          "compress-threads": 8,
          "compress-level": 1,
-         "cpu-throttle-initial": 20
+         "x-cpu-throttle-initial": 20
       }
    }
 
@@ -4437,59 +4398,6 @@ Example:
 EQMP
 
     {
-        .name       = "x-blockdev-change",
-        .args_type  = "parent:B,child:B?,node:B?",
-        .mhandler.cmd_new = qmp_marshal_x_blockdev_change,
-    },
-
-SQMP
-x-blockdev-change
------------------
-
-Dynamically reconfigure the block driver state graph. It can be used
-to add, remove, insert or replace a graph node. Currently only the
-Quorum driver implements this feature to add or remove its child. This
-is useful to fix a broken quorum child.
-
-If @node is specified, it will be inserted under @parent. @child
-may not be specified in this case. If both @parent and @child are
-specified but @node is not, @child will be detached from @parent.
-
-Arguments:
-- "parent": the id or name of the parent node (json-string)
-- "child": the name of a child under the given parent node (json-string, optional)
-- "node": the name of the node that will be added (json-string, optional)
-
-Note: this command is experimental, and not a stable API. It doesn't
-support all kinds of operations, all kinds of children, nor all block
-drivers.
-
-Warning: The data in a new quorum child MUST be consistent with that of
-the rest of the array.
-
-Example:
-
-Add a new node to a quorum
--> { "execute": "blockdev-add",
-     "arguments": { "options": { "driver": "raw",
-                                 "node-name": "new_node",
-                                 "file": { "driver": "file",
-                                           "filename": "test.raw" } } } }
-<- { "return": {} }
--> { "execute": "x-blockdev-change",
-     "arguments": { "parent": "disk1",
-                    "node": "new_node" } }
-<- { "return": {} }
-
-Delete a quorum's node
--> { "execute": "x-blockdev-change",
-     "arguments": { "parent": "disk1",
-                    "child": "children.1" } }
-<- { "return": {} }
-
-EQMP
-
-    {
         .name       = "query-named-block-nodes",
         .args_type  = "",
         .mhandler.cmd_new = qmp_marshal_query_named_block_nodes,
@@ -4715,7 +4623,7 @@ EQMP
 
     {
         .name       = "trace-event-get-state",
-        .args_type  = "name:s,vcpu:i?",
+        .args_type  = "name:s",
         .mhandler.cmd_new = qmp_marshal_trace_event_get_state,
     },
 
@@ -4725,20 +4633,6 @@ trace-event-get-state
 
 Query the state of events.
 
-Arguments:
-
-- "name": Event name pattern (json-string).
-- "vcpu": The vCPU to query, any vCPU by default (json-int, optional).
-
-An event is returned if:
-- its name matches the "name" pattern, and
-- if "vcpu" is given, the event has the "vcpu" property.
-
-Therefore, if "vcpu" is given, the operation will only match per-vCPU events,
-returning their state on the specified vCPU. Special case: if "name" is an exact
-match, "vcpu" is given and the event does not have the "vcpu" property, an error
-is returned.
-
 Example:
 
 -> { "execute": "trace-event-get-state", "arguments": { "name": "qemu_memalign" } }
@@ -4747,7 +4641,7 @@ EQMP
 
     {
         .name       = "trace-event-set-state",
-        .args_type  = "name:s,enable:b,ignore-unavailable:b?,vcpu:i?",
+        .args_type  = "name:s,enable:b,ignore-unavailable:b?",
         .mhandler.cmd_new = qmp_marshal_trace_event_set_state,
     },
 
@@ -4757,23 +4651,6 @@ trace-event-set-state
 
 Set the state of events.
 
-Arguments:
-
-- "name": Event name pattern (json-string).
-- "enable": Whether to enable or disable the event (json-bool).
-- "ignore-unavailable": Whether to ignore errors for events that cannot be
-  changed (json-bool, optional).
-- "vcpu": The vCPU to act upon, all vCPUs by default (json-int, optional).
-
-An event's state is modified if:
-- its name matches the "name" pattern, and
-- if "vcpu" is given, the event has the "vcpu" property.
-
-Therefore, if "vcpu" is given, the operation will only match per-vCPU events,
-setting their state on the specified vCPU. Special case: if "name" is an exact
-match, "vcpu" is given and the event does not have the "vcpu" property, an error
-is returned.
-
 Example:
 
 -> { "execute": "trace-event-set-state", "arguments": { "name": "qemu_memalign", "enable": "true" } }
@@ -4802,6 +4679,8 @@ The consoles are visible in the qom tree, under
 /backend/console[$index]. They have a device link and head property, so
 it is possible to map which console belongs to which device and display.
 
+Note: this command is experimental, and not a stable API.
+
 Example (1):
 
 Press left mouse button.
@@ -5001,41 +4880,3 @@ Example:
                 { "version": 3, "emulated": false, "kernel": true } ] }
 
 EQMP
-
-    {
-        .name       = "query-hotpluggable-cpus",
-        .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_hotpluggable_cpus,
-    },
-
-SQMP
-Show existing/possible CPUs
----------------------------
-
-Arguments: None.
-
-Example for pseries machine type started with
--smp 2,cores=2,maxcpus=4 -cpu POWER8:
-
--> { "execute": "query-hotpluggable-cpus" }
-<- {"return": [
-     { "props": { "core-id": 8 }, "type": "POWER8-spapr-cpu-core",
-       "vcpus-count": 1 },
-     { "props": { "core-id": 0 }, "type": "POWER8-spapr-cpu-core",
-       "vcpus-count": 1, "qom-path": "/machine/unattached/device[0]"}
-   ]}'
-
-Example for pc machine type started with
--smp 1,maxcpus=2:
-    -> { "execute": "query-hotpluggable-cpus" }
-    <- {"return": [
-         {
-            "type": "qemu64-x86_64-cpu", "vcpus-count": 1,
-            "props": {"core-id": 0, "socket-id": 1, "thread-id": 0}
-         },
-         {
-            "qom-path": "/machine/unattached/device[0]",
-            "type": "qemu64-x86_64-cpu", "vcpus-count": 1,
-            "props": {"core-id": 0, "socket-id": 0, "thread-id": 0}
-         }
-       ]}
diff --git a/qmp.c b/qmp.c
index b6d531e..9d0953b 100644 (file)
--- a/qmp.c
+++ b/qmp.c
@@ -14,7 +14,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu-version.h"
 #include "qemu/cutils.h"
 #include "monitor/monitor.h"
 #include "sysemu/sysemu.h"
@@ -182,7 +181,6 @@ void qmp_cont(Error **errp)
     Error *local_err = NULL;
     BlockBackend *blk;
     BlockDriverState *bs;
-    BdrvNextIterator it;
 
     /* if there is a dump in background, we should wait until the dump
      * finished */
@@ -201,8 +199,7 @@ void qmp_cont(Error **errp)
     for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
         blk_iostatus_reset(blk);
     }
-
-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+    for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
         bdrv_add_key(bs, NULL, &local_err);
         if (local_err) {
             error_propagate(errp, local_err);
@@ -655,7 +652,7 @@ void qmp_object_add(const char *type, const char *id,
                     bool has_props, QObject *props, Error **errp)
 {
     const QDict *pdict = NULL;
-    Visitor *v;
+    QmpInputVisitor *qiv;
     Object *obj;
 
     if (props) {
@@ -666,9 +663,10 @@ void qmp_object_add(const char *type, const char *id,
         }
     }
 
-    v = qmp_input_visitor_new(props, true);
-    obj = user_creatable_add_type(type, id, pdict, v, errp);
-    visit_free(v);
+    qiv = qmp_input_visitor_new(props);
+    obj = user_creatable_add_type(type, id, pdict,
+                                  qmp_input_get_visitor(qiv), errp);
+    qmp_input_visitor_cleanup(qiv);
     if (obj) {
         object_unref(obj);
     }
index af4a75e..496374d 100644 (file)
 #define MAX_TOKEN_SIZE (64ULL << 20)
 
 /*
- * Required by JSON (RFC 7159):
- *
- * \"([^\\\"]|\\[\"'\\/bfnrt]|\\u[0-9a-fA-F]{4})*\"
- * -?(0|[1-9][0-9]*)(.[0-9]+)?([eE][-+]?[0-9]+)?
+ * \"([^\\\"]|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*\"
+ * '([^\\']|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*'
+ * 0|([1-9][0-9]*(.[0-9]+)?([eE]([-+])?[0-9]+))
  * [{}\[\],:]
- * [a-z]+   # covers null, true, false
- *
- * Extension of '' strings:
- *
- * '([^\\']|\\[\"'\\/bfnrt]|\\u[0-9a-fA-F]{4})*'
- *
- * Extension for vararg handling in JSON construction:
- *
- * %((l|ll|I64)?d|[ipsf])
+ * [a-z]+
  *
  */
 
@@ -222,7 +213,7 @@ static const uint8_t json_lexer[][256] =  {
         ['\t'] = IN_WHITESPACE,
         ['\r'] = IN_WHITESPACE,
         ['\n'] = IN_WHITESPACE,
-    },
+    },        
 
     /* escape */
     [IN_ESCAPE_LL] = {
index c18e48a..67ed727 100644 (file)
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
-#include "qapi/qmp/types.h"
+#include "qapi/qmp/qstring.h"
+#include "qapi/qmp/qint.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qfloat.h"
+#include "qapi/qmp/qbool.h"
 #include "qapi/qmp/json-parser.h"
 #include "qapi/qmp/json-lexer.h"
 #include "qapi/qmp/json-streamer.h"
index 60f158c..a128536 100644 (file)
@@ -705,16 +705,19 @@ int qdict_array_entries(QDict *src, const char *subqdict)
     for (i = 0; i < INT_MAX; i++) {
         QObject *subqobj;
         int subqdict_entries;
-        char *prefix = g_strdup_printf("%s%u.", subqdict, i);
+        size_t slen = 32 + subqdict_len;
+        char indexstr[slen], prefix[slen];
+        size_t snprintf_ret;
 
-        subqdict_entries = qdict_count_prefixed_entries(src, prefix);
+        snprintf_ret = snprintf(indexstr, slen, "%s%u", subqdict, i);
+        assert(snprintf_ret < slen);
 
-        /* Remove ending "." */
-        prefix[strlen(prefix) - 1] = 0;
-        subqobj = qdict_get(src, prefix);
+        subqobj = qdict_get(src, indexstr);
 
-        g_free(prefix);
+        snprintf_ret = snprintf(prefix, slen, "%s%u.", subqdict, i);
+        assert(snprintf_ret < slen);
 
+        subqdict_entries = qdict_count_prefixed_entries(src, prefix);
         if (subqdict_entries < 0) {
             return subqdict_entries;
         }
index 9a0de89..ef160d2 100644 (file)
 #include "qapi/qmp/json-parser.h"
 #include "qapi/qmp/json-streamer.h"
 #include "qapi/qmp/qjson.h"
-#include "qapi/qmp/types.h"
+#include "qapi/qmp/qint.h"
+#include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qfloat.h"
+#include "qapi/qmp/qdict.h"
 #include "qemu/unicode.h"
 
 typedef struct JSONParsingState
index 86b60cb..1ec74de 100644 (file)
@@ -100,6 +100,7 @@ QObject *qlist_pop(QList *qlist)
 QObject *qlist_peek(QList *qlist)
 {
     QListEntry *entry;
+    QObject *ret;
 
     if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
         return NULL;
@@ -107,7 +108,9 @@ QObject *qlist_peek(QList *qlist)
 
     entry = QTAILQ_FIRST(&qlist->head);
 
-    return entry->value;
+    ret = entry->value;
+
+    return ret;
 }
 
 int qlist_empty(const QList *qlist)
index fe4fa10..cd41fb9 100644 (file)
@@ -9,7 +9,12 @@
 
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "qapi/qmp/types.h"
+#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qfloat.h"
+#include "qapi/qmp/qint.h"
+#include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qstring.h"
 
 static void (*qdestroy[QTYPE__MAX])(QObject *) = {
     [QTYPE_NONE] = NULL,               /* No such object exists */
index 2553247..c9007d3 100644 (file)
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -28,7 +28,6 @@
 #include "exec/log.h"
 #include "qemu/error-report.h"
 #include "sysemu/sysemu.h"
-#include "hw/qdev-properties.h"
 
 bool cpu_exists(int64_t id)
 {
@@ -47,7 +46,7 @@ bool cpu_exists(int64_t id)
 CPUState *cpu_generic_init(const char *typename, const char *cpu_model)
 {
     char *str, *name, *featurestr;
-    CPUState *cpu = NULL;
+    CPUState *cpu;
     ObjectClass *oc;
     CPUClass *cc;
     Error *err = NULL;
@@ -61,18 +60,16 @@ CPUState *cpu_generic_init(const char *typename, const char *cpu_model)
         return NULL;
     }
 
-    cc = CPU_CLASS(oc);
+    cpu = CPU(object_new(object_class_get_name(oc)));
+    cc = CPU_GET_CLASS(cpu);
+
     featurestr = strtok(NULL, ",");
-    /* TODO: all callers of cpu_generic_init() need to be converted to
-     * call parse_features() only once, before calling cpu_generic_init().
-     */
-    cc->parse_features(object_class_get_name(oc), featurestr, &err);
+    cc->parse_features(cpu, featurestr, &err);
     g_free(str);
     if (err != NULL) {
         goto out;
     }
 
-    cpu = CPU(object_new(object_class_get_name(oc)));
     object_property_set_bool(OBJECT(cpu), true, "realized", &err);
 
 out:
@@ -257,6 +254,7 @@ static void cpu_common_reset(CPUState *cpu)
     }
 
     cpu->interrupt_request = 0;
+    cpu->current_tb = NULL;
     cpu->halted = 0;
     cpu->mem_io_pc = 0;
     cpu->mem_io_vaddr = 0;
@@ -285,37 +283,25 @@ static ObjectClass *cpu_common_class_by_name(const char *cpu_model)
     return NULL;
 }
 
-static void cpu_common_parse_features(const char *typename, char *features,
+static void cpu_common_parse_features(CPUState *cpu, char *features,
                                       Error **errp)
 {
     char *featurestr; /* Single "key=value" string being parsed */
     char *val;
-    static bool cpu_globals_initialized;
-
-    /* TODO: all callers of ->parse_features() need to be changed to
-     * call it only once, so we can remove this check (or change it
-     * to assert(!cpu_globals_initialized).
-     * Current callers of ->parse_features() are:
-     * - cpu_generic_init()
-     */
-    if (cpu_globals_initialized) {
-        return;
-    }
-    cpu_globals_initialized = true;
+    Error *err = NULL;
 
     featurestr = features ? strtok(features, ",") : NULL;
 
     while (featurestr) {
         val = strchr(featurestr, '=');
         if (val) {
-            GlobalProperty *prop = g_new0(typeof(*prop), 1);
             *val = 0;
             val++;
-            prop->driver = typename;
-            prop->property = g_strdup(featurestr);
-            prop->value = g_strdup(val);
-            prop->errp = &error_fatal;
-            qdev_prop_register_global(prop);
+            object_property_parse(OBJECT(cpu), val, featurestr, &err);
+            if (err) {
+                error_propagate(errp, err);
+                return;
+            }
         } else {
             error_setg(errp, "Expected key=value format, found %s.",
                        featurestr);
@@ -340,12 +326,11 @@ static void cpu_common_initfn(Object *obj)
     CPUState *cpu = CPU(obj);
     CPUClass *cc = CPU_GET_CLASS(obj);
 
-    cpu->cpu_index = UNASSIGNED_CPU_INDEX;
+    cpu->cpu_index = -1;
     cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
     qemu_mutex_init(&cpu->work_mutex);
     QTAILQ_INIT(&cpu->breakpoints);
     QTAILQ_INIT(&cpu->watchpoints);
-    bitmap_zero(cpu->trace_dstate, TRACE_VCPU_EVENT_COUNT);
 }
 
 static void cpu_common_finalize(Object *obj)
index 8166b7d..8e6e68d 100644 (file)
@@ -202,14 +202,6 @@ static size_t type_object_get_size(TypeImpl *ti)
     return 0;
 }
 
-size_t object_type_get_instance_size(const char *typename)
-{
-    TypeImpl *type = type_get_by_name(typename);
-
-    g_assert(type != NULL);
-    return type_object_get_size(type);
-}
-
 static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type)
 {
     assert(target_type);
@@ -549,7 +541,9 @@ Object *object_new_with_propv(const char *typename,
     return obj;
 
  error:
-    error_propagate(errp, local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
     object_unref(obj);
     return NULL;
 }
@@ -1221,7 +1215,8 @@ int object_property_get_enum(Object *obj, const char *name,
                              const char *typename, Error **errp)
 {
     Error *err = NULL;
-    Visitor *v;
+    StringOutputVisitor *sov;
+    StringInputVisitor *siv;
     char *str;
     int ret;
     ObjectProperty *prop = object_property_find(obj, name, errp);
@@ -1240,20 +1235,21 @@ int object_property_get_enum(Object *obj, const char *name,
 
     enumprop = prop->opaque;
 
-    v = string_output_visitor_new(false, &str);
-    object_property_get(obj, v, name, &err);
+    sov = string_output_visitor_new(false);
+    object_property_get(obj, string_output_get_visitor(sov), name, &err);
     if (err) {
         error_propagate(errp, err);
-        visit_free(v);
+        string_output_visitor_cleanup(sov);
         return 0;
     }
-    visit_complete(v, &str);
-    visit_free(v);
-    v = string_input_visitor_new(str);
-    visit_type_enum(v, name, &ret, enumprop->strings, errp);
+    str = string_output_get_string(sov);
+    siv = string_input_visitor_new(str);
+    string_output_visitor_cleanup(sov);
+    visit_type_enum(string_input_get_visitor(siv), name, &ret,
+                    enumprop->strings, errp);
 
     g_free(str);
-    visit_free(v);
+    string_input_visitor_cleanup(siv);
 
     return ret;
 }
@@ -1262,51 +1258,55 @@ void object_property_get_uint16List(Object *obj, const char *name,
                                     uint16List **list, Error **errp)
 {
     Error *err = NULL;
-    Visitor *v;
+    StringOutputVisitor *ov;
+    StringInputVisitor *iv;
     char *str;
 
-    v = string_output_visitor_new(false, &str);
-    object_property_get(obj, v, name, &err);
+    ov = string_output_visitor_new(false);
+    object_property_get(obj, string_output_get_visitor(ov),
+                        name, &err);
     if (err) {
         error_propagate(errp, err);
         goto out;
     }
-    visit_complete(v, &str);
-    visit_free(v);
-    v = string_input_visitor_new(str);
-    visit_type_uint16List(v, NULL, list, errp);
+    str = string_output_get_string(ov);
+    iv = string_input_visitor_new(str);
+    visit_type_uint16List(string_input_get_visitor(iv), NULL, list, errp);
 
     g_free(str);
+    string_input_visitor_cleanup(iv);
 out:
-    visit_free(v);
+    string_output_visitor_cleanup(ov);
 }
 
 void object_property_parse(Object *obj, const char *string,
                            const char *name, Error **errp)
 {
-    Visitor *v = string_input_visitor_new(string);
-    object_property_set(obj, v, name, errp);
-    visit_free(v);
+    StringInputVisitor *siv;
+    siv = string_input_visitor_new(string);
+    object_property_set(obj, string_input_get_visitor(siv), name, errp);
+
+    string_input_visitor_cleanup(siv);
 }
 
 char *object_property_print(Object *obj, const char *name, bool human,
                             Error **errp)
 {
-    Visitor *v;
+    StringOutputVisitor *sov;
     char *string = NULL;
     Error *local_err = NULL;
 
-    v = string_output_visitor_new(human, &string);
-    object_property_get(obj, v, name, &local_err);
+    sov = string_output_visitor_new(human);
+    object_property_get(obj, string_output_get_visitor(sov), name, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         goto out;
     }
 
-    visit_complete(v, &string);
+    string = string_output_get_string(sov);
 
 out:
-    visit_free(v);
+    string_output_visitor_cleanup(sov);
     return string;
 }
 
@@ -2036,9 +2036,10 @@ static void property_get_tm(Object *obj, Visitor *v, const char *name,
     if (err) {
         goto out_end;
     }
-    visit_check_struct(v, &err);
 out_end:
-    visit_end_struct(v, NULL);
+    error_propagate(errp, err);
+    err = NULL;
+    visit_end_struct(v, errp);
 out:
     error_propagate(errp, err);
 
index bf59846..3931890 100644 (file)
@@ -42,7 +42,7 @@ Object *user_creatable_add(const QDict *qdict,
     char *type = NULL;
     char *id = NULL;
     Object *obj = NULL;
-    Error *local_err = NULL;
+    Error *local_err = NULL, *end_err = NULL;
     QDict *pdict;
 
     pdict = qdict_clone_shallow(qdict);
@@ -63,15 +63,21 @@ Object *user_creatable_add(const QDict *qdict,
     if (local_err) {
         goto out_visit;
     }
-    visit_check_struct(v, &local_err);
+
+    obj = user_creatable_add_type(type, id, pdict, v, &local_err);
     if (local_err) {
         goto out_visit;
     }
 
-    obj = user_creatable_add_type(type, id, pdict, v, &local_err);
-
-out_visit:
-    visit_end_struct(v, NULL);
+ out_visit:
+    visit_end_struct(v, &end_err);
+    if (end_err) {
+        error_propagate(&local_err, end_err);
+        if (obj) {
+            user_creatable_del(id, NULL);
+        }
+        goto out;
+    }
 
 out:
     QDECREF(pdict);
@@ -112,25 +118,15 @@ Object *user_creatable_add_type(const char *type, const char *id,
         return NULL;
     }
 
-    assert(qdict);
     obj = object_new(type);
-    visit_start_struct(v, NULL, NULL, 0, &local_err);
-    if (local_err) {
-        goto out;
-    }
-    for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
-        object_property_set(obj, v, e->key, &local_err);
-        if (local_err) {
-            break;
+    if (qdict) {
+        for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
+            object_property_set(obj, v, e->key, &local_err);
+            if (local_err) {
+                goto out;
+            }
         }
     }
-    if (!local_err) {
-        visit_check_struct(v, &local_err);
-    }
-    visit_end_struct(v, NULL);
-    if (local_err) {
-        goto out;
-    }
 
     object_property_add_child(object_get_objects_root(),
                               id, obj, &local_err);
@@ -156,15 +152,15 @@ out:
 
 Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
 {
-    Visitor *v;
+    OptsVisitor *ov;
     QDict *pdict;
     Object *obj = NULL;
 
-    v = opts_visitor_new(opts);
+    ov = opts_visitor_new(opts);
     pdict = qemu_opts_to_qdict(opts, NULL);
 
-    obj = user_creatable_add(pdict, v, errp);
-    visit_free(v);
+    obj = user_creatable_add(pdict, opts_get_visitor(ov), errp);
+    opts_visitor_cleanup(ov);
     QDECREF(pdict);
     return obj;
 }
index c225abc..e6b17c1 100644 (file)
 void object_property_set_qobject(Object *obj, QObject *value,
                                  const char *name, Error **errp)
 {
-    Visitor *v;
-    /* TODO: Should we reject, rather than ignore, excess input? */
-    v = qmp_input_visitor_new(value, false);
-    object_property_set(obj, v, name, errp);
-    visit_free(v);
+    QmpInputVisitor *qiv;
+    qiv = qmp_input_visitor_new(value);
+    object_property_set(obj, qmp_input_get_visitor(qiv), name, errp);
+
+    qmp_input_visitor_cleanup(qiv);
 }
 
 QObject *object_property_get_qobject(Object *obj, const char *name,
@@ -33,14 +33,14 @@ QObject *object_property_get_qobject(Object *obj, const char *name,
 {
     QObject *ret = NULL;
     Error *local_err = NULL;
-    Visitor *v;
+    QmpOutputVisitor *qov;
 
-    v = qmp_output_visitor_new(&ret);
-    object_property_get(obj, v, name, &local_err);
+    qov = qmp_output_visitor_new();
+    object_property_get(obj, qmp_output_get_visitor(qov), name, &local_err);
     if (!local_err) {
-        visit_complete(v, &ret);
+        ret = qmp_output_get_qobject(qov);
     }
     error_propagate(errp, local_err);
-    visit_free(v);
+    qmp_output_visitor_cleanup(qov);
     return ret;
 }
diff --git a/qom/trace-events b/qom/trace-events
deleted file mode 100644 (file)
index 97db357..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# qom/object.c
-object_dynamic_cast_assert(const char *type, const char *target, const char *file, int line, const char *func) "%s->%s (%s:%d:%s)"
-object_class_dynamic_cast_assert(const char *type, const char *target, const char *file, int line, const char *func) "%s->%s (%s:%d:%s)"
diff --git a/qtest.c b/qtest.c
index da4826c..87575bc 100644 (file)
--- a/qtest.c
+++ b/qtest.c
@@ -13,8 +13,6 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "sysemu/qtest.h"
 #include "hw/qdev.h"
 #include "sysemu/char.h"
index edf46ab..23b6922 100755 (executable)
@@ -9,6 +9,10 @@
  *
  */
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
 #include "qemu/osdep.h"
 #include "qemu/error-report.h"
 #include "sysemu/replay.h"
index bd93554..06babe0 100644 (file)
 #include "replay-internal.h"
 #include "qemu/notify.h"
 #include "ui/input.h"
-#include "qapi/clone-visitor.h"
+#include "qapi/qmp-output-visitor.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi-visit.h"
+
+static InputEvent *qapi_clone_InputEvent(InputEvent *src)
+{
+    QmpOutputVisitor *qov;
+    QmpInputVisitor *qiv;
+    Visitor *ov, *iv;
+    QObject *obj;
+    InputEvent *dst = NULL;
+
+    qov = qmp_output_visitor_new();
+    ov = qmp_output_get_visitor(qov);
+    visit_type_InputEvent(ov, NULL, &src, &error_abort);
+    obj = qmp_output_get_qobject(qov);
+    qmp_output_visitor_cleanup(qov);
+    if (!obj) {
+        return NULL;
+    }
+
+    qiv = qmp_input_visitor_new(obj);
+    iv = qmp_input_get_visitor(qiv);
+    visit_type_InputEvent(iv, NULL, &dst, &error_abort);
+    qmp_input_visitor_cleanup(qiv);
+    qobject_decref(obj);
+
+    return dst;
+}
 
 void replay_save_input_event(InputEvent *evt)
 {
@@ -115,7 +143,7 @@ InputEvent *replay_read_input_event(void)
         break;
     }
 
-    return QAPI_CLONE(InputEvent, &evt);
+    return qapi_clone_InputEvent(&evt);
 }
 
 void replay_input_event(QemuConsole *src, InputEvent *evt)
@@ -123,7 +151,7 @@ void replay_input_event(QemuConsole *src, InputEvent *evt)
     if (replay_mode == REPLAY_MODE_PLAY) {
         /* Nothing */
     } else if (replay_mode == REPLAY_MODE_RECORD) {
-        replay_add_input_event(QAPI_CLONE(InputEvent, evt));
+        replay_add_input_event(qapi_clone_InputEvent(evt));
     } else {
         qemu_input_event_send_impl(src, evt);
     }
index 88b3709..7bd1252 100644 (file)
@@ -1,13 +1,11 @@
 
 vgabios_variants := stdvga cirrus vmware qxl isavga virtio
 vgabios_targets  := $(subst -isavga,,$(patsubst %,vgabios-%.bin,$(vgabios_variants)))
-pxerom_variants  := e1000 e1000e eepro100 ne2k_pci pcnet rtl8139 virtio vmxnet3
-pxerom_targets   := 8086100e 808610d3 80861209 10500940 10222000 10ec8139 1af41000 15ad07b0
+pxerom_variants  := e1000 eepro100 ne2k_pci pcnet rtl8139 virtio
+pxerom_targets   := 8086100e 80861209 10500940 10222000 10ec8139 1af41000
 
 pxe-rom-e1000    efi-rom-e1000    : VID := 8086
 pxe-rom-e1000    efi-rom-e1000    : DID := 100e
-pxe-rom-e1000e   efi-rom-e1000e   : VID := 8086
-pxe-rom-e1000e   efi-rom-e1000e   : DID := 10d3
 pxe-rom-eepro100 efi-rom-eepro100 : VID := 8086
 pxe-rom-eepro100 efi-rom-eepro100 : DID := 1209
 pxe-rom-ne2k_pci efi-rom-ne2k_pci : VID := 1050
@@ -18,8 +16,6 @@ pxe-rom-rtl8139  efi-rom-rtl8139  : VID := 10ec
 pxe-rom-rtl8139  efi-rom-rtl8139  : DID := 8139
 pxe-rom-virtio   efi-rom-virtio   : VID := 1af4
 pxe-rom-virtio   efi-rom-virtio   : DID := 1000
-pxe-rom-vmxnet3  efi-rom-vmxnet3  : VID := 15ad
-pxe-rom-vmxnet3  efi-rom-vmxnet3  : DID := 07b0
 
 #
 # cross compiler auto detection
index 93203af..0a9da77 100644 (file)
@@ -2,11 +2,9 @@
 # need to turn off features (xhci,uas) to make it fit into 128k
 CONFIG_QEMU=y
 CONFIG_ROM_SIZE=128
-CONFIG_BOOTSPLASH=n
 CONFIG_XEN=n
 CONFIG_USB_OHCI=n
 CONFIG_USB_XHCI=n
 CONFIG_USB_UAS=n
 CONFIG_SDCARD=n
 CONFIG_TCGBIOS=n
-CONFIG_MPT_SCSI=n
index 582ffe8..2a9cc9e 100644 (file)
@@ -9,7 +9,6 @@ ASFLAGS         :=
 LDFLAGS                :=
 HOST_CFLAGS    :=
 MAKEDEPS       := Makefile
-CROSS_COMPILE  ?= $(CROSS)
 
 ###############################################################################
 #
@@ -53,6 +52,9 @@ EINFO         := ./util/einfo
 GENKEYMAP      := ./util/genkeymap.pl
 DOXYGEN                := doxygen
 LCAB           := lcab
+BINUTILS_DIR   := /usr
+BFD_DIR                := $(BINUTILS_DIR)
+ZLIB_DIR       := /usr
 
 ###############################################################################
 #
@@ -81,14 +83,6 @@ SRCDIRS              += drivers/block
 SRCDIRS                += drivers/nvs
 SRCDIRS                += drivers/bitbash
 SRCDIRS                += drivers/infiniband
-SRCDIRS                += drivers/infiniband/mlx_utils_flexboot/src
-SRCDIRS                += drivers/infiniband/mlx_utils/src/public
-SRCDIRS                += drivers/infiniband/mlx_utils/mlx_lib/mlx_reg_access
-SRCDIRS                += drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig
-SRCDIRS                += drivers/infiniband/mlx_utils/mlx_lib/mlx_vmac
-SRCDIRS                += drivers/infiniband/mlx_utils/mlx_lib/mlx_blink_leds
-SRCDIRS                += drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed
-SRCDIRS                += drivers/infiniband/mlx_nodnic/src
 SRCDIRS                += drivers/usb
 SRCDIRS                += interface/pxe interface/efi interface/smbios
 SRCDIRS                += interface/bofm
@@ -157,9 +151,6 @@ all : $(ALL)
 everything :
        $(Q)$(MAKE) --no-print-directory $(ALL) \
                bin/3c509.rom bin/intel.rom bin/intel.mrom \
-               bin-x86_64-pcbios/8086100e.mrom bin-x86_64-pcbios/intel.rom \
-               bin-x86_64-pcbios/ipxe.usb bin-x86_64-pcbios/ipxe.pxe \
-               bin-x86_64-pcbios/undionly.kpxe \
                bin-i386-efi/ipxe.efi bin-i386-efi/ipxe.efidrv \
                bin-i386-efi/ipxe.efirom \
                bin-x86_64-efi/ipxe.efi bin-x86_64-efi/ipxe.efidrv \
diff --git a/roms/ipxe/src/Makefile.efi b/roms/ipxe/src/Makefile.efi
deleted file mode 100644 (file)
index 151b331..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-# -*- makefile -*- : Force emacs to use Makefile mode
-
-# The EFI linker script
-#
-LDSCRIPT       = scripts/efi.lds
-
-# Retain relocation information for elf2efi
-#
-LDFLAGS                += -q -S
-
-# Media types.
-#
-NON_AUTO_MEDIA += efi
-NON_AUTO_MEDIA += efidrv
-NON_AUTO_MEDIA += drv.efi
-NON_AUTO_MEDIA += efirom
-
-# Include SNP driver in the all-drivers build
-#
-DRIVERS_net += snp
-
-# Rules for building EFI files
-#
-$(BIN)/%.efi : $(BIN)/%.efi.tmp $(ELF2EFI)
-       $(QM)$(ECHO) "  [FINISH] $@"
-       $(Q)$(ELF2EFI) --subsystem=10 $< $@
-
-$(BIN)/%.efidrv : $(BIN)/%.efidrv.tmp $(ELF2EFI)
-       $(QM)$(ECHO) "  [FINISH] $@"
-       $(Q)$(ELF2EFI) --subsystem=11 $< $@
-
-$(BIN)/%.drv.efi : $(BIN)/%.efidrv
-       $(QM)$(ECHO) "  [FINISH] $@"
-       $(Q)$(CP) $< $@
-
-$(BIN)/%.efirom : $(BIN)/%.efidrv $(EFIROM)
-       $(QM)$(ECHO) "  [FINISH] $@"
-       $(Q)$(EFIROM) -v $(TGT_PCI_VENDOR) -d $(TGT_PCI_DEVICE) $< $@
-
-$(BIN)/efidrv.cab : $(BIN)/alldrv.efis # $(ALL_drv.efi) is not yet defined
-       $(QM)$(ECHO) "  [CAB] $@"
-       $(Q)$(LCAB) -n -q $(ALL_drv.efi) $@
-
-$(BIN)/%.usb : $(BIN)/%.efi
-       $(QM)$(ECHO) "  [GENEFIDSK] $@"
-       $(Q)bash util/genefidsk -o $@ -b $(EFI_BOOT_FILE) $<
index ceff814..03800c8 100644 (file)
@@ -491,11 +491,6 @@ LDFLAGS            += -static
 #
 CFLAGS         += -include include/compiler.h
 
-# The section type character (e.g. "@" in "@progbits") varies by
-# architecture.
-#
-CFLAGS         += -DASM_TCHAR='$(ASM_TCHAR)' -DASM_TCHAR_OPS='$(ASM_TCHAR_OPS)'
-
 # CFLAGS for specific object types
 #
 CFLAGS_c       +=
@@ -739,8 +734,8 @@ $(DBGCOL_LIST) : $(MAKEDEPS)
 VERYCLEANUP += $(DBGCOL_LIST)
 
 DBGCOL_COLOURS := $(subst -, ,$(DBGCOL))
-DBGCOL_MIN := $(firstword $(DBGCOL_COLOURS))
-DBGCOL_MAX := $(lastword $(DBGCOL_COLOURS))
+DBGCOL_MIN := $(word 1,$(DBGCOL_COLOURS))
+DBGCOL_MAX := $(word 2,$(DBGCOL_COLOURS))
 
 debug_DEPS += $(DBGCOL_LIST)
 
@@ -901,7 +896,7 @@ endif
 # Device ID tables (using IDs from ROM definition file)
 #
 define obj_pci_id_asm
-       .section ".pci_devlist.$(1)", "a", $(ASM_TCHAR)progbits
+       .section ".pci_devlist.$(1)", "a", @progbits
        .globl pci_devlist_$(1)
 pci_devlist_$(1):
        .short ( 0x$(1) & 0xffff )
@@ -965,13 +960,13 @@ DRIVERS_ipxe      = $(DRIVERS_net) $(DRIVERS_infiniband) \
 # TGT_DRIVERS  : the driver for each element (e.g. "rtl8139 prism2_pci")
 # TGT_ROM_NAME : the ROM name (e.g. "dfe538")
 #
+CARD_DRIVER    = $(firstword $(DRIVER_$(1)) $(1))
 TGT_ELEMENTS   = $(subst --, ,$(firstword $(subst ., ,$(notdir $@))))
 TGT_ROM_NAME   = $(firstword $(TGT_ELEMENTS))
-TGT_DRIVERS    = $(strip $(foreach TGT_ELEMENT,$(TGT_ELEMENTS), \
-                                   $(if $(DRIVERS_$(TGT_ELEMENT)), \
-                                        $(DRIVERS_$(TGT_ELEMENT)), \
-                                        $(firstword $(DRIVER_$(TGT_ELEMENT)) \
-                                                    $(TGT_ELEMENT)))))
+TGT_DRIVERS    = $(strip $(if $(DRIVERS_$(TGT_ROM_NAME)), \
+                              $(DRIVERS_$(TGT_ROM_NAME)), \
+                              $(foreach TGT_ELEMENT,$(TGT_ELEMENTS), \
+                                $(call CARD_DRIVER,$(TGT_ELEMENT))) ))
 TGT_PREFIX_NAME        = $(word 2,$(subst ., ,$(notdir $@)))
 TGT_PREFIX     = $(strip $(if $(filter rom,$(TGT_PREFIX_NAME)), \
                               $(ROM_TYPE_$(TGT_ROM_NAME))rom, \
@@ -1010,7 +1005,7 @@ TGT_LD_ENTRY      = _$(TGT_PREFIX)_start
 #                --defsym pci_vendor=0x1186 --defsym pci_device=0x1300")
 #
 TGT_LD_FLAGS   = $(foreach SYM,$(TGT_LD_ENTRY) $(TGT_LD_DRIVERS) \
-                   $(TGT_LD_DEVLIST) obj_config obj_config_$(PLATFORM),\
+                   $(TGT_LD_DEVLIST) obj_config,\
                    -u $(SYM) --defsym check_$(SYM)=$(SYM) ) \
                  $(patsubst %,--defsym %,$(TGT_LD_IDS)) \
                  -e $(TGT_LD_ENTRY)
@@ -1303,15 +1298,21 @@ CLEANUP += $(ZBIN)
 #
 # The EFI image converter
 #
+ELF2EFI_CFLAGS := -I$(BINUTILS_DIR)/include -I$(BFD_DIR)/include \
+                  -I$(ZLIB_DIR)/include -idirafter include
+ELF2EFI_LDFLAGS        := -L$(BINUTILS_DIR)/lib -L$(BFD_DIR)/lib -L$(ZLIB_DIR)/lib \
+                  -lbfd -ldl -liberty -lz -Wl,--no-warn-search-mismatch
 
 $(ELF2EFI32) : util/elf2efi.c $(MAKEDEPS)
        $(QM)$(ECHO) "  [HOSTCC] $@"
-       $(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -DEFI_TARGET32 $< -o $@
+       $(Q)$(HOST_CC) $(HOST_CFLAGS) $(ELF2EFI_CFLAGS) -DEFI_TARGET_IA32 $< \
+               $(ELF2EFI_LDFLAGS) -o $@
 CLEANUP += $(ELF2EFI32)
 
 $(ELF2EFI64) : util/elf2efi.c $(MAKEDEPS)
        $(QM)$(ECHO) "  [HOSTCC] $@"
-       $(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -DEFI_TARGET64 $< -o $@
+       $(Q)$(HOST_CC) $(HOST_CFLAGS) $(ELF2EFI_CFLAGS) -DEFI_TARGET_X64 $< \
+               $(ELF2EFI_LDFLAGS) -o $@
 CLEANUP += $(ELF2EFI64)
 
 $(EFIROM) : util/efirom.c $(MAKEDEPS)
diff --git a/roms/ipxe/src/arch/arm/Makefile b/roms/ipxe/src/arch/arm/Makefile
deleted file mode 100644 (file)
index 3cee5f3..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# Assembler section type character
-#
-ASM_TCHAR      := %
-ASM_TCHAR_OPS  := %%
-
-# Include common ARM headers
-#
-INCDIRS                += arch/arm/include
-
-# ARM-specific directories containing source files
-#
-SRCDIRS                += arch/arm/interface/efi
diff --git a/roms/ipxe/src/arch/arm/Makefile.efi b/roms/ipxe/src/arch/arm/Makefile.efi
deleted file mode 100644 (file)
index f04be42..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# -*- makefile -*- : Force emacs to use Makefile mode
-
-# Include generic EFI Makefile
-#
-MAKEDEPS       += Makefile.efi
-include Makefile.efi
diff --git a/roms/ipxe/src/arch/arm/core/arm_io.c b/roms/ipxe/src/arch/arm/core/arm_io.c
deleted file mode 100644 (file)
index 1ef571f..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/io.h>
-#include <ipxe/arm_io.h>
-
-/** @file
- *
- * iPXE I/O API for ARM
- *
- */
-
-/** An ARM I/O qword */
-union arm32_io_qword {
-       uint64_t qword;
-       uint32_t dword[2];
-};
-
-/**
- * Read 64-bit qword from memory-mapped device
- *
- * @v io_addr          I/O address
- * @ret data           Value read
- *
- * This is not atomic for ARM32.
- */
-static uint64_t arm32_readq ( volatile uint64_t *io_addr ) {
-       volatile union arm32_io_qword *ptr =
-               container_of ( io_addr, union arm32_io_qword, qword );
-       union arm32_io_qword tmp;
-
-       tmp.dword[0] = readl ( &ptr->dword[0] );
-       tmp.dword[1] = readl ( &ptr->dword[1] );
-       return tmp.qword;
-}
-
-/**
- * Write 64-bit qword to memory-mapped device
- *
- * @v data             Value to write
- * @v io_addr          I/O address
- *
- * This is not atomic for ARM32.
- */
-static void arm32_writeq ( uint64_t data, volatile uint64_t *io_addr ) {
-       volatile union arm32_io_qword *ptr =
-               container_of ( io_addr, union arm32_io_qword, qword );
-       union arm32_io_qword tmp;
-
-       tmp.qword = data;
-       writel ( tmp.dword[0], &ptr->dword[0] );
-       writel ( tmp.dword[1], &ptr->dword[1] );
-}
-
-PROVIDE_IOAPI_INLINE ( arm, phys_to_bus );
-PROVIDE_IOAPI_INLINE ( arm, bus_to_phys );
-PROVIDE_IOAPI_INLINE ( arm, readb );
-PROVIDE_IOAPI_INLINE ( arm, readw );
-PROVIDE_IOAPI_INLINE ( arm, readl );
-PROVIDE_IOAPI_INLINE ( arm, writeb );
-PROVIDE_IOAPI_INLINE ( arm, writew );
-PROVIDE_IOAPI_INLINE ( arm, writel );
-PROVIDE_IOAPI_INLINE ( arm, iodelay );
-PROVIDE_IOAPI_INLINE ( arm, mb );
-#ifdef __aarch64__
-PROVIDE_IOAPI_INLINE ( arm, readq );
-PROVIDE_IOAPI_INLINE ( arm, writeq );
-#else
-PROVIDE_IOAPI ( arm, readq, arm32_readq );
-PROVIDE_IOAPI ( arm, writeq, arm32_writeq );
-#endif
diff --git a/roms/ipxe/src/arch/arm/include/bits/endian.h b/roms/ipxe/src/arch/arm/include/bits/endian.h
deleted file mode 100644 (file)
index 4506711..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _BITS_ENDIAN_H
-#define _BITS_ENDIAN_H
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/* ARM may be either little-endian or big-endian */
-#ifdef __ARM_BIG_ENDIAN
-#define __BYTE_ORDER __BIG_ENDIAN
-#else
-#define __BYTE_ORDER __LITTLE_ENDIAN
-#endif
-
-#endif /* _BITS_ENDIAN_H */
diff --git a/roms/ipxe/src/arch/arm/include/bits/errfile.h b/roms/ipxe/src/arch/arm/include/bits/errfile.h
deleted file mode 100644 (file)
index 65f7f71..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _BITS_ERRFILE_H
-#define _BITS_ERRFILE_H
-
-/** @file
- *
- * ARM-specific error file identifiers
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/**
- * @addtogroup errfile Error file identifiers
- * @{
- */
-
-/** @} */
-
-#endif /* _BITS_ERRFILE_H */
diff --git a/roms/ipxe/src/arch/arm/include/bits/hyperv.h b/roms/ipxe/src/arch/arm/include/bits/hyperv.h
deleted file mode 100644 (file)
index f0e0c87..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _BITS_HYPERV_H
-#define _BITS_HYPERV_H
-
-/** @file
- *
- * Hyper-V interface
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#endif /* _BITS_HYPERV_H */
diff --git a/roms/ipxe/src/arch/arm/include/bits/io.h b/roms/ipxe/src/arch/arm/include/bits/io.h
deleted file mode 100644 (file)
index 90f6455..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _BITS_IO_H
-#define _BITS_IO_H
-
-/** @file
- *
- * ARM-specific I/O API implementations
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/arm_io.h>
-
-#endif /* _BITS_IO_H */
diff --git a/roms/ipxe/src/arch/arm/include/bits/iomap.h b/roms/ipxe/src/arch/arm/include/bits/iomap.h
deleted file mode 100644 (file)
index ae953c4..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _BITS_IOMAP_H
-#define _BITS_IOMAP_H
-
-/** @file
- *
- * ARM-specific I/O mapping API implementations
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#endif /* _BITS_IOMAP_H */
diff --git a/roms/ipxe/src/arch/arm/include/bits/nap.h b/roms/ipxe/src/arch/arm/include/bits/nap.h
deleted file mode 100644 (file)
index e30a714..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _BITS_NAP_H
-#define _BITS_NAP_H
-
-/** @file
- *
- * ARM-specific CPU sleeping API implementations
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/efi/efiarm_nap.h>
-
-#endif /* _BITS_MAP_H */
diff --git a/roms/ipxe/src/arch/arm/include/bits/pci_io.h b/roms/ipxe/src/arch/arm/include/bits/pci_io.h
deleted file mode 100644 (file)
index fba0eb9..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _BITS_PCI_IO_H
-#define _BITS_PCI_IO_H
-
-/** @file
- *
- * ARM PCI I/O API implementations
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/io.h>
-
-#endif /* _BITS_PCI_IO_H */
diff --git a/roms/ipxe/src/arch/arm/include/bits/uart.h b/roms/ipxe/src/arch/arm/include/bits/uart.h
deleted file mode 100644 (file)
index 6f85975..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _BITS_UART_H
-#define _BITS_UART_H
-
-/** @file
- *
- * 16550-compatible UART
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#endif /* _BITS_UART_H */
diff --git a/roms/ipxe/src/arch/arm/include/bits/umalloc.h b/roms/ipxe/src/arch/arm/include/bits/umalloc.h
deleted file mode 100644 (file)
index 27970d7..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _BITS_UMALLOC_H
-#define _BITS_UMALLOC_H
-
-/** @file
- *
- * ARM-specific user memory allocation API implementations
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#endif /* _BITS_UMALLOC_H */
diff --git a/roms/ipxe/src/arch/arm/include/bits/xen.h b/roms/ipxe/src/arch/arm/include/bits/xen.h
deleted file mode 100644 (file)
index 34f6479..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef _BITS_XEN_H
-#define _BITS_XEN_H
-
-/** @file
- *
- * Xen interface
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/* Hypercall registers */
-#ifdef __aarch64__
-#define XEN_HC "x16"
-#define XEN_REG1 "x0"
-#define XEN_REG2 "x1"
-#define XEN_REG3 "x2"
-#define XEN_REG4 "x3"
-#define XEN_REG5 "x4"
-#else
-#define XEN_HC "r12"
-#define XEN_REG1 "r0"
-#define XEN_REG2 "r1"
-#define XEN_REG3 "r2"
-#define XEN_REG4 "r3"
-#define XEN_REG5 "r4"
-#endif
-
-/**
- * Issue hypercall with one argument
- *
- * @v xen              Xen hypervisor
- * @v hypercall                Hypercall number
- * @v arg1             First argument
- * @ret retval         Return value
- */
-static inline __attribute__ (( always_inline )) unsigned long
-xen_hypercall_1 ( struct xen_hypervisor *xen __unused, unsigned int hypercall,
-                 unsigned long arg1 ) {
-       register unsigned long hc asm ( XEN_HC ) = hypercall;
-       register unsigned long reg1 asm ( XEN_REG1 ) = arg1;
-
-       __asm__ __volatile__ ( "hvc %1"
-                              : "+r" ( reg1 )
-                              : "i" ( XEN_HYPERCALL_TAG ), "r" ( hc )
-                              : "memory", "cc" );
-       return reg1;
-}
-
-/**
- * Issue hypercall with two arguments
- *
- * @v xen              Xen hypervisor
- * @v hypercall                Hypercall number
- * @v arg1             First argument
- * @v arg2             Second argument
- * @ret retval         Return value
- */
-static inline __attribute__ (( always_inline )) unsigned long
-xen_hypercall_2 ( struct xen_hypervisor *xen __unused, unsigned int hypercall,
-                 unsigned long arg1, unsigned long arg2 ) {
-       register unsigned long hc asm ( XEN_HC ) = hypercall;
-       register unsigned long reg1 asm ( XEN_REG1 ) = arg1;
-       register unsigned long reg2 asm ( XEN_REG2 ) = arg2;
-
-       __asm__ __volatile__ ( "hvc %2"
-                              : "+r" ( reg1 ), "+r" ( reg2 )
-                              : "i" ( XEN_HYPERCALL_TAG ), "r" ( hc )
-                              : "memory", "cc" );
-       return reg1;
-}
-
-/**
- * Issue hypercall with three arguments
- *
- * @v xen              Xen hypervisor
- * @v hypercall                Hypercall number
- * @v arg1             First argument
- * @v arg2             Second argument
- * @v arg3             Third argument
- * @ret retval         Return value
- */
-static inline __attribute__ (( always_inline )) unsigned long
-xen_hypercall_3 ( struct xen_hypervisor *xen __unused, unsigned int hypercall,
-                 unsigned long arg1, unsigned long arg2, unsigned long arg3 ) {
-       register unsigned long hc asm ( XEN_HC ) = hypercall;
-       register unsigned long reg1 asm ( XEN_REG1 ) = arg1;
-       register unsigned long reg2 asm ( XEN_REG2 ) = arg2;
-       register unsigned long reg3 asm ( XEN_REG3 ) = arg3;
-
-       __asm__ __volatile__ ( "hvc %3"
-                              : "+r" ( reg1 ), "+r" ( reg2 ), "+r" ( reg3 )
-                              : "i" ( XEN_HYPERCALL_TAG ), "r" ( hc )
-                              : "memory", "cc" );
-       return reg1;
-}
-
-/**
- * Issue hypercall with four arguments
- *
- * @v xen              Xen hypervisor
- * @v hypercall                Hypercall number
- * @v arg1             First argument
- * @v arg2             Second argument
- * @v arg3             Third argument
- * @v arg4             Fourth argument
- * @ret retval         Return value
- */
-static inline __attribute__ (( always_inline )) unsigned long
-xen_hypercall_4 ( struct xen_hypervisor *xen __unused, unsigned int hypercall,
-                 unsigned long arg1, unsigned long arg2, unsigned long arg3,
-                 unsigned long arg4 ) {
-       register unsigned long hc asm ( XEN_HC ) = hypercall;
-       register unsigned long reg1 asm ( XEN_REG1 ) = arg1;
-       register unsigned long reg2 asm ( XEN_REG2 ) = arg2;
-       register unsigned long reg3 asm ( XEN_REG3 ) = arg3;
-       register unsigned long reg4 asm ( XEN_REG4 ) = arg4;
-
-       __asm__ __volatile__ ( "hvc %4"
-                              : "+r" ( reg1 ), "+r" ( reg2 ), "+r" ( reg3 ),
-                                "+r" ( reg4 )
-                              : "i" ( XEN_HYPERCALL_TAG ), "r" ( hc )
-                              : "memory", "cc" );
-       return reg1;
-}
-
-/**
- * Issue hypercall with five arguments
- *
- * @v xen              Xen hypervisor
- * @v hypercall                Hypercall number
- * @v arg1             First argument
- * @v arg2             Second argument
- * @v arg3             Third argument
- * @v arg4             Fourth argument
- * @v arg5             Fifth argument
- * @ret retval         Return value
- */
-static inline __attribute__ (( always_inline )) unsigned long
-xen_hypercall_5 ( struct xen_hypervisor *xen __unused, unsigned int hypercall,
-                 unsigned long arg1, unsigned long arg2, unsigned long arg3,
-                 unsigned long arg4, unsigned long arg5 ) {
-       register unsigned long hc asm ( XEN_HC ) = hypercall;
-       register unsigned long reg1 asm ( XEN_REG1 ) = arg1;
-       register unsigned long reg2 asm ( XEN_REG2 ) = arg2;
-       register unsigned long reg3 asm ( XEN_REG3 ) = arg3;
-       register unsigned long reg4 asm ( XEN_REG4 ) = arg4;
-       register unsigned long reg5 asm ( XEN_REG5 ) = arg5;
-
-       __asm__ __volatile__ ( "hvc %5"
-                              : "+r" ( reg1 ), "+r" ( reg2 ), "+r" ( reg3 ),
-                                "+r" ( reg4 ), "+r" ( reg5 )
-                              : "i" ( XEN_HYPERCALL_TAG ), "r" ( hc )
-                              : "memory", "cc" );
-       return reg1;
-}
-
-#endif /* _BITS_XEN_H */
diff --git a/roms/ipxe/src/arch/arm/include/ipxe/arm_io.h b/roms/ipxe/src/arch/arm/include/ipxe/arm_io.h
deleted file mode 100644 (file)
index f8765af..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef _IPXE_ARM_IO_H
-#define _IPXE_ARM_IO_H
-
-/** @file
- *
- * iPXE I/O API for ARM
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#ifdef IOAPI_ARM
-#define IOAPI_PREFIX_arm
-#else
-#define IOAPI_PREFIX_arm __arm_
-#endif
-
-/*
- * Memory space mappings
- *
- */
-
-/** Page shift */
-#define PAGE_SHIFT 12
-
-/*
- * Physical<->Bus address mappings
- *
- */
-
-static inline __always_inline unsigned long
-IOAPI_INLINE ( arm, phys_to_bus ) ( unsigned long phys_addr ) {
-       return phys_addr;
-}
-
-static inline __always_inline unsigned long
-IOAPI_INLINE ( arm, bus_to_phys ) ( unsigned long bus_addr ) {
-       return bus_addr;
-}
-
-/*
- * MMIO reads and writes up to native word size
- *
- */
-
-#define ARM_READX( _api_func, _type, _insn_suffix, _reg_prefix )             \
-static inline __always_inline _type                                          \
-IOAPI_INLINE ( arm, _api_func ) ( volatile _type *io_addr ) {                \
-       _type data;                                                           \
-       __asm__ __volatile__ ( "ldr" _insn_suffix " %" _reg_prefix "0, %1"    \
-                              : "=r" ( data ) : "Qo" ( *io_addr ) );         \
-       return data;                                                          \
-}
-#ifdef __aarch64__
-ARM_READX ( readb, uint8_t, "b", "w" );
-ARM_READX ( readw, uint16_t, "h", "w" );
-ARM_READX ( readl, uint32_t, "", "w" );
-ARM_READX ( readq, uint64_t, "", "" );
-#else
-ARM_READX ( readb, uint8_t, "b", "" );
-ARM_READX ( readw, uint16_t, "h", "" );
-ARM_READX ( readl, uint32_t, "", "" );
-#endif
-
-#define ARM_WRITEX( _api_func, _type, _insn_suffix, _reg_prefix )                      \
-static inline __always_inline void                                           \
-IOAPI_INLINE ( arm, _api_func ) ( _type data, volatile _type *io_addr ) {     \
-       __asm__ __volatile__ ( "str" _insn_suffix " %" _reg_prefix "0, %1"    \
-                              : : "r" ( data ), "Qo" ( *io_addr ) );         \
-}
-#ifdef __aarch64__
-ARM_WRITEX ( writeb, uint8_t, "b", "w" );
-ARM_WRITEX ( writew, uint16_t, "h", "w" );
-ARM_WRITEX ( writel, uint32_t, "", "w" );
-ARM_WRITEX ( writeq, uint64_t, "", "" );
-#else
-ARM_WRITEX ( writeb, uint8_t, "b", "" );
-ARM_WRITEX ( writew, uint16_t, "h", "" );
-ARM_WRITEX ( writel, uint32_t, "", "" );
-#endif
-
-/*
- * Slow down I/O
- *
- */
-static inline __always_inline void
-IOAPI_INLINE ( arm, iodelay ) ( void ) {
-       /* Nothing to do */
-}
-
-/*
- * Memory barrier
- *
- */
-static inline __always_inline void
-IOAPI_INLINE ( arm, mb ) ( void ) {
-
-#ifdef __aarch64__
-       __asm__ __volatile__ ( "dmb sy" );
-#else
-       __asm__ __volatile__ ( "dmb" );
-#endif
-}
-
-#endif /* _IPXE_ARM_IO_H */
diff --git a/roms/ipxe/src/arch/arm/include/ipxe/efi/efiarm_nap.h b/roms/ipxe/src/arch/arm/include/ipxe/efi/efiarm_nap.h
deleted file mode 100644 (file)
index dcbdd3e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _IPXE_EFIARM_NAP_H
-#define _IPXE_EFIARM_NAP_H
-
-/** @file
- *
- * EFI CPU sleeping
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#ifdef NAP_EFIARM
-#define NAP_PREFIX_efiarm
-#else
-#define NAP_PREFIX_efiarm __efiarm_
-#endif
-
-#endif /* _IPXE_EFIARM_NAP_H */
diff --git a/roms/ipxe/src/arch/arm/interface/efi/efiarm_nap.c b/roms/ipxe/src/arch/arm/interface/efi/efiarm_nap.c
deleted file mode 100644 (file)
index 9ed638e..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/nap.h>
-#include <ipxe/efi/efi.h>
-
-/** @file
- *
- * iPXE CPU sleeping API for EFI
- *
- */
-
-/**
- * Sleep until next interrupt
- *
- */
-static void efiarm_cpu_nap ( void ) {
-       /*
-        * I can't find any EFI API that allows us to put the CPU to
-        * sleep.  The CpuSleep() function is defined in CpuLib.h, but
-        * isn't part of any exposed protocol so we have no way to
-        * call it.
-        *
-        * The EFI shell doesn't seem to bother sleeping the CPU; it
-        * just sits there idly burning power.
-        *
-        */
-       __asm__ __volatile__ ( "wfi" );
-}
-
-PROVIDE_NAP ( efiarm, cpu_nap, efiarm_cpu_nap );
diff --git a/roms/ipxe/src/arch/arm32/Makefile b/roms/ipxe/src/arch/arm32/Makefile
deleted file mode 100644 (file)
index 3a7c092..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# ARM32-specific directories containing source files
-#
-SRCDIRS                += arch/arm32/core
-SRCDIRS                += arch/arm32/libgcc
-
-# ARM32-specific flags
-#
-CFLAGS         += -mthumb -mcpu=cortex-a15 -mabi=aapcs -mfloat-abi=soft
-CFLAGS         += -mword-relocations
-ASFLAGS                += -mthumb -mcpu=cortex-a15
-
-# EFI requires -fshort-wchar, and nothing else currently uses wchar_t
-#
-CFLAGS         += -fshort-wchar
-
-# Include common ARM Makefile
-MAKEDEPS       += arch/arm/Makefile
-include arch/arm/Makefile
-
-# Include platform-specific Makefile
-#
-MAKEDEPS       += arch/arm32/Makefile.$(PLATFORM)
-include arch/arm32/Makefile.$(PLATFORM)
diff --git a/roms/ipxe/src/arch/arm32/Makefile.efi b/roms/ipxe/src/arch/arm32/Makefile.efi
deleted file mode 100644 (file)
index a06354f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# -*- makefile -*- : Force emacs to use Makefile mode
-
-# Specify EFI image builder
-#
-ELF2EFI                = $(ELF2EFI32)
-
-# Specify EFI boot file
-#
-EFI_BOOT_FILE  = bootarm.efi
-
-# Include generic EFI Makefile
-#
-MAKEDEPS       += arch/arm/Makefile.efi
-include arch/arm/Makefile.efi
diff --git a/roms/ipxe/src/arch/arm32/core/arm32_bigint.c b/roms/ipxe/src/arch/arm32/core/arm32_bigint.c
deleted file mode 100644 (file)
index 839bead..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <string.h>
-#include <ipxe/bigint.h>
-
-/** @file
- *
- * Big integer support
- */
-
-/**
- * Multiply big integers
- *
- * @v multiplicand0    Element 0 of big integer to be multiplied
- * @v multiplier0      Element 0 of big integer to be multiplied
- * @v result0          Element 0 of big integer to hold result
- * @v size             Number of elements
- */
-void bigint_multiply_raw ( const uint32_t *multiplicand0,
-                          const uint32_t *multiplier0,
-                          uint32_t *result0, unsigned int size ) {
-       const bigint_t ( size ) __attribute__ (( may_alias )) *multiplicand =
-               ( ( const void * ) multiplicand0 );
-       const bigint_t ( size ) __attribute__ (( may_alias )) *multiplier =
-               ( ( const void * ) multiplier0 );
-       bigint_t ( size * 2 ) __attribute__ (( may_alias )) *result =
-               ( ( void * ) result0 );
-       unsigned int i;
-       unsigned int j;
-       uint32_t multiplicand_element;
-       uint32_t multiplier_element;
-       uint32_t *result_elements;
-       uint32_t discard_low;
-       uint32_t discard_high;
-       uint32_t discard_temp;
-
-       /* Zero result */
-       memset ( result, 0, sizeof ( *result ) );
-
-       /* Multiply integers one element at a time */
-       for ( i = 0 ; i < size ; i++ ) {
-               multiplicand_element = multiplicand->element[i];
-               for ( j = 0 ; j < size ; j++ ) {
-                       multiplier_element = multiplier->element[j];
-                       result_elements = &result->element[ i + j ];
-                       /* Perform a single multiply, and add the
-                        * resulting double-element into the result,
-                        * carrying as necessary.  The carry can
-                        * never overflow beyond the end of the
-                        * result, since:
-                        *
-                        *     a < 2^{n}, b < 2^{n} => ab < 2^{2n}
-                        */
-                       __asm__ __volatile__ ( "umull %1, %2, %5, %6\n\t"
-                                              "ldr %3, [%0]\n\t"
-                                              "adds %3, %1\n\t"
-                                              "stmia %0!, {%3}\n\t"
-                                              "ldr %3, [%0]\n\t"
-                                              "adcs %3, %2\n\t"
-                                              "stmia %0!, {%3}\n\t"
-                                              "bcc 2f\n\t"
-                                              "\n1:\n\t"
-                                              "ldr %3, [%0]\n\t"
-                                              "adcs %3, #0\n\t"
-                                              "stmia %0!, {%3}\n\t"
-                                              "bcs 1b\n\t"
-                                              "\n2:\n\t"
-                                              : "+l" ( result_elements ),
-                                                "=l" ( discard_low ),
-                                                "=l" ( discard_high ),
-                                                "=l" ( discard_temp ),
-                                                "+m" ( *result )
-                                              : "l" ( multiplicand_element ),
-                                                "l" ( multiplier_element )
-                                              : "cc" );
-               }
-       }
-}
diff --git a/roms/ipxe/src/arch/arm32/core/setjmp.S b/roms/ipxe/src/arch/arm32/core/setjmp.S
deleted file mode 100644 (file)
index 7e7b0fe..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
-
-       .text
-       .arm
-
-/*
- * Save stack context for non-local goto
- */
-       .globl  setjmp
-       .type   setjmp, %function
-setjmp:
-       /* Store registers */
-       stmia   r0, { r4, r5, r6, r7, r8, r9, r10, fp, sp, lr }
-       /* Return 0 when returning as setjmp() */
-       mov     r0, #0
-       bx      lr
-       .size   setjmp, . - setjmp
-
-/*
- * Non-local jump to a saved stack context
- */
-       .globl  longjmp
-       .type   longjmp, %function
-longjmp:
-       /* Restore registers */
-       ldmia   r0, { r4, r5, r6, r7, r8, r9, r10, fp, sp, lr }
-       /* Force result to non-zero */
-       movs    r0, r1
-       moveq   r0, #1
-       /* Return to setjmp() caller */
-       bx      lr
-       .size   longjmp, . - longjmp
diff --git a/roms/ipxe/src/arch/arm32/include/bits/bigint.h b/roms/ipxe/src/arch/arm32/include/bits/bigint.h
deleted file mode 100644 (file)
index 103c6c4..0000000
+++ /dev/null
@@ -1,316 +0,0 @@
-#ifndef _BITS_BIGINT_H
-#define _BITS_BIGINT_H
-
-/** @file
- *
- * Big integer support
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <string.h>
-#include <strings.h>
-
-/** Element of a big integer */
-typedef uint32_t bigint_element_t;
-
-/**
- * Initialise big integer
- *
- * @v value0           Element 0 of big integer to initialise
- * @v size             Number of elements
- * @v data             Raw data
- * @v len              Length of raw data
- */
-static inline __attribute__ (( always_inline )) void
-bigint_init_raw ( uint32_t *value0, unsigned int size,
-                 const void *data, size_t len ) {
-       size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len );
-       uint8_t *value_byte = ( ( void * ) value0 );
-       const uint8_t *data_byte = ( data + len );
-
-       /* Copy raw data in reverse order, padding with zeros */
-       while ( len-- )
-               *(value_byte++) = *(--data_byte);
-       while ( pad_len-- )
-               *(value_byte++) = 0;
-}
-
-/**
- * Add big integers
- *
- * @v addend0          Element 0 of big integer to add
- * @v value0           Element 0 of big integer to be added to
- * @v size             Number of elements
- */
-static inline __attribute__ (( always_inline )) void
-bigint_add_raw ( const uint32_t *addend0, uint32_t *value0,
-                unsigned int size ) {
-       bigint_t ( size ) __attribute__ (( may_alias )) *value =
-               ( ( void * ) value0 );
-       uint32_t *discard_addend;
-       uint32_t *discard_value;
-       uint32_t *discard_end;
-       uint32_t discard_addend_i;
-       uint32_t discard_value_i;
-
-       __asm__ __volatile__ ( "adds %2, %0, %8, lsl #2\n\t" /* clear CF */
-                              "\n1:\n\t"
-                              "ldmia %0!, {%3}\n\t"
-                              "ldr %4, [%1]\n\t"
-                              "adcs %4, %3\n\t"
-                              "stmia %1!, {%4}\n\t"
-                              "teq %0, %2\n\t"
-                              "bne 1b\n\t"
-                              : "=l" ( discard_addend ),
-                                "=l" ( discard_value ),
-                                "=l" ( discard_end ),
-                                "=l" ( discard_addend_i ),
-                                "=l" ( discard_value_i ),
-                                "+m" ( *value )
-                              : "0" ( addend0 ), "1" ( value0 ), "l" ( size )
-                              : "cc" );
-}
-
-/**
- * Subtract big integers
- *
- * @v subtrahend0      Element 0 of big integer to subtract
- * @v value0           Element 0 of big integer to be subtracted from
- * @v size             Number of elements
- */
-static inline __attribute__ (( always_inline )) void
-bigint_subtract_raw ( const uint32_t *subtrahend0, uint32_t *value0,
-                     unsigned int size ) {
-       bigint_t ( size ) __attribute__ (( may_alias )) *value =
-               ( ( void * ) value0 );
-       uint32_t *discard_subtrahend;
-       uint32_t *discard_value;
-       uint32_t *discard_end;
-       uint32_t discard_subtrahend_i;
-       uint32_t discard_value_i;
-
-       __asm__ __volatile__ ( "add %2, %0, %8, lsl #2\n\t"
-                              "cmp %2, %0\n\t" /* set CF */
-                              "\n1:\n\t"
-                              "ldmia %0!, {%3}\n\t"
-                              "ldr %4, [%1]\n\t"
-                              "sbcs %4, %3\n\t"
-                              "stmia %1!, {%4}\n\t"
-                              "teq %0, %2\n\t"
-                              "bne 1b\n\t"
-                              : "=l" ( discard_subtrahend ),
-                                "=l" ( discard_value ),
-                                "=l" ( discard_end ),
-                                "=l" ( discard_subtrahend_i ),
-                                "=l" ( discard_value_i ),
-                                "+m" ( *value )
-                              : "0" ( subtrahend0 ), "1" ( value0 ),
-                                "l" ( size )
-                              : "cc" );
-}
-
-/**
- * Rotate big integer left
- *
- * @v value0           Element 0 of big integer
- * @v size             Number of elements
- */
-static inline __attribute__ (( always_inline )) void
-bigint_rol_raw ( uint32_t *value0, unsigned int size ) {
-       bigint_t ( size ) __attribute__ (( may_alias )) *value =
-               ( ( void * ) value0 );
-       uint32_t *discard_value;
-       uint32_t *discard_end;
-       uint32_t discard_value_i;
-
-       __asm__ __volatile__ ( "adds %1, %0, %5, lsl #2\n\t" /* clear CF */
-                              "\n1:\n\t"
-                              "ldr %2, [%0]\n\t"
-                              "adcs %2, %2\n\t"
-                              "stmia %0!, {%2}\n\t"
-                              "teq %0, %1\n\t"
-                              "bne 1b\n\t"
-                              : "=l" ( discard_value ),
-                                "=l" ( discard_end ),
-                                "=l" ( discard_value_i ),
-                                "+m" ( *value )
-                              : "0" ( value0 ), "1" ( size )
-                              : "cc" );
-}
-
-/**
- * Rotate big integer right
- *
- * @v value0           Element 0 of big integer
- * @v size             Number of elements
- */
-static inline __attribute__ (( always_inline )) void
-bigint_ror_raw ( uint32_t *value0, unsigned int size ) {
-       bigint_t ( size ) __attribute__ (( may_alias )) *value =
-               ( ( void * ) value0 );
-       uint32_t *discard_value;
-       uint32_t *discard_end;
-       uint32_t discard_value_i;
-
-       __asm__ __volatile__ ( "adds %1, %0, %5, lsl #2\n\t" /* clear CF */
-                              "\n1:\n\t"
-                              "ldmdb %1!, {%2}\n\t"
-                              "rrxs %2, %2\n\t"
-                              "str %2, [%1]\n\t"
-                              "teq %0, %1\n\t"
-                              "bne 1b\n\t"
-                              : "=l" ( discard_value ),
-                                "=l" ( discard_end ),
-                                "=l" ( discard_value_i ),
-                                "+m" ( *value )
-                              : "0" ( value0 ), "1" ( size )
-                              : "cc" );
-}
-
-/**
- * Test if big integer is equal to zero
- *
- * @v value0           Element 0 of big integer
- * @v size             Number of elements
- * @ret is_zero                Big integer is equal to zero
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_zero_raw ( const uint32_t *value0, unsigned int size ) {
-       const uint32_t *value = value0;
-       uint32_t value_i;
-
-       do {
-               value_i = *(value++);
-               if ( value_i )
-                       break;
-       } while ( --size );
-
-       return ( value_i == 0 );
-}
-
-/**
- * Compare big integers
- *
- * @v value0           Element 0 of big integer
- * @v reference0       Element 0 of reference big integer
- * @v size             Number of elements
- * @ret geq            Big integer is greater than or equal to the reference
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_geq_raw ( const uint32_t *value0, const uint32_t *reference0,
-                   unsigned int size ) {
-       const uint32_t *value = ( value0 + size );
-       const uint32_t *reference = ( reference0 + size );
-       uint32_t value_i;
-       uint32_t reference_i;
-
-       do {
-               value_i = *(--value);
-               reference_i = *(--reference);
-               if ( value_i != reference_i )
-                       break;
-       } while ( --size );
-
-       return ( value_i >= reference_i );
-}
-
-/**
- * Test if bit is set in big integer
- *
- * @v value0           Element 0 of big integer
- * @v size             Number of elements
- * @v bit              Bit to test
- * @ret is_set         Bit is set
- */
-static inline __attribute__ (( always_inline )) int
-bigint_bit_is_set_raw ( const uint32_t *value0, unsigned int size,
-                       unsigned int bit ) {
-       const bigint_t ( size ) __attribute__ (( may_alias )) *value =
-               ( ( const void * ) value0 );
-       unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) );
-       unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) );
-
-       return ( value->element[index] & ( 1 << subindex ) );
-}
-
-/**
- * Find highest bit set in big integer
- *
- * @v value0           Element 0 of big integer
- * @v size             Number of elements
- * @ret max_bit                Highest bit set + 1 (or 0 if no bits set)
- */
-static inline __attribute__ (( always_inline )) int
-bigint_max_set_bit_raw ( const uint32_t *value0, unsigned int size ) {
-       const uint32_t *value = ( value0 + size );
-       int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) );
-       uint32_t value_i;
-
-       do {
-               value_i = *(--value);
-               max_bit -= ( 32 - fls ( value_i ) );
-               if ( value_i )
-                       break;
-       } while ( --size );
-
-       return max_bit;
-}
-
-/**
- * Grow big integer
- *
- * @v source0          Element 0 of source big integer
- * @v source_size      Number of elements in source big integer
- * @v dest0            Element 0 of destination big integer
- * @v dest_size                Number of elements in destination big integer
- */
-static inline __attribute__ (( always_inline )) void
-bigint_grow_raw ( const uint32_t *source0, unsigned int source_size,
-                 uint32_t *dest0, unsigned int dest_size ) {
-       unsigned int pad_size = ( dest_size - source_size );
-
-       memcpy ( dest0, source0, sizeof ( bigint_t ( source_size ) ) );
-       memset ( ( dest0 + source_size ), 0, sizeof ( bigint_t ( pad_size ) ) );
-}
-
-/**
- * Shrink big integer
- *
- * @v source0          Element 0 of source big integer
- * @v source_size      Number of elements in source big integer
- * @v dest0            Element 0 of destination big integer
- * @v dest_size                Number of elements in destination big integer
- */
-static inline __attribute__ (( always_inline )) void
-bigint_shrink_raw ( const uint32_t *source0, unsigned int source_size __unused,
-                   uint32_t *dest0, unsigned int dest_size ) {
-
-       memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) );
-}
-
-/**
- * Finalise big integer
- *
- * @v value0           Element 0 of big integer to finalise
- * @v size             Number of elements
- * @v out              Output buffer
- * @v len              Length of output buffer
- */
-static inline __attribute__ (( always_inline )) void
-bigint_done_raw ( const uint32_t *value0, unsigned int size __unused,
-                 void *out, size_t len ) {
-       const uint8_t *value_byte = ( ( const void * ) value0 );
-       uint8_t *out_byte = ( out + len );
-
-       /* Copy raw data in reverse order */
-       while ( len-- )
-               *(--out_byte) = *(value_byte++);
-}
-
-extern void bigint_multiply_raw ( const uint32_t *multiplicand0,
-                                 const uint32_t *multiplier0,
-                                 uint32_t *value0, unsigned int size );
-
-#endif /* _BITS_BIGINT_H */
diff --git a/roms/ipxe/src/arch/arm32/include/bits/bitops.h b/roms/ipxe/src/arch/arm32/include/bits/bitops.h
deleted file mode 100644 (file)
index 9a5fe14..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef _BITS_BITOPS_H
-#define _BITS_BITOPS_H
-
-/** @file
- *
- * ARM bit operations
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-
-/**
- * Test and set bit atomically
- *
- * @v bit              Bit to set
- * @v bits             Bit field
- * @ret old            Old value of bit (zero or non-zero)
- */
-static inline __attribute__ (( always_inline )) int
-test_and_set_bit ( unsigned int bit, volatile void *bits ) {
-       unsigned int index = ( bit / 32 );
-       unsigned int offset = ( bit % 32 );
-       volatile uint32_t *dword = ( ( ( volatile uint32_t * ) bits ) + index );
-       uint32_t mask = ( 1UL << offset );
-       uint32_t old;
-       uint32_t new;
-       uint32_t flag;
-
-       __asm__ __volatile__ ( "\n1:\n\t"
-                              "ldrex %0, %3\n\t"
-                              "orr %1, %0, %4\n\t"
-                              "strex %2, %1, %3\n\t"
-                              "tst %2, %2\n\t"
-                              "bne 1b\n\t"
-                              : "=&r" ( old ), "=&r" ( new ), "=&l" ( flag ),
-                                "+Q" ( *dword )
-                              : "r" ( mask )
-                              : "cc" );
-
-       return ( old & mask );
-}
-
-/**
- * Test and clear bit atomically
- *
- * @v bit              Bit to set
- * @v bits             Bit field
- * @ret old            Old value of bit (zero or non-zero)
- */
-static inline __attribute__ (( always_inline )) int
-test_and_clear_bit ( unsigned int bit, volatile void *bits ) {
-       unsigned int index = ( bit / 32 );
-       unsigned int offset = ( bit % 32 );
-       volatile uint32_t *dword = ( ( ( volatile uint32_t * ) bits ) + index );
-       uint32_t mask = ( 1UL << offset );
-       uint32_t old;
-       uint32_t new;
-       uint32_t flag;
-
-       __asm__ __volatile__ ( "\n1:\n\t"
-                              "ldrex %0, %3\n\t"
-                              "bic %1, %0, %4\n\t"
-                              "strex %2, %1, %3\n\t"
-                              "tst %2, %2\n\t"
-                              "bne 1b\n\t"
-                              : "=&r" ( old ), "=&r" ( new ), "=&l" ( flag ),
-                                "+Q" ( *dword )
-                              : "r" ( mask )
-                              : "cc" );
-
-       return ( old & mask );
-}
-
-/**
- * Set bit atomically
- *
- * @v bit              Bit to set
- * @v bits             Bit field
- */
-static inline __attribute__ (( always_inline )) void
-set_bit ( unsigned int bit, volatile void *bits ) {
-
-       test_and_set_bit ( bit, bits );
-}
-
-/**
- * Clear bit atomically
- *
- * @v bit              Bit to set
- * @v bits             Bit field
- */
-static inline __attribute__ (( always_inline )) void
-clear_bit ( unsigned int bit, volatile void *bits ) {
-
-       test_and_clear_bit ( bit, bits );
-}
-
-#endif /* _BITS_BITOPS_H */
diff --git a/roms/ipxe/src/arch/arm32/include/bits/byteswap.h b/roms/ipxe/src/arch/arm32/include/bits/byteswap.h
deleted file mode 100644 (file)
index 1fc884b..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef _BITS_BYTESWAP_H
-#define _BITS_BYTESWAP_H
-
-/** @file
- *
- * Byte-order swapping functions
- *
- */
-
-#include <stdint.h>
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-static inline __attribute__ (( always_inline, const )) uint16_t
-__bswap_variable_16 ( uint16_t x ) {
-       __asm__ ( "rev16 %0, %1" : "=l" ( x ) : "l" ( x ) );
-       return x;
-}
-
-static inline __attribute__ (( always_inline )) void
-__bswap_16s ( uint16_t *x ) {
-       *x = __bswap_variable_16 ( *x );
-}
-
-static inline __attribute__ (( always_inline, const )) uint32_t
-__bswap_variable_32 ( uint32_t x ) {
-       __asm__ ( "rev %0, %1" : "=l" ( x ) : "l" ( x ) );
-       return x;
-}
-
-static inline __attribute__ (( always_inline )) void
-__bswap_32s ( uint32_t *x ) {
-       *x = __bswap_variable_32 ( *x );
-}
-
-static inline __attribute__ (( always_inline, const )) uint64_t
-__bswap_variable_64 ( uint64_t x ) {
-       uint32_t in_high = ( x >> 32 );
-       uint32_t in_low = ( x & 0xffffffffUL );
-       uint32_t out_high = __bswap_variable_32 ( in_low );
-       uint32_t out_low = __bswap_variable_32 ( in_high );
-
-       return ( ( ( ( uint64_t ) out_high ) << 32 ) |
-                ( ( uint64_t ) out_low ) );
-}
-
-static inline __attribute__ (( always_inline )) void
-__bswap_64s ( uint64_t *x ) {
-       *x = __bswap_variable_64 ( *x );
-}
-
-#endif
diff --git a/roms/ipxe/src/arch/arm32/include/bits/compiler.h b/roms/ipxe/src/arch/arm32/include/bits/compiler.h
deleted file mode 100644 (file)
index e420cf9..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _BITS_COMPILER_H
-#define _BITS_COMPILER_H
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** Dummy relocation type */
-#define RELOC_TYPE_NONE R_ARM_NONE
-
-#ifndef ASSEMBLY
-
-#define __asmcall
-#define __libgcc
-
-#endif /* ASSEMBLY */
-
-#endif /*_BITS_COMPILER_H */
diff --git a/roms/ipxe/src/arch/arm32/include/bits/profile.h b/roms/ipxe/src/arch/arm32/include/bits/profile.h
deleted file mode 100644 (file)
index 2b15d16..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _BITS_PROFILE_H
-#define _BITS_PROFILE_H
-
-/** @file
- *
- * Profiling
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-
-/**
- * Get profiling timestamp
- *
- * @ret timestamp      Timestamp
- */
-static inline __attribute__ (( always_inline )) uint64_t
-profile_timestamp ( void ) {
-       uint32_t cycles;
-
-       /* Read cycle counter */
-       __asm__ __volatile__ ( "mcr p15, 0, %1, c9, c12, 0\n\t"
-                              "mrc p15, 0, %0, c9, c13, 0\n\t"
-                              : "=r" ( cycles ) : "r" ( 1 ) );
-       return cycles;
-}
-
-#endif /* _BITS_PROFILE_H */
diff --git a/roms/ipxe/src/arch/arm32/include/bits/stdint.h b/roms/ipxe/src/arch/arm32/include/bits/stdint.h
deleted file mode 100644 (file)
index fe1f994..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _BITS_STDINT_H
-#define _BITS_STDINT_H
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-typedef __SIZE_TYPE__          size_t;
-typedef signed long            ssize_t;
-typedef signed long            off_t;
-
-typedef unsigned char          uint8_t;
-typedef unsigned short         uint16_t;
-typedef unsigned int           uint32_t;
-typedef unsigned long long     uint64_t;
-
-typedef signed char            int8_t;
-typedef signed short           int16_t;
-typedef signed int             int32_t;
-typedef signed long long       int64_t;
-
-typedef unsigned long          physaddr_t;
-typedef unsigned long          intptr_t;
-
-#endif /* _BITS_STDINT_H */
diff --git a/roms/ipxe/src/arch/arm32/include/bits/string.h b/roms/ipxe/src/arch/arm32/include/bits/string.h
deleted file mode 100644 (file)
index 5b1c150..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef BITS_STRING_H
-#define BITS_STRING_H
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * String functions
- *
- */
-
-/**
- * Fill memory region
- *
- * @v dest             Destination region
- * @v character                Fill character
- * @v len              Length
- * @ret dest           Destination region
- */
-static inline __attribute__ (( always_inline )) void *
-memset ( void *dest, int character, size_t len ) {
-
-       /* Not yet optimised */
-       generic_memset ( dest, character, len );
-       return dest;
-}
-
-/**
- * Copy memory region
- *
- * @v dest             Destination region
- * @v src              Source region
- * @v len              Length
- * @ret dest           Destination region
- */
-static inline __attribute__ (( always_inline )) void *
-memcpy ( void *dest, const void *src, size_t len ) {
-
-       /* Not yet optimised */
-       generic_memcpy ( dest, src, len );
-       return dest;
-}
-
-/**
- * Copy (possibly overlapping) memory region
- *
- * @v dest             Destination region
- * @v src              Source region
- * @v len              Length
- * @ret dest           Destination region
- */
-static inline __attribute__ (( always_inline )) void *
-memmove ( void *dest, const void *src, size_t len ) {
-
-       /* Not yet optimised */
-       generic_memmove ( dest, src, len );
-       return dest;
-}
-
-#endif /* BITS_STRING_H */
diff --git a/roms/ipxe/src/arch/arm32/include/bits/strings.h b/roms/ipxe/src/arch/arm32/include/bits/strings.h
deleted file mode 100644 (file)
index adbd5f4..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef _BITS_STRINGS_H
-#define _BITS_STRINGS_H
-
-/** @file
- *
- * String functions
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/**
- * Find first (i.e. least significant) set bit
- *
- * @v value            Value
- * @ret lsb            Least significant bit set in value (LSB=1), or zero
- */
-static inline __attribute__ (( always_inline )) int __ffsl ( long value ) {
-       unsigned long bits = value;
-       unsigned long lsb;
-       unsigned int lz;
-
-       /* Extract least significant set bit */
-       lsb = ( bits & -bits );
-
-       /* Count number of leading zeroes before LSB */
-       __asm__ ( "clz %0, %1" : "=r" ( lz ) : "r" ( lsb ) );
-
-       return ( 32 - lz );
-}
-
-/**
- * Find first (i.e. least significant) set bit
- *
- * @v value            Value
- * @ret lsb            Least significant bit set in value (LSB=1), or zero
- */
-static inline __attribute__ (( always_inline )) int __ffsll ( long long value ){
-       unsigned long high = ( value >> 32 );
-       unsigned long low = ( value >> 0 );
-
-       if ( low ) {
-               return ( __ffsl ( low ) );
-       } else if ( high ) {
-               return ( 32 + __ffsl ( high ) );
-       } else {
-               return 0;
-       }
-}
-
-/**
- * Find last (i.e. most significant) set bit
- *
- * @v value            Value
- * @ret msb            Most significant bit set in value (LSB=1), or zero
- */
-static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
-       unsigned int lz;
-
-       /* Count number of leading zeroes */
-       __asm__ ( "clz %0, %1" : "=r" ( lz ) : "r" ( value ) );
-
-       return ( 32 - lz );
-}
-
-/**
- * Find last (i.e. most significant) set bit
- *
- * @v value            Value
- * @ret msb            Most significant bit set in value (LSB=1), or zero
- */
-static inline __attribute__ (( always_inline )) int __flsll ( long long value ){
-       unsigned long high = ( value >> 32 );
-       unsigned long low = ( value >> 0 );
-
-       if ( high ) {
-               return ( 32 + __flsl ( high ) );
-       } else if ( low ) {
-               return ( __flsl ( low ) );
-       } else {
-               return 0;
-       }
-}
-
-#endif /* _BITS_STRINGS_H */
diff --git a/roms/ipxe/src/arch/arm32/include/bits/tcpip.h b/roms/ipxe/src/arch/arm32/include/bits/tcpip.h
deleted file mode 100644 (file)
index fc3c5b3..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _BITS_TCPIP_H
-#define _BITS_TCPIP_H
-
-/** @file
- *
- * Transport-network layer interface
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-static inline __attribute__ (( always_inline )) uint16_t
-tcpip_continue_chksum ( uint16_t partial, const void *data, size_t len ) {
-
-       /* Not yet optimised */
-       return generic_tcpip_continue_chksum ( partial, data, len );
-}
-
-#endif /* _BITS_TCPIP_H */
diff --git a/roms/ipxe/src/arch/arm32/include/efi/ipxe/dhcp_arch.h b/roms/ipxe/src/arch/arm32/include/efi/ipxe/dhcp_arch.h
deleted file mode 100644 (file)
index f9baab4..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-#ifndef _DHCP_ARCH_H
-#define _DHCP_ARCH_H
-
-/** @file
- *
- * Architecture-specific DHCP options
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/dhcp.h>
-
-#define DHCP_ARCH_VENDOR_CLASS_ID \
-       DHCP_STRING ( 'P', 'X', 'E', 'C', 'l', 'i', 'e', 'n', 't', ':',      \
-                     'A', 'r', 'c', 'h', ':', '0', '0', '0', '0', '7', ':', \
-                     'U', 'N', 'D', 'I', ':', '0', '0', '3', '0', '1', '0' )
-
-#define DHCP_ARCH_CLIENT_ARCHITECTURE \
-       DHCP_WORD ( DHCP_CLIENT_ARCHITECTURE_ARM32 )
-
-#define DHCP_ARCH_CLIENT_NDI DHCP_OPTION ( 1 /* UNDI */ , 3, 10 /* v3.10 */ )
-
-#endif
diff --git a/roms/ipxe/src/arch/arm32/include/gdbmach.h b/roms/ipxe/src/arch/arm32/include/gdbmach.h
deleted file mode 100644 (file)
index cd152ee..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef GDBMACH_H
-#define GDBMACH_H
-
-/** @file
- *
- * GDB architecture specifics
- *
- * This file declares functions for manipulating the machine state and
- * debugging context.
- *
- */
-
-#include <stdint.h>
-
-typedef unsigned long gdbreg_t;
-
-/* Register snapshot */
-enum {
-       /* Not yet implemented */
-       GDBMACH_NREGS,
-};
-
-#define GDBMACH_SIZEOF_REGS ( GDBMACH_NREGS * sizeof ( gdbreg_t ) )
-
-static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) {
-       /* Not yet implemented */
-       ( void ) regs;
-       ( void ) pc;
-}
-
-static inline void gdbmach_set_single_step ( gdbreg_t *regs, int step ) {
-       /* Not yet implemented */
-       ( void ) regs;
-       ( void ) step;
-}
-
-static inline void gdbmach_breakpoint ( void ) {
-       /* Not yet implemented */
-}
-
-extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len,
-                                   int enable );
-extern void gdbmach_init ( void );
-
-#endif /* GDBMACH_H */
diff --git a/roms/ipxe/src/arch/arm32/include/limits.h b/roms/ipxe/src/arch/arm32/include/limits.h
deleted file mode 100644 (file)
index bb48b75..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef LIMITS_H
-#define LIMITS_H       1
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/* Number of bits in a `char' */
-#define CHAR_BIT       8
-
-/* Minimum and maximum values a `signed char' can hold */
-#define SCHAR_MIN      (-128)
-#define SCHAR_MAX      127
-
-/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */
-#define UCHAR_MAX      255
-
-/* Minimum and maximum values a `char' can hold */
-#define CHAR_MIN       SCHAR_MIN
-#define CHAR_MAX       SCHAR_MAX
-
-/* Minimum and maximum values a `signed short int' can hold */
-#define SHRT_MIN       (-32768)
-#define SHRT_MAX       32767
-
-/* Maximum value an `unsigned short' can hold. (Minimum is 0.) */
-#define USHRT_MAX      65535
-
-
-/* Minimum and maximum values a `signed int' can hold */
-#define INT_MIN                (-INT_MAX - 1)
-#define INT_MAX                2147483647
-
-/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
-#define UINT_MAX       4294967295U
-
-
-/* Minimum and maximum values a `signed int' can hold */
-#define INT_MAX                2147483647
-#define INT_MIN                (-INT_MAX - 1)
-
-
-/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
-#define UINT_MAX       4294967295U
-
-
-/* Minimum and maximum values a `signed long' can hold */
-#define LONG_MAX       2147483647
-#define LONG_MIN       (-LONG_MAX - 1L)
-
-/* Maximum value an `unsigned long' can hold. (Minimum is 0.) */
-#define ULONG_MAX      4294967295UL
-
-/* Minimum and maximum values a `signed long long' can hold */
-#define LLONG_MAX      9223372036854775807LL
-#define LLONG_MIN      (-LONG_MAX - 1LL)
-
-
-/* Maximum value an `unsigned long long' can hold. (Minimum is 0.) */
-#define ULLONG_MAX     18446744073709551615ULL
-
-
-#endif /* LIMITS_H */
diff --git a/roms/ipxe/src/arch/arm32/include/setjmp.h b/roms/ipxe/src/arch/arm32/include/setjmp.h
deleted file mode 100644 (file)
index 4828b47..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _SETJMP_H
-#define _SETJMP_H
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-
-/** A jump buffer */
-typedef struct {
-       /** Saved r4 */
-       uint32_t r4;
-       /** Saved r5 */
-       uint32_t r5;
-       /** Saved r6 */
-       uint32_t r6;
-       /** Saved r7 */
-       uint32_t r7;
-       /** Saved r8 */
-       uint32_t r8;
-       /** Saved r9 */
-       uint32_t r9;
-       /** Saved r10 */
-       uint32_t r10;
-       /** Saved frame pointer (r11) */
-       uint32_t fp;
-       /** Saved stack pointer (r13) */
-       uint32_t sp;
-       /** Saved link register (r14) */
-       uint32_t lr;
-} jmp_buf[1];
-
-extern int __asmcall __attribute__ (( returns_twice ))
-setjmp ( jmp_buf env );
-
-extern void __asmcall __attribute__ (( noreturn ))
-longjmp ( jmp_buf env, int val );
-
-#endif /* _SETJMP_H */
diff --git a/roms/ipxe/src/arch/arm32/libgcc/lldivmod.S b/roms/ipxe/src/arch/arm32/libgcc/lldivmod.S
deleted file mode 100644 (file)
index 910be4b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
-
-       .text
-       .thumb
-
-/**
- * Unsigned long long division
- *
- * @v r1:r0            Dividend
- * @v r3:r2            Divisor
- * @ret r1:r0          Quotient
- * @ret r3:r2          Remainder
- */
-       .section ".text.__aeabi_uldivmod", "ax", %progbits
-       .globl  __aeabi_uldivmod
-       .type   __aeabi_uldivmod, %function
-__aeabi_uldivmod:
-       /* Allocate stack space for remainder and pointer to remainder */
-       push    {r0, r1, r2, r3, r4, lr}
-       /* Call __udivmoddi4() */
-       add     r4, sp, #8
-       str     r4, [sp]
-       bl      __udivmoddi4
-       /* Retrieve remainder and return */
-       add     sp, sp, #8
-       pop     {r2, r3, r4, pc}
-       .size   __aeabi_uldivmod, . - __aeabi_uldivmod
-
-/**
- * Signed long long division
- *
- * @v r1:r0            Dividend
- * @v r3:r2            Divisor
- * @ret r1:r0          Quotient
- * @ret r3:r2          Remainder
- */
-       .section ".text.__aeabi_ldivmod", "ax", %progbits
-       .globl  __aeabi_ldivmod
-       .type   __aeabi_ldivmod, %function
-__aeabi_ldivmod:
-       /* Allocate stack space for remainder and pointer to remainder */
-       push    {r0, r1, r2, r3, r4, lr}
-       /* Call __divmoddi4() */
-       add     r4, sp, #8
-       str     r4, [sp]
-       bl      __divmoddi4
-       /* Retrieve remainder and return */
-       add     sp, sp, #8
-       pop     {r2, r3, r4, pc}
-       .size   __aeabi_ldivmod, . - __aeabi_ldivmod
diff --git a/roms/ipxe/src/arch/arm32/libgcc/llshift.S b/roms/ipxe/src/arch/arm32/libgcc/llshift.S
deleted file mode 100644 (file)
index cc16e26..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
-
-       .text
-       .arm
-
-/**
- * Logical shift left
- *
- * @v r1:r0            Value to shift
- * @v r2               Shift amount
- * @ret r1:r0          Shifted value
- */
-       .section ".text.__aeabi_llsl", "ax", %progbits
-       .globl  __aeabi_llsl
-       .type   __aeabi_llsl, %function
-__aeabi_llsl:
-       /* r3 = ( shift - 32 ) */
-       subs    r3, r2, #32
-       /* If shift >= 32, then
-        *   high = ( low << ( shift - 32 ) )
-        */
-       movpl   r1, r0, lsl r3
-       /* If shift < 32, then
-        *   high = ( ( high << shift ) | ( low >> ( 32 - shift ) ) )
-        */
-       movmi   r1, r1, lsl r2
-       rsbmi   r3, r2, #32
-       orrmi   r1, r1, r0, lsr r3
-       /* low = ( low << shift ) */
-       mov     r0, r0, lsl r2
-       bx      lr
-       .size   __aeabi_llsl, . - __aeabi_llsl
-
-/**
- * Logical shift right
- *
- * @v r1:r0            Value to shift
- * @v r2               Shift amount
- * @ret r1:r0          Shifted value
- */
-       .section ".text.__aeabi_llsr", "ax", %progbits
-       .globl  __aeabi_llsr
-       .type   __aeabi_llsr, %function
-__aeabi_llsr:
-       /* r3 = ( shift - 32 ) */
-       subs    r3, r2, #32
-       /* If shift >= 32, then
-        *   low = ( high >> ( shift - 32 ) )
-        */
-       movpl   r0, r1, lsr r3
-       /* If shift < 32, then
-        *   low = ( ( low >> shift ) | ( high << ( 32 - shift ) ) )
-        */
-       movmi   r0, r0, lsr r2
-       rsbmi   r3, r2, #32
-       orrmi   r0, r0, r1, lsl r3
-       /* high = ( high >> shift ) */
-       mov     r1, r1, lsr r2
-       bx      lr
-       .size   __aeabi_llsr, . - __aeabi_llsr
-
-/**
- * Arithmetic shift right
- *
- * @v r1:r0            Value to shift
- * @v r2               Shift amount
- * @ret r1:r0          Shifted value
- */
-       .section ".text.__aeabi_lasr", "ax", %progbits
-       .globl  __aeabi_lasr
-       .type   __aeabi_lasr, %function
-__aeabi_lasr:
-       /* r3 = ( shift - 32 ) */
-       subs    r3, r2, #32
-       /* If shift >= 32, then
-        *   low = ( high >> ( shift - 32 ) )
-        */
-       movpl   r0, r1, asr r3
-       /* If shift < 32, then
-        *   low = ( ( low >> shift ) | ( high << ( 32 - shift ) ) )
-        */
-       movmi   r0, r0, lsr r2
-       rsbmi   r3, r2, #32
-       orrmi   r0, r0, r1, lsl r3
-       /* high = ( high >> shift ) */
-       mov     r1, r1, asr r2
-       bx      lr
-       .size   __aeabi_lasr, . - __aeabi_lasr
diff --git a/roms/ipxe/src/arch/arm64/Makefile b/roms/ipxe/src/arch/arm64/Makefile
deleted file mode 100644 (file)
index d121871..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# ARM64-specific directories containing source files
-#
-SRCDIRS                += arch/arm64/core
-
-# ARM64-specific flags
-#
-CFLAGS         += -mabi=lp64 -mlittle-endian -mcmodel=small
-CFLAGS         += -fomit-frame-pointer
-ASFLAGS                += -mabi=lp64 -EL
-
-# EFI requires -fshort-wchar, and nothing else currently uses wchar_t
-#
-CFLAGS         += -fshort-wchar
-
-# Include common ARM Makefile
-MAKEDEPS       += arch/arm/Makefile
-include arch/arm/Makefile
-
-# Include platform-specific Makefile
-#
-MAKEDEPS       += arch/arm64/Makefile.$(PLATFORM)
-include arch/arm64/Makefile.$(PLATFORM)
diff --git a/roms/ipxe/src/arch/arm64/Makefile.efi b/roms/ipxe/src/arch/arm64/Makefile.efi
deleted file mode 100644 (file)
index 998a64d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# -*- makefile -*- : Force emacs to use Makefile mode
-
-# Specify EFI image builder
-#
-ELF2EFI                = $(ELF2EFI64)
-
-# Specify EFI boot file
-#
-EFI_BOOT_FILE  = bootaa64.efi
-
-# Include generic EFI Makefile
-#
-MAKEDEPS       += arch/arm/Makefile.efi
-include arch/arm/Makefile.efi
diff --git a/roms/ipxe/src/arch/arm64/core/arm64_bigint.c b/roms/ipxe/src/arch/arm64/core/arm64_bigint.c
deleted file mode 100644 (file)
index bc4ee9a..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <string.h>
-#include <ipxe/bigint.h>
-
-/** @file
- *
- * Big integer support
- */
-
-/**
- * Multiply big integers
- *
- * @v multiplicand0    Element 0 of big integer to be multiplied
- * @v multiplier0      Element 0 of big integer to be multiplied
- * @v result0          Element 0 of big integer to hold result
- * @v size             Number of elements
- */
-void bigint_multiply_raw ( const uint64_t *multiplicand0,
-                          const uint64_t *multiplier0,
-                          uint64_t *result0, unsigned int size ) {
-       const bigint_t ( size ) __attribute__ (( may_alias )) *multiplicand =
-               ( ( const void * ) multiplicand0 );
-       const bigint_t ( size ) __attribute__ (( may_alias )) *multiplier =
-               ( ( const void * ) multiplier0 );
-       bigint_t ( size * 2 ) __attribute__ (( may_alias )) *result =
-               ( ( void * ) result0 );
-       unsigned int i;
-       unsigned int j;
-       uint64_t multiplicand_element;
-       uint64_t multiplier_element;
-       uint64_t *result_elements;
-       uint64_t discard_low;
-       uint64_t discard_high;
-       uint64_t discard_temp_low;
-       uint64_t discard_temp_high;
-
-       /* Zero result */
-       memset ( result, 0, sizeof ( *result ) );
-
-       /* Multiply integers one element at a time */
-       for ( i = 0 ; i < size ; i++ ) {
-               multiplicand_element = multiplicand->element[i];
-               for ( j = 0 ; j < size ; j++ ) {
-                       multiplier_element = multiplier->element[j];
-                       result_elements = &result->element[ i + j ];
-                       /* Perform a single multiply, and add the
-                        * resulting double-element into the result,
-                        * carrying as necessary.  The carry can
-                        * never overflow beyond the end of the
-                        * result, since:
-                        *
-                        *     a < 2^{n}, b < 2^{n} => ab < 2^{2n}
-                        */
-                       __asm__ __volatile__ ( "mul %1, %6, %7\n\t"
-                                              "umulh %2, %6, %7\n\t"
-                                              "ldp %3, %4, [%0]\n\t"
-                                              "adds %3, %3, %1\n\t"
-                                              "adcs %4, %4, %2\n\t"
-                                              "stp %3, %4, [%0], #16\n\t"
-                                              "bcc 2f\n\t"
-                                              "\n1:\n\t"
-                                              "ldr %3, [%0]\n\t"
-                                              "adcs %3, %3, xzr\n\t"
-                                              "str %3, [%0], #8\n\t"
-                                              "bcs 1b\n\t"
-                                              "\n2:\n\t"
-                                              : "+r" ( result_elements ),
-                                                "=&r" ( discard_low ),
-                                                "=&r" ( discard_high ),
-                                                "=r" ( discard_temp_low ),
-                                                "=r" ( discard_temp_high ),
-                                                "+m" ( *result )
-                                              : "r" ( multiplicand_element ),
-                                                "r" ( multiplier_element )
-                                              : "cc" );
-               }
-       }
-}
diff --git a/roms/ipxe/src/arch/arm64/core/arm64_string.c b/roms/ipxe/src/arch/arm64/core/arm64_string.c
deleted file mode 100644 (file)
index 28a2b73..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-/** @file
- *
- * Optimised string operations
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <string.h>
-
-/**
- * Copy memory area
- *
- * @v dest             Destination address
- * @v src              Source address
- * @v len              Length
- * @ret dest           Destination address
- */
-void arm64_memcpy ( void *dest, const void *src, size_t len ) {
-       void *discard_dest;
-       void *discard_end;
-       const void *discard_src;
-       size_t discard_offset;
-       unsigned long discard_data;
-       unsigned long discard_low;
-       unsigned long discard_high;
-
-       /* If length is too short for an "ldp"/"stp" instruction pair,
-        * then just copy individual bytes.
-        */
-       if ( len < 16 ) {
-               __asm__ __volatile__ ( "cbz %0, 2f\n\t"
-                                      "\n1:\n\t"
-                                      "sub %0, %0, #1\n\t"
-                                      "ldrb %w1, [%3, %0]\n\t"
-                                      "strb %w1, [%2, %0]\n\t"
-                                      "cbnz %0, 1b\n\t"
-                                      "\n2:\n\t"
-                                      : "=&r" ( discard_offset ),
-                                        "=&r" ( discard_data )
-                                      : "r" ( dest ), "r" ( src ), "0" ( len )
-                                      : "memory" );
-               return;
-       }
-
-       /* Use "ldp"/"stp" to copy 16 bytes at a time: one initial
-        * potentially unaligned access, multiple destination-aligned
-        * accesses, one final potentially unaligned access.
-        */
-       __asm__ __volatile__ ( "ldp %3, %4, [%1], #16\n\t"
-                              "stp %3, %4, [%0], #16\n\t"
-                              "and %3, %0, #15\n\t"
-                              "sub %0, %0, %3\n\t"
-                              "sub %1, %1, %3\n\t"
-                              "bic %2, %5, #15\n\t"
-                              "b 2f\n\t"
-                              "\n1:\n\t"
-                              "ldp %3, %4, [%1], #16\n\t"
-                              "stp %3, %4, [%0], #16\n\t"
-                              "\n2:\n\t"
-                              "cmp %0, %2\n\t"
-                              "bne 1b\n\t"
-                              "ldp %3, %4, [%6, #-16]\n\t"
-                              "stp %3, %4, [%5, #-16]\n\t"
-                              : "=&r" ( discard_dest ),
-                                "=&r" ( discard_src ),
-                                "=&r" ( discard_end ),
-                                "=&r" ( discard_low ),
-                                "=&r" ( discard_high )
-                              : "r" ( dest + len ), "r" ( src + len ),
-                                "0" ( dest ), "1" ( src )
-                              : "memory", "cc" );
-}
-
-/**
- * Zero memory region
- *
- * @v dest             Destination region
- * @v len              Length
- */
-void arm64_bzero ( void *dest, size_t len ) {
-       size_t discard_offset;
-       void *discard_dest;
-       void *discard_end;
-
-       /* If length is too short for an "stp" instruction, then just
-        * zero individual bytes.
-        */
-       if ( len < 16 ) {
-               __asm__ __volatile__ ( "cbz %0, 2f\n\t"
-                                      "\n1:\n\t"
-                                      "sub %0, %0, #1\n\t"
-                                      "strb wzr, [%1, %0]\n\t"
-                                      "cbnz %0, 1b\n\t"
-                                      "\n2:\n\t"
-                                      : "=&r" ( discard_offset )
-                                      : "r" ( dest ), "0" ( len )
-                                      : "memory" );
-               return;
-       }
-
-       /* Use "stp" to zero 16 bytes at a time: one initial
-        * potentially unaligned access, multiple aligned accesses,
-        * one final potentially unaligned access.
-        */
-       __asm__ __volatile__ ( "stp xzr, xzr, [%0], #16\n\t"
-                              "bic %0, %0, #15\n\t"
-                              "bic %1, %2, #15\n\t"
-                              "b 2f\n\t"
-                              "\n1:\n\t"
-                              "stp xzr, xzr, [%0], #16\n\t"
-                              "\n2:\n\t"
-                              "cmp %0, %1\n\t"
-                              "bne 1b\n\t"
-                              "stp xzr, xzr, [%2, #-16]\n\t"
-                              : "=&r" ( discard_dest ),
-                                "=&r" ( discard_end )
-                              : "r" ( dest + len ), "0" ( dest )
-                              : "memory", "cc" );
-}
-
-/**
- * Fill memory region
- *
- * @v dest             Destination region
- * @v len              Length
- * @v character                Fill character
- *
- * The unusual parameter order is to allow for more efficient
- * tail-calling to arm64_memset() when zeroing a region.
- */
-void arm64_memset ( void *dest, size_t len, int character ) {
-       size_t discard_offset;
-
-       /* Use optimised zeroing code if applicable */
-       if ( character == 0 ) {
-               arm64_bzero ( dest, len );
-               return;
-       }
-
-       /* Fill one byte at a time.  Calling memset() with a non-zero
-        * value is relatively rare and unlikely to be
-        * performance-critical.
-        */
-       __asm__ __volatile__ ( "cbz %0, 2f\n\t"
-                              "\n1:\n\t"
-                              "sub %0, %0, #1\n\t"
-                              "strb %w2, [%1, %0]\n\t"
-                              "cbnz %0, 1b\n\t"
-                              "\n2:\n\t"
-                              : "=&r" ( discard_offset )
-                              : "r" ( dest ), "r" ( character ), "0" ( len )
-                              : "memory" );
-}
-
-/**
- * Copy (possibly overlapping) memory region forwards
- *
- * @v dest             Destination region
- * @v src              Source region
- * @v len              Length
- */
-void arm64_memmove_forwards ( void *dest, const void *src, size_t len ) {
-       void *discard_dest;
-       const void *discard_src;
-       unsigned long discard_data;
-
-       /* Assume memmove() is not performance-critical, and perform a
-        * bytewise copy for simplicity.
-        */
-       __asm__ __volatile__ ( "b 2f\n\t"
-                              "\n1:\n\t"
-                              "ldrb %w2, [%1], #1\n\t"
-                              "strb %w2, [%0], #1\n\t"
-                              "\n2:\n\t"
-                              "cmp %0, %3\n\t"
-                              "bne 1b\n\t"
-                              : "=&r" ( discard_dest ),
-                                "=&r" ( discard_src ),
-                                "=&r" ( discard_data )
-                              : "r" ( dest + len ), "0" ( dest ), "1" ( src )
-                              : "memory" );
-}
-
-/**
- * Copy (possibly overlapping) memory region backwards
- *
- * @v dest             Destination region
- * @v src              Source region
- * @v len              Length
- */
-void arm64_memmove_backwards ( void *dest, const void *src, size_t len ) {
-       size_t discard_offset;
-       unsigned long discard_data;
-
-       /* Assume memmove() is not performance-critical, and perform a
-        * bytewise copy for simplicity.
-        */
-       __asm__ __volatile__ ( "cbz %0, 2f\n\t"
-                              "\n1:\n\t"
-                              "sub %0, %0, #1\n\t"
-                              "ldrb %w1, [%3, %0]\n\t"
-                              "strb %w1, [%2, %0]\n\t"
-                              "cbnz %0, 1b\n\t"
-                              "\n2:\n\t"
-                              : "=&r" ( discard_offset ),
-                                "=&r" ( discard_data )
-                              : "r" ( dest ), "r" ( src ), "0" ( len )
-                              : "memory" );
-}
-
-/**
- * Copy (possibly overlapping) memory region
- *
- * @v dest             Destination region
- * @v src              Source region
- * @v len              Length
- */
-void arm64_memmove ( void *dest, const void *src, size_t len ) {
-
-       if ( dest <= src ) {
-               arm64_memmove_forwards ( dest, src, len );
-       } else {
-               arm64_memmove_backwards ( dest, src, len );
-       }
-}
diff --git a/roms/ipxe/src/arch/arm64/core/arm64_tcpip.c b/roms/ipxe/src/arch/arm64/core/arm64_tcpip.c
deleted file mode 100644 (file)
index 0ef04ea..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * TCP/IP checksum
- *
- */
-
-#include <strings.h>
-#include <ipxe/tcpip.h>
-
-/** Alignment used by main checksumming loop */
-#define TCPIP_CHKSUM_ALIGN 16
-
-/** Number of steps in each iteration of the unrolled main checksumming loop */
-#define TCPIP_CHKSUM_UNROLL 4
-
-/**
- * Calculate continued TCP/IP checkum
- *
- * @v sum              Checksum of already-summed data, in network byte order
- * @v data             Data buffer
- * @v len              Length of data buffer
- * @ret sum            Updated checksum, in network byte order
- */
-uint16_t tcpip_continue_chksum ( uint16_t sum, const void *data,
-                                size_t len ) {
-       intptr_t start;
-       intptr_t end;
-       intptr_t mid;
-       unsigned int pre;
-       unsigned int post;
-       unsigned int first;
-       uint64_t discard_low;
-       uint64_t discard_high;
-
-       /* Avoid potentially undefined shift operation */
-       if ( len == 0 )
-               return sum;
-
-       /* Find maximally-aligned midpoint.  For short blocks of data,
-        * this may be aligned to fewer than 16 bytes.
-        */
-       start = ( ( intptr_t ) data );
-       end = ( start + len );
-       mid = ( end &
-               ~( ( ~( 1UL << 63 ) ) >> ( 64 - flsl ( start ^ end ) ) ) );
-
-       /* Calculate pre- and post-alignment lengths */
-       pre = ( ( mid - start ) & ( TCPIP_CHKSUM_ALIGN - 1 ) );
-       post = ( ( end - mid ) & ( TCPIP_CHKSUM_ALIGN - 1 ) );
-
-       /* Calculate number of steps in first iteration of unrolled loop */
-       first = ( ( ( len - pre - post ) / TCPIP_CHKSUM_ALIGN ) &
-                 ( TCPIP_CHKSUM_UNROLL - 1 ) );
-
-       /* Calculate checksum */
-       __asm__ ( /* Invert sum */
-                 "eor %w0, %w0, #0xffff\n\t"
-                 /* Clear carry flag */
-                 "cmn xzr, xzr\n\t"
-                 /* Byteswap and sum pre-alignment byte, if applicable */
-                 "tbz %w4, #0, 1f\n\t"
-                 "ldrb %w2, [%1], #1\n\t"
-                 "rev16 %w0, %w0\n\t"
-                 "rev16 %w2, %w2\n\t"
-                 "adcs %0, %0, %2\n\t"
-                 "\n1:\n\t"
-                 /* Sum pre-alignment halfword, if applicable */
-                 "tbz %w4, #1, 1f\n\t"
-                 "ldrh %w2, [%1], #2\n\t"
-                 "adcs %0, %0, %2\n\t"
-                 "\n1:\n\t"
-                 /* Sum pre-alignment word, if applicable */
-                 "tbz %w4, #2, 1f\n\t"
-                 "ldr %w2, [%1], #4\n\t"
-                 "adcs %0, %0, %2\n\t"
-                 "\n1:\n\t"
-                 /* Sum pre-alignment doubleword, if applicable */
-                 "tbz %w4, #3, 1f\n\t"
-                 "ldr %2, [%1], #8\n\t"
-                 "adcs %0, %0, %2\n\t"
-                 "\n1:\n\t"
-                 /* Jump into unrolled (x4) main loop */
-                 "adr %2, 2f\n\t"
-                 "sub %2, %2, %5, lsl #3\n\t"
-                 "sub %2, %2, %5, lsl #2\n\t"
-                 "br %2\n\t"
-                 "\n1:\n\t"
-                 "ldp %2, %3, [%1], #16\n\t"
-                 "adcs %0, %0, %2\n\t"
-                 "adcs %0, %0, %3\n\t"
-                 "ldp %2, %3, [%1], #16\n\t"
-                 "adcs %0, %0, %2\n\t"
-                 "adcs %0, %0, %3\n\t"
-                 "ldp %2, %3, [%1], #16\n\t"
-                 "adcs %0, %0, %2\n\t"
-                 "adcs %0, %0, %3\n\t"
-                 "ldp %2, %3, [%1], #16\n\t"
-                 "adcs %0, %0, %2\n\t"
-                 "adcs %0, %0, %3\n\t"
-                 "\n2:\n\t"
-                 "sub %2, %1, %6\n\t"
-                 "cbnz %2, 1b\n\t"
-                 /* Sum post-alignment doubleword, if applicable */
-                 "tbz %w7, #3, 1f\n\t"
-                 "ldr %2, [%1], #8\n\t"
-                 "adcs %0, %0, %2\n\t"
-                 "\n1:\n\t"
-                 /* Sum post-alignment word, if applicable */
-                 "tbz %w7, #2, 1f\n\t"
-                 "ldr %w2, [%1], #4\n\t"
-                 "adcs %0, %0, %2\n\t"
-                 "\n1:\n\t"
-                 /* Sum post-alignment halfword, if applicable */
-                 "tbz %w7, #1, 1f\n\t"
-                 "ldrh %w2, [%1], #2\n\t"
-                 "adcs %0, %0, %2\n\t"
-                 "\n1:\n\t"
-                 /* Sum post-alignment byte, if applicable */
-                 "tbz %w7, #0, 1f\n\t"
-                 "ldrb %w2, [%1], #1\n\t"
-                 "adcs %0, %0, %2\n\t"
-                 "\n1:\n\t"
-                 /* Fold down to a uint32_t plus carry flag */
-                 "lsr %2, %0, #32\n\t"
-                 "adcs %w0, %w0, %w2\n\t"
-                 /* Fold down to a uint16_t plus carry in bit 16 */
-                 "ubfm %2, %0, #0, #15\n\t"
-                 "ubfm %3, %0, #16, #31\n\t"
-                 "adc %w0, %w2, %w3\n\t"
-                 /* Fold down to a uint16_t */
-                 "tbz %w0, #16, 1f\n\t"
-                 "mov %w2, #0xffff\n\t"
-                 "sub %w0, %w0, %w2\n\t"
-                 "tbz %w0, #16, 1f\n\t"
-                 "sub %w0, %w0, %w2\n\t"
-                 "\n1:\n\t"
-                 /* Byteswap back, if applicable */
-                 "tbz %w4, #0, 1f\n\t"
-                 "rev16 %w0, %w0\n\t"
-                 "\n1:\n\t"
-                 /* Invert sum */
-                 "eor %w0, %w0, #0xffff\n\t"
-                 : "+r" ( sum ), "+r" ( data ), "=&r" ( discard_low ),
-                   "=&r" ( discard_high )
-                 : "r" ( pre ), "r" ( first ), "r" ( end - post ),
-                   "r" ( post )
-                 : "cc" );
-
-       return sum;
-}
diff --git a/roms/ipxe/src/arch/arm64/core/setjmp.S b/roms/ipxe/src/arch/arm64/core/setjmp.S
deleted file mode 100644 (file)
index fa47aa0..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
-
-       .text
-
-       /* Must match jmp_buf structure layout */
-       .struct 0
-env_x19_x20:   .quad   0, 0
-env_x21_x22:   .quad   0, 0
-env_x23_x24:   .quad   0, 0
-env_x25_x26:   .quad   0, 0
-env_x27_x28:   .quad   0, 0
-env_x29_x30:   .quad   0, 0
-env_sp:                .quad   0
-       .previous
-
-/*
- * Save stack context for non-local goto
- */
-       .globl  setjmp
-       .type   setjmp, %function
-setjmp:
-       /* Store registers */
-       stp     x19, x20, [x0, #env_x19_x20]
-       stp     x21, x22, [x0, #env_x21_x22]
-       stp     x23, x24, [x0, #env_x23_x24]
-       stp     x25, x26, [x0, #env_x25_x26]
-       stp     x27, x28, [x0, #env_x27_x28]
-       stp     x29, x30, [x0, #env_x29_x30]
-       mov     x16, sp
-       str     x16, [x0, #env_sp]
-       /* Return 0 when returning as setjmp() */
-       mov     x0, #0
-       ret
-       .size   setjmp, . - setjmp
-
-/*
- * Non-local jump to a saved stack context
- */
-       .globl  longjmp
-       .type   longjmp, %function
-longjmp:
-       /* Restore registers */
-       ldp     x19, x20, [x0, #env_x19_x20]
-       ldp     x21, x22, [x0, #env_x21_x22]
-       ldp     x23, x24, [x0, #env_x23_x24]
-       ldp     x25, x26, [x0, #env_x25_x26]
-       ldp     x27, x28, [x0, #env_x27_x28]
-       ldp     x29, x30, [x0, #env_x29_x30]
-       ldr     x16, [x0, #env_sp]
-       mov     sp, x16
-       /* Force result to non-zero */
-       cmp     w1, #0
-       csinc   w0, w1, w1, ne
-       /* Return to setjmp() caller */
-       br      x30
-       .size   longjmp, . - longjmp
diff --git a/roms/ipxe/src/arch/arm64/include/bits/bigint.h b/roms/ipxe/src/arch/arm64/include/bits/bigint.h
deleted file mode 100644 (file)
index 79983b4..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-#ifndef _BITS_BIGINT_H
-#define _BITS_BIGINT_H
-
-/** @file
- *
- * Big integer support
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <string.h>
-#include <strings.h>
-
-/** Element of a big integer */
-typedef uint64_t bigint_element_t;
-
-/**
- * Initialise big integer
- *
- * @v value0           Element 0 of big integer to initialise
- * @v size             Number of elements
- * @v data             Raw data
- * @v len              Length of raw data
- */
-static inline __attribute__ (( always_inline )) void
-bigint_init_raw ( uint64_t *value0, unsigned int size,
-                 const void *data, size_t len ) {
-       size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len );
-       uint8_t *value_byte = ( ( void * ) value0 );
-       const uint8_t *data_byte = ( data + len );
-
-       /* Copy raw data in reverse order, padding with zeros */
-       while ( len-- )
-               *(value_byte++) = *(--data_byte);
-       while ( pad_len-- )
-               *(value_byte++) = 0;
-}
-
-/**
- * Add big integers
- *
- * @v addend0          Element 0 of big integer to add
- * @v value0           Element 0 of big integer to be added to
- * @v size             Number of elements
- */
-static inline __attribute__ (( always_inline )) void
-bigint_add_raw ( const uint64_t *addend0, uint64_t *value0,
-                unsigned int size ) {
-       bigint_t ( size ) __attribute__ (( may_alias )) *value =
-               ( ( void * ) value0 );
-       uint64_t *discard_addend;
-       uint64_t *discard_value;
-       uint64_t discard_addend_i;
-       uint64_t discard_value_i;
-       unsigned int discard_size;
-
-       __asm__ __volatile__ ( "cmn xzr, xzr\n\t" /* clear CF */
-                              "\n1:\n\t"
-                              "ldr %3, [%0], #8\n\t"
-                              "ldr %4, [%1]\n\t"
-                              "adcs %4, %4, %3\n\t"
-                              "str %4, [%1], #8\n\t"
-                              "sub %w2, %w2, #1\n\t"
-                              "cbnz %w2, 1b\n\t"
-                              : "=r" ( discard_addend ),
-                                "=r" ( discard_value ),
-                                "=r" ( discard_size ),
-                                "=r" ( discard_addend_i ),
-                                "=r" ( discard_value_i ),
-                                "+m" ( *value )
-                              : "0" ( addend0 ), "1" ( value0 ), "2" ( size )
-                              : "cc" );
-}
-
-/**
- * Subtract big integers
- *
- * @v subtrahend0      Element 0 of big integer to subtract
- * @v value0           Element 0 of big integer to be subtracted from
- * @v size             Number of elements
- */
-static inline __attribute__ (( always_inline )) void
-bigint_subtract_raw ( const uint64_t *subtrahend0, uint64_t *value0,
-                     unsigned int size ) {
-       bigint_t ( size ) __attribute__ (( may_alias )) *value =
-               ( ( void * ) value0 );
-       uint64_t *discard_subtrahend;
-       uint64_t *discard_value;
-       uint64_t discard_subtrahend_i;
-       uint64_t discard_value_i;
-       unsigned int discard_size;
-
-       __asm__ __volatile__ ( "cmp xzr, xzr\n\t" /* set CF */
-                              "\n1:\n\t"
-                              "ldr %3, [%0], #8\n\t"
-                              "ldr %4, [%1]\n\t"
-                              "sbcs %4, %4, %3\n\t"
-                              "str %4, [%1], #8\n\t"
-                              "sub %w2, %w2, #1\n\t"
-                              "cbnz %w2, 1b\n\t"
-                              : "=r" ( discard_subtrahend ),
-                                "=r" ( discard_value ),
-                                "=r" ( discard_size ),
-                                "=r" ( discard_subtrahend_i ),
-                                "=r" ( discard_value_i ),
-                                "+m" ( *value )
-                              : "0" ( subtrahend0 ), "1" ( value0 ),
-                                "2" ( size )
-                              : "cc" );
-}
-
-/**
- * Rotate big integer left
- *
- * @v value0           Element 0 of big integer
- * @v size             Number of elements
- */
-static inline __attribute__ (( always_inline )) void
-bigint_rol_raw ( uint64_t *value0, unsigned int size ) {
-       bigint_t ( size ) __attribute__ (( may_alias )) *value =
-               ( ( void * ) value0 );
-       uint64_t *discard_value;
-       uint64_t discard_value_i;
-       unsigned int discard_size;
-
-       __asm__ __volatile__ ( "cmn xzr, xzr\n\t" /* clear CF */
-                              "\n1:\n\t"
-                              "ldr %2, [%0]\n\t"
-                              "adcs %2, %2, %2\n\t"
-                              "str %2, [%0], #8\n\t"
-                              "sub %w1, %w1, #1\n\t"
-                              "cbnz %w1, 1b\n\t"
-                              : "=r" ( discard_value ),
-                                "=r" ( discard_size ),
-                                "=r" ( discard_value_i ),
-                                "+m" ( *value )
-                              : "0" ( value0 ), "1" ( size )
-                              : "cc" );
-}
-
-/**
- * Rotate big integer right
- *
- * @v value0           Element 0 of big integer
- * @v size             Number of elements
- */
-static inline __attribute__ (( always_inline )) void
-bigint_ror_raw ( uint64_t *value0, unsigned int size ) {
-       bigint_t ( size ) __attribute__ (( may_alias )) *value =
-               ( ( void * ) value0 );
-       uint64_t *discard_value;
-       uint64_t discard_value_i;
-       uint64_t discard_value_j;
-       unsigned int discard_size;
-
-       __asm__ __volatile__ ( "mov %3, #0\n\t"
-                              "\n1:\n\t"
-                              "sub %w1, %w1, #1\n\t"
-                              "ldr %2, [%0, %1, lsl #3]\n\t"
-                              "extr %3, %3, %2, #1\n\t"
-                              "str %3, [%0, %1, lsl #3]\n\t"
-                              "mov %3, %2\n\t"
-                              "cbnz %w1, 1b\n\t"
-                              : "=r" ( discard_value ),
-                                "=r" ( discard_size ),
-                                "=r" ( discard_value_i ),
-                                "=r" ( discard_value_j ),
-                                "+m" ( *value )
-                              : "0" ( value0 ), "1" ( size ) );
-}
-
-/**
- * Test if big integer is equal to zero
- *
- * @v value0           Element 0 of big integer
- * @v size             Number of elements
- * @ret is_zero                Big integer is equal to zero
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_zero_raw ( const uint64_t *value0, unsigned int size ) {
-       const uint64_t *value = value0;
-       uint64_t value_i;
-
-       do {
-               value_i = *(value++);
-               if ( value_i )
-                       break;
-       } while ( --size );
-
-       return ( value_i == 0 );
-}
-
-/**
- * Compare big integers
- *
- * @v value0           Element 0 of big integer
- * @v reference0       Element 0 of reference big integer
- * @v size             Number of elements
- * @ret geq            Big integer is greater than or equal to the reference
- */
-static inline __attribute__ (( always_inline, pure )) int
-bigint_is_geq_raw ( const uint64_t *value0, const uint64_t *reference0,
-                   unsigned int size ) {
-       const uint64_t *value = ( value0 + size );
-       const uint64_t *reference = ( reference0 + size );
-       uint64_t value_i;
-       uint64_t reference_i;
-
-       do {
-               value_i = *(--value);
-               reference_i = *(--reference);
-               if ( value_i != reference_i )
-                       break;
-       } while ( --size );
-
-       return ( value_i >= reference_i );
-}
-
-/**
- * Test if bit is set in big integer
- *
- * @v value0           Element 0 of big integer
- * @v size             Number of elements
- * @v bit              Bit to test
- * @ret is_set         Bit is set
- */
-static inline __attribute__ (( always_inline )) int
-bigint_bit_is_set_raw ( const uint64_t *value0, unsigned int size,
-                       unsigned int bit ) {
-       const bigint_t ( size ) __attribute__ (( may_alias )) *value =
-               ( ( const void * ) value0 );
-       unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) );
-       unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) );
-
-       return ( !! ( value->element[index] & ( 1UL << subindex ) ) );
-}
-
-/**
- * Find highest bit set in big integer
- *
- * @v value0           Element 0 of big integer
- * @v size             Number of elements
- * @ret max_bit                Highest bit set + 1 (or 0 if no bits set)
- */
-static inline __attribute__ (( always_inline )) int
-bigint_max_set_bit_raw ( const uint64_t *value0, unsigned int size ) {
-       const uint64_t *value = ( value0 + size );
-       int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) );
-       uint64_t value_i;
-
-       do {
-               value_i = *(--value);
-               max_bit -= ( 64 - fls ( value_i ) );
-               if ( value_i )
-                       break;
-       } while ( --size );
-
-       return max_bit;
-}
-
-/**
- * Grow big integer
- *
- * @v source0          Element 0 of source big integer
- * @v source_size      Number of elements in source big integer
- * @v dest0            Element 0 of destination big integer
- * @v dest_size                Number of elements in destination big integer
- */
-static inline __attribute__ (( always_inline )) void
-bigint_grow_raw ( const uint64_t *source0, unsigned int source_size,
-                 uint64_t *dest0, unsigned int dest_size ) {
-       unsigned int pad_size = ( dest_size - source_size );
-
-       memcpy ( dest0, source0, sizeof ( bigint_t ( source_size ) ) );
-       memset ( ( dest0 + source_size ), 0, sizeof ( bigint_t ( pad_size ) ) );
-}
-
-/**
- * Shrink big integer
- *
- * @v source0          Element 0 of source big integer
- * @v source_size      Number of elements in source big integer
- * @v dest0            Element 0 of destination big integer
- * @v dest_size                Number of elements in destination big integer
- */
-static inline __attribute__ (( always_inline )) void
-bigint_shrink_raw ( const uint64_t *source0, unsigned int source_size __unused,
-                   uint64_t *dest0, unsigned int dest_size ) {
-
-       memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) );
-}
-
-/**
- * Finalise big integer
- *
- * @v value0           Element 0 of big integer to finalise
- * @v size             Number of elements
- * @v out              Output buffer
- * @v len              Length of output buffer
- */
-static inline __attribute__ (( always_inline )) void
-bigint_done_raw ( const uint64_t *value0, unsigned int size __unused,
-                 void *out, size_t len ) {
-       const uint8_t *value_byte = ( ( const void * ) value0 );
-       uint8_t *out_byte = ( out + len );
-
-       /* Copy raw data in reverse order */
-       while ( len-- )
-               *(--out_byte) = *(value_byte++);
-}
-
-extern void bigint_multiply_raw ( const uint64_t *multiplicand0,
-                                 const uint64_t *multiplier0,
-                                 uint64_t *value0, unsigned int size );
-
-#endif /* _BITS_BIGINT_H */
diff --git a/roms/ipxe/src/arch/arm64/include/bits/bitops.h b/roms/ipxe/src/arch/arm64/include/bits/bitops.h
deleted file mode 100644 (file)
index 4350f62..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef _BITS_BITOPS_H
-#define _BITS_BITOPS_H
-
-/** @file
- *
- * ARM bit operations
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-
-/**
- * Test and set bit atomically
- *
- * @v bit              Bit to set
- * @v bits             Bit field
- * @ret old            Old value of bit (zero or non-zero)
- */
-static inline __attribute__ (( always_inline )) int
-test_and_set_bit ( unsigned int bit, volatile void *bits ) {
-       unsigned int index = ( bit / 64 );
-       unsigned int offset = ( bit % 64 );
-       volatile uint64_t *qword = ( ( ( volatile uint64_t * ) bits ) + index );
-       uint64_t mask = ( 1UL << offset );
-       uint64_t old;
-       uint64_t new;
-       uint32_t flag;
-
-       __asm__ __volatile__ ( "\n1:\n\t"
-                              "ldxr %0, %3\n\t"
-                              "orr %1, %0, %4\n\t"
-                              "stxr %w2, %1, %3\n\t"
-                              "tst %w2, %w2\n\t"
-                              "bne 1b\n\t"
-                              : "=&r" ( old ), "=&r" ( new ), "=&r" ( flag ),
-                                "+Q" ( *qword )
-                              : "r" ( mask )
-                              : "cc" );
-
-       return ( !! ( old & mask ) );
-}
-
-/**
- * Test and clear bit atomically
- *
- * @v bit              Bit to set
- * @v bits             Bit field
- * @ret old            Old value of bit (zero or non-zero)
- */
-static inline __attribute__ (( always_inline )) int
-test_and_clear_bit ( unsigned int bit, volatile void *bits ) {
-       unsigned int index = ( bit / 64 );
-       unsigned int offset = ( bit % 64 );
-       volatile uint64_t *qword = ( ( ( volatile uint64_t * ) bits ) + index );
-       uint64_t mask = ( 1UL << offset );
-       uint64_t old;
-       uint64_t new;
-       uint32_t flag;
-
-       __asm__ __volatile__ ( "\n1:\n\t"
-                              "ldxr %0, %3\n\t"
-                              "bic %1, %0, %4\n\t"
-                              "stxr %w2, %1, %3\n\t"
-                              "tst %w2, %w2\n\t"
-                              "bne 1b\n\t"
-                              : "=&r" ( old ), "=&r" ( new ), "=&r" ( flag ),
-                                "+Q" ( *qword )
-                              : "r" ( mask )
-                              : "cc" );
-
-       return ( !! ( old & mask ) );
-}
-
-/**
- * Set bit atomically
- *
- * @v bit              Bit to set
- * @v bits             Bit field
- */
-static inline __attribute__ (( always_inline )) void
-set_bit ( unsigned int bit, volatile void *bits ) {
-
-       test_and_set_bit ( bit, bits );
-}
-
-/**
- * Clear bit atomically
- *
- * @v bit              Bit to set
- * @v bits             Bit field
- */
-static inline __attribute__ (( always_inline )) void
-clear_bit ( unsigned int bit, volatile void *bits ) {
-
-       test_and_clear_bit ( bit, bits );
-}
-
-#endif /* _BITS_BITOPS_H */
diff --git a/roms/ipxe/src/arch/arm64/include/bits/byteswap.h b/roms/ipxe/src/arch/arm64/include/bits/byteswap.h
deleted file mode 100644 (file)
index 169d6c2..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef _BITS_BYTESWAP_H
-#define _BITS_BYTESWAP_H
-
-/** @file
- *
- * Byte-order swapping functions
- *
- */
-
-#include <stdint.h>
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-static inline __attribute__ (( always_inline, const )) uint16_t
-__bswap_variable_16 ( uint16_t x ) {
-       __asm__ ( "rev16 %0, %1" : "=r" ( x ) : "r" ( x ) );
-       return x;
-}
-
-static inline __attribute__ (( always_inline )) void
-__bswap_16s ( uint16_t *x ) {
-       *x = __bswap_variable_16 ( *x );
-}
-
-static inline __attribute__ (( always_inline, const )) uint32_t
-__bswap_variable_32 ( uint32_t x ) {
-       __asm__ ( "rev32 %0, %1" : "=r" ( x ) : "r" ( x ) );
-       return x;
-}
-
-static inline __attribute__ (( always_inline )) void
-__bswap_32s ( uint32_t *x ) {
-       *x = __bswap_variable_32 ( *x );
-}
-
-static inline __attribute__ (( always_inline, const )) uint64_t
-__bswap_variable_64 ( uint64_t x ) {
-       __asm__ ( "rev %0, %1" : "=r" ( x ) : "r" ( x ) );
-       return x;
-}
-
-static inline __attribute__ (( always_inline )) void
-__bswap_64s ( uint64_t *x ) {
-       *x = __bswap_variable_64 ( *x );
-}
-
-#endif
diff --git a/roms/ipxe/src/arch/arm64/include/bits/compiler.h b/roms/ipxe/src/arch/arm64/include/bits/compiler.h
deleted file mode 100644 (file)
index 3b129c2..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _BITS_COMPILER_H
-#define _BITS_COMPILER_H
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** Dummy relocation type */
-#define RELOC_TYPE_NONE R_AARCH64_NULL
-
-#ifndef ASSEMBLY
-
-#define __asmcall
-#define __libgcc
-
-#endif /* ASSEMBLY */
-
-#endif /*_BITS_COMPILER_H */
diff --git a/roms/ipxe/src/arch/arm64/include/bits/profile.h b/roms/ipxe/src/arch/arm64/include/bits/profile.h
deleted file mode 100644 (file)
index 62ffa37..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _BITS_PROFILE_H
-#define _BITS_PROFILE_H
-
-/** @file
- *
- * Profiling
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-
-/**
- * Get profiling timestamp
- *
- * @ret timestamp      Timestamp
- */
-static inline __attribute__ (( always_inline )) uint64_t
-profile_timestamp ( void ) {
-       uint64_t cycles;
-
-       /* Read cycle counter */
-       __asm__ __volatile__ ( "mrs %0, CNTVCT_EL0\n\t" : "=r" ( cycles ) );
-       return cycles;
-}
-
-#endif /* _BITS_PROFILE_H */
diff --git a/roms/ipxe/src/arch/arm64/include/bits/stdint.h b/roms/ipxe/src/arch/arm64/include/bits/stdint.h
deleted file mode 100644 (file)
index 9eb72e9..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _BITS_STDINT_H
-#define _BITS_STDINT_H
-
-typedef __SIZE_TYPE__          size_t;
-typedef signed long            ssize_t;
-typedef signed long            off_t;
-
-typedef unsigned char          uint8_t;
-typedef unsigned short         uint16_t;
-typedef unsigned int           uint32_t;
-typedef unsigned long long     uint64_t;
-
-typedef signed char            int8_t;
-typedef signed short           int16_t;
-typedef signed int             int32_t;
-typedef signed long long       int64_t;
-
-typedef unsigned long          physaddr_t;
-typedef unsigned long          intptr_t;
-
-#endif /* _BITS_STDINT_H */
diff --git a/roms/ipxe/src/arch/arm64/include/bits/string.h b/roms/ipxe/src/arch/arm64/include/bits/string.h
deleted file mode 100644 (file)
index c05fbe3..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-#ifndef BITS_STRING_H
-#define BITS_STRING_H
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * String functions
- *
- */
-
-extern void arm64_bzero ( void *dest, size_t len );
-extern void arm64_memset ( void *dest, size_t len, int character );
-extern void arm64_memcpy ( void *dest, const void *src, size_t len );
-extern void arm64_memmove_forwards ( void *dest, const void *src, size_t len );
-extern void arm64_memmove_backwards ( void *dest, const void *src, size_t len );
-extern void arm64_memmove ( void *dest, const void *src, size_t len );
-
-/**
- * Fill memory region
- *
- * @v dest             Destination region
- * @v character                Fill character
- * @v len              Length
- * @ret dest           Destination region
- */
-static inline __attribute__ (( always_inline )) void *
-memset ( void *dest, int character, size_t len ) {
-
-       /* Allow gcc to generate inline "stX xzr" instructions for
-        * small, constant lengths.
-        */
-       if ( __builtin_constant_p ( character ) && ( character == 0 ) &&
-            __builtin_constant_p ( len ) && ( len <= 64 ) ) {
-               __builtin_memset ( dest, 0, len );
-               return dest;
-       }
-
-       /* For zeroing larger or non-constant lengths, use the
-        * optimised variable-length zeroing code.
-        */
-       if ( __builtin_constant_p ( character ) && ( character == 0 ) ) {
-               arm64_bzero ( dest, len );
-               return dest;
-       }
-
-       /* Not necessarily zeroing: use basic variable-length code */
-       arm64_memset ( dest, len, character );
-       return dest;
-}
-
-/**
- * Copy memory region
- *
- * @v dest             Destination region
- * @v src              Source region
- * @v len              Length
- * @ret dest           Destination region
- */
-static inline __attribute__ (( always_inline )) void *
-memcpy ( void *dest, const void *src, size_t len ) {
-
-       /* Allow gcc to generate inline "ldX"/"stX" instructions for
-        * small, constant lengths.
-        */
-       if ( __builtin_constant_p ( len ) && ( len <= 64 ) ) {
-               __builtin_memcpy ( dest, src, len );
-               return dest;
-       }
-
-       /* Otherwise, use variable-length code */
-       arm64_memcpy ( dest, src, len );
-       return dest;
-}
-
-/**
- * Copy (possibly overlapping) memory region
- *
- * @v dest             Destination region
- * @v src              Source region
- * @v len              Length
- * @ret dest           Destination region
- */
-static inline __attribute__ (( always_inline )) void *
-memmove ( void *dest, const void *src, size_t len ) {
-       ssize_t offset = ( dest - src );
-
-       /* If required direction of copy is known at build time, then
-        * use the appropriate forwards/backwards copy directly.
-        */
-       if ( __builtin_constant_p ( offset ) ) {
-               if ( offset <= 0 ) {
-                       arm64_memmove_forwards ( dest, src, len );
-                       return dest;
-               } else {
-                       arm64_memmove_backwards ( dest, src, len );
-                       return dest;
-               }
-       }
-
-       /* Otherwise, use ambidirectional copy */
-       arm64_memmove ( dest, src, len );
-       return dest;
-}
-
-#endif /* BITS_STRING_H */
diff --git a/roms/ipxe/src/arch/arm64/include/bits/strings.h b/roms/ipxe/src/arch/arm64/include/bits/strings.h
deleted file mode 100644 (file)
index d5340f4..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef _BITS_STRINGS_H
-#define _BITS_STRINGS_H
-
-/** @file
- *
- * String functions
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/**
- * Find first (i.e. least significant) set bit
- *
- * @v value            Value
- * @ret lsb            Least significant bit set in value (LSB=1), or zero
- */
-static inline __attribute__ (( always_inline )) int __ffsll ( long long value ){
-       unsigned long long bits = value;
-       unsigned long long lsb;
-       unsigned int lz;
-
-       /* Extract least significant set bit */
-       lsb = ( bits & -bits );
-
-       /* Count number of leading zeroes before LSB */
-       __asm__ ( "clz %0, %1" : "=r" ( lz ) : "r" ( lsb ) );
-
-       return ( 64 - lz );
-}
-
-/**
- * Find first (i.e. least significant) set bit
- *
- * @v value            Value
- * @ret lsb            Least significant bit set in value (LSB=1), or zero
- */
-static inline __attribute__ (( always_inline )) int __ffsl ( long value ) {
-
-       return __ffsll ( value );
-}
-
-/**
- * Find last (i.e. most significant) set bit
- *
- * @v value            Value
- * @ret msb            Most significant bit set in value (LSB=1), or zero
- */
-static inline __attribute__ (( always_inline )) int __flsll ( long long value ){
-       unsigned int lz;
-
-       /* Count number of leading zeroes */
-       __asm__ ( "clz %0, %1" : "=r" ( lz ) : "r" ( value ) );
-
-       return ( 64 - lz );
-}
-
-/**
- * Find last (i.e. most significant) set bit
- *
- * @v value            Value
- * @ret msb            Most significant bit set in value (LSB=1), or zero
- */
-static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
-
-       return __flsll ( value );
-}
-
-#endif /* _BITS_STRINGS_H */
diff --git a/roms/ipxe/src/arch/arm64/include/bits/tcpip.h b/roms/ipxe/src/arch/arm64/include/bits/tcpip.h
deleted file mode 100644 (file)
index 6868653..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _BITS_TCPIP_H
-#define _BITS_TCPIP_H
-
-/** @file
- *
- * Transport-network layer interface
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-extern uint16_t tcpip_continue_chksum ( uint16_t sum, const void *data,
-                                       size_t len );
-
-#endif /* _BITS_TCPIP_H */
diff --git a/roms/ipxe/src/arch/arm64/include/efi/ipxe/dhcp_arch.h b/roms/ipxe/src/arch/arm64/include/efi/ipxe/dhcp_arch.h
deleted file mode 100644 (file)
index 48a36d0..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-#ifndef _DHCP_ARCH_H
-#define _DHCP_ARCH_H
-
-/** @file
- *
- * Architecture-specific DHCP options
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/dhcp.h>
-
-#define DHCP_ARCH_VENDOR_CLASS_ID \
-       DHCP_STRING ( 'P', 'X', 'E', 'C', 'l', 'i', 'e', 'n', 't', ':',      \
-                     'A', 'r', 'c', 'h', ':', '0', '0', '0', '0', '7', ':', \
-                     'U', 'N', 'D', 'I', ':', '0', '0', '3', '0', '1', '0' )
-
-#define DHCP_ARCH_CLIENT_ARCHITECTURE \
-       DHCP_WORD ( DHCP_CLIENT_ARCHITECTURE_ARM64 )
-
-#define DHCP_ARCH_CLIENT_NDI DHCP_OPTION ( 1 /* UNDI */ , 3, 10 /* v3.10 */ )
-
-#endif
diff --git a/roms/ipxe/src/arch/arm64/include/gdbmach.h b/roms/ipxe/src/arch/arm64/include/gdbmach.h
deleted file mode 100644 (file)
index cd152ee..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef GDBMACH_H
-#define GDBMACH_H
-
-/** @file
- *
- * GDB architecture specifics
- *
- * This file declares functions for manipulating the machine state and
- * debugging context.
- *
- */
-
-#include <stdint.h>
-
-typedef unsigned long gdbreg_t;
-
-/* Register snapshot */
-enum {
-       /* Not yet implemented */
-       GDBMACH_NREGS,
-};
-
-#define GDBMACH_SIZEOF_REGS ( GDBMACH_NREGS * sizeof ( gdbreg_t ) )
-
-static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) {
-       /* Not yet implemented */
-       ( void ) regs;
-       ( void ) pc;
-}
-
-static inline void gdbmach_set_single_step ( gdbreg_t *regs, int step ) {
-       /* Not yet implemented */
-       ( void ) regs;
-       ( void ) step;
-}
-
-static inline void gdbmach_breakpoint ( void ) {
-       /* Not yet implemented */
-}
-
-extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len,
-                                   int enable );
-extern void gdbmach_init ( void );
-
-#endif /* GDBMACH_H */
diff --git a/roms/ipxe/src/arch/arm64/include/limits.h b/roms/ipxe/src/arch/arm64/include/limits.h
deleted file mode 100644 (file)
index 8cf87b4..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef LIMITS_H
-#define LIMITS_H       1
-
-/* Number of bits in a `char' */
-#define CHAR_BIT       8
-
-/* Minimum and maximum values a `signed char' can hold */
-#define SCHAR_MIN      (-128)
-#define SCHAR_MAX      127
-
-/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */
-#define UCHAR_MAX      255
-
-/* Minimum and maximum values a `char' can hold */
-#define CHAR_MIN       SCHAR_MIN
-#define CHAR_MAX       SCHAR_MAX
-
-/* Minimum and maximum values a `signed short int' can hold */
-#define SHRT_MIN       (-32768)
-#define SHRT_MAX       32767
-
-/* Maximum value an `unsigned short' can hold. (Minimum is 0.) */
-#define USHRT_MAX      65535
-
-
-/* Minimum and maximum values a `signed int' can hold */
-#define INT_MIN                (-INT_MAX - 1)
-#define INT_MAX                2147483647
-
-/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
-#define UINT_MAX       4294967295U
-
-
-/* Minimum and maximum values a `signed int' can hold */
-#define INT_MAX                2147483647
-#define INT_MIN                (-INT_MAX - 1)
-
-
-/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
-#define UINT_MAX       4294967295U
-
-
-/* Minimum and maximum values a `signed long' can hold */
-#define LONG_MAX       9223372036854775807L
-#define LONG_MIN       (-LONG_MAX - 1L)
-
-/* Maximum value an `unsigned long' can hold. (Minimum is 0.) */
-#define ULONG_MAX      18446744073709551615UL
-
-/* Minimum and maximum values a `signed long long' can hold */
-#define LLONG_MAX      9223372036854775807LL
-#define LLONG_MIN      (-LONG_MAX - 1LL)
-
-
-/* Maximum value an `unsigned long long' can hold. (Minimum is 0.) */
-#define ULLONG_MAX     18446744073709551615ULL
-
-
-#endif /* LIMITS_H */
diff --git a/roms/ipxe/src/arch/arm64/include/setjmp.h b/roms/ipxe/src/arch/arm64/include/setjmp.h
deleted file mode 100644 (file)
index 85a7a9c..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef _SETJMP_H
-#define _SETJMP_H
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-
-/** A jump buffer */
-typedef struct {
-       /** Saved x19 */
-       uint64_t x19;
-       /** Saved x20 */
-       uint64_t x20;
-       /** Saved x21 */
-       uint64_t x21;
-       /** Saved x22 */
-       uint64_t x22;
-       /** Saved x23 */
-       uint64_t x23;
-       /** Saved x24 */
-       uint64_t x24;
-       /** Saved x25 */
-       uint64_t x25;
-       /** Saved x26 */
-       uint64_t x26;
-       /** Saved x27 */
-       uint64_t x27;
-       /** Saved x28 */
-       uint64_t x28;
-       /** Saved frame pointer (x29) */
-       uint64_t x29;
-       /** Saved link register (x30) */
-       uint64_t x30;
-       /** Saved stack pointer (x31) */
-       uint64_t sp;
-} jmp_buf[1];
-
-extern int __asmcall __attribute__ (( returns_twice ))
-setjmp ( jmp_buf env );
-
-extern void __asmcall __attribute__ (( noreturn ))
-longjmp ( jmp_buf env, int val );
-
-#endif /* _SETJMP_H */
index fe3adc9..99f8753 100644 (file)
@@ -80,10 +80,34 @@ PIE_FLAGS := $(shell $(PIE_TEST) && $(ECHO) '-fno-PIE -nopie')
 WORKAROUND_CFLAGS += $(PIE_FLAGS)
 endif
 
+# Define version string for lkrnprefix.S
+#
+CFLAGS_lkrnprefix      += -DVERSION="\"$(VERSION)\""
+
+# Locations of utilities
+#
+ISOLINUX_BIN_LIST      := \
+       $(ISOLINUX_BIN) \
+       /usr/lib/syslinux/isolinux.bin \
+       /usr/lib/syslinux/bios/isolinux.bin \
+       /usr/share/syslinux/isolinux.bin \
+       /usr/share/syslinux/bios/isolinux.bin \
+       /usr/local/share/syslinux/isolinux.bin \
+       /usr/local/share/syslinux/bios/isolinux.bin \
+       /usr/lib/ISOLINUX/isolinux.bin
+ISOLINUX_BIN   = $(firstword $(wildcard $(ISOLINUX_BIN_LIST)))
+
 # i386-specific directories containing source files
 #
-SRCDIRS                += arch/i386/core
-SRCDIRS                += arch/i386/tests
+SRCDIRS                += arch/i386/core arch/i386/transitions arch/i386/prefix
+SRCDIRS                += arch/i386/firmware/pcbios
+SRCDIRS                += arch/i386/image
+SRCDIRS                += arch/i386/interface/pcbios
+SRCDIRS                += arch/i386/interface/pxe
+SRCDIRS                += arch/i386/interface/pxeparent
+SRCDIRS        += arch/i386/interface/syslinux
+SRCDIRS                += arch/i386/interface/vmware
+SRCDIRS                += arch/i386/hci/commands
 
 # Include common x86 Makefile
 #
index 37ede65..aa809eb 100644 (file)
@@ -8,10 +8,6 @@ ELF2EFI                = $(ELF2EFI32)
 #
 CFLAGS         += -malign-double
 
-# Specify EFI boot file
-#
-EFI_BOOT_FILE  = bootia32.efi
-
 # Include generic EFI Makefile
 #
 MAKEDEPS       += arch/x86/Makefile.efi
index dfb8db0..ff82373 100644 (file)
@@ -1,6 +1,100 @@
 # -*- makefile -*- : Force emacs to use Makefile mode
 
-# Include generic BIOS Makefile
+# The i386 linker script
 #
-MAKEDEPS       += arch/x86/Makefile.pcbios
-include arch/x86/Makefile.pcbios
+LDSCRIPT       = arch/i386/scripts/i386.lds
+
+# Stop ld from complaining about our customised linker script
+#
+LDFLAGS                += -N --no-check-sections
+
+# pcbios specific drivers
+SRCDIRS                += arch/i386/drivers
+SRCDIRS                += arch/i386/drivers/net
+
+# Media types.
+#
+MEDIA          += rom
+MEDIA          += mrom
+MEDIA          += pcirom
+MEDIA          += isarom
+MEDIA          += pxe
+MEDIA          += kpxe
+MEDIA          += kkpxe
+MEDIA          += kkkpxe
+MEDIA          += lkrn
+MEDIA          += dsk
+MEDIA          += nbi
+MEDIA          += hd
+MEDIA          += raw
+MEDIA          += exe
+
+# Padding rules
+#
+PAD_rom                = $(PERL) $(PADIMG) --blksize=512 --byte=0xff
+PAD_mrom       = $(PAD_rom)
+PAD_pcirom     = $(PAD_rom)
+PAD_isarom     = $(PAD_rom)
+PAD_dsk                = $(PERL) $(PADIMG) --blksize=512
+PAD_hd         = $(PERL) $(PADIMG) --blksize=32768
+PAD_exe                = $(PERL) $(PADIMG) --blksize=512
+
+# Finalisation rules
+#
+FINALISE_rom   = $(PERL) $(FIXROM)
+FINALISE_mrom  = $(FINALISE_rom)
+FINALISE_pcirom        = $(FINALISE_rom)
+FINALISE_isarom        = $(FINALISE_rom)
+
+# Use $(ROMS) rather than $(DRIVERS) for "allroms", "allmroms", etc.
+#
+LIST_NAME_rom := ROMS
+LIST_NAME_mrom := ROMS
+LIST_NAME_pcirom := ROMS
+LIST_NAME_isarom := ROMS
+
+# rule to make a non-emulation ISO boot image
+NON_AUTO_MEDIA += iso
+%iso:  %lkrn util/geniso
+       $(QM)$(ECHO) "  [GENISO] $@"
+       $(Q)ISOLINUX_BIN=$(ISOLINUX_BIN) VERSION="$(VERSION)" bash util/geniso -o $@ $<
+
+# rule to make a floppy emulation ISO boot image
+NON_AUTO_MEDIA += liso
+%liso: %lkrn util/geniso
+       $(QM)$(ECHO) "  [GENISO] $@"
+       $(Q)VERSION="$(VERSION)" bash util/geniso -l -o $@ $<
+
+# rule to make a syslinux floppy image (mountable, bootable)
+NON_AUTO_MEDIA += sdsk
+%sdsk: %lkrn util/gensdsk
+       $(QM)$(ECHO) "  [GENSDSK] $@"
+       $(Q)bash util/gensdsk $@ $<
+
+# rule to write disk images to /dev/fd0
+NON_AUTO_MEDIA += fd0
+%fd0 : %dsk
+       $(QM)$(ECHO) "  [DD] $@"
+       $(Q)dd if=$< bs=512 conv=sync of=/dev/fd0
+       $(Q)sync
+
+# Special target for building Master Boot Record binary
+$(BIN)/mbr.bin : $(BIN)/mbr.o
+       $(QM)$(ECHO) "  [OBJCOPY] $@"
+       $(Q)$(OBJCOPY) -O binary $< $@
+
+# rule to make a USB disk image
+$(BIN)/usbdisk.bin : $(BIN)/usbdisk.o
+       $(QM)$(ECHO) "  [OBJCOPY] $@"
+       $(Q)$(OBJCOPY) -O binary $< $@
+
+NON_AUTO_MEDIA += usb
+%usb: $(BIN)/usbdisk.bin %hd
+       $(QM)$(ECHO) "  [FINISH] $@"
+       $(Q)cat $^ > $@
+
+# Padded floppy image (e.g. for iLO)
+NON_AUTO_MEDIA += pdsk
+%pdsk : %dsk
+       $(Q)cp $< $@
+       $(Q)$(PADIMG) --blksize=1474560 $@
similarity index 93%
rename from roms/ipxe/src/arch/x86/core/cachedhcp.c
rename to roms/ipxe/src/arch/i386/core/cachedhcp.c
index ff35b92..a5c6240 100644 (file)
@@ -58,7 +58,6 @@ static void cachedhcp_init ( void ) {
        struct dhcp_packet *dhcppkt;
        struct dhcp_packet *tmp;
        struct dhcphdr *dhcphdr;
-       size_t max_len;
        size_t len;
 
        /* Do nothing if no cached DHCPACK is present */
@@ -70,25 +69,23 @@ static void cachedhcp_init ( void ) {
        /* No reliable way to determine length before parsing packet;
         * start by assuming maximum length permitted by PXE.
         */
-       max_len = sizeof ( BOOTPLAYER_t );
+       len = sizeof ( BOOTPLAYER_t );
 
        /* Allocate and populate DHCP packet */
-       dhcppkt = zalloc ( sizeof ( *dhcppkt ) + max_len );
+       dhcppkt = zalloc ( sizeof ( *dhcppkt ) + len );
        if ( ! dhcppkt ) {
                DBGC ( colour, "CACHEDHCP could not allocate copy\n" );
                return;
        }
        dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
        copy_from_user ( dhcphdr, phys_to_user ( cached_dhcpack_phys ), 0,
-                        max_len );
-       dhcppkt_init ( dhcppkt, dhcphdr, max_len );
+                        len );
+       dhcppkt_init ( dhcppkt, dhcphdr, len );
 
-       /* Shrink packet to required length.  If reallocation fails,
-        * just continue to use the original packet and waste the
-        * unused space.
+       /* Resize packet to required length.  If reallocation fails,
+        * just continue to use the original packet.
         */
        len = dhcppkt_len ( dhcppkt );
-       assert ( len <= max_len );
        tmp = realloc ( dhcppkt, ( sizeof ( *dhcppkt ) + len ) );
        if ( tmp )
                dhcppkt = tmp;
similarity index 78%
rename from roms/ipxe/src/arch/x86/core/dumpregs.c
rename to roms/ipxe/src/arch/i386/core/dumpregs.c
index 37d62a7..82dc218 100644 (file)
@@ -6,8 +6,11 @@ void __asmcall _dump_regs ( struct i386_all_regs *ix86 ) {
        __asm__ __volatile__ (
                TEXT16_CODE ( ".globl dump_regs\n\t"
                              "\ndump_regs:\n\t"
-                             VIRT_CALL ( _dump_regs )
-                             "ret\n\t" ) );
+                             "pushl $_dump_regs\n\t"
+                             "pushw %%cs\n\t"
+                             "call prot_call\n\t"
+                             "addr32 leal 4(%%esp), %%esp\n\t"
+                             "ret\n\t" ) : : );
 
        printf ( "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
                 "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
index 666ecce..a1e309d 100644 (file)
 /* POSIX signal numbers for reporting traps to GDB */
 #define SIGILL 4
 #define SIGTRAP 5
+#define SIGBUS 7
 #define SIGFPE 8
+#define SIGSEGV 11
 #define SIGSTKFLT 16
 
-       .globl  gdbmach_sigfpe
-gdbmach_sigfpe:
+       .globl  gdbmach_nocode_sigfpe
+gdbmach_nocode_sigfpe:
        pushl   $SIGFPE
        jmp     gdbmach_interrupt
 
-       .globl  gdbmach_sigtrap
-gdbmach_sigtrap:
+       .globl  gdbmach_nocode_sigtrap
+gdbmach_nocode_sigtrap:
        pushl   $SIGTRAP
        jmp     gdbmach_interrupt
 
-       .globl  gdbmach_sigstkflt
-gdbmach_sigstkflt:
+       .globl  gdbmach_nocode_sigstkflt
+gdbmach_nocode_sigstkflt:
        pushl   $SIGSTKFLT
        jmp     gdbmach_interrupt
 
-       .globl  gdbmach_sigill
-gdbmach_sigill:
+       .globl  gdbmach_nocode_sigill
+gdbmach_nocode_sigill:
        pushl   $SIGILL
        jmp     gdbmach_interrupt
 
+       .globl  gdbmach_withcode_sigbus
+gdbmach_withcode_sigbus:
+       movl    $SIGBUS, (%esp)
+       jmp     gdbmach_interrupt
+
+       .globl  gdbmach_withcode_sigsegv
+gdbmach_withcode_sigsegv:
+       movl    $SIGSEGV, (%esp)
+       jmp     gdbmach_interrupt
+
 /* When invoked, the stack contains: eflags, cs, eip, signo. */
 #define IH_OFFSET_GDB_REGS ( 0 )
 #define IH_OFFSET_GDB_EIP ( IH_OFFSET_GDB_REGS + SIZEOF_I386_REGS )
diff --git a/roms/ipxe/src/arch/i386/core/gdbmach.c b/roms/ipxe/src/arch/i386/core/gdbmach.c
new file mode 100644 (file)
index 0000000..d92a4ac
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2008 Stefan Hajnoczi <stefanha@gmail.com>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stddef.h>
+#include <stdio.h>
+#include <assert.h>
+#include <ipxe/uaccess.h>
+#include <ipxe/gdbstub.h>
+#include <librm.h>
+#include <gdbmach.h>
+
+/** @file
+ *
+ * GDB architecture-specific bits for i386
+ *
+ */
+
+enum {
+       DR7_CLEAR = 0x00000400,    /* disable hardware breakpoints */
+       DR6_CLEAR = 0xffff0ff0,    /* clear breakpoint status */
+};
+
+/** Hardware breakpoint, fields stored in x86 bit pattern form */
+struct hwbp {
+       int type;           /* type (1=write watchpoint, 3=access watchpoint) */
+       unsigned long addr; /* linear address */
+       size_t len;         /* length (0=1-byte, 1=2-byte, 3=4-byte) */
+       int enabled;
+};
+
+static struct hwbp hwbps [ 4 ];
+static gdbreg_t dr7 = DR7_CLEAR;
+
+static struct hwbp *gdbmach_find_hwbp ( int type, unsigned long addr, size_t len ) {
+       struct hwbp *available = NULL;
+       unsigned int i;
+       for ( i = 0; i < sizeof hwbps / sizeof hwbps [ 0 ]; i++ ) {
+               if ( hwbps [ i ].type == type && hwbps [ i ].addr == addr && hwbps [ i ].len == len ) {
+                       return &hwbps [ i ];
+               }
+               if ( !hwbps [ i ].enabled ) {
+                       available = &hwbps [ i ];
+               }
+       }
+       return available;
+}
+
+static void gdbmach_commit_hwbp ( struct hwbp *bp ) {
+       unsigned int regnum = bp - hwbps;
+
+       /* Set breakpoint address */
+       assert ( regnum < ( sizeof hwbps / sizeof hwbps [ 0 ] ) );
+       switch ( regnum ) {
+               case 0:
+                       __asm__ __volatile__ ( "movl %0, %%dr0\n" : : "r" ( bp->addr ) );
+                       break;
+               case 1:
+                       __asm__ __volatile__ ( "movl %0, %%dr1\n" : : "r" ( bp->addr ) );
+                       break;
+               case 2:
+                       __asm__ __volatile__ ( "movl %0, %%dr2\n" : : "r" ( bp->addr ) );
+                       break;
+               case 3:
+                       __asm__ __volatile__ ( "movl %0, %%dr3\n" : : "r" ( bp->addr ) );
+                       break;
+       }
+
+       /* Set type */
+       dr7 &= ~( 0x3 << ( 16 + 4 * regnum ) );
+       dr7 |= bp->type << ( 16 + 4 * regnum );
+
+       /* Set length */
+       dr7 &= ~( 0x3 << ( 18 + 4 * regnum ) );
+       dr7 |= bp->len << ( 18 + 4 * regnum );
+
+       /* Set/clear local enable bit */
+       dr7 &= ~( 0x3 << 2 * regnum );
+       dr7 |= bp->enabled << 2 * regnum;
+}
+
+int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len, int enable ) {
+       struct hwbp *bp;
+       
+       /* Check and convert breakpoint type to x86 type */
+       switch ( type ) {
+               case GDBMACH_WATCH:
+                       type = 0x1;
+                       break;
+               case GDBMACH_AWATCH:
+                       type = 0x3;
+                       break;
+               default:
+                       return 0; /* unsupported breakpoint type */
+       }
+
+       /* Only lengths 1, 2, and 4 are supported */
+       if ( len != 2 && len != 4 ) {
+               len = 1;
+       }
+       len--; /* convert to x86 breakpoint length bit pattern */
+
+       /* Calculate linear address by adding segment base */
+       addr += virt_offset;
+
+       /* Set up the breakpoint */
+       bp = gdbmach_find_hwbp ( type, addr, len );
+       if ( !bp ) {
+               return 0; /* ran out of hardware breakpoints */
+       }
+       bp->type = type;
+       bp->addr = addr;
+       bp->len = len;
+       bp->enabled = enable;
+       gdbmach_commit_hwbp ( bp );
+       return 1;
+}
+
+static void gdbmach_disable_hwbps ( void ) {
+       /* Store and clear hardware breakpoints */
+       __asm__ __volatile__ ( "movl %0, %%dr7\n" : : "r" ( DR7_CLEAR ) );
+}
+
+static void gdbmach_enable_hwbps ( void ) {
+       /* Clear breakpoint status register */
+       __asm__ __volatile__ ( "movl %0, %%dr6\n" : : "r" ( DR6_CLEAR ) );
+
+       /* Restore hardware breakpoints */
+       __asm__ __volatile__ ( "movl %0, %%dr7\n" : : "r" ( dr7 ) );
+}
+
+__asmcall void gdbmach_handler ( int signo, gdbreg_t *regs ) {
+       gdbmach_disable_hwbps();
+       gdbstub_handler ( signo, regs );
+       gdbmach_enable_hwbps();
+}
+
+static void * gdbmach_interrupt_vectors[] = {
+       gdbmach_nocode_sigfpe,          /* Divide by zero */
+       gdbmach_nocode_sigtrap,         /* Debug trap */
+       NULL,                           /* Non-maskable interrupt */
+       gdbmach_nocode_sigtrap,         /* Breakpoint */
+       gdbmach_nocode_sigstkflt,       /* Overflow */
+       gdbmach_nocode_sigstkflt,       /* Bound range exceeded */
+       gdbmach_nocode_sigill,          /* Invalid opcode */
+       NULL,                           /* Device not available */
+       gdbmach_withcode_sigbus,        /* Double fault */
+       NULL,                           /* Coprocessor segment overrun */
+       gdbmach_withcode_sigsegv,       /* Invalid TSS */
+       gdbmach_withcode_sigsegv,       /* Segment not present */
+       gdbmach_withcode_sigsegv,       /* Stack segment fault */
+       gdbmach_withcode_sigsegv,       /* General protection fault */
+       gdbmach_withcode_sigsegv,       /* Page fault */
+};
+
+void gdbmach_init ( void ) {
+       unsigned int i;
+
+       for ( i = 0 ; i < ( sizeof ( gdbmach_interrupt_vectors ) /
+                           sizeof ( gdbmach_interrupt_vectors[0] ) ) ; i++ ) {
+               set_interrupt_vector ( i, gdbmach_interrupt_vectors[i] );
+       }
+}
similarity index 76%
rename from roms/ipxe/src/arch/x86/core/relocate.c
rename to roms/ipxe/src/arch/i386/core/relocate.c
index 765d465..54ad387 100644 (file)
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
+/*
+ * The linker passes in the symbol _max_align, which is the alignment
+ * that we must preserve, in bytes.
+ *
+ */
+extern char _max_align[];
+#define max_align ( ( unsigned int ) _max_align )
+
 /* Linker symbols */
 extern char _textdata[];
 extern char _etextdata[];
@@ -22,12 +30,6 @@ extern char _etextdata[];
  */
 #define MAX_ADDR (0xfff00000UL)
 
-/* Preserve alignment to a 4kB page
- *
- * Required for x86_64, and doesn't hurt for i386.
- */
-#define ALIGN 4096
-
 /**
  * Relocate iPXE
  *
@@ -42,8 +44,8 @@ extern char _etextdata[];
  */
 __asmcall void relocate ( struct i386_all_regs *ix86 ) {
        struct memory_map memmap;
-       uint32_t start, end, size, padded_size, max;
-       uint32_t new_start, new_end;
+       unsigned long start, end, size, padded_size, max;
+       unsigned long new_start, new_end;
        unsigned i;
 
        /* Get memory map and current location */
@@ -51,17 +53,17 @@ __asmcall void relocate ( struct i386_all_regs *ix86 ) {
        start = virt_to_phys ( _textdata );
        end = virt_to_phys ( _etextdata );
        size = ( end - start );
-       padded_size = ( size + ALIGN - 1 );
+       padded_size = ( size + max_align - 1 );
 
-       DBG ( "Relocate: currently at [%x,%x)\n"
-             "...need %x bytes for %d-byte alignment\n",
-             start, end, padded_size, ALIGN );
+       DBG ( "Relocate: currently at [%lx,%lx)\n"
+             "...need %lx bytes for %d-byte alignment\n",
+             start, end, padded_size, max_align );
 
        /* Determine maximum usable address */
        max = MAX_ADDR;
        if ( ix86->regs.ebp < max ) {
                max = ix86->regs.ebp;
-               DBG ( "Limiting relocation to [0,%x)\n", max );
+               DBG ( "Limiting relocation to [0,%lx)\n", max );
        }
 
        /* Walk through the memory map and find the highest address
@@ -70,7 +72,7 @@ __asmcall void relocate ( struct i386_all_regs *ix86 ) {
        new_end = end;
        for ( i = 0 ; i < memmap.count ; i++ ) {
                struct memory_region *region = &memmap.regions[i];
-               uint32_t r_start, r_end;
+               unsigned long r_start, r_end;
 
                DBG ( "Considering [%llx,%llx)\n", region->start, region->end);
                
@@ -79,17 +81,17 @@ __asmcall void relocate ( struct i386_all_regs *ix86 ) {
                 * with using just 32-bit arithmetic after this stage.
                 */
                if ( region->start > max ) {
-                       DBG ( "...starts after max=%x\n", max );
+                       DBG ( "...starts after max=%lx\n", max );
                        continue;
                }
                r_start = region->start;
                if ( region->end > max ) {
-                       DBG ( "...end truncated to max=%x\n", max );
+                       DBG ( "...end truncated to max=%lx\n", max );
                        r_end = max;
                } else {
                        r_end = region->end;
                }
-               DBG ( "...usable portion is [%x,%x)\n", r_start, r_end );
+               DBG ( "...usable portion is [%lx,%lx)\n", r_start, r_end );
 
                /* If we have rounded down r_end below r_ start, skip
                 * this block.
@@ -101,7 +103,7 @@ __asmcall void relocate ( struct i386_all_regs *ix86 ) {
 
                /* Check that there is enough space to fit in iPXE */
                if ( ( r_end - r_start ) < size ) {
-                       DBG ( "...too small (need %x bytes)\n", size );
+                       DBG ( "...too small (need %lx bytes)\n", size );
                        continue;
                }
 
@@ -123,10 +125,10 @@ __asmcall void relocate ( struct i386_all_regs *ix86 ) {
         * required alignemnt.
         */
        new_start = new_end - padded_size;
-       new_start += ( ( start - new_start ) & ( ALIGN - 1 ) );
+       new_start += ( start - new_start ) & ( max_align - 1 );
        new_end = new_start + size;
 
-       DBG ( "Relocating from [%x,%x) to [%x,%x)\n",
+       DBG ( "Relocating from [%lx,%lx) to [%lx,%lx)\n",
              start, end, new_start, new_end );
        
        /* Let prefix know what to copy */
similarity index 76%
rename from roms/ipxe/src/arch/x86/core/stack.S
rename to roms/ipxe/src/arch/i386/core/stack.S
index 995c397..98f1cd9 100644 (file)
@@ -2,12 +2,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 
        .arch i386
 
-#ifdef __x86_64__
-#define STACK_SIZE 8192
-#else
-#define STACK_SIZE 4096
-#endif
-
 /****************************************************************************
  * Internal stack
  ****************************************************************************
@@ -16,6 +10,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
        .align 8
        .globl _stack
 _stack:
-       .space STACK_SIZE
+       .space 4096
        .globl _estack
 _estack:
diff --git a/roms/ipxe/src/arch/i386/core/virtaddr.S b/roms/ipxe/src/arch/i386/core/virtaddr.S
new file mode 100644 (file)
index 0000000..4255915
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Functions to support the virtual addressing method of relocation
+ * that Etherboot uses.
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+
+#include "librm.h"
+               
+       .arch i386
+       .text
+       .code32
+       
+/****************************************************************************
+ * _virt_to_phys (virtual addressing)
+ *
+ * Switch from virtual to flat physical addresses.  %esp is adjusted
+ * to a physical value.  Segment registers are set to flat physical
+ * selectors.  All other registers are preserved.  Flags are
+ * preserved.
+ *
+ * Parameters: none
+ * Returns: none
+ ****************************************************************************
+ */
+       .globl _virt_to_phys
+_virt_to_phys:
+       /* Preserve registers and flags */
+       pushfl
+       pushl   %eax
+       pushl   %ebp
+
+       /* Change return address to a physical address */
+       movl    virt_offset, %ebp
+       addl    %ebp, 12(%esp)
+
+       /* Switch to physical code segment */
+       cli
+       pushl   $PHYSICAL_CS
+       leal    1f(%ebp), %eax
+       pushl   %eax
+       lret
+1:
+       /* Reload other segment registers and adjust %esp */
+       movl    $PHYSICAL_DS, %eax
+       movl    %eax, %ds
+       movl    %eax, %es
+       movl    %eax, %fs
+       movl    %eax, %gs
+       movl    %eax, %ss
+       addl    %ebp, %esp
+
+       /* Restore registers and flags, and return */
+       popl    %ebp
+       popl    %eax
+       popfl
+       ret
+
+/****************************************************************************
+ * _phys_to_virt (flat physical addressing)
+ *
+ * Switch from flat physical to virtual addresses.  %esp is adjusted
+ * to a virtual value.  Segment registers are set to virtual
+ * selectors.  All other registers are preserved.  Flags are
+ * preserved.
+ *
+ * Parameters: none
+ * Returns: none
+ ****************************************************************************
+ */
+       .globl _phys_to_virt
+_phys_to_virt:
+       /* Preserve registers and flags */
+       pushfl
+       pushl   %eax
+       pushl   %ebp
+
+       /* Switch to virtual code segment */
+       cli
+       ljmp    $VIRTUAL_CS, $1f
+1:
+       /* Reload data segment registers */
+       movl    $VIRTUAL_DS, %eax
+       movl    %eax, %ds
+       movl    %eax, %es
+       movl    %eax, %fs
+       movl    %eax, %gs
+
+       /* Reload stack segment and adjust %esp */
+       movl    virt_offset, %ebp
+       movl    %eax, %ss
+       subl    %ebp, %esp
+
+       /* Change the return address to a virtual address */
+       subl    %ebp, 12(%esp)
+
+       /* Restore registers and flags, and return */
+       popl    %ebp
+       popl    %eax
+       popfl
+       ret
+
+/****************************************************************************
+ * _intr_to_virt (virtual code segment, virtual or physical stack segment)
+ *
+ * Switch from virtual code segment with either a virtual or physical
+ * stack segment to using virtual addressing.  %esp is adjusted if
+ * necessary to a virtual value.  Segment registers are set to virtual
+ * selectors.  All other registers are preserved.  Flags are
+ * preserved.
+ *
+ * Parameters: none
+ * Returns: none
+ ****************************************************************************
+ */
+       .globl _intr_to_virt
+_intr_to_virt:
+       /* Preserve registers and flags */
+       pushfl
+       pushl   %eax
+       pushl   %ebp
+
+       /* Check whether stack segment is physical or virtual */
+       movl    %ss, %eax
+       cmpw    $VIRTUAL_DS, %ax
+       movl    $VIRTUAL_DS, %eax
+
+       /* Reload data segment registers */
+       movl    %eax, %ds
+       movl    %eax, %es
+       movl    %eax, %fs
+       movl    %eax, %gs
+
+       /* Reload stack segment and adjust %esp if necessary */
+       je      1f
+       movl    virt_offset, %ebp
+       movl    %eax, %ss
+       subl    %ebp, %esp
+1:
+       /* Restore registers and flags, and return */
+       popl    %ebp
+       popl    %eax
+       popfl
+       ret
similarity index 99%
rename from roms/ipxe/src/arch/x86/drivers/net/undinet.c
rename to roms/ipxe/src/arch/i386/drivers/net/undinet.c
index 091ef92..6450665 100644 (file)
@@ -143,7 +143,8 @@ static void undinet_hook_isr ( unsigned int irq ) {
        assert ( undiisr_irq == 0 );
 
        undiisr_irq = irq;
-       hook_bios_interrupt ( IRQ_INT ( irq ), ( ( intptr_t ) undiisr ),
+       hook_bios_interrupt ( IRQ_INT ( irq ),
+                             ( ( unsigned int ) undiisr ),
                              &undiisr_next_handler );
 }
 
@@ -156,7 +157,8 @@ static void undinet_unhook_isr ( unsigned int irq ) {
 
        assert ( irq <= IRQ_MAX );
 
-       unhook_bios_interrupt ( IRQ_INT ( irq ), ( ( intptr_t ) undiisr ),
+       unhook_bios_interrupt ( IRQ_INT ( irq ),
+                               ( ( unsigned int ) undiisr ),
                                &undiisr_next_handler );
        undiisr_irq = 0;
 }
@@ -591,8 +593,6 @@ static const struct undinet_irq_broken undinet_irq_broken_list[] = {
        /* HP XX70x laptops */
        { .pci_vendor = 0x8086, .pci_device = 0x1502 },
        { .pci_vendor = 0x8086, .pci_device = 0x1503 },
-       /* HP 745 G3 laptop */
-       { .pci_vendor = 0x14e4, .pci_device = 0x1687 },
 };
 
 /**
@@ -26,12 +26,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <assert.h>
 #include <realmode.h>
 #include <bios.h>
-#include <biosint.h>
 #include <ipxe/console.h>
 #include <ipxe/ansiesc.h>
-#include <ipxe/keys.h>
 #include <ipxe/keymap.h>
-#include <ipxe/init.h>
 #include <config/console.h>
 
 #define ATTR_BOLD              0x08
@@ -69,17 +66,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /** Current character attribute */
 static unsigned int bios_attr = ATTR_DEFAULT;
 
-/** Keypress injection lock */
-static uint8_t __text16 ( bios_inject_lock );
-#define bios_inject_lock __use_text16 ( bios_inject_lock )
-
-/** Vector for chaining to other INT 16 handlers */
-static struct segoff __text16 ( int16_vector );
-#define int16_vector __use_text16 ( int16_vector )
-
-/** Assembly wrapper */
-extern void int16_wrapper ( void );
-
 /**
  * Handle ANSI CUP (cursor position)
  *
@@ -279,35 +265,30 @@ static void bios_putchar ( int character ) {
  * not in the middle of such a sequence, this will point to a NUL
  * (note: not "will be NULL").
  */
-static const char *bios_ansi_input = "";
-
-/** A BIOS key */
-struct bios_key {
-       /** Scancode */
-       uint8_t scancode;
-       /** Key code */
-       uint16_t key;
-} __attribute__ (( packed ));
-
-/** Mapping from BIOS scan codes to iPXE key codes */
-static const struct bios_key bios_keys[] = {
-       { 0x53, KEY_DC },
-       { 0x48, KEY_UP },
-       { 0x50, KEY_DOWN },
-       { 0x4b, KEY_LEFT },
-       { 0x4d, KEY_RIGHT },
-       { 0x47, KEY_HOME },
-       { 0x4f, KEY_END },
-       { 0x49, KEY_PPAGE },
-       { 0x51, KEY_NPAGE },
-       { 0x3f, KEY_F5 },
-       { 0x40, KEY_F6 },
-       { 0x41, KEY_F7 },
-       { 0x42, KEY_F8 },
-       { 0x43, KEY_F9 },
-       { 0x44, KEY_F10 },
-       { 0x85, KEY_F11 },
-       { 0x86, KEY_F12 },
+static const char *ansi_input = "";
+
+/** A mapping from a BIOS scan code to an ANSI escape sequence */
+#define BIOS_KEY( key, ansi ) key ansi "\0"
+
+/** Mapping from BIOS scan codes to ANSI escape sequences */
+static const char ansi_sequences[] = {
+       BIOS_KEY ( "\x53", "[3~" )      /* Delete */
+       BIOS_KEY ( "\x48", "[A" )       /* Up arrow */
+       BIOS_KEY ( "\x50", "[B" )       /* Down arrow */
+       BIOS_KEY ( "\x4b", "[D" )       /* Left arrow */
+       BIOS_KEY ( "\x4d", "[C" )       /* Right arrow */
+       BIOS_KEY ( "\x47", "[H" )       /* Home */
+       BIOS_KEY ( "\x4f", "[F" )       /* End */
+       BIOS_KEY ( "\x49", "[5~" )      /* Page up */
+       BIOS_KEY ( "\x51", "[6~" )      /* Page down */
+       BIOS_KEY ( "\x3f", "[15~" )     /* F5 */
+       BIOS_KEY ( "\x40", "[17~" )     /* F6 */
+       BIOS_KEY ( "\x41", "[18~" )     /* F7 */
+       BIOS_KEY ( "\x42", "[19~" )     /* F8 (required for PXE) */
+       BIOS_KEY ( "\x43", "[20~" )     /* F9 */
+       BIOS_KEY ( "\x44", "[21~" )     /* F10 */
+       BIOS_KEY ( "\x85", "[23~" )     /* F11 */
+       BIOS_KEY ( "\x86", "[24~" )     /* F12 */
 };
 
 /**
@@ -316,35 +297,14 @@ static const struct bios_key bios_keys[] = {
  * @v scancode         BIOS scancode
  * @ret ansi_seq       ANSI escape sequence, if any, otherwise NULL
  */
-static const char * bios_ansi_seq ( unsigned int scancode ) {
-       static char buf[ 5 /* "[" + two digits + terminator + NUL */ ];
-       unsigned int key;
-       unsigned int terminator;
-       unsigned int n;
-       unsigned int i;
-       char *tmp = buf;
-
-       /* Construct ANSI escape sequence for scancode, if known */
-       for ( i = 0 ; i < ( sizeof ( bios_keys ) /
-                           sizeof ( bios_keys[0] ) ) ; i++ ) {
-
-               /* Look for matching scancode */
-               if ( bios_keys[i].scancode != scancode )
-                       continue;
-
-               /* Construct escape sequence */
-               key = bios_keys[i].key;
-               n = KEY_ANSI_N ( key );
-               terminator = KEY_ANSI_TERMINATOR ( key );
-               *(tmp++) = '[';
-               if ( n )
-                       tmp += sprintf ( tmp, "%d", n );
-               *(tmp++) = terminator;
-               *(tmp++) = '\0';
-               assert ( tmp <= &buf[ sizeof ( buf ) ] );
-               return buf;
-       }
+static const char * scancode_to_ansi_seq ( unsigned int scancode ) {
+       const char *seq = ansi_sequences;
 
+       while ( *seq ) {
+               if ( *(seq++) == ( ( char ) scancode ) )
+                       return seq;
+               seq += ( strlen ( seq ) + 1 );
+       }
        DBG ( "Unrecognised BIOS scancode %02x\n", scancode );
        return NULL;
 }
@@ -376,23 +336,16 @@ static int bios_getchar ( void ) {
        const char *ansi_seq;
 
        /* If we are mid-sequence, pass out the next byte */
-       if ( ( character = *bios_ansi_input ) ) {
-               bios_ansi_input++;
+       if ( ( character = *ansi_input ) ) {
+               ansi_input++;
                return character;
        }
 
-       /* Do nothing if injection is in progress */
-       if ( bios_inject_lock )
-               return 0;
-
        /* Read character from real BIOS console */
-       bios_inject_lock++;
        __asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
                                           "int $0x16\n\t"
                                           "cli\n\t" )
-                              : "=a" ( keypress )
-                              : "a" ( 0x1000 ), "m" ( bios_inject_lock ) );
-       bios_inject_lock--;
+                              : "=a" ( keypress ) : "a" ( 0x1000 ) );
        character = ( keypress & 0xff );
 
        /* If it's a normal character, just map and return it */
@@ -400,9 +353,9 @@ static int bios_getchar ( void ) {
                return bios_keymap ( character );
 
        /* Otherwise, check for a special key that we know about */
-       if ( ( ansi_seq = bios_ansi_seq ( keypress >> 8 ) ) ) {
+       if ( ( ansi_seq = scancode_to_ansi_seq ( keypress >> 8 ) ) ) {
                /* Start of escape sequence: return ESC (0x1b) */
-               bios_ansi_input = ansi_seq;
+               ansi_input = ansi_seq;
                return 0x1b;
        }
 
@@ -420,143 +373,23 @@ static int bios_iskey ( void ) {
        unsigned int flags;
 
        /* If we are mid-sequence, we are always ready */
-       if ( *bios_ansi_input )
+       if ( *ansi_input )
                return 1;
 
-       /* Do nothing if injection is in progress */
-       if ( bios_inject_lock )
-               return 0;
-
        /* Otherwise check the real BIOS console */
-       bios_inject_lock++;
        __asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
                                           "int $0x16\n\t"
                                           "pushfw\n\t"
                                           "popw %w0\n\t"
                                           "cli\n\t" )
-                              : "=R" ( flags ), "=a" ( discard_a )
-                              : "a" ( 0x1100 ), "m" ( bios_inject_lock ) );
-       bios_inject_lock--;
+                              : "=r" ( flags ), "=a" ( discard_a )
+                              : "a" ( 0x1100 ) );
        return ( ! ( flags & ZF ) );
 }
 
-/** BIOS console */
 struct console_driver bios_console __console_driver = {
        .putchar = bios_putchar,
        .getchar = bios_getchar,
        .iskey = bios_iskey,
        .usage = CONSOLE_PCBIOS,
 };
-
-/**
- * Inject keypresses
- *
- * @v ix86             Registers as passed to INT 16
- */
-static __asmcall void bios_inject ( struct i386_all_regs *ix86 ) {
-       unsigned int discard_a;
-       unsigned int scancode;
-       unsigned int i;
-       uint16_t keypress;
-       int key;
-
-       /* If this is a blocking call, then loop until the
-        * non-blocking variant of the call indicates that a keypress
-        * is available.  Do this without acquiring the injection
-        * lock, so that injection may take place.
-        */
-       if ( ( ix86->regs.ah & ~0x10 ) == 0x00 ) {
-               __asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
-                                                  "\n1:\n\t"
-                                                  "pushw %%ax\n\t"
-                                                  "int $0x16\n\t"
-                                                  "popw %%ax\n\t"
-                                                  "jc 2f\n\t"
-                                                  "jz 1b\n\t"
-                                                  "\n2:\n\t"
-                                                  "cli\n\t" )
-                                      : "=a" ( discard_a )
-                                      : "a" ( ix86->regs.eax | 0x0100 ),
-                                        "m" ( bios_inject_lock ) );
-       }
-
-       /* Acquire injection lock */
-       bios_inject_lock++;
-
-       /* Check for keypresses */
-       if ( iskey() ) {
-
-               /* Get key */
-               key = getkey ( 0 );
-
-               /* Reverse internal CR->LF mapping */
-               if ( key == '\n' )
-                       key = '\r';
-
-               /* Convert to keypress */
-               keypress = ( ( key << 8 ) | key );
-
-               /* Handle special keys */
-               if ( key >= KEY_MIN ) {
-                       for ( i = 0 ; i < ( sizeof ( bios_keys ) /
-                                           sizeof ( bios_keys[0] ) ) ; i++ ) {
-                               if ( bios_keys[i].key == key ) {
-                                       scancode = bios_keys[i].scancode;
-                                       keypress = ( scancode << 8 );
-                                       break;
-                               }
-                       }
-               }
-
-               /* Inject keypress */
-               DBGC ( &bios_console, "BIOS injecting keypress %04x\n",
-                      keypress );
-               __asm__ __volatile__ ( REAL_CODE ( "int $0x16\n\t" )
-                                      : "=a" ( discard_a )
-                                      : "a" ( 0x0500 ), "c" ( keypress ),
-                                        "m" ( bios_inject_lock ) );
-       }
-
-       /* Release injection lock */
-       bios_inject_lock--;
-}
-
-/**
- * Start up keypress injection
- *
- */
-static void bios_inject_startup ( void ) {
-
-       /* Assembly wrapper to call bios_inject() */
-       __asm__ __volatile__ (
-               TEXT16_CODE ( "\nint16_wrapper:\n\t"
-                             "pushfw\n\t"
-                             "cmpb $0, %cs:bios_inject_lock\n\t"
-                             "jnz 1f\n\t"
-                             VIRT_CALL ( bios_inject )
-                             "\n1:\n\t"
-                             "popfw\n\t"
-                             "ljmp *%cs:int16_vector\n\t" ) );
-
-       /* Hook INT 16 */
-       hook_bios_interrupt ( 0x16, ( ( intptr_t ) int16_wrapper ),
-                             &int16_vector );
-}
-
-/**
- * Shut down keypress injection
- *
- * @v booting          System is shutting down for OS boot
- */
-static void bios_inject_shutdown ( int booting __unused ) {
-
-       /* Unhook INT 16 */
-       unhook_bios_interrupt ( 0x16, ( ( intptr_t ) int16_wrapper ),
-                               &int16_vector );
-}
-
-/** Keypress injection startup function */
-struct startup_fn bios_inject_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
-       .startup = bios_inject_startup,
-       .shutdown = bios_inject_shutdown,
-};
@@ -88,11 +88,11 @@ void fake_e820 ( void ) {
                              "ljmp *%%cs:real_int15_vector\n\t" )
                : : "i" ( sizeof ( e820map ) ) );
 
-       hook_bios_interrupt ( 0x15, ( intptr_t ) int15_fakee820,
+       hook_bios_interrupt ( 0x15, ( unsigned int ) int15_fakee820,
                              &real_int15_vector );
 }
 
 void unfake_e820 ( void ) {
-       unhook_bios_interrupt ( 0x15, ( intptr_t ) int15_fakee820,
+       unhook_bios_interrupt ( 0x15, ( unsigned int ) int15_fakee820,
                                &real_int15_vector );
 }
@@ -76,9 +76,9 @@ extern struct segoff __text16 ( int15_vector );
 extern char _textdata[];
 extern char _etextdata[];
 extern char _text16_memsz[];
-#define _text16_memsz ( ( size_t ) _text16_memsz )
+#define _text16_memsz ( ( unsigned int ) _text16_memsz )
 extern char _data16_memsz[];
-#define _data16_memsz ( ( size_t ) _data16_memsz )
+#define _data16_memsz ( ( unsigned int ) _data16_memsz )
 
 /**
  * Hide region of memory from system memory map
@@ -179,7 +179,8 @@ static void hide_etherboot ( void ) {
        }
 
        /* Hook INT 15 */
-       hook_bios_interrupt ( 0x15, ( intptr_t ) int15, &int15_vector );
+       hook_bios_interrupt ( 0x15, ( unsigned int ) int15,
+                             &int15_vector );
 
        /* Dump memory map after mangling */
        DBG ( "Hidden iPXE from system memory map\n" );
@@ -209,7 +210,7 @@ static void unhide_etherboot ( int flags __unused ) {
        }
 
        /* Try to unhook INT 15 */
-       if ( ( rc = unhook_bios_interrupt ( 0x15, ( intptr_t ) int15,
+       if ( ( rc = unhook_bios_interrupt ( 0x15, ( unsigned int ) int15,
                                            &int15_vector ) ) != 0 ) {
                DBG ( "Cannot unhook INT15: %s\n", strerror ( rc ) );
                /* Leave it hooked; there's nothing else we can do,
@@ -92,7 +92,7 @@ static unsigned int extmemsize_e801 ( void ) {
                                           "int $0x15\n\t"
                                           "pushfw\n\t"
                                           "popw %w0\n\t" )
-                              : "=R" ( flags ),
+                              : "=r" ( flags ),
                                 "=a" ( extmem_1m_to_16m_k ),
                                 "=b" ( extmem_16m_plus_64k ),
                                 "=c" ( confmem_1m_to_16m_k ),
@@ -174,7 +174,7 @@ static int meme820 ( struct memory_map *memmap ) {
        struct memory_region *prev_region = NULL;
        uint32_t next = 0;
        uint32_t smap;
-       uint32_t size;
+       size_t size;
        unsigned int flags;
        unsigned int discard_D;
 
@@ -216,7 +216,7 @@ static int meme820 ( struct memory_map *memmap ) {
                }
 
                if ( size < E820_MIN_SIZE ) {
-                       DBG ( "INT 15,e820 returned only %d bytes\n", size );
+                       DBG ( "INT 15,e820 returned only %zd bytes\n", size );
                        return -EINVAL;
                }
 
similarity index 93%
rename from roms/ipxe/src/arch/x86/image/bootsector.c
rename to roms/ipxe/src/arch/i386/image/bootsector.c
index 67dad04..dba8761 100644 (file)
@@ -71,9 +71,9 @@ int call_bootsector ( unsigned int segment, unsigned int offset,
        DBG ( "Booting from boot sector at %04x:%04x\n", segment, offset );
 
        /* Hook INTs 18 and 19 to capture failure paths */
-       hook_bios_interrupt ( 0x18, ( intptr_t ) bootsector_exec_fail,
+       hook_bios_interrupt ( 0x18, ( unsigned int ) bootsector_exec_fail,
                              &int18_vector );
-       hook_bios_interrupt ( 0x19, ( intptr_t ) bootsector_exec_fail,
+       hook_bios_interrupt ( 0x19, ( unsigned int ) bootsector_exec_fail,
                              &int19_vector );
 
        /* Boot the loaded sector
@@ -132,9 +132,9 @@ int call_bootsector ( unsigned int segment, unsigned int offset,
        DBG ( "Booted disk returned via INT 18 or 19\n" );
 
        /* Unhook INTs 18 and 19 */
-       unhook_bios_interrupt ( 0x18, ( intptr_t ) bootsector_exec_fail,
+       unhook_bios_interrupt ( 0x18, ( unsigned int ) bootsector_exec_fail,
                                &int18_vector );
-       unhook_bios_interrupt ( 0x19, ( intptr_t ) bootsector_exec_fail,
+       unhook_bios_interrupt ( 0x19, ( unsigned int ) bootsector_exec_fail,
                                &int19_vector );
        
        return -ECANCELED;
similarity index 99%
rename from roms/ipxe/src/arch/x86/image/bzimage.c
rename to roms/ipxe/src/arch/i386/image/bzimage.c
index d9b5ddc..a64206c 100644 (file)
@@ -631,9 +631,9 @@ static int bzimage_exec ( struct image *image ) {
                                           "pushw %w2\n\t"
                                           "pushw $0\n\t"
                                           "lret\n\t" )
-                              : : "R" ( bzimg.rm_kernel_seg ),
-                                  "R" ( bzimg.rm_heap ),
-                                  "R" ( bzimg.rm_kernel_seg + 0x20 ) );
+                              : : "r" ( bzimg.rm_kernel_seg ),
+                                  "r" ( bzimg.rm_heap ),
+                                  "r" ( bzimg.rm_kernel_seg + 0x20 ) );
 
        /* There is no way for the image to return, since we provide
         * no return address.
similarity index 77%
rename from roms/ipxe/src/arch/x86/image/com32.c
rename to roms/ipxe/src/arch/i386/image/com32.c
index 0166528..c12ffb6 100644 (file)
@@ -40,7 +40,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/segment.h>
 #include <ipxe/init.h>
 #include <ipxe/io.h>
-#include <ipxe/console.h>
 
 /**
  * Execute COMBOOT image
@@ -76,6 +75,8 @@ static int com32_exec_loop ( struct image *image ) {
 
                assert ( avail_mem_top != 0 );
 
+               com32_external_esp = phys_to_virt ( avail_mem_top );
+
                /* Hook COMBOOT API interrupts */
                hook_comboot_interrupts();
 
@@ -86,44 +87,34 @@ static int com32_exec_loop ( struct image *image ) {
                 */
                unregister_image ( image );
 
-               __asm__ __volatile__ ( PHYS_CODE (
-                       /* Preserve registers */
-                       "pushal\n\t"
-                       /* Preserve stack pointer */
-                       "subl $4, %k0\n\t"
-                       "movl %%esp, (%k0)\n\t"
-                       /* Switch to COM32 stack */
-                       "movl %k0, %%esp\n\t"
-                       /* Enable interrupts */
-                       "sti\n\t"
-                       /* Construct stack frame */
-                       "pushl %k1\n\t"
-                       "pushl %k2\n\t"
-                       "pushl %k3\n\t"
-                       "pushl %k4\n\t"
-                       "pushl %k5\n\t"
-                       "pushl %k6\n\t"
-                       "pushl $6\n\t"
-                       /* Call COM32 entry point */
-                       "movl %k7, %k0\n\t"
-                       "call *%k0\n\t"
-                       /* Disable interrupts */
-                       "cli\n\t"
-                       /* Restore stack pointer */
-                       "movl 24(%%esp), %%esp\n\t"
-                       /* Restore registers */
-                       "popal\n\t" )
-                       :
-                       : "r" ( avail_mem_top ),
-                         "r" ( virt_to_phys ( com32_cfarcall_wrapper ) ),
-                         "r" ( virt_to_phys ( com32_farcall_wrapper ) ),
-                         "r" ( get_fbms() * 1024 - ( COM32_BOUNCE_SEG << 4 ) ),
-                         "i" ( COM32_BOUNCE_SEG << 4 ),
-                         "r" ( virt_to_phys ( com32_intcall_wrapper ) ),
-                         "r" ( virt_to_phys ( image->cmdline ?
-                                              image->cmdline : "" ) ),
-                         "i" ( COM32_START_PHYS )
-                       : "memory" );
+               __asm__ __volatile__ (
+                       "movl %%esp, (com32_internal_esp)\n\t" /* Save internal virtual address space ESP */
+                       "movl (com32_external_esp), %%esp\n\t" /* Switch to COM32 ESP (top of available memory) */
+                       "call _virt_to_phys\n\t"               /* Switch to flat physical address space */
+                       "sti\n\t"                              /* Enable interrupts */
+                       "pushl %0\n\t"                         /* Pointer to CDECL helper function */
+                       "pushl %1\n\t"                         /* Pointer to FAR call helper function */
+                       "pushl %2\n\t"                         /* Size of low memory bounce buffer */
+                       "pushl %3\n\t"                         /* Pointer to low memory bounce buffer */
+                       "pushl %4\n\t"                         /* Pointer to INT call helper function */
+                       "pushl %5\n\t"                         /* Pointer to the command line arguments */
+                       "pushl $6\n\t"                         /* Number of additional arguments */
+                       "call *%6\n\t"                         /* Execute image */
+                       "cli\n\t"                              /* Disable interrupts */
+                       "call _phys_to_virt\n\t"               /* Switch back to internal virtual address space */
+                       "movl (com32_internal_esp), %%esp\n\t" /* Switch back to internal stack */
+               :
+               :
+                       /* %0 */ "r" ( virt_to_phys ( com32_cfarcall_wrapper ) ),
+                       /* %1 */ "r" ( virt_to_phys ( com32_farcall_wrapper ) ),
+                       /* %2 */ "r" ( get_fbms() * 1024 - (COM32_BOUNCE_SEG << 4) ),
+                       /* %3 */ "i" ( COM32_BOUNCE_SEG << 4 ),
+                       /* %4 */ "r" ( virt_to_phys ( com32_intcall_wrapper ) ),
+                       /* %5 */ "r" ( virt_to_phys ( image->cmdline ?
+                                                     image->cmdline : "" ) ),
+                       /* %6 */ "r" ( COM32_START_PHYS )
+               :
+                       "memory" );
                DBGC ( image, "COM32 %p: returned\n", image );
                break;
 
@@ -155,7 +146,7 @@ static int com32_exec_loop ( struct image *image ) {
 
 /**
  * Check image name extension
- *
+ * 
  * @v image            COM32 image
  * @ret rc             Return status code
  */
@@ -163,7 +154,7 @@ static int com32_identify ( struct image *image ) {
        const char *ext;
        static const uint8_t magic[] = { 0xB8, 0xFF, 0x4C, 0xCD, 0x21 };
        uint8_t buf[5];
-
+       
        if ( image->len >= 5 ) {
                /* Check for magic number
                 * mov eax,21cd4cffh
@@ -290,9 +281,6 @@ static int com32_exec ( struct image *image ) {
                return rc;
        }
 
-       /* Reset console */
-       console_reset();
-
        return com32_exec_loop ( image );
 }
 
similarity index 98%
rename from roms/ipxe/src/arch/x86/image/comboot.c
rename to roms/ipxe/src/arch/i386/image/comboot.c
index 9a847f0..1ec0233 100644 (file)
@@ -40,7 +40,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/segment.h>
 #include <ipxe/init.h>
 #include <ipxe/features.h>
-#include <ipxe/console.h>
 
 FEATURE ( FEATURE_IMAGE, "COMBOOT", DHCP_EB_FEATURE_COMBOOT, 1 );
 
@@ -64,7 +63,7 @@ struct comboot_psp {
 
 /**
  * Copy command line to PSP
- *
+ * 
  * @v image            COMBOOT image
  */
 static void comboot_copy_cmdline ( struct image * image, userptr_t seg_userptr ) {
@@ -97,7 +96,7 @@ static void comboot_copy_cmdline ( struct image * image, userptr_t seg_userptr )
 
 /**
  * Initialize PSP
- *
+ * 
  * @v image            COMBOOT image
  * @v seg_userptr      segment to initialize
  */
@@ -213,7 +212,7 @@ static int comboot_exec_loop ( struct image *image ) {
 
 /**
  * Check image name extension
- *
+ * 
  * @v image            COMBOOT image
  * @ret rc             Return status code
  */
@@ -254,7 +253,7 @@ static int comboot_prepare_segment ( struct image *image )
        seg_userptr = real_to_user ( COMBOOT_PSP_SEG, 0 );
 
        /* Allow etra 0x100 bytes before image for PSP */
-       filesz = image->len + 0x100;
+       filesz = image->len + 0x100; 
 
        /* Ensure the entire 64k segment is free */
        memsz = 0xFFFF;
@@ -289,7 +288,7 @@ static int comboot_probe ( struct image *image ) {
 
        /* Check if this is a COMBOOT image */
        if ( ( rc = comboot_identify ( image ) ) != 0 ) {
-
+               
                return rc;
        }
 
@@ -304,7 +303,7 @@ static int comboot_probe ( struct image *image ) {
  */
 static int comboot_exec ( struct image *image ) {
        int rc;
-
+       
        /* Sanity check for filesize */
        if( image->len >= 0xFF00 ) {
                DBGC( image, "COMBOOT %p: image too large\n",
@@ -317,9 +316,6 @@ static int comboot_exec ( struct image *image ) {
                return rc;
        }
 
-       /* Reset console */
-       console_reset();
-
        return comboot_exec_loop ( image );
 }
 
similarity index 99%
rename from roms/ipxe/src/arch/x86/image/nbi.c
rename to roms/ipxe/src/arch/i386/image/nbi.c
index b691bee..9904614 100644 (file)
@@ -241,7 +241,7 @@ static int nbi_process_segments ( struct image *image,
  */
 static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
        int discard_D, discard_S, discard_b;
-       int32_t rc;
+       int rc;
 
        DBGC ( image, "NBI %p executing 16-bit image at %04x:%04x\n", image,
               imgheader->execaddr.segoff.segment,
@@ -283,7 +283,7 @@ static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) {
                0
        };
        int discard_D, discard_S, discard_b;
-       int32_t rc;
+       int rc;
 
        DBGC ( image, "NBI %p executing 32-bit image at %lx\n",
               image, imgheader->execaddr.linear );
similarity index 98%
rename from roms/ipxe/src/arch/x86/image/pxe_image.c
rename to roms/ipxe/src/arch/i386/image/pxe_image.c
index 297a618..5b0f6eb 100644 (file)
@@ -78,9 +78,6 @@ static int pxe_exec ( struct image *image ) {
        /* Activate PXE */
        pxe_activate ( netdev );
 
-       /* Construct fake DHCP packets */
-       pxe_fake_cached_info();
-
        /* Set PXE command line */
        pxe_cmdline = image->cmdline;
 
similarity index 95%
rename from roms/ipxe/src/arch/x86/include/biosint.h
rename to roms/ipxe/src/arch/i386/include/biosint.h
index f47116f..67d6a38 100644 (file)
@@ -29,6 +29,5 @@ extern void hook_bios_interrupt ( unsigned int interrupt, unsigned int handler,
 extern int unhook_bios_interrupt ( unsigned int interrupt,
                                   unsigned int handler,
                                   struct segoff *chain_vector );
-extern void check_bios_interrupts ( void );
 
 #endif /* BIOSINT_H */
index 7c4a093..8720113 100644 (file)
@@ -9,7 +9,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #ifndef ASSEMBLY
 
 /** Declare a function with standard calling conventions */
-#define __asmcall __attribute__ (( used, cdecl, regparm(0) ))
+#define __asmcall __attribute__ (( cdecl, regparm(0) ))
 
 /**
  * Declare a function with libgcc implicit linkage
@@ -3,7 +3,7 @@
 
 /** @file
  *
- * x86-specific entropy API implementations
+ * i386-specific entropy API implementations
  *
  */
 
index 0ba58af..3565c8a 100644 (file)
@@ -46,4 +46,27 @@ hv_call ( struct hv_hypervisor *hv, unsigned int code, const void *in,
        return result;
 }
 
+/**
+ * Set bit atomically
+ *
+ * @v bits             Bit field
+ * @v bit              Bit to set
+ */
+static inline __attribute__ (( always_inline )) void
+hv_set_bit ( void *bits, unsigned int bit ) {
+       struct {
+               uint32_t dword[ ( bit / 32 ) + 1 ];
+       } *dwords = bits;
+
+       /* Set bit using "lock bts".  Inform compiler that any memory
+        * from the start of the bit field up to and including the
+        * dword containing this bit may be modified.  (This is
+        * overkill but shouldn't matter in practice since we're
+        * unlikely to subsequently read other bits from the same bit
+        * field.)
+        */
+       __asm__ __volatile__ ( "lock bts %1, %0"
+                              : "+m" ( *dwords ) : "Ir" ( bit ) );
+}
+
 #endif /* _BITS_HYPERV_H */
similarity index 79%
rename from roms/ipxe/src/arch/x86/include/bits/nap.h
rename to roms/ipxe/src/arch/i386/include/bits/nap.h
index 7103b94..e8bcfd1 100644 (file)
@@ -3,7 +3,7 @@
 
 /** @file
  *
- * x86-specific CPU sleeping API implementations
+ * i386-specific CPU sleeping API implementations
  *
  */
 
similarity index 79%
rename from roms/ipxe/src/arch/x86/include/bits/reboot.h
rename to roms/ipxe/src/arch/i386/include/bits/reboot.h
index e702dd3..803dacf 100644 (file)
@@ -3,7 +3,7 @@
 
 /** @file
  *
- * x86-specific reboot API implementations
+ * i386-specific reboot API implementations
  *
  */
 
@@ -3,7 +3,7 @@
 
 /** @file
  *
- * x86-specific sanboot API implementations
+ * i386-specific sanboot API implementations
  *
  */
 
similarity index 79%
rename from roms/ipxe/src/arch/x86/include/bits/smbios.h
rename to roms/ipxe/src/arch/i386/include/bits/smbios.h
index 9977c87..2ab31e7 100644 (file)
@@ -3,7 +3,7 @@
 
 /** @file
  *
- * x86-specific SMBIOS API implementations
+ * i386-specific SMBIOS API implementations
  *
  */
 
similarity index 79%
rename from roms/ipxe/src/arch/x86/include/bits/time.h
rename to roms/ipxe/src/arch/i386/include/bits/time.h
index 556d96f..6a5d63d 100644 (file)
@@ -3,7 +3,7 @@
 
 /** @file
  *
- * x86-specific time API implementations
+ * i386-specific time API implementations
  *
  */
 
similarity index 81%
rename from roms/ipxe/src/arch/x86/include/bits/timer.h
rename to roms/ipxe/src/arch/i386/include/bits/timer.h
index b0ff5ee..f7d86d7 100644 (file)
@@ -3,7 +3,7 @@
 
 /** @file
  *
- * x86-specific timer API implementations
+ * i386-specific timer API implementations
  *
  */
 
@@ -3,7 +3,7 @@
 
 /** @file
  *
- * x86-specific user access API implementations
+ * i386-specific user access API implementations
  *
  */
 
@@ -3,7 +3,7 @@
 
 /** @file
  *
- * x86-specific user memory allocation API implementations
+ * i386-specific user memory allocation API implementations
  *
  */
 
similarity index 95%
rename from roms/ipxe/src/arch/x86/include/comboot.h
rename to roms/ipxe/src/arch/i386/include/comboot.h
index 69c6ef0..2d2f04f 100644 (file)
@@ -10,7 +10,7 @@
 FILE_LICENCE ( GPL2_OR_LATER );
 
 #include <stdint.h>
-#include <rmsetjmp.h>
+#include <setjmp.h>
 #include <ipxe/in.h>
 
 /** Segment used for COMBOOT PSP and image */
@@ -29,7 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #define COMBOOT_FEATURE_LOCAL_BOOT (1 << 0)
 #define COMBOOT_FEATURE_IDLE_LOOP  (1 << 1)
 
-/** Maximum number of shuffle descriptors for
+/** Maximum number of shuffle descriptors for 
  * shuffle and boot functions
  * (INT 22h AX=0012h, 001Ah, 001Bh)
  */
@@ -102,7 +102,7 @@ typedef struct {
 extern void hook_comboot_interrupts ( );
 extern void unhook_comboot_interrupts ( );
 
-/* These are not the correct prototypes, but it doens't matter,
+/* These are not the correct prototypes, but it doens't matter, 
  * as we only ever get the address of these functions;
  * they are only called from COM32 code running in PHYS_CODE
  */
@@ -116,6 +116,8 @@ extern int comboot_resolv ( const char *name, struct in_addr *address );
 /* setjmp/longjmp context buffer used to return after loading an image */
 extern rmjmp_buf comboot_return;
 
+extern void *com32_external_esp;
+
 #define COMBOOT_EXIT 1
 #define COMBOOT_EXIT_RUN_KERNEL 2
 #define COMBOOT_EXIT_COMMAND 3
index 52cce78..416ae34 100644 (file)
@@ -47,10 +47,12 @@ enum {
 };
 
 /* Interrupt vectors */
-extern void gdbmach_sigfpe ( void );
-extern void gdbmach_sigtrap ( void );
-extern void gdbmach_sigstkflt ( void );
-extern void gdbmach_sigill ( void );
+extern void gdbmach_nocode_sigfpe ( void );
+extern void gdbmach_nocode_sigtrap ( void );
+extern void gdbmach_nocode_sigstkflt ( void );
+extern void gdbmach_nocode_sigill ( void );
+extern void gdbmach_withcode_sigbus ( void );
+extern void gdbmach_withcode_sigsegv ( void );
 
 static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) {
        regs [ GDBMACH_EIP ] = pc;
@@ -15,4 +15,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define SANBOOT_PREFIX_pcbios __pcbios_
 #endif
 
+/**
+ * Get default SAN drive number
+ *
+ * @ret drive          Default drive number
+ */
+static inline __always_inline unsigned int
+SANBOOT_INLINE ( pcbios, san_default_drive ) ( void ) {
+       /* Default to booting from first hard disk */
+       return 0x80;
+}
+
 #endif /* _IPXE_BIOS_SANBOOT_H */
similarity index 56%
rename from roms/ipxe/src/arch/x86/include/librm.h
rename to roms/ipxe/src/arch/i386/include/librm.h
index 311748b..a8a578a 100644 (file)
@@ -7,62 +7,19 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  * Don't change these unless you really know what you're doing.
  */
+
 #define VIRTUAL_CS 0x08
 #define VIRTUAL_DS 0x10
 #define PHYSICAL_CS 0x18
 #define PHYSICAL_DS 0x20
 #define REAL_CS 0x28
 #define REAL_DS 0x30
-#define P2R_DS 0x38
-#define LONG_CS 0x40
-
-/* Calculate symbol address within VIRTUAL_CS or VIRTUAL_DS
- *
- * In a 64-bit build, we set the bases of VIRTUAL_CS and VIRTUAL_DS
- * such that truncating a .textdata symbol value to 32 bits gives a
- * valid 32-bit virtual address.
- *
- * The C code is compiled with -mcmodel=kernel and so we must place
- * all .textdata symbols within the negative 2GB of the 64-bit address
- * space.  Consequently, all .textdata symbols will have the MSB set
- * after truncation to 32 bits.  This means that a straightforward
- * R_X86_64_32 relocation record for the symbol will fail, since the
- * truncated symbol value will not correctly zero-extend to the
- * original 64-bit value.
- *
- * Using an R_X86_64_32S relocation record would work, but there is no
- * (sensible) way to generate these relocation records within 32-bit
- * or 16-bit code.
- *
- * The simplest solution is to generate an R_X86_64_32 relocation
- * record with an addend of (-0xffffffff00000000).  Since all
- * .textdata symbols are within the negative 2GB of the 64-bit address
- * space, this addend acts to effectively truncate the symbol to 32
- * bits, thereby matching the semantics of the R_X86_64_32 relocation
- * records generated for 32-bit and 16-bit code.
- *
- * In a 32-bit build, this problem does not exist, and we can just use
- * the .textdata symbol values directly.
- */
-#ifdef __x86_64__
-#define VIRTUAL(address) ( (address) - 0xffffffff00000000 )
-#else
-#define VIRTUAL(address) (address)
+#if 0
+#define LONG_CS 0x38
+#define LONG_DS 0x40
 #endif
 
-#ifdef ASSEMBLY
-
-/**
- * Call C function from real-mode code
- *
- * @v function         C function
- */
-.macro virtcall function
-       pushl   $VIRTUAL(\function)
-       call    virt_call
-.endm
-
-#else /* ASSEMBLY */
+#ifndef ASSEMBLY
 
 #ifdef UACCESS_LIBRM
 #define UACCESS_PREFIX_librm
@@ -70,17 +27,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define UACCESS_PREFIX_librm __librm_
 #endif
 
-/**
- * Call C function from real-mode code
- *
- * @v function         C function
- */
-#define VIRT_CALL( function )                                          \
-       "pushl $( " _S2 ( VIRTUAL ( function ) ) " )\n\t"               \
-       "call virt_call\n\t"
-
 /* Variables in librm.S */
-extern const unsigned long virt_offset;
+extern unsigned long virt_offset;
 
 /**
  * Convert physical address to user pointer
@@ -90,15 +38,6 @@ extern const unsigned long virt_offset;
  */
 static inline __always_inline userptr_t
 UACCESS_INLINE ( librm, phys_to_user ) ( unsigned long phys_addr ) {
-
-       /* In a 64-bit build, any valid physical address is directly
-        * usable as a virtual address, since the low 4GB is
-        * identity-mapped.
-        */
-       if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) )
-               return phys_addr;
-
-       /* In a 32-bit build, subtract virt_offset */
        return ( phys_addr - virt_offset );
 }
 
@@ -111,20 +50,7 @@ UACCESS_INLINE ( librm, phys_to_user ) ( unsigned long phys_addr ) {
  */
 static inline __always_inline unsigned long
 UACCESS_INLINE ( librm, user_to_phys ) ( userptr_t userptr, off_t offset ) {
-       unsigned long addr = ( userptr + offset );
-
-       /* In a 64-bit build, any virtual address in the low 4GB is
-        * directly usable as a physical address, since the low 4GB is
-        * identity-mapped.
-        */
-       if ( ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) &&
-            ( addr <= 0xffffffffUL ) )
-               return addr;
-
-       /* In a 32-bit build or in a 64-bit build with a virtual
-        * address above 4GB: add virt_offset
-        */
-       return ( addr + virt_offset );
+       return ( userptr + offset + virt_offset );
 }
 
 static inline __always_inline userptr_t
@@ -193,8 +119,8 @@ UACCESS_INLINE ( librm, memchr_user ) ( userptr_t buffer, off_t offset,
  *
  */
 
-extern char * const data16;
-extern char * const text16;
+extern char *data16;
+extern char *text16;
 
 #define __data16( variable )                                           \
        __attribute__ (( section ( ".data16" ) ))                       \
@@ -239,33 +165,27 @@ extern char * const text16;
 /* Variables in librm.S, present in the normal data segment */
 extern uint16_t rm_sp;
 extern uint16_t rm_ss;
-extern const uint16_t __text16 ( rm_cs );
+extern uint16_t __text16 ( rm_cs );
 #define rm_cs __use_text16 ( rm_cs )
-extern const uint16_t __text16 ( rm_ds );
+extern uint16_t __text16 ( rm_ds );
 #define rm_ds __use_text16 ( rm_ds )
 
 extern uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size );
 extern void remove_user_from_rm_stack ( userptr_t data, size_t size );
 
-/* CODE_DEFAULT: restore default .code32/.code64 directive */
-#ifdef __x86_64__
-#define CODE_DEFAULT ".code64"
-#else
-#define CODE_DEFAULT ".code32"
-#endif
-
 /* TEXT16_CODE: declare a fragment of code that resides in .text16 */
 #define TEXT16_CODE( asm_code_str )                    \
        ".section \".text16\", \"ax\", @progbits\n\t"   \
        ".code16\n\t"                                   \
        asm_code_str "\n\t"                             \
-       CODE_DEFAULT "\n\t"                             \
+       ".code32\n\t"                                   \
        ".previous\n\t"
 
 /* REAL_CODE: declare a fragment of code that executes in real mode */
 #define REAL_CODE( asm_code_str )                      \
-       "push $1f\n\t"                                  \
+       "pushl $1f\n\t"                                 \
        "call real_call\n\t"                            \
+       "addl $4, %%esp\n\t"                            \
        TEXT16_CODE ( "\n1:\n\t"                        \
                      asm_code_str                      \
                      "\n\t"                            \
@@ -273,38 +193,23 @@ extern void remove_user_from_rm_stack ( userptr_t data, size_t size );
 
 /* PHYS_CODE: declare a fragment of code that executes in flat physical mode */
 #define PHYS_CODE( asm_code_str )                      \
-       "push $1f\n\t"                                  \
-       "call phys_call\n\t"                            \
-       ".section \".text.phys\", \"ax\", @progbits\n\t"\
-       ".code32\n\t"                                   \
-       "\n1:\n\t"                                      \
+       "call _virt_to_phys\n\t"                        \
        asm_code_str                                    \
-       "\n\t"                                          \
-       "ret\n\t"                                       \
-       CODE_DEFAULT "\n\t"                             \
-       ".previous\n\t"
+       "call _phys_to_virt\n\t"
 
 /** Number of interrupts */
 #define NUM_INT 256
 
-/** A 32-bit interrupt descriptor table register */
-struct idtr32 {
+/** An interrupt descriptor table register */
+struct idtr {
        /** Limit */
        uint16_t limit;
        /** Base */
        uint32_t base;
 } __attribute__ (( packed ));
 
-/** A 64-bit interrupt descriptor table register */
-struct idtr64 {
-       /** Limit */
-       uint16_t limit;
-       /** Base */
-       uint64_t base;
-} __attribute__ (( packed ));
-
-/** A 32-bit interrupt descriptor table entry */
-struct interrupt32_descriptor {
+/** An interrupt descriptor table entry */
+struct interrupt_descriptor {
        /** Low 16 bits of address */
        uint16_t low;
        /** Code segment */
@@ -317,44 +222,23 @@ struct interrupt32_descriptor {
        uint16_t high;
 } __attribute__ (( packed ));
 
-/** A 64-bit interrupt descriptor table entry */
-struct interrupt64_descriptor {
-       /** Low 16 bits of address */
-       uint16_t low;
-       /** Code segment */
-       uint16_t segment;
-       /** Unused */
-       uint8_t unused;
-       /** Type and attributes */
-       uint8_t attr;
-       /** Middle 16 bits of address */
-       uint16_t mid;
-       /** High 32 bits of address */
-       uint32_t high;
-       /** Reserved */
-       uint32_t reserved;
-} __attribute__ (( packed ));
-
 /** Interrupt descriptor is present */
 #define IDTE_PRESENT 0x80
 
 /** Interrupt descriptor 32-bit interrupt gate type */
 #define IDTE_TYPE_IRQ32 0x0e
 
-/** Interrupt descriptor 64-bit interrupt gate type */
-#define IDTE_TYPE_IRQ64 0x0e
-
 /** An interrupt vector
  *
  * Each interrupt vector comprises an eight-byte fragment of code:
  *
- *   50                        pushl %eax (or pushq %rax in long mode)
+ *   60                        pushal
  *   b0 xx             movb $INT, %al
  *   e9 xx xx xx xx    jmp interrupt_wrapper
  */
 struct interrupt_vector {
-       /** "push" instruction */
-       uint8_t push;
+       /** "pushal" instruction */
+       uint8_t pushal;
        /** "movb" instruction */
        uint8_t movb;
        /** Interrupt number */
@@ -367,8 +251,8 @@ struct interrupt_vector {
        uint8_t next[0];
 } __attribute__ (( packed ));
 
-/** "push %eax" instruction */
-#define PUSH_INSN 0x50
+/** "pushal" instruction */
+#define PUSHAL_INSN 0x60
 
 /** "movb" instruction */
 #define MOVB_INSN 0xb0
@@ -378,51 +262,6 @@ struct interrupt_vector {
 
 extern void set_interrupt_vector ( unsigned int intr, void *vector );
 
-/** A page table */
-struct page_table {
-       /** Page address and flags */
-       uint64_t page[512];
-};
-
-/** Page flags */
-enum page_flags {
-       /** Page is present */
-       PAGE_P = 0x01,
-       /** Page is writable */
-       PAGE_RW = 0x02,
-       /** Page is accessible by user code */
-       PAGE_US = 0x04,
-       /** Page-level write-through */
-       PAGE_PWT = 0x08,
-       /** Page-level cache disable */
-       PAGE_PCD = 0x10,
-       /** Page is a large page */
-       PAGE_PS = 0x80,
-       /** Page is the last page in an allocation
-        *
-        * This bit is ignored by the hardware.  We use it to track
-        * the size of allocations made by ioremap().
-        */
-       PAGE_LAST = 0x800,
-};
-
-/** The I/O space page table */
-extern struct page_table io_pages;
-
-/** I/O page size
- *
- * We choose to use 2MB pages for I/O space, to minimise the number of
- * page table entries required.
- */
-#define IO_PAGE_SIZE 0x200000UL
-
-/** I/O page base address
- *
- * We choose to place I/O space immediately above the identity-mapped
- * 32-bit address space.
- */
-#define IO_BASE ( ( void * ) 0x100000000ULL )
-
 #endif /* ASSEMBLY */
 
 #endif /* LIBRM_H */
similarity index 99%
rename from roms/ipxe/src/arch/x86/include/pxe.h
rename to roms/ipxe/src/arch/i386/include/pxe.h
index 54649b5..66d7526 100644 (file)
@@ -192,7 +192,6 @@ extern struct net_device *pxe_netdev;
 extern const char *pxe_cmdline;
 
 extern void pxe_set_netdev ( struct net_device *netdev );
-extern void pxe_fake_cached_info ( void );
 extern PXENV_EXIT_t pxenv_tftp_read_file ( struct s_PXENV_TFTP_READ_FILE
                                           *tftp_read_file );
 extern PXENV_EXIT_t undi_loader ( struct s_UNDI_LOADER *undi_loader );
similarity index 97%
rename from roms/ipxe/src/arch/x86/include/pxe_call.h
rename to roms/ipxe/src/arch/i386/include/pxe_call.h
index 2ad0a95..cbd5483 100644 (file)
@@ -10,7 +10,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <pxe_api.h>
 #include <realmode.h>
-#include <rmsetjmp.h>
+#include <setjmp.h>
 
 struct net_device;
 
similarity index 98%
rename from roms/ipxe/src/arch/x86/include/registers.h
rename to roms/ipxe/src/arch/i386/include/registers.h
index dd3b59f..d9aa3c3 100644 (file)
@@ -167,7 +167,7 @@ struct i386_seg_regs {
  *
  * @endcode
  *
- * virt_call() and kir_call() create this data structure on the stack
+ * prot_call() and kir_call() create this data structure on the stack
  * and pass in a pointer to this structure.
  *
  */
index 9856669..fe1a9ef 100644 (file)
@@ -4,6 +4,7 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <stdint.h>
+#include <realmode.h>
 
 /** A jump buffer */
 typedef struct {
@@ -21,10 +22,29 @@ typedef struct {
        uint32_t ebp;
 } jmp_buf[1];
 
+/** A real-mode-extended jump buffer */
+typedef struct {
+       /** Jump buffer */
+       jmp_buf env;
+       /** Real-mode stack pointer */
+       segoff_t rm_stack;
+} rmjmp_buf[1];
+
 extern int __asmcall __attribute__ (( returns_twice ))
 setjmp ( jmp_buf env );
 
 extern void __asmcall __attribute__ (( noreturn ))
 longjmp ( jmp_buf env, int val );
 
+#define rmsetjmp( _env ) ( {                                   \
+       (_env)->rm_stack.segment = rm_ss;                       \
+       (_env)->rm_stack.offset = rm_sp;                        \
+       setjmp ( (_env)->env ); } )                             \
+
+#define rmlongjmp( _env, _val ) do {                           \
+       rm_ss = (_env)->rm_stack.segment;                       \
+       rm_sp = (_env)->rm_stack.offset;                        \
+       longjmp ( (_env)->env, (_val) );                        \
+       } while ( 0 )
+
 #endif /* _SETJMP_H */
@@ -46,7 +46,7 @@ static void bios_reboot ( int warm ) {
        put_real ( flag, BDA_SEG, BDA_REBOOT );
 
        /* Jump to system reset vector */
-       __asm__ __volatile__ ( REAL_CODE ( "ljmp $0xf000, $0xfff0" ) );
+       __asm__ __volatile__ ( REAL_CODE ( "ljmp $0xf000, $0xfff0" ) : : );
 }
 
 PROVIDE_REBOOT ( pcbios, reboot, bios_reboot );
@@ -90,30 +90,3 @@ int unhook_bios_interrupt ( unsigned int interrupt, unsigned int handler,
        hooked_bios_interrupts--;
        return 0;
 }
-
-/**
- * Dump changes to interrupt vector table (for debugging)
- *
- */
-void check_bios_interrupts ( void ) {
-       static struct segoff vectors[256];
-       static uint8_t initialised;
-       struct segoff vector;
-       unsigned int i;
-
-       /* Print any changed interrupt vectors */
-       for ( i = 0; i < ( sizeof ( vectors ) / sizeof ( vectors[0] ) ); i++ ) {
-               copy_from_real ( &vector, 0, ( i * sizeof ( vector ) ),
-                                sizeof ( vector ) );
-               if ( memcmp ( &vector, &vectors[i], sizeof ( vector ) ) == 0 )
-                       continue;
-               if ( initialised ) {
-                       dbg_printf ( "INT %02x changed %04x:%04x => "
-                                    "%04x:%04x\n", i, vectors[i].segment,
-                                    vectors[i].offset, vector.segment,
-                                    vector.offset );
-               }
-               memcpy ( &vectors[i], &vector, sizeof ( vectors[i] ) );
-       }
-       initialised = 1;
-}
@@ -44,8 +44,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/pci.h>
 #include <ipxe/iso9660.h>
 #include <ipxe/eltorito.h>
-#include <ipxe/dhcp.h>
-#include <ipxe/settings.h>
 #include <realmode.h>
 #include <bios.h>
 #include <biosint.h>
@@ -1482,7 +1480,9 @@ static void int13_hook_vector ( void ) {
                             /* Clear OF, set CF, call int13() */
                             "orb $0, %%al\n\t" 
                             "stc\n\t"
-                            VIRT_CALL ( int13 )
+                            "pushl %0\n\t"
+                            "pushw %%cs\n\t"
+                            "call prot_call\n\t"
                             /* Chain if OF not set */
                             "jo 1f\n\t"
                             "pushfw\n\t"
@@ -1513,16 +1513,18 @@ static void int13_hook_vector ( void ) {
                             "\n3:\n\t"
                             "movw %%bp, %%sp\n\t"
                             "popw %%bp\n\t"
-                            "iret\n\t" ) : : );
+                            "iret\n\t" )
+              : : "i" ( int13 ) );
 
-       hook_bios_interrupt ( 0x13, ( intptr_t ) int13_wrapper, &int13_vector );
+       hook_bios_interrupt ( 0x13, ( unsigned int ) int13_wrapper,
+                             &int13_vector );
 }
 
 /**
  * Unhook INT 13 handler
  */
 static void int13_unhook_vector ( void ) {
-       unhook_bios_interrupt ( 0x13, ( intptr_t ) int13_wrapper,
+       unhook_bios_interrupt ( 0x13, ( unsigned int ) int13_wrapper,
                                &int13_vector );
 }
 
@@ -1590,7 +1592,7 @@ static void int13_free ( struct refcnt *refcnt ) {
  *
  * @v uri              URI
  * @v drive            Drive number
- * @ret drive          Drive number, or negative error
+ * @ret rc             Return status code
  *
  * Registers the drive with the INT 13 emulation subsystem, and hooks
  * the INT 13 interrupt vector (if not already hooked).
@@ -1605,10 +1607,6 @@ static int int13_hook ( struct uri *uri, unsigned int drive ) {
        int13_sync_num_drives();
        natural_drive = ( ( drive & 0x80 ) ? ( num_drives | 0x80 ) : num_fdds );
 
-       /* Use natural drive number if directed to do so */
-       if ( ( drive & 0x7f ) == 0x7f )
-               drive = natural_drive;
-
        /* Check that drive number is not in use */
        list_for_each_entry ( int13, &int13s, list ) {
                if ( int13->drive == drive ) {
@@ -1667,7 +1665,7 @@ static int int13_hook ( struct uri *uri, unsigned int drive ) {
        int13_sync_num_drives();
 
        free ( scratch );
-       return drive;
+       return 0;
 
  err_guess_geometry:
  err_parse_iso9660:
@@ -1988,32 +1986,7 @@ static int int13_describe ( unsigned int drive ) {
        return 0;
 }
 
-/** The "san-drive" setting */
-const struct setting san_drive_setting __setting ( SETTING_SANBOOT_EXTRA,
-                                                  san-drive ) = {
-       .name = "san-drive",
-       .description = "SAN drive number",
-       .tag = DHCP_EB_SAN_DRIVE,
-       .type = &setting_type_uint8,
-};
-
-/**
- * Get default SAN drive number
- *
- * @ret drive          Default drive number
- */
-static unsigned int int13_default_drive ( void ) {
-       unsigned long drive;
-
-       /* Use "san-drive" setting, if specified */
-       if ( fetch_uint_setting ( NULL, &san_drive_setting, &drive ) >= 0 )
-               return drive;
-
-       /* Otherwise, default to booting from first hard disk */
-       return 0x80;
-}
-
-PROVIDE_SANBOOT ( pcbios, san_default_drive, int13_default_drive );
+PROVIDE_SANBOOT_INLINE ( pcbios, san_default_drive );
 PROVIDE_SANBOOT ( pcbios, san_hook, int13_hook );
 PROVIDE_SANBOOT ( pcbios, san_unhook, int13_unhook );
 PROVIDE_SANBOOT ( pcbios, san_boot, int13_boot );
@@ -38,9 +38,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/memblock.h>
 #include <ipxe/umalloc.h>
 
-/** Maximum usable address for external allocated memory */
-#define EM_MAX_ADDRESS 0xffffffffUL
-
 /** Alignment of external allocated memory */
 #define EM_ALIGN ( 4 * 1024 )
 
@@ -65,56 +62,6 @@ static userptr_t bottom = UNULL;
 static size_t heap_size;
 
 /**
- * Find largest usable memory region
- *
- * @ret start          Start of region
- * @ret len            Length of region
- */
-size_t largest_memblock ( userptr_t *start ) {
-       struct memory_map memmap;
-       struct memory_region *region;
-       physaddr_t max = EM_MAX_ADDRESS;
-       physaddr_t region_start;
-       physaddr_t region_end;
-       size_t region_len;
-       unsigned int i;
-       size_t len = 0;
-
-       /* Avoid returning uninitialised data on error */
-       *start = UNULL;
-
-       /* Scan through all memory regions */
-       get_memmap ( &memmap );
-       for ( i = 0 ; i < memmap.count ; i++ ) {
-               region = &memmap.regions[i];
-               DBG ( "Considering [%llx,%llx)\n", region->start, region->end );
-
-               /* Truncate block to maximum physical address */
-               if ( region->start > max ) {
-                       DBG ( "...starts after maximum address %lx\n", max );
-                       continue;
-               }
-               region_start = region->start;
-               if ( region->end > max ) {
-                       DBG ( "...end truncated to maximum address %lx\n", max);
-                       region_end = 0; /* =max, given the wraparound */
-               } else {
-                       region_end = region->end;
-               }
-               region_len = ( region_end - region_start );
-
-               /* Use largest block */
-               if ( region_len > len ) {
-                       DBG ( "...new best block found\n" );
-                       *start = phys_to_user ( region_start );
-                       len = region_len;
-               }
-       }
-
-       return len;
-}
-
-/**
  * Initialise external heap
  *
  */
@@ -70,7 +70,7 @@ static int pcibios_num_bus ( void ) {
  */
 int pcibios_read ( struct pci_device *pci, uint32_t command, uint32_t *value ){
        int discard_b, discard_D;
-       uint16_t status;
+       int status;
 
        __asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
                                           "int $0x1a\n\t"
@@ -85,7 +85,7 @@ int pcibios_read ( struct pci_device *pci, uint32_t command, uint32_t *value ){
                                 "b" ( pci->busdevfn )
                               : "edx" );
 
-       return ( status >> 8 );
+       return ( ( status >> 8 ) & 0xff );
 }
 
 /**
@@ -98,7 +98,7 @@ int pcibios_read ( struct pci_device *pci, uint32_t command, uint32_t *value ){
  */
 int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){
        int discard_b, discard_c, discard_D;
-       uint16_t status;
+       int status;
 
        __asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
                                           "int $0x1a\n\t"
@@ -111,7 +111,7 @@ int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){
                                 "b" ( pci->busdevfn ), "c" ( value )
                               : "edx" );
        
-       return ( status >> 8 );
+       return ( ( status >> 8 ) & 0xff );
 }
 
 PROVIDE_PCIAPI ( pcbios, pci_num_bus, pcibios_num_bus );
@@ -36,6 +36,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <rtc.h>
 #include <ipxe/entropy.h>
 
+/** RTC "interrupt triggered" flag */
+static uint8_t __text16 ( rtc_flag );
+#define rtc_flag __use_text16 ( rtc_flag )
+
 /** RTC interrupt handler */
 extern void rtc_isr ( void );
 
@@ -54,27 +58,27 @@ static void rtc_hook_isr ( void ) {
                              /* Preserve registers */
                              "pushw %%ax\n\t"
                              /* Set "interrupt triggered" flag */
-                             "movb $0x01, %%cs:rtc_flag\n\t"
+                             "cs movb $0x01, %c0\n\t"
                              /* Read RTC status register C to
                               * acknowledge interrupt
                               */
-                             "movb %2, %%al\n\t"
-                             "outb %%al, %0\n\t"
-                             "inb %1\n\t"
+                             "movb %3, %%al\n\t"
+                             "outb %%al, %1\n\t"
+                             "inb %2\n\t"
                              /* Send EOI */
                              "movb $0x20, %%al\n\t"
                              "outb %%al, $0xa0\n\t"
                              "outb %%al, $0x20\n\t"
                              /* Restore registers and return */
                              "popw %%ax\n\t"
-                             "iret\n\t"
-                             "\nrtc_flag:\n\t"
-                             ".byte 0\n\t" )
+                             "iret\n\t" )
                :
-               : "i" ( CMOS_ADDRESS ), "i" ( CMOS_DATA ),
+               : "p" ( __from_text16 ( &rtc_flag ) ),
+                 "i" ( CMOS_ADDRESS ), "i" ( CMOS_DATA ),
                  "i" ( RTC_STATUS_C ) );
 
-       hook_bios_interrupt ( RTC_INT, ( intptr_t ) rtc_isr, &rtc_old_handler );
+       hook_bios_interrupt ( RTC_INT, ( unsigned int ) rtc_isr,
+                             &rtc_old_handler );
 }
 
 /**
@@ -84,7 +88,7 @@ static void rtc_hook_isr ( void ) {
 static void rtc_unhook_isr ( void ) {
        int rc;
 
-       rc = unhook_bios_interrupt ( RTC_INT, ( intptr_t ) rtc_isr,
+       rc = unhook_bios_interrupt ( RTC_INT, ( unsigned int ) rtc_isr,
                                     &rtc_old_handler );
        assert ( rc == 0 ); /* Should always be able to unhook */
 }
@@ -164,9 +168,9 @@ uint8_t rtc_sample ( void ) {
                REAL_CODE ( /* Enable interrupts */
                            "sti\n\t"
                            /* Wait for RTC interrupt */
-                           "movb %b2, %%cs:rtc_flag\n\t"
+                           "cs movb %b2, %c4\n\t"
                            "\n1:\n\t"
-                           "xchgb %b2, %%cs:rtc_flag\n\t" /* Serialize */
+                           "cs xchgb %b2, %c4\n\t" /* Serialize */
                            "testb %b2, %b2\n\t"
                            "jz 1b\n\t"
                            /* Read "before" TSC */
@@ -175,9 +179,9 @@ uint8_t rtc_sample ( void ) {
                            "pushl %0\n\t"
                            /* Wait for another RTC interrupt */
                            "xorb %b2, %b2\n\t"
-                           "movb %b2, %%cs:rtc_flag\n\t"
+                           "cs movb %b2, %c4\n\t"
                            "\n1:\n\t"
-                           "xchgb %b2, %%cs:rtc_flag\n\t" /* Serialize */
+                           "cs xchgb %b2, %c4\n\t" /* Serialize */
                            "testb %b2, %b2\n\t"
                            "jz 1b\n\t"
                            /* Read "after" TSC */
@@ -187,8 +191,8 @@ uint8_t rtc_sample ( void ) {
                            /* Disable interrupts */
                            "cli\n\t"
                            )
-               : "=a" ( after ), "=d" ( before ), "=Q" ( temp )
-               : "2" ( 0 ) );
+               : "=a" ( after ), "=d" ( before ), "=q" ( temp )
+               : "2" ( 0 ), "p" ( __from_text16 ( &rtc_flag ) ) );
 
        return ( after - before );
 }
@@ -60,21 +60,12 @@ struct console_driver bios_console __attribute__ (( weak ));
 #define EIO_VBE( code )                                                        \
        EUNIQ ( EINFO_EIO, (code), EIO_FAILED, EIO_HARDWARE, EIO_MODE )
 
-/* Set default console usage if applicable
- *
- * We accept either CONSOLE_FRAMEBUFFER or CONSOLE_VESAFB.
- */
-#if ( defined ( CONSOLE_FRAMEBUFFER ) && ! defined ( CONSOLE_VESAFB ) )
-#define CONSOLE_VESAFB CONSOLE_FRAMEBUFFER
-#endif
+/* Set default console usage if applicable */
 #if ! ( defined ( CONSOLE_VESAFB ) && CONSOLE_EXPLICIT ( CONSOLE_VESAFB ) )
 #undef CONSOLE_VESAFB
 #define CONSOLE_VESAFB ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
 #endif
 
-/** Character height */
-#define VESAFB_CHAR_HEIGHT 16
-
 /** Font corresponding to selected character width and height */
 #define VESAFB_FONT VBE_FONT_8x16
 
@@ -89,12 +80,12 @@ struct vesafb {
        physaddr_t start;
        /** Pixel geometry */
        struct fbcon_geometry pixel;
+       /** Margin */
+       struct fbcon_margin margin;
        /** Colour mapping */
        struct fbcon_colour_map map;
        /** Font definition */
        struct fbcon_font font;
-       /** Character glyphs */
-       struct segoff glyphs;
        /** Saved VGA mode */
        uint8_t saved_mode;
 };
@@ -128,23 +119,11 @@ static int vesafb_rc ( unsigned int status ) {
 }
 
 /**
- * Get character glyph
- *
- * @v character                Character
- * @v glyph            Character glyph to fill in
- */
-static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) {
-       size_t offset = ( character * VESAFB_CHAR_HEIGHT );
-
-       copy_from_real ( glyph, vesafb.glyphs.segment,
-                        ( vesafb.glyphs.offset + offset ), VESAFB_CHAR_HEIGHT);
-}
-
-/**
  * Get font definition
  *
  */
 static void vesafb_font ( void ) {
+       struct segoff font;
 
        /* Get font information
         *
@@ -165,14 +144,13 @@ static void vesafb_font ( void ) {
                                           "movw %%es, %%cx\n\t"
                                           "movw %%bp, %%dx\n\t"
                                           "popw %%bp\n\t" /* gcc bug */ )
-                              : "=c" ( vesafb.glyphs.segment ),
-                                "=d" ( vesafb.glyphs.offset )
+                              : "=c" ( font.segment ),
+                                "=d" ( font.offset )
                               : "a" ( VBE_GET_FONT ),
                                 "b" ( VESAFB_FONT ) );
        DBGC ( &vbe_buf, "VESAFB has font %04x at %04x:%04x\n",
-              VESAFB_FONT, vesafb.glyphs.segment, vesafb.glyphs.offset );
-       vesafb.font.height = VESAFB_CHAR_HEIGHT;
-       vesafb.font.glyph = vesafb_glyph;
+              VESAFB_FONT, font.segment, font.offset );
+       vesafb.font.start = real_to_user ( font.segment, font.offset );
 }
 
 /**
@@ -423,6 +401,12 @@ static void vesafb_restore ( void ) {
 static int vesafb_init ( struct console_configuration *config ) {
        uint32_t discard_b;
        uint16_t *mode_numbers;
+       unsigned int xgap;
+       unsigned int ygap;
+       unsigned int left;
+       unsigned int right;
+       unsigned int top;
+       unsigned int bottom;
        int mode_number;
        int rc;
 
@@ -448,13 +432,31 @@ static int vesafb_init ( struct console_configuration *config ) {
        if ( ( rc = vesafb_set_mode ( mode_number ) ) != 0 )
                goto err_set_mode;
 
+       /* Calculate margin.  If the actual screen size is larger than
+        * the requested screen size, then update the margins so that
+        * the margin remains relative to the requested screen size.
+        * (As an exception, if a zero margin was specified then treat
+        * this as meaning "expand to edge of actual screen".)
+        */
+       xgap = ( vesafb.pixel.width - config->width );
+       ygap = ( vesafb.pixel.height - config->height );
+       left = ( xgap / 2 );
+       right = ( xgap - left );
+       top = ( ygap / 2 );
+       bottom = ( ygap - top );
+       vesafb.margin.left = ( config->left + ( config->left ? left : 0 ) );
+       vesafb.margin.right = ( config->right + ( config->right ? right : 0 ) );
+       vesafb.margin.top = ( config->top + ( config->top ? top : 0 ) );
+       vesafb.margin.bottom =
+               ( config->bottom + ( config->bottom ? bottom : 0 ) );
+
        /* Get font data */
        vesafb_font();
 
        /* Initialise frame buffer console */
        if ( ( rc = fbcon_init ( &vesafb.fbcon, phys_to_user ( vesafb.start ),
-                                &vesafb.pixel, &vesafb.map, &vesafb.font,
-                                config ) ) != 0 )
+                                &vesafb.pixel, &vesafb.margin, &vesafb.map,
+                                &vesafb.font, config->pixbuf ) ) != 0 )
                goto err_fbcon_init;
 
        free ( mode_numbers );
@@ -26,8 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/uaccess.h>
 #include <ipxe/init.h>
 #include <ipxe/profile.h>
-#include <ipxe/netdevice.h>
-#include <rmsetjmp.h>
+#include <setjmp.h>
 #include <registers.h>
 #include <biosint.h>
 #include <pxe.h>
@@ -54,14 +53,6 @@ extern void pxe_int_1a ( void );
 /** INT 1A hooked flag */
 static int int_1a_hooked = 0;
 
-/** Real-mode code segment size */
-extern char _text16_memsz[];
-#define _text16_memsz ( ( size_t ) _text16_memsz )
-
-/** Real-mode data segment size */
-extern char _data16_memsz[];
-#define _data16_memsz ( ( size_t ) _data16_memsz )
-
 /** PXENV_UNDI_TRANSMIT API call profiler */
 static struct profiler pxe_api_tx_profiler __profiler =
        { .name = "pxeapi.tx" };
@@ -274,13 +265,10 @@ struct init_fn pxe_init_fn __init_fn ( INIT_NORMAL ) = {
  * @v netdev           Net device to use as PXE net device
  */
 void pxe_activate ( struct net_device *netdev ) {
-       uint32_t discard_a;
-       uint32_t discard_b;
-       uint32_t discard_d;
 
        /* Ensure INT 1A is hooked */
        if ( ! int_1a_hooked ) {
-               hook_bios_interrupt ( 0x1a, ( intptr_t ) pxe_int_1a,
+               hook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a,
                                      &pxe_int_1a_vector );
                devices_get();
                int_1a_hooked = 1;
@@ -288,15 +276,6 @@ void pxe_activate ( struct net_device *netdev ) {
 
        /* Set PXE network device */
        pxe_set_netdev ( netdev );
-
-       /* Notify BIOS of installation */
-       __asm__ __volatile__ ( REAL_CODE ( "pushw %%cs\n\t"
-                                          "popw %%es\n\t"
-                                          "int $0x1a\n\t" )
-                              : "=a" ( discard_a ), "=b" ( discard_b ),
-                                "=d" ( discard_d )
-                              : "0" ( 0x564e ),
-                                "1" ( __from_text16 ( &pxenv ) ) );
 }
 
 /**
@@ -313,10 +292,10 @@ int pxe_deactivate ( void ) {
        /* Ensure INT 1A is unhooked, if possible */
        if ( int_1a_hooked ) {
                if ( ( rc = unhook_bios_interrupt ( 0x1a,
-                                                   ( intptr_t ) pxe_int_1a,
+                                                   (unsigned int) pxe_int_1a,
                                                    &pxe_int_1a_vector ))!= 0){
-                       DBGC ( &pxe_netdev, "PXE could not unhook INT 1A: %s\n",
-                              strerror ( rc ) );
+                       DBG ( "Could not unhook INT 1A: %s\n",
+                             strerror ( rc ) );
                        return rc;
                }
                devices_put();
@@ -339,14 +318,10 @@ int pxe_start_nbp ( void ) {
        int discard_b, discard_c, discard_d, discard_D;
        uint16_t status;
 
-       DBGC ( &pxe_netdev, "PXE NBP starting with netdev %s, code %04x:%04zx, "
-              "data %04x:%04zx\n", ( pxe_netdev ? pxe_netdev->name : "<none>"),
-              rm_cs, _text16_memsz, rm_ds, _data16_memsz );
-
        /* Allow restarting NBP via PXENV_RESTART_TFTP */
        jmp = rmsetjmp ( pxe_restart_nbp );
        if ( jmp )
-               DBGC ( &pxe_netdev, "PXE NBP restarting (%x)\n", jmp );
+               DBG ( "Restarting NBP (%x)\n", jmp );
 
        /* Far call to PXE NBP */
        __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */
@@ -371,31 +346,6 @@ int pxe_start_nbp ( void ) {
        return 0;
 }
 
-/**
- * Notify BIOS of existence of network device
- *
- * @v netdev           Network device
- * @ret rc             Return status code
- */
-static int pxe_notify ( struct net_device *netdev ) {
-
-       /* Do nothing if we already have a network device */
-       if ( pxe_netdev )
-               return 0;
-
-       /* Activate (and deactivate) PXE stack to notify BIOS */
-       pxe_activate ( netdev );
-       pxe_deactivate();
-
-       return 0;
-}
-
-/** PXE BIOS notification driver */
-struct net_driver pxe_driver __net_driver = {
-       .name = "PXE",
-       .probe = pxe_notify,
-};
-
 REQUIRING_SYMBOL ( pxe_api_call );
 REQUIRE_OBJECT ( pxe_preboot );
 REQUIRE_OBJECT ( pxe_undi );
@@ -24,8 +24,6 @@
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 
-#include <librm.h>
-
        .arch i386
 
 /****************************************************************************
@@ -122,7 +120,10 @@ pxenv_null_entry:
        .section ".text16", "ax", @progbits
        .code16
 pxenv_entry:
-       virtcall pxe_api_call
+       pushl   $pxe_api_call
+       pushw   %cs
+       call    prot_call
+       addl    $4, %esp
        lret
        .size   pxenv_entry, . - pxenv_entry
 
@@ -33,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <stdint.h>
 #include <string.h>
 #include <stdlib.h>
+#include <setjmp.h>
 #include <ipxe/uaccess.h>
 #include <ipxe/dhcp.h>
 #include <ipxe/fakedhcp.h>
@@ -43,7 +44,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/if_ether.h>
 #include <basemem_packet.h>
 #include <biosint.h>
-#include <rmsetjmp.h>
 #include "pxe.h"
 #include "pxe_call.h"
 
@@ -129,38 +129,6 @@ static union pxe_cached_info __bss16_array ( cached_info, [NUM_CACHED_INFOS] );
 #define cached_info __use_data16 ( cached_info )
 
 /**
- * Construct cached DHCP packets
- *
- */
-void pxe_fake_cached_info ( void ) {
-       struct pxe_dhcp_packet_creator *creator;
-       union pxe_cached_info *info;
-       unsigned int i;
-       int rc;
-
-       /* Sanity check */
-       assert ( pxe_netdev != NULL );
-
-       /* Erase any stale packets */
-       memset ( cached_info, 0, sizeof ( cached_info ) );
-
-       /* Construct all DHCP packets */
-       for ( i = 0 ; i < ( sizeof ( pxe_dhcp_packet_creators ) /
-                           sizeof ( pxe_dhcp_packet_creators[0] ) ) ; i++ ) {
-
-               /* Construct DHCP packet */
-               creator = &pxe_dhcp_packet_creators[i];
-               info = &cached_info[i];
-               if ( ( rc = creator->create ( pxe_netdev, info,
-                                             sizeof ( *info ) ) ) != 0 ) {
-                       DBGC ( &pxe_netdev, " failed to build packet: %s\n",
-                              strerror ( rc ) );
-                       /* Continue constructing remaining packets */
-               }
-       }
-}
-
-/**
  * UNLOAD BASE CODE STACK
  *
  * @v None                             -
@@ -181,10 +149,12 @@ pxenv_unload_stack ( struct s_PXENV_UNLOAD_STACK *unload_stack ) {
  */
 static PXENV_EXIT_t
 pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO *get_cached_info ) {
+       struct pxe_dhcp_packet_creator *creator;
        union pxe_cached_info *info;
        unsigned int idx;
        size_t len;
        userptr_t buffer;
+       int rc;
 
        DBGC ( &pxe_netdev, "PXENV_GET_CACHED_INFO %s to %04x:%04x+%x",
               pxenv_get_cached_info_name ( get_cached_info->PacketType ),
@@ -192,15 +162,31 @@ pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO *get_cached_info ) {
               get_cached_info->Buffer.offset, get_cached_info->BufferSize );
 
        /* Sanity check */
+       if ( ! pxe_netdev ) {
+               DBGC ( &pxe_netdev, "PXENV_GET_CACHED_INFO called with no "
+                      "network device\n" );
+               get_cached_info->Status = PXENV_STATUS_UNDI_INVALID_STATE;
+               return PXENV_EXIT_FAILURE;
+       }
+
+       /* Sanity check */
         idx = ( get_cached_info->PacketType - 1 );
        if ( idx >= NUM_CACHED_INFOS ) {
                DBGC ( &pxe_netdev, " bad PacketType %d\n",
                       get_cached_info->PacketType );
-               get_cached_info->Status = PXENV_STATUS_UNSUPPORTED;
-               return PXENV_EXIT_FAILURE;
+               goto err;
        }
        info = &cached_info[idx];
 
+       /* Construct DHCP packet */
+       creator = &pxe_dhcp_packet_creators[idx];
+       if ( ( rc = creator->create ( pxe_netdev, info,
+                                     sizeof ( *info ) ) ) != 0 ) {
+               DBGC ( &pxe_netdev, " failed to build packet: %s\n",
+                      strerror ( rc ) );
+               goto err;
+       }
+
        /* Copy packet (if applicable) */
        len = get_cached_info->BufferSize;
        if ( len == 0 ) {
@@ -252,6 +238,10 @@ pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO *get_cached_info ) {
        DBGC ( &pxe_netdev, "\n" );
        get_cached_info->Status = PXENV_STATUS_SUCCESS;
        return PXENV_EXIT_SUCCESS;
+
+ err:
+       get_cached_info->Status = PXENV_STATUS_OUT_OF_RESOURCES;
+       return PXENV_EXIT_FAILURE;
 }
 
 /* PXENV_RESTART_TFTP
@@ -160,20 +160,25 @@ static struct pxe_tftp_connection pxe_tftp = {
 };
 
 /**
+ * Maximum length of a PXE TFTP URI
+ *
+ * The PXE TFTP API provides 128 characters for the filename; the
+ * extra 128 bytes allow for the remainder of the URI.
+ */
+#define PXE_TFTP_URI_LEN 256
+
+/**
  * Open PXE TFTP connection
  *
  * @v ipaddress                IP address
- * @v port             TFTP server port (in network byte order)
+ * @v port             TFTP server port
  * @v filename         File name
  * @v blksize          Requested block size
  * @ret rc             Return status code
  */
 static int pxe_tftp_open ( IP4_t ipaddress, UDP_PORT_t port,
                           UINT8_t *filename, UINT16_t blksize ) {
-       union {
-               struct sockaddr sa;
-               struct sockaddr_in sin;
-       } server;
+       struct in_addr address;
        struct uri *uri;
        int rc;
 
@@ -186,15 +191,12 @@ static int pxe_tftp_open ( IP4_t ipaddress, UDP_PORT_t port,
        pxe_tftp.rc = -EINPROGRESS;
 
        /* Construct URI */
-       memset ( &server, 0, sizeof ( server ) );
-       server.sin.sin_family = AF_INET;
-       server.sin.sin_addr.s_addr = ipaddress;
-       server.sin.sin_port = port;
-       DBG ( " %s", sock_ntoa ( &server.sa ) );
+       address.s_addr = ipaddress;
+       DBG ( " %s", inet_ntoa ( address ) );
        if ( port )
                DBG ( ":%d", ntohs ( port ) );
        DBG ( ":%s", filename );
-       uri = pxe_uri ( &server.sa, ( ( char * ) filename ) );
+       uri = tftp_uri ( address, ntohs ( port ), ( ( char * ) filename ) );
        if ( ! uri ) {
                DBG ( " could not create URI\n" );
                return -ENOMEM;
@@ -11,7 +11,6 @@
 #include <ipxe/udp.h>
 #include <ipxe/uaccess.h>
 #include <ipxe/process.h>
-#include <ipxe/netdevice.h>
 #include <realmode.h>
 #include <pxe.h>
 
@@ -181,15 +180,6 @@ static PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN *pxenv_udp_open ) {
        pxe_udp.local.sin_addr.s_addr = pxenv_udp_open->src_ip;
        DBG ( " %s\n", inet_ntoa ( pxe_udp.local.sin_addr ) );
 
-       /* Open network device, if necessary */
-       if ( pxe_netdev && ( ! netdev_is_open ( pxe_netdev ) ) &&
-            ( ( rc = netdev_open ( pxe_netdev ) ) != 0 ) ) {
-               DBG ( "PXENV_UDP_OPEN could not (implicitly) open %s: %s\n",
-                     pxe_netdev->name, strerror ( rc ) );
-               pxenv_udp_open->Status = PXENV_STATUS ( rc );
-               return PXENV_EXIT_FAILURE;
-       }
-
        /* Open promiscuous UDP connection */
        intf_restart ( &pxe_udp.xfer, 0 );
        if ( ( rc = udp_open_promisc ( &pxe_udp.xfer ) ) != 0 ) {
@@ -208,10 +208,8 @@ int pxeparent_call ( SEGOFF16_t entry, unsigned int function,
                     void *params, size_t params_len ) {
        struct pxeparent_profiler *profiler = pxeparent_profiler ( function );
        PXENV_EXIT_t exit;
-       uint32_t before;
-       uint32_t started;
-       uint32_t stopped;
-       uint32_t after;
+       unsigned long started;
+       unsigned long stopped;
        int discard_D;
        int rc;
 
@@ -242,14 +240,12 @@ int pxeparent_call ( SEGOFF16_t entry, unsigned int function,
                                 "D" ( __from_data16 ( &pxeparent_params ) )
                               : "ecx", "esi" );
        profile_stop ( &profiler->total );
-       before = profile_started ( &profiler->total );
-       after = profile_stopped ( &profiler->total );
-       profile_start_at ( &profiler->p2r, before );
+       profile_start_at ( &profiler->p2r, profile_started ( &profiler->total));
        profile_stop_at ( &profiler->p2r, started );
        profile_start_at ( &profiler->ext, started );
        profile_stop_at ( &profiler->ext, stopped );
        profile_start_at ( &profiler->r2p, stopped );
-       profile_stop_at ( &profiler->r2p, after );
+       profile_stop_at ( &profiler->r2p, profile_stopped ( &profiler->total ));
 
        /* Determine return status code based on PXENV_EXIT and
         * PXENV_STATUS
@@ -46,9 +46,6 @@ uint16_t __bss16 ( com32_saved_sp );
  */
 void __asmcall com32_intcall ( uint8_t interrupt, physaddr_t inregs_phys, physaddr_t outregs_phys ) {
 
-       DBGC ( &com32_regs, "COM32 INT%x in %#08lx out %#08lx\n",
-              interrupt, inregs_phys, outregs_phys );
-
        memcpy_user ( virt_to_user( &com32_regs ), 0,
                      phys_to_user ( inregs_phys ), 0,
                      sizeof(com32sys_t) );
@@ -79,7 +76,7 @@ void __asmcall com32_intcall ( uint8_t interrupt, physaddr_t inregs_phys, physad
                            /* patch INT instruction */
                            "pushw %%ax\n\t"
                            "movb %%ss:(com32_int_vector), %%al\n\t"
-                           "movb %%al, %%cs:(com32_intcall_instr + 1)\n\t"
+                           "movb %%al, %%cs:(com32_intcall_instr + 1)\n\t" 
                            /* perform a jump to avoid problems with cache
                             * consistency in self-modifying code on some CPUs (486)
                             */
@@ -109,7 +106,7 @@ void __asmcall com32_intcall ( uint8_t interrupt, physaddr_t inregs_phys, physad
 
        if ( outregs_phys ) {
                memcpy_user ( phys_to_user ( outregs_phys ), 0,
-                             virt_to_user( &com32_regs ), 0,
+                             virt_to_user( &com32_regs ), 0, 
                              sizeof(com32sys_t) );
        }
 }
@@ -119,9 +116,6 @@ void __asmcall com32_intcall ( uint8_t interrupt, physaddr_t inregs_phys, physad
  */
 void __asmcall com32_farcall ( uint32_t proc, physaddr_t inregs_phys, physaddr_t outregs_phys ) {
 
-       DBGC ( &com32_regs, "COM32 farcall %04x:%04x in %#08lx out %#08lx\n",
-              ( proc >> 16 ), ( proc & 0xffff ), inregs_phys, outregs_phys );
-
        memcpy_user ( virt_to_user( &com32_regs ), 0,
                      phys_to_user ( inregs_phys ), 0,
                      sizeof(com32sys_t) );
@@ -171,7 +165,7 @@ void __asmcall com32_farcall ( uint32_t proc, physaddr_t inregs_phys, physaddr_t
 
        if ( outregs_phys ) {
                memcpy_user ( phys_to_user ( outregs_phys ), 0,
-                             virt_to_user( &com32_regs ), 0,
+                             virt_to_user( &com32_regs ), 0, 
                              sizeof(com32sys_t) );
        }
 }
@@ -182,16 +176,13 @@ void __asmcall com32_farcall ( uint32_t proc, physaddr_t inregs_phys, physaddr_t
 int __asmcall com32_cfarcall ( uint32_t proc, physaddr_t stack, size_t stacksz ) {
        int32_t eax;
 
-       DBGC ( &com32_regs, "COM32 cfarcall %04x:%04x params %#08lx+%#zx\n",
-              ( proc >> 16 ), ( proc & 0xffff ), stack, stacksz );
-
        copy_user_to_rm_stack ( phys_to_user ( stack ), stacksz );
        com32_farcall_proc = proc;
 
        __asm__ __volatile__ (
                REAL_CODE ( "lcall *%%ss:(com32_farcall_proc)\n\t" )
                : "=a" (eax)
-               :
+               : 
                : "ecx", "edx" );
 
        remove_user_from_rm_stack ( 0, stacksz );
 
 FILE_LICENCE ( GPL2_OR_LATER )
 
-#include "librm.h"
-
        .text
-
+       .arch i386
        .code32
+
        .globl com32_farcall_wrapper
 com32_farcall_wrapper:
-       movl    $VIRTUAL(com32_farcall), %eax
-       jmp     com32_wrapper
 
-       .code32
+       movl $com32_farcall, %eax
+       jmp com32_wrapper
+
+
        .globl com32_cfarcall_wrapper
 com32_cfarcall_wrapper:
-       movl    $VIRTUAL(com32_cfarcall), %eax
-       jmp     com32_wrapper
 
-       .code32
+       movl $com32_cfarcall, %eax
+       jmp com32_wrapper
+
+
        .globl com32_intcall_wrapper
 com32_intcall_wrapper:
-       movl    $VIRTUAL(com32_intcall), %eax
-       /* fall through */
 
-       .code32
-com32_wrapper:
+       movl $com32_intcall, %eax
+       /*jmp com32_wrapper*/ /* fall through */
 
-       /* Disable interrupts */
+com32_wrapper:
        cli
 
        /* Switch to internal virtual address space */
-       call    _phys_to_virt
-
-#ifdef __x86_64__
-
-       .code64
+       call _phys_to_virt
 
-       /* Preserve registers which are callee-save for COM32 (i386 API) */
-       pushq   %rdi
-       pushq   %rsi
-       pushq   %rbp
+       mov %eax, (com32_helper_function)
 
-       /* Extract parameters from stack */
-       movl    28(%rsp), %edi
-       movl    32(%rsp), %esi
-       movl    36(%rsp), %edx
+       /* Save external COM32 stack pointer */
+       movl %esp, (com32_external_esp)
 
-       /* Align stack pointer */
-       movq    %rsp, %rbp
-       andq    $~0x07, %rsp
+       /* Copy arguments to caller-save registers */
+       movl 12(%esp), %eax
+       movl 8(%esp), %ecx
+       movl 4(%esp), %edx
 
-       /* Call helper function */
-       movslq  %eax, %rax
-       call    *%rax
+       /* Switch to internal stack */
+       movl (com32_internal_esp), %esp
 
-       /* Restore stack pointer */
-       movq    %rbp, %rsp
+       /* Copy arguments to internal stack */
+       pushl %eax
+       pushl %ecx
+       pushl %edx
 
-       /* Restore registers */
-       popq    %rbp
-       popq    %rsi
-       popq    %rdi
+       call *(com32_helper_function)
 
-#else /* _x86_64 */
+       /* Clean up stack */
+       addl $12, %esp
 
-       /* Call helper function */
-       pushl   12(%esp)
-       pushl   12(%esp)
-       pushl   12(%esp)
-       call    *%eax
-       addl    $12, %esp
-
-#endif /* _x86_64 */
+       /* Save internal stack pointer and restore external stack pointer */
+       movl %esp, (com32_internal_esp)
+       movl (com32_external_esp), %esp
 
        /* Switch to external flat physical address space */
-       call    _virt_to_phys
-       .code32
+       call _virt_to_phys
 
-       /* Reenable interrupts and return */
        sti
        ret
+
+
+       .data
+
+/* Internal iPXE virtual address space %esp */
+.globl com32_internal_esp
+.lcomm com32_internal_esp, 4
+
+/* External flat physical address space %esp */
+.globl com32_external_esp
+.lcomm com32_external_esp, 4
+
+/* Function pointer of helper to call */
+.lcomm com32_helper_function, 4
@@ -32,7 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <comboot.h>
 #include <bzimage.h>
 #include <pxe_call.h>
-#include <rmsetjmp.h>
+#include <setjmp.h>
 #include <string.h>
 #include <ipxe/posix_io.h>
 #include <ipxe/process.h>
@@ -489,7 +489,7 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
                        struct in_addr addr;
 
                        copy_from_user ( hostname, hostname_u, 0, len + 1 );
-
+                       
                        /* TODO:
                         * "If the hostname does not contain a dot (.), the
                         * local domain name is automatically appended."
@@ -519,7 +519,7 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
 
                /* Jump to real-mode entry point */
                __asm__ __volatile__ (
-                       REAL_CODE (
+                       REAL_CODE ( 
                                "pushw %0\n\t"
                                "popw %%ds\n\t"
                                "pushl %1\n\t"
@@ -660,30 +660,42 @@ void hook_comboot_interrupts ( ) {
 
        __asm__ __volatile__ (
                TEXT16_CODE ( "\nint20_wrapper:\n\t"
-                             VIRT_CALL ( int20 )
-                             "clc\n\t"
+                             "pushl %0\n\t"
+                             "pushw %%cs\n\t"
+                             "call prot_call\n\t"
+                             "addw $4, %%sp\n\t"
                              "call patch_cf\n\t"
-                             "iret\n\t" ) );
+                             "iret\n\t" )
+                         : : "i" ( int20 ) );
 
-       hook_bios_interrupt ( 0x20, ( intptr_t ) int20_wrapper, &int20_vector );
+       hook_bios_interrupt ( 0x20, ( unsigned int ) int20_wrapper,
+                                     &int20_vector );
 
        __asm__ __volatile__ (
                TEXT16_CODE ( "\nint21_wrapper:\n\t"
-                             VIRT_CALL ( int21 )
-                             "clc\n\t"
+                             "pushl %0\n\t"
+                             "pushw %%cs\n\t"
+                             "call prot_call\n\t"
+                             "addw $4, %%sp\n\t"
                              "call patch_cf\n\t"
-                             "iret\n\t" ) );
+                             "iret\n\t" )
+                         : : "i" ( int21 ) );
 
-       hook_bios_interrupt ( 0x21, ( intptr_t ) int21_wrapper, &int21_vector );
+       hook_bios_interrupt ( 0x21, ( unsigned int ) int21_wrapper,
+                             &int21_vector );
 
        __asm__  __volatile__ (
                TEXT16_CODE ( "\nint22_wrapper:\n\t"
-                             VIRT_CALL ( int22 )
-                             "clc\n\t"
+                             "pushl %0\n\t"
+                             "pushw %%cs\n\t"
+                             "call prot_call\n\t"
+                             "addw $4, %%sp\n\t"
                              "call patch_cf\n\t"
-                             "iret\n\t" ) );
+                             "iret\n\t" )
+                         : : "i" ( int22) );
 
-       hook_bios_interrupt ( 0x22, ( intptr_t ) int22_wrapper, &int22_vector );
+       hook_bios_interrupt ( 0x22, ( unsigned int ) int22_wrapper,
+                             &int22_vector );
 }
 
 /**
@@ -691,13 +703,13 @@ void hook_comboot_interrupts ( ) {
  */
 void unhook_comboot_interrupts ( ) {
 
-       unhook_bios_interrupt ( 0x20, ( intptr_t ) int20_wrapper,
+       unhook_bios_interrupt ( 0x20, ( unsigned int ) int20_wrapper,
                                &int20_vector );
 
-       unhook_bios_interrupt ( 0x21, ( intptr_t ) int21_wrapper,
+       unhook_bios_interrupt ( 0x21, ( unsigned int ) int21_wrapper,
                                &int21_vector );
 
-       unhook_bios_interrupt ( 0x22, ( intptr_t ) int22_wrapper,
+       unhook_bios_interrupt ( 0x22, ( unsigned int ) int22_wrapper,
                                &int22_vector );
 }
 
similarity index 99%
rename from roms/ipxe/src/arch/x86/prefix/dskprefix.S
rename to roms/ipxe/src/arch/i386/prefix/dskprefix.S
index 0503f11..7aa017c 100644 (file)
@@ -18,8 +18,6 @@
 
 FILE_LICENCE ( GPL2_ONLY )
 
-#include <librm.h>
-
 .equ   BOOTSEG, 0x07C0                 /* original address of boot-sector */
 
 .equ   SYSSEG, 0x1000                  /* system loaded at SYSSEG<<4 */
@@ -372,8 +370,10 @@ start_runtime:
        lret
        .section ".text16", "awx", @progbits
 1:
-       /* Run iPXE */
-       virtcall main
+       pushl   $main
+       pushw   %cs
+       call    prot_call
+       popl    %ecx /* discard */
 
        /* Uninstall iPXE */
        call    uninstall
similarity index 98%
rename from roms/ipxe/src/arch/x86/prefix/exeprefix.S
rename to roms/ipxe/src/arch/i386/prefix/exeprefix.S
index c351456..5c648d5 100644 (file)
@@ -24,8 +24,6 @@
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 
-#include <librm.h>
-
 /* Initial temporary stack size */
 #define EXE_STACK_SIZE 0x400
 
@@ -150,7 +148,10 @@ _exe_start:
        movl    %esi, cmdline_phys
 
        /* Run iPXE */
-       virtcall main
+       pushl   $main
+       pushw   %cs
+       call    prot_call
+       popl    %ecx /* discard */
 
        /* Uninstall iPXE */
        call    uninstall
similarity index 95%
rename from roms/ipxe/src/arch/x86/prefix/hdprefix.S
rename to roms/ipxe/src/arch/i386/prefix/hdprefix.S
index 24f5d38..1d012d8 100644 (file)
@@ -1,7 +1,5 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 
-#include <librm.h>
-
        .text
        .arch i386
        .section ".prefix", "awx", @progbits
@@ -101,8 +99,10 @@ start_image:
        lret
        .section ".text16", "awx", @progbits
 1:
-       /* Run iPXE */
-       virtcall main
+       pushl   $main
+       pushw   %cs
+       call    prot_call
+       popl    %ecx /* discard */
 
        /* Uninstall iPXE */
        call    uninstall
similarity index 87%
rename from roms/ipxe/src/arch/x86/prefix/libprefix.S
rename to roms/ipxe/src/arch/i386/prefix/libprefix.S
index 533be98..7d5c1ed 100644 (file)
@@ -24,8 +24,6 @@
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 
-#include <librm.h>
-
        .arch i386
 
 /* Image compression enabled */
@@ -71,7 +69,7 @@ progress_\@:
  *   %ds:di : next character in output buffer (if applicable)
  *****************************************************************************
  */
-       .section ".prefix.print_character", "awx", @progbits
+       .section ".prefix.lib", "awx", @progbits
        .code16
        .globl  print_character
 print_character:
@@ -109,7 +107,7 @@ print_character:
  *   %ds:di : next character in output buffer (if applicable)
  *****************************************************************************
  */
-       .section ".prefix.print_space", "awx", @progbits
+       .section ".prefix.lib", "awx", @progbits
        .code16
        .globl  print_space
 print_space:
@@ -134,7 +132,7 @@ print_space:
  *   %ds:di : next character in output buffer (if applicable)
  *****************************************************************************
  */
-       .section ".prefix.print_message", "awx", @progbits
+       .section ".prefix.lib", "awx", @progbits
        .code16
        .globl  print_message
 print_message:
@@ -164,7 +162,7 @@ print_message:
  *   %ds:di : next character in output buffer (if applicable)
  *****************************************************************************
  */
-       .section ".prefix.print_hex", "awx", @progbits
+       .section ".prefix.lib", "awx", @progbits
        .code16
        .globl  print_hex_dword
 print_hex_dword:
@@ -212,7 +210,7 @@ print_hex_nibble:
  *   %ds:di : next character in output buffer (if applicable)
  *****************************************************************************
  */
-       .section ".prefix.print_pci_busdevfn", "awx", @progbits
+       .section ".prefix.lib", "awx", @progbits
        .code16
        .globl  print_pci_busdevfn
 print_pci_busdevfn:
@@ -249,7 +247,7 @@ print_pci_busdevfn:
  *   %ds:di : next character in output buffer (if applicable)
  *****************************************************************************
  */
-       .section ".prefix.print_kill_line", "awx", @progbits
+       .section ".prefix.lib", "awx", @progbits
        .code16
        .globl  print_kill_line
 print_kill_line:
@@ -287,7 +285,7 @@ print_kill_line:
  *   None
  ****************************************************************************
  */
-       .section ".prefix.copy_bytes", "awx", @progbits
+       .section ".prefix.lib", "awx", @progbits
        .code16
 copy_bytes:
        pushl   %ecx
@@ -310,7 +308,7 @@ copy_bytes:
  *   None
  ****************************************************************************
  */
-       .section ".prefix.zero_bytes", "awx", @progbits
+       .section ".prefix.lib", "awx", @progbits
        .code16
 zero_bytes:
        pushl   %ecx
@@ -341,12 +339,11 @@ zero_bytes:
  * Returns:
  *   %esi : next source physical address
  *   %edi : next destination physical address
- *   CF : as returned by memcpy()-like function
  * Corrupts:
  *   None
  ****************************************************************************
  */
-       .section ".prefix.process_bytes", "awx", @progbits
+       .section ".prefix.lib", "awx", @progbits
        .code16
 process_bytes:
 
@@ -357,7 +354,6 @@ process_bytes:
        pushl   %ebp
 
        /* Construct GDT on stack (since .prefix may not be writable) */
-       .equ    GDT_LEN, 0x20
        .equ    PM_DS, 0x18     /* Flat data segment */
        pushl   $0x00cf9300
        pushl   $0x0000ffff
@@ -371,7 +367,7 @@ process_bytes:
        pushw   $0xffff
        pushl   $0              /* Base and length */
        pushw   %ss
-       pushw   $( GDT_LEN - 1 )
+       pushw   $0x1f
        movzwl  %sp, %ebp
        shll    $4, 0x02(%bp)
        addl    %ebp, 0x02(%bp)
@@ -409,9 +405,7 @@ process_bytes:
 
        /* Return to (flat) real mode */
        movl    %cr0, %eax
-       pushfw
        andb    $0!CR0_PE, %al
-       popfw
        movl    %eax, %cr0
        lret
 2:     /* lret will ljmp to here */
@@ -437,7 +431,7 @@ process_bytes:
 
        /* Restore GDT */
        data32 lgdt -8(%bp)
-       leaw    GDT_LEN(%bp), %sp
+       addw    $( 8 /* saved GDT */ + ( PM_DS + 8 ) /* GDT on stack */ ), %sp
 
        /* Restore registers and return */
        popl    %ebp
@@ -465,7 +459,6 @@ process_bytes:
        call    *%bx
 
        /* Convert %ds:esi and %es:edi back to physical addresses */
-       pushfw
        xorl    %eax, %eax
        movw    %ds, %ax
        shll    $4, %eax
@@ -474,7 +467,6 @@ process_bytes:
        movw    %es, %ax
        shll    $4, %eax
        addl    %eax, %edi
-       popfw
 
        /* Restore registers and return */
        popw    %es
@@ -499,12 +491,11 @@ process_bytes:
  * Returns:
  *   %esi : next source physical address (will be a multiple of 16)
  *   %edi : next destination physical address (will be a multiple of 16)
- *   CF set on failure
  * Corrupts:
  *   none
  ****************************************************************************
  */
-       .section ".prefix.install_block", "awx", @progbits
+       .section ".prefix.lib", "awx", @progbits
        .code16
 install_block:
        /* Preserve registers */
@@ -518,7 +509,6 @@ install_block:
        movw    $copy_bytes, %bx
 #endif
        call    process_bytes
-       jc      99f
 
        /* Zero .bss portion */
        negl    %ecx
@@ -530,9 +520,9 @@ install_block:
        addl    $0xf, %esi
        andl    $~0xf, %esi
        addl    $0xf, %edi
-       andl    $~0xf, %edi /* Will also clear CF */
+       andl    $~0xf, %edi
 
-99:    /* Restore registers and return */
+       /* Restore registers and return */
        popw    %bx
        popl    %ecx
        ret
@@ -554,7 +544,7 @@ install_block:
  *   none
  ****************************************************************************
  */
-       .section ".prefix.alloc_basemem", "awx", @progbits
+       .section ".prefix.lib", "awx", @progbits
        .code16
        .globl  alloc_basemem
 alloc_basemem:
@@ -568,11 +558,14 @@ alloc_basemem:
        shlw    $6, %ax
 
        /* Calculate .data16 segment address */
-       subw    $_data16_memsz_ppgh, %ax
+       subw    $_data16_memsz_pgh, %ax
        pushw   %ax
 
-       /* Calculate .text16 segment address */
-       subw    $_text16_memsz_ppgh, %ax
+       /* Calculate .text16 segment address.  Round down to ensure
+        * low bits are zero, to speed up mode transitions under KVM.
+        */
+       subw    $_text16_memsz_pgh, %ax
+       andb    $~0x03, %al
        pushw   %ax
 
        /* Update FBMS */
@@ -601,7 +594,7 @@ alloc_basemem:
  *   none
  ****************************************************************************
  */
-       .section ".text16.free_basemem", "ax", @progbits
+       .section ".text16", "ax", @progbits
        .code16
        .globl  free_basemem
 free_basemem:
@@ -623,8 +616,8 @@ free_basemem:
 
        /* OK to free memory */
        movw    %cs, %ax
-       addw    $_text16_memsz_ppgh, %ax
-       addw    $_data16_memsz_ppgh, %ax
+       addw    $_text16_memsz_pgh, %ax
+       addw    $_data16_memsz_pgh, %ax
        shrw    $6, %ax
        movw    %ax, %fs:0x13
        xorw    %ax, %ax
@@ -635,7 +628,7 @@ free_basemem:
        ret
        .size free_basemem, . - free_basemem
 
-       .section ".text16.data.hooked_bios_interrupts", "aw", @progbits
+       .section ".text16.data", "aw", @progbits
        .globl  hooked_bios_interrupts
 hooked_bios_interrupts:
        .word   0
@@ -655,7 +648,7 @@ hooked_bios_interrupts:
  *   none
  ****************************************************************************
  */
-       .section ".prefix.install", "awx", @progbits
+       .section ".prefix.lib", "awx", @progbits
        .code16
        .globl install
 install:
@@ -698,7 +691,7 @@ install:
  *   none
  ****************************************************************************
  */
-       .section ".prefix.install_prealloc", "awx", @progbits
+       .section ".prefix.lib", "awx", @progbits
        .code16
        .globl install_prealloc
 install_prealloc:
@@ -738,7 +731,6 @@ install_prealloc:
        movl    $_text16_early_filesz, %ecx
        movl    $_text16_early_memsz, %edx
        call    install_block           /* .text16.early */
-       jc      install_block_death
        popl    %ecx                    /* Calculate offset to next block */
        subl    %esi, %ecx
        negl    %ecx
@@ -757,8 +749,17 @@ install_prealloc:
        pushw   $access_highmem
        lret
 1:     /* Die if we could not access high memory */
-       jc      access_highmem_death
-
+       jnc     3f
+       movw    $a20_death_message, %si
+       xorw    %di, %di
+       call    print_message
+2:     jmp     2b
+       .section ".prefix.data", "aw", @progbits
+a20_death_message:
+       .asciz  "\nHigh memory inaccessible - cannot continue\n"
+       .size   a20_death_message, . - a20_death_message
+       .previous
+3:
 #endif
 
        /* Open payload (which may not yet be in memory) */
@@ -769,7 +770,25 @@ install_prealloc:
        pushw   $open_payload
        lret
 1:     /* Die if we could not access the payload */
-       jc      open_payload_death
+       jnc     3f
+       xorw    %di, %di
+       movl    %esi, %eax
+       call    print_hex_dword
+       call    print_space
+       movl    %ecx, %eax
+       call    print_hex_dword
+       movw    $payload_death_message, %si
+       call    print_message
+2:     /* Halt system */
+       cli
+       hlt
+       jmp     2b
+       .section ".prefix.data", "aw", @progbits
+payload_death_message:
+       .asciz  "\nPayload inaccessible - cannot continue\n"
+       .size   payload_death_message, . - payload_death_message
+       .previous
+3:
 
        /* Calculate physical address of payload (i.e. first source) */
        testl   %esi, %esi
@@ -783,14 +802,12 @@ install_prealloc:
        movl    $_text16_late_filesz, %ecx
        movl    $_text16_late_memsz, %edx
        call    install_block           /* .text16.late */
-       jc      install_block_death
        progress "  .data16\n"
        movzwl  %bx, %edi
        shll    $4, %edi
        movl    $_data16_filesz, %ecx
        movl    $_data16_filesz, %edx   /* do not zero our temporary stack */
        call    install_block           /* .data16 */
-       jc      install_block_death
 
        /* Set up %ds for access to .data16 */
        movw    %bx, %ds
@@ -813,7 +830,6 @@ install_prealloc:
        movw    %ax, %di
        addl    $0x400, %edi
        subl    $_textdata_memsz_kb, %edi
-       andw    $~0x03, %di
        shll    $10, %edi
        /* Sanity check: if we have ended up below 1MB, use 1MB */
        cmpl    $0x100000, %edi
@@ -830,7 +846,6 @@ install_prealloc:
        movl    $_textdata_filesz, %ecx
        movl    $_textdata_memsz, %edx
        call    install_block
-       jc      install_block_death
        popl    %edi
 
 #endif /* KEEP_IT_REAL */
@@ -854,15 +869,6 @@ install_prealloc:
        movw    %ax, (init_librm_vector+2)
        lcall   *init_librm_vector
 
-       /* Prepare for return to .prefix segment */
-       pushw   %cs
-
-       /* Jump to .text16 segment */
-       pushw   %ax
-       pushw   $1f
-       lret
-       .section ".text16.install_prealloc", "ax", @progbits
-1:
        /* Inhibit INT 15,e820 and INT 15,e801 if applicable */
        testl   %ebp, %ebp
        jnz     1f
@@ -874,13 +880,11 @@ install_prealloc:
         * ready for the copy to the new location.
         */
        progress "  relocate\n"
-       virtcall relocate
+       movw    %ax, (prot_call_vector+2)
+       pushl   $relocate
+       lcall   *prot_call_vector
+       popl    %edx /* discard */
 
-       /* Jump back to .prefix segment */
-       pushw   $1f
-       lret
-       .section ".prefix.install_prealloc", "awx", @progbits
-1:
        /* Copy code to new location */
        progress "  copy\n"
        pushl   %edi
@@ -917,7 +921,7 @@ install_prealloc:
        /* Vectors for far calls to .text16 functions.  Must be in
         * .data16, since .prefix may not be writable.
         */
-       .section ".data16.install_prealloc", "aw", @progbits
+       .section ".data16", "aw", @progbits
 #ifdef KEEP_IT_REAL
 init_libkir_vector:
        .word init_libkir
@@ -928,6 +932,10 @@ init_librm_vector:
        .word init_librm
        .word 0
        .size init_librm_vector, . - init_librm_vector
+prot_call_vector:
+       .word prot_call
+       .word 0
+       .size prot_call_vector, . - prot_call_vector
 #endif
 close_payload_vector:
        .word close_payload
@@ -935,7 +943,7 @@ close_payload_vector:
        .size close_payload_vector, . - close_payload_vector
 
        /* Dummy routines to open and close payload */
-       .section ".text16.early.data.open_payload", "aw", @progbits
+       .section ".text16.early.data", "aw", @progbits
        .weak   open_payload
        .weak   close_payload
 open_payload:
@@ -945,52 +953,6 @@ close_payload:
        .size   open_payload, . - open_payload
        .size   close_payload, . - close_payload
 
-       /* Report installation failure */
-       .section ".prefix.install_death", "ax", @progbits
-install_death:
-       pushw   %cs
-       popw    %ds
-       xorw    %di, %di
-       call    print_hex_dword
-       call    print_space
-       movl    %esi, %eax
-       call    print_hex_dword
-       call    print_space
-       movl    %ecx, %eax
-       call    print_hex_dword
-       movw    $install_death_message, %si
-       call    print_message
-2:     /* Halt system */
-       cli
-       hlt
-       jmp     2b
-       .size   install_death, . - install_death
-       .section ".prefix.data.install_death_message", "aw", @progbits
-install_death_message:
-       .asciz  "\nInstallation failed - cannot continue\n"
-       .size   install_death_message, . - install_death_message
-
-       /* Report failure to access high memory */
-       .section ".prefix.install_block_death", "ax", @progbits
-install_block_death:
-       movl    $0x1b101b10, %eax
-       jmp     install_death
-       .size   install_block_death, . - install_block_death
-
-       /* Report failure to access high memory */
-       .section ".prefix.access_highmem_death", "ax", @progbits
-access_highmem_death:
-       movl    $0x0a200a20, %eax
-       jmp     install_death
-       .size   access_highmem_death, . - access_highmem_death
-
-       /* Report failure to open payload */
-       .section ".prefix.open_payload_death", "ax", @progbits
-open_payload_death:
-       xorl    %eax, %eax
-       jmp     install_death
-       .size   open_payload_death, . - open_payload_death
-
 /****************************************************************************
  * uninstall
  *
@@ -1004,7 +966,7 @@ open_payload_death:
  *   none
  ****************************************************************************
  */
-       .section ".text16.uninstall", "ax", @progbits
+       .section ".text16", "ax", @progbits
        .code16
        .globl uninstall
 uninstall:
similarity index 98%
rename from roms/ipxe/src/arch/x86/prefix/lkrnprefix.S
rename to roms/ipxe/src/arch/i386/prefix/lkrnprefix.S
index 922181f..64135e1 100644 (file)
@@ -1,7 +1,5 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 
-#include <librm.h>
-
 #define BZI_LOAD_HIGH_ADDR 0x100000
 
        .text
@@ -199,7 +197,10 @@ no_cmd_line:
        movl    %ecx, initrd_len
 
        /* Run iPXE */
-       virtcall main
+       pushl   $main
+       pushw   %cs
+       call    prot_call
+       popl    %ecx /* discard */
 
        /* Uninstall iPXE */
        call    uninstall
similarity index 96%
rename from roms/ipxe/src/arch/x86/prefix/nbiprefix.S
rename to roms/ipxe/src/arch/i386/prefix/nbiprefix.S
index de38e4a..16c7956 100644 (file)
@@ -1,7 +1,5 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 
-#include <librm.h>
-
        .text
        .arch i386
        .code16
@@ -68,8 +66,10 @@ _nbi_start:
        lret
        .section ".text16", "awx", @progbits
 1:
-       /* Run iPXE */
-       virtcall main
+       pushl   $main
+       pushw   %cs
+       call    prot_call
+       popl    %ecx /* discard */
 
        /* Uninstall iPXE */
        call    uninstall
similarity index 99%
rename from roms/ipxe/src/arch/x86/prefix/pxeprefix.S
rename to roms/ipxe/src/arch/i386/prefix/pxeprefix.S
index 52ea180..465ce43 100644 (file)
@@ -16,7 +16,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
        .org 0
        .code16
 
-#include <librm.h>
 #include <undi.h>
 
 #define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
@@ -821,7 +820,10 @@ run_ipxe:
        movl    %ecx, cached_dhcpack_phys
 
        /* Run main program */
-       virtcall main
+       pushl   $main
+       pushw   %cs
+       call    prot_call
+       popl    %ecx /* discard */
 
        /* Uninstall iPXE */
        call    uninstall
similarity index 96%
rename from roms/ipxe/src/arch/x86/prefix/romprefix.S
rename to roms/ipxe/src/arch/i386/prefix/romprefix.S
index f4ca206..18dda2b 100644 (file)
@@ -8,7 +8,6 @@
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 
-#include <librm.h>
 #include <config/general.h>
 #include <config/branding.h>
 
@@ -124,7 +123,7 @@ pci_devlist_end:
        .long   pciheader_image_length
        .long   512
        .long   0
-       .ascii  "ADHW"
+       .ascii  ZINFO_TYPE_ADxW
        .long   pciheader_runtime_length
        .long   512
        .long   0
@@ -403,22 +402,19 @@ pmm_scan:
        /* Shrink ROM */
        movb    shrunk_rom_size, %al
        movb    %al, romheader_size
-1:     /* Allocate decompression PMM block.  Allow 4kB for page
-        * alignment and round up the size to the nearest 128kB, then
-        * use the size within the PMM handle; this allows the same
-        * decompression area to be shared between multiple iPXE ROMs
-        * even with differing build IDs
+1:     /* Allocate decompression PMM block.  Round up the size to the
+        * nearest 128kB and use the size within the PMM handle; this
+        * allows the same decompression area to be shared between
+        * multiple iPXE ROMs even with differing build IDs
         */
        movl    $_textdata_memsz_pgh, %ecx
-       addl    $( 0x00000100 /* 4kB */ + 0x00001fff /* 128kB - 1 */ ), %ecx
-       andl    $( 0xffffe000 /* ~( 128kB - 1 ) */ ), %ecx
+       addl    $0x00001fff, %ecx
+       andl    $0xffffe000, %ecx
        movl    %ecx, %ebx
        shrw    $12, %bx
        orl     $PMM_HANDLE_BASE_DECOMPRESS_TO, %ebx
        movw    $get_pmm_decompress_to, %bp
        call    get_pmm
-       addl    $( 0x00000fff /* 4kB - 1 */ ), %esi
-       andl    $( 0xfffff000 /* ~( 4kB - 1 ) */ ), %esi
        movl    %esi, decompress_to
        /* Restore registers */
        popal
@@ -439,25 +435,13 @@ no_pmm:
         * memory.  Will be a no-op for lower PCI versions.
         */
 .ifeqs BUSTYPE, "PCIR"
-       /* Get runtime segment address and length */
-       movw    %gs, %ax
-       movw    %ax, %es
-       movzbw  romheader_size, %cx
-       /* Print runtime segment address */
        xorw    %di, %di
        call    print_space
+       movw    %gs, %ax
        call    print_hex_word
-       /* Fail if we have insufficient space in final location */
-       movw    %cs, %si
-       cmpw    %si, %ax
-       je      1f
-       cmpw    pciheader_runtime_length, %cx
-       jbe     1f
-       movb    $( '!' ), %al
-       call    print_character
-       xorw    %cx, %cx
-1:     /* Copy to final location */
+       movzbw  romheader_size, %cx
        shlw    $9, %cx
+       movw    %ax, %es
        xorw    %si, %si
        xorw    %di, %di
        cs rep  movsb
@@ -807,8 +791,11 @@ exec:      /* Set %ds = %cs */
 #endif /* AUTOBOOT_ROM_FILTER */
 .endif
 
-       /* Run iPXE */
-       virtcall main
+       /* Call main() */
+       pushl   $main
+       pushw   %cs
+       call    prot_call
+       popl    %eax /* discard */
 
        /* Set up flat real mode for return to BIOS */
        call    flatten_real_mode
similarity index 83%
rename from roms/ipxe/src/arch/x86/prefix/undiloader.S
rename to roms/ipxe/src/arch/i386/prefix/undiloader.S
index 530b48e..5cace44 100644 (file)
@@ -1,7 +1,5 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 
-#include <librm.h>
-
        .text
        .code16
        .arch i386
@@ -20,16 +18,13 @@ undiloader:
        pushw   %ds
        pushw   %es
        pushw   %bx
-
        /* ROM segment address to %ds */
        pushw   %cs
        popw    %ds
-
        /* UNDI loader parameter structure address into %es:%di */
        movw    %sp, %bx
        movw    %ss:22(%bx), %di
        movw    %ss:24(%bx), %es
-
        /* Install to specified real-mode addresses */
        pushw   %di
        movw    %es:12(%di), %bx
@@ -39,17 +34,16 @@ undiloader:
        orl     $0xffffffff, %ebp       /* Allow arbitrary relocation */
        call    install_prealloc
        popw    %di
-
-       /* Jump to .text16 segment */
-       pushw   %ax
+       /* Call UNDI loader C code */
+       pushl   $pxe_loader_call
+       pushw   %cs
        pushw   $1f
+       pushw   %ax
+       pushw   $prot_call
        lret
-       .section ".text16", "ax", @progbits
-1:
-       /* Call UNDI loader C code */
-       virtcall pxe_loader_call
-
-1:     /* Restore registers and return */
+1:     popw    %bx     /* discard */
+       popw    %bx     /* discard */
+       /* Restore registers and return */
        popw    %bx
        popw    %es
        popw    %ds
@@ -57,3 +51,4 @@ undiloader:
        popl    %edi
        popl    %esi
        lret
+       .size undiloader, . - undiloader
similarity index 95%
rename from roms/ipxe/src/arch/x86/prefix/unlzma.S
rename to roms/ipxe/src/arch/i386/prefix/unlzma.S
index ce18c75..8d4b3c1 100644 (file)
@@ -58,9 +58,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
        .code32
 #endif /* CODE16 */
 
-#define CRCPOLY 0xedb88320
-#define CRCSEED 0xffffffff
-
 /****************************************************************************
  * Debugging
  ****************************************************************************
@@ -866,44 +863,6 @@ bcj_filter:
        .size   bcj_filter, . - bcj_filter
 
 /****************************************************************************
- * Verify CRC32
- *
- * Parameters:
- *   %ds:%esi : Start of compressed input data
- *   %edx : Length of compressed input data (including CRC)
- * Returns:
- *   CF clear if CRC32 is zero
- *   All other registers are preserved
- * Corrupts:
- *   %eax
- *   %ebx
- *   %ecx
- *   %edx
- *   %esi
- ****************************************************************************
- */
-verify_crc32:
-       /* Calculate CRC */
-       addl    %esi, %edx
-       movl    $CRCSEED, %ebx
-1:     ADDR32 lodsb
-       xorb    %al, %bl
-       movw    $8, %cx
-2:     rcrl    %ebx
-       jnc     3f
-       xorl    $CRCPOLY, %ebx
-3:     ADDR16 loop 2b
-       cmpl    %esi, %edx
-       jne     1b
-       /* Set CF if result is nonzero */
-       testl   %ebx, %ebx
-       jz      1f
-       stc
-1:     /* Return */
-       ret
-       .size   verify_crc32, . - verify_crc32
-
-/****************************************************************************
  * decompress (real-mode or 16/32-bit protected-mode near call)
  *
  * Decompress data
@@ -914,7 +873,6 @@ verify_crc32:
  * Returns:
  *   %ds:%esi - End of compressed input data
  *   %es:%edi - End of decompressed output data
- *   CF set if CRC32 was incorrect
  *   All other registers are preserved
  *
  * NOTE: It would be possible to build a smaller version of the
@@ -930,13 +888,6 @@ decompress:
        pushl   %ecx
        pushl   %edx
        pushl   %ebp
-       /* Verify CRC32 */
-       ADDR32 lodsl
-       movl    %eax, %edx
-       pushl   %esi
-       call    verify_crc32
-       popl    %esi
-       jc      99f
        /* Allocate parameter block */
        subl    $sizeof__lzma_dec, %esp
        movl    %esp, %ebp
@@ -977,11 +928,8 @@ decompress:
        movl    out_start(%ebp), %esi
        call    bcj_filter
        popl    %esi
-       /* Skip CRC */
-       ADDR32 lodsl
-       /* Free parameter block (and clear CF) */
+       /* Restore registers and return */
        addl    $sizeof__lzma_dec, %esp
-99:    /* Restore registers and return */
        popl    %ebp
        popl    %edx
        popl    %ecx
similarity index 86%
rename from roms/ipxe/src/arch/x86/scripts/pcbios.lds
rename to roms/ipxe/src/arch/i386/scripts/i386.lds
index c9a91c0..38c89e1 100644 (file)
@@ -27,20 +27,6 @@ SECTIONS {
     PROVIDE ( _max_align = 16 );
 
     /*
-     * Values used in page table calculations
-     *
-     * On older versions of ld (without the SANE_EXPR feature),
-     * numeric literals within a section description tend to be
-     * interpreted as section-relative symbols.
-     *
-     */
-    _page_size = 4096;
-    _page_size_1 = ( _page_size - 1 );
-    _pte_size = 8;
-    _pte_count = ( _page_size / _pte_size );
-    _pte_count_1 = ( _pte_count - 1 );
-
-    /*
      * Allow decompressor to require a minimum amount of temporary stack
      * space.
      *
@@ -141,18 +127,6 @@ SECTIONS {
        *(COMMON)
        *(.stack)
        *(.stack.*)
-       _pages = .;
-       *(.pages)
-       *(.pages.*)
-       _use_page_tables = ABSOLUTE ( . ) - ABSOLUTE ( _pages );
-       _textdata_paged_len =
-           ABSOLUTE ( ABSOLUTE ( . ) - ABSOLUTE ( _textdata ) );
-       _textdata_ptes =
-           ABSOLUTE ( ( _textdata_paged_len + _page_size_1 ) / _page_size );
-       _textdata_pdes =
-           ABSOLUTE ( ( _textdata_ptes + _pte_count_1 ) / _pte_count );
-       . += ( _use_page_tables ? ( _textdata_pdes * _page_size ) : 0 );
-       _epages = .;
        _etextdata = .;
     }
     _textdata_filesz   = ABSOLUTE ( _mtextdata ) - ABSOLUTE ( _textdata );
@@ -273,8 +247,8 @@ SECTIONS {
      * Values calculated to save code from doing it
      *
      */
-    _text16_memsz_ppgh = ( ( ( _text16_memsz + 63 ) / 64 ) * 4 );
-    _data16_memsz_ppgh = ( ( ( _data16_memsz + 63 ) / 64 ) * 4 );
+    _text16_memsz_pgh  = ( ( _text16_memsz + 15 ) / 16 );
+    _data16_memsz_pgh  = ( ( _data16_memsz + 15 ) / 16 );
     _textdata_memsz_pgh        = ( ( _textdata_memsz + 15 ) / 16 );
     _textdata_memsz_kb = ( ( _textdata_memsz + 1023 ) / 1024 );
 }
diff --git a/roms/ipxe/src/arch/i386/transitions/librm.S b/roms/ipxe/src/arch/i386/transitions/librm.S
new file mode 100644 (file)
index 0000000..863e224
--- /dev/null
@@ -0,0 +1,671 @@
+/*
+ * librm: a library for interfacing to real-mode code
+ *
+ * Michael Brown <mbrown@fensystems.co.uk>
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+
+/* Drag in local definitions */
+#include "librm.h"
+
+/* For switches to/from protected mode */
+#define CR0_PE 1
+
+/* Size of various C data structures */
+#define SIZEOF_I386_SEG_REGS   12
+#define SIZEOF_I386_REGS       32
+#define SIZEOF_REAL_MODE_REGS  ( SIZEOF_I386_SEG_REGS + SIZEOF_I386_REGS )
+#define SIZEOF_I386_FLAGS      4
+#define SIZEOF_I386_ALL_REGS   ( SIZEOF_REAL_MODE_REGS + SIZEOF_I386_FLAGS )
+       
+       .arch i386
+
+/****************************************************************************
+ * Global descriptor table
+ *
+ * Call init_librm to set up the GDT before attempting to use any
+ * protected-mode code.
+ *
+ * NOTE: This must be located before prot_to_real, otherwise gas
+ * throws a "can't handle non absolute segment in `ljmp'" error due to
+ * not knowing the value of REAL_CS when the ljmp is encountered.
+ *
+ * Note also that putting ".word gdt_end - gdt - 1" directly into
+ * gdt_limit, rather than going via gdt_length, will also produce the
+ * "non absolute segment" error.  This is most probably a bug in gas.
+ ****************************************************************************
+ */
+       .section ".data16", "aw", @progbits
+       .align 16
+gdt:
+gdtr:          /* The first GDT entry is unused, the GDTR can fit here. */
+gdt_limit:             .word gdt_length - 1
+gdt_base:              .long 0
+                       .word 0 /* padding */
+
+       .org    gdt + VIRTUAL_CS, 0
+virtual_cs:    /* 32 bit protected mode code segment, virtual addresses */
+       .word   0xffff, 0
+       .byte   0, 0x9f, 0xcf, 0
+
+       .org    gdt + VIRTUAL_DS, 0
+virtual_ds:    /* 32 bit protected mode data segment, virtual addresses */
+       .word   0xffff, 0
+       .byte   0, 0x93, 0xcf, 0
+       
+       .org    gdt + PHYSICAL_CS, 0
+physical_cs:   /* 32 bit protected mode code segment, physical addresses */
+       .word   0xffff, 0
+       .byte   0, 0x9f, 0xcf, 0
+
+       .org    gdt + PHYSICAL_DS, 0
+physical_ds:   /* 32 bit protected mode data segment, physical addresses */
+       .word   0xffff, 0
+       .byte   0, 0x93, 0xcf, 0        
+
+       .org    gdt + REAL_CS, 0
+real_cs:       /* 16 bit real mode code segment */
+       .word   0xffff, 0
+       .byte   0, 0x9b, 0x00, 0
+
+       .org    gdt + REAL_DS   
+real_ds:       /* 16 bit real mode data segment */
+       .word   0xffff, ( REAL_DS << 4 )
+       .byte   0, 0x93, 0x00, 0
+
+gdt_end:
+       .equ    gdt_length, gdt_end - gdt
+
+/****************************************************************************
+ * init_librm (real-mode far call, 16-bit real-mode far return address)
+ *
+ * Initialise the GDT ready for transitions to protected mode.
+ *
+ * Parameters:
+ *   %cs : .text16 segment
+ *   %ds : .data16 segment
+ *   %edi : Physical base of protected-mode code (virt_offset)
+ ****************************************************************************
+ */
+       .section ".text16", "ax", @progbits
+       .code16
+       .globl init_librm
+init_librm:
+       /* Preserve registers */
+       pushl   %eax
+       pushl   %ebx
+
+       /* Store virt_offset and set up virtual_cs and virtual_ds segments */
+       movl    %edi, %eax
+       movw    $virtual_cs, %bx
+       call    set_seg_base
+       movw    $virtual_ds, %bx
+       call    set_seg_base    
+       movl    %edi, rm_virt_offset
+
+       /* Negate virt_offset */
+       negl    %edi
+               
+       /* Store rm_cs and text16, set up real_cs segment */
+       xorl    %eax, %eax
+       movw    %cs, %ax
+       movw    %ax, %cs:rm_cs
+       shll    $4, %eax
+       movw    $real_cs, %bx
+       call    set_seg_base
+       addr32 leal     (%eax, %edi), %ebx
+       movl    %ebx, rm_text16
+
+       /* Store rm_ds and data16 */
+       xorl    %eax, %eax
+       movw    %ds, %ax
+       movw    %ax, %cs:rm_ds
+       shll    $4, %eax
+       addr32 leal     (%eax, %edi), %ebx
+       movl    %ebx, rm_data16
+
+       /* Set GDT base */
+       movl    %eax, gdt_base
+       addl    $gdt, gdt_base
+
+       /* Initialise IDT */
+       pushl   $init_idt
+       pushw   %cs
+       call    prot_call
+       popl    %eax /* discard */
+
+       /* Restore registers */
+       negl    %edi
+       popl    %ebx
+       popl    %eax
+       lret
+
+       .section ".text16", "ax", @progbits
+       .code16
+set_seg_base:
+1:     movw    %ax, 2(%bx)
+       rorl    $16, %eax
+       movb    %al, 4(%bx)
+       movb    %ah, 7(%bx)
+       roll    $16, %eax
+       ret
+
+/****************************************************************************
+ * real_to_prot (real-mode near call, 32-bit virtual return address)
+ *
+ * Switch from 16-bit real-mode to 32-bit protected mode with virtual
+ * addresses.  The real-mode %ss:sp is stored in rm_ss and rm_sp, and
+ * the protected-mode %esp is restored from the saved pm_esp.
+ * Interrupts are disabled.  All other registers may be destroyed.
+ *
+ * The return address for this function should be a 32-bit virtual
+ * address.
+ *
+ * Parameters: 
+ *   %ecx : number of bytes to move from RM stack to PM stack
+ *
+ ****************************************************************************
+ */
+       .section ".text16", "ax", @progbits
+       .code16
+real_to_prot:
+       /* Enable A20 line */
+       call    enable_a20
+       /* A failure at this point is fatal, and there's nothing we
+        * can do about it other than lock the machine to make the
+        * problem immediately visible.
+        */
+1:     jc      1b
+
+       /* Make sure we have our data segment available */
+       movw    %cs:rm_ds, %ax
+       movw    %ax, %ds
+
+       /* Add virt_offset, text16 and data16 to stack to be
+        * copied, and also copy the return address.
+        */
+       pushl   rm_virt_offset
+       pushl   rm_text16
+       pushl   rm_data16
+       addw    $16, %cx /* %ecx must be less than 64kB anyway */
+
+       /* Real-mode %ss:%sp => %ebp:%edx and virtual address => %esi */
+       xorl    %ebp, %ebp
+       movw    %ss, %bp
+       movzwl  %sp, %edx
+       movl    %ebp, %eax
+       shll    $4, %eax
+       addr32 leal (%eax,%edx), %esi
+       subl    rm_virt_offset, %esi
+
+       /* Load protected-mode global descriptor table */
+       data32 lgdt gdtr
+
+       /* Zero segment registers.  This wastes around 12 cycles on
+        * real hardware, but saves a substantial number of emulated
+        * instructions under KVM.
+        */
+       xorw    %ax, %ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %fs
+       movw    %ax, %gs
+       movw    %ax, %ss
+
+       /* Switch to protected mode */
+       cli
+       movl    %cr0, %eax
+       orb     $CR0_PE, %al
+       movl    %eax, %cr0
+       data32 ljmp     $VIRTUAL_CS, $r2p_pmode
+       .section ".text", "ax", @progbits
+       .code32
+r2p_pmode:
+       /* Set up protected-mode data segments and stack pointer */
+       movw    $VIRTUAL_DS, %ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %fs
+       movw    %ax, %gs
+       movw    %ax, %ss
+       movl    pm_esp, %esp
+
+       /* Load protected-mode interrupt descriptor table */
+       lidt    idtr
+
+       /* Record real-mode %ss:sp (after removal of data) */
+       movw    %bp, rm_ss
+       addl    %ecx, %edx
+       movw    %dx, rm_sp
+
+       /* Move data from RM stack to PM stack */
+       subl    %ecx, %esp
+       movl    %esp, %edi
+       rep movsb
+
+       /* Publish virt_offset, text16 and data16 for PM code to use */
+       popl    data16
+       popl    text16
+       popl    virt_offset
+
+       /* Return to virtual address */
+       ret
+
+/****************************************************************************
+ * prot_to_real (protected-mode near call, 32-bit real-mode return address)
+ *
+ * Switch from 32-bit protected mode with virtual addresses to 16-bit
+ * real mode.  The protected-mode %esp is stored in pm_esp and the
+ * real-mode %ss:sp is restored from the saved rm_ss and rm_sp.  The
+ * high word of the real-mode %esp is set to zero.  All real-mode data
+ * segment registers are loaded from the saved rm_ds.  Interrupts are
+ * *not* enabled, since we want to be able to use prot_to_real in an
+ * ISR.  All other registers may be destroyed.
+ *
+ * The return address for this function should be a 32-bit (sic)
+ * real-mode offset within .code16.
+ *
+ * Parameters: 
+ *   %ecx : number of bytes to move from PM stack to RM stack
+ *   %esi : real-mode global and interrupt descriptor table registers
+ *
+ ****************************************************************************
+ */
+       .section ".text", "ax", @progbits
+       .code32
+prot_to_real:
+       /* Copy real-mode global descriptor table register to RM code segment */
+       movl    text16, %edi
+       leal    rm_gdtr(%edi), %edi
+       movsw
+       movsl
+
+       /* Load real-mode interrupt descriptor table register */
+       lidt    (%esi)
+
+       /* Add return address to data to be moved to RM stack */
+       addl    $4, %ecx
+       
+       /* Real-mode %ss:sp => %ebp:edx and virtual address => %edi */
+       movzwl  rm_ss, %ebp
+       movzwl  rm_sp, %edx
+       subl    %ecx, %edx
+       movl    %ebp, %eax
+       shll    $4, %eax
+       leal    (%eax,%edx), %edi
+       subl    virt_offset, %edi
+       
+       /* Move data from PM stack to RM stack */
+       movl    %esp, %esi
+       rep movsb
+       
+       /* Record protected-mode %esp (after removal of data) */
+       movl    %esi, pm_esp
+
+       /* Load real-mode segment limits */
+       movw    $REAL_DS, %ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %fs
+       movw    %ax, %gs
+       movw    %ax, %ss
+       ljmp    $REAL_CS, $p2r_rmode
+       .section ".text16", "ax", @progbits
+       .code16
+p2r_rmode:
+       /* Load real-mode GDT */
+       data32 lgdt %cs:rm_gdtr
+       /* Switch to real mode */
+       movl    %cr0, %eax
+       andb    $0!CR0_PE, %al
+       movl    %eax, %cr0
+p2r_ljmp_rm_cs:
+       ljmp    $0, $1f
+1:
+       /* Set up real-mode data segments and stack pointer */
+       movw    %cs:rm_ds, %ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %fs
+       movw    %ax, %gs
+       movw    %bp, %ss
+       movl    %edx, %esp
+
+       /* Return to real-mode address */
+       data32 ret
+
+
+       /* Real-mode code and data segments.  Assigned by the call to
+        * init_librm.  rm_cs doubles as the segment part of the jump
+        * instruction used by prot_to_real.  Both are located in
+        * .text16 rather than .data16: rm_cs since it forms part of
+        * the jump instruction within the code segment, and rm_ds
+        * since real-mode code needs to be able to locate the data
+        * segment with no other reference available.
+        */
+       .globl rm_cs
+       .equ    rm_cs, ( p2r_ljmp_rm_cs + 3 )
+
+       .section ".text16.data", "aw", @progbits
+       .globl rm_ds
+rm_ds: .word 0
+
+       /* Real-mode global and interrupt descriptor table registers */
+       .section ".text16.data", "aw", @progbits
+rm_gdtr:
+       .word 0 /* Limit */
+       .long 0 /* Base */
+
+/****************************************************************************
+ * prot_call (real-mode far call, 16-bit real-mode far return address)
+ *
+ * Call a specific C function in the protected-mode code.  The
+ * prototype of the C function must be
+ *   void function ( struct i386_all_regs *ix86 ); 
+ * ix86 will point to a struct containing the real-mode registers
+ * at entry to prot_call.  
+ *
+ * All registers will be preserved across prot_call(), unless the C
+ * function explicitly overwrites values in ix86.  Interrupt status
+ * and GDT will also be preserved.  Gate A20 will be enabled.
+ *
+ * Note that prot_call() does not rely on the real-mode stack
+ * remaining intact in order to return, since everything relevant is
+ * copied to the protected-mode stack for the duration of the call.
+ * In particular, this means that a real-mode prefix can make a call
+ * to main() which will return correctly even if the prefix's stack
+ * gets vapourised during the Etherboot run.  (The prefix cannot rely
+ * on anything else on the stack being preserved, so should move any
+ * critical data to registers before calling main()).
+ *
+ * Parameters:
+ *   function : virtual address of protected-mode function to call
+ *
+ * Example usage:
+ *     pushl   $pxe_api_call
+ *     call    prot_call
+ *     addw    $4, %sp
+ * to call in to the C function
+ *      void pxe_api_call ( struct i386_all_regs *ix86 );
+ ****************************************************************************
+ */
+
+#define PC_OFFSET_GDT ( 0 )
+#define PC_OFFSET_IDT ( PC_OFFSET_GDT + 6 )
+#define PC_OFFSET_IX86 ( PC_OFFSET_IDT + 6 )
+#define PC_OFFSET_RETADDR ( PC_OFFSET_IX86 + SIZEOF_I386_ALL_REGS )
+#define PC_OFFSET_FUNCTION ( PC_OFFSET_RETADDR + 4 )
+#define PC_OFFSET_END ( PC_OFFSET_FUNCTION + 4 )
+
+       .section ".text16", "ax", @progbits
+       .code16
+       .globl prot_call
+prot_call:
+       /* Preserve registers, flags and GDT on external RM stack */
+       pushfl
+       pushal
+       pushw   %gs
+       pushw   %fs
+       pushw   %es
+       pushw   %ds
+       pushw   %ss
+       pushw   %cs
+       subw    $PC_OFFSET_IX86, %sp
+       movw    %sp, %bp
+       sidt    PC_OFFSET_IDT(%bp)
+       sgdt    PC_OFFSET_GDT(%bp)
+
+       /* For sanity's sake, clear the direction flag as soon as possible */
+       cld
+
+       /* Switch to protected mode and move register dump to PM stack */
+       movl    $PC_OFFSET_END, %ecx
+       pushl   $pc_pmode
+       jmp     real_to_prot
+       .section ".text", "ax", @progbits
+       .code32
+pc_pmode:
+       /* Call function */
+       leal    PC_OFFSET_IX86(%esp), %eax
+       pushl   %eax
+       call    *(PC_OFFSET_FUNCTION+4)(%esp)
+       popl    %eax /* discard */
+
+       /* Switch to real mode and move register dump back to RM stack */
+       movl    $PC_OFFSET_END, %ecx
+       movl    %esp, %esi
+       pushl   $pc_rmode
+       jmp     prot_to_real
+       .section ".text16", "ax", @progbits
+       .code16
+pc_rmode:
+       /* Restore registers and flags and return */
+       addw    $( PC_OFFSET_IX86 + 4 /* also skip %cs and %ss */ ), %sp
+       popw    %ds
+       popw    %es
+       popw    %fs
+       popw    %gs
+       popal
+       /* popal skips %esp.  We therefore want to do "movl -20(%sp),
+        * %esp", but -20(%sp) is not a valid 80386 expression.
+        * Fortunately, prot_to_real() zeroes the high word of %esp, so
+        * we can just use -20(%esp) instead.
+        */
+       addr32 movl -20(%esp), %esp
+       popfl
+       lret
+
+/****************************************************************************
+ * real_call (protected-mode near call, 32-bit virtual return address)
+ *
+ * Call a real-mode function from protected-mode code.
+ *
+ * The non-segment register values will be passed directly to the
+ * real-mode code.  The segment registers will be set as per
+ * prot_to_real.  The non-segment register values set by the real-mode
+ * function will be passed back to the protected-mode caller.  A
+ * result of this is that this routine cannot be called directly from
+ * C code, since it clobbers registers that the C ABI expects the
+ * callee to preserve.
+ *
+ * librm.h defines a convenient macro REAL_CODE() for using real_call.
+ * See librm.h and realmode.h for details and examples.
+ *
+ * Parameters:
+ *   (32-bit) near pointer to real-mode function to call
+ *
+ * Returns: none
+ ****************************************************************************
+ */
+
+#define RC_OFFSET_PRESERVE_REGS ( 0 )
+#define RC_OFFSET_RETADDR ( RC_OFFSET_PRESERVE_REGS + SIZEOF_I386_REGS )
+#define RC_OFFSET_FUNCTION ( RC_OFFSET_RETADDR + 4 )
+#define RC_OFFSET_END ( RC_OFFSET_FUNCTION + 4 )
+
+       .section ".text", "ax", @progbits
+       .code32
+       .globl real_call
+real_call:
+       /* Create register dump and function pointer copy on PM stack */
+       pushal
+       pushl   RC_OFFSET_FUNCTION(%esp)
+
+       /* Switch to real mode and move register dump to RM stack  */
+       movl    $( RC_OFFSET_RETADDR + 4 /* function pointer copy */ ), %ecx
+       pushl   $rc_rmode
+       movl    $rm_default_gdtr_idtr, %esi
+       jmp     prot_to_real
+       .section ".text16", "ax", @progbits
+       .code16
+rc_rmode:
+       /* Call real-mode function */
+       popl    rc_function
+       popal
+       call    *rc_function
+       pushal
+
+       /* For sanity's sake, clear the direction flag as soon as possible */
+       cld
+
+       /* Switch to protected mode and move register dump back to PM stack */
+       movl    $RC_OFFSET_RETADDR, %ecx
+       pushl   $rc_pmode
+       jmp     real_to_prot
+       .section ".text", "ax", @progbits
+       .code32
+rc_pmode:
+       /* Restore registers and return */
+       popal
+       ret
+
+
+       /* Function vector, used because "call xx(%sp)" is not a valid
+        * 16-bit expression.
+        */
+       .section ".data16", "aw", @progbits
+rc_function:   .word 0, 0
+
+       /* Default real-mode global and interrupt descriptor table registers */
+       .section ".data", "aw", @progbits
+rm_default_gdtr_idtr:
+       .word 0         /* Global descriptor table limit */
+       .long 0         /* Global descriptor table base */
+       .word 0x03ff    /* Interrupt descriptor table limit */
+       .long 0         /* Interrupt descriptor table base */
+
+/****************************************************************************
+ * flatten_real_mode (real-mode near call)
+ *
+ * Switch to flat real mode
+ *
+ ****************************************************************************
+ */
+       .section ".text16", "ax", @progbits
+       .code16
+       .globl flatten_real_mode
+flatten_real_mode:
+       /* Modify GDT to use flat real mode */
+       movb    $0x8f, real_cs + 6
+       movb    $0x8f, real_ds + 6
+       /* Call dummy protected-mode function */
+       pushl   $flatten_dummy
+       pushw   %cs
+       call    prot_call
+       addw    $4, %sp
+       /* Restore GDT */
+       movb    $0x00, real_cs + 6
+       movb    $0x00, real_ds + 6
+       /* Return */
+       ret
+
+       .section ".text", "ax", @progbits
+       .code32
+flatten_dummy:
+       ret
+
+/****************************************************************************
+ * Interrupt wrapper
+ *
+ * Used by the protected-mode interrupt vectors to call the
+ * interrupt() function.
+ *
+ * May be entered with either physical or virtual stack segment.
+ ****************************************************************************
+ */
+       .globl interrupt_wrapper
+interrupt_wrapper:
+       /* Preserve segment registers and original %esp */
+       pushl   %ds
+       pushl   %es
+       pushl   %fs
+       pushl   %gs
+       pushl   %ss
+       pushl   %esp
+
+       /* Switch to virtual addressing */
+       call    _intr_to_virt
+
+       /* Expand IRQ number to whole %eax register */
+       movzbl  %al, %eax
+
+       /* Call interrupt handler */
+       call    interrupt
+
+       /* Restore original stack and segment registers */
+       lss     (%esp), %esp
+       popl    %ss
+       popl    %gs
+       popl    %fs
+       popl    %es
+       popl    %ds
+
+       /* Restore registers and return */
+       popal
+       iret
+
+/****************************************************************************
+ * Stored real-mode and protected-mode stack pointers
+ *
+ * The real-mode stack pointer is stored here whenever real_to_prot
+ * is called and restored whenever prot_to_real is called.  The
+ * converse happens for the protected-mode stack pointer.
+ *
+ * Despite initial appearances this scheme is, in fact re-entrant,
+ * because program flow dictates that we always return via the point
+ * we left by.  For example:
+ *    PXE API call entry
+ *  1   real => prot
+ *        ...
+ *        Print a text string
+ *         ...
+ *  2       prot => real
+ *            INT 10
+ *  3       real => prot
+ *         ...
+ *        ...
+ *  4   prot => real
+ *    PXE API call exit
+ *
+ * At point 1, the RM mode stack value, say RPXE, is stored in
+ * rm_ss,sp.  We want this value to still be present in rm_ss,sp when
+ * we reach point 4.
+ *
+ * At point 2, the RM stack value is restored from RPXE.  At point 3,
+ * the RM stack value is again stored in rm_ss,sp.  This *does*
+ * overwrite the RPXE that we have stored there, but it's the same
+ * value, since the code between points 2 and 3 has managed to return
+ * to us.
+ ****************************************************************************
+ */
+       .section ".data", "aw", @progbits
+       .globl rm_sp
+rm_sp: .word 0
+       .globl rm_ss
+rm_ss: .word 0
+pm_esp:        .long _estack
+
+/****************************************************************************
+ * Virtual address offsets
+ *
+ * These are used by the protected-mode code to map between virtual
+ * and physical addresses, and to access variables in the .text16 or
+ * .data16 segments.
+ ****************************************************************************
+ */
+       /* Internal copies, created by init_librm (which runs in real mode) */
+       .section ".data16", "aw", @progbits
+rm_virt_offset:        .long 0
+rm_text16:     .long 0
+rm_data16:     .long 0
+
+       /* Externally-visible copies, created by real_to_prot */
+       .section ".data", "aw", @progbits
+       .globl virt_offset
+virt_offset:   .long 0 
+       .globl text16
+text16:                .long 0
+       .globl data16
+data16:                .long 0
diff --git a/roms/ipxe/src/arch/i386/transitions/librm_mgmt.c b/roms/ipxe/src/arch/i386/transitions/librm_mgmt.c
new file mode 100644 (file)
index 0000000..becb026
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * librm: a library for interfacing to real-mode code
+ *
+ * Michael Brown <mbrown@fensystems.co.uk>
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/profile.h>
+#include <realmode.h>
+#include <pic8259.h>
+
+/*
+ * This file provides functions for managing librm.
+ *
+ */
+
+/** The interrupt wrapper */
+extern char interrupt_wrapper[];
+
+/** The interrupt vectors */
+static struct interrupt_vector intr_vec[NUM_INT];
+
+/** The interrupt descriptor table */
+struct interrupt_descriptor idt[NUM_INT] __attribute__ (( aligned ( 16 ) ));
+
+/** The interrupt descriptor table register */
+struct idtr idtr = {
+       .limit = ( sizeof ( idt ) - 1 ),
+};
+
+/** Timer interrupt profiler */
+static struct profiler timer_irq_profiler __profiler = { .name = "irq.timer" };
+
+/** Other interrupt profiler */
+static struct profiler other_irq_profiler __profiler = { .name = "irq.other" };
+
+/**
+ * Allocate space on the real-mode stack and copy data there from a
+ * user buffer
+ *
+ * @v data             User buffer
+ * @v size             Size of stack data
+ * @ret sp             New value of real-mode stack pointer
+ */
+uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size ) {
+       userptr_t rm_stack;
+       rm_sp -= size;
+       rm_stack = real_to_user ( rm_ss, rm_sp );
+       memcpy_user ( rm_stack, 0, data, 0, size );
+       return rm_sp;
+};
+
+/**
+ * Deallocate space on the real-mode stack, optionally copying back
+ * data to a user buffer.
+ *
+ * @v data             User buffer
+ * @v size             Size of stack data
+ */
+void remove_user_from_rm_stack ( userptr_t data, size_t size ) {
+       if ( data ) {
+               userptr_t rm_stack = real_to_user ( rm_ss, rm_sp );
+               memcpy_user ( rm_stack, 0, data, 0, size );
+       }
+       rm_sp += size;
+};
+
+/**
+ * Set interrupt vector
+ *
+ * @v intr             Interrupt number
+ * @v vector           Interrupt vector, or NULL to disable
+ */
+void set_interrupt_vector ( unsigned int intr, void *vector ) {
+       struct interrupt_descriptor *idte;
+
+       idte = &idt[intr];
+       idte->segment = VIRTUAL_CS;
+       idte->attr = ( vector ? ( IDTE_PRESENT | IDTE_TYPE_IRQ32 ) : 0 );
+       idte->low = ( ( ( uint32_t ) vector ) & 0xffff );
+       idte->high = ( ( ( uint32_t ) vector ) >> 16 );
+}
+
+/**
+ * Initialise interrupt descriptor table
+ *
+ */
+void init_idt ( void ) {
+       struct interrupt_vector *vec;
+       unsigned int intr;
+
+       /* Initialise the interrupt descriptor table and interrupt vectors */
+       for ( intr = 0 ; intr < NUM_INT ; intr++ ) {
+               vec = &intr_vec[intr];
+               vec->pushal = PUSHAL_INSN;
+               vec->movb = MOVB_INSN;
+               vec->intr = intr;
+               vec->jmp = JMP_INSN;
+               vec->offset = ( ( uint32_t ) interrupt_wrapper -
+                               ( uint32_t ) vec->next );
+               set_interrupt_vector ( intr, vec );
+       }
+       DBGC ( &intr_vec[0], "INTn vector at %p+%zxn (phys %#lx+%zxn)\n",
+              intr_vec, sizeof ( intr_vec[0] ),
+              virt_to_phys ( intr_vec ), sizeof ( intr_vec[0] ) );
+
+       /* Initialise the interrupt descriptor table register */
+       idtr.base = virt_to_phys ( idt );
+}
+
+/**
+ * Determine interrupt profiler (for debugging)
+ *
+ * @v intr             Interrupt number
+ * @ret profiler       Profiler
+ */
+static struct profiler * interrupt_profiler ( int intr ) {
+
+       switch ( intr ) {
+       case IRQ_INT ( 0 ) :
+               return &timer_irq_profiler;
+       default:
+               return &other_irq_profiler;
+       }
+}
+
+/**
+ * Interrupt handler
+ *
+ * @v intr             Interrupt number
+ */
+void __attribute__ (( cdecl, regparm ( 1 ) )) interrupt ( int intr ) {
+       struct profiler *profiler = interrupt_profiler ( intr );
+       uint32_t discard_eax;
+
+       /* Reissue interrupt in real mode */
+       profile_start ( profiler );
+       __asm__ __volatile__ ( REAL_CODE ( "movb %%al, %%cs:(1f + 1)\n\t"
+                                          "\n1:\n\t"
+                                          "int $0x00\n\t" )
+                              : "=a" ( discard_eax ) : "0" ( intr ) );
+       profile_stop ( profiler );
+       profile_exclude ( profiler );
+}
+
+PROVIDE_UACCESS_INLINE ( librm, phys_to_user );
+PROVIDE_UACCESS_INLINE ( librm, user_to_phys );
+PROVIDE_UACCESS_INLINE ( librm, virt_to_user );
+PROVIDE_UACCESS_INLINE ( librm, user_to_virt );
+PROVIDE_UACCESS_INLINE ( librm, userptr_add );
+PROVIDE_UACCESS_INLINE ( librm, memcpy_user );
+PROVIDE_UACCESS_INLINE ( librm, memmove_user );
+PROVIDE_UACCESS_INLINE ( librm, memset_user );
+PROVIDE_UACCESS_INLINE ( librm, strlen_user );
+PROVIDE_UACCESS_INLINE ( librm, memchr_user );
@@ -52,13 +52,13 @@ static struct profiler r2p_profiler __profiler = { .name = "r2p" };
 /** Real-mode call profiler */
 static struct profiler real_call_profiler __profiler = { .name = "real_call" };
 
-/** Virtual call profiler */
-static struct profiler virt_call_profiler __profiler = { .name = "virt_call" };
+/** Protected-mode call profiler */
+static struct profiler prot_call_profiler __profiler = { .name = "prot_call" };
 
 /**
- * Dummy function for profiling tests
+ * Dummy protected-mode function
  */
-static __asmcall void librm_test_call ( struct i386_all_regs *ix86 __unused ) {
+static void librm_test_prot_call ( void ) {
        /* Do nothing */
 }
 
@@ -69,11 +69,9 @@ static __asmcall void librm_test_call ( struct i386_all_regs *ix86 __unused ) {
 static void librm_test_exec ( void ) {
        unsigned int i;
        unsigned long timestamp;
-       uint32_t timestamp_lo;
-       uint32_t timestamp_hi;
-       uint32_t started;
-       uint32_t stopped;
-       uint32_t discard_d;
+       unsigned long started;
+       unsigned long stopped;
+       unsigned int discard_d;
 
        /* Profile mode transitions.  We want to profile each
         * direction of the transition separately, so perform an RDTSC
@@ -83,12 +81,8 @@ static void librm_test_exec ( void ) {
        for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
                profile_start ( &p2r_profiler );
                __asm__ __volatile__ ( REAL_CODE ( "rdtsc\n\t" )
-                                      : "=a" ( timestamp_lo ),
-                                        "=d" ( timestamp_hi )
+                                      : "=a" ( timestamp ), "=d" ( discard_d )
                                       : );
-               timestamp = timestamp_lo;
-               if ( sizeof ( timestamp ) > sizeof ( timestamp_lo ) )
-                       timestamp |= ( ( ( uint64_t ) timestamp_hi ) << 32 );
                profile_start_at ( &r2p_profiler, timestamp );
                profile_stop ( &r2p_profiler );
                profile_stop_at ( &p2r_profiler, timestamp );
@@ -97,20 +91,24 @@ static void librm_test_exec ( void ) {
        /* Profile complete real-mode call cycle */
        for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
                profile_start ( &real_call_profiler );
-               __asm__ __volatile__ ( REAL_CODE ( "" ) );
+               __asm__ __volatile__ ( REAL_CODE ( "" ) : : );
                profile_stop ( &real_call_profiler );
        }
 
-       /* Profile complete virtual call cycle */
+       /* Profile complete protected-mode call cycle */
        for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
                __asm__ __volatile__ ( REAL_CODE ( "rdtsc\n\t"
-                                                  "movl %k0, %k2\n\t"
-                                                  VIRT_CALL ( librm_test_call )
+                                                  "movl %0, %2\n\t"
+                                                  "pushl %3\n\t"
+                                                  "pushw %%cs\n\t"
+                                                  "call prot_call\n\t"
+                                                  "addw $4, %%sp\n\t"
                                                   "rdtsc\n\t" )
                                       : "=a" ( stopped ), "=d" ( discard_d ),
-                                        "=R" ( started ) : );
-               profile_start_at ( &virt_call_profiler, started );
-               profile_stop_at ( &virt_call_profiler, stopped );
+                                        "=r" ( started )
+                                      : "i" ( librm_test_prot_call ) );
+               profile_start_at ( &prot_call_profiler, started );
+               profile_stop_at ( &prot_call_profiler, stopped );
        }
 }
 
index 368c29f..98c49b9 100644 (file)
@@ -1,8 +1,3 @@
-# Assembler section type character
-#
-ASM_TCHAR      := @
-ASM_TCHAR_OPS  := @
-
 # Include common x86 headers
 #
 INCDIRS                += arch/x86/include
@@ -10,18 +5,11 @@ INCDIRS              += arch/x86/include
 # x86-specific directories containing source files
 #
 SRCDIRS                += arch/x86/core
-SRCDIRS                += arch/x86/image
-SRCDIRS                += arch/x86/interface/pcbios
-SRCDIRS                += arch/x86/interface/pxe
-SRCDIRS                += arch/x86/interface/pxeparent
 SRCDIRS                += arch/x86/interface/efi
-SRCDIRS                += arch/x86/interface/vmware
-SRCDIRS                += arch/x86/interface/syslinux
 SRCDIRS                += arch/x86/prefix
 SRCDIRS                += arch/x86/hci/commands
 SRCDIRS                += arch/x86/drivers/xen
 SRCDIRS                += arch/x86/drivers/hyperv
-SRCDIRS                += arch/x86/transitions
 
 # breaks building some of the linux-related objects
 CFLAGS         += -Ulinux
@@ -29,10 +17,6 @@ CFLAGS               += -Ulinux
 # disable valgrind
 CFLAGS         += -DNVALGRIND
 
-# Define version string for lkrnprefix.S
-#
-CFLAGS_lkrnprefix      += -DVERSION="\"$(VERSION)\""
-
 # Include Hyper-V driver in the all-drivers build
 #
 DRIVERS_hyperv += hyperv
index f04be42..f73bc7d 100644 (file)
@@ -1,6 +1,42 @@
 # -*- makefile -*- : Force emacs to use Makefile mode
 
-# Include generic EFI Makefile
+# The EFI linker script
 #
-MAKEDEPS       += Makefile.efi
-include Makefile.efi
+LDSCRIPT       = arch/x86/scripts/efi.lds
+
+# Retain relocation information for elf2efi
+#
+LDFLAGS                += -q -S
+
+# Media types.
+#
+NON_AUTO_MEDIA += efi
+NON_AUTO_MEDIA += efidrv
+NON_AUTO_MEDIA += drv.efi
+NON_AUTO_MEDIA += efirom
+
+# Include SNP driver in the all-drivers build
+#
+DRIVERS_net += snp
+
+# Rules for building EFI files
+#
+$(BIN)/%.efi : $(BIN)/%.efi.tmp $(ELF2EFI)
+       $(QM)$(ECHO) "  [FINISH] $@"
+       $(Q)$(ELF2EFI) --subsystem=10 $< $@
+
+$(BIN)/%.efidrv : $(BIN)/%.efidrv.tmp $(ELF2EFI)
+       $(QM)$(ECHO) "  [FINISH] $@"
+       $(Q)$(ELF2EFI) --subsystem=11 $< $@
+
+$(BIN)/%.drv.efi : $(BIN)/%.efidrv
+       $(QM)$(ECHO) "  [FINISH] $@"
+       $(Q)$(CP) $< $@
+
+$(BIN)/%.efirom : $(BIN)/%.efidrv $(EFIROM)
+       $(QM)$(ECHO) "  [FINISH] $@"
+       $(Q)$(EFIROM) -v $(TGT_PCI_VENDOR) -d $(TGT_PCI_DEVICE) $< $@
+
+$(BIN)/efidrv.cab : $(BIN)/alldrv.efis # $(ALL_drv.efi) is not yet defined
+       $(QM)$(ECHO) "  [CAB] $@"
+       $(Q)$(LCAB) -n -q $(ALL_drv.efi) $@
diff --git a/roms/ipxe/src/arch/x86/Makefile.pcbios b/roms/ipxe/src/arch/x86/Makefile.pcbios
deleted file mode 100644 (file)
index f8c2253..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-# -*- makefile -*- : Force emacs to use Makefile mode
-
-# BIOS-specific directories containing source files
-#
-SRCDIRS                += arch/x86/drivers/net
-
-# The i386 linker script
-#
-LDSCRIPT       = arch/x86/scripts/pcbios.lds
-
-# Stop ld from complaining about our customised linker script
-#
-LDFLAGS                += -N --no-check-sections
-
-# Prefix always starts at address zero
-#
-LDFLAGS                += --section-start=.prefix=0
-
-# Media types.
-#
-MEDIA          += rom
-MEDIA          += mrom
-MEDIA          += pcirom
-MEDIA          += isarom
-MEDIA          += pxe
-MEDIA          += kpxe
-MEDIA          += kkpxe
-MEDIA          += kkkpxe
-MEDIA          += lkrn
-MEDIA          += dsk
-MEDIA          += nbi
-MEDIA          += hd
-MEDIA          += raw
-MEDIA          += exe
-
-# Padding rules
-#
-PAD_rom                = $(PERL) $(PADIMG) --blksize=512 --byte=0xff
-PAD_mrom       = $(PAD_rom)
-PAD_pcirom     = $(PAD_rom)
-PAD_isarom     = $(PAD_rom)
-PAD_dsk                = $(PERL) $(PADIMG) --blksize=512
-PAD_hd         = $(PERL) $(PADIMG) --blksize=32768
-PAD_exe                = $(PERL) $(PADIMG) --blksize=512
-
-# Finalisation rules
-#
-FINALISE_rom   = $(PERL) $(FIXROM)
-FINALISE_mrom  = $(FINALISE_rom)
-FINALISE_pcirom        = $(FINALISE_rom)
-FINALISE_isarom        = $(FINALISE_rom)
-
-# Use $(ROMS) rather than $(DRIVERS) for "allroms", "allmroms", etc.
-#
-LIST_NAME_rom := ROMS
-LIST_NAME_mrom := ROMS
-LIST_NAME_pcirom := ROMS
-LIST_NAME_isarom := ROMS
-
-# Locations of isolinux files
-#
-SYSLINUX_DIR_LIST      := \
-       /usr/lib/syslinux \
-       /usr/lib/syslinux/bios \
-       /usr/lib/syslinux/modules/bios \
-       /usr/share/syslinux \
-       /usr/share/syslinux/bios \
-       /usr/share/syslinux/modules/bios \
-       /usr/local/share/syslinux \
-       /usr/local/share/syslinux/bios \
-       /usr/local/share/syslinux/modules/bios \
-       /usr/lib/ISOLINUX
-ISOLINUX_BIN_LIST      := \
-       $(ISOLINUX_BIN) \
-       $(patsubst %,%/isolinux.bin,$(SYSLINUX_DIR_LIST))
-LDLINUX_C32_LIST       := \
-       $(LDLINUX_C32) \
-       $(patsubst %,%/ldlinux.c32,$(SYSLINUX_DIR_LIST))
-ISOLINUX_BIN   = $(firstword $(wildcard $(ISOLINUX_BIN_LIST)))
-LDLINUX_C32    = $(firstword $(wildcard $(LDLINUX_C32_LIST)))
-
-# rule to make a non-emulation ISO boot image
-NON_AUTO_MEDIA += iso
-%iso:  %lkrn util/geniso
-       $(QM)$(ECHO) "  [GENISO] $@"
-       $(Q)ISOLINUX_BIN=$(ISOLINUX_BIN) LDLINUX_C32=$(LDLINUX_C32) \
-           VERSION="$(VERSION)" bash util/geniso -o $@ $<
-
-# rule to make a floppy emulation ISO boot image
-NON_AUTO_MEDIA += liso
-%liso: %lkrn util/geniso
-       $(QM)$(ECHO) "  [GENISO] $@"
-       $(Q)VERSION="$(VERSION)" bash util/geniso -l -o $@ $<
-
-# rule to make a syslinux floppy image (mountable, bootable)
-NON_AUTO_MEDIA += sdsk
-%sdsk: %lkrn util/gensdsk
-       $(QM)$(ECHO) "  [GENSDSK] $@"
-       $(Q)bash util/gensdsk $@ $<
-
-# rule to write disk images to /dev/fd0
-NON_AUTO_MEDIA += fd0
-%fd0 : %dsk
-       $(QM)$(ECHO) "  [DD] $@"
-       $(Q)dd if=$< bs=512 conv=sync of=/dev/fd0
-       $(Q)sync
-
-# Special target for building Master Boot Record binary
-$(BIN)/mbr.bin : $(BIN)/mbr.o
-       $(QM)$(ECHO) "  [LD] $@"
-       $(Q)$(LD) $(LDFLAGS) -o $@ --oformat binary -e 0 $<
-
-# rule to make a USB disk image
-$(BIN)/usbdisk.bin : $(BIN)/usbdisk.o
-       $(QM)$(ECHO) "  [LD] $@"
-       $(Q)$(LD) $(LDFLAGS) -o $@ --oformat binary -e 0 $<
-
-NON_AUTO_MEDIA += usb
-%usb: $(BIN)/usbdisk.bin %hd
-       $(QM)$(ECHO) "  [FINISH] $@"
-       $(Q)cat $^ > $@
-
-# Padded floppy image (e.g. for iLO)
-NON_AUTO_MEDIA += pdsk
-%pdsk : %dsk
-       $(Q)cp $< $@
-       $(Q)$(PADIMG) --blksize=1474560 $@
diff --git a/roms/ipxe/src/arch/x86/core/gdbmach.c b/roms/ipxe/src/arch/x86/core/gdbmach.c
deleted file mode 100644 (file)
index af6abfe..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2008 Stefan Hajnoczi <stefanha@gmail.com>.
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stddef.h>
-#include <stdio.h>
-#include <errno.h>
-#include <assert.h>
-#include <ipxe/uaccess.h>
-#include <ipxe/gdbstub.h>
-#include <librm.h>
-#include <gdbmach.h>
-
-/** @file
- *
- * GDB architecture-specific bits for x86
- *
- */
-
-/** Number of hardware breakpoints */
-#define NUM_HWBP 4
-
-/** Debug register 7: Global breakpoint enable */
-#define DR7_G( bp ) ( 2 << ( 2 * (bp) ) )
-
-/** Debug register 7: Global exact breakpoint enable */
-#define DR7_GE ( 1 << 9 )
-
-/** Debug register 7: Break on data writes */
-#define DR7_RWLEN_WRITE 0x11110000
-
-/** Debug register 7: Break on data access */
-#define DR7_RWLEN_ACCESS 0x33330000
-
-/** Debug register 7: One-byte length */
-#define DR7_RWLEN_1 0x00000000
-
-/** Debug register 7: Two-byte length */
-#define DR7_RWLEN_2 0x44440000
-
-/** Debug register 7: Four-byte length */
-#define DR7_RWLEN_4 0xcccc0000
-
-/** Debug register 7: Eight-byte length */
-#define DR7_RWLEN_8 0x88880000
-
-/** Debug register 7: Breakpoint R/W and length mask */
-#define DR7_RWLEN_MASK( bp ) ( 0xf0000 << ( 4 * (bp) ) )
-
-/** Hardware breakpoint addresses (debug registers 0-3) */
-static unsigned long dr[NUM_HWBP];
-
-/** Active value of debug register 7 */
-static unsigned long dr7 = DR7_GE;
-
-/**
- * Update debug registers
- *
- */
-static void gdbmach_update ( void ) {
-
-       /* Set debug registers */
-       __asm__ __volatile__ ( "mov %0, %%dr0" : : "r" ( dr[0] ) );
-       __asm__ __volatile__ ( "mov %0, %%dr1" : : "r" ( dr[1] ) );
-       __asm__ __volatile__ ( "mov %0, %%dr2" : : "r" ( dr[2] ) );
-       __asm__ __volatile__ ( "mov %0, %%dr3" : : "r" ( dr[3] ) );
-       __asm__ __volatile__ ( "mov %0, %%dr7" : : "r" ( dr7 ) );
-}
-
-/**
- * Find reusable or available hardware breakpoint
- *
- * @v addr             Linear address
- * @v rwlen            Control bits
- * @ret bp             Hardware breakpoint, or negative error
- */
-static int gdbmach_find ( unsigned long addr, unsigned int rwlen ) {
-       unsigned int i;
-       int bp = -ENOENT;
-
-       /* Look for a reusable or available breakpoint */
-       for ( i = 0 ; i < NUM_HWBP ; i++ ) {
-
-               /* If breakpoint is not enabled, then it is available */
-               if ( ! ( dr7 & DR7_G ( i ) ) ) {
-                       bp = i;
-                       continue;
-               }
-
-               /* If breakpoint is enabled and has the same address
-                * and control bits, then reuse it.
-                */
-               if ( ( dr[i] == addr ) &&
-                    ( ( ( dr7 ^ rwlen ) & DR7_RWLEN_MASK ( i ) ) == 0 ) ) {
-                       bp = i;
-                       break;
-               }
-       }
-
-       return bp;
-}
-
-/**
- * Set hardware breakpoint
- *
- * @v type             GDB breakpoint type
- * @v addr             Virtual address
- * @v len              Length
- * @v enable           Enable (not disable) breakpoint
- * @ret rc             Return status code
- */
-int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len,
-                            int enable ) {
-       unsigned int rwlen;
-       unsigned long mask;
-       int bp;
-
-       /* Parse breakpoint type */
-       switch ( type ) {
-       case GDBMACH_WATCH:
-               rwlen = DR7_RWLEN_WRITE;
-               break;
-       case GDBMACH_AWATCH:
-               rwlen = DR7_RWLEN_ACCESS;
-               break;
-       default:
-               return -ENOTSUP;
-       }
-
-       /* Parse breakpoint length */
-       switch ( len ) {
-       case 1:
-               rwlen |= DR7_RWLEN_1;
-               break;
-       case 2:
-               rwlen |= DR7_RWLEN_2;
-               break;
-       case 4:
-               rwlen |= DR7_RWLEN_4;
-               break;
-       case 8:
-               rwlen |= DR7_RWLEN_8;
-               break;
-       default:
-               return -ENOTSUP;
-       }
-
-       /* Convert to linear address */
-       if ( sizeof ( physaddr_t ) <= sizeof ( uint32_t ) )
-               addr = virt_to_phys ( ( void * ) addr );
-
-       /* Find reusable or available hardware breakpoint */
-       bp = gdbmach_find ( addr, rwlen );
-       if ( bp < 0 )
-               return ( enable ? -ENOBUFS : 0 );
-
-       /* Configure this breakpoint */
-       DBGC ( &dr[0], "GDB bp %d at %p+%zx type %d (%sabled)\n",
-              bp, ( ( void * ) addr ), len, type, ( enable ? "en" : "dis" ) );
-       dr[bp] = addr;
-       mask = DR7_RWLEN_MASK ( bp );
-       dr7 = ( ( dr7 & ~mask ) | ( rwlen & mask ) );
-       mask = DR7_G ( bp );
-       dr7 &= ~mask;
-       if ( enable )
-               dr7 |= mask;
-
-       /* Update debug registers */
-       gdbmach_update();
-
-       return 0;
-}
-
-/**
- * Handle exception
- *
- * @v signo            GDB signal number
- * @v regs             Register dump
- */
-__asmcall void gdbmach_handler ( int signo, gdbreg_t *regs ) {
-       unsigned long dr7_disabled = DR7_GE;
-       unsigned long dr6_clear = 0;
-
-       /* Temporarily disable breakpoints */
-       __asm__ __volatile__ ( "mov %0, %%dr7\n" : : "r" ( dr7_disabled ) );
-
-       /* Handle exception */
-       DBGC ( &dr[0], "GDB signal %d\n", signo );
-       DBGC2_HDA ( &dr[0], 0, regs, ( GDBMACH_NREGS * sizeof ( *regs ) ) );
-       gdbstub_handler ( signo, regs );
-       DBGC ( &dr[0], "GDB signal %d returning\n", signo );
-       DBGC2_HDA ( &dr[0], 0, regs, ( GDBMACH_NREGS * sizeof ( *regs ) ) );
-
-       /* Clear breakpoint status register */
-       __asm__ __volatile__ ( "mov %0, %%dr6\n" : : "r" ( dr6_clear ) );
-
-       /* Re-enable breakpoints */
-       __asm__ __volatile__ ( "mov %0, %%dr7\n" : : "r" ( dr7 ) );
-}
-
-/**
- * CPU exception vectors
- *
- * Note that we cannot intercept anything from INT8 (double fault)
- * upwards, since these overlap by default with IRQ0-7.
- */
-static void * gdbmach_vectors[] = {
-       gdbmach_sigfpe,         /* Divide by zero */
-       gdbmach_sigtrap,        /* Debug trap */
-       NULL,                   /* Non-maskable interrupt */
-       gdbmach_sigtrap,        /* Breakpoint */
-       gdbmach_sigstkflt,      /* Overflow */
-       gdbmach_sigstkflt,      /* Bound range exceeded */
-       gdbmach_sigill,         /* Invalid opcode */
-};
-
-/**
- * Initialise GDB
- */
-void gdbmach_init ( void ) {
-       unsigned int i;
-
-       /* Hook CPU exception vectors */
-       for ( i = 0 ; i < ( sizeof ( gdbmach_vectors ) /
-                           sizeof ( gdbmach_vectors[0] ) ) ; i++ ) {
-               if ( gdbmach_vectors[i] )
-                       set_interrupt_vector ( i, gdbmach_vectors[i] );
-       }
-}
index 0d09be8..9b8e6b1 100644 (file)
@@ -36,12 +36,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  * Prepare for Type 1 PCI configuration space access
  *
  * @v pci              PCI device
- * @v where            Location within PCI configuration space
+ * @v where    Location within PCI configuration space
  */
 void pcidirect_prepare ( struct pci_device *pci, int where ) {
-       uint16_t busdevfn = ( pci->busdevfn & 0xffff );
-
-       outl ( ( 0x80000000 | ( busdevfn << 8 ) | ( where & ~3 ) ),
+       outl ( ( 0x80000000 | ( pci->busdevfn << 8 ) | ( where & ~3 ) ),
               PCIDIRECT_CONFIG_ADDRESS );
 }
 
index 6c6b6e1..3081fa8 100644 (file)
@@ -74,6 +74,9 @@ static __unused void i386_writeq ( uint64_t data, volatile uint64_t *io_addr ) {
 
 PROVIDE_IOAPI_INLINE ( x86, phys_to_bus );
 PROVIDE_IOAPI_INLINE ( x86, bus_to_phys );
+PROVIDE_IOAPI_INLINE ( x86, ioremap );
+PROVIDE_IOAPI_INLINE ( x86, iounmap );
+PROVIDE_IOAPI_INLINE ( x86, io_to_bus );
 PROVIDE_IOAPI_INLINE ( x86, readb );
 PROVIDE_IOAPI_INLINE ( x86, readw );
 PROVIDE_IOAPI_INLINE ( x86, readl );
index ed323d5..88042f5 100644 (file)
@@ -42,8 +42,8 @@ extern char x86_tcpip_loop_end[];
  * @v len              Length of data buffer
  * @ret cksum          Updated checksum, in network byte order
  */
-uint16_t tcpip_continue_chksum ( uint16_t partial, const void *data,
-                                size_t len ) {
+uint16_t x86_tcpip_continue_chksum ( uint16_t partial,
+                                    const void *data, size_t len ) {
        unsigned long sum = ( ( ~partial ) & 0xffff );
        unsigned long initial_word_count;
        unsigned long loop_count;
diff --git a/roms/ipxe/src/arch/x86/include/bits/bitops.h b/roms/ipxe/src/arch/x86/include/bits/bitops.h
deleted file mode 100644 (file)
index 17dcf10..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-#ifndef _BITS_BITOPS_H
-#define _BITS_BITOPS_H
-
-/** @file
- *
- * x86 bit operations
- *
- * We perform atomic bit set and bit clear operations using "lock bts"
- * and "lock btr".  We use the output constraint to inform the
- * compiler that any memory from the start of the bit field up to and
- * including the byte containing the bit may be modified.  (This is
- * overkill but shouldn't matter in practice since we're unlikely to
- * subsequently read other bits from the same bit field.)
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-
-/**
- * Set bit atomically
- *
- * @v bit              Bit to set
- * @v bits             Bit field
- */
-static inline __attribute__ (( always_inline )) void
-set_bit ( unsigned int bit, volatile void *bits ) {
-       volatile struct {
-               uint8_t byte[ ( bit / 8 ) + 1 ];
-       } *bytes = bits;
-
-       __asm__ __volatile__ ( "lock bts %1, %0"
-                              : "+m" ( *bytes ) : "Ir" ( bit ) );
-}
-
-/**
- * Clear bit atomically
- *
- * @v bit              Bit to set
- * @v bits             Bit field
- */
-static inline __attribute__ (( always_inline )) void
-clear_bit ( unsigned int bit, volatile void *bits ) {
-       volatile struct {
-               uint8_t byte[ ( bit / 8 ) + 1 ];
-       } *bytes = bits;
-
-       __asm__ __volatile__ ( "lock btr %1, %0"
-                              : "+m" ( *bytes ) : "Ir" ( bit ) );
-}
-
-/**
- * Test and set bit atomically
- *
- * @v bit              Bit to set
- * @v bits             Bit field
- * @ret old            Old value of bit (zero or non-zero)
- */
-static inline __attribute__ (( always_inline )) int
-test_and_set_bit ( unsigned int bit, volatile void *bits ) {
-       volatile struct {
-               uint8_t byte[ ( bit / 8 ) + 1 ];
-       } *bytes = bits;
-       int old;
-
-       __asm__ __volatile__ ( "lock bts %2, %0\n\t"
-                              "sbb %1, %1\n\t"
-                              : "+m" ( *bytes ), "=r"  ( old )
-                              : "Ir" ( bit ) );
-       return old;
-}
-
-/**
- * Test and clear bit atomically
- *
- * @v bit              Bit to set
- * @v bits             Bit field
- * @ret old            Old value of bit (zero or non-zero)
- */
-static inline __attribute__ (( always_inline )) int
-test_and_clear_bit ( unsigned int bit, volatile void *bits ) {
-       volatile struct {
-               uint8_t byte[ ( bit / 8 ) + 1 ];
-       } *bytes = bits;
-       int old;
-
-       __asm__ __volatile__ ( "lock btr %2, %0\n\t"
-                              "sbb %1, %1\n\t"
-                              : "+m" ( *bytes ), "=r"  ( old )
-                              : "Ir" ( bit ) );
-       return old;
-}
-
-#endif /* _BITS_BITOPS_H */
index 4279224..0d1617d 100644 (file)
@@ -22,7 +22,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define ERRFILE_apm            ( ERRFILE_ARCH | ERRFILE_CORE | 0x000b0000 )
 #define ERRFILE_vesafb         ( ERRFILE_ARCH | ERRFILE_CORE | 0x000c0000 )
 #define ERRFILE_int13con       ( ERRFILE_ARCH | ERRFILE_CORE | 0x000d0000 )
-#define ERRFILE_gdbmach                ( ERRFILE_ARCH | ERRFILE_CORE | 0x000e0000 )
 
 #define ERRFILE_bootsector     ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00000000 )
 #define ERRFILE_bzimage               ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00010000 )
@@ -53,6 +52,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #define ERRFILE_cpuid_cmd      ( ERRFILE_ARCH | ERRFILE_OTHER | 0x00000000 )
 #define ERRFILE_cpuid_settings ( ERRFILE_ARCH | ERRFILE_OTHER | 0x00010000 )
+#define ERRFILE_efi_entropy    ( ERRFILE_ARCH | ERRFILE_OTHER | 0x00020000 )
 
 /** @} */
 
diff --git a/roms/ipxe/src/arch/x86/include/bits/iomap.h b/roms/ipxe/src/arch/x86/include/bits/iomap.h
deleted file mode 100644 (file)
index d6fff25..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _BITS_IOMAP_H
-#define _BITS_IOMAP_H
-
-/** @file
- *
- * x86-specific I/O mapping API implementations
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/iomap_pages.h>
-
-#endif /* _BITS_IOMAP_H */
index 0ac55b1..5c2baff 100644 (file)
@@ -9,7 +9,9 @@
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
-extern uint16_t tcpip_continue_chksum ( uint16_t partial, const void *data,
-                                       size_t len );
+extern uint16_t x86_tcpip_continue_chksum ( uint16_t partial,
+                                           const void *data, size_t len );
+
+#define tcpip_continue_chksum x86_tcpip_continue_chksum
 
 #endif /* _BITS_TCPIP_H */
index 3433cea..fc065ea 100644 (file)
@@ -161,4 +161,23 @@ xen_hypercall_5 ( struct xen_hypervisor *xen, unsigned int hypercall,
        return retval;
 }
 
+/**
+ * Test and clear pending event
+ *
+ * @v xen              Xen hypervisor
+ * @v port             Event channel port
+ * @ret pending                Event was pending
+ */
+static inline __attribute__ (( always_inline )) uint8_t
+xenevent_pending ( struct xen_hypervisor *xen, evtchn_port_t port ) {
+       uint8_t pending;
+
+       __asm__ __volatile__ ( "lock btr %2, %0\n\t"
+                              "setc %1\n\t"
+                              : "+m" ( xen->shared->evtchn_pending ),
+                                "=a"  ( pending )
+                              : "Ir" ( port ) );
+       return pending;
+}
+
 #endif /* _BITS_XEN_H */
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/iomap_pages.h b/roms/ipxe/src/arch/x86/include/ipxe/iomap_pages.h
deleted file mode 100644 (file)
index 18e0a30..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _IPXE_IOMAP_PAGES_H
-#define _IPXE_IOMAP_PAGES_H
-
-/** @file
- *
- * I/O mapping API using page tables
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#ifdef IOMAP_PAGES
-#define IOMAP_PREFIX_pages
-#else
-#define IOMAP_PREFIX_pages __pages_
-#endif
-
-static inline __always_inline unsigned long
-IOMAP_INLINE ( pages, io_to_bus ) ( volatile const void *io_addr ) {
-       /* Not easy to do; just return the CPU address for debugging purposes */
-       return ( ( intptr_t ) io_addr );
-}
-
-#endif /* _IPXE_IOMAP_PAGES_H */
index a6ebe1f..5214e9f 100644 (file)
@@ -32,7 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define PAGE_SHIFT 12
 
 /*
- * Physical<->Bus address mappings
+ * Physical<->Bus and Bus<->I/O address mappings
  *
  */
 
@@ -46,6 +46,21 @@ IOAPI_INLINE ( x86, bus_to_phys ) ( unsigned long bus_addr ) {
        return bus_addr;
 }
 
+static inline __always_inline void *
+IOAPI_INLINE ( x86, ioremap ) ( unsigned long bus_addr, size_t len __unused ) {
+       return ( bus_addr ? phys_to_virt ( bus_addr ) : NULL );
+}
+
+static inline __always_inline void
+IOAPI_INLINE ( x86, iounmap ) ( volatile const void *io_addr __unused ) {
+       /* Nothing to do */
+}
+
+static inline __always_inline unsigned long
+IOAPI_INLINE ( x86, io_to_bus ) ( volatile const void *io_addr ) {
+       return virt_to_phys ( io_addr );
+}
+
 /*
  * MMIO reads and writes up to native word size
  *
diff --git a/roms/ipxe/src/arch/x86/include/rmsetjmp.h b/roms/ipxe/src/arch/x86/include/rmsetjmp.h
deleted file mode 100644 (file)
index 3470be4..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _RMSETJMP_H
-#define _RMSETJMP_H
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <setjmp.h>
-#include <realmode.h>
-
-/** A real-mode-extended jump buffer */
-typedef struct {
-       /** Jump buffer */
-       jmp_buf env;
-       /** Real-mode stack pointer */
-       segoff_t rm_stack;
-} rmjmp_buf[1];
-
-#define rmsetjmp( _env ) ( {                                   \
-       (_env)->rm_stack.segment = rm_ss;                       \
-       (_env)->rm_stack.offset = rm_sp;                        \
-       setjmp ( (_env)->env ); } )                             \
-
-#define rmlongjmp( _env, _val ) do {                           \
-       rm_ss = (_env)->rm_stack.segment;                       \
-       rm_sp = (_env)->rm_stack.offset;                        \
-       longjmp ( (_env)->env, (_val) );                        \
-       } while ( 0 )
-
-#endif /* _RMSETJMP_H */
@@ -26,7 +26,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <errno.h>
 #include <ipxe/entropy.h>
 #include <ipxe/crc32.h>
-#include <ipxe/profile.h>
 #include <ipxe/efi/efi.h>
 #include <ipxe/efi/Protocol/Rng.h>
 
@@ -105,12 +104,13 @@ static void efi_entropy_disable ( void ) {
 /**
  * Wait for a timer tick
  *
- * @ret low            CPU profiling low-order bits, or negative error
+ * @ret low            TSC low-order bits, or negative error
  */
 static int efi_entropy_tick ( void ) {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        UINTN index;
        uint16_t low;
+       uint32_t discard_d;
        EFI_STATUS efirc;
        int rc;
 
@@ -129,8 +129,8 @@ static int efi_entropy_tick ( void ) {
                return rc;
        }
 
-       /* Get current CPU profiling timestamp low-order bits */
-       low = profile_timestamp();
+       /* Get current TSC low-order bits */
+       __asm__ __volatile__ ( "rdtsc" : "=a" ( low ), "=d" ( discard_d ) );
 
        return low;
 }
diff --git a/roms/ipxe/src/arch/x86/transitions/librm.S b/roms/ipxe/src/arch/x86/transitions/librm.S
deleted file mode 100644 (file)
index e91ede3..0000000
+++ /dev/null
@@ -1,1592 +0,0 @@
-/*
- * librm: a library for interfacing to real-mode code
- *
- * Michael Brown <mbrown@fensystems.co.uk>
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
-
-/* Drag in local definitions */
-#include "librm.h"
-
-/* CR0: protection enabled */
-#define CR0_PE ( 1 << 0 )
-
-/* CR0: paging */
-#define CR0_PG ( 1 << 31 )
-
-/* CR4: physical address extensions */
-#define CR4_PAE ( 1 << 5 )
-
-/* Extended feature enable MSR (EFER) */
-#define MSR_EFER 0xc0000080
-
-/* EFER: long mode enable */
-#define EFER_LME ( 1 << 8 )
-
-/* Page: present */
-#define PG_P 0x01
-
-/* Page: read/write */
-#define PG_RW 0x02
-
-/* Page: user/supervisor */
-#define PG_US 0x04
-
-/* Page: page size */
-#define PG_PS 0x80
-
-/* Size of various paging-related data structures */
-#define SIZEOF_PTE_LOG2 3
-#define SIZEOF_PTE ( 1 << SIZEOF_PTE_LOG2 )
-#define SIZEOF_PT_LOG2 12
-#define SIZEOF_PT ( 1 << SIZEOF_PT_LOG2 )
-#define SIZEOF_4KB_PAGE_LOG2 12
-#define SIZEOF_4KB_PAGE ( 1 << SIZEOF_4KB_PAGE_LOG2 )
-#define SIZEOF_2MB_PAGE_LOG2 21
-#define SIZEOF_2MB_PAGE ( 1 << SIZEOF_2MB_PAGE_LOG2 )
-#define SIZEOF_LOW_4GB_LOG2 32
-#define SIZEOF_LOW_4GB ( 1 << SIZEOF_LOW_4GB_LOG2 )
-
-/* Size of various C data structures */
-#define SIZEOF_I386_SEG_REGS   12
-#define SIZEOF_I386_REGS       32
-#define SIZEOF_REAL_MODE_REGS  ( SIZEOF_I386_SEG_REGS + SIZEOF_I386_REGS )
-#define SIZEOF_I386_FLAGS      4
-#define SIZEOF_I386_ALL_REGS   ( SIZEOF_REAL_MODE_REGS + SIZEOF_I386_FLAGS )
-#define SIZEOF_X86_64_REGS     128
-
-/* Size of an address */
-#ifdef __x86_64__
-#define SIZEOF_ADDR 8
-#else
-#define SIZEOF_ADDR 4
-#endif
-
-/* Default code size */
-#ifdef __x86_64__
-#define CODE_DEFAULT code64
-#else
-#define CODE_DEFAULT code32
-#endif
-
-/* Selectively assemble code for 32-bit/64-bit builds */
-#ifdef __x86_64__
-#define if32 if 0
-#define if64 if 1
-#else
-#define if32 if 1
-#define if64 if 0
-#endif
-
-/****************************************************************************
- * Global descriptor table
- *
- * Call init_librm to set up the GDT before attempting to use any
- * protected-mode code.
- *
- * NOTE: This must be located before prot_to_real, otherwise gas
- * throws a "can't handle non absolute segment in `ljmp'" error due to
- * not knowing the value of REAL_CS when the ljmp is encountered.
- *
- * Note also that putting ".word gdt_end - gdt - 1" directly into
- * gdt_limit, rather than going via gdt_length, will also produce the
- * "non absolute segment" error.  This is most probably a bug in gas.
- ****************************************************************************
- */
-       .section ".data16.gdt", "aw", @progbits
-       .align 16
-gdt:
-gdtr:          /* The first GDT entry is unused, the GDTR can fit here. */
-gdt_limit:             .word gdt_length - 1
-gdt_base:              .long 0
-                       .word 0 /* padding */
-
-       .org    gdt + VIRTUAL_CS, 0
-virtual_cs:    /* 32 bit protected mode code segment, virtual addresses */
-       .word   0xffff, 0
-       .byte   0, 0x9f, 0xcf, 0
-
-       .org    gdt + VIRTUAL_DS, 0
-virtual_ds:    /* 32 bit protected mode data segment, virtual addresses */
-       .word   0xffff, 0
-       .byte   0, 0x93, 0xcf, 0
-       
-       .org    gdt + PHYSICAL_CS, 0
-physical_cs:   /* 32 bit protected mode code segment, physical addresses */
-       .word   0xffff, 0
-       .byte   0, 0x9f, 0xcf, 0
-
-       .org    gdt + PHYSICAL_DS, 0
-physical_ds:   /* 32 bit protected mode data segment, physical addresses */
-       .word   0xffff, 0
-       .byte   0, 0x93, 0xcf, 0        
-
-       .org    gdt + REAL_CS, 0
-real_cs:       /* 16 bit real mode code segment */
-       .word   0xffff, 0
-       .byte   0, 0x9b, 0x00, 0
-
-       .org    gdt + REAL_DS, 0
-real_ds:       /* 16 bit real mode data segment */
-       .word   0xffff, 0
-       .byte   0, 0x93, 0x00, 0
-
-       .org    gdt + P2R_DS, 0
-p2r_ds:                /* 16 bit real mode data segment for prot_to_real transition */
-       .word   0xffff, ( P2R_DS << 4 )
-       .byte   0, 0x93, 0x00, 0
-
-       .org    gdt + LONG_CS, 0
-long_cs:       /* 64 bit long mode code segment */
-       .word   0, 0
-       .byte   0, 0x9a, 0x20, 0
-
-gdt_end:
-       .equ    gdt_length, gdt_end - gdt
-
-/****************************************************************************
- * Stored real-mode and protected-mode stack pointers
- *
- * The real-mode stack pointer is stored here whenever real_to_prot
- * is called and restored whenever prot_to_real is called.  The
- * converse happens for the protected-mode stack pointer.
- *
- * Despite initial appearances this scheme is, in fact re-entrant,
- * because program flow dictates that we always return via the point
- * we left by.  For example:
- *    PXE API call entry
- *  1   real => prot
- *        ...
- *        Print a text string
- *         ...
- *  2       prot => real
- *            INT 10
- *  3       real => prot
- *         ...
- *        ...
- *  4   prot => real
- *    PXE API call exit
- *
- * At point 1, the RM mode stack value, say RPXE, is stored in
- * rm_ss,sp.  We want this value to still be present in rm_ss,sp when
- * we reach point 4.
- *
- * At point 2, the RM stack value is restored from RPXE.  At point 3,
- * the RM stack value is again stored in rm_ss,sp.  This *does*
- * overwrite the RPXE that we have stored there, but it's the same
- * value, since the code between points 2 and 3 has managed to return
- * to us.
- ****************************************************************************
- */
-       .section ".bss.rm_ss_sp", "aw", @nobits
-       .globl rm_sp
-rm_sp: .word 0
-       .globl rm_ss
-rm_ss: .word 0
-
-       .section ".data.pm_esp", "aw", @progbits
-pm_esp:        .long VIRTUAL(_estack)
-
-/****************************************************************************
- * Temporary static data buffer
- *
- * This is used to reduce the amount of real-mode stack space consumed
- * during mode transitions, since we are sometimes called with very
- * little real-mode stack space available.
- ****************************************************************************
- */
-       /* Temporary static buffer usage by virt_call */
-       .struct 0
-VC_TMP_GDT:            .space  6
-VC_TMP_IDT:            .space  6
-VC_TMP_PAD:            .space  4 /* for alignment */
-.if64
-VC_TMP_CR3:            .space  4
-VC_TMP_CR4:            .space  4
-VC_TMP_EMER:           .space  8
-.endif
-VC_TMP_FXSAVE:         .space  512
-VC_TMP_END:
-       .previous
-
-       /* Temporary static buffer usage by real_call */
-       .struct 0
-RC_TMP_FUNCTION:       .space  4
-RC_TMP_END:
-       .previous
-
-       /* Shared temporary static buffer */
-       .section ".bss16.rm_tmpbuf", "aw", @nobits
-       .align 16
-rm_tmpbuf:
-       .space  VC_TMP_END
-       .size   rm_tmpbuf, . - rm_tmpbuf
-
-/****************************************************************************
- * Virtual address offsets
- *
- * These are used by the protected-mode code to map between virtual
- * and physical addresses, and to access variables in the .text16 or
- * .data16 segments.
- ****************************************************************************
- */
-       .struct 0
-VA_VIRT_OFFSET:        .space  SIZEOF_ADDR
-VA_TEXT16:     .space  SIZEOF_ADDR
-VA_DATA16:     .space  SIZEOF_ADDR
-VA_SIZE:
-       .previous
-
-       /* Internal copies, used only by librm itself */
-       .section ".bss16.rm_virt_addrs", "aw", @nobits
-rm_virt_addrs: .space  VA_SIZE
-       .equ    rm_virt_offset, ( rm_virt_addrs + VA_VIRT_OFFSET )
-       .equ    rm_text16, ( rm_virt_addrs + VA_TEXT16 )
-       .equ    rm_data16, ( rm_virt_addrs + VA_DATA16 )
-
-       /* Externally visible variables, used by C code */
-       .section ".bss.virt_addrs", "aw", @nobits
-virt_addrs:    .space  VA_SIZE
-       .globl  virt_offset
-       .equ    virt_offset, ( virt_addrs + VA_VIRT_OFFSET )
-       .globl  text16
-       .equ    text16, ( virt_addrs + VA_TEXT16 )
-       .globl  data16
-       .equ    data16, ( virt_addrs + VA_DATA16 )
-
-/****************************************************************************
- * init_librm (real-mode far call, 16-bit real-mode far return address)
- *
- * Initialise the GDT ready for transitions to protected mode.
- *
- * Parameters:
- *   %cs : .text16 segment
- *   %ds : .data16 segment
- *   %edi : Physical base of protected-mode code
- ****************************************************************************
- */
-       .section ".text16.init_librm", "ax", @progbits
-       .code16
-       .globl init_librm
-init_librm:
-       /* Preserve registers */
-       pushl   %eax
-       pushl   %ebx
-       pushl   %edi
-
-       /* Store rm_virt_offset and set up virtual_cs and virtual_ds segments */
-       subl    $VIRTUAL(_textdata), %edi
-       movl    %edi, rm_virt_offset
-.if64 ;        setae   (rm_virt_offset+4) ; .endif
-       movl    %edi, %eax
-       movw    $virtual_cs, %bx
-       call    set_seg_base
-       movw    $virtual_ds, %bx
-       call    set_seg_base
-
-       /* Store rm_cs and rm_text16, set up real_cs segment */
-       xorl    %eax, %eax
-       movw    %cs, %ax
-       movw    %ax, %cs:rm_cs
-       shll    $4, %eax
-       movw    $real_cs, %bx
-       call    set_seg_base
-.if32 ;        subl    %edi, %eax ; .endif
-       movl    %eax, rm_text16
-
-       /* Store rm_ds and rm_data16, set up real_ds segment and GDT base */
-       xorl    %eax, %eax
-       movw    %ds, %ax
-       movw    %ax, %cs:rm_ds
-       shll    $4, %eax
-       movw    $real_ds, %bx
-       call    set_seg_base
-       movl    %eax, gdt_base
-       addl    $gdt, gdt_base
-.if32 ;        subl    %edi, %eax ; .endif
-       movl    %eax, rm_data16
-
-       /* Configure virt_call for protected mode, if applicable */
-.if64 ;        movl    $VIRTUAL(vc_pmode), %cs:vc_jmp_offset ; .endif
-
-       /* Switch to protected mode */
-       virtcall init_librm_pmode
-       .section ".text.init_librm", "ax", @progbits
-       .code32
-init_librm_pmode:
-
-       /* Store virt_offset, text16, and data16 */
-       pushw   %ds
-       movw    $REAL_DS, %ax
-       movw    %ax, %ds
-       movl    $rm_virt_addrs, %esi
-       movl    $VIRTUAL(virt_addrs), %edi
-       movl    $( VA_SIZE / 4 ), %ecx
-       rep movsl
-       popw    %ds
-
-.if64 ;        /* Initialise long mode, if applicable */
-       movl    VIRTUAL(virt_offset), %edi
-       leal    VIRTUAL(p2l_ljmp_target)(%edi), %eax
-       movl    %eax, VIRTUAL(p2l_ljmp_offset)
-       call    init_pages
-.endif
-       /* Return to real mode */
-       ret
-       .section ".text16.init_librm", "ax", @progbits
-       .code16
-init_librm_rmode:
-
-       /* Configure virt_call for long mode, if applicable */
-.if64 ;        movl    $VIRTUAL(vc_lmode), %cs:vc_jmp_offset ; .endif
-
-       /* Initialise IDT */
-       virtcall init_idt
-
-       /* Restore registers */
-       popl    %edi
-       popl    %ebx
-       popl    %eax
-       lret
-
-       .section ".text16.set_seg_base", "ax", @progbits
-       .code16
-set_seg_base:
-1:     movw    %ax, 2(%bx)
-       rorl    $16, %eax
-       movb    %al, 4(%bx)
-       movb    %ah, 7(%bx)
-       roll    $16, %eax
-       ret
-
-/****************************************************************************
- * real_to_prot (real-mode near call, 32-bit virtual return address)
- *
- * Switch from 16-bit real-mode to 32-bit protected mode with virtual
- * addresses.  The real-mode %ss:sp is stored in rm_ss and rm_sp, and
- * the protected-mode %esp is restored from the saved pm_esp.
- * Interrupts are disabled.  All other registers may be destroyed.
- *
- * The return address for this function should be a 32-bit virtual
- * address.
- *
- * Parameters: 
- *   %ecx : number of bytes to move from RM stack to PM stack
- *   %edx : number of bytes to copy from RM temporary buffer to PM stack
- *
- ****************************************************************************
- */
-       .section ".text16.real_to_prot", "ax", @progbits
-       .code16
-real_to_prot:
-       /* Enable A20 line */
-       call    enable_a20
-       /* A failure at this point is fatal, and there's nothing we
-        * can do about it other than lock the machine to make the
-        * problem immediately visible.
-        */
-1:     jc      1b
-
-       /* Make sure we have our data segment available */
-       movw    %cs:rm_ds, %ds
-
-       /* Add protected-mode return address to length of data to be copied */
-       addw    $4, %cx /* %ecx must be less than 64kB anyway */
-
-       /* Real-mode %ss:%sp => %ebp and virtual address => %esi */
-       xorl    %eax, %eax
-       movw    %ss, %ax
-       shll    $4, %eax
-       movzwl  %sp, %ebp
-       addr32 leal (%eax,%ebp), %esi
-       subl    rm_virt_offset, %esi
-       shll    $12, %eax
-       orl     %eax, %ebp
-
-       /* Real-mode data segment virtual address => %ebx */
-       movl    rm_data16, %ebx
-.if64 ; subl   rm_virt_offset, %ebx ; .endif
-
-       /* Load protected-mode global descriptor table */
-       data32 lgdt gdtr
-
-       /* Zero segment registers.  This wastes around 12 cycles on
-        * real hardware, but saves a substantial number of emulated
-        * instructions under KVM.
-        */
-       xorw    %ax, %ax
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %fs
-       movw    %ax, %gs
-       movw    %ax, %ss
-
-       /* Switch to protected mode (with paging disabled if applicable) */
-       cli
-       movl    %cr0, %eax
-.if64 ;        andl    $~CR0_PG, %eax ; .endif
-       orb     $CR0_PE, %al
-       movl    %eax, %cr0
-       data32 ljmp     $VIRTUAL_CS, $VIRTUAL(r2p_pmode)
-       .section ".text.real_to_prot", "ax", @progbits
-       .code32
-r2p_pmode:
-       /* Set up protected-mode data segments and stack pointer */
-       movw    $VIRTUAL_DS, %ax
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %fs
-       movw    %ax, %gs
-       movw    %ax, %ss
-       movl    VIRTUAL(pm_esp), %esp
-
-       /* Load protected-mode interrupt descriptor table */
-       lidt    VIRTUAL(idtr32)
-
-       /* Record real-mode %ss:sp (after removal of data) */
-       addl    %ecx, %ebp
-       movl    %ebp, VIRTUAL(rm_sp)
-
-       /* Move data from RM stack to PM stack */
-       subl    %edx, %esp
-       subl    %ecx, %esp
-       movl    %esp, %edi
-       rep movsb
-
-       /* Copy data from RM temporary buffer to PM stack */
-       leal    rm_tmpbuf(%ebx), %esi
-       movl    %edx, %ecx
-       rep movsb
-
-       /* Return to virtual address */
-       ret
-
-/****************************************************************************
- * prot_to_real (protected-mode near call, 32-bit real-mode return address)
- *
- * Switch from 32-bit protected mode with virtual addresses to 16-bit
- * real mode.  The protected-mode %esp is stored in pm_esp and the
- * real-mode %ss:sp is restored from the saved rm_ss and rm_sp.  The
- * high word of the real-mode %esp is set to zero.  All real-mode data
- * segment registers are loaded from the saved rm_ds.  Interrupts are
- * *not* enabled, since we want to be able to use prot_to_real in an
- * ISR.  All other registers may be destroyed.
- *
- * The return address for this function should be a 32-bit (sic)
- * real-mode offset within .code16.
- *
- * Parameters: 
- *   %ecx : number of bytes to move from PM stack to RM stack
- *   %edx : number of bytes to move from PM stack to RM temporary buffer
- *   %esi : real-mode global and interrupt descriptor table registers
- *
- ****************************************************************************
- */
-       .section ".text.prot_to_real", "ax", @progbits
-       .code32
-prot_to_real:
-       /* Copy real-mode global descriptor table register to RM code segment */
-       movl    VIRTUAL(text16), %edi
-.if64 ;        subl    VIRTUAL(virt_offset), %edi ; .endif
-       leal    rm_gdtr(%edi), %edi
-       movsw
-       movsl
-
-       /* Load real-mode interrupt descriptor table register */
-       lidt    (%esi)
-
-       /* Add return address to data to be moved to RM stack */
-       addl    $4, %ecx
-
-       /* Real-mode %ss:sp => %ebp and virtual address => %edi */
-       movl    VIRTUAL(rm_sp), %ebp
-       subl    %ecx, %ebp
-       movzwl  VIRTUAL(rm_ss), %eax
-       shll    $4, %eax
-       movzwl  %bp, %edi
-       addl    %eax, %edi
-       subl    VIRTUAL(virt_offset), %edi
-
-       /* Move data from PM stack to RM stack */
-       movl    %esp, %esi
-       rep movsb
-
-       /* Move data from PM stack to RM temporary buffer */
-       movl    VIRTUAL(data16), %edi
-.if64 ;        subl    VIRTUAL(virt_offset), %edi ; .endif
-       addl    $rm_tmpbuf, %edi
-       movl    %edx, %ecx
-       rep movsb
-
-       /* Record protected-mode %esp (after removal of data) */
-       movl    %esi, VIRTUAL(pm_esp)
-
-       /* Load real-mode segment limits */
-       movw    $P2R_DS, %ax
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %fs
-       movw    %ax, %gs
-       movw    %ax, %ss
-       ljmp    $REAL_CS, $p2r_rmode
-       .section ".text16.prot_to_real", "ax", @progbits
-       .code16
-p2r_rmode:
-       /* Load real-mode GDT */
-       data32 lgdt %cs:rm_gdtr
-       /* Switch to real mode */
-       movl    %cr0, %eax
-       andb    $0!CR0_PE, %al
-       movl    %eax, %cr0
-p2r_ljmp_rm_cs:
-       ljmp    $0, $1f
-1:
-       /* Set up real-mode data segments and stack pointer */
-       movw    %cs:rm_ds, %ax
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %fs
-       movw    %ax, %gs
-       movl    %ebp, %eax
-       shrl    $16, %eax
-       movw    %ax, %ss
-       movzwl  %bp, %esp
-
-       /* Return to real-mode address */
-       data32 ret
-
-
-       /* Real-mode code and data segments.  Assigned by the call to
-        * init_librm.  rm_cs doubles as the segment part of the jump
-        * instruction used by prot_to_real.  Both are located in
-        * .text16 rather than .data16: rm_cs since it forms part of
-        * the jump instruction within the code segment, and rm_ds
-        * since real-mode code needs to be able to locate the data
-        * segment with no other reference available.
-        */
-       .globl rm_cs
-       .equ    rm_cs, ( p2r_ljmp_rm_cs + 3 )
-
-       .section ".text16.data.rm_ds", "aw", @progbits
-       .globl rm_ds
-rm_ds: .word 0
-
-       /* Real-mode global and interrupt descriptor table registers */
-       .section ".text16.data.rm_gdtr", "aw", @progbits
-rm_gdtr:
-       .word 0 /* Limit */
-       .long 0 /* Base */
-
-/****************************************************************************
- * phys_to_prot (protected-mode near call, 32-bit physical return address)
- *
- * Switch from 32-bit protected mode with physical addresses to 32-bit
- * protected mode with virtual addresses.  %esp is adjusted to a
- * virtual address.  All other registers are preserved.
- *
- * The return address for this function should be a 32-bit physical
- * (sic) address.
- *
- ****************************************************************************
- */
-       .section ".text.phys_to_prot", "ax", @progbits
-       .code32
-       .globl phys_to_prot
-phys_to_prot:
-       /* Preserve registers */
-       pushl   %eax
-       pushl   %ebp
-
-       /* Switch to virtual code segment */
-       cli
-       ljmp    $VIRTUAL_CS, $VIRTUAL(1f)
-1:
-       /* Switch to virtual data segment and adjust %esp */
-       movw    $VIRTUAL_DS, %ax
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %fs
-       movw    %ax, %gs
-       movw    %ax, %ss
-       movl    VIRTUAL(virt_offset), %ebp
-       subl    %ebp, %esp
-
-       /* Adjust return address to a virtual address */
-       subl    %ebp, 8(%esp)
-
-       /* Restore registers and return */
-       popl    %ebp
-       popl    %eax
-       ret
-
-.if32  /* Expose as _phys_to_virt for use by COMBOOT, if applicable */
-       .globl  _phys_to_virt
-       .equ    _phys_to_virt, phys_to_prot
-.endif
-
-/****************************************************************************
- * prot_to_phys (protected-mode near call, 32-bit virtual return address)
- *
- * Switch from 32-bit protected mode with virtual addresses to 32-bit
- * protected mode with physical addresses.  %esp is adjusted to a
- * physical address.  All other registers are preserved.
- *
- * The return address for this function should be a 32-bit virtual
- * (sic) address.
- *
- ****************************************************************************
- */
-       .section ".text.prot_to_phys", "ax", @progbits
-       .code32
-prot_to_phys:
-       /* Preserve registers */
-       pushl   %eax
-       pushl   %ebp
-
-       /* Adjust return address to a physical address */
-       movl    VIRTUAL(virt_offset), %ebp
-       addl    %ebp, 8(%esp)
-
-       /* Switch to physical code segment */
-       cli
-       pushl   $PHYSICAL_CS
-       leal    VIRTUAL(1f)(%ebp), %eax
-       pushl   %eax
-       lret
-1:
-       /* Switch to physical data segment and adjust %esp */
-       movw    $PHYSICAL_DS, %ax
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %fs
-       movw    %ax, %gs
-       movw    %ax, %ss
-       addl    %ebp, %esp
-
-       /* Restore registers and return */
-       popl    %ebp
-       popl    %eax
-       ret
-
-.if32  /* Expose as _virt_to_phys for use by COMBOOT, if applicable */
-       .globl  _virt_to_phys
-       .equ    _virt_to_phys, prot_to_phys
-.endif
-
-/****************************************************************************
- * intr_to_prot (protected-mode near call, 32-bit virtual return address)
- *
- * Switch from 32-bit protected mode with a virtual code segment and
- * either a physical or virtual stack segment to 32-bit protected mode
- * with normal virtual addresses.  %esp is adjusted if necessary to a
- * virtual address.  All other registers are preserved.
- *
- * The return address for this function should be a 32-bit virtual
- * address.
- *
- ****************************************************************************
- */
-       .section ".text.intr_to_prot", "ax", @progbits
-       .code32
-       .globl intr_to_prot
-intr_to_prot:
-       /* Preserve registers */
-       pushl   %eax
-
-       /* Check whether stack segment is physical or virtual */
-       movw    %ss, %ax
-       cmpw    $VIRTUAL_DS, %ax
-       movw    $VIRTUAL_DS, %ax
-
-       /* Reload data segment registers */
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %fs
-       movw    %ax, %gs
-
-       /* Reload stack segment and adjust %esp if necessary */
-       je      1f
-       movw    %ax, %ss
-       subl    VIRTUAL(virt_offset), %esp
-1:
-       /* Restore registers and return */
-       popl    %eax
-       ret
-
-       /* Expose as _intr_to_virt for use by GDB */
-       .globl  _intr_to_virt
-       .equ    _intr_to_virt, intr_to_prot
-
-/****************************************************************************
- * prot_to_long (protected-mode near call, 32-bit virtual return address)
- *
- * Switch from 32-bit protected mode with virtual addresses to 64-bit
- * long mode.  The protected-mode %esp is adjusted to a physical
- * address.  All other registers are preserved.
- *
- * The return address for this function should be a 32-bit (sic)
- * virtual address.
- *
- ****************************************************************************
- */
-       .if64
-
-       .section ".text.prot_to_long", "ax", @progbits
-       .code32
-prot_to_long:
-       /* Preserve registers */
-       pushl   %eax
-       pushl   %ecx
-       pushl   %edx
-
-       /* Set up PML4 */
-       movl    VIRTUAL(pml4), %eax
-       movl    %eax, %cr3
-
-       /* Enable PAE */
-       movl    %cr4, %eax
-       orb     $CR4_PAE, %al
-       movl    %eax, %cr4
-
-       /* Enable long mode */
-       movl    $MSR_EFER, %ecx
-       rdmsr
-       orw     $EFER_LME, %ax
-       wrmsr
-
-       /* Enable paging */
-       movl    %cr0, %eax
-       orl     $CR0_PG, %eax
-       movl    %eax, %cr0
-
-       /* Restore registers */
-       popl    %edx
-       popl    %ecx
-       popl    %eax
-
-       /* Construct 64-bit return address */
-       pushl   (%esp)
-       movl    $0xffffffff, 4(%esp)
-p2l_ljmp:
-       /* Switch to long mode (using a physical %rip) */
-       ljmp    $LONG_CS, $0
-       .code64
-p2l_lmode:
-       /* Adjust and zero-extend %esp to a physical address */
-       addl    virt_offset, %esp
-
-       /* Use long-mode IDT */
-       lidt    idtr64
-
-       /* Return to virtual address */
-       ret
-
-       /* Long mode jump offset and target.  Required since an ljmp
-        * in protected mode will zero-extend the offset, and so
-        * cannot reach an address within the negative 2GB as used by
-        * -mcmodel=kernel.  Assigned by the call to init_librm.
-        */
-       .equ    p2l_ljmp_offset, ( p2l_ljmp + 1 )
-       .equ    p2l_ljmp_target, p2l_lmode
-
-       .endif
-
-/****************************************************************************
- * long_to_prot (long-mode near call, 64-bit virtual return address)
- *
- * Switch from 64-bit long mode to 32-bit protected mode with virtual
- * addresses.  The long-mode %rsp is adjusted to a virtual address.
- * All other registers are preserved.
- *
- * The return address for this function should be a 64-bit (sic)
- * virtual address.
- *
- ****************************************************************************
- */
-       .if64
-
-       .section ".text.long_to_prot", "ax", @progbits
-       .code64
-long_to_prot:
-       /* Switch to protected mode */
-       ljmp    *l2p_vector
-       .code32
-l2p_pmode:
-       /* Adjust %esp to a virtual address */
-       subl    VIRTUAL(virt_offset), %esp
-
-       /* Preserve registers */
-       pushl   %eax
-       pushl   %ecx
-       pushl   %edx
-
-       /* Disable paging */
-       movl    %cr0, %eax
-       andl    $~CR0_PG, %eax
-       movl    %eax, %cr0
-
-       /* Disable PAE (in case external non-PAE-aware code enables paging) */
-       movl    %cr4, %eax
-       andb    $~CR4_PAE, %al
-       movl    %eax, %cr4
-
-       /* Disable long mode */
-       movl    $MSR_EFER, %ecx
-       rdmsr
-       andw    $~EFER_LME, %ax
-       wrmsr
-
-       /* Restore registers */
-       popl    %edx
-       popl    %ecx
-       popl    %eax
-
-       /* Use protected-mode IDT */
-       lidt    VIRTUAL(idtr32)
-
-       /* Return */
-       ret     $4
-
-       /* Long mode jump vector.  Required since there is no "ljmp
-        * immediate" instruction in long mode.
-        */
-       .section ".data.l2p_vector", "aw", @progbits
-l2p_vector:
-       .long   VIRTUAL(l2p_pmode), VIRTUAL_CS
-
-       .endif
-
-/****************************************************************************
- * long_save_regs (long-mode near call, 64-bit virtual return address)
- *
- * Preserve registers that are accessible only in long mode.  This
- * includes %r8-%r15 and the upper halves of %rax, %rbx, %rcx, %rdx,
- * %rsi, %rdi, and %rbp.
- *
- ****************************************************************************
- */
-       .if64
-
-       .section ".text.long_preserve_regs", "ax", @progbits
-       .code64
-long_preserve_regs:
-       /* Preserve registers */
-       pushq   %rax
-       pushq   %rcx
-       pushq   %rdx
-       pushq   %rbx
-       pushq   %rsp
-       pushq   %rbp
-       pushq   %rsi
-       pushq   %rdi
-       pushq   %r8
-       pushq   %r9
-       pushq   %r10
-       pushq   %r11
-       pushq   %r12
-       pushq   %r13
-       pushq   %r14
-       pushq   %r15
-
-       /* Return */
-       jmp     *SIZEOF_X86_64_REGS(%rsp)
-
-       .endif
-
-/****************************************************************************
- * long_restore_regs (long-mode near call, 64-bit virtual return address)
- *
- * Restore registers that are accessible only in long mode.  This
- * includes %r8-%r15 and the upper halves of %rax, %rbx, %rcx, %rdx,
- * %rsi, %rdi, and %rbp.
- *
- ****************************************************************************
- */
-       .if64
-
-       .section ".text.long_restore_regs", "ax", @progbits
-       .code64
-long_restore_regs:
-       /* Move return address above register dump */
-       popq    SIZEOF_X86_64_REGS(%rsp)
-
-       /* Restore registers */
-       popq    %r15
-       popq    %r14
-       popq    %r13
-       popq    %r12
-       popq    %r11
-       popq    %r10
-       popq    %r9
-       popq    %r8
-       movl    %edi, (%rsp)
-       popq    %rdi
-       movl    %esi, (%rsp)
-       popq    %rsi
-       movl    %ebp, (%rsp)
-       popq    %rbp
-       leaq    8(%rsp), %rsp /* discard */
-       movl    %ebx, (%rsp)
-       popq    %rbx
-       movl    %edx, (%rsp)
-       popq    %rdx
-       movl    %ecx, (%rsp)
-       popq    %rcx
-       movl    %eax, (%rsp)
-       popq    %rax
-
-       /* Return */
-       ret
-
-       .endif
-
-/****************************************************************************
- * virt_call (real-mode near call, 16-bit real-mode near return address)
- *
- * Call a specific C function in 32-bit protected mode or 64-bit long
- * mode (as applicable).  The prototype of the C function must be
- *   void function ( struct i386_all_regs *ix86 ); 
- * ix86 will point to a struct containing the real-mode registers
- * at entry to virt_call().
- *
- * All registers will be preserved across virt_call(), unless the C
- * function explicitly overwrites values in ix86.  Interrupt status
- * and GDT will also be preserved.  Gate A20 will be enabled.
- *
- * Note that virt_call() does not rely on the real-mode stack
- * remaining intact in order to return, since everything relevant is
- * copied to the protected-mode stack for the duration of the call.
- * In particular, this means that a real-mode prefix can make a call
- * to main() which will return correctly even if the prefix's stack
- * gets vapourised during the Etherboot run.  (The prefix cannot rely
- * on anything else on the stack being preserved, so should move any
- * critical data to registers before calling main()).
- *
- * Parameters:
- *   function : 32-bit virtual address of function to call
- *
- * Example usage:
- *     pushl   $pxe_api_call
- *     call    virt_call
- * to call in to the C function
- *      void pxe_api_call ( struct i386_all_regs *ix86 );
- ****************************************************************************
- */
-       .struct 0
-VC_OFFSET_IX86:                .space  SIZEOF_I386_ALL_REGS
-VC_OFFSET_PADDING:     .space  2 /* for alignment */
-VC_OFFSET_RETADDR:     .space  2
-VC_OFFSET_PARAMS:
-VC_OFFSET_FUNCTION:    .space  4
-VC_OFFSET_END:
-       .previous
-
-       .section ".text16.virt_call", "ax", @progbits
-       .code16
-       .globl virt_call
-virt_call:
-       /* Preserve registers and flags on external RM stack */
-       pushw   %ss /* padding */
-       pushfl
-       pushal
-       pushw   %gs
-       pushw   %fs
-       pushw   %es
-       pushw   %ds
-       pushw   %ss
-       pushw   %cs
-
-       /* Claim ownership of temporary static buffer */
-       cli
-
-       /* Preserve FPU, MMX and SSE state in temporary static buffer */
-       movw    %cs:rm_ds, %ds
-       fxsave  ( rm_tmpbuf + VC_TMP_FXSAVE )
-
-       /* Preserve GDT and IDT in temporary static buffer */
-       sidt    ( rm_tmpbuf + VC_TMP_IDT )
-       sgdt    ( rm_tmpbuf + VC_TMP_GDT )
-
-.if64 ;        /* Preserve control registers, if applicable */
-       movl    $MSR_EFER, %ecx
-       rdmsr
-       movl    %eax, ( rm_tmpbuf + VC_TMP_EMER + 0 )
-       movl    %edx, ( rm_tmpbuf + VC_TMP_EMER + 4 )
-       movl    %cr4, %eax
-       movl    %eax, ( rm_tmpbuf + VC_TMP_CR4 )
-       movl    %cr3, %eax
-       movl    %eax, ( rm_tmpbuf + VC_TMP_CR3 )
-.endif
-       /* For sanity's sake, clear the direction flag as soon as possible */
-       cld
-
-       /* Switch to protected mode and move register dump to PM stack */
-       movl    $VC_OFFSET_END, %ecx
-       movl    $VC_TMP_END, %edx
-       pushl   $VIRTUAL(vc_pmode)
-vc_jmp:        jmp     real_to_prot
-       .section ".text.virt_call", "ax", @progbits
-       .code32
-vc_pmode:
-       /* Call function (in protected mode) */
-       pushl   %esp
-       call    *(VC_OFFSET_FUNCTION+4)(%esp)
-       popl    %eax /* discard */
-
-.if64 ; /* Switch to long mode */
-       jmp     1f
-vc_lmode:
-       call    prot_to_long
-       .code64
-
-       /* Call function (in long mode) */
-       movq    %rsp, %rdi
-       movslq  VC_OFFSET_FUNCTION(%rsp), %rax
-       callq   *%rax
-
-       /* Switch to protected mode */
-       call    long_to_prot
-1:     .code32
-.endif
-       /* Switch to real mode and move register dump back to RM stack */
-       movl    $VC_OFFSET_END, %ecx
-       movl    $VC_TMP_END, %edx
-       leal    VC_TMP_GDT(%esp, %ecx), %esi
-       pushl   $vc_rmode
-       jmp     prot_to_real
-       .section ".text16.virt_call", "ax", @progbits
-       .code16
-vc_rmode:
-.if64 ;        /* Restore control registers, if applicable */
-       movw    %sp, %bp
-       movl    ( rm_tmpbuf + VC_TMP_CR3 ), %eax
-       movl    %eax, %cr3
-       movl    ( rm_tmpbuf + VC_TMP_CR4 ), %eax
-       movl    %eax, %cr4
-       movl    ( rm_tmpbuf + VC_TMP_EMER + 0 ), %eax
-       movl    ( rm_tmpbuf + VC_TMP_EMER + 4 ), %edx
-       movl    $MSR_EFER, %ecx
-       wrmsr
-.endif
-       /* Restore FPU, MMX and SSE state from temporary static buffer */
-       fxrstor ( rm_tmpbuf + VC_TMP_FXSAVE )
-
-       /* Restore registers and flags and return */
-       popl    %eax /* skip %cs and %ss */
-       popw    %ds
-       popw    %es
-       popw    %fs
-       popw    %gs
-       popal
-       /* popal skips %esp.  We therefore want to do "movl -20(%sp),
-        * %esp", but -20(%sp) is not a valid 80386 expression.
-        * Fortunately, prot_to_real() zeroes the high word of %esp, so
-        * we can just use -20(%esp) instead.
-        */
-       addr32 movl -20(%esp), %esp
-       popfl
-       popw    %ss /* padding */
-
-       /* Return and discard function parameters */
-       ret     $( VC_OFFSET_END - VC_OFFSET_PARAMS )
-
-
-       /* Protected-mode jump target */
-       .equ    vc_jmp_offset, ( vc_jmp - 4 )
-
-/****************************************************************************
- * real_call (protected-mode near call, 32-bit virtual return address)
- * real_call (long-mode near call, 64-bit virtual return address)
- *
- * Call a real-mode function from protected-mode or long-mode code.
- *
- * The non-segment register values will be passed directly to the
- * real-mode code.  The segment registers will be set as per
- * prot_to_real.  The non-segment register values set by the real-mode
- * function will be passed back to the protected-mode or long-mode
- * caller.  A result of this is that this routine cannot be called
- * directly from C code, since it clobbers registers that the C ABI
- * expects the callee to preserve.
- *
- * librm.h defines a convenient macro REAL_CODE() for using real_call.
- * See librm.h and realmode.h for details and examples.
- *
- * Parameters:
- *   function : offset within .text16 of real-mode function to call
- *
- * Returns: none
- ****************************************************************************
- */
-       .struct 0
-RC_OFFSET_REGS:                .space  SIZEOF_I386_REGS
-RC_OFFSET_REGS_END:
-RC_OFFSET_FUNCTION_COPY:.space 4
-.if64
-RC_OFFSET_LREGS:       .space  SIZEOF_X86_64_REGS
-RC_OFFSET_LREG_RETADDR:        .space  SIZEOF_ADDR
-.endif
-RC_OFFSET_RETADDR:     .space  SIZEOF_ADDR
-RC_OFFSET_PARAMS:
-RC_OFFSET_FUNCTION:    .space  SIZEOF_ADDR
-RC_OFFSET_END:
-       .previous
-
-       .section ".text.real_call", "ax", @progbits
-       .CODE_DEFAULT
-       .globl real_call
-real_call:
-.if64 ;        /* Preserve registers and switch to protected mode, if applicable */
-       call    long_preserve_regs
-       call    long_to_prot
-       .code32
-.endif
-       /* Create register dump and function pointer copy on PM stack */
-       pushl   ( RC_OFFSET_FUNCTION - RC_OFFSET_FUNCTION_COPY - 4 )(%esp)
-       pushal
-
-       /* Switch to real mode and move register dump to RM stack  */
-       movl    $RC_OFFSET_REGS_END, %ecx
-       movl    $RC_TMP_END, %edx
-       pushl   $rc_rmode
-       movl    $VIRTUAL(rm_default_gdtr_idtr), %esi
-       jmp     prot_to_real
-       .section ".text16.real_call", "ax", @progbits
-       .code16
-rc_rmode:
-       /* Call real-mode function */
-       popal
-       call    *( rm_tmpbuf + RC_TMP_FUNCTION )
-       pushal
-
-       /* For sanity's sake, clear the direction flag as soon as possible */
-       cld
-
-       /* Switch to protected mode and move register dump back to PM stack */
-       movl    $RC_OFFSET_REGS_END, %ecx
-       xorl    %edx, %edx
-       pushl   $VIRTUAL(rc_pmode)
-       jmp     real_to_prot
-       .section ".text.real_call", "ax", @progbits
-       .code32
-rc_pmode:
-       /* Restore registers */
-       popal
-
-.if64 ; /* Switch to long mode and restore registers, if applicable */
-       call    prot_to_long
-       .code64
-       call    long_restore_regs
-.endif
-       /* Return and discard function parameters */
-       ret     $( RC_OFFSET_END - RC_OFFSET_PARAMS )
-
-
-       /* Default real-mode global and interrupt descriptor table registers */
-       .section ".data.rm_default_gdtr_idtr", "aw", @progbits
-rm_default_gdtr_idtr:
-       .word 0         /* Global descriptor table limit */
-       .long 0         /* Global descriptor table base */
-       .word 0x03ff    /* Interrupt descriptor table limit */
-       .long 0         /* Interrupt descriptor table base */
-
-/****************************************************************************
- * phys_call (protected-mode near call, 32-bit virtual return address)
- * phys_call (long-mode near call, 64-bit virtual return address)
- *
- * Call a function with flat 32-bit physical addressing
- *
- * The non-segment register values will be passed directly to the
- * function.  The segment registers will be set for flat 32-bit
- * physical addressing.  The non-segment register values set by the
- * function will be passed back to the caller.
- *
- * librm.h defines a convenient macro PHYS_CODE() for using phys_call.
- *
- * Parameters:
- *   function : virtual (sic) address of function to call
- *
- ****************************************************************************
- */
-       .struct 0
-.if64
-PHC_OFFSET_LREGS:      .space  SIZEOF_X86_64_REGS
-PHC_OFFSET_LREG_RETADDR:.space SIZEOF_ADDR
-.endif
-PHC_OFFSET_RETADDR:    .space  SIZEOF_ADDR
-PHC_OFFSET_PARAMS:
-PHC_OFFSET_FUNCTION:   .space  SIZEOF_ADDR
-PHC_OFFSET_END:
-       .previous
-
-       .section ".text.phys_call", "ax", @progbits
-       .CODE_DEFAULT
-       .globl phys_call
-phys_call:
-.if64 ;        /* Preserve registers and switch to protected mode, if applicable */
-       call    long_preserve_regs
-       call    long_to_prot
-       .code32
-.endif
-       /* Adjust function pointer to a physical address */
-       pushl   %ebp
-       movl    VIRTUAL(virt_offset), %ebp
-       addl    %ebp, ( PHC_OFFSET_FUNCTION + 4 /* saved %ebp */ )(%esp)
-       popl    %ebp
-
-       /* Switch to physical addresses */
-       call    prot_to_phys
-
-       /* Call function */
-       call    *PHC_OFFSET_FUNCTION(%esp)
-
-       /* For sanity's sake, clear the direction flag as soon as possible */
-       cld
-
-       /* Switch to virtual addresses */
-       call    phys_to_prot
-
-.if64 ; /* Switch to long mode and restore registers, if applicable */
-       call    prot_to_long
-       .code64
-       call    long_restore_regs
-.endif
-       /* Return and discard function parameters */
-       ret     $( PHC_OFFSET_END - PHC_OFFSET_PARAMS )
-
-/****************************************************************************
- * phys_to_long (protected-mode near call, 32-bit physical return address)
- *
- * Used by COMBOOT.
- *
- ****************************************************************************
- */
-       .if64
-
-       .section ".text.phys_to_long", "ax", @progbits
-       .code32
-phys_to_long:
-
-       /* Switch to virtual addresses */
-       call    phys_to_prot
-
-       /* Convert to 32-bit virtual return address */
-       pushl   %eax
-       movl    VIRTUAL(virt_offset), %eax
-       subl    %eax, 4(%esp)
-       popl    %eax
-
-       /* Switch to long mode and return */
-       jmp     prot_to_long
-
-       /* Expose as _phys_to_virt for use by COMBOOT */
-       .globl  _phys_to_virt
-       .equ    _phys_to_virt, phys_to_long
-
-       .endif
-
-/****************************************************************************
- * long_to_phys (long-mode near call, 64-bit virtual return address)
- *
- * Used by COMBOOT.
- *
- ****************************************************************************
- */
-       .if64
-
-       .section ".text.long_to_phys", "ax", @progbits
-       .code64
-long_to_phys:
-
-       /* Switch to protected mode */
-       call    long_to_prot
-       .code32
-
-       /* Convert to 32-bit virtual return address */
-       popl    (%esp)
-
-       /* Switch to physical addresses and return */
-       jmp     prot_to_phys
-
-       /* Expose as _virt_to_phys for use by COMBOOT */
-       .globl  _virt_to_phys
-       .equ    _virt_to_phys, long_to_phys
-
-       .endif
-
-/****************************************************************************
- * flatten_real_mode (real-mode near call)
- *
- * Switch to flat real mode
- *
- ****************************************************************************
- */
-       .section ".text16.flatten_real_mode", "ax", @progbits
-       .code16
-       .globl flatten_real_mode
-flatten_real_mode:
-       /* Modify GDT to use flat real mode */
-       movb    $0x8f, real_cs + 6
-       movb    $0x8f, real_ds + 6
-       /* Call dummy protected-mode function */
-       virtcall flatten_dummy
-       /* Restore GDT */
-       movb    $0x00, real_cs + 6
-       movb    $0x00, real_ds + 6
-       /* Return */
-       ret
-
-       .section ".text.flatten_dummy", "ax", @progbits
-       .CODE_DEFAULT
-flatten_dummy:
-       ret
-
-/****************************************************************************
- * Interrupt wrapper
- *
- * Used by the protected-mode and long-mode interrupt vectors to call
- * the interrupt() function.
- *
- * May be entered with either physical or virtual stack segment.
- ****************************************************************************
- */
-       .section ".text.interrupt_wrapper", "ax", @progbits
-       .code32
-       .globl interrupt_wrapper
-interrupt_wrapper:
-       /* Preserve registers (excluding already-saved %eax and
-        * otherwise unused registers which are callee-save for both
-        * 32-bit and 64-bit ABIs).
-        */
-       pushl   %ebx
-       pushl   %ecx
-       pushl   %edx
-       pushl   %esi
-       pushl   %edi
-
-       /* Expand IRQ number to whole %eax register */
-       movzbl  %al, %eax
-
-.if64 ; /* Skip transition to long mode, if applicable */
-       movw    %cs, %bx
-       cmpw    $LONG_CS, %bx
-       je      1f
-.endif
-       /* Preserve segment registers and original %esp */
-       pushl   %ds
-       pushl   %es
-       pushl   %fs
-       pushl   %gs
-       pushl   %ss
-       pushl   %esp
-
-       /* Switch to virtual addressing */
-       call    intr_to_prot
-.if64
-       /* Switch to long mode */
-       call    prot_to_long
-       .code64
-
-1:     /* Preserve long-mode caller-save registers */
-       pushq   %r8
-       pushq   %r9
-       pushq   %r10
-       pushq   %r11
-
-       /* Expand IRQ number to whole %rdi register */
-       movl    %eax, %edi
-.endif
-       /* Call interrupt handler */
-       call    interrupt
-.if64
-       /* Restore long-mode caller-save registers */
-       popq    %r11
-       popq    %r10
-       popq    %r9
-       popq    %r8
-
-       /* Skip transition back to protected mode, if applicable */
-       cmpw    $LONG_CS, %bx
-       je      1f
-
-       /* Switch to protected mode */
-       call    long_to_prot
-       .code32
-       cmpw    $LONG_CS, %bx
-.endif
-       /* Restore segment registers and original %esp */
-       lss     (%esp), %esp
-       popl    %ss
-       popl    %gs
-       popl    %fs
-       popl    %es
-       popl    %ds
-
-1:     /* Restore registers */
-       popl    %edi
-       popl    %esi
-       popl    %edx
-       popl    %ecx
-       popl    %ebx
-       popl    %eax
-
-       /* Return from interrupt (with REX prefix if required) */
-.if64 ; jne 1f ; .byte 0x48 ; .endif
-1:     iret
-
-/****************************************************************************
- * Page tables
- *
- ****************************************************************************
- */
-       .section ".pages", "aw", @nobits
-       .align  SIZEOF_PT
-
-       /* Page map level 4 entries (PML4Es)
-        *
-        * This comprises
-        *
-        * - PML4E[0x000] covering [0x0000000000000000-0x0000007fffffffff]
-        * - PML4E[0x1ff] covering [0xffffff8000000000-0xffffffffffffffff]
-        *
-        * These point to the PDPT.  This creates some aliased
-        * addresses within unused portions of the 64-bit address
-        * space, but allows us to use just a single PDPT.
-        *
-        * - PDE[...] covering arbitrary 2MB portions of I/O space
-        *
-        * These are 2MB pages created by ioremap() to cover I/O
-        * device addresses.
-        */
-pml4e:
-       .space  SIZEOF_PT
-       .size   pml4e, . - pml4e
-
-       .globl  io_pages
-       .equ    io_pages, pml4e
-
-       /* Page directory pointer table entries (PDPTEs)
-        *
-        * This comprises:
-        *
-        * - PDPTE[0x000] covering [0x0000000000000000-0x000000003fffffff]
-        * - PDPTE[0x001] covering [0x0000000040000000-0x000000007fffffff]
-        * - PDPTE[0x002] covering [0x0000000080000000-0x00000000bfffffff]
-        * - PDPTE[0x003] covering [0x00000000c0000000-0x00000000ffffffff]
-        *
-        * These point to the appropriate page directories (in pde_low)
-        * used to identity-map the whole of the 32-bit address space.
-        *
-        * - PDPTE[0x004] covering [0x0000000100000000-0x000000013fffffff]
-        *
-        * This points back to the PML4, allowing the PML4 to be
-        * (ab)used to hold 2MB pages used for I/O device addresses.
-        *
-        * - PDPTE[0x1ff] covering [0xffffffffc0000000-0xffffffffffffffff]
-        *
-        * This points back to the PDPT itself, allowing the PDPT to be
-        * (ab)used to hold PDEs covering .textdata.
-        *
-        * - PDE[N-M] covering [_textdata,_end)
-        *
-        * These are used to point to the page tables (in pte_textdata)
-        * used to map our .textdata section.  Note that each PDE
-        * covers 2MB, so we are likely to use only a single PDE in
-        * practice.
-        */
-pdpte:
-       .space  SIZEOF_PT
-       .size   pdpte, . - pdpte
-       .equ    pde_textdata, pdpte /* (ab)use */
-
-       /* Page directory entries (PDEs) for the low 4GB
-        *
-        * This comprises 2048 2MB pages to identity-map the whole of
-        * the 32-bit address space.
-        */
-pde_low:
-       .equ    PDE_LOW_PTES, ( SIZEOF_LOW_4GB / SIZEOF_2MB_PAGE )
-       .equ    PDE_LOW_PTS, ( ( PDE_LOW_PTES * SIZEOF_PTE ) / SIZEOF_PT )
-       .space  ( PDE_LOW_PTS * SIZEOF_PT )
-       .size   pde_low, . - pde_low
-
-       /* Page table entries (PTEs) for .textdata
-        *
-        * This comprises enough 4kB pages to map the whole of
-        * .textdata.  The required number of PTEs is calculated by
-        * the linker script.
-        *
-        * Note that these mappings do not cover the PTEs themselves.
-        * This does not matter, since code running with paging
-        * enabled never needs to access these PTEs.
-        */
-pte_textdata:
-       /* Allocated by linker script; must be at the end of .textdata */
-
-       .section ".bss.pml4", "aw", @nobits
-pml4:  .long   0
-
-/****************************************************************************
- * init_pages (protected-mode near call)
- *
- * Initialise the page tables ready for long mode.
- *
- * Parameters:
- *   %edi : virt_offset
- ****************************************************************************
- */
-       .section ".text.init_pages", "ax", @progbits
-       .code32
-init_pages:
-       /* Initialise PML4Es for low 4GB and negative 2GB */
-       leal    ( VIRTUAL(pdpte) + ( PG_P | PG_RW | PG_US ) )(%edi), %eax
-       movl    %eax, VIRTUAL(pml4e)
-       movl    %eax, ( VIRTUAL(pml4e) + SIZEOF_PT - SIZEOF_PTE )
-
-       /* Initialise PDPTE for negative 1GB */
-       movl    %eax, ( VIRTUAL(pdpte) + SIZEOF_PT - SIZEOF_PTE )
-
-       /* Initialise PDPTE for I/O space */
-       leal    ( VIRTUAL(pml4e) + ( PG_P | PG_RW | PG_US ) )(%edi), %eax
-       movl    %eax, ( VIRTUAL(pdpte) + ( PDE_LOW_PTS * SIZEOF_PTE ) )
-
-       /* Initialise PDPTEs for low 4GB */
-       movl    $PDE_LOW_PTS, %ecx
-       leal    ( VIRTUAL(pde_low) + ( PDE_LOW_PTS * SIZEOF_PT ) + \
-                 ( PG_P | PG_RW | PG_US ) )(%edi), %eax
-1:     subl    $SIZEOF_PT, %eax
-       movl    %eax, ( VIRTUAL(pdpte) - SIZEOF_PTE )(,%ecx,SIZEOF_PTE)
-       loop    1b
-
-       /* Initialise PDEs for low 4GB */
-       movl    $PDE_LOW_PTES, %ecx
-       leal    ( 0 + ( PG_P | PG_RW | PG_US | PG_PS ) ), %eax
-1:     subl    $SIZEOF_2MB_PAGE, %eax
-       movl    %eax, ( VIRTUAL(pde_low) - SIZEOF_PTE )(,%ecx,SIZEOF_PTE)
-       loop    1b
-
-       /* Initialise PDEs for .textdata */
-       movl    $_textdata_pdes, %ecx
-       leal    ( VIRTUAL(_etextdata) + ( PG_P | PG_RW | PG_US ) )(%edi), %eax
-       movl    $VIRTUAL(_textdata), %ebx
-       shrl    $( SIZEOF_2MB_PAGE_LOG2 - SIZEOF_PTE_LOG2 ), %ebx
-       andl    $( SIZEOF_PT - 1 ), %ebx
-1:     subl    $SIZEOF_PT, %eax
-       movl    %eax, (VIRTUAL(pde_textdata) - SIZEOF_PTE)(%ebx,%ecx,SIZEOF_PTE)
-       loop    1b
-
-       /* Initialise PTEs for .textdata */
-       movl    $_textdata_ptes, %ecx
-       leal    ( VIRTUAL(_textdata) + ( PG_P | PG_RW | PG_US ) )(%edi), %eax
-       addl    $_textdata_paged_len, %eax
-1:     subl    $SIZEOF_4KB_PAGE, %eax
-       movl    %eax, ( VIRTUAL(pte_textdata) - SIZEOF_PTE )(,%ecx,SIZEOF_PTE)
-       loop    1b
-
-       /* Record PML4 physical address */
-       leal    VIRTUAL(pml4e)(%edi), %eax
-       movl    %eax, VIRTUAL(pml4)
-
-       /* Return */
-       ret
diff --git a/roms/ipxe/src/arch/x86/transitions/librm_mgmt.c b/roms/ipxe/src/arch/x86/transitions/librm_mgmt.c
deleted file mode 100644 (file)
index 8776f28..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * librm: a library for interfacing to real-mode code
- *
- * Michael Brown <mbrown@fensystems.co.uk>
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <strings.h>
-#include <assert.h>
-#include <ipxe/profile.h>
-#include <realmode.h>
-#include <pic8259.h>
-
-/*
- * This file provides functions for managing librm.
- *
- */
-
-/** The interrupt wrapper */
-extern char interrupt_wrapper[];
-
-/** The interrupt vectors */
-static struct interrupt_vector intr_vec[NUM_INT];
-
-/** The 32-bit interrupt descriptor table */
-static struct interrupt32_descriptor
-idt32[NUM_INT] __attribute__ (( aligned ( 16 ) ));
-
-/** The 32-bit interrupt descriptor table register */
-struct idtr32 idtr32 = {
-       .limit = ( sizeof ( idt32 ) - 1 ),
-};
-
-/** The 64-bit interrupt descriptor table */
-static struct interrupt64_descriptor
-idt64[NUM_INT] __attribute__ (( aligned ( 16 ) ));
-
-/** The interrupt descriptor table register */
-struct idtr64 idtr64 = {
-       .limit = ( sizeof ( idt64 ) - 1 ),
-};
-
-/** Timer interrupt profiler */
-static struct profiler timer_irq_profiler __profiler = { .name = "irq.timer" };
-
-/** Other interrupt profiler */
-static struct profiler other_irq_profiler __profiler = { .name = "irq.other" };
-
-/**
- * Allocate space on the real-mode stack and copy data there from a
- * user buffer
- *
- * @v data             User buffer
- * @v size             Size of stack data
- * @ret sp             New value of real-mode stack pointer
- */
-uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size ) {
-       userptr_t rm_stack;
-       rm_sp -= size;
-       rm_stack = real_to_user ( rm_ss, rm_sp );
-       memcpy_user ( rm_stack, 0, data, 0, size );
-       return rm_sp;
-};
-
-/**
- * Deallocate space on the real-mode stack, optionally copying back
- * data to a user buffer.
- *
- * @v data             User buffer
- * @v size             Size of stack data
- */
-void remove_user_from_rm_stack ( userptr_t data, size_t size ) {
-       if ( data ) {
-               userptr_t rm_stack = real_to_user ( rm_ss, rm_sp );
-               memcpy_user ( rm_stack, 0, data, 0, size );
-       }
-       rm_sp += size;
-};
-
-/**
- * Set interrupt vector
- *
- * @v intr             Interrupt number
- * @v vector           Interrupt vector, or NULL to disable
- */
-void set_interrupt_vector ( unsigned int intr, void *vector ) {
-       struct interrupt32_descriptor *idte32;
-       struct interrupt64_descriptor *idte64;
-       intptr_t addr = ( ( intptr_t ) vector );
-
-       /* Populate 32-bit interrupt descriptor */
-       idte32 = &idt32[intr];
-       idte32->segment = VIRTUAL_CS;
-       idte32->attr = ( vector ? ( IDTE_PRESENT | IDTE_TYPE_IRQ32 ) : 0 );
-       idte32->low = ( addr >> 0 );
-       idte32->high = ( addr >> 16 );
-
-       /* Populate 64-bit interrupt descriptor, if applicable */
-       if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) {
-               idte64 = &idt64[intr];
-               idte64->segment = LONG_CS;
-               idte64->attr = ( vector ?
-                                ( IDTE_PRESENT | IDTE_TYPE_IRQ64 ) : 0 );
-               idte64->low = ( addr >> 0 );
-               idte64->mid = ( addr >> 16 );
-               idte64->high = ( ( ( uint64_t ) addr ) >> 32 );
-       }
-}
-
-/**
- * Initialise interrupt descriptor table
- *
- */
-void init_idt ( void ) {
-       struct interrupt_vector *vec;
-       unsigned int intr;
-
-       /* Initialise the interrupt descriptor table and interrupt vectors */
-       for ( intr = 0 ; intr < NUM_INT ; intr++ ) {
-               vec = &intr_vec[intr];
-               vec->push = PUSH_INSN;
-               vec->movb = MOVB_INSN;
-               vec->intr = intr;
-               vec->jmp = JMP_INSN;
-               vec->offset = ( ( intptr_t ) interrupt_wrapper -
-                               ( intptr_t ) vec->next );
-               set_interrupt_vector ( intr, vec );
-       }
-       DBGC ( &intr_vec[0], "INTn vector at %p+%zxn (phys %#lx+%zxn)\n",
-              intr_vec, sizeof ( intr_vec[0] ),
-              virt_to_phys ( intr_vec ), sizeof ( intr_vec[0] ) );
-
-       /* Initialise the 32-bit interrupt descriptor table register */
-       idtr32.base = virt_to_phys ( idt32 );
-
-       /* Initialise the 64-bit interrupt descriptor table register,
-        * if applicable.
-        */
-       if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) )
-               idtr64.base = virt_to_phys ( idt64 );
-}
-
-/**
- * Determine interrupt profiler (for debugging)
- *
- * @v intr             Interrupt number
- * @ret profiler       Profiler
- */
-static struct profiler * interrupt_profiler ( int intr ) {
-
-       switch ( intr ) {
-       case IRQ_INT ( 0 ) :
-               return &timer_irq_profiler;
-       default:
-               return &other_irq_profiler;
-       }
-}
-
-/**
- * Interrupt handler
- *
- * @v intr             Interrupt number
- */
-void __attribute__ (( regparm ( 1 ) )) interrupt ( int intr ) {
-       struct profiler *profiler = interrupt_profiler ( intr );
-       uint32_t discard_eax;
-
-       /* Reissue interrupt in real mode */
-       profile_start ( profiler );
-       __asm__ __volatile__ ( REAL_CODE ( "movb %%al, %%cs:(1f + 1)\n\t"
-                                          "\n1:\n\t"
-                                          "int $0x00\n\t" )
-                              : "=a" ( discard_eax ) : "0" ( intr ) );
-       profile_stop ( profiler );
-       profile_exclude ( profiler );
-}
-
-/**
- * Map pages for I/O
- *
- * @v bus_addr         Bus address
- * @v len              Length of region
- * @ret io_addr                I/O address
- */
-static void * ioremap_pages ( unsigned long bus_addr, size_t len ) {
-       unsigned long start;
-       unsigned int count;
-       unsigned int stride;
-       unsigned int first;
-       unsigned int i;
-       size_t offset;
-       void *io_addr;
-
-       DBGC ( &io_pages, "IO mapping %08lx+%zx\n", bus_addr, len );
-
-       /* Sanity check */
-       assert ( len != 0 );
-
-       /* Round down start address to a page boundary */
-       start = ( bus_addr & ~( IO_PAGE_SIZE - 1 ) );
-       offset = ( bus_addr - start );
-       assert ( offset < IO_PAGE_SIZE );
-
-       /* Calculate number of pages required */
-       count = ( ( offset + len + IO_PAGE_SIZE - 1 ) / IO_PAGE_SIZE );
-       assert ( count != 0 );
-       assert ( count < ( sizeof ( io_pages.page ) /
-                          sizeof ( io_pages.page[0] ) ) );
-
-       /* Round up number of pages to a power of two */
-       stride = ( 1 << ( fls ( count ) - 1 ) );
-       assert ( count <= stride );
-
-       /* Allocate pages */
-       for ( first = 0 ; first < ( sizeof ( io_pages.page ) /
-                                   sizeof ( io_pages.page[0] ) ) ;
-             first += stride ) {
-
-               /* Calculate I/O address */
-               io_addr = ( IO_BASE + ( first * IO_PAGE_SIZE ) + offset );
-
-               /* Check that page table entries are available */
-               for ( i = first ; i < ( first + count ) ; i++ ) {
-                       if ( io_pages.page[i] & PAGE_P ) {
-                               io_addr = NULL;
-                               break;
-                       }
-               }
-               if ( ! io_addr )
-                       continue;
-
-               /* Create page table entries */
-               for ( i = first ; i < ( first + count ) ; i++ ) {
-                       io_pages.page[i] = ( start | PAGE_P | PAGE_RW |
-                                            PAGE_US | PAGE_PWT | PAGE_PCD |
-                                            PAGE_PS );
-                       start += IO_PAGE_SIZE;
-               }
-
-               /* Mark last page as being the last in this allocation */
-               io_pages.page[ i - 1 ] |= PAGE_LAST;
-
-               /* Return I/O address */
-               DBGC ( &io_pages, "IO mapped %08lx+%zx to %p using PTEs "
-                      "[%d-%d]\n", bus_addr, len, io_addr, first,
-                      ( first + count - 1 ) );
-               return io_addr;
-       }
-
-       DBGC ( &io_pages, "IO could not map %08lx+%zx\n", bus_addr, len );
-       return NULL;
-}
-
-/**
- * Unmap pages for I/O
- *
- * @v io_addr          I/O address
- */
-static void iounmap_pages ( volatile const void *io_addr ) {
-       volatile const void *invalidate = io_addr;
-       unsigned int first;
-       unsigned int i;
-       int is_last;
-
-       DBGC ( &io_pages, "IO unmapping %p\n", io_addr );
-
-       /* Calculate first page table entry */
-       first = ( ( io_addr - IO_BASE ) / IO_PAGE_SIZE );
-
-       /* Clear page table entries */
-       for ( i = first ; ; i++ ) {
-
-               /* Sanity check */
-               assert ( io_pages.page[i] & PAGE_P );
-
-               /* Check if this is the last page in this allocation */
-               is_last = ( io_pages.page[i] & PAGE_LAST );
-
-               /* Clear page table entry */
-               io_pages.page[i] = 0;
-
-               /* Invalidate TLB for this page */
-               __asm__ __volatile__ ( "invlpg (%0)" : : "r" ( invalidate ) );
-               invalidate += IO_PAGE_SIZE;
-
-               /* Terminate if this was the last page */
-               if ( is_last )
-                       break;
-       }
-
-       DBGC ( &io_pages, "IO unmapped %p using PTEs [%d-%d]\n",
-              io_addr, first, i );
-}
-
-PROVIDE_UACCESS_INLINE ( librm, phys_to_user );
-PROVIDE_UACCESS_INLINE ( librm, user_to_phys );
-PROVIDE_UACCESS_INLINE ( librm, virt_to_user );
-PROVIDE_UACCESS_INLINE ( librm, user_to_virt );
-PROVIDE_UACCESS_INLINE ( librm, userptr_add );
-PROVIDE_UACCESS_INLINE ( librm, memcpy_user );
-PROVIDE_UACCESS_INLINE ( librm, memmove_user );
-PROVIDE_UACCESS_INLINE ( librm, memset_user );
-PROVIDE_UACCESS_INLINE ( librm, strlen_user );
-PROVIDE_UACCESS_INLINE ( librm, memchr_user );
-PROVIDE_IOMAP_INLINE ( pages, io_to_bus );
-PROVIDE_IOMAP ( pages, ioremap, ioremap_pages );
-PROVIDE_IOMAP ( pages, iounmap, iounmap_pages );
index 246905c..48c0aa1 100644 (file)
@@ -7,6 +7,10 @@ CFLAGS         += -fstrength-reduce -fomit-frame-pointer
 #
 CFLAGS         += -falign-jumps=1 -falign-loops=1 -falign-functions=1
 
+# Use %rip-relative addressing wherever possible.
+#
+CFLAGS         += -fpie
+
 # Force 64-bit code
 #
 CFLAGS         += -m64
index 0041bb8..26b7127 100644 (file)
@@ -1,9 +1,5 @@
 # -*- makefile -*- : Force emacs to use Makefile mode
 
-# Use %rip-relative addressing wherever possible.
-#
-CFLAGS         += -fpie
-
 # EFI probably doesn't guarantee us a red zone, so let's not rely on it.
 #
 CFLAGS         += -mno-red-zone
@@ -12,10 +8,6 @@ CFLAGS                += -mno-red-zone
 #
 ELF2EFI                = $(ELF2EFI64)
 
-# Specify EFI boot file
-#
-EFI_BOOT_FILE  = bootx64.efi
-
 # Include generic EFI Makefile
 #
 MAKEDEPS       += arch/x86/Makefile.efi
diff --git a/roms/ipxe/src/arch/x86_64/Makefile.pcbios b/roms/ipxe/src/arch/x86_64/Makefile.pcbios
deleted file mode 100644 (file)
index ba4c8d8..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- makefile -*- : Force emacs to use Makefile mode
-
-# Place .textdata in negative 2GB of address space
-#
-CFLAGS         += -mcmodel=kernel
-LDFLAGS                += --section-start=.textdata=0xffffffffeb000000
-
-# Assembly code does not respect a red zone.
-#
-CFLAGS         += -mno-red-zone
-
-# Include generic BIOS Makefile
-#
-MAKEDEPS       += arch/x86/Makefile.pcbios
-include arch/x86/Makefile.pcbios
diff --git a/roms/ipxe/src/arch/x86_64/core/gdbidt.S b/roms/ipxe/src/arch/x86_64/core/gdbidt.S
deleted file mode 100644 (file)
index 89280bf..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * GDB exception handlers
- *
- */
-
-/* Size of a register */
-#define SIZEOF_REG 8
-
-/* POSIX signal numbers for reporting traps to GDB */
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGFPE 8
-#define SIGSTKFLT 16
-
-       .section ".text.gdbmach_interrupt", "ax", @progbits
-       .code64
-
-       .struct 0
-/* Register dump created for GDB stub */
-regs:
-regs_rax:      .space  SIZEOF_REG
-regs_rbx:      .space  SIZEOF_REG
-regs_rcx:      .space  SIZEOF_REG
-regs_rdx:      .space  SIZEOF_REG
-regs_rsi:      .space  SIZEOF_REG
-regs_rdi:      .space  SIZEOF_REG
-regs_rbp:      .space  SIZEOF_REG
-regs_rsp:      .space  SIZEOF_REG
-regs_r8:       .space  SIZEOF_REG
-regs_r9:       .space  SIZEOF_REG
-regs_r10:      .space  SIZEOF_REG
-regs_r11:      .space  SIZEOF_REG
-regs_r12:      .space  SIZEOF_REG
-regs_r13:      .space  SIZEOF_REG
-regs_r14:      .space  SIZEOF_REG
-regs_r15:      .space  SIZEOF_REG
-regs_rip:      .space  SIZEOF_REG
-regs_rflags:   .space  SIZEOF_REG
-regs_cs:       .space  SIZEOF_REG
-regs_ss:       .space  SIZEOF_REG
-regs_ds:       .space  SIZEOF_REG
-regs_es:       .space  SIZEOF_REG
-regs_fs:       .space  SIZEOF_REG
-regs_gs:       .space  SIZEOF_REG
-regs_end:
-/* GDB signal code */
-gdb:
-gdb_code:      .space  SIZEOF_REG
-gdb_end:
-/* Long-mode exception frame */
-frame:
-frame_rip:     .space  SIZEOF_REG
-frame_cs:      .space  SIZEOF_REG
-frame_rflags:  .space  SIZEOF_REG
-frame_rsp:     .space  SIZEOF_REG
-frame_ss:      .space  SIZEOF_REG
-frame_end:
-       .previous
-
-       .globl  gdbmach_sigfpe
-gdbmach_sigfpe:
-       push    $SIGFPE
-       jmp     gdbmach_interrupt
-
-       .globl  gdbmach_sigtrap
-gdbmach_sigtrap:
-       push    $SIGTRAP
-       jmp     gdbmach_interrupt
-
-       .globl  gdbmach_sigstkflt
-gdbmach_sigstkflt:
-       push    $SIGSTKFLT
-       jmp     gdbmach_interrupt
-
-       .globl  gdbmach_sigill
-gdbmach_sigill:
-       push    $SIGILL
-       jmp     gdbmach_interrupt
-
-gdbmach_interrupt:
-
-       /* Create register dump */
-       pushq   %gs
-       pushq   %fs
-       pushq   $0              /* %es unused in long mode */
-       pushq   $0              /* %ds unused in long mode */
-       pushq   ( frame_ss      - regs_ss       - SIZEOF_REG )(%rsp)
-       pushq   ( frame_cs      - regs_cs       - SIZEOF_REG )(%rsp)
-       pushq   ( frame_rflags  - regs_rflags   - SIZEOF_REG )(%rsp)
-       pushq   ( frame_rip     - regs_rip      - SIZEOF_REG )(%rsp)
-       pushq   %r15
-       pushq   %r14
-       pushq   %r13
-       pushq   %r12
-       pushq   %r11
-       pushq   %r10
-       pushq   %r9
-       pushq   %r8
-       pushq   ( frame_rsp     - regs_rsp      - SIZEOF_REG )(%rsp)
-       pushq   %rbp
-       pushq   %rdi
-       pushq   %rsi
-       pushq   %rdx
-       pushq   %rcx
-       pushq   %rbx
-       pushq   %rax
-
-       /* Call GDB stub exception handler */
-       movq    gdb_code(%rsp), %rdi
-       movq    %rsp, %rsi
-       call    gdbmach_handler
-
-       /* Restore from register dump */
-       popq    %rax
-       popq    %rbx
-       popq    %rcx
-       popq    %rdx
-       popq    %rsi
-       popq    %rdi
-       popq    %rbp
-       popq    ( frame_rsp     - regs_rsp      - SIZEOF_REG )(%rsp)
-       popq    %r8
-       popq    %r9
-       popq    %r10
-       popq    %r11
-       popq    %r12
-       popq    %r13
-       popq    %r14
-       popq    %r15
-       popq    ( frame_rip     - regs_rip      - SIZEOF_REG )(%rsp)
-       popq    ( frame_rflags  - regs_rflags   - SIZEOF_REG )(%rsp)
-       popq    ( frame_cs      - regs_cs       - SIZEOF_REG )(%rsp)
-       popq    ( frame_ss      - regs_ss       - SIZEOF_REG )(%rsp)
-       addq    $( regs_fs - regs_ds ), %rsp    /* skip %ds, %es */
-       popq    %fs
-       popq    %gs
-
-       /* Skip code */
-       addq    $( gdb_end - gdb_code ), %rsp   /* skip code */
-
-       /* Return */
-       iretq
index 98c560e..f70b2e5 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef ASSEMBLY
 
 /** Declare a function with standard calling conventions */
-#define __asmcall __attribute__ (( used, regparm(0) ))
+#define __asmcall __attribute__ (( regparm(0) ))
 
 /** Declare a function with libgcc implicit linkage */
 #define __libgcc
@@ -3,7 +3,7 @@
 
 /** @file
  *
- * ARM-specific entropy API implementations
+ * x86_64-specific entropy API implementations
  *
  */
 
index 975b1ee..845c182 100644 (file)
@@ -49,4 +49,27 @@ hv_call ( struct hv_hypervisor *hv, unsigned int code, const void *in,
        return result;
 }
 
+/**
+ * Set bit atomically
+ *
+ * @v bits             Bit field
+ * @v bit              Bit to set
+ */
+static inline __attribute__ (( always_inline )) void
+hv_set_bit ( void *bits, unsigned int bit ) {
+       struct {
+               uint64_t qword[ ( bit / 64 ) + 1 ];
+       } *qwords = bits;
+
+       /* Set bit using "lock bts".  Inform compiler that any memory
+        * from the start of the bit field up to and including the
+        * qword containing this bit may be modified.  (This is
+        * overkill but shouldn't matter in practice since we're
+        * unlikely to subsequently read other bits from the same bit
+        * field.)
+        */
+       __asm__ __volatile__ ( "lock bts %1, %0"
+                              : "+m" ( *qwords ) : "Ir" ( bit ) );
+}
+
 #endif /* _BITS_HYPERV_H */
diff --git a/roms/ipxe/src/arch/x86_64/include/bits/nap.h b/roms/ipxe/src/arch/x86_64/include/bits/nap.h
new file mode 100644 (file)
index 0000000..8b42c0a
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _BITS_NAP_H
+#define _BITS_NAP_H
+
+/** @file
+ *
+ * x86_64-specific CPU sleeping API implementations
+ *
+ */
+
+#include <ipxe/efi/efix86_nap.h>
+
+#endif /* _BITS_MAP_H */
@@ -3,7 +3,7 @@
 
 /** @file
  *
- * ARM-specific reboot API implementations
+ * x86_64-specific reboot API implementations
  *
  */
 
@@ -3,7 +3,7 @@
 
 /** @file
  *
- * ARM-specific sanboot API implementations
+ * x86_64-specific sanboot API implementations
  *
  */
 
@@ -3,10 +3,8 @@
 
 /** @file
  *
- * ARM-specific SMBIOS API implementations
+ * i386-specific SMBIOS API implementations
  *
  */
 
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
 #endif /* _BITS_SMBIOS_H */
similarity index 74%
rename from roms/ipxe/src/arch/arm/include/bits/time.h
rename to roms/ipxe/src/arch/x86_64/include/bits/time.h
index 724d8b9..aa74fac 100644 (file)
@@ -3,7 +3,7 @@
 
 /** @file
  *
- * ARM-specific time API implementations
+ * x86_64-specific time API implementations
  *
  */
 
similarity index 52%
rename from roms/ipxe/src/arch/arm/include/bits/timer.h
rename to roms/ipxe/src/arch/x86_64/include/bits/timer.h
index 64e7d31..dfa6c27 100644 (file)
@@ -3,10 +3,8 @@
 
 /** @file
  *
- * ARM-specific timer API implementations
+ * x86_64-specific timer API implementations
  *
  */
 
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
 #endif /* _BITS_TIMER_H */
@@ -3,10 +3,8 @@
 
 /** @file
  *
- * ARM-specific user access API implementations
+ * x86_64-specific user access API implementations
  *
  */
 
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
 #endif /* _BITS_UACCESS_H */
diff --git a/roms/ipxe/src/arch/x86_64/include/bits/umalloc.h b/roms/ipxe/src/arch/x86_64/include/bits/umalloc.h
new file mode 100644 (file)
index 0000000..12bf949
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _BITS_UMALLOC_H
+#define _BITS_UMALLOC_H
+
+/** @file
+ *
+ * x86_64-specific user memory allocation API implementations
+ *
+ */
+
+#endif /* _BITS_UMALLOC_H */
index 367405f..6dadbbd 100644 (file)
 
 typedef unsigned long gdbreg_t;
 
-/* Register snapshot */
+/* The register snapshot, this must be in sync with interrupt handler and the
+ * GDB protocol. */
 enum {
-       GDBMACH_RAX,
-       GDBMACH_RBX,
-       GDBMACH_RCX,
-       GDBMACH_RDX,
-       GDBMACH_RSI,
-       GDBMACH_RDI,
-       GDBMACH_RBP,
-       GDBMACH_RSP,
-       GDBMACH_R8,
-       GDBMACH_R9,
-       GDBMACH_R10,
-       GDBMACH_R11,
-       GDBMACH_R12,
-       GDBMACH_R13,
-       GDBMACH_R14,
-       GDBMACH_R15,
-       GDBMACH_RIP,
-       GDBMACH_RFLAGS,
-       GDBMACH_CS,
-       GDBMACH_SS,
-       GDBMACH_DS,
-       GDBMACH_ES,
-       GDBMACH_FS,
-       GDBMACH_GS,
+       // STUB: don't expect this to work!
+       GDBMACH_EIP,
+       GDBMACH_EFLAGS,
        GDBMACH_NREGS,
+       GDBMACH_SIZEOF_REGS = GDBMACH_NREGS * sizeof ( gdbreg_t )
 };
 
-#define GDBMACH_SIZEOF_REGS ( GDBMACH_NREGS * sizeof ( gdbreg_t ) )
-
 /* Breakpoint types */
 enum {
        GDBMACH_BPMEM,
@@ -54,27 +33,21 @@ enum {
        GDBMACH_AWATCH,
 };
 
-/* Exception vectors */
-extern void gdbmach_sigfpe ( void );
-extern void gdbmach_sigtrap ( void );
-extern void gdbmach_sigstkflt ( void );
-extern void gdbmach_sigill ( void );
-
 static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) {
-       regs[GDBMACH_RIP] = pc;
+       regs [ GDBMACH_EIP ] = pc;
 }
 
 static inline void gdbmach_set_single_step ( gdbreg_t *regs, int step ) {
-       regs[GDBMACH_RFLAGS] &= ~( 1 << 8 ); /* Trace Flag (TF) */
-       regs[GDBMACH_RFLAGS] |= ( step << 8 );
+       regs [ GDBMACH_EFLAGS ] &= ~( 1 << 8 ); /* Trace Flag (TF) */
+       regs [ GDBMACH_EFLAGS ] |= ( step << 8 );
 }
 
 static inline void gdbmach_breakpoint ( void ) {
        __asm__ __volatile__ ( "int $3\n" );
 }
 
-extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len,
-                                   int enable );
+extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len, int enable );
+
 extern void gdbmach_init ( void );
 
 #endif /* GDBMACH_H */
diff --git a/roms/ipxe/src/arch/x86_64/include/pcbios/ipxe/dhcp_arch.h b/roms/ipxe/src/arch/x86_64/include/pcbios/ipxe/dhcp_arch.h
deleted file mode 100644 (file)
index e07e4c1..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2010 VMware, Inc.  All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-#ifndef _DHCP_ARCH_H
-#define _DHCP_ARCH_H
-
-/** @file
- *
- * Architecture-specific DHCP options
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/dhcp.h>
-
-#define DHCP_ARCH_VENDOR_CLASS_ID \
-       DHCP_STRING ( 'P', 'X', 'E', 'C', 'l', 'i', 'e', 'n', 't', ':',      \
-                     'A', 'r', 'c', 'h', ':', '0', '0', '0', '0', '0', ':', \
-                     'U', 'N', 'D', 'I', ':', '0', '0', '2', '0', '0', '1' )
-
-#define DHCP_ARCH_CLIENT_ARCHITECTURE \
-       DHCP_WORD ( DHCP_CLIENT_ARCHITECTURE_X86 )
-
-#define DHCP_ARCH_CLIENT_NDI DHCP_OPTION ( 1 /* UNDI */ , 2, 1 /* v2.1 */ )
-
-#endif
diff --git a/roms/ipxe/src/config/cloud/aws.ipxe b/roms/ipxe/src/config/cloud/aws.ipxe
deleted file mode 100644 (file)
index d857d71..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#!ipxe
-
-echo Amazon EC2 - iPXE boot via user-data
-ifstat ||
-dhcp ||
-route ||
-chain -ar http://169.254.169.254/latest/user-data
diff --git a/roms/ipxe/src/config/cloud/colour.h b/roms/ipxe/src/config/cloud/colour.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/roms/ipxe/src/config/cloud/console.h b/roms/ipxe/src/config/cloud/console.h
deleted file mode 100644 (file)
index dae18e5..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Console configuration suitable for use in public cloud
- * environments, or any environment where direct console access is not
- * available.
- *
- */
-
-/* Log to syslog(s) server
- *
- * The syslog server to be used must be specified via e.g.
- * "set syslog 192.168.0.1".
- */
-#define CONSOLE_SYSLOG
-#define CONSOLE_SYSLOGS
-
-/* Log to serial port
- *
- * Note that the serial port output from an AWS EC2 virtual machine is
- * generally available (as the "System Log") only after the instance
- * has been stopped.
- */
-#define CONSOLE_SERIAL
-
-/* Log to partition on local disk
- *
- * If all other log mechanisms fail then the VM boot disk containing
- * the iPXE image can be detached and attached to another machine in
- * the same cloud, allowing the log to be retrieved from the log
- * partition.
- */
-#define CONSOLE_INT13
diff --git a/roms/ipxe/src/config/cloud/crypto.h b/roms/ipxe/src/config/cloud/crypto.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/roms/ipxe/src/config/cloud/general.h b/roms/ipxe/src/config/cloud/general.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/roms/ipxe/src/config/cloud/serial.h b/roms/ipxe/src/config/cloud/serial.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/roms/ipxe/src/config/cloud/settings.h b/roms/ipxe/src/config/cloud/settings.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/roms/ipxe/src/config/cloud/sideband.h b/roms/ipxe/src/config/cloud/sideband.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/roms/ipxe/src/config/cloud/usb.h b/roms/ipxe/src/config/cloud/usb.h
deleted file mode 100644 (file)
index e69de29..0000000
index e24cfe0..1dd912c 100644 (file)
@@ -51,6 +51,9 @@ PROVIDE_REQUIRING_SYMBOL();
  *
  */
 
+#ifdef CONSOLE_PCBIOS
+REQUIRE_OBJECT ( bios_console );
+#endif
 #ifdef CONSOLE_SERIAL
 REQUIRE_OBJECT ( serial );
 #endif
@@ -78,6 +81,12 @@ REQUIRE_OBJECT ( vmconsole );
 #ifdef CONSOLE_DEBUGCON
 REQUIRE_OBJECT ( debugcon );
 #endif
+#ifdef CONSOLE_VESAFB
+REQUIRE_OBJECT ( vesafb );
+#endif
+#ifdef CONSOLE_INT13
+REQUIRE_OBJECT ( int13con );
+#endif
 
 /*
  * Drag in all requested network protocols
@@ -278,9 +287,6 @@ REQUIRE_OBJECT ( ipstat_cmd );
 #ifdef PROFSTAT_CMD
 REQUIRE_OBJECT ( profstat_cmd );
 #endif
-#ifdef NTP_CMD
-REQUIRE_OBJECT ( ntp_cmd );
-#endif
 
 /*
  * Drag in miscellaneous objects
diff --git a/roms/ipxe/src/config/config_efi.c b/roms/ipxe/src/config/config_efi.c
deleted file mode 100644 (file)
index 92678d1..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <config/general.h>
-#include <config/console.h>
-
-/** @file
- *
- * EFI-specific configuration options
- *
- */
-
-PROVIDE_REQUIRING_SYMBOL();
-
-/*
- * Drag in all requested console types
- *
- */
-
-#ifdef CONSOLE_EFI
-REQUIRE_OBJECT ( efi_console );
-#endif
-#ifdef CONSOLE_EFIFB
-REQUIRE_OBJECT ( efi_fbcon );
-#endif
-#ifdef CONSOLE_FRAMEBUFFER
-REQUIRE_OBJECT ( efi_fbcon );
-#endif
-#ifdef DOWNLOAD_PROTO_FILE
-REQUIRE_OBJECT ( efi_local );
-#endif
index b5f7ddc..de7a07c 100644 (file)
@@ -43,6 +43,3 @@ REQUIRE_OBJECT ( fcoe );
 #ifdef NET_PROTO_STP
 REQUIRE_OBJECT ( stp );
 #endif
-#ifdef NET_PROTO_LACP
-REQUIRE_OBJECT ( eth_slow );
-#endif
index 4da8fe2..a742e75 100644 (file)
@@ -37,20 +37,3 @@ PROVIDE_REQUIRING_SYMBOL();
 #ifdef SANBOOT_PROTO_IB_SRP
 REQUIRE_OBJECT ( ib_srp );
 #endif
-
-/*
- * Drag in Infiniband-specific virtual network devices
- */
-#ifdef VNIC_IPOIB
-REQUIRE_OBJECT ( ipoib );
-#endif
-#ifdef VNIC_XSIGO
-REQUIRE_OBJECT ( xsigo );
-#endif
-
-/*
- * Drag in Infiniband-specific commands
- */
-#ifdef IBMGMT_CMD
-REQUIRE_OBJECT ( ibmgmt_cmd );
-#endif
diff --git a/roms/ipxe/src/config/config_linux.c b/roms/ipxe/src/config/config_linux.c
deleted file mode 100644 (file)
index 71eeff9..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <config/console.h>
-
-/** @file
- *
- * Linux-specific configuration options
- *
- */
-
-PROVIDE_REQUIRING_SYMBOL();
-
-/*
- * Drag in all requested console types
- *
- */
-
-#ifdef CONSOLE_LINUX
-REQUIRE_OBJECT ( linux_console );
-#endif
diff --git a/roms/ipxe/src/config/config_pcbios.c b/roms/ipxe/src/config/config_pcbios.c
deleted file mode 100644 (file)
index 698c68a..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <config/console.h>
-
-/** @file
- *
- * BIOS-specific configuration options
- *
- */
-
-PROVIDE_REQUIRING_SYMBOL();
-
-/*
- * Drag in all requested console types
- *
- */
-
-#ifdef CONSOLE_PCBIOS
-REQUIRE_OBJECT ( bios_console );
-#endif
-#ifdef CONSOLE_VESAFB
-REQUIRE_OBJECT ( vesafb );
-#endif
-#ifdef CONSOLE_FRAMEBUFFER
-REQUIRE_OBJECT ( vesafb );
-#endif
-#ifdef CONSOLE_INT13
-REQUIRE_OBJECT ( int13con );
-#endif
index 17296d2..dc0e6e6 100644 (file)
@@ -43,9 +43,6 @@ REQUIRE_OBJECT ( ehci );
 #ifdef USB_HCD_UHCI
 REQUIRE_OBJECT ( uhci );
 #endif
-#ifdef USB_HCD_USBIO
-REQUIRE_OBJECT ( usbio );
-#endif
 
 /*
  * Drag in USB peripherals
@@ -53,10 +50,3 @@ REQUIRE_OBJECT ( usbio );
 #ifdef USB_KEYBOARD
 REQUIRE_OBJECT ( usbkbd );
 #endif
-
-/*
- * Drag in USB external interfaces
- */
-#ifdef USB_EFI
-REQUIRE_OBJECT ( efi_usb );
-#endif
index 9f770d0..ffa5cf5 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Console configuration
  *
- * These options specify the console types that iPXE will use for
+ * These options specify the console types that Etherboot will use for
  * interaction with the user.
  *
  */
@@ -14,51 +14,19 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <config/defaults.h>
 
-/*
- * Default console types
- *
- * These are all enabled by default for the appropriate platforms.
- * You may disable them if needed.
- *
- */
-
-//#undef       CONSOLE_PCBIOS          /* Default BIOS console */
-//#undef       CONSOLE_EFI             /* Default EFI console */
-//#undef       CONSOLE_LINUX           /* Default Linux console */
-
-/*
- * Additional console types
- *
- * These are not enabled by default, but may be useful in your
- * environment.
- *
- */
-
-//#define      CONSOLE_SERIAL          /* Serial port console */
-//#define      CONSOLE_FRAMEBUFFER     /* Graphical framebuffer console */
+//#define      CONSOLE_PCBIOS          /* Default BIOS console */
+//#define      CONSOLE_SERIAL          /* Serial port */
+//#define      CONSOLE_DIRECT_VGA      /* Direct access to VGA card */
+//#define      CONSOLE_PC_KBD          /* Direct access to PC keyboard */
 //#define      CONSOLE_SYSLOG          /* Syslog console */
 //#define      CONSOLE_SYSLOGS         /* Encrypted syslog console */
 //#define      CONSOLE_VMWARE          /* VMware logfile console */
-//#define      CONSOLE_DEBUGCON        /* Bochs/QEMU/KVM debug port console */
+//#define      CONSOLE_DEBUGCON        /* Debug port console */
+//#define      CONSOLE_VESAFB          /* VESA framebuffer console */
 //#define      CONSOLE_INT13           /* INT13 disk log console */
 
-/*
- * Very obscure console types
- *
- * You almost certainly do not need to enable these.
- *
- */
-
-//#define      CONSOLE_DIRECT_VGA      /* Direct access to VGA card */
-//#define      CONSOLE_PC_KBD          /* Direct access to PC keyboard */
-
-/* Keyboard map (available maps in hci/keymap/) */
 #define        KEYBOARD_MAP    us
 
-/* Control which syslog() messages are generated.
- *
- * Note that this is not related in any way to CONSOLE_SYSLOG.
- */
 #define        LOG_LEVEL       LOG_NONE
 
 #include <config/named.h>
index 8f885c5..bccfc04 100644 (file)
@@ -50,14 +50,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  */
 #define TIMESTAMP_ERROR_MARGIN ( ( 12 * 60 + 30 ) * 60 )
 
-/** Default cross-signed certificate source
- *
- * This is the default location from which iPXE will attempt to
- * download cross-signed certificates in order to complete a
- * certificate chain.
- */
-#define CROSSCERT "http://ca.ipxe.org/auto"
-
 #include <config/named.h>
 #include NAMED_CONFIG(crypto.h)
 #include <config/local/crypto.h>
index ba4eed9..cdf41c5 100644 (file)
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #define UACCESS_EFI
-#define IOMAP_VIRT
+#define IOAPI_X86
 #define PCIAPI_EFI
 #define CONSOLE_EFI
 #define TIMER_EFI
+#define NAP_EFIX86
 #define UMALLOC_EFI
 #define SMBIOS_EFI
 #define SANBOOT_NULL
@@ -22,27 +23,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define TIME_EFI
 #define REBOOT_EFI
 
-#define DOWNLOAD_PROTO_FILE    /* Local filesystem access */
-
 #define        IMAGE_EFI               /* EFI image support */
 #define        IMAGE_SCRIPT            /* iPXE script image support */
 
-#define        USB_HCD_XHCI            /* xHCI USB host controller */
-#define        USB_HCD_EHCI            /* EHCI USB host controller */
-#define        USB_HCD_UHCI            /* UHCI USB host controller */
-#define        USB_EFI                 /* Provide EFI_USB_IO_PROTOCOL interface */
-
 #define        REBOOT_CMD              /* Reboot command */
-
-#if defined ( __i386__ ) || defined ( __x86_64__ )
-#define IOAPI_X86
-#define NAP_EFIX86
 #define        CPUID_CMD               /* x86 CPU feature detection command */
-#endif
-
-#if defined ( __arm__ ) || defined ( __aarch64__ )
-#define IOAPI_ARM
-#define NAP_EFIARM
-#endif
 
 #endif /* CONFIG_DEFAULTS_EFI_H */
index e191505..3ed8343 100644 (file)
@@ -22,12 +22,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define TIME_RTC
 #define REBOOT_PCBIOS
 
-#ifdef __x86_64__
-#define IOMAP_PAGES
-#else
-#define IOMAP_VIRT
-#endif
-
 #define        IMAGE_ELF               /* ELF image support */
 #define        IMAGE_MULTIBOOT         /* MultiBoot image support */
 #define        IMAGE_PXE               /* PXE image support */
index bff5b56..49fe16b 100644 (file)
@@ -25,12 +25,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 //#define DHCP_DISC_END_TIMEOUT_SEC    32      /* as per PXE spec */
 
 /*
- * Maximum number of discovery deferrals due to blocked links
- * (e.g. from non-forwarding STP ports)
- */
-#define DHCP_DISC_MAX_DEFERRALS                60
-
-/*
  * ProxyDHCP offers are given precedence by continue to wait for them
  * after a valid DHCPOFFER is received.  We'll wait through this
  * timeout for it.  The PXE spec indicates waiting through the 4 & 8
index a71ba72..ee15f6b 100644 (file)
@@ -38,7 +38,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #undef NET_PROTO_IPV6          /* IPv6 protocol */
 #undef NET_PROTO_FCOE          /* Fibre Channel over Ethernet protocol */
 #define        NET_PROTO_STP           /* Spanning Tree protocol */
-#define        NET_PROTO_LACP          /* Link Aggregation control protocol */
 
 /*
  * PXE support
@@ -58,7 +57,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #undef DOWNLOAD_PROTO_FTP      /* File Transfer Protocol */
 #undef DOWNLOAD_PROTO_SLAM     /* Scalable Local Area Multicast */
 #undef DOWNLOAD_PROTO_NFS      /* Network File System Protocol */
-//#undef DOWNLOAD_PROTO_FILE   /* Local filesystem access */
 
 /*
  * SAN boot protocols
@@ -122,7 +120,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define        CONFIG_CMD              /* Option configuration console */
 #define        IFMGMT_CMD              /* Interface management commands */
 #define        IWMGMT_CMD              /* Wireless interface management commands */
-#define IBMGMT_CMD             /* Infiniband management commands */
 #define FCMGMT_CMD             /* Fibre Channel management commands */
 #define        ROUTE_CMD               /* Routing table management commands */
 #define IMAGE_CMD              /* Image management commands */
@@ -147,7 +144,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 //#define CONSOLE_CMD          /* Console command */
 //#define IPSTAT_CMD           /* IP statistics commands */
 //#define PROFSTAT_CMD         /* Profiling commands */
-//#define NTP_CMD              /* NTP commands */
 
 /*
  * ROM-specific options
@@ -157,13 +153,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define        AUTOBOOT_ROM_FILTER     /* Autoboot only devices matching our ROM */
 
 /*
- * Virtual network devices
- *
- */
-#define VNIC_IPOIB             /* Infiniband IPoIB virtual NICs */
-//#define VNIC_XSIGO           /* Infiniband Xsigo virtual NICs */
-
-/*
  * Error message tables to include
  *
  */
index d2519d8..52e82ea 100644 (file)
@@ -15,22 +15,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  * USB host controllers (all enabled by default)
  *
  */
-//#undef       USB_HCD_XHCI    /* xHCI USB host controller */
-//#undef       USB_HCD_EHCI    /* EHCI USB host controller */
-//#undef       USB_HCD_UHCI    /* UHCI USB host controller */
-//#define      USB_HCD_USBIO   /* Very slow EFI USB host controller */
+//#undef       USB_HCD_XHCI            /* xHCI USB host controller */
+//#undef       USB_HCD_EHCI            /* EHCI USB host controller */
+//#undef       USB_HCD_UHCI            /* UHCI USB host controller */
 
 /*
  * USB peripherals
  *
  */
-//#undef       USB_KEYBOARD    /* USB keyboards */
-
-/*
- * USB external interfaces
- *
- */
-//#undef       USB_EFI         /* Provide EFI_USB_IO_PROTOCOL interface */
+//#undef       USB_KEYBOARD            /* USB keyboards */
 
 #include <config/named.h>
 #include NAMED_CONFIG(usb.h)
index 9b2a823..def5d8b 100644 (file)
@@ -194,12 +194,8 @@ static int dbg_autocolour ( unsigned long stream ) {
  * @v stream           Message stream ID
  */
 void dbg_autocolourise ( unsigned long stream ) {
-
-       if ( DBGCOL_MIN ) {
-               dbg_printf ( "\033[%dm",
-                            ( stream ?
-                              ( DBGCOL_MIN + dbg_autocolour ( stream ) ) : 0));
-       }
+       dbg_printf ( "\033[%dm",
+                    ( stream ? ( DBGCOL_MIN + dbg_autocolour ( stream ) ) :0));
 }
 
 /**
@@ -207,7 +203,5 @@ void dbg_autocolourise ( unsigned long stream ) {
  *
  */
 void dbg_decolourise ( void ) {
-
-       if ( DBGCOL_MIN )
-               dbg_printf ( "\033[0m" );
+       dbg_printf ( "\033[0m" );
 }
index ba678f8..d745f36 100644 (file)
@@ -136,9 +136,9 @@ static int downloader_progress ( struct downloader *downloader,
  * @v meta             Data transfer metadata
  * @ret rc             Return status code
  */
-static int downloader_deliver ( struct downloader *downloader,
-                               struct io_buffer *iobuf,
-                               struct xfer_metadata *meta ) {
+static int downloader_xfer_deliver ( struct downloader *downloader,
+                                    struct io_buffer *iobuf,
+                                    struct xfer_metadata *meta ) {
        int rc;
 
        /* Add data to buffer */
@@ -160,51 +160,16 @@ static int downloader_deliver ( struct downloader *downloader,
  * @ret xferbuf                Data transfer buffer, or NULL on error
  */
 static struct xfer_buffer *
-downloader_buffer ( struct downloader *downloader ) {
+downloader_xfer_buffer ( struct downloader *downloader ) {
 
        /* Provide direct access to underlying data transfer buffer */
        return &downloader->buffer;
 }
 
-/**
- * Redirect data transfer interface
- *
- * @v downloader       Downloader
- * @v type             New location type
- * @v args             Remaining arguments depend upon location type
- * @ret rc             Return status code
- */
-static int downloader_vredirect ( struct downloader *downloader, int type,
-                                 va_list args ) {
-       va_list tmp;
-       struct uri *uri;
-       int rc;
-
-       /* Intercept redirects to a LOCATION_URI and update the image URI */
-       if ( type == LOCATION_URI ) {
-
-               /* Extract URI argument */
-               va_copy ( tmp, args );
-               uri = va_arg ( tmp, struct uri * );
-               va_end ( tmp );
-
-               /* Set image URI */
-               if ( ( rc = image_set_uri ( downloader->image, uri ) ) != 0 )
-                       return rc;
-       }
-
-       /* Redirect to new location */
-       if ( ( rc = xfer_vreopen ( &downloader->xfer, type, args ) ) != 0 )
-               return rc;
-
-       return 0;
-}
-
 /** Downloader data transfer interface operations */
 static struct interface_operation downloader_xfer_operations[] = {
-       INTF_OP ( xfer_deliver, struct downloader *, downloader_deliver ),
-       INTF_OP ( xfer_buffer, struct downloader *, downloader_buffer ),
-       INTF_OP ( xfer_vredirect, struct downloader *, downloader_vredirect ),
+       INTF_OP ( xfer_deliver, struct downloader *, downloader_xfer_deliver ),
+       INTF_OP ( xfer_buffer, struct downloader *, downloader_xfer_buffer ),
        INTF_OP ( intf_close, struct downloader *, downloader_finished ),
 };
 
index a13884b..2c2ade0 100644 (file)
@@ -36,6 +36,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/command.h>
 #include <ipxe/parseopt.h>
 #include <ipxe/settings.h>
+#include <ipxe/console.h>
+#include <ipxe/keys.h>
+#include <ipxe/process.h>
+#include <ipxe/nap.h>
 #include <ipxe/shell.h>
 
 /** @file
@@ -569,6 +573,8 @@ static struct command_descriptor sleep_cmd =
 static int sleep_exec ( int argc, char **argv ) {
        struct sleep_options opts;
        unsigned int seconds;
+       unsigned long start;
+       unsigned long delay;
        int rc;
 
        /* Parse options */
@@ -580,8 +586,14 @@ static int sleep_exec ( int argc, char **argv ) {
                return rc;
 
        /* Delay for specified number of seconds */
-       if ( sleep ( seconds ) != 0 )
-               return -ECANCELED;
+       start = currticks();
+       delay = ( seconds * TICKS_PER_SEC );
+       while ( ( currticks() - start ) <= delay ) {
+               step();
+               if ( iskey() && ( getchar() == CTRL_C ) )
+                       return -ECANCELED;
+               cpu_nap();
+       }
 
        return 0;
 }
index 44a56e1..6d8b008 100644 (file)
@@ -156,7 +156,7 @@ static void fbcon_store ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
  */
 static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
                         unsigned int xpos, unsigned int ypos ) {
-       uint8_t glyph[fbcon->font->height];
+       struct fbcon_font_glyph glyph;
        size_t offset;
        size_t pixel_len;
        size_t skip_len;
@@ -167,7 +167,9 @@ static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
        void *src;
 
        /* Get font character */
-       fbcon->font->glyph ( cell->character, glyph );
+       copy_from_user ( &glyph, fbcon->font->start,
+                        ( cell->character * sizeof ( glyph ) ),
+                        sizeof ( glyph ) );
 
        /* Calculate pixel geometry */
        offset = ( fbcon->indent +
@@ -180,7 +182,7 @@ static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
        transparent = ( cell->background == FBCON_TRANSPARENT );
 
        /* Draw character rows */
-       for ( row = 0 ; row < fbcon->font->height ; row++ ) {
+       for ( row = 0 ; row < FBCON_CHAR_HEIGHT ; row++ ) {
 
                /* Draw background picture, if applicable */
                if ( transparent ) {
@@ -195,7 +197,7 @@ static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
                }
 
                /* Draw character row */
-               for ( column = FBCON_CHAR_WIDTH, bitmask = glyph[row] ;
+               for ( column = FBCON_CHAR_WIDTH, bitmask = glyph.bitmask[row] ;
                      column ; column--, bitmask <<= 1, offset += pixel_len ) {
                        if ( bitmask & 0x80 ) {
                                src = &cell->foreground;
@@ -575,24 +577,22 @@ static int fbcon_picture_init ( struct fbcon *fbcon,
  * @v fbcon            Frame buffer console
  * @v start            Start address
  * @v pixel            Pixel geometry
+ * @v margin           Minimum margin
  * @v map              Colour mapping
  * @v font             Font definition
- * @v config           Console configuration
+ * @v pixbuf           Background picture (if any)
  * @ret rc             Return status code
  */
 int fbcon_init ( struct fbcon *fbcon, userptr_t start,
                 struct fbcon_geometry *pixel,
+                struct fbcon_margin *margin,
                 struct fbcon_colour_map *map,
                 struct fbcon_font *font,
-                struct console_configuration *config ) {
+                struct pixel_buffer *pixbuf ) {
        int width;
        int height;
        unsigned int xgap;
        unsigned int ygap;
-       unsigned int left;
-       unsigned int right;
-       unsigned int top;
-       unsigned int bottom;
        int rc;
 
        /* Initialise data structure */
@@ -611,51 +611,31 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start,
               user_to_phys ( fbcon->start, 0 ),
               user_to_phys ( fbcon->start, fbcon->len ) );
 
-       /* Calculate margin.  If the actual screen size is larger than
-        * the requested screen size, then update the margins so that
-        * the margin remains relative to the requested screen size.
-        * (As an exception, if a zero margin was specified then treat
-        * this as meaning "expand to edge of actual screen".)
-        */
-       xgap = ( pixel->width - config->width );
-       ygap = ( pixel->height - config->height );
-       left = ( xgap / 2 );
-       right = ( xgap - left );
-       top = ( ygap / 2 );
-       bottom = ( ygap - top );
-       fbcon->margin.left = ( config->left + ( config->left ? left : 0 ) );
-       fbcon->margin.right = ( config->right + ( config->right ? right : 0 ) );
-       fbcon->margin.top = ( config->top + ( config->top ? top : 0 ) );
-       fbcon->margin.bottom =
-               ( config->bottom + ( config->bottom ? bottom : 0 ) );
-
        /* Expand margin to accommodate whole characters */
-       width = ( pixel->width - fbcon->margin.left - fbcon->margin.right );
-       height = ( pixel->height - fbcon->margin.top - fbcon->margin.bottom );
-       if ( ( width < FBCON_CHAR_WIDTH ) ||
-            ( height < ( ( int ) font->height ) ) ) {
+       width = ( pixel->width - margin->left - margin->right );
+       height = ( pixel->height - margin->top - margin->bottom );
+       if ( ( width < FBCON_CHAR_WIDTH ) || ( height < FBCON_CHAR_HEIGHT ) ) {
                DBGC ( fbcon, "FBCON %p has unusable character area "
-                      "[%d-%d),[%d-%d)\n", fbcon, fbcon->margin.left,
-                      ( pixel->width - fbcon->margin.right ),
-                      fbcon->margin.top,
-                      ( pixel->height - fbcon->margin.bottom ) );
+                      "[%d-%d),[%d-%d)\n", fbcon,
+                      margin->left, ( pixel->width - margin->right ),
+                      margin->top, ( pixel->height - margin->bottom ) );
                rc = -EINVAL;
                goto err_margin;
        }
        xgap = ( width % FBCON_CHAR_WIDTH );
-       ygap = ( height % font->height );
-       fbcon->margin.left += ( xgap / 2 );
-       fbcon->margin.top += ( ygap / 2 );
-       fbcon->margin.right += ( xgap - ( xgap / 2 ) );
-       fbcon->margin.bottom += ( ygap - ( ygap / 2 ) );
+       ygap = ( height % FBCON_CHAR_HEIGHT );
+       fbcon->margin.left = ( margin->left + ( xgap / 2 ) );
+       fbcon->margin.top = ( margin->top + ( ygap / 2 ) );
+       fbcon->margin.right = ( margin->right + ( xgap - ( xgap / 2 ) ) );
+       fbcon->margin.bottom = ( margin->bottom + ( ygap - ( ygap / 2 ) ) );
        fbcon->indent = ( ( fbcon->margin.top * pixel->stride ) +
                          ( fbcon->margin.left * pixel->len ) );
 
        /* Derive character geometry from pixel geometry */
        fbcon->character.width = ( width / FBCON_CHAR_WIDTH );
-       fbcon->character.height = ( height / font->height );
+       fbcon->character.height = ( height / FBCON_CHAR_HEIGHT );
        fbcon->character.len = ( pixel->len * FBCON_CHAR_WIDTH );
-       fbcon->character.stride = ( pixel->stride * font->height );
+       fbcon->character.stride = ( pixel->stride * FBCON_CHAR_HEIGHT );
        DBGC ( fbcon, "FBCON %p is pixel %dx%d, char %dx%d at "
               "[%d-%d),[%d-%d)\n", fbcon, fbcon->pixel->width,
               fbcon->pixel->height, fbcon->character.width,
@@ -682,8 +662,7 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start,
        memset_user ( fbcon->start, 0, 0, fbcon->len );
 
        /* Generate pixel buffer from background image, if applicable */
-       if ( config->pixbuf &&
-            ( ( rc = fbcon_picture_init ( fbcon, config->pixbuf ) ) != 0 ) )
+       if ( pixbuf && ( ( rc = fbcon_picture_init ( fbcon, pixbuf ) ) != 0 ) )
                goto err_picture;
 
        /* Draw background picture (including margins), if applicable */
index 8b57ddf..6ad52d1 100644 (file)
@@ -40,7 +40,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 enum {
        POSIX_EINVAL = 0x1c,  /* used to report bad arguments to GDB */
-       SIZEOF_PAYLOAD = 512, /* buffer size of GDB payload data */
+       SIZEOF_PAYLOAD = 256, /* buffer size of GDB payload data */
 };
 
 struct gdbstub {
@@ -255,20 +255,17 @@ static void gdbstub_continue ( struct gdbstub *stub, int single_step ) {
 static void gdbstub_breakpoint ( struct gdbstub *stub ) {
        unsigned long args [ 3 ];
        int enable = stub->payload [ 0 ] == 'Z' ? 1 : 0;
-       int rc;
-
        if ( !gdbstub_get_packet_args ( stub, args, sizeof args / sizeof args [ 0 ], NULL ) ) {
                gdbstub_send_errno ( stub, POSIX_EINVAL );
                return;
        }
-       if ( ( rc = gdbmach_set_breakpoint ( args [ 0 ], args [ 1 ],
-                                            args [ 2 ], enable ) ) != 0 ) {
+       if ( gdbmach_set_breakpoint ( args [ 0 ], args [ 1 ], args [ 2 ], enable ) ) {
+               gdbstub_send_ok ( stub );
+       } else {
                /* Not supported */
                stub->len = 0;
                gdbstub_tx_packet ( stub );
-               return;
        }
-       gdbstub_send_ok ( stub );
 }
 
 static void gdbstub_rx_packet ( struct gdbstub *stub ) {
index 0c280d2..0f0f8b7 100644 (file)
@@ -76,14 +76,9 @@ int getkey ( unsigned long timeout ) {
        if ( character != ESC )
                return character;
 
-       character = getchar_timeout ( GETKEY_TIMEOUT );
-       if ( character < 0 )
-               return ESC;
-
-       if ( isalpha ( character ) )
-               return ( toupper ( character ) - 'A' + 1 );
-
        while ( ( character = getchar_timeout ( GETKEY_TIMEOUT ) ) >= 0 ) {
+               if ( character == '[' )
+                       continue;
                if ( isdigit ( character ) ) {
                        n = ( ( n * 10 ) + ( character - '0' ) );
                        continue;
index a185b82..529e3d7 100644 (file)
@@ -88,6 +88,7 @@ static void free_image ( struct refcnt *refcnt ) {
  * @ret image          Executable image
  */
 struct image * alloc_image ( struct uri *uri ) {
+       const char *name;
        struct image *image;
        int rc;
 
@@ -98,43 +99,24 @@ struct image * alloc_image ( struct uri *uri ) {
 
        /* Initialise image */
        ref_init ( &image->refcnt, free_image );
-       if ( uri && ( ( rc = image_set_uri ( image, uri ) ) != 0 ) )
-               goto err_set_uri;
+       if ( uri ) {
+               image->uri = uri_get ( uri );
+               if ( uri->path ) {
+                       name = basename ( ( char * ) uri->path );
+                       if ( ( rc = image_set_name ( image, name ) ) != 0 )
+                               goto err_set_name;
+               }
+       }
 
        return image;
 
- err_set_uri:
+ err_set_name:
        image_put ( image );
  err_alloc:
        return NULL;
 }
 
 /**
- * Set image URI
- *
- * @v image            Image
- * @v uri              New image URI
- * @ret rc             Return status code
- */
-int image_set_uri ( struct image *image, struct uri *uri ) {
-       const char *name;
-       int rc;
-
-       /* Set name, if image does not already have one */
-       if ( uri->path && ( ! ( image->name && image->name[0] ) ) ) {
-               name = basename ( ( char * ) uri->path );
-               if ( ( rc = image_set_name ( image, name ) ) != 0 )
-                       return rc;
-       }
-
-       /* Update image URI */
-       uri_put ( image->uri );
-       image->uri = uri_get ( uri );
-
-       return 0;
-}
-
-/**
  * Set image name
  *
  * @v image            Image
@@ -191,7 +173,7 @@ static int image_probe ( struct image *image ) {
                        image->type = type;
                        DBGC ( image, "IMAGE %s is %s\n",
                               image->name, type->name );
-                       return 0;
+                       break;
                }
                DBGC ( image, "IMAGE %s is not %s: %s\n", image->name,
                       type->name, strerror ( rc ) );
index 0ee53e0..3e52ada 100644 (file)
@@ -47,45 +47,20 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  */
 struct io_buffer * alloc_iob_raw ( size_t len, size_t align, size_t offset ) {
        struct io_buffer *iobuf;
-       size_t padding;
-       size_t threshold;
-       unsigned int align_log2;
        void *data;
 
-       /* Calculate padding required below alignment boundary to
-        * ensure that a correctly aligned inline struct io_buffer
-        * could fit (regardless of the requested offset).
-        */
-       padding = ( sizeof ( *iobuf ) + __alignof__ ( *iobuf ) - 1 );
+       /* Align buffer length to ensure that struct io_buffer is aligned */
+       len = ( len + __alignof__ ( *iobuf ) - 1 ) &
+               ~( __alignof__ ( *iobuf ) - 1 );
 
-       /* Round up requested alignment to at least the size of the
-        * padding, to simplify subsequent calculations.
-        */
-       if ( align < padding )
-               align = padding;
+       /* Round up alignment to the nearest power of two */
+       align = ( 1 << fls ( align - 1 ) );
 
-       /* Round up alignment to the nearest power of two, avoiding
-        * a potentially undefined shift operation.
+       /* Allocate buffer plus descriptor as a single unit, unless
+        * doing so will push the total size over the alignment
+        * boundary.
         */
-       align_log2 = fls ( align - 1 );
-       if ( align_log2 >= ( 8 * sizeof ( align ) ) )
-               return NULL;
-       align = ( 1UL << align_log2 );
-
-       /* Calculate length threshold */
-       assert ( align >= padding );
-       threshold = ( align - padding );
-
-       /* Allocate buffer plus an inline descriptor as a single unit,
-        * unless doing so would push the total size over the
-        * alignment boundary.
-        */
-       if ( len <= threshold ) {
-
-               /* Round up buffer length to ensure that struct
-                * io_buffer is aligned.
-                */
-               len += ( ( - len - offset ) & ( __alignof__ ( *iobuf ) - 1 ) );
+       if ( ( len + sizeof ( *iobuf ) ) <= align ) {
 
                /* Allocate memory for buffer plus descriptor */
                data = malloc_dma_offset ( len + sizeof ( *iobuf ), align,
diff --git a/roms/ipxe/src/core/iomap_virt.c b/roms/ipxe/src/core/iomap_virt.c
deleted file mode 100644 (file)
index c7f4872..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * iPXE I/O mapping API using phys_to_virt()
- *
- */
-
-#include <ipxe/iomap.h>
-
-PROVIDE_IOMAP_INLINE ( virt, ioremap );
-PROVIDE_IOMAP_INLINE ( virt, iounmap );
-PROVIDE_IOMAP_INLINE ( virt, io_to_bus );
index 32c2035..b120c03 100644 (file)
@@ -275,7 +275,7 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
        size_t align_mask;
        size_t actual_size;
        size_t pre_size;
-       size_t post_size;
+       ssize_t post_size;
        struct memory_block *pre;
        struct memory_block *post;
        void *ptr;
@@ -291,16 +291,6 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
         */
        actual_size = ( ( size + MIN_MEMBLOCK_SIZE - 1 ) &
                        ~( MIN_MEMBLOCK_SIZE - 1 ) );
-       if ( ! actual_size ) {
-               /* The requested size is not permitted to be zero.  A
-                * zero result at this point indicates that either the
-                * original requested size was zero, or that unsigned
-                * integer overflow has occurred.
-                */
-               ptr = NULL;
-               goto done;
-       }
-       assert ( actual_size >= size );
        align_mask = ( ( align - 1 ) | ( MIN_MEMBLOCK_SIZE - 1 ) );
 
        DBGC2 ( &heap, "Allocating %#zx (aligned %#zx+%zx)\n",
@@ -310,55 +300,55 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
                list_for_each_entry ( block, &free_blocks, list ) {
                        pre_size = ( ( offset - virt_to_phys ( block ) )
                                     & align_mask );
-                       if ( ( block->size < pre_size ) ||
-                            ( ( block->size - pre_size ) < actual_size ) )
-                               continue;
                        post_size = ( block->size - pre_size - actual_size );
-                       /* Split block into pre-block, block, and
-                        * post-block.  After this split, the "pre"
-                        * block is the one currently linked into the
-                        * free list.
-                        */
-                       pre   = block;
-                       block = ( ( ( void * ) pre   ) + pre_size );
-                       post  = ( ( ( void * ) block ) + actual_size );
-                       DBGC2 ( &heap, "[%p,%p) -> [%p,%p) + [%p,%p)\n", pre,
-                               ( ( ( void * ) pre ) + pre->size ), pre, block,
-                               post, ( ( ( void * ) pre ) + pre->size ) );
-                       /* If there is a "post" block, add it in to
-                        * the free list.  Leak it if it is too small
-                        * (which can happen only at the very end of
-                        * the heap).
-                        */
-                       if ( post_size >= MIN_MEMBLOCK_SIZE ) {
-                               VALGRIND_MAKE_MEM_UNDEFINED ( post,
-                                                             sizeof ( *post ));
-                               post->size = post_size;
-                               list_add ( &post->list, &pre->list );
-                       }
-                       /* Shrink "pre" block, leaving the main block
-                        * isolated and no longer part of the free
-                        * list.
-                        */
-                       pre->size = pre_size;
-                       /* If there is no "pre" block, remove it from
-                        * the list.  Also remove it (i.e. leak it) if
-                        * it is too small, which can happen only at
-                        * the very start of the heap.
-                        */
-                       if ( pre_size < MIN_MEMBLOCK_SIZE ) {
-                               list_del ( &pre->list );
-                               VALGRIND_MAKE_MEM_NOACCESS ( pre,
-                                                            sizeof ( *pre ) );
+                       if ( post_size >= 0 ) {
+                               /* Split block into pre-block, block, and
+                                * post-block.  After this split, the "pre"
+                                * block is the one currently linked into the
+                                * free list.
+                                */
+                               pre   = block;
+                               block = ( ( ( void * ) pre   ) + pre_size );
+                               post  = ( ( ( void * ) block ) + actual_size );
+                               DBGC2 ( &heap, "[%p,%p) -> [%p,%p) + [%p,%p)\n",
+                                       pre, ( ( ( void * ) pre ) + pre->size ),
+                                       pre, block, post,
+                                       ( ( ( void * ) pre ) + pre->size ) );
+                               /* If there is a "post" block, add it in to
+                                * the free list.  Leak it if it is too small
+                                * (which can happen only at the very end of
+                                * the heap).
+                                */
+                               if ( (size_t) post_size >= MIN_MEMBLOCK_SIZE ) {
+                                       VALGRIND_MAKE_MEM_UNDEFINED
+                                               ( post, sizeof ( *post ) );
+                                       post->size = post_size;
+                                       list_add ( &post->list, &pre->list );
+                               }
+                               /* Shrink "pre" block, leaving the main block
+                                * isolated and no longer part of the free
+                                * list.
+                                */
+                               pre->size = pre_size;
+                               /* If there is no "pre" block, remove it from
+                                * the list.  Also remove it (i.e. leak it) if
+                                * it is too small, which can happen only at
+                                * the very start of the heap.
+                                */
+                               if ( pre_size < MIN_MEMBLOCK_SIZE ) {
+                                       list_del ( &pre->list );
+                                       VALGRIND_MAKE_MEM_NOACCESS
+                                               ( pre, sizeof ( *pre ) );
+                               }
+                               /* Update total free memory */
+                               freemem -= actual_size;
+                               /* Return allocated block */
+                               DBGC2 ( &heap, "Allocated [%p,%p)\n", block,
+                                       ( ( ( void * ) block ) + size ) );
+                               ptr = block;
+                               VALGRIND_MAKE_MEM_UNDEFINED ( ptr, size );
+                               goto done;
                        }
-                       /* Update total free memory */
-                       freemem -= actual_size;
-                       /* Return allocated block */
-                       DBGC2 ( &heap, "Allocated [%p,%p)\n", block,
-                               ( ( ( void * ) block ) + size ) );
-                       ptr = block;
-                       VALGRIND_MAKE_MEM_UNDEFINED ( ptr, size );
-                       goto done;
                }
 
                /* Try discarding some cached data to free up memory */
@@ -515,8 +505,6 @@ void * realloc ( void *old_ptr, size_t new_size ) {
        if ( new_size ) {
                new_total_size = ( new_size +
                                   offsetof ( struct autosized_block, data ) );
-               if ( new_total_size < new_size )
-                       return NULL;
                new_block = alloc_memblock ( new_total_size, 1, 0 );
                if ( ! new_block )
                        return NULL;
diff --git a/roms/ipxe/src/core/memblock.c b/roms/ipxe/src/core/memblock.c
new file mode 100644 (file)
index 0000000..aecddc2
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+/** @file
+ *
+ * Largest memory block
+ *
+ */
+
+#include <stdint.h>
+#include <ipxe/uaccess.h>
+#include <ipxe/io.h>
+#include <ipxe/memblock.h>
+
+/**
+ * Find largest usable memory region
+ *
+ * @ret start          Start of region
+ * @ret len            Length of region
+ */
+size_t largest_memblock ( userptr_t *start ) {
+       struct memory_map memmap;
+       struct memory_region *region;
+       physaddr_t max = ~( ( physaddr_t ) 0 );
+       physaddr_t region_start;
+       physaddr_t region_end;
+       size_t region_len;
+       unsigned int i;
+       size_t len = 0;
+
+       /* Avoid returning uninitialised data on error */
+       *start = UNULL;
+
+       /* Scan through all memory regions */
+       get_memmap ( &memmap );
+       for ( i = 0 ; i < memmap.count ; i++ ) {
+               region = &memmap.regions[i];
+               DBG ( "Considering [%llx,%llx)\n", region->start, region->end );
+
+               /* Truncate block to maximum physical address */
+               if ( region->start > max ) {
+                       DBG ( "...starts after maximum address %lx\n", max );
+                       continue;
+               }
+               region_start = region->start;
+               if ( region->end > max ) {
+                       DBG ( "...end truncated to maximum address %lx\n", max);
+                       region_end = 0; /* =max, given the wraparound */
+               } else {
+                       region_end = region->end;
+               }
+               region_len = ( region_end - region_start );
+
+               /* Use largest block */
+               if ( region_len > len ) {
+                       DBG ( "...new best block found\n" );
+                       *start = phys_to_user ( region_start );
+                       len = region_len;
+               }
+       }
+
+       return len;
+}
index 1098bd7..fab3e5f 100644 (file)
@@ -145,7 +145,7 @@ static int memmap_settings_fetch ( struct settings *settings,
        unsigned int i;
        unsigned int count;
 
-       DBGC ( settings, "MEMMAP start %ld count %ld %s%s%s%s scale %ld\n",
+       DBGC ( settings, "MEMMAP start %d count %d %s%s%s%s scale %d\n",
               MEMMAP_START ( setting->tag ), MEMMAP_COUNT ( setting->tag ),
               ( MEMMAP_INCLUDE_START ( setting->tag ) ? "start" : "" ),
               ( ( MEMMAP_INCLUDE_START ( setting->tag ) &&
index c12bd3c..41e18f8 100644 (file)
@@ -65,10 +65,6 @@ struct pixel_buffer * alloc_pixbuf ( unsigned int width, unsigned int height ) {
        pixbuf->height = height;
        pixbuf->len = ( width * height * sizeof ( uint32_t ) );
 
-       /* Check for multiplication overflow */
-       if ( ( ( pixbuf->len / sizeof ( uint32_t ) ) / width ) != height )
-               goto err_overflow;
-
        /* Allocate pixel data buffer */
        pixbuf->data = umalloc ( pixbuf->len );
        if ( ! pixbuf->data )
@@ -77,7 +73,6 @@ struct pixel_buffer * alloc_pixbuf ( unsigned int width, unsigned int height ) {
        return pixbuf;
 
  err_alloc_data:
- err_overflow:
        pixbuf_put ( pixbuf );
  err_alloc_pixbuf:
        return NULL;
index 975a03c..a74175a 100644 (file)
@@ -18,8 +18,6 @@ static int32_t rnd_seed = 0;
  */
 void srandom ( unsigned int seed ) {
        rnd_seed = seed;
-       if ( ! rnd_seed )
-               rnd_seed = 4; /* Chosen by fair dice roll */
 }
 
 /**
index dd22f67..4ce0255 100644 (file)
@@ -30,7 +30,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  */
 
 #include <stddef.h>
-#include <string.h>
 #include <ipxe/init.h>
 #include <ipxe/uart.h>
 #include <ipxe/console.h>
index 9cae0ca..12e6c7d 100644 (file)
@@ -1474,9 +1474,9 @@ struct setting * find_setting ( const char *name ) {
  * @v name             Name
  * @ret tag            Tag number, or 0 if not a valid number
  */
-static unsigned long parse_setting_tag ( const char *name ) {
+static unsigned int parse_setting_tag ( const char *name ) {
        char *tmp = ( ( char * ) name );
-       unsigned long tag = 0;
+       unsigned int tag = 0;
 
        while ( 1 ) {
                tag = ( ( tag << 8 ) | strtoul ( tmp, &tmp, 0 ) );
@@ -1666,43 +1666,15 @@ const struct setting_type setting_type_string __setting_type = {
        .format = format_string_setting,
 };
 
-/**
- * Parse URI-encoded string setting value
+/** A URI-encoded string setting type
  *
- * @v type             Setting type
- * @v value            Formatted setting value
- * @v buf              Buffer to contain raw value
- * @v len              Length of buffer
- * @ret len            Length of raw value, or negative error
- */
-static int parse_uristring_setting ( const struct setting_type *type __unused,
-                                    const char *value, void *buf, size_t len ){
-
-       return uri_decode ( value, buf, len );
-}
-
-/**
- * Format URI-encoded string setting value
- *
- * @v type             Setting type
- * @v raw              Raw setting value
- * @v raw_len          Length of raw setting value
- * @v buf              Buffer to contain formatted value
- * @v len              Length of buffer
- * @ret len            Length of formatted value, or negative error
+ * This setting type is obsolete; the name ":uristring" is retained to
+ * avoid breaking existing scripts.
  */
-static int format_uristring_setting ( const struct setting_type *type __unused,
-                                     const void *raw, size_t raw_len,
-                                     char *buf, size_t len ) {
-
-       return uri_encode ( 0, raw, raw_len, buf, len );
-}
-
-/** A URI-encoded string setting type */
 const struct setting_type setting_type_uristring __setting_type = {
        .name = "uristring",
-       .parse = parse_uristring_setting,
-       .format = format_uristring_setting,
+       .parse = parse_string_setting,
+       .format = format_string_setting,
 };
 
 /**
@@ -2232,10 +2204,6 @@ static int format_busdevfn_setting ( const struct setting_type *type __unused,
                                     const void *raw, size_t raw_len, char *buf,
                                     size_t len ) {
        unsigned long busdevfn;
-       unsigned int seg;
-       unsigned int bus;
-       unsigned int slot;
-       unsigned int func;
        int check_len;
 
        /* Extract numeric value */
@@ -2244,14 +2212,9 @@ static int format_busdevfn_setting ( const struct setting_type *type __unused,
                return check_len;
        assert ( check_len == ( int ) raw_len );
 
-       /* Extract PCI address components */
-       seg = PCI_SEG ( busdevfn );
-       bus = PCI_BUS ( busdevfn );
-       slot = PCI_SLOT ( busdevfn );
-       func = PCI_FUNC ( busdevfn );
-
        /* Format value */
-       return snprintf ( buf, len, "%04x:%02x:%02x.%x", seg, bus, slot, func );
+       return snprintf ( buf, len, "%02lx:%02lx.%lx", PCI_BUS ( busdevfn ),
+                         PCI_SLOT ( busdevfn ), PCI_FUNC ( busdevfn ) );
 }
 
 /** PCI bus:dev.fn setting type */
index 5a185e6..3e658e5 100644 (file)
@@ -81,7 +81,7 @@ void * generic_memmove ( void *dest, const void *src, size_t len ) {
        uint8_t *dest_bytes = ( dest + len );
 
        if ( dest < src )
-               return generic_memcpy ( dest, src, len );
+               return memcpy ( dest, src, len );
        while ( len-- )
                *(--dest_bytes) = *(--src_bytes);
        return dest;
index c353ac5..29a924e 100644 (file)
@@ -43,9 +43,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  * 400.
  */
 
-/** Current system clock offset */
-signed long time_offset;
-
 /** Days of week (for debugging) */
 static const char *weekdays[] = {
        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
index ca945cf..dbd89f1 100644 (file)
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <unistd.h>
-#include <ipxe/process.h>
-#include <ipxe/console.h>
-#include <ipxe/keys.h>
-#include <ipxe/nap.h>
 
 /**
  * Delay for a fixed number of milliseconds
@@ -40,24 +36,12 @@ void mdelay ( unsigned long msecs ) {
 }
 
 /**
- * Sleep (interruptibly) for a fixed number of seconds
+ * Delay for a fixed number of seconds
  *
  * @v secs             Number of seconds for which to delay
- * @ret secs           Number of seconds remaining, if interrupted
  */
 unsigned int sleep ( unsigned int secs ) {
-       unsigned long start = currticks();
-       unsigned long now;
-
-       for ( ; secs ; secs-- ) {
-               while ( ( ( now = currticks() ) - start ) < TICKS_PER_SEC ) {
-                       step();
-                       if ( iskey() && ( getchar() == CTRL_C ) )
-                               return secs;
-                       cpu_nap();
-               }
-               start = now;
-       }
-
+       while ( secs-- )
+               mdelay ( 1000 );
        return 0;
 }
index 73ad2b2..3b5f270 100644 (file)
@@ -36,23 +36,18 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ctype.h>
 #include <ipxe/vsprintf.h>
 #include <ipxe/params.h>
-#include <ipxe/tcpip.h>
 #include <ipxe/uri.h>
 
 /**
- * Decode URI field
+ * Decode URI field (in place)
  *
- * @v encoded          Encoded field
- * @v buf              Data buffer
- * @v len              Length
- * @ret len            Length of data
+ * @v string           String
  *
  * URI decoding can never increase the length of a string; we can
  * therefore safely decode in place.
  */
-size_t uri_decode ( const char *encoded, void *buf, size_t len ) {
-       uint8_t *out = buf;
-       unsigned int count = 0;
+static void uri_decode ( char *string ) {
+       char *dest = string;
        char hexbuf[3];
        char *hexbuf_end;
        char c;
@@ -60,42 +55,18 @@ size_t uri_decode ( const char *encoded, void *buf, size_t len ) {
        unsigned int skip;
 
        /* Copy string, decoding escaped characters as necessary */
-       while ( ( c = *(encoded++) ) ) {
+       do {
+               c = *(string++);
                if ( c == '%' ) {
-                       snprintf ( hexbuf, sizeof ( hexbuf ), "%s", encoded );
+                       snprintf ( hexbuf, sizeof ( hexbuf ), "%s", string );
                        decoded = strtoul ( hexbuf, &hexbuf_end, 16 );
                        skip = ( hexbuf_end - hexbuf );
-                       encoded += skip;
+                       string += skip;
                        if ( skip )
                                c = decoded;
                }
-               if ( count < len )
-                       out[count] = c;
-               count++;
-       }
-       return count;
-}
-
-/**
- * Decode URI field in-place
- *
- * @v uri              URI
- * @v field            URI field index
- */
-static void uri_decode_inplace ( struct uri *uri, unsigned int field ) {
-       const char *encoded = uri_field ( uri, field );
-       char *decoded = ( ( char * ) encoded );
-       size_t len;
-
-       /* Do nothing if field is not present */
-       if ( ! encoded )
-               return;
-
-       /* Decode field in place */
-       len = uri_decode ( encoded, decoded, strlen ( encoded ) );
-
-       /* Terminate decoded string */
-       decoded[len] = '\0';
+               *(dest++) = c;
+       } while ( c );
 }
 
 /**
@@ -144,20 +115,15 @@ static int uri_character_escaped ( char c, unsigned int field ) {
         * '%', the full set of characters with significance to the
         * URL parser is "/#:@?".  We choose for each URI field which
         * of these require escaping in our use cases.
-        *
-        * For the scheme field (equivalently, if field is zero), we
-        * escape anything that has significance not just for our URI
-        * parser but for any other URI parsers (e.g. HTTP query
-        * string parsers, which care about '=' and '&').
         */
        static const char *escaped[URI_FIELDS] = {
-               /* Scheme or default: escape everything */
-               [URI_SCHEME]    = "/#:@?=&",
+               /* Scheme: escape everything */
+               [URI_SCHEME]    = "/#:@?",
                /* Opaque part: escape characters which would affect
                 * the reparsing of the URI, allowing everything else
                 * (e.g. ':', which will appear in iSCSI URIs).
                 */
-               [URI_OPAQUE]    = "#",
+               [URI_OPAQUE]    = "/#",
                /* User name: escape everything */
                [URI_USER]      = "/#:@?",
                /* Password: escape everything */
@@ -191,16 +157,14 @@ static int uri_character_escaped ( char c, unsigned int field ) {
 /**
  * Encode URI field
  *
+ * @v uri              URI
  * @v field            URI field index
- * @v raw              Raw data
- * @v raw_len          Length of raw data
- * @v buf              Buffer
+ * @v buf              Buffer to contain encoded string
  * @v len              Length of buffer
  * @ret len            Length of encoded string (excluding NUL)
  */
-size_t uri_encode ( unsigned int field, const void *raw, size_t raw_len,
+size_t uri_encode ( const char *string, unsigned int field,
                    char *buf, ssize_t len ) {
-       const uint8_t *raw_bytes = ( ( const uint8_t * ) raw );
        ssize_t remaining = len;
        size_t used;
        char c;
@@ -210,8 +174,7 @@ size_t uri_encode ( unsigned int field, const void *raw, size_t raw_len,
                buf[0] = '\0';
 
        /* Copy string, escaping as necessary */
-       while ( raw_len-- ) {
-               c = *(raw_bytes++);
+       while ( ( c = *(string++) ) ) {
                if ( uri_character_escaped ( c, field ) ) {
                        used = ssnprintf ( buf, remaining, "%%%02X", c );
                } else {
@@ -225,21 +188,6 @@ size_t uri_encode ( unsigned int field, const void *raw, size_t raw_len,
 }
 
 /**
- * Encode URI field string
- *
- * @v field            URI field index
- * @v string           String
- * @v buf              Buffer
- * @v len              Length of buffer
- * @ret len            Length of encoded string (excluding NUL)
- */
-size_t uri_encode_string ( unsigned int field, const char *string,
-                          char *buf, ssize_t len ) {
-
-       return uri_encode ( field, string, strlen ( string ), buf, len );
-}
-
-/**
  * Dump URI for debugging
  *
  * @v uri              URI
@@ -368,7 +316,7 @@ struct uri * parse_uri ( const char *uri_string ) {
                goto done;
 
        /* Identify net/absolute/relative path */
-       if ( uri->scheme && ( strncmp ( path, "//", 2 ) == 0 ) ) {
+       if ( strncmp ( path, "//", 2 ) == 0 ) {
                /* Net path.  If this is terminated by the first '/'
                 * of an absolute path, then we have no space for a
                 * terminator after the authority field, so shuffle
@@ -419,11 +367,13 @@ struct uri * parse_uri ( const char *uri_string ) {
                uri->port = tmp;
        }
 
- done:
        /* Decode fields in-place */
-       for ( field = 0 ; field < URI_FIELDS ; field++ )
-               uri_decode_inplace ( uri, field );
+       for ( field = 0 ; field < URI_FIELDS ; field++ ) {
+               if ( uri_field ( uri, field ) )
+                       uri_decode ( ( char * ) uri_field ( uri, field ) );
+       }
 
+ done:
        DBGC ( uri, "URI parsed \"%s\" to", uri_string );
        uri_dump ( uri );
        DBGC ( uri, "\n" );
@@ -456,8 +406,10 @@ unsigned int uri_port ( const struct uri *uri, unsigned int default_port ) {
  */
 size_t format_uri ( const struct uri *uri, char *buf, size_t len ) {
        static const char prefixes[URI_FIELDS] = {
+               [URI_OPAQUE] = ':',
                [URI_PASSWORD] = ':',
                [URI_PORT] = ':',
+               [URI_PATH] = '/',
                [URI_QUERY] = '?',
                [URI_FRAGMENT] = '#',
        };
@@ -484,19 +436,21 @@ size_t format_uri ( const struct uri *uri, char *buf, size_t len ) {
                prefix = prefixes[field];
                if ( ( field == URI_HOST ) && ( uri->user != NULL ) )
                        prefix = '@';
+               if ( ( field == URI_PATH ) && ( uri->path[0] == '/' ) )
+                       prefix = '\0';
                if ( prefix ) {
                        used += ssnprintf ( ( buf + used ), ( len - used ),
                                            "%c", prefix );
                }
 
                /* Encode this field */
-               used += uri_encode_string ( field, uri_field ( uri, field ),
-                                           ( buf + used ), ( len - used ) );
+               used += uri_encode ( uri_field ( uri, field ), field,
+                                    ( buf + used ), ( len - used ) );
 
                /* Suffix this field, if applicable */
-               if ( field == URI_SCHEME ) {
+               if ( ( field == URI_SCHEME ) && ( ! uri->opaque ) ) {
                        used += ssnprintf ( ( buf + used ), ( len - used ),
-                                           ":%s", ( uri->host ? "//" : "" ) );
+                                           "://" );
                }
        }
 
@@ -602,7 +556,7 @@ struct uri * uri_dup ( const struct uri *uri ) {
  *
  * @v base_uri         Base path
  * @v relative_uri     Relative path
- * @ret resolved_uri   Resolved path, or NULL on failure
+ * @ret resolved_uri   Resolved path
  *
  * Takes a base path (e.g. "/var/lib/tftpboot/vmlinuz" and a relative
  * path (e.g. "initrd.gz") and produces a new path
@@ -613,8 +567,9 @@ struct uri * uri_dup ( const struct uri *uri ) {
  */
 char * resolve_path ( const char *base_path,
                      const char *relative_path ) {
-       char *base_copy;
-       char *base_tmp;
+       size_t base_len = ( strlen ( base_path ) + 1 );
+       char base_path_copy[base_len];
+       char *base_tmp = base_path_copy;
        char *resolved;
 
        /* If relative path is absolute, just re-use it */
@@ -622,12 +577,8 @@ char * resolve_path ( const char *base_path,
                return strdup ( relative_path );
 
        /* Create modifiable copy of path for dirname() */
-       base_copy = strdup ( base_path );
-       if ( ! base_copy )
-               return NULL;
-
-       /* Strip filename portion of base path */
-       base_tmp = dirname ( base_copy );
+       memcpy ( base_tmp, base_path, base_len );
+       base_tmp = dirname ( base_tmp );
 
        /* Process "./" and "../" elements */
        while ( *relative_path == '.' ) {
@@ -657,8 +608,8 @@ char * resolve_path ( const char *base_path,
        if ( asprintf ( &resolved, "%s%s%s", base_tmp,
                        ( ( base_tmp[ strlen ( base_tmp ) - 1 ] == '/' ) ?
                          "" : "/" ), relative_path ) < 0 )
-               resolved = NULL;
-       free ( base_copy );
+               return NULL;
+
        return resolved;
 }
 
@@ -667,7 +618,7 @@ char * resolve_path ( const char *base_path,
  *
  * @v base_uri         Base URI, or NULL
  * @v relative_uri     Relative URI
- * @ret resolved_uri   Resolved URI, or NULL on failure
+ * @ret resolved_uri   Resolved URI
  *
  * Takes a base URI (e.g. "http://ipxe.org/kernels/vmlinuz" and a
  * relative URI (e.g. "../initrds/initrd.gz") and produces a new URI
@@ -711,83 +662,30 @@ struct uri * resolve_uri ( const struct uri *base_uri,
 }
 
 /**
- * Construct TFTP URI from server address and filename
- *
- * @v sa_server                Server address
- * @v filename         Filename
- * @ret uri            URI, or NULL on failure
- */
-static struct uri * tftp_uri ( struct sockaddr *sa_server,
-                              const char *filename ) {
-       struct sockaddr_tcpip *st_server =
-               ( ( struct sockaddr_tcpip * ) sa_server );
-       char buf[ 6 /* "65535" + NUL */ ];
-       char *path;
-       struct uri tmp;
-       struct uri *uri = NULL;
-
-       /* Initialise TFTP URI */
-       memset ( &tmp, 0, sizeof ( tmp ) );
-       tmp.scheme = "tftp";
-
-       /* Construct TFTP server address */
-       tmp.host = sock_ntoa ( sa_server );
-       if ( ! tmp.host )
-               goto err_host;
-
-       /* Construct TFTP server port, if applicable */
-       if ( st_server->st_port ) {
-               snprintf ( buf, sizeof ( buf ), "%d",
-                          ntohs ( st_server->st_port ) );
-               tmp.port = buf;
-       }
-
-       /* Construct TFTP path */
-       if ( asprintf ( &path, "/%s", filename ) < 0 )
-               goto err_path;
-       tmp.path = path;
-
-       /* Demangle URI */
-       uri = uri_dup ( &tmp );
-       if ( ! uri )
-               goto err_uri;
-
- err_uri:
-       free ( path );
- err_path:
- err_host:
-       return uri;
-}
-
-/**
- * Construct URI from server address and filename
+ * Construct TFTP URI from next-server and filename
  *
- * @v sa_server                Server address
+ * @v next_server      Next-server address
+ * @v port             Port number, or zero to use the default port
  * @v filename         Filename
  * @ret uri            URI, or NULL on failure
  *
- * PXE TFTP filenames specified via the DHCP next-server field often
+ * TFTP filenames specified via the DHCP next-server field often
  * contain characters such as ':' or '#' which would confuse the
  * generic URI parser.  We provide a mechanism for directly
  * constructing a TFTP URI from the next-server and filename.
  */
-struct uri * pxe_uri ( struct sockaddr *sa_server, const char *filename ) {
-       struct uri *uri;
-
-       /* Fail if filename is empty */
-       if ( ! ( filename && filename[0] ) )
-               return NULL;
-
-       /* If filename is a hierarchical absolute URI, then use that
-        * URI.  (We accept only hierarchical absolute URIs, since PXE
-        * filenames sometimes start with DOS drive letters such as
-        * "C:\", which get misinterpreted as opaque absolute URIs.)
-        */
-       uri = parse_uri ( filename );
-       if ( uri && uri_is_absolute ( uri ) && ( ! uri->opaque ) )
-               return uri;
-       uri_put ( uri );
-
-       /* Otherwise, construct a TFTP URI directly */
-       return tftp_uri ( sa_server, filename );
+struct uri * tftp_uri ( struct in_addr next_server, unsigned int port,
+                       const char *filename ) {
+       char buf[ 6 /* "65535" + NUL */ ];
+       struct uri uri;
+
+       memset ( &uri, 0, sizeof ( uri ) );
+       uri.scheme = "tftp";
+       uri.host = inet_ntoa ( next_server );
+       if ( port ) {
+               snprintf ( buf, sizeof ( buf ), "%d", port );
+               uri.port = buf;
+       }
+       uri.path = filename;
+       return uri_dup ( &uri );
 }
index 9d3a97c..cb3bec5 100644 (file)
@@ -257,13 +257,11 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) {
                } else if ( *fmt == 's' ) {
                        if ( length < &type_sizes[LONG_LEN] ) {
                                ptr = va_arg ( args, char * );
-                               if ( ! ptr )
-                                       ptr = "<NULL>";
                        } else {
                                wptr = va_arg ( args, wchar_t * );
-                               if ( ! wptr )
-                                       ptr = "<NULL>";
                        }
+                       if ( ( ptr == NULL ) && ( wptr == NULL ) )
+                               ptr = "<NULL>";
                } else if ( *fmt == 'p' ) {
                        intptr_t ptrval;
 
index 9c71ffe..aca12bf 100644 (file)
@@ -82,6 +82,18 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
        __einfo_uniqify ( EINFO_ENOTTY, 0x01, "Inappropriate algorithm" )
 
 /**
+ * Invalidate ASN.1 object cursor
+ *
+ * @v cursor           ASN.1 object cursor
+ */
+void asn1_invalidate_cursor ( struct asn1_cursor *cursor ) {
+       static uint8_t asn1_invalid_object[] = { ASN1_END, 0 };
+
+       cursor->data = asn1_invalid_object;
+       cursor->len = 0;
+}
+
+/**
  * Start parsing ASN.1 object
  *
  * @v cursor           ASN.1 object cursor
index e62d833..503ce49 100644 (file)
@@ -45,7 +45,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define CERT( _index, _path )                                          \
        extern char stored_cert_ ## _index ## _data[];                  \
        extern char stored_cert_ ## _index ## _len[];                   \
-       __asm__ ( ".section \".rodata\", \"a\", " PROGBITS "\n\t"       \
+       __asm__ ( ".section \".rodata\", \"a\", @progbits\n\t"          \
                  "\nstored_cert_" #_index "_data:\n\t"                 \
                  ".incbin \"" _path "\"\n\t"                           \
                  "\nstored_cert_" #_index "_end:\n\t"                  \
index a3366e8..5c8b5e6 100644 (file)
  * You can also choose to distribute this program under the terms of
  * the Unmodified Binary Distribution Licence (as given in the file
  * COPYING.UBDL), provided that you have satisfied its requirements.
- *
- * Alternatively, you may distribute this code in source or binary
- * form, with or without modification, provided that the following
- * conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the above disclaimer.
- *
- *  2. Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the above
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
  */
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
index dc0dc0c..c1417e6 100644 (file)
  * You can also choose to distribute this program under the terms of
  * the Unmodified Binary Distribution Licence (as given in the file
  * COPYING.UBDL), provided that you have satisfied its requirements.
- *
- * Alternatively, you may distribute this code in source or binary
- * form, with or without modification, provided that the following
- * conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the above disclaimer.
- *
- *  2. Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the above
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
  */
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
index f898619..95a4619 100644 (file)
  * You can also choose to distribute this program under the terms of
  * the Unmodified Binary Distribution Licence (as given in the file
  * COPYING.UBDL), provided that you have satisfied its requirements.
- *
- * Alternatively, you may distribute this code in source or binary
- * form, with or without modification, provided that the following
- * conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the above disclaimer.
- *
- *  2. Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the above
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
  */
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
index 0982977..6c1d5de 100644 (file)
  * You can also choose to distribute this program under the terms of
  * the Unmodified Binary Distribution Licence (as given in the file
  * COPYING.UBDL), provided that you have satisfied its requirements.
- *
- * Alternatively, you may distribute this code in source or binary
- * form, with or without modification, provided that the following
- * conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the above disclaimer.
- *
- *  2. Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the above
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
  */
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
index e7adcdb..5df55bc 100644 (file)
@@ -209,10 +209,10 @@ static int ocsp_request ( struct ocsp_check *ocsp ) {
 static int ocsp_uri_string ( struct ocsp_check *ocsp ) {
        struct x509_ocsp_responder *responder =
                &ocsp->cert->extensions.auth_info.ocsp;
-       char *base64;
-       char *sep;
-       size_t base64_len;
-       size_t uri_len;
+       struct uri path_uri;
+       char *path_base64_string;
+       char *path_uri_string;
+       size_t path_len;
        size_t len;
        int rc;
 
@@ -224,44 +224,46 @@ static int ocsp_uri_string ( struct ocsp_check *ocsp ) {
                goto err_no_uri;
        }
 
-       /* Calculate base64-encoded request length */
-       base64_len = ( base64_encoded_len ( ocsp->request.builder.len )
-                      + 1 /* NUL */ );
-
-       /* Allocate and construct the base64-encoded request */
-       base64 = malloc ( base64_len );
-       if ( ! base64 ) {
+       /* Base64-encode the request as the URI path */
+       path_len = ( base64_encoded_len ( ocsp->request.builder.len )
+                    + 1 /* NUL */ );
+       path_base64_string = malloc ( path_len );
+       if ( ! path_base64_string ) {
                rc = -ENOMEM;
-               goto err_alloc_base64;
+               goto err_path_base64;
        }
        base64_encode ( ocsp->request.builder.data, ocsp->request.builder.len,
-                       base64, base64_len );
+                       path_base64_string, path_len );
 
-       /* Calculate URI-encoded base64-encoded request length */
-       uri_len = ( uri_encode ( URI_PATH, base64, ( base64_len - 1 /* NUL */ ),
-                                NULL, 0 ) + 1 /* NUL */ );
+       /* URI-encode the Base64-encoded request */
+       memset ( &path_uri, 0, sizeof ( path_uri ) );
+       path_uri.path = path_base64_string;
+       path_uri_string = format_uri_alloc ( &path_uri );
+       if ( ! path_uri_string ) {
+               rc = -ENOMEM;
+               goto err_path_uri;
+       }
 
-       /* Allocate and construct the URI string */
-       len = ( responder->uri.len + 1 /* possible "/" */ + uri_len );
+       /* Construct URI string */
+       len = ( responder->uri.len + strlen ( path_uri_string ) + 1 /* NUL */ );
        ocsp->uri_string = zalloc ( len );
        if ( ! ocsp->uri_string ) {
                rc = -ENOMEM;
-               goto err_alloc_uri;
+               goto err_ocsp_uri;
        }
        memcpy ( ocsp->uri_string, responder->uri.data, responder->uri.len );
-       sep = &ocsp->uri_string[ responder->uri.len - 1 ];
-       if ( *sep != '/' )
-               *(++sep) = '/';
-       uri_encode ( URI_PATH, base64, base64_len, ( sep + 1 ), uri_len );
+       strcpy ( &ocsp->uri_string[responder->uri.len], path_uri_string );
        DBGC2 ( ocsp, "OCSP %p \"%s\" URI is %s\n",
                ocsp, x509_name ( ocsp->cert ), ocsp->uri_string );
 
        /* Success */
        rc = 0;
 
- err_alloc_uri:
-       free ( base64 );
- err_alloc_base64:
+ err_ocsp_uri:
+       free ( path_uri_string );
+ err_path_uri:
+       free ( path_base64_string );
+ err_path_base64:
  err_no_uri:
        return rc;
 }
index 7ef0488..a6043bd 100644 (file)
@@ -54,7 +54,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /* Raw private key data */
 extern char private_key_data[];
 extern char private_key_len[];
-__asm__ ( ".section \".rodata\", \"a\", " PROGBITS "\n\t"
+__asm__ ( ".section \".rodata\", \"a\", @progbits\n\t"
          "\nprivate_key_data:\n\t"
 #ifdef PRIVATE_KEY
          ".incbin \"" PRIVATE_KEY "\"\n\t"
@@ -69,12 +69,6 @@ struct asn1_cursor private_key = {
        .len = ( ( size_t ) private_key_len ),
 };
 
-/** Default private key */
-static struct asn1_cursor default_private_key = {
-       .data = private_key_data,
-       .len = ( ( size_t ) private_key_len ),
-};
-
 /** Private key setting */
 static struct setting privkey_setting __setting ( SETTING_CRYPTO, privkey ) = {
        .name = "privkey",
@@ -98,8 +92,8 @@ static int privkey_apply_settings ( void ) {
        if ( ALLOW_KEY_OVERRIDE ) {
 
                /* Restore default private key */
-               memcpy ( &private_key, &default_private_key,
-                        sizeof ( private_key ) );
+               private_key.data = private_key_data;
+               private_key.len = ( ( size_t ) private_key_len );
 
                /* Fetch new private key, if any */
                free ( key_data );
index a5a77e3..943b288 100644 (file)
  * You can also choose to distribute this program under the terms of
  * the Unmodified Binary Distribution Licence (as given in the file
  * COPYING.UBDL), provided that you have satisfied its requirements.
- *
- * Alternatively, you may distribute this code in source or binary
- * form, with or without modification, provided that the following
- * conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the above disclaimer.
- *
- *  2. Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the above
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
  */
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
index f7b9dcf..00ea164 100644 (file)
@@ -93,14 +93,13 @@ struct x509_root root_certificates = {
  * a rebuild.
  */
 static void rootcert_init ( void ) {
-       static int initialised;
        void *external = NULL;
        int len;
 
        /* Allow trusted root certificates to be overridden only if
         * not explicitly specified at build time.
         */
-       if ( ALLOW_TRUST_OVERRIDE && ( ! initialised ) ) {
+       if ( ALLOW_TRUST_OVERRIDE ) {
 
                /* Fetch copy of "trust" setting, if it exists.  This
                 * memory will never be freed.
@@ -110,9 +109,6 @@ static void rootcert_init ( void ) {
                        root_certificates.fingerprints = external;
                        root_certificates.count = ( len / FINGERPRINT_LEN );
                }
-
-               /* Prevent subsequent modifications */
-               initialised = 1;
        }
 
        DBGC ( &root_certificates, "ROOTCERT using %d %s certificate(s):\n",
@@ -122,6 +118,6 @@ static void rootcert_init ( void ) {
 }
 
 /** Root certificate initialiser */
-struct startup_fn rootcert_startup_fn __startup_fn ( STARTUP_LATE ) = {
-       .startup = rootcert_init,
+struct init_fn rootcert_init_fn __init_fn ( INIT_LATE ) = {
+       .initialise = rootcert_init,
 };
index 91a808d..6aabd76 100644 (file)
@@ -260,7 +260,6 @@ static int ibft_fill_nic ( struct ibft_nic *nic,
        ibft_set_ipaddr_setting ( NULL, &nic->dns[0], &dns_setting,
                                  ( sizeof ( nic->dns ) /
                                    sizeof ( nic->dns[0] ) ) );
-       ibft_set_ipaddr_setting ( parent, &nic->dhcp, &dhcp_server_setting, 1 );
        DBG ( "iBFT NIC DNS = %s", ibft_ipaddr ( &nic->dns[0] ) );
        DBG ( ", %s\n", ibft_ipaddr ( &nic->dns[1] ) );
        if ( ( rc = ibft_set_string_setting ( NULL, strings, &nic->hostname,
index 06b36a7..6fbedd9 100644 (file)
@@ -175,7 +175,7 @@ void adjust_pci_device ( struct pci_device *pci ) {
  * @ret rc             Return status code
  */
 int pci_read_config ( struct pci_device *pci ) {
-       uint32_t busdevfn;
+       uint16_t busdevfn;
        uint8_t hdrtype;
        uint32_t tmp;
 
@@ -203,8 +203,8 @@ int pci_read_config ( struct pci_device *pci ) {
        pci_read_bases ( pci );
 
        /* Initialise generic device component */
-       snprintf ( pci->dev.name, sizeof ( pci->dev.name ), "%04x:%02x:%02x.%x",
-                  PCI_SEG ( pci->busdevfn ), PCI_BUS ( pci->busdevfn ),
+       snprintf ( pci->dev.name, sizeof ( pci->dev.name ),
+                  "PCI%02x:%02x.%x", PCI_BUS ( pci->busdevfn ),
                   PCI_SLOT ( pci->busdevfn ), PCI_FUNC ( pci->busdevfn ) );
        pci->dev.desc.bus_type = BUS_TYPE_PCI;
        pci->dev.desc.location = pci->busdevfn;
@@ -232,7 +232,7 @@ int pci_find_next ( struct pci_device *pci, unsigned int busdevfn ) {
 
        /* Determine number of PCI buses */
        if ( ! end )
-               end = PCI_BUSDEVFN ( 0, pci_num_bus(), 0, 0 );
+               end = PCI_BUSDEVFN ( pci_num_bus(), 0, 0 );
 
        /* Find next PCI device, if any */
        for ( ; busdevfn < end ; busdevfn++ ) {
index 9800555..1cb9fa5 100644 (file)
@@ -70,7 +70,7 @@ static int pci_settings_fetch ( struct settings *settings __unused,
        unsigned int i;
 
        /* Extract busdevfn, offset, and length from tag */
-       tag_busdevfn = ( setting->tag >> 16 );
+       tag_busdevfn = ( ( setting->tag >> 16 ) & 0xffff );
        tag_offset = ( ( setting->tag >> 8 ) & 0xff );
        tag_len = ( ( setting->tag >> 0 ) & 0xff );
 
diff --git a/roms/ipxe/src/drivers/bus/pciea.c b/roms/ipxe/src/drivers/bus/pciea.c
deleted file mode 100644 (file)
index aaa69cf..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <errno.h>
-#include <ipxe/pci.h>
-#include <ipxe/pciea.h>
-
-/** @file
- *
- * PCI Enhanced Allocation
- *
- */
-
-/**
- * Locate PCI Enhanced Allocation BAR equivalent entry
- *
- * @v pci              PCI device
- * @v bei              BAR equivalent indicator
- * @ret offset         PCI Enhanced Allocation entry offset, or negative error
- */
-static int pciea_offset ( struct pci_device *pci, unsigned int bei ) {
-       uint8_t entries;
-       uint32_t desc;
-       unsigned int i;
-       int offset;
-
-       /* Locate Enhanced Allocation capability */
-       offset = pci_find_capability ( pci, PCI_CAP_ID_EA );
-       if ( offset < 0 )
-               return offset;
-
-       /* Get number of entries */
-       pci_read_config_byte ( pci, ( offset + PCIEA_ENTRIES ), &entries );
-       entries &= PCIEA_ENTRIES_MASK;
-
-       /* Locate first entry */
-       offset += PCIEA_FIRST;
-
-       /* Search for a matching entry */
-       for ( i = 0 ; i < entries ; i++ ) {
-
-               /* Read entry descriptor */
-               pci_read_config_dword ( pci, offset, &desc );
-
-               /* Check for a matching entry */
-               if ( ( desc & PCIEA_DESC_ENABLED ) &&
-                    ( bei == PCIEA_DESC_BEI ( desc ) ) )
-                       return offset;
-
-               /* Move to next entry */
-               offset += ( ( PCIEA_DESC_SIZE ( desc ) + 1 ) << 2 );
-       }
-
-       return -ENOENT;
-}
-
-/**
- * Read PCI Enhanced Allocation BAR equivalent value
- *
- * @v pci              PCI device
- * @v bei              BAR equivalent indicator
- * @v low_offset       Offset to low dword of value
- * @ret value          BAR equivalent value
- */
-static unsigned long pciea_bar_value ( struct pci_device *pci, unsigned int bei,
-                                      unsigned int low_offset ) {
-       uint32_t low;
-       uint32_t high;
-       int offset;
-
-       /* Locate Enhanced Allocation offset for this BEI */
-       offset = pciea_offset ( pci, bei );
-       if ( offset < 0 )
-               return 0;
-
-       /* Read BAR equivalent */
-       offset += low_offset;
-       pci_read_config_dword ( pci, offset, &low );
-       if ( low & PCIEA_LOW_ATTR_64BIT ) {
-               offset += PCIEA_LOW_HIGH;
-               pci_read_config_dword ( pci, offset, &high );
-               if ( high ) {
-                       if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) {
-                               return ( ( ( uint64_t ) high << 32 ) | low );
-                       } else {
-                               DBGC ( pci, PCI_FMT " unhandled 64-bit EA BAR "
-                                      "%08x%08x\n",
-                                      PCI_ARGS ( pci ), high, low );
-                               return 0;
-                       }
-               }
-       }
-       return low;
-}
-
-/**
- * Find the start of a PCI Enhanced Allocation BAR equivalent
- *
- * @v pci              PCI device
- * @v bei              BAR equivalent indicator
- * @ret start          BAR start address
- *
- * If the address exceeds the size of an unsigned long (i.e. if a
- * 64-bit BAR has a non-zero high dword on a 32-bit machine), the
- * return value will be zero.
- */
-unsigned long pciea_bar_start ( struct pci_device *pci, unsigned int bei ) {
-       unsigned long base;
-
-       base = pciea_bar_value ( pci, bei, PCIEA_LOW_BASE );
-       return ( base & ~PCIEA_LOW_ATTR_MASK );
-}
-
-/**
- * Find the size of a PCI Enhanced Allocation BAR equivalent
- *
- * @v pci              PCI device
- * @v bei              BAR equivalent indicator
- * @ret size           BAR size
- */
-unsigned long pciea_bar_size ( struct pci_device *pci, unsigned int bei ) {
-       unsigned long limit;
-
-       limit = pciea_bar_value ( pci, bei, PCIEA_LOW_LIMIT );
-       return ( limit ? ( ( limit | PCIEA_LOW_ATTR_MASK ) + 1 ) : 0 );
-}
index 3082d8a..82287fb 100644 (file)
@@ -3,24 +3,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <stdint.h>
 #include <ipxe/pci.h>
 
-static int pci_find_capability_common ( struct pci_device *pci,
-                                       uint8_t pos, int cap ) {
-       uint8_t id;
-       int ttl = 48;
-
-       while ( ttl-- && pos >= 0x40 ) {
-               pos &= ~3;
-               pci_read_config_byte ( pci, pos + PCI_CAP_ID, &id );
-               DBG ( "PCI Capability: %d\n", id );
-               if ( id == 0xff )
-                       break;
-               if ( id == cap )
-                       return pos;
-               pci_read_config_byte ( pci, pos + PCI_CAP_NEXT, &pos );
-       }
-       return 0;
-}
-
 /**
  * Look for a PCI capability
  *
@@ -35,8 +17,9 @@ static int pci_find_capability_common ( struct pci_device *pci,
  */
 int pci_find_capability ( struct pci_device *pci, int cap ) {
        uint16_t status;
-       uint8_t pos;
+       uint8_t pos, id;
        uint8_t hdr_type;
+       int ttl = 48;
 
        pci_read_config_word ( pci, PCI_STATUS, &status );
        if ( ! ( status & PCI_STATUS_CAP_LIST ) )
@@ -53,28 +36,17 @@ int pci_find_capability ( struct pci_device *pci, int cap ) {
                pci_read_config_byte ( pci, PCI_CB_CAPABILITY_LIST, &pos );
                break;
        }
-       return pci_find_capability_common ( pci, pos, cap );
-}
-
-/**
- * Look for another PCI capability
- *
- * @v pci              PCI device to query
- * @v pos              Address of the current capability
- * @v cap              Capability code
- * @ret address                Address of capability, or 0 if not found
- *
- * Determine whether or not a device supports a given PCI capability
- * starting the search at a given address within the device's PCI
- * configuration space. Returns the address of the next capability
- * structure within the device's PCI configuration space, or 0 if the
- * device does not support another such capability.
- */
-int pci_find_next_capability ( struct pci_device *pci, int pos, int cap ) {
-       uint8_t new_pos;
-
-       pci_read_config_byte ( pci, pos + PCI_CAP_NEXT, &new_pos );
-       return pci_find_capability_common ( pci, new_pos, cap );
+       while ( ttl-- && pos >= 0x40 ) {
+               pos &= ~3;
+               pci_read_config_byte ( pci, pos + PCI_CAP_ID, &id );
+               DBG ( "PCI Capability: %d\n", id );
+               if ( id == 0xff )
+                       break;
+               if ( id == cap )
+                       return pos;
+               pci_read_config_byte ( pci, pos + PCI_CAP_NEXT, &pos );
+       }
+       return 0;
 }
 
 /**
index 880e3f0..2019e33 100644 (file)
@@ -243,6 +243,7 @@ int usb_endpoint_described ( struct usb_endpoint *ep,
                             struct usb_interface_descriptor *interface,
                             unsigned int type, unsigned int index ) {
        struct usb_device *usb = ep->usb;
+       struct usb_port *port = usb->port;
        struct usb_endpoint_descriptor *desc;
        struct usb_endpoint_companion_descriptor *descx;
        unsigned int sizes;
@@ -266,7 +267,7 @@ int usb_endpoint_described ( struct usb_endpoint *ep,
        /* Calculate interval */
        if ( ( type & USB_ENDPOINT_ATTR_TYPE_MASK ) ==
             USB_ENDPOINT_ATTR_INTERRUPT ) {
-               if ( usb->speed >= USB_SPEED_HIGH ) {
+               if ( port->speed >= USB_SPEED_HIGH ) {
                        /* 2^(desc->interval-1) is a microframe count */
                        interval = ( 1 << ( desc->interval - 1 ) );
                } else {
@@ -484,7 +485,7 @@ int usb_message ( struct usb_endpoint *ep, unsigned int request,
        assert ( iob_headroom ( iobuf ) >= sizeof ( *packet ) );
 
        /* Fail immediately if device has been unplugged */
-       if ( port->disconnected )
+       if ( port->speed == USB_SPEED_NONE )
                return -ENODEV;
 
        /* Reset endpoint if required */
@@ -529,11 +530,10 @@ int usb_stream ( struct usb_endpoint *ep, struct io_buffer *iobuf,
                 int terminate ) {
        struct usb_device *usb = ep->usb;
        struct usb_port *port = usb->port;
-       int zlp;
        int rc;
 
        /* Fail immediately if device has been unplugged */
-       if ( port->disconnected )
+       if ( port->speed == USB_SPEED_NONE )
                return -ENODEV;
 
        /* Reset endpoint if required */
@@ -541,13 +541,8 @@ int usb_stream ( struct usb_endpoint *ep, struct io_buffer *iobuf,
             ( ( rc = usb_endpoint_reset ( ep ) ) != 0 ) )
                return rc;
 
-       /* Append a zero-length packet if necessary */
-       zlp = terminate;
-       if ( iob_len ( iobuf ) & ( ep->mtu - 1 ) )
-               zlp = 0;
-
        /* Enqueue stream transfer */
-       if ( ( rc = ep->host->stream ( ep, iobuf, zlp ) ) != 0 ) {
+       if ( ( rc = ep->host->stream ( ep, iobuf, terminate ) ) != 0 ) {
                DBGC ( usb, "USB %s %s could not enqueue stream transfer: %s\n",
                       usb->name, usb_endpoint_name ( ep ), strerror ( rc ) );
                return rc;
@@ -601,7 +596,6 @@ void usb_complete_err ( struct usb_endpoint *ep, struct io_buffer *iobuf,
  */
 int usb_prefill ( struct usb_endpoint *ep ) {
        struct io_buffer *iobuf;
-       size_t reserve = ep->reserve;
        size_t len = ( ep->len ? ep->len : ep->mtu );
        unsigned int fill;
        int rc;
@@ -615,12 +609,11 @@ int usb_prefill ( struct usb_endpoint *ep ) {
        for ( fill = 0 ; fill < ep->max ; fill++ ) {
 
                /* Allocate I/O buffer */
-               iobuf = alloc_iob ( reserve + len );
+               iobuf = alloc_iob ( len );
                if ( ! iobuf ) {
                        rc = -ENOMEM;
                        goto err_alloc;
                }
-               iob_reserve ( iobuf, reserve );
 
                /* Add to recycled buffer list */
                list_add_tail ( &iobuf->list, &ep->recycled );
@@ -641,7 +634,6 @@ int usb_prefill ( struct usb_endpoint *ep ) {
  */
 int usb_refill ( struct usb_endpoint *ep ) {
        struct io_buffer *iobuf;
-       size_t reserve = ep->reserve;
        size_t len = ( ep->len ? ep->len : ep->mtu );
        int rc;
 
@@ -655,10 +647,9 @@ int usb_refill ( struct usb_endpoint *ep ) {
                /* Get or allocate buffer */
                if ( list_empty ( &ep->recycled ) ) {
                        /* Recycled buffer list is empty; allocate new buffer */
-                       iobuf = alloc_iob ( reserve + len );
+                       iobuf = alloc_iob ( len );
                        if ( ! iobuf )
                                return -ENOMEM;
-                       iob_reserve ( iobuf, reserve );
                } else {
                        /* Get buffer from recycled buffer list */
                        iobuf = list_first_entry ( &ep->recycled,
@@ -904,155 +895,75 @@ int usb_get_string_descriptor ( struct usb_device *usb, unsigned int index,
  */
 
 /**
- * Get USB configuration descriptor
- *
- * @v usb              USB device
- * @v index            Configuration index
- * @ret config         Configuration descriptor
- * @ret rc             Return status code
- *
- * The configuration descriptor is dynamically allocated and must
- * eventually be freed by the caller.
- */
-static int
-usb_config_descriptor ( struct usb_device *usb, unsigned int index,
-                       struct usb_configuration_descriptor **config ) {
-       struct usb_configuration_descriptor partial;
-       size_t len;
-       int rc;
-
-       /* Read first part of configuration descriptor to get size */
-       if ( ( rc = usb_get_config_descriptor ( usb, index, &partial,
-                                               sizeof ( partial ) ) ) != 0 ) {
-               DBGC ( usb, "USB %s could not get configuration descriptor %d: "
-                      "%s\n", usb->name, index, strerror ( rc ) );
-               goto err_get_partial;
-       }
-       len = le16_to_cpu ( partial.len );
-       if ( len < sizeof ( partial ) ) {
-               DBGC ( usb, "USB %s underlength configuraton descriptor %d\n",
-                      usb->name, index );
-               rc = -EINVAL;
-               goto err_partial_len;
-       }
-
-       /* Allocate buffer for whole configuration descriptor */
-       *config = malloc ( len );
-       if ( ! *config ) {
-               rc = -ENOMEM;
-               goto err_alloc_config;
-       }
-
-       /* Read whole configuration descriptor */
-       if ( ( rc = usb_get_config_descriptor ( usb, index, *config,
-                                               len ) ) != 0 ) {
-               DBGC ( usb, "USB %s could not get configuration descriptor %d: "
-                      "%s\n", usb->name, index, strerror ( rc ) );
-               goto err_get_config_descriptor;
-       }
-       if ( (*config)->len != partial.len ) {
-               DBGC ( usb, "USB %s bad configuration descriptor %d length\n",
-                      usb->name, index );
-               rc = -EINVAL;
-               goto err_config_len;
-       }
-
-       return 0;
-
- err_config_len:
- err_get_config_descriptor:
-       free ( *config );
- err_alloc_config:
- err_partial_len:
- err_get_partial:
-       return rc;
-}
-
-/**
  * Describe USB function
  *
- * @v usb              USB device
+ * @v func             USB function
  * @v config           Configuration descriptor
  * @v first            First interface number
- * @v interfaces       Interface list to fill in
- * @v desc             Function descriptor to fill in
  * @ret rc             Return status code
  */
-static int usb_describe ( struct usb_device *usb,
+static int usb_function ( struct usb_function *func,
                          struct usb_configuration_descriptor *config,
-                         unsigned int first, uint8_t *interfaces,
-                         struct usb_function_descriptor *desc ) {
+                         unsigned int first ) {
+       struct usb_device *usb = func->usb;
        struct usb_interface_association_descriptor *association;
        struct usb_interface_descriptor *interface;
        struct cdc_union_descriptor *cdc_union;
        unsigned int i;
 
-       /* Fill in vendor and product ID */
-       memset ( desc, 0, sizeof ( *desc ) );
-       desc->vendor = le16_to_cpu ( usb->device.vendor );
-       desc->product = le16_to_cpu ( usb->device.product );
-
        /* First, look for an interface association descriptor */
        association = usb_interface_association_descriptor ( config, first );
        if ( association ) {
 
                /* Sanity check */
-               assert ( association->first == first );
-               if ( ( first + association->count ) > config->interfaces ) {
+               if ( association->count > config->interfaces ) {
                        DBGC ( usb, "USB %s has invalid association [%d-%d)\n",
-                              usb->name, first, ( first + association->count));
+                              func->name, association->first,
+                              ( association->first + association->count ) );
                        return -ERANGE;
                }
 
                /* Describe function */
-               memcpy ( &desc->class, &association->class,
-                        sizeof ( desc->class ) );
-               desc->count = association->count;
+               memcpy ( &func->class, &association->class,
+                        sizeof ( func->class ) );
+               func->count = association->count;
                for ( i = 0 ; i < association->count ; i++ )
-                       interfaces[i] = ( first + i );
+                       func->interface[i] = ( association->first + i );
                return 0;
        }
 
        /* Next, look for an interface descriptor */
        interface = usb_interface_descriptor ( config, first, 0 );
        if ( ! interface ) {
-               DBGC ( usb, "USB %s has no descriptor for interface %d\n",
-                      usb->name, first );
+               DBGC ( usb, "USB %s has no interface descriptor\n",
+                      func->name );
                return -ENOENT;
        }
 
        /* Describe function */
-       memcpy ( &desc->class, &interface->class, sizeof ( desc->class ) );
-       desc->count = 1;
-       interfaces[0] = first;
+       memcpy ( &func->class, &interface->class, sizeof ( func->class ) );
+       func->count = 1;
+       func->interface[0] = first;
 
        /* Look for a CDC union descriptor, if applicable */
-       if ( ( desc->class.class.class == USB_CLASS_CDC ) &&
+       if ( ( func->class.class == USB_CLASS_CDC ) &&
             ( cdc_union = cdc_union_descriptor ( config, interface ) ) ) {
 
                /* Determine interface count */
-               desc->count = ( ( cdc_union->header.len -
+               func->count = ( ( cdc_union->header.len -
                                  offsetof ( typeof ( *cdc_union ),
                                             interface[0] ) ) /
                                sizeof ( cdc_union->interface[0] ) );
-               if ( desc->count > config->interfaces ) {
+               if ( func->count > config->interfaces ) {
                        DBGC ( usb, "USB %s has invalid union functional "
                               "descriptor with %d interfaces\n",
-                              usb->name, desc->count );
+                              func->name, func->count );
                        return -ERANGE;
                }
 
                /* Describe function */
-               for ( i = 0 ; i < desc->count ; i++ ) {
-                       if ( cdc_union->interface[i] >= config->interfaces ) {
-                               DBGC ( usb, "USB %s has invalid union "
-                                      "functional descriptor covering "
-                                      "interface %d\n", usb->name,
-                                      cdc_union->interface[i] );
-                               return -ERANGE;
-                       }
-                       interfaces[i] = cdc_union->interface[i];
-               }
+               for ( i = 0 ; i < func->count ; i++ )
+                       func->interface[i] = cdc_union->interface[i];
 
                return 0;
        }
@@ -1061,108 +972,22 @@ static int usb_describe ( struct usb_device *usb,
 }
 
 /**
- * Update list of used interface
+ * Check for a USB device ID match
  *
- * @v usb              USB device
- * @v count            Number of interfaces
- * @v interface                List of interfaces
- * @v used             List of already-used interfaces
- * @ret rc             Return status code
- */
-static int usb_used ( struct usb_device *usb, unsigned int count,
-                     uint8_t *interface, uint8_t *used ) {
-       unsigned int i;
-
-       for ( i = 0 ; i < count ; i++ ) {
-               if ( used[interface[i]] ) {
-                       DBGC ( usb, "USB %s interface %d already in use\n",
-                              usb->name, interface[i] );
-                       return -EINVAL;
-               }
-               used[interface[i]] = 1;
-       }
-       return 0;
-}
-
-/**
- * Find USB device driver
- *
- * @v desc             Function descriptor
- * @ret id             USB device ID, or NULL
- * @ret driver         USB device driver, or NULL
- */
-struct usb_driver * usb_find_driver ( struct usb_function_descriptor *desc,
-                                     struct usb_device_id **id ) {
-       struct usb_driver *driver;
-       unsigned int i;
-
-       /* Look for a matching driver */
-       for_each_table_entry ( driver, USB_DRIVERS ) {
-               for ( i = 0 ; i < driver->id_count ; i++ ) {
-
-                       /* Ignore non-matching driver class */
-                       if ( ( driver->class.class.scalar ^ desc->class.scalar )
-                            & driver->class.mask.scalar )
-                               continue;
-
-                       /* Look for a matching ID */
-                       *id = &driver->ids[i];
-                       if ( ( ( (*id)->vendor == desc->vendor ) ||
-                              ( (*id)->vendor == USB_ANY_ID ) ) &&
-                            ( ( (*id)->product == desc->product ) ||
-                              ( (*id)->product == USB_ANY_ID ) ) )
-                               return driver;
-               }
-       }
-
-       /* Not found */
-       *id = NULL;
-       return NULL;
-}
-
-/**
- * Get USB device configuration score
- *
- * @v usb              USB device
- * @v config           Configuration descriptor
- * @ret score          Device configuration score, or negative error
+ * @v func             USB function
+ * @v id               Device ID
+ * @ret matches                Device ID matches
  */
-static int usb_score ( struct usb_device *usb,
-                      struct usb_configuration_descriptor *config ) {
-       uint8_t used[config->interfaces];
-       uint8_t interface[config->interfaces];
-       struct usb_function_descriptor desc;
-       struct usb_driver *driver;
-       struct usb_device_id *id;
-       unsigned int first;
-       unsigned int score = 0;
-       int rc;
-
-       /* Identify each function in turn */
-       memset ( used, 0, sizeof ( used ) );
-       for ( first = 0 ; first < config->interfaces ; first++ ) {
-
-               /* Skip interfaces already used */
-               if ( used[first] )
-                       continue;
-
-               /* Describe function */
-               if ( ( rc = usb_describe ( usb, config, first, interface,
-                                          &desc ) ) != 0 )
-                       return rc;
-
-               /* Update used interfaces */
-               if ( ( rc = usb_used ( usb, desc.count, interface,
-                                      used ) ) != 0 )
-                       return rc;
-
-               /* Look for a driver for this function */
-               driver = usb_find_driver ( &desc, &id );
-               if ( driver )
-                       score += driver->score;
-       }
-
-       return score;
+static int
+usb_device_id_matches ( struct usb_function *func, struct usb_device_id *id ) {
+
+       return ( ( ( id->vendor == func->dev.desc.vendor ) ||
+                  ( id->vendor == USB_ANY_ID ) ) &&
+                ( ( id->product == func->dev.desc.device ) ||
+                  ( id->product == USB_ANY_ID ) ) &&
+                ( id->class.class == func->class.class ) &&
+                ( id->class.subclass == func->class.subclass ) &&
+                ( id->class.protocol == func->class.protocol ) );
 }
 
 /**
@@ -1177,32 +1002,39 @@ static int usb_probe ( struct usb_function *func,
        struct usb_device *usb = func->usb;
        struct usb_driver *driver;
        struct usb_device_id *id;
+       unsigned int i;
        int rc;
 
-       /* Identify driver */
-       driver = usb_find_driver ( &func->desc, &id );
-       if ( ! driver ) {
-               DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d has no driver\n",
-                      func->name, func->desc.vendor, func->desc.product,
-                      func->desc.class.class.class,
-                      func->desc.class.class.subclass,
-                      func->desc.class.class.protocol );
-               return -ENOENT;
-       }
+       /* Look for a matching driver */
+       for_each_table_entry ( driver, USB_DRIVERS ) {
+               for ( i = 0 ; i < driver->id_count ; i++ ) {
 
-       /* Record driver */
-       func->driver = driver;
-       func->id = id;
-       func->dev.driver_name = id->name;
+                       /* Check for a matching ID */
+                       id = &driver->ids[i];
+                       if ( ! usb_device_id_matches ( func, id ) )
+                               continue;
 
-       /* Probe driver */
-       if ( ( rc = driver->probe ( func, config ) ) != 0 ) {
-               DBGC ( usb, "USB %s failed to probe driver %s: %s\n",
-                      func->name, id->name, strerror ( rc ) );
-               return rc;
+                       /* Probe driver */
+                       if ( ( rc = driver->probe ( func, config ) ) != 0 ) {
+                               DBGC ( usb, "USB %s failed to probe driver %s: "
+                                      "%s\n", func->name, id->name,
+                                      strerror ( rc ) );
+                               /* Continue trying other drivers */
+                               continue;
+                       }
+
+                       /* Record driver */
+                       func->driver = driver;
+                       func->dev.driver_name = id->name;
+                       return 0;
+               }
        }
 
-       return 0;
+       /* No driver found */
+       DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d has no driver\n",
+              func->name, func->dev.desc.vendor, func->dev.desc.device,
+              func->class.class, func->class.subclass, func->class.protocol );
+       return -ENOENT;
 }
 
 /**
@@ -1256,45 +1088,50 @@ usb_probe_all ( struct usb_device *usb,
                           "%s-%d.%d", usb->name, config->config, first );
                INIT_LIST_HEAD ( &func->dev.children );
                func->dev.parent = bus->dev;
-               list_add_tail ( &func->list, &usb->functions );
 
                /* Identify function */
-               if ( ( rc = usb_describe ( usb, config, first, func->interface,
-                                          &func->desc ) ) != 0 )
-                       goto err_describe;
-               assert ( func->desc.count <= config->interfaces );
+               if ( ( rc = usb_function ( func, config, first ) ) != 0 )
+                       goto err_function;
+               assert ( func->count <= config->interfaces );
 
                /* Mark interfaces as used */
-               if ( ( rc = usb_used ( usb, func->desc.count, func->interface,
-                                      used ) ) != 0 )
-                       goto err_used;
+               for ( i = 0 ; i < func->count ; i++ ) {
+                       if ( func->interface[i] >= config->interfaces ) {
+                               DBGC ( usb, "USB %s has invalid interface %d\n",
+                                      func->name, func->interface[i] );
+                               goto err_interface;
+                       }
+                       used[ func->interface[i] ] = 1;
+               }
 
                /* Probe device driver */
                if ( ( rc = usb_probe ( func, config ) ) != 0 )
                        goto err_probe;
                DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d interfaces ",
-                      func->name, func->desc.vendor, func->desc.product,
-                      func->desc.class.class.class,
-                      func->desc.class.class.subclass,
-                      func->desc.class.class.protocol );
-               for ( i = 0 ; i < func->desc.count ; i++ )
+                      func->name, func->dev.desc.vendor, func->dev.desc.device,
+                      func->class.class, func->class.subclass,
+                      func->class.protocol );
+               for ( i = 0 ; i < func->count ; i++ )
                        DBGC ( usb, "%s%d", ( i ? "," : "" ),
                               func->interface[i] );
                DBGC ( usb, " using driver %s\n", func->dev.driver_name );
 
+               /* Add to list of functions */
+               list_add ( &func->list, &usb->functions );
+
                /* Add to device hierarchy */
                list_add_tail ( &func->dev.siblings, &bus->dev->children );
 
                continue;
 
                list_del ( &func->dev.siblings );
+               list_del ( &func->list );
                usb_remove ( func );
        err_probe:
-       err_used:
-       err_describe:
-               list_del ( &func->list );
                free ( func );
        err_alloc:
+       err_interface:
+       err_function:
                /* Continue registering other functions */
                continue;
        }
@@ -1328,6 +1165,82 @@ static void usb_remove_all ( struct usb_device *usb ) {
 }
 
 /**
+ * Select USB device configuration
+ *
+ * @v usb              USB device
+ * @v index            Configuration index
+ * @ret rc             Return status code
+ */
+static int usb_configure ( struct usb_device *usb, unsigned int index ) {
+       struct usb_configuration_descriptor partial;
+       struct usb_configuration_descriptor *config;
+       size_t len;
+       int rc;
+
+       /* Read first part of configuration descriptor to get size */
+       if ( ( rc = usb_get_config_descriptor ( usb, index, &partial,
+                                               sizeof ( partial ) ) ) != 0 ) {
+               DBGC ( usb, "USB %s could not get configuration descriptor %d: "
+                      "%s\n", usb->name, index, strerror ( rc ) );
+               goto err_get_partial;
+       }
+       len = le16_to_cpu ( partial.len );
+       if ( len < sizeof ( partial ) ) {
+               DBGC ( usb, "USB %s underlength configuraton descriptor %d\n",
+                      usb->name, index );
+               rc = -EINVAL;
+               goto err_partial_len;
+       }
+
+       /* Allocate buffer for whole configuration descriptor */
+       config = malloc ( len );
+       if ( ! config ) {
+               rc = -ENOMEM;
+               goto err_alloc_config;
+       }
+
+       /* Read whole configuration descriptor */
+       if ( ( rc = usb_get_config_descriptor ( usb, index, config,
+                                               len ) ) != 0 ) {
+               DBGC ( usb, "USB %s could not get configuration descriptor %d: "
+                      "%s\n", usb->name, index, strerror ( rc ) );
+               goto err_get_config_descriptor;
+       }
+       if ( config->len != partial.len ) {
+               DBGC ( usb, "USB %s bad configuration descriptor %d length\n",
+                      usb->name, index );
+               rc = -EINVAL;
+               goto err_config_len;
+       }
+
+       /* Set configuration */
+       if ( ( rc = usb_set_configuration ( usb, config->config ) ) != 0){
+               DBGC ( usb, "USB %s could not set configuration %d: %s\n",
+                      usb->name, config->config, strerror ( rc ) );
+               goto err_set_configuration;
+       }
+
+       /* Probe USB device drivers */
+       usb_probe_all ( usb, config );
+
+       /* Free configuration descriptor */
+       free ( config );
+
+       return 0;
+
+       usb_remove_all ( usb );
+       usb_set_configuration ( usb, 0 );
+ err_set_configuration:
+ err_config_len:
+ err_get_config_descriptor:
+       free ( config );
+ err_alloc_config:
+ err_partial_len:
+ err_get_partial:
+       return rc;
+}
+
+/**
  * Clear USB device configuration
  *
  * @v usb              USB device
@@ -1349,76 +1262,32 @@ static void usb_deconfigure ( struct usb_device *usb ) {
 }
 
 /**
- * Choose our preferred USB device configuration
+ * Find and select a supported USB device configuration
  *
  * @v usb              USB device
  * @ret rc             Return status code
  */
-static int usb_autoconfigure ( struct usb_device *usb ) {
-       struct usb_configuration_descriptor *config;
-       unsigned int preferred = 0;
+static int usb_configure_any ( struct usb_device *usb ) {
        unsigned int index;
-       int score;
-       int best = 0;
-       int rc;
+       int rc = -ENOENT;
 
-       /* Calculate driver score for each configuration index */
+       /* Attempt all configuration indexes */
        for ( index = 0 ; index < usb->device.configurations ; index++ ) {
 
-               /* Read configuration descriptor */
-               if ( ( rc = usb_config_descriptor ( usb, index,
-                                                   &config ) ) != 0 )
-                       goto err_config;
-
-               /* Get score for this configuration */
-               score = usb_score ( usb, config );
-               if ( score < 0 ) {
-                       rc = score;
-                       goto err_score;
-               }
-               DBGC2 ( usb, "USB %s configuration %d score %d\n",
-                       usb->name, config->config, score );
+               /* Attempt this configuration index */
+               if ( ( rc = usb_configure ( usb, index ) ) != 0 )
+                       continue;
 
-               /* Record as preferred configuration, if applicable */
-               if ( score > best ) {
-                       best = score;
-                       preferred = index;
+               /* If we have no drivers, then try the next configuration */
+               if ( list_empty ( &usb->functions ) ) {
+                       rc = -ENOTSUP;
+                       usb_deconfigure ( usb );
+                       continue;
                }
 
-               /* Free configuration descriptor */
-               free ( config );
-               config = NULL;
-       }
-
-       /* Read preferred configuration descriptor */
-       if ( ( rc = usb_config_descriptor ( usb, preferred, &config ) ) != 0 )
-               goto err_preferred;
-
-       /* Set configuration */
-       if ( ( rc = usb_set_configuration ( usb, config->config ) ) != 0){
-               DBGC ( usb, "USB %s could not set configuration %d: %s\n",
-                      usb->name, config->config, strerror ( rc ) );
-               goto err_set_configuration;
+               return 0;
        }
 
-       /* Probe USB device drivers */
-       usb_probe_all ( usb, config );
-
-       /* Free configuration descriptor */
-       free ( config );
-
-       return 0;
-
-       usb_remove_all ( usb );
-       usb_set_configuration ( usb, 0 );
- err_set_configuration:
-       free ( config );
- err_preferred:
-       return rc;
-
- err_score:
-       free ( config );
- err_config:
        return rc;
 }
 
@@ -1497,9 +1366,8 @@ static int register_usb ( struct usb_device *usb ) {
                       hub->name, port->address, strerror ( rc ) );
                goto err_speed;
        }
-       usb->speed = port->speed;
        DBGC2 ( usb, "USB %s attached as %s-speed device\n",
-               usb->name, usb_speed_name ( usb->speed ) );
+               usb->name, usb_speed_name ( port->speed ) );
 
        /* Open device */
        if ( ( rc = usb->host->open ( usb ) ) != 0 ) {
@@ -1509,7 +1377,7 @@ static int register_usb ( struct usb_device *usb ) {
        }
 
        /* Describe control endpoint */
-       mtu = USB_EP0_DEFAULT_MTU ( usb->speed );
+       mtu = USB_EP0_DEFAULT_MTU ( port->speed );
        usb_endpoint_describe ( &usb->control, USB_EP0_ADDRESS,
                                USB_EP0_ATTRIBUTES, mtu, USB_EP0_BURST,
                                USB_EP0_INTERVAL );
@@ -1560,16 +1428,16 @@ static int register_usb ( struct usb_device *usb ) {
               le16_to_cpu ( usb->device.product ), usb->device.class.class,
               usb->device.class.subclass, usb->device.class.protocol,
               usb_bcd ( le16_to_cpu ( usb->device.protocol ) ),
-              usb_speed_name ( usb->speed ), usb->control.mtu );
+              usb_speed_name ( port->speed ), usb->control.mtu );
 
        /* Configure device */
-       if ( ( rc = usb_autoconfigure ( usb ) ) != 0 )
-               goto err_autoconfigure;
+       if ( ( rc = usb_configure_any ( usb ) ) != 0 )
+               goto err_configure_any;
 
        return 0;
 
        usb_deconfigure ( usb );
- err_autoconfigure:
+ err_configure_any:
  err_get_device_descriptor:
  err_mtu:
  err_get_mtu:
@@ -1723,24 +1591,23 @@ static int usb_hotplugged ( struct usb_port *port ) {
        if ( ( rc = hub->driver->speed ( hub, port ) ) != 0 ) {
                DBGC ( hub, "USB hub %s port %d could not get speed: %s\n",
                       hub->name, port->address, strerror ( rc ) );
-               /* Treat as a disconnection */
-               port->disconnected = 1;
-               port->speed = USB_SPEED_NONE;
+               goto err_speed;
        }
 
        /* Detach device, if applicable */
        if ( port->attached && ( port->disconnected || ! port->speed ) )
                usb_detached ( port );
 
-       /* Clear any recorded disconnections */
-       port->disconnected = 0;
-
        /* Attach device, if applicable */
        if ( port->speed && ( ! port->attached ) &&
             ( ( rc = usb_attached ( port ) ) != 0 ) )
-               return rc;
+               goto err_attached;
 
-       return 0;
+ err_attached:
+ err_speed:
+       /* Clear any recorded disconnections */
+       port->disconnected = 0;
+       return rc;
 }
 
 /******************************************************************************
@@ -2239,12 +2106,12 @@ struct usb_port * usb_transaction_translator ( struct usb_device *usb ) {
        struct usb_device *parent;
 
        /* Navigate up to root hub.  If we find a low-speed or
-        * full-speed device with a higher-speed parent hub, then that
-        * device's port is the transaction translator.
+        * full-speed port with a higher-speed parent device, then
+        * that port is the transaction translator.
         */
        for ( ; ( parent = usb->port->hub->usb ) ; usb = parent ) {
-               if ( ( usb->speed <= USB_SPEED_FULL ) &&
-                    ( parent->speed > USB_SPEED_FULL ) )
+               if ( ( usb->port->speed <= USB_SPEED_FULL ) &&
+                    ( parent->port->speed > USB_SPEED_FULL ) )
                        return usb->port;
        }
 
index 3311595..fbef067 100644 (file)
  *
  */
 
-#include "errno.h"
-#include "byteswap.h"
 #include "etherboot.h"
 #include "ipxe/io.h"
-#include "ipxe/iomap.h"
-#include "ipxe/pci.h"
-#include "ipxe/reboot.h"
-#include "ipxe/virtio-pci.h"
 #include "ipxe/virtio-ring.h"
+#include "ipxe/virtio-pci.h"
 
 int vp_find_vq(unsigned int ioaddr, int queue_index,
                struct vring_virtqueue *vq)
@@ -35,19 +30,19 @@ int vp_find_vq(unsigned int ioaddr, int queue_index,
 
    num = inw(ioaddr + VIRTIO_PCI_QUEUE_NUM);
    if (!num) {
-           DBG("VIRTIO-PCI ERROR: queue size is 0\n");
+           printf("ERROR: queue size is 0\n");
            return -1;
    }
 
    if (num > MAX_QUEUE_NUM) {
-           DBG("VIRTIO-PCI ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM);
+           printf("ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM);
            return -1;
    }
 
    /* check if the queue is already active */
 
    if (inl(ioaddr + VIRTIO_PCI_QUEUE_PFN)) {
-           DBG("VIRTIO-PCI ERROR: queue already active\n");
+           printf("ERROR: queue already active\n");
            return -1;
    }
 
@@ -67,343 +62,3 @@ int vp_find_vq(unsigned int ioaddr, int queue_index,
 
    return num;
 }
-
-#define CFG_POS(vdev, field) \
-    (vdev->cfg_cap_pos + offsetof(struct virtio_pci_cfg_cap, field))
-
-static void prep_pci_cfg_cap(struct virtio_pci_modern_device *vdev,
-                             struct virtio_pci_region *region,
-                             size_t offset, u32 length)
-{
-    pci_write_config_byte(vdev->pci, CFG_POS(vdev, cap.bar), region->bar);
-    pci_write_config_dword(vdev->pci, CFG_POS(vdev, cap.length), length);
-    pci_write_config_dword(vdev->pci, CFG_POS(vdev, cap.offset),
-        (intptr_t)(region->base + offset));
-}
-
-void vpm_iowrite8(struct virtio_pci_modern_device *vdev,
-                  struct virtio_pci_region *region, u8 data, size_t offset)
-{
-    switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
-    case VIRTIO_PCI_REGION_MEMORY:
-        writeb(data, region->base + offset);
-        break;
-    case VIRTIO_PCI_REGION_PORT:
-        outb(data, region->base + offset);
-        break;
-    case VIRTIO_PCI_REGION_PCI_CONFIG:
-        prep_pci_cfg_cap(vdev, region, offset, 1);
-        pci_write_config_byte(vdev->pci, CFG_POS(vdev, pci_cfg_data), data);
-        break;
-    default:
-        assert(0);
-        break;
-    }
-}
-
-void vpm_iowrite16(struct virtio_pci_modern_device *vdev,
-                   struct virtio_pci_region *region, u16 data, size_t offset)
-{
-    data = cpu_to_le16(data);
-    switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
-    case VIRTIO_PCI_REGION_MEMORY:
-        writew(data, region->base + offset);
-        break;
-    case VIRTIO_PCI_REGION_PORT:
-        outw(data, region->base + offset);
-        break;
-    case VIRTIO_PCI_REGION_PCI_CONFIG:
-        prep_pci_cfg_cap(vdev, region, offset, 2);
-        pci_write_config_word(vdev->pci, CFG_POS(vdev, pci_cfg_data), data);
-        break;
-    default:
-        assert(0);
-        break;
-    }
-}
-
-void vpm_iowrite32(struct virtio_pci_modern_device *vdev,
-                   struct virtio_pci_region *region, u32 data, size_t offset)
-{
-    data = cpu_to_le32(data);
-    switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
-    case VIRTIO_PCI_REGION_MEMORY:
-        writel(data, region->base + offset);
-        break;
-    case VIRTIO_PCI_REGION_PORT:
-        outl(data, region->base + offset);
-        break;
-    case VIRTIO_PCI_REGION_PCI_CONFIG:
-        prep_pci_cfg_cap(vdev, region, offset, 4);
-        pci_write_config_dword(vdev->pci, CFG_POS(vdev, pci_cfg_data), data);
-        break;
-    default:
-        assert(0);
-        break;
-    }
-}
-
-u8 vpm_ioread8(struct virtio_pci_modern_device *vdev,
-               struct virtio_pci_region *region, size_t offset)
-{
-    uint8_t data;
-    switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
-    case VIRTIO_PCI_REGION_MEMORY:
-        data = readb(region->base + offset);
-        break;
-    case VIRTIO_PCI_REGION_PORT:
-        data = inb(region->base + offset);
-        break;
-    case VIRTIO_PCI_REGION_PCI_CONFIG:
-        prep_pci_cfg_cap(vdev, region, offset, 1);
-        pci_read_config_byte(vdev->pci, CFG_POS(vdev, pci_cfg_data), &data);
-        break;
-    default:
-        assert(0);
-        data = 0;
-        break;
-    }
-    return data;
-}
-
-u16 vpm_ioread16(struct virtio_pci_modern_device *vdev,
-                 struct virtio_pci_region *region, size_t offset)
-{
-    uint16_t data;
-    switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
-    case VIRTIO_PCI_REGION_MEMORY:
-        data = readw(region->base + offset);
-        break;
-    case VIRTIO_PCI_REGION_PORT:
-        data = inw(region->base + offset);
-        break;
-    case VIRTIO_PCI_REGION_PCI_CONFIG:
-        prep_pci_cfg_cap(vdev, region, offset, 2);
-        pci_read_config_word(vdev->pci, CFG_POS(vdev, pci_cfg_data), &data);
-        break;
-    default:
-        assert(0);
-        data = 0;
-        break;
-    }
-    return le16_to_cpu(data);
-}
-
-u32 vpm_ioread32(struct virtio_pci_modern_device *vdev,
-                 struct virtio_pci_region *region, size_t offset)
-{
-    uint32_t data;
-    switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
-    case VIRTIO_PCI_REGION_MEMORY:
-        data = readw(region->base + offset);
-        break;
-    case VIRTIO_PCI_REGION_PORT:
-        data = inw(region->base + offset);
-        break;
-    case VIRTIO_PCI_REGION_PCI_CONFIG:
-        prep_pci_cfg_cap(vdev, region, offset, 4);
-        pci_read_config_dword(vdev->pci, CFG_POS(vdev, pci_cfg_data), &data);
-        break;
-    default:
-        assert(0);
-        data = 0;
-        break;
-    }
-    return le32_to_cpu(data);
-}
-
-int virtio_pci_find_capability(struct pci_device *pci, uint8_t cfg_type)
-{
-    int pos;
-    uint8_t type, bar;
-
-    for (pos = pci_find_capability(pci, PCI_CAP_ID_VNDR);
-         pos > 0;
-         pos = pci_find_next_capability(pci, pos, PCI_CAP_ID_VNDR)) {
-
-        pci_read_config_byte(pci, pos + offsetof(struct virtio_pci_cap,
-            cfg_type), &type);
-        pci_read_config_byte(pci, pos + offsetof(struct virtio_pci_cap,
-            bar), &bar);
-
-        /* Ignore structures with reserved BAR values */
-        if (bar > 0x5) {
-            continue;
-        }
-
-        if (type == cfg_type) {
-            return pos;
-        }
-    }
-    return 0;
-}
-
-int virtio_pci_map_capability(struct pci_device *pci, int cap, size_t minlen,
-                              u32 align, u32 start, u32 size,
-                              struct virtio_pci_region *region)
-{
-    u8 bar;
-    u32 offset, length, base_raw;
-    unsigned long base;
-
-    pci_read_config_byte(pci, cap + offsetof(struct virtio_pci_cap, bar), &bar);
-    pci_read_config_dword(pci, cap + offsetof(struct virtio_pci_cap, offset),
-                          &offset);
-    pci_read_config_dword(pci, cap + offsetof(struct virtio_pci_cap, length),
-                          &length);
-
-    if (length <= start) {
-        DBG("VIRTIO-PCI bad capability len %d (>%d expected)\n", length, start);
-        return -EINVAL;
-    }
-    if (length - start < minlen) {
-        DBG("VIRTIO-PCI bad capability len %d (>=%zd expected)\n", length, minlen);
-        return -EINVAL;
-    }
-    length -= start;
-    if (start + offset < offset) {
-        DBG("VIRTIO-PCI map wrap-around %d+%d\n", start, offset);
-        return -EINVAL;
-    }
-    offset += start;
-    if (offset & (align - 1)) {
-        DBG("VIRTIO-PCI offset %d not aligned to %d\n", offset, align);
-        return -EINVAL;
-    }
-    if (length > size) {
-        length = size;
-    }
-
-    if (minlen + offset < minlen ||
-        minlen + offset > pci_bar_size(pci, PCI_BASE_ADDRESS(bar))) {
-        DBG("VIRTIO-PCI map virtio %zd@%d out of range on bar %i length %ld\n",
-            minlen, offset,
-            bar, pci_bar_size(pci, PCI_BASE_ADDRESS(bar)));
-        return -EINVAL;
-    }
-
-    region->base = NULL;
-    region->length = length;
-    region->bar = bar;
-
-    base = pci_bar_start(pci, PCI_BASE_ADDRESS(bar));
-    if (base) {
-        pci_read_config_dword(pci, PCI_BASE_ADDRESS(bar), &base_raw);
-
-        if (base_raw & PCI_BASE_ADDRESS_SPACE_IO) {
-            /* Region accessed using port I/O */
-            region->base = (void *)(base + offset);
-            region->flags = VIRTIO_PCI_REGION_PORT;
-        } else {
-            /* Region mapped into memory space */
-            region->base = ioremap(base + offset, length);
-            region->flags = VIRTIO_PCI_REGION_MEMORY;
-        }
-    }
-    if (!region->base) {
-        /* Region accessed via PCI config space window */
-           region->base = (void *)(intptr_t)offset;
-        region->flags = VIRTIO_PCI_REGION_PCI_CONFIG;
-    }
-    return 0;
-}
-
-void virtio_pci_unmap_capability(struct virtio_pci_region *region)
-{
-    unsigned region_type = region->flags & VIRTIO_PCI_REGION_TYPE_MASK;
-    if (region_type == VIRTIO_PCI_REGION_MEMORY) {
-        iounmap(region->base);
-    }
-}
-
-void vpm_notify(struct virtio_pci_modern_device *vdev,
-                struct vring_virtqueue *vq)
-{
-    vpm_iowrite16(vdev, &vq->notification, (u16)vq->queue_index, 0);
-}
-
-int vpm_find_vqs(struct virtio_pci_modern_device *vdev,
-                 unsigned nvqs, struct vring_virtqueue *vqs)
-{
-    unsigned i;
-    struct vring_virtqueue *vq;
-    u16 size, off;
-    u32 notify_offset_multiplier;
-    int err;
-
-    if (nvqs > vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(num_queues))) {
-        return -ENOENT;
-    }
-
-    /* Read notify_off_multiplier from config space. */
-    pci_read_config_dword(vdev->pci,
-        vdev->notify_cap_pos + offsetof(struct virtio_pci_notify_cap,
-        notify_off_multiplier),
-        &notify_offset_multiplier);
-
-    for (i = 0; i < nvqs; i++) {
-        /* Select the queue we're interested in */
-        vpm_iowrite16(vdev, &vdev->common, (u16)i, COMMON_OFFSET(queue_select));
-
-        /* Check if queue is either not available or already active. */
-        size = vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(queue_size));
-        /* QEMU has a bug where queues don't revert to inactive on device
-         * reset. Skip checking the queue_enable field until it is fixed.
-         */
-        if (!size /*|| vpm_ioread16(vdev, &vdev->common.queue_enable)*/)
-            return -ENOENT;
-
-        if (size & (size - 1)) {
-            DBG("VIRTIO-PCI %p: bad queue size %d", vdev, size);
-            return -EINVAL;
-        }
-
-        vq = &vqs[i];
-        vq->queue_index = i;
-
-        /* get offset of notification word for this vq */
-        off = vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(queue_notify_off));
-        vq->vring.num = size;
-
-        vring_init(&vq->vring, size, (unsigned char *)vq->queue);
-
-        /* activate the queue */
-        vpm_iowrite16(vdev, &vdev->common, size, COMMON_OFFSET(queue_size));
-
-        vpm_iowrite64(vdev, &vdev->common, virt_to_phys(vq->vring.desc),
-                      COMMON_OFFSET(queue_desc_lo),
-                      COMMON_OFFSET(queue_desc_hi));
-        vpm_iowrite64(vdev, &vdev->common, virt_to_phys(vq->vring.avail),
-                      COMMON_OFFSET(queue_avail_lo),
-                      COMMON_OFFSET(queue_avail_hi));
-        vpm_iowrite64(vdev, &vdev->common, virt_to_phys(vq->vring.used),
-                      COMMON_OFFSET(queue_used_lo),
-                      COMMON_OFFSET(queue_used_hi));
-
-        err = virtio_pci_map_capability(vdev->pci,
-            vdev->notify_cap_pos, 2, 2,
-            off * notify_offset_multiplier, 2,
-            &vq->notification);
-        if (err) {
-            goto err_map_notify;
-        }
-    }
-
-    /* Select and activate all queues. Has to be done last: once we do
-     * this, there's no way to go back except reset.
-     */
-    for (i = 0; i < nvqs; i++) {
-        vq = &vqs[i];
-        vpm_iowrite16(vdev, &vdev->common, (u16)vq->queue_index,
-                      COMMON_OFFSET(queue_select));
-        vpm_iowrite16(vdev, &vdev->common, 1, COMMON_OFFSET(queue_enable));
-    }
-    return 0;
-
-err_map_notify:
-    /* Undo the virtio_pci_map_capability calls. */
-    while (i-- > 0) {
-        virtio_pci_unmap_capability(&vqs[i].notification);
-    }
-    return err;
-}
index 98e787e..e55b6d0 100644 (file)
@@ -18,8 +18,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
 
 #include "etherboot.h"
 #include "ipxe/io.h"
-#include "ipxe/virtio-pci.h"
 #include "ipxe/virtio-ring.h"
+#include "ipxe/virtio-pci.h"
 
 #define BUG() do { \
    printf("BUG: failure at %s:%d/%s()!\n", \
@@ -122,8 +122,7 @@ void vring_add_buf(struct vring_virtqueue *vq,
    wmb();
 }
 
-void vring_kick(struct virtio_pci_modern_device *vdev, unsigned int ioaddr,
-                struct vring_virtqueue *vq, int num_added)
+void vring_kick(unsigned int ioaddr, struct vring_virtqueue *vq, int num_added)
 {
    struct vring *vr = &vq->vring;
 
@@ -131,13 +130,7 @@ void vring_kick(struct virtio_pci_modern_device *vdev, unsigned int ioaddr,
    vr->avail->idx += num_added;
 
    mb();
-   if (!(vr->used->flags & VRING_USED_F_NO_NOTIFY)) {
-           if (vdev) {
-                   /* virtio 1.0 */
-                   vpm_notify(vdev, vq);
-           } else {
-                   /* legacy virtio */
-                   vp_notify(ioaddr, vq->queue_index);
-           }
-   }
+   if (!(vr->used->flags & VRING_USED_F_NO_NOTIFY))
+           vp_notify(ioaddr, vq->queue_index);
 }
+
diff --git a/roms/ipxe/src/drivers/infiniband/CIB_PRM.h b/roms/ipxe/src/drivers/infiniband/CIB_PRM.h
deleted file mode 100755 (executable)
index 6d07c01..0000000
+++ /dev/null
@@ -1,1168 +0,0 @@
-/*
- * Copyright (C) 2013-2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#ifndef __CIB_PRM__
-#define __CIB_PRM__
-
-typedef unsigned long long     __be64;
-typedef uint32_t               __be32;
-typedef uint16_t               __be16;
-
-#define GOLAN_CMD_DATA_BLOCK_SIZE      (1 << 9)
-#define GOLAN_CMD_PAS_CNT                      (GOLAN_CMD_DATA_BLOCK_SIZE / sizeof(__be64))
-#define MAILBOX_STRIDE                         (1 << 10)
-#define MAILBOX_MASK                           (MAILBOX_STRIDE - 1)
-
-#define GOLAN_PCI_CMD_XPORT                    7
-#define CMD_OWNER_HW                           0x1
-
-#define IB_NUM_PKEYS           0x20
-
-struct health_buffer {
-       __be32          assert_var[5];
-       __be32          rsvd0[3];
-       __be32          assert_exit_ptr;
-       __be32          assert_callra;
-       __be32          rsvd1[2];
-       __be32          fw_ver;
-       __be32          hw_id;
-       __be32          rsvd2;
-       u8              irisc_index;
-       u8              synd;
-       __be16          ext_sync;
-} __attribute ( ( packed ) );
-
-struct golan_hca_init_seg {
-       __be32                  fw_rev;
-       __be32                  cmdif_rev_fw_sub;
-       __be32                  rsvd0[2];
-       __be32                  cmdq_addr_h;
-       __be32                  cmdq_addr_l_sz;
-       __be32                  cmd_dbell;
-       __be32                  rsvd1[121];
-       struct health_buffer    health;
-       __be32                  rsvd2[884];
-       __be32                  health_counter;
-       __be32                  rsvd3[1023];
-       __be64                  ieee1588_clk;
-       __be32                  ieee1588_clk_type;
-       __be32                  clr_intx;
-} __attribute ( ( packed ) );
-
-enum golan_manage_pages_mode {
-       GOLAN_PAGES_CANT_GIVE    = 0,
-       GOLAN_PAGES_GIVE         = 1,
-       GOLAN_PAGES_TAKE         = 2
-};
-
-enum golan_qry_pages_mode {
-       GOLAN_BOOT_PAGES        = 0x1,
-       GOLAN_INIT_PAGES        = 0x2,
-       GOLAN_REG_PAGES         = 0x3,
-};
-
-enum {
-       GOLAN_REG_PCAP           = 0x5001,
-       GOLAN_REG_PMTU           = 0x5003,
-       GOLAN_REG_PTYS           = 0x5004,
-       GOLAN_REG_PAOS           = 0x5006,
-       GOLAN_REG_PMAOS          = 0x5012,
-       GOLAN_REG_PUDE           = 0x5009,
-       GOLAN_REG_PMPE           = 0x5010,
-       GOLAN_REG_PELC           = 0x500e,
-       GOLAN_REG_PMLP           = 0, /* TBD */
-       GOLAN_REG_NODE_DESC      = 0x6001,
-       GOLAN_REG_HOST_ENDIANESS = 0x7004,
-};
-
-enum {
-       GOLAN_CMD_OP_QUERY_HCA_CAP              = 0x100,
-       GOLAN_CMD_OP_QUERY_ADAPTER              = 0x101,
-       GOLAN_CMD_OP_INIT_HCA                   = 0x102,
-       GOLAN_CMD_OP_TEARDOWN_HCA               = 0x103,
-       GOLAN_CMD_OP_ENABLE_HCA                 = 0x104,
-       GOLAN_CMD_OP_DISABLE_HCA                = 0x105,
-
-       GOLAN_CMD_OP_QUERY_PAGES                = 0x107,
-       GOLAN_CMD_OP_MANAGE_PAGES               = 0x108,
-       GOLAN_CMD_OP_SET_HCA_CAP                = 0x109,
-
-       GOLAN_CMD_OP_CREATE_MKEY                = 0x200,
-       GOLAN_CMD_OP_QUERY_MKEY                 = 0x201,
-       GOLAN_CMD_OP_DESTROY_MKEY               = 0x202,
-       GOLAN_CMD_OP_QUERY_SPECIAL_CONTEXTS     = 0x203,
-
-       GOLAN_CMD_OP_CREATE_EQ                  = 0x301,
-       GOLAN_CMD_OP_DESTROY_EQ                 = 0x302,
-       GOLAN_CMD_OP_QUERY_EQ                   = 0x303,
-
-       GOLAN_CMD_OP_CREATE_CQ                  = 0x400,
-       GOLAN_CMD_OP_DESTROY_CQ                 = 0x401,
-       GOLAN_CMD_OP_QUERY_CQ                   = 0x402,
-       GOLAN_CMD_OP_MODIFY_CQ                  = 0x403,
-
-       GOLAN_CMD_OP_CREATE_QP                  = 0x500,
-       GOLAN_CMD_OP_DESTROY_QP                 = 0x501,
-       GOLAN_CMD_OP_RST2INIT_QP                = 0x502,
-       GOLAN_CMD_OP_INIT2RTR_QP                = 0x503,
-       GOLAN_CMD_OP_RTR2RTS_QP                 = 0x504,
-       GOLAN_CMD_OP_RTS2RTS_QP                 = 0x505,
-       GOLAN_CMD_OP_SQERR2RTS_QP               = 0x506,
-       GOLAN_CMD_OP_2ERR_QP                    = 0x507,
-       GOLAN_CMD_OP_RTS2SQD_QP                 = 0x508,
-       GOLAN_CMD_OP_SQD2RTS_QP                 = 0x509,
-       GOLAN_CMD_OP_2RST_QP                    = 0x50a,
-       GOLAN_CMD_OP_QUERY_QP                   = 0x50b,
-       GOLAN_CMD_OP_CONF_SQP                   = 0x50c,
-       GOLAN_CMD_OP_MAD_IFC                    = 0x50d,
-       GOLAN_CMD_OP_INIT2INIT_QP               = 0x50e,
-       GOLAN_CMD_OP_SUSPEND_QP                 = 0x50f,
-       GOLAN_CMD_OP_UNSUSPEND_QP               = 0x510,
-       GOLAN_CMD_OP_SQD2SQD_QP                 = 0x511,
-       GOLAN_CMD_OP_ALLOC_QP_COUNTER_SET       = 0x512,
-       GOLAN_CMD_OP_DEALLOC_QP_COUNTER_SET     = 0x513,
-       GOLAN_CMD_OP_QUERY_QP_COUNTER_SET       = 0x514,
-
-       GOLAN_CMD_OP_CREATE_PSV                 = 0x600,
-       GOLAN_CMD_OP_DESTROY_PSV                = 0x601,
-       GOLAN_CMD_OP_QUERY_PSV                  = 0x602,
-       GOLAN_CMD_OP_QUERY_SIG_RULE_TABLE       = 0x603,
-       GOLAN_CMD_OP_QUERY_BLOCK_SIZE_TABLE     = 0x604,
-
-       GOLAN_CMD_OP_CREATE_SRQ                 = 0x700,
-       GOLAN_CMD_OP_DESTROY_SRQ                = 0x701,
-       GOLAN_CMD_OP_QUERY_SRQ                  = 0x702,
-       GOLAN_CMD_OP_ARM_RQ                     = 0x703,
-       GOLAN_CMD_OP_RESIZE_SRQ                 = 0x704,
-
-       GOLAN_CMD_OP_QUERY_HCA_VPORT_CONTEXT    = 0x762,
-       GOLAN_CMD_OP_QUERY_HCA_VPORT_GID                = 0x764,
-       GOLAN_CMD_OP_QUERY_HCA_VPORT_PKEY       = 0x765,
-
-       GOLAN_CMD_OP_ALLOC_PD                   = 0x800,
-       GOLAN_CMD_OP_DEALLOC_PD                 = 0x801,
-       GOLAN_CMD_OP_ALLOC_UAR                  = 0x802,
-       GOLAN_CMD_OP_DEALLOC_UAR                = 0x803,
-
-       GOLAN_CMD_OP_ATTACH_TO_MCG              = 0x806,
-       GOLAN_CMD_OP_DETACH_FROM_MCG            = 0x807,
-
-
-       GOLAN_CMD_OP_ALLOC_XRCD                 = 0x80e,
-       GOLAN_CMD_OP_DEALLOC_XRCD               = 0x80f,
-
-       GOLAN_CMD_OP_ACCESS_REG                 = 0x805,
-};
-
-struct golan_inbox_hdr {
-       __be16          opcode;
-       u8              rsvd[4];
-       __be16          opmod;
-} __attribute ( ( packed ) );
-
-struct golan_cmd_layout {
-       u8              type;
-       u8              rsvd0[3];
-       __be32          inlen;
-       union {
-               __be64          in_ptr;
-               __be32          in_ptr32[2];
-       };
-       __be32          in[4];
-       __be32          out[4];
-       union {
-               __be64          out_ptr;
-               __be32          out_ptr32[2];
-       };
-       __be32          outlen;
-       u8              token;
-       u8              sig;
-       u8              rsvd1;
-       volatile u8     status_own;
-} __attribute ( ( packed ) );
-
-struct golan_outbox_hdr {
-       u8              status;
-       u8              rsvd[3];
-       __be32          syndrome;
-} __attribute ( ( packed ) );
-
-enum {
-    GOLAN_DEV_CAP_FLAG_RC              = 1LL <<  0,
-    GOLAN_DEV_CAP_FLAG_UC              = 1LL <<  1,
-    GOLAN_DEV_CAP_FLAG_UD              = 1LL <<  2,
-    GOLAN_DEV_CAP_FLAG_XRC             = 1LL <<  3,
-    GOLAN_DEV_CAP_FLAG_SRQ             = 1LL <<  6,
-    GOLAN_DEV_CAP_FLAG_BAD_PKEY_CNTR   = 1LL <<  8,
-    GOLAN_DEV_CAP_FLAG_BAD_QKEY_CNTR   = 1LL <<  9,
-    GOLAN_DEV_CAP_FLAG_APM             = 1LL << 17,
-    GOLAN_DEV_CAP_FLAG_ATOMIC          = 1LL << 18,
-    GOLAN_DEV_CAP_FLAG_ON_DMND_PG      = 1LL << 24,
-    GOLAN_DEV_CAP_FLAG_RESIZE_SRQ      = 1LL << 32,
-    GOLAN_DEV_CAP_FLAG_REMOTE_FENCE    = 1LL << 38,
-    GOLAN_DEV_CAP_FLAG_TLP_HINTS       = 1LL << 39,
-    GOLAN_DEV_CAP_FLAG_SIG_HAND_OVER   = 1LL << 40,
-    GOLAN_DEV_CAP_FLAG_DCT             = 1LL << 41,
-    GOLAN_DEV_CAP_FLAG_CMDIF_CSUM      = 1LL << 46,
-};
-
-
-struct golan_hca_cap {
-       u8              rsvd1[16];
-       u8              log_max_srq_sz;
-       u8              log_max_qp_sz;
-       u8              rsvd2;
-       u8              log_max_qp;
-       u8              log_max_strq_sz;
-       u8              log_max_srqs;
-       u8              rsvd4[2];
-       u8              rsvd5;
-       u8              log_max_cq_sz;
-       u8              rsvd6;
-       u8              log_max_cq;
-       u8              log_max_eq_sz;
-       u8              log_max_mkey;
-       u8              rsvd7;
-       u8              log_max_eq;
-       u8              max_indirection;
-       u8              log_max_mrw_sz;
-       u8              log_max_bsf_list_sz;
-       u8              log_max_klm_list_sz;
-       u8              rsvd_8_0;
-       u8              log_max_ra_req_dc;
-       u8              rsvd_8_1;
-       u8              log_max_ra_res_dc;
-       u8              rsvd9;
-       u8              log_max_ra_req_qp;
-       u8              rsvd10;
-       u8              log_max_ra_res_qp;
-       u8              rsvd11[4];
-       __be16          max_qp_count;
-       __be16          pkey_table_size;
-       u8              rsvd13;
-       u8              local_ca_ack_delay;
-       u8              rsvd14;
-       u8              num_ports;
-       u8              log_max_msg;
-       u8              rsvd15[3];
-       __be16          stat_rate_support;
-       u8              rsvd16[2];
-       __be64          flags;
-       u8              rsvd17;
-       u8              uar_sz;
-       u8              rsvd18;
-       u8              log_pg_sz;
-       __be16          bf_log_bf_reg_size;
-       u8              rsvd19[4];
-       __be16          max_wqe_sz_sq;
-       u8              rsvd20[2];
-       __be16          max_wqe_sz_rq;
-       u8              rsvd21[2];
-       __be16          max_wqe_sz_sq_dc;
-       u8              rsvd22[4];
-       __be16          max_qp_mcg;
-       u8              rsvd23;
-       u8              log_max_mcg;
-       u8              rsvd24;
-       u8              log_max_pd;
-       u8              rsvd25;
-       u8              log_max_xrcd;
-       u8              rsvd26[40];
-       __be32          uar_page_sz;
-       u8              rsvd27[28];
-       u8              log_msx_atomic_size_qp;
-       u8              rsvd28[2];
-       u8              log_msx_atomic_size_dc;
-       u8              rsvd29[76];
-} __attribute ( ( packed ) );
-
-struct golan_query_pages_inbox {
-       struct golan_inbox_hdr  hdr;
-       u8                      rsvd[8];
-} __attribute ( ( packed ) );
-
-struct golan_query_pages_outbox {
-       struct golan_outbox_hdr hdr;
-       u8                      rsvd[2];
-       __be16                  func_id;
-       __be32                  num_pages;
-} __attribute ( ( packed ) );
-
-struct golan_cmd_query_hca_cap_mbox_in {
-       struct golan_inbox_hdr  hdr;
-       u8                                              rsvd[8];
-} __attribute ( ( packed ) );
-
-struct golan_cmd_query_hca_cap_mbox_out {
-       struct golan_outbox_hdr hdr;
-       u8                                              rsvd0[8];
-       struct golan_hca_cap    hca_cap;
-} __attribute ( ( packed ) );
-
-struct golan_cmd_set_hca_cap_mbox_in {
-       struct golan_inbox_hdr  hdr;
-       u8                                              rsvd[8];
-       struct golan_hca_cap    hca_cap;
-} __attribute ( ( packed ) );
-
-struct golan_cmd_set_hca_cap_mbox_out {
-       struct golan_outbox_hdr hdr;
-       u8                                              rsvd0[8];
-} __attribute ( ( packed ) );
-
-struct golan_cmd_init_hca_mbox_in {
-       struct golan_inbox_hdr  hdr;
-       u8                                              rsvd0[2];
-       __be16                                  profile;
-       u8                                              rsvd1[4];
-} __attribute ( ( packed ) );
-
-struct golan_cmd_init_hca_mbox_out {
-       struct golan_outbox_hdr hdr;
-       u8                                              rsvd[8];
-} __attribute ( ( packed ) );
-
-enum golan_teardown {
-       GOLAN_TEARDOWN_GRACEFUL = 0x0,
-       GOLAN_TEARDOWN_PANIC    = 0x1
-};
-
-struct golan_cmd_teardown_hca_mbox_in {
-    struct golan_inbox_hdr     hdr;
-    u8                                         rsvd0[2];
-    __be16                     profile;
-    u8                                 rsvd1[4];
-} __attribute ( ( packed ) );
-
-struct golan_cmd_teardown_hca_mbox_out {
-    struct golan_outbox_hdr hdr;
-    u8                                 rsvd[8];
-} __attribute ( ( packed ) );
-
-struct golan_enable_hca_mbox_in {
-       struct golan_inbox_hdr  hdr;
-       u8                      rsvd[8];
-} __attribute ( ( packed ) );
-
-struct golan_enable_hca_mbox_out {
-       struct golan_outbox_hdr hdr;
-       u8                      rsvd[8];
-} __attribute ( ( packed ) );
-
-struct golan_disable_hca_mbox_in {
-    struct golan_inbox_hdr  hdr;
-    u8                                 rsvd[8];
-} __attribute ( ( packed ) );
-
-struct golan_disable_hca_mbox_out {
-    struct golan_outbox_hdr    hdr;
-    u8                                 rsvd[8];
-} __attribute ( ( packed ) );
-
-struct golan_manage_pages_inbox_data {
-       u8                      rsvd2[16];
-       __be64                  pas[0];
-} __attribute ( ( packed ) );
-
-struct golan_manage_pages_inbox {
-       struct golan_inbox_hdr  hdr;
-       __be16                  rsvd0;
-       __be16                  func_id;
-       __be32                  num_entries;
-       struct golan_manage_pages_inbox_data    data;
-} __attribute ( ( packed ) );
-
-struct golan_manage_pages_outbox_data {
-       __be64                  pas[0];
-} __attribute ( ( packed ) );
-
-struct golan_manage_pages_outbox {
-       struct golan_outbox_hdr                 hdr;
-       __be32                                  num_entries;
-       __be32                                  rsrvd;
-       struct golan_manage_pages_outbox_data   data;
-} __attribute ( ( packed ) );
-
-struct golan_reg_host_endianess {
-       u8      he;
-       u8      rsvd[15];
-} __attribute ( ( packed ) );
-
-struct golan_cmd_prot_block {
-       union {
-               __be64          data[GOLAN_CMD_PAS_CNT];
-               u8          bdata[GOLAN_CMD_DATA_BLOCK_SIZE];
-       };
-       u8              rsvd0[48];
-       __be64          next;
-       __be32          block_num;
-       u8              rsvd1;
-       u8              token;
-       u8              ctrl_sig;
-       u8              sig;
-} __attribute ( ( packed ) );
-
-/* MAD IFC structures */
-#define GOLAN_MAD_SIZE                                         256
-#define GOLAN_MAD_IFC_NO_VALIDATION                    0x3
-#define GOLAN_MAD_IFC_RLID_BIT                         16
-
-struct golan_mad_ifc_mbox_in {
-    struct golan_inbox_hdr     hdr;
-    __be16                     remote_lid;
-    u8                                 rsvd0;
-    u8                                 port;
-    u8                                 rsvd1[4];
-    u8                                                 mad[GOLAN_MAD_SIZE];
-} __attribute ( ( packed ) );
-
-struct golan_mad_ifc_mbox_out {
-    struct golan_outbox_hdr    hdr;
-    u8                                 rsvd[8];
-    u8                                                 mad[GOLAN_MAD_SIZE];
-} __attribute ( ( packed ) );
-
-/* UAR Structures */
-struct golan_alloc_uar_mbox_in {
-    struct golan_inbox_hdr  hdr;
-    u8                      rsvd[8];
-} __attribute ( ( packed ) );
-
-struct golan_alloc_uar_mbox_out {
-    struct golan_outbox_hdr hdr;
-    __be32                  uarn;
-    u8                      rsvd[4];
-} __attribute ( ( packed ) );
-
-struct golan_free_uar_mbox_in {
-    struct golan_inbox_hdr  hdr;
-    __be32                  uarn;
-    u8                      rsvd[4];
-} __attribute ( ( packed ) );
-
-struct golan_free_uar_mbox_out {
-    struct golan_outbox_hdr hdr;
-    u8                      rsvd[8];
-} __attribute ( ( packed ) );
-
-/* Event Queue Structures */
-enum {
-    GOLAN_EQ_STATE_ARMED       = 0x9,
-    GOLAN_EQ_STATE_FIRED       = 0xa,
-    GOLAN_EQ_STATE_ALWAYS_ARMED        = 0xb,
-};
-
-
-struct golan_eq_context {
-       u8                      status;
-       u8                      ec_oi;
-       u8                      st;
-       u8                      rsvd2[7];
-       __be16          page_pffset;
-       __be32          log_sz_usr_page;
-       u8                      rsvd3[7];
-       u8                      intr;
-       u8                      log_page_size;
-       u8                      rsvd4[15];
-       __be32          consumer_counter;
-       __be32          produser_counter;
-       u8                      rsvd5[16];
-} __attribute ( ( packed ) );
-
-struct golan_create_eq_mbox_in_data {
-       struct golan_eq_context ctx;
-       u8                                              rsvd2[8];
-       __be64                                  events_mask;
-       u8                                              rsvd3[176];
-       __be64                                  pas[0];
-} __attribute ( ( packed ) );
-
-struct golan_create_eq_mbox_in {
-       struct golan_inbox_hdr                          hdr;
-       u8                                                                      rsvd0[3];
-       u8                                                                      input_eqn;
-       u8                                                                      rsvd1[4];
-       struct golan_create_eq_mbox_in_data data;
-} __attribute ( ( packed ) );
-
-struct golan_create_eq_mbox_out {
-       struct golan_outbox_hdr hdr;
-       u8                                              rsvd0[3];
-       u8                                              eq_number;
-       u8                                              rsvd1[4];
-} __attribute ( ( packed ) );
-
-struct golan_destroy_eq_mbox_in {
-       struct golan_inbox_hdr  hdr;
-       u8                                              rsvd0[3];
-       u8                                              eqn;
-       u8                                              rsvd1[4];
-} __attribute ( ( packed ) );
-
-struct golan_destroy_eq_mbox_out {
-       struct golan_outbox_hdr hdr;
-       u8                                              rsvd[8];
-} __attribute ( ( packed ) );
-
-/***********************************************/
-/************** Query Vport ****************/
-struct golan_query_hca_vport_context_inbox {
-       struct golan_inbox_hdr  hdr;
-       __be16                  other_vport     : 1;
-       __be16                  rsvd1           : 7;
-       __be16                  port_num                : 4;
-       __be16                  rsvd2           : 4;
-       __be16                  vport_number;
-       u8                      rsvd[4];
-} __attribute ( ( packed ) );
-
-struct golan_query_hca_vport_context_data {
-       __be32                  field_select;
-       __be32                  rsvd1[7];
-       //****
-       __be16                  sm_virt_aware                   : 1;
-       __be16                  has_smi                         : 1;
-       __be16                  has_raw                         : 1;
-       __be16                  grh_required                    : 1;
-       __be16                  rsvd2                           : 12;
-       u8                      port_physical_state     : 4;
-       u8                      vport_state_policy      : 4;
-       u8                      port_state                      : 4;
-       u8                      vport_state                     : 4;
-       //****
-       u8                      rsvd3[4];
-       //****
-       __be32                  system_image_guid[2];
-       //****
-       __be32                  port_guid[2];
-       //****
-       __be32                  node_guid[2];
-       //****
-       __be32                  cap_mask1;
-       __be32                  cap_mask1_field_select;
-       __be32                  cap_mask2;
-       __be32                  cap_mask2_field_select;
-       u8                      rsvd4[16];
-       __be16                  lid;
-       u8                      rsvd5                           : 4;
-       u8                      init_type_reply         : 4;
-       u8                      lmc                                     : 3;
-       u8                      subnet_timeout          : 5;
-       __be16                  sm_lid;
-       u8                      sm_sl                           : 4;
-       u8                      rsvd6                           : 4;
-       u8                      rsvd7;
-       __be16                  qkey_violation_counter;
-       __be16                  pkey_violation_counter;
-       u8                      rsvd8[100];
-} __attribute ( ( packed ) );
-
-struct golan_query_hca_vport_context_outbox {
-       struct golan_outbox_hdr hdr;
-       u8                      rsvd[8];
-       struct golan_query_hca_vport_context_data context_data;
-} __attribute ( ( packed ) );
-
-struct golan_query_hca_vport_gid_inbox {
-       struct golan_inbox_hdr  hdr;
-       u8                      other_vport     : 1;
-       u8                      rsvd1           : 7;
-       u8                      port_num                : 4;
-       u8                      rsvd2           : 4;
-       __be16                  vport_number;
-       __be16                  rsvd3;
-       __be16                  gid_index;
-} __attribute ( ( packed ) );
-
-struct golan_query_hca_vport_gid_outbox {
-       struct golan_outbox_hdr hdr;
-       u8                      rsvd0[4];
-       __be16                  gids_num;
-       u8                      rsvd1[2];
-       __be32          gid0[4];
-} __attribute ( ( packed ) );
-
-struct golan_query_hca_vport_pkey_inbox {
-       struct golan_inbox_hdr  hdr;
-       u8                      other_vport     : 1;
-       u8                      rsvd1           : 7;
-       u8                      port_num                : 4;
-       u8                      rsvd2           : 4;
-       __be16                  vport_number;
-       __be16                  rsvd3;
-       __be16                  pkey_index;
-} __attribute ( ( packed ) );
-
-struct golan_query_hca_vport_pkey_data {
-       __be16                  rsvd1;
-       __be16                  pkey0;
-} __attribute ( ( packed ) );
-
-struct golan_query_hca_vport_pkey_outbox {
-       struct golan_outbox_hdr hdr;
-       u8                      rsvd[8];
-       struct golan_query_hca_vport_pkey_data *pkey_data;
-} __attribute ( ( packed ) );
-
-struct golan_eqe_comp {
-       __be32  reserved[6];
-       __be32  cqn;
-} __attribute ( ( packed ) );
-
-struct golan_eqe_qp_srq {
-       __be32  reserved[6];
-       __be32  qp_srq_n;
-} __attribute ( ( packed ) );
-
-struct golan_eqe_cq_err {
-       __be32  cqn;
-       u8      reserved1[7];
-       u8      syndrome;
-} __attribute ( ( packed ) );
-
-struct golan_eqe_dropped_packet {
-};
-
-struct golan_eqe_port_state {
-       u8      reserved0[8];
-       u8      port;
-} __attribute ( ( packed ) );
-
-struct golan_eqe_gpio {
-       __be32  reserved0[2];
-       __be64  gpio_event;
-} __attribute ( ( packed ) );
-
-struct golan_eqe_congestion {
-       u8      type;
-       u8      rsvd0;
-       u8      congestion_level;
-} __attribute ( ( packed ) );
-
-struct golan_eqe_stall_vl {
-       u8      rsvd0[3];
-       u8      port_vl;
-} __attribute ( ( packed ) );
-
-struct golan_eqe_cmd {
-       __be32  vector;
-       __be32  rsvd[6];
-} __attribute ( ( packed ) );
-
-struct golan_eqe_page_req {
-       u8              rsvd0[2];
-       __be16          func_id;
-       u8              rsvd1[2];
-       __be16          num_pages;
-       __be32          rsvd2[5];
-} __attribute ( ( packed ) );
-
-union ev_data {
-       __be32                          raw[7];
-       struct golan_eqe_cmd            cmd;
-       struct golan_eqe_comp           comp;
-       struct golan_eqe_qp_srq         qp_srq;
-       struct golan_eqe_cq_err         cq_err;
-       struct golan_eqe_dropped_packet dp;
-       struct golan_eqe_port_state     port;
-       struct golan_eqe_gpio           gpio;
-       struct golan_eqe_congestion     cong;
-       struct golan_eqe_stall_vl       stall_vl;
-       struct golan_eqe_page_req       req_pages;
-} __attribute__ ((packed));
-
-struct golan_eqe {
-       u8                              rsvd0;
-       u8                              type;
-       u8                              rsvd1;
-       u8                              sub_type;
-       __be32                  rsvd2[7];
-       union ev_data   data;
-       __be16                  rsvd3;
-       u8                              signature;
-       u8                              owner;
-} __attribute__ ((packed));
-
-/* Protection Domain Structures */
-struct golan_alloc_pd_mbox_in {
-       struct golan_inbox_hdr  hdr;
-       u8                      rsvd[8];
-} __attribute ( ( packed ) );
-
-struct golan_alloc_pd_mbox_out {
-       struct golan_outbox_hdr hdr;
-       __be32                  pdn;
-       u8                      rsvd[4];
-} __attribute ( ( packed ) );
-
-struct golan_dealloc_pd_mbox_in {
-       struct golan_inbox_hdr  hdr;
-       __be32                  pdn;
-       u8                      rsvd[4];
-} __attribute ( ( packed ) );
-
-struct golan_dealloc_pd_mbox_out {
-       struct golan_outbox_hdr hdr;
-       u8                      rsvd[8];
-} __attribute ( ( packed ) );
-
-/* Memory key structures */
-#define GOLAN_IB_ACCESS_LOCAL_READ     (1 << 2)
-#define GOLAN_IB_ACCESS_LOCAL_WRITE    (1 << 3)
-#define GOLAN_MKEY_LEN64               (1 << 31)
-#define GOLAN_CREATE_MKEY_SEG_QPN_BIT  8
-
-struct golan_mkey_seg {
-       /*
-        * This is a two bit field occupying bits 31-30.
-        * bit 31 is always 0,
-        * bit 30 is zero for regular MRs and 1 (e.g free) for UMRs that do not have tanslation
-        */
-       u8              status;
-       u8              pcie_control;
-       u8              flags;
-       u8              version;
-       __be32          qpn_mkey7_0;
-       u8              rsvd1[4];
-       __be32          flags_pd;
-       __be64          start_addr;
-       __be64          len;
-       __be32          bsfs_octo_size;
-       u8              rsvd2[16];
-       __be32          xlt_oct_size;
-       u8              rsvd3[3];
-       u8              log2_page_size;
-       u8              rsvd4[4];
-} __attribute ( ( packed ) );
-
-struct golan_create_mkey_mbox_in_data {
-       struct golan_mkey_seg   seg;
-       u8                      rsvd1[16];
-       __be32                  xlat_oct_act_size;
-       __be32                  bsf_coto_act_size;
-       u8                      rsvd2[168];
-       __be64                  pas[0];
-} __attribute ( ( packed ) );
-
-struct golan_create_mkey_mbox_in {
-       struct golan_inbox_hdr                  hdr;
-       __be32                                  input_mkey_index;
-       u8                                      rsvd0[4];
-       struct golan_create_mkey_mbox_in_data   data;
-} __attribute ( ( packed ) );
-
-struct golan_create_mkey_mbox_out {
-       struct golan_outbox_hdr hdr;
-       __be32                  mkey;
-       u8                      rsvd[4];
-} __attribute ( ( packed ) );
-
-struct golan_destroy_mkey_mbox_in {
-       struct golan_inbox_hdr  hdr;
-       __be32                  mkey;
-       u8                      rsvd[4];
-} __attribute ( ( packed ) );
-
-struct golan_destroy_mkey_mbox_out {
-       struct golan_outbox_hdr hdr;
-       u8                      rsvd[8];
-} __attribute ( ( packed ) );
-
-/* Completion Queue Structures */
-enum {
-    GOLAN_CQ_STATE_ARMED       = 9,
-    GOLAN_CQ_STATE_ALWAYS_ARMED        = 0xb,
-    GOLAN_CQ_STATE_FIRED       = 0xa
-};
-
-enum {
-    GOLAN_CQE_REQ              = 0,
-    GOLAN_CQE_RESP_WR_IMM      = 1,
-    GOLAN_CQE_RESP_SEND        = 2,
-    GOLAN_CQE_RESP_SEND_IMM    = 3,
-    GOLAN_CQE_RESP_SEND_INV    = 4,
-    GOLAN_CQE_RESIZE_CQ                = 0xff, /* TBD */
-    GOLAN_CQE_REQ_ERR          = 13,
-    GOLAN_CQE_RESP_ERR         = 14
-};
-
-struct golan_cq_context {
-       u8              status;
-       u8              cqe_sz_flags;
-       u8              st;
-       u8              rsvd3;
-       u8              rsvd4[6];
-       __be16          page_offset;
-       __be32          log_sz_usr_page;
-       __be16          cq_period;
-       __be16          cq_max_count;
-       __be16          rsvd20;
-       __be16          c_eqn;
-       u8              log_pg_sz;
-       u8              rsvd25[7];
-       __be32          last_notified_index;
-       __be32          solicit_producer_index;
-       __be32          consumer_counter;
-       __be32          producer_counter;
-       u8              rsvd48[8];
-       __be64          db_record_addr;
-} __attribute ( ( packed ) );
-
-
-struct golan_create_cq_mbox_in_data    {
-       struct golan_cq_context ctx;
-       u8                                              rsvd6[192];
-       __be64                                  pas[0];
-} __attribute ( ( packed ) );
-
-struct golan_create_cq_mbox_in {
-       struct golan_inbox_hdr                          hdr;
-       __be32                                                          input_cqn;
-       u8                                                                      rsvdx[4];
-       struct golan_create_cq_mbox_in_data     data;
-} __attribute ( ( packed ) );
-
-struct golan_create_cq_mbox_out {
-       struct golan_outbox_hdr hdr;
-       __be32                                  cqn;
-       u8                                              rsvd0[4];
-} __attribute ( ( packed ) );
-
-struct golan_destroy_cq_mbox_in {
-       struct golan_inbox_hdr  hdr;
-       __be32                                  cqn;
-       u8                                              rsvd0[4];
-} __attribute ( ( packed ) );
-
-struct golan_destroy_cq_mbox_out {
-       struct golan_outbox_hdr hdr;
-       u8                                              rsvd0[8];
-} __attribute ( ( packed ) );
-
-struct golan_err_cqe {
-       u8              rsvd0[32];
-       __be32  srqn;
-       u8              rsvd1[16];
-       u8              hw_syndrom;
-       u8              rsvd2;
-       u8              vendor_err_synd;
-       u8              syndrome;
-       __be32  s_wqe_opcode_qpn;
-       __be16  wqe_counter;
-       u8              signature;
-       u8              op_own;
-} __attribute ( ( packed ) );
-
-struct golan_cqe64 {
-       u8              rsvd0[17];
-       u8              ml_path;
-       u8              rsvd20[4];
-       __be16  slid;
-       __be32  flags_rqpn;
-       u8              rsvd28[4];
-       __be32  srqn;
-       __be32  imm_inval_pkey;
-       u8              rsvd40[4];
-       __be32  byte_cnt;
-       __be64  timestamp;
-       __be32  sop_drop_qpn;
-       __be16  wqe_counter;
-       u8              signature;
-       u8              op_own;
-} __attribute ( ( packed ) );
-
-/* Queue Pair Structures */
-#define GOLAN_QP_CTX_ST_BIT                    16
-#define GOLAN_QP_CTX_PM_STATE_BIT              11
-#define GOLAN_QP_CTX_FRE_BIT                   11
-#define GOLAN_QP_CTX_RLKY_BIT                  4
-#define GOLAN_QP_CTX_RQ_SIZE_BIT               3
-#define GOLAN_QP_CTX_SQ_SIZE_BIT               11
-#define GOLAN_QP_CTX_MTU_BIT                   5
-#define GOLAN_QP_CTX_ACK_REQ_FREQ_BIT          28
-
-enum {
-       GOLAN_QP_CTX_DONT_USE_RSRVD_LKEY        = 0,
-       GOLAN_QP_CTX_USE_RSRVD_LKEY             = 1
-};
-
-enum {
-       GOLAN_IB_ACK_REQ_FREQ                   = 8,
-};
-
-enum golan_qp_optpar {
-       GOLAN_QP_PARAM_ALT_ADDR_PATH            = 1 << 0,
-       GOLAN_QP_PARAM_RRE                      = 1 << 1,
-       GOLAN_QP_PARAM_RAE                      = 1 << 2,
-       GOLAN_QP_PARAM_RWE                      = 1 << 3,
-       GOLAN_QP_PARAM_PKEY_INDEX               = 1 << 4,
-       GOLAN_QP_PARAM_Q_KEY                    = 1 << 5,
-       GOLAN_QP_PARAM_RNR_TIMEOUT              = 1 << 6,
-       GOLAN_QP_PARAM_PRIMARY_ADDR_PATH        = 1 << 7,
-       GOLAN_QP_PARAM_SRA_MAX                  = 1 << 8,
-       GOLAN_QP_PARAM_RRA_MAX                  = 1 << 9,
-       GOLAN_QP_PARAM_PM_STATE                 = 1 << 10,
-       GOLAN_QP_PARAM_RETRY_COUNT              = 1 << 12,
-       GOLAN_QP_PARAM_RNR_RETRY                = 1 << 13,
-       GOLAN_QP_PARAM_ACK_TIMEOUT              = 1 << 14,
-       GOLAN_QP_PARAM_PRI_PORT                 = 1 << 16,
-       GOLAN_QP_PARAM_SRQN                     = 1 << 18,
-       GOLAN_QP_PARAM_CQN_RCV                  = 1 << 19,
-       GOLAN_QP_PARAM_DC_HS                    = 1 << 20,
-       GOLAN_QP_PARAM_DC_KEY                   = 1 << 21
-};
-
-#define GOLAN_QP_PARAMS_INIT2RTR_MASK  (GOLAN_QP_PARAM_PKEY_INDEX      |\
-                                        GOLAN_QP_PARAM_Q_KEY           |\
-                                        GOLAN_QP_PARAM_RWE             |\
-                                        GOLAN_QP_PARAM_RRE)
-
-#define GOLAN_QP_PARAMS_RTR2RTS_MASK    (GOLAN_QP_PARAM_PM_STATE       |\
-                                        GOLAN_QP_PARAM_RNR_TIMEOUT     |\
-                                        GOLAN_QP_PARAM_Q_KEY           |\
-                                        GOLAN_QP_PARAM_RWE             |\
-                                        GOLAN_QP_PARAM_RRE)
-
-
-enum {
-       GOLAN_QP_ST_RC                  = 0x0,
-       GOLAN_QP_ST_UC                  = 0x1,
-       GOLAN_QP_ST_UD                  = 0x2,
-       GOLAN_QP_ST_XRC                 = 0x3,
-       GOLAN_QP_ST_MLX                 = 0x4,
-       GOLAN_QP_ST_DC                  = 0x5,
-       GOLAN_QP_ST_QP0                 = 0x7,
-       GOLAN_QP_ST_QP1                 = 0x8,
-       GOLAN_QP_ST_RAW_ETHERTYPE       = 0x9,
-       GOLAN_QP_ST_RAW_IPV6            = 0xa,
-       GOLAN_QP_ST_SNIFFER             = 0xb,
-       GOLAN_QP_ST_SYNC_UMR            = 0xe,
-       GOLAN_QP_ST_PTP_1588            = 0xd,
-       GOLAN_QP_ST_REG_UMR             = 0xc,
-       GOLAN_QP_ST_MAX
-};
-
-enum {
-       GOLAN_QP_PM_MIGRATED    = 0x3,
-       GOLAN_QP_PM_ARMED       = 0x0,
-       GOLAN_QP_PM_REARM       = 0x1
-};
-
-enum {
-       GOLAN_QP_LAT_SENSITIVE  = 1 << 28,
-       GOLAN_QP_ENABLE_SIG     = 1 << 31
-};
-
-
-struct golan_qp_db {
-       u8              rsvd0[2];
-       __be16  recv_db;
-       u8              rsvd1[2];
-       __be16  send_db;
-} __attribute ( ( packed ) );
-
-enum {
-       GOLAN_WQE_CTRL_CQ_UPDATE     = 2 << 2, /*Wissam, wtf?*/
-       GOLAN_WQE_CTRL_SOLICITED     = 1 << 1
-};
-
-struct golan_wqe_ctrl_seg {
-       __be32          opmod_idx_opcode;
-       __be32          qpn_ds;
-       u8                      signature;
-       u8                      rsvd[2];
-       u8                      fm_ce_se;
-       __be32          imm;
-} __attribute ( ( packed ) );
-
-struct golan_av {
-       union {
-               struct {
-                       __be32  qkey;
-                       __be32  reserved;
-               } qkey;
-               __be64  dc_key;
-       } key;
-       __be32  dqp_dct;
-       u8              stat_rate_sl;
-       u8              fl_mlid;
-       __be16  rlid;
-       u8              reserved0[10];
-       u8              tclass;
-       u8              hop_limit;
-       __be32  grh_gid_fl;
-       u8              rgid[16];
-} __attribute ( ( packed ) );
-
-struct golan_wqe_data_seg {
-       __be32  byte_count;
-       __be32  lkey;
-       __be64  addr;
-} __attribute ( ( packed ) );
-
-struct golan_wqe_signature_seg {
-       u8      rsvd0[4];
-       u8      signature;
-       u8      rsvd1[11];
-} __attribute ( ( packed ) );
-
-struct golan_wqe_inline_seg {
-       __be32  byte_count;
-} __attribute ( ( packed ) );
-
-struct golan_qp_path {
-       u8                      fl;
-       u8                      rsvd3;
-       u8                      free_ar;
-       u8                      pkey_index;
-       u8                      rsvd0;
-       u8                      grh_mlid;
-       __be16          rlid;
-       u8                      ackto_lt;
-       u8                      mgid_index;
-       u8                      static_rate;
-       u8                      hop_limit;
-       __be32          tclass_flowlabel;
-       u8                      rgid[16];
-       u8                      rsvd1[4];
-       u8                      sl;
-       u8                      port;
-       u8                      rsvd2[6];
-} __attribute ( ( packed ) );
-
-struct golan_qp_context {
-       __be32                  flags;
-       __be32                  flags_pd;
-       u8                      mtu_msgmax;
-       u8                      rq_size_stride;
-       __be16                  sq_crq_size;
-       __be32                  qp_counter_set_usr_page;
-       __be32                  wire_qpn;
-       __be32                  log_pg_sz_remote_qpn;
-       struct                  golan_qp_path pri_path;
-       struct                  golan_qp_path alt_path;
-       __be32                  params1;
-       u8                      reserved2[4];
-       __be32                  next_send_psn;
-       __be32                  cqn_send;
-       u8                      reserved3[8];
-       __be32                  last_acked_psn;
-       __be32                  ssn;
-       __be32                  params2;
-       __be32                  rnr_nextrecvpsn;
-       __be32                  xrcd;
-       __be32                  cqn_recv;
-       __be64                  db_rec_addr;
-       __be32                  qkey;
-       __be32                  rq_type_srqn;
-       __be32                  rmsn;
-       __be16                  hw_sq_wqe_counter;
-       __be16                  sw_sq_wqe_counter;
-       __be16                  hw_rcyclic_byte_counter;
-       __be16                  hw_rq_counter;
-       __be16                  sw_rcyclic_byte_counter;
-       __be16                  sw_rq_counter;
-       u8                      rsvd0[5];
-       u8                      cgs;
-       u8                      cs_req;
-       u8                      cs_res;
-       __be64                  dc_access_key;
-       u8                      rsvd1[24];
-} __attribute ( ( packed ) );
-
-struct golan_create_qp_mbox_in_data {
-       __be32                          opt_param_mask;
-       u8                              rsvd1[4];
-       struct golan_qp_context         ctx;
-       u8                              rsvd3[16];
-       __be64                          pas[0];
-} __attribute ( ( packed ) );
-
-struct golan_create_qp_mbox_in {
-       struct golan_inbox_hdr                  hdr;
-       __be32                                  input_qpn;
-       u8                                      rsvd0[4];
-       struct golan_create_qp_mbox_in_data     data;
-} __attribute ( ( packed ) );
-
-struct golan_create_qp_mbox_out {
-       struct golan_outbox_hdr hdr;
-       __be32                  qpn;
-       u8                      rsvd0[4];
-} __attribute ( ( packed ) );
-
-struct golan_destroy_qp_mbox_in {
-       struct golan_inbox_hdr  hdr;
-       __be32                  qpn;
-       u8                      rsvd0[4];
-} __attribute ( ( packed ) );
-
-struct golan_destroy_qp_mbox_out {
-       struct golan_outbox_hdr hdr;
-       u8                      rsvd0[8];
-} __attribute ( ( packed ) );
-
-struct golan_modify_qp_mbox_in_data {
-       __be32                  optparam;
-       u8                      rsvd0[4];
-       struct golan_qp_context ctx;
-} __attribute ( ( packed ) );
-
-struct golan_modify_qp_mbox_in {
-       struct golan_inbox_hdr          hdr;
-       __be32                          qpn;
-       u8                              rsvd1[4];
-       struct golan_modify_qp_mbox_in_data     data;
-} __attribute ( ( packed ) );
-
-struct golan_modify_qp_mbox_out {
-       struct golan_outbox_hdr         hdr;
-       u8                              rsvd0[8];
-} __attribute ( ( packed ) );
-
-struct golan_attach_mcg_mbox_in {
-    struct golan_inbox_hdr     hdr;
-    __be32                     qpn;
-    __be32                     rsvd;
-    u8                         gid[16];
-} __attribute ( ( packed ) );
-
-struct golan_attach_mcg_mbox_out {
-    struct golan_outbox_hdr    hdr;
-    u8                         rsvf[8];
-} __attribute ( ( packed ) );
-
-struct golan_detach_mcg_mbox_in {
-    struct golan_inbox_hdr     hdr;
-    __be32                     qpn;
-    __be32                     rsvd;
-    u8                         gid[16];
-} __attribute ( ( packed ) );
-
-struct golan_detach_mcg_mbox_out {
-    struct golan_outbox_hdr    hdr;
-    u8                                 rsvf[8];
-} __attribute ( ( packed ) );
-
-
-#define MAILBOX_SIZE   sizeof(struct golan_cmd_prot_block)
-
-#endif /* __CIB_PRM__ */
index 9671174..2a6c32d 100644 (file)
@@ -897,44 +897,26 @@ static int arbel_create_send_wq ( struct arbel_send_work_queue *arbel_send_wq,
  *
  * @v arbel_recv_wq    Receive work queue
  * @v num_wqes         Number of work queue entries
- * @v type             Queue pair type
  * @ret rc             Return status code
  */
 static int arbel_create_recv_wq ( struct arbel_recv_work_queue *arbel_recv_wq,
-                                 unsigned int num_wqes,
-                                 enum ib_queue_pair_type type ) {
+                                 unsigned int num_wqes ) {
        struct arbelprm_recv_wqe *wqe;
        struct arbelprm_recv_wqe *next_wqe;
        unsigned int wqe_idx_mask;
        size_t nds;
        unsigned int i;
        unsigned int j;
-       int rc;
 
        /* Allocate work queue */
        arbel_recv_wq->wqe_size = ( num_wqes *
                                    sizeof ( arbel_recv_wq->wqe[0] ) );
        arbel_recv_wq->wqe = malloc_dma ( arbel_recv_wq->wqe_size,
                                          sizeof ( arbel_recv_wq->wqe[0] ) );
-       if ( ! arbel_recv_wq->wqe ) {
-               rc = -ENOMEM;
-               goto err_alloc_wqe;
-       }
+       if ( ! arbel_recv_wq->wqe )
+               return -ENOMEM;
        memset ( arbel_recv_wq->wqe, 0, arbel_recv_wq->wqe_size );
 
-       /* Allocate GRH entries, if needed */
-       if ( ( type == IB_QPT_SMI ) || ( type == IB_QPT_GSI ) ||
-            ( type == IB_QPT_UD ) ) {
-               arbel_recv_wq->grh_size = ( num_wqes *
-                                           sizeof ( arbel_recv_wq->grh[0] ) );
-               arbel_recv_wq->grh = malloc_dma ( arbel_recv_wq->grh_size,
-                                                 sizeof ( void * ) );
-               if ( ! arbel_recv_wq->grh ) {
-                       rc = -ENOMEM;
-                       goto err_alloc_grh;
-               }
-       }
-
        /* Link work queue entries */
        wqe_idx_mask = ( num_wqes - 1 );
        nds = ( ( offsetof ( typeof ( *wqe ), data ) +
@@ -953,12 +935,6 @@ static int arbel_create_recv_wq ( struct arbel_recv_work_queue *arbel_recv_wq,
        }
        
        return 0;
-
-       free_dma ( arbel_recv_wq->grh, arbel_recv_wq->grh_size );
- err_alloc_grh:
-       free_dma ( arbel_recv_wq->wqe, arbel_recv_wq->wqe_size );
- err_alloc_wqe:
-       return rc;
 }
 
 /**
@@ -1009,8 +985,8 @@ static int arbel_create_qp ( struct ib_device *ibdev,
        if ( ( rc = arbel_create_send_wq ( &arbel_qp->send,
                                           qp->send.num_wqes ) ) != 0 )
                goto err_create_send_wq;
-       if ( ( rc = arbel_create_recv_wq ( &arbel_qp->recv, qp->recv.num_wqes,
-                                          qp->type ) ) != 0 )
+       if ( ( rc = arbel_create_recv_wq ( &arbel_qp->recv,
+                                          qp->recv.num_wqes ) ) != 0 )
                goto err_create_recv_wq;
 
        /* Send and receive work queue entries must be within the same 4GB */
@@ -1102,7 +1078,6 @@ static int arbel_create_qp ( struct ib_device *ibdev,
        MLX_FILL_1 ( send_db_rec, 1, res, ARBEL_UAR_RES_NONE );
        MLX_FILL_1 ( recv_db_rec, 1, res, ARBEL_UAR_RES_NONE );
  err_unsupported_address_split:
-       free_dma ( arbel_qp->recv.grh, arbel_qp->recv.grh_size );
        free_dma ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
  err_create_recv_wq:
        free_dma ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
@@ -1231,9 +1206,8 @@ static void arbel_destroy_qp ( struct ib_device *ibdev,
        MLX_FILL_1 ( recv_db_rec, 1, res, ARBEL_UAR_RES_NONE );
 
        /* Free memory */
-       free_dma ( arbel_qp->recv.grh, arbel_qp->recv.grh_size );
-       free_dma ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
        free_dma ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
+       free_dma ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
        free ( arbel_qp );
 
        /* Mark queue number as free */
@@ -1503,8 +1477,6 @@ static int arbel_post_recv ( struct ib_device *ibdev,
        struct ib_work_queue *wq = &qp->recv;
        struct arbel_recv_work_queue *arbel_recv_wq = &arbel_qp->recv;
        struct arbelprm_recv_wqe *wqe;
-       struct arbelprm_wqe_segment_data_ptr *data;
-       struct ib_global_route_header *grh;
        union arbelprm_doorbell_record *db_rec;
        unsigned int wqe_idx_mask;
 
@@ -1519,19 +1491,12 @@ static int arbel_post_recv ( struct ib_device *ibdev,
        wqe = &arbel_recv_wq->wqe[wq->next_idx & wqe_idx_mask].recv;
 
        /* Construct work queue entry */
-       data = &wqe->data[0];
-       if ( arbel_recv_wq->grh ) {
-               grh = &arbel_recv_wq->grh[wq->next_idx & wqe_idx_mask];
-               MLX_FILL_1 ( data, 0, byte_count, sizeof ( *grh ) );
-               MLX_FILL_1 ( data, 1, l_key, arbel->lkey );
-               MLX_FILL_H ( data, 2, local_address_h, virt_to_bus ( grh ) );
-               MLX_FILL_1 ( data, 3, local_address_l, virt_to_bus ( grh ) );
-               data++;
-       }
-       MLX_FILL_1 ( data, 0, byte_count, iob_tailroom ( iobuf ) );
-       MLX_FILL_1 ( data, 1, l_key, arbel->lkey );
-       MLX_FILL_H ( data, 2, local_address_h, virt_to_bus ( iobuf->data ) );
-       MLX_FILL_1 ( data, 3, local_address_l, virt_to_bus ( iobuf->data ) );
+       MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_tailroom ( iobuf ) );
+       MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->lkey );
+       MLX_FILL_H ( &wqe->data[0], 2,
+                    local_address_h, virt_to_bus ( iobuf->data ) );
+       MLX_FILL_1 ( &wqe->data[0], 3,
+                    local_address_l, virt_to_bus ( iobuf->data ) );
 
        /* Update doorbell record */
        barrier();
@@ -1646,16 +1611,17 @@ static int arbel_complete ( struct ib_device *ibdev,
                MLX_FILL_1 ( &recv_wqe->data[0], 0, byte_count, 0 );
                MLX_FILL_1 ( &recv_wqe->data[0], 1,
                             l_key, ARBEL_INVALID_LKEY );
+               assert ( len <= iob_tailroom ( iobuf ) );
+               iob_put ( iobuf, len );
                memset ( &recv_dest, 0, sizeof ( recv_dest ) );
                recv_dest.qpn = qpn;
                switch ( qp->type ) {
                case IB_QPT_SMI:
                case IB_QPT_GSI:
                case IB_QPT_UD:
-                       /* Locate corresponding GRH */
-                       assert ( arbel_recv_wq->grh != NULL );
-                       grh = &arbel_recv_wq->grh[wqe_idx];
-                       len -= sizeof ( *grh );
+                       assert ( iob_len ( iobuf ) >= sizeof ( *grh ) );
+                       grh = iobuf->data;
+                       iob_pull ( iobuf, sizeof ( *grh ) );
                        /* Construct address vector */
                        source = &recv_source;
                        memset ( source, 0, sizeof ( *source ) );
@@ -1676,8 +1642,6 @@ static int arbel_complete ( struct ib_device *ibdev,
                        assert ( 0 );
                        return -EINVAL;
                }
-               assert ( len <= iob_tailroom ( iobuf ) );
-               iob_put ( iobuf, len );
                /* Hand off to completion handler */
                ib_complete_recv ( ibdev, qp, &recv_dest, source, iobuf, rc );
        }
@@ -3036,16 +3000,6 @@ static int arbel_probe ( struct pci_device *pci ) {
        pci_set_drvdata ( pci, arbel );
        arbel->pci = pci;
 
-       /* Fix up PCI device */
-       adjust_pci_device ( pci );
-
-       /* Map PCI BARs */
-       arbel->config = ioremap ( pci_bar_start ( pci, ARBEL_PCI_CONFIG_BAR ),
-                                 ARBEL_PCI_CONFIG_BAR_SIZE );
-       arbel->uar = ioremap ( ( pci_bar_start ( pci, ARBEL_PCI_UAR_BAR ) +
-                                ARBEL_PCI_UAR_IDX * ARBEL_PCI_UAR_SIZE ),
-                              ARBEL_PCI_UAR_SIZE );
-
        /* Allocate Infiniband devices */
        for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ ) {
                ibdev = alloc_ibdev ( 0 );
@@ -3060,6 +3014,16 @@ static int arbel_probe ( struct pci_device *pci ) {
                ib_set_drvdata ( ibdev, arbel );
        }
 
+       /* Fix up PCI device */
+       adjust_pci_device ( pci );
+
+       /* Get PCI BARs */
+       arbel->config = ioremap ( pci_bar_start ( pci, ARBEL_PCI_CONFIG_BAR ),
+                                 ARBEL_PCI_CONFIG_BAR_SIZE );
+       arbel->uar = ioremap ( ( pci_bar_start ( pci, ARBEL_PCI_UAR_BAR ) +
+                                ARBEL_PCI_UAR_IDX * ARBEL_PCI_UAR_SIZE ),
+                              ARBEL_PCI_UAR_SIZE );
+
        /* Reset device */
        arbel_reset ( arbel );
 
@@ -3108,8 +3072,6 @@ static int arbel_probe ( struct pci_device *pci ) {
  err_alloc_ibdev:
        for ( i-- ; i >= 0 ; i-- )
                ibdev_put ( arbel->ibdev[i] );
-       iounmap ( arbel->uar );
-       iounmap ( arbel->config );
        arbel_free ( arbel );
  err_alloc:
        return rc;
@@ -3128,8 +3090,6 @@ static void arbel_remove ( struct pci_device *pci ) {
                unregister_ibdev ( arbel->ibdev[i] );
        for ( i = ( ARBEL_NUM_PORTS - 1 ) ; i >= 0 ; i-- )
                ibdev_put ( arbel->ibdev[i] );
-       iounmap ( arbel->uar );
-       iounmap ( arbel->config );
        arbel_free ( arbel );
 }
 
index 8a5a996..73394cd 100644 (file)
@@ -237,7 +237,7 @@ struct arbelprm_rc_send_wqe {
        struct arbelprm_wqe_segment_data_ptr data[ARBEL_MAX_GATHER];
 } __attribute__ (( packed ));
 
-#define ARBEL_MAX_SCATTER 2
+#define ARBEL_MAX_SCATTER 1
 
 struct arbelprm_recv_wqe {
        /* The autogenerated header is inconsistent between send and
@@ -369,10 +369,6 @@ struct arbel_recv_work_queue {
        union arbel_recv_wqe *wqe;
        /** Size of work queue */
        size_t wqe_size;
-       /** GRH buffers (if applicable) */
-       struct ib_global_route_header *grh;
-       /** Size of GRB buffers */
-       size_t grh_size;
 };
 
 /** Number of special queue pairs */
diff --git a/roms/ipxe/src/drivers/infiniband/flexboot_nodnic.c b/roms/ipxe/src/drivers/infiniband/flexboot_nodnic.c
deleted file mode 100644 (file)
index dea19ca..0000000
+++ /dev/null
@@ -1,1479 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <byteswap.h>
-#include <ipxe/pci.h>
-#include <ipxe/malloc.h>
-#include <ipxe/umalloc.h>
-#include <ipxe/if_ether.h>
-#include <ipxe/ethernet.h>
-#include <ipxe/vlan.h>
-#include <ipxe/io.h>
-#include "flexboot_nodnic.h"
-#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h"
-#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h"
-#include "mlx_utils/include/public/mlx_pci_gw.h"
-#include "mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.h"
-#include "mlx_utils/include/public/mlx_types.h"
-#include "mlx_utils/include/public/mlx_utils.h"
-#include "mlx_utils/include/public/mlx_bail.h"
-#include "mlx_nodnic/include/mlx_cmd.h"
-#include "mlx_utils/include/public/mlx_memory.h"
-#include "mlx_utils/include/public/mlx_pci.h"
-#include "mlx_nodnic/include/mlx_device.h"
-#include "mlx_nodnic/include/mlx_port.h"
-
-/***************************************************************************
- *
- * Completion queue operations
- *
- ***************************************************************************
- */
-static int flexboot_nodnic_arm_cq ( struct flexboot_nodnic_port *port ) {
-#ifndef DEVICE_CX3
-       mlx_uint32 val = ( port->eth_cq->next_idx & 0xffff );
-       if ( nodnic_port_set ( & port->port_priv, nodnic_port_option_arm_cq, val ) ) {
-               MLX_DEBUG_ERROR( port->port_priv.device, "Failed to arm the CQ\n" );
-               return MLX_FAILED;
-       }
-#else
-       mlx_utils *utils = port->port_priv.device->utils;
-       nodnic_port_data_flow_gw *ptr = port->port_priv.data_flow_gw;
-       mlx_uint32 data = 0;
-       mlx_uint32 val = 0;
-
-       if ( port->port_priv.device->device_cap.crspace_doorbells == 0 ) {
-               val = ( port->eth_cq->next_idx & 0xffff );
-               if ( nodnic_port_set ( & port->port_priv, nodnic_port_option_arm_cq, val ) ) {
-                       MLX_DEBUG_ERROR( port->port_priv.device, "Failed to arm the CQ\n" );
-                       return MLX_FAILED;
-               }
-       } else {
-               /* Arming the CQ with CQ CI should be with this format -
-                * 16 bit - CQ CI - same endianness as the FW (don't swap bytes)
-                * 15 bit - reserved
-                *  1 bit - arm CQ - must correct the endianness with the reserved above */
-               data = ( ( ( port->eth_cq->next_idx & 0xffff ) << 16 ) | 0x0080 );
-               /* Write the new index and update FW that new data was submitted */
-               mlx_pci_mem_write ( utils, MlxPciWidthUint32, 0,
-                               ( mlx_uint64 ) & ( ptr->armcq_cq_ci_dword ), 1, &data );
-       }
-#endif
-       return 0;
-}
-
-/**
- * Create completion queue
- *
- * @v ibdev            Infiniband device
- * @v cq               Completion queue
- * @ret rc             Return status code
- */
-static int flexboot_nodnic_create_cq ( struct ib_device *ibdev ,
-                             struct ib_completion_queue *cq ) {
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
-       struct flexboot_nodnic_completion_queue *flexboot_nodnic_cq;
-       mlx_status status = MLX_SUCCESS;
-
-       flexboot_nodnic_cq = (struct flexboot_nodnic_completion_queue *)
-                       zalloc(sizeof(*flexboot_nodnic_cq));
-       if ( flexboot_nodnic_cq == NULL ) {
-               status = MLX_OUT_OF_RESOURCES;
-               goto qp_alloc_err;
-       }
-
-       status = nodnic_port_create_cq(&port->port_priv,
-                       cq->num_cqes *
-                       flexboot_nodnic->callbacks->get_cqe_size(),
-                       &flexboot_nodnic_cq->nodnic_completion_queue
-                       );
-       MLX_FATAL_CHECK_STATUS(status, create_err,
-                               "nodnic_port_create_cq failed");
-       flexboot_nodnic->callbacks->cqe_set_owner(
-                       flexboot_nodnic_cq->nodnic_completion_queue->cq_virt,
-                       cq->num_cqes);
-
-
-       ib_cq_set_drvdata ( cq, flexboot_nodnic_cq );
-       return status;
-create_err:
-       free(flexboot_nodnic_cq);
-qp_alloc_err:
-       return status;
-}
-
-/**
- * Destroy completion queue
- *
- * @v ibdev            Infiniband device
- * @v cq               Completion queue
- */
-static void flexboot_nodnic_destroy_cq ( struct ib_device *ibdev ,
-                               struct ib_completion_queue *cq ) {
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
-       struct flexboot_nodnic_completion_queue *flexboot_nodnic_cq = ib_cq_get_drvdata ( cq );
-
-       nodnic_port_destroy_cq(&port->port_priv,
-                       flexboot_nodnic_cq->nodnic_completion_queue);
-
-       free(flexboot_nodnic_cq);
-}
-
-static
-struct ib_work_queue * flexboot_nodnic_find_wq ( struct ib_device *ibdev ,
-                                                       struct ib_completion_queue *cq,
-                                                       unsigned long qpn, int is_send ) {
-       struct ib_work_queue *wq;
-       struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp;
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
-       struct nodnic_ring  *ring;
-       mlx_uint32 out_qpn;
-       list_for_each_entry ( wq, &cq->work_queues, list ) {
-               flexboot_nodnic_qp = ib_qp_get_drvdata ( wq->qp );
-               if( wq->is_send == is_send && wq->is_send == TRUE ) {
-                       ring = &flexboot_nodnic_qp->nodnic_queue_pair->send.nodnic_ring;
-               } else if( wq->is_send == is_send && wq->is_send == FALSE ) {
-                       ring = &flexboot_nodnic_qp->nodnic_queue_pair->receive.nodnic_ring;
-               } else {
-                       continue;
-               }
-               nodnic_port_get_qpn(&port->port_priv, ring, &out_qpn);
-               if ( out_qpn == qpn )
-                       return wq;
-       }
-       return NULL;
-}
-
-/**
- * Handle completion
- *
- * @v ibdev            Infiniband device
- * @v cq               Completion queue
- * @v cqe              Hardware completion queue entry
- * @ret rc             Return status code
- */
-static int flexboot_nodnic_complete ( struct ib_device *ibdev,
-                            struct ib_completion_queue *cq,
-                                struct cqe_data *cqe_data ) {
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       struct ib_work_queue *wq;
-       struct ib_queue_pair *qp;
-       struct io_buffer *iobuf;
-       struct ib_address_vector recv_dest;
-       struct ib_address_vector recv_source;
-       unsigned long qpn;
-       unsigned long wqe_idx;
-       unsigned long wqe_idx_mask;
-       size_t len;
-       int rc = 0;
-
-       /* Parse completion */
-       qpn = cqe_data->qpn;
-
-       if ( cqe_data->is_error == TRUE ) {
-               DBGC ( flexboot_nodnic, "flexboot_nodnic %p CQN %#lx syndrome %x vendor %x\n",
-                               flexboot_nodnic, cq->cqn, cqe_data->syndrome,
-                               cqe_data->vendor_err_syndrome );
-               rc = -EIO;
-               /* Don't return immediately; propagate error to completer */
-       }
-
-       /* Identify work queue */
-       wq = flexboot_nodnic_find_wq( ibdev, cq, qpn, cqe_data->is_send );
-       if ( wq == NULL ) {
-               DBGC ( flexboot_nodnic,
-                               "flexboot_nodnic %p CQN %#lx unknown %s QPN %#lx\n",
-                               flexboot_nodnic, cq->cqn,
-                               ( cqe_data->is_send ? "send" : "recv" ), qpn );
-               return -EIO;
-       }
-       qp = wq->qp;
-
-       /* Identify work queue entry */
-       wqe_idx = cqe_data->wqe_counter;
-       wqe_idx_mask = ( wq->num_wqes - 1 );
-       DBGCP ( flexboot_nodnic,
-                       "NODNIC %p CQN %#lx QPN %#lx %s WQE %#lx completed:\n",
-                       flexboot_nodnic, cq->cqn, qp->qpn,
-                       ( cqe_data->is_send ? "send" : "recv" ),
-               wqe_idx );
-
-       /* Identify I/O buffer */
-       iobuf = wq->iobufs[wqe_idx & wqe_idx_mask];
-       if ( iobuf == NULL ) {
-               DBGC ( flexboot_nodnic,
-                               "NODNIC %p CQN %#lx QPN %#lx empty %s WQE %#lx\n",
-                               flexboot_nodnic, cq->cqn, qp->qpn,
-                      ( cqe_data->is_send ? "send" : "recv" ), wqe_idx );
-               return -EIO;
-       }
-       wq->iobufs[wqe_idx & wqe_idx_mask] = NULL;
-
-       if ( cqe_data->is_send == TRUE ) {
-               /* Hand off to completion handler */
-               ib_complete_send ( ibdev, qp, iobuf, rc );
-       } else if ( rc != 0 ) {
-               /* Propagate error to receive completion handler */
-               ib_complete_recv ( ibdev, qp, NULL, NULL, iobuf, rc );
-       } else {
-               /* Set received length */
-               len = cqe_data->byte_cnt;
-               assert ( len <= iob_tailroom ( iobuf ) );
-               iob_put ( iobuf, len );
-               memset ( &recv_dest, 0, sizeof ( recv_dest ) );
-               recv_dest.qpn = qpn;
-               memset ( &recv_source, 0, sizeof ( recv_source ) );
-               switch ( qp->type ) {
-               case IB_QPT_SMI:
-               case IB_QPT_GSI:
-               case IB_QPT_UD:
-               case IB_QPT_RC:
-                       break;
-               case IB_QPT_ETH:
-                       break;
-               default:
-                       assert ( 0 );
-                       return -EINVAL;
-               }
-               /* Hand off to completion handler */
-               ib_complete_recv ( ibdev, qp, &recv_dest,
-                               &recv_source, iobuf, rc );
-       }
-
-       return rc;
-}
-/**
- * Poll completion queue
- *
- * @v ibdev            Infiniband device
- * @v cq               Completion queues
- */
-static void flexboot_nodnic_poll_cq ( struct ib_device *ibdev,
-                            struct ib_completion_queue *cq) {
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       struct flexboot_nodnic_completion_queue *flexboot_nodnic_cq = ib_cq_get_drvdata ( cq );
-       void *cqe;
-       mlx_size cqe_size;
-       struct cqe_data cqe_data;
-       unsigned int cqe_idx_mask;
-       int rc;
-
-       cqe_size = flexboot_nodnic->callbacks->get_cqe_size();
-       while ( TRUE ) {
-               /* Look for completion entry */
-               cqe_idx_mask = ( cq->num_cqes - 1 );
-               cqe = ((uint8_t *)flexboot_nodnic_cq->nodnic_completion_queue->cq_virt) +
-                               cqe_size * (cq->next_idx & cqe_idx_mask);
-
-               /* TODO: check fill_completion */
-               flexboot_nodnic->callbacks->fill_completion(cqe, &cqe_data);
-               if ( cqe_data.owner ^
-                               ( ( cq->next_idx & cq->num_cqes ) ? 1 : 0 ) ) {
-                       /* Entry still owned by hardware; end of poll */
-                       break;
-               }
-               /* Handle completion */
-               rc = flexboot_nodnic_complete ( ibdev, cq, &cqe_data );
-               if ( rc != 0 ) {
-                       DBGC ( flexboot_nodnic, "flexboot_nodnic %p CQN %#lx failed to complete: %s\n",
-                                       flexboot_nodnic, cq->cqn, strerror ( rc ) );
-                       DBGC_HDA ( flexboot_nodnic, virt_to_phys ( cqe ),
-                                  cqe, sizeof ( *cqe ) );
-               }
-
-               /* Update completion queue's index */
-               cq->next_idx++;
-       }
-}
-/***************************************************************************
- *
- * Queue pair operations
- *
- ***************************************************************************
- */
-
-
-/**
- * Create queue pair
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- * @ret rc             Return status code
- */
-static int flexboot_nodnic_create_qp ( struct ib_device *ibdev,
-                             struct ib_queue_pair *qp ) {
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
-       struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp;
-       mlx_status status = MLX_SUCCESS;
-
-       flexboot_nodnic_qp = (struct flexboot_nodnic_queue_pair *)zalloc(sizeof(*flexboot_nodnic_qp));
-       if ( flexboot_nodnic_qp == NULL ) {
-               status = MLX_OUT_OF_RESOURCES;
-               goto qp_alloc_err;
-       }
-
-       status = nodnic_port_create_qp(&port->port_priv, qp->type,
-                       qp->send.num_wqes * sizeof(struct nodnic_send_wqbb),
-                       qp->send.num_wqes,
-                       qp->recv.num_wqes * sizeof(struct nodnic_recv_wqe),
-                       qp->recv.num_wqes,
-                       &flexboot_nodnic_qp->nodnic_queue_pair);
-       MLX_FATAL_CHECK_STATUS(status, create_err,
-                       "nodnic_port_create_qp failed");
-       ib_qp_set_drvdata ( qp, flexboot_nodnic_qp );
-       return status;
-create_err:
-       free(flexboot_nodnic_qp);
-qp_alloc_err:
-       return status;
-}
-
-/**
- * Modify queue pair
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- * @ret rc             Return status code
- */
-static int flexboot_nodnic_modify_qp ( struct ib_device *ibdev __unused,
-                             struct ib_queue_pair *qp __unused) {
-       /*not needed*/
-       return 0;
-}
-
-/**
- * Destroy queue pair
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- */
-static void flexboot_nodnic_destroy_qp ( struct ib_device *ibdev,
-                               struct ib_queue_pair *qp ) {
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
-       struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp = ib_qp_get_drvdata ( qp );
-
-       nodnic_port_destroy_qp(&port->port_priv, qp->type,
-                       flexboot_nodnic_qp->nodnic_queue_pair);
-
-       free(flexboot_nodnic_qp);
-}
-
-/***************************************************************************
- *
- * Work request operations
- *
- ***************************************************************************
- */
-
-/**
- * Post send work queue entry
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- * @v av               Address vector
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int flexboot_nodnic_post_send ( struct ib_device *ibdev,
-                             struct ib_queue_pair *qp,
-                             struct ib_address_vector *av,
-                             struct io_buffer *iobuf) {
-
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp = ib_qp_get_drvdata ( qp );
-       struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
-       struct ib_work_queue *wq = &qp->send;
-       struct nodnic_send_wqbb *wqbb;
-       nodnic_qp *nodnic_qp = flexboot_nodnic_qp->nodnic_queue_pair;
-       struct nodnic_send_ring *send_ring = &nodnic_qp->send;
-       mlx_status status = MLX_SUCCESS;
-       unsigned int wqe_idx_mask;
-       unsigned long wqe_idx;
-
-       if ( ( port->port_priv.dma_state == FALSE ) ||
-                ( port->port_priv.port_state & NODNIC_PORT_DISABLING_DMA ) ) {
-               DBGC ( flexboot_nodnic, "flexboot_nodnic DMA disabled\n");
-               status = -ENETDOWN;
-               goto post_send_done;
-       }
-
-       /* Allocate work queue entry */
-       wqe_idx = wq->next_idx;
-       wqe_idx_mask = ( wq->num_wqes - 1 );
-       if ( wq->iobufs[wqe_idx & wqe_idx_mask] ) {
-               DBGC ( flexboot_nodnic, "flexboot_nodnic %p QPN %#lx send queue full\n",
-                               flexboot_nodnic, qp->qpn );
-               status = -ENOBUFS;
-               goto post_send_done;
-       }
-       wqbb = &send_ring->wqe_virt[wqe_idx & wqe_idx_mask];
-       wq->iobufs[wqe_idx & wqe_idx_mask] = iobuf;
-
-       assert ( flexboot_nodnic->callbacks->
-                       fill_send_wqe[qp->type] != NULL );
-       status = flexboot_nodnic->callbacks->
-                       fill_send_wqe[qp->type] ( ibdev, qp, av, iobuf,
-                                       wqbb, wqe_idx );
-       if ( status != 0 ) {
-               DBGC ( flexboot_nodnic, "flexboot_nodnic %p QPN %#lx fill send wqe failed\n",
-                               flexboot_nodnic, qp->qpn );
-               goto post_send_done;
-       }
-
-       wq->next_idx++;
-
-       status = port->port_priv.send_doorbell ( &port->port_priv,
-                               &send_ring->nodnic_ring, ( mlx_uint16 ) wq->next_idx );
-       if ( status != 0 ) {
-               DBGC ( flexboot_nodnic, "flexboot_nodnic %p ring send doorbell failed\n", flexboot_nodnic );
-       }
-
-post_send_done:
-       return status;
-}
-
-/**
- * Post receive work queue entry
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int flexboot_nodnic_post_recv ( struct ib_device *ibdev,
-                             struct ib_queue_pair *qp,
-                             struct io_buffer *iobuf ) {
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp = ib_qp_get_drvdata ( qp );
-       struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
-       struct ib_work_queue *wq = &qp->recv;
-       nodnic_qp *nodnic_qp = flexboot_nodnic_qp->nodnic_queue_pair;
-       struct nodnic_recv_ring *recv_ring = &nodnic_qp->receive;
-       struct nodnic_recv_wqe *wqe;
-       unsigned int wqe_idx_mask;
-       mlx_status status = MLX_SUCCESS;
-
-       /* Allocate work queue entry */
-       wqe_idx_mask = ( wq->num_wqes - 1 );
-       if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
-               DBGC ( flexboot_nodnic,
-                               "flexboot_nodnic %p QPN %#lx receive queue full\n",
-                               flexboot_nodnic, qp->qpn );
-               status = -ENOBUFS;
-               goto post_recv_done;
-       }
-       wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
-       wqe = &((struct nodnic_recv_wqe*)recv_ring->wqe_virt)[wq->next_idx & wqe_idx_mask];
-
-       MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_tailroom ( iobuf ) );
-       MLX_FILL_1 ( &wqe->data[0], 1, l_key, flexboot_nodnic->device_priv.lkey );
-       MLX_FILL_H ( &wqe->data[0], 2,
-                        local_address_h, virt_to_bus ( iobuf->data ) );
-       MLX_FILL_1 ( &wqe->data[0], 3,
-                        local_address_l, virt_to_bus ( iobuf->data ) );
-
-       wq->next_idx++;
-
-       status = port->port_priv.recv_doorbell ( &port->port_priv,
-                               &recv_ring->nodnic_ring, ( mlx_uint16 ) wq->next_idx );
-       if ( status != 0 ) {
-               DBGC ( flexboot_nodnic, "flexboot_nodnic %p ring receive doorbell failed\n", flexboot_nodnic );
-       }
-post_recv_done:
-       return status;
-}
-
-/***************************************************************************
- *
- * Event queues
- *
- ***************************************************************************
- */
-
-static void flexboot_nodnic_poll_eq ( struct ib_device *ibdev ) {
-       struct flexboot_nodnic *flexboot_nodnic;
-       struct flexboot_nodnic_port *port;
-       struct net_device *netdev;
-       nodnic_port_state state = 0;
-       mlx_status status;
-
-       if ( ! ibdev ) {
-               DBG ( "%s: ibdev = NULL!!!\n", __FUNCTION__ );
-               return;
-       }
-
-       flexboot_nodnic = ib_get_drvdata ( ibdev );
-       port = &flexboot_nodnic->port[ibdev->port - 1];
-       netdev = port->netdev;
-
-       if ( ! netdev_is_open ( netdev ) ) {
-               DBG2( "%s: port %d is closed\n", __FUNCTION__, port->ibdev->port );
-               return;
-       }
-
-       /* we don't poll EQ. Just poll link status if it's not active */
-       if ( ! netdev_link_ok ( netdev ) ) {
-               status = nodnic_port_get_state ( &port->port_priv, &state );
-               MLX_FATAL_CHECK_STATUS(status, state_err, "nodnic_port_get_state failed");
-
-               if ( state == nodnic_port_state_active ) {
-                       DBG( "%s: port %d physical link is up\n", __FUNCTION__,
-                                       port->ibdev->port );
-                       port->type->state_change ( flexboot_nodnic, port, 1 );
-               }
-       }
-state_err:
-       return;
-}
-
-/***************************************************************************
- *
- * Multicast group operations
- *
- ***************************************************************************
- */
-static int flexboot_nodnic_mcast_attach ( struct ib_device *ibdev,
-                                struct ib_queue_pair *qp,
-                                union ib_gid *gid) {
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
-       mlx_mac_address mac;
-       mlx_status status = MLX_SUCCESS;
-
-       switch (qp->type) {
-       case IB_QPT_ETH:
-               memcpy(&mac, &gid, sizeof(mac));
-               status = nodnic_port_add_mac_filter(&port->port_priv, mac);
-               MLX_CHECK_STATUS(flexboot_nodnic->device_priv, status, mac_err,
-                               "nodnic_port_add_mac_filter failed");
-               break;
-       default:
-               break;
-       }
-mac_err:
-       return status;
-}
-static void flexboot_nodnic_mcast_detach ( struct ib_device *ibdev,
-                                 struct ib_queue_pair *qp,
-                                 union ib_gid *gid ) {
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
-       mlx_mac_address mac;
-       mlx_status status = MLX_SUCCESS;
-
-       switch (qp->type) {
-       case IB_QPT_ETH:
-               memcpy(&mac, &gid, sizeof(mac));
-               status = nodnic_port_remove_mac_filter(&port->port_priv, mac);
-               MLX_CHECK_STATUS(flexboot_nodnic->device_priv, status, mac_err,
-                               "nodnic_port_remove_mac_filter failed");
-               break;
-       default:
-               break;
-       }
-mac_err:
-       return;
-}
-/***************************************************************************
- *
- * Infiniband link-layer operations
- *
- ***************************************************************************
- */
-
-/**
- * Initialise Infiniband link
- *
- * @v ibdev            Infiniband device
- * @ret rc             Return status code
- */
-static int flexboot_nodnic_ib_open ( struct ib_device *ibdev __unused) {
-       int rc = 0;
-
-       /*TODO: add implementation*/
-       return rc;
-}
-
-/**
- * Close Infiniband link
- *
- * @v ibdev            Infiniband device
- */
-static void flexboot_nodnic_ib_close ( struct ib_device *ibdev __unused) {
-       /*TODO: add implementation*/
-}
-
-/**
- * Inform embedded subnet management agent of a received MAD
- *
- * @v ibdev            Infiniband device
- * @v mad              MAD
- * @ret rc             Return status code
- */
-static int flexboot_nodnic_inform_sma ( struct ib_device *ibdev __unused,
-                              union ib_mad *mad __unused) {
-       /*TODO: add implementation*/
-       return 0;
-}
-
-/** flexboot_nodnic Infiniband operations */
-static struct ib_device_operations flexboot_nodnic_ib_operations = {
-       .create_cq      = flexboot_nodnic_create_cq,
-       .destroy_cq     = flexboot_nodnic_destroy_cq,
-       .create_qp      = flexboot_nodnic_create_qp,
-       .modify_qp      = flexboot_nodnic_modify_qp,
-       .destroy_qp     = flexboot_nodnic_destroy_qp,
-       .post_send      = flexboot_nodnic_post_send,
-       .post_recv      = flexboot_nodnic_post_recv,
-       .poll_cq        = flexboot_nodnic_poll_cq,
-       .poll_eq        = flexboot_nodnic_poll_eq,
-       .open           = flexboot_nodnic_ib_open,
-       .close          = flexboot_nodnic_ib_close,
-       .mcast_attach   = flexboot_nodnic_mcast_attach,
-       .mcast_detach   = flexboot_nodnic_mcast_detach,
-       .set_port_info  = flexboot_nodnic_inform_sma,
-       .set_pkey_table = flexboot_nodnic_inform_sma,
-};
-/***************************************************************************
- *
- *
- *
- ***************************************************************************
- */
-
-#define FLEX_NODNIC_TX_POLL_TOUT       500000
-#define FLEX_NODNIC_TX_POLL_USLEEP     10
-
-static void flexboot_nodnic_complete_all_tx ( struct flexboot_nodnic_port *port ) {
-       struct ib_device *ibdev = port->ibdev;
-       struct ib_completion_queue *cq;
-       struct ib_work_queue *wq;
-       int keep_polling = 0;
-       int timeout = FLEX_NODNIC_TX_POLL_TOUT;
-
-       list_for_each_entry ( cq, &ibdev->cqs, list ) {
-               do {
-                       ib_poll_cq ( ibdev, cq );
-                       keep_polling = 0;
-                       list_for_each_entry ( wq, &cq->work_queues, list ) {
-                               if ( wq->is_send )
-                                       keep_polling += ( wq->fill > 0 );
-                       }
-                       udelay ( FLEX_NODNIC_TX_POLL_USLEEP );
-               } while ( keep_polling && ( timeout-- > 0 ) );
-       }
-}
-
-static void flexboot_nodnic_port_disable_dma ( struct flexboot_nodnic_port *port ) {
-       nodnic_port_priv *port_priv = & ( port->port_priv );
-       mlx_status status;
-
-       if ( ! ( port_priv->port_state & NODNIC_PORT_OPENED ) )
-               return;
-
-       port_priv->port_state |= NODNIC_PORT_DISABLING_DMA;
-       flexboot_nodnic_complete_all_tx ( port );
-       if ( ( status = nodnic_port_disable_dma ( port_priv ) ) ) {
-               MLX_DEBUG_WARN ( port, "Failed to disable DMA %d\n", status );
-       }
-
-       port_priv->port_state &= ~NODNIC_PORT_DISABLING_DMA;
-}
-
-/***************************************************************************
- *
- * Ethernet operation
- *
- ***************************************************************************
- */
-
-/** Number of flexboot_nodnic Ethernet send work queue entries */
-#define FLEXBOOT_NODNIC_ETH_NUM_SEND_WQES 64
-
-/** Number of flexboot_nodnic Ethernet receive work queue entries */
-#define FLEXBOOT_NODNIC_ETH_NUM_RECV_WQES 64
-/** flexboot nodnic Ethernet queue pair operations */
-static struct ib_queue_pair_operations flexboot_nodnic_eth_qp_op = {
-       .alloc_iob = alloc_iob,
-};
-
-/**
- * Transmit packet via flexboot_nodnic Ethernet device
- *
- * @v netdev           Network device
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int flexboot_nodnic_eth_transmit ( struct net_device *netdev,
-                                struct io_buffer *iobuf) {
-       struct flexboot_nodnic_port *port = netdev->priv;
-       struct ib_device *ibdev = port->ibdev;
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       int rc;
-
-       rc = ib_post_send ( ibdev, port->eth_qp, NULL, iobuf);
-       /* Transmit packet */
-       if ( rc != 0) {
-               DBGC ( flexboot_nodnic, "NODNIC %p port %d could not transmit: %s\n",
-                               flexboot_nodnic, ibdev->port, strerror ( rc ) );
-               return rc;
-       }
-
-       return 0;
-}
-
-/**
- * Handle flexboot_nodnic Ethernet device send completion
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void flexboot_nodnic_eth_complete_send ( struct ib_device *ibdev __unused,
-                                      struct ib_queue_pair *qp,
-                                      struct io_buffer *iobuf,
-                                          int rc) {
-       struct net_device *netdev = ib_qp_get_ownerdata ( qp );
-
-       netdev_tx_complete_err ( netdev, iobuf, rc );
-}
-
-/**
- * Handle flexboot_nodnic Ethernet device receive completion
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- * @v av               Address vector, or NULL
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void flexboot_nodnic_eth_complete_recv ( struct ib_device *ibdev __unused,
-                               struct ib_queue_pair *qp,
-                               struct ib_address_vector *dest __unused,
-                               struct ib_address_vector *source,
-                                struct io_buffer *iobuf,
-                               int rc) {
-       struct net_device *netdev = ib_qp_get_ownerdata ( qp );
-
-       if ( rc != 0 ) {
-               DBG ( "Received packet with error\n" );
-               netdev_rx_err ( netdev, iobuf, rc );
-               return;
-       }
-
-       if ( source == NULL ) {
-               DBG ( "Received packet without address vector\n" );
-               netdev_rx_err ( netdev, iobuf, -ENOTTY );
-               return;
-       }
-       netdev_rx ( netdev, iobuf );
-}
-
-/** flexboot_nodnic Ethernet device completion operations */
-static struct ib_completion_queue_operations flexboot_nodnic_eth_cq_op = {
-       .complete_send = flexboot_nodnic_eth_complete_send,
-       .complete_recv = flexboot_nodnic_eth_complete_recv,
-};
-
-/**
- * Poll flexboot_nodnic Ethernet device
- *
- * @v netdev           Network device
- */
-static void flexboot_nodnic_eth_poll ( struct net_device *netdev) {
-       struct flexboot_nodnic_port *port = netdev->priv;
-       struct ib_device *ibdev = port->ibdev;
-
-       ib_poll_eq ( ibdev );
-}
-
-/**
- * Open flexboot_nodnic Ethernet device
- *
- * @v netdev           Network device
- * @ret rc             Return status code
- */
-static int flexboot_nodnic_eth_open ( struct net_device *netdev ) {
-       struct flexboot_nodnic_port *port = netdev->priv;
-       struct ib_device *ibdev = port->ibdev;
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       mlx_status status = MLX_SUCCESS;
-       struct ib_completion_queue *dummy_cq = NULL;
-       struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp = NULL;
-       mlx_uint64      cq_size = 0;
-       mlx_uint32      qpn = 0;
-       nodnic_port_state state = nodnic_port_state_down;
-
-       if ( port->port_priv.port_state & NODNIC_PORT_OPENED ) {
-               DBGC ( flexboot_nodnic, "%s: port %d is already opened\n",
-                               __FUNCTION__, port->ibdev->port );
-               return 0;
-       }
-
-       port->port_priv.port_state |= NODNIC_PORT_OPENED;
-
-       dummy_cq = zalloc ( sizeof ( struct ib_completion_queue ) );
-       if ( dummy_cq == NULL ) {
-               DBGC ( flexboot_nodnic, "%s: Failed to allocate dummy CQ\n", __FUNCTION__ );
-               status = MLX_OUT_OF_RESOURCES;
-               goto err_create_dummy_cq;
-       }
-       INIT_LIST_HEAD ( &dummy_cq->work_queues );
-
-       port->eth_qp = ib_create_qp ( ibdev, IB_QPT_ETH,
-                                       FLEXBOOT_NODNIC_ETH_NUM_SEND_WQES, dummy_cq,
-                                       FLEXBOOT_NODNIC_ETH_NUM_RECV_WQES, dummy_cq,
-                                       &flexboot_nodnic_eth_qp_op, netdev->name );
-       if ( !port->eth_qp ) {
-               DBGC ( flexboot_nodnic, "flexboot_nodnic %p port %d could not create queue pair\n",
-                                flexboot_nodnic, ibdev->port );
-               status = MLX_OUT_OF_RESOURCES;
-               goto err_create_qp;
-       }
-
-       ib_qp_set_ownerdata ( port->eth_qp, netdev );
-
-       status = nodnic_port_get_cq_size(&port->port_priv, &cq_size);
-       MLX_FATAL_CHECK_STATUS(status, get_cq_size_err,
-                       "nodnic_port_get_cq_size failed");
-
-       port->eth_cq = ib_create_cq ( ibdev, cq_size,
-                       &flexboot_nodnic_eth_cq_op );
-       if ( !port->eth_cq ) {
-               DBGC ( flexboot_nodnic,
-                       "flexboot_nodnic %p port %d could not create completion queue\n",
-                       flexboot_nodnic, ibdev->port );
-               status = MLX_OUT_OF_RESOURCES;
-               goto err_create_cq;
-       }
-       port->eth_qp->send.cq = port->eth_cq;
-       list_del(&port->eth_qp->send.list);
-       list_add ( &port->eth_qp->send.list, &port->eth_cq->work_queues );
-       port->eth_qp->recv.cq = port->eth_cq;
-       list_del(&port->eth_qp->recv.list);
-       list_add ( &port->eth_qp->recv.list, &port->eth_cq->work_queues );
-
-       status = nodnic_port_allocate_eq(&port->port_priv,
-               flexboot_nodnic->device_priv.device_cap.log_working_buffer_size);
-       MLX_FATAL_CHECK_STATUS(status, eq_alloc_err,
-                               "nodnic_port_allocate_eq failed");
-
-       status = nodnic_port_init(&port->port_priv);
-       MLX_FATAL_CHECK_STATUS(status, init_err,
-                                       "nodnic_port_init failed");
-
-       /* update qp - qpn */
-       flexboot_nodnic_qp = ib_qp_get_drvdata ( port->eth_qp );
-       status = nodnic_port_get_qpn(&port->port_priv,
-                       &flexboot_nodnic_qp->nodnic_queue_pair->send.nodnic_ring,
-                       &qpn);
-       MLX_FATAL_CHECK_STATUS(status, qpn_err,
-                                               "nodnic_port_get_qpn failed");
-       port->eth_qp->qpn = qpn;
-
-       /* Fill receive rings */
-       ib_refill_recv ( ibdev, port->eth_qp );
-
-       status = nodnic_port_enable_dma(&port->port_priv);
-       MLX_FATAL_CHECK_STATUS(status, dma_err,
-                                       "nodnic_port_enable_dma failed");
-
-       if (flexboot_nodnic->device_priv.device_cap.support_promisc_filter) {
-               status = nodnic_port_set_promisc(&port->port_priv, TRUE);
-               MLX_FATAL_CHECK_STATUS(status, promisc_err,
-                                                       "nodnic_port_set_promisc failed");
-       }
-
-       status = nodnic_port_get_state(&port->port_priv, &state);
-       MLX_FATAL_CHECK_STATUS(status, state_err,
-                                               "nodnic_port_get_state failed");
-
-       port->type->state_change (
-                       flexboot_nodnic, port, state == nodnic_port_state_active );
-
-       DBGC ( flexboot_nodnic, "%s: port %d opened (link is %s)\n",
-                       __FUNCTION__, port->ibdev->port,
-                       ( ( state == nodnic_port_state_active ) ? "Up" : "Down" ) );
-
-       free(dummy_cq);
-       return 0;
-state_err:
-promisc_err:
-dma_err:
-qpn_err:
-       nodnic_port_close(&port->port_priv);
-init_err:
-       nodnic_port_free_eq(&port->port_priv);
-eq_alloc_err:
-err_create_cq:
-get_cq_size_err:
-       ib_destroy_qp(ibdev, port->eth_qp );
-err_create_qp:
-       free(dummy_cq);
-err_create_dummy_cq:
-       port->port_priv.port_state &= ~NODNIC_PORT_OPENED;
-       return status;
-}
-
-/**
- * Close flexboot_nodnic Ethernet device
- *
- * @v netdev           Network device
- */
-static void flexboot_nodnic_eth_close ( struct net_device *netdev) {
-       struct flexboot_nodnic_port *port = netdev->priv;
-       struct ib_device *ibdev = port->ibdev;
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       mlx_status status = MLX_SUCCESS;
-
-       if ( ! ( port->port_priv.port_state & NODNIC_PORT_OPENED ) ) {
-               DBGC ( flexboot_nodnic, "%s: port %d is already closed\n",
-                               __FUNCTION__, port->ibdev->port );
-               return;
-       }
-
-       if (flexboot_nodnic->device_priv.device_cap.support_promisc_filter) {
-               if ( ( status = nodnic_port_set_promisc( &port->port_priv, FALSE ) ) ) {
-                       DBGC ( flexboot_nodnic,
-                                       "nodnic_port_set_promisc failed (status = %d)\n", status );
-               }
-       }
-
-       flexboot_nodnic_port_disable_dma ( port );
-
-       port->port_priv.port_state &= ~NODNIC_PORT_OPENED;
-
-       port->type->state_change ( flexboot_nodnic, port, FALSE );
-
-       /* Close port */
-       status = nodnic_port_close(&port->port_priv);
-       if ( status != MLX_SUCCESS ) {
-               DBGC ( flexboot_nodnic, "flexboot_nodnic %p port %d could not close port: %s\n",
-                               flexboot_nodnic, ibdev->port, strerror ( status ) );
-               /* Nothing we can do about this */
-       }
-
-       ib_destroy_qp ( ibdev, port->eth_qp );
-       port->eth_qp = NULL;
-       ib_destroy_cq ( ibdev, port->eth_cq );
-       port->eth_cq = NULL;
-
-       nodnic_port_free_eq(&port->port_priv);
-
-       DBGC ( flexboot_nodnic, "%s: port %d closed\n", __FUNCTION__, port->ibdev->port );
-}
-
-void flexboot_nodnic_eth_irq ( struct net_device *netdev, int enable ) {
-       struct flexboot_nodnic_port *port = netdev->priv;
-
-       if ( enable ) {
-               if ( ( port->port_priv.port_state & NODNIC_PORT_OPENED ) &&
-                        ! ( port->port_priv.port_state & NODNIC_PORT_DISABLING_DMA ) ) {
-                       flexboot_nodnic_arm_cq ( port );
-               } else {
-                       /* do nothing */
-               }
-       } else {
-               nodnic_device_clear_int( port->port_priv.device );
-       }
-}
-
-/** flexboot_nodnic Ethernet network device operations */
-static struct net_device_operations flexboot_nodnic_eth_operations = {
-       .open           = flexboot_nodnic_eth_open,
-       .close          = flexboot_nodnic_eth_close,
-       .transmit       = flexboot_nodnic_eth_transmit,
-       .poll           = flexboot_nodnic_eth_poll,
-};
-
-/**
- * Register flexboot_nodnic Ethernet device
- */
-static int flexboot_nodnic_register_netdev ( struct flexboot_nodnic *flexboot_nodnic,
-                                   struct flexboot_nodnic_port *port) {
-       mlx_status status = MLX_SUCCESS;
-       struct net_device       *netdev;
-       struct ib_device        *ibdev = port->ibdev;
-       union {
-               uint8_t bytes[8];
-               uint32_t dwords[2];
-       } mac;
-
-       /* Allocate network devices */
-       netdev = alloc_etherdev ( 0 );
-       if ( netdev == NULL ) {
-               DBGC ( flexboot_nodnic, "flexboot_nodnic %p port %d could not allocate net device\n",
-                               flexboot_nodnic, ibdev->port );
-               status = MLX_OUT_OF_RESOURCES;
-               goto alloc_err;
-       }
-       port->netdev = netdev;
-       netdev_init ( netdev, &flexboot_nodnic_eth_operations );
-       netdev->dev = ibdev->dev;
-       netdev->priv = port;
-
-       status = nodnic_port_query(&port->port_priv,
-                       nodnic_port_option_mac_high,
-                       &mac.dwords[0]);
-       MLX_FATAL_CHECK_STATUS(status, mac_err,
-                       "failed to query mac high");
-       status = nodnic_port_query(&port->port_priv,
-                       nodnic_port_option_mac_low,
-                       &mac.dwords[1]);
-       MLX_FATAL_CHECK_STATUS(status, mac_err,
-                               "failed to query mac low");
-       mac.dwords[0] = htonl(mac.dwords[0]);
-       mac.dwords[1] = htonl(mac.dwords[1]);
-       memcpy ( netdev->hw_addr,
-                        &mac.bytes[2], ETH_ALEN);
-       /* Register network device */
-       status = register_netdev ( netdev );
-       if ( status != MLX_SUCCESS ) {
-               DBGC ( flexboot_nodnic,
-                       "flexboot_nodnic %p port %d could not register network device: %s\n",
-                       flexboot_nodnic, ibdev->port, strerror ( status ) );
-               goto reg_err;
-       }
-       return status;
-reg_err:
-mac_err:
-       netdev_put ( netdev );
-alloc_err:
-       return status;
-}
-
-/**
- * Handle flexboot_nodnic Ethernet device port state change
- */
-static void flexboot_nodnic_state_change_netdev ( struct flexboot_nodnic *flexboot_nodnic __unused,
-                                        struct flexboot_nodnic_port *port,
-                                        int link_up ) {
-       struct net_device *netdev = port->netdev;
-
-       if ( link_up )
-               netdev_link_up ( netdev );
-       else
-               netdev_link_down ( netdev );
-
-}
-
-/**
- * Unregister flexboot_nodnic Ethernet device
- */
-static void flexboot_nodnic_unregister_netdev ( struct flexboot_nodnic *flexboot_nodnic __unused,
-                                      struct flexboot_nodnic_port *port ) {
-       struct net_device *netdev = port->netdev;
-       unregister_netdev ( netdev );
-       netdev_nullify ( netdev );
-       netdev_put ( netdev );
-}
-
-/** flexboot_nodnic Ethernet port type */
-static struct flexboot_nodnic_port_type flexboot_nodnic_port_type_eth = {
-       .register_dev = flexboot_nodnic_register_netdev,
-       .state_change = flexboot_nodnic_state_change_netdev,
-       .unregister_dev = flexboot_nodnic_unregister_netdev,
-};
-
-/***************************************************************************
- *
- * PCI interface helper functions
- *
- ***************************************************************************
- */
-static
-mlx_status
-flexboot_nodnic_allocate_infiniband_devices( struct flexboot_nodnic *flexboot_nodnic_priv ) {
-       mlx_status status = MLX_SUCCESS;
-       nodnic_device_priv *device_priv = &flexboot_nodnic_priv->device_priv;
-       struct pci_device *pci = flexboot_nodnic_priv->pci;
-       struct ib_device *ibdev = NULL;
-       unsigned int i = 0;
-
-       /* Allocate Infiniband devices */
-       for (; i < device_priv->device_cap.num_ports; i++) {
-               if ( ! ( flexboot_nodnic_priv->port_mask & ( i + 1 ) ) )
-                       continue;
-               ibdev = alloc_ibdev(0);
-               if (ibdev == NULL) {
-                       status = MLX_OUT_OF_RESOURCES;
-                       goto err_alloc_ibdev;
-               }
-               flexboot_nodnic_priv->port[i].ibdev = ibdev;
-               ibdev->op = &flexboot_nodnic_ib_operations;
-               ibdev->dev = &pci->dev;
-               ibdev->port = ( FLEXBOOT_NODNIC_PORT_BASE + i);
-               ib_set_drvdata(ibdev, flexboot_nodnic_priv);
-       }
-       return status;
-err_alloc_ibdev:
-       for ( i-- ; ( signed int ) i >= 0 ; i-- )
-               ibdev_put ( flexboot_nodnic_priv->port[i].ibdev );
-       return status;
-}
-
-static
-mlx_status
-flexboot_nodnic_thin_init_ports( struct flexboot_nodnic *flexboot_nodnic_priv ) {
-       mlx_status status = MLX_SUCCESS;
-       nodnic_device_priv *device_priv = &flexboot_nodnic_priv->device_priv;
-       nodnic_port_priv *port_priv = NULL;
-       unsigned int i = 0;
-
-       for ( i = 0; i < device_priv->device_cap.num_ports; i++ ) {
-               if ( ! ( flexboot_nodnic_priv->port_mask & ( i + 1 ) ) )
-                       continue;
-               port_priv = &flexboot_nodnic_priv->port[i].port_priv;
-               status = nodnic_port_thin_init( device_priv, port_priv, i );
-               MLX_FATAL_CHECK_STATUS(status, thin_init_err,
-                               "flexboot_nodnic_thin_init_ports failed");
-       }
-thin_init_err:
-       return status;
-}
-
-
-static
-mlx_status
-flexboot_nodnic_set_ports_type ( struct flexboot_nodnic *flexboot_nodnic_priv ) {
-       mlx_status status = MLX_SUCCESS;
-       nodnic_device_priv      *device_priv = &flexboot_nodnic_priv->device_priv;
-       nodnic_port_priv        *port_priv = NULL;
-       nodnic_port_type        type = NODNIC_PORT_TYPE_UNKNOWN;
-       unsigned int i = 0;
-
-       for ( i = 0 ; i < device_priv->device_cap.num_ports ; i++ ) {
-               if ( ! ( flexboot_nodnic_priv->port_mask & ( i + 1 ) ) )
-                       continue;
-               port_priv = &flexboot_nodnic_priv->port[i].port_priv;
-               status = nodnic_port_get_type(port_priv, &type);
-               MLX_FATAL_CHECK_STATUS(status, type_err,
-                               "nodnic_port_get_type failed");
-               switch ( type ) {
-               case NODNIC_PORT_TYPE_ETH:
-                       DBGC ( flexboot_nodnic_priv, "Port %d type is Ethernet\n", i );
-                       flexboot_nodnic_priv->port[i].type = &flexboot_nodnic_port_type_eth;
-                       break;
-               case NODNIC_PORT_TYPE_IB:
-                       DBGC ( flexboot_nodnic_priv, "Port %d type is Infiniband\n", i );
-                       status = MLX_UNSUPPORTED;
-                       goto type_err;
-               default:
-                       DBGC ( flexboot_nodnic_priv, "Port %d type is unknown\n", i );
-                       status = MLX_UNSUPPORTED;
-                       goto type_err;
-               }
-       }
-type_err:
-       return status;
-}
-
-static
-mlx_status
-flexboot_nodnic_ports_register_dev( struct flexboot_nodnic *flexboot_nodnic_priv ) {
-       mlx_status status = MLX_SUCCESS;
-       nodnic_device_priv *device_priv = &flexboot_nodnic_priv->device_priv;
-       struct flexboot_nodnic_port *port = NULL;
-       unsigned int i = 0;
-
-       for (; i < device_priv->device_cap.num_ports; i++) {
-               if ( ! ( flexboot_nodnic_priv->port_mask & ( i + 1 ) ) )
-                       continue;
-               port = &flexboot_nodnic_priv->port[i];
-               status = port->type->register_dev ( flexboot_nodnic_priv, port );
-               MLX_FATAL_CHECK_STATUS(status, reg_err,
-                               "port register_dev failed");
-       }
-reg_err:
-       return status;
-}
-
-static
-mlx_status
-flexboot_nodnic_ports_unregister_dev ( struct flexboot_nodnic *flexboot_nodnic_priv ) {
-       struct flexboot_nodnic_port *port;
-       nodnic_device_priv      *device_priv = &flexboot_nodnic_priv->device_priv;
-       int i = (device_priv->device_cap.num_ports - 1);
-
-       for (; i >= 0; i--) {
-               if ( ! ( flexboot_nodnic_priv->port_mask & ( i + 1 ) ) )
-                       continue;
-               port = &flexboot_nodnic_priv->port[i];
-               port->type->unregister_dev(flexboot_nodnic_priv, port);
-               ibdev_put(flexboot_nodnic_priv->port[i].ibdev);
-       }
-       return MLX_SUCCESS;
-}
-
-/***************************************************************************
- *
- * flexboot nodnic interface
- *
- ***************************************************************************
- */
-__unused static void flexboot_nodnic_enable_dma ( struct flexboot_nodnic *nodnic ) {
-       nodnic_port_priv *port_priv;
-       mlx_status status;
-       int i;
-
-       for ( i = 0; i < nodnic->device_priv.device_cap.num_ports; i++ ) {
-               if ( ! ( nodnic->port_mask & ( i + 1 ) ) )
-                       continue;
-               port_priv = & ( nodnic->port[i].port_priv );
-               if ( ! ( port_priv->port_state & NODNIC_PORT_OPENED ) )
-                       continue;
-
-               if ( ( status = nodnic_port_enable_dma ( port_priv ) ) ) {
-                       MLX_DEBUG_WARN ( nodnic, "Failed to enable DMA %d\n", status );
-               }
-       }
-}
-
-__unused static void flexboot_nodnic_disable_dma ( struct flexboot_nodnic *nodnic ) {
-       int i;
-
-       for ( i = 0; i < nodnic->device_priv.device_cap.num_ports; i++ ) {
-               if ( ! ( nodnic->port_mask & ( i + 1 ) ) )
-                       continue;
-               flexboot_nodnic_port_disable_dma ( & ( nodnic->port[i] ) );
-       }
-}
-
-int flexboot_nodnic_is_supported ( struct pci_device *pci ) {
-       mlx_utils utils;
-       mlx_pci_gw_buffer buffer;
-       mlx_status status;
-       int is_supported = 0;
-
-       DBG ( "%s: start\n", __FUNCTION__ );
-
-       memset ( &utils, 0, sizeof ( utils ) );
-
-       status = mlx_utils_init ( &utils, pci );
-       MLX_CHECK_STATUS ( pci, status, utils_init_err, "mlx_utils_init failed" );
-
-       status = mlx_pci_gw_init ( &utils );
-       MLX_CHECK_STATUS ( pci, status, pci_gw_init_err, "mlx_pci_gw_init failed" );
-
-       status = mlx_pci_gw_read ( &utils, PCI_GW_SPACE_NODNIC,
-                       NODNIC_NIC_INTERFACE_SUPPORTED_OFFSET, &buffer );
-
-       if ( status == MLX_SUCCESS ) {
-               buffer >>= NODNIC_NIC_INTERFACE_SUPPORTED_BIT;
-               is_supported = ( buffer & 0x1 );
-       }
-
-       mlx_pci_gw_teardown( &utils );
-
-pci_gw_init_err:
-utils_init_err:
-       DBG ( "%s: NODNIC is %s supported (status = %d)\n",
-                       __FUNCTION__, ( is_supported ? "": "not" ), status );
-       return is_supported;
-}
-
-void flexboot_nodnic_copy_mac ( uint8_t mac_addr[], uint32_t low_byte,
-               uint16_t high_byte ) {
-       union mac_addr {
-               struct {
-                       uint32_t low_byte;
-                       uint16_t high_byte;
-               };
-               uint8_t mac_addr[ETH_ALEN];
-       } mac_addr_aux;
-
-       mac_addr_aux.high_byte = high_byte;
-       mac_addr_aux.low_byte = low_byte;
-
-       mac_addr[0] = mac_addr_aux.mac_addr[5];
-       mac_addr[1] = mac_addr_aux.mac_addr[4];
-       mac_addr[2] = mac_addr_aux.mac_addr[3];
-       mac_addr[3] = mac_addr_aux.mac_addr[2];
-       mac_addr[4] = mac_addr_aux.mac_addr[1];
-       mac_addr[5] = mac_addr_aux.mac_addr[0];
-}
-
-static mlx_status flexboot_nodnic_get_factory_mac (
-               struct flexboot_nodnic *flexboot_nodnic_priv, uint8_t port __unused ) {
-       struct mlx_vmac_query_virt_mac virt_mac;
-       mlx_status status;
-
-       memset ( & virt_mac, 0, sizeof ( virt_mac ) );
-       status = mlx_vmac_query_virt_mac ( flexboot_nodnic_priv->device_priv.utils,
-                       &virt_mac );
-       if ( ! status ) {
-               DBGC ( flexboot_nodnic_priv, "NODNIC %p Failed to set the virtual MAC\n",
-                       flexboot_nodnic_priv );
-       }
-
-       return status;
-}
-
-/**
- * Set port masking
- *
- * @v flexboot_nodnic          nodnic device
- * @ret rc             Return status code
- */
-static int flexboot_nodnic_set_port_masking ( struct flexboot_nodnic *flexboot_nodnic ) {
-       unsigned int i;
-       nodnic_device_priv *device_priv = &flexboot_nodnic->device_priv;
-
-       flexboot_nodnic->port_mask = 0;
-       for ( i = 0; i < device_priv->device_cap.num_ports; i++ ) {
-               flexboot_nodnic->port_mask |= (i + 1);
-       }
-
-       if ( ! flexboot_nodnic->port_mask ) {
-               /* No port was enabled */
-               DBGC ( flexboot_nodnic, "NODNIC %p No port was enabled for "
-                               "booting\n", flexboot_nodnic );
-               return -ENETUNREACH;
-       }
-
-       return 0;
-}
-
-int flexboot_nodnic_probe ( struct pci_device *pci,
-               struct flexboot_nodnic_callbacks *callbacks,
-               void *drv_priv __unused ) {
-       mlx_status status = MLX_SUCCESS;
-       struct flexboot_nodnic *flexboot_nodnic_priv = NULL;
-       nodnic_device_priv *device_priv = NULL;
-       int i = 0;
-
-       if ( ( pci == NULL ) || ( callbacks == NULL ) ) {
-               DBGC ( flexboot_nodnic_priv, "%s: Bad Parameter\n", __FUNCTION__ );
-               return -EINVAL;
-       }
-
-       flexboot_nodnic_priv = zalloc( sizeof ( *flexboot_nodnic_priv ) );
-       if ( flexboot_nodnic_priv == NULL ) {
-               DBGC ( flexboot_nodnic_priv, "%s: Failed to allocate priv data\n", __FUNCTION__ );
-               status = MLX_OUT_OF_RESOURCES;
-               goto device_err_alloc;
-       }
-
-       /* Register settings
-        * Note that pci->priv will be the device private data */
-       flexboot_nodnic_priv->pci = pci;
-       flexboot_nodnic_priv->callbacks = callbacks;
-       pci_set_drvdata ( pci, flexboot_nodnic_priv );
-
-       device_priv = &flexboot_nodnic_priv->device_priv;
-       device_priv->utils = (mlx_utils *)zalloc( sizeof ( mlx_utils ) );
-       if ( device_priv->utils == NULL ) {
-               DBGC ( flexboot_nodnic_priv, "%s: Failed to allocate utils\n", __FUNCTION__ );
-               status = MLX_OUT_OF_RESOURCES;
-               goto utils_err_alloc;
-       }
-
-       status = mlx_utils_init( device_priv->utils, pci );
-       MLX_FATAL_CHECK_STATUS(status, utils_init_err,
-                       "mlx_utils_init failed");
-
-       /* nodnic init*/
-       status = mlx_pci_gw_init( device_priv->utils );
-       MLX_FATAL_CHECK_STATUS(status, cmd_init_err,
-                       "mlx_pci_gw_init failed");
-
-       /* init device */
-       status = nodnic_device_init( device_priv );
-       MLX_FATAL_CHECK_STATUS(status, device_init_err,
-                               "nodnic_device_init failed");
-
-       status = nodnic_device_get_cap( device_priv );
-       MLX_FATAL_CHECK_STATUS(status, get_cap_err,
-                                       "nodnic_device_get_cap failed");
-
-       status =  flexboot_nodnic_set_port_masking ( flexboot_nodnic_priv );
-       MLX_FATAL_CHECK_STATUS(status, err_set_masking,
-                                               "flexboot_nodnic_set_port_masking failed");
-
-       status = flexboot_nodnic_allocate_infiniband_devices( flexboot_nodnic_priv );
-       MLX_FATAL_CHECK_STATUS(status, err_alloc_ibdev,
-                                       "flexboot_nodnic_allocate_infiniband_devices failed");
-
-       /* port init */
-       status = flexboot_nodnic_thin_init_ports( flexboot_nodnic_priv );
-       MLX_FATAL_CHECK_STATUS(status, err_thin_init_ports,
-                                               "flexboot_nodnic_thin_init_ports failed");
-
-       /* device reg */
-       status = flexboot_nodnic_set_ports_type( flexboot_nodnic_priv );
-       MLX_CHECK_STATUS( flexboot_nodnic_priv, status, err_set_ports_types,
-                                               "flexboot_nodnic_set_ports_type failed");
-
-       status = flexboot_nodnic_ports_register_dev( flexboot_nodnic_priv );
-       MLX_FATAL_CHECK_STATUS(status, reg_err,
-                                       "flexboot_nodnic_ports_register_dev failed");
-
-       for ( i = 0; i < device_priv->device_cap.num_ports; i++ ) {
-               if ( ! ( flexboot_nodnic_priv->port_mask & ( i + 1 ) ) )
-                       continue;
-               flexboot_nodnic_get_factory_mac ( flexboot_nodnic_priv, i );
-       }
-
-       /* Update ETH operations with IRQ function if supported */
-       DBGC ( flexboot_nodnic_priv, "%s: %s IRQ function\n",
-                       __FUNCTION__, ( callbacks->irq ? "Valid" : "No" ) );
-       flexboot_nodnic_eth_operations.irq = callbacks->irq;
-       return 0;
-
-       flexboot_nodnic_ports_unregister_dev ( flexboot_nodnic_priv );
-reg_err:
-err_set_ports_types:
-err_thin_init_ports:
-err_alloc_ibdev:
-err_set_masking:
-get_cap_err:
-       nodnic_device_teardown ( device_priv );
-device_init_err:
-       mlx_pci_gw_teardown ( device_priv->utils );
-cmd_init_err:
-utils_init_err:
-       free ( device_priv->utils );
-utils_err_alloc:
-       free ( flexboot_nodnic_priv );
-device_err_alloc:
-       return status;
-}
-
-void flexboot_nodnic_remove ( struct pci_device *pci )
-{
-       struct flexboot_nodnic *flexboot_nodnic_priv = pci_get_drvdata ( pci );
-       nodnic_device_priv *device_priv = & ( flexboot_nodnic_priv->device_priv );
-
-       flexboot_nodnic_ports_unregister_dev ( flexboot_nodnic_priv );
-       nodnic_device_teardown( device_priv );
-       mlx_pci_gw_teardown( device_priv->utils );
-       free( device_priv->utils );
-       free( flexboot_nodnic_priv );
-}
diff --git a/roms/ipxe/src/drivers/infiniband/flexboot_nodnic.h b/roms/ipxe/src/drivers/infiniband/flexboot_nodnic.h
deleted file mode 100644 (file)
index 8027229..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-#ifndef SRC_DRIVERS_INFINIBAND_FLEXBOOT_NODNIC_FLEXBOOT_NODNIC_H_
-#define SRC_DRIVERS_INFINIBAND_FLEXBOOT_NODNIC_FLEXBOOT_NODNIC_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_nodnic/include/mlx_nodnic_data_structures.h"
-#include "nodnic_prm.h"
-#include <ipxe/io.h>
-#include <ipxe/infiniband.h>
-#include <ipxe/netdevice.h>
-
-/*
- * If defined, use interrupts in NODNIC driver
- */
-#define NODNIC_IRQ_ENABLED
-
-#define FLEXBOOT_NODNIC_MAX_PORTS              2
-#define FLEXBOOT_NODNIC_PORT_BASE              1
-
-#define FLEXBOOT_NODNIC_OPCODE_SEND            0xa
-
-/* Port protocol */
-enum flexboot_nodnic_protocol {
-       FLEXBOOT_NODNIC_PROT_IB_IPV6 = 0,
-       FLEXBOOT_NODNIC_PROT_ETH,
-       FLEXBOOT_NODNIC_PROT_IB_IPV4,
-       FLEXBOOT_NODNIC_PROT_FCOE
-};
-
-/** A flexboot nodnic port */
-struct flexboot_nodnic_port {
-       /** Infiniband device */
-       struct ib_device *ibdev;
-       /** Network device */
-       struct net_device *netdev;
-       /** nodic port */
-       nodnic_port_priv port_priv;
-       /** Port type */
-       struct flexboot_nodnic_port_type *type;
-       /** Ethernet completion queue */
-       struct ib_completion_queue *eth_cq;
-       /** Ethernet queue pair */
-       struct ib_queue_pair *eth_qp;
-};
-
-
-/** A flexboot nodnic queue pair */
-struct flexboot_nodnic_queue_pair {
-       nodnic_qp *nodnic_queue_pair;
-};
-
-/** A flexboot nodnic cq */
-struct flexboot_nodnic_completion_queue {
-       nodnic_cq *nodnic_completion_queue;
-};
-
-/** A flexboot_nodnic device */
-struct flexboot_nodnic {
-       /** PCI device */
-       struct pci_device *pci;
-       /** nic specific data*/
-       struct flexboot_nodnic_callbacks *callbacks;
-       /**nodnic device*/
-       nodnic_device_priv device_priv;
-       /**flexboot_nodnic ports*/
-       struct flexboot_nodnic_port port[FLEXBOOT_NODNIC_MAX_PORTS];
-       /** Device open request counter */
-       unsigned int open_count;
-       /** Port masking  */
-       u16 port_mask;
-       /** device private data */
-       void *priv_data;
-};
-
-/** A flexboot_nodnic port type */
-struct flexboot_nodnic_port_type {
-       /** Register port
-        *
-        * @v flexboot_nodnic           flexboot_nodnic device
-        * @v port              flexboot_nodnic port
-        * @ret mlx_status              Return status code
-        */
-       mlx_status ( * register_dev ) (
-                       struct flexboot_nodnic *flexboot_nodnic,
-                       struct flexboot_nodnic_port *port
-                       );
-       /** Port state changed
-        *
-        * @v flexboot_nodnic           flexboot_nodnic device
-        * @v port              flexboot_nodnic port
-        * @v link_up           Link is up
-        */
-       void ( * state_change ) (
-                       struct flexboot_nodnic *flexboot_nodnic,
-                                 struct flexboot_nodnic_port *port,
-                                 int link_up
-                                 );
-       /** Unregister port
-        *
-        * @v flexboot_nodnic           flexboot_nodnic device
-        * @v port              flexboot_nodnic port
-        */
-       void ( * unregister_dev ) (
-                       struct flexboot_nodnic *flexboot_nodnic,
-                       struct flexboot_nodnic_port *port
-                       );
-};
-
-struct cqe_data{
-       mlx_boolean owner;
-       mlx_uint32 qpn;
-       mlx_uint32 is_send;
-       mlx_uint32 is_error;
-       mlx_uint32 syndrome;
-       mlx_uint32 vendor_err_syndrome;
-       mlx_uint32 wqe_counter;
-       mlx_uint32 byte_cnt;
-};
-
-struct flexboot_nodnic_callbacks {
-       mlx_status ( * fill_completion ) ( void *cqe, struct cqe_data *cqe_data );
-       mlx_status ( * cqe_set_owner ) ( void *cq, unsigned int num_cqes );
-       mlx_size ( * get_cqe_size ) ();
-       mlx_status ( * fill_send_wqe[5] ) (
-                               struct ib_device *ibdev,
-                               struct ib_queue_pair *qp,
-                               struct ib_address_vector *av,
-                               struct io_buffer *iobuf,
-                               struct nodnic_send_wqbb *wqbb,
-                               unsigned long wqe_idx
-                               );
-       void ( * irq ) ( struct net_device *netdev, int enable );
-};
-
-int flexboot_nodnic_probe ( struct pci_device *pci,
-               struct flexboot_nodnic_callbacks *callbacks,
-               void *drv_priv );
-void flexboot_nodnic_remove ( struct pci_device *pci );
-void flexboot_nodnic_eth_irq ( struct net_device *netdev, int enable );
-int flexboot_nodnic_is_supported ( struct pci_device *pci );
-void flexboot_nodnic_copy_mac ( uint8_t mac_addr[], uint32_t low_byte,
-               uint16_t high_byte );
-
-#endif /* SRC_DRIVERS_INFINIBAND_FLEXBOOT_NODNIC_FLEXBOOT_NODNIC_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/golan.c b/roms/ipxe/src/drivers/infiniband/golan.c
deleted file mode 100755 (executable)
index d410fdf..0000000
+++ /dev/null
@@ -1,2672 +0,0 @@
-/*
- * Copyright (C) 2013-2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <errno.h>
-#include <strings.h>
-#include <byteswap.h>
-#include <ipxe/malloc.h>
-#include <ipxe/umalloc.h>
-#include <ipxe/infiniband.h>
-#include <ipxe/ib_smc.h>
-#include <ipxe/iobuf.h>
-#include <ipxe/netdevice.h>
-#include <ipxe/ethernet.h>
-#include <ipxe/if_ether.h>
-#include <ipxe/in.h>
-#include <ipxe/ipoib.h>
-#include "flexboot_nodnic.h"
-#include "nodnic_shomron_prm.h"
-#include "golan.h"
-#include "mlx_utils/include/public/mlx_bail.h"
-#include "mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h"
-#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h"
-#include "mlx_utils/include/public/mlx_pci_gw.h"
-#include "mlx_nodnic/include/mlx_port.h"
-
-/******************************************************************************/
-/************* Very simple memory management for umalloced pages **************/
-/******* Temporary solution until full memory management is implemented *******/
-/******************************************************************************/
-#define GOLAN_PAGES    20
-struct golan_page {
-       struct list_head list;
-       userptr_t addr;
-};
-
-static void golan_free_pages ( struct list_head *head ) {
-       struct golan_page *page, *tmp;
-       list_for_each_entry_safe ( page, tmp, head, list ) {
-               list_del ( &page->list );
-               ufree ( page->addr );
-               free ( page );
-       }
-}
-
-static int golan_init_pages ( struct list_head *head ) {
-       struct golan_page *new_entry;
-       int rc, i;
-
-       if ( !head ) {
-               rc = -EINVAL;
-               goto err_golan_init_pages_bad_param;
-       }
-
-       INIT_LIST_HEAD ( head );
-
-       for ( i = 0; i < GOLAN_PAGES; i++ ) {
-               new_entry = zalloc ( sizeof ( *new_entry ) );
-               if ( new_entry == NULL ) {
-                       rc = -ENOMEM;
-                       goto err_golan_init_pages_alloc_page;
-               }
-               new_entry->addr = umalloc ( GOLAN_PAGE_SIZE );
-               if ( new_entry->addr == UNULL ) {
-                       free ( new_entry );
-                       rc = -ENOMEM;
-                       goto err_golan_init_pages_alloc_page;
-               }
-               list_add ( &new_entry->list, head );
-       }
-
-       return 0;
-
-err_golan_init_pages_alloc_page:
-       golan_free_pages ( head );
-err_golan_init_pages_bad_param:
-       return rc;
-}
-
-static userptr_t golan_get_page ( struct list_head *head ) {
-       struct golan_page *page;
-       userptr_t addr;
-
-       if ( list_empty ( head ) )
-               return UNULL;
-
-       page = list_first_entry ( head, struct golan_page, list );
-       list_del ( &page->list );
-       addr = page->addr;
-       free ( page );
-       return addr;
-}
-
-/******************************************************************************/
-
-const char *golan_qp_state_as_string[] = {
-       "RESET",
-       "INIT",
-       "RTR",
-       "RTS",
-       "SQD",
-       "SQE",
-       "ERR"
-};
-
-static inline int golan_check_rc_and_cmd_status ( struct golan_cmd_layout *cmd, int rc ) {
-       struct golan_outbox_hdr *out_hdr = ( struct golan_outbox_hdr * ) ( cmd->out );
-       if ( rc == -EBUSY ) {
-               DBG ( "HCA is busy (rc = -EBUSY)\n" );
-               return rc;
-       } else if ( out_hdr->status ) {
-               DBG("%s status = 0x%x - syndrom = 0x%x\n", __FUNCTION__,
-                               out_hdr->status, be32_to_cpu(out_hdr->syndrome));
-               return out_hdr->status;
-       }
-       return 0;
-}
-
-#define GOLAN_CHECK_RC_AND_CMD_STATUS(_lable)                                                  \
-               do {                                                                                                                    \
-                       if ( ( rc = golan_check_rc_and_cmd_status ( cmd, rc ) ) )       \
-                               goto _lable;                                                                                    \
-               } while (0)
-
-#define GOLAN_PRINT_RC_AND_CMD_STATUS  golan_check_rc_and_cmd_status ( cmd, rc )
-
-
-struct mbox {
-       union {
-               struct golan_cmd_prot_block     mblock;
-               u8      data[MAILBOX_STRIDE];
-               __be64  qdata[MAILBOX_STRIDE >> 3];
-       };
-};
-
-static inline uint32_t  ilog2(uint32_t mem)
-{
-       return ( fls ( mem ) - 1 );
-}
-
-#define        CTRL_SIG_SZ     (sizeof(mailbox->mblock) - sizeof(mailbox->mblock.bdata) - 2)
-
-static inline u8 xor8_buf(void *buf, int len)
-{
-       u8 sum = 0;
-       int i;
-       u8 *ptr = buf;
-
-       for (i = 0; i < len; ++i)
-               sum ^= ptr[i];
-
-       return sum;
-}
-
-static inline int verify_block_sig(struct golan_cmd_prot_block *block)
-{
-       if (xor8_buf(block->rsvd0, sizeof(*block) - sizeof(block->data) - 1) != 0xff)
-               return -EINVAL;
-
-       if (xor8_buf(block, sizeof(*block)) != 0xff)
-               return -EINVAL;
-       return 0;
-}
-
-static inline const char *cmd_status_str(u8 status)
-{
-       switch (status) {
-               case 0x0:       return "OK";
-               case 0x1:       return "internal error";
-               case 0x2:       return "bad operation";
-               case 0x3:       return "bad parameter";
-               case 0x4:       return "bad system state";
-               case 0x5:       return "bad resource";
-               case 0x6:       return "resource busy";
-               case 0x8:       return "limits exceeded";
-               case 0x9:       return "bad resource state";
-               case 0xa:       return "bad index";
-               case 0xf:       return "no resources";
-               case 0x50:      return "bad input length";
-               case 0x51:      return "bad output length";
-               case 0x10:      return "bad QP state";
-               case 0x30:      return "bad packet (discarded)";
-               case 0x40:      return "bad size too many outstanding CQEs";
-               case 0xff:      return "Command Timed Out";
-               default:        return "unknown status";
-       }
-}
-
-static inline uint16_t fw_rev_maj(struct golan *golan)
-{
-       return be32_to_cpu(readl(&golan->iseg->fw_rev)) & 0xffff;
-}
-
-static inline u16 fw_rev_min(struct golan *golan)
-{
-       return be32_to_cpu(readl(&golan->iseg->fw_rev)) >> 16;
-}
-
-static inline u16 fw_rev_sub(struct golan *golan)
-{
-       return be32_to_cpu(readl(&golan->iseg->cmdif_rev_fw_sub)) & 0xffff;
-}
-
-static inline u16 cmdif_rev(struct golan *golan)
-{
-       return be32_to_cpu(readl(&golan->iseg->cmdif_rev_fw_sub)) >> 16;
-}
-
-
-static inline struct golan_cmd_layout *get_cmd( struct golan *golan, int idx )
-{
-       return golan->cmd.addr + (idx << golan->cmd.log_stride);
-}
-
-static inline void golan_calc_sig(struct golan *golan, uint32_t cmd_idx,
-                               uint32_t inbox_idx, uint32_t outbox_idx)
-{
-       struct golan_cmd_layout *cmd    = get_cmd(golan, cmd_idx);
-       struct mbox *mailbox = NULL;
-
-       if (inbox_idx != NO_MBOX) {
-               mailbox                         = GET_INBOX(golan, inbox_idx);
-               mailbox->mblock.token           = cmd->token;
-               mailbox->mblock.ctrl_sig        = ~xor8_buf(mailbox->mblock.rsvd0,
-                                                               CTRL_SIG_SZ);
-       }
-       if (outbox_idx != NO_MBOX) {
-               mailbox                         = GET_OUTBOX(golan, outbox_idx);
-               mailbox->mblock.token           = cmd->token;
-               mailbox->mblock.ctrl_sig        = ~xor8_buf(mailbox->mblock.rsvd0,
-                                                               CTRL_SIG_SZ);
-       }
-       cmd->sig = ~xor8_buf(cmd, sizeof(*cmd));
-}
-
-/**
-  * Get Golan FW
-  */
-static int fw_ver_and_cmdif ( struct golan *golan ) {
-       DBGC (golan ,"\n[%x:%x]rev maj.min.submin = %x.%x.%x cmdif = %x\n",
-               golan->iseg->fw_rev,
-               golan->iseg->cmdif_rev_fw_sub,
-               fw_rev_maj ( golan ), fw_rev_min ( golan ),
-               fw_rev_sub ( golan ), cmdif_rev ( golan));
-
-       if (cmdif_rev ( golan) != PXE_CMDIF_REF) {
-               DBGC (golan ,"CMDIF %d not supported current is %d\n",
-                       cmdif_rev ( golan ), PXE_CMDIF_REF);
-               return 1;
-       }
-       return 0;
-}
-
-static inline void show_out_status(uint32_t *out)
-{
-       DBG("%x\n", be32_to_cpu(out[0]));
-       DBG("%x\n", be32_to_cpu(out[1]));
-       DBG("%x\n", be32_to_cpu(out[2]));
-       DBG("%x\n", be32_to_cpu(out[3]));
-}
-/**
-  * Check if CMD has finished.
-  */
-static inline uint32_t is_command_finished( struct golan *golan, int idx)
-{
-       wmb();
-       return !(get_cmd( golan , idx )->status_own & CMD_OWNER_HW);
-}
-
-/**
- * Wait for Golan command completion
- *
- * @v golan            Golan device
- * @ret rc             Return status code
- */
-static inline int golan_cmd_wait(struct golan *golan, int idx, const char *command)
-{
-       unsigned int wait;
-       int     rc = -EBUSY;
-
-       for ( wait = GOLAN_HCR_MAX_WAIT_MS ; wait ; --wait ) {
-               if (is_command_finished(golan, idx)) {
-                       rc = CMD_STATUS(golan, idx);
-                       rmb();
-                       break;
-               } else {
-                       mdelay ( 1 );
-               }
-       }
-       if (rc) {
-               DBGC (golan ,"[%s]RC is %s[%x]\n", command, cmd_status_str(rc), rc);
-       }
-
-       golan->cmd_bm &= ~(1 << idx);
-       return rc;
-}
-
-/**
-  * Notify the HW that commands are ready
-  */
-static inline void send_command(struct golan *golan)
-{
-       wmb(); //Make sure the command is visible in "memory".
-       writel(cpu_to_be32(golan->cmd_bm) , &golan->iseg->cmd_dbell);
-}
-
-static inline int send_command_and_wait(struct golan *golan, uint32_t cmd_idx,
-                                       uint32_t inbox_idx, uint32_t outbox_idx, const char *command)
-{
-       golan_calc_sig(golan, cmd_idx, inbox_idx, outbox_idx);
-       send_command(golan);
-       return golan_cmd_wait(golan, cmd_idx, command);
-}
-
-/**
-  * Prepare a FW command,
-  * In - comamnd idx (Must be valid)
-  * writes the command parameters.
-  */
-static inline struct golan_cmd_layout *write_cmd(struct golan *golan, int idx,
-                                                       uint16_t opcode, uint16_t opmod,
-                                                       uint16_t inbox_idx,
-                                                       uint16_t outbox_idx, uint16_t inlen,
-                                                       uint16_t outlen)
-{
-       struct golan_cmd_layout *cmd    = get_cmd(golan , idx);
-       struct golan_inbox_hdr *hdr     = (struct golan_inbox_hdr *)cmd->in;
-       static uint8_t token;
-
-       memset(cmd, 0, sizeof(*cmd));
-
-       cmd->type               = GOLAN_PCI_CMD_XPORT;
-       cmd->status_own         = CMD_OWNER_HW;
-       cmd->outlen             = cpu_to_be32(outlen);
-       cmd->inlen              = cpu_to_be32(inlen);
-       hdr->opcode             = cpu_to_be16(opcode);
-       hdr->opmod              = cpu_to_be16(opmod);
-
-       if (inbox_idx != NO_MBOX) {
-               memset(GET_INBOX(golan, inbox_idx), 0, MAILBOX_SIZE);
-               cmd->in_ptr     = VIRT_2_BE64_BUS(GET_INBOX(golan, inbox_idx));
-               cmd->token      = ++token;
-       }
-       if (outbox_idx != NO_MBOX) {
-               memset(GET_OUTBOX(golan, outbox_idx), 0, MAILBOX_SIZE);
-               cmd->out_ptr = VIRT_2_BE64_BUS(GET_OUTBOX(golan, outbox_idx));
-       }
-
-       golan->cmd_bm |= 1 << idx;
-
-       assert ( cmd != NULL );
-       return cmd;
-}
-
-static inline int golan_core_enable_hca(struct golan *golan)
-{
-       struct golan_cmd_layout *cmd;
-       int rc = 0;
-
-       DBGC(golan, "%s\n", __FUNCTION__);
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_ENABLE_HCA, 0x0,
-                       NO_MBOX, NO_MBOX,
-                       sizeof(struct golan_enable_hca_mbox_in),
-                       sizeof(struct golan_enable_hca_mbox_out));
-
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_PRINT_RC_AND_CMD_STATUS;
-       return rc;
-}
-
-static inline void golan_disable_hca(struct golan *golan)
-{
-       struct golan_cmd_layout *cmd;
-       int rc;
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_DISABLE_HCA, 0x0,
-                                       NO_MBOX, NO_MBOX,
-                                   sizeof(struct golan_disable_hca_mbox_in),
-                                   sizeof(struct golan_disable_hca_mbox_out));
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_PRINT_RC_AND_CMD_STATUS;
-}
-
-static inline int golan_set_hca_cap(struct golan *golan)
-{
-       struct golan_cmd_layout *cmd;
-       int rc;
-
-       DBGC(golan, "%s\n", __FUNCTION__);
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_SET_HCA_CAP, 0x0,
-                       GEN_MBOX, NO_MBOX,
-                       sizeof(struct golan_cmd_set_hca_cap_mbox_in),
-                       sizeof(struct golan_cmd_set_hca_cap_mbox_out));
-
-       golan->caps.flags &= ~GOLAN_DEV_CAP_FLAG_CMDIF_CSUM;
-       DBGC( golan , "%s caps.uar_sz = %d\n", __FUNCTION__, golan->caps.uar_sz);
-       DBGC( golan , "%s caps.log_pg_sz = %d\n", __FUNCTION__, golan->caps.log_pg_sz);
-       DBGC( golan , "%s caps.log_uar_sz = %d\n", __FUNCTION__, be32_to_cpu(golan->caps.uar_page_sz));
-       golan->caps.uar_page_sz = 0;
-
-
-       memcpy(((struct golan_hca_cap *)GET_INBOX(golan, GEN_MBOX)),
-                  &(golan->caps),
-                  sizeof(struct golan_hca_cap));
-
-       //if command failed we should reset the caps in golan->caps
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, GEN_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_PRINT_RC_AND_CMD_STATUS;
-       return rc;
-}
-
-static inline int golan_qry_hca_cap(struct golan *golan)
-{
-       struct golan_cmd_layout *cmd;
-       int rc = 0;
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_QUERY_HCA_CAP, 0x1,
-                                       NO_MBOX, GEN_MBOX,
-                                       sizeof(struct golan_cmd_query_hca_cap_mbox_in),
-                                       sizeof(struct golan_cmd_query_hca_cap_mbox_out));
-
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, GEN_MBOX, __FUNCTION__);
-       GOLAN_CHECK_RC_AND_CMD_STATUS( err_query_hca_cap );
-
-       memcpy(&(golan->caps),
-                  ((struct golan_hca_cap *)GET_OUTBOX(golan, GEN_MBOX)),
-                  sizeof(struct golan_hca_cap));
-err_query_hca_cap:
-       return rc;
-}
-
-static inline int golan_take_pages ( struct golan *golan, uint32_t pages, __be16 func_id ) {
-       uint32_t out_num_entries = 0;
-       int size_ibox =  sizeof(struct golan_manage_pages_inbox);
-       int size_obox = sizeof(struct golan_manage_pages_outbox);
-       int rc = 0;
-
-       DBGC(golan, "%s\n", __FUNCTION__);
-
-       while ( pages > 0 ) {
-               uint32_t pas_num = min(pages, MAX_PASE_MBOX);
-               unsigned i;
-               struct golan_cmd_layout *cmd;
-               struct golan_manage_pages_inbox *in;
-               struct golan_manage_pages_outbox_data *out;
-
-               size_ibox += (pas_num * GOLAN_PAS_SIZE);
-               size_obox += (pas_num * GOLAN_PAS_SIZE);
-
-               cmd = write_cmd(golan, MEM_CMD_IDX, GOLAN_CMD_OP_MANAGE_PAGES, GOLAN_PAGES_TAKE,
-                               MEM_MBOX, MEM_MBOX,
-                               size_ibox,
-                               size_obox);
-
-               in = (struct golan_manage_pages_inbox *)cmd->in; /* Warning (WE CANT USE THE LAST 2 FIELDS) */
-
-               in->func_id     = func_id; /* Already BE */
-               in->num_entries = cpu_to_be32(pas_num);
-
-               if ( ( rc = send_command_and_wait(golan, MEM_CMD_IDX, MEM_MBOX, MEM_MBOX, __FUNCTION__) ) == 0 ) {
-                       out = (struct golan_manage_pages_outbox_data *)GET_OUTBOX(golan, MEM_MBOX);
-                       out_num_entries = be32_to_cpu(((struct golan_manage_pages_outbox *)(cmd->out))->num_entries);
-                       for (i = 0; i < out_num_entries; ++i) {
-                               ufree(BE64_BUS_2_USR(out->pas[i]));
-                       }
-               } else {
-                       if ( rc == -EBUSY ) {
-                               DBGC (golan ,"HCA is busy (rc = -EBUSY)\n" );
-                       } else {
-                               DBGC (golan ,"%s: rc =0x%x[%s]<%x> syn 0x%x[0x%x] for %d pages\n",
-                                               __FUNCTION__, rc, cmd_status_str(rc),
-                                               CMD_SYND(golan, MEM_CMD_IDX),
-                                               get_cmd( golan , MEM_CMD_IDX )->status_own,
-                                               be32_to_cpu(CMD_SYND(golan, MEM_CMD_IDX)), pas_num);
-                       }
-                       return rc;
-               }
-
-               pages -= out_num_entries;
-       }
-       DBGC( golan , "%s Pages handled\n", __FUNCTION__);
-       return 0;
-}
-
-static inline int golan_provide_pages ( struct golan *golan , uint32_t pages, __be16 func_id ) {
-       struct mbox *mailbox;
-       int size_ibox =  sizeof(struct golan_manage_pages_inbox);
-       int size_obox = sizeof(struct golan_manage_pages_outbox);
-       int rc = 0;
-
-       DBGC(golan, "%s\n", __FUNCTION__);
-
-       while ( pages > 0 ) {
-               uint32_t pas_num = min(pages, MAX_PASE_MBOX);
-               unsigned i, j;
-               struct golan_cmd_layout *cmd;
-               struct golan_manage_pages_inbox *in;
-               userptr_t addr = 0;
-
-               mailbox = GET_INBOX(golan, MEM_MBOX);
-               size_ibox += (pas_num * GOLAN_PAS_SIZE);
-               size_obox += (pas_num * GOLAN_PAS_SIZE);
-
-               cmd = write_cmd(golan, MEM_CMD_IDX, GOLAN_CMD_OP_MANAGE_PAGES, GOLAN_PAGES_GIVE,
-                               MEM_MBOX, MEM_MBOX,
-                               size_ibox,
-                               size_obox);
-
-               in = (struct golan_manage_pages_inbox *)cmd->in; /* Warning (WE CANT USE THE LAST 2 FIELDS) */
-
-               in->func_id     = func_id; /* Already BE */
-               in->num_entries = cpu_to_be32(pas_num);
-
-               for ( i = 0 , j = MANAGE_PAGES_PSA_OFFSET; i < pas_num; ++i ,++j ) {
-                       if (!(addr = umalloc(GOLAN_PAGE_SIZE))) {
-                               rc = -ENOMEM;
-                               DBGC (golan ,"Couldnt allocated page \n");
-                               goto malloc_dma_failed;
-                       }
-                       if (GOLAN_PAGE_MASK & user_to_phys(addr, 0)) {
-                               DBGC (golan ,"Addr not Page alligned [%lx %lx]\n", user_to_phys(addr, 0), addr);
-                       }
-                       mailbox->mblock.data[j] = USR_2_BE64_BUS(addr);
-               }
-
-               if ( ( rc = send_command_and_wait(golan, MEM_CMD_IDX, MEM_MBOX, MEM_MBOX, __FUNCTION__) ) == 0 ) {
-                       pages -= pas_num;
-                       golan->total_dma_pages += pas_num;
-               } else {
-                       if ( rc == -EBUSY ) {
-                               DBGC (golan ,"HCA is busy (rc = -EBUSY)\n" );
-                       } else {
-                               DBGC (golan ,"%s: rc =0x%x[%s]<%x> syn 0x%x[0x%x] for %d pages\n",
-                                               __FUNCTION__, rc, cmd_status_str(rc),
-                                               CMD_SYND(golan, MEM_CMD_IDX),
-                                               get_cmd( golan , MEM_CMD_IDX )->status_own,
-                                               be32_to_cpu(CMD_SYND(golan, MEM_CMD_IDX)), pas_num);
-                       }
-                       ufree ( addr );
-                       goto err_send_command;
-               }
-       }
-       DBGC( golan , "%s Pages handled\n", __FUNCTION__);
-       return 0;
-
-err_send_command:
-malloc_dma_failed:
-       /* Go over In box and free pages */
-       /* Send Error to FW */
-       /* What is next - Disable HCA? */
-       DBGC (golan ,"%s Failed (rc = 0x%x)\n", __FUNCTION__, rc);
-       return rc;
-}
-
-static inline int golan_handle_pages(struct golan *golan,
-                                       enum golan_qry_pages_mode qry,
-                                       enum golan_manage_pages_mode mode)
-{
-       struct golan_cmd_layout *cmd;
-
-       int rc = 0;
-       int32_t pages;
-       uint16_t total_pages;
-       __be16  func_id;
-
-       DBGC(golan, "%s\n", __FUNCTION__);
-
-       cmd = write_cmd(golan, MEM_CMD_IDX, GOLAN_CMD_OP_QUERY_PAGES, qry,
-                       NO_MBOX, NO_MBOX,
-                       sizeof(struct golan_query_pages_inbox),
-                       sizeof(struct golan_query_pages_outbox));
-
-       rc = send_command_and_wait(golan, MEM_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_CHECK_RC_AND_CMD_STATUS( err_handle_pages_query );
-
-       pages = be32_to_cpu(QRY_PAGES_OUT(golan, MEM_CMD_IDX)->num_pages);
-
-       DBGC( golan , "%s pages needed: %d\n", __FUNCTION__, pages);
-
-       func_id = QRY_PAGES_OUT(golan, MEM_CMD_IDX)->func_id;
-
-       total_pages = (( pages >= 0 ) ? pages : ( pages * ( -1 ) ));
-
-       if ( mode == GOLAN_PAGES_GIVE ) {
-               rc = golan_provide_pages(golan, total_pages, func_id);
-       } else {
-               rc = golan_take_pages(golan, golan->total_dma_pages, func_id);
-               golan->total_dma_pages = 0;
-       }
-
-       if ( rc ) {
-               DBGC (golan , "Failed to %s pages (rc = %d) - DMA pages allocated = %d\n",
-                       ( ( mode == GOLAN_PAGES_GIVE ) ? "give" : "take" ), rc , golan->total_dma_pages );
-               return rc;
-       }
-
-       return 0;
-
-err_handle_pages_query:
-       DBGC (golan ,"%s Qyery pages failed (rc = 0x%x)\n", __FUNCTION__, rc);
-       return rc;
-}
-
-static inline int golan_set_access_reg ( struct golan *golan __attribute__ (( unused )), uint32_t reg __attribute__ (( unused )))
-{
-#if 0
-       write_cmd(golan, _CMD_IDX, GOLAN_CMD_OP_QUERY_PAGES, 0x0,
-                       NO_MBOX, NO_MBOX,
-                       sizeof(struct golan_reg_host_endianess),
-                       sizeof(struct golan_reg_host_endianess));
-        in->arg = cpu_to_be32(arg);
-        in->register_id = cpu_to_be16(reg_num);
-#endif
-       DBGC (golan ," %s Not implemented yet\n", __FUNCTION__);
-       return 0;
-}
-
-static inline void golan_cmd_uninit ( struct golan *golan )
-{
-       free_dma(golan->mboxes.outbox, GOLAN_PAGE_SIZE);
-       free_dma(golan->mboxes.inbox, GOLAN_PAGE_SIZE);
-       free_dma(golan->cmd.addr, GOLAN_PAGE_SIZE);
-}
-
-/**
- * Initialise Golan Command Q parameters
- *     -- Alocate a 4kb page for the Command Q
- *     -- Read the stride and log num commands available
- *     -- Write the address to cmdq_phy_addr in iseg
- * @v golan            Golan device
- */
-static inline int golan_cmd_init ( struct golan *golan )
-{
-       int rc = 0;
-       uint32_t addr_l_sz;
-
-       if (!(golan->cmd.addr = malloc_dma(GOLAN_PAGE_SIZE , GOLAN_PAGE_SIZE))) {
-               rc = -ENOMEM;
-               goto malloc_dma_failed;
-       }
-       if (!(golan->mboxes.inbox = malloc_dma(GOLAN_PAGE_SIZE , GOLAN_PAGE_SIZE))) {
-               rc = -ENOMEM;
-               goto malloc_dma_inbox_failed;
-       }
-       if (!(golan->mboxes.outbox = malloc_dma(GOLAN_PAGE_SIZE , GOLAN_PAGE_SIZE))) {
-               rc = -ENOMEM;
-               goto malloc_dma_outbox_failed;
-       }
-       addr_l_sz       = be32_to_cpu(readl(&golan->iseg->cmdq_addr_l_sz));
-
-       golan->cmd.log_stride   = addr_l_sz & 0xf;
-       golan->cmd.size         = 1 << (( addr_l_sz >> 4 ) & 0xf);
-
-       addr_l_sz = virt_to_bus(golan->cmd.addr);
-       writel(0 /* cpu_to_be32(golan->cmd.addr) >> 32 */, &golan->iseg->cmdq_addr_h);
-       writel(cpu_to_be32(addr_l_sz), &golan->iseg->cmdq_addr_l_sz);
-       wmb(); //Make sure the addr is visible in "memory".
-
-       addr_l_sz = be32_to_cpu(readl(&golan->iseg->cmdq_addr_l_sz));
-
-       DBGC( golan , "%s Command interface was initialized\n", __FUNCTION__);
-       return 0;
-
-malloc_dma_outbox_failed:
-       free_dma(golan->mboxes.inbox, GOLAN_PAGE_SIZE);
-malloc_dma_inbox_failed:
-       free_dma(golan->cmd.addr, GOLAN_PAGE_SIZE);
-malloc_dma_failed:
-       DBGC (golan ,"%s Failed to initialize command interface (rc = 0x%x)\n",
-                  __FUNCTION__, rc);
-       return rc;
-}
-
-static inline int golan_hca_init(struct golan *golan)
-{
-       struct golan_cmd_layout *cmd;
-       int rc = 0;
-
-       DBGC(golan, "%s\n", __FUNCTION__);
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_INIT_HCA, 0x0,
-                       NO_MBOX, NO_MBOX,
-                       sizeof(struct golan_cmd_init_hca_mbox_in),
-                       sizeof(struct golan_cmd_init_hca_mbox_out));
-
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_PRINT_RC_AND_CMD_STATUS;
-       return rc;
-}
-
-static inline void golan_teardown_hca(struct golan *golan, enum golan_teardown op_mod)
-{
-       struct golan_cmd_layout *cmd;
-       int rc;
-
-       DBGC (golan, "%s in\n", __FUNCTION__);
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_TEARDOWN_HCA, op_mod,
-                       NO_MBOX, NO_MBOX,
-                       sizeof(struct golan_cmd_teardown_hca_mbox_in),
-                       sizeof(struct golan_cmd_teardown_hca_mbox_out));
-
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_PRINT_RC_AND_CMD_STATUS;
-
-       DBGC (golan, "%s HCA teardown compleated\n", __FUNCTION__);
-}
-
-static inline int golan_alloc_uar(struct golan *golan)
-{
-       struct golan_uar *uar = &golan->uar;
-       struct golan_cmd_layout *cmd;
-       struct golan_alloc_uar_mbox_out *out;
-       int rc;
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_ALLOC_UAR, 0x0,
-                       NO_MBOX, NO_MBOX,
-                       sizeof(struct golan_alloc_uar_mbox_in),
-                       sizeof(struct golan_alloc_uar_mbox_out));
-
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_CHECK_RC_AND_CMD_STATUS( err_alloc_uar_cmd );
-       out = (struct golan_alloc_uar_mbox_out *) ( cmd->out );
-
-       uar->index      = be32_to_cpu(out->uarn) & 0xffffff;
-
-       uar->phys = (pci_bar_start(golan->pci, GOLAN_HCA_BAR) + (uar->index << GOLAN_PAGE_SHIFT));
-       uar->virt = (void *)(ioremap(uar->phys, GOLAN_PAGE_SIZE));
-
-       DBGC( golan , "%s: UAR allocated with index 0x%x\n", __FUNCTION__, uar->index);
-       return 0;
-
-err_alloc_uar_cmd:
-       DBGC (golan ,"%s [%d] out\n", __FUNCTION__, rc);
-       return rc;
-}
-
-static void golan_dealloc_uar(struct golan *golan)
-{
-       struct golan_cmd_layout *cmd;
-       uint32_t uar_index = golan->uar.index;
-       int rc;
-
-       DBGC (golan, "%s in\n", __FUNCTION__);
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_DEALLOC_UAR, 0x0,
-                                       NO_MBOX, NO_MBOX,
-                                       sizeof(struct golan_free_uar_mbox_in),
-                                       sizeof(struct golan_free_uar_mbox_out));
-
-       ((struct golan_free_uar_mbox_in *)(cmd->in))->uarn = cpu_to_be32(uar_index);
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_PRINT_RC_AND_CMD_STATUS;
-       golan->uar.index = 0;
-
-       DBGC (golan, "%s UAR (0x%x) was destroyed\n", __FUNCTION__, uar_index);
-}
-
-static void golan_eq_update_ci(struct golan_event_queue *eq, int arm)
-{
-       __be32 *addr = eq->doorbell + (arm ? 0 : 2);
-       u32 val = (eq->cons_index & 0xffffff) | (eq->eqn << 24);
-       writel(cpu_to_be32(val) , addr);
-       /* We still want ordering, just not swabbing, so add a barrier */
-       wmb();
-}
-
-static int golan_create_eq(struct golan *golan)
-{
-       struct golan_event_queue *eq = &golan->eq;
-       struct golan_create_eq_mbox_in_data *in;
-       struct golan_cmd_layout *cmd;
-       struct golan_create_eq_mbox_out *out;
-       int rc, i;
-       userptr_t addr;
-
-       eq->cons_index  = 0;
-       eq->size        = GOLAN_NUM_EQES * sizeof(eq->eqes[0]);
-       addr            = golan_get_page ( &golan->pages );
-       if (!addr) {
-               rc = -ENOMEM;
-               goto err_create_eq_eqe_alloc;
-       }
-       eq->eqes                = (struct golan_eqe *)user_to_virt(addr, 0);
-
-       /* Set EQEs ownership bit to HW ownership */
-       for (i = 0; i < GOLAN_NUM_EQES; ++i) {
-               eq->eqes[i].owner = GOLAN_EQE_HW_OWNERSHIP;
-       }
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_CREATE_EQ, 0x0,
-                       GEN_MBOX, NO_MBOX,
-                       sizeof(struct golan_create_eq_mbox_in) + GOLAN_PAS_SIZE,
-                       sizeof(struct golan_create_eq_mbox_out));
-
-       in = (struct golan_create_eq_mbox_in_data *)GET_INBOX(golan, GEN_MBOX);
-
-       /* Fill the physical address of the page */
-       in->pas[0]              = USR_2_BE64_BUS(addr);
-       in->ctx.log_sz_usr_page = cpu_to_be32((ilog2(GOLAN_NUM_EQES)) << 24 | golan->uar.index);
-       DBGC( golan , "UAR idx %x (BE %x)\n", golan->uar.index, in->ctx.log_sz_usr_page);
-       in->events_mask         = cpu_to_be64(1 << GOLAN_EVENT_TYPE_PORT_CHANGE);
-
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, GEN_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_CHECK_RC_AND_CMD_STATUS( err_create_eq_cmd );
-       out = (struct golan_create_eq_mbox_out *)cmd->out;
-
-       eq->eqn         = out->eq_number;
-       eq->doorbell    = ((void *)golan->uar.virt) + GOLAN_EQ_DOORBELL_OFFSET;
-
-       /* EQs are created in ARMED state */
-       golan_eq_update_ci(eq, GOLAN_EQ_UNARMED);
-
-       DBGC( golan , "%s: Event queue created (EQN = 0x%x)\n", __FUNCTION__, eq->eqn);
-       return 0;
-
-err_create_eq_cmd:
-       ufree(virt_to_user(golan->eq.eqes));
-err_create_eq_eqe_alloc:
-       DBGC (golan ,"%s [%d] out\n", __FUNCTION__, rc);
-       return rc;
-}
-
-static void golan_destory_eq(struct golan *golan)
-{
-       struct golan_cmd_layout *cmd;
-       struct golan_destroy_eq_mbox_in *in;
-       uint8_t eqn = golan->eq.eqn;
-       int rc;
-
-       DBGC (golan, "%s in\n", __FUNCTION__);
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_DESTROY_EQ, 0x0,
-                                       NO_MBOX, NO_MBOX,
-                                       sizeof(struct golan_destroy_eq_mbox_in),
-                                       sizeof(struct golan_destroy_eq_mbox_out));
-
-       in = GOLAN_MBOX_IN ( cmd, in );
-       in->eqn = eqn;
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_PRINT_RC_AND_CMD_STATUS;
-
-       ufree(virt_to_user(golan->eq.eqes));
-       golan->eq.eqn = 0;
-
-       DBGC( golan, "%s Event queue (0x%x) was destroyed\n", __FUNCTION__, eqn);
-}
-
-static int golan_alloc_pd(struct golan *golan)
-{
-       struct golan_cmd_layout *cmd;
-       struct golan_alloc_pd_mbox_out *out;
-       int rc;
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_ALLOC_PD, 0x0,
-                       NO_MBOX, NO_MBOX,
-                       sizeof(struct golan_alloc_pd_mbox_in),
-                       sizeof(struct golan_alloc_pd_mbox_out));
-
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_CHECK_RC_AND_CMD_STATUS( err_alloc_pd_cmd );
-       out = (struct golan_alloc_pd_mbox_out *) ( cmd->out );
-
-       golan->pdn = (be32_to_cpu(out->pdn) & 0xffffff);
-       DBGC( golan , "%s: Protection domain created (PDN = 0x%x)\n", __FUNCTION__,
-               golan->pdn);
-       return 0;
-
-err_alloc_pd_cmd:
-       DBGC (golan ,"%s [%d] out\n", __FUNCTION__, rc);
-       return rc;
-}
-
-static void golan_dealloc_pd(struct golan *golan)
-{
-       struct golan_cmd_layout *cmd;
-       uint32_t pdn = golan->pdn;
-       int rc;
-
-       DBGC (golan,"%s in\n", __FUNCTION__);
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_DEALLOC_PD, 0x0,
-                                       NO_MBOX, NO_MBOX,
-                                       sizeof(struct golan_alloc_pd_mbox_in),
-                                       sizeof(struct golan_alloc_pd_mbox_out));
-
-       ((struct golan_dealloc_pd_mbox_in *)(cmd->in))->pdn = cpu_to_be32(pdn);
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_PRINT_RC_AND_CMD_STATUS;
-       golan->pdn = 0;
-
-       DBGC (golan ,"%s Protection domain (0x%x) was destroyed\n", __FUNCTION__, pdn);
-}
-
-static int golan_create_mkey(struct golan *golan)
-{
-       struct golan_create_mkey_mbox_in_data *in;
-       struct golan_cmd_layout *cmd;
-       struct golan_create_mkey_mbox_out *out;
-       int rc;
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_CREATE_MKEY, 0x0,
-                                       GEN_MBOX, NO_MBOX,
-                                       sizeof(struct golan_create_mkey_mbox_in),
-                                       sizeof(struct golan_create_mkey_mbox_out));
-
-       in = (struct golan_create_mkey_mbox_in_data *)GET_INBOX(golan, GEN_MBOX);
-
-       in->seg.flags                   = GOLAN_IB_ACCESS_LOCAL_WRITE | GOLAN_IB_ACCESS_LOCAL_READ;
-       in->seg.flags_pd                = cpu_to_be32(golan->pdn | GOLAN_MKEY_LEN64);
-       in->seg.qpn_mkey7_0             = cpu_to_be32(0xffffff << GOLAN_CREATE_MKEY_SEG_QPN_BIT);
-
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, GEN_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_CHECK_RC_AND_CMD_STATUS( err_create_mkey_cmd );
-       out = (struct golan_create_mkey_mbox_out *) ( cmd->out );
-
-       golan->mkey = ((be32_to_cpu(out->mkey) & 0xffffff) << 8);
-       DBGC( golan , "%s: Got DMA Key for local access read/write (MKEY = 0x%x)\n",
-                  __FUNCTION__, golan->mkey);
-       return 0;
-err_create_mkey_cmd:
-       DBGC (golan ,"%s [%d] out\n", __FUNCTION__, rc);
-       return rc;
-}
-
-static void golan_destroy_mkey(struct golan *golan)
-{
-       struct golan_cmd_layout *cmd;
-       u32 mkey = golan->mkey;
-       int rc;
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_DESTROY_MKEY, 0x0,
-                                       NO_MBOX, NO_MBOX,
-                                       sizeof(struct golan_destroy_mkey_mbox_in),
-                                       sizeof(struct golan_destroy_mkey_mbox_out));
-       ((struct golan_destroy_mkey_mbox_in *)(cmd->in))->mkey = cpu_to_be32(mkey >> 8);
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_PRINT_RC_AND_CMD_STATUS;
-       golan->mkey = 0;
-
-       DBGC( golan , "%s DMA Key (0x%x) for local access write was destroyed\n"
-                  , __FUNCTION__, mkey);
-}
-
-
-/**
- * Initialise Golan PCI parameters
- *
- * @v golan            Golan device
- */
-static inline void golan_pci_init(struct golan *golan)
-{
-       struct pci_device *pci = golan->pci;
-
-       /* Fix up PCI device */
-       adjust_pci_device ( pci );
-
-       /* Get HCA BAR */
-       golan->iseg     = ioremap ( pci_bar_start ( pci, GOLAN_HCA_BAR),
-                                       GOLAN_PCI_CONFIG_BAR_SIZE );
-}
-
-static inline struct golan *golan_alloc()
-{
-       void *golan = zalloc(sizeof(struct golan));
-       if ( !golan )
-               goto err_zalloc;
-
-       return golan;
-
-err_zalloc:
-       return NULL;
-}
-
-/**
- * Create completion queue
- *
- * @v ibdev            Infiniband device
- * @v cq               Completion queue
- * @ret rc             Return status code
- */
-static int golan_create_cq(struct ib_device *ibdev,
-                               struct ib_completion_queue *cq)
-{
-       struct golan *golan = ib_get_drvdata(ibdev);
-       struct golan_completion_queue *golan_cq;
-       struct golan_cmd_layout *cmd;
-       struct golan_create_cq_mbox_in_data *in;
-       struct golan_create_cq_mbox_out *out;
-       int     rc;
-       unsigned int i;
-       userptr_t addr;
-
-       golan_cq = zalloc(sizeof(*golan_cq));
-       if (!golan_cq) {
-               rc = -ENOMEM;
-               goto err_create_cq;
-       }
-       golan_cq->size                  = sizeof(golan_cq->cqes[0]) * cq->num_cqes;
-       golan_cq->doorbell_record       = malloc_dma(GOLAN_CQ_DB_RECORD_SIZE,
-                                                       GOLAN_CQ_DB_RECORD_SIZE);
-       if (!golan_cq->doorbell_record) {
-               rc = -ENOMEM;
-               goto err_create_cq_db_alloc;
-       }
-
-       addr = golan_get_page ( &golan->pages );
-       if (!addr) {
-               rc = -ENOMEM;
-               goto err_create_cq_cqe_alloc;
-       }
-       golan_cq->cqes = (struct golan_cqe64 *)user_to_virt(addr, 0);
-
-       /* Set CQEs ownership bit to HW ownership */
-       for (i = 0; i < cq->num_cqes; ++i) {
-               golan_cq->cqes[i].op_own = ((GOLAN_CQE_OPCODE_NOT_VALID <<
-                                                                   GOLAN_CQE_OPCODE_BIT) |
-                                                                   GOLAN_CQE_HW_OWNERSHIP);
-       }
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_CREATE_CQ, 0x0,
-                                       GEN_MBOX, NO_MBOX,
-                                   sizeof(struct golan_create_cq_mbox_in) + GOLAN_PAS_SIZE,
-                                   sizeof(struct golan_create_cq_mbox_out));
-
-       in = (struct golan_create_cq_mbox_in_data *)GET_INBOX(golan, GEN_MBOX);
-
-       /* Fill the physical address of the page */
-       in->pas[0]              = USR_2_BE64_BUS(addr);
-       in->ctx.cqe_sz_flags    = GOLAN_CQE_SIZE_64 << 5;
-       in->ctx.log_sz_usr_page = cpu_to_be32(((ilog2(cq->num_cqes)) << 24) | golan->uar.index);
-       in->ctx.c_eqn           = cpu_to_be16(golan->eq.eqn);
-       in->ctx.db_record_addr  = VIRT_2_BE64_BUS(golan_cq->doorbell_record);
-
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, GEN_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_CHECK_RC_AND_CMD_STATUS( err_create_cq_cmd );
-       out = (struct golan_create_cq_mbox_out *) ( cmd->out );
-
-       cq->cqn = (be32_to_cpu(out->cqn) & 0xffffff);
-
-       ib_cq_set_drvdata(cq, golan_cq);
-
-       DBGC( golan , "%s CQ created successfully (CQN = 0x%lx)\n", __FUNCTION__, cq->cqn);
-       return 0;
-
-err_create_cq_cmd:
-       ufree(virt_to_user(golan_cq->cqes));
-err_create_cq_cqe_alloc:
-       free_dma(golan_cq->doorbell_record, GOLAN_CQ_DB_RECORD_SIZE);
-err_create_cq_db_alloc:
-       free ( golan_cq );
-err_create_cq:
-       DBGC (golan ,"%s out rc = 0x%x\n", __FUNCTION__, rc);
-       return rc;
-}
-
-/**
- * Destroy completion queue
- *
- * @v ibdev            Infiniband device
- * @v cq               Completion queue
- */
-static void golan_destroy_cq(struct ib_device *ibdev,
-                               struct ib_completion_queue *cq)
-{
-       struct golan                    *golan          = ib_get_drvdata(ibdev);
-       struct golan_completion_queue   *golan_cq       = ib_cq_get_drvdata(cq);
-       struct golan_cmd_layout         *cmd;
-       uint32_t cqn = cq->cqn;
-       int rc;
-
-       DBGC (golan, "%s in\n", __FUNCTION__);
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_DESTROY_CQ, 0x0,
-                                       NO_MBOX, NO_MBOX,
-                                   sizeof(struct golan_destroy_cq_mbox_in),
-                                   sizeof(struct golan_destroy_cq_mbox_out));
-       ((struct golan_destroy_cq_mbox_in *)(cmd->in))->cqn = cpu_to_be32(cqn);
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_PRINT_RC_AND_CMD_STATUS;
-       cq->cqn = 0;
-
-       ib_cq_set_drvdata(cq, NULL);
-       ufree(virt_to_user(golan_cq->cqes));
-       free_dma(golan_cq->doorbell_record, GOLAN_CQ_DB_RECORD_SIZE);
-       free(golan_cq);
-
-       DBGC (golan, "%s CQ number 0x%x was destroyed\n", __FUNCTION__, cqn);
-}
-
-static void golan_cq_clean(struct ib_completion_queue *cq)
-{
-       ib_poll_cq(cq->ibdev, cq);
-}
-
-static int golan_qp_type_to_st(enum ib_queue_pair_type type)
-{
-       int qpt = type;
-
-       switch (qpt) {
-       case IB_QPT_RC:
-               return GOLAN_QP_ST_RC;
-       case IB_QPT_UD:
-               return GOLAN_QP_ST_UD;
-       case IB_QPT_SMI:
-               return GOLAN_QP_ST_QP0;
-       case IB_QPT_GSI:
-               return GOLAN_QP_ST_QP1;
-       case IB_QPT_ETH:
-       default:
-               return -EINVAL;
-       }
-}
-#if 0
-static int golan_is_special_qp(enum ib_queue_pair_type type)
-{
-       return (type == IB_QPT_GSI || type == IB_QPT_SMI);
-}
-#endif
-static int golan_create_qp_aux(struct ib_device *ibdev,
-                               struct ib_queue_pair *qp,
-                               int *qpn)
-{
-       struct golan *golan = ib_get_drvdata(ibdev);
-       struct golan_queue_pair *golan_qp;
-       struct golan_create_qp_mbox_in_data *in;
-       struct golan_cmd_layout *cmd;
-       struct golan_wqe_data_seg *data;
-       struct golan_create_qp_mbox_out *out;
-       userptr_t addr;
-       uint32_t wqe_size_in_bytes;
-       uint32_t max_qp_size_in_wqes;
-       unsigned int i;
-       int rc;
-
-       golan_qp = zalloc(sizeof(*golan_qp));
-       if (!golan_qp) {
-               rc = -ENOMEM;
-               goto err_create_qp;
-       }
-
-       if ( ( qp->type == IB_QPT_SMI ) || ( qp->type == IB_QPT_GSI ) ||
-                ( qp->type == IB_QPT_UD ) ) {
-               golan_qp->rq.grh_size = ( qp->recv.num_wqes *
-                                       sizeof ( golan_qp->rq.grh[0] ));
-       }
-
-       /* Calculate receive queue size */
-       golan_qp->rq.size = qp->recv.num_wqes * GOLAN_RECV_WQE_SIZE;
-       if (GOLAN_RECV_WQE_SIZE > be16_to_cpu(golan->caps.max_wqe_sz_rq)) {
-               DBGC (golan ,"%s receive wqe size [%zd] > max wqe size [%d]\n", __FUNCTION__,
-                               GOLAN_RECV_WQE_SIZE, be16_to_cpu(golan->caps.max_wqe_sz_rq));
-               rc = -EINVAL;
-               goto err_create_qp_rq_size;
-       }
-
-       wqe_size_in_bytes = sizeof(golan_qp->sq.wqes[0]);
-       /* Calculate send queue size */
-       if (wqe_size_in_bytes > be16_to_cpu(golan->caps.max_wqe_sz_sq)) {
-               DBGC (golan ,"%s send WQE size [%d] > max WQE size [%d]\n", __FUNCTION__,
-                               wqe_size_in_bytes,
-                               be16_to_cpu(golan->caps.max_wqe_sz_sq));
-               rc = -EINVAL;
-               goto err_create_qp_sq_wqe_size;
-       }
-       golan_qp->sq.size = (qp->send.num_wqes * wqe_size_in_bytes);
-       max_qp_size_in_wqes = (1 << ((uint32_t)(golan->caps.log_max_qp_sz)));
-       if (qp->send.num_wqes > max_qp_size_in_wqes) {
-               DBGC (golan ,"%s send wq size [%d] > max wq size [%d]\n", __FUNCTION__,
-                               golan_qp->sq.size, max_qp_size_in_wqes);
-               rc = -EINVAL;
-               goto err_create_qp_sq_size;
-       }
-
-       golan_qp->size = golan_qp->sq.size + golan_qp->rq.size;
-
-       /* allocate dma memory for WQEs (1 page is enough) - should change it */
-       addr = golan_get_page ( &golan->pages );
-       if (!addr) {
-               rc = -ENOMEM;
-               goto err_create_qp_wqe_alloc;
-       }
-       golan_qp->wqes          = user_to_virt(addr, 0);
-       golan_qp->rq.wqes       = golan_qp->wqes;
-       golan_qp->sq.wqes       = golan_qp->wqes + golan_qp->rq.size;//(union golan_send_wqe *)&
-                       //(((struct golan_recv_wqe_ud *)(golan_qp->wqes))[qp->recv.num_wqes]);
-
-       if ( golan_qp->rq.grh_size ) {
-               golan_qp->rq.grh = ( golan_qp->wqes +
-                               golan_qp->sq.size +
-                               golan_qp->rq.size );
-       }
-
-       /* Invalidate all WQEs */
-       data = &golan_qp->rq.wqes[0].data[0];
-       for ( i = 0 ; i < ( golan_qp->rq.size / sizeof ( *data ) ); i++ ){
-               data->lkey = cpu_to_be32 ( GOLAN_INVALID_LKEY );
-               data++;
-       }
-
-       golan_qp->doorbell_record = malloc_dma(sizeof(struct golan_qp_db),
-                                               sizeof(struct golan_qp_db));
-       if (!golan_qp->doorbell_record) {
-               rc = -ENOMEM;
-               goto err_create_qp_db_alloc;
-       }
-       memset(golan_qp->doorbell_record, 0, sizeof(struct golan_qp_db));
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_CREATE_QP, 0x0,
-                       GEN_MBOX, NO_MBOX,
-                       sizeof(struct golan_create_qp_mbox_in) + GOLAN_PAS_SIZE,
-                       sizeof(struct golan_create_qp_mbox_out));
-
-       in = (struct golan_create_qp_mbox_in_data *)GET_INBOX(golan, GEN_MBOX);
-
-       /* Fill the physical address of the page */
-       in->pas[0]                      = USR_2_BE64_BUS(addr);
-       in->ctx.qp_counter_set_usr_page = cpu_to_be32(golan->uar.index);
-
-       in->ctx.flags_pd        = cpu_to_be32(golan->pdn);
-       in->ctx.flags           = cpu_to_be32((golan_qp_type_to_st(qp->type)
-                                               << GOLAN_QP_CTX_ST_BIT) |
-                                               (GOLAN_QP_PM_MIGRATED <<
-                                               GOLAN_QP_CTX_PM_STATE_BIT));
-//     cgs     set to 0, initialy.
-//     atomic mode
-       in->ctx.rq_size_stride  = ((ilog2(qp->recv.num_wqes) <<
-                                                               GOLAN_QP_CTX_RQ_SIZE_BIT) |
-                                                               (sizeof(golan_qp->rq.wqes[0]) / GOLAN_RECV_WQE_SIZE));
-       in->ctx.sq_crq_size             = cpu_to_be16(ilog2(golan_qp->sq.size / GOLAN_SEND_WQE_BB_SIZE)
-                                                                                 << GOLAN_QP_CTX_SQ_SIZE_BIT);
-       in->ctx.cqn_send                = cpu_to_be32(qp->send.cq->cqn);
-       in->ctx.cqn_recv                = cpu_to_be32(qp->recv.cq->cqn);
-       in->ctx.db_rec_addr     = VIRT_2_BE64_BUS(golan_qp->doorbell_record);
-
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, GEN_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_CHECK_RC_AND_CMD_STATUS( err_create_qp_cmd );
-       out = (struct golan_create_qp_mbox_out *)cmd->out;
-
-       *qpn = (be32_to_cpu(out->qpn) & 0xffffff);
-       /*
-       * Hardware wants QPN written in big-endian order (after
-       * shifting) for send doorbell.  Precompute this value to save
-       * a little bit when posting sends.
-       */
-       golan_qp->doorbell_qpn  = cpu_to_be32(*qpn << 8);
-       golan_qp->state                 = GOLAN_IB_QPS_RESET;
-
-       ib_qp_set_drvdata(qp, golan_qp);
-
-       return 0;
-
-err_create_qp_cmd:
-       free_dma(golan_qp->doorbell_record, sizeof(struct golan_qp_db));
-err_create_qp_db_alloc:
-       ufree((userptr_t)golan_qp->wqes);
-err_create_qp_wqe_alloc:
-err_create_qp_sq_size:
-err_create_qp_sq_wqe_size:
-err_create_qp_rq_size:
-       free ( golan_qp );
-err_create_qp:
-       return rc;
-}
-
-/**
- * Create queue pair
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- * @ret rc             Return status code
- */
-static int golan_create_qp(struct ib_device *ibdev,
-                               struct ib_queue_pair *qp)
-{
-       int rc, qpn = -1;
-
-       switch (qp->type) {
-       case IB_QPT_UD:
-       case IB_QPT_SMI:
-       case IB_QPT_GSI:
-               rc = golan_create_qp_aux(ibdev, qp, &qpn);
-               if (rc) {
-                       DBG ( "%s Failed to create QP (rc = 0x%x)\n", __FUNCTION__, rc);
-                       return rc;
-               }
-               qp->qpn = qpn;
-
-               break;
-       case IB_QPT_ETH:
-       case IB_QPT_RC:
-       default:
-               DBG ( "%s unsupported QP type (0x%x)\n", __FUNCTION__, qp->type);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int golan_modify_qp_rst_to_init(struct ib_device *ibdev,
-                                       struct ib_queue_pair *qp __unused,
-                                       struct golan_modify_qp_mbox_in_data *in)
-{
-       int rc = 0;
-
-       in->ctx.qkey                    = cpu_to_be32((uint32_t)(qp->qkey));
-
-       in->ctx.pri_path.port           = ibdev->port;
-       in->ctx.flags                   |= cpu_to_be32(GOLAN_QP_PM_MIGRATED << GOLAN_QP_CTX_PM_STATE_BIT);
-       in->ctx.pri_path.pkey_index     = 0; /* default index */
-       /* QK is 0 */
-       /* QP cntr set 0 */
-       return rc;
-}
-
-static int golan_modify_qp_init_to_rtr(struct ib_device *ibdev __unused,
-                                       struct ib_queue_pair *qp __unused,
-                                       struct golan_modify_qp_mbox_in_data *in)
-{
-       int rc = 0;
-
-       in->optparam = 0;
-       return rc;
-}
-
-static int golan_modify_qp_rtr_to_rts(struct ib_device *ibdev __unused,
-                                       struct ib_queue_pair *qp __unused,
-                                       struct golan_modify_qp_mbox_in_data *in __unused)
-{
-       int rc = 0;
-
-       in->optparam = 0;
-       /* In good flow psn in 0 */
-       return rc;
-}
-
-static int golan_modify_qp_to_rst(struct ib_device *ibdev,
-                                       struct ib_queue_pair *qp)
-{
-       struct golan *golan = ib_get_drvdata(ibdev);
-       struct golan_queue_pair *golan_qp = ib_qp_get_drvdata(qp);
-       struct golan_cmd_layout *cmd;
-       int rc;
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_2RST_QP, 0x0,
-                                       NO_MBOX, NO_MBOX,
-                                       sizeof(struct golan_modify_qp_mbox_in),
-                                       sizeof(struct golan_modify_qp_mbox_out));
-       ((struct golan_modify_qp_mbox_in *)(cmd->in))->qpn = cpu_to_be32(qp->qpn);
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_CHECK_RC_AND_CMD_STATUS( err_modify_qp_2rst_cmd );
-
-       golan_qp->state = GOLAN_IB_QPS_RESET;
-       DBGC( golan , "%s QP number 0x%lx was modified to RESET\n",
-               __FUNCTION__, qp->qpn);
-
-       return 0;
-
-err_modify_qp_2rst_cmd:
-       DBGC (golan ,"%s Failed to modify QP number 0x%lx (rc = 0x%x)\n",
-               __FUNCTION__, qp->qpn, rc);
-       return rc;
-}
-
-static int (*golan_modify_qp_methods[])(struct ib_device *ibdev,
-                                       struct ib_queue_pair *qp,
-                                       struct golan_modify_qp_mbox_in_data *in) = {
-
-       [GOLAN_IB_QPS_RESET]    = golan_modify_qp_rst_to_init,
-       [GOLAN_IB_QPS_INIT]     = golan_modify_qp_init_to_rtr,
-       [GOLAN_IB_QPS_RTR]      = golan_modify_qp_rtr_to_rts
-};
-
-static int golan_modify_qp(struct ib_device *ibdev,
-                               struct ib_queue_pair *qp)
-{
-       struct golan *golan = ib_get_drvdata(ibdev);
-       struct golan_queue_pair *golan_qp = ib_qp_get_drvdata(qp);
-       struct golan_modify_qp_mbox_in_data *in;
-       struct golan_cmd_layout *cmd;
-       enum golan_ib_qp_state prev_state;
-       int rc;
-       int modify_cmd[] = {GOLAN_CMD_OP_RST2INIT_QP,
-                               GOLAN_CMD_OP_INIT2RTR_QP,
-                               GOLAN_CMD_OP_RTR2RTS_QP};
-
-       while (golan_qp->state < GOLAN_IB_QPS_RTS) {
-               prev_state = golan_qp->state;
-               cmd = write_cmd(golan, DEF_CMD_IDX, modify_cmd[golan_qp->state], 0x0,
-                                               GEN_MBOX, NO_MBOX,
-                                               sizeof(struct golan_modify_qp_mbox_in),
-                                               sizeof(struct golan_modify_qp_mbox_out));
-
-               in = (struct golan_modify_qp_mbox_in_data *)GET_INBOX(golan, GEN_MBOX);
-               ((struct golan_modify_qp_mbox_in *)(cmd->in))->qpn = cpu_to_be32(qp->qpn);
-               rc = golan_modify_qp_methods[golan_qp->state](ibdev, qp, in);
-               if (rc) {
-                       goto err_modify_qp_fill_inbox;
-               }
-//             in->ctx.qp_counter_set_usr_page = cpu_to_be32(golan->uar.index);
-               rc = send_command_and_wait(golan, DEF_CMD_IDX, GEN_MBOX, NO_MBOX, __FUNCTION__);
-               GOLAN_CHECK_RC_AND_CMD_STATUS( err_modify_qp_cmd );
-
-               ++(golan_qp->state);
-
-               DBGC( golan , "%s QP number 0x%lx was modified from %s to %s\n",
-                       __FUNCTION__, qp->qpn, golan_qp_state_as_string[prev_state],
-                       golan_qp_state_as_string[golan_qp->state]);
-       }
-
-       DBGC( golan , "%s QP number 0x%lx is ready to receive/send packets.\n",
-               __FUNCTION__, qp->qpn);
-       return 0;
-
-err_modify_qp_cmd:
-err_modify_qp_fill_inbox:
-       DBGC (golan ,"%s Failed to modify QP number 0x%lx (rc = 0x%x)\n",
-                  __FUNCTION__, qp->qpn, rc);
-       return rc;
-}
-
-/**
- * Destroy queue pair
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- */
-static void golan_destroy_qp(struct ib_device *ibdev,
-                               struct ib_queue_pair *qp)
-{
-       struct golan            *golan          = ib_get_drvdata(ibdev);
-       struct golan_queue_pair *golan_qp       = ib_qp_get_drvdata(qp);
-       struct golan_cmd_layout                 *cmd;
-       unsigned long            qpn = qp->qpn;
-       int rc;
-
-       DBGC (golan, "%s in\n", __FUNCTION__);
-
-       if (golan_qp->state != GOLAN_IB_QPS_RESET) {
-               if (golan_modify_qp_to_rst(ibdev, qp)) {
-                       DBGC (golan ,"%s Failed to modify QP 0x%lx to RESET\n", __FUNCTION__,
-                                  qp->qpn);
-               }
-       }
-
-       if (qp->recv.cq) {
-               golan_cq_clean(qp->recv.cq);
-       }
-       if (qp->send.cq && (qp->send.cq != qp->recv.cq)) {
-               golan_cq_clean(qp->send.cq);
-       }
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_DESTROY_QP, 0x0,
-                                       NO_MBOX, NO_MBOX,
-                                   sizeof(struct golan_destroy_qp_mbox_in),
-                                   sizeof(struct golan_destroy_qp_mbox_out));
-       ((struct golan_destroy_qp_mbox_in *)(cmd->in))->qpn = cpu_to_be32(qpn);
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_PRINT_RC_AND_CMD_STATUS;
-       qp->qpn = 0;
-
-       ib_qp_set_drvdata(qp, NULL);
-       free_dma(golan_qp->doorbell_record, sizeof(struct golan_qp_db));
-       ufree((userptr_t)golan_qp->wqes);
-       free(golan_qp);
-
-       DBGC( golan ,"%s QP 0x%lx was destroyed\n", __FUNCTION__, qpn);
-}
-
-/**
- * Calculate transmission rate
- *
- * @v av               Address vector
- * @ret golan_rate     Golan rate
- */
-static unsigned int golan_rate(enum ib_rate rate) {
-       return (((rate >= IB_RATE_2_5) && (rate <= IB_RATE_120)) ? (rate + 5) : 0);
-}
-
-/**
- * Post send work queue entry
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- * @v av               Address vector
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int golan_post_send(struct ib_device *ibdev,
-                               struct ib_queue_pair *qp,
-                               struct ib_address_vector *av,
-                               struct io_buffer *iobuf)
-{
-       struct golan                    *golan          = ib_get_drvdata(ibdev);
-       struct golan_queue_pair         *golan_qp       = ib_qp_get_drvdata(qp);
-       struct golan_send_wqe_ud *wqe           = NULL;
-       struct golan_av                 *datagram       = NULL;
-       unsigned long                   wqe_idx_mask;
-       unsigned long                   wqe_idx;
-       struct golan_wqe_data_seg       *data           = NULL;
-       struct golan_wqe_ctrl_seg       *ctrl           = NULL;
-//     static uint8_t                  toggle          = 0;
-
-
-       wqe_idx_mask = (qp->send.num_wqes - 1);
-       wqe_idx = (qp->send.next_idx & wqe_idx_mask);
-       if (qp->send.iobufs[wqe_idx]) {
-               DBGC (golan ,"%s Send queue of QPN 0x%lx is full\n", __FUNCTION__, qp->qpn);
-               return -ENOMEM;
-       }
-
-       qp->send.iobufs[wqe_idx] = iobuf;
-
-       // change to this
-       //wqe_size_in_octa_words = golan_qp->sq.wqe_size_in_wqebb >> 4;
-
-       wqe                     = &golan_qp->sq.wqes[wqe_idx].ud;
-
-       //CHECK HW OWNERSHIP BIT ???
-
-       memset(wqe, 0, sizeof(*wqe));
-
-       ctrl                    = &wqe->ctrl;
-       ctrl->opmod_idx_opcode  = cpu_to_be32(GOLAN_SEND_OPCODE |
-                                                 ((u32)(golan_qp->sq.next_idx) <<
-                                                 GOLAN_WQE_CTRL_WQE_IDX_BIT));
-       ctrl->qpn_ds            = cpu_to_be32(GOLAN_SEND_UD_WQE_SIZE >> 4) |
-                                                         golan_qp->doorbell_qpn;
-       ctrl->fm_ce_se          = 0x8;//10 - 0 - 0
-       data                    = &wqe->data;
-       data->byte_count        = cpu_to_be32(iob_len(iobuf));
-       data->lkey              = cpu_to_be32(golan->mkey);
-       data->addr              = VIRT_2_BE64_BUS(iobuf->data);
-
-       datagram                = &wqe->datagram;
-       datagram->key.qkey.qkey = cpu_to_be32(av->qkey);
-       datagram->dqp_dct       = cpu_to_be32((1 << 31) | av->qpn);
-       datagram->stat_rate_sl  = ((golan_rate(av->rate) << 4) | av->sl);
-       datagram->fl_mlid       = (ibdev->lid & 0x007f); /* take only the 7 low bits of the LID */
-       datagram->rlid          = cpu_to_be16(av->lid);
-       datagram->grh_gid_fl    = cpu_to_be32(av->gid_present << 30);
-       memcpy(datagram->rgid, av->gid.bytes, 16 /* sizeof(datagram->rgid) */);
-
-       /*
-       * Make sure that descriptors are written before
-       * updating doorbell record and ringing the doorbell
-       */
-       ++(qp->send.next_idx);
-       golan_qp->sq.next_idx = (golan_qp->sq.next_idx + GOLAN_WQEBBS_PER_SEND_UD_WQE);
-       golan_qp->doorbell_record->send_db = cpu_to_be16(golan_qp->sq.next_idx);
-       wmb();
-       writeq(*((__be64 *)ctrl), golan->uar.virt + 0x800);// +
-//                     ((toggle++ & 0x1) ? 0x100 : 0x0));
-       return 0;
-}
-
-/**
- * Post receive work queue entry
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int golan_post_recv(struct ib_device *ibdev,
-                               struct ib_queue_pair *qp,
-                               struct io_buffer *iobuf)
-{
-       struct golan            *golan          = ib_get_drvdata(ibdev);
-       struct golan_queue_pair *golan_qp       = ib_qp_get_drvdata(qp);
-       struct ib_work_queue            *wq     = &qp->recv;
-       struct golan_recv_wqe_ud        *wqe;
-       struct ib_global_route_header *grh;
-       struct golan_wqe_data_seg *data;
-       unsigned int wqe_idx_mask;
-
-       /* Allocate work queue entry */
-       wqe_idx_mask = (wq->num_wqes - 1);
-       if (wq->iobufs[wq->next_idx & wqe_idx_mask]) {
-               DBGC (golan ,"%s Receive queue of QPN 0x%lx is full\n", __FUNCTION__, qp->qpn);
-               return -ENOMEM;
-       }
-
-       wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
-       wqe = & golan_qp->rq.wqes[wq->next_idx & wqe_idx_mask];
-
-       memset(wqe, 0, sizeof(*wqe));
-       data = &wqe->data[0];
-       if ( golan_qp->rq.grh ) {
-               grh = &golan_qp->rq.grh[wq->next_idx & wqe_idx_mask];
-               data->byte_count = cpu_to_be32 ( sizeof ( *grh ) );
-               data->lkey = cpu_to_be32 ( golan->mkey );
-               data->addr = VIRT_2_BE64_BUS ( grh );
-               data++;
-       }
-
-       data->byte_count = cpu_to_be32(iob_tailroom(iobuf));
-       data->lkey = cpu_to_be32(golan->mkey);
-       data->addr = VIRT_2_BE64_BUS(iobuf->data);
-
-       ++wq->next_idx;
-
-       /*
-       * Make sure that descriptors are written before
-       * updating doorbell record and ringing the doorbell
-       */
-       wmb();
-       golan_qp->doorbell_record->recv_db = cpu_to_be16(qp->recv.next_idx & 0xffff);
-
-       return 0;
-}
-
-static int golan_query_vport_context ( struct ib_device *ibdev ) {
-       struct golan *golan = ib_get_drvdata ( ibdev );
-       struct golan_cmd_layout *cmd;
-       struct golan_query_hca_vport_context_inbox *in;
-       struct golan_query_hca_vport_context_data *context_data;
-       int rc;
-
-       cmd = write_cmd ( golan, DEF_CMD_IDX, GOLAN_CMD_OP_QUERY_HCA_VPORT_CONTEXT,
-                       0x0, GEN_MBOX, GEN_MBOX,
-                       sizeof(struct golan_query_hca_vport_context_inbox),
-                       sizeof(struct golan_query_hca_vport_context_outbox) );
-
-       in = GOLAN_MBOX_IN ( cmd, in );
-       in->port_num = (u8)ibdev->port;
-
-       rc = send_command_and_wait ( golan, DEF_CMD_IDX, GEN_MBOX, GEN_MBOX, __FUNCTION__ );
-       GOLAN_CHECK_RC_AND_CMD_STATUS( err_query_vport_context_cmd );
-
-       context_data = (struct golan_query_hca_vport_context_data *)( GET_OUTBOX ( golan, GEN_MBOX ) );
-
-       ibdev->node_guid.dwords[0]      = context_data->node_guid[0];
-       ibdev->node_guid.dwords[1]      = context_data->node_guid[1];
-       ibdev->lid                                      = be16_to_cpu( context_data->lid );
-       ibdev->sm_lid                           = be16_to_cpu( context_data->sm_lid );
-       ibdev->sm_sl                            = context_data->sm_sl;
-       ibdev->port_state                       = context_data->port_state;
-
-       return 0;
-err_query_vport_context_cmd:
-       DBGC (golan ,"%s [%d] out\n", __FUNCTION__, rc);
-       return rc;
-}
-
-
-static int golan_query_vport_gid ( struct ib_device *ibdev ) {
-       struct golan *golan = ib_get_drvdata( ibdev );
-       struct golan_cmd_layout *cmd;
-       struct golan_query_hca_vport_gid_inbox *in;
-       union ib_gid *ib_gid;
-       int rc;
-
-       cmd = write_cmd( golan, DEF_CMD_IDX, GOLAN_CMD_OP_QUERY_HCA_VPORT_GID,
-                       0x0, GEN_MBOX, GEN_MBOX,
-                       sizeof(struct golan_query_hca_vport_gid_inbox),
-                       sizeof(struct golan_query_hca_vport_gid_outbox) );
-
-       in = GOLAN_MBOX_IN ( cmd, in );
-       in->port_num = (u8)ibdev->port;
-       in->gid_index = 0;
-       rc = send_command_and_wait ( golan, DEF_CMD_IDX, GEN_MBOX, GEN_MBOX, __FUNCTION__ );
-       GOLAN_CHECK_RC_AND_CMD_STATUS( err_query_vport_gid_cmd );
-
-       ib_gid = (union ib_gid *)( GET_OUTBOX ( golan, GEN_MBOX ) );
-
-       memcpy ( &ibdev->gid, ib_gid, sizeof(ibdev->gid) );
-
-       return 0;
-err_query_vport_gid_cmd:
-               DBGC ( golan, "%s [%d] out\n", __FUNCTION__, rc);
-       return rc;
-}
-
-static int golan_query_vport_pkey ( struct ib_device *ibdev ) {
-       struct golan *golan = ib_get_drvdata ( ibdev );
-       struct golan_cmd_layout *cmd;
-       struct golan_query_hca_vport_pkey_inbox *in;
-       //struct golan_query_hca_vport_pkey_data *pkey_table;
-       int pkey_table_size_in_entries = (1 << (7 + golan->caps.pkey_table_size));
-       int rc;
-
-       cmd = write_cmd ( golan, DEF_CMD_IDX, GOLAN_CMD_OP_QUERY_HCA_VPORT_PKEY,
-                       0x0, GEN_MBOX, GEN_MBOX,
-                       sizeof(struct golan_query_hca_vport_pkey_inbox),
-                       sizeof(struct golan_outbox_hdr) + 8 +
-                       sizeof(struct golan_query_hca_vport_pkey_data) * pkey_table_size_in_entries );
-
-       in = GOLAN_MBOX_IN ( cmd, in );
-       in->port_num = (u8)ibdev->port;
-       in->pkey_index = 0xffff;
-       rc = send_command_and_wait ( golan, DEF_CMD_IDX, GEN_MBOX, GEN_MBOX, __FUNCTION__ );
-       GOLAN_CHECK_RC_AND_CMD_STATUS( err_query_vport_pkey_cmd );
-
-       //pkey_table = (struct golan_query_hca_vport_pkey_data *)( GET_OUTBOX ( golan, GEN_MBOX ) );
-
-       return 0;
-err_query_vport_pkey_cmd:
-       DBGC (golan ,"%s [%d] out\n", __FUNCTION__, rc);
-       return rc;
-}
-
-static int golan_get_ib_info ( struct ib_device *ibdev ) {
-       int rc;
-
-       rc = golan_query_vport_context ( ibdev );
-       if ( rc != 0 ) {
-               DBG ( "golan_get_ib_info: golan_query_vport_context Failed (rc = %d)\n",rc );
-               goto err_query_vport_context;
-       }
-
-       rc = golan_query_vport_gid ( ibdev );
-       if ( rc != 0 ) {
-               DBG ( "golan_get_ib_info: golan_query_vport_gid Failed (rc = %d)\n",rc );
-               goto err_query_vport_gid;
-       }
-
-       rc = golan_query_vport_pkey ( ibdev );
-       if ( rc != 0 ) {
-               DBG ( "golan_get_ib_info: golan_query_vport_pkey Failed (rc = %d)\n",rc );
-               goto err_query_vport_pkey;
-       }
-       return rc;
-err_query_vport_pkey:
-err_query_vport_gid:
-err_query_vport_context:
-       DBG ( "%s [%d] out\n", __FUNCTION__, rc);
-       return rc;
-}
-
-static int golan_complete(struct ib_device *ibdev,
-                               struct ib_completion_queue *cq,
-                               struct golan_cqe64 *cqe64)
-{
-       struct golan *golan     = ib_get_drvdata(ibdev);
-       struct ib_work_queue *wq;
-       struct golan_queue_pair *golan_qp;
-       struct ib_queue_pair *qp;
-       struct io_buffer *iobuf = NULL;
-       struct ib_address_vector recv_dest;
-       struct ib_address_vector recv_source;
-       struct ib_global_route_header *grh;
-       struct golan_err_cqe *err_cqe64;
-       int gid_present, idx;
-       u16 wqe_ctr;
-       uint8_t opcode;
-       static int error_state;
-       uint32_t qpn = be32_to_cpu(cqe64->sop_drop_qpn) & 0xffffff;
-       int is_send = 0;
-       size_t len;
-
-       opcode = cqe64->op_own >> GOLAN_CQE_OPCODE_BIT;
-       DBGC2( golan , "%s completion with opcode 0x%x\n", __FUNCTION__, opcode);
-
-       if (opcode == GOLAN_CQE_REQ || opcode == GOLAN_CQE_REQ_ERR) {
-               is_send = 1;
-       } else {
-               is_send = 0;
-       }
-       if (opcode == GOLAN_CQE_REQ_ERR || opcode == GOLAN_CQE_RESP_ERR) {
-               err_cqe64 = (struct golan_err_cqe *)cqe64;
-               int i = 0;
-               if (!error_state++) {
-                       DBGC (golan ,"\n");
-                       for ( i = 0 ; i < 16 ; i += 2 ) {
-                               DBGC (golan ,"%x       %x\n",
-                                               be32_to_cpu(((uint32_t *)(err_cqe64))[i]),
-                                               be32_to_cpu(((uint32_t *)(err_cqe64))[i + 1]));
-                       }
-                       DBGC (golan ,"CQE with error: Syndrome(0x%x), VendorSynd(0x%x), HW_SYN(0x%x)\n",
-                                       err_cqe64->syndrome, err_cqe64->vendor_err_synd,
-                                       err_cqe64->hw_syndrom);
-               }
-       }
-       /* Identify work queue */
-       wq = ib_find_wq(cq, qpn, is_send);
-       if (!wq) {
-               DBGC (golan ,"%s unknown %s QPN 0x%x in CQN 0x%lx\n",
-                      __FUNCTION__, (is_send ? "send" : "recv"), qpn, cq->cqn);
-               return -EINVAL;
-       }
-
-       qp = wq->qp;
-       golan_qp = ib_qp_get_drvdata ( qp );
-
-       wqe_ctr = be16_to_cpu(cqe64->wqe_counter);
-       if (is_send) {
-               wqe_ctr &= ((GOLAN_WQEBBS_PER_SEND_UD_WQE * wq->num_wqes) - 1);
-               idx = wqe_ctr / GOLAN_WQEBBS_PER_SEND_UD_WQE;
-       } else {
-               idx = wqe_ctr & (wq->num_wqes - 1);
-       }
-
-       iobuf = wq->iobufs[idx];
-       if (!iobuf) {
-               DBGC (golan ,"%s IO Buffer 0x%x not found in QPN 0x%x\n",
-                          __FUNCTION__, idx, qpn);
-               return -EINVAL;
-       }
-       wq->iobufs[idx] = NULL;
-
-       if (is_send) {
-               ib_complete_send(ibdev, qp, iobuf, (opcode == GOLAN_CQE_REQ_ERR));
-       } else {
-               len = be32_to_cpu(cqe64->byte_cnt);
-               memset(&recv_dest, 0, sizeof(recv_dest));
-               recv_dest.qpn = qpn;
-               /* Construct address vector */
-               memset(&recv_source, 0, sizeof(recv_source));
-               switch (qp->type) {
-               case IB_QPT_SMI:
-               case IB_QPT_GSI:
-               case IB_QPT_UD:
-                       /* Locate corresponding GRH */
-                       assert ( golan_qp->rq.grh != NULL );
-                       grh = &golan_qp->rq.grh[ idx ];
-
-                       recv_source.qpn = be32_to_cpu(cqe64->flags_rqpn) & 0xffffff;
-                       recv_source.lid = be16_to_cpu(cqe64->slid);
-                       recv_source.sl  = (be32_to_cpu(cqe64->flags_rqpn) >> 24) & 0xf;
-                       gid_present = (be32_to_cpu(cqe64->flags_rqpn) >> 28) & 3;
-                       if (!gid_present) {
-                               recv_dest.gid_present = recv_source.gid_present = 0;
-                       } else {
-                               recv_dest.gid_present = recv_source.gid_present = 1;
-                               //if (recv_source.gid_present == 0x1) {
-                               memcpy(&recv_source.gid, &grh->sgid, sizeof(recv_source.gid));
-                               memcpy(&recv_dest.gid, &grh->dgid, sizeof(recv_dest.gid));
-                               //} else { // recv_source.gid_present = 0x3
-                                       /* GRH is located in the upper 64 byte of the CQE128
-                                        * currently not supported */
-                                       //;
-                               //}
-                       }
-                       len -= sizeof ( *grh );
-                       break;
-               case IB_QPT_RC:
-               case IB_QPT_ETH:
-               default:
-                       DBGC (golan ,"%s Unsupported QP type (0x%x)\n", __FUNCTION__, qp->type);
-                       return -EINVAL;
-               }
-               assert(len <= iob_tailroom(iobuf));
-               iob_put(iobuf, len);
-               ib_complete_recv(ibdev, qp, &recv_dest, &recv_source, iobuf, (opcode == GOLAN_CQE_RESP_ERR));
-       }
-       return 0;
-}
-
-static int golan_is_hw_ownership(struct ib_completion_queue *cq,
-                                                                struct golan_cqe64 *cqe64)
-{
-       return ((cqe64->op_own & GOLAN_CQE_OWNER_MASK) !=
-                       ((cq->next_idx >> ilog2(cq->num_cqes)) & 1));
-}
-static void golan_poll_cq(struct ib_device *ibdev,
-                               struct ib_completion_queue *cq)
-{
-       unsigned int            i;
-       int                     rc = 0;
-       unsigned int            cqe_idx_mask;
-       struct golan_cqe64      *cqe64;
-       struct golan_completion_queue *golan_cq = ib_cq_get_drvdata(cq);
-       struct golan            *golan  = ib_get_drvdata(ibdev);
-
-       for (i = 0; i < cq->num_cqes; ++i) {
-               /* Look for completion entry */
-               cqe_idx_mask = (cq->num_cqes - 1);
-               cqe64 = &golan_cq->cqes[cq->next_idx & cqe_idx_mask];
-               /* temporary valid only for 64 byte CQE */
-               if (golan_is_hw_ownership(cq, cqe64) ||
-                       ((cqe64->op_own >> GOLAN_CQE_OPCODE_BIT) ==
-                       GOLAN_CQE_OPCODE_NOT_VALID)) {
-                       break;  /* HW ownership */
-               }
-
-               DBGC2( golan , "%s CQN 0x%lx [%ld] \n", __FUNCTION__, cq->cqn, cq->next_idx);
-               /*
-                * Make sure we read CQ entry contents after we've checked the
-                * ownership bit. (PRM - 6.5.3.2)
-                */
-               rmb();
-               rc = golan_complete(ibdev, cq, cqe64);
-               if (rc != 0) {
-                       DBGC (golan ,"%s CQN 0x%lx failed to complete\n", __FUNCTION__, cq->cqn);
-               }
-
-               /* Update completion queue's index */
-               cq->next_idx++;
-
-               /* Update doorbell record */
-               *(golan_cq->doorbell_record) = cpu_to_be32(cq->next_idx & 0xffffff);
-       }
-}
-
-static const char *golan_eqe_type_str(u8 type)
-{
-       switch (type) {
-       case GOLAN_EVENT_TYPE_COMP:
-               return "GOLAN_EVENT_TYPE_COMP";
-       case GOLAN_EVENT_TYPE_PATH_MIG:
-               return "GOLAN_EVENT_TYPE_PATH_MIG";
-       case GOLAN_EVENT_TYPE_COMM_EST:
-               return "GOLAN_EVENT_TYPE_COMM_EST";
-       case GOLAN_EVENT_TYPE_SQ_DRAINED:
-               return "GOLAN_EVENT_TYPE_SQ_DRAINED";
-       case GOLAN_EVENT_TYPE_SRQ_LAST_WQE:
-               return "GOLAN_EVENT_TYPE_SRQ_LAST_WQE";
-       case GOLAN_EVENT_TYPE_SRQ_RQ_LIMIT:
-               return "GOLAN_EVENT_TYPE_SRQ_RQ_LIMIT";
-       case GOLAN_EVENT_TYPE_CQ_ERROR:
-               return "GOLAN_EVENT_TYPE_CQ_ERROR";
-       case GOLAN_EVENT_TYPE_WQ_CATAS_ERROR:
-               return "GOLAN_EVENT_TYPE_WQ_CATAS_ERROR";
-       case GOLAN_EVENT_TYPE_PATH_MIG_FAILED:
-               return "GOLAN_EVENT_TYPE_PATH_MIG_FAILED";
-       case GOLAN_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
-               return "GOLAN_EVENT_TYPE_WQ_INVAL_REQ_ERROR";
-       case GOLAN_EVENT_TYPE_WQ_ACCESS_ERROR:
-               return "GOLAN_EVENT_TYPE_WQ_ACCESS_ERROR";
-       case GOLAN_EVENT_TYPE_SRQ_CATAS_ERROR:
-               return "GOLAN_EVENT_TYPE_SRQ_CATAS_ERROR";
-       case GOLAN_EVENT_TYPE_INTERNAL_ERROR:
-               return "GOLAN_EVENT_TYPE_INTERNAL_ERROR";
-       case GOLAN_EVENT_TYPE_PORT_CHANGE:
-               return "GOLAN_EVENT_TYPE_PORT_CHANGE";
-       case GOLAN_EVENT_TYPE_GPIO_EVENT:
-               return "GOLAN_EVENT_TYPE_GPIO_EVENT";
-       case GOLAN_EVENT_TYPE_REMOTE_CONFIG:
-               return "GOLAN_EVENT_TYPE_REMOTE_CONFIG";
-       case GOLAN_EVENT_TYPE_DB_BF_CONGESTION:
-               return "GOLAN_EVENT_TYPE_DB_BF_CONGESTION";
-       case GOLAN_EVENT_TYPE_STALL_EVENT:
-               return "GOLAN_EVENT_TYPE_STALL_EVENT";
-       case GOLAN_EVENT_TYPE_CMD:
-               return "GOLAN_EVENT_TYPE_CMD";
-       case GOLAN_EVENT_TYPE_PAGE_REQUEST:
-               return "GOLAN_EVENT_TYPE_PAGE_REQUEST";
-       default:
-               return "Unrecognized event";
-       }
-}
-
-static const char *golan_eqe_port_subtype_str(u8 subtype)
-{
-       switch (subtype) {
-       case GOLAN_PORT_CHANGE_SUBTYPE_DOWN:
-               return "GOLAN_PORT_CHANGE_SUBTYPE_DOWN";
-       case GOLAN_PORT_CHANGE_SUBTYPE_ACTIVE:
-               return "GOLAN_PORT_CHANGE_SUBTYPE_ACTIVE";
-       case GOLAN_PORT_CHANGE_SUBTYPE_INITIALIZED:
-               return "GOLAN_PORT_CHANGE_SUBTYPE_INITIALIZED";
-       case GOLAN_PORT_CHANGE_SUBTYPE_LID:
-               return "GOLAN_PORT_CHANGE_SUBTYPE_LID";
-       case GOLAN_PORT_CHANGE_SUBTYPE_PKEY:
-               return "GOLAN_PORT_CHANGE_SUBTYPE_PKEY";
-       case GOLAN_PORT_CHANGE_SUBTYPE_GUID:
-               return "GOLAN_PORT_CHANGE_SUBTYPE_GUID";
-       case GOLAN_PORT_CHANGE_SUBTYPE_CLIENT_REREG:
-               return "GOLAN_PORT_CHANGE_SUBTYPE_CLIENT_REREG";
-       default:
-               return "Unrecognized event";
-       }
-}
-
-/**
- * Update Infiniband parameters using Commands
- *
- * @v ibdev            Infiniband device
- * @ret rc             Return status code
- */
-static int golan_ib_update ( struct ib_device *ibdev ) {
-       int rc;
-
-       /* Get IB parameters */
-       if ( ( rc = golan_get_ib_info ( ibdev ) ) != 0 )
-               return rc;
-
-       /* Notify Infiniband core of potential link state change */
-       ib_link_state_changed ( ibdev );
-
-       return 0;
-}
-
-static inline void golan_handle_port_event(struct golan *golan, struct golan_eqe *eqe)
-{
-       struct ib_device *ibdev;
-       u8 port;
-
-       port = (eqe->data.port.port >> 4) & 0xf;
-       ibdev = golan->ports[port - 1].ibdev;
-
-       if ( ! ib_is_open ( ibdev ) )
-               return;
-
-       switch (eqe->sub_type) {
-       case GOLAN_PORT_CHANGE_SUBTYPE_CLIENT_REREG:
-       case GOLAN_PORT_CHANGE_SUBTYPE_ACTIVE:
-               golan_ib_update ( ibdev );
-       case GOLAN_PORT_CHANGE_SUBTYPE_DOWN:
-       case GOLAN_PORT_CHANGE_SUBTYPE_LID:
-       case GOLAN_PORT_CHANGE_SUBTYPE_PKEY:
-       case GOLAN_PORT_CHANGE_SUBTYPE_GUID:
-       case GOLAN_PORT_CHANGE_SUBTYPE_INITIALIZED:
-               DBGC( golan , "%s event %s(%d) (sub event %s(%d))arrived on port %d\n",
-                          __FUNCTION__, golan_eqe_type_str(eqe->type), eqe->type,
-                          golan_eqe_port_subtype_str(eqe->sub_type),
-                          eqe->sub_type, port);
-               break;
-       default:
-               DBGC (golan ,"%s Port event with unrecognized subtype: port %d, sub_type %d\n",
-                          __FUNCTION__, port, eqe->sub_type);
-       }
-}
-
-static struct golan_eqe *golan_next_eqe_sw(struct golan_event_queue *eq)
-{
-       uint32_t entry = (eq->cons_index & (GOLAN_NUM_EQES - 1));
-       struct golan_eqe *eqe = &(eq->eqes[entry]);
-       return ((eqe->owner != ((eq->cons_index >> ilog2(GOLAN_NUM_EQES)) & 1)) ? NULL : eqe);
-}
-
-
-/**
- * Poll event queue
- *
- * @v ibdev            Infiniband device
- */
-static void golan_poll_eq(struct ib_device *ibdev)
-{
-       struct golan            *golan  = ib_get_drvdata(ibdev);
-       struct golan_event_queue *eq    = &(golan->eq);
-       struct golan_eqe        *eqe;
-       u32 cqn;
-       int counter = 0;
-
-       while ((eqe = golan_next_eqe_sw(eq)) && (counter < GOLAN_NUM_EQES)) {
-               /*
-                * Make sure we read EQ entry contents after we've
-                * checked the ownership bit.
-                */
-               rmb();
-
-               DBGC( golan , "%s eqn %d, eqe type %s\n", __FUNCTION__, eq->eqn,
-                          golan_eqe_type_str(eqe->type));
-               switch (eqe->type) {
-               case GOLAN_EVENT_TYPE_COMP:
-                       /* We dont need to handle completion events since we
-                        * poll all the CQs after polling the EQ */
-                       break;
-               case GOLAN_EVENT_TYPE_PATH_MIG:
-               case GOLAN_EVENT_TYPE_COMM_EST:
-               case GOLAN_EVENT_TYPE_SQ_DRAINED:
-               case GOLAN_EVENT_TYPE_SRQ_LAST_WQE:
-               case GOLAN_EVENT_TYPE_WQ_CATAS_ERROR:
-               case GOLAN_EVENT_TYPE_PATH_MIG_FAILED:
-               case GOLAN_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
-               case GOLAN_EVENT_TYPE_WQ_ACCESS_ERROR:
-               case GOLAN_EVENT_TYPE_SRQ_RQ_LIMIT:
-               case GOLAN_EVENT_TYPE_SRQ_CATAS_ERROR:
-                       DBGC( golan , "%s event %s(%d) arrived\n", __FUNCTION__,
-                                  golan_eqe_type_str(eqe->type), eqe->type);
-                       break;
-               case GOLAN_EVENT_TYPE_CMD:
-//                     golan_cmd_comp_handler(be32_to_cpu(eqe->data.cmd.vector));
-                       break;
-               case GOLAN_EVENT_TYPE_PORT_CHANGE:
-                       golan_handle_port_event(golan, eqe);
-                       break;
-               case GOLAN_EVENT_TYPE_CQ_ERROR:
-                       cqn = be32_to_cpu(eqe->data.cq_err.cqn) & 0xffffff;
-                       DBGC (golan ,"CQ error on CQN 0x%x, syndrom 0x%x\n",
-                                  cqn, eqe->data.cq_err.syndrome);
-//                     mlx5_cq_event(dev, cqn, eqe->type);
-                       break;
-               case GOLAN_EVENT_TYPE_PAGE_REQUEST:
-                       {
-                               /* we should check if we get this event while we
-                                * waiting for a command */
-                               u16 func_id = be16_to_cpu(eqe->data.req_pages.func_id);
-                               s16 npages = be16_to_cpu(eqe->data.req_pages.num_pages);
-
-                               DBGC (golan ,"%s page request for func 0x%x, napges %d\n",
-                                          __FUNCTION__, func_id, npages);
-                               golan_provide_pages(golan, npages, func_id);
-                       }
-                       break;
-               default:
-                       DBGC (golan ,"%s Unhandled event 0x%x on EQ 0x%x\n", __FUNCTION__,
-                                  eqe->type, eq->eqn);
-                       break;
-               }
-
-               ++eq->cons_index;
-               golan_eq_update_ci(eq, GOLAN_EQ_UNARMED);
-               ++counter;
-       }
-}
-
-/**
- * Attach to multicast group
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- * @v gid              Multicast GID
- * @ret rc             Return status code
- */
-static int golan_mcast_attach(struct ib_device *ibdev,
-                               struct ib_queue_pair *qp,
-                               union ib_gid *gid)
-{
-       struct golan *golan = ib_get_drvdata(ibdev);
-       struct golan_cmd_layout *cmd;
-       int rc;
-
-       if ( qp == NULL ) {
-               DBGC( golan, "%s: Invalid pointer, could not attach QPN to MCG\n",
-                       __FUNCTION__ );
-               return -EFAULT;
-       }
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_ATTACH_TO_MCG, 0x0,
-                                       GEN_MBOX, NO_MBOX,
-                                       sizeof(struct golan_attach_mcg_mbox_in),
-                                       sizeof(struct golan_attach_mcg_mbox_out));
-       ((struct golan_attach_mcg_mbox_in *)(cmd->in))->qpn = cpu_to_be32(qp->qpn);
-
-       memcpy(GET_INBOX(golan, GEN_MBOX), gid, sizeof(*gid));
-
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, GEN_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_CHECK_RC_AND_CMD_STATUS( err_attach_to_mcg_cmd );
-
-       DBGC( golan , "%s: QPN 0x%lx was attached to MCG\n", __FUNCTION__, qp->qpn);
-       return 0;
-err_attach_to_mcg_cmd:
-       DBGC (golan ,"%s [%d] out\n", __FUNCTION__, rc);
-       return rc;
-}
-
-/**
- * Detach from multicast group
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- * @v gid              Multicast GID
- * @ret rc             Return status code
- */
-static void golan_mcast_detach(struct ib_device *ibdev,
-                               struct ib_queue_pair *qp,
-                               union ib_gid *gid)
-{
-       struct golan *golan = ib_get_drvdata(ibdev);
-       struct golan_cmd_layout *cmd;
-       int rc;
-
-       cmd = write_cmd(golan, DEF_CMD_IDX, GOLAN_CMD_OP_DETACH_FROM_MCG, 0x0,
-                                       GEN_MBOX, NO_MBOX,
-                                   sizeof(struct golan_detach_mcg_mbox_in),
-                                   sizeof(struct golan_detach_mcg_mbox_out));
-       ((struct golan_detach_mcg_mbox_in *)(cmd->in))->qpn = cpu_to_be32(qp->qpn);
-
-       memcpy(GET_INBOX(golan, GEN_MBOX), gid, sizeof(*gid));
-
-       rc = send_command_and_wait(golan, DEF_CMD_IDX, GEN_MBOX, NO_MBOX, __FUNCTION__);
-       GOLAN_PRINT_RC_AND_CMD_STATUS;
-
-       DBGC( golan , "%s: QPN 0x%lx was detached from MCG\n", __FUNCTION__, qp->qpn);
-}
-
-/**
- * Inform embedded subnet management agent of a received MAD
- *
- * @v ibdev            Infiniband device
- * @v mad              MAD
- * @ret rc             Return status code
- */
-static int golan_inform_sma(struct ib_device *ibdev,
-                               union ib_mad *mad)
-{
-       if (!ibdev || !mad) {
-               return 1;
-       }
-
-       return 0;
-}
-
-static int golan_register_ibdev(struct golan_port *port)
-{
-       struct ib_device *ibdev = port->ibdev;
-       int rc;
-
-       golan_get_ib_info ( ibdev );
-       /* Register Infiniband device */
-       if ((rc = register_ibdev(ibdev)) != 0) {
-               DBG ( "%s port %d could not register IB device: (rc = %d)\n",
-                       __FUNCTION__, ibdev->port, rc);
-               return rc;
-       }
-
-       port->netdev = ipoib_netdev( ibdev );
-
-       return 0;
-}
-
-static inline void golan_bring_down(struct golan *golan)
-{
-
-       DBGC(golan, "%s: start\n", __FUNCTION__);
-
-       if (~golan->flags & GOLAN_OPEN) {
-               DBGC(golan, "%s: end (already closed)\n", __FUNCTION__);
-               return;
-       }
-
-       golan_destroy_mkey(golan);
-       golan_dealloc_pd(golan);
-       golan_destory_eq(golan);
-       golan_dealloc_uar(golan);
-       golan_teardown_hca(golan, GOLAN_TEARDOWN_GRACEFUL);
-       golan_handle_pages(golan, GOLAN_REG_PAGES , GOLAN_PAGES_TAKE);
-       golan_disable_hca(golan);
-       golan_cmd_uninit(golan);
-       golan->flags &= ~GOLAN_OPEN;
-       DBGC(golan, "%s: end\n", __FUNCTION__);
-}
-
-static int golan_set_link_speed ( struct golan *golan ){
-       mlx_utils utils;
-       mlx_status status;
-       int i = 0;
-
-       memset ( &utils, 0, sizeof ( utils ) );
-
-       status = mlx_utils_init ( &utils, golan->pci );
-       MLX_CHECK_STATUS ( golan->pci, status, utils_init_err, "mlx_utils_init failed" );
-
-       status = mlx_pci_gw_init ( &utils );
-       MLX_CHECK_STATUS ( golan->pci, status, pci_gw_init_err, "mlx_pci_gw_init failed" );
-
-       for ( i = 0; i < golan->caps.num_ports; ++i ) {
-               status = mlx_set_link_speed( &utils, i + 1, LINK_SPEED_IB, LINK_SPEED_SDR );
-               MLX_CHECK_STATUS ( golan->pci, status, set_link_speed_err, "mlx_set_link_speed failed" );
-       }
-
-set_link_speed_err:
-       mlx_pci_gw_teardown( &utils );
-pci_gw_init_err:
-utils_init_err:
-       return status;
-}
-
-static inline int golan_bring_up(struct golan *golan)
-{
-       int rc = 0;
-       DBGC(golan, "%s\n", __FUNCTION__);
-
-       if (golan->flags & GOLAN_OPEN)
-               return 0;
-
-       if (( rc = golan_cmd_init(golan) ))
-               goto out;
-
-       if (( rc = golan_core_enable_hca(golan) ))
-               goto cmd_uninit;
-
-       /* Query for need for boot pages */
-       if (( rc = golan_handle_pages(golan, GOLAN_BOOT_PAGES, GOLAN_PAGES_GIVE) ))
-               goto disable;
-
-       if (( rc = golan_qry_hca_cap(golan) ))
-               goto pages;
-
-       if (( rc = golan_set_hca_cap(golan) ))
-               goto pages;
-
-       if (( rc = golan_handle_pages(golan, GOLAN_INIT_PAGES, GOLAN_PAGES_GIVE) ))
-               goto pages;
-
-       if (( rc = golan_set_link_speed ( golan ) ))
-               goto pages_teardown;
-
-       //Reg Init?
-       if (( rc = golan_hca_init(golan) ))
-               goto pages_2;
-
-       if (( rc = golan_alloc_uar(golan) ))
-               goto teardown;
-
-       if (( rc = golan_create_eq(golan) ))
-               goto de_uar;
-
-       if (( rc = golan_alloc_pd(golan) ))
-               goto de_eq;
-
-       if (( rc = golan_create_mkey(golan) ))
-               goto de_pd;
-
-       golan->flags |= GOLAN_OPEN;
-       return 0;
-
-       golan_destroy_mkey(golan);
-de_pd:
-       golan_dealloc_pd(golan);
-de_eq:
-       golan_destory_eq(golan);
-de_uar:
-       golan_dealloc_uar(golan);
-teardown:
-       golan_teardown_hca(golan, GOLAN_TEARDOWN_GRACEFUL);
-pages_2:
-pages_teardown:
-       golan_handle_pages(golan, GOLAN_INIT_PAGES, GOLAN_PAGES_TAKE);
-pages:
-       golan_handle_pages(golan, GOLAN_BOOT_PAGES, GOLAN_PAGES_TAKE);
-disable:
-       golan_disable_hca(golan);
-cmd_uninit:
-       golan_cmd_uninit(golan);
-out:
-       return rc;
-}
-
-/**
- * Close Infiniband link
- *
- * @v ibdev            Infiniband device
- */
-static void golan_ib_close ( struct ib_device *ibdev __unused ) {}
-
-/**
- * Initialise Infiniband link
- *
- * @v ibdev            Infiniband device
- * @ret rc             Return status code
- */
-static int golan_ib_open ( struct ib_device *ibdev ) {
-       DBG ( "%s start\n", __FUNCTION__ );
-
-       if ( ! ibdev )
-               return -EINVAL;
-
-       golan_ib_update ( ibdev );
-
-       DBG ( "%s end\n", __FUNCTION__ );
-       return 0;
-}
-
-/** Golan Infiniband operations */
-static struct ib_device_operations golan_ib_operations = {
-       .create_cq      = golan_create_cq,
-       .destroy_cq     = golan_destroy_cq,
-       .create_qp      = golan_create_qp,
-       .modify_qp      = golan_modify_qp,
-       .destroy_qp     = golan_destroy_qp,
-       .post_send      = golan_post_send,
-       .post_recv      = golan_post_recv,
-       .poll_cq        = golan_poll_cq,
-       .poll_eq        = golan_poll_eq,
-       .open           = golan_ib_open,
-       .close          = golan_ib_close,
-       .mcast_attach   = golan_mcast_attach,
-       .mcast_detach   = golan_mcast_detach,
-       .set_port_info  = golan_inform_sma,
-       .set_pkey_table = golan_inform_sma,
-};
-
-static int golan_probe_normal ( struct pci_device *pci ) {
-       struct golan *golan;
-       struct ib_device *ibdev;
-       struct golan_port *port;
-       int i;
-       int rc = 0;
-
-       golan = golan_alloc();
-       if ( !golan ) {
-               rc = -ENOMEM;
-               goto err_golan_alloc;
-       }
-
-       if ( golan_init_pages( &golan->pages ) ) {
-               rc = -ENOMEM;
-               goto err_golan_golan_init_pages;
-       }
-
-       /* Setup PCI bus and HCA BAR */
-       pci_set_drvdata( pci, golan );
-       golan->pci = pci;
-       golan_pci_init( golan );
-       /* config command queues */
-       if ( fw_ver_and_cmdif( golan ) ) {
-               rc = -1;
-               goto err_fw_ver_cmdif;
-       }
-
-       if ( golan_bring_up( golan ) ) {
-               DBGC (golan ,"golan bringup failed\n");
-               rc = -1;
-               goto err_golan_bringup;
-       }
-
-       /* Allocate Infiniband devices */
-       for (i = 0; i < golan->caps.num_ports; ++i) {
-               ibdev = alloc_ibdev( 0 );
-               if ( !ibdev ) {
-                       rc = -ENOMEM;
-                       goto err_golan_probe_alloc_ibdev;
-               }
-               golan->ports[i].ibdev = ibdev;
-               golan->ports[i].vep_number = 0;
-               ibdev->op = &golan_ib_operations;
-               ibdev->dev = &pci->dev;
-               ibdev->port = (GOLAN_PORT_BASE + i);
-               ib_set_drvdata( ibdev, golan );
-       }
-
-       /* Register devices */
-       for ( i = 0; i < golan->caps.num_ports; ++i ) {
-               port = &golan->ports[i];
-               if ((rc = golan_register_ibdev ( port ) ) != 0 )
-                       goto err_golan_probe_register_ibdev;
-       }
-
-       return 0;
-
-       i = golan->caps.num_ports;
-err_golan_probe_register_ibdev:
-       for ( i-- ; ( signed int ) i >= 0 ; i-- )
-               unregister_ibdev ( golan->ports[i].ibdev );
-
-       i = golan->caps.num_ports;
-err_golan_probe_alloc_ibdev:
-       for ( i-- ; ( signed int ) i >= 0 ; i-- )
-               ibdev_put ( golan->ports[i].ibdev );
-
-       golan_bring_down ( golan );
-err_golan_bringup:
-err_fw_ver_cmdif:
-       iounmap( golan->iseg );
-       golan_free_pages( &golan->pages );
-err_golan_golan_init_pages:
-       free ( golan );
-err_golan_alloc:
-       DBGC (golan ,"%s rc = %d\n", __FUNCTION__, rc);
-       return rc;
-}
-
-static void golan_remove_normal ( struct pci_device *pci ) {
-       struct golan    *golan = pci_get_drvdata(pci);
-       struct golan_port *port;
-       int i;
-
-       DBGC(golan, "%s\n", __FUNCTION__);
-
-       for ( i = ( golan->caps.num_ports - 1 ) ; i >= 0 ; i-- ) {
-               port = &golan->ports[i];
-               unregister_ibdev ( port->ibdev );
-       }
-       for ( i = ( golan->caps.num_ports - 1 ) ; i >= 0 ; i-- ) {
-               netdev_nullify ( golan->ports[i].netdev );
-               netdev_put ( golan->ports[i].netdev );
-       }
-       for ( i = ( golan->caps.num_ports - 1 ) ; i >= 0 ; i-- ) {
-               ibdev_put ( golan->ports[i].ibdev );
-       }
-
-       golan_bring_down(golan);
-       iounmap( golan->iseg );
-       golan_free_pages( &golan->pages );
-       free(golan);
-}
-
-/***************************************************************************
- * NODNIC operations
- **************************************************************************/
-static mlx_status shomron_fill_eth_send_wqe ( struct ib_device *ibdev,
-                          struct ib_queue_pair *qp, struct ib_address_vector *av __unused,
-                          struct io_buffer *iobuf, struct nodnic_send_wqbb *wqbb,
-                          unsigned long wqe_index ) {
-       mlx_status status = MLX_SUCCESS;
-       struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
-       struct shomron_nodnic_eth_send_wqe *eth_wqe =  NULL;
-       struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
-       struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp =
-                       ib_qp_get_drvdata ( qp );
-       nodnic_qp *nodnic_qp = flexboot_nodnic_qp->nodnic_queue_pair;
-       struct nodnic_send_ring *send_ring = &nodnic_qp->send;
-       mlx_uint32 qpn = 0;
-
-       eth_wqe = (struct shomron_nodnic_eth_send_wqe *)wqbb;
-       memset ( ( ( ( void * ) eth_wqe ) ), 0,
-                          ( sizeof ( *eth_wqe ) ) );
-
-       status = nodnic_port_get_qpn(&port->port_priv, &send_ring->nodnic_ring,
-                       &qpn);
-       if ( status != MLX_SUCCESS ) {
-               DBG("nodnic_port_get_qpn failed\n");
-               goto err;
-       }
-
-#define SHOMRON_GENERATE_CQE 0x3
-#define SHOMRON_INLINE_HEADERS_SIZE 18
-#define SHOMRON_INLINE_HEADERS_OFFSET 32
-       MLX_FILL_2 ( &eth_wqe->ctrl, 0, opcode, FLEXBOOT_NODNIC_OPCODE_SEND,
-                       wqe_index, wqe_index & 0xFFFF);
-       MLX_FILL_2 ( &eth_wqe->ctrl, 1, ds, 0x4 , qpn, qpn );
-       MLX_FILL_1 ( &eth_wqe->ctrl, 2,
-                    ce, SHOMRON_GENERATE_CQE /* generate completion */
-                        );
-       MLX_FILL_2 ( &eth_wqe->ctrl, 7,
-                       inline_headers1,
-                       cpu_to_be16(*(mlx_uint16 *)iobuf->data),
-                       inline_headers_size, SHOMRON_INLINE_HEADERS_SIZE
-                        );
-       memcpy((void *)&eth_wqe->ctrl + SHOMRON_INLINE_HEADERS_OFFSET,
-                       iobuf->data + 2, SHOMRON_INLINE_HEADERS_SIZE - 2);
-       iob_pull(iobuf, SHOMRON_INLINE_HEADERS_SIZE);
-       MLX_FILL_1 ( &eth_wqe->data[0], 0,
-                    byte_count, iob_len ( iobuf ) );
-       MLX_FILL_1 ( &eth_wqe->data[0], 1, l_key,
-                       flexboot_nodnic->device_priv.lkey );
-       MLX_FILL_H ( &eth_wqe->data[0], 2,
-                    local_address_h, virt_to_bus ( iobuf->data ) );
-       MLX_FILL_1 ( &eth_wqe->data[0], 3,
-                    local_address_l, virt_to_bus ( iobuf->data ) );
-err:
-       return status;
-}
-
-static mlx_status shomron_fill_completion( void *cqe, struct cqe_data *cqe_data ) {
-       union shomronprm_completion_entry *cq_entry;
-       uint32_t opcode;
-
-       cq_entry = (union shomronprm_completion_entry *)cqe;
-       cqe_data->owner = MLX_GET ( &cq_entry->normal, owner );
-       opcode = MLX_GET ( &cq_entry->normal, opcode );
-#define FLEXBOOT_NODNIC_OPCODE_CQ_SEND 0
-#define FLEXBOOT_NODNIC_OPCODE_CQ_RECV 2
-#define FLEXBOOT_NODNIC_OPCODE_CQ_SEND_ERR 13
-#define FLEXBOOT_NODNIC_OPCODE_CQ_RECV_ERR 14
-       cqe_data->is_error =
-                       ( opcode >= FLEXBOOT_NODNIC_OPCODE_CQ_RECV_ERR);
-       if ( cqe_data->is_error ) {
-               cqe_data->syndrome = MLX_GET ( &cq_entry->error, syndrome );
-               cqe_data->vendor_err_syndrome =
-                               MLX_GET ( &cq_entry->error, vendor_error_syndrome );
-               cqe_data->is_send =
-                                       (opcode == FLEXBOOT_NODNIC_OPCODE_CQ_SEND_ERR);
-       } else {
-               cqe_data->is_send =
-                       (opcode == FLEXBOOT_NODNIC_OPCODE_CQ_SEND);
-               cqe_data->wqe_counter = MLX_GET ( &cq_entry->normal, wqe_counter );
-               cqe_data->byte_cnt = MLX_GET ( &cq_entry->normal, byte_cnt );
-
-       }
-       if ( cqe_data->is_send == TRUE )
-               cqe_data->qpn = MLX_GET ( &cq_entry->normal, qpn );
-       else
-               cqe_data->qpn = MLX_GET ( &cq_entry->normal, srqn );
-
-       return 0;
-}
-
-static mlx_status shomron_cqe_set_owner ( void *cq, unsigned int num_cqes ) {
-       unsigned int i = 0;
-       union shomronprm_completion_entry *cq_list;
-
-       cq_list = (union shomronprm_completion_entry *)cq;
-       for ( ; i < num_cqes ; i++ )
-               MLX_FILL_1 ( &cq_list[i].normal, 15, owner, 1 );
-       return 0;
-}
-
-static mlx_size shomron_get_cqe_size () {
-       return sizeof ( union shomronprm_completion_entry );
-}
-
-struct flexboot_nodnic_callbacks shomron_nodnic_callbacks = {
-       .get_cqe_size = shomron_get_cqe_size,
-       .fill_send_wqe[IB_QPT_ETH] = shomron_fill_eth_send_wqe,
-       .fill_completion = shomron_fill_completion,
-       .cqe_set_owner = shomron_cqe_set_owner,
-       .irq = flexboot_nodnic_eth_irq,
-};
-
-static int shomron_nodnic_supported = 0;
-
-static int shomron_nodnic_is_supported ( struct pci_device *pci ) {
-       if ( pci->device == 0x1011 )
-               return 0;
-
-       return flexboot_nodnic_is_supported ( pci );
-}
-/**************************************************************************/
-
-static int golan_probe ( struct pci_device *pci ) {
-       int rc = -ENOTSUP;
-
-       DBG ( "%s: start\n", __FUNCTION__ );
-
-       if ( ! pci ) {
-               DBG ( "%s: PCI is NULL\n", __FUNCTION__ );
-               rc = -EINVAL;
-               goto probe_done;
-       }
-
-       shomron_nodnic_supported = shomron_nodnic_is_supported ( pci );
-       if ( shomron_nodnic_supported ) {
-               rc = flexboot_nodnic_probe ( pci, &shomron_nodnic_callbacks, NULL );
-               if ( rc == 0 ) {
-                       DBG ( "%s: Using NODNIC driver\n", __FUNCTION__ );
-                       goto probe_done;
-               }
-               shomron_nodnic_supported = 0;
-       }
-
-       if ( ! shomron_nodnic_supported ) {
-               DBG ( "%s: Using normal driver\n", __FUNCTION__ );
-               rc = golan_probe_normal ( pci );
-       }
-
-probe_done:
-       DBG ( "%s: rc = %d\n", __FUNCTION__, rc );
-       return rc;
-}
-
-static void golan_remove ( struct pci_device *pci ) {
-       DBG ( "%s: start\n", __FUNCTION__ );
-
-       if ( ! shomron_nodnic_supported ) {
-               DBG ( "%s: Using normal driver remove\n", __FUNCTION__ );
-               golan_remove_normal ( pci );
-               return;
-       }
-
-       DBG ( "%s: Using NODNIC driver remove\n", __FUNCTION__ );
-
-       flexboot_nodnic_remove ( pci );
-
-       DBG ( "%s: end\n", __FUNCTION__ );
-}
-
-static struct pci_device_id golan_nics[] = {
-       PCI_ROM ( 0x15b3, 0x1011, "ConnectIB", "ConnectIB HCA driver: DevID 4113", 0 ),
-       PCI_ROM ( 0x15b3, 0x1013, "ConnectX-4", "ConnectX-4 HCA driver, DevID 4115", 0 ),
-       PCI_ROM ( 0x15b3, 0x1015, "ConnectX-4Lx", "ConnectX-4Lx HCA driver, DevID 4117", 0 ),
-};
-
-struct pci_driver golan_driver __pci_driver = {
-       .ids            = golan_nics,
-       .id_count       = (sizeof(golan_nics) / sizeof(golan_nics[0])),
-       .probe          = golan_probe,
-       .remove         = golan_remove,
-};
diff --git a/roms/ipxe/src/drivers/infiniband/golan.h b/roms/ipxe/src/drivers/infiniband/golan.h
deleted file mode 100755 (executable)
index a6cb4e7..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-#ifndef _GOLAN_H_
-#define _GOLAN_H_
-
-/*
- * Copyright (C) 2013-2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <byteswap.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <ipxe/io.h>
-#include <ipxe/pci.h>
-#include <ipxe/pcibackup.h>
-#include "CIB_PRM.h"
-
-#define GOLAN_PCI_CONFIG_BAR_SIZE      0x100000//HERMON_PCI_CONFIG_BAR_SIZE //TODO: What is the BAR size?
-
-#define GOLAN_PAS_SIZE sizeof(uint64_t)
-
-#define GOLAN_INVALID_LKEY 0x00000100UL
-
-#define GOLAN_MAX_PORTS        2
-#define GOLAN_PORT_BASE 1
-
-#define MELLANOX_VID   0x15b3
-#define GOLAN_HCA_BAR  PCI_BASE_ADDRESS_0      //BAR 0
-
-#define GOLAN_HCR_MAX_WAIT_MS  10000
-
-#define min(a,b) ((a)<(b)?(a):(b))
-
-#define GOLAN_PAGE_SHIFT       12
-#define        GOLAN_PAGE_SIZE         (1 << GOLAN_PAGE_SHIFT)
-#define GOLAN_PAGE_MASK                (GOLAN_PAGE_SIZE - 1)
-
-#define MAX_MBOX       ( GOLAN_PAGE_SIZE / MAILBOX_STRIDE )
-#define DEF_CMD_IDX    1
-#define MEM_CMD_IDX    0
-#define NO_MBOX                0xffff
-#define MEM_MBOX       MEM_CMD_IDX
-#define GEN_MBOX       DEF_CMD_IDX
-
-#define CMD_IF_REV     4
-
-#define MAX_PASE_MBOX  ((GOLAN_CMD_PAS_CNT) - 2)
-
-#define CMD_STATUS( golan , idx )              ((struct golan_outbox_hdr *)(get_cmd( (golan) , (idx) )->out))->status
-#define CMD_SYND( golan , idx )                ((struct golan_outbox_hdr *)(get_cmd( (golan) , (idx) )->out))->syndrome
-#define QRY_PAGES_OUT( golan, idx )            ((struct golan_query_pages_outbox *)(get_cmd( (golan) , (idx) )->out))
-
-#define VIRT_2_BE64_BUS( addr )                cpu_to_be64(((unsigned long long )virt_to_bus(addr)))
-#define BE64_BUS_2_VIRT( addr )                bus_to_virt(be64_to_cpu(addr))
-#define USR_2_BE64_BUS( addr )         cpu_to_be64(((unsigned long long )user_to_phys(addr, 0)))
-#define BE64_BUS_2_USR( addr )         be64_to_cpu(phys_to_user(addr))
-
-#define GET_INBOX(golan, idx)          (&(((struct mbox *)(golan->mboxes.inbox))[idx]))
-#define GET_OUTBOX(golan, idx)         (&(((struct mbox *)(golan->mboxes.outbox))[idx]))
-
-#define GOLAN_MBOX_IN( cmd_ptr, in_ptr ) ( {                             \
-       union {                                                           \
-               __be32 raw[4];                                            \
-               typeof ( *(in_ptr) ) cooked;                              \
-       } *u = container_of ( &(cmd_ptr)->in[0], typeof ( *u ), raw[0] ); \
-       &u->cooked; } )
-
-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
-
-/* Fw status fields */
-typedef enum {
-       NO_ERRORS          = 0x0,
-       SIGNATURE_ERROR    = 0x1,
-       TOKEN_ERROR        = 0x2,
-       BAD_BLOCK_NUMBER   = 0x3,
-       BAD_OUTPUT_POINTER = 0x4,   // pointer not align to mailbox size
-       BAD_INPUT_POINTER  = 0x5,   // pointer not align to mailbox size
-       INTERNAL_ERROR     = 0x6,
-       INPUT_LEN_ERROR    = 0x7,   // input  length less than 0x8.
-       OUTPUT_LEN_ERROR   = 0x8,   // output length less than 0x8.
-       RESERVE_NOT_ZERO   = 0x9,
-       BAD_CMD_TYPE       = 0x10,
-} return_hdr_t;
-
-struct golan_cmdq_md {
-       void    *addr;
-       u16     log_stride;
-       u16     size;
-};
-
-struct golan_uar {
-    uint32_t           index;
-    void               *virt;
-    unsigned long      phys;
-};
-
-/* Queue Pair */
-#define GOLAN_SEND_WQE_BB_SIZE                 64
-#define GOLAN_SEND_UD_WQE_SIZE                 sizeof(struct golan_send_wqe_ud)
-#define GOLAN_RECV_WQE_SIZE                            sizeof(struct golan_recv_wqe_ud)
-#define GOLAN_WQEBBS_PER_SEND_UD_WQE   DIV_ROUND_UP(GOLAN_SEND_UD_WQE_SIZE, GOLAN_SEND_WQE_BB_SIZE)
-#define GOLAN_SEND_OPCODE                      0x0a
-#define GOLAN_WQE_CTRL_WQE_IDX_BIT     8
-
-enum golan_ib_qp_state {
-       GOLAN_IB_QPS_RESET,
-       GOLAN_IB_QPS_INIT,
-       GOLAN_IB_QPS_RTR,
-       GOLAN_IB_QPS_RTS,
-       GOLAN_IB_QPS_SQD,
-       GOLAN_IB_QPS_SQE,
-       GOLAN_IB_QPS_ERR
-};
-
-struct golan_send_wqe_ud {
-       struct golan_wqe_ctrl_seg ctrl;
-       struct golan_av datagram;
-       struct golan_wqe_data_seg data;
-};
-
-union golan_send_wqe {
-       struct golan_send_wqe_ud ud;
-       uint8_t pad[GOLAN_WQEBBS_PER_SEND_UD_WQE * GOLAN_SEND_WQE_BB_SIZE];
-};
-
-struct golan_recv_wqe_ud {
-       struct golan_wqe_data_seg data[2];
-};
-
-struct golan_recv_wq {
-       struct golan_recv_wqe_ud *wqes;
-       /* WQ size in bytes */
-       int     size;
-       /* In SQ, it will be increased in wqe_size (number of WQEBBs per WQE) */
-       u16 next_idx;
-       /** GRH buffers (if applicable) */
-       struct ib_global_route_header *grh;
-       /** Size of GRH buffers */
-       size_t grh_size;
-};
-
-struct golan_send_wq {
-       union golan_send_wqe *wqes;
-       /* WQ size in bytes */
-       int size;
-       /* In SQ, it will be increased in wqe_size (number of WQEBBs per WQE) */
-       u16 next_idx;
-};
-
-struct golan_queue_pair {
-       void *wqes;
-       int size;
-       struct golan_recv_wq rq;
-       struct golan_send_wq sq;
-       struct golan_qp_db *doorbell_record;
-       u32 doorbell_qpn;
-       enum golan_ib_qp_state state;
-};
-
-/* Completion Queue */
-#define GOLAN_CQE_OPCODE_NOT_VALID     0x0f
-#define GOLAN_CQE_OPCODE_BIT           4
-#define GOLAN_CQ_DB_RECORD_SIZE                sizeof(uint64_t)
-#define GOLAN_CQE_OWNER_MASK           1
-
-#define MANAGE_PAGES_PSA_OFFSET                0
-#define PXE_CMDIF_REF                  5
-
-enum {
-       GOLAN_CQE_SW_OWNERSHIP = 0x0,
-       GOLAN_CQE_HW_OWNERSHIP = 0x1
-};
-
-enum {
-       GOLAN_CQE_SIZE_64       = 0,
-       GOLAN_CQE_SIZE_128      = 1
-};
-
-struct golan_completion_queue {
-       struct golan_cqe64      *cqes;
-       int                                     size;
-       __be64          *doorbell_record;
-};
-
-
-/* Event Queue */
-#define GOLAN_EQE_SIZE                         sizeof(struct golan_eqe)
-#define GOLAN_NUM_EQES                                 8
-#define GOLAN_EQ_DOORBELL_OFFSET               0x40
-
-#define GOLAN_EQ_MAP_ALL_EVENTS                                        \
-       ((1 << GOLAN_EVENT_TYPE_PATH_MIG                )|      \
-       (1 << GOLAN_EVENT_TYPE_COMM_EST                 )|      \
-       (1 << GOLAN_EVENT_TYPE_SQ_DRAINED               )|      \
-       (1 << GOLAN_EVENT_TYPE_SRQ_LAST_WQE             )|      \
-       (1 << GOLAN_EVENT_TYPE_SRQ_RQ_LIMIT             )|      \
-       (1 << GOLAN_EVENT_TYPE_CQ_ERROR                 )|      \
-       (1 << GOLAN_EVENT_TYPE_WQ_CATAS_ERROR           )|      \
-       (1 << GOLAN_EVENT_TYPE_PATH_MIG_FAILED          )|      \
-       (1 << GOLAN_EVENT_TYPE_WQ_INVAL_REQ_ERROR       )|      \
-       (1 << GOLAN_EVENT_TYPE_WQ_ACCESS_ERROR          )|      \
-       (1 << GOLAN_EVENT_TYPE_SRQ_CATAS_ERROR          )|      \
-       (1 << GOLAN_EVENT_TYPE_INTERNAL_ERROR           )|      \
-       (1 << GOLAN_EVENT_TYPE_PORT_CHANGE              )|      \
-       (1 << GOLAN_EVENT_TYPE_GPIO_EVENT               )|      \
-       (1 << GOLAN_EVENT_TYPE_CLIENT_RE_REGISTER       )|      \
-       (1 << GOLAN_EVENT_TYPE_REMOTE_CONFIG            )|      \
-       (1 << GOLAN_EVENT_TYPE_DB_BF_CONGESTION         )|      \
-       (1 << GOLAN_EVENT_TYPE_STALL_EVENT              )|      \
-       (1 << GOLAN_EVENT_TYPE_PACKET_DROPPED           )|      \
-       (1 << GOLAN_EVENT_TYPE_CMD                      )|      \
-       (1 << GOLAN_EVENT_TYPE_PAGE_REQUEST             ))
-
-enum golan_event {
-       GOLAN_EVENT_TYPE_COMP                   = 0x0,
-
-       GOLAN_EVENT_TYPE_PATH_MIG               = 0x01,
-       GOLAN_EVENT_TYPE_COMM_EST               = 0x02,
-       GOLAN_EVENT_TYPE_SQ_DRAINED             = 0x03,
-       GOLAN_EVENT_TYPE_SRQ_LAST_WQE           = 0x13,
-       GOLAN_EVENT_TYPE_SRQ_RQ_LIMIT           = 0x14,
-
-       GOLAN_EVENT_TYPE_CQ_ERROR               = 0x04,
-       GOLAN_EVENT_TYPE_WQ_CATAS_ERROR         = 0x05,
-       GOLAN_EVENT_TYPE_PATH_MIG_FAILED        = 0x07,
-       GOLAN_EVENT_TYPE_WQ_INVAL_REQ_ERROR     = 0x10,
-       GOLAN_EVENT_TYPE_WQ_ACCESS_ERROR        = 0x11,
-       GOLAN_EVENT_TYPE_SRQ_CATAS_ERROR        = 0x12,
-
-       GOLAN_EVENT_TYPE_INTERNAL_ERROR         = 0x08,
-       GOLAN_EVENT_TYPE_PORT_CHANGE            = 0x09,
-       GOLAN_EVENT_TYPE_GPIO_EVENT             = 0x15,
-//     GOLAN_EVENT_TYPE_CLIENT_RE_REGISTER     = 0x16,
-       GOLAN_EVENT_TYPE_REMOTE_CONFIG          = 0x19,
-
-       GOLAN_EVENT_TYPE_DB_BF_CONGESTION       = 0x1a,
-       GOLAN_EVENT_TYPE_STALL_EVENT            = 0x1b,
-
-       GOLAN_EVENT_TYPE_PACKET_DROPPED         = 0x1f,
-
-       GOLAN_EVENT_TYPE_CMD                    = 0x0a,
-       GOLAN_EVENT_TYPE_PAGE_REQUEST           = 0x0b,
-       GOLAN_EVENT_TYPE_PAGE_FAULT             = 0x0C,
-};
-
-enum golan_port_sub_event {
-    GOLAN_PORT_CHANGE_SUBTYPE_DOWN             = 1,
-    GOLAN_PORT_CHANGE_SUBTYPE_ACTIVE           = 4,
-    GOLAN_PORT_CHANGE_SUBTYPE_INITIALIZED      = 5,
-    GOLAN_PORT_CHANGE_SUBTYPE_LID              = 6,
-    GOLAN_PORT_CHANGE_SUBTYPE_PKEY             = 7,
-    GOLAN_PORT_CHANGE_SUBTYPE_GUID             = 8,
-    GOLAN_PORT_CHANGE_SUBTYPE_CLIENT_REREG     = 9
-};
-
-
-enum {
-       GOLAN_EQE_SW_OWNERSHIP = 0x0,
-       GOLAN_EQE_HW_OWNERSHIP = 0x1
-};
-
-enum {
-       GOLAN_EQ_UNARMED        = 0,
-       GOLAN_EQ_ARMED          = 1,
-};
-
-struct golan_event_queue {
-       uint8_t                 eqn;
-       uint64_t                mask;
-       struct golan_eqe        *eqes;
-       int                     size;
-       __be32                  *doorbell;
-       uint32_t                cons_index;
-};
-
-struct golan_port {
-       /** Infiniband device */
-       struct ib_device        *ibdev;
-       /** Network device */
-       struct net_device       *netdev;
-       /** VEP number */
-       u8 vep_number;
-};
-
-struct golan_mboxes {
-       void    *inbox;
-       void    *outbox;
-};
-
-#define GOLAN_OPEN     0x1
-
-struct golan {
-       struct pci_device               *pci;
-       struct golan_hca_init_seg       *iseg;
-       struct golan_cmdq_md            cmd;
-       struct golan_hca_cap            caps; /* stored as big indian*/
-       struct golan_mboxes             mboxes;
-       struct list_head                pages;
-       uint32_t                        cmd_bm;
-       uint32_t                        total_dma_pages;
-       struct golan_uar                uar;
-       struct golan_event_queue        eq;
-       uint32_t                        pdn;
-       u32                             mkey;
-       u32                             flags;
-
-       struct golan_port               ports[GOLAN_MAX_PORTS];
-};
-
-#endif /* _GOLAN_H_*/
index 79d6060..a9c7287 100644 (file)
@@ -1111,8 +1111,6 @@ static int hermon_create_qp ( struct ib_device *ibdev,
        struct hermon *hermon = ib_get_drvdata ( ibdev );
        struct hermon_queue_pair *hermon_qp;
        struct hermonprm_qp_ee_state_transitions qpctx;
-       struct hermonprm_wqe_segment_data_ptr *data;
-       unsigned int i;
        int rc;
 
        /* Calculate queue pair number */
@@ -1149,14 +1147,8 @@ static int hermon_create_qp ( struct ib_device *ibdev,
                                     sizeof ( hermon_qp->send.wqe[0] ) );
        hermon_qp->recv.wqe_size = ( qp->recv.num_wqes *
                                     sizeof ( hermon_qp->recv.wqe[0] ) );
-       if ( ( qp->type == IB_QPT_SMI ) || ( qp->type == IB_QPT_GSI ) ||
-            ( qp->type == IB_QPT_UD ) ) {
-               hermon_qp->recv.grh_size = ( qp->recv.num_wqes *
-                                            sizeof ( hermon_qp->recv.grh[0] ));
-       }
        hermon_qp->wqe_size = ( hermon_qp->send.wqe_size +
-                               hermon_qp->recv.wqe_size +
-                               hermon_qp->recv.grh_size );
+                               hermon_qp->recv.wqe_size );
        hermon_qp->wqe = malloc_dma ( hermon_qp->wqe_size,
                                      sizeof ( hermon_qp->send.wqe[0] ) );
        if ( ! hermon_qp->wqe ) {
@@ -1164,21 +1156,9 @@ static int hermon_create_qp ( struct ib_device *ibdev,
                goto err_alloc_wqe;
        }
        hermon_qp->send.wqe = hermon_qp->wqe;
-       hermon_qp->recv.wqe = ( hermon_qp->wqe + hermon_qp->send.wqe_size );
-       if ( hermon_qp->recv.grh_size ) {
-               hermon_qp->recv.grh = ( hermon_qp->wqe +
-                                       hermon_qp->send.wqe_size +
-                                       hermon_qp->recv.wqe_size );
-       }
-
-       /* Initialise work queue entries */
        memset ( hermon_qp->send.wqe, 0xff, hermon_qp->send.wqe_size );
+       hermon_qp->recv.wqe = ( hermon_qp->wqe + hermon_qp->send.wqe_size );
        memset ( hermon_qp->recv.wqe, 0, hermon_qp->recv.wqe_size );
-       data = &hermon_qp->recv.wqe[0].recv.data[0];
-       for ( i = 0 ; i < ( hermon_qp->recv.wqe_size / sizeof ( *data ) ); i++){
-               MLX_FILL_1 ( data, 1, l_key, HERMON_INVALID_LKEY );
-               data++;
-       }
 
        /* Allocate MTT entries */
        if ( ( rc = hermon_alloc_mtt ( hermon, hermon_qp->wqe,
@@ -1653,8 +1633,6 @@ static int hermon_post_recv ( struct ib_device *ibdev,
        struct ib_work_queue *wq = &qp->recv;
        struct hermon_recv_work_queue *hermon_recv_wq = &hermon_qp->recv;
        struct hermonprm_recv_wqe *wqe;
-       struct hermonprm_wqe_segment_data_ptr *data;
-       struct ib_global_route_header *grh;
        unsigned int wqe_idx_mask;
 
        /* Allocate work queue entry */
@@ -1668,19 +1646,12 @@ static int hermon_post_recv ( struct ib_device *ibdev,
        wqe = &hermon_recv_wq->wqe[wq->next_idx & wqe_idx_mask].recv;
 
        /* Construct work queue entry */
-       data = &wqe->data[0];
-       if ( hermon_qp->recv.grh ) {
-               grh = &hermon_qp->recv.grh[wq->next_idx & wqe_idx_mask];
-               MLX_FILL_1 ( data, 0, byte_count, sizeof ( *grh ) );
-               MLX_FILL_1 ( data, 1, l_key, hermon->lkey );
-               MLX_FILL_H ( data, 2, local_address_h, virt_to_bus ( grh ) );
-               MLX_FILL_1 ( data, 3, local_address_l, virt_to_bus ( grh ) );
-               data++;
-       }
-       MLX_FILL_1 ( data, 0, byte_count, iob_tailroom ( iobuf ) );
-       MLX_FILL_1 ( data, 1, l_key, hermon->lkey );
-       MLX_FILL_H ( data, 2, local_address_h, virt_to_bus ( iobuf->data ) );
-       MLX_FILL_1 ( data, 3, local_address_l, virt_to_bus ( iobuf->data ) );
+       MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_tailroom ( iobuf ) );
+       MLX_FILL_1 ( &wqe->data[0], 1, l_key, hermon->lkey );
+       MLX_FILL_H ( &wqe->data[0], 2,
+                    local_address_h, virt_to_bus ( iobuf->data ) );
+       MLX_FILL_1 ( &wqe->data[0], 3,
+                    local_address_l, virt_to_bus ( iobuf->data ) );
 
        /* Update work queue's index */
        wq->next_idx++;
@@ -1705,7 +1676,6 @@ static int hermon_complete ( struct ib_device *ibdev,
                             struct ib_completion_queue *cq,
                             union hermonprm_completion_entry *cqe ) {
        struct hermon *hermon = ib_get_drvdata ( ibdev );
-       struct hermon_queue_pair *hermon_qp;
        struct ib_work_queue *wq;
        struct ib_queue_pair *qp;
        struct io_buffer *iobuf;
@@ -1743,7 +1713,6 @@ static int hermon_complete ( struct ib_device *ibdev,
                return -EIO;
        }
        qp = wq->qp;
-       hermon_qp = ib_qp_get_drvdata ( qp );
 
        /* Identify work queue entry */
        wqe_idx = MLX_GET ( &cqe->normal, wqe_counter );
@@ -1769,6 +1738,8 @@ static int hermon_complete ( struct ib_device *ibdev,
        } else {
                /* Set received length */
                len = MLX_GET ( &cqe->normal, byte_cnt );
+               assert ( len <= iob_tailroom ( iobuf ) );
+               iob_put ( iobuf, len );
                memset ( &recv_dest, 0, sizeof ( recv_dest ) );
                recv_dest.qpn = qpn;
                memset ( &recv_source, 0, sizeof ( recv_source ) );
@@ -1776,10 +1747,9 @@ static int hermon_complete ( struct ib_device *ibdev,
                case IB_QPT_SMI:
                case IB_QPT_GSI:
                case IB_QPT_UD:
-                       /* Locate corresponding GRH */
-                       assert ( hermon_qp->recv.grh != NULL );
-                       grh = &hermon_qp->recv.grh[ wqe_idx & wqe_idx_mask ];
-                       len -= sizeof ( *grh );
+                       assert ( iob_len ( iobuf ) >= sizeof ( *grh ) );
+                       grh = iobuf->data;
+                       iob_pull ( iobuf, sizeof ( *grh ) );
                        /* Construct address vector */
                        source = &recv_source;
                        source->qpn = MLX_GET ( &cqe->normal, srq_rqpn );
@@ -1805,8 +1775,6 @@ static int hermon_complete ( struct ib_device *ibdev,
                        assert ( 0 );
                        return -EINVAL;
                }
-               assert ( len <= iob_tailroom ( iobuf ) );
-               iob_put ( iobuf, len );
                /* Hand off to completion handler */
                ib_complete_recv ( ibdev, qp, &recv_dest, source, iobuf, rc );
        }
@@ -3274,7 +3242,7 @@ static int hermon_eth_open ( struct net_device *netdev ) {
        port->eth_qp = ib_create_qp ( ibdev, IB_QPT_ETH,
                                      HERMON_ETH_NUM_SEND_WQES, port->eth_cq,
                                      HERMON_ETH_NUM_RECV_WQES, port->eth_cq,
-                                     &hermon_eth_qp_op, netdev->name );
+                                     &hermon_eth_qp_op );
        if ( ! port->eth_qp ) {
                DBGC ( hermon, "Hermon %p port %d could not create queue "
                       "pair\n", hermon, ibdev->port );
@@ -3780,6 +3748,24 @@ static void hermon_free ( struct hermon *hermon ) {
 }
 
 /**
+ * Initialise Hermon PCI parameters
+ *
+ * @v hermon           Hermon device
+ */
+static void hermon_pci_init ( struct hermon *hermon ) {
+       struct pci_device *pci = hermon->pci;
+
+       /* Fix up PCI device */
+       adjust_pci_device ( pci );
+
+       /* Get PCI BARs */
+       hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR),
+                                  HERMON_PCI_CONFIG_BAR_SIZE );
+       hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
+                               HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
+}
+
+/**
  * Probe PCI device
  *
  * @v pci              PCI device
@@ -3803,14 +3789,8 @@ static int hermon_probe ( struct pci_device *pci ) {
        pci_set_drvdata ( pci, hermon );
        hermon->pci = pci;
 
-       /* Fix up PCI device */
-       adjust_pci_device ( pci );
-
-       /* Map PCI BARs */
-       hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR ),
-                                  HERMON_PCI_CONFIG_BAR_SIZE );
-       hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
-                               HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
+       /* Initialise PCI parameters */
+       hermon_pci_init ( hermon );
 
        /* Reset device */
        hermon_reset ( hermon );
@@ -3905,8 +3885,6 @@ static int hermon_probe ( struct pci_device *pci ) {
  err_get_cap:
        hermon_stop_firmware ( hermon );
  err_start_firmware:
-       iounmap ( hermon->uar );
-       iounmap ( hermon->config );
        hermon_free ( hermon );
  err_alloc:
        return rc;
@@ -3932,8 +3910,6 @@ static void hermon_remove ( struct pci_device *pci ) {
        }
        for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- )
                ibdev_put ( hermon->port[i].ibdev );
-       iounmap ( hermon->uar );
-       iounmap ( hermon->config );
        hermon_free ( hermon );
 }
 
@@ -3957,12 +3933,8 @@ static int hermon_bofm_probe ( struct pci_device *pci ) {
        pci_set_drvdata ( pci, hermon );
        hermon->pci = pci;
 
-       /* Fix up PCI device */
-       adjust_pci_device ( pci );
-
-       /* Map PCI BAR */
-       hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR ),
-                                  HERMON_PCI_CONFIG_BAR_SIZE );
+       /* Initialise PCI parameters */
+       hermon_pci_init ( hermon );
 
        /* Initialise BOFM device */
        bofm_init ( &hermon->bofm, pci, &hermon_bofm_operations );
@@ -3977,7 +3949,6 @@ static int hermon_bofm_probe ( struct pci_device *pci ) {
        return 0;
 
  err_bofm_register:
-       iounmap ( hermon->config );
        hermon_free ( hermon );
  err_alloc:
        return rc;
@@ -3992,7 +3963,6 @@ static void hermon_bofm_remove ( struct pci_device *pci ) {
        struct hermon *hermon = pci_get_drvdata ( pci );
 
        bofm_unregister ( &hermon->bofm );
-       iounmap ( hermon->config );
        hermon_free ( hermon );
 }
 
index 61e2857..e0b028f 100644 (file)
@@ -515,7 +515,7 @@ struct hermonprm_eth_send_wqe {
        struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_GATHER];
 } __attribute__ (( packed ));
 
-#define HERMON_MAX_SCATTER 2
+#define HERMON_MAX_SCATTER 1
 
 struct hermonprm_recv_wqe {
        struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_SCATTER];
@@ -686,10 +686,6 @@ struct hermon_recv_work_queue {
        union hermon_recv_wqe *wqe;
        /** Size of work queue */
        size_t wqe_size;
-       /** GRH buffers (if applicable) */
-       struct ib_global_route_header *grh;
-       /** Size of GRH buffers */
-       size_t grh_size;
        /** Doorbell record */
        struct hermonprm_qp_db_record *doorbell;
 };
index 77d50d1..a6ae9f5 100644 (file)
@@ -112,21 +112,32 @@ struct linda {
  * This card requires atomic 64-bit accesses.  Strange things happen
  * if you try to use 32-bit accesses; sometimes they work, sometimes
  * they don't, sometimes you get random data.
+ *
+ * These accessors use the "movq" MMX instruction, and so won't work
+ * on really old Pentiums (which won't have PCIe anyway, so this is
+ * something of a moot point).
  */
 
 /**
  * Read Linda qword register
  *
  * @v linda            Linda device
- * @v qword            Register buffer to read into
+ * @v dwords           Register buffer to read into
  * @v offset           Register offset
  */
-static void linda_readq ( struct linda *linda, uint64_t *qword,
+static void linda_readq ( struct linda *linda, uint32_t *dwords,
                          unsigned long offset ) {
-       *qword = readq ( linda->regs + offset );
+       void *addr = ( linda->regs + offset );
+
+       __asm__ __volatile__ ( "movq (%1), %%mm0\n\t"
+                              "movq %%mm0, (%0)\n\t"
+                              : : "r" ( dwords ), "r" ( addr ) : "memory" );
+
+       DBGIO ( "[%08lx] => %08x%08x\n",
+               virt_to_phys ( addr ), dwords[1], dwords[0] );
 }
 #define linda_readq( _linda, _ptr, _offset ) \
-       linda_readq ( (_linda), (_ptr)->u.qwords, (_offset) )
+       linda_readq ( (_linda), (_ptr)->u.dwords, (_offset) )
 #define linda_readq_array8b( _linda, _ptr, _offset, _idx ) \
        linda_readq ( (_linda), (_ptr), ( (_offset) + ( (_idx) * 8 ) ) )
 #define linda_readq_array64k( _linda, _ptr, _offset, _idx ) \
@@ -136,15 +147,22 @@ static void linda_readq ( struct linda *linda, uint64_t *qword,
  * Write Linda qword register
  *
  * @v linda            Linda device
- * @v qword            Register buffer to write
+ * @v dwords           Register buffer to write
  * @v offset           Register offset
  */
-static void linda_writeq ( struct linda *linda, const uint64_t *qword,
+static void linda_writeq ( struct linda *linda, const uint32_t *dwords,
                           unsigned long offset ) {
-       writeq ( *qword, ( linda->regs + offset ) );
+       void *addr = ( linda->regs + offset );
+
+       DBGIO ( "[%08lx] <= %08x%08x\n",
+               virt_to_phys ( addr ), dwords[1], dwords[0] );
+
+       __asm__ __volatile__ ( "movq (%0), %%mm0\n\t"
+                              "movq %%mm0, (%1)\n\t"
+                              : : "r" ( dwords ), "r" ( addr ) : "memory" );
 }
 #define linda_writeq( _linda, _ptr, _offset ) \
-       linda_writeq ( (_linda), (_ptr)->u.qwords, (_offset) )
+       linda_writeq ( (_linda), (_ptr)->u.dwords, (_offset) )
 #define linda_writeq_array8b( _linda, _ptr, _offset, _idx ) \
        linda_writeq ( (_linda), (_ptr), ( (_offset) + ( (_idx) * 8 ) ) )
 #define linda_writeq_array64k( _linda, _ptr, _offset, _idx ) \
@@ -1271,15 +1289,8 @@ static void linda_complete_recv ( struct ib_device *ibdev,
                        /* Completing the eager buffer described in
                         * this header entry.
                         */
-                       if ( payload_len <= iob_tailroom ( iobuf ) ) {
-                               iob_put ( iobuf, payload_len );
-                               rc = ( err ?
-                                      -EIO : ( useegrbfr ? 0 : -ECANCELED ) );
-                       } else {
-                               DBGC ( linda, "Linda %p bad payload len %zd\n",
-                                      linda, payload_len );
-                               rc = -EPROTO;
-                       }
+                       iob_put ( iobuf, payload_len );
+                       rc = ( err ? -EIO : ( useegrbfr ? 0 : -ECANCELED ) );
                        /* Redirect to target QP if necessary */
                        if ( qp != intended_qp ) {
                                DBGC ( linda, "Linda %p redirecting QPN %ld "
@@ -1290,7 +1301,7 @@ static void linda_complete_recv ( struct ib_device *ibdev,
                                intended_qp->recv.fill++;
                        }
                        ib_complete_recv ( ibdev, intended_qp, &dest, &source,
-                                          iobuf, rc );
+                                          iobuf, rc);
                } else {
                        /* Completing on a skipped-over eager buffer */
                        ib_complete_recv ( ibdev, qp, &dest, &source, iobuf,
@@ -2334,7 +2345,7 @@ static int linda_probe ( struct pci_device *pci ) {
        /* Fix up PCI device */
        adjust_pci_device ( pci );
 
-       /* Map PCI BARs */
+       /* Get PCI BARs */
        linda->regs = ioremap ( pci->membase, LINDA_BAR0_SIZE );
        DBGC2 ( linda, "Linda %p has BAR at %08lx\n", linda, pci->membase );
 
@@ -2395,7 +2406,6 @@ static int linda_probe ( struct pci_device *pci ) {
  err_init_ib_serdes:
  err_read_eeprom:
  err_init_i2c:
-       iounmap ( linda->regs );
        ibdev_put ( ibdev );
  err_alloc_ibdev:
        return rc;
@@ -2413,7 +2423,6 @@ static void linda_remove ( struct pci_device *pci ) {
        unregister_ibdev ( ibdev );
        linda_fini_recv ( linda );
        linda_fini_send ( linda );
-       iounmap ( linda->regs );
        ibdev_put ( ibdev );
 }
 
index 44c7686..46a920a 100644 (file)
@@ -33,8 +33,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  */
 
-#define PSEUDOBIT_LITTLE_ENDIAN
-#include <ipxe/pseudobit.h>
+#define BITOPS_LITTLE_ENDIAN
+#include <ipxe/bitops.h>
 #include "qib_7220_regs.h"
 
 struct ib_device;
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_cmd.h b/roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_cmd.h
deleted file mode 100644 (file)
index e1e89b4..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef NODNIC_CMD_H_
-#define NODNIC_CMD_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_nodnic_data_structures.h"
-#include "../../mlx_utils/include/public/mlx_utils.h"
-#include "../../mlx_utils/include/public/mlx_pci_gw.h"
-
-mlx_status
-nodnic_cmd_read(
-                               IN nodnic_device_priv *device_priv,
-                               IN mlx_uint32 address,
-                               OUT mlx_pci_gw_buffer *buffer
-                               );
-
-mlx_status
-nodnic_cmd_write(
-                               IN nodnic_device_priv *device_priv,
-                               IN mlx_uint32 address,
-                               IN mlx_pci_gw_buffer buffer
-                               );
-
-#endif /* STUB_NODNIC_CMD_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_device.h b/roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_device.h
deleted file mode 100644 (file)
index b0cc7f7..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef NODNIC_DEVICE_H_
-#define NODNIC_DEVICE_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_nodnic_data_structures.h"
-
-#define NODIC_SUPPORTED_REVISION 1
-//Initialization segment
-#define NODNIC_CMDQ_PHY_ADDR_HIGH_OFFSET 0x10
-#define NODNIC_CMDQ_PHY_ADDR_LOW_OFFSET 0x14
-#define NODNIC_NIC_INTERFACE_OFFSET 0x14
-#define NODNIC_INITIALIZING_OFFSET 0x1fc
-#define NODNIC_NIC_INTERFACE_SUPPORTED_OFFSET 0x1fc
-#define NODNIC_LOCATION_OFFSET 0x240
-
-#define NODNIC_CMDQ_PHY_ADDR_LOW_MASK 0xFFFFE000
-#define NODNIC_NIC_INTERFACE_SUPPORTED_MASK 0x4000000
-
-#define NODNIC_NIC_INTERFACE_BIT 9
-#define NODNIC_DISABLE_INTERFACE_BIT 8
-#define NODNIC_NIC_INTERFACE_SUPPORTED_BIT 26
-#define NODNIC_INITIALIZING_BIT 31
-
-#define NODNIC_NIC_DISABLE_INT_OFFSET  0x100c
-
-//nodnic segment
-#define NODNIC_REVISION_OFFSET 0x0
-#define NODNIC_HARDWARE_FORMAT_OFFSET 0x0
-
-
-
-mlx_status
-nodnic_device_init(
-                               IN nodnic_device_priv *device_priv
-                               );
-
-mlx_status
-nodnic_device_teardown(
-                               IN nodnic_device_priv *device_priv
-                               );
-
-
-mlx_status
-nodnic_device_get_cap(
-                               IN nodnic_device_priv *device_priv
-                               );
-
-mlx_status
-nodnic_device_clear_int (
-                               IN nodnic_device_priv *device_priv
-                               );
-
-mlx_status
-nodnic_device_get_fw_version(
-                               IN nodnic_device_priv *device_priv,
-                               OUT mlx_uint16          *fw_ver_minor,
-                               OUT mlx_uint16          *fw_ver_sub_minor,
-                               OUT mlx_uint16          *fw_ver_major
-                               );
-#endif /* STUB_NODNIC_DEVICE_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_nodnic_data_structures.h b/roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_nodnic_data_structures.h
deleted file mode 100644 (file)
index f58213b..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-#ifndef NODNIC_NODNICDATASTRUCTURES_H_
-#define NODNIC_NODNICDATASTRUCTURES_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../mlx_utils/include/public/mlx_utils.h"
-
-/* todo: fix coding convention */
-#define NODNIC_MEMORY_ALIGN            0x1000
-
-#define NODNIC_MAX_MAC_FILTERS 5
-#define NODNIC_MAX_MGID_FILTERS 4
-
-typedef struct _nodnic_device_priv                             nodnic_device_priv;
-typedef struct _nodnic_port_priv                               nodnic_port_priv;
-typedef struct _nodnic_device_capabilites              nodnic_device_capabilites;
-typedef struct _nodnic_qp                                              nodnic_qp;
-typedef struct _nodnic_cq                                              nodnic_cq;
-typedef struct _nodnic_eq                                              nodnic_eq;
-
-/* NODNIC Port states
- * Bit 0 - port open/close
- * Bit 1 - port is [not] in disabling DMA
- * 0 - closed and not disabling DMA
- * 1 - opened and not disabling DMA
- * 3 - opened and disabling DMA
- */
-#define NODNIC_PORT_OPENED                     0b00000001
-#define NODNIC_PORT_DISABLING_DMA      0b00000010
-
-typedef enum {
-       ConnectX3 = 0,
-       Connectx4
-}nodnic_hardware_format;
-
-
-typedef enum {
-       NODNIC_QPT_SMI,
-       NODNIC_QPT_GSI,
-       NODNIC_QPT_UD,
-       NODNIC_QPT_RC,
-       NODNIC_QPT_ETH,
-}nodnic_queue_pair_type;
-typedef enum {
-       NODNIC_PORT_TYPE_IB = 0,
-       NODNIC_PORT_TYPE_ETH,
-       NODNIC_PORT_TYPE_UNKNOWN,
-}nodnic_port_type;
-
-
-#define RECV_WQE_SIZE 16
-#define NODNIC_WQBB_SIZE 64
-/** A nodnic send wqbb */
-struct nodnic_send_wqbb {
-       mlx_uint8 force_align[NODNIC_WQBB_SIZE];
-};
-struct nodnic_ring {
-       mlx_uint32 offset;
-       /** Work queue entries */
-       /* TODO: add to memory entity */
-       mlx_physical_address wqe_physical;
-       mlx_void *map;
-       /** Size of work queue */
-       mlx_size wq_size;
-       /** Next work queue entry index
-        *
-        * This is the index of the next entry to be filled (i.e. the
-        * first empty entry).  This value is not bounded by num_wqes;
-        * users must logical-AND with (num_wqes-1) to generate an
-        * array index.
-        */
-       mlx_uint32 num_wqes;
-       mlx_uint32 qpn;
-       mlx_uint32 next_idx;
-       mlx_uint32      ring_pi;
-};
-
-struct nodnic_send_ring{
-       struct nodnic_ring nodnic_ring;
-       struct nodnic_send_wqbb *wqe_virt;
-};
-
-
-struct nodnic_recv_ring{
-       struct nodnic_ring nodnic_ring;
-       void *wqe_virt;
-};
-struct _nodnic_qp{
-       nodnic_queue_pair_type  type;
-       struct nodnic_send_ring         send;
-       struct nodnic_recv_ring         receive;
-};
-
-struct _nodnic_cq{
-       /** cq entries */
-       mlx_void *cq_virt;
-       mlx_physical_address cq_physical;
-       mlx_void *map;
-       /** cq */
-       mlx_size cq_size;
-};
-
-struct _nodnic_eq{
-       mlx_void *eq_virt;
-       mlx_physical_address eq_physical;
-       mlx_void *map;
-       mlx_size eq_size;
-};
-struct _nodnic_device_capabilites{
-       mlx_boolean                                     support_mac_filters;
-       mlx_boolean                                     support_promisc_filter;
-       mlx_boolean                                     support_promisc_multicast_filter;
-       mlx_uint8                                       log_working_buffer_size;
-       mlx_uint8                                       log_pkey_table_size;
-       mlx_boolean                                     num_ports; // 0 - single port, 1 - dual port
-       mlx_uint8                                       log_max_ring_size;
-#ifdef DEVICE_CX3
-       mlx_uint8                                       crspace_doorbells;
-#endif
-};
-
-#ifdef DEVICE_CX3
-/* This is the structure of the data in the scratchpad
- * Read/Write data from/to its field using PCI accesses only */
-typedef struct _nodnic_port_data_flow_gw nodnic_port_data_flow_gw;
-struct _nodnic_port_data_flow_gw {
-       mlx_uint32      send_doorbell;
-       mlx_uint32      recv_doorbell;
-       mlx_uint32      reserved2[2];
-       mlx_uint32      armcq_cq_ci_dword;
-       mlx_uint32      dma_en;
-} __attribute__ ((packed));
-#endif
-
-struct _nodnic_device_priv{
-       mlx_boolean                                     is_initiailzied;
-       mlx_utils                                       *utils;
-
-       //nodnic structure offset in init segment
-       mlx_uint32                                      device_offset;
-
-       nodnic_device_capabilites       device_cap;
-
-       mlx_uint8                                       nodnic_revision;
-       nodnic_hardware_format          hardware_format;
-       mlx_uint32                                      pd;
-       mlx_uint32                                      lkey;
-       mlx_uint64                                      device_guid;
-       nodnic_port_priv                        *ports;
-#ifdef DEVICE_CX3
-       mlx_void                                        *crspace_clear_int;
-#endif
-};
-
-struct _nodnic_port_priv{
-       nodnic_device_priv              *device;
-       mlx_uint32                              port_offset;
-       mlx_uint8                               port_state;
-       mlx_boolean                             network_state;
-       mlx_boolean                             dma_state;
-       nodnic_port_type                port_type;
-       mlx_uint8                               port_num;
-       nodnic_eq                               eq;
-       mlx_mac_address                 mac_filters[5];
-       mlx_status (*send_doorbell)(
-                       IN nodnic_port_priv             *port_priv,
-                       IN struct nodnic_ring   *ring,
-                       IN mlx_uint16 index);
-       mlx_status (*recv_doorbell)(
-                       IN nodnic_port_priv             *port_priv,
-                       IN struct nodnic_ring   *ring,
-                       IN mlx_uint16 index);
-       mlx_status (*set_dma)(
-                       IN nodnic_port_priv             *port_priv,
-                       IN mlx_boolean                  value);
-#ifdef DEVICE_CX3
-       nodnic_port_data_flow_gw *data_flow_gw;
-#endif
-};
-
-
-#endif /* STUB_NODNIC_NODNICDATASTRUCTURES_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_port.h b/roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_port.h
deleted file mode 100644 (file)
index 4fd96a6..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-#ifndef NODNIC_PORT_H_
-#define NODNIC_PORT_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_nodnic_data_structures.h"
-
-#define NODNIC_PORT_MAC_FILTERS_OFFSET 0x10
-
-typedef enum {
-       nodnic_port_option_link_type = 0,
-       nodnic_port_option_mac_low,
-       nodnic_port_option_mac_high,
-       nodnic_port_option_log_cq_size,
-       nodnic_port_option_reset_needed,
-       nodnic_port_option_mac_filters_en,
-       nodnic_port_option_port_state,
-       nodnic_port_option_network_en,
-       nodnic_port_option_dma_en,
-       nodnic_port_option_eq_addr_low,
-       nodnic_port_option_eq_addr_high,
-       nodnic_port_option_cq_addr_low,
-       nodnic_port_option_cq_addr_high,
-       nodnic_port_option_port_management_change_event,
-       nodnic_port_option_port_promisc_en,
-       nodnic_port_option_arm_cq,
-       nodnic_port_option_port_promisc_multicast_en,
-#ifdef DEVICE_CX3
-       nodnic_port_option_crspace_en,
-#endif
-}nodnic_port_option;
-
-struct nodnic_port_data_entry{
-       nodnic_port_option      option;
-       mlx_uint32                      offset;
-       mlx_uint8                       align;
-       mlx_uint32                      mask;
-};
-
-struct nodnic_qp_data_entry{
-       nodnic_queue_pair_type  type;
-       mlx_uint32                      send_offset;
-       mlx_uint32                      recv_offset;
-};
-
-
-typedef enum {
-       nodnic_port_state_down = 0,
-       nodnic_port_state_initialize,
-       nodnic_port_state_armed,
-       nodnic_port_state_active,
-}nodnic_port_state;
-
-mlx_status
-nodnic_port_get_state(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       OUT nodnic_port_state                   *state
-                                       );
-
-mlx_status
-nodnic_port_get_type(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       OUT nodnic_port_type    *type
-                                       );
-
-mlx_status
-nodnic_port_query(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       IN  nodnic_port_option          option,
-                                       OUT     mlx_uint32                              *out
-                                       );
-
-mlx_status
-nodnic_port_set(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       IN  nodnic_port_option          option,
-                                       IN      mlx_uint32                              in
-                                       );
-
-mlx_status
-nodnic_port_create_cq(
-                                       IN nodnic_port_priv     *port_priv,
-                                       IN mlx_size     cq_size,
-                                       OUT nodnic_cq   **cq
-                                       );
-
-mlx_status
-nodnic_port_destroy_cq(
-                                       IN nodnic_port_priv     *port_priv,
-                                       IN nodnic_cq    *cq
-                                       );
-
-mlx_status
-nodnic_port_create_qp(
-                                       IN nodnic_port_priv     *port_priv,
-                                       IN nodnic_queue_pair_type       type,
-                                       IN mlx_size     send_wq_size,
-                                       IN mlx_uint32 send_wqe_num,
-                                       IN mlx_size     receive_wq_size,
-                                       IN mlx_uint32 recv_wqe_num,
-                                       OUT nodnic_qp   **qp
-                                       );
-
-mlx_status
-nodnic_port_destroy_qp(
-                                       IN nodnic_port_priv     *port_priv,
-                                       IN nodnic_queue_pair_type       type,
-                                       IN nodnic_qp    *qp
-                                       );
-mlx_status
-nodnic_port_get_qpn(
-                       IN nodnic_port_priv     *port_priv,
-                       IN struct nodnic_ring *ring,
-                       OUT mlx_uint32 *qpn
-                       );
-mlx_status
-nodnic_port_update_ring_doorbell(
-                                       IN nodnic_port_priv     *port_priv,
-                                       IN struct nodnic_ring *ring,
-                                       IN mlx_uint16 index
-                                       );
-mlx_status
-nodnic_port_get_cq_size(
-               IN nodnic_port_priv     *port_priv,
-               OUT mlx_uint64 *cq_size
-               );
-
-mlx_status
-nodnic_port_allocate_eq(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       IN  mlx_uint8                   log_eq_size
-                                       );
-mlx_status
-nodnic_port_free_eq(
-                                       IN  nodnic_port_priv    *port_priv
-                                       );
-
-mlx_status
-nodnic_port_add_mac_filter(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       IN  mlx_mac_address     mac
-                                       );
-
-mlx_status
-nodnic_port_remove_mac_filter(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       IN  mlx_mac_address     mac
-                                       );
-mlx_status
-nodnic_port_add_mgid_filter(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       IN  mlx_mac_address     mac
-                                       );
-
-mlx_status
-nodnic_port_remove_mgid_filter(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       IN  mlx_mac_address     mac
-                                       );
-mlx_status
-nodnic_port_thin_init(
-               IN nodnic_device_priv   *device_priv,
-               IN nodnic_port_priv             *port_priv,
-               IN mlx_uint8                    port_index
-               );
-
-mlx_status
-nodnic_port_set_promisc(
-               IN nodnic_port_priv             *port_priv,
-               IN mlx_boolean                  value
-               );
-
-mlx_status
-nodnic_port_set_promisc_multicast(
-               IN nodnic_port_priv             *port_priv,
-               IN mlx_boolean                  value
-               );
-
-mlx_status
-nodnic_port_init(
-               IN nodnic_port_priv             *port_priv
-               );
-
-mlx_status
-nodnic_port_close(
-               IN nodnic_port_priv             *port_priv
-               );
-
-mlx_status
-nodnic_port_enable_dma(
-               IN nodnic_port_priv             *port_priv
-               );
-
-mlx_status
-nodnic_port_disable_dma(
-               IN nodnic_port_priv             *port_priv
-               );
-
-mlx_status
-nodnic_port_read_reset_needed(
-                                               IN nodnic_port_priv             *port_priv,
-                                               OUT mlx_boolean                 *reset_needed
-                                               );
-
-mlx_status
-nodnic_port_read_port_management_change_event(
-                                               IN nodnic_port_priv             *port_priv,
-                                               OUT mlx_boolean                 *change_event
-                                               );
-#endif /* STUB_NODNIC_PORT_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_cmd.c b/roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_cmd.c
deleted file mode 100644 (file)
index 69f8535..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../include/mlx_cmd.h"
-#include "../../mlx_utils/include/public/mlx_pci_gw.h"
-#include "../../mlx_utils/include/public/mlx_bail.h"
-#include "../../mlx_utils/include/public/mlx_pci.h"
-#include "../../mlx_utils/include/public/mlx_logging.h"
-
-mlx_status
-nodnic_cmd_read(
-                               IN nodnic_device_priv *device_priv,
-                               IN mlx_uint32 address,
-                               OUT mlx_pci_gw_buffer *buffer
-                               )
-{
-       mlx_status              status = MLX_SUCCESS;
-       mlx_utils               *utils = NULL;
-
-       if ( device_priv == NULL || buffer == NULL ) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       utils = device_priv->utils;
-
-       status = mlx_pci_gw_read(utils, PCI_GW_SPACE_NODNIC, address, buffer);
-       MLX_CHECK_STATUS(device_priv, status, read_error,"mlx_pci_gw_read failed");
-
-read_error:
-bad_param:
-       return status;
-}
-
-mlx_status
-nodnic_cmd_write(
-                               IN nodnic_device_priv *device_priv,
-                               IN mlx_uint32 address,
-                               IN mlx_pci_gw_buffer buffer
-                               )
-{
-       mlx_status              status = MLX_SUCCESS;
-       mlx_utils               *utils = NULL;
-
-
-       if ( device_priv == NULL ) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       utils = device_priv->utils;
-
-
-       status = mlx_pci_gw_write(utils, PCI_GW_SPACE_NODNIC, address, buffer);
-       MLX_CHECK_STATUS(device_priv, status, write_error,"mlx_pci_gw_write failed");
-write_error:
-bad_param:
-       return status;
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_device.c b/roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_device.c
deleted file mode 100644 (file)
index 4acc94f..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../include/mlx_device.h"
-#include "../include/mlx_cmd.h"
-#include "../../mlx_utils/include/public/mlx_bail.h"
-#include "../../mlx_utils/include/public/mlx_pci.h"
-#include "../../mlx_utils/include/public/mlx_memory.h"
-#include "../../mlx_utils/include/public/mlx_logging.h"
-
-#define CHECK_BIT(field, offset)       (((field) & ((mlx_uint32)1 << (offset))) != 0)
-
-static
-mlx_status
-check_nodnic_interface_supported(
-                                                       IN nodnic_device_priv* device_priv,
-                                                       OUT mlx_boolean *out
-                                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32      output = 0;
-       status = nodnic_cmd_read(device_priv, NODNIC_NIC_INTERFACE_SUPPORTED_OFFSET,
-                       &output);
-       MLX_FATAL_CHECK_STATUS(status, read_error, "failed to read nic_interface_supported");
-       *out = CHECK_BIT(output, NODNIC_NIC_INTERFACE_SUPPORTED_BIT);
-read_error:
-       return status;
-}
-
-static
-mlx_status
-wait_for_device_initialization(
-                                                       IN nodnic_device_priv* device_priv
-                                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint8 try = 0;
-       mlx_uint32                      buffer = 0;
-
-#define CHECK_DEVICE_INIT_TRIES 10
-       for( ; try < CHECK_DEVICE_INIT_TRIES ; try++){
-               status = nodnic_cmd_read(device_priv, NODNIC_INITIALIZING_OFFSET, &buffer);
-               MLX_CHECK_STATUS(device_priv, status, read_error, "failed to read initializing");
-               if( !CHECK_BIT(buffer, NODNIC_INITIALIZING_BIT)){
-                       goto init_done;
-               }
-               mlx_utils_delay_in_ms(100);
-       }
-       status = MLX_FAILED;
-read_error:
-init_done:
-       return status;
-}
-
-static
-mlx_status
-disable_nodnic_inteface(
-                                               IN nodnic_device_priv *device_priv
-                                               )
-{
-       mlx_status                      status = MLX_SUCCESS;
-       mlx_uint32                      buffer = 0;
-
-       buffer = (1 << NODNIC_DISABLE_INTERFACE_BIT);
-       status = nodnic_cmd_write(device_priv, NODNIC_CMDQ_PHY_ADDR_LOW_OFFSET, buffer);
-       MLX_FATAL_CHECK_STATUS(status, write_err, "failed to write cmdq_phy_addr + nic_interface");
-
-       status = wait_for_device_initialization(device_priv);
-       MLX_FATAL_CHECK_STATUS(status, init_err, "failed to initialize device");
-init_err:
-write_err:
-       return status;
-}
-static
-mlx_status
-nodnic_device_start_nodnic(
-                               IN nodnic_device_priv *device_priv
-                               )
-{
-       mlx_status                      status = MLX_SUCCESS;
-       mlx_uint32                      buffer = 0;
-       mlx_boolean                     nodnic_supported = 0;
-
-       status = wait_for_device_initialization(device_priv);
-       MLX_FATAL_CHECK_STATUS(status, wait_for_fw_err, "failed to initialize device");
-
-       status = check_nodnic_interface_supported(device_priv, &nodnic_supported);
-       MLX_FATAL_CHECK_STATUS(status, read_err,"failed to check nic_interface_supported");
-
-       if(     nodnic_supported == 0 ){
-               status = MLX_UNSUPPORTED;
-               goto nodnic_unsupported;
-       }
-       buffer =  (1 << NODNIC_NIC_INTERFACE_BIT);
-       status = nodnic_cmd_write(device_priv, NODNIC_NIC_INTERFACE_OFFSET, buffer);
-       MLX_FATAL_CHECK_STATUS(status, write_err, "failed to write cmdq_phy_addr + nic_interface");
-
-       status = wait_for_device_initialization(device_priv);
-       MLX_FATAL_CHECK_STATUS(status, init_err, "failed to initialize device");
-init_err:
-read_err:
-write_err:
-nodnic_unsupported:
-wait_for_fw_err:
-       return status;
-}
-
-static
-mlx_status
-nodnic_device_get_nodnic_data(
-                               IN nodnic_device_priv *device_priv
-                               )
-{
-       mlx_status                      status = MLX_SUCCESS;
-       mlx_uint32                      buffer = 0;
-
-       status = nodnic_cmd_read(device_priv, NODNIC_LOCATION_OFFSET, &device_priv->device_offset);
-       MLX_FATAL_CHECK_STATUS(status, nodnic_offset_read_err, "failed to read nodnic offset");
-
-       status = nodnic_cmd_read(device_priv,
-                       device_priv->device_offset + NODNIC_REVISION_OFFSET, &buffer);
-       MLX_FATAL_CHECK_STATUS(status, nodnic_revision_read_err, "failed to read nodnic revision");
-
-       device_priv->nodnic_revision = (buffer >> 24) & 0xFF;
-       if( device_priv->nodnic_revision != NODIC_SUPPORTED_REVISION ){
-               MLX_DEBUG_ERROR(device_priv, "nodnic revision not supported\n");
-               status = MLX_UNSUPPORTED;
-               goto unsupported_revision;
-       }
-
-       status = nodnic_cmd_read(device_priv,
-                       device_priv->device_offset + NODNIC_HARDWARE_FORMAT_OFFSET, &buffer);
-       MLX_FATAL_CHECK_STATUS(status, nodnic_hardware_format_read_err, "failed to read nodnic revision");
-       device_priv->hardware_format = (buffer >> 16) & 0xFF;
-
-       return status;
-
-unsupported_revision:
-nodnic_hardware_format_read_err:
-nodnic_offset_read_err:
-nodnic_revision_read_err:
-       disable_nodnic_inteface(device_priv);
-       return status;
-}
-
-mlx_status
-nodnic_device_clear_int (
-                               IN nodnic_device_priv *device_priv
-                               )
-{
-       mlx_status                      status = MLX_SUCCESS;
-       mlx_uint32                      disable = 1;
-#ifndef DEVICE_CX3
-       status = nodnic_cmd_write(device_priv, NODNIC_NIC_DISABLE_INT_OFFSET, disable);
-       MLX_CHECK_STATUS(device_priv, status, clear_int_done, "failed writing to disable_bit");
-#else
-       mlx_utils *utils = device_priv->utils;
-       mlx_uint64 clear_int = (mlx_uint64)(device_priv->crspace_clear_int);
-       mlx_uint32 swapped = 0;
-
-       if (device_priv->device_cap.crspace_doorbells == 0) {
-               status = nodnic_cmd_write(device_priv, NODNIC_NIC_DISABLE_INT_OFFSET, disable);
-               MLX_CHECK_STATUS(device_priv, status, clear_int_done, "failed writing to disable_bit");
-       } else {
-               /* Write the new index and update FW that new data was submitted */
-               disable = 0x80000000;
-               mlx_memory_cpu_to_be32(utils, disable, &swapped);
-               mlx_pci_mem_write (utils, MlxPciWidthUint32, 0, clear_int, 1, &swapped);
-               mlx_pci_mem_read (utils, MlxPciWidthUint32, 0, clear_int, 1, &swapped);
-       }
-#endif
-clear_int_done:
-       return status;
-}
-
-mlx_status
-nodnic_device_init(
-                               IN nodnic_device_priv *device_priv
-                               )
-{
-       mlx_status                      status = MLX_SUCCESS;
-
-       if( device_priv == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto parm_err;
-       }
-       status = nodnic_device_start_nodnic(device_priv);
-       MLX_FATAL_CHECK_STATUS(status, start_nodnic_err, "nodnic_device_start_nodnic failed");
-
-       status = nodnic_device_get_nodnic_data(device_priv);
-       MLX_FATAL_CHECK_STATUS(status, data_err, "nodnic_device_get_nodnic_data failed");
-       return status;
-data_err:
-start_nodnic_err:
-parm_err:
-       return status;
-}
-
-mlx_status
-nodnic_device_teardown(
-                               IN nodnic_device_priv *device_priv
-                               )
-{
-       mlx_status                      status = MLX_SUCCESS;
-       status = disable_nodnic_inteface(device_priv);
-       MLX_FATAL_CHECK_STATUS(status, disable_failed, "failed to disable nodnic interface");
-disable_failed:
-       return status;
-}
-
-mlx_status
-nodnic_device_get_cap(
-                               IN nodnic_device_priv *device_priv
-                               )
-{
-       mlx_status                                      status = MLX_SUCCESS;
-       nodnic_device_capabilites       *device_cap = NULL;
-       mlx_uint32                                      buffer = 0;
-       mlx_uint64                                      guid_l = 0;
-       mlx_uint64                                      guid_h = 0;
-       if( device_priv == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto parm_err;
-       }
-
-       device_cap = &device_priv->device_cap;
-
-       //get device capabilities
-       status = nodnic_cmd_read(device_priv, device_priv->device_offset + 0x0, &buffer);
-       MLX_FATAL_CHECK_STATUS(status, read_err, "failed to read nodnic first dword");
-
-#define NODNIC_DEVICE_SUPPORT_MAC_FILTERS_OFFSET 15
-#define NODNIC_DEVICE_SUPPORT_PROMISC_FILTER_OFFSET 14
-#define NODNIC_DEVICE_SUPPORT_PROMISC_MULT_FILTER_OFFSET 13
-#define NODNIC_DEVICE_LOG_WORKING_BUFFER_SIZE_OFFSET 8
-#define NODNIC_DEVICE_LOG_WORKING_BUFFER_SIZE_MASK 0x7
-#define NODNIC_DEVICE_LOG_PKEY_TABLE_SIZE_OFFSET 4
-#define NODNIC_DEVICE_LOG_PKEY_TABLE_SIZE_MASK 0xF
-#define NODNIC_DEVICE_NUM_PORTS_OFFSET 0
-       device_cap->support_mac_filters = CHECK_BIT(buffer, NODNIC_DEVICE_SUPPORT_MAC_FILTERS_OFFSET);
-
-       device_cap->support_promisc_filter = CHECK_BIT(buffer, NODNIC_DEVICE_SUPPORT_PROMISC_FILTER_OFFSET);
-
-       device_cap->support_promisc_multicast_filter = CHECK_BIT(buffer, NODNIC_DEVICE_SUPPORT_PROMISC_MULT_FILTER_OFFSET);
-
-       device_cap->log_working_buffer_size =
-                       (buffer >> NODNIC_DEVICE_LOG_WORKING_BUFFER_SIZE_OFFSET) & NODNIC_DEVICE_LOG_WORKING_BUFFER_SIZE_MASK;
-
-       device_cap->log_pkey_table_size =
-                       (buffer >> NODNIC_DEVICE_LOG_PKEY_TABLE_SIZE_OFFSET) & NODNIC_DEVICE_LOG_PKEY_TABLE_SIZE_MASK;
-
-       device_cap->num_ports = CHECK_BIT(buffer, NODNIC_DEVICE_NUM_PORTS_OFFSET) + 1;
-
-#ifdef DEVICE_CX3
-#define NODNIC_DEVICE_CRSPACE_DB_OFFSET 12
-       device_cap->crspace_doorbells = CHECK_BIT(buffer, NODNIC_DEVICE_CRSPACE_DB_OFFSET);
-#endif
-
-       status = nodnic_cmd_read(device_priv, device_priv->device_offset + 0x4, &buffer);
-       MLX_FATAL_CHECK_STATUS(status, read_err, "failed to read nodnic second dword");
-
-#define NODNIC_DEVICE_LOG_MAX_RING_SIZE_OFFSET 24
-#define NODNIC_DEVICE_LOG_MAX_RING_SIZE_MASK 0x3F
-#define NODNIC_DEVICE_PD_MASK 0xFFFFFF
-       device_cap->log_max_ring_size =
-                       (buffer >> NODNIC_DEVICE_LOG_MAX_RING_SIZE_OFFSET) & NODNIC_DEVICE_LOG_MAX_RING_SIZE_MASK;
-
-       //get device magic numbers
-       device_priv->pd = buffer & NODNIC_DEVICE_PD_MASK;
-
-       status = nodnic_cmd_read(device_priv, device_priv->device_offset + 0x8, &buffer);
-       MLX_FATAL_CHECK_STATUS(status, read_err, "failed to read nodnic third dword");
-       device_priv->lkey = buffer;
-
-#ifdef DEVICE_CX3
-       if ( device_cap->crspace_doorbells ) {
-               status = nodnic_cmd_read(device_priv, device_priv->device_offset + 0x18, &buffer);
-               MLX_FATAL_CHECK_STATUS(status, read_err, "failed to read nodnic_crspace_clear_int address");
-               device_priv->crspace_clear_int = device_priv->utils->config + buffer;
-       }
-#endif
-
-       status = nodnic_cmd_read(device_priv, device_priv->device_offset + 0x10, (mlx_uint32*)&guid_h);
-       MLX_FATAL_CHECK_STATUS(status, read_err, "failed to read nodnic guid_h");
-       status = nodnic_cmd_read(device_priv, device_priv->device_offset + 0x14, (mlx_uint32*)&guid_l);
-       MLX_FATAL_CHECK_STATUS(status, read_err, "failed to read nodnic guid_l");
-       device_priv->device_guid = guid_l | (guid_h << 32);
-read_err:
-parm_err:
-       return status;
-}
-
-mlx_status
-nodnic_device_get_fw_version(
-                               IN nodnic_device_priv *device_priv,
-                               OUT mlx_uint16          *fw_ver_minor,
-                               OUT mlx_uint16          *fw_ver_sub_minor,
-                               OUT mlx_uint16          *fw_ver_major
-                               ){
-       mlx_status              status = MLX_SUCCESS;
-       mlx_uint32              buffer = 0;
-
-       if( device_priv == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto parm_err;
-       }
-
-       status = nodnic_cmd_read(device_priv, 0x0, &buffer);
-       MLX_CHECK_STATUS(device_priv, status, read_err, "failed to read fw revision major and minor");
-
-       *fw_ver_minor = (mlx_uint16)(buffer >> 16);
-       *fw_ver_major = (mlx_uint16)buffer;
-
-       status = nodnic_cmd_read(device_priv, 0x4, &buffer);
-       MLX_CHECK_STATUS(device_priv, status, read_err, "failed to read fw revision sub minor");
-
-       *fw_ver_sub_minor = (mlx_uint16)buffer;
-read_err:
-parm_err:
-       return status;
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_port.c b/roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_port.c
deleted file mode 100644 (file)
index a7afdab..0000000
+++ /dev/null
@@ -1,1038 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../include/mlx_port.h"
-#include "../include/mlx_cmd.h"
-#include "../../mlx_utils/include/public/mlx_memory.h"
-#include "../../mlx_utils/include/public/mlx_pci.h"
-#include "../../mlx_utils/include/public/mlx_bail.h"
-
-#define PortDataEntry( _option, _offset, _align, _mask) { \
-  .option = _option,                     \
-  .offset = _offset,                   \
-  .align = _align,                  \
-  .mask = _mask,                    \
-  }
-
-#define QpDataEntry( _type, _send_offset, _recv_offset) { \
-  .type = _type,                     \
-  .send_offset = _send_offset,                   \
-  .recv_offset = _recv_offset,                  \
-  }
-
-
-struct nodnic_port_data_entry nodnic_port_data_table[] = {
-               PortDataEntry(nodnic_port_option_link_type, 0x0, 4, 0x1),
-               PortDataEntry(nodnic_port_option_mac_low, 0xc, 0, 0xFFFFFFFF),
-               PortDataEntry(nodnic_port_option_mac_high, 0x8, 0, 0xFFFF),
-               PortDataEntry(nodnic_port_option_log_cq_size, 0x6c, 0, 0x3F),
-               PortDataEntry(nodnic_port_option_reset_needed, 0x0, 31, 0x1),
-               PortDataEntry(nodnic_port_option_mac_filters_en, 0x4, 0, 0x1F),
-               PortDataEntry(nodnic_port_option_port_state, 0x0, 0, 0xF),
-               PortDataEntry(nodnic_port_option_network_en, 0x4, 31, 0x1),
-               PortDataEntry(nodnic_port_option_dma_en, 0x4, 30, 0x1),
-               PortDataEntry(nodnic_port_option_eq_addr_low, 0x74, 0, 0xFFFFFFFF),
-               PortDataEntry(nodnic_port_option_eq_addr_high, 0x70, 0, 0xFFFFFFFF),
-               PortDataEntry(nodnic_port_option_cq_addr_low, 0x6c, 12, 0xFFFFF),
-               PortDataEntry(nodnic_port_option_cq_addr_high, 0x68, 0, 0xFFFFFFFF),
-               PortDataEntry(nodnic_port_option_port_management_change_event, 0x0, 30, 0x1),
-               PortDataEntry(nodnic_port_option_port_promisc_en, 0x4, 29, 0x1),
-               PortDataEntry(nodnic_port_option_arm_cq, 0x78, 8, 0xffff),
-               PortDataEntry(nodnic_port_option_port_promisc_multicast_en, 0x4, 28, 0x1),
-#ifdef DEVICE_CX3
-               PortDataEntry(nodnic_port_option_crspace_en, 0x4, 27, 0x1),
-#endif
-};
-
-#define MAX_QP_DATA_ENTRIES 5
-struct nodnic_qp_data_entry nodnic_qp_data_teable[MAX_QP_DATA_ENTRIES] = {
-               QpDataEntry(NODNIC_QPT_SMI, 0, 0),
-               QpDataEntry(NODNIC_QPT_GSI, 0, 0),
-               QpDataEntry(NODNIC_QPT_UD, 0, 0),
-               QpDataEntry(NODNIC_QPT_RC, 0, 0),
-               QpDataEntry(NODNIC_QPT_ETH, 0x80, 0xC0),
-};
-
-#define MAX_NODNIC_PORTS 2
-int nodnic_port_offset_table[MAX_NODNIC_PORTS] = {
-       0x100, //port 1 offset
-       0x280, //port 1 offset
-};
-
-mlx_status
-nodnic_port_get_state(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       OUT nodnic_port_state                   *state
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 out = 0;
-
-       status = nodnic_port_query(port_priv,
-                       nodnic_port_option_port_state, &out);
-       MLX_CHECK_STATUS(port_priv->device, status, query_err,
-                       "nodnic_port_query failed");
-       *state = (nodnic_port_state)out;
-query_err:
-       return status;
-}
-mlx_status
-nodnic_port_get_type(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       OUT nodnic_port_type    *type
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 out = 0;
-
-       if ( port_priv->port_type == NODNIC_PORT_TYPE_UNKNOWN){
-               status = nodnic_port_query(port_priv,
-                               nodnic_port_option_link_type, &out);
-               MLX_FATAL_CHECK_STATUS(status, query_err,
-                               "nodnic_port_query failed");
-               port_priv->port_type = (nodnic_port_type)out;
-       }
-       *type = port_priv->port_type;
-query_err:
-       return status;
-}
-
-mlx_status
-nodnic_port_query(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       IN  nodnic_port_option          option,
-                                       OUT     mlx_uint32                              *out
-                                       )
-{
-       mlx_status                              status = MLX_SUCCESS;
-       nodnic_device_priv              *device_priv = NULL;
-       struct nodnic_port_data_entry *data_entry;
-       mlx_uint32                              buffer = 0;
-       if( port_priv == NULL || out == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_parm;
-       }
-       device_priv = port_priv->device;
-
-       data_entry = &nodnic_port_data_table[option];
-
-       status = nodnic_cmd_read(device_priv,
-                       port_priv->port_offset + data_entry->offset , &buffer);
-       MLX_CHECK_STATUS(device_priv, status, read_err,
-                       "nodnic_cmd_read failed");
-       *out = (buffer >> data_entry->align) & data_entry->mask;
-read_err:
-invalid_parm:
-       return status;
-}
-
-mlx_status
-nodnic_port_set(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       IN  nodnic_port_option          option,
-                                       IN      mlx_uint32                              in
-                                       )
-{
-       mlx_status                              status = MLX_SUCCESS;
-       nodnic_device_priv              *device_priv = NULL;
-       struct nodnic_port_data_entry *data_entry;
-       mlx_uint32                              buffer = 0;
-
-       if( port_priv == NULL ){
-               MLX_DEBUG_FATAL_ERROR("port_priv is NULL\n");
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_parm;
-       }
-       device_priv = port_priv->device;
-       data_entry = &nodnic_port_data_table[option];
-
-       if( in > data_entry->mask ){
-               MLX_DEBUG_FATAL_ERROR("in > data_entry->mask (%d > %d)\n",
-                               in, data_entry->mask);
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_parm;
-       }
-       status = nodnic_cmd_read(device_priv,
-                       port_priv->port_offset + data_entry->offset, &buffer);
-       MLX_FATAL_CHECK_STATUS(status, read_err,
-                       "nodnic_cmd_read failed");
-       buffer = buffer & ~(data_entry->mask << data_entry->align);
-       buffer = buffer | (in << data_entry->align);
-       status = nodnic_cmd_write(device_priv,
-                       port_priv->port_offset + data_entry->offset, buffer);
-       MLX_FATAL_CHECK_STATUS(status, write_err,
-                       "nodnic_cmd_write failed");
-write_err:
-read_err:
-invalid_parm:
-       return status;
-}
-
-mlx_status
-nodnic_port_read_reset_needed(
-                                               IN nodnic_port_priv             *port_priv,
-                                               OUT mlx_boolean                 *reset_needed
-                                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 out = 0;
-       status = nodnic_port_query(port_priv,
-                       nodnic_port_option_reset_needed, &out);
-       MLX_CHECK_STATUS(port_priv->device, status, query_err,
-                       "nodnic_port_query failed");
-       *reset_needed = (mlx_boolean)out;
-query_err:
-       return status;
-}
-
-mlx_status
-nodnic_port_read_port_management_change_event(
-                                               IN nodnic_port_priv             *port_priv,
-                                               OUT mlx_boolean                 *change_event
-                                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 out = 0;
-       status = nodnic_port_query(port_priv,
-                       nodnic_port_option_port_management_change_event, &out);
-       MLX_CHECK_STATUS(port_priv->device, status, query_err,
-                       "nodnic_port_query failed");
-       *change_event = (mlx_boolean)out;
-query_err:
-       return status;
-}
-
-mlx_status
-nodnic_port_create_cq(
-                                       IN nodnic_port_priv     *port_priv,
-                                       IN mlx_size     cq_size,
-                                       OUT nodnic_cq   **cq
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       nodnic_device_priv *device_priv = NULL;
-       mlx_uint64 address = 0;
-       if( port_priv == NULL || cq == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_parm;
-       }
-
-       device_priv =  port_priv->device;
-
-       status = mlx_memory_zalloc(device_priv->utils,
-                               sizeof(nodnic_cq),(mlx_void **)cq);
-       MLX_FATAL_CHECK_STATUS(status, alloc_err,
-                       "cq priv allocation error");
-
-       (*cq)->cq_size = cq_size;
-       status = mlx_memory_alloc_dma(device_priv->utils,
-                       (*cq)->cq_size, NODNIC_MEMORY_ALIGN,
-                               &(*cq)->cq_virt);
-       MLX_FATAL_CHECK_STATUS(status, dma_alloc_err,
-                               "cq allocation error");
-
-       status = mlx_memory_map_dma(device_priv->utils,
-                                               (*cq)->cq_virt,
-                                               (*cq)->cq_size,
-                                               &(*cq)->cq_physical,
-                                               &(*cq)->map);
-       MLX_FATAL_CHECK_STATUS(status, cq_map_err,
-                               "cq map error");
-
-       /* update cq address */
-#define NODIC_CQ_ADDR_HIGH 0x68
-#define NODIC_CQ_ADDR_LOW 0x6c
-       address = (mlx_uint64)(*cq)->cq_physical;
-       nodnic_port_set(port_priv, nodnic_port_option_cq_addr_low,
-                       (mlx_uint32)(address >> 12));
-       address = address >> 32;
-       nodnic_port_set(port_priv, nodnic_port_option_cq_addr_high,
-                               (mlx_uint32)address);
-
-       return status;
-       mlx_memory_ummap_dma(device_priv->utils, (*cq)->map);
-cq_map_err:
-       mlx_memory_free_dma(device_priv->utils, (*cq)->cq_size,
-                       (void **)&((*cq)->cq_virt));
-dma_alloc_err:
-       mlx_memory_free(device_priv->utils, (void **)cq);
-alloc_err:
-invalid_parm:
-       return status;
-}
-
-mlx_status
-nodnic_port_destroy_cq(
-                                       IN nodnic_port_priv     *port_priv,
-                                       IN nodnic_cq    *cq
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       nodnic_device_priv *device_priv = NULL;
-
-       if( port_priv == NULL || cq == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_parm;
-       }
-       device_priv =  port_priv->device;
-
-       mlx_memory_ummap_dma(device_priv->utils, cq->map);
-
-       mlx_memory_free_dma(device_priv->utils, cq->cq_size,
-                       (void **)&(cq->cq_virt));
-
-       mlx_memory_free(device_priv->utils, (void **)&cq);
-invalid_parm:
-       return status;
-}
-mlx_status
-nodnic_port_create_qp(
-                                       IN nodnic_port_priv     *port_priv,
-                                       IN nodnic_queue_pair_type       type,
-                                       IN mlx_size     send_wq_size,
-                                       IN mlx_uint32 send_wqe_num,
-                                       IN mlx_size     receive_wq_size,
-                                       IN mlx_uint32 recv_wqe_num,
-                                       OUT nodnic_qp   **qp
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       nodnic_device_priv *device_priv = NULL;
-       mlx_uint32 max_ring_size = 0;
-       mlx_uint64 address = 0;
-       mlx_uint32 log_size = 0;
-       if( port_priv == NULL || qp == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_parm;
-       }
-
-       device_priv =  port_priv->device;
-       max_ring_size = (1 << device_priv->device_cap.log_max_ring_size);
-       if( send_wq_size > max_ring_size ||
-                       receive_wq_size > max_ring_size ){
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_parm;
-       }
-
-       status = mlx_memory_zalloc(device_priv->utils,
-                       sizeof(nodnic_qp),(mlx_void **)qp);
-       MLX_FATAL_CHECK_STATUS(status, alloc_err,
-                       "qp allocation error");
-
-       if( nodnic_qp_data_teable[type].send_offset == 0 ||
-                       nodnic_qp_data_teable[type].recv_offset == 0){
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_type;
-       }
-
-       (*qp)->send.nodnic_ring.offset = port_priv->port_offset +
-                               nodnic_qp_data_teable[type].send_offset;
-       (*qp)->receive.nodnic_ring.offset = port_priv->port_offset +
-                       nodnic_qp_data_teable[type].recv_offset;
-
-       status = mlx_memory_alloc_dma(device_priv->utils,
-                       send_wq_size, NODNIC_MEMORY_ALIGN,
-                       (void*)&(*qp)->send.wqe_virt);
-       MLX_FATAL_CHECK_STATUS(status, send_alloc_err,
-                               "send wq allocation error");
-
-       status = mlx_memory_alloc_dma(device_priv->utils,
-                               receive_wq_size, NODNIC_MEMORY_ALIGN,
-                               &(*qp)->receive.wqe_virt);
-       MLX_FATAL_CHECK_STATUS(status, receive_alloc_err,
-                               "receive wq allocation error");
-
-       status = mlx_memory_map_dma(device_priv->utils,
-                                               (*qp)->send.wqe_virt,
-                                               send_wq_size,
-                                               &(*qp)->send.nodnic_ring.wqe_physical,
-                                               &(*qp)->send.nodnic_ring.map);
-       MLX_FATAL_CHECK_STATUS(status, send_map_err,
-                               "send wq map error");
-
-       status = mlx_memory_map_dma(device_priv->utils,
-                                               (*qp)->receive.wqe_virt,
-                                               receive_wq_size,
-                                               &(*qp)->receive.nodnic_ring.wqe_physical,
-                                               &(*qp)->receive.nodnic_ring.map);
-       MLX_FATAL_CHECK_STATUS(status, receive_map_err,
-                               "receive wq map error");
-
-       (*qp)->send.nodnic_ring.wq_size = send_wq_size;
-       (*qp)->send.nodnic_ring.num_wqes = send_wqe_num;
-       (*qp)->receive.nodnic_ring.wq_size = receive_wq_size;
-       (*qp)->receive.nodnic_ring.num_wqes = recv_wqe_num;
-
-       /* Set Ownership bit in Send/receive queue (0 - recv ; 1 - send) */
-       mlx_memory_set(device_priv->utils, (*qp)->send.wqe_virt, 0xff, send_wq_size );
-       mlx_memory_set(device_priv->utils, (*qp)->receive.wqe_virt, 0, recv_wqe_num );
-
-       /* update send ring */
-#define NODIC_RING_QP_ADDR_HIGH 0x0
-#define NODIC_RING_QP_ADDR_LOW 0x4
-       address = (mlx_uint64)(*qp)->send.nodnic_ring.wqe_physical;
-       status = nodnic_cmd_write(device_priv, (*qp)->send.nodnic_ring.offset +
-                       NODIC_RING_QP_ADDR_HIGH,
-                       (mlx_uint32)(address >> 32));
-       MLX_FATAL_CHECK_STATUS(status, write_send_addr_err,
-                                       "send address write error 1");
-       mlx_utils_ilog2((*qp)->send.nodnic_ring.wq_size, &log_size);
-       address = address | log_size;
-       status = nodnic_cmd_write(device_priv, (*qp)->send.nodnic_ring.offset +
-                       NODIC_RING_QP_ADDR_LOW,
-                               (mlx_uint32)address);
-       MLX_FATAL_CHECK_STATUS(status, write_send_addr_err,
-                                               "send address write error 2");
-       /* update receive ring */
-       address = (mlx_uint64)(*qp)->receive.nodnic_ring.wqe_physical;
-       status = nodnic_cmd_write(device_priv, (*qp)->receive.nodnic_ring.offset +
-                       NODIC_RING_QP_ADDR_HIGH,
-                       (mlx_uint32)(address >> 32));
-       MLX_FATAL_CHECK_STATUS(status, write_recv_addr_err,
-                                               "receive address write error 1");
-       mlx_utils_ilog2((*qp)->receive.nodnic_ring.wq_size, &log_size);
-       address = address | log_size;
-       status = nodnic_cmd_write(device_priv, (*qp)->receive.nodnic_ring.offset +
-                       NODIC_RING_QP_ADDR_LOW,
-                               (mlx_uint32)address);
-       MLX_FATAL_CHECK_STATUS(status, write_recv_addr_err,
-                                               "receive address write error 2");
-
-       return status;
-write_recv_addr_err:
-write_send_addr_err:
-       mlx_memory_ummap_dma(device_priv->utils, (*qp)->receive.nodnic_ring.map);
-receive_map_err:
-       mlx_memory_ummap_dma(device_priv->utils, (*qp)->send.nodnic_ring.map);
-send_map_err:
-       mlx_memory_free_dma(device_priv->utils, receive_wq_size,
-                       &((*qp)->receive.wqe_virt));
-receive_alloc_err:
-       mlx_memory_free_dma(device_priv->utils, send_wq_size,
-                       (void **)&((*qp)->send.wqe_virt));
-send_alloc_err:
-invalid_type:
-       mlx_memory_free(device_priv->utils, (void **)qp);
-alloc_err:
-invalid_parm:
-       return status;
-}
-
-mlx_status
-nodnic_port_destroy_qp(
-                                       IN nodnic_port_priv     *port_priv,
-                                       IN nodnic_queue_pair_type       type __attribute__((unused)),
-                                       IN nodnic_qp    *qp
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       nodnic_device_priv *device_priv = port_priv->device;
-
-       status = mlx_memory_ummap_dma(device_priv->utils,
-                       qp->receive.nodnic_ring.map);
-       if( status != MLX_SUCCESS){
-               MLX_DEBUG_ERROR(device_priv, "mlx_memory_ummap_dma failed (Status = %d)\n", status);
-       }
-
-       status = mlx_memory_ummap_dma(device_priv->utils, qp->send.nodnic_ring.map);
-       if( status != MLX_SUCCESS){
-               MLX_DEBUG_ERROR(device_priv, "mlx_memory_ummap_dma failed (Status = %d)\n", status);
-       }
-
-       status = mlx_memory_free_dma(device_priv->utils,
-                       qp->receive.nodnic_ring.wq_size,
-                       (void **)&(qp->receive.wqe_virt));
-       if( status != MLX_SUCCESS){
-               MLX_DEBUG_ERROR(device_priv, "mlx_memory_free_dma failed (Status = %d)\n", status);
-       }
-       status = mlx_memory_free_dma(device_priv->utils,
-                       qp->send.nodnic_ring.wq_size,
-                       (void **)&(qp->send.wqe_virt));
-       if( status != MLX_SUCCESS){
-               MLX_DEBUG_ERROR(device_priv, "mlx_memory_free_dma failed (Status = %d)\n", status);
-       }
-       status = mlx_memory_free(device_priv->utils, (void **)&qp);
-       if( status != MLX_SUCCESS){
-               MLX_DEBUG_ERROR(device_priv, "mlx_memory_free failed (Status = %d)\n", status);
-       }
-       return status;
-}
-
-mlx_status
-nodnic_port_get_qpn(
-                       IN nodnic_port_priv     *port_priv,
-                       IN struct nodnic_ring  *ring,
-                       OUT mlx_uint32 *qpn
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 buffer = 0;
-       if( ring == NULL || qpn == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       if( ring->qpn != 0 ){
-               *qpn = ring->qpn;
-               goto success;
-       }
-#define NODNIC_RING_QPN_OFFSET 0xc
-#define NODNIC_RING_QPN_MASK 0xFFFFFF
-       status = nodnic_cmd_read(port_priv->device,
-                       ring->offset + NODNIC_RING_QPN_OFFSET,
-                       &buffer);
-       MLX_FATAL_CHECK_STATUS(status, read_err,
-                       "nodnic_cmd_read failed");
-       ring->qpn = buffer & NODNIC_RING_QPN_MASK;
-       *qpn = ring->qpn;
-read_err:
-success:
-bad_param:
-       return status;
-}
-
-#ifdef DEVICE_CX3
-static
-mlx_status
-nodnic_port_send_db_connectx3(
-               IN nodnic_port_priv     *port_priv,
-               IN struct nodnic_ring *ring __attribute__((unused)),
-               IN mlx_uint16 index
-               )
-{
-       nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
-       mlx_uint32 index32 = index;
-       mlx_pci_mem_write(port_priv->device->utils, MlxPciWidthUint32, 0,
-                       (mlx_uint64)&(ptr->send_doorbell), 1, &index32);
-       return MLX_SUCCESS;
-}
-
-static
-mlx_status
-nodnic_port_recv_db_connectx3(
-               IN nodnic_port_priv     *port_priv,
-               IN struct nodnic_ring *ring __attribute__((unused)),
-               IN mlx_uint16 index
-               )
-{
-       nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
-       mlx_uint32 index32 = index;
-       mlx_pci_mem_write(port_priv->device->utils, MlxPciWidthUint32, 0,
-                       (mlx_uint64)&(ptr->recv_doorbell), 1, &index32);
-       return MLX_SUCCESS;
-}
-#endif
-
-mlx_status
-nodnic_port_update_ring_doorbell(
-                                       IN nodnic_port_priv     *port_priv,
-                                       IN struct nodnic_ring *ring,
-                                       IN mlx_uint16 index
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 buffer = 0;
-       if( ring == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-#define NODNIC_RING_RING_OFFSET 0x8
-       buffer = (mlx_uint32)((index & 0xFFFF)<< 8);
-       status = nodnic_cmd_write(port_priv->device,
-                               ring->offset + NODNIC_RING_RING_OFFSET,
-                               buffer);
-       MLX_CHECK_STATUS(port_priv->device, status, write_err,
-                               "nodnic_cmd_write failed");
-write_err:
-bad_param:
-       return status;
-}
-
-mlx_status
-nodnic_port_get_cq_size(
-               IN nodnic_port_priv     *port_priv,
-               OUT mlx_uint64 *cq_size
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 out = 0;
-       status = nodnic_port_query(port_priv, nodnic_port_option_log_cq_size, &out);
-       MLX_FATAL_CHECK_STATUS(status, query_err,
-                       "nodnic_port_query failed");
-       *cq_size = 1 << out;
-query_err:
-       return status;
-}
-
-mlx_status
-nodnic_port_allocate_eq(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       IN  mlx_uint8                   log_eq_size
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       nodnic_device_priv *device_priv = NULL;
-       mlx_uint64 address = 0;
-
-       if( port_priv == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       device_priv = port_priv->device;
-       port_priv->eq.eq_size = ( ( 1 << log_eq_size ) * 1024 ); /* Size is in KB */
-       status = mlx_memory_alloc_dma(device_priv->utils,
-                                                               port_priv->eq.eq_size,
-                                                               NODNIC_MEMORY_ALIGN,
-                                                               &port_priv->eq.eq_virt);
-       MLX_FATAL_CHECK_STATUS(status, alloc_err,
-                                                       "eq allocation error");
-
-       status = mlx_memory_map_dma(device_priv->utils,
-                                                       port_priv->eq.eq_virt,
-                                                       port_priv->eq.eq_size,
-                                                       &port_priv->eq.eq_physical,
-                                                       &port_priv->eq.map);
-       MLX_FATAL_CHECK_STATUS(status, map_err,
-                                                               "eq map error");
-
-       address = port_priv->eq.eq_physical;
-       status = nodnic_port_set(port_priv, nodnic_port_option_eq_addr_low,
-                                               (mlx_uint32)address);
-       MLX_FATAL_CHECK_STATUS(status, set_err,
-                       "failed to set eq addr low");
-       address = (address >> 32);
-       status = nodnic_port_set(port_priv, nodnic_port_option_eq_addr_high,
-                                               (mlx_uint32)address);
-       MLX_FATAL_CHECK_STATUS(status, set_err,
-                               "failed to set eq addr high");
-       return status;
-set_err:
-       mlx_memory_ummap_dma(device_priv->utils, port_priv->eq.map);
-map_err:
-       mlx_memory_free_dma(device_priv->utils,
-                       port_priv->eq.eq_size,
-                       (void **)&(port_priv->eq.eq_virt));
-alloc_err:
-bad_param:
-       return status;
-}
-mlx_status
-nodnic_port_free_eq(
-                                       IN  nodnic_port_priv    *port_priv
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       nodnic_device_priv *device_priv = NULL;
-
-       if( port_priv == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       device_priv = port_priv->device;
-       mlx_memory_ummap_dma(device_priv->utils, port_priv->eq.map);
-
-       mlx_memory_free_dma(device_priv->utils,
-                       port_priv->eq.eq_size,
-                       (void **)&(port_priv->eq.eq_virt));
-
-bad_param:
-       return status;
-}
-
-mlx_status
-nodnic_port_add_mac_filter(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       IN  mlx_mac_address     mac
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       nodnic_device_priv *device= NULL;;
-       mlx_uint8 index = 0;
-       mlx_uint32 out = 0;
-       mlx_uint32 mac_filters_en = 0;
-       mlx_uint32 address = 0;
-       mlx_mac_address zero_mac;
-       mlx_utils *utils = NULL;
-
-       if( port_priv == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       memset(&zero_mac, 0, sizeof(zero_mac));
-
-       device = port_priv->device;
-       utils = device->utils;
-
-       /* check if mac already exists */
-       for( ; index < NODNIC_MAX_MAC_FILTERS ; index ++) {
-               mlx_memory_cmp(utils, &port_priv->mac_filters[index], &mac,
-                               sizeof(mac), &out);
-               if ( out == 0 ){
-                       status = MLX_FAILED;
-                       goto already_exists;
-               }
-       }
-
-       /* serch for available mac filter slot */
-       for (index = 0 ; index < NODNIC_MAX_MAC_FILTERS ; index ++) {
-               mlx_memory_cmp(utils, &port_priv->mac_filters[index], &zero_mac,
-                               sizeof(zero_mac), &out);
-               if ( out == 0 ){
-                       break;
-               }
-       }
-       if ( index >= NODNIC_MAX_MAC_FILTERS ){
-               status = MLX_FAILED;
-               goto mac_list_full;
-       }
-
-       status = nodnic_port_query(port_priv, nodnic_port_option_mac_filters_en,
-                       &mac_filters_en);
-       MLX_CHECK_STATUS(device, status , query_err,
-                       "nodnic_port_query failed");
-       if(mac_filters_en & (1 << index)){
-               status = MLX_FAILED;
-               goto mac_list_full;
-       }
-       port_priv->mac_filters[index] = mac;
-
-       // set mac filter
-       address = port_priv->port_offset + NODNIC_PORT_MAC_FILTERS_OFFSET +
-                               (0x8 * index);
-
-       status = nodnic_cmd_write(device, address, mac.high );
-       MLX_CHECK_STATUS(device, status, write_err,     "set mac high failed");
-       status = nodnic_cmd_write(device, address + 0x4, mac.low );
-       MLX_CHECK_STATUS(device, status, write_err, "set mac low failed");
-
-       // enable mac filter
-       mac_filters_en = mac_filters_en | (1 << index);
-       status = nodnic_port_set(port_priv, nodnic_port_option_mac_filters_en,
-                               mac_filters_en);
-       MLX_CHECK_STATUS(device, status , set_err,
-                       "nodnic_port_set failed");
-set_err:
-write_err:
-query_err:
-mac_list_full:
-already_exists:
-bad_param:
-       return status;
-}
-
-mlx_status
-nodnic_port_remove_mac_filter(
-                                       IN  nodnic_port_priv    *port_priv,
-                                       IN  mlx_mac_address     mac
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       nodnic_device_priv *device= NULL;;
-       mlx_uint8 index = 0;
-       mlx_uint32 out = 0;
-       mlx_uint32 mac_filters_en = 0;
-       mlx_mac_address zero_mac;
-       mlx_utils *utils = NULL;
-
-       if( port_priv == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       memset(&zero_mac, 0, sizeof(zero_mac));
-
-       device = port_priv->device;
-       utils = device->utils;
-
-       /* serch for mac filter */
-       for( ; index < NODNIC_MAX_MAC_FILTERS ; index ++) {
-               mlx_memory_cmp(utils, &port_priv->mac_filters[index], &mac,
-                               sizeof(mac), &out);
-               if ( out == 0 ){
-                       break;
-               }
-       }
-       if ( index == NODNIC_MAX_MAC_FILTERS ){
-               status = MLX_FAILED;
-               goto mac_not_found;
-       }
-
-       status = nodnic_port_query(port_priv, nodnic_port_option_mac_filters_en,
-                       &mac_filters_en);
-       MLX_CHECK_STATUS(device, status , query_err,
-                       "nodnic_port_query failed");
-       if((mac_filters_en & (1 << index)) == 0){
-               status = MLX_FAILED;
-               goto mac_not_en;
-       }
-       port_priv->mac_filters[index] = zero_mac;
-
-       // disable mac filter
-       mac_filters_en = mac_filters_en & ~(1 << index);
-       status = nodnic_port_set(port_priv, nodnic_port_option_mac_filters_en,
-                               mac_filters_en);
-       MLX_CHECK_STATUS(device, status , set_err,
-                       "nodnic_port_set failed");
-set_err:
-query_err:
-mac_not_en:
-mac_not_found:
-bad_param:
-       return status;
-}
-
-static
-mlx_status
-nodnic_port_set_network(
-               IN nodnic_port_priv             *port_priv,
-               IN mlx_boolean                  value
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       /*mlx_uint32 network_valid = 0;
-       mlx_uint8 try = 0;*/
-
-       status = nodnic_port_set(port_priv, nodnic_port_option_network_en, value);
-       MLX_CHECK_STATUS(port_priv->device, status, set_err,
-                       "nodnic_port_set failed");
-       port_priv->network_state = value;
-set_err:
-       return status;
-}
-
-#ifdef DEVICE_CX3
-static
-mlx_status
-nodnic_port_set_dma_connectx3(
-               IN nodnic_port_priv             *port_priv,
-               IN mlx_boolean                  value
-               )
-{
-       mlx_utils *utils = port_priv->device->utils;
-       nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
-       mlx_uint32 data = (value ? 0xffffffff : 0x0);
-       mlx_pci_mem_write(utils, MlxPciWidthUint32, 0,
-                       (mlx_uint64)&(ptr->dma_en), 1, &data);
-       return MLX_SUCCESS;
-}
-#endif
-
-static
-mlx_status
-nodnic_port_set_dma(
-               IN nodnic_port_priv             *port_priv,
-               IN mlx_boolean                  value
-               )
-{
-       return nodnic_port_set(port_priv, nodnic_port_option_dma_en, value);
-}
-
-static
-mlx_status
-nodnic_port_check_and_set_dma(
-               IN nodnic_port_priv             *port_priv,
-               IN mlx_boolean                  value
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       if ( port_priv->dma_state == value ) {
-               MLX_DEBUG_WARN(port_priv->device,
-                               "nodnic_port_check_and_set_dma: already %s\n",
-                               (value ? "enabled" : "disabled"));
-               status = MLX_SUCCESS;
-               goto set_out;
-       }
-
-       status = port_priv->set_dma(port_priv, value);
-       MLX_CHECK_STATUS(port_priv->device, status, set_err,
-                       "nodnic_port_set failed");
-       port_priv->dma_state = value;
-set_err:
-set_out:
-       return status;
-}
-
-
-mlx_status
-nodnic_port_set_promisc(
-               IN nodnic_port_priv             *port_priv,
-               IN mlx_boolean                  value
-               ){
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32      buffer = value;
-
-       status = nodnic_port_set(port_priv, nodnic_port_option_port_promisc_en, buffer);
-       MLX_CHECK_STATUS(port_priv->device, status, set_err,
-                       "nodnic_port_set failed");
-set_err:
-       return status;
-}
-
-mlx_status
-nodnic_port_set_promisc_multicast(
-               IN nodnic_port_priv             *port_priv,
-               IN mlx_boolean                  value
-               ){
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32      buffer = value;
-
-       status = nodnic_port_set(port_priv, nodnic_port_option_port_promisc_multicast_en, buffer);
-       MLX_CHECK_STATUS(port_priv->device, status, set_err,
-                       "nodnic_port_set failed");
-set_err:
-       return status;
-}
-
-mlx_status
-nodnic_port_init(
-               IN nodnic_port_priv             *port_priv
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-
-       if( port_priv == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       status = nodnic_port_set_network(port_priv, TRUE);
-       MLX_FATAL_CHECK_STATUS(status, set_err,
-                                       "nodnic_port_set_network failed");
-set_err:
-bad_param:
-       return status;
-}
-
-mlx_status
-nodnic_port_close(
-               IN nodnic_port_priv             *port_priv
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-
-       if( port_priv == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       status = nodnic_port_set_network(port_priv, FALSE);
-       MLX_FATAL_CHECK_STATUS(status, set_err,
-                                       "nodnic_port_set_network failed");
-set_err:
-bad_param:
-       return status;
-}
-
-mlx_status
-nodnic_port_enable_dma(
-               IN nodnic_port_priv             *port_priv
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-
-       if( port_priv == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       status = nodnic_port_check_and_set_dma(port_priv, TRUE);
-       MLX_CHECK_STATUS(port_priv->device, status, set_err,
-                                       "nodnic_port_check_and_set_dma failed");
-set_err:
-bad_param:
-       return status;
-}
-
-mlx_status
-nodnic_port_disable_dma(
-               IN nodnic_port_priv             *port_priv
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-
-       if( port_priv == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       status = nodnic_port_check_and_set_dma(port_priv, FALSE);
-       MLX_CHECK_STATUS(port_priv->device, status, set_err,
-                                       "nodnic_port_check_and_set_dma failed");
-set_err:
-bad_param:
-       return status;
-}
-
-mlx_status
-nodnic_port_thin_init(
-               IN nodnic_device_priv   *device_priv,
-               IN nodnic_port_priv             *port_priv,
-               IN mlx_uint8                    port_index
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_boolean     reset_needed = 0;
-#ifdef DEVICE_CX3
-       mlx_uint32 offset;
-#endif
-
-       if( device_priv == NULL || port_priv == NULL || port_index > 1){
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_parm;
-       }
-
-       port_priv->device = device_priv;
-
-       port_priv->port_offset = device_priv->device_offset +
-                       nodnic_port_offset_table[port_index];
-
-       port_priv->port_num = port_index + 1;
-
-       port_priv->send_doorbell = nodnic_port_update_ring_doorbell;
-       port_priv->recv_doorbell = nodnic_port_update_ring_doorbell;
-       port_priv->set_dma = nodnic_port_set_dma;
-#ifdef DEVICE_CX3
-       if (device_priv->device_cap.crspace_doorbells) {
-               status = nodnic_cmd_read(device_priv, (port_priv->port_offset + 0x100),
-                               &offset);
-               if (status != MLX_SUCCESS) {
-                       return status;
-               } else {
-                       port_priv->data_flow_gw = (nodnic_port_data_flow_gw *)
-                                       (device_priv->utils->config + offset);
-               }
-               if ( nodnic_port_set ( port_priv, nodnic_port_option_crspace_en, 1 ) ) {
-                       return MLX_FAILED;
-               }
-               port_priv->send_doorbell = nodnic_port_send_db_connectx3;
-               port_priv->recv_doorbell = nodnic_port_recv_db_connectx3;
-               port_priv->set_dma = nodnic_port_set_dma_connectx3;
-       }
-#endif
-       /* clear reset_needed */
-       nodnic_port_read_reset_needed(port_priv, &reset_needed);
-
-       port_priv->port_type = NODNIC_PORT_TYPE_UNKNOWN;
-invalid_parm:
-       return status;
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_memory_priv.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_memory_priv.h
deleted file mode 100644 (file)
index 1f8ba89..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifndef MLXUTILS_INCLUDE_PRIVATE_MEMORYPRIV_H_
-#define MLXUTILS_INCLUDE_PRIVATE_MEMORYPRIV_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../../mlx_utils/include/public/mlx_utils.h"
-
-mlx_status
-mlx_memory_alloc_priv(
-                               IN mlx_utils *utils,
-                               IN mlx_size size,
-                               OUT mlx_void **ptr
-                               );
-
-mlx_status
-mlx_memory_zalloc_priv(
-                               IN mlx_utils *utils,
-                               IN mlx_size size,
-                               OUT mlx_void **ptr
-                               );
-
-mlx_status
-mlx_memory_free_priv(
-                               IN mlx_utils *utils,
-                               IN mlx_void *ptr
-                               );
-mlx_status
-mlx_memory_alloc_dma_priv(
-                                       IN mlx_utils *utils,
-                                       IN mlx_size size ,
-                                       IN mlx_size align,
-                                       OUT mlx_void **ptr
-                                       );
-
-mlx_status
-mlx_memory_free_dma_priv(
-                                       IN mlx_utils *utils,
-                                       IN mlx_size size ,
-                                       IN mlx_void *ptr
-                                       );
-mlx_status
-mlx_memory_map_dma_priv(
-                                       IN mlx_utils *utils,
-                                       IN mlx_void *addr ,
-                                       IN mlx_size number_of_bytes,
-                                       OUT mlx_physical_address *phys_addr,
-                                       OUT mlx_void **mapping
-                                       );
-
-mlx_status
-mlx_memory_ummap_dma_priv(
-                                       IN mlx_utils *utils,
-                                       IN mlx_void *mapping
-                                       );
-
-mlx_status
-mlx_memory_cmp_priv(
-                                       IN mlx_utils *utils,
-                                       IN mlx_void *first_block,
-                                       IN mlx_void *second_block,
-                                       IN mlx_size size,
-                                       OUT mlx_uint32 *out
-                                       );
-
-mlx_status
-mlx_memory_set_priv(
-                                       IN mlx_utils *utils,
-                                       IN mlx_void *block,
-                                       IN mlx_int32 value,
-                                       IN mlx_size size
-                                       );
-
-mlx_status
-mlx_memory_cpy_priv(
-                                       IN mlx_utils *utils,
-                                       OUT mlx_void *destination_buffer,
-                                       IN mlx_void *source_buffer,
-                                       IN mlx_size length
-                                       );
-
-mlx_status
-mlx_memory_cpu_to_be32_priv(
-                       IN mlx_utils *utils,
-                       IN mlx_uint32 source,
-                       IN mlx_uint32 *destination
-                       );
-
-mlx_status
-mlx_memory_be32_to_cpu_priv(
-                       IN mlx_utils *utils,
-                       IN mlx_uint32 source,
-                       IN mlx_uint32 *destination
-                       );
-#endif /* STUB_MLXUTILS_INCLUDE_PRIVATE_MEMORYPRIV_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_pci_priv.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_pci_priv.h
deleted file mode 100644 (file)
index 89cad75..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef STUB_MLXUTILS_INCLUDE_PRIVATE_PCIPRIV_H_
-#define STUB_MLXUTILS_INCLUDE_PRIVATE_PCIPRIV_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../include/public/mlx_pci.h"
-#include "../../include/public/mlx_utils.h"
-
-mlx_status
-mlx_pci_init_priv(
-                       IN mlx_utils *utils
-                       );
-
-mlx_status
-mlx_pci_read_priv(
-                       IN mlx_utils *utils,
-                       IN mlx_pci_width width,
-                       IN mlx_uint32 offset,
-                       IN mlx_uintn count,
-                       OUT mlx_void *buffer
-                       );
-
-mlx_status
-mlx_pci_write_priv(
-                       IN mlx_utils *utils,
-                       IN mlx_pci_width width,
-                       IN mlx_uint32 offset,
-                       IN mlx_uintn count,
-                       IN mlx_void *buffer
-                       );
-
-mlx_status
-mlx_pci_mem_read_priv(
-                               IN mlx_utils *utils,
-                               IN mlx_pci_width width,
-                               IN mlx_uint8 bar_index,
-                               IN mlx_uint64 offset,
-                               IN mlx_uintn count,
-                               OUT mlx_void *buffer
-                               );
-
-mlx_status
-mlx_pci_mem_write_priv(
-                               IN mlx_utils *utils,
-                               IN mlx_pci_width width,
-                               IN mlx_uint8 bar_index,
-                               IN mlx_uint64 offset,
-                               IN mlx_uintn count,
-                               IN mlx_void *buffer
-                               );
-
-
-#endif /* STUB_MLXUTILS_INCLUDE_PRIVATE_PCIPRIV_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_utils_priv.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_utils_priv.h
deleted file mode 100644 (file)
index 268b76f..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef SRC_DRIVERS_INFINIBAND_MLX_UTILS_INCLUDE_PRIVATE_MLX_UTILS_PRIV_H_
-#define SRC_DRIVERS_INFINIBAND_MLX_UTILS_INCLUDE_PRIVATE_MLX_UTILS_PRIV_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../include/public/mlx_utils.h"
-
-mlx_status
-mlx_utils_delay_in_ms_priv(
-                       IN mlx_uint32 msecs
-               );
-
-mlx_status
-mlx_utils_delay_in_us_priv(
-                       IN mlx_uint32 usecs
-               );
-
-mlx_status
-mlx_utils_ilog2_priv(
-                       IN mlx_uint32 i,
-                       OUT mlx_uint32 *log
-               );
-
-mlx_status
-mlx_utils_init_lock_priv(
-                       OUT void **lock
-               );
-
-mlx_status
-mlx_utils_free_lock_priv(
-                       IN void *lock
-               );
-
-mlx_status
-mlx_utils_acquire_lock_priv (
-                       IN void *lock
-               );
-
-mlx_status
-mlx_utils_release_lock_priv (
-                       IN void *lock
-               );
-
-mlx_status
-mlx_utils_rand_priv (
-               IN mlx_utils *utils,
-               OUT mlx_uint32 *rand_num
-               );
-#endif /* SRC_DRIVERS_INFINIBAND_MLX_UTILS_INCLUDE_PRIVATE_MLX_UTILS_PRIV_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_bail.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_bail.h
deleted file mode 100644 (file)
index a4f4b37..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef INCLUDE_PUBLIC_MLXBAIL_H_
-#define INCLUDE_PUBLIC_MLXBAIL_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_types.h"
-
-#define MLX_BAIL_ERROR(id, status,message) MLX_CHECK_STATUS(id, status, bail, message)
-
-#define MLX_FATAL_CHECK_STATUS(status, label, message)                                         \
-        do {                                                                                                                                   \
-            if (status != MLX_SUCCESS) {                                                                               \
-                MLX_DEBUG_FATAL_ERROR(message " (Status = %d)\n", status);     \
-                goto label;                                                                                                            \
-            }                                                                                                                                  \
-        } while (0)
-
-#define MLX_CHECK_STATUS(id, status, label, message)                                   \
-        do {                                                                                                                   \
-            if (status != MLX_SUCCESS) {                                                               \
-                MLX_DEBUG_ERROR(id, message " (Status = %d)\n", status);\
-                goto label;                                                                                            \
-            }                                                                                                                  \
-        } while (0)
-
-
-
-#endif /* INCLUDE_PUBLIC_MLXBAIL_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_icmd.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_icmd.h
deleted file mode 100644 (file)
index 1ed423d..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef MLXUTILS_INCLUDE_PUBLIC_MLX_ICMD_H_
-#define MLXUTILS_INCLUDE_PUBLIC_MLX_ICMD_H_
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_utils.h"
-
-#define MLX_ICMD_MB_ADDR 0x100000
-#define MLX_ICMD_MB_SIZE_ADDR 0x1000
-#define MLX_ICMD_CTRL_ADDR 0x0
-
-#define MLX_ICMD_SEMAPHORE_ADDR 0x0
-
-#define MLX_ICMD_SEMAPHORE_ID 1234
-
-enum {
-       FLASH_REG_ACCESS        = 0x9001,
-       GET_FW_INFO                     = 0x8007,
-       QUERY_VIRTUAL_MAC       = 0x9003,
-       SET_VIRTUAL_MAC         = 0x9004,
-       QUERY_WOL_ROL           = 0x9005,
-       SET_WOL_ROL                     = 0x9006,
-       OCBB_INIT                       = 0x9007,
-       OCBB_QUERY_HEADER_STATUS        = 0x9008,
-       OCBB_QUERY_ETOC_STATUS  = 0x9009,
-       OCBB_QUERY_SET_EVENT    = 0x900A,
-       OCSD_INIT                       = 0xf004,
-};
-
-struct mlx_icmd_ocsd {
-       mlx_uint32 reserved;
-       mlx_uint64 address;
-};
-
-mlx_status
-mlx_icmd_send_command(
-                               IN mlx_utils *utils,
-                               IN  mlx_uint16 opcode,
-                               IN OUT mlx_void* data,
-                               IN mlx_uint32 write_data_size,
-                               IN mlx_uint32 read_data_size
-                               );
-
-#endif /* MLXUTILS_INCLUDE_PUBLIC_MLX_ICMD_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_logging.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_logging.h
deleted file mode 100644 (file)
index 7b7b852..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef PUBLIC_INCLUDE_MLX_LOGGER_H_
-#define PUBLIC_INCLUDE_MLX_LOGGER_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../../mlx_utils_flexboot/include/mlx_logging_priv.h"
-
-#define MLX_DEBUG_FATAL_ERROR(...)     MLX_DEBUG_FATAL_ERROR_PRIVATE(__VA_ARGS__)
-#define MLX_DEBUG_ERROR(...)           MLX_DEBUG_ERROR_PRIVATE(__VA_ARGS__)
-#define MLX_DEBUG_WARN(...)                    MLX_DEBUG_WARN_PRIVATE(__VA_ARGS__)
-#define MLX_DEBUG_INFO1(...)           MLX_DEBUG_INFO1_PRIVATE(__VA_ARGS__)
-#define MLX_DEBUG_INFO2(...)           MLX_DEBUG_INFO2_PRIVATE(__VA_ARGS__)
-#define MLX_DBG_ERROR(...)                     MLX_DBG_ERROR_PRIVATE(__VA_ARGS__)
-#define MLX_DBG_WARN(...)                      MLX_DBG_WARN_PRIVATE(__VA_ARGS__)
-#define MLX_DBG_INFO1(...)                     MLX_DBG_INFO1_PRIVATE(__VA_ARGS__)
-#define MLX_DBG_INFO2(...)                     MLX_DBG_INFO2_PRIVATE(__VA_ARGS__)
-
-#define MLX_TRACE_1_START()                            MLX_DBG_INFO1_PRIVATE("Start\n")
-#define MLX_TRACE_1_END()                              MLX_DBG_INFO1_PRIVATE("End\n")
-#define MLX_TRACE_1_END_STATUS(status) MLX_DBG_INFO1_PRIVATE("End (%s=%d)\n", #status,status)
-#define MLX_TRACE_2_START()                            MLX_DBG_INFO2_PRIVATE("Start\n")
-#define MLX_TRACE_2_END()                              MLX_DBG_INFO2_PRIVATE("End\n")
-#define MLX_TRACE_2_END_STATUS(status) MLX_DBG_INFO2_PRIVATE("End (%s=%d)\n", #status,status)
-
-
-
-#endif /* PUBLIC_INCLUDE_MLX_LOGGER_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_memory.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_memory.h
deleted file mode 100644 (file)
index 0567566..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-#ifndef MLXUTILS_INCLUDE_PUBLIC_MEMORY_H_
-#define MLXUTILS_INCLUDE_PUBLIC_MEMORY_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_utils.h"
-
-
-mlx_status
-mlx_memory_alloc(
-                               IN mlx_utils *utils,
-                               IN mlx_size size,
-                               OUT mlx_void **ptr
-                               );
-
-mlx_status
-mlx_memory_zalloc(
-                               IN mlx_utils *utils,
-                               IN mlx_size size,
-                               OUT mlx_void **ptr
-                               );
-
-mlx_status
-mlx_memory_free(
-                               IN mlx_utils *utils,
-                               IN mlx_void **ptr
-                               );
-mlx_status
-mlx_memory_alloc_dma(
-                                       IN mlx_utils *utils,
-                                       IN mlx_size size ,
-                                       IN mlx_size align,
-                                       OUT mlx_void **ptr
-                                       );
-
-mlx_status
-mlx_memory_free_dma(
-                                       IN mlx_utils *utils,
-                                       IN mlx_size size ,
-                                       IN mlx_void **ptr
-                                       );
-mlx_status
-mlx_memory_map_dma(
-                                       IN mlx_utils *utils,
-                                       IN mlx_void *Addr ,
-                                       IN mlx_size NumberOfBytes,
-                                       OUT mlx_physical_address *PhysAddr,
-                                       OUT mlx_void **Mapping
-                                       );
-
-mlx_status
-mlx_memory_ummap_dma(
-                                       IN mlx_utils *utils,
-                                       IN mlx_void *Mapping
-                                       );
-
-mlx_status
-mlx_memory_cmp(
-                                       IN mlx_utils *utils,
-                                       IN mlx_void *first_block,
-                                       IN mlx_void *second_block,
-                                       IN mlx_size size,
-                                       OUT mlx_uint32 *out
-                                       );
-
-mlx_status
-mlx_memory_set(
-                                       IN mlx_utils *utils,
-                                       IN mlx_void *block,
-                                       IN mlx_int32 value,
-                                       IN mlx_size size
-                                       );
-
-mlx_status
-mlx_memory_cpy(
-                                       IN mlx_utils *utils,
-                                       OUT mlx_void *destination_buffer,
-                                       IN mlx_void *source_buffer,
-                                       IN mlx_size length
-                                       );
-
-mlx_status
-mlx_memory_cpu_to_be32(
-                       IN mlx_utils *utils,
-                       IN mlx_uint32 source,
-                       IN mlx_uint32 *destination
-                       );
-
-mlx_status
-mlx_memory_be32_to_cpu(
-                       IN mlx_utils *utils,
-                       IN mlx_uint32 source,
-                       IN mlx_uint32 *destination
-                       );
-
-#endif /* STUB_MLXUTILS_INCLUDE_PUBLIC_MEMORY_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_pci.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_pci.h
deleted file mode 100644 (file)
index 416bdb6..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef STUB_MLXUTILS_INCLUDE_PUBLIC_PCI_H_
-#define STUB_MLXUTILS_INCLUDE_PUBLIC_PCI_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_utils.h"
-
-typedef enum {
-                         MlxPciWidthUint8      = 0,
-                         MlxPciWidthUint16,
-                         MlxPciWidthUint32,
-                         MlxPciWidthUint64,
-} mlx_pci_width;
-
-mlx_status
-mlx_pci_init(
-                       IN mlx_utils *utils
-                       );
-
-mlx_status
-mlx_pci_read(
-                       IN mlx_utils *utils,
-                       IN mlx_pci_width width,
-                       IN mlx_uint32 offset,
-                       IN mlx_uintn count,
-                       OUT mlx_void *buffer
-                       );
-
-mlx_status
-mlx_pci_write(
-                       IN mlx_utils *utils,
-                       IN mlx_pci_width width,
-                       IN mlx_uint32 offset,
-                       IN mlx_uintn count,
-                       IN mlx_void *buffer
-                       );
-
-mlx_status
-mlx_pci_mem_read(
-                               IN mlx_utils *utils,
-                               IN mlx_pci_width width,
-                               IN mlx_uint8 bar_index,
-                               IN mlx_uint64 offset,
-                               IN mlx_uintn count,
-                               OUT mlx_void *buffer
-                               );
-
-mlx_status
-mlx_pci_mem_write(
-                               IN mlx_utils *utils,
-                               IN mlx_pci_width width,
-                               IN mlx_uint8 bar_index,
-                               IN mlx_uint64 offset,
-                               IN mlx_uintn count,
-                               IN mlx_void *buffer
-                               );
-
-
-#endif /* STUB_MLXUTILS_INCLUDE_PUBLIC_PCI_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_pci_gw.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_pci_gw.h
deleted file mode 100644 (file)
index c074a22..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef INCLUDE_PUBLIC_MLX_PCI_GW_H_
-#define INCLUDE_PUBLIC_MLX_PCI_GW_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_utils.h"
-
-#define PCI_GW_FIRST_CAPABILITY_POINTER_OFFSET 0x34
-
-#define PCI_GW_CAPABILITY_ID 0x9
-
-#define PCI_GW_CAPABILITY_ID_OFFSET 0x0
-#define PCI_GW_CAPABILITY_NEXT_POINTER_OFFSET 0x1
-#define PCI_GW_CAPABILITY_SPACE_OFFSET 0x4
-#define PCI_GW_CAPABILITY_STATUS_OFFSET 0x7
-#define PCI_GW_CAPABILITY_COUNTER_OFFSET 0x8
-#define PCI_GW_CAPABILITY_SEMAPHORE_OFFSET 0xC
-#define PCI_GW_CAPABILITY_ADDRESS_OFFSET 0x10
-#define PCI_GW_CAPABILITY_FLAG_OFFSET 0x10
-#define PCI_GW_CAPABILITY_DATA_OFFSET 0x14
-
-#define PCI_GW_SEMPHORE_TRIES 3000000
-#define PCI_GW_GET_OWNERSHIP_TRIES 5000
-#define PCI_GW_READ_FLAG_TRIES 3000000
-
-#define PCI_GW_WRITE_FLAG 0x80000000
-
-#define PCI_GW_SPACE_NODNIC 0x4
-#define PCI_GW_SPACE_ALL_ICMD 0x3
-#define PCI_GW_SPACE_SEMAPHORE 0xa
-#define PCI_GW_SPACE_CR0 0x2
-
-typedef mlx_uint32     mlx_pci_gw_buffer;
-
-
-mlx_status
-mlx_pci_gw_init(
-                               IN mlx_utils *utils
-                               );
-mlx_status
-mlx_pci_gw_teardown(
-                               IN mlx_utils *utils
-                               );
-mlx_status
-mlx_pci_gw_read(
-                               IN mlx_utils *utils,
-                               IN mlx_pci_gw_space space,
-                               IN mlx_uint32 address,
-                               OUT mlx_pci_gw_buffer *buffer
-                               );
-
-mlx_status
-mlx_pci_gw_write(
-                               IN mlx_utils *utils,
-                               IN mlx_pci_gw_space space,
-                               IN mlx_uint32 address,
-                               IN mlx_pci_gw_buffer buffer
-                               );
-
-
-
-#endif /* INCLUDE_PUBLIC_MLX_PCI_GW_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_types.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_types.h
deleted file mode 100644 (file)
index 9c66567..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef INCLUDE_PUBLIC_MLXTYPES_H_
-#define INCLUDE_PUBLIC_MLXTYPES_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../../mlx_utils_flexboot/include/mlx_types_priv.h"
-
-#endif /* INCLUDE_PUBLIC_MLXBAIL_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_utils.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_utils.h
deleted file mode 100644 (file)
index 46ad97c..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-#ifndef MLXUTILS_INCLUDE_PUBLIC_MLXUTILS_H_
-#define MLXUTILS_INCLUDE_PUBLIC_MLXUTILS_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_logging.h"
-#include "mlx_types.h"
-
-#define IN
-#define OUT
-
-typedef mlx_uint16     mlx_pci_gw_space;
-
-typedef struct{
-       mlx_uint32      pci_cmd_offset;
-       mlx_pci_gw_space space;
-} __attribute__ (( packed )) mlx_pci_gw;
-
-typedef struct {
-       mlx_boolean icmd_opened;
-       mlx_boolean took_semaphore;
-       mlx_uint32 max_cmd_size;
-} __attribute__ (( packed )) mlx_icmd ;
-
-typedef  struct{
-       mlx_pci *pci;
-       mlx_pci_gw pci_gw;
-       mlx_icmd icmd;
-       void *lock;
-#ifdef DEVICE_CX3
-       /* ACCESS to BAR0 */
-       void *config;
-#endif
-} __attribute__ (( packed )) mlx_utils;
-
-mlx_status
-mlx_utils_init(
-                               IN mlx_utils *utils,
-                               IN mlx_pci *pci
-                               );
-
-mlx_status
-mlx_utils_teardown(
-                               IN mlx_utils *utils
-                               );
-mlx_status
-mlx_utils_delay_in_ms(
-                       IN mlx_uint32 msecs
-               );
-
-mlx_status
-mlx_utils_delay_in_us(
-                       IN mlx_uint32 usecs
-               );
-
-mlx_status
-mlx_utils_ilog2(
-                       IN mlx_uint32 i,
-                       OUT mlx_uint32 *log
-               );
-
-mlx_status
-mlx_utils_init_lock(
-                       IN OUT mlx_utils *utils
-               );
-
-mlx_status
-mlx_utils_free_lock(
-                       IN OUT mlx_utils *utils
-               );
-
-mlx_status
-mlx_utils_acquire_lock (
-                       IN OUT mlx_utils *utils
-               );
-
-mlx_status
-mlx_utils_release_lock (
-               IN OUT mlx_utils *utils
-               );
-
-mlx_status
-mlx_utils_rand (
-               IN mlx_utils *utils,
-               OUT mlx_uint32 *rand_num
-               );
-#endif /* STUB_MLXUTILS_INCLUDE_PUBLIC_MLXUTILS_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_blink_leds/mlx_blink_leds.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_blink_leds/mlx_blink_leds.c
deleted file mode 100644 (file)
index ba56e72..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../mlx_lib/mlx_blink_leds/mlx_blink_leds.h"
-#include "../../include/public/mlx_memory.h"
-#include "../../include/public/mlx_bail.h"
-
-mlx_status
-mlx_blink_leds(
-               IN mlx_utils *utils,
-               IN mlx_uint16 secs
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct mlx_led_control led_control;
-       mlx_uint32 reg_status;
-
-       if (utils == NULL ) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       mlx_memory_set(utils, &led_control, 0, sizeof(led_control));
-       led_control.beacon_duration = secs;
-       status = mlx_reg_access(utils, REG_ID_MLCR, REG_ACCESS_WRITE, &led_control, sizeof(led_control),
-                       &reg_status);
-       MLX_CHECK_STATUS(utils, status, reg_err, "mlx_reg_access failed ");
-       if (reg_status != 0) {
-               MLX_DEBUG_ERROR(utils,"mlx_reg_access failed with status = %d\n", reg_status);
-               status = MLX_FAILED;
-               goto reg_err;
-       }
-reg_err:
-bad_param:
-       return status;
-}
-
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_blink_leds/mlx_blink_leds.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_blink_leds/mlx_blink_leds.h
deleted file mode 100644 (file)
index 886645f..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef MLX_BLINK_LEDS_H_
-#define MLX_BLINK_LEDS_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../mlx_lib/mlx_reg_access/mlx_reg_access.h"
-#include "../../include/public/mlx_utils.h"
-
-struct mlx_led_control {
-       mlx_uint32 reserved1    :16;
-       mlx_uint32 port :8;
-       mlx_uint32 bla  :8;
-/* -------------- */
-       mlx_uint32 beacon_duration      :16;
-       mlx_uint32 reserved2    :16;
-/* -------------- */
-       mlx_uint32 beacon_remain        :16;
-       mlx_uint32 reserved3    :16;
-};
-
-mlx_status
-mlx_blink_leds(
-               IN mlx_utils *utils,
-               IN mlx_uint16 secs
-               );
-
-#endif /* MLX_NVCONFIG_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.c
deleted file mode 100644 (file)
index d315530..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../mlx_lib/mlx_link_speed/mlx_link_speed.h"
-#include "../../include/public/mlx_memory.h"
-#include "../../include/public/mlx_bail.h"
-
-mlx_status
-mlx_set_link_speed(
-               IN mlx_utils *utils,
-               IN mlx_uint8 port_num,
-               IN LINK_SPEED_TYPE type,
-               IN LINK_SPEED speed
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct mlx_link_speed link_speed;
-       mlx_uint32 reg_status;
-
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       mlx_memory_set(utils, &link_speed, 0, sizeof(link_speed));
-
-       link_speed.loacl_port = port_num;
-       link_speed.proto_mask = 1 << type;
-
-       status = mlx_reg_access(utils, REG_ID_PTYS, REG_ACCESS_READ, &link_speed,
-                       sizeof(link_speed), &reg_status);
-
-       MLX_CHECK_STATUS(utils, status, reg_err, "mlx_reg_access failed ");
-       if (reg_status != 0) {
-               MLX_DEBUG_ERROR(utils,"mlx_reg_access failed with status = %d\n", reg_status);
-               status = MLX_FAILED;
-               goto reg_err;
-       }
-       switch (speed) {
-       case LINK_SPEED_1GB:
-               link_speed.eth_proto_admin = link_speed.eth_proto_capability & LINK_SPEED_1GB_MASK;
-               break;
-       case LINK_SPEED_10GB:
-               link_speed.eth_proto_admin = link_speed.eth_proto_capability & LINK_SPEED_10GB_MASK;
-               break;
-       case LINK_SPEED_40GB:
-               link_speed.eth_proto_admin = link_speed.eth_proto_capability & LINK_SPEED_40GB_MASK;
-               break;
-       case LINK_SPEED_100GB:
-               link_speed.eth_proto_admin = link_speed.eth_proto_capability & LINK_SPEED_100GB_MASK;
-               break;
-       case LINK_SPEED_SDR:
-               link_speed.ib_proto_admin = link_speed.ib_proto_capability & LINK_SPEED_SDR_MASK;
-               break;
-       case LINK_SPEED_DEFAULT:
-               if (type == LINK_SPEED_ETH) {
-                       link_speed.eth_proto_admin = link_speed.eth_proto_capability;
-               } else {
-                       link_speed.ib_proto_admin = link_speed.ib_proto_capability;
-               }
-               break;
-       }
-       status = mlx_reg_access(utils, REG_ID_PTYS, REG_ACCESS_WRITE, &link_speed,
-                               sizeof(link_speed), &reg_status);
-       MLX_CHECK_STATUS(utils, status, reg_err, "mlx_reg_access failed ");
-       if (reg_status != 0) {
-               MLX_DEBUG_ERROR(utils,"mlx_reg_access failed with status = %d\n", reg_status);
-               status = MLX_FAILED;
-               goto reg_err;
-       }
-reg_err:
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_get_max_speed(
-               IN mlx_utils *utils,
-               IN mlx_uint8 port_num,
-               IN LINK_SPEED_TYPE type,
-               OUT mlx_uint64 *speed
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct mlx_link_speed link_speed;
-       mlx_uint32 reg_status;
-       mlx_uint64 speed_giga = 0;
-       mlx_uint8  lanes_number = 1;
-
-       *speed = 0;
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       mlx_memory_set(utils, &link_speed, 0, sizeof(link_speed));
-
-       link_speed.loacl_port = port_num;
-       link_speed.proto_mask = 1 << type;
-
-       status = mlx_reg_access(utils, REG_ID_PTYS, REG_ACCESS_READ, &link_speed,
-                       sizeof(link_speed), &reg_status);
-       MLX_CHECK_STATUS(utils, status, reg_err, "mlx_reg_access failed ");
-       if (reg_status != 0) {
-               MLX_DEBUG_ERROR(utils,"mlx_reg_access failed with status = %d\n", reg_status);
-               status = MLX_FAILED;
-               goto reg_err;
-       }
-
-       if ( type == LINK_SPEED_ETH ) {
-               if ( link_speed.eth_proto_capability & LINK_SPEED_100GB_MASK ) {
-                       speed_giga = 100;
-               } else if ( link_speed.eth_proto_capability & LINK_SPEED_56GB_MASK ) {
-                       speed_giga = 56;
-               } else if ( link_speed.eth_proto_capability & LINK_SPEED_50GB_MASK ) {
-                       speed_giga = 50;
-               } else if ( link_speed.eth_proto_capability & LINK_SPEED_40GB_MASK ) {
-                       speed_giga = 40;
-               } else if (link_speed.eth_proto_capability & LINK_SPEED_25GB_MASK) {
-                       speed_giga = 25;
-               } else if ( link_speed.eth_proto_capability & LINK_SPEED_20GB_MASK ) {
-                       speed_giga = 20;
-               } else if ( link_speed.eth_proto_capability & LINK_SPEED_10GB_MASK) {
-                       speed_giga = 10;
-               } else if ( link_speed.eth_proto_capability & LINK_SPEED_1GB_MASK ) {
-                       speed_giga = 1;
-               }
-       } else {
-               if ( link_speed.ib_proto_capability & LINK_SPEED_EDR_MASK ) {
-                       speed_giga = 25;
-               } else if ( link_speed.ib_proto_capability & LINK_SPEED_EDR20_MASK ) {
-                       speed_giga = 20;
-               } else if ( link_speed.ib_proto_capability & LINK_SPEED_FDR_MASK ) {
-                       speed_giga = 14;
-               } else if ( link_speed.ib_proto_capability & LINK_SPEED_QDR_MASK ) {
-                       speed_giga = 10;
-               } else if ( link_speed.ib_proto_capability & LINK_SPEED_DDR_MASK ) {
-                       speed_giga = 5;
-               } else if ( link_speed.ib_proto_capability & LINK_SPEED_SDR_MASK ) {
-                       speed_giga = 2.5;
-               }
-               if ( link_speed.ib_link_width_capability & LINK_SPEED_WITDH_12_MASK ) {
-                       lanes_number = 12;
-               } else if ( link_speed.ib_link_width_capability & LINK_SPEED_WITDH_8_MASK ) {
-                       lanes_number = 8;
-               } else if (link_speed.ib_link_width_capability & LINK_SPEED_WITDH_4_MASK ) {
-                       lanes_number = 4;
-               } else if (link_speed.ib_link_width_capability & LINK_SPEED_WITDH_2_MASK ) {
-                       lanes_number = 2;
-               } else if (link_speed.ib_link_width_capability & LINK_SPEED_WITDH_1_MASK ) {
-                       lanes_number = 1;
-               }
-               speed_giga = speed_giga * lanes_number;
-       }
-       // Return data in bits
-       *speed = speed_giga * GIGA_TO_BIT;
-reg_err:
-bad_param:
-       return status;
-}
-
-
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h
deleted file mode 100644 (file)
index 15b28f5..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-#ifndef MLX_LINK_SPEED_H_
-#define MLX_LINK_SPEED_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../mlx_lib/mlx_reg_access/mlx_reg_access.h"
-#include "../../include/public/mlx_utils.h"
-
-#define LINK_SPEED_100GB_MASK        (ETH_SPEED_ENABLE_MASK_100GBASECR4 | ETH_SPEED_ENABLE_MASK_100GBASESR4 | ETH_SPEED_ENABLE_MASK_100GBASEKR4 | ETH_SPEED_ENABLE_MASK_100GBASELR4)
-#define LINK_SPEED_56GB_MASK         (ETH_SPEED_ENABLE_MASK_56GBASER4)
-#define LINK_SPEED_50GB_MASK         (ETH_SPEED_ENABLE_MASK_50GBASECR2 | ETH_SPEED_ENABLE_MASK_50GBASEKR2)
-#define LINK_SPEED_40GB_MASK         (ETH_SPEED_ENABLE_MASK_40GBASECR4 | ETH_SPEED_ENABLE_MASK_40GBASEKR4 | ETH_SPEED_ENABLE_MASK_40GBASESR4 | ETH_SPEED_ENABLE_MASK_40GBASELR4)
-#define LINK_SPEED_25GB_MASK         (ETH_SPEED_ENABLE_MASK_25GBASECR | ETH_SPEED_ENABLE_MASK_25GBASEKR | ETH_SPEED_ENABLE_MASK_25GBASESR)
-#define LINK_SPEED_20GB_MASK         (ETH_SPEED_ENABLE_MASK_20GBASER2)
-#define LINK_SPEED_10GB_MASK         (ETH_SPEED_ENABLE_MASK_10GBASECR | ETH_SPEED_ENABLE_MASK_10GBASESR | ETH_SPEED_ENABLE_MASK_10GBASELR | ETH_SPEED_ENABLE_MASK_10GBASEKR)
-#define LINK_SPEED_1GB_MASK          (ETH_SPEED_ENABLE_MASK_1000BASECX | ETH_SPEED_ENABLE_MASK_1000BASEKX | ETH_SPEED_ENABLE_MASK_100BaseTX | ETH_SPEED_ENABLE_MASK_1000BASET)
-
-#define LINK_SPEED_SDR_MASK 0x1
-#define LINK_SPEED_DDR_MASK 0x2
-#define LINK_SPEED_QDR_MASK 0xC
-#define LINK_SPEED_FDR_MASK 0x10
-#define LINK_SPEED_EDR20_MASK 0x200
-#define LINK_SPEED_EDR_MASK 0x20
-
-#define LINK_SPEED_WITDH_1_MASK 0x1
-#define LINK_SPEED_WITDH_2_MASK 0x2
-#define LINK_SPEED_WITDH_4_MASK 0x4
-#define LINK_SPEED_WITDH_8_MASK 0x8
-#define LINK_SPEED_WITDH_12_MASK 0x10
-
-#define GIGA_TO_BIT 0x40000000
-
-enum {
-    ETH_SPEED_ENABLE_MASK_1000BASECX  = 0x0001,
-    ETH_SPEED_ENABLE_MASK_1000BASEKX  = 0x0002,
-    ETH_SPEED_ENABLE_MASK_10GBASECX4  = 0x0004,
-    ETH_SPEED_ENABLE_MASK_10GBASEKX4  = 0x0008,
-    ETH_SPEED_ENABLE_MASK_10GBASEKR   = 0x0010,
-    ETH_SPEED_ENABLE_MASK_20GBASER2   = 0x0020,
-    ETH_SPEED_ENABLE_MASK_40GBASECR4  = 0x0040,
-    ETH_SPEED_ENABLE_MASK_40GBASEKR4  = 0x0080,
-    ETH_SPEED_ENABLE_MASK_56GBASER4   = 0x0100,
-    ETH_SPEED_ENABLE_MASK_10GBASECR   = 0x1000,
-    ETH_SPEED_ENABLE_MASK_10GBASESR   = 0x2000,
-    ETH_SPEED_ENABLE_MASK_10GBASELR   = 0x4000,
-    ETH_SPEED_ENABLE_MASK_40GBASESR4  = 0x8000,
-    ETH_SPEED_ENABLE_MASK_40GBASELR4  = 0x10000,
-    ETH_SPEED_ENABLE_MASK_50GBASEKR4  = 0x80000,
-    ETH_SPEED_ENABLE_MASK_100GBASECR4 = 0x100000,
-    ETH_SPEED_ENABLE_MASK_100GBASESR4 = 0x200000,
-    ETH_SPEED_ENABLE_MASK_100GBASEKR4 = 0x400000,
-    ETH_SPEED_ENABLE_MASK_100GBASELR4 = 0x800000,
-    ETH_SPEED_ENABLE_MASK_100BaseTX   = 0x1000000,
-    ETH_SPEED_ENABLE_MASK_1000BASET   = 0x2000000,
-    ETH_SPEED_ENABLE_MASK_10GBASET    = 0x4000000,
-    ETH_SPEED_ENABLE_MASK_25GBASECR   = 0x8000000,
-    ETH_SPEED_ENABLE_MASK_25GBASEKR   = 0x10000000,
-    ETH_SPEED_ENABLE_MASK_25GBASESR   = 0x20000000,
-    ETH_SPEED_ENABLE_MASK_50GBASECR2  = 0x40000000,
-    ETH_SPEED_ENABLE_MASK_50GBASEKR2  = 0x80000000,
-    ETH_SPEED_ENABLE_MASK_BAD         = 0xffff,
-};
-
-
-typedef enum {
-       LINK_SPEED_IB = 0,
-       LINK_SPEED_FC,
-       LINK_SPEED_ETH,
-} LINK_SPEED_TYPE;
-
-typedef enum {
-       LINK_SPEED_1GB = 0,
-       LINK_SPEED_10GB,
-       LINK_SPEED_40GB,
-       LINK_SPEED_100GB,
-       LINK_SPEED_SDR,
-       LINK_SPEED_DEFAULT,
-} LINK_SPEED;
-
-struct mlx_link_speed {
-       mlx_uint32 proto_mask   :3;
-       mlx_uint32 reserved1    :13;
-       mlx_uint32 loacl_port   :8;
-       mlx_uint32 reserved2    :8;
-       /* -------------- */
-       mlx_uint32 reserved3    :32;
-       /* -------------- */
-       mlx_uint32 reserved4    :32;
-       /* -------------- */
-       mlx_uint32 eth_proto_capability :32;
-       /* -------------- */
-       mlx_uint32 ib_proto_capability  :16;
-       mlx_uint32 ib_link_width_capability     :16;
-       /* -------------- */
-       mlx_uint32 reserved5    :32;
-       /* -------------- */
-       mlx_uint32 eth_proto_admin      :32;
-       /* -------------- */
-       mlx_uint32 ib_proto_admin       :16;
-       mlx_uint32 ib_link_width_admin  :16;
-       /* -------------- */
-       mlx_uint32 reserved6    :32;
-       /* -------------- */
-       mlx_uint32 eth_proto_oper       :32;
-       /* -------------- */
-       mlx_uint32 ib_proto_oper        :16;
-       mlx_uint32 ib_link_width_oper   :16;
-};
-
-mlx_status
-mlx_set_link_speed(
-               IN mlx_utils *utils,
-               IN mlx_uint8 port_num,
-               IN LINK_SPEED_TYPE type,
-               IN LINK_SPEED speed
-               );
-
-mlx_status
-mlx_get_max_speed(
-               IN mlx_utils *utils,
-               IN mlx_uint8 port_num,
-               IN LINK_SPEED_TYPE type,
-               OUT mlx_uint64 *speed
-               );
-
-#endif /* MLX_LINK_SPEED_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_mtu/mlx_mtu.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_mtu/mlx_mtu.c
deleted file mode 100644 (file)
index 7557302..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_mtu.h"
-#include "mlx_memory.h"
-#include "mlx_bail.h"
-
-mlx_status
-mlx_get_max_mtu(
-               IN mlx_utils    *utils,
-               IN mlx_uint8    port_num,
-               OUT mlx_uint32  *max_mtu
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct mlx_mtu mtu;
-       mlx_uint32 reg_status;
-       *max_mtu = 0;
-
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       mlx_memory_set(utils, &mtu, 0, sizeof(mtu));
-
-       mtu.local_port = port_num;
-
-       status = mlx_reg_access(utils, REG_ID_PMTU, REG_ACCESS_READ, &mtu,
-                       sizeof(mtu), &reg_status);
-       MLX_CHECK_STATUS(utils, status, reg_err, "mlx_reg_access failed ");
-       if (reg_status != 0) {
-               MLX_DEBUG_ERROR(utils,"mlx_reg_access failed with status = %d\n", reg_status);
-               status = MLX_FAILED;
-               goto reg_err;
-       }
-       // Return data in bits
-       *max_mtu = mtu.max_mtu * BYTE_TO_BIT;
-reg_err:
-bad_param:
-       return status;
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_mtu/mlx_mtu.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_mtu/mlx_mtu.h
deleted file mode 100644 (file)
index c622262..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef MLX_MTU_H_
-#define MLX_MTU_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_reg_access.h"
-#include "mlx_utils.h"
-
-#define BYTE_TO_BIT    0x8
-
-struct mlx_mtu {
-       mlx_uint32 reserved1    :16;
-       mlx_uint32 local_port   :8;
-       mlx_uint32 reserved2    :8;
-       /* -------------- */
-       mlx_uint32 reserved3    :16;
-       mlx_uint32 max_mtu              :16;
-       /* -------------- */
-       mlx_uint32 reserved4    :16;
-       mlx_uint32 admin_mtu    :16;
-       /* -------------- */
-       mlx_uint32 reserved5    :16;
-       mlx_uint32 oper_mtu             :16;
-};
-
-mlx_status
-mlx_get_max_mtu(
-               IN mlx_utils    *utils,
-               IN mlx_uint8    port_num,
-               OUT mlx_uint32  *max_mtu
-               );
-
-#endif /* MLX_MTU_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.c
deleted file mode 100644 (file)
index 2277e0c..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../mlx_lib/mlx_nvconfig/mlx_nvconfig.h"
-#include "../../include/public/mlx_memory.h"
-#include "../../include/public/mlx_bail.h"
-
-#define TlvMappingEntry( _tlv_type, _real_tlv_type, _class_code, _fw_reset_needed) { \
-  .tlv_type = _tlv_type,                     \
-  .real_tlv_type = _real_tlv_type,                   \
-  .class_code = _class_code,                  \
-  .fw_reset_needed = _fw_reset_needed,        \
-  }
-
-struct nvconfig_tlv_mapping nvconfig_tlv_mapping[] = {
-               TlvMappingEntry(0x10, 0x10, NVRAM_TLV_CLASS_HOST, TRUE),
-               TlvMappingEntry(0x12, 0x12, NVRAM_TLV_CLASS_PHYSICAL_PORT, TRUE),
-               TlvMappingEntry(0x80, 0x80, NVRAM_TLV_CLASS_GLOBAL, TRUE),
-               TlvMappingEntry(0x81, 0x81, NVRAM_TLV_CLASS_GLOBAL, TRUE),
-               TlvMappingEntry(0x100, 0x100, NVRAM_TLV_CLASS_GLOBAL, TRUE),
-               TlvMappingEntry(0x2001, 0x195, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2010, 0x210, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2011, 0x211, NVRAM_TLV_CLASS_GLOBAL, FALSE),
-               TlvMappingEntry(0x2020, 0x2020, NVRAM_TLV_CLASS_PHYSICAL_PORT, FALSE),
-               TlvMappingEntry(0x2021, 0x221, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2023, 0x223, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2100, 0x230, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2101, 0x231, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2102, 0x232, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2103, 0x233, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2104, 0x234, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2105, 0x235, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2106, 0x236, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2107, 0x237, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2108, 0x238, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2109, 0x239, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x210A, 0x23A, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2200, 0x240, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2201, 0x241, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2202, 0x242, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2203, 0x243, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2204, 0x244, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2205, 0x245, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0x2207, 0x247, NVRAM_TLV_CLASS_HOST, FALSE),
-               TlvMappingEntry(0, 0, 0, 0),
-};
-
-static
-mlx_status
-nvconfig_set_fw_reset_level(
-               IN mlx_utils *utils,
-               IN      mlx_uint16      tlv_type
-               )
-{
-#define WARM_REBOOT_RESET ((mlx_uint64)0x1 << 38)
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 reg_status;
-       mlx_uint64 mfrl = WARM_REBOOT_RESET ;
-       mlx_uint8 index = 0;
-       mlx_boolean reset_needed = FALSE;
-
-       for (index = 0 ; nvconfig_tlv_mapping[index].tlv_type != 0 ; index++) {
-               if (nvconfig_tlv_mapping[index].tlv_type == tlv_type) {
-                       reset_needed = nvconfig_tlv_mapping[index].fw_reset_needed;
-               }
-       }
-
-       if (reset_needed == FALSE) {
-               goto no_fw_reset_needed;
-       }
-       status = mlx_reg_access(utils, REG_ID_MFRL, REG_ACCESS_WRITE, &mfrl, sizeof(mfrl),
-                               &reg_status);
-       MLX_CHECK_STATUS(utils, status, reg_err, "mlx_reg_access failed ");
-
-       if (reg_status != 0) {
-               MLX_DEBUG_ERROR(utils,"nvconfig_set_fw_reset_level failed with status = %d\n", reg_status);
-               status = MLX_FAILED;
-               goto reg_err;
-       }
-reg_err:
-no_fw_reset_needed:
-       return status;
-}
-
-
-static
-mlx_status
-nvconfig_get_tlv_type_and_class(
-               IN      mlx_uint16      tlv_type,
-               OUT mlx_uint16  *real_tlv_type,
-               OUT NVRAM_CLASS_CODE *class_code
-               )
-{
-       mlx_uint8 index = 0;
-       for ( ; nvconfig_tlv_mapping[index].tlv_type != 0 ; index ++) {
-               if ( nvconfig_tlv_mapping[index].tlv_type == tlv_type) {
-                       *real_tlv_type = nvconfig_tlv_mapping[index].real_tlv_type;
-                       *class_code = nvconfig_tlv_mapping[index].class_code;
-                       return MLX_SUCCESS;
-               }
-       }
-       return MLX_NOT_FOUND;
-}
-static
-void
-nvconfig_fill_tlv_type(
-               IN mlx_uint8 port,
-               IN NVRAM_CLASS_CODE class_code,
-               IN mlx_uint16 tlv_type,
-               OUT union nvconfig_tlv_type *nvconfig_tlv_type
-               )
-{
-       switch (class_code) {
-       case NVRAM_TLV_CLASS_GLOBAL:
-               nvconfig_tlv_type->global.param_class = NVRAM_TLV_CLASS_GLOBAL;
-               nvconfig_tlv_type->global.param_idx = tlv_type;
-               break;
-       case NVRAM_TLV_CLASS_HOST:
-               nvconfig_tlv_type->per_host.param_class = NVRAM_TLV_CLASS_HOST;
-               nvconfig_tlv_type->per_host.param_idx = tlv_type;
-               break;
-       case NVRAM_TLV_CLASS_PHYSICAL_PORT:
-               nvconfig_tlv_type->per_port.param_class = NVRAM_TLV_CLASS_PHYSICAL_PORT;
-               nvconfig_tlv_type->per_port.param_idx = tlv_type;
-               nvconfig_tlv_type->per_port.port = port;
-               break;
-       }
-}
-mlx_status
-nvconfig_query_capability(
-               IN mlx_utils *utils,
-               IN mlx_uint8 port,
-               IN mlx_uint16 tlv_type,
-               OUT mlx_boolean *read_supported,
-               OUT mlx_boolean *write_supported
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct nvconfig_nvqc nvqc;
-       mlx_uint32 reg_status;
-       NVRAM_CLASS_CODE class_code;
-       mlx_uint16 real_tlv_type;
-
-       if (utils == NULL || read_supported == NULL || write_supported == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       status = nvconfig_get_tlv_type_and_class(tlv_type, &real_tlv_type, &class_code);
-       MLX_CHECK_STATUS(utils, status, tlv_not_supported, "tlv not supported");
-
-       mlx_memory_set(utils, &nvqc, 0, sizeof(nvqc));
-       nvconfig_fill_tlv_type(port, class_code, real_tlv_type, &nvqc.tlv_type);
-
-       status = mlx_reg_access(utils, REG_ID_NVQC, REG_ACCESS_READ, &nvqc, sizeof(nvqc),
-                       &reg_status);
-       MLX_CHECK_STATUS(utils, status, reg_err, "mlx_reg_access failed ");
-       if (reg_status != 0) {
-               MLX_DEBUG_ERROR(utils,"mlx_reg_access failed with status = %d\n", reg_status);
-               status = MLX_FAILED;
-               goto reg_err;
-       }
-       *read_supported = nvqc.support_rd;
-       *write_supported = nvqc.support_wr;
-reg_err:
-tlv_not_supported:
-bad_param:
-       return status;
-}
-
-mlx_status
-nvconfig_nvdata_invalidate(
-               IN mlx_utils *utils,
-               IN mlx_uint8 port,
-               IN mlx_uint16 tlv_type
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct nvconfig_header nv_header;
-       mlx_uint32 reg_status;
-       NVRAM_CLASS_CODE class_code;
-       mlx_uint16 real_tlv_type;
-
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       status = nvconfig_get_tlv_type_and_class(tlv_type, &real_tlv_type, &class_code);
-       MLX_CHECK_STATUS(utils, status, tlv_not_supported, "tlv not supported");
-
-       mlx_memory_set(utils, &nv_header, 0, sizeof(nv_header));
-       nvconfig_fill_tlv_type(port, class_code, real_tlv_type, &nv_header.tlv_type);
-
-       status = mlx_reg_access(utils, REG_ID_NVDI, REG_ACCESS_WRITE, &nv_header, sizeof(nv_header),
-                       &reg_status);
-       MLX_CHECK_STATUS(utils, status, reg_err, "mlx_reg_access failed ");
-       if (reg_status != 0) {
-               MLX_DEBUG_ERROR(utils,"mlx_reg_access failed with status = %d\n", reg_status);
-               status = MLX_FAILED;
-               goto reg_err;
-       }
-reg_err:
-tlv_not_supported:
-bad_param:
-       return status;
-}
-
-mlx_status
-nvconfig_nvdata_access(
-               IN mlx_utils *utils,
-               IN mlx_uint8 port,
-               IN mlx_uint16 tlv_type,
-               IN REG_ACCESS_OPT opt,
-               IN mlx_size data_size,
-               IN NV_DEFAULT_OPT def_en,
-               IN OUT mlx_uint8 *version,
-               IN OUT mlx_void *data
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct nvconfig_nvda nvda;
-       mlx_uint32 reg_status;
-       mlx_uint32 real_size_to_read;
-       mlx_uint32 index;
-       NVRAM_CLASS_CODE class_code;
-       mlx_uint16 real_tlv_type;
-       mlx_size data_size_align_to_dword;
-
-       if (utils == NULL || data == NULL || data_size > NVCONFIG_MAX_TLV_SIZE) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       status = nvconfig_get_tlv_type_and_class(tlv_type, &real_tlv_type, &class_code);
-       MLX_CHECK_STATUS(utils, status, tlv_not_supported, "tlv not supported");
-
-       data_size_align_to_dword = ((data_size + 3) / sizeof(mlx_uint32)) * sizeof(mlx_uint32);
-       mlx_memory_set(utils, &nvda, 0, sizeof(nvda));
-       nvda.nv_header.length = data_size_align_to_dword;
-       nvda.nv_header.rd_en = 0;
-       nvda.nv_header.def_en = def_en;
-       nvda.nv_header.over_en = 1;
-       nvda.nv_header.version = *version;
-
-       nvconfig_fill_tlv_type(port, class_code, real_tlv_type, &nvda.nv_header.tlv_type);
-
-       mlx_memory_cpy(utils, nvda.data, data, data_size);
-       for (index = 0 ; index * 4 < NVCONFIG_MAX_TLV_SIZE ; index++) {
-               mlx_memory_be32_to_cpu(utils,(((mlx_uint32 *)nvda.data)[index]), ((mlx_uint32 *)nvda.data) + index);
-       }
-       status = mlx_reg_access(utils, REG_ID_NVDA, opt, &nvda,
-                       data_size_align_to_dword + sizeof(nvda.nv_header), &reg_status);
-       MLX_CHECK_STATUS(utils, status, reg_err, "mlx_reg_access failed ");
-       if (reg_status != 0) {
-               MLX_DEBUG_ERROR(utils,"mlx_reg_access failed with status = %d\n", reg_status);
-               status = MLX_FAILED;
-               goto reg_err;
-       }
-       for (index = 0 ; index * 4 < NVCONFIG_MAX_TLV_SIZE ; index++) {
-               mlx_memory_cpu_to_be32(utils,(((mlx_uint32 *)nvda.data)[index]), ((mlx_uint32 *)nvda.data) + index);
-       }
-       if (opt == REG_ACCESS_READ) {
-               real_size_to_read = (nvda.nv_header.length > data_size) ? data_size :
-                               nvda.nv_header.length;
-               mlx_memory_cpy(utils, data, nvda.data, real_size_to_read);
-               *version = nvda.nv_header.version;
-       } else {
-               nvconfig_set_fw_reset_level(utils, tlv_type);
-       }
-reg_err:
-tlv_not_supported:
-bad_param:
-       return status;
-}
-
-
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h
deleted file mode 100644 (file)
index 8333e83..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-#ifndef MLX_NVCONFIG_H_
-#define MLX_NVCONFIG_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../mlx_reg_access/mlx_reg_access.h"
-#include "../../include/public/mlx_utils.h"
-
-typedef enum {
-       NVRAM_TLV_CLASS_GLOBAL = 0,
-       NVRAM_TLV_CLASS_PHYSICAL_PORT = 1,
-       NVRAM_TLV_CLASS_HOST = 3,
-} NVRAM_CLASS_CODE;
-
-struct nvconfig_tlv_type_per_port {
-        mlx_uint32 param_idx   :16;
-        mlx_uint32 port                :8;
-        mlx_uint32 param_class :8;
-};
-
-struct nvconfig_tlv_type_per_host {
-       mlx_uint32 param_idx    :10;
-       mlx_uint32 function             :8;
-       mlx_uint32 host                 :6;
-       mlx_uint32 param_class  :8;
-};
-
-struct nvconfig_tlv_type_global {
-       mlx_uint32 param_idx    :24;
-       mlx_uint32 param_class  :8;
-};
-
-struct nvconfig_tlv_mapping{
-       mlx_uint16      tlv_type;
-       mlx_uint16      real_tlv_type;
-       NVRAM_CLASS_CODE class_code;
-       mlx_boolean fw_reset_needed;
-};
-
-union nvconfig_tlv_type {
-       struct nvconfig_tlv_type_per_port per_port;
-       struct nvconfig_tlv_type_per_host per_host;
-       struct nvconfig_tlv_type_global global;
-};
-
-
-struct nvconfig_nvqc {
-       union nvconfig_tlv_type tlv_type;
-/* -------------- */
-        mlx_uint32 support_rd  :1; /*the configuration item is supported and can be read */
-        mlx_uint32 support_wr  :1; /*the configuration item is supported and can be updated */
-        mlx_uint32 reserved1   :2;
-        mlx_uint32 version             :4; /*The maximum version of the configuration item currently supported by the firmware. */
-        mlx_uint32 reserved2   :24;
-};
-
-
-struct nvconfig_header {
-        mlx_uint32 length              :9; /*Size of configuration item data in bytes between 0..256 */
-        mlx_uint32 reserved0   :3;
-        mlx_uint32 version             :4; /* Configuration item version */
-        mlx_uint32 reserved1   :7;
-
-        mlx_uint32 def_en              :1; /*Choose whether to access the default value or the user-defined value.
-                                                                       0x0 Read or write the user-defined value.
-                                                                       0x1 Read the default value (only valid for reads).*/
-
-        mlx_uint32 rd_en               :1; /*enables reading the TLV by lower priorities
-                                                                       0 - TLV can be read by the subsequent lifecycle priorities.
-                                                                       1 - TLV cannot be read by the subsequent lifecycle priorities. */
-        mlx_uint32 over_en             :1; /*enables overwriting the TLV by lower priorities
-                                                                       0 - Can only be overwritten by the current lifecycle priority
-                                                                       1 - Allowed to be overwritten by subsequent lifecycle priorities */
-        mlx_uint32 header_type :2;
-        mlx_uint32 priority            :2;
-        mlx_uint32 valid       :2;
-/* -------------- */
-        union nvconfig_tlv_type tlv_type;;
-/* -------------- */
-       mlx_uint32 crc                  :16;
-       mlx_uint32 reserved             :16;
-};
-
-#define NVCONFIG_MAX_TLV_SIZE 256
-
-struct nvconfig_nvda {
-       struct nvconfig_header nv_header;
-       mlx_uint8 data[NVCONFIG_MAX_TLV_SIZE];
-};
-
-
-mlx_status
-nvconfig_query_capability(
-               IN mlx_utils *utils,
-               IN mlx_uint8 port,
-               IN mlx_uint16 tlv_type,
-               OUT mlx_boolean *read_supported,
-               OUT mlx_boolean *write_supported
-               );
-
-
-mlx_status
-nvconfig_nvdata_invalidate(
-               IN mlx_utils *utils,
-               IN mlx_uint8 port,
-               IN mlx_uint16 tlv_type
-               );
-
-mlx_status
-nvconfig_nvdata_access(
-               IN mlx_utils *utils,
-               IN mlx_uint8 port,
-               IN mlx_uint16 tlv_type,
-               IN REG_ACCESS_OPT opt,
-               IN mlx_size data_size,
-               IN NV_DEFAULT_OPT def_en,
-               IN OUT mlx_uint8 *version,
-               IN OUT mlx_void *data
-               );
-
-#endif /* MLX_NVCONFIG_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.c
deleted file mode 100644 (file)
index 77eda8a..0000000
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE( GPL2_OR_LATER);
-
-#include "../../mlx_lib/mlx_nvconfig/mlx_nvconfig.h"
-#include "../../include/public/mlx_memory.h"
-#include "../../include/public/mlx_bail.h"
-#include "../../mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h"
-
-struct tlv_default {
-       mlx_uint16 tlv_type;
-       mlx_size data_size;
-       mlx_status (*set_defaults)( IN void *data, IN int status,
-                       OUT void *def_struct);
-};
-
-#define TlvDefaultEntry( _tlv_type, _data_size, _set_defaults) { \
-  .tlv_type = _tlv_type,                     \
-  .data_size = sizeof ( _data_size ),                   \
-  .set_defaults = _set_defaults,                  \
-  }
-
-static
-mlx_status
-nvconfig_get_boot_default_conf(
-               IN void *data,
-               IN int status,
-               OUT void *def_struct
-               )
-{
-       union mlx_nvconfig_nic_boot_conf *nic_boot_conf =
-                       (union mlx_nvconfig_nic_boot_conf *) data;
-       struct mlx_nvconfig_port_conf_defaults *port_conf_def =
-                       (struct mlx_nvconfig_port_conf_defaults *) def_struct;
-
-       /* boot_option_rom_en is deprecated - enabled always */
-       port_conf_def->boot_option_rom_en = DEFAULT_OPTION_ROM_EN;
-
-       MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
-                       "TLV not found. Using hard-coded defaults ");
-       port_conf_def->boot_vlan = nic_boot_conf->vlan_id;
-       port_conf_def->boot_protocol = nic_boot_conf->legacy_boot_prot;
-       port_conf_def->boot_retry_count = nic_boot_conf->boot_retry_count;
-       port_conf_def->boot_vlan_en = nic_boot_conf->en_vlan;
-
-       return MLX_SUCCESS;
-
-nvdata_access_err:
-       port_conf_def->boot_vlan = DEFAULT_BOOT_VLAN;
-       port_conf_def->boot_protocol = DEFAULT_BOOT_PROTOCOL;
-
-       return status;
-}
-
-static
-mlx_status
-nvconfig_get_boot_ext_default_conf(
-               IN void *data,
-               IN int status,
-               OUT void *def_struct
-               )
-{
-       union mlx_nvconfig_nic_boot_ext_conf *nic_boot_ext_conf =
-                       (union mlx_nvconfig_nic_boot_ext_conf *) data;
-       struct mlx_nvconfig_port_conf_defaults *port_conf_def =
-                       (struct mlx_nvconfig_port_conf_defaults *) def_struct;
-
-       MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
-                       "TLV not found. Using hard-coded defaults ");
-       port_conf_def->linkup_timeout = nic_boot_ext_conf->linkup_timeout;
-       port_conf_def->ip_ver = nic_boot_ext_conf->ip_ver;
-
-       return MLX_SUCCESS;
-
-nvdata_access_err:
-       port_conf_def->linkup_timeout = DEFAULT_BOOT_LINK_UP_TO;
-       port_conf_def->ip_ver = DEFAULT_BOOT_IP_VER;
-
-       return status;
-}
-
-static
-mlx_status
-nvconfig_get_iscsi_init_dhcp_default_conf(
-               IN void *data,
-               IN int status,
-               OUT void *def_struct
-               )
-{
-       union mlx_nvconfig_iscsi_init_dhcp_conf *iscsi_init_dhcp_conf =
-                       (union mlx_nvconfig_iscsi_init_dhcp_conf *) data;
-       struct mlx_nvconfig_port_conf_defaults *port_conf_def =
-                       (struct mlx_nvconfig_port_conf_defaults *) def_struct;
-
-       MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
-                       "TLV not found. Using hard-coded defaults ");
-       port_conf_def->iscsi_dhcp_params_en = iscsi_init_dhcp_conf->dhcp_iscsi_en;
-       port_conf_def->iscsi_ipv4_dhcp_en = iscsi_init_dhcp_conf->ipv4_dhcp_en;
-
-       return MLX_SUCCESS;
-
-nvdata_access_err:
-       port_conf_def->iscsi_dhcp_params_en = DEFAULT_ISCSI_DHCP_PARAM_EN;
-       port_conf_def->iscsi_ipv4_dhcp_en = DEFAULT_ISCSI_IPV4_DHCP_EN;
-
-       return status;
-}
-
-static
-mlx_status
-nvconfig_get_ib_boot_default_conf(
-               IN void *data,
-               IN int status,
-               OUT void *def_struct
-               )
-{
-       union mlx_nvconfig_nic_ib_boot_conf *ib_boot_conf =
-                       (union mlx_nvconfig_nic_ib_boot_conf *) data;
-       struct mlx_nvconfig_port_conf_defaults *port_conf_def =
-                       (struct mlx_nvconfig_port_conf_defaults *) def_struct;
-
-       MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
-                       "nvconfig_nvdata_default_access failed ");
-       port_conf_def->boot_pkey = ib_boot_conf->boot_pkey;
-
-nvdata_access_err:
-       return status;
-}
-
-static
-mlx_status
-nvconfig_get_wol_default_conf(
-               IN void *data,
-               IN int status,
-               OUT void *def_struct
-               )
-{
-       union mlx_nvconfig_wol_conf *wol_conf = (union mlx_nvconfig_wol_conf *) data;
-       struct mlx_nvconfig_port_conf_defaults *port_conf_def =
-                       (struct mlx_nvconfig_port_conf_defaults *) def_struct;
-
-       MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
-                       "nvconfig_nvdata_default_access failed ");
-       port_conf_def->en_wol_magic = wol_conf->en_wol_magic;
-
-nvdata_access_err:
-       return status;
-}
-
-static
-mlx_status
-nvconfig_get_iscsi_gen_default_conf(
-               IN void *data,
-               IN int status,
-               OUT void *def_struct)
-{
-       union mlx_nvconfig_iscsi_general *iscsi_gen =
-                       (union mlx_nvconfig_iscsi_general *) data;
-       struct mlx_nvconfig_port_conf_defaults *port_conf_def =
-                       (struct mlx_nvconfig_port_conf_defaults *) def_struct;
-
-       MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
-                       "nvconfig_nvdata_default_access failed ");
-       port_conf_def->iscsi_boot_to_target = iscsi_gen->boot_to_target;
-       port_conf_def->iscsi_vlan_en = iscsi_gen->vlan_en;
-       port_conf_def->iscsi_tcp_timestamps_en = iscsi_gen->tcp_timestamps_en;
-       port_conf_def->iscsi_chap_mutual_auth_en = iscsi_gen->chap_mutual_auth_en;
-       port_conf_def->iscsi_chap_auth_en = iscsi_gen->chap_auth_en;
-       port_conf_def->iscsi_lun_busy_retry_count = iscsi_gen->lun_busy_retry_count;
-       port_conf_def->iscsi_link_up_delay_time = iscsi_gen->link_up_delay_time;
-
-nvdata_access_err:
-       return status;
-}
-
-static
-mlx_status
-nvconfig_get_ib_dhcp_default_conf(
-               IN void *data,
-               IN int status,
-               OUT void *def_struct
-               )
-{
-       union mlx_nvconfig_ib_dhcp_conf *ib_dhcp =
-                       (union mlx_nvconfig_ib_dhcp_conf *) data;
-       struct mlx_nvconfig_port_conf_defaults *port_conf_def =
-                       (struct mlx_nvconfig_port_conf_defaults *) def_struct;
-
-       MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
-                       "nvconfig_nvdata_default_access failed ");
-       port_conf_def->client_identifier = ib_dhcp->client_identifier;
-       port_conf_def->mac_admin_bit = ib_dhcp->mac_admin_bit;
-
-nvdata_access_err:
-       return status;
-}
-
-static
-mlx_status
-nvconfig_get_ocsd_ocbb_default_conf( IN void *data,
-               IN int status, OUT void *def_struct) {
-       union mlx_nvconfig_ocsd_ocbb_conf *ocsd_ocbb =
-                       (union mlx_nvconfig_ocsd_ocbb_conf *) data;
-       struct mlx_nvconfig_conf_defaults *conf_def =
-                       (struct mlx_nvconfig_conf_defaults *) def_struct;
-
-       MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
-                       "TLV not found. Using hard-coded defaults ");
-       conf_def->ocsd_ocbb_en = ocsd_ocbb->ocsd_ocbb_en;
-
-       return MLX_SUCCESS;
-
-nvdata_access_err:
-       conf_def->ocsd_ocbb_en = DEFAULT_OCSD_OCBB_EN;
-
-       return status;
-}
-
-static
-mlx_status
-nvconfig_get_vpi_link_default_conf(
-               IN void *data,
-               IN int status,
-               OUT void *def_struct
-               )
-{
-       union mlx_nvconfig_vpi_link_conf *vpi_link =
-                       (union mlx_nvconfig_vpi_link_conf *) data;
-       struct mlx_nvconfig_port_conf_defaults *port_conf_def =
-                       (struct mlx_nvconfig_port_conf_defaults *) def_struct;
-
-       MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
-                       "nvconfig_nvdata_default_access failed ");
-       port_conf_def->network_link_type = vpi_link->network_link_type;
-       port_conf_def->default_link_type = vpi_link->default_link_type;
-
-nvdata_access_err:
-       return status;
-}
-
-static
-mlx_status
-nvconfig_get_rom_banner_to_default_conf(
-               IN void *data,
-               IN int status,
-               OUT void *def_struct
-               )
-{
-       union mlx_nvconfig_rom_banner_timeout_conf *rom_banner_timeout_conf =
-                       (union mlx_nvconfig_rom_banner_timeout_conf *) data;
-       struct mlx_nvconfig_conf_defaults *conf_def =
-                       (struct mlx_nvconfig_conf_defaults *) def_struct;
-
-       MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
-                       "TLV not found. Using hard-coded defaults ");
-       conf_def->flexboot_menu_to = rom_banner_timeout_conf->rom_banner_to;
-
-       return MLX_SUCCESS;
-
-nvdata_access_err:
-       conf_def->flexboot_menu_to = DEFAULT_FLEXBOOT_MENU_TO;
-
-       return status;
-}
-
-static
-mlx_status
-nvconfig_get_nv_virt_caps_default_conf(
-               IN void *data,
-               IN int status,
-               OUT void *def_struct
-               )
-{
-       union mlx_nvconfig_virt_caps *nv_virt_caps =
-                       (union mlx_nvconfig_virt_caps *) data;
-       struct mlx_nvconfig_conf_defaults *conf_def =
-                       (struct mlx_nvconfig_conf_defaults *) def_struct;
-
-       MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
-                       "TLV not found. Using hard-coded defaults ");
-       conf_def->max_vfs = nv_virt_caps->max_vfs_per_pf;
-
-       return MLX_SUCCESS;
-
-nvdata_access_err:
-       conf_def->max_vfs = DEFAULT_MAX_VFS;
-
-       return status;
-}
-
-static
-mlx_status
-nvconfig_get_nv_virt_default_conf(
-               IN void *data,
-               IN int status,
-               OUT void *def_struct
-               )
-{
-       union mlx_nvconfig_virt_conf *nv_virt_conf =
-                       (union mlx_nvconfig_virt_conf *) data;
-       struct mlx_nvconfig_conf_defaults *conf_def =
-                       (struct mlx_nvconfig_conf_defaults *) def_struct;
-
-       MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
-                       "nvconfig_nvdata_default_access failed ");
-       conf_def->total_vfs = nv_virt_conf->num_of_vfs;
-       conf_def->sriov_en = nv_virt_conf->virt_mode;
-
-nvdata_access_err:
-       return status;
-}
-
-static struct tlv_default tlv_port_defaults[] = {
-       TlvDefaultEntry(BOOT_SETTINGS_TYPE, union mlx_nvconfig_nic_boot_conf, &nvconfig_get_boot_default_conf),
-       TlvDefaultEntry(BOOT_SETTINGS_EXT_TYPE, union mlx_nvconfig_nic_boot_ext_conf, &nvconfig_get_boot_ext_default_conf),
-       TlvDefaultEntry(ISCSI_INITIATOR_DHCP_CONF_TYPE, union mlx_nvconfig_iscsi_init_dhcp_conf, &nvconfig_get_iscsi_init_dhcp_default_conf),
-       TlvDefaultEntry(IB_BOOT_SETTING_TYPE, union mlx_nvconfig_nic_ib_boot_conf, &nvconfig_get_ib_boot_default_conf),
-       TlvDefaultEntry(WAKE_ON_LAN_TYPE, union mlx_nvconfig_wol_conf, &nvconfig_get_wol_default_conf),
-       TlvDefaultEntry(ISCSI_GENERAL_SETTINGS_TYPE, union mlx_nvconfig_iscsi_general, &nvconfig_get_iscsi_gen_default_conf),
-       TlvDefaultEntry(IB_DHCP_SETTINGS_TYPE, union mlx_nvconfig_ib_dhcp_conf, &nvconfig_get_ib_dhcp_default_conf),
-       TlvDefaultEntry(VPI_LINK_TYPE, union mlx_nvconfig_vpi_link_conf, &nvconfig_get_vpi_link_default_conf),
-};
-
-static struct tlv_default tlv_general_defaults[] = {
-       TlvDefaultEntry(BANNER_TO_TYPE, union mlx_nvconfig_rom_banner_timeout_conf, &nvconfig_get_rom_banner_to_default_conf),
-       TlvDefaultEntry(GLOPAL_PCI_CAPS_TYPE, union mlx_nvconfig_virt_caps, &nvconfig_get_nv_virt_caps_default_conf),
-       TlvDefaultEntry(GLOPAL_PCI_SETTINGS_TYPE, union mlx_nvconfig_virt_conf, &nvconfig_get_nv_virt_default_conf),
-       TlvDefaultEntry(OCSD_OCBB_TYPE, union mlx_nvconfig_ocsd_ocbb_conf, &nvconfig_get_ocsd_ocbb_default_conf),
-};
-
-static
-mlx_status
-nvconfig_nvdata_default_access(
-               IN mlx_utils *utils,
-               IN mlx_uint8 port,
-               IN mlx_uint16 tlv_type,
-               IN mlx_size data_size,
-               OUT mlx_void *data
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 index;
-       mlx_uint8 version = 0;
-
-       status = nvconfig_nvdata_access(utils, port, tlv_type, REG_ACCESS_READ,
-                       data_size, TLV_ACCESS_DEFAULT_EN, &version, data);
-       MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
-                               "nvconfig_nvdata_access failed ");
-       for (index = 0; index * 4 < data_size; index++) {
-               mlx_memory_be32_to_cpu(utils, (((mlx_uint32 *) data)[index]),
-                               ((mlx_uint32 *) data) + index);
-       }
-
-nvdata_access_err:
-       return status;
-}
-
-static
-mlx_status
-nvconfig_nvdata_read_default_value(
-               IN mlx_utils *utils,
-               IN mlx_uint8 modifier,
-               IN struct tlv_default *def,
-               OUT void *def_struct
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       void *data = NULL;
-
-       status = mlx_memory_zalloc(utils, def->data_size,&data);
-       MLX_CHECK_STATUS(utils, status, memory_err,
-                               "mlx_memory_zalloc failed ");
-       status = nvconfig_nvdata_default_access(utils, modifier, def->tlv_type,
-                       def->data_size, data);
-       def->set_defaults(data, status, def_struct);
-       mlx_memory_free(utils, &data);
-
-memory_err:
-       return status;
-}
-
-static
-void
-nvconfig_nvdata_read_default_values(
-               IN mlx_utils *utils,
-               IN mlx_uint8 modifier,
-               IN struct tlv_default defaults_table[],
-               IN mlx_uint8 defaults_table_size,
-               OUT void *def_strct
-               )
-{
-       struct tlv_default *defs;
-       unsigned int i;
-
-       for (i = 0; i < defaults_table_size; i++) {
-               defs = &defaults_table[i];
-               nvconfig_nvdata_read_default_value(utils, modifier, defs, def_strct);
-       }
-}
-
-mlx_status
-nvconfig_read_port_default_values(
-               IN mlx_utils *utils,
-               IN mlx_uint8 port,
-               OUT struct mlx_nvconfig_port_conf_defaults *port_conf_def
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-
-       if (utils == NULL || port_conf_def == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               MLX_DEBUG_ERROR(utils,"bad params.");
-               goto bad_param;
-       }
-       mlx_memory_set(utils, port_conf_def, 0, sizeof(*port_conf_def));
-       nvconfig_nvdata_read_default_values(utils, port, tlv_port_defaults,
-                               (sizeof(tlv_port_defaults)/sizeof(tlv_port_defaults[0])),
-                               port_conf_def);
-
-bad_param:
-       return status;
-}
-
-mlx_status
-nvconfig_read_general_default_values(
-               IN mlx_utils *utils,
-               OUT struct mlx_nvconfig_conf_defaults *conf_def
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-
-       if (utils == NULL || conf_def == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               MLX_DEBUG_ERROR(utils,"bad params.");
-               goto bad_param;
-       }
-       mlx_memory_set(utils, conf_def, 0, sizeof(*conf_def));
-       nvconfig_nvdata_read_default_values(utils, 0, tlv_general_defaults,
-                       (sizeof(tlv_general_defaults)/sizeof(tlv_general_defaults[0])),
-                       conf_def);
-
-bad_param:
-       return status;
-}
-
-mlx_status
-nvconfig_read_rom_ini_values(
-               IN mlx_utils *utils,
-               OUT struct mlx_nvcofnig_romini *rom_ini
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-
-       if (utils == NULL || rom_ini == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               MLX_DEBUG_ERROR(utils,"bad params.");
-               goto bad_param;
-       }
-       mlx_memory_set(utils, rom_ini, 0, sizeof(*rom_ini));
-
-       status = nvconfig_nvdata_default_access(utils, 0, GLOBAL_ROM_INI_TYPE,
-                       sizeof(*rom_ini), rom_ini);
-bad_param:
-       return status;
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h
deleted file mode 100644 (file)
index 163c2a3..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-#ifndef MLX_NVCONFIG_DEFAULTS_H_
-#define MLX_NVCONFIG_DEFAULTS_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-#include "mlx_nvconfig_prm.h"
-/*
- * Default values
- */
-#define DEFAULT_FLEXBOOT_MENU_TO 4
-#define DEFAULT_MAX_VFS 8
-#define DEFAULT_BOOT_PROTOCOL 1
-#define DEFAULT_OPTION_ROM_EN 1
-#define DEFAULT_BOOT_VLAN 1
-#define DEFAULT_ISCSI_DHCP_PARAM_EN 1
-#define DEFAULT_ISCSI_IPV4_DHCP_EN 1
-#define DEFAULT_OCSD_OCBB_EN 1
-#define DEFAULT_BOOT_IP_VER 0
-#define DEFAULT_BOOT_LINK_UP_TO 0
-
-struct mlx_nvconfig_port_conf_defaults {
-       mlx_uint8 pptx;
-       mlx_uint8 pprx;
-       mlx_boolean boot_option_rom_en;
-       mlx_boolean boot_vlan_en;
-       mlx_uint8 boot_retry_count;
-       mlx_uint8 boot_protocol;
-       mlx_uint8 boot_vlan;
-       mlx_uint8 boot_pkey;
-       mlx_boolean en_wol_magic;
-       mlx_uint8 network_link_type;
-       mlx_uint8 iscsi_boot_to_target;
-       mlx_boolean iscsi_vlan_en;
-       mlx_boolean iscsi_tcp_timestamps_en;
-       mlx_boolean iscsi_chap_mutual_auth_en;
-       mlx_boolean iscsi_chap_auth_en;
-       mlx_boolean iscsi_dhcp_params_en;
-       mlx_boolean iscsi_ipv4_dhcp_en;
-       mlx_uint8 iscsi_lun_busy_retry_count;
-       mlx_uint8 iscsi_link_up_delay_time;
-       mlx_uint8 client_identifier;
-       mlx_uint8 mac_admin_bit;
-       mlx_uint8 default_link_type;
-       mlx_uint8 linkup_timeout;
-       mlx_uint8 ip_ver;
-};
-
-struct mlx_nvconfig_conf_defaults  {
-       mlx_uint8 max_vfs;
-       mlx_uint8 total_vfs;
-       mlx_uint8 sriov_en;
-       mlx_uint8 maximum_uar_bar_size;
-       mlx_uint8 uar_bar_size;
-       mlx_uint8 flexboot_menu_to;
-       mlx_boolean ocsd_ocbb_en;
-};
-
-mlx_status
-nvconfig_read_port_default_values(
-               IN mlx_utils *utils,
-               IN mlx_uint8 port,
-               OUT struct mlx_nvconfig_port_conf_defaults *port_conf_def
-               );
-
-mlx_status
-nvconfig_read_general_default_values(
-               IN mlx_utils *utils,
-               OUT struct mlx_nvconfig_conf_defaults *conf_def
-               );
-
-mlx_status
-nvconfig_read_rom_ini_values(
-               IN mlx_utils *utils,
-               OUT struct mlx_nvcofnig_romini *rom_ini
-               );
-#endif /* MLX_NVCONFIG_DEFAULTS_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_prm.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_prm.h
deleted file mode 100644 (file)
index 5b3af1e..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-#ifndef MLX_NVCONFIG_PRM_H_
-#define MLX_NVCONFIG_PRM_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../include/public/mlx_types.h"
-
-enum {
-       WAKE_ON_LAN_TYPE                                = 0x10,
-       VIRTUALIZATION_TYPE                             = 0x11,
-       VPI_LINK_TYPE                                   = 0x12,
-       BOOT_SETTINGS_EXT_TYPE                  = 0x2001,
-       BANNER_TO_TYPE                                  = 0x2010,
-       OCSD_OCBB_TYPE                                  = 0x2011,
-       FLOW_CONTROL_TYPE                               = 0x2020,
-       BOOT_SETTINGS_TYPE                              = 0x2021,
-       ISCSI_GENERAL_SETTINGS_TYPE             = 0x2100,
-       IB_BOOT_SETTING_TYPE                    = 0x2022,
-       IB_DHCP_SETTINGS_TYPE                   = 0x2023,
-       GLOPAL_PCI_SETTINGS_TYPE                = 0x80,
-       GLOPAL_PCI_CAPS_TYPE                    = 0x81,
-       GLOBAL_ROM_INI_TYPE                             = 0x100,
-
-       // Types for iSCSI strings
-       DHCP_VEND_ID                                    = 0x2101,
-       ISCSI_INITIATOR_IPV4_ADDR               = 0x2102,
-       ISCSI_INITIATOR_SUBNET                  = 0x2103,
-       ISCSI_INITIATOR_IPV4_GATEWAY    = 0x2104,
-       ISCSI_INITIATOR_IPV4_PRIM_DNS   = 0x2105,
-       ISCSI_INITIATOR_IPV4_SECDNS             = 0x2106,
-       ISCSI_INITIATOR_NAME                    = 0x2107,
-       ISCSI_INITIATOR_CHAP_ID                 = 0x2108,
-       ISCSI_INITIATOR_CHAP_PWD                = 0x2109,
-       ISCSI_INITIATOR_DHCP_CONF_TYPE  = 0x210a,
-
-       CONNECT_FIRST_TGT                               = 0x2200,
-       FIRST_TGT_IP_ADDRESS                    = 0x2201,
-       FIRST_TGT_TCP_PORT                              = 0x2202,
-       FIRST_TGT_BOOT_LUN                              = 0x2203,
-       FIRST_TGT_ISCSI_NAME                    = 0x2204,
-       FIRST_TGT_CHAP_ID                               = 0x2205,
-       FIRST_TGT_CHAP_PWD                              = 0x2207,
-};
-
-union mlx_nvconfig_nic_boot_conf {
-       struct {
-               mlx_uint32      vlan_id                         : 12;
-               mlx_uint32      link_speed                      : 4;
-               mlx_uint32      legacy_boot_prot        : 8;
-               mlx_uint32      boot_retry_count        : 3;
-               mlx_uint32      boot_strap_type         : 3;
-               mlx_uint32      en_vlan                         : 1;
-               mlx_uint32      en_option_rom           : 1;
-       };
-       mlx_uint32 dword;
-};
-
-union mlx_nvconfig_nic_boot_ext_conf {
-       struct {
-               mlx_uint32      linkup_timeout  : 8;
-               mlx_uint32      ip_ver                  : 2;
-               mlx_uint32      reserved0               : 22;
-       };
-       mlx_uint32 dword;
-};
-
-union mlx_nvconfig_rom_banner_timeout_conf {
-       struct {
-               mlx_uint32      rom_banner_to   : 4;
-               mlx_uint32      reserved                : 28;
-       };
-       mlx_uint32 dword;
-};
-
-union mlx_nvconfig_virt_conf {
-       struct {
-               mlx_uint32 reserved0                            :24;
-               mlx_uint32 pf_bar_size_valid            :1;
-               mlx_uint32 vf_bar_size_valid            :1;
-               mlx_uint32 num_pf_msix_valid            :1;
-               mlx_uint32 num_vf_msix_valid            :1;
-               mlx_uint32 num_pfs_valid                        :1;
-               mlx_uint32 fpp_valid                            :1;
-               mlx_uint32 full_vf_qos_valid            :1;
-               mlx_uint32 sriov_valid                  :1;
-               /*-------------------*/
-               mlx_uint32 num_of_vfs                           :16;
-               mlx_uint32 num_of_pfs                           :4;
-               mlx_uint32 reserved1                            :9;
-               mlx_uint32 fpp_en                                       :1;
-               mlx_uint32 full_vf_qos                  :1;
-               mlx_uint32 virt_mode                            :1; //sriov_en
-               /*-------------------*/
-               mlx_uint32 log_pf_uar_bar_size  :6;
-               mlx_uint32 log_vf_uar_bar_size  :6;
-               mlx_uint32 num_pf_msix                  :10;
-               mlx_uint32 num_vf_msix                  :10;
-       };
-       mlx_uint32 dword[3];
-};
-
-union mlx_nvconfig_virt_caps {
-       struct {
-               mlx_uint32 reserved0                            :24;
-               mlx_uint32 max_vfs_per_pf_valid :1;
-               mlx_uint32 max_total_msix_valid :1;
-               mlx_uint32 max_total_bar_valid  :1;
-               mlx_uint32 num_pfs_supported            :1;
-               mlx_uint32 num_vf_msix_supported        :1;
-               mlx_uint32 num_pf_msix_supported        :1;
-               mlx_uint32 vf_bar_size_supported        :1;
-               mlx_uint32 pf_bar_size_supported        :1;
-               /*-------------------*/
-               mlx_uint32 max_vfs_per_pf                       :16;
-               mlx_uint32 max_num_pfs                  :4;
-               mlx_uint32 reserved1                            :9;
-               mlx_uint32 fpp_support                  :1;
-               mlx_uint32 vf_qos_control_support       :1;
-               mlx_uint32 sriov_support                        :1;
-               /*-------------------*/
-               mlx_uint32 max_log_pf_uar_bar_size      :6;
-               mlx_uint32 max_log_vf_uar_bar_size      :6;
-               mlx_uint32 max_num_pf_msix                      :10;
-               mlx_uint32 max_num_vf_msix                      :10;
-               /*-------------------*/
-               mlx_uint32 max_total_msix;
-               /*-------------------*/
-               mlx_uint32 max_total_bar;
-       };
-       mlx_uint32 dword[5];
-};
-
-union mlx_nvconfig_iscsi_init_dhcp_conf {
-       struct {
-               mlx_uint32 reserved0            :30;
-               mlx_uint32 dhcp_iscsi_en        :1;
-               mlx_uint32 ipv4_dhcp_en :1;
-
-       };
-       mlx_uint32 dword;
-};
-
-union mlx_nvconfig_nic_ib_boot_conf {
-       struct {
-               mlx_uint32      boot_pkey                       : 16;
-               mlx_uint32      reserved0                       : 16;
-       };
-       mlx_uint32 dword;
-};
-
-union mlx_nvconfig_wol_conf {
-       struct {
-               mlx_uint32      reserved0               :9;
-               mlx_uint32      en_wol_passwd   :1;
-               mlx_uint32      en_wol_magic    :1;
-               mlx_uint32      reserved1               :21;
-               mlx_uint32      reserved2               :32;
-       };
-       mlx_uint32 dword[2];
-};
-
-union mlx_nvconfig_iscsi_general {
-       struct {
-               mlx_uint32      reserved0                       :22;
-               mlx_uint32      boot_to_target          :2;
-               mlx_uint32      reserved1                       :2;
-               mlx_uint32      vlan_en                         :1;
-               mlx_uint32      tcp_timestamps_en       :1;
-               mlx_uint32      chap_mutual_auth_en     :1;
-               mlx_uint32      chap_auth_en            :1;
-               mlx_uint32      reserved2                       :2;
-               /*-------------------*/
-               mlx_uint32      vlan                            :12;
-               mlx_uint32      reserved3                       :20;
-               /*-------------------*/
-               mlx_uint32      lun_busy_retry_count:8;
-               mlx_uint32      link_up_delay_time      :8;
-               mlx_uint32      reserved4                       :16;
-       };
-       mlx_uint32 dword[3];
-};
-
-union mlx_nvconfig_ib_dhcp_conf {
-       struct {
-               mlx_uint32 reserved                     :24;
-               mlx_uint32 client_identifier    :4;
-               mlx_uint32 mac_admin_bit                :4;
-       };
-       mlx_uint32 dword;
-};
-
-union mlx_nvconfig_ocsd_ocbb_conf {
-       struct {
-               mlx_uint32      reserved                :31;
-               mlx_uint32      ocsd_ocbb_en    :1;
-       };
-       mlx_uint32 dword;
-};
-
-union mlx_nvconfig_vpi_link_conf {
-       struct {
-               mlx_uint32      network_link_type       :2;
-               mlx_uint32      default_link_type       :2;
-               mlx_uint32      reserved                :28;
-       };
-       mlx_uint32 dword;
-};
-
-struct  mlx_nvcofnig_romini {
-       mlx_uint32 reserved0    :1;
-       mlx_uint32 shared_memory_en     :1;
-       mlx_uint32 hii_vpi_en   :1;
-       mlx_uint32 tech_enum    :1;
-       mlx_uint32 reserved1    :4;
-       mlx_uint32 static_component_name_string :1;
-       mlx_uint32 hii_iscsi_configuration      :1;
-       mlx_uint32 hii_ibm_aim  :1;
-       mlx_uint32 hii_platform_setup   :1;
-       mlx_uint32 hii_bdf_decimal      :1;
-       mlx_uint32 hii_read_only        :1;
-       mlx_uint32 reserved2    :10;
-       mlx_uint32 mac_enum             :1;
-       mlx_uint32 port_enum    :1;
-       mlx_uint32 flash_en             :1;
-       mlx_uint32 fmp_en               :1;
-       mlx_uint32 bofm_en              :1;
-       mlx_uint32 platform_to_driver_en                :1;
-       mlx_uint32 hii_en               :1;
-       mlx_uint32 undi_en              :1;
-       /* -------------- */
-       mlx_uint64 dhcp_user_class;
-       /* -------------- */
-       mlx_uint32 reserved3    :22;
-       mlx_uint32 uri_boot_retry_delay :4;
-       mlx_uint32 uri_boot_retry       :4;
-       mlx_uint32 option_rom_debug     :1;
-       mlx_uint32 promiscuous_vlan     :1;
-};
-
-#endif /* MLX_NVCONFIG_PRM_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_ocbb/mlx_ocbb.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_ocbb/mlx_ocbb.c
deleted file mode 100644 (file)
index 3852efb..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_ocbb.h"
-#include "mlx_icmd.h"
-#include "mlx_bail.h"
-
-mlx_status
-mlx_ocbb_init (
-       IN mlx_utils *utils,
-       IN mlx_uint64 address
-       )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct mlx_ocbb_init ocbb_init;
-       ocbb_init.address_hi = (mlx_uint32)(address >> 32);
-       ocbb_init.address_lo = (mlx_uint32)address;
-
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       status = mlx_icmd_send_command(
-                       utils,
-                       OCBB_INIT,
-                       &ocbb_init,
-                       sizeof(ocbb_init),
-                       0
-                       );
-       MLX_CHECK_STATUS(utils, status, icmd_err, "mlx_icmd_send_command failed");
-icmd_err:
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_ocbb_query_header_status (
-       IN mlx_utils *utils,
-       OUT mlx_uint8 *ocbb_status
-       )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct mlx_ocbb_query_status ocbb_query_status;
-
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       status = mlx_icmd_send_command(
-                       utils,
-                       OCBB_QUERY_HEADER_STATUS,
-                       &ocbb_query_status,
-                       0,
-                       sizeof(ocbb_query_status)
-                       );
-       MLX_CHECK_STATUS(utils, status, icmd_err, "mlx_icmd_send_command failed");
-       *ocbb_status = ocbb_query_status.status;
-icmd_err:
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_ocbb_query_etoc_status (
-       IN mlx_utils *utils,
-       OUT mlx_uint8 *ocbb_status
-       )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct mlx_ocbb_query_status ocbb_query_status;
-
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       status = mlx_icmd_send_command(
-                       utils,
-                       OCBB_QUERY_ETOC_STATUS,
-                       &ocbb_query_status,
-                       0,
-                       sizeof(ocbb_query_status)
-                       );
-       MLX_CHECK_STATUS(utils, status, icmd_err, "mlx_icmd_send_command failed");
-       *ocbb_status = ocbb_query_status.status;
-icmd_err:
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_ocbb_set_event (
-       IN mlx_utils *utils,
-       IN mlx_uint64                   event_data,
-       IN mlx_uint8                    event_number,
-       IN mlx_uint8                    event_length,
-       IN mlx_uint8                    data_length,
-       IN mlx_uint8                    data_start_offset
-       )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct mlx_ocbb_set_event ocbb_event;
-
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       ocbb_event.data_length = data_length;
-       ocbb_event.data_start_offset = data_start_offset;
-       ocbb_event.event_number = event_number;
-       ocbb_event.event_data = event_data;
-       ocbb_event.event_length = event_length;
-       status = mlx_icmd_send_command(
-                       utils,
-                       OCBB_QUERY_SET_EVENT,
-                       &ocbb_event,
-                       sizeof(ocbb_event),
-                       0
-                       );
-       MLX_CHECK_STATUS(utils, status, icmd_err, "mlx_icmd_send_command failed");
-icmd_err:
-bad_param:
-       return status;
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_ocbb/mlx_ocbb.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_ocbb/mlx_ocbb.h
deleted file mode 100644 (file)
index 49312b9..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef MLX_OCBB_H_
-#define MLX_OCBB_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_utils.h"
-
-#define MLX_OCBB_EVENT_DATA_SIZE 2
-struct mlx_ocbb_init {
-       mlx_uint32 address_hi;
-       mlx_uint32 address_lo;
-};
-
-struct mlx_ocbb_query_status {
-       mlx_uint32 reserved     :24;
-       mlx_uint32 status       :8;
-};
-
-struct mlx_ocbb_set_event {
-       mlx_uint64 event_data;
-       mlx_uint32 event_number :8;
-       mlx_uint32 event_length :8;
-       mlx_uint32 data_length  :8;
-       mlx_uint32 data_start_offset    :8;
-};
-
-mlx_status
-mlx_ocbb_init (
-       IN mlx_utils *utils,
-       IN mlx_uint64 address
-       );
-
-mlx_status
-mlx_ocbb_query_header_status (
-       IN mlx_utils *utils,
-       OUT mlx_uint8 *ocbb_status
-       );
-
-mlx_status
-mlx_ocbb_query_etoc_status (
-       IN mlx_utils *utils,
-       OUT mlx_uint8 *ocbb_status
-       );
-
-mlx_status
-mlx_ocbb_set_event (
-       IN mlx_utils *utils,
-       IN mlx_uint64                   EventData,
-       IN mlx_uint8                    EventNumber,
-       IN mlx_uint8                    EventLength,
-       IN mlx_uint8                    DataLength,
-       IN mlx_uint8                    DataStartOffset
-       );
-#endif /* MLX_OCBB_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_reg_access/mlx_reg_access.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_reg_access/mlx_reg_access.c
deleted file mode 100644 (file)
index 143ab1b..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../mlx_lib/mlx_reg_access/mlx_reg_access.h"
-#include "../../include/public/mlx_icmd.h"
-#include "../../include/public/mlx_bail.h"
-#include "../../include/public/mlx_memory.h"
-
-static
-mlx_status
-init_operation_tlv(
-               IN struct mail_box_tlv *mail_box_tlv,
-               IN mlx_uint16  reg_id,
-               IN REG_ACCESS_OPT reg_opt
-               )
-{
-#define TLV_OPERATION 1
-       mail_box_tlv->operation_tlv.Type                        = TLV_OPERATION;
-#define MAD_CLASS_REG_ACCESS 1
-       mail_box_tlv->operation_tlv.cls                 = MAD_CLASS_REG_ACCESS;
-#define TLV_OPERATION_SIZE 4
-       mail_box_tlv->operation_tlv.len                 = TLV_OPERATION_SIZE;
-       mail_box_tlv->operation_tlv.method                      = reg_opt;
-       mail_box_tlv->operation_tlv.register_id = reg_id;
-       return MLX_SUCCESS;
-}
-
-mlx_status
-mlx_reg_access(
-               IN mlx_utils *utils,
-               IN mlx_uint16  reg_id,
-               IN REG_ACCESS_OPT reg_opt,
-               IN OUT mlx_void *reg_data,
-        IN mlx_size reg_size,
-        OUT mlx_uint32 *reg_status
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct mail_box_tlv mail_box_tlv;
-
-       if (utils == NULL || reg_data == NULL || reg_status == NULL
-                       || reg_size > REG_ACCESS_MAX_REG_SIZE) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       mlx_memory_set(utils, &mail_box_tlv, 0, sizeof(mail_box_tlv));
-
-       init_operation_tlv(&mail_box_tlv, reg_id, reg_opt);
-
-#define REG_ACCESS_TLV_REG 3
-#define REG_TLV_HEADER_LEN 4
-#define OP_TLV_SIZE 16
-       mail_box_tlv.reg_tlv.Type = REG_ACCESS_TLV_REG;
-       mail_box_tlv.reg_tlv.len  = ((reg_size + REG_TLV_HEADER_LEN + 3) >> 2); // length is in dwords round up
-       mlx_memory_cpy(utils, &mail_box_tlv.reg_tlv.data, reg_data, reg_size);
-
-       reg_size += OP_TLV_SIZE + REG_TLV_HEADER_LEN;
-
-       status = mlx_icmd_send_command(utils, FLASH_REG_ACCESS, &mail_box_tlv, reg_size, reg_size);
-       MLX_CHECK_STATUS(utils, status, icmd_err, "failed to send icmd");
-
-       mlx_memory_cpy(utils, reg_data, &mail_box_tlv.reg_tlv.data,
-                       reg_size - (OP_TLV_SIZE + REG_TLV_HEADER_LEN));
-
-       *reg_status = mail_box_tlv.operation_tlv.status;
-icmd_err:
-bad_param:
-       return status;
-}
-
-
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_reg_access/mlx_reg_access.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_reg_access/mlx_reg_access.h
deleted file mode 100644 (file)
index 9fbf516..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#ifndef MLX_REG_ACCESS_H_
-#define MLX_REG_ACCESS_H_
-
-#include "../../include/public/mlx_icmd.h"
-
-#define REG_ACCESS_MAX_REG_SIZE 236
-
-typedef enum {
-  REG_ACCESS_READ = 1,
-  REG_ACCESS_WRITE = 2,
-} REG_ACCESS_OPT;
-
-typedef enum {
-  TLV_ACCESS_DEFAULT_DIS = 0,
-  TLV_ACCESS_DEFAULT_EN = 1,
-} NV_DEFAULT_OPT;
-
-#define REG_ID_NVDA  0x9024
-#define REG_ID_NVDI  0x9025
-#define REG_ID_NVIA 0x9029
-#define REG_ID_MLCR  0x902b
-#define REG_ID_NVQC  0x9030
-#define REG_ID_MFRL 0x9028
-#define REG_ID_PTYS 0x5004
-#define REG_ID_PMTU 0x5003
-
-struct operation_tlv {
-    mlx_uint32 reserved0       :8;    /* bit_offset:0 */    /* element_size: 8 */
-    mlx_uint32 status          :7;    /* bit_offset:8 */    /* element_size: 7 */
-    mlx_uint32 dr                      :1;    /* bit_offset:15 */    /* element_size: 1 */
-    mlx_uint32 len                     :11;    /* bit_offset:16 */    /* element_size: 11 */
-    mlx_uint32 Type            :5;    /* bit_offset:27 */    /* element_size: 5 */
-    mlx_uint32 cls                     :8;    /* bit_offset:32 */    /* element_size: 8 */
-    mlx_uint32 method          :7;    /* bit_offset:40 */    /* element_size: 7 */
-    mlx_uint32 r                       :1;    /* bit_offset:47 */    /* element_size: 1 */
-    mlx_uint32 register_id     :16;    /* bit_offset:48 */    /* element_size: 16 */
-    mlx_uint64 tid                     ;    /* bit_offset:64 */    /* element_size: 64 */
-};
-
-struct reg_tlv {
-       mlx_uint32      reserved0       :16;    /* bit_offset:0 */    /* element_size: 16 */
-       mlx_uint32      len             :11;    /* bit_offset:16 */    /* element_size: 11 */
-       mlx_uint32      Type            :5;    /* bit_offset:27 */    /* element_size: 5 */
-       mlx_uint8       data[REG_ACCESS_MAX_REG_SIZE];
-};
-
-struct mail_box_tlv {
-       struct operation_tlv operation_tlv;
-       struct reg_tlv reg_tlv;
-};
-mlx_status
-mlx_reg_access(
-               IN mlx_utils *utils,
-               IN mlx_uint16  reg_id,
-               IN REG_ACCESS_OPT reg_opt,
-               IN OUT mlx_void *reg_data,
-        IN mlx_size reg_size,
-        OUT mlx_uint32 *reg_status
-               );
-
-#endif /* MLX_REG_ACCESS_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.c
deleted file mode 100644 (file)
index 65d04c9..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../mlx_lib/mlx_vmac/mlx_vmac.h"
-#include "../../include/public/mlx_icmd.h"
-#include "../../include/public/mlx_bail.h"
-
-mlx_status
-mlx_vmac_query_virt_mac (
-       IN mlx_utils *utils,
-       OUT struct mlx_vmac_query_virt_mac *virt_mac
-       )
-{
-       mlx_status status = MLX_SUCCESS;
-       if (utils == NULL || virt_mac == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       status = mlx_icmd_send_command(
-                       utils,
-                       QUERY_VIRTUAL_MAC,
-                       virt_mac,
-                       0,
-                       sizeof(*virt_mac)
-                       );
-       MLX_CHECK_STATUS(utils, status, icmd_err, "mlx_icmd_send_command failed");
-icmd_err:
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_vmac_set_virt_mac (
-       IN mlx_utils *utils,
-       OUT struct mlx_vmac_set_virt_mac *virt_mac
-       )
-{
-       mlx_status status = MLX_SUCCESS;
-       if (utils == NULL || virt_mac == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       status = mlx_icmd_send_command(
-                       utils,
-                       SET_VIRTUAL_MAC,
-                       virt_mac,
-                       sizeof(*virt_mac),
-                       0
-                       );
-       MLX_CHECK_STATUS(utils, status, icmd_err, "mlx_icmd_send_command failed");
-icmd_err:
-bad_param:
-       return status;
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.h
deleted file mode 100644 (file)
index 2214d91..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef MLX_VMAC_H_
-#define MLX_VMAC_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../include/public/mlx_utils.h"
-
-struct mlx_vmac_query_virt_mac {
-       mlx_uint32 reserved0    :30;
-       mlx_uint32 mac_aux_v    :1;
-       mlx_uint32 virtual_mac_en       :1;
-       mlx_uint32 parmanent_mac_high   :16;
-       mlx_uint32 reserved1    :16;
-       mlx_uint32 parmanent_mac_low    :32;
-       mlx_uint32 virtual_mac_high     :16;
-       mlx_uint32 Reserved2    :16;
-       mlx_uint32 virtual_mac_low      :32;
-};
-
-struct mlx_vmac_set_virt_mac {
-       mlx_uint32 Reserved0    :30;
-       mlx_uint32 mac_aux_v    :1;
-       mlx_uint32 virtual_mac_en       :1;
-       mlx_uint32 reserved1    :32;
-       mlx_uint32 reserved2    :32;
-       mlx_uint32 virtual_mac_high;
-       mlx_uint32 virtual_mac_low;
-};
-
-mlx_status
-mlx_vmac_query_virt_mac (
-       IN mlx_utils *utils,
-       OUT struct mlx_vmac_query_virt_mac *virt_mac
-       );
-
-mlx_status
-mlx_vmac_set_virt_mac (
-       IN mlx_utils *utils,
-       OUT struct mlx_vmac_set_virt_mac *virt_mac
-       );
-#endif /* MLX_VMAC_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_wol_rol/mlx_wol_rol.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_wol_rol/mlx_wol_rol.c
deleted file mode 100644 (file)
index a6c23c4..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "mlx_wol_rol.h"
-#include "mlx_icmd.h"
-#include "mlx_memory.h"
-#include "mlx_bail.h"
-
-mlx_status
-mlx_set_wol (
-       IN mlx_utils *utils,
-       IN mlx_uint8 wol_mask
-       )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct mlx_wol_rol wol_rol;
-
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       mlx_memory_set(utils, &wol_rol, 0, sizeof(wol_rol));
-       wol_rol.wol_mode_valid = TRUE;
-       wol_rol.wol_mode = wol_mask;
-       status = mlx_icmd_send_command(
-                       utils,
-                       SET_WOL_ROL,
-                       &wol_rol,
-                       sizeof(wol_rol),
-                       0
-                       );
-       MLX_CHECK_STATUS(utils, status, icmd_err, "mlx_icmd_send_command failed");
-icmd_err:
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_query_wol (
-       IN mlx_utils *utils,
-       OUT mlx_uint8 *wol_mask
-       )
-{
-       mlx_status status = MLX_SUCCESS;
-       struct mlx_wol_rol wol_rol;
-
-       if (utils == NULL || wol_mask == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       mlx_memory_set(utils, &wol_rol, 0, sizeof(wol_rol));
-       status = mlx_icmd_send_command(
-                       utils,
-                       QUERY_WOL_ROL,
-                       &wol_rol,
-                       0,
-                       sizeof(wol_rol)
-                       );
-       MLX_CHECK_STATUS(utils, status, icmd_err, "mlx_icmd_send_command failed");
-       *wol_mask = wol_rol.wol_mode;
-icmd_err:
-bad_param:
-       return status;
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_wol_rol/mlx_wol_rol.h b/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_wol_rol/mlx_wol_rol.h
deleted file mode 100644 (file)
index 610419d..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef MLX_WOL_ROL_H_
-#define MLX_WOL_ROL_H_
-
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-
-#include "mlx_utils.h"
-
-typedef enum {
-       WOL_MODE_DISABLE = 0x0,
-       WOL_MODE_SECURE = 0x2,
-       WOL_MODE_MAGIC = 0x4,
-       WOL_MODE_ARP = 0x8,
-       WOL_MODE_BC = 0x10,
-       WOL_MODE_MC = 0x20,
-       WOL_MODE_UC = 0x40,
-       WOL_MODE_PHY = 0x80,
-} WOL_MODE;
-
-struct mlx_wol_rol {
-       mlx_uint32 reserved0    :32;
-       mlx_uint32 reserved1    :32;
-       mlx_uint32 wol_mode             :8;
-       mlx_uint32 rol_mode             :8;
-       mlx_uint32 reserved3    :14;
-       mlx_uint32 wol_mode_valid       :1;
-       mlx_uint32 rol_mode_valid       :1;
-};
-
-mlx_status
-mlx_set_wol (
-       IN mlx_utils *utils,
-       IN mlx_uint8 wol_mask
-       );
-
-mlx_status
-mlx_query_wol (
-       IN mlx_utils *utils,
-       OUT mlx_uint8 *wol_mask
-       );
-
-#endif /* MLX_WOL_ROL_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/src/private/uefi/mlx_logging_impl.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/src/private/uefi/mlx_logging_impl.c
deleted file mode 100644 (file)
index 4386ad9..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-MlxDebugLogImpl()
-               {
-       DBGC((DEBUG),"");
-               }
-MlxInfoLogImpl()
-{
-       DBGC((INFO),"");
-                       }
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_icmd.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_icmd.c
deleted file mode 100644 (file)
index f7d365d..0000000
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../include/public/mlx_bail.h"
-#include "../../include/public/mlx_icmd.h"
-#include "../../include/public/mlx_pci_gw.h"
-#include "../../include/public/mlx_utils.h"
-
-static
-mlx_status
-mlx_icmd_get_semaphore(
-                               IN mlx_utils *utils
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 retries = 0;
-       mlx_uint32 semaphore_id;
-       mlx_uint32 buffer;
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_param;
-       }
-
-       status = mlx_utils_rand(utils, &semaphore_id);
-       MLX_CHECK_STATUS(utils, status, rand_err, "failed to get random number");
-#define ICMD_GET_SEMAPHORE_TRIES 2560
-       for (retries = 0 ; retries < ICMD_GET_SEMAPHORE_TRIES ; retries++) {
-               status = mlx_pci_gw_read( utils, PCI_GW_SPACE_SEMAPHORE,
-                                       MLX_ICMD_SEMAPHORE_ADDR, &buffer);
-               MLX_CHECK_STATUS(utils, status, read_err, "failed to read icmd semaphore");
-               if (buffer != 0) {
-                       mlx_utils_delay_in_ms(10);
-                       continue;
-               }
-               mlx_pci_gw_write( utils, PCI_GW_SPACE_SEMAPHORE,
-                                                       MLX_ICMD_SEMAPHORE_ADDR, semaphore_id);
-               MLX_CHECK_STATUS(utils, status, set_err, "failed to set icmd semaphore");
-               status = mlx_pci_gw_read( utils, PCI_GW_SPACE_SEMAPHORE,
-                                                       MLX_ICMD_SEMAPHORE_ADDR, &buffer);
-               MLX_CHECK_STATUS(utils, status, read_err, "failed to read icmd semaphore");
-               if (semaphore_id == buffer) {
-                       status = MLX_SUCCESS;
-                       utils->icmd.took_semaphore = TRUE;
-                       break;
-               }
-               mlx_utils_delay_in_ms(10);
-       }
-       if (semaphore_id != buffer) {
-               status = MLX_FAILED;
-       }
-read_err:
-set_err:
-rand_err:
-invalid_param:
-       return status;
-}
-static
-mlx_status
-mlx_icmd_clear_semaphore(
-                               IN mlx_utils *utils
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_param;
-       }
-
-       if (utils->icmd.took_semaphore == FALSE) {
-               goto semaphore_not_taken;
-       }
-       status = mlx_pci_gw_write( utils, PCI_GW_SPACE_SEMAPHORE,
-                       MLX_ICMD_SEMAPHORE_ADDR, 0);
-       MLX_CHECK_STATUS(utils, status, read_err, "failed to clear icmd semaphore");
-
-       utils->icmd.took_semaphore = FALSE;
-read_err:
-semaphore_not_taken:
-invalid_param:
-       return status;
-}
-
-static
-mlx_status
-mlx_icmd_init(
-                               IN mlx_utils *utils
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_param;
-       }
-       if (utils->icmd.icmd_opened == TRUE) {
-               goto already_opened;
-       }
-
-       utils->icmd.took_semaphore = FALSE;
-
-       status = mlx_pci_gw_read( utils, PCI_GW_SPACE_ALL_ICMD,
-                       MLX_ICMD_MB_SIZE_ADDR, &utils->icmd.max_cmd_size);
-       MLX_CHECK_STATUS(utils, status, read_err, "failed to read icmd mail box size");
-
-       utils->icmd.icmd_opened = TRUE;
-read_err:
-already_opened:
-invalid_param:
-       return status;
-}
-
-static
-mlx_status
-mlx_icmd_set_opcode(
-                               IN mlx_utils *utils,
-                               IN mlx_uint16 opcode
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 buffer;
-
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_param;
-       }
-
-       status = mlx_pci_gw_read( utils, PCI_GW_SPACE_ALL_ICMD,
-                               MLX_ICMD_CTRL_ADDR, &buffer);
-       MLX_CHECK_STATUS(utils, status, read_err, "failed to read icmd ctrl");
-
-#define MLX_ICMD_OPCODE_ALIGN 16
-#define MLX_ICMD_OPCODE_MASK 0xffff
-
-       buffer = buffer & ~(MLX_ICMD_OPCODE_MASK << MLX_ICMD_OPCODE_ALIGN);
-       buffer = buffer | (opcode << MLX_ICMD_OPCODE_ALIGN);
-
-       status = mlx_pci_gw_write( utils, PCI_GW_SPACE_ALL_ICMD,
-                                       MLX_ICMD_CTRL_ADDR, buffer);
-       MLX_CHECK_STATUS(utils, status, write_err, "failed to write icmd ctrl");
-write_err:
-read_err:
-invalid_param:
-       return status;
-}
-
-static
-mlx_status
-mlx_icmd_go(
-                       IN mlx_utils *utils
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 buffer;
-       mlx_uint32 busy;
-       mlx_uint32 wait_iteration = 0;
-
-       if (utils == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_param;
-       }
-
-       status = mlx_pci_gw_read( utils, PCI_GW_SPACE_ALL_ICMD,
-                               MLX_ICMD_CTRL_ADDR, &buffer);
-       MLX_CHECK_STATUS(utils, status, read_err, "failed to read icmd ctrl");
-
-#define MLX_ICMD_BUSY_ALIGN 0
-#define MLX_ICMD_BUSY_MASK 0x1
-
-       busy = (buffer >> MLX_ICMD_BUSY_ALIGN) & MLX_ICMD_BUSY_MASK;
-       if (busy != 0) {
-               status = MLX_FAILED;
-               goto already_busy;
-       }
-
-       buffer = buffer | (1 << MLX_ICMD_BUSY_ALIGN);
-
-       status = mlx_pci_gw_write( utils, PCI_GW_SPACE_ALL_ICMD,
-                                       MLX_ICMD_CTRL_ADDR, buffer);
-       MLX_CHECK_STATUS(utils, status, write_err, "failed to write icmd ctrl");
-
-#define MLX_ICMD_BUSY_MAX_ITERATIONS 1024
-       do {
-               if (++wait_iteration > MLX_ICMD_BUSY_MAX_ITERATIONS) {
-                       status = MLX_FAILED;
-                       MLX_DEBUG_ERROR(utils, "ICMD time out");
-                       goto busy_timeout;
-               }
-
-               mlx_utils_delay_in_ms(10);
-               status = mlx_pci_gw_read( utils, PCI_GW_SPACE_ALL_ICMD,
-                                       MLX_ICMD_CTRL_ADDR, &buffer);
-               MLX_CHECK_STATUS(utils, status, read_err, "failed to read icmd ctrl");
-               busy = (buffer >> MLX_ICMD_BUSY_ALIGN) & MLX_ICMD_BUSY_MASK;
-       } while (busy != 0);
-
-busy_timeout:
-write_err:
-already_busy:
-read_err:
-invalid_param:
-       return status;
-}
-
-static
-mlx_status
-mlx_icmd_get_status(
-                       IN mlx_utils *utils,
-                       OUT mlx_uint32 *out_status
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 buffer;
-
-       if (utils == NULL || out_status == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_param;
-       }
-
-       status = mlx_pci_gw_read( utils, PCI_GW_SPACE_ALL_ICMD,
-                               MLX_ICMD_CTRL_ADDR, &buffer);
-       MLX_CHECK_STATUS(utils, status, read_err, "failed to read icmd ctrl");
-
-#define MLX_ICMD_STATUS_ALIGN 8
-#define MLX_ICMD_STATUS_MASK 0xff
-
-       *out_status = (buffer >> MLX_ICMD_STATUS_ALIGN) & MLX_ICMD_STATUS_MASK;
-
-read_err:
-invalid_param:
-       return status;
-}
-
-static
-mlx_status
-mlx_icmd_write_buffer(
-               IN mlx_utils *utils,
-               IN mlx_void* data,
-               IN mlx_uint32 data_size
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 data_offset = 0;
-       mlx_size dword_size = sizeof(mlx_uint32);
-
-       if (utils == NULL || data == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_param;
-       }
-
-       for (data_offset = 0 ; data_offset*dword_size < data_size ; data_offset++) {
-               status = mlx_pci_gw_write( utils, PCI_GW_SPACE_ALL_ICMD,
-                                                       MLX_ICMD_MB_ADDR + data_offset*dword_size,
-                                                       ((mlx_uint32*)data)[data_offset]);
-               MLX_CHECK_STATUS(utils, status, write_err, "failed to write icmd MB");
-       }
-write_err:
-invalid_param:
-       return status;
-}
-
-
-static
-mlx_status
-mlx_icmd_read_buffer(
-               IN mlx_utils *utils,
-               OUT mlx_void* data,
-               IN mlx_uint32 data_size
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 data_offset = 0;
-       mlx_size dword_size = sizeof(mlx_uint32);
-
-       if (utils == NULL || data == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_param;
-       }
-
-       for (data_offset = 0 ; data_offset*dword_size < data_size ; data_offset++) {
-               status = mlx_pci_gw_read( utils, PCI_GW_SPACE_ALL_ICMD,
-                                                       MLX_ICMD_MB_ADDR + data_offset*dword_size,
-                                                       (mlx_uint32*)data + data_offset);
-               MLX_CHECK_STATUS(utils, status, read_err, "failed to read icmd MB");
-       }
-read_err:
-invalid_param:
-       return status;
-}
-mlx_status
-mlx_icmd_send_command(
-                               IN mlx_utils *utils,
-                               IN  mlx_uint16 opcode,
-                               IN OUT mlx_void* data,
-                               IN mlx_uint32 write_data_size,
-                               IN mlx_uint32 read_data_size
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint32 icmd_status = MLX_FAILED;
-
-       if (utils == NULL || data == NULL) {
-               status = MLX_INVALID_PARAMETER;
-               goto invalid_param;
-       }
-       status = mlx_icmd_init(utils);
-       MLX_CHECK_STATUS(utils, status, open_err, "failed to open icmd");
-
-       if (write_data_size > utils->icmd.max_cmd_size ||
-                       read_data_size > utils->icmd.max_cmd_size) {
-               status = MLX_INVALID_PARAMETER;
-               goto size_err;
-       }
-
-       status = mlx_icmd_get_semaphore(utils);
-       MLX_CHECK_STATUS(utils, status, semaphore_err, "failed to get icmd semaphore");
-
-       status = mlx_icmd_set_opcode(utils, opcode);
-       MLX_CHECK_STATUS(utils, status, opcode_err, "failed to set icmd opcode");
-
-       if (write_data_size != 0) {
-               status = mlx_icmd_write_buffer(utils, data, write_data_size);
-               MLX_CHECK_STATUS(utils, status, opcode_err, "failed to write icmd MB");
-       }
-
-       status = mlx_icmd_go(utils);
-       MLX_CHECK_STATUS(utils, status, go_err, "failed to activate icmd");
-
-       status = mlx_icmd_get_status(utils, &icmd_status);
-       MLX_CHECK_STATUS(utils, status, get_status_err, "failed to set icmd opcode");
-
-       if (icmd_status != 0) {
-               MLX_DEBUG_ERROR(utils, "icmd failed with status = %d\n", icmd_status);
-               status = MLX_FAILED;
-               goto icmd_failed;
-       }
-       if (read_data_size != 0) {
-               status = mlx_icmd_read_buffer(utils, data, read_data_size);
-               MLX_CHECK_STATUS(utils, status, read_err, "failed to read icmd MB");
-       }
-read_err:
-icmd_failed:
-get_status_err:
-go_err:
-opcode_err:
-       mlx_icmd_clear_semaphore(utils);
-semaphore_err:
-size_err:
-open_err:
-invalid_param:
-       return status;
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_memory.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_memory.c
deleted file mode 100644 (file)
index 5aa5a53..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <stddef.h>
-#include "../../include/private/mlx_memory_priv.h"
-#include "../../include/public/mlx_memory.h"
-
-mlx_status
-mlx_memory_alloc(
-                               IN mlx_utils *utils,
-                               IN mlx_size size,
-                               OUT mlx_void **ptr
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       *ptr = NULL;
-       if ( utils == NULL || size == 0 || *ptr != NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       status = mlx_memory_alloc_priv(utils, size, ptr);
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_memory_zalloc(
-                               IN mlx_utils *utils,
-                               IN mlx_size size,
-                               OUT mlx_void **ptr
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       *ptr = NULL;
-       if ( utils == NULL || size == 0 || *ptr != NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       status = mlx_memory_zalloc_priv(utils, size, ptr);
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_memory_free(
-                               IN mlx_utils *utils,
-                               IN mlx_void **ptr
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       if ( utils == NULL ||  ptr == NULL || *ptr == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       status = mlx_memory_free_priv(utils, *ptr);
-       *ptr = NULL;
-bad_param:
-       return status;
-}
-mlx_status
-mlx_memory_alloc_dma(
-                                       IN mlx_utils *utils,
-                                       IN mlx_size size ,
-                                       IN mlx_size align,
-                                       OUT mlx_void **ptr
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       *ptr = NULL;
-       if ( utils == NULL || size == 0 || *ptr != NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       status = mlx_memory_alloc_dma_priv(utils, size, align, ptr);
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_memory_free_dma(
-                                       IN mlx_utils *utils,
-                                       IN mlx_size size ,
-                                       IN mlx_void **ptr
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       if ( utils == NULL || size == 0 || ptr == NULL || *ptr == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       status = mlx_memory_free_dma_priv(utils, size, *ptr);
-       *ptr = NULL;
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_memory_map_dma(
-                                       IN mlx_utils *utils,
-                                       IN mlx_void *addr ,
-                                       IN mlx_size number_of_bytes,
-                                       OUT mlx_physical_address *phys_addr,
-                                       OUT mlx_void **mapping
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       if ( utils == NULL || phys_addr == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       status = mlx_memory_map_dma_priv(utils, addr, number_of_bytes, phys_addr, mapping);
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_memory_ummap_dma(
-                                       IN mlx_utils *utils,
-                                       IN mlx_void *mapping
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       if ( utils == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       status = mlx_memory_ummap_dma_priv(utils, mapping);
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_memory_cmp(
-                       IN mlx_utils *utils,
-                       IN mlx_void *first_block,
-                       IN mlx_void *second_block,
-                       IN mlx_size size,
-                       OUT mlx_uint32 *out
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       if ( utils == NULL || first_block == NULL || second_block == NULL ||
-                       out == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       status = mlx_memory_cmp_priv(utils, first_block, second_block, size, out);
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_memory_set(
-                                       IN mlx_utils *utils,
-                                       IN mlx_void *block,
-                                       IN mlx_int32 value,
-                                       IN mlx_size size
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       if ( utils == NULL || block == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       status = mlx_memory_set_priv(utils, block, value, size);
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_memory_cpy(
-                       IN mlx_utils *utils,
-                       OUT mlx_void *destination_buffer,
-                       IN mlx_void *source_buffer,
-                       IN mlx_size length
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       if ( utils == NULL || destination_buffer == NULL || source_buffer == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       status = mlx_memory_cpy_priv(utils, destination_buffer, source_buffer, length);
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_memory_cpu_to_be32(
-                       IN mlx_utils *utils,
-                       IN mlx_uint32 source,
-                       IN mlx_uint32 *destination
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       if ( utils == NULL || destination == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       status = mlx_memory_cpu_to_be32_priv(utils, source, destination);
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_memory_be32_to_cpu(
-                       IN mlx_utils *utils,
-                       IN mlx_uint32 source,
-                       IN mlx_uint32 *destination
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       if ( utils == NULL || destination == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-       status = mlx_memory_be32_to_cpu_priv(utils, source, destination);
-bad_param:
-       return status;
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_pci.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_pci.c
deleted file mode 100644 (file)
index 91c44d9..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <stddef.h>
-#include "../../include/private/mlx_pci_priv.h"
-#include "../../include/public/mlx_pci.h"
-
-mlx_status
-mlx_pci_init(
-                       IN mlx_utils *utils
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       if( utils == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto bail;
-       }
-       status = mlx_pci_init_priv(utils);
-bail:
-       return status;
-}
-
-mlx_status
-mlx_pci_read(
-                       IN mlx_utils *utils,
-                       IN mlx_pci_width width,
-                       IN mlx_uint32 offset,
-                       IN mlx_uintn count,
-                       OUT mlx_void *buffer
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       if( utils == NULL || count == 0){
-               status = MLX_INVALID_PARAMETER;
-               goto bail;
-       }
-       status = mlx_pci_read_priv(utils, width, offset, count, buffer);
-bail:
-       return status;
-}
-
-mlx_status
-mlx_pci_write(
-                       IN mlx_utils *utils,
-                       IN mlx_pci_width width,
-                       IN mlx_uint32 offset,
-                       IN mlx_uintn count,
-                       IN mlx_void *buffer
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       if( utils == NULL || count == 0){
-               status = MLX_INVALID_PARAMETER;
-               goto bail;
-       }
-       status = mlx_pci_write_priv(utils, width, offset, count, buffer);
-bail:
-       return status;
-}
-
-mlx_status
-mlx_pci_mem_read(
-                               IN mlx_utils *utils,
-                               IN mlx_pci_width width,
-                               IN mlx_uint8 bar_index,
-                               IN mlx_uint64 offset,
-                               IN mlx_uintn count,
-                               OUT mlx_void *buffer
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       if( utils == NULL || count == 0){
-               status = MLX_INVALID_PARAMETER;
-               goto bail;
-       }
-       status = mlx_pci_mem_read_priv(utils, bar_index, width, offset, count, buffer);
-bail:
-       return status;
-}
-
-mlx_status
-mlx_pci_mem_write(
-                               IN mlx_utils *utils,
-                               IN mlx_pci_width width,
-                               IN mlx_uint8 bar_index,
-                               IN mlx_uint64 offset,
-                               IN mlx_uintn count,
-                               IN mlx_void *buffer
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       if( utils == NULL || count == 0){
-               status = MLX_INVALID_PARAMETER;
-               goto bail;
-       }
-       status = mlx_pci_mem_write_priv(utils, width, bar_index, offset, count, buffer);
-bail:
-       return status;
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_pci_gw.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_pci_gw.c
deleted file mode 100644 (file)
index 30c1e64..0000000
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "../../include/public/mlx_pci_gw.h"
-#include "../../include/public/mlx_bail.h"
-#include "../../include/public/mlx_pci.h"
-#include "../../include/public/mlx_logging.h"
-
-/* Lock/unlock GW on each VSEC access */
-#undef VSEC_DEBUG
-
-static
-mlx_status
-mlx_pci_gw_check_capability_id(
-                                                       IN mlx_utils *utils,
-                                                       IN mlx_uint8 cap_pointer,
-                                                       OUT mlx_boolean *bool
-                                                       )
-{
-       mlx_status              status = MLX_SUCCESS;
-       mlx_uint8               offset = cap_pointer + PCI_GW_CAPABILITY_ID_OFFSET;
-       mlx_uint8               id = 0;
-       status = mlx_pci_read(utils, MlxPciWidthUint8, offset,
-                               1, &id);
-       MLX_CHECK_STATUS(utils, status, read_err,"failed to read capability id");
-       *bool = ( id == PCI_GW_CAPABILITY_ID );
-read_err:
-       return status;
-}
-
-static
-mlx_status
-mlx_pci_gw_get_ownership(
-                                               IN mlx_utils *utils
-                                               )
-{
-       mlx_status                      status = MLX_SUCCESS;
-       mlx_uint32                      cap_offset = utils->pci_gw.pci_cmd_offset;
-       mlx_uint32                      semaphore = 0;
-       mlx_uint32                      counter = 0;
-       mlx_uint32                      get_semaphore_try = 0;
-       mlx_uint32                      get_ownership_try = 0;
-
-       for( ; get_ownership_try < PCI_GW_GET_OWNERSHIP_TRIES; get_ownership_try ++){
-               for( ; get_semaphore_try <= PCI_GW_SEMPHORE_TRIES ; get_semaphore_try++){
-                       status = mlx_pci_read(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_SEMAPHORE_OFFSET,
-                                       1, &semaphore);
-                       MLX_CHECK_STATUS(utils, status, read_err,"failed to read semaphore");
-                       if( semaphore == 0 ){
-                               break;
-                       }
-                       mlx_utils_delay_in_us(10);
-               }
-               if( semaphore != 0 ){
-                       status = MLX_FAILED;
-                       goto semaphore_err;
-               }
-
-               status = mlx_pci_read(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_COUNTER_OFFSET,
-                                               1, &counter);
-               MLX_CHECK_STATUS(utils, status, read_err, "failed to read counter");
-
-               status = mlx_pci_write(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_SEMAPHORE_OFFSET,
-                                               1, &counter);
-               MLX_CHECK_STATUS(utils, status, write_err,"failed to write semaphore");
-
-               status = mlx_pci_read(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_SEMAPHORE_OFFSET,
-                                               1, &semaphore);
-               MLX_CHECK_STATUS(utils, status, read_err,"failed to read semaphore");
-               if( counter == semaphore ){
-                       break;
-               }
-       }
-       if( counter != semaphore ){
-               status = MLX_FAILED;
-       }
-write_err:
-read_err:
-semaphore_err:
-       return status;
-}
-
-static
-mlx_status
-mlx_pci_gw_free_ownership(
-                                               IN mlx_utils *utils
-                                               )
-{
-       mlx_status              status = MLX_SUCCESS;
-       mlx_uint32              cap_offset = utils->pci_gw.pci_cmd_offset;
-       mlx_uint32              value = 0;
-
-       status = mlx_pci_write(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_SEMAPHORE_OFFSET,
-                                       1, &value);
-       MLX_CHECK_STATUS(utils, status, write_err,"failed to write semaphore");
-write_err:
-       return status;
-}
-
-static
-mlx_status
-mlx_pci_gw_set_space(
-                                       IN mlx_utils *utils,
-                                       IN mlx_pci_gw_space space
-                                       )
-{
-       mlx_status              status = MLX_SUCCESS;
-       mlx_uint32              cap_offset = utils->pci_gw.pci_cmd_offset;;
-       mlx_uint8               space_status = 0;
-
-       /* set nodnic*/
-       status = mlx_pci_write(utils, MlxPciWidthUint16, cap_offset + PCI_GW_CAPABILITY_SPACE_OFFSET, 1, &space);
-       MLX_CHECK_STATUS(utils, status, read_error,"failed to write capability space");
-
-       status = mlx_pci_read(utils, MlxPciWidthUint8, cap_offset + PCI_GW_CAPABILITY_STATUS_OFFSET, 1, &space_status);
-       MLX_CHECK_STATUS(utils, status, read_error,"failed to read capability status");
-       if( (space_status & 0x20) == 0){
-               status = MLX_FAILED;
-               goto space_unsupported;
-       }
-read_error:
-space_unsupported:
-       return status;
-}
-
-static
-mlx_status
-mlx_pci_gw_wait_for_flag_value(
-                                                       IN mlx_utils *utils,
-                                                       IN mlx_boolean value
-                                                       )
-{
-       mlx_status              status = MLX_SUCCESS;
-       mlx_uint32              try = 0;
-       mlx_uint32              cap_offset = utils->pci_gw.pci_cmd_offset;
-       mlx_uint32              flag = 0;
-
-       for(; try < PCI_GW_READ_FLAG_TRIES ; try ++ ) {
-               status = mlx_pci_read(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_FLAG_OFFSET, 1, &flag);
-               MLX_CHECK_STATUS(utils, status, read_error, "failed to read capability flag");
-               if( ((flag & 0x80000000) != 0) == value ){
-                       goto flag_valid;
-               }
-               mlx_utils_delay_in_us(10);
-       }
-       status = MLX_FAILED;
-flag_valid:
-read_error:
-       return status;
-}
-static
-mlx_status
-mlx_pci_gw_search_capability(
-                               IN mlx_utils *utils,
-                               OUT mlx_uint32  *cap_offset
-                               )
-{
-       mlx_status              status = MLX_SUCCESS;
-       mlx_uint8               cap_pointer = 0;
-       mlx_boolean             is_capability = FALSE;
-
-       if( cap_offset == NULL || utils == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       //get first capability pointer
-       status = mlx_pci_read(utils, MlxPciWidthUint8, PCI_GW_FIRST_CAPABILITY_POINTER_OFFSET,
-                       1, &cap_pointer);
-       MLX_CHECK_STATUS(utils, status, read_err,
-                       "failed to read capability pointer");
-
-       //search the right capability
-       while( cap_pointer != 0 ){
-               status = mlx_pci_gw_check_capability_id(utils, cap_pointer, &is_capability);
-               MLX_CHECK_STATUS(utils, status, check_err
-                               ,"failed to check capability id");
-
-               if( is_capability == TRUE ){
-                       *cap_offset = cap_pointer;
-                       break;
-               }
-
-               status = mlx_pci_read(utils, MlxPciWidthUint8, cap_pointer +
-                               PCI_GW_CAPABILITY_NEXT_POINTER_OFFSET ,
-                               1, &cap_pointer);
-               MLX_CHECK_STATUS(utils, status, read_err,
-                               "failed to read capability pointer");
-       }
-       if( is_capability != TRUE ){
-               status = MLX_NOT_FOUND;
-       }
-check_err:
-read_err:
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_pci_gw_init(
-                       IN mlx_utils *utils
-                       )
-{
-       mlx_status              status = MLX_SUCCESS;
-       mlx_pci_gw *pci_gw = NULL;
-
-       if( utils == NULL){
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       pci_gw = &utils->pci_gw;
-
-       status = mlx_pci_gw_search_capability(utils, &pci_gw->pci_cmd_offset);
-       MLX_CHECK_STATUS(utils, status, cap_err,
-                                       "mlx_pci_gw_search_capability failed");
-
-#if ! defined ( VSEC_DEBUG )
-       status = mlx_pci_gw_get_ownership(utils);
-       MLX_CHECK_STATUS(utils, status, ownership_err,"failed to get ownership");
-ownership_err:
-#endif
-cap_err:
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_pci_gw_teardown(
-               IN mlx_utils *utils __attribute__ ((unused))
-               )
-{
-#if ! defined ( VSEC_DEBUG )
-       mlx_pci_gw_free_ownership(utils);
-#endif
-       return MLX_SUCCESS;
-}
-
-mlx_status
-mlx_pci_gw_read(
-               IN mlx_utils *utils,
-               IN mlx_pci_gw_space space,
-               IN mlx_uint32 address,
-               OUT mlx_pci_gw_buffer *buffer
-               )
-{
-       mlx_status              status = MLX_SUCCESS;
-       mlx_pci_gw              *pci_gw = NULL;
-       mlx_uint32              cap_offset = 0;
-
-       if (utils == NULL || buffer == NULL || utils->pci_gw.pci_cmd_offset == 0) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       mlx_utils_acquire_lock(utils);
-
-       pci_gw = &utils->pci_gw;
-       cap_offset = pci_gw->pci_cmd_offset;
-
-#if ! defined ( VSEC_DEBUG )
-       if (pci_gw->space != space) {
-                  status = mlx_pci_gw_set_space(utils, space);
-                  MLX_CHECK_STATUS(utils, status, space_error,"failed to set space");
-                  pci_gw->space = space;
-       }
-#else
-       status = mlx_pci_gw_get_ownership(utils);
-       MLX_CHECK_STATUS(utils, status, ownership_err,"failed to get ownership");
-
-       status = mlx_pci_gw_set_space(utils, space);
-       MLX_CHECK_STATUS(utils, status, space_error,"failed to set space");
-       pci_gw->space = space;
-#endif
-
-       status = mlx_pci_write(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_ADDRESS_OFFSET, 1, &address);
-       MLX_CHECK_STATUS(utils, status, read_error,"failed to write capability address");
-
-#if defined ( DEVICE_CX3 )
-       /* WA for PCI issue (race) */
-       mlx_utils_delay_in_us ( 10 );
-#endif
-
-       status = mlx_pci_gw_wait_for_flag_value(utils, TRUE);
-       MLX_CHECK_STATUS(utils, status, read_error, "flag failed to change");
-
-       status = mlx_pci_read(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_DATA_OFFSET, 1, buffer);
-       MLX_CHECK_STATUS(utils, status, read_error,"failed to read capability data");
-
-#if defined ( VSEC_DEBUG )
-       status = mlx_pci_gw_free_ownership(utils);
-       MLX_CHECK_STATUS(utils, status, free_err,
-                                               "mlx_pci_gw_free_ownership failed");
-free_err:
-       mlx_utils_release_lock(utils);
-       return status;
-#endif
-read_error:
-space_error:
-#if defined ( VSEC_DEBUG )
-       mlx_pci_gw_free_ownership(utils);
-ownership_err:
-#endif
-mlx_utils_release_lock(utils);
-bad_param:
-       return status;
-}
-
-mlx_status
-mlx_pci_gw_write(
-                               IN mlx_utils *utils,
-                               IN mlx_pci_gw_space space,
-                               IN mlx_uint32 address,
-                               IN mlx_pci_gw_buffer buffer
-                               )
-{
-       mlx_status              status = MLX_SUCCESS;
-       mlx_pci_gw              *pci_gw = NULL;
-       mlx_uint32              cap_offset = 0;
-       mlx_uint32              fixed_address = address | PCI_GW_WRITE_FLAG;
-
-       if (utils == NULL || utils->pci_gw.pci_cmd_offset == 0) {
-               status = MLX_INVALID_PARAMETER;
-               goto bad_param;
-       }
-
-       mlx_utils_acquire_lock(utils);
-
-       pci_gw = &utils->pci_gw;
-       cap_offset = pci_gw->pci_cmd_offset;
-
-#if ! defined ( VSEC_DEBUG )
-       if (pci_gw->space != space) {
-                  status = mlx_pci_gw_set_space(utils, space);
-                  MLX_CHECK_STATUS(utils, status, space_error,"failed to set space");
-                  pci_gw->space = space;
-       }
-#else
-       status = mlx_pci_gw_get_ownership(utils);
-       MLX_CHECK_STATUS(utils, status, ownership_err,"failed to get ownership");
-
-       status = mlx_pci_gw_set_space(utils, space);
-       MLX_CHECK_STATUS(utils, status, space_error,"failed to set space");
-       pci_gw->space = space;
-#endif
-       status = mlx_pci_write(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_DATA_OFFSET, 1, &buffer);
-       MLX_CHECK_STATUS(utils, status, read_error,"failed to write capability data");
-
-       status = mlx_pci_write(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_ADDRESS_OFFSET, 1, &fixed_address);
-       MLX_CHECK_STATUS(utils, status, read_error,"failed to write capability address");
-
-       status = mlx_pci_gw_wait_for_flag_value(utils, FALSE);
-       MLX_CHECK_STATUS(utils, status, read_error, "flag failed to change");
-#if defined ( VSEC_DEBUG )
-       status = mlx_pci_gw_free_ownership(utils);
-       MLX_CHECK_STATUS(utils, status, free_err,
-                                               "mlx_pci_gw_free_ownership failed");
-free_err:
-mlx_utils_release_lock(utils);
-       return status;
-#endif
-read_error:
-space_error:
-#if defined ( VSEC_DEBUG )
-       mlx_pci_gw_free_ownership(utils);
-ownership_err:
-#endif
-mlx_utils_release_lock(utils);
-bad_param:
-       return status;
-}
-
-
-
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_utils.c b/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_utils.c
deleted file mode 100644 (file)
index c824b17..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <stddef.h>
-#include "../../include/private/mlx_utils_priv.h"
-#include "../../include/public/mlx_pci.h"
-#include "../../include/public/mlx_utils.h"
-
-mlx_status
-mlx_utils_init(
-                               IN mlx_utils *utils,
-                               IN mlx_pci *pci
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       if( pci == NULL || utils == NULL ){
-               status = MLX_INVALID_PARAMETER;
-               goto bail;
-       }
-       utils->pci = pci;
-       status = mlx_pci_init(utils);
-       status = mlx_utils_init_lock(utils);
-bail:
-       return status;
-}
-
-mlx_status
-mlx_utils_teardown(
-                               IN mlx_utils *utils __attribute__ ((unused))
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_utils_free_lock(utils);
-       return status;
-}
-
-mlx_status
-mlx_utils_delay_in_ms(
-                       IN mlx_uint32 msecs
-               )
-{
-       mlx_utils_delay_in_ms_priv(msecs);
-       return MLX_SUCCESS;
-}
-mlx_status
-mlx_utils_delay_in_us(
-                       IN mlx_uint32 usecs
-               )
-{
-       mlx_utils_delay_in_us_priv(usecs);
-       return MLX_SUCCESS;
-}
-mlx_status
-mlx_utils_ilog2(
-                       IN mlx_uint32 i,
-                       OUT mlx_uint32 *log
-               )
-{
-       mlx_utils_ilog2_priv(i, log);
-       return MLX_SUCCESS;
-}
-
-mlx_status
-mlx_utils_init_lock(
-                       IN OUT mlx_utils *utils
-               )
-{
-       return mlx_utils_init_lock_priv(&(utils->lock));
-
-}
-
-mlx_status
-mlx_utils_free_lock(
-                       IN OUT mlx_utils *utils
-               )
-{
-       return mlx_utils_free_lock_priv(utils->lock);
-}
-
-mlx_status
-mlx_utils_acquire_lock (
-                       IN OUT mlx_utils *utils
-               )
-{
-       return mlx_utils_acquire_lock_priv(utils->lock);
-}
-
-mlx_status
-mlx_utils_release_lock (
-               IN OUT mlx_utils *utils
-               )
-{
-       return mlx_utils_release_lock_priv(utils->lock);
-}
-
-mlx_status
-mlx_utils_rand (
-               IN mlx_utils *utils,
-               OUT mlx_uint32 *rand_num
-               )
-{
-       return mlx_utils_rand_priv(utils, rand_num);
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_logging_priv.h b/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_logging_priv.h
deleted file mode 100644 (file)
index af7e86f..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * DebugPriv.h
- *
- *  Created on: Jan 19, 2015
- *      Author: maord
- */
-
-#ifndef STUB_MLXUTILS_INCLUDE_PRIVATE_FLEXBOOT_DEBUG_H_
-#define STUB_MLXUTILS_INCLUDE_PRIVATE_FLEXBOOT_DEBUG_H_
-
-#include <stdio.h>
-#include <compiler.h>
-
-#define MLX_DEBUG_FATAL_ERROR_PRIVATE(...)             do {                            \
-               DBG("%s: ",__func__);                                           \
-               DBG(__VA_ARGS__);                       \
-       } while ( 0 )
-
-#define MLX_DEBUG_ERROR_PRIVATE(id, ...)               do {                            \
-               DBGC(id, "%s: ",__func__);                      \
-               DBGC(id, __VA_ARGS__);                  \
-       } while ( 0 )
-
-#define MLX_DEBUG_WARN_PRIVATE(id, ...)                do {                            \
-               DBGC(id, "%s: ",__func__);                      \
-               DBGC(id, __VA_ARGS__);                  \
-       } while ( 0 )
-
-#define MLX_DEBUG_INFO1_PRIVATE(id, ...)               do {                            \
-               DBGC(id, "%s: ",__func__);                      \
-               DBGC(id, __VA_ARGS__);                  \
-       } while ( 0 )
-
-#define MLX_DEBUG_INFO2_PRIVATE(id, ...)               do {                            \
-               DBGC2(id, "%s: ",__func__);                     \
-               DBGC2(id, __VA_ARGS__);                 \
-       } while ( 0 )
-
-#define MLX_DBG_ERROR_PRIVATE(...)             do {                            \
-               DBG("%s: ",__func__);                   \
-               DBG(__VA_ARGS__);                       \
-       } while ( 0 )
-
-#define MLX_DBG_WARN_PRIVATE(...)              do {                            \
-               DBG("%s: ",__func__);                   \
-               DBG(__VA_ARGS__);                       \
-       } while ( 0 )
-
-#define MLX_DBG_INFO1_PRIVATE(...)             do {                            \
-               DBG("%s: ",__func__);                   \
-               DBG(__VA_ARGS__);                       \
-       } while ( 0 )
-
-#define MLX_DBG_INFO2_PRIVATE(...)             do {                            \
-               DBG2("%s: ",__func__);                  \
-               DBG2(__VA_ARGS__);                      \
-       } while ( 0 )
-
-
-
-#endif /* STUB_MLXUTILS_INCLUDE_PRIVATE_FLEXBOOT_DEBUG_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_types_priv.h b/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_types_priv.h
deleted file mode 100644 (file)
index feaeae6..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * types.h
- *
- *  Created on: Jan 18, 2015
- *      Author: maord
- */
-
-#ifndef A_MLXUTILS_INCLUDE_PUBLIC_TYPES_H_
-#define A_MLXUTILS_INCLUDE_PUBLIC_TYPES_H_
-#include <stdint.h>
-//#include <errno.h>
-#include <ipxe/pci.h>
-
-#define MLX_SUCCESS 0
-#define MLX_OUT_OF_RESOURCES (-1)
-//(-ENOMEM)
-#define MLX_INVALID_PARAMETER (-2)
-//(-EINVAL)
-#define MLX_UNSUPPORTED (-3)
-//(-ENOSYS)
-#define MLX_NOT_FOUND (-4)
-
-#define MLX_FAILED (-5)
-
-#undef TRUE
-#define TRUE   1
-#undef FALSE
-#define FALSE  !TRUE
-
-typedef int mlx_status;
-
-typedef uint8_t                mlx_uint8;
-typedef uint16_t       mlx_uint16;
-typedef uint32_t       mlx_uint32;
-typedef uint64_t       mlx_uint64;
-typedef uint32_t       mlx_uintn;
-
-typedef int8_t         mlx_int8;
-typedef int16_t                mlx_int16;;
-typedef int32_t                mlx_int32;
-typedef int64_t                mlx_int64;
-typedef uint8_t                mlx_boolean;
-
-typedef struct pci_device      mlx_pci;
-
-typedef size_t         mlx_size;
-
-typedef void           mlx_void;
-
-#define MAC_ADDR_LEN 6
-typedef unsigned long  mlx_physical_address;
-typedef union {
-       struct {
-               uint32_t low;
-               uint32_t high;
-       } __attribute__ (( packed ));
-       uint8_t addr[MAC_ADDR_LEN];
-} mlx_mac_address;
-
-#endif /* A_MLXUTILS_INCLUDE_PUBLIC_TYPES_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_memory_priv.c b/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_memory_priv.c
deleted file mode 100644 (file)
index cb9e759..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * MemoryPriv.c
- *
- *  Created on: Jan 21, 2015
- *      Author: maord
- */
-
-#include <ipxe/malloc.h>
-#include <stddef.h>
-#include <byteswap.h>
-#include <ipxe/io.h>
-#include "../../mlx_utils/include/private/mlx_memory_priv.h"
-
-
-mlx_status
-mlx_memory_alloc_priv(
-                               IN mlx_utils *utils __attribute__ ((unused)),
-                               IN mlx_size size,
-                               OUT mlx_void **ptr
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       *ptr = malloc(size);
-       if(*ptr == NULL){
-               status = MLX_OUT_OF_RESOURCES;
-       }
-       return status;
-}
-
-mlx_status
-mlx_memory_zalloc_priv(
-                               IN mlx_utils *utils __attribute__ ((unused)),
-                               IN mlx_size size,
-                               OUT mlx_void **ptr
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       *ptr = zalloc(size);
-       if(*ptr == NULL){
-               status = MLX_OUT_OF_RESOURCES;
-       }
-       return status;
-}
-
-mlx_status
-mlx_memory_free_priv(
-                               IN mlx_utils *utils __attribute__ ((unused)),
-                               IN mlx_void *ptr
-                               )
-{
-       mlx_status status = MLX_SUCCESS;
-       free(ptr);
-       return status;
-}
-mlx_status
-mlx_memory_alloc_dma_priv(
-                                       IN mlx_utils *utils __attribute__ ((unused)),
-                                       IN mlx_size size ,
-                                       IN mlx_size align,
-                                       OUT mlx_void **ptr
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       *ptr = malloc_dma(size, align);
-       if (*ptr == NULL) {
-               status = MLX_OUT_OF_RESOURCES;
-       } else {
-               memset(*ptr, 0, size);
-       }
-       return status;
-}
-
-mlx_status
-mlx_memory_free_dma_priv(
-                                       IN mlx_utils *utils __attribute__ ((unused)),
-                                       IN mlx_size size ,
-                                       IN mlx_void *ptr
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       free_dma(ptr, size);
-       return status;
-}
-mlx_status
-mlx_memory_map_dma_priv(
-                                       IN mlx_utils *utils __attribute__ ((unused)),
-                                       IN mlx_void *addr ,
-                                       IN mlx_size number_of_bytes __attribute__ ((unused)),
-                                       OUT mlx_physical_address *phys_addr,
-                                       OUT mlx_void **mapping __attribute__ ((unused))
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       *phys_addr = virt_to_bus(addr);
-       return status;
-}
-
-mlx_status
-mlx_memory_ummap_dma_priv(
-                                       IN mlx_utils *utils __attribute__ ((unused)),
-                                       IN mlx_void *mapping __attribute__ ((unused))
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       return status;
-}
-
-mlx_status
-mlx_memory_cmp_priv(
-                                       IN mlx_utils *utils __unused,
-                                       IN mlx_void *first_block,
-                                       IN mlx_void *second_block,
-                                       IN mlx_size size,
-                                       OUT mlx_uint32 *out
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       *out = memcmp(first_block, second_block, size);
-       return status;
-}
-
-mlx_status
-mlx_memory_set_priv(
-                                       IN mlx_utils *utils __unused,
-                                       IN mlx_void *block,
-                                       IN mlx_int32 value,
-                                       IN mlx_size size
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       memset(block, value, size);
-       return status;
-}
-
-mlx_status
-mlx_memory_cpy_priv(
-                                       IN mlx_utils *utils __unused,
-                                       OUT mlx_void *destination_buffer,
-                                       IN mlx_void *source_buffer,
-                                       IN mlx_size length
-                                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       memcpy(destination_buffer, source_buffer, length);
-       return status;
-}
-
-mlx_status
-mlx_memory_cpu_to_be32_priv(
-                       IN mlx_utils *utils __unused,
-                       IN mlx_uint32 source,
-                       IN mlx_uint32 *destination
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       *destination = cpu_to_be32(source);
-       return status;
-}
-
-
-mlx_status
-mlx_memory_be32_to_cpu_priv(
-                       IN mlx_utils *utils __unused,
-                       IN mlx_uint32 source,
-                       IN mlx_uint32 *destination
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       *destination = be32_to_cpu(source);
-       return status;
-}
-
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c b/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c
deleted file mode 100644 (file)
index f8caefd..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * MlxPciPriv.c
- *
- *  Created on: Jan 21, 2015
- *      Author: maord
- */
-
-#include <ipxe/pci.h>
-#include "../../mlx_utils/include/private/mlx_pci_priv.h"
-
-
-static
-mlx_status
-mlx_pci_config_byte(
-               IN mlx_utils *utils,
-               IN mlx_boolean read,
-               IN mlx_uint32 offset,
-               IN OUT mlx_uint8 *buffer
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       if (read) {
-               status = pci_read_config_byte(utils->pci, offset, buffer);
-       }else {
-               status = pci_write_config_byte(utils->pci, offset, *buffer);
-       }
-       return status;
-}
-
-static
-mlx_status
-mlx_pci_config_word(
-               IN mlx_utils *utils,
-               IN mlx_boolean read,
-               IN mlx_uint32 offset,
-               IN OUT mlx_uint16 *buffer
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       if (read) {
-               status = pci_read_config_word(utils->pci, offset, buffer);
-       }else {
-               status = pci_write_config_word(utils->pci, offset, *buffer);
-       }
-       return status;
-}
-
-static
-mlx_status
-mlx_pci_config_dword(
-               IN mlx_utils *utils,
-               IN mlx_boolean read,
-               IN mlx_uint32 offset,
-               IN OUT mlx_uint32 *buffer
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       if (read) {
-               status = pci_read_config_dword(utils->pci, offset, buffer);
-       }else {
-               status = pci_write_config_dword(utils->pci, offset, *buffer);
-       }
-       return status;
-}
-static
-mlx_status
-mlx_pci_config(
-               IN mlx_utils *utils,
-               IN mlx_boolean read,
-               IN mlx_pci_width width,
-               IN mlx_uint32 offset,
-               IN mlx_uintn count,
-               IN OUT mlx_void *buffer
-               )
-{
-       mlx_status status = MLX_SUCCESS;
-       mlx_uint8 *tmp =  (mlx_uint8*)buffer;
-       mlx_uintn iteration = 0;
-       if( width == MlxPciWidthUint64) {
-               width = MlxPciWidthUint32;
-               count = count * 2;
-       }
-
-       for(;iteration < count ; iteration++) {
-               switch (width){
-               case MlxPciWidthUint8:
-                       status = mlx_pci_config_byte(utils, read , offset++, tmp++);
-                       break;
-               case MlxPciWidthUint16:
-                       status = mlx_pci_config_word(utils, read , offset, (mlx_uint16*)tmp);
-                       tmp += 2;
-                       offset += 2;
-                       break;
-               case MlxPciWidthUint32:
-                       status = mlx_pci_config_dword(utils, read , offset, (mlx_uint32*)tmp);
-                       tmp += 4;
-                       offset += 4;
-                       break;
-               default:
-                       status = MLX_INVALID_PARAMETER;
-               }
-               if(status != MLX_SUCCESS) {
-                       goto config_error;
-               }
-       }
-config_error:
-       return status;
-}
-mlx_status
-mlx_pci_init_priv(
-                       IN mlx_utils *utils
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       adjust_pci_device ( utils->pci );
-#ifdef DEVICE_CX3
-       utils->config = ioremap ( pci_bar_start ( utils->pci, PCI_BASE_ADDRESS_0),
-                       0x100000 );
-#endif
-       return status;
-}
-
-mlx_status
-mlx_pci_read_priv(
-                       IN mlx_utils *utils,
-                       IN mlx_pci_width width,
-                       IN mlx_uint32 offset,
-                       IN mlx_uintn count,
-                       OUT mlx_void *buffer
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       status = mlx_pci_config(utils, TRUE, width, offset, count, buffer);
-       return status;
-}
-
-mlx_status
-mlx_pci_write_priv(
-                       IN mlx_utils *utils,
-                       IN mlx_pci_width width,
-                       IN mlx_uint32 offset,
-                       IN mlx_uintn count,
-                       IN mlx_void *buffer
-                       )
-{
-       mlx_status status = MLX_SUCCESS;
-       status = mlx_pci_config(utils, FALSE, width, offset, count, buffer);
-       return status;
-}
-
-mlx_status
-mlx_pci_mem_read_priv(
-                               IN mlx_utils *utils  __attribute__ ((unused)),
-                               IN mlx_pci_width width  __attribute__ ((unused)),
-                               IN mlx_uint8 bar_index  __attribute__ ((unused)),
-                               IN mlx_uint64 offset,
-                               IN mlx_uintn count  __attribute__ ((unused)),
-                               OUT mlx_void *buffer
-                               )
-{
-       if (buffer == NULL || width != MlxPciWidthUint32)
-               return MLX_INVALID_PARAMETER;
-       *((mlx_uint32 *)buffer) = readl(offset);
-       return MLX_SUCCESS;
-}
-
-mlx_status
-mlx_pci_mem_write_priv(
-                               IN mlx_utils *utils  __attribute__ ((unused)),
-                               IN mlx_pci_width width  __attribute__ ((unused)),
-                               IN mlx_uint8 bar_index  __attribute__ ((unused)),
-                               IN mlx_uint64 offset,
-                               IN mlx_uintn count  __attribute__ ((unused)),
-                               IN mlx_void *buffer
-                               )
-{
-       if (buffer == NULL || width != MlxPciWidthUint32)
-               return MLX_INVALID_PARAMETER;
-       barrier();
-       writel(*((mlx_uint32 *)buffer), offset);
-       return MLX_SUCCESS;
-}
diff --git a/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_utils_priv.c b/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_utils_priv.c
deleted file mode 100644 (file)
index 5fca406..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * MlxUtilsPriv.c
- *
- *  Created on: Jan 25, 2015
- *      Author: maord
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <strings.h>
-#include "../../mlx_utils/include/private/mlx_utils_priv.h"
-
-mlx_status
-mlx_utils_delay_in_ms_priv(
-                       IN mlx_uint32 msecs
-               )
-{
-       mdelay(msecs);
-       return MLX_SUCCESS;
-}
-
-mlx_status
-mlx_utils_delay_in_us_priv(
-                       IN mlx_uint32 usecs
-               )
-{
-       udelay(usecs);
-       return MLX_SUCCESS;
-}
-
-mlx_status
-mlx_utils_ilog2_priv(
-                       IN mlx_uint32 i,
-                       OUT mlx_uint32 *log
-               )
-{
-       *log = ( fls ( i ) - 1 );
-       return MLX_SUCCESS;
-}
-
-mlx_status
-mlx_utils_init_lock_priv(
-                       OUT void **lock __unused
-               )
-{
-       return MLX_SUCCESS;
-}
-
-mlx_status
-mlx_utils_free_lock_priv(
-                       IN void *lock __unused
-               )
-{
-       return MLX_SUCCESS;
-}
-
-mlx_status
-mlx_utils_acquire_lock_priv (
-                       IN void *lock __unused
-               )
-{
-       return MLX_SUCCESS;
-}
-
-mlx_status
-mlx_utils_release_lock_priv (
-                       IN void *lock __unused
-               )
-{
-       return MLX_SUCCESS;
-}
-
-mlx_status
-mlx_utils_rand_priv (
-                       IN  mlx_utils *utils __unused,
-                       OUT mlx_uint32 *rand_num
-               )
-{
-       do {
-               *rand_num = rand();
-       } while ( *rand_num == 0 );
-       return MLX_SUCCESS;
-}
diff --git a/roms/ipxe/src/drivers/infiniband/nodnic_prm.h b/roms/ipxe/src/drivers/infiniband/nodnic_prm.h
deleted file mode 100644 (file)
index 5e0fa98..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#ifndef SRC_DRIVERS_INFINIBAND_MLX_NODNIC_INCLUDE_PRM_NODNIC_PRM_H_
-#define SRC_DRIVERS_INFINIBAND_MLX_NODNIC_INCLUDE_PRM_NODNIC_PRM_H_
-
-#include "mlx_bitops.h"
-
-struct nodnic_wqe_segment_data_ptr_st {        /* Little Endian */
-    pseudo_bit_t       byte_count[0x0001f];
-    pseudo_bit_t       always0[0x00001];
-/* -------------- */
-    pseudo_bit_t       l_key[0x00020];
-/* -------------- */
-    pseudo_bit_t       local_address_h[0x00020];
-/* -------------- */
-    pseudo_bit_t       local_address_l[0x00020];
-/* -------------- */
-};
-
-struct MLX_DECLARE_STRUCT ( nodnic_wqe_segment_data_ptr );
-
-#define HERMON_MAX_SCATTER 1
-
-struct nodnic_recv_wqe {
-       struct nodnic_wqe_segment_data_ptr data[HERMON_MAX_SCATTER];
-} __attribute__ (( packed ));
-
-#endif /* SRC_DRIVERS_INFINIBAND_MLX_NODNIC_INCLUDE_PRM_NODNIC_PRM_H_ */
diff --git a/roms/ipxe/src/drivers/infiniband/nodnic_shomron_prm.h b/roms/ipxe/src/drivers/infiniband/nodnic_shomron_prm.h
deleted file mode 100644 (file)
index 85cd971..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2015 Mellanox Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#ifndef SRC_DRIVERS_INFINIBAND_MLX_NODNIC_INCLUDE_PRM_NODNIC_SHOMRON_PRM_H_
-#define SRC_DRIVERS_INFINIBAND_MLX_NODNIC_INCLUDE_PRM_NODNIC_SHOMRON_PRM_H_
-
-
-
-#include "nodnic_prm.h"
-
-
-#define SHOMRON_MAX_GATHER 1
-
-/* Send wqe segment ctrl */
-
-struct shomronprm_wqe_segment_ctrl_send_st {   /* Little Endian */
-    pseudo_bit_t       opcode[0x00008];
-    pseudo_bit_t       wqe_index[0x00010];
-    pseudo_bit_t       reserved1[0x00008];
-/* -------------- */
-    pseudo_bit_t       ds[0x00006];           /* descriptor (wqe) size in 16bytes chunk */
-    pseudo_bit_t       reserved2[0x00002];
-    pseudo_bit_t       qpn[0x00018];
-/* -------------- */
-       pseudo_bit_t    reserved3[0x00002];
-       pseudo_bit_t    ce[0x00002];
-       pseudo_bit_t    reserved4[0x0001c];
-/* -------------- */
-       pseudo_bit_t    reserved5[0x00040];
-/* -------------- */
-       pseudo_bit_t    mss[0x0000e];
-       pseudo_bit_t    reserved6[0x0000e];
-       pseudo_bit_t    cs13_inner[0x00001];
-       pseudo_bit_t    cs14_inner[0x00001];
-       pseudo_bit_t    cs13[0x00001];
-       pseudo_bit_t    cs14[0x00001];
-/* -------------- */
-       pseudo_bit_t    reserved7[0x00020];
-/* -------------- */
-       pseudo_bit_t    inline_headers1[0x00010];
-       pseudo_bit_t    inline_headers_size[0x0000a]; //sum size of inline_hdr1+inline_hdrs (0x10)
-       pseudo_bit_t    reserved8[0x00006];
-/* -------------- */
-       pseudo_bit_t    inline_headers2[0x00020];
-/* -------------- */
-       pseudo_bit_t    inline_headers3[0x00020];
-/* -------------- */
-       pseudo_bit_t    inline_headers4[0x00020];
-/* -------------- */
-       pseudo_bit_t    inline_headers5[0x00020];
-};
-
-
-
-/* Completion Queue Entry Format        #### michal - fixed by gdror */
-
-struct shomronprm_completion_queue_entry_st {  /* Little Endian */
-
-       pseudo_bit_t    reserved1[0x00080];
-/* -------------- */
-       pseudo_bit_t    reserved2[0x00010];
-       pseudo_bit_t    ml_path[0x00007];
-       pseudo_bit_t    reserved3[0x00009];
-/* -------------- */
-       pseudo_bit_t    slid[0x00010];
-       pseudo_bit_t    reserved4[0x00010];
-/* -------------- */
-       pseudo_bit_t    rqpn[0x00018];
-       pseudo_bit_t    sl[0x00004];
-       pseudo_bit_t    l3_hdr[0x00002];
-       pseudo_bit_t    reserved5[0x00002];
-/* -------------- */
-       pseudo_bit_t    reserved10[0x00020];
-/* -------------- */
-       pseudo_bit_t    srqn[0x00018];
-       pseudo_bit_t    reserved11[0x0008];
-/* -------------- */
-       pseudo_bit_t    pkey_index[0x00020];
-/* -------------- */
-       pseudo_bit_t    reserved6[0x00020];
-/* -------------- */
-       pseudo_bit_t    byte_cnt[0x00020];
-/* -------------- */
-       pseudo_bit_t    reserved7[0x00040];
-/* -------------- */
-       pseudo_bit_t    qpn[0x00018];
-       pseudo_bit_t    rx_drop_counter[0x00008];
-/* -------------- */
-       pseudo_bit_t    owner[0x00001];
-       pseudo_bit_t    reserved8[0x00003];
-       pseudo_bit_t    opcode[0x00004];
-       pseudo_bit_t    reserved9[0x00008];
-       pseudo_bit_t    wqe_counter[0x00010];
-};
-
-
-/* Completion with Error CQE             #### michal - gdror fixed */
-
-struct shomronprm_completion_with_error_st {   /* Little Endian */
-       pseudo_bit_t    reserved1[0x001a0];
-       /* -------------- */
-       pseudo_bit_t    syndrome[0x00008];
-       pseudo_bit_t    vendor_error_syndrome[0x00008];
-       pseudo_bit_t    reserved2[0x00010];
-       /* -------------- */
-       pseudo_bit_t    reserved3[0x00040];
-};
-
-
-struct MLX_DECLARE_STRUCT ( shomronprm_wqe_segment_ctrl_send );
-struct MLX_DECLARE_STRUCT ( shomronprm_completion_queue_entry );
-struct MLX_DECLARE_STRUCT ( shomronprm_completion_with_error );
-
-struct shomron_nodnic_eth_send_wqe {
-       struct shomronprm_wqe_segment_ctrl_send ctrl;
-       struct nodnic_wqe_segment_data_ptr data[SHOMRON_MAX_GATHER];
-} __attribute__ (( packed ));
-
-union shomronprm_completion_entry {
-       struct shomronprm_completion_queue_entry normal;
-       struct shomronprm_completion_with_error error;
-} __attribute__ (( packed ));
-
-
-#endif /* SRC_DRIVERS_INFINIBAND_MLX_NODNIC_INCLUDE_PRM_NODNIC_SHOMRON_PRM_H_ */
index af7006e..e22f234 100644 (file)
@@ -137,21 +137,32 @@ struct qib7322 {
  * This card requires atomic 64-bit accesses.  Strange things happen
  * if you try to use 32-bit accesses; sometimes they work, sometimes
  * they don't, sometimes you get random data.
+ *
+ * These accessors use the "movq" MMX instruction, and so won't work
+ * on really old Pentiums (which won't have PCIe anyway, so this is
+ * something of a moot point).
  */
 
 /**
  * Read QIB7322 qword register
  *
  * @v qib7322          QIB7322 device
- * @v qword            Register buffer to read into
+ * @v dwords           Register buffer to read into
  * @v offset           Register offset
  */
-static void qib7322_readq ( struct qib7322 *qib7322, uint64_t *qword,
+static void qib7322_readq ( struct qib7322 *qib7322, uint32_t *dwords,
                            unsigned long offset ) {
-       *qword = readq ( qib7322->regs + offset );
+       void *addr = ( qib7322->regs + offset );
+
+       __asm__ __volatile__ ( "movq (%1), %%mm0\n\t"
+                              "movq %%mm0, (%0)\n\t"
+                              : : "r" ( dwords ), "r" ( addr ) : "memory" );
+
+       DBGIO ( "[%08lx] => %08x%08x\n",
+               virt_to_phys ( addr ), dwords[1], dwords[0] );
 }
 #define qib7322_readq( _qib7322, _ptr, _offset ) \
-       qib7322_readq ( (_qib7322), (_ptr)->u.qwords, (_offset) )
+       qib7322_readq ( (_qib7322), (_ptr)->u.dwords, (_offset) )
 #define qib7322_readq_array8b( _qib7322, _ptr, _offset, _idx ) \
        qib7322_readq ( (_qib7322), (_ptr), ( (_offset) + ( (_idx) * 8 ) ) )
 #define qib7322_readq_array64k( _qib7322, _ptr, _offset, _idx ) \
@@ -163,15 +174,22 @@ static void qib7322_readq ( struct qib7322 *qib7322, uint64_t *qword,
  * Write QIB7322 qword register
  *
  * @v qib7322          QIB7322 device
- * @v qword            Register buffer to write
+ * @v dwords           Register buffer to write
  * @v offset           Register offset
  */
-static void qib7322_writeq ( struct qib7322 *qib7322, const uint64_t *qword,
+static void qib7322_writeq ( struct qib7322 *qib7322, const uint32_t *dwords,
                             unsigned long offset ) {
-       writeq ( *qword, ( qib7322->regs + offset ) );
+       void *addr = ( qib7322->regs + offset );
+
+       DBGIO ( "[%08lx] <= %08x%08x\n",
+               virt_to_phys ( addr ), dwords[1], dwords[0] );
+
+       __asm__ __volatile__ ( "movq (%0), %%mm0\n\t"
+                              "movq %%mm0, (%1)\n\t"
+                              : : "r" ( dwords ), "r" ( addr ) : "memory" );
 }
 #define qib7322_writeq( _qib7322, _ptr, _offset ) \
-       qib7322_writeq ( (_qib7322), (_ptr)->u.qwords, (_offset) )
+       qib7322_writeq ( (_qib7322), (_ptr)->u.dwords, (_offset) )
 #define qib7322_writeq_array8b( _qib7322, _ptr, _offset, _idx ) \
        qib7322_writeq ( (_qib7322), (_ptr), ( (_offset) + ( (_idx) * 8 ) ) )
 #define qib7322_writeq_array64k( _qib7322, _ptr, _offset, _idx ) \
@@ -1507,15 +1525,8 @@ static void qib7322_complete_recv ( struct ib_device *ibdev,
                        /* Completing the eager buffer described in
                         * this header entry.
                         */
-                       if ( payload_len <= iob_tailroom ( iobuf ) ) {
-                               iob_put ( iobuf, payload_len );
-                               rc = ( err ?
-                                      -EIO : ( useegrbfr ? 0 : -ECANCELED ) );
-                       } else {
-                               DBGC ( qib7322, "QIB7322 %p bad payload len "
-                                      "%zd\n", qib7322, payload_len );
-                               rc = -EPROTO;
-                       }
+                       iob_put ( iobuf, payload_len );
+                       rc = ( err ? -EIO : ( useegrbfr ? 0 : -ECANCELED ) );
                        /* Redirect to target QP if necessary */
                        if ( qp != intended_qp ) {
                                DBGC2 ( qib7322, "QIB7322 %p redirecting QPN "
@@ -1526,7 +1537,7 @@ static void qib7322_complete_recv ( struct ib_device *ibdev,
                                intended_qp->recv.fill++;
                        }
                        ib_complete_recv ( ibdev, intended_qp, &dest, &source,
-                                          iobuf, rc );
+                                          iobuf, rc);
                } else {
                        /* Completing on a skipped-over eager buffer */
                        ib_complete_recv ( ibdev, qp, &dest, &source, iobuf,
@@ -2296,7 +2307,7 @@ static int qib7322_probe ( struct pci_device *pci ) {
        /* Fix up PCI device */
        adjust_pci_device ( pci );
 
-       /* Map PCI BARs */
+       /* Get PCI BARs */
        qib7322->regs = ioremap ( pci->membase, QIB7322_BAR0_SIZE );
        DBGC2 ( qib7322, "QIB7322 %p has BAR at %08lx\n",
                qib7322, pci->membase );
@@ -2391,7 +2402,6 @@ static int qib7322_probe ( struct pci_device *pci ) {
  err_init_recv:
  err_read_eeprom:
  err_init_i2c:
-       iounmap ( qib7322->regs );
        free ( qib7322 );
  err_alloc_qib7322:
        return rc;
@@ -2414,7 +2424,6 @@ static void qib7322_remove ( struct pci_device *pci ) {
                ibdev_put ( qib7322->ibdev[i] );
        qib7322_fini_send ( qib7322 );
        qib7322_fini_recv ( qib7322 );
-       iounmap ( qib7322->regs );
        free ( qib7322 );
 }
 
index dab95cf..72797b2 100644 (file)
@@ -33,8 +33,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  */
 
-#define PSEUDOBIT_LITTLE_ENDIAN
-#include <ipxe/pseudobit.h>
+#define BITOPS_LITTLE_ENDIAN
+#include <ipxe/bitops.h>
 #include "qib_7322_regs.h"
 
 /** A QIB7322 GPIO register */
index 92d38cf..2338c54 100644 (file)
@@ -391,7 +391,7 @@ vxsetlink(void)
 {       
     int i, j;
     char *reason, *warning;
-    static signed char prev_conn = -1;
+    static char prev_conn = -1;
 
     if (prev_conn == -1) {
         prev_conn = vx_connector;
index d7c09f7..4d9bc8d 100644 (file)
@@ -108,7 +108,7 @@ static void t509_enable ( struct nic *nic ) {
        else if (connector == utp) {
                GO_WINDOW(nic->ioaddr,4);
                outw(ENABLE_UTP, nic->ioaddr + EP_W4_MEDIA_TYPE);
-               mdelay(2000);   /* Give time for media to negotiate */
+               sleep(2);       /* Give time for media to negotiate */
                GO_WINDOW(nic->ioaddr,1);
        }
 
diff --git a/roms/ipxe/src/drivers/net/acm.c b/roms/ipxe/src/drivers/net/acm.c
deleted file mode 100644 (file)
index 16dab4b..0000000
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <byteswap.h>
-#include <ipxe/profile.h>
-#include <ipxe/usb.h>
-#include <ipxe/usbnet.h>
-#include <ipxe/rndis.h>
-#include "acm.h"
-
-/** @file
- *
- * USB RNDIS driver
- *
- */
-
-/** Interrupt completion profiler */
-static struct profiler acm_intr_profiler __profiler =
-       { .name = "acm.intr" };
-
-/** Bulk IN completion profiler */
-static struct profiler acm_in_profiler __profiler =
-       { .name = "acm.in" };
-
-/** Bulk OUT profiler */
-static struct profiler acm_out_profiler __profiler =
-       { .name = "acm.out" };
-
-/******************************************************************************
- *
- * USB RNDIS communications interface
- *
- ******************************************************************************
- */
-
-/**
- * Complete interrupt transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void acm_intr_complete ( struct usb_endpoint *ep,
-                               struct io_buffer *iobuf, int rc ) {
-       struct acm_device *acm = container_of ( ep, struct acm_device,
-                                               usbnet.intr );
-       struct rndis_device *rndis = acm->rndis;
-       struct usb_setup_packet *message;
-
-       /* Profile completions */
-       profile_start ( &acm_intr_profiler );
-
-       /* Ignore packets cancelled when the endpoint closes */
-       if ( ! ep->open )
-               goto ignore;
-
-       /* Drop packets with errors */
-       if ( rc != 0 ) {
-               DBGC ( acm, "ACM %p interrupt failed: %s\n",
-                      acm, strerror ( rc ) );
-               DBGC_HDA ( acm, 0, iobuf->data, iob_len ( iobuf ) );
-               goto error;
-       }
-
-       /* Extract message header */
-       if ( iob_len ( iobuf ) < sizeof ( *message ) ) {
-               DBGC ( acm, "ACM %p underlength interrupt:\n", acm );
-               DBGC_HDA ( acm, 0, iobuf->data, iob_len ( iobuf ) );
-               rc = -EINVAL;
-               goto error;
-       }
-       message = iobuf->data;
-
-       /* Parse message header */
-       switch ( message->request ) {
-
-       case cpu_to_le16 ( CDC_RESPONSE_AVAILABLE ) :
-       case cpu_to_le16 ( 0x0001 ) : /* qemu seems to use this value */
-               acm->responded = 1;
-               break;
-
-       default:
-               DBGC ( acm, "ACM %p unrecognised interrupt:\n", acm );
-               DBGC_HDA ( acm, 0, iobuf->data, iob_len ( iobuf ) );
-               rc = -ENOTSUP;
-               goto error;
-       }
-
-       /* Free I/O buffer */
-       free_iob ( iobuf );
-       profile_stop ( &acm_intr_profiler );
-
-       return;
-
- error:
-       rndis_rx_err ( rndis, iob_disown ( iobuf ), rc );
- ignore:
-       free_iob ( iobuf );
-       return;
-}
-
-/** Interrupt endpoint operations */
-static struct usb_endpoint_driver_operations acm_intr_operations = {
-       .complete = acm_intr_complete,
-};
-
-/******************************************************************************
- *
- * USB RNDIS data interface
- *
- ******************************************************************************
- */
-
-/**
- * Complete bulk IN transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void acm_in_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
-                             int rc ) {
-       struct acm_device *acm = container_of ( ep, struct acm_device,
-                                               usbnet.in );
-       struct rndis_device *rndis = acm->rndis;
-
-       /* Profile receive completions */
-       profile_start ( &acm_in_profiler );
-
-       /* Ignore packets cancelled when the endpoint closes */
-       if ( ! ep->open )
-               goto ignore;
-
-       /* Record USB errors against the RNDIS device */
-       if ( rc != 0 ) {
-               DBGC ( acm, "ACM %p bulk IN failed: %s\n",
-                      acm, strerror ( rc ) );
-               goto error;
-       }
-
-       /* Hand off to RNDIS */
-       rndis_rx ( rndis, iob_disown ( iobuf ) );
-
-       profile_stop ( &acm_in_profiler );
-       return;
-
- error:
-       rndis_rx_err ( rndis, iob_disown ( iobuf ), rc );
- ignore:
-       free_iob ( iobuf );
-}
-
-/** Bulk IN endpoint operations */
-static struct usb_endpoint_driver_operations acm_in_operations = {
-       .complete = acm_in_complete,
-};
-
-/**
- * Transmit packet
- *
- * @v acm              USB RNDIS device
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int acm_out_transmit ( struct acm_device *acm,
-                             struct io_buffer *iobuf ) {
-       int rc;
-
-       /* Profile transmissions */
-       profile_start ( &acm_out_profiler );
-
-       /* Enqueue I/O buffer */
-       if ( ( rc = usb_stream ( &acm->usbnet.out, iobuf, 0 ) ) != 0 )
-               return rc;
-
-       profile_stop ( &acm_out_profiler );
-       return 0;
-}
-
-/**
- * Complete bulk OUT transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void acm_out_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
-                              int rc ) {
-       struct acm_device *acm = container_of ( ep, struct acm_device,
-                                               usbnet.out );
-       struct rndis_device *rndis = acm->rndis;
-
-       /* Report TX completion */
-       rndis_tx_complete_err ( rndis, iobuf, rc );
-}
-
-/** Bulk OUT endpoint operations */
-static struct usb_endpoint_driver_operations acm_out_operations = {
-       .complete = acm_out_complete,
-};
-
-/******************************************************************************
- *
- * USB RNDIS control interface
- *
- ******************************************************************************
- */
-
-/**
- * Send control packet
- *
- * @v acm              USB RNDIS device
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int acm_control_transmit ( struct acm_device *acm,
-                                 struct io_buffer *iobuf ) {
-       struct rndis_device *rndis = acm->rndis;
-       struct usb_device *usb = acm->usb;
-       int rc;
-
-       /* Send packet as an encapsulated command */
-       if ( ( rc = cdc_send_encapsulated_command ( usb, acm->usbnet.comms,
-                                                   iobuf->data,
-                                                   iob_len ( iobuf ) ) ) != 0){
-               DBGC ( acm, "ACM %p could not send encapsulated command: %s\n",
-                      acm, strerror ( rc ) );
-               return rc;
-       }
-
-       /* Complete packet immediately */
-       rndis_tx_complete ( rndis, iobuf );
-
-       return 0;
-}
-
-/**
- * Receive control packet
- *
- * @v acm              USB RNDIS device
- * @ret rc             Return status code
- */
-static int acm_control_receive ( struct acm_device *acm ) {
-       struct rndis_device *rndis = acm->rndis;
-       struct usb_device *usb = acm->usb;
-       struct io_buffer *iobuf;
-       struct rndis_header *header;
-       size_t mtu = ACM_RESPONSE_MTU;
-       size_t len;
-       int rc;
-
-       /* Allocate I/O buffer */
-       iobuf = alloc_iob ( mtu );
-       if ( ! iobuf ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-
-       /* Get encapsulated response */
-       if ( ( rc = cdc_get_encapsulated_response ( usb, acm->usbnet.comms,
-                                                   iobuf->data, mtu ) ) != 0 ){
-               DBGC ( acm, "ACM %p could not get encapsulated response: %s\n",
-                      acm, strerror ( rc ) );
-               goto err_get_response;
-       }
-
-       /* Fix up buffer length */
-       header = iobuf->data;
-       len = le32_to_cpu ( header->len );
-       if ( len > mtu ) {
-               DBGC ( acm, "ACM %p overlength encapsulated response\n", acm );
-               DBGC_HDA ( acm, 0, iobuf->data, mtu );
-               rc = -EPROTO;
-               goto err_len;
-       }
-       iob_put ( iobuf, len );
-
-       /* Hand off to RNDIS */
-       rndis_rx ( rndis, iob_disown ( iobuf ) );
-
-       return 0;
-
- err_len:
- err_get_response:
-       free_iob ( iobuf );
- err_alloc:
-       return rc;
-}
-
-/******************************************************************************
- *
- * RNDIS interface
- *
- ******************************************************************************
- */
-
-/**
- * Open RNDIS device
- *
- * @v rndis            RNDIS device
- * @ret rc             Return status code
- */
-static int acm_open ( struct rndis_device *rndis ) {
-       struct acm_device *acm = rndis->priv;
-       int rc;
-
-       /* Open USB network device */
-       if ( ( rc = usbnet_open ( &acm->usbnet ) ) != 0 )
-               goto err_open;
-
-       return 0;
-
-       usbnet_close ( &acm->usbnet );
- err_open:
-       return rc;
-}
-
-/**
- * Close RNDIS device
- *
- * @v rndis            RNDIS device
- */
-static void acm_close ( struct rndis_device *rndis ) {
-       struct acm_device *acm = rndis->priv;
-
-       /* Close USB network device */
-       usbnet_close ( &acm->usbnet );
-}
-
-/**
- * Transmit packet
- *
- * @v rndis            RNDIS device
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int acm_transmit ( struct rndis_device *rndis,
-                         struct io_buffer *iobuf ) {
-       struct acm_device *acm = rndis->priv;
-       struct rndis_header *header = iobuf->data;
-
-       /* Sanity check */
-       assert ( iob_len ( iobuf ) >= sizeof ( *header ) );
-       assert ( iob_len ( iobuf ) == le32_to_cpu ( header->len ) );
-
-       /* Transmit packet via appropriate mechanism */
-       if ( header->type == cpu_to_le32 ( RNDIS_PACKET_MSG ) ) {
-               return acm_out_transmit ( acm, iobuf );
-       } else {
-               return acm_control_transmit ( acm, iobuf );
-       }
-}
-
-/**
- * Poll for completed and received packets
- *
- * @v rndis            RNDIS device
- */
-static void acm_poll ( struct rndis_device *rndis ) {
-       struct acm_device *acm = rndis->priv;
-       int rc;
-
-       /* Poll USB bus */
-       usb_poll ( acm->bus );
-
-       /* Refill rings */
-       if ( ( rc = usbnet_refill ( &acm->usbnet ) ) != 0 )
-               rndis_rx_err ( rndis, NULL, rc );
-
-       /* Retrieve encapsulated response, if applicable */
-       if ( acm->responded ) {
-
-               /* Clear flag */
-               acm->responded = 0;
-
-               /* Get encapsulated response */
-               if ( ( rc = acm_control_receive ( acm ) ) != 0 )
-                       rndis_rx_err ( rndis, NULL, rc );
-       }
-}
-
-/** USB RNDIS operations */
-static struct rndis_operations acm_operations = {
-       .open           = acm_open,
-       .close          = acm_close,
-       .transmit       = acm_transmit,
-       .poll           = acm_poll,
-};
-
-/******************************************************************************
- *
- * USB interface
- *
- ******************************************************************************
- */
-
-/**
- * Probe device
- *
- * @v func             USB function
- * @v config           Configuration descriptor
- * @ret rc             Return status code
- */
-static int acm_probe ( struct usb_function *func,
-                      struct usb_configuration_descriptor *config ) {
-       struct usb_device *usb = func->usb;
-       struct rndis_device *rndis;
-       struct acm_device *acm;
-       int rc;
-
-       /* Allocate and initialise structure */
-       rndis = alloc_rndis ( sizeof ( *acm ) );
-       if ( ! rndis ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       rndis_init ( rndis, &acm_operations );
-       rndis->netdev->dev = &func->dev;
-       acm = rndis->priv;
-       acm->usb = usb;
-       acm->bus = usb->port->hub->bus;
-       acm->rndis = rndis;
-       usbnet_init ( &acm->usbnet, func, &acm_intr_operations,
-                     &acm_in_operations, &acm_out_operations );
-       usb_refill_init ( &acm->usbnet.intr, 0, 0, ACM_INTR_MAX_FILL );
-       usb_refill_init ( &acm->usbnet.in, 0, ACM_IN_MTU, ACM_IN_MAX_FILL );
-
-       /* Describe USB network device */
-       if ( ( rc = usbnet_describe ( &acm->usbnet, config ) ) != 0 ) {
-               DBGC ( acm, "ACM %p could not describe: %s\n",
-                      acm, strerror ( rc ) );
-               goto err_describe;
-       }
-
-       /* Register RNDIS device */
-       if ( ( rc = register_rndis ( rndis ) ) != 0 )
-               goto err_register;
-
-       usb_func_set_drvdata ( func, acm );
-       return 0;
-
-       unregister_rndis ( rndis );
- err_register:
- err_describe:
-       free_rndis ( rndis );
- err_alloc:
-       return rc;
-}
-
-/**
- * Remove device
- *
- * @v func             USB function
- */
-static void acm_remove ( struct usb_function *func ) {
-       struct acm_device *acm = usb_func_get_drvdata ( func );
-       struct rndis_device *rndis = acm->rndis;
-
-       /* Unregister RNDIS device */
-       unregister_rndis ( rndis );
-
-       /* Free RNDIS device */
-       free_rndis ( rndis );
-}
-
-/** USB CDC-ACM device IDs */
-static struct usb_device_id cdc_acm_ids[] = {
-       {
-               .name = "cdc-acm",
-               .vendor = USB_ANY_ID,
-               .product = USB_ANY_ID,
-       },
-};
-
-/** USB CDC-ACM driver */
-struct usb_driver cdc_acm_driver __usb_driver = {
-       .ids = cdc_acm_ids,
-       .id_count = ( sizeof ( cdc_acm_ids ) / sizeof ( cdc_acm_ids[0] ) ),
-       .class = USB_CLASS_ID ( USB_CLASS_CDC, USB_SUBCLASS_CDC_ACM,
-                               USB_PROTOCOL_ACM_RNDIS ),
-       .score = USB_SCORE_DEPRECATED,
-       .probe = acm_probe,
-       .remove = acm_remove,
-};
-
-/** USB RF-RNDIS device IDs */
-static struct usb_device_id rf_rndis_ids[] = {
-       {
-               .name = "rf-rndis",
-               .vendor = USB_ANY_ID,
-               .product = USB_ANY_ID,
-       },
-};
-
-/** USB RF-RNDIS driver */
-struct usb_driver rf_rndis_driver __usb_driver = {
-       .ids = rf_rndis_ids,
-       .id_count = ( sizeof ( rf_rndis_ids ) / sizeof ( rf_rndis_ids[0] ) ),
-       .class = USB_CLASS_ID ( USB_CLASS_WIRELESS, USB_SUBCLASS_WIRELESS_RADIO,
-                               USB_PROTOCOL_RADIO_RNDIS ),
-       .score = USB_SCORE_DEPRECATED,
-       .probe = acm_probe,
-       .remove = acm_remove,
-};
diff --git a/roms/ipxe/src/drivers/net/acm.h b/roms/ipxe/src/drivers/net/acm.h
deleted file mode 100644 (file)
index d494496..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef _ACM_H
-#define _ACM_H
-
-/** @file
- *
- * USB RNDIS Ethernet driver
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/usb.h>
-#include <ipxe/cdc.h>
-
-/** CDC-ACM subclass */
-#define USB_SUBCLASS_CDC_ACM 0x02
-
-/** CDC-ACM RNDIS device protocol */
-#define USB_PROTOCOL_ACM_RNDIS 0xff
-
-/** Class code for wireless devices */
-#define USB_CLASS_WIRELESS 0xe0
-
-/** Radio frequency device subclass */
-#define USB_SUBCLASS_WIRELESS_RADIO 0x01
-
-/** Radio frequency RNDIS device protocol */
-#define USB_PROTOCOL_RADIO_RNDIS 0x03
-
-/** A USB RNDIS network device */
-struct acm_device {
-       /** USB device */
-       struct usb_device *usb;
-       /** USB bus */
-       struct usb_bus *bus;
-       /** RNDIS device */
-       struct rndis_device *rndis;
-       /** USB network device */
-       struct usbnet_device usbnet;
-
-       /** An encapsulated response is available */
-       int responded;
-};
-
-/** Interrupt maximum fill level
- *
- * This is a policy decision.
- */
-#define ACM_INTR_MAX_FILL 2
-
-/** Bulk IN maximum fill level
- *
- * This is a policy decision.
- */
-#define ACM_IN_MAX_FILL 8
-
-/** Bulk IN buffer size
- *
- * This is a policy decision.
- */
-#define ACM_IN_MTU 2048
-
-/** Encapsulated response buffer size
- *
- * This is a policy decision.
- */
-#define ACM_RESPONSE_MTU 128
-
-#endif /* _ACM_H */
index d6a0373..42ad59f 100644 (file)
@@ -101,6 +101,8 @@ static inline u32 get_unaligned_le32(const void *p)
  */
 #define        ATH_KEYMAX              128     /* max key cache size we handle */
 
+static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
 struct ath_ani {
        int caldone;
        unsigned int longcal_timer;
@@ -227,6 +229,10 @@ struct ath_common {
        int btcoex_enabled;
 };
 
+struct io_buffer *ath_rxbuf_alloc(struct ath_common *common,
+                               u32 len,
+                               u32 *iob_addr);
+
 void ath_hw_setbssidmask(struct ath_common *common);
 int ath_hw_keyreset(struct ath_common *common, u16 entry);
 void ath_hw_cycle_counters_update(struct ath_common *common);
index a6a65a2..92c4ffd 100644 (file)
@@ -85,6 +85,46 @@ static struct pci_device_id ath5k_nics[] = {
        PCI_ROM(0x168c, 0x001d, "ath2417", "Atheros 2417 Nala", AR5K_AR5212),
 };
 
+/* Known SREVs */
+static const struct ath5k_srev_name srev_names[] = {
+       { "5210",       AR5K_VERSION_MAC,       AR5K_SREV_AR5210 },
+       { "5311",       AR5K_VERSION_MAC,       AR5K_SREV_AR5311 },
+       { "5311A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311A },
+       { "5311B",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311B },
+       { "5211",       AR5K_VERSION_MAC,       AR5K_SREV_AR5211 },
+       { "5212",       AR5K_VERSION_MAC,       AR5K_SREV_AR5212 },
+       { "5213",       AR5K_VERSION_MAC,       AR5K_SREV_AR5213 },
+       { "5213A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5213A },
+       { "2413",       AR5K_VERSION_MAC,       AR5K_SREV_AR2413 },
+       { "2414",       AR5K_VERSION_MAC,       AR5K_SREV_AR2414 },
+       { "5424",       AR5K_VERSION_MAC,       AR5K_SREV_AR5424 },
+       { "5413",       AR5K_VERSION_MAC,       AR5K_SREV_AR5413 },
+       { "5414",       AR5K_VERSION_MAC,       AR5K_SREV_AR5414 },
+       { "2415",       AR5K_VERSION_MAC,       AR5K_SREV_AR2415 },
+       { "5416",       AR5K_VERSION_MAC,       AR5K_SREV_AR5416 },
+       { "5418",       AR5K_VERSION_MAC,       AR5K_SREV_AR5418 },
+       { "2425",       AR5K_VERSION_MAC,       AR5K_SREV_AR2425 },
+       { "2417",       AR5K_VERSION_MAC,       AR5K_SREV_AR2417 },
+       { "xxxxx",      AR5K_VERSION_MAC,       AR5K_SREV_UNKNOWN },
+       { "5110",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5110 },
+       { "5111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111 },
+       { "5111A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111A },
+       { "2111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2111 },
+       { "5112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112 },
+       { "5112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112A },
+       { "5112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112B },
+       { "2112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112 },
+       { "2112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112A },
+       { "2112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112B },
+       { "2413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2413 },
+       { "5413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5413 },
+       { "2316",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2316 },
+       { "2317",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2317 },
+       { "5424",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5424 },
+       { "5133",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5133 },
+       { "xxxxx",      AR5K_VERSION_RAD,       AR5K_SREV_UNKNOWN },
+};
+
 #define ATH5K_SPMBL_NO   1
 #define ATH5K_SPMBL_YES  2
 #define ATH5K_SPMBL_BOTH 3
index c2a66a4..7891d39 100644 (file)
@@ -1219,12 +1219,12 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
 
        /* Update radio registers */
        ath5k_hw_reg_write(ah, (phy_sig & ~(AR5K_PHY_SIG_FIRPWR)) |
-               AR5K_REG_SM(-1U, AR5K_PHY_SIG_FIRPWR), AR5K_PHY_SIG);
+               AR5K_REG_SM(-1, AR5K_PHY_SIG_FIRPWR), AR5K_PHY_SIG);
 
        ath5k_hw_reg_write(ah, (phy_agc & ~(AR5K_PHY_AGCCOARSE_HI |
                        AR5K_PHY_AGCCOARSE_LO)) |
-               AR5K_REG_SM(-1U, AR5K_PHY_AGCCOARSE_HI) |
-               AR5K_REG_SM(-127U, AR5K_PHY_AGCCOARSE_LO), AR5K_PHY_AGCCOARSE);
+               AR5K_REG_SM(-1, AR5K_PHY_AGCCOARSE_HI) |
+               AR5K_REG_SM(-127, AR5K_PHY_AGCCOARSE_LO), AR5K_PHY_AGCCOARSE);
 
        ath5k_hw_reg_write(ah, (phy_sat & ~(AR5K_PHY_ADCSAT_ICNT |
                        AR5K_PHY_ADCSAT_THR)) |
index 73765a7..2f36a4e 100644 (file)
@@ -134,6 +134,14 @@ static int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
        return 0;
 }
 
+
+/*
+ * index into rates for control rates, we can set it up like this because
+ * this is only used for AR5212 and we know it supports G mode
+ */
+static const unsigned int control_rates[] =
+       { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
+
 /**
  * ath5k_hw_write_rate_duration - fill rate code to duration table
  *
index f9a92c9..d7a5ac0 100644 (file)
@@ -16,7 +16,7 @@
 
 FILE_LICENCE ( BSD2 );
 
-static __unused const u32 ar9280Modes_9280_2[][6] = {
+static const u32 ar9280Modes_9280_2[][6] = {
        {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0},
        {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0},
        {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180},
@@ -65,7 +65,7 @@ static __unused const u32 ar9280Modes_9280_2[][6] = {
        {0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000},
 };
 
-static __unused const u32 ar9280Common_9280_2[][2] = {
+static const u32 ar9280Common_9280_2[][2] = {
        /* Addr      allmodes  */
        {0x0000000c, 0x00000000},
        {0x00000030, 0x00020015},
@@ -409,7 +409,7 @@ static __unused const u32 ar9280Common_9280_2[][2] = {
        {0x00007898, 0x2a850160},
 };
 
-static __unused const u32 ar9280Modes_fast_clock_9280_2[][3] = {
+static const u32 ar9280Modes_fast_clock_9280_2[][3] = {
        /* Addr      5G_HT20     5G_HT40   */
        {0x00001030, 0x00000268, 0x000004d0},
        {0x00001070, 0x0000018c, 0x00000318},
@@ -426,7 +426,7 @@ static __unused const u32 ar9280Modes_fast_clock_9280_2[][3] = {
        {0x00009918, 0x0000000b, 0x00000016},
 };
 
-static __unused const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = {
+static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = {
        {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290},
        {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300},
        {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304},
@@ -559,7 +559,7 @@ static __unused const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = {
        {0x0000a848, 0x00001066, 0x00001066, 0x00001055, 0x00001055, 0x00001055},
 };
 
-static __unused const u32 ar9280Modes_original_rxgain_9280_2[][6] = {
+static const u32 ar9280Modes_original_rxgain_9280_2[][6] = {
        {0x00009a00, 0x00008184, 0x00008184, 0x00008000, 0x00008000, 0x00008000},
        {0x00009a04, 0x00008188, 0x00008188, 0x00008000, 0x00008000, 0x00008000},
        {0x00009a08, 0x0000818c, 0x0000818c, 0x00008000, 0x00008000, 0x00008000},
@@ -692,7 +692,7 @@ static __unused const u32 ar9280Modes_original_rxgain_9280_2[][6] = {
        {0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063},
 };
 
-static __unused const u32 ar9280Modes_backoff_13db_rxgain_9280_2[][6] = {
+static const u32 ar9280Modes_backoff_13db_rxgain_9280_2[][6] = {
        {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290},
        {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300},
        {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304},
@@ -825,7 +825,7 @@ static __unused const u32 ar9280Modes_backoff_13db_rxgain_9280_2[][6] = {
        {0x0000a848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a},
 };
 
-static __unused const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = {
+static const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = {
        {0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652},
        {0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce},
        {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -859,7 +859,7 @@ static __unused const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = {
        {0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480},
 };
 
-static __unused const u32 ar9280Modes_original_tx_gain_9280_2[][6] = {
+static const u32 ar9280Modes_original_tx_gain_9280_2[][6] = {
        {0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652},
        {0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce},
        {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -893,7 +893,7 @@ static __unused const u32 ar9280Modes_original_tx_gain_9280_2[][6] = {
        {0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480},
 };
 
-static __unused const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = {
+static const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = {
        /* Addr      allmodes  */
        {0x00004040, 0x9248fd00},
        {0x00004040, 0x24924924},
@@ -907,7 +907,7 @@ static __unused const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = {
        {0x00004044, 0x00000000},
 };
 
-static __unused const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
+static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
        /* Addr      allmodes  */
        {0x00004040, 0x9248fd00},
        {0x00004040, 0x24924924},
@@ -921,7 +921,7 @@ static __unused const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
        {0x00004044, 0x00000000},
 };
 
-static __unused const u32 ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
+static const u32 ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
        /* Addr      allmodes  */
        {0x00004040, 0x9248fd00},
        {0x00004040, 0x24924924},
@@ -935,7 +935,7 @@ static __unused const u32 ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
        {0x00004044, 0x00000000},
 };
 
-static __unused const u32 ar9285PciePhy_clkreq_off_L1_9285[][2] = {
+static const u32 ar9285PciePhy_clkreq_off_L1_9285[][2] = {
        /* Addr      allmodes  */
        {0x00004040, 0x9248fd00},
        {0x00004040, 0x24924924},
@@ -949,7 +949,7 @@ static __unused const u32 ar9285PciePhy_clkreq_off_L1_9285[][2] = {
        {0x00004044, 0x00000000},
 };
 
-static __unused const u32 ar9285Modes_9285_1_2[][6] = {
+static const u32 ar9285Modes_9285_1_2[][6] = {
        {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0},
        {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0},
        {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180},
@@ -1254,7 +1254,7 @@ static __unused const u32 ar9285Modes_9285_1_2[][6] = {
        {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e},
 };
 
-static __unused const u32 ar9285Common_9285_1_2[][2] = {
+static const u32 ar9285Common_9285_1_2[][2] = {
        /* Addr      allmodes  */
        {0x0000000c, 0x00000000},
        {0x00000030, 0x00020045},
@@ -1574,7 +1574,7 @@ static __unused const u32 ar9285Common_9285_1_2[][2] = {
        {0x00007870, 0x10142c00},
 };
 
-static __unused const u32 ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
+static const u32 ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
        {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000},
        {0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000},
@@ -1614,7 +1614,7 @@ static __unused const u32 ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
        {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7},
 };
 
-static __unused const u32 ar9285Modes_original_tx_gain_9285_1_2[][6] = {
+static const u32 ar9285Modes_original_tx_gain_9285_1_2[][6] = {
        {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000},
        {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000},
@@ -1654,7 +1654,7 @@ static __unused const u32 ar9285Modes_original_tx_gain_9285_1_2[][6] = {
        {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c},
 };
 
-static __unused const u32 ar9285Modes_XE2_0_normal_power[][6] = {
+static const u32 ar9285Modes_XE2_0_normal_power[][6] = {
        {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000},
        {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000},
@@ -1694,7 +1694,7 @@ static __unused const u32 ar9285Modes_XE2_0_normal_power[][6] = {
        {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c},
 };
 
-static __unused const u32 ar9285Modes_XE2_0_high_power[][6] = {
+static const u32 ar9285Modes_XE2_0_high_power[][6] = {
        {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000},
        {0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000},
@@ -1734,7 +1734,7 @@ static __unused const u32 ar9285Modes_XE2_0_high_power[][6] = {
        {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7},
 };
 
-static __unused const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
+static const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
        /* Addr      allmodes  */
        {0x00004040, 0x9248fd00},
        {0x00004040, 0x24924924},
@@ -1748,7 +1748,7 @@ static __unused const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
        {0x00004044, 0x00000000},
 };
 
-static __unused const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
+static const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
        /* Addr      allmodes  */
        {0x00004040, 0x9248fd00},
        {0x00004040, 0x24924924},
@@ -1762,7 +1762,7 @@ static __unused const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
        {0x00004044, 0x00000000},
 };
 
-static __unused const u32 ar9287Modes_9287_1_1[][6] = {
+static const u32 ar9287Modes_9287_1_1[][6] = {
        {0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0},
        {0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0},
        {0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180},
@@ -1808,7 +1808,7 @@ static __unused const u32 ar9287Modes_9287_1_1[][6] = {
        {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 };
 
-static __unused const u32 ar9287Common_9287_1_1[][2] = {
+static const u32 ar9287Common_9287_1_1[][2] = {
        /* Addr      allmodes  */
        {0x0000000c, 0x00000000},
        {0x00000030, 0x00020015},
@@ -2177,21 +2177,21 @@ static __unused const u32 ar9287Common_9287_1_1[][2] = {
        {0x000078b8, 0x2a850160},
 };
 
-static __unused const u32 ar9287Common_normal_cck_fir_coeff_9287_1_1[][2] = {
+static const u32 ar9287Common_normal_cck_fir_coeff_9287_1_1[][2] = {
        /* Addr      allmodes  */
        {0x0000a1f4, 0x00fffeff},
        {0x0000a1f8, 0x00f5f9ff},
        {0x0000a1fc, 0xb79f6427},
 };
 
-static __unused const u32 ar9287Common_japan_2484_cck_fir_coeff_9287_1_1[][2] = {
+static const u32 ar9287Common_japan_2484_cck_fir_coeff_9287_1_1[][2] = {
        /* Addr      allmodes  */
        {0x0000a1f4, 0x00000000},
        {0x0000a1f8, 0xefff0301},
        {0x0000a1fc, 0xca9228ee},
 };
 
-static __unused const u32 ar9287Modes_tx_gain_9287_1_1[][6] = {
+static const u32 ar9287Modes_tx_gain_9287_1_1[][6] = {
        {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002},
        {0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004},
@@ -2239,7 +2239,7 @@ static __unused const u32 ar9287Modes_tx_gain_9287_1_1[][6] = {
        {0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000},
 };
 
-static __unused const u32 ar9287Modes_rx_gain_9287_1_1[][6] = {
+static const u32 ar9287Modes_rx_gain_9287_1_1[][6] = {
        {0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120},
        {0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124},
        {0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128},
@@ -2500,7 +2500,7 @@ static __unused const u32 ar9287Modes_rx_gain_9287_1_1[][6] = {
        {0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067},
 };
 
-static __unused const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
+static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
        /* Addr      allmodes  */
        {0x00004040, 0x9248fd00},
        {0x00004040, 0x24924924},
@@ -2514,7 +2514,7 @@ static __unused const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
        {0x00004044, 0x00000000},
 };
 
-static __unused const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
+static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
        /* Addr      allmodes  */
        {0x00004040, 0x9248fd00},
        {0x00004040, 0x24924924},
@@ -2528,7 +2528,7 @@ static __unused const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
        {0x00004044, 0x00000000},
 };
 
-static __unused const u32 ar9271Modes_9271[][6] = {
+static const u32 ar9271Modes_9271[][6] = {
        {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0},
        {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0},
        {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180},
@@ -2834,7 +2834,7 @@ static __unused const u32 ar9271Modes_9271[][6] = {
        {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e},
 };
 
-static __unused const u32 ar9271Common_9271[][2] = {
+static const u32 ar9271Common_9271[][2] = {
        /* Addr      allmodes  */
        {0x0000000c, 0x00000000},
        {0x00000030, 0x00020045},
@@ -3163,26 +3163,26 @@ static __unused const u32 ar9271Common_9271[][2] = {
        {0x0000d384, 0xf3307ff0},
 };
 
-static __unused const u32 ar9271Common_normal_cck_fir_coeff_9271[][2] = {
+static const u32 ar9271Common_normal_cck_fir_coeff_9271[][2] = {
        /* Addr      allmodes  */
        {0x0000a1f4, 0x00fffeff},
        {0x0000a1f8, 0x00f5f9ff},
        {0x0000a1fc, 0xb79f6427},
 };
 
-static __unused const u32 ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = {
+static const u32 ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = {
        /* Addr      allmodes  */
        {0x0000a1f4, 0x00000000},
        {0x0000a1f8, 0xefff0301},
        {0x0000a1fc, 0xca9228ee},
 };
 
-static __unused const u32 ar9271Modes_9271_1_0_only[][6] = {
+static const u32 ar9271Modes_9271_1_0_only[][6] = {
        {0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311},
        {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001},
 };
 
-static __unused const u32 ar9271Modes_9271_ANI_reg[][6] = {
+static const u32 ar9271Modes_9271_ANI_reg[][6] = {
        {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2},
        {0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e},
        {0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e},
@@ -3193,7 +3193,7 @@ static __unused const u32 ar9271Modes_9271_ANI_reg[][6] = {
        {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
 };
 
-static __unused const u32 ar9271Modes_normal_power_tx_gain_9271[][6] = {
+static const u32 ar9271Modes_normal_power_tx_gain_9271[][6] = {
        {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000},
        {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000},
@@ -3229,7 +3229,7 @@ static __unused const u32 ar9271Modes_normal_power_tx_gain_9271[][6] = {
        {0x0000a3e0, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd},
 };
 
-static __unused const u32 ar9271Modes_high_power_tx_gain_9271[][6] = {
+static const u32 ar9271Modes_high_power_tx_gain_9271[][6] = {
        {0x0000a300, 0x00000000, 0x00000000, 0x00010000, 0x00010000, 0x00000000},
        {0x0000a304, 0x00000000, 0x00000000, 0x00016200, 0x00016200, 0x00000000},
        {0x0000a308, 0x00000000, 0x00000000, 0x00018201, 0x00018201, 0x00000000},
index b1303bb..e8ac70d 100644 (file)
@@ -19,7 +19,7 @@
 
 /* AR9003 2.2 */
 
-static __unused const u32 ar9300_2p2_radio_postamble[][5] = {
+static const u32 ar9300_2p2_radio_postamble[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
        {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
@@ -32,7 +32,7 @@ static __unused const u32 ar9300_2p2_radio_postamble[][5] = {
        {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
 };
 
-static __unused const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
+static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
        {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
@@ -138,7 +138,7 @@ static __unused const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
        {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
 };
 
-static __unused const u32 ar9300Modes_fast_clock_2p2[][3] = {
+static const u32 ar9300Modes_fast_clock_2p2[][3] = {
        /* Addr      5G_HT20     5G_HT40   */
        {0x00001030, 0x00000268, 0x000004d0},
        {0x00001070, 0x0000018c, 0x00000318},
@@ -151,7 +151,7 @@ static __unused const u32 ar9300Modes_fast_clock_2p2[][3] = {
        {0x0000a254, 0x00000898, 0x00001130},
 };
 
-static __unused const u32 ar9300_2p2_radio_core[][2] = {
+static const u32 ar9300_2p2_radio_core[][2] = {
        /* Addr      allmodes  */
        {0x00016000, 0x36db6db6},
        {0x00016004, 0x6db6db40},
@@ -295,7 +295,7 @@ static __unused const u32 ar9300_2p2_radio_core[][2] = {
        {0x00016bd4, 0x00000000},
 };
 
-static __unused const u32 ar9300Common_rx_gain_table_merlin_2p2[][2] = {
+static const u32 ar9300Common_rx_gain_table_merlin_2p2[][2] = {
        /* Addr      allmodes  */
        {0x0000a000, 0x02000101},
        {0x0000a004, 0x02000102},
@@ -555,7 +555,7 @@ static __unused const u32 ar9300Common_rx_gain_table_merlin_2p2[][2] = {
        {0x0000b1fc, 0x00000776},
 };
 
-static __unused const u32 ar9300_2p2_mac_postamble[][5] = {
+static const u32 ar9300_2p2_mac_postamble[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
        {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
@@ -567,12 +567,12 @@ static __unused const u32 ar9300_2p2_mac_postamble[][5] = {
        {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
 };
 
-static __unused const u32 ar9300_2p2_soc_postamble[][5] = {
+static const u32 ar9300_2p2_soc_postamble[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
 };
 
-static __unused const u32 ar9200_merlin_2p2_radio_core[][2] = {
+static const u32 ar9200_merlin_2p2_radio_core[][2] = {
        /* Addr      allmodes  */
        {0x00007800, 0x00040000},
        {0x00007804, 0xdb005012},
@@ -614,7 +614,7 @@ static __unused const u32 ar9200_merlin_2p2_radio_core[][2] = {
        {0x00007894, 0x5a108000},
 };
 
-static __unused const u32 ar9300_2p2_baseband_postamble[][5] = {
+static const u32 ar9300_2p2_baseband_postamble[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
        {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
@@ -670,7 +670,7 @@ static __unused const u32 ar9300_2p2_baseband_postamble[][5] = {
        {0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
 };
 
-static __unused const u32 ar9300_2p2_baseband_core[][2] = {
+static const u32 ar9300_2p2_baseband_core[][2] = {
        /* Addr      allmodes  */
        {0x00009800, 0xafe68e30},
        {0x00009804, 0xfd14e000},
@@ -833,7 +833,7 @@ static __unused const u32 ar9300_2p2_baseband_core[][2] = {
        {0x0000c420, 0x00000000},
 };
 
-static __unused const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
+static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
        {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
@@ -939,7 +939,7 @@ static __unused const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
        {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
 };
 
-static __unused const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
+static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
        {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
@@ -1045,7 +1045,7 @@ static __unused const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
        {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
 };
 
-static __unused const u32 ar9300Common_rx_gain_table_2p2[][2] = {
+static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
        /* Addr      allmodes  */
        {0x0000a000, 0x00010000},
        {0x0000a004, 0x00030002},
@@ -1305,7 +1305,7 @@ static __unused const u32 ar9300Common_rx_gain_table_2p2[][2] = {
        {0x0000b1fc, 0x00000196},
 };
 
-static __unused const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = {
+static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
        {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
@@ -1411,7 +1411,7 @@ static __unused const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = {
        {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
 };
 
-static __unused const u32 ar9300_2p2_mac_core[][2] = {
+static const u32 ar9300_2p2_mac_core[][2] = {
        /* Addr      allmodes  */
        {0x00000008, 0x00000000},
        {0x00000030, 0x00020085},
@@ -1570,7 +1570,7 @@ static __unused const u32 ar9300_2p2_mac_core[][2] = {
        {0x000083d0, 0x000301ff},
 };
 
-static __unused const u32 ar9300Common_wo_xlna_rx_gain_table_2p2[][2] = {
+static const u32 ar9300Common_wo_xlna_rx_gain_table_2p2[][2] = {
        /* Addr      allmodes  */
        {0x0000a000, 0x00010000},
        {0x0000a004, 0x00030002},
@@ -1830,7 +1830,7 @@ static __unused const u32 ar9300Common_wo_xlna_rx_gain_table_2p2[][2] = {
        {0x0000b1fc, 0x00000196},
 };
 
-static __unused const u32 ar9300_2p2_soc_preamble[][2] = {
+static const u32 ar9300_2p2_soc_preamble[][2] = {
        /* Addr      allmodes  */
        {0x000040a4, 0x00a0c1c9},
        {0x00007008, 0x00000000},
@@ -1840,21 +1840,21 @@ static __unused const u32 ar9300_2p2_soc_preamble[][2] = {
        {0x00007048, 0x00000008},
 };
 
-static __unused const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
+static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
        /* Addr      allmodes  */
        {0x00004040, 0x0821265e},
        {0x00004040, 0x0008003b},
        {0x00004044, 0x00000000},
 };
 
-static __unused const u32 ar9300PciePhy_clkreq_enable_L1_2p2[][2] = {
+static const u32 ar9300PciePhy_clkreq_enable_L1_2p2[][2] = {
        /* Addr      allmodes  */
        {0x00004040, 0x08253e5e},
        {0x00004040, 0x0008003b},
        {0x00004044, 0x00000000},
 };
 
-static __unused const u32 ar9300PciePhy_clkreq_disable_L1_2p2[][2] = {
+static const u32 ar9300PciePhy_clkreq_disable_L1_2p2[][2] = {
        /* Addr      allmodes  */
        {0x00004040, 0x08213e5e},
        {0x00004040, 0x0008003b},
index 784080b..815a8af 100644 (file)
@@ -17,7 +17,7 @@
 #ifndef INITVALS_9340_H
 #define INITVALS_9340_H
 
-static __unused const u32 ar9340_1p0_radio_postamble[][5] = {
+static const u32 ar9340_1p0_radio_postamble[][5] = {
        /*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
        {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800},
        {0x0001610c, 0x08000000, 0x08000000, 0x00000000, 0x00000000},
@@ -26,7 +26,7 @@ static __unused const u32 ar9340_1p0_radio_postamble[][5] = {
        {0x00016540, 0x10804000, 0x10804000, 0x50804000, 0x50804000},
 };
 
-static __unused const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = {
+static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = {
        /*   Addr     5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
        {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
        {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -99,7 +99,7 @@ static __unused const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = {
        {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
 };
 
-static __unused const u32 ar9340Modes_fast_clock_1p0[][3] = {
+static const u32 ar9340Modes_fast_clock_1p0[][3] = {
        /*  Addr      5G_HT20     5G_HT40  */
        {0x00001030, 0x00000268, 0x000004d0},
        {0x00001070, 0x0000018c, 0x00000318},
@@ -112,7 +112,7 @@ static __unused const u32 ar9340Modes_fast_clock_1p0[][3] = {
        {0x0000a254, 0x00000898, 0x00001130},
 };
 
-static __unused const u32 ar9340_1p0_radio_core[][2] = {
+static const u32 ar9340_1p0_radio_core[][2] = {
        /*  Addr     allmodes  */
        {0x00016000, 0x36db6db6},
        {0x00016004, 0x6db6db40},
@@ -218,13 +218,13 @@ static __unused const u32 ar9340_1p0_radio_core[][2] = {
        {0x000167d4, 0x00000000},
 };
 
-static __unused const u32 ar9340_1p0_radio_core_40M[][2] = {
+static const u32 ar9340_1p0_radio_core_40M[][2] = {
        {0x0001609c, 0x02566f3a},
        {0x000160ac, 0xa4647c00},
        {0x000160b0, 0x01885f5a},
 };
 
-static __unused const u32 ar9340_1p0_mac_postamble[][5] = {
+static const u32 ar9340_1p0_mac_postamble[][5] = {
        /* Addr       5G_HT20     5G_HT40     2G_HT40    2G_HT20  */
        {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
        {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
@@ -236,12 +236,12 @@ static __unused const u32 ar9340_1p0_mac_postamble[][5] = {
        {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
 };
 
-static __unused const u32 ar9340_1p0_soc_postamble[][5] = {
+static const u32 ar9340_1p0_soc_postamble[][5] = {
        /*   Addr     5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
        {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
 };
 
-static __unused const u32 ar9340_1p0_baseband_postamble[][5] = {
+static const u32 ar9340_1p0_baseband_postamble[][5] = {
        /*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
        {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
        {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e},
@@ -288,7 +288,7 @@ static __unused const u32 ar9340_1p0_baseband_postamble[][5] = {
        {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
 };
 
-static __unused const u32 ar9340_1p0_baseband_core[][2] = {
+static const u32 ar9340_1p0_baseband_core[][2] = {
        /*  Addr     allmodes  */
        {0x00009800, 0xafe68e30},
        {0x00009804, 0xfd14e000},
@@ -464,7 +464,7 @@ static __unused const u32 ar9340_1p0_baseband_core[][2] = {
        {0x0000b420, 0x00000000},
 };
 
-static __unused const u32 ar9340Modes_high_power_tx_gain_table_1p0[][5] = {
+static const u32 ar9340Modes_high_power_tx_gain_table_1p0[][5] = {
        /*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
        {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
        {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
@@ -537,7 +537,7 @@ static __unused const u32 ar9340Modes_high_power_tx_gain_table_1p0[][5] = {
        {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
 };
 
-static __unused const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = {
+static const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = {
        /*  Addr       5G_HT20    5G_HT40     2G_HT40     2G_HT20  */
        {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
        {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
@@ -609,7 +609,7 @@ static __unused const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = {
        {0x00016444, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4},
        {0x00016448, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266},
 };
-static __unused const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = {
+static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = {
        /*  Addr      5G_HT20      5G_HT40     2G_HT40    2G_HT20  */
        {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
        {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
@@ -683,7 +683,7 @@ static __unused const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = {
 };
 
 
-static __unused const u32 ar9340Common_rx_gain_table_1p0[][2] = {
+static const u32 ar9340Common_rx_gain_table_1p0[][2] = {
        /*   Addr     allmodes */
        {0x0000a000, 0x00010000},
        {0x0000a004, 0x00030002},
@@ -943,7 +943,7 @@ static __unused const u32 ar9340Common_rx_gain_table_1p0[][2] = {
        {0x0000b1fc, 0x00000196},
 };
 
-static __unused const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = {
+static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = {
        /*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
        {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
        {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -1016,7 +1016,7 @@ static __unused const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = {
        {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
 };
 
-static __unused const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = {
+static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = {
        /*  Addr       5G_HT20     5G_HT40     2G_HT40    2G_HT20  */
        {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
        {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -1089,7 +1089,7 @@ static __unused const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = {
        {0x00016448, 0x24927266, 0x24927266, 0x8e482266, 0x8e482266},
 };
 
-static __unused const u32 ar9340_1p0_mac_core[][2] = {
+static const u32 ar9340_1p0_mac_core[][2] = {
        /*    Addr        allmodes        */
        {0x00000008, 0x00000000},
        {0x00000030, 0x00020085},
@@ -1253,7 +1253,7 @@ static __unused const u32 ar9340_1p0_mac_core[][2] = {
        {0x000083d0, 0x000301ff},
 };
 
-static __unused const u32 ar9340Common_wo_xlna_rx_gain_table_1p0[][2] = {
+static const u32 ar9340Common_wo_xlna_rx_gain_table_1p0[][2] = {
        /*    Addr        allmodes        */
        {0x0000a000, 0x00010000},
        {0x0000a004, 0x00030002},
@@ -1513,7 +1513,7 @@ static __unused const u32 ar9340Common_wo_xlna_rx_gain_table_1p0[][2] = {
        {0x0000b1fc, 0x00000196},
 };
 
-static __unused const u32 ar9340_1p0_soc_preamble[][2] = {
+static const u32 ar9340_1p0_soc_preamble[][2] = {
        /*    Addr        allmodes        */
        {0x000040a4, 0x00a0c1c9},
        {0x00007008, 0x00000000},
index c854398..611ea6c 100644 (file)
@@ -17,7 +17,7 @@
 #ifndef INITVALS_9485_H
 #define INITVALS_9485_H
 
-static __unused const u32 ar9485_1_1_mac_core[][2] = {
+static const u32 ar9485_1_1_mac_core[][2] = {
        /*  Addr       allmodes */
        {0x00000008, 0x00000000},
        {0x00000030, 0x00020085},
@@ -179,7 +179,7 @@ static __unused const u32 ar9485_1_1_mac_core[][2] = {
        {0x000083d0, 0x000301ff},
 };
 
-static __unused const u32 ar9485_1_1_baseband_core[][2] = {
+static const u32 ar9485_1_1_baseband_core[][2] = {
        /* Addr       allmodes */
        {0x00009800, 0xafe68e30},
        {0x00009804, 0xfd14e000},
@@ -316,7 +316,7 @@ static __unused const u32 ar9485_1_1_baseband_core[][2] = {
        {0x0000a7dc, 0x00000000},
 };
 
-static __unused const u32 ar9485Common_1_1[][2] = {
+static const u32 ar9485Common_1_1[][2] = {
        /*  Addr      allmodes */
        {0x00007010, 0x00000022},
        {0x00007020, 0x00000000},
@@ -324,7 +324,7 @@ static __unused const u32 ar9485Common_1_1[][2] = {
        {0x00007038, 0x000004c2},
 };
 
-static __unused const u32 ar9485_1_1_baseband_postamble[][5] = {
+static const u32 ar9485_1_1_baseband_postamble[][5] = {
        /* Addr       5G_HT20        5G_HT40       2G_HT40       2G_HT20 */
        {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
        {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e},
@@ -369,7 +369,7 @@ static __unused const u32 ar9485_1_1_baseband_postamble[][5] = {
        {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 };
 
-static __unused const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = {
+static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = {
        /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20 */
        {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
        {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
@@ -442,7 +442,7 @@ static __unused const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = {
        {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
 };
 
-static __unused const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = {
+static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = {
        /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20  */
        {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
        {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
@@ -515,7 +515,7 @@ static __unused const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = {
        {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
 };
 
-static __unused const u32 ar9485_1_1_radio_postamble[][2] = {
+static const u32 ar9485_1_1_radio_postamble[][2] = {
        /* Addr        allmodes */
        {0x0001609c, 0x0b283f31},
        {0x000160ac, 0x24611800},
@@ -524,7 +524,7 @@ static __unused const u32 ar9485_1_1_radio_postamble[][2] = {
        {0x00016140, 0x10804008},
 };
 
-static __unused const u32 ar9485_1_1_mac_postamble[][5] = {
+static const u32 ar9485_1_1_mac_postamble[][5] = {
        /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20 */
        {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
        {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
@@ -536,7 +536,7 @@ static __unused const u32 ar9485_1_1_mac_postamble[][5] = {
        {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
 };
 
-static __unused const u32 ar9485_1_1_radio_core[][2] = {
+static const u32 ar9485_1_1_radio_core[][2] = {
        /* Addr        allmodes */
        {0x00016000, 0x36db6db6},
        {0x00016004, 0x6db6db40},
@@ -601,14 +601,14 @@ static __unused const u32 ar9485_1_1_radio_core[][2] = {
        {0x00016c44, 0x12000000},
 };
 
-static __unused const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = {
+static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = {
        /* Addr        allmodes */
        {0x00018c00, 0x10052e5e},
        {0x00018c04, 0x000801d8},
        {0x00018c08, 0x0000080c},
 };
 
-static __unused const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
+static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
        /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20 */
        {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
        {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
@@ -681,7 +681,7 @@ static __unused const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
        {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
 };
 
-static __unused const u32 ar9485_1_1[][2] = {
+static const u32 ar9485_1_1[][2] = {
        /* Addr        allmodes */
        {0x0000a580, 0x00000000},
        {0x0000a584, 0x00000000},
@@ -701,7 +701,7 @@ static __unused const u32 ar9485_1_1[][2] = {
        {0x0000a5bc, 0x00000000},
 };
 
-static __unused const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = {
+static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = {
        /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20 */
        {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003},
        {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
@@ -774,14 +774,14 @@ static __unused const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = {
        {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
 };
 
-static __unused const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = {
+static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = {
        /* Addr        allmodes */
        {0x00018c00, 0x10013e5e},
        {0x00018c04, 0x000801d8},
        {0x00018c08, 0x0000080c},
 };
 
-static __unused const u32 ar9485_1_1_soc_preamble[][2] = {
+static const u32 ar9485_1_1_soc_preamble[][2] = {
        /* Addr        allmodes */
        {0x00004014, 0xba280400},
        {0x00004090, 0x00aa10aa},
@@ -793,14 +793,14 @@ static __unused const u32 ar9485_1_1_soc_preamble[][2] = {
        {0x00007048, 0x00000002},
 };
 
-static __unused const u32 ar9485_1_1_baseband_core_txfir_coeff_japan_2484[][2] = {
+static const u32 ar9485_1_1_baseband_core_txfir_coeff_japan_2484[][2] = {
        /* Addr        allmodes */
        {0x0000a398, 0x00000000},
        {0x0000a39c, 0x6f7f0301},
        {0x0000a3a0, 0xca9228ee},
 };
 
-static __unused const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = {
+static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = {
        /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20  */
        {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
        {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
@@ -873,21 +873,21 @@ static __unused const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = {
        {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
 };
 
-static __unused const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = {
+static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = {
        /* Addr        5G_HT2        5G_HT40  */
        {0x00009e00, 0x03721821, 0x03721821},
        {0x0000a230, 0x0000400b, 0x00004016},
        {0x0000a254, 0x00000898, 0x00001130},
 };
 
-static __unused const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
+static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
        /* Addr        allmodes  */
        {0x00018c00, 0x10012e5e},
        {0x00018c04, 0x000801d8},
        {0x00018c08, 0x0000080c},
 };
 
-static __unused const u32 ar9485_common_rx_gain_1_1[][2] = {
+static const u32 ar9485_common_rx_gain_1_1[][2] = {
        /* Addr        allmodes */
        {0x0000a000, 0x00010000},
        {0x0000a004, 0x00030002},
@@ -1019,14 +1019,14 @@ static __unused const u32 ar9485_common_rx_gain_1_1[][2] = {
        {0x0000a1fc, 0x00000296},
 };
 
-static __unused const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = {
+static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = {
        /* Addr        allmodes */
        {0x00018c00, 0x10053e5e},
        {0x00018c04, 0x000801d8},
        {0x00018c08, 0x0000080c},
 };
 
-static __unused const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = {
+static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = {
        /* Addr        allmodes */
        {0x0000a000, 0x00060005},
        {0x0000a004, 0x00810080},
index a204237..f552aca 100644 (file)
@@ -368,9 +368,10 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
 
        if (match) {
                if (AR_SREV_9287(ah)) {
+                       /* FIXME: array overrun? */
                        for (i = 0; i < numXpdGains; i++) {
                                minPwrT4[i] = data_9287[idxL].pwrPdg[i][0];
-                               maxPwrT4[i] = data_9287[idxL].pwrPdg[i][intercepts - 1];
+                               maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4];
                                ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
                                                data_9287[idxL].pwrPdg[i],
                                                data_9287[idxL].vpdPdg[i],
@@ -380,7 +381,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
                } else if (eeprom_4k) {
                        for (i = 0; i < numXpdGains; i++) {
                                minPwrT4[i] = data_4k[idxL].pwrPdg[i][0];
-                               maxPwrT4[i] = data_4k[idxL].pwrPdg[i][intercepts - 1];
+                               maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4];
                                ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
                                                data_4k[idxL].pwrPdg[i],
                                                data_4k[idxL].vpdPdg[i],
@@ -390,7 +391,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
                } else {
                        for (i = 0; i < numXpdGains; i++) {
                                minPwrT4[i] = data_def[idxL].pwrPdg[i][0];
-                               maxPwrT4[i] = data_def[idxL].pwrPdg[i][intercepts - 1];
+                               maxPwrT4[i] = data_def[idxL].pwrPdg[i][4];
                                ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
                                                data_def[idxL].pwrPdg[i],
                                                data_def[idxL].vpdPdg[i],
index 98a0d6d..03de770 100644 (file)
@@ -22,7 +22,6 @@ FILE_LICENCE ( BSD2 );
 #include <ipxe/malloc.h>
 #include <ipxe/pci_io.h>
 #include <ipxe/pci.h>
-#include <ipxe/ethernet.h>
 
 #include "ath9k.h"
 
@@ -350,7 +349,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
        ath9k_hw_set_diversity(sc->sc_ah, 1);
        sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
 
-       memcpy(common->bssidmask, eth_broadcast, ETH_ALEN);
+       memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
 }
 
 static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
index 0ffe9d4..ba363c6 100644 (file)
@@ -98,6 +98,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct io_buffer *iob;
+       u32 *iob_addr = NULL;
        struct ath_buf *bf;
        int error = 0;
 
@@ -121,14 +122,15 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
        }
 
        list_for_each_entry(bf, &sc->rx.rxbuf, list) {
-               iob = alloc_iob_raw ( common->rx_bufsize, common->cachelsz, 0 );
+               iob = ath_rxbuf_alloc(common, common->rx_bufsize,
+                                     iob_addr);
                if (iob == NULL) {
                        error = -ENOMEM;
                        goto err;
                }
 
                bf->bf_mpdu = iob;
-               bf->bf_buf_addr = virt_to_bus ( iob->data );
+               bf->bf_buf_addr = *iob_addr;
        }
        sc->rx.rxlink = NULL;
 
@@ -431,6 +433,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, int hp __unused)
 {
        struct ath_buf *bf;
        struct io_buffer *iob = NULL, *requeue_iob;
+       u32 *requeue_iob_addr = NULL;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
        /*
@@ -473,8 +476,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, int hp __unused)
 
                /* Ensure we always have an iob to requeue once we are done
                 * processing the current buffer's iob */
-               requeue_iob = alloc_iob_raw ( common->rx_bufsize,
-                                             common->cachelsz, 0 );
+               requeue_iob = ath_rxbuf_alloc(common, common->rx_bufsize, requeue_iob_addr);
 
                /* If there is no memory we ignore the current RX'd frame,
                 * tell hardware it can give us a new frame using the old
@@ -489,7 +491,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, int hp __unused)
 
                /* We will now give hardware our shiny new allocated iob */
                bf->bf_mpdu = requeue_iob;
-               bf->bf_buf_addr = virt_to_bus ( requeue_iob->data );
+               bf->bf_buf_addr = *requeue_iob_addr;
 
                /*
                 * change the default rx antenna if rx diversity chooses the
diff --git a/roms/ipxe/src/drivers/net/ath/ath_main.c b/roms/ipxe/src/drivers/net/ath/ath_main.c
new file mode 100644 (file)
index 0000000..85d159a
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2009 Atheros Communications Inc.
+ *
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
+ * Original from Linux kernel 3.0.1
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <ipxe/io.h>
+
+#include "ath.h"
+
+struct io_buffer *ath_rxbuf_alloc(struct ath_common *common,
+                               u32 len,
+                               u32 *iob_addr)
+{
+       struct io_buffer *iob;
+       u32 off;
+
+       /*
+        * Cache-line-align.  This is important (for the
+        * 5210 at least) as not doing so causes bogus data
+        * in rx'd frames.
+        */
+
+       /* Note: the kernel can allocate a value greater than
+        * what we ask it to give us. We really only need 4 KB as that
+        * is this hardware supports and in fact we need at least 3849
+        * as that is the MAX AMSDU size this hardware supports.
+        * Unfortunately this means we may get 8 KB here from the
+        * kernel... and that is actually what is observed on some
+        * systems :( */
+       iob = alloc_iob(len + common->cachelsz - 1);
+       if (iob != NULL) {
+               *iob_addr = virt_to_bus(iob->data);
+               off = ((unsigned long) iob->data) % common->cachelsz;
+               if (off != 0)
+               {
+                       iob_reserve(iob, common->cachelsz - off);
+                       *iob_addr += common->cachelsz - off;
+               }
+       } else {
+               DBG("ath: iobuffer alloc of size %d failed\n", len);
+               return NULL;
+       }
+
+       return iob;
+}
diff --git a/roms/ipxe/src/drivers/net/axge.c b/roms/ipxe/src/drivers/net/axge.c
deleted file mode 100644 (file)
index ab59a8b..0000000
+++ /dev/null
@@ -1,798 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <ipxe/netdevice.h>
-#include <ipxe/ethernet.h>
-#include <ipxe/if_ether.h>
-#include <ipxe/profile.h>
-#include <ipxe/usb.h>
-#include "axge.h"
-
-/** @file
- *
- * Asix 10/100/1000 USB Ethernet driver
- *
- * Large chunks of functionality are undocumented in the available
- * datasheets.  The gaps are deduced from combinations of the Linux
- * driver, the FreeBSD driver, and experimentation with the hardware.
- */
-
-/** Interrupt completion profiler */
-static struct profiler axge_intr_profiler __profiler =
-       { .name = "axge.intr" };
-
-/** Bulk IN completion profiler */
-static struct profiler axge_in_profiler __profiler =
-       { .name = "axge.in" };
-
-/** Bulk OUT profiler */
-static struct profiler axge_out_profiler __profiler =
-       { .name = "axge.out" };
-
-/** Default bulk IN configuration
- *
- * The Linux and FreeBSD drivers have set of magic constants which are
- * chosen based on both the Ethernet and USB link speeds.
- *
- * Experimentation shows that setting the "timer" value to zero seems
- * to prevent the device from ever coalescing multiple packets into a
- * single bulk IN transfer.  This allows us to get away with using a
- * 2kB receive I/O buffer and a zerocopy receive path.
- */
-static struct axge_bulk_in_control axge_bicr = {
-       .ctrl = 7,
-       .timer = cpu_to_le16 ( 0 ),
-       .size = 0,
-       .ifg = 0,
-};
-
-/******************************************************************************
- *
- * Register access
- *
- ******************************************************************************
- */
-
-/**
- * Read register
- *
- * @v asix             AXGE device
- * @v offset           Register offset
- * @v data             Data buffer
- * @v len              Length of data
- * @ret rc             Return status code
- */
-static inline int axge_read_register ( struct axge_device *axge,
-                                      unsigned int offset, void *data,
-                                      size_t len ) {
-
-       return usb_control ( axge->usb, AXGE_READ_MAC_REGISTER,
-                            offset, len, data, len );
-}
-
-/**
- * Read one-byte register
- *
- * @v asix             AXGE device
- * @v offset           Register offset
- * @v value            Value to fill in
- * @ret rc             Return status code
- */
-static inline int axge_read_byte ( struct axge_device *axge,
-                                  unsigned int offset, uint8_t *value ) {
-
-       return axge_read_register ( axge, offset, value, sizeof ( *value ) );
-}
-
-/**
- * Read two-byte register
- *
- * @v asix             AXGE device
- * @v offset           Register offset
- * @v value            Value to fill in
- * @ret rc             Return status code
- */
-static inline int axge_read_word ( struct axge_device *axge,
-                                  unsigned int offset, uint16_t *value ) {
-
-       return axge_read_register ( axge, offset, value, sizeof ( *value ) );
-}
-
-/**
- * Read four-byte register
- *
- * @v asix             AXGE device
- * @v offset           Register offset
- * @v value            Value to fill in
- * @ret rc             Return status code
- */
-static inline int axge_read_dword ( struct axge_device *axge,
-                                   unsigned int offset, uint32_t *value ) {
-
-       return axge_read_register ( axge, offset, value, sizeof ( *value ) );
-}
-
-/**
- * Write register
- *
- * @v asix             AXGE device
- * @v offset           Register offset
- * @v data             Data buffer
- * @v len              Length of data
- * @ret rc             Return status code
- */
-static inline int axge_write_register ( struct axge_device *axge,
-                                       unsigned int offset, void *data,
-                                       size_t len ) {
-
-       return usb_control ( axge->usb, AXGE_WRITE_MAC_REGISTER,
-                            offset, len, data, len );
-}
-
-/**
- * Write one-byte register
- *
- * @v asix             AXGE device
- * @v offset           Register offset
- * @v value            Value
- * @ret rc             Return status code
- */
-static inline int axge_write_byte ( struct axge_device *axge,
-                                   unsigned int offset, uint8_t value ) {
-
-       return axge_write_register ( axge, offset, &value, sizeof ( value ));
-}
-
-/**
- * Write two-byte register
- *
- * @v asix             AXGE device
- * @v offset           Register offset
- * @v value            Value
- * @ret rc             Return status code
- */
-static inline int axge_write_word ( struct axge_device *axge,
-                                   unsigned int offset, uint16_t value ) {
-
-       return axge_write_register ( axge, offset, &value, sizeof ( value ));
-}
-
-/**
- * Write one-byte register
- *
- * @v asix             AXGE device
- * @v offset           Register offset
- * @v value            Value
- * @ret rc             Return status code
- */
-static inline int axge_write_dword ( struct axge_device *axge,
-                                    unsigned int offset, uint32_t value ) {
-
-       return axge_write_register ( axge, offset, &value, sizeof ( value ));
-}
-
-/******************************************************************************
- *
- * Link status
- *
- ******************************************************************************
- */
-
-/**
- * Get link status
- *
- * @v asix             AXGE device
- * @ret rc             Return status code
- */
-static int axge_check_link ( struct axge_device *axge ) {
-       struct net_device *netdev = axge->netdev;
-       uint8_t plsr;
-       int rc;
-
-       /* Read physical link status register */
-       if ( ( rc = axge_read_byte ( axge, AXGE_PLSR, &plsr ) ) != 0 ) {
-               DBGC ( axge, "AXGE %p could not read PLSR: %s\n",
-                      axge, strerror ( rc ) );
-               return rc;
-       }
-
-       /* Update link status */
-       if ( plsr & AXGE_PLSR_EPHY_ANY ) {
-               DBGC ( axge, "AXGE %p link up (PLSR %02x)\n", axge, plsr );
-               netdev_link_up ( netdev );
-       } else {
-               DBGC ( axge, "AXGE %p link down (PLSR %02x)\n", axge, plsr );
-               netdev_link_down ( netdev );
-       }
-
-       return 0;
-}
-
-/******************************************************************************
- *
- * AXGE communications interface
- *
- ******************************************************************************
- */
-
-/**
- * Complete interrupt transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void axge_intr_complete ( struct usb_endpoint *ep,
-                                struct io_buffer *iobuf, int rc ) {
-       struct axge_device *axge = container_of ( ep, struct axge_device,
-                                                 usbnet.intr );
-       struct net_device *netdev = axge->netdev;
-       struct axge_interrupt *intr;
-       size_t len = iob_len ( iobuf );
-       unsigned int link_ok;
-
-       /* Profile completions */
-       profile_start ( &axge_intr_profiler );
-
-       /* Ignore packets cancelled when the endpoint closes */
-       if ( ! ep->open )
-               goto ignore;
-
-       /* Drop packets with errors */
-       if ( rc != 0 ) {
-               DBGC ( axge, "AXGE %p interrupt failed: %s\n",
-                      axge, strerror ( rc ) );
-               DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
-               goto error;
-       }
-
-       /* Extract message header */
-       if ( len < sizeof ( *intr ) ) {
-               DBGC ( axge, "AXGE %p underlength interrupt:\n", axge );
-               DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
-               rc = -EINVAL;
-               goto error;
-       }
-       intr = iobuf->data;
-
-       /* Check magic signature */
-       if ( intr->magic != cpu_to_le16 ( AXGE_INTR_MAGIC ) ) {
-               DBGC ( axge, "AXGE %p malformed interrupt:\n", axge );
-               DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
-               rc = -EINVAL;
-               goto error;
-       }
-
-       /* Extract link status */
-       link_ok = ( intr->link & cpu_to_le16 ( AXGE_INTR_LINK_PPLS ) );
-       if ( link_ok && ! netdev_link_ok ( netdev ) ) {
-               DBGC ( axge, "AXGE %p link up\n", axge );
-               netdev_link_up ( netdev );
-       } else if ( netdev_link_ok ( netdev ) && ! link_ok ) {
-               DBGC ( axge, "AXGE %p link down\n", axge );
-               netdev_link_down ( netdev );
-       }
-
-       /* Free I/O buffer */
-       free_iob ( iobuf );
-       profile_stop ( &axge_intr_profiler );
-
-       return;
-
- error:
-       netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
- ignore:
-       free_iob ( iobuf );
-       return;
-}
-
-/** Interrupt endpoint operations */
-static struct usb_endpoint_driver_operations axge_intr_operations = {
-       .complete = axge_intr_complete,
-};
-
-/******************************************************************************
- *
- * AXGE data interface
- *
- ******************************************************************************
- */
-
-/**
- * Complete bulk IN transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void axge_in_complete ( struct usb_endpoint *ep,
-                              struct io_buffer *iobuf, int rc ) {
-       struct axge_device *axge = container_of ( ep, struct axge_device,
-                                                 usbnet.in );
-       struct net_device *netdev = axge->netdev;
-       struct axge_rx_footer *ftr;
-       struct axge_rx_descriptor *desc;
-       struct io_buffer *pkt;
-       unsigned int count;
-       unsigned int offset;
-       size_t len;
-       size_t padded_len;
-
-       /* Profile receive completions */
-       profile_start ( &axge_in_profiler );
-
-       /* Ignore packets cancelled when the endpoint closes */
-       if ( ! ep->open )
-               goto ignore;
-
-       /* Record USB errors against the network device */
-       if ( rc != 0 ) {
-               DBGC ( axge, "AXGE %p bulk IN failed: %s\n",
-                      axge, strerror ( rc ) );
-               goto error;
-       }
-
-       /* Sanity check */
-       if ( iob_len ( iobuf ) < sizeof ( *ftr ) ) {
-               DBGC ( axge, "AXGE %p underlength bulk IN:\n", axge );
-               DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
-               rc = -EINVAL;
-               goto error;
-       }
-
-       /* Parse ftr, strip ftr and descriptors */
-       iob_unput ( iobuf, sizeof ( *ftr ) );
-       ftr = ( iobuf->data + iob_len ( iobuf ) );
-       count = le16_to_cpu ( ftr->count );
-       if ( count == 0 ) {
-               DBGC ( axge, "AXGE %p zero-packet bulk IN:\n", axge );
-               DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
-               goto ignore;
-       }
-       offset = le16_to_cpu ( ftr->offset );
-       if ( ( iob_len ( iobuf ) < offset ) ||
-            ( ( iob_len ( iobuf ) - offset ) < ( count * sizeof ( *desc ) ) )){
-               DBGC ( axge, "AXGE %p malformed bulk IN footer:\n", axge );
-               DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
-               rc = -EINVAL;
-               goto error;
-       }
-       desc = ( iobuf->data + offset );
-       iob_unput ( iobuf, ( iob_len ( iobuf ) - offset ) );
-
-       /* Process packets */
-       for ( ; count-- ; desc++ ) {
-
-               /* Parse descriptor */
-               len = ( le16_to_cpu ( desc->len_flags ) & AXGE_RX_LEN_MASK );
-               padded_len = ( ( len + AXGE_RX_LEN_PAD_ALIGN - 1 ) &
-                              ~( AXGE_RX_LEN_PAD_ALIGN - 1 ) );
-               if ( iob_len ( iobuf ) < padded_len ) {
-                       DBGC ( axge, "AXGE %p malformed bulk IN descriptor:\n",
-                              axge );
-                       DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
-                       rc = -EINVAL;
-                       goto error;
-               }
-
-               /* Check for previous dropped packets */
-               if ( desc->len_flags & cpu_to_le16 ( AXGE_RX_CRC_ERROR ) )
-                       netdev_rx_err ( netdev, NULL, -EIO );
-               if ( desc->len_flags & cpu_to_le16 ( AXGE_RX_DROP_ERROR ) )
-                       netdev_rx_err ( netdev, NULL, -ENOBUFS );
-
-               /* Allocate new I/O buffer, if applicable */
-               if ( count ) {
-
-                       /* More packets remain: allocate a new buffer */
-                       pkt = alloc_iob ( AXGE_IN_RESERVE + len );
-                       if ( ! pkt ) {
-                               /* Record error and continue */
-                               netdev_rx_err ( netdev, NULL, -ENOMEM );
-                               iob_pull ( iobuf, padded_len );
-                               continue;
-                       }
-                       iob_reserve ( pkt, AXGE_IN_RESERVE );
-                       memcpy ( iob_put ( pkt, len ), iobuf->data, len );
-                       iob_pull ( iobuf, padded_len );
-
-               } else {
-
-                       /* This is the last (or only) packet: use this buffer */
-                       iob_unput ( iobuf, ( padded_len - len ) );
-                       pkt = iob_disown ( iobuf );
-               }
-
-               /* Hand off to network stack */
-               netdev_rx ( netdev, iob_disown ( pkt ) );
-       }
-
-       assert ( iobuf == NULL );
-       profile_stop ( &axge_in_profiler );
-       return;
-
- error:
-       netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
- ignore:
-       free_iob ( iobuf );
-}
-
-/** Bulk IN endpoint operations */
-static struct usb_endpoint_driver_operations axge_in_operations = {
-       .complete = axge_in_complete,
-};
-
-/**
- * Transmit packet
- *
- * @v asix             AXGE device
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int axge_out_transmit ( struct axge_device *axge,
-                              struct io_buffer *iobuf ) {
-       struct axge_tx_header *hdr;
-       size_t len = iob_len ( iobuf );
-       int rc;
-
-       /* Profile transmissions */
-       profile_start ( &axge_out_profiler );
-
-       /* Prepend header */
-       if ( ( rc = iob_ensure_headroom ( iobuf, sizeof ( *hdr ) ) ) != 0 )
-               return rc;
-       hdr = iob_push ( iobuf, sizeof ( *hdr ) );
-       hdr->len = cpu_to_le32 ( len );
-       hdr->wtf = 0;
-
-       /* Enqueue I/O buffer */
-       if ( ( rc = usb_stream ( &axge->usbnet.out, iobuf, 0 ) ) != 0 )
-               return rc;
-
-       profile_stop ( &axge_out_profiler );
-       return 0;
-}
-
-/**
- * Complete bulk OUT transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void axge_out_complete ( struct usb_endpoint *ep,
-                               struct io_buffer *iobuf, int rc ) {
-       struct axge_device *axge = container_of ( ep, struct axge_device,
-                                                 usbnet.out );
-       struct net_device *netdev = axge->netdev;
-
-       /* Report TX completion */
-       netdev_tx_complete_err ( netdev, iobuf, rc );
-}
-
-/** Bulk OUT endpoint operations */
-static struct usb_endpoint_driver_operations axge_out_operations = {
-       .complete = axge_out_complete,
-};
-
-/******************************************************************************
- *
- * Network device interface
- *
- ******************************************************************************
- */
-
-/**
- * Open network device
- *
- * @v netdev           Network device
- * @ret rc             Return status code
- */
-static int axge_open ( struct net_device *netdev ) {
-       struct axge_device *axge = netdev->priv;
-       uint16_t rcr;
-       int rc;
-
-       /* Open USB network device */
-       if ( ( rc = usbnet_open ( &axge->usbnet ) ) != 0 ) {
-               DBGC ( axge, "AXGE %p could not open: %s\n",
-                      axge, strerror ( rc ) );
-               goto err_open;
-       }
-
-       /* Set MAC address */
-       if ( ( rc = axge_write_register ( axge, AXGE_NIDR,
-                                         netdev->ll_addr, ETH_ALEN ) ) !=0){
-               DBGC ( axge, "AXGE %p could not set MAC address: %s\n",
-                      axge, strerror ( rc ) );
-               goto err_write_mac;
-       }
-
-       /* Enable receiver */
-       rcr = cpu_to_le16 ( AXGE_RCR_PRO | AXGE_RCR_AMALL |
-                           AXGE_RCR_AB | AXGE_RCR_SO );
-       if ( ( rc = axge_write_word ( axge, AXGE_RCR, rcr ) ) != 0 ) {
-               DBGC ( axge, "AXGE %p could not write RCR: %s\n",
-                      axge, strerror ( rc ) );
-               goto err_write_rcr;
-       }
-
-       /* Update link status */
-       axge_check_link ( axge );
-
-       return 0;
-
-       axge_write_word ( axge, AXGE_RCR, 0 );
- err_write_rcr:
- err_write_mac:
-       usbnet_close ( &axge->usbnet );
- err_open:
-       return rc;
-}
-
-/**
- * Close network device
- *
- * @v netdev           Network device
- */
-static void axge_close ( struct net_device *netdev ) {
-       struct axge_device *axge = netdev->priv;
-
-       /* Disable receiver */
-       axge_write_word ( axge, AXGE_RCR, 0 );
-
-       /* Close USB network device */
-       usbnet_close ( &axge->usbnet );
-}
-
-/**
- * Transmit packet
- *
- * @v netdev           Network device
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int axge_transmit ( struct net_device *netdev,
-                          struct io_buffer *iobuf ) {
-       struct axge_device *axge = netdev->priv;
-       int rc;
-
-       /* Transmit packet */
-       if ( ( rc = axge_out_transmit ( axge, iobuf ) ) != 0 )
-               return rc;
-
-       return 0;
-}
-
-/**
- * Poll for completed and received packets
- *
- * @v netdev           Network device
- */
-static void axge_poll ( struct net_device *netdev ) {
-       struct axge_device *axge = netdev->priv;
-       int rc;
-
-       /* Poll USB bus */
-       usb_poll ( axge->bus );
-
-       /* Refill endpoints */
-       if ( ( rc = usbnet_refill ( &axge->usbnet ) ) != 0 )
-               netdev_rx_err ( netdev, NULL, rc );
-}
-
-/** AXGE network device operations */
-static struct net_device_operations axge_operations = {
-       .open           = axge_open,
-       .close          = axge_close,
-       .transmit       = axge_transmit,
-       .poll           = axge_poll,
-};
-
-/******************************************************************************
- *
- * USB interface
- *
- ******************************************************************************
- */
-
-/**
- * Probe device
- *
- * @v func             USB function
- * @v config           Configuration descriptor
- * @ret rc             Return status code
- */
-static int axge_probe ( struct usb_function *func,
-                       struct usb_configuration_descriptor *config ) {
-       struct usb_device *usb = func->usb;
-       struct net_device *netdev;
-       struct axge_device *axge;
-       uint16_t epprcr;
-       uint16_t msr;
-       uint8_t csr;
-       int rc;
-
-       /* Allocate and initialise structure */
-       netdev = alloc_etherdev ( sizeof ( *axge ) );
-       if ( ! netdev ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       netdev_init ( netdev, &axge_operations );
-       netdev->dev = &func->dev;
-       axge = netdev->priv;
-       memset ( axge, 0, sizeof ( *axge ) );
-       axge->usb = usb;
-       axge->bus = usb->port->hub->bus;
-       axge->netdev = netdev;
-       usbnet_init ( &axge->usbnet, func, &axge_intr_operations,
-                     &axge_in_operations, &axge_out_operations );
-       usb_refill_init ( &axge->usbnet.intr, 0, 0, AXGE_INTR_MAX_FILL );
-       usb_refill_init ( &axge->usbnet.in, AXGE_IN_RESERVE,
-                         AXGE_IN_MTU, AXGE_IN_MAX_FILL );
-       DBGC ( axge, "AXGE %p on %s\n", axge, func->name );
-
-       /* Describe USB network device */
-       if ( ( rc = usbnet_describe ( &axge->usbnet, config ) ) != 0 ) {
-               DBGC ( axge, "AXGE %p could not describe: %s\n",
-                      axge, strerror ( rc ) );
-               goto err_describe;
-       }
-
-       /* Fetch MAC address */
-       if ( ( rc = axge_read_register ( axge, AXGE_NIDR, netdev->hw_addr,
-                                        ETH_ALEN ) ) != 0 ) {
-               DBGC ( axge, "AXGE %p could not fetch MAC address: %s\n",
-                      axge, strerror ( rc ) );
-               goto err_read_mac;
-       }
-
-       /* Power up PHY */
-       if ( ( rc = axge_write_word ( axge, AXGE_EPPRCR, 0 ) ) != 0 ) {
-               DBGC ( axge, "AXGE %p could not write EPPRCR: %s\n",
-                      axge, strerror ( rc ) );
-               goto err_write_epprcr_off;
-       }
-       epprcr = cpu_to_le16 ( AXGE_EPPRCR_IPRL );
-       if ( ( rc = axge_write_word ( axge, AXGE_EPPRCR, epprcr ) ) != 0){
-               DBGC ( axge, "AXGE %p could not write EPPRCR: %s\n",
-                      axge, strerror ( rc ) );
-               goto err_write_epprcr_on;
-       }
-       mdelay ( AXGE_EPPRCR_DELAY_MS );
-
-       /* Select clocks */
-       csr = ( AXGE_CSR_BCS | AXGE_CSR_ACS );
-       if ( ( rc = axge_write_byte ( axge, AXGE_CSR, csr ) ) != 0){
-               DBGC ( axge, "AXGE %p could not write CSR: %s\n",
-                      axge, strerror ( rc ) );
-               goto err_write_csr;
-       }
-       mdelay ( AXGE_CSR_DELAY_MS );
-
-       /* Configure bulk IN pipeline */
-       if ( ( rc = axge_write_register ( axge, AXGE_BICR, &axge_bicr,
-                                         sizeof ( axge_bicr ) ) ) != 0 ){
-               DBGC ( axge, "AXGE %p could not write BICR: %s\n",
-                      axge, strerror ( rc ) );
-               goto err_write_bicr;
-       }
-
-       /* Set medium status */
-       msr = cpu_to_le16 ( AXGE_MSR_GM | AXGE_MSR_FD | AXGE_MSR_RFC |
-                           AXGE_MSR_TFC | AXGE_MSR_RE );
-       if ( ( rc = axge_write_word ( axge, AXGE_MSR, msr ) ) != 0 ) {
-               DBGC ( axge, "AXGE %p could not write MSR: %s\n",
-                      axge, strerror ( rc ) );
-               goto err_write_msr;
-       }
-
-       /* Register network device */
-       if ( ( rc = register_netdev ( netdev ) ) != 0 )
-               goto err_register;
-
-       /* Update link status */
-       axge_check_link ( axge );
-
-       usb_func_set_drvdata ( func, axge );
-       return 0;
-
-       unregister_netdev ( netdev );
- err_register:
- err_write_msr:
- err_write_bicr:
- err_write_csr:
- err_write_epprcr_on:
- err_write_epprcr_off:
- err_read_mac:
- err_describe:
-       netdev_nullify ( netdev );
-       netdev_put ( netdev );
- err_alloc:
-       return rc;
-}
-
-/**
- * Remove device
- *
- * @v func             USB function
- */
-static void axge_remove ( struct usb_function *func ) {
-       struct axge_device *axge = usb_func_get_drvdata ( func );
-       struct net_device *netdev = axge->netdev;
-
-       unregister_netdev ( netdev );
-       netdev_nullify ( netdev );
-       netdev_put ( netdev );
-}
-
-/** AXGE device IDs */
-static struct usb_device_id axge_ids[] = {
-       {
-               .name = "ax88179",
-               .vendor = 0x0b95,
-               .product = 0x1790,
-       },
-       {
-               .name = "ax88178a",
-               .vendor = 0x0b95,
-               .product = 0x178a,
-       },
-       {
-               .name = "dub1312",
-               .vendor = 0x2001,
-               .product = 0x4a00,
-       },
-       {
-               .name = "axge-sitecom",
-               .vendor = 0x0df6,
-               .product = 0x0072,
-       },
-       {
-               .name = "axge-samsung",
-               .vendor = 0x04e8,
-               .product = 0xa100,
-       },
-       {
-               .name = "onelinkdock",
-               .vendor = 0x17ef,
-               .product = 0x304b,
-       },
-};
-
-/** AXGE driver */
-struct usb_driver axge_driver __usb_driver = {
-       .ids = axge_ids,
-       .id_count = ( sizeof ( axge_ids ) / sizeof ( axge_ids[0] ) ),
-       .class = USB_CLASS_ID ( USB_ANY_ID, USB_ANY_ID, USB_ANY_ID ),
-       .score = USB_SCORE_NORMAL,
-       .probe = axge_probe,
-       .remove = axge_remove,
-};
diff --git a/roms/ipxe/src/drivers/net/axge.h b/roms/ipxe/src/drivers/net/axge.h
deleted file mode 100644 (file)
index 65bf911..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-#ifndef _AXGE_H
-#define _AXGE_H
-
-/** @file
- *
- * Asix 10/100/1000 USB Ethernet driver
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/usb.h>
-#include <ipxe/usbnet.h>
-
-/** Read MAC register */
-#define AXGE_READ_MAC_REGISTER                                         \
-       ( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE |             \
-         USB_REQUEST_TYPE ( 0x01 ) )
-
-/** Write MAC register */
-#define AXGE_WRITE_MAC_REGISTER                                                \
-       ( USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE |            \
-         USB_REQUEST_TYPE ( 0x01 ) )
-
-/** Physical Link Status Register */
-#define AXGE_PLSR 0x02
-#define AXGE_PLSR_EPHY_10              0x10    /**< Ethernet at 10Mbps */
-#define AXGE_PLSR_EPHY_100             0x20    /**< Ethernet at 100Mbps */
-#define AXGE_PLSR_EPHY_1000            0x40    /**< Ethernet at 1000Mbps */
-#define AXGE_PLSR_EPHY_ANY                                             \
-       ( AXGE_PLSR_EPHY_10 |                                           \
-         AXGE_PLSR_EPHY_100 |                                          \
-         AXGE_PLSR_EPHY_1000 )
-
-/** RX Control Register */
-#define AXGE_RCR 0x0b
-#define AXGE_RCR_PRO                   0x0001  /**< Promiscuous mode */
-#define AXGE_RCR_AMALL                 0x0002  /**< Accept all multicasts */
-#define AXGE_RCR_AB                    0x0008  /**< Accept broadcasts */
-#define AXGE_RCR_SO                    0x0080  /**< Start operation */
-
-/** Node ID Register */
-#define AXGE_NIDR 0x10
-
-/** Medium Status Register */
-#define AXGE_MSR 0x22
-#define AXGE_MSR_GM                    0x0001  /**< Gigabit mode */
-#define AXGE_MSR_FD                    0x0002  /**< Full duplex */
-#define AXGE_MSR_RFC                   0x0010  /**< RX flow control enable */
-#define AXGE_MSR_TFC                   0x0020  /**< TX flow control enable */
-#define AXGE_MSR_RE                    0x0100  /**< Receive enable */
-
-/** Ethernet PHY Power and Reset Control Register */
-#define AXGE_EPPRCR 0x26
-#define AXGE_EPPRCR_IPRL               0x0020  /**< Undocumented */
-
-/** Delay after initialising EPPRCR */
-#define AXGE_EPPRCR_DELAY_MS 200
-
-/** Bulk IN Control Register (undocumented) */
-#define AXGE_BICR 0x2e
-
-/** Bulk IN Control (undocumented) */
-struct axge_bulk_in_control {
-       /** Control */
-       uint8_t ctrl;
-       /** Timer */
-       uint16_t timer;
-       /** Size */
-       uint8_t size;
-       /** Inter-frame gap */
-       uint8_t ifg;
-} __attribute__ (( packed ));
-
-/** Clock Select Register (undocumented) */
-#define AXGE_CSR 0x33
-#define AXGE_CSR_BCS                   0x01    /**< Undocumented */
-#define AXGE_CSR_ACS                   0x02    /**< Undocumented */
-
-/** Delay after initialising CSR */
-#define AXGE_CSR_DELAY_MS 100
-
-/** Transmit packet header */
-struct axge_tx_header {
-       /** Packet length */
-       uint32_t len;
-       /** Answers on a postcard, please */
-       uint32_t wtf;
-} __attribute__ (( packed ));
-
-/** Receive packet footer */
-struct axge_rx_footer {
-       /** Packet count */
-       uint16_t count;
-       /** Header offset */
-       uint16_t offset;
-} __attribute__ (( packed ));
-
-/** Receive packet descriptor */
-struct axge_rx_descriptor {
-       /** Checksum information */
-       uint16_t check;
-       /** Length and error flags */
-       uint16_t len_flags;
-} __attribute__ (( packed ));
-
-/** Receive packet length mask */
-#define AXGE_RX_LEN_MASK 0x1fff
-
-/** Receive packet length alignment */
-#define AXGE_RX_LEN_PAD_ALIGN 8
-
-/** Receive packet CRC error */
-#define AXGE_RX_CRC_ERROR 0x2000
-
-/** Receive packet dropped error */
-#define AXGE_RX_DROP_ERROR 0x8000
-
-/** Interrupt data */
-struct axge_interrupt {
-       /** Magic signature */
-       uint16_t magic;
-       /** Link state */
-       uint16_t link;
-       /** PHY register MR01 */
-       uint16_t mr01;
-       /** PHY register MR05 */
-       uint16_t mr05;
-} __attribute__ (( packed ));
-
-/** Interrupt magic signature */
-#define AXGE_INTR_MAGIC 0x00a1
-
-/** Link is up */
-#define AXGE_INTR_LINK_PPLS 0x0001
-
-/** An AXGE network device */
-struct axge_device {
-       /** USB device */
-       struct usb_device *usb;
-       /** USB bus */
-       struct usb_bus *bus;
-       /** Network device */
-       struct net_device *netdev;
-       /** USB network device */
-       struct usbnet_device usbnet;
-};
-
-/** Interrupt maximum fill level
- *
- * This is a policy decision.
- */
-#define AXGE_INTR_MAX_FILL 2
-
-/** Bulk IN maximum fill level
- *
- * This is a policy decision.
- */
-#define AXGE_IN_MAX_FILL 8
-
-/** Bulk IN buffer size
- *
- * This is a policy decision.
- */
-#define AXGE_IN_MTU 2048
-
-/** Amount of space to reserve at start of bulk IN buffers
- *
- * This is required to allow for protocols such as ARP which may reuse
- * a received I/O buffer for transmission.
- */
-#define AXGE_IN_RESERVE sizeof ( struct axge_tx_header )
-
-#endif /* _AXGE_H */
index 61b957b..58d8dd9 100644 (file)
@@ -532,8 +532,8 @@ static int dm96xx_probe ( struct usb_function *func,
        dm96xx->netdev = netdev;
        usbnet_init ( &dm96xx->usbnet, func, &dm96xx_intr_operations,
                      &dm96xx_in_operations, &dm96xx_out_operations );
-       usb_refill_init ( &dm96xx->usbnet.intr, 0, 0, DM96XX_INTR_MAX_FILL );
-       usb_refill_init ( &dm96xx->usbnet.in, 0, DM96XX_IN_MTU,
+       usb_refill_init ( &dm96xx->usbnet.intr, 0, DM96XX_INTR_MAX_FILL );
+       usb_refill_init ( &dm96xx->usbnet.in, DM96XX_IN_MTU,
                          DM96XX_IN_MAX_FILL );
        DBGC ( dm96xx, "DM96XX %p on %s\n", dm96xx, func->name );
 
@@ -666,8 +666,6 @@ static struct usb_device_id dm96xx_ids[] = {
 struct usb_driver dm96xx_driver __usb_driver = {
        .ids = dm96xx_ids,
        .id_count = ( sizeof ( dm96xx_ids ) / sizeof ( dm96xx_ids[0] ) ),
-       .class = USB_CLASS_ID ( USB_ANY_ID, USB_ANY_ID, USB_ANY_ID ),
-       .score = USB_SCORE_NORMAL,
        .probe = dm96xx_probe,
        .remove = dm96xx_remove,
 };
index f2d9161..8c84ea9 100644 (file)
@@ -437,8 +437,8 @@ static int ecm_probe ( struct usb_function *func,
        ecm->netdev = netdev;
        usbnet_init ( &ecm->usbnet, func, &ecm_intr_operations,
                      &ecm_in_operations, &ecm_out_operations );
-       usb_refill_init ( &ecm->usbnet.intr, 0, 0, ECM_INTR_MAX_FILL );
-       usb_refill_init ( &ecm->usbnet.in, 0, ECM_IN_MTU, ECM_IN_MAX_FILL );
+       usb_refill_init ( &ecm->usbnet.intr, 0, ECM_INTR_MAX_FILL );
+       usb_refill_init ( &ecm->usbnet.in, ECM_IN_MTU, ECM_IN_MAX_FILL );
        DBGC ( ecm, "ECM %p on %s\n", ecm, func->name );
 
        /* Describe USB network device */
@@ -503,6 +503,11 @@ static struct usb_device_id ecm_ids[] = {
                .name = "cdc-ecm",
                .vendor = USB_ANY_ID,
                .product = USB_ANY_ID,
+               .class = {
+                       .class = USB_CLASS_CDC,
+                       .subclass = USB_SUBCLASS_CDC_ECM,
+                       .protocol = 0,
+               },
        },
 };
 
@@ -510,8 +515,6 @@ static struct usb_device_id ecm_ids[] = {
 struct usb_driver ecm_driver __usb_driver = {
        .ids = ecm_ids,
        .id_count = ( sizeof ( ecm_ids ) / sizeof ( ecm_ids[0] ) ),
-       .class = USB_CLASS_ID ( USB_CLASS_CDC, USB_SUBCLASS_CDC_ECM, 0 ),
-       .score = USB_SCORE_NORMAL,
        .probe = ecm_probe,
        .remove = ecm_remove,
 };
index d68b36c..b91848f 100644 (file)
@@ -1125,8 +1125,8 @@ int nii_start ( struct efi_device *efidev ) {
        /* Register network device */
        if ( ( rc = register_netdev ( netdev ) ) != 0 )
                goto err_register_netdev;
-       DBGC ( nii, "NII %s registered as %s for %s\n", nii->dev.name,
-              netdev->name, efi_handle_name ( device ) );
+       DBGC ( nii, "NII %s registered as %s for %p %s\n", nii->dev.name,
+              netdev->name, device, efi_handle_name ( device ) );
 
        /* Set initial link state (if media detection is not supported) */
        if ( ! nii->media )
index fbd6069..acfcfba 100644 (file)
@@ -48,8 +48,8 @@ static int snp_supported ( EFI_HANDLE device ) {
 
        /* Check that this is not a device we are providing ourselves */
        if ( find_snpdev ( device ) != NULL ) {
-               DBGCP ( device, "SNP %s is provided by this binary\n",
-                       efi_handle_name ( device ) );
+               DBGCP ( device, "SNP %p %s is provided by this binary\n",
+                       device, efi_handle_name ( device ) );
                return -ENOTTY;
        }
 
@@ -58,12 +58,12 @@ static int snp_supported ( EFI_HANDLE device ) {
                                          &efi_simple_network_protocol_guid,
                                          NULL, efi_image_handle, device,
                                          EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
-               DBGCP ( device, "SNP %s is not an SNP device\n",
-                       efi_handle_name ( device ) );
+               DBGCP ( device, "SNP %p %s is not an SNP device\n",
+                       device, efi_handle_name ( device ) );
                return -EEFI ( efirc );
        }
-       DBGC ( device, "SNP %s is an SNP device\n",
-              efi_handle_name ( device ) );
+       DBGC ( device, "SNP %p %s is an SNP device\n",
+              device, efi_handle_name ( device ) );
 
        return 0;
 }
@@ -80,8 +80,8 @@ static int nii_supported ( EFI_HANDLE device ) {
 
        /* Check that this is not a device we are providing ourselves */
        if ( find_snpdev ( device ) != NULL ) {
-               DBGCP ( device, "NII %s is provided by this binary\n",
-                       efi_handle_name ( device ) );
+               DBGCP ( device, "NII %p %s is provided by this binary\n",
+                       device, efi_handle_name ( device ) );
                return -ENOTTY;
        }
 
@@ -90,12 +90,12 @@ static int nii_supported ( EFI_HANDLE device ) {
                                          &efi_nii31_protocol_guid,
                                          NULL, efi_image_handle, device,
                                          EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
-               DBGCP ( device, "NII %s is not an NII device\n",
-                       efi_handle_name ( device ) );
+               DBGCP ( device, "NII %p %s is not an NII device\n",
+                       device, efi_handle_name ( device ) );
                return -EEFI ( efirc );
        }
-       DBGC ( device, "NII %s is an NII device\n",
-              efi_handle_name ( device ) );
+       DBGC ( device, "NII %p %s is an NII device\n",
+              device, efi_handle_name ( device ) );
 
        return 0;
 }
index 88474b0..96642c4 100644 (file)
@@ -191,7 +191,6 @@ static void snpnet_poll_tx ( struct net_device *netdev ) {
        int rc;
 
        /* Get status */
-       txbuf = NULL;
        if ( ( efirc = snp->snp->GetStatus ( snp->snp, &irq, &txbuf ) ) != 0 ) {
                rc = -EEFI ( efirc );
                DBGC ( snp, "SNP %s could not get status: %s\n",
@@ -432,8 +431,8 @@ int snpnet_start ( struct efi_device *efidev ) {
                                          ( EFI_OPEN_PROTOCOL_BY_DRIVER |
                                            EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
                rc = -EEFI ( efirc );
-               DBGC ( device, "SNP %s cannot open SNP protocol: %s\n",
-                      efi_handle_name ( device ), strerror ( rc ) );
+               DBGC ( device, "SNP %p %s cannot open SNP protocol: %s\n",
+                      device, efi_handle_name ( device ), strerror ( rc ) );
                DBGC_EFI_OPENERS ( device, device,
                                   &efi_simple_network_protocol_guid );
                goto err_open_protocol;
@@ -464,30 +463,32 @@ int snpnet_start ( struct efi_device *efidev ) {
        if ( ( mode->State == EfiSimpleNetworkStopped ) &&
             ( ( efirc = snp->snp->Start ( snp->snp ) ) != 0 ) ) {
                rc = -EEFI ( efirc );
-               DBGC ( device, "SNP %s could not start: %s\n",
+               DBGC ( device, "SNP %p %s could not start: %s\n", device,
                       efi_handle_name ( device ), strerror ( rc ) );
                goto err_start;
        }
        if ( ( mode->State == EfiSimpleNetworkInitialized ) &&
             ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) ) {
                rc = -EEFI ( efirc );
-               DBGC ( device, "SNP %s could not shut down: %s\n",
+               DBGC ( device, "SNP %p %s could not shut down: %s\n", device,
                       efi_handle_name ( device ), strerror ( rc ) );
                goto err_shutdown;
        }
 
        /* Populate network device parameters */
        if ( mode->HwAddressSize != netdev->ll_protocol->hw_addr_len ) {
-               DBGC ( device, "SNP %s has invalid hardware address length "
-                      "%d\n", efi_handle_name ( device ), mode->HwAddressSize);
+               DBGC ( device, "SNP %p %s has invalid hardware address "
+                      "length %d\n", device, efi_handle_name ( device ),
+                      mode->HwAddressSize );
                rc = -ENOTSUP;
                goto err_hw_addr_len;
        }
        memcpy ( netdev->hw_addr, &mode->PermanentAddress,
                 netdev->ll_protocol->hw_addr_len );
        if ( mode->HwAddressSize != netdev->ll_protocol->ll_addr_len ) {
-               DBGC ( device, "SNP %s has invalid link-layer address length "
-                      "%d\n", efi_handle_name ( device ), mode->HwAddressSize);
+               DBGC ( device, "SNP %p %s has invalid link-layer address "
+                      "length %d\n", device, efi_handle_name ( device ),
+                      mode->HwAddressSize );
                rc = -ENOTSUP;
                goto err_ll_addr_len;
        }
@@ -499,8 +500,8 @@ int snpnet_start ( struct efi_device *efidev ) {
        /* Register network device */
        if ( ( rc = register_netdev ( netdev ) ) != 0 )
                goto err_register_netdev;
-       DBGC ( device, "SNP %s registered as %s\n",
-              efi_handle_name ( device ), netdev->name );
+       DBGC ( device, "SNP %p %s registered as %s\n",
+              device, efi_handle_name ( device ), netdev->name );
 
        /* Set initial link state */
        if ( snp->snp->Mode->MediaPresentSupported ) {
@@ -546,7 +547,7 @@ void snpnet_stop ( struct efi_device *efidev ) {
        /* Stop SNP protocol */
        if ( ( efirc = snp->snp->Stop ( snp->snp ) ) != 0 ) {
                rc = -EEFI ( efirc );
-               DBGC ( device, "SNP %s could not stop: %s\n",
+               DBGC ( device, "SNP %p %s could not stop: %s\n", device,
                       efi_handle_name ( device ), strerror ( rc ) );
                /* Nothing we can do about this */
        }
index cb7ea1b..73abfdb 100644 (file)
@@ -81,14 +81,14 @@ static int chained_locate ( struct chained_protocol *chained ) {
        /* Locate handle supporting this protocol */
        if ( ( rc = efi_locate_device ( device, chained->protocol,
                                        &parent ) ) != 0 ) {
-               DBGC ( device, "CHAINED %s does not support %s: %s\n",
-                      efi_handle_name ( device ),
+               DBGC ( device, "CHAINED %p %s does not support %s: %s\n",
+                      device, efi_handle_name ( device ),
                       efi_guid_ntoa ( chained->protocol ), strerror ( rc ) );
                goto err_locate_device;
        }
-       DBGC ( device, "CHAINED %s found %s on ", efi_handle_name ( device ),
-              efi_guid_ntoa ( chained->protocol ) );
-       DBGC ( device, "%s\n", efi_handle_name ( parent ) );
+       DBGC ( device, "CHAINED %p %s found %s on ", device,
+              efi_handle_name ( device ), efi_guid_ntoa ( chained->protocol ));
+       DBGC ( device, "%p %s\n", parent, efi_handle_name ( parent ) );
 
        /* Get protocol instance */
        if ( ( efirc = bs->OpenProtocol ( parent, chained->protocol,
@@ -96,11 +96,11 @@ static int chained_locate ( struct chained_protocol *chained ) {
                                          device,
                                          EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
                rc = -EEFI ( efirc );
-               DBGC ( device, "CHAINED %s could not open %s on ",
-                      efi_handle_name ( device ),
+               DBGC ( device, "CHAINED %p %s could not open %s on ",
+                      device, efi_handle_name ( device ),
                       efi_guid_ntoa ( chained->protocol ) );
-               DBGC ( device, "%s: %s\n",
-                      efi_handle_name ( parent ), strerror ( rc ) );
+               DBGC ( device, "%p %s: %s\n",
+                      parent, efi_handle_name ( parent ), strerror ( rc ) );
                goto err_open_protocol;
        }
 
@@ -130,25 +130,25 @@ static int chained_supported ( EFI_HANDLE device,
                                          efi_image_handle, device,
                                          EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
                rc = -EEFI ( efirc );
-               DBGCP ( device, "CHAINED %s is not a %s device\n",
-                       efi_handle_name ( device ),
+               DBGCP ( device, "CHAINED %p %s is not a %s device\n",
+                       device, efi_handle_name ( device ),
                        efi_guid_ntoa ( chained->protocol ) );
                goto err_open_protocol;
        }
 
        /* Test for a match against the chainloading device */
        if ( interface != chained->interface ) {
-               DBGC ( device, "CHAINED %s %p is not the chainloaded %s\n",
-                      efi_handle_name ( device ), interface,
-                      efi_guid_ntoa ( chained->protocol ) );
+               DBGC ( device, "CHAINED %p %s %p is not the chainloaded "
+                      "%s\n", device, efi_handle_name ( device ),
+                      interface, efi_guid_ntoa ( chained->protocol ) );
                rc = -ENOTTY;
                goto err_no_match;
        }
 
        /* Success */
        rc = 0;
-       DBGC ( device, "CHAINED %s %p is the chainloaded %s\n",
-              efi_handle_name ( device ), interface,
+       DBGC ( device, "CHAINED %p %s %p is the chainloaded %s\n",
+              device, efi_handle_name ( device ), interface,
               efi_guid_ntoa ( chained->protocol ) );
 
  err_no_match:
diff --git a/roms/ipxe/src/drivers/net/eoib.c b/roms/ipxe/src/drivers/net/eoib.c
deleted file mode 100644 (file)
index f58e74b..0000000
+++ /dev/null
@@ -1,895 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ipxe/errortab.h>
-#include <ipxe/malloc.h>
-#include <ipxe/iobuf.h>
-#include <ipxe/if_ether.h>
-#include <ipxe/netdevice.h>
-#include <ipxe/ethernet.h>
-#include <ipxe/infiniband.h>
-#include <ipxe/ib_mcast.h>
-#include <ipxe/ib_pathrec.h>
-#include <ipxe/eoib.h>
-
-/** @file
- *
- * Ethernet over Infiniband
- *
- */
-
-/** Number of EoIB send work queue entries */
-#define EOIB_NUM_SEND_WQES 8
-
-/** Number of EoIB receive work queue entries */
-#define EOIB_NUM_RECV_WQES 4
-
-/** Number of EoIB completion queue entries */
-#define EOIB_NUM_CQES 16
-
-/** Link status for "broadcast join in progress" */
-#define EINPROGRESS_JOINING __einfo_error ( EINFO_EINPROGRESS_JOINING )
-#define EINFO_EINPROGRESS_JOINING __einfo_uniqify \
-       ( EINFO_EINPROGRESS, 0x01, "Joining" )
-
-/** Human-readable message for the link status */
-struct errortab eoib_errors[] __errortab = {
-       __einfo_errortab ( EINFO_EINPROGRESS_JOINING ),
-};
-
-/** List of EoIB devices */
-static LIST_HEAD ( eoib_devices );
-
-static struct net_device_operations eoib_operations;
-
-/****************************************************************************
- *
- * EoIB peer cache
- *
- ****************************************************************************
- */
-
-/** An EoIB peer cache entry */
-struct eoib_peer {
-       /** List of EoIB peer cache entries */
-       struct list_head list;
-       /** Ethernet MAC */
-       uint8_t mac[ETH_ALEN];
-       /** Infiniband address vector */
-       struct ib_address_vector av;
-};
-
-/**
- * Find EoIB peer cache entry
- *
- * @v eoib             EoIB device
- * @v mac              Ethernet MAC
- * @ret peer           EoIB peer, or NULL if not found
- */
-static struct eoib_peer * eoib_find_peer ( struct eoib_device *eoib,
-                                          const uint8_t *mac ) {
-       struct eoib_peer *peer;
-
-       /* Find peer cache entry */
-       list_for_each_entry ( peer, &eoib->peers, list ) {
-               if ( memcmp ( mac, peer->mac, sizeof ( peer->mac ) ) == 0 ) {
-                       /* Move peer to start of list */
-                       list_del ( &peer->list );
-                       list_add ( &peer->list, &eoib->peers );
-                       return peer;
-               }
-       }
-
-       return NULL;
-}
-
-/**
- * Create EoIB peer cache entry
- *
- * @v eoib             EoIB device
- * @v mac              Ethernet MAC
- * @ret peer           EoIB peer, or NULL on error
- */
-static struct eoib_peer * eoib_create_peer ( struct eoib_device *eoib,
-                                            const uint8_t *mac ) {
-       struct eoib_peer *peer;
-
-       /* Allocate and initialise peer cache entry */
-       peer = zalloc ( sizeof ( *peer ) );
-       if ( peer ) {
-               memcpy ( peer->mac, mac, sizeof ( peer->mac ) );
-               list_add ( &peer->list, &eoib->peers );
-       }
-       return peer;
-}
-
-/**
- * Flush EoIB peer cache
- *
- * @v eoib             EoIB device
- */
-static void eoib_flush_peers ( struct eoib_device *eoib ) {
-       struct eoib_peer *peer;
-       struct eoib_peer *tmp;
-
-       list_for_each_entry_safe ( peer, tmp, &eoib->peers, list ) {
-               list_del ( &peer->list );
-               free ( peer );
-       }
-}
-
-/**
- * Discard some entries from the peer cache
- *
- * @ret discarded      Number of cached items discarded
- */
-static unsigned int eoib_discard ( void ) {
-       struct net_device *netdev;
-       struct eoib_device *eoib;
-       struct eoib_peer *peer;
-       unsigned int discarded = 0;
-
-       /* Try to discard one cache entry for each EoIB device */
-       for_each_netdev ( netdev ) {
-
-               /* Skip non-EoIB devices */
-               if ( netdev->op != &eoib_operations )
-                       continue;
-               eoib = netdev->priv;
-
-               /* Discard least recently used cache entry (if any) */
-               list_for_each_entry_reverse ( peer, &eoib->peers, list ) {
-                       list_del ( &peer->list );
-                       free ( peer );
-                       discarded++;
-                       break;
-               }
-       }
-
-       return discarded;
-}
-
-/** EoIB cache discarder */
-struct cache_discarder eoib_discarder __cache_discarder ( CACHE_EXPENSIVE ) = {
-       .discard = eoib_discard,
-};
-
-/**
- * Find destination address vector
- *
- * @v eoib             EoIB device
- * @v mac              Ethernet MAC
- * @ret av             Address vector, or NULL to send as broadcast
- */
-static struct ib_address_vector * eoib_tx_av ( struct eoib_device *eoib,
-                                              const uint8_t *mac ) {
-       struct ib_device *ibdev = eoib->ibdev;
-       struct eoib_peer *peer;
-       int rc;
-
-       /* If this is a broadcast or multicast MAC address, then send
-        * this packet as a broadcast.
-        */
-       if ( is_multicast_ether_addr ( mac ) ) {
-               DBGCP ( eoib, "EoIB %s %s TX multicast\n",
-                       eoib->name, eth_ntoa ( mac ) );
-               return NULL;
-       }
-
-       /* If we have no peer cache entry, then create one and send
-        * this packet as a broadcast.
-        */
-       peer = eoib_find_peer ( eoib, mac );
-       if ( ! peer ) {
-               DBGC ( eoib, "EoIB %s %s TX unknown\n",
-                      eoib->name, eth_ntoa ( mac ) );
-               eoib_create_peer ( eoib, mac );
-               return NULL;
-       }
-
-       /* If we have not yet recorded a received GID and QPN for this
-        * peer cache entry, then send this packet as a broadcast.
-        */
-       if ( ! peer->av.gid_present ) {
-               DBGCP ( eoib, "EoIB %s %s TX not yet recorded\n",
-                       eoib->name, eth_ntoa ( mac ) );
-               return NULL;
-       }
-
-       /* If we have not yet resolved a path to this peer, then send
-        * this packet as a broadcast.
-        */
-       if ( ( rc = ib_resolve_path ( ibdev, &peer->av ) ) != 0 ) {
-               DBGCP ( eoib, "EoIB %s %s TX not yet resolved\n",
-                       eoib->name, eth_ntoa ( mac ) );
-               return NULL;
-       }
-
-       /* Force use of GRH even for local destinations */
-       peer->av.gid_present = 1;
-
-       /* We have a fully resolved peer: send this packet as a
-        * unicast.
-        */
-       DBGCP ( eoib, "EoIB %s %s TX " IB_GID_FMT " QPN %#lx\n", eoib->name,
-               eth_ntoa ( mac ), IB_GID_ARGS ( &peer->av.gid ), peer->av.qpn );
-       return &peer->av;
-}
-
-/**
- * Record source address vector
- *
- * @v eoib             EoIB device
- * @v mac              Ethernet MAC
- * @v lid              Infiniband LID
- */
-static void eoib_rx_av ( struct eoib_device *eoib, const uint8_t *mac,
-                        const struct ib_address_vector *av ) {
-       const union ib_gid *gid = &av->gid;
-       unsigned long qpn = av->qpn;
-       struct eoib_peer *peer;
-
-       /* Sanity checks */
-       if ( ! av->gid_present ) {
-               DBGC ( eoib, "EoIB %s %s RX with no GID\n",
-                      eoib->name, eth_ntoa ( mac ) );
-               return;
-       }
-
-       /* Find peer cache entry (if any) */
-       peer = eoib_find_peer ( eoib, mac );
-       if ( ! peer ) {
-               DBGCP ( eoib, "EoIB %s %s RX " IB_GID_FMT " (ignored)\n",
-                       eoib->name, eth_ntoa ( mac ), IB_GID_ARGS ( gid ) );
-               return;
-       }
-
-       /* Some dubious EoIB implementations utilise an Ethernet-to-
-        * EoIB gateway that will send packets from the wrong QPN.
-        */
-       if ( eoib_has_gateway ( eoib ) &&
-            ( memcmp ( gid, &eoib->gateway.gid, sizeof ( *gid ) ) == 0 ) ) {
-               qpn = eoib->gateway.qpn;
-       }
-
-       /* Do nothing if peer cache entry is complete and correct */
-       if ( ( peer->av.lid == av->lid ) && ( peer->av.qpn == qpn ) ) {
-               DBGCP ( eoib, "EoIB %s %s RX unchanged\n",
-                       eoib->name, eth_ntoa ( mac ) );
-               return;
-       }
-
-       /* Update peer cache entry */
-       peer->av.qpn = qpn;
-       peer->av.qkey = eoib->broadcast.qkey;
-       peer->av.gid_present = 1;
-       memcpy ( &peer->av.gid, gid, sizeof ( peer->av.gid ) );
-       DBGC ( eoib, "EoIB %s %s RX " IB_GID_FMT " QPN %#lx\n", eoib->name,
-              eth_ntoa ( mac ), IB_GID_ARGS ( &peer->av.gid ), peer->av.qpn );
-}
-
-/****************************************************************************
- *
- * EoIB network device
- *
- ****************************************************************************
- */
-
-/**
- * Transmit packet via EoIB network device
- *
- * @v netdev           Network device
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int eoib_transmit ( struct net_device *netdev,
-                          struct io_buffer *iobuf ) {
-       struct eoib_device *eoib = netdev->priv;
-       struct eoib_header *eoib_hdr;
-       struct ethhdr *ethhdr;
-       struct ib_address_vector *av;
-       size_t zlen;
-
-       /* Sanity checks */
-       assert ( iob_len ( iobuf ) >= sizeof ( *ethhdr ) );
-       assert ( iob_headroom ( iobuf ) >= sizeof ( *eoib_hdr ) );
-
-       /* Look up destination address vector */
-       ethhdr = iobuf->data;
-       av = eoib_tx_av ( eoib, ethhdr->h_dest );
-
-       /* Prepend EoIB header */
-       eoib_hdr = iob_push ( iobuf, sizeof ( *eoib_hdr ) );
-       eoib_hdr->magic = htons ( EOIB_MAGIC );
-       eoib_hdr->reserved = 0;
-
-       /* Pad buffer to minimum Ethernet frame size */
-       zlen = ( sizeof ( *eoib_hdr ) + ETH_ZLEN );
-       assert ( zlen <= IOB_ZLEN );
-       if ( iob_len ( iobuf ) < zlen )
-               iob_pad ( iobuf, zlen );
-
-       /* If we have no unicast address then send as a broadcast,
-        * with a duplicate sent to the gateway if applicable.
-        */
-       if ( ! av ) {
-               av = &eoib->broadcast;
-               if ( eoib_has_gateway ( eoib ) )
-                       eoib->duplicate ( eoib, iobuf );
-       }
-
-       /* Post send work queue entry */
-       return ib_post_send ( eoib->ibdev, eoib->qp, av, iobuf );
-}
-
-/**
- * Handle EoIB send completion
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void eoib_complete_send ( struct ib_device *ibdev __unused,
-                                struct ib_queue_pair *qp,
-                                struct io_buffer *iobuf, int rc ) {
-       struct eoib_device *eoib = ib_qp_get_ownerdata ( qp );
-
-       netdev_tx_complete_err ( eoib->netdev, iobuf, rc );
-}
-
-/**
- * Handle EoIB receive completion
- *
- * @v ibdev            Infiniband device
- * @v qp               Queue pair
- * @v dest             Destination address vector, or NULL
- * @v source           Source address vector, or NULL
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void eoib_complete_recv ( struct ib_device *ibdev __unused,
-                                struct ib_queue_pair *qp,
-                                struct ib_address_vector *dest __unused,
-                                struct ib_address_vector *source,
-                                struct io_buffer *iobuf, int rc ) {
-       struct eoib_device *eoib = ib_qp_get_ownerdata ( qp );
-       struct net_device *netdev = eoib->netdev;
-       struct eoib_header *eoib_hdr;
-       struct ethhdr *ethhdr;
-
-       /* Record errors */
-       if ( rc != 0 ) {
-               netdev_rx_err ( netdev, iobuf, rc );
-               return;
-       }
-
-       /* Sanity check */
-       if ( iob_len ( iobuf ) < ( sizeof ( *eoib_hdr ) + sizeof ( *ethhdr ) )){
-               DBGC ( eoib, "EoIB %s received packet too short to "
-                      "contain EoIB and Ethernet headers\n", eoib->name );
-               DBGC_HD ( eoib, iobuf->data, iob_len ( iobuf ) );
-               netdev_rx_err ( netdev, iobuf, -EIO );
-               return;
-       }
-       if ( ! source ) {
-               DBGC ( eoib, "EoIB %s received packet without address "
-                      "vector\n", eoib->name );
-               netdev_rx_err ( netdev, iobuf, -ENOTTY );
-               return;
-       }
-
-       /* Strip EoIB header */
-       iob_pull ( iobuf, sizeof ( *eoib_hdr ) );
-
-       /* Update neighbour cache entry, if any */
-       ethhdr = iobuf->data;
-       eoib_rx_av ( eoib, ethhdr->h_source, source );
-
-       /* Hand off to network layer */
-       netdev_rx ( netdev, iobuf );
-}
-
-/** EoIB completion operations */
-static struct ib_completion_queue_operations eoib_cq_op = {
-       .complete_send = eoib_complete_send,
-       .complete_recv = eoib_complete_recv,
-};
-
-/** EoIB queue pair operations */
-static struct ib_queue_pair_operations eoib_qp_op = {
-       .alloc_iob = alloc_iob,
-};
-
-/**
- * Poll EoIB network device
- *
- * @v netdev           Network device
- */
-static void eoib_poll ( struct net_device *netdev ) {
-       struct eoib_device *eoib = netdev->priv;
-       struct ib_device *ibdev = eoib->ibdev;
-
-       /* Poll Infiniband device */
-       ib_poll_eq ( ibdev );
-
-       /* Poll the retry timers (required for EoIB multicast join) */
-       retry_poll();
-}
-
-/**
- * Handle EoIB broadcast multicast group join completion
- *
- * @v membership       Multicast group membership
- * @v rc               Status code
- */
-static void eoib_join_complete ( struct ib_mc_membership *membership, int rc ) {
-       struct eoib_device *eoib =
-               container_of ( membership, struct eoib_device, membership );
-
-       /* Record join status as link status */
-       netdev_link_err ( eoib->netdev, rc );
-}
-
-/**
- * Join EoIB broadcast multicast group
- *
- * @v eoib             EoIB device
- * @ret rc             Return status code
- */
-static int eoib_join_broadcast_group ( struct eoib_device *eoib ) {
-       int rc;
-
-       /* Join multicast group */
-       if ( ( rc = ib_mcast_join ( eoib->ibdev, eoib->qp,
-                                   &eoib->membership, &eoib->broadcast,
-                                   eoib->mask, eoib_join_complete ) ) != 0 ) {
-               DBGC ( eoib, "EoIB %s could not join broadcast group: %s\n",
-                      eoib->name, strerror ( rc ) );
-               return rc;
-       }
-
-       return 0;
-}
-
-/**
- * Leave EoIB broadcast multicast group
- *
- * @v eoib             EoIB device
- */
-static void eoib_leave_broadcast_group ( struct eoib_device *eoib ) {
-
-       /* Leave multicast group */
-       ib_mcast_leave ( eoib->ibdev, eoib->qp, &eoib->membership );
-}
-
-/**
- * Handle link status change
- *
- * @v eoib             EoIB device
- */
-static void eoib_link_state_changed ( struct eoib_device *eoib ) {
-       struct net_device *netdev = eoib->netdev;
-       struct ib_device *ibdev = eoib->ibdev;
-       int rc;
-
-       /* Leave existing broadcast group */
-       if ( eoib->qp )
-               eoib_leave_broadcast_group ( eoib );
-
-       /* Update broadcast GID based on potentially-new partition key */
-       eoib->broadcast.gid.words[2] = htons ( ibdev->pkey | IB_PKEY_FULL );
-
-       /* Set net device link state to reflect Infiniband link state */
-       rc = ib_link_rc ( ibdev );
-       netdev_link_err ( netdev, ( rc ? rc : -EINPROGRESS_JOINING ) );
-
-       /* Join new broadcast group */
-       if ( ib_is_open ( ibdev ) && ib_link_ok ( ibdev ) && eoib->qp &&
-            ( ( rc = eoib_join_broadcast_group ( eoib ) ) != 0 ) ) {
-               DBGC ( eoib, "EoIB %s could not rejoin broadcast group: "
-                      "%s\n", eoib->name, strerror ( rc ) );
-               netdev_link_err ( netdev, rc );
-               return;
-       }
-}
-
-/**
- * Open EoIB network device
- *
- * @v netdev           Network device
- * @ret rc             Return status code
- */
-static int eoib_open ( struct net_device *netdev ) {
-       struct eoib_device *eoib = netdev->priv;
-       struct ib_device *ibdev = eoib->ibdev;
-       int rc;
-
-       /* Open IB device */
-       if ( ( rc = ib_open ( ibdev ) ) != 0 ) {
-               DBGC ( eoib, "EoIB %s could not open %s: %s\n",
-                      eoib->name, ibdev->name, strerror ( rc ) );
-               goto err_ib_open;
-       }
-
-       /* Allocate completion queue */
-       eoib->cq = ib_create_cq ( ibdev, EOIB_NUM_CQES, &eoib_cq_op );
-       if ( ! eoib->cq ) {
-               DBGC ( eoib, "EoIB %s could not allocate completion queue\n",
-                      eoib->name );
-               rc = -ENOMEM;
-               goto err_create_cq;
-       }
-
-       /* Allocate queue pair */
-       eoib->qp = ib_create_qp ( ibdev, IB_QPT_UD, EOIB_NUM_SEND_WQES,
-                                  eoib->cq, EOIB_NUM_RECV_WQES, eoib->cq,
-                                 &eoib_qp_op, netdev->name );
-       if ( ! eoib->qp ) {
-               DBGC ( eoib, "EoIB %s could not allocate queue pair\n",
-                      eoib->name );
-               rc = -ENOMEM;
-               goto err_create_qp;
-       }
-       ib_qp_set_ownerdata ( eoib->qp, eoib );
-
-       /* Fill receive rings */
-       ib_refill_recv ( ibdev, eoib->qp );
-
-       /* Fake a link status change to join the broadcast group */
-       eoib_link_state_changed ( eoib );
-
-       return 0;
-
-       ib_destroy_qp ( ibdev, eoib->qp );
-       eoib->qp = NULL;
- err_create_qp:
-       ib_destroy_cq ( ibdev, eoib->cq );
-       eoib->cq = NULL;
- err_create_cq:
-       ib_close ( ibdev );
- err_ib_open:
-       return rc;
-}
-
-/**
- * Close EoIB network device
- *
- * @v netdev           Network device
- */
-static void eoib_close ( struct net_device *netdev ) {
-       struct eoib_device *eoib = netdev->priv;
-       struct ib_device *ibdev = eoib->ibdev;
-
-       /* Flush peer cache */
-       eoib_flush_peers ( eoib );
-
-       /* Leave broadcast group */
-       eoib_leave_broadcast_group ( eoib );
-
-       /* Tear down the queues */
-       ib_destroy_qp ( ibdev, eoib->qp );
-       eoib->qp = NULL;
-       ib_destroy_cq ( ibdev, eoib->cq );
-       eoib->cq = NULL;
-
-       /* Close IB device */
-       ib_close ( ibdev );
-}
-
-/** EoIB network device operations */
-static struct net_device_operations eoib_operations = {
-       .open           = eoib_open,
-       .close          = eoib_close,
-       .transmit       = eoib_transmit,
-       .poll           = eoib_poll,
-};
-
-/**
- * Create EoIB device
- *
- * @v ibdev            Infiniband device
- * @v hw_addr          Ethernet MAC
- * @v broadcast                Broadcast address vector
- * @v name             Interface name (or NULL to use default)
- * @ret rc             Return status code
- */
-int eoib_create ( struct ib_device *ibdev, const uint8_t *hw_addr,
-                 struct ib_address_vector *broadcast, const char *name ) {
-       struct net_device *netdev;
-       struct eoib_device *eoib;
-       int rc;
-
-       /* Allocate network device */
-       netdev = alloc_etherdev ( sizeof ( *eoib ) );
-       if ( ! netdev ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       netdev_init ( netdev, &eoib_operations );
-       eoib = netdev->priv;
-       netdev->dev = ibdev->dev;
-       eoib->netdev = netdev;
-       eoib->ibdev = ibdev_get ( ibdev );
-       memcpy ( &eoib->broadcast, broadcast, sizeof ( eoib->broadcast ) );
-       INIT_LIST_HEAD ( &eoib->peers );
-
-       /* Set MAC address */
-       memcpy ( netdev->hw_addr, hw_addr, ETH_ALEN );
-
-       /* Set interface name, if applicable */
-       if ( name )
-               snprintf ( netdev->name, sizeof ( netdev->name ), "%s", name );
-       eoib->name = netdev->name;
-
-       /* Add to list of EoIB devices */
-       list_add_tail ( &eoib->list, &eoib_devices );
-
-       /* Register network device */
-       if ( ( rc = register_netdev ( netdev ) ) != 0 )
-               goto err_register;
-
-       DBGC ( eoib, "EoIB %s created for %s MAC %s\n",
-              eoib->name, ibdev->name, eth_ntoa ( hw_addr ) );
-       DBGC ( eoib, "EoIB %s broadcast GID " IB_GID_FMT "\n",
-              eoib->name, IB_GID_ARGS ( &broadcast->gid ) );
-       return 0;
-
-       unregister_netdev ( netdev );
- err_register:
-       list_del ( &eoib->list );
-       ibdev_put ( ibdev );
-       netdev_nullify ( netdev );
-       netdev_put ( netdev );
- err_alloc:
-       return rc;
-}
-
-/**
- * Find EoIB device
- *
- * @v ibdev            Infiniband device
- * @v hw_addr          Original Ethernet MAC
- * @ret eoib           EoIB device
- */
-struct eoib_device * eoib_find ( struct ib_device *ibdev,
-                                const uint8_t *hw_addr ) {
-       struct eoib_device *eoib;
-
-       list_for_each_entry ( eoib, &eoib_devices, list ) {
-               if ( ( eoib->ibdev == ibdev ) &&
-                    ( memcmp ( eoib->netdev->hw_addr, hw_addr,
-                               ETH_ALEN ) == 0 ) )
-                       return eoib;
-       }
-       return NULL;
-}
-
-/**
- * Remove EoIB device
- *
- * @v eoib             EoIB device
- */
-void eoib_destroy ( struct eoib_device *eoib ) {
-       struct net_device *netdev = eoib->netdev;
-
-       /* Unregister network device */
-       unregister_netdev ( netdev );
-
-       /* Remove from list of network devices */
-       list_del ( &eoib->list );
-
-       /* Drop reference to Infiniband device */
-       ibdev_put ( eoib->ibdev );
-
-       /* Free network device */
-       DBGC ( eoib, "EoIB %s destroyed\n", eoib->name );
-       netdev_nullify ( netdev );
-       netdev_put ( netdev );
-}
-
-/**
- * Probe EoIB device
- *
- * @v ibdev            Infiniband device
- * @ret rc             Return status code
- */
-static int eoib_probe ( struct ib_device *ibdev __unused ) {
-
-       /* EoIB devices are not created automatically */
-       return 0;
-}
-
-/**
- * Handle device or link status change
- *
- * @v ibdev            Infiniband device
- */
-static void eoib_notify ( struct ib_device *ibdev ) {
-       struct eoib_device *eoib;
-
-       /* Handle link status change for any attached EoIB devices */
-       list_for_each_entry ( eoib, &eoib_devices, list ) {
-               if ( eoib->ibdev != ibdev )
-                       continue;
-               eoib_link_state_changed ( eoib );
-       }
-}
-
-/**
- * Remove EoIB device
- *
- * @v ibdev            Infiniband device
- */
-static void eoib_remove ( struct ib_device *ibdev ) {
-       struct eoib_device *eoib;
-       struct eoib_device *tmp;
-
-       /* Remove any attached EoIB devices */
-       list_for_each_entry_safe ( eoib, tmp, &eoib_devices, list ) {
-               if ( eoib->ibdev != ibdev )
-                       continue;
-               eoib_destroy ( eoib );
-       }
-}
-
-/** EoIB driver */
-struct ib_driver eoib_driver __ib_driver = {
-       .name = "EoIB",
-       .probe = eoib_probe,
-       .notify = eoib_notify,
-       .remove = eoib_remove,
-};
-
-/****************************************************************************
- *
- * EoIB heartbeat packets
- *
- ****************************************************************************
- */
-
-/**
- * Silently ignore incoming EoIB heartbeat packets
- *
- * @v iobuf            I/O buffer
- * @v netdev           Network device
- * @v ll_source                Link-layer source address
- * @v flags            Packet flags
- * @ret rc             Return status code
- */
-static int eoib_heartbeat_rx ( struct io_buffer *iobuf,
-                              struct net_device *netdev __unused,
-                              const void *ll_dest __unused,
-                              const void *ll_source __unused,
-                              unsigned int flags __unused ) {
-       free_iob ( iobuf );
-       return 0;
-}
-
-/**
- * Transcribe EoIB heartbeat address
- *
- * @v net_addr         EoIB heartbeat address
- * @ret string         "<EoIB>"
- *
- * This operation is meaningless for the EoIB heartbeat protocol.
- */
-static const char * eoib_heartbeat_ntoa ( const void *net_addr __unused ) {
-       return "<EoIB>";
-}
-
-/** EoIB heartbeat network protocol */
-struct net_protocol eoib_heartbeat_protocol __net_protocol = {
-       .name = "EoIB",
-       .net_proto = htons ( EOIB_MAGIC ),
-       .rx = eoib_heartbeat_rx,
-       .ntoa = eoib_heartbeat_ntoa,
-};
-
-/****************************************************************************
- *
- * EoIB gateway
- *
- ****************************************************************************
- *
- * Some dubious EoIB implementations require all broadcast traffic to
- * be sent twice: once to the actual broadcast group, and once as a
- * unicast to the EoIB-to-Ethernet gateway.  This somewhat curious
- * design arises since the EoIB-to-Ethernet gateway hardware lacks the
- * ability to attach a queue pair to a multicast GID (or LID), and so
- * cannot receive traffic sent to the broadcast group.
- *
- */
-
-/**
- * Transmit duplicate packet to the EoIB gateway
- *
- * @v eoib             EoIB device
- * @v original         Original I/O buffer
- */
-static void eoib_duplicate ( struct eoib_device *eoib,
-                            struct io_buffer *original ) {
-       struct net_device *netdev = eoib->netdev;
-       struct ib_device *ibdev = eoib->ibdev;
-       struct ib_address_vector *av = &eoib->gateway;
-       size_t len = iob_len ( original );
-       struct io_buffer *copy;
-       int rc;
-
-       /* Create copy of I/O buffer */
-       copy = alloc_iob ( len );
-       if ( ! copy ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       memcpy ( iob_put ( copy, len ), original->data, len );
-
-       /* Append to network device's transmit queue */
-       list_add_tail ( &copy->list, &original->list );
-
-       /* Resolve path to gateway */
-       if ( ( rc = ib_resolve_path ( ibdev, av ) ) != 0 ) {
-               DBGC ( eoib, "EoIB %s no path to gateway: %s\n",
-                      eoib->name, strerror ( rc ) );
-               goto err_path;
-       }
-
-       /* Force use of GRH even for local destinations */
-       av->gid_present = 1;
-
-       /* Post send work queue entry */
-       if ( ( rc = ib_post_send ( eoib->ibdev, eoib->qp, av, copy ) ) != 0 )
-               goto err_post_send;
-
-       return;
-
- err_post_send:
- err_path:
- err_alloc:
-       netdev_tx_complete_err ( netdev, copy, rc );
-}
-
-/**
- * Set EoIB gateway
- *
- * @v eoib             EoIB device
- * @v av               Address vector, or NULL to clear gateway
- */
-void eoib_set_gateway ( struct eoib_device *eoib,
-                       struct ib_address_vector *av ) {
-
-       if ( av ) {
-               DBGC ( eoib, "EoIB %s using gateway " IB_GID_FMT "\n",
-                      eoib->name, IB_GID_ARGS ( &av->gid ) );
-               memcpy ( &eoib->gateway, av, sizeof ( eoib->gateway ) );
-               eoib->duplicate = eoib_duplicate;
-       } else {
-               DBGC ( eoib, "EoIB %s not using gateway\n", eoib->name );
-               eoib->duplicate = NULL;
-       }
-}
index 2cd41d4..29d1174 100644 (file)
@@ -4006,7 +4006,7 @@ efab_init_mac ( struct efab_nic *efab )
                 * because we want to use it, or because we're about
                 * to reset the mac anyway
                 */
-               mdelay ( 2000 );
+               sleep ( 2 );
 
                if ( ! efab->link_up ) {
                        EFAB_ERR ( "!\n" );
index 127f5c7..6309e9a 100644 (file)
@@ -295,23 +295,14 @@ static int intel_reset ( struct intel_nic *intel ) {
        writel ( ctrl, intel->regs + INTEL_CTRL );
        mdelay ( INTEL_RESET_DELAY_MS );
 
-       /* On some models (notably ICH), the PHY reset mechanism
-        * appears to be broken.  In particular, the PHY_CTRL register
-        * will be correctly loaded from NVM but the values will not
-        * be propagated to the "OEM bits" PHY register.  This
-        * typically has the effect of dropping the link speed to
-        * 10Mbps.
-        *
-        * Work around this problem by skipping the PHY reset if
-        * either (a) the link is already up, or (b) this particular
-        * NIC is known to be broken.
+       /* If link is already up, do not attempt to reset the PHY.  On
+        * some models (notably ICH), performing a PHY reset seems to
+        * drop the link speed to 10Mbps.
         */
        status = readl ( intel->regs + INTEL_STATUS );
-       if ( ( intel->flags & INTEL_NO_PHY_RST ) ||
-            ( status & INTEL_STATUS_LU ) ) {
-               DBGC ( intel, "INTEL %p %sMAC reset (ctrl %08x)\n", intel,
-                      ( ( intel->flags & INTEL_NO_PHY_RST ) ? "forced " : "" ),
-                      ctrl );
+       if ( status & INTEL_STATUS_LU ) {
+               DBGC ( intel, "INTEL %p MAC reset (ctrl %08x)\n",
+                      intel, ctrl );
                return 0;
        }
 
@@ -1038,7 +1029,7 @@ static struct pci_device_id intel_nics[] = {
        PCI_ROM ( 0x8086, 0x10f5, "82567lm", "82567LM", 0 ),
        PCI_ROM ( 0x8086, 0x10f6, "82574l", "82574L", 0 ),
        PCI_ROM ( 0x8086, 0x1501, "82567v-3", "82567V-3", INTEL_PBS_ERRATA ),
-       PCI_ROM ( 0x8086, 0x1502, "82579lm", "82579LM", INTEL_NO_PHY_RST ),
+       PCI_ROM ( 0x8086, 0x1502, "82579lm", "82579LM", 0 ),
        PCI_ROM ( 0x8086, 0x1503, "82579v", "82579V", 0 ),
        PCI_ROM ( 0x8086, 0x150a, "82576ns", "82576NS", 0 ),
        PCI_ROM ( 0x8086, 0x150c, "82583v", "82583V", 0 ),
@@ -1057,18 +1048,14 @@ static struct pci_device_id intel_nics[] = {
        PCI_ROM ( 0x8086, 0x1526, "82576-5", "82576", 0 ),
        PCI_ROM ( 0x8086, 0x1527, "82580-f2", "82580 Fiber", 0 ),
        PCI_ROM ( 0x8086, 0x1533, "i210", "I210", 0 ),
-       PCI_ROM ( 0x8086, 0x1539, "i211", "I211", 0 ),
-       PCI_ROM ( 0x8086, 0x153a, "i217lm", "I217-LM", INTEL_NO_PHY_RST ),
+       PCI_ROM ( 0x8086, 0x153a, "i217lm", "I217-LM", 0 ),
        PCI_ROM ( 0x8086, 0x153b, "i217v", "I217-V", 0 ),
        PCI_ROM ( 0x8086, 0x1559, "i218v", "I218-V", 0),
        PCI_ROM ( 0x8086, 0x155a, "i218lm", "I218-LM", 0),
-       PCI_ROM ( 0x8086, 0x157b, "i210-2", "I210", 0 ),
-       PCI_ROM ( 0x8086, 0x15a0, "i218lm-2", "I218-LM", INTEL_NO_PHY_RST ),
+       PCI_ROM ( 0x8086, 0x15a0, "i218lm-2", "I218-LM", 0 ),
        PCI_ROM ( 0x8086, 0x15a1, "i218v-2", "I218-V", 0 ),
-       PCI_ROM ( 0x8086, 0x15a2, "i218lm-3", "I218-LM", INTEL_NO_PHY_RST ),
-       PCI_ROM ( 0x8086, 0x15a3, "i218v-3", "I218-V", INTEL_NO_PHY_RST ),
-       PCI_ROM ( 0x8086, 0x15b7, "i219lm-2", "I219-LM (2)", 0 ),
-       PCI_ROM ( 0x8086, 0x15b8, "i219v-2", "I219-V (2)", 0 ),
+       PCI_ROM ( 0x8086, 0x15a2, "i218lm-3", "I218-LM", 0 ),
+       PCI_ROM ( 0x8086, 0x15a3, "i218v-3", "I218-V", 0 ),
        PCI_ROM ( 0x8086, 0x294c, "82566dc-2", "82566DC-2", 0 ),
        PCI_ROM ( 0x8086, 0x2e6e, "cemedia", "CE Media Processor", 0 ),
 };
index 16a72a1..ce9e3f4 100644 (file)
@@ -99,8 +99,8 @@ struct intel_descriptor {
 #define INTEL_IRQ_TXQE         0x00000002UL    /**< Transmit queue empty */
 #define INTEL_IRQ_LSC          0x00000004UL    /**< Link status change */
 #define INTEL_IRQ_RXDMT0       0x00000010UL    /**< Receive queue low */
-#define INTEL_IRQ_RXO          0x00000040UL    /**< Receive overrun */
 #define INTEL_IRQ_RXT0         0x00000080UL    /**< Receive timer */
+#define INTEL_IRQ_RXO          0x00000400UL    /**< Receive overrun */
 
 /** Interrupt Mask Set/Read Register */
 #define INTEL_IMS 0x000d0UL
@@ -301,8 +301,6 @@ enum intel_flags {
        INTEL_PBS_ERRATA = 0x0001,
        /** VMware missing interrupt workaround required */
        INTEL_VMWARE = 0x0002,
-       /** PHY reset is broken */
-       INTEL_NO_PHY_RST = 0x0004,
 };
 
 /**
index 8a65c87..6552d76 100644 (file)
@@ -65,23 +65,13 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
                          "Missing REMAC for IPv4 packet (ARP sent)" )
 
 /** Number of IPoIB send work queue entries */
-#define IPOIB_NUM_SEND_WQES 8
+#define IPOIB_NUM_SEND_WQES 2
 
 /** Number of IPoIB receive work queue entries */
 #define IPOIB_NUM_RECV_WQES 4
 
 /** Number of IPoIB completion entries */
-#define IPOIB_NUM_CQES 16
-
-/** An IPoIB broadcast address */
-struct ipoib_broadcast {
-       /** MAC address */
-       struct ipoib_mac mac;
-       /** Address vector */
-       struct ib_address_vector av;
-       /** Multicast group membership */
-       struct ib_mc_membership membership;
-};
+#define IPOIB_NUM_CQES 8
 
 /** An IPoIB device */
 struct ipoib_device {
@@ -89,16 +79,22 @@ struct ipoib_device {
        struct net_device *netdev;
        /** Underlying Infiniband device */
        struct ib_device *ibdev;
-       /** List of IPoIB devices */
-       struct list_head list;
        /** Completion queue */
        struct ib_completion_queue *cq;
        /** Queue pair */
        struct ib_queue_pair *qp;
        /** Local MAC */
        struct ipoib_mac mac;
-       /** Broadcast address */
-       struct ipoib_broadcast broadcast;
+       /** Broadcast MAC */
+       struct ipoib_mac broadcast;
+       /** Joined to IPv4 broadcast multicast group
+        *
+        * This flag indicates whether or not we have initiated the
+        * join to the IPv4 broadcast multicast group.
+        */
+       int broadcast_joined;
+       /** IPv4 broadcast multicast group membership */
+       struct ib_mc_membership broadcast_membership;
        /** REMAC cache */
        struct list_head peers;
 };
@@ -120,9 +116,6 @@ struct errortab ipoib_errors[] __errortab = {
        __einfo_errortab ( EINFO_EINPROGRESS_JOINING ),
 };
 
-/** List of all IPoIB devices */
-static LIST_HEAD ( ipoib_devices );
-
 static struct net_device_operations ipoib_operations;
 
 /****************************************************************************
@@ -157,7 +150,7 @@ static struct ipoib_mac * ipoib_find_remac ( struct ipoib_device *ipoib,
         * multicasts as broadcasts for simplicity.
         */
        if ( is_multicast_ether_addr ( remac ) )
-               return &ipoib->broadcast.mac;
+               return &ipoib->broadcast;
 
        /* Try to find via REMAC cache */
        list_for_each_entry ( peer, &ipoib->peers, list ) {
@@ -503,10 +496,8 @@ static int ipoib_transmit ( struct net_device *netdev,
        struct ethhdr *ethhdr;
        struct iphdr *iphdr;
        struct ipoib_hdr *ipoib_hdr;
-       struct ipoib_remac *remac;
        struct ipoib_mac *mac;
-       struct ib_address_vector *dest;
-       struct ib_address_vector av;
+       struct ib_address_vector dest;
        uint16_t net_proto;
        int rc;
 
@@ -524,32 +515,12 @@ static int ipoib_transmit ( struct net_device *netdev,
 
        /* Strip eIPoIB header */
        ethhdr = iobuf->data;
-       remac = ( ( struct ipoib_remac * ) ethhdr->h_dest );
        net_proto = ethhdr->h_protocol;
        iob_pull ( iobuf, sizeof ( *ethhdr ) );
 
        /* Identify destination address */
-       if ( is_multicast_ether_addr ( remac ) ) {
-
-               /* Transmit multicasts as broadcasts, for simplicity */
-               dest = &ipoib->broadcast.av;
-
-       } else if ( ( mac = ipoib_find_remac ( ipoib, remac ) ) ) {
-
-               /* Construct address vector from IPoIB MAC */
-               dest = &av;
-               memset ( dest, 0, sizeof ( *dest ) );
-               dest->qpn = ( ntohl ( mac->flags__qpn ) & IB_QPN_MASK );
-               dest->qkey = ipoib->broadcast.av.qkey;
-               dest->gid_present = 1;
-               memcpy ( &dest->gid, &mac->gid, sizeof ( dest->gid ) );
-               if ( ( rc = ib_resolve_path ( ibdev, dest ) ) != 0 ) {
-                       /* Path not resolved yet */
-                       return rc;
-               }
-
-       } else {
-
+       mac = ipoib_find_remac ( ipoib, ( ( void * ) ethhdr->h_dest ) );
+       if ( ! mac ) {
                /* Generate a new ARP request (if possible) to trigger
                 * population of the REMAC cache entry.
                 */
@@ -586,8 +557,17 @@ static int ipoib_transmit ( struct net_device *netdev,
        ipoib_hdr->proto = net_proto;
        ipoib_hdr->reserved = 0;
 
-       /* Transmit packet */
-       return ib_post_send ( ibdev, ipoib->qp, dest, iobuf );
+       /* Construct address vector */
+       memset ( &dest, 0, sizeof ( dest ) );
+       dest.qpn = ( ntohl ( mac->flags__qpn ) & IB_QPN_MASK );
+       dest.gid_present = 1;
+       memcpy ( &dest.gid, &mac->gid, sizeof ( dest.gid ) );
+       if ( ( rc = ib_resolve_path ( ibdev, &dest ) ) != 0 ) {
+               /* Path not resolved yet */
+               return rc;
+       }
+
+       return ib_post_send ( ibdev, ipoib->qp, &dest, iobuf );
 }
 
 /**
@@ -671,8 +651,9 @@ static void ipoib_complete_recv ( struct ib_device *ibdev __unused,
        ethhdr->h_protocol = net_proto;
 
        /* Construct destination address */
-       if ( dest->gid_present && IB_GID_MULTICAST ( &dest->gid ) ) {
-               /* Multicast GID: use the Ethernet broadcast address */
+       if ( dest->gid_present && ( memcmp ( &dest->gid, &ipoib->broadcast.gid,
+                                            sizeof ( dest->gid ) ) == 0 ) ) {
+               /* Broadcast GID; use the Ethernet broadcast address */
                memcpy ( &ethhdr->h_dest, eth_broadcast,
                         sizeof ( ethhdr->h_dest ) );
        } else {
@@ -746,13 +727,18 @@ static void ipoib_poll ( struct net_device *netdev ) {
 /**
  * Handle IPv4 broadcast multicast group join completion
  *
+ * @v ibdev            Infiniband device
+ * @v qp               Queue pair
  * @v membership       Multicast group membership
  * @v rc               Status code
+ * @v mad              Response MAD (or NULL on error)
  */
-void ipoib_join_complete ( struct ib_mc_membership *membership, int rc ) {
+void ipoib_join_complete ( struct ib_device *ibdev __unused,
+                          struct ib_queue_pair *qp __unused,
+                          struct ib_mc_membership *membership, int rc,
+                          union ib_mad *mad __unused ) {
        struct ipoib_device *ipoib = container_of ( membership,
-                                                   struct ipoib_device,
-                                                   broadcast.membership );
+                                  struct ipoib_device, broadcast_membership );
 
        /* Record join status as link status */
        netdev_link_err ( ipoib->netdev, rc );
@@ -767,15 +753,15 @@ void ipoib_join_complete ( struct ib_mc_membership *membership, int rc ) {
 static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
        int rc;
 
-       /* Join multicast group */
        if ( ( rc = ib_mcast_join ( ipoib->ibdev, ipoib->qp,
-                                   &ipoib->broadcast.membership,
-                                   &ipoib->broadcast.av, 0,
+                                   &ipoib->broadcast_membership,
+                                   &ipoib->broadcast.gid,
                                    ipoib_join_complete ) ) != 0 ) {
                DBGC ( ipoib, "IPoIB %p could not join broadcast group: %s\n",
                       ipoib, strerror ( rc ) );
                return rc;
        }
+       ipoib->broadcast_joined = 1;
 
        return 0;
 }
@@ -787,19 +773,21 @@ static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) {
  */
 static void ipoib_leave_broadcast_group ( struct ipoib_device *ipoib ) {
 
-       /* Leave multicast group */
-       ib_mcast_leave ( ipoib->ibdev, ipoib->qp,
-                        &ipoib->broadcast.membership );
+       if ( ipoib->broadcast_joined ) {
+               ib_mcast_leave ( ipoib->ibdev, ipoib->qp,
+                                &ipoib->broadcast_membership );
+               ipoib->broadcast_joined = 0;
+       }
 }
 
 /**
  * Handle link status change
  *
- * @v ipoib            IPoIB device
+ * @v ibdev            Infiniband device
  */
-static void ipoib_link_state_changed ( struct ipoib_device *ipoib ) {
-       struct ib_device *ibdev = ipoib->ibdev;
-       struct net_device *netdev = ipoib->netdev;
+static void ipoib_link_state_changed ( struct ib_device *ibdev ) {
+       struct net_device *netdev = ib_get_ownerdata ( ibdev );
+       struct ipoib_device *ipoib = netdev->priv;
        int rc;
 
        /* Leave existing broadcast group */
@@ -810,17 +798,10 @@ static void ipoib_link_state_changed ( struct ipoib_device *ipoib ) {
        memcpy ( &ipoib->mac.gid.s.prefix, &ibdev->gid.s.prefix,
                 sizeof ( ipoib->mac.gid.s.prefix ) );
 
-       /* Update broadcast MAC GID based on potentially-new partition key */
-       ipoib->broadcast.mac.gid.words[2] =
+       /* Update broadcast GID based on potentially-new partition key */
+       ipoib->broadcast.gid.words[2] =
                htons ( ibdev->pkey | IB_PKEY_FULL );
 
-       /* Construct broadcast address vector from broadcast MAC address */
-       memset ( &ipoib->broadcast.av, 0, sizeof ( ipoib->broadcast.av ) );
-       ipoib->broadcast.av.qpn = IB_QPN_BROADCAST;
-       ipoib->broadcast.av.gid_present = 1;
-       memcpy ( &ipoib->broadcast.av.gid, &ipoib->broadcast.mac.gid,
-                sizeof ( ipoib->broadcast.av.gid ) );
-
        /* Set net device link state to reflect Infiniband link state */
        rc = ib_link_rc ( ibdev );
        netdev_link_err ( netdev, ( rc ? rc : -EINPROGRESS_JOINING ) );
@@ -865,7 +846,7 @@ static int ipoib_open ( struct net_device *netdev ) {
        /* Allocate queue pair */
        ipoib->qp = ib_create_qp ( ibdev, IB_QPT_UD, IPOIB_NUM_SEND_WQES,
                                   ipoib->cq, IPOIB_NUM_RECV_WQES, ipoib->cq,
-                                  &ipoib_qp_op, netdev->name );
+                                  &ipoib_qp_op );
        if ( ! ipoib->qp ) {
                DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
                       ipoib );
@@ -881,7 +862,7 @@ static int ipoib_open ( struct net_device *netdev ) {
        ib_refill_recv ( ibdev, ipoib->qp );
 
        /* Fake a link status change to join the broadcast group */
-       ipoib_link_state_changed ( ipoib );
+       ipoib_link_state_changed ( ibdev );
 
        return 0;
 
@@ -947,6 +928,7 @@ static int ipoib_probe ( struct ib_device *ibdev ) {
                return -ENOMEM;
        netdev_init ( netdev, &ipoib_operations );
        ipoib = netdev->priv;
+       ib_set_ownerdata ( ibdev, netdev );
        netdev->dev = ibdev->dev;
        memset ( ipoib, 0, sizeof ( *ipoib ) );
        ipoib->netdev = netdev;
@@ -956,18 +938,14 @@ static int ipoib_probe ( struct ib_device *ibdev ) {
        /* Extract hardware address */
        memcpy ( netdev->hw_addr, &ibdev->gid.s.guid,
                 sizeof ( ibdev->gid.s.guid ) );
-       memcpy ( netdev->ll_addr, ibdev->lemac, ETH_ALEN );
 
        /* Set local MAC address */
        memcpy ( &ipoib->mac.gid.s.guid, &ibdev->gid.s.guid,
                 sizeof ( ipoib->mac.gid.s.guid ) );
 
        /* Set default broadcast MAC address */
-       memcpy ( &ipoib->broadcast.mac, &ipoib_broadcast,
-                sizeof ( ipoib->broadcast.mac ) );
-
-       /* Add to list of IPoIB devices */
-       list_add_tail ( &ipoib->list, &ipoib_devices );
+       memcpy ( &ipoib->broadcast, &ipoib_broadcast,
+                sizeof ( ipoib->broadcast ) );
 
        /* Register network device */
        if ( ( rc = register_netdev ( netdev ) ) != 0 )
@@ -975,74 +953,29 @@ static int ipoib_probe ( struct ib_device *ibdev ) {
 
        return 0;
 
-       unregister_netdev ( netdev );
  err_register_netdev:
-       list_del ( &ipoib->list );
        netdev_nullify ( netdev );
        netdev_put ( netdev );
        return rc;
 }
 
 /**
- * Handle device or link status change
- *
- * @v ibdev            Infiniband device
- */
-static void ipoib_notify ( struct ib_device *ibdev ) {
-       struct ipoib_device *ipoib;
-
-       /* Handle link status change for any attached IPoIB devices */
-       list_for_each_entry ( ipoib, &ipoib_devices, list ) {
-               if ( ipoib->ibdev != ibdev )
-                       continue;
-               ipoib_link_state_changed ( ipoib );
-       }
-}
-
-/**
  * Remove IPoIB device
  *
  * @v ibdev            Infiniband device
  */
 static void ipoib_remove ( struct ib_device *ibdev ) {
-       struct ipoib_device *ipoib;
-       struct ipoib_device *tmp;
-       struct net_device *netdev;
+       struct net_device *netdev = ib_get_ownerdata ( ibdev );
 
-       /* Remove any attached IPoIB devices */
-       list_for_each_entry_safe ( ipoib, tmp, &ipoib_devices, list ) {
-               if ( ipoib->ibdev != ibdev )
-                       continue;
-               netdev = ipoib->netdev;
-               unregister_netdev ( netdev );
-               list_del ( &ipoib->list );
-               netdev_nullify ( netdev );
-               netdev_put ( netdev );
-       }
+       unregister_netdev ( netdev );
+       netdev_nullify ( netdev );
+       netdev_put ( netdev );
 }
 
 /** IPoIB driver */
 struct ib_driver ipoib_driver __ib_driver = {
        .name = "IPoIB",
        .probe = ipoib_probe,
-       .notify = ipoib_notify,
+       .notify = ipoib_link_state_changed,
        .remove = ipoib_remove,
 };
-
-/**
- * Find IPoIB network device
- *
- * @v ibdev            Infiniband device
- * @ret netdev         IPoIB network device, or NULL if not found
- */
-struct net_device * ipoib_netdev ( struct ib_device *ibdev ) {
-       struct ipoib_device *ipoib;
-
-       /* Find matching IPoIB device */
-       list_for_each_entry ( ipoib, &ipoib_devices, list ) {
-               if ( ipoib->ibdev != ibdev )
-                       continue;
-               return ipoib->netdev;
-       }
-       return NULL;
-}
index 1837291..10728d2 100644 (file)
@@ -186,7 +186,7 @@ static int ncm_in_prefill ( struct ncm_device *ncm ) {
                        count = NCM_IN_MIN_COUNT;
                if ( ( count * mtu ) > NCM_IN_MAX_SIZE )
                        continue;
-               usb_refill_init ( &ncm->usbnet.in, 0, mtu, count );
+               usb_refill_init ( &ncm->usbnet.in, mtu, count );
                if ( ( rc = usb_prefill ( &ncm->usbnet.in ) ) != 0 ) {
                        DBGC ( ncm, "NCM %p could not prefill %dx %zd-byte "
                               "buffers for bulk IN\n", ncm, count, mtu );
@@ -453,15 +453,6 @@ static int ncm_open ( struct net_device *netdev ) {
                goto err_set_ntb_input_size;
        }
 
-       /* Set MAC address */
-       if ( ( rc = usb_control ( usb, NCM_SET_NET_ADDRESS, 0,
-                                 ncm->usbnet.comms, netdev->ll_addr,
-                                 netdev->ll_protocol->ll_addr_len ) ) != 0 ) {
-               DBGC ( ncm, "NCM %p could not set MAC address: %s\n",
-                      ncm, strerror ( rc ) );
-               /* Ignore error and continue */
-       }
-
        /* Open USB network device */
        if ( ( rc = usbnet_open ( &ncm->usbnet ) ) != 0 ) {
                DBGC ( ncm, "NCM %p could not open: %s\n",
@@ -575,7 +566,7 @@ static int ncm_probe ( struct usb_function *func,
        ncm->netdev = netdev;
        usbnet_init ( &ncm->usbnet, func, &ncm_intr_operations,
                      &ncm_in_operations, &ncm_out_operations );
-       usb_refill_init ( &ncm->usbnet.intr, 0, 0, NCM_INTR_COUNT );
+       usb_refill_init ( &ncm->usbnet.intr, 0, NCM_INTR_COUNT );
        DBGC ( ncm, "NCM %p on %s\n", ncm, func->name );
 
        /* Describe USB network device */
@@ -664,6 +655,11 @@ static struct usb_device_id ncm_ids[] = {
                .name = "cdc-ncm",
                .vendor = USB_ANY_ID,
                .product = USB_ANY_ID,
+               .class = {
+                       .class = USB_CLASS_CDC,
+                       .subclass = USB_SUBCLASS_CDC_NCM,
+                       .protocol = 0,
+               },
        },
 };
 
@@ -671,8 +667,6 @@ static struct usb_device_id ncm_ids[] = {
 struct usb_driver ncm_driver __usb_driver = {
        .ids = ncm_ids,
        .id_count = ( sizeof ( ncm_ids ) / sizeof ( ncm_ids[0] ) ),
-       .class = USB_CLASS_ID ( USB_CLASS_CDC, USB_SUBCLASS_CDC_NCM, 0 ),
-       .score = USB_SCORE_NORMAL,
        .probe = ncm_probe,
        .remove = ncm_remove,
 };
index 6b0d21c..a9565a5 100644 (file)
@@ -51,11 +51,6 @@ struct ncm_ntb_parameters {
        uint16_t max;
 } __attribute__ (( packed ));
 
-/** Set MAC address */
-#define NCM_SET_NET_ADDRESS                                            \
-       ( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE |          \
-         USB_REQUEST_TYPE ( 0x82 ) )
-
 /** Set NTB input size */
 #define NCM_SET_NTB_INPUT_SIZE                                         \
        ( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE |          \
index 781049f..38b6674 100644 (file)
@@ -2060,7 +2060,6 @@ static int phantom_probe ( struct pci_device *pci ) {
        struct net_device *netdev;
        struct phantom_nic *phantom;
        struct settings *parent_settings;
-       unsigned int busdevfn;
        int rc;
 
        /* Allocate Phantom device */
@@ -2091,20 +2090,19 @@ static int phantom_probe ( struct pci_device *pci ) {
         * B2 will have this fixed; remove this hack when B1 is no
         * longer in use.
         */
-       busdevfn = pci->busdevfn;
-       if ( PCI_FUNC ( busdevfn ) == 0 ) {
+       if ( PCI_FUNC ( pci->busdevfn ) == 0 ) {
                unsigned int i;
                for ( i = 0 ; i < 8 ; i++ ) {
                        uint32_t temp;
                        pci->busdevfn =
-                               PCI_BUSDEVFN ( PCI_SEG ( busdevfn ),
-                                              PCI_BUS ( busdevfn ),
-                                              PCI_SLOT ( busdevfn ), i );
+                               PCI_BUSDEVFN ( PCI_BUS ( pci->busdevfn ),
+                                              PCI_SLOT ( pci->busdevfn ), i );
                        pci_read_config_dword ( pci, 0xc8, &temp );
                        pci_read_config_dword ( pci, 0xc8, &temp );
                        pci_write_config_dword ( pci, 0xc8, 0xf1000 );
                }
-               pci->busdevfn = busdevfn;
+               pci->busdevfn = PCI_BUSDEVFN ( PCI_BUS ( pci->busdevfn ),
+                                              PCI_SLOT ( pci->busdevfn ), 0 );
        }
 
        /* Initialise the command PEG */
index 81f3d98..991c30f 100644 (file)
@@ -72,6 +72,12 @@ struct pci_driver sis190_isa_bridge_driver __pci_driver = {
 static const u32 sis190_intr_mask =
        RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt | LinkChange;
 
+/*
+ * Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
+ * The chips use a 64 element hash table based on the Ethernet CRC.
+ */
+static const int multicast_filter_limit = 32;
+
 static void __mdio_cmd(void *ioaddr, u32 ctl)
 {
        unsigned int i;
index 79f94d2..0551333 100644 (file)
@@ -297,6 +297,13 @@ static struct mii_chip_info {
        { NULL, { 0x00, 0x00 }, 0, 0 }
 };
 
+static const struct {
+       const char *name;
+} sis_chip_info[] = {
+       { "SiS 190 PCI Fast Ethernet adapter" },
+       { "SiS 191 PCI Gigabit Ethernet adapter" },
+};
+
 static void sis190_phy_task(struct sis190_private *tp);
 static void sis190_free(struct net_device *dev);
 static inline void sis190_init_rxfilter(struct net_device *dev);
index c326422..6384e76 100755 (executable)
@@ -84,6 +84,9 @@ static struct net_device_operations skge_operations = {
 /* Avoid conditionals by using array */
 static const int txqaddr[] = { Q_XA1, Q_XA2 };
 static const int rxqaddr[] = { Q_R1, Q_R2 };
+static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F };
+static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F };
+static const u32 napimask[] = { IS_R1_F|IS_XA1_F, IS_R2_F|IS_XA2_F };
 static const u32 portmask[] = { IS_PORT_1, IS_PORT_2 };
 
 /* Determine supported/advertised modes based on hardware.
@@ -1919,6 +1922,8 @@ static void skge_tx_clean(struct net_device *dev)
        skge->tx_ring.to_clean = e;
 }
 
+static const u8 pause_mc_addr[ETH_ALEN] = { 0x1, 0x80, 0xc2, 0x0, 0x0, 0x1 };
+
 static inline u16 phy_length(const struct skge_hw *hw, u32 status)
 {
        if (hw->chip_id == CHIP_ID_GENESIS)
index 4ce98ac..017e02a 100644 (file)
@@ -511,7 +511,6 @@ static int smsc75xx_dump_statistics ( struct smsc75xx_device *smsc75xx ) {
  */
 static int smsc75xx_reset ( struct smsc75xx_device *smsc75xx ) {
        uint32_t hw_cfg;
-       unsigned int i;
        int rc;
 
        /* Reset device */
@@ -520,22 +519,18 @@ static int smsc75xx_reset ( struct smsc75xx_device *smsc75xx ) {
                return rc;
 
        /* Wait for reset to complete */
-       for ( i = 0 ; i < SMSC75XX_RESET_MAX_WAIT_MS ; i++ ) {
+       udelay ( SMSC75XX_RESET_DELAY_US );
 
-               /* Check if reset has completed */
-               if ( ( rc = smsc75xx_readl ( smsc75xx, SMSC75XX_HW_CFG,
-                                            &hw_cfg ) ) != 0 )
-                       return rc;
-               if ( ! ( hw_cfg & SMSC75XX_HW_CFG_LRST ) )
-                       return 0;
-
-               /* Delay */
-               mdelay ( 1 );
+       /* Check that reset has completed */
+       if ( ( rc = smsc75xx_readl ( smsc75xx, SMSC75XX_HW_CFG,
+                                    &hw_cfg ) ) != 0 )
+               return rc;
+       if ( hw_cfg & SMSC75XX_HW_CFG_LRST ) {
+               DBGC ( smsc75xx, "SMSC75XX %p failed to reset\n", smsc75xx );
+               return -ETIMEDOUT;
        }
 
-       DBGC ( smsc75xx, "SMSC75XX %p timed out waiting for reset\n",
-              smsc75xx );
-       return -ETIMEDOUT;
+       return 0;
 }
 
 /******************************************************************************
@@ -984,9 +979,8 @@ static int smsc75xx_probe ( struct usb_function *func,
        smsc75xx->netdev = netdev;
        usbnet_init ( &smsc75xx->usbnet, func, &smsc75xx_intr_operations,
                      &smsc75xx_in_operations, &smsc75xx_out_operations );
-       usb_refill_init ( &smsc75xx->usbnet.intr, 0, 0,
-                         SMSC75XX_INTR_MAX_FILL );
-       usb_refill_init ( &smsc75xx->usbnet.in, 0, SMSC75XX_IN_MTU,
+       usb_refill_init ( &smsc75xx->usbnet.intr, 0, SMSC75XX_INTR_MAX_FILL );
+       usb_refill_init ( &smsc75xx->usbnet.in, SMSC75XX_IN_MTU,
                          SMSC75XX_IN_MAX_FILL );
        mii_init ( &smsc75xx->mii, &smsc75xx_mii_operations );
        DBGC ( smsc75xx, "SMSC75XX %p on %s\n", smsc75xx, func->name );
@@ -1044,11 +1038,13 @@ static struct usb_device_id smsc75xx_ids[] = {
                .name = "smsc7500",
                .vendor = 0x0424,
                .product = 0x7500,
+               .class = { 0xff, 0x00, 0xff },
        },
        {
                .name = "smsc7505",
                .vendor = 0x0424,
                .product = 0x7505,
+               .class = { 0xff, 0x00, 0xff },
        },
 };
 
@@ -1056,8 +1052,6 @@ static struct usb_device_id smsc75xx_ids[] = {
 struct usb_driver smsc75xx_driver __usb_driver = {
        .ids = smsc75xx_ids,
        .id_count = ( sizeof ( smsc75xx_ids ) / sizeof ( smsc75xx_ids[0] ) ),
-       .class = USB_CLASS_ID ( 0xff, 0x00, 0xff ),
-       .score = USB_SCORE_NORMAL,
        .probe = smsc75xx_probe,
        .remove = smsc75xx_remove,
 };
index ae81fc1..2463b72 100644 (file)
@@ -280,8 +280,8 @@ struct smsc75xx_device {
        uint32_t int_sts;
 };
 
-/** Maximum time to wait for reset (in milliseconds) */
-#define SMSC75XX_RESET_MAX_WAIT_MS 100
+/** Reset delay (in microseconds) */
+#define SMSC75XX_RESET_DELAY_US 2
 
 /** Maximum time to wait for EEPROM (in milliseconds) */
 #define SMSC75XX_EEPROM_MAX_WAIT_MS 100
diff --git a/roms/ipxe/src/drivers/net/smsc95xx.c b/roms/ipxe/src/drivers/net/smsc95xx.c
deleted file mode 100644 (file)
index 3d9c0f1..0000000
+++ /dev/null
@@ -1,1300 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <byteswap.h>
-#include <ipxe/ethernet.h>
-#include <ipxe/usb.h>
-#include <ipxe/usbnet.h>
-#include <ipxe/profile.h>
-#include <ipxe/base16.h>
-#include <ipxe/smbios.h>
-#include "smsc95xx.h"
-
-/** @file
- *
- * SMSC LAN95xx USB Ethernet driver
- *
- */
-
-/** Interrupt completion profiler */
-static struct profiler smsc95xx_intr_profiler __profiler =
-       { .name = "smsc95xx.intr" };
-
-/** Bulk IN completion profiler */
-static struct profiler smsc95xx_in_profiler __profiler =
-       { .name = "smsc95xx.in" };
-
-/** Bulk OUT profiler */
-static struct profiler smsc95xx_out_profiler __profiler =
-       { .name = "smsc95xx.out" };
-
-/******************************************************************************
- *
- * Register access
- *
- ******************************************************************************
- */
-
-/**
- * Write register (without byte-swapping)
- *
- * @v smsc95xx         SMSC95xx device
- * @v address          Register address
- * @v value            Register value
- * @ret rc             Return status code
- */
-static int smsc95xx_raw_writel ( struct smsc95xx_device *smsc95xx,
-                                unsigned int address, uint32_t value ) {
-       int rc;
-
-       /* Write register */
-       DBGCIO ( smsc95xx, "SMSC95XX %p [%03x] <= %08x\n",
-                smsc95xx, address, le32_to_cpu ( value ) );
-       if ( ( rc = usb_control ( smsc95xx->usb, SMSC95XX_REGISTER_WRITE, 0,
-                                 address, &value, sizeof ( value ) ) ) != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p could not write %03x: %s\n",
-                      smsc95xx, address, strerror ( rc ) );
-               return rc;
-       }
-
-       return 0;
-}
-
-/**
- * Write register
- *
- * @v smsc95xx         SMSC95xx device
- * @v address          Register address
- * @v value            Register value
- * @ret rc             Return status code
- */
-static inline __attribute__ (( always_inline )) int
-smsc95xx_writel ( struct smsc95xx_device *smsc95xx, unsigned int address,
-                 uint32_t value ) {
-       int rc;
-
-       /* Write register */
-       if ( ( rc = smsc95xx_raw_writel ( smsc95xx, address,
-                                         cpu_to_le32 ( value ) ) ) != 0 )
-               return rc;
-
-       return 0;
-}
-
-/**
- * Read register (without byte-swapping)
- *
- * @v smsc95xx         SMSC95xx device
- * @v address          Register address
- * @ret value          Register value
- * @ret rc             Return status code
- */
-static int smsc95xx_raw_readl ( struct smsc95xx_device *smsc95xx,
-                               unsigned int address, uint32_t *value ) {
-       int rc;
-
-       /* Read register */
-       if ( ( rc = usb_control ( smsc95xx->usb, SMSC95XX_REGISTER_READ, 0,
-                                 address, value, sizeof ( *value ) ) ) != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p could not read %03x: %s\n",
-                      smsc95xx, address, strerror ( rc ) );
-               return rc;
-       }
-       DBGCIO ( smsc95xx, "SMSC95XX %p [%03x] => %08x\n",
-                smsc95xx, address, le32_to_cpu ( *value ) );
-
-       return 0;
-}
-
-/**
- * Read register
- *
- * @v smsc95xx         SMSC95xx device
- * @v address          Register address
- * @ret value          Register value
- * @ret rc             Return status code
- */
-static inline __attribute__ (( always_inline )) int
-smsc95xx_readl ( struct smsc95xx_device *smsc95xx, unsigned int address,
-                uint32_t *value ) {
-       int rc;
-
-       /* Read register */
-       if ( ( rc = smsc95xx_raw_readl ( smsc95xx, address, value ) ) != 0 )
-               return rc;
-       le32_to_cpus ( value );
-
-       return 0;
-}
-
-/******************************************************************************
- *
- * EEPROM access
- *
- ******************************************************************************
- */
-
-/**
- * Wait for EEPROM to become idle
- *
- * @v smsc95xx         SMSC95xx device
- * @ret rc             Return status code
- */
-static int smsc95xx_eeprom_wait ( struct smsc95xx_device *smsc95xx ) {
-       uint32_t e2p_cmd;
-       unsigned int i;
-       int rc;
-
-       /* Wait for EPC_BSY to become clear */
-       for ( i = 0 ; i < SMSC95XX_EEPROM_MAX_WAIT_MS ; i++ ) {
-
-               /* Read E2P_CMD and check EPC_BSY */
-               if ( ( rc = smsc95xx_readl ( smsc95xx, SMSC95XX_E2P_CMD,
-                                            &e2p_cmd ) ) != 0 )
-                       return rc;
-               if ( ! ( e2p_cmd & SMSC95XX_E2P_CMD_EPC_BSY ) )
-                       return 0;
-
-               /* Delay */
-               mdelay ( 1 );
-       }
-
-       DBGC ( smsc95xx, "SMSC95XX %p timed out waiting for EEPROM\n",
-              smsc95xx );
-       return -ETIMEDOUT;
-}
-
-/**
- * Read byte from EEPROM
- *
- * @v smsc95xx         SMSC95xx device
- * @v address          EEPROM address
- * @ret byte           Byte read, or negative error
- */
-static int smsc95xx_eeprom_read_byte ( struct smsc95xx_device *smsc95xx,
-                                      unsigned int address ) {
-       uint32_t e2p_cmd;
-       uint32_t e2p_data;
-       int rc;
-
-       /* Wait for EEPROM to become idle */
-       if ( ( rc = smsc95xx_eeprom_wait ( smsc95xx ) ) != 0 )
-               return rc;
-
-       /* Initiate read command */
-       e2p_cmd = ( SMSC95XX_E2P_CMD_EPC_BSY | SMSC95XX_E2P_CMD_EPC_CMD_READ |
-                   SMSC95XX_E2P_CMD_EPC_ADDR ( address ) );
-       if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_E2P_CMD,
-                                     e2p_cmd ) ) != 0 )
-               return rc;
-
-       /* Wait for command to complete */
-       if ( ( rc = smsc95xx_eeprom_wait ( smsc95xx ) ) != 0 )
-               return rc;
-
-       /* Read EEPROM data */
-       if ( ( rc = smsc95xx_readl ( smsc95xx, SMSC95XX_E2P_DATA,
-                                    &e2p_data ) ) != 0 )
-               return rc;
-
-       return SMSC95XX_E2P_DATA_GET ( e2p_data );
-}
-
-/**
- * Read data from EEPROM
- *
- * @v smsc95xx         SMSC95xx device
- * @v address          EEPROM address
- * @v data             Data buffer
- * @v len              Length of data
- * @ret rc             Return status code
- */
-static int smsc95xx_eeprom_read ( struct smsc95xx_device *smsc95xx,
-                                 unsigned int address, void *data,
-                                 size_t len ) {
-       uint8_t *bytes;
-       int byte;
-
-       /* Read bytes */
-       for ( bytes = data ; len-- ; address++, bytes++ ) {
-               byte = smsc95xx_eeprom_read_byte ( smsc95xx, address );
-               if ( byte < 0 )
-                       return byte;
-               *bytes = byte;
-       }
-
-       return 0;
-}
-
-/******************************************************************************
- *
- * MAC address
- *
- ******************************************************************************
- */
-
-/**
- * Fetch MAC address from EEPROM
- *
- * @v smsc95xx         SMSC95xx device
- * @v hw_addr          Hardware address to fill in
- * @ret rc             Return status code
- */
-static int smsc95xx_fetch_mac_eeprom ( struct smsc95xx_device *smsc95xx,
-                                      uint8_t *hw_addr ) {
-       int rc;
-
-       /* Read MAC address from EEPROM */
-       if ( ( rc = smsc95xx_eeprom_read ( smsc95xx, SMSC95XX_EEPROM_MAC,
-                                          hw_addr, ETH_ALEN ) ) != 0 )
-               return rc;
-
-       /* Check that EEPROM is physically present */
-       if ( ! is_valid_ether_addr ( hw_addr ) ) {
-               DBGC ( smsc95xx, "SMSC95XX %p has no EEPROM (%s)\n",
-                      smsc95xx, eth_ntoa ( hw_addr ) );
-               return -ENODEV;
-       }
-
-       DBGC ( smsc95xx, "SMSC95XX %p using EEPROM MAC %s\n",
-              smsc95xx, eth_ntoa ( hw_addr ) );
-       return 0;
-}
-
-/**
- * Construct MAC address for Honeywell VM3
- *
- * @v smsc95xx         SMSC95xx device
- * @v hw_addr          Hardware address to fill in
- * @ret rc             Return status code
- */
-static int smsc95xx_fetch_mac_vm3 ( struct smsc95xx_device *smsc95xx,
-                                   uint8_t *hw_addr ) {
-       struct smbios_structure structure;
-       struct smbios_system_information system;
-       struct {
-               char manufacturer[ 10 /* "Honeywell" + NUL */ ];
-               char product[ 4 /* "VM3" + NUL */ ];
-               char mac[ base16_encoded_len ( ETH_ALEN ) + 1 /* NUL */ ];
-       } strings;
-       int len;
-       int rc;
-
-       /* Find system information */
-       if ( ( rc = find_smbios_structure ( SMBIOS_TYPE_SYSTEM_INFORMATION, 0,
-                                           &structure ) ) != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p could not find system "
-                      "information: %s\n", smsc95xx, strerror ( rc ) );
-               return rc;
-       }
-
-       /* Read system information */
-       if ( ( rc = read_smbios_structure ( &structure, &system,
-                                           sizeof ( system ) ) ) != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p could not read system "
-                      "information: %s\n", smsc95xx, strerror ( rc ) );
-               return rc;
-       }
-
-       /* NUL-terminate all strings to be fetched */
-       memset ( &strings, 0, sizeof ( strings ) );
-
-       /* Fetch system manufacturer name */
-       len = read_smbios_string ( &structure, system.manufacturer,
-                                  strings.manufacturer,
-                                  ( sizeof ( strings.manufacturer ) - 1 ) );
-       if ( len < 0 ) {
-               rc = len;
-               DBGC ( smsc95xx, "SMSC95XX %p could not read manufacturer "
-                      "name: %s\n", smsc95xx, strerror ( rc ) );
-               return rc;
-       }
-
-       /* Fetch system product name */
-       len = read_smbios_string ( &structure, system.product, strings.product,
-                                  ( sizeof ( strings.product ) - 1 ) );
-       if ( len < 0 ) {
-               rc = len;
-               DBGC ( smsc95xx, "SMSC95XX %p could not read product name: "
-                      "%s\n", smsc95xx, strerror ( rc ) );
-               return rc;
-       }
-
-       /* Ignore non-VM3 devices */
-       if ( ( strcmp ( strings.manufacturer, "Honeywell" ) != 0 ) ||
-            ( strcmp ( strings.product, "VM3" ) != 0 ) )
-               return -ENOTTY;
-
-       /* Find OEM strings */
-       if ( ( rc = find_smbios_structure ( SMBIOS_TYPE_OEM_STRINGS, 0,
-                                           &structure ) ) != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p could not find OEM strings: %s\n",
-                      smsc95xx, strerror ( rc ) );
-               return rc;
-       }
-
-       /* Fetch MAC address */
-       len = read_smbios_string ( &structure, SMSC95XX_VM3_OEM_STRING_MAC,
-                                  strings.mac, ( sizeof ( strings.mac ) - 1 ));
-       if ( len < 0 ) {
-               rc = len;
-               DBGC ( smsc95xx, "SMSC95XX %p could not read OEM string: %s\n",
-                      smsc95xx, strerror ( rc ) );
-               return rc;
-       }
-
-       /* Sanity check */
-       if ( len != ( ( int ) ( sizeof ( strings.mac ) - 1 ) ) ) {
-               DBGC ( smsc95xx, "SMSC95XX %p invalid MAC address \"%s\"\n",
-                      smsc95xx, strings.mac );
-               return -EINVAL;
-       }
-
-       /* Decode MAC address */
-       len = base16_decode ( strings.mac, hw_addr, ETH_ALEN );
-       if ( len < 0 ) {
-               rc = len;
-               DBGC ( smsc95xx, "SMSC95XX %p invalid MAC address \"%s\"\n",
-                      smsc95xx, strings.mac );
-               return rc;
-       }
-
-       DBGC ( smsc95xx, "SMSC95XX %p using VM3 MAC %s\n",
-              smsc95xx, eth_ntoa ( hw_addr ) );
-       return 0;
-}
-
-/**
- * Fetch MAC address
- *
- * @v smsc95xx         SMSC95xx device
- * @v hw_addr          Hardware address to fill in
- * @ret rc             Return status code
- */
-static int smsc95xx_fetch_mac ( struct smsc95xx_device *smsc95xx,
-                               uint8_t *hw_addr ) {
-       int rc;
-
-       /* Read MAC address from EEPROM, if present */
-       if ( ( rc = smsc95xx_fetch_mac_eeprom ( smsc95xx, hw_addr ) ) == 0 )
-               return 0;
-
-       /* Construct MAC address for Honeywell VM3, if applicable */
-       if ( ( rc = smsc95xx_fetch_mac_vm3 ( smsc95xx, hw_addr ) ) == 0 )
-               return 0;
-
-       /* Otherwise, generate a random MAC address */
-       eth_random_addr ( hw_addr );
-       DBGC ( smsc95xx, "SMSC95XX %p using random MAC %s\n",
-              smsc95xx, eth_ntoa ( hw_addr ) );
-       return 0;
-}
-
-/******************************************************************************
- *
- * MII access
- *
- ******************************************************************************
- */
-
-/**
- * Wait for MII to become idle
- *
- * @v smsc95xx         SMSC95xx device
- * @ret rc             Return status code
- */
-static int smsc95xx_mii_wait ( struct smsc95xx_device *smsc95xx ) {
-       uint32_t mii_access;
-       unsigned int i;
-       int rc;
-
-       /* Wait for MIIBZY to become clear */
-       for ( i = 0 ; i < SMSC95XX_MII_MAX_WAIT_MS ; i++ ) {
-
-               /* Read MII_ACCESS and check MIIBZY */
-               if ( ( rc = smsc95xx_readl ( smsc95xx, SMSC95XX_MII_ACCESS,
-                                            &mii_access ) ) != 0 )
-                       return rc;
-               if ( ! ( mii_access & SMSC95XX_MII_ACCESS_MIIBZY ) )
-                       return 0;
-
-               /* Delay */
-               mdelay ( 1 );
-       }
-
-       DBGC ( smsc95xx, "SMSC95XX %p timed out waiting for MII\n",
-              smsc95xx );
-       return -ETIMEDOUT;
-}
-
-/**
- * Read from MII register
- *
- * @v mii              MII interface
- * @v reg              Register address
- * @ret value          Data read, or negative error
- */
-static int smsc95xx_mii_read ( struct mii_interface *mii, unsigned int reg ) {
-       struct smsc95xx_device *smsc95xx =
-               container_of ( mii, struct smsc95xx_device, mii );
-       uint32_t mii_access;
-       uint32_t mii_data;
-       int rc;
-
-       /* Wait for MII to become idle */
-       if ( ( rc = smsc95xx_mii_wait ( smsc95xx ) ) != 0 )
-               return rc;
-
-       /* Initiate read command */
-       mii_access = ( SMSC95XX_MII_ACCESS_PHY_ADDRESS |
-                      SMSC95XX_MII_ACCESS_MIIRINDA ( reg ) |
-                      SMSC95XX_MII_ACCESS_MIIBZY );
-       if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_MII_ACCESS,
-                                     mii_access ) ) != 0 )
-               return rc;
-
-       /* Wait for command to complete */
-       if ( ( rc = smsc95xx_mii_wait ( smsc95xx ) ) != 0 )
-               return rc;
-
-       /* Read MII data */
-       if ( ( rc = smsc95xx_readl ( smsc95xx, SMSC95XX_MII_DATA,
-                                    &mii_data ) ) != 0 )
-               return rc;
-
-       return SMSC95XX_MII_DATA_GET ( mii_data );
-}
-
-/**
- * Write to MII register
- *
- * @v mii              MII interface
- * @v reg              Register address
- * @v data             Data to write
- * @ret rc             Return status code
- */
-static int smsc95xx_mii_write ( struct mii_interface *mii, unsigned int reg,
-                               unsigned int data ) {
-       struct smsc95xx_device *smsc95xx =
-               container_of ( mii, struct smsc95xx_device, mii );
-       uint32_t mii_access;
-       uint32_t mii_data;
-       int rc;
-
-       /* Wait for MII to become idle */
-       if ( ( rc = smsc95xx_mii_wait ( smsc95xx ) ) != 0 )
-               return rc;
-
-       /* Write MII data */
-       mii_data = SMSC95XX_MII_DATA_SET ( data );
-       if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_MII_DATA,
-                                     mii_data ) ) != 0 )
-               return rc;
-
-       /* Initiate write command */
-       mii_access = ( SMSC95XX_MII_ACCESS_PHY_ADDRESS |
-                      SMSC95XX_MII_ACCESS_MIIRINDA ( reg ) |
-                      SMSC95XX_MII_ACCESS_MIIWNR |
-                      SMSC95XX_MII_ACCESS_MIIBZY );
-       if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_MII_ACCESS,
-                                     mii_access ) ) != 0 )
-               return rc;
-
-       /* Wait for command to complete */
-       if ( ( rc = smsc95xx_mii_wait ( smsc95xx ) ) != 0 )
-               return rc;
-
-       return 0;
-}
-
-/** MII operations */
-static struct mii_operations smsc95xx_mii_operations = {
-       .read = smsc95xx_mii_read,
-       .write = smsc95xx_mii_write,
-};
-
-/**
- * Check link status
- *
- * @v smsc95xx         SMSC95xx device
- * @ret rc             Return status code
- */
-static int smsc95xx_check_link ( struct smsc95xx_device *smsc95xx ) {
-       struct net_device *netdev = smsc95xx->netdev;
-       int intr;
-       int rc;
-
-       /* Read PHY interrupt source */
-       intr = mii_read ( &smsc95xx->mii, SMSC95XX_MII_PHY_INTR_SOURCE );
-       if ( intr < 0 ) {
-               rc = intr;
-               DBGC ( smsc95xx, "SMSC95XX %p could not get PHY interrupt "
-                      "source: %s\n", smsc95xx, strerror ( rc ) );
-               return rc;
-       }
-
-       /* Acknowledge PHY interrupt */
-       if ( ( rc = mii_write ( &smsc95xx->mii, SMSC95XX_MII_PHY_INTR_SOURCE,
-                               intr ) ) != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p could not acknowledge PHY "
-                      "interrupt: %s\n", smsc95xx, strerror ( rc ) );
-               return rc;
-       }
-
-       /* Check link status */
-       if ( ( rc = mii_check_link ( &smsc95xx->mii, netdev ) ) != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p could not check link: %s\n",
-                      smsc95xx, strerror ( rc ) );
-               return rc;
-       }
-
-       DBGC ( smsc95xx, "SMSC95XX %p link %s (intr %#04x)\n",
-              smsc95xx, ( netdev_link_ok ( netdev ) ? "up" : "down" ), intr );
-       return 0;
-}
-
-/******************************************************************************
- *
- * Statistics (for debugging)
- *
- ******************************************************************************
- */
-
-/**
- * Get RX statistics
- *
- * @v smsc95xx         SMSC95xx device
- * @v stats            Statistics to fill in
- * @ret rc             Return status code
- */
-static int smsc95xx_get_rx_statistics ( struct smsc95xx_device *smsc95xx,
-                                       struct smsc95xx_rx_statistics *stats ) {
-       int rc;
-
-       /* Get statistics */
-       if ( ( rc = usb_control ( smsc95xx->usb, SMSC95XX_GET_STATISTICS, 0,
-                                 SMSC95XX_RX_STATISTICS, stats,
-                                 sizeof ( *stats ) ) ) != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p could not get RX statistics: "
-                      "%s\n", smsc95xx, strerror ( rc ) );
-               return rc;
-       }
-
-       return 0;
-}
-
-/**
- * Get TX statistics
- *
- * @v smsc95xx         SMSC95xx device
- * @v stats            Statistics to fill in
- * @ret rc             Return status code
- */
-static int smsc95xx_get_tx_statistics ( struct smsc95xx_device *smsc95xx,
-                                       struct smsc95xx_tx_statistics *stats ) {
-       int rc;
-
-       /* Get statistics */
-       if ( ( rc = usb_control ( smsc95xx->usb, SMSC95XX_GET_STATISTICS, 0,
-                                 SMSC95XX_TX_STATISTICS, stats,
-                                 sizeof ( *stats ) ) ) != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p could not get TX statistics: "
-                      "%s\n", smsc95xx, strerror ( rc ) );
-               return rc;
-       }
-
-       return 0;
-}
-
-/**
- * Dump statistics (for debugging)
- *
- * @v smsc95xx         SMSC95xx device
- * @ret rc             Return status code
- */
-static int smsc95xx_dump_statistics ( struct smsc95xx_device *smsc95xx ) {
-       struct smsc95xx_rx_statistics rx;
-       struct smsc95xx_tx_statistics tx;
-       int rc;
-
-       /* Do nothing unless debugging is enabled */
-       if ( ! DBG_LOG )
-               return 0;
-
-       /* Get RX statistics */
-       if ( ( rc = smsc95xx_get_rx_statistics ( smsc95xx, &rx ) ) != 0 )
-               return rc;
-
-       /* Get TX statistics */
-       if ( ( rc = smsc95xx_get_tx_statistics ( smsc95xx, &tx ) ) != 0 )
-               return rc;
-
-       /* Dump statistics */
-       DBGC ( smsc95xx, "SMSC95XX %p RX good %d bad %d crc %d und %d aln %d "
-              "ovr %d lat %d drp %d\n", smsc95xx, le32_to_cpu ( rx.good ),
-              le32_to_cpu ( rx.bad ), le32_to_cpu ( rx.crc ),
-              le32_to_cpu ( rx.undersize ), le32_to_cpu ( rx.alignment ),
-              le32_to_cpu ( rx.oversize ), le32_to_cpu ( rx.late ),
-              le32_to_cpu ( rx.dropped ) );
-       DBGC ( smsc95xx, "SMSC95XX %p TX good %d bad %d pau %d sgl %d mul %d "
-              "exc %d lat %d und %d def %d car %d\n", smsc95xx,
-              le32_to_cpu ( tx.good ), le32_to_cpu ( tx.bad ),
-              le32_to_cpu ( tx.pause ), le32_to_cpu ( tx.single ),
-              le32_to_cpu ( tx.multiple ), le32_to_cpu ( tx.excessive ),
-              le32_to_cpu ( tx.late ), le32_to_cpu ( tx.underrun ),
-              le32_to_cpu ( tx.deferred ), le32_to_cpu ( tx.carrier ) );
-
-       return 0;
-}
-
-/******************************************************************************
- *
- * Device reset
- *
- ******************************************************************************
- */
-
-/**
- * Reset device
- *
- * @v smsc95xx         SMSC95xx device
- * @ret rc             Return status code
- */
-static int smsc95xx_reset ( struct smsc95xx_device *smsc95xx ) {
-       uint32_t hw_cfg;
-       uint32_t led_gpio_cfg;
-       int rc;
-
-       /* Reset device */
-       if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_HW_CFG,
-                                     SMSC95XX_HW_CFG_LRST ) ) != 0 )
-               return rc;
-
-       /* Wait for reset to complete */
-       udelay ( SMSC95XX_RESET_DELAY_US );
-
-       /* Check that reset has completed */
-       if ( ( rc = smsc95xx_readl ( smsc95xx, SMSC95XX_HW_CFG,
-                                    &hw_cfg ) ) != 0 )
-               return rc;
-       if ( hw_cfg & SMSC95XX_HW_CFG_LRST ) {
-               DBGC ( smsc95xx, "SMSC95XX %p failed to reset\n", smsc95xx );
-               return -ETIMEDOUT;
-       }
-
-       /* Configure LEDs */
-       led_gpio_cfg = ( SMSC95XX_LED_GPIO_CFG_GPCTL2_NSPD_LED |
-                        SMSC95XX_LED_GPIO_CFG_GPCTL1_NLNKA_LED |
-                        SMSC95XX_LED_GPIO_CFG_GPCTL0_NFDX_LED );
-       if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_LED_GPIO_CFG,
-                                     led_gpio_cfg ) ) != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p could not configure LEDs: %s\n",
-                      smsc95xx, strerror ( rc ) );
-               /* Ignore error and continue */
-       }
-
-       return 0;
-}
-
-/******************************************************************************
- *
- * Endpoint operations
- *
- ******************************************************************************
- */
-
-/**
- * Complete interrupt transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void smsc95xx_intr_complete ( struct usb_endpoint *ep,
-                                    struct io_buffer *iobuf, int rc ) {
-       struct smsc95xx_device *smsc95xx =
-               container_of ( ep, struct smsc95xx_device, usbnet.intr );
-       struct net_device *netdev = smsc95xx->netdev;
-       struct smsc95xx_interrupt *intr;
-
-       /* Profile completions */
-       profile_start ( &smsc95xx_intr_profiler );
-
-       /* Ignore packets cancelled when the endpoint closes */
-       if ( ! ep->open )
-               goto done;
-
-       /* Record USB errors against the network device */
-       if ( rc != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p interrupt failed: %s\n",
-                      smsc95xx, strerror ( rc ) );
-               DBGC_HDA ( smsc95xx, 0, iobuf->data, iob_len ( iobuf ) );
-               netdev_rx_err ( netdev, NULL, rc );
-               goto done;
-       }
-
-       /* Extract interrupt data */
-       if ( iob_len ( iobuf ) != sizeof ( *intr ) ) {
-               DBGC ( smsc95xx, "SMSC95XX %p malformed interrupt\n",
-                      smsc95xx );
-               DBGC_HDA ( smsc95xx, 0, iobuf->data, iob_len ( iobuf ) );
-               netdev_rx_err ( netdev, NULL, rc );
-               goto done;
-       }
-       intr = iobuf->data;
-
-       /* Record interrupt status */
-       smsc95xx->int_sts = le32_to_cpu ( intr->int_sts );
-       profile_stop ( &smsc95xx_intr_profiler );
-
- done:
-       /* Free I/O buffer */
-       free_iob ( iobuf );
-}
-
-/** Interrupt endpoint operations */
-static struct usb_endpoint_driver_operations smsc95xx_intr_operations = {
-       .complete = smsc95xx_intr_complete,
-};
-
-/**
- * Complete bulk IN transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void smsc95xx_in_complete ( struct usb_endpoint *ep,
-                                  struct io_buffer *iobuf, int rc ) {
-       struct smsc95xx_device *smsc95xx =
-               container_of ( ep, struct smsc95xx_device, usbnet.in );
-       struct net_device *netdev = smsc95xx->netdev;
-       struct smsc95xx_rx_header *header;
-
-       /* Profile completions */
-       profile_start ( &smsc95xx_in_profiler );
-
-       /* Ignore packets cancelled when the endpoint closes */
-       if ( ! ep->open ) {
-               free_iob ( iobuf );
-               return;
-       }
-
-       /* Record USB errors against the network device */
-       if ( rc != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p bulk IN failed: %s\n",
-                      smsc95xx, strerror ( rc ) );
-               goto err;
-       }
-
-       /* Sanity check */
-       if ( iob_len ( iobuf ) < ( sizeof ( *header ) + 4 /* CRC */ ) ) {
-               DBGC ( smsc95xx, "SMSC95XX %p underlength bulk IN\n",
-                      smsc95xx );
-               DBGC_HDA ( smsc95xx, 0, iobuf->data, iob_len ( iobuf ) );
-               rc = -EINVAL;
-               goto err;
-       }
-
-       /* Strip header and CRC */
-       header = iobuf->data;
-       iob_pull ( iobuf, sizeof ( *header ) );
-       iob_unput ( iobuf, 4 /* CRC */ );
-
-       /* Check for errors */
-       if ( header->command & cpu_to_le32 ( SMSC95XX_RX_RUNT |
-                                            SMSC95XX_RX_LATE |
-                                            SMSC95XX_RX_CRC ) ) {
-               DBGC ( smsc95xx, "SMSC95XX %p receive error (%08x):\n",
-                      smsc95xx, le32_to_cpu ( header->command ) );
-               DBGC_HDA ( smsc95xx, 0, iobuf->data, iob_len ( iobuf ) );
-               rc = -EIO;
-               goto err;
-       }
-
-       /* Hand off to network stack */
-       netdev_rx ( netdev, iob_disown ( iobuf ) );
-
-       profile_stop ( &smsc95xx_in_profiler );
-       return;
-
- err:
-       /* Hand off to network stack */
-       netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
-}
-
-/** Bulk IN endpoint operations */
-static struct usb_endpoint_driver_operations smsc95xx_in_operations = {
-       .complete = smsc95xx_in_complete,
-};
-
-/**
- * Transmit packet
- *
- * @v smsc95xx         SMSC95xx device
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int smsc95xx_out_transmit ( struct smsc95xx_device *smsc95xx,
-                                  struct io_buffer *iobuf ) {
-       struct smsc95xx_tx_header *header;
-       size_t len = iob_len ( iobuf );
-       int rc;
-
-       /* Profile transmissions */
-       profile_start ( &smsc95xx_out_profiler );
-
-       /* Prepend header */
-       if ( ( rc = iob_ensure_headroom ( iobuf, sizeof ( *header ) ) ) != 0 )
-               return rc;
-       header = iob_push ( iobuf, sizeof ( *header ) );
-       header->command = cpu_to_le32 ( SMSC95XX_TX_FIRST | SMSC95XX_TX_LAST |
-                                       SMSC95XX_TX_LEN ( len ) );
-       header->len = cpu_to_le32 ( len );
-
-       /* Enqueue I/O buffer */
-       if ( ( rc = usb_stream ( &smsc95xx->usbnet.out, iobuf, 0 ) ) != 0 )
-               return rc;
-
-       profile_stop ( &smsc95xx_out_profiler );
-       return 0;
-}
-
-/**
- * Complete bulk OUT transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void smsc95xx_out_complete ( struct usb_endpoint *ep,
-                                   struct io_buffer *iobuf, int rc ) {
-       struct smsc95xx_device *smsc95xx =
-               container_of ( ep, struct smsc95xx_device, usbnet.out );
-       struct net_device *netdev = smsc95xx->netdev;
-
-       /* Report TX completion */
-       netdev_tx_complete_err ( netdev, iobuf, rc );
-}
-
-/** Bulk OUT endpoint operations */
-static struct usb_endpoint_driver_operations smsc95xx_out_operations = {
-       .complete = smsc95xx_out_complete,
-};
-
-/******************************************************************************
- *
- * Network device interface
- *
- ******************************************************************************
- */
-
-/**
- * Open network device
- *
- * @v netdev           Network device
- * @ret rc             Return status code
- */
-static int smsc95xx_open ( struct net_device *netdev ) {
-       struct smsc95xx_device *smsc95xx = netdev->priv;
-       union smsc95xx_mac mac;
-       int rc;
-
-       /* Clear stored interrupt status */
-       smsc95xx->int_sts = 0;
-
-       /* Copy MAC address */
-       memset ( &mac, 0, sizeof ( mac ) );
-       memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );
-
-       /* Configure bulk IN empty response */
-       if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_HW_CFG,
-                                     SMSC95XX_HW_CFG_BIR ) ) != 0 )
-               goto err_hw_cfg;
-
-       /* Open USB network device */
-       if ( ( rc = usbnet_open ( &smsc95xx->usbnet ) ) != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p could not open: %s\n",
-                      smsc95xx, strerror ( rc ) );
-               goto err_open;
-       }
-
-       /* Configure interrupt endpoint */
-       if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_INT_EP_CTL,
-                                     ( SMSC95XX_INT_EP_CTL_RXDF_EN |
-                                       SMSC95XX_INT_EP_CTL_PHY_EN ) ) ) != 0 )
-               goto err_int_ep_ctl;
-
-       /* Configure bulk IN delay */
-       if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_BULK_IN_DLY,
-                                     SMSC95XX_BULK_IN_DLY_SET ( 0 ) ) ) != 0 )
-               goto err_bulk_in_dly;
-
-       /* Configure MAC */
-       if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_MAC_CR,
-                                     ( SMSC95XX_MAC_CR_RXALL |
-                                       SMSC95XX_MAC_CR_FDPX |
-                                       SMSC95XX_MAC_CR_MCPAS |
-                                       SMSC95XX_MAC_CR_PRMS |
-                                       SMSC95XX_MAC_CR_PASSBAD |
-                                       SMSC95XX_MAC_CR_TXEN |
-                                       SMSC95XX_MAC_CR_RXEN ) ) ) != 0 )
-               goto err_mac_cr;
-
-       /* Configure transmit datapath */
-       if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_TX_CFG,
-                                     SMSC95XX_TX_CFG_ON ) ) != 0 )
-               goto err_tx_cfg;
-
-       /* Write MAC address high register */
-       if ( ( rc = smsc95xx_raw_writel ( smsc95xx, SMSC95XX_ADDRH,
-                                         mac.addr.h ) ) != 0 )
-               goto err_addrh;
-
-       /* Write MAC address low register */
-       if ( ( rc = smsc95xx_raw_writel ( smsc95xx, SMSC95XX_ADDRL,
-                                         mac.addr.l ) ) != 0 )
-               goto err_addrl;
-
-       /* Enable PHY interrupts */
-       if ( ( rc = mii_write ( &smsc95xx->mii, SMSC95XX_MII_PHY_INTR_MASK,
-                               ( SMSC95XX_PHY_INTR_ANEG_DONE |
-                                 SMSC95XX_PHY_INTR_LINK_DOWN ) ) ) != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p could not set PHY interrupt "
-                      "mask: %s\n", smsc95xx, strerror ( rc ) );
-               goto err_phy_intr_mask;
-       }
-
-       /* Update link status */
-       smsc95xx_check_link ( smsc95xx );
-
-       return 0;
-
- err_phy_intr_mask:
- err_addrl:
- err_addrh:
- err_tx_cfg:
- err_mac_cr:
- err_bulk_in_dly:
- err_int_ep_ctl:
-       usbnet_close ( &smsc95xx->usbnet );
- err_open:
- err_hw_cfg:
-       smsc95xx_reset ( smsc95xx );
-       return rc;
-}
-
-/**
- * Close network device
- *
- * @v netdev           Network device
- */
-static void smsc95xx_close ( struct net_device *netdev ) {
-       struct smsc95xx_device *smsc95xx = netdev->priv;
-
-       /* Close USB network device */
-       usbnet_close ( &smsc95xx->usbnet );
-
-       /* Dump statistics (for debugging) */
-       smsc95xx_dump_statistics ( smsc95xx );
-
-       /* Reset device */
-       smsc95xx_reset ( smsc95xx );
-}
-
-/**
- * Transmit packet
- *
- * @v netdev           Network device
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int smsc95xx_transmit ( struct net_device *netdev,
-                              struct io_buffer *iobuf ) {
-       struct smsc95xx_device *smsc95xx = netdev->priv;
-       int rc;
-
-       /* Transmit packet */
-       if ( ( rc = smsc95xx_out_transmit ( smsc95xx, iobuf ) ) != 0 )
-               return rc;
-
-       return 0;
-}
-
-/**
- * Poll for completed and received packets
- *
- * @v netdev           Network device
- */
-static void smsc95xx_poll ( struct net_device *netdev ) {
-       struct smsc95xx_device *smsc95xx = netdev->priv;
-       uint32_t int_sts;
-       int rc;
-
-       /* Poll USB bus */
-       usb_poll ( smsc95xx->bus );
-
-       /* Refill endpoints */
-       if ( ( rc = usbnet_refill ( &smsc95xx->usbnet ) ) != 0 )
-               netdev_rx_err ( netdev, NULL, rc );
-
-       /* Do nothing more unless there are interrupts to handle */
-       int_sts = smsc95xx->int_sts;
-       if ( ! int_sts )
-               return;
-
-       /* Check link status if applicable */
-       if ( int_sts & SMSC95XX_INT_STS_PHY_INT ) {
-               smsc95xx_check_link ( smsc95xx );
-               int_sts &= ~SMSC95XX_INT_STS_PHY_INT;
-       }
-
-       /* Record RX FIFO overflow if applicable */
-       if ( int_sts & SMSC95XX_INT_STS_RXDF_INT ) {
-               DBGC2 ( smsc95xx, "SMSC95XX %p RX FIFO overflowed\n",
-                       smsc95xx );
-               netdev_rx_err ( netdev, NULL, -ENOBUFS );
-               int_sts &= ~SMSC95XX_INT_STS_RXDF_INT;
-       }
-
-       /* Check for unexpected interrupts */
-       if ( int_sts ) {
-               DBGC ( smsc95xx, "SMSC95XX %p unexpected interrupt %#08x\n",
-                      smsc95xx, int_sts );
-               netdev_rx_err ( netdev, NULL, -ENOTTY );
-       }
-
-       /* Clear interrupts */
-       if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_INT_STS,
-                                     smsc95xx->int_sts ) ) != 0 )
-               netdev_rx_err ( netdev, NULL, rc );
-       smsc95xx->int_sts = 0;
-}
-
-/** SMSC95xx network device operations */
-static struct net_device_operations smsc95xx_operations = {
-       .open           = smsc95xx_open,
-       .close          = smsc95xx_close,
-       .transmit       = smsc95xx_transmit,
-       .poll           = smsc95xx_poll,
-};
-
-/******************************************************************************
- *
- * USB interface
- *
- ******************************************************************************
- */
-
-/**
- * Probe device
- *
- * @v func             USB function
- * @v config           Configuration descriptor
- * @ret rc             Return status code
- */
-static int smsc95xx_probe ( struct usb_function *func,
-                           struct usb_configuration_descriptor *config ) {
-       struct usb_device *usb = func->usb;
-       struct net_device *netdev;
-       struct smsc95xx_device *smsc95xx;
-       int rc;
-
-       /* Allocate and initialise structure */
-       netdev = alloc_etherdev ( sizeof ( *smsc95xx ) );
-       if ( ! netdev ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       netdev_init ( netdev, &smsc95xx_operations );
-       netdev->dev = &func->dev;
-       smsc95xx = netdev->priv;
-       memset ( smsc95xx, 0, sizeof ( *smsc95xx ) );
-       smsc95xx->usb = usb;
-       smsc95xx->bus = usb->port->hub->bus;
-       smsc95xx->netdev = netdev;
-       usbnet_init ( &smsc95xx->usbnet, func, &smsc95xx_intr_operations,
-                     &smsc95xx_in_operations, &smsc95xx_out_operations );
-       usb_refill_init ( &smsc95xx->usbnet.intr, 0, 0,
-                         SMSC95XX_INTR_MAX_FILL );
-       usb_refill_init ( &smsc95xx->usbnet.in,
-                         ( sizeof ( struct smsc95xx_tx_header ) -
-                           sizeof ( struct smsc95xx_rx_header ) ),
-                         SMSC95XX_IN_MTU, SMSC95XX_IN_MAX_FILL );
-       mii_init ( &smsc95xx->mii, &smsc95xx_mii_operations );
-       DBGC ( smsc95xx, "SMSC95XX %p on %s\n", smsc95xx, func->name );
-
-       /* Describe USB network device */
-       if ( ( rc = usbnet_describe ( &smsc95xx->usbnet, config ) ) != 0 ) {
-               DBGC ( smsc95xx, "SMSC95XX %p could not describe: %s\n",
-                      smsc95xx, strerror ( rc ) );
-               goto err_describe;
-       }
-
-       /* Reset device */
-       if ( ( rc = smsc95xx_reset ( smsc95xx ) ) != 0 )
-               goto err_reset;
-
-       /* Read MAC address */
-       if ( ( rc = smsc95xx_fetch_mac ( smsc95xx, netdev->hw_addr ) ) != 0 )
-               goto err_fetch_mac;
-
-       /* Register network device */
-       if ( ( rc = register_netdev ( netdev ) ) != 0 )
-               goto err_register;
-
-       usb_func_set_drvdata ( func, netdev );
-       return 0;
-
-       unregister_netdev ( netdev );
- err_register:
- err_fetch_mac:
- err_reset:
- err_describe:
-       netdev_nullify ( netdev );
-       netdev_put ( netdev );
- err_alloc:
-       return rc;
-}
-
-/**
- * Remove device
- *
- * @v func             USB function
- */
-static void smsc95xx_remove ( struct usb_function *func ) {
-       struct net_device *netdev = usb_func_get_drvdata ( func );
-
-       unregister_netdev ( netdev );
-       netdev_nullify ( netdev );
-       netdev_put ( netdev );
-}
-
-/** SMSC95xx device IDs */
-static struct usb_device_id smsc95xx_ids[] = {
-       {
-               .name = "smsc9500",
-               .vendor = 0x0424,
-               .product = 0x9500,
-       },
-       {
-               .name = "smsc9505",
-               .vendor = 0x0424,
-               .product = 0x9505,
-       },
-       {
-               .name = "smsc9500a",
-               .vendor = 0x0424,
-               .product = 0x9e00,
-       },
-       {
-               .name = "smsc9505a",
-               .vendor = 0x0424,
-               .product = 0x9e01,
-       },
-       {
-               .name = "smsc9514",
-               .vendor = 0x0424,
-               .product = 0xec00,
-       },
-       {
-               .name = "smsc9500-s",
-               .vendor = 0x0424,
-               .product = 0x9900,
-       },
-       {
-               .name = "smsc9505-s",
-               .vendor = 0x0424,
-               .product = 0x9901,
-       },
-       {
-               .name = "smsc9500a-s",
-               .vendor = 0x0424,
-               .product = 0x9902,
-       },
-       {
-               .name = "smsc9505a-s",
-               .vendor = 0x0424,
-               .product = 0x9903,
-       },
-       {
-               .name = "smsc9514-s",
-               .vendor = 0x0424,
-               .product = 0x9904,
-       },
-       {
-               .name = "smsc9500a-h",
-               .vendor = 0x0424,
-               .product = 0x9905,
-       },
-       {
-               .name = "smsc9505a-h",
-               .vendor = 0x0424,
-               .product = 0x9906,
-       },
-       {
-               .name = "smsc9500-2",
-               .vendor = 0x0424,
-               .product = 0x9907,
-       },
-       {
-               .name = "smsc9500a-2",
-               .vendor = 0x0424,
-               .product = 0x9908,
-       },
-       {
-               .name = "smsc9514-2",
-               .vendor = 0x0424,
-               .product = 0x9909,
-       },
-       {
-               .name = "smsc9530",
-               .vendor = 0x0424,
-               .product = 0x9530,
-       },
-       {
-               .name = "smsc9730",
-               .vendor = 0x0424,
-               .product = 0x9730,
-       },
-       {
-               .name = "smsc89530",
-               .vendor = 0x0424,
-               .product = 0x9e08,
-       },
-};
-
-/** SMSC LAN95xx driver */
-struct usb_driver smsc95xx_driver __usb_driver = {
-       .ids = smsc95xx_ids,
-       .id_count = ( sizeof ( smsc95xx_ids ) / sizeof ( smsc95xx_ids[0] ) ),
-       .class = USB_CLASS_ID ( 0xff, 0x00, 0xff ),
-       .score = USB_SCORE_NORMAL,
-       .probe = smsc95xx_probe,
-       .remove = smsc95xx_remove,
-};
diff --git a/roms/ipxe/src/drivers/net/smsc95xx.h b/roms/ipxe/src/drivers/net/smsc95xx.h
deleted file mode 100644 (file)
index c2512e0..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-#ifndef _SMSC95XX_H
-#define _SMSC95XX_H
-
-/** @file
- *
- * SMSC LAN95xx USB Ethernet driver
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/usb.h>
-#include <ipxe/usbnet.h>
-#include <ipxe/if_ether.h>
-#include <ipxe/mii.h>
-
-/** Register write command */
-#define SMSC95XX_REGISTER_WRITE                                        \
-       ( USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE |    \
-         USB_REQUEST_TYPE ( 0xa0 ) )
-
-/** Register read command */
-#define SMSC95XX_REGISTER_READ                                 \
-       ( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE |     \
-         USB_REQUEST_TYPE ( 0xa1 ) )
-
-/** Get statistics command */
-#define SMSC95XX_GET_STATISTICS                                        \
-       ( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE |     \
-         USB_REQUEST_TYPE ( 0xa2 ) )
-
-/** Interrupt status register */
-#define SMSC95XX_INT_STS 0x008
-#define SMSC95XX_INT_STS_RXDF_INT      0x00000800UL    /**< RX FIFO overflow */
-#define SMSC95XX_INT_STS_PHY_INT       0x00008000UL    /**< PHY interrupt */
-
-/** Transmit configuration register */
-#define SMSC95XX_TX_CFG 0x010
-#define SMSC95XX_TX_CFG_ON             0x00000004UL    /**< TX enable */
-
-/** Hardware configuration register */
-#define SMSC95XX_HW_CFG 0x014
-#define SMSC95XX_HW_CFG_BIR            0x00001000UL    /**< Bulk IN use NAK */
-#define SMSC95XX_HW_CFG_LRST           0x00000008UL    /**< Soft lite reset */
-
-/** LED GPIO configuration register */
-#define SMSC95XX_LED_GPIO_CFG 0x024
-#define SMSC95XX_LED_GPIO_CFG_GPCTL2(x)        ( (x) << 24 )   /**< GPIO 2 control */
-#define SMSC95XX_LED_GPIO_CFG_GPCTL2_NSPD_LED \
-       SMSC95XX_LED_GPIO_CFG_GPCTL2 ( 1 )              /**< Link speed LED */
-#define SMSC95XX_LED_GPIO_CFG_GPCTL1(x)        ( (x) << 20 )   /**< GPIO 1 control */
-#define SMSC95XX_LED_GPIO_CFG_GPCTL1_NLNKA_LED \
-       SMSC95XX_LED_GPIO_CFG_GPCTL1 ( 1 )              /**< Activity LED */
-#define SMSC95XX_LED_GPIO_CFG_GPCTL0(x)        ( (x) << 16 )   /**< GPIO 0 control */
-#define SMSC95XX_LED_GPIO_CFG_GPCTL0_NFDX_LED \
-       SMSC95XX_LED_GPIO_CFG_GPCTL0 ( 1 )              /**< Full-duplex LED */
-
-/** EEPROM command register */
-#define SMSC95XX_E2P_CMD 0x030
-#define SMSC95XX_E2P_CMD_EPC_BSY       0x80000000UL    /**< EPC busy */
-#define SMSC95XX_E2P_CMD_EPC_CMD_READ  0x00000000UL    /**< READ command */
-#define SMSC95XX_E2P_CMD_EPC_ADDR(addr) ( (addr) << 0 )        /**< EPC address */
-
-/** EEPROM data register */
-#define SMSC95XX_E2P_DATA 0x034
-#define SMSC95XX_E2P_DATA_GET(e2p_data) \
-       ( ( (e2p_data) >> 0 ) & 0xff )                  /**< EEPROM data */
-
-/** MAC address EEPROM address */
-#define SMSC95XX_EEPROM_MAC 0x01
-
-/** Interrupt endpoint control register */
-#define SMSC95XX_INT_EP_CTL 0x068
-#define SMSC95XX_INT_EP_CTL_RXDF_EN    0x00000800UL    /**< RX FIFO overflow */
-#define SMSC95XX_INT_EP_CTL_PHY_EN     0x00008000UL    /**< PHY interrupt */
-
-/** Bulk IN delay register */
-#define SMSC95XX_BULK_IN_DLY 0x06c
-#define SMSC95XX_BULK_IN_DLY_SET(ticks)        ( (ticks) << 0 ) /**< Delay / 16.7ns */
-
-/** MAC control register */
-#define SMSC95XX_MAC_CR 0x100
-#define SMSC95XX_MAC_CR_RXALL          0x80000000UL    /**< Receive all */
-#define SMSC95XX_MAC_CR_FDPX           0x00100000UL    /**< Full duplex */
-#define SMSC95XX_MAC_CR_MCPAS          0x00080000UL    /**< All multicast */
-#define SMSC95XX_MAC_CR_PRMS           0x00040000UL    /**< Promiscuous */
-#define SMSC95XX_MAC_CR_PASSBAD                0x00010000UL    /**< Pass bad frames */
-#define SMSC95XX_MAC_CR_TXEN           0x00000008UL    /**< TX enabled */
-#define SMSC95XX_MAC_CR_RXEN           0x00000004UL    /**< RX enabled */
-
-/** MAC address high register */
-#define SMSC95XX_ADDRH 0x104
-
-/** MAC address low register */
-#define SMSC95XX_ADDRL 0x108
-
-/** MII access register */
-#define SMSC95XX_MII_ACCESS 0x114
-#define SMSC95XX_MII_ACCESS_PHY_ADDRESS        0x00000800UL    /**< PHY address */
-#define SMSC95XX_MII_ACCESS_MIIRINDA(addr) ( (addr) << 6 ) /**< MII register */
-#define SMSC95XX_MII_ACCESS_MIIWNR     0x00000002UL    /**< MII write */
-#define SMSC95XX_MII_ACCESS_MIIBZY     0x00000001UL    /**< MII busy */
-
-/** MII data register */
-#define SMSC95XX_MII_DATA 0x118
-#define SMSC95XX_MII_DATA_SET(data)    ( (data) << 0 ) /**< Set data */
-#define SMSC95XX_MII_DATA_GET(mii_data) \
-       ( ( (mii_data) >> 0 ) & 0xffff )                /**< Get data */
-
-/** PHY interrupt source MII register */
-#define SMSC95XX_MII_PHY_INTR_SOURCE 29
-
-/** PHY interrupt mask MII register */
-#define SMSC95XX_MII_PHY_INTR_MASK 30
-
-/** PHY interrupt: auto-negotiation complete */
-#define SMSC95XX_PHY_INTR_ANEG_DONE    0x0040
-
-/** PHY interrupt: link down */
-#define SMSC95XX_PHY_INTR_LINK_DOWN    0x0010
-
-/** MAC address */
-union smsc95xx_mac {
-       /** MAC receive address registers */
-       struct {
-               /** MAC receive address low register */
-               uint32_t l;
-               /** MAC receive address high register */
-               uint32_t h;
-       } __attribute__ (( packed )) addr;
-       /** Raw MAC address */
-       uint8_t raw[ETH_ALEN];
-};
-
-/** Receive packet header */
-struct smsc95xx_rx_header {
-       /** Command word */
-       uint32_t command;
-} __attribute__ (( packed ));
-
-/** Runt frame */
-#define SMSC95XX_RX_RUNT 0x00004000UL
-
-/** Late collision */
-#define SMSC95XX_RX_LATE 0x00000040UL
-
-/** CRC error */
-#define SMSC95XX_RX_CRC 0x00000002UL
-
-/** Transmit packet header */
-struct smsc95xx_tx_header {
-       /** Command word */
-       uint32_t command;
-       /** Frame length */
-       uint32_t len;
-} __attribute__ (( packed ));
-
-/** First segment */
-#define SMSC95XX_TX_FIRST 0x00002000UL
-
-/** Last segment */
-#define SMSC95XX_TX_LAST 0x00001000UL
-
-/** Buffer size */
-#define SMSC95XX_TX_LEN(len) ( (len) << 0 )
-
-/** Interrupt packet format */
-struct smsc95xx_interrupt {
-       /** Current value of INT_STS register */
-       uint32_t int_sts;
-} __attribute__ (( packed ));
-
-/** Receive statistics */
-struct smsc95xx_rx_statistics {
-       /** Good frames */
-       uint32_t good;
-       /** CRC errors */
-       uint32_t crc;
-       /** Runt frame errors */
-       uint32_t undersize;
-       /** Alignment errors */
-       uint32_t alignment;
-       /** Frame too long errors */
-       uint32_t oversize;
-       /** Later collision errors */
-       uint32_t late;
-       /** Bad frames */
-       uint32_t bad;
-       /** Dropped frames */
-       uint32_t dropped;
-} __attribute__ (( packed ));
-
-/** Receive statistics */
-#define SMSC95XX_RX_STATISTICS 0
-
-/** Transmit statistics */
-struct smsc95xx_tx_statistics {
-       /** Good frames */
-       uint32_t good;
-       /** Pause frames */
-       uint32_t pause;
-       /** Single collisions */
-       uint32_t single;
-       /** Multiple collisions */
-       uint32_t multiple;
-       /** Excessive collisions */
-       uint32_t excessive;
-       /** Late collisions */
-       uint32_t late;
-       /** Buffer underruns */
-       uint32_t underrun;
-       /** Excessive deferrals */
-       uint32_t deferred;
-       /** Carrier errors */
-       uint32_t carrier;
-       /** Bad frames */
-       uint32_t bad;
-} __attribute__ (( packed ));
-
-/** Transmit statistics */
-#define SMSC95XX_TX_STATISTICS 1
-
-/** A SMSC95xx network device */
-struct smsc95xx_device {
-       /** USB device */
-       struct usb_device *usb;
-       /** USB bus */
-       struct usb_bus *bus;
-       /** Network device */
-       struct net_device *netdev;
-       /** USB network device */
-       struct usbnet_device usbnet;
-       /** MII interface */
-       struct mii_interface mii;
-       /** Interrupt status */
-       uint32_t int_sts;
-};
-
-/** Reset delay (in microseconds) */
-#define SMSC95XX_RESET_DELAY_US 2
-
-/** Maximum time to wait for EEPROM (in milliseconds) */
-#define SMSC95XX_EEPROM_MAX_WAIT_MS 100
-
-/** Maximum time to wait for MII (in milliseconds) */
-#define SMSC95XX_MII_MAX_WAIT_MS 100
-
-/** Interrupt maximum fill level
- *
- * This is a policy decision.
- */
-#define SMSC95XX_INTR_MAX_FILL 2
-
-/** Bulk IN maximum fill level
- *
- * This is a policy decision.
- */
-#define SMSC95XX_IN_MAX_FILL 8
-
-/** Bulk IN buffer size */
-#define SMSC95XX_IN_MTU                                                \
-       ( sizeof ( struct smsc95xx_rx_header ) +                \
-         ETH_FRAME_LEN + 4 /* possible VLAN header */          \
-         + 4 /* CRC */ )
-
-/** Honeywell VM3 MAC address OEM string index */
-#define SMSC95XX_VM3_OEM_STRING_MAC 2
-
-#endif /* _SMSC95XX_H */
index 1bed066..42bfa2d 100644 (file)
@@ -486,8 +486,6 @@ static void tg3_poll(struct net_device *dev)
         */
        tp->hw_status->status &= ~SD_STATUS_UPDATED;
 
-       mb();
-
        tg3_poll_link(tp);
        tg3_tx_complete(dev);
        tg3_rx_complete(dev);
@@ -547,7 +545,7 @@ static int tg3_test_dma(struct tg3 *tp)
                goto out_nofree;
        }
        buf_dma = virt_to_bus(buf);
-       DBGC2(tp->dev, "dma test buffer, virt: %p phys: %#016lx\n", buf, buf_dma);
+       DBGC2(tp->dev, "dma test buffer, virt: %p phys: %#08x\n", buf, buf_dma);
 
        if (tg3_flag(tp, 57765_PLUS)) {
                tp->dma_rwctrl = DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
index be02c57..2b85b06 100644 (file)
@@ -52,6 +52,7 @@
 #define PCI_X_CMD                      2       /* Modes & Features */
 #define PCI_X_CMD_ERO                  0x0002  /* Enable Relaxed Ordering */
 
+#define PCI_EXP_DEVCTL                 8       /* Device Control */
 #define PCI_EXP_DEVCTL_RELAX_EN                0x0010 /* Enable relaxed ordering */
 #define PCI_EXP_DEVCTL_NOSNOOP_EN      0x0800  /* Enable No Snoop */
 #define PCI_EXP_DEVCTL_PAYLOAD         0x00e0  /* Max_Payload_Size */
@@ -2788,7 +2789,7 @@ struct tg3_hw_stats {
        u8                              __reserved4[0xb00-0x9c8];
 };
 
-typedef unsigned long dma_addr_t;
+typedef u32 dma_addr_t;
 
 /* 'mapping' is superfluous as the chip does not write into
  * the tx/rx post rings so we could just fetch it from there.
@@ -3320,25 +3321,43 @@ void tg3_write_indirect_mbox(struct tg3 *tp, u32 off, u32 val);
 
 /* Functions & macros to verify TG3_FLAGS types */
 
+static inline int variable_test_bit(int nr, volatile const unsigned long *addr)
+{
+       int oldbit;
+
+       asm volatile("bt %2,%1\n\t"
+                    "sbb %0,%0"
+                    : "=r" (oldbit)
+                    : "m" (*(unsigned long *)addr), "Ir" (nr));
+
+       return oldbit;
+}
+
 static inline int _tg3_flag(enum TG3_FLAGS flag, unsigned long *bits)
 {
-       unsigned int index = ( flag / ( 8 * sizeof ( *bits ) ) );
-       unsigned int bit = ( flag % ( 8 * sizeof ( *bits ) ) );
-       return ( !! ( bits[index] & ( 1UL << bit ) ) );
+       return variable_test_bit(flag, bits);
+}
+
+#define BITOP_ADDR(x) "+m" (*(volatile long *) (x))
+
+static inline void __set_bit(int nr, volatile unsigned long *addr)
+{
+       asm volatile("bts %1,%0" : BITOP_ADDR(addr) : "Ir" (nr) : "memory");
 }
 
 static inline void _tg3_flag_set(enum TG3_FLAGS flag, unsigned long *bits)
 {
-       unsigned int index = ( flag / ( 8 * sizeof ( *bits ) ) );
-       unsigned int bit = ( flag % ( 8 * sizeof ( *bits ) ) );
-       bits[index] |= ( 1UL << bit );
+       __set_bit(flag, bits);
+}
+
+static inline void __clear_bit(int nr, volatile unsigned long *addr)
+{
+       asm volatile("btr %1,%0" : BITOP_ADDR(addr) : "Ir" (nr));
 }
 
 static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
 {
-       unsigned int index = ( flag / ( 8 * sizeof ( *bits ) ) );
-       unsigned int bit = ( flag % ( 8 * sizeof ( *bits ) ) );
-       bits[index] &= ~( 1UL << bit );
+       __clear_bit(flag, bits);
 }
 
 #define tg3_flag(tp, flag)                             \
diff --git a/roms/ipxe/src/drivers/net/thunderx.c b/roms/ipxe/src/drivers/net/thunderx.c
deleted file mode 100644 (file)
index 306adc4..0000000
+++ /dev/null
@@ -1,1706 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <string.h>
-#include <strings.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <assert.h>
-#include <byteswap.h>
-#include <ipxe/netdevice.h>
-#include <ipxe/ethernet.h>
-#include <ipxe/if_ether.h>
-#include <ipxe/iobuf.h>
-#include <ipxe/malloc.h>
-#include <ipxe/pci.h>
-#include <ipxe/pciea.h>
-#include <ipxe/umalloc.h>
-#include "thunderx.h"
-#include "thunderxcfg.h"
-
-/** @file
- *
- * Cavium ThunderX Ethernet driver
- *
- */
-
-/** List of BGX Ethernet interfaces */
-static LIST_HEAD ( txnic_bgxs );
-
-/** List of physical functions */
-static LIST_HEAD ( txnic_pfs );
-
-/** Debug colour for physical function and BGX messages */
-#define TXNICCOL(x) ( &txnic_pfs + (x)->node )
-
-/** Board configuration protocol */
-static EFI_THUNDER_CONFIG_PROTOCOL *txcfg;
-EFI_REQUEST_PROTOCOL ( EFI_THUNDER_CONFIG_PROTOCOL, &txcfg );
-
-/******************************************************************************
- *
- * Diagnostics
- *
- ******************************************************************************
- */
-
-/**
- * Show virtual NIC diagnostics (for debugging)
- *
- * @v vnic             Virtual NIC
- */
-static __attribute__ (( unused )) void txnic_diag ( struct txnic *vnic ) {
-
-       DBGC ( vnic, "TXNIC %s SQ %05zx(%05llx)/%05zx(%05llx) %08llx\n",
-              vnic->name,
-              ( ( vnic->sq.prod % TXNIC_SQES ) * TXNIC_SQ_STRIDE ),
-              readq ( vnic->regs + TXNIC_QS_SQ_TAIL(0) ),
-              ( ( vnic->sq.cons % TXNIC_SQES ) * TXNIC_SQ_STRIDE ),
-              readq ( vnic->regs + TXNIC_QS_SQ_HEAD(0) ),
-              readq ( vnic->regs + TXNIC_QS_SQ_STATUS(0) ) );
-       DBGC ( vnic, "TXNIC %s RQ %05zx(%05llx)/%05zx(%05llx) %016llx\n",
-              vnic->name,
-              ( ( vnic->rq.prod % TXNIC_RQES ) * TXNIC_RQ_STRIDE ),
-              readq ( vnic->regs + TXNIC_QS_RBDR_TAIL(0) ),
-              ( ( vnic->rq.cons % TXNIC_RQES ) * TXNIC_RQ_STRIDE ),
-              readq ( vnic->regs + TXNIC_QS_RBDR_HEAD(0) ),
-              readq ( vnic->regs + TXNIC_QS_RBDR_STATUS0(0) ) );
-       DBGC ( vnic, "TXNIC %s CQ xxxxx(%05llx)/%05x(%05llx) %08llx:%08llx\n",
-              vnic->name, readq ( vnic->regs + TXNIC_QS_CQ_TAIL(0) ),
-              ( ( vnic->cq.cons % TXNIC_CQES ) * TXNIC_CQ_STRIDE ),
-              readq ( vnic->regs + TXNIC_QS_CQ_HEAD(0) ),
-              readq ( vnic->regs + TXNIC_QS_CQ_STATUS(0) ),
-              readq ( vnic->regs + TXNIC_QS_CQ_STATUS2(0) ) );
-}
-
-/******************************************************************************
- *
- * Send queue
- *
- ******************************************************************************
- */
-
-/**
- * Create send queue
- *
- * @v vnic             Virtual NIC
- * @ret rc             Return status code
- */
-static int txnic_create_sq ( struct txnic *vnic ) {
-
-       /* Reset send queue */
-       vnic->sq.prod = 0;
-       vnic->sq.cons = 0;
-       writeq ( TXNIC_QS_SQ_CFG_RESET, ( vnic->regs + TXNIC_QS_SQ_CFG(0) ) );
-
-       /* Configure and enable send queue */
-       writeq ( user_to_phys ( vnic->sq.sqe, 0 ),
-                ( vnic->regs + TXNIC_QS_SQ_BASE(0) ) );
-       writeq ( ( TXNIC_QS_SQ_CFG_ENA | TXNIC_QS_SQ_CFG_QSIZE_1K ),
-                ( vnic->regs + TXNIC_QS_SQ_CFG(0) ) );
-
-       DBGC ( vnic, "TXNIC %s SQ at [%08lx,%08lx)\n",
-              vnic->name, user_to_phys ( vnic->sq.sqe, 0 ),
-              user_to_phys ( vnic->sq.sqe, TXNIC_SQ_SIZE ) );
-       return 0;
-}
-
-/**
- * Disable send queue
- *
- * @v vnic             Virtual NIC
- * @ret rc             Return status code
- */
-static int txnic_disable_sq ( struct txnic *vnic ) {
-       uint64_t status;
-       unsigned int i;
-
-       /* Disable send queue */
-       writeq ( 0, ( vnic->regs + TXNIC_QS_SQ_CFG(0) ) );
-
-       /* Wait for send queue to be stopped */
-       for ( i = 0 ; i < TXNIC_SQ_STOP_MAX_WAIT_MS ; i++ ) {
-
-               /* Check if send queue is stopped */
-               status = readq ( vnic->regs + TXNIC_QS_SQ_STATUS(0) );
-               if ( status & TXNIC_QS_SQ_STATUS_STOPPED )
-                       return 0;
-
-               /* Delay */
-               mdelay ( 1 );
-       }
-
-       DBGC ( vnic, "TXNIC %s SQ disable timed out\n", vnic->name );
-       return -ETIMEDOUT;
-}
-
-/**
- * Destroy send queue
- *
- * @v vnic             Virtual NIC
- */
-static void txnic_destroy_sq ( struct txnic *vnic ) {
-       int rc;
-
-       /* Disable send queue */
-       if ( ( rc = txnic_disable_sq ( vnic ) ) != 0 ) {
-               /* Nothing else we can do */
-               return;
-       }
-
-       /* Reset send queue */
-       writeq ( TXNIC_QS_SQ_CFG_RESET, ( vnic->regs + TXNIC_QS_SQ_CFG(0) ) );
-}
-
-/**
- * Send packet
- *
- * @v vnic             Virtual NIC
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int txnic_send ( struct txnic *vnic, struct io_buffer *iobuf ) {
-       struct txnic_sqe sqe;
-       unsigned int sq_idx;
-       size_t offset;
-       size_t len;
-
-       /* Get next send queue entry */
-       if ( ( vnic->sq.prod - vnic->sq.cons ) >= TXNIC_SQ_FILL ) {
-               DBGC ( vnic, "TXNIC %s out of send queue entries\n",
-                      vnic->name );
-               return -ENOBUFS;
-       }
-       sq_idx = ( vnic->sq.prod++ % TXNIC_SQES );
-       offset = ( sq_idx * TXNIC_SQ_STRIDE );
-
-       /* Populate send descriptor */
-       len = iob_len ( iobuf );
-       memset ( &sqe, 0, sizeof ( sqe ) );
-       sqe.hdr.total = cpu_to_le32 ( ( len >= ETH_ZLEN ) ? len : ETH_ZLEN );
-       sqe.hdr.subdcnt = ( TXNIC_SQE_SUBDESCS - 1 );
-       sqe.hdr.flags = TXNIC_SEND_HDR_FLAGS;
-       sqe.gather.size = cpu_to_le16 ( len );
-       sqe.gather.flags = TXNIC_SEND_GATHER_FLAGS;
-       sqe.gather.addr = cpu_to_le64 ( virt_to_bus ( iobuf->data ) );
-       DBGC2 ( vnic, "TXNIC %s SQE %#03x is [%08lx,%08lx)\n",
-               vnic->name, sq_idx, virt_to_bus ( iobuf->data ),
-               ( virt_to_bus ( iobuf->data ) + len ) );
-
-       /* Copy send descriptor to ring */
-       copy_to_user ( vnic->sq.sqe, offset, &sqe, sizeof ( sqe ) );
-
-       /* Ring doorbell */
-       wmb();
-       writeq ( TXNIC_SQE_SUBDESCS, ( vnic->regs + TXNIC_QS_SQ_DOOR(0) ) );
-
-       return 0;
-}
-
-/**
- * Complete send queue entry
- *
- * @v vnic             Virtual NIC
- * @v cqe              Send completion queue entry
- */
-static void txnic_complete_sqe ( struct txnic *vnic,
-                                struct txnic_cqe_send *cqe ) {
-       struct net_device *netdev = vnic->netdev;
-       unsigned int sq_idx;
-       unsigned int status;
-
-       /* Parse completion */
-       sq_idx = ( le16_to_cpu ( cqe->sqe_ptr ) / TXNIC_SQE_SUBDESCS );
-       status = cqe->send_status;
-
-       /* Sanity check */
-       assert ( sq_idx == ( vnic->sq.cons % TXNIC_SQES ) );
-
-       /* Free send queue entry */
-       vnic->sq.cons++;
-
-       /* Complete transmission */
-       if ( status ) {
-               DBGC ( vnic, "TXNIC %s SQE %#03x complete (status %#02x)\n",
-                      vnic->name, sq_idx, status );
-               netdev_tx_complete_next_err ( netdev, -EIO );
-       } else {
-               DBGC2 ( vnic, "TXNIC %s SQE %#03x complete\n",
-                       vnic->name, sq_idx );
-               netdev_tx_complete_next ( netdev );
-       }
-}
-
-/******************************************************************************
- *
- * Receive queue
- *
- ******************************************************************************
- */
-
-/**
- * Create receive queue
- *
- * @v vnic             Virtual NIC
- * @ret rc             Return status code
- */
-static int txnic_create_rq ( struct txnic *vnic ) {
-
-       /* Reset receive buffer descriptor ring */
-       vnic->rq.prod = 0;
-       vnic->rq.cons = 0;
-       writeq ( TXNIC_QS_RBDR_CFG_RESET,
-                ( vnic->regs + TXNIC_QS_RBDR_CFG(0) ) );
-
-       /* Configure and enable receive buffer descriptor ring */
-       writeq ( user_to_phys ( vnic->rq.rqe, 0 ),
-                ( vnic->regs + TXNIC_QS_RBDR_BASE(0) ) );
-       writeq ( ( TXNIC_QS_RBDR_CFG_ENA | TXNIC_QS_RBDR_CFG_QSIZE_8K |
-                  TXNIC_QS_RBDR_CFG_LINES ( TXNIC_RQE_SIZE /
-                                            TXNIC_LINE_SIZE ) ),
-                ( vnic->regs + TXNIC_QS_RBDR_CFG(0) ) );
-
-       /* Enable receive queue */
-       writeq ( TXNIC_QS_RQ_CFG_ENA, ( vnic->regs + TXNIC_QS_RQ_CFG(0) ) );
-
-       DBGC ( vnic, "TXNIC %s RQ at [%08lx,%08lx)\n",
-              vnic->name, user_to_phys ( vnic->rq.rqe, 0 ),
-              user_to_phys ( vnic->rq.rqe, TXNIC_RQ_SIZE ) );
-       return 0;
-}
-
-/**
- * Disable receive queue
- *
- * @v vnic             Virtual NIC
- * @ret rc             Return status code
- */
-static int txnic_disable_rq ( struct txnic *vnic ) {
-       uint64_t cfg;
-       unsigned int i;
-
-       /* Disable receive queue */
-       writeq ( 0, ( vnic->regs + TXNIC_QS_RQ_CFG(0) ) );
-
-       /* Wait for receive queue to be disabled */
-       for ( i = 0 ; i < TXNIC_RQ_DISABLE_MAX_WAIT_MS ; i++ ) {
-
-               /* Check if receive queue is disabled */
-               cfg = readq ( vnic->regs + TXNIC_QS_RQ_CFG(0) );
-               if ( ! ( cfg & TXNIC_QS_RQ_CFG_ENA ) )
-                       return 0;
-
-               /* Delay */
-               mdelay ( 1 );
-       }
-
-       DBGC ( vnic, "TXNIC %s RQ disable timed out\n", vnic->name );
-       return -ETIMEDOUT;
-}
-
-/**
- * Destroy receive queue
- *
- * @v vnic             Virtual NIC
- */
-static void txnic_destroy_rq ( struct txnic *vnic ) {
-       unsigned int i;
-       int rc;
-
-       /* Disable receive queue */
-       if ( ( rc = txnic_disable_rq ( vnic ) ) != 0 ) {
-               /* Leak memory; there's nothing else we can do */
-               return;
-       }
-
-       /* Disable receive buffer descriptor ring */
-       writeq ( 0, ( vnic->regs + TXNIC_QS_RBDR_CFG(0) ) );
-
-       /* Reset receive buffer descriptor ring */
-       writeq ( TXNIC_QS_RBDR_CFG_RESET,
-                ( vnic->regs + TXNIC_QS_RBDR_CFG(0) ) );
-
-       /* Free any unused I/O buffers */
-       for ( i = 0 ; i < TXNIC_RQ_FILL ; i++ ) {
-               if ( vnic->rq.iobuf[i] )
-                       free_iob ( vnic->rq.iobuf[i] );
-               vnic->rq.iobuf[i] = NULL;
-       }
-}
-
-/**
- * Refill receive queue
- *
- * @v vnic             Virtual NIC
- */
-static void txnic_refill_rq ( struct txnic *vnic ) {
-       struct io_buffer *iobuf;
-       struct txnic_rqe rqe;
-       unsigned int rq_idx;
-       unsigned int rq_iobuf_idx;
-       unsigned int refilled = 0;
-       size_t offset;
-
-       /* Refill ring */
-       while ( ( vnic->rq.prod - vnic->rq.cons ) < TXNIC_RQ_FILL ) {
-
-               /* Allocate I/O buffer */
-               iobuf = alloc_iob ( TXNIC_RQE_SIZE );
-               if ( ! iobuf ) {
-                       /* Wait for next refill */
-                       break;
-               }
-
-               /* Get next receive descriptor */
-               rq_idx = ( vnic->rq.prod++ % TXNIC_RQES );
-               offset = ( rq_idx * TXNIC_RQ_STRIDE );
-
-               /* Populate receive descriptor */
-               rqe.rbdre.addr = cpu_to_le64 ( virt_to_bus ( iobuf->data ) );
-               DBGC2 ( vnic, "TXNIC %s RQE %#03x is [%08lx,%08lx)\n",
-                       vnic->name, rq_idx, virt_to_bus ( iobuf->data ),
-                       ( virt_to_bus ( iobuf->data ) + TXNIC_RQE_SIZE ) );
-
-               /* Copy receive descriptor to ring */
-               copy_to_user ( vnic->rq.rqe, offset, &rqe, sizeof ( rqe ) );
-               refilled++;
-
-               /* Record I/O buffer */
-               rq_iobuf_idx = ( rq_idx % TXNIC_RQ_FILL );
-               assert ( vnic->rq.iobuf[rq_iobuf_idx] == NULL );
-               vnic->rq.iobuf[rq_iobuf_idx] = iobuf;
-       }
-
-       /* Ring doorbell */
-       wmb();
-       writeq ( refilled, ( vnic->regs + TXNIC_QS_RBDR_DOOR(0) ) );
-}
-
-/**
- * Complete receive queue entry
- *
- * @v vnic             Virtual NIC
- * @v cqe              Receive completion queue entry
- */
-static void txnic_complete_rqe ( struct txnic *vnic,
-                                struct txnic_cqe_rx *cqe ) {
-       struct net_device *netdev = vnic->netdev;
-       struct io_buffer *iobuf;
-       unsigned int errop;
-       unsigned int rq_idx;
-       unsigned int rq_iobuf_idx;
-       size_t apad_len;
-       size_t len;
-
-       /* Parse completion */
-       errop = cqe->errop;
-       apad_len = TXNIC_CQE_RX_APAD_LEN ( cqe->apad );
-       len = le16_to_cpu ( cqe->len );
-
-       /* Get next receive I/O buffer */
-       rq_idx = ( vnic->rq.cons++ % TXNIC_RQES );
-       rq_iobuf_idx = ( rq_idx % TXNIC_RQ_FILL );
-       iobuf = vnic->rq.iobuf[rq_iobuf_idx];
-       vnic->rq.iobuf[rq_iobuf_idx] = NULL;
-
-       /* Populate I/O buffer */
-       iob_reserve ( iobuf, apad_len );
-       iob_put ( iobuf, len );
-
-       /* Hand off to network stack */
-       if ( errop ) {
-               DBGC ( vnic, "TXNIC %s RQE %#03x error (length %zd, errop "
-                      "%#02x)\n", vnic->name, rq_idx, len, errop );
-               netdev_rx_err ( netdev, iobuf, -EIO );
-       } else {
-               DBGC2 ( vnic, "TXNIC %s RQE %#03x complete (length %zd)\n",
-                       vnic->name, rq_idx, len );
-               netdev_rx ( netdev, iobuf );
-       }
-}
-
-/******************************************************************************
- *
- * Completion queue
- *
- ******************************************************************************
- */
-
-/**
- * Create completion queue
- *
- * @v vnic             Virtual NIC
- * @ret rc             Return status code
- */
-static int txnic_create_cq ( struct txnic *vnic ) {
-
-       /* Reset completion queue */
-       vnic->cq.cons = 0;
-       writeq ( TXNIC_QS_CQ_CFG_RESET, ( vnic->regs + TXNIC_QS_CQ_CFG(0) ) );
-
-       /* Configure and enable completion queue */
-       writeq ( user_to_phys ( vnic->cq.cqe, 0 ),
-                ( vnic->regs + TXNIC_QS_CQ_BASE(0) ) );
-       writeq ( ( TXNIC_QS_CQ_CFG_ENA | TXNIC_QS_CQ_CFG_QSIZE_256 ),
-                ( vnic->regs + TXNIC_QS_CQ_CFG(0) ) );
-
-       DBGC ( vnic, "TXNIC %s CQ at [%08lx,%08lx)\n",
-              vnic->name, user_to_phys ( vnic->cq.cqe, 0 ),
-              user_to_phys ( vnic->cq.cqe, TXNIC_CQ_SIZE ) );
-       return 0;
-}
-
-/**
- * Disable completion queue
- *
- * @v vnic             Virtual NIC
- * @ret rc             Return status code
- */
-static int txnic_disable_cq ( struct txnic *vnic ) {
-       uint64_t cfg;
-       unsigned int i;
-
-       /* Disable completion queue */
-       writeq ( 0, ( vnic->regs + TXNIC_QS_CQ_CFG(0) ) );
-
-       /* Wait for completion queue to be disabled */
-       for ( i = 0 ; i < TXNIC_CQ_DISABLE_MAX_WAIT_MS ; i++ ) {
-
-               /* Check if completion queue is disabled */
-               cfg = readq ( vnic->regs + TXNIC_QS_CQ_CFG(0) );
-               if ( ! ( cfg & TXNIC_QS_CQ_CFG_ENA ) )
-                       return 0;
-
-               /* Delay */
-               mdelay ( 1 );
-       }
-
-       DBGC ( vnic, "TXNIC %s CQ disable timed out\n", vnic->name );
-       return -ETIMEDOUT;
-}
-
-/**
- * Destroy completion queue
- *
- * @v vnic             Virtual NIC
- */
-static void txnic_destroy_cq ( struct txnic *vnic ) {
-       int rc;
-
-       /* Disable completion queue */
-       if ( ( rc = txnic_disable_cq ( vnic ) ) != 0 ) {
-               /* Leak memory; there's nothing else we can do */
-               return;
-       }
-
-       /* Reset completion queue */
-       writeq ( TXNIC_QS_CQ_CFG_RESET, ( vnic->regs + TXNIC_QS_CQ_CFG(0) ) );
-}
-
-/**
- * Poll completion queue
- *
- * @v vnic             Virtual NIC
- */
-static void txnic_poll_cq ( struct txnic *vnic ) {
-       union txnic_cqe cqe;
-       uint64_t status;
-       size_t offset;
-       unsigned int qcount;
-       unsigned int cq_idx;
-       unsigned int i;
-
-       /* Get number of completions */
-       status = readq ( vnic->regs + TXNIC_QS_CQ_STATUS(0) );
-       qcount = TXNIC_QS_CQ_STATUS_QCOUNT ( status );
-       if ( ! qcount )
-               return;
-
-       /* Process completion queue entries */
-       for ( i = 0 ; i < qcount ; i++ ) {
-
-               /* Get completion queue entry */
-               cq_idx = ( vnic->cq.cons++ % TXNIC_CQES );
-               offset = ( cq_idx * TXNIC_CQ_STRIDE );
-               copy_from_user ( &cqe, vnic->cq.cqe, offset, sizeof ( cqe ) );
-
-               /* Process completion queue entry */
-               switch ( cqe.common.cqe_type ) {
-               case TXNIC_CQE_TYPE_SEND:
-                       txnic_complete_sqe ( vnic, &cqe.send );
-                       break;
-               case TXNIC_CQE_TYPE_RX:
-                       txnic_complete_rqe ( vnic, &cqe.rx );
-                       break;
-               default:
-                       DBGC ( vnic, "TXNIC %s unknown completion type %d\n",
-                              vnic->name, cqe.common.cqe_type );
-                       DBGC_HDA ( vnic, user_to_phys ( vnic->cq.cqe, offset ),
-                                  &cqe, sizeof ( cqe ) );
-                       break;
-               }
-       }
-
-       /* Ring doorbell */
-       writeq ( qcount, ( vnic->regs + TXNIC_QS_CQ_DOOR(0) ) );
-}
-
-/******************************************************************************
- *
- * Virtual NIC
- *
- ******************************************************************************
- */
-
-/**
- * Open virtual NIC
- *
- * @v vnic             Virtual NIC
- * @ret rc             Return status code
- */
-static int txnic_open ( struct txnic *vnic ) {
-       int rc;
-
-       /* Create completion queue */
-       if ( ( rc = txnic_create_cq ( vnic ) ) != 0 )
-               goto err_create_cq;
-
-       /* Create send queue */
-       if ( ( rc = txnic_create_sq ( vnic ) ) != 0 )
-               goto err_create_sq;
-
-       /* Create receive queue */
-       if ( ( rc = txnic_create_rq ( vnic ) ) != 0 )
-               goto err_create_rq;
-
-       /* Refill receive queue */
-       txnic_refill_rq ( vnic );
-
-       return 0;
-
-       txnic_destroy_rq ( vnic );
- err_create_rq:
-       txnic_destroy_sq ( vnic );
- err_create_sq:
-       txnic_destroy_cq ( vnic );
- err_create_cq:
-       return rc;
-}
-
-/**
- * Close virtual NIC
- *
- * @v vnic             Virtual NIC
- */
-static void txnic_close ( struct txnic *vnic ) {
-
-       /* Destroy receive queue */
-       txnic_destroy_rq ( vnic );
-
-       /* Destroy send queue */
-       txnic_destroy_sq ( vnic );
-
-       /* Destroy completion queue */
-       txnic_destroy_cq ( vnic );
-}
-
-/**
- * Poll virtual NIC
- *
- * @v vnic             Virtual NIC
- */
-static void txnic_poll ( struct txnic *vnic ) {
-
-       /* Poll completion queue */
-       txnic_poll_cq ( vnic );
-
-       /* Refill receive queue */
-       txnic_refill_rq ( vnic );
-}
-
-/**
- * Allocate virtual NIC
- *
- * @v dev              Underlying device
- * @v membase          Register base address
- * @ret vnic           Virtual NIC, or NULL on failure
- */
-static struct txnic * txnic_alloc ( struct device *dev,
-                                   unsigned long membase ) {
-       struct net_device *netdev;
-       struct txnic *vnic;
-
-       /* Allocate network device */
-       netdev = alloc_etherdev ( sizeof ( *vnic ) );
-       if ( ! netdev )
-               goto err_alloc_netdev;
-       netdev->dev = dev;
-       vnic = netdev->priv;
-       vnic->netdev = netdev;
-       vnic->name = dev->name;
-
-       /* Allow caller to reuse netdev->priv.  (The generic virtual
-        * NIC code never assumes that netdev->priv==vnic.)
-        */
-       netdev->priv = NULL;
-
-       /* Allocate completion queue */
-       vnic->cq.cqe = umalloc ( TXNIC_CQ_SIZE );
-       if ( ! vnic->cq.cqe )
-               goto err_alloc_cq;
-
-       /* Allocate send queue */
-       vnic->sq.sqe = umalloc ( TXNIC_SQ_SIZE );
-       if ( ! vnic->sq.sqe )
-               goto err_alloc_sq;
-
-       /* Allocate receive queue */
-       vnic->rq.rqe = umalloc ( TXNIC_RQ_SIZE );
-       if ( ! vnic->rq.rqe )
-               goto err_alloc_rq;
-
-       /* Map registers */
-       vnic->regs = ioremap ( membase, TXNIC_VF_BAR_SIZE );
-       if ( ! vnic->regs )
-               goto err_ioremap;
-
-       return vnic;
-
-       iounmap ( vnic->regs );
- err_ioremap:
-       ufree ( vnic->rq.rqe );
- err_alloc_rq:
-       ufree ( vnic->sq.sqe );
- err_alloc_sq:
-       ufree ( vnic->cq.cqe );
- err_alloc_cq:
-       netdev_nullify ( netdev );
-       netdev_put ( netdev );
- err_alloc_netdev:
-       return NULL;
-}
-
-/**
- * Free virtual NIC
- *
- * @v vnic             Virtual NIC
- */
-static void txnic_free ( struct txnic *vnic ) {
-       struct net_device *netdev = vnic->netdev;
-
-       /* Unmap registers */
-       iounmap ( vnic->regs );
-
-       /* Free receive queue */
-       ufree ( vnic->rq.rqe );
-
-       /* Free send queue */
-       ufree ( vnic->sq.sqe );
-
-       /* Free completion queue */
-       ufree ( vnic->cq.cqe );
-
-       /* Free network device */
-       netdev_nullify ( netdev );
-       netdev_put ( netdev );
-}
-
-/******************************************************************************
- *
- * Logical MAC virtual NICs
- *
- ******************************************************************************
- */
-
-/**
- * Show LMAC diagnostics (for debugging)
- *
- * @v lmac             Logical MAC
- */
-static __attribute__ (( unused )) void
-txnic_lmac_diag ( struct txnic_lmac *lmac ) {
-       struct txnic *vnic = lmac->vnic;
-       uint64_t status1;
-       uint64_t status2;
-       uint64_t br_status1;
-       uint64_t br_status2;
-       uint64_t br_algn_status;
-       uint64_t br_pmd_status;
-       uint64_t an_status;
-
-       /* Read status (clearing latching bits) */
-       writeq ( BGX_SPU_STATUS1_RCV_LNK, ( lmac->regs + BGX_SPU_STATUS1 ) );
-       writeq ( BGX_SPU_STATUS2_RCVFLT, ( lmac->regs + BGX_SPU_STATUS2 ) );
-       status1 = readq ( lmac->regs + BGX_SPU_STATUS1 );
-       status2 = readq ( lmac->regs + BGX_SPU_STATUS2 );
-       DBGC ( vnic, "TXNIC %s SPU %02llx:%04llx%s%s%s\n",
-              vnic->name, status1, status2,
-              ( ( status1 & BGX_SPU_STATUS1_FLT ) ? " FLT" : "" ),
-              ( ( status1 & BGX_SPU_STATUS1_RCV_LNK ) ? " RCV_LNK" : "" ),
-              ( ( status2 & BGX_SPU_STATUS2_RCVFLT ) ? " RCVFLT" : "" ) );
-
-       /* Read BASE-R status (clearing latching bits) */
-       writeq ( ( BGX_SPU_BR_STATUS2_LATCHED_LOCK |
-                  BGX_SPU_BR_STATUS2_LATCHED_BER ),
-                ( lmac->regs + BGX_SPU_BR_STATUS2 ) );
-       br_status1 = readq ( lmac->regs + BGX_SPU_BR_STATUS1 );
-       br_status2 = readq ( lmac->regs + BGX_SPU_BR_STATUS2 );
-       DBGC ( vnic, "TXNIC %s BR %04llx:%04llx%s%s%s%s%s\n",
-              vnic->name, br_status2, br_status2,
-              ( ( br_status1 & BGX_SPU_BR_STATUS1_RCV_LNK ) ? " RCV_LNK" : ""),
-              ( ( br_status1 & BGX_SPU_BR_STATUS1_HI_BER ) ? " HI_BER" : "" ),
-              ( ( br_status1 & BGX_SPU_BR_STATUS1_BLK_LOCK ) ?
-                " BLK_LOCK" : "" ),
-              ( ( br_status2 & BGX_SPU_BR_STATUS2_LATCHED_LOCK ) ?
-                " LATCHED_LOCK" : "" ),
-              ( ( br_status2 & BGX_SPU_BR_STATUS2_LATCHED_BER ) ?
-                " LATCHED_BER" : "" ) );
-
-       /* Read BASE-R alignment status */
-       br_algn_status = readq ( lmac->regs + BGX_SPU_BR_ALGN_STATUS );
-       DBGC ( vnic, "TXNIC %s BR ALGN %016llx%s\n", vnic->name, br_algn_status,
-              ( ( br_algn_status & BGX_SPU_BR_ALGN_STATUS_ALIGND ) ?
-                " ALIGND" : "" ) );
-
-       /* Read BASE-R link training status */
-       br_pmd_status = readq ( lmac->regs + BGX_SPU_BR_PMD_STATUS );
-       DBGC ( vnic, "TXNIC %s BR PMD %04llx\n", vnic->name, br_pmd_status );
-
-       /* Read autonegotiation status (clearing latching bits) */
-       writeq ( ( BGX_SPU_AN_STATUS_PAGE_RX | BGX_SPU_AN_STATUS_LINK_STATUS ),
-                ( lmac->regs + BGX_SPU_AN_STATUS ) );
-       an_status = readq ( lmac->regs + BGX_SPU_AN_STATUS );
-       DBGC ( vnic, "TXNIC %s BR AN %04llx%s%s%s%s%s\n", vnic->name, an_status,
-              ( ( an_status & BGX_SPU_AN_STATUS_XNP_STAT ) ? " XNP_STAT" : ""),
-              ( ( an_status & BGX_SPU_AN_STATUS_PAGE_RX ) ? " PAGE_RX" : "" ),
-              ( ( an_status & BGX_SPU_AN_STATUS_AN_COMPLETE ) ?
-                " AN_COMPLETE" : "" ),
-              ( ( an_status & BGX_SPU_AN_STATUS_LINK_STATUS ) ?
-                " LINK_STATUS" : "" ),
-              ( ( an_status & BGX_SPU_AN_STATUS_LP_AN_ABLE ) ?
-                " LP_AN_ABLE" : "" ) );
-
-       /* Read transmit statistics */
-       DBGC ( vnic, "TXNIC %s TXF xc %#llx xd %#llx mc %#llx sc %#llx ok "
-              "%#llx bc %#llx mc %#llx un %#llx pa %#llx\n", vnic->name,
-              readq ( lmac->regs + BGX_CMR_TX_STAT0 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT1 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT2 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT3 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT5 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT14 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT15 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT16 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT17 ) );
-       DBGC ( vnic, "TXNIC %s TXB ok %#llx hist %#llx:%#llx:%#llx:%#llx:"
-              "%#llx:%#llx:%#llx:%#llx\n", vnic->name,
-              readq ( lmac->regs + BGX_CMR_TX_STAT4 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT6 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT7 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT8 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT9 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT10 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT11 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT12 ),
-              readq ( lmac->regs + BGX_CMR_TX_STAT13 ) );
-
-       /* Read receive statistics */
-       DBGC ( vnic, "TXNIC %s RXF ok %#llx pa %#llx nm %#llx ov %#llx er "
-              "%#llx nc %#llx\n", vnic->name,
-              readq ( lmac->regs + BGX_CMR_RX_STAT0 ),
-              readq ( lmac->regs + BGX_CMR_RX_STAT2 ),
-              readq ( lmac->regs + BGX_CMR_RX_STAT4 ),
-              readq ( lmac->regs + BGX_CMR_RX_STAT6 ),
-              readq ( lmac->regs + BGX_CMR_RX_STAT8 ),
-              readq ( lmac->regs + BGX_CMR_RX_STAT9 ) );
-       DBGC ( vnic, "TXNIC %s RXB ok %#llx pa %#llx nm %#llx ov %#llx nc "
-              "%#llx\n", vnic->name,
-              readq ( lmac->regs + BGX_CMR_RX_STAT1 ),
-              readq ( lmac->regs + BGX_CMR_RX_STAT3 ),
-              readq ( lmac->regs + BGX_CMR_RX_STAT5 ),
-              readq ( lmac->regs + BGX_CMR_RX_STAT7 ),
-              readq ( lmac->regs + BGX_CMR_RX_STAT10 ) );
-}
-
-/**
- * Update LMAC link state
- *
- * @v lmac             Logical MAC
- */
-static void txnic_lmac_update_link ( struct txnic_lmac *lmac ) {
-       struct txnic *vnic = lmac->vnic;
-       struct net_device *netdev = vnic->netdev;
-       uint64_t status1;
-
-       /* Read status (clearing latching bits) */
-       writeq ( BGX_SPU_STATUS1_RCV_LNK, ( lmac->regs + BGX_SPU_STATUS1 ) );
-       status1 = readq ( lmac->regs + BGX_SPU_STATUS1 );
-
-       /* Report link status */
-       if ( status1 & BGX_SPU_STATUS1_RCV_LNK ) {
-               netdev_link_up ( netdev );
-       } else {
-               netdev_link_down ( netdev );
-       }
-}
-
-/**
- * Poll LMAC link state
- *
- * @v lmac             Logical MAC
- */
-static void txnic_lmac_poll_link ( struct txnic_lmac *lmac ) {
-       struct txnic *vnic = lmac->vnic;
-       uint64_t intr;
-
-       /* Get interrupt status */
-       intr = readq ( lmac->regs + BGX_SPU_INT );
-       if ( ! intr )
-               return;
-       DBGC ( vnic, "TXNIC %s INT %04llx%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
-              vnic->name, intr,
-              ( ( intr & BGX_SPU_INT_TRAINING_FAIL ) ? " TRAINING_FAIL" : "" ),
-              ( ( intr & BGX_SPU_INT_TRAINING_DONE ) ? " TRAINING_DONE" : "" ),
-              ( ( intr & BGX_SPU_INT_AN_COMPLETE ) ? " AN_COMPLETE" : "" ),
-              ( ( intr & BGX_SPU_INT_AN_LINK_GOOD ) ? " AN_LINK_GOOD" : "" ),
-              ( ( intr & BGX_SPU_INT_AN_PAGE_RX ) ? " AN_PAGE_RX" : "" ),
-              ( ( intr & BGX_SPU_INT_FEC_UNCORR ) ? " FEC_UNCORR" : "" ),
-              ( ( intr & BGX_SPU_INT_FEC_CORR ) ? " FEC_CORR" : "" ),
-              ( ( intr & BGX_SPU_INT_BIP_ERR ) ? " BIP_ERR" : "" ),
-              ( ( intr & BGX_SPU_INT_DBG_SYNC ) ? " DBG_SYNC" : "" ),
-              ( ( intr & BGX_SPU_INT_ALGNLOS ) ? " ALGNLOS" : "" ),
-              ( ( intr & BGX_SPU_INT_SYNLOS ) ? " SYNLOS" : "" ),
-              ( ( intr & BGX_SPU_INT_BITLCKLS ) ? " BITLCKLS" : "" ),
-              ( ( intr & BGX_SPU_INT_ERR_BLK ) ? " ERR_BLK" : "" ),
-              ( ( intr & BGX_SPU_INT_RX_LINK_DOWN ) ? " RX_LINK_DOWN" : "" ),
-              ( ( intr & BGX_SPU_INT_RX_LINK_UP ) ? " RX_LINK_UP" : "" ) );
-
-       /* Clear interrupt status */
-       writeq ( intr, ( lmac->regs + BGX_SPU_INT ) );
-
-       /* Update link state */
-       txnic_lmac_update_link ( lmac );
-}
-
-/**
- * Reset LMAC
- *
- * @v lmac             Logical MAC
- */
-static void txnic_lmac_reset ( struct txnic_lmac *lmac ) {
-       struct txnic_bgx *bgx = lmac->bgx;
-       struct txnic_pf *pf = bgx->pf;
-       void *qsregs = ( pf->regs + TXNIC_PF_QS ( lmac->idx ) );
-
-       /* There is no reset available for the physical function
-        * aspects of a virtual NIC; we have to explicitly reload a
-        * sensible set of default values.
-        */
-       writeq ( 0, ( qsregs + TXNIC_PF_QS_CFG ) );
-       writeq ( 0, ( qsregs + TXNIC_PF_QS_RQ_CFG(0) ) );
-       writeq ( 0, ( qsregs + TXNIC_PF_QS_RQ_DROP_CFG(0) ) );
-       writeq ( 0, ( qsregs + TXNIC_PF_QS_RQ_BP_CFG(0) ) );
-       writeq ( 0, ( qsregs + TXNIC_PF_QS_SQ_CFG(0) ) );
-}
-
-/**
- * Open network device
- *
- * @v netdev           Network device
- * @ret rc             Return status code
- */
-static int txnic_lmac_open ( struct net_device *netdev ) {
-       struct txnic_lmac *lmac = netdev->priv;
-       struct txnic_bgx *bgx = lmac->bgx;
-       struct txnic_pf *pf = bgx->pf;
-       struct txnic *vnic = lmac->vnic;
-       unsigned int vnic_idx = lmac->idx;
-       unsigned int chan_idx = TXNIC_CHAN_IDX ( vnic_idx );
-       unsigned int tl4_idx = TXNIC_TL4_IDX ( vnic_idx );
-       unsigned int tl3_idx = TXNIC_TL3_IDX ( vnic_idx );
-       unsigned int tl2_idx = TXNIC_TL2_IDX ( vnic_idx );
-       void *lmregs = ( pf->regs + TXNIC_PF_LMAC ( vnic_idx ) );
-       void *chregs = ( pf->regs + TXNIC_PF_CHAN ( chan_idx ) );
-       void *qsregs = ( pf->regs + TXNIC_PF_QS ( vnic_idx ) );
-       size_t max_pkt_size;
-       int rc;
-
-       /* Configure channel/match parse indices */
-       writeq ( ( TXNIC_PF_MPI_CFG_VNIC ( vnic_idx ) |
-                  TXNIC_PF_MPI_CFG_RSSI_BASE ( vnic_idx ) ),
-                ( TXNIC_PF_MPI_CFG ( vnic_idx ) + pf->regs ) );
-       writeq ( ( TXNIC_PF_RSSI_RQ_RQ_QS ( vnic_idx ) ),
-                ( TXNIC_PF_RSSI_RQ ( vnic_idx ) + pf->regs ) );
-
-       /* Configure LMAC */
-       max_pkt_size = ( netdev->max_pkt_len + 4 /* possible VLAN */ );
-       writeq ( ( TXNIC_PF_LMAC_CFG_ADJUST_DEFAULT |
-                  TXNIC_PF_LMAC_CFG_MIN_PKT_SIZE ( ETH_ZLEN ) ),
-                ( TXNIC_PF_LMAC_CFG + lmregs ) );
-       writeq ( ( TXNIC_PF_LMAC_CFG2_MAX_PKT_SIZE ( max_pkt_size ) ),
-                ( TXNIC_PF_LMAC_CFG2 + lmregs ) );
-       writeq ( ( TXNIC_PF_LMAC_CREDIT_CC_UNIT_CNT_DEFAULT |
-                  TXNIC_PF_LMAC_CREDIT_CC_PACKET_CNT_DEFAULT |
-                  TXNIC_PF_LMAC_CREDIT_CC_ENABLE ),
-                ( TXNIC_PF_LMAC_CREDIT + lmregs ) );
-
-       /* Configure channels */
-       writeq ( ( TXNIC_PF_CHAN_TX_CFG_BP_ENA ),
-                ( TXNIC_PF_CHAN_TX_CFG + chregs ) );
-       writeq ( ( TXNIC_PF_CHAN_RX_CFG_CPI_BASE ( vnic_idx ) ),
-                ( TXNIC_PF_CHAN_RX_CFG + chregs ) );
-       writeq ( ( TXNIC_PF_CHAN_RX_BP_CFG_ENA |
-                  TXNIC_PF_CHAN_RX_BP_CFG_BPID ( vnic_idx ) ),
-                ( TXNIC_PF_CHAN_RX_BP_CFG + chregs ) );
-
-       /* Configure traffic limiters */
-       writeq ( ( TXNIC_PF_TL2_CFG_RR_QUANTUM_DEFAULT ),
-                ( TXNIC_PF_TL2_CFG ( tl2_idx ) + pf->regs ) );
-       writeq ( ( TXNIC_PF_TL3_CFG_RR_QUANTUM_DEFAULT ),
-                ( TXNIC_PF_TL3_CFG ( tl3_idx ) + pf->regs ) );
-       writeq ( ( TXNIC_PF_TL3_CHAN_CHAN ( chan_idx ) ),
-                ( TXNIC_PF_TL3_CHAN ( tl3_idx ) + pf->regs ) );
-       writeq ( ( TXNIC_PF_TL4_CFG_SQ_QS ( vnic_idx ) |
-                  TXNIC_PF_TL4_CFG_RR_QUANTUM_DEFAULT ),
-                ( TXNIC_PF_TL4_CFG ( tl4_idx ) + pf->regs ) );
-
-       /* Configure send queue */
-       writeq ( ( TXNIC_PF_QS_SQ_CFG_CQ_QS ( vnic_idx ) ),
-                ( TXNIC_PF_QS_SQ_CFG(0) + qsregs ) );
-       writeq ( ( TXNIC_PF_QS_SQ_CFG2_TL4 ( tl4_idx ) ),
-                ( TXNIC_PF_QS_SQ_CFG2(0) + qsregs ) );
-
-       /* Configure receive queue */
-       writeq ( ( TXNIC_PF_QS_RQ_CFG_CACHING_ALL |
-                  TXNIC_PF_QS_RQ_CFG_CQ_QS ( vnic_idx ) |
-                  TXNIC_PF_QS_RQ_CFG_RBDR_CONT_QS ( vnic_idx ) |
-                  TXNIC_PF_QS_RQ_CFG_RBDR_STRT_QS ( vnic_idx ) ),
-                ( TXNIC_PF_QS_RQ_CFG(0) + qsregs ) );
-       writeq ( ( TXNIC_PF_QS_RQ_BP_CFG_RBDR_BP_ENA |
-                  TXNIC_PF_QS_RQ_BP_CFG_CQ_BP_ENA |
-                  TXNIC_PF_QS_RQ_BP_CFG_BPID ( vnic_idx ) ),
-                ( TXNIC_PF_QS_RQ_BP_CFG(0) + qsregs ) );
-
-       /* Enable queue set */
-       writeq ( ( TXNIC_PF_QS_CFG_ENA | TXNIC_PF_QS_CFG_VNIC ( vnic_idx ) ),
-                ( TXNIC_PF_QS_CFG + qsregs ) );
-
-       /* Open virtual NIC */
-       if ( ( rc = txnic_open ( vnic ) ) != 0 )
-               goto err_open;
-
-       /* Update link state */
-       txnic_lmac_update_link ( lmac );
-
-       return 0;
-
-       txnic_close ( vnic );
- err_open:
-       writeq ( 0, ( qsregs + TXNIC_PF_QS_CFG ) );
-       return rc;
-}
-
-/**
- * Close network device
- *
- * @v netdev           Network device
- */
-static void txnic_lmac_close ( struct net_device *netdev ) {
-       struct txnic_lmac *lmac = netdev->priv;
-       struct txnic_bgx *bgx = lmac->bgx;
-       struct txnic_pf *pf = bgx->pf;
-       struct txnic *vnic = lmac->vnic;
-       void *qsregs = ( pf->regs + TXNIC_PF_QS ( lmac->idx ) );
-
-       /* Close virtual NIC */
-       txnic_close ( vnic );
-
-       /* Disable queue set */
-       writeq ( 0, ( qsregs + TXNIC_PF_QS_CFG ) );
-}
-
-/**
- * Transmit packet
- *
- * @v netdev           Network device
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int txnic_lmac_transmit ( struct net_device *netdev,
-                                struct io_buffer *iobuf ) {
-       struct txnic_lmac *lmac = netdev->priv;
-       struct txnic *vnic = lmac->vnic;
-
-       return txnic_send ( vnic, iobuf );
-}
-
-/**
- * Poll network device
- *
- * @v netdev           Network device
- */
-static void txnic_lmac_poll ( struct net_device *netdev ) {
-       struct txnic_lmac *lmac = netdev->priv;
-       struct txnic *vnic = lmac->vnic;
-
-       /* Poll virtual NIC */
-       txnic_poll ( vnic );
-
-       /* Poll link state */
-       txnic_lmac_poll_link ( lmac );
-}
-
-/** Network device operations */
-static struct net_device_operations txnic_lmac_operations = {
-       .open = txnic_lmac_open,
-       .close = txnic_lmac_close,
-       .transmit = txnic_lmac_transmit,
-       .poll = txnic_lmac_poll,
-};
-
-/**
- * Probe logical MAC virtual NIC
- *
- * @v lmac             Logical MAC
- * @ret rc             Return status code
- */
-static int txnic_lmac_probe ( struct txnic_lmac *lmac ) {
-       struct txnic_bgx *bgx = lmac->bgx;
-       struct txnic_pf *pf = bgx->pf;
-       struct txnic *vnic;
-       struct net_device *netdev;
-       unsigned long membase;
-       int rc;
-
-       /* Sanity check */
-       assert ( lmac->vnic == NULL );
-
-       /* Calculate register base address */
-       membase = ( pf->vf_membase + ( lmac->idx * pf->vf_stride ) );
-
-       /* Allocate and initialise network device */
-       vnic = txnic_alloc ( &bgx->pci->dev, membase );
-       if ( ! vnic ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       netdev = vnic->netdev;
-       netdev_init ( netdev, &txnic_lmac_operations );
-       netdev->priv = lmac;
-       lmac->vnic = vnic;
-
-       /* Reset device */
-       txnic_lmac_reset ( lmac );
-
-       /* Set MAC address */
-       memcpy ( netdev->hw_addr, lmac->mac.raw, ETH_ALEN );
-
-       /* Register network device */
-       if ( ( rc = register_netdev ( netdev ) ) != 0 )
-               goto err_register;
-       vnic->name = netdev->name;
-       DBGC ( TXNICCOL ( pf ), "TXNIC %d/%d/%d is %s (%s)\n", pf->node,
-              bgx->idx, lmac->idx, vnic->name, eth_ntoa ( lmac->mac.raw ) );
-
-       /* Update link state */
-       txnic_lmac_update_link ( lmac );
-
-       return 0;
-
-       unregister_netdev ( netdev );
- err_register:
-       txnic_lmac_reset ( lmac );
-       txnic_free ( vnic );
-       lmac->vnic = NULL;
- err_alloc:
-       return rc;
-}
-
-/**
- * Remove logical MAC virtual NIC
- *
- * @v lmac             Logical MAC
- */
-static void txnic_lmac_remove ( struct txnic_lmac *lmac ) {
-
-       /* Sanity check */
-       assert ( lmac->vnic != NULL );
-
-       /* Unregister network device */
-       unregister_netdev ( lmac->vnic->netdev );
-
-       /* Reset device */
-       txnic_lmac_reset ( lmac );
-
-       /* Free virtual NIC */
-       txnic_free ( lmac->vnic );
-       lmac->vnic = NULL;
-}
-
-/**
- * Probe all LMACs on a BGX Ethernet interface
- *
- * @v pf               Physical function
- * @v bgx              BGX Ethernet interface
- * @ret rc             Return status code
- */
-static int txnic_lmac_probe_all ( struct txnic_pf *pf, struct txnic_bgx *bgx ) {
-       unsigned int bgx_idx;
-       int lmac_idx;
-       int count;
-       int rc;
-
-       /* Sanity checks */
-       bgx_idx = bgx->idx;
-       assert ( pf->node == bgx->node );
-       assert ( pf->bgx[bgx_idx] == NULL );
-       assert ( bgx->pf == NULL );
-
-       /* Associate BGX with physical function */
-       pf->bgx[bgx_idx] = bgx;
-       bgx->pf = pf;
-
-       /* Probe all LMACs */
-       count = bgx->count;
-       for ( lmac_idx = 0 ; lmac_idx < count ; lmac_idx++ ) {
-               if ( ( rc = txnic_lmac_probe ( &bgx->lmac[lmac_idx] ) ) != 0 )
-                       goto err_probe;
-       }
-
-       return 0;
-
-       lmac_idx = count;
- err_probe:
-       for ( lmac_idx-- ; lmac_idx >= 0 ; lmac_idx-- )
-               txnic_lmac_remove ( &bgx->lmac[lmac_idx] );
-       pf->bgx[bgx_idx] = NULL;
-       bgx->pf = NULL;
-       return rc;
-}
-
-/**
- * Remove all LMACs on a BGX Ethernet interface
- *
- * @v pf               Physical function
- * @v bgx              BGX Ethernet interface
- */
-static void txnic_lmac_remove_all ( struct txnic_pf *pf,
-                                   struct txnic_bgx *bgx ) {
-       unsigned int lmac_idx;
-
-       /* Sanity checks */
-       assert ( pf->bgx[bgx->idx] == bgx );
-       assert ( bgx->pf == pf );
-
-       /* Remove all LMACs */
-       for ( lmac_idx = 0 ; lmac_idx < bgx->count ; lmac_idx++ )
-               txnic_lmac_remove ( &bgx->lmac[lmac_idx] );
-
-       /* Disassociate BGX from physical function */
-       pf->bgx[bgx->idx] = NULL;
-       bgx->pf = NULL;
-}
-
-/******************************************************************************
- *
- * NIC physical function interface
- *
- ******************************************************************************
- */
-
-/**
- * Probe PCI device
- *
- * @v pci              PCI device
- * @ret rc             Return status code
- */
-static int txnic_pf_probe ( struct pci_device *pci ) {
-       struct txnic_pf *pf;
-       struct txnic_bgx *bgx;
-       unsigned long membase;
-       unsigned int i;
-       int rc;
-
-       /* Allocate and initialise structure */
-       pf = zalloc ( sizeof ( *pf ) );
-       if ( ! pf ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       pf->pci = pci;
-       pci_set_drvdata ( pci, pf );
-
-       /* Get base addresses */
-       membase = pciea_bar_start ( pci, PCIEA_BEI_BAR_0 );
-       pf->vf_membase = pciea_bar_start ( pci, PCIEA_BEI_VF_BAR_0 );
-       pf->vf_stride = pciea_bar_size ( pci, PCIEA_BEI_VF_BAR_0 );
-
-       /* Calculate node ID */
-       pf->node = txnic_address_node ( membase );
-       DBGC ( TXNICCOL ( pf ), "TXNIC %d/*/* PF %s at %#lx (VF %#lx+%#lx)\n",
-              pf->node, pci->dev.name, membase, pf->vf_membase, pf->vf_stride);
-
-       /* Fix up PCI device */
-       adjust_pci_device ( pci );
-
-       /* Map registers */
-       pf->regs = ioremap ( membase, TXNIC_PF_BAR_SIZE );
-       if ( ! pf->regs ) {
-               rc = -ENODEV;
-               goto err_ioremap;
-       }
-
-       /* Configure physical function */
-       writeq ( TXNIC_PF_CFG_ENA, ( pf->regs + TXNIC_PF_CFG ) );
-       writeq ( ( TXNIC_PF_BP_CFG_BP_POLL_ENA |
-                  TXNIC_PF_BP_CFG_BP_POLL_DLY_DEFAULT ),
-                ( pf->regs + TXNIC_PF_BP_CFG ) );
-       for ( i = 0 ; i < TXNIC_NUM_BGX ; i++ ) {
-               writeq ( ( TXNIC_PF_INTF_SEND_CFG_BLOCK_BGX |
-                          TXNIC_PF_INTF_SEND_CFG_BLOCK ( i ) ),
-                        ( pf->regs + TXNIC_PF_INTF_SEND_CFG ( i ) ) );
-               writeq ( ( TXNIC_PF_INTF_BP_CFG_BP_ENA |
-                          TXNIC_PF_INTF_BP_CFG_BP_ID_BGX |
-                          TXNIC_PF_INTF_BP_CFG_BP_ID ( i ) ),
-                        ( pf->regs + TXNIC_PF_INTF_BP_CFG ( i ) ) );
-       }
-       writeq ( ( TXNIC_PF_PKIND_CFG_LENERR_EN |
-                  TXNIC_PF_PKIND_CFG_MAXLEN_DISABLE |
-                  TXNIC_PF_PKIND_CFG_MINLEN_DISABLE ),
-                ( pf->regs + TXNIC_PF_PKIND_CFG(0) ) );
-
-       /* Add to list of physical functions */
-       list_add_tail ( &pf->list, &txnic_pfs );
-
-       /* Probe all LMACs, if applicable */
-       list_for_each_entry ( bgx, &txnic_bgxs, list ) {
-               if ( bgx->node != pf->node )
-                       continue;
-               if ( ( rc = txnic_lmac_probe_all ( pf, bgx ) ) != 0 )
-                       goto err_probe;
-       }
-
-       return 0;
-
- err_probe:
-       for ( i = 0 ; i < TXNIC_NUM_BGX ; i++ ) {
-               if ( pf->bgx[i] )
-                       txnic_lmac_remove_all ( pf, pf->bgx[i] );
-       }
-       list_del ( &pf->list );
-       writeq ( 0, ( pf->regs + TXNIC_PF_CFG ) );
-       iounmap ( pf->regs );
- err_ioremap:
-       free ( pf );
- err_alloc:
-       return rc;
-}
-
-/**
- * Remove PCI device
- *
- * @v pci              PCI device
- */
-static void txnic_pf_remove ( struct pci_device *pci ) {
-       struct txnic_pf *pf = pci_get_drvdata ( pci );
-       unsigned int i;
-
-       /* Remove all LMACs, if applicable */
-       for ( i = 0 ; i < TXNIC_NUM_BGX ; i++ ) {
-               if ( pf->bgx[i] )
-                       txnic_lmac_remove_all ( pf, pf->bgx[i] );
-       }
-
-       /* Remove from list of physical functions */
-       list_del ( &pf->list );
-
-       /* Disable physical function */
-       writeq ( 0, ( pf->regs + TXNIC_PF_CFG ) );
-
-       /* Unmap registers */
-       iounmap ( pf->regs );
-
-       /* Free physical function */
-       free ( pf );
-}
-
-/** NIC physical function PCI device IDs */
-static struct pci_device_id txnic_pf_ids[] = {
-       PCI_ROM ( 0x177d, 0xa01e, "thunder-pf", "ThunderX NIC PF", 0 ),
-};
-
-/** NIC physical function PCI driver */
-struct pci_driver txnic_pf_driver __pci_driver = {
-       .ids = txnic_pf_ids,
-       .id_count = ( sizeof ( txnic_pf_ids ) / sizeof ( txnic_pf_ids[0] ) ),
-       .probe = txnic_pf_probe,
-       .remove = txnic_pf_remove,
-};
-
-/******************************************************************************
- *
- * BGX interface
- *
- ******************************************************************************
- */
-
-/** LMAC types */
-static struct txnic_lmac_type txnic_lmac_types[] = {
-       [TXNIC_LMAC_XAUI] = {
-               .name = "XAUI",
-               .count = 1,
-               .lane_to_sds = 0xe4,
-       },
-       [TXNIC_LMAC_RXAUI] = {
-               .name = "RXAUI",
-               .count = 2,
-               .lane_to_sds = 0x0e04,
-       },
-       [TXNIC_LMAC_10G_R] = {
-               .name = "10GBASE-R",
-               .count = 4,
-               .lane_to_sds = 0x00000000,
-       },
-       [TXNIC_LMAC_40G_R] = {
-               .name = "40GBASE-R",
-               .count = 1,
-               .lane_to_sds = 0xe4,
-       },
-};
-
-/**
- * Detect BGX Ethernet interface LMAC type
- *
- * @v bgx              BGX Ethernet interface
- * @ret type           LMAC type, or negative error
- */
-static int txnic_bgx_detect ( struct txnic_bgx *bgx ) {
-       uint64_t config;
-       uint64_t br_pmd_control;
-       uint64_t rx_lmacs;
-       unsigned int type;
-
-       /* We assume that the early (pre-UEFI) firmware will have
-        * configured at least the LMAC 0 type and use of link
-        * training, and may have overridden the number of LMACs.
-        */
-
-       /* Determine type from LMAC 0 */
-       config = readq ( bgx->regs + BGX_CMR_CONFIG );
-       type = BGX_CMR_CONFIG_LMAC_TYPE_GET ( config );
-       if ( ( type >= ( sizeof ( txnic_lmac_types ) /
-                        sizeof ( txnic_lmac_types[0] ) ) ) ||
-            ( txnic_lmac_types[type].count == 0 ) ) {
-               DBGC ( TXNICCOL ( bgx ), "TXNIC %d/%d/* BGX unknown type %d\n",
-                      bgx->node, bgx->idx, type );
-               return -ENOTTY;
-       }
-       bgx->type = &txnic_lmac_types[type];
-
-       /* Check whether link training is required */
-       br_pmd_control = readq ( bgx->regs + BGX_SPU_BR_PMD_CONTROL );
-       bgx->training =
-               ( !! ( br_pmd_control & BGX_SPU_BR_PMD_CONTROL_TRAIN_EN ) );
-
-       /* Determine number of LMACs */
-       rx_lmacs = readq ( bgx->regs + BGX_CMR_RX_LMACS );
-       bgx->count = BGX_CMR_RX_LMACS_LMACS_GET ( rx_lmacs );
-       if ( ( bgx->count == TXNIC_NUM_LMAC ) &&
-            ( bgx->type->count != TXNIC_NUM_LMAC ) ) {
-               DBGC ( TXNICCOL ( bgx ), "TXNIC %d/%d/* assuming %d LMACs\n",
-                      bgx->node, bgx->idx, bgx->type->count );
-               bgx->count = bgx->type->count;
-       }
-
-       return type;
-}
-
-/**
- * Initialise BGX Ethernet interface
- *
- * @v bgx              BGX Ethernet interface
- * @v type             LMAC type
- */
-static void txnic_bgx_init ( struct txnic_bgx *bgx, unsigned int type ) {
-       uint64_t global_config;
-       uint32_t lane_to_sds;
-       unsigned int i;
-
-       /* Set number of LMACs */
-       writeq ( BGX_CMR_RX_LMACS_LMACS_SET ( bgx->count ),
-                ( bgx->regs + BGX_CMR_RX_LMACS ) );
-       writeq ( BGX_CMR_TX_LMACS_LMACS_SET ( bgx->count ),
-                ( bgx->regs + BGX_CMR_TX_LMACS ) );
-
-       /* Set LMAC types and lane mappings, and disable all LMACs */
-       lane_to_sds = bgx->type->lane_to_sds;
-       for ( i = 0 ; i < bgx->count ; i++ ) {
-               writeq ( ( BGX_CMR_CONFIG_LMAC_TYPE_SET ( type ) |
-                          BGX_CMR_CONFIG_LANE_TO_SDS ( lane_to_sds ) ),
-                        ( bgx->regs + BGX_LMAC ( i ) + BGX_CMR_CONFIG ) );
-               lane_to_sds >>= 8;
-       }
-
-       /* Reset all MAC address filtering */
-       for ( i = 0 ; i < TXNIC_NUM_DMAC ; i++ )
-               writeq ( 0, ( bgx->regs + BGX_CMR_RX_DMAC_CAM ( i ) ) );
-
-       /* Reset NCSI steering */
-       for ( i = 0 ; i < TXNIC_NUM_STEERING ; i++ )
-               writeq ( 0, ( bgx->regs + BGX_CMR_RX_STEERING ( i ) ) );
-
-       /* Enable backpressure to all channels */
-       writeq ( BGX_CMR_CHAN_MSK_AND_ALL ( bgx->count ),
-                ( bgx->regs + BGX_CMR_CHAN_MSK_AND ) );
-
-       /* Strip FCS */
-       global_config = readq ( bgx->regs + BGX_CMR_GLOBAL_CONFIG );
-       global_config |= BGX_CMR_GLOBAL_CONFIG_FCS_STRIP;
-       writeq ( global_config, ( bgx->regs + BGX_CMR_GLOBAL_CONFIG ) );
-}
-
-/**
- * Get MAC address
- *
- * @v lmac             Logical MAC
- */
-static void txnic_bgx_mac ( struct txnic_lmac *lmac ) {
-       struct txnic_bgx *bgx = lmac->bgx;
-       BOARD_CFG *boardcfg;
-       NODE_CFG *nodecfg;
-       BGX_CFG *bgxcfg;
-       LMAC_CFG *lmaccfg;
-
-       /* Extract MAC from Board Configuration protocol, if available */
-       if ( txcfg ) {
-               boardcfg = txcfg->BoardConfig;
-               nodecfg = &boardcfg->Node[ bgx->node % MAX_NODES ];
-               bgxcfg = &nodecfg->BgxCfg[ bgx->idx % BGX_PER_NODE_COUNT ];
-               lmaccfg = &bgxcfg->Lmacs[ lmac->idx % LMAC_PER_BGX_COUNT ];
-               lmac->mac.be64 = cpu_to_be64 ( lmaccfg->MacAddress );
-       } else {
-               DBGC ( TXNICCOL ( bgx ), "TXNIC %d/%d/%d has no board "
-                      "configuration protocol\n", bgx->node, bgx->idx,
-                      lmac->idx );
-       }
-
-       /* Use random MAC address if none available */
-       if ( ! lmac->mac.be64 ) {
-               DBGC ( TXNICCOL ( bgx ), "TXNIC %d/%d/%d has no MAC address\n",
-                      bgx->node, bgx->idx, lmac->idx );
-               eth_random_addr ( lmac->mac.raw );
-       }
-}
-
-/**
- * Initialise Super PHY Unit (SPU)
- *
- * @v lmac             Logical MAC
- */
-static void txnic_bgx_spu_init ( struct txnic_lmac *lmac ) {
-       struct txnic_bgx *bgx = lmac->bgx;
-
-       /* Reset PHY */
-       writeq ( BGX_SPU_CONTROL1_RESET, ( lmac->regs + BGX_SPU_CONTROL1 ) );
-       mdelay ( BGX_SPU_RESET_DELAY_MS );
-
-       /* Power down PHY */
-       writeq ( BGX_SPU_CONTROL1_LO_PWR, ( lmac->regs + BGX_SPU_CONTROL1 ) );
-
-       /* Configure training, if applicable */
-       if ( bgx->training ) {
-               writeq ( 0, ( lmac->regs + BGX_SPU_BR_PMD_LP_CUP ) );
-               writeq ( 0, ( lmac->regs + BGX_SPU_BR_PMD_LD_CUP ) );
-               writeq ( 0, ( lmac->regs + BGX_SPU_BR_PMD_LD_REP ) );
-               writeq ( BGX_SPU_BR_PMD_CONTROL_TRAIN_EN,
-                        ( lmac->regs + BGX_SPU_BR_PMD_CONTROL ) );
-       }
-
-       /* Disable forward error correction */
-       writeq ( 0, ( lmac->regs + BGX_SPU_FEC_CONTROL ) );
-
-       /* Disable autonegotiation */
-       writeq ( 0, ( lmac->regs + BGX_SPU_AN_CONTROL ) );
-
-       /* Power up PHY */
-       writeq ( 0, ( lmac->regs + BGX_SPU_CONTROL1 ) );
-}
-
-/**
- * Initialise LMAC
- *
- * @v bgx              BGX Ethernet interface
- * @v lmac_idx         LMAC index
- */
-static void txnic_bgx_lmac_init ( struct txnic_bgx *bgx,
-                                 unsigned int lmac_idx ) {
-       struct txnic_lmac *lmac = &bgx->lmac[lmac_idx];
-       uint64_t config;
-
-       /* Record associated BGX */
-       lmac->bgx = bgx;
-
-       /* Set register base address (already mapped) */
-       lmac->regs = ( bgx->regs + BGX_LMAC ( lmac_idx ) );
-
-       /* Calculate virtual NIC index */
-       lmac->idx = TXNIC_VNIC_IDX ( bgx->idx, lmac_idx );
-
-       /* Set MAC address */
-       txnic_bgx_mac ( lmac );
-
-       /* Initialise PHY */
-       txnic_bgx_spu_init ( lmac );
-
-       /* Accept all multicasts and broadcasts */
-       writeq ( ( BGX_CMR_RX_DMAC_CTL_MCST_MODE_ACCEPT |
-                  BGX_CMR_RX_DMAC_CTL_BCST_ACCEPT ),
-                ( lmac->regs + BGX_CMR_RX_DMAC_CTL ) );
-
-       /* Enable LMAC */
-       config = readq ( lmac->regs + BGX_CMR_CONFIG );
-       config |= ( BGX_CMR_CONFIG_ENABLE |
-                   BGX_CMR_CONFIG_DATA_PKT_RX_EN |
-                   BGX_CMR_CONFIG_DATA_PKT_TX_EN );
-       writeq ( config, ( lmac->regs + BGX_CMR_CONFIG ) );
-}
-
-/**
- * Probe PCI device
- *
- * @v pci              PCI device
- * @ret rc             Return status code
- */
-static int txnic_bgx_probe ( struct pci_device *pci ) {
-       struct txnic_bgx *bgx;
-       struct txnic_pf *pf;
-       unsigned long membase;
-       unsigned int i;
-       int type;
-       int rc;
-
-       /* Allocate and initialise structure */
-       bgx = zalloc ( sizeof ( *bgx ) );
-       if ( ! bgx ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       bgx->pci = pci;
-       pci_set_drvdata ( pci, bgx );
-
-       /* Get base address */
-       membase = pciea_bar_start ( pci, PCIEA_BEI_BAR_0 );
-
-       /* Calculate node ID and index */
-       bgx->node = txnic_address_node ( membase );
-       bgx->idx = txnic_address_bgx ( membase );
-
-       /* Fix up PCI device */
-       adjust_pci_device ( pci );
-
-       /* Map registers */
-       bgx->regs = ioremap ( membase, TXNIC_BGX_BAR_SIZE );
-       if ( ! bgx->regs ) {
-               rc = -ENODEV;
-               goto err_ioremap;
-       }
-
-       /* Detect LMAC type */
-       if ( ( type = txnic_bgx_detect ( bgx ) ) < 0 ) {
-               rc = type;
-               goto err_detect;
-       }
-       DBGC ( TXNICCOL ( bgx ), "TXNIC %d/%d/* BGX %s at %#lx %dx %s%s\n",
-              bgx->node, bgx->idx, pci->dev.name, membase, bgx->count,
-              bgx->type->name, ( bgx->training ? "(training)" : "" ) );
-
-       /* Initialise interface */
-       txnic_bgx_init ( bgx, type );
-
-       /* Initialise all LMACs */
-       for ( i = 0 ; i < bgx->count ; i++ )
-               txnic_bgx_lmac_init ( bgx, i );
-
-       /* Add to list of BGX devices */
-       list_add_tail ( &bgx->list, &txnic_bgxs );
-
-       /* Probe all LMACs, if applicable */
-       list_for_each_entry ( pf, &txnic_pfs, list ) {
-               if ( pf->node != bgx->node )
-                       continue;
-               if ( ( rc = txnic_lmac_probe_all ( pf, bgx ) ) != 0 )
-                       goto err_probe;
-       }
-
-       return 0;
-
-       if ( bgx->pf )
-               txnic_lmac_remove_all ( bgx->pf, bgx );
-       list_del ( &bgx->list );
- err_probe:
- err_detect:
-       iounmap ( bgx->regs );
- err_ioremap:
-       free ( bgx );
- err_alloc:
-       return rc;
-}
-
-/**
- * Remove PCI device
- *
- * @v pci              PCI device
- */
-static void txnic_bgx_remove ( struct pci_device *pci ) {
-       struct txnic_bgx *bgx = pci_get_drvdata ( pci );
-
-       /* Remove all LMACs, if applicable */
-       if ( bgx->pf )
-               txnic_lmac_remove_all ( bgx->pf, bgx );
-
-       /* Remove from list of BGX devices */
-       list_del ( &bgx->list );
-
-       /* Unmap registers */
-       iounmap ( bgx->regs );
-
-       /* Free BGX device */
-       free ( bgx );
-}
-
-/** BGX PCI device IDs */
-static struct pci_device_id txnic_bgx_ids[] = {
-       PCI_ROM ( 0x177d, 0xa026, "thunder-bgx", "ThunderX BGX", 0 ),
-};
-
-/** BGX PCI driver */
-struct pci_driver txnic_bgx_driver __pci_driver = {
-       .ids = txnic_bgx_ids,
-       .id_count = ( sizeof ( txnic_bgx_ids ) / sizeof ( txnic_bgx_ids[0] ) ),
-       .probe = txnic_bgx_probe,
-       .remove = txnic_bgx_remove,
-};
diff --git a/roms/ipxe/src/drivers/net/thunderx.h b/roms/ipxe/src/drivers/net/thunderx.h
deleted file mode 100644 (file)
index 410daf6..0000000
+++ /dev/null
@@ -1,949 +0,0 @@
-#ifndef _THUNDERX_H
-#define _THUNDERX_H
-
-/** @file
- *
- * Cavium ThunderX Ethernet driver
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <ipxe/list.h>
-#include <ipxe/netdevice.h>
-#include <ipxe/uaccess.h>
-
-/******************************************************************************
- *
- * Address space
- *
- ******************************************************************************
- */
-
-/** Size of a cache line */
-#define TXNIC_LINE_SIZE 128
-
-/** Virtual function BAR size */
-#define TXNIC_VF_BAR_SIZE 0x200000UL
-
-/** Physical function BAR size */
-#define TXNIC_PF_BAR_SIZE 0x40000000UL
-
-/** BGX BAR size */
-#define TXNIC_BGX_BAR_SIZE 0x400000UL
-
-/** Maximum number of BGX Ethernet interfaces (per node) */
-#define TXNIC_NUM_BGX 2
-
-/** Maximum number of Logical MACs (per BGX) */
-#define TXNIC_NUM_LMAC 4
-
-/** Maximum number of destination MAC addresses (per BGX) */
-#define TXNIC_NUM_DMAC 32
-
-/** Maximum number of steering rules (per BGX) */
-#define TXNIC_NUM_STEERING 8
-
-/**
- * Calculate node ID
- *
- * @v addr             PCI BAR base address
- * @ret node           Node ID
- */
-static inline unsigned int txnic_address_node ( uint64_t addr ) {
-
-       /* Node ID is in bits [45:44] of the hardcoded BAR address */
-       return ( ( addr >> 44 ) & 0x3 );
-}
-
-/**
- * Calculate BGX Ethernet interface index
- *
- * @v addr             PCI BAR base address
- * @ret index          Index
- */
-static inline unsigned int txnic_address_bgx ( uint64_t addr ) {
-
-       /* Index is in bit 24 of the hardcoded BAR address */
-       return ( ( addr >> 24 ) & 0x1 );
-}
-
-/******************************************************************************
- *
- * Send queue
- *
- ******************************************************************************
- */
-
-/** Send queue configuration */
-#define TXNIC_QS_SQ_CFG(q)             ( ( (q) << 18 ) | 0x010800 )
-#define TXNIC_QS_SQ_CFG_ENA                    (                1ULL   << 19 )
-#define TXNIC_QS_SQ_CFG_RESET                  (                1ULL   << 17 )
-#define TXNIC_QS_SQ_CFG_QSIZE(sz)              ( ( ( uint64_t ) (sz) ) <<  8 )
-#define TXNIC_QS_SQ_CFG_QSIZE_1K \
-       TXNIC_QS_SQ_CFG_QSIZE ( 0 )
-
-/** Send queue base address */
-#define TXNIC_QS_SQ_BASE(q)            ( ( (q) << 18 ) | 0x010820 )
-
-/** Send queue head pointer */
-#define TXNIC_QS_SQ_HEAD(q)            ( ( (q) << 18 ) | 0x010828 )
-
-/** Send queue tail pointer */
-#define TXNIC_QS_SQ_TAIL(q)            ( ( (q) << 18 ) | 0x010830 )
-
-/** Send queue doorbell */
-#define TXNIC_QS_SQ_DOOR(q)            ( ( (q) << 18 ) | 0x010838 )
-
-/** Send queue status */
-#define TXNIC_QS_SQ_STATUS(q)          ( ( (q) << 18 ) | 0x010840 )
-#define TXNIC_QS_SQ_STATUS_STOPPED             (                1ULL   << 21 )
-
-/** Maximum time to wait for a send queue to stop
- *
- * This is a policy decision.
- */
-#define TXNIC_SQ_STOP_MAX_WAIT_MS 100
-
-/** A send header subdescriptor */
-struct txnic_send_header {
-       /** Total length */
-       uint32_t total;
-       /** Unused */
-       uint8_t unused_a[2];
-       /** Subdescriptor count */
-       uint8_t subdcnt;
-       /** Flags */
-       uint8_t flags;
-       /** Unused */
-       uint8_t unused_b[8];
-} __attribute__ (( packed ));
-
-/** Flags for send header subdescriptor
- *
- * These comprise SUBDC=0x1 and PNC=0x1.
- */
-#define TXNIC_SEND_HDR_FLAGS 0x14
-
-/** A send gather subdescriptor */
-struct txnic_send_gather {
-       /** Size */
-       uint16_t size;
-       /** Unused */
-       uint8_t unused[5];
-       /** Flags */
-       uint8_t flags;
-       /** Address */
-       uint64_t addr;
-} __attribute__ (( packed ));
-
-/** Flags for send gather subdescriptor
- *
- * These comprise SUBDC=0x4 and LD_TYPE=0x0.
- */
-#define TXNIC_SEND_GATHER_FLAGS 0x40
-
-/** A send queue entry
- *
- * Each send queue entry comprises a single send header subdescriptor
- * and a single send gather subdescriptor.
- */
-struct txnic_sqe {
-       /** Send header descriptor */
-       struct txnic_send_header hdr;
-       /** Send gather descriptor */
-       struct txnic_send_gather gather;
-} __attribute__ (( packed ));
-
-/** Number of subdescriptors per send queue entry */
-#define TXNIC_SQE_SUBDESCS ( sizeof ( struct txnic_sqe ) / \
-                            sizeof ( struct txnic_send_header ) )
-
-/** Number of send queue entries
- *
- * The minimum send queue size is 1024 entries.
- */
-#define TXNIC_SQES ( 1024 / TXNIC_SQE_SUBDESCS )
-
-/** Send queue maximum fill level
- *
- * This is a policy decision.
- */
-#define TXNIC_SQ_FILL 32
-
-/** Send queue alignment */
-#define TXNIC_SQ_ALIGN TXNIC_LINE_SIZE
-
-/** Send queue stride */
-#define TXNIC_SQ_STRIDE sizeof ( struct txnic_sqe )
-
-/** Send queue size */
-#define TXNIC_SQ_SIZE ( TXNIC_SQES * TXNIC_SQ_STRIDE )
-
-/** A send queue */
-struct txnic_sq {
-       /** Producer counter */
-       unsigned int prod;
-       /** Consumer counter */
-       unsigned int cons;
-       /** Send queue entries */
-       userptr_t sqe;
-};
-
-/******************************************************************************
- *
- * Receive queue
- *
- ******************************************************************************
- */
-
-/** Receive queue configuration */
-#define TXNIC_QS_RQ_CFG(q)             ( ( (q) << 18 ) | 0x010600 )
-#define TXNIC_QS_RQ_CFG_ENA                    (                1ULL   <<  1 )
-
-/** Maximum time to wait for a receive queue to disable
- *
- * This is a policy decision.
- */
-#define TXNIC_RQ_DISABLE_MAX_WAIT_MS 100
-
-/** Receive buffer descriptor ring configuration */
-#define TXNIC_QS_RBDR_CFG(q)           ( ( (q) << 18 ) | 0x010c00 )
-#define TXNIC_QS_RBDR_CFG_ENA                  (                1ULL   << 44 )
-#define TXNIC_QS_RBDR_CFG_RESET                        (                1ULL   << 43 )
-#define TXNIC_QS_RBDR_CFG_QSIZE(sz)            ( ( ( uint64_t ) (sz) ) << 32 )
-#define TXNIC_QS_RBDR_CFG_QSIZE_8K \
-       TXNIC_QS_RBDR_CFG_QSIZE ( 0 )
-#define TXNIC_QS_RBDR_CFG_LINES(sz)            ( ( ( uint64_t ) (sz) ) <<  0 )
-
-/** Receive buffer descriptor ring base address */
-#define TXNIC_QS_RBDR_BASE(q)          ( ( (q) << 18 ) | 0x010c20 )
-
-/** Receive buffer descriptor ring head pointer */
-#define TXNIC_QS_RBDR_HEAD(q)          ( ( (q) << 18 ) | 0x010c28 )
-
-/** Receive buffer descriptor ring tail pointer */
-#define TXNIC_QS_RBDR_TAIL(q)          ( ( (q) << 18 ) | 0x010c30 )
-
-/** Receive buffer descriptor ring doorbell */
-#define TXNIC_QS_RBDR_DOOR(q)          ( ( (q) << 18 ) | 0x010c38 )
-
-/** Receive buffer descriptor ring status 0 */
-#define TXNIC_QS_RBDR_STATUS0(q)       ( ( (q) << 18 ) | 0x010c40 )
-
-/** A receive buffer descriptor ring entry */
-struct txnic_rbdr_entry {
-       /** Address */
-       uint64_t addr;
-} __attribute__ (( packed ));
-
-/** A receive queue entry */
-struct txnic_rqe {
-       /** Receive buffer descriptor ring entry */
-       struct txnic_rbdr_entry rbdre;
-} __attribute__ (( packed ));
-
-/** Number of receive queue entries
- *
- * The minimum receive queue size is 8192 entries.
- */
-#define TXNIC_RQES 8192
-
-/** Receive queue maximum fill level
- *
- * This is a policy decision.  Must not exceed TXNIC_RQES.
- */
-#define TXNIC_RQ_FILL 32
-
-/** Receive queue entry size
- *
- * This is a policy decision.
- */
-#define TXNIC_RQE_SIZE ( ( ETH_DATA_ALIGN + ETH_FRAME_LEN +            \
-                          4 /* VLAN */ + TXNIC_LINE_SIZE - 1 )         \
-                        & ~( TXNIC_LINE_SIZE - 1 ) )
-
-/** Receive queue alignment */
-#define TXNIC_RQ_ALIGN TXNIC_LINE_SIZE
-
-/** Receive queue stride */
-#define TXNIC_RQ_STRIDE sizeof ( struct txnic_rqe )
-
-/** Receive queue size */
-#define TXNIC_RQ_SIZE ( TXNIC_RQES * TXNIC_RQ_STRIDE )
-
-/** A receive queue */
-struct txnic_rq {
-       /** Producer counter */
-       unsigned int prod;
-       /** Consumer counter */
-       unsigned int cons;
-       /** Receive queue entries */
-       userptr_t rqe;
-       /** I/O buffers */
-       struct io_buffer *iobuf[TXNIC_RQ_FILL];
-};
-
-/******************************************************************************
- *
- * Completion queue
- *
- ******************************************************************************
- */
-
-/** Completion queue configuration */
-#define TXNIC_QS_CQ_CFG(q)             ( ( (q) << 18 ) | 0x010400 )
-#define TXNIC_QS_CQ_CFG_ENA                    (                1ULL   << 42 )
-#define TXNIC_QS_CQ_CFG_RESET                  (                1ULL   << 41 )
-#define TXNIC_QS_CQ_CFG_QSIZE(sz)              ( ( ( uint64_t ) (sz) ) << 32 )
-#define TXNIC_QS_CQ_CFG_QSIZE_256 \
-       TXNIC_QS_CQ_CFG_QSIZE ( 7 )
-
-/** Maximum time to wait for a completion queue to disable
- *
- * This is a policy decision.
- */
-#define TXNIC_CQ_DISABLE_MAX_WAIT_MS 100
-
-/** Completion queue base address */
-#define TXNIC_QS_CQ_BASE(q)            ( ( (q) << 18 ) | 0x010420 )
-
-/** Completion queue head pointer */
-#define TXNIC_QS_CQ_HEAD(q)            ( ( (q) << 18 ) | 0x010428 )
-
-/** Completion queue tail pointer */
-#define TXNIC_QS_CQ_TAIL(q)            ( ( (q) << 18 ) | 0x010430 )
-
-/** Completion queue doorbell */
-#define TXNIC_QS_CQ_DOOR(q)            ( ( (q) << 18 ) | 0x010438 )
-
-/** Completion queue status */
-#define TXNIC_QS_CQ_STATUS(q)          ( ( (q) << 18 ) | 0x010440 )
-#define TXNIC_QS_CQ_STATUS_QCOUNT(status) \
-       ( ( (status) >> 0 ) & 0xffff )
-
-/** Completion queue status 2 */
-#define TXNIC_QS_CQ_STATUS2(q)         ( ( (q) << 18 ) | 0x010448 )
-
-/** A send completion queue entry */
-struct txnic_cqe_send {
-       /** Status */
-       uint8_t send_status;
-       /** Unused */
-       uint8_t unused[4];
-       /** Send queue entry pointer */
-       uint16_t sqe_ptr;
-       /** Type */
-       uint8_t cqe_type;
-} __attribute__ (( packed ));
-
-/** Send completion queue entry type */
-#define TXNIC_CQE_TYPE_SEND 0x80
-
-/** A receive completion queue entry */
-struct txnic_cqe_rx {
-       /** Error opcode */
-       uint8_t errop;
-       /** Unused */
-       uint8_t unused_a[6];
-       /** Type */
-       uint8_t cqe_type;
-       /** Unused */
-       uint8_t unused_b[1];
-       /** Padding */
-       uint8_t apad;
-       /** Unused */
-       uint8_t unused_c[4];
-       /** Length */
-       uint16_t len;
-} __attribute__ (( packed ));
-
-/** Receive completion queue entry type */
-#define TXNIC_CQE_TYPE_RX 0x20
-
-/** Applied padding */
-#define TXNIC_CQE_RX_APAD_LEN( apad ) ( (apad) >> 5 )
-
-/** Completion queue entry common fields */
-struct txnic_cqe_common {
-       /** Unused */
-       uint8_t unused_a[7];
-       /** Type */
-       uint8_t cqe_type;
-} __attribute__ (( packed ));
-
-/** A completion queue entry */
-union txnic_cqe {
-       /** Common fields */
-       struct txnic_cqe_common common;
-       /** Send completion */
-       struct txnic_cqe_send send;
-       /** Receive completion */
-       struct txnic_cqe_rx rx;
-};
-
-/** Number of completion queue entries
- *
- * The minimum completion queue size is 256 entries.
- */
-#define TXNIC_CQES 256
-
-/** Completion queue alignment */
-#define TXNIC_CQ_ALIGN 512
-
-/** Completion queue stride */
-#define TXNIC_CQ_STRIDE 512
-
-/** Completion queue size */
-#define TXNIC_CQ_SIZE ( TXNIC_CQES * TXNIC_CQ_STRIDE )
-
-/** A completion queue */
-struct txnic_cq {
-       /** Consumer counter */
-       unsigned int cons;
-       /** Completion queue entries */
-       userptr_t cqe;
-};
-
-/******************************************************************************
- *
- * Virtual NIC
- *
- ******************************************************************************
- */
-
-/** A virtual NIC */
-struct txnic {
-       /** Registers */
-       void *regs;
-       /** Device name (for debugging) */
-       const char *name;
-       /** Network device */
-       struct net_device *netdev;
-
-       /** Send queue */
-       struct txnic_sq sq;
-       /** Receive queue */
-       struct txnic_rq rq;
-       /** Completion queue */
-       struct txnic_cq cq;
-};
-
-/******************************************************************************
- *
- * Physical function
- *
- ******************************************************************************
- */
-
-/** Physical function configuration */
-#define TXNIC_PF_CFG                   0x000000
-#define TXNIC_PF_CFG_ENA                       (                1ULL   <<  0 )
-
-/** Backpressure configuration */
-#define TXNIC_PF_BP_CFG                        0x000080
-#define TXNIC_PF_BP_CFG_BP_POLL_ENA            (                1ULL   <<  6 )
-#define TXNIC_PF_BP_CFG_BP_POLL_DLY(dl)                ( ( ( uint64_t ) (dl) ) <<  0 )
-#define TXNIC_PF_BP_CFG_BP_POLL_DLY_DEFAULT \
-       TXNIC_PF_BP_CFG_BP_POLL_DLY ( 3 )
-
-/** Interface send configuration */
-#define TXNIC_PF_INTF_SEND_CFG(in)     ( ( (in) << 8 ) | 0x000200 )
-#define TXNIC_PF_INTF_SEND_CFG_BLOCK_BGX       (                1ULL   <<  3 )
-#define TXNIC_PF_INTF_SEND_CFG_BLOCK(bl)       ( ( ( uint64_t ) (bl) ) <<  0 )
-
-/** Interface backpressure configuration */
-#define TXNIC_PF_INTF_BP_CFG(in)       ( ( (in) << 8 ) | 0x000208 )
-#define TXNIC_PF_INTF_BP_CFG_BP_ENA            (                1ULL   << 63 )
-#define TXNIC_PF_INTF_BP_CFG_BP_ID_BGX         (                1ULL   <<  3 )
-#define TXNIC_PF_INTF_BP_CFG_BP_ID(bp)         ( ( ( uint64_t ) (bp) ) <<  0 )
-
-/** Port kind configuration */
-#define TXNIC_PF_PKIND_CFG(pk)         ( ( (pk) << 3 ) | 0x000600 )
-#define TXNIC_PF_PKIND_CFG_LENERR_EN           (                1ULL   << 33 )
-#define TXNIC_PF_PKIND_CFG_MAXLEN(ct)          ( ( ( uint64_t ) (ct) ) << 16 )
-#define TXNIC_PF_PKIND_CFG_MAXLEN_DISABLE \
-       TXNIC_PF_PKIND_CFG_MAXLEN ( 0xffff )
-#define TXNIC_PF_PKIND_CFG_MINLEN(ct)          ( ( ( uint64_t ) (ct) ) <<  0 )
-#define TXNIC_PF_PKIND_CFG_MINLEN_DISABLE \
-       TXNIC_PF_PKIND_CFG_MINLEN ( 0x0000 )
-
-/** Match parse index configuration */
-#define TXNIC_PF_MPI_CFG(ix)           ( ( (ix) << 3 ) | 0x210000 )
-#define TXNIC_PF_MPI_CFG_VNIC(vn)              ( ( ( uint64_t ) (vn) ) << 24 )
-#define TXNIC_PF_MPI_CFG_RSSI_BASE(ix)         ( ( ( uint64_t ) (ix) ) <<  0 )
-
-/** RSS indirection receive queue */
-#define TXNIC_PF_RSSI_RQ(ix)           ( ( (ix) << 3 ) | 0x220000 )
-#define TXNIC_PF_RSSI_RQ_RQ_QS(qs)             ( ( ( uint64_t ) (qs) ) << 3 )
-
-/** LMAC registers */
-#define TXNIC_PF_LMAC(lm)              ( ( (lm) << 3 ) | 0x240000 )
-
-/** LMAC configuration */
-#define TXNIC_PF_LMAC_CFG              0x000000
-#define TXNIC_PF_LMAC_CFG_ADJUST(ad)           ( ( ( uint64_t ) (ad) ) <<  8 )
-#define TXNIC_PF_LMAC_CFG_ADJUST_DEFAULT \
-       TXNIC_PF_LMAC_CFG_ADJUST ( 6 )
-#define TXNIC_PF_LMAC_CFG_MIN_PKT_SIZE(sz)     ( ( ( uint64_t ) (sz) ) <<  0 )
-
-/** LMAC configuration 2 */
-#define TXNIC_PF_LMAC_CFG2             0x000100
-#define TXNIC_PF_LMAC_CFG2_MAX_PKT_SIZE(sz)    ( ( ( uint64_t ) (sz) ) <<  0 )
-
-/** LMAC credit */
-#define TXNIC_PF_LMAC_CREDIT           0x004000
-#define TXNIC_PF_LMAC_CREDIT_CC_UNIT_CNT(ct)   ( ( ( uint64_t ) (ct) ) << 12 )
-#define TXNIC_PF_LMAC_CREDIT_CC_UNIT_CNT_DEFAULT \
-       TXNIC_PF_LMAC_CREDIT_CC_UNIT_CNT ( 192 )
-#define TXNIC_PF_LMAC_CREDIT_CC_PACKET_CNT(ct) ( ( ( uint64_t ) (ct) ) <<  2 )
-#define TXNIC_PF_LMAC_CREDIT_CC_PACKET_CNT_DEFAULT \
-       TXNIC_PF_LMAC_CREDIT_CC_PACKET_CNT ( 511 )
-#define TXNIC_PF_LMAC_CREDIT_CC_ENABLE         (                1ULL   <<  1 )
-
-/** Channel registers */
-#define TXNIC_PF_CHAN(ch)              ( ( (ch) << 3 ) | 0x400000 )
-
-/** Channel transmit configuration */
-#define TXNIC_PF_CHAN_TX_CFG           0x000000
-#define TXNIC_PF_CHAN_TX_CFG_BP_ENA            (                1ULL   <<  0 )
-
-/** Channel receive configuration */
-#define TXNIC_PF_CHAN_RX_CFG           0x020000
-#define TXNIC_PF_CHAN_RX_CFG_CPI_BASE(ix)      ( ( ( uint64_t ) (ix) ) << 48 )
-
-/** Channel receive backpressure configuration */
-#define TXNIC_PF_CHAN_RX_BP_CFG                0x080000
-#define TXNIC_PF_CHAN_RX_BP_CFG_ENA            (                1ULL   << 63 )
-#define TXNIC_PF_CHAN_RX_BP_CFG_BPID(bp)       ( ( ( uint64_t ) (bp) ) <<  0 )
-
-/** Traffic limiter 2 configuration */
-#define TXNIC_PF_TL2_CFG(tl)           ( ( (tl) << 3 ) | 0x500000 )
-#define TXNIC_PF_TL2_CFG_RR_QUANTUM(rr)                ( ( ( uint64_t ) (rr) ) <<  0 )
-#define TXNIC_PF_TL2_CFG_RR_QUANTUM_DEFAULT \
-       TXNIC_PF_TL2_CFG_RR_QUANTUM ( 0x905 )
-
-/** Traffic limiter 3 configuration */
-#define TXNIC_PF_TL3_CFG(tl)           ( ( (tl) << 3 ) | 0x600000 )
-#define TXNIC_PF_TL3_CFG_RR_QUANTUM(rr)                ( ( ( uint64_t ) (rr) ) <<  0 )
-#define TXNIC_PF_TL3_CFG_RR_QUANTUM_DEFAULT \
-       TXNIC_PF_TL3_CFG_RR_QUANTUM ( 0x905 )
-
-/** Traffic limiter 3 channel mapping */
-#define TXNIC_PF_TL3_CHAN(tl)          ( ( (tl) << 3 ) | 0x620000 )
-#define TXNIC_PF_TL3_CHAN_CHAN(ch)             ( ( (ch) & 0x7f ) << 0 )
-
-/** Traffic limiter 4 configuration */
-#define TXNIC_PF_TL4_CFG(tl)           ( ( (tl) << 3 ) | 0x800000 )
-#define TXNIC_PF_TL4_CFG_SQ_QS(qs)             ( ( ( uint64_t ) (qs) ) << 27 )
-#define TXNIC_PF_TL4_CFG_RR_QUANTUM(rr)                ( ( ( uint64_t ) (rr) ) <<  0 )
-#define TXNIC_PF_TL4_CFG_RR_QUANTUM_DEFAULT \
-       TXNIC_PF_TL4_CFG_RR_QUANTUM ( 0x905 )
-
-/** Queue set registers */
-#define TXNIC_PF_QS(qs)                        ( ( (qs) << 21 ) | 0x20000000UL )
-
-/** Queue set configuration */
-#define TXNIC_PF_QS_CFG                        0x010000
-#define TXNIC_PF_QS_CFG_ENA                    (                1ULL   << 31 )
-#define TXNIC_PF_QS_CFG_VNIC(vn)               ( ( ( uint64_t ) (vn) ) <<  0 )
-
-/** Receive queue configuration */
-#define TXNIC_PF_QS_RQ_CFG(q)          ( ( (q) << 18 ) | 0x010400 )
-#define TXNIC_PF_QS_RQ_CFG_CACHING(cx)         ( ( ( uint64_t ) (cx) ) << 26 )
-#define TXNIC_PF_QS_RQ_CFG_CACHING_ALL \
-       TXNIC_PF_QS_RQ_CFG_CACHING ( 1 )
-#define TXNIC_PF_QS_RQ_CFG_CQ_QS(qs)           ( ( ( uint64_t ) (qs) ) << 19 )
-#define TXNIC_PF_QS_RQ_CFG_RBDR_CONT_QS(qs)    ( ( ( uint64_t ) (qs) ) <<  9 )
-#define TXNIC_PF_QS_RQ_CFG_RBDR_STRT_QS(qs)    ( ( ( uint64_t ) (qs) ) <<  1 )
-
-/** Receive queue drop configuration */
-#define TXNIC_PF_QS_RQ_DROP_CFG(q)     ( ( (q) << 18 ) | 0x010420 )
-
-/** Receive queue backpressure configuration */
-#define TXNIC_PF_QS_RQ_BP_CFG(q)       ( ( (q) << 18 ) | 0x010500 )
-#define TXNIC_PF_QS_RQ_BP_CFG_RBDR_BP_ENA      (                1ULL   << 63 )
-#define TXNIC_PF_QS_RQ_BP_CFG_CQ_BP_ENA                (                1ULL   << 62 )
-#define TXNIC_PF_QS_RQ_BP_CFG_BPID(bp)         ( ( ( uint64_t ) (bp) ) <<  0 )
-
-/** Send queue configuration */
-#define TXNIC_PF_QS_SQ_CFG(q)          ( ( (q) << 18 ) | 0x010c00 )
-#define TXNIC_PF_QS_SQ_CFG_CQ_QS(qs)           ( ( ( uint64_t ) (qs) ) <<  3 )
-
-/** Send queue configuration 2 */
-#define TXNIC_PF_QS_SQ_CFG2(q)         ( ( (q) << 18 ) | 0x010c08 )
-#define TXNIC_PF_QS_SQ_CFG2_TL4(tl)            ( ( ( uint64_t ) (tl) ) <<  0 )
-
-/** A physical function */
-struct txnic_pf {
-       /** Registers */
-       void *regs;
-       /** PCI device */
-       struct pci_device *pci;
-       /** Node ID */
-       unsigned int node;
-
-       /** Virtual function BAR base */
-       unsigned long vf_membase;
-       /** Virtual function BAR stride */
-       unsigned long vf_stride;
-
-       /** List of physical functions */
-       struct list_head list;
-       /** BGX Ethernet interfaces (if known) */
-       struct txnic_bgx *bgx[TXNIC_NUM_BGX];
-};
-
-/**
- * Calculate virtual NIC index
- *
- * @v bgx_idx          BGX Ethernet interface index
- * @v lmac_idx         Logical MAC index
- * @ret vnic_idx       Virtual NIC index
- */
-#define TXNIC_VNIC_IDX( bgx_idx, lmac_idx ) \
-       ( ( (bgx_idx) * TXNIC_NUM_LMAC ) + (lmac_idx) )
-
-/**
- * Calculate BGX Ethernet interface index
- *
- * @v vnic_idx         Virtual NIC index
- * @ret bgx_idx                BGX Ethernet interface index
- */
-#define TXNIC_BGX_IDX( vnic_idx ) ( (vnic_idx) / TXNIC_NUM_LMAC )
-
-/**
- * Calculate logical MAC index
- *
- * @v vnic_idx         Virtual NIC index
- * @ret lmac_idx       Logical MAC index
- */
-#define TXNIC_LMAC_IDX( vnic_idx ) ( (vnic_idx) % TXNIC_NUM_LMAC )
-
-/**
- * Calculate traffic limiter 2 index
- *
- * @v vnic_idx         Virtual NIC index
- * @v tl2_idx          Traffic limiter 2 index
- */
-#define TXNIC_TL2_IDX( vnic_idx ) ( (vnic_idx) << 3 )
-
-/**
- * Calculate traffic limiter 3 index
- *
- * @v vnic_idx         Virtual NIC index
- * @v tl3_idx          Traffic limiter 3 index
- */
-#define TXNIC_TL3_IDX( vnic_idx ) ( (vnic_idx) << 5 )
-
-/**
- * Calculate traffic limiter 4 index
- *
- * @v vnic_idx         Virtual NIC index
- * @v tl4_idx          Traffic limiter 4 index
- */
-#define TXNIC_TL4_IDX( vnic_idx ) ( (vnic_idx) << 7 )
-
-/**
- * Calculate channel index
- *
- * @v vnic_idx         Virtual NIC index
- * @v chan_idx         Channel index
- */
-#define TXNIC_CHAN_IDX( vnic_idx ) ( ( TXNIC_BGX_IDX (vnic_idx) << 7 ) | \
-                                    ( TXNIC_LMAC_IDX (vnic_idx) << 4 ) )
-
-/******************************************************************************
- *
- * BGX Ethernet interface
- *
- ******************************************************************************
- */
-
-/** Per-LMAC registers */
-#define BGX_LMAC(lm)                   ( ( (lm) << 20 ) | 0x00000000UL )
-
-/** CMR configuration */
-#define BGX_CMR_CONFIG                 0x000000
-#define BGX_CMR_CONFIG_ENABLE                  (                1ULL   << 15 )
-#define BGX_CMR_CONFIG_DATA_PKT_RX_EN          (                1ULL   << 14 )
-#define BGX_CMR_CONFIG_DATA_PKT_TX_EN          (                1ULL   << 13 )
-#define BGX_CMR_CONFIG_LMAC_TYPE_GET(config) \
-       ( ( (config) >> 8 ) & 0x7 )
-#define BGX_CMR_CONFIG_LMAC_TYPE_SET(ty)       ( ( ( uint64_t ) (ty) ) <<  8 )
-#define BGX_CMR_CONFIG_LANE_TO_SDS(ls)         ( ( ( uint64_t ) (ls) ) <<  0 )
-
-/** CMR global configuration */
-#define BGX_CMR_GLOBAL_CONFIG          0x000008
-#define BGX_CMR_GLOBAL_CONFIG_FCS_STRIP                (                1ULL   <<  6 )
-
-/** CMR receive statistics 0 */
-#define BGX_CMR_RX_STAT0               0x000070
-
-/** CMR receive statistics 1 */
-#define BGX_CMR_RX_STAT1               0x000078
-
-/** CMR receive statistics 2 */
-#define BGX_CMR_RX_STAT2               0x000080
-
-/** CMR receive statistics 3 */
-#define BGX_CMR_RX_STAT3               0x000088
-
-/** CMR receive statistics 4 */
-#define BGX_CMR_RX_STAT4               0x000090
-
-/** CMR receive statistics 5 */
-#define BGX_CMR_RX_STAT5               0x000098
-
-/** CMR receive statistics 6 */
-#define BGX_CMR_RX_STAT6               0x0000a0
-
-/** CMR receive statistics 7 */
-#define BGX_CMR_RX_STAT7               0x0000a8
-
-/** CMR receive statistics 8 */
-#define BGX_CMR_RX_STAT8               0x0000b0
-
-/** CMR receive statistics 9 */
-#define BGX_CMR_RX_STAT9               0x0000b8
-
-/** CMR receive statistics 10 */
-#define BGX_CMR_RX_STAT10              0x0000c0
-
-/** CMR destination MAC control */
-#define BGX_CMR_RX_DMAC_CTL            0x0000e8
-#define BGX_CMR_RX_DMAC_CTL_MCST_MODE(md)      ( ( ( uint64_t ) (md) ) <<  1 )
-#define BGX_CMR_RX_DMAC_CTL_MCST_MODE_ACCEPT \
-       BGX_CMR_RX_DMAC_CTL_MCST_MODE ( 1 )
-#define BGX_CMR_RX_DMAC_CTL_BCST_ACCEPT                (                1ULL   <<  0 )
-
-/** CMR destination MAC CAM */
-#define BGX_CMR_RX_DMAC_CAM(i)         ( ( (i) << 3 ) | 0x000200 )
-
-/** CMR receive steering */
-#define BGX_CMR_RX_STEERING(i)         ( ( (i) << 3 ) | 0x000300 )
-
-/** CMR backpressure channel mask AND */
-#define BGX_CMR_CHAN_MSK_AND           0x000450
-#define BGX_CMR_CHAN_MSK_AND_ALL(count) \
-       ( 0xffffffffffffffffULL >> ( 16 * ( 4 - (count) ) ) )
-
-/** CMR transmit statistics 0 */
-#define BGX_CMR_TX_STAT0               0x000600
-
-/** CMR transmit statistics 1 */
-#define BGX_CMR_TX_STAT1               0x000608
-
-/** CMR transmit statistics 2 */
-#define BGX_CMR_TX_STAT2               0x000610
-
-/** CMR transmit statistics 3 */
-#define BGX_CMR_TX_STAT3               0x000618
-
-/** CMR transmit statistics 4 */
-#define BGX_CMR_TX_STAT4               0x000620
-
-/** CMR transmit statistics 5 */
-#define BGX_CMR_TX_STAT5               0x000628
-
-/** CMR transmit statistics 6 */
-#define BGX_CMR_TX_STAT6               0x000630
-
-/** CMR transmit statistics 7 */
-#define BGX_CMR_TX_STAT7               0x000638
-
-/** CMR transmit statistics 8 */
-#define BGX_CMR_TX_STAT8               0x000640
-
-/** CMR transmit statistics 9 */
-#define BGX_CMR_TX_STAT9               0x000648
-
-/** CMR transmit statistics 10 */
-#define BGX_CMR_TX_STAT10              0x000650
-
-/** CMR transmit statistics 11 */
-#define BGX_CMR_TX_STAT11              0x000658
-
-/** CMR transmit statistics 12 */
-#define BGX_CMR_TX_STAT12              0x000660
-
-/** CMR transmit statistics 13 */
-#define BGX_CMR_TX_STAT13              0x000668
-
-/** CMR transmit statistics 14 */
-#define BGX_CMR_TX_STAT14              0x000670
-
-/** CMR transmit statistics 15 */
-#define BGX_CMR_TX_STAT15              0x000678
-
-/** CMR transmit statistics 16 */
-#define BGX_CMR_TX_STAT16              0x000680
-
-/** CMR transmit statistics 17 */
-#define BGX_CMR_TX_STAT17              0x000688
-
-/** CMR receive logical MACs */
-#define BGX_CMR_RX_LMACS               0x000468
-#define BGX_CMR_RX_LMACS_LMACS_GET(lmacs) \
-       ( ( (lmacs) >> 0 ) & 0x7 )
-#define BGX_CMR_RX_LMACS_LMACS_SET(ct)         ( ( ( uint64_t ) (ct) ) <<  0 )
-
-/** CMR transmit logical MACs */
-#define BGX_CMR_TX_LMACS               0x001000
-#define BGX_CMR_TX_LMACS_LMACS_GET(lmacs) \
-       ( ( (lmacs) >> 0 ) & 0x7 )
-#define BGX_CMR_TX_LMACS_LMACS_SET(ct)         ( ( ( uint64_t ) (ct) ) <<  0 )
-
-/** SPU control 1 */
-#define BGX_SPU_CONTROL1               0x010000
-#define BGX_SPU_CONTROL1_RESET                 (                1ULL   << 15 )
-#define BGX_SPU_CONTROL1_LO_PWR                        (                1ULL   << 11 )
-
-/** SPU reset delay */
-#define BGX_SPU_RESET_DELAY_MS 10
-
-/** SPU status 1 */
-#define BGX_SPU_STATUS1                        0x010008
-#define BGX_SPU_STATUS1_FLT                    (                1ULL   <<  7 )
-#define BGX_SPU_STATUS1_RCV_LNK                        (                1ULL   <<  2 )
-
-/** SPU status 2 */
-#define BGX_SPU_STATUS2                        0x010020
-#define BGX_SPU_STATUS2_RCVFLT                 (                1ULL   << 10 )
-
-/** SPU BASE-R status 1 */
-#define BGX_SPU_BR_STATUS1             0x010030
-#define BGX_SPU_BR_STATUS1_RCV_LNK             (                1ULL   << 12 )
-#define BGX_SPU_BR_STATUS1_HI_BER              (                1ULL   <<  1 )
-#define BGX_SPU_BR_STATUS1_BLK_LOCK            (                1ULL   <<  0 )
-
-/** SPU BASE-R status 2 */
-#define BGX_SPU_BR_STATUS2             0x010038
-#define BGX_SPU_BR_STATUS2_LATCHED_LOCK                (                1ULL   << 15 )
-#define BGX_SPU_BR_STATUS2_LATCHED_BER         (                1ULL   << 14 )
-
-/** SPU BASE-R alignment status */
-#define BGX_SPU_BR_ALGN_STATUS         0x010050
-#define BGX_SPU_BR_ALGN_STATUS_ALIGND          (                1ULL   << 12 )
-
-/** SPU BASE-R link training control */
-#define BGX_SPU_BR_PMD_CONTROL         0x010068
-#define BGX_SPU_BR_PMD_CONTROL_TRAIN_EN                (                1ULL   <<  1 )
-
-/** SPU BASE-R link training status */
-#define BGX_SPU_BR_PMD_STATUS          0x010070
-
-/** SPU link partner coefficient update */
-#define BGX_SPU_BR_PMD_LP_CUP          0x010078
-
-/** SPU local device coefficient update */
-#define BGX_SPU_BR_PMD_LD_CUP          0x010088
-
-/** SPU local device status report */
-#define BGX_SPU_BR_PMD_LD_REP          0x010090
-
-/** SPU forward error correction control */
-#define BGX_SPU_FEC_CONTROL            0x0100a0
-
-/** SPU autonegotation control */
-#define BGX_SPU_AN_CONTROL             0x0100c8
-
-/** SPU autonegotiation status */
-#define BGX_SPU_AN_STATUS              0x0100d0
-#define BGX_SPU_AN_STATUS_XNP_STAT             (                1ULL   <<  7 )
-#define BGX_SPU_AN_STATUS_PAGE_RX              (                1ULL   <<  6 )
-#define BGX_SPU_AN_STATUS_AN_COMPLETE          (                1ULL   <<  5 )
-#define BGX_SPU_AN_STATUS_LINK_STATUS          (                1ULL   <<  2 )
-#define BGX_SPU_AN_STATUS_LP_AN_ABLE           (                1ULL   <<  0 )
-
-/** SPU interrupt */
-#define BGX_SPU_INT                    0x010220
-#define BGX_SPU_INT_TRAINING_FAIL              (                1ULL   << 14 )
-#define BGX_SPU_INT_TRAINING_DONE              (                1ULL   << 13 )
-#define BGX_SPU_INT_AN_COMPLETE                        (                1ULL   << 12 )
-#define BGX_SPU_INT_AN_LINK_GOOD               (                1ULL   << 11 )
-#define BGX_SPU_INT_AN_PAGE_RX                 (                1ULL   << 10 )
-#define BGX_SPU_INT_FEC_UNCORR                 (                1ULL   <<  9 )
-#define BGX_SPU_INT_FEC_CORR                   (                1ULL   <<  8 )
-#define BGX_SPU_INT_BIP_ERR                    (                1ULL   <<  7 )
-#define BGX_SPU_INT_DBG_SYNC                   (                1ULL   <<  6 )
-#define BGX_SPU_INT_ALGNLOS                    (                1ULL   <<  5 )
-#define BGX_SPU_INT_SYNLOS                     (                1ULL   <<  4 )
-#define BGX_SPU_INT_BITLCKLS                   (                1ULL   <<  3 )
-#define BGX_SPU_INT_ERR_BLK                    (                1ULL   <<  2 )
-#define BGX_SPU_INT_RX_LINK_DOWN               (                1ULL   <<  1 )
-#define BGX_SPU_INT_RX_LINK_UP                 (                1ULL   <<  0 )
-
-/** LMAC types */
-enum txnic_lmac_types {
-       TXNIC_LMAC_SGMII        = 0x0,          /**< SGMII/1000BASE-X */
-       TXNIC_LMAC_XAUI         = 0x1,          /**< 10GBASE-X/XAUI or DXAUI */
-       TXNIC_LMAC_RXAUI        = 0x2,          /**< Reduced XAUI */
-       TXNIC_LMAC_10G_R        = 0x3,          /**< 10GBASE-R */
-       TXNIC_LMAC_40G_R        = 0x4,          /**< 40GBASE-R */
-};
-
-/** An LMAC type */
-struct txnic_lmac_type {
-       /** Name */
-       const char *name;
-       /** Number of LMACs */
-       uint8_t count;
-       /** Lane-to-SDS mapping */
-       uint32_t lane_to_sds;
-};
-
-/** An LMAC address */
-union txnic_lmac_address {
-       struct {
-               uint8_t pad[2];
-               uint8_t raw[ETH_ALEN];
-       } __attribute__ (( packed ));
-       uint64_t be64;
-};
-
-/** A Logical MAC (LMAC) */
-struct txnic_lmac {
-       /** Registers */
-       void *regs;
-       /** Containing BGX Ethernet interface */
-       struct txnic_bgx *bgx;
-       /** Virtual NIC index */
-       unsigned int idx;
-
-       /** MAC address */
-       union txnic_lmac_address mac;
-
-       /** Virtual NIC (if applicable) */
-       struct txnic *vnic;
-};
-
-/** A BGX Ethernet interface */
-struct txnic_bgx {
-       /** Registers */
-       void *regs;
-       /** PCI device */
-       struct pci_device *pci;
-       /** Node ID */
-       unsigned int node;
-       /** BGX index */
-       unsigned int idx;
-
-       /** LMAC type */
-       struct txnic_lmac_type *type;
-       /** Number of LMACs */
-       unsigned int count;
-       /** Link training is in use */
-       int training;
-
-       /** List of BGX Ethernet interfaces */
-       struct list_head list;
-       /** Physical function (if known) */
-       struct txnic_pf *pf;
-
-       /** Logical MACs */
-       struct txnic_lmac lmac[TXNIC_NUM_LMAC];
-};
-
-#endif /* _THUNDERX_H */
diff --git a/roms/ipxe/src/drivers/net/thunderxcfg.h b/roms/ipxe/src/drivers/net/thunderxcfg.h
deleted file mode 100644 (file)
index 235c543..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-#ifndef _THUNDERXCFG_H
-#define _THUNDERXCFG_H
-
-/** @file
- *
- * Cavium ThunderX Board Configuration
- *
- * The definitions in this section are extracted from BSD-licensed
- * (but non-public) portions of ThunderPkg.
- *
- */
-
-FILE_LICENCE ( BSD2 );
-
-#include <ipxe/efi/efi.h>
-
-/******************************************************************************
- *
- * From ThunderxBoardConfig.h
- *
- ******************************************************************************
- *
- *  Header file for Cavium ThunderX Board Configurations
- *  Copyright (c) 2015, Cavium Inc.
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions
- *  are met:
- *
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- *  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- *  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- *  SUCH DAMAGE.
- *
- */
-
-#define MAX_NODES              2
-#define CLUSTER_COUNT          3
-#define CORE_PER_CLUSTER_COUNT  16
-#define CORE_COUNT             (CLUSTER_COUNT*CORE_PER_CLUSTER_COUNT)
-#define BGX_PER_NODE_COUNT     2
-#define LMAC_PER_BGX_COUNT     4
-#define PEM_PER_NODE_COUNT     6
-#define LMC_PER_NODE_COUNT     4
-#define DIMM_PER_LMC_COUNT     2
-
-#define THUNDERX_CPU_ID(node, cluster, core) (((node) << 16) | ((cluster) << 8) | (core))
-
-//TODO: Put common type definitions in separate common include file
-typedef enum {
-    BGX_MODE_SGMII, /* 1 lane, 1.250 Gbaud */
-    BGX_MODE_XAUI,  /* 4 lanes, 3.125 Gbaud */
-    BGX_MODE_DXAUI, /* 4 lanes, 6.250 Gbaud */
-    BGX_MODE_RXAUI, /* 2 lanes, 6.250 Gbaud */
-    BGX_MODE_XFI,   /* 1 lane, 10.3125 Gbaud */
-    BGX_MODE_XLAUI, /* 4 lanes, 10.3125 Gbaud */
-    BGX_MODE_10G_KR,/* 1 lane, 10.3125 Gbaud */
-    BGX_MODE_40G_KR,/* 4 lanes, 10.3125 Gbaud */
-    BGX_MODE_UNKNOWN
-} BGX_MODE_T;
-
-typedef enum {
-    EBB8800,
-    EBB8804,
-    CRB_1S,
-    CRB_2S,
-    ASIANCAT,
-    GBT_MT60,
-    INVENTEC_P3E003,
-    BOARD_MAX
-} BOARD_TYPE;
-
-typedef struct {
-    BOOLEAN Enabled;
-    UINT64  LaneToSds;
-    UINT64  MacAddress;
-} LMAC_CFG;
-
-typedef struct {
-    BOOLEAN BgxEnabled;
-    BGX_MODE_T BgxMode;
-    UINTN    LmacCount; //Maximum number of LMAcs
-    UINT64   BaseAddress;
-    UINT64   LmacType;
-    /* Bit mask of QLMs connected to this BGX */
-    UINT64   QlmMask;
-    UINT64   QlmFreq;
-    BOOLEAN  UseTraining;
-    LMAC_CFG Lmacs[LMAC_PER_BGX_COUNT];
-} BGX_CFG;
-
-typedef struct {
-    BOOLEAN PemUsable;
-} PEM_CFG;
-
-typedef struct {
-    enum { NotPresent, Empty, Available } Status;
-    UINT8 Type;
-    UINT8 SubType;
-    UINT8 Rank;
-    UINT16 Mfg;
-    UINTN SizeMb;
-    UINTN Speed;
-    CHAR8 Serial[16];
-    CHAR8 PartNo[24];
-} DIMM_CFG;
-
-typedef struct {
-    DIMM_CFG DimmCfg[DIMM_PER_LMC_COUNT];
-} LMC_CFG;
-
-typedef struct {
-    BOOLEAN Core[CORE_COUNT];
-    BGX_CFG BgxCfg[BGX_PER_NODE_COUNT];
-    PEM_CFG PemCfg[PEM_PER_NODE_COUNT];
-    LMC_CFG LmcCfg[LMC_PER_NODE_COUNT];
-    UINT64 RamStart;
-    UINT64 RamReserve;
-    UINT64 RamSize;
-    UINTN CPUSpeed;
-    UINTN CPUVersion;
-} NODE_CFG;
-
-#define MAX_SERIAL 32
-#define MAX_REVISION 32
-typedef struct {
-    BOARD_TYPE BoardType;
-    CHAR8 Serial[MAX_SERIAL];
-    CHAR8 Revision[MAX_REVISION];
-    UINTN NumNodes;
-    UINTN BmcBootTwsiBus;
-    UINTN BmcBootTwsiAddr;
-    UINTN RtcTwsiBus;
-    UINTN RtcTwsiAddr;
-    /* IPMI support*/
-    UINTN BmcIpmiTwsiBus;
-    UINTN BmcIpmiTwsiAddr;
-    NODE_CFG Node[MAX_NODES];
-    UINT16 CpuClusterCount;
-    UINT16 CpuPerClusterCount;
-    UINT16 PcieSegmentCount;
-    UINT64 MacAddrRangeStart;
-    UINTN DdrSpeed;
-    UINT64 AcpiOemTableId;
-} BOARD_CFG;
-
-/******************************************************************************
- *
- * From ThunderConfigProtocol.h
- *
- ******************************************************************************
- *
- *  Thunder board Configuration Protocol
- *
- *  Copyright (c) 2015, Cavium Inc. All rights reserved.<BR>
- *
- *  This program and the accompanying materials are licensed and made
- *  available under the terms and conditions of the BSD License which
- *  accompanies this distribution.  The full text of the license may
- *  be found at http://opensource.org/licenses/bsd-license.php
- *
- *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
- *  BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
- *  EXPRESS OR IMPLIED.
- *
- */
-
-#define EFI_THUNDER_CONFIG_PROTOCOL_GUID \
-  {0xb75a0608, 0x99ff, 0x11e5, {0x9b, 0xeb, 0x00, 0x14, 0xd1, 0xfa, 0x23, 0x5c}}
-
-///
-/// Forward declaration
-///
-typedef struct _EFI_THUNDER_CONFIG_PROTOCOL EFI_THUNDER_CONFIG_PROTOCOL;
-
-///
-/// Function prototypes
-///
-typedef
-EFI_STATUS
-(EFIAPI *EFI_THUNDER_CONFIG_PROTOCOL_GET_CONFIG)(
-  IN EFI_THUNDER_CONFIG_PROTOCOL  *This,
-  OUT BOARD_CFG** cfg
-  );
-
-///
-/// Protocol structure
-///
-struct _EFI_THUNDER_CONFIG_PROTOCOL {
-  EFI_THUNDER_CONFIG_PROTOCOL_GET_CONFIG GetConfig;
-  BOARD_CFG* BoardConfig;
-};
-
-#endif /* _THUNDERXCFG_H */
index fe0fd4b..533ccb0 100644 (file)
@@ -24,15 +24,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <errno.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <ipxe/list.h>
 #include <ipxe/iobuf.h>
 #include <ipxe/netdevice.h>
 #include <ipxe/pci.h>
 #include <ipxe/if_ether.h>
 #include <ipxe/ethernet.h>
-#include <ipxe/virtio-pci.h>
 #include <ipxe/virtio-ring.h>
+#include <ipxe/virtio-pci.h>
 #include "virtio-net.h"
 
 /*
@@ -89,12 +88,6 @@ struct virtnet_nic {
        /** Base pio register address */
        unsigned long ioaddr;
 
-       /** 0 for legacy, 1 for virtio 1.0 */
-       int virtio_version;
-
-       /** Virtio 1.0 device data */
-       struct virtio_pci_modern_device vdev;
-
        /** RX/TX virtqueues */
        struct vring_virtqueue *virtqueue;
 
@@ -105,7 +98,7 @@ struct virtnet_nic {
        unsigned int rx_num_iobufs;
 
        /** Virtio net packet header, we only need one */
-       struct virtio_net_hdr_modern empty_header;
+       struct virtio_net_hdr empty_header;
 };
 
 /** Add an iobuf to a virtqueue
@@ -122,9 +115,6 @@ static void virtnet_enqueue_iob ( struct net_device *netdev,
        struct vring_virtqueue *vq = &virtnet->virtqueue[vq_idx];
        unsigned int out = ( vq_idx == TX_INDEX ) ? 2 : 0;
        unsigned int in = ( vq_idx == TX_INDEX ) ? 0 : 2;
-       size_t header_len = virtnet->virtio_version
-               ? sizeof ( virtnet->empty_header )
-               : sizeof ( virtnet->empty_header.legacy );
        struct vring_list list[] = {
                {
                        /* Share a single zeroed virtio net header between all
@@ -133,7 +123,7 @@ static void virtnet_enqueue_iob ( struct net_device *netdev,
                         * header fields get used.
                         */
                        .addr = ( char* ) &virtnet->empty_header,
-                       .length = header_len,
+                       .length = sizeof ( virtnet->empty_header ),
                },
                {
                        .addr = ( char* ) iobuf->data,
@@ -145,8 +135,7 @@ static void virtnet_enqueue_iob ( struct net_device *netdev,
                virtnet, iobuf, vq_idx );
 
        vring_add_buf ( vq, list, out, in, iobuf, 0 );
-       vring_kick ( virtnet->virtio_version ? &virtnet->vdev : NULL,
-                    virtnet->ioaddr, vq, 1 );
+       vring_kick ( virtnet->ioaddr, vq, 1 );
 }
 
 /** Try to keep rx virtqueue filled with iobufs
@@ -175,12 +164,12 @@ static void virtnet_refill_rx_virtqueue ( struct net_device *netdev ) {
        }
 }
 
-/** Open network device, legacy virtio 0.9.5
+/** Open network device
  *
  * @v netdev   Network device
  * @ret rc     Return status code
  */
-static int virtnet_open_legacy ( struct net_device *netdev ) {
+static int virtnet_open ( struct net_device *netdev ) {
        struct virtnet_nic *virtnet = netdev->priv;
        unsigned long ioaddr = virtnet->ioaddr;
        u32 features;
@@ -221,81 +210,6 @@ static int virtnet_open_legacy ( struct net_device *netdev ) {
        return 0;
 }
 
-/** Open network device, modern virtio 1.0
- *
- * @v netdev   Network device
- * @ret rc     Return status code
- */
-static int virtnet_open_modern ( struct net_device *netdev ) {
-       struct virtnet_nic *virtnet = netdev->priv;
-       u64 features;
-       u8 status;
-
-       /* Negotiate features */
-       features = vpm_get_features ( &virtnet->vdev );
-       if ( ! ( features & VIRTIO_F_VERSION_1 ) ) {
-               vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_FAILED );
-               return -EINVAL;
-       }
-       vpm_set_features ( &virtnet->vdev, features & (
-               ( 1ULL << VIRTIO_NET_F_MAC ) |
-               ( 1ULL << VIRTIO_F_VERSION_1 ) |
-               ( 1ULL << VIRTIO_F_ANY_LAYOUT ) ) );
-       vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_FEATURES_OK );
-
-       status = vpm_get_status ( &virtnet->vdev );
-       if ( ! ( status & VIRTIO_CONFIG_S_FEATURES_OK ) ) {
-               DBGC ( virtnet, "VIRTIO-NET %p device didn't accept features\n",
-                      virtnet );
-               vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_FAILED );
-               return -EINVAL;
-       }
-
-       /* Allocate virtqueues */
-       virtnet->virtqueue = zalloc ( QUEUE_NB *
-                                     sizeof ( *virtnet->virtqueue ) );
-       if ( ! virtnet->virtqueue ) {
-               vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_FAILED );
-               return -ENOMEM;
-       }
-
-       /* Initialize rx/tx virtqueues */
-       if ( vpm_find_vqs ( &virtnet->vdev, QUEUE_NB, virtnet->virtqueue ) ) {
-               DBGC ( virtnet, "VIRTIO-NET %p cannot register queues\n",
-                      virtnet );
-               free ( virtnet->virtqueue );
-               virtnet->virtqueue = NULL;
-               vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_FAILED );
-               return -ENOENT;
-       }
-
-       /* Disable interrupts before starting */
-       netdev_irq ( netdev, 0 );
-
-       vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_DRIVER_OK );
-
-       /* Initialize rx packets */
-       INIT_LIST_HEAD ( &virtnet->rx_iobufs );
-       virtnet->rx_num_iobufs = 0;
-       virtnet_refill_rx_virtqueue ( netdev );
-       return 0;
-}
-
-/** Open network device
- *
- * @v netdev   Network device
- * @ret rc     Return status code
- */
-static int virtnet_open ( struct net_device *netdev ) {
-       struct virtnet_nic *virtnet = netdev->priv;
-
-       if ( virtnet->virtio_version ) {
-               return virtnet_open_modern ( netdev );
-       } else {
-               return virtnet_open_legacy ( netdev );
-       }
-}
-
 /** Close network device
  *
  * @v netdev   Network device
@@ -304,19 +218,10 @@ static void virtnet_close ( struct net_device *netdev ) {
        struct virtnet_nic *virtnet = netdev->priv;
        struct io_buffer *iobuf;
        struct io_buffer *next_iobuf;
-       int i;
 
-       if ( virtnet->virtio_version ) {
-               vpm_reset ( &virtnet->vdev );
-       } else {
-               vp_reset ( virtnet->ioaddr );
-       }
+       vp_reset ( virtnet->ioaddr );
 
        /* Virtqueues can be freed now that NIC is reset */
-       for ( i = 0 ; i < QUEUE_NB ; i++ ) {
-               virtio_pci_unmap_capability ( &virtnet->virtqueue[i].notification );
-       }
-
        free ( virtnet->virtqueue );
        virtnet->virtqueue = NULL;
 
@@ -397,14 +302,10 @@ static void virtnet_poll ( struct net_device *netdev ) {
 
        /* Acknowledge interrupt.  This is necessary for UNDI operation and
         * interrupts that are raised despite VRING_AVAIL_F_NO_INTERRUPT being
-        * set (that flag is just a hint and the hypervisor does not have to
+        * set (that flag is just a hint and the hypervisor not not have to
         * honor it).
         */
-       if ( virtnet->virtio_version ) {
-               vpm_get_isr ( &virtnet->vdev );
-       } else {
-               vp_get_isr ( virtnet->ioaddr );
-       }
+       vp_get_isr ( virtnet->ioaddr );
 
        virtnet_process_tx_packets ( netdev );
        virtnet_process_rx_packets ( netdev );
@@ -437,12 +338,13 @@ static struct net_device_operations virtnet_operations = {
 };
 
 /**
- * Probe PCI device, legacy virtio 0.9.5
+ * Probe PCI device
  *
  * @v pci      PCI device
+ * @v id       PCI ID
  * @ret rc     Return status code
  */
-static int virtnet_probe_legacy ( struct pci_device *pci ) {
+static int virtnet_probe ( struct pci_device *pci ) {
        unsigned long ioaddr = pci->ioaddr;
        struct net_device *netdev;
        struct virtnet_nic *virtnet;
@@ -493,154 +395,12 @@ static int virtnet_probe_legacy ( struct pci_device *pci ) {
 }
 
 /**
- * Probe PCI device, modern virtio 1.0
- *
- * @v pci      PCI device
- * @v found_dev        Set to non-zero if modern device was found (probe may still fail)
- * @ret rc     Return status code
- */
-static int virtnet_probe_modern ( struct pci_device *pci, int *found_dev ) {
-       struct net_device *netdev;
-       struct virtnet_nic *virtnet;
-       u64 features;
-       int rc, common, isr, notify, config, device;
-
-       common = virtio_pci_find_capability ( pci, VIRTIO_PCI_CAP_COMMON_CFG );
-       if ( ! common ) {
-               DBG ( "Common virtio capability not found!\n" );
-               return -ENODEV;
-       }
-       *found_dev = 1;
-
-       isr = virtio_pci_find_capability ( pci, VIRTIO_PCI_CAP_ISR_CFG );
-       notify = virtio_pci_find_capability ( pci, VIRTIO_PCI_CAP_NOTIFY_CFG );
-       config = virtio_pci_find_capability ( pci, VIRTIO_PCI_CAP_PCI_CFG );
-       if ( ! isr || ! notify || ! config ) {
-               DBG ( "Missing virtio capabilities %i/%i/%i/%i\n",
-                     common, isr, notify, config );
-               return -EINVAL;
-       }
-       device = virtio_pci_find_capability ( pci, VIRTIO_PCI_CAP_DEVICE_CFG );
-
-       /* Allocate and hook up net device */
-       netdev = alloc_etherdev ( sizeof ( *virtnet ) );
-       if ( ! netdev )
-               return -ENOMEM;
-       netdev_init ( netdev, &virtnet_operations );
-       virtnet = netdev->priv;
-
-       pci_set_drvdata ( pci, netdev );
-       netdev->dev = &pci->dev;
-
-       DBGC ( virtnet, "VIRTIO-NET modern %p busaddr=%s irq=%d\n",
-              virtnet, pci->dev.name, pci->irq );
-
-       virtnet->vdev.pci = pci;
-       rc = virtio_pci_map_capability ( pci, common,
-               sizeof ( struct virtio_pci_common_cfg ), 4,
-               0, sizeof ( struct virtio_pci_common_cfg ),
-               &virtnet->vdev.common );
-       if ( rc )
-               goto err_map_common;
-
-       rc = virtio_pci_map_capability ( pci, isr, sizeof ( u8 ), 1,
-               0, 1,
-               &virtnet->vdev.isr );
-       if ( rc )
-               goto err_map_isr;
-
-       virtnet->vdev.notify_cap_pos = notify;
-       virtnet->vdev.cfg_cap_pos = config;
-
-       /* Map the device capability */
-       if ( device ) {
-               rc = virtio_pci_map_capability ( pci, device,
-                       0, 4, 0, sizeof ( struct virtio_net_config ),
-                       &virtnet->vdev.device );
-               if ( rc )
-                       goto err_map_device;
-       }
-
-       /* Enable the PCI device */
-       adjust_pci_device ( pci );
-
-       /* Reset the device and set initial status bits */
-       vpm_reset ( &virtnet->vdev );
-       vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_ACKNOWLEDGE );
-       vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_DRIVER );
-
-       /* Load MAC address */
-       if ( device ) {
-               features = vpm_get_features ( &virtnet->vdev );
-               if ( features & ( 1ULL << VIRTIO_NET_F_MAC ) ) {
-                       vpm_get ( &virtnet->vdev,
-                                 offsetof ( struct virtio_net_config, mac ),
-                                 netdev->hw_addr, ETH_ALEN );
-                       DBGC ( virtnet, "VIRTIO-NET %p mac=%s\n", virtnet,
-                              eth_ntoa ( netdev->hw_addr ) );
-               }
-       }
-
-       /* We need a valid MAC address */
-       if ( ! is_valid_ether_addr ( netdev->hw_addr ) ) {
-               rc = -EADDRNOTAVAIL;
-               goto err_mac_address;
-       }
-
-       /* Register network device */
-       if ( ( rc = register_netdev ( netdev ) ) != 0 )
-               goto err_register_netdev;
-
-       /* Mark link as up, control virtqueue is not used */
-       netdev_link_up ( netdev );
-
-       virtnet->virtio_version = 1;
-       return 0;
-
-       unregister_netdev ( netdev );
-err_register_netdev:
-err_mac_address:
-       vpm_reset ( &virtnet->vdev );
-       netdev_nullify ( netdev );
-       netdev_put ( netdev );
-
-       virtio_pci_unmap_capability ( &virtnet->vdev.device );
-err_map_device:
-       virtio_pci_unmap_capability ( &virtnet->vdev.isr );
-err_map_isr:
-       virtio_pci_unmap_capability ( &virtnet->vdev.common );
-err_map_common:
-       return rc;
-}
-
-/**
- * Probe PCI device
- *
- * @v pci      PCI device
- * @ret rc     Return status code
- */
-static int virtnet_probe ( struct pci_device *pci ) {
-       int found_modern = 0;
-       int rc = virtnet_probe_modern ( pci, &found_modern );
-       if ( ! found_modern && pci->device < 0x1040 ) {
-               /* fall back to the legacy probe */
-               rc = virtnet_probe_legacy ( pci );
-       }
-       return rc;
-}
-
-/**
  * Remove device
  *
  * @v pci      PCI device
  */
 static void virtnet_remove ( struct pci_device *pci ) {
        struct net_device *netdev = pci_get_drvdata ( pci );
-       struct virtnet_nic *virtnet = netdev->priv;
-
-       virtio_pci_unmap_capability ( &virtnet->vdev.device );
-       virtio_pci_unmap_capability ( &virtnet->vdev.isr );
-       virtio_pci_unmap_capability ( &virtnet->vdev.common );
 
        unregister_netdev ( netdev );
        netdev_nullify ( netdev );
@@ -649,7 +409,6 @@ static void virtnet_remove ( struct pci_device *pci ) {
 
 static struct pci_device_id virtnet_nics[] = {
 PCI_ROM(0x1af4, 0x1000, "virtio-net", "Virtio Network Interface", 0),
-PCI_ROM(0x1af4, 0x1041, "virtio-net", "Virtio Network Interface 1.0", 0),
 };
 
 struct pci_driver virtnet_driver __pci_driver = {
index c2b4a17..3abef28 100644 (file)
 #define VIRTIO_NET_F_HOST_TSO6  12      /* Host can handle TSOv6 in. */
 #define VIRTIO_NET_F_HOST_ECN   13      /* Host can handle TSO[6] w/ ECN in. */
 #define VIRTIO_NET_F_HOST_UFO   14      /* Host can handle UFO in. */
-#define VIRTIO_NET_F_MRG_RXBUF  15      /* Driver can merge receive buffers. */
-#define VIRTIO_NET_F_STATUS     16      /* Configuration status field is available. */
-#define VIRTIO_NET_F_CTRL_VQ    17      /* Control channel is available. */
-#define VIRTIO_NET_F_CTRL_RX    18      /* Control channel RX mode support. */
-#define VIRTIO_NET_F_CTRL_VLAN  19      /* Control channel VLAN filtering. */
-#define VIRTIO_NET_F_GUEST_ANNOUNCE 21  /* Driver can send gratuitous packets. */
 
 struct virtio_net_config
 {
@@ -47,14 +41,4 @@ struct virtio_net_hdr
    uint16_t csum_start;
    uint16_t csum_offset;
 };
-
-/* Virtio 1.0 version of the first element of the scatter-gather list. */
-struct virtio_net_hdr_modern
-{
-   struct virtio_net_hdr legacy;
-
-   /* Used only if VIRTIO_NET_F_MRG_RXBUF: */
-   uint16_t num_buffers;
-};
-
 #endif /* _VIRTIO_NET_H_ */
index 6a54dbf..8d4f4b8 100644 (file)
@@ -92,24 +92,19 @@ static int vmxnet3_transmit ( struct net_device *netdev,
                              struct io_buffer *iobuf ) {
        struct vmxnet3_nic *vmxnet = netdev_priv ( netdev );
        struct vmxnet3_tx_desc *tx_desc;
-       unsigned int fill;
        unsigned int desc_idx;
        unsigned int generation;
 
        /* Check that we have a free transmit descriptor */
-       fill = ( vmxnet->count.tx_prod - vmxnet->count.tx_cons );
-       if ( fill >= VMXNET3_TX_FILL ) {
+       desc_idx = ( vmxnet->count.tx_prod % VMXNET3_NUM_TX_DESC );
+       generation = ( ( vmxnet->count.tx_prod & VMXNET3_NUM_TX_DESC ) ?
+                      0 : cpu_to_le32 ( VMXNET3_TXF_GEN ) );
+       if ( vmxnet->tx_iobuf[desc_idx] ) {
                DBGC ( vmxnet, "VMXNET3 %p out of transmit descriptors\n",
                       vmxnet );
                return -ENOBUFS;
        }
 
-       /* Locate transmit descriptor */
-       desc_idx = ( vmxnet->count.tx_prod % VMXNET3_NUM_TX_DESC );
-       generation = ( ( vmxnet->count.tx_prod & VMXNET3_NUM_TX_DESC ) ?
-                      0 : cpu_to_le32 ( VMXNET3_TXF_GEN ) );
-       assert ( vmxnet->tx_iobuf[desc_idx] == NULL );
-
        /* Increment producer counter */
        vmxnet->count.tx_prod++;
 
index 5e1e0cb..a1671d9 100644 (file)
@@ -493,9 +493,6 @@ struct vmxnet3_nic {
 /** MTU size */
 #define VMXNET3_MTU ( ETH_FRAME_LEN + 4 /* VLAN */ + 4 /* FCS */ )
 
-/** Transmit ring maximum fill level */
-#define VMXNET3_TX_FILL ( VMXNET3_NUM_TX_DESC - 1 )
-
 /** Receive ring maximum fill level */
 #define VMXNET3_RX_FILL 8
 
index 35cbc8d..4124692 100644 (file)
@@ -175,61 +175,6 @@ static int ehci_ctrl_reachable ( struct ehci_device *ehci, void *ptr ) {
 
 /******************************************************************************
  *
- * Diagnostics
- *
- ******************************************************************************
- */
-
-/**
- * Dump host controller registers
- *
- * @v ehci             EHCI device
- */
-static __unused void ehci_dump ( struct ehci_device *ehci ) {
-       uint8_t caplength;
-       uint16_t hciversion;
-       uint32_t hcsparams;
-       uint32_t hccparams;
-       uint32_t usbcmd;
-       uint32_t usbsts;
-       uint32_t usbintr;
-       uint32_t frindex;
-       uint32_t ctrldssegment;
-       uint32_t periodiclistbase;
-       uint32_t asynclistaddr;
-       uint32_t configflag;
-
-       /* Do nothing unless debugging is enabled */
-       if ( ! DBG_LOG )
-               return;
-
-       /* Dump capability registers */
-       caplength = readb ( ehci->cap + EHCI_CAP_CAPLENGTH );
-       hciversion = readw ( ehci->cap + EHCI_CAP_HCIVERSION );
-       hcsparams = readl ( ehci->cap + EHCI_CAP_HCSPARAMS );
-       hccparams = readl ( ehci->cap + EHCI_CAP_HCCPARAMS );
-       DBGC ( ehci, "EHCI %s caplen %02x hciversion %04x hcsparams %08x "
-              "hccparams %08x\n", ehci->name, caplength, hciversion,
-              hcsparams,  hccparams );
-
-       /* Dump operational registers */
-       usbcmd = readl ( ehci->op + EHCI_OP_USBCMD );
-       usbsts = readl ( ehci->op + EHCI_OP_USBSTS );
-       usbintr = readl ( ehci->op + EHCI_OP_USBINTR );
-       frindex = readl ( ehci->op + EHCI_OP_FRINDEX );
-       ctrldssegment = readl ( ehci->op + EHCI_OP_CTRLDSSEGMENT );
-       periodiclistbase = readl ( ehci->op + EHCI_OP_PERIODICLISTBASE );
-       asynclistaddr = readl ( ehci->op + EHCI_OP_ASYNCLISTADDR );
-       configflag = readl ( ehci->op + EHCI_OP_CONFIGFLAG );
-       DBGC ( ehci, "EHCI %s usbcmd %08x usbsts %08x usbint %08x frindx "
-              "%08x\n", ehci->name, usbcmd, usbsts, usbintr, frindex );
-       DBGC ( ehci, "EHCI %s ctrlds %08x period %08x asyncl %08x cfgflg "
-              "%08x\n", ehci->name, ctrldssegment, periodiclistbase,
-              asynclistaddr, configflag );
-}
-
-/******************************************************************************
- *
  * USB legacy support
  *
  ******************************************************************************
@@ -288,14 +233,6 @@ static void ehci_legacy_claim ( struct ehci_device *ehci,
        if ( ! legacy )
                return;
 
-       /* Dump original SMI usage */
-       pci_read_config_dword ( pci, ( legacy + EHCI_USBLEGSUP_CTLSTS ),
-                               &ctlsts );
-       if ( ctlsts ) {
-               DBGC ( ehci, "EHCI %s BIOS using SMIs: %08x\n",
-                      ehci->name, ctlsts );
-       }
-
        /* Claim ownership */
        pci_write_config_byte ( pci, ( legacy + EHCI_USBLEGSUP_OS ),
                                EHCI_USBLEGSUP_OS_OWNED );
@@ -339,11 +276,9 @@ static void ehci_legacy_claim ( struct ehci_device *ehci,
  */
 static void ehci_legacy_release ( struct ehci_device *ehci,
                                  struct pci_device *pci ) {
-       unsigned int legacy = ehci->legacy;
-       uint32_t ctlsts;
 
        /* Do nothing unless legacy support capability is present */
-       if ( ! legacy )
+       if ( ! ehci->legacy )
                return;
 
        /* Do nothing if releasing ownership is prevented */
@@ -354,14 +289,8 @@ static void ehci_legacy_release ( struct ehci_device *ehci,
        }
 
        /* Release ownership */
-       pci_write_config_byte ( pci, ( legacy + EHCI_USBLEGSUP_OS ), 0 );
+       pci_write_config_byte ( pci, ( ehci->legacy + EHCI_USBLEGSUP_OS ), 0 );
        DBGC ( ehci, "EHCI %s released ownership to BIOS\n", ehci->name );
-
-       /* Dump restored SMI usage */
-       pci_read_config_dword ( pci, ( legacy + EHCI_USBLEGSUP_CTLSTS ),
-                               &ctlsts );
-       DBGC ( ehci, "EHCI %s BIOS reclaimed SMIs: %08x\n",
-              ehci->name, ctlsts );
 }
 
 /******************************************************************************
@@ -674,8 +603,6 @@ static int ehci_enqueue ( struct ehci_device *ehci, struct ehci_ring *ring,
 
        /* Fail if any portion is unreachable */
        for ( i = 0 ; i < count ; i++ ) {
-               if ( ! xfer[i].len )
-                       continue;
                phys = ( virt_to_phys ( xfer[i].data ) + xfer[i].len - 1 );
                if ( ( phys > 0xffffffffUL ) && ( ! ehci->addr64 ) )
                        return -ENOTSUP;
@@ -1041,10 +968,10 @@ static uint32_t ehci_endpoint_characteristics ( struct usb_endpoint *ep ) {
                chr |= EHCI_CHR_TOGGLE;
 
        /* Determine endpoint speed */
-       if ( usb->speed == USB_SPEED_HIGH ) {
+       if ( usb->port->speed == USB_SPEED_HIGH ) {
                chr |= EHCI_CHR_EPS_HIGH;
        } else {
-               if ( usb->speed == USB_SPEED_FULL ) {
+               if ( usb->port->speed == USB_SPEED_FULL ) {
                        chr |= EHCI_CHR_EPS_FULL;
                } else {
                        chr |= EHCI_CHR_EPS_LOW;
@@ -1292,75 +1219,40 @@ static int ehci_endpoint_message ( struct usb_endpoint *ep,
 }
 
 /**
- * Calculate number of transfer descriptors
- *
- * @v len              Length of data
- * @v zlp              Append a zero-length packet
- * @ret count          Number of transfer descriptors
- */
-static unsigned int ehci_endpoint_count ( size_t len, int zlp ) {
-       unsigned int count;
-
-       /* Split into 16kB transfers.  A single transfer can handle up
-        * to 20kB if it happens to be page-aligned, or up to 16kB
-        * with arbitrary alignment.  We simplify the code by assuming
-        * that we can fit only 16kB into each transfer.
-        */
-       count = ( ( len + EHCI_MTU - 1 ) / EHCI_MTU );
-
-       /* Append a zero-length transfer if applicable */
-       if ( zlp || ( count == 0 ) )
-               count++;
-
-       return count;
-}
-
-/**
  * Enqueue stream transfer
  *
  * @v ep               USB endpoint
  * @v iobuf            I/O buffer
- * @v zlp              Append a zero-length packet
+ * @v terminate                Terminate using a short packet
  * @ret rc             Return status code
  */
 static int ehci_endpoint_stream ( struct usb_endpoint *ep,
-                                 struct io_buffer *iobuf, int zlp ) {
+                                 struct io_buffer *iobuf, int terminate ) {
        struct ehci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
        struct ehci_device *ehci = endpoint->ehci;
-       void *data = iobuf->data;
-       size_t len = iob_len ( iobuf );
-       unsigned int count = ehci_endpoint_count ( len, zlp );
        unsigned int input = ( ep->address & USB_DIR_IN );
-       unsigned int flags = ( input ? EHCI_FL_PID_IN : EHCI_FL_PID_OUT );
-       struct ehci_transfer xfers[count];
+       struct ehci_transfer xfers[2];
        struct ehci_transfer *xfer = xfers;
-       size_t xfer_len;
-       unsigned int i;
+       size_t len = iob_len ( iobuf );
        int rc;
 
-       /* Create transfers */
-       for ( i = 0 ; i < count ; i++ ) {
-
-               /* Calculate transfer length */
-               xfer_len = EHCI_MTU;
-               if ( xfer_len > len )
-                       xfer_len = len;
-
-               /* Create transfer */
-               xfer->data = data;
-               xfer->len = xfer_len;
-               xfer->flags = flags;
-
-               /* Move to next transfer */
-               data += xfer_len;
-               len -= xfer_len;
+       /* Create transfer */
+       xfer->data = iobuf->data;
+       xfer->len = len;
+       xfer->flags = ( EHCI_FL_IOC |
+                       ( input ? EHCI_FL_PID_IN : EHCI_FL_PID_OUT ) );
+       xfer++;
+       if ( terminate && ( ( len & ( ep->mtu - 1 ) ) == 0 ) ) {
+               xfer->data = NULL;
+               xfer->len = 0;
+               assert ( ! input );
+               xfer->flags = ( EHCI_FL_IOC | EHCI_FL_PID_OUT );
                xfer++;
        }
-       xfer[-1].flags |= EHCI_FL_IOC;
 
        /* Enqueue transfer */
        if ( ( rc = ehci_enqueue ( ehci, &endpoint->ring, iobuf, xfers,
-                                  count ) ) != 0 )
+                                  ( xfer - xfers ) ) ) != 0 )
                return rc;
 
        return 0;
index 528c1be..b6bb925 100644 (file)
@@ -697,7 +697,7 @@ static int uhci_endpoint_open ( struct usb_endpoint *ep ) {
                goto err_ring_alloc;
        endpoint->ring.mtu = ep->mtu;
        endpoint->ring.flags = UHCI_FL_CERR_MAX;
-       if ( usb->speed < USB_SPEED_FULL )
+       if ( usb->port->speed < USB_SPEED_FULL )
                endpoint->ring.flags |= UHCI_FL_LS;
        endpoint->ring.control = ( UHCI_CONTROL_DEVICE ( usb->address ) |
                                   UHCI_CONTROL_ENDPOINT ( ep->address ) );
@@ -835,20 +835,22 @@ static int uhci_endpoint_message ( struct usb_endpoint *ep,
  *
  * @v ep               USB endpoint
  * @v iobuf            I/O buffer
- * @v zlp              Append a zero-length packet
+ * @v terminate                Terminate using a short packet
  * @ret rc             Return status code
  */
 static int uhci_endpoint_stream ( struct usb_endpoint *ep,
-                                 struct io_buffer *iobuf, int zlp ) {
+                                 struct io_buffer *iobuf, int terminate ) {
        struct uhci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
        struct uhci_ring *ring = &endpoint->ring;
        unsigned int count;
        size_t len;
        int input;
+       int zlp;
        int rc;
 
        /* Calculate number of descriptors */
        len = iob_len ( iobuf );
+       zlp = ( terminate && ( ( len & ( ring->mtu - 1 ) ) == 0 ) );
        count = ( ( ( len + ring->mtu - 1 ) / ring->mtu ) + ( zlp ? 1 : 0 ) );
 
        /* Enqueue transfer */
index 47914bc..bf2a200 100644 (file)
@@ -155,10 +155,6 @@ static int hub_open ( struct usb_hub *hub ) {
        /* Refill interrupt ring */
        hub_refill ( hubdev );
 
-       /* Delay to allow ports to stabilise on out-of-spec hubs */
-       if ( hubdev->flags & USB_HUB_SLOW_START )
-               mdelay ( USB_HUB_SLOW_START_DELAY_MS );
-
        return 0;
 
        usb_endpoint_close ( &hubdev->intr );
@@ -414,9 +410,8 @@ static int hub_probe ( struct usb_function *func,
        hubdev->usb = usb;
        hubdev->features =
                ( enhanced ? USB_HUB_FEATURES_ENHANCED : USB_HUB_FEATURES );
-       hubdev->flags = func->id->driver_data;
        usb_endpoint_init ( &hubdev->intr, usb, &usb_hub_intr_operations );
-       usb_refill_init ( &hubdev->intr, 0, 0, USB_HUB_INTR_FILL );
+       usb_refill_init ( &hubdev->intr, 0, USB_HUB_INTR_FILL );
        process_init_stopped ( &hubdev->refill, &hub_refill_desc, NULL );
 
        /* Locate hub interface descriptor */
@@ -501,10 +496,9 @@ static void hub_remove ( struct usb_function *func ) {
        unsigned int i;
 
        /* If hub has been unplugged, mark all ports as unplugged */
-       if ( usb->port->disconnected ) {
+       if ( usb->port->speed == USB_SPEED_NONE ) {
                for ( i = 1 ; i <= hub->ports ; i++ ) {
                        port = usb_port ( hub, i );
-                       port->disconnected = 1;
                        port->speed = USB_SPEED_NONE;
                }
        }
@@ -523,15 +517,24 @@ static void hub_remove ( struct usb_function *func ) {
 /** USB hub device IDs */
 static struct usb_device_id hub_ids[] = {
        {
-               .name = "avocent-hub",
-               .vendor = 0x0624,
-               .product = 0x0248,
-               .driver_data = USB_HUB_SLOW_START,
+               .name = "hub-1",
+               .vendor = USB_ANY_ID,
+               .product = USB_ANY_ID,
+               .class = {
+                       .class = USB_CLASS_HUB,
+                       .subclass = 0,
+                       .protocol = 0,
+               },
        },
        {
-               .name = "hub",
+               .name = "hub-2",
                .vendor = USB_ANY_ID,
                .product = USB_ANY_ID,
+               .class = {
+                       .class = USB_CLASS_HUB,
+                       .subclass = 0,
+                       .protocol = 1,
+               },
        },
 };
 
@@ -539,8 +542,6 @@ static struct usb_device_id hub_ids[] = {
 struct usb_driver usb_hub_driver __usb_driver = {
        .ids = hub_ids,
        .id_count = ( sizeof ( hub_ids ) / sizeof ( hub_ids[0] ) ),
-       .class = USB_CLASS_ID ( USB_CLASS_HUB, 0, USB_ANY_ID ),
-       .score = USB_SCORE_NORMAL,
        .probe = hub_probe,
        .remove = hub_remove,
 };
index a5f123a..d7d8f96 100644 (file)
@@ -257,8 +257,6 @@ struct usb_hub_device {
        struct usb_hub *hub;
        /** Features */
        unsigned int features;
-       /** Flags */
-       unsigned int flags;
 
        /** Interrupt endpoint */
        struct usb_endpoint intr;
@@ -266,12 +264,6 @@ struct usb_hub_device {
        struct process refill;
 };
 
-/** Hub requires additional settling delay */
-#define USB_HUB_SLOW_START 0x0001
-
-/** Additional setting delay for out-of-spec hubs */
-#define USB_HUB_SLOW_START_DELAY_MS 500
-
 /** Interrupt ring fill level
  *
  * This is a policy decision.
diff --git a/roms/ipxe/src/drivers/usb/usbio.c b/roms/ipxe/src/drivers/usb/usbio.c
deleted file mode 100644 (file)
index 153f394..0000000
+++ /dev/null
@@ -1,1717 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_driver.h>
-#include <ipxe/efi/efi_utils.h>
-#include <ipxe/efi/Protocol/UsbIo.h>
-#include <ipxe/usb.h>
-#include "usbio.h"
-
-/** @file
- *
- * EFI_USB_IO_PROTOCOL pseudo Host Controller Interface driver
- *
- *
- * The EFI_USB_IO_PROTOCOL is an almost unbelievably poorly designed
- * abstraction of a USB device.  It would be just about forgivable for
- * an API to support only synchronous operation for bulk OUT
- * endpoints.  It is imbecilic to support only synchronous operation
- * for bulk IN endpoints.  This apparently intern-designed API
- * throttles a typical NIC down to 1.5% of its maximum throughput.
- * That isn't a typo.  It really is that slow.
- *
- * We can't even work around this stupidity by talking to the host
- * controller abstraction directly, because an identical limitation
- * exists in the EFI_USB2_HC_PROTOCOL.
- *
- * Unless you derive therapeutic value from watching download progress
- * indicators lethargically creep through every single integer from 0
- * to 100, you should use iPXE's native USB host controller drivers
- * instead.  (Or just upgrade from UEFI to "legacy" BIOS, which will
- * produce a similar speed increase.)
- *
- *
- * For added excitement, the EFI_USB_IO_PROTOCOL makes the
- * (demonstrably incorrect) assumption that a USB driver needs to
- * attach to exactly one interface within a USB device, and provides a
- * helper method to retrieve "the" interface descriptor.  Since pretty
- * much every USB network device requires binding to a pair of
- * control+data interfaces, this aspect of EFI_USB_IO_PROTOCOL is of
- * no use to us.
- *
- * We have our own existing code for reading USB descriptors, so we
- * don't actually care that the UsbGetInterfaceDescriptor() method
- * provided by EFI_USB_IO_PROTOCOL is useless for network devices.  We
- * can read the descriptors ourselves (via UsbControlTransfer()) and
- * get all of the information we need this way.  We can even work
- * around the fact that EFI_USB_IO_PROTOCOL provides separate handles
- * for each of the two interfaces comprising our network device.
- *
- * However, if we discover that we need to select an alternative
- * device configuration (e.g. for devices exposing both RNDIS and
- * ECM), then all hell breaks loose.  EFI_USB_IO_PROTOCOL starts to
- * panic because its cached interface and endpoint descriptors will no
- * longer be valid.  As mentioned above, the cached descriptors are
- * useless for network devices anyway so we _really_ don't care about
- * this, but EFI_USB_IO_PROTOCOL certainly cares.  It prints out a
- * manic warning message containing no fewer than six exclamation
- * marks and then literally commits seppuku in the middle of the
- * UsbControlTransfer() method by attempting to uninstall itself.
- * Quite how the caller is supposed to react when asked to stop using
- * the EFI_USB_IO_PROTOCOL instance while in the middle of an
- * uninterruptible call to said instance is left as an exercise for
- * the interested reader.
- *
- * There is no sensible way to work around this, so we just
- * preemptively fail if asked to change the device configuration, on
- * the basis that reporting a sarcastic error message is often
- * preferable to jumping through a NULL pointer and crashing the
- * system.
- */
-
-/* Disambiguate the various error causes */
-#define ENOTSUP_MORONIC_SPECIFICATION                                  \
-       __einfo_error ( EINFO_ENOTSUP_MORONIC_SPECIFICATION )
-#define EINFO_ENOTSUP_MORONIC_SPECIFICATION                            \
-       __einfo_uniqify ( EINFO_ENOTSUP, 0x01,                          \
-                         "EFI_USB_IO_PROTOCOL was designed by morons" )
-
-/******************************************************************************
- *
- * Device model
- *
- ******************************************************************************
- */
-
-/**
- * Determine endpoint interface number
- *
- * @v usbio            USB I/O device
- * @v ep               USB Endpoint
- * @ret interface      Interface number, or negative error
- */
-static int usbio_interface ( struct usbio_device *usbio,
-                            struct usb_endpoint *ep ) {
-       EFI_HANDLE handle = usbio->handle;
-       struct usb_device *usb = ep->usb;
-       struct usb_configuration_descriptor *config;
-       struct usb_interface_descriptor *interface;
-       struct usb_endpoint_descriptor *endpoint;
-       struct usb_function *func;
-       unsigned int i;
-
-       /* The control endpoint is not part of a described interface */
-       if ( ep->address == USB_EP0_ADDRESS )
-               return 0;
-
-       /* Iterate over all interface descriptors looking for a match */
-       config = usbio->config;
-       for_each_config_descriptor ( interface, config ) {
-
-               /* Skip non-interface descriptors */
-               if ( interface->header.type != USB_INTERFACE_DESCRIPTOR )
-                       continue;
-
-               /* Iterate over all endpoint descriptors looking for a match */
-               for_each_interface_descriptor ( endpoint, config, interface ) {
-
-                       /* Skip non-endpoint descriptors */
-                       if ( endpoint->header.type != USB_ENDPOINT_DESCRIPTOR )
-                               continue;
-
-                       /* Check endpoint address */
-                       if ( endpoint->endpoint != ep->address )
-                               continue;
-
-                       /* Check interface belongs to this function */
-                       list_for_each_entry ( func, &usb->functions, list ) {
-
-                               /* Skip non-matching functions */
-                               if ( func->interface[0] != usbio->first )
-                                       continue;
-
-                               /* Iterate over all interfaces for a match */
-                               for ( i = 0 ; i < func->desc.count ; i++ ) {
-                                       if ( interface->interface ==
-                                            func->interface[i] )
-                                               return interface->interface;
-                               }
-                       }
-               }
-       }
-
-       DBGC ( usbio, "USBIO %s cannot find interface for %s",
-              efi_handle_name ( handle ), usb_endpoint_name ( ep ) );
-       return -ENOENT;
-}
-
-/**
- * Open USB I/O interface
- *
- * @v usbio            USB I/O device
- * @v interface                Interface number
- * @ret rc             Return status code
- */
-static int usbio_open ( struct usbio_device *usbio, unsigned int interface ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_HANDLE handle = usbio->handle;
-       struct usbio_interface *intf = &usbio->interface[interface];
-       EFI_DEVICE_PATH_PROTOCOL *path;
-       EFI_DEVICE_PATH_PROTOCOL *end;
-       USB_DEVICE_PATH *usbpath;
-       union {
-               void *interface;
-               EFI_USB_IO_PROTOCOL *io;
-       } u;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Sanity check */
-       assert ( interface < usbio->config->interfaces );
-
-       /* If interface is already open, just increment the usage count */
-       if ( intf->count ) {
-               intf->count++;
-               return 0;
-       }
-
-       /* Construct device path for this interface */
-       path = usbio->path;
-       usbpath = usbio->usbpath;
-       usbpath->InterfaceNumber = interface;
-       end = efi_devpath_end ( path );
-
-       /* Locate handle for this endpoint's interface */
-       if ( ( efirc = bs->LocateDevicePath ( &efi_usb_io_protocol_guid, &path,
-                                             &intf->handle ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( usbio, "USBIO %s could not locate ",
-                      efi_handle_name ( handle ) );
-               DBGC ( usbio, "%s: %s\n",
-                      efi_devpath_text ( usbio->path ), strerror ( rc ) );
-               return rc;
-       }
-
-       /* Check that expected path was located */
-       if ( path != end ) {
-               DBGC ( usbio, "USBIO %s located incomplete ",
-                      efi_handle_name ( handle ) );
-               DBGC ( usbio, "%s\n", efi_handle_name ( intf->handle ) );
-               return -EXDEV;
-       }
-
-       /* Open USB I/O protocol on this handle */
-       if ( ( efirc = bs->OpenProtocol ( intf->handle,
-                                         &efi_usb_io_protocol_guid,
-                                         &u.interface, efi_image_handle,
-                                         intf->handle,
-                                         ( EFI_OPEN_PROTOCOL_BY_DRIVER |
-                                           EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
-               rc = -EEFI ( efirc );
-               DBGC ( usbio, "USBIO %s cannot open ",
-                      efi_handle_name ( handle ) );
-               DBGC ( usbio, "%s: %s\n",
-                      efi_handle_name ( intf->handle ), strerror ( rc ) );
-               DBGC_EFI_OPENERS ( usbio, intf->handle,
-                                  &efi_usb_io_protocol_guid );
-               return rc;
-       }
-       intf->io = u.io;
-
-       /* Increment usage count */
-       intf->count++;
-
-       return 0;
-}
-
-/**
- * Close USB I/O interface
- *
- * @v usbio            USB I/O device
- * @v interface                Interface number
- */
-static void usbio_close ( struct usbio_device *usbio, unsigned int interface ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       struct usbio_interface *intf = &usbio->interface[interface];
-
-       /* Sanity checks */
-       assert ( interface < usbio->config->interfaces );
-       assert ( intf->count > 0 );
-
-       /* Decrement usage count */
-       intf->count--;
-
-       /* Do nothing if interface is still in use */
-       if ( intf->count )
-               return;
-
-       /* Close USB I/O protocol */
-       bs->CloseProtocol ( intf->handle, &efi_usb_io_protocol_guid,
-                           efi_image_handle, intf->handle );
-}
-
-/******************************************************************************
- *
- * Control endpoints
- *
- ******************************************************************************
- */
-
-/**
- * Open control endpoint
- *
- * @v endpoint         Endpoint
- * @ret rc             Return status code
- */
-static int usbio_control_open ( struct usbio_endpoint *endpoint __unused ) {
-
-       /* Nothing to do */
-       return 0;
-}
-
-/**
- * Close control endpoint
- *
- * @v endpoint         Endpoint
- */
-static void usbio_control_close ( struct usbio_endpoint *endpoint __unused ) {
-
-       /* Nothing to do */
-}
-
-/**
- * Poll control endpoint
- *
- * @v endpoint         Endpoint
- */
-static void usbio_control_poll ( struct usbio_endpoint *endpoint ) {
-       struct usbio_device *usbio = endpoint->usbio;
-       struct usb_endpoint *ep = endpoint->ep;
-       EFI_HANDLE handle = usbio->handle;
-       EFI_USB_IO_PROTOCOL *io;
-       union {
-               struct usb_setup_packet setup;
-               EFI_USB_DEVICE_REQUEST efi;
-       } *msg;
-       EFI_USB_DATA_DIRECTION direction;
-       struct io_buffer *iobuf;
-       unsigned int index;
-       unsigned int flags;
-       unsigned int recipient;
-       unsigned int interface;
-       uint16_t request;
-       void *data;
-       size_t len;
-       UINT32 status;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Do nothing if ring is empty */
-       if ( endpoint->cons == endpoint->prod )
-               return;
-
-       /* Consume next transfer */
-       index = ( endpoint->cons++ % USBIO_RING_COUNT );
-       iobuf = endpoint->iobuf[index];
-       flags = endpoint->flags[index];
-
-       /* Sanity check */
-       if ( ! ( flags & USBIO_MESSAGE ) ) {
-               DBGC ( usbio, "USBIO %s %s non-message transfer\n",
-                      efi_handle_name ( handle ), usb_endpoint_name ( ep ) );
-               rc = -ENOTSUP;
-               goto err_not_message;
-       }
-
-       /* Construct transfer */
-       assert ( iob_len ( iobuf ) >= sizeof ( *msg ) );
-       msg = iobuf->data;
-       iob_pull ( iobuf, sizeof ( *msg ) );
-       request = le16_to_cpu ( msg->setup.request );
-       len = iob_len ( iobuf );
-       if ( len ) {
-               data = iobuf->data;
-               direction = ( ( request & USB_DIR_IN ) ?
-                             EfiUsbDataIn : EfiUsbDataOut );
-       } else {
-               data = NULL;
-               direction = EfiUsbNoData;
-       }
-
-       /* Determine interface for this transfer */
-       recipient = ( request & USB_RECIP_MASK );
-       if ( recipient == USB_RECIP_INTERFACE ) {
-               /* Recipient is an interface: use interface number directly */
-               interface = le16_to_cpu ( msg->setup.index );
-       } else {
-               /* Route all other requests through the first interface */
-               interface = 0;
-       }
-
-       /* Open interface */
-       if ( ( rc = usbio_open ( usbio, interface ) ) != 0 )
-               goto err_open;
-       io = usbio->interface[interface].io;
-
-       /* Due to the design of EFI_USB_IO_PROTOCOL, attempting to set
-        * the configuration to a non-default value is basically a
-        * self-destruct button.
-        */
-       if ( ( request == USB_SET_CONFIGURATION ) &&
-            ( le16_to_cpu ( msg->setup.value ) != usbio->config->config ) ) {
-               rc = -ENOTSUP_MORONIC_SPECIFICATION;
-               DBGC ( usbio, "USBIO %s cannot change configuration: %s\n",
-                      efi_handle_name ( handle ), strerror ( rc ) );
-               goto err_moronic_specification;
-       }
-
-       /* Submit transfer */
-       if ( ( efirc = io->UsbControlTransfer ( io, &msg->efi, direction, 0,
-                                               data, len, &status ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( usbio, "USBIO %s %s could not submit control transfer ",
-                      efi_handle_name ( handle ), usb_endpoint_name ( ep ) );
-               DBGC ( usbio, "via %s: %s (status %04x)\n",
-                      efi_handle_name ( usbio->interface[interface].handle ),
-                      strerror ( rc ), status );
-               goto err_transfer;
-       }
-
-       /* Close interface */
-       usbio_close ( usbio, interface );
-
-       /* Complete transfer */
-       usb_complete ( ep, iobuf );
-
-       return;
-
- err_transfer:
- err_moronic_specification:
-       usbio_close ( usbio, interface );
- err_open:
- err_not_message:
-       usb_complete_err ( ep, iobuf, rc );
-}
-
-/** Control endpoint operations */
-static struct usbio_operations usbio_control_operations = {
-       .open   = usbio_control_open,
-       .close  = usbio_control_close,
-       .poll   = usbio_control_poll,
-};
-
-/******************************************************************************
- *
- * Bulk IN endpoints
- *
- ******************************************************************************
- */
-
-/**
- * Open bulk IN endpoint
- *
- * @v endpoint         Endpoint
- * @ret rc             Return status code
- */
-static int usbio_bulk_in_open ( struct usbio_endpoint *endpoint __unused ) {
-
-       /* Nothing to do */
-       return 0;
-}
-
-/**
- * Close bulk IN endpoint
- *
- * @v endpoint         Endpoint
- */
-static void usbio_bulk_in_close ( struct usbio_endpoint *endpoint __unused ) {
-
-       /* Nothing to do */
-}
-
-/**
- * Poll bulk IN endpoint
- *
- * @v endpoint         Endpoint
- */
-static void usbio_bulk_in_poll ( struct usbio_endpoint *endpoint ) {
-       struct usbio_device *usbio = endpoint->usbio;
-       struct usb_endpoint *ep = endpoint->ep;
-       EFI_USB_IO_PROTOCOL *io = endpoint->io;
-       EFI_HANDLE handle = usbio->handle;
-       struct io_buffer *iobuf;
-       unsigned int index;
-       UINTN len;
-       UINT32 status;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Do nothing if ring is empty */
-       if ( endpoint->cons == endpoint->prod )
-               return;
-
-       /* Attempt (but do not yet consume) next transfer */
-       index = ( endpoint->cons % USBIO_RING_COUNT );
-       iobuf = endpoint->iobuf[index];
-
-       /* Construct transfer */
-       len = iob_len ( iobuf );
-
-       /* Upon being turned on, the EFI_USB_IO_PROTOCOL did nothing
-        * for several minutes before firing a small ARP packet a few
-        * millimetres into the ether.
-        */
-       efirc = io->UsbBulkTransfer ( io, ep->address, iobuf->data,
-                                     &len, 1, &status );
-       if ( efirc == EFI_TIMEOUT )
-               return;
-
-       /* Consume transfer */
-       endpoint->cons++;
-
-       /* Check for failure */
-       if ( efirc != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC2 ( usbio, "USBIO %s %s could not submit bulk IN transfer: "
-                       "%s (status %04x)\n", efi_handle_name ( handle ),
-                       usb_endpoint_name ( ep ), strerror ( rc ), status );
-               usb_complete_err ( ep, iobuf, rc );
-               return;
-       }
-
-       /* Update length */
-       iob_put ( iobuf, ( len - iob_len ( iobuf ) ) );
-
-       /* Complete transfer */
-       usb_complete ( ep, iobuf );
-}
-
-/** Bulk endpoint operations */
-static struct usbio_operations usbio_bulk_in_operations = {
-       .open   = usbio_bulk_in_open,
-       .close  = usbio_bulk_in_close,
-       .poll   = usbio_bulk_in_poll,
-};
-
-/******************************************************************************
- *
- * Bulk OUT endpoints
- *
- ******************************************************************************
- */
-
-/**
- * Open bulk OUT endpoint
- *
- * @v endpoint         Endpoint
- * @ret rc             Return status code
- */
-static int usbio_bulk_out_open ( struct usbio_endpoint *endpoint __unused ) {
-
-       /* Nothing to do */
-       return 0;
-}
-
-/**
- * Close bulk OUT endpoint
- *
- * @v endpoint         Endpoint
- */
-static void usbio_bulk_out_close ( struct usbio_endpoint *endpoint __unused ) {
-
-       /* Nothing to do */
-}
-
-/**
- * Poll bulk OUT endpoint
- *
- * @v endpoint         Endpoint
- */
-static void usbio_bulk_out_poll ( struct usbio_endpoint *endpoint ) {
-       struct usbio_device *usbio = endpoint->usbio;
-       struct usb_endpoint *ep = endpoint->ep;
-       EFI_USB_IO_PROTOCOL *io = endpoint->io;
-       EFI_HANDLE handle = usbio->handle;
-       struct io_buffer *iobuf;
-       unsigned int index;
-       unsigned int flags;
-       UINTN len;
-       UINT32 status;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Do nothing if ring is empty */
-       if ( endpoint->cons == endpoint->prod )
-               return;
-
-       /* Consume next transfer */
-       index = ( endpoint->cons++ % USBIO_RING_COUNT );
-       iobuf = endpoint->iobuf[index];
-       flags = endpoint->flags[index];
-
-       /* Construct transfer */
-       len = iob_len ( iobuf );
-
-       /* Submit transfer */
-       if ( ( efirc = io->UsbBulkTransfer ( io, ep->address, iobuf->data,
-                                            &len, 0, &status ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( usbio, "USBIO %s %s could not submit bulk OUT transfer: "
-                      "%s (status %04x)\n", efi_handle_name ( handle ),
-                      usb_endpoint_name ( ep ), strerror ( rc ), status );
-               goto err;
-       }
-
-       /* Update length */
-       iob_put ( iobuf, ( len - iob_len ( iobuf ) ) );
-
-       /* Submit zero-length transfer if required */
-       len = 0;
-       if ( ( flags & USBIO_ZLEN ) &&
-            ( efirc = io->UsbBulkTransfer ( io, ep->address, NULL, &len, 0,
-                                            &status ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( usbio, "USBIO %s %s could not submit zero-length "
-                      "transfer: %s (status %04x)\n",
-                      efi_handle_name ( handle ), usb_endpoint_name ( ep ),
-                      strerror ( rc ), status );
-               goto err;
-       }
-
-       /* Complete transfer */
-       usb_complete ( ep, iobuf );
-
-       return;
-
- err:
-       usb_complete_err ( ep, iobuf, rc );
-}
-
-/** Bulk endpoint operations */
-static struct usbio_operations usbio_bulk_out_operations = {
-       .open   = usbio_bulk_out_open,
-       .close  = usbio_bulk_out_close,
-       .poll   = usbio_bulk_out_poll,
-};
-
-/******************************************************************************
- *
- * Interrupt endpoints
- *
- ******************************************************************************
- *
- * The EFI_USB_IO_PROTOCOL provides two ways to interact with
- * interrupt endpoints, neither of which naturally model the hardware
- * interaction.  The UsbSyncInterruptTransfer() method allows imposes
- * a 1ms overhead for every interrupt transfer (which could result in
- * up to a 50% decrease in overall throughput for the device).  The
- * UsbAsyncInterruptTransfer() method provides no way for us to
- * prevent transfers when no I/O buffers are available.
- *
- * We work around this design by utilising a small, fixed ring buffer
- * into which the interrupt callback delivers the data.  This aims to
- * provide buffer space even if no I/O buffers have yet been enqueued.
- * The scheme is not guaranteed since the fixed ring buffer may also
- * become full.  However:
- *
- *   - devices which send a constant stream of interrupts (and which
- *     therefore might exhaust the fixed ring buffer) tend to be
- *     responding to every interrupt request, and can tolerate lost
- *     packets, and
- *
- *   - devices which cannot tolerate lost interrupt packets tend to send
- *     only a few small messages.
- *
- * The scheme should therefore work in practice.
- */
-
-/**
- * Interrupt endpoint callback
- *
- * @v data             Received data
- * @v len              Length of received data
- * @v context          Callback context
- * @v status           Transfer status
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI usbio_interrupt_callback ( VOID *data, UINTN len,
-                                                   VOID *context,
-                                                   UINT32 status ) {
-       struct usbio_interrupt_ring *intr = context;
-       struct usbio_endpoint *endpoint = intr->endpoint;
-       struct usbio_device *usbio = endpoint->usbio;
-       struct usb_endpoint *ep = endpoint->ep;
-       EFI_HANDLE handle = usbio->handle;
-       unsigned int fill;
-       unsigned int index;
-
-       /* Sanity check */
-       assert ( len <= ep->mtu );
-
-       /* Do nothing if ring is empty */
-       fill = ( intr->prod - intr->cons );
-       if ( fill >= USBIO_INTR_COUNT ) {
-               DBGC ( usbio, "USBIO %s %s dropped interrupt completion\n",
-                      efi_handle_name ( handle ), usb_endpoint_name ( ep ) );
-               return 0;
-       }
-
-       /* Do nothing if transfer was unsuccessful */
-       if ( status != 0 ) {
-               DBGC ( usbio, "USBIO %s %s interrupt completion status %04x\n",
-                      efi_handle_name ( handle ), usb_endpoint_name ( ep ),
-                      status );
-               return 0; /* Unclear what failure actually means here */
-       }
-
-       /* Copy data to buffer and increment producer counter */
-       index = ( intr->prod % USBIO_INTR_COUNT );
-       memcpy ( intr->data[index], data, len );
-       intr->len[index] = len;
-       intr->prod++;
-
-       return 0;
-}
-
-/**
- * Open interrupt endpoint
- *
- * @v endpoint         Endpoint
- * @ret rc             Return status code
- */
-static int usbio_interrupt_open ( struct usbio_endpoint *endpoint ) {
-       struct usbio_device *usbio = endpoint->usbio;
-       struct usbio_interrupt_ring *intr;
-       struct usb_endpoint *ep = endpoint->ep;
-       EFI_USB_IO_PROTOCOL *io = endpoint->io;
-       EFI_HANDLE handle = usbio->handle;
-       unsigned int interval;
-       unsigned int i;
-       void *data;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Allocate interrupt ring buffer */
-       intr = zalloc ( sizeof ( *intr ) + ( USBIO_INTR_COUNT * ep->mtu ) );
-       if ( ! intr ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       endpoint->intr = intr;
-       intr->endpoint = endpoint;
-       data = ( ( ( void * ) intr ) + sizeof ( *intr ) );
-       for ( i = 0 ; i < USBIO_INTR_COUNT ; i++ ) {
-               intr->data[i] = data;
-               data += ep->mtu;
-       }
-
-       /* Determine polling interval */
-       interval = ( ep->interval >> 3 /* microframes -> milliseconds */ );
-       if ( ! interval )
-               interval = 1; /* May not be zero */
-
-       /* Add to periodic schedule */
-       if ( ( efirc = io->UsbAsyncInterruptTransfer ( io, ep->address, TRUE,
-                                                      interval, ep->mtu,
-                                                      usbio_interrupt_callback,
-                                                      intr ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( usbio, "USBIO %s %s could not schedule interrupt "
-                      "transfer: %s\n", efi_handle_name ( handle ),
-                      usb_endpoint_name ( ep ), strerror ( rc ) );
-               goto err_schedule;
-       }
-
-       return 0;
-
-       io->UsbAsyncInterruptTransfer ( io, ep->address, FALSE, 0, 0,
-                                       NULL, NULL );
- err_schedule:
-       free ( intr );
- err_alloc:
-       return rc;
-}
-
-/**
- * Close interrupt endpoint
- *
- * @v endpoint         Endpoint
- */
-static void usbio_interrupt_close ( struct usbio_endpoint *endpoint ) {
-       struct usb_endpoint *ep = endpoint->ep;
-       EFI_USB_IO_PROTOCOL *io = endpoint->io;
-
-       /* Remove from periodic schedule */
-       io->UsbAsyncInterruptTransfer ( io, ep->address, FALSE, 0, 0,
-                                       NULL, NULL );
-
-       /* Free interrupt ring buffer */
-       free ( endpoint->intr );
-}
-
-/**
- * Poll interrupt endpoint
- *
- * @v endpoint         Endpoint
- */
-static void usbio_interrupt_poll ( struct usbio_endpoint *endpoint ) {
-       struct usbio_interrupt_ring *intr = endpoint->intr;
-       struct usb_endpoint *ep = endpoint->ep;
-       struct io_buffer *iobuf;
-       unsigned int index;
-       unsigned int intr_index;
-       size_t len;
-
-       /* Do nothing if ring is empty */
-       if ( endpoint->cons == endpoint->prod )
-               return;
-
-       /* Do nothing if interrupt ring is empty */
-       if ( intr->cons == intr->prod )
-               return;
-
-       /* Consume next transfer */
-       index = ( endpoint->cons++ % USBIO_RING_COUNT );
-       iobuf = endpoint->iobuf[index];
-
-       /* Populate I/O buffer */
-       intr_index = ( intr->cons++ % USBIO_INTR_COUNT );
-       len = intr->len[intr_index];
-       assert ( len <= iob_len ( iobuf ) );
-       iob_put ( iobuf, ( len - iob_len ( iobuf ) ) );
-       memcpy ( iobuf->data, intr->data[intr_index], len );
-
-       /* Complete transfer */
-       usb_complete ( ep, iobuf );
-}
-
-/** Interrupt endpoint operations */
-static struct usbio_operations usbio_interrupt_operations = {
-       .open   = usbio_interrupt_open,
-       .close  = usbio_interrupt_close,
-       .poll   = usbio_interrupt_poll,
-};
-
-/******************************************************************************
- *
- * Endpoint operations
- *
- ******************************************************************************
- */
-
-/**
- * Open endpoint
- *
- * @v ep               USB endpoint
- * @ret rc             Return status code
- */
-static int usbio_endpoint_open ( struct usb_endpoint *ep ) {
-       struct usb_bus *bus = ep->usb->port->hub->bus;
-       struct usbio_device *usbio = usb_bus_get_hostdata ( bus );
-       struct usbio_endpoint *endpoint;
-       EFI_HANDLE handle = usbio->handle;
-       unsigned int attr = ( ep->attributes & USB_ENDPOINT_ATTR_TYPE_MASK );
-       int interface;
-       int rc;
-
-       /* Allocate and initialise structure */
-       endpoint = zalloc ( sizeof ( *endpoint ) );
-       if ( ! endpoint ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       usb_endpoint_set_hostdata ( ep, endpoint );
-       endpoint->usbio = usbio;
-       endpoint->ep = ep;
-
-       /* Identify endpoint operations */
-       if ( attr == USB_ENDPOINT_ATTR_CONTROL ) {
-               endpoint->op = &usbio_control_operations;
-       } else if ( attr == USB_ENDPOINT_ATTR_BULK ) {
-               endpoint->op = ( ( ep->address & USB_DIR_IN ) ?
-                                &usbio_bulk_in_operations :
-                                &usbio_bulk_out_operations );
-       } else if ( attr == USB_ENDPOINT_ATTR_INTERRUPT ) {
-               endpoint->op = &usbio_interrupt_operations;
-       } else {
-               rc = -ENOTSUP;
-               goto err_operations;
-       }
-
-       /* Identify interface for this endpoint */
-       interface = usbio_interface ( usbio, ep );
-       if ( interface < 0 ) {
-               rc = interface;
-               goto err_interface;
-       }
-       endpoint->interface = interface;
-
-       /* Open interface */
-       if ( ( rc = usbio_open ( usbio, interface ) ) != 0 )
-               goto err_open_interface;
-       endpoint->handle = usbio->interface[interface].handle;
-       endpoint->io = usbio->interface[interface].io;
-       DBGC ( usbio, "USBIO %s %s using ",
-              efi_handle_name ( handle ), usb_endpoint_name ( ep ) );
-       DBGC ( usbio, "%s\n", efi_handle_name ( endpoint->handle ) );
-
-       /* Open endpoint */
-       if ( ( rc = endpoint->op->open ( endpoint ) ) != 0 )
-               goto err_open_endpoint;
-
-       /* Add to list of endpoints */
-       list_add_tail ( &endpoint->list, &usbio->endpoints );
-
-       return 0;
-
-       list_del ( &endpoint->list );
-       endpoint->op->close ( endpoint );
- err_open_endpoint:
-       usbio_close ( usbio, interface );
- err_open_interface:
- err_interface:
- err_operations:
-       free ( endpoint );
- err_alloc:
-       return rc;
-}
-
-/**
- * Close endpoint
- *
- * @v ep               USB endpoint
- */
-static void usbio_endpoint_close ( struct usb_endpoint *ep ) {
-       struct usbio_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
-       struct usbio_device *usbio = endpoint->usbio;
-       struct io_buffer *iobuf;
-       unsigned int index;
-
-       /* Remove from list of endpoints */
-       list_del ( &endpoint->list );
-
-       /* Close endpoint */
-       endpoint->op->close ( endpoint );
-
-       /* Close interface */
-       usbio_close ( usbio, endpoint->interface );
-
-       /* Cancel any incomplete transfers */
-       while ( endpoint->cons != endpoint->prod ) {
-               index = ( endpoint->cons++ % USBIO_RING_COUNT );
-               iobuf = endpoint->iobuf[index];
-               usb_complete_err ( ep, iobuf, -ECANCELED );
-       }
-
-       /* Free endpoint */
-       free ( endpoint );
-}
-
-/**
- * Reset endpoint
- *
- * @v ep               USB endpoint
- * @ret rc             Return status code
- */
-static int usbio_endpoint_reset ( struct usb_endpoint *ep __unused ) {
-
-       /* Nothing to do */
-       return 0;
-}
-
-/**
- * Update MTU
- *
- * @v ep               USB endpoint
- * @ret rc             Return status code
- */
-static int usbio_endpoint_mtu ( struct usb_endpoint *ep __unused ) {
-
-       /* Nothing to do */
-       return 0;
-}
-
-/**
- * Enqueue transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @v flags            Transfer flags
- * @ret rc             Return status code
- */
-static int usbio_endpoint_enqueue ( struct usb_endpoint *ep,
-                                   struct io_buffer *iobuf,
-                                   unsigned int flags ) {
-       struct usbio_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
-       unsigned int fill;
-       unsigned int index;
-
-       /* Fail if transfer ring is full */
-       fill = ( endpoint->prod - endpoint->cons );
-       if ( fill >= USBIO_RING_COUNT )
-               return -ENOBUFS;
-
-       /* Add to ring */
-       index = ( endpoint->prod++ % USBIO_RING_COUNT );
-       endpoint->iobuf[index] = iobuf;
-       endpoint->flags[index] = flags;
-
-       return 0;
-}
-
-/**
- * Enqueue message transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @ret rc             Return status code
- */
-static int usbio_endpoint_message ( struct usb_endpoint *ep,
-                                   struct io_buffer *iobuf ) {
-
-       /* Enqueue transfer */
-       return usbio_endpoint_enqueue ( ep, iobuf, USBIO_MESSAGE );
-}
-
-/**
- * Enqueue stream transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @v zlp              Append a zero-length packet
- * @ret rc             Return status code
- */
-static int usbio_endpoint_stream ( struct usb_endpoint *ep,
-                                  struct io_buffer *iobuf, int zlp ) {
-
-       /* Enqueue transfer */
-       return usbio_endpoint_enqueue ( ep, iobuf, ( zlp ? USBIO_ZLEN : 0 ) );
-}
-
-/**
- * Poll for completions
- *
- * @v endpoint         Endpoint
- */
-static void usbio_endpoint_poll ( struct usbio_endpoint *endpoint ) {
-
-       /* Poll endpoint */
-       endpoint->op->poll ( endpoint );
-}
-
-/******************************************************************************
- *
- * Device operations
- *
- ******************************************************************************
- */
-
-/**
- * Open device
- *
- * @v usb              USB device
- * @ret rc             Return status code
- */
-static int usbio_device_open ( struct usb_device *usb ) {
-       struct usbio_device *usbio =
-               usb_bus_get_hostdata ( usb->port->hub->bus );
-
-       usb_set_hostdata ( usb, usbio );
-       return 0;
-}
-
-/**
- * Close device
- *
- * @v usb              USB device
- */
-static void usbio_device_close ( struct usb_device *usb __unused ) {
-
-       /* Nothing to do */
-}
-
-/**
- * Assign device address
- *
- * @v usb              USB device
- * @ret rc             Return status code
- */
-static int usbio_device_address ( struct usb_device *usb __unused ) {
-
-       /* Nothing to do */
-       return 0;
-}
-
-/******************************************************************************
- *
- * Hub operations
- *
- ******************************************************************************
- */
-
-/**
- * Open hub
- *
- * @v hub              USB hub
- * @ret rc             Return status code
- */
-static int usbio_hub_open ( struct usb_hub *hub ) {
-
-       /* Disallow non-root hubs */
-       if ( hub->usb )
-               return -ENOTSUP;
-
-       /* Nothing to do */
-       return 0;
-}
-
-/**
- * Close hub
- *
- * @v hub              USB hub
- */
-static void usbio_hub_close ( struct usb_hub *hub __unused ) {
-
-       /* Nothing to do */
-}
-
-/******************************************************************************
- *
- * Root hub operations
- *
- ******************************************************************************
- */
-
-/**
- * Open root hub
- *
- * @v hub              USB hub
- * @ret rc             Return status code
- */
-static int usbio_root_open ( struct usb_hub *hub __unused ) {
-
-       /* Nothing to do */
-       return 0;
-}
-
-/**
- * Close root hub
- *
- * @v hub              USB hub
- */
-static void usbio_root_close ( struct usb_hub *hub __unused ) {
-
-       /* Nothing to do */
-}
-
-/**
- * Enable port
- *
- * @v hub              USB hub
- * @v port             USB port
- * @ret rc             Return status code
- */
-static int usbio_root_enable ( struct usb_hub *hub __unused,
-                              struct usb_port *port __unused ) {
-
-       /* Nothing to do */
-       return 0;
-}
-
-/**
- * Disable port
- *
- * @v hub              USB hub
- * @v port             USB port
- * @ret rc             Return status code
- */
-static int usbio_root_disable ( struct usb_hub *hub __unused,
-                               struct usb_port *port __unused ) {
-
-       /* Nothing to do */
-       return 0;
-}
-
-/**
- * Update root hub port speed
- *
- * @v hub              USB hub
- * @v port             USB port
- * @ret rc             Return status code
- */
-static int usbio_root_speed ( struct usb_hub *hub __unused,
-                             struct usb_port *port ) {
-
-       /* Not actually exposed via EFI_USB_IO_PROTOCOL */
-       port->speed = USB_SPEED_HIGH;
-       return 0;
-}
-
-/**
- * Clear transaction translator buffer
- *
- * @v hub              USB hub
- * @v port             USB port
- * @v ep               USB endpoint
- * @ret rc             Return status code
- */
-static int usbio_root_clear_tt ( struct usb_hub *hub __unused,
-                                struct usb_port *port __unused,
-                                struct usb_endpoint *ep __unused ) {
-
-       /* Should never be called; this is a root hub */
-       return -ENOTSUP;
-}
-
-/******************************************************************************
- *
- * Bus operations
- *
- ******************************************************************************
- */
-
-/**
- * Open USB bus
- *
- * @v bus              USB bus
- * @ret rc             Return status code
- */
-static int usbio_bus_open ( struct usb_bus *bus __unused ) {
-
-       /* Nothing to do */
-       return 0;
-}
-
-/**
- * Close USB bus
- *
- * @v bus              USB bus
- */
-static void usbio_bus_close ( struct usb_bus *bus __unused ) {
-
-       /* Nothing to do */
-}
-
-/**
- * Poll USB bus
- *
- * @v bus              USB bus
- */
-static void usbio_bus_poll ( struct usb_bus *bus ) {
-       struct usbio_device *usbio = usb_bus_get_hostdata ( bus );
-       struct usbio_endpoint *endpoint;
-
-       /* Poll all endpoints.  We trust that completion handlers are
-        * minimal and will not do anything that could plausibly
-        * affect the endpoint list itself.
-        */
-       list_for_each_entry ( endpoint, &usbio->endpoints, list )
-               usbio_endpoint_poll ( endpoint );
-}
-
-/******************************************************************************
- *
- * EFI driver interface
- *
- ******************************************************************************
- */
-
-/** USB I/O host controller driver operations */
-static struct usb_host_operations usbio_operations = {
-       .endpoint = {
-               .open = usbio_endpoint_open,
-               .close = usbio_endpoint_close,
-               .reset = usbio_endpoint_reset,
-               .mtu = usbio_endpoint_mtu,
-               .message = usbio_endpoint_message,
-               .stream = usbio_endpoint_stream,
-       },
-       .device = {
-               .open = usbio_device_open,
-               .close = usbio_device_close,
-               .address = usbio_device_address,
-       },
-       .bus = {
-               .open = usbio_bus_open,
-               .close = usbio_bus_close,
-               .poll = usbio_bus_poll,
-       },
-       .hub = {
-               .open = usbio_hub_open,
-               .close = usbio_hub_close,
-       },
-       .root = {
-               .open = usbio_root_open,
-               .close = usbio_root_close,
-               .enable = usbio_root_enable,
-               .disable = usbio_root_disable,
-               .speed = usbio_root_speed,
-               .clear_tt = usbio_root_clear_tt,
-       },
-};
-
-/**
- * Check to see if driver supports a device
- *
- * @v handle           EFI device handle
- * @ret rc             Return status code
- */
-static int usbio_supported ( EFI_HANDLE handle ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_USB_DEVICE_DESCRIPTOR device;
-       EFI_USB_INTERFACE_DESCRIPTOR interface;
-       struct usb_function_descriptor desc;
-       struct usb_driver *driver;
-       struct usb_device_id *id;
-       union {
-               void *interface;
-               EFI_USB_IO_PROTOCOL *io;
-       } usb;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Get protocol */
-       if ( ( efirc = bs->OpenProtocol ( handle, &efi_usb_io_protocol_guid,
-                                         &usb.interface, efi_image_handle,
-                                         handle,
-                                         EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
-               rc = -EEFI ( efirc );
-               DBGCP ( handle, "USB %s is not a USB device\n",
-                       efi_handle_name ( handle ) );
-               goto err_open_protocol;
-       }
-
-       /* Get device descriptor */
-       if ( ( efirc = usb.io->UsbGetDeviceDescriptor ( usb.io,
-                                                       &device ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( handle, "USB %s could not get device descriptor: "
-                      "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
-               goto err_get_device_descriptor;
-       }
-       memset ( &desc, 0, sizeof ( desc ) );
-       desc.vendor = device.IdVendor;
-       desc.product = device.IdProduct;
-
-       /* Get interface descriptor */
-       if ( ( efirc = usb.io->UsbGetInterfaceDescriptor ( usb.io,
-                                                          &interface ) ) !=0){
-               rc = -EEFI ( efirc );
-               DBGC ( handle, "USB %s could not get interface descriptor: "
-                      "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
-               goto err_get_interface_descriptor;
-       }
-       desc.class.class.class = interface.InterfaceClass;
-       desc.class.class.subclass = interface.InterfaceSubClass;
-       desc.class.class.protocol = interface.InterfaceProtocol;
-
-       /* Look for a driver for this interface */
-       driver = usb_find_driver ( &desc, &id );
-       if ( ! driver ) {
-               rc = -ENOTSUP;
-               goto err_unsupported;
-       }
-
-       /* Success */
-       rc = 0;
-
- err_unsupported:
- err_get_interface_descriptor:
- err_get_device_descriptor:
-       bs->CloseProtocol ( handle, &efi_usb_io_protocol_guid,
-                           efi_image_handle, handle );
- err_open_protocol:
-       return rc;
-}
-
-/**
- * Fetch configuration descriptor
- *
- * @v usbio            USB I/O device
- * @ret rc             Return status code
- */
-static int usbio_config ( struct usbio_device *usbio ) {
-       EFI_HANDLE handle = usbio->handle;
-       EFI_USB_IO_PROTOCOL *io = usbio->io;
-       EFI_USB_DEVICE_DESCRIPTOR device;
-       EFI_USB_CONFIG_DESCRIPTOR partial;
-       union {
-               struct usb_setup_packet setup;
-               EFI_USB_DEVICE_REQUEST efi;
-       } msg;
-       UINT32 status;
-       size_t len;
-       unsigned int count;
-       unsigned int value;
-       unsigned int i;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Get device descriptor */
-       if ( ( efirc = io->UsbGetDeviceDescriptor ( io, &device ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( usbio, "USB %s could not get device descriptor: "
-                      "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
-               goto err_get_device_descriptor;
-       }
-       count = device.NumConfigurations;
-
-       /* Get current partial configuration descriptor */
-       if ( ( efirc = io->UsbGetConfigDescriptor ( io, &partial ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( usbio, "USB %s could not get partial configuration "
-                      "descriptor: %s\n", efi_handle_name ( handle ),
-                      strerror ( rc ) );
-               goto err_get_configuration_descriptor;
-       }
-       len = le16_to_cpu ( partial.TotalLength );
-
-       /* Allocate configuration descriptor */
-       usbio->config = malloc ( len );
-       if ( ! usbio->config ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-
-       /* There is, naturally, no way to retrieve the entire device
-        * configuration descriptor via EFI_USB_IO_PROTOCOL.  Worse,
-        * there is no way to even retrieve the index of the current
-        * configuration descriptor.  We have to iterate over all
-        * possible configuration descriptors looking for the
-        * descriptor that matches the current configuration value.
-        */
-       for ( i = 0 ; i < count ; i++ ) {
-
-               /* Construct request */
-               msg.setup.request = cpu_to_le16 ( USB_GET_DESCRIPTOR );
-               value = ( ( USB_CONFIGURATION_DESCRIPTOR << 8 ) | i );
-               msg.setup.value = cpu_to_le16 ( value );
-               msg.setup.index = 0;
-               msg.setup.len = cpu_to_le16 ( len );
-
-               /* Get full configuration descriptor */
-               if ( ( efirc = io->UsbControlTransfer ( io, &msg.efi,
-                                                       EfiUsbDataIn, 0,
-                                                       usbio->config, len,
-                                                       &status ) ) != 0 ) {
-                       rc = -EEFI ( efirc );
-                       DBGC ( usbio, "USB %s could not get configuration %d "
-                              "descriptor: %s\n", efi_handle_name ( handle ),
-                              i, strerror ( rc ) );
-                       goto err_control_transfer;
-               }
-
-               /* Ignore unless this is the current configuration */
-               if ( usbio->config->config != partial.ConfigurationValue )
-                       continue;
-
-               /* Check length */
-               if ( le16_to_cpu ( usbio->config->len ) != len ) {
-                       DBGC ( usbio, "USB %s configuration descriptor length "
-                              "mismatch\n", efi_handle_name ( handle ) );
-                       rc = -EINVAL;
-                       goto err_len;
-               }
-
-               return 0;
-       }
-
-       /* No match found */
-       DBGC ( usbio, "USB %s could not find current configuration "
-              "descriptor\n", efi_handle_name ( handle ) );
-       rc = -ENOENT;
-
- err_len:
- err_control_transfer:
-       free ( usbio->config );
- err_alloc:
- err_get_configuration_descriptor:
- err_get_device_descriptor:
-       return rc;
-}
-
-/**
- * Construct device path for opening other interfaces
- *
- * @v usbio            USB I/O device
- * @ret rc             Return status code
- */
-static int usbio_path ( struct usbio_device *usbio ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_HANDLE handle = usbio->handle;
-       EFI_DEVICE_PATH_PROTOCOL *path;
-       EFI_DEVICE_PATH_PROTOCOL *end;
-       USB_DEVICE_PATH *usbpath;
-       union {
-               void *interface;
-               EFI_DEVICE_PATH_PROTOCOL *path;
-       } u;
-       size_t len;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Open device path protocol */
-       if ( ( efirc = bs->OpenProtocol ( handle,
-                                         &efi_device_path_protocol_guid,
-                                         &u.interface, efi_image_handle,
-                                         handle,
-                                         EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
-               rc = -EEFI ( efirc );
-               DBGC ( usbio, "USBIO %s cannot open device path protocol: "
-                      "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
-               goto err_open_protocol;
-       }
-       path = u.interface;
-
-       /* Locate end of device path and sanity check */
-       len = efi_devpath_len ( path );
-       if ( len < sizeof ( *usbpath ) ) {
-               DBGC ( usbio, "USBIO %s underlength device path\n",
-                      efi_handle_name ( handle ) );
-               rc = -EINVAL;
-               goto err_underlength;
-       }
-       usbpath = ( ( ( void * ) path ) + len - sizeof ( *usbpath ) );
-       if ( ! ( ( usbpath->Header.Type == MESSAGING_DEVICE_PATH ) &&
-                ( usbpath->Header.SubType == MSG_USB_DP ) ) ) {
-               DBGC ( usbio, "USBIO %s not a USB device path: ",
-                      efi_handle_name ( handle ) );
-               DBGC ( usbio, "%s\n", efi_devpath_text ( path ) );
-               rc = -EINVAL;
-               goto err_non_usb;
-       }
-
-       /* Allocate copy of device path */
-       usbio->path = malloc ( len + sizeof ( *end ) );
-       if ( ! usbio->path ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       memcpy ( usbio->path, path, ( len + sizeof ( *end ) ) );
-       usbio->usbpath = ( ( ( void * ) usbio->path ) + len -
-                          sizeof ( *usbpath ) );
-
-       /* Close protocol */
-       bs->CloseProtocol ( handle, &efi_device_path_protocol_guid,
-                           efi_image_handle, handle );
-
-       return 0;
-
-       free ( usbio->path );
- err_alloc:
- err_non_usb:
- err_underlength:
-       bs->CloseProtocol ( handle, &efi_device_path_protocol_guid,
-                           efi_image_handle, handle );
- err_open_protocol:
-       return rc;
-}
-
-/**
- * Construct interface list
- *
- * @v usbio            USB I/O device
- * @ret rc             Return status code
- */
-static int usbio_interfaces ( struct usbio_device *usbio ) {
-       EFI_HANDLE handle = usbio->handle;
-       EFI_USB_IO_PROTOCOL *io = usbio->io;
-       EFI_USB_INTERFACE_DESCRIPTOR interface;
-       unsigned int first;
-       unsigned int count;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Get interface descriptor */
-       if ( ( efirc = io->UsbGetInterfaceDescriptor ( io, &interface ) ) != 0){
-               rc = -EEFI ( efirc );
-               DBGC ( usbio, "USB %s could not get interface descriptor: "
-                      "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
-               goto err_get_interface_descriptor;
-       }
-
-       /* Record first interface number */
-       first = interface.InterfaceNumber;
-       count = usbio->config->interfaces;
-       assert ( first < count );
-       usbio->first = first;
-
-       /* Allocate interface list */
-       usbio->interface = zalloc ( count * sizeof ( usbio->interface[0] ) );
-       if ( ! usbio->interface ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-
-       /* Use already-opened protocol for control transfers and for
-        * the first interface.
-        */
-       usbio->interface[0].handle = handle;
-       usbio->interface[0].io = io;
-       usbio->interface[0].count = 1;
-       usbio->interface[first].handle = handle;
-       usbio->interface[first].io = io;
-       usbio->interface[first].count = 1;
-
-       return 0;
-
-       free ( usbio->interface );
- err_alloc:
- err_get_interface_descriptor:
-       return rc;
-}
-
-/**
- * Attach driver to device
- *
- * @v efidev           EFI device
- * @ret rc             Return status code
- */
-static int usbio_start ( struct efi_device *efidev ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_HANDLE handle = efidev->device;
-       struct usbio_device *usbio;
-       struct usb_port *port;
-       union {
-               void *interface;
-               EFI_USB_IO_PROTOCOL *io;
-       } u;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Allocate and initialise structure */
-       usbio = zalloc ( sizeof ( *usbio ) );
-       if ( ! usbio ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       efidev_set_drvdata ( efidev, usbio );
-       usbio->handle = handle;
-       INIT_LIST_HEAD ( &usbio->endpoints );
-
-       /* Open USB I/O protocol */
-       if ( ( efirc = bs->OpenProtocol ( handle, &efi_usb_io_protocol_guid,
-                                         &u.interface, efi_image_handle,
-                                         handle,
-                                         ( EFI_OPEN_PROTOCOL_BY_DRIVER |
-                                           EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
-               rc = -EEFI ( efirc );
-               DBGC ( usbio, "USBIO %s cannot open USB I/O protocol: %s\n",
-                      efi_handle_name ( handle ), strerror ( rc ) );
-               DBGC_EFI_OPENERS ( usbio, handle, &efi_usb_io_protocol_guid );
-               goto err_open_usbio;
-       }
-       usbio->io = u.io;
-
-       /* Describe generic device */
-       efi_device_info ( handle, "USB", &usbio->dev );
-       usbio->dev.parent = &efidev->dev;
-       list_add ( &usbio->dev.siblings, &efidev->dev.children );
-       INIT_LIST_HEAD ( &usbio->dev.children );
-
-       /* Fetch configuration descriptor */
-       if ( ( rc = usbio_config ( usbio ) ) != 0 )
-               goto err_config;
-
-       /* Construct device path */
-       if ( ( rc = usbio_path ( usbio ) ) != 0 )
-               goto err_path;
-
-       /* Construct interface list */
-       if ( ( rc = usbio_interfaces ( usbio ) ) != 0 )
-               goto err_interfaces;
-
-       /* Allocate USB bus */
-       usbio->bus = alloc_usb_bus ( &usbio->dev, 1 /* single "port" */,
-                                    USBIO_MTU, &usbio_operations );
-       if ( ! usbio->bus ) {
-               rc = -ENOMEM;
-               goto err_alloc_bus;
-       }
-       usb_bus_set_hostdata ( usbio->bus, usbio );
-       usb_hub_set_drvdata ( usbio->bus->hub, usbio );
-
-       /* Set port protocol */
-       port = usb_port ( usbio->bus->hub, 1 );
-       port->protocol = USB_PROTO_2_0;
-
-       /* Register USB bus */
-       if ( ( rc = register_usb_bus ( usbio->bus ) ) != 0 )
-               goto err_register;
-
-       return 0;
-
-       unregister_usb_bus ( usbio->bus );
- err_register:
-       free_usb_bus ( usbio->bus );
- err_alloc_bus:
-       free ( usbio->interface );
- err_interfaces:
-       free ( usbio->path );
- err_path:
-       free ( usbio->config );
- err_config:
-       list_del ( &usbio->dev.siblings );
-       bs->CloseProtocol ( handle, &efi_usb_io_protocol_guid,
-                           efi_image_handle, handle );
- err_open_usbio:
-       free ( usbio );
- err_alloc:
-       return rc;
-}
-
-/**
- * Detach driver from device
- *
- * @v efidev           EFI device
- */
-static void usbio_stop ( struct efi_device *efidev ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_HANDLE handle = efidev->device;
-       struct usbio_device *usbio = efidev_get_drvdata ( efidev );
-
-       unregister_usb_bus ( usbio->bus );
-       free_usb_bus ( usbio->bus );
-       free ( usbio->interface );
-       free ( usbio->path );
-       free ( usbio->config );
-       list_del ( &usbio->dev.siblings );
-       bs->CloseProtocol ( handle, &efi_usb_io_protocol_guid,
-                           efi_image_handle, handle );
-       free ( usbio );
-}
-
-/** EFI USB I/O driver */
-struct efi_driver usbio_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
-       .name = "USBIO",
-       .supported = usbio_supported,
-       .start = usbio_start,
-       .stop = usbio_stop,
-};
diff --git a/roms/ipxe/src/drivers/usb/usbio.h b/roms/ipxe/src/drivers/usb/usbio.h
deleted file mode 100644 (file)
index 1d02876..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-#ifndef _USBIO_H
-#define _USBIO_H
-
-/** @file
- *
- * EFI_USB_IO_PROTOCOL pseudo Host Controller Interface driver
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/list.h>
-#include <ipxe/device.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/Protocol/UsbIo.h>
-#include <ipxe/efi/Protocol/DevicePath.h>
-#include <ipxe/usb.h>
-
-/** USB I/O maximum transfer size
- *
- * The API provides no way to discover the maximum transfer size.
- * Assume the 16kB supported by EHCI.
- */
-#define USBIO_MTU 16384
-
-/** USB I/O interrupt ring buffer size
- *
- * This is a policy decision.
- */
-#define USBIO_INTR_COUNT 4
-
-/** A USB interrupt ring buffer */
-struct usbio_interrupt_ring {
-       /** USB I/O endpoint */
-       struct usbio_endpoint *endpoint;
-       /** Producer counter */
-       unsigned int prod;
-       /** Consumer counter */
-       unsigned int cons;
-       /** Data buffers */
-       void *data[USBIO_INTR_COUNT];
-       /** Lengths */
-       size_t len[USBIO_INTR_COUNT];
-};
-
-/** USB I/O ring buffer size
- *
- * This is a policy decision.
- */
-#define USBIO_RING_COUNT 64
-
-/** A USB I/O endpoint */
-struct usbio_endpoint {
-       /** USB I/O device */
-       struct usbio_device *usbio;
-       /** USB endpoint */
-       struct usb_endpoint *ep;
-       /** List of endpoints */
-       struct list_head list;
-       /** USB I/O endpoint operations */
-       struct usbio_operations *op;
-
-       /** Containing interface number */
-       unsigned int interface;
-       /** EFI handle */
-       EFI_HANDLE handle;
-       /** USB I/O protocol */
-       EFI_USB_IO_PROTOCOL *io;
-
-       /** Producer counter */
-       unsigned int prod;
-       /** Consumer counter */
-       unsigned int cons;
-       /** I/O buffers */
-       struct io_buffer *iobuf[USBIO_RING_COUNT];
-       /** Flags */
-       uint8_t flags[USBIO_RING_COUNT];
-
-       /** Interrupt ring buffer (if applicable) */
-       struct usbio_interrupt_ring *intr;
-};
-
-/** USB I/O transfer flags */
-enum usbio_flags {
-       /** This is a message transfer */
-       USBIO_MESSAGE = 0x01,
-       /** This transfer requires zero-length packet termination */
-       USBIO_ZLEN = 0x02,
-};
-
-/** USB I/O endpoint operations */
-struct usbio_operations {
-       /** Open endpoint
-        *
-        * @v endpoint          Endpoint
-        * @ret rc              Return status code
-        */
-       int ( * open ) ( struct usbio_endpoint *endpoint );
-       /** Close endpoint
-        *
-        * @v endpoint          Endpoint
-        */
-       void ( * close ) ( struct usbio_endpoint *endpoint );
-       /** Poll endpoint
-        *
-        * @v endpoint          Endpoint
-        */
-       void ( * poll ) ( struct usbio_endpoint *endpoint );
-};
-
-/** A USB I/O protocol interface */
-struct usbio_interface {
-       /** EFI device handle */
-       EFI_HANDLE handle;
-       /** USB I/O protocol */
-       EFI_USB_IO_PROTOCOL *io;
-       /** Usage count */
-       unsigned int count;
-};
-
-/** A USB I/O protocol device
- *
- * We model each externally-provided USB I/O protocol device as a host
- * controller containing a root hub with a single port.
- */
-struct usbio_device {
-       /** EFI device handle */
-       EFI_HANDLE handle;
-       /** USB I/O protocol */
-       EFI_USB_IO_PROTOCOL *io;
-       /** Generic device */
-       struct device dev;
-
-       /** Configuration descriptor */
-       struct usb_configuration_descriptor *config;
-
-       /** Device path */
-       EFI_DEVICE_PATH_PROTOCOL *path;
-       /** Final component of USB device path */
-       USB_DEVICE_PATH *usbpath;
-
-       /** First interface number */
-       uint8_t first;
-       /** USB I/O protocol interfaces */
-       struct usbio_interface *interface;
-
-       /** USB bus */
-       struct usb_bus *bus;
-       /** List of endpoints */
-       struct list_head endpoints;
-};
-
-#endif /* _USBIO_H */
index a8ab6ab..ea94f2e 100644 (file)
@@ -53,14 +53,13 @@ static LIST_HEAD ( usb_keyboards );
  *
  * @v keycode          Keycode
  * @v modifiers                Modifiers
- * @v leds             LED state
  * @ret key            iPXE key
  *
  * Key codes are defined in the USB HID Usage Tables Keyboard/Keypad
  * page.
  */
-static unsigned int usbkbd_map ( unsigned int keycode, unsigned int modifiers,
-                                unsigned int leds ) {
+static unsigned int usbkbd_map ( unsigned int keycode,
+                                unsigned int modifiers ) {
        unsigned int key;
 
        if ( keycode < USBKBD_KEY_A ) {
@@ -71,8 +70,7 @@ static unsigned int usbkbd_map ( unsigned int keycode, unsigned int modifiers,
                key = ( keycode - USBKBD_KEY_A + 'a' );
                if ( modifiers & USBKBD_CTRL ) {
                        key -= ( 'a' - CTRL_A );
-               } else if ( ( modifiers & USBKBD_SHIFT ) ||
-                           ( leds & USBKBD_LED_CAPS_LOCK ) ) {
+               } else if ( modifiers & USBKBD_SHIFT ) {
                        key -= ( 'a' - 'A' );
                }
        } else if ( keycode <= USBKBD_KEY_0 ) {
@@ -102,22 +100,7 @@ static unsigned int usbkbd_map ( unsigned int keycode, unsigned int modifiers,
                        KEY_PPAGE, KEY_DC, KEY_END, KEY_NPAGE, KEY_RIGHT,
                        KEY_LEFT, KEY_DOWN, KEY_UP
                };
-               key = special[ keycode - USBKBD_KEY_CAPS_LOCK ];
-       } else if ( keycode <= USBKBD_KEY_PAD_ENTER ) {
-               /* Keypad (unaffected by Num Lock) */
-               key = "\0/*-+\n" [ keycode - USBKBD_KEY_NUM_LOCK ];
-       } else if ( keycode <= USBKBD_KEY_PAD_DOT ) {
-               /* Keypad (affected by Num Lock) */
-               if ( leds & USBKBD_LED_NUM_LOCK ) {
-                       key = "1234567890." [ keycode - USBKBD_KEY_PAD_1 ];
-               } else {
-                       static const uint16_t keypad[] = {
-                               KEY_END, KEY_DOWN, KEY_NPAGE, KEY_LEFT, 0,
-                               KEY_RIGHT, KEY_HOME, KEY_UP, KEY_PPAGE,
-                               KEY_IC, KEY_DC
-                       };
-                       key = keypad[ keycode - USBKBD_KEY_PAD_1 ];
-               };
+               key = special[ keycode - USBKBD_KEY_CAPSLOCK ];
        } else {
                key = 0;
        }
@@ -141,25 +124,10 @@ static unsigned int usbkbd_map ( unsigned int keycode, unsigned int modifiers,
  */
 static void usbkbd_produce ( struct usb_keyboard *kbd, unsigned int keycode,
                             unsigned int modifiers ) {
-       unsigned int leds = 0;
        unsigned int key;
 
-       /* Check for LED-modifying keys */
-       if ( keycode == USBKBD_KEY_CAPS_LOCK ) {
-               leds = USBKBD_LED_CAPS_LOCK;
-       } else if ( keycode == USBKBD_KEY_NUM_LOCK ) {
-               leds = USBKBD_LED_NUM_LOCK;
-       }
-
-       /* Handle LED-modifying keys */
-       if ( leds ) {
-               kbd->leds ^= leds;
-               kbd->leds_changed = 1;
-               return;
-       }
-
        /* Map to iPXE key */
-       key = usbkbd_map ( keycode, modifiers, kbd->leds );
+       key = usbkbd_map ( keycode, modifiers );
 
        /* Do nothing if this keycode has no corresponding iPXE key */
        if ( ! key ) {
@@ -367,37 +335,6 @@ static struct usb_endpoint_driver_operations usbkbd_operations = {
 
 /******************************************************************************
  *
- * Keyboard LEDs
- *
- ******************************************************************************
- */
-
-/**
- * Set keyboard LEDs
- *
- * @v kbd              USB keyboard
- * @ret rc             Return status code
- */
-static int usbkbd_set_leds ( struct usb_keyboard *kbd ) {
-       struct usb_function *func = kbd->hid.func;
-       int rc;
-
-       DBGC2 ( kbd, "KBD %s setting LEDs to %#02x\n", kbd->name, kbd->leds );
-
-       /* Set keyboard LEDs */
-       if ( ( rc = usbhid_set_report ( func->usb, func->interface[0],
-                                       USBHID_REPORT_OUTPUT, 0, &kbd->leds,
-                                       sizeof ( kbd->leds ) ) ) != 0 ) {
-               DBGC ( kbd, "KBD %s could not set LEDs to %#02x: %s\n",
-                      kbd->name, kbd->leds, strerror ( rc ) );
-               return rc;
-       }
-
-       return 0;
-}
-
-/******************************************************************************
- *
  * USB interface
  *
  ******************************************************************************
@@ -425,7 +362,7 @@ static int usbkbd_probe ( struct usb_function *func,
        kbd->name = func->name;
        kbd->bus = usb->port->hub->bus;
        usbhid_init ( &kbd->hid, func, &usbkbd_operations, NULL );
-       usb_refill_init ( &kbd->hid.in, 0, sizeof ( kbd->report ),
+       usb_refill_init ( &kbd->hid.in, sizeof ( kbd->report ),
                          USBKBD_INTR_MAX_FILL );
 
        /* Describe USB human interface device */
@@ -463,9 +400,6 @@ static int usbkbd_probe ( struct usb_function *func,
        /* Add to list of USB keyboards */
        list_add_tail ( &kbd->list, &usb_keyboards );
 
-       /* Set initial LED state */
-       usbkbd_set_leds ( kbd );
-
        usb_func_set_drvdata ( func, kbd );
        return 0;
 
@@ -503,6 +437,11 @@ static struct usb_device_id usbkbd_ids[] = {
                .name = "kbd",
                .vendor = USB_ANY_ID,
                .product = USB_ANY_ID,
+               .class = {
+                       .class = USB_CLASS_HID,
+                       .subclass = USB_SUBCLASS_HID_BOOT,
+                       .protocol = USBKBD_PROTOCOL,
+               },
        },
 };
 
@@ -510,9 +449,6 @@ static struct usb_device_id usbkbd_ids[] = {
 struct usb_driver usbkbd_driver __usb_driver = {
        .ids = usbkbd_ids,
        .id_count = ( sizeof ( usbkbd_ids ) / sizeof ( usbkbd_ids[0] ) ),
-       .class = USB_CLASS_ID ( USB_CLASS_HID, USB_SUBCLASS_HID_BOOT,
-                               USBKBD_PROTOCOL ),
-       .score = USB_SCORE_NORMAL,
        .probe = usbkbd_probe,
        .remove = usbkbd_remove,
 };
@@ -550,20 +486,10 @@ static int usbkbd_iskey ( void ) {
        struct usb_keyboard *kbd;
        unsigned int fill;
 
-       /* Poll USB keyboards, refill endpoints, and set LEDs if applicable */
+       /* Poll all USB keyboards and refill endpoints */
        list_for_each_entry ( kbd, &usb_keyboards, list ) {
-
-               /* Poll keyboard */
                usb_poll ( kbd->bus );
-
-               /* Refill endpoints */
                usb_refill ( &kbd->hid.in );
-
-               /* Update keyboard LEDs, if applicable */
-               if ( kbd->leds_changed ) {
-                       usbkbd_set_leds ( kbd );
-                       kbd->leds_changed = 0;
-               }
        }
 
        /* Check for a non-empty keyboard buffer */
index cedebfe..7eab24e 100644 (file)
@@ -68,20 +68,8 @@ enum usb_keycode {
        USBKBD_KEY_SPACE = 0x2c,
        USBKBD_KEY_MINUS = 0x2d,
        USBKBD_KEY_SLASH = 0x38,
-       USBKBD_KEY_CAPS_LOCK = 0x39,
-       USBKBD_KEY_F1 = 0x3a,
+       USBKBD_KEY_CAPSLOCK = 0x39,
        USBKBD_KEY_UP = 0x52,
-       USBKBD_KEY_NUM_LOCK = 0x53,
-       USBKBD_KEY_PAD_ENTER = 0x58,
-       USBKBD_KEY_PAD_1 = 0x59,
-       USBKBD_KEY_PAD_DOT = 0x63,
-};
-
-/** USB keyboard LEDs */
-enum usb_keyboard_led {
-       USBKBD_LED_NUM_LOCK = 0x01,
-       USBKBD_LED_CAPS_LOCK = 0x02,
-       USBKBD_LED_SCROLL_LOCK = 0x04,
 };
 
 /** Keyboard idle duration (in 4ms units)
@@ -132,11 +120,6 @@ struct usb_keyboard {
        /** Autorepeat hold-off time (in number of completions reported) */
        unsigned int holdoff;
 
-       /** Keyboard LED state */
-       uint8_t leds;
-       /** Keyboard LEDs changed */
-       uint8_t leds_changed;
-
        /** Keyboard buffer
         *
         * This stores iPXE key values.
index d18d817..b92336d 100644 (file)
@@ -173,7 +173,7 @@ static int usbnet_comms_describe ( struct usbnet_device *usbnet,
        int rc;
 
        /* Iterate over all available interfaces */
-       for ( i = 0 ; i < usbnet->func->desc.count ; i++ ) {
+       for ( i = 0 ; i < usbnet->func->count ; i++ ) {
 
                /* Get interface number */
                comms = usbnet->func->interface[i];
@@ -217,7 +217,7 @@ static int usbnet_data_describe ( struct usbnet_device *usbnet,
        int rc;
 
        /* Iterate over all available interfaces */
-       for ( i = 0 ; i < usbnet->func->desc.count ; i++ ) {
+       for ( i = 0 ; i < usbnet->func->count ; i++ ) {
 
                /* Get interface number */
                data = usbnet->func->interface[i];
index 48ac6a3..49e6731 100644 (file)
@@ -2542,44 +2542,20 @@ static int xhci_endpoint_message ( struct usb_endpoint *ep,
 }
 
 /**
- * Calculate number of TRBs
- *
- * @v len              Length of data
- * @v zlp              Append a zero-length packet
- * @ret count          Number of transfer descriptors
- */
-static unsigned int xhci_endpoint_count ( size_t len, int zlp ) {
-       unsigned int count;
-
-       /* Split into 64kB TRBs */
-       count = ( ( len + XHCI_MTU - 1 ) / XHCI_MTU );
-
-       /* Append a zero-length TRB if applicable */
-       if ( zlp || ( count == 0 ) )
-               count++;
-
-       return count;
-}
-
-/**
  * Enqueue stream transfer
  *
  * @v ep               USB endpoint
  * @v iobuf            I/O buffer
- * @v zlp              Append a zero-length packet
+ * @v terminate                Terminate using a short packet
  * @ret rc             Return status code
  */
 static int xhci_endpoint_stream ( struct usb_endpoint *ep,
-                                 struct io_buffer *iobuf, int zlp ) {
+                                 struct io_buffer *iobuf, int terminate ) {
        struct xhci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
-       void *data = iobuf->data;
-       size_t len = iob_len ( iobuf );
-       unsigned int count = xhci_endpoint_count ( len, zlp );
-       union xhci_trb trbs[count];
+       union xhci_trb trbs[ 1 /* Normal */ + 1 /* Possible zero-length */ ];
        union xhci_trb *trb = trbs;
        struct xhci_trb_normal *normal;
-       unsigned int i;
-       size_t trb_len;
+       size_t len = iob_len ( iobuf );
        int rc;
 
        /* Profile stream transfers */
@@ -2587,36 +2563,20 @@ static int xhci_endpoint_stream ( struct usb_endpoint *ep,
 
        /* Construct normal TRBs */
        memset ( &trbs, 0, sizeof ( trbs ) );
-       for ( i = 0 ; i < count ; i ++ ) {
-
-               /* Calculate TRB length */
-               trb_len = XHCI_MTU;
-               if ( trb_len > len )
-                       trb_len = len;
-
-               /* Construct normal TRB */
-               normal = &trb->normal;
-               normal->data = cpu_to_le64 ( virt_to_phys ( data ) );
-               normal->len = cpu_to_le32 ( trb_len );
-               normal->type = XHCI_TRB_NORMAL;
+       normal = &(trb++)->normal;
+       normal->data = cpu_to_le64 ( virt_to_phys ( iobuf->data ) );
+       normal->len = cpu_to_le32 ( len );
+       normal->type = XHCI_TRB_NORMAL;
+       if ( terminate && ( ( len & ( ep->mtu - 1 ) ) == 0 ) ) {
                normal->flags = XHCI_TRB_CH;
-
-               /* Move to next TRB */
-               data += trb_len;
-               len -= trb_len;
-               trb++;
+               normal = &(trb++)->normal;
+               normal->type = XHCI_TRB_NORMAL;
        }
-
-       /* Mark zero-length packet (if present) as a separate transfer */
-       if ( zlp && ( count > 1 ) )
-               trb[-2].normal.flags = 0;
-
-       /* Generate completion for final TRB */
-       trb[-1].normal.flags = XHCI_TRB_IOC;
+       normal->flags = XHCI_TRB_IOC;
 
        /* Enqueue TRBs */
        if ( ( rc = xhci_enqueue_multi ( &endpoint->ring, iobuf, trbs,
-                                        count ) ) != 0 )
+                                        ( trb - trbs ) ) ) != 0 )
                return rc;
 
        /* Ring the doorbell */
@@ -2759,6 +2719,7 @@ static void xhci_device_close ( struct usb_device *usb ) {
 static int xhci_device_address ( struct usb_device *usb ) {
        struct xhci_slot *slot = usb_get_hostdata ( usb );
        struct xhci_device *xhci = slot->xhci;
+       struct usb_port *port = usb->port;
        struct usb_port *root_port;
        int psiv;
        int rc;
@@ -2771,7 +2732,7 @@ static int xhci_device_address ( struct usb_device *usb ) {
        slot->port = root_port->address;
 
        /* Calculate protocol speed ID */
-       psiv = xhci_port_psiv ( xhci, slot->port, usb->speed );
+       psiv = xhci_port_psiv ( xhci, slot->port, port->speed );
        if ( psiv < 0 ) {
                rc = psiv;
                return rc;
diff --git a/roms/ipxe/src/hci/commands/ibmgmt_cmd.c b/roms/ipxe/src/hci/commands/ibmgmt_cmd.c
deleted file mode 100644 (file)
index 1154d74..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdio.h>
-#include <errno.h>
-#include <getopt.h>
-#include <ipxe/command.h>
-#include <ipxe/parseopt.h>
-#include <ipxe/infiniband.h>
-#include <usr/ibmgmt.h>
-
-/** @file
- *
- * Infiniband device management commands
- *
- */
-
-/** "ibstat" options */
-struct ibstat_options {};
-
-/** "ibstat" option list */
-static struct option_descriptor ibstat_opts[] = {};
-
-/** "ibstat" command descriptor */
-static struct command_descriptor ibstat_cmd =
-       COMMAND_DESC ( struct ibstat_options, ibstat_opts, 0, 0, "" );
-
-/**
- * The "ibstat" command
- *
- * @v argc             Argument count
- * @v argv             Argument list
- * @ret rc             Return status code
- */
-static int ibstat_exec ( int argc, char **argv ) {
-       struct ibstat_options opts;
-       struct ib_device *ibdev;
-       int rc;
-
-       /* Parse options */
-       if ( ( rc = parse_options ( argc, argv, &ibstat_cmd, &opts ) ) != 0 )
-               return rc;
-
-       /* Show all Infiniband devices */
-       for_each_ibdev ( ibdev )
-               ibstat ( ibdev );
-
-       return 0;
-}
-
-/** Infiniband commands */
-struct command ibmgmt_commands[] __command = {
-       {
-               .name = "ibstat",
-               .exec = ibstat_exec,
-       },
-};
index 393b3c3..a989932 100644 (file)
@@ -43,16 +43,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 struct lotest_options {
        /** MTU */
        unsigned int mtu;
-       /** Broadcast */
-       int broadcast;
 };
 
 /** "lotest" option list */
 static struct option_descriptor lotest_opts[] = {
        OPTION_DESC ( "mtu", 'm', required_argument,
                      struct lotest_options, mtu, parse_integer ),
-       OPTION_DESC ( "broadcast", 'b', no_argument,
-                     struct lotest_options, broadcast, parse_flag ),
 };
 
 /** "lotest" command descriptor */
@@ -90,8 +86,7 @@ static int lotest_exec ( int argc, char **argv ) {
                opts.mtu = ETH_MAX_MTU;
 
        /* Perform loopback test */
-       if ( ( rc = loopback_test ( sender, receiver, opts.mtu,
-                                   opts.broadcast ) ) != 0 ) {
+       if ( ( rc = loopback_test ( sender, receiver, opts.mtu ) ) != 0 ) {
                printf ( "Test failed: %s\n", strerror ( rc ) );
                return rc;
        }
diff --git a/roms/ipxe/src/hci/commands/ntp_cmd.c b/roms/ipxe/src/hci/commands/ntp_cmd.c
deleted file mode 100644 (file)
index 8f741a5..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdio.h>
-#include <string.h>
-#include <getopt.h>
-#include <ipxe/command.h>
-#include <ipxe/parseopt.h>
-#include <usr/ntpmgmt.h>
-
-/** @file
- *
- * NTP commands
- *
- */
-
-/** "ntp" options */
-struct ntp_options {};
-
-/** "ntp" option list */
-static struct option_descriptor ntp_opts[] = {};
-
-/** "ntp" command descriptor */
-static struct command_descriptor ntp_cmd =
-       COMMAND_DESC ( struct ntp_options, ntp_opts, 1, 1, "<server>" );
-
-/**
- * "ntp" command
- *
- * @v argc             Argument count
- * @v argv             Argument list
- * @ret rc             Return status code
- */
-static int ntp_exec ( int argc, char **argv ) {
-       struct ntp_options opts;
-       const char *hostname;
-       int rc;
-
-       /* Parse options */
-       if ( ( rc = parse_options ( argc, argv, &ntp_cmd, &opts ) ) != 0 )
-               return rc;
-
-       /* Parse hostname */
-       hostname = argv[optind];
-
-       /* Get time and date via NTP */
-       if ( ( rc = ntp ( hostname ) ) != 0 ) {
-               printf ( "Could not get time and date: %s\n", strerror ( rc ) );
-               return rc;
-       }
-
-       return 0;
-}
-
-/** NTP command */
-struct command ntp_command __command = {
-       .name = "ntp",
-       .exec = ntp_exec,
-};
index 5f5d1f4..7f39bde 100644 (file)
@@ -18,6 +18,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  * @ret rc     return status code
  */
 int delwin ( WINDOW *win ) {
+       if ( win == NULL )
+               return ERR;
+
        /* I think we should blank the region covered by the window -
           ncurses doesn't do this, but they have a buffer, so they
           may just be deleting from an offscreen context whereas we
@@ -48,6 +51,8 @@ int delwin ( WINDOW *win ) {
 WINDOW *derwin ( WINDOW *parent, int nlines, int ncols,
                                 int begin_y, int begin_x ) {
        WINDOW *child;
+       if ( parent == NULL )
+               return NULL;
        if ( ( child = malloc( sizeof( WINDOW ) ) ) == NULL )
                return NULL;
        if ( ( (unsigned)ncols > parent->width ) || 
@@ -70,6 +75,8 @@ WINDOW *derwin ( WINDOW *parent, int nlines, int ncols,
  */
 WINDOW *dupwin ( WINDOW *orig ) {
        WINDOW *copy;
+       if ( orig == NULL )
+               return NULL;
        if ( ( copy = malloc( sizeof( WINDOW ) ) ) == NULL )
                return NULL;
        copy->scr = orig->scr;
@@ -92,6 +99,8 @@ WINDOW *dupwin ( WINDOW *orig ) {
  * @ret rc     return status code
  */
 int mvwin ( WINDOW *win, int y, int x ) {
+       if ( win == NULL )
+               return ERR;
        if ( ( ( (unsigned)y + win->height ) > LINES ) ||
             ( ( (unsigned)x + win->width ) > COLS ) )
                return ERR;
@@ -140,6 +149,8 @@ WINDOW *newwin ( int nlines, int ncols, int begin_y, int begin_x ) {
 WINDOW *subwin ( WINDOW *parent, int nlines, int ncols,
                                 int begin_y, int begin_x ) {
        WINDOW *child;
+       if ( parent == NULL )
+               return NULL;
        if ( ( child = malloc( sizeof( WINDOW ) ) ) == NULL )
                return NULL;
        child = newwin( nlines, ncols, begin_y, begin_x );
index 47580c0..b7d8f9c 100644 (file)
@@ -29,12 +29,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/efi/efi_utils.h>
 #include <ipxe/efi/efi_strings.h>
 #include <ipxe/efi/efi_wrap.h>
-#include <ipxe/efi/efi_pxe.h>
 #include <ipxe/image.h>
 #include <ipxe/init.h>
 #include <ipxe/features.h>
 #include <ipxe/uri.h>
-#include <ipxe/console.h>
 
 FEATURE ( FEATURE_IMAGE, "EFI", DHCP_EB_FEATURE_EFI, 1 );
 
@@ -74,7 +72,8 @@ efi_image_path ( struct image *image, EFI_DEVICE_PATH_PROTOCOL *parent ) {
        size_t len;
 
        /* Calculate device path lengths */
-       prefix_len = efi_devpath_len ( parent );
+       end = efi_devpath_end ( parent );
+       prefix_len = ( ( void * ) end - ( void * ) parent );
        name_len = strlen ( image->name );
        filepath_len = ( SIZE_OF_FILEPATH_DEVICE_PATH +
                         ( name_len + 1 /* NUL */ ) * sizeof ( wchar_t ) );
@@ -160,13 +159,6 @@ static int efi_image_exec ( struct image *image ) {
                goto err_file_install;
        }
 
-       /* Install PXE base code protocol */
-       if ( ( rc = efi_pxe_install ( snpdev->handle, snpdev->netdev ) ) != 0 ){
-               DBGC ( image, "EFIIMAGE %p could not install PXE protocol: "
-                      "%s\n", image, strerror ( rc ) );
-               goto err_pxe_install;
-       }
-
        /* Install iPXE download protocol */
        if ( ( rc = efi_download_install ( snpdev->handle ) ) != 0 ) {
                DBGC ( image, "EFIIMAGE %p could not install iPXE download "
@@ -237,9 +229,6 @@ static int efi_image_exec ( struct image *image ) {
        /* Wrap calls made by the loaded image (for debugging) */
        efi_wrap ( handle );
 
-       /* Reset console since image will probably use it */
-       console_reset();
-
        /* Start the image */
        if ( ( efirc = bs->StartImage ( handle, NULL, NULL ) ) != 0 ) {
                rc = -EEFI_START ( efirc );
@@ -277,8 +266,6 @@ static int efi_image_exec ( struct image *image ) {
  err_image_path:
        efi_download_uninstall ( snpdev->handle );
  err_download_install:
-       efi_pxe_uninstall ( snpdev->handle );
- err_pxe_install:
        efi_file_uninstall ( snpdev->handle );
  err_file_install:
  err_no_snpdev:
index 376e5d2..48dd868 100644 (file)
@@ -18,7 +18,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define EMBED( _index, _path, _name )                                  \
        extern char embedded_image_ ## _index ## _data[];               \
        extern char embedded_image_ ## _index ## _len[];                \
-       __asm__ ( ".section \".rodata\", \"a\", " PROGBITS "\n\t"       \
+       __asm__ ( ".section \".rodata\", \"a\", @progbits\n\t"          \
                  "\nembedded_image_" #_index "_data:\n\t"              \
                  ".incbin \"" _path "\"\n\t"                           \
                  "\nembedded_image_" #_index "_end:\n\t"               \
index 32afb64..ca82f95 100644 (file)
 /** Stringify expanded argument */
 #define _S2( x ) _S1 ( x )
 
-/* Assembler section types */
-#ifdef ASSEMBLY
-#define PROGBITS _C2 ( ASM_TCHAR, progbits )
-#define NOBITS _C2 ( ASM_TCHAR, nobits )
-#else
-#define PROGBITS_OPS _S2 ( ASM_TCHAR_OPS ) "progbits"
-#define PROGBITS _S2 ( ASM_TCHAR ) "progbits"
-#define NOBITS_OPS _S2 ( ASM_TCHAR_OPS ) "nobits"
-#define NOBITS _S2 ( ASM_TCHAR ) "nobits"
-#endif
-
 /**
  * @defgroup symmacros Macros to provide or require explicit symbols
  * @{
@@ -75,7 +64,7 @@
  */
 #ifdef ASSEMBLY
 #define PROVIDE_SYMBOL( symbol )                               \
-       .section ".provided", "a", NOBITS ;                     \
+       .section ".provided", "a", @nobits ;                    \
        .hidden symbol ;                                        \
        .globl  symbol ;                                        \
        symbol: ;                                               \
  */
 #ifdef ASSEMBLY
 #define PROVIDE_REQUIRING_SYMBOL()                             \
-       .section ".tbl.requiring_symbols", "a", PROGBITS ;      \
+       .section ".tbl.requiring_symbols", "a", @progbits ;     \
        __requiring_symbol__:   .byte 0 ;                       \
        .size __requiring_symbol__, . - __requiring_symbol__ ;  \
        .previous
 #else
 #define PROVIDE_REQUIRING_SYMBOL()                             \
        __asm__ ( ".section \".tbl.requiring_symbols\", "       \
-                 "         \"a\", " PROGBITS "\n"              \
+                 "         \"a\", @progbits\n"                 \
                  "__requiring_symbol__:\t.byte 0\n"            \
                  ".size __requiring_symbol__, "                \
                  "      . - __requiring_symbol__\n"            \
index 342384f..036479a 100644 (file)
@@ -258,7 +258,7 @@ static inline void eplatform_discard ( int dummy __unused, ... ) {}
  * @ret error          Error
  */
 #define __einfo_error( einfo ) ( {                                     \
-       __asm__ ( ".section \".einfo\", \"\", " PROGBITS_OPS "\n\t"     \
+       __asm__ ( ".section \".einfo\", \"\", @progbits\n\t"            \
                  ".align 8\n\t"                                        \
                  "\n1:\n\t"                                            \
                  ".long ( 4f - 1b )\n\t"                               \
index 2e635b4..5fbd582 100644 (file)
@@ -315,26 +315,14 @@ struct asn1_bit_string {
 } __attribute__ (( packed ));
 
 /**
- * Invalidate ASN.1 object cursor
- *
- * @v cursor           ASN.1 object cursor
- */
-static inline __attribute__ (( always_inline )) void
-asn1_invalidate_cursor ( struct asn1_cursor *cursor ) {
-       cursor->len = 0;
-}
-
-/**
  * Extract ASN.1 type
  *
  * @v cursor           ASN.1 object cursor
- * @ret type           Type, or ASN1_END if cursor is invalid
+ * @ret type           Type
  */
 static inline __attribute__ (( always_inline )) unsigned int
 asn1_type ( const struct asn1_cursor *cursor ) {
-       const uint8_t *type = cursor->data;
-
-       return ( ( cursor->len >= sizeof ( *type ) ) ? *type : ASN1_END );
+       return ( *( ( const uint8_t * ) cursor->data ) );
 }
 
 extern void asn1_invalidate_cursor ( struct asn1_cursor *cursor );
index 7366cd9..220ab0f 100644 (file)
 #ifndef _IPXE_BITOPS_H
 #define _IPXE_BITOPS_H
 
-/** @file
+/*
+ * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
  *
- * Bit operations
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
  *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
  */
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
-#include <bits/bitops.h>
+/**
+ * @file
+ *
+ * Bit operations
+ *
+ */
+
+#include <stdint.h>
+#include <byteswap.h>
+
+/* Endianness selection.
+ *
+ * This is a property of the NIC, not a property of the host CPU.
+ */
+#ifdef BITOPS_LITTLE_ENDIAN
+#define cpu_to_BIT64   cpu_to_le64
+#define cpu_to_BIT32   cpu_to_le32
+#define BIT64_to_cpu   le64_to_cpu
+#define BIT32_to_cpu   le32_to_cpu
+#endif
+#ifdef BITOPS_BIG_ENDIAN
+#define cpu_to_BIT64   cpu_to_be64
+#define cpu_to_BIT32   cpu_to_be32
+#define BIT64_to_cpu   be64_to_cpu
+#define BIT32_to_cpu   be32_to_cpu
+#endif
+
+/** Datatype used to represent a bit in the pseudo-structures */
+typedef unsigned char pseudo_bit_t;
+
+/**
+ * Wrapper structure for pseudo_bit_t structures
+ *
+ * This structure provides a wrapper around pseudo_bit_t structures.
+ * It has the correct size, and also encapsulates type information
+ * about the underlying pseudo_bit_t-based structure, which allows the
+ * BIT_FILL() etc. macros to work without requiring explicit type
+ * information.
+ */
+#define PSEUDO_BIT_STRUCT( _structure )                                              \
+       union {                                                               \
+               uint8_t bytes[ sizeof ( _structure ) / 8 ];                   \
+               uint32_t dwords[ sizeof ( _structure ) / 32 ];                \
+               uint64_t qwords[ sizeof ( _structure ) / 64 ];                \
+               _structure *dummy[0];                                         \
+       } __attribute__ (( packed )) u
+
+/** Get pseudo_bit_t structure type from wrapper structure pointer */
+#define PSEUDO_BIT_STRUCT_TYPE( _ptr )                                       \
+       typeof ( *((_ptr)->u.dummy[0]) )
+
+/** Bit offset of a field within a pseudo_bit_t structure */
+#define BIT_OFFSET( _ptr, _field )                                           \
+       offsetof ( PSEUDO_BIT_STRUCT_TYPE ( _ptr ), _field )
+
+/** Bit width of a field within a pseudo_bit_t structure */
+#define BIT_WIDTH( _ptr, _field )                                            \
+       sizeof ( ( ( PSEUDO_BIT_STRUCT_TYPE ( _ptr ) * ) NULL )->_field )
+
+/** Qword offset of a field within a pseudo_bit_t structure */
+#define QWORD_OFFSET( _ptr, _field )                                         \
+       ( BIT_OFFSET ( _ptr, _field ) / 64 )
+
+/** Qword bit offset of a field within a pseudo_bit_t structure */
+#define QWORD_BIT_OFFSET( _ptr, _index, _field )                             \
+       ( BIT_OFFSET ( _ptr, _field ) - ( 64 * (_index) ) )
+
+/** Bit mask for a field within a pseudo_bit_t structure */
+#define BIT_MASK( _ptr, _field )                                             \
+       ( ( ~( ( uint64_t ) 0 ) ) >>                                          \
+         ( 64 - BIT_WIDTH ( _ptr, _field ) ) )
+
+/*
+ * Assemble native-endian qword from named fields and values
+ *
+ */
+
+#define BIT_ASSEMBLE_1( _ptr, _index, _field, _value )                       \
+       ( ( ( uint64_t) (_value) ) <<                                         \
+         QWORD_BIT_OFFSET ( _ptr, _index, _field ) )
+
+#define BIT_ASSEMBLE_2( _ptr, _index, _field, _value, ... )                  \
+       ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
+         BIT_ASSEMBLE_1 ( _ptr, _index, __VA_ARGS__ ) )
+
+#define BIT_ASSEMBLE_3( _ptr, _index, _field, _value, ... )                  \
+       ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
+         BIT_ASSEMBLE_2 ( _ptr, _index, __VA_ARGS__ ) )
+
+#define BIT_ASSEMBLE_4( _ptr, _index, _field, _value, ... )                  \
+       ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
+         BIT_ASSEMBLE_3 ( _ptr, _index, __VA_ARGS__ ) )
+
+#define BIT_ASSEMBLE_5( _ptr, _index, _field, _value, ... )                  \
+       ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
+         BIT_ASSEMBLE_4 ( _ptr, _index, __VA_ARGS__ ) )
+
+#define BIT_ASSEMBLE_6( _ptr, _index, _field, _value, ... )                  \
+       ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
+         BIT_ASSEMBLE_5 ( _ptr, _index, __VA_ARGS__ ) )
+
+#define BIT_ASSEMBLE_7( _ptr, _index, _field, _value, ... )                  \
+       ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
+         BIT_ASSEMBLE_6 ( _ptr, _index, __VA_ARGS__ ) )
+
+/*
+ * Build native-endian (positive) qword bitmasks from named fields
+ *
+ */
+
+#define BIT_MASK_1( _ptr, _index, _field )                                   \
+       ( BIT_MASK ( _ptr, _field ) <<                                        \
+         QWORD_BIT_OFFSET ( _ptr, _index, _field ) )
+
+#define BIT_MASK_2( _ptr, _index, _field, ... )                                      \
+       ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
+         BIT_MASK_1 ( _ptr, _index, __VA_ARGS__ ) )
+
+#define BIT_MASK_3( _ptr, _index, _field, ... )                                      \
+       ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
+         BIT_MASK_2 ( _ptr, _index, __VA_ARGS__ ) )
+
+#define BIT_MASK_4( _ptr, _index, _field, ... )                                      \
+       ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
+         BIT_MASK_3 ( _ptr, _index, __VA_ARGS__ ) )
+
+#define BIT_MASK_5( _ptr, _index, _field, ... )                                      \
+       ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
+         BIT_MASK_4 ( _ptr, _index, __VA_ARGS__ ) )
+
+#define BIT_MASK_6( _ptr, _index, _field, ... )                                      \
+       ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
+         BIT_MASK_5 ( _ptr, _index, __VA_ARGS__ ) )
+
+#define BIT_MASK_7( _ptr, _index, _field, ... )                                      \
+       ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
+         BIT_MASK_6 ( _ptr, _index, __VA_ARGS__ ) )
+
+/*
+ * Populate little-endian qwords from named fields and values
+ *
+ */
+
+#define BIT_FILL( _ptr, _index, _assembled ) do {                            \
+               uint64_t *__ptr = &(_ptr)->u.qwords[(_index)];                \
+               uint64_t __assembled = (_assembled);                          \
+               *__ptr = cpu_to_BIT64 ( __assembled );                        \
+       } while ( 0 )
+
+#define BIT_FILL_1( _ptr, _field1, ... )                                     \
+       BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
+                  BIT_ASSEMBLE_1 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
+                                   _field1, __VA_ARGS__ ) )
+
+#define BIT_FILL_2( _ptr, _field1, ... )                                     \
+       BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
+                  BIT_ASSEMBLE_2 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
+                                   _field1, __VA_ARGS__ ) )
+
+#define BIT_FILL_3( _ptr, _field1, ... )                                     \
+       BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
+                  BIT_ASSEMBLE_3 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
+                                   _field1, __VA_ARGS__ ) )
+
+#define BIT_FILL_4( _ptr, _field1, ... )                                     \
+       BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
+                  BIT_ASSEMBLE_4 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
+                                   _field1, __VA_ARGS__ ) )
+
+#define BIT_FILL_5( _ptr, _field1, ... )                                     \
+       BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
+                  BIT_ASSEMBLE_5 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
+                                   _field1, __VA_ARGS__ ) )
+
+#define BIT_FILL_6( _ptr, _field1, ... )                                     \
+       BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
+                  BIT_ASSEMBLE_6 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
+                                   _field1, __VA_ARGS__ ) )
+
+/** Extract value of named field */
+#define BIT_GET64( _ptr, _field )                                            \
+       ( {                                                                   \
+               unsigned int __index = QWORD_OFFSET ( _ptr, _field );         \
+               uint64_t *__ptr = &(_ptr)->u.qwords[__index];                 \
+               uint64_t __value = BIT64_to_cpu ( *__ptr );                   \
+               __value >>=                                                   \
+                   QWORD_BIT_OFFSET ( _ptr, __index, _field );               \
+               __value &= BIT_MASK ( _ptr, _field );                         \
+               __value;                                                      \
+       } )
+
+/** Extract value of named field (for fields up to the size of a long) */
+#define BIT_GET( _ptr, _field )                                                      \
+       ( ( unsigned long ) BIT_GET64 ( _ptr, _field ) )
 
-void set_bit ( unsigned int bit, volatile void *bits );
-void clear_bit ( unsigned int bit, volatile void *bits );
-int test_and_set_bit ( unsigned int bit, volatile void *bits );
-int test_and_clear_bit ( unsigned int bit, volatile void *bits );
+#define BIT_SET( _ptr, _field, _value ) do {                                 \
+               unsigned int __index = QWORD_OFFSET ( _ptr, _field );         \
+               uint64_t *__ptr = &(_ptr)->u.qwords[__index];                 \
+               unsigned int __shift =                                        \
+                       QWORD_BIT_OFFSET ( _ptr, __index, _field );           \
+               uint64_t __value = (_value);                                  \
+               *__ptr &= cpu_to_BIT64 ( ~( BIT_MASK ( _ptr, _field ) <<      \
+                                           __shift ) );                      \
+               *__ptr |= cpu_to_BIT64 ( __value << __shift );                \
+       } while ( 0 )
 
 #endif /* _IPXE_BITOPS_H */
index b8b4a59..f1799cd 100644 (file)
@@ -14,16 +14,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /** Class code for communications devices */
 #define USB_CLASS_CDC 2
 
-/** Send encapsulated command */
-#define CDC_SEND_ENCAPSULATED_COMMAND                                  \
-       ( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE |          \
-         USB_REQUEST_TYPE ( 0x00 ) )
-
-/** Get encapsulated response */
-#define CDC_GET_ENCAPSULATED_RESPONSE                                  \
-       ( USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE |           \
-         USB_REQUEST_TYPE ( 0x01 ) )
-
 /** Union functional descriptor */
 struct cdc_union_descriptor {
        /** Descriptor header */
@@ -40,11 +30,6 @@ struct cdc_union_descriptor {
 /** Ethernet descriptor subtype */
 #define CDC_SUBTYPE_ETHERNET 15
 
-/** Response available */
-#define CDC_RESPONSE_AVAILABLE                                         \
-       ( USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE |           \
-         USB_REQUEST_TYPE ( 0x01 ) )
-
 /** Network connection notification */
 #define CDC_NETWORK_CONNECTION                                         \
        ( USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE |           \
@@ -67,38 +52,4 @@ extern struct cdc_union_descriptor *
 cdc_union_descriptor ( struct usb_configuration_descriptor *config,
                       struct usb_interface_descriptor *interface );
 
-/**
- * Send encapsulated command
- *
- * @v usb              USB device
- * @v interface                Interface number
- * @v data             Command
- * @v len              Length of command
- * @ret rc             Return status code
- */
-static inline __attribute__ (( always_inline )) int
-cdc_send_encapsulated_command ( struct usb_device *usb, unsigned int interface,
-                               void *data, size_t len ) {
-
-       return usb_control ( usb, CDC_SEND_ENCAPSULATED_COMMAND, 0, interface,
-                            data, len );
-}
-
-/**
-* Get encapsulated response
-*
-* @v usb               USB device
-* @v interface         Interface number
-* @v data              Response buffer
-* @v len               Length of response buffer
-* @ret rc              Return status code
-*/
-static inline __attribute__ (( always_inline )) int
-cdc_get_encapsulated_response ( struct usb_device *usb, unsigned int interface,
-                               void *data, size_t len ) {
-
-       return usb_control ( usb, CDC_GET_ENCAPSULATED_RESPONSE, 0, interface,
-                            data, len );
-}
-
 #endif /* _IPXE_CDC_H */
index 693aa7e..a11db34 100644 (file)
@@ -266,16 +266,12 @@ enum dhcp_client_architecture_values {
        DHCP_CLIENT_ARCHITECTURE_LC = 0x0005,
        /** EFI IA32 */
        DHCP_CLIENT_ARCHITECTURE_IA32 = 0x0006,
-       /** EFI x86-64 */
-       DHCP_CLIENT_ARCHITECTURE_X86_64 = 0x0007,
+       /** EFI BC */
+       DHCP_CLIENT_ARCHITECTURE_EFI = 0x0007,
        /** EFI Xscale */
        DHCP_CLIENT_ARCHITECTURE_XSCALE = 0x0008,
-       /** EFI BC */
-       DHCP_CLIENT_ARCHITECTURE_EFI = 0x0009,
-       /** EFI 32-bit ARM */
-       DHCP_CLIENT_ARCHITECTURE_ARM32 = 0x000a,
-       /** EFI 64-bit ARM */
-       DHCP_CLIENT_ARCHITECTURE_ARM64 = 0x000b,
+       /** EFI x86-64 */
+       DHCP_CLIENT_ARCHITECTURE_X86_64 = 0x0009,
 };
 
 /** Client network device interface */
@@ -407,12 +403,12 @@ struct dhcp_netdev_desc {
 /** Use cached network settings (obsolete; do not reuse this value) */
 #define DHCP_EB_USE_CACHED DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb2 )
 
-/** SAN drive number
+/** BIOS drive number
  *
- * This is the drive number for a SAN-hooked drive.  For BIOS, 0x80 is
+ * This is the drive number for a drive emulated via INT 13.  0x80 is
  * the first hard disk, 0x81 is the second hard disk, etc.
  */
-#define DHCP_EB_SAN_DRIVE DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbd )
+#define DHCP_EB_BIOS_DRIVE DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbd )
 
 /** Username
  *
diff --git a/roms/ipxe/src/include/ipxe/efi/AArch64/ProcessorBind.h b/roms/ipxe/src/include/ipxe/efi/AArch64/ProcessorBind.h
deleted file mode 100644 (file)
index d430172..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/** @file
-  Processor or Compiler specific defines and types for AArch64.
-
-  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
-  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-  Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
-
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef __PROCESSOR_BIND_H__
-#define __PROCESSOR_BIND_H__
-
-FILE_LICENCE ( BSD3 );
-
-///
-/// Define the processor type so other code can make processor based choices
-///
-#define MDE_CPU_AARCH64
-
-//
-// Make sure we are using the correct packing rules per EFI specification
-//
-#ifndef __GNUC__
-#pragma pack()
-#endif
-
-#if _MSC_EXTENSIONS
-  //
-  // use Microsoft* C complier dependent integer width types
-  //
-  typedef unsigned __int64    UINT64;
-  typedef __int64             INT64;
-  typedef unsigned __int32    UINT32;
-  typedef __int32             INT32;
-  typedef unsigned short      UINT16;
-  typedef unsigned short      CHAR16;
-  typedef short               INT16;
-  typedef unsigned char       BOOLEAN;
-  typedef unsigned char       UINT8;
-  typedef char                CHAR8;
-  typedef signed char         INT8;
-#else
-  //
-  // Assume standard AARCH64 alignment.
-  //
-  typedef unsigned long long  UINT64;
-  typedef long long           INT64;
-  typedef unsigned int        UINT32;
-  typedef int                 INT32;
-  typedef unsigned short      UINT16;
-  typedef unsigned short      CHAR16;
-  typedef short               INT16;
-  typedef unsigned char       BOOLEAN;
-  typedef unsigned char       UINT8;
-  typedef char                CHAR8;
-  typedef signed char         INT8;
-#endif
-
-///
-/// Unsigned value of native width.  (4 bytes on supported 32-bit processor instructions,
-/// 8 bytes on supported 64-bit processor instructions)
-///
-typedef UINT64  UINTN;
-
-///
-/// Signed value of native width.  (4 bytes on supported 32-bit processor instructions,
-/// 8 bytes on supported 64-bit processor instructions)
-///
-typedef INT64   INTN;
-
-//
-// Processor specific defines
-//
-
-///
-/// A value of native width with the highest bit set.
-///
-#define MAX_BIT     0x8000000000000000ULL
-
-///
-/// A value of native width with the two highest bits set.
-///
-#define MAX_2_BITS  0xC000000000000000ULL
-
-///
-/// Maximum legal AARCH64  address
-///
-#define MAX_ADDRESS   0xFFFFFFFFFFFFFFFFULL
-
-///
-/// Maximum legal AArch64 INTN and UINTN values.
-///
-#define MAX_INTN   ((INTN)0x7FFFFFFFFFFFFFFFULL)
-#define MAX_UINTN  ((UINTN)0xFFFFFFFFFFFFFFFFULL)
-
-///
-/// The stack alignment required for AARCH64
-///
-#define CPU_STACK_ALIGNMENT  16
-
-//
-// Modifier to ensure that all protocol member functions and EFI intrinsics
-// use the correct C calling convention. All protocol member functions and
-// EFI intrinsics are required to modify their member functions with EFIAPI.
-//
-#define EFIAPI
-
-// When compiling with Clang, we still use GNU as for the assembler, so we still
-// need to define the GCC_ASM* macros.
-#if defined(__GNUC__) || defined(__clang__)
-  ///
-  /// For GNU assembly code, .global or .globl can declare global symbols.
-  /// Define this macro to unify the usage.
-  ///
-  #define ASM_GLOBAL .globl
-
-  #define GCC_ASM_EXPORT(func__)  \
-         .global  _CONCATENATE (__USER_LABEL_PREFIX__, func__)    ;\
-         .type ASM_PFX(func__), %function
-
-  #define GCC_ASM_IMPORT(func__)  \
-         .extern  _CONCATENATE (__USER_LABEL_PREFIX__, func__)
-
-#endif
-
-/**
-  Return the pointer to the first instruction of a function given a function pointer.
-  On ARM CPU architectures, these two pointer values are the same,
-  so the implementation of this macro is very simple.
-
-  @param  FunctionPointer   A pointer to a function.
-
-  @return The pointer to the first instruction of a function given a function pointer.
-
-**/
-#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer)
-
-#ifndef __USER_LABEL_PREFIX__
-#define __USER_LABEL_PREFIX__
-#endif
-
-#endif
diff --git a/roms/ipxe/src/include/ipxe/efi/Arm/ProcessorBind.h b/roms/ipxe/src/include/ipxe/efi/Arm/ProcessorBind.h
deleted file mode 100644 (file)
index 51a7271..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/** @file
-  Processor or Compiler specific defines and types for ARM.
-
-  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
-  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef __PROCESSOR_BIND_H__
-#define __PROCESSOR_BIND_H__
-
-FILE_LICENCE ( BSD3 );
-
-///
-/// Define the processor type so other code can make processor based choices
-///
-#define MDE_CPU_ARM
-
-//
-// Make sure we are using the correct packing rules per EFI specification
-//
-#ifndef __GNUC__
-#pragma pack()
-#endif
-
-#if _MSC_EXTENSIONS
-  //
-  // use Microsoft* C complier dependent integer width types
-  //
-  typedef unsigned __int64    UINT64;
-  typedef __int64             INT64;
-  typedef unsigned __int32    UINT32;
-  typedef __int32             INT32;
-  typedef unsigned short      UINT16;
-  typedef unsigned short      CHAR16;
-  typedef short               INT16;
-  typedef unsigned char       BOOLEAN;
-  typedef unsigned char       UINT8;
-  typedef char                CHAR8;
-  typedef signed char         INT8;
-#else
-  //
-  // Assume standard ARM alignment.
-  // Need to check portability of long long
-  //
-  typedef unsigned long long  UINT64;
-  typedef long long           INT64;
-  typedef unsigned int        UINT32;
-  typedef int                 INT32;
-  typedef unsigned short      UINT16;
-  typedef unsigned short      CHAR16;
-  typedef short               INT16;
-  typedef unsigned char       BOOLEAN;
-  typedef unsigned char       UINT8;
-  typedef char                CHAR8;
-  typedef signed char         INT8;
-#endif
-
-///
-/// Unsigned value of native width.  (4 bytes on supported 32-bit processor instructions,
-/// 8 bytes on supported 64-bit processor instructions)
-///
-typedef UINT32  UINTN;
-
-///
-/// Signed value of native width.  (4 bytes on supported 32-bit processor instructions,
-/// 8 bytes on supported 64-bit processor instructions)
-///
-typedef INT32   INTN;
-
-//
-// Processor specific defines
-//
-
-///
-/// A value of native width with the highest bit set.
-///
-#define MAX_BIT      0x80000000
-
-///
-/// A value of native width with the two highest bits set.
-///
-#define MAX_2_BITS   0xC0000000
-
-///
-/// Maximum legal ARM address
-///
-#define MAX_ADDRESS  0xFFFFFFFF
-
-///
-/// Maximum legal ARM INTN and UINTN values.
-///
-#define MAX_INTN   ((INTN)0x7FFFFFFF)
-#define MAX_UINTN  ((UINTN)0xFFFFFFFF)
-
-///
-/// The stack alignment required for ARM
-///
-#define CPU_STACK_ALIGNMENT  sizeof(UINT64)
-
-//
-// Modifier to ensure that all protocol member functions and EFI intrinsics
-// use the correct C calling convention. All protocol member functions and
-// EFI intrinsics are required to modify their member functions with EFIAPI.
-//
-#define EFIAPI
-
-// When compiling with Clang, we still use GNU as for the assembler, so we still
-// need to define the GCC_ASM* macros.
-#if defined(__GNUC__) || defined(__clang__)
-  ///
-  /// For GNU assembly code, .global or .globl can declare global symbols.
-  /// Define this macro to unify the usage.
-  ///
-  #define ASM_GLOBAL .globl
-
-  #if !defined(__APPLE__)
-    ///
-    /// ARM EABI defines that the linker should not manipulate call relocations
-    /// (do bl/blx conversion) unless the target symbol has function type.
-    /// CodeSourcery 2010.09 started requiring the .type to function properly
-    ///
-    #define INTERWORK_FUNC(func__)   .type ASM_PFX(func__), %function
-
-    #define GCC_ASM_EXPORT(func__)  \
-             .global  _CONCATENATE (__USER_LABEL_PREFIX__, func__)    ;\
-             .type ASM_PFX(func__), %function
-
-    #define GCC_ASM_IMPORT(func__)  \
-             .extern  _CONCATENATE (__USER_LABEL_PREFIX__, func__)
-
-  #else
-    //
-    // .type not supported by Apple Xcode tools
-    //
-    #define INTERWORK_FUNC(func__)
-
-    #define GCC_ASM_EXPORT(func__)  \
-             .globl  _CONCATENATE (__USER_LABEL_PREFIX__, func__)    \
-
-    #define GCC_ASM_IMPORT(name)
-
-  #endif
-#endif
-
-/**
-  Return the pointer to the first instruction of a function given a function pointer.
-  On ARM CPU architectures, these two pointer values are the same,
-  so the implementation of this macro is very simple.
-
-  @param  FunctionPointer   A pointer to a function.
-
-  @return The pointer to the first instruction of a function given a function pointer.
-
-**/
-#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer)
-
-#ifndef __USER_LABEL_PREFIX__
-#define __USER_LABEL_PREFIX__
-#endif
-
-#endif
-
-
index 8a047ae..844f428 100644 (file)
@@ -6,7 +6,7 @@
   environment. There are a set of base libraries in the Mde Package that can
   be used to implement base modules.
 
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
@@ -29,12 +29,6 @@ FILE_LICENCE ( BSD3 );
 //
 #include <ipxe/efi/ProcessorBind.h>
 
-#if defined(_MSC_EXTENSIONS)
-//
-// Disable warning when last field of data structure is a zero sized array.
-//
-#pragma warning ( disable : 4200 )
-#endif
 
 /**
   Verifies the storage size of a given data type.
@@ -943,11 +937,6 @@ typedef UINTN RETURN_STATUS;
 #define RETURN_COMPROMISED_DATA      ENCODE_ERROR (33)
 
 ///
-/// A HTTP error occurred during the network operation.
-///
-#define RETURN_HTTP_ERROR            ENCODE_ERROR (35)
-
-///
 /// The string contained one or more characters that
 /// the device could not render and were skipped.
 ///
@@ -976,12 +965,6 @@ typedef UINTN RETURN_STATUS;
 ///
 #define RETURN_WARN_STALE_DATA       ENCODE_WARNING (5)
 
-///
-/// The resulting buffer contains UEFI-compliant file system.
-///
-#define RETURN_WARN_FILE_SYSTEM      ENCODE_WARNING (6)
-
-
 /**
   Returns a 16-bit signature built from 2 ASCII characters.
 
@@ -1035,46 +1018,5 @@ typedef UINTN RETURN_STATUS;
 #define SIGNATURE_64(A, B, C, D, E, F, G, H) \
     (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32))
 
-#if defined(_MSC_EXTENSIONS) && !defined (__INTEL_COMPILER) && !defined (MDE_CPU_EBC)
-  #pragma intrinsic(_ReturnAddress)
-  /**
-    Get the return address of the calling funcation.
-
-    Based on intrinsic function _ReturnAddress that provides the address of
-    the instruction in the calling function that will be executed after
-    control returns to the caller.
-
-    @param L    Return Level.
-
-    @return The return address of the calling funcation or 0 if L != 0.
-
-  **/
-  #define RETURN_ADDRESS(L)     ((L == 0) ? _ReturnAddress() : (VOID *) 0)
-#elif defined(__GNUC__)
-  void * __builtin_return_address (unsigned int level);
-  /**
-    Get the return address of the calling funcation.
-
-    Based on built-in Function __builtin_return_address that returns
-    the return address of the current function, or of one of its callers.
-
-    @param L    Return Level.
-
-    @return The return address of the calling funcation.
-
-  **/
-  #define RETURN_ADDRESS(L)     __builtin_return_address (L)
-#else
-  /**
-    Get the return address of the calling funcation.
-
-    @param L    Return Level.
-
-    @return 0 as compilers don't support this feature.
-
-  **/
-  #define RETURN_ADDRESS(L)     ((VOID *) 0)
-#endif
-
 #endif
 
index 4914289..cc4a1f9 100644 (file)
@@ -1,11 +1,11 @@
 /** @file
-  GUIDs used to locate the SMBIOS tables in the UEFI 2.5 system table.
+  GUIDs used to locate the SMBIOS tables in the UEFI 2.0 system table.
 
-  These GUIDs in the system table are the only legal ways to search for and
+  This GUID in the system table is the only legal way to search for and
   locate the SMBIOS tables. Do not search the 0xF0000 segment to find SMBIOS
   tables.
 
-  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -15,7 +15,7 @@
   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
   @par Revision Reference:
-  GUIDs defined in UEFI 2.5 spec.
+  GUIDs defined in UEFI 2.0 spec.
 
 **/
 
@@ -29,12 +29,6 @@ FILE_LICENCE ( BSD3 );
     0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
   }
 
-#define SMBIOS3_TABLE_GUID \
-  { \
-    0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 } \
-  }
-
 extern EFI_GUID       gEfiSmbiosTableGuid;
-extern EFI_GUID       gEfiSmbios3TableGuid;
 
 #endif
index 375ff2d..16e30b3 100644 (file)
@@ -1,7 +1,7 @@
 /** @file
   Processor or Compiler specific defines and types for IA-32 architecture.
 
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -95,26 +95,6 @@ FILE_LICENCE ( BSD3 );
 //
 #pragma warning ( disable : 4206 )
 
-#if _MSC_VER == 1800 || _MSC_VER == 1900
-
-//
-// Disable these warnings for VS2013.
-//
-
-//
-// This warning is for potentially uninitialized local variable, and it may cause false
-// positive issues in VS2013 and VS2015 build
-//
-#pragma warning ( disable : 4701 )
-
-//
-// This warning is for potentially uninitialized local pointer variable, and it may cause
-// false positive issues in VS2013 and VS2015 build
-//
-#pragma warning ( disable : 4703 )
-
-#endif
-
 #endif
 
 
diff --git a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi20.h b/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi20.h
deleted file mode 100644 (file)
index f5ff44c..0000000
+++ /dev/null
@@ -1,547 +0,0 @@
-/** @file
-  ACPI 2.0 definitions from the ACPI Specification, revision 2.0
-
-  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-**/
-
-#ifndef _ACPI_2_0_H_
-#define _ACPI_2_0_H_
-
-FILE_LICENCE ( BSD3 );
-
-#include <ipxe/efi/IndustryStandard/Acpi10.h>
-
-//
-// Define for Desriptor
-//
-#define ACPI_LARGE_GENERIC_REGISTER_DESCRIPTOR_NAME          0x02
-
-#define ACPI_GENERIC_REGISTER_DESCRIPTOR          0x82
-
-//
-// Ensure proper structure formats
-//
-#pragma pack(1)
-
-///
-/// Generic Register Descriptor
-///
-typedef PACKED struct {
-  ACPI_LARGE_RESOURCE_HEADER    Header;
-  UINT8                         AddressSpaceId;
-  UINT8                         RegisterBitWidth;
-  UINT8                         RegisterBitOffset;
-  UINT8                         AddressSize;
-  UINT64                        RegisterAddress;
-} EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR;
-
-#pragma pack()
-
-//
-// Ensure proper structure formats
-//
-#pragma pack(1)
-
-///
-/// ACPI 2.0 Generic Address Space definition
-///
-typedef struct {
-  UINT8   AddressSpaceId;
-  UINT8   RegisterBitWidth;
-  UINT8   RegisterBitOffset;
-  UINT8   Reserved;
-  UINT64  Address;
-} EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE;
-
-//
-// Generic Address Space Address IDs
-//
-#define EFI_ACPI_2_0_SYSTEM_MEMORY              0
-#define EFI_ACPI_2_0_SYSTEM_IO                  1
-#define EFI_ACPI_2_0_PCI_CONFIGURATION_SPACE    2
-#define EFI_ACPI_2_0_EMBEDDED_CONTROLLER        3
-#define EFI_ACPI_2_0_SMBUS                      4
-#define EFI_ACPI_2_0_FUNCTIONAL_FIXED_HARDWARE  0x7F
-
-//
-// ACPI 2.0 table structures
-//
-
-///
-/// Root System Description Pointer Structure
-///
-typedef struct {
-  UINT64  Signature;
-  UINT8   Checksum;
-  UINT8   OemId[6];
-  UINT8   Revision;
-  UINT32  RsdtAddress;
-  UINT32  Length;
-  UINT64  XsdtAddress;
-  UINT8   ExtendedChecksum;
-  UINT8   Reserved[3];
-} EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
-
-///
-/// RSD_PTR Revision (as defined in ACPI 2.0 spec.)
-///
-#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02
-
-///
-/// Common table header, this prefaces all ACPI tables, including FACS, but
-/// excluding the RSD PTR structure
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-} EFI_ACPI_2_0_COMMON_HEADER;
-
-//
-// Root System Description Table
-// No definition needed as it is a common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers.
-//
-
-///
-/// RSDT Revision (as defined in ACPI 2.0 spec.)
-///
-#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
-
-//
-// Extended System Description Table
-// No definition needed as it is a common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers.
-//
-
-///
-/// XSDT Revision (as defined in ACPI 2.0 spec.)
-///
-#define EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Fixed ACPI Description Table Structure (FADT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER             Header;
-  UINT32                                  FirmwareCtrl;
-  UINT32                                  Dsdt;
-  UINT8                                   Reserved0;
-  UINT8                                   PreferredPmProfile;
-  UINT16                                  SciInt;
-  UINT32                                  SmiCmd;
-  UINT8                                   AcpiEnable;
-  UINT8                                   AcpiDisable;
-  UINT8                                   S4BiosReq;
-  UINT8                                   PstateCnt;
-  UINT32                                  Pm1aEvtBlk;
-  UINT32                                  Pm1bEvtBlk;
-  UINT32                                  Pm1aCntBlk;
-  UINT32                                  Pm1bCntBlk;
-  UINT32                                  Pm2CntBlk;
-  UINT32                                  PmTmrBlk;
-  UINT32                                  Gpe0Blk;
-  UINT32                                  Gpe1Blk;
-  UINT8                                   Pm1EvtLen;
-  UINT8                                   Pm1CntLen;
-  UINT8                                   Pm2CntLen;
-  UINT8                                   PmTmrLen;
-  UINT8                                   Gpe0BlkLen;
-  UINT8                                   Gpe1BlkLen;
-  UINT8                                   Gpe1Base;
-  UINT8                                   CstCnt;
-  UINT16                                  PLvl2Lat;
-  UINT16                                  PLvl3Lat;
-  UINT16                                  FlushSize;
-  UINT16                                  FlushStride;
-  UINT8                                   DutyOffset;
-  UINT8                                   DutyWidth;
-  UINT8                                   DayAlrm;
-  UINT8                                   MonAlrm;
-  UINT8                                   Century;
-  UINT16                                  IaPcBootArch;
-  UINT8                                   Reserved1;
-  UINT32                                  Flags;
-  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE  ResetReg;
-  UINT8                                   ResetValue;
-  UINT8                                   Reserved2[3];
-  UINT64                                  XFirmwareCtrl;
-  UINT64                                  XDsdt;
-  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE  XPm1aEvtBlk;
-  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE  XPm1bEvtBlk;
-  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE  XPm1aCntBlk;
-  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE  XPm1bCntBlk;
-  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE  XPm2CntBlk;
-  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE  XPmTmrBlk;
-  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE  XGpe0Blk;
-  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE  XGpe1Blk;
-} EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE;
-
-///
-/// FADT Version (as defined in ACPI 2.0 spec.)
-///
-#define EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION  0x03
-
-//
-// Fixed ACPI Description Table Preferred Power Management Profile
-//
-#define EFI_ACPI_2_0_PM_PROFILE_UNSPECIFIED         0
-#define EFI_ACPI_2_0_PM_PROFILE_DESKTOP             1
-#define EFI_ACPI_2_0_PM_PROFILE_MOBILE              2
-#define EFI_ACPI_2_0_PM_PROFILE_WORKSTATION         3
-#define EFI_ACPI_2_0_PM_PROFILE_ENTERPRISE_SERVER   4
-#define EFI_ACPI_2_0_PM_PROFILE_SOHO_SERVER         5
-#define EFI_ACPI_2_0_PM_PROFILE_APPLIANCE_PC        6
-
-//
-// Fixed ACPI Description Table Boot Architecture Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_2_0_LEGACY_DEVICES          BIT0
-#define EFI_ACPI_2_0_8042                    BIT1
-
-//
-// Fixed ACPI Description Table Fixed Feature Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_2_0_WBINVD                  BIT0
-#define EFI_ACPI_2_0_WBINVD_FLUSH            BIT1
-#define EFI_ACPI_2_0_PROC_C1                 BIT2
-#define EFI_ACPI_2_0_P_LVL2_UP               BIT3
-#define EFI_ACPI_2_0_PWR_BUTTON              BIT4
-#define EFI_ACPI_2_0_SLP_BUTTON              BIT5
-#define EFI_ACPI_2_0_FIX_RTC                 BIT6
-#define EFI_ACPI_2_0_RTC_S4                  BIT7
-#define EFI_ACPI_2_0_TMR_VAL_EXT             BIT8
-#define EFI_ACPI_2_0_DCK_CAP                 BIT9
-#define EFI_ACPI_2_0_RESET_REG_SUP           BIT10
-#define EFI_ACPI_2_0_SEALED_CASE             BIT11
-#define EFI_ACPI_2_0_HEADLESS                BIT12
-#define EFI_ACPI_2_0_CPU_SW_SLP              BIT13
-
-///
-/// Firmware ACPI Control Structure
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-  UINT32  HardwareSignature;
-  UINT32  FirmwareWakingVector;
-  UINT32  GlobalLock;
-  UINT32  Flags;
-  UINT64  XFirmwareWakingVector;
-  UINT8   Version;
-  UINT8   Reserved[31];
-} EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
-
-///
-/// FACS Version (as defined in ACPI 2.0 spec.)
-///
-#define EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION  0x01
-
-///
-/// Firmware Control Structure Feature Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_2_0_S4BIOS_F        BIT0
-
-///
-/// Multiple APIC Description Table header definition.  The rest of the table
-/// must be defined in a platform specific manner.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      LocalApicAddress;
-  UINT32                      Flags;
-} EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER;
-
-///
-/// MADT Revision (as defined in ACPI 2.0 spec.)
-///
-#define EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Multiple APIC Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_2_0_PCAT_COMPAT          BIT0
-
-//
-// Multiple APIC Description Table APIC structure types
-// All other values between 0x09 an 0xFF are reserved and
-// will be ignored by OSPM.
-//
-#define EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC           0x00
-#define EFI_ACPI_2_0_IO_APIC                        0x01
-#define EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE      0x02
-#define EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE  0x03
-#define EFI_ACPI_2_0_LOCAL_APIC_NMI                 0x04
-#define EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE    0x05
-#define EFI_ACPI_2_0_IO_SAPIC                       0x06
-#define EFI_ACPI_2_0_PROCESSOR_LOCAL_SAPIC          0x07
-#define EFI_ACPI_2_0_PLATFORM_INTERRUPT_SOURCES     0x08
-
-//
-// APIC Structure Definitions
-//
-
-///
-/// Processor Local APIC Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT8   ApicId;
-  UINT32  Flags;
-} EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE;
-
-///
-/// Local APIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_2_0_LOCAL_APIC_ENABLED         BIT0
-
-///
-/// IO APIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   IoApicId;
-  UINT8   Reserved;
-  UINT32  IoApicAddress;
-  UINT32  GlobalSystemInterruptBase;
-} EFI_ACPI_2_0_IO_APIC_STRUCTURE;
-
-///
-/// Interrupt Source Override Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Bus;
-  UINT8   Source;
-  UINT32  GlobalSystemInterrupt;
-  UINT16  Flags;
-} EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE;
-
-///
-/// Non-Maskable Interrupt Source Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT32  GlobalSystemInterrupt;
-} EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE;
-
-///
-/// Local APIC NMI Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT16  Flags;
-  UINT8   LocalApicLint;
-} EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE;
-
-///
-/// Local APIC Address Override Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved;
-  UINT64  LocalApicAddress;
-} EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
-
-///
-/// IO SAPIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   IoApicId;
-  UINT8   Reserved;
-  UINT32  GlobalSystemInterruptBase;
-  UINT64  IoSapicAddress;
-} EFI_ACPI_2_0_IO_SAPIC_STRUCTURE;
-
-///
-/// Local SAPIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT8   LocalSapicId;
-  UINT8   LocalSapicEid;
-  UINT8   Reserved[3];
-  UINT32  Flags;
-} EFI_ACPI_2_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
-
-///
-/// Platform Interrupt Sources Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT8   InterruptType;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT8   IoSapicVector;
-  UINT32  GlobalSystemInterrupt;
-  UINT32  Reserved;
-} EFI_ACPI_2_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE;
-
-///
-/// Smart Battery Description Table (SBST)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      WarningEnergyLevel;
-  UINT32                      LowEnergyLevel;
-  UINT32                      CriticalEnergyLevel;
-} EFI_ACPI_2_0_SMART_BATTERY_DESCRIPTION_TABLE;
-
-///
-/// SBST Version (as defined in ACPI 2.0 spec.)
-///
-#define EFI_ACPI_2_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Embedded Controller Boot Resources Table (ECDT)
-/// The table is followed by a null terminated ASCII string that contains
-/// a fully qualified reference to the name space object.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER             Header;
-  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE  EcControl;
-  EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE  EcData;
-  UINT32                                  Uid;
-  UINT8                                   GpeBit;
-} EFI_ACPI_2_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE;
-
-///
-/// ECDT Version (as defined in ACPI 2.0 spec.)
-///
-#define EFI_ACPI_2_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION  0x01
-
-//
-// Known table signatures
-//
-
-///
-/// "RSD PTR " Root System Description Pointer
-///
-#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE  SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ')
-
-///
-/// "SPIC" Multiple SAPIC Description Table
-///
-/// BUGBUG: Don't know where this came from except SR870BN4 uses it.
-/// #define EFI_ACPI_2_0_MULTIPLE_SAPIC_DESCRIPTION_TABLE_SIGNATURE 0x43495053
-///
-#define EFI_ACPI_2_0_MULTIPLE_SAPIC_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('A', 'P', 'I', 'C')
-
-///
-/// "BOOT" MS Simple Boot Spec
-///
-#define EFI_ACPI_2_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE  SIGNATURE_32('B', 'O', 'O', 'T')
-
-///
-/// "DBGP" MS Bebug Port Spec
-///
-#define EFI_ACPI_2_0_DEBUG_PORT_TABLE_SIGNATURE  SIGNATURE_32('D', 'B', 'G', 'P')
-
-///
-/// "DSDT" Differentiated System Description Table
-///
-#define EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('D', 'S', 'D', 'T')
-
-///
-/// "ECDT" Embedded Controller Boot Resources Table
-///
-#define EFI_ACPI_2_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE  SIGNATURE_32('E', 'C', 'D', 'T')
-
-///
-/// "ETDT" Event Timer Description Table
-///
-#define EFI_ACPI_2_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('E', 'T', 'D', 'T')
-
-///
-/// "FACS" Firmware ACPI Control Structure
-///
-#define EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE  SIGNATURE_32('F', 'A', 'C', 'S')
-
-///
-/// "FACP" Fixed ACPI Description Table
-///
-#define EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('F', 'A', 'C', 'P')
-
-///
-/// "APIC" Multiple APIC Description Table
-///
-#define EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('A', 'P', 'I', 'C')
-
-///
-/// "PSDT" Persistent System Description Table
-///
-#define EFI_ACPI_2_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('P', 'S', 'D', 'T')
-
-///
-/// "RSDT" Root System Description Table
-///
-#define EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('R', 'S', 'D', 'T')
-
-///
-/// "SBST" Smart Battery Specification Table
-///
-#define EFI_ACPI_2_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE  SIGNATURE_32('S', 'B', 'S', 'T')
-
-///
-/// "SLIT" System Locality Information Table
-///
-#define EFI_ACPI_2_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE  SIGNATURE_32('S', 'L', 'I', 'T')
-
-///
-/// "SPCR" Serial Port Concole Redirection Table
-///
-#define EFI_ACPI_2_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE  SIGNATURE_32('S', 'P', 'C', 'R')
-
-///
-/// "SRAT" Static Resource Affinity Table
-///
-#define EFI_ACPI_2_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE  SIGNATURE_32('S', 'R', 'A', 'T')
-
-///
-/// "SSDT" Secondary System Description Table
-///
-#define EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('S', 'S', 'D', 'T')
-
-///
-/// "SPMI" Server Platform Management Interface Table
-///
-#define EFI_ACPI_2_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_SIGNATURE  SIGNATURE_32('S', 'P', 'M', 'I')
-
-///
-/// "XSDT" Extended System Description Table
-///
-#define EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('X', 'S', 'D', 'T')
-
-///
-/// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
-///
-#define EFI_ACPI_2_0_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_SIGNATURE  SIGNATURE_32('M', 'C', 'F', 'G')
-
-#pragma pack()
-
-#endif
diff --git a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi30.h b/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi30.h
deleted file mode 100644 (file)
index abaa721..0000000
+++ /dev/null
@@ -1,731 +0,0 @@
-/** @file
-  ACPI 3.0 definitions from the ACPI Specification Revision 3.0b October 10, 2006
-
-  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-**/
-
-#ifndef _ACPI_3_0_H_
-#define _ACPI_3_0_H_
-
-FILE_LICENCE ( BSD3 );
-
-#include <ipxe/efi/IndustryStandard/Acpi20.h>
-
-//
-// Define for Desriptor
-//
-#define ACPI_LARGE_EXTENDED_ADDRESS_SPACE_DESCRIPTOR_NAME    0x0B
-
-#define ACPI_EXTENDED_ADDRESS_SPACE_DESCRIPTOR    0x8B
-
-//
-// Ensure proper structure formats
-//
-#pragma pack(1)
-
-///
-/// Extended Address Space Descriptor
-///
-typedef PACKED struct {
-  ACPI_LARGE_RESOURCE_HEADER    Header;
-  UINT8                         ResType;
-  UINT8                         GenFlag;
-  UINT8                         SpecificFlag;
-  UINT8                         RevisionId;
-  UINT8                         Reserved;
-  UINT64                        AddrSpaceGranularity;
-  UINT64                        AddrRangeMin;
-  UINT64                        AddrRangeMax;
-  UINT64                        AddrTranslationOffset;
-  UINT64                        AddrLen;
-  UINT64                        TypeSpecificAttribute;
-} EFI_ACPI_EXTENDED_ADDRESS_SPACE_DESCRIPTOR;
-
-#pragma pack()
-
-//
-// Memory Type Specific Flags
-//
-#define EFI_ACPI_MEMORY_TYPE_SPECIFIC_ATTRIBUTES_UC  0x0000000000000001
-#define EFI_ACPI_MEMORY_TYPE_SPECIFIC_ATTRIBUTES_WC  0x0000000000000002
-#define EFI_ACPI_MEMORY_TYPE_SPECIFIC_ATTRIBUTES_WT  0x0000000000000004
-#define EFI_ACPI_MEMORY_TYPE_SPECIFIC_ATTRIBUTES_WB  0x0000000000000008
-#define EFI_ACPI_MEMORY_TYPE_SPECIFIC_ATTRIBUTES_UCE 0x0000000000000010
-#define EFI_ACPI_MEMORY_TYPE_SPECIFIC_ATTRIBUTES_NV  0x0000000000008000
-
-//
-// Ensure proper structure formats
-//
-#pragma pack(1)
-
-///
-/// ACPI 3.0 Generic Address Space definition
-///
-typedef struct {
-  UINT8   AddressSpaceId;
-  UINT8   RegisterBitWidth;
-  UINT8   RegisterBitOffset;
-  UINT8   AccessSize;
-  UINT64  Address;
-} EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE;
-
-//
-// Generic Address Space Address IDs
-//
-#define EFI_ACPI_3_0_SYSTEM_MEMORY              0
-#define EFI_ACPI_3_0_SYSTEM_IO                  1
-#define EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE    2
-#define EFI_ACPI_3_0_EMBEDDED_CONTROLLER        3
-#define EFI_ACPI_3_0_SMBUS                      4
-#define EFI_ACPI_3_0_FUNCTIONAL_FIXED_HARDWARE  0x7F
-
-//
-// Generic Address Space Access Sizes
-//
-#define EFI_ACPI_3_0_UNDEFINED  0
-#define EFI_ACPI_3_0_BYTE       1
-#define EFI_ACPI_3_0_WORD       2
-#define EFI_ACPI_3_0_DWORD      3
-#define EFI_ACPI_3_0_QWORD      4
-
-//
-// ACPI 3.0 table structures
-//
-
-///
-/// Root System Description Pointer Structure
-///
-typedef struct {
-  UINT64  Signature;
-  UINT8   Checksum;
-  UINT8   OemId[6];
-  UINT8   Revision;
-  UINT32  RsdtAddress;
-  UINT32  Length;
-  UINT64  XsdtAddress;
-  UINT8   ExtendedChecksum;
-  UINT8   Reserved[3];
-} EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
-
-///
-/// RSD_PTR Revision (as defined in ACPI 3.0b spec.)
-///
-#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02  ///< ACPISpec (Revision 3.0b) says current value is 2
-
-///
-/// Common table header, this prefaces all ACPI tables, including FACS, but
-/// excluding the RSD PTR structure
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-} EFI_ACPI_3_0_COMMON_HEADER;
-
-//
-// Root System Description Table
-// No definition needed as it is a common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers.
-//
-
-///
-/// RSDT Revision (as defined in ACPI 3.0 spec.)
-///
-#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
-
-//
-// Extended System Description Table
-// No definition needed as it is a common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers.
-//
-
-///
-/// XSDT Revision (as defined in ACPI 3.0 spec.)
-///
-#define EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Fixed ACPI Description Table Structure (FADT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER             Header;
-  UINT32                                  FirmwareCtrl;
-  UINT32                                  Dsdt;
-  UINT8                                   Reserved0;
-  UINT8                                   PreferredPmProfile;
-  UINT16                                  SciInt;
-  UINT32                                  SmiCmd;
-  UINT8                                   AcpiEnable;
-  UINT8                                   AcpiDisable;
-  UINT8                                   S4BiosReq;
-  UINT8                                   PstateCnt;
-  UINT32                                  Pm1aEvtBlk;
-  UINT32                                  Pm1bEvtBlk;
-  UINT32                                  Pm1aCntBlk;
-  UINT32                                  Pm1bCntBlk;
-  UINT32                                  Pm2CntBlk;
-  UINT32                                  PmTmrBlk;
-  UINT32                                  Gpe0Blk;
-  UINT32                                  Gpe1Blk;
-  UINT8                                   Pm1EvtLen;
-  UINT8                                   Pm1CntLen;
-  UINT8                                   Pm2CntLen;
-  UINT8                                   PmTmrLen;
-  UINT8                                   Gpe0BlkLen;
-  UINT8                                   Gpe1BlkLen;
-  UINT8                                   Gpe1Base;
-  UINT8                                   CstCnt;
-  UINT16                                  PLvl2Lat;
-  UINT16                                  PLvl3Lat;
-  UINT16                                  FlushSize;
-  UINT16                                  FlushStride;
-  UINT8                                   DutyOffset;
-  UINT8                                   DutyWidth;
-  UINT8                                   DayAlrm;
-  UINT8                                   MonAlrm;
-  UINT8                                   Century;
-  UINT16                                  IaPcBootArch;
-  UINT8                                   Reserved1;
-  UINT32                                  Flags;
-  EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE  ResetReg;
-  UINT8                                   ResetValue;
-  UINT8                                   Reserved2[3];
-  UINT64                                  XFirmwareCtrl;
-  UINT64                                  XDsdt;
-  EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE  XPm1aEvtBlk;
-  EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE  XPm1bEvtBlk;
-  EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE  XPm1aCntBlk;
-  EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE  XPm1bCntBlk;
-  EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE  XPm2CntBlk;
-  EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE  XPmTmrBlk;
-  EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE  XGpe0Blk;
-  EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE  XGpe1Blk;
-} EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE;
-
-///
-/// FADT Version (as defined in ACPI 3.0 spec.)
-///
-#define EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION  0x04
-
-//
-// Fixed ACPI Description Table Preferred Power Management Profile
-//
-#define EFI_ACPI_3_0_PM_PROFILE_UNSPECIFIED         0
-#define EFI_ACPI_3_0_PM_PROFILE_DESKTOP             1
-#define EFI_ACPI_3_0_PM_PROFILE_MOBILE              2
-#define EFI_ACPI_3_0_PM_PROFILE_WORKSTATION         3
-#define EFI_ACPI_3_0_PM_PROFILE_ENTERPRISE_SERVER   4
-#define EFI_ACPI_3_0_PM_PROFILE_SOHO_SERVER         5
-#define EFI_ACPI_3_0_PM_PROFILE_APPLIANCE_PC        6
-#define EFI_ACPI_3_0_PM_PROFILE_PERFORMANCE_SERVER  7
-
-//
-// Fixed ACPI Description Table Boot Architecture Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_3_0_LEGACY_DEVICES              BIT0
-#define EFI_ACPI_3_0_8042                        BIT1
-#define EFI_ACPI_3_0_VGA_NOT_PRESENT             BIT2
-#define EFI_ACPI_3_0_MSI_NOT_SUPPORTED           BIT3
-#define EFI_ACPI_3_0_PCIE_ASPM_CONTROLS          BIT4
-
-//
-// Fixed ACPI Description Table Fixed Feature Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_3_0_WBINVD                                 BIT0
-#define EFI_ACPI_3_0_WBINVD_FLUSH                           BIT1
-#define EFI_ACPI_3_0_PROC_C1                                BIT2
-#define EFI_ACPI_3_0_P_LVL2_UP                              BIT3
-#define EFI_ACPI_3_0_PWR_BUTTON                             BIT4
-#define EFI_ACPI_3_0_SLP_BUTTON                             BIT5
-#define EFI_ACPI_3_0_FIX_RTC                                BIT6
-#define EFI_ACPI_3_0_RTC_S4                                 BIT7
-#define EFI_ACPI_3_0_TMR_VAL_EXT                            BIT8
-#define EFI_ACPI_3_0_DCK_CAP                                BIT9
-#define EFI_ACPI_3_0_RESET_REG_SUP                          BIT10
-#define EFI_ACPI_3_0_SEALED_CASE                            BIT11
-#define EFI_ACPI_3_0_HEADLESS                               BIT12
-#define EFI_ACPI_3_0_CPU_SW_SLP                             BIT13
-#define EFI_ACPI_3_0_PCI_EXP_WAK                            BIT14
-#define EFI_ACPI_3_0_USE_PLATFORM_CLOCK                     BIT15
-#define EFI_ACPI_3_0_S4_RTC_STS_VALID                       BIT16
-#define EFI_ACPI_3_0_REMOTE_POWER_ON_CAPABLE                BIT17
-#define EFI_ACPI_3_0_FORCE_APIC_CLUSTER_MODEL               BIT18
-#define EFI_ACPI_3_0_FORCE_APIC_PHYSICAL_DESTINATION_MODE   BIT19
-
-///
-/// Firmware ACPI Control Structure
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-  UINT32  HardwareSignature;
-  UINT32  FirmwareWakingVector;
-  UINT32  GlobalLock;
-  UINT32  Flags;
-  UINT64  XFirmwareWakingVector;
-  UINT8   Version;
-  UINT8   Reserved[31];
-} EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
-
-///
-/// FACS Version (as defined in ACPI 3.0 spec.)
-///
-#define EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION  0x01
-
-///
-/// Firmware Control Structure Feature Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_3_0_S4BIOS_F       BIT0
-
-//
-// Differentiated System Description Table,
-// Secondary System Description Table
-// and Persistent System Description Table,
-// no definition needed as they are common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block.
-//
-#define EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION   0x02
-#define EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION        0x02
-
-///
-/// Multiple APIC Description Table header definition.  The rest of the table
-/// must be defined in a platform specific manner.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      LocalApicAddress;
-  UINT32                      Flags;
-} EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER;
-
-///
-/// MADT Revision (as defined in ACPI 3.0 spec.)
-///
-#define EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x02
-
-///
-/// Multiple APIC Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_3_0_PCAT_COMPAT         BIT0
-
-//
-// Multiple APIC Description Table APIC structure types
-// All other values between 0x09 an 0xFF are reserved and
-// will be ignored by OSPM.
-//
-#define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC           0x00
-#define EFI_ACPI_3_0_IO_APIC                        0x01
-#define EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE      0x02
-#define EFI_ACPI_3_0_NON_MASKABLE_INTERRUPT_SOURCE  0x03
-#define EFI_ACPI_3_0_LOCAL_APIC_NMI                 0x04
-#define EFI_ACPI_3_0_LOCAL_APIC_ADDRESS_OVERRIDE    0x05
-#define EFI_ACPI_3_0_IO_SAPIC                       0x06
-#define EFI_ACPI_3_0_LOCAL_SAPIC                    0x07
-#define EFI_ACPI_3_0_PLATFORM_INTERRUPT_SOURCES     0x08
-
-//
-// APIC Structure Definitions
-//
-
-///
-/// Processor Local APIC Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT8   ApicId;
-  UINT32  Flags;
-} EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE;
-
-///
-/// Local APIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_3_0_LOCAL_APIC_ENABLED        BIT0
-
-///
-/// IO APIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   IoApicId;
-  UINT8   Reserved;
-  UINT32  IoApicAddress;
-  UINT32  GlobalSystemInterruptBase;
-} EFI_ACPI_3_0_IO_APIC_STRUCTURE;
-
-///
-/// Interrupt Source Override Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Bus;
-  UINT8   Source;
-  UINT32  GlobalSystemInterrupt;
-  UINT16  Flags;
-} EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE;
-
-///
-/// Platform Interrupt Sources Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT8   InterruptType;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT8   IoSapicVector;
-  UINT32  GlobalSystemInterrupt;
-  UINT32  PlatformInterruptSourceFlags;
-  UINT8   CpeiProcessorOverride;
-  UINT8   Reserved[31];
-} EFI_ACPI_3_0_PLATFORM_INTERRUPT_APIC_STRUCTURE;
-
-//
-// MPS INTI flags.
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_3_0_POLARITY      (3 << 0)
-#define EFI_ACPI_3_0_TRIGGER_MODE  (3 << 2)
-
-///
-/// Non-Maskable Interrupt Source Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT32  GlobalSystemInterrupt;
-} EFI_ACPI_3_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE;
-
-///
-/// Local APIC NMI Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT16  Flags;
-  UINT8   LocalApicLint;
-} EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE;
-
-///
-/// Local APIC Address Override Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved;
-  UINT64  LocalApicAddress;
-} EFI_ACPI_3_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
-
-///
-/// IO SAPIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   IoApicId;
-  UINT8   Reserved;
-  UINT32  GlobalSystemInterruptBase;
-  UINT64  IoSapicAddress;
-} EFI_ACPI_3_0_IO_SAPIC_STRUCTURE;
-
-///
-/// Local SAPIC Structure
-/// This struct followed by a null-terminated ASCII string - ACPI Processor UID String
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT8   LocalSapicId;
-  UINT8   LocalSapicEid;
-  UINT8   Reserved[3];
-  UINT32  Flags;
-  UINT32  ACPIProcessorUIDValue;
-} EFI_ACPI_3_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
-
-///
-/// Platform Interrupt Sources Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT8   InterruptType;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT8   IoSapicVector;
-  UINT32  GlobalSystemInterrupt;
-  UINT32  PlatformInterruptSourceFlags;
-} EFI_ACPI_3_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE;
-
-///
-/// Platform Interrupt Source Flags.
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_3_0_CPEI_PROCESSOR_OVERRIDE          BIT0
-
-///
-/// Smart Battery Description Table (SBST)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      WarningEnergyLevel;
-  UINT32                      LowEnergyLevel;
-  UINT32                      CriticalEnergyLevel;
-} EFI_ACPI_3_0_SMART_BATTERY_DESCRIPTION_TABLE;
-
-///
-/// SBST Version (as defined in ACPI 3.0 spec.)
-///
-#define EFI_ACPI_3_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Embedded Controller Boot Resources Table (ECDT)
-/// The table is followed by a null terminated ASCII string that contains
-/// a fully qualified reference to the name space object.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER             Header;
-  EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE  EcControl;
-  EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE  EcData;
-  UINT32                                  Uid;
-  UINT8                                   GpeBit;
-} EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE;
-
-///
-/// ECDT Version (as defined in ACPI 3.0 spec.)
-///
-#define EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION  0x01
-
-///
-/// System Resource Affinity Table (SRAT.  The rest of the table
-/// must be defined in a platform specific manner.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      Reserved1;  ///< Must be set to 1
-  UINT64                      Reserved2;
-} EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER;
-
-///
-/// SRAT Version (as defined in ACPI 3.0 spec.)
-///
-#define EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION  0x02
-
-//
-// SRAT structure types.
-// All other values between 0x02 an 0xFF are reserved and
-// will be ignored by OSPM.
-//
-#define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY  0x00
-#define EFI_ACPI_3_0_MEMORY_AFFINITY                      0x01
-
-///
-/// Processor Local APIC/SAPIC Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   ProximityDomain7To0;
-  UINT8   ApicId;
-  UINT32  Flags;
-  UINT8   LocalSapicEid;
-  UINT8   ProximityDomain31To8[3];
-  UINT8   Reserved[4];
-} EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE;
-
-///
-/// Local APIC/SAPIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0)
-
-///
-/// Memory Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT32  ProximityDomain;
-  UINT16  Reserved1;
-  UINT32  AddressBaseLow;
-  UINT32  AddressBaseHigh;
-  UINT32  LengthLow;
-  UINT32  LengthHigh;
-  UINT32  Reserved2;
-  UINT32  Flags;
-  UINT64  Reserved3;
-} EFI_ACPI_3_0_MEMORY_AFFINITY_STRUCTURE;
-
-//
-// Memory Flags.  All other bits are reserved and must be 0.
-//
-#define EFI_ACPI_3_0_MEMORY_ENABLED       (1 << 0)
-#define EFI_ACPI_3_0_MEMORY_HOT_PLUGGABLE (1 << 1)
-#define EFI_ACPI_3_0_MEMORY_NONVOLATILE   (1 << 2)
-
-///
-/// System Locality Distance Information Table (SLIT).
-/// The rest of the table is a matrix.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT64                      NumberOfSystemLocalities;
-} EFI_ACPI_3_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER;
-
-///
-/// SLIT Version (as defined in ACPI 3.0 spec.)
-///
-#define EFI_ACPI_3_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION  0x01
-
-//
-// Known table signatures
-//
-
-///
-/// "RSD PTR " Root System Description Pointer
-///
-#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE  SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ')
-
-///
-/// "APIC" Multiple APIC Description Table
-///
-#define EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('A', 'P', 'I', 'C')
-
-///
-/// "DSDT" Differentiated System Description Table
-///
-#define EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('D', 'S', 'D', 'T')
-
-///
-/// "ECDT" Embedded Controller Boot Resources Table
-///
-#define EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE  SIGNATURE_32('E', 'C', 'D', 'T')
-
-///
-/// "FACP" Fixed ACPI Description Table
-///
-#define EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('F', 'A', 'C', 'P')
-
-///
-/// "FACS" Firmware ACPI Control Structure
-///
-#define EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE  SIGNATURE_32('F', 'A', 'C', 'S')
-
-///
-/// "PSDT" Persistent System Description Table
-///
-#define EFI_ACPI_3_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('P', 'S', 'D', 'T')
-
-///
-/// "RSDT" Root System Description Table
-///
-#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('R', 'S', 'D', 'T')
-
-///
-/// "SBST" Smart Battery Specification Table
-///
-#define EFI_ACPI_3_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE  SIGNATURE_32('S', 'B', 'S', 'T')
-
-///
-/// "SLIT" System Locality Information Table
-///
-#define EFI_ACPI_3_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE  SIGNATURE_32('S', 'L', 'I', 'T')
-
-///
-/// "SRAT" System Resource Affinity Table
-///
-#define EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE  SIGNATURE_32('S', 'R', 'A', 'T')
-
-///
-/// "SSDT" Secondary System Description Table
-///
-#define EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('S', 'S', 'D', 'T')
-
-///
-/// "XSDT" Extended System Description Table
-///
-#define EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('X', 'S', 'D', 'T')
-
-///
-/// "BOOT" MS Simple Boot Spec
-///
-#define EFI_ACPI_3_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE  SIGNATURE_32('B', 'O', 'O', 'T')
-
-///
-/// "CPEP" Corrected Platform Error Polling Table
-///
-#define EFI_ACPI_3_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE  SIGNATURE_32('C', 'P', 'E', 'P')
-
-///
-/// "DBGP" MS Debug Port Spec
-///
-#define EFI_ACPI_3_0_DEBUG_PORT_TABLE_SIGNATURE  SIGNATURE_32('D', 'B', 'G', 'P')
-
-///
-/// "ETDT" Event Timer Description Table
-///
-#define EFI_ACPI_3_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('E', 'T', 'D', 'T')
-
-///
-/// "HPET" IA-PC High Precision Event Timer Table
-///
-#define EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE  SIGNATURE_32('H', 'P', 'E', 'T')
-
-///
-/// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
-///
-#define EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('M', 'C', 'F', 'G')
-
-///
-/// "SPCR" Serial Port Concole Redirection Table
-///
-#define EFI_ACPI_3_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE  SIGNATURE_32('S', 'P', 'C', 'R')
-
-///
-/// "SPMI" Server Platform Management Interface Table
-///
-#define EFI_ACPI_3_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE  SIGNATURE_32('S', 'P', 'M', 'I')
-
-///
-/// "TCPA" Trusted Computing Platform Alliance Capabilities Table
-///
-#define EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE  SIGNATURE_32('T', 'C', 'P', 'A')
-
-///
-/// "WDRT" Watchdog Resource Table
-///
-#define EFI_ACPI_3_0_WATCHDOG_RESOURCE_TABLE_SIGNATURE  SIGNATURE_32('W', 'D', 'R', 'T')
-
-///
-/// "WDAT" Watchdog Action Table
-///
-#define EFI_ACPI_3_0_WATCHDOG_ACTION_TABLE_SIGNATURE  SIGNATURE_32('W', 'D', 'A', 'T')
-
-///
-/// "WSPT" Windows Specific Properties Table
-///
-#define EFI_ACPI_3_0_WINDOWS_SPECIFIC_PROPERTIES_TABLE_SIGNATURE  SIGNATURE_32('W', 'S', 'P', 'T')
-
-///
-/// "iBFT" iSCSI Boot Firmware Table
-///
-#define EFI_ACPI_3_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE  SIGNATURE_32('i', 'B', 'F', 'T')
-
-#pragma pack()
-
-#endif
diff --git a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi40.h b/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi40.h
deleted file mode 100644 (file)
index 5fcad3e..0000000
+++ /dev/null
@@ -1,1311 +0,0 @@
-/** @file
-  ACPI 4.0 definitions from the ACPI Specification Revision 4.0a April 5, 2010
-
-  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-**/
-
-#ifndef _ACPI_4_0_H_
-#define _ACPI_4_0_H_
-
-FILE_LICENCE ( BSD3 );
-
-#include <ipxe/efi/IndustryStandard/Acpi30.h>
-
-//
-// Ensure proper structure formats
-//
-#pragma pack(1)
-
-///
-/// ACPI 4.0 Generic Address Space definition
-///
-typedef struct {
-  UINT8   AddressSpaceId;
-  UINT8   RegisterBitWidth;
-  UINT8   RegisterBitOffset;
-  UINT8   AccessSize;
-  UINT64  Address;
-} EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE;
-
-//
-// Generic Address Space Address IDs
-//
-#define EFI_ACPI_4_0_SYSTEM_MEMORY              0
-#define EFI_ACPI_4_0_SYSTEM_IO                  1
-#define EFI_ACPI_4_0_PCI_CONFIGURATION_SPACE    2
-#define EFI_ACPI_4_0_EMBEDDED_CONTROLLER        3
-#define EFI_ACPI_4_0_SMBUS                      4
-#define EFI_ACPI_4_0_FUNCTIONAL_FIXED_HARDWARE  0x7F
-
-//
-// Generic Address Space Access Sizes
-//
-#define EFI_ACPI_4_0_UNDEFINED  0
-#define EFI_ACPI_4_0_BYTE       1
-#define EFI_ACPI_4_0_WORD       2
-#define EFI_ACPI_4_0_DWORD      3
-#define EFI_ACPI_4_0_QWORD      4
-
-//
-// ACPI 4.0 table structures
-//
-
-///
-/// Root System Description Pointer Structure
-///
-typedef struct {
-  UINT64  Signature;
-  UINT8   Checksum;
-  UINT8   OemId[6];
-  UINT8   Revision;
-  UINT32  RsdtAddress;
-  UINT32  Length;
-  UINT64  XsdtAddress;
-  UINT8   ExtendedChecksum;
-  UINT8   Reserved[3];
-} EFI_ACPI_4_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
-
-///
-/// RSD_PTR Revision (as defined in ACPI 4.0b spec.)
-///
-#define EFI_ACPI_4_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02  ///< ACPISpec (Revision 4.0a) says current value is 2
-
-///
-/// Common table header, this prefaces all ACPI tables, including FACS, but
-/// excluding the RSD PTR structure
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-} EFI_ACPI_4_0_COMMON_HEADER;
-
-//
-// Root System Description Table
-// No definition needed as it is a common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers.
-//
-
-///
-/// RSDT Revision (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
-
-//
-// Extended System Description Table
-// No definition needed as it is a common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers.
-//
-
-///
-/// XSDT Revision (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Fixed ACPI Description Table Structure (FADT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER             Header;
-  UINT32                                  FirmwareCtrl;
-  UINT32                                  Dsdt;
-  UINT8                                   Reserved0;
-  UINT8                                   PreferredPmProfile;
-  UINT16                                  SciInt;
-  UINT32                                  SmiCmd;
-  UINT8                                   AcpiEnable;
-  UINT8                                   AcpiDisable;
-  UINT8                                   S4BiosReq;
-  UINT8                                   PstateCnt;
-  UINT32                                  Pm1aEvtBlk;
-  UINT32                                  Pm1bEvtBlk;
-  UINT32                                  Pm1aCntBlk;
-  UINT32                                  Pm1bCntBlk;
-  UINT32                                  Pm2CntBlk;
-  UINT32                                  PmTmrBlk;
-  UINT32                                  Gpe0Blk;
-  UINT32                                  Gpe1Blk;
-  UINT8                                   Pm1EvtLen;
-  UINT8                                   Pm1CntLen;
-  UINT8                                   Pm2CntLen;
-  UINT8                                   PmTmrLen;
-  UINT8                                   Gpe0BlkLen;
-  UINT8                                   Gpe1BlkLen;
-  UINT8                                   Gpe1Base;
-  UINT8                                   CstCnt;
-  UINT16                                  PLvl2Lat;
-  UINT16                                  PLvl3Lat;
-  UINT16                                  FlushSize;
-  UINT16                                  FlushStride;
-  UINT8                                   DutyOffset;
-  UINT8                                   DutyWidth;
-  UINT8                                   DayAlrm;
-  UINT8                                   MonAlrm;
-  UINT8                                   Century;
-  UINT16                                  IaPcBootArch;
-  UINT8                                   Reserved1;
-  UINT32                                  Flags;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE  ResetReg;
-  UINT8                                   ResetValue;
-  UINT8                                   Reserved2[3];
-  UINT64                                  XFirmwareCtrl;
-  UINT64                                  XDsdt;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE  XPm1aEvtBlk;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE  XPm1bEvtBlk;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE  XPm1aCntBlk;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE  XPm1bCntBlk;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE  XPm2CntBlk;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE  XPmTmrBlk;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE  XGpe0Blk;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE  XGpe1Blk;
-} EFI_ACPI_4_0_FIXED_ACPI_DESCRIPTION_TABLE;
-
-///
-/// FADT Version (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION  0x04
-
-//
-// Fixed ACPI Description Table Preferred Power Management Profile
-//
-#define EFI_ACPI_4_0_PM_PROFILE_UNSPECIFIED         0
-#define EFI_ACPI_4_0_PM_PROFILE_DESKTOP             1
-#define EFI_ACPI_4_0_PM_PROFILE_MOBILE              2
-#define EFI_ACPI_4_0_PM_PROFILE_WORKSTATION         3
-#define EFI_ACPI_4_0_PM_PROFILE_ENTERPRISE_SERVER   4
-#define EFI_ACPI_4_0_PM_PROFILE_SOHO_SERVER         5
-#define EFI_ACPI_4_0_PM_PROFILE_APPLIANCE_PC        6
-#define EFI_ACPI_4_0_PM_PROFILE_PERFORMANCE_SERVER  7
-
-//
-// Fixed ACPI Description Table Boot Architecture Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_4_0_LEGACY_DEVICES              BIT0
-#define EFI_ACPI_4_0_8042                        BIT1
-#define EFI_ACPI_4_0_VGA_NOT_PRESENT             BIT2
-#define EFI_ACPI_4_0_MSI_NOT_SUPPORTED           BIT3
-#define EFI_ACPI_4_0_PCIE_ASPM_CONTROLS          BIT4
-
-//
-// Fixed ACPI Description Table Fixed Feature Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_4_0_WBINVD                                 BIT0
-#define EFI_ACPI_4_0_WBINVD_FLUSH                           BIT1
-#define EFI_ACPI_4_0_PROC_C1                                BIT2
-#define EFI_ACPI_4_0_P_LVL2_UP                              BIT3
-#define EFI_ACPI_4_0_PWR_BUTTON                             BIT4
-#define EFI_ACPI_4_0_SLP_BUTTON                             BIT5
-#define EFI_ACPI_4_0_FIX_RTC                                BIT6
-#define EFI_ACPI_4_0_RTC_S4                                 BIT7
-#define EFI_ACPI_4_0_TMR_VAL_EXT                            BIT8
-#define EFI_ACPI_4_0_DCK_CAP                                BIT9
-#define EFI_ACPI_4_0_RESET_REG_SUP                          BIT10
-#define EFI_ACPI_4_0_SEALED_CASE                            BIT11
-#define EFI_ACPI_4_0_HEADLESS                               BIT12
-#define EFI_ACPI_4_0_CPU_SW_SLP                             BIT13
-#define EFI_ACPI_4_0_PCI_EXP_WAK                            BIT14
-#define EFI_ACPI_4_0_USE_PLATFORM_CLOCK                     BIT15
-#define EFI_ACPI_4_0_S4_RTC_STS_VALID                       BIT16
-#define EFI_ACPI_4_0_REMOTE_POWER_ON_CAPABLE                BIT17
-#define EFI_ACPI_4_0_FORCE_APIC_CLUSTER_MODEL               BIT18
-#define EFI_ACPI_4_0_FORCE_APIC_PHYSICAL_DESTINATION_MODE   BIT19
-
-///
-/// Firmware ACPI Control Structure
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-  UINT32  HardwareSignature;
-  UINT32  FirmwareWakingVector;
-  UINT32  GlobalLock;
-  UINT32  Flags;
-  UINT64  XFirmwareWakingVector;
-  UINT8   Version;
-  UINT8   Reserved0[3];
-  UINT32  OspmFlags;
-  UINT8   Reserved1[24];
-} EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
-
-///
-/// FACS Version (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION  0x02
-
-///
-/// Firmware Control Structure Feature Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_4_0_S4BIOS_F                     BIT0
-#define EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F       BIT1
-
-///
-/// OSPM Enabled Firmware Control Structure Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_4_0_OSPM_64BIT_WAKE__F           BIT0
-
-//
-// Differentiated System Description Table,
-// Secondary System Description Table
-// and Persistent System Description Table,
-// no definition needed as they are common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block.
-//
-#define EFI_ACPI_4_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION   0x02
-#define EFI_ACPI_4_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION        0x02
-
-///
-/// Multiple APIC Description Table header definition.  The rest of the table
-/// must be defined in a platform specific manner.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      LocalApicAddress;
-  UINT32                      Flags;
-} EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER;
-
-///
-/// MADT Revision (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x03
-
-///
-/// Multiple APIC Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_4_0_PCAT_COMPAT         BIT0
-
-//
-// Multiple APIC Description Table APIC structure types
-// All other values between 0x0B an 0xFF are reserved and
-// will be ignored by OSPM.
-//
-#define EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC           0x00
-#define EFI_ACPI_4_0_IO_APIC                        0x01
-#define EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE      0x02
-#define EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE  0x03
-#define EFI_ACPI_4_0_LOCAL_APIC_NMI                 0x04
-#define EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE    0x05
-#define EFI_ACPI_4_0_IO_SAPIC                       0x06
-#define EFI_ACPI_4_0_LOCAL_SAPIC                    0x07
-#define EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES     0x08
-#define EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC         0x09
-#define EFI_ACPI_4_0_LOCAL_X2APIC_NMI               0x0A
-
-//
-// APIC Structure Definitions
-//
-
-///
-/// Processor Local APIC Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT8   ApicId;
-  UINT32  Flags;
-} EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE;
-
-///
-/// Local APIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_4_0_LOCAL_APIC_ENABLED        BIT0
-
-///
-/// IO APIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   IoApicId;
-  UINT8   Reserved;
-  UINT32  IoApicAddress;
-  UINT32  GlobalSystemInterruptBase;
-} EFI_ACPI_4_0_IO_APIC_STRUCTURE;
-
-///
-/// Interrupt Source Override Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Bus;
-  UINT8   Source;
-  UINT32  GlobalSystemInterrupt;
-  UINT16  Flags;
-} EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE;
-
-///
-/// Platform Interrupt Sources Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT8   InterruptType;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT8   IoSapicVector;
-  UINT32  GlobalSystemInterrupt;
-  UINT32  PlatformInterruptSourceFlags;
-  UINT8   CpeiProcessorOverride;
-  UINT8   Reserved[31];
-} EFI_ACPI_4_0_PLATFORM_INTERRUPT_APIC_STRUCTURE;
-
-//
-// MPS INTI flags.
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_4_0_POLARITY      (3 << 0)
-#define EFI_ACPI_4_0_TRIGGER_MODE  (3 << 2)
-
-///
-/// Non-Maskable Interrupt Source Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT32  GlobalSystemInterrupt;
-} EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE;
-
-///
-/// Local APIC NMI Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT16  Flags;
-  UINT8   LocalApicLint;
-} EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE;
-
-///
-/// Local APIC Address Override Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved;
-  UINT64  LocalApicAddress;
-} EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
-
-///
-/// IO SAPIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   IoApicId;
-  UINT8   Reserved;
-  UINT32  GlobalSystemInterruptBase;
-  UINT64  IoSapicAddress;
-} EFI_ACPI_4_0_IO_SAPIC_STRUCTURE;
-
-///
-/// Local SAPIC Structure
-/// This struct followed by a null-terminated ASCII string - ACPI Processor UID String
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT8   LocalSapicId;
-  UINT8   LocalSapicEid;
-  UINT8   Reserved[3];
-  UINT32  Flags;
-  UINT32  ACPIProcessorUIDValue;
-} EFI_ACPI_4_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
-
-///
-/// Platform Interrupt Sources Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT8   InterruptType;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT8   IoSapicVector;
-  UINT32  GlobalSystemInterrupt;
-  UINT32  PlatformInterruptSourceFlags;
-} EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE;
-
-///
-/// Platform Interrupt Source Flags.
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_4_0_CPEI_PROCESSOR_OVERRIDE          BIT0
-
-///
-/// Processor Local x2APIC Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Reserved[2];
-  UINT32  X2ApicId;
-  UINT32  Flags;
-  UINT32  AcpiProcessorUid;
-} EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE;
-
-///
-/// Local x2APIC NMI Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT32  AcpiProcessorUid;
-  UINT8   LocalX2ApicLint;
-  UINT8   Reserved[3];
-} EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE;
-
-///
-/// Smart Battery Description Table (SBST)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      WarningEnergyLevel;
-  UINT32                      LowEnergyLevel;
-  UINT32                      CriticalEnergyLevel;
-} EFI_ACPI_4_0_SMART_BATTERY_DESCRIPTION_TABLE;
-
-///
-/// SBST Version (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Embedded Controller Boot Resources Table (ECDT)
-/// The table is followed by a null terminated ASCII string that contains
-/// a fully qualified reference to the name space object.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER             Header;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE  EcControl;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE  EcData;
-  UINT32                                  Uid;
-  UINT8                                   GpeBit;
-} EFI_ACPI_4_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE;
-
-///
-/// ECDT Version (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION  0x01
-
-///
-/// System Resource Affinity Table (SRAT.  The rest of the table
-/// must be defined in a platform specific manner.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      Reserved1;  ///< Must be set to 1
-  UINT64                      Reserved2;
-} EFI_ACPI_4_0_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER;
-
-///
-/// SRAT Version (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION  0x03
-
-//
-// SRAT structure types.
-// All other values between 0x03 an 0xFF are reserved and
-// will be ignored by OSPM.
-//
-#define EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY  0x00
-#define EFI_ACPI_4_0_MEMORY_AFFINITY                      0x01
-#define EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_AFFINITY      0x02
-
-///
-/// Processor Local APIC/SAPIC Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   ProximityDomain7To0;
-  UINT8   ApicId;
-  UINT32  Flags;
-  UINT8   LocalSapicEid;
-  UINT8   ProximityDomain31To8[3];
-  UINT32  ClockDomain;
-} EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE;
-
-///
-/// Local APIC/SAPIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0)
-
-///
-/// Memory Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT32  ProximityDomain;
-  UINT16  Reserved1;
-  UINT32  AddressBaseLow;
-  UINT32  AddressBaseHigh;
-  UINT32  LengthLow;
-  UINT32  LengthHigh;
-  UINT32  Reserved2;
-  UINT32  Flags;
-  UINT64  Reserved3;
-} EFI_ACPI_4_0_MEMORY_AFFINITY_STRUCTURE;
-
-//
-// Memory Flags.  All other bits are reserved and must be 0.
-//
-#define EFI_ACPI_4_0_MEMORY_ENABLED       (1 << 0)
-#define EFI_ACPI_4_0_MEMORY_HOT_PLUGGABLE (1 << 1)
-#define EFI_ACPI_4_0_MEMORY_NONVOLATILE   (1 << 2)
-
-///
-/// Processor Local x2APIC Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Reserved1[2];
-  UINT32  ProximityDomain;
-  UINT32  X2ApicId;
-  UINT32  Flags;
-  UINT32  ClockDomain;
-  UINT8   Reserved2[4];
-} EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE;
-
-///
-/// System Locality Distance Information Table (SLIT).
-/// The rest of the table is a matrix.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT64                      NumberOfSystemLocalities;
-} EFI_ACPI_4_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER;
-
-///
-/// SLIT Version (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION  0x01
-
-///
-/// Corrected Platform Error Polling Table (CPEP)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT8                       Reserved[8];
-} EFI_ACPI_4_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER;
-
-///
-/// CPEP Version (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_REVISION 0x01
-
-//
-// CPEP processor structure types.
-//
-#define EFI_ACPI_4_0_CPEP_PROCESSOR_APIC_SAPIC  0x00
-
-///
-/// Corrected Platform Error Polling Processor Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT32  PollingInterval;
-} EFI_ACPI_4_0_CPEP_PROCESSOR_APIC_SAPIC_STRUCTURE;
-
-///
-/// Maximum System Characteristics Table (MSCT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      OffsetProxDomInfo;
-  UINT32                      MaximumNumberOfProximityDomains;
-  UINT32                      MaximumNumberOfClockDomains;
-  UINT64                      MaximumPhysicalAddress;
-} EFI_ACPI_4_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_HEADER;
-
-///
-/// MSCT Version (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_REVISION 0x01
-
-///
-/// Maximum Proximity Domain Information Structure Definition
-///
-typedef struct {
-  UINT8   Revision;
-  UINT8   Length;
-  UINT32  ProximityDomainRangeLow;
-  UINT32  ProximityDomainRangeHigh;
-  UINT32  MaximumProcessorCapacity;
-  UINT64  MaximumMemoryCapacity;
-} EFI_ACPI_4_0_MAXIMUM_PROXIMITY_DOMAIN_INFORMATION_STRUCTURE;
-
-///
-/// Boot Error Record Table (BERT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      BootErrorRegionLength;
-  UINT64                      BootErrorRegion;
-} EFI_ACPI_4_0_BOOT_ERROR_RECORD_TABLE_HEADER;
-
-///
-/// BERT Version (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_BOOT_ERROR_RECORD_TABLE_REVISION 0x01
-
-///
-/// Boot Error Region Block Status Definition
-///
-typedef struct {
-  UINT32       UncorrectableErrorValid:1;
-  UINT32       CorrectableErrorValid:1;
-  UINT32       MultipleUncorrectableErrors:1;
-  UINT32       MultipleCorrectableErrors:1;
-  UINT32       ErrorDataEntryCount:10;
-  UINT32       Reserved:18;
-} EFI_ACPI_4_0_ERROR_BLOCK_STATUS;
-
-///
-/// Boot Error Region Definition
-///
-typedef struct {
-  EFI_ACPI_4_0_ERROR_BLOCK_STATUS              BlockStatus;
-  UINT32                                       RawDataOffset;
-  UINT32                                       RawDataLength;
-  UINT32                                       DataLength;
-  UINT32                                       ErrorSeverity;
-} EFI_ACPI_4_0_BOOT_ERROR_REGION_STRUCTURE;
-
-//
-// Boot Error Severity types
-//
-#define EFI_ACPI_4_0_ERROR_SEVERITY_CORRECTABLE  0x00
-#define EFI_ACPI_4_0_ERROR_SEVERITY_FATAL        0x01
-#define EFI_ACPI_4_0_ERROR_SEVERITY_CORRECTED    0x02
-#define EFI_ACPI_4_0_ERROR_SEVERITY_NONE         0x03
-
-///
-/// Generic Error Data Entry Definition
-///
-typedef struct {
-  UINT8    SectionType[16];
-  UINT32   ErrorSeverity;
-  UINT16   Revision;
-  UINT8    ValidationBits;
-  UINT8    Flags;
-  UINT32   ErrorDataLength;
-  UINT8    FruId[16];
-  UINT8    FruText[20];
-} EFI_ACPI_4_0_GENERIC_ERROR_DATA_ENTRY_STRUCTURE;
-
-///
-/// Generic Error Data Entry Version (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_GENERIC_ERROR_DATA_ENTRY_REVISION  0x0201
-
-///
-/// HEST - Hardware Error Source Table
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      ErrorSourceCount;
-} EFI_ACPI_4_0_HARDWARE_ERROR_SOURCE_TABLE_HEADER;
-
-///
-/// HEST Version (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01
-
-//
-// Error Source structure types.
-//
-#define EFI_ACPI_4_0_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION  0x00
-#define EFI_ACPI_4_0_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK  0x01
-#define EFI_ACPI_4_0_IA32_ARCHITECTURE_NMI_ERROR                0x02
-#define EFI_ACPI_4_0_PCI_EXPRESS_ROOT_PORT_AER                  0x06
-#define EFI_ACPI_4_0_PCI_EXPRESS_DEVICE_AER                     0x07
-#define EFI_ACPI_4_0_PCI_EXPRESS_BRIDGE_AER                     0x08
-#define EFI_ACPI_4_0_GENERIC_HARDWARE_ERROR                     0x09
-
-//
-// Error Source structure flags.
-//
-#define EFI_ACPI_4_0_ERROR_SOURCE_FLAG_FIRMWARE_FIRST       (1 << 0)
-#define EFI_ACPI_4_0_ERROR_SOURCE_FLAG_GLOBAL               (1 << 1)
-
-///
-/// IA-32 Architecture Machine Check Exception Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT64  GlobalCapabilityInitData;
-  UINT64  GlobalControlInitData;
-  UINT8   NumberOfHardwareBanks;
-  UINT8   Reserved1[7];
-} EFI_ACPI_4_0_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE;
-
-///
-/// IA-32 Architecture Machine Check Bank Structure Definition
-///
-typedef struct {
-  UINT8   BankNumber;
-  UINT8   ClearStatusOnInitialization;
-  UINT8   StatusDataFormat;
-  UINT8   Reserved0;
-  UINT32  ControlRegisterMsrAddress;
-  UINT64  ControlInitData;
-  UINT32  StatusRegisterMsrAddress;
-  UINT32  AddressRegisterMsrAddress;
-  UINT32  MiscRegisterMsrAddress;
-} EFI_ACPI_4_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE;
-
-///
-/// IA-32 Architecture Machine Check Bank Structure MCA data format
-///
-#define EFI_ACPI_4_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_IA32      0x00
-#define EFI_ACPI_4_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_INTEL64   0x01
-#define EFI_ACPI_4_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_AMD64     0x02
-
-//
-// Hardware Error Notification types. All other values are reserved
-//
-#define EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_POLLED                0x00
-#define EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_EXTERNAL_INTERRUPT    0x01
-#define EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_LOCAL_INTERRUPT       0x02
-#define EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_SCI                   0x03
-#define EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_NMI                   0x04
-
-///
-/// Hardware Error Notification Configuration Write Enable Structure Definition
-///
-typedef struct {
-  UINT16    Type:1;
-  UINT16    PollInterval:1;
-  UINT16    SwitchToPollingThresholdValue:1;
-  UINT16    SwitchToPollingThresholdWindow:1;
-  UINT16    ErrorThresholdValue:1;
-  UINT16    ErrorThresholdWindow:1;
-  UINT16    Reserved:10;
-} EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE;
-
-///
-/// Hardware Error Notification Structure Definition
-///
-typedef struct {
-  UINT8                                                                          Type;
-  UINT8                                                                          Length;
-  EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE  ConfigurationWriteEnable;
-  UINT32                                                                         PollInterval;
-  UINT32                                                                         Vector;
-  UINT32                                                                         SwitchToPollingThresholdValue;
-  UINT32                                                                         SwitchToPollingThresholdWindow;
-  UINT32                                                                         ErrorThresholdValue;
-  UINT32                                                                         ErrorThresholdWindow;
-} EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE;
-
-///
-/// IA-32 Architecture Corrected Machine Check Structure Definition
-///
-typedef struct {
-  UINT16                                                 Type;
-  UINT16                                                 SourceId;
-  UINT8                                                  Reserved0[2];
-  UINT8                                                  Flags;
-  UINT8                                                  Enabled;
-  UINT32                                                 NumberOfRecordsToPreAllocate;
-  UINT32                                                 MaxSectionsPerRecord;
-  EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE     NotificationStructure;
-  UINT8                                                  NumberOfHardwareBanks;
-  UINT8                                                  Reserved1[3];
-} EFI_ACPI_4_0_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE;
-
-///
-/// IA-32 Architecture NMI Error Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  MaxRawDataLength;
-} EFI_ACPI_4_0_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE;
-
-///
-/// PCI Express Root Port AER Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  Bus;
-  UINT16  Device;
-  UINT16  Function;
-  UINT16  DeviceControl;
-  UINT8   Reserved1[2];
-  UINT32  UncorrectableErrorMask;
-  UINT32  UncorrectableErrorSeverity;
-  UINT32  CorrectableErrorMask;
-  UINT32  AdvancedErrorCapabilitiesAndControl;
-  UINT32  RootErrorCommand;
-} EFI_ACPI_4_0_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE;
-
-///
-/// PCI Express Device AER Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  Bus;
-  UINT16  Device;
-  UINT16  Function;
-  UINT16  DeviceControl;
-  UINT8   Reserved1[2];
-  UINT32  UncorrectableErrorMask;
-  UINT32  UncorrectableErrorSeverity;
-  UINT32  CorrectableErrorMask;
-  UINT32  AdvancedErrorCapabilitiesAndControl;
-} EFI_ACPI_4_0_PCI_EXPRESS_DEVICE_AER_STRUCTURE;
-
-///
-/// PCI Express Bridge AER Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  Bus;
-  UINT16  Device;
-  UINT16  Function;
-  UINT16  DeviceControl;
-  UINT8   Reserved1[2];
-  UINT32  UncorrectableErrorMask;
-  UINT32  UncorrectableErrorSeverity;
-  UINT32  CorrectableErrorMask;
-  UINT32  AdvancedErrorCapabilitiesAndControl;
-  UINT32  SecondaryUncorrectableErrorMask;
-  UINT32  SecondaryUncorrectableErrorSeverity;
-  UINT32  SecondaryAdvancedErrorCapabilitiesAndControl;
-} EFI_ACPI_4_0_PCI_EXPRESS_BRIDGE_AER_STRUCTURE;
-
-///
-/// Generic Hardware Error Source Structure Definition
-///
-typedef struct {
-  UINT16                                                 Type;
-  UINT16                                                 SourceId;
-  UINT16                                                 RelatedSourceId;
-  UINT8                                                  Flags;
-  UINT8                                                  Enabled;
-  UINT32                                                 NumberOfRecordsToPreAllocate;
-  UINT32                                                 MaxSectionsPerRecord;
-  UINT32                                                 MaxRawDataLength;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE                 ErrorStatusAddress;
-  EFI_ACPI_4_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE     NotificationStructure;
-  UINT32                                                 ErrorStatusBlockLength;
-} EFI_ACPI_4_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE;
-
-///
-/// Generic Error Status Definition
-///
-typedef struct {
-  EFI_ACPI_4_0_ERROR_BLOCK_STATUS              BlockStatus;
-  UINT32                                       RawDataOffset;
-  UINT32                                       RawDataLength;
-  UINT32                                       DataLength;
-  UINT32                                       ErrorSeverity;
-} EFI_ACPI_4_0_GENERIC_ERROR_STATUS_STRUCTURE;
-
-///
-/// ERST - Error Record Serialization Table
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      SerializationHeaderSize;
-  UINT8                       Reserved0[4];
-  UINT32                      InstructionEntryCount;
-} EFI_ACPI_4_0_ERROR_RECORD_SERIALIZATION_TABLE_HEADER;
-
-///
-/// ERST Version (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_ERROR_RECORD_SERIALIZATION_TABLE_REVISION 0x01
-
-///
-/// ERST Serialization Actions
-///
-#define EFI_ACPI_4_0_ERST_BEGIN_WRITE_OPERATION                    0x00
-#define EFI_ACPI_4_0_ERST_BEGIN_READ_OPERATION                     0x01
-#define EFI_ACPI_4_0_ERST_BEGIN_CLEAR_OPERATION                    0x02
-#define EFI_ACPI_4_0_ERST_END_OPERATION                            0x03
-#define EFI_ACPI_4_0_ERST_SET_RECORD_OFFSET                        0x04
-#define EFI_ACPI_4_0_ERST_EXECUTE_OPERATION                        0x05
-#define EFI_ACPI_4_0_ERST_CHECK_BUSY_STATUS                        0x06
-#define EFI_ACPI_4_0_ERST_GET_COMMAND_STATUS                       0x07
-#define EFI_ACPI_4_0_ERST_GET_RECORD_IDENTIFIER                    0x08
-#define EFI_ACPI_4_0_ERST_SET_RECORD_IDENTIFIER                    0x09
-#define EFI_ACPI_4_0_ERST_GET_RECORD_COUNT                         0x0A
-#define EFI_ACPI_4_0_ERST_BEGIN_DUMMY_WRITE_OPERATION              0x0B
-#define EFI_ACPI_4_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE              0x0D
-#define EFI_ACPI_4_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE_LENGTH       0x0E
-#define EFI_ACPI_4_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES   0x0F
-
-///
-/// ERST Action Command Status
-///
-#define EFI_ACPI_4_0_EINJ_STATUS_SUCCESS                           0x00
-#define EFI_ACPI_4_0_EINJ_STATUS_NOT_ENOUGH_SPACE                  0x01
-#define EFI_ACPI_4_0_EINJ_STATUS_HARDWARE_NOT_AVAILABLE            0x02
-#define EFI_ACPI_4_0_EINJ_STATUS_FAILED                            0x03
-#define EFI_ACPI_4_0_EINJ_STATUS_RECORD_STORE_EMPTY                0x04
-#define EFI_ACPI_4_0_EINJ_STATUS_RECORD_NOT_FOUND                  0x05
-
-///
-/// ERST Serialization Instructions
-///
-#define EFI_ACPI_4_0_ERST_READ_REGISTER                            0x00
-#define EFI_ACPI_4_0_ERST_READ_REGISTER_VALUE                      0x01
-#define EFI_ACPI_4_0_ERST_WRITE_REGISTER                           0x02
-#define EFI_ACPI_4_0_ERST_WRITE_REGISTER_VALUE                     0x03
-#define EFI_ACPI_4_0_ERST_NOOP                                     0x04
-#define EFI_ACPI_4_0_ERST_LOAD_VAR1                                0x05
-#define EFI_ACPI_4_0_ERST_LOAD_VAR2                                0x06
-#define EFI_ACPI_4_0_ERST_STORE_VAR1                               0x07
-#define EFI_ACPI_4_0_ERST_ADD                                      0x08
-#define EFI_ACPI_4_0_ERST_SUBTRACT                                 0x09
-#define EFI_ACPI_4_0_ERST_ADD_VALUE                                0x0A
-#define EFI_ACPI_4_0_ERST_SUBTRACT_VALUE                           0x0B
-#define EFI_ACPI_4_0_ERST_STALL                                    0x0C
-#define EFI_ACPI_4_0_ERST_STALL_WHILE_TRUE                         0x0D
-#define EFI_ACPI_4_0_ERST_SKIP_NEXT_INSTRUCTION_IF_TRUE            0x0E
-#define EFI_ACPI_4_0_ERST_GOTO                                     0x0F
-#define EFI_ACPI_4_0_ERST_SET_SRC_ADDRESS_BASE                     0x10
-#define EFI_ACPI_4_0_ERST_SET_DST_ADDRESS_BASE                     0x11
-#define EFI_ACPI_4_0_ERST_MOVE_DATA                                0x12
-
-///
-/// ERST Instruction Flags
-///
-#define EFI_ACPI_4_0_ERST_PRESERVE_REGISTER                        0x01
-
-///
-/// ERST Serialization Instruction Entry
-///
-typedef struct {
-  UINT8                                    SerializationAction;
-  UINT8                                    Instruction;
-  UINT8                                    Flags;
-  UINT8                                    Reserved0;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE   RegisterRegion;
-  UINT64                                   Value;
-  UINT64                                   Mask;
-} EFI_ACPI_4_0_ERST_SERIALIZATION_INSTRUCTION_ENTRY;
-
-///
-/// EINJ - Error Injection Table
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      InjectionHeaderSize;
-  UINT8                       InjectionFlags;
-  UINT8                       Reserved0[3];
-  UINT32                      InjectionEntryCount;
-} EFI_ACPI_4_0_ERROR_INJECTION_TABLE_HEADER;
-
-///
-/// EINJ Version (as defined in ACPI 4.0 spec.)
-///
-#define EFI_ACPI_4_0_ERROR_INJECTION_TABLE_REVISION 0x01
-
-///
-/// EINJ Error Injection Actions
-///
-#define EFI_ACPI_4_0_EINJ_BEGIN_INJECTION_OPERATION                0x00
-#define EFI_ACPI_4_0_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE           0x01
-#define EFI_ACPI_4_0_EINJ_SET_ERROR_TYPE                           0x02
-#define EFI_ACPI_4_0_EINJ_GET_ERROR_TYPE                           0x03
-#define EFI_ACPI_4_0_EINJ_END_OPERATION                            0x04
-#define EFI_ACPI_4_0_EINJ_EXECUTE_OPERATION                        0x05
-#define EFI_ACPI_4_0_EINJ_CHECK_BUSY_STATUS                        0x06
-#define EFI_ACPI_4_0_EINJ_GET_COMMAND_STATUS                       0x07
-#define EFI_ACPI_4_0_EINJ_TRIGGER_ERROR                            0xFF
-
-///
-/// EINJ Action Command Status
-///
-#define EFI_ACPI_4_0_EINJ_STATUS_SUCCESS                           0x00
-#define EFI_ACPI_4_0_EINJ_STATUS_UNKNOWN_FAILURE                   0x01
-#define EFI_ACPI_4_0_EINJ_STATUS_INVALID_ACCESS                    0x02
-
-///
-/// EINJ Error Type Definition
-///
-#define EFI_ACPI_4_0_EINJ_ERROR_PROCESSOR_CORRECTABLE                 (1 << 0)
-#define EFI_ACPI_4_0_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_NONFATAL      (1 << 1)
-#define EFI_ACPI_4_0_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_FATAL         (1 << 2)
-#define EFI_ACPI_4_0_EINJ_ERROR_MEMORY_CORRECTABLE                    (1 << 3)
-#define EFI_ACPI_4_0_EINJ_ERROR_MEMORY_UNCORRECTABLE_NONFATAL         (1 << 4)
-#define EFI_ACPI_4_0_EINJ_ERROR_MEMORY_UNCORRECTABLE_FATAL            (1 << 5)
-#define EFI_ACPI_4_0_EINJ_ERROR_PCI_EXPRESS_CORRECTABLE               (1 << 6)
-#define EFI_ACPI_4_0_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_NONFATAL    (1 << 7)
-#define EFI_ACPI_4_0_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_FATAL       (1 << 8)
-#define EFI_ACPI_4_0_EINJ_ERROR_PLATFORM_CORRECTABLE                  (1 << 9)
-#define EFI_ACPI_4_0_EINJ_ERROR_PLATFORM_UNCORRECTABLE_NONFATAL       (1 << 10)
-#define EFI_ACPI_4_0_EINJ_ERROR_PLATFORM_UNCORRECTABLE_FATAL          (1 << 11)
-
-///
-/// EINJ Injection Instructions
-///
-#define EFI_ACPI_4_0_EINJ_READ_REGISTER                            0x00
-#define EFI_ACPI_4_0_EINJ_READ_REGISTER_VALUE                      0x01
-#define EFI_ACPI_4_0_EINJ_WRITE_REGISTER                           0x02
-#define EFI_ACPI_4_0_EINJ_WRITE_REGISTER_VALUE                     0x03
-#define EFI_ACPI_4_0_EINJ_NOOP                                     0x04
-
-///
-/// EINJ Instruction Flags
-///
-#define EFI_ACPI_4_0_EINJ_PRESERVE_REGISTER                        0x01
-
-///
-/// EINJ Injection Instruction Entry
-///
-typedef struct {
-  UINT8                                    InjectionAction;
-  UINT8                                    Instruction;
-  UINT8                                    Flags;
-  UINT8                                    Reserved0;
-  EFI_ACPI_4_0_GENERIC_ADDRESS_STRUCTURE   RegisterRegion;
-  UINT64                                   Value;
-  UINT64                                   Mask;
-} EFI_ACPI_4_0_EINJ_INJECTION_INSTRUCTION_ENTRY;
-
-///
-/// EINJ Trigger Action Table
-///
-typedef struct {
-  UINT32  HeaderSize;
-  UINT32  Revision;
-  UINT32  TableSize;
-  UINT32  EntryCount;
-} EFI_ACPI_4_0_EINJ_TRIGGER_ACTION_TABLE;
-
-//
-// Known table signatures
-//
-
-///
-/// "RSD PTR " Root System Description Pointer
-///
-#define EFI_ACPI_4_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE  SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ')
-
-///
-/// "APIC" Multiple APIC Description Table
-///
-#define EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('A', 'P', 'I', 'C')
-
-///
-/// "BERT" Boot Error Record Table
-///
-#define EFI_ACPI_4_0_BOOT_ERROR_RECORD_TABLE_SIGNATURE  SIGNATURE_32('B', 'E', 'R', 'T')
-
-///
-/// "CPEP" Corrected Platform Error Polling Table
-///
-#define EFI_ACPI_4_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE  SIGNATURE_32('C', 'P', 'E', 'P')
-
-///
-/// "DSDT" Differentiated System Description Table
-///
-#define EFI_ACPI_4_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('D', 'S', 'D', 'T')
-
-///
-/// "ECDT" Embedded Controller Boot Resources Table
-///
-#define EFI_ACPI_4_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE  SIGNATURE_32('E', 'C', 'D', 'T')
-
-///
-/// "EINJ" Error Injection Table
-///
-#define EFI_ACPI_4_0_ERROR_INJECTION_TABLE_SIGNATURE  SIGNATURE_32('E', 'I', 'N', 'J')
-
-///
-/// "ERST" Error Record Serialization Table
-///
-#define EFI_ACPI_4_0_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE  SIGNATURE_32('E', 'R', 'S', 'T')
-
-///
-/// "FACP" Fixed ACPI Description Table
-///
-#define EFI_ACPI_4_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('F', 'A', 'C', 'P')
-
-///
-/// "FACS" Firmware ACPI Control Structure
-///
-#define EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE  SIGNATURE_32('F', 'A', 'C', 'S')
-
-///
-/// "HEST" Hardware Error Source Table
-///
-#define EFI_ACPI_4_0_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE  SIGNATURE_32('H', 'E', 'S', 'T')
-
-///
-/// "MSCT" Maximum System Characteristics Table
-///
-#define EFI_ACPI_4_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE  SIGNATURE_32('M', 'S', 'C', 'T')
-
-///
-/// "PSDT" Persistent System Description Table
-///
-#define EFI_ACPI_4_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('P', 'S', 'D', 'T')
-
-///
-/// "RSDT" Root System Description Table
-///
-#define EFI_ACPI_4_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('R', 'S', 'D', 'T')
-
-///
-/// "SBST" Smart Battery Specification Table
-///
-#define EFI_ACPI_4_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE  SIGNATURE_32('S', 'B', 'S', 'T')
-
-///
-/// "SLIT" System Locality Information Table
-///
-#define EFI_ACPI_4_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE  SIGNATURE_32('S', 'L', 'I', 'T')
-
-///
-/// "SRAT" System Resource Affinity Table
-///
-#define EFI_ACPI_4_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE  SIGNATURE_32('S', 'R', 'A', 'T')
-
-///
-/// "SSDT" Secondary System Description Table
-///
-#define EFI_ACPI_4_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('S', 'S', 'D', 'T')
-
-///
-/// "XSDT" Extended System Description Table
-///
-#define EFI_ACPI_4_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('X', 'S', 'D', 'T')
-
-///
-/// "BOOT" MS Simple Boot Spec
-///
-#define EFI_ACPI_4_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE  SIGNATURE_32('B', 'O', 'O', 'T')
-
-///
-/// "DBGP" MS Debug Port Spec
-///
-#define EFI_ACPI_4_0_DEBUG_PORT_TABLE_SIGNATURE  SIGNATURE_32('D', 'B', 'G', 'P')
-
-///
-/// "DMAR" DMA Remapping Table
-///
-#define EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE  SIGNATURE_32('D', 'M', 'A', 'R')
-
-///
-/// "ETDT" Event Timer Description Table
-///
-#define EFI_ACPI_4_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('E', 'T', 'D', 'T')
-
-///
-/// "HPET" IA-PC High Precision Event Timer Table
-///
-#define EFI_ACPI_4_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE  SIGNATURE_32('H', 'P', 'E', 'T')
-
-///
-/// "iBFT" iSCSI Boot Firmware Table
-///
-#define EFI_ACPI_4_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE  SIGNATURE_32('i', 'B', 'F', 'T')
-
-///
-/// "IVRS" I/O Virtualization Reporting Structure
-///
-#define EFI_ACPI_4_0_IO_VIRTUALIZATION_REPORTING_STRUCTURE_SIGNATURE  SIGNATURE_32('I', 'V', 'R', 'S')
-
-///
-/// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
-///
-#define EFI_ACPI_4_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('M', 'C', 'F', 'G')
-
-///
-/// "MCHI" Management Controller Host Interface Table
-///
-#define EFI_ACPI_4_0_MANAGEMENT_CONTROLLER_HOST_INTERFACE_TABLE_SIGNATURE  SIGNATURE_32('M', 'C', 'H', 'I')
-
-///
-/// "SPCR" Serial Port Concole Redirection Table
-///
-#define EFI_ACPI_4_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE  SIGNATURE_32('S', 'P', 'C', 'R')
-
-///
-/// "SPMI" Server Platform Management Interface Table
-///
-#define EFI_ACPI_4_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE  SIGNATURE_32('S', 'P', 'M', 'I')
-
-///
-/// "TCPA" Trusted Computing Platform Alliance Capabilities Table
-///
-#define EFI_ACPI_4_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE  SIGNATURE_32('T', 'C', 'P', 'A')
-
-///
-/// "UEFI" UEFI ACPI Data Table
-///
-#define EFI_ACPI_4_0_UEFI_ACPI_DATA_TABLE_SIGNATURE  SIGNATURE_32('U', 'E', 'F', 'I')
-
-///
-/// "WAET" Windows ACPI Enlightenment Table
-///
-#define EFI_ACPI_4_0_WINDOWS_ACPI_ENLIGHTENMENT_TABLE_SIGNATURE  SIGNATURE_32('W', 'A', 'E', 'T')
-
-///
-/// "WDAT" Watchdog Action Table
-///
-#define EFI_ACPI_4_0_WATCHDOG_ACTION_TABLE_SIGNATURE  SIGNATURE_32('W', 'D', 'A', 'T')
-
-///
-/// "WDRT" Watchdog Resource Table
-///
-#define EFI_ACPI_4_0_WATCHDOG_RESOURCE_TABLE_SIGNATURE  SIGNATURE_32('W', 'D', 'R', 'T')
-
-#pragma pack()
-
-#endif
diff --git a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi50.h b/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi50.h
deleted file mode 100644 (file)
index df9e715..0000000
+++ /dev/null
@@ -1,2121 +0,0 @@
-/** @file
-  ACPI 5.0 definitions from the ACPI Specification Revision 5.0a November 13, 2013.
-
-  Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>
-  Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-**/
-
-#ifndef _ACPI_5_0_H_
-#define _ACPI_5_0_H_
-
-FILE_LICENCE ( BSD3 );
-
-#include <ipxe/efi/IndustryStandard/Acpi40.h>
-
-//
-// Define for Desriptor
-//
-#define ACPI_SMALL_FIXED_DMA_DESCRIPTOR_NAME                         0x0A
-#define ACPI_LARGE_GPIO_CONNECTION_DESCRIPTOR_NAME                   0x0C
-#define ACPI_LARGE_GENERIC_SERIAL_BUS_CONNECTION_DESCRIPTOR_NAME     0x0E
-
-#define ACPI_FIXED_DMA_DESCRIPTOR                         0x55
-#define ACPI_GPIO_CONNECTION_DESCRIPTOR                   0x8C
-#define ACPI_GENERIC_SERIAL_BUS_CONNECTION_DESCRIPTOR     0x8E
-
-#pragma pack(1)
-
-///
-/// Generic DMA Descriptor.
-///
-typedef PACKED struct {
-  ACPI_SMALL_RESOURCE_HEADER   Header;
-  UINT16                       DmaRequestLine;
-  UINT16                       DmaChannel;
-  UINT8                        DmaTransferWidth;
-} EFI_ACPI_FIXED_DMA_DESCRIPTOR;
-
-///
-/// GPIO Connection Descriptor
-///
-typedef PACKED struct {
-  ACPI_LARGE_RESOURCE_HEADER    Header;
-  UINT8                         RevisionId;
-  UINT8                         ConnectionType;
-  UINT16                        GeneralFlags;
-  UINT16                        InterruptFlags;
-  UINT8                         PinConfiguration;
-  UINT16                        OutputDriveStrength;
-  UINT16                        DebounceTimeout;
-  UINT16                        PinTableOffset;
-  UINT8                         ResourceSourceIndex;
-  UINT16                        ResourceSourceNameOffset;
-  UINT16                        VendorDataOffset;
-  UINT16                        VendorDataLength;
-} EFI_ACPI_GPIO_CONNECTION_DESCRIPTOR;
-
-#define EFI_ACPI_GPIO_CONNECTION_TYPE_INTERRUPT   0x0
-#define EFI_ACPI_GPIO_CONNECTION_TYPE_IO          0x1
-
-///
-/// Serial Bus Resource Descriptor (Generic)
-///
-typedef PACKED struct {
-  ACPI_LARGE_RESOURCE_HEADER    Header;
-  UINT8                         RevisionId;
-  UINT8                         ResourceSourceIndex;
-  UINT8                         SerialBusType;
-  UINT8                         GeneralFlags;
-  UINT16                        TypeSpecificFlags;
-  UINT8                         TypeSpecificRevisionId;
-  UINT16                        TypeDataLength;
-// Type specific data
-} EFI_ACPI_SERIAL_BUS_RESOURCE_DESCRIPTOR;
-
-#define EFI_ACPI_SERIAL_BUS_RESOURCE_TYPE_I2C   0x1
-#define EFI_ACPI_SERIAL_BUS_RESOURCE_TYPE_SPI   0x2
-#define EFI_ACPI_SERIAL_BUS_RESOURCE_TYPE_UART  0x3
-
-///
-/// Serial Bus Resource Descriptor (I2C)
-///
-typedef PACKED struct {
-  ACPI_LARGE_RESOURCE_HEADER    Header;
-  UINT8                         RevisionId;
-  UINT8                         ResourceSourceIndex;
-  UINT8                         SerialBusType;
-  UINT8                         GeneralFlags;
-  UINT16                        TypeSpecificFlags;
-  UINT8                         TypeSpecificRevisionId;
-  UINT16                        TypeDataLength;
-  UINT32                        ConnectionSpeed;
-  UINT16                        SlaveAddress;
-} EFI_ACPI_SERIAL_BUS_RESOURCE_I2C_DESCRIPTOR;
-
-///
-/// Serial Bus Resource Descriptor (SPI)
-///
-typedef PACKED struct {
-  ACPI_LARGE_RESOURCE_HEADER    Header;
-  UINT8                         RevisionId;
-  UINT8                         ResourceSourceIndex;
-  UINT8                         SerialBusType;
-  UINT8                         GeneralFlags;
-  UINT16                        TypeSpecificFlags;
-  UINT8                         TypeSpecificRevisionId;
-  UINT16                        TypeDataLength;
-  UINT32                        ConnectionSpeed;
-  UINT8                         DataBitLength;
-  UINT8                         Phase;
-  UINT8                         Polarity;
-  UINT16                        DeviceSelection;
-} EFI_ACPI_SERIAL_BUS_RESOURCE_SPI_DESCRIPTOR;
-
-///
-/// Serial Bus Resource Descriptor (UART)
-///
-typedef PACKED struct {
-  ACPI_LARGE_RESOURCE_HEADER    Header;
-  UINT8                         RevisionId;
-  UINT8                         ResourceSourceIndex;
-  UINT8                         SerialBusType;
-  UINT8                         GeneralFlags;
-  UINT16                        TypeSpecificFlags;
-  UINT8                         TypeSpecificRevisionId;
-  UINT16                        TypeDataLength;
-  UINT32                        DefaultBaudRate;
-  UINT16                        RxFIFO;
-  UINT16                        TxFIFO;
-  UINT8                         Parity;
-  UINT8                         SerialLinesEnabled;
-} EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR;
-
-#pragma pack()
-
-//
-// Ensure proper structure formats
-//
-#pragma pack(1)
-
-///
-/// ACPI 5.0 Generic Address Space definition
-///
-typedef struct {
-  UINT8   AddressSpaceId;
-  UINT8   RegisterBitWidth;
-  UINT8   RegisterBitOffset;
-  UINT8   AccessSize;
-  UINT64  Address;
-} EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE;
-
-//
-// Generic Address Space Address IDs
-//
-#define EFI_ACPI_5_0_SYSTEM_MEMORY              0
-#define EFI_ACPI_5_0_SYSTEM_IO                  1
-#define EFI_ACPI_5_0_PCI_CONFIGURATION_SPACE    2
-#define EFI_ACPI_5_0_EMBEDDED_CONTROLLER        3
-#define EFI_ACPI_5_0_SMBUS                      4
-#define EFI_ACPI_5_0_PLATFORM_COMMUNICATION_CHANNEL  0x0A
-#define EFI_ACPI_5_0_FUNCTIONAL_FIXED_HARDWARE       0x7F
-
-//
-// Generic Address Space Access Sizes
-//
-#define EFI_ACPI_5_0_UNDEFINED  0
-#define EFI_ACPI_5_0_BYTE       1
-#define EFI_ACPI_5_0_WORD       2
-#define EFI_ACPI_5_0_DWORD      3
-#define EFI_ACPI_5_0_QWORD      4
-
-//
-// ACPI 5.0 table structures
-//
-
-///
-/// Root System Description Pointer Structure
-///
-typedef struct {
-  UINT64  Signature;
-  UINT8   Checksum;
-  UINT8   OemId[6];
-  UINT8   Revision;
-  UINT32  RsdtAddress;
-  UINT32  Length;
-  UINT64  XsdtAddress;
-  UINT8   ExtendedChecksum;
-  UINT8   Reserved[3];
-} EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
-
-///
-/// RSD_PTR Revision (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02  ///< ACPISpec (Revision 5.0) says current value is 2
-
-///
-/// Common table header, this prefaces all ACPI tables, including FACS, but
-/// excluding the RSD PTR structure
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-} EFI_ACPI_5_0_COMMON_HEADER;
-
-//
-// Root System Description Table
-// No definition needed as it is a common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers.
-//
-
-///
-/// RSDT Revision (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
-
-//
-// Extended System Description Table
-// No definition needed as it is a common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers.
-//
-
-///
-/// XSDT Revision (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Fixed ACPI Description Table Structure (FADT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER             Header;
-  UINT32                                  FirmwareCtrl;
-  UINT32                                  Dsdt;
-  UINT8                                   Reserved0;
-  UINT8                                   PreferredPmProfile;
-  UINT16                                  SciInt;
-  UINT32                                  SmiCmd;
-  UINT8                                   AcpiEnable;
-  UINT8                                   AcpiDisable;
-  UINT8                                   S4BiosReq;
-  UINT8                                   PstateCnt;
-  UINT32                                  Pm1aEvtBlk;
-  UINT32                                  Pm1bEvtBlk;
-  UINT32                                  Pm1aCntBlk;
-  UINT32                                  Pm1bCntBlk;
-  UINT32                                  Pm2CntBlk;
-  UINT32                                  PmTmrBlk;
-  UINT32                                  Gpe0Blk;
-  UINT32                                  Gpe1Blk;
-  UINT8                                   Pm1EvtLen;
-  UINT8                                   Pm1CntLen;
-  UINT8                                   Pm2CntLen;
-  UINT8                                   PmTmrLen;
-  UINT8                                   Gpe0BlkLen;
-  UINT8                                   Gpe1BlkLen;
-  UINT8                                   Gpe1Base;
-  UINT8                                   CstCnt;
-  UINT16                                  PLvl2Lat;
-  UINT16                                  PLvl3Lat;
-  UINT16                                  FlushSize;
-  UINT16                                  FlushStride;
-  UINT8                                   DutyOffset;
-  UINT8                                   DutyWidth;
-  UINT8                                   DayAlrm;
-  UINT8                                   MonAlrm;
-  UINT8                                   Century;
-  UINT16                                  IaPcBootArch;
-  UINT8                                   Reserved1;
-  UINT32                                  Flags;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE  ResetReg;
-  UINT8                                   ResetValue;
-  UINT8                                   Reserved2[3];
-  UINT64                                  XFirmwareCtrl;
-  UINT64                                  XDsdt;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE  XPm1aEvtBlk;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE  XPm1bEvtBlk;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE  XPm1aCntBlk;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE  XPm1bCntBlk;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE  XPm2CntBlk;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE  XPmTmrBlk;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE  XGpe0Blk;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE  XGpe1Blk;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE  SleepControlReg;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE  SleepStatusReg;
-} EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE;
-
-///
-/// FADT Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION  0x05
-
-//
-// Fixed ACPI Description Table Preferred Power Management Profile
-//
-#define EFI_ACPI_5_0_PM_PROFILE_UNSPECIFIED         0
-#define EFI_ACPI_5_0_PM_PROFILE_DESKTOP             1
-#define EFI_ACPI_5_0_PM_PROFILE_MOBILE              2
-#define EFI_ACPI_5_0_PM_PROFILE_WORKSTATION         3
-#define EFI_ACPI_5_0_PM_PROFILE_ENTERPRISE_SERVER   4
-#define EFI_ACPI_5_0_PM_PROFILE_SOHO_SERVER         5
-#define EFI_ACPI_5_0_PM_PROFILE_APPLIANCE_PC        6
-#define EFI_ACPI_5_0_PM_PROFILE_PERFORMANCE_SERVER  7
-#define EFI_ACPI_5_0_PM_PROFILE_TABLET              8
-
-//
-// Fixed ACPI Description Table Boot Architecture Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_5_0_LEGACY_DEVICES              BIT0
-#define EFI_ACPI_5_0_8042                        BIT1
-#define EFI_ACPI_5_0_VGA_NOT_PRESENT             BIT2
-#define EFI_ACPI_5_0_MSI_NOT_SUPPORTED           BIT3
-#define EFI_ACPI_5_0_PCIE_ASPM_CONTROLS          BIT4
-#define EFI_ACPI_5_0_CMOS_RTC_NOT_PRESENT        BIT5
-
-//
-// Fixed ACPI Description Table Fixed Feature Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_5_0_WBINVD                                 BIT0
-#define EFI_ACPI_5_0_WBINVD_FLUSH                           BIT1
-#define EFI_ACPI_5_0_PROC_C1                                BIT2
-#define EFI_ACPI_5_0_P_LVL2_UP                              BIT3
-#define EFI_ACPI_5_0_PWR_BUTTON                             BIT4
-#define EFI_ACPI_5_0_SLP_BUTTON                             BIT5
-#define EFI_ACPI_5_0_FIX_RTC                                BIT6
-#define EFI_ACPI_5_0_RTC_S4                                 BIT7
-#define EFI_ACPI_5_0_TMR_VAL_EXT                            BIT8
-#define EFI_ACPI_5_0_DCK_CAP                                BIT9
-#define EFI_ACPI_5_0_RESET_REG_SUP                          BIT10
-#define EFI_ACPI_5_0_SEALED_CASE                            BIT11
-#define EFI_ACPI_5_0_HEADLESS                               BIT12
-#define EFI_ACPI_5_0_CPU_SW_SLP                             BIT13
-#define EFI_ACPI_5_0_PCI_EXP_WAK                            BIT14
-#define EFI_ACPI_5_0_USE_PLATFORM_CLOCK                     BIT15
-#define EFI_ACPI_5_0_S4_RTC_STS_VALID                       BIT16
-#define EFI_ACPI_5_0_REMOTE_POWER_ON_CAPABLE                BIT17
-#define EFI_ACPI_5_0_FORCE_APIC_CLUSTER_MODEL               BIT18
-#define EFI_ACPI_5_0_FORCE_APIC_PHYSICAL_DESTINATION_MODE   BIT19
-#define EFI_ACPI_5_0_HW_REDUCED_ACPI                        BIT20
-#define EFI_ACPI_5_0_LOW_POWER_S0_IDLE_CAPABLE              BIT21
-
-///
-/// Firmware ACPI Control Structure
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-  UINT32  HardwareSignature;
-  UINT32  FirmwareWakingVector;
-  UINT32  GlobalLock;
-  UINT32  Flags;
-  UINT64  XFirmwareWakingVector;
-  UINT8   Version;
-  UINT8   Reserved0[3];
-  UINT32  OspmFlags;
-  UINT8   Reserved1[24];
-} EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
-
-///
-/// FACS Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION  0x02
-
-///
-/// Firmware Control Structure Feature Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_5_0_S4BIOS_F                     BIT0
-#define EFI_ACPI_5_0_64BIT_WAKE_SUPPORTED_F       BIT1
-
-///
-/// OSPM Enabled Firmware Control Structure Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_5_0_OSPM_64BIT_WAKE_F            BIT0
-
-//
-// Differentiated System Description Table,
-// Secondary System Description Table
-// and Persistent System Description Table,
-// no definition needed as they are common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block.
-//
-#define EFI_ACPI_5_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION   0x02
-#define EFI_ACPI_5_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION        0x02
-
-///
-/// Multiple APIC Description Table header definition.  The rest of the table
-/// must be defined in a platform specific manner.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      LocalApicAddress;
-  UINT32                      Flags;
-} EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER;
-
-///
-/// MADT Revision (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x03
-
-///
-/// Multiple APIC Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_5_0_PCAT_COMPAT         BIT0
-
-//
-// Multiple APIC Description Table APIC structure types
-// All other values between 0x0D and 0x7F are reserved and
-// will be ignored by OSPM. 0x80 ~ 0xFF are reserved for OEM.
-//
-#define EFI_ACPI_5_0_PROCESSOR_LOCAL_APIC           0x00
-#define EFI_ACPI_5_0_IO_APIC                        0x01
-#define EFI_ACPI_5_0_INTERRUPT_SOURCE_OVERRIDE      0x02
-#define EFI_ACPI_5_0_NON_MASKABLE_INTERRUPT_SOURCE  0x03
-#define EFI_ACPI_5_0_LOCAL_APIC_NMI                 0x04
-#define EFI_ACPI_5_0_LOCAL_APIC_ADDRESS_OVERRIDE    0x05
-#define EFI_ACPI_5_0_IO_SAPIC                       0x06
-#define EFI_ACPI_5_0_LOCAL_SAPIC                    0x07
-#define EFI_ACPI_5_0_PLATFORM_INTERRUPT_SOURCES     0x08
-#define EFI_ACPI_5_0_PROCESSOR_LOCAL_X2APIC         0x09
-#define EFI_ACPI_5_0_LOCAL_X2APIC_NMI               0x0A
-#define EFI_ACPI_5_0_GIC                            0x0B
-#define EFI_ACPI_5_0_GICD                           0x0C
-
-//
-// APIC Structure Definitions
-//
-
-///
-/// Processor Local APIC Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT8   ApicId;
-  UINT32  Flags;
-} EFI_ACPI_5_0_PROCESSOR_LOCAL_APIC_STRUCTURE;
-
-///
-/// Local APIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_0_LOCAL_APIC_ENABLED        BIT0
-
-///
-/// IO APIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   IoApicId;
-  UINT8   Reserved;
-  UINT32  IoApicAddress;
-  UINT32  GlobalSystemInterruptBase;
-} EFI_ACPI_5_0_IO_APIC_STRUCTURE;
-
-///
-/// Interrupt Source Override Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Bus;
-  UINT8   Source;
-  UINT32  GlobalSystemInterrupt;
-  UINT16  Flags;
-} EFI_ACPI_5_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE;
-
-///
-/// Platform Interrupt Sources Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT8   InterruptType;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT8   IoSapicVector;
-  UINT32  GlobalSystemInterrupt;
-  UINT32  PlatformInterruptSourceFlags;
-  UINT8   CpeiProcessorOverride;
-  UINT8   Reserved[31];
-} EFI_ACPI_5_0_PLATFORM_INTERRUPT_APIC_STRUCTURE;
-
-//
-// MPS INTI flags.
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_5_0_POLARITY      (3 << 0)
-#define EFI_ACPI_5_0_TRIGGER_MODE  (3 << 2)
-
-///
-/// Non-Maskable Interrupt Source Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT32  GlobalSystemInterrupt;
-} EFI_ACPI_5_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE;
-
-///
-/// Local APIC NMI Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT16  Flags;
-  UINT8   LocalApicLint;
-} EFI_ACPI_5_0_LOCAL_APIC_NMI_STRUCTURE;
-
-///
-/// Local APIC Address Override Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved;
-  UINT64  LocalApicAddress;
-} EFI_ACPI_5_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
-
-///
-/// IO SAPIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   IoApicId;
-  UINT8   Reserved;
-  UINT32  GlobalSystemInterruptBase;
-  UINT64  IoSapicAddress;
-} EFI_ACPI_5_0_IO_SAPIC_STRUCTURE;
-
-///
-/// Local SAPIC Structure
-/// This struct followed by a null-terminated ASCII string - ACPI Processor UID String
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT8   LocalSapicId;
-  UINT8   LocalSapicEid;
-  UINT8   Reserved[3];
-  UINT32  Flags;
-  UINT32  ACPIProcessorUIDValue;
-} EFI_ACPI_5_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
-
-///
-/// Platform Interrupt Sources Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT8   InterruptType;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT8   IoSapicVector;
-  UINT32  GlobalSystemInterrupt;
-  UINT32  PlatformInterruptSourceFlags;
-} EFI_ACPI_5_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE;
-
-///
-/// Platform Interrupt Source Flags.
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_5_0_CPEI_PROCESSOR_OVERRIDE          BIT0
-
-///
-/// Processor Local x2APIC Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Reserved[2];
-  UINT32  X2ApicId;
-  UINT32  Flags;
-  UINT32  AcpiProcessorUid;
-} EFI_ACPI_5_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE;
-
-///
-/// Local x2APIC NMI Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT32  AcpiProcessorUid;
-  UINT8   LocalX2ApicLint;
-  UINT8   Reserved[3];
-} EFI_ACPI_5_0_LOCAL_X2APIC_NMI_STRUCTURE;
-
-///
-/// GIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved;
-  UINT32  GicId;
-  UINT32  AcpiProcessorUid;
-  UINT32  Flags;
-  UINT32  ParkingProtocolVersion;
-  UINT32  PerformanceInterruptGsiv;
-  UINT64  ParkedAddress;
-  UINT64  PhysicalBaseAddress;
-} EFI_ACPI_5_0_GIC_STRUCTURE;
-
-///
-/// GIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_0_GIC_ENABLED                     BIT0
-#define EFI_ACPI_5_0_PERFORMANCE_INTERRUPT_MODEL     BIT1
-
-///
-/// GIC Distributor Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved1;
-  UINT32  GicId;
-  UINT64  PhysicalBaseAddress;
-  UINT32  SystemVectorBase;
-  UINT32  Reserved2;
-} EFI_ACPI_5_0_GIC_DISTRIBUTOR_STRUCTURE;
-
-///
-/// Smart Battery Description Table (SBST)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      WarningEnergyLevel;
-  UINT32                      LowEnergyLevel;
-  UINT32                      CriticalEnergyLevel;
-} EFI_ACPI_5_0_SMART_BATTERY_DESCRIPTION_TABLE;
-
-///
-/// SBST Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Embedded Controller Boot Resources Table (ECDT)
-/// The table is followed by a null terminated ASCII string that contains
-/// a fully qualified reference to the name space object.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER             Header;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE  EcControl;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE  EcData;
-  UINT32                                  Uid;
-  UINT8                                   GpeBit;
-} EFI_ACPI_5_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE;
-
-///
-/// ECDT Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION  0x01
-
-///
-/// System Resource Affinity Table (SRAT).  The rest of the table
-/// must be defined in a platform specific manner.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      Reserved1;  ///< Must be set to 1
-  UINT64                      Reserved2;
-} EFI_ACPI_5_0_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER;
-
-///
-/// SRAT Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION  0x03
-
-//
-// SRAT structure types.
-// All other values between 0x03 an 0xFF are reserved and
-// will be ignored by OSPM.
-//
-#define EFI_ACPI_5_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY  0x00
-#define EFI_ACPI_5_0_MEMORY_AFFINITY                      0x01
-#define EFI_ACPI_5_0_PROCESSOR_LOCAL_X2APIC_AFFINITY      0x02
-
-///
-/// Processor Local APIC/SAPIC Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   ProximityDomain7To0;
-  UINT8   ApicId;
-  UINT32  Flags;
-  UINT8   LocalSapicEid;
-  UINT8   ProximityDomain31To8[3];
-  UINT32  ClockDomain;
-} EFI_ACPI_5_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE;
-
-///
-/// Local APIC/SAPIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_0_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0)
-
-///
-/// Memory Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT32  ProximityDomain;
-  UINT16  Reserved1;
-  UINT32  AddressBaseLow;
-  UINT32  AddressBaseHigh;
-  UINT32  LengthLow;
-  UINT32  LengthHigh;
-  UINT32  Reserved2;
-  UINT32  Flags;
-  UINT64  Reserved3;
-} EFI_ACPI_5_0_MEMORY_AFFINITY_STRUCTURE;
-
-//
-// Memory Flags.  All other bits are reserved and must be 0.
-//
-#define EFI_ACPI_5_0_MEMORY_ENABLED       (1 << 0)
-#define EFI_ACPI_5_0_MEMORY_HOT_PLUGGABLE (1 << 1)
-#define EFI_ACPI_5_0_MEMORY_NONVOLATILE   (1 << 2)
-
-///
-/// Processor Local x2APIC Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Reserved1[2];
-  UINT32  ProximityDomain;
-  UINT32  X2ApicId;
-  UINT32  Flags;
-  UINT32  ClockDomain;
-  UINT8   Reserved2[4];
-} EFI_ACPI_5_0_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE;
-
-///
-/// System Locality Distance Information Table (SLIT).
-/// The rest of the table is a matrix.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT64                      NumberOfSystemLocalities;
-} EFI_ACPI_5_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER;
-
-///
-/// SLIT Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION  0x01
-
-///
-/// Corrected Platform Error Polling Table (CPEP)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT8                       Reserved[8];
-} EFI_ACPI_5_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER;
-
-///
-/// CPEP Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_REVISION 0x01
-
-//
-// CPEP processor structure types.
-//
-#define EFI_ACPI_5_0_CPEP_PROCESSOR_APIC_SAPIC  0x00
-
-///
-/// Corrected Platform Error Polling Processor Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT32  PollingInterval;
-} EFI_ACPI_5_0_CPEP_PROCESSOR_APIC_SAPIC_STRUCTURE;
-
-///
-/// Maximum System Characteristics Table (MSCT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      OffsetProxDomInfo;
-  UINT32                      MaximumNumberOfProximityDomains;
-  UINT32                      MaximumNumberOfClockDomains;
-  UINT64                      MaximumPhysicalAddress;
-} EFI_ACPI_5_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_HEADER;
-
-///
-/// MSCT Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_REVISION 0x01
-
-///
-/// Maximum Proximity Domain Information Structure Definition
-///
-typedef struct {
-  UINT8   Revision;
-  UINT8   Length;
-  UINT32  ProximityDomainRangeLow;
-  UINT32  ProximityDomainRangeHigh;
-  UINT32  MaximumProcessorCapacity;
-  UINT64  MaximumMemoryCapacity;
-} EFI_ACPI_5_0_MAXIMUM_PROXIMITY_DOMAIN_INFORMATION_STRUCTURE;
-
-///
-/// ACPI RAS Feature Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT8                       PlatformCommunicationChannelIdentifier[12];
-} EFI_ACPI_5_0_RAS_FEATURE_TABLE;
-
-///
-/// RASF Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_RAS_FEATURE_TABLE_REVISION 0x01
-
-///
-/// ACPI RASF Platform Communication Channel Shared Memory Region definition.
-///
-typedef struct {
-  UINT32                      Signature;
-  UINT16                      Command;
-  UINT16                      Status;
-  UINT16                      Version;
-  UINT8                       RASCapabilities[16];
-  UINT8                       SetRASCapabilities[16];
-  UINT16                      NumberOfRASFParameterBlocks;
-  UINT32                      SetRASCapabilitiesStatus;
-} EFI_ACPI_5_0_RASF_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION;
-
-///
-/// ACPI RASF PCC command code
-///
-#define EFI_ACPI_5_0_RASF_PCC_COMMAND_CODE_EXECUTE_RASF_COMMAND  0x01
-
-///
-/// ACPI RASF Platform RAS Capabilities
-///
-#define EFI_ACPI_5_0_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED                          0x01
-#define EFI_ACPI_5_0_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED_AND_EXPOSED_TO_SOFTWARE  0x02
-
-///
-/// ACPI RASF Parameter Block structure for PATROL_SCRUB
-///
-typedef struct {
-  UINT16                      Type;
-  UINT16                      Version;
-  UINT16                      Length;
-  UINT16                      PatrolScrubCommand;
-  UINT64                      RequestedAddressRange[2];
-  UINT64                      ActualAddressRange[2];
-  UINT16                      Flags;
-  UINT8                       RequestedSpeed;
-} EFI_ACPI_5_0_RASF_PATROL_SCRUB_PLATFORM_BLOCK_STRUCTURE;
-
-///
-/// ACPI RASF Patrol Scrub command
-///
-#define EFI_ACPI_5_0_RASF_PATROL_SCRUB_COMMAND_GET_PATROL_PARAMETERS   0x01
-#define EFI_ACPI_5_0_RASF_PATROL_SCRUB_COMMAND_START_PATROL_SCRUBBER   0x02
-#define EFI_ACPI_5_0_RASF_PATROL_SCRUB_COMMAND_STOP_PATROL_SCRUBBER    0x03
-
-///
-/// Memory Power State Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT8                       PlatformCommunicationChannelIdentifier;
-  UINT8                       Reserved[3];
-// Memory Power Node Structure
-// Memory Power State Characteristics
-} EFI_ACPI_5_0_MEMORY_POWER_STATUS_TABLE;
-
-///
-/// MPST Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_MEMORY_POWER_STATE_TABLE_REVISION 0x01
-
-///
-/// MPST Platform Communication Channel Shared Memory Region definition.
-///
-typedef struct {
-  UINT32                      Signature;
-  UINT16                      Command;
-  UINT16                      Status;
-  UINT32                      MemoryPowerCommandRegister;
-  UINT32                      MemoryPowerStatusRegister;
-  UINT32                      PowerStateId;
-  UINT32                      MemoryPowerNodeId;
-  UINT64                      MemoryEnergyConsumed;
-  UINT64                      ExpectedAveragePowerComsuned;
-} EFI_ACPI_5_0_MPST_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION;
-
-///
-/// ACPI MPST PCC command code
-///
-#define EFI_ACPI_5_0_MPST_PCC_COMMAND_CODE_EXECUTE_MPST_COMMAND  0x03
-
-///
-/// ACPI MPST Memory Power command
-///
-#define EFI_ACPI_5_0_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_POWER_STATE       0x01
-#define EFI_ACPI_5_0_MPST_MEMORY_POWER_COMMAND_SET_MEMORY_POWER_STATE       0x02
-#define EFI_ACPI_5_0_MPST_MEMORY_POWER_COMMAND_GET_AVERAGE_POWER_CONSUMED   0x03
-#define EFI_ACPI_5_0_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_ENERGY_CONSUMED   0x04
-
-///
-/// MPST Memory Power Node Table
-///
-typedef struct {
-  UINT8                                             PowerStateValue;
-  UINT8                                             PowerStateInformationIndex;
-} EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE;
-
-typedef struct {
-  UINT8                                             Flag;
-  UINT8                                             Reserved;
-  UINT16                                            MemoryPowerNodeId;
-  UINT32                                            Length;
-  UINT64                                            AddressBase;
-  UINT64                                            AddressLength;
-  UINT32                                            NumberOfPowerStates;
-  UINT32                                            NumberOfPhysicalComponents;
-//EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE              MemoryPowerState[NumberOfPowerStates];
-//UINT16                                            PhysicalComponentIdentifier[NumberOfPhysicalComponents];
-} EFI_ACPI_5_0_MPST_MEMORY_POWER_STRUCTURE;
-
-#define EFI_ACPI_5_0_MPST_MEMORY_POWER_STRUCTURE_FLAG_ENABLE          0x01
-#define EFI_ACPI_5_0_MPST_MEMORY_POWER_STRUCTURE_FLAG_POWER_MANAGED   0x02
-#define EFI_ACPI_5_0_MPST_MEMORY_POWER_STRUCTURE_FLAG_HOT_PLUGGABLE   0x04
-
-typedef struct {
-  UINT16                      MemoryPowerNodeCount;
-  UINT8                       Reserved[2];
-} EFI_ACPI_5_0_MPST_MEMORY_POWER_NODE_TABLE;
-
-///
-/// MPST Memory Power State Characteristics Table
-///
-typedef struct {
-  UINT8                                             PowerStateStructureID;
-  UINT8                                             Flag;
-  UINT16                                            Reserved;
-  UINT32                                            AveragePowerConsumedInMPS0;
-  UINT32                                            RelativePowerSavingToMPS0;
-  UINT64                                            ExitLatencyToMPS0;
-} EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE;
-
-#define EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_MEMORY_CONTENT_PRESERVED              0x01
-#define EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_ENTRY   0x02
-#define EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_EXIT    0x04
-
-typedef struct {
-  UINT16                      MemoryPowerStateCharacteristicsCount;
-  UINT8                       Reserved[2];
-} EFI_ACPI_5_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE;
-
-///
-/// Memory Topology Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      Reserved;
-} EFI_ACPI_5_0_MEMORY_TOPOLOGY_TABLE;
-
-///
-/// PMTT Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_MEMORY_TOPOLOGY_TABLE_REVISION 0x01
-
-///
-/// Common Memory Aggregator Device Structure.
-///
-typedef struct {
-  UINT8                       Type;
-  UINT8                       Reserved;
-  UINT16                      Length;
-  UINT16                      Flags;
-  UINT16                      Reserved1;
-} EFI_ACPI_5_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
-
-///
-/// Memory Aggregator Device Type
-///
-#define EFI_ACPI_5_0_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_SOCKET            0x1
-#define EFI_ACPI_5_0_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_MEMORY_CONTROLLER 0x2
-#define EFI_ACPI_5_0_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_DIMM              0x3
-
-///
-/// Socket Memory Aggregator Device Structure.
-///
-typedef struct {
-  EFI_ACPI_5_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE  Header;
-  UINT16                                                       SocketIdentifier;
-  UINT16                                                       Reserved;
-//EFI_ACPI_5_0_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE  MemoryController[];
-} EFI_ACPI_5_0_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
-
-///
-/// MemoryController Memory Aggregator Device Structure.
-///
-typedef struct {
-  EFI_ACPI_5_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE  Header;
-  UINT32                                                       ReadLatency;
-  UINT32                                                       WriteLatency;
-  UINT32                                                       ReadBandwidth;
-  UINT32                                                       WriteBandwidth;
-  UINT16                                                       OptimalAccessUnit;
-  UINT16                                                       OptimalAccessAlignment;
-  UINT16                                                       Reserved;
-  UINT16                                                       NumberOfProximityDomains;
-//UINT32                                                       ProximityDomain[NumberOfProximityDomains];
-//EFI_ACPI_5_0_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE    PhysicalComponent[];
-} EFI_ACPI_5_0_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
-
-///
-/// DIMM Memory Aggregator Device Structure.
-///
-typedef struct {
-  EFI_ACPI_5_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE  Header;
-  UINT16                                                       PhysicalComponentIdentifier;
-  UINT16                                                       Reserved;
-  UINT32                                                       SizeOfDimm;
-  UINT32                                                       SmbiosHandle;
-} EFI_ACPI_5_0_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
-
-///
-/// Boot Graphics Resource Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  ///
-  /// 2-bytes (16 bit) version ID. This value must be 1.
-  ///
-  UINT16                      Version;
-  ///
-  /// 1-byte status field indicating current status about the table.
-  ///     Bits[7:1] = Reserved (must be zero)
-  ///     Bit [0] = Valid. A one indicates the boot image graphic is valid.
-  ///
-  UINT8                       Status;
-  ///
-  /// 1-byte enumerated type field indicating format of the image.
-  ///     0 = Bitmap
-  ///     1 - 255  Reserved (for future use)
-  ///
-  UINT8                       ImageType;
-  ///
-  /// 8-byte (64 bit) physical address pointing to the firmware's in-memory copy
-  /// of the image bitmap.
-  ///
-  UINT64                      ImageAddress;
-  ///
-  /// A 4-byte (32-bit) unsigned long describing the display X-offset of the boot image.
-  /// (X, Y) display offset of the top left corner of the boot image.
-  /// The top left corner of the display is at offset (0, 0).
-  ///
-  UINT32                      ImageOffsetX;
-  ///
-  /// A 4-byte (32-bit) unsigned long describing the display Y-offset of the boot image.
-  /// (X, Y) display offset of the top left corner of the boot image.
-  /// The top left corner of the display is at offset (0, 0).
-  ///
-  UINT32                      ImageOffsetY;
-} EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE;
-
-///
-/// BGRT Revision
-///
-#define EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION 1
-
-///
-/// BGRT Version
-///
-#define EFI_ACPI_5_0_BGRT_VERSION         0x01
-
-///
-/// BGRT Status
-///
-#define EFI_ACPI_5_0_BGRT_STATUS_NOT_DISPLAYED 0x00
-#define EFI_ACPI_5_0_BGRT_STATUS_DISPLAYED     0x01
-#define EFI_ACPI_5_0_BGRT_STATUS_INVALID       EFI_ACPI_5_0_BGRT_STATUS_NOT_DISPLAYED
-#define EFI_ACPI_5_0_BGRT_STATUS_VALID         EFI_ACPI_5_0_BGRT_STATUS_DISPLAYED
-
-///
-/// BGRT Image Type
-///
-#define EFI_ACPI_5_0_BGRT_IMAGE_TYPE_BMP  0x00
-
-///
-/// FPDT Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION 0x01
-
-///
-/// FPDT Performance Record Types
-///
-#define EFI_ACPI_5_0_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER      0x0000
-#define EFI_ACPI_5_0_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER     0x0001
-
-///
-/// FPDT Performance Record Revision
-///
-#define EFI_ACPI_5_0_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER  0x01
-#define EFI_ACPI_5_0_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER 0x01
-
-///
-/// FPDT Runtime Performance Record Types
-///
-#define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME                0x0000
-#define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND               0x0001
-#define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT      0x0002
-
-///
-/// FPDT Runtime Performance Record Revision
-///
-#define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME            0x01
-#define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND           0x01
-#define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT  0x02
-
-///
-/// FPDT Performance Record header
-///
-typedef struct {
-  UINT16           Type;
-  UINT8            Length;
-  UINT8            Revision;
-} EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER;
-
-///
-/// FPDT Performance Table header
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-} EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER;
-
-///
-/// FPDT Firmware Basic Boot Performance Pointer Record Structure
-///
-typedef struct {
-  EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  UINT32                                          Reserved;
-  ///
-  /// 64-bit processor-relative physical address of the Basic Boot Performance Table.
-  ///
-  UINT64                                          BootPerformanceTablePointer;
-} EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD;
-
-///
-/// FPDT S3 Performance Table Pointer Record Structure
-///
-typedef struct {
-  EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  UINT32                                          Reserved;
-  ///
-  /// 64-bit processor-relative physical address of the S3 Performance Table.
-  ///
-  UINT64                                          S3PerformanceTablePointer;
-} EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD;
-
-///
-/// FPDT Firmware Basic Boot Performance Record Structure
-///
-typedef struct {
-  EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  UINT32                                          Reserved;
-  ///
-  /// Timer value logged at the beginning of firmware image execution.
-  /// This may not always be zero or near zero.
-  ///
-  UINT64                                          ResetEnd;
-  ///
-  /// Timer value logged just prior to loading the OS boot loader into memory.
-  /// For non-UEFI compatible boots, this field must be zero.
-  ///
-  UINT64                                          OsLoaderLoadImageStart;
-  ///
-  /// Timer value logged just prior to launching the previously loaded OS boot loader image.
-  /// For non-UEFI compatible boots, the timer value logged will be just prior
-  /// to the INT 19h handler invocation.
-  ///
-  UINT64                                          OsLoaderStartImageStart;
-  ///
-  /// Timer value logged at the point when the OS loader calls the
-  /// ExitBootServices function for UEFI compatible firmware.
-  /// For non-UEFI compatible boots, this field must be zero.
-  ///
-  UINT64                                          ExitBootServicesEntry;
-  ///
-  /// Timer value logged at the point just prior towhen the OS loader gaining
-  /// control back from calls the ExitBootServices function for UEFI compatible firmware.
-  /// For non-UEFI compatible boots, this field must be zero.
-  ///
-  UINT64                                          ExitBootServicesExit;
-} EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD;
-
-///
-/// FPDT Firmware Basic Boot Performance Table signature
-///
-#define EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE  SIGNATURE_32('F', 'B', 'P', 'T')
-
-//
-// FPDT Firmware Basic Boot Performance Table
-//
-typedef struct {
-  EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER      Header;
-  //
-  // one or more Performance Records.
-  //
-} EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_TABLE;
-
-///
-/// FPDT "S3PT" S3 Performance Table
-///
-#define EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE  SIGNATURE_32('S', '3', 'P', 'T')
-
-//
-// FPDT Firmware S3 Boot Performance Table
-//
-typedef struct {
-  EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER      Header;
-  //
-  // one or more Performance Records.
-  //
-} EFI_ACPI_5_0_FPDT_FIRMWARE_S3_BOOT_TABLE;
-
-///
-/// FPDT Basic S3 Resume Performance Record
-///
-typedef struct {
-  EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  ///
-  /// A count of the number of S3 resume cycles since the last full boot sequence.
-  ///
-  UINT32                                          ResumeCount;
-  ///
-  /// Timer recorded at the end of BIOS S3 resume, just prior to handoff to the
-  /// OS waking vector. Only the most recent resume cycle's time is retained.
-  ///
-  UINT64                                          FullResume;
-  ///
-  /// Average timer value of all resume cycles logged since the last full boot
-  /// sequence, including the most recent resume.  Note that the entire log of
-  /// timer values does not need to be retained in order to calculate this average.
-  ///
-  UINT64                                          AverageResume;
-} EFI_ACPI_5_0_FPDT_S3_RESUME_RECORD;
-
-///
-/// FPDT Basic S3 Suspend Performance Record
-///
-typedef struct {
-  EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  ///
-  /// Timer value recorded at the OS write to SLP_TYP upon entry to S3.
-  /// Only the most recent suspend cycle's timer value is retained.
-  ///
-  UINT64                                          SuspendStart;
-  ///
-  /// Timer value recorded at the final firmware write to SLP_TYP (or other
-  /// mechanism) used to trigger hardware entry to S3.
-  /// Only the most recent suspend cycle's timer value is retained.
-  ///
-  UINT64                                          SuspendEnd;
-} EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD;
-
-///
-/// Firmware Performance Record Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-} EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_RECORD_TABLE;
-
-///
-/// Generic Timer Description Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT64                      PhysicalAddress;
-  UINT32                      GlobalFlags;
-  UINT32                      SecurePL1TimerGSIV;
-  UINT32                      SecurePL1TimerFlags;
-  UINT32                      NonSecurePL1TimerGSIV;
-  UINT32                      NonSecurePL1TimerFlags;
-  UINT32                      VirtualTimerGSIV;
-  UINT32                      VirtualTimerFlags;
-  UINT32                      NonSecurePL2TimerGSIV;
-  UINT32                      NonSecurePL2TimerFlags;
-} EFI_ACPI_5_0_GENERIC_TIMER_DESCRIPTION_TABLE;
-
-///
-/// GTDT Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Global Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_0_GTDT_GLOBAL_FLAG_MEMORY_MAPPED_BLOCK_PRESENT   BIT0
-#define EFI_ACPI_5_0_GTDT_GLOBAL_FLAG_INTERRUPT_MODE                BIT1
-
-///
-/// Timer Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_0_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE          BIT0
-#define EFI_ACPI_5_0_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY      BIT1
-
-///
-/// Boot Error Record Table (BERT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      BootErrorRegionLength;
-  UINT64                      BootErrorRegion;
-} EFI_ACPI_5_0_BOOT_ERROR_RECORD_TABLE_HEADER;
-
-///
-/// BERT Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_BOOT_ERROR_RECORD_TABLE_REVISION 0x01
-
-///
-/// Boot Error Region Block Status Definition
-///
-typedef struct {
-  UINT32       UncorrectableErrorValid:1;
-  UINT32       CorrectableErrorValid:1;
-  UINT32       MultipleUncorrectableErrors:1;
-  UINT32       MultipleCorrectableErrors:1;
-  UINT32       ErrorDataEntryCount:10;
-  UINT32       Reserved:18;
-} EFI_ACPI_5_0_ERROR_BLOCK_STATUS;
-
-///
-/// Boot Error Region Definition
-///
-typedef struct {
-  EFI_ACPI_5_0_ERROR_BLOCK_STATUS              BlockStatus;
-  UINT32                                       RawDataOffset;
-  UINT32                                       RawDataLength;
-  UINT32                                       DataLength;
-  UINT32                                       ErrorSeverity;
-} EFI_ACPI_5_0_BOOT_ERROR_REGION_STRUCTURE;
-
-//
-// Boot Error Severity types
-//
-#define EFI_ACPI_5_0_ERROR_SEVERITY_CORRECTABLE  0x00
-#define EFI_ACPI_5_0_ERROR_SEVERITY_FATAL        0x01
-#define EFI_ACPI_5_0_ERROR_SEVERITY_CORRECTED    0x02
-#define EFI_ACPI_5_0_ERROR_SEVERITY_NONE         0x03
-
-///
-/// Generic Error Data Entry Definition
-///
-typedef struct {
-  UINT8    SectionType[16];
-  UINT32   ErrorSeverity;
-  UINT16   Revision;
-  UINT8    ValidationBits;
-  UINT8    Flags;
-  UINT32   ErrorDataLength;
-  UINT8    FruId[16];
-  UINT8    FruText[20];
-} EFI_ACPI_5_0_GENERIC_ERROR_DATA_ENTRY_STRUCTURE;
-
-///
-/// Generic Error Data Entry Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_GENERIC_ERROR_DATA_ENTRY_REVISION  0x0201
-
-///
-/// HEST - Hardware Error Source Table
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      ErrorSourceCount;
-} EFI_ACPI_5_0_HARDWARE_ERROR_SOURCE_TABLE_HEADER;
-
-///
-/// HEST Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01
-
-//
-// Error Source structure types.
-//
-#define EFI_ACPI_5_0_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION  0x00
-#define EFI_ACPI_5_0_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK  0x01
-#define EFI_ACPI_5_0_IA32_ARCHITECTURE_NMI_ERROR                0x02
-#define EFI_ACPI_5_0_PCI_EXPRESS_ROOT_PORT_AER                  0x06
-#define EFI_ACPI_5_0_PCI_EXPRESS_DEVICE_AER                     0x07
-#define EFI_ACPI_5_0_PCI_EXPRESS_BRIDGE_AER                     0x08
-#define EFI_ACPI_5_0_GENERIC_HARDWARE_ERROR                     0x09
-
-//
-// Error Source structure flags.
-//
-#define EFI_ACPI_5_0_ERROR_SOURCE_FLAG_FIRMWARE_FIRST       (1 << 0)
-#define EFI_ACPI_5_0_ERROR_SOURCE_FLAG_GLOBAL               (1 << 1)
-
-///
-/// IA-32 Architecture Machine Check Exception Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT64  GlobalCapabilityInitData;
-  UINT64  GlobalControlInitData;
-  UINT8   NumberOfHardwareBanks;
-  UINT8   Reserved1[7];
-} EFI_ACPI_5_0_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE;
-
-///
-/// IA-32 Architecture Machine Check Bank Structure Definition
-///
-typedef struct {
-  UINT8   BankNumber;
-  UINT8   ClearStatusOnInitialization;
-  UINT8   StatusDataFormat;
-  UINT8   Reserved0;
-  UINT32  ControlRegisterMsrAddress;
-  UINT64  ControlInitData;
-  UINT32  StatusRegisterMsrAddress;
-  UINT32  AddressRegisterMsrAddress;
-  UINT32  MiscRegisterMsrAddress;
-} EFI_ACPI_5_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE;
-
-///
-/// IA-32 Architecture Machine Check Bank Structure MCA data format
-///
-#define EFI_ACPI_5_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_IA32      0x00
-#define EFI_ACPI_5_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_INTEL64   0x01
-#define EFI_ACPI_5_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_AMD64     0x02
-
-//
-// Hardware Error Notification types. All other values are reserved
-//
-#define EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_POLLED                0x00
-#define EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_EXTERNAL_INTERRUPT    0x01
-#define EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_LOCAL_INTERRUPT       0x02
-#define EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_SCI                   0x03
-#define EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_NMI                   0x04
-
-///
-/// Hardware Error Notification Configuration Write Enable Structure Definition
-///
-typedef struct {
-  UINT16    Type:1;
-  UINT16    PollInterval:1;
-  UINT16    SwitchToPollingThresholdValue:1;
-  UINT16    SwitchToPollingThresholdWindow:1;
-  UINT16    ErrorThresholdValue:1;
-  UINT16    ErrorThresholdWindow:1;
-  UINT16    Reserved:10;
-} EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE;
-
-///
-/// Hardware Error Notification Structure Definition
-///
-typedef struct {
-  UINT8                                                                          Type;
-  UINT8                                                                          Length;
-  EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE  ConfigurationWriteEnable;
-  UINT32                                                                         PollInterval;
-  UINT32                                                                         Vector;
-  UINT32                                                                         SwitchToPollingThresholdValue;
-  UINT32                                                                         SwitchToPollingThresholdWindow;
-  UINT32                                                                         ErrorThresholdValue;
-  UINT32                                                                         ErrorThresholdWindow;
-} EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE;
-
-///
-/// IA-32 Architecture Corrected Machine Check Structure Definition
-///
-typedef struct {
-  UINT16                                                 Type;
-  UINT16                                                 SourceId;
-  UINT8                                                  Reserved0[2];
-  UINT8                                                  Flags;
-  UINT8                                                  Enabled;
-  UINT32                                                 NumberOfRecordsToPreAllocate;
-  UINT32                                                 MaxSectionsPerRecord;
-  EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE     NotificationStructure;
-  UINT8                                                  NumberOfHardwareBanks;
-  UINT8                                                  Reserved1[3];
-} EFI_ACPI_5_0_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE;
-
-///
-/// IA-32 Architecture NMI Error Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  MaxRawDataLength;
-} EFI_ACPI_5_0_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE;
-
-///
-/// PCI Express Root Port AER Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  Bus;
-  UINT16  Device;
-  UINT16  Function;
-  UINT16  DeviceControl;
-  UINT8   Reserved1[2];
-  UINT32  UncorrectableErrorMask;
-  UINT32  UncorrectableErrorSeverity;
-  UINT32  CorrectableErrorMask;
-  UINT32  AdvancedErrorCapabilitiesAndControl;
-  UINT32  RootErrorCommand;
-} EFI_ACPI_5_0_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE;
-
-///
-/// PCI Express Device AER Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  Bus;
-  UINT16  Device;
-  UINT16  Function;
-  UINT16  DeviceControl;
-  UINT8   Reserved1[2];
-  UINT32  UncorrectableErrorMask;
-  UINT32  UncorrectableErrorSeverity;
-  UINT32  CorrectableErrorMask;
-  UINT32  AdvancedErrorCapabilitiesAndControl;
-} EFI_ACPI_5_0_PCI_EXPRESS_DEVICE_AER_STRUCTURE;
-
-///
-/// PCI Express Bridge AER Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  Bus;
-  UINT16  Device;
-  UINT16  Function;
-  UINT16  DeviceControl;
-  UINT8   Reserved1[2];
-  UINT32  UncorrectableErrorMask;
-  UINT32  UncorrectableErrorSeverity;
-  UINT32  CorrectableErrorMask;
-  UINT32  AdvancedErrorCapabilitiesAndControl;
-  UINT32  SecondaryUncorrectableErrorMask;
-  UINT32  SecondaryUncorrectableErrorSeverity;
-  UINT32  SecondaryAdvancedErrorCapabilitiesAndControl;
-} EFI_ACPI_5_0_PCI_EXPRESS_BRIDGE_AER_STRUCTURE;
-
-///
-/// Generic Hardware Error Source Structure Definition
-///
-typedef struct {
-  UINT16                                                 Type;
-  UINT16                                                 SourceId;
-  UINT16                                                 RelatedSourceId;
-  UINT8                                                  Flags;
-  UINT8                                                  Enabled;
-  UINT32                                                 NumberOfRecordsToPreAllocate;
-  UINT32                                                 MaxSectionsPerRecord;
-  UINT32                                                 MaxRawDataLength;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE                 ErrorStatusAddress;
-  EFI_ACPI_5_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE     NotificationStructure;
-  UINT32                                                 ErrorStatusBlockLength;
-} EFI_ACPI_5_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE;
-
-///
-/// Generic Error Status Definition
-///
-typedef struct {
-  EFI_ACPI_5_0_ERROR_BLOCK_STATUS              BlockStatus;
-  UINT32                                       RawDataOffset;
-  UINT32                                       RawDataLength;
-  UINT32                                       DataLength;
-  UINT32                                       ErrorSeverity;
-} EFI_ACPI_5_0_GENERIC_ERROR_STATUS_STRUCTURE;
-
-///
-/// ERST - Error Record Serialization Table
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      SerializationHeaderSize;
-  UINT8                       Reserved0[4];
-  UINT32                      InstructionEntryCount;
-} EFI_ACPI_5_0_ERROR_RECORD_SERIALIZATION_TABLE_HEADER;
-
-///
-/// ERST Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_ERROR_RECORD_SERIALIZATION_TABLE_REVISION 0x01
-
-///
-/// ERST Serialization Actions
-///
-#define EFI_ACPI_5_0_ERST_BEGIN_WRITE_OPERATION                    0x00
-#define EFI_ACPI_5_0_ERST_BEGIN_READ_OPERATION                     0x01
-#define EFI_ACPI_5_0_ERST_BEGIN_CLEAR_OPERATION                    0x02
-#define EFI_ACPI_5_0_ERST_END_OPERATION                            0x03
-#define EFI_ACPI_5_0_ERST_SET_RECORD_OFFSET                        0x04
-#define EFI_ACPI_5_0_ERST_EXECUTE_OPERATION                        0x05
-#define EFI_ACPI_5_0_ERST_CHECK_BUSY_STATUS                        0x06
-#define EFI_ACPI_5_0_ERST_GET_COMMAND_STATUS                       0x07
-#define EFI_ACPI_5_0_ERST_GET_RECORD_IDENTIFIER                    0x08
-#define EFI_ACPI_5_0_ERST_SET_RECORD_IDENTIFIER                    0x09
-#define EFI_ACPI_5_0_ERST_GET_RECORD_COUNT                         0x0A
-#define EFI_ACPI_5_0_ERST_BEGIN_DUMMY_WRITE_OPERATION              0x0B
-#define EFI_ACPI_5_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE              0x0D
-#define EFI_ACPI_5_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE_LENGTH       0x0E
-#define EFI_ACPI_5_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES   0x0F
-
-///
-/// ERST Action Command Status
-///
-#define EFI_ACPI_5_0_ERST_STATUS_SUCCESS                           0x00
-#define EFI_ACPI_5_0_ERST_STATUS_NOT_ENOUGH_SPACE                  0x01
-#define EFI_ACPI_5_0_ERST_STATUS_HARDWARE_NOT_AVAILABLE            0x02
-#define EFI_ACPI_5_0_ERST_STATUS_FAILED                            0x03
-#define EFI_ACPI_5_0_ERST_STATUS_RECORD_STORE_EMPTY                0x04
-#define EFI_ACPI_5_0_ERST_STATUS_RECORD_NOT_FOUND                  0x05
-
-///
-/// ERST Serialization Instructions
-///
-#define EFI_ACPI_5_0_ERST_READ_REGISTER                            0x00
-#define EFI_ACPI_5_0_ERST_READ_REGISTER_VALUE                      0x01
-#define EFI_ACPI_5_0_ERST_WRITE_REGISTER                           0x02
-#define EFI_ACPI_5_0_ERST_WRITE_REGISTER_VALUE                     0x03
-#define EFI_ACPI_5_0_ERST_NOOP                                     0x04
-#define EFI_ACPI_5_0_ERST_LOAD_VAR1                                0x05
-#define EFI_ACPI_5_0_ERST_LOAD_VAR2                                0x06
-#define EFI_ACPI_5_0_ERST_STORE_VAR1                               0x07
-#define EFI_ACPI_5_0_ERST_ADD                                      0x08
-#define EFI_ACPI_5_0_ERST_SUBTRACT                                 0x09
-#define EFI_ACPI_5_0_ERST_ADD_VALUE                                0x0A
-#define EFI_ACPI_5_0_ERST_SUBTRACT_VALUE                           0x0B
-#define EFI_ACPI_5_0_ERST_STALL                                    0x0C
-#define EFI_ACPI_5_0_ERST_STALL_WHILE_TRUE                         0x0D
-#define EFI_ACPI_5_0_ERST_SKIP_NEXT_INSTRUCTION_IF_TRUE            0x0E
-#define EFI_ACPI_5_0_ERST_GOTO                                     0x0F
-#define EFI_ACPI_5_0_ERST_SET_SRC_ADDRESS_BASE                     0x10
-#define EFI_ACPI_5_0_ERST_SET_DST_ADDRESS_BASE                     0x11
-#define EFI_ACPI_5_0_ERST_MOVE_DATA                                0x12
-
-///
-/// ERST Instruction Flags
-///
-#define EFI_ACPI_5_0_ERST_PRESERVE_REGISTER                        0x01
-
-///
-/// ERST Serialization Instruction Entry
-///
-typedef struct {
-  UINT8                                    SerializationAction;
-  UINT8                                    Instruction;
-  UINT8                                    Flags;
-  UINT8                                    Reserved0;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE   RegisterRegion;
-  UINT64                                   Value;
-  UINT64                                   Mask;
-} EFI_ACPI_5_0_ERST_SERIALIZATION_INSTRUCTION_ENTRY;
-
-///
-/// EINJ - Error Injection Table
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      InjectionHeaderSize;
-  UINT8                       InjectionFlags;
-  UINT8                       Reserved0[3];
-  UINT32                      InjectionEntryCount;
-} EFI_ACPI_5_0_ERROR_INJECTION_TABLE_HEADER;
-
-///
-/// EINJ Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_ERROR_INJECTION_TABLE_REVISION 0x01
-
-///
-/// EINJ Error Injection Actions
-///
-#define EFI_ACPI_5_0_EINJ_BEGIN_INJECTION_OPERATION                0x00
-#define EFI_ACPI_5_0_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE           0x01
-#define EFI_ACPI_5_0_EINJ_SET_ERROR_TYPE                           0x02
-#define EFI_ACPI_5_0_EINJ_GET_ERROR_TYPE                           0x03
-#define EFI_ACPI_5_0_EINJ_END_OPERATION                            0x04
-#define EFI_ACPI_5_0_EINJ_EXECUTE_OPERATION                        0x05
-#define EFI_ACPI_5_0_EINJ_CHECK_BUSY_STATUS                        0x06
-#define EFI_ACPI_5_0_EINJ_GET_COMMAND_STATUS                       0x07
-#define EFI_ACPI_5_0_EINJ_TRIGGER_ERROR                            0xFF
-
-///
-/// EINJ Action Command Status
-///
-#define EFI_ACPI_5_0_EINJ_STATUS_SUCCESS                           0x00
-#define EFI_ACPI_5_0_EINJ_STATUS_UNKNOWN_FAILURE                   0x01
-#define EFI_ACPI_5_0_EINJ_STATUS_INVALID_ACCESS                    0x02
-
-///
-/// EINJ Error Type Definition
-///
-#define EFI_ACPI_5_0_EINJ_ERROR_PROCESSOR_CORRECTABLE                 (1 << 0)
-#define EFI_ACPI_5_0_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_NONFATAL      (1 << 1)
-#define EFI_ACPI_5_0_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_FATAL         (1 << 2)
-#define EFI_ACPI_5_0_EINJ_ERROR_MEMORY_CORRECTABLE                    (1 << 3)
-#define EFI_ACPI_5_0_EINJ_ERROR_MEMORY_UNCORRECTABLE_NONFATAL         (1 << 4)
-#define EFI_ACPI_5_0_EINJ_ERROR_MEMORY_UNCORRECTABLE_FATAL            (1 << 5)
-#define EFI_ACPI_5_0_EINJ_ERROR_PCI_EXPRESS_CORRECTABLE               (1 << 6)
-#define EFI_ACPI_5_0_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_NONFATAL    (1 << 7)
-#define EFI_ACPI_5_0_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_FATAL       (1 << 8)
-#define EFI_ACPI_5_0_EINJ_ERROR_PLATFORM_CORRECTABLE                  (1 << 9)
-#define EFI_ACPI_5_0_EINJ_ERROR_PLATFORM_UNCORRECTABLE_NONFATAL       (1 << 10)
-#define EFI_ACPI_5_0_EINJ_ERROR_PLATFORM_UNCORRECTABLE_FATAL          (1 << 11)
-
-///
-/// EINJ Injection Instructions
-///
-#define EFI_ACPI_5_0_EINJ_READ_REGISTER                            0x00
-#define EFI_ACPI_5_0_EINJ_READ_REGISTER_VALUE                      0x01
-#define EFI_ACPI_5_0_EINJ_WRITE_REGISTER                           0x02
-#define EFI_ACPI_5_0_EINJ_WRITE_REGISTER_VALUE                     0x03
-#define EFI_ACPI_5_0_EINJ_NOOP                                     0x04
-
-///
-/// EINJ Instruction Flags
-///
-#define EFI_ACPI_5_0_EINJ_PRESERVE_REGISTER                        0x01
-
-///
-/// EINJ Injection Instruction Entry
-///
-typedef struct {
-  UINT8                                    InjectionAction;
-  UINT8                                    Instruction;
-  UINT8                                    Flags;
-  UINT8                                    Reserved0;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE   RegisterRegion;
-  UINT64                                   Value;
-  UINT64                                   Mask;
-} EFI_ACPI_5_0_EINJ_INJECTION_INSTRUCTION_ENTRY;
-
-///
-/// EINJ Trigger Action Table
-///
-typedef struct {
-  UINT32  HeaderSize;
-  UINT32  Revision;
-  UINT32  TableSize;
-  UINT32  EntryCount;
-} EFI_ACPI_5_0_EINJ_TRIGGER_ACTION_TABLE;
-
-///
-/// Platform Communications Channel Table (PCCT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      Flags;
-  UINT64                      Reserved;
-} EFI_ACPI_5_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER;
-
-///
-/// PCCT Version (as defined in ACPI 5.0 spec.)
-///
-#define EFI_ACPI_5_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION 0x01
-
-///
-/// PCCT Global Flags
-///
-#define EFI_ACPI_5_0_PCCT_FLAGS_SCI_DOORBELL                      BIT0
-
-//
-// PCCT Subspace type
-//
-#define EFI_ACPI_5_0_PCCT_SUBSPACE_TYPE_GENERIC  0x00
-
-///
-/// PCC Subspace Structure Header
-///
-typedef struct {
-  UINT8        Type;
-  UINT8        Length;
-} EFI_ACPI_5_0_PCCT_SUBSPACE_HEADER;
-
-///
-/// Generic Communications Subspace Structure
-///
-typedef struct {
-  UINT8                                    Type;
-  UINT8                                    Length;
-  UINT8                                    Reserved[6];
-  UINT64                                   BaseAddress;
-  UINT64                                   AddressLength;
-  EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE   DoorbellRegister;
-  UINT64                                   DoorbellPreserve;
-  UINT64                                   DoorbellWrite;
-  UINT32                                   NominalLatency;
-  UINT32                                   MaximumPeriodicAccessRate;
-  UINT16                                   MinimumRequestTurnaroundTime;
-} EFI_ACPI_5_0_PCCT_SUBSPACE_GENERIC;
-
-///
-/// Generic Communications Channel Shared Memory Region
-///
-
-typedef struct {
-  UINT8                                    Command;
-  UINT8                                    Reserved:7;
-  UINT8                                    GenerateSci:1;
-} EFI_ACPI_5_0_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND;
-
-typedef struct {
-  UINT8                                    CommandComplete:1;
-  UINT8                                    SciDoorbell:1;
-  UINT8                                    Error:1;
-  UINT8                                    PlatformNotification:1;
-  UINT8                                    Reserved:4;
-  UINT8                                    Reserved1;
-} EFI_ACPI_5_0_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS;
-
-typedef struct {
-  UINT32                                                    Signature;
-  EFI_ACPI_5_0_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND    Command;
-  EFI_ACPI_5_0_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS     Status;
-} EFI_ACPI_5_0_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER;
-
-//
-// Known table signatures
-//
-
-///
-/// "RSD PTR " Root System Description Pointer
-///
-#define EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE  SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ')
-
-///
-/// "APIC" Multiple APIC Description Table
-///
-#define EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('A', 'P', 'I', 'C')
-
-///
-/// "BERT" Boot Error Record Table
-///
-#define EFI_ACPI_5_0_BOOT_ERROR_RECORD_TABLE_SIGNATURE  SIGNATURE_32('B', 'E', 'R', 'T')
-
-///
-/// "BGRT" Boot Graphics Resource Table
-///
-#define EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE  SIGNATURE_32('B', 'G', 'R', 'T')
-
-///
-/// "CPEP" Corrected Platform Error Polling Table
-///
-#define EFI_ACPI_5_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE  SIGNATURE_32('C', 'P', 'E', 'P')
-
-///
-/// "DSDT" Differentiated System Description Table
-///
-#define EFI_ACPI_5_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('D', 'S', 'D', 'T')
-
-///
-/// "ECDT" Embedded Controller Boot Resources Table
-///
-#define EFI_ACPI_5_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE  SIGNATURE_32('E', 'C', 'D', 'T')
-
-///
-/// "EINJ" Error Injection Table
-///
-#define EFI_ACPI_5_0_ERROR_INJECTION_TABLE_SIGNATURE  SIGNATURE_32('E', 'I', 'N', 'J')
-
-///
-/// "ERST" Error Record Serialization Table
-///
-#define EFI_ACPI_5_0_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE  SIGNATURE_32('E', 'R', 'S', 'T')
-
-///
-/// "FACP" Fixed ACPI Description Table
-///
-#define EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('F', 'A', 'C', 'P')
-
-///
-/// "FACS" Firmware ACPI Control Structure
-///
-#define EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE  SIGNATURE_32('F', 'A', 'C', 'S')
-
-///
-/// "FPDT" Firmware Performance Data Table
-///
-#define EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE  SIGNATURE_32('F', 'P', 'D', 'T')
-
-///
-/// "GTDT" Generic Timer Description Table
-///
-#define EFI_ACPI_5_0_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('G', 'T', 'D', 'T')
-
-///
-/// "HEST" Hardware Error Source Table
-///
-#define EFI_ACPI_5_0_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE  SIGNATURE_32('H', 'E', 'S', 'T')
-
-///
-/// "MPST" Memory Power State Table
-///
-#define EFI_ACPI_5_0_MEMORY_POWER_STATE_TABLE_SIGNATURE  SIGNATURE_32('M', 'P', 'S', 'T')
-
-///
-/// "MSCT" Maximum System Characteristics Table
-///
-#define EFI_ACPI_5_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE  SIGNATURE_32('M', 'S', 'C', 'T')
-
-///
-/// "PMTT" Platform Memory Topology Table
-///
-#define EFI_ACPI_5_0_PLATFORM_MEMORY_TOPOLOGY_TABLE_SIGNATURE  SIGNATURE_32('P', 'M', 'T', 'T')
-
-///
-/// "PSDT" Persistent System Description Table
-///
-#define EFI_ACPI_5_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('P', 'S', 'D', 'T')
-
-///
-/// "RASF" ACPI RAS Feature Table
-///
-#define EFI_ACPI_5_0_ACPI_RAS_FEATURE_TABLE_SIGNATURE  SIGNATURE_32('R', 'A', 'S', 'F')
-
-///
-/// "RSDT" Root System Description Table
-///
-#define EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('R', 'S', 'D', 'T')
-
-///
-/// "SBST" Smart Battery Specification Table
-///
-#define EFI_ACPI_5_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE  SIGNATURE_32('S', 'B', 'S', 'T')
-
-///
-/// "SLIT" System Locality Information Table
-///
-#define EFI_ACPI_5_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE  SIGNATURE_32('S', 'L', 'I', 'T')
-
-///
-/// "SRAT" System Resource Affinity Table
-///
-#define EFI_ACPI_5_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE  SIGNATURE_32('S', 'R', 'A', 'T')
-
-///
-/// "SSDT" Secondary System Description Table
-///
-#define EFI_ACPI_5_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('S', 'S', 'D', 'T')
-
-///
-/// "XSDT" Extended System Description Table
-///
-#define EFI_ACPI_5_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('X', 'S', 'D', 'T')
-
-///
-/// "BOOT" MS Simple Boot Spec
-///
-#define EFI_ACPI_5_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE  SIGNATURE_32('B', 'O', 'O', 'T')
-
-///
-/// "CSRT" MS Core System Resource Table
-///
-#define EFI_ACPI_5_0_CORE_SYSTEM_RESOURCE_TABLE_SIGNATURE  SIGNATURE_32('C', 'S', 'R', 'T')
-
-///
-/// "DBG2" MS Debug Port 2 Spec
-///
-#define EFI_ACPI_5_0_DEBUG_PORT_2_TABLE_SIGNATURE  SIGNATURE_32('D', 'B', 'G', '2')
-
-///
-/// "DBGP" MS Debug Port Spec
-///
-#define EFI_ACPI_5_0_DEBUG_PORT_TABLE_SIGNATURE  SIGNATURE_32('D', 'B', 'G', 'P')
-
-///
-/// "DMAR" DMA Remapping Table
-///
-#define EFI_ACPI_5_0_DMA_REMAPPING_TABLE_SIGNATURE  SIGNATURE_32('D', 'M', 'A', 'R')
-
-///
-/// "DRTM" Dynamic Root of Trust for Measurement Table
-///
-#define EFI_ACPI_5_0_DYNAMIC_ROOT_OF_TRUST_FOR_MEASUREMENT_TABLE_SIGNATURE  SIGNATURE_32('D', 'R', 'T', 'M')
-
-///
-/// "ETDT" Event Timer Description Table
-///
-#define EFI_ACPI_5_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('E', 'T', 'D', 'T')
-
-///
-/// "HPET" IA-PC High Precision Event Timer Table
-///
-#define EFI_ACPI_5_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE  SIGNATURE_32('H', 'P', 'E', 'T')
-
-///
-/// "iBFT" iSCSI Boot Firmware Table
-///
-#define EFI_ACPI_5_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE  SIGNATURE_32('i', 'B', 'F', 'T')
-
-///
-/// "IVRS" I/O Virtualization Reporting Structure
-///
-#define EFI_ACPI_5_0_IO_VIRTUALIZATION_REPORTING_STRUCTURE_SIGNATURE  SIGNATURE_32('I', 'V', 'R', 'S')
-
-///
-/// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
-///
-#define EFI_ACPI_5_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('M', 'C', 'F', 'G')
-
-///
-/// "MCHI" Management Controller Host Interface Table
-///
-#define EFI_ACPI_5_0_MANAGEMENT_CONTROLLER_HOST_INTERFACE_TABLE_SIGNATURE  SIGNATURE_32('M', 'C', 'H', 'I')
-
-///
-/// "MSDM" MS Data Management Table
-///
-#define EFI_ACPI_5_0_DATA_MANAGEMENT_TABLE_SIGNATURE  SIGNATURE_32('M', 'S', 'D', 'M')
-
-///
-/// "SLIC" MS Software Licensing Table Specification
-///
-#define EFI_ACPI_5_0_SOFTWARE_LICENSING_TABLE_SIGNATURE  SIGNATURE_32('S', 'L', 'I', 'C')
-
-///
-/// "SPCR" Serial Port Concole Redirection Table
-///
-#define EFI_ACPI_5_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE  SIGNATURE_32('S', 'P', 'C', 'R')
-
-///
-/// "SPMI" Server Platform Management Interface Table
-///
-#define EFI_ACPI_5_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE  SIGNATURE_32('S', 'P', 'M', 'I')
-
-///
-/// "TCPA" Trusted Computing Platform Alliance Capabilities Table
-///
-#define EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE  SIGNATURE_32('T', 'C', 'P', 'A')
-
-///
-/// "TPM2" Trusted Computing Platform 1 Table
-///
-#define EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE  SIGNATURE_32('T', 'P', 'M', '2')
-
-///
-/// "UEFI" UEFI ACPI Data Table
-///
-#define EFI_ACPI_5_0_UEFI_ACPI_DATA_TABLE_SIGNATURE  SIGNATURE_32('U', 'E', 'F', 'I')
-
-///
-/// "WAET" Windows ACPI Emulated Devices Table
-///
-#define EFI_ACPI_5_0_WINDOWS_ACPI_EMULATED_DEVICES_TABLE_SIGNATURE  SIGNATURE_32('W', 'A', 'E', 'T')
-#define EFI_ACPI_5_0_WINDOWS_ACPI_ENLIGHTENMENT_TABLE_SIGNATURE  EFI_ACPI_5_0_WINDOWS_ACPI_EMULATED_DEVICES_TABLE_SIGNATURE
-
-///
-/// "WDAT" Watchdog Action Table
-///
-#define EFI_ACPI_5_0_WATCHDOG_ACTION_TABLE_SIGNATURE  SIGNATURE_32('W', 'D', 'A', 'T')
-
-///
-/// "WDRT" Watchdog Resource Table
-///
-#define EFI_ACPI_5_0_WATCHDOG_RESOURCE_TABLE_SIGNATURE  SIGNATURE_32('W', 'D', 'R', 'T')
-
-///
-/// "WPBT" MS Platform Binary Table
-///
-#define EFI_ACPI_5_0_PLATFORM_BINARY_TABLE_SIGNATURE  SIGNATURE_32('W', 'P', 'B', 'T')
-
-#pragma pack()
-
-#endif
diff --git a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi51.h b/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi51.h
deleted file mode 100644 (file)
index b006139..0000000
+++ /dev/null
@@ -1,2141 +0,0 @@
-/** @file
-  ACPI 5.1 definitions from the ACPI Specification Revision 5.1 July, 2014.
-
-  Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>
-  Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
-  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-**/
-
-#ifndef _ACPI_5_1_H_
-#define _ACPI_5_1_H_
-
-FILE_LICENCE ( BSD3 );
-
-#include <ipxe/efi/IndustryStandard/Acpi50.h>
-
-//
-// Ensure proper structure formats
-//
-#pragma pack(1)
-
-///
-/// ACPI 5.1 Generic Address Space definition
-///
-typedef struct {
-  UINT8   AddressSpaceId;
-  UINT8   RegisterBitWidth;
-  UINT8   RegisterBitOffset;
-  UINT8   AccessSize;
-  UINT64  Address;
-} EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE;
-
-//
-// Generic Address Space Address IDs
-//
-#define EFI_ACPI_5_1_SYSTEM_MEMORY              0
-#define EFI_ACPI_5_1_SYSTEM_IO                  1
-#define EFI_ACPI_5_1_PCI_CONFIGURATION_SPACE    2
-#define EFI_ACPI_5_1_EMBEDDED_CONTROLLER        3
-#define EFI_ACPI_5_1_SMBUS                      4
-#define EFI_ACPI_5_1_PLATFORM_COMMUNICATION_CHANNEL  0x0A
-#define EFI_ACPI_5_1_FUNCTIONAL_FIXED_HARDWARE       0x7F
-
-//
-// Generic Address Space Access Sizes
-//
-#define EFI_ACPI_5_1_UNDEFINED  0
-#define EFI_ACPI_5_1_BYTE       1
-#define EFI_ACPI_5_1_WORD       2
-#define EFI_ACPI_5_1_DWORD      3
-#define EFI_ACPI_5_1_QWORD      4
-
-//
-// ACPI 5.1 table structures
-//
-
-///
-/// Root System Description Pointer Structure
-///
-typedef struct {
-  UINT64  Signature;
-  UINT8   Checksum;
-  UINT8   OemId[6];
-  UINT8   Revision;
-  UINT32  RsdtAddress;
-  UINT32  Length;
-  UINT64  XsdtAddress;
-  UINT8   ExtendedChecksum;
-  UINT8   Reserved[3];
-} EFI_ACPI_5_1_ROOT_SYSTEM_DESCRIPTION_POINTER;
-
-///
-/// RSD_PTR Revision (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02  ///< ACPISpec (Revision 5.1) says current value is 2
-
-///
-/// Common table header, this prefaces all ACPI tables, including FACS, but
-/// excluding the RSD PTR structure
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-} EFI_ACPI_5_1_COMMON_HEADER;
-
-//
-// Root System Description Table
-// No definition needed as it is a common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers.
-//
-
-///
-/// RSDT Revision (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
-
-//
-// Extended System Description Table
-// No definition needed as it is a common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers.
-//
-
-///
-/// XSDT Revision (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Fixed ACPI Description Table Structure (FADT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER             Header;
-  UINT32                                  FirmwareCtrl;
-  UINT32                                  Dsdt;
-  UINT8                                   Reserved0;
-  UINT8                                   PreferredPmProfile;
-  UINT16                                  SciInt;
-  UINT32                                  SmiCmd;
-  UINT8                                   AcpiEnable;
-  UINT8                                   AcpiDisable;
-  UINT8                                   S4BiosReq;
-  UINT8                                   PstateCnt;
-  UINT32                                  Pm1aEvtBlk;
-  UINT32                                  Pm1bEvtBlk;
-  UINT32                                  Pm1aCntBlk;
-  UINT32                                  Pm1bCntBlk;
-  UINT32                                  Pm2CntBlk;
-  UINT32                                  PmTmrBlk;
-  UINT32                                  Gpe0Blk;
-  UINT32                                  Gpe1Blk;
-  UINT8                                   Pm1EvtLen;
-  UINT8                                   Pm1CntLen;
-  UINT8                                   Pm2CntLen;
-  UINT8                                   PmTmrLen;
-  UINT8                                   Gpe0BlkLen;
-  UINT8                                   Gpe1BlkLen;
-  UINT8                                   Gpe1Base;
-  UINT8                                   CstCnt;
-  UINT16                                  PLvl2Lat;
-  UINT16                                  PLvl3Lat;
-  UINT16                                  FlushSize;
-  UINT16                                  FlushStride;
-  UINT8                                   DutyOffset;
-  UINT8                                   DutyWidth;
-  UINT8                                   DayAlrm;
-  UINT8                                   MonAlrm;
-  UINT8                                   Century;
-  UINT16                                  IaPcBootArch;
-  UINT8                                   Reserved1;
-  UINT32                                  Flags;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE  ResetReg;
-  UINT8                                   ResetValue;
-  UINT16                                  ArmBootArch;
-  UINT8                                   MinorVersion;
-  UINT64                                  XFirmwareCtrl;
-  UINT64                                  XDsdt;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE  XPm1aEvtBlk;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE  XPm1bEvtBlk;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE  XPm1aCntBlk;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE  XPm1bCntBlk;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE  XPm2CntBlk;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE  XPmTmrBlk;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE  XGpe0Blk;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE  XGpe1Blk;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE  SleepControlReg;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE  SleepStatusReg;
-} EFI_ACPI_5_1_FIXED_ACPI_DESCRIPTION_TABLE;
-
-///
-/// FADT Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_FIXED_ACPI_DESCRIPTION_TABLE_REVISION  0x05
-#define EFI_ACPI_5_1_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION  0x01
-
-//
-// Fixed ACPI Description Table Preferred Power Management Profile
-//
-#define EFI_ACPI_5_1_PM_PROFILE_UNSPECIFIED         0
-#define EFI_ACPI_5_1_PM_PROFILE_DESKTOP             1
-#define EFI_ACPI_5_1_PM_PROFILE_MOBILE              2
-#define EFI_ACPI_5_1_PM_PROFILE_WORKSTATION         3
-#define EFI_ACPI_5_1_PM_PROFILE_ENTERPRISE_SERVER   4
-#define EFI_ACPI_5_1_PM_PROFILE_SOHO_SERVER         5
-#define EFI_ACPI_5_1_PM_PROFILE_APPLIANCE_PC        6
-#define EFI_ACPI_5_1_PM_PROFILE_PERFORMANCE_SERVER  7
-#define EFI_ACPI_5_1_PM_PROFILE_TABLET              8
-
-//
-// Fixed ACPI Description Table Boot Architecture Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_5_1_LEGACY_DEVICES              BIT0
-#define EFI_ACPI_5_1_8042                        BIT1
-#define EFI_ACPI_5_1_VGA_NOT_PRESENT             BIT2
-#define EFI_ACPI_5_1_MSI_NOT_SUPPORTED           BIT3
-#define EFI_ACPI_5_1_PCIE_ASPM_CONTROLS          BIT4
-#define EFI_ACPI_5_1_CMOS_RTC_NOT_PRESENT        BIT5
-
-//
-// Fixed ACPI Description Table Arm Boot Architecture Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_5_1_ARM_PSCI_COMPLIANT              BIT0
-#define EFI_ACPI_5_1_ARM_PSCI_USE_HVC                BIT1
-
-//
-// Fixed ACPI Description Table Fixed Feature Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_5_1_WBINVD                                 BIT0
-#define EFI_ACPI_5_1_WBINVD_FLUSH                           BIT1
-#define EFI_ACPI_5_1_PROC_C1                                BIT2
-#define EFI_ACPI_5_1_P_LVL2_UP                              BIT3
-#define EFI_ACPI_5_1_PWR_BUTTON                             BIT4
-#define EFI_ACPI_5_1_SLP_BUTTON                             BIT5
-#define EFI_ACPI_5_1_FIX_RTC                                BIT6
-#define EFI_ACPI_5_1_RTC_S4                                 BIT7
-#define EFI_ACPI_5_1_TMR_VAL_EXT                            BIT8
-#define EFI_ACPI_5_1_DCK_CAP                                BIT9
-#define EFI_ACPI_5_1_RESET_REG_SUP                          BIT10
-#define EFI_ACPI_5_1_SEALED_CASE                            BIT11
-#define EFI_ACPI_5_1_HEADLESS                               BIT12
-#define EFI_ACPI_5_1_CPU_SW_SLP                             BIT13
-#define EFI_ACPI_5_1_PCI_EXP_WAK                            BIT14
-#define EFI_ACPI_5_1_USE_PLATFORM_CLOCK                     BIT15
-#define EFI_ACPI_5_1_S4_RTC_STS_VALID                       BIT16
-#define EFI_ACPI_5_1_REMOTE_POWER_ON_CAPABLE                BIT17
-#define EFI_ACPI_5_1_FORCE_APIC_CLUSTER_MODEL               BIT18
-#define EFI_ACPI_5_1_FORCE_APIC_PHYSICAL_DESTINATION_MODE   BIT19
-#define EFI_ACPI_5_1_HW_REDUCED_ACPI                        BIT20
-#define EFI_ACPI_5_1_LOW_POWER_S0_IDLE_CAPABLE              BIT21
-
-///
-/// Firmware ACPI Control Structure
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-  UINT32  HardwareSignature;
-  UINT32  FirmwareWakingVector;
-  UINT32  GlobalLock;
-  UINT32  Flags;
-  UINT64  XFirmwareWakingVector;
-  UINT8   Version;
-  UINT8   Reserved0[3];
-  UINT32  OspmFlags;
-  UINT8   Reserved1[24];
-} EFI_ACPI_5_1_FIRMWARE_ACPI_CONTROL_STRUCTURE;
-
-///
-/// FACS Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION  0x02
-
-///
-/// Firmware Control Structure Feature Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_5_1_S4BIOS_F                     BIT0
-#define EFI_ACPI_5_1_64BIT_WAKE_SUPPORTED_F       BIT1
-
-///
-/// OSPM Enabled Firmware Control Structure Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_5_1_OSPM_64BIT_WAKE_F            BIT0
-
-//
-// Differentiated System Description Table,
-// Secondary System Description Table
-// and Persistent System Description Table,
-// no definition needed as they are common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block.
-//
-#define EFI_ACPI_5_1_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION   0x02
-#define EFI_ACPI_5_1_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION        0x02
-
-///
-/// Multiple APIC Description Table header definition.  The rest of the table
-/// must be defined in a platform specific manner.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      LocalApicAddress;
-  UINT32                      Flags;
-} EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER;
-
-///
-/// MADT Revision (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x03
-
-///
-/// Multiple APIC Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_5_1_PCAT_COMPAT         BIT0
-
-//
-// Multiple APIC Description Table APIC structure types
-// All other values between 0x0D and 0x7F are reserved and
-// will be ignored by OSPM. 0x80 ~ 0xFF are reserved for OEM.
-//
-#define EFI_ACPI_5_1_PROCESSOR_LOCAL_APIC           0x00
-#define EFI_ACPI_5_1_IO_APIC                        0x01
-#define EFI_ACPI_5_1_INTERRUPT_SOURCE_OVERRIDE      0x02
-#define EFI_ACPI_5_1_NON_MASKABLE_INTERRUPT_SOURCE  0x03
-#define EFI_ACPI_5_1_LOCAL_APIC_NMI                 0x04
-#define EFI_ACPI_5_1_LOCAL_APIC_ADDRESS_OVERRIDE    0x05
-#define EFI_ACPI_5_1_IO_SAPIC                       0x06
-#define EFI_ACPI_5_1_LOCAL_SAPIC                    0x07
-#define EFI_ACPI_5_1_PLATFORM_INTERRUPT_SOURCES     0x08
-#define EFI_ACPI_5_1_PROCESSOR_LOCAL_X2APIC         0x09
-#define EFI_ACPI_5_1_LOCAL_X2APIC_NMI               0x0A
-#define EFI_ACPI_5_1_GIC                            0x0B
-#define EFI_ACPI_5_1_GICD                           0x0C
-#define EFI_ACPI_5_1_GIC_MSI_FRAME                  0x0D
-#define EFI_ACPI_5_1_GICR                           0x0E
-
-//
-// APIC Structure Definitions
-//
-
-///
-/// Processor Local APIC Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT8   ApicId;
-  UINT32  Flags;
-} EFI_ACPI_5_1_PROCESSOR_LOCAL_APIC_STRUCTURE;
-
-///
-/// Local APIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_1_LOCAL_APIC_ENABLED        BIT0
-
-///
-/// IO APIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   IoApicId;
-  UINT8   Reserved;
-  UINT32  IoApicAddress;
-  UINT32  GlobalSystemInterruptBase;
-} EFI_ACPI_5_1_IO_APIC_STRUCTURE;
-
-///
-/// Interrupt Source Override Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Bus;
-  UINT8   Source;
-  UINT32  GlobalSystemInterrupt;
-  UINT16  Flags;
-} EFI_ACPI_5_1_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE;
-
-///
-/// Platform Interrupt Sources Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT8   InterruptType;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT8   IoSapicVector;
-  UINT32  GlobalSystemInterrupt;
-  UINT32  PlatformInterruptSourceFlags;
-  UINT8   CpeiProcessorOverride;
-  UINT8   Reserved[31];
-} EFI_ACPI_5_1_PLATFORM_INTERRUPT_APIC_STRUCTURE;
-
-//
-// MPS INTI flags.
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_5_1_POLARITY      (3 << 0)
-#define EFI_ACPI_5_1_TRIGGER_MODE  (3 << 2)
-
-///
-/// Non-Maskable Interrupt Source Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT32  GlobalSystemInterrupt;
-} EFI_ACPI_5_1_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE;
-
-///
-/// Local APIC NMI Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT16  Flags;
-  UINT8   LocalApicLint;
-} EFI_ACPI_5_1_LOCAL_APIC_NMI_STRUCTURE;
-
-///
-/// Local APIC Address Override Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved;
-  UINT64  LocalApicAddress;
-} EFI_ACPI_5_1_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
-
-///
-/// IO SAPIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   IoApicId;
-  UINT8   Reserved;
-  UINT32  GlobalSystemInterruptBase;
-  UINT64  IoSapicAddress;
-} EFI_ACPI_5_1_IO_SAPIC_STRUCTURE;
-
-///
-/// Local SAPIC Structure
-/// This struct followed by a null-terminated ASCII string - ACPI Processor UID String
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT8   LocalSapicId;
-  UINT8   LocalSapicEid;
-  UINT8   Reserved[3];
-  UINT32  Flags;
-  UINT32  ACPIProcessorUIDValue;
-} EFI_ACPI_5_1_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
-
-///
-/// Platform Interrupt Sources Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT8   InterruptType;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT8   IoSapicVector;
-  UINT32  GlobalSystemInterrupt;
-  UINT32  PlatformInterruptSourceFlags;
-} EFI_ACPI_5_1_PLATFORM_INTERRUPT_SOURCES_STRUCTURE;
-
-///
-/// Platform Interrupt Source Flags.
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_5_1_CPEI_PROCESSOR_OVERRIDE          BIT0
-
-///
-/// Processor Local x2APIC Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Reserved[2];
-  UINT32  X2ApicId;
-  UINT32  Flags;
-  UINT32  AcpiProcessorUid;
-} EFI_ACPI_5_1_PROCESSOR_LOCAL_X2APIC_STRUCTURE;
-
-///
-/// Local x2APIC NMI Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT32  AcpiProcessorUid;
-  UINT8   LocalX2ApicLint;
-  UINT8   Reserved[3];
-} EFI_ACPI_5_1_LOCAL_X2APIC_NMI_STRUCTURE;
-
-///
-/// GIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved;
-  UINT32  CPUInterfaceNumber;
-  UINT32  AcpiProcessorUid;
-  UINT32  Flags;
-  UINT32  ParkingProtocolVersion;
-  UINT32  PerformanceInterruptGsiv;
-  UINT64  ParkedAddress;
-  UINT64  PhysicalBaseAddress;
-  UINT64  GICV;
-  UINT64  GICH;
-  UINT32  VGICMaintenanceInterrupt;
-  UINT64  GICRBaseAddress;
-  UINT64  MPIDR;
-} EFI_ACPI_5_1_GIC_STRUCTURE;
-
-///
-/// GIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_1_GIC_ENABLED                              BIT0
-#define EFI_ACPI_5_1_PERFORMANCE_INTERRUPT_MODEL              BIT1
-#define EFI_ACPI_5_1_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS    BIT2
-
-///
-/// GIC Distributor Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved1;
-  UINT32  GicId;
-  UINT64  PhysicalBaseAddress;
-  UINT32  SystemVectorBase;
-  UINT8   GicVersion;
-  UINT8   Reserved2[3];
-} EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE;
-
-///
-/// GIC Version
-///
-#define EFI_ACPI_5_1_GIC_V2                                   0x01
-#define EFI_ACPI_5_1_GIC_V2m                                  0x02
-#define EFI_ACPI_5_1_GIC_V3                                   0x03
-#define EFI_ACPI_5_1_GIC_V4                                   0x04
-
-///
-/// GIC MSI Frame Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved1;
-  UINT32  GicMsiFrameId;
-  UINT64  PhysicalBaseAddress;
-  UINT32  Flags;
-  UINT16  SPICount;
-  UINT16  SPIBase;
-} EFI_ACPI_5_1_GIC_MSI_FRAME_STRUCTURE;
-
-///
-/// GIC MSI Frame Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_1_SPI_COUNT_BASE_SELECT                    BIT0
-
-///
-/// GICR Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved;
-  UINT64  DiscoveryRangeBaseAddress;
-  UINT32  DiscoveryRangeLength;
-} EFI_ACPI_5_1_GICR_STRUCTURE;
-
-///
-/// Smart Battery Description Table (SBST)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      WarningEnergyLevel;
-  UINT32                      LowEnergyLevel;
-  UINT32                      CriticalEnergyLevel;
-} EFI_ACPI_5_1_SMART_BATTERY_DESCRIPTION_TABLE;
-
-///
-/// SBST Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Embedded Controller Boot Resources Table (ECDT)
-/// The table is followed by a null terminated ASCII string that contains
-/// a fully qualified reference to the name space object.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER             Header;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE  EcControl;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE  EcData;
-  UINT32                                  Uid;
-  UINT8                                   GpeBit;
-} EFI_ACPI_5_1_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE;
-
-///
-/// ECDT Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION  0x01
-
-///
-/// System Resource Affinity Table (SRAT).  The rest of the table
-/// must be defined in a platform specific manner.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      Reserved1;  ///< Must be set to 1
-  UINT64                      Reserved2;
-} EFI_ACPI_5_1_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER;
-
-///
-/// SRAT Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION  0x03
-
-//
-// SRAT structure types.
-// All other values between 0x04 an 0xFF are reserved and
-// will be ignored by OSPM.
-//
-#define EFI_ACPI_5_1_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY  0x00
-#define EFI_ACPI_5_1_MEMORY_AFFINITY                      0x01
-#define EFI_ACPI_5_1_PROCESSOR_LOCAL_X2APIC_AFFINITY      0x02
-#define EFI_ACPI_5_1_GICC_AFFINITY                        0x03
-
-///
-/// Processor Local APIC/SAPIC Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   ProximityDomain7To0;
-  UINT8   ApicId;
-  UINT32  Flags;
-  UINT8   LocalSapicEid;
-  UINT8   ProximityDomain31To8[3];
-  UINT32  ClockDomain;
-} EFI_ACPI_5_1_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE;
-
-///
-/// Local APIC/SAPIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_1_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0)
-
-///
-/// Memory Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT32  ProximityDomain;
-  UINT16  Reserved1;
-  UINT32  AddressBaseLow;
-  UINT32  AddressBaseHigh;
-  UINT32  LengthLow;
-  UINT32  LengthHigh;
-  UINT32  Reserved2;
-  UINT32  Flags;
-  UINT64  Reserved3;
-} EFI_ACPI_5_1_MEMORY_AFFINITY_STRUCTURE;
-
-//
-// Memory Flags.  All other bits are reserved and must be 0.
-//
-#define EFI_ACPI_5_1_MEMORY_ENABLED       (1 << 0)
-#define EFI_ACPI_5_1_MEMORY_HOT_PLUGGABLE (1 << 1)
-#define EFI_ACPI_5_1_MEMORY_NONVOLATILE   (1 << 2)
-
-///
-/// Processor Local x2APIC Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Reserved1[2];
-  UINT32  ProximityDomain;
-  UINT32  X2ApicId;
-  UINT32  Flags;
-  UINT32  ClockDomain;
-  UINT8   Reserved2[4];
-} EFI_ACPI_5_1_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE;
-
-///
-/// GICC Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT32  ProximityDomain;
-  UINT32  AcpiProcessorUid;
-  UINT32  Flags;
-  UINT32  ClockDomain;
-} EFI_ACPI_5_1_GICC_AFFINITY_STRUCTURE;
-
-///
-/// GICC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_1_GICC_ENABLED (1 << 0)
-
-///
-/// System Locality Distance Information Table (SLIT).
-/// The rest of the table is a matrix.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT64                      NumberOfSystemLocalities;
-} EFI_ACPI_5_1_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER;
-
-///
-/// SLIT Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION  0x01
-
-///
-/// Corrected Platform Error Polling Table (CPEP)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT8                       Reserved[8];
-} EFI_ACPI_5_1_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER;
-
-///
-/// CPEP Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_REVISION 0x01
-
-//
-// CPEP processor structure types.
-//
-#define EFI_ACPI_5_1_CPEP_PROCESSOR_APIC_SAPIC  0x00
-
-///
-/// Corrected Platform Error Polling Processor Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT32  PollingInterval;
-} EFI_ACPI_5_1_CPEP_PROCESSOR_APIC_SAPIC_STRUCTURE;
-
-///
-/// Maximum System Characteristics Table (MSCT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      OffsetProxDomInfo;
-  UINT32                      MaximumNumberOfProximityDomains;
-  UINT32                      MaximumNumberOfClockDomains;
-  UINT64                      MaximumPhysicalAddress;
-} EFI_ACPI_5_1_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_HEADER;
-
-///
-/// MSCT Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_REVISION 0x01
-
-///
-/// Maximum Proximity Domain Information Structure Definition
-///
-typedef struct {
-  UINT8   Revision;
-  UINT8   Length;
-  UINT32  ProximityDomainRangeLow;
-  UINT32  ProximityDomainRangeHigh;
-  UINT32  MaximumProcessorCapacity;
-  UINT64  MaximumMemoryCapacity;
-} EFI_ACPI_5_1_MAXIMUM_PROXIMITY_DOMAIN_INFORMATION_STRUCTURE;
-
-///
-/// ACPI RAS Feature Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT8                       PlatformCommunicationChannelIdentifier[12];
-} EFI_ACPI_5_1_RAS_FEATURE_TABLE;
-
-///
-/// RASF Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_RAS_FEATURE_TABLE_REVISION 0x01
-
-///
-/// ACPI RASF Platform Communication Channel Shared Memory Region definition.
-///
-typedef struct {
-  UINT32                      Signature;
-  UINT16                      Command;
-  UINT16                      Status;
-  UINT16                      Version;
-  UINT8                       RASCapabilities[16];
-  UINT8                       SetRASCapabilities[16];
-  UINT16                      NumberOfRASFParameterBlocks;
-  UINT32                      SetRASCapabilitiesStatus;
-} EFI_ACPI_5_1_RASF_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION;
-
-///
-/// ACPI RASF PCC command code
-///
-#define EFI_ACPI_5_1_RASF_PCC_COMMAND_CODE_EXECUTE_RASF_COMMAND  0x01
-
-///
-/// ACPI RASF Platform RAS Capabilities
-///
-#define EFI_ACPI_5_1_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED                          0x01
-#define EFI_ACPI_5_1_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED_AND_EXPOSED_TO_SOFTWARE  0x02
-
-///
-/// ACPI RASF Parameter Block structure for PATROL_SCRUB
-///
-typedef struct {
-  UINT16                      Type;
-  UINT16                      Version;
-  UINT16                      Length;
-  UINT16                      PatrolScrubCommand;
-  UINT64                      RequestedAddressRange[2];
-  UINT64                      ActualAddressRange[2];
-  UINT16                      Flags;
-  UINT8                       RequestedSpeed;
-} EFI_ACPI_5_1_RASF_PATROL_SCRUB_PLATFORM_BLOCK_STRUCTURE;
-
-///
-/// ACPI RASF Patrol Scrub command
-///
-#define EFI_ACPI_5_1_RASF_PATROL_SCRUB_COMMAND_GET_PATROL_PARAMETERS   0x01
-#define EFI_ACPI_5_1_RASF_PATROL_SCRUB_COMMAND_START_PATROL_SCRUBBER   0x02
-#define EFI_ACPI_5_1_RASF_PATROL_SCRUB_COMMAND_STOP_PATROL_SCRUBBER    0x03
-
-///
-/// Memory Power State Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT8                       PlatformCommunicationChannelIdentifier;
-  UINT8                       Reserved[3];
-// Memory Power Node Structure
-// Memory Power State Characteristics
-} EFI_ACPI_5_1_MEMORY_POWER_STATUS_TABLE;
-
-///
-/// MPST Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_MEMORY_POWER_STATE_TABLE_REVISION 0x01
-
-///
-/// MPST Platform Communication Channel Shared Memory Region definition.
-///
-typedef struct {
-  UINT32                      Signature;
-  UINT16                      Command;
-  UINT16                      Status;
-  UINT32                      MemoryPowerCommandRegister;
-  UINT32                      MemoryPowerStatusRegister;
-  UINT32                      PowerStateId;
-  UINT32                      MemoryPowerNodeId;
-  UINT64                      MemoryEnergyConsumed;
-  UINT64                      ExpectedAveragePowerComsuned;
-} EFI_ACPI_5_1_MPST_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION;
-
-///
-/// ACPI MPST PCC command code
-///
-#define EFI_ACPI_5_1_MPST_PCC_COMMAND_CODE_EXECUTE_MPST_COMMAND  0x03
-
-///
-/// ACPI MPST Memory Power command
-///
-#define EFI_ACPI_5_1_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_POWER_STATE       0x01
-#define EFI_ACPI_5_1_MPST_MEMORY_POWER_COMMAND_SET_MEMORY_POWER_STATE       0x02
-#define EFI_ACPI_5_1_MPST_MEMORY_POWER_COMMAND_GET_AVERAGE_POWER_CONSUMED   0x03
-#define EFI_ACPI_5_1_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_ENERGY_CONSUMED   0x04
-
-///
-/// MPST Memory Power Node Table
-///
-typedef struct {
-  UINT8                                             PowerStateValue;
-  UINT8                                             PowerStateInformationIndex;
-} EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE;
-
-typedef struct {
-  UINT8                                             Flag;
-  UINT8                                             Reserved;
-  UINT16                                            MemoryPowerNodeId;
-  UINT32                                            Length;
-  UINT64                                            AddressBase;
-  UINT64                                            AddressLength;
-  UINT32                                            NumberOfPowerStates;
-  UINT32                                            NumberOfPhysicalComponents;
-//EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE              MemoryPowerState[NumberOfPowerStates];
-//UINT16                                            PhysicalComponentIdentifier[NumberOfPhysicalComponents];
-} EFI_ACPI_5_1_MPST_MEMORY_POWER_STRUCTURE;
-
-#define EFI_ACPI_5_1_MPST_MEMORY_POWER_STRUCTURE_FLAG_ENABLE          0x01
-#define EFI_ACPI_5_1_MPST_MEMORY_POWER_STRUCTURE_FLAG_POWER_MANAGED   0x02
-#define EFI_ACPI_5_1_MPST_MEMORY_POWER_STRUCTURE_FLAG_HOT_PLUGGABLE   0x04
-
-typedef struct {
-  UINT16                      MemoryPowerNodeCount;
-  UINT8                       Reserved[2];
-} EFI_ACPI_5_1_MPST_MEMORY_POWER_NODE_TABLE;
-
-///
-/// MPST Memory Power State Characteristics Table
-///
-typedef struct {
-  UINT8                                             PowerStateStructureID;
-  UINT8                                             Flag;
-  UINT16                                            Reserved;
-  UINT32                                            AveragePowerConsumedInMPS0;
-  UINT32                                            RelativePowerSavingToMPS0;
-  UINT64                                            ExitLatencyToMPS0;
-} EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE;
-
-#define EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_MEMORY_CONTENT_PRESERVED              0x01
-#define EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_ENTRY   0x02
-#define EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_EXIT    0x04
-
-typedef struct {
-  UINT16                      MemoryPowerStateCharacteristicsCount;
-  UINT8                       Reserved[2];
-} EFI_ACPI_5_1_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE;
-
-///
-/// Memory Topology Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      Reserved;
-} EFI_ACPI_5_1_MEMORY_TOPOLOGY_TABLE;
-
-///
-/// PMTT Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_MEMORY_TOPOLOGY_TABLE_REVISION 0x01
-
-///
-/// Common Memory Aggregator Device Structure.
-///
-typedef struct {
-  UINT8                       Type;
-  UINT8                       Reserved;
-  UINT16                      Length;
-  UINT16                      Flags;
-  UINT16                      Reserved1;
-} EFI_ACPI_5_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
-
-///
-/// Memory Aggregator Device Type
-///
-#define EFI_ACPI_5_1_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_SOCKET            0x1
-#define EFI_ACPI_5_1_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_MEMORY_CONTROLLER 0x2
-#define EFI_ACPI_5_1_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_DIMM              0x3
-
-///
-/// Socket Memory Aggregator Device Structure.
-///
-typedef struct {
-  EFI_ACPI_5_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE  Header;
-  UINT16                                                       SocketIdentifier;
-  UINT16                                                       Reserved;
-//EFI_ACPI_5_1_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE  MemoryController[];
-} EFI_ACPI_5_1_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
-
-///
-/// MemoryController Memory Aggregator Device Structure.
-///
-typedef struct {
-  EFI_ACPI_5_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE  Header;
-  UINT32                                                       ReadLatency;
-  UINT32                                                       WriteLatency;
-  UINT32                                                       ReadBandwidth;
-  UINT32                                                       WriteBandwidth;
-  UINT16                                                       OptimalAccessUnit;
-  UINT16                                                       OptimalAccessAlignment;
-  UINT16                                                       Reserved;
-  UINT16                                                       NumberOfProximityDomains;
-//UINT32                                                       ProximityDomain[NumberOfProximityDomains];
-//EFI_ACPI_5_1_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE    PhysicalComponent[];
-} EFI_ACPI_5_1_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
-
-///
-/// DIMM Memory Aggregator Device Structure.
-///
-typedef struct {
-  EFI_ACPI_5_1_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE  Header;
-  UINT16                                                       PhysicalComponentIdentifier;
-  UINT16                                                       Reserved;
-  UINT32                                                       SizeOfDimm;
-  UINT32                                                       SmbiosHandle;
-} EFI_ACPI_5_1_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
-
-///
-/// Boot Graphics Resource Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  ///
-  /// 2-bytes (16 bit) version ID. This value must be 1.
-  ///
-  UINT16                      Version;
-  ///
-  /// 1-byte status field indicating current status about the table.
-  ///     Bits[7:1] = Reserved (must be zero)
-  ///     Bit [0] = Valid. A one indicates the boot image graphic is valid.
-  ///
-  UINT8                       Status;
-  ///
-  /// 1-byte enumerated type field indicating format of the image.
-  ///     0 = Bitmap
-  ///     1 - 255  Reserved (for future use)
-  ///
-  UINT8                       ImageType;
-  ///
-  /// 8-byte (64 bit) physical address pointing to the firmware's in-memory copy
-  /// of the image bitmap.
-  ///
-  UINT64                      ImageAddress;
-  ///
-  /// A 4-byte (32-bit) unsigned long describing the display X-offset of the boot image.
-  /// (X, Y) display offset of the top left corner of the boot image.
-  /// The top left corner of the display is at offset (0, 0).
-  ///
-  UINT32                      ImageOffsetX;
-  ///
-  /// A 4-byte (32-bit) unsigned long describing the display Y-offset of the boot image.
-  /// (X, Y) display offset of the top left corner of the boot image.
-  /// The top left corner of the display is at offset (0, 0).
-  ///
-  UINT32                      ImageOffsetY;
-} EFI_ACPI_5_1_BOOT_GRAPHICS_RESOURCE_TABLE;
-
-///
-/// BGRT Revision
-///
-#define EFI_ACPI_5_1_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION 1
-
-///
-/// BGRT Version
-///
-#define EFI_ACPI_5_1_BGRT_VERSION         0x01
-
-///
-/// BGRT Status
-///
-#define EFI_ACPI_5_1_BGRT_STATUS_NOT_DISPLAYED 0x00
-#define EFI_ACPI_5_1_BGRT_STATUS_DISPLAYED     0x01
-
-///
-/// BGRT Image Type
-///
-#define EFI_ACPI_5_1_BGRT_IMAGE_TYPE_BMP  0x00
-
-///
-/// FPDT Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION 0x01
-
-///
-/// FPDT Performance Record Types
-///
-#define EFI_ACPI_5_1_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER      0x0000
-#define EFI_ACPI_5_1_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER     0x0001
-
-///
-/// FPDT Performance Record Revision
-///
-#define EFI_ACPI_5_1_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER  0x01
-#define EFI_ACPI_5_1_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER 0x01
-
-///
-/// FPDT Runtime Performance Record Types
-///
-#define EFI_ACPI_5_1_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME                0x0000
-#define EFI_ACPI_5_1_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND               0x0001
-#define EFI_ACPI_5_1_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT      0x0002
-
-///
-/// FPDT Runtime Performance Record Revision
-///
-#define EFI_ACPI_5_1_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME            0x01
-#define EFI_ACPI_5_1_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND           0x01
-#define EFI_ACPI_5_1_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT  0x02
-
-///
-/// FPDT Performance Record header
-///
-typedef struct {
-  UINT16           Type;
-  UINT8            Length;
-  UINT8            Revision;
-} EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER;
-
-///
-/// FPDT Performance Table header
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-} EFI_ACPI_5_1_FPDT_PERFORMANCE_TABLE_HEADER;
-
-///
-/// FPDT Firmware Basic Boot Performance Pointer Record Structure
-///
-typedef struct {
-  EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  UINT32                                          Reserved;
-  ///
-  /// 64-bit processor-relative physical address of the Basic Boot Performance Table.
-  ///
-  UINT64                                          BootPerformanceTablePointer;
-} EFI_ACPI_5_1_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD;
-
-///
-/// FPDT S3 Performance Table Pointer Record Structure
-///
-typedef struct {
-  EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  UINT32                                          Reserved;
-  ///
-  /// 64-bit processor-relative physical address of the S3 Performance Table.
-  ///
-  UINT64                                          S3PerformanceTablePointer;
-} EFI_ACPI_5_1_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD;
-
-///
-/// FPDT Firmware Basic Boot Performance Record Structure
-///
-typedef struct {
-  EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  UINT32                                          Reserved;
-  ///
-  /// Timer value logged at the beginning of firmware image execution.
-  /// This may not always be zero or near zero.
-  ///
-  UINT64                                          ResetEnd;
-  ///
-  /// Timer value logged just prior to loading the OS boot loader into memory.
-  /// For non-UEFI compatible boots, this field must be zero.
-  ///
-  UINT64                                          OsLoaderLoadImageStart;
-  ///
-  /// Timer value logged just prior to launching the previously loaded OS boot loader image.
-  /// For non-UEFI compatible boots, the timer value logged will be just prior
-  /// to the INT 19h handler invocation.
-  ///
-  UINT64                                          OsLoaderStartImageStart;
-  ///
-  /// Timer value logged at the point when the OS loader calls the
-  /// ExitBootServices function for UEFI compatible firmware.
-  /// For non-UEFI compatible boots, this field must be zero.
-  ///
-  UINT64                                          ExitBootServicesEntry;
-  ///
-  /// Timer value logged at the point just prior towhen the OS loader gaining
-  /// control back from calls the ExitBootServices function for UEFI compatible firmware.
-  /// For non-UEFI compatible boots, this field must be zero.
-  ///
-  UINT64                                          ExitBootServicesExit;
-} EFI_ACPI_5_1_FPDT_FIRMWARE_BASIC_BOOT_RECORD;
-
-///
-/// FPDT Firmware Basic Boot Performance Table signature
-///
-#define EFI_ACPI_5_1_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE  SIGNATURE_32('F', 'B', 'P', 'T')
-
-//
-// FPDT Firmware Basic Boot Performance Table
-//
-typedef struct {
-  EFI_ACPI_5_1_FPDT_PERFORMANCE_TABLE_HEADER      Header;
-  //
-  // one or more Performance Records.
-  //
-} EFI_ACPI_5_1_FPDT_FIRMWARE_BASIC_BOOT_TABLE;
-
-///
-/// FPDT "S3PT" S3 Performance Table
-///
-#define EFI_ACPI_5_1_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE  SIGNATURE_32('S', '3', 'P', 'T')
-
-//
-// FPDT Firmware S3 Boot Performance Table
-//
-typedef struct {
-  EFI_ACPI_5_1_FPDT_PERFORMANCE_TABLE_HEADER      Header;
-  //
-  // one or more Performance Records.
-  //
-} EFI_ACPI_5_1_FPDT_FIRMWARE_S3_BOOT_TABLE;
-
-///
-/// FPDT Basic S3 Resume Performance Record
-///
-typedef struct {
-  EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  ///
-  /// A count of the number of S3 resume cycles since the last full boot sequence.
-  ///
-  UINT32                                          ResumeCount;
-  ///
-  /// Timer recorded at the end of BIOS S3 resume, just prior to handoff to the
-  /// OS waking vector. Only the most recent resume cycle's time is retained.
-  ///
-  UINT64                                          FullResume;
-  ///
-  /// Average timer value of all resume cycles logged since the last full boot
-  /// sequence, including the most recent resume.  Note that the entire log of
-  /// timer values does not need to be retained in order to calculate this average.
-  ///
-  UINT64                                          AverageResume;
-} EFI_ACPI_5_1_FPDT_S3_RESUME_RECORD;
-
-///
-/// FPDT Basic S3 Suspend Performance Record
-///
-typedef struct {
-  EFI_ACPI_5_1_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  ///
-  /// Timer value recorded at the OS write to SLP_TYP upon entry to S3.
-  /// Only the most recent suspend cycle's timer value is retained.
-  ///
-  UINT64                                          SuspendStart;
-  ///
-  /// Timer value recorded at the final firmware write to SLP_TYP (or other
-  /// mechanism) used to trigger hardware entry to S3.
-  /// Only the most recent suspend cycle's timer value is retained.
-  ///
-  UINT64                                          SuspendEnd;
-} EFI_ACPI_5_1_FPDT_S3_SUSPEND_RECORD;
-
-///
-/// Firmware Performance Record Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-} EFI_ACPI_5_1_FIRMWARE_PERFORMANCE_RECORD_TABLE;
-
-///
-/// Generic Timer Description Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT64                      CntControlBasePhysicalAddress;
-  UINT32                      Reserved;
-  UINT32                      SecurePL1TimerGSIV;
-  UINT32                      SecurePL1TimerFlags;
-  UINT32                      NonSecurePL1TimerGSIV;
-  UINT32                      NonSecurePL1TimerFlags;
-  UINT32                      VirtualTimerGSIV;
-  UINT32                      VirtualTimerFlags;
-  UINT32                      NonSecurePL2TimerGSIV;
-  UINT32                      NonSecurePL2TimerFlags;
-  UINT64                      CntReadBasePhysicalAddress;
-  UINT32                      PlatformTimerCount;
-  UINT32                      PlatformTimerOffset;
-} EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE;
-
-///
-/// GTDT Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION 0x02
-
-///
-/// Timer Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE          BIT0
-#define EFI_ACPI_5_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY      BIT1
-#define EFI_ACPI_5_1_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY          BIT2
-
-///
-/// Platform Timer Type
-///
-#define EFI_ACPI_5_1_GTDT_GT_BLOCK                       0
-#define EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG          1
-
-///
-/// GT Block Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT16  Length;
-  UINT8   Reserved;
-  UINT64  CntCtlBase;
-  UINT32  GTBlockTimerCount;
-  UINT32  GTBlockTimerOffset;
-} EFI_ACPI_5_1_GTDT_GT_BLOCK_STRUCTURE;
-
-///
-/// GT Block Timer Structure
-///
-typedef struct {
-  UINT8   GTFrameNumber;
-  UINT8   Reserved[3];
-  UINT64  CntBaseX;
-  UINT64  CntEL0BaseX;
-  UINT32  GTxPhysicalTimerGSIV;
-  UINT32  GTxPhysicalTimerFlags;
-  UINT32  GTxVirtualTimerGSIV;
-  UINT32  GTxVirtualTimerFlags;
-  UINT32  GTxCommonFlags;
-} EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_STRUCTURE;
-
-///
-/// GT Block Physical Timers and Virtual Timers Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE          BIT0
-#define EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY      BIT1
-
-///
-/// Common Flags Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_1_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER              BIT0
-#define EFI_ACPI_5_1_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY      BIT1
-
-///
-/// SBSA Generic Watchdog Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT16  Length;
-  UINT8   Reserved;
-  UINT64  RefreshFramePhysicalAddress;
-  UINT64  WatchdogControlFramePhysicalAddress;
-  UINT32  WatchdogTimerGSIV;
-  UINT32  WatchdogTimerFlags;
-} EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE;
-
-///
-/// SBSA Generic Watchdog Timer Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE          BIT0
-#define EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY      BIT1
-#define EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER                  BIT2
-
-///
-/// Boot Error Record Table (BERT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      BootErrorRegionLength;
-  UINT64                      BootErrorRegion;
-} EFI_ACPI_5_1_BOOT_ERROR_RECORD_TABLE_HEADER;
-
-///
-/// BERT Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_BOOT_ERROR_RECORD_TABLE_REVISION 0x01
-
-///
-/// Boot Error Region Block Status Definition
-///
-typedef struct {
-  UINT32       UncorrectableErrorValid:1;
-  UINT32       CorrectableErrorValid:1;
-  UINT32       MultipleUncorrectableErrors:1;
-  UINT32       MultipleCorrectableErrors:1;
-  UINT32       ErrorDataEntryCount:10;
-  UINT32       Reserved:18;
-} EFI_ACPI_5_1_ERROR_BLOCK_STATUS;
-
-///
-/// Boot Error Region Definition
-///
-typedef struct {
-  EFI_ACPI_5_1_ERROR_BLOCK_STATUS              BlockStatus;
-  UINT32                                       RawDataOffset;
-  UINT32                                       RawDataLength;
-  UINT32                                       DataLength;
-  UINT32                                       ErrorSeverity;
-} EFI_ACPI_5_1_BOOT_ERROR_REGION_STRUCTURE;
-
-//
-// Boot Error Severity types
-//
-#define EFI_ACPI_5_1_ERROR_SEVERITY_CORRECTABLE  0x00
-#define EFI_ACPI_5_1_ERROR_SEVERITY_FATAL        0x01
-#define EFI_ACPI_5_1_ERROR_SEVERITY_CORRECTED    0x02
-#define EFI_ACPI_5_1_ERROR_SEVERITY_NONE         0x03
-
-///
-/// Generic Error Data Entry Definition
-///
-typedef struct {
-  UINT8    SectionType[16];
-  UINT32   ErrorSeverity;
-  UINT16   Revision;
-  UINT8    ValidationBits;
-  UINT8    Flags;
-  UINT32   ErrorDataLength;
-  UINT8    FruId[16];
-  UINT8    FruText[20];
-} EFI_ACPI_5_1_GENERIC_ERROR_DATA_ENTRY_STRUCTURE;
-
-///
-/// Generic Error Data Entry Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_GENERIC_ERROR_DATA_ENTRY_REVISION  0x0201
-
-///
-/// HEST - Hardware Error Source Table
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      ErrorSourceCount;
-} EFI_ACPI_5_1_HARDWARE_ERROR_SOURCE_TABLE_HEADER;
-
-///
-/// HEST Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01
-
-//
-// Error Source structure types.
-//
-#define EFI_ACPI_5_1_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION  0x00
-#define EFI_ACPI_5_1_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK  0x01
-#define EFI_ACPI_5_1_IA32_ARCHITECTURE_NMI_ERROR                0x02
-#define EFI_ACPI_5_1_PCI_EXPRESS_ROOT_PORT_AER                  0x06
-#define EFI_ACPI_5_1_PCI_EXPRESS_DEVICE_AER                     0x07
-#define EFI_ACPI_5_1_PCI_EXPRESS_BRIDGE_AER                     0x08
-#define EFI_ACPI_5_1_GENERIC_HARDWARE_ERROR                     0x09
-
-//
-// Error Source structure flags.
-//
-#define EFI_ACPI_5_1_ERROR_SOURCE_FLAG_FIRMWARE_FIRST       (1 << 0)
-#define EFI_ACPI_5_1_ERROR_SOURCE_FLAG_GLOBAL               (1 << 1)
-
-///
-/// IA-32 Architecture Machine Check Exception Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT64  GlobalCapabilityInitData;
-  UINT64  GlobalControlInitData;
-  UINT8   NumberOfHardwareBanks;
-  UINT8   Reserved1[7];
-} EFI_ACPI_5_1_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE;
-
-///
-/// IA-32 Architecture Machine Check Bank Structure Definition
-///
-typedef struct {
-  UINT8   BankNumber;
-  UINT8   ClearStatusOnInitialization;
-  UINT8   StatusDataFormat;
-  UINT8   Reserved0;
-  UINT32  ControlRegisterMsrAddress;
-  UINT64  ControlInitData;
-  UINT32  StatusRegisterMsrAddress;
-  UINT32  AddressRegisterMsrAddress;
-  UINT32  MiscRegisterMsrAddress;
-} EFI_ACPI_5_1_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE;
-
-///
-/// IA-32 Architecture Machine Check Bank Structure MCA data format
-///
-#define EFI_ACPI_5_1_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_IA32      0x00
-#define EFI_ACPI_5_1_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_INTEL64   0x01
-#define EFI_ACPI_5_1_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_AMD64     0x02
-
-//
-// Hardware Error Notification types. All other values are reserved
-//
-#define EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_POLLED                0x00
-#define EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_EXTERNAL_INTERRUPT    0x01
-#define EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_LOCAL_INTERRUPT       0x02
-#define EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_SCI                   0x03
-#define EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_NMI                   0x04
-
-///
-/// Hardware Error Notification Configuration Write Enable Structure Definition
-///
-typedef struct {
-  UINT16    Type:1;
-  UINT16    PollInterval:1;
-  UINT16    SwitchToPollingThresholdValue:1;
-  UINT16    SwitchToPollingThresholdWindow:1;
-  UINT16    ErrorThresholdValue:1;
-  UINT16    ErrorThresholdWindow:1;
-  UINT16    Reserved:10;
-} EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE;
-
-///
-/// Hardware Error Notification Structure Definition
-///
-typedef struct {
-  UINT8                                                                          Type;
-  UINT8                                                                          Length;
-  EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE  ConfigurationWriteEnable;
-  UINT32                                                                         PollInterval;
-  UINT32                                                                         Vector;
-  UINT32                                                                         SwitchToPollingThresholdValue;
-  UINT32                                                                         SwitchToPollingThresholdWindow;
-  UINT32                                                                         ErrorThresholdValue;
-  UINT32                                                                         ErrorThresholdWindow;
-} EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_STRUCTURE;
-
-///
-/// IA-32 Architecture Corrected Machine Check Structure Definition
-///
-typedef struct {
-  UINT16                                                 Type;
-  UINT16                                                 SourceId;
-  UINT8                                                  Reserved0[2];
-  UINT8                                                  Flags;
-  UINT8                                                  Enabled;
-  UINT32                                                 NumberOfRecordsToPreAllocate;
-  UINT32                                                 MaxSectionsPerRecord;
-  EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_STRUCTURE     NotificationStructure;
-  UINT8                                                  NumberOfHardwareBanks;
-  UINT8                                                  Reserved1[3];
-} EFI_ACPI_5_1_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE;
-
-///
-/// IA-32 Architecture NMI Error Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  MaxRawDataLength;
-} EFI_ACPI_5_1_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE;
-
-///
-/// PCI Express Root Port AER Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  Bus;
-  UINT16  Device;
-  UINT16  Function;
-  UINT16  DeviceControl;
-  UINT8   Reserved1[2];
-  UINT32  UncorrectableErrorMask;
-  UINT32  UncorrectableErrorSeverity;
-  UINT32  CorrectableErrorMask;
-  UINT32  AdvancedErrorCapabilitiesAndControl;
-  UINT32  RootErrorCommand;
-} EFI_ACPI_5_1_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE;
-
-///
-/// PCI Express Device AER Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  Bus;
-  UINT16  Device;
-  UINT16  Function;
-  UINT16  DeviceControl;
-  UINT8   Reserved1[2];
-  UINT32  UncorrectableErrorMask;
-  UINT32  UncorrectableErrorSeverity;
-  UINT32  CorrectableErrorMask;
-  UINT32  AdvancedErrorCapabilitiesAndControl;
-} EFI_ACPI_5_1_PCI_EXPRESS_DEVICE_AER_STRUCTURE;
-
-///
-/// PCI Express Bridge AER Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  Bus;
-  UINT16  Device;
-  UINT16  Function;
-  UINT16  DeviceControl;
-  UINT8   Reserved1[2];
-  UINT32  UncorrectableErrorMask;
-  UINT32  UncorrectableErrorSeverity;
-  UINT32  CorrectableErrorMask;
-  UINT32  AdvancedErrorCapabilitiesAndControl;
-  UINT32  SecondaryUncorrectableErrorMask;
-  UINT32  SecondaryUncorrectableErrorSeverity;
-  UINT32  SecondaryAdvancedErrorCapabilitiesAndControl;
-} EFI_ACPI_5_1_PCI_EXPRESS_BRIDGE_AER_STRUCTURE;
-
-///
-/// Generic Hardware Error Source Structure Definition
-///
-typedef struct {
-  UINT16                                                 Type;
-  UINT16                                                 SourceId;
-  UINT16                                                 RelatedSourceId;
-  UINT8                                                  Flags;
-  UINT8                                                  Enabled;
-  UINT32                                                 NumberOfRecordsToPreAllocate;
-  UINT32                                                 MaxSectionsPerRecord;
-  UINT32                                                 MaxRawDataLength;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE                 ErrorStatusAddress;
-  EFI_ACPI_5_1_HARDWARE_ERROR_NOTIFICATION_STRUCTURE     NotificationStructure;
-  UINT32                                                 ErrorStatusBlockLength;
-} EFI_ACPI_5_1_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE;
-
-///
-/// Generic Error Status Definition
-///
-typedef struct {
-  EFI_ACPI_5_1_ERROR_BLOCK_STATUS              BlockStatus;
-  UINT32                                       RawDataOffset;
-  UINT32                                       RawDataLength;
-  UINT32                                       DataLength;
-  UINT32                                       ErrorSeverity;
-} EFI_ACPI_5_1_GENERIC_ERROR_STATUS_STRUCTURE;
-
-///
-/// ERST - Error Record Serialization Table
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      SerializationHeaderSize;
-  UINT8                       Reserved0[4];
-  UINT32                      InstructionEntryCount;
-} EFI_ACPI_5_1_ERROR_RECORD_SERIALIZATION_TABLE_HEADER;
-
-///
-/// ERST Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_ERROR_RECORD_SERIALIZATION_TABLE_REVISION 0x01
-
-///
-/// ERST Serialization Actions
-///
-#define EFI_ACPI_5_1_ERST_BEGIN_WRITE_OPERATION                    0x00
-#define EFI_ACPI_5_1_ERST_BEGIN_READ_OPERATION                     0x01
-#define EFI_ACPI_5_1_ERST_BEGIN_CLEAR_OPERATION                    0x02
-#define EFI_ACPI_5_1_ERST_END_OPERATION                            0x03
-#define EFI_ACPI_5_1_ERST_SET_RECORD_OFFSET                        0x04
-#define EFI_ACPI_5_1_ERST_EXECUTE_OPERATION                        0x05
-#define EFI_ACPI_5_1_ERST_CHECK_BUSY_STATUS                        0x06
-#define EFI_ACPI_5_1_ERST_GET_COMMAND_STATUS                       0x07
-#define EFI_ACPI_5_1_ERST_GET_RECORD_IDENTIFIER                    0x08
-#define EFI_ACPI_5_1_ERST_SET_RECORD_IDENTIFIER                    0x09
-#define EFI_ACPI_5_1_ERST_GET_RECORD_COUNT                         0x0A
-#define EFI_ACPI_5_1_ERST_BEGIN_DUMMY_WRITE_OPERATION              0x0B
-#define EFI_ACPI_5_1_ERST_GET_ERROR_LOG_ADDRESS_RANGE              0x0D
-#define EFI_ACPI_5_1_ERST_GET_ERROR_LOG_ADDRESS_RANGE_LENGTH       0x0E
-#define EFI_ACPI_5_1_ERST_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES   0x0F
-
-///
-/// ERST Action Command Status
-///
-#define EFI_ACPI_5_1_ERST_STATUS_SUCCESS                           0x00
-#define EFI_ACPI_5_1_ERST_STATUS_NOT_ENOUGH_SPACE                  0x01
-#define EFI_ACPI_5_1_ERST_STATUS_HARDWARE_NOT_AVAILABLE            0x02
-#define EFI_ACPI_5_1_ERST_STATUS_FAILED                            0x03
-#define EFI_ACPI_5_1_ERST_STATUS_RECORD_STORE_EMPTY                0x04
-#define EFI_ACPI_5_1_ERST_STATUS_RECORD_NOT_FOUND                  0x05
-
-///
-/// ERST Serialization Instructions
-///
-#define EFI_ACPI_5_1_ERST_READ_REGISTER                            0x00
-#define EFI_ACPI_5_1_ERST_READ_REGISTER_VALUE                      0x01
-#define EFI_ACPI_5_1_ERST_WRITE_REGISTER                           0x02
-#define EFI_ACPI_5_1_ERST_WRITE_REGISTER_VALUE                     0x03
-#define EFI_ACPI_5_1_ERST_NOOP                                     0x04
-#define EFI_ACPI_5_1_ERST_LOAD_VAR1                                0x05
-#define EFI_ACPI_5_1_ERST_LOAD_VAR2                                0x06
-#define EFI_ACPI_5_1_ERST_STORE_VAR1                               0x07
-#define EFI_ACPI_5_1_ERST_ADD                                      0x08
-#define EFI_ACPI_5_1_ERST_SUBTRACT                                 0x09
-#define EFI_ACPI_5_1_ERST_ADD_VALUE                                0x0A
-#define EFI_ACPI_5_1_ERST_SUBTRACT_VALUE                           0x0B
-#define EFI_ACPI_5_1_ERST_STALL                                    0x0C
-#define EFI_ACPI_5_1_ERST_STALL_WHILE_TRUE                         0x0D
-#define EFI_ACPI_5_1_ERST_SKIP_NEXT_INSTRUCTION_IF_TRUE            0x0E
-#define EFI_ACPI_5_1_ERST_GOTO                                     0x0F
-#define EFI_ACPI_5_1_ERST_SET_SRC_ADDRESS_BASE                     0x10
-#define EFI_ACPI_5_1_ERST_SET_DST_ADDRESS_BASE                     0x11
-#define EFI_ACPI_5_1_ERST_MOVE_DATA                                0x12
-
-///
-/// ERST Instruction Flags
-///
-#define EFI_ACPI_5_1_ERST_PRESERVE_REGISTER                        0x01
-
-///
-/// ERST Serialization Instruction Entry
-///
-typedef struct {
-  UINT8                                    SerializationAction;
-  UINT8                                    Instruction;
-  UINT8                                    Flags;
-  UINT8                                    Reserved0;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE   RegisterRegion;
-  UINT64                                   Value;
-  UINT64                                   Mask;
-} EFI_ACPI_5_1_ERST_SERIALIZATION_INSTRUCTION_ENTRY;
-
-///
-/// EINJ - Error Injection Table
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      InjectionHeaderSize;
-  UINT8                       InjectionFlags;
-  UINT8                       Reserved0[3];
-  UINT32                      InjectionEntryCount;
-} EFI_ACPI_5_1_ERROR_INJECTION_TABLE_HEADER;
-
-///
-/// EINJ Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_ERROR_INJECTION_TABLE_REVISION 0x01
-
-///
-/// EINJ Error Injection Actions
-///
-#define EFI_ACPI_5_1_EINJ_BEGIN_INJECTION_OPERATION                0x00
-#define EFI_ACPI_5_1_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE           0x01
-#define EFI_ACPI_5_1_EINJ_SET_ERROR_TYPE                           0x02
-#define EFI_ACPI_5_1_EINJ_GET_ERROR_TYPE                           0x03
-#define EFI_ACPI_5_1_EINJ_END_OPERATION                            0x04
-#define EFI_ACPI_5_1_EINJ_EXECUTE_OPERATION                        0x05
-#define EFI_ACPI_5_1_EINJ_CHECK_BUSY_STATUS                        0x06
-#define EFI_ACPI_5_1_EINJ_GET_COMMAND_STATUS                       0x07
-#define EFI_ACPI_5_1_EINJ_TRIGGER_ERROR                            0xFF
-
-///
-/// EINJ Action Command Status
-///
-#define EFI_ACPI_5_1_EINJ_STATUS_SUCCESS                           0x00
-#define EFI_ACPI_5_1_EINJ_STATUS_UNKNOWN_FAILURE                   0x01
-#define EFI_ACPI_5_1_EINJ_STATUS_INVALID_ACCESS                    0x02
-
-///
-/// EINJ Error Type Definition
-///
-#define EFI_ACPI_5_1_EINJ_ERROR_PROCESSOR_CORRECTABLE                 (1 << 0)
-#define EFI_ACPI_5_1_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_NONFATAL      (1 << 1)
-#define EFI_ACPI_5_1_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_FATAL         (1 << 2)
-#define EFI_ACPI_5_1_EINJ_ERROR_MEMORY_CORRECTABLE                    (1 << 3)
-#define EFI_ACPI_5_1_EINJ_ERROR_MEMORY_UNCORRECTABLE_NONFATAL         (1 << 4)
-#define EFI_ACPI_5_1_EINJ_ERROR_MEMORY_UNCORRECTABLE_FATAL            (1 << 5)
-#define EFI_ACPI_5_1_EINJ_ERROR_PCI_EXPRESS_CORRECTABLE               (1 << 6)
-#define EFI_ACPI_5_1_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_NONFATAL    (1 << 7)
-#define EFI_ACPI_5_1_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_FATAL       (1 << 8)
-#define EFI_ACPI_5_1_EINJ_ERROR_PLATFORM_CORRECTABLE                  (1 << 9)
-#define EFI_ACPI_5_1_EINJ_ERROR_PLATFORM_UNCORRECTABLE_NONFATAL       (1 << 10)
-#define EFI_ACPI_5_1_EINJ_ERROR_PLATFORM_UNCORRECTABLE_FATAL          (1 << 11)
-
-///
-/// EINJ Injection Instructions
-///
-#define EFI_ACPI_5_1_EINJ_READ_REGISTER                            0x00
-#define EFI_ACPI_5_1_EINJ_READ_REGISTER_VALUE                      0x01
-#define EFI_ACPI_5_1_EINJ_WRITE_REGISTER                           0x02
-#define EFI_ACPI_5_1_EINJ_WRITE_REGISTER_VALUE                     0x03
-#define EFI_ACPI_5_1_EINJ_NOOP                                     0x04
-
-///
-/// EINJ Instruction Flags
-///
-#define EFI_ACPI_5_1_EINJ_PRESERVE_REGISTER                        0x01
-
-///
-/// EINJ Injection Instruction Entry
-///
-typedef struct {
-  UINT8                                    InjectionAction;
-  UINT8                                    Instruction;
-  UINT8                                    Flags;
-  UINT8                                    Reserved0;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE   RegisterRegion;
-  UINT64                                   Value;
-  UINT64                                   Mask;
-} EFI_ACPI_5_1_EINJ_INJECTION_INSTRUCTION_ENTRY;
-
-///
-/// EINJ Trigger Action Table
-///
-typedef struct {
-  UINT32  HeaderSize;
-  UINT32  Revision;
-  UINT32  TableSize;
-  UINT32  EntryCount;
-} EFI_ACPI_5_1_EINJ_TRIGGER_ACTION_TABLE;
-
-///
-/// Platform Communications Channel Table (PCCT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      Flags;
-  UINT64                      Reserved;
-} EFI_ACPI_5_1_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER;
-
-///
-/// PCCT Version (as defined in ACPI 5.1 spec.)
-///
-#define EFI_ACPI_5_1_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION 0x01
-
-///
-/// PCCT Global Flags
-///
-#define EFI_ACPI_5_1_PCCT_FLAGS_SCI_DOORBELL                      BIT0
-
-//
-// PCCT Subspace type
-//
-#define EFI_ACPI_5_1_PCCT_SUBSPACE_TYPE_GENERIC  0x00
-
-///
-/// PCC Subspace Structure Header
-///
-typedef struct {
-  UINT8        Type;
-  UINT8        Length;
-} EFI_ACPI_5_1_PCCT_SUBSPACE_HEADER;
-
-///
-/// Generic Communications Subspace Structure
-///
-typedef struct {
-  UINT8                                    Type;
-  UINT8                                    Length;
-  UINT8                                    Reserved[6];
-  UINT64                                   BaseAddress;
-  UINT64                                   AddressLength;
-  EFI_ACPI_5_1_GENERIC_ADDRESS_STRUCTURE   DoorbellRegister;
-  UINT64                                   DoorbellPreserve;
-  UINT64                                   DoorbellWrite;
-  UINT32                                   NominalLatency;
-  UINT32                                   MaximumPeriodicAccessRate;
-  UINT16                                   MinimumRequestTurnaroundTime;
-} EFI_ACPI_5_1_PCCT_SUBSPACE_GENERIC;
-
-///
-/// Generic Communications Channel Shared Memory Region
-///
-
-typedef struct {
-  UINT8                                    Command;
-  UINT8                                    Reserved:7;
-  UINT8                                    GenerateSci:1;
-} EFI_ACPI_5_1_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND;
-
-typedef struct {
-  UINT8                                    CommandComplete:1;
-  UINT8                                    SciDoorbell:1;
-  UINT8                                    Error:1;
-  UINT8                                    PlatformNotification:1;
-  UINT8                                    Reserved:4;
-  UINT8                                    Reserved1;
-} EFI_ACPI_5_1_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS;
-
-typedef struct {
-  UINT32                                                    Signature;
-  EFI_ACPI_5_1_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND    Command;
-  EFI_ACPI_5_1_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS     Status;
-} EFI_ACPI_5_1_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER;
-
-//
-// Known table signatures
-//
-
-///
-/// "RSD PTR " Root System Description Pointer
-///
-#define EFI_ACPI_5_1_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE  SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ')
-
-///
-/// "APIC" Multiple APIC Description Table
-///
-#define EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('A', 'P', 'I', 'C')
-
-///
-/// "BERT" Boot Error Record Table
-///
-#define EFI_ACPI_5_1_BOOT_ERROR_RECORD_TABLE_SIGNATURE  SIGNATURE_32('B', 'E', 'R', 'T')
-
-///
-/// "BGRT" Boot Graphics Resource Table
-///
-#define EFI_ACPI_5_1_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE  SIGNATURE_32('B', 'G', 'R', 'T')
-
-///
-/// "CPEP" Corrected Platform Error Polling Table
-///
-#define EFI_ACPI_5_1_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE  SIGNATURE_32('C', 'P', 'E', 'P')
-
-///
-/// "DSDT" Differentiated System Description Table
-///
-#define EFI_ACPI_5_1_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('D', 'S', 'D', 'T')
-
-///
-/// "ECDT" Embedded Controller Boot Resources Table
-///
-#define EFI_ACPI_5_1_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE  SIGNATURE_32('E', 'C', 'D', 'T')
-
-///
-/// "EINJ" Error Injection Table
-///
-#define EFI_ACPI_5_1_ERROR_INJECTION_TABLE_SIGNATURE  SIGNATURE_32('E', 'I', 'N', 'J')
-
-///
-/// "ERST" Error Record Serialization Table
-///
-#define EFI_ACPI_5_1_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE  SIGNATURE_32('E', 'R', 'S', 'T')
-
-///
-/// "FACP" Fixed ACPI Description Table
-///
-#define EFI_ACPI_5_1_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('F', 'A', 'C', 'P')
-
-///
-/// "FACS" Firmware ACPI Control Structure
-///
-#define EFI_ACPI_5_1_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE  SIGNATURE_32('F', 'A', 'C', 'S')
-
-///
-/// "FPDT" Firmware Performance Data Table
-///
-#define EFI_ACPI_5_1_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE  SIGNATURE_32('F', 'P', 'D', 'T')
-
-///
-/// "GTDT" Generic Timer Description Table
-///
-#define EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('G', 'T', 'D', 'T')
-
-///
-/// "HEST" Hardware Error Source Table
-///
-#define EFI_ACPI_5_1_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE  SIGNATURE_32('H', 'E', 'S', 'T')
-
-///
-/// "MPST" Memory Power State Table
-///
-#define EFI_ACPI_5_1_MEMORY_POWER_STATE_TABLE_SIGNATURE  SIGNATURE_32('M', 'P', 'S', 'T')
-
-///
-/// "MSCT" Maximum System Characteristics Table
-///
-#define EFI_ACPI_5_1_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE  SIGNATURE_32('M', 'S', 'C', 'T')
-
-///
-/// "PMTT" Platform Memory Topology Table
-///
-#define EFI_ACPI_5_1_PLATFORM_MEMORY_TOPOLOGY_TABLE_SIGNATURE  SIGNATURE_32('P', 'M', 'T', 'T')
-
-///
-/// "PSDT" Persistent System Description Table
-///
-#define EFI_ACPI_5_1_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('P', 'S', 'D', 'T')
-
-///
-/// "RASF" ACPI RAS Feature Table
-///
-#define EFI_ACPI_5_1_ACPI_RAS_FEATURE_TABLE_SIGNATURE  SIGNATURE_32('R', 'A', 'S', 'F')
-
-///
-/// "RSDT" Root System Description Table
-///
-#define EFI_ACPI_5_1_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('R', 'S', 'D', 'T')
-
-///
-/// "SBST" Smart Battery Specification Table
-///
-#define EFI_ACPI_5_1_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE  SIGNATURE_32('S', 'B', 'S', 'T')
-
-///
-/// "SLIT" System Locality Information Table
-///
-#define EFI_ACPI_5_1_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE  SIGNATURE_32('S', 'L', 'I', 'T')
-
-///
-/// "SRAT" System Resource Affinity Table
-///
-#define EFI_ACPI_5_1_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE  SIGNATURE_32('S', 'R', 'A', 'T')
-
-///
-/// "SSDT" Secondary System Description Table
-///
-#define EFI_ACPI_5_1_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('S', 'S', 'D', 'T')
-
-///
-/// "XSDT" Extended System Description Table
-///
-#define EFI_ACPI_5_1_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('X', 'S', 'D', 'T')
-
-///
-/// "BOOT" MS Simple Boot Spec
-///
-#define EFI_ACPI_5_1_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE  SIGNATURE_32('B', 'O', 'O', 'T')
-
-///
-/// "CSRT" MS Core System Resource Table
-///
-#define EFI_ACPI_5_1_CORE_SYSTEM_RESOURCE_TABLE_SIGNATURE  SIGNATURE_32('C', 'S', 'R', 'T')
-
-///
-/// "DBG2" MS Debug Port 2 Spec
-///
-#define EFI_ACPI_5_1_DEBUG_PORT_2_TABLE_SIGNATURE  SIGNATURE_32('D', 'B', 'G', '2')
-
-///
-/// "DBGP" MS Debug Port Spec
-///
-#define EFI_ACPI_5_1_DEBUG_PORT_TABLE_SIGNATURE  SIGNATURE_32('D', 'B', 'G', 'P')
-
-///
-/// "DMAR" DMA Remapping Table
-///
-#define EFI_ACPI_5_1_DMA_REMAPPING_TABLE_SIGNATURE  SIGNATURE_32('D', 'M', 'A', 'R')
-
-///
-/// "DRTM" Dynamic Root of Trust for Measurement Table
-///
-#define EFI_ACPI_5_1_DYNAMIC_ROOT_OF_TRUST_FOR_MEASUREMENT_TABLE_SIGNATURE  SIGNATURE_32('D', 'R', 'T', 'M')
-
-///
-/// "ETDT" Event Timer Description Table
-///
-#define EFI_ACPI_5_1_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('E', 'T', 'D', 'T')
-
-///
-/// "HPET" IA-PC High Precision Event Timer Table
-///
-#define EFI_ACPI_5_1_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE  SIGNATURE_32('H', 'P', 'E', 'T')
-
-///
-/// "iBFT" iSCSI Boot Firmware Table
-///
-#define EFI_ACPI_5_1_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE  SIGNATURE_32('i', 'B', 'F', 'T')
-
-///
-/// "IVRS" I/O Virtualization Reporting Structure
-///
-#define EFI_ACPI_5_1_IO_VIRTUALIZATION_REPORTING_STRUCTURE_SIGNATURE  SIGNATURE_32('I', 'V', 'R', 'S')
-
-///
-/// "LPIT" Low Power Idle Table
-///
-#define EFI_ACPI_5_1_IO_LOW_POWER_IDLE_TABLE_STRUCTURE_SIGNATURE  SIGNATURE_32('L', 'P', 'I', 'T')
-
-///
-/// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
-///
-#define EFI_ACPI_5_1_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('M', 'C', 'F', 'G')
-
-///
-/// "MCHI" Management Controller Host Interface Table
-///
-#define EFI_ACPI_5_1_MANAGEMENT_CONTROLLER_HOST_INTERFACE_TABLE_SIGNATURE  SIGNATURE_32('M', 'C', 'H', 'I')
-
-///
-/// "MSDM" MS Data Management Table
-///
-#define EFI_ACPI_5_1_DATA_MANAGEMENT_TABLE_SIGNATURE  SIGNATURE_32('M', 'S', 'D', 'M')
-
-///
-/// "SLIC" MS Software Licensing Table Specification
-///
-#define EFI_ACPI_5_1_SOFTWARE_LICENSING_TABLE_SIGNATURE  SIGNATURE_32('S', 'L', 'I', 'C')
-
-///
-/// "SPCR" Serial Port Concole Redirection Table
-///
-#define EFI_ACPI_5_1_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE  SIGNATURE_32('S', 'P', 'C', 'R')
-
-///
-/// "SPMI" Server Platform Management Interface Table
-///
-#define EFI_ACPI_5_1_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE  SIGNATURE_32('S', 'P', 'M', 'I')
-
-///
-/// "TCPA" Trusted Computing Platform Alliance Capabilities Table
-///
-#define EFI_ACPI_5_1_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE  SIGNATURE_32('T', 'C', 'P', 'A')
-
-///
-/// "TPM2" Trusted Computing Platform 1 Table
-///
-#define EFI_ACPI_5_1_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE  SIGNATURE_32('T', 'P', 'M', '2')
-
-///
-/// "UEFI" UEFI ACPI Data Table
-///
-#define EFI_ACPI_5_1_UEFI_ACPI_DATA_TABLE_SIGNATURE  SIGNATURE_32('U', 'E', 'F', 'I')
-
-///
-/// "WAET" Windows ACPI Emulated Devices Table
-///
-#define EFI_ACPI_5_1_WINDOWS_ACPI_EMULATED_DEVICES_TABLE_SIGNATURE  SIGNATURE_32('W', 'A', 'E', 'T')
-
-///
-/// "WDAT" Watchdog Action Table
-///
-#define EFI_ACPI_5_1_WATCHDOG_ACTION_TABLE_SIGNATURE  SIGNATURE_32('W', 'D', 'A', 'T')
-
-///
-/// "WDRT" Watchdog Resource Table
-///
-#define EFI_ACPI_5_1_WATCHDOG_RESOURCE_TABLE_SIGNATURE  SIGNATURE_32('W', 'D', 'R', 'T')
-
-///
-/// "WPBT" MS Platform Binary Table
-///
-#define EFI_ACPI_5_1_PLATFORM_BINARY_TABLE_SIGNATURE  SIGNATURE_32('W', 'P', 'B', 'T')
-
-#pragma pack()
-
-#endif
diff --git a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi60.h b/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi60.h
deleted file mode 100644 (file)
index 18eb5f7..0000000
+++ /dev/null
@@ -1,2348 +0,0 @@
-/** @file
-  ACPI 6.0 definitions from the ACPI Specification Revision 6.0 April, 2015.
-
-  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
-  (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-**/
-
-#ifndef _ACPI_6_0_H_
-#define _ACPI_6_0_H_
-
-FILE_LICENCE ( BSD3 );
-
-#include <ipxe/efi/IndustryStandard/Acpi51.h>
-
-//
-// Ensure proper structure formats
-//
-#pragma pack(1)
-
-///
-/// ACPI 6.0 Generic Address Space definition
-///
-typedef struct {
-  UINT8   AddressSpaceId;
-  UINT8   RegisterBitWidth;
-  UINT8   RegisterBitOffset;
-  UINT8   AccessSize;
-  UINT64  Address;
-} EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE;
-
-//
-// Generic Address Space Address IDs
-//
-#define EFI_ACPI_6_0_SYSTEM_MEMORY              0
-#define EFI_ACPI_6_0_SYSTEM_IO                  1
-#define EFI_ACPI_6_0_PCI_CONFIGURATION_SPACE    2
-#define EFI_ACPI_6_0_EMBEDDED_CONTROLLER        3
-#define EFI_ACPI_6_0_SMBUS                      4
-#define EFI_ACPI_6_0_PLATFORM_COMMUNICATION_CHANNEL  0x0A
-#define EFI_ACPI_6_0_FUNCTIONAL_FIXED_HARDWARE       0x7F
-
-//
-// Generic Address Space Access Sizes
-//
-#define EFI_ACPI_6_0_UNDEFINED  0
-#define EFI_ACPI_6_0_BYTE       1
-#define EFI_ACPI_6_0_WORD       2
-#define EFI_ACPI_6_0_DWORD      3
-#define EFI_ACPI_6_0_QWORD      4
-
-//
-// ACPI 6.0 table structures
-//
-
-///
-/// Root System Description Pointer Structure
-///
-typedef struct {
-  UINT64  Signature;
-  UINT8   Checksum;
-  UINT8   OemId[6];
-  UINT8   Revision;
-  UINT32  RsdtAddress;
-  UINT32  Length;
-  UINT64  XsdtAddress;
-  UINT8   ExtendedChecksum;
-  UINT8   Reserved[3];
-} EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
-
-///
-/// RSD_PTR Revision (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02  ///< ACPISpec (Revision 6.0) says current value is 2
-
-///
-/// Common table header, this prefaces all ACPI tables, including FACS, but
-/// excluding the RSD PTR structure
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-} EFI_ACPI_6_0_COMMON_HEADER;
-
-//
-// Root System Description Table
-// No definition needed as it is a common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT32 table pointers.
-//
-
-///
-/// RSDT Revision (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
-
-//
-// Extended System Description Table
-// No definition needed as it is a common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a variable number of UINT64 table pointers.
-//
-
-///
-/// XSDT Revision (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Fixed ACPI Description Table Structure (FADT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER             Header;
-  UINT32                                  FirmwareCtrl;
-  UINT32                                  Dsdt;
-  UINT8                                   Reserved0;
-  UINT8                                   PreferredPmProfile;
-  UINT16                                  SciInt;
-  UINT32                                  SmiCmd;
-  UINT8                                   AcpiEnable;
-  UINT8                                   AcpiDisable;
-  UINT8                                   S4BiosReq;
-  UINT8                                   PstateCnt;
-  UINT32                                  Pm1aEvtBlk;
-  UINT32                                  Pm1bEvtBlk;
-  UINT32                                  Pm1aCntBlk;
-  UINT32                                  Pm1bCntBlk;
-  UINT32                                  Pm2CntBlk;
-  UINT32                                  PmTmrBlk;
-  UINT32                                  Gpe0Blk;
-  UINT32                                  Gpe1Blk;
-  UINT8                                   Pm1EvtLen;
-  UINT8                                   Pm1CntLen;
-  UINT8                                   Pm2CntLen;
-  UINT8                                   PmTmrLen;
-  UINT8                                   Gpe0BlkLen;
-  UINT8                                   Gpe1BlkLen;
-  UINT8                                   Gpe1Base;
-  UINT8                                   CstCnt;
-  UINT16                                  PLvl2Lat;
-  UINT16                                  PLvl3Lat;
-  UINT16                                  FlushSize;
-  UINT16                                  FlushStride;
-  UINT8                                   DutyOffset;
-  UINT8                                   DutyWidth;
-  UINT8                                   DayAlrm;
-  UINT8                                   MonAlrm;
-  UINT8                                   Century;
-  UINT16                                  IaPcBootArch;
-  UINT8                                   Reserved1;
-  UINT32                                  Flags;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE  ResetReg;
-  UINT8                                   ResetValue;
-  UINT16                                  ArmBootArch;
-  UINT8                                   MinorVersion;
-  UINT64                                  XFirmwareCtrl;
-  UINT64                                  XDsdt;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE  XPm1aEvtBlk;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE  XPm1bEvtBlk;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE  XPm1aCntBlk;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE  XPm1bCntBlk;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE  XPm2CntBlk;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE  XPmTmrBlk;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE  XGpe0Blk;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE  XGpe1Blk;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE  SleepControlReg;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE  SleepStatusReg;
-  UINT64                                  HypervisorVendorIdentity;
-} EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE;
-
-///
-/// FADT Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION  0x06
-#define EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION  0x00
-
-//
-// Fixed ACPI Description Table Preferred Power Management Profile
-//
-#define EFI_ACPI_6_0_PM_PROFILE_UNSPECIFIED         0
-#define EFI_ACPI_6_0_PM_PROFILE_DESKTOP             1
-#define EFI_ACPI_6_0_PM_PROFILE_MOBILE              2
-#define EFI_ACPI_6_0_PM_PROFILE_WORKSTATION         3
-#define EFI_ACPI_6_0_PM_PROFILE_ENTERPRISE_SERVER   4
-#define EFI_ACPI_6_0_PM_PROFILE_SOHO_SERVER         5
-#define EFI_ACPI_6_0_PM_PROFILE_APPLIANCE_PC        6
-#define EFI_ACPI_6_0_PM_PROFILE_PERFORMANCE_SERVER  7
-#define EFI_ACPI_6_0_PM_PROFILE_TABLET              8
-
-//
-// Fixed ACPI Description Table Boot Architecture Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_6_0_LEGACY_DEVICES              BIT0
-#define EFI_ACPI_6_0_8042                        BIT1
-#define EFI_ACPI_6_0_VGA_NOT_PRESENT             BIT2
-#define EFI_ACPI_6_0_MSI_NOT_SUPPORTED           BIT3
-#define EFI_ACPI_6_0_PCIE_ASPM_CONTROLS          BIT4
-#define EFI_ACPI_6_0_CMOS_RTC_NOT_PRESENT        BIT5
-
-//
-// Fixed ACPI Description Table Arm Boot Architecture Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_6_0_ARM_PSCI_COMPLIANT              BIT0
-#define EFI_ACPI_6_0_ARM_PSCI_USE_HVC                BIT1
-
-//
-// Fixed ACPI Description Table Fixed Feature Flags
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_6_0_WBINVD                                 BIT0
-#define EFI_ACPI_6_0_WBINVD_FLUSH                           BIT1
-#define EFI_ACPI_6_0_PROC_C1                                BIT2
-#define EFI_ACPI_6_0_P_LVL2_UP                              BIT3
-#define EFI_ACPI_6_0_PWR_BUTTON                             BIT4
-#define EFI_ACPI_6_0_SLP_BUTTON                             BIT5
-#define EFI_ACPI_6_0_FIX_RTC                                BIT6
-#define EFI_ACPI_6_0_RTC_S4                                 BIT7
-#define EFI_ACPI_6_0_TMR_VAL_EXT                            BIT8
-#define EFI_ACPI_6_0_DCK_CAP                                BIT9
-#define EFI_ACPI_6_0_RESET_REG_SUP                          BIT10
-#define EFI_ACPI_6_0_SEALED_CASE                            BIT11
-#define EFI_ACPI_6_0_HEADLESS                               BIT12
-#define EFI_ACPI_6_0_CPU_SW_SLP                             BIT13
-#define EFI_ACPI_6_0_PCI_EXP_WAK                            BIT14
-#define EFI_ACPI_6_0_USE_PLATFORM_CLOCK                     BIT15
-#define EFI_ACPI_6_0_S4_RTC_STS_VALID                       BIT16
-#define EFI_ACPI_6_0_REMOTE_POWER_ON_CAPABLE                BIT17
-#define EFI_ACPI_6_0_FORCE_APIC_CLUSTER_MODEL               BIT18
-#define EFI_ACPI_6_0_FORCE_APIC_PHYSICAL_DESTINATION_MODE   BIT19
-#define EFI_ACPI_6_0_HW_REDUCED_ACPI                        BIT20
-#define EFI_ACPI_6_0_LOW_POWER_S0_IDLE_CAPABLE              BIT21
-
-///
-/// Firmware ACPI Control Structure
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-  UINT32  HardwareSignature;
-  UINT32  FirmwareWakingVector;
-  UINT32  GlobalLock;
-  UINT32  Flags;
-  UINT64  XFirmwareWakingVector;
-  UINT8   Version;
-  UINT8   Reserved0[3];
-  UINT32  OspmFlags;
-  UINT8   Reserved1[24];
-} EFI_ACPI_6_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
-
-///
-/// FACS Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION  0x02
-
-///
-/// Firmware Control Structure Feature Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_6_0_S4BIOS_F                     BIT0
-#define EFI_ACPI_6_0_64BIT_WAKE_SUPPORTED_F       BIT1
-
-///
-/// OSPM Enabled Firmware Control Structure Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_6_0_OSPM_64BIT_WAKE_F            BIT0
-
-//
-// Differentiated System Description Table,
-// Secondary System Description Table
-// and Persistent System Description Table,
-// no definition needed as they are common description table header, the same with
-// EFI_ACPI_DESCRIPTION_HEADER, followed by a definition block.
-//
-#define EFI_ACPI_6_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION   0x02
-#define EFI_ACPI_6_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION        0x02
-
-///
-/// Multiple APIC Description Table header definition.  The rest of the table
-/// must be defined in a platform specific manner.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      LocalApicAddress;
-  UINT32                      Flags;
-} EFI_ACPI_6_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER;
-
-///
-/// MADT Revision (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x03
-
-///
-/// Multiple APIC Flags
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_6_0_PCAT_COMPAT         BIT0
-
-//
-// Multiple APIC Description Table APIC structure types
-// All other values between 0x0D and 0x7F are reserved and
-// will be ignored by OSPM. 0x80 ~ 0xFF are reserved for OEM.
-//
-#define EFI_ACPI_6_0_PROCESSOR_LOCAL_APIC           0x00
-#define EFI_ACPI_6_0_IO_APIC                        0x01
-#define EFI_ACPI_6_0_INTERRUPT_SOURCE_OVERRIDE      0x02
-#define EFI_ACPI_6_0_NON_MASKABLE_INTERRUPT_SOURCE  0x03
-#define EFI_ACPI_6_0_LOCAL_APIC_NMI                 0x04
-#define EFI_ACPI_6_0_LOCAL_APIC_ADDRESS_OVERRIDE    0x05
-#define EFI_ACPI_6_0_IO_SAPIC                       0x06
-#define EFI_ACPI_6_0_LOCAL_SAPIC                    0x07
-#define EFI_ACPI_6_0_PLATFORM_INTERRUPT_SOURCES     0x08
-#define EFI_ACPI_6_0_PROCESSOR_LOCAL_X2APIC         0x09
-#define EFI_ACPI_6_0_LOCAL_X2APIC_NMI               0x0A
-#define EFI_ACPI_6_0_GIC                            0x0B
-#define EFI_ACPI_6_0_GICD                           0x0C
-#define EFI_ACPI_6_0_GIC_MSI_FRAME                  0x0D
-#define EFI_ACPI_6_0_GICR                           0x0E
-#define EFI_ACPI_6_0_GIC_ITS                        0x0F
-
-//
-// APIC Structure Definitions
-//
-
-///
-/// Processor Local APIC Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorUid;
-  UINT8   ApicId;
-  UINT32  Flags;
-} EFI_ACPI_6_0_PROCESSOR_LOCAL_APIC_STRUCTURE;
-
-///
-/// Local APIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_6_0_LOCAL_APIC_ENABLED        BIT0
-
-///
-/// IO APIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   IoApicId;
-  UINT8   Reserved;
-  UINT32  IoApicAddress;
-  UINT32  GlobalSystemInterruptBase;
-} EFI_ACPI_6_0_IO_APIC_STRUCTURE;
-
-///
-/// Interrupt Source Override Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Bus;
-  UINT8   Source;
-  UINT32  GlobalSystemInterrupt;
-  UINT16  Flags;
-} EFI_ACPI_6_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE;
-
-///
-/// Platform Interrupt Sources Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT8   InterruptType;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT8   IoSapicVector;
-  UINT32  GlobalSystemInterrupt;
-  UINT32  PlatformInterruptSourceFlags;
-  UINT8   CpeiProcessorOverride;
-  UINT8   Reserved[31];
-} EFI_ACPI_6_0_PLATFORM_INTERRUPT_APIC_STRUCTURE;
-
-//
-// MPS INTI flags.
-// All other bits are reserved and must be set to 0.
-//
-#define EFI_ACPI_6_0_POLARITY      (3 << 0)
-#define EFI_ACPI_6_0_TRIGGER_MODE  (3 << 2)
-
-///
-/// Non-Maskable Interrupt Source Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT32  GlobalSystemInterrupt;
-} EFI_ACPI_6_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE;
-
-///
-/// Local APIC NMI Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorUid;
-  UINT16  Flags;
-  UINT8   LocalApicLint;
-} EFI_ACPI_6_0_LOCAL_APIC_NMI_STRUCTURE;
-
-///
-/// Local APIC Address Override Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved;
-  UINT64  LocalApicAddress;
-} EFI_ACPI_6_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
-
-///
-/// IO SAPIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   IoApicId;
-  UINT8   Reserved;
-  UINT32  GlobalSystemInterruptBase;
-  UINT64  IoSapicAddress;
-} EFI_ACPI_6_0_IO_SAPIC_STRUCTURE;
-
-///
-/// Local SAPIC Structure
-/// This struct followed by a null-terminated ASCII string - ACPI Processor UID String
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   AcpiProcessorId;
-  UINT8   LocalSapicId;
-  UINT8   LocalSapicEid;
-  UINT8   Reserved[3];
-  UINT32  Flags;
-  UINT32  ACPIProcessorUIDValue;
-} EFI_ACPI_6_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
-
-///
-/// Platform Interrupt Sources Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT8   InterruptType;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT8   IoSapicVector;
-  UINT32  GlobalSystemInterrupt;
-  UINT32  PlatformInterruptSourceFlags;
-} EFI_ACPI_6_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE;
-
-///
-/// Platform Interrupt Source Flags.
-/// All other bits are reserved and must be set to 0.
-///
-#define EFI_ACPI_6_0_CPEI_PROCESSOR_OVERRIDE          BIT0
-
-///
-/// Processor Local x2APIC Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Reserved[2];
-  UINT32  X2ApicId;
-  UINT32  Flags;
-  UINT32  AcpiProcessorUid;
-} EFI_ACPI_6_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE;
-
-///
-/// Local x2APIC NMI Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Flags;
-  UINT32  AcpiProcessorUid;
-  UINT8   LocalX2ApicLint;
-  UINT8   Reserved[3];
-} EFI_ACPI_6_0_LOCAL_X2APIC_NMI_STRUCTURE;
-
-///
-/// GIC Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved;
-  UINT32  CPUInterfaceNumber;
-  UINT32  AcpiProcessorUid;
-  UINT32  Flags;
-  UINT32  ParkingProtocolVersion;
-  UINT32  PerformanceInterruptGsiv;
-  UINT64  ParkedAddress;
-  UINT64  PhysicalBaseAddress;
-  UINT64  GICV;
-  UINT64  GICH;
-  UINT32  VGICMaintenanceInterrupt;
-  UINT64  GICRBaseAddress;
-  UINT64  MPIDR;
-  UINT8   ProcessorPowerEfficiencyClass;
-  UINT8   Reserved2[3];
-} EFI_ACPI_6_0_GIC_STRUCTURE;
-
-///
-/// GIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_6_0_GIC_ENABLED                              BIT0
-#define EFI_ACPI_6_0_PERFORMANCE_INTERRUPT_MODEL              BIT1
-#define EFI_ACPI_6_0_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS    BIT2
-
-///
-/// GIC Distributor Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved1;
-  UINT32  GicId;
-  UINT64  PhysicalBaseAddress;
-  UINT32  SystemVectorBase;
-  UINT8   GicVersion;
-  UINT8   Reserved2[3];
-} EFI_ACPI_6_0_GIC_DISTRIBUTOR_STRUCTURE;
-
-///
-/// GIC Version
-///
-#define EFI_ACPI_6_0_GIC_V1                                   0x01
-#define EFI_ACPI_6_0_GIC_V2                                   0x02
-#define EFI_ACPI_6_0_GIC_V3                                   0x03
-#define EFI_ACPI_6_0_GIC_V4                                   0x04
-
-///
-/// GIC MSI Frame Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved1;
-  UINT32  GicMsiFrameId;
-  UINT64  PhysicalBaseAddress;
-  UINT32  Flags;
-  UINT16  SPICount;
-  UINT16  SPIBase;
-} EFI_ACPI_6_0_GIC_MSI_FRAME_STRUCTURE;
-
-///
-/// GIC MSI Frame Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_6_0_SPI_COUNT_BASE_SELECT                    BIT0
-
-///
-/// GICR Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved;
-  UINT64  DiscoveryRangeBaseAddress;
-  UINT32  DiscoveryRangeLength;
-} EFI_ACPI_6_0_GICR_STRUCTURE;
-
-///
-/// GIC Interrupt Translation Service Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT16  Reserved;
-  UINT32  GicItsId;
-  UINT64  PhysicalBaseAddress;
-  UINT32  Reserved2;
-} EFI_ACPI_6_0_GIC_ITS_STRUCTURE;
-
-///
-/// Smart Battery Description Table (SBST)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      WarningEnergyLevel;
-  UINT32                      LowEnergyLevel;
-  UINT32                      CriticalEnergyLevel;
-} EFI_ACPI_6_0_SMART_BATTERY_DESCRIPTION_TABLE;
-
-///
-/// SBST Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01
-
-///
-/// Embedded Controller Boot Resources Table (ECDT)
-/// The table is followed by a null terminated ASCII string that contains
-/// a fully qualified reference to the name space object.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER             Header;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE  EcControl;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE  EcData;
-  UINT32                                  Uid;
-  UINT8                                   GpeBit;
-} EFI_ACPI_6_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE;
-
-///
-/// ECDT Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION  0x01
-
-///
-/// System Resource Affinity Table (SRAT).  The rest of the table
-/// must be defined in a platform specific manner.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      Reserved1;  ///< Must be set to 1
-  UINT64                      Reserved2;
-} EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER;
-
-///
-/// SRAT Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION  0x03
-
-//
-// SRAT structure types.
-// All other values between 0x04 an 0xFF are reserved and
-// will be ignored by OSPM.
-//
-#define EFI_ACPI_6_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY  0x00
-#define EFI_ACPI_6_0_MEMORY_AFFINITY                      0x01
-#define EFI_ACPI_6_0_PROCESSOR_LOCAL_X2APIC_AFFINITY      0x02
-#define EFI_ACPI_6_0_GICC_AFFINITY                        0x03
-
-///
-/// Processor Local APIC/SAPIC Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   ProximityDomain7To0;
-  UINT8   ApicId;
-  UINT32  Flags;
-  UINT8   LocalSapicEid;
-  UINT8   ProximityDomain31To8[3];
-  UINT32  ClockDomain;
-} EFI_ACPI_6_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE;
-
-///
-/// Local APIC/SAPIC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_6_0_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0)
-
-///
-/// Memory Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT32  ProximityDomain;
-  UINT16  Reserved1;
-  UINT32  AddressBaseLow;
-  UINT32  AddressBaseHigh;
-  UINT32  LengthLow;
-  UINT32  LengthHigh;
-  UINT32  Reserved2;
-  UINT32  Flags;
-  UINT64  Reserved3;
-} EFI_ACPI_6_0_MEMORY_AFFINITY_STRUCTURE;
-
-//
-// Memory Flags.  All other bits are reserved and must be 0.
-//
-#define EFI_ACPI_6_0_MEMORY_ENABLED       (1 << 0)
-#define EFI_ACPI_6_0_MEMORY_HOT_PLUGGABLE (1 << 1)
-#define EFI_ACPI_6_0_MEMORY_NONVOLATILE   (1 << 2)
-
-///
-/// Processor Local x2APIC Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   Reserved1[2];
-  UINT32  ProximityDomain;
-  UINT32  X2ApicId;
-  UINT32  Flags;
-  UINT32  ClockDomain;
-  UINT8   Reserved2[4];
-} EFI_ACPI_6_0_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE;
-
-///
-/// GICC Affinity Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT32  ProximityDomain;
-  UINT32  AcpiProcessorUid;
-  UINT32  Flags;
-  UINT32  ClockDomain;
-} EFI_ACPI_6_0_GICC_AFFINITY_STRUCTURE;
-
-///
-/// GICC Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_6_0_GICC_ENABLED (1 << 0)
-
-///
-/// System Locality Distance Information Table (SLIT).
-/// The rest of the table is a matrix.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT64                      NumberOfSystemLocalities;
-} EFI_ACPI_6_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER;
-
-///
-/// SLIT Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION  0x01
-
-///
-/// Corrected Platform Error Polling Table (CPEP)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT8                       Reserved[8];
-} EFI_ACPI_6_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_HEADER;
-
-///
-/// CPEP Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_REVISION 0x01
-
-//
-// CPEP processor structure types.
-//
-#define EFI_ACPI_6_0_CPEP_PROCESSOR_APIC_SAPIC  0x00
-
-///
-/// Corrected Platform Error Polling Processor Structure Definition
-///
-typedef struct {
-  UINT8   Type;
-  UINT8   Length;
-  UINT8   ProcessorId;
-  UINT8   ProcessorEid;
-  UINT32  PollingInterval;
-} EFI_ACPI_6_0_CPEP_PROCESSOR_APIC_SAPIC_STRUCTURE;
-
-///
-/// Maximum System Characteristics Table (MSCT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      OffsetProxDomInfo;
-  UINT32                      MaximumNumberOfProximityDomains;
-  UINT32                      MaximumNumberOfClockDomains;
-  UINT64                      MaximumPhysicalAddress;
-} EFI_ACPI_6_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_HEADER;
-
-///
-/// MSCT Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_REVISION 0x01
-
-///
-/// Maximum Proximity Domain Information Structure Definition
-///
-typedef struct {
-  UINT8   Revision;
-  UINT8   Length;
-  UINT32  ProximityDomainRangeLow;
-  UINT32  ProximityDomainRangeHigh;
-  UINT32  MaximumProcessorCapacity;
-  UINT64  MaximumMemoryCapacity;
-} EFI_ACPI_6_0_MAXIMUM_PROXIMITY_DOMAIN_INFORMATION_STRUCTURE;
-
-///
-/// ACPI RAS Feature Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT8                       PlatformCommunicationChannelIdentifier[12];
-} EFI_ACPI_6_0_RAS_FEATURE_TABLE;
-
-///
-/// RASF Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_RAS_FEATURE_TABLE_REVISION 0x01
-
-///
-/// ACPI RASF Platform Communication Channel Shared Memory Region definition.
-///
-typedef struct {
-  UINT32                      Signature;
-  UINT16                      Command;
-  UINT16                      Status;
-  UINT16                      Version;
-  UINT8                       RASCapabilities[16];
-  UINT8                       SetRASCapabilities[16];
-  UINT16                      NumberOfRASFParameterBlocks;
-  UINT32                      SetRASCapabilitiesStatus;
-} EFI_ACPI_6_0_RASF_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION;
-
-///
-/// ACPI RASF PCC command code
-///
-#define EFI_ACPI_6_0_RASF_PCC_COMMAND_CODE_EXECUTE_RASF_COMMAND  0x01
-
-///
-/// ACPI RASF Platform RAS Capabilities
-///
-#define EFI_ACPI_6_0_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED                          0x01
-#define EFI_ACPI_6_0_RASF_PLATFORM_RAS_CAPABILITY_HARDWARE_BASED_PATROL_SCRUB_SUPPOTED_AND_EXPOSED_TO_SOFTWARE  0x02
-
-///
-/// ACPI RASF Parameter Block structure for PATROL_SCRUB
-///
-typedef struct {
-  UINT16                      Type;
-  UINT16                      Version;
-  UINT16                      Length;
-  UINT16                      PatrolScrubCommand;
-  UINT64                      RequestedAddressRange[2];
-  UINT64                      ActualAddressRange[2];
-  UINT16                      Flags;
-  UINT8                       RequestedSpeed;
-} EFI_ACPI_6_0_RASF_PATROL_SCRUB_PLATFORM_BLOCK_STRUCTURE;
-
-///
-/// ACPI RASF Patrol Scrub command
-///
-#define EFI_ACPI_6_0_RASF_PATROL_SCRUB_COMMAND_GET_PATROL_PARAMETERS   0x01
-#define EFI_ACPI_6_0_RASF_PATROL_SCRUB_COMMAND_START_PATROL_SCRUBBER   0x02
-#define EFI_ACPI_6_0_RASF_PATROL_SCRUB_COMMAND_STOP_PATROL_SCRUBBER    0x03
-
-///
-/// Memory Power State Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT8                       PlatformCommunicationChannelIdentifier;
-  UINT8                       Reserved[3];
-// Memory Power Node Structure
-// Memory Power State Characteristics
-} EFI_ACPI_6_0_MEMORY_POWER_STATUS_TABLE;
-
-///
-/// MPST Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_MEMORY_POWER_STATE_TABLE_REVISION 0x01
-
-///
-/// MPST Platform Communication Channel Shared Memory Region definition.
-///
-typedef struct {
-  UINT32                      Signature;
-  UINT16                      Command;
-  UINT16                      Status;
-  UINT32                      MemoryPowerCommandRegister;
-  UINT32                      MemoryPowerStatusRegister;
-  UINT32                      PowerStateId;
-  UINT32                      MemoryPowerNodeId;
-  UINT64                      MemoryEnergyConsumed;
-  UINT64                      ExpectedAveragePowerComsuned;
-} EFI_ACPI_6_0_MPST_PLATFORM_COMMUNICATION_CHANNEL_SHARED_MEMORY_REGION;
-
-///
-/// ACPI MPST PCC command code
-///
-#define EFI_ACPI_6_0_MPST_PCC_COMMAND_CODE_EXECUTE_MPST_COMMAND  0x03
-
-///
-/// ACPI MPST Memory Power command
-///
-#define EFI_ACPI_6_0_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_POWER_STATE       0x01
-#define EFI_ACPI_6_0_MPST_MEMORY_POWER_COMMAND_SET_MEMORY_POWER_STATE       0x02
-#define EFI_ACPI_6_0_MPST_MEMORY_POWER_COMMAND_GET_AVERAGE_POWER_CONSUMED   0x03
-#define EFI_ACPI_6_0_MPST_MEMORY_POWER_COMMAND_GET_MEMORY_ENERGY_CONSUMED   0x04
-
-///
-/// MPST Memory Power Node Table
-///
-typedef struct {
-  UINT8                                             PowerStateValue;
-  UINT8                                             PowerStateInformationIndex;
-} EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE;
-
-typedef struct {
-  UINT8                                             Flag;
-  UINT8                                             Reserved;
-  UINT16                                            MemoryPowerNodeId;
-  UINT32                                            Length;
-  UINT64                                            AddressBase;
-  UINT64                                            AddressLength;
-  UINT32                                            NumberOfPowerStates;
-  UINT32                                            NumberOfPhysicalComponents;
-//EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE              MemoryPowerState[NumberOfPowerStates];
-//UINT16                                            PhysicalComponentIdentifier[NumberOfPhysicalComponents];
-} EFI_ACPI_6_0_MPST_MEMORY_POWER_STRUCTURE;
-
-#define EFI_ACPI_6_0_MPST_MEMORY_POWER_STRUCTURE_FLAG_ENABLE          0x01
-#define EFI_ACPI_6_0_MPST_MEMORY_POWER_STRUCTURE_FLAG_POWER_MANAGED   0x02
-#define EFI_ACPI_6_0_MPST_MEMORY_POWER_STRUCTURE_FLAG_HOT_PLUGGABLE   0x04
-
-typedef struct {
-  UINT16                      MemoryPowerNodeCount;
-  UINT8                       Reserved[2];
-} EFI_ACPI_6_0_MPST_MEMORY_POWER_NODE_TABLE;
-
-///
-/// MPST Memory Power State Characteristics Table
-///
-typedef struct {
-  UINT8                                             PowerStateStructureID;
-  UINT8                                             Flag;
-  UINT16                                            Reserved;
-  UINT32                                            AveragePowerConsumedInMPS0;
-  UINT32                                            RelativePowerSavingToMPS0;
-  UINT64                                            ExitLatencyToMPS0;
-} EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE;
-
-#define EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_MEMORY_CONTENT_PRESERVED              0x01
-#define EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_ENTRY   0x02
-#define EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_STRUCTURE_FLAG_AUTONOMOUS_MEMORY_POWER_STATE_EXIT    0x04
-
-typedef struct {
-  UINT16                      MemoryPowerStateCharacteristicsCount;
-  UINT8                       Reserved[2];
-} EFI_ACPI_6_0_MPST_MEMORY_POWER_STATE_CHARACTERISTICS_TABLE;
-
-///
-/// Memory Topology Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      Reserved;
-} EFI_ACPI_6_0_MEMORY_TOPOLOGY_TABLE;
-
-///
-/// PMTT Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_MEMORY_TOPOLOGY_TABLE_REVISION 0x01
-
-///
-/// Common Memory Aggregator Device Structure.
-///
-typedef struct {
-  UINT8                       Type;
-  UINT8                       Reserved;
-  UINT16                      Length;
-  UINT16                      Flags;
-  UINT16                      Reserved1;
-} EFI_ACPI_6_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
-
-///
-/// Memory Aggregator Device Type
-///
-#define EFI_ACPI_6_0_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_SOCKET            0x1
-#define EFI_ACPI_6_0_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_MEMORY_CONTROLLER 0x2
-#define EFI_ACPI_6_0_PMMT_MEMORY_AGGREGATOR_DEVICE_TYPE_DIMM              0x3
-
-///
-/// Socket Memory Aggregator Device Structure.
-///
-typedef struct {
-  EFI_ACPI_6_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE  Header;
-  UINT16                                                       SocketIdentifier;
-  UINT16                                                       Reserved;
-//EFI_ACPI_6_0_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE  MemoryController[];
-} EFI_ACPI_6_0_PMMT_SOCKET_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
-
-///
-/// MemoryController Memory Aggregator Device Structure.
-///
-typedef struct {
-  EFI_ACPI_6_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE  Header;
-  UINT32                                                       ReadLatency;
-  UINT32                                                       WriteLatency;
-  UINT32                                                       ReadBandwidth;
-  UINT32                                                       WriteBandwidth;
-  UINT16                                                       OptimalAccessUnit;
-  UINT16                                                       OptimalAccessAlignment;
-  UINT16                                                       Reserved;
-  UINT16                                                       NumberOfProximityDomains;
-//UINT32                                                       ProximityDomain[NumberOfProximityDomains];
-//EFI_ACPI_6_0_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE    PhysicalComponent[];
-} EFI_ACPI_6_0_PMMT_MEMORY_CONTROLLER_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
-
-///
-/// DIMM Memory Aggregator Device Structure.
-///
-typedef struct {
-  EFI_ACPI_6_0_PMMT_COMMON_MEMORY_AGGREGATOR_DEVICE_STRUCTURE  Header;
-  UINT16                                                       PhysicalComponentIdentifier;
-  UINT16                                                       Reserved;
-  UINT32                                                       SizeOfDimm;
-  UINT32                                                       SmbiosHandle;
-} EFI_ACPI_6_0_PMMT_DIMM_MEMORY_AGGREGATOR_DEVICE_STRUCTURE;
-
-///
-/// Boot Graphics Resource Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  ///
-  /// 2-bytes (16 bit) version ID. This value must be 1.
-  ///
-  UINT16                      Version;
-  ///
-  /// 1-byte status field indicating current status about the table.
-  ///     Bits[7:1] = Reserved (must be zero)
-  ///     Bit [0] = Valid. A one indicates the boot image graphic is valid.
-  ///
-  UINT8                       Status;
-  ///
-  /// 1-byte enumerated type field indicating format of the image.
-  ///     0 = Bitmap
-  ///     1 - 255  Reserved (for future use)
-  ///
-  UINT8                       ImageType;
-  ///
-  /// 8-byte (64 bit) physical address pointing to the firmware's in-memory copy
-  /// of the image bitmap.
-  ///
-  UINT64                      ImageAddress;
-  ///
-  /// A 4-byte (32-bit) unsigned long describing the display X-offset of the boot image.
-  /// (X, Y) display offset of the top left corner of the boot image.
-  /// The top left corner of the display is at offset (0, 0).
-  ///
-  UINT32                      ImageOffsetX;
-  ///
-  /// A 4-byte (32-bit) unsigned long describing the display Y-offset of the boot image.
-  /// (X, Y) display offset of the top left corner of the boot image.
-  /// The top left corner of the display is at offset (0, 0).
-  ///
-  UINT32                      ImageOffsetY;
-} EFI_ACPI_6_0_BOOT_GRAPHICS_RESOURCE_TABLE;
-
-///
-/// BGRT Revision
-///
-#define EFI_ACPI_6_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION 1
-
-///
-/// BGRT Version
-///
-#define EFI_ACPI_6_0_BGRT_VERSION         0x01
-
-///
-/// BGRT Status
-///
-#define EFI_ACPI_6_0_BGRT_STATUS_NOT_DISPLAYED 0x00
-#define EFI_ACPI_6_0_BGRT_STATUS_DISPLAYED     0x01
-
-///
-/// BGRT Image Type
-///
-#define EFI_ACPI_6_0_BGRT_IMAGE_TYPE_BMP  0x00
-
-///
-/// FPDT Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION 0x01
-
-///
-/// FPDT Performance Record Types
-///
-#define EFI_ACPI_6_0_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER      0x0000
-#define EFI_ACPI_6_0_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER     0x0001
-
-///
-/// FPDT Performance Record Revision
-///
-#define EFI_ACPI_6_0_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER  0x01
-#define EFI_ACPI_6_0_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER 0x01
-
-///
-/// FPDT Runtime Performance Record Types
-///
-#define EFI_ACPI_6_0_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME                0x0000
-#define EFI_ACPI_6_0_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND               0x0001
-#define EFI_ACPI_6_0_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT      0x0002
-
-///
-/// FPDT Runtime Performance Record Revision
-///
-#define EFI_ACPI_6_0_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME            0x01
-#define EFI_ACPI_6_0_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND           0x01
-#define EFI_ACPI_6_0_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT  0x02
-
-///
-/// FPDT Performance Record header
-///
-typedef struct {
-  UINT16           Type;
-  UINT8            Length;
-  UINT8            Revision;
-} EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER;
-
-///
-/// FPDT Performance Table header
-///
-typedef struct {
-  UINT32  Signature;
-  UINT32  Length;
-} EFI_ACPI_6_0_FPDT_PERFORMANCE_TABLE_HEADER;
-
-///
-/// FPDT Firmware Basic Boot Performance Pointer Record Structure
-///
-typedef struct {
-  EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  UINT32                                          Reserved;
-  ///
-  /// 64-bit processor-relative physical address of the Basic Boot Performance Table.
-  ///
-  UINT64                                          BootPerformanceTablePointer;
-} EFI_ACPI_6_0_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD;
-
-///
-/// FPDT S3 Performance Table Pointer Record Structure
-///
-typedef struct {
-  EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  UINT32                                          Reserved;
-  ///
-  /// 64-bit processor-relative physical address of the S3 Performance Table.
-  ///
-  UINT64                                          S3PerformanceTablePointer;
-} EFI_ACPI_6_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD;
-
-///
-/// FPDT Firmware Basic Boot Performance Record Structure
-///
-typedef struct {
-  EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  UINT32                                          Reserved;
-  ///
-  /// Timer value logged at the beginning of firmware image execution.
-  /// This may not always be zero or near zero.
-  ///
-  UINT64                                          ResetEnd;
-  ///
-  /// Timer value logged just prior to loading the OS boot loader into memory.
-  /// For non-UEFI compatible boots, this field must be zero.
-  ///
-  UINT64                                          OsLoaderLoadImageStart;
-  ///
-  /// Timer value logged just prior to launching the previously loaded OS boot loader image.
-  /// For non-UEFI compatible boots, the timer value logged will be just prior
-  /// to the INT 19h handler invocation.
-  ///
-  UINT64                                          OsLoaderStartImageStart;
-  ///
-  /// Timer value logged at the point when the OS loader calls the
-  /// ExitBootServices function for UEFI compatible firmware.
-  /// For non-UEFI compatible boots, this field must be zero.
-  ///
-  UINT64                                          ExitBootServicesEntry;
-  ///
-  /// Timer value logged at the point just prior towhen the OS loader gaining
-  /// control back from calls the ExitBootServices function for UEFI compatible firmware.
-  /// For non-UEFI compatible boots, this field must be zero.
-  ///
-  UINT64                                          ExitBootServicesExit;
-} EFI_ACPI_6_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD;
-
-///
-/// FPDT Firmware Basic Boot Performance Table signature
-///
-#define EFI_ACPI_6_0_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE  SIGNATURE_32('F', 'B', 'P', 'T')
-
-//
-// FPDT Firmware Basic Boot Performance Table
-//
-typedef struct {
-  EFI_ACPI_6_0_FPDT_PERFORMANCE_TABLE_HEADER      Header;
-  //
-  // one or more Performance Records.
-  //
-} EFI_ACPI_6_0_FPDT_FIRMWARE_BASIC_BOOT_TABLE;
-
-///
-/// FPDT "S3PT" S3 Performance Table
-///
-#define EFI_ACPI_6_0_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE  SIGNATURE_32('S', '3', 'P', 'T')
-
-//
-// FPDT Firmware S3 Boot Performance Table
-//
-typedef struct {
-  EFI_ACPI_6_0_FPDT_PERFORMANCE_TABLE_HEADER      Header;
-  //
-  // one or more Performance Records.
-  //
-} EFI_ACPI_6_0_FPDT_FIRMWARE_S3_BOOT_TABLE;
-
-///
-/// FPDT Basic S3 Resume Performance Record
-///
-typedef struct {
-  EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  ///
-  /// A count of the number of S3 resume cycles since the last full boot sequence.
-  ///
-  UINT32                                          ResumeCount;
-  ///
-  /// Timer recorded at the end of BIOS S3 resume, just prior to handoff to the
-  /// OS waking vector. Only the most recent resume cycle's time is retained.
-  ///
-  UINT64                                          FullResume;
-  ///
-  /// Average timer value of all resume cycles logged since the last full boot
-  /// sequence, including the most recent resume.  Note that the entire log of
-  /// timer values does not need to be retained in order to calculate this average.
-  ///
-  UINT64                                          AverageResume;
-} EFI_ACPI_6_0_FPDT_S3_RESUME_RECORD;
-
-///
-/// FPDT Basic S3 Suspend Performance Record
-///
-typedef struct {
-  EFI_ACPI_6_0_FPDT_PERFORMANCE_RECORD_HEADER     Header;
-  ///
-  /// Timer value recorded at the OS write to SLP_TYP upon entry to S3.
-  /// Only the most recent suspend cycle's timer value is retained.
-  ///
-  UINT64                                          SuspendStart;
-  ///
-  /// Timer value recorded at the final firmware write to SLP_TYP (or other
-  /// mechanism) used to trigger hardware entry to S3.
-  /// Only the most recent suspend cycle's timer value is retained.
-  ///
-  UINT64                                          SuspendEnd;
-} EFI_ACPI_6_0_FPDT_S3_SUSPEND_RECORD;
-
-///
-/// Firmware Performance Record Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-} EFI_ACPI_6_0_FIRMWARE_PERFORMANCE_RECORD_TABLE;
-
-///
-/// Generic Timer Description Table definition.
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT64                      CntControlBasePhysicalAddress;
-  UINT32                      Reserved;
-  UINT32                      SecurePL1TimerGSIV;
-  UINT32                      SecurePL1TimerFlags;
-  UINT32                      NonSecurePL1TimerGSIV;
-  UINT32                      NonSecurePL1TimerFlags;
-  UINT32                      VirtualTimerGSIV;
-  UINT32                      VirtualTimerFlags;
-  UINT32                      NonSecurePL2TimerGSIV;
-  UINT32                      NonSecurePL2TimerFlags;
-  UINT64                      CntReadBasePhysicalAddress;
-  UINT32                      PlatformTimerCount;
-  UINT32                      PlatformTimerOffset;
-} EFI_ACPI_6_0_GENERIC_TIMER_DESCRIPTION_TABLE;
-
-///
-/// GTDT Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION 0x02
-
-///
-/// Timer Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_6_0_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE          BIT0
-#define EFI_ACPI_6_0_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY      BIT1
-#define EFI_ACPI_6_0_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY          BIT2
-
-///
-/// Platform Timer Type
-///
-#define EFI_ACPI_6_0_GTDT_GT_BLOCK                       0
-#define EFI_ACPI_6_0_GTDT_SBSA_GENERIC_WATCHDOG          1
-
-///
-/// GT Block Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT16  Length;
-  UINT8   Reserved;
-  UINT64  CntCtlBase;
-  UINT32  GTBlockTimerCount;
-  UINT32  GTBlockTimerOffset;
-} EFI_ACPI_6_0_GTDT_GT_BLOCK_STRUCTURE;
-
-///
-/// GT Block Timer Structure
-///
-typedef struct {
-  UINT8   GTFrameNumber;
-  UINT8   Reserved[3];
-  UINT64  CntBaseX;
-  UINT64  CntEL0BaseX;
-  UINT32  GTxPhysicalTimerGSIV;
-  UINT32  GTxPhysicalTimerFlags;
-  UINT32  GTxVirtualTimerGSIV;
-  UINT32  GTxVirtualTimerFlags;
-  UINT32  GTxCommonFlags;
-} EFI_ACPI_6_0_GTDT_GT_BLOCK_TIMER_STRUCTURE;
-
-///
-/// GT Block Physical Timers and Virtual Timers Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_6_0_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE          BIT0
-#define EFI_ACPI_6_0_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY      BIT1
-
-///
-/// Common Flags Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_6_0_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER              BIT0
-#define EFI_ACPI_6_0_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY      BIT1
-
-///
-/// SBSA Generic Watchdog Structure
-///
-typedef struct {
-  UINT8   Type;
-  UINT16  Length;
-  UINT8   Reserved;
-  UINT64  RefreshFramePhysicalAddress;
-  UINT64  WatchdogControlFramePhysicalAddress;
-  UINT32  WatchdogTimerGSIV;
-  UINT32  WatchdogTimerFlags;
-} EFI_ACPI_6_0_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE;
-
-///
-/// SBSA Generic Watchdog Timer Flags.  All other bits are reserved and must be 0.
-///
-#define EFI_ACPI_6_0_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE          BIT0
-#define EFI_ACPI_6_0_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY      BIT1
-#define EFI_ACPI_6_0_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER                  BIT2
-
-//
-// NVDIMM Firmware Interface Table definition.
-//
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER    Header;
-  UINT32                         Reserved;
-} EFI_ACPI_6_0_NVDIMM_FIRMWARE_INTERFACE_TABLE;
-
-//
-// NFIT Version (as defined in ACPI 6.0 spec.)
-//
-#define EFI_ACPI_6_0_NVDIMM_FIRMWARE_INTERFACE_TABLE_REVISION 0x1
-
-//
-// Definition for NFIT Table Structure Types
-//
-#define EFI_ACPI_6_0_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE              0
-#define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_TO_SYSTEM_ADDRESS_RANGE_MAP_STRUCTURE_TYPE  1
-#define EFI_ACPI_6_0_NFIT_INTERLEAVE_STRUCTURE_TYPE                                 2
-#define EFI_ACPI_6_0_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE_TYPE              3
-#define EFI_ACPI_6_0_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE_TYPE                      4
-#define EFI_ACPI_6_0_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE_TYPE            5
-#define EFI_ACPI_6_0_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE_TYPE                         6
-
-//
-// Definition for NFIT Structure Header
-//
-typedef struct {
-  UINT16                                      Type;
-  UINT16                                      Length;
-} EFI_ACPI_6_0_NFIT_STRUCTURE_HEADER;
-
-//
-// Definition for System Physical Address Range Structure
-//
-#define EFI_ACPI_6_0_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_CONTROL_REGION_FOR_MANAGEMENT      BIT0
-#define EFI_ACPI_6_0_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_FLAGS_PROXIMITY_DOMAIN_VALID             BIT1
-#define EFI_ACPI_6_0_NFIT_GUID_VOLATILE_MEMORY_REGION                             { 0x7305944F, 0xFDDA, 0x44E3, { 0xB1, 0x6C, 0x3F, 0x22, 0xD2, 0x52, 0xE5, 0xD0 }}
-#define EFI_ACPI_6_0_NFIT_GUID_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_REGION          { 0x66F0D379, 0xB4F3, 0x4074, { 0xAC, 0x43, 0x0D, 0x33, 0x18, 0xB7, 0x8C, 0xDB }}
-#define EFI_ACPI_6_0_NFIT_GUID_NVDIMM_CONTROL_REGION                              { 0x92F701F6, 0x13B4, 0x405D, { 0x91, 0x0B, 0x29, 0x93, 0x67, 0xE8, 0x23, 0x4C }}
-#define EFI_ACPI_6_0_NFIT_GUID_NVDIMM_BLOCK_DATA_WINDOW_REGION                    { 0x91AF0530, 0x5D86, 0x470E, { 0xA6, 0xB0, 0x0A, 0x2D, 0xB9, 0x40, 0x82, 0x49 }}
-#define EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE   { 0x77AB535A, 0x45FC, 0x624B, { 0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }}
-#define EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE     { 0x3D5ABD30, 0x4175, 0x87CE, { 0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }}
-#define EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT { 0x5CEA02C9, 0x4D07, 0x69D3, { 0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }}
-#define EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT   { 0x08018188, 0x42CD, 0xBB48, { 0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }}
-typedef struct {
-  UINT16                                      Type;
-  UINT16                                      Length;
-  UINT16                                      SPARangeStructureIndex;
-  UINT16                                      Flags;
-  UINT32                                      Reserved_8;
-  UINT32                                      ProximityDomain;
-  GUID                                        AddressRangeTypeGUID;
-  UINT64                                      SystemPhysicalAddressRangeBase;
-  UINT64                                      SystemPhysicalAddressRangeLength;
-  UINT64                                      AddressRangeMemoryMappingAttribute;
-} EFI_ACPI_6_0_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE;
-
-//
-// Definition for Memory Device to System Physical Address Range Mapping Structure
-//
-typedef struct {
-  UINT32                                      DIMMNumber:4;
-  UINT32                                      MemoryChannelNumber:4;
-  UINT32                                      MemoryControllerID:4;
-  UINT32                                      SocketID:4;
-  UINT32                                      NodeControllerID:12;
-  UINT32                                      Reserved_28:4;
-} EFI_ACPI_6_0_NFIT_DEVICE_HANDLE;
-
-#define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_STATE_FLAGS_PREVIOUS_SAVE_FAIL                                      BIT0
-#define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_STATE_FLAGS_LAST_RESTORE_FAIL                                       BIT1
-#define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_STATE_FLAGS_PLATFORM_FLUSH_FAIL                                     BIT2
-#define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_STATE_FLAGS_NOT_ARMED_PRIOR_TO_OSPM_HAND_OFF                        BIT3
-#define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_STATE_FLAGS_SMART_HEALTH_EVENTS_PRIOR_OSPM_HAND_OFF                 BIT4
-#define EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_STATE_FLAGS_FIRMWARE_ENABLED_TO_NOTIFY_OSPM_ON_SMART_HEALTH_EVENTS  BIT5
-typedef struct {
-  UINT16                                      Type;
-  UINT16                                      Length;
-  EFI_ACPI_6_0_NFIT_DEVICE_HANDLE             NFITDeviceHandle;
-  UINT16                                      MemoryDevicePhysicalID;
-  UINT16                                      MemoryDeviceRegionID;
-  UINT16                                      SPARangeStructureIndex ;
-  UINT16                                      NVDIMMControlRegionStructureIndex;
-  UINT64                                      MemoryDeviceRegionSize;
-  UINT64                                      RegionOffset;
-  UINT64                                      MemoryDevicePhysicalAddressRegionBase;
-  UINT16                                      InterleaveStructureIndex;
-  UINT16                                      InterleaveWays;
-  UINT16                                      MemoryDeviceStateFlags;
-  UINT16                                      Reserved_46;
-} EFI_ACPI_6_0_NFIT_MEMORY_DEVICE_TO_SYSTEM_ADDRESS_RANGE_MAP_STRUCTURE;
-
-//
-// Definition for Interleave Structure
-//
-typedef struct {
-  UINT16                                      Type;
-  UINT16                                      Length;
-  UINT16                                      InterleaveStructureIndex;
-  UINT16                                      Reserved_6;
-  UINT32                                      NumberOfLines;
-  UINT32                                      LineSize;
-//UINT32                                      LineOffset[NumberOfLines];
-} EFI_ACPI_6_0_NFIT_INTERLEAVE_STRUCTURE;
-
-//
-// Definition for SMBIOS Management Information Structure
-//
-typedef struct {
-  UINT16                                      Type;
-  UINT16                                      Length;
-  UINT32                                      Reserved_4;
-//UINT8                                       Data[];
-} EFI_ACPI_6_0_NFIT_SMBIOS_MANAGEMENT_INFORMATION_STRUCTURE;
-
-//
-// Definition for NVDIMM Control Region Structure
-//
-#define EFI_ACPI_6_0_NFIT_NVDIMM_CONTROL_REGION_FLAGS_BLOCK_DATA_WINDOWS_BUFFERED    BIT0
-typedef struct {
-  UINT16                                      Type;
-  UINT16                                      Length;
-  UINT16                                      NVDIMMControlRegionStructureIndex;
-  UINT16                                      VendorID;
-  UINT16                                      DeviceID;
-  UINT16                                      RevisionID;
-  UINT16                                      SubsystemVendorID;
-  UINT16                                      SubsystemDeviceID;
-  UINT16                                      SubsystemRevisionID;
-  UINT8                                       Reserved_18[6];
-  UINT32                                      SerialNumber;
-  UINT16                                      RegionFormatInterfaceCode;
-  UINT16                                      NumberOfBlockControlWindows;
-  UINT64                                      SizeOfBlockControlWindow;
-  UINT64                                      CommandRegisterOffsetInBlockControlWindow;
-  UINT64                                      SizeOfCommandRegisterInBlockControlWindows;
-  UINT64                                      StatusRegisterOffsetInBlockControlWindow;
-  UINT64                                      SizeOfStatusRegisterInBlockControlWindows;
-  UINT16                                      NVDIMMControlRegionFlag;
-  UINT8                                       Reserved_74[6];
-} EFI_ACPI_6_0_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE;
-
-//
-// Definition for NVDIMM Block Data Window Region Structure
-//
-typedef struct {
-  UINT16                                      Type;
-  UINT16                                      Length;
-  UINT16                                      NVDIMMControlRegionStructureIndex;
-  UINT16                                      NumberOfBlockDataWindows;
-  UINT64                                      BlockDataWindowStartOffset;
-  UINT64                                      SizeOfBlockDataWindow;
-  UINT64                                      BlockAccessibleMemoryCapacity;
-  UINT64                                      BeginningAddressOfFirstBlockInBlockAccessibleMemory;
-} EFI_ACPI_6_0_NFIT_NVDIMM_BLOCK_DATA_WINDOW_REGION_STRUCTURE;
-
-//
-// Definition for Flush Hint Address Structure
-//
-typedef struct {
-  UINT16                                      Type;
-  UINT16                                      Length;
-  EFI_ACPI_6_0_NFIT_DEVICE_HANDLE             NFITDeviceHandle;
-  UINT16                                      NumberOfFlushHintAddresses;
-  UINT8                                       Reserved_10[6];
-//UINT64                                      FlushHintAddress[NumberOfFlushHintAddresses];
-} EFI_ACPI_6_0_NFIT_FLUSH_HINT_ADDRESS_STRUCTURE;
-
-///
-/// Boot Error Record Table (BERT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      BootErrorRegionLength;
-  UINT64                      BootErrorRegion;
-} EFI_ACPI_6_0_BOOT_ERROR_RECORD_TABLE_HEADER;
-
-///
-/// BERT Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_BOOT_ERROR_RECORD_TABLE_REVISION 0x01
-
-///
-/// Boot Error Region Block Status Definition
-///
-typedef struct {
-  UINT32       UncorrectableErrorValid:1;
-  UINT32       CorrectableErrorValid:1;
-  UINT32       MultipleUncorrectableErrors:1;
-  UINT32       MultipleCorrectableErrors:1;
-  UINT32       ErrorDataEntryCount:10;
-  UINT32       Reserved:18;
-} EFI_ACPI_6_0_ERROR_BLOCK_STATUS;
-
-///
-/// Boot Error Region Definition
-///
-typedef struct {
-  EFI_ACPI_6_0_ERROR_BLOCK_STATUS              BlockStatus;
-  UINT32                                       RawDataOffset;
-  UINT32                                       RawDataLength;
-  UINT32                                       DataLength;
-  UINT32                                       ErrorSeverity;
-} EFI_ACPI_6_0_BOOT_ERROR_REGION_STRUCTURE;
-
-//
-// Boot Error Severity types
-//
-#define EFI_ACPI_6_0_ERROR_SEVERITY_CORRECTABLE  0x00
-#define EFI_ACPI_6_0_ERROR_SEVERITY_FATAL        0x01
-#define EFI_ACPI_6_0_ERROR_SEVERITY_CORRECTED    0x02
-#define EFI_ACPI_6_0_ERROR_SEVERITY_NONE         0x03
-
-///
-/// Generic Error Data Entry Definition
-///
-typedef struct {
-  UINT8    SectionType[16];
-  UINT32   ErrorSeverity;
-  UINT16   Revision;
-  UINT8    ValidationBits;
-  UINT8    Flags;
-  UINT32   ErrorDataLength;
-  UINT8    FruId[16];
-  UINT8    FruText[20];
-} EFI_ACPI_6_0_GENERIC_ERROR_DATA_ENTRY_STRUCTURE;
-
-///
-/// Generic Error Data Entry Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_GENERIC_ERROR_DATA_ENTRY_REVISION  0x0201
-
-///
-/// HEST - Hardware Error Source Table
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      ErrorSourceCount;
-} EFI_ACPI_6_0_HARDWARE_ERROR_SOURCE_TABLE_HEADER;
-
-///
-/// HEST Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01
-
-//
-// Error Source structure types.
-//
-#define EFI_ACPI_6_0_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION  0x00
-#define EFI_ACPI_6_0_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK  0x01
-#define EFI_ACPI_6_0_IA32_ARCHITECTURE_NMI_ERROR                0x02
-#define EFI_ACPI_6_0_PCI_EXPRESS_ROOT_PORT_AER                  0x06
-#define EFI_ACPI_6_0_PCI_EXPRESS_DEVICE_AER                     0x07
-#define EFI_ACPI_6_0_PCI_EXPRESS_BRIDGE_AER                     0x08
-#define EFI_ACPI_6_0_GENERIC_HARDWARE_ERROR                     0x09
-
-//
-// Error Source structure flags.
-//
-#define EFI_ACPI_6_0_ERROR_SOURCE_FLAG_FIRMWARE_FIRST       (1 << 0)
-#define EFI_ACPI_6_0_ERROR_SOURCE_FLAG_GLOBAL               (1 << 1)
-
-///
-/// IA-32 Architecture Machine Check Exception Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT64  GlobalCapabilityInitData;
-  UINT64  GlobalControlInitData;
-  UINT8   NumberOfHardwareBanks;
-  UINT8   Reserved1[7];
-} EFI_ACPI_6_0_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE;
-
-///
-/// IA-32 Architecture Machine Check Bank Structure Definition
-///
-typedef struct {
-  UINT8   BankNumber;
-  UINT8   ClearStatusOnInitialization;
-  UINT8   StatusDataFormat;
-  UINT8   Reserved0;
-  UINT32  ControlRegisterMsrAddress;
-  UINT64  ControlInitData;
-  UINT32  StatusRegisterMsrAddress;
-  UINT32  AddressRegisterMsrAddress;
-  UINT32  MiscRegisterMsrAddress;
-} EFI_ACPI_6_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE;
-
-///
-/// IA-32 Architecture Machine Check Bank Structure MCA data format
-///
-#define EFI_ACPI_6_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_IA32      0x00
-#define EFI_ACPI_6_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_INTEL64   0x01
-#define EFI_ACPI_6_0_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_DATA_FORMAT_AMD64     0x02
-
-//
-// Hardware Error Notification types. All other values are reserved
-//
-#define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_POLLED                0x00
-#define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_EXTERNAL_INTERRUPT    0x01
-#define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_LOCAL_INTERRUPT       0x02
-#define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_SCI                   0x03
-#define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_NMI                   0x04
-#define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_CMCI                  0x05
-#define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_MCE                   0x06
-#define EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_GPIO_SIGNAL           0x07
-
-///
-/// Hardware Error Notification Configuration Write Enable Structure Definition
-///
-typedef struct {
-  UINT16    Type:1;
-  UINT16    PollInterval:1;
-  UINT16    SwitchToPollingThresholdValue:1;
-  UINT16    SwitchToPollingThresholdWindow:1;
-  UINT16    ErrorThresholdValue:1;
-  UINT16    ErrorThresholdWindow:1;
-  UINT16    Reserved:10;
-} EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE;
-
-///
-/// Hardware Error Notification Structure Definition
-///
-typedef struct {
-  UINT8                                                                          Type;
-  UINT8                                                                          Length;
-  EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_CONFIGURATION_WRITE_ENABLE_STRUCTURE  ConfigurationWriteEnable;
-  UINT32                                                                         PollInterval;
-  UINT32                                                                         Vector;
-  UINT32                                                                         SwitchToPollingThresholdValue;
-  UINT32                                                                         SwitchToPollingThresholdWindow;
-  UINT32                                                                         ErrorThresholdValue;
-  UINT32                                                                         ErrorThresholdWindow;
-} EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE;
-
-///
-/// IA-32 Architecture Corrected Machine Check Structure Definition
-///
-typedef struct {
-  UINT16                                                 Type;
-  UINT16                                                 SourceId;
-  UINT8                                                  Reserved0[2];
-  UINT8                                                  Flags;
-  UINT8                                                  Enabled;
-  UINT32                                                 NumberOfRecordsToPreAllocate;
-  UINT32                                                 MaxSectionsPerRecord;
-  EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE     NotificationStructure;
-  UINT8                                                  NumberOfHardwareBanks;
-  UINT8                                                  Reserved1[3];
-} EFI_ACPI_6_0_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE;
-
-///
-/// IA-32 Architecture NMI Error Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  MaxRawDataLength;
-} EFI_ACPI_6_0_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE;
-
-///
-/// PCI Express Root Port AER Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  Bus;
-  UINT16  Device;
-  UINT16  Function;
-  UINT16  DeviceControl;
-  UINT8   Reserved1[2];
-  UINT32  UncorrectableErrorMask;
-  UINT32  UncorrectableErrorSeverity;
-  UINT32  CorrectableErrorMask;
-  UINT32  AdvancedErrorCapabilitiesAndControl;
-  UINT32  RootErrorCommand;
-} EFI_ACPI_6_0_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE;
-
-///
-/// PCI Express Device AER Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  Bus;
-  UINT16  Device;
-  UINT16  Function;
-  UINT16  DeviceControl;
-  UINT8   Reserved1[2];
-  UINT32  UncorrectableErrorMask;
-  UINT32  UncorrectableErrorSeverity;
-  UINT32  CorrectableErrorMask;
-  UINT32  AdvancedErrorCapabilitiesAndControl;
-} EFI_ACPI_6_0_PCI_EXPRESS_DEVICE_AER_STRUCTURE;
-
-///
-/// PCI Express Bridge AER Structure Definition
-///
-typedef struct {
-  UINT16  Type;
-  UINT16  SourceId;
-  UINT8   Reserved0[2];
-  UINT8   Flags;
-  UINT8   Enabled;
-  UINT32  NumberOfRecordsToPreAllocate;
-  UINT32  MaxSectionsPerRecord;
-  UINT32  Bus;
-  UINT16  Device;
-  UINT16  Function;
-  UINT16  DeviceControl;
-  UINT8   Reserved1[2];
-  UINT32  UncorrectableErrorMask;
-  UINT32  UncorrectableErrorSeverity;
-  UINT32  CorrectableErrorMask;
-  UINT32  AdvancedErrorCapabilitiesAndControl;
-  UINT32  SecondaryUncorrectableErrorMask;
-  UINT32  SecondaryUncorrectableErrorSeverity;
-  UINT32  SecondaryAdvancedErrorCapabilitiesAndControl;
-} EFI_ACPI_6_0_PCI_EXPRESS_BRIDGE_AER_STRUCTURE;
-
-///
-/// Generic Hardware Error Source Structure Definition
-///
-typedef struct {
-  UINT16                                                 Type;
-  UINT16                                                 SourceId;
-  UINT16                                                 RelatedSourceId;
-  UINT8                                                  Flags;
-  UINT8                                                  Enabled;
-  UINT32                                                 NumberOfRecordsToPreAllocate;
-  UINT32                                                 MaxSectionsPerRecord;
-  UINT32                                                 MaxRawDataLength;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE                 ErrorStatusAddress;
-  EFI_ACPI_6_0_HARDWARE_ERROR_NOTIFICATION_STRUCTURE     NotificationStructure;
-  UINT32                                                 ErrorStatusBlockLength;
-} EFI_ACPI_6_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE;
-
-///
-/// Generic Error Status Definition
-///
-typedef struct {
-  EFI_ACPI_6_0_ERROR_BLOCK_STATUS              BlockStatus;
-  UINT32                                       RawDataOffset;
-  UINT32                                       RawDataLength;
-  UINT32                                       DataLength;
-  UINT32                                       ErrorSeverity;
-} EFI_ACPI_6_0_GENERIC_ERROR_STATUS_STRUCTURE;
-
-///
-/// ERST - Error Record Serialization Table
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      SerializationHeaderSize;
-  UINT8                       Reserved0[4];
-  UINT32                      InstructionEntryCount;
-} EFI_ACPI_6_0_ERROR_RECORD_SERIALIZATION_TABLE_HEADER;
-
-///
-/// ERST Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_ERROR_RECORD_SERIALIZATION_TABLE_REVISION 0x01
-
-///
-/// ERST Serialization Actions
-///
-#define EFI_ACPI_6_0_ERST_BEGIN_WRITE_OPERATION                    0x00
-#define EFI_ACPI_6_0_ERST_BEGIN_READ_OPERATION                     0x01
-#define EFI_ACPI_6_0_ERST_BEGIN_CLEAR_OPERATION                    0x02
-#define EFI_ACPI_6_0_ERST_END_OPERATION                            0x03
-#define EFI_ACPI_6_0_ERST_SET_RECORD_OFFSET                        0x04
-#define EFI_ACPI_6_0_ERST_EXECUTE_OPERATION                        0x05
-#define EFI_ACPI_6_0_ERST_CHECK_BUSY_STATUS                        0x06
-#define EFI_ACPI_6_0_ERST_GET_COMMAND_STATUS                       0x07
-#define EFI_ACPI_6_0_ERST_GET_RECORD_IDENTIFIER                    0x08
-#define EFI_ACPI_6_0_ERST_SET_RECORD_IDENTIFIER                    0x09
-#define EFI_ACPI_6_0_ERST_GET_RECORD_COUNT                         0x0A
-#define EFI_ACPI_6_0_ERST_BEGIN_DUMMY_WRITE_OPERATION              0x0B
-#define EFI_ACPI_6_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE              0x0D
-#define EFI_ACPI_6_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE_LENGTH       0x0E
-#define EFI_ACPI_6_0_ERST_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES   0x0F
-
-///
-/// ERST Action Command Status
-///
-#define EFI_ACPI_6_0_ERST_STATUS_SUCCESS                           0x00
-#define EFI_ACPI_6_0_ERST_STATUS_NOT_ENOUGH_SPACE                  0x01
-#define EFI_ACPI_6_0_ERST_STATUS_HARDWARE_NOT_AVAILABLE            0x02
-#define EFI_ACPI_6_0_ERST_STATUS_FAILED                            0x03
-#define EFI_ACPI_6_0_ERST_STATUS_RECORD_STORE_EMPTY                0x04
-#define EFI_ACPI_6_0_ERST_STATUS_RECORD_NOT_FOUND                  0x05
-
-///
-/// ERST Serialization Instructions
-///
-#define EFI_ACPI_6_0_ERST_READ_REGISTER                            0x00
-#define EFI_ACPI_6_0_ERST_READ_REGISTER_VALUE                      0x01
-#define EFI_ACPI_6_0_ERST_WRITE_REGISTER                           0x02
-#define EFI_ACPI_6_0_ERST_WRITE_REGISTER_VALUE                     0x03
-#define EFI_ACPI_6_0_ERST_NOOP                                     0x04
-#define EFI_ACPI_6_0_ERST_LOAD_VAR1                                0x05
-#define EFI_ACPI_6_0_ERST_LOAD_VAR2                                0x06
-#define EFI_ACPI_6_0_ERST_STORE_VAR1                               0x07
-#define EFI_ACPI_6_0_ERST_ADD                                      0x08
-#define EFI_ACPI_6_0_ERST_SUBTRACT                                 0x09
-#define EFI_ACPI_6_0_ERST_ADD_VALUE                                0x0A
-#define EFI_ACPI_6_0_ERST_SUBTRACT_VALUE                           0x0B
-#define EFI_ACPI_6_0_ERST_STALL                                    0x0C
-#define EFI_ACPI_6_0_ERST_STALL_WHILE_TRUE                         0x0D
-#define EFI_ACPI_6_0_ERST_SKIP_NEXT_INSTRUCTION_IF_TRUE            0x0E
-#define EFI_ACPI_6_0_ERST_GOTO                                     0x0F
-#define EFI_ACPI_6_0_ERST_SET_SRC_ADDRESS_BASE                     0x10
-#define EFI_ACPI_6_0_ERST_SET_DST_ADDRESS_BASE                     0x11
-#define EFI_ACPI_6_0_ERST_MOVE_DATA                                0x12
-
-///
-/// ERST Instruction Flags
-///
-#define EFI_ACPI_6_0_ERST_PRESERVE_REGISTER                        0x01
-
-///
-/// ERST Serialization Instruction Entry
-///
-typedef struct {
-  UINT8                                    SerializationAction;
-  UINT8                                    Instruction;
-  UINT8                                    Flags;
-  UINT8                                    Reserved0;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE   RegisterRegion;
-  UINT64                                   Value;
-  UINT64                                   Mask;
-} EFI_ACPI_6_0_ERST_SERIALIZATION_INSTRUCTION_ENTRY;
-
-///
-/// EINJ - Error Injection Table
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      InjectionHeaderSize;
-  UINT8                       InjectionFlags;
-  UINT8                       Reserved0[3];
-  UINT32                      InjectionEntryCount;
-} EFI_ACPI_6_0_ERROR_INJECTION_TABLE_HEADER;
-
-///
-/// EINJ Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_ERROR_INJECTION_TABLE_REVISION 0x01
-
-///
-/// EINJ Error Injection Actions
-///
-#define EFI_ACPI_6_0_EINJ_BEGIN_INJECTION_OPERATION                0x00
-#define EFI_ACPI_6_0_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE           0x01
-#define EFI_ACPI_6_0_EINJ_SET_ERROR_TYPE                           0x02
-#define EFI_ACPI_6_0_EINJ_GET_ERROR_TYPE                           0x03
-#define EFI_ACPI_6_0_EINJ_END_OPERATION                            0x04
-#define EFI_ACPI_6_0_EINJ_EXECUTE_OPERATION                        0x05
-#define EFI_ACPI_6_0_EINJ_CHECK_BUSY_STATUS                        0x06
-#define EFI_ACPI_6_0_EINJ_GET_COMMAND_STATUS                       0x07
-#define EFI_ACPI_6_0_EINJ_TRIGGER_ERROR                            0xFF
-
-///
-/// EINJ Action Command Status
-///
-#define EFI_ACPI_6_0_EINJ_STATUS_SUCCESS                           0x00
-#define EFI_ACPI_6_0_EINJ_STATUS_UNKNOWN_FAILURE                   0x01
-#define EFI_ACPI_6_0_EINJ_STATUS_INVALID_ACCESS                    0x02
-
-///
-/// EINJ Error Type Definition
-///
-#define EFI_ACPI_6_0_EINJ_ERROR_PROCESSOR_CORRECTABLE                 (1 << 0)
-#define EFI_ACPI_6_0_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_NONFATAL      (1 << 1)
-#define EFI_ACPI_6_0_EINJ_ERROR_PROCESSOR_UNCORRECTABLE_FATAL         (1 << 2)
-#define EFI_ACPI_6_0_EINJ_ERROR_MEMORY_CORRECTABLE                    (1 << 3)
-#define EFI_ACPI_6_0_EINJ_ERROR_MEMORY_UNCORRECTABLE_NONFATAL         (1 << 4)
-#define EFI_ACPI_6_0_EINJ_ERROR_MEMORY_UNCORRECTABLE_FATAL            (1 << 5)
-#define EFI_ACPI_6_0_EINJ_ERROR_PCI_EXPRESS_CORRECTABLE               (1 << 6)
-#define EFI_ACPI_6_0_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_NONFATAL    (1 << 7)
-#define EFI_ACPI_6_0_EINJ_ERROR_PCI_EXPRESS_UNCORRECTABLE_FATAL       (1 << 8)
-#define EFI_ACPI_6_0_EINJ_ERROR_PLATFORM_CORRECTABLE                  (1 << 9)
-#define EFI_ACPI_6_0_EINJ_ERROR_PLATFORM_UNCORRECTABLE_NONFATAL       (1 << 10)
-#define EFI_ACPI_6_0_EINJ_ERROR_PLATFORM_UNCORRECTABLE_FATAL          (1 << 11)
-
-///
-/// EINJ Injection Instructions
-///
-#define EFI_ACPI_6_0_EINJ_READ_REGISTER                            0x00
-#define EFI_ACPI_6_0_EINJ_READ_REGISTER_VALUE                      0x01
-#define EFI_ACPI_6_0_EINJ_WRITE_REGISTER                           0x02
-#define EFI_ACPI_6_0_EINJ_WRITE_REGISTER_VALUE                     0x03
-#define EFI_ACPI_6_0_EINJ_NOOP                                     0x04
-
-///
-/// EINJ Instruction Flags
-///
-#define EFI_ACPI_6_0_EINJ_PRESERVE_REGISTER                        0x01
-
-///
-/// EINJ Injection Instruction Entry
-///
-typedef struct {
-  UINT8                                    InjectionAction;
-  UINT8                                    Instruction;
-  UINT8                                    Flags;
-  UINT8                                    Reserved0;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE   RegisterRegion;
-  UINT64                                   Value;
-  UINT64                                   Mask;
-} EFI_ACPI_6_0_EINJ_INJECTION_INSTRUCTION_ENTRY;
-
-///
-/// EINJ Trigger Action Table
-///
-typedef struct {
-  UINT32  HeaderSize;
-  UINT32  Revision;
-  UINT32  TableSize;
-  UINT32  EntryCount;
-} EFI_ACPI_6_0_EINJ_TRIGGER_ACTION_TABLE;
-
-///
-/// Platform Communications Channel Table (PCCT)
-///
-typedef struct {
-  EFI_ACPI_DESCRIPTION_HEADER Header;
-  UINT32                      Flags;
-  UINT64                      Reserved;
-} EFI_ACPI_6_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER;
-
-///
-/// PCCT Version (as defined in ACPI 6.0 spec.)
-///
-#define EFI_ACPI_6_0_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION 0x01
-
-///
-/// PCCT Global Flags
-///
-#define EFI_ACPI_6_0_PCCT_FLAGS_SCI_DOORBELL                      BIT0
-
-//
-// PCCT Subspace type
-//
-#define EFI_ACPI_6_0_PCCT_SUBSPACE_TYPE_GENERIC  0x00
-
-///
-/// PCC Subspace Structure Header
-///
-typedef struct {
-  UINT8        Type;
-  UINT8        Length;
-} EFI_ACPI_6_0_PCCT_SUBSPACE_HEADER;
-
-///
-/// Generic Communications Subspace Structure
-///
-typedef struct {
-  UINT8                                    Type;
-  UINT8                                    Length;
-  UINT8                                    Reserved[6];
-  UINT64                                   BaseAddress;
-  UINT64                                   AddressLength;
-  EFI_ACPI_6_0_GENERIC_ADDRESS_STRUCTURE   DoorbellRegister;
-  UINT64                                   DoorbellPreserve;
-  UINT64                                   DoorbellWrite;
-  UINT32                                   NominalLatency;
-  UINT32                                   MaximumPeriodicAccessRate;
-  UINT16                                   MinimumRequestTurnaroundTime;
-} EFI_ACPI_6_0_PCCT_SUBSPACE_GENERIC;
-
-///
-/// Generic Communications Channel Shared Memory Region
-///
-
-typedef struct {
-  UINT8                                    Command;
-  UINT8                                    Reserved:7;
-  UINT8                                    GenerateSci:1;
-} EFI_ACPI_6_0_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND;
-
-typedef struct {
-  UINT8                                    CommandComplete:1;
-  UINT8                                    SciDoorbell:1;
-  UINT8                                    Error:1;
-  UINT8                                    PlatformNotification:1;
-  UINT8                                    Reserved:4;
-  UINT8                                    Reserved1;
-} EFI_ACPI_6_0_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS;
-
-typedef struct {
-  UINT32                                                    Signature;
-  EFI_ACPI_6_0_PCCT_GENERIC_SHARED_MEMORY_REGION_COMMAND    Command;
-  EFI_ACPI_6_0_PCCT_GENERIC_SHARED_MEMORY_REGION_STATUS     Status;
-} EFI_ACPI_6_0_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER;
-
-//
-// Known table signatures
-//
-
-///
-/// "RSD PTR " Root System Description Pointer
-///
-#define EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE  SIGNATURE_64('R', 'S', 'D', ' ', 'P', 'T', 'R', ' ')
-
-///
-/// "APIC" Multiple APIC Description Table
-///
-#define EFI_ACPI_6_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('A', 'P', 'I', 'C')
-
-///
-/// "BERT" Boot Error Record Table
-///
-#define EFI_ACPI_6_0_BOOT_ERROR_RECORD_TABLE_SIGNATURE  SIGNATURE_32('B', 'E', 'R', 'T')
-
-///
-/// "BGRT" Boot Graphics Resource Table
-///
-#define EFI_ACPI_6_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE  SIGNATURE_32('B', 'G', 'R', 'T')
-
-///
-/// "CPEP" Corrected Platform Error Polling Table
-///
-#define EFI_ACPI_6_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE  SIGNATURE_32('C', 'P', 'E', 'P')
-
-///
-/// "DSDT" Differentiated System Description Table
-///
-#define EFI_ACPI_6_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('D', 'S', 'D', 'T')
-
-///
-/// "ECDT" Embedded Controller Boot Resources Table
-///
-#define EFI_ACPI_6_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE  SIGNATURE_32('E', 'C', 'D', 'T')
-
-///
-/// "EINJ" Error Injection Table
-///
-#define EFI_ACPI_6_0_ERROR_INJECTION_TABLE_SIGNATURE  SIGNATURE_32('E', 'I', 'N', 'J')
-
-///
-/// "ERST" Error Record Serialization Table
-///
-#define EFI_ACPI_6_0_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE  SIGNATURE_32('E', 'R', 'S', 'T')
-
-///
-/// "FACP" Fixed ACPI Description Table
-///
-#define EFI_ACPI_6_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('F', 'A', 'C', 'P')
-
-///
-/// "FACS" Firmware ACPI Control Structure
-///
-#define EFI_ACPI_6_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE  SIGNATURE_32('F', 'A', 'C', 'S')
-
-///
-/// "FPDT" Firmware Performance Data Table
-///
-#define EFI_ACPI_6_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE  SIGNATURE_32('F', 'P', 'D', 'T')
-
-///
-/// "GTDT" Generic Timer Description Table
-///
-#define EFI_ACPI_6_0_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('G', 'T', 'D', 'T')
-
-///
-/// "HEST" Hardware Error Source Table
-///
-#define EFI_ACPI_6_0_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE  SIGNATURE_32('H', 'E', 'S', 'T')
-
-///
-/// "MPST" Memory Power State Table
-///
-#define EFI_ACPI_6_0_MEMORY_POWER_STATE_TABLE_SIGNATURE  SIGNATURE_32('M', 'P', 'S', 'T')
-
-///
-/// "MSCT" Maximum System Characteristics Table
-///
-#define EFI_ACPI_6_0_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE  SIGNATURE_32('M', 'S', 'C', 'T')
-
-///
-/// "NFIT" NVDIMM Firmware Interface Table
-///
-#define EFI_ACPI_6_0_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE  SIGNATURE_32('N', 'F', 'I', 'T')
-
-///
-/// "PMTT" Platform Memory Topology Table
-///
-#define EFI_ACPI_6_0_PLATFORM_MEMORY_TOPOLOGY_TABLE_SIGNATURE  SIGNATURE_32('P', 'M', 'T', 'T')
-
-///
-/// "PSDT" Persistent System Description Table
-///
-#define EFI_ACPI_6_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('P', 'S', 'D', 'T')
-
-///
-/// "RASF" ACPI RAS Feature Table
-///
-#define EFI_ACPI_6_0_ACPI_RAS_FEATURE_TABLE_SIGNATURE  SIGNATURE_32('R', 'A', 'S', 'F')
-
-///
-/// "RSDT" Root System Description Table
-///
-#define EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('R', 'S', 'D', 'T')
-
-///
-/// "SBST" Smart Battery Specification Table
-///
-#define EFI_ACPI_6_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE  SIGNATURE_32('S', 'B', 'S', 'T')
-
-///
-/// "SLIT" System Locality Information Table
-///
-#define EFI_ACPI_6_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE  SIGNATURE_32('S', 'L', 'I', 'T')
-
-///
-/// "SRAT" System Resource Affinity Table
-///
-#define EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE  SIGNATURE_32('S', 'R', 'A', 'T')
-
-///
-/// "SSDT" Secondary System Description Table
-///
-#define EFI_ACPI_6_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('S', 'S', 'D', 'T')
-
-///
-/// "XSDT" Extended System Description Table
-///
-#define EFI_ACPI_6_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('X', 'S', 'D', 'T')
-
-///
-/// "BOOT" MS Simple Boot Spec
-///
-#define EFI_ACPI_6_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE  SIGNATURE_32('B', 'O', 'O', 'T')
-
-///
-/// "CSRT" MS Core System Resource Table
-///
-#define EFI_ACPI_6_0_CORE_SYSTEM_RESOURCE_TABLE_SIGNATURE  SIGNATURE_32('C', 'S', 'R', 'T')
-
-///
-/// "DBG2" MS Debug Port 2 Spec
-///
-#define EFI_ACPI_6_0_DEBUG_PORT_2_TABLE_SIGNATURE  SIGNATURE_32('D', 'B', 'G', '2')
-
-///
-/// "DBGP" MS Debug Port Spec
-///
-#define EFI_ACPI_6_0_DEBUG_PORT_TABLE_SIGNATURE  SIGNATURE_32('D', 'B', 'G', 'P')
-
-///
-/// "DMAR" DMA Remapping Table
-///
-#define EFI_ACPI_6_0_DMA_REMAPPING_TABLE_SIGNATURE  SIGNATURE_32('D', 'M', 'A', 'R')
-
-///
-/// "DRTM" Dynamic Root of Trust for Measurement Table
-///
-#define EFI_ACPI_6_0_DYNAMIC_ROOT_OF_TRUST_FOR_MEASUREMENT_TABLE_SIGNATURE  SIGNATURE_32('D', 'R', 'T', 'M')
-
-///
-/// "ETDT" Event Timer Description Table
-///
-#define EFI_ACPI_6_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('E', 'T', 'D', 'T')
-
-///
-/// "HPET" IA-PC High Precision Event Timer Table
-///
-#define EFI_ACPI_6_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE  SIGNATURE_32('H', 'P', 'E', 'T')
-
-///
-/// "iBFT" iSCSI Boot Firmware Table
-///
-#define EFI_ACPI_6_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE  SIGNATURE_32('i', 'B', 'F', 'T')
-
-///
-/// "IORT" Interrupt Source Override
-///
-#define EFI_ACPI_6_0_INTERRUPT_SOURCE_OVERRIDE_SIGNATURE  SIGNATURE_32('I', 'O', 'R', 'T')
-
-///
-/// "IVRS" I/O Virtualization Reporting Structure
-///
-#define EFI_ACPI_6_0_IO_VIRTUALIZATION_REPORTING_STRUCTURE_SIGNATURE  SIGNATURE_32('I', 'V', 'R', 'S')
-
-///
-/// "LPIT" Low Power Idle Table
-///
-#define EFI_ACPI_6_0_LOW_POWER_IDLE_TABLE_STRUCTURE_SIGNATURE  SIGNATURE_32('L', 'P', 'I', 'T')
-
-///
-/// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
-///
-#define EFI_ACPI_6_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('M', 'C', 'F', 'G')
-
-///
-/// "MCHI" Management Controller Host Interface Table
-///
-#define EFI_ACPI_6_0_MANAGEMENT_CONTROLLER_HOST_INTERFACE_TABLE_SIGNATURE  SIGNATURE_32('M', 'C', 'H', 'I')
-
-///
-/// "MSDM" MS Data Management Table
-///
-#define EFI_ACPI_6_0_DATA_MANAGEMENT_TABLE_SIGNATURE  SIGNATURE_32('M', 'S', 'D', 'M')
-
-///
-/// "SLIC" MS Software Licensing Table Specification
-///
-#define EFI_ACPI_6_0_SOFTWARE_LICENSING_TABLE_SIGNATURE  SIGNATURE_32('S', 'L', 'I', 'C')
-
-///
-/// "SPCR" Serial Port Concole Redirection Table
-///
-#define EFI_ACPI_6_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE  SIGNATURE_32('S', 'P', 'C', 'R')
-
-///
-/// "SPMI" Server Platform Management Interface Table
-///
-#define EFI_ACPI_6_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE  SIGNATURE_32('S', 'P', 'M', 'I')
-
-///
-/// "STAO" _STA Override Table
-///
-#define EFI_ACPI_6_0_STA_OVERRIDE_TABLE_SIGNATURE  SIGNATURE_32('S', 'T', 'A', 'O')
-
-///
-/// "TCPA" Trusted Computing Platform Alliance Capabilities Table
-///
-#define EFI_ACPI_6_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE  SIGNATURE_32('T', 'C', 'P', 'A')
-
-///
-/// "TPM2" Trusted Computing Platform 1 Table
-///
-#define EFI_ACPI_6_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE  SIGNATURE_32('T', 'P', 'M', '2')
-
-///
-/// "UEFI" UEFI ACPI Data Table
-///
-#define EFI_ACPI_6_0_UEFI_ACPI_DATA_TABLE_SIGNATURE  SIGNATURE_32('U', 'E', 'F', 'I')
-
-///
-/// "WAET" Windows ACPI Emulated Devices Table
-///
-#define EFI_ACPI_6_0_WINDOWS_ACPI_EMULATED_DEVICES_TABLE_SIGNATURE  SIGNATURE_32('W', 'A', 'E', 'T')
-
-///
-/// "WDAT" Watchdog Action Table
-///
-#define EFI_ACPI_6_0_WATCHDOG_ACTION_TABLE_SIGNATURE  SIGNATURE_32('W', 'D', 'A', 'T')
-
-///
-/// "WDRT" Watchdog Resource Table
-///
-#define EFI_ACPI_6_0_WATCHDOG_RESOURCE_TABLE_SIGNATURE  SIGNATURE_32('W', 'D', 'R', 'T')
-
-///
-/// "WPBT" MS Platform Binary Table
-///
-#define EFI_ACPI_6_0_PLATFORM_BINARY_TABLE_SIGNATURE  SIGNATURE_32('W', 'P', 'B', 'T')
-
-///
-/// "XENV" Xen Project Table
-///
-#define EFI_ACPI_6_0_XEN_PROJECT_TABLE_SIGNATURE  SIGNATURE_32('X', 'E', 'N', 'V')
-
-#pragma pack()
-
-#endif
diff --git a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Bluetooth.h b/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Bluetooth.h
deleted file mode 100644 (file)
index f63ab89..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/** @file
-  This file contains the Bluetooth definitions that are consumed by drivers.
-  These definitions are from Bluetooth Core Specification Version 4.0 June, 2010
-
-  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef _BLUETOOTH_H_
-#define _BLUETOOTH_H_
-
-FILE_LICENCE ( BSD3 );
-
-#pragma pack(1)
-
-///
-/// BLUETOOTH_ADDRESS
-///
-typedef struct {
-  ///
-  /// 48bit Bluetooth device address.
-  ///
-  UINT8      Address[6];
-} BLUETOOTH_ADDRESS;
-
-///
-/// BLUETOOTH_CLASS_OF_DEVICE. See Bluetooth specification for detail.
-///
-typedef struct {
-  UINT8      FormatType:2;
-  UINT8      MinorDeviceClass: 6;
-  UINT16     MajorDeviceClass: 5;
-  UINT16     MajorServiceClass:11;
-} BLUETOOTH_CLASS_OF_DEVICE;
-
-#pragma pack()
-
-#define BLUETOOTH_HCI_COMMAND_LOCAL_READABLE_NAME_MAX_SIZE    248
-
-#define BLUETOOTH_HCI_LINK_KEY_SIZE                           16
-
-#endif
index f0f2ae9..a73820f 100644 (file)
@@ -9,7 +9,7 @@
 
 
   Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
-  Copyright (c) 2014 - 2105, Hewlett-Packard Development Company, L.P.<BR>
+  Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -554,7 +554,6 @@ typedef struct {
 #define PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET      0x18
 #define PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET    0x19
 #define PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET  0x1a
-#define PCI_BRIDGE_SECONDARY_LATENCY_TIMER_OFFSET   0x1b
 #define PCI_BRIDGE_STATUS_REGISTER_OFFSET           0x1E
 #define PCI_BRIDGE_CONTROL_REGISTER_OFFSET          0x3E
 
diff --git a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Tpm20.h b/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Tpm20.h
deleted file mode 100644 (file)
index 656bf21..0000000
+++ /dev/null
@@ -1,1822 +0,0 @@
-/** @file
-  TPM2.0 Specification data structures
-  (Trusted Platform Module Library Specification, Family "2.0", Level 00, Revision 00.96,
-  @http://www.trustedcomputinggroup.org/resources/tpm_library_specification)
-
-  Check http://trustedcomputinggroup.org for latest specification updates.
-
-Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved. <BR>
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-
-#ifndef _TPM20_H_
-#define _TPM20_H_
-
-FILE_LICENCE ( BSD3 );
-
-#include <ipxe/efi/IndustryStandard/Tpm12.h>
-
-#pragma pack (1)
-
-// Annex A Algorithm Constants
-
-// Table 205 - Defines for SHA1 Hash Values
-#define SHA1_DIGEST_SIZE 20
-#define SHA1_BLOCK_SIZE  64
-
-// Table 206 - Defines for SHA256 Hash Values
-#define SHA256_DIGEST_SIZE 32
-#define SHA256_BLOCK_SIZE  64
-
-// Table 207 - Defines for SHA384 Hash Values
-#define SHA384_DIGEST_SIZE 48
-#define SHA384_BLOCK_SIZE  128
-
-// Table 208 - Defines for SHA512 Hash Values
-#define SHA512_DIGEST_SIZE 64
-#define SHA512_BLOCK_SIZE  128
-
-// Table 209 - Defines for SM3_256 Hash Values
-#define SM3_256_DIGEST_SIZE 32
-#define SM3_256_BLOCK_SIZE  64
-
-// Table 210 - Defines for Architectural Limits Values
-#define MAX_SESSION_NUMBER 3
-
-// Annex B Implementation Definitions
-
-// Table 211 - Defines for Logic Values
-#define YES   1
-#define NO    0
-#define SET   1
-#define CLEAR 0
-
-// Table 215 - Defines for RSA Algorithm Constants
-#define MAX_RSA_KEY_BITS  2048
-#define MAX_RSA_KEY_BYTES ((MAX_RSA_KEY_BITS + 7) / 8)
-
-// Table 216 - Defines for ECC Algorithm Constants
-#define MAX_ECC_KEY_BITS  256
-#define MAX_ECC_KEY_BYTES ((MAX_ECC_KEY_BITS + 7) / 8)
-
-// Table 217 - Defines for AES Algorithm Constants
-#define MAX_AES_KEY_BITS         128
-#define MAX_AES_BLOCK_SIZE_BYTES 16
-#define MAX_AES_KEY_BYTES        ((MAX_AES_KEY_BITS + 7) / 8)
-
-// Table 218 - Defines for SM4 Algorithm Constants
-#define MAX_SM4_KEY_BITS         128
-#define MAX_SM4_BLOCK_SIZE_BYTES 16
-#define MAX_SM4_KEY_BYTES        ((MAX_SM4_KEY_BITS + 7) / 8)
-
-// Table 219 - Defines for Symmetric Algorithm Constants
-#define MAX_SYM_KEY_BITS   MAX_AES_KEY_BITS
-#define MAX_SYM_KEY_BYTES  MAX_AES_KEY_BYTES
-#define MAX_SYM_BLOCK_SIZE MAX_AES_BLOCK_SIZE_BYTES
-
-// Table 220 - Defines for Implementation Values
-typedef UINT16                        BSIZE;
-#define BUFFER_ALIGNMENT              4
-#define IMPLEMENTATION_PCR            24
-#define PLATFORM_PCR                  24
-#define DRTM_PCR                      17
-#define NUM_LOCALITIES                5
-#define MAX_HANDLE_NUM                3
-#define MAX_ACTIVE_SESSIONS           64
-typedef UINT16                        CONTEXT_SLOT;
-typedef UINT64                        CONTEXT_COUNTER;
-#define MAX_LOADED_SESSIONS           3
-#define MAX_SESSION_NUM               3
-#define MAX_LOADED_OBJECTS            3
-#define MIN_EVICT_OBJECTS             2
-#define PCR_SELECT_MIN                ((PLATFORM_PCR + 7) / 8)
-#define PCR_SELECT_MAX                ((IMPLEMENTATION_PCR + 7) / 8)
-#define NUM_POLICY_PCR_GROUP          1
-#define NUM_AUTHVALUE_PCR_GROUP       1
-#define MAX_CONTEXT_SIZE              4000
-#define MAX_DIGEST_BUFFER             1024
-#define MAX_NV_INDEX_SIZE             1024
-#define MAX_CAP_BUFFER                1024
-#define NV_MEMORY_SIZE                16384
-#define NUM_STATIC_PCR                16
-#define MAX_ALG_LIST_SIZE             64
-#define TIMER_PRESCALE                100000
-#define PRIMARY_SEED_SIZE             32
-#define CONTEXT_ENCRYPT_ALG           TPM_ALG_AES
-#define CONTEXT_ENCRYPT_KEY_BITS      MAX_SYM_KEY_BITS
-#define CONTEXT_ENCRYPT_KEY_BYTES     ((CONTEXT_ENCRYPT_KEY_BITS + 7) / 8)
-#define CONTEXT_INTEGRITY_HASH_ALG    TPM_ALG_SHA256
-#define CONTEXT_INTEGRITY_HASH_SIZE   SHA256_DIGEST_SIZE
-#define PROOF_SIZE                    CONTEXT_INTEGRITY_HASH_SIZE
-#define NV_CLOCK_UPDATE_INTERVAL      12
-#define NUM_POLICY_PCR                1
-#define MAX_COMMAND_SIZE              4096
-#define MAX_RESPONSE_SIZE             4096
-#define ORDERLY_BITS                  8
-#define MAX_ORDERLY_COUNT             ((1 << ORDERLY_BITS) - 1)
-#define ALG_ID_FIRST                  TPM_ALG_FIRST
-#define ALG_ID_LAST                   TPM_ALG_LAST
-#define MAX_SYM_DATA                  128
-#define MAX_RNG_ENTROPY_SIZE          64
-#define RAM_INDEX_SPACE               512
-#define RSA_DEFAULT_PUBLIC_EXPONENT   0x00010001
-#define CRT_FORMAT_RSA                YES
-#define PRIVATE_VENDOR_SPECIFIC_BYTES ((MAX_RSA_KEY_BYTES / 2) * ( 3 + CRT_FORMAT_RSA * 2))
-
-// Capability related MAX_ value
-#define MAX_CAP_DATA       (MAX_CAP_BUFFER - sizeof(TPM_CAP) - sizeof(UINT32))
-#define MAX_CAP_ALGS       (MAX_CAP_DATA / sizeof(TPMS_ALG_PROPERTY))
-#define MAX_CAP_HANDLES    (MAX_CAP_DATA / sizeof(TPM_HANDLE))
-#define MAX_CAP_CC         (MAX_CAP_DATA / sizeof(TPM_CC))
-#define MAX_TPM_PROPERTIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PROPERTY))
-#define MAX_PCR_PROPERTIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PCR_SELECT))
-#define MAX_ECC_CURVES     (MAX_CAP_DATA / sizeof(TPM_ECC_CURVE))
-
-//
-// Always set 5 here, because we want to support all hash algo in BIOS.
-//
-#define HASH_COUNT 5
-
-// 5 Base Types
-
-// Table 3 - Definition of Base Types
-typedef UINT8 BYTE;
-
-// Table 4 - Definition of Types for Documentation Clarity
-//
-// NOTE: Comment because it has same name as TPM1.2 (value is same, so not runtime issue)
-//
-//typedef UINT32 TPM_ALGORITHM_ID;
-//typedef UINT32 TPM_MODIFIER_INDICATOR;
-typedef UINT32 TPM_AUTHORIZATION_SIZE;
-typedef UINT32 TPM_PARAMETER_SIZE;
-typedef UINT16 TPM_KEY_SIZE;
-typedef UINT16 TPM_KEY_BITS;
-
-// 6 Constants
-
-// Table 6 - TPM_GENERATED Constants
-typedef UINT32 TPM_GENERATED;
-#define TPM_GENERATED_VALUE (TPM_GENERATED)(0xff544347)
-
-// Table 7 - TPM_ALG_ID Constants
-typedef UINT16 TPM_ALG_ID;
-//
-// NOTE: Comment some algo which has same name as TPM1.2 (value is same, so not runtime issue)
-//
-#define TPM_ALG_ERROR          (TPM_ALG_ID)(0x0000)
-#define TPM_ALG_FIRST          (TPM_ALG_ID)(0x0001)
-//#define TPM_ALG_RSA            (TPM_ALG_ID)(0x0001)
-//#define TPM_ALG_SHA            (TPM_ALG_ID)(0x0004)
-#define TPM_ALG_SHA1           (TPM_ALG_ID)(0x0004)
-//#define TPM_ALG_HMAC           (TPM_ALG_ID)(0x0005)
-#define TPM_ALG_AES            (TPM_ALG_ID)(0x0006)
-//#define TPM_ALG_MGF1           (TPM_ALG_ID)(0x0007)
-#define TPM_ALG_KEYEDHASH      (TPM_ALG_ID)(0x0008)
-//#define TPM_ALG_XOR            (TPM_ALG_ID)(0x000A)
-#define TPM_ALG_SHA256         (TPM_ALG_ID)(0x000B)
-#define TPM_ALG_SHA384         (TPM_ALG_ID)(0x000C)
-#define TPM_ALG_SHA512         (TPM_ALG_ID)(0x000D)
-#define TPM_ALG_NULL           (TPM_ALG_ID)(0x0010)
-#define TPM_ALG_SM3_256        (TPM_ALG_ID)(0x0012)
-#define TPM_ALG_SM4            (TPM_ALG_ID)(0x0013)
-#define TPM_ALG_RSASSA         (TPM_ALG_ID)(0x0014)
-#define TPM_ALG_RSAES          (TPM_ALG_ID)(0x0015)
-#define TPM_ALG_RSAPSS         (TPM_ALG_ID)(0x0016)
-#define TPM_ALG_OAEP           (TPM_ALG_ID)(0x0017)
-#define TPM_ALG_ECDSA          (TPM_ALG_ID)(0x0018)
-#define TPM_ALG_ECDH           (TPM_ALG_ID)(0x0019)
-#define TPM_ALG_ECDAA          (TPM_ALG_ID)(0x001A)
-#define TPM_ALG_SM2            (TPM_ALG_ID)(0x001B)
-#define TPM_ALG_ECSCHNORR      (TPM_ALG_ID)(0x001C)
-#define TPM_ALG_ECMQV          (TPM_ALG_ID)(0x001D)
-#define TPM_ALG_KDF1_SP800_56a (TPM_ALG_ID)(0x0020)
-#define TPM_ALG_KDF2           (TPM_ALG_ID)(0x0021)
-#define TPM_ALG_KDF1_SP800_108 (TPM_ALG_ID)(0x0022)
-#define TPM_ALG_ECC            (TPM_ALG_ID)(0x0023)
-#define TPM_ALG_SYMCIPHER      (TPM_ALG_ID)(0x0025)
-#define TPM_ALG_CTR            (TPM_ALG_ID)(0x0040)
-#define TPM_ALG_OFB            (TPM_ALG_ID)(0x0041)
-#define TPM_ALG_CBC            (TPM_ALG_ID)(0x0042)
-#define TPM_ALG_CFB            (TPM_ALG_ID)(0x0043)
-#define TPM_ALG_ECB            (TPM_ALG_ID)(0x0044)
-#define TPM_ALG_LAST           (TPM_ALG_ID)(0x0044)
-
-// Table 8 - TPM_ECC_CURVE Constants
-typedef UINT16 TPM_ECC_CURVE;
-#define TPM_ECC_NONE      (TPM_ECC_CURVE)(0x0000)
-#define TPM_ECC_NIST_P192 (TPM_ECC_CURVE)(0x0001)
-#define TPM_ECC_NIST_P224 (TPM_ECC_CURVE)(0x0002)
-#define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0003)
-#define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0004)
-#define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0005)
-#define TPM_ECC_BN_P256   (TPM_ECC_CURVE)(0x0010)
-#define TPM_ECC_BN_P638   (TPM_ECC_CURVE)(0x0011)
-#define TPM_ECC_SM2_P256  (TPM_ECC_CURVE)(0x0020)
-
-// Table 11 - TPM_CC Constants (Numeric Order)
-typedef UINT32 TPM_CC;
-#define TPM_CC_FIRST                      (TPM_CC)(0x0000011F)
-#define TPM_CC_PP_FIRST                   (TPM_CC)(0x0000011F)
-#define TPM_CC_NV_UndefineSpaceSpecial    (TPM_CC)(0x0000011F)
-#define TPM_CC_EvictControl               (TPM_CC)(0x00000120)
-#define TPM_CC_HierarchyControl           (TPM_CC)(0x00000121)
-#define TPM_CC_NV_UndefineSpace           (TPM_CC)(0x00000122)
-#define TPM_CC_ChangeEPS                  (TPM_CC)(0x00000124)
-#define TPM_CC_ChangePPS                  (TPM_CC)(0x00000125)
-#define TPM_CC_Clear                      (TPM_CC)(0x00000126)
-#define TPM_CC_ClearControl               (TPM_CC)(0x00000127)
-#define TPM_CC_ClockSet                   (TPM_CC)(0x00000128)
-#define TPM_CC_HierarchyChangeAuth        (TPM_CC)(0x00000129)
-#define TPM_CC_NV_DefineSpace             (TPM_CC)(0x0000012A)
-#define TPM_CC_PCR_Allocate               (TPM_CC)(0x0000012B)
-#define TPM_CC_PCR_SetAuthPolicy          (TPM_CC)(0x0000012C)
-#define TPM_CC_PP_Commands                (TPM_CC)(0x0000012D)
-#define TPM_CC_SetPrimaryPolicy           (TPM_CC)(0x0000012E)
-#define TPM_CC_FieldUpgradeStart          (TPM_CC)(0x0000012F)
-#define TPM_CC_ClockRateAdjust            (TPM_CC)(0x00000130)
-#define TPM_CC_CreatePrimary              (TPM_CC)(0x00000131)
-#define TPM_CC_NV_GlobalWriteLock         (TPM_CC)(0x00000132)
-#define TPM_CC_PP_LAST                    (TPM_CC)(0x00000132)
-#define TPM_CC_GetCommandAuditDigest      (TPM_CC)(0x00000133)
-#define TPM_CC_NV_Increment               (TPM_CC)(0x00000134)
-#define TPM_CC_NV_SetBits                 (TPM_CC)(0x00000135)
-#define TPM_CC_NV_Extend                  (TPM_CC)(0x00000136)
-#define TPM_CC_NV_Write                   (TPM_CC)(0x00000137)
-#define TPM_CC_NV_WriteLock               (TPM_CC)(0x00000138)
-#define TPM_CC_DictionaryAttackLockReset  (TPM_CC)(0x00000139)
-#define TPM_CC_DictionaryAttackParameters (TPM_CC)(0x0000013A)
-#define TPM_CC_NV_ChangeAuth              (TPM_CC)(0x0000013B)
-#define TPM_CC_PCR_Event                  (TPM_CC)(0x0000013C)
-#define TPM_CC_PCR_Reset                  (TPM_CC)(0x0000013D)
-#define TPM_CC_SequenceComplete           (TPM_CC)(0x0000013E)
-#define TPM_CC_SetAlgorithmSet            (TPM_CC)(0x0000013F)
-#define TPM_CC_SetCommandCodeAuditStatus  (TPM_CC)(0x00000140)
-#define TPM_CC_FieldUpgradeData           (TPM_CC)(0x00000141)
-#define TPM_CC_IncrementalSelfTest        (TPM_CC)(0x00000142)
-#define TPM_CC_SelfTest                   (TPM_CC)(0x00000143)
-#define TPM_CC_Startup                    (TPM_CC)(0x00000144)
-#define TPM_CC_Shutdown                   (TPM_CC)(0x00000145)
-#define TPM_CC_StirRandom                 (TPM_CC)(0x00000146)
-#define TPM_CC_ActivateCredential         (TPM_CC)(0x00000147)
-#define TPM_CC_Certify                    (TPM_CC)(0x00000148)
-#define TPM_CC_PolicyNV                   (TPM_CC)(0x00000149)
-#define TPM_CC_CertifyCreation            (TPM_CC)(0x0000014A)
-#define TPM_CC_Duplicate                  (TPM_CC)(0x0000014B)
-#define TPM_CC_GetTime                    (TPM_CC)(0x0000014C)
-#define TPM_CC_GetSessionAuditDigest      (TPM_CC)(0x0000014D)
-#define TPM_CC_NV_Read                    (TPM_CC)(0x0000014E)
-#define TPM_CC_NV_ReadLock                (TPM_CC)(0x0000014F)
-#define TPM_CC_ObjectChangeAuth           (TPM_CC)(0x00000150)
-#define TPM_CC_PolicySecret               (TPM_CC)(0x00000151)
-#define TPM_CC_Rewrap                     (TPM_CC)(0x00000152)
-#define TPM_CC_Create                     (TPM_CC)(0x00000153)
-#define TPM_CC_ECDH_ZGen                  (TPM_CC)(0x00000154)
-#define TPM_CC_HMAC                       (TPM_CC)(0x00000155)
-#define TPM_CC_Import                     (TPM_CC)(0x00000156)
-#define TPM_CC_Load                       (TPM_CC)(0x00000157)
-#define TPM_CC_Quote                      (TPM_CC)(0x00000158)
-#define TPM_CC_RSA_Decrypt                (TPM_CC)(0x00000159)
-#define TPM_CC_HMAC_Start                 (TPM_CC)(0x0000015B)
-#define TPM_CC_SequenceUpdate             (TPM_CC)(0x0000015C)
-#define TPM_CC_Sign                       (TPM_CC)(0x0000015D)
-#define TPM_CC_Unseal                     (TPM_CC)(0x0000015E)
-#define TPM_CC_PolicySigned               (TPM_CC)(0x00000160)
-#define TPM_CC_ContextLoad                (TPM_CC)(0x00000161)
-#define TPM_CC_ContextSave                (TPM_CC)(0x00000162)
-#define TPM_CC_ECDH_KeyGen                (TPM_CC)(0x00000163)
-#define TPM_CC_EncryptDecrypt             (TPM_CC)(0x00000164)
-#define TPM_CC_FlushContext               (TPM_CC)(0x00000165)
-#define TPM_CC_LoadExternal               (TPM_CC)(0x00000167)
-#define TPM_CC_MakeCredential             (TPM_CC)(0x00000168)
-#define TPM_CC_NV_ReadPublic              (TPM_CC)(0x00000169)
-#define TPM_CC_PolicyAuthorize            (TPM_CC)(0x0000016A)
-#define TPM_CC_PolicyAuthValue            (TPM_CC)(0x0000016B)
-#define TPM_CC_PolicyCommandCode          (TPM_CC)(0x0000016C)
-#define TPM_CC_PolicyCounterTimer         (TPM_CC)(0x0000016D)
-#define TPM_CC_PolicyCpHash               (TPM_CC)(0x0000016E)
-#define TPM_CC_PolicyLocality             (TPM_CC)(0x0000016F)
-#define TPM_CC_PolicyNameHash             (TPM_CC)(0x00000170)
-#define TPM_CC_PolicyOR                   (TPM_CC)(0x00000171)
-#define TPM_CC_PolicyTicket               (TPM_CC)(0x00000172)
-#define TPM_CC_ReadPublic                 (TPM_CC)(0x00000173)
-#define TPM_CC_RSA_Encrypt                (TPM_CC)(0x00000174)
-#define TPM_CC_StartAuthSession           (TPM_CC)(0x00000176)
-#define TPM_CC_VerifySignature            (TPM_CC)(0x00000177)
-#define TPM_CC_ECC_Parameters             (TPM_CC)(0x00000178)
-#define TPM_CC_FirmwareRead               (TPM_CC)(0x00000179)
-#define TPM_CC_GetCapability              (TPM_CC)(0x0000017A)
-#define TPM_CC_GetRandom                  (TPM_CC)(0x0000017B)
-#define TPM_CC_GetTestResult              (TPM_CC)(0x0000017C)
-#define TPM_CC_Hash                       (TPM_CC)(0x0000017D)
-#define TPM_CC_PCR_Read                   (TPM_CC)(0x0000017E)
-#define TPM_CC_PolicyPCR                  (TPM_CC)(0x0000017F)
-#define TPM_CC_PolicyRestart              (TPM_CC)(0x00000180)
-#define TPM_CC_ReadClock                  (TPM_CC)(0x00000181)
-#define TPM_CC_PCR_Extend                 (TPM_CC)(0x00000182)
-#define TPM_CC_PCR_SetAuthValue           (TPM_CC)(0x00000183)
-#define TPM_CC_NV_Certify                 (TPM_CC)(0x00000184)
-#define TPM_CC_EventSequenceComplete      (TPM_CC)(0x00000185)
-#define TPM_CC_HashSequenceStart          (TPM_CC)(0x00000186)
-#define TPM_CC_PolicyPhysicalPresence     (TPM_CC)(0x00000187)
-#define TPM_CC_PolicyDuplicationSelect    (TPM_CC)(0x00000188)
-#define TPM_CC_PolicyGetDigest            (TPM_CC)(0x00000189)
-#define TPM_CC_TestParms                  (TPM_CC)(0x0000018A)
-#define TPM_CC_Commit                     (TPM_CC)(0x0000018B)
-#define TPM_CC_PolicyPassword             (TPM_CC)(0x0000018C)
-#define TPM_CC_ZGen_2Phase                (TPM_CC)(0x0000018D)
-#define TPM_CC_EC_Ephemeral               (TPM_CC)(0x0000018E)
-#define TPM_CC_LAST                       (TPM_CC)(0x0000018E)
-
-// Table 15 - TPM_RC Constants (Actions)
-typedef UINT32 TPM_RC;
-#define TPM_RC_SUCCESS           (TPM_RC)(0x000)
-#define TPM_RC_BAD_TAG           (TPM_RC)(0x030)
-#define RC_VER1                  (TPM_RC)(0x100)
-#define TPM_RC_INITIALIZE        (TPM_RC)(RC_VER1 + 0x000)
-#define TPM_RC_FAILURE           (TPM_RC)(RC_VER1 + 0x001)
-#define TPM_RC_SEQUENCE          (TPM_RC)(RC_VER1 + 0x003)
-#define TPM_RC_PRIVATE           (TPM_RC)(RC_VER1 + 0x00B)
-#define TPM_RC_HMAC              (TPM_RC)(RC_VER1 + 0x019)
-#define TPM_RC_DISABLED          (TPM_RC)(RC_VER1 + 0x020)
-#define TPM_RC_EXCLUSIVE         (TPM_RC)(RC_VER1 + 0x021)
-#define TPM_RC_AUTH_TYPE         (TPM_RC)(RC_VER1 + 0x024)
-#define TPM_RC_AUTH_MISSING      (TPM_RC)(RC_VER1 + 0x025)
-#define TPM_RC_POLICY            (TPM_RC)(RC_VER1 + 0x026)
-#define TPM_RC_PCR               (TPM_RC)(RC_VER1 + 0x027)
-#define TPM_RC_PCR_CHANGED       (TPM_RC)(RC_VER1 + 0x028)
-#define TPM_RC_UPGRADE           (TPM_RC)(RC_VER1 + 0x02D)
-#define TPM_RC_TOO_MANY_CONTEXTS (TPM_RC)(RC_VER1 + 0x02E)
-#define TPM_RC_AUTH_UNAVAILABLE  (TPM_RC)(RC_VER1 + 0x02F)
-#define TPM_RC_REBOOT            (TPM_RC)(RC_VER1 + 0x030)
-#define TPM_RC_UNBALANCED        (TPM_RC)(RC_VER1 + 0x031)
-#define TPM_RC_COMMAND_SIZE      (TPM_RC)(RC_VER1 + 0x042)
-#define TPM_RC_COMMAND_CODE      (TPM_RC)(RC_VER1 + 0x043)
-#define TPM_RC_AUTHSIZE          (TPM_RC)(RC_VER1 + 0x044)
-#define TPM_RC_AUTH_CONTEXT      (TPM_RC)(RC_VER1 + 0x045)
-#define TPM_RC_NV_RANGE          (TPM_RC)(RC_VER1 + 0x046)
-#define TPM_RC_NV_SIZE           (TPM_RC)(RC_VER1 + 0x047)
-#define TPM_RC_NV_LOCKED         (TPM_RC)(RC_VER1 + 0x048)
-#define TPM_RC_NV_AUTHORIZATION  (TPM_RC)(RC_VER1 + 0x049)
-#define TPM_RC_NV_UNINITIALIZED  (TPM_RC)(RC_VER1 + 0x04A)
-#define TPM_RC_NV_SPACE          (TPM_RC)(RC_VER1 + 0x04B)
-#define TPM_RC_NV_DEFINED        (TPM_RC)(RC_VER1 + 0x04C)
-#define TPM_RC_BAD_CONTEXT       (TPM_RC)(RC_VER1 + 0x050)
-#define TPM_RC_CPHASH            (TPM_RC)(RC_VER1 + 0x051)
-#define TPM_RC_PARENT            (TPM_RC)(RC_VER1 + 0x052)
-#define TPM_RC_NEEDS_TEST        (TPM_RC)(RC_VER1 + 0x053)
-#define TPM_RC_NO_RESULT         (TPM_RC)(RC_VER1 + 0x054)
-#define TPM_RC_SENSITIVE         (TPM_RC)(RC_VER1 + 0x055)
-#define RC_MAX_FM0               (TPM_RC)(RC_VER1 + 0x07F)
-#define RC_FMT1                  (TPM_RC)(0x080)
-#define TPM_RC_ASYMMETRIC        (TPM_RC)(RC_FMT1 + 0x001)
-#define TPM_RC_ATTRIBUTES        (TPM_RC)(RC_FMT1 + 0x002)
-#define TPM_RC_HASH              (TPM_RC)(RC_FMT1 + 0x003)
-#define TPM_RC_VALUE             (TPM_RC)(RC_FMT1 + 0x004)
-#define TPM_RC_HIERARCHY         (TPM_RC)(RC_FMT1 + 0x005)
-#define TPM_RC_KEY_SIZE          (TPM_RC)(RC_FMT1 + 0x007)
-#define TPM_RC_MGF               (TPM_RC)(RC_FMT1 + 0x008)
-#define TPM_RC_MODE              (TPM_RC)(RC_FMT1 + 0x009)
-#define TPM_RC_TYPE              (TPM_RC)(RC_FMT1 + 0x00A)
-#define TPM_RC_HANDLE            (TPM_RC)(RC_FMT1 + 0x00B)
-#define TPM_RC_KDF               (TPM_RC)(RC_FMT1 + 0x00C)
-#define TPM_RC_RANGE             (TPM_RC)(RC_FMT1 + 0x00D)
-#define TPM_RC_AUTH_FAIL         (TPM_RC)(RC_FMT1 + 0x00E)
-#define TPM_RC_NONCE             (TPM_RC)(RC_FMT1 + 0x00F)
-#define TPM_RC_PP                (TPM_RC)(RC_FMT1 + 0x010)
-#define TPM_RC_SCHEME            (TPM_RC)(RC_FMT1 + 0x012)
-#define TPM_RC_SIZE              (TPM_RC)(RC_FMT1 + 0x015)
-#define TPM_RC_SYMMETRIC         (TPM_RC)(RC_FMT1 + 0x016)
-#define TPM_RC_TAG               (TPM_RC)(RC_FMT1 + 0x017)
-#define TPM_RC_SELECTOR          (TPM_RC)(RC_FMT1 + 0x018)
-#define TPM_RC_INSUFFICIENT      (TPM_RC)(RC_FMT1 + 0x01A)
-#define TPM_RC_SIGNATURE         (TPM_RC)(RC_FMT1 + 0x01B)
-#define TPM_RC_KEY               (TPM_RC)(RC_FMT1 + 0x01C)
-#define TPM_RC_POLICY_FAIL       (TPM_RC)(RC_FMT1 + 0x01D)
-#define TPM_RC_INTEGRITY         (TPM_RC)(RC_FMT1 + 0x01F)
-#define TPM_RC_TICKET            (TPM_RC)(RC_FMT1 + 0x020)
-#define TPM_RC_RESERVED_BITS     (TPM_RC)(RC_FMT1 + 0x021)
-#define TPM_RC_BAD_AUTH          (TPM_RC)(RC_FMT1 + 0x022)
-#define TPM_RC_EXPIRED           (TPM_RC)(RC_FMT1 + 0x023)
-#define TPM_RC_POLICY_CC         (TPM_RC)(RC_FMT1 + 0x024 )
-#define TPM_RC_BINDING           (TPM_RC)(RC_FMT1 + 0x025)
-#define TPM_RC_CURVE             (TPM_RC)(RC_FMT1 + 0x026)
-#define TPM_RC_ECC_POINT         (TPM_RC)(RC_FMT1 + 0x027)
-#define RC_WARN                  (TPM_RC)(0x900)
-#define TPM_RC_CONTEXT_GAP       (TPM_RC)(RC_WARN + 0x001)
-#define TPM_RC_OBJECT_MEMORY     (TPM_RC)(RC_WARN + 0x002)
-#define TPM_RC_SESSION_MEMORY    (TPM_RC)(RC_WARN + 0x003)
-#define TPM_RC_MEMORY            (TPM_RC)(RC_WARN + 0x004)
-#define TPM_RC_SESSION_HANDLES   (TPM_RC)(RC_WARN + 0x005)
-#define TPM_RC_OBJECT_HANDLES    (TPM_RC)(RC_WARN + 0x006)
-#define TPM_RC_LOCALITY          (TPM_RC)(RC_WARN + 0x007)
-#define TPM_RC_YIELDED           (TPM_RC)(RC_WARN + 0x008)
-#define TPM_RC_CANCELED          (TPM_RC)(RC_WARN + 0x009)
-#define TPM_RC_TESTING           (TPM_RC)(RC_WARN + 0x00A)
-#define TPM_RC_REFERENCE_H0      (TPM_RC)(RC_WARN + 0x010)
-#define TPM_RC_REFERENCE_H1      (TPM_RC)(RC_WARN + 0x011)
-#define TPM_RC_REFERENCE_H2      (TPM_RC)(RC_WARN + 0x012)
-#define TPM_RC_REFERENCE_H3      (TPM_RC)(RC_WARN + 0x013)
-#define TPM_RC_REFERENCE_H4      (TPM_RC)(RC_WARN + 0x014)
-#define TPM_RC_REFERENCE_H5      (TPM_RC)(RC_WARN + 0x015)
-#define TPM_RC_REFERENCE_H6      (TPM_RC)(RC_WARN + 0x016)
-#define TPM_RC_REFERENCE_S0      (TPM_RC)(RC_WARN + 0x018)
-#define TPM_RC_REFERENCE_S1      (TPM_RC)(RC_WARN + 0x019)
-#define TPM_RC_REFERENCE_S2      (TPM_RC)(RC_WARN + 0x01A)
-#define TPM_RC_REFERENCE_S3      (TPM_RC)(RC_WARN + 0x01B)
-#define TPM_RC_REFERENCE_S4      (TPM_RC)(RC_WARN + 0x01C)
-#define TPM_RC_REFERENCE_S5      (TPM_RC)(RC_WARN + 0x01D)
-#define TPM_RC_REFERENCE_S6      (TPM_RC)(RC_WARN + 0x01E)
-#define TPM_RC_NV_RATE           (TPM_RC)(RC_WARN + 0x020)
-#define TPM_RC_LOCKOUT           (TPM_RC)(RC_WARN + 0x021)
-#define TPM_RC_RETRY             (TPM_RC)(RC_WARN + 0x022)
-#define TPM_RC_NV_UNAVAILABLE    (TPM_RC)(RC_WARN + 0x023)
-#define TPM_RC_NOT_USED          (TPM_RC)(RC_WARN + 0x7F)
-#define TPM_RC_H                 (TPM_RC)(0x000)
-#define TPM_RC_P                 (TPM_RC)(0x040)
-#define TPM_RC_S                 (TPM_RC)(0x800)
-#define TPM_RC_1                 (TPM_RC)(0x100)
-#define TPM_RC_2                 (TPM_RC)(0x200)
-#define TPM_RC_3                 (TPM_RC)(0x300)
-#define TPM_RC_4                 (TPM_RC)(0x400)
-#define TPM_RC_5                 (TPM_RC)(0x500)
-#define TPM_RC_6                 (TPM_RC)(0x600)
-#define TPM_RC_7                 (TPM_RC)(0x700)
-#define TPM_RC_8                 (TPM_RC)(0x800)
-#define TPM_RC_9                 (TPM_RC)(0x900)
-#define TPM_RC_A                 (TPM_RC)(0xA00)
-#define TPM_RC_B                 (TPM_RC)(0xB00)
-#define TPM_RC_C                 (TPM_RC)(0xC00)
-#define TPM_RC_D                 (TPM_RC)(0xD00)
-#define TPM_RC_E                 (TPM_RC)(0xE00)
-#define TPM_RC_F                 (TPM_RC)(0xF00)
-#define TPM_RC_N_MASK            (TPM_RC)(0xF00)
-
-// Table 16 - TPM_CLOCK_ADJUST Constants
-typedef INT8 TPM_CLOCK_ADJUST;
-#define TPM_CLOCK_COARSE_SLOWER (TPM_CLOCK_ADJUST)(-3)
-#define TPM_CLOCK_MEDIUM_SLOWER (TPM_CLOCK_ADJUST)(-2)
-#define TPM_CLOCK_FINE_SLOWER   (TPM_CLOCK_ADJUST)(-1)
-#define TPM_CLOCK_NO_CHANGE     (TPM_CLOCK_ADJUST)(0)
-#define TPM_CLOCK_FINE_FASTER   (TPM_CLOCK_ADJUST)(1)
-#define TPM_CLOCK_MEDIUM_FASTER (TPM_CLOCK_ADJUST)(2)
-#define TPM_CLOCK_COARSE_FASTER (TPM_CLOCK_ADJUST)(3)
-
-// Table 17 - TPM_EO Constants
-typedef UINT16 TPM_EO;
-#define TPM_EO_EQ          (TPM_EO)(0x0000)
-#define TPM_EO_NEQ         (TPM_EO)(0x0001)
-#define TPM_EO_SIGNED_GT   (TPM_EO)(0x0002)
-#define TPM_EO_UNSIGNED_GT (TPM_EO)(0x0003)
-#define TPM_EO_SIGNED_LT   (TPM_EO)(0x0004)
-#define TPM_EO_UNSIGNED_LT (TPM_EO)(0x0005)
-#define TPM_EO_SIGNED_GE   (TPM_EO)(0x0006)
-#define TPM_EO_UNSIGNED_GE (TPM_EO)(0x0007)
-#define TPM_EO_SIGNED_LE   (TPM_EO)(0x0008)
-#define TPM_EO_UNSIGNED_LE (TPM_EO)(0x0009)
-#define TPM_EO_BITSET      (TPM_EO)(0x000A)
-#define TPM_EO_BITCLEAR    (TPM_EO)(0x000B)
-
-// Table 18 - TPM_ST Constants
-typedef UINT16 TPM_ST;
-#define TPM_ST_RSP_COMMAND          (TPM_ST)(0x00C4)
-#define TPM_ST_NULL                 (TPM_ST)(0X8000)
-#define TPM_ST_NO_SESSIONS          (TPM_ST)(0x8001)
-#define TPM_ST_SESSIONS             (TPM_ST)(0x8002)
-#define TPM_ST_ATTEST_NV            (TPM_ST)(0x8014)
-#define TPM_ST_ATTEST_COMMAND_AUDIT (TPM_ST)(0x8015)
-#define TPM_ST_ATTEST_SESSION_AUDIT (TPM_ST)(0x8016)
-#define TPM_ST_ATTEST_CERTIFY       (TPM_ST)(0x8017)
-#define TPM_ST_ATTEST_QUOTE         (TPM_ST)(0x8018)
-#define TPM_ST_ATTEST_TIME          (TPM_ST)(0x8019)
-#define TPM_ST_ATTEST_CREATION      (TPM_ST)(0x801A)
-#define TPM_ST_CREATION             (TPM_ST)(0x8021)
-#define TPM_ST_VERIFIED             (TPM_ST)(0x8022)
-#define TPM_ST_AUTH_SECRET          (TPM_ST)(0x8023)
-#define TPM_ST_HASHCHECK            (TPM_ST)(0x8024)
-#define TPM_ST_AUTH_SIGNED          (TPM_ST)(0x8025)
-#define TPM_ST_FU_MANIFEST          (TPM_ST)(0x8029)
-
-// Table 19 - TPM_SU Constants
-typedef UINT16 TPM_SU;
-#define TPM_SU_CLEAR (TPM_SU)(0x0000)
-#define TPM_SU_STATE (TPM_SU)(0x0001)
-
-// Table 20 - TPM_SE Constants
-typedef UINT8 TPM_SE;
-#define TPM_SE_HMAC   (TPM_SE)(0x00)
-#define TPM_SE_POLICY (TPM_SE)(0x01)
-#define TPM_SE_TRIAL  (TPM_SE)(0x03)
-
-// Table 21 - TPM_CAP Constants
-typedef UINT32 TPM_CAP;
-#define TPM_CAP_FIRST           (TPM_CAP)(0x00000000)
-#define TPM_CAP_ALGS            (TPM_CAP)(0x00000000)
-#define TPM_CAP_HANDLES         (TPM_CAP)(0x00000001)
-#define TPM_CAP_COMMANDS        (TPM_CAP)(0x00000002)
-#define TPM_CAP_PP_COMMANDS     (TPM_CAP)(0x00000003)
-#define TPM_CAP_AUDIT_COMMANDS  (TPM_CAP)(0x00000004)
-#define TPM_CAP_PCRS            (TPM_CAP)(0x00000005)
-#define TPM_CAP_TPM_PROPERTIES  (TPM_CAP)(0x00000006)
-#define TPM_CAP_PCR_PROPERTIES  (TPM_CAP)(0x00000007)
-#define TPM_CAP_ECC_CURVES      (TPM_CAP)(0x00000008)
-#define TPM_CAP_LAST            (TPM_CAP)(0x00000008)
-#define TPM_CAP_VENDOR_PROPERTY (TPM_CAP)(0x00000100)
-
-// Table 22 - TPM_PT Constants
-typedef UINT32 TPM_PT;
-#define TPM_PT_NONE                (TPM_PT)(0x00000000)
-#define PT_GROUP                   (TPM_PT)(0x00000100)
-#define PT_FIXED                   (TPM_PT)(PT_GROUP * 1)
-#define TPM_PT_FAMILY_INDICATOR    (TPM_PT)(PT_FIXED + 0)
-#define TPM_PT_LEVEL               (TPM_PT)(PT_FIXED + 1)
-#define TPM_PT_REVISION            (TPM_PT)(PT_FIXED + 2)
-#define TPM_PT_DAY_OF_YEAR         (TPM_PT)(PT_FIXED + 3)
-#define TPM_PT_YEAR                (TPM_PT)(PT_FIXED + 4)
-#define TPM_PT_MANUFACTURER        (TPM_PT)(PT_FIXED + 5)
-#define TPM_PT_VENDOR_STRING_1     (TPM_PT)(PT_FIXED + 6)
-#define TPM_PT_VENDOR_STRING_2     (TPM_PT)(PT_FIXED + 7)
-#define TPM_PT_VENDOR_STRING_3     (TPM_PT)(PT_FIXED + 8)
-#define TPM_PT_VENDOR_STRING_4     (TPM_PT)(PT_FIXED + 9)
-#define TPM_PT_VENDOR_TPM_TYPE     (TPM_PT)(PT_FIXED + 10)
-#define TPM_PT_FIRMWARE_VERSION_1  (TPM_PT)(PT_FIXED + 11)
-#define TPM_PT_FIRMWARE_VERSION_2  (TPM_PT)(PT_FIXED + 12)
-#define TPM_PT_INPUT_BUFFER        (TPM_PT)(PT_FIXED + 13)
-#define TPM_PT_HR_TRANSIENT_MIN    (TPM_PT)(PT_FIXED + 14)
-#define TPM_PT_HR_PERSISTENT_MIN   (TPM_PT)(PT_FIXED + 15)
-#define TPM_PT_HR_LOADED_MIN       (TPM_PT)(PT_FIXED + 16)
-#define TPM_PT_ACTIVE_SESSIONS_MAX (TPM_PT)(PT_FIXED + 17)
-#define TPM_PT_PCR_COUNT           (TPM_PT)(PT_FIXED + 18)
-#define TPM_PT_PCR_SELECT_MIN      (TPM_PT)(PT_FIXED + 19)
-#define TPM_PT_CONTEXT_GAP_MAX     (TPM_PT)(PT_FIXED + 20)
-#define TPM_PT_NV_COUNTERS_MAX     (TPM_PT)(PT_FIXED + 22)
-#define TPM_PT_NV_INDEX_MAX        (TPM_PT)(PT_FIXED + 23)
-#define TPM_PT_MEMORY              (TPM_PT)(PT_FIXED + 24)
-#define TPM_PT_CLOCK_UPDATE        (TPM_PT)(PT_FIXED + 25)
-#define TPM_PT_CONTEXT_HASH        (TPM_PT)(PT_FIXED + 26)
-#define TPM_PT_CONTEXT_SYM         (TPM_PT)(PT_FIXED + 27)
-#define TPM_PT_CONTEXT_SYM_SIZE    (TPM_PT)(PT_FIXED + 28)
-#define TPM_PT_ORDERLY_COUNT       (TPM_PT)(PT_FIXED + 29)
-#define TPM_PT_MAX_COMMAND_SIZE    (TPM_PT)(PT_FIXED + 30)
-#define TPM_PT_MAX_RESPONSE_SIZE   (TPM_PT)(PT_FIXED + 31)
-#define TPM_PT_MAX_DIGEST          (TPM_PT)(PT_FIXED + 32)
-#define TPM_PT_MAX_OBJECT_CONTEXT  (TPM_PT)(PT_FIXED + 33)
-#define TPM_PT_MAX_SESSION_CONTEXT (TPM_PT)(PT_FIXED + 34)
-#define TPM_PT_PS_FAMILY_INDICATOR (TPM_PT)(PT_FIXED + 35)
-#define TPM_PT_PS_LEVEL            (TPM_PT)(PT_FIXED + 36)
-#define TPM_PT_PS_REVISION         (TPM_PT)(PT_FIXED + 37)
-#define TPM_PT_PS_DAY_OF_YEAR      (TPM_PT)(PT_FIXED + 38)
-#define TPM_PT_PS_YEAR             (TPM_PT)(PT_FIXED + 39)
-#define TPM_PT_SPLIT_MAX           (TPM_PT)(PT_FIXED + 40)
-#define TPM_PT_TOTAL_COMMANDS      (TPM_PT)(PT_FIXED + 41)
-#define TPM_PT_LIBRARY_COMMANDS    (TPM_PT)(PT_FIXED + 42)
-#define TPM_PT_VENDOR_COMMANDS     (TPM_PT)(PT_FIXED + 43)
-#define PT_VAR                     (TPM_PT)(PT_GROUP * 2)
-#define TPM_PT_PERMANENT           (TPM_PT)(PT_VAR + 0)
-#define TPM_PT_STARTUP_CLEAR       (TPM_PT)(PT_VAR + 1)
-#define TPM_PT_HR_NV_INDEX         (TPM_PT)(PT_VAR + 2)
-#define TPM_PT_HR_LOADED           (TPM_PT)(PT_VAR + 3)
-#define TPM_PT_HR_LOADED_AVAIL     (TPM_PT)(PT_VAR + 4)
-#define TPM_PT_HR_ACTIVE           (TPM_PT)(PT_VAR + 5)
-#define TPM_PT_HR_ACTIVE_AVAIL     (TPM_PT)(PT_VAR + 6)
-#define TPM_PT_HR_TRANSIENT_AVAIL  (TPM_PT)(PT_VAR + 7)
-#define TPM_PT_HR_PERSISTENT       (TPM_PT)(PT_VAR + 8)
-#define TPM_PT_HR_PERSISTENT_AVAIL (TPM_PT)(PT_VAR + 9)
-#define TPM_PT_NV_COUNTERS         (TPM_PT)(PT_VAR + 10)
-#define TPM_PT_NV_COUNTERS_AVAIL   (TPM_PT)(PT_VAR + 11)
-#define TPM_PT_ALGORITHM_SET       (TPM_PT)(PT_VAR + 12)
-#define TPM_PT_LOADED_CURVES       (TPM_PT)(PT_VAR + 13)
-#define TPM_PT_LOCKOUT_COUNTER     (TPM_PT)(PT_VAR + 14)
-#define TPM_PT_MAX_AUTH_FAIL       (TPM_PT)(PT_VAR + 15)
-#define TPM_PT_LOCKOUT_INTERVAL    (TPM_PT)(PT_VAR + 16)
-#define TPM_PT_LOCKOUT_RECOVERY    (TPM_PT)(PT_VAR + 17)
-#define TPM_PT_NV_WRITE_RECOVERY   (TPM_PT)(PT_VAR + 18)
-#define TPM_PT_AUDIT_COUNTER_0     (TPM_PT)(PT_VAR + 19)
-#define TPM_PT_AUDIT_COUNTER_1     (TPM_PT)(PT_VAR + 20)
-
-// Table 23 - TPM_PT_PCR Constants
-typedef UINT32 TPM_PT_PCR;
-#define TPM_PT_PCR_FIRST        (TPM_PT_PCR)(0x00000000)
-#define TPM_PT_PCR_SAVE         (TPM_PT_PCR)(0x00000000)
-#define TPM_PT_PCR_EXTEND_L0    (TPM_PT_PCR)(0x00000001)
-#define TPM_PT_PCR_RESET_L0     (TPM_PT_PCR)(0x00000002)
-#define TPM_PT_PCR_EXTEND_L1    (TPM_PT_PCR)(0x00000003)
-#define TPM_PT_PCR_RESET_L1     (TPM_PT_PCR)(0x00000004)
-#define TPM_PT_PCR_EXTEND_L2    (TPM_PT_PCR)(0x00000005)
-#define TPM_PT_PCR_RESET_L2     (TPM_PT_PCR)(0x00000006)
-#define TPM_PT_PCR_EXTEND_L3    (TPM_PT_PCR)(0x00000007)
-#define TPM_PT_PCR_RESET_L3     (TPM_PT_PCR)(0x00000008)
-#define TPM_PT_PCR_EXTEND_L4    (TPM_PT_PCR)(0x00000009)
-#define TPM_PT_PCR_RESET_L4     (TPM_PT_PCR)(0x0000000A)
-#define TPM_PT_PCR_NO_INCREMENT (TPM_PT_PCR)(0x00000011)
-#define TPM_PT_PCR_DRTM_RESET   (TPM_PT_PCR)(0x00000012)
-#define TPM_PT_PCR_POLICY       (TPM_PT_PCR)(0x00000013)
-#define TPM_PT_PCR_AUTH         (TPM_PT_PCR)(0x00000014)
-#define TPM_PT_PCR_LAST         (TPM_PT_PCR)(0x00000014)
-
-// Table 24 - TPM_PS Constants
-typedef UINT32 TPM_PS;
-#define TPM_PS_MAIN           (TPM_PS)(0x00000000)
-#define TPM_PS_PC             (TPM_PS)(0x00000001)
-#define TPM_PS_PDA            (TPM_PS)(0x00000002)
-#define TPM_PS_CELL_PHONE     (TPM_PS)(0x00000003)
-#define TPM_PS_SERVER         (TPM_PS)(0x00000004)
-#define TPM_PS_PERIPHERAL     (TPM_PS)(0x00000005)
-#define TPM_PS_TSS            (TPM_PS)(0x00000006)
-#define TPM_PS_STORAGE        (TPM_PS)(0x00000007)
-#define TPM_PS_AUTHENTICATION (TPM_PS)(0x00000008)
-#define TPM_PS_EMBEDDED       (TPM_PS)(0x00000009)
-#define TPM_PS_HARDCOPY       (TPM_PS)(0x0000000A)
-#define TPM_PS_INFRASTRUCTURE (TPM_PS)(0x0000000B)
-#define TPM_PS_VIRTUALIZATION (TPM_PS)(0x0000000C)
-#define TPM_PS_TNC            (TPM_PS)(0x0000000D)
-#define TPM_PS_MULTI_TENANT   (TPM_PS)(0x0000000E)
-#define TPM_PS_TC             (TPM_PS)(0x0000000F)
-
-// 7 Handles
-
-// Table 25 - Handles Types
-//
-// NOTE: Comment because it has same name as TPM1.2 (value is same, so not runtime issue)
-//
-//typedef UINT32    TPM_HANDLE;
-
-// Table 26 - TPM_HT Constants
-typedef UINT8 TPM_HT;
-#define TPM_HT_PCR            (TPM_HT)(0x00)
-#define TPM_HT_NV_INDEX       (TPM_HT)(0x01)
-#define TPM_HT_HMAC_SESSION   (TPM_HT)(0x02)
-#define TPM_HT_LOADED_SESSION (TPM_HT)(0x02)
-#define TPM_HT_POLICY_SESSION (TPM_HT)(0x03)
-#define TPM_HT_ACTIVE_SESSION (TPM_HT)(0x03)
-#define TPM_HT_PERMANENT      (TPM_HT)(0x40)
-#define TPM_HT_TRANSIENT      (TPM_HT)(0x80)
-#define TPM_HT_PERSISTENT     (TPM_HT)(0x81)
-
-// Table 27 - TPM_RH Constants
-typedef UINT32 TPM_RH;
-#define TPM_RH_FIRST       (TPM_RH)(0x40000000)
-#define TPM_RH_SRK         (TPM_RH)(0x40000000)
-#define TPM_RH_OWNER       (TPM_RH)(0x40000001)
-#define TPM_RH_REVOKE      (TPM_RH)(0x40000002)
-#define TPM_RH_TRANSPORT   (TPM_RH)(0x40000003)
-#define TPM_RH_OPERATOR    (TPM_RH)(0x40000004)
-#define TPM_RH_ADMIN       (TPM_RH)(0x40000005)
-#define TPM_RH_EK          (TPM_RH)(0x40000006)
-#define TPM_RH_NULL        (TPM_RH)(0x40000007)
-#define TPM_RH_UNASSIGNED  (TPM_RH)(0x40000008)
-#define TPM_RS_PW          (TPM_RH)(0x40000009)
-#define TPM_RH_LOCKOUT     (TPM_RH)(0x4000000A)
-#define TPM_RH_ENDORSEMENT (TPM_RH)(0x4000000B)
-#define TPM_RH_PLATFORM    (TPM_RH)(0x4000000C)
-#define TPM_RH_PLATFORM_NV (TPM_RH)(0x4000000D)
-#define TPM_RH_AUTH_00     (TPM_RH)(0x40000010)
-#define TPM_RH_AUTH_FF     (TPM_RH)(0x4000010F)
-#define TPM_RH_LAST        (TPM_RH)(0x4000010F)
-
-// Table 28 - TPM_HC Constants
-typedef TPM_HANDLE TPM_HC;
-#define HR_HANDLE_MASK       (TPM_HC)(0x00FFFFFF)
-#define HR_RANGE_MASK        (TPM_HC)(0xFF000000)
-#define HR_SHIFT             (TPM_HC)(24)
-#define HR_PCR               (TPM_HC)((TPM_HC)TPM_HT_PCR << HR_SHIFT)
-#define HR_HMAC_SESSION      (TPM_HC)((TPM_HC)TPM_HT_HMAC_SESSION << HR_SHIFT)
-#define HR_POLICY_SESSION    (TPM_HC)((TPM_HC)TPM_HT_POLICY_SESSION << HR_SHIFT)
-#define HR_TRANSIENT         (TPM_HC)((TPM_HC)TPM_HT_TRANSIENT << HR_SHIFT)
-#define HR_PERSISTENT        (TPM_HC)((TPM_HC)TPM_HT_PERSISTENT << HR_SHIFT)
-#define HR_NV_INDEX          (TPM_HC)((TPM_HC)TPM_HT_NV_INDEX << HR_SHIFT)
-#define HR_PERMANENT         (TPM_HC)((TPM_HC)TPM_HT_PERMANENT << HR_SHIFT)
-#define PCR_FIRST            (TPM_HC)(HR_PCR + 0)
-#define PCR_LAST             (TPM_HC)(PCR_FIRST + IMPLEMENTATION_PCR - 1)
-#define HMAC_SESSION_FIRST   (TPM_HC)(HR_HMAC_SESSION + 0)
-#define HMAC_SESSION_LAST    (TPM_HC)(HMAC_SESSION_FIRST + MAX_ACTIVE_SESSIONS - 1)
-#define LOADED_SESSION_FIRST (TPM_HC)(HMAC_SESSION_FIRST)
-#define LOADED_SESSION_LAST  (TPM_HC)(HMAC_SESSION_LAST)
-#define POLICY_SESSION_FIRST (TPM_HC)(HR_POLICY_SESSION + 0)
-#define POLICY_SESSION_LAST  (TPM_HC)(POLICY_SESSION_FIRST + MAX_ACTIVE_SESSIONS - 1)
-#define TRANSIENT_FIRST      (TPM_HC)(HR_TRANSIENT + 0)
-#define ACTIVE_SESSION_FIRST (TPM_HC)(POLICY_SESSION_FIRST)
-#define ACTIVE_SESSION_LAST  (TPM_HC)(POLICY_SESSION_LAST)
-#define TRANSIENT_LAST       (TPM_HC)(TRANSIENT_FIRST+MAX_LOADED_OBJECTS - 1)
-#define PERSISTENT_FIRST     (TPM_HC)(HR_PERSISTENT + 0)
-#define PERSISTENT_LAST      (TPM_HC)(PERSISTENT_FIRST + 0x00FFFFFF)
-#define PLATFORM_PERSISTENT  (TPM_HC)(PERSISTENT_FIRST + 0x00800000)
-#define NV_INDEX_FIRST       (TPM_HC)(HR_NV_INDEX + 0)
-#define NV_INDEX_LAST        (TPM_HC)(NV_INDEX_FIRST + 0x00FFFFFF)
-#define PERMANENT_FIRST      (TPM_HC)(TPM_RH_FIRST)
-#define PERMANENT_LAST       (TPM_HC)(TPM_RH_LAST)
-
-// 8 Attribute Structures
-
-// Table 29 - TPMA_ALGORITHM Bits
-typedef struct {
-  UINT32 asymmetric    : 1;
-  UINT32 symmetric     : 1;
-  UINT32 hash          : 1;
-  UINT32 object        : 1;
-  UINT32 reserved4_7   : 4;
-  UINT32 signing       : 1;
-  UINT32 encrypting    : 1;
-  UINT32 method        : 1;
-  UINT32 reserved11_31 : 21;
-} TPMA_ALGORITHM;
-
-// Table 30 - TPMA_OBJECT Bits
-typedef struct {
-  UINT32 reserved1            : 1;
-  UINT32 fixedTPM             : 1;
-  UINT32 stClear              : 1;
-  UINT32 reserved4            : 1;
-  UINT32 fixedParent          : 1;
-  UINT32 sensitiveDataOrigin  : 1;
-  UINT32 userWithAuth         : 1;
-  UINT32 adminWithPolicy      : 1;
-  UINT32 reserved8_9          : 2;
-  UINT32 noDA                 : 1;
-  UINT32 encryptedDuplication : 1;
-  UINT32 reserved12_15        : 4;
-  UINT32 restricted           : 1;
-  UINT32 decrypt              : 1;
-  UINT32 sign                 : 1;
-  UINT32 reserved19_31        : 13;
-} TPMA_OBJECT;
-
-// Table 31 - TPMA_SESSION Bits
-typedef struct {
-  UINT8 continueSession : 1;
-  UINT8 auditExclusive  : 1;
-  UINT8 auditReset      : 1;
-  UINT8 reserved3_4     : 2;
-  UINT8 decrypt         : 1;
-  UINT8 encrypt         : 1;
-  UINT8 audit           : 1;
-} TPMA_SESSION;
-
-// Table 32 - TPMA_LOCALITY Bits
-//
-// NOTE: Use low case here to resolve conflict
-//
-typedef struct {
-  UINT8 locZero  : 1;
-  UINT8 locOne   : 1;
-  UINT8 locTwo   : 1;
-  UINT8 locThree : 1;
-  UINT8 locFour  : 1;
-  UINT8 Extended : 3;
-} TPMA_LOCALITY;
-
-// Table 33 - TPMA_PERMANENT Bits
-typedef struct {
-  UINT32 ownerAuthSet       : 1;
-  UINT32 endorsementAuthSet : 1;
-  UINT32 lockoutAuthSet     : 1;
-  UINT32 reserved3_7        : 5;
-  UINT32 disableClear       : 1;
-  UINT32 inLockout          : 1;
-  UINT32 tpmGeneratedEPS    : 1;
-  UINT32 reserved11_31      : 21;
-} TPMA_PERMANENT;
-
-// Table 34 - TPMA_STARTUP_CLEAR Bits
-typedef struct {
-  UINT32 phEnable     : 1;
-  UINT32 shEnable     : 1;
-  UINT32 ehEnable     : 1;
-  UINT32 reserved3_30 : 28;
-  UINT32 orderly      : 1;
-} TPMA_STARTUP_CLEAR;
-
-// Table 35 - TPMA_MEMORY Bits
-typedef struct {
-  UINT32 sharedRAM         : 1;
-  UINT32 sharedNV          : 1;
-  UINT32 objectCopiedToRam : 1;
-  UINT32 reserved3_31      : 29;
-} TPMA_MEMORY;
-
-// Table 36 - TPMA_CC Bits
-typedef struct {
-  UINT32 commandIndex  : 16;
-  UINT32 reserved16_21 : 6;
-  UINT32 nv            : 1;
-  UINT32 extensive     : 1;
-  UINT32 flushed       : 1;
-  UINT32 cHandles      : 3;
-  UINT32 rHandle       : 1;
-  UINT32 V             : 1;
-  UINT32 Res           : 2;
-} TPMA_CC;
-
-// 9 Interface Types
-
-// Table 37 - TPMI_YES_NO Type
-typedef BYTE TPMI_YES_NO;
-
-// Table 38 - TPMI_DH_OBJECT Type
-typedef TPM_HANDLE TPMI_DH_OBJECT;
-
-// Table 39 - TPMI_DH_PERSISTENT Type
-typedef TPM_HANDLE TPMI_DH_PERSISTENT;
-
-// Table 40 - TPMI_DH_ENTITY Type
-typedef TPM_HANDLE TPMI_DH_ENTITY;
-
-// Table 41 - TPMI_DH_PCR Type
-typedef TPM_HANDLE TPMI_DH_PCR;
-
-// Table 42 - TPMI_SH_AUTH_SESSION Type
-typedef TPM_HANDLE TPMI_SH_AUTH_SESSION;
-
-// Table 43 - TPMI_SH_HMAC Type
-typedef TPM_HANDLE TPMI_SH_HMAC;
-
-// Table 44 - TPMI_SH_POLICY Type
-typedef TPM_HANDLE TPMI_SH_POLICY;
-
-// Table 45 - TPMI_DH_CONTEXT Type
-typedef TPM_HANDLE TPMI_DH_CONTEXT;
-
-// Table 46 - TPMI_RH_HIERARCHY Type
-typedef TPM_HANDLE TPMI_RH_HIERARCHY;
-
-// Table 47 - TPMI_RH_HIERARCHY_AUTH Type
-typedef TPM_HANDLE TPMI_RH_HIERARCHY_AUTH;
-
-// Table 48 - TPMI_RH_PLATFORM Type
-typedef TPM_HANDLE TPMI_RH_PLATFORM;
-
-// Table 49 - TPMI_RH_OWNER Type
-typedef TPM_HANDLE TPMI_RH_OWNER;
-
-// Table 50 - TPMI_RH_ENDORSEMENT Type
-typedef TPM_HANDLE TPMI_RH_ENDORSEMENT;
-
-// Table 51 - TPMI_RH_PROVISION Type
-typedef TPM_HANDLE TPMI_RH_PROVISION;
-
-// Table 52 - TPMI_RH_CLEAR Type
-typedef TPM_HANDLE TPMI_RH_CLEAR;
-
-// Table 53 - TPMI_RH_NV_AUTH Type
-typedef TPM_HANDLE TPMI_RH_NV_AUTH;
-
-// Table 54 - TPMI_RH_LOCKOUT Type
-typedef TPM_HANDLE TPMI_RH_LOCKOUT;
-
-// Table 55 - TPMI_RH_NV_INDEX Type
-typedef TPM_HANDLE TPMI_RH_NV_INDEX;
-
-// Table 56 - TPMI_ALG_HASH Type
-typedef TPM_ALG_ID TPMI_ALG_HASH;
-
-// Table 57 - TPMI_ALG_ASYM Type
-typedef TPM_ALG_ID TPMI_ALG_ASYM;
-
-// Table 58 - TPMI_ALG_SYM Type
-typedef TPM_ALG_ID TPMI_ALG_SYM;
-
-// Table 59 - TPMI_ALG_SYM_OBJECT Type
-typedef TPM_ALG_ID TPMI_ALG_SYM_OBJECT;
-
-// Table 60 - TPMI_ALG_SYM_MODE Type
-typedef TPM_ALG_ID TPMI_ALG_SYM_MODE;
-
-// Table 61 - TPMI_ALG_KDF Type
-typedef TPM_ALG_ID TPMI_ALG_KDF;
-
-// Table 62 - TPMI_ALG_SIG_SCHEME Type
-typedef TPM_ALG_ID TPMI_ALG_SIG_SCHEME;
-
-// Table 63 - TPMI_ECC_KEY_EXCHANGE Type
-typedef TPM_ALG_ID TPMI_ECC_KEY_EXCHANGE;
-
-// Table 64 - TPMI_ST_COMMAND_TAG Type
-typedef TPM_ST TPMI_ST_COMMAND_TAG;
-
-// 10 Structure Definitions
-
-// Table 65 - TPMS_ALGORITHM_DESCRIPTION Structure
-typedef struct {
-  TPM_ALG_ID     alg;
-  TPMA_ALGORITHM attributes;
-} TPMS_ALGORITHM_DESCRIPTION;
-
-// Table 66 - TPMU_HA Union
-typedef union {
-  BYTE sha1[SHA1_DIGEST_SIZE];
-  BYTE sha256[SHA256_DIGEST_SIZE];
-  BYTE sm3_256[SM3_256_DIGEST_SIZE];
-  BYTE sha384[SHA384_DIGEST_SIZE];
-  BYTE sha512[SHA512_DIGEST_SIZE];
-} TPMU_HA;
-
-// Table 67 - TPMT_HA Structure
-typedef struct {
-  TPMI_ALG_HASH hashAlg;
-  TPMU_HA       digest;
-} TPMT_HA;
-
-// Table 68 - TPM2B_DIGEST Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[sizeof(TPMU_HA)];
-} TPM2B_DIGEST;
-
-// Table 69 - TPM2B_DATA Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[sizeof(TPMT_HA)];
-} TPM2B_DATA;
-
-// Table 70 - TPM2B_NONCE Types
-typedef TPM2B_DIGEST TPM2B_NONCE;
-
-// Table 71 - TPM2B_AUTH Types
-typedef TPM2B_DIGEST TPM2B_AUTH;
-
-// Table 72 - TPM2B_OPERAND Types
-typedef TPM2B_DIGEST TPM2B_OPERAND;
-
-// Table 73 - TPM2B_EVENT Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[1024];
-} TPM2B_EVENT;
-
-// Table 74 - TPM2B_MAX_BUFFER Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[MAX_DIGEST_BUFFER];
-} TPM2B_MAX_BUFFER;
-
-// Table 75 - TPM2B_MAX_NV_BUFFER Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[MAX_NV_INDEX_SIZE];
-} TPM2B_MAX_NV_BUFFER;
-
-// Table 76 - TPM2B_TIMEOUT Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[sizeof(UINT64)];
-} TPM2B_TIMEOUT;
-
-// Table 77 -- TPM2B_IV Structure <I/O>
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[MAX_SYM_BLOCK_SIZE];
-} TPM2B_IV;
-
-// Table 78 - TPMU_NAME Union
-typedef union {
-  TPMT_HA    digest;
-  TPM_HANDLE handle;
-} TPMU_NAME;
-
-// Table 79 - TPM2B_NAME Structure
-typedef struct {
-  UINT16 size;
-  BYTE   name[sizeof(TPMU_NAME)];
-} TPM2B_NAME;
-
-// Table 80 - TPMS_PCR_SELECT Structure
-typedef struct {
-  UINT8 sizeofSelect;
-  BYTE  pcrSelect[PCR_SELECT_MAX];
-} TPMS_PCR_SELECT;
-
-// Table 81 - TPMS_PCR_SELECTION Structure
-typedef struct {
-  TPMI_ALG_HASH hash;
-  UINT8         sizeofSelect;
-  BYTE          pcrSelect[PCR_SELECT_MAX];
-} TPMS_PCR_SELECTION;
-
-// Table 84 - TPMT_TK_CREATION Structure
-typedef struct {
-  TPM_ST            tag;
-  TPMI_RH_HIERARCHY hierarchy;
-  TPM2B_DIGEST      digest;
-} TPMT_TK_CREATION;
-
-// Table 85 - TPMT_TK_VERIFIED Structure
-typedef struct {
-  TPM_ST            tag;
-  TPMI_RH_HIERARCHY hierarchy;
-  TPM2B_DIGEST      digest;
-} TPMT_TK_VERIFIED;
-
-// Table 86 - TPMT_TK_AUTH Structure
-typedef struct {
-  TPM_ST            tag;
-  TPMI_RH_HIERARCHY hierarchy;
-  TPM2B_DIGEST      digest;
-} TPMT_TK_AUTH;
-
-// Table 87 - TPMT_TK_HASHCHECK Structure
-typedef struct {
-  TPM_ST            tag;
-  TPMI_RH_HIERARCHY hierarchy;
-  TPM2B_DIGEST      digest;
-} TPMT_TK_HASHCHECK;
-
-// Table 88 - TPMS_ALG_PROPERTY Structure
-typedef struct {
-  TPM_ALG_ID     alg;
-  TPMA_ALGORITHM algProperties;
-} TPMS_ALG_PROPERTY;
-
-// Table 89 - TPMS_TAGGED_PROPERTY Structure
-typedef struct {
-  TPM_PT property;
-  UINT32 value;
-} TPMS_TAGGED_PROPERTY;
-
-// Table 90 - TPMS_TAGGED_PCR_SELECT Structure
-typedef struct {
-  TPM_PT tag;
-  UINT8  sizeofSelect;
-  BYTE   pcrSelect[PCR_SELECT_MAX];
-} TPMS_TAGGED_PCR_SELECT;
-
-// Table 91 - TPML_CC Structure
-typedef struct {
-  UINT32 count;
-  TPM_CC commandCodes[MAX_CAP_CC];
-} TPML_CC;
-
-// Table 92 - TPML_CCA Structure
-typedef struct {
-  UINT32  count;
-  TPMA_CC commandAttributes[MAX_CAP_CC];
-} TPML_CCA;
-
-// Table 93 - TPML_ALG Structure
-typedef struct {
-  UINT32     count;
-  TPM_ALG_ID algorithms[MAX_ALG_LIST_SIZE];
-} TPML_ALG;
-
-// Table 94 - TPML_HANDLE Structure
-typedef struct {
-  UINT32     count;
-  TPM_HANDLE handle[MAX_CAP_HANDLES];
-} TPML_HANDLE;
-
-// Table 95 - TPML_DIGEST Structure
-typedef struct {
-  UINT32       count;
-  TPM2B_DIGEST digests[8];
-} TPML_DIGEST;
-
-// Table 96 -- TPML_DIGEST_VALUES Structure <I/O>
-typedef struct {
-  UINT32  count;
-  TPMT_HA digests[HASH_COUNT];
-} TPML_DIGEST_VALUES;
-
-// Table 97 - TPM2B_DIGEST_VALUES Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[sizeof(TPML_DIGEST_VALUES)];
-} TPM2B_DIGEST_VALUES;
-
-// Table 98 - TPML_PCR_SELECTION Structure
-typedef struct {
-  UINT32             count;
-  TPMS_PCR_SELECTION pcrSelections[HASH_COUNT];
-} TPML_PCR_SELECTION;
-
-// Table 99 - TPML_ALG_PROPERTY Structure
-typedef struct {
-  UINT32            count;
-  TPMS_ALG_PROPERTY algProperties[MAX_CAP_ALGS];
-} TPML_ALG_PROPERTY;
-
-// Table 100 - TPML_TAGGED_TPM_PROPERTY Structure
-typedef struct {
-  UINT32               count;
-  TPMS_TAGGED_PROPERTY tpmProperty[MAX_TPM_PROPERTIES];
-} TPML_TAGGED_TPM_PROPERTY;
-
-// Table 101 - TPML_TAGGED_PCR_PROPERTY Structure
-typedef struct {
-  UINT32                 count;
-  TPMS_TAGGED_PCR_SELECT pcrProperty[MAX_PCR_PROPERTIES];
-} TPML_TAGGED_PCR_PROPERTY;
-
-// Table 102 - TPML_ECC_CURVE Structure
-typedef struct {
-  UINT32        count;
-  TPM_ECC_CURVE eccCurves[MAX_ECC_CURVES];
-} TPML_ECC_CURVE;
-
-// Table 103 - TPMU_CAPABILITIES Union
-typedef union {
-  TPML_ALG_PROPERTY        algorithms;
-  TPML_HANDLE              handles;
-  TPML_CCA                 command;
-  TPML_CC                  ppCommands;
-  TPML_CC                  auditCommands;
-  TPML_PCR_SELECTION       assignedPCR;
-  TPML_TAGGED_TPM_PROPERTY tpmProperties;
-  TPML_TAGGED_PCR_PROPERTY pcrProperties;
-  TPML_ECC_CURVE           eccCurves;
-} TPMU_CAPABILITIES;
-
-// Table 104 - TPMS_CAPABILITY_DATA Structure
-typedef struct {
-  TPM_CAP           capability;
-  TPMU_CAPABILITIES data;
-} TPMS_CAPABILITY_DATA;
-
-// Table 105 - TPMS_CLOCK_INFO Structure
-typedef struct {
-  UINT64      clock;
-  UINT32      resetCount;
-  UINT32      restartCount;
-  TPMI_YES_NO safe;
-} TPMS_CLOCK_INFO;
-
-// Table 106 - TPMS_TIME_INFO Structure
-typedef struct {
-  UINT64          time;
-  TPMS_CLOCK_INFO clockInfo;
-} TPMS_TIME_INFO;
-
-// Table 107 - TPMS_TIME_ATTEST_INFO Structure
-typedef struct {
-  TPMS_TIME_INFO time;
-  UINT64         firmwareVersion;
-} TPMS_TIME_ATTEST_INFO;
-
-// Table 108 - TPMS_CERTIFY_INFO Structure
-typedef struct {
-  TPM2B_NAME name;
-  TPM2B_NAME qualifiedName;
-} TPMS_CERTIFY_INFO;
-
-// Table 109 - TPMS_QUOTE_INFO Structure
-typedef struct {
-  TPML_PCR_SELECTION pcrSelect;
-  TPM2B_DIGEST       pcrDigest;
-} TPMS_QUOTE_INFO;
-
-// Table 110 - TPMS_COMMAND_AUDIT_INFO Structure
-typedef struct {
-  UINT64       auditCounter;
-  TPM_ALG_ID   digestAlg;
-  TPM2B_DIGEST auditDigest;
-  TPM2B_DIGEST commandDigest;
-} TPMS_COMMAND_AUDIT_INFO;
-
-// Table 111 - TPMS_SESSION_AUDIT_INFO Structure
-typedef struct {
-  TPMI_YES_NO  exclusiveSession;
-  TPM2B_DIGEST sessionDigest;
-} TPMS_SESSION_AUDIT_INFO;
-
-// Table 112 - TPMS_CREATION_INFO Structure
-typedef struct {
-  TPM2B_NAME   objectName;
-  TPM2B_DIGEST creationHash;
-} TPMS_CREATION_INFO;
-
-// Table 113 - TPMS_NV_CERTIFY_INFO Structure
-typedef struct {
-  TPM2B_NAME          indexName;
-  UINT16              offset;
-  TPM2B_MAX_NV_BUFFER nvContents;
-} TPMS_NV_CERTIFY_INFO;
-
-// Table 114 - TPMI_ST_ATTEST Type
-typedef TPM_ST TPMI_ST_ATTEST;
-
-// Table 115 - TPMU_ATTEST Union
-typedef union {
-  TPMS_CERTIFY_INFO       certify;
-  TPMS_CREATION_INFO      creation;
-  TPMS_QUOTE_INFO         quote;
-  TPMS_COMMAND_AUDIT_INFO commandAudit;
-  TPMS_SESSION_AUDIT_INFO sessionAudit;
-  TPMS_TIME_ATTEST_INFO   time;
-  TPMS_NV_CERTIFY_INFO    nv;
-} TPMU_ATTEST;
-
-// Table 116 - TPMS_ATTEST Structure
-typedef struct {
-  TPM_GENERATED   magic;
-  TPMI_ST_ATTEST  type;
-  TPM2B_NAME      qualifiedSigner;
-  TPM2B_DATA      extraData;
-  TPMS_CLOCK_INFO clockInfo;
-  UINT64          firmwareVersion;
-  TPMU_ATTEST     attested;
-} TPMS_ATTEST;
-
-// Table 117 - TPM2B_ATTEST Structure
-typedef struct {
-  UINT16 size;
-  BYTE   attestationData[sizeof(TPMS_ATTEST)];
-} TPM2B_ATTEST;
-
-// Table 118 - TPMS_AUTH_COMMAND Structure
-typedef struct {
-  TPMI_SH_AUTH_SESSION sessionHandle;
-  TPM2B_NONCE          nonce;
-  TPMA_SESSION         sessionAttributes;
-  TPM2B_AUTH           hmac;
-} TPMS_AUTH_COMMAND;
-
-// Table 119 - TPMS_AUTH_RESPONSE Structure
-typedef struct {
-  TPM2B_NONCE  nonce;
-  TPMA_SESSION sessionAttributes;
-  TPM2B_AUTH   hmac;
-} TPMS_AUTH_RESPONSE;
-
-// 11 Algorithm Parameters and Structures
-
-// Table 120 - TPMI_AES_KEY_BITS Type
-typedef TPM_KEY_BITS TPMI_AES_KEY_BITS;
-
-// Table 121 - TPMI_SM4_KEY_BITS Type
-typedef TPM_KEY_BITS TPMI_SM4_KEY_BITS;
-
-// Table 122 - TPMU_SYM_KEY_BITS Union
-typedef union {
-  TPMI_AES_KEY_BITS aes;
-  TPMI_SM4_KEY_BITS SM4;
-  TPM_KEY_BITS      sym;
-  TPMI_ALG_HASH     xor;
-} TPMU_SYM_KEY_BITS;
-
-// Table 123 - TPMU_SYM_MODE Union
-typedef union {
-  TPMI_ALG_SYM_MODE aes;
-  TPMI_ALG_SYM_MODE SM4;
-  TPMI_ALG_SYM_MODE sym;
-} TPMU_SYM_MODE;
-
-// Table 125 - TPMT_SYM_DEF Structure
-typedef struct {
-  TPMI_ALG_SYM      algorithm;
-  TPMU_SYM_KEY_BITS keyBits;
-  TPMU_SYM_MODE     mode;
-} TPMT_SYM_DEF;
-
-// Table 126 - TPMT_SYM_DEF_OBJECT Structure
-typedef struct {
-  TPMI_ALG_SYM_OBJECT algorithm;
-  TPMU_SYM_KEY_BITS   keyBits;
-  TPMU_SYM_MODE       mode;
-} TPMT_SYM_DEF_OBJECT;
-
-// Table 127 - TPM2B_SYM_KEY Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[MAX_SYM_KEY_BYTES];
-} TPM2B_SYM_KEY;
-
-// Table 128 - TPMS_SYMCIPHER_PARMS Structure
-typedef struct {
-  TPMT_SYM_DEF_OBJECT sym;
-} TPMS_SYMCIPHER_PARMS;
-
-// Table 129 - TPM2B_SENSITIVE_DATA Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[MAX_SYM_DATA];
-} TPM2B_SENSITIVE_DATA;
-
-// Table 130 - TPMS_SENSITIVE_CREATE Structure
-typedef struct {
-  TPM2B_AUTH           userAuth;
-  TPM2B_SENSITIVE_DATA data;
-} TPMS_SENSITIVE_CREATE;
-
-// Table 131 - TPM2B_SENSITIVE_CREATE Structure
-typedef struct {
-  UINT16                size;
-  TPMS_SENSITIVE_CREATE sensitive;
-} TPM2B_SENSITIVE_CREATE;
-
-// Table 132 - TPMS_SCHEME_SIGHASH Structure
-typedef struct {
-  TPMI_ALG_HASH hashAlg;
-} TPMS_SCHEME_SIGHASH;
-
-// Table 133 - TPMI_ALG_KEYEDHASH_SCHEME Type
-typedef TPM_ALG_ID TPMI_ALG_KEYEDHASH_SCHEME;
-
-// Table 134 - HMAC_SIG_SCHEME Types
-typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_HMAC;
-
-// Table 135 - TPMS_SCHEME_XOR Structure
-typedef struct {
-  TPMI_ALG_HASH hashAlg;
-  TPMI_ALG_KDF  kdf;
-} TPMS_SCHEME_XOR;
-
-// Table 136 - TPMU_SCHEME_KEYEDHASH Union
-typedef union {
-  TPMS_SCHEME_HMAC hmac;
-  TPMS_SCHEME_XOR  xor;
-} TPMU_SCHEME_KEYEDHASH;
-
-// Table 137 - TPMT_KEYEDHASH_SCHEME Structure
-typedef struct {
-  TPMI_ALG_KEYEDHASH_SCHEME scheme;
-  TPMU_SCHEME_KEYEDHASH     details;
-} TPMT_KEYEDHASH_SCHEME;
-
-// Table 138 - RSA_SIG_SCHEMES Types
-typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_RSASSA;
-typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_RSAPSS;
-
-// Table 139 - ECC_SIG_SCHEMES Types
-typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_ECDSA;
-typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_SM2;
-typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_ECSCHNORR;
-
-// Table 140 - TPMS_SCHEME_ECDAA Structure
-typedef struct {
-  TPMI_ALG_HASH hashAlg;
-  UINT16        count;
-} TPMS_SCHEME_ECDAA;
-
-// Table 141 - TPMU_SIG_SCHEME Union
-typedef union {
-  TPMS_SCHEME_RSASSA    rsassa;
-  TPMS_SCHEME_RSAPSS    rsapss;
-  TPMS_SCHEME_ECDSA     ecdsa;
-  TPMS_SCHEME_ECDAA     ecdaa;
-  TPMS_SCHEME_ECSCHNORR ecSchnorr;
-  TPMS_SCHEME_HMAC      hmac;
-  TPMS_SCHEME_SIGHASH   any;
-} TPMU_SIG_SCHEME;
-
-// Table 142 - TPMT_SIG_SCHEME Structure
-typedef struct {
-  TPMI_ALG_SIG_SCHEME scheme;
-  TPMU_SIG_SCHEME     details;
-} TPMT_SIG_SCHEME;
-
-// Table 143 - TPMS_SCHEME_OAEP Structure
-typedef struct {
-  TPMI_ALG_HASH hashAlg;
-} TPMS_SCHEME_OAEP;
-
-// Table 144 - TPMS_SCHEME_ECDH Structure
-typedef struct {
-  TPMI_ALG_HASH hashAlg;
-} TPMS_SCHEME_ECDH;
-
-// Table 145 - TPMS_SCHEME_MGF1 Structure
-typedef struct {
-  TPMI_ALG_HASH hashAlg;
-} TPMS_SCHEME_MGF1;
-
-// Table 146 - TPMS_SCHEME_KDF1_SP800_56a Structure
-typedef struct {
-  TPMI_ALG_HASH hashAlg;
-} TPMS_SCHEME_KDF1_SP800_56a;
-
-// Table 147 - TPMS_SCHEME_KDF2 Structure
-typedef struct {
-  TPMI_ALG_HASH hashAlg;
-} TPMS_SCHEME_KDF2;
-
-// Table 148 - TPMS_SCHEME_KDF1_SP800_108 Structure
-typedef struct {
-  TPMI_ALG_HASH hashAlg;
-} TPMS_SCHEME_KDF1_SP800_108;
-
-// Table 149 - TPMU_KDF_SCHEME Union
-typedef union {
-  TPMS_SCHEME_MGF1           mgf1;
-  TPMS_SCHEME_KDF1_SP800_56a kdf1_SP800_56a;
-  TPMS_SCHEME_KDF2           kdf2;
-  TPMS_SCHEME_KDF1_SP800_108 kdf1_sp800_108;
-} TPMU_KDF_SCHEME;
-
-// Table 150 - TPMT_KDF_SCHEME Structure
-typedef struct {
-  TPMI_ALG_KDF    scheme;
-  TPMU_KDF_SCHEME details;
-} TPMT_KDF_SCHEME;
-
-// Table 151 - TPMI_ALG_ASYM_SCHEME Type
-typedef TPM_ALG_ID TPMI_ALG_ASYM_SCHEME;
-
-// Table 152 - TPMU_ASYM_SCHEME Union
-typedef union {
-  TPMS_SCHEME_RSASSA    rsassa;
-  TPMS_SCHEME_RSAPSS    rsapss;
-  TPMS_SCHEME_OAEP      oaep;
-  TPMS_SCHEME_ECDSA     ecdsa;
-  TPMS_SCHEME_ECDAA     ecdaa;
-  TPMS_SCHEME_ECSCHNORR ecSchnorr;
-  TPMS_SCHEME_SIGHASH   anySig;
-} TPMU_ASYM_SCHEME;
-
-// Table 153 - TPMT_ASYM_SCHEME Structure
-typedef struct {
-  TPMI_ALG_ASYM_SCHEME scheme;
-  TPMU_ASYM_SCHEME     details;
-} TPMT_ASYM_SCHEME;
-
-// Table 154 - TPMI_ALG_RSA_SCHEME Type
-typedef TPM_ALG_ID TPMI_ALG_RSA_SCHEME;
-
-// Table 155 - TPMT_RSA_SCHEME Structure
-typedef struct {
-  TPMI_ALG_RSA_SCHEME scheme;
-  TPMU_ASYM_SCHEME    details;
-} TPMT_RSA_SCHEME;
-
-// Table 156 - TPMI_ALG_RSA_DECRYPT Type
-typedef TPM_ALG_ID TPMI_ALG_RSA_DECRYPT;
-
-// Table 157 - TPMT_RSA_DECRYPT Structure
-typedef struct {
-  TPMI_ALG_RSA_DECRYPT scheme;
-  TPMU_ASYM_SCHEME     details;
-} TPMT_RSA_DECRYPT;
-
-// Table 158 - TPM2B_PUBLIC_KEY_RSA Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[MAX_RSA_KEY_BYTES];
-} TPM2B_PUBLIC_KEY_RSA;
-
-// Table 159 - TPMI_RSA_KEY_BITS Type
-typedef TPM_KEY_BITS TPMI_RSA_KEY_BITS;
-
-// Table 160 - TPM2B_PRIVATE_KEY_RSA Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[MAX_RSA_KEY_BYTES/2];
-} TPM2B_PRIVATE_KEY_RSA;
-
-// Table 161 - TPM2B_ECC_PARAMETER Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[MAX_ECC_KEY_BYTES];
-} TPM2B_ECC_PARAMETER;
-
-// Table 162 - TPMS_ECC_POINT Structure
-typedef struct {
-  TPM2B_ECC_PARAMETER x;
-  TPM2B_ECC_PARAMETER y;
-} TPMS_ECC_POINT;
-
-// Table 163 -- TPM2B_ECC_POINT Structure <I/O>
-typedef struct {
-  UINT16         size;
-  TPMS_ECC_POINT point;
-} TPM2B_ECC_POINT;
-
-// Table 164 - TPMI_ALG_ECC_SCHEME Type
-typedef TPM_ALG_ID TPMI_ALG_ECC_SCHEME;
-
-// Table 165 - TPMI_ECC_CURVE Type
-typedef TPM_ECC_CURVE TPMI_ECC_CURVE;
-
-// Table 166 - TPMT_ECC_SCHEME Structure
-typedef struct {
-  TPMI_ALG_ECC_SCHEME scheme;
-  TPMU_SIG_SCHEME     details;
-} TPMT_ECC_SCHEME;
-
-// Table 167 - TPMS_ALGORITHM_DETAIL_ECC Structure
-typedef struct {
-  TPM_ECC_CURVE       curveID;
-  UINT16              keySize;
-  TPMT_KDF_SCHEME     kdf;
-  TPMT_ECC_SCHEME     sign;
-  TPM2B_ECC_PARAMETER p;
-  TPM2B_ECC_PARAMETER a;
-  TPM2B_ECC_PARAMETER b;
-  TPM2B_ECC_PARAMETER gX;
-  TPM2B_ECC_PARAMETER gY;
-  TPM2B_ECC_PARAMETER n;
-  TPM2B_ECC_PARAMETER h;
-} TPMS_ALGORITHM_DETAIL_ECC;
-
-// Table 168 - TPMS_SIGNATURE_RSASSA Structure
-typedef struct {
-  TPMI_ALG_HASH        hash;
-  TPM2B_PUBLIC_KEY_RSA sig;
-} TPMS_SIGNATURE_RSASSA;
-
-// Table 169 - TPMS_SIGNATURE_RSAPSS Structure
-typedef struct {
-  TPMI_ALG_HASH        hash;
-  TPM2B_PUBLIC_KEY_RSA sig;
-} TPMS_SIGNATURE_RSAPSS;
-
-// Table 170 - TPMS_SIGNATURE_ECDSA Structure
-typedef struct {
-  TPMI_ALG_HASH       hash;
-  TPM2B_ECC_PARAMETER signatureR;
-  TPM2B_ECC_PARAMETER signatureS;
-} TPMS_SIGNATURE_ECDSA;
-
-// Table 171 - TPMU_SIGNATURE Union
-typedef union {
-  TPMS_SIGNATURE_RSASSA rsassa;
-  TPMS_SIGNATURE_RSAPSS rsapss;
-  TPMS_SIGNATURE_ECDSA  ecdsa;
-  TPMS_SIGNATURE_ECDSA  sm2;
-  TPMS_SIGNATURE_ECDSA  ecdaa;
-  TPMS_SIGNATURE_ECDSA  ecschnorr;
-  TPMT_HA               hmac;
-  TPMS_SCHEME_SIGHASH   any;
-} TPMU_SIGNATURE;
-
-// Table 172 - TPMT_SIGNATURE Structure
-typedef struct {
-  TPMI_ALG_SIG_SCHEME sigAlg;
-  TPMU_SIGNATURE      signature;
-} TPMT_SIGNATURE;
-
-// Table 173 - TPMU_ENCRYPTED_SECRET Union
-typedef union {
-  BYTE ecc[sizeof(TPMS_ECC_POINT)];
-  BYTE rsa[MAX_RSA_KEY_BYTES];
-  BYTE symmetric[sizeof(TPM2B_DIGEST)];
-  BYTE keyedHash[sizeof(TPM2B_DIGEST)];
-} TPMU_ENCRYPTED_SECRET;
-
-// Table 174 - TPM2B_ENCRYPTED_SECRET Structure
-typedef struct {
-  UINT16 size;
-  BYTE   secret[sizeof(TPMU_ENCRYPTED_SECRET)];
-} TPM2B_ENCRYPTED_SECRET;
-
-// 12 Key/Object Complex
-
-// Table 175 - TPMI_ALG_PUBLIC Type
-typedef TPM_ALG_ID TPMI_ALG_PUBLIC;
-
-// Table 176 - TPMU_PUBLIC_ID Union
-typedef union {
-  TPM2B_DIGEST         keyedHash;
-  TPM2B_DIGEST         sym;
-  TPM2B_PUBLIC_KEY_RSA rsa;
-  TPMS_ECC_POINT       ecc;
-} TPMU_PUBLIC_ID;
-
-// Table 177 - TPMS_KEYEDHASH_PARMS Structure
-typedef struct {
-  TPMT_KEYEDHASH_SCHEME scheme;
-} TPMS_KEYEDHASH_PARMS;
-
-// Table 178 - TPMS_ASYM_PARMS Structure
-typedef struct {
-  TPMT_SYM_DEF_OBJECT symmetric;
-  TPMT_ASYM_SCHEME    scheme;
-} TPMS_ASYM_PARMS;
-
-// Table 179 - TPMS_RSA_PARMS Structure
-typedef struct {
-  TPMT_SYM_DEF_OBJECT symmetric;
-  TPMT_RSA_SCHEME     scheme;
-  TPMI_RSA_KEY_BITS   keyBits;
-  UINT32              exponent;
-} TPMS_RSA_PARMS;
-
-// Table 180 - TPMS_ECC_PARMS Structure
-typedef struct {
-  TPMT_SYM_DEF_OBJECT symmetric;
-  TPMT_ECC_SCHEME     scheme;
-  TPMI_ECC_CURVE      curveID;
-  TPMT_KDF_SCHEME     kdf;
-} TPMS_ECC_PARMS;
-
-// Table 181 - TPMU_PUBLIC_PARMS Union
-typedef union {
-  TPMS_KEYEDHASH_PARMS keyedHashDetail;
-  TPMT_SYM_DEF_OBJECT  symDetail;
-  TPMS_RSA_PARMS       rsaDetail;
-  TPMS_ECC_PARMS       eccDetail;
-  TPMS_ASYM_PARMS      asymDetail;
-} TPMU_PUBLIC_PARMS;
-
-// Table 182 - TPMT_PUBLIC_PARMS Structure
-typedef struct {
-  TPMI_ALG_PUBLIC   type;
-  TPMU_PUBLIC_PARMS parameters;
-} TPMT_PUBLIC_PARMS;
-
-// Table 183 - TPMT_PUBLIC Structure
-typedef struct {
-  TPMI_ALG_PUBLIC   type;
-  TPMI_ALG_HASH     nameAlg;
-  TPMA_OBJECT       objectAttributes;
-  TPM2B_DIGEST      authPolicy;
-  TPMU_PUBLIC_PARMS parameters;
-  TPMU_PUBLIC_ID    unique;
-} TPMT_PUBLIC;
-
-// Table 184 - TPM2B_PUBLIC Structure
-typedef struct {
-  UINT16      size;
-  TPMT_PUBLIC publicArea;
-} TPM2B_PUBLIC;
-
-// Table 185 - TPM2B_PRIVATE_VENDOR_SPECIFIC Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[PRIVATE_VENDOR_SPECIFIC_BYTES];
-} TPM2B_PRIVATE_VENDOR_SPECIFIC;
-
-// Table 186 - TPMU_SENSITIVE_COMPOSITE Union
-typedef union {
-  TPM2B_PRIVATE_KEY_RSA         rsa;
-  TPM2B_ECC_PARAMETER           ecc;
-  TPM2B_SENSITIVE_DATA          bits;
-  TPM2B_SYM_KEY                 sym;
-  TPM2B_PRIVATE_VENDOR_SPECIFIC any;
-} TPMU_SENSITIVE_COMPOSITE;
-
-// Table 187 - TPMT_SENSITIVE Structure
-typedef struct {
-  TPMI_ALG_PUBLIC          sensitiveType;
-  TPM2B_AUTH               authValue;
-  TPM2B_DIGEST             seedValue;
-  TPMU_SENSITIVE_COMPOSITE sensitive;
-} TPMT_SENSITIVE;
-
-// Table 188 - TPM2B_SENSITIVE Structure
-typedef struct {
-  UINT16         size;
-  TPMT_SENSITIVE sensitiveArea;
-} TPM2B_SENSITIVE;
-
-// Table 189 - _PRIVATE Structure
-typedef struct {
-  TPM2B_DIGEST   integrityOuter;
-  TPM2B_DIGEST   integrityInner;
-  TPMT_SENSITIVE sensitive;
-} _PRIVATE;
-
-// Table 190 - TPM2B_PRIVATE Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[sizeof(_PRIVATE)];
-} TPM2B_PRIVATE;
-
-// Table 191 - _ID_OBJECT Structure
-typedef struct {
-  TPM2B_DIGEST integrityHMAC;
-  TPM2B_DIGEST encIdentity;
-} _ID_OBJECT;
-
-// Table 192 - TPM2B_ID_OBJECT Structure
-typedef struct {
-  UINT16 size;
-  BYTE   credential[sizeof(_ID_OBJECT)];
-} TPM2B_ID_OBJECT;
-
-// 13 NV Storage Structures
-
-// Table 193 - TPM_NV_INDEX Bits
-//
-// NOTE: Comment here to resolve conflict
-//
-//typedef struct {
-//  UINT32 index : 22;
-//  UINT32 space : 2;
-//  UINT32 RH_NV : 8;
-//} TPM_NV_INDEX;
-
-// Table 195 - TPMA_NV Bits
-typedef struct {
-  UINT32 TPMA_NV_PPWRITE        : 1;
-  UINT32 TPMA_NV_OWNERWRITE     : 1;
-  UINT32 TPMA_NV_AUTHWRITE      : 1;
-  UINT32 TPMA_NV_POLICYWRITE    : 1;
-  UINT32 TPMA_NV_COUNTER        : 1;
-  UINT32 TPMA_NV_BITS           : 1;
-  UINT32 TPMA_NV_EXTEND         : 1;
-  UINT32 reserved7_9            : 3;
-  UINT32 TPMA_NV_POLICY_DELETE  : 1;
-  UINT32 TPMA_NV_WRITELOCKED    : 1;
-  UINT32 TPMA_NV_WRITEALL       : 1;
-  UINT32 TPMA_NV_WRITEDEFINE    : 1;
-  UINT32 TPMA_NV_WRITE_STCLEAR  : 1;
-  UINT32 TPMA_NV_GLOBALLOCK     : 1;
-  UINT32 TPMA_NV_PPREAD         : 1;
-  UINT32 TPMA_NV_OWNERREAD      : 1;
-  UINT32 TPMA_NV_AUTHREAD       : 1;
-  UINT32 TPMA_NV_POLICYREAD     : 1;
-  UINT32 reserved20_24          : 5;
-  UINT32 TPMA_NV_NO_DA          : 1;
-  UINT32 TPMA_NV_ORDERLY        : 1;
-  UINT32 TPMA_NV_CLEAR_STCLEAR  : 1;
-  UINT32 TPMA_NV_READLOCKED     : 1;
-  UINT32 TPMA_NV_WRITTEN        : 1;
-  UINT32 TPMA_NV_PLATFORMCREATE : 1;
-  UINT32 TPMA_NV_READ_STCLEAR   : 1;
-} TPMA_NV;
-
-// Table 196 - TPMS_NV_PUBLIC Structure
-typedef struct {
-  TPMI_RH_NV_INDEX nvIndex;
-  TPMI_ALG_HASH    nameAlg;
-  TPMA_NV          attributes;
-  TPM2B_DIGEST     authPolicy;
-  UINT16           dataSize;
-} TPMS_NV_PUBLIC;
-
-// Table 197 - TPM2B_NV_PUBLIC Structure
-typedef struct {
-  UINT16         size;
-  TPMS_NV_PUBLIC nvPublic;
-} TPM2B_NV_PUBLIC;
-
-// 14 Context Data
-
-// Table 198 - TPM2B_CONTEXT_SENSITIVE Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[MAX_CONTEXT_SIZE];
-} TPM2B_CONTEXT_SENSITIVE;
-
-// Table 199 - TPMS_CONTEXT_DATA Structure
-typedef struct {
-  TPM2B_DIGEST            integrity;
-  TPM2B_CONTEXT_SENSITIVE encrypted;
-} TPMS_CONTEXT_DATA;
-
-// Table 200 - TPM2B_CONTEXT_DATA Structure
-typedef struct {
-  UINT16 size;
-  BYTE   buffer[sizeof(TPMS_CONTEXT_DATA)];
-} TPM2B_CONTEXT_DATA;
-
-// Table 201 - TPMS_CONTEXT Structure
-typedef struct {
-  UINT64             sequence;
-  TPMI_DH_CONTEXT    savedHandle;
-  TPMI_RH_HIERARCHY  hierarchy;
-  TPM2B_CONTEXT_DATA contextBlob;
-} TPMS_CONTEXT;
-
-// 15 Creation Data
-
-// Table 203 - TPMS_CREATION_DATA Structure
-typedef struct {
-  TPML_PCR_SELECTION pcrSelect;
-  TPM2B_DIGEST       pcrDigest;
-  TPMA_LOCALITY      locality;
-  TPM_ALG_ID         parentNameAlg;
-  TPM2B_NAME         parentName;
-  TPM2B_NAME         parentQualifiedName;
-  TPM2B_DATA         outsideInfo;
-} TPMS_CREATION_DATA;
-
-// Table 204 - TPM2B_CREATION_DATA Structure
-typedef struct {
-  UINT16             size;
-  TPMS_CREATION_DATA creationData;
-} TPM2B_CREATION_DATA;
-
-
-//
-// Command Header
-//
-typedef struct {
-  TPM_ST tag;
-  UINT32 paramSize;
-  TPM_CC commandCode;
-} TPM2_COMMAND_HEADER;
-
-typedef struct {
-  TPM_ST tag;
-  UINT32 paramSize;
-  TPM_RC responseCode;
-} TPM2_RESPONSE_HEADER;
-
-#pragma pack ()
-
-//
-// TCG Algorithm Registry
-//
-#define HASH_ALG_SHA1    0x00000001
-#define HASH_ALG_SHA256  0x00000002
-#define HASH_ALG_SHA384  0x00000004
-#define HASH_ALG_SHA512  0x00000008
-#define HASH_ALG_SM3_256 0x00000010
-
-#endif
index df65be9..8bb7ea3 100644 (file)
@@ -1,7 +1,7 @@
 /** @file
   TCG EFI Platform Definition in TCG_EFI_Platform_1_20_Final
 
-  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
 FILE_LICENCE ( BSD3 );
 
 #include <ipxe/efi/IndustryStandard/Tpm12.h>
-#include <ipxe/efi/IndustryStandard/Tpm20.h>
 #include <ipxe/efi/Uefi.h>
 
 //
 // Standard event types
 //
 #define EV_POST_CODE                ((TCG_EVENTTYPE) 0x00000001)
-#define EV_NO_ACTION                ((TCG_EVENTTYPE) 0x00000003)
 #define EV_SEPARATOR                ((TCG_EVENTTYPE) 0x00000004)
 #define EV_S_CRTM_CONTENTS          ((TCG_EVENTTYPE) 0x00000007)
 #define EV_S_CRTM_VERSION           ((TCG_EVENTTYPE) 0x00000008)
@@ -45,7 +43,6 @@ FILE_LICENCE ( BSD3 );
 #define EV_EFI_ACTION                       (EV_EFI_EVENT_BASE + 7)
 #define EV_EFI_PLATFORM_FIRMWARE_BLOB       (EV_EFI_EVENT_BASE + 8)
 #define EV_EFI_HANDOFF_TABLES               (EV_EFI_EVENT_BASE + 9)
-#define EV_EFI_VARIABLE_AUTHORITY           (EV_EFI_EVENT_BASE + 0xE0)
 
 #define EFI_CALLING_EFI_APPLICATION         \
   "Calling EFI Application from Boot Option"
@@ -77,9 +74,6 @@ FILE_LICENCE ( BSD3 );
 #define EV_POSTCODE_INFO_OPROM        "Embedded Option ROM"
 #define OPROM_LEN                     (sizeof(EV_POSTCODE_INFO_OPROM) - 1)
 
-#define FIRMWARE_DEBUGGER_EVENT_STRING      "UEFI Debug Mode"
-#define FIRMWARE_DEBUGGER_EVENT_STRING_LEN  (sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1)
-
 //
 // Set structure alignment to 1-byte
 //
@@ -162,17 +156,6 @@ typedef struct tdEFI_VARIABLE_DATA {
   INT8                              VariableData[1];  ///< Driver or platform-specific data
 } EFI_VARIABLE_DATA;
 
-//
-// For TrEE1.0 compatibility
-//
-typedef struct {
-  EFI_GUID                          VariableName;
-  UINT64                            UnicodeNameLength;   // The TCG Definition used UINTN
-  UINT64                            VariableDataLength;  // The TCG Definition used UINTN
-  CHAR16                            UnicodeName[1];
-  INT8                              VariableData[1];
-} EFI_VARIABLE_DATA_TREE;
-
 typedef struct tdEFI_GPT_DATA {
   EFI_PARTITION_TABLE_HEADER  EfiPartitionHeader;
   UINTN                       NumberOfPartitions;
@@ -180,97 +163,6 @@ typedef struct tdEFI_GPT_DATA {
 } EFI_GPT_DATA;
 
 //
-// Crypto Agile Log Entry Format
-//
-typedef struct tdTCG_PCR_EVENT2 {
-  TCG_PCRINDEX        PCRIndex;
-  TCG_EVENTTYPE       EventType;
-  TPML_DIGEST_VALUES  Digest;
-  UINT32              EventSize;
-  UINT8               Event[1];
-} TCG_PCR_EVENT2;
-
-//
-// Log Header Entry Data
-//
-typedef struct {
-  //
-  // TCG defined hashing algorithm ID.
-  //
-  UINT16              algorithmId;
-  //
-  // The size of the digest for the respective hashing algorithm.
-  //
-  UINT16              digestSize;
-} TCG_EfiSpecIdEventAlgorithmSize;
-
-#define TCG_EfiSpecIDEventStruct_SIGNATURE_02 "Spec ID Event02"
-#define TCG_EfiSpecIDEventStruct_SIGNATURE_03 "Spec ID Event03"
-
-#define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM12   1
-#define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM12   2
-#define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM12          2
-
-#define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2   2
-#define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2   0
-#define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2          0
-
-typedef struct {
-  UINT8               signature[16];
-  //
-  // The value for the Platform Class.
-  // The enumeration is defined in the TCG ACPI Specification Client Common Header.
-  //
-  UINT32              platformClass;
-  //
-  // The TCG EFI Platform Specification minor version number this BIOS supports.
-  // Any BIOS supporting version (1.22) MUST set this value to 02h.
-  // Any BIOS supporting version (2.0) SHALL set this value to 0x00.
-  //
-  UINT8               specVersionMinor;
-  //
-  // The TCG EFI Platform Specification major version number this BIOS supports.
-  // Any BIOS supporting version (1.22) MUST set this value to 01h.
-  // Any BIOS supporting version (2.0) SHALL set this value to 0x02.
-  //
-  UINT8               specVersionMajor;
-  //
-  // The TCG EFI Platform Specification errata for this specification this BIOS supports.
-  // Any BIOS supporting version and errata (1.22) MUST set this value to 02h.
-  // Any BIOS supporting version and errata (2.0) SHALL set this value to 0x00.
-  //
-  UINT8               specErrata;
-  //
-  // Specifies the size of the UINTN fields used in various data structures used in this specification.
-  // 0x01 indicates UINT32 and 0x02 indicates UINT64.
-  //
-  UINT8               uintnSize;
-  //
-  // This field is added in "Spec ID Event03".
-  // The number of hashing algorithms used in this event log (except the first event).
-  // All events in this event log use all hashing algorithms defined here.
-  //
-//UINT32              numberOfAlgorithms;
-  //
-  // This field is added in "Spec ID Event03".
-  // An array of size numberOfAlgorithms of value pairs.
-  //
-//TCG_EfiSpecIdEventAlgorithmSize digestSize[numberOfAlgorithms];
-  //
-  // Size in bytes of the VendorInfo field.
-  // Maximum value SHALL be FFh bytes.
-  //
-//UINT8               vendorInfoSize;
-  //
-  // Provided for use by the BIOS implementer.
-  // The value might be used, for example, to provide more detailed information about the specific BIOS such as BIOS revision numbers, etc.
-  // The values within this field are not standardized and are implementer-specific.
-  // Platform-specific or -unique information SHALL NOT be provided in this field.
-  //
-//UINT8               vendorInfo[vendorInfoSize];
-} TCG_EfiSpecIDEventStruct;
-
-//
 // Restore original structure alignment
 //
 #pragma pack ()
diff --git a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Usb.h b/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Usb.h
deleted file mode 100644 (file)
index 7eb1a8d..0000000
+++ /dev/null
@@ -1,388 +0,0 @@
-/** @file
-  Support for USB 2.0 standard.
-
-  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef __USB_H__
-#define __USB_H__
-
-FILE_LICENCE ( BSD3 );
-
-//
-// Subset of Class and Subclass definitions from USB Specs
-//
-
-//
-// Usb mass storage class code
-//
-#define USB_MASS_STORE_CLASS    0x08
-
-//
-// Usb mass storage subclass code, specify the command set used.
-//
-#define USB_MASS_STORE_RBC      0x01 ///< Reduced Block Commands
-#define USB_MASS_STORE_8020I    0x02 ///< SFF-8020i, typically a CD/DVD device
-#define USB_MASS_STORE_QIC      0x03 ///< Typically a tape device
-#define USB_MASS_STORE_UFI      0x04 ///< Typically a floppy disk driver device
-#define USB_MASS_STORE_8070I    0x05 ///< SFF-8070i, typically a floppy disk driver device.
-#define USB_MASS_STORE_SCSI     0x06 ///< SCSI transparent command set
-
-//
-// Usb mass storage protocol code, specify the transport protocol
-//
-#define USB_MASS_STORE_CBI0     0x00 ///< CBI protocol with command completion interrupt
-#define USB_MASS_STORE_CBI1     0x01 ///< CBI protocol without command completion interrupt
-#define USB_MASS_STORE_BOT      0x50 ///< Bulk-Only Transport
-
-//
-// Standard device request and request type
-// USB 2.0 spec, Section 9.4
-//
-#define USB_DEV_GET_STATUS                  0x00
-#define USB_DEV_GET_STATUS_REQ_TYPE_D       0x80 // Receiver : Device
-#define USB_DEV_GET_STATUS_REQ_TYPE_I       0x81 // Receiver : Interface
-#define USB_DEV_GET_STATUS_REQ_TYPE_E       0x82 // Receiver : Endpoint
-
-#define USB_DEV_CLEAR_FEATURE               0x01
-#define USB_DEV_CLEAR_FEATURE_REQ_TYPE_D    0x00 // Receiver : Device
-#define USB_DEV_CLEAR_FEATURE_REQ_TYPE_I    0x01 // Receiver : Interface
-#define USB_DEV_CLEAR_FEATURE_REQ_TYPE_E    0x02 // Receiver : Endpoint
-
-#define USB_DEV_SET_FEATURE                 0x03
-#define USB_DEV_SET_FEATURE_REQ_TYPE_D      0x00 // Receiver : Device
-#define USB_DEV_SET_FEATURE_REQ_TYPE_I      0x01 // Receiver : Interface
-#define USB_DEV_SET_FEATURE_REQ_TYPE_E      0x02 // Receiver : Endpoint
-
-#define USB_DEV_SET_ADDRESS                 0x05
-#define USB_DEV_SET_ADDRESS_REQ_TYPE        0x00
-
-#define USB_DEV_GET_DESCRIPTOR              0x06
-#define USB_DEV_GET_DESCRIPTOR_REQ_TYPE     0x80
-
-#define USB_DEV_SET_DESCRIPTOR              0x07
-#define USB_DEV_SET_DESCRIPTOR_REQ_TYPE     0x00
-
-#define USB_DEV_GET_CONFIGURATION           0x08
-#define USB_DEV_GET_CONFIGURATION_REQ_TYPE  0x80
-
-#define USB_DEV_SET_CONFIGURATION           0x09
-#define USB_DEV_SET_CONFIGURATION_REQ_TYPE  0x00
-
-#define USB_DEV_GET_INTERFACE               0x0A
-#define USB_DEV_GET_INTERFACE_REQ_TYPE      0x81
-
-#define USB_DEV_SET_INTERFACE               0x0B
-#define USB_DEV_SET_INTERFACE_REQ_TYPE      0x01
-
-#define USB_DEV_SYNCH_FRAME                 0x0C
-#define USB_DEV_SYNCH_FRAME_REQ_TYPE        0x82
-
-
-//
-// USB standard descriptors and reqeust
-//
-#pragma pack(1)
-
-///
-/// Format of Setup Data for USB Device Requests
-/// USB 2.0 spec, Section 9.3
-///
-typedef struct {
-  UINT8           RequestType;
-  UINT8           Request;
-  UINT16          Value;
-  UINT16          Index;
-  UINT16          Length;
-} USB_DEVICE_REQUEST;
-
-///
-/// Standard Device Descriptor
-/// USB 2.0 spec, Section 9.6.1
-///
-typedef struct {
-  UINT8           Length;
-  UINT8           DescriptorType;
-  UINT16          BcdUSB;
-  UINT8           DeviceClass;
-  UINT8           DeviceSubClass;
-  UINT8           DeviceProtocol;
-  UINT8           MaxPacketSize0;
-  UINT16          IdVendor;
-  UINT16          IdProduct;
-  UINT16          BcdDevice;
-  UINT8           StrManufacturer;
-  UINT8           StrProduct;
-  UINT8           StrSerialNumber;
-  UINT8           NumConfigurations;
-} USB_DEVICE_DESCRIPTOR;
-
-///
-/// Standard Configuration Descriptor
-/// USB 2.0 spec, Section 9.6.3
-///
-typedef struct {
-  UINT8           Length;
-  UINT8           DescriptorType;
-  UINT16          TotalLength;
-  UINT8           NumInterfaces;
-  UINT8           ConfigurationValue;
-  UINT8           Configuration;
-  UINT8           Attributes;
-  UINT8           MaxPower;
-} USB_CONFIG_DESCRIPTOR;
-
-///
-/// Standard Interface Descriptor
-/// USB 2.0 spec, Section 9.6.5
-///
-typedef struct {
-  UINT8           Length;
-  UINT8           DescriptorType;
-  UINT8           InterfaceNumber;
-  UINT8           AlternateSetting;
-  UINT8           NumEndpoints;
-  UINT8           InterfaceClass;
-  UINT8           InterfaceSubClass;
-  UINT8           InterfaceProtocol;
-  UINT8           Interface;
-} USB_INTERFACE_DESCRIPTOR;
-
-///
-/// Standard Endpoint Descriptor
-/// USB 2.0 spec, Section 9.6.6
-///
-typedef struct {
-  UINT8           Length;
-  UINT8           DescriptorType;
-  UINT8           EndpointAddress;
-  UINT8           Attributes;
-  UINT16          MaxPacketSize;
-  UINT8           Interval;
-} USB_ENDPOINT_DESCRIPTOR;
-
-///
-/// UNICODE String Descriptor
-/// USB 2.0 spec, Section 9.6.7
-///
-typedef struct {
-  UINT8           Length;
-  UINT8           DescriptorType;
-  CHAR16          String[1];
-} EFI_USB_STRING_DESCRIPTOR;
-
-#pragma pack()
-
-
-typedef enum {
-  //
-  // USB request type
-  //
-  USB_REQ_TYPE_STANDARD   = (0x00 << 5),
-  USB_REQ_TYPE_CLASS      = (0x01 << 5),
-  USB_REQ_TYPE_VENDOR     = (0x02 << 5),
-
-  //
-  // Standard control transfer request type, or the value
-  // to fill in EFI_USB_DEVICE_REQUEST.Request
-  //
-  USB_REQ_GET_STATUS      = 0x00,
-  USB_REQ_CLEAR_FEATURE   = 0x01,
-  USB_REQ_SET_FEATURE     = 0x03,
-  USB_REQ_SET_ADDRESS     = 0x05,
-  USB_REQ_GET_DESCRIPTOR  = 0x06,
-  USB_REQ_SET_DESCRIPTOR  = 0x07,
-  USB_REQ_GET_CONFIG      = 0x08,
-  USB_REQ_SET_CONFIG      = 0x09,
-  USB_REQ_GET_INTERFACE   = 0x0A,
-  USB_REQ_SET_INTERFACE   = 0x0B,
-  USB_REQ_SYNCH_FRAME     = 0x0C,
-
-  //
-  // Usb control transfer target
-  //
-  USB_TARGET_DEVICE       = 0,
-  USB_TARGET_INTERFACE    = 0x01,
-  USB_TARGET_ENDPOINT     = 0x02,
-  USB_TARGET_OTHER        = 0x03,
-
-  //
-  // USB Descriptor types
-  //
-  USB_DESC_TYPE_DEVICE    = 0x01,
-  USB_DESC_TYPE_CONFIG    = 0x02,
-  USB_DESC_TYPE_STRING    = 0x03,
-  USB_DESC_TYPE_INTERFACE = 0x04,
-  USB_DESC_TYPE_ENDPOINT  = 0x05,
-  USB_DESC_TYPE_HID       = 0x21,
-  USB_DESC_TYPE_REPORT    = 0x22,
-
-  //
-  // Features to be cleared by CLEAR_FEATURE requests
-  //
-  USB_FEATURE_ENDPOINT_HALT = 0,
-
-  //
-  // USB endpoint types: 00: control, 01: isochronous, 10: bulk, 11: interrupt
-  //
-  USB_ENDPOINT_CONTROL    = 0x00,
-  USB_ENDPOINT_ISO        = 0x01,
-  USB_ENDPOINT_BULK       = 0x02,
-  USB_ENDPOINT_INTERRUPT  = 0x03,
-
-  USB_ENDPOINT_TYPE_MASK  = 0x03,
-  USB_ENDPOINT_DIR_IN     = 0x80,
-
-  //
-  //Use 200 ms to increase the error handling response time
-  //
-  EFI_USB_INTERRUPT_DELAY = 2000000
-} USB_TYPES_DEFINITION;
-
-
-//
-// HID constants definition, see Device Class Definition
-// for Human Interface Devices (HID) rev1.11
-//
-
-//
-// HID standard GET_DESCRIPTOR request.
-//
-#define USB_HID_GET_DESCRIPTOR_REQ_TYPE  0x81
-
-//
-// HID specific requests.
-//
-#define USB_HID_CLASS_GET_REQ_TYPE       0xa1
-#define USB_HID_CLASS_SET_REQ_TYPE       0x21
-
-//
-// HID report item format
-//
-#define HID_ITEM_FORMAT_SHORT 0
-#define HID_ITEM_FORMAT_LONG  1
-
-//
-// Special tag indicating long items
-//
-#define HID_ITEM_TAG_LONG 15
-
-//
-// HID report descriptor item type (prefix bit 2,3)
-//
-#define HID_ITEM_TYPE_MAIN      0
-#define HID_ITEM_TYPE_GLOBAL    1
-#define HID_ITEM_TYPE_LOCAL     2
-#define HID_ITEM_TYPE_RESERVED  3
-
-//
-// HID report descriptor main item tags
-//
-#define HID_MAIN_ITEM_TAG_INPUT             8
-#define HID_MAIN_ITEM_TAG_OUTPUT            9
-#define HID_MAIN_ITEM_TAG_FEATURE           11
-#define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION  10
-#define HID_MAIN_ITEM_TAG_END_COLLECTION    12
-
-//
-// HID report descriptor main item contents
-//
-#define HID_MAIN_ITEM_CONSTANT      0x001
-#define HID_MAIN_ITEM_VARIABLE      0x002
-#define HID_MAIN_ITEM_RELATIVE      0x004
-#define HID_MAIN_ITEM_WRAP          0x008
-#define HID_MAIN_ITEM_NONLINEAR     0x010
-#define HID_MAIN_ITEM_NO_PREFERRED  0x020
-#define HID_MAIN_ITEM_NULL_STATE    0x040
-#define HID_MAIN_ITEM_VOLATILE      0x080
-#define HID_MAIN_ITEM_BUFFERED_BYTE 0x100
-
-//
-// HID report descriptor collection item types
-//
-#define HID_COLLECTION_PHYSICAL     0
-#define HID_COLLECTION_APPLICATION  1
-#define HID_COLLECTION_LOGICAL      2
-
-//
-// HID report descriptor global item tags
-//
-#define HID_GLOBAL_ITEM_TAG_USAGE_PAGE        0
-#define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM   1
-#define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM   2
-#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM  3
-#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM  4
-#define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT     5
-#define HID_GLOBAL_ITEM_TAG_UNIT              6
-#define HID_GLOBAL_ITEM_TAG_REPORT_SIZE       7
-#define HID_GLOBAL_ITEM_TAG_REPORT_ID         8
-#define HID_GLOBAL_ITEM_TAG_REPORT_COUNT      9
-#define HID_GLOBAL_ITEM_TAG_PUSH              10
-#define HID_GLOBAL_ITEM_TAG_POP               11
-
-//
-// HID report descriptor local item tags
-//
-#define HID_LOCAL_ITEM_TAG_USAGE              0
-#define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM      1
-#define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM      2
-#define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX   3
-#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4
-#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5
-#define HID_LOCAL_ITEM_TAG_STRING_INDEX       7
-#define HID_LOCAL_ITEM_TAG_STRING_MINIMUM     8
-#define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM     9
-#define HID_LOCAL_ITEM_TAG_DELIMITER          10
-
-//
-// HID report types
-//
-#define HID_INPUT_REPORT    1
-#define HID_OUTPUT_REPORT   2
-#define HID_FEATURE_REPORT  3
-
-//
-// HID class protocol request
-//
-#define EFI_USB_GET_REPORT_REQUEST    0x01
-#define EFI_USB_GET_IDLE_REQUEST      0x02
-#define EFI_USB_GET_PROTOCOL_REQUEST  0x03
-#define EFI_USB_SET_REPORT_REQUEST    0x09
-#define EFI_USB_SET_IDLE_REQUEST      0x0a
-#define EFI_USB_SET_PROTOCOL_REQUEST  0x0b
-
-#pragma pack(1)
-///
-/// Descriptor header for Report/Physical Descriptors
-/// HID 1.1, section 6.2.1
-///
-typedef struct hid_class_descriptor {
-  UINT8   DescriptorType;
-  UINT16  DescriptorLength;
-} EFI_USB_HID_CLASS_DESCRIPTOR;
-
-///
-/// The HID descriptor identifies the length and type
-/// of subordinate descriptors for a device.
-/// HID 1.1, section 6.2.1
-///
-typedef struct hid_descriptor {
-  UINT8                         Length;
-  UINT8                         DescriptorType;
-  UINT16                        BcdHID;
-  UINT8                         CountryCode;
-  UINT8                         NumDescriptors;
-  EFI_USB_HID_CLASS_DESCRIPTOR  HidClassDesc[1];
-} EFI_USB_HID_DESCRIPTOR;
-
-#pragma pack()
-
-#endif
index a45a20d..e9c31d1 100644 (file)
@@ -1,8 +1,8 @@
 /** @file
   Provides string functions, linked list functions, math functions, synchronization
-  functions, file path functions, and CPU architecture-specific functions.
+  functions, and CPU architecture-specific functions.
 
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
@@ -185,321 +185,7 @@ typedef struct {
 // String Services
 //
 
-
 /**
-  Returns the length of a Null-terminated Unicode string.
-
-  If String is not aligned on a 16-bit boundary, then ASSERT().
-
-  @param  String   A pointer to a Null-terminated Unicode string.
-  @param  MaxSize  The maximum number of Destination Unicode
-                   char, including terminating null char.
-
-  @retval 0        If String is NULL.
-  @retval MaxSize  If there is no null character in the first MaxSize characters of String.
-  @return The number of characters that percede the terminating null character.
-
-**/
-UINTN
-EFIAPI
-StrnLenS (
-  IN CONST CHAR16              *String,
-  IN UINTN                     MaxSize
-  );
-
-/**
-  Copies the string pointed to by Source (including the terminating null char)
-  to the array pointed to by Destination.
-
-  If Destination is not aligned on a 16-bit boundary, then ASSERT().
-  If Source is not aligned on a 16-bit boundary, then ASSERT().
-  If an error would be returned, then the function will also ASSERT().
-
-  @param  Destination              A pointer to a Null-terminated Unicode string.
-  @param  DestMax                  The maximum number of Destination Unicode
-                                   char, including terminating null char.
-  @param  Source                   A pointer to a Null-terminated Unicode string.
-
-  @retval RETURN_SUCCESS           String is copied.
-  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).
-  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
-                                   If Source is NULL.
-                                   If PcdMaximumUnicodeStringLength is not zero,
-                                    and DestMax is greater than
-                                    PcdMaximumUnicodeStringLength.
-                                   If DestMax is 0.
-  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
-**/
-RETURN_STATUS
-EFIAPI
-StrCpyS (
-  OUT CHAR16       *Destination,
-  IN  UINTN        DestMax,
-  IN  CONST CHAR16 *Source
-  );
-
-/**
-  Copies not more than Length successive char from the string pointed to by
-  Source to the array pointed to by Destination. If no null char is copied from
-  Source, then Destination[Length] is always set to null.
-
-  If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
-  If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
-  If an error would be returned, then the function will also ASSERT().
-
-  @param  Destination              A pointer to a Null-terminated Unicode string.
-  @param  DestMax                  The maximum number of Destination Unicode
-                                   char, including terminating null char.
-  @param  Source                   A pointer to a Null-terminated Unicode string.
-  @param  Length                   The maximum number of Unicode characters to copy.
-
-  @retval RETURN_SUCCESS           String is copied.
-  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than
-                                   MIN(StrLen(Source), Length).
-  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
-                                   If Source is NULL.
-                                   If PcdMaximumUnicodeStringLength is not zero,
-                                    and DestMax is greater than
-                                    PcdMaximumUnicodeStringLength.
-                                   If DestMax is 0.
-  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
-**/
-RETURN_STATUS
-EFIAPI
-StrnCpyS (
-  OUT CHAR16       *Destination,
-  IN  UINTN        DestMax,
-  IN  CONST CHAR16 *Source,
-  IN  UINTN        Length
-  );
-
-/**
-  Appends a copy of the string pointed to by Source (including the terminating
-  null char) to the end of the string pointed to by Destination.
-
-  If Destination is not aligned on a 16-bit boundary, then ASSERT().
-  If Source is not aligned on a 16-bit boundary, then ASSERT().
-  If an error would be returned, then the function will also ASSERT().
-
-  @param  Destination              A pointer to a Null-terminated Unicode string.
-  @param  DestMax                  The maximum number of Destination Unicode
-                                   char, including terminating null char.
-  @param  Source                   A pointer to a Null-terminated Unicode string.
-
-  @retval RETURN_SUCCESS           String is appended.
-  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
-                                   StrLen(Destination).
-  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
-                                   greater than StrLen(Source).
-  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
-                                   If Source is NULL.
-                                   If PcdMaximumUnicodeStringLength is not zero,
-                                    and DestMax is greater than
-                                    PcdMaximumUnicodeStringLength.
-                                   If DestMax is 0.
-  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
-**/
-RETURN_STATUS
-EFIAPI
-StrCatS (
-  IN OUT CHAR16       *Destination,
-  IN     UINTN        DestMax,
-  IN     CONST CHAR16 *Source
-  );
-
-/**
-  Appends not more than Length successive char from the string pointed to by
-  Source to the end of the string pointed to by Destination. If no null char is
-  copied from Source, then Destination[StrLen(Destination) + Length] is always
-  set to null.
-
-  If Destination is not aligned on a 16-bit boundary, then ASSERT().
-  If Source is not aligned on a 16-bit boundary, then ASSERT().
-  If an error would be returned, then the function will also ASSERT().
-
-  @param  Destination              A pointer to a Null-terminated Unicode string.
-  @param  DestMax                  The maximum number of Destination Unicode
-                                   char, including terminating null char.
-  @param  Source                   A pointer to a Null-terminated Unicode string.
-  @param  Length                   The maximum number of Unicode characters to copy.
-
-  @retval RETURN_SUCCESS           String is appended.
-  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
-                                   StrLen(Destination).
-  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
-                                   greater than MIN(StrLen(Source), Length).
-  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
-                                   If Source is NULL.
-                                   If PcdMaximumUnicodeStringLength is not zero,
-                                    and DestMax is greater than
-                                    PcdMaximumUnicodeStringLength.
-                                   If DestMax is 0.
-  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
-**/
-RETURN_STATUS
-EFIAPI
-StrnCatS (
-  IN OUT CHAR16       *Destination,
-  IN     UINTN        DestMax,
-  IN     CONST CHAR16 *Source,
-  IN     UINTN        Length
-  );
-
-/**
-  Returns the length of a Null-terminated Ascii string.
-
-  @param  String   A pointer to a Null-terminated Ascii string.
-  @param  MaxSize  The maximum number of Destination Ascii
-                   char, including terminating null char.
-
-  @retval 0        If String is NULL.
-  @retval MaxSize  If there is no null character in the first MaxSize characters of String.
-  @return The number of characters that percede the terminating null character.
-
-**/
-UINTN
-EFIAPI
-AsciiStrnLenS (
-  IN CONST CHAR8               *String,
-  IN UINTN                     MaxSize
-  );
-
-/**
-  Copies the string pointed to by Source (including the terminating null char)
-  to the array pointed to by Destination.
-
-  If an error would be returned, then the function will also ASSERT().
-
-  @param  Destination              A pointer to a Null-terminated Ascii string.
-  @param  DestMax                  The maximum number of Destination Ascii
-                                   char, including terminating null char.
-  @param  Source                   A pointer to a Null-terminated Ascii string.
-
-  @retval RETURN_SUCCESS           String is copied.
-  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).
-  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
-                                   If Source is NULL.
-                                   If PcdMaximumAsciiStringLength is not zero,
-                                    and DestMax is greater than
-                                    PcdMaximumAsciiStringLength.
-                                   If DestMax is 0.
-  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
-**/
-RETURN_STATUS
-EFIAPI
-AsciiStrCpyS (
-  OUT CHAR8        *Destination,
-  IN  UINTN        DestMax,
-  IN  CONST CHAR8  *Source
-  );
-
-/**
-  Copies not more than Length successive char from the string pointed to by
-  Source to the array pointed to by Destination. If no null char is copied from
-  Source, then Destination[Length] is always set to null.
-
-  If an error would be returned, then the function will also ASSERT().
-
-  @param  Destination              A pointer to a Null-terminated Ascii string.
-  @param  DestMax                  The maximum number of Destination Ascii
-                                   char, including terminating null char.
-  @param  Source                   A pointer to a Null-terminated Ascii string.
-  @param  Length                   The maximum number of Ascii characters to copy.
-
-  @retval RETURN_SUCCESS           String is copied.
-  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than
-                                   MIN(StrLen(Source), Length).
-  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
-                                   If Source is NULL.
-                                   If PcdMaximumAsciiStringLength is not zero,
-                                    and DestMax is greater than
-                                    PcdMaximumAsciiStringLength.
-                                   If DestMax is 0.
-  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
-**/
-RETURN_STATUS
-EFIAPI
-AsciiStrnCpyS (
-  OUT CHAR8        *Destination,
-  IN  UINTN        DestMax,
-  IN  CONST CHAR8  *Source,
-  IN  UINTN        Length
-  );
-
-/**
-  Appends a copy of the string pointed to by Source (including the terminating
-  null char) to the end of the string pointed to by Destination.
-
-  If an error would be returned, then the function will also ASSERT().
-
-  @param  Destination              A pointer to a Null-terminated Ascii string.
-  @param  DestMax                  The maximum number of Destination Ascii
-                                   char, including terminating null char.
-  @param  Source                   A pointer to a Null-terminated Ascii string.
-
-  @retval RETURN_SUCCESS           String is appended.
-  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
-                                   StrLen(Destination).
-  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
-                                   greater than StrLen(Source).
-  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
-                                   If Source is NULL.
-                                   If PcdMaximumAsciiStringLength is not zero,
-                                    and DestMax is greater than
-                                    PcdMaximumAsciiStringLength.
-                                   If DestMax is 0.
-  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
-**/
-RETURN_STATUS
-EFIAPI
-AsciiStrCatS (
-  IN OUT CHAR8        *Destination,
-  IN     UINTN        DestMax,
-  IN     CONST CHAR8  *Source
-  );
-
-/**
-  Appends not more than Length successive char from the string pointed to by
-  Source to the end of the string pointed to by Destination. If no null char is
-  copied from Source, then Destination[StrLen(Destination) + Length] is always
-  set to null.
-
-  If an error would be returned, then the function will also ASSERT().
-
-  @param  Destination              A pointer to a Null-terminated Ascii string.
-  @param  DestMax                  The maximum number of Destination Ascii
-                                   char, including terminating null char.
-  @param  Source                   A pointer to a Null-terminated Ascii string.
-  @param  Length                   The maximum number of Ascii characters to copy.
-
-  @retval RETURN_SUCCESS           String is appended.
-  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
-                                   StrLen(Destination).
-  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
-                                   greater than MIN(StrLen(Source), Length).
-  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
-                                   If Source is NULL.
-                                   If PcdMaximumAsciiStringLength is not zero,
-                                    and DestMax is greater than
-                                    PcdMaximumAsciiStringLength.
-                                   If DestMax is 0.
-  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
-**/
-RETURN_STATUS
-EFIAPI
-AsciiStrnCatS (
-  IN OUT CHAR8        *Destination,
-  IN     UINTN        DestMax,
-  IN     CONST CHAR8  *Source,
-  IN     UINTN        Length
-  );
-
-
-#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
-
-/**
-  [ATTENTION] This function is deprecated for security reason.
-
   Copies one Null-terminated Unicode string to another Null-terminated Unicode
   string and returns the new Unicode string.
 
@@ -531,8 +217,6 @@ StrCpy (
 
 
 /**
-  [ATTENTION] This function is deprecated for security reason.
-
   Copies up to a specified length from one Null-terminated Unicode string to
   another Null-terminated Unicode string and returns the new Unicode string.
 
@@ -569,7 +253,7 @@ StrnCpy (
   IN      CONST CHAR16              *Source,
   IN      UINTN                     Length
   );
-#endif
+
 
 /**
   Returns the length of a Null-terminated Unicode string.
@@ -697,11 +381,7 @@ StrnCmp (
   );
 
 
-#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
-
 /**
-  [ATTENTION] This function is deprecated for security reason.
-
   Concatenates one Null-terminated Unicode string to another Null-terminated
   Unicode string, and returns the concatenated Unicode string.
 
@@ -742,8 +422,6 @@ StrCat (
 
 
 /**
-  [ATTENTION] This function is deprecated for security reason.
-
   Concatenates up to a specified length one Null-terminated Unicode to the end
   of another Null-terminated Unicode string, and returns the concatenated
   Unicode string.
@@ -788,7 +466,6 @@ StrnCat (
   IN      CONST CHAR16              *Source,
   IN      UINTN                     Length
   );
-#endif
 
 /**
   Returns the first occurrence of a Null-terminated Unicode sub-string
@@ -1027,11 +704,7 @@ UnicodeStrToAsciiStr (
   );
 
 
-#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
-
 /**
-  [ATTENTION] This function is deprecated for security reason.
-
   Copies one Null-terminated ASCII string to another Null-terminated ASCII
   string and returns the new ASCII string.
 
@@ -1061,8 +734,6 @@ AsciiStrCpy (
 
 
 /**
-  [ATTENTION] This function is deprecated for security reason.
-
   Copies up to a specified length one Null-terminated ASCII string to another
   Null-terminated ASCII string and returns the new ASCII string.
 
@@ -1096,7 +767,7 @@ AsciiStrnCpy (
   IN      CONST CHAR8               *Source,
   IN      UINTN                     Length
   );
-#endif
+
 
 /**
   Returns the length of a Null-terminated ASCII string.
@@ -1256,11 +927,7 @@ AsciiStrnCmp (
   );
 
 
-#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
-
 /**
-  [ATTENTION] This function is deprecated for security reason.
-
   Concatenates one Null-terminated ASCII string to another Null-terminated
   ASCII string, and returns the concatenated ASCII string.
 
@@ -1296,8 +963,6 @@ AsciiStrCat (
 
 
 /**
-  [ATTENTION] This function is deprecated for security reason.
-
   Concatenates up to a specified length one Null-terminated ASCII string to
   the end of another Null-terminated ASCII string, and returns the
   concatenated ASCII string.
@@ -1340,7 +1005,7 @@ AsciiStrnCat (
   IN      CONST CHAR8               *Source,
   IN      UINTN                     Length
   );
-#endif
+
 
 /**
   Returns the first occurrence of a Null-terminated ASCII sub-string
@@ -1605,43 +1270,6 @@ BcdToDecimal8 (
   IN      UINT8                     Value
   );
 
-//
-//  File Path Manipulation Functions
-//
-
-/**
-  Removes the last directory or file entry in a path by changing the last
-  L'\' to a CHAR_NULL.
-
-  @param[in, out] Path    The pointer to the path to modify.
-
-  @retval FALSE     Nothing was found to remove.
-  @retval TRUE      A directory or file was removed.
-**/
-BOOLEAN
-EFIAPI
-PathRemoveLastItem(
-  IN OUT CHAR16 *Path
-  );
-
-/**
-  Function to clean up paths.
-    - Single periods in the path are removed.
-    - Double periods in the path are removed along with a single parent directory.
-    - Forward slashes L'/' are converted to backward slashes L'\'.
-
-  This will be done inline and the existing buffer may be larger than required
-  upon completion.
-
-  @param[in] Path       The pointer to the string containing the path.
-
-  @return       Returns Path, otherwise returns NULL to indicate that an error has occured.
-**/
-CHAR16*
-EFIAPI
-PathCleanUpDirectories(
-  IN CHAR16 *Path
-  );
 
 //
 // Linked List Functions and Macros
@@ -7649,57 +7277,6 @@ AsmPrepareAndThunk16 (
   IN OUT  THUNK_CONTEXT             *ThunkContext
   );
 
-/**
-  Generates a 16-bit random number through RDRAND instruction.
-
-  if Rand is NULL, then ASSERT().
-
-  @param[out]  Rand     Buffer pointer to store the random result.
-
-  @retval TRUE          RDRAND call was successful.
-  @retval FALSE         Failed attempts to call RDRAND.
-
- **/
-BOOLEAN
-EFIAPI
-AsmRdRand16 (
-  OUT     UINT16                    *Rand
-  );
-
-/**
-  Generates a 32-bit random number through RDRAND instruction.
-
-  if Rand is NULL, then ASSERT().
-
-  @param[out]  Rand     Buffer pointer to store the random result.
-
-  @retval TRUE          RDRAND call was successful.
-  @retval FALSE         Failed attempts to call RDRAND.
-
-**/
-BOOLEAN
-EFIAPI
-AsmRdRand32 (
-  OUT     UINT32                    *Rand
-  );
-
-/**
-  Generates a 64-bit random number through RDRAND instruction.
-
-  if Rand is NULL, then ASSERT().
-
-  @param[out]  Rand     Buffer pointer to store the random result.
-
-  @retval TRUE          RDRAND call was successful.
-  @retval FALSE         Failed attempts to call RDRAND.
-
-**/
-BOOLEAN
-EFIAPI
-AsmRdRand64  (
-  OUT     UINT64                    *Rand
-  );
-
 #endif
 #endif
 
index 047c077..50d25f2 100644 (file)
@@ -1,7 +1,7 @@
 /** @file
   Include file matches things in PI.
 
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -11,7 +11,7 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
   @par Revision Reference:
-  PI Version 1.4
+  PI Version 1.2
 
 **/
 
@@ -50,16 +50,6 @@ typedef enum {
   /// access I/O devices in the platform.
   ///
   EfiGcdMemoryTypeMemoryMappedIo,
-  ///
-  /// A memory region that is visible to the boot processor.
-  /// This memory supports byte-addressable non-volatility.
-  ///
-  EfiGcdMemoryTypePersistentMemory,
-  ///
-  /// A memory region that provides higher reliability relative to other memory in the
-  /// system. If all memory has the same reliability, then this bit is not used.
-  ///
-  EfiGcdMemoryTypeMoreReliable,
   EfiGcdMemoryTypeMaximum
 } EFI_GCD_MEMORY_TYPE;
 
@@ -377,7 +367,7 @@ EFI_STATUS
                                 resource range specified by BaseAddress and Length.
   @retval EFI_UNSUPPORTED       The bit mask of attributes is not support for the memory resource
                                 range specified by BaseAddress and Length.
-  @retval EFI_ACCESS_DENIED     The attributes for the memory resource range specified by
+  @retval EFI_ACCESS_DEFINED    The attributes for the memory resource range specified by
                                 BaseAddress and Length cannot be modified.
   @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the attributes of
                                 the memory resource range.
@@ -393,31 +383,6 @@ EFI_STATUS
   );
 
 /**
-  Modifies the capabilities for a memory region in the global coherency domain of the
-  processor.
-
-  @param  BaseAddress      The physical address that is the start address of a memory region.
-  @param  Length           The size in bytes of the memory region.
-  @param  Capabilities     The bit mask of capabilities that the memory region supports.
-
-  @retval EFI_SUCCESS           The capabilities were set for the memory region.
-  @retval EFI_INVALID_PARAMETER Length is zero.
-  @retval EFI_UNSUPPORTED       The capabilities specified by Capabilities do not include the
-                                memory region attributes currently in use.
-  @retval EFI_ACCESS_DENIED     The capabilities for the memory resource range specified by
-                                BaseAddress and Length cannot be modified.
-  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the capabilities
-                                of the memory resource range.
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_SET_MEMORY_SPACE_CAPABILITIES) (
-  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
-  IN UINT64                Length,
-  IN UINT64                Capabilities
-  );
-
-/**
   Returns a map of the memory resources in the global coherency domain of the
   processor.
 
@@ -694,7 +659,7 @@ EFI_STATUS
 //
 #define DXE_SERVICES_SIGNATURE            0x565245535f455844ULL
 #define DXE_SPECIFICATION_MAJOR_REVISION  1
-#define DXE_SPECIFICATION_MINOR_REVISION  40
+#define DXE_SPECIFICATION_MINOR_REVISION  30
 #define DXE_SERVICES_REVISION             ((DXE_SPECIFICATION_MAJOR_REVISION<<16) | (DXE_SPECIFICATION_MINOR_REVISION))
 
 typedef struct {
@@ -731,12 +696,23 @@ typedef struct {
   // Service to process a single firmware volume found in a capsule
   //
   EFI_PROCESS_FIRMWARE_VOLUME     ProcessFirmwareVolume;
-  //
-  // Extensions to Global Coherency Domain Services
-  //
-  EFI_SET_MEMORY_SPACE_CAPABILITIES SetMemorySpaceCapabilities;
 } DXE_SERVICES;
 
 typedef DXE_SERVICES EFI_DXE_SERVICES;
 
+
+/**
+  The function prototype for invoking a function on an Application Processor.
+
+  This definition is used by the UEFI MP Serices Protocol, and the
+  PI SMM System Table.
+
+  @param[in,out] Buffer  The pointer to private data buffer.
+**/
+typedef
+VOID
+(EFIAPI *EFI_AP_PROCEDURE)(
+  IN OUT VOID  *Buffer
+  );
+
 #endif
index 9bd22a5..f6cf957 100644 (file)
@@ -1,7 +1,7 @@
 /** @file
   The firmware file related definitions in PI.
 
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -11,7 +11,7 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
   @par Revision Reference:
-  PI Version 1.4.
+  PI Version 1.2.
 
 **/
 
@@ -175,7 +175,7 @@ typedef struct {
   /// If FFS_ATTRIB_LARGE_FILE is set in Attributes, then ExtendedSize exists and Size must be set to zero.
   /// If FFS_ATTRIB_LARGE_FILE is not set then EFI_FFS_FILE_HEADER is used.
   ///
-  UINT64                    ExtendedSize;
+  UINT32                    ExtendedSize;
 } EFI_FFS_FILE_HEADER2;
 
 #define IS_FFS_FILE2(FfsFileHeaderPtr) \
@@ -185,7 +185,7 @@ typedef struct {
     ((UINT32) (*((UINT32 *) ((EFI_FFS_FILE_HEADER *) (UINTN) FfsFileHeaderPtr)->Size) & 0x00ffffff))
 
 #define FFS_FILE2_SIZE(FfsFileHeaderPtr) \
-    ((UINT32) (((EFI_FFS_FILE_HEADER2 *) (UINTN) FfsFileHeaderPtr)->ExtendedSize))
+    (((EFI_FFS_FILE_HEADER2 *) (UINTN) FfsFileHeaderPtr)->ExtendedSize)
 
 typedef UINT8 EFI_SECTION_TYPE;
 
index 121748d..c68ea30 100644 (file)
@@ -1,7 +1,7 @@
 /** @file
   HOB related definitions in PI.
 
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -11,7 +11,7 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
   @par Revision Reference:
-  PI Version 1.4
+  PI Version 1.0
 
 **/
 
@@ -257,16 +257,8 @@ typedef UINT32 EFI_RESOURCE_ATTRIBUTE_TYPE;
 #define EFI_RESOURCE_ATTRIBUTE_INITIALIZED              0x00000002
 #define EFI_RESOURCE_ATTRIBUTE_TESTED                   0x00000004
 #define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED           0x00000080
-//
-// This is typically used as memory cacheability attribute today.
-// NOTE: Since PI spec 1.4, please use EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED
-// as Physical write protected attribute, and EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED
-// means Memory cacheability attribute: The memory supports being programmed with
-// a writeprotected cacheable attribute.
-//
 #define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED          0x00000100
 #define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED      0x00000200
-#define EFI_RESOURCE_ATTRIBUTE_PERSISTENT               0x00800000
 //
 // The rest of the attributes are used to describe capabilities
 //
@@ -283,27 +275,8 @@ typedef UINT32 EFI_RESOURCE_ATTRIBUTE_TYPE;
 #define EFI_RESOURCE_ATTRIBUTE_64_BIT_IO                0x00010000
 #define EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED        0x00020000
 #define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE         0x00100000
-//
-// This is typically used as memory cacheability attribute today.
-// NOTE: Since PI spec 1.4, please use EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE
-// as Memory capability attribute: The memory supports being protected from processor
-// writes, and EFI_RESOURCE_ATTRIBUTE_WRITE_PROTEC TABLE means Memory cacheability attribute:
-// The memory supports being programmed with a writeprotected cacheable attribute.
-//
 #define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE        0x00200000
 #define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE    0x00400000
-#define EFI_RESOURCE_ATTRIBUTE_PERSISTABLE              0x01000000
-
-#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED      0x00040000
-#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE    0x00800000
-
-//
-// Physical memory relative reliability attribute. This
-// memory provides higher reliability relative to other
-// memory in the system. If all memory has the same
-// reliability, then this bit is not used.
-//
-#define EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE            0x02000000
 
 ///
 /// Describes the resource properties of all fixed,
index f35bb14..daf6591 100644 (file)
@@ -1,7 +1,7 @@
 /** @file
   Include file matches things in PI for multiple module types.
 
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -164,18 +164,4 @@ typedef struct {
   CHAR8             *PcdName;
 } EFI_PCD_INFO;
 
-/**
-  The function prototype for invoking a function on an Application Processor.
-
-  This definition is used by the UEFI MP Serices Protocol, and the
-  PI SMM System Table.
-
-  @param[in,out] Buffer  The pointer to private data buffer.
-**/
-typedef
-VOID
-(EFIAPI *EFI_AP_PROCEDURE)(
-  IN OUT VOID  *Buffer
-  );
-
 #endif
index ff1517f..7466814 100644 (file)
@@ -18,12 +18,4 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/efi/X64/ProcessorBind.h>
 #endif
 
-#if __arm__
-#include <ipxe/efi/Arm/ProcessorBind.h>
-#endif
-
-#if __aarch64__
-#include <ipxe/efi/AArch64/ProcessorBind.h>
-#endif
-
 #endif /* _IPXE_EFI_PROCESSOR_BIND_H */
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/AbsolutePointer.h b/roms/ipxe/src/include/ipxe/efi/Protocol/AbsolutePointer.h
deleted file mode 100644 (file)
index b20ca05..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/** @file
-  The file provides services that allow information about an
-  absolute pointer device to be retrieved.
-
-  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef __ABSOLUTE_POINTER_H__
-#define __ABSOLUTE_POINTER_H__
-
-FILE_LICENCE ( BSD3 );
-
-
-#define EFI_ABSOLUTE_POINTER_PROTOCOL_GUID \
-  { 0x8D59D32B, 0xC655, 0x4AE9, { 0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43 } }
-
-
-typedef struct _EFI_ABSOLUTE_POINTER_PROTOCOL EFI_ABSOLUTE_POINTER_PROTOCOL;
-
-
-//*******************************************************
-// EFI_ABSOLUTE_POINTER_MODE
-//*******************************************************
-
-
-/**
-  The following data values in the EFI_ABSOLUTE_POINTER_MODE
-  interface are read-only and are changed by using the appropriate
-  interface functions.
-**/
-typedef struct {
-  UINT64 AbsoluteMinX; ///< The Absolute Minimum of the device on the x-axis
-  UINT64 AbsoluteMinY; ///< The Absolute Minimum of the device on the y axis.
-  UINT64 AbsoluteMinZ; ///< The Absolute Minimum of the device on the z-axis
-  UINT64 AbsoluteMaxX; ///< The Absolute Maximum of the device on the x-axis. If 0, and the
-                       ///< AbsoluteMinX is 0, then the pointer device does not support a xaxis
-  UINT64 AbsoluteMaxY; ///< The Absolute Maximum of the device on the y -axis. If 0, and the
-                       ///< AbsoluteMinX is 0, then the pointer device does not support a yaxis.
-  UINT64 AbsoluteMaxZ; ///< The Absolute Maximum of the device on the z-axis. If 0 , and the
-                       ///< AbsoluteMinX is 0, then the pointer device does not support a zaxis
-  UINT32 Attributes;   ///< The following bits are set as needed (or'd together) to indicate the
-                       ///< capabilities of the device supported. The remaining bits are undefined
-                       ///< and should be 0
-} EFI_ABSOLUTE_POINTER_MODE;
-
-///
-/// If set, indicates this device supports an alternate button input.
-///
-#define EFI_ABSP_SupportsAltActive    0x00000001
-
-///
-/// If set, indicates this device returns pressure data in parameter CurrentZ.
-///
-#define EFI_ABSP_SupportsPressureAsZ  0x00000002
-
-
-/**
-  This function resets the pointer device hardware. As part of
-  initialization process, the firmware/device will make a quick
-  but reasonable attempt to verify that the device is
-  functioning. If the ExtendedVerification flag is TRUE the
-  firmware may take an extended amount of time to verify the
-  device is operating on reset. Otherwise the reset operation is
-  to occur as quickly as possible. The hardware verification
-  process is not defined by this specification and is left up to
-  the platform firmware or driver to implement.
-
-  @param This                 A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL
-                              instance.
-
-  @param ExtendedVerification Indicates that the driver may
-                              perform a more exhaustive
-                              verification operation of the
-                              device during reset.
-
-  @retval EFI_SUCCESS       The device was reset.
-
-  @retval EFI_DEVICE_ERROR  The device is not functioning
-                            correctly and could not be reset.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_ABSOLUTE_POINTER_RESET)(
-  IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,
-  IN BOOLEAN                       ExtendedVerification
-);
-
-///
-/// This bit is set if the touch sensor is active.
-///
-#define EFI_ABSP_TouchActive  0x00000001
-
-///
-/// This bit is set if the alt sensor, such as pen-side button, is active
-///
-#define EFI_ABS_AltActive     0x00000002
-
-
-/**
-  Definition of EFI_ABSOLUTE_POINTER_STATE.
-**/
-typedef struct {
-  ///
-  /// The unsigned position of the activation on the x axis. If the AboluteMinX
-  /// and the AboluteMaxX fields of the EFI_ABSOLUTE_POINTER_MODE structure are
-  /// both 0, then this pointer device does not support an x-axis, and this field
-  /// must be ignored.
-  ///
-  UINT64 CurrentX;
-
-  ///
-  /// The unsigned position of the activation on the y axis. If the AboluteMinY
-  /// and the AboluteMaxY fields of the EFI_ABSOLUTE_POINTER_MODE structure are
-  /// both 0, then this pointer device does not support an y-axis, and this field
-  /// must be ignored.
-  ///
-  UINT64 CurrentY;
-
-  ///
-  /// The unsigned position of the activation on the z axis, or the pressure
-  /// measurement. If the AboluteMinZ and the AboluteMaxZ fields of the
-  /// EFI_ABSOLUTE_POINTER_MODE structure are both 0, then this pointer device
-  /// does not support an z-axis, and this field must be ignored.
-  ///
-  UINT64 CurrentZ;
-
-  ///
-  /// Bits are set to 1 in this structure item to indicate that device buttons are
-  /// active.
-  ///
-  UINT32 ActiveButtons;
-} EFI_ABSOLUTE_POINTER_STATE;
-
-/**
-  The GetState() function retrieves the current state of a pointer
-  device. This includes information on the active state associated
-  with the pointer device and the current position of the axes
-  associated with the pointer device. If the state of the pointer
-  device has not changed since the last call to GetState(), then
-  EFI_NOT_READY is returned. If the state of the pointer device
-  has changed since the last call to GetState(), then the state
-  information is placed in State, and EFI_SUCCESS is returned. If
-  a device error occurs while attempting to retrieve the state
-  information, then EFI_DEVICE_ERROR is returned.
-
-
-  @param This   A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL
-                instance.
-
-  @param State  A pointer to the state information on the
-                pointer device.
-
-  @retval EFI_SUCCESS       The state of the pointer device was
-                            returned in State.
-
-  @retval EFI_NOT_READY     The state of the pointer device has not
-                            changed since the last call to GetState().
-
-  @retval EFI_DEVICE_ERROR  A device error occurred while
-                            attempting to retrieve the pointer
-                            device's current state.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_ABSOLUTE_POINTER_GET_STATE)(
-  IN      EFI_ABSOLUTE_POINTER_PROTOCOL  *This,
-  IN OUT  EFI_ABSOLUTE_POINTER_STATE     *State
-);
-
-
-///
-/// The EFI_ABSOLUTE_POINTER_PROTOCOL provides a set of services
-/// for a pointer device that can be used as an input device from an
-/// application written to this specification. The services include
-/// the ability to: reset the pointer device, retrieve the state of
-/// the pointer device, and retrieve the capabilities of the pointer
-/// device. The service also provides certain data items describing the device.
-///
-struct _EFI_ABSOLUTE_POINTER_PROTOCOL {
-  EFI_ABSOLUTE_POINTER_RESET      Reset;
-  EFI_ABSOLUTE_POINTER_GET_STATE  GetState;
-  ///
-  /// Event to use with WaitForEvent() to wait for input from the pointer device.
-  ///
-  EFI_EVENT                       WaitForInput;
-  ///
-  /// Pointer to EFI_ABSOLUTE_POINTER_MODE data.
-  ///
-  EFI_ABSOLUTE_POINTER_MODE       *Mode;
-};
-
-
-extern EFI_GUID gEfiAbsolutePointerProtocolGuid;
-
-
-#endif
-
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/AppleNetBoot.h b/roms/ipxe/src/include/ipxe/efi/Protocol/AppleNetBoot.h
deleted file mode 100644 (file)
index 144beff..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef __EFI_APPLE_NET_BOOT_PROTOCOL_H__
-#define __EFI_APPLE_NET_BOOT_PROTOCOL_H__
-
-/** @file
- *
- * Apple Net Boot Protocol
- *
- */
-
-FILE_LICENCE ( BSD3 );
-
-#define EFI_APPLE_NET_BOOT_PROTOCOL_GUID                               \
-       { 0x78ee99fb, 0x6a5e, 0x4186,                                   \
-       { 0x97, 0xde, 0xcd, 0x0a, 0xba, 0x34, 0x5a, 0x74 } }
-
-typedef struct _EFI_APPLE_NET_BOOT_PROTOCOL EFI_APPLE_NET_BOOT_PROTOCOL;
-
-/**
-  Get a DHCP packet obtained by the firmware during NetBoot.
-
-  @param  This         A pointer to the APPLE_NET_BOOT_PROTOCOL instance.
-  @param  BufferSize   A pointer to the size of the buffer in bytes.
-  @param  DataBuffer   The memory buffer to copy the packet to. If it is
-                       NULL, then the size of the packet is returned
-                       in BufferSize.
-  @retval EFI_SUCCESS          The packet was copied.
-  @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the
-                               current packet. BufferSize has been
-                               updated with the size needed to
-                               complete the request.
-**/
-typedef
-EFI_STATUS
-(EFIAPI *GET_DHCP_RESPONSE) (
-  IN EFI_APPLE_NET_BOOT_PROTOCOL       *This,
-  IN OUT UINTN                         *BufferSize,
-  OUT VOID                             *DataBuffer
-  );
-
-struct _EFI_APPLE_NET_BOOT_PROTOCOL
-{
-  GET_DHCP_RESPONSE    GetDhcpResponse;
-  GET_DHCP_RESPONSE    GetBsdpResponse;
-};
-
-#endif /*__EFI_APPLE_NET_BOOT_PROTOCOL_H__ */
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/Cpu.h b/roms/ipxe/src/include/ipxe/efi/Protocol/Cpu.h
new file mode 100644 (file)
index 0000000..665924e
--- /dev/null
@@ -0,0 +1,302 @@
+/** @file
+  CPU Architectural Protocol as defined in PI spec Volume 2 DXE
+
+  This code abstracts the DXE core from processor implementation details.
+
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __ARCH_PROTOCOL_CPU_H__
+#define __ARCH_PROTOCOL_CPU_H__
+
+FILE_LICENCE ( BSD3 );
+
+#include <ipxe/efi/Protocol/DebugSupport.h>
+
+#define EFI_CPU_ARCH_PROTOCOL_GUID \
+  { 0x26baccb1, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }
+
+typedef struct _EFI_CPU_ARCH_PROTOCOL   EFI_CPU_ARCH_PROTOCOL;
+
+///
+/// The type of flush operation
+///
+typedef enum {
+  EfiCpuFlushTypeWriteBackInvalidate,
+  EfiCpuFlushTypeWriteBack,
+  EfiCpuFlushTypeInvalidate,
+  EfiCpuMaxFlushType
+} EFI_CPU_FLUSH_TYPE;
+
+///
+/// The type of processor INIT.
+///
+typedef enum {
+  EfiCpuInit,
+  EfiCpuMaxInitType
+} EFI_CPU_INIT_TYPE;
+
+/**
+  EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
+
+  @param  InterruptType    Defines the type of interrupt or exception that
+                           occurred on the processor.This parameter is processor architecture specific.
+  @param  SystemContext    A pointer to the processor context when
+                           the interrupt occurred on the processor.
+
+  @return None
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_CPU_INTERRUPT_HANDLER)(
+  IN CONST  EFI_EXCEPTION_TYPE  InterruptType,
+  IN CONST  EFI_SYSTEM_CONTEXT  SystemContext
+  );
+
+/**
+  This function flushes the range of addresses from Start to Start+Length
+  from the processor's data cache. If Start is not aligned to a cache line
+  boundary, then the bytes before Start to the preceding cache line boundary
+  are also flushed. If Start+Length is not aligned to a cache line boundary,
+  then the bytes past Start+Length to the end of the next cache line boundary
+  are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be
+  supported. If the data cache is fully coherent with all DMA operations, then
+  this function can just return EFI_SUCCESS. If the processor does not support
+  flushing a range of the data cache, then the entire data cache can be flushed.
+
+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.
+  @param  Start            The beginning physical address to flush from the processor's data
+                           cache.
+  @param  Length           The number of bytes to flush from the processor's data cache. This
+                           function may flush more bytes than Length specifies depending upon
+                           the granularity of the flush operation that the processor supports.
+  @param  FlushType        Specifies the type of flush operation to perform.
+
+  @retval EFI_SUCCESS           The address range from Start to Start+Length was flushed from
+                                the processor's data cache.
+  @retval EFI_UNSUPPORTEDT      The processor does not support the cache flush type specified
+                                by FlushType.
+  @retval EFI_DEVICE_ERROR      The address range from Start to Start+Length could not be flushed
+                                from the processor's data cache.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CPU_FLUSH_DATA_CACHE)(
+  IN EFI_CPU_ARCH_PROTOCOL              *This,
+  IN EFI_PHYSICAL_ADDRESS               Start,
+  IN UINT64                             Length,
+  IN EFI_CPU_FLUSH_TYPE                 FlushType
+  );
+
+
+/**
+  This function enables interrupt processing by the processor.
+
+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.
+
+  @retval EFI_SUCCESS           Interrupts are enabled on the processor.
+  @retval EFI_DEVICE_ERROR      Interrupts could not be enabled on the processor.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CPU_ENABLE_INTERRUPT)(
+  IN EFI_CPU_ARCH_PROTOCOL              *This
+  );
+
+
+/**
+  This function disables interrupt processing by the processor.
+
+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.
+
+  @retval EFI_SUCCESS           Interrupts are disabled on the processor.
+  @retval EFI_DEVICE_ERROR      Interrupts could not be disabled on the processor.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CPU_DISABLE_INTERRUPT)(
+  IN EFI_CPU_ARCH_PROTOCOL              *This
+  );
+
+
+/**
+  This function retrieves the processor's current interrupt state a returns it in
+  State. If interrupts are currently enabled, then TRUE is returned. If interrupts
+  are currently disabled, then FALSE is returned.
+
+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.
+  @param  State            A pointer to the processor's current interrupt state. Set to TRUE if
+                           interrupts are enabled and FALSE if interrupts are disabled.
+
+  @retval EFI_SUCCESS           The processor's current interrupt state was returned in State.
+  @retval EFI_INVALID_PARAMETER State is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CPU_GET_INTERRUPT_STATE)(
+  IN EFI_CPU_ARCH_PROTOCOL              *This,
+  OUT BOOLEAN                           *State
+  );
+
+
+/**
+  This function generates an INIT on the processor. If this function succeeds, then the
+  processor will be reset, and control will not be returned to the caller. If InitType is
+  not supported by this processor, or the processor cannot programmatically generate an
+  INIT without help from external hardware, then EFI_UNSUPPORTED is returned. If an error
+  occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is returned.
+
+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.
+  @param  InitType         The type of processor INIT to perform.
+
+  @retval EFI_SUCCESS           The processor INIT was performed. This return code should never be seen.
+  @retval EFI_UNSUPPORTED       The processor INIT operation specified by InitType is not supported
+                                by this processor.
+  @retval EFI_DEVICE_ERROR      The processor INIT failed.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CPU_INIT)(
+  IN EFI_CPU_ARCH_PROTOCOL              *This,
+  IN EFI_CPU_INIT_TYPE                  InitType
+  );
+
+
+/**
+  This function registers and enables the handler specified by InterruptHandler for a processor
+  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+  handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+  The installed handler is called once for each processor interrupt or exception.
+
+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.
+  @param  InterruptType    A pointer to the processor's current interrupt state. Set to TRUE if interrupts
+                           are enabled and FALSE if interrupts are disabled.
+  @param  InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+                           when a processor interrupt occurs. If this parameter is NULL, then the handler
+                           will be uninstalled.
+
+  @retval EFI_SUCCESS           The handler for the processor interrupt was successfully installed or uninstalled.
+  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a handler for InterruptType was
+                                previously installed.
+  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+                                previously installed.
+  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is not supported.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CPU_REGISTER_INTERRUPT_HANDLER)(
+  IN EFI_CPU_ARCH_PROTOCOL              *This,
+  IN EFI_EXCEPTION_TYPE                 InterruptType,
+  IN EFI_CPU_INTERRUPT_HANDLER          InterruptHandler
+  );
+
+
+/**
+  This function reads the processor timer specified by TimerIndex and returns it in TimerValue.
+
+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.
+  @param  TimerIndex       Specifies which processor timer is to be returned in TimerValue. This parameter
+                           must be between 0 and NumberOfTimers-1.
+  @param  TimerValue       Pointer to the returned timer value.
+  @param  TimerPeriod      A pointer to the amount of time that passes in femtoseconds for each increment
+                           of TimerValue. If TimerValue does not increment at a predictable rate, then 0 is
+                           returned. This parameter is optional and may be NULL.
+
+  @retval EFI_SUCCESS           The processor timer value specified by TimerIndex was returned in TimerValue.
+  @retval EFI_DEVICE_ERROR      An error occurred attempting to read one of the processor's timers.
+  @retval EFI_INVALID_PARAMETER TimerValue is NULL or TimerIndex is not valid.
+  @retval EFI_UNSUPPORTED       The processor does not have any readable timers.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CPU_GET_TIMER_VALUE)(
+  IN EFI_CPU_ARCH_PROTOCOL              *This,
+  IN UINT32                             TimerIndex,
+  OUT UINT64                            *TimerValue,
+  OUT UINT64                            *TimerPeriod OPTIONAL
+  );
+
+
+/**
+  This function modifies the attributes for the memory region specified by BaseAddress and
+  Length from their current attributes to the attributes specified by Attributes.
+
+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.
+  @param  BaseAddress      The physical address that is the start address of a memory region.
+  @param  Length           The size in bytes of the memory region.
+  @param  Attributes       The bit mask of attributes to set for the memory region.
+
+  @retval EFI_SUCCESS           The attributes were set for the memory region.
+  @retval EFI_ACCESS_DENIED     The attributes for the memory resource range specified by
+                                BaseAddress and Length cannot be modified.
+  @retval EFI_INVALID_PARAMETER Length is zero.
+                                Attributes specified an illegal combination of attributes that
+                                cannot be set together.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the attributes of
+                                the memory resource range.
+  @retval EFI_UNSUPPORTED       The processor does not support one or more bytes of the memory
+                                resource range specified by BaseAddress and Length.
+                                The bit mask of attributes is not support for the memory resource
+                                range specified by BaseAddress and Length.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CPU_SET_MEMORY_ATTRIBUTES)(
+  IN EFI_CPU_ARCH_PROTOCOL              *This,
+  IN  EFI_PHYSICAL_ADDRESS              BaseAddress,
+  IN  UINT64                            Length,
+  IN  UINT64                            Attributes
+  );
+
+
+///
+/// The EFI_CPU_ARCH_PROTOCOL is used to abstract processor-specific functions from the DXE
+/// Foundation. This includes flushing caches, enabling and disabling interrupts, hooking interrupt
+/// vectors and exception vectors, reading internal processor timers, resetting the processor, and
+/// determining the processor frequency.
+///
+struct _EFI_CPU_ARCH_PROTOCOL {
+  EFI_CPU_FLUSH_DATA_CACHE            FlushDataCache;
+  EFI_CPU_ENABLE_INTERRUPT            EnableInterrupt;
+  EFI_CPU_DISABLE_INTERRUPT           DisableInterrupt;
+  EFI_CPU_GET_INTERRUPT_STATE         GetInterruptState;
+  EFI_CPU_INIT                        Init;
+  EFI_CPU_REGISTER_INTERRUPT_HANDLER  RegisterInterruptHandler;
+  EFI_CPU_GET_TIMER_VALUE             GetTimerValue;
+  EFI_CPU_SET_MEMORY_ATTRIBUTES       SetMemoryAttributes;
+  ///
+  /// The number of timers that are available in a processor. The value in this
+  /// field is a constant that must not be modified after the CPU Architectural
+  /// Protocol is installed. All consumers must treat this as a read-only field.
+  ///
+  UINT32                              NumberOfTimers;
+  ///
+  /// The size, in bytes, of the alignment required for DMA buffer allocations.
+  /// This is typically the size of the largest data cache line in the platform.
+  /// The value in this field is a constant that must not be modified after the
+  /// CPU Architectural Protocol is installed. All consumers must treat this as
+  /// a read-only field.
+  ///
+  UINT32                              DmaBufferAlignment;
+};
+
+extern EFI_GUID gEfiCpuArchProtocolGuid;
+
+#endif
index d35b65f..a305df5 100644 (file)
@@ -5,7 +5,7 @@
   from a software point of view. The path must persist from boot to boot, so
   it can not contain things like PCI bus numbers that change from boot to boot.
 
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -22,8 +22,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 FILE_LICENCE ( BSD3 );
 
 #include <ipxe/efi/Guid/PcAnsi.h>
-#include <ipxe/efi/IndustryStandard/Bluetooth.h>
-#include <ipxe/efi/IndustryStandard/Acpi60.h>
 
 ///
 /// Device Path protocol.
@@ -174,26 +172,6 @@ typedef struct {
 } CONTROLLER_DEVICE_PATH;
 
 ///
-/// BMC Device Path SubType.
-///
-#define HW_BMC_DP                 0x06
-
-///
-/// BMC Device Path.
-///
-typedef struct {
-  EFI_DEVICE_PATH_PROTOCOL        Header;
-  ///
-  /// Interface Type.
-  ///
-  UINT8                           InterfaceType;
-  ///
-  /// Base Address.
-  ///
-  UINT8                           BaseAddress[8];
-} BMC_DEVICE_PATH;
-
-///
 /// ACPI Device Paths.
 ///
 #define ACPI_DEVICE_PATH          0x02
@@ -297,14 +275,14 @@ typedef struct {
 #define ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL  4
 
 #define ACPI_DISPLAY_ADR(_DeviceIdScheme, _HeadId, _NonVgaOutput, _BiosCanDetect, _VendorInfo, _Type, _Port, _Index) \
-          ((UINT32)(  ((UINT32)((_DeviceIdScheme) & 0x1) << 31) |  \
-                      (((_HeadId)                 & 0x7) << 18) |  \
-                      (((_NonVgaOutput)           & 0x1) << 17) |  \
-                      (((_BiosCanDetect)          & 0x1) << 16) |  \
-                      (((_VendorInfo)             & 0xf) << 12) |  \
-                      (((_Type)                   & 0xf) << 8)  |  \
-                      (((_Port)                   & 0xf) << 4)  |  \
-                       ((_Index)                  & 0xf) ))
+          ((UINT32)( (((_DeviceIdScheme) & 0x1) << 31) |  \
+                      (((_HeadId)         & 0x7) << 18) |  \
+                      (((_NonVgaOutput)   & 0x1) << 17) |  \
+                      (((_BiosCanDetect)  & 0x1) << 16) |  \
+                      (((_VendorInfo)     & 0xf) << 12) |  \
+                      (((_Type)           & 0xf) << 8)  |  \
+                      (((_Port)           & 0xf) << 4)  |  \
+                       ((_Index)          & 0xf) ))
 
 ///
 /// Messaging Device Paths.
@@ -820,43 +798,6 @@ typedef struct {
 } NVME_NAMESPACE_DEVICE_PATH;
 
 ///
-/// Uniform Resource Identifiers (URI) Device Path SubType
-///
-#define MSG_URI_DP                0x18
-typedef struct {
-  EFI_DEVICE_PATH_PROTOCOL        Header;
-  ///
-  /// Instance of the URI pursuant to RFC 3986.
-  ///
-  CHAR8                           Uri[];
-} URI_DEVICE_PATH;
-
-///
-/// Universal Flash Storage (UFS) Device Path SubType.
-///
-#define MSG_UFS_DP                0x19
-typedef struct {
-  EFI_DEVICE_PATH_PROTOCOL        Header;
-  ///
-  /// Target ID on the UFS bus (PUN).
-  ///
-  UINT8                           Pun;
-  ///
-  /// Logical Unit Number (LUN).
-  ///
-  UINT8                           Lun;
-} UFS_DEVICE_PATH;
-
-///
-/// SD (Secure Digital) Device Path SubType.
-///
-#define MSG_SD_DP                 0x1A
-typedef struct {
-  EFI_DEVICE_PATH_PROTOCOL        Header;
-  UINT8                           SlotNumber;
-} SD_DEVICE_PATH;
-
-///
 /// iSCSI Device Path SubType
 ///
 #define MSG_ISCSI_DP              0x13
@@ -907,30 +848,6 @@ typedef struct {
   UINT16                          VlanId;
 } VLAN_DEVICE_PATH;
 
-///
-/// Bluetooth Device Path SubType.
-///
-#define MSG_BLUETOOTH_DP     0x1b
-typedef struct {
-  EFI_DEVICE_PATH_PROTOCOL        Header;
-  ///
-  /// 48bit Bluetooth device address.
-  ///
-  BLUETOOTH_ADDRESS               BD_ADDR;
-} BLUETOOTH_DEVICE_PATH;
-
-///
-/// Wi-Fi Device Path SubType.
-///
-#define MSG_WIFI_DP               0x1C
-typedef struct {
-  EFI_DEVICE_PATH_PROTOCOL        Header;
-  ///
-  /// Service set identifier. A 32-byte octets string.
-  ///
-  UINT8                           SSId[32];
-} WIFI_DEVICE_PATH;
-
 //
 // Media Device Path
 //
@@ -1100,62 +1017,6 @@ typedef struct {
 } MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH;
 
 ///
-/// This GUID defines a RAM Disk supporting a raw disk format in volatile memory.
-///
-#define EFI_VIRTUAL_DISK_GUID               EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE
-
-extern  EFI_GUID                            gEfiVirtualDiskGuid;
-
-///
-/// This GUID defines a RAM Disk supporting an ISO image in volatile memory.
-///
-#define EFI_VIRTUAL_CD_GUID                 EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE
-
-extern  EFI_GUID                            gEfiVirtualCdGuid;
-
-///
-/// This GUID defines a RAM Disk supporting a raw disk format in persistent memory.
-///
-#define EFI_PERSISTENT_VIRTUAL_DISK_GUID    EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT
-
-extern  EFI_GUID                            gEfiPersistentVirtualDiskGuid;
-
-///
-/// This GUID defines a RAM Disk supporting an ISO image in persistent memory.
-///
-#define EFI_PERSISTENT_VIRTUAL_CD_GUID      EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT
-
-extern  EFI_GUID                            gEfiPersistentVirtualCdGuid;
-
-///
-/// Media ram disk device path.
-///
-#define MEDIA_RAM_DISK_DP         0x09
-
-///
-/// Used to describe the ram disk device path.
-///
-typedef struct {
-  EFI_DEVICE_PATH_PROTOCOL        Header;
-  ///
-  /// Starting Memory Address.
-  ///
-  UINT32                          StartingAddr[2];
-  ///
-  /// Ending Memory Address.
-  ///
-  UINT32                          EndingAddr[2];
-  ///
-  /// GUID that defines the type of the RAM Disk.
-  ///
-  EFI_GUID                        TypeGuid;
-  ///
-  /// RAM Diskinstance number, if supported. The default value is zero.
-  ///
-  UINT16                          Instance;
-} MEDIA_RAM_DISK_DEVICE_PATH;
-
-///
 /// BIOS Boot Specification Device Path.
 ///
 #define BBS_DEVICE_PATH           0x05
@@ -1208,7 +1069,6 @@ typedef union {
   VENDOR_DEVICE_PATH                         Vendor;
 
   CONTROLLER_DEVICE_PATH                     Controller;
-  BMC_DEVICE_PATH                            Bmc;
   ACPI_HID_DEVICE_PATH                       Acpi;
   ACPI_EXTENDED_HID_DEVICE_PATH              ExtendedAcpi;
   ACPI_ADR_DEVICE_PATH                       AcpiAdr;
@@ -1236,11 +1096,6 @@ typedef union {
   SAS_DEVICE_PATH                            Sas;
   SASEX_DEVICE_PATH                          SasEx;
   NVME_NAMESPACE_DEVICE_PATH                 NvmeNamespace;
-  URI_DEVICE_PATH                            Uri;
-  BLUETOOTH_DEVICE_PATH                      Bluetooth;
-  WIFI_DEVICE_PATH                           WiFi;
-  UFS_DEVICE_PATH                            Ufs;
-  SD_DEVICE_PATH                             Sd;
   HARDDRIVE_DEVICE_PATH                      HardDrive;
   CDROM_DEVICE_PATH                          CD;
 
@@ -1250,7 +1105,7 @@ typedef union {
   MEDIA_FW_VOL_DEVICE_PATH                   FirmwareVolume;
   MEDIA_FW_VOL_FILEPATH_DEVICE_PATH          FirmwareFile;
   MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH    Offset;
-  MEDIA_RAM_DISK_DEVICE_PATH                 RamDisk;
+
   BBS_BBS_DEVICE_PATH                        Bbs;
 } EFI_DEV_PATH;
 
@@ -1264,7 +1119,6 @@ typedef union {
   VENDOR_DEVICE_PATH                         *Vendor;
 
   CONTROLLER_DEVICE_PATH                     *Controller;
-  BMC_DEVICE_PATH                            *Bmc;
   ACPI_HID_DEVICE_PATH                       *Acpi;
   ACPI_EXTENDED_HID_DEVICE_PATH              *ExtendedAcpi;
   ACPI_ADR_DEVICE_PATH                       *AcpiAdr;
@@ -1292,11 +1146,6 @@ typedef union {
   SAS_DEVICE_PATH                            *Sas;
   SASEX_DEVICE_PATH                          *SasEx;
   NVME_NAMESPACE_DEVICE_PATH                 *NvmeNamespace;
-  URI_DEVICE_PATH                            *Uri;
-  BLUETOOTH_DEVICE_PATH                      *Bluetooth;
-  WIFI_DEVICE_PATH                           *WiFi;
-  UFS_DEVICE_PATH                            *Ufs;
-  SD_DEVICE_PATH                             *Sd;
   HARDDRIVE_DEVICE_PATH                      *HardDrive;
   CDROM_DEVICE_PATH                          *CD;
 
@@ -1306,7 +1155,7 @@ typedef union {
   MEDIA_FW_VOL_DEVICE_PATH                   *FirmwareVolume;
   MEDIA_FW_VOL_FILEPATH_DEVICE_PATH          *FirmwareFile;
   MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH    *Offset;
-  MEDIA_RAM_DISK_DEVICE_PATH                 *RamDisk;
+
   BBS_BBS_DEVICE_PATH                        *Bbs;
   UINT8                                      *Raw;
 } EFI_DEV_PATH_PTR;
index 8033a11..0c0f56d 100644 (file)
@@ -4,7 +4,7 @@
   The EFI_FORM_BROWSER2_PROTOCOL is the interface to call for drivers to
   leverage the EFI configuration driver interface.
 
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -65,7 +65,6 @@ typedef UINTN EFI_BROWSER_ACTION_REQUEST;
 #define EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT 5
 #define EFI_BROWSER_ACTION_REQUEST_FORM_APPLY        6
 #define EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD      7
-#define EFI_BROWSER_ACTION_REQUEST_RECONNECT         8
 
 
 /**
index df90805..17ce3fd 100644 (file)
@@ -5,7 +5,7 @@
   This protocol is published by drivers providing and requesting
   configuration data from HII. It may only be invoked by HII.
 
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -36,7 +36,6 @@ typedef UINTN EFI_BROWSER_ACTION;
 #define EFI_BROWSER_ACTION_RETRIEVE   2
 #define EFI_BROWSER_ACTION_FORM_OPEN  3
 #define EFI_BROWSER_ACTION_FORM_CLOSE 4
-#define EFI_BROWSER_ACTION_SUBMITTED  5
 #define EFI_BROWSER_ACTION_DEFAULT_STANDARD      0x1000
 #define EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING 0x1001
 #define EFI_BROWSER_ACTION_DEFAULT_SAFE          0x1002
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/HiiFont.h b/roms/ipxe/src/include/ipxe/efi/Protocol/HiiFont.h
deleted file mode 100644 (file)
index f2b72dc..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-/** @file
-  The file provides services to retrieve font information.
-
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials are licensed and made available under
-the terms and conditions of the BSD License that accompanies this distribution.
-The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php.
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef __HII_FONT_H__
-#define __HII_FONT_H__
-
-FILE_LICENCE ( BSD3 );
-
-#include <ipxe/efi/Protocol/GraphicsOutput.h>
-#include <ipxe/efi/Protocol/HiiImage.h>
-
-#define EFI_HII_FONT_PROTOCOL_GUID \
-{ 0xe9ca4775, 0x8657, 0x47fc, { 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x8, 0x43, 0x24 } }
-
-typedef struct _EFI_HII_FONT_PROTOCOL EFI_HII_FONT_PROTOCOL;
-
-typedef VOID    *EFI_FONT_HANDLE;
-
-///
-/// EFI_HII_OUT_FLAGS.
-///
-typedef UINT32  EFI_HII_OUT_FLAGS;
-
-#define EFI_HII_OUT_FLAG_CLIP         0x00000001
-#define EFI_HII_OUT_FLAG_WRAP         0x00000002
-#define EFI_HII_OUT_FLAG_CLIP_CLEAN_Y 0x00000004
-#define EFI_HII_OUT_FLAG_CLIP_CLEAN_X 0x00000008
-#define EFI_HII_OUT_FLAG_TRANSPARENT  0x00000010
-#define EFI_HII_IGNORE_IF_NO_GLYPH    0x00000020
-#define EFI_HII_IGNORE_LINE_BREAK     0x00000040
-#define EFI_HII_DIRECT_TO_SCREEN      0x00000080
-
-/**
-  Definition of EFI_HII_ROW_INFO.
-**/
-typedef struct _EFI_HII_ROW_INFO {
-  ///
-  /// The index of the first character in the string which is displayed on the line.
-  ///
-  UINTN   StartIndex;
-  ///
-  /// The index of the last character in the string which is displayed on the line.
-  /// If this is the same as StartIndex, then no characters are displayed.
-  ///
-  UINTN   EndIndex;
-  UINTN   LineHeight; ///< The height of the line, in pixels.
-  UINTN   LineWidth;  ///< The width of the text on the line, in pixels.
-
-  ///
-  /// The font baseline offset in pixels from the bottom of the row, or 0 if none.
-  ///
-  UINTN   BaselineOffset;
-} EFI_HII_ROW_INFO;
-
-///
-/// Font info flag. All flags (FONT, SIZE, STYLE, and COLOR) are defined.
-/// They are defined as EFI_FONT_INFO_***
-///
-typedef UINT32  EFI_FONT_INFO_MASK;
-
-#define EFI_FONT_INFO_SYS_FONT        0x00000001
-#define EFI_FONT_INFO_SYS_SIZE        0x00000002
-#define EFI_FONT_INFO_SYS_STYLE       0x00000004
-#define EFI_FONT_INFO_SYS_FORE_COLOR  0x00000010
-#define EFI_FONT_INFO_SYS_BACK_COLOR  0x00000020
-#define EFI_FONT_INFO_RESIZE          0x00001000
-#define EFI_FONT_INFO_RESTYLE         0x00002000
-#define EFI_FONT_INFO_ANY_FONT        0x00010000
-#define EFI_FONT_INFO_ANY_SIZE        0x00020000
-#define EFI_FONT_INFO_ANY_STYLE       0x00040000
-
-//
-// EFI_FONT_INFO
-//
-typedef struct {
-  EFI_HII_FONT_STYLE FontStyle;
-  UINT16             FontSize;      ///< character cell height in pixels
-  CHAR16             FontName[1];
-} EFI_FONT_INFO;
-
-/**
-  Describes font output-related information.
-
-  This structure is used for describing the way in which a string
-  should be rendered in a particular font. FontInfo specifies the
-  basic font information and ForegroundColor and BackgroundColor
-  specify the color in which they should be displayed. The flags
-  in FontInfoMask describe where the system default should be
-  supplied instead of the specified information. The flags also
-  describe what options can be used to make a match between the
-  font requested and the font available.
-**/
-typedef struct _EFI_FONT_DISPLAY_INFO {
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL ForegroundColor;
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL BackgroundColor;
-  EFI_FONT_INFO_MASK            FontInfoMask;
-  EFI_FONT_INFO                 FontInfo;
-} EFI_FONT_DISPLAY_INFO;
-
-/**
-
-  This function renders a string to a bitmap or the screen using
-  the specified font, color and options. It either draws the
-  string and glyphs on an existing bitmap, allocates a new bitmap,
-  or uses the screen. The strings can be clipped or wrapped.
-  Optionally, the function also returns the information about each
-  row and the character position on that row. If
-  EFI_HII_OUT_FLAG_CLIP is set, then text will be formatted only
-  based on explicit line breaks and all pixels which would lie
-  outside the bounding box specified by Width and Height are
-  ignored. The information in the RowInfoArray only describes
-  characters which are at least partially displayed. For the final
-  row, the LineHeight and BaseLine may describe pixels that are
-  outside the limit specified by Height (unless
-  EFI_HII_OUT_FLAG_CLIP_CLEAN_Y is specified) even though those
-  pixels were not drawn. The LineWidth may describe pixels which
-  are outside the limit specified by Width (unless
-  EFI_HII_OUT_FLAG_CLIP_CLEAN_X is specified) even though those
-  pixels were not drawn. If EFI_HII_OUT_FLAG_CLIP_CLEAN_X is set,
-  then it modifies the behavior of EFI_HII_OUT_FLAG_CLIP so that
-  if a character's right-most on pixel cannot fit, then it will
-  not be drawn at all. This flag requires that
-  EFI_HII_OUT_FLAG_CLIP be set. If EFI_HII_OUT_FLAG_CLIP_CLEAN_Y
-  is set, then it modifies the behavior of EFI_HII_OUT_FLAG_CLIP
-  so that if a row's bottom-most pixel cannot fit, then it will
-  not be drawn at all. This flag requires that
-  EFI_HII_OUT_FLAG_CLIP be set. If EFI_HII_OUT_FLAG_WRAP is set,
-  then text will be wrapped at the right-most line-break
-  opportunity prior to a character whose right-most extent would
-  exceed Width. If no line-break opportunity can be found, then
-  the text will behave as if EFI_HII_OUT_FLAG_CLIP_CLEAN_X is set.
-  This flag cannot be used with EFI_HII_OUT_FLAG_CLIP_CLEAN_X. If
-  EFI_HII_OUT_FLAG_TRANSPARENT is set, then BackgroundColor is
-  ignored and all 'off' pixels in the character's drawn
-  will use the pixel value from Blt. This flag cannot be used if
-  Blt is NULL upon entry. If EFI_HII_IGNORE_IF_NO_GLYPH is set,
-  then characters which have no glyphs are not drawn. Otherwise,
-  they are replaced with Unicode character code 0xFFFD (REPLACEMENT
-  CHARACTER). If EFI_HII_IGNORE_LINE_BREAK is set, then explicit
-  line break characters will be ignored. If
-  EFI_HII_DIRECT_TO_SCREEN is set, then the string will be written
-  directly to the output device specified by Screen. Otherwise the
-  string will be rendered to the bitmap specified by Bitmap.
-
-  @param This             A pointer to the EFI_HII_FONT_PROTOCOL instance.
-
-  @param Flags            Describes how the string is to be drawn.
-
-  @param String           Points to the null-terminated string to be
-
-  @param StringInfo       Points to the string output information,
-                          including the color and font. If NULL, then
-                          the string will be output in the default
-                          system font and color.
-
-  @param Blt              If this points to a non-NULL on entry, this points
-                          to the image, which is Width pixels wide and
-                          Height pixels high. The string will be drawn onto
-                          this image and EFI_HII_OUT_FLAG_CLIP is implied.
-                          If this points to a NULL on entry, then a buffer
-                          will be allocated to hold the generated image and
-                          the pointer updated on exit. It is the caller's
-                          responsibility to free this buffer.
-
-  @param BltX, BltY       Specifies the offset from the left and top
-                          edge of the image of the first character
-                          cell in the image.
-
-  @param RowInfoArray     If this is non-NULL on entry, then on
-                          exit, this will point to an allocated buffer
-                          containing row information and
-                          RowInfoArraySize will be updated to contain
-                          the number of elements. This array describes
-                          the characters that were at least partially
-                          drawn and the heights of the rows. It is the
-                          caller's responsibility to free this buffer.
-
-  @param RowInfoArraySize If this is non-NULL on entry, then on
-                          exit it contains the number of
-                          elements in RowInfoArray.
-
-  @param ColumnInfoArray  If this is non-NULL, then on return it
-                          will be filled with the horizontal
-                          offset for each character in the
-                          string on the row where it is
-                          displayed. Non-printing characters
-                          will have the offset ~0. The caller is
-                          responsible for allocating a buffer large
-                          enough so that there is one entry for
-                          each character in the string, not
-                          including the null-terminator. It is
-                          possible when character display is
-                          normalized that some character cells
-                          overlap.
-
-  @retval EFI_SUCCESS           The string was successfully updated.
-
-  @retval EFI_OUT_OF_RESOURCES  Unable to allocate an output buffer for RowInfoArray or Blt.
-
-  @retval EFI_INVALID_PARAMETER The String or Blt was NULL.
-
-  @retval EFI_INVALID_PARAMETER Flags were invalid combination.
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_HII_STRING_TO_IMAGE)(
-  IN CONST  EFI_HII_FONT_PROTOCOL *This,
-  IN        EFI_HII_OUT_FLAGS     Flags,
-  IN CONST  EFI_STRING            String,
-  IN CONST  EFI_FONT_DISPLAY_INFO *StringInfo,
-  IN OUT    EFI_IMAGE_OUTPUT      **Blt,
-  IN        UINTN                 BltX,
-  IN        UINTN                 BltY,
-  OUT       EFI_HII_ROW_INFO      **RowInfoArray OPTIONAL,
-  OUT       UINTN                 *RowInfoArraySize OPTIONAL,
-  OUT       UINTN                 *ColumnInfoArray OPTIONAL
-);
-
-
-
-/**
-
-  This function renders a string as a bitmap or to the screen
-  and can clip or wrap the string. The bitmap is either supplied
-  by the caller or allocated by the function. The
-  strings are drawn with the font, size and style specified and
-  can be drawn transparently or opaquely. The function can also
-  return information about each row and each character's
-  position on the row. If EFI_HII_OUT_FLAG_CLIP is set, then
-  text will be formatted based only on explicit line breaks, and
-  all pixels that would lie outside the bounding box specified
-  by Width and Height are ignored. The information in the
-  RowInfoArray only describes characters which are at least
-  partially displayed. For the final row, the LineHeight and
-  BaseLine may describe pixels which are outside the limit
-  specified by Height (unless EFI_HII_OUT_FLAG_CLIP_CLEAN_Y is
-  specified) even though those pixels were not drawn. If
-  EFI_HII_OUT_FLAG_CLIP_CLEAN_X is set, then it modifies the
-  behavior of EFI_HII_OUT_FLAG_CLIP so that if a character's
-  right-most on pixel cannot fit, then it will not be drawn at
-  all. This flag requires that EFI_HII_OUT_FLAG_CLIP be set. If
-  EFI_HII_OUT_FLAG_CLIP_CLEAN_Y is set, then it modifies the
-  behavior of EFI_HII_OUT_FLAG_CLIP so that if a row's bottom
-  most pixel cannot fit, then it will not be drawn at all. This
-  flag requires that EFI_HII_OUT_FLAG_CLIP be set. If
-  EFI_HII_OUT_FLAG_WRAP is set, then text will be wrapped at the
-  right-most line-break opportunity prior to a character whose
-  right-most extent would exceed Width. If no line-break
-  opportunity can be found, then the text will behave as if
-  EFI_HII_OUT_FLAG_CLIP_CLEAN_X is set. This flag cannot be used
-  with EFI_HII_OUT_FLAG_CLIP_CLEAN_X. If
-  EFI_HII_OUT_FLAG_TRANSPARENT is set, then BackgroundColor is
-  ignored and all off" pixels in the character's glyph will
-  use the pixel value from Blt. This flag cannot be used if Blt
-  is NULL upon entry. If EFI_HII_IGNORE_IF_NO_GLYPH is set, then
-  characters which have no glyphs are not drawn. Otherwise, they
-  are replaced with Unicode character code 0xFFFD (REPLACEMENT
-  CHARACTER). If EFI_HII_IGNORE_LINE_BREAK is set, then explicit
-  line break characters will be ignored. If
-  EFI_HII_DIRECT_TO_SCREEN is set, then the string will be
-  written directly to the output device specified by Screen.
-  Otherwise the string will be rendered to the bitmap specified
-  by Bitmap.
-
-
-  @param This       A pointer to the EFI_HII_FONT_PROTOCOL instance.
-
-  @param Flags      Describes how the string is to be drawn.
-
-  @param PackageList
-                    The package list in the HII database to
-                    search for the specified string.
-
-  @param StringId   The string's id, which is unique within
-                    PackageList.
-
-  @param Language   Points to the language for the retrieved
-                    string. If NULL, then the current system
-                    language is used.
-
-  @param StringInfo Points to the string output information,
-                    including the color and font. If NULL, then
-                    the string will be output in the default
-                    system font and color.
-
-  @param Blt        If this points to a non-NULL on entry, this points
-                    to the image, which is Width pixels wide and
-                    Height pixels high. The string will be drawn onto
-                    this image and EFI_HII_OUT_FLAG_CLIP is implied.
-                    If this points to a NULL on entry, then a buffer
-                    will be allocated to hold the generated image and
-                    the pointer updated on exit. It is the caller's
-                    responsibility to free this buffer.
-
-  @param BltX, BltY Specifies the offset from the left and top
-                    edge of the output image of the first
-                    character cell in the image.
-
-  @param RowInfoArray     If this is non-NULL on entry, then on
-                          exit, this will point to an allocated
-                          buffer containing row information and
-                          RowInfoArraySize will be updated to
-                          contain the number of elements. This array
-                          describes the characters which were at
-                          least partially drawn and the heights of
-                          the rows. It is the caller's
-                          responsibility to free this buffer.
-
-  @param RowInfoArraySize If this is non-NULL on entry, then on
-                          exit it contains the number of
-                          elements in RowInfoArray.
-
-  @param ColumnInfoArray  If non-NULL, on return it is filled
-                          with the horizontal offset for each
-                          character in the string on the row
-                          where it is displayed. Non-printing
-                          characters will have the offset ~0.
-                          The caller is responsible to allocate
-                          a buffer large enough so that there is
-                          one entry for each character in the
-                          string, not including the
-                          null-terminator. It is possible when
-                          character display is normalized that
-                          some character cells overlap.
-
-
-  @retval EFI_SUCCESS           The string was successfully updated.
-
-  @retval EFI_OUT_OF_RESOURCES  Unable to allocate an output
-                                buffer for RowInfoArray or Blt.
-
-  @retval EFI_INVALID_PARAMETER The String, or Blt, or Height, or
-                                Width was NULL.
-  @retval EFI_INVALID_PARAMETER The Blt or PackageList was NULL.
-  @retval EFI_INVALID_PARAMETER Flags were invalid combination.
-  @retval EFI_NOT_FOUND         The specified PackageList is not in the Database,
-                                or the stringid is not in the specified PackageList.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_HII_STRING_ID_TO_IMAGE)(
-  IN CONST  EFI_HII_FONT_PROTOCOL *This,
-  IN        EFI_HII_OUT_FLAGS     Flags,
-  IN        EFI_HII_HANDLE        PackageList,
-  IN        EFI_STRING_ID         StringId,
-  IN CONST  CHAR8                 *Language,
-  IN CONST  EFI_FONT_DISPLAY_INFO *StringInfo       OPTIONAL,
-  IN OUT    EFI_IMAGE_OUTPUT      **Blt,
-  IN        UINTN                 BltX,
-  IN        UINTN                 BltY,
-  OUT       EFI_HII_ROW_INFO      **RowInfoArray    OPTIONAL,
-  OUT       UINTN                 *RowInfoArraySize OPTIONAL,
-  OUT       UINTN                 *ColumnInfoArray  OPTIONAL
-);
-
-
-/**
-
-  Convert the glyph for a single character into a bitmap.
-
-  @param This       A pointer to the EFI_HII_FONT_PROTOCOL instance.
-
-  @param Char       The character to retrieve.
-
-  @param StringInfo Points to the string font and color
-                    information or NULL if the string should use
-                    the default system font and color.
-
-  @param Blt        This must point to a NULL on entry. A buffer will
-                    be allocated to hold the output and the pointer
-                    updated on exit. It is the caller's responsibility
-                    to free this buffer.
-
-  @param Baseline   The number of pixels from the bottom of the bitmap
-                    to the baseline.
-
-
-  @retval EFI_SUCCESS             The glyph bitmap created.
-
-  @retval EFI_OUT_OF_RESOURCES    Unable to allocate the output buffer Blt.
-
-  @retval EFI_WARN_UNKNOWN_GLYPH  The glyph was unknown and was
-                                  replaced with the glyph for
-                                  Unicode character code 0xFFFD.
-
-  @retval EFI_INVALID_PARAMETER   Blt is NULL, or Width is NULL, or
-                                  Height is NULL
-
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_HII_GET_GLYPH)(
-  IN CONST  EFI_HII_FONT_PROTOCOL *This,
-  IN CONST  CHAR16                Char,
-  IN CONST  EFI_FONT_DISPLAY_INFO *StringInfo,
-  OUT       EFI_IMAGE_OUTPUT      **Blt,
-  OUT       UINTN                 *Baseline OPTIONAL
-);
-
-/**
-
-  This function iterates through fonts which match the specified
-  font, using the specified criteria. If String is non-NULL, then
-  all of the characters in the string must exist in order for a
-  candidate font to be returned.
-
-  @param This           A pointer to the EFI_HII_FONT_PROTOCOL instance.
-
-  @param FontHandle     On entry, points to the font handle returned
-                        by a previous call to GetFontInfo() or NULL
-                        to start with the first font. On return,
-                        points to the returned font handle or points
-                        to NULL if there are no more matching fonts.
-
-  @param StringInfoIn   Upon entry, points to the font to return
-                        information about. If NULL, then the information
-                        about the system default font will be returned.
-
-  @param  StringInfoOut Upon return, contains the matching font's information.
-                        If NULL, then no information is returned. This buffer
-                        is allocated with a call to the Boot Service AllocatePool().
-                        It is the caller's responsibility to call the Boot
-                        Service FreePool() when the caller no longer requires
-                        the contents of StringInfoOut.
-
-  @param String         Points to the string which will be tested to
-                        determine if all characters are available. If
-                        NULL, then any font is acceptable.
-
-  @retval EFI_SUCCESS            Matching font returned successfully.
-
-  @retval EFI_NOT_FOUND          No matching font was found.
-
-  @retval EFI_OUT_OF_RESOURCES   There were insufficient resources to complete the request.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_HII_GET_FONT_INFO)(
-  IN CONST  EFI_HII_FONT_PROTOCOL *This,
-  IN OUT    EFI_FONT_HANDLE       *FontHandle,
-  IN CONST  EFI_FONT_DISPLAY_INFO *StringInfoIn, OPTIONAL
-  OUT       EFI_FONT_DISPLAY_INFO **StringInfoOut,
-  IN CONST  EFI_STRING            String OPTIONAL
-);
-
-///
-/// The protocol provides the service to retrieve the font informations.
-///
-struct _EFI_HII_FONT_PROTOCOL {
-  EFI_HII_STRING_TO_IMAGE     StringToImage;
-  EFI_HII_STRING_ID_TO_IMAGE  StringIdToImage;
-  EFI_HII_GET_GLYPH           GetGlyph;
-  EFI_HII_GET_FONT_INFO       GetFontInfo;
-};
-
-extern EFI_GUID gEfiHiiFontProtocolGuid;
-
-
-#endif
-
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/HiiImage.h b/roms/ipxe/src/include/ipxe/efi/Protocol/HiiImage.h
deleted file mode 100644 (file)
index b18d51a..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/** @file
-  The file provides services to access to images in the images database.
-
-  Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef __HII_IMAGE_H__
-#define __HII_IMAGE_H__
-
-FILE_LICENCE ( BSD3 );
-
-#define EFI_HII_IMAGE_PROTOCOL_GUID \
-  { 0x31a6406a, 0x6bdf, 0x4e46, { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } }
-
-typedef struct _EFI_HII_IMAGE_PROTOCOL EFI_HII_IMAGE_PROTOCOL;
-
-
-///
-/// Flags in EFI_IMAGE_INPUT
-///
-#define EFI_IMAGE_TRANSPARENT 0x00000001
-
-/**
-
-  Definition of EFI_IMAGE_INPUT.
-
-  @param Flags  Describe image characteristics. If
-                EFI_IMAGE_TRANSPARENT is set, then the image was
-                designed for transparent display.
-
-  @param Width  Image width, in pixels.
-
-  @param Height Image height, in pixels.
-
-  @param Bitmap A pointer to the actual bitmap, organized left-to-right,
-                top-to-bottom. The size of the bitmap is
-                Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL).
-
-
-**/
-typedef struct _EFI_IMAGE_INPUT {
-  UINT32                          Flags;
-  UINT16                          Width;
-  UINT16                          Height;
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *Bitmap;
-} EFI_IMAGE_INPUT;
-
-
-/**
-
-  This function adds the image Image to the group of images
-  owned by PackageList, and returns a new image identifier
-  (ImageId).
-
-  @param This        A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
-
-  @param PackageList Handle of the package list where this image will be added.
-
-  @param ImageId     On return, contains the new image id, which is
-                     unique within PackageList.
-
-  @param Image       Points to the image.
-
-  @retval EFI_SUCCESS             The new image was added
-                                  successfully
-
-  @retval EFI_OUT_OF_RESOURCES    Could not add the image.
-
-  @retval EFI_INVALID_PARAMETER   Image is NULL or ImageId is
-                                  NULL.
-
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_HII_NEW_IMAGE)(
-  IN CONST  EFI_HII_IMAGE_PROTOCOL  *This,
-  IN        EFI_HII_HANDLE          PackageList,
-  OUT       EFI_IMAGE_ID            *ImageId,
-  IN CONST  EFI_IMAGE_INPUT         *Image
-);
-
-/**
-
-  This function retrieves the image specified by ImageId which
-  is associated with the specified PackageList and copies it
-  into the buffer specified by Image. If the image specified by
-  ImageId is not present in the specified PackageList, then
-  EFI_NOT_FOUND is returned. If the buffer specified by
-  ImageSize is too small to hold the image, then
-  EFI_BUFFER_TOO_SMALL will be returned. ImageSize will be
-  updated to the size of buffer actually required to hold the
-  image.
-
-  @param This         A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
-
-  @param PackageList  The package list in the HII database to
-                      search for the specified image.
-
-  @param ImageId      The image's id, which is unique within
-                      PackageList.
-
-  @param Image        Points to the new image.
-
-  @retval EFI_SUCCESS            The image was returned successfully.
-
-  @retval EFI_NOT_FOUND          The image specified by ImageId is not
-                                 available. Or The specified PackageList is not in the database.
-
-  @retval EFI_INVALID_PARAMETER  The Image or Langugae was NULL.
-  @retval EFI_OUT_OF_RESOURCES   The bitmap could not be retrieved because there was not
-                                 enough memory.
-
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_HII_GET_IMAGE)(
-  IN CONST  EFI_HII_IMAGE_PROTOCOL  *This,
-  IN        EFI_HII_HANDLE          PackageList,
-  IN        EFI_IMAGE_ID            ImageId,
-  OUT       EFI_IMAGE_INPUT         *Image
-);
-
-/**
-
-  This function updates the image specified by ImageId in the
-  specified PackageListHandle to the image specified by Image.
-
-
-  @param This         A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
-
-  @param PackageList  The package list containing the images.
-
-  @param ImageId      The image id, which is unique within PackageList.
-
-  @param Image        Points to the image.
-
-  @retval EFI_SUCCESS           The image was successfully updated.
-
-  @retval EFI_NOT_FOUND         The image specified by ImageId is not in the database.
-                                The specified PackageList is not in the database.
-
-  @retval EFI_INVALID_PARAMETER The Image or Language was NULL.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_HII_SET_IMAGE)(
-  IN CONST  EFI_HII_IMAGE_PROTOCOL  *This,
-  IN        EFI_HII_HANDLE          PackageList,
-  IN        EFI_IMAGE_ID            ImageId,
-  IN CONST  EFI_IMAGE_INPUT         *Image
-);
-
-
-///
-/// EFI_HII_DRAW_FLAGS describes how the image is to be drawn.
-/// These flags are defined as EFI_HII_DRAW_FLAG_***
-///
-typedef UINT32  EFI_HII_DRAW_FLAGS;
-
-#define EFI_HII_DRAW_FLAG_CLIP          0x00000001
-#define EFI_HII_DRAW_FLAG_TRANSPARENT   0x00000030
-#define EFI_HII_DRAW_FLAG_DEFAULT       0x00000000
-#define EFI_HII_DRAW_FLAG_FORCE_TRANS   0x00000010
-#define EFI_HII_DRAW_FLAG_FORCE_OPAQUE  0x00000020
-#define EFI_HII_DIRECT_TO_SCREEN        0x00000080
-
-/**
-
-  Definition of EFI_IMAGE_OUTPUT.
-
-  @param Width  Width of the output image.
-
-  @param Height Height of the output image.
-
-  @param Bitmap Points to the output bitmap.
-
-  @param Screen Points to the EFI_GRAPHICS_OUTPUT_PROTOCOL which
-                describes the screen on which to draw the
-                specified image.
-
-**/
-typedef struct _EFI_IMAGE_OUTPUT {
-  UINT16  Width;
-  UINT16  Height;
-  union {
-    EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Bitmap;
-    EFI_GRAPHICS_OUTPUT_PROTOCOL  *Screen;
-  } Image;
-} EFI_IMAGE_OUTPUT;
-
-
-/**
-
-  This function renders an image to a bitmap or the screen using
-  the specified color and options. It draws the image on an
-  existing bitmap, allocates a new bitmap or uses the screen. The
-  images can be clipped. If EFI_HII_DRAW_FLAG_CLIP is set, then
-  all pixels drawn outside the bounding box specified by Width and
-  Height are ignored. If EFI_HII_DRAW_FLAG_TRANSPARENT is set,
-  then all 'off' pixels in the images drawn will use the
-  pixel value from Blt. This flag cannot be used if Blt is NULL
-  upon entry. If EFI_HII_DIRECT_TO_SCREEN is set, then the image
-  will be written directly to the output device specified by
-  Screen. Otherwise the image will be rendered to the bitmap
-  specified by Bitmap.
-
-
-  @param This       A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
-
-  @param Flags      Describes how the image is to be drawn.
-                    EFI_HII_DRAW_FLAGS is defined in Related
-                    Definitions, below.
-
-  @param Image      Points to the image to be displayed.
-
-  @param Blt        If this points to a non-NULL on entry, this points
-                    to the image, which is Width pixels wide and
-                    Height pixels high. The image will be drawn onto
-                    this image and EFI_HII_DRAW_FLAG_CLIP is implied.
-                    If this points to a NULL on entry, then a buffer
-                    will be allocated to hold the generated image and
-                    the pointer updated on exit. It is the caller's
-                    responsibility to free this buffer.
-
-  @param BltX, BltY Specifies the offset from the left and top
-                    edge of the image of the first pixel in
-                    the image.
-
-  @retval EFI_SUCCESS           The image was successfully updated.
-
-  @retval EFI_OUT_OF_RESOURCES  Unable to allocate an output
-                                buffer for RowInfoArray or Blt.
-
-  @retval EFI_INVALID_PARAMETER The Image or Blt or Height or
-                                Width was NULL.
-
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_HII_DRAW_IMAGE)(
-  IN CONST  EFI_HII_IMAGE_PROTOCOL  *This,
-  IN        EFI_HII_DRAW_FLAGS      Flags,
-  IN CONST  EFI_IMAGE_INPUT         *Image,
-  IN OUT    EFI_IMAGE_OUTPUT        **Blt,
-  IN        UINTN                   BltX,
-  IN        UINTN                   BltY
-);
-
-/**
-
-  This function renders an image as a bitmap or to the screen and
-  can clip the image. The bitmap is either supplied by the caller
-  or else is allocated by the function. The images can be drawn
-  transparently or opaquely. If EFI_HII_DRAW_FLAG_CLIP is set,
-  then all pixels drawn outside the bounding box specified by
-  Width and Height are ignored. If EFI_HII_DRAW_FLAG_TRANSPARENT
-  is set, then all "off" pixels in the character's glyph will
-  use the pixel value from Blt. This flag cannot be used if Blt
-  is NULL upon entry. If EFI_HII_DIRECT_TO_SCREEN is set, then
-  the image will be written directly to the output device
-  specified by Screen. Otherwise the image will be rendered to
-  the bitmap specified by Bitmap.
-  This function renders an image to a bitmap or the screen using
-  the specified color and options. It draws the image on an
-  existing bitmap, allocates a new bitmap or uses the screen. The
-  images can be clipped. If EFI_HII_DRAW_FLAG_CLIP is set, then
-  all pixels drawn outside the bounding box specified by Width and
-  Height are ignored. The EFI_HII_DRAW_FLAG_TRANSPARENT flag
-  determines whether the image will be drawn transparent or
-  opaque. If EFI_HII_DRAW_FLAG_FORCE_TRANS is set, then the image
-  will be drawn so that all 'off' pixels in the image will
-  be drawn using the pixel value from Blt and all other pixels
-  will be copied. If EFI_HII_DRAW_FLAG_FORCE_OPAQUE is set, then
-  the image's pixels will be copied directly to the
-  destination. If EFI_HII_DRAW_FLAG_DEFAULT is set, then the image
-  will be drawn transparently or opaque, depending on the
-  image's transparency setting (see EFI_IMAGE_TRANSPARENT).
-  Images cannot be drawn transparently if Blt is NULL. If
-  EFI_HII_DIRECT_TO_SCREEN is set, then the image will be written
-  directly to the output device specified by Screen. Otherwise the
-  image will be rendered to the bitmap specified by Bitmap.
-
-  @param This         A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
-
-  @param Flags        Describes how the image is to be drawn.
-
-  @param PackageList  The package list in the HII database to
-                      search for the specified image.
-
-  @param ImageId      The image's id, which is unique within PackageList.
-
-  @param Blt          If this points to a non-NULL on entry, this points
-                      to the image, which is Width pixels wide and
-                      Height pixels high. The image will be drawn onto
-                      this image and EFI_HII_DRAW_FLAG_CLIP is implied.
-                      If this points to a NULL on entry, then a buffer
-                      will be allocated to hold the generated image and
-                      the pointer updated on exit. It is the caller's
-                      responsibility to free this buffer.
-
-  @param BltX, BltY   Specifies the offset from the left and top
-                      edge of the output image of the first
-                      pixel in the image.
-
-  @retval EFI_SUCCESS           The image was successfully updated.
-
-  @retval EFI_OUT_OF_RESOURCES  Unable to allocate an output
-                                buffer for RowInfoArray or Blt.
-
-  @retval EFI_NOT_FOUND         The image specified by ImageId is not in the database.
-                                Or The specified PackageList is not in the database.
-
-  @retval EFI_INVALID_PARAMETER The Blt was NULL.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_HII_DRAW_IMAGE_ID)(
-IN CONST  EFI_HII_IMAGE_PROTOCOL  *This,
-IN        EFI_HII_DRAW_FLAGS      Flags,
-IN        EFI_HII_HANDLE          PackageList,
-IN        EFI_IMAGE_ID            ImageId,
-IN OUT    EFI_IMAGE_OUTPUT        **Blt,
-IN        UINTN                   BltX,
-IN        UINTN                   BltY
-);
-
-
-///
-/// Services to access to images in the images database.
-///
-struct _EFI_HII_IMAGE_PROTOCOL {
-  EFI_HII_NEW_IMAGE     NewImage;
-  EFI_HII_GET_IMAGE     GetImage;
-  EFI_HII_SET_IMAGE     SetImage;
-  EFI_HII_DRAW_IMAGE    DrawImage;
-  EFI_HII_DRAW_IMAGE_ID DrawImageId;
-};
-
-extern EFI_GUID gEfiHiiImageProtocolGuid;
-
-#endif
-
-
index ba80fdc..99387e8 100644 (file)
@@ -7,7 +7,7 @@
 
   UEFI 2.0 can boot from any device that produces a LoadFile protocol.
 
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -66,7 +66,7 @@ typedef EFI_LOAD_FILE_PROTOCOL  EFI_LOAD_FILE_INTERFACE;
   @retval EFI_NO_RESPONSE       The remote system did not respond.
   @retval EFI_NOT_FOUND         The file was not found.
   @retval EFI_ABORTED           The file load process was manually cancelled.
-  @retval EFI_WARN_FILE_SYSTEM  The resulting Buffer contains UEFI-compliant file system.
+
 **/
 typedef
 EFI_STATUS
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/SerialIo.h b/roms/ipxe/src/include/ipxe/efi/Protocol/SerialIo.h
deleted file mode 100644 (file)
index 130a6ec..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-/** @file
-  Serial IO protocol as defined in the UEFI 2.0 specification.
-
-  Abstraction of a basic serial device. Targeted at 16550 UART, but
-  could be much more generic.
-
-  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef __SERIAL_IO_PROTOCOL_H__
-#define __SERIAL_IO_PROTOCOL_H__
-
-FILE_LICENCE ( BSD3 );
-
-#define EFI_SERIAL_IO_PROTOCOL_GUID \
-  { \
-    0xBB25CF6F, 0xF1D4, 0x11D2, {0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD } \
-  }
-
-///
-/// Protocol GUID defined in EFI1.1.
-///
-#define SERIAL_IO_PROTOCOL  EFI_SERIAL_IO_PROTOCOL_GUID
-
-typedef struct _EFI_SERIAL_IO_PROTOCOL EFI_SERIAL_IO_PROTOCOL;
-
-
-///
-/// Backward-compatible with EFI1.1.
-///
-typedef EFI_SERIAL_IO_PROTOCOL  SERIAL_IO_INTERFACE;
-
-///
-/// Parity type that is computed or checked as each character is transmitted or received. If the
-/// device does not support parity, the value is the default parity value.
-///
-typedef enum {
-  DefaultParity,
-  NoParity,
-  EvenParity,
-  OddParity,
-  MarkParity,
-  SpaceParity
-} EFI_PARITY_TYPE;
-
-///
-/// Stop bits type
-///
-typedef enum {
-  DefaultStopBits,
-  OneStopBit,
-  OneFiveStopBits,
-  TwoStopBits
-} EFI_STOP_BITS_TYPE;
-
-//
-// define for Control bits, grouped by read only, write only, and read write
-//
-//
-// Read Only
-//
-#define EFI_SERIAL_CLEAR_TO_SEND        0x00000010
-#define EFI_SERIAL_DATA_SET_READY       0x00000020
-#define EFI_SERIAL_RING_INDICATE        0x00000040
-#define EFI_SERIAL_CARRIER_DETECT       0x00000080
-#define EFI_SERIAL_INPUT_BUFFER_EMPTY   0x00000100
-#define EFI_SERIAL_OUTPUT_BUFFER_EMPTY  0x00000200
-
-//
-// Write Only
-//
-#define EFI_SERIAL_REQUEST_TO_SEND      0x00000002
-#define EFI_SERIAL_DATA_TERMINAL_READY  0x00000001
-
-//
-// Read Write
-//
-#define EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE     0x00001000
-#define EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE     0x00002000
-#define EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE 0x00004000
-
-//
-// Serial IO Member Functions
-//
-/**
-  Reset the serial device.
-
-  @param  This              Protocol instance pointer.
-
-  @retval EFI_SUCCESS       The device was reset.
-  @retval EFI_DEVICE_ERROR  The serial device could not be reset.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_SERIAL_RESET)(
-  IN EFI_SERIAL_IO_PROTOCOL *This
-  );
-
-/**
-  Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
-  data bits, and stop bits on a serial device.
-
-  @param  This             Protocol instance pointer.
-  @param  BaudRate         The requested baud rate. A BaudRate value of 0 will use the
-                           device's default interface speed.
-  @param  ReveiveFifoDepth The requested depth of the FIFO on the receive side of the
-                           serial interface. A ReceiveFifoDepth value of 0 will use
-                           the device's default FIFO depth.
-  @param  Timeout          The requested time out for a single character in microseconds.
-                           This timeout applies to both the transmit and receive side of the
-                           interface. A Timeout value of 0 will use the device's default time
-                           out value.
-  @param  Parity           The type of parity to use on this serial device. A Parity value of
-                           DefaultParity will use the device's default parity value.
-  @param  DataBits         The number of data bits to use on the serial device. A DataBits
-                           vaule of 0 will use the device's default data bit setting.
-  @param  StopBits         The number of stop bits to use on this serial device. A StopBits
-                           value of DefaultStopBits will use the device's default number of
-                           stop bits.
-
-  @retval EFI_SUCCESS      The device was reset.
-  @retval EFI_DEVICE_ERROR The serial device could not be reset.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_SERIAL_SET_ATTRIBUTES)(
-  IN EFI_SERIAL_IO_PROTOCOL         *This,
-  IN UINT64                         BaudRate,
-  IN UINT32                         ReceiveFifoDepth,
-  IN UINT32                         Timeout,
-  IN EFI_PARITY_TYPE                Parity,
-  IN UINT8                          DataBits,
-  IN EFI_STOP_BITS_TYPE             StopBits
-  );
-
-/**
-  Set the control bits on a serial device
-
-  @param  This             Protocol instance pointer.
-  @param  Control          Set the bits of Control that are settable.
-
-  @retval EFI_SUCCESS      The new control bits were set on the serial device.
-  @retval EFI_UNSUPPORTED  The serial device does not support this operation.
-  @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_SERIAL_SET_CONTROL_BITS)(
-  IN EFI_SERIAL_IO_PROTOCOL         *This,
-  IN UINT32                         Control
-  );
-
-/**
-  Retrieves the status of thecontrol bits on a serial device
-
-  @param  This              Protocol instance pointer.
-  @param  Control           A pointer to return the current Control signals from the serial device.
-
-  @retval EFI_SUCCESS       The control bits were read from the serial device.
-  @retval EFI_DEVICE_ERROR  The serial device is not functioning correctly.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_SERIAL_GET_CONTROL_BITS)(
-  IN EFI_SERIAL_IO_PROTOCOL         *This,
-  OUT UINT32                        *Control
-  );
-
-/**
-  Writes data to a serial device.
-
-  @param  This              Protocol instance pointer.
-  @param  BufferSize        On input, the size of the Buffer. On output, the amount of
-                            data actually written.
-  @param  Buffer            The buffer of data to write
-
-  @retval EFI_SUCCESS       The data was written.
-  @retval EFI_DEVICE_ERROR  The device reported an error.
-  @retval EFI_TIMEOUT       The data write was stopped due to a timeout.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_SERIAL_WRITE)(
-  IN EFI_SERIAL_IO_PROTOCOL         *This,
-  IN OUT UINTN                      *BufferSize,
-  IN VOID                           *Buffer
-  );
-
-/**
-  Writes data to a serial device.
-
-  @param  This              Protocol instance pointer.
-  @param  BufferSize        On input, the size of the Buffer. On output, the amount of
-                            data returned in Buffer.
-  @param  Buffer            The buffer to return the data into.
-
-  @retval EFI_SUCCESS       The data was read.
-  @retval EFI_DEVICE_ERROR  The device reported an error.
-  @retval EFI_TIMEOUT       The data write was stopped due to a timeout.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_SERIAL_READ)(
-  IN EFI_SERIAL_IO_PROTOCOL         *This,
-  IN OUT UINTN                      *BufferSize,
-  OUT VOID                          *Buffer
-  );
-
-/**
-  @par Data Structure Description:
-  The data values in SERIAL_IO_MODE are read-only and are updated by the code
-  that produces the SERIAL_IO_PROTOCOL member functions.
-
-  @param ControlMask
-  A mask for the Control bits that the device supports. The device
-  must always support the Input Buffer Empty control bit.
-
-  @param TimeOut
-  If applicable, the number of microseconds to wait before timing out
-  a Read or Write operation.
-
-  @param BaudRate
-  If applicable, the current baud rate setting of the device; otherwise,
-  baud rate has the value of zero to indicate that device runs at the
-  device's designed speed.
-
-  @param ReceiveFifoDepth
-  The number of characters the device will buffer on input
-
-  @param DataBits
-  The number of characters the device will buffer on input
-
-  @param Parity
-  If applicable, this is the EFI_PARITY_TYPE that is computed or
-  checked as each character is transmitted or reveived. If the device
-  does not support parity the value is the default parity value.
-
-  @param StopBits
-  If applicable, the EFI_STOP_BITS_TYPE number of stop bits per
-  character. If the device does not support stop bits the value is
-  the default stop bit values.
-
-**/
-typedef struct {
-  UINT32  ControlMask;
-
-  //
-  // current Attributes
-  //
-  UINT32  Timeout;
-  UINT64  BaudRate;
-  UINT32  ReceiveFifoDepth;
-  UINT32  DataBits;
-  UINT32  Parity;
-  UINT32  StopBits;
-} EFI_SERIAL_IO_MODE;
-
-#define EFI_SERIAL_IO_PROTOCOL_REVISION    0x00010000
-#define SERIAL_IO_INTERFACE_REVISION  EFI_SERIAL_IO_PROTOCOL_REVISION
-
-///
-/// The Serial I/O protocol is used to communicate with UART-style serial devices.
-/// These can be standard UART serial ports in PC-AT systems, serial ports attached
-/// to a USB interface, or potentially any character-based I/O device.
-///
-struct _EFI_SERIAL_IO_PROTOCOL {
-  ///
-  /// The revision to which the EFI_SERIAL_IO_PROTOCOL adheres. All future revisions
-  /// must be backwards compatible. If a future version is not backwards compatible,
-  /// it is not the same GUID.
-  ///
-  UINT32                      Revision;
-  EFI_SERIAL_RESET            Reset;
-  EFI_SERIAL_SET_ATTRIBUTES   SetAttributes;
-  EFI_SERIAL_SET_CONTROL_BITS SetControl;
-  EFI_SERIAL_GET_CONTROL_BITS GetControl;
-  EFI_SERIAL_WRITE            Write;
-  EFI_SERIAL_READ             Read;
-  ///
-  /// Pointer to SERIAL_IO_MODE data.
-  ///
-  EFI_SERIAL_IO_MODE          *Mode;
-};
-
-extern EFI_GUID gEfiSerialIoProtocolGuid;
-
-#endif
index 2faa668..2b521a9 100644 (file)
@@ -9,7 +9,7 @@
   MCast - MultiCast
   ...
 
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -123,25 +123,6 @@ typedef struct {
   ///
   UINT64  UnsupportedProtocol;
 
-  ///
-  /// Number of valid frames received that were duplicated.
-  ///
-  UINT64  RxDuplicatedFrames;
-
-  ///
-  /// Number of encrypted frames received that failed to decrypt.
-  ///
-  UINT64  RxDecryptErrorFrames;
-
-  ///
-  /// Number of frames that failed to transmit after exceeding the retry limit.
-  ///
-  UINT64  TxErrorFrames;
-
-  ///
-  /// Number of frames transmitted successfully after more than one attempt.
-  ///
-  UINT64  TxRetryFrames;
 } EFI_NETWORK_STATISTICS;
 
 ///
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/SimplePointer.h b/roms/ipxe/src/include/ipxe/efi/Protocol/SimplePointer.h
deleted file mode 100644 (file)
index 3b1e305..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/** @file
-  Simple Pointer protocol from the UEFI 2.0 specification.
-
-  Abstraction of a very simple pointer device like a mouse or trackball.
-
-  Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef __SIMPLE_POINTER_H__
-#define __SIMPLE_POINTER_H__
-
-FILE_LICENCE ( BSD3 );
-
-#define EFI_SIMPLE_POINTER_PROTOCOL_GUID \
-  { \
-    0x31878c87, 0xb75, 0x11d5, {0x9a, 0x4f, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
-  }
-
-typedef struct _EFI_SIMPLE_POINTER_PROTOCOL  EFI_SIMPLE_POINTER_PROTOCOL;
-
-//
-// Data structures
-//
-typedef struct {
-  ///
-  /// The signed distance in counts that the pointer device has been moved along the x-axis.
-  ///
-  INT32   RelativeMovementX;
-  ///
-  /// The signed distance in counts that the pointer device has been moved along the y-axis.
-  ///
-  INT32   RelativeMovementY;
-  ///
-  /// The signed distance in counts that the pointer device has been moved along the z-axis.
-  ///
-  INT32   RelativeMovementZ;
-  ///
-  /// If TRUE, then the left button of the pointer device is being
-  /// pressed. If FALSE, then the left button of the pointer device is not being pressed.
-  ///
-  BOOLEAN LeftButton;
-  ///
-  /// If TRUE, then the right button of the pointer device is being
-  /// pressed. If FALSE, then the right button of the pointer device is not being pressed.
-  ///
-  BOOLEAN RightButton;
-} EFI_SIMPLE_POINTER_STATE;
-
-typedef struct {
-  ///
-  /// The resolution of the pointer device on the x-axis in counts/mm.
-  /// If 0, then the pointer device does not support an x-axis.
-  ///
-  UINT64  ResolutionX;
-  ///
-  /// The resolution of the pointer device on the y-axis in counts/mm.
-  /// If 0, then the pointer device does not support an x-axis.
-  ///
-  UINT64  ResolutionY;
-  ///
-  /// The resolution of the pointer device on the z-axis in counts/mm.
-  /// If 0, then the pointer device does not support an x-axis.
-  ///
-  UINT64  ResolutionZ;
-  ///
-  /// TRUE if a left button is present on the pointer device. Otherwise FALSE.
-  ///
-  BOOLEAN LeftButton;
-  ///
-  /// TRUE if a right button is present on the pointer device. Otherwise FALSE.
-  ///
-  BOOLEAN RightButton;
-} EFI_SIMPLE_POINTER_MODE;
-
-/**
-  Resets the pointer device hardware.
-
-  @param  This                  A pointer to the EFI_SIMPLE_POINTER_PROTOCOL
-                                instance.
-  @param  ExtendedVerification  Indicates that the driver may perform a more exhaustive
-                                verification operation of the device during reset.
-
-  @retval EFI_SUCCESS           The device was reset.
-  @retval EFI_DEVICE_ERROR      The device is not functioning correctly and could not be reset.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_SIMPLE_POINTER_RESET)(
-  IN EFI_SIMPLE_POINTER_PROTOCOL            *This,
-  IN BOOLEAN                                ExtendedVerification
-  );
-
-/**
-  Retrieves the current state of a pointer device.
-
-  @param  This                  A pointer to the EFI_SIMPLE_POINTER_PROTOCOL
-                                instance.
-  @param  State                 A pointer to the state information on the pointer device.
-
-  @retval EFI_SUCCESS           The state of the pointer device was returned in State.
-  @retval EFI_NOT_READY         The state of the pointer device has not changed since the last call to
-                                GetState().
-  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to retrieve the pointer device's
-                                current state.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_SIMPLE_POINTER_GET_STATE)(
-  IN EFI_SIMPLE_POINTER_PROTOCOL          *This,
-  IN OUT EFI_SIMPLE_POINTER_STATE         *State
-  );
-
-///
-/// The EFI_SIMPLE_POINTER_PROTOCOL provides a set of services for a pointer
-/// device that can use used as an input device from an application written
-/// to this specification. The services include the ability to reset the
-/// pointer device, retrieve get the state of the pointer device, and
-/// retrieve the capabilities of the pointer device.
-///
-struct _EFI_SIMPLE_POINTER_PROTOCOL {
-  EFI_SIMPLE_POINTER_RESET      Reset;
-  EFI_SIMPLE_POINTER_GET_STATE  GetState;
-  ///
-  /// Event to use with WaitForEvent() to wait for input from the pointer device.
-  ///
-  EFI_EVENT                     WaitForInput;
-  ///
-  /// Pointer to EFI_SIMPLE_POINTER_MODE data.
-  ///
-  EFI_SIMPLE_POINTER_MODE       *Mode;
-};
-
-extern EFI_GUID gEfiSimplePointerProtocolGuid;
-
-#endif
index 8aa36c3..a79cf43 100644 (file)
@@ -6,7 +6,7 @@
   a single hardware device or a virtual device that is an aggregation
   of multiple physical devices.
 
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -117,7 +117,7 @@ typedef EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   SIMPLE_TEXT_OUTPUT_INTERFACE;
 #define EFI_BROWN                 (EFI_GREEN | EFI_RED)
 #define EFI_LIGHTGRAY             (EFI_BLUE | EFI_GREEN | EFI_RED)
 #define EFI_BRIGHT                0x08
-#define EFI_DARKGRAY              (EFI_BLACK | EFI_BRIGHT)
+#define EFI_DARKGRAY              (EFI_BRIGHT)
 #define EFI_LIGHTBLUE             (EFI_BLUE | EFI_BRIGHT)
 #define EFI_LIGHTGREEN            (EFI_GREEN | EFI_BRIGHT)
 #define EFI_LIGHTCYAN             (EFI_CYAN | EFI_BRIGHT)
@@ -126,18 +126,7 @@ typedef EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   SIMPLE_TEXT_OUTPUT_INTERFACE;
 #define EFI_YELLOW                (EFI_BROWN | EFI_BRIGHT)
 #define EFI_WHITE                 (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT)
 
-//
-// Macro to accept color values in their raw form to create
-// a value that represents both a foreground and background
-// color in a single byte.
-// For Foreground, and EFI_* value is valid from EFI_BLACK(0x00) to
-// EFI_WHITE (0x0F).
-// For Background, only EFI_BLACK, EFI_BLUE, EFI_GREEN, EFI_CYAN,
-// EFI_RED, EFI_MAGENTA, EFI_BROWN, and EFI_LIGHTGRAY are acceptable
-//
-// Do not use EFI_BACKGROUND_xxx values with this macro.
-//
-#define EFI_TEXT_ATTR(Foreground,Background) ((Foreground) | ((Background) << 4))
+#define EFI_TEXT_ATTR(f, b)       ((f) | ((b) << 4))
 
 #define EFI_BACKGROUND_BLACK      0x00
 #define EFI_BACKGROUND_BLUE       0x10
index 86c69a8..1068448 100644 (file)
@@ -1,8 +1,8 @@
 /** @file
-  TCG Service Protocol as defined in TCG_EFI_Protocol_1_22_Final
+  TCG Service Protocol as defined in TCG_EFI_Protocol_1_20_Final
   See http://trustedcomputinggroup.org for the latest specification
 
-Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -44,6 +44,12 @@ typedef struct _TCG_EFI_BOOT_SERVICE_CAPABILITY {
 
 typedef UINT32   TCG_ALGORITHM_ID;
 
+///
+/// Note:
+///   Status codes returned for functions of EFI_TCG_PROTOCOL do not exactly match
+///   those defined in the TCG EFI Protocol 1.20 Final Specification.
+///
+
 /**
   This service provides EFI protocol capability information, state information
   about the TPM, and Event Log state information.
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/UgaDraw.h b/roms/ipxe/src/include/ipxe/efi/Protocol/UgaDraw.h
deleted file mode 100644 (file)
index 5650206..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/** @file
-  UGA Draw protocol from the EFI 1.10 specification.
-
-  Abstraction of a very simple graphics device.
-
-  Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef __UGA_DRAW_H__
-#define __UGA_DRAW_H__
-
-FILE_LICENCE ( BSD3 );
-
-
-#define EFI_UGA_DRAW_PROTOCOL_GUID \
-  { \
-    0x982c298b, 0xf4fa, 0x41cb, {0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 } \
-  }
-
-typedef struct _EFI_UGA_DRAW_PROTOCOL EFI_UGA_DRAW_PROTOCOL;
-
-/**
-  Return the current video mode information.
-
-  @param  This                  The EFI_UGA_DRAW_PROTOCOL instance.
-  @param  HorizontalResolution  The size of video screen in pixels in the X dimension.
-  @param  VerticalResolution    The size of video screen in pixels in the Y dimension.
-  @param  ColorDepth            Number of bits per pixel, currently defined to be 32.
-  @param  RefreshRate           The refresh rate of the monitor in Hertz.
-
-  @retval EFI_SUCCESS           Mode information returned.
-  @retval EFI_NOT_STARTED       Video display is not initialized. Call SetMode ()
-  @retval EFI_INVALID_PARAMETER One of the input args was NULL.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_UGA_DRAW_PROTOCOL_GET_MODE)(
-  IN  EFI_UGA_DRAW_PROTOCOL *This,
-  OUT UINT32                *HorizontalResolution,
-  OUT UINT32                *VerticalResolution,
-  OUT UINT32                *ColorDepth,
-  OUT UINT32                *RefreshRate
-  );
-
-/**
-  Set the current video mode information.
-
-  @param  This                 The EFI_UGA_DRAW_PROTOCOL instance.
-  @param  HorizontalResolution The size of video screen in pixels in the X dimension.
-  @param  VerticalResolution   The size of video screen in pixels in the Y dimension.
-  @param  ColorDepth           Number of bits per pixel, currently defined to be 32.
-  @param  RefreshRate          The refresh rate of the monitor in Hertz.
-
-  @retval EFI_SUCCESS          Mode information returned.
-  @retval EFI_NOT_STARTED      Video display is not initialized. Call SetMode ()
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_UGA_DRAW_PROTOCOL_SET_MODE)(
-  IN  EFI_UGA_DRAW_PROTOCOL *This,
-  IN  UINT32                HorizontalResolution,
-  IN  UINT32                VerticalResolution,
-  IN  UINT32                ColorDepth,
-  IN  UINT32                RefreshRate
-  );
-
-typedef struct {
-  UINT8 Blue;
-  UINT8 Green;
-  UINT8 Red;
-  UINT8 Reserved;
-} EFI_UGA_PIXEL;
-
-typedef union {
-  EFI_UGA_PIXEL Pixel;
-  UINT32        Raw;
-} EFI_UGA_PIXEL_UNION;
-
-///
-/// Enumration value for actions of Blt operations.
-///
-typedef enum {
-  EfiUgaVideoFill,          ///< Write data from the  BltBuffer pixel (SourceX, SourceY)
-                            ///< directly to every pixel of the video display rectangle
-                            ///< (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
-                            ///< Only one pixel will be used from the BltBuffer. Delta is NOT used.
-
-  EfiUgaVideoToBltBuffer,   ///< Read data from the video display rectangle
-                            ///< (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
-                            ///< the BltBuffer rectangle (DestinationX, DestinationY )
-                            ///< (DestinationX + Width, DestinationY + Height). If DestinationX or
-                            ///< DestinationY is not zero then Delta must be set to the length in bytes
-                            ///< of a row in the BltBuffer.
-
-  EfiUgaBltBufferToVideo,   ///< Write data from the  BltBuffer rectangle
-                            ///< (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
-                            ///< video display rectangle (DestinationX, DestinationY)
-                            ///< (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
-                            ///< not zero then Delta must be set to the length in bytes of a row in the
-                            ///< BltBuffer.
-
-  EfiUgaVideoToVideo,       ///< Copy from the video display rectangle (SourceX, SourceY)
-                            ///< (SourceX + Width, SourceY + Height) .to the video display rectangle
-                            ///< (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
-                            ///< The BltBuffer and Delta  are not used in this mode.
-
-  EfiUgaBltMax              ///< Maxmimum value for enumration value of Blt operation. If a Blt operation
-                            ///< larger or equal to this enumration value, it is invalid.
-} EFI_UGA_BLT_OPERATION;
-
-/**
-    Blt a rectangle of pixels on the graphics screen.
-
-    @param[in] This          - Protocol instance pointer.
-    @param[in] BltBuffer     - Buffer containing data to blit into video buffer. This
-                               buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
-    @param[in] BltOperation  - Operation to perform on BlitBuffer and video memory
-    @param[in] SourceX       - X coordinate of source for the BltBuffer.
-    @param[in] SourceY       - Y coordinate of source for the BltBuffer.
-    @param[in] DestinationX  - X coordinate of destination for the BltBuffer.
-    @param[in] DestinationY  - Y coordinate of destination for the BltBuffer.
-    @param[in] Width         - Width of rectangle in BltBuffer in pixels.
-    @param[in] Height        - Hight of rectangle in BltBuffer in pixels.
-    @param[in] Delta         - OPTIONAL
-
-    @retval EFI_SUCCESS           - The Blt operation completed.
-    @retval EFI_INVALID_PARAMETER - BltOperation is not valid.
-    @retval EFI_DEVICE_ERROR      - A hardware error occured writting to the video buffer.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_UGA_DRAW_PROTOCOL_BLT)(
-  IN  EFI_UGA_DRAW_PROTOCOL                   * This,
-  IN  EFI_UGA_PIXEL                           * BltBuffer, OPTIONAL
-  IN  EFI_UGA_BLT_OPERATION                   BltOperation,
-  IN  UINTN                                   SourceX,
-  IN  UINTN                                   SourceY,
-  IN  UINTN                                   DestinationX,
-  IN  UINTN                                   DestinationY,
-  IN  UINTN                                   Width,
-  IN  UINTN                                   Height,
-  IN  UINTN                                   Delta         OPTIONAL
-  );
-
-///
-/// This protocol provides a basic abstraction to set video modes and
-/// copy pixels to and from the graphics controller's frame buffer.
-///
-struct _EFI_UGA_DRAW_PROTOCOL {
-  EFI_UGA_DRAW_PROTOCOL_GET_MODE  GetMode;
-  EFI_UGA_DRAW_PROTOCOL_SET_MODE  SetMode;
-  EFI_UGA_DRAW_PROTOCOL_BLT       Blt;
-};
-
-extern EFI_GUID gEfiUgaDrawProtocolGuid;
-
-#endif
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/UnicodeCollation.h b/roms/ipxe/src/include/ipxe/efi/Protocol/UnicodeCollation.h
deleted file mode 100644 (file)
index 870428c..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/** @file
-  Unicode Collation protocol that follows the UEFI 2.0 specification.
-  This protocol is used to allow code running in the boot services environment
-  to perform lexical comparison functions on Unicode strings for given languages.
-
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials are licensed and made available under
-the terms and conditions of the BSD License that accompanies this distribution.
-The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php.
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef __UNICODE_COLLATION_H__
-#define __UNICODE_COLLATION_H__
-
-FILE_LICENCE ( BSD3 );
-
-#define EFI_UNICODE_COLLATION_PROTOCOL_GUID \
-  { \
-    0x1d85cd7f, 0xf43d, 0x11d2, {0x9a, 0xc, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
-  }
-
-#define EFI_UNICODE_COLLATION_PROTOCOL2_GUID \
-  { \
-    0xa4c751fc, 0x23ae, 0x4c3e, {0x92, 0xe9, 0x49, 0x64, 0xcf, 0x63, 0xf3, 0x49 } \
-  }
-
-typedef struct _EFI_UNICODE_COLLATION_PROTOCOL  EFI_UNICODE_COLLATION_PROTOCOL;
-
-
-///
-/// Protocol GUID name defined in EFI1.1.
-///
-#define UNICODE_COLLATION_PROTOCOL              EFI_UNICODE_COLLATION_PROTOCOL_GUID
-
-///
-/// Protocol defined in EFI1.1.
-///
-typedef EFI_UNICODE_COLLATION_PROTOCOL          UNICODE_COLLATION_INTERFACE;
-
-///
-/// Protocol data structures and defines
-///
-#define EFI_UNICODE_BYTE_ORDER_MARK (CHAR16) (0xfeff)
-
-//
-// Protocol member functions
-//
-/**
-  Performs a case-insensitive comparison of two Null-terminated strings.
-
-  @param  This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
-  @param  Str1 A pointer to a Null-terminated string.
-  @param  Str2 A pointer to a Null-terminated string.
-
-  @retval 0   Str1 is equivalent to Str2.
-  @retval >0  Str1 is lexically greater than Str2.
-  @retval <0  Str1 is lexically less than Str2.
-
-**/
-typedef
-INTN
-(EFIAPI *EFI_UNICODE_COLLATION_STRICOLL)(
-  IN EFI_UNICODE_COLLATION_PROTOCOL         *This,
-  IN CHAR16                                 *Str1,
-  IN CHAR16                                 *Str2
-  );
-
-/**
-  Performs a case-insensitive comparison of a Null-terminated
-  pattern string and a Null-terminated string.
-
-  @param  This    A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
-  @param  String  A pointer to a Null-terminated string.
-  @param  Pattern A pointer to a Null-terminated pattern string.
-
-  @retval TRUE    Pattern was found in String.
-  @retval FALSE   Pattern was not found in String.
-
-**/
-typedef
-BOOLEAN
-(EFIAPI *EFI_UNICODE_COLLATION_METAIMATCH)(
-  IN EFI_UNICODE_COLLATION_PROTOCOL         *This,
-  IN CHAR16                                 *String,
-  IN CHAR16                                 *Pattern
-  );
-
-/**
-  Converts all the characters in a Null-terminated string to
-  lower case characters.
-
-  @param  This   A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
-  @param  String A pointer to a Null-terminated string.
-
-**/
-typedef
-VOID
-(EFIAPI *EFI_UNICODE_COLLATION_STRLWR)(
-  IN EFI_UNICODE_COLLATION_PROTOCOL         *This,
-  IN OUT CHAR16                             *Str
-  );
-
-/**
-  Converts all the characters in a Null-terminated string to upper
-  case characters.
-
-  @param  This   A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
-  @param  String A pointer to a Null-terminated string.
-
-**/
-typedef
-VOID
-(EFIAPI *EFI_UNICODE_COLLATION_STRUPR)(
-  IN EFI_UNICODE_COLLATION_PROTOCOL         *This,
-  IN OUT CHAR16                             *Str
-  );
-
-/**
-  Converts an 8.3 FAT file name in an OEM character set to a Null-terminated
-  string.
-
-  @param  This    A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
-  @param  FatSize The size of the string Fat in bytes.
-  @param  Fat     A pointer to a Null-terminated string that contains an 8.3 file
-                  name using an 8-bit OEM character set.
-  @param  String  A pointer to a Null-terminated string. The string must
-                  be allocated in advance to hold FatSize characters.
-
-**/
-typedef
-VOID
-(EFIAPI *EFI_UNICODE_COLLATION_FATTOSTR)(
-  IN EFI_UNICODE_COLLATION_PROTOCOL         *This,
-  IN UINTN                                  FatSize,
-  IN CHAR8                                  *Fat,
-  OUT CHAR16                                *String
-  );
-
-/**
-  Converts a Null-terminated string to legal characters in a FAT
-  filename using an OEM character set.
-
-  @param  This    A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
-  @param  String  A pointer to a Null-terminated string.
-  @param  FatSize The size of the string Fat in bytes.
-  @param  Fat     A pointer to a string that contains the converted version of
-                  String using legal FAT characters from an OEM character set.
-
-  @retval TRUE    One or more conversions failed and were substituted with '_'
-  @retval FALSE   None of the conversions failed.
-
-**/
-typedef
-BOOLEAN
-(EFIAPI *EFI_UNICODE_COLLATION_STRTOFAT)(
-  IN EFI_UNICODE_COLLATION_PROTOCOL         *This,
-  IN CHAR16                                 *String,
-  IN UINTN                                  FatSize,
-  OUT CHAR8                                 *Fat
-  );
-
-///
-/// The EFI_UNICODE_COLLATION_PROTOCOL is used to perform case-insensitive
-/// comparisons of strings.
-///
-struct _EFI_UNICODE_COLLATION_PROTOCOL {
-  EFI_UNICODE_COLLATION_STRICOLL    StriColl;
-  EFI_UNICODE_COLLATION_METAIMATCH  MetaiMatch;
-  EFI_UNICODE_COLLATION_STRLWR      StrLwr;
-  EFI_UNICODE_COLLATION_STRUPR      StrUpr;
-
-  //
-  // for supporting fat volumes
-  //
-  EFI_UNICODE_COLLATION_FATTOSTR    FatToStr;
-  EFI_UNICODE_COLLATION_STRTOFAT    StrToFat;
-
-  ///
-  /// A Null-terminated ASCII string array that contains one or more language codes.
-  /// When this field is used for UnicodeCollation2, it is specified in RFC 4646 format.
-  /// When it is used for UnicodeCollation, it is specified in ISO 639-2 format.
-  ///
-  CHAR8                             *SupportedLanguages;
-};
-
-extern EFI_GUID gEfiUnicodeCollationProtocolGuid;
-extern EFI_GUID gEfiUnicodeCollation2ProtocolGuid;
-
-#endif
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/Usb2HostController.h b/roms/ipxe/src/include/ipxe/efi/Protocol/Usb2HostController.h
deleted file mode 100644 (file)
index 8308e8f..0000000
+++ /dev/null
@@ -1,666 +0,0 @@
-/** @file
-  EFI_USB2_HC_PROTOCOL as defined in UEFI 2.0.
-  The USB Host Controller Protocol is used by code, typically USB bus drivers,
-  running in the EFI boot services environment, to perform data transactions over
-  a USB bus. In addition, it provides an abstraction for the root hub of the USB bus.
-
-  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef _USB2_HOSTCONTROLLER_H_
-#define _USB2_HOSTCONTROLLER_H_
-
-FILE_LICENCE ( BSD3 );
-
-#include <ipxe/efi/Protocol/UsbIo.h>
-
-#define EFI_USB2_HC_PROTOCOL_GUID \
-  { \
-    0x3e745226, 0x9818, 0x45b6, {0xa2, 0xac, 0xd7, 0xcd, 0xe, 0x8b, 0xa2, 0xbc } \
-  }
-
-///
-/// Forward reference for pure ANSI compatability
-///
-typedef struct _EFI_USB2_HC_PROTOCOL EFI_USB2_HC_PROTOCOL;
-
-
-typedef struct {
-  UINT16          PortStatus;        ///< Contains current port status bitmap.
-  UINT16          PortChangeStatus;  ///< Contains current port status change bitmap.
-} EFI_USB_PORT_STATUS;
-
-///
-/// EFI_USB_PORT_STATUS.PortStatus bit definition
-///
-#define USB_PORT_STAT_CONNECTION    0x0001
-#define USB_PORT_STAT_ENABLE        0x0002
-#define USB_PORT_STAT_SUSPEND       0x0004
-#define USB_PORT_STAT_OVERCURRENT   0x0008
-#define USB_PORT_STAT_RESET         0x0010
-#define USB_PORT_STAT_POWER         0x0100
-#define USB_PORT_STAT_LOW_SPEED     0x0200
-#define USB_PORT_STAT_HIGH_SPEED    0x0400
-#define USB_PORT_STAT_SUPER_SPEED   0x0800
-#define USB_PORT_STAT_OWNER         0x2000
-
-///
-/// EFI_USB_PORT_STATUS.PortChangeStatus bit definition
-///
-#define USB_PORT_STAT_C_CONNECTION  0x0001
-#define USB_PORT_STAT_C_ENABLE      0x0002
-#define USB_PORT_STAT_C_SUSPEND     0x0004
-#define USB_PORT_STAT_C_OVERCURRENT 0x0008
-#define USB_PORT_STAT_C_RESET       0x0010
-
-
-///
-/// Usb port features value
-/// Each value indicates its bit index in the port status and status change bitmaps,
-/// if combines these two bitmaps into a 32-bit bitmap.
-///
-typedef enum {
-  EfiUsbPortEnable            = 1,
-  EfiUsbPortSuspend           = 2,
-  EfiUsbPortReset             = 4,
-  EfiUsbPortPower             = 8,
-  EfiUsbPortOwner             = 13,
-  EfiUsbPortConnectChange     = 16,
-  EfiUsbPortEnableChange      = 17,
-  EfiUsbPortSuspendChange     = 18,
-  EfiUsbPortOverCurrentChange = 19,
-  EfiUsbPortResetChange       = 20
-} EFI_USB_PORT_FEATURE;
-
-#define EFI_USB_SPEED_FULL      0x0000  ///< 12 Mb/s, USB 1.1 OHCI and UHCI HC.
-#define EFI_USB_SPEED_LOW       0x0001  ///< 1 Mb/s, USB 1.1 OHCI and UHCI HC.
-#define EFI_USB_SPEED_HIGH      0x0002  ///< 480 Mb/s, USB 2.0 EHCI HC.
-#define EFI_USB_SPEED_SUPER     0x0003  ///< 4.8 Gb/s, USB 3.0 XHCI HC.
-
-typedef struct {
-  UINT8      TranslatorHubAddress; ///< device address
-  UINT8      TranslatorPortNumber; ///< the port number of the hub that device is connected to.
-} EFI_USB2_HC_TRANSACTION_TRANSLATOR;
-
-//
-// Protocol definitions
-//
-
-/**
-  Retrieves the Host Controller capabilities.
-
-  @param  This           A pointer to the EFI_USB2_HC_PROTOCOL instance.
-  @param  MaxSpeed       Host controller data transfer speed.
-  @param  PortNumber     Number of the root hub ports.
-  @param  Is64BitCapable TRUE if controller supports 64-bit memory addressing,
-                         FALSE otherwise.
-
-  @retval EFI_SUCCESS           The host controller capabilities were retrieved successfully.
-  @retval EFI_INVALID_PARAMETER One of the input args was NULL.
-  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to
-                                retrieve the capabilities.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB2_HC_PROTOCOL_GET_CAPABILITY)(
-  IN  EFI_USB2_HC_PROTOCOL  *This,
-  OUT UINT8                 *MaxSpeed,
-  OUT UINT8                 *PortNumber,
-  OUT UINT8                 *Is64BitCapable
-  );
-
-#define EFI_USB_HC_RESET_GLOBAL             0x0001
-#define EFI_USB_HC_RESET_HOST_CONTROLLER    0x0002
-#define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG  0x0004
-#define EFI_USB_HC_RESET_HOST_WITH_DEBUG    0x0008
-/**
-  Provides software reset for the USB host controller.
-
-  @param  This       A pointer to the EFI_USB2_HC_PROTOCOL instance.
-  @param  Attributes A bit mask of the reset operation to perform.
-
-  @retval EFI_SUCCESS           The reset operation succeeded.
-  @retval EFI_INVALID_PARAMETER Attributes is not valid.
-  @retval EFI_UNSUPPORTED       The type of reset specified by Attributes is not currently
-                                supported by the host controller hardware.
-  @retval EFI_ACCESS_DENIED     Reset operation is rejected due to the debug port being configured
-                                and active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
-                                EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Attributes can be used to
-                                perform reset operation for this host controller.
-  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to
-                                retrieve the capabilities.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB2_HC_PROTOCOL_RESET)(
-  IN EFI_USB2_HC_PROTOCOL   *This,
-  IN UINT16                 Attributes
-  );
-
-/**
-  Enumration value for status of USB HC.
-**/
-typedef enum {
-  EfiUsbHcStateHalt,                ///< The host controller is in halt
-                                    ///< state. No USB transactions can occur
-                                    ///< while in this state. The host
-                                    ///< controller can enter this state for
-                                    ///< three reasons: 1) After host
-                                    ///< controller hardware reset. 2)
-                                    ///< Explicitly set by software. 3)
-                                    ///< Triggered by a fatal error such as
-                                    ///< consistency check failure.
-
-  EfiUsbHcStateOperational,         ///< The host controller is in an
-                                    ///< operational state. When in
-                                    ///< this state, the host
-                                    ///< controller can execute bus
-                                    ///< traffic. This state must be
-                                    ///< explicitly set to enable the
-                                    ///< USB bus traffic.
-
-  EfiUsbHcStateSuspend,             ///< The host controller is in the
-                                    ///< suspend state. No USB
-                                    ///< transactions can occur while in
-                                    ///< this state. The host controller
-                                    ///< enters this state for the
-                                    ///< following reasons: 1) Explicitly
-                                    ///< set by software. 2) Triggered
-                                    ///< when there is no bus traffic for
-                                    ///< 3 microseconds.
-
-  EfiUsbHcStateMaximum              ///< Maximum value for enumration value of HC status.
-} EFI_USB_HC_STATE;
-
-/**
-  Retrieves current state of the USB host controller.
-
-  @param  This  A pointer to the EFI_USB2_HC_PROTOCOL instance.
-  @param  State A pointer to the EFI_USB_HC_STATE data structure that
-                indicates current state of the USB host controller.
-
-  @retval EFI_SUCCESS           The state information of the host controller was returned in State.
-  @retval EFI_INVALID_PARAMETER State is NULL.
-  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to retrieve the
-                                host controller's current state.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB2_HC_PROTOCOL_GET_STATE)(
-  IN        EFI_USB2_HC_PROTOCOL    *This,
-  OUT       EFI_USB_HC_STATE        *State
-);
-
-/**
-  Sets the USB host controller to a specific state.
-
-  @param  This  A pointer to the EFI_USB2_HC_PROTOCOL instance.
-  @param  State Indicates the state of the host controller that will be set.
-
-  @retval EFI_SUCCESS           The USB host controller was successfully placed in the state
-                                specified by State.
-  @retval EFI_INVALID_PARAMETER State is not valid.
-  @retval EFI_DEVICE_ERROR      Failed to set the state specified by State due to device error.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB2_HC_PROTOCOL_SET_STATE)(
-  IN EFI_USB2_HC_PROTOCOL    *This,
-  IN EFI_USB_HC_STATE        State
-  );
-
-/**
-  Submits control transfer to a target USB device.
-
-  @param  This                A pointer to the EFI_USB2_HC_PROTOCOL instance.
-  @param  DeviceAddress       Represents the address of the target device on the USB.
-  @param  DeviceSpeed         Indicates device speed.
-  @param  MaximumPacketLength Indicates the maximum packet size that the default control transfer
-                              endpoint is capable of sending or receiving.
-  @param  Request             A pointer to the USB device request that will be sent to the USB device.
-  @param  TransferDirection   Specifies the data direction for the transfer. There are three values
-                              available, EfiUsbDataIn, EfiUsbDataOut and EfiUsbNoData.
-  @param  Data                A pointer to the buffer of data that will be transmitted to USB device or
-                              received from USB device.
-  @param  DataLength          On input, indicates the size, in bytes, of the data buffer specified by Data.
-                              On output, indicates the amount of data actually transferred.
-  @param  TimeOut             Indicates the maximum time, in milliseconds, which the transfer is
-                              allowed to complete.
-  @param  Translator          A pointer to the transaction translator data.
-  @param  TransferResult      A pointer to the detailed result information generated by this control
-                              transfer.
-
-  @retval EFI_SUCCESS           The control transfer was completed successfully.
-  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
-  @retval EFI_OUT_OF_RESOURCES  The control transfer could not be completed due to a lack of resources.
-  @retval EFI_TIMEOUT           The control transfer failed due to timeout.
-  @retval EFI_DEVICE_ERROR      The control transfer failed due to host controller or device error.
-                                Caller should check TransferResult for detailed error information.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB2_HC_PROTOCOL_CONTROL_TRANSFER)(
-  IN     EFI_USB2_HC_PROTOCOL               *This,
-  IN     UINT8                              DeviceAddress,
-  IN     UINT8                              DeviceSpeed,
-  IN     UINTN                              MaximumPacketLength,
-  IN     EFI_USB_DEVICE_REQUEST             *Request,
-  IN     EFI_USB_DATA_DIRECTION             TransferDirection,
-  IN OUT VOID                               *Data       OPTIONAL,
-  IN OUT UINTN                              *DataLength OPTIONAL,
-  IN     UINTN                              TimeOut,
-  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
-  OUT    UINT32                             *TransferResult
-  );
-
-#define EFI_USB_MAX_BULK_BUFFER_NUM 10
-
-/**
-  Submits bulk transfer to a bulk endpoint of a USB device.
-
-  @param  This                A pointer to the EFI_USB2_HC_PROTOCOL instance.
-  @param  DeviceAddress       Represents the address of the target device on the USB.
-  @param  EndPointAddress     The combination of an endpoint number and an endpoint direction of the
-                              target USB device.
-  @param  DeviceSpeed         Indicates device speed.
-  @param  MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of
-                              sending or receiving.
-  @param  DataBuffersNumber   Number of data buffers prepared for the transfer.
-  @param  Data                Array of pointers to the buffers of data that will be transmitted to USB
-                              device or received from USB device.
-  @param  DataLength          When input, indicates the size, in bytes, of the data buffers specified by
-                              Data. When output, indicates the actually transferred data size.
-  @param  DataToggle          A pointer to the data toggle value.
-  @param  TimeOut             Indicates the maximum time, in milliseconds, which the transfer is
-                              allowed to complete.
-  @param  Translator          A pointer to the transaction translator data.
-  @param  TransferResult      A pointer to the detailed result information of the bulk transfer.
-
-  @retval EFI_SUCCESS           The bulk transfer was completed successfully.
-  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
-  @retval EFI_OUT_OF_RESOURCES  The bulk transfer could not be submitted due to a lack of resources.
-  @retval EFI_TIMEOUT           The bulk transfer failed due to timeout.
-  @retval EFI_DEVICE_ERROR      The bulk transfer failed due to host controller or device error.
-                                Caller should check TransferResult for detailed error information.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB2_HC_PROTOCOL_BULK_TRANSFER)(
-  IN     EFI_USB2_HC_PROTOCOL               *This,
-  IN     UINT8                              DeviceAddress,
-  IN     UINT8                              EndPointAddress,
-  IN     UINT8                              DeviceSpeed,
-  IN     UINTN                              MaximumPacketLength,
-  IN     UINT8                              DataBuffersNumber,
-  IN OUT VOID                               *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
-  IN OUT UINTN                              *DataLength,
-  IN OUT UINT8                              *DataToggle,
-  IN     UINTN                              TimeOut,
-  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
-  OUT    UINT32                             *TransferResult
-  );
-
-/**
-  Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device.
-  Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated in the following specification version.
-
-  @param  This                A pointer to the EFI_USB2_HC_PROTOCOL instance.
-  @param  DeviceAddress       Represents the address of the target device on the USB.
-  @param  EndPointAddress     The combination of an endpoint number and an endpoint direction of the
-                              target USB device.
-  @param  DeviceSpeed         Indicates device speed.
-  @param  MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of
-                              sending or receiving.
-  @param  IsNewTransfer       If TRUE, an asynchronous interrupt pipe is built between the host and the
-                              target interrupt endpoint. If FALSE, the specified asynchronous interrupt
-                              pipe is canceled. If TRUE, and an interrupt transfer exists for the target
-                              end point, then EFI_INVALID_PARAMETER is returned.
-  @param  DataToggle          A pointer to the data toggle value.
-  @param  PollingInterval     Indicates the interval, in milliseconds, that the asynchronous interrupt
-                              transfer is polled.
-  @param  DataLength          Indicates the length of data to be received at the rate specified by
-                              PollingInterval from the target asynchronous interrupt endpoint.
-  @param  Translator          A pointr to the transaction translator data.
-  @param  CallBackFunction    The Callback function. This function is called at the rate specified by
-                              PollingInterval.
-  @param  Context             The context that is passed to the CallBackFunction. This is an
-                              optional parameter and may be NULL.
-
-  @retval EFI_SUCCESS           The asynchronous interrupt transfer request has been successfully
-                                submitted or canceled.
-  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
-  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB2_HC_PROTOCOL_ASYNC_INTERRUPT_TRANSFER)(
-  IN     EFI_USB2_HC_PROTOCOL                                *This,
-  IN     UINT8                                               DeviceAddress,
-  IN     UINT8                                               EndPointAddress,
-  IN     UINT8                                               DeviceSpeed,
-  IN     UINTN                                               MaxiumPacketLength,
-  IN     BOOLEAN                                             IsNewTransfer,
-  IN OUT UINT8                                               *DataToggle,
-  IN     UINTN                                               PollingInterval  OPTIONAL,
-  IN     UINTN                                               DataLength       OPTIONAL,
-  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR                  *Translator      OPTIONAL,
-  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK                     CallBackFunction OPTIONAL,
-  IN     VOID                                                *Context         OPTIONAL
-  );
-
-/**
-  Submits synchronous interrupt transfer to an interrupt endpoint of a USB device.
-  Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated in the following specification version.
-
-  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.
-  @param  DeviceAddress         Represents the address of the target device on the USB.
-  @param  EndPointAddress       The combination of an endpoint number and an endpoint direction of the
-                                target USB device.
-  @param  DeviceSpeed           Indicates device speed.
-  @param  MaximumPacketLength   Indicates the maximum packet size the target endpoint is capable of
-                                sending or receiving.
-  @param  Data                  A pointer to the buffer of data that will be transmitted to USB device or
-                                received from USB device.
-  @param  DataLength            On input, the size, in bytes, of the data buffer specified by Data. On
-                                output, the number of bytes transferred.
-  @param  DataToggle            A pointer to the data toggle value.
-  @param  TimeOut               Indicates the maximum time, in milliseconds, which the transfer is
-                                allowed to complete.
-  @param  Translator            A pointr to the transaction translator data.
-  @param  TransferResult        A pointer to the detailed result information from the synchronous
-                                interrupt transfer.
-
-  @retval EFI_SUCCESS           The synchronous interrupt transfer was completed successfully.
-  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
-  @retval EFI_OUT_OF_RESOURCES  The synchronous interrupt transfer could not be submitted due to a lack of resources.
-  @retval EFI_TIMEOUT           The synchronous interrupt transfer failed due to timeout.
-  @retval EFI_DEVICE_ERROR      The synchronous interrupt transfer failed due to host controller or device error.
-                                Caller should check TransferResult for detailed error information.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB2_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER)(
-  IN     EFI_USB2_HC_PROTOCOL                        *This,
-  IN     UINT8                                       DeviceAddress,
-  IN     UINT8                                       EndPointAddress,
-  IN     UINT8                                       DeviceSpeed,
-  IN     UINTN                                       MaximumPacketLength,
-  IN OUT VOID                                        *Data,
-  IN OUT UINTN                                       *DataLength,
-  IN OUT UINT8                                       *DataToggle,
-  IN     UINTN                                       TimeOut,
-  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR          *Translator,
-  OUT    UINT32                                      *TransferResult
-  );
-
-#define EFI_USB_MAX_ISO_BUFFER_NUM  7
-#define EFI_USB_MAX_ISO_BUFFER_NUM1 2
-
-/**
-  Submits isochronous transfer to an isochronous endpoint of a USB device.
-
-  This function is used to submit isochronous transfer to a target endpoint of a USB device.
-  The target endpoint is specified by DeviceAddressand EndpointAddress. Isochronous transfers are
-  used when working with isochronous date. It provides periodic, continuous communication between
-  the host and a device. Isochronous transfers can beused only by full-speed, high-speed, and
-  super-speed devices.
-
-  High-speed isochronous transfers can be performed using multiple data buffers. The number of
-  buffers that are actually prepared for the transfer is specified by DataBuffersNumber. For
-  full-speed isochronous transfers this value is ignored.
-
-  Data represents a list of pointers to the data buffers. For full-speed isochronous transfers
-  only the data pointed by Data[0]shall be used. For high-speed isochronous transfers and for
-  the split transactions depending on DataLengththere several data buffers canbe used. For the
-  high-speed isochronous transfers the total number of buffers must not exceed EFI_USB_MAX_ISO_BUFFER_NUM.
-
-  For split transactions performed on full-speed device by high-speed host controller the total
-  number of buffers is limited to EFI_USB_MAX_ISO_BUFFER_NUM1.
-  If the isochronous transfer is successful, then EFI_SUCCESSis returned. The isochronous transfer
-  is designed to be completed within one USB frame time, if it cannot be completed, EFI_TIMEOUT
-  is returned. If an error other than timeout occurs during the USB transfer, then EFI_DEVICE_ERROR
-  is returned and the detailed status code will be returned in TransferResult.
-
-  EFI_INVALID_PARAMETERis returned if one of the following conditionsis satisfied:
-    - Data is NULL.
-    - DataLength is 0.
-    - DeviceSpeed is not one of the supported values listed above.
-    - MaximumPacketLength is invalid. MaximumPacketLength must be 1023 or less for full-speed devices,
-      and 1024 or less for high-speed and super-speed devices.
-    - TransferResult is NULL.
-
-  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.
-  @param  DeviceAddress         Represents the address of the target device on the USB.
-  @param  EndPointAddress       The combination of an endpoint number and an endpoint direction of the
-                                target USB device.
-  @param  DeviceSpeed           Indicates device speed. The supported values are EFI_USB_SPEED_FULL,
-                                EFI_USB_SPEED_HIGH, or EFI_USB_SPEED_SUPER.
-  @param  MaximumPacketLength   Indicates the maximum packet size the target endpoint is capable of
-                                sending or receiving.
-  @param  DataBuffersNumber     Number of data buffers prepared for the transfer.
-  @param  Data                  Array of pointers to the buffers of data that will be transmitted to USB
-                                device or received from USB device.
-  @param  DataLength            Specifies the length, in bytes, of the data to be sent to or received from
-                                the USB device.
-  @param  Translator            A pointer to the transaction translator data.
-  @param  TransferResult        A pointer to the detailed result information of the isochronous transfer.
-
-  @retval EFI_SUCCESS           The isochronous transfer was completed successfully.
-  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
-  @retval EFI_OUT_OF_RESOURCES  The isochronous transfer could not be submitted due to a lack of resources.
-  @retval EFI_TIMEOUT           The isochronous transfer cannot be completed within the one USB frame time.
-  @retval EFI_DEVICE_ERROR      The isochronous transfer failed due to host controller or device error.
-                                Caller should check TransferResult for detailed error information.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB2_HC_PROTOCOL_ISOCHRONOUS_TRANSFER)(
-  IN     EFI_USB2_HC_PROTOCOL               *This,
-  IN     UINT8                              DeviceAddress,
-  IN     UINT8                              EndPointAddress,
-  IN     UINT8                              DeviceSpeed,
-  IN     UINTN                              MaximumPacketLength,
-  IN     UINT8                              DataBuffersNumber,
-  IN OUT VOID                               *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
-  IN     UINTN                              DataLength,
-  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
-  OUT    UINT32                             *TransferResult
-  );
-
-/**
-  Submits nonblocking isochronous transfer to an isochronous endpoint of a USB device.
-
-  This is an asynchronous type of USB isochronous transfer. If the caller submits a USB
-  isochronous transfer request through this function, this function will return immediately.
-
-  When the isochronous transfer completes, the IsochronousCallbackfunction will be triggered,
-  the caller can know the transfer results. If the transfer is successful, the caller can get
-  the data received or sent in this callback function.
-
-  The target endpoint is specified by DeviceAddressand EndpointAddress. Isochronous transfers
-  are used when working with isochronous date. It provides periodic, continuous communication
-  between the host and a device. Isochronous transfers can be used only by full-speed, high-speed,
-  and super-speed devices.
-
-  High-speed isochronous transfers can be performed using multiple data buffers. The number of
-  buffers that are actually prepared for the transfer is specified by DataBuffersNumber. For
-  full-speed isochronous transfers this value is ignored.
-
-  Data represents a list of pointers to the data buffers. For full-speed isochronous transfers
-  only the data pointed by Data[0] shall be used. For high-speed isochronous transfers and for
-  the split transactions depending on DataLength there several data buffers can be used. For
-  the high-speed isochronous transfers the total number of buffers must not exceed EFI_USB_MAX_ISO_BUFFER_NUM.
-
-  For split transactions performed on full-speed device by high-speed host controller the total
-  number of buffers is limited to EFI_USB_MAX_ISO_BUFFER_NUM1.
-
-  EFI_INVALID_PARAMETER is returned if one of the following conditionsis satisfied:
-    - Data is NULL.
-    - DataLength is 0.
-    - DeviceSpeed is not one of the supported values listed above.
-    - MaximumPacketLength is invalid. MaximumPacketLength must be 1023 or less for full-speed
-      devices and 1024 or less for high-speed and super-speed devices.
-
-  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.
-  @param  DeviceAddress         Represents the address of the target device on the USB.
-  @param  EndPointAddress       The combination of an endpoint number and an endpoint direction of the
-                                target USB device.
-  @param  DeviceSpeed           Indicates device speed. The supported values are EFI_USB_SPEED_FULL,
-                                EFI_USB_SPEED_HIGH, or EFI_USB_SPEED_SUPER.
-  @param  MaximumPacketLength   Indicates the maximum packet size the target endpoint is capable of
-                                sending or receiving.
-  @param  DataBuffersNumber     Number of data buffers prepared for the transfer.
-  @param  Data                  Array of pointers to the buffers of data that will be transmitted to USB
-                                device or received from USB device.
-  @param  DataLength            Specifies the length, in bytes, of the data to be sent to or received from
-                                the USB device.
-  @param  Translator            A pointer to the transaction translator data.
-  @param  IsochronousCallback   The Callback function. This function is called if the requested
-                                isochronous transfer is completed.
-  @param  Context               Data passed to the IsochronousCallback function. This is an
-                                optional parameter and may be NULL.
-
-  @retval EFI_SUCCESS           The asynchronous isochronous transfer request has been successfully
-                                submitted or canceled.
-  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
-  @retval EFI_OUT_OF_RESOURCES  The asynchronous isochronous transfer could not be submitted due to
-                                a lack of resources.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB2_HC_PROTOCOL_ASYNC_ISOCHRONOUS_TRANSFER)(
-  IN     EFI_USB2_HC_PROTOCOL               *This,
-  IN     UINT8                              DeviceAddress,
-  IN     UINT8                              EndPointAddress,
-  IN     UINT8                              DeviceSpeed,
-  IN     UINTN                              MaximumPacketLength,
-  IN     UINT8                              DataBuffersNumber,
-  IN OUT VOID                               *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
-  IN     UINTN                              DataLength,
-  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
-  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK    IsochronousCallBack,
-  IN     VOID                               *Context OPTIONAL
-  );
-
-/**
-  Retrieves the current status of a USB root hub port.
-
-  @param  This       A pointer to the EFI_USB2_HC_PROTOCOL instance.
-  @param  PortNumber Specifies the root hub port from which the status is to be retrieved.
-                     This value is zero based.
-  @param  PortStatus A pointer to the current port status bits and port status change bits.
-
-  @retval EFI_SUCCESS           The status of the USB root hub port specified by PortNumber
-                                was returned in PortStatus.
-  @retval EFI_INVALID_PARAMETER PortNumber is invalid.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB2_HC_PROTOCOL_GET_ROOTHUB_PORT_STATUS)(
-  IN        EFI_USB2_HC_PROTOCOL    *This,
-  IN        UINT8                   PortNumber,
-  OUT       EFI_USB_PORT_STATUS     *PortStatus
-  );
-
-/**
-  Sets a feature for the specified root hub port.
-
-  @param  This        A pointer to the EFI_USB2_HC_PROTOCOL instance.
-  @param  PortNumber  Specifies the root hub port whose feature is requested to be set. This
-                      value is zero based.
-  @param  PortFeature Indicates the feature selector associated with the feature set request.
-
-  @retval EFI_SUCCESS           The feature specified by PortFeature was set for the USB
-                                root hub port specified by PortNumber.
-  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB2_HC_PROTOCOL_SET_ROOTHUB_PORT_FEATURE)(
-  IN EFI_USB2_HC_PROTOCOL    *This,
-  IN UINT8                   PortNumber,
-  IN EFI_USB_PORT_FEATURE    PortFeature
-  );
-
-/**
-  Clears a feature for the specified root hub port.
-
-  @param  This        A pointer to the EFI_USB2_HC_PROTOCOL instance.
-  @param  PortNumber  Specifies the root hub port whose feature is requested to be cleared. This
-                      value is zero based.
-  @param  PortFeature Indicates the feature selector associated with the feature clear request.
-
-  @retval EFI_SUCCESS           The feature specified by PortFeature was cleared for the USB
-                                root hub port specified by PortNumber.
-  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB2_HC_PROTOCOL_CLEAR_ROOTHUB_PORT_FEATURE)(
-  IN EFI_USB2_HC_PROTOCOL    *This,
-  IN UINT8                   PortNumber,
-  IN EFI_USB_PORT_FEATURE    PortFeature
-  );
-
-///
-/// The EFI_USB2_HC_PROTOCOL provides USB host controller management, basic
-/// data transactions over a USB bus, and USB root hub access. A device driver
-/// that wishes to manage a USB bus in a system retrieves the EFI_USB2_HC_PROTOCOL
-/// instance that is associated with the USB bus to be managed. A device handle
-/// for a USB host controller will minimally contain an EFI_DEVICE_PATH_PROTOCOL
-/// instance, and an EFI_USB2_HC_PROTOCOL instance.
-///
-struct _EFI_USB2_HC_PROTOCOL {
-  EFI_USB2_HC_PROTOCOL_GET_CAPABILITY              GetCapability;
-  EFI_USB2_HC_PROTOCOL_RESET                       Reset;
-  EFI_USB2_HC_PROTOCOL_GET_STATE                   GetState;
-  EFI_USB2_HC_PROTOCOL_SET_STATE                   SetState;
-  EFI_USB2_HC_PROTOCOL_CONTROL_TRANSFER            ControlTransfer;
-  EFI_USB2_HC_PROTOCOL_BULK_TRANSFER               BulkTransfer;
-  EFI_USB2_HC_PROTOCOL_ASYNC_INTERRUPT_TRANSFER    AsyncInterruptTransfer;
-  EFI_USB2_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER     SyncInterruptTransfer;
-  EFI_USB2_HC_PROTOCOL_ISOCHRONOUS_TRANSFER        IsochronousTransfer;
-  EFI_USB2_HC_PROTOCOL_ASYNC_ISOCHRONOUS_TRANSFER  AsyncIsochronousTransfer;
-  EFI_USB2_HC_PROTOCOL_GET_ROOTHUB_PORT_STATUS     GetRootHubPortStatus;
-  EFI_USB2_HC_PROTOCOL_SET_ROOTHUB_PORT_FEATURE    SetRootHubPortFeature;
-  EFI_USB2_HC_PROTOCOL_CLEAR_ROOTHUB_PORT_FEATURE  ClearRootHubPortFeature;
-
-  ///
-  /// The major revision number of the USB host controller. The revision information
-  /// indicates the release of the Universal Serial Bus Specification with which the
-  /// host controller is compliant.
-  ///
-  UINT16                                           MajorRevision;
-
-  ///
-  /// The minor revision number of the USB host controller. The revision information
-  /// indicates the release of the Universal Serial Bus Specification with which the
-  /// host controller is compliant.
-  ///
-  UINT16                                           MinorRevision;
-};
-
-extern EFI_GUID gEfiUsb2HcProtocolGuid;
-
-#endif
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/UsbHostController.h b/roms/ipxe/src/include/ipxe/efi/Protocol/UsbHostController.h
deleted file mode 100644 (file)
index a29088c..0000000
+++ /dev/null
@@ -1,510 +0,0 @@
-/** @file
-  EFI_USB_HC_PROTOCOL as defined in EFI 1.10.
-
-  The USB Host Controller Protocol is used by code, typically USB bus drivers,
-  running in the EFI boot services environment, to perform data transactions
-  over a USB bus. In addition, it provides an abstraction for the root hub of the USB bus.
-
-  Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef _USB_HOSTCONTROLLER_H_
-#define _USB_HOSTCONTROLLER_H_
-
-FILE_LICENCE ( BSD3 );
-
-#include <ipxe/efi/Protocol/Usb2HostController.h>
-
-#define EFI_USB_HC_PROTOCOL_GUID \
-  { \
-    0xf5089266, 0x1aa0, 0x4953, {0x97, 0xd8, 0x56, 0x2f, 0x8a, 0x73, 0xb5, 0x19 } \
-  }
-
-///
-/// Forward reference for pure ANSI compatability
-///
-typedef struct _EFI_USB_HC_PROTOCOL EFI_USB_HC_PROTOCOL;
-
-//
-// Protocol definitions
-//
-
-/**
-  Provides software reset for the USB host controller.
-
-  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
-  @param  Attributes            A bit mask of the reset operation to perform.
-
-  @retval EFI_SUCCESS           The reset operation succeeded.
-  @retval EFI_UNSUPPORTED       The type of reset specified by Attributes is not currently supported
-                                by the host controller hardware.
-  @retval EFI_INVALID_PARAMETER Attributes is not valid.
-  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to perform the reset operation.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_HC_PROTOCOL_RESET)(
-  IN EFI_USB_HC_PROTOCOL     *This,
-  IN UINT16                  Attributes
-  );
-
-/**
-  Retrieves current state of the USB host controller.
-
-  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
-  @param  State                 A pointer to the EFI_USB_HC_STATE data structure that
-                                indicates current state of the USB host controller.
-
-  @retval EFI_SUCCESS           The state information of the host controller was returned in State.
-  @retval EFI_INVALID_PARAMETER State is NULL.
-  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to retrieve the host controller's
-                                current state.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_HC_PROTOCOL_GET_STATE)(
-  IN  EFI_USB_HC_PROTOCOL    *This,
-  OUT EFI_USB_HC_STATE       *State
-  );
-
-/**
-  Sets the USB host controller to a specific state.
-
-  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
-  @param  State                 Indicates the state of the host controller that will be set.
-
-  @retval EFI_SUCCESS           The USB host controller was successfully placed in the state specified by
-                                State.
-  @retval EFI_INVALID_PARAMETER State is NULL.
-  @retval EFI_DEVICE_ERROR      Failed to set the state specified by State due to device error.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_HC_PROTOCOL_SET_STATE)(
-  IN EFI_USB_HC_PROTOCOL     *This,
-  IN EFI_USB_HC_STATE        State
-  );
-
-/**
-  Submits control transfer to a target USB device.
-
-  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
-  @param  DeviceAddress         Represents the address of the target device on the USB, which is
-                                assigned during USB enumeration.
-  @param  IsSlowDevice          Indicates whether the target device is slow device or full-speed
-                                device.
-  @param  MaximumPacketLength   Indicates the maximum packet size that the default control
-                                transfer endpoint is capable of sending or receiving.
-  @param  Request               A pointer to the USB device request that will be sent to the USB
-                                device.
-  @param  TransferDirection     Specifies the data direction for the transfer. There are three
-                                values available, EfiUsbDataIn, EfiUsbDataOut and EfiUsbNoData.
-  @param  Data                  A pointer to the buffer of data that will be transmitted to USB
-                                device or received from USB device.
-  @param  DataLength            On input, indicates the size, in bytes, of the data buffer specified
-                                by Data. On output, indicates the amount of data actually
-                                transferred.
-  @param  TimeOut               Indicates the maximum time, in milliseconds, which the transfer
-                                is allowed to complete.
-  @param  TransferResult        A pointer to the detailed result information generated by this
-                                control transfer.
-
-  @retval EFI_SUCCESS           The control transfer was completed successfully.
-  @retval EFI_OUT_OF_RESOURCES  The control transfer could not be completed due to a lack of resources.
-  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
-  @retval EFI_TIMEOUT           The control transfer failed due to timeout.
-  @retval EFI_DEVICE_ERROR      The control transfer failed due to host controller or device error.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_HC_PROTOCOL_CONTROL_TRANSFER)(
-  IN     EFI_USB_HC_PROTOCOL       *This,
-  IN     UINT8                     DeviceAddress,
-  IN     BOOLEAN                   IsSlowDevice,
-  IN     UINT8                     MaximumPacketLength,
-  IN     EFI_USB_DEVICE_REQUEST    *Request,
-  IN     EFI_USB_DATA_DIRECTION    TransferDirection,
-  IN OUT VOID                      *Data       OPTIONAL,
-  IN OUT UINTN                     *DataLength OPTIONAL,
-  IN     UINTN                     TimeOut,
-  OUT    UINT32                    *TransferResult
-  );
-
-/**
-  Submits bulk transfer to a bulk endpoint of a USB device.
-
-  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
-  @param  DeviceAddress         Represents the address of the target device on the USB, which is
-                                assigned during USB enumeration.
-  @param  EndPointAddress       The combination of an endpoint number and an endpoint
-                                direction of the target USB device. Each endpoint address
-                                supports data transfer in one direction except the control
-                                endpoint (whose default endpoint address is 0). It is the
-                                caller's responsibility to make sure that the EndPointAddress
-                                represents a bulk endpoint.
-  @param  MaximumPacketLength   Indicates the maximum packet size that the default control
-                                transfer endpoint is capable of sending or receiving.
-  @param  Data                  A pointer to the buffer of data that will be transmitted to USB
-                                device or received from USB device.
-  @param  DataLength            On input, indicates the size, in bytes, of the data buffer specified
-                                by Data. On output, indicates the amount of data actually
-                                transferred.
-  @param  DataToggle            A pointer to the data toggle value.
-  @param  TimeOut               Indicates the maximum time, in milliseconds, which the transfer
-                                is allowed to complete.
-  @param  TransferResult        A pointer to the detailed result information of the bulk transfer.
-
-  @retval EFI_SUCCESS           The bulk transfer was completed successfully.
-  @retval EFI_OUT_OF_RESOURCES  The bulk transfer could not be completed due to a lack of resources.
-  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
-  @retval EFI_TIMEOUT           The bulk transfer failed due to timeout.
-  @retval EFI_DEVICE_ERROR      The bulk transfer failed due to host controller or device error.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_HC_PROTOCOL_BULK_TRANSFER)(
-  IN     EFI_USB_HC_PROTOCOL    *This,
-  IN     UINT8                  DeviceAddress,
-  IN     UINT8                  EndPointAddress,
-  IN     UINT8                  MaximumPacketLength,
-  IN OUT VOID                   *Data,
-  IN OUT UINTN                  *DataLength,
-  IN OUT UINT8                  *DataToggle,
-  IN     UINTN                  TimeOut,
-  OUT    UINT32                 *TransferResult
-  );
-
-/**
-  Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device.
-
-  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
-  @param  DeviceAddress         Represents the address of the target device on the USB, which is
-                                assigned during USB enumeration.
-  @param  EndPointAddress       The combination of an endpoint number and an endpoint
-                                direction of the target USB device. Each endpoint address
-                                supports data transfer in one direction except the control
-                                endpoint (whose default endpoint address is zero). It is the
-                                caller's responsibility to make sure that the
-                                EndPointAddress represents an interrupt endpoint.
-  @param  IsSlowDevice          Indicates whether the target device is slow device or full-speed
-                                device.
-  @param  MaximumPacketLength   Indicates the maximum packet size that the default control
-                                transfer endpoint is capable of sending or receiving.
-  @param  IsNewTransfer         If TRUE, an asynchronous interrupt pipe is built between the host
-                                and the target interrupt endpoint. If FALSE, the specified asynchronous
-                                interrupt pipe is canceled. If TRUE, and an interrupt transfer exists
-                                for the target end point, then EFI_INVALID_PARAMETER is returned.
-  @param  DataToggle            A pointer to the data toggle value. On input, it is valid when
-                                IsNewTransfer is TRUE, and it indicates the initial data toggle
-                                value the asynchronous interrupt transfer should adopt. On output,
-                                it is valid when IsNewTransfer is FALSE, and it is updated to indicate
-                                the data toggle value of the subsequent asynchronous interrupt transfer.
-  @param  PollingInterval       Indicates the interval, in milliseconds, that the asynchronous
-                                interrupt transfer is polled.
-  @param  DataLength            Indicates the length of data to be received at the rate specified by
-                                PollingInterval from the target asynchronous interrupt
-                                endpoint. This parameter is only required when IsNewTransfer is TRUE.
-  @param  CallBackFunction      The Callback function. This function is called at the rate specified by
-                                PollingInterval. This parameter is only required when IsNewTransfer is TRUE.
-  @param  Context               The context that is passed to the CallBackFunction.
-
-  @retval EFI_SUCCESS           The asynchronous interrupt transfer request has been successfully
-                                submitted or canceled.
-  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
-  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
-  @retval EFI_TIMEOUT           The bulk transfer failed due to timeout.
-  @retval EFI_DEVICE_ERROR      The bulk transfer failed due to host controller or device error.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_HC_PROTOCOL_ASYNC_INTERRUPT_TRANSFER)(
-  IN     EFI_USB_HC_PROTOCOL                                 *This,
-  IN     UINT8                                               DeviceAddress,
-  IN     UINT8                                               EndPointAddress,
-  IN     BOOLEAN                                             IsSlowDevice,
-  IN     UINT8                                               MaxiumPacketLength,
-  IN     BOOLEAN                                             IsNewTransfer,
-  IN OUT UINT8                                               *DataToggle,
-  IN     UINTN                                               PollingInterval  OPTIONAL,
-  IN     UINTN                                               DataLength       OPTIONAL,
-  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK                     CallBackFunction OPTIONAL,
-  IN     VOID                                                *Context         OPTIONAL
-  );
-
-/**
-  Submits synchronous interrupt transfer to an interrupt endpoint of a USB device.
-
-  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
-  @param  DeviceAddress         Represents the address of the target device on the USB, which is
-                                assigned during USB enumeration.
-  @param  EndPointAddress       The combination of an endpoint number and an endpoint
-                                direction of the target USB device. Each endpoint address
-                                supports data transfer in one direction except the control
-                                endpoint (whose default endpoint address is zero). It is the
-                                caller's responsibility to make sure that the
-                                EndPointAddress represents an interrupt endpoint.
-  @param  IsSlowDevice          Indicates whether the target device is slow device or full-speed
-                                device.
-  @param  MaximumPacketLength   Indicates the maximum packet size that the default control
-                                transfer endpoint is capable of sending or receiving.
-  @param  Data                  A pointer to the buffer of data that will be transmitted to USB
-                                device or received from USB device.                                                                                            asynchronous interrupt pipe is canceled.
-  @param  DataLength            On input, the size, in bytes, of the data buffer specified by Data.
-                                On output, the number of bytes transferred.
-  @param  DataToggle            A pointer to the data toggle value. On input, it indicates the initial
-                                data toggle value the synchronous interrupt transfer should adopt;
-                                on output, it is updated to indicate the data toggle value of the
-                                subsequent synchronous interrupt transfer.
-  @param  TimeOut               Indicates the maximum time, in milliseconds, which the transfer
-                                is allowed to complete.
-  @param  TransferResult        A pointer to the detailed result information from the synchronous
-                                interrupt transfer.
-
-  @retval EFI_SUCCESS           The synchronous interrupt transfer was completed successfully.
-  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
-  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
-  @retval EFI_TIMEOUT           The synchronous interrupt transfer failed due to timeout.
-  @retval EFI_DEVICE_ERROR      The synchronous interrupt transfer failed due to host controller or device error.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER)(
-  IN     EFI_USB_HC_PROTOCOL    *This,
-  IN     UINT8                  DeviceAddress,
-  IN     UINT8                  EndPointAddress,
-  IN     BOOLEAN                IsSlowDevice,
-  IN     UINT8                  MaximumPacketLength,
-  IN OUT VOID                   *Data,
-  IN OUT UINTN                  *DataLength,
-  IN OUT UINT8                  *DataToggle,
-  IN     UINTN                  TimeOut,
-  OUT    UINT32                 *TransferResult
-  );
-
-/**
-  Submits isochronous transfer to an isochronous endpoint of a USB device.
-
-  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
-  @param  DeviceAddress         Represents the address of the target device on the USB, which is
-                                assigned during USB enumeration.
-  @param  EndPointAddress       The combination of an endpoint number and an endpoint
-                                direction of the target USB device. Each endpoint address
-                                supports data transfer in one direction except the control
-                                endpoint (whose default endpoint address is 0). It is the caller's
-                                responsibility to make sure that the EndPointAddress
-                                represents an isochronous endpoint.
-  @param  MaximumPacketLength   Indicates the maximum packet size that the default control
-                                transfer endpoint is capable of sending or receiving.
-  @param  Data                  A pointer to the buffer of data that will be transmitted to USB
-                                device or received from USB device.                                                                                            asynchronous interrupt pipe is canceled.
-  @param  DataLength            Specifies the length, in bytes, of the data to be sent to or received
-                                from the USB device.
-  @param  TransferResult        A pointer to the detailed result information from the isochronous
-                                transfer.
-
-  @retval EFI_SUCCESS           The isochronous transfer was completed successfully.
-  @retval EFI_OUT_OF_RESOURCES  The isochronous could not be completed due to a lack of resources.
-  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
-  @retval EFI_TIMEOUT           The isochronous transfer failed due to timeout.
-  @retval EFI_DEVICE_ERROR      The isochronous transfer failed due to host controller or device error.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_HC_PROTOCOL_ISOCHRONOUS_TRANSFER)(
-  IN     EFI_USB_HC_PROTOCOL    *This,
-  IN     UINT8                  DeviceAddress,
-  IN     UINT8                  EndPointAddress,
-  IN     UINT8                  MaximumPacketLength,
-  IN OUT VOID                   *Data,
-  IN     UINTN                  DataLength,
-  OUT    UINT32                 *TransferResult
-  );
-
-/**
-  Submits nonblocking isochronous transfer to an isochronous endpoint of a USB device.
-
-  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
-  @param  DeviceAddress         Represents the address of the target device on the USB, which is
-                                assigned during USB enumeration.
-  @param  EndPointAddress       The combination of an endpoint number and an endpoint
-                                direction of the target USB device. Each endpoint address
-                                supports data transfer in one direction except the control
-                                endpoint (whose default endpoint address is zero). It is the
-                                caller's responsibility to make sure that the
-                                EndPointAddress represents an isochronous endpoint.
-  @param  MaximumPacketLength   Indicates the maximum packet size that the default control
-                                transfer endpoint is capable of sending or receiving. For isochronous
-                                endpoints, this value is used to reserve the bus time in the schedule,
-                                required for the perframe data payloads. The pipe may, on an ongoing basis,
-                                actually use less bandwidth than that reserved.
-  @param  Data                  A pointer to the buffer of data that will be transmitted to USB
-                                device or received from USB device.                                                                                            asynchronous interrupt pipe is canceled.
-  @param  DataLength            Specifies the length, in bytes, of the data to be sent to or received
-                                from the USB device.
-  @param  IsochronousCallback   The Callback function.This function is called if the requested
-                                isochronous transfer is completed.
-  @param  Context               Data passed to the IsochronousCallback function. This is
-                                an optional parameter and may be NULL.
-
-  @retval EFI_SUCCESS           The asynchronous isochronous transfer was completed successfully.
-  @retval EFI_OUT_OF_RESOURCES  The asynchronous isochronous could not be completed due to a lack of resources.
-  @retval EFI_INVALID_PARAMETER Some parameters are invalid.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_HC_PROTOCOL_ASYNC_ISOCHRONOUS_TRANSFER)(
-  IN     EFI_USB_HC_PROTOCOL                *This,
-  IN     UINT8                              DeviceAddress,
-  IN     UINT8                              EndPointAddress,
-  IN     UINT8                              MaximumPacketLength,
-  IN OUT VOID                               *Data,
-  IN     UINTN                              DataLength,
-  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK    IsochronousCallBack,
-  IN     VOID                               *Context OPTIONAL
-  );
-
-/**
-  Retrieves the number of root hub ports.
-
-  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
-  @param  PortNumber            A pointer to the number of the root hub ports.
-
-  @retval EFI_SUCCESS           The port number was retrieved successfully.
-  @retval EFI_DEVICE_ERROR      An error was encountered while attempting to retrieve the port number.
-  @retval EFI_INVALID_PARAMETER PortNumber is NULL.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_HC_PROTOCOL_GET_ROOTHUB_PORT_NUMBER)(
-  IN EFI_USB_HC_PROTOCOL    *This,
-  OUT UINT8                 *PortNumber
-  );
-
-/**
-  Retrieves the current status of a USB root hub port.
-
-  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
-  @param  PortNumber            Specifies the root hub port from which the status is to be retrieved.
-                                This value is zero based. For example, if a root hub has two ports,
-                                then the first port is numbered 0, and the second port is
-                                numbered 1.
-  @param  PortStatus            A pointer to the current port status bits and port status change bits.
-
-  @retval EFI_SUCCESS           The status of the USB root hub port specified by PortNumber
-                                was returned in PortStatus.
-  @retval EFI_INVALID_PARAMETER PortNumber is invalid.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_HC_PROTOCOL_GET_ROOTHUB_PORT_STATUS)(
-  IN EFI_USB_HC_PROTOCOL     *This,
-  IN  UINT8                  PortNumber,
-  OUT EFI_USB_PORT_STATUS    *PortStatus
-  );
-
-/**
-  Sets a feature for the specified root hub port.
-
-  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
-  @param  PortNumber            Specifies the root hub port from which the status is to be retrieved.
-                                This value is zero based. For example, if a root hub has two ports,
-                                then the first port is numbered 0, and the second port is
-                                numbered 1.
-  @param  PortFeature           Indicates the feature selector associated with the feature set
-                                request.
-
-  @retval EFI_SUCCESS           The feature specified by PortFeature was set for the USB
-                                root hub port specified by PortNumber.
-  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_HC_PROTOCOL_SET_ROOTHUB_PORT_FEATURE)(
-  IN EFI_USB_HC_PROTOCOL     *This,
-  IN UINT8                   PortNumber,
-  IN EFI_USB_PORT_FEATURE    PortFeature
-  );
-
-/**
-  Clears a feature for the specified root hub port.
-
-  @param  This                  A pointer to the EFI_USB_HC_PROTOCOL instance.
-  @param  PortNumber            Specifies the root hub port from which the status is to be retrieved.
-                                This value is zero based. For example, if a root hub has two ports,
-                                then the first port is numbered 0, and the second port is
-                                numbered 1.
-  @param  PortFeature           Indicates the feature selector associated with the feature clear
-                                request.
-
-  @retval EFI_SUCCESS           The feature specified by PortFeature was cleared for the USB
-                                root hub port specified by PortNumber.
-  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_HC_PROTOCOL_CLEAR_ROOTHUB_PORT_FEATURE)(
-  IN EFI_USB_HC_PROTOCOL     *This,
-  IN UINT8                   PortNumber,
-  IN EFI_USB_PORT_FEATURE    PortFeature
-  );
-
-
-///
-/// The EFI_USB_HC_PROTOCOL provides USB host controller management, basic data transactions
-/// over a USB bus, and USB root hub access. A device driver that wishes to manage a USB bus in a
-/// system retrieves the EFI_USB_HC_PROTOCOL instance that is associated with the USB bus to be
-/// managed. A device handle for a USB host controller will minimally contain an
-/// EFI_DEVICE_PATH_PROTOCOL instance, and an EFI_USB_HC_PROTOCOL instance.
-///
-struct _EFI_USB_HC_PROTOCOL {
-  EFI_USB_HC_PROTOCOL_RESET                       Reset;
-  EFI_USB_HC_PROTOCOL_GET_STATE                   GetState;
-  EFI_USB_HC_PROTOCOL_SET_STATE                   SetState;
-  EFI_USB_HC_PROTOCOL_CONTROL_TRANSFER            ControlTransfer;
-  EFI_USB_HC_PROTOCOL_BULK_TRANSFER               BulkTransfer;
-  EFI_USB_HC_PROTOCOL_ASYNC_INTERRUPT_TRANSFER    AsyncInterruptTransfer;
-  EFI_USB_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER     SyncInterruptTransfer;
-  EFI_USB_HC_PROTOCOL_ISOCHRONOUS_TRANSFER        IsochronousTransfer;
-  EFI_USB_HC_PROTOCOL_ASYNC_ISOCHRONOUS_TRANSFER  AsyncIsochronousTransfer;
-  EFI_USB_HC_PROTOCOL_GET_ROOTHUB_PORT_NUMBER     GetRootHubPortNumber;
-  EFI_USB_HC_PROTOCOL_GET_ROOTHUB_PORT_STATUS     GetRootHubPortStatus;
-  EFI_USB_HC_PROTOCOL_SET_ROOTHUB_PORT_FEATURE    SetRootHubPortFeature;
-  EFI_USB_HC_PROTOCOL_CLEAR_ROOTHUB_PORT_FEATURE  ClearRootHubPortFeature;
-  ///
-  /// The major revision number of the USB host controller. The revision information
-  /// indicates the release of the Universal Serial Bus Specification with which the
-  /// host controller is compliant.
-  ///
-  UINT16                                          MajorRevision;
-  ///
-  /// The minor revision number of the USB host controller. The revision information
-  /// indicates the release of the Universal Serial Bus Specification with which the
-  /// host controller is compliant.
-  ///
-  UINT16                                          MinorRevision;
-};
-
-extern EFI_GUID gEfiUsbHcProtocolGuid;
-
-#endif
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/UsbIo.h b/roms/ipxe/src/include/ipxe/efi/Protocol/UsbIo.h
deleted file mode 100644 (file)
index b8d33ee..0000000
+++ /dev/null
@@ -1,514 +0,0 @@
-/** @file
-  EFI Usb I/O Protocol as defined in UEFI specification.
-  This protocol is used by code, typically drivers, running in the EFI
-  boot services environment to access USB devices like USB keyboards,
-  mice and mass storage devices. In particular, functions for managing devices
-  on USB buses are defined here.
-
-  Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef __USB_IO_H__
-#define __USB_IO_H__
-
-FILE_LICENCE ( BSD3 );
-
-#include <ipxe/efi/IndustryStandard/Usb.h>
-
-//
-// Global ID for the USB I/O Protocol
-//
-#define EFI_USB_IO_PROTOCOL_GUID \
-  { \
-    0x2B2F68D6, 0x0CD2, 0x44cf, {0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \
-  }
-
-typedef struct _EFI_USB_IO_PROTOCOL   EFI_USB_IO_PROTOCOL;
-
-//
-// Related Definition for EFI USB I/O protocol
-//
-
-//
-// USB standard descriptors and reqeust
-//
-typedef USB_DEVICE_REQUEST        EFI_USB_DEVICE_REQUEST;
-typedef USB_DEVICE_DESCRIPTOR     EFI_USB_DEVICE_DESCRIPTOR;
-typedef USB_CONFIG_DESCRIPTOR     EFI_USB_CONFIG_DESCRIPTOR;
-typedef USB_INTERFACE_DESCRIPTOR  EFI_USB_INTERFACE_DESCRIPTOR;
-typedef USB_ENDPOINT_DESCRIPTOR   EFI_USB_ENDPOINT_DESCRIPTOR;
-
-///
-/// USB data transfer direction
-///
-typedef enum {
-  EfiUsbDataIn,
-  EfiUsbDataOut,
-  EfiUsbNoData
-} EFI_USB_DATA_DIRECTION;
-
-//
-// USB Transfer Results
-//
-#define EFI_USB_NOERROR             0x00
-#define EFI_USB_ERR_NOTEXECUTE      0x01
-#define EFI_USB_ERR_STALL           0x02
-#define EFI_USB_ERR_BUFFER          0x04
-#define EFI_USB_ERR_BABBLE          0x08
-#define EFI_USB_ERR_NAK             0x10
-#define EFI_USB_ERR_CRC             0x20
-#define EFI_USB_ERR_TIMEOUT         0x40
-#define EFI_USB_ERR_BITSTUFF        0x80
-#define EFI_USB_ERR_SYSTEM          0x100
-
-/**
-  Async USB transfer callback routine.
-
-  @param  Data                  Data received or sent via the USB Asynchronous Transfer, if the
-                                transfer completed successfully.
-  @param  DataLength            The length of Data received or sent via the Asynchronous
-                                Transfer, if transfer successfully completes.
-  @param  Context               Data passed from UsbAsyncInterruptTransfer() request.
-  @param  Status                Indicates the result of the asynchronous transfer.
-
-  @retval EFI_SUCCESS           The asynchronous USB transfer request has been successfully executed.
-  @retval EFI_DEVICE_ERROR      The asynchronous USB transfer request failed.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_ASYNC_USB_TRANSFER_CALLBACK)(
-  IN VOID         *Data,
-  IN UINTN        DataLength,
-  IN VOID         *Context,
-  IN UINT32       Status
-  );
-
-//
-// Prototype for EFI USB I/O protocol
-//
-
-
-/**
-  This function is used to manage a USB device with a control transfer pipe. A control transfer is
-  typically used to perform device initialization and configuration.
-
-  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.
-  @param  Request               A pointer to the USB device request that will be sent to the USB
-                                device.
-  @param  Direction             Indicates the data direction.
-  @param  Timeout               Indicating the transfer should be completed within this time frame.
-                                The units are in milliseconds.
-  @param  Data                  A pointer to the buffer of data that will be transmitted to USB
-                                device or received from USB device.
-  @param  DataLength            The size, in bytes, of the data buffer specified by Data.
-  @param  Status                A pointer to the result of the USB transfer.
-
-  @retval EFI_SUCCESS           The control transfer has been successfully executed.
-  @retval EFI_DEVICE_ERROR      The transfer failed. The transfer status is returned in Status.
-  @retval EFI_INVALID_PARAMETE  One or more parameters are invalid.
-  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
-  @retval EFI_TIMEOUT           The control transfer fails due to timeout.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_IO_CONTROL_TRANSFER)(
-  IN EFI_USB_IO_PROTOCOL                        *This,
-  IN EFI_USB_DEVICE_REQUEST                     *Request,
-  IN EFI_USB_DATA_DIRECTION                     Direction,
-  IN UINT32                                     Timeout,
-  IN OUT VOID                                   *Data OPTIONAL,
-  IN UINTN                                      DataLength  OPTIONAL,
-  OUT UINT32                                    *Status
-  );
-
-/**
-  This function is used to manage a USB device with the bulk transfer pipe. Bulk Transfers are
-  typically used to transfer large amounts of data to/from USB devices.
-
-  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.
-  @param  DeviceEndpoint        The destination USB device endpoint to which the
-                                device request is being sent. DeviceEndpoint must
-                                be between 0x01 and 0x0F or between 0x81 and 0x8F,
-                                otherwise EFI_INVALID_PARAMETER is returned. If
-                                the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER
-                                is returned. The MSB of this parameter indicates
-                                the endpoint direction. The number "1" stands for
-                                an IN endpoint, and "0" stands for an OUT endpoint.
-  @param  Data                  A pointer to the buffer of data that will be transmitted to USB
-                                device or received from USB device.
-  @param  DataLength            The size, in bytes, of the data buffer specified by Data.
-                                On input, the size, in bytes, of the data buffer specified by Data.
-                                On output, the number of bytes that were actually transferred.
-  @param  Timeout               Indicating the transfer should be completed within this time frame.
-                                The units are in milliseconds. If Timeout is 0, then the
-                                caller must wait for the function to be completed until
-                                EFI_SUCCESS or EFI_DEVICE_ERROR is returned.
-  @param  Status                This parameter indicates the USB transfer status.
-
-  @retval EFI_SUCCESS           The bulk transfer has been successfully executed.
-  @retval EFI_DEVICE_ERROR      The transfer failed. The transfer status is returned in Status.
-  @retval EFI_INVALID_PARAMETE  One or more parameters are invalid.
-  @retval EFI_OUT_OF_RESOURCES  The request could not be submitted due to a lack of resources.
-  @retval EFI_TIMEOUT           The control transfer fails due to timeout.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_IO_BULK_TRANSFER)(
-  IN EFI_USB_IO_PROTOCOL            *This,
-  IN UINT8                          DeviceEndpoint,
-  IN OUT VOID                       *Data,
-  IN OUT UINTN                      *DataLength,
-  IN UINTN                          Timeout,
-  OUT UINT32                        *Status
-  );
-
-/**
-  This function is used to manage a USB device with an interrupt transfer pipe. An Asynchronous
-  Interrupt Transfer is typically used to query a device's status at a fixed rate. For example,
-  keyboard, mouse, and hub devices use this type of transfer to query their interrupt endpoints at
-  a fixed rate.
-
-  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.
-  @param  DeviceEndpoint        The destination USB device endpoint to which the
-                                device request is being sent. DeviceEndpoint must
-                                be between 0x01 and 0x0F or between 0x81 and 0x8F,
-                                otherwise EFI_INVALID_PARAMETER is returned. If
-                                the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER
-                                is returned. The MSB of this parameter indicates
-                                the endpoint direction. The number "1" stands for
-                                an IN endpoint, and "0" stands for an OUT endpoint.
-  @param  IsNewTransfer         If TRUE, a new transfer will be submitted to USB controller. If
-                                FALSE, the interrupt transfer is deleted from the device's interrupt
-                                transfer queue.
-  @param  PollingInterval       Indicates the periodic rate, in milliseconds, that the transfer is to be
-                                executed.This parameter is required when IsNewTransfer is TRUE. The
-                                value must be between 1 to 255, otherwise EFI_INVALID_PARAMETER is returned.
-                                The units are in milliseconds.
-  @param  DataLength            Specifies the length, in bytes, of the data to be received from the
-                                USB device. This parameter is only required when IsNewTransfer is TRUE.
-  @param  InterruptCallback     The Callback function. This function is called if the asynchronous
-                                interrupt transfer is completed. This parameter is required
-                                when IsNewTransfer is TRUE.
-  @param  Context               Data passed to the InterruptCallback function. This is an optional
-                                parameter and may be NULL.
-
-  @retval EFI_SUCCESS           The asynchronous USB transfer request transfer has been successfully executed.
-  @retval EFI_DEVICE_ERROR      The asynchronous USB transfer request failed.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_IO_ASYNC_INTERRUPT_TRANSFER)(
-  IN EFI_USB_IO_PROTOCOL                                 *This,
-  IN UINT8                                               DeviceEndpoint,
-  IN BOOLEAN                                             IsNewTransfer,
-  IN UINTN                                               PollingInterval    OPTIONAL,
-  IN UINTN                                               DataLength         OPTIONAL,
-  IN EFI_ASYNC_USB_TRANSFER_CALLBACK                     InterruptCallBack  OPTIONAL,
-  IN VOID                                                *Context OPTIONAL
-  );
-
-/**
-  This function is used to manage a USB device with an interrupt transfer pipe.
-
-  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.
-  @param  DeviceEndpoint        The destination USB device endpoint to which the
-                                device request is being sent. DeviceEndpoint must
-                                be between 0x01 and 0x0F or between 0x81 and 0x8F,
-                                otherwise EFI_INVALID_PARAMETER is returned. If
-                                the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER
-                                is returned. The MSB of this parameter indicates
-                                the endpoint direction. The number "1" stands for
-                                an IN endpoint, and "0" stands for an OUT endpoint.
-  @param  Data                  A pointer to the buffer of data that will be transmitted to USB
-                                device or received from USB device.
-  @param  DataLength            On input, then size, in bytes, of the buffer Data. On output, the
-                                amount of data actually transferred.
-  @param  Timeout               The time out, in seconds, for this transfer. If Timeout is 0,
-                                then the caller must wait for the function to be completed
-                                until EFI_SUCCESS or EFI_DEVICE_ERROR is returned. If the
-                                transfer is not completed in this time frame, then EFI_TIMEOUT is returned.
-  @param  Status                This parameter indicates the USB transfer status.
-
-  @retval EFI_SUCCESS           The sync interrupt transfer has been successfully executed.
-  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
-  @retval EFI_DEVICE_ERROR      The sync interrupt transfer request failed.
-  @retval EFI_OUT_OF_RESOURCES  The request could not be submitted due to a lack of resources.
-  @retval EFI_TIMEOUT           The transfer fails due to timeout.
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_IO_SYNC_INTERRUPT_TRANSFER)(
-  IN EFI_USB_IO_PROTOCOL            *This,
-  IN     UINT8                      DeviceEndpoint,
-  IN OUT VOID                       *Data,
-  IN OUT UINTN                      *DataLength,
-  IN     UINTN                      Timeout,
-  OUT    UINT32                     *Status
-  );
-
-/**
-  This function is used to manage a USB device with an isochronous transfer pipe. An Isochronous
-  transfer is typically used to transfer streaming data.
-
-  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.
-  @param  DeviceEndpoint        The destination USB device endpoint to which the
-                                device request is being sent. DeviceEndpoint must
-                                be between 0x01 and 0x0F or between 0x81 and 0x8F,
-                                otherwise EFI_INVALID_PARAMETER is returned. If
-                                the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER
-                                is returned. The MSB of this parameter indicates
-                                the endpoint direction. The number "1" stands for
-                                an IN endpoint, and "0" stands for an OUT endpoint.
-  @param  Data                  A pointer to the buffer of data that will be transmitted to USB
-                                device or received from USB device.
-  @param  DataLength            The size, in bytes, of the data buffer specified by Data.
-  @param  Status                This parameter indicates the USB transfer status.
-
-  @retval EFI_SUCCESS           The isochronous transfer has been successfully executed.
-  @retval EFI_INVALID_PARAMETER The parameter DeviceEndpoint is not valid.
-  @retval EFI_DEVICE_ERROR      The transfer failed due to the reason other than timeout, The error status
-                                is returned in Status.
-  @retval EFI_OUT_OF_RESOURCES  The request could not be submitted due to a lack of resources.
-  @retval EFI_TIMEOUT           The transfer fails due to timeout.
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_IO_ISOCHRONOUS_TRANSFER)(
-  IN EFI_USB_IO_PROTOCOL            *This,
-  IN     UINT8                      DeviceEndpoint,
-  IN OUT VOID                       *Data,
-  IN     UINTN                      DataLength,
-  OUT    UINT32                     *Status
-  );
-
-/**
-  This function is used to manage a USB device with an isochronous transfer pipe. An Isochronous
-  transfer is typically used to transfer streaming data.
-
-  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.
-  @param  DeviceEndpoint        The destination USB device endpoint to which the
-                                device request is being sent. DeviceEndpoint must
-                                be between 0x01 and 0x0F or between 0x81 and 0x8F,
-                                otherwise EFI_INVALID_PARAMETER is returned. If
-                                the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER
-                                is returned. The MSB of this parameter indicates
-                                the endpoint direction. The number "1" stands for
-                                an IN endpoint, and "0" stands for an OUT endpoint.
-  @param  Data                  A pointer to the buffer of data that will be transmitted to USB
-                                device or received from USB device.
-  @param  DataLength            The size, in bytes, of the data buffer specified by Data.
-                                This is an optional parameter and may be NULL.
-  @param  IsochronousCallback   The IsochronousCallback() function.This function is
-                                called if the requested isochronous transfer is completed.
-  @param  Context               Data passed to the IsochronousCallback() function.
-
-  @retval EFI_SUCCESS           The asynchronous isochronous transfer has been successfully submitted
-                                to the system.
-  @retval EFI_INVALID_PARAMETER The parameter DeviceEndpoint is not valid.
-  @retval EFI_OUT_OF_RESOURCES  The request could not be submitted due to a lack of resources.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_IO_ASYNC_ISOCHRONOUS_TRANSFER)(
-  IN EFI_USB_IO_PROTOCOL              *This,
-  IN UINT8                            DeviceEndpoint,
-  IN OUT VOID                         *Data,
-  IN     UINTN                        DataLength,
-  IN EFI_ASYNC_USB_TRANSFER_CALLBACK  IsochronousCallBack,
-  IN VOID                             *Context OPTIONAL
-  );
-
-/**
-  Resets and reconfigures the USB controller. This function will work for all USB devices except
-  USB Hub Controllers.
-
-  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.
-
-  @retval EFI_SUCCESS           The USB controller was reset.
-  @retval EFI_INVALID_PARAMETER If the controller specified by This is a USB hub.
-  @retval EFI_DEVICE_ERROR      An error occurred during the reconfiguration process.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_IO_PORT_RESET)(
-  IN EFI_USB_IO_PROTOCOL    *This
-  );
-
-/**
-  Retrieves the USB Device Descriptor.
-
-  @param  This                  A pointer to the EFI_USB_IO_PROTOCOL instance.
-  @param  DeviceDescriptor      A pointer to the caller allocated USB Device Descriptor.
-
-  @retval EFI_SUCCESS           The device descriptor was retrieved successfully.
-  @retval EFI_INVALID_PARAMETER DeviceDescriptor is NULL.
-  @retval EFI_NOT_FOUND         The device descriptor was not found. The device may not be configured.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_IO_GET_DEVICE_DESCRIPTOR)(
-  IN EFI_USB_IO_PROTOCOL            *This,
-  OUT EFI_USB_DEVICE_DESCRIPTOR     *DeviceDescriptor
-  );
-
-/**
-  Retrieves the USB Device Descriptor.
-
-  @param  This                    A pointer to the EFI_USB_IO_PROTOCOL instance.
-  @param  ConfigurationDescriptor A pointer to the caller allocated USB Active Configuration
-                                  Descriptor.
-  @retval EFI_SUCCESS             The active configuration descriptor was retrieved successfully.
-  @retval EFI_INVALID_PARAMETER   ConfigurationDescriptor is NULL.
-  @retval EFI_NOT_FOUND           An active configuration descriptor cannot be found. The device may not
-                                  be configured.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_IO_GET_CONFIG_DESCRIPTOR)(
-  IN EFI_USB_IO_PROTOCOL            *This,
-  OUT EFI_USB_CONFIG_DESCRIPTOR     *ConfigurationDescriptor
-  );
-
-/**
-  Retrieves the Interface Descriptor for a USB Device Controller. As stated earlier, an interface
-  within a USB device is equivalently to a USB Controller within the current configuration.
-
-  @param  This                    A pointer to the EFI_USB_IO_PROTOCOL instance.
-  @param  InterfaceDescriptor     A pointer to the caller allocated USB Interface Descriptor within
-                                  the configuration setting.
-  @retval EFI_SUCCESS             The interface descriptor retrieved successfully.
-  @retval EFI_INVALID_PARAMETER   InterfaceDescriptor is NULL.
-  @retval EFI_NOT_FOUND           The interface descriptor cannot be found. The device may not be
-                                  correctly configured.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_IO_GET_INTERFACE_DESCRIPTOR)(
-  IN EFI_USB_IO_PROTOCOL            *This,
-  OUT EFI_USB_INTERFACE_DESCRIPTOR  *InterfaceDescriptor
-  );
-
-/**
-  Retrieves an Endpoint Descriptor within a USB Controller.
-
-  @param  This                    A pointer to the EFI_USB_IO_PROTOCOL instance.
-  @param  EndpointIndex           Indicates which endpoint descriptor to retrieve.
-  @param  EndpointDescriptor      A pointer to the caller allocated USB Endpoint Descriptor of
-                                  a USB controller.
-
-  @retval EFI_SUCCESS             The endpoint descriptor was retrieved successfully.
-  @retval EFI_INVALID_PARAMETER   One or more parameters are invalid.
-  @retval EFI_NOT_FOUND           The endpoint descriptor cannot be found. The device may not be
-                                  correctly configured.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_IO_GET_ENDPOINT_DESCRIPTOR)(
-  IN EFI_USB_IO_PROTOCOL            *This,
-  IN  UINT8                         EndpointIndex,
-  OUT EFI_USB_ENDPOINT_DESCRIPTOR   *EndpointDescriptor
-  );
-
-/**
-  Retrieves a string stored in a USB Device.
-
-  @param  This                    A pointer to the EFI_USB_IO_PROTOCOL instance.
-  @param  LangID                  The Language ID for the string being retrieved.
-  @param  StringID                The ID of the string being retrieved.
-  @param  String                  A pointer to a buffer allocated by this function with
-                                  AllocatePool() to store the string.If this function
-                                  returns EFI_SUCCESS, it stores the string the caller
-                                  wants to get. The caller should release the string
-                                  buffer with FreePool() after the string is not used any more.
-
-  @retval EFI_SUCCESS             The string was retrieved successfully.
-  @retval EFI_NOT_FOUND           The string specified by LangID and StringID was not found.
-  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to allocate the return buffer String.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_IO_GET_STRING_DESCRIPTOR)(
-  IN EFI_USB_IO_PROTOCOL            *This,
-  IN  UINT16                        LangID,
-  IN  UINT8                         StringID,
-  OUT CHAR16                        **String
-  );
-
-/**
-  Retrieves all the language ID codes that the USB device supports.
-
-  @param  This                    A pointer to the EFI_USB_IO_PROTOCOL instance.
-  @param  LangIDTable             Language ID for the string the caller wants to get.
-                                  This is a 16-bit ID defined by Microsoft. This
-                                  buffer pointer is allocated and maintained by
-                                  the USB Bus Driver, the caller should not modify
-                                  its contents.
-  @param  TableSize               The size, in bytes, of the table LangIDTable.
-
-  @retval EFI_SUCCESS             The support languages were retrieved successfully.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EFI_USB_IO_GET_SUPPORTED_LANGUAGE)(
-  IN EFI_USB_IO_PROTOCOL            *This,
-  OUT UINT16                        **LangIDTable,
-  OUT UINT16                        *TableSize
-  );
-
-///
-/// The EFI_USB_IO_PROTOCOL provides four basic transfers types described
-/// in the USB 1.1 Specification. These include control transfer, interrupt
-/// transfer, bulk transfer and isochronous transfer. The EFI_USB_IO_PROTOCOL
-/// also provides some basic USB device/controller management and configuration
-/// interfaces. A USB device driver uses the services of this protocol to manage USB devices.
-///
-struct _EFI_USB_IO_PROTOCOL {
-  //
-  // IO transfer
-  //
-  EFI_USB_IO_CONTROL_TRANSFER           UsbControlTransfer;
-  EFI_USB_IO_BULK_TRANSFER              UsbBulkTransfer;
-  EFI_USB_IO_ASYNC_INTERRUPT_TRANSFER   UsbAsyncInterruptTransfer;
-  EFI_USB_IO_SYNC_INTERRUPT_TRANSFER    UsbSyncInterruptTransfer;
-  EFI_USB_IO_ISOCHRONOUS_TRANSFER       UsbIsochronousTransfer;
-  EFI_USB_IO_ASYNC_ISOCHRONOUS_TRANSFER UsbAsyncIsochronousTransfer;
-
-  //
-  // Common device request
-  //
-  EFI_USB_IO_GET_DEVICE_DESCRIPTOR      UsbGetDeviceDescriptor;
-  EFI_USB_IO_GET_CONFIG_DESCRIPTOR      UsbGetConfigDescriptor;
-  EFI_USB_IO_GET_INTERFACE_DESCRIPTOR   UsbGetInterfaceDescriptor;
-  EFI_USB_IO_GET_ENDPOINT_DESCRIPTOR    UsbGetEndpointDescriptor;
-  EFI_USB_IO_GET_STRING_DESCRIPTOR      UsbGetStringDescriptor;
-  EFI_USB_IO_GET_SUPPORTED_LANGUAGE     UsbGetSupportedLanguages;
-
-  //
-  // Reset controller's parent port
-  //
-  EFI_USB_IO_PORT_RESET                 UsbPortReset;
-};
-
-extern EFI_GUID gEfiUsbIoProtocolGuid;
-
-#endif
index ef0ea67..371dae6 100644 (file)
@@ -1,8 +1,8 @@
 /** @file
   Defines data types and constants introduced in UEFI.
 
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
-Portions copyright (c) 2011 - 2016, ARM Ltd. All rights reserved.<BR>
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
 
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
@@ -153,14 +153,12 @@ typedef union {
 #define EFI_END_OF_FILE           RETURN_END_OF_FILE
 #define EFI_INVALID_LANGUAGE      RETURN_INVALID_LANGUAGE
 #define EFI_COMPROMISED_DATA      RETURN_COMPROMISED_DATA
-#define EFI_HTTP_ERROR            RETURN_HTTP_ERROR
 
 #define EFI_WARN_UNKNOWN_GLYPH    RETURN_WARN_UNKNOWN_GLYPH
 #define EFI_WARN_DELETE_FAILURE   RETURN_WARN_DELETE_FAILURE
 #define EFI_WARN_WRITE_FAILURE    RETURN_WARN_WRITE_FAILURE
 #define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL
 #define EFI_WARN_STALE_DATA       RETURN_WARN_STALE_DATA
-#define EFI_WARN_FILE_SYSTEM      RETURN_WARN_FILE_SYSTEM
 ///@}
 
 ///
index 49ea24f..19121de 100644 (file)
@@ -3,7 +3,7 @@
   IFR is primarily consumed by the EFI presentation engine, and produced by EFI
   internal application and drivers as well as all add-in card option-ROM drivers
 
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -782,7 +782,6 @@ typedef union {
 #define EFI_IFR_MODAL_TAG_OP           0x61
 #define EFI_IFR_REFRESH_ID_OP          0x62
 #define EFI_IFR_WARNING_IF_OP          0x63
-#define EFI_IFR_MATCH2_OP              0x64
 
 //
 // Definitions of IFR Standard Headers
@@ -814,11 +813,10 @@ typedef struct _EFI_IFR_QUESTION_HEADER {
 //
 // Flag values of EFI_IFR_QUESTION_HEADER
 //
-#define EFI_IFR_FLAG_READ_ONLY          0x01
-#define EFI_IFR_FLAG_CALLBACK           0x04
-#define EFI_IFR_FLAG_RESET_REQUIRED     0x10
-#define EFI_IFR_FLAG_RECONNECT_REQUIRED 0x40
-#define EFI_IFR_FLAG_OPTIONS_ONLY       0x80
+#define EFI_IFR_FLAG_READ_ONLY         0x01
+#define EFI_IFR_FLAG_CALLBACK          0x04
+#define EFI_IFR_FLAG_RESET_REQUIRED    0x10
+#define EFI_IFR_FLAG_OPTIONS_ONLY      0x80
 
 //
 // Definition for Opcode Reference
@@ -1403,11 +1401,6 @@ typedef struct _EFI_IFR_MATCH {
   EFI_IFR_OP_HEADER        Header;
 } EFI_IFR_MATCH;
 
-typedef struct _EFI_IFR_MATCH2 {
-  EFI_IFR_OP_HEADER        Header;
-  EFI_GUID                 SyntaxType;
-} EFI_IFR_MATCH2;
-
 typedef struct _EFI_IFR_MULTIPLY {
   EFI_IFR_OP_HEADER        Header;
 } EFI_IFR_MULTIPLY;
index 38ec09f..678f3eb 100644 (file)
@@ -1,7 +1,7 @@
 /** @file
   This includes some definitions introduced in UEFI that will be used in both PEI and DXE phases.
 
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -84,48 +84,10 @@ typedef enum {
   /// Address space reserved by the firmware for code that is part of the processor.
   ///
   EfiPalCode,
-  ///
-  /// A memory region that operates as EfiConventionalMemory,
-  /// however it happens to also support byte-addressable non-volatility.
-  ///
-  EfiPersistentMemory,
   EfiMaxMemoryType
 } EFI_MEMORY_TYPE;
 
 ///
-/// Enumeration of reset types.
-///
-typedef enum {
-  ///
-  /// Used to induce a system-wide reset. This sets all circuitry within the
-  /// system to its initial state.  This type of reset is asynchronous to system
-  /// operation and operates withgout regard to cycle boundaries.  EfiColdReset
-  /// is tantamount to a system power cycle.
-  ///
-  EfiResetCold,
-  ///
-  /// Used to induce a system-wide initialization. The processors are set to their
-  /// initial state, and pending cycles are not corrupted.  If the system does
-  /// not support this reset type, then an EfiResetCold must be performed.
-  ///
-  EfiResetWarm,
-  ///
-  /// Used to induce an entry into a power state equivalent to the ACPI G2/S5 or G3
-  /// state.  If the system does not support this reset type, then when the system
-  /// is rebooted, it should exhibit the EfiResetCold attributes.
-  ///
-  EfiResetShutdown,
-  ///
-  /// Used to induce a system-wide reset. The exact type of the reset is defined by
-  /// the EFI_GUID that follows the Null-terminated Unicode string passed into
-  /// ResetData. If the platform does not recognize the EFI_GUID in ResetData the
-  /// platform must pick a supported reset type to perform. The platform may
-  /// optionally log the parameters from any non-normal reset that occurs.
-  ///
-  EfiResetPlatformSpecific
-} EFI_RESET_TYPE;
-
-///
 /// Data structure that precedes all of the standard EFI table types.
 ///
 typedef struct {
index 13be21a..5c0b203 100644 (file)
@@ -3,7 +3,7 @@
   structure prototypes, global variables and constants that
   are needed for porting PXE to EFI.
 
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -1460,26 +1460,6 @@ typedef struct s_pxe_db_statistics {
 ///
 #define PXE_STATISTICS_UNSUPPORTED_PROTOCOL 0x15
 
-///
-/// Number of valid frames received that were duplicated.
-///
-#define PXE_STATISTICS_RX_DUPLICATED_FRAMES 0x16
-
-///
-/// Number of encrypted frames received that failed to decrypt.
-///
-#define PXE_STATISTICS_RX_DECRYPT_ERROR_FRAMES 0x17
-
-///
-/// Number of frames that failed to transmit after exceeding the retry limit.
-///
-#define PXE_STATISTICS_TX_ERROR_FRAMES 0x18
-
-///
-/// Number of frames transmitted successfully after more than one attempt.
-///
-#define PXE_STATISTICS_TX_RETRY_FRAMES 0x19
-
 typedef struct s_pxe_cpb_mcast_ip_to_mac {
   ///
   /// Multicast IP address to be converted to multicast MAC address.
index 98ac876..422b2f3 100644 (file)
@@ -1,11 +1,11 @@
 /** @file
   Include file that supports UEFI.
 
-  This include file must contain things defined in the UEFI 2.6 specification.
-  If a code construct is defined in the UEFI 2.6 specification it must be included
+  This include file must contain things defined in the UEFI 2.4 specification.
+  If a code construct is defined in the UEFI 2.4 specification it must be included
   by this include file.
 
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under
 the terms and conditions of the BSD License that accompanies this distribution.
 The full text of the license may be found at
@@ -65,35 +65,21 @@ typedef enum {
 //
 // Memory cacheability attributes
 //
-#define EFI_MEMORY_UC               0x0000000000000001ULL
-#define EFI_MEMORY_WC               0x0000000000000002ULL
-#define EFI_MEMORY_WT               0x0000000000000004ULL
-#define EFI_MEMORY_WB               0x0000000000000008ULL
-#define EFI_MEMORY_UCE              0x0000000000000010ULL
+#define EFI_MEMORY_UC   0x0000000000000001ULL
+#define EFI_MEMORY_WC   0x0000000000000002ULL
+#define EFI_MEMORY_WT   0x0000000000000004ULL
+#define EFI_MEMORY_WB   0x0000000000000008ULL
+#define EFI_MEMORY_UCE  0x0000000000000010ULL
 //
 // Physical memory protection attributes
 //
-// Note: UEFI spec 2.5 and following: use EFI_MEMORY_RO as write-protected physical memory
-// protection attribute. Also, EFI_MEMORY_WP means cacheability attribute.
-//
-#define EFI_MEMORY_WP               0x0000000000001000ULL
-#define EFI_MEMORY_RP               0x0000000000002000ULL
-#define EFI_MEMORY_XP               0x0000000000004000ULL
-#define EFI_MEMORY_RO               0x0000000000020000ULL
-//
-// Physical memory persistence attribute.
-// The memory region supports byte-addressable non-volatility.
-//
-#define EFI_MEMORY_NV               0x0000000000008000ULL
-//
-// The memory region provides higher reliability relative to other memory in the system.
-// If all memory has the same reliability, then this bit is not used.
-//
-#define EFI_MEMORY_MORE_RELIABLE    0x0000000000010000ULL
+#define EFI_MEMORY_WP   0x0000000000001000ULL
+#define EFI_MEMORY_RP   0x0000000000002000ULL
+#define EFI_MEMORY_XP   0x0000000000004000ULL
 //
 // Runtime memory attribute
 //
-#define EFI_MEMORY_RUNTIME          0x8000000000000000ULL
+#define EFI_MEMORY_RUNTIME  0x8000000000000000ULL
 
 ///
 /// Memory descriptor version number.
@@ -133,23 +119,18 @@ typedef struct {
 /**
   Allocates memory pages from the system.
 
-  @param[in]       Type         The type of allocation to perform.
-  @param[in]       MemoryType   The type of memory to allocate.
-                                MemoryType values in the range 0x70000000..0x7FFFFFFF
-                                are reserved for OEM use. MemoryType values in the range
-                                0x80000000..0xFFFFFFFF are reserved for use by UEFI OS loaders
-                                that are provided by operating system vendors.
-  @param[in]       Pages        The number of contiguous 4 KB pages to allocate.
-  @param[in, out]  Memory       The pointer to a physical address. On input, the way in which the address is
-                                used depends on the value of Type.
+  @param  Type        The type of allocation to perform.
+  @param  MemoryType  The type of memory to allocate.
+  @param  Pages       The number of contiguous 4 KB pages to allocate.
+  @param  Memory      The pointer to a physical address. On input, the way in which the address is
+                      used depends on the value of Type.
 
   @retval EFI_SUCCESS           The requested pages were allocated.
   @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or
                                 AllocateMaxAddress or AllocateAddress.
                                 2) MemoryType is in the range
-                                EfiMaxMemoryType..0x6FFFFFFF.
                                 3) Memory is NULL.
-                                4) MemoryType is EfiPersistentMemory.
+                                EfiMaxMemoryType..0x7FFFFFFF.
   @retval EFI_OUT_OF_RESOURCES  The pages could not be allocated.
   @retval EFI_NOT_FOUND         The requested pages could not be found.
 
@@ -166,8 +147,8 @@ EFI_STATUS
 /**
   Frees memory pages.
 
-  @param[in]  Memory      The base physical address of the pages to be freed.
-  @param[in]  Pages       The number of contiguous 4 KB pages to free.
+  @param  Memory      The base physical address of the pages to be freed.
+  @param  Pages       The number of contiguous 4 KB pages to free.
 
   @retval EFI_SUCCESS           The requested pages were freed.
   @retval EFI_INVALID_PARAMETER Memory is not a page-aligned address or Pages is invalid.
@@ -185,19 +166,19 @@ EFI_STATUS
 /**
   Returns the current memory map.
 
-  @param[in, out]  MemoryMapSize         A pointer to the size, in bytes, of the MemoryMap buffer.
-                                         On input, this is the size of the buffer allocated by the caller.
-                                         On output, it is the size of the buffer returned by the firmware if
-                                         the buffer was large enough, or the size of the buffer needed to contain
-                                         the map if the buffer was too small.
-  @param[in, out]  MemoryMap             A pointer to the buffer in which firmware places the current memory
-                                         map.
-  @param[out]      MapKey                A pointer to the location in which firmware returns the key for the
-                                         current memory map.
-  @param[out]      DescriptorSize        A pointer to the location in which firmware returns the size, in bytes, of
-                                         an individual EFI_MEMORY_DESCRIPTOR.
-  @param[out]      DescriptorVersion     A pointer to the location in which firmware returns the version number
-                                         associated with the EFI_MEMORY_DESCRIPTOR.
+  @param  MemoryMapSize         A pointer to the size, in bytes, of the MemoryMap buffer.
+                                On input, this is the size of the buffer allocated by the caller.
+                                On output, it is the size of the buffer returned by the firmware if
+                                the buffer was large enough, or the size of the buffer needed to contain
+                                the map if the buffer was too small.
+  @param  MemoryMap             A pointer to the buffer in which firmware places the current memory
+                                map.
+  @param  MapKey                A pointer to the location in which firmware returns the key for the
+                                current memory map.
+  @param  DescriptorSize        A pointer to the location in which firmware returns the size, in bytes, of
+                                an individual EFI_MEMORY_DESCRIPTOR.
+  @param  DescriptorVersion     A pointer to the location in which firmware returns the version number
+                                associated with the EFI_MEMORY_DESCRIPTOR.
 
   @retval EFI_SUCCESS           The memory map was returned in the MemoryMap buffer.
   @retval EFI_BUFFER_TOO_SMALL  The MemoryMap buffer was too small. The current buffer size
@@ -220,20 +201,14 @@ EFI_STATUS
 /**
   Allocates pool memory.
 
-  @param[in]   PoolType         The type of pool to allocate.
-                                MemoryType values in the range 0x70000000..0x7FFFFFFF
-                                are reserved for OEM use. MemoryType values in the range
-                                0x80000000..0xFFFFFFFF are reserved for use by UEFI OS loaders
-                                that are provided by operating system vendors.
-  @param[in]   Size             The number of bytes to allocate from the pool.
-  @param[out]  Buffer           A pointer to a pointer to the allocated buffer if the call succeeds;
+  @param  PoolType              The type of pool to allocate.
+  @param  Size                  The number of bytes to allocate from the pool.
+  @param  Buffer                A pointer to a pointer to the allocated buffer if the call succeeds;
                                 undefined otherwise.
 
   @retval EFI_SUCCESS           The requested number of bytes was allocated.
   @retval EFI_OUT_OF_RESOURCES  The pool requested could not be allocated.
-  @retval EFI_INVALID_PARAMETER Buffer is NULL.
-                                PoolType is in the range EfiMaxMemoryType..0x6FFFFFFF.
-                                PoolType is EfiPersistentMemory.
+  @retval EFI_INVALID_PARAMETER PoolType was invalid or Buffer is NULL.
 
 **/
 typedef
@@ -247,7 +222,7 @@ EFI_STATUS
 /**
   Returns pool memory to the system.
 
-  @param[in]  Buffer            The pointer to the buffer to free.
+  @param  Buffer                The pointer to the buffer to free.
 
   @retval EFI_SUCCESS           The memory was returned to the system.
   @retval EFI_INVALID_PARAMETER Buffer was invalid.
@@ -262,10 +237,10 @@ EFI_STATUS
 /**
   Changes the runtime addressing mode of EFI firmware from physical to virtual.
 
-  @param[in]  MemoryMapSize     The size in bytes of VirtualMap.
-  @param[in]  DescriptorSize    The size in bytes of an entry in the VirtualMap.
-  @param[in]  DescriptorVersion The version of the structure entries in VirtualMap.
-  @param[in]  VirtualMap        An array of memory descriptors which contain new virtual
+  @param  MemoryMapSize         The size in bytes of VirtualMap.
+  @param  DescriptorSize        The size in bytes of an entry in the VirtualMap.
+  @param  DescriptorVersion     The version of the structure entries in VirtualMap.
+  @param  VirtualMap            An array of memory descriptors which contain new virtual
                                 address mapping information for all runtime ranges.
 
   @retval EFI_SUCCESS           The virtual address map has been applied.
@@ -290,15 +265,15 @@ EFI_STATUS
 /**
   Connects one or more drivers to a controller.
 
-  @param[in]  ControllerHandle      The handle of the controller to which driver(s) are to be connected.
-  @param[in]  DriverImageHandle     A pointer to an ordered list handles that support the
-                                    EFI_DRIVER_BINDING_PROTOCOL.
-  @param[in]  RemainingDevicePath   A pointer to the device path that specifies a child of the
-                                    controller specified by ControllerHandle.
-  @param[in]  Recursive             If TRUE, then ConnectController() is called recursively
-                                    until the entire tree of controllers below the controller specified
-                                    by ControllerHandle have been created. If FALSE, then
-                                    the tree of controllers is only expanded one level.
+  @param  ControllerHandle      The handle of the controller to which driver(s) are to be connected.
+  @param  DriverImageHandle     A pointer to an ordered list handles that support the
+                                EFI_DRIVER_BINDING_PROTOCOL.
+  @param  RemainingDevicePath   A pointer to the device path that specifies a child of the
+                                controller specified by ControllerHandle.
+  @param  Recursive             If TRUE, then ConnectController() is called recursively
+                                until the entire tree of controllers below the controller specified
+                                by ControllerHandle have been created. If FALSE, then
+                                the tree of controllers is only expanded one level.
 
   @retval EFI_SUCCESS           1) One or more drivers were connected to ControllerHandle.
                                 2) No drivers were connected to ControllerHandle, but
@@ -324,13 +299,13 @@ EFI_STATUS
 /**
   Disconnects one or more drivers from a controller.
 
-  @param[in]  ControllerHandle      The handle of the controller from which driver(s) are to be disconnected.
-  @param[in]  DriverImageHandle     The driver to disconnect from ControllerHandle.
-                                    If DriverImageHandle is NULL, then all the drivers currently managing
-                                    ControllerHandle are disconnected from ControllerHandle.
-  @param[in]  ChildHandle           The handle of the child to destroy.
-                                    If ChildHandle is NULL, then all the children of ControllerHandle are
-                                    destroyed before the drivers are disconnected from ControllerHandle.
+  @param  ControllerHandle      The handle of the controller from which driver(s) are to be disconnected.
+  @param  DriverImageHandle     The driver to disconnect from ControllerHandle.
+                                If DriverImageHandle is NULL, then all the drivers currently managing
+                                ControllerHandle are disconnected from ControllerHandle.
+  @param  ChildHandle           The handle of the child to destroy.
+                                If ChildHandle is NULL, then all the children of ControllerHandle are
+                                destroyed before the drivers are disconnected from ControllerHandle.
 
   @retval EFI_SUCCESS           1) One or more drivers were disconnected from the controller.
                                 2) On entry, no drivers are managing ControllerHandle.
@@ -363,9 +338,9 @@ EFI_STATUS
 /**
   Determines the new virtual address that is to be used on subsequent memory accesses.
 
-  @param[in]       DebugDisposition  Supplies type information for the pointer being converted.
-  @param[in, out]  Address           A pointer to a pointer that is to be fixed to be the value needed
-                                     for the new virtual address mappings being applied.
+  @param  DebugDisposition      Supplies type information for the pointer being converted.
+  @param  Address               A pointer to a pointer that is to be fixed to be the value needed
+                                for the new virtual address mappings being applied.
 
   @retval EFI_SUCCESS           The pointer pointed to by Address was modified.
   @retval EFI_INVALID_PARAMETER 1) Address is NULL.
@@ -407,9 +382,9 @@ EFI_STATUS
 /**
   Invoke a notification event
 
-  @param[in]  Event                 Event whose notification function is being invoked.
-  @param[in]  Context               The pointer to the notification function's context,
-                                    which is implementation-dependent.
+  @param  Event                 Event whose notification function is being invoked.
+  @param  Context               The pointer to the notification function's context,
+                                which is implementation-dependent.
 
 **/
 typedef
@@ -422,12 +397,12 @@ VOID
 /**
   Creates an event.
 
-  @param[in]   Type             The type of event to create and its mode and attributes.
-  @param[in]   NotifyTpl        The task priority level of event notifications, if needed.
-  @param[in]   NotifyFunction   The pointer to the event's notification function, if any.
-  @param[in]   NotifyContext    The pointer to the notification function's context; corresponds to parameter
+  @param  Type                  The type of event to create and its mode and attributes.
+  @param  NotifyTpl             The task priority level of event notifications, if needed.
+  @param  NotifyFunction        The pointer to the event's notification function, if any.
+  @param  NotifyContext         The pointer to the notification function's context; corresponds to parameter
                                 Context in the notification function.
-  @param[out]  Event            The pointer to the newly created event if the call succeeds; undefined
+  @param  Event                 The pointer to the newly created event if the call succeeds; undefined
                                 otherwise.
 
   @retval EFI_SUCCESS           The event structure was created.
@@ -448,15 +423,15 @@ EFI_STATUS
 /**
   Creates an event in a group.
 
-  @param[in]   Type             The type of event to create and its mode and attributes.
-  @param[in]   NotifyTpl        The task priority level of event notifications,if needed.
-  @param[in]   NotifyFunction   The pointer to the event's notification function, if any.
-  @param[in]   NotifyContext    The pointer to the notification function's context; corresponds to parameter
+  @param  Type                  The type of event to create and its mode and attributes.
+  @param  NotifyTpl             The task priority level of event notifications,if needed.
+  @param  NotifyFunction        The pointer to the event's notification function, if any.
+  @param  NotifyContext         The pointer to the notification function's context; corresponds to parameter
                                 Context in the notification function.
-  @param[in]   EventGroup       The pointer to the unique identifier of the group to which this event belongs.
+  @param  EventGroup            The pointer to the unique identifier of the group to which this event belongs.
                                 If this is NULL, then the function behaves as if the parameters were passed
                                 to CreateEvent.
-  @param[out]  Event            The pointer to the newly created event if the call succeeds; undefined
+  @param  Event                 The pointer to the newly created event if the call succeeds; undefined
                                 otherwise.
 
   @retval EFI_SUCCESS           The event structure was created.
@@ -496,9 +471,9 @@ typedef enum {
 /**
   Sets the type of timer and the trigger time for a timer event.
 
-  @param[in]  Event             The timer event that is to be signaled at the specified time.
-  @param[in]  Type              The type of time that is specified in TriggerTime.
-  @param[in]  TriggerTime       The number of 100ns units until the timer expires.
+  @param  Event                 The timer event that is to be signaled at the specified time.
+  @param  Type                  The type of time that is specified in TriggerTime.
+  @param  TriggerTime           The number of 100ns units until the timer expires.
                                 A TriggerTime of 0 is legal.
                                 If Type is TimerRelative and TriggerTime is 0, then the timer
                                 event will be signaled on the next timer tick.
@@ -520,7 +495,7 @@ EFI_STATUS
 /**
   Signals an event.
 
-  @param[in]  Event             The event to signal.
+  @param  Event                 The event to signal.
 
   @retval EFI_SUCCESS           The event has been signaled.
 
@@ -534,9 +509,9 @@ EFI_STATUS
 /**
   Stops execution until an event is signaled.
 
-  @param[in]   NumberOfEvents   The number of events in the Event array.
-  @param[in]   Event            An array of EFI_EVENT.
-  @param[out]  Index            The pointer to the index of the event which satisfied the wait condition.
+  @param  NumberOfEvents        The number of events in the Event array.
+  @param  Event                 An array of EFI_EVENT.
+  @param  Index                 The pointer to the index of the event which satisfied the wait condition.
 
   @retval EFI_SUCCESS           The event indicated by Index was signaled.
   @retval EFI_INVALID_PARAMETER 1) NumberOfEvents is 0.
@@ -556,7 +531,7 @@ EFI_STATUS
 /**
   Closes an event.
 
-  @param[in]  Event             The event to close.
+  @param  Event                 The event to close.
 
   @retval EFI_SUCCESS           The event has been closed.
 
@@ -570,7 +545,7 @@ EFI_STATUS
 /**
   Checks whether an event is in the signaled state.
 
-  @param[in]  Event             The event to check.
+  @param  Event                 The event to check.
 
   @retval EFI_SUCCESS           The event is in the signaled state.
   @retval EFI_NOT_READY         The event is not in the signaled state.
@@ -596,7 +571,7 @@ EFI_STATUS
 /**
   Raises a task's priority level and returns its previous level.
 
-  @param[in]  NewTpl          The new task priority level.
+  @param  NewTpl                The new task priority level.
 
   @return Previous task priority level
 
@@ -610,7 +585,7 @@ EFI_TPL
 /**
   Restores a task's priority level to its previous value.
 
-  @param[in]  OldTpl          The previous task priority level to restore.
+  @param  OldTpl                The previous task priority level to restore.
 
 **/
 typedef
@@ -622,15 +597,14 @@ VOID
 /**
   Returns the value of a variable.
 
-  @param[in]       VariableName  A Null-terminated string that is the name of the vendor's
-                                 variable.
-  @param[in]       VendorGuid    A unique identifier for the vendor.
-  @param[out]      Attributes    If not NULL, a pointer to the memory location to return the
-                                 attributes bitmask for the variable.
-  @param[in, out]  DataSize      On input, the size in bytes of the return Data buffer.
-                                 On output the size of data returned in Data.
-  @param[out]      Data          The buffer to return the contents of the variable. May be NULL
-                                 with a zero DataSize in order to determine the size buffer needed.
+  @param  VariableName          A Null-terminated string that is the name of the vendor's
+                                variable.
+  @param  VendorGuid            A unique identifier for the vendor.
+  @param  Attributes            If not NULL, a pointer to the memory location to return the
+                                attributes bitmask for the variable.
+  @param  DataSize              On input, the size in bytes of the return Data buffer.
+                                On output the size of data returned in Data.
+  @param  Data                  The buffer to return the contents of the variable.
 
   @retval EFI_SUCCESS            The function completed successfully.
   @retval EFI_NOT_FOUND          The variable was not found.
@@ -650,19 +624,19 @@ EFI_STATUS
   IN     EFI_GUID                    *VendorGuid,
   OUT    UINT32                      *Attributes,    OPTIONAL
   IN OUT UINTN                       *DataSize,
-  OUT    VOID                        *Data           OPTIONAL
+  OUT    VOID                        *Data
   );
 
 /**
   Enumerates the current variable names.
 
-  @param[in, out]  VariableNameSize The size of the VariableName buffer.
-  @param[in, out]  VariableName     On input, supplies the last VariableName that was returned
-                                    by GetNextVariableName(). On output, returns the Nullterminated
-                                    string of the current variable.
-  @param[in, out]  VendorGuid       On input, supplies the last VendorGuid that was returned by
-                                    GetNextVariableName(). On output, returns the
-                                    VendorGuid of the current variable.
+  @param  VariableNameSize      The size of the VariableName buffer.
+  @param  VariableName          On input, supplies the last VariableName that was returned
+                                by GetNextVariableName(). On output, returns the Nullterminated
+                                string of the current variable.
+  @param  VendorGuid            On input, supplies the last VendorGuid that was returned by
+                                GetNextVariableName(). On output, returns the
+                                VendorGuid of the current variable.
 
   @retval EFI_SUCCESS           The function completed successfully.
   @retval EFI_NOT_FOUND         The next variable was not found.
@@ -684,13 +658,13 @@ EFI_STATUS
 /**
   Sets the value of a variable.
 
-  @param[in]  VariableName       A Null-terminated string that is the name of the vendor's variable.
+  @param  VariableName           A Null-terminated string that is the name of the vendor's variable.
                                  Each VariableName is unique for each VendorGuid. VariableName must
                                  contain 1 or more characters. If VariableName is an empty string,
                                  then EFI_INVALID_PARAMETER is returned.
-  @param[in]  VendorGuid         A unique identifier for the vendor.
-  @param[in]  Attributes         Attributes bitmask to set for the variable.
-  @param[in]  DataSize           The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE,
+  @param  VendorGuid             A unique identifier for the vendor.
+  @param  Attributes             Attributes bitmask to set for the variable.
+  @param  DataSize               The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE,
                                  EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or
                                  EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero
                                  causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is
@@ -699,7 +673,7 @@ EFI_STATUS
                                  even if no new data value is provided,see the description of the
                                  EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not
                                  be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated).
-  @param[in]  Data               The contents for the variable.
+  @param  Data                   The contents for the variable.
 
   @retval EFI_SUCCESS            The firmware has successfully stored the variable and its data as
                                  defined by the Attributes.
@@ -761,8 +735,8 @@ typedef struct {
   Returns the current time and date information, and the time-keeping capabilities
   of the hardware platform.
 
-  @param[out]  Time             A pointer to storage to receive a snapshot of the current time.
-  @param[out]  Capabilities     An optional pointer to a buffer to receive the real time clock
+  @param  Time                  A pointer to storage to receive a snapshot of the current time.
+  @param  Capabilities          An optional pointer to a buffer to receive the real time clock
                                 device's capabilities.
 
   @retval EFI_SUCCESS           The operation completed successfully.
@@ -780,7 +754,7 @@ EFI_STATUS
 /**
   Sets the current local time and date information.
 
-  @param[in]  Time              A pointer to the current time.
+  @param  Time                  A pointer to the current time.
 
   @retval EFI_SUCCESS           The operation completed successfully.
   @retval EFI_INVALID_PARAMETER A time field is out of range.
@@ -796,9 +770,9 @@ EFI_STATUS
 /**
   Returns the current wakeup alarm clock setting.
 
-  @param[out]  Enabled          Indicates if the alarm is currently enabled or disabled.
-  @param[out]  Pending          Indicates if the alarm signal is pending and requires acknowledgement.
-  @param[out]  Time             The current alarm setting.
+  @param  Enabled               Indicates if the alarm is currently enabled or disabled.
+  @param  Pending               Indicates if the alarm signal is pending and requires acknowledgement.
+  @param  Time                  The current alarm setting.
 
   @retval EFI_SUCCESS           The alarm settings were returned.
   @retval EFI_INVALID_PARAMETER Enabled is NULL.
@@ -819,8 +793,8 @@ EFI_STATUS
 /**
   Sets the system wakeup alarm clock time.
 
-  @param[in]  Enable            Enable or disable the wakeup alarm.
-  @param[in]  Time              If Enable is TRUE, the time to set the wakeup alarm for.
+  @param  Enabled               Enable or disable the wakeup alarm.
+  @param  Time                  If Enable is TRUE, the time to set the wakeup alarm for.
                                 If Enable is FALSE, then this parameter is optional, and may be NULL.
 
   @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled. If
@@ -840,32 +814,32 @@ EFI_STATUS
 /**
   Loads an EFI image into memory.
 
-  @param[in]   BootPolicy        If TRUE, indicates that the request originates from the boot
-                                 manager, and that the boot manager is attempting to load
-                                 FilePath as a boot selection. Ignored if SourceBuffer is
-                                 not NULL.
-  @param[in]   ParentImageHandle The caller's image handle.
-  @param[in]   DevicePath        The DeviceHandle specific file path from which the image is
-                                 loaded.
-  @param[in]   SourceBuffer      If not NULL, a pointer to the memory location containing a copy
-                                 of the image to be loaded.
-  @param[in]   SourceSize        The size in bytes of SourceBuffer. Ignored if SourceBuffer is NULL.
-  @param[out]  ImageHandle       The pointer to the returned image handle that is created when the
-                                 image is successfully loaded.
-
-  @retval EFI_SUCCESS            Image was loaded into memory correctly.
-  @retval EFI_NOT_FOUND          Both SourceBuffer and DevicePath are NULL.
-  @retval EFI_INVALID_PARAMETER  One or more parametes are invalid.
-  @retval EFI_UNSUPPORTED        The image type is not supported.
-  @retval EFI_OUT_OF_RESOURCES   Image was not loaded due to insufficient resources.
-  @retval EFI_LOAD_ERROR         Image was not loaded because the image format was corrupt or not
-                                 understood.
-  @retval EFI_DEVICE_ERROR       Image was not loaded because the device returned a read error.
-  @retval EFI_ACCESS_DENIED      Image was not loaded because the platform policy prohibits the
-                                 image from being loaded. NULL is returned in *ImageHandle.
+  @param  BootPolicy            If TRUE, indicates that the request originates from the boot
+                                manager, and that the boot manager is attempting to load
+                                FilePath as a boot selection. Ignored if SourceBuffer is
+                                not NULL.
+  @param  ParentImageHandle     The caller's image handle.
+  @param  DevicePath            The DeviceHandle specific file path from which the image is
+                                loaded.
+  @param  SourceBuffer          If not NULL, a pointer to the memory location containing a copy
+                                of the image to be loaded.
+  @param  SourceSize            The size in bytes of SourceBuffer. Ignored if SourceBuffer is NULL.
+  @param  ImageHandle           The pointer to the returned image handle that is created when the
+                                image is successfully loaded.
+
+  @retval EFI_SUCCESS           Image was loaded into memory correctly.
+  @retval EFI_NOT_FOUND         Both SourceBuffer and DevicePath are NULL.
+  @retval EFI_INVALID_PARAMETER One or more parametes are invalid.
+  @retval EFI_UNSUPPORTED       The image type is not supported.
+  @retval EFI_OUT_OF_RESOURCES  Image was not loaded due to insufficient resources.
+  @retval EFI_LOAD_ERROR        Image was not loaded because the image format was corrupt or not
+                                understood.
+  @retval EFI_DEVICE_ERROR      Image was not loaded because the device returned a read error.
+  @retval EFI_ACCESS_DENIED     Image was not loaded because the platform policy prohibits the
+                                image from being loaded. NULL is returned in *ImageHandle.
   @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a
-                                 valid EFI_LOADED_IMAGE_PROTOCOL. However, the current
-                                 platform policy specifies that the image should not be started.
+                                valid EFI_LOADED_IMAGE_PROTOCOL. However, the current
+                                platform policy specifies that the image should not be started.
 **/
 typedef
 EFI_STATUS
@@ -881,10 +855,10 @@ EFI_STATUS
 /**
   Transfers control to a loaded image's entry point.
 
-  @param[in]   ImageHandle       Handle of image to be started.
-  @param[out]  ExitDataSize      The pointer to the size, in bytes, of ExitData.
-  @param[out]  ExitData          The pointer to a pointer to a data buffer that includes a Null-terminated
-                                 string, optionally followed by additional binary data.
+  @param  ImageHandle           Handle of image to be started.
+  @param  ExitDataSize          The pointer to the size, in bytes, of ExitData.
+  @param  ExitData              The pointer to a pointer to a data buffer that includes a Null-terminated
+                                string, optionally followed by additional binary data.
 
   @retval EFI_INVALID_PARAMETER  ImageHandle is either an invalid image handle or the image
                                  has already been initialized with StartImage.
@@ -903,11 +877,11 @@ EFI_STATUS
 /**
   Terminates a loaded EFI image and returns control to boot services.
 
-  @param[in]  ImageHandle       Handle that identifies the image. This parameter is passed to the
+  @param  ImageHandle           Handle that identifies the image. This parameter is passed to the
                                 image on entry.
-  @param[in]  ExitStatus        The image's exit code.
-  @param[in]  ExitDataSize      The size, in bytes, of ExitData. Ignored if ExitStatus is EFI_SUCCESS.
-  @param[in]  ExitData          The pointer to a data buffer that includes a Null-terminated string,
+  @param  ExitStatus            The image's exit code.
+  @param  ExitDataSize          The size, in bytes, of ExitData. Ignored if ExitStatus is EFI_SUCCESS.
+  @param  ExitData              The pointer to a data buffer that includes a Null-terminated string,
                                 optionally followed by additional binary data. The string is a
                                 description that the caller may use to further indicate the reason
                                 for the image's exit. ExitData is only valid if ExitStatus
@@ -932,7 +906,7 @@ EFI_STATUS
 /**
   Unloads an image.
 
-  @param[in]  ImageHandle       Handle that identifies the image to be unloaded.
+  @param  ImageHandle           Handle that identifies the image to be unloaded.
 
   @retval EFI_SUCCESS           The image has been unloaded.
   @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
@@ -947,8 +921,8 @@ EFI_STATUS
 /**
   Terminates all boot services.
 
-  @param[in]  ImageHandle       Handle that identifies the exiting image.
-  @param[in]  MapKey            Key to the latest memory map.
+  @param  ImageHandle           Handle that identifies the exiting image.
+  @param  MapKey                Key to the latest memory map.
 
   @retval EFI_SUCCESS           Boot services have been terminated.
   @retval EFI_INVALID_PARAMETER MapKey is incorrect.
@@ -964,7 +938,7 @@ EFI_STATUS
 /**
   Induces a fine-grained stall.
 
-  @param[in]  Microseconds      The number of microseconds to stall execution.
+  @param  Microseconds          The number of microseconds to stall execution.
 
   @retval EFI_SUCCESS           Execution was stalled at least the requested number of
                                 Microseconds.
@@ -979,10 +953,10 @@ EFI_STATUS
 /**
   Sets the system's watchdog timer.
 
-  @param[in]  Timeout           The number of seconds to set the watchdog timer to.
-  @param[in]  WatchdogCode      The numeric code to log on a watchdog timer timeout event.
-  @param[in]  DataSize          The size, in bytes, of WatchdogData.
-  @param[in]  WatchdogData      A data buffer that includes a Null-terminated string, optionally
+  @param  Timeout               The number of seconds to set the watchdog timer to.
+  @param  WatchdogCode          The numeric code to log on a watchdog timer timeout event.
+  @param  DataSize              The size, in bytes, of WatchdogData.
+  @param  WatchdogData          A data buffer that includes a Null-terminated string, optionally
                                 followed by additional binary data.
 
   @retval EFI_SUCCESS           The timeout has been set.
@@ -1001,13 +975,46 @@ EFI_STATUS
   IN CHAR16                   *WatchdogData OPTIONAL
   );
 
+///
+/// Enumeration of reset types.
+///
+typedef enum {
+  ///
+  /// Used to induce a system-wide reset. This sets all circuitry within the
+  /// system to its initial state.  This type of reset is asynchronous to system
+  /// operation and operates withgout regard to cycle boundaries.  EfiColdReset
+  /// is tantamount to a system power cycle.
+  ///
+  EfiResetCold,
+  ///
+  /// Used to induce a system-wide initialization. The processors are set to their
+  /// initial state, and pending cycles are not corrupted.  If the system does
+  /// not support this reset type, then an EfiResetCold must be performed.
+  ///
+  EfiResetWarm,
+  ///
+  /// Used to induce an entry into a power state equivalent to the ACPI G2/S5 or G3
+  /// state.  If the system does not support this reset type, then when the system
+  /// is rebooted, it should exhibit the EfiResetCold attributes.
+  ///
+  EfiResetShutdown,
+  ///
+  /// Used to induce a system-wide reset. The exact type of the reset is defined by
+  /// the EFI_GUID that follows the Null-terminated Unicode string passed into
+  /// ResetData. If the platform does not recognize the EFI_GUID in ResetData the
+  /// platform must pick a supported reset type to perform. The platform may
+  /// optionally log the parameters from any non-normal reset that occurs.
+  ///
+  EfiResetPlatformSpecific
+} EFI_RESET_TYPE;
+
 /**
   Resets the entire platform.
 
-  @param[in]  ResetType         The type of reset to perform.
-  @param[in]  ResetStatus       The status code for the reset.
-  @param[in]  DataSize          The size, in bytes, of WatchdogData.
-  @param[in]  ResetData         For a ResetType of EfiResetCold, EfiResetWarm, or
+  @param  ResetType             The type of reset to perform.
+  @param  ResetStatus           The status code for the reset.
+  @param  DataSize              The size, in bytes, of WatchdogData.
+  @param  ResetData             For a ResetType of EfiResetCold, EfiResetWarm, or
                                 EfiResetShutdown the data buffer starts with a Null-terminated
                                 string, optionally followed by additional binary data.
 
@@ -1024,7 +1031,7 @@ VOID
 /**
   Returns a monotonically increasing count for the platform.
 
-  @param[out]  Count            The pointer to returned value.
+  @param  Count                 The pointer to returned value.
 
   @retval EFI_SUCCESS           The next monotonic count was returned.
   @retval EFI_INVALID_PARAMETER Count is NULL.
@@ -1040,7 +1047,7 @@ EFI_STATUS
 /**
   Returns the next high 32 bits of the platform's monotonic counter.
 
-  @param[out]  HighCount        The pointer to returned value.
+  @param  HighCount             The pointer to returned value.
 
   @retval EFI_SUCCESS           The next high monotonic count was returned.
   @retval EFI_INVALID_PARAMETER HighCount is NULL.
@@ -1056,9 +1063,9 @@ EFI_STATUS
 /**
   Computes and returns a 32-bit CRC for a data buffer.
 
-  @param[in]   Data             A pointer to the buffer on which the 32-bit CRC is to be computed.
-  @param[in]   DataSize         The number of bytes in the buffer Data.
-  @param[out]  Crc32            The 32-bit CRC that was computed for the data buffer specified by Data
+  @param  Data                  A pointer to the buffer on which the 32-bit CRC is to be computed.
+  @param  DataSize              The number of bytes in the buffer Data.
+  @param  Crc32                 The 32-bit CRC that was computed for the data buffer specified by Data
                                 and DataSize.
 
   @retval EFI_SUCCESS           The 32-bit CRC was computed for the data buffer and returned in
@@ -1079,9 +1086,9 @@ EFI_STATUS
 /**
   Copies the contents of one buffer to another buffer.
 
-  @param[in]  Destination       The pointer to the destination buffer of the memory copy.
-  @param[in]  Source            The pointer to the source buffer of the memory copy.
-  @param[in]  Length            Number of bytes to copy from Source to Destination.
+  @param  Destination           The pointer to the destination buffer of the memory copy.
+  @param  Source                The pointer to the source buffer of the memory copy.
+  @param  Length                Number of bytes to copy from Source to Destination.
 
 **/
 typedef
@@ -1095,9 +1102,9 @@ VOID
 /**
   The SetMem() function fills a buffer with a specified value.
 
-  @param[in]  Buffer            The pointer to the buffer to fill.
-  @param[in]  Size              Number of bytes in Buffer to fill.
-  @param[in]  Value             Value to fill Buffer with.
+  @param  Buffer                The pointer to the buffer to fill.
+  @param  Size                  Number of bytes in Buffer to fill.
+  @param  Value                 Value to fill Buffer with.
 
 **/
 typedef
@@ -1125,10 +1132,10 @@ typedef enum {
   InstallMultipleProtocolInterfaces() be used in place of
   InstallProtocolInterface()
 
-  @param[in, out]  Handle         A pointer to the EFI_HANDLE on which the interface is to be installed.
-  @param[in]       Protocol       The numeric ID of the protocol interface.
-  @param[in]       InterfaceType  Indicates whether Interface is supplied in native form.
-  @param[in]       Interface      A pointer to the protocol interface.
+  @param  Handle                A pointer to the EFI_HANDLE on which the interface is to be installed.
+  @param  Protocol              The numeric ID of the protocol interface.
+  @param  InterfaceType         Indicates whether Interface is supplied in native form.
+  @param  Interface             A pointer to the protocol interface.
 
   @retval EFI_SUCCESS           The protocol interface was installed.
   @retval EFI_OUT_OF_RESOURCES  Space for a new handle could not be allocated.
@@ -1150,7 +1157,7 @@ EFI_STATUS
 /**
   Installs one or more protocol interfaces into the boot services environment.
 
-  @param[in, out]  Handle       The pointer to a handle to install the new protocol interfaces on,
+  @param  Handle                The pointer to a handle to install the new protocol interfaces on,
                                 or a pointer to NULL if a new handle is to be allocated.
   @param  ...                   A variable argument list containing pairs of protocol GUIDs and protocol
                                 interfaces.
@@ -1173,11 +1180,11 @@ EFI_STATUS
 /**
   Reinstalls a protocol interface on a device handle.
 
-  @param[in]  Handle            Handle on which the interface is to be reinstalled.
-  @param[in]  Protocol          The numeric ID of the interface.
-  @param[in]  OldInterface      A pointer to the old interface. NULL can be used if a structure is not
+  @param  Handle                Handle on which the interface is to be reinstalled.
+  @param  Protocol              The numeric ID of the interface.
+  @param  OldInterface          A pointer to the old interface. NULL can be used if a structure is not
                                 associated with Protocol.
-  @param[in]  NewInterface      A pointer to the new interface.
+  @param  NewInterface          A pointer to the new interface.
 
   @retval EFI_SUCCESS           The protocol interface was reinstalled.
   @retval EFI_NOT_FOUND         The OldInterface on the handle was not found.
@@ -1202,9 +1209,9 @@ EFI_STATUS
   UninstallMultipleProtocolInterfaces() be used in place of
   UninstallProtocolInterface().
 
-  @param[in]  Handle            The handle on which the interface was installed.
-  @param[in]  Protocol          The numeric ID of the interface.
-  @param[in]  Interface         A pointer to the interface.
+  @param  Handle                The handle on which the interface was installed.
+  @param  Protocol              The numeric ID of the interface.
+  @param  Interface             A pointer to the interface.
 
   @retval EFI_SUCCESS           The interface was removed.
   @retval EFI_NOT_FOUND         The interface was not found.
@@ -1225,7 +1232,7 @@ EFI_STATUS
 /**
   Removes one or more protocol interfaces into the boot services environment.
 
-  @param[in]  Handle            The handle to remove the protocol interfaces from.
+  @param  Handle                The handle to remove the protocol interfaces from.
   @param  ...                   A variable argument list containing pairs of protocol GUIDs and
                                 protocol interfaces.
 
@@ -1243,9 +1250,9 @@ EFI_STATUS
 /**
   Queries a handle to determine if it supports a specified protocol.
 
-  @param[in]   Handle           The handle being queried.
-  @param[in]   Protocol         The published unique identifier of the protocol.
-  @param[out]  Interface        Supplies the address where a pointer to the corresponding Protocol
+  @param  Handle                The handle being queried.
+  @param  Protocol              The published unique identifier of the protocol.
+  @param  Interface             Supplies the address where a pointer to the corresponding Protocol
                                 Interface is returned.
 
   @retval EFI_SUCCESS           The interface information for the specified protocol was returned.
@@ -1274,18 +1281,18 @@ EFI_STATUS
   Queries a handle to determine if it supports a specified protocol. If the protocol is supported by the
   handle, it opens the protocol on behalf of the calling agent.
 
-  @param[in]   Handle           The handle for the protocol interface that is being opened.
-  @param[in]   Protocol         The published unique identifier of the protocol.
-  @param[out]  Interface        Supplies the address where a pointer to the corresponding Protocol
+  @param  Handle                The handle for the protocol interface that is being opened.
+  @param  Protocol              The published unique identifier of the protocol.
+  @param  Interface             Supplies the address where a pointer to the corresponding Protocol
                                 Interface is returned.
-  @param[in]   AgentHandle      The handle of the agent that is opening the protocol interface
+  @param  AgentHandle           The handle of the agent that is opening the protocol interface
                                 specified by Protocol and Interface.
-  @param[in]   ControllerHandle If the agent that is opening a protocol is a driver that follows the
+  @param  ControllerHandle      If the agent that is opening a protocol is a driver that follows the
                                 UEFI Driver Model, then this parameter is the controller handle
                                 that requires the protocol interface. If the agent does not follow
                                 the UEFI Driver Model, then this parameter is optional and may
                                 be NULL.
-  @param[in]   Attributes       The open mode of the protocol interface specified by Handle
+  @param  Attributes            The open mode of the protocol interface specified by Handle
                                 and Protocol.
 
   @retval EFI_SUCCESS           An item was added to the open list for the protocol interface, and the
@@ -1312,11 +1319,11 @@ EFI_STATUS
 /**
   Closes a protocol on a handle that was opened using OpenProtocol().
 
-  @param[in]  Handle            The handle for the protocol interface that was previously opened
+  @param  Handle                The handle for the protocol interface that was previously opened
                                 with OpenProtocol(), and is now being closed.
-  @param[in]  Protocol          The published unique identifier of the protocol.
-  @param[in]  AgentHandle       The handle of the agent that is closing the protocol interface.
-  @param[in]  ControllerHandle  If the agent that opened a protocol is a driver that follows the
+  @param  Protocol              The published unique identifier of the protocol.
+  @param  AgentHandle           The handle of the agent that is closing the protocol interface.
+  @param  ControllerHandle      If the agent that opened a protocol is a driver that follows the
                                 UEFI Driver Model, then this parameter is the controller handle
                                 that required the protocol interface.
 
@@ -1352,11 +1359,11 @@ typedef struct {
 /**
   Retrieves the list of agents that currently have a protocol interface opened.
 
-  @param[in]   Handle           The handle for the protocol interface that is being queried.
-  @param[in]   Protocol         The published unique identifier of the protocol.
-  @param[out]  EntryBuffer      A pointer to a buffer of open protocol information in the form of
+  @param  Handle                The handle for the protocol interface that is being queried.
+  @param  Protocol              The published unique identifier of the protocol.
+  @param  EntryBuffer           A pointer to a buffer of open protocol information in the form of
                                 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.
-  @param[out]  EntryCount       A pointer to the number of entries in EntryBuffer.
+  @param  EntryCount            A pointer to the number of entries in EntryBuffer.
 
   @retval EFI_SUCCESS           The open protocol information was returned in EntryBuffer, and the
                                 number of entries was returned EntryCount.
@@ -1377,12 +1384,12 @@ EFI_STATUS
   Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated
   from pool.
 
-  @param[in]   Handle              The handle from which to retrieve the list of protocol interface
-                                   GUIDs.
-  @param[out]  ProtocolBuffer      A pointer to the list of protocol interface GUID pointers that are
-                                   installed on Handle.
-  @param[out]  ProtocolBufferCount A pointer to the number of GUID pointers present in
-                                   ProtocolBuffer.
+  @param  Handle                The handle from which to retrieve the list of protocol interface
+                                GUIDs.
+  @param  ProtocolBuffer        A pointer to the list of protocol interface GUID pointers that are
+                                installed on Handle.
+  @param  ProtocolBufferCount   A pointer to the number of GUID pointers present in
+                                ProtocolBuffer.
 
   @retval EFI_SUCCESS           The list of protocol interface GUIDs installed on Handle was returned in
                                 ProtocolBuffer. The number of protocol interface GUIDs was
@@ -1405,10 +1412,10 @@ EFI_STATUS
 /**
   Creates an event that is to be signaled whenever an interface is installed for a specified protocol.
 
-  @param[in]   Protocol         The numeric ID of the protocol for which the event is to be registered.
-  @param[in]   Event            Event that is to be signaled whenever a protocol interface is registered
+  @param  Protocol              The numeric ID of the protocol for which the event is to be registered.
+  @param  Event                 Event that is to be signaled whenever a protocol interface is registered
                                 for Protocol.
-  @param[out]  Registration     A pointer to a memory location to receive the registration value.
+  @param  Registration          A pointer to a memory location to receive the registration value.
 
   @retval EFI_SUCCESS           The notification event has been registered.
   @retval EFI_OUT_OF_RESOURCES  Space for the notification event could not be allocated.
@@ -1447,14 +1454,14 @@ typedef enum {
 /**
   Returns an array of handles that support a specified protocol.
 
-  @param[in]       SearchType   Specifies which handle(s) are to be returned.
-  @param[in]       Protocol     Specifies the protocol to search by.
-  @param[in]       SearchKey    Specifies the search key.
-  @param[in, out]  BufferSize   On input, the size in bytes of Buffer. On output, the size in bytes of
+  @param  SearchType            Specifies which handle(s) are to be returned.
+  @param  Protocol              Specifies the protocol to search by.
+  @param  SearchKey             Specifies the search key.
+  @param  BufferSize            On input, the size in bytes of Buffer. On output, the size in bytes of
                                 the array returned in Buffer (if the buffer was large enough) or the
                                 size, in bytes, of the buffer needed to obtain the array (if the buffer was
                                 not large enough).
-  @param[out]      Buffer       The buffer in which the array is returned.
+  @param  Buffer                The buffer in which the array is returned.
 
   @retval EFI_SUCCESS           The array of handles was returned.
   @retval EFI_NOT_FOUND         No handles match the search.
@@ -1479,11 +1486,11 @@ EFI_STATUS
 /**
   Locates the handle to a device on the device path that supports the specified protocol.
 
-  @param[in]       Protocol     Specifies the protocol to search for.
-  @param[in, out]  DevicePath   On input, a pointer to a pointer to the device path. On output, the device
+  @param  Protocol              Specifies the protocol to search for.
+  @param  DevicePath            On input, a pointer to a pointer to the device path. On output, the device
                                 path pointer is modified to point to the remaining part of the device
                                 path.
-  @param[out]      Device       A pointer to the returned device handle.
+  @param  Device                A pointer to the returned device handle.
 
   @retval EFI_SUCCESS           The resulting handle was returned.
   @retval EFI_NOT_FOUND         No handles match the search.
@@ -1503,8 +1510,8 @@ EFI_STATUS
 /**
   Adds, updates, or removes a configuration table entry from the EFI System Table.
 
-  @param[in]  Guid              A pointer to the GUID for the entry to add, update, or remove.
-  @param[in]  Table             A pointer to the configuration table for the entry to add, update, or
+  @param  Guid                  A pointer to the GUID for the entry to add, update, or remove.
+  @param  Table                 A pointer to the configuration table for the entry to add, update, or
                                 remove. May be NULL.
 
   @retval EFI_SUCCESS           The (Guid, Table) pair was added, updated, or removed.
@@ -1523,12 +1530,12 @@ EFI_STATUS
 /**
   Returns an array of handles that support the requested protocol in a buffer allocated from pool.
 
-  @param[in]       SearchType   Specifies which handle(s) are to be returned.
-  @param[in]       Protocol     Provides the protocol to search by.
+  @param  SearchType            Specifies which handle(s) are to be returned.
+  @param  Protocol              Provides the protocol to search by.
                                 This parameter is only valid for a SearchType of ByProtocol.
-  @param[in]       SearchKey    Supplies the search key depending on the SearchType.
-  @param[in, out]  NoHandles    The number of handles returned in Buffer.
-  @param[out]      Buffer       A pointer to the buffer to return the requested array of handles that
+  @param  SearchKey             Supplies the search key depending on the SearchType.
+  @param  NoHandles             The number of handles returned in Buffer.
+  @param  Buffer                A pointer to the buffer to return the requested array of handles that
                                 support Protocol.
 
   @retval EFI_SUCCESS           The array of handles was returned in Buffer, and the number of
@@ -1552,10 +1559,10 @@ EFI_STATUS
 /**
   Returns the first protocol instance that matches the given protocol.
 
-  @param[in]  Protocol          Provides the protocol to search for.
-  @param[in]  Registration      Optional registration key returned from
+  @param  Protocol              Provides the protocol to search for.
+  @param  Registration          Optional registration key returned from
                                 RegisterProtocolNotify().
-  @param[out]  Interface        On return, a pointer to the first interface that matches Protocol and
+  @param  Interface             On return, a pointer to the first interface that matches Protocol and
                                 Registration.
 
   @retval EFI_SUCCESS           A protocol instance matching Protocol was found and returned in
@@ -1650,13 +1657,13 @@ typedef struct {
   be passed into ResetSystem() and will cause the capsule to be processed by the firmware as
   part of the reset process.
 
-  @param[in]  CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules
-                                 being passed into update capsule.
-  @param[in]  CapsuleCount       Number of pointers to EFI_CAPSULE_HEADER in
-                                 CaspuleHeaderArray.
-  @param[in]  ScatterGatherList  Physical pointer to a set of
-                                 EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the
-                                 location in physical memory of a set of capsules.
+  @param  CapsuleHeaderArray    Virtual pointer to an array of virtual pointers to the capsules
+                                being passed into update capsule.
+  @param  CapsuleCount          Number of pointers to EFI_CAPSULE_HEADER in
+                                CaspuleHeaderArray.
+  @param  ScatterGatherList     Physical pointer to a set of
+                                EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the
+                                location in physical memory of a set of capsules.
 
   @retval EFI_SUCCESS           Valid capsule was passed. If
                                 CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the
@@ -1684,14 +1691,14 @@ EFI_STATUS
 /**
   Returns if the capsule can be supported via UpdateCapsule().
 
-  @param[in]   CapsuleHeaderArray  Virtual pointer to an array of virtual pointers to the capsules
-                                   being passed into update capsule.
-  @param[in]   CapsuleCount        Number of pointers to EFI_CAPSULE_HEADER in
-                                   CaspuleHeaderArray.
-  @param[out]  MaxiumCapsuleSize   On output the maximum size that UpdateCapsule() can
-                                   support as an argument to UpdateCapsule() via
-                                   CapsuleHeaderArray and ScatterGatherList.
-  @param[out]  ResetType           Returns the type of reset required for the capsule update.
+  @param  CapsuleHeaderArray    Virtual pointer to an array of virtual pointers to the capsules
+                                being passed into update capsule.
+  @param  CapsuleCount          Number of pointers to EFI_CAPSULE_HEADER in
+                                CaspuleHeaderArray.
+  @param  MaxiumCapsuleSize     On output the maximum size that UpdateCapsule() can
+                                support as an argument to UpdateCapsule() via
+                                CapsuleHeaderArray and ScatterGatherList.
+  @param  ResetType             Returns the type of reset required for the capsule update.
 
   @retval EFI_SUCCESS           Valid answer returned.
   @retval EFI_UNSUPPORTED       The capsule type is not supported on this platform, and
@@ -1716,16 +1723,16 @@ EFI_STATUS
 /**
   Returns information about the EFI variables.
 
-  @param[in]   Attributes                   Attributes bitmask to specify the type of variables on
-                                            which to return information.
-  @param[out]  MaximumVariableStorageSize   On output the maximum size of the storage space
-                                            available for the EFI variables associated with the
-                                            attributes specified.
-  @param[out]  RemainingVariableStorageSize Returns the remaining size of the storage space
-                                            available for the EFI variables associated with the
-                                            attributes specified.
-  @param[out]  MaximumVariableSize          Returns the maximum size of the individual EFI
-                                            variables associated with the attributes specified.
+  @param  Attributes                   Attributes bitmask to specify the type of variables on
+                                       which to return information.
+  @param  MaximumVariableStorageSize   On output the maximum size of the storage space
+                                       available for the EFI variables associated with the
+                                       attributes specified.
+  @param  RemainingVariableStorageSize Returns the remaining size of the storage space
+                                       available for the EFI variables associated with the
+                                       attributes specified.
+  @param  MaximumVariableSize          Returns the maximum size of the individual EFI
+                                       variables associated with the attributes specified.
 
   @retval EFI_SUCCESS                  Valid answer returned.
   @retval EFI_INVALID_PARAMETER        An invalid combination of attribute bits was supplied
@@ -1752,14 +1759,11 @@ EFI_STATUS
 #define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED  0x0000000000000004
 #define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED            0x0000000000000008
 #define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED     0x0000000000000010
-#define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY          0x0000000000000040
 
 //
 // EFI Runtime Services Table
 //
 #define EFI_SYSTEM_TABLE_SIGNATURE      SIGNATURE_64 ('I','B','I',' ','S','Y','S','T')
-#define EFI_2_60_SYSTEM_TABLE_REVISION  ((2 << 16) | (60))
-#define EFI_2_50_SYSTEM_TABLE_REVISION  ((2 << 16) | (50))
 #define EFI_2_40_SYSTEM_TABLE_REVISION  ((2 << 16) | (40))
 #define EFI_2_31_SYSTEM_TABLE_REVISION  ((2 << 16) | (31))
 #define EFI_2_30_SYSTEM_TABLE_REVISION  ((2 << 16) | (30))
@@ -1768,7 +1772,7 @@ EFI_STATUS
 #define EFI_2_00_SYSTEM_TABLE_REVISION  ((2 << 16) | (00))
 #define EFI_1_10_SYSTEM_TABLE_REVISION  ((1 << 16) | (10))
 #define EFI_1_02_SYSTEM_TABLE_REVISION  ((1 << 16) | (02))
-#define EFI_SYSTEM_TABLE_REVISION       EFI_2_60_SYSTEM_TABLE_REVISION
+#define EFI_SYSTEM_TABLE_REVISION       EFI_2_40_SYSTEM_TABLE_REVISION
 #define EFI_SPECIFICATION_VERSION       EFI_SYSTEM_TABLE_REVISION
 
 #define EFI_RUNTIME_SERVICES_SIGNATURE  SIGNATURE_64 ('R','U','N','T','S','E','R','V')
@@ -2010,8 +2014,8 @@ typedef struct {
   the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
   both device drivers and bus drivers.
 
-  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
-  @param[in]  SystemTable       A pointer to the EFI System Table.
+  @param  ImageHandle           The firmware allocated handle for the UEFI image.
+  @param  SystemTable           A pointer to the EFI System Table.
 
   @retval EFI_SUCCESS           The operation completed successfully.
   @retval Others                An unexpected error occurred.
@@ -2024,69 +2028,19 @@ EFI_STATUS
   );
 
 //
-// EFI Load Option. This data structure describes format of UEFI boot option variables.
-//
-// NOTE: EFI Load Option is a byte packed buffer of variable length fields.
-// The first two fields have fixed length. They are declared as members of the
-// EFI_LOAD_OPTION structure. All the other fields are variable length fields.
-// They are listed in the comment block below for reference purposes.
-//
-#pragma pack(1)
-typedef struct _EFI_LOAD_OPTION {
-  ///
-  /// The attributes for this load option entry. All unused bits must be zero
-  /// and are reserved by the UEFI specification for future growth.
-  ///
-  UINT32                           Attributes;
-  ///
-  /// Length in bytes of the FilePathList. OptionalData starts at offset
-  /// sizeof(UINT32) + sizeof(UINT16) + StrSize(Description) + FilePathListLength
-  /// of the EFI_LOAD_OPTION descriptor.
-  ///
-  UINT16                           FilePathListLength;
-  ///
-  /// The user readable description for the load option.
-  /// This field ends with a Null character.
-  ///
-  // CHAR16                        Description[];
-  ///
-  /// A packed array of UEFI device paths. The first element of the array is a
-  /// device path that describes the device and location of the Image for this
-  /// load option. The FilePathList[0] is specific to the device type. Other
-  /// device paths may optionally exist in the FilePathList, but their usage is
-  /// OSV specific. Each element in the array is variable length, and ends at
-  /// the device path end structure. Because the size of Description is
-  /// arbitrary, this data structure is not guaranteed to be aligned on a
-  /// natural boundary. This data structure may have to be copied to an aligned
-  /// natural boundary before it is used.
-  ///
-  // EFI_DEVICE_PATH_PROTOCOL      FilePathList[];
-  ///
-  /// The remaining bytes in the load option descriptor are a binary data buffer
-  /// that is passed to the loaded image. If the field is zero bytes long, a
-  /// NULL pointer is passed to the loaded image. The number of bytes in
-  /// OptionalData can be computed by subtracting the starting offset of
-  /// OptionalData from total size in bytes of the EFI_LOAD_OPTION.
-  ///
-  // UINT8                         OptionalData[];
-} EFI_LOAD_OPTION;
-#pragma pack()
-
-//
 // EFI Load Options Attributes
 //
-#define LOAD_OPTION_ACTIVE              0x00000001
-#define LOAD_OPTION_FORCE_RECONNECT     0x00000002
-#define LOAD_OPTION_HIDDEN              0x00000008
-#define LOAD_OPTION_CATEGORY            0x00001F00
-
-#define LOAD_OPTION_CATEGORY_BOOT       0x00000000
-#define LOAD_OPTION_CATEGORY_APP        0x00000100
-
-#define EFI_BOOT_OPTION_SUPPORT_KEY     0x00000001
-#define EFI_BOOT_OPTION_SUPPORT_APP     0x00000002
-#define EFI_BOOT_OPTION_SUPPORT_SYSPREP 0x00000010
-#define EFI_BOOT_OPTION_SUPPORT_COUNT   0x00000300
+#define LOAD_OPTION_ACTIVE            0x00000001
+#define LOAD_OPTION_FORCE_RECONNECT   0x00000002
+#define LOAD_OPTION_HIDDEN            0x00000008
+#define LOAD_OPTION_CATEGORY          0x00001F00
+
+#define LOAD_OPTION_CATEGORY_BOOT     0x00000000
+#define LOAD_OPTION_CATEGORY_APP      0x00000100
+
+#define EFI_BOOT_OPTION_SUPPORT_KEY   0x00000001
+#define EFI_BOOT_OPTION_SUPPORT_APP   0x00000002
+#define EFI_BOOT_OPTION_SUPPORT_COUNT 0x00000300
 
 ///
 /// EFI Boot Key Data
index b64c25c..4f21bb8 100644 (file)
@@ -1,7 +1,7 @@
 /** @file
   Processor or Compiler specific defines and types x64 (Intel 64, AMD64).
 
-  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -96,26 +96,6 @@ FILE_LICENCE ( BSD3 );
 //
 #pragma warning ( disable : 4206 )
 
-#if _MSC_VER == 1800 || _MSC_VER == 1900
-
-//
-// Disable these warnings for VS2013.
-//
-
-//
-// This warning is for potentially uninitialized local variable, and it may cause false
-// positive issues in VS2013 and VS2015 build
-//
-#pragma warning ( disable : 4701 )
-
-//
-// This warning is for potentially uninitialized local pointer variable, and it may cause
-// false positive issues in VS2013 and VS2015 build
-//
-#pragma warning ( disable : 4703 )
-
-#endif
-
 #endif
 
 
@@ -271,12 +251,12 @@ typedef INT64   INTN;
   ///
 #elif defined(_MSC_EXTENSIONS)
   ///
-  /// Microsoft* compiler specific method for EFIAPI calling convention.
+  /// Microsoft* compiler specific method for EFIAPI calling convension
   ///
   #define EFIAPI __cdecl
 #elif defined(__GNUC__)
   ///
-  /// Define the standard calling convention regardless of optimization level.
+  /// Define the standard calling convention reguardless of optimization level.
   /// The GCC support assumes a GCC compiler that supports the EFI ABI. The EFI
   /// ABI is much closer to the x64 Microsoft* ABI than standard x64 (x86-64)
   /// GCC ABI. Thus a standard x64 (x86-64) GCC compiler can not be used for
index db9943a..ab52dd9 100644 (file)
@@ -153,15 +153,12 @@ struct efi_config_table {
  */
 #define EEFI( efirc ) EPLATFORM ( EINFO_EPLATFORM, efirc )
 
-extern EFI_GUID efi_absolute_pointer_protocol_guid;
-extern EFI_GUID efi_apple_net_boot_protocol_guid;
 extern EFI_GUID efi_arp_protocol_guid;
 extern EFI_GUID efi_arp_service_binding_protocol_guid;
 extern EFI_GUID efi_block_io_protocol_guid;
 extern EFI_GUID efi_bus_specific_driver_override_protocol_guid;
 extern EFI_GUID efi_component_name_protocol_guid;
 extern EFI_GUID efi_component_name2_protocol_guid;
-extern EFI_GUID efi_console_control_protocol_guid;
 extern EFI_GUID efi_device_path_protocol_guid;
 extern EFI_GUID efi_dhcp4_protocol_guid;
 extern EFI_GUID efi_dhcp4_service_binding_protocol_guid;
@@ -169,7 +166,6 @@ extern EFI_GUID efi_disk_io_protocol_guid;
 extern EFI_GUID efi_driver_binding_protocol_guid;
 extern EFI_GUID efi_graphics_output_protocol_guid;
 extern EFI_GUID efi_hii_config_access_protocol_guid;
-extern EFI_GUID efi_hii_font_protocol_guid;
 extern EFI_GUID efi_ip4_protocol_guid;
 extern EFI_GUID efi_ip4_config_protocol_guid;
 extern EFI_GUID efi_ip4_service_binding_protocol_guid;
@@ -186,43 +182,23 @@ extern EFI_GUID efi_nii31_protocol_guid;
 extern EFI_GUID efi_pci_io_protocol_guid;
 extern EFI_GUID efi_pci_root_bridge_io_protocol_guid;
 extern EFI_GUID efi_pxe_base_code_protocol_guid;
-extern EFI_GUID efi_serial_io_protocol_guid;
 extern EFI_GUID efi_simple_file_system_protocol_guid;
 extern EFI_GUID efi_simple_network_protocol_guid;
-extern EFI_GUID efi_simple_pointer_protocol_guid;
-extern EFI_GUID efi_simple_text_input_protocol_guid;
-extern EFI_GUID efi_simple_text_input_ex_protocol_guid;
-extern EFI_GUID efi_simple_text_output_protocol_guid;
 extern EFI_GUID efi_tcg_protocol_guid;
 extern EFI_GUID efi_tcp4_protocol_guid;
 extern EFI_GUID efi_tcp4_service_binding_protocol_guid;
-extern EFI_GUID efi_tree_protocol_guid;
 extern EFI_GUID efi_udp4_protocol_guid;
 extern EFI_GUID efi_udp4_service_binding_protocol_guid;
-extern EFI_GUID efi_uga_draw_protocol_guid;
-extern EFI_GUID efi_unicode_collation_protocol_guid;
-extern EFI_GUID efi_usb_hc_protocol_guid;
-extern EFI_GUID efi_usb2_hc_protocol_guid;
-extern EFI_GUID efi_usb_io_protocol_guid;
 extern EFI_GUID efi_vlan_config_protocol_guid;
 
-extern EFI_GUID efi_file_info_id;
-extern EFI_GUID efi_file_system_info_id;
-
 extern EFI_HANDLE efi_image_handle;
 extern EFI_LOADED_IMAGE_PROTOCOL *efi_loaded_image;
 extern EFI_DEVICE_PATH_PROTOCOL *efi_loaded_image_path;
 extern EFI_SYSTEM_TABLE *efi_systab;
 
-extern const __attribute__ (( pure )) char * efi_guid_ntoa ( EFI_GUID *guid );
-extern const __attribute__ (( pure )) char *
-efi_locate_search_type_name ( EFI_LOCATE_SEARCH_TYPE search_type );
-extern const __attribute__ (( pure )) char *
-efi_open_attributes_name ( unsigned int attributes );
-extern const __attribute__ (( pure )) char *
-efi_devpath_text ( EFI_DEVICE_PATH_PROTOCOL *path );
-extern const __attribute__ (( pure )) char *
-efi_handle_name ( EFI_HANDLE handle );
+extern const char * efi_guid_ntoa ( EFI_GUID *guid );
+extern const char * efi_devpath_text ( EFI_DEVICE_PATH_PROTOCOL *path );
+extern const char * efi_handle_name ( EFI_HANDLE handle );
 
 extern void dbg_efi_openers ( EFI_HANDLE handle, EFI_GUID *protocol );
 extern void dbg_efi_protocols ( EFI_HANDLE handle );
index 74ece90..f497df3 100644 (file)
@@ -19,8 +19,6 @@ struct efi_device {
        struct device dev;
        /** EFI device handle */
        EFI_HANDLE device;
-       /** EFI device path copy */
-       EFI_DEVICE_PATH_PROTOCOL *path;
        /** Driver for this device */
        struct efi_driver *driver;
        /** Driver-private data */
diff --git a/roms/ipxe/src/include/ipxe/efi/efi_pxe.h b/roms/ipxe/src/include/ipxe/efi/efi_pxe.h
deleted file mode 100644 (file)
index b356f37..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _IPXE_EFI_PXE_H
-#define _IPXE_EFI_PXE_H
-
-/** @file
- *
- * EFI PXE base code protocol
- */
-
-#include <ipxe/efi/efi.h>
-#include <ipxe/netdevice.h>
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-extern int efi_pxe_install ( EFI_HANDLE handle, struct net_device *netdev );
-extern void efi_pxe_uninstall ( EFI_HANDLE handle );
-
-#endif /* _IPXE_EFI_PXE_H */
index 4c5461e..1e5c666 100644 (file)
@@ -73,14 +73,14 @@ extern int efi_snp_hii_install ( struct efi_snp_device *snpdev );
 extern void efi_snp_hii_uninstall ( struct efi_snp_device *snpdev );
 extern struct efi_snp_device * find_snpdev ( EFI_HANDLE handle );
 extern struct efi_snp_device * last_opened_snpdev ( void );
-extern void efi_snp_add_claim ( int delta );
+extern void efi_snp_set_claimed ( int claimed );
 
 /**
  * Claim network devices for use by iPXE
  *
  */
 static inline void efi_snp_claim ( void ) {
-       efi_snp_add_claim ( +1 );
+       efi_snp_set_claimed ( 1 );
 }
 
 /**
@@ -88,7 +88,7 @@ static inline void efi_snp_claim ( void ) {
  *
  */
 static inline void efi_snp_release ( void ) {
-       efi_snp_add_claim ( -1 );
+       efi_snp_set_claimed ( 0 );
 }
 
 #endif /* _IPXE_EFI_SNP_H */
index c498759..c037653 100644 (file)
@@ -15,22 +15,4 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define TIMER_PREFIX_efi __efi_
 #endif
 
-/**
- * Number of ticks per second
- *
- * This is a policy decision.
- */
-#define EFI_TICKS_PER_SEC 20
-
-/**
- * Get number of ticks per second
- *
- * @ret ticks_per_sec  Number of ticks per second
- */
-static inline __attribute__ (( always_inline )) unsigned long
-TIMER_INLINE ( efi, ticks_per_sec ) ( void ) {
-
-       return EFI_TICKS_PER_SEC;
-}
-
 #endif /* _IPXE_EFI_TIMER_H */
diff --git a/roms/ipxe/src/include/ipxe/efi/efi_usb.h b/roms/ipxe/src/include/ipxe/efi/efi_usb.h
deleted file mode 100644 (file)
index 05b4fad..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef _IPXE_EFI_USB_H
-#define _IPXE_EFI_USB_H
-
-/** @file
- *
- * USB I/O protocol
- *
- */
-
-#include <ipxe/list.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_driver.h>
-#include <ipxe/efi/Protocol/UsbIo.h>
-#include <ipxe/usb.h>
-
-/** An EFI USB device */
-struct efi_usb_device {
-       /** Name */
-       const char *name;
-       /** The underlying USB device */
-       struct usb_device *usb;
-       /** The underlying EFI device */
-       struct efi_device *efidev;
-       /** Configuration descriptor */
-       struct usb_configuration_descriptor *config;
-       /** Supported languages */
-       struct usb_descriptor_header *languages;
-       /** List of interfaces */
-       struct list_head interfaces;
-};
-
-/** An EFI USB device interface */
-struct efi_usb_interface {
-       /** Name */
-       char name[32];
-       /** Containing USB device */
-       struct efi_usb_device *usbdev;
-       /** List of interfaces */
-       struct list_head list;
-
-       /** Interface number */
-       unsigned int interface;
-       /** Alternate setting */
-       unsigned int alternate;
-       /** EFI handle */
-       EFI_HANDLE handle;
-       /** USB I/O protocol */
-       EFI_USB_IO_PROTOCOL usbio;
-       /** Device path */
-       EFI_DEVICE_PATH_PROTOCOL *path;
-
-       /** Opened endpoints */
-       struct efi_usb_endpoint *endpoint[32];
-};
-
-/** An EFI USB device endpoint */
-struct efi_usb_endpoint {
-       /** EFI USB device interface */
-       struct efi_usb_interface *usbintf;
-       /** USB endpoint */
-       struct usb_endpoint ep;
-
-       /** Most recent synchronous completion status */
-       int rc;
-
-       /** Asynchronous timer event */
-       EFI_EVENT event;
-       /** Asynchronous callback handler */
-       EFI_ASYNC_USB_TRANSFER_CALLBACK callback;
-       /** Asynchronous callback context */
-       void *context;
-};
-
-/** Asynchronous transfer fill level
- *
- * This is a policy decision.
- */
-#define EFI_USB_ASYNC_FILL 2
-
-#endif /* _IPXE_EFI_USB_H */
index 67acba1..57268da 100644 (file)
@@ -15,7 +15,6 @@ struct device;
 
 extern EFI_DEVICE_PATH_PROTOCOL *
 efi_devpath_end ( EFI_DEVICE_PATH_PROTOCOL *path );
-extern size_t efi_devpath_len ( EFI_DEVICE_PATH_PROTOCOL *path );
 extern int efi_locate_device ( EFI_HANDLE device, EFI_GUID *protocol,
                               EFI_HANDLE *parent );
 extern int efi_child_add ( EFI_HANDLE parent, EFI_HANDLE child );
diff --git a/roms/ipxe/src/include/ipxe/eoib.h b/roms/ipxe/src/include/ipxe/eoib.h
deleted file mode 100644 (file)
index 93f496c..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef _IPXE_EOIB_H
-#define _IPXE_EOIB_H
-
-/** @file
- *
- * Ethernet over Infiniband
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <byteswap.h>
-#include <ipxe/netdevice.h>
-#include <ipxe/infiniband.h>
-#include <ipxe/ib_mcast.h>
-
-/** An EoIB header */
-struct eoib_header {
-       /** Signature */
-       uint16_t magic;
-       /** Reserved */
-       uint16_t reserved;
-} __attribute__ (( packed ));
-
-/** EoIB magic signature */
-#define EOIB_MAGIC 0x8919
-
-/** An EoIB device */
-struct eoib_device {
-       /** Name */
-       const char *name;
-       /** Network device */
-       struct net_device *netdev;
-       /** Underlying Infiniband device */
-       struct ib_device *ibdev;
-       /** List of EoIB devices */
-       struct list_head list;
-       /** Broadcast address */
-       struct ib_address_vector broadcast;
-
-       /** Completion queue */
-       struct ib_completion_queue *cq;
-       /** Queue pair */
-       struct ib_queue_pair *qp;
-       /** Broadcast group membership */
-       struct ib_mc_membership membership;
-
-       /** Peer cache */
-       struct list_head peers;
-
-       /** Send duplicate packet to gateway (or NULL)
-        *
-        * @v eoib              EoIB device
-        * @v original          Original I/O buffer
-        */
-       void ( * duplicate ) ( struct eoib_device *eoib,
-                              struct io_buffer *original );
-       /** Gateway (if any) */
-       struct ib_address_vector gateway;
-       /** Multicast group additional component mask */
-       unsigned int mask;
-};
-
-/**
- * Check if EoIB device uses a gateway
- *
- * @v eoib             EoIB device
- * @v has_gw           EoIB device uses a gateway
- */
-static inline int eoib_has_gateway ( struct eoib_device *eoib ) {
-
-       return ( eoib->duplicate != NULL );
-}
-
-/**
- * Force creation of multicast group
- *
- * @v eoib             EoIB device
- */
-static inline void eoib_force_group_creation ( struct eoib_device *eoib ) {
-
-       /* Some dubious EoIB implementations require each endpoint to
-        * force the creation of the multicast group.  Yes, this makes
-        * it impossible for the group parameters (e.g. SL) to ever be
-        * modified without breaking backwards compatiblity with every
-        * existing driver.
-        */
-       eoib->mask = ( IB_SA_MCMEMBER_REC_PKEY | IB_SA_MCMEMBER_REC_QKEY |
-                      IB_SA_MCMEMBER_REC_SL | IB_SA_MCMEMBER_REC_FLOW_LABEL |
-                      IB_SA_MCMEMBER_REC_TRAFFIC_CLASS );
-}
-
-extern int eoib_create ( struct ib_device *ibdev, const uint8_t *hw_addr,
-                        struct ib_address_vector *broadcast,
-                        const char *name );
-extern struct eoib_device * eoib_find ( struct ib_device *ibdev,
-                                       const uint8_t *hw_addr );
-extern void eoib_destroy ( struct eoib_device *eoib );
-extern void eoib_set_gateway ( struct eoib_device *eoib,
-                              struct ib_address_vector *av );
-
-#endif /* _IPXE_EOIB_H */
index f743dae..e21c959 100644 (file)
@@ -85,7 +85,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define ERRFILE_uhci                ( ERRFILE_DRIVER | 0x000b0000 )
 #define ERRFILE_usbhid              ( ERRFILE_DRIVER | 0x000c0000 )
 #define ERRFILE_usbkbd              ( ERRFILE_DRIVER | 0x000d0000 )
-#define ERRFILE_usbio               ( ERRFILE_DRIVER | 0x000e0000 )
 
 #define ERRFILE_nvs                 ( ERRFILE_DRIVER | 0x00100000 )
 #define ERRFILE_spi                 ( ERRFILE_DRIVER | 0x00110000 )
@@ -183,15 +182,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define ERRFILE_smsc75xx            ( ERRFILE_DRIVER | 0x00770000 )
 #define ERRFILE_intelvf                     ( ERRFILE_DRIVER | 0x00780000 )
 #define ERRFILE_intelxvf            ( ERRFILE_DRIVER | 0x00790000 )
-#define ERRFILE_smsc95xx            ( ERRFILE_DRIVER | 0x007a0000 )
-#define ERRFILE_acm                 ( ERRFILE_DRIVER | 0x007b0000 )
-#define ERRFILE_eoib                ( ERRFILE_DRIVER | 0x007c0000 )
-#define ERRFILE_golan               ( ERRFILE_DRIVER | 0x007d0000 )
-#define ERRFILE_flexboot_nodnic             ( ERRFILE_DRIVER | 0x007e0000 )
-#define ERRFILE_virtio_pci          ( ERRFILE_DRIVER | 0x007f0000 )
-#define ERRFILE_pciea               ( ERRFILE_DRIVER | 0x00c00000 )
-#define ERRFILE_axge                ( ERRFILE_DRIVER | 0x00c10000 )
-#define ERRFILE_thunderx            ( ERRFILE_DRIVER | 0x00c20000 )
 
 #define ERRFILE_aoe                    ( ERRFILE_NET | 0x00000000 )
 #define ERRFILE_arp                    ( ERRFILE_NET | 0x00010000 )
@@ -265,8 +255,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define ERRFILE_peerdisc               ( ERRFILE_NET | 0x00450000 )
 #define ERRFILE_peerblk                        ( ERRFILE_NET | 0x00460000 )
 #define ERRFILE_peermux                        ( ERRFILE_NET | 0x00470000 )
-#define ERRFILE_xsigo                  ( ERRFILE_NET | 0x00480000 )
-#define ERRFILE_ntp                    ( ERRFILE_NET | 0x00490000 )
 
 #define ERRFILE_image                ( ERRFILE_IMAGE | 0x00000000 )
 #define ERRFILE_elf                  ( ERRFILE_IMAGE | 0x00010000 )
@@ -351,11 +339,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define ERRFILE_vmbus                ( ERRFILE_OTHER | 0x00470000 )
 #define ERRFILE_efi_time             ( ERRFILE_OTHER | 0x00480000 )
 #define ERRFILE_efi_watchdog         ( ERRFILE_OTHER | 0x00490000 )
-#define ERRFILE_efi_pxe                      ( ERRFILE_OTHER | 0x004a0000 )
-#define ERRFILE_efi_usb                      ( ERRFILE_OTHER | 0x004b0000 )
-#define ERRFILE_efi_fbcon            ( ERRFILE_OTHER | 0x004c0000 )
-#define ERRFILE_efi_local            ( ERRFILE_OTHER | 0x004d0000 )
-#define ERRFILE_efi_entropy          ( ERRFILE_OTHER | 0x004e0000 )
 
 /** @} */
 
index 42ffca3..d442bb9 100644 (file)
@@ -12,11 +12,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <stdint.h>
 #include <ipxe/ansiesc.h>
 #include <ipxe/uaccess.h>
-#include <ipxe/console.h>
+
+struct pixel_buffer;
 
 /** Character width, in pixels */
 #define FBCON_CHAR_WIDTH 9
 
+/** Character height, in pixels */
+#define FBCON_CHAR_HEIGHT 16
+
 /** Bold colour modifier (RGB value) */
 #define FBCON_BOLD 0x555555
 
@@ -26,21 +30,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /** A font glyph */
 struct fbcon_font_glyph {
        /** Row bitmask */
-       uint8_t bitmask[0];
-};
+       uint8_t bitmask[FBCON_CHAR_HEIGHT];
+} __attribute__ (( packed ));
 
 /** A font definition */
 struct fbcon_font {
-       /** Character height (in pixels) */
-       unsigned int height;
-       /**
-        * Get character glyph
-        *
-        * @v character         Character
-        * @v glyph             Character glyph to fill in
-        */
-       void ( * glyph ) ( unsigned int character, uint8_t *glyph );
-};
+       /** Character glyphs */
+       userptr_t start;
+} __attribute__ (( packed ));
 
 /** A frame buffer geometry
  *
@@ -148,9 +145,10 @@ struct fbcon {
 
 extern int fbcon_init ( struct fbcon *fbcon, userptr_t start,
                        struct fbcon_geometry *pixel,
+                       struct fbcon_margin *margin,
                        struct fbcon_colour_map *map,
                        struct fbcon_font *font,
-                       struct console_configuration *config );
+                       struct pixel_buffer *pixbuf );
 extern void fbcon_fini ( struct fbcon *fbcon );
 extern void fbcon_putchar ( struct fbcon *fbcon, int character );
 
index f3276e6..47ad27f 100644 (file)
@@ -12,8 +12,9 @@ FILE_LICENCE ( BSD2 );
 #include <ipxe/infiniband.h>
 #include <ipxe/xfer.h>
 
-extern int ib_cmrc_open ( struct interface *xfer, struct ib_device *ibdev,
-                         union ib_gid *dgid, union ib_guid *service_id,
-                         const char *name );
+extern int ib_cmrc_open ( struct interface *xfer,
+                         struct ib_device *ibdev,
+                         union ib_gid *dgid,
+                         union ib_guid *service_id );
 
 #endif /* _IPXE_IB_CMRC_H */
index 1342740..ae1eea7 100644 (file)
@@ -144,9 +144,6 @@ struct ib_port_info {
 #define IB_LINK_SPEED_SDR              0x01
 #define IB_LINK_SPEED_DDR              0x02
 #define IB_LINK_SPEED_QDR              0x04
-#define IB_LINK_SPEED_FDR10            0x08
-#define IB_LINK_SPEED_FDR              0x10
-#define IB_LINK_SPEED_EDR              0x20
 
 #define IB_PORT_STATE_DOWN             0x01
 #define IB_PORT_STATE_INIT             0x02
@@ -219,25 +216,8 @@ struct ib_sa_hdr {
        uint32_t comp_mask[2];
 } __attribute__ (( packed ));
 
-#define IB_SA_ATTR_SERVICE_REC                 0x31
-#define IB_SA_ATTR_PATH_REC                    0x35
 #define IB_SA_ATTR_MC_MEMBER_REC               0x38
-
-struct ib_service_record {
-       uint64_t id;
-       union ib_gid gid;
-       uint16_t pkey;
-       uint16_t reserved;
-       uint32_t lease;
-       uint8_t key[16];
-       char name[64];
-       uint8_t data8[16];
-       uint16_t data16[8];
-       uint32_t data32[4];
-       uint64_t data64[2];
-} __attribute__ (( packed ));
-
-#define IB_SA_SERVICE_REC_NAME                 (1<<6)
+#define IB_SA_ATTR_PATH_REC                    0x35
 
 struct ib_path_record {
        uint32_t reserved0[2];
@@ -295,7 +275,6 @@ struct ib_mc_member_record {
 #define IB_SA_MCMEMBER_REC_PROXY_JOIN          (1<<17)
 
 union ib_sa_data {
-       struct ib_service_record service_record;
        struct ib_path_record path_record;
        struct ib_mc_member_record mc_member_record;
 } __attribute__ (( packed ));
@@ -525,12 +504,6 @@ union ib_mad_class_specific {
        struct ib_smp_class_specific smp;
 } __attribute__ (( packed ));
 
-/** A management datagram transaction identifier */
-struct ib_mad_tid {
-       uint32_t high;
-       uint32_t low;
-} __attribute__ (( packed ));
-
 /** A management datagram common header
  *
  * Defined in section 13.4.2 of the IBA.
@@ -542,7 +515,7 @@ struct ib_mad_hdr {
        uint8_t method;
        uint16_t status;
        union ib_mad_class_specific class_specific;
-       struct ib_mad_tid tid;
+       uint32_t tid[2];
        uint16_t attr_id;
        uint8_t reserved[2];
        uint32_t attr_mod;
index df348bd..5640669 100644 (file)
@@ -17,25 +17,30 @@ struct ib_mad_transaction;
 struct ib_mc_membership {
        /** Queue pair */
        struct ib_queue_pair *qp;
-       /** Address vector */
-       struct ib_address_vector *av;
-       /** Attached to multicast GID */
-       int attached;
+       /** Multicast GID */
+       union ib_gid gid;
        /** Multicast group join transaction */
        struct ib_mad_transaction *madx;
        /** Handle join success/failure
         *
+        * @v ibdev             Infiniband device
+        * @v qp                Queue pair
         * @v membership        Multicast group membership
         * @v rc                Status code
+        * @v mad               Response MAD (or NULL on error)
         */
-       void ( * complete ) ( struct ib_mc_membership *membership, int rc );
+       void ( * complete ) ( struct ib_device *ibdev, struct ib_queue_pair *qp,
+                             struct ib_mc_membership *membership, int rc,
+                             union ib_mad *mad );
 };
 
 extern int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
                           struct ib_mc_membership *membership,
-                          struct ib_address_vector *av, unsigned int mask,
-                          void ( * joined ) ( struct ib_mc_membership *memb,
-                                              int rc ) );
+                          union ib_gid *gid,
+                          void ( * joined ) ( struct ib_device *ibdev,
+                                              struct ib_queue_pair *qp,
+                                              struct ib_mc_membership *memb,
+                                              int rc, union ib_mad *mad ) );
 
 extern void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp,
                             struct ib_mc_membership *membership );
index 747f963..f275fcb 100644 (file)
@@ -19,7 +19,6 @@ union ib_guid {
        uint8_t bytes[8];
        uint16_t words[4];
        uint32_t dwords[2];
-       uint64_t qword;
 };
 
 /** Infiniband Globally Unique Identifier debug message format */
@@ -34,7 +33,6 @@ union ib_gid {
        uint8_t bytes[16];
        uint16_t words[8];
        uint32_t dwords[4];
-       uint64_t qwords[2];
        struct {
                union ib_guid prefix;
                union ib_guid guid;
@@ -48,9 +46,6 @@ union ib_gid {
 #define IB_GID_ARGS( gid ) \
        IB_GUID_ARGS ( &(gid)->s.prefix ), IB_GUID_ARGS ( &(gid)->s.guid )
 
-/** Test for multicast GID */
-#define IB_GID_MULTICAST( gid ) ( (gid)->bytes[0] == 0xff )
-
 /** An Infiniband Local Route Header */
 struct ib_local_route_header {
        /** Virtual lane and link version */
diff --git a/roms/ipxe/src/include/ipxe/ib_service.h b/roms/ipxe/src/include/ipxe/ib_service.h
deleted file mode 100644 (file)
index 88afe4e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef _IPXE_IB_SERVICE_H
-#define _IPXE_IB_SERVICE_H
-
-/** @file
- *
- * Infiniband service records
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/infiniband.h>
-#include <ipxe/ib_mi.h>
-
-extern struct ib_mad_transaction *
-ib_create_service_madx ( struct ib_device *ibdev,
-                        struct ib_mad_interface *mi, const char *name,
-                        struct ib_mad_transaction_operations *op );
-
-#endif /* _IPXE_IB_SERVICE_H */
index 9d7b03f..4eb1f80 100644 (file)
@@ -99,14 +99,4 @@ static inline void * arp_target_pa ( struct arphdr *arphdr ) {
        return ( arp_target_ha ( arphdr ) + arphdr->ar_hln );
 }
 
-/** ARP packet length
- *
- * @v arphdr   ARP header
- * @ret len    Length (including header)
- */
-static inline size_t arp_len ( struct arphdr *arphdr ) {
-       return ( sizeof ( *arphdr ) +
-                ( 2 * ( arphdr->ar_hln + arphdr->ar_pln ) ) );
-}
-
 #endif /* _IPXE_IF_ARP_H */
index f33fedd..6abd7a2 100644 (file)
@@ -158,7 +158,6 @@ static inline struct image * first_image ( void ) {
 }
 
 extern struct image * alloc_image ( struct uri *uri );
-extern int image_set_uri ( struct image *image, struct uri *uri );
 extern int image_set_name ( struct image *image, const char *name );
 extern int image_set_cmdline ( struct image *image, const char *cmdline );
 extern int register_image ( struct image *image );
index d7ecd16..87cfe50 100644 (file)
@@ -15,7 +15,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/tables.h>
 #include <ipxe/ib_packet.h>
 #include <ipxe/ib_mad.h>
-#include <ipxe/if_ether.h>
 
 /** Subnet management interface QPN */
 #define IB_QPN_SMI 0
@@ -159,8 +158,6 @@ struct ib_queue_pair {
        struct ib_device *ibdev;
        /** List of queue pairs on this Infiniband device */
        struct list_head list;
-       /** Queue pair name */
-       const char *name;
        /** Queue pair number */
        unsigned long qpn;
        /** Externally-visible queue pair number
@@ -391,9 +388,6 @@ struct ib_device_operations {
                                   union ib_mad *mad );
 };
 
-/** Maximum length of an Infiniband device name */
-#define IBDEV_NAME_LEN 8
-
 /** An Infiniband device */
 struct ib_device {
        /** Reference counter */
@@ -402,10 +396,6 @@ struct ib_device {
        struct list_head list;
        /** List of open Infiniband devices */
        struct list_head open_list;
-       /** Index of this Infiniband device */
-       unsigned int index;
-       /** Name of this Infiniband device */
-       char name[IBDEV_NAME_LEN];
        /** Underlying device */
        struct device *dev;
        /** List of completion queues */
@@ -458,11 +448,10 @@ struct ib_device {
        /** General services interface */
        struct ib_mad_interface *gsi;
 
-       /** IPoIB LEMAC (if non-default) */
-       uint8_t lemac[ETH_ALEN];
-
        /** Driver private data */
        void *drv_priv;
+       /** Owner private data */
+       void *owner_priv;
 };
 
 /** An Infiniband upper-layer driver */
@@ -504,7 +493,7 @@ extern struct ib_queue_pair *
 ib_create_qp ( struct ib_device *ibdev, enum ib_queue_pair_type type,
               unsigned int num_send_wqes, struct ib_completion_queue *send_cq,
               unsigned int num_recv_wqes, struct ib_completion_queue *recv_cq,
-              struct ib_queue_pair_operations *op, const char *name );
+              struct ib_queue_pair_operations *op );
 extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp );
 extern void ib_destroy_qp ( struct ib_device *ibdev,
                            struct ib_queue_pair *qp );
@@ -706,4 +695,26 @@ ib_get_drvdata ( struct ib_device *ibdev ) {
        return ibdev->drv_priv;
 }
 
+/**
+ * Set Infiniband device owner-private data
+ *
+ * @v ibdev            Infiniband device
+ * @v priv             Private data
+ */
+static inline __always_inline void
+ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) {
+       ibdev->owner_priv = priv;
+}
+
+/**
+ * Get Infiniband device owner-private data
+ *
+ * @v ibdev            Infiniband device
+ * @ret priv           Private data
+ */
+static inline __always_inline void *
+ib_get_ownerdata ( struct ib_device *ibdev ) {
+       return ibdev->owner_priv;
+}
+
 #endif /* _IPXE_INFINIBAND_H */
index fe13881..af76791 100644 (file)
@@ -20,8 +20,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <stdint.h>
 #include <ipxe/api.h>
-#include <ipxe/iomap.h>
 #include <config/ioapi.h>
+#include <ipxe/uaccess.h>
 
 /** Page size */
 #define PAGE_SIZE ( 1 << PAGE_SHIFT )
@@ -197,6 +197,30 @@ static inline __always_inline void * bus_to_virt ( unsigned long bus_addr ) {
 }
 
 /**
+ * Map bus address as an I/O address
+ *
+ * @v bus_addr         Bus address
+ * @v len              Length of region
+ * @ret io_addr                I/O address
+ */
+void * ioremap ( unsigned long bus_addr, size_t len );
+
+/**
+ * Unmap I/O address
+ *
+ * @v io_addr          I/O address
+ */
+void iounmap ( volatile const void *io_addr );
+
+/**
+ * Convert I/O address to bus address (for debug only)
+ *
+ * @v io_addr          I/O address
+ * @ret bus_addr       Bus address
+ */
+unsigned long io_to_bus ( volatile const void *io_addr );
+
+/**
  * Read byte from memory-mapped device
  *
  * @v io_addr          I/O address
diff --git a/roms/ipxe/src/include/ipxe/iomap.h b/roms/ipxe/src/include/ipxe/iomap.h
deleted file mode 100644 (file)
index b8ded38..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef _IPXE_IOMAP_H
-#define _IPXE_IOMAP_H
-
-/** @file
- *
- * iPXE I/O mapping API
- *
- * The I/O mapping API provides methods for mapping and unmapping I/O
- * devices.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <ipxe/api.h>
-#include <config/ioapi.h>
-#include <ipxe/uaccess.h>
-
-/**
- * Calculate static inline I/O mapping API function name
- *
- * @v _prefix          Subsystem prefix
- * @v _api_func                API function
- * @ret _subsys_func   Subsystem API function
- */
-#define IOMAP_INLINE( _subsys, _api_func ) \
-       SINGLE_API_INLINE ( IOMAP_PREFIX_ ## _subsys, _api_func )
-
-/**
- * Provide an I/O mapping API implementation
- *
- * @v _prefix          Subsystem prefix
- * @v _api_func                API function
- * @v _func            Implementing function
- */
-#define PROVIDE_IOMAP( _subsys, _api_func, _func ) \
-       PROVIDE_SINGLE_API ( IOMAP_PREFIX_ ## _subsys, _api_func, _func )
-
-/**
- * Provide a static inline I/O mapping API implementation
- *
- * @v _prefix          Subsystem prefix
- * @v _api_func                API function
- */
-#define PROVIDE_IOMAP_INLINE( _subsys, _api_func ) \
-       PROVIDE_SINGLE_API_INLINE ( IOMAP_PREFIX_ ## _subsys, _api_func )
-
-/* Include all architecture-independent I/O API headers */
-#include <ipxe/iomap_virt.h>
-
-/* Include all architecture-dependent I/O API headers */
-#include <bits/iomap.h>
-
-/**
- * Map bus address as an I/O address
- *
- * @v bus_addr         Bus address
- * @v len              Length of region
- * @ret io_addr                I/O address
- */
-void * ioremap ( unsigned long bus_addr, size_t len );
-
-/**
- * Unmap I/O address
- *
- * @v io_addr          I/O address
- */
-void iounmap ( volatile const void *io_addr );
-
-/**
- * Convert I/O address to bus address (for debug only)
- *
- * @v io_addr          I/O address
- * @ret bus_addr       Bus address
- */
-unsigned long io_to_bus ( volatile const void *io_addr );
-
-#endif /* _IPXE_IOMAP_H */
diff --git a/roms/ipxe/src/include/ipxe/iomap_virt.h b/roms/ipxe/src/include/ipxe/iomap_virt.h
deleted file mode 100644 (file)
index 4962b7c..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef _IPXE_IOMAP_VIRT_H
-#define _IPXE_IOMAP_VIRT_H
-
-/** @file
- *
- * iPXE I/O mapping API using phys_to_virt()
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#ifdef IOMAP_VIRT
-#define IOMAP_PREFIX_virt
-#else
-#define IOMAP_PREFIX_virt __virt_
-#endif
-
-static inline __always_inline void *
-IOMAP_INLINE ( virt, ioremap ) ( unsigned long bus_addr, size_t len __unused ) {
-       return ( bus_addr ? phys_to_virt ( bus_addr ) : NULL );
-}
-
-static inline __always_inline void
-IOMAP_INLINE ( virt, iounmap ) ( volatile const void *io_addr __unused ) {
-       /* Nothing to do */
-}
-
-static inline __always_inline unsigned long
-IOMAP_INLINE ( virt, io_to_bus ) ( volatile const void *io_addr ) {
-       return virt_to_phys ( io_addr );
-}
-
-#endif /* _IPXE_IOMAP_VIRT_H */
index 065eeab..b34dd32 100644 (file)
@@ -62,6 +62,5 @@ struct ipoib_remac {
 
 extern const char * ipoib_ntoa ( const void *ll_addr );
 extern struct net_device * alloc_ipoibdev ( size_t priv_size );
-extern struct net_device * ipoib_netdev ( struct ib_device *ibdev );
 
 #endif /* _IPXE_IPOIB_H */
diff --git a/roms/ipxe/src/include/ipxe/linux_compat.h b/roms/ipxe/src/include/ipxe/linux_compat.h
new file mode 100644 (file)
index 0000000..4704c48
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _IPXE_LINUX_COMPAT_H
+#define _IPXE_LINUX_COMPAT_H
+
+/** @file
+ *
+ * Linux code compatibility
+ *
+ * This file exists to ease the building of Linux source code within
+ * iPXE.  This is intended to facilitate quick testing; it is not
+ * intended to be a substitute for proper porting.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <errno.h>
+#include <stdio.h>
+#include <byteswap.h>
+#include <ipxe/bitops.h>
+
+#define __init
+#define __exit
+#define __initdata
+#define __exitdata
+#define printk printf
+
+#endif /* _IPXE_LINUX_COMPAT_H */
diff --git a/roms/ipxe/src/include/ipxe/ntp.h b/roms/ipxe/src/include/ipxe/ntp.h
deleted file mode 100644 (file)
index f5b3d23..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-#ifndef _IPXE_NTP_H
-#define _IPXE_NTP_H
-
-/** @file
- *
- * Network Time Protocol
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <ipxe/in.h>
-#include <ipxe/interface.h>
-
-/** NTP port */
-#define NTP_PORT 123
-
-/** An NTP short-format timestamp */
-struct ntp_short {
-       /** Seconds */
-       uint16_t seconds;
-       /** Fraction of a second */
-       uint16_t fraction;
-} __attribute__ (( packed ));
-
-/** An NTP timestamp */
-struct ntp_timestamp {
-       /** Seconds */
-       uint32_t seconds;
-       /** Fraction of a second */
-       uint32_t fraction;
-} __attribute__ (( packed ));
-
-/** An NTP reference identifier */
-union ntp_id {
-       /** Textual identifier */
-       char text[4];
-       /** IPv4 address */
-       struct in_addr in;
-       /** Opaque integer */
-       uint32_t opaque;
-};
-
-/** An NTP header */
-struct ntp_header {
-       /** Flags */
-       uint8_t flags;
-       /** Stratum */
-       uint8_t stratum;
-       /** Polling rate */
-       int8_t poll;
-       /** Precision */
-       int8_t precision;
-       /** Root delay */
-       struct ntp_short delay;
-       /** Root dispersion */
-       struct ntp_short dispersion;
-       /** Reference clock identifier */
-       union ntp_id id;
-       /** Reference timestamp */
-       struct ntp_timestamp reference;
-       /** Originate timestamp */
-       struct ntp_timestamp originate;
-       /** Receive timestamp */
-       struct ntp_timestamp receive;
-       /** Transmit timestamp */
-       struct ntp_timestamp transmit;
-} __attribute__ (( packed ));
-
-/** Leap second indicator: unknown */
-#define NTP_FL_LI_UNKNOWN 0xc0
-
-/** NTP version: 1 */
-#define NTP_FL_VN_1 0x20
-
-/** NTP mode: client */
-#define NTP_FL_MODE_CLIENT 0x03
-
-/** NTP mode: server */
-#define NTP_FL_MODE_SERVER 0x04
-
-/** NTP mode mask */
-#define NTP_FL_MODE_MASK 0x07
-
-/** NTP timestamp for start of Unix epoch */
-#define NTP_EPOCH 2208988800UL
-
-/** NTP fraction of a second magic value
- *
- * This is a policy decision.
- */
-#define NTP_FRACTION_MAGIC 0x69505845UL
-
-/** NTP minimum retransmission timeout
- *
- * This is a policy decision.
- */
-#define NTP_MIN_TIMEOUT ( 1 * TICKS_PER_SEC )
-
-/** NTP maximum retransmission timeout
- *
- * This is a policy decision.
- */
-#define NTP_MAX_TIMEOUT ( 10 * TICKS_PER_SEC )
-
-extern int start_ntp ( struct interface *job, const char *hostname );
-
-#endif /* _IPXE_NTP_H */
index ddd8c8d..a841e00 100644 (file)
@@ -94,7 +94,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define PCI_CAP_ID_VPD                 0x03    /**< Vital product data */
 #define PCI_CAP_ID_VNDR                        0x09    /**< Vendor-specific */
 #define PCI_CAP_ID_EXP                 0x10    /**< PCI Express */
-#define PCI_CAP_ID_EA                  0x14    /**< Enhanced Allocation */
 
 /** Next capability */
 #define PCI_CAP_NEXT           0x01
@@ -105,10 +104,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define PCI_PM_CTRL_PME_ENABLE         0x0100  /**< PME pin enable */
 #define PCI_PM_CTRL_PME_STATUS         0x8000  /**< PME pin status */
 
-/** PCI Express */
-#define PCI_EXP_DEVCTL         0x08
-#define PCI_EXP_DEVCTL_FLR             0x8000  /**< Function level reset */
-
 /** Uncorrectable error status */
 #define PCI_ERR_UNCOR_STATUS   0x04
 
@@ -133,9 +128,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
        ( ( ( (base) & 0xff ) << 16 ) | ( ( (sub) & 0xff ) << 8 ) |     \
          ( ( (progif) & 0xff) << 0 ) )
 
-/** PCI Express function level reset delay (in ms) */
-#define PCI_EXP_FLR_DELAY_MS 100
-
 /** A PCI device ID list entry */
 struct pci_device_id {
        /** Name */
@@ -195,8 +187,8 @@ struct pci_device {
        uint32_t class;
        /** Interrupt number */
        uint8_t irq;
-       /** Segment, bus, device, and function (bus:dev.fn) number */
-       uint32_t busdevfn;
+       /** Bus, device, and function (bus:dev.fn) number */
+       uint16_t busdevfn;
        /** Driver for this device */
        struct pci_driver *driver;
        /** Driver-private data
@@ -241,13 +233,11 @@ struct pci_driver {
 /** Declare a fallback PCI driver */
 #define __pci_driver_fallback __table_entry ( PCI_DRIVERS, 02 )
 
-#define PCI_SEG( busdevfn )            ( ( (busdevfn) >> 16 ) & 0xffff )
 #define PCI_BUS( busdevfn )            ( ( (busdevfn) >> 8 ) & 0xff )
 #define PCI_SLOT( busdevfn )           ( ( (busdevfn) >> 3 ) & 0x1f )
 #define PCI_FUNC( busdevfn )           ( ( (busdevfn) >> 0 ) & 0x07 )
-#define PCI_BUSDEVFN( segment, bus, slot, func )                       \
-       ( ( (segment) << 16 ) | ( (bus) << 8 ) |                        \
-         ( (slot) << 3 ) | ( (func) << 0 ) )
+#define PCI_BUSDEVFN( bus, slot, func )        \
+       ( ( (bus) << 8 ) | ( (slot) << 3 ) | ( (func) << 0 ) )
 #define PCI_FIRST_FUNC( busdevfn )     ( (busdevfn) & ~0x07 )
 #define PCI_LAST_FUNC( busdevfn )      ( (busdevfn) | 0x07 )
 
@@ -273,12 +263,12 @@ struct pci_driver {
        PCI_ID( _vendor, _device, _name, _description, _data )
 
 /** PCI device debug message format */
-#define PCI_FMT "%04x:%02x:%02x.%x"
+#define PCI_FMT "PCI %02x:%02x.%x"
 
 /** PCI device debug message arguments */
 #define PCI_ARGS( pci )                                                        \
-       PCI_SEG ( (pci)->busdevfn ), PCI_BUS ( (pci)->busdevfn ),       \
-       PCI_SLOT ( (pci)->busdevfn ), PCI_FUNC ( (pci)->busdevfn )
+       PCI_BUS ( (pci)->busdevfn ), PCI_SLOT ( (pci)->busdevfn ),      \
+       PCI_FUNC ( (pci)->busdevfn )
 
 extern void adjust_pci_device ( struct pci_device *pci );
 extern unsigned long pci_bar_start ( struct pci_device *pci,
@@ -289,8 +279,6 @@ extern int pci_find_driver ( struct pci_device *pci );
 extern int pci_probe ( struct pci_device *pci );
 extern void pci_remove ( struct pci_device *pci );
 extern int pci_find_capability ( struct pci_device *pci, int capability );
-extern int pci_find_next_capability ( struct pci_device *pci,
-                                     int pos, int capability );
 extern unsigned long pci_bar_size ( struct pci_device *pci, unsigned int reg );
 
 /**
diff --git a/roms/ipxe/src/include/ipxe/pciea.h b/roms/ipxe/src/include/ipxe/pciea.h
deleted file mode 100644 (file)
index 941c94e..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef _IPXE_PCIEA_H
-#define _IPXE_PCIEA_H
-
-/** @file
- *
- * PCI Enhanced Allocation
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/pci.h>
-
-/** Number of entries */
-#define PCIEA_ENTRIES 2
-#define PCIEA_ENTRIES_MASK 0x3f
-
-/** First entry */
-#define PCIEA_FIRST 4
-
-/** Entry descriptor */
-#define PCIEA_DESC 0
-
-/** Entry size */
-#define PCIEA_DESC_SIZE(desc) ( ( (desc) >> 0 ) & 0x7 )
-
-/** BAR equivalent indicator */
-#define PCIEA_DESC_BEI(desc) ( ( (desc) >> 4 ) & 0xf )
-
-/** BAR equivalent indicators */
-enum pciea_bei {
-       PCIEA_BEI_BAR_0 = 0,            /**< Standard BAR 0 */
-       PCIEA_BEI_BAR_1 = 1,            /**< Standard BAR 1 */
-       PCIEA_BEI_BAR_2 = 2,            /**< Standard BAR 2 */
-       PCIEA_BEI_BAR_3 = 3,            /**< Standard BAR 3 */
-       PCIEA_BEI_BAR_4 = 4,            /**< Standard BAR 4 */
-       PCIEA_BEI_BAR_5 = 5,            /**< Standard BAR 5 */
-       PCIEA_BEI_ROM = 8,              /**< Expansion ROM BAR */
-       PCIEA_BEI_VF_BAR_0 = 9,         /**< Virtual function BAR 0 */
-       PCIEA_BEI_VF_BAR_1 = 10,        /**< Virtual function BAR 1 */
-       PCIEA_BEI_VF_BAR_2 = 11,        /**< Virtual function BAR 2 */
-       PCIEA_BEI_VF_BAR_3 = 12,        /**< Virtual function BAR 3 */
-       PCIEA_BEI_VF_BAR_4 = 13,        /**< Virtual function BAR 4 */
-       PCIEA_BEI_VF_BAR_5 = 14,        /**< Virtual function BAR 5 */
-};
-
-/** Entry is enabled */
-#define PCIEA_DESC_ENABLED 0x80000000UL
-
-/** Base address low dword */
-#define PCIEA_LOW_BASE 4
-
-/** Limit low dword */
-#define PCIEA_LOW_LIMIT 8
-
-/** BAR is 64-bit */
-#define PCIEA_LOW_ATTR_64BIT 0x00000002UL
-
-/** Low dword attribute bit mask */
-#define PCIEA_LOW_ATTR_MASK 0x00000003UL
-
-/** Offset to high dwords */
-#define PCIEA_LOW_HIGH 8
-
-extern unsigned long pciea_bar_start ( struct pci_device *pci,
-                                      unsigned int bei );
-extern unsigned long pciea_bar_size ( struct pci_device *pci,
-                                     unsigned int bei );
-
-#endif /* _IPXE_PCIEA_H */
index 81ff57d..27066e9 100644 (file)
@@ -112,7 +112,7 @@ pool_is_reopenable ( struct pooled_connection *pool ) {
        /* A connection is reopenable if it has been recycled but is
         * not yet known to be alive.
         */
-       return ( ( pool->flags & POOL_RECYCLED ) &&
+       return ( ( pool->flags & POOL_RECYCLED ) &
                 ( ! ( pool->flags & POOL_ALIVE ) ) );
 }
 
diff --git a/roms/ipxe/src/include/ipxe/pseudobit.h b/roms/ipxe/src/include/ipxe/pseudobit.h
deleted file mode 100644 (file)
index 431b106..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-#ifndef _IPXE_PSEUDOBIT_H
-#define _IPXE_PSEUDOBIT_H
-
-/*
- * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/**
- * @file
- *
- * Pseudo-bit structures
- *
- */
-
-#include <stdint.h>
-#include <byteswap.h>
-
-/* Endianness selection.
- *
- * This is a property of the device, not a property of the host CPU.
- */
-#ifdef PSEUDOBIT_LITTLE_ENDIAN
-#define cpu_to_BIT64   cpu_to_le64
-#define cpu_to_BIT32   cpu_to_le32
-#define BIT64_to_cpu   le64_to_cpu
-#define BIT32_to_cpu   le32_to_cpu
-#define QWORD_SHIFT( offset, width ) (offset)
-#endif
-#ifdef PSEUDOBIT_BIG_ENDIAN
-#define cpu_to_BIT64   cpu_to_be64
-#define cpu_to_BIT32   cpu_to_be32
-#define BIT64_to_cpu   be64_to_cpu
-#define BIT32_to_cpu   be32_to_cpu
-#define QWORD_SHIFT( offset, width ) ( 64 - (offset) - (width) )
-#endif
-
-/** Datatype used to represent a bit in the pseudo-structures */
-typedef unsigned char pseudo_bit_t;
-
-/**
- * Wrapper structure for pseudo_bit_t structures
- *
- * This structure provides a wrapper around pseudo_bit_t structures.
- * It has the correct size, and also encapsulates type information
- * about the underlying pseudo_bit_t-based structure, which allows the
- * BIT_FILL() etc. macros to work without requiring explicit type
- * information.
- */
-#define PSEUDO_BIT_STRUCT( _structure )                                              \
-       union {                                                               \
-               uint8_t bytes[ sizeof ( _structure ) / 8 ];                   \
-               uint32_t dwords[ sizeof ( _structure ) / 32 ];                \
-               uint64_t qwords[ sizeof ( _structure ) / 64 ];                \
-               _structure *dummy[0];                                         \
-       } __attribute__ (( packed )) u
-
-/** Get pseudo_bit_t structure type from wrapper structure pointer */
-#define PSEUDO_BIT_STRUCT_TYPE( _ptr )                                       \
-       typeof ( *((_ptr)->u.dummy[0]) )
-
-/** Bit offset of a field within a pseudo_bit_t structure */
-#define BIT_OFFSET( _ptr, _field )                                           \
-       offsetof ( PSEUDO_BIT_STRUCT_TYPE ( _ptr ), _field )
-
-/** Bit width of a field within a pseudo_bit_t structure */
-#define BIT_WIDTH( _ptr, _field )                                            \
-       sizeof ( ( ( PSEUDO_BIT_STRUCT_TYPE ( _ptr ) * ) NULL )->_field )
-
-/** Qword offset of a field within a pseudo_bit_t structure */
-#define QWORD_OFFSET( _ptr, _field )                                         \
-       ( BIT_OFFSET ( _ptr, _field ) / 64 )
-
-/** Qword bit offset of a field within a pseudo_bit_t structure */
-#define QWORD_BIT_OFFSET( _ptr, _index, _field )                             \
-       ( BIT_OFFSET ( _ptr, _field ) - ( 64 * (_index) ) )
-
-/** Qword bit shift for a field within a pseudo_bit_t structure */
-#define QWORD_BIT_SHIFT( _ptr, _index, _field )                                      \
-       QWORD_SHIFT ( QWORD_BIT_OFFSET ( _ptr, _index, _field ),              \
-                     BIT_WIDTH ( _ptr, _field ) )
-
-/** Bit mask for a field within a pseudo_bit_t structure */
-#define BIT_MASK( _ptr, _field )                                             \
-       ( ( ~( ( uint64_t ) 0 ) ) >>                                          \
-         ( 64 - BIT_WIDTH ( _ptr, _field ) ) )
-
-/*
- * Assemble native-endian qword from named fields and values
- *
- */
-
-#define BIT_ASSEMBLE_1( _ptr, _index, _field, _value )                       \
-       ( ( ( uint64_t) (_value) ) <<                                         \
-         QWORD_BIT_SHIFT ( _ptr, _index, _field ) )
-
-#define BIT_ASSEMBLE_2( _ptr, _index, _field, _value, ... )                  \
-       ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
-         BIT_ASSEMBLE_1 ( _ptr, _index, __VA_ARGS__ ) )
-
-#define BIT_ASSEMBLE_3( _ptr, _index, _field, _value, ... )                  \
-       ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
-         BIT_ASSEMBLE_2 ( _ptr, _index, __VA_ARGS__ ) )
-
-#define BIT_ASSEMBLE_4( _ptr, _index, _field, _value, ... )                  \
-       ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
-         BIT_ASSEMBLE_3 ( _ptr, _index, __VA_ARGS__ ) )
-
-#define BIT_ASSEMBLE_5( _ptr, _index, _field, _value, ... )                  \
-       ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
-         BIT_ASSEMBLE_4 ( _ptr, _index, __VA_ARGS__ ) )
-
-#define BIT_ASSEMBLE_6( _ptr, _index, _field, _value, ... )                  \
-       ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
-         BIT_ASSEMBLE_5 ( _ptr, _index, __VA_ARGS__ ) )
-
-#define BIT_ASSEMBLE_7( _ptr, _index, _field, _value, ... )                  \
-       ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
-         BIT_ASSEMBLE_6 ( _ptr, _index, __VA_ARGS__ ) )
-
-/*
- * Build native-endian (positive) qword bitmasks from named fields
- *
- */
-
-#define BIT_MASK_1( _ptr, _index, _field )                                   \
-       ( BIT_MASK ( _ptr, _field ) <<                                        \
-         QWORD_BIT_SHIFT ( _ptr, _index, _field ) )
-
-#define BIT_MASK_2( _ptr, _index, _field, ... )                                      \
-       ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
-         BIT_MASK_1 ( _ptr, _index, __VA_ARGS__ ) )
-
-#define BIT_MASK_3( _ptr, _index, _field, ... )                                      \
-       ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
-         BIT_MASK_2 ( _ptr, _index, __VA_ARGS__ ) )
-
-#define BIT_MASK_4( _ptr, _index, _field, ... )                                      \
-       ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
-         BIT_MASK_3 ( _ptr, _index, __VA_ARGS__ ) )
-
-#define BIT_MASK_5( _ptr, _index, _field, ... )                                      \
-       ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
-         BIT_MASK_4 ( _ptr, _index, __VA_ARGS__ ) )
-
-#define BIT_MASK_6( _ptr, _index, _field, ... )                                      \
-       ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
-         BIT_MASK_5 ( _ptr, _index, __VA_ARGS__ ) )
-
-#define BIT_MASK_7( _ptr, _index, _field, ... )                                      \
-       ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
-         BIT_MASK_6 ( _ptr, _index, __VA_ARGS__ ) )
-
-/*
- * Populate device-endian qwords from named fields and values
- *
- */
-
-#define BIT_FILL( _ptr, _index, _assembled ) do {                            \
-               uint64_t *__ptr = &(_ptr)->u.qwords[(_index)];                \
-               uint64_t __assembled = (_assembled);                          \
-               *__ptr = cpu_to_BIT64 ( __assembled );                        \
-       } while ( 0 )
-
-#define BIT_FILL_1( _ptr, _field1, ... )                                     \
-       BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
-                  BIT_ASSEMBLE_1 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
-                                   _field1, __VA_ARGS__ ) )
-
-#define BIT_FILL_2( _ptr, _field1, ... )                                     \
-       BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
-                  BIT_ASSEMBLE_2 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
-                                   _field1, __VA_ARGS__ ) )
-
-#define BIT_FILL_3( _ptr, _field1, ... )                                     \
-       BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
-                  BIT_ASSEMBLE_3 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
-                                   _field1, __VA_ARGS__ ) )
-
-#define BIT_FILL_4( _ptr, _field1, ... )                                     \
-       BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
-                  BIT_ASSEMBLE_4 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
-                                   _field1, __VA_ARGS__ ) )
-
-#define BIT_FILL_5( _ptr, _field1, ... )                                     \
-       BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
-                  BIT_ASSEMBLE_5 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
-                                   _field1, __VA_ARGS__ ) )
-
-#define BIT_FILL_6( _ptr, _field1, ... )                                     \
-       BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
-                  BIT_ASSEMBLE_6 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
-                                   _field1, __VA_ARGS__ ) )
-
-#define BIT_QWORD_PTR( _ptr, _field )                                        \
-       ( {                                                                   \
-               unsigned int __index = QWORD_OFFSET ( _ptr, _field );         \
-               uint64_t *__ptr = &(_ptr)->u.qwords[__index];                 \
-               __ptr;                                                        \
-       } )
-
-/** Extract value of named field */
-#define BIT_GET64( _ptr, _field )                                            \
-       ( {                                                                   \
-               unsigned int __index = QWORD_OFFSET ( _ptr, _field );         \
-               uint64_t *__ptr = &(_ptr)->u.qwords[__index];                 \
-               uint64_t __value = BIT64_to_cpu ( *__ptr );                   \
-               __value >>=                                                   \
-                   QWORD_BIT_SHIFT ( _ptr, __index, _field );                \
-               __value &= BIT_MASK ( _ptr, _field );                         \
-               __value;                                                      \
-       } )
-
-/** Extract value of named field (for fields up to the size of a long) */
-#define BIT_GET( _ptr, _field )                                                      \
-       ( ( unsigned long ) BIT_GET64 ( _ptr, _field ) )
-
-#define BIT_SET( _ptr, _field, _value ) do {                                 \
-               unsigned int __index = QWORD_OFFSET ( _ptr, _field );         \
-               uint64_t *__ptr = &(_ptr)->u.qwords[__index];                 \
-               unsigned int __shift =                                        \
-                       QWORD_BIT_SHIFT ( _ptr, __index, _field );            \
-               uint64_t __value = (_value);                                  \
-               *__ptr &= cpu_to_BIT64 ( ~( BIT_MASK ( _ptr, _field ) <<      \
-                                           __shift ) );                      \
-               *__ptr |= cpu_to_BIT64 ( __value << __shift );                \
-       } while ( 0 )
-
-#endif /* _IPXE_PSEUDOBIT_H */
index 041e189..57025f2 100644 (file)
@@ -70,7 +70,7 @@ unsigned int san_default_drive ( void );
  *
  * @v uri              URI
  * @v drive            Drive number
- * @ret drive          Drive number, or negative error
+ * @ret rc             Return status code
  */
 int san_hook ( struct uri *uri, unsigned int drive );
 
index 6534c25..95a553c 100644 (file)
@@ -40,7 +40,7 @@ struct setting {
         * (such as a DHCP option number, or an SMBIOS structure and
         * field number).
         */
-       unsigned long tag;
+       unsigned int tag;
        /** Setting scope (or NULL)
         *
         * For historic reasons, a NULL scope with a non-zero tag
@@ -452,18 +452,6 @@ extern const struct setting
 busid_setting __setting ( SETTING_NETDEV, busid );
 extern const struct setting
 user_class_setting __setting ( SETTING_HOST_EXTRA, user-class );
-extern const struct setting
-manufacturer_setting __setting ( SETTING_HOST_EXTRA, manufacturer );
-extern const struct setting
-product_setting __setting ( SETTING_HOST_EXTRA, product );
-extern const struct setting
-serial_setting __setting ( SETTING_HOST_EXTRA, serial );
-extern const struct setting
-asset_setting __setting ( SETTING_HOST_EXTRA, asset );
-extern const struct setting
-board_serial_setting __setting ( SETTING_HOST_EXTRA, board-serial );
-extern const struct setting dhcp_server_setting __setting ( SETTING_MISC,
-                                                           dhcp-server );
 
 /**
  * Initialise a settings block
index c1d8fea..24b05ed 100644 (file)
@@ -152,9 +152,6 @@ struct smbios_enclosure_information {
 /** SMBIOS enclosure information structure type */
 #define SMBIOS_TYPE_ENCLOSURE_INFORMATION 3
 
-/** SMBIOS OEM strings structure type */
-#define SMBIOS_TYPE_OEM_STRINGS 11
-
 /**
  * SMBIOS entry point descriptor
  *
index 21be3ca..063ebaa 100644 (file)
@@ -140,6 +140,8 @@ struct tcp_timestamp_padded_option {
 
 /** Parsed TCP options */
 struct tcp_options {
+       /** MSS option, if present */
+       const struct tcp_mss_option *mssopt;
        /** Window scale option, if present */
        const struct tcp_window_scale_option *wsopt;
        /** SACK permitted option, if present */
@@ -379,14 +381,6 @@ struct tcp_options {
 #define TCP_MSL ( 2 * 60 * TICKS_PER_SEC )
 
 /**
- * TCP keepalive period
- *
- * We send keepalive ACKs after this period of inactivity has elapsed
- * on an established connection.
- */
-#define TCP_KEEPALIVE_DELAY ( 15 * TICKS_PER_SEC )
-
-/**
  * TCP maximum header length
  *
  */
index 414daad..3cfc8e3 100644 (file)
@@ -13,48 +13,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/socket.h>
 #include <ipxe/in.h>
 #include <ipxe/tables.h>
-
-extern uint16_t generic_tcpip_continue_chksum ( uint16_t partial,
-                                               const void *data, size_t len );
-
 #include <bits/tcpip.h>
 
 struct io_buffer;
 struct net_device;
 struct ip_statistics;
 
-/** Positive zero checksum value */
-#define TCPIP_POSITIVE_ZERO_CSUM 0x0000
-
-/** Negative zero checksum value */
-#define TCPIP_NEGATIVE_ZERO_CSUM 0xffff
-
 /** Empty checksum value
  *
- * All of our TCP/IP checksum algorithms will return only the positive
- * representation of zero (0x0000) for a zero checksum over non-zero
- * input data.  This property arises since the end-around carry used
- * to mimic one's complement addition using unsigned arithmetic
- * prevents the running total from ever returning to 0x0000.  The
- * running total will therefore use only the negative representation
- * of zero (0xffff).  Since the return value is the one's complement
- * negation of the running total (calculated by simply bit-inverting
- * the running total), the return value will therefore use only the
- * positive representation of zero (0x0000).
- *
- * It is a very common misconception (found in many places such as
- * RFC1624) that this is a property guaranteed by the underlying
- * mathematics.  It is not; the choice of which zero representation is
- * used is merely an artifact of the software implementation of the
- * checksum algorithm.
- *
- * For consistency, we choose to use the positive representation of
- * zero (0x0000) for the checksum of a zero-length block of data.
- * This ensures that all of our TCP/IP checksum algorithms will return
- * only the positive representation of zero (0x0000) for a zero
- * checksum (regardless of the input data).
+ * This is the TCP/IP checksum over a zero-length block of data.
  */
-#define TCPIP_EMPTY_CSUM TCPIP_POSITIVE_ZERO_CSUM
+#define TCPIP_EMPTY_CSUM 0xffff
 
 /** TCP/IP address flags */
 enum tcpip_st_flags {
@@ -119,13 +88,6 @@ struct tcpip_protocol {
         int ( * rx ) ( struct io_buffer *iobuf, struct net_device *netdev,
                       struct sockaddr_tcpip *st_src,
                       struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum );
-       /** Preferred zero checksum value
-        *
-        * The checksum is a one's complement value: zero may be
-        * represented by either positive zero (0x0000) or negative
-        * zero (0xffff).
-        */
-       uint16_t zero_csum;
         /** 
         * Transport-layer protocol number
         *
@@ -144,8 +106,6 @@ struct tcpip_net_protocol {
        sa_family_t sa_family;
        /** Fixed header length */
        size_t header_len;
-       /** Network-layer protocol */
-       struct net_protocol *net_protocol;
        /**
         * Transmit packet
         *
@@ -196,11 +156,19 @@ extern int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip,
                      struct sockaddr_tcpip *st_dest,
                      struct net_device *netdev,
                      uint16_t *trans_csum );
-extern struct tcpip_net_protocol * tcpip_net_protocol ( sa_family_t sa_family );
 extern struct net_device * tcpip_netdev ( struct sockaddr_tcpip *st_dest );
 extern size_t tcpip_mtu ( struct sockaddr_tcpip *st_dest );
+extern uint16_t generic_tcpip_continue_chksum ( uint16_t partial,
+                                               const void *data, size_t len );
 extern uint16_t tcpip_chksum ( const void *data, size_t len );
 extern int tcpip_bind ( struct sockaddr_tcpip *st_local,
                        int ( * available ) ( int port ) );
 
+/* Use generic_tcpip_continue_chksum() if no architecture-specific
+ * version is available
+ */
+#ifndef tcpip_continue_chksum
+#define tcpip_continue_chksum generic_tcpip_continue_chksum
+#endif
+
 #endif /* _IPXE_TCPIP_H */
index 89bf90e..4c5bb2a 100644 (file)
@@ -50,24 +50,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /* Include all architecture-dependent time API headers */
 #include <bits/time.h>
 
-extern signed long time_offset;
-
 /**
- * Get current time in seconds (ignoring system clock offset)
+ * Get current time in seconds
  *
  * @ret time           Time, in seconds
  */
 time_t time_now ( void );
 
-/**
- * Adjust system clock
- *
- * @v delta            Clock adjustment, in seconds
- */
-static inline __attribute__ (( always_inline )) void
-time_adjust ( signed long delta ) {
-
-       time_offset += delta;
-}
-
 #endif /* _IPXE_TIME_H */
index 3879a0e..00e5a24 100644 (file)
@@ -191,11 +191,8 @@ uri_put ( struct uri *uri ) {
 
 extern struct uri *cwuri;
 
-extern size_t uri_decode ( const char *encoded, void *buf, size_t len );
-extern size_t uri_encode ( unsigned int field, const void *raw, size_t raw_len,
+extern size_t uri_encode ( const char *string, unsigned int field,
                           char *buf, ssize_t len );
-extern size_t uri_encode_string ( unsigned int field, const char *string,
-                                 char *buf, ssize_t len );
 extern struct uri * parse_uri ( const char *uri_string );
 extern size_t format_uri ( const struct uri *uri, char *buf, size_t len );
 extern char * format_uri_alloc ( const struct uri *uri );
@@ -206,8 +203,8 @@ extern char * resolve_path ( const char *base_path,
                             const char *relative_path );
 extern struct uri * resolve_uri ( const struct uri *base_uri,
                                  struct uri *relative_uri );
-extern struct uri * pxe_uri ( struct sockaddr *sa_server,
-                             const char *filename );
+extern struct uri * tftp_uri ( struct in_addr next_server, unsigned int port,
+                              const char *filename );
 extern void churi ( struct uri *uri );
 
 #endif /* _IPXE_URI_H */
index e7909d3..ab060b8 100644 (file)
@@ -68,7 +68,7 @@ enum usb_pid {
 struct usb_setup_packet {
        /** Request */
        uint16_t request;
-       /** Value parameter */
+       /** Value paramer */
        uint16_t value;
        /** Index parameter */
        uint16_t index;
@@ -91,9 +91,6 @@ struct usb_setup_packet {
 /** Vendor-specific request type */
 #define USB_TYPE_VENDOR ( 2 << 5 )
 
-/** Request recipient mask */
-#define USB_RECIP_MASK ( 0x1f << 0 )
-
 /** Request recipient is the device */
 #define USB_RECIP_DEVICE ( 0 << 0 )
 
@@ -414,9 +411,7 @@ struct usb_endpoint {
 
        /** Recycled I/O buffer list */
        struct list_head recycled;
-       /** Refill buffer reserved header length */
-       size_t reserve;
-       /** Refill buffer payload length */
+       /** Refill buffer length */
        size_t len;
        /** Maximum fill level */
        unsigned int max;
@@ -460,11 +455,11 @@ struct usb_endpoint_host_operations {
         *
         * @v ep                USB endpoint
         * @v iobuf             I/O buffer
-        * @v zlp               Append a zero-length packet
+        * @v terminate         Terminate using a short packet
         * @ret rc              Return status code
         */
        int ( * stream ) ( struct usb_endpoint *ep, struct io_buffer *iobuf,
-                          int zlp );
+                          int terminate );
 };
 
 /** USB endpoint driver operations */
@@ -590,16 +585,13 @@ extern void usb_complete_err ( struct usb_endpoint *ep,
  * Initialise USB endpoint refill
  *
  * @v ep               USB endpoint
- * @v reserve          Refill buffer reserved header length
- * @v len              Refill buffer payload length (zero for endpoint's MTU)
+ * @v len              Refill buffer length (or zero to use endpoint's MTU)
  * @v max              Maximum fill level
  */
 static inline __attribute__ (( always_inline )) void
-usb_refill_init ( struct usb_endpoint *ep, size_t reserve, size_t len,
-                 unsigned int max ) {
+usb_refill_init ( struct usb_endpoint *ep, size_t len, unsigned int max ) {
 
        INIT_LIST_HEAD ( &ep->recycled );
-       ep->reserve = reserve;
        ep->len = len;
        ep->max = max;
 }
@@ -620,31 +612,6 @@ extern int usb_prefill ( struct usb_endpoint *ep );
 extern int usb_refill ( struct usb_endpoint *ep );
 extern void usb_flush ( struct usb_endpoint *ep );
 
-/** A USB class descriptor */
-union usb_class_descriptor {
-       /** Class */
-       struct usb_class class;
-       /** Scalar value */
-       uint32_t scalar;
-};
-
-/**
- * A USB function descriptor
- *
- * This is an internal descriptor used to represent an association of
- * interfaces within a USB device.
- */
-struct usb_function_descriptor {
-       /** Vendor ID */
-       uint16_t vendor;
-       /** Product ID */
-       uint16_t product;
-       /** Class */
-       union usb_class_descriptor class;
-       /** Number of interfaces */
-       unsigned int count;
-};
-
 /**
  * A USB function
  *
@@ -656,8 +623,10 @@ struct usb_function {
        const char *name;
        /** USB device */
        struct usb_device *usb;
-       /** Function descriptor */
-       struct usb_function_descriptor desc;
+       /** Class */
+       struct usb_class class;
+       /** Number of interfaces */
+       unsigned int count;
        /** Generic device */
        struct device dev;
        /** List of functions within this USB device */
@@ -667,8 +636,6 @@ struct usb_function {
        struct usb_driver *driver;
        /** Driver private data */
        void *priv;
-       /** Driver device ID */
-       struct usb_device_id *id;
 
        /** List of interface numbers
         *
@@ -705,8 +672,6 @@ struct usb_device {
        char name[32];
        /** USB port */
        struct usb_port *port;
-       /** Device speed */
-       unsigned int speed;
        /** List of devices on this bus */
        struct list_head list;
        /** Device address, if assigned */
@@ -1193,7 +1158,7 @@ usb_get_device_descriptor ( struct usb_device *usb,
  * @v data             Configuration descriptor to fill in
  * @ret rc             Return status code
  */
-static inline __attribute__ (( always_inline )) int
+static inline __attribute (( always_inline )) int
 usb_get_config_descriptor ( struct usb_device *usb, unsigned int index,
                            struct usb_configuration_descriptor *data,
                            size_t len ) {
@@ -1315,58 +1280,19 @@ struct usb_device_id {
        uint16_t vendor;
        /** Product ID */
        uint16_t product;
-       /** Arbitrary driver data */
-       unsigned long driver_data;
+       /** Class */
+       struct usb_class class;
 };
 
 /** Match-anything ID */
 #define USB_ANY_ID 0xffff
 
-/** A USB class ID */
-struct usb_class_id {
-       /** Class */
-       union usb_class_descriptor class;
-       /** Class mask */
-       union usb_class_descriptor mask;
-};
-
-/** Construct USB class ID
- *
- * @v base             Base class code (or USB_ANY_ID)
- * @v subclass         Subclass code (or USB_ANY_ID)
- * @v protocol         Protocol code (or USB_ANY_ID)
- */
-#define USB_CLASS_ID( base, subclass, protocol ) {                     \
-       .class = {                                                      \
-               .class = {                                              \
-                       ( (base) & 0xff ),                              \
-                       ( (subclass) & 0xff ),                          \
-                       ( (protocol) & 0xff ),                          \
-               },                                                      \
-       },                                                              \
-       .mask = {                                                       \
-               .class = {                                              \
-                       ( ( (base) == USB_ANY_ID ) ? 0x00 : 0xff ),     \
-                       ( ( (subclass) == USB_ANY_ID ) ? 0x00 : 0xff ), \
-                       ( ( (protocol) == USB_ANY_ID ) ? 0x00 : 0xff ), \
-               },                                                      \
-               },                                                      \
-       }
-
 /** A USB driver */
 struct usb_driver {
        /** USB ID table */
        struct usb_device_id *ids;
        /** Number of entries in ID table */
        unsigned int id_count;
-       /** Class ID */
-       struct usb_class_id class;
-       /** Driver score
-        *
-        * This is used to determine the preferred configuration for a
-        * USB device.
-        */
-       unsigned int score;
        /**
         * Probe device
         *
@@ -1390,18 +1316,4 @@ struct usb_driver {
 /** Declare a USB driver */
 #define __usb_driver __table_entry ( USB_DRIVERS, 01 )
 
-/** USB driver scores */
-enum usb_driver_score {
-       /** Fallback driver (has no effect on overall score) */
-       USB_SCORE_FALLBACK = 0,
-       /** Deprecated driver */
-       USB_SCORE_DEPRECATED = 1,
-       /** Normal driver */
-       USB_SCORE_NORMAL = 2,
-};
-
-extern struct usb_driver *
-usb_find_driver ( struct usb_function_descriptor *desc,
-                 struct usb_device_id **id );
-
 #endif /* _IPXE_USB_H */
index 233534e..fe9d844 100644 (file)
@@ -33,20 +33,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
        ( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE |          \
          USB_REQUEST_TYPE ( 0x0a ) )
 
-/** Set report */
-#define USBHID_SET_REPORT                                              \
-       ( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE |          \
-         USB_REQUEST_TYPE ( 0x09 ) )
-
-/** Input report type */
-#define USBHID_REPORT_INPUT 0x01
-
-/** Output report type */
-#define USBHID_REPORT_OUTPUT 0x02
-
-/** Feature report type */
-#define USBHID_REPORT_FEATURE 0x03
-
 /** A USB human interface device */
 struct usb_hid {
        /** USB function */
@@ -111,26 +97,6 @@ usbhid_set_idle ( struct usb_device *usb, unsigned int interface,
                             interface, NULL, 0 );
 }
 
-/**
- * Set report
- *
- * @v usb              USB device
- * @v interface                Interface number
- * @v type             Report type
- * @v report           Report ID
- * @v data             Report data
- * @v len              Length of report data
- * @ret rc             Return status code
- */
-static inline __attribute__ (( always_inline )) int
-usbhid_set_report ( struct usb_device *usb, unsigned int interface,
-                   unsigned int type, unsigned int report, void *data,
-                   size_t len ) {
-
-       return usb_control ( usb, USBHID_SET_REPORT, ( ( type << 8 ) | report ),
-                            interface, data, len );
-}
-
 extern int usbhid_open ( struct usb_hid *hid );
 extern void usbhid_close ( struct usb_hid *hid );
 extern int usbhid_refill ( struct usb_hid *hid );
index f3c9b17..a09c463 100644 (file)
 /* Virtio ABI version, this must match exactly */
 #define VIRTIO_PCI_ABI_VERSION          0
 
-/* PCI capability types: */
-#define VIRTIO_PCI_CAP_COMMON_CFG       1  /* Common configuration */
-#define VIRTIO_PCI_CAP_NOTIFY_CFG       2  /* Notifications */
-#define VIRTIO_PCI_CAP_ISR_CFG          3  /* ISR access */
-#define VIRTIO_PCI_CAP_DEVICE_CFG       4  /* Device specific configuration */
-#define VIRTIO_PCI_CAP_PCI_CFG          5  /* PCI configuration access */
-
-#define __u8       uint8_t
-#define __le16     uint16_t
-#define __le32     uint32_t
-#define __le64     uint64_t
-
-/* This is the PCI capability header: */
-struct virtio_pci_cap {
-    __u8 cap_vndr;    /* Generic PCI field: PCI_CAP_ID_VNDR */
-    __u8 cap_next;    /* Generic PCI field: next ptr. */
-    __u8 cap_len;     /* Generic PCI field: capability length */
-    __u8 cfg_type;    /* Identifies the structure. */
-    __u8 bar;         /* Where to find it. */
-    __u8 padding[3];  /* Pad to full dword. */
-    __le32 offset;    /* Offset within bar. */
-    __le32 length;    /* Length of the structure, in bytes. */
-};
-
-struct virtio_pci_notify_cap {
-    struct virtio_pci_cap cap;
-    __le32 notify_off_multiplier; /* Multiplier for queue_notify_off. */
-};
-
-struct virtio_pci_cfg_cap {
-    struct virtio_pci_cap cap;
-    __u8 pci_cfg_data[4]; /* Data for BAR access. */
-};
-
-/* Fields in VIRTIO_PCI_CAP_COMMON_CFG: */
-struct virtio_pci_common_cfg {
-    /* About the whole device. */
-    __le32 device_feature_select; /* read-write */
-    __le32 device_feature;        /* read-only */
-    __le32 guest_feature_select;  /* read-write */
-    __le32 guest_feature;         /* read-write */
-    __le16 msix_config;           /* read-write */
-    __le16 num_queues;            /* read-only */
-    __u8 device_status;           /* read-write */
-    __u8 config_generation;       /* read-only */
-
-    /* About a specific virtqueue. */
-    __le16 queue_select;          /* read-write */
-    __le16 queue_size;            /* read-write, power of 2. */
-    __le16 queue_msix_vector;     /* read-write */
-    __le16 queue_enable;          /* read-write */
-    __le16 queue_notify_off;      /* read-only */
-    __le32 queue_desc_lo;         /* read-write */
-    __le32 queue_desc_hi;         /* read-write */
-    __le32 queue_avail_lo;        /* read-write */
-    __le32 queue_avail_hi;        /* read-write */
-    __le32 queue_used_lo;         /* read-write */
-    __le32 queue_used_hi;         /* read-write */
-};
-
-/* Virtio 1.0 PCI region descriptor. We support memory mapped I/O, port I/O,
- * and PCI config space access via the cfg PCI capability as a fallback. */
-struct virtio_pci_region {
-    void *base;
-    size_t length;
-    u8 bar;
-
-/* How to interpret the base field */
-#define VIRTIO_PCI_REGION_TYPE_MASK  0x00000003
-/* The base field is a memory address */
-#define VIRTIO_PCI_REGION_MEMORY     0x00000001
-/* The base field is a port address */
-#define VIRTIO_PCI_REGION_PORT       0x00000002
-/* The base field is an offset within the PCI bar */
-#define VIRTIO_PCI_REGION_PCI_CONFIG 0x00000003
-    unsigned flags;
-};
-
-/* Virtio 1.0 device state */
-struct virtio_pci_modern_device {
-    struct pci_device *pci;
-
-    /* VIRTIO_PCI_CAP_PCI_CFG position */
-    int cfg_cap_pos;
-
-    /* VIRTIO_PCI_CAP_COMMON_CFG data */
-    struct virtio_pci_region common;
-
-    /* VIRTIO_PCI_CAP_DEVICE_CFG data */
-    struct virtio_pci_region device;
-
-    /* VIRTIO_PCI_CAP_ISR_CFG data */
-    struct virtio_pci_region isr;
-
-    /* VIRTIO_PCI_CAP_NOTIFY_CFG data */
-    int notify_cap_pos;
-};
-
 static inline u32 vp_get_features(unsigned int ioaddr)
 {
    return inl(ioaddr + VIRTIO_PCI_HOST_FEATURES);
@@ -194,115 +96,6 @@ static inline void vp_del_vq(unsigned int ioaddr, int queue_index)
    outl(0, ioaddr + VIRTIO_PCI_QUEUE_PFN);
 }
 
-struct vring_virtqueue;
-
 int vp_find_vq(unsigned int ioaddr, int queue_index,
                struct vring_virtqueue *vq);
-
-/* Virtio 1.0 I/O routines abstract away the three possible HW access
- * mechanisms - memory, port I/O, and PCI cfg space access. Also built-in
- * are endianness conversions - to LE on write and from LE on read. */
-
-void vpm_iowrite8(struct virtio_pci_modern_device *vdev,
-                  struct virtio_pci_region *region, u8 data, size_t offset);
-
-void vpm_iowrite16(struct virtio_pci_modern_device *vdev,
-                   struct virtio_pci_region *region, u16 data, size_t offset);
-
-void vpm_iowrite32(struct virtio_pci_modern_device *vdev,
-                   struct virtio_pci_region *region, u32 data, size_t offset);
-
-static inline void vpm_iowrite64(struct virtio_pci_modern_device *vdev,
-                                 struct virtio_pci_region *region,
-                                 u64 data, size_t offset_lo, size_t offset_hi)
-{
-    vpm_iowrite32(vdev, region, (u32)data, offset_lo);
-    vpm_iowrite32(vdev, region, data >> 32, offset_hi);
-}
-
-u8 vpm_ioread8(struct virtio_pci_modern_device *vdev,
-               struct virtio_pci_region *region, size_t offset);
-
-u16 vpm_ioread16(struct virtio_pci_modern_device *vdev,
-                 struct virtio_pci_region *region, size_t offset);
-
-u32 vpm_ioread32(struct virtio_pci_modern_device *vdev,
-                 struct virtio_pci_region *region, size_t offset);
-
-/* Virtio 1.0 device manipulation routines */
-
-#define COMMON_OFFSET(field) offsetof(struct virtio_pci_common_cfg, field)
-
-static inline void vpm_reset(struct virtio_pci_modern_device *vdev)
-{
-    vpm_iowrite8(vdev, &vdev->common, 0, COMMON_OFFSET(device_status));
-    while (vpm_ioread8(vdev, &vdev->common, COMMON_OFFSET(device_status)))
-        mdelay(1);
-}
-
-static inline u8 vpm_get_status(struct virtio_pci_modern_device *vdev)
-{
-    return vpm_ioread8(vdev, &vdev->common, COMMON_OFFSET(device_status));
-}
-
-static inline void vpm_add_status(struct virtio_pci_modern_device *vdev,
-                                  u8 status)
-{
-    u8 curr_status = vpm_ioread8(vdev, &vdev->common, COMMON_OFFSET(device_status));
-    vpm_iowrite8(vdev, &vdev->common,
-                 curr_status | status, COMMON_OFFSET(device_status));
-}
-
-static inline u64 vpm_get_features(struct virtio_pci_modern_device *vdev)
-{
-    u32 features_lo, features_hi;
-
-    vpm_iowrite32(vdev, &vdev->common, 0, COMMON_OFFSET(device_feature_select));
-    features_lo = vpm_ioread32(vdev, &vdev->common, COMMON_OFFSET(device_feature));
-    vpm_iowrite32(vdev, &vdev->common, 1, COMMON_OFFSET(device_feature_select));
-    features_hi = vpm_ioread32(vdev, &vdev->common, COMMON_OFFSET(device_feature));
-
-    return ((u64)features_hi << 32) | features_lo;
-}
-
-static inline void vpm_set_features(struct virtio_pci_modern_device *vdev,
-                                    u64 features)
-{
-    u32 features_lo = (u32)features;
-    u32 features_hi = features >> 32;
-
-    vpm_iowrite32(vdev, &vdev->common, 0, COMMON_OFFSET(guest_feature_select));
-    vpm_iowrite32(vdev, &vdev->common, features_lo, COMMON_OFFSET(guest_feature));
-    vpm_iowrite32(vdev, &vdev->common, 1, COMMON_OFFSET(guest_feature_select));
-    vpm_iowrite32(vdev, &vdev->common, features_hi, COMMON_OFFSET(guest_feature));
-}
-
-static inline void vpm_get(struct virtio_pci_modern_device *vdev,
-                           unsigned offset, void *buf, unsigned len)
-{
-    u8 *ptr = buf;
-    unsigned i;
-
-    for (i = 0; i < len; i++)
-        ptr[i] = vpm_ioread8(vdev, &vdev->device, offset + i);
-}
-
-static inline u8 vpm_get_isr(struct virtio_pci_modern_device *vdev)
-{
-    return vpm_ioread8(vdev, &vdev->isr, 0);
-}
-
-void vpm_notify(struct virtio_pci_modern_device *vdev,
-                struct vring_virtqueue *vq);
-
-int vpm_find_vqs(struct virtio_pci_modern_device *vdev,
-                 unsigned nvqs, struct vring_virtqueue *vqs);
-
-int virtio_pci_find_capability(struct pci_device *pci, uint8_t cfg_type);
-
-int virtio_pci_map_capability(struct pci_device *pci, int cap, size_t minlen,
-                              u32 align, u32 start, u32 size,
-                              struct virtio_pci_region *region);
-
-void virtio_pci_unmap_capability(struct virtio_pci_region *region);
 #endif /* _VIRTIO_PCI_H_ */
index 6ba550b..c687aca 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef _VIRTIO_RING_H_
 # define _VIRTIO_RING_H_
 
-#include <ipxe/virtio-pci.h>
-
 /* Status byte for guest to report progress, and synchronize features. */
 /* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
 #define VIRTIO_CONFIG_S_ACKNOWLEDGE     1
@@ -10,17 +8,9 @@
 #define VIRTIO_CONFIG_S_DRIVER          2
 /* Driver has used its parts of the config, and is happy */
 #define VIRTIO_CONFIG_S_DRIVER_OK       4
-/* Driver has finished configuring features */
-#define VIRTIO_CONFIG_S_FEATURES_OK     8
 /* We've given up on this device. */
 #define VIRTIO_CONFIG_S_FAILED          0x80
 
-/* Virtio feature flags used to negotiate device and driver features. */
-/* Can the device handle any descriptor layout? */
-#define VIRTIO_F_ANY_LAYOUT             27
-/* v1.0 compliant. */
-#define VIRTIO_F_VERSION_1              32
-
 #define MAX_QUEUE_NUM      (256)
 
 #define VRING_DESC_F_NEXT  1
@@ -81,7 +71,6 @@ struct vring_virtqueue {
    void *vdata[MAX_QUEUE_NUM];
    /* PCI */
    int queue_index;
-   struct virtio_pci_region notification;
 };
 
 struct vring_list {
@@ -145,7 +134,6 @@ void *vring_get_buf(struct vring_virtqueue *vq, unsigned int *len);
 void vring_add_buf(struct vring_virtqueue *vq, struct vring_list list[],
                    unsigned int out, unsigned int in,
                    void *index, int num_added);
-void vring_kick(struct virtio_pci_modern_device *vdev, unsigned int ioaddr,
-                struct vring_virtqueue *vq, int num_added);
+void vring_kick(unsigned int ioaddr, struct vring_virtqueue *vq, int num_added);
 
 #endif /* _VIRTIO_RING_H_ */
index 0fb8b76..eac1145 100644 (file)
@@ -13,7 +13,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define __XEN_INTERFACE_VERSION__ 0x00040400
 
 #include <stdint.h>
-#include <ipxe/bitops.h>
 #include <ipxe/uaccess.h>
 #include <xen/xen.h>
 #include <xen/event_channel.h>
@@ -59,19 +58,6 @@ struct xen_hypervisor {
        struct xen_store store;
 };
 
-/**
- * Test and clear pending event
- *
- * @v xen              Xen hypervisor
- * @v port             Event channel port
- * @ret pending                Event was pending
- */
-static inline __attribute__ (( always_inline )) int
-xenevent_pending ( struct xen_hypervisor *xen, evtchn_port_t port ) {
-
-       return test_and_clear_bit ( port, xen->shared->evtchn_pending );
-}
-
 #include <bits/xen.h>
 
 /**
diff --git a/roms/ipxe/src/include/ipxe/xsigo.h b/roms/ipxe/src/include/ipxe/xsigo.h
deleted file mode 100644 (file)
index f4f14c4..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-#ifndef _IPXE_XSIGO_H
-#define _IPXE_XSIGO_H
-
-/** @file
- *
- * Xsigo virtual Ethernet devices
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <ipxe/infiniband.h>
-#include <ipxe/eoib.h>
-
-/** Xsigo directory service record name */
-#define XDS_SERVICE_NAME "XSIGOXDS"
-
-/** Xsigo configuration manager service ID */
-#define XCM_SERVICE_ID { 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0x97, 0x01 }
-
-/** Xsigo management class */
-#define XSIGO_MGMT_CLASS 0x0b
-
-/** Xsigo management class version */
-#define XSIGO_MGMT_CLASS_VERSION 2
-
-/** Xsigo configuration manager request MAD */
-#define XSIGO_ATTR_XCM_REQUEST 0xb002
-
-/** Generic operating system type */
-#define XSIGO_OS_TYPE_GENERIC 0x40
-
-/** Xsigo virtual Ethernet broadcast GID prefix */
-#define XVE_PREFIX 0xff15101cUL
-
-/** Xsigo resource types */
-enum xsigo_resource_type {
-       /** Virtual Ethernet resource type */
-       XSIGO_RESOURCE_XVE = ( 1 << 6 ),
-       /** Absence-of-high-availability "resource" type */
-       XSIGO_RESOURCE_NO_HA = ( 1 << 4 ),
-};
-
-/** A Xsigo server identifier */
-struct xsigo_server_id {
-       /** Virtual machine ID */
-       uint32_t vm;
-       /** Port GUID */
-       union ib_guid guid;
-} __attribute__ (( packed ));
-
-/** A Xsigo configuration manager identifier */
-struct xsigo_manager_id {
-       /** Port GUID */
-       union ib_guid guid;
-       /** LID */
-       uint16_t lid;
-       /** Reserved */
-       uint8_t reserved[10];
-} __attribute__ (( packed ));
-
-/** A Xsigo configuration manager request MAD */
-struct xsigo_managers_request {
-       /** MAD header */
-       struct ib_mad_hdr mad_hdr;
-       /** Reserved */
-       uint8_t reserved0[32];
-       /** Server ID */
-       struct xsigo_server_id server;
-       /** Hostname */
-       char hostname[ 65 /* Seriously, guys? */ ];
-       /** OS version */
-       char os_version[32];
-       /** CPU architecture */
-       char arch[16];
-       /** OS type */
-       uint8_t os_type;
-       /** Reserved */
-       uint8_t reserved1[3];
-       /** Firmware version */
-       uint64_t firmware_version;
-       /** Hardware version */
-       uint32_t hardware_version;
-       /** Driver version */
-       uint32_t driver_version;
-       /** System ID */
-       union ib_gid system_id;
-       /** Resource types */
-       uint16_t resources;
-       /** Reserved */
-       uint8_t reserved2[2];
-       /** Build version */
-       char build[16];
-       /** Reserved */
-       uint8_t reserved3[19];
-} __attribute__ (( packed ));
-
-/** Resource types are present */
-#define XSIGO_RESOURCES_PRESENT 0x8000
-
-/** A Xsigo configuration manager reply MAD */
-struct xsigo_managers_reply {
-       /** MAD header */
-       struct ib_mad_hdr mad_hdr;
-       /** Reserved */
-       uint8_t reserved0[32];
-       /** Server ID */
-       struct xsigo_server_id server;
-       /** Number of XCM records */
-       uint8_t count;
-       /** Version */
-       uint8_t version;
-       /** Reserved */
-       uint8_t reserved1[2];
-       /** Managers */
-       struct xsigo_manager_id manager[8];
-       /** Reserved */
-       uint8_t reserved2[24];
-} __attribute__ (( packed ));
-
-/** A Xsigo MAD */
-union xsigo_mad {
-       /** Generic MAD */
-       union ib_mad mad;
-       /** Configuration manager request */
-       struct xsigo_managers_request request;
-       /** Configuration manager reply */
-       struct xsigo_managers_reply reply;
-} __attribute__ (( packed ));
-
-/** An XSMP node identifier */
-struct xsmp_node_id {
-       /** Auxiliary ID (never used) */
-       uint32_t aux;
-       /** Port GUID */
-       union ib_guid guid;
-} __attribute__ (( packed ));
-
-/** An XSMP message header */
-struct xsmp_message_header {
-       /** Message type */
-       uint8_t type;
-       /** Reason code */
-       uint8_t code;
-       /** Length */
-       uint16_t len;
-       /** Sequence number */
-       uint32_t seq;
-       /** Source node ID */
-       struct xsmp_node_id src;
-       /** Destination node ID */
-       struct xsmp_node_id dst;
-} __attribute__ (( packed ));
-
-/** XSMP message types */
-enum xsmp_message_type {
-       /** Session message type */
-       XSMP_TYPE_SESSION = 1,
-       /** Virtual Ethernet message type */
-       XSMP_TYPE_XVE = 6,
-};
-
-/** An XSMP session message */
-struct xsmp_session_message {
-       /** Message header */
-       struct xsmp_message_header hdr;
-       /** Message type */
-       uint8_t type;
-       /** Reason code */
-       uint8_t code;
-       /** Length (excluding message header) */
-       uint16_t len;
-       /** Operating system type */
-       uint8_t os_type;
-       /** Reserved */
-       uint8_t reserved0;
-       /** Resource types */
-       uint16_t resources;
-       /** Driver version */
-       uint32_t driver_version;
-       /** Required chassis version */
-       uint32_t chassis_version;
-       /** Boot flags */
-       uint32_t boot;
-       /** Firmware version */
-       uint64_t firmware_version;
-       /** Hardware version */
-       uint32_t hardware_version;
-       /** Vendor part ID */
-       uint32_t vendor;
-       /** Protocol version */
-       uint32_t xsmp_version;
-       /** Chassis name */
-       char chassis[32];
-       /** Session name */
-       char session[32];
-       /** Reserved */
-       uint8_t reserved1[120];
-} __attribute__ (( packed ));
-
-/** XSMP session message types */
-enum xsmp_session_type {
-       /** Keepalive message */
-       XSMP_SESSION_TYPE_HELLO = 1,
-       /** Initial registration message */
-       XSMP_SESSION_TYPE_REGISTER = 2,
-       /** Registration confirmation message */
-       XSMP_SESSION_TYPE_CONFIRM = 3,
-       /** Registration rejection message */
-       XSMP_SESSION_TYPE_REJECT = 4,
-       /** Shutdown message */
-       XSMP_SESSION_TYPE_SHUTDOWN = 5,
-};
-
-/** XSMP boot flags */
-enum xsmp_session_boot {
-       /** PXE boot */
-       XSMP_BOOT_PXE = ( 1 << 0 ),
-};
-
-/** XSMP virtual Ethernet channel adapter parameters */
-struct xsmp_xve_ca {
-       /** Subnet prefix (little-endian) */
-       union ib_guid prefix_le;
-       /** Control queue pair number */
-       uint32_t ctrl;
-       /** Data queue pair number */
-       uint32_t data;
-       /** Partition key */
-       uint16_t pkey;
-       /** Queue key */
-       uint16_t qkey;
-} __attribute__ (( packed ));
-
-/** XSMP virtual Ethernet MAC address */
-struct xsmp_xve_mac {
-       /** High 16 bits */
-       uint16_t high;
-       /** Low 32 bits */
-       uint32_t low;
-} __attribute__ (( packed ));
-
-/** An XSMP virtual Ethernet message */
-struct xsmp_xve_message {
-       /** Message header */
-       struct xsmp_message_header hdr;
-       /** Message type */
-       uint8_t type;
-       /** Reason code */
-       uint8_t code;
-       /** Length (excluding message header) */
-       uint16_t len;
-       /** Update bitmask */
-       uint32_t update;
-       /** Resource identifier */
-       union ib_guid resource;
-       /** TCA GUID (little-endian) */
-       union ib_guid guid_le;
-       /** TCA LID */
-       uint16_t lid;
-       /** MAC address (little-endian) */
-       struct xsmp_xve_mac mac_le;
-       /** Rate */
-       uint16_t rate;
-       /** Administrative state (non-zero = "up") */
-       uint16_t state;
-       /** Encapsulation (apparently obsolete and unused) */
-       uint16_t encap;
-       /** MTU */
-       uint16_t mtu;
-       /** Installation flags (apparently obsolete and unused) */
-       uint32_t install;
-       /** Interface name */
-       char name[16];
-       /** Service level */
-       uint16_t sl;
-       /** Flow control enabled (apparently obsolete and unused) */
-       uint16_t flow;
-       /** Committed rate (in Mbps) */
-       uint16_t committed_mbps;
-       /** Peak rate (in Mbps) */
-       uint16_t peak_mbps;
-       /** Committed burst size (in bytes) */
-       uint32_t committed_burst;
-       /** Peak burst size (in bytes) */
-       uint32_t peak_burst;
-       /** VMware index */
-       uint8_t vmware;
-       /** Reserved */
-       uint8_t reserved0;
-       /** Multipath flags */
-       uint16_t multipath;
-       /** Multipath group name */
-       char group[48];
-       /** Link aggregation flag */
-       uint8_t agg;
-       /** Link aggregation policy */
-       uint8_t policy;
-       /** Network ID */
-       uint32_t network;
-       /** Mode */
-       uint8_t mode;
-       /** Uplink type */
-       uint8_t uplink;
-       /** Target channel adapter parameters */
-       struct xsmp_xve_ca tca;
-       /** Host channel adapter parameters */
-       struct xsmp_xve_ca hca;
-       /** Reserved */
-       uint8_t reserved1[336];
-} __attribute__ (( packed ));
-
-/** XSMP virtual Ethernet message types */
-enum xsmp_xve_type {
-       /** Install virtual NIC */
-       XSMP_XVE_TYPE_INSTALL = 1,
-       /** Delete virtual NIC */
-       XSMP_XVE_TYPE_DELETE = 2,
-       /** Update virtual NIC */
-       XSMP_XVE_TYPE_UPDATE = 3,
-       /** Set operational state up */
-       XSMP_XVE_TYPE_OPER_UP = 6,
-       /** Set operational state down */
-       XSMP_XVE_TYPE_OPER_DOWN = 7,
-       /** Get operational state */
-       XSMP_XVE_TYPE_OPER_REQ = 15,
-       /** Virtual NIC is ready */
-       XSMP_XVE_TYPE_READY = 20,
-};
-
-/** XSMP virtual Ethernet message codes */
-enum xsmp_xve_code {
-       /* Something went wrong */
-       XSMP_XVE_CODE_ERROR = 0x84,
-};
-
-/** XSMP virtual Ethernet update bitmask */
-enum xsmp_xve_update {
-       /** Update MTU */
-       XSMP_XVE_UPDATE_MTU = ( 1 << 2 ),
-       /** Update administrative state */
-       XSMP_XVE_UPDATE_STATE = ( 1 << 6 ),
-       /** Update gateway to mark as down */
-       XSMP_XVE_UPDATE_GW_DOWN = ( 1 << 30 ),
-       /** Update gateway information */
-       XSMP_XVE_UPDATE_GW_CHANGE = ( 1 << 31 ),
-};
-
-/** XSMP virtual Ethernet modes */
-enum xsmp_xve_mode {
-       /** Reliable Connected */
-       XSMP_XVE_MODE_RC = 1,
-       /** Unreliable Datagram */
-       XSMP_XVE_MODE_UD = 2,
-};
-
-/** XSMP virtual Ethernet uplink types */
-enum xsmp_xve_uplink {
-       /** No uplink */
-       XSMP_XVE_NO_UPLINK = 1,
-       /** Has uplink */
-       XSMP_XVE_UPLINK = 2,
-};
-
-/** An XSMP message */
-union xsmp_message {
-       /** Message header */
-       struct xsmp_message_header hdr;
-       /** Session message */
-       struct xsmp_session_message sess;
-       /** Virtual Ethernet message */
-       struct xsmp_xve_message xve;
-};
-
-/** Delay between attempts to open the Infiniband device
- *
- * This is a policy decision.
- */
-#define XSIGO_OPEN_RETRY_DELAY ( 2 * TICKS_PER_SEC )
-
-/** Delay between unsuccessful discovery attempts
- *
- * This is a policy decision.
- */
-#define XSIGO_DISCOVERY_FAILURE_DELAY ( 10 * TICKS_PER_SEC )
-
-/** Delay between successful discovery attempts
- *
- * This is a policy decision.
- */
-#define XSIGO_DISCOVERY_SUCCESS_DELAY ( 20 * TICKS_PER_SEC )
-
-/** Delay between keepalive requests
- *
- * This is a policy decision.
- */
-#define XSIGO_KEEPALIVE_INTERVAL ( 10 * TICKS_PER_SEC )
-
-/** Maximum time to wait for a keepalive response
- *
- * This is a policy decision.
- */
-#define XSIGO_KEEPALIVE_MAX_WAIT ( 2 * TICKS_PER_SEC )
-
-#endif /* _IPXE_XSIGO_H */
index 8b06e88..4c91f57 100644 (file)
@@ -209,8 +209,7 @@ static inline void * legacy_isa_get_drvdata ( void *hwdev ) {
 
 #undef DRIVER
 #define DRIVER(_name_text,_unused2,_unused3,_name,_probe,_disable)       \
-       static __attribute__ (( unused )) const char                      \
-       _name ## _text[] = _name_text;                                    \
+       static const char _name ## _text[] = _name_text;                  \
        static inline int                                                 \
        _name ## _probe ( struct nic *nic, void *hwdev ) {                \
                return _probe ( nic, hwdev );                             \
index fb01c48..3c05629 100644 (file)
@@ -34,7 +34,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  */
 #define container_of( ptr, type, field ) ( {                           \
        type *__container;                                              \
-       const volatile typeof ( __container->field ) *__field = (ptr);  \
+       const typeof ( __container->field ) *__field = (ptr);           \
        __container = ( ( ( void * ) __field ) -                        \
                        offsetof ( type, field ) );                     \
        __container; } )
index 0f41820..0fab6c7 100644 (file)
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <stddef.h>
-
-extern void * generic_memset ( void *dest, int character,
-                              size_t len ) __nonnull;
-extern void * generic_memcpy ( void *dest, const void *src,
-                              size_t len ) __nonnull;
-extern void * generic_memmove ( void *dest, const void *src,
-                               size_t len ) __nonnull;
-
 #include <bits/string.h>
 
 /* Architecture-specific code is expected to provide these functions,
@@ -26,6 +18,12 @@ extern void * generic_memmove ( void *dest, const void *src,
 void * memset ( void *dest, int character, size_t len ) __nonnull;
 void * memcpy ( void *dest, const void *src, size_t len ) __nonnull;
 void * memmove ( void *dest, const void *src, size_t len ) __nonnull;
+extern void * generic_memset ( void *dest, int character,
+                              size_t len ) __nonnull;
+extern void * generic_memcpy ( void *dest, const void *src,
+                              size_t len ) __nonnull;
+extern void * generic_memmove ( void *dest, const void *src,
+                               size_t len ) __nonnull;
 
 extern int __pure memcmp ( const void *first, const void *second,
                           size_t len ) __nonnull;
index ab93a3d..462ac69 100644 (file)
@@ -39,10 +39,10 @@ struct tm {
  * @v t                        Time to fill in, or NULL
  * @ret time           Current time
  */
-static inline __attribute__ (( always_inline )) time_t time ( time_t *t ) {
+static inline time_t time ( time_t *t ) {
        time_t now;
 
-       now = ( time_now() + time_offset );
+       now = time_now();
        if ( t )
                *t = now;
        return now;
diff --git a/roms/ipxe/src/include/usr/ibmgmt.h b/roms/ipxe/src/include/usr/ibmgmt.h
deleted file mode 100644 (file)
index 16a0991..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _USR_IBMGMT_H
-#define _USR_IBMGMT_H
-
-/** @file
- *
- * Infiniband device management
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-struct ib_device;
-
-extern void ibstat ( struct ib_device *ibdev );
-
-#endif /* _USR_IBMGMT_H */
index bd66f4a..ce0fe5e 100644 (file)
@@ -10,7 +10,6 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 extern int loopback_test ( struct net_device *sender,
-                          struct net_device *receiver,
-                          size_t mtu, int broadcast );
+                          struct net_device *receiver, size_t mtu );
 
 #endif /* _USR_LOTEST_H */
diff --git a/roms/ipxe/src/include/usr/ntpmgmt.h b/roms/ipxe/src/include/usr/ntpmgmt.h
deleted file mode 100644 (file)
index 284e668..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _USR_NTPMGMT_H
-#define _USR_NTPMGMT_H
-
-/** @file
- *
- * NTP management
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-extern int ntp ( const char *hostname );
-
-#endif /* _USR_NTPMGMT_H */
index 5403919..545088d 100644 (file)
@@ -313,12 +313,12 @@ int bofm ( userptr_t bofmtab, struct pci_device *pci ) {
                }
                DBG ( "BOFM: slot %d port %d%s is " PCI_FMT " mport %d\n",
                      en.slot, ( en.port + 1 ),
-                     ( ( en.slot || en.port ) ? "" : "(?)" ), 0,
+                     ( ( en.slot || en.port ) ? "" : "(?)" ),
                      PCI_BUS ( en.busdevfn ), PCI_SLOT ( en.busdevfn ),
                      PCI_FUNC ( en.busdevfn ), en.mport );
                bofm = bofm_find_busdevfn ( en.busdevfn );
                if ( ! bofm ) {
-                       DBG ( "BOFM: " PCI_FMT " mport %d ignored\n", 0,
+                       DBG ( "BOFM: " PCI_FMT " mport %d ignored\n",
                              PCI_BUS ( en.busdevfn ), PCI_SLOT ( en.busdevfn ),
                              PCI_FUNC ( en.busdevfn ), en.mport );
                        continue;
index 00f6a1d..ea0e15f 100644 (file)
@@ -178,8 +178,8 @@ static int efi_bofm_supported ( EFI_HANDLE device ) {
 
        /* Look for a BOFM driver */
        if ( ( rc = bofm_find_driver ( &pci ) ) != 0 ) {
-               DBGCP ( device, "EFIBOFM %s has no driver\n",
-                       efi_handle_name ( device ) );
+               DBGCP ( device, "EFIBOFM %p %s has no driver\n",
+                       device, efi_handle_name ( device ) );
                return rc;
        }
 
@@ -187,8 +187,8 @@ static int efi_bofm_supported ( EFI_HANDLE device ) {
        if ( ( efirc = bs->LocateProtocol ( &bofm1_protocol_guid, NULL,
                                            &bofm1.interface ) ) != 0 ) {
                rc = -EEFI ( efirc );
-               DBGC ( device, "EFIBOFM %s cannot find BOFM protocol\n",
-                      efi_handle_name ( device ) );
+               DBGC ( device, "EFIBOFM %p %s cannot find BOFM protocol\n",
+                      device, efi_handle_name ( device ) );
                return rc;
        }
 
@@ -198,13 +198,13 @@ static int efi_bofm_supported ( EFI_HANDLE device ) {
                                                      0x00 /* No iSCSI */,
                                                      0x02 /* Version */ ))!=0){
                rc = -EEFI ( efirc );
-               DBGC ( device, "EFIBOFM %s could not register support: %s\n",
-                      efi_handle_name ( device ), strerror ( rc ) );
+               DBGC ( device, "EFIBOFM %p %s could not register support: %s\n",
+                      device, efi_handle_name ( device ), strerror ( rc ) );
                return rc;
        }
 
-       DBGC ( device, "EFIBOFM %s has driver \"%s\"\n",
-              efi_handle_name ( device ), pci.id->name );
+       DBGC ( device, "EFIBOFM %p %s has driver \"%s\"\n",
+              device, efi_handle_name ( device ), pci.id->name );
        return 0;
 }
 
@@ -241,48 +241,49 @@ static int efi_bofm_start ( struct efi_device *efidev ) {
        if ( ( efirc = bs->LocateProtocol ( &bofm1_protocol_guid, NULL,
                                            &bofm1.interface ) ) != 0 ) {
                rc = -EEFI ( efirc );
-               DBGC ( device, "EFIBOFM %s cannot find BOFM protocol\n",
-                      efi_handle_name ( device ) );
+               DBGC ( device, "EFIBOFM %p %s cannot find BOFM protocol\n",
+                      device, efi_handle_name ( device ) );
                goto err_locate_bofm;
        }
        bofmtab = &bofm1.bofm1->BofmTable;
-       DBGC ( device, "EFIBOFM %s found version 1 BOFM table at %p+%04x\n",
-              efi_handle_name ( device ), bofmtab, bofmtab->Parameters.Length);
+       DBGC ( device, "EFIBOFM %p %s found version 1 BOFM table at %p+%04x\n",
+              device, efi_handle_name ( device ), bofmtab,
+              bofmtab->Parameters.Length );
 
        /* Locate BOFM2 protocol, if available */
        if ( ( efirc = bs->LocateProtocol ( &bofm2_protocol_guid, NULL,
                                            &bofm2.interface ) ) == 0 ) {
                bofmtab2 = &bofm2.bofm2->BofmTable;
-               DBGC ( device, "EFIBOFM %s found version 2 BOFM table at "
-                      "%p+%04x\n", efi_handle_name ( device ), bofmtab2,
-                      bofmtab2->Parameters.Length );
+               DBGC ( device, "EFIBOFM %p %s found version 2 BOFM table at "
+                      "%p+%04x\n", device, efi_handle_name ( device ),
+                      bofmtab2, bofmtab2->Parameters.Length );
                assert ( bofm2.bofm2->RegisterSupport ==
                         bofm1.bofm1->RegisterSupport );
        } else {
-               DBGC ( device, "EFIBOFM %s cannot find BOFM2 protocol\n",
-                      efi_handle_name ( device ) );
+               DBGC ( device, "EFIBOFM %p %s cannot find BOFM2 protocol\n",
+                      device, efi_handle_name ( device ) );
                /* Not a fatal error; may be a BOFM1-only system */
                bofmtab2 = NULL;
        }
 
        /* Process BOFM table */
-       DBGC2 ( device, "EFIBOFM %s version 1 before processing:\n",
-               efi_handle_name ( device ) );
+       DBGC2 ( device, "EFIBOFM %p %s version 1 before processing:\n",
+               device, efi_handle_name ( device ) );
        DBGC2_HD ( device, bofmtab, bofmtab->Parameters.Length );
        if ( bofmtab2 ) {
-               DBGC2 ( device, "EFIBOFM %s version 2 before processing:\n",
-                       efi_handle_name ( device ) );
+               DBGC2 ( device, "EFIBOFM %p %s version 2 before processing:\n",
+                       device, efi_handle_name ( device ) );
                DBGC2_HD ( device, bofmtab2, bofmtab2->Parameters.Length );
        }
        bofmrc = bofm ( virt_to_user ( bofmtab2 ? bofmtab2 : bofmtab ), &pci );
-       DBGC ( device, "EFIBOFM %s status %08x\n",
-              efi_handle_name ( device ), bofmrc );
-       DBGC2 ( device, "EFIBOFM %s version 1 after processing:\n",
-               efi_handle_name ( device ) );
+       DBGC ( device, "EFIBOFM %p %s status %08x\n",
+              device, efi_handle_name ( device ), bofmrc );
+       DBGC2 ( device, "EFIBOFM %p %s version 1 after processing:\n",
+               device, efi_handle_name ( device ) );
        DBGC2_HD ( device, bofmtab, bofmtab->Parameters.Length );
        if ( bofmtab2 ) {
-               DBGC2 ( device, "EFIBOFM %s version 2 after processing:\n",
-                       efi_handle_name ( device ) );
+               DBGC2 ( device, "EFIBOFM %p %s version 2 after processing:\n",
+                       device, efi_handle_name ( device ) );
                DBGC2_HD ( device, bofmtab2, bofmtab2->Parameters.Length );
        }
 
@@ -291,18 +292,18 @@ static int efi_bofm_start ( struct efi_device *efidev ) {
                if ( ( efirc = bofm2.bofm2->SetStatus ( bofm2.bofm2, device,
                                                        FALSE, bofmrc ) ) != 0){
                        rc = -EEFI ( efirc );
-                       DBGC ( device, "EFIBOFM %s could not set BOFM2 "
-                              "status: %s\n", efi_handle_name ( device ),
-                              strerror ( rc ) );
+                       DBGC ( device, "EFIBOFM %p %s could not set BOFM2 "
+                              "status: %s\n", device,
+                              efi_handle_name ( device ), strerror ( rc ) );
                        goto err_set_status;
                }
        } else {
                if ( ( efirc = bofm1.bofm1->SetStatus ( bofm1.bofm1, device,
                                                        FALSE, bofmrc ) ) != 0){
                        rc = -EEFI ( efirc );
-                       DBGC ( device, "EFIBOFM %s could not set BOFM "
-                              "status: %s\n", efi_handle_name ( device ),
-                              strerror ( rc ) );
+                       DBGC ( device, "EFIBOFM %p %s could not set BOFM "
+                              "status: %s\n", device,
+                              efi_handle_name ( device ), strerror ( rc ) );
                        goto err_set_status;
                }
        }
index 047baed..3b30f30 100644 (file)
@@ -239,14 +239,6 @@ static const char *ansi_sequences[] = {
        [SCAN_DELETE] = "[3~",
        [SCAN_PAGE_UP] = "[5~",
        [SCAN_PAGE_DOWN] = "[6~",
-       [SCAN_F5] = "[15~",
-       [SCAN_F6] = "[17~",
-       [SCAN_F7] = "[18~",
-       [SCAN_F8] = "[19~",
-       [SCAN_F9] = "[20~",
-       [SCAN_F10] = "[21~",
-       [SCAN_F11] = "[23~",
-       [SCAN_F12] = "[24~",
        /* EFI translates some (but not all) incoming escape sequences
         * via the serial console into equivalent scancodes.  When it
         * doesn't recognise a sequence, it helpfully(!) translates
index 19531fd..4738039 100644 (file)
@@ -35,7 +35,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <errno.h>
 #include <ipxe/uuid.h>
 #include <ipxe/base16.h>
-#include <ipxe/vsprintf.h>
 #include <ipxe/efi/efi.h>
 #include <ipxe/efi/efi_utils.h>
 #include <ipxe/efi/Protocol/ComponentName.h>
@@ -69,10 +68,6 @@ struct efi_well_known_guid {
 
 /** Well-known GUIDs */
 static struct efi_well_known_guid efi_well_known_guids[] = {
-       { &efi_absolute_pointer_protocol_guid,
-         "AbsolutePointer" },
-       { &efi_apple_net_boot_protocol_guid,
-         "AppleNetBoot" },
        { &efi_arp_protocol_guid,
          "Arp" },
        { &efi_arp_service_binding_protocol_guid,
@@ -85,8 +80,6 @@ static struct efi_well_known_guid efi_well_known_guids[] = {
          "ComponentName" },
        { &efi_component_name2_protocol_guid,
          "ComponentName2" },
-       { &efi_console_control_protocol_guid,
-         "ConsoleControl" },
        { &efi_device_path_protocol_guid,
          "DevicePath" },
        { &efi_driver_binding_protocol_guid,
@@ -101,8 +94,6 @@ static struct efi_well_known_guid efi_well_known_guids[] = {
          "GraphicsOutput" },
        { &efi_hii_config_access_protocol_guid,
          "HiiConfigAccess" },
-       { &efi_hii_font_protocol_guid,
-         "HiiFont" },
        { &efi_ip4_protocol_guid,
          "Ip4" },
        { &efi_ip4_config_protocol_guid,
@@ -137,42 +128,20 @@ static struct efi_well_known_guid efi_well_known_guids[] = {
          "PciRootBridgeIo" },
        { &efi_pxe_base_code_protocol_guid,
          "PxeBaseCode" },
-       { &efi_serial_io_protocol_guid,
-         "SerialIo" },
        { &efi_simple_file_system_protocol_guid,
          "SimpleFileSystem" },
        { &efi_simple_network_protocol_guid,
          "SimpleNetwork" },
-       { &efi_simple_pointer_protocol_guid,
-         "SimplePointer" },
-       { &efi_simple_text_input_protocol_guid,
-         "SimpleTextInput" },
-       { &efi_simple_text_input_ex_protocol_guid,
-         "SimpleTextInputEx" },
-       { &efi_simple_text_output_protocol_guid,
-         "SimpleTextOutput" },
        { &efi_tcg_protocol_guid,
          "Tcg" },
        { &efi_tcp4_protocol_guid,
          "Tcp4" },
        { &efi_tcp4_service_binding_protocol_guid,
          "Tcp4Sb" },
-       { &efi_tree_protocol_guid,
-         "TrEE" },
        { &efi_udp4_protocol_guid,
          "Udp4" },
        { &efi_udp4_service_binding_protocol_guid,
          "Udp4Sb" },
-       { &efi_uga_draw_protocol_guid,
-         "UgaDraw" },
-       { &efi_unicode_collation_protocol_guid,
-         "UnicodeCollation" },
-       { &efi_usb_hc_protocol_guid,
-         "UsbHc" },
-       { &efi_usb2_hc_protocol_guid,
-         "Usb2Hc" },
-       { &efi_usb_io_protocol_guid,
-         "UsbIo" },
        { &efi_vlan_config_protocol_guid,
          "VlanConfig" },
        { &efi_vlan_config_dxe_guid,
@@ -185,7 +154,7 @@ static struct efi_well_known_guid efi_well_known_guids[] = {
  * @v guid             GUID
  * @ret string         Printable string
  */
-const __attribute__ (( pure )) char * efi_guid_ntoa ( EFI_GUID *guid ) {
+const char * efi_guid_ntoa ( EFI_GUID *guid ) {
        union {
                union uuid uuid;
                EFI_GUID guid;
@@ -212,26 +181,6 @@ const __attribute__ (( pure )) char * efi_guid_ntoa ( EFI_GUID *guid ) {
 }
 
 /**
- * Name locate search type
- *
- * @v search_type      Locate search type
- * @ret name           Locate search type name
- */
-const __attribute__ (( pure )) char *
-efi_locate_search_type_name ( EFI_LOCATE_SEARCH_TYPE search_type ) {
-       static char buf[16];
-
-       switch ( search_type ) {
-       case AllHandles :       return "AllHandles";
-       case ByRegisterNotify:  return "ByRegisterNotify";
-       case ByProtocol:        return "ByProtocol";
-       default:
-               snprintf ( buf, sizeof ( buf ), "UNKNOWN<%d>", search_type );
-               return buf;
-       }
-}
-
-/**
  * Name protocol open attributes
  *
  * @v attributes       Protocol open attributes
@@ -242,8 +191,7 @@ efi_locate_search_type_name ( EFI_LOCATE_SEARCH_TYPE search_type ) {
  * (T)EST_PROTOCOL, BY_(C)HILD_CONTROLLER, BY_(D)RIVER, and
  * E(X)CLUSIVE.
  */
-const __attribute__ (( pure )) char *
-efi_open_attributes_name ( unsigned int attributes ) {
+static const char * efi_open_attributes_name ( unsigned int attributes ) {
        static char attribute_chars[] = "HGTCDX";
        static char name[ sizeof ( attribute_chars ) ];
        char *tmp = name;
@@ -275,9 +223,8 @@ void dbg_efi_openers ( EFI_HANDLE handle, EFI_GUID *protocol ) {
 
        /* Sanity check */
        if ( ( ! handle ) || ( ! protocol ) ) {
-               printf ( "HANDLE %s could not retrieve openers for %s\n",
-                        efi_handle_name ( handle ),
-                        efi_guid_ntoa ( protocol ) );
+               printf ( "EFI could not retrieve openers for %s on %p\n",
+                        efi_guid_ntoa ( protocol ), handle );
                return;
        }
 
@@ -285,24 +232,24 @@ void dbg_efi_openers ( EFI_HANDLE handle, EFI_GUID *protocol ) {
        if ( ( efirc = bs->OpenProtocolInformation ( handle, protocol, &openers,
                                                     &count ) ) != 0 ) {
                rc = -EEFI ( efirc );
-               printf ( "HANDLE %s could not retrieve openers for %s: %s\n",
-                        efi_handle_name ( handle ),
-                        efi_guid_ntoa ( protocol ), strerror ( rc ) );
+               printf ( "EFI could not retrieve openers for %s on %p: %s\n",
+                        efi_guid_ntoa ( protocol ), handle, strerror ( rc ) );
                return;
        }
 
        /* Dump list of openers */
        for ( i = 0 ; i < count ; i++ ) {
                opener = &openers[i];
-               printf ( "HANDLE %s %s opened %dx (%s)",
-                        efi_handle_name ( handle ),
+               printf ( "HANDLE %p %s %s opened %dx (%s)",
+                        handle, efi_handle_name ( handle ),
                         efi_guid_ntoa ( protocol ), opener->OpenCount,
                         efi_open_attributes_name ( opener->Attributes ) );
-               printf ( " by %s", efi_handle_name ( opener->AgentHandle ) );
+               printf ( " by %p %s", opener->AgentHandle,
+                        efi_handle_name ( opener->AgentHandle ) );
                if ( opener->ControllerHandle == handle ) {
                        printf ( "\n" );
                } else {
-                       printf ( " for %s\n",
+                       printf ( " for %p %s\n", opener->ControllerHandle,
                                 efi_handle_name ( opener->ControllerHandle ) );
                }
        }
@@ -327,8 +274,7 @@ void dbg_efi_protocols ( EFI_HANDLE handle ) {
 
        /* Sanity check */
        if ( ! handle ) {
-               printf ( "HANDLE %s could not retrieve protocols\n",
-                        efi_handle_name ( handle ) );
+               printf ( "EFI could not retrieve protocols for %p\n", handle );
                return;
        }
 
@@ -336,15 +282,16 @@ void dbg_efi_protocols ( EFI_HANDLE handle ) {
        if ( ( efirc = bs->ProtocolsPerHandle ( handle, &protocols,
                                                &count ) ) != 0 ) {
                rc = -EEFI ( efirc );
-               printf ( "HANDLE %s could not retrieve protocols: %s\n",
-                        efi_handle_name ( handle ), strerror ( rc ) );
+               printf ( "EFI could not retrieve protocols for %p: %s\n",
+                        handle, strerror ( rc ) );
                return;
        }
 
        /* Dump list of protocols */
        for ( i = 0 ; i < count ; i++ ) {
                protocol = protocols[i];
-               printf ( "HANDLE %s %s supported\n", efi_handle_name ( handle ),
+               printf ( "HANDLE %p %s %s supported\n",
+                        handle, efi_handle_name ( handle ),
                         efi_guid_ntoa ( protocol ) );
                dbg_efi_openers ( handle, protocol );
        }
@@ -359,10 +306,12 @@ void dbg_efi_protocols ( EFI_HANDLE handle ) {
  * @v path             Device path
  * @ret text           Textual representation of device path, or NULL
  */
-const __attribute__ (( pure )) char *
-efi_devpath_text ( EFI_DEVICE_PATH_PROTOCOL *path ) {
+const char * efi_devpath_text ( EFI_DEVICE_PATH_PROTOCOL *path ) {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        static char text[256];
+       void *start;
+       void *end;
+       size_t max_len;
        size_t len;
        CHAR16 *wtext;
 
@@ -375,8 +324,13 @@ efi_devpath_text ( EFI_DEVICE_PATH_PROTOCOL *path ) {
        /* If we have no DevicePathToText protocol then use a raw hex string */
        if ( ! efidpt ) {
                DBG ( "[No DevicePathToText]" );
-               len = efi_devpath_len ( path );
-               base16_encode ( path, len, text, sizeof ( text ) );
+               start = path;
+               end = efi_devpath_end ( path );
+               len = ( end - start );
+               max_len = ( ( sizeof ( text ) - 1 /* NUL */ ) / 2 /* "xx" */ );
+               if ( len > max_len )
+                       len = max_len;
+               base16_encode ( start, len, text, sizeof ( text ) );
                return text;
        }
 
@@ -609,42 +563,6 @@ efi_loaded_image_filepath_name ( EFI_LOADED_IMAGE_PROTOCOL *loaded ) {
        return efi_devpath_text ( loaded->FilePath );
 }
 
-/**
- * Get console input handle name
- *
- * @v input            Simple text input protocol
- * @ret name           Console input handle name, or NULL
- */
-static const char *
-efi_conin_name ( EFI_SIMPLE_TEXT_INPUT_PROTOCOL *input ) {
-
-       /* Check for match against ConIn */
-       if ( input == efi_systab->ConIn )
-               return "ConIn";
-
-       return NULL;
-}
-
-/**
- * Get console output handle name
- *
- * @v output           Simple text output protocol
- * @ret name           Console output handle name, or NULL
- */
-static const char *
-efi_conout_name ( EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *output ) {
-
-       /* Check for match against ConOut */
-       if ( output == efi_systab->ConOut )
-               return "ConOut";
-
-       /* Check for match against StdErr (if different from ConOut) */
-       if ( output == efi_systab->StdErr )
-               return "StdErr";
-
-       return NULL;
-}
-
 /** An EFI handle name type */
 struct efi_handle_name_type {
        /** Protocol */
@@ -693,12 +611,6 @@ static struct efi_handle_name_type efi_handle_name_types[] = {
        /* Handle's loaded image file path (for image handles) */
        EFI_HANDLE_NAME_TYPE ( &efi_loaded_image_protocol_guid,
                               efi_loaded_image_filepath_name ),
-       /* Our standard input file handle */
-       EFI_HANDLE_NAME_TYPE ( &efi_simple_text_input_protocol_guid,
-                              efi_conin_name ),
-       /* Our standard output and standard error file handles */
-       EFI_HANDLE_NAME_TYPE ( &efi_simple_text_output_protocol_guid,
-                              efi_conout_name ),
 };
 
 /**
@@ -707,13 +619,9 @@ static struct efi_handle_name_type efi_handle_name_types[] = {
  * @v handle           EFI handle
  * @ret text           Name of handle, or NULL
  */
-const __attribute__ (( pure )) char * efi_handle_name ( EFI_HANDLE handle ) {
+const char * efi_handle_name ( EFI_HANDLE handle ) {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        struct efi_handle_name_type *type;
-       static char buf[256];
-       size_t used = 0;
-       EFI_GUID **protocols;
-       UINTN count;
        unsigned int i;
        void *interface;
        const char *name;
@@ -753,19 +661,5 @@ const __attribute__ (( pure )) char * efi_handle_name ( EFI_HANDLE handle ) {
                        return name;
        }
 
-       /* If no name is found, then use the raw handle value and a
-        * list of installed protocols.
-        */
-       used = ssnprintf ( buf, sizeof ( buf ), "UNKNOWN<%p", handle );
-       if ( ( efirc = bs->ProtocolsPerHandle ( handle, &protocols,
-                                               &count ) ) == 0 ) {
-               for ( i = 0 ; i < count ; i++ ) {
-                       used += ssnprintf ( ( buf + used ),
-                                           ( sizeof ( buf ) - used ), ",%s",
-                                           efi_guid_ntoa ( protocols[i] ) );
-               }
-               bs->FreePool ( protocols );
-       }
-       used += ssnprintf ( ( buf + used ), ( sizeof ( buf ) - used ), ">" );
-       return buf;
+       return "UNKNOWN";
 }
index 22aa3ee..ba7784c 100644 (file)
@@ -30,7 +30,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/efi/Protocol/ComponentName2.h>
 #include <ipxe/efi/Protocol/DevicePath.h>
 #include <ipxe/efi/efi_strings.h>
-#include <ipxe/efi/efi_utils.h>
 #include <ipxe/efi/efi_driver.h>
 
 /** @file
@@ -69,16 +68,18 @@ static struct efi_device * efidev_find ( EFI_HANDLE device ) {
  * @ret efidev         Parent EFI device, or NULL
  */
 struct efi_device * efidev_parent ( struct device *dev ) {
-       struct device *parent;
+       struct device *parent = dev->parent;
+       struct efi_device *efidev;
 
-       /* Walk upwards until we find an EFI device */
-       while ( ( parent = dev->parent ) ) {
-               if ( parent->desc.bus_type == BUS_TYPE_EFI )
-                       return container_of ( parent, struct efi_device, dev );
-               dev = parent;
-       }
+       /* Check that parent exists and is an EFI device */
+       if ( ! parent )
+               return NULL;
+       if ( parent->desc.bus_type != BUS_TYPE_EFI )
+               return NULL;
 
-       return NULL;
+       /* Get containing EFI device */
+       efidev = container_of ( parent, struct efi_device, dev );
+       return efidev;
 }
 
 /**
@@ -95,29 +96,30 @@ efi_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
        struct efi_driver *efidrv;
        int rc;
 
-       DBGCP ( device, "EFIDRV %s DRIVER_SUPPORTED",
-               efi_handle_name ( device ) );
+       DBGCP ( device, "EFIDRV %p %s DRIVER_SUPPORTED",
+               device, efi_handle_name ( device ) );
        if ( child )
                DBGCP ( device, " (child %s)", efi_devpath_text ( child ) );
        DBGCP ( device, "\n" );
 
        /* Do nothing if we are already driving this device */
        if ( efidev_find ( device ) != NULL ) {
-               DBGCP ( device, "EFIDRV %s is already started\n",
-                       efi_handle_name ( device ) );
+               DBGCP ( device, "EFIDRV %p %s is already started\n",
+                       device, efi_handle_name ( device ) );
                return EFI_ALREADY_STARTED;
        }
 
        /* Look for a driver claiming to support this device */
        for_each_table_entry ( efidrv, EFI_DRIVERS ) {
                if ( ( rc = efidrv->supported ( device ) ) == 0 ) {
-                       DBGC ( device, "EFIDRV %s has driver \"%s\"\n",
-                              efi_handle_name ( device ), efidrv->name );
+                       DBGC ( device, "EFIDRV %p %s has driver \"%s\"\n",
+                              device, efi_handle_name ( device ),
+                              efidrv->name );
                        return 0;
                }
        }
-       DBGCP ( device, "EFIDRV %s has no driver\n",
-               efi_handle_name ( device ) );
+       DBGCP ( device, "EFIDRV %p %s has no driver\n",
+               device, efi_handle_name ( device ) );
 
        return EFI_UNSUPPORTED;
 }
@@ -133,19 +135,13 @@ efi_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
 static EFI_STATUS EFIAPI
 efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
                   EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        struct efi_driver *efidrv;
        struct efi_device *efidev;
-       union {
-               EFI_DEVICE_PATH_PROTOCOL *path;
-               void *interface;
-       } path;
-       EFI_DEVICE_PATH_PROTOCOL *path_end;
-       size_t path_len;
        EFI_STATUS efirc;
        int rc;
 
-       DBGC ( device, "EFIDRV %s DRIVER_START", efi_handle_name ( device ) );
+       DBGC ( device, "EFIDRV %p %s DRIVER_START",
+              device, efi_handle_name ( device ) );
        if ( child )
                DBGC ( device, " (child %s)", efi_devpath_text ( child ) );
        DBGC ( device, "\n" );
@@ -153,73 +149,48 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
        /* Do nothing if we are already driving this device */
        efidev = efidev_find ( device );
        if ( efidev ) {
-               DBGCP ( device, "EFIDRV %s is already started\n",
-                       efi_handle_name ( device ) );
+               DBGCP ( device, "EFIDRV %p %s is already started\n",
+                       device, efi_handle_name ( device ) );
                efirc = EFI_ALREADY_STARTED;
                goto err_already_started;
        }
 
-       /* Open device path */
-       if ( ( efirc = bs->OpenProtocol ( device,
-                                         &efi_device_path_protocol_guid,
-                                         &path.interface, efi_image_handle,
-                                         device,
-                                         EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
-               rc = -EEFI ( efirc );
-               DBGC ( device, "EFIDRV %s could not open device path: %s\n",
-                      efi_handle_name ( device ), strerror ( rc ) );
-               goto err_open_path;
-       }
-       path_len = ( efi_devpath_len ( path.path ) + sizeof ( *path_end ) );
-
        /* Allocate and initialise structure */
-       efidev = zalloc ( sizeof ( *efidev ) + path_len );
+       efidev = zalloc ( sizeof ( *efidev ) );
        if ( ! efidev ) {
                efirc = EFI_OUT_OF_RESOURCES;
                goto err_alloc;
        }
        efidev->device = device;
        efidev->dev.desc.bus_type = BUS_TYPE_EFI;
-       efidev->path = ( ( ( void * ) efidev ) + sizeof ( *efidev ) );
-       memcpy ( efidev->path, path.path, path_len );
        INIT_LIST_HEAD ( &efidev->dev.children );
        list_add ( &efidev->dev.siblings, &efi_devices );
 
-       /* Close device path */
-       bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
-                           efi_image_handle, device );
-       path.path = NULL;
-
        /* Try to start this device */
        for_each_table_entry ( efidrv, EFI_DRIVERS ) {
                if ( ( rc = efidrv->supported ( device ) ) != 0 ) {
-                       DBGC ( device, "EFIDRV %s is not supported by driver "
-                              "\"%s\": %s\n", efi_handle_name ( device ),
-                              efidrv->name,
+                       DBGC ( device, "EFIDRV %p %s is not supported by "
+                              "driver \"%s\": %s\n", device,
+                              efi_handle_name ( device ), efidrv->name,
                               strerror ( rc ) );
                        continue;
                }
                if ( ( rc = efidrv->start ( efidev ) ) == 0 ) {
                        efidev->driver = efidrv;
-                       DBGC ( device, "EFIDRV %s using driver \"%s\"\n",
-                              efi_handle_name ( device ),
+                       DBGC ( device, "EFIDRV %p %s using driver \"%s\"\n",
+                              device, efi_handle_name ( device ),
                               efidev->driver->name );
                        return 0;
                }
-               DBGC ( device, "EFIDRV %s could not start driver \"%s\": %s\n",
-                      efi_handle_name ( device ), efidrv->name,
-                      strerror ( rc ) );
+               DBGC ( device, "EFIDRV %p %s could not start driver \"%s\": "
+                      "%s\n", device, efi_handle_name ( device ),
+                      efidrv->name, strerror ( rc ) );
        }
        efirc = EFI_UNSUPPORTED;
 
        list_del ( &efidev->dev.siblings );
        free ( efidev );
  err_alloc:
-       if ( path.path ) {
-               bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
-                                   efi_image_handle, device );
-       }
- err_open_path:
  err_already_started:
        return efirc;
 }
@@ -242,19 +213,20 @@ efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
        struct efi_device *efidev;
        UINTN i;
 
-       DBGC ( device, "EFIDRV %s DRIVER_STOP", efi_handle_name ( device ) );
+       DBGC ( device, "EFIDRV %p %s DRIVER_STOP",
+              device, efi_handle_name ( device ) );
        for ( i = 0 ; i < num_children ; i++ ) {
-               DBGC ( device, "%s%s", ( i ? ", " : " child " ),
-                      efi_handle_name ( children[i] ) );
+               DBGC ( device, "%s%p %s", ( i ? ", " : " child " ),
+                      children[i], efi_handle_name ( children[i] ) );
        }
        DBGC ( device, "\n" );
 
        /* Do nothing unless we are driving this device */
        efidev = efidev_find ( device );
        if ( ! efidev ) {
-               DBGCP ( device, "EFIDRV %s is not started\n",
-                       efi_handle_name ( device ) );
-               return EFI_DEVICE_ERROR;
+               DBGCP ( device, "EFIDRV %p %s is not started\n",
+                       device, efi_handle_name ( device ) );
+               return 0;
        }
 
        /* Stop this device */
@@ -406,35 +378,36 @@ static int efi_driver_connect ( EFI_HANDLE device ) {
        }
 
        /* Disconnect any existing drivers */
-       DBGC2 ( device, "EFIDRV %s before disconnecting:\n",
-               efi_handle_name ( device ) );
+       DBGC2 ( device, "EFIDRV %p %s before disconnecting:\n",
+               device, efi_handle_name ( device ) );
        DBGC2_EFI_PROTOCOLS ( device, device );
-       DBGC ( device, "EFIDRV %s disconnecting existing drivers\n",
-              efi_handle_name ( device ) );
+       DBGC ( device, "EFIDRV %p %s disconnecting existing drivers\n",
+              device, efi_handle_name ( device ) );
        if ( ( efirc = bs->DisconnectController ( device, NULL,
                                                  NULL ) ) != 0 ) {
                rc = -EEFI ( efirc );
-               DBGC ( device, "EFIDRV %s could not disconnect existing "
-                      "drivers: %s\n", efi_handle_name ( device ),
+               DBGC ( device, "EFIDRV %p %s could not disconnect existing "
+                      "drivers: %s\n", device, efi_handle_name ( device ),
                       strerror ( rc ) );
                /* Ignore the error and attempt to connect our drivers */
        }
-       DBGC2 ( device, "EFIDRV %s after disconnecting:\n",
-               efi_handle_name ( device ) );
+       DBGC2 ( device, "EFIDRV %p %s after disconnecting:\n",
+               device, efi_handle_name ( device ) );
        DBGC2_EFI_PROTOCOLS ( device, device );
 
        /* Connect our driver */
-       DBGC ( device, "EFIDRV %s connecting new drivers\n",
-              efi_handle_name ( device ) );
+       DBGC ( device, "EFIDRV %p %s connecting new drivers\n",
+              device, efi_handle_name ( device ) );
        if ( ( efirc = bs->ConnectController ( device, drivers, NULL,
                                               FALSE ) ) != 0 ) {
                rc = -EEFI ( efirc );
-               DBGC ( device, "EFIDRV %s could not connect new drivers: "
-                      "%s\n", efi_handle_name ( device ), strerror ( rc ) );
+               DBGC ( device, "EFIDRV %p %s could not connect new drivers: "
+                      "%s\n", device, efi_handle_name ( device ),
+                      strerror ( rc ) );
                return rc;
        }
-       DBGC2 ( device, "EFIDRV %s after connecting:\n",
-               efi_handle_name ( device ) );
+       DBGC2 ( device, "EFIDRV %p %s after connecting:\n",
+               device, efi_handle_name ( device ) );
        DBGC2_EFI_PROTOCOLS ( device, device );
 
        return 0;
diff --git a/roms/ipxe/src/interface/efi/efi_fbcon.c b/roms/ipxe/src/interface/efi/efi_fbcon.c
deleted file mode 100644 (file)
index abc5a93..0000000
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/**
- * @file
- *
- * EFI frame buffer console
- *
- */
-
-#include <string.h>
-#include <strings.h>
-#include <ctype.h>
-#include <errno.h>
-#include <assert.h>
-#include <limits.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/Protocol/GraphicsOutput.h>
-#include <ipxe/efi/Protocol/HiiFont.h>
-#include <ipxe/ansicol.h>
-#include <ipxe/fbcon.h>
-#include <ipxe/console.h>
-#include <ipxe/umalloc.h>
-#include <ipxe/rotate.h>
-#include <config/console.h>
-
-/* Avoid dragging in EFI console if not otherwise used */
-extern struct console_driver efi_console;
-struct console_driver efi_console __attribute__ (( weak ));
-
-/* Set default console usage if applicable
- *
- * We accept either CONSOLE_FRAMEBUFFER or CONSOLE_EFIFB.
- */
-#if ( defined ( CONSOLE_FRAMEBUFFER ) && ! defined ( CONSOLE_EFIFB ) )
-#define CONSOLE_EFIFB CONSOLE_FRAMEBUFFER
-#endif
-#if ! ( defined ( CONSOLE_EFIFB ) && CONSOLE_EXPLICIT ( CONSOLE_EFIFB ) )
-#undef CONSOLE_EFIFB
-#define CONSOLE_EFIFB ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
-#endif
-
-/* Forward declaration */
-struct console_driver efifb_console __console_driver;
-
-/** An EFI frame buffer */
-struct efifb {
-       /** EFI graphics output protocol */
-       EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
-       /** EFI HII font protocol */
-       EFI_HII_FONT_PROTOCOL *hiifont;
-       /** Saved mode */
-       UINT32 saved_mode;
-
-       /** Frame buffer console */
-       struct fbcon fbcon;
-       /** Physical start address */
-       physaddr_t start;
-       /** Pixel geometry */
-       struct fbcon_geometry pixel;
-       /** Colour mapping */
-       struct fbcon_colour_map map;
-       /** Font definition */
-       struct fbcon_font font;
-       /** Character glyphs */
-       userptr_t glyphs;
-};
-
-/** The EFI frame buffer */
-static struct efifb efifb;
-
-/**
- * Get character glyph
- *
- * @v character                Character
- * @v glyph            Character glyph to fill in
- */
-static void efifb_glyph ( unsigned int character, uint8_t *glyph ) {
-       size_t offset = ( character * efifb.font.height );
-
-       copy_from_user ( glyph, efifb.glyphs, offset, efifb.font.height );
-}
-
-/**
- * Get character glyphs
- *
- * @ret rc             Return status code
- */
-static int efifb_glyphs ( void ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_IMAGE_OUTPUT *blt;
-       EFI_GRAPHICS_OUTPUT_BLT_PIXEL *pixel;
-       size_t offset;
-       size_t len;
-       uint8_t bitmask;
-       unsigned int character;
-       unsigned int x;
-       unsigned int y;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Get font height.  The GetFontInfo() call nominally returns
-        * this information in an EFI_FONT_DISPLAY_INFO structure, but
-        * is known to fail on many UEFI implementations.  Instead, we
-        * iterate over all printable characters to find the maximum
-        * height.
-        */
-       efifb.font.height = 0;
-       for ( character = 0 ; character < 256 ; character++ ) {
-
-               /* Skip non-printable characters */
-               if ( ! isprint ( character ) )
-                       continue;
-
-               /* Get glyph */
-               blt = NULL;
-               if ( ( efirc = efifb.hiifont->GetGlyph ( efifb.hiifont,
-                                                        character, NULL, &blt,
-                                                        NULL ) ) != 0 ) {
-                       rc = -EEFI ( efirc );
-                       DBGC ( &efifb, "EFIFB could not get glyph %d: %s\n",
-                              character, strerror ( rc ) );
-                       continue;
-               }
-               assert ( blt != NULL );
-
-               /* Calculate maximum height */
-               if ( efifb.font.height < blt->Height )
-                       efifb.font.height = blt->Height;
-
-               /* Free glyph */
-               bs->FreePool ( blt );
-       }
-       if ( ! efifb.font.height ) {
-               DBGC ( &efifb, "EFIFB could not get font height\n" );
-               return -ENOENT;
-       }
-
-       /* Allocate glyph data */
-       len = ( 256 * efifb.font.height * sizeof ( bitmask ) );
-       efifb.glyphs = umalloc ( len );
-       if ( ! efifb.glyphs ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       memset_user ( efifb.glyphs, 0, 0, len );
-
-       /* Get font data */
-       for ( character = 0 ; character < 256 ; character++ ) {
-
-               /* Skip non-printable characters */
-               if ( ! isprint ( character ) )
-                       continue;
-
-               /* Get glyph */
-               blt = NULL;
-               if ( ( efirc = efifb.hiifont->GetGlyph ( efifb.hiifont,
-                                                        character, NULL, &blt,
-                                                        NULL ) ) != 0 ) {
-                       rc = -EEFI ( efirc );
-                       DBGC ( &efifb, "EFIFB could not get glyph %d: %s\n",
-                              character, strerror ( rc ) );
-                       continue;
-               }
-               assert ( blt != NULL );
-
-               /* Sanity check */
-               if ( blt->Width > 8 ) {
-                       DBGC ( &efifb, "EFIFB glyph %d invalid width %d\n",
-                              character, blt->Width );
-                       continue;
-               }
-               if ( blt->Height > efifb.font.height ) {
-                       DBGC ( &efifb, "EFIFB glyph %d invalid height %d\n",
-                              character, blt->Height );
-                       continue;
-               }
-
-               /* Convert glyph to bitmap */
-               pixel = blt->Image.Bitmap;
-               offset = ( character * efifb.font.height );
-               for ( y = 0 ; y < blt->Height ; y++ ) {
-                       bitmask = 0;
-                       for ( x = 0 ; x < blt->Width ; x++ ) {
-                               bitmask = rol8 ( bitmask, 1 );
-                               if ( pixel->Blue || pixel->Green || pixel->Red )
-                                       bitmask |= 0x01;
-                               pixel++;
-                       }
-                       copy_to_user ( efifb.glyphs, offset++, &bitmask,
-                                      sizeof ( bitmask ) );
-               }
-
-               /* Free glyph */
-               bs->FreePool ( blt );
-       }
-
-       efifb.font.glyph = efifb_glyph;
-       return 0;
-
-       ufree ( efifb.glyphs );
- err_alloc:
-       return rc;
-}
-
-/**
- * Generate colour mapping for a single colour component
- *
- * @v mask             Mask value
- * @v scale            Scale value to fill in
- * @v lsb              LSB value to fill in
- * @ret rc             Return status code
- */
-static int efifb_colour_map_mask ( uint32_t mask, uint8_t *scale,
-                                  uint8_t *lsb ) {
-       uint32_t check;
-
-       /* Fill in LSB and scale */
-       *lsb = ( mask ? ( ffs ( mask ) - 1 ) : 0 );
-       *scale = ( mask ? ( 8 - ( fls ( mask ) - *lsb ) ) : 8 );
-
-       /* Check that original mask was contiguous */
-       check = ( ( 0xff >> *scale ) << *lsb );
-       if ( check != mask )
-               return -ENOTSUP;
-
-       return 0;
-}
-
-/**
- * Generate colour mapping
- *
- * @v info             EFI mode information
- * @v map              Colour mapping to fill in
- * @ret bpp            Number of bits per pixel, or negative error
- */
-static int efifb_colour_map ( EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info,
-                             struct fbcon_colour_map *map ) {
-       static EFI_PIXEL_BITMASK rgb_mask = {
-               0x000000ffUL, 0x0000ff00UL, 0x00ff0000UL, 0xff000000UL
-       };
-       static EFI_PIXEL_BITMASK bgr_mask = {
-               0x00ff0000UL, 0x0000ff00UL, 0x000000ffUL, 0xff000000UL
-       };
-       EFI_PIXEL_BITMASK *mask;
-       uint8_t reserved_scale;
-       uint8_t reserved_lsb;
-       int rc;
-
-       /* Determine applicable mask */
-       switch ( info->PixelFormat ) {
-       case PixelRedGreenBlueReserved8BitPerColor:
-               mask = &rgb_mask;
-               break;
-       case PixelBlueGreenRedReserved8BitPerColor:
-               mask = &bgr_mask;
-               break;
-       case PixelBitMask:
-               mask = &info->PixelInformation;
-               break;
-       default:
-               DBGC ( &efifb, "EFIFB unrecognised pixel format %d\n",
-                      info->PixelFormat );
-               return -ENOTSUP;
-       }
-
-       /* Map each colour component */
-       if ( ( rc = efifb_colour_map_mask ( mask->RedMask, &map->red_scale,
-                                           &map->red_lsb ) ) != 0 )
-               return rc;
-       if ( ( rc = efifb_colour_map_mask ( mask->GreenMask, &map->green_scale,
-                                           &map->green_lsb ) ) != 0 )
-               return rc;
-       if ( ( rc = efifb_colour_map_mask ( mask->BlueMask, &map->blue_scale,
-                                           &map->blue_lsb ) ) != 0 )
-               return rc;
-       if ( ( rc = efifb_colour_map_mask ( mask->ReservedMask, &reserved_scale,
-                                           &reserved_lsb ) ) != 0 )
-               return rc;
-
-       /* Calculate total number of bits per pixel */
-       return ( 32 - ( reserved_scale + map->red_scale + map->green_scale +
-                       map->blue_scale ) );
-}
-
-/**
- * Select video mode
- *
- * @v min_width                Minimum required width (in pixels)
- * @v min_height       Minimum required height (in pixels)
- * @v min_bpp          Minimum required colour depth (in bits per pixel)
- * @ret mode_number    Mode number, or negative error
- */
-static int efifb_select_mode ( unsigned int min_width, unsigned int min_height,
-                              unsigned int min_bpp ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       struct fbcon_colour_map map;
-       EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
-       int best_mode_number = -ENOENT;
-       unsigned int best_score = INT_MAX;
-       unsigned int score;
-       unsigned int mode;
-       int bpp;
-       UINTN size;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Find the best mode */
-       for ( mode = 0 ; mode < efifb.gop->Mode->MaxMode ; mode++ ) {
-
-               /* Get mode information */
-               if ( ( efirc = efifb.gop->QueryMode ( efifb.gop, mode, &size,
-                                                     &info ) ) != 0 ) {
-                       rc = -EEFI ( efirc );
-                       DBGC ( &efifb, "EFIFB could not get mode %d "
-                              "information: %s\n", mode, strerror ( rc ) );
-                       goto err_query;
-               }
-
-               /* Skip unusable modes */
-               bpp = efifb_colour_map ( info, &map );
-               if ( bpp < 0 ) {
-                       rc = bpp;
-                       DBGC ( &efifb, "EFIFB could not build colour map for "
-                              "mode %d: %s\n", mode, strerror ( rc ) );
-                       goto err_map;
-               }
-
-               /* Skip modes not meeting the requirements */
-               if ( ( info->HorizontalResolution < min_width ) ||
-                    ( info->VerticalResolution < min_height ) ||
-                    ( ( ( unsigned int ) bpp ) < min_bpp ) ) {
-                       goto err_requirements;
-               }
-
-               /* Select this mode if it has the best (i.e. lowest)
-                * score.  We choose the scoring system to favour
-                * modes close to the specified width and height;
-                * within modes of the same width and height we prefer
-                * a higher colour depth.
-                */
-               score = ( ( info->HorizontalResolution *
-                           info->VerticalResolution ) - bpp );
-               if ( score < best_score ) {
-                       best_mode_number = mode;
-                       best_score = score;
-               }
-
-       err_requirements:
-       err_map:
-               bs->FreePool ( info );
-       err_query:
-               continue;
-       }
-
-       if ( best_mode_number < 0 )
-               DBGC ( &efifb, "EFIFB found no suitable mode\n" );
-       return best_mode_number;
-}
-
-/**
- * Restore video mode
- *
- * @v rc               Return status code
- */
-static int efifb_restore ( void ) {
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Restore original mode */
-       if ( ( efirc = efifb.gop->SetMode ( efifb.gop,
-                                           efifb.saved_mode ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( &efifb, "EFIFB could not restore mode %d: %s\n",
-                      efifb.saved_mode, strerror ( rc ) );
-               return rc;
-       }
-
-       return 0;
-}
-
-/**
- * Initialise EFI frame buffer
- *
- * @v config           Console configuration, or NULL to reset
- * @ret rc             Return status code
- */
-static int efifb_init ( struct console_configuration *config ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
-       void *interface;
-       int mode;
-       int bpp;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Locate graphics output protocol */
-       if ( ( efirc = bs->LocateProtocol ( &efi_graphics_output_protocol_guid,
-                                           NULL, &interface ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( &efifb, "EFIFB could not locate graphics output "
-                      "protocol: %s\n", strerror ( rc ) );
-               goto err_locate_gop;
-       }
-       efifb.gop = interface;
-
-       /* Locate HII font protocol */
-       if ( ( efirc = bs->LocateProtocol ( &efi_hii_font_protocol_guid,
-                                           NULL, &interface ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( &efifb, "EFIFB could not locate HII font protocol: %s\n",
-                      strerror ( rc ) );
-               goto err_locate_hiifont;
-       }
-       efifb.hiifont = interface;
-
-       /* Locate glyphs */
-       if ( ( rc = efifb_glyphs() ) != 0 )
-               goto err_glyphs;
-
-       /* Save original mode */
-       efifb.saved_mode = efifb.gop->Mode->Mode;
-
-       /* Select mode */
-       if ( ( mode = efifb_select_mode ( config->width, config->height,
-                                         config->depth ) ) < 0 ) {
-               rc = mode;
-               goto err_select_mode;
-       }
-
-       /* Set mode */
-       if ( ( efirc = efifb.gop->SetMode ( efifb.gop, mode ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( &efifb, "EFIFB could not set mode %d: %s\n",
-                      mode, strerror ( rc ) );
-               goto err_set_mode;
-       }
-       info = efifb.gop->Mode->Info;
-
-       /* Populate colour map */
-       bpp = efifb_colour_map ( info, &efifb.map );
-       if ( bpp < 0 ) {
-               rc = bpp;
-               DBGC ( &efifb, "EFIFB could not build colour map for "
-                      "mode %d: %s\n", mode, strerror ( rc ) );
-               goto err_map;
-       }
-
-       /* Populate pixel geometry */
-       efifb.pixel.width = info->HorizontalResolution;
-       efifb.pixel.height = info->VerticalResolution;
-       efifb.pixel.len = ( ( bpp + 7 ) / 8 );
-       efifb.pixel.stride = ( efifb.pixel.len * info->PixelsPerScanLine );
-
-       /* Populate frame buffer address */
-       efifb.start = efifb.gop->Mode->FrameBufferBase;
-       DBGC ( &efifb, "EFIFB using mode %d (%dx%d %dbpp at %#08lx)\n",
-              mode, efifb.pixel.width, efifb.pixel.height, bpp, efifb.start );
-
-       /* Initialise frame buffer console */
-       if ( ( rc = fbcon_init ( &efifb.fbcon, phys_to_user ( efifb.start ),
-                                &efifb.pixel, &efifb.map, &efifb.font,
-                                config ) ) != 0 )
-               goto err_fbcon_init;
-
-       return 0;
-
-       fbcon_fini ( &efifb.fbcon );
- err_fbcon_init:
- err_map:
-       efifb_restore();
- err_set_mode:
- err_select_mode:
-       ufree ( efifb.glyphs );
- err_glyphs:
- err_locate_hiifont:
- err_locate_gop:
-       return rc;
-}
-
-/**
- * Finalise EFI frame buffer
- *
- */
-static void efifb_fini ( void ) {
-
-       /* Finalise frame buffer console */
-       fbcon_fini ( &efifb.fbcon );
-
-       /* Restore saved mode */
-       efifb_restore();
-
-       /* Free glyphs */
-       ufree ( efifb.glyphs );
-}
-
-/**
- * Print a character to current cursor position
- *
- * @v character                Character
- */
-static void efifb_putchar ( int character ) {
-
-       fbcon_putchar ( &efifb.fbcon, character );
-}
-
-/**
- * Configure console
- *
- * @v config           Console configuration, or NULL to reset
- * @ret rc             Return status code
- */
-static int efifb_configure ( struct console_configuration *config ) {
-       int rc;
-
-       /* Reset console, if applicable */
-       if ( ! efifb_console.disabled ) {
-               efifb_fini();
-               efi_console.disabled &= ~CONSOLE_DISABLED_OUTPUT;
-               ansicol_reset_magic();
-       }
-       efifb_console.disabled = CONSOLE_DISABLED;
-
-       /* Do nothing more unless we have a usable configuration */
-       if ( ( config == NULL ) ||
-            ( config->width == 0 ) || ( config->height == 0 ) ) {
-               return 0;
-       }
-
-       /* Initialise EFI frame buffer */
-       if ( ( rc = efifb_init ( config ) ) != 0 )
-               return rc;
-
-       /* Mark console as enabled */
-       efifb_console.disabled = 0;
-       efi_console.disabled |= CONSOLE_DISABLED_OUTPUT;
-
-       /* Set magic colour to transparent if we have a background picture */
-       if ( config->pixbuf )
-               ansicol_set_magic_transparent();
-
-       return 0;
-}
-
-/** EFI graphics output protocol console driver */
-struct console_driver efifb_console __console_driver = {
-       .usage = CONSOLE_EFIFB,
-       .putchar = efifb_putchar,
-       .configure = efifb_configure,
-       .disabled = CONSOLE_DISABLED,
-};
index 52de098..3715b70 100644 (file)
@@ -47,6 +47,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/efi/efi_strings.h>
 #include <ipxe/efi/efi_file.h>
 
+/** EFI file information GUID */
+static EFI_GUID efi_file_info_id = EFI_FILE_INFO_ID;
+
+/** EFI file system information GUID */
+static EFI_GUID efi_file_system_info_id = EFI_FILE_SYSTEM_INFO_ID;
+
 /** EFI media ID */
 #define EFI_MEDIA_ID_MAGIC 0x69505845
 
@@ -608,9 +614,6 @@ int efi_file_install ( EFI_HANDLE handle ) {
        EFI_STATUS efirc;
        int rc;
 
-       /* Reset root directory state */
-       efi_file_root.pos = 0;
-
        /* Install the simple file system protocol, block I/O
         * protocol, and disk I/O protocol.  We don't have a block
         * device, but large parts of the EDK2 codebase make the
index 62ee5a5..ab1c91e 100644 (file)
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <ipxe/efi/efi.h>
-#include <ipxe/efi/Protocol/AbsolutePointer.h>
-#include <ipxe/efi/Protocol/AppleNetBoot.h>
 #include <ipxe/efi/Protocol/Arp.h>
 #include <ipxe/efi/Protocol/BlockIo.h>
 #include <ipxe/efi/Protocol/BusSpecificDriverOverride.h>
 #include <ipxe/efi/Protocol/ComponentName.h>
 #include <ipxe/efi/Protocol/ComponentName2.h>
-#include <ipxe/efi/Protocol/ConsoleControl/ConsoleControl.h>
 #include <ipxe/efi/Protocol/DevicePath.h>
 #include <ipxe/efi/Protocol/DevicePathToText.h>
 #include <ipxe/efi/Protocol/Dhcp4.h>
@@ -39,7 +36,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/efi/Protocol/DriverBinding.h>
 #include <ipxe/efi/Protocol/GraphicsOutput.h>
 #include <ipxe/efi/Protocol/HiiConfigAccess.h>
-#include <ipxe/efi/Protocol/HiiFont.h>
 #include <ipxe/efi/Protocol/Ip4.h>
 #include <ipxe/efi/Protocol/Ip4Config.h>
 #include <ipxe/efi/Protocol/LoadFile.h>
@@ -51,24 +47,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/efi/Protocol/PciIo.h>
 #include <ipxe/efi/Protocol/PciRootBridgeIo.h>
 #include <ipxe/efi/Protocol/PxeBaseCode.h>
-#include <ipxe/efi/Protocol/SerialIo.h>
 #include <ipxe/efi/Protocol/SimpleFileSystem.h>
 #include <ipxe/efi/Protocol/SimpleNetwork.h>
-#include <ipxe/efi/Protocol/SimplePointer.h>
-#include <ipxe/efi/Protocol/SimpleTextIn.h>
-#include <ipxe/efi/Protocol/SimpleTextInEx.h>
-#include <ipxe/efi/Protocol/SimpleTextOut.h>
 #include <ipxe/efi/Protocol/TcgService.h>
 #include <ipxe/efi/Protocol/Tcp4.h>
 #include <ipxe/efi/Protocol/Udp4.h>
-#include <ipxe/efi/Protocol/UgaDraw.h>
-#include <ipxe/efi/Protocol/UnicodeCollation.h>
-#include <ipxe/efi/Protocol/UsbHostController.h>
-#include <ipxe/efi/Protocol/Usb2HostController.h>
-#include <ipxe/efi/Protocol/UsbIo.h>
 #include <ipxe/efi/Protocol/VlanConfig.h>
-#include <ipxe/efi/Guid/FileInfo.h>
-#include <ipxe/efi/Guid/FileSystemInfo.h>
 
 /** @file
  *
@@ -76,19 +60,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  */
 
-/* TrEE protocol GUID definition in EDK2 headers is broken (missing braces) */
-#define EFI_TREE_PROTOCOL_GUID                                         \
-       { 0x607f766c, 0x7455, 0x42be,                                   \
-         { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } }
-
-/** Absolute pointer protocol GUID */
-EFI_GUID efi_absolute_pointer_protocol_guid
-       = EFI_ABSOLUTE_POINTER_PROTOCOL_GUID;
-
-/** Apple NetBoot protocol GUID */
-EFI_GUID efi_apple_net_boot_protocol_guid
-       = EFI_APPLE_NET_BOOT_PROTOCOL_GUID;
-
 /** ARP protocol GUID */
 EFI_GUID efi_arp_protocol_guid
        = EFI_ARP_PROTOCOL_GUID;
@@ -113,10 +84,6 @@ EFI_GUID efi_component_name_protocol_guid
 EFI_GUID efi_component_name2_protocol_guid
        = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
 
-/** Console control protocol GUID */
-EFI_GUID efi_console_control_protocol_guid
-       = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
-
 /** Device path protocol GUID */
 EFI_GUID efi_device_path_protocol_guid
        = EFI_DEVICE_PATH_PROTOCOL_GUID;
@@ -145,10 +112,6 @@ EFI_GUID efi_graphics_output_protocol_guid
 EFI_GUID efi_hii_config_access_protocol_guid
        = EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID;
 
-/** HII font protocol GUID */
-EFI_GUID efi_hii_font_protocol_guid
-       = EFI_HII_FONT_PROTOCOL_GUID;
-
 /** IPv4 protocol GUID */
 EFI_GUID efi_ip4_protocol_guid
        = EFI_IP4_PROTOCOL_GUID;
@@ -213,10 +176,6 @@ EFI_GUID efi_pci_root_bridge_io_protocol_guid
 EFI_GUID efi_pxe_base_code_protocol_guid
        = EFI_PXE_BASE_CODE_PROTOCOL_GUID;
 
-/** Serial I/O protocol GUID */
-EFI_GUID efi_serial_io_protocol_guid
-       = EFI_SERIAL_IO_PROTOCOL_GUID;
-
 /** Simple file system protocol GUID */
 EFI_GUID efi_simple_file_system_protocol_guid
        = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
@@ -225,22 +184,6 @@ EFI_GUID efi_simple_file_system_protocol_guid
 EFI_GUID efi_simple_network_protocol_guid
        = EFI_SIMPLE_NETWORK_PROTOCOL_GUID;
 
-/** Simple pointer protocol GUID */
-EFI_GUID efi_simple_pointer_protocol_guid
-       = EFI_SIMPLE_POINTER_PROTOCOL_GUID;
-
-/** Simple text input protocol GUID */
-EFI_GUID efi_simple_text_input_protocol_guid
-       = EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID;
-
-/** Simple text input extension protocol GUID */
-EFI_GUID efi_simple_text_input_ex_protocol_guid
-       = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
-
-/** Simple text output protocol GUID */
-EFI_GUID efi_simple_text_output_protocol_guid
-       = EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID;
-
 /** TCG protocol GUID */
 EFI_GUID efi_tcg_protocol_guid
        = EFI_TCG_PROTOCOL_GUID;
@@ -253,10 +196,6 @@ EFI_GUID efi_tcp4_protocol_guid
 EFI_GUID efi_tcp4_service_binding_protocol_guid
        = EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID;
 
-/** TrEE protocol GUID */
-EFI_GUID efi_tree_protocol_guid
-       = EFI_TREE_PROTOCOL_GUID;
-
 /** UDPv4 protocol GUID */
 EFI_GUID efi_udp4_protocol_guid
        = EFI_UDP4_PROTOCOL_GUID;
@@ -265,32 +204,6 @@ EFI_GUID efi_udp4_protocol_guid
 EFI_GUID efi_udp4_service_binding_protocol_guid
        = EFI_UDP4_SERVICE_BINDING_PROTOCOL_GUID;
 
-/** UGA draw protocol GUID */
-EFI_GUID efi_uga_draw_protocol_guid
-       = EFI_UGA_DRAW_PROTOCOL_GUID;
-
-/** Unicode collation protocol GUID */
-EFI_GUID efi_unicode_collation_protocol_guid
-       = EFI_UNICODE_COLLATION_PROTOCOL_GUID;
-
-/** USB host controller protocol GUID */
-EFI_GUID efi_usb_hc_protocol_guid
-       = EFI_USB_HC_PROTOCOL_GUID;
-
-/** USB2 host controller protocol GUID */
-EFI_GUID efi_usb2_hc_protocol_guid
-       = EFI_USB2_HC_PROTOCOL_GUID;
-
-/** USB I/O protocol GUID */
-EFI_GUID efi_usb_io_protocol_guid
-       = EFI_USB_IO_PROTOCOL_GUID;
-
 /** VLAN configuration protocol GUID */
 EFI_GUID efi_vlan_config_protocol_guid
        = EFI_VLAN_CONFIG_PROTOCOL_GUID;
-
-/** File information GUID */
-EFI_GUID efi_file_info_id = EFI_FILE_INFO_ID;
-
-/** File system information GUID */
-EFI_GUID efi_file_system_info_id = EFI_FILE_SYSTEM_INFO_ID;
diff --git a/roms/ipxe/src/interface/efi/efi_local.c b/roms/ipxe/src/interface/efi/efi_local.c
deleted file mode 100644 (file)
index bd010ad..0000000
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <string.h>
-#include <strings.h>
-#include <stdio.h>
-#include <errno.h>
-#include <assert.h>
-#include <ipxe/refcnt.h>
-#include <ipxe/malloc.h>
-#include <ipxe/xfer.h>
-#include <ipxe/open.h>
-#include <ipxe/uri.h>
-#include <ipxe/iobuf.h>
-#include <ipxe/process.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_strings.h>
-#include <ipxe/efi/efi_utils.h>
-#include <ipxe/efi/Protocol/SimpleFileSystem.h>
-#include <ipxe/efi/Guid/FileInfo.h>
-#include <ipxe/efi/Guid/FileSystemInfo.h>
-
-/** @file
- *
- * EFI local file access
- *
- */
-
-/** Download blocksize */
-#define EFI_LOCAL_BLKSIZE 4096
-
-/** An EFI local file */
-struct efi_local {
-       /** Reference count */
-       struct refcnt refcnt;
-       /** Data transfer interface */
-       struct interface xfer;
-       /** Download process */
-       struct process process;
-
-       /** EFI root directory */
-       EFI_FILE_PROTOCOL *root;
-       /** EFI file */
-       EFI_FILE_PROTOCOL *file;
-       /** Length of file */
-       size_t len;
-};
-
-/**
- * Close local file
- *
- * @v local            Local file
- * @v rc               Reason for close
- */
-static void efi_local_close ( struct efi_local *local, int rc ) {
-
-       /* Stop process */
-       process_del ( &local->process );
-
-       /* Shut down data transfer interface */
-       intf_shutdown ( &local->xfer, rc );
-
-       /* Close EFI file */
-       if ( local->file ) {
-               local->file->Close ( local->file );
-               local->file = NULL;
-       }
-
-       /* Close EFI root directory */
-       if ( local->root ) {
-               local->root->Close ( local->root );
-               local->root = NULL;
-       }
-}
-
-/**
- * Local file process
- *
- * @v local            Local file
- */
-static void efi_local_step ( struct efi_local *local ) {
-       EFI_FILE_PROTOCOL *file = local->file;
-       struct io_buffer *iobuf = NULL;
-       size_t remaining;
-       size_t frag_len;
-       UINTN size;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Wait until data transfer interface is ready */
-       if ( ! xfer_window ( &local->xfer ) )
-               return;
-
-       /* Presize receive buffer */
-       remaining = local->len;
-       xfer_seek ( &local->xfer, remaining );
-       xfer_seek ( &local->xfer, 0 );
-
-       /* Get file contents */
-       while ( remaining ) {
-
-               /* Calculate length for this fragment */
-               frag_len = remaining;
-               if ( frag_len > EFI_LOCAL_BLKSIZE )
-                       frag_len = EFI_LOCAL_BLKSIZE;
-
-               /* Allocate I/O buffer */
-               iobuf = xfer_alloc_iob ( &local->xfer, frag_len );
-               if ( ! iobuf ) {
-                       rc = -ENOMEM;
-                       goto err;
-               }
-
-               /* Read block */
-               size = frag_len;
-               if ( ( efirc = file->Read ( file, &size, iobuf->data ) ) != 0 ){
-                       rc = -EEFI ( efirc );
-                       DBGC ( local, "LOCAL %p could not read from file: %s\n",
-                              local, strerror ( rc ) );
-                       goto err;
-               }
-               assert ( size <= frag_len );
-               iob_put ( iobuf, size );
-
-               /* Deliver data */
-               if ( ( rc = xfer_deliver_iob ( &local->xfer,
-                                              iob_disown ( iobuf ) ) ) != 0 ) {
-                       DBGC ( local, "LOCAL %p could not deliver data: %s\n",
-                              local, strerror ( rc ) );
-                       goto err;
-               }
-
-               /* Move to next block */
-               remaining -= frag_len;
-       }
-
-       /* Close download */
-       efi_local_close ( local, 0 );
-
-       return;
-
- err:
-       free_iob ( iobuf );
-       efi_local_close ( local, rc );
-}
-
-/** Data transfer interface operations */
-static struct interface_operation efi_local_operations[] = {
-       INTF_OP ( xfer_window_changed, struct efi_local *, efi_local_step ),
-       INTF_OP ( intf_close, struct efi_local *, efi_local_close ),
-};
-
-/** Data transfer interface descriptor */
-static struct interface_descriptor efi_local_xfer_desc =
-       INTF_DESC ( struct efi_local, xfer, efi_local_operations );
-
-/** Process descriptor */
-static struct process_descriptor efi_local_process_desc =
-       PROC_DESC_ONCE ( struct efi_local, process, efi_local_step );
-
-/**
- * Check for matching volume name
- *
- * @v local            Local file
- * @v device           Device handle
- * @v root             Root filesystem handle
- * @v volume           Volume name
- * @ret rc             Return status code
- */
-static int efi_local_check_volume_name ( struct efi_local *local,
-                                        EFI_HANDLE device,
-                                        EFI_FILE_PROTOCOL *root,
-                                        const char *volume ) {
-       EFI_FILE_SYSTEM_INFO *info;
-       UINTN size;
-       char *label;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Get length of file system information */
-       size = 0;
-       root->GetInfo ( root, &efi_file_system_info_id, &size, NULL );
-
-       /* Allocate file system information */
-       info = malloc ( size );
-       if ( ! info ) {
-               rc = -ENOMEM;
-               goto err_alloc_info;
-       }
-
-       /* Get file system information */
-       if ( ( efirc = root->GetInfo ( root, &efi_file_system_info_id, &size,
-                                      info ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( local, "LOCAL %p could not get file system info on %s: "
-                      "%s\n", local, efi_handle_name ( device ),
-                      strerror ( rc ) );
-               goto err_get_info;
-       }
-       DBGC2 ( local, "LOCAL %p found %s with label \"%ls\"\n",
-               local, efi_handle_name ( device ), info->VolumeLabel );
-
-       /* Construct volume label for comparison */
-       if ( asprintf ( &label, "%ls", info->VolumeLabel ) < 0 ) {
-               rc = -ENOMEM;
-               goto err_alloc_label;
-       }
-
-       /* Compare volume label */
-       if ( strcasecmp ( volume, label ) != 0 ) {
-               rc = -ENOENT;
-               goto err_compare;
-       }
-
-       /* Success */
-       rc = 0;
-
- err_compare:
-       free ( label );
- err_alloc_label:
- err_get_info:
-       free ( info );
- err_alloc_info:
-       return rc;
-}
-
-/**
- * Open root filesystem
- *
- * @v local            Local file
- * @v device           Device handle
- * @v root             Root filesystem handle to fill in
- * @ret rc             Return status code
- */
-static int efi_local_open_root ( struct efi_local *local, EFI_HANDLE device,
-                                EFI_FILE_PROTOCOL **root ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       union {
-               void *interface;
-               EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *fs;
-       } u;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Open file system protocol */
-       if ( ( efirc = bs->OpenProtocol ( device,
-                                         &efi_simple_file_system_protocol_guid,
-                                         &u.interface, efi_image_handle,
-                                         device,
-                                         EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
-               rc = -EEFI ( efirc );
-               DBGC ( local, "LOCAL %p could not open filesystem on %s: %s\n",
-                      local, efi_handle_name ( device ), strerror ( rc ) );
-               goto err_filesystem;
-       }
-
-       /* Open root directory */
-       if ( ( efirc = u.fs->OpenVolume ( u.fs, root ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( local, "LOCAL %p could not open volume on %s: %s\n",
-                      local, efi_handle_name ( device ), strerror ( rc ) );
-               goto err_volume;
-       }
-
-       /* Success */
-       rc = 0;
-
- err_volume:
-       bs->CloseProtocol ( device, &efi_simple_file_system_protocol_guid,
-                           efi_image_handle, device );
- err_filesystem:
-       return rc;
-}
-
-/**
- * Open root filesystem of specified volume
- *
- * @v local            Local file
- * @v volume           Volume name, or NULL to use loaded image's device
- * @ret rc             Return status code
- */
-static int efi_local_open_volume ( struct efi_local *local,
-                                  const char *volume ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_GUID *protocol = &efi_simple_file_system_protocol_guid;
-       int ( * check ) ( struct efi_local *local, EFI_HANDLE device,
-                         EFI_FILE_PROTOCOL *root, const char *volume );
-       EFI_FILE_PROTOCOL *root;
-       EFI_HANDLE *handles;
-       EFI_HANDLE device;
-       UINTN num_handles;
-       UINTN i;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Identify candidate handles */
-       if ( volume ) {
-               /* Locate all filesystem handles */
-               if ( ( efirc = bs->LocateHandleBuffer ( ByProtocol, protocol,
-                                                       NULL, &num_handles,
-                                                       &handles ) ) != 0 ) {
-                       rc = -EEFI ( efirc );
-                       DBGC ( local, "LOCAL %p could not enumerate handles: "
-                              "%s\n", local, strerror ( rc ) );
-                       return rc;
-               }
-               check = efi_local_check_volume_name;
-       } else {
-               /* Use our loaded image's device handle */
-               handles = &efi_loaded_image->DeviceHandle;
-               num_handles = 1;
-               check = NULL;
-       }
-
-       /* Find matching handle */
-       for ( i = 0 ; i < num_handles ; i++ ) {
-
-               /* Get this device handle */
-               device = handles[i];
-
-               /* Open root directory */
-               if ( ( rc = efi_local_open_root ( local, device, &root ) ) != 0)
-                       continue;
-
-               /* Check volume name, if applicable */
-               if ( ( check == NULL ) ||
-                    ( ( rc = check ( local, device, root, volume ) ) == 0 ) ) {
-                       DBGC ( local, "LOCAL %p using %s",
-                              local, efi_handle_name ( device ) );
-                       if ( volume )
-                               DBGC ( local, " with label \"%s\"", volume );
-                       DBGC ( local, "\n" );
-                       local->root = root;
-                       break;
-               }
-
-               /* Close root directory */
-               root->Close ( root );
-       }
-
-       /* Free handles, if applicable */
-       if ( volume )
-               bs->FreePool ( handles );
-
-       /* Fail if we found no matching handle */
-       if ( ! local->root ) {
-               DBGC ( local, "LOCAL %p found no matching handle\n", local );
-               return -ENOENT;
-       }
-
-       return 0;
-}
-
-/**
- * Open fully-resolved path
- *
- * @v local            Local file
- * @v resolved         Resolved path
- * @ret rc             Return status code
- */
-static int efi_local_open_resolved ( struct efi_local *local,
-                                    const char *resolved ) {
-       size_t name_len = strlen ( resolved );
-       CHAR16 name[ name_len + 1 /* wNUL */ ];
-       EFI_FILE_PROTOCOL *file;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Construct filename */
-       efi_snprintf ( name, ( name_len + 1 /* wNUL */ ), "%s", resolved );
-
-       /* Open file */
-       if ( ( efirc = local->root->Open ( local->root, &file, name,
-                                          EFI_FILE_MODE_READ, 0 ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( local, "LOCAL %p could not open \"%s\": %s\n",
-                      local, resolved, strerror ( rc ) );
-               return rc;
-       }
-       local->file = file;
-
-       return 0;
-}
-
-/**
- * Open specified path
- *
- * @v local            Local file
- * @v path             Path to file
- * @ret rc             Return status code
- */
-static int efi_local_open_path ( struct efi_local *local, const char *path ) {
-       FILEPATH_DEVICE_PATH *fp = container_of ( efi_loaded_image->FilePath,
-                                                 FILEPATH_DEVICE_PATH, Header);
-       size_t fp_len = ( fp ? efi_devpath_len ( &fp->Header ) : 0 );
-       char base[ fp_len / 2 /* Cannot exceed this length */ ];
-       size_t remaining = sizeof ( base );
-       size_t len;
-       char *resolved;
-       char *tmp;
-       int rc;
-
-       /* Construct base path to our own image, if possible */
-       memset ( base, 0, sizeof ( base ) );
-       tmp = base;
-       while ( fp && ( fp->Header.Type != END_DEVICE_PATH_TYPE ) ) {
-               len = snprintf ( tmp, remaining, "%ls", fp->PathName );
-               assert ( len < remaining );
-               tmp += len;
-               remaining -= len;
-               fp = ( ( ( void * ) fp ) + ( ( fp->Header.Length[1] << 8 ) |
-                                            fp->Header.Length[0] ) );
-       }
-       DBGC2 ( local, "LOCAL %p base path \"%s\"\n",
-               local, base );
-
-       /* Convert to sane path separators */
-       for ( tmp = base ; *tmp ; tmp++ ) {
-               if ( *tmp == '\\' )
-                       *tmp = '/';
-       }
-
-       /* Resolve path */
-       resolved = resolve_path ( base, path );
-       if ( ! resolved ) {
-               rc = -ENOMEM;
-               goto err_resolve;
-       }
-
-       /* Convert to insane path separators */
-       for ( tmp = resolved ; *tmp ; tmp++ ) {
-               if ( *tmp == '/' )
-                       *tmp = '\\';
-       }
-       DBGC ( local, "LOCAL %p using \"%s\"\n",
-              local, resolved );
-
-       /* Open resolved path */
-       if ( ( rc = efi_local_open_resolved ( local, resolved ) ) != 0 )
-               goto err_open;
-
- err_open:
-       free ( resolved );
- err_resolve:
-       return rc;
-}
-
-/**
- * Get file length
- *
- * @v local            Local file
- * @ret rc             Return status code
- */
-static int efi_local_len ( struct efi_local *local ) {
-       EFI_FILE_PROTOCOL *file = local->file;
-       EFI_FILE_INFO *info;
-       EFI_STATUS efirc;
-       UINTN size;
-       int rc;
-
-       /* Get size of file information */
-       size = 0;
-       file->GetInfo ( file, &efi_file_info_id, &size, NULL );
-
-       /* Allocate file information */
-       info = malloc ( size );
-       if ( ! info ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-
-       /* Get file information */
-       if ( ( efirc = file->GetInfo ( file, &efi_file_info_id, &size,
-                                      info ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( local, "LOCAL %p could not get file info: %s\n",
-                      local, strerror ( rc ) );
-               goto err_info;
-       }
-
-       /* Record file length */
-       local->len = info->FileSize;
-
-       /* Success */
-       rc = 0;
-
- err_info:
-       free ( info );
- err_alloc:
-       return rc;
-}
-
-/**
- * Open local file
- *
- * @v xfer             Data transfer interface
- * @v uri              Request URI
- * @ret rc             Return status code
- */
-static int efi_local_open ( struct interface *xfer, struct uri *uri ) {
-       struct efi_local *local;
-       const char *volume;
-       const char *path;
-       int rc;
-
-       /* Parse URI */
-       volume = ( ( uri->host && uri->host[0] ) ? uri->host : NULL );
-       path = ( uri->opaque ? uri->opaque : uri->path );
-
-       /* Allocate and initialise structure */
-       local = zalloc ( sizeof ( *local ) );
-       if ( ! local ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       ref_init ( &local->refcnt, NULL );
-       intf_init ( &local->xfer, &efi_local_xfer_desc, &local->refcnt );
-       process_init ( &local->process, &efi_local_process_desc,
-                      &local->refcnt );
-
-       /* Open specified volume */
-       if ( ( rc = efi_local_open_volume ( local, volume ) ) != 0 )
-               goto err_open_root;
-
-       /* Open specified path */
-       if ( ( rc = efi_local_open_path ( local, path ) ) != 0 )
-               goto err_open_file;
-
-       /* Get length of file */
-       if ( ( rc = efi_local_len ( local ) ) != 0 )
-               goto err_len;
-
-       /* Attach to parent interface, mortalise self, and return */
-       intf_plug_plug ( &local->xfer, xfer );
-       ref_put ( &local->refcnt );
-       return 0;
-
- err_len:
- err_open_file:
- err_open_root:
-       efi_local_close ( local, 0 );
-       ref_put ( &local->refcnt );
- err_alloc:
-       return rc;
-}
-
-/** EFI local file URI opener */
-struct uri_opener efi_local_uri_opener __uri_opener = {
-       .scheme = "file",
-       .open   = efi_local_open,
-};
index 9f0851a..97ea72b 100644 (file)
@@ -61,157 +61,58 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  ******************************************************************************
  */
 
-/**
- * Locate EFI PCI root bridge I/O protocol
- *
- * @v pci              PCI device
- * @ret handle         EFI PCI root bridge handle
- * @ret root           EFI PCI root bridge I/O protocol, or NULL if not found
- * @ret rc             Return status code
- */
-static int efipci_root ( struct pci_device *pci, EFI_HANDLE *handle,
-                        EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **root ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_HANDLE *handles;
-       UINTN num_handles;
-       union {
-               void *interface;
-               EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *root;
-       } u;
-       EFI_STATUS efirc;
-       UINTN i;
-       int rc;
+/** PCI root bridge I/O protocol */
+static EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *efipci;
+EFI_REQUEST_PROTOCOL ( EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL, &efipci );
 
-       /* Enumerate all handles */
-       if ( ( efirc = bs->LocateHandleBuffer ( ByProtocol,
-                       &efi_pci_root_bridge_io_protocol_guid,
-                       NULL, &num_handles, &handles ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( pci, "EFIPCI cannot locate root bridges: %s\n",
-                      strerror ( rc ) );
-               goto err_locate;
-       }
-
-       /* Look for matching root bridge I/O protocol */
-       for ( i = 0 ; i < num_handles ; i++ ) {
-               *handle = handles[i];
-               if ( ( efirc = bs->OpenProtocol ( *handle,
-                               &efi_pci_root_bridge_io_protocol_guid,
-                               &u.interface, efi_image_handle, *handle,
-                               EFI_OPEN_PROTOCOL_GET_PROTOCOL ) ) != 0 ) {
-                       rc = -EEFI ( efirc );
-                       DBGC ( pci, "EFIPCI cannot open %s: %s\n",
-                              efi_handle_name ( *handle ), strerror ( rc ) );
-                       continue;
-               }
-               if ( u.root->SegmentNumber == PCI_SEG ( pci->busdevfn ) ) {
-                       *root = u.root;
-                       bs->FreePool ( handles );
-                       return 0;
-               }
-               bs->CloseProtocol ( *handle,
-                                   &efi_pci_root_bridge_io_protocol_guid,
-                                   efi_image_handle, *handle );
-       }
-       DBGC ( pci, "EFIPCI found no root bridge for " PCI_FMT "\n",
-              PCI_ARGS ( pci ) );
-       rc = -ENOENT;
-
-       bs->FreePool ( handles );
- err_locate:
-       return rc;
-}
-
-/**
- * Calculate EFI PCI configuration space address
- *
- * @v pci              PCI device
- * @v location         Encoded offset and width
- * @ret address                EFI PCI address
- */
 static unsigned long efipci_address ( struct pci_device *pci,
                                      unsigned long location ) {
-
        return EFI_PCI_ADDRESS ( PCI_BUS ( pci->busdevfn ),
                                 PCI_SLOT ( pci->busdevfn ),
                                 PCI_FUNC ( pci->busdevfn ),
                                 EFIPCI_OFFSET ( location ) );
 }
 
-/**
- * Read from PCI configuration space
- *
- * @v pci              PCI device
- * @v location         Encoded offset and width
- * @ret value          Value
- * @ret rc             Return status code
- */
 int efipci_read ( struct pci_device *pci, unsigned long location,
                  void *value ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *root;
-       EFI_HANDLE handle;
        EFI_STATUS efirc;
        int rc;
 
-       /* Identify root bridge */
-       if ( ( rc = efipci_root ( pci, &handle, &root ) ) != 0 )
-               goto err_root;
+       if ( ! efipci )
+               return -ENOTSUP;
 
-       /* Read from configuration space */
-       if ( ( efirc = root->Pci.Read ( root, EFIPCI_WIDTH ( location ),
-                                       efipci_address ( pci, location ), 1,
-                                       value ) ) != 0 ) {
+       if ( ( efirc = efipci->Pci.Read ( efipci, EFIPCI_WIDTH ( location ),
+                                         efipci_address ( pci, location ), 1,
+                                         value ) ) != 0 ) {
                rc = -EEFI ( efirc );
                DBG ( "EFIPCI config read from " PCI_FMT " offset %02lx "
                      "failed: %s\n", PCI_ARGS ( pci ),
                      EFIPCI_OFFSET ( location ), strerror ( rc ) );
-               goto err_read;
+               return -EIO;
        }
 
- err_read:
-       bs->CloseProtocol ( handle, &efi_pci_root_bridge_io_protocol_guid,
-                           efi_image_handle, handle );
- err_root:
-       return rc;
+       return 0;
 }
 
-/**
- * Write to PCI configuration space
- *
- * @v pci              PCI device
- * @v location         Encoded offset and width
- * @v value            Value
- * @ret rc             Return status code
- */
 int efipci_write ( struct pci_device *pci, unsigned long location,
                   unsigned long value ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *root;
-       EFI_HANDLE handle;
        EFI_STATUS efirc;
        int rc;
 
-       /* Identify root bridge */
-       if ( ( rc = efipci_root ( pci, &handle, &root ) ) != 0 )
-               goto err_root;
+       if ( ! efipci )
+               return -ENOTSUP;
 
-       /* Read from configuration space */
-       if ( ( efirc = root->Pci.Write ( root, EFIPCI_WIDTH ( location ),
-                                        efipci_address ( pci, location ), 1,
-                                        &value ) ) != 0 ) {
+       if ( ( efirc = efipci->Pci.Write ( efipci, EFIPCI_WIDTH ( location ),
+                                          efipci_address ( pci, location ), 1,
+                                          &value ) ) != 0 ) {
                rc = -EEFI ( efirc );
                DBG ( "EFIPCI config write to " PCI_FMT " offset %02lx "
                      "failed: %s\n", PCI_ARGS ( pci ),
                      EFIPCI_OFFSET ( location ), strerror ( rc ) );
-               goto err_write;
+               return -EIO;
        }
 
- err_write:
-       bs->CloseProtocol ( handle, &efi_pci_root_bridge_io_protocol_guid,
-                           efi_image_handle, handle );
- err_root:
-       return rc;
+       return 0;
 }
 
 PROVIDE_PCIAPI_INLINE ( efi, pci_num_bus );
@@ -245,7 +146,6 @@ int efipci_open ( EFI_HANDLE device, UINT32 attributes,
                void *interface;
        } pci_io;
        UINTN pci_segment, pci_bus, pci_dev, pci_fn;
-       unsigned int busdevfn;
        EFI_STATUS efirc;
        int rc;
 
@@ -254,8 +154,8 @@ int efipci_open ( EFI_HANDLE device, UINT32 attributes,
                                          &pci_io.interface, efi_image_handle,
                                          device, attributes ) ) != 0 ) {
                rc = -EEFI_PCI ( efirc );
-               DBGCP ( device, "EFIPCI %s cannot open PCI protocols: %s\n",
-                       efi_handle_name ( device ), strerror ( rc ) );
+               DBGCP ( device, "EFIPCI %p %s cannot open PCI protocols: %s\n",
+                       device, efi_handle_name ( device ), strerror ( rc ) );
                goto err_open_protocol;
        }
 
@@ -264,11 +164,11 @@ int efipci_open ( EFI_HANDLE device, UINT32 attributes,
                                                    &pci_bus, &pci_dev,
                                                    &pci_fn ) ) != 0 ) {
                rc = -EEFI ( efirc );
-               DBGC ( device, "EFIPCI %s could not get PCI location: %s\n",
-                      efi_handle_name ( device ), strerror ( rc ) );
+               DBGC ( device, "EFIPCI %p %s could not get PCI location: %s\n",
+                      device, efi_handle_name ( device ), strerror ( rc ) );
                goto err_get_location;
        }
-       DBGC2 ( device, "EFIPCI %s is PCI %04lx:%02lx:%02lx.%lx\n",
+       DBGC2 ( device, "EFIPCI %p %s is PCI %04lx:%02lx:%02lx.%lx\n", device,
                efi_handle_name ( device ), ( ( unsigned long ) pci_segment ),
                ( ( unsigned long ) pci_bus ), ( ( unsigned long ) pci_dev ),
                ( ( unsigned long ) pci_fn ) );
@@ -290,11 +190,11 @@ int efipci_open ( EFI_HANDLE device, UINT32 attributes,
                                    EFI_PCI_IO_ATTRIBUTE_BUS_MASTER, NULL );
 
        /* Populate PCI device */
-       busdevfn = PCI_BUSDEVFN ( pci_segment, pci_bus, pci_dev, pci_fn );
-       pci_init ( pci, busdevfn );
+       pci_init ( pci, PCI_BUSDEVFN ( pci_bus, pci_dev, pci_fn ) );
        if ( ( rc = pci_read_config ( pci ) ) != 0 ) {
-               DBGC ( device, "EFIPCI %s cannot read PCI configuration: %s\n",
-                      efi_handle_name ( device ), strerror ( rc ) );
+               DBGC ( device, "EFIPCI %p %s cannot read PCI configuration: "
+                      "%s\n", device, efi_handle_name ( device ),
+                      strerror ( rc ) );
                goto err_pci_read_config;
        }
 
@@ -364,12 +264,12 @@ static int efipci_supported ( EFI_HANDLE device ) {
 
        /* Look for a driver */
        if ( ( rc = pci_find_driver ( &pci ) ) != 0 ) {
-               DBGCP ( device, "EFIPCI %s has no driver\n",
-                       efi_handle_name ( device ) );
+               DBGCP ( device, "EFIPCI %p %s has no driver\n",
+                       device, efi_handle_name ( device ) );
                return rc;
        }
-       DBGC ( device, "EFIPCI %s has driver \"%s\"\n",
-              efi_handle_name ( device ), pci.id->name );
+       DBGC ( device, "EFIPCI %p %s has driver \"%s\"\n",
+              device, efi_handle_name ( device ), pci.id->name );
 
        return 0;
 }
@@ -396,16 +296,16 @@ static int efipci_start ( struct efi_device *efidev ) {
        if ( ( rc = efipci_open ( device, ( EFI_OPEN_PROTOCOL_BY_DRIVER |
                                            EFI_OPEN_PROTOCOL_EXCLUSIVE ),
                                  pci ) ) != 0 ) {
-               DBGC ( device, "EFIPCI %s could not open PCI device: %s\n",
-                      efi_handle_name ( device ), strerror ( rc ) );
+               DBGC ( device, "EFIPCI %p %s could not open PCI device: %s\n",
+                      device, efi_handle_name ( device ), strerror ( rc ) );
                DBGC_EFI_OPENERS ( device, device, &efi_pci_io_protocol_guid );
                goto err_open;
        }
 
        /* Find driver */
        if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
-               DBGC ( device, "EFIPCI %s has no driver\n",
-                      efi_handle_name ( device ) );
+               DBGC ( device, "EFIPCI %p %s has no driver\n",
+                      device, efi_handle_name ( device ) );
                goto err_find_driver;
        }
 
@@ -415,13 +315,13 @@ static int efipci_start ( struct efi_device *efidev ) {
 
        /* Probe driver */
        if ( ( rc = pci_probe ( pci ) ) != 0 ) {
-               DBGC ( device, "EFIPCI %s could not probe driver \"%s\": %s\n",
-                      efi_handle_name ( device ), pci->id->name,
-                      strerror ( rc ) );
+               DBGC ( device, "EFIPCI %p %s could not probe driver \"%s\": "
+                      "%s\n", device, efi_handle_name ( device ),
+                      pci->id->name, strerror ( rc ) );
                goto err_probe;
        }
-       DBGC ( device, "EFIPCI %s using driver \"%s\"\n",
-              efi_handle_name ( device ), pci->id->name );
+       DBGC ( device, "EFIPCI %p %s using driver \"%s\"\n",
+              device, efi_handle_name ( device ), pci->id->name );
 
        efidev_set_drvdata ( efidev, pci );
        return 0;
diff --git a/roms/ipxe/src/interface/efi/efi_pxe.c b/roms/ipxe/src/interface/efi/efi_pxe.c
deleted file mode 100644 (file)
index a1f81df..0000000
+++ /dev/null
@@ -1,1687 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <string.h>
-#include <errno.h>
-#include <ipxe/refcnt.h>
-#include <ipxe/list.h>
-#include <ipxe/netdevice.h>
-#include <ipxe/fakedhcp.h>
-#include <ipxe/process.h>
-#include <ipxe/uri.h>
-#include <ipxe/in.h>
-#include <ipxe/socket.h>
-#include <ipxe/tcpip.h>
-#include <ipxe/xferbuf.h>
-#include <ipxe/open.h>
-#include <ipxe/dhcppkt.h>
-#include <ipxe/udp.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_snp.h>
-#include <ipxe/efi/efi_pxe.h>
-#include <ipxe/efi/Protocol/PxeBaseCode.h>
-#include <ipxe/efi/Protocol/AppleNetBoot.h>
-#include <usr/ifmgmt.h>
-#include <config/general.h>
-
-/** @file
- *
- * EFI PXE base code protocol
- *
- */
-
-/* Downgrade user experience if configured to do so
- *
- * See comments in efi_snp.c
- */
-#ifdef EFI_DOWNGRADE_UX
-static EFI_GUID dummy_pxe_base_code_protocol_guid = {
-       0x70647523, 0x2320, 0x7477,
-       { 0x66, 0x20, 0x23, 0x6d, 0x6f, 0x72, 0x6f, 0x6e }
-};
-#define efi_pxe_base_code_protocol_guid dummy_pxe_base_code_protocol_guid
-#endif
-
-/** A PXE base code */
-struct efi_pxe {
-       /** Reference count */
-       struct refcnt refcnt;
-       /** Underlying network device */
-       struct net_device *netdev;
-       /** Name */
-       const char *name;
-       /** List of PXE base codes */
-       struct list_head list;
-
-       /** Installed handle */
-       EFI_HANDLE handle;
-       /** PXE base code protocol */
-       EFI_PXE_BASE_CODE_PROTOCOL base;
-       /** PXE base code mode */
-       EFI_PXE_BASE_CODE_MODE mode;
-       /** Apple NetBoot protocol */
-       EFI_APPLE_NET_BOOT_PROTOCOL apple;
-
-       /** TCP/IP network-layer protocol */
-       struct tcpip_net_protocol *tcpip;
-       /** Network-layer protocol */
-       struct net_protocol *net;
-
-       /** Data transfer buffer */
-       struct xfer_buffer buf;
-
-       /** (M)TFTP download interface */
-       struct interface tftp;
-       /** Block size (for TFTP) */
-       size_t blksize;
-       /** Overall return status */
-       int rc;
-
-       /** UDP interface */
-       struct interface udp;
-       /** List of received UDP packets */
-       struct list_head queue;
-       /** UDP interface closer process */
-       struct process process;
-};
-
-/**
- * Free PXE base code
- *
- * @v refcnt           Reference count
- */
-static void efi_pxe_free ( struct refcnt *refcnt ) {
-       struct efi_pxe *pxe = container_of ( refcnt, struct efi_pxe, refcnt );
-
-       netdev_put ( pxe->netdev );
-       free ( pxe );
-}
-
-/** List of PXE base codes */
-static LIST_HEAD ( efi_pxes );
-
-/**
- * Locate PXE base code
- *
- * @v handle           EFI handle
- * @ret pxe            PXE base code, or NULL
- */
-static struct efi_pxe * efi_pxe_find ( EFI_HANDLE handle ) {
-       struct efi_pxe *pxe;
-
-       /* Locate base code */
-       list_for_each_entry ( pxe, &efi_pxes, list ) {
-               if ( pxe->handle == handle )
-                       return pxe;
-       }
-
-       return NULL;
-}
-
-/******************************************************************************
- *
- * IP addresses
- *
- ******************************************************************************
- */
-
-/**
- * An EFI socket address
- *
- */
-struct sockaddr_efi {
-       /** Socket address family (part of struct @c sockaddr) */
-       sa_family_t se_family;
-       /** Flags (part of struct @c sockaddr_tcpip) */
-       uint16_t se_flags;
-       /** TCP/IP port (part of struct @c sockaddr_tcpip) */
-       uint16_t se_port;
-       /** Scope ID (part of struct @c sockaddr_tcpip)
-        *
-        * For link-local or multicast addresses, this is the network
-        * device index.
-        */
-        uint16_t se_scope_id;
-       /** IP address */
-       EFI_IP_ADDRESS se_addr;
-       /** Padding
-        *
-        * This ensures that a struct @c sockaddr_tcpip is large
-        * enough to hold a socket address for any TCP/IP address
-        * family.
-        */
-       char pad[ sizeof ( struct sockaddr ) -
-                 ( sizeof ( sa_family_t ) /* se_family */ +
-                   sizeof ( uint16_t ) /* se_flags */ +
-                   sizeof ( uint16_t ) /* se_port */ +
-                   sizeof ( uint16_t ) /* se_scope_id */ +
-                   sizeof ( EFI_IP_ADDRESS ) /* se_addr */ ) ];
-} __attribute__ (( packed, may_alias ));
-
-/**
- * Populate socket address from EFI IP address
- *
- * @v pxe              PXE base code
- * @v ip               EFI IP address
- * @v sa               Socket address to fill in
- */
-static void efi_pxe_ip_sockaddr ( struct efi_pxe *pxe, EFI_IP_ADDRESS *ip,
-                                 struct sockaddr *sa ) {
-       union {
-               struct sockaddr sa;
-               struct sockaddr_efi se;
-       } *sockaddr = container_of ( sa, typeof ( *sockaddr ), sa );
-
-       /* Initialise socket address */
-       memset ( sockaddr, 0, sizeof ( *sockaddr ) );
-       sockaddr->sa.sa_family = pxe->tcpip->sa_family;
-       memcpy ( &sockaddr->se.se_addr, ip, pxe->net->net_addr_len );
-       sockaddr->se.se_scope_id = pxe->netdev->index;
-}
-
-/**
- * Transcribe EFI IP address (for debugging)
- *
- * @v pxe              PXE base code
- * @v ip               EFI IP address
- * @ret text           Transcribed IP address
- */
-static const char * efi_pxe_ip_ntoa ( struct efi_pxe *pxe,
-                                     EFI_IP_ADDRESS *ip ) {
-
-       return pxe->net->ntoa ( ip );
-}
-
-/**
- * Populate local IP address
- *
- * @v pxe              PXE base code
- * @ret rc             Return status code
- */
-static int efi_pxe_ip ( struct efi_pxe *pxe ) {
-       EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
-       struct in_addr address;
-       struct in_addr netmask;
-
-       /* It's unclear which of the potentially many IPv6 addresses
-        * is supposed to be used.
-        */
-       if ( mode->UsingIpv6 )
-               return -ENOTSUP;
-
-       /* Fetch IP address and subnet mask */
-       fetch_ipv4_setting ( netdev_settings ( pxe->netdev ), &ip_setting,
-                            &address );
-       fetch_ipv4_setting ( netdev_settings ( pxe->netdev ), &netmask_setting,
-                            &netmask );
-
-       /* Populate IP address and subnet mask */
-       memset ( &mode->StationIp, 0, sizeof ( mode->StationIp ) );
-       memcpy ( &mode->StationIp, &address, sizeof ( address ) );
-       memset ( &mode->SubnetMask, 0, sizeof ( mode->SubnetMask ) );
-       memcpy ( &mode->SubnetMask, &netmask, sizeof ( netmask ) );
-
-       return 0;
-}
-
-/**
- * Check if IP address matches filter
- *
- * @v pxe              PXE base code
- * @v ip               EFI IP address
- * @ret is_match       IP address matches filter
- */
-static int efi_pxe_ip_filter ( struct efi_pxe *pxe, EFI_IP_ADDRESS *ip ) {
-       EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
-       EFI_PXE_BASE_CODE_IP_FILTER *filter = &mode->IpFilter;
-       uint8_t filters = filter->Filters;
-       union {
-               EFI_IP_ADDRESS ip;
-               struct in_addr in;
-               struct in6_addr in6;
-       } *u = container_of ( ip, typeof ( *u ), ip );
-       size_t addr_len = pxe->net->net_addr_len;
-       unsigned int i;
-
-       /* Match everything, if applicable */
-       if ( filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS )
-               return 1;
-
-       /* Match all multicasts, if applicable */
-       if ( filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST ) {
-               if ( mode->UsingIpv6 ) {
-                       if ( IN6_IS_ADDR_MULTICAST ( &u->in6 ) )
-                               return 1;
-               } else {
-                       if ( IN_IS_MULTICAST ( u->in.s_addr ) )
-                               return 1;
-               }
-       }
-
-       /* Match IPv4 broadcasts, if applicable */
-       if ( filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST ) {
-               if ( ( ! mode->UsingIpv6 ) &&
-                    ( u->in.s_addr == INADDR_BROADCAST ) )
-                       return 1;
-       }
-
-       /* Match station address, if applicable */
-       if ( filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP ) {
-               if ( memcmp ( ip, &mode->StationIp, addr_len ) == 0 )
-                       return 1;
-       }
-
-       /* Match explicit addresses, if applicable */
-       for ( i = 0 ; i < filter->IpCnt ; i++ ) {
-               if ( memcmp ( ip, &filter->IpList[i], addr_len ) == 0 )
-                       return 1;
-       }
-
-       return 0;
-}
-
-/******************************************************************************
- *
- * Data transfer buffer
- *
- ******************************************************************************
- */
-
-/**
- * Reallocate PXE data transfer buffer
- *
- * @v xferbuf          Data transfer buffer
- * @v len              New length (or zero to free buffer)
- * @ret rc             Return status code
- */
-static int efi_pxe_buf_realloc ( struct xfer_buffer *xferbuf __unused,
-                                size_t len __unused ) {
-
-       /* Can never reallocate: return EFI_BUFFER_TOO_SMALL */
-       return -ERANGE;
-}
-
-/**
- * Write data to PXE data transfer buffer
- *
- * @v xferbuf          Data transfer buffer
- * @v offset           Starting offset
- * @v data             Data to copy
- * @v len              Length of data
- */
-static void efi_pxe_buf_write ( struct xfer_buffer *xferbuf, size_t offset,
-                               const void *data, size_t len ) {
-
-       /* Copy data to buffer */
-       memcpy ( ( xferbuf->data + offset ), data, len );
-}
-
-/** PXE data transfer buffer operations */
-static struct xfer_buffer_operations efi_pxe_buf_operations = {
-       .realloc = efi_pxe_buf_realloc,
-       .write = efi_pxe_buf_write,
-};
-
-/******************************************************************************
- *
- * (M)TFTP download interface
- *
- ******************************************************************************
- */
-
-/**
- * Close PXE (M)TFTP download interface
- *
- * @v pxe              PXE base code
- * @v rc               Reason for close
- */
-static void efi_pxe_tftp_close ( struct efi_pxe *pxe, int rc ) {
-
-       /* Restart interface */
-       intf_restart ( &pxe->tftp, rc );
-
-       /* Record overall status */
-       pxe->rc = rc;
-}
-
-/**
- * Check PXE (M)TFTP download flow control window
- *
- * @v pxe              PXE base code
- * @ret len            Length of window
- */
-static size_t efi_pxe_tftp_window ( struct efi_pxe *pxe ) {
-
-       /* Return requested blocksize */
-       return pxe->blksize;
-}
-
-/**
- * Receive new PXE (M)TFTP download data
- *
- * @v pxe              PXE base code
- * @v iobuf            I/O buffer
- * @v meta             Transfer metadata
- * @ret rc             Return status code
- */
-static int efi_pxe_tftp_deliver ( struct efi_pxe *pxe,
-                                 struct io_buffer *iobuf,
-                                 struct xfer_metadata *meta ) {
-       int rc;
-
-       /* Deliver to data transfer buffer */
-       if ( ( rc = xferbuf_deliver ( &pxe->buf, iob_disown ( iobuf ),
-                                     meta ) ) != 0 )
-               goto err_deliver;
-
-       return 0;
-
- err_deliver:
-       efi_pxe_tftp_close ( pxe, rc );
-       return rc;
-}
-
-/** PXE file data transfer interface operations */
-static struct interface_operation efi_pxe_tftp_operations[] = {
-       INTF_OP ( xfer_deliver, struct efi_pxe *, efi_pxe_tftp_deliver ),
-       INTF_OP ( xfer_window, struct efi_pxe *, efi_pxe_tftp_window ),
-       INTF_OP ( intf_close, struct efi_pxe *, efi_pxe_tftp_close ),
-};
-
-/** PXE file data transfer interface descriptor */
-static struct interface_descriptor efi_pxe_tftp_desc =
-       INTF_DESC ( struct efi_pxe, tftp, efi_pxe_tftp_operations );
-
-/**
- * Open (M)TFTP download interface
- *
- * @v pxe              PXE base code
- * @v ip               EFI IP address
- * @v filename         Filename
- * @ret rc             Return status code
- */
-static int efi_pxe_tftp_open ( struct efi_pxe *pxe, EFI_IP_ADDRESS *ip,
-                              const char *filename ) {
-       struct sockaddr server;
-       struct uri *uri;
-       int rc;
-
-       /* Parse server address and filename */
-       efi_pxe_ip_sockaddr ( pxe, ip, &server );
-       uri = pxe_uri ( &server, filename );
-       if ( ! uri ) {
-               DBGC ( pxe, "PXE %s could not parse %s:%s\n", pxe->name,
-                      efi_pxe_ip_ntoa ( pxe, ip ), filename );
-               rc = -ENOTSUP;
-               goto err_parse;
-       }
-
-       /* Open URI */
-       if ( ( rc = xfer_open_uri ( &pxe->tftp, uri ) ) != 0 ) {
-               DBGC ( pxe, "PXE %s could not open: %s\n",
-                      pxe->name, strerror ( rc ) );
-               goto err_open;
-       }
-
- err_open:
-       uri_put ( uri );
- err_parse:
-       return rc;
-}
-
-/******************************************************************************
- *
- * UDP interface
- *
- ******************************************************************************
- */
-
-/** EFI UDP pseudo-header */
-struct efi_pxe_udp_pseudo_header {
-       /** Network-layer protocol */
-       struct net_protocol *net;
-       /** Destination port */
-       uint16_t dest_port;
-       /** Source port */
-       uint16_t src_port;
-} __attribute__ (( packed ));
-
-/**
- * Close UDP interface
- *
- * @v pxe              PXE base code
- * @v rc               Reason for close
- */
-static void efi_pxe_udp_close ( struct efi_pxe *pxe, int rc ) {
-       struct io_buffer *iobuf;
-       struct io_buffer *tmp;
-
-       /* Release our claim on SNP devices, if applicable */
-       if ( process_running ( &pxe->process ) )
-               efi_snp_release();
-
-       /* Stop process */
-       process_del ( &pxe->process );
-
-       /* Restart UDP interface */
-       intf_restart ( &pxe->udp, rc );
-
-       /* Flush any received UDP packets */
-       list_for_each_entry_safe ( iobuf, tmp, &pxe->queue, list ) {
-               list_del ( &iobuf->list );
-               free_iob ( iobuf );
-       }
-}
-
-/**
- * Receive UDP packet
- *
- * @v pxe              PXE base code
- * @v iobuf            I/O buffer
- * @v meta             Data transfer metadata
- * @ret rc             Return status code
- */
-static int efi_pxe_udp_deliver ( struct efi_pxe *pxe, struct io_buffer *iobuf,
-                                struct xfer_metadata *meta ) {
-       struct sockaddr_efi *se_src;
-       struct sockaddr_efi *se_dest;
-       struct tcpip_net_protocol *tcpip;
-       struct net_protocol *net;
-       struct efi_pxe_udp_pseudo_header *pshdr;
-       size_t addr_len;
-       size_t pshdr_len;
-       int rc;
-
-       /* Sanity checks */
-       assert ( meta != NULL );
-       se_src = ( ( struct sockaddr_efi * ) meta->src );
-       assert ( se_src != NULL );
-       se_dest = ( ( struct sockaddr_efi * ) meta->dest );
-       assert ( se_dest != NULL );
-       assert ( se_src->se_family == se_dest->se_family );
-
-       /* Determine protocol */
-       tcpip = tcpip_net_protocol ( se_src->se_family );
-       if ( ! tcpip ) {
-               rc = -ENOTSUP;
-               goto err_unsupported;
-       }
-       net = tcpip->net_protocol;
-       addr_len = net->net_addr_len;
-
-       /* Construct pseudo-header */
-       pshdr_len = ( sizeof ( *pshdr ) + ( 2 * addr_len ) );
-       if ( ( rc = iob_ensure_headroom ( iobuf, pshdr_len ) ) != 0 )
-               goto err_headroom;
-       memcpy ( iob_push ( iobuf, addr_len ), &se_src->se_addr, addr_len );
-       memcpy ( iob_push ( iobuf, addr_len ), &se_dest->se_addr, addr_len );
-       pshdr = iob_push ( iobuf, sizeof ( *pshdr ) );
-       pshdr->net = net;
-       pshdr->dest_port = ntohs ( se_dest->se_port );
-       pshdr->src_port = ntohs ( se_src->se_port );
-
-       /* Add to queue */
-       list_add_tail ( &iobuf->list, &pxe->queue );
-
-       return 0;
-
- err_unsupported:
- err_headroom:
-       free_iob ( iobuf );
-       return rc;
-}
-
-/** PXE UDP interface operations */
-static struct interface_operation efi_pxe_udp_operations[] = {
-       INTF_OP ( xfer_deliver, struct efi_pxe *, efi_pxe_udp_deliver ),
-       INTF_OP ( intf_close, struct efi_pxe *, efi_pxe_udp_close ),
-};
-
-/** PXE UDP interface descriptor */
-static struct interface_descriptor efi_pxe_udp_desc =
-       INTF_DESC ( struct efi_pxe, udp, efi_pxe_udp_operations );
-
-/**
- * Open UDP interface
- *
- * @v pxe              PXE base code
- * @ret rc             Return status code
- */
-static int efi_pxe_udp_open ( struct efi_pxe *pxe ) {
-       int rc;
-
-       /* If interface is already open, then cancel the scheduled close */
-       if ( process_running ( &pxe->process ) ) {
-               process_del ( &pxe->process );
-               return 0;
-       }
-
-       /* Open promiscuous UDP interface */
-       if ( ( rc = udp_open_promisc ( &pxe->udp ) ) != 0 ) {
-               DBGC ( pxe, "PXE %s could not open UDP connection: %s\n",
-                      pxe->name, strerror ( rc ) );
-               return rc;
-       }
-
-       /* Claim network devices */
-       efi_snp_claim();
-
-       return 0;
-}
-
-/**
- * Schedule close of UDP interface
- *
- * @v pxe              PXE base code
- */
-static void efi_pxe_udp_schedule_close ( struct efi_pxe *pxe ) {
-
-       /* The EFI PXE base code protocol does not provide any
-        * explicit UDP open/close methods.  To avoid the overhead of
-        * reopening a socket for each read/write operation, we start
-        * a process which will close the socket immediately if the
-        * next call into iPXE is anything other than a UDP
-        * read/write.
-        */
-       process_add ( &pxe->process );
-}
-
-/**
- * Scheduled close of UDP interface
- *
- * @v pxe              PXE base code
- */
-static void efi_pxe_udp_scheduled_close ( struct efi_pxe *pxe ) {
-
-       /* Close UDP interface */
-       efi_pxe_udp_close ( pxe, 0 );
-}
-
-/** UDP close process descriptor */
-static struct process_descriptor efi_pxe_process_desc =
-       PROC_DESC_ONCE ( struct efi_pxe, process, efi_pxe_udp_scheduled_close );
-
-/******************************************************************************
- *
- * Fake DHCP packets
- *
- ******************************************************************************
- */
-
-/**
- * Name fake DHCP packet
- *
- * @v pxe              PXE base code
- * @v packet           Packet
- * @ret name           Name of packet
- */
-static const char * efi_pxe_fake_name ( struct efi_pxe *pxe,
-                                       EFI_PXE_BASE_CODE_PACKET *packet ) {
-       EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
-
-       if ( packet == &mode->DhcpDiscover ) {
-               return "DhcpDiscover";
-       } else if ( packet == &mode->DhcpAck ) {
-               return "DhcpAck";
-       } else if ( packet == &mode->ProxyOffer ) {
-               return "ProxyOffer";
-       } else if ( packet == &mode->PxeDiscover ) {
-               return "PxeDiscover";
-       } else if ( packet == &mode->PxeReply ) {
-               return "PxeReply";
-       } else if ( packet == &mode->PxeBisReply ) {
-               return "PxeBisReply";
-       } else {
-               return "<UNKNOWN>";
-       }
-}
-
-/**
- * Construct fake DHCP packet and flag
- *
- * @v pxe              PXE base code
- * @v fake             Fake packet constructor
- * @v packet           Packet to fill in
- * @ret exists         Packet existence flag
- */
-static BOOLEAN efi_pxe_fake ( struct efi_pxe *pxe,
-                             int ( * fake ) ( struct net_device *netdev,
-                                              void *data, size_t len ),
-                             EFI_PXE_BASE_CODE_PACKET *packet ) {
-       EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
-       struct dhcp_packet dhcppkt;
-       struct dhcphdr *dhcphdr;
-       unsigned int len;
-       int rc;
-
-       /* The fake packet constructors do not support IPv6 */
-       if ( mode->UsingIpv6 )
-               return FALSE;
-
-       /* Attempt to construct packet */
-       if ( ( rc = fake ( pxe->netdev, packet, sizeof ( *packet ) ) != 0 ) ) {
-               DBGC ( pxe, "PXE %s could not fake %s: %s\n", pxe->name,
-                      efi_pxe_fake_name ( pxe, packet ), strerror ( rc ) );
-               return FALSE;
-       }
-
-       /* The WDS bootstrap wdsmgfw.efi has a buggy DHCPv4 packet
-        * parser which does not correctly handle DHCP padding bytes.
-        * Specifically, if a padding byte (i.e. a zero) is
-        * encountered, the parse will first increment the pointer by
-        * one to skip over the padding byte but will then drop into
-        * the code path for handling normal options, which increments
-        * the pointer by two to skip over the (already-skipped) type
-        * field and the (non-existent) length field.
-        *
-        * The upshot of this bug in WDS is that the parser will fail
-        * with an error 0xc0000023 if the number of spare bytes after
-        * the end of the options is not an exact multiple of three.
-        *
-        * Work around this buggy parser by adding an explicit
-        * DHCP_END tag.
-        */
-       dhcphdr = container_of ( &packet->Dhcpv4.BootpOpcode,
-                                struct dhcphdr, op );
-       dhcppkt_init ( &dhcppkt, dhcphdr, sizeof ( *packet ) );
-       len = dhcppkt_len ( &dhcppkt );
-       if ( len < sizeof ( *packet ) )
-               packet->Raw[len] = DHCP_END;
-
-       return TRUE;
-}
-
-/**
- * Construct fake DHCP packets
- *
- * @v pxe              PXE base code
- */
-static void efi_pxe_fake_all ( struct efi_pxe *pxe ) {
-       EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
-
-       /* Construct fake packets */
-       mode->DhcpDiscoverValid =
-               efi_pxe_fake ( pxe, create_fakedhcpdiscover,
-                              &mode->DhcpDiscover );
-       mode->DhcpAckReceived =
-               efi_pxe_fake ( pxe, create_fakedhcpack,
-                              &mode->DhcpAck );
-       mode->PxeReplyReceived =
-               efi_pxe_fake ( pxe, create_fakepxebsack,
-                              &mode->PxeReply );
-}
-
-/******************************************************************************
- *
- * Base code protocol
- *
- ******************************************************************************
- */
-
-/**
- * Start PXE base code
- *
- * @v base             PXE base code protocol
- * @v use_ipv6         Use IPv6
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI efi_pxe_start ( EFI_PXE_BASE_CODE_PROTOCOL *base,
-                                        BOOLEAN use_ipv6 ) {
-       struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
-       EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
-       struct tcpip_net_protocol *ipv6 = tcpip_net_protocol ( AF_INET6 );
-       sa_family_t family = ( use_ipv6 ? AF_INET6 : AF_INET );
-       int rc;
-
-       DBGC ( pxe, "PXE %s START %s\n", pxe->name, ( ipv6 ? "IPv6" : "IPv4" ));
-
-       /* Initialise mode structure */
-       memset ( mode, 0, sizeof ( *mode ) );
-       mode->AutoArp = TRUE;
-       mode->TTL = DEFAULT_TTL;
-       mode->ToS = DEFAULT_ToS;
-       mode->IpFilter.Filters =
-               ( EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP |
-                 EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST |
-                 EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS |
-                 EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST );
-
-       /* Check for IPv4/IPv6 support */
-       mode->Ipv6Supported = ( ipv6 != NULL );
-       mode->Ipv6Available = ( ipv6 != NULL );
-       pxe->tcpip = tcpip_net_protocol ( family );
-       if ( ! pxe->tcpip ) {
-               DBGC ( pxe, "PXE %s has no support for %s\n",
-                      pxe->name, socket_family_name ( family ) );
-               return EFI_UNSUPPORTED;
-       }
-       pxe->net = pxe->tcpip->net_protocol;
-       mode->UsingIpv6 = use_ipv6;
-
-       /* Populate station IP address */
-       if ( ( rc = efi_pxe_ip ( pxe ) ) != 0 )
-               return rc;
-
-       /* Construct fake DHCP packets */
-       efi_pxe_fake_all ( pxe );
-
-       /* Record that base code is started */
-       mode->Started = TRUE;
-       DBGC ( pxe, "PXE %s using %s\n",
-              pxe->name, pxe->net->ntoa ( &mode->StationIp ) );
-
-       return 0;
-}
-
-/**
- * Stop PXE base code
- *
- * @v base             PXE base code protocol
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI efi_pxe_stop ( EFI_PXE_BASE_CODE_PROTOCOL *base ) {
-       struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
-       EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
-
-       DBGC ( pxe, "PXE %s STOP\n", pxe->name );
-
-       /* Record that base code is stopped */
-       mode->Started = FALSE;
-
-       /* Close TFTP */
-       efi_pxe_tftp_close ( pxe, 0 );
-
-       /* Close UDP */
-       efi_pxe_udp_close ( pxe, 0 );
-
-       return 0;
-}
-
-/**
- * Perform DHCP
- *
- * @v base             PXE base code protocol
- * @v sort             Offers should be sorted
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI efi_pxe_dhcp ( EFI_PXE_BASE_CODE_PROTOCOL *base,
-                                       BOOLEAN sort ) {
-       struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
-       struct net_device *netdev = pxe->netdev;
-       int rc;
-
-       DBGC ( pxe, "PXE %s DHCP %s\n",
-              pxe->name, ( sort ? "sorted" : "unsorted" ) );
-
-       /* Claim network devices */
-       efi_snp_claim();
-
-       /* Initiate configuration */
-       if ( ( rc = netdev_configure_all ( netdev ) ) != 0 ) {
-               DBGC ( pxe, "PXE %s could not initiate configuration: %s\n",
-                      pxe->name, strerror ( rc ) );
-               goto err_configure;
-       }
-
-       /* Wait for configuration to complete (or time out) */
-       while ( netdev_configuration_in_progress ( netdev ) )
-               step();
-
-       /* Report timeout if configuration failed */
-       if ( ! netdev_configuration_ok ( netdev ) ) {
-               rc = -ETIMEDOUT;
-               goto err_timeout;
-       }
-
-       /* Update station IP address */
-       if ( ( rc = efi_pxe_ip ( pxe ) ) != 0 )
-               goto err_ip;
-
-       /* Update faked DHCP packets */
-       efi_pxe_fake_all ( pxe );
-
- err_ip:
- err_timeout:
- err_configure:
-       efi_snp_release();
-       return EFIRC ( rc );
-}
-
-/**
- * Perform boot server discovery
- *
- * @v base             PXE base code protocol
- * @v type             Boot server type
- * @v layer            Boot server layer
- * @v bis              Use boot integrity services
- * @v info             Additional information
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_pxe_discover ( EFI_PXE_BASE_CODE_PROTOCOL *base, UINT16 type, UINT16 *layer,
-                  BOOLEAN bis, EFI_PXE_BASE_CODE_DISCOVER_INFO *info ) {
-       struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
-       EFI_IP_ADDRESS *ip;
-       unsigned int i;
-
-       DBGC ( pxe, "PXE %s DISCOVER type %d layer %d%s\n",
-              pxe->name, type, *layer, ( bis ? " bis" : "" ) );
-       if ( info ) {
-               DBGC ( pxe, "%s%s%s%s %s",
-                      ( info->UseMCast ? " mcast" : "" ),
-                      ( info->UseBCast ? " bcast" : "" ),
-                      ( info->UseUCast ? " ucast" : "" ),
-                      ( info->MustUseList ? " list" : "" ),
-                      efi_pxe_ip_ntoa ( pxe, &info->ServerMCastIp ) );
-               for ( i = 0 ; i < info->IpCnt ; i++ ) {
-                       ip = &info->SrvList[i].IpAddr;
-                       DBGC ( pxe, " %d%s:%s", info->SrvList[i].Type,
-                              ( info->SrvList[i].AcceptAnyResponse ?
-                                ":any" : "" ), efi_pxe_ip_ntoa ( pxe, ip ) );
-               }
-       }
-       DBGC ( pxe, "\n" );
-
-       /* Not used by any bootstrap I can find to test with */
-       return EFI_UNSUPPORTED;
-}
-
-/**
- * Perform (M)TFTP
- *
- * @v base             PXE base code protocol
- * @v opcode           TFTP opcode
- * @v data             Data buffer
- * @v overwrite                Overwrite file
- * @v len              Length of data buffer
- * @v blksize          Block size
- * @v ip               Server address
- * @v filename         Filename
- * @v info             Additional information
- * @v callback         Pass packets to callback instead of data buffer
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_pxe_mtftp ( EFI_PXE_BASE_CODE_PROTOCOL *base,
-               EFI_PXE_BASE_CODE_TFTP_OPCODE opcode, VOID *data,
-               BOOLEAN overwrite, UINT64 *len, UINTN *blksize,
-               EFI_IP_ADDRESS *ip, UINT8 *filename,
-               EFI_PXE_BASE_CODE_MTFTP_INFO *info, BOOLEAN callback ) {
-       struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
-       int rc;
-
-       DBGC ( pxe, "PXE %s MTFTP %d%s %p+%llx", pxe->name, opcode,
-              ( overwrite ? " overwrite" : "" ), data, *len );
-       if ( blksize )
-               DBGC ( pxe, " blksize %zd", ( ( size_t ) *blksize ) );
-       DBGC ( pxe, " %s:%s", efi_pxe_ip_ntoa ( pxe, ip ), filename );
-       if ( info ) {
-               DBGC ( pxe, " %s:%d:%d:%d:%d",
-                      efi_pxe_ip_ntoa ( pxe, &info->MCastIp ),
-                      info->CPort, info->SPort, info->ListenTimeout,
-                      info->TransmitTimeout );
-       }
-       DBGC ( pxe, "%s\n", ( callback ? " callback" : "" ) );
-
-       /* Fail unless operation is supported */
-       if ( ! ( ( opcode == EFI_PXE_BASE_CODE_TFTP_READ_FILE ) ||
-                ( opcode == EFI_PXE_BASE_CODE_MTFTP_READ_FILE ) ) ) {
-               DBGC ( pxe, "PXE %s unsupported MTFTP opcode %d\n",
-                      pxe->name, opcode );
-               rc = -ENOTSUP;
-               goto err_opcode;
-       }
-
-       /* Claim network devices */
-       efi_snp_claim();
-
-       /* Determine block size.  Ignore the requested block size
-        * unless we are using callbacks, since limiting HTTP to a
-        * 512-byte TCP window is not sensible.
-        */
-       pxe->blksize = ( ( callback && blksize ) ? *blksize : -1UL );
-
-       /* Initialise data transfer buffer */
-       pxe->buf.data = data;
-       pxe->buf.len = *len;
-
-       /* Open download */
-       if ( ( rc = efi_pxe_tftp_open ( pxe, ip,
-                                       ( ( const char * ) filename ) ) ) != 0 )
-               goto err_open;
-
-       /* Wait for download to complete */
-       pxe->rc = -EINPROGRESS;
-       while ( pxe->rc == -EINPROGRESS )
-               step();
-       if ( ( rc = pxe->rc ) != 0 ) {
-               DBGC ( pxe, "PXE %s download failed: %s\n",
-                      pxe->name, strerror ( rc ) );
-               goto err_download;
-       }
-
- err_download:
-       efi_pxe_tftp_close ( pxe, rc );
- err_open:
-       efi_snp_release();
- err_opcode:
-       return EFIRC ( rc );
-}
-
-/**
- * Transmit UDP packet
- *
- * @v base             PXE base code protocol
- * @v flags            Operation flags
- * @v dest_ip          Destination address
- * @v dest_port                Destination port
- * @v gateway          Gateway address
- * @v src_ip           Source address
- * @v src_port         Source port
- * @v hdr_len          Header length
- * @v hdr              Header data
- * @v len              Length
- * @v data             Data
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_pxe_udp_write ( EFI_PXE_BASE_CODE_PROTOCOL *base, UINT16 flags,
-                   EFI_IP_ADDRESS *dest_ip,
-                   EFI_PXE_BASE_CODE_UDP_PORT *dest_port,
-                   EFI_IP_ADDRESS *gateway, EFI_IP_ADDRESS *src_ip,
-                   EFI_PXE_BASE_CODE_UDP_PORT *src_port,
-                   UINTN *hdr_len, VOID *hdr, UINTN *len, VOID *data ) {
-       struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
-       EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
-       struct io_buffer *iobuf;
-       struct xfer_metadata meta;
-       union {
-               struct sockaddr_tcpip st;
-               struct sockaddr sa;
-       } dest;
-       union {
-               struct sockaddr_tcpip st;
-               struct sockaddr sa;
-       } src;
-       int rc;
-
-       DBGC2 ( pxe, "PXE %s UDP WRITE ", pxe->name );
-       if ( src_ip )
-               DBGC2 ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, src_ip ) );
-       DBGC2 ( pxe, ":" );
-       if ( src_port &&
-            ( ! ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT ) ) ) {
-               DBGC2 ( pxe, "%d", *src_port );
-       } else {
-               DBGC2 ( pxe, "*" );
-       }
-       DBGC2 ( pxe, "->%s:%d", efi_pxe_ip_ntoa ( pxe, dest_ip ), *dest_port );
-       if ( gateway )
-               DBGC2 ( pxe, " via %s", efi_pxe_ip_ntoa ( pxe, gateway ) );
-       if ( hdr_len )
-               DBGC2 ( pxe, " %p+%zx", hdr, ( ( size_t ) *hdr_len ) );
-       DBGC2 ( pxe, " %p+%zx", data, ( ( size_t ) *len ) );
-       if ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT )
-               DBGC2 ( pxe, " frag" );
-       DBGC2 ( pxe, "\n" );
-
-       /* Open UDP connection (if applicable) */
-       if ( ( rc = efi_pxe_udp_open ( pxe ) ) != 0 )
-               goto err_open;
-
-       /* Construct destination address */
-       efi_pxe_ip_sockaddr ( pxe, dest_ip, &dest.sa );
-       dest.st.st_port = htons ( *dest_port );
-
-       /* Construct source address */
-       efi_pxe_ip_sockaddr ( pxe, ( src_ip ? src_ip : &mode->StationIp ),
-                             &src.sa );
-       if ( src_port &&
-            ( ! ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT ) ) ) {
-               src.st.st_port = htons ( *src_port );
-       } else {
-               /* The API does not allow for a sensible concept of
-                * binding to a local port, so just use a random value.
-                */
-               src.st.st_port = ( random() | htons ( 1024 ) );
-               if ( src_port )
-                       *src_port = ntohs ( src.st.st_port );
-       }
-
-       /* Allocate I/O buffer */
-       iobuf = xfer_alloc_iob ( &pxe->udp,
-                                ( *len + ( hdr_len ? *hdr_len : 0 ) ) );
-       if ( ! iobuf ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-
-       /* Populate I/O buffer */
-       if ( hdr_len )
-               memcpy ( iob_put ( iobuf, *hdr_len ), hdr, *hdr_len );
-       memcpy ( iob_put ( iobuf, *len ), data, *len );
-
-       /* Construct metadata */
-       memset ( &meta, 0, sizeof ( meta ) );
-       meta.src = &src.sa;
-       meta.dest = &dest.sa;
-       meta.netdev = pxe->netdev;
-
-       /* Deliver I/O buffer */
-       if ( ( rc = xfer_deliver ( &pxe->udp, iob_disown ( iobuf ),
-                                  &meta ) ) != 0 ) {
-               DBGC ( pxe, "PXE %s could not transmit: %s\n",
-                      pxe->name, strerror ( rc ) );
-               goto err_deliver;
-       }
-
- err_deliver:
-       free_iob ( iobuf );
- err_alloc:
-       efi_pxe_udp_schedule_close ( pxe );
- err_open:
-       return EFIRC ( rc );
-}
-
-/**
- * Receive UDP packet
- *
- * @v base             PXE base code protocol
- * @v flags            Operation flags
- * @v dest_ip          Destination address
- * @v dest_port                Destination port
- * @v src_ip           Source address
- * @v src_port         Source port
- * @v hdr_len          Header length
- * @v hdr              Header data
- * @v len              Length
- * @v data             Data
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_pxe_udp_read ( EFI_PXE_BASE_CODE_PROTOCOL *base, UINT16 flags,
-                  EFI_IP_ADDRESS *dest_ip,
-                  EFI_PXE_BASE_CODE_UDP_PORT *dest_port,
-                  EFI_IP_ADDRESS *src_ip,
-                  EFI_PXE_BASE_CODE_UDP_PORT *src_port,
-                  UINTN *hdr_len, VOID *hdr, UINTN *len, VOID *data ) {
-       struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
-       struct io_buffer *iobuf;
-       struct efi_pxe_udp_pseudo_header *pshdr;
-       EFI_IP_ADDRESS *actual_dest_ip;
-       EFI_IP_ADDRESS *actual_src_ip;
-       size_t addr_len;
-       size_t frag_len;
-       int rc;
-
-       DBGC2 ( pxe, "PXE %s UDP READ ", pxe->name );
-       if ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER ) {
-               DBGC2 ( pxe, "(filter)" );
-       } else if ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP ) {
-               DBGC2 ( pxe, "*" );
-       } else if ( dest_ip ) {
-               DBGC2 ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, dest_ip ) );
-       }
-       DBGC2 ( pxe, ":" );
-       if ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT ) {
-               DBGC2 ( pxe, "*" );
-       } else if ( dest_port ) {
-               DBGC2 ( pxe, "%d", *dest_port );
-       } else {
-               DBGC2 ( pxe, "<NULL>" );
-       }
-       DBGC2 ( pxe, "<-" );
-       if ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP ) {
-               DBGC2 ( pxe, "*" );
-       } else if ( src_ip ) {
-               DBGC2 ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, src_ip ) );
-       } else {
-               DBGC2 ( pxe, "<NULL>" );
-       }
-       DBGC2 ( pxe, ":" );
-       if ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT ) {
-               DBGC2 ( pxe, "*" );
-       } else if ( src_port ) {
-               DBGC2 ( pxe, "%d", *src_port );
-       } else {
-               DBGC2 ( pxe, "<NULL>" );
-       }
-       if ( hdr_len )
-               DBGC2 ( pxe, " %p+%zx", hdr, ( ( size_t ) *hdr_len ) );
-       DBGC2 ( pxe, " %p+%zx\n", data, ( ( size_t ) *len ) );
-
-       /* Open UDP connection (if applicable) */
-       if ( ( rc = efi_pxe_udp_open ( pxe ) ) != 0 )
-               goto err_open;
-
-       /* Try receiving a packet, if the queue is empty */
-       if ( list_empty ( &pxe->queue ) )
-               step();
-
-       /* Remove first packet from the queue */
-       iobuf = list_first_entry ( &pxe->queue, struct io_buffer, list );
-       if ( ! iobuf ) {
-               rc = -ETIMEDOUT; /* "no packet" */
-               goto err_empty;
-       }
-       list_del ( &iobuf->list );
-
-       /* Strip pseudo-header */
-       pshdr = iobuf->data;
-       addr_len = ( pshdr->net->net_addr_len );
-       iob_pull ( iobuf, sizeof ( *pshdr ) );
-       actual_dest_ip = iobuf->data;
-       iob_pull ( iobuf, addr_len );
-       actual_src_ip = iobuf->data;
-       iob_pull ( iobuf, addr_len );
-       DBGC2 ( pxe, "PXE %s UDP RX %s:%d", pxe->name,
-               pshdr->net->ntoa ( actual_dest_ip ), pshdr->dest_port );
-       DBGC2 ( pxe, "<-%s:%d len %#zx\n", pshdr->net->ntoa ( actual_src_ip ),
-               pshdr->src_port, iob_len ( iobuf ) );
-
-       /* Filter based on network-layer protocol */
-       if ( pshdr->net != pxe->net ) {
-               DBGC2 ( pxe, "PXE %s filtered out %s packet\n",
-                       pxe->name, pshdr->net->name );
-               rc = -ETIMEDOUT; /* "no packet" */
-               goto err_filter;
-       }
-
-       /* Filter based on port numbers */
-       if ( ! ( ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT ) ||
-                ( dest_port && ( *dest_port == pshdr->dest_port ) ) ) ) {
-               DBGC2 ( pxe, "PXE %s filtered out destination port %d\n",
-                       pxe->name, pshdr->dest_port );
-               rc = -ETIMEDOUT; /* "no packet" */
-               goto err_filter;
-       }
-       if ( ! ( ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT ) ||
-                ( src_port && ( *src_port == pshdr->src_port ) ) ) ) {
-               DBGC2 ( pxe, "PXE %s filtered out source port %d\n",
-                       pxe->name, pshdr->src_port );
-               rc = -ETIMEDOUT; /* "no packet" */
-               goto err_filter;
-       }
-
-       /* Filter based on source IP address */
-       if ( ! ( ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP ) ||
-                ( src_ip &&
-                  ( memcmp ( src_ip, actual_src_ip, addr_len ) == 0 ) ) ) ) {
-               DBGC2 ( pxe, "PXE %s filtered out source IP %s\n",
-                       pxe->name, pshdr->net->ntoa ( actual_src_ip ) );
-               rc = -ETIMEDOUT; /* "no packet" */
-               goto err_filter;
-       }
-
-       /* Filter based on destination IP address */
-       if ( ! ( ( ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER ) &&
-                  efi_pxe_ip_filter ( pxe, actual_dest_ip ) ) ||
-                ( ( ! ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER ) ) &&
-                  ( ( flags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP ) ||
-                       ( dest_ip && ( memcmp ( dest_ip, actual_dest_ip,
-                                               addr_len ) == 0 ) ) ) ) ) ) {
-               DBGC2 ( pxe, "PXE %s filtered out destination IP %s\n",
-                       pxe->name, pshdr->net->ntoa ( actual_dest_ip ) );
-               rc = -ETIMEDOUT; /* "no packet" */
-               goto err_filter;
-       }
-
-       /* Fill in addresses and port numbers */
-       if ( dest_ip )
-               memcpy ( dest_ip, actual_dest_ip, addr_len );
-       if ( dest_port )
-               *dest_port = pshdr->dest_port;
-       if ( src_ip )
-               memcpy ( src_ip, actual_src_ip, addr_len );
-       if ( src_port )
-               *src_port = pshdr->src_port;
-
-       /* Fill in header, if applicable */
-       if ( hdr_len ) {
-               frag_len = iob_len ( iobuf );
-               if ( frag_len > *hdr_len )
-                       frag_len = *hdr_len;
-               memcpy ( hdr, iobuf->data, frag_len );
-               iob_pull ( iobuf, frag_len );
-               *hdr_len = frag_len;
-       }
-
-       /* Fill in data buffer */
-       frag_len = iob_len ( iobuf );
-       if ( frag_len > *len )
-               frag_len = *len;
-       memcpy ( data, iobuf->data, frag_len );
-       iob_pull ( iobuf, frag_len );
-       *len = frag_len;
-
-       /* Check for overflow */
-       if ( iob_len ( iobuf ) ) {
-               rc = -ERANGE;
-               goto err_too_short;
-       }
-
-       /* Success */
-       rc = 0;
-
- err_too_short:
- err_filter:
-       free_iob ( iobuf );
- err_empty:
-       efi_pxe_udp_schedule_close ( pxe );
- err_open:
-       return EFIRC ( rc );
-}
-
-/**
- * Set receive filter
- *
- * @v base             PXE base code protocol
- * @v filter           Receive filter
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_pxe_set_ip_filter ( EFI_PXE_BASE_CODE_PROTOCOL *base,
-                       EFI_PXE_BASE_CODE_IP_FILTER *filter ) {
-       struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
-       EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
-       unsigned int i;
-
-       DBGC ( pxe, "PXE %s SET IP FILTER %02x",
-              pxe->name, filter->Filters );
-       for ( i = 0 ; i < filter->IpCnt ; i++ ) {
-               DBGC ( pxe, " %s",
-                      efi_pxe_ip_ntoa ( pxe, &filter->IpList[i] ) );
-       }
-       DBGC ( pxe, "\n" );
-
-       /* Update filter */
-       memcpy ( &mode->IpFilter, filter, sizeof ( mode->IpFilter ) );
-
-       return 0;
-}
-
-/**
- * Resolve MAC address
- *
- * @v base             PXE base code protocol
- * @v ip               IP address
- * @v mac              MAC address to fill in
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI efi_pxe_arp ( EFI_PXE_BASE_CODE_PROTOCOL *base,
-                                      EFI_IP_ADDRESS *ip,
-                                      EFI_MAC_ADDRESS *mac ) {
-       struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
-
-       DBGC ( pxe, "PXE %s ARP %s %p\n",
-              pxe->name, efi_pxe_ip_ntoa ( pxe, ip ), mac );
-
-       /* Not used by any bootstrap I can find to test with */
-       return EFI_UNSUPPORTED;
-}
-
-/**
- * Set parameters
- *
- * @v base             PXE base code protocol
- * @v autoarp          Automatic ARP packet generation
- * @v sendguid         Send GUID as client hardware address
- * @v ttl              IP time to live
- * @v tos              IP type of service
- * @v callback         Make callbacks
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_pxe_set_parameters ( EFI_PXE_BASE_CODE_PROTOCOL *base,
-                        BOOLEAN *autoarp, BOOLEAN *sendguid, UINT8 *ttl,
-                        UINT8 *tos, BOOLEAN *callback ) {
-       struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
-       EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
-
-       DBGC ( pxe, "PXE %s SET PARAMETERS", pxe->name );
-       if ( autoarp )
-               DBGC ( pxe, " %s", ( *autoarp ? "autoarp" : "noautoarp" ) );
-       if ( sendguid )
-               DBGC ( pxe, " %s", ( *sendguid ? "sendguid" : "sendmac" ) );
-       if ( ttl )
-               DBGC ( pxe, " ttl %d", *ttl );
-       if ( tos )
-               DBGC ( pxe, " tos %d", *tos );
-       if ( callback ) {
-               DBGC ( pxe, " %s",
-                      ( *callback ? "callback" : "nocallback" ) );
-       }
-       DBGC ( pxe, "\n" );
-
-       /* Update parameters */
-       if ( autoarp )
-               mode->AutoArp = *autoarp;
-       if ( sendguid )
-               mode->SendGUID = *sendguid;
-       if ( ttl )
-               mode->TTL = *ttl;
-       if ( tos )
-               mode->ToS = *tos;
-       if ( callback )
-               mode->MakeCallbacks = *callback;
-
-       return 0;
-}
-
-/**
- * Set IP address
- *
- * @v base             PXE base code protocol
- * @v ip               IP address
- * @v netmask          Subnet mask
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_pxe_set_station_ip ( EFI_PXE_BASE_CODE_PROTOCOL *base,
-                        EFI_IP_ADDRESS *ip, EFI_IP_ADDRESS *netmask ) {
-       struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
-       EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
-
-       DBGC ( pxe, "PXE %s SET STATION IP ", pxe->name );
-       if ( ip )
-               DBGC ( pxe, "%s", efi_pxe_ip_ntoa ( pxe, ip ) );
-       if ( netmask )
-               DBGC ( pxe, "/%s", efi_pxe_ip_ntoa ( pxe, netmask ) );
-       DBGC ( pxe, "\n" );
-
-       /* Update IP address and netmask */
-       if ( ip )
-               memcpy ( &mode->StationIp, ip, sizeof ( mode->StationIp ) );
-       if ( netmask )
-               memcpy ( &mode->SubnetMask, netmask, sizeof (mode->SubnetMask));
-
-       return 0;
-}
-
-/**
- * Update cached DHCP packets
- *
- * @v base             PXE base code protocol
- * @v dhcpdisc_ok      DHCPDISCOVER is valid
- * @v dhcpack_ok       DHCPACK received
- * @v proxyoffer_ok    ProxyDHCPOFFER received
- * @v pxebsdisc_ok     PxeBsDISCOVER valid
- * @v pxebsack_ok      PxeBsACK received
- * @v pxebsbis_ok      PxeBsBIS received
- * @v dhcpdisc         DHCPDISCOVER packet
- * @v dhcpack          DHCPACK packet
- * @v proxyoffer       ProxyDHCPOFFER packet
- * @v pxebsdisc                PxeBsDISCOVER packet
- * @v pxebsack         PxeBsACK packet
- * @v pxebsbis         PxeBsBIS packet
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_pxe_set_packets ( EFI_PXE_BASE_CODE_PROTOCOL *base, BOOLEAN *dhcpdisc_ok,
-                     BOOLEAN *dhcpack_ok, BOOLEAN *proxyoffer_ok,
-                     BOOLEAN *pxebsdisc_ok, BOOLEAN *pxebsack_ok,
-                     BOOLEAN *pxebsbis_ok, EFI_PXE_BASE_CODE_PACKET *dhcpdisc,
-                     EFI_PXE_BASE_CODE_PACKET *dhcpack,
-                     EFI_PXE_BASE_CODE_PACKET *proxyoffer,
-                     EFI_PXE_BASE_CODE_PACKET *pxebsdisc,
-                     EFI_PXE_BASE_CODE_PACKET *pxebsack,
-                     EFI_PXE_BASE_CODE_PACKET *pxebsbis ) {
-       struct efi_pxe *pxe = container_of ( base, struct efi_pxe, base );
-       EFI_PXE_BASE_CODE_MODE *mode = &pxe->mode;
-
-       DBGC ( pxe, "PXE %s SET PACKETS\n", pxe->name );
-
-       /* Update fake packet flags */
-       if ( dhcpdisc_ok )
-               mode->DhcpDiscoverValid = *dhcpdisc_ok;
-       if ( dhcpack_ok )
-               mode->DhcpAckReceived = *dhcpack_ok;
-       if ( proxyoffer_ok )
-               mode->ProxyOfferReceived = *proxyoffer_ok;
-       if ( pxebsdisc_ok )
-               mode->PxeDiscoverValid = *pxebsdisc_ok;
-       if ( pxebsack_ok )
-               mode->PxeReplyReceived = *pxebsack_ok;
-       if ( pxebsbis_ok )
-               mode->PxeBisReplyReceived = *pxebsbis_ok;
-
-       /* Update fake packet contents */
-       if ( dhcpdisc )
-               memcpy ( &mode->DhcpDiscover, dhcpdisc, sizeof ( *dhcpdisc ) );
-       if ( dhcpack )
-               memcpy ( &mode->DhcpAck, dhcpack, sizeof ( *dhcpack ) );
-       if ( proxyoffer )
-               memcpy ( &mode->ProxyOffer, proxyoffer, sizeof ( *proxyoffer ));
-       if ( pxebsdisc )
-               memcpy ( &mode->PxeDiscover, pxebsdisc, sizeof ( *pxebsdisc ) );
-       if ( pxebsack )
-               memcpy ( &mode->PxeReply, pxebsack, sizeof ( *pxebsack ) );
-       if ( pxebsbis )
-               memcpy ( &mode->PxeBisReply, pxebsbis, sizeof ( *pxebsbis ) );
-
-       return 0;
-}
-
-/** PXE base code protocol */
-static EFI_PXE_BASE_CODE_PROTOCOL efi_pxe_base_code_protocol = {
-       .Revision       = EFI_PXE_BASE_CODE_PROTOCOL_REVISION,
-       .Start          = efi_pxe_start,
-       .Stop           = efi_pxe_stop,
-       .Dhcp           = efi_pxe_dhcp,
-       .Discover       = efi_pxe_discover,
-       .Mtftp          = efi_pxe_mtftp,
-       .UdpWrite       = efi_pxe_udp_write,
-       .UdpRead        = efi_pxe_udp_read,
-       .SetIpFilter    = efi_pxe_set_ip_filter,
-       .Arp            = efi_pxe_arp,
-       .SetParameters  = efi_pxe_set_parameters,
-       .SetStationIp   = efi_pxe_set_station_ip,
-       .SetPackets     = efi_pxe_set_packets,
-};
-
-/******************************************************************************
- *
- * Apple NetBoot protocol
- *
- ******************************************************************************
- */
-
-/**
- * Get DHCP/BSDP response
- *
- * @v packet           Packet
- * @v len              Length of data buffer
- * @v data             Data buffer
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_apple_get_response ( EFI_PXE_BASE_CODE_PACKET *packet, UINTN *len,
-                        VOID *data ) {
-
-       /* Check length */
-       if ( *len < sizeof ( *packet ) ) {
-               *len = sizeof ( *packet );
-               return EFI_BUFFER_TOO_SMALL;
-       }
-
-       /* Copy packet */
-       memcpy ( data, packet, sizeof ( *packet ) );
-       *len = sizeof ( *packet );
-
-       return EFI_SUCCESS;
-}
-
-/**
- * Get DHCP response
- *
- * @v apple            Apple NetBoot protocol
- * @v len              Length of data buffer
- * @v data             Data buffer
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_apple_get_dhcp_response ( EFI_APPLE_NET_BOOT_PROTOCOL *apple,
-                             UINTN *len, VOID *data ) {
-       struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
-
-       return efi_apple_get_response ( &pxe->mode.DhcpAck, len, data );
-}
-
-/**
- * Get BSDP response
- *
- * @v apple            Apple NetBoot protocol
- * @v len              Length of data buffer
- * @v data             Data buffer
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_apple_get_bsdp_response ( EFI_APPLE_NET_BOOT_PROTOCOL *apple,
-                             UINTN *len, VOID *data ) {
-       struct efi_pxe *pxe = container_of ( apple, struct efi_pxe, apple );
-
-       return efi_apple_get_response ( &pxe->mode.PxeReply, len, data );
-}
-
-/** Apple NetBoot protocol */
-static EFI_APPLE_NET_BOOT_PROTOCOL efi_apple_net_boot_protocol = {
-       .GetDhcpResponse = efi_apple_get_dhcp_response,
-       .GetBsdpResponse = efi_apple_get_bsdp_response,
-};
-
-/******************************************************************************
- *
- * Installer
- *
- ******************************************************************************
- */
-
-/**
- * Install PXE base code protocol
- *
- * @v handle           EFI handle
- * @v netdev           Underlying network device
- * @ret rc             Return status code
- */
-int efi_pxe_install ( EFI_HANDLE handle, struct net_device *netdev ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       struct tcpip_net_protocol *ipv6 = tcpip_net_protocol ( AF_INET6 );
-       struct efi_pxe *pxe;
-       struct in_addr ip;
-       BOOLEAN use_ipv6;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Allocate and initialise structure */
-       pxe = zalloc ( sizeof ( *pxe ) );
-       if ( ! pxe ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       ref_init ( &pxe->refcnt, efi_pxe_free );
-       pxe->netdev = netdev_get ( netdev );
-       pxe->name = netdev->name;
-       pxe->handle = handle;
-       memcpy ( &pxe->base, &efi_pxe_base_code_protocol, sizeof ( pxe->base ));
-       pxe->base.Mode = &pxe->mode;
-       memcpy ( &pxe->apple, &efi_apple_net_boot_protocol,
-                sizeof ( pxe->apple ) );
-       pxe->buf.op = &efi_pxe_buf_operations;
-       intf_init ( &pxe->tftp, &efi_pxe_tftp_desc, &pxe->refcnt );
-       intf_init ( &pxe->udp, &efi_pxe_udp_desc, &pxe->refcnt );
-       INIT_LIST_HEAD ( &pxe->queue );
-       process_init_stopped ( &pxe->process, &efi_pxe_process_desc,
-                              &pxe->refcnt );
-
-       /* Crude heuristic: assume that we prefer to use IPv4 if we
-        * have an IPv4 address for the network device, otherwise
-        * prefer IPv6 (if available).
-        */
-       fetch_ipv4_setting ( netdev_settings ( netdev ), &ip_setting, &ip );
-       use_ipv6 = ( ip.s_addr ? FALSE : ( ipv6 != NULL ) );
-
-       /* Start base code */
-       efi_pxe_start ( &pxe->base, use_ipv6 );
-
-       /* Install PXE base code protocol */
-       if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
-                       &handle,
-                       &efi_pxe_base_code_protocol_guid, &pxe->base,
-                       &efi_apple_net_boot_protocol_guid, &pxe->apple,
-                       NULL ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( pxe, "PXE %s could not install base code protocol: %s\n",
-                      pxe->name, strerror ( rc ) );
-               goto err_install_protocol;
-       }
-
-       /* Transfer reference to list and return */
-       list_add_tail ( &pxe->list, &efi_pxes );
-       DBGC ( pxe, "PXE %s installed for %s\n",
-              pxe->name, efi_handle_name ( handle ) );
-       return 0;
-
-       bs->UninstallMultipleProtocolInterfaces (
-                       handle,
-                       &efi_pxe_base_code_protocol_guid, &pxe->base,
-                       &efi_apple_net_boot_protocol_guid, &pxe->apple,
-                       NULL );
- err_install_protocol:
-       ref_put ( &pxe->refcnt );
- err_alloc:
-       return rc;
-}
-
-/**
- * Uninstall PXE base code protocol
- *
- * @v handle           EFI handle
- */
-void efi_pxe_uninstall ( EFI_HANDLE handle ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       struct efi_pxe *pxe;
-
-       /* Locate PXE base code */
-       pxe = efi_pxe_find ( handle );
-       if ( ! handle ) {
-               DBG ( "PXE could not find base code for %s\n",
-                     efi_handle_name ( handle ) );
-               return;
-       }
-
-       /* Stop base code */
-       efi_pxe_stop ( &pxe->base );
-
-       /* Uninstall PXE base code protocol */
-       bs->UninstallMultipleProtocolInterfaces (
-                       handle,
-                       &efi_pxe_base_code_protocol_guid, &pxe->base,
-                       &efi_apple_net_boot_protocol_guid, &pxe->apple,
-                       NULL );
-
-       /* Remove from list and drop list's reference */
-       list_del ( &pxe->list );
-       ref_put ( &pxe->refcnt );
-}
index e6388bf..3dfcc5e 100644 (file)
@@ -25,11 +25,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <assert.h>
 #include <byteswap.h>
 #include <ipxe/netdevice.h>
-#include <ipxe/vlan.h>
 #include <ipxe/iobuf.h>
 #include <ipxe/in.h>
 #include <ipxe/version.h>
-#include <ipxe/console.h>
 #include <ipxe/efi/efi.h>
 #include <ipxe/efi/efi_driver.h>
 #include <ipxe/efi/efi_strings.h>
@@ -185,7 +183,7 @@ efi_snp_start ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
        struct efi_snp_device *snpdev =
                container_of ( snp, struct efi_snp_device, snp );
 
-       DBGC ( snpdev, "SNPDEV %p START\n", snpdev );
+       DBGC2 ( snpdev, "SNPDEV %p START\n", snpdev );
 
        /* Fail if net device is currently claimed for use by iPXE */
        if ( efi_snp_claimed )
@@ -207,7 +205,7 @@ efi_snp_stop ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
        struct efi_snp_device *snpdev =
                container_of ( snp, struct efi_snp_device, snp );
 
-       DBGC ( snpdev, "SNPDEV %p STOP\n", snpdev );
+       DBGC2 ( snpdev, "SNPDEV %p STOP\n", snpdev );
 
        /* Fail if net device is currently claimed for use by iPXE */
        if ( efi_snp_claimed )
@@ -215,7 +213,6 @@ efi_snp_stop ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
 
        snpdev->started = 0;
        efi_snp_set_state ( snpdev );
-
        return 0;
 }
 
@@ -234,9 +231,9 @@ efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
                container_of ( snp, struct efi_snp_device, snp );
        int rc;
 
-       DBGC ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
-              snpdev, ( ( unsigned long ) extra_rx_bufsize ),
-              ( ( unsigned long ) extra_tx_bufsize ) );
+       DBGC2 ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
+               snpdev, ( ( unsigned long ) extra_rx_bufsize ),
+               ( ( unsigned long ) extra_tx_bufsize ) );
 
        /* Fail if net device is currently claimed for use by iPXE */
        if ( efi_snp_claimed )
@@ -265,8 +262,8 @@ efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
                container_of ( snp, struct efi_snp_device, snp );
        int rc;
 
-       DBGC ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
-              snpdev, ( ext_verify ? "with" : "without" ) );
+       DBGC2 ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
+               snpdev, ( ext_verify ? "with" : "without" ) );
 
        /* Fail if net device is currently claimed for use by iPXE */
        if ( efi_snp_claimed )
@@ -297,7 +294,7 @@ efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
        struct efi_snp_device *snpdev =
                container_of ( snp, struct efi_snp_device, snp );
 
-       DBGC ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
+       DBGC2 ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
 
        /* Fail if net device is currently claimed for use by iPXE */
        if ( efi_snp_claimed )
@@ -329,21 +326,19 @@ efi_snp_receive_filters ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINT32 enable,
                container_of ( snp, struct efi_snp_device, snp );
        unsigned int i;
 
-       DBGC ( snpdev, "SNPDEV %p RECEIVE_FILTERS %08x&~%08x%s %ld mcast\n",
-              snpdev, enable, disable, ( mcast_reset ? " reset" : "" ),
-              ( ( unsigned long ) mcast_count ) );
+       DBGC2 ( snpdev, "SNPDEV %p RECEIVE_FILTERS %08x&~%08x%s %ld mcast\n",
+               snpdev, enable, disable, ( mcast_reset ? " reset" : "" ),
+               ( ( unsigned long ) mcast_count ) );
        for ( i = 0 ; i < mcast_count ; i++ ) {
                DBGC2_HDA ( snpdev, i, &mcast[i],
                            snpdev->netdev->ll_protocol->ll_addr_len );
        }
 
-       /* Lie through our teeth, otherwise MNP refuses to accept us.
-        *
-        * Return success even if the SNP device is currently claimed
-        * for use by iPXE, since otherwise Windows Deployment
-        * Services refuses to attempt to receive further packets via
-        * our EFI PXE Base Code protocol.
-        */
+       /* Fail if net device is currently claimed for use by iPXE */
+       if ( efi_snp_claimed )
+               return EFI_NOT_READY;
+
+       /* Lie through our teeth, otherwise MNP refuses to accept us */
        return 0;
 }
 
@@ -362,8 +357,8 @@ efi_snp_station_address ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
                container_of ( snp, struct efi_snp_device, snp );
        struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
 
-       DBGC ( snpdev, "SNPDEV %p STATION_ADDRESS %s\n", snpdev,
-              ( reset ? "reset" : ll_protocol->ntoa ( new ) ) );
+       DBGC2 ( snpdev, "SNPDEV %p STATION_ADDRESS %s\n", snpdev,
+               ( reset ? "reset" : ll_protocol->ntoa ( new ) ) );
 
        /* Fail if net device is currently claimed for use by iPXE */
        if ( efi_snp_claimed )
@@ -399,8 +394,8 @@ efi_snp_statistics ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
                container_of ( snp, struct efi_snp_device, snp );
        EFI_NETWORK_STATISTICS stats_buf;
 
-       DBGC ( snpdev, "SNPDEV %p STATISTICS%s", snpdev,
-              ( reset ? " reset" : "" ) );
+       DBGC2 ( snpdev, "SNPDEV %p STATISTICS%s", snpdev,
+               ( reset ? " reset" : "" ) );
 
        /* Fail if net device is currently claimed for use by iPXE */
        if ( efi_snp_claimed )
@@ -452,7 +447,7 @@ efi_snp_mcast_ip_to_mac ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ipv6,
 
        ip_str = ( ipv6 ? "(IPv6)" /* FIXME when we have inet6_ntoa() */ :
                   inet_ntoa ( *( ( struct in_addr * ) ip ) ) );
-       DBGC ( snpdev, "SNPDEV %p MCAST_IP_TO_MAC %s\n", snpdev, ip_str );
+       DBGC2 ( snpdev, "SNPDEV %p MCAST_IP_TO_MAC %s\n", snpdev, ip_str );
 
        /* Fail if net device is currently claimed for use by iPXE */
        if ( efi_snp_claimed )
@@ -485,9 +480,9 @@ efi_snp_nvdata ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN read,
        struct efi_snp_device *snpdev =
                container_of ( snp, struct efi_snp_device, snp );
 
-       DBGC ( snpdev, "SNPDEV %p NVDATA %s %lx+%lx\n", snpdev,
-              ( read ? "read" : "write" ), ( ( unsigned long ) offset ),
-              ( ( unsigned long ) len ) );
+       DBGC2 ( snpdev, "SNPDEV %p NVDATA %s %lx+%lx\n", snpdev,
+               ( read ? "read" : "write" ), ( ( unsigned long ) offset ),
+               ( ( unsigned long ) len ) );
        if ( ! read )
                DBGC2_HDA ( snpdev, offset, data, len );
 
@@ -807,608 +802,6 @@ static EFI_SIMPLE_NETWORK_PROTOCOL efi_snp_device_snp = {
 
 /******************************************************************************
  *
- * UNDI protocol
- *
- ******************************************************************************
- */
-
-/** Union type for command parameter blocks */
-typedef union {
-       PXE_CPB_STATION_ADDRESS station_address;
-       PXE_CPB_FILL_HEADER fill_header;
-       PXE_CPB_FILL_HEADER_FRAGMENTED fill_header_fragmented;
-       PXE_CPB_TRANSMIT transmit;
-       PXE_CPB_RECEIVE receive;
-} PXE_CPB_ANY;
-
-/** Union type for data blocks */
-typedef union {
-       PXE_DB_GET_INIT_INFO get_init_info;
-       PXE_DB_STATION_ADDRESS station_address;
-       PXE_DB_GET_STATUS get_status;
-       PXE_DB_RECEIVE receive;
-} PXE_DB_ANY;
-
-/**
- * Calculate UNDI byte checksum
- *
- * @v data             Data
- * @v len              Length of data
- * @ret sum            Checksum
- */
-static uint8_t efi_undi_checksum ( void *data, size_t len ) {
-       uint8_t *bytes = data;
-       uint8_t sum = 0;
-
-       while ( len-- )
-               sum += *bytes++;
-       return sum;
-}
-
-/**
- * Get UNDI SNP device interface number
- *
- * @v snpdev           SNP device
- * @ret ifnum          UNDI interface number
- */
-static unsigned int efi_undi_ifnum ( struct efi_snp_device *snpdev ) {
-
-       /* iPXE network device indexes are one-based (leaving zero
-        * meaning "unspecified").  UNDI interface numbers are
-        * zero-based.
-        */
-       return ( snpdev->netdev->index - 1 );
-}
-
-/**
- * Identify UNDI SNP device
- *
- * @v ifnum            Interface number
- * @ret snpdev         SNP device, or NULL if not found
- */
-static struct efi_snp_device * efi_undi_snpdev ( unsigned int ifnum ) {
-       struct efi_snp_device *snpdev;
-
-       list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
-               if ( efi_undi_ifnum ( snpdev ) == ifnum )
-                       return snpdev;
-       }
-       return NULL;
-}
-
-/**
- * Convert EFI status code to UNDI status code
- *
- * @v efirc            EFI status code
- * @ret statcode       UNDI status code
- */
-static PXE_STATCODE efi_undi_statcode ( EFI_STATUS efirc ) {
-
-       switch ( efirc ) {
-       case EFI_INVALID_PARAMETER:     return PXE_STATCODE_INVALID_PARAMETER;
-       case EFI_UNSUPPORTED:           return PXE_STATCODE_UNSUPPORTED;
-       case EFI_OUT_OF_RESOURCES:      return PXE_STATCODE_BUFFER_FULL;
-       case EFI_PROTOCOL_ERROR:        return PXE_STATCODE_DEVICE_FAILURE;
-       case EFI_NOT_READY:             return PXE_STATCODE_NO_DATA;
-       default:
-               return PXE_STATCODE_INVALID_CDB;
-       }
-}
-
-/**
- * Get state
- *
- * @v snpdev           SNP device
- * @v cdb              Command description block
- * @ret efirc          EFI status code
- */
-static EFI_STATUS efi_undi_get_state ( struct efi_snp_device *snpdev,
-                                      PXE_CDB *cdb ) {
-       EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
-
-       DBGC ( snpdev, "UNDI %p GET STATE\n", snpdev );
-
-       /* Return current state */
-       if ( mode->State == EfiSimpleNetworkInitialized ) {
-               cdb->StatFlags |= PXE_STATFLAGS_GET_STATE_INITIALIZED;
-       } else if ( mode->State == EfiSimpleNetworkStarted ) {
-               cdb->StatFlags |= PXE_STATFLAGS_GET_STATE_STARTED;
-       } else {
-               cdb->StatFlags |= PXE_STATFLAGS_GET_STATE_STOPPED;
-       }
-
-       return 0;
-}
-
-/**
- * Start
- *
- * @v snpdev           SNP device
- * @ret efirc          EFI status code
- */
-static EFI_STATUS efi_undi_start ( struct efi_snp_device *snpdev ) {
-       EFI_STATUS efirc;
-
-       DBGC ( snpdev, "UNDI %p START\n", snpdev );
-
-       /* Start SNP device */
-       if ( ( efirc = efi_snp_start ( &snpdev->snp ) ) != 0 )
-               return efirc;
-
-       return 0;
-}
-
-/**
- * Stop
- *
- * @v snpdev           SNP device
- * @ret efirc          EFI status code
- */
-static EFI_STATUS efi_undi_stop ( struct efi_snp_device *snpdev ) {
-       EFI_STATUS efirc;
-
-       DBGC ( snpdev, "UNDI %p STOP\n", snpdev );
-
-       /* Stop SNP device */
-       if ( ( efirc = efi_snp_stop ( &snpdev->snp ) ) != 0 )
-               return efirc;
-
-       return 0;
-}
-
-/**
- * Get initialisation information
- *
- * @v snpdev           SNP device
- * @v cdb              Command description block
- * @v db               Data block
- * @ret efirc          EFI status code
- */
-static EFI_STATUS efi_undi_get_init_info ( struct efi_snp_device *snpdev,
-                                          PXE_CDB *cdb,
-                                          PXE_DB_GET_INIT_INFO *db ) {
-       struct net_device *netdev = snpdev->netdev;
-       struct ll_protocol *ll_protocol = netdev->ll_protocol;
-
-       DBGC ( snpdev, "UNDI %p GET INIT INFO\n", snpdev );
-
-       /* Populate structure */
-       memset ( db, 0, sizeof ( *db ) );
-       db->FrameDataLen = ( netdev->max_pkt_len - ll_protocol->ll_header_len );
-       db->MediaHeaderLen = ll_protocol->ll_header_len;
-       db->HWaddrLen = ll_protocol->ll_addr_len;
-       db->IFtype = ntohs ( ll_protocol->ll_proto );
-       cdb->StatFlags |= ( PXE_STATFLAGS_CABLE_DETECT_SUPPORTED |
-                           PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED );
-
-       return 0;
-}
-
-/**
- * Initialise
- *
- * @v snpdev           SNP device
- * @v cdb              Command description block
- * @v efirc            EFI status code
- */
-static EFI_STATUS efi_undi_initialize ( struct efi_snp_device *snpdev,
-                                       PXE_CDB *cdb ) {
-       struct net_device *netdev = snpdev->netdev;
-       EFI_STATUS efirc;
-
-       DBGC ( snpdev, "UNDI %p INITIALIZE\n", snpdev );
-
-       /* Reset SNP device */
-       if ( ( efirc = efi_snp_initialize ( &snpdev->snp, 0, 0 ) ) != 0 )
-               return efirc;
-
-       /* Report link state */
-       if ( ! netdev_link_ok ( netdev ) )
-               cdb->StatFlags |= PXE_STATFLAGS_INITIALIZED_NO_MEDIA;
-
-       return 0;
-}
-
-/**
- * Reset
- *
- * @v snpdev           SNP device
- * @v efirc            EFI status code
- */
-static EFI_STATUS efi_undi_reset ( struct efi_snp_device *snpdev ) {
-       EFI_STATUS efirc;
-
-       DBGC ( snpdev, "UNDI %p RESET\n", snpdev );
-
-       /* Reset SNP device */
-       if ( ( efirc = efi_snp_reset ( &snpdev->snp, 0 ) ) != 0 )
-               return efirc;
-
-       return 0;
-}
-
-/**
- * Shutdown
- *
- * @v snpdev           SNP device
- * @v efirc            EFI status code
- */
-static EFI_STATUS efi_undi_shutdown ( struct efi_snp_device *snpdev ) {
-       EFI_STATUS efirc;
-
-       DBGC ( snpdev, "UNDI %p SHUTDOWN\n", snpdev );
-
-       /* Reset SNP device */
-       if ( ( efirc = efi_snp_shutdown ( &snpdev->snp ) ) != 0 )
-               return efirc;
-
-       return 0;
-}
-
-/**
- * Get/set receive filters
- *
- * @v snpdev           SNP device
- * @v cdb              Command description block
- * @v efirc            EFI status code
- */
-static EFI_STATUS efi_undi_receive_filters ( struct efi_snp_device *snpdev,
-                                            PXE_CDB *cdb ) {
-
-       DBGC ( snpdev, "UNDI %p RECEIVE FILTERS\n", snpdev );
-
-       /* Mark everything as supported */
-       cdb->StatFlags |= ( PXE_STATFLAGS_RECEIVE_FILTER_UNICAST |
-                           PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST |
-                           PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS |
-                           PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST );
-
-       return 0;
-}
-
-/**
- * Get/set station address
- *
- * @v snpdev           SNP device
- * @v cdb              Command description block
- * @v cpb              Command parameter block
- * @v efirc            EFI status code
- */
-static EFI_STATUS efi_undi_station_address ( struct efi_snp_device *snpdev,
-                                            PXE_CDB *cdb,
-                                            PXE_CPB_STATION_ADDRESS *cpb,
-                                            PXE_DB_STATION_ADDRESS *db ) {
-       struct net_device *netdev = snpdev->netdev;
-       struct ll_protocol *ll_protocol = netdev->ll_protocol;
-       void *mac;
-       int reset;
-       EFI_STATUS efirc;
-
-       DBGC ( snpdev, "UNDI %p STATION ADDRESS\n", snpdev );
-
-       /* Update address if applicable */
-       reset = ( cdb->OpFlags & PXE_OPFLAGS_STATION_ADDRESS_RESET );
-       mac = ( cpb ? &cpb->StationAddr : NULL );
-       if ( ( reset || mac ) &&
-            ( ( efirc = efi_snp_station_address ( &snpdev->snp, reset,
-                                                  mac ) ) != 0 ) )
-               return efirc;
-
-       /* Fill in current addresses, if applicable */
-       if ( db ) {
-               memset ( db, 0, sizeof ( *db ) );
-               memcpy ( &db->StationAddr, netdev->ll_addr,
-                        ll_protocol->ll_addr_len );
-               memcpy ( &db->BroadcastAddr, netdev->ll_broadcast,
-                        ll_protocol->ll_addr_len );
-               memcpy ( &db->PermanentAddr, netdev->hw_addr,
-                        ll_protocol->hw_addr_len );
-       }
-
-       return 0;
-}
-
-/**
- * Get interrupt status
- *
- * @v snpdev           SNP device
- * @v cdb              Command description block
- * @v db               Data block
- * @v efirc            EFI status code
- */
-static EFI_STATUS efi_undi_get_status ( struct efi_snp_device *snpdev,
-                                       PXE_CDB *cdb, PXE_DB_GET_STATUS *db ) {
-       UINT32 interrupts;
-       VOID *txbuf;
-       struct io_buffer *rxbuf;
-       EFI_STATUS efirc;
-
-       DBGC2 ( snpdev, "UNDI %p GET STATUS\n", snpdev );
-
-       /* Get status */
-       if ( ( efirc = efi_snp_get_status ( &snpdev->snp, &interrupts,
-                                           &txbuf ) ) != 0 )
-               return efirc;
-
-       /* Report status */
-       memset ( db, 0, sizeof ( *db ) );
-       if ( interrupts & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT )
-               cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_RECEIVE;
-       if ( interrupts & EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT )
-               cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_TRANSMIT;
-       if ( txbuf ) {
-               db->TxBuffer[0] = ( ( intptr_t ) txbuf );
-       } else {
-               cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN;
-               /* The specification states clearly that UNDI drivers
-                * should set TXBUF_QUEUE_EMPTY if all completed
-                * buffer addresses are written into the returned data
-                * block.  However, SnpDxe chooses to interpret
-                * TXBUF_QUEUE_EMPTY as a synonym for
-                * NO_TXBUFS_WRITTEN, thereby rendering it entirely
-                * pointless.  Work around this UEFI stupidity, as per
-                * usual.
-                */
-               if ( snpdev->tx_prod == snpdev->tx_cons )
-                       cdb->StatFlags |=
-                               PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY;
-       }
-       rxbuf = list_first_entry ( &snpdev->rx, struct io_buffer, list );
-       if ( rxbuf )
-               db->RxFrameLen = iob_len ( rxbuf );
-       if ( ! netdev_link_ok ( snpdev->netdev ) )
-               cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_NO_MEDIA;
-
-       return 0;
-}
-
-/**
- * Fill header
- *
- * @v snpdev           SNP device
- * @v cdb              Command description block
- * @v cpb              Command parameter block
- * @v efirc            EFI status code
- */
-static EFI_STATUS efi_undi_fill_header ( struct efi_snp_device *snpdev,
-                                        PXE_CDB *cdb, PXE_CPB_ANY *cpb ) {
-       struct net_device *netdev = snpdev->netdev;
-       struct ll_protocol *ll_protocol = netdev->ll_protocol;
-       PXE_CPB_FILL_HEADER *whole = &cpb->fill_header;
-       PXE_CPB_FILL_HEADER_FRAGMENTED *fragged = &cpb->fill_header_fragmented;
-       VOID *data;
-       void *dest;
-       void *src;
-       uint16_t proto;
-       struct io_buffer iobuf;
-       int rc;
-
-       /* SnpDxe will (pointlessly) use PXE_CPB_FILL_HEADER_FRAGMENTED
-        * even though we choose to explicitly not claim support for
-        * fragments via PXE_ROMID_IMP_FRAG_SUPPORTED.
-        */
-       if ( cdb->OpFlags & PXE_OPFLAGS_FILL_HEADER_FRAGMENTED ) {
-               data = ( ( void * ) ( intptr_t ) fragged->FragDesc[0].FragAddr);
-               dest = &fragged->DestAddr;
-               src = &fragged->SrcAddr;
-               proto = fragged->Protocol;
-       } else {
-               data = ( ( void * ) ( intptr_t ) whole->MediaHeader );
-               dest = &whole->DestAddr;
-               src = &whole->SrcAddr;
-               proto = whole->Protocol;
-       }
-
-       /* Construct link-layer header */
-       iob_populate ( &iobuf, data, 0, ll_protocol->ll_header_len );
-       iob_reserve ( &iobuf, ll_protocol->ll_header_len );
-       if ( ( rc = ll_protocol->push ( netdev, &iobuf, dest, src,
-                                       proto ) ) != 0 )
-               return EFIRC ( rc );
-
-       return 0;
-}
-
-/**
- * Transmit
- *
- * @v snpdev           SNP device
- * @v cpb              Command parameter block
- * @v efirc            EFI status code
- */
-static EFI_STATUS efi_undi_transmit ( struct efi_snp_device *snpdev,
-                                     PXE_CPB_TRANSMIT *cpb ) {
-       VOID *data = ( ( void * ) ( intptr_t ) cpb->FrameAddr );
-       EFI_STATUS efirc;
-
-       DBGC2 ( snpdev, "UNDI %p TRANSMIT\n", snpdev );
-
-       /* Transmit packet */
-       if ( ( efirc = efi_snp_transmit ( &snpdev->snp, 0, cpb->DataLen,
-                                         data, NULL, NULL, NULL ) ) != 0 )
-               return efirc;
-
-       return 0;
-}
-
-/**
- * Receive
- *
- * @v snpdev           SNP device
- * @v cpb              Command parameter block
- * @v efirc            EFI status code
- */
-static EFI_STATUS efi_undi_receive ( struct efi_snp_device *snpdev,
-                                    PXE_CPB_RECEIVE *cpb,
-                                    PXE_DB_RECEIVE *db ) {
-       struct net_device *netdev = snpdev->netdev;
-       struct ll_protocol *ll_protocol = netdev->ll_protocol;
-       VOID *data = ( ( void * ) ( intptr_t ) cpb->BufferAddr );
-       UINTN hdr_len;
-       UINTN len = cpb->BufferLen;
-       EFI_MAC_ADDRESS src;
-       EFI_MAC_ADDRESS dest;
-       UINT16 proto;
-       EFI_STATUS efirc;
-
-       DBGC2 ( snpdev, "UNDI %p RECEIVE\n", snpdev );
-
-       /* Receive packet */
-       if ( ( efirc = efi_snp_receive ( &snpdev->snp, &hdr_len, &len, data,
-                                        &src, &dest, &proto ) ) != 0 )
-               return efirc;
-
-       /* Describe frame */
-       memset ( db, 0, sizeof ( *db ) );
-       memcpy ( &db->SrcAddr, &src, ll_protocol->ll_addr_len );
-       memcpy ( &db->DestAddr, &dest, ll_protocol->ll_addr_len );
-       db->FrameLen = len;
-       db->Protocol = proto;
-       db->MediaHeaderLen = ll_protocol->ll_header_len;
-       db->Type = PXE_FRAME_TYPE_PROMISCUOUS;
-
-       return 0;
-}
-
-/** UNDI entry point */
-static EFIAPI VOID efi_undi_issue ( UINT64 cdb_phys ) {
-       PXE_CDB *cdb = ( ( void * ) ( intptr_t ) cdb_phys );
-       PXE_CPB_ANY *cpb = ( ( void * ) ( intptr_t ) cdb->CPBaddr );
-       PXE_DB_ANY *db = ( ( void * ) ( intptr_t ) cdb->DBaddr );
-       struct efi_snp_device *snpdev;
-       EFI_STATUS efirc;
-
-       /* Identify device */
-       snpdev = efi_undi_snpdev ( cdb->IFnum );
-       if ( ! snpdev ) {
-               DBGC ( cdb, "UNDI invalid interface number %d\n", cdb->IFnum );
-               cdb->StatCode = PXE_STATCODE_INVALID_CDB;
-               cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
-               return;
-       }
-
-       /* Fail if net device is currently claimed for use by iPXE */
-       if ( efi_snp_claimed ) {
-               cdb->StatCode = PXE_STATCODE_BUSY;
-               cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
-               return;
-       }
-
-       /* Handle opcode */
-       cdb->StatCode = PXE_STATCODE_SUCCESS;
-       cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
-       switch ( cdb->OpCode ) {
-
-       case PXE_OPCODE_GET_STATE:
-               efirc = efi_undi_get_state ( snpdev, cdb );
-               break;
-
-       case PXE_OPCODE_START:
-               efirc = efi_undi_start ( snpdev );
-               break;
-
-       case PXE_OPCODE_STOP:
-               efirc = efi_undi_stop ( snpdev );
-               break;
-
-       case PXE_OPCODE_GET_INIT_INFO:
-               efirc = efi_undi_get_init_info ( snpdev, cdb,
-                                                &db->get_init_info );
-               break;
-
-       case PXE_OPCODE_INITIALIZE:
-               efirc = efi_undi_initialize ( snpdev, cdb );
-               break;
-
-       case PXE_OPCODE_RESET:
-               efirc = efi_undi_reset ( snpdev );
-               break;
-
-       case PXE_OPCODE_SHUTDOWN:
-               efirc = efi_undi_shutdown ( snpdev );
-               break;
-
-       case PXE_OPCODE_RECEIVE_FILTERS:
-               efirc = efi_undi_receive_filters ( snpdev, cdb );
-               break;
-
-       case PXE_OPCODE_STATION_ADDRESS:
-               efirc = efi_undi_station_address ( snpdev, cdb,
-                                                  &cpb->station_address,
-                                                  &db->station_address );
-               break;
-
-       case PXE_OPCODE_GET_STATUS:
-               efirc = efi_undi_get_status ( snpdev, cdb, &db->get_status );
-               break;
-
-       case PXE_OPCODE_FILL_HEADER:
-               efirc = efi_undi_fill_header ( snpdev, cdb, cpb );
-               break;
-
-       case PXE_OPCODE_TRANSMIT:
-               efirc = efi_undi_transmit ( snpdev, &cpb->transmit );
-               break;
-
-       case PXE_OPCODE_RECEIVE:
-               efirc = efi_undi_receive ( snpdev, &cpb->receive,
-                                          &db->receive );
-               break;
-
-       default:
-               DBGC ( snpdev, "UNDI %p unsupported opcode %#04x\n",
-                      snpdev, cdb->OpCode );
-               efirc = EFI_UNSUPPORTED;
-               break;
-       }
-
-       /* Convert EFI status code to UNDI status code */
-       if ( efirc != 0 ) {
-               cdb->StatFlags &= ~PXE_STATFLAGS_STATUS_MASK;
-               cdb->StatFlags |= PXE_STATFLAGS_COMMAND_FAILED;
-               cdb->StatCode = efi_undi_statcode ( efirc );
-       }
-}
-
-/** UNDI interface
- *
- * Must be aligned on a 16-byte boundary, for no particularly good
- * reason.
- */
-static PXE_SW_UNDI efi_snp_undi __attribute__ (( aligned ( 16 ) )) = {
-       .Signature      = PXE_ROMID_SIGNATURE,
-       .Len            = sizeof ( efi_snp_undi ),
-       .Rev            = PXE_ROMID_REV,
-       .MajorVer       = PXE_ROMID_MAJORVER,
-       .MinorVer       = PXE_ROMID_MINORVER,
-       .Implementation = ( PXE_ROMID_IMP_SW_VIRT_ADDR |
-                           PXE_ROMID_IMP_STATION_ADDR_SETTABLE |
-                           PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED |
-                           PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED |
-                           PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED |
-                           PXE_ROMID_IMP_TX_COMPLETE_INT_SUPPORTED |
-                           PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED ),
-       /* SnpDxe checks that BusCnt is non-zero.  It makes no further
-        * use of BusCnt, and never looks as BusType[].  As with much
-        * of the EDK2 code, this check seems to serve no purpose
-        * whatsoever but must nonetheless be humoured.
-        */
-       .BusCnt         = 1,
-       .BusType[0]     = PXE_BUSTYPE ( 'i', 'P', 'X', 'E' ),
-};
-
-/** Network Identification Interface (NII) */
-static EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL efi_snp_device_nii = {
-       .Revision       = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION,
-       .StringId       = "UNDI",
-       .Type           = EfiNetworkInterfaceUndi,
-       .MajorVer       = 3,
-       .MinorVer       = 1,
-       .Ipv6Supported  = TRUE, /* This is a raw packet interface, FFS! */
-};
-
-/******************************************************************************
- *
  * Component name protocol
  *
  ******************************************************************************
@@ -1497,9 +890,6 @@ efi_snp_load_file ( EFI_LOAD_FILE_PROTOCOL *load_file,
        if ( ( rc = ipxe ( netdev ) ) != 0 )
                goto err_ipxe;
 
-       /* Reset console */
-       console_reset();
-
  err_ipxe:
        efi_watchdog_stop();
        efi_snp_release();
@@ -1544,13 +934,13 @@ static int efi_snp_probe ( struct net_device *netdev ) {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        struct efi_device *efidev;
        struct efi_snp_device *snpdev;
+       union {
+               EFI_DEVICE_PATH_PROTOCOL *path;
+               void *interface;
+       } path;
        EFI_DEVICE_PATH_PROTOCOL *path_end;
        MAC_ADDR_DEVICE_PATH *macpath;
-       VLAN_DEVICE_PATH *vlanpath;
        size_t path_prefix_len = 0;
-       unsigned int ifcnt;
-       unsigned int tag;
-       void *interface;
        EFI_STATUS efirc;
        int rc;
 
@@ -1598,17 +988,10 @@ static int efi_snp_probe ( struct net_device *netdev ) {
        efi_snp_set_mode ( snpdev );
 
        /* Populate the NII structure */
-       memcpy ( &snpdev->nii, &efi_snp_device_nii, sizeof ( snpdev->nii ) );
-       snpdev->nii.Id = ( ( intptr_t ) &efi_snp_undi );
-       snpdev->nii.IfNum = efi_undi_ifnum ( snpdev );
-       efi_snp_undi.EntryPoint = ( ( intptr_t ) efi_undi_issue );
-       ifcnt = ( ( efi_snp_undi.IFcntExt << 8 ) | efi_snp_undi.IFcnt );
-       if ( ifcnt < snpdev->nii.IfNum )
-               ifcnt = snpdev->nii.IfNum;
-       efi_snp_undi.IFcnt = ( ifcnt & 0xff );
-       efi_snp_undi.IFcntExt = ( ifcnt >> 8 );
-       efi_snp_undi.Fudge -= efi_undi_checksum ( &efi_snp_undi,
-                                                 sizeof ( efi_snp_undi ) );
+       snpdev->nii.Revision =
+               EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION;
+       strncpy ( snpdev->nii.StringId, "iPXE",
+                 sizeof ( snpdev->nii.StringId ) );
 
        /* Populate the component name structure */
        efi_snprintf ( snpdev->driver_name,
@@ -1634,36 +1017,40 @@ static int efi_snp_probe ( struct net_device *netdev ) {
                                       sizeof ( snpdev->name[0] ) ),
                       "%s", netdev->name );
 
+       /* Get the parent device path */
+       if ( ( efirc = bs->OpenProtocol ( efidev->device,
+                                         &efi_device_path_protocol_guid,
+                                         &path.interface, efi_image_handle,
+                                         efidev->device,
+                                         EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
+               rc = -EEFI ( efirc );
+               DBGC ( snpdev, "SNPDEV %p cannot get %p %s device path: %s\n",
+                      snpdev, efidev->device,
+                      efi_handle_name ( efidev->device ), strerror ( rc ) );
+               goto err_open_device_path;
+       }
+
        /* Allocate the new device path */
-       path_prefix_len = efi_devpath_len ( efidev->path );
+       path_end = efi_devpath_end ( path.path );
+       path_prefix_len = ( ( ( void * ) path_end ) - ( ( void * ) path.path ));
        snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
-                               sizeof ( *vlanpath ) + sizeof ( *path_end ) );
+                               sizeof ( *path_end ) );
        if ( ! snpdev->path ) {
                rc = -ENOMEM;
                goto err_alloc_device_path;
        }
 
        /* Populate the device path */
-       memcpy ( snpdev->path, efidev->path, path_prefix_len );
+       memcpy ( snpdev->path, path.path, path_prefix_len );
        macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
+       path_end = ( ( void * ) ( macpath + 1 ) );
        memset ( macpath, 0, sizeof ( *macpath ) );
        macpath->Header.Type = MESSAGING_DEVICE_PATH;
        macpath->Header.SubType = MSG_MAC_ADDR_DP;
        macpath->Header.Length[0] = sizeof ( *macpath );
        memcpy ( &macpath->MacAddress, netdev->ll_addr,
-                netdev->ll_protocol->ll_addr_len );
+                sizeof ( macpath->MacAddress ) );
        macpath->IfType = ntohs ( netdev->ll_protocol->ll_proto );
-       if ( ( tag = vlan_tag ( netdev ) ) ) {
-               vlanpath = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
-               memset ( vlanpath, 0, sizeof ( *vlanpath ) );
-               vlanpath->Header.Type = MESSAGING_DEVICE_PATH;
-               vlanpath->Header.SubType = MSG_VLAN_DP;
-               vlanpath->Header.Length[0] = sizeof ( *vlanpath );
-               vlanpath->VlanId = tag;
-               path_end = ( ( ( void * ) vlanpath ) + sizeof ( *vlanpath ) );
-       } else {
-               path_end = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
-       }
        memset ( path_end, 0, sizeof ( *path_end ) );
        path_end->Type = END_DEVICE_PATH_TYPE;
        path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
@@ -1680,47 +1067,16 @@ static int efi_snp_probe ( struct net_device *netdev ) {
                        &efi_load_file_protocol_guid, &snpdev->load_file,
                        NULL ) ) != 0 ) {
                rc = -EEFI ( efirc );
-               DBGC ( snpdev, "SNPDEV %p could not install protocols: %s\n",
-                      snpdev, strerror ( rc ) );
+               DBGC ( snpdev, "SNPDEV %p could not install protocols: "
+                      "%s\n", snpdev, strerror ( rc ) );
                goto err_install_protocol_interface;
        }
 
-       /* SnpDxe will repeatedly start up and shut down our NII/UNDI
-        * interface (in order to obtain the MAC address) before
-        * discovering that it cannot install another SNP on the same
-        * handle.  This causes the underlying network device to be
-        * unexpectedly closed.
-        *
-        * Prevent this by opening our own NII (and NII31) protocol
-        * instances to prevent SnpDxe from attempting to bind to
-        * them.
-        */
-       if ( ( efirc = bs->OpenProtocol ( snpdev->handle,
-                                         &efi_nii_protocol_guid, &interface,
-                                         efi_image_handle, snpdev->handle,
-                                         ( EFI_OPEN_PROTOCOL_BY_DRIVER |
-                                           EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
-               rc = -EEFI ( efirc );
-               DBGC ( snpdev, "SNPDEV %p could not open NII protocol: %s\n",
-                      snpdev, strerror ( rc ) );
-               goto err_open_nii;
-       }
-       if ( ( efirc = bs->OpenProtocol ( snpdev->handle,
-                                         &efi_nii31_protocol_guid, &interface,
-                                         efi_image_handle, snpdev->handle,
-                                         ( EFI_OPEN_PROTOCOL_BY_DRIVER |
-                                           EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
-               rc = -EEFI ( efirc );
-               DBGC ( snpdev, "SNPDEV %p could not open NII31 protocol: %s\n",
-                      snpdev, strerror ( rc ) );
-               goto err_open_nii31;
-       }
-
        /* Add as child of EFI parent device */
        if ( ( rc = efi_child_add ( efidev->device, snpdev->handle ) ) != 0 ) {
-               DBGC ( snpdev, "SNPDEV %p could not become child of %s: %s\n",
-                      snpdev, efi_handle_name ( efidev->device ),
-                      strerror ( rc ) );
+               DBGC ( snpdev, "SNPDEV %p could not become child of %p %s: "
+                      "%s\n", snpdev, efidev->device,
+                      efi_handle_name ( efidev->device ), strerror ( rc ) );
                goto err_efi_child_add;
        }
 
@@ -1741,21 +1097,15 @@ static int efi_snp_probe ( struct net_device *netdev ) {
        bs->CloseProtocol ( efidev->device, &efi_device_path_protocol_guid,
                            efi_image_handle, efidev->device );
 
-       DBGC ( snpdev, "SNPDEV %p installed for %s as device %s\n",
-              snpdev, netdev->name, efi_handle_name ( snpdev->handle ) );
+       DBGC ( snpdev, "SNPDEV %p installed for %s as device %p %s\n",
+              snpdev, netdev->name, snpdev->handle,
+              efi_handle_name ( snpdev->handle ) );
        return 0;
 
-       list_del ( &snpdev->list );
        if ( snpdev->package_list )
                efi_snp_hii_uninstall ( snpdev );
        efi_child_del ( efidev->device, snpdev->handle );
  err_efi_child_add:
-       bs->CloseProtocol ( snpdev->handle, &efi_nii_protocol_guid,
-                           efi_image_handle, snpdev->handle );
- err_open_nii:
-       bs->CloseProtocol ( snpdev->handle, &efi_nii31_protocol_guid,
-                           efi_image_handle, snpdev->handle );
- err_open_nii31:
        bs->UninstallMultipleProtocolInterfaces (
                        snpdev->handle,
                        &efi_simple_network_protocol_guid, &snpdev->snp,
@@ -1768,6 +1118,9 @@ static int efi_snp_probe ( struct net_device *netdev ) {
  err_install_protocol_interface:
        free ( snpdev->path );
  err_alloc_device_path:
+       bs->CloseProtocol ( efidev->device, &efi_device_path_protocol_guid,
+                           efi_image_handle, efidev->device );
+ err_open_device_path:
        bs->CloseEvent ( snpdev->snp.WaitForPacket );
  err_create_event:
  err_ll_addr_len:
@@ -1820,14 +1173,10 @@ static void efi_snp_remove ( struct net_device *netdev ) {
        }
 
        /* Uninstall the SNP */
-       list_del ( &snpdev->list );
        if ( snpdev->package_list )
                efi_snp_hii_uninstall ( snpdev );
        efi_child_del ( snpdev->efidev->device, snpdev->handle );
-       bs->CloseProtocol ( snpdev->handle, &efi_nii_protocol_guid,
-                           efi_image_handle, snpdev->handle );
-       bs->CloseProtocol ( snpdev->handle, &efi_nii31_protocol_guid,
-                           efi_image_handle, snpdev->handle );
+       list_del ( &snpdev->list );
        bs->UninstallMultipleProtocolInterfaces (
                        snpdev->handle,
                        &efi_simple_network_protocol_guid, &snpdev->snp,
@@ -1883,16 +1232,15 @@ struct efi_snp_device * last_opened_snpdev ( void ) {
 }
 
 /**
- * Add to SNP claimed/released count
+ * Set SNP claimed/released state
  *
- * @v delta            Claim count change
+ * @v claimed          Network devices are claimed for use by iPXE
  */
-void efi_snp_add_claim ( int delta ) {
+void efi_snp_set_claimed ( int claimed ) {
        struct efi_snp_device *snpdev;
 
        /* Claim SNP devices */
-       efi_snp_claimed += delta;
-       assert ( efi_snp_claimed >= 0 );
+       efi_snp_claimed = claimed;
 
        /* Update SNP mode state for each interface */
        list_for_each_entry ( snpdev, &efi_snp_devices, list )
index 1e87ea1..720402b 100644 (file)
@@ -546,13 +546,6 @@ efi_snp_hii_extract_config ( const EFI_HII_CONFIG_ACCESS_PROTOCOL *hii,
        /* Initialise results */
        *results = NULL;
 
-       /* Work around apparently broken UEFI specification */
-       if ( ! ( request && request[0] ) ) {
-               DBGC ( snpdev, "SNPDEV %p ExtractConfig ignoring malformed "
-                      "request\n", snpdev );
-               return EFI_INVALID_PARAMETER;
-       }
-
        /* Process all request fragments */
        for ( pos = *progress = request ; *progress && **progress ;
              pos = *progress + 1 ) {
index da06412..81620c9 100644 (file)
@@ -25,10 +25,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
+#include <assert.h>
 #include <unistd.h>
 #include <ipxe/timer.h>
-#include <ipxe/init.h>
 #include <ipxe/efi/efi.h>
+#include <ipxe/efi/Protocol/Cpu.h>
 
 /** @file
  *
@@ -36,14 +38,19 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  */
 
-/** Current tick count */
-static unsigned long efi_jiffies;
+/** Scale factor to apply to CPU timer 0
+ *
+ * The timer is scaled down in order to ensure that reasonable values
+ * for "number of ticks" don't exceed the size of an unsigned long.
+ */
+#define EFI_TIMER0_SHIFT 12
 
-/** Timer tick event */
-static EFI_EVENT efi_tick_event;
+/** Calibration time */
+#define EFI_CALIBRATE_DELAY_MS 1
 
-/** Colour for debug messages */
-#define colour &efi_jiffies
+/** CPU protocol */
+static EFI_CPU_ARCH_PROTOCOL *cpu_arch;
+EFI_REQUIRE_PROTOCOL ( EFI_CPU_ARCH_PROTOCOL, &cpu_arch );
 
 /**
  * Delay for a fixed number of microseconds
@@ -57,8 +64,8 @@ static void efi_udelay ( unsigned long usecs ) {
 
        if ( ( efirc = bs->Stall ( usecs ) ) != 0 ) {
                rc = -EEFI ( efirc );
-               DBGC ( colour, "EFI could not delay for %ldus: %s\n",
-                      usecs, strerror ( rc ) );
+               DBG ( "EFI could not delay for %ldus: %s\n",
+                     usecs, strerror ( rc ) );
                /* Probably screwed */
        }
 }
@@ -69,92 +76,53 @@ static void efi_udelay ( unsigned long usecs ) {
  * @ret ticks          Current time, in ticks
  */
 static unsigned long efi_currticks ( void ) {
-
-       return efi_jiffies;
-}
-
-/**
- * Timer tick
- *
- * @v event            Timer tick event
- * @v context          Event context
- */
-static EFIAPI void efi_tick ( EFI_EVENT event __unused,
-                             void *context __unused ) {
-
-       /* Increment tick count */
-       efi_jiffies++;
-}
-
-/**
- * Start timer tick
- *
- */
-static void efi_tick_startup ( void ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
+       UINT64 time;
        EFI_STATUS efirc;
        int rc;
 
-       /* Create timer tick event */
-       if ( ( efirc = bs->CreateEvent ( ( EVT_TIMER | EVT_NOTIFY_SIGNAL ),
-                                        TPL_CALLBACK, efi_tick, NULL,
-                                        &efi_tick_event ) ) != 0 ) {
+       /* Read CPU timer 0 (TSC) */
+       if ( ( efirc = cpu_arch->GetTimerValue ( cpu_arch, 0, &time,
+                                                NULL ) ) != 0 ) {
                rc = -EEFI ( efirc );
-               DBGC ( colour, "EFI could not create timer tick: %s\n",
-                      strerror ( rc ) );
-               /* Nothing we can do about it */
-               return;
+               DBG ( "EFI could not read CPU timer: %s\n", strerror ( rc ) );
+               /* Probably screwed */
+               return -1UL;
        }
 
-       /* Start timer tick */
-       if ( ( efirc = bs->SetTimer ( efi_tick_event, TimerPeriodic,
-                                     ( 10000000 / EFI_TICKS_PER_SEC ) ) ) !=0){
-               rc = -EEFI ( efirc );
-               DBGC ( colour, "EFI could not start timer tick: %s\n",
-                      strerror ( rc ) );
-               /* Nothing we can do about it */
-               return;
-       }
-       DBGC ( colour, "EFI timer started at %d ticks per second\n",
-              EFI_TICKS_PER_SEC );
+       return ( time >> EFI_TIMER0_SHIFT );
 }
 
 /**
- * Stop timer tick
+ * Get number of ticks per second
  *
- * @v booting          System is shutting down in order to boot
+ * @ret ticks_per_sec  Number of ticks per second
  */
-static void efi_tick_shutdown ( int booting __unused ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Stop timer tick */
-       if ( ( efirc = bs->SetTimer ( efi_tick_event, TimerCancel, 0 ) ) != 0 ){
-               rc = -EEFI ( efirc );
-               DBGC ( colour, "EFI could not stop timer tick: %s\n",
-                      strerror ( rc ) );
-               /* Self-destruct initiated */
-               return;
+static unsigned long efi_ticks_per_sec ( void ) {
+       static unsigned long ticks_per_sec = 0;
+
+       /* Calibrate timer, if necessary.  EFI does nominally provide
+        * the timer speed via the (optional) TimerPeriod parameter to
+        * the GetTimerValue() call, but it gets the speed slightly
+        * wrong.  By up to three orders of magnitude.  Not helpful.
+        */
+       if ( ! ticks_per_sec ) {
+               unsigned long start;
+               unsigned long elapsed;
+
+               DBG ( "Calibrating EFI timer with a %d ms delay\n",
+                     EFI_CALIBRATE_DELAY_MS );
+               start = currticks();
+               mdelay ( EFI_CALIBRATE_DELAY_MS );
+               elapsed = ( currticks() - start );
+               ticks_per_sec = ( elapsed * ( 1000 / EFI_CALIBRATE_DELAY_MS ));
+               DBG ( "EFI CPU timer calibrated at %ld ticks in %d ms (%ld "
+                     "ticks/sec)\n", elapsed, EFI_CALIBRATE_DELAY_MS,
+                     ticks_per_sec );
        }
-       DBGC ( colour, "EFI timer stopped\n" );
 
-       /* Destroy timer tick event */
-       if ( ( efirc = bs->CloseEvent ( efi_tick_event ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( colour, "EFI could not destroy timer tick: %s\n",
-                      strerror ( rc ) );
-               /* Probably non-fatal */
-               return;
-       }
+       return ticks_per_sec;
 }
 
-/** Timer tick startup function */
-struct startup_fn efi_tick_startup_fn __startup_fn ( STARTUP_EARLY ) = {
-       .startup = efi_tick_startup,
-       .shutdown = efi_tick_shutdown,
-};
-
 PROVIDE_TIMER ( efi, udelay, efi_udelay );
 PROVIDE_TIMER ( efi, currticks, efi_currticks );
-PROVIDE_TIMER_INLINE ( efi, ticks_per_sec );
+PROVIDE_TIMER ( efi, ticks_per_sec, efi_ticks_per_sec );
diff --git a/roms/ipxe/src/interface/efi/efi_usb.c b/roms/ipxe/src/interface/efi/efi_usb.c
deleted file mode 100644 (file)
index db8c3d3..0000000
+++ /dev/null
@@ -1,1305 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <assert.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_utils.h>
-#include <ipxe/efi/efi_driver.h>
-#include <ipxe/efi/efi_usb.h>
-#include <ipxe/usb.h>
-
-/** @file
- *
- * EFI USB I/O PROTOCOL
- *
- */
-
-/**
- * Transcribe data direction (for debugging)
- *
- * @v direction                Data direction
- * @ret text           Transcribed data direction
- */
-static const char * efi_usb_direction_name ( EFI_USB_DATA_DIRECTION direction ){
-
-       switch ( direction ) {
-       case EfiUsbDataIn:      return "in";
-       case EfiUsbDataOut:     return "out";
-       case EfiUsbNoData:      return "none";
-       default:                return "<UNKNOWN>";
-       }
-}
-
-/******************************************************************************
- *
- * Endpoints
- *
- ******************************************************************************
- */
-
-/**
- * Poll USB bus
- *
- * @v usbdev           EFI USB device
- */
-static void efi_usb_poll ( struct efi_usb_device *usbdev ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       struct usb_bus *bus = usbdev->usb->port->hub->bus;
-       EFI_TPL tpl;
-
-       /* UEFI manages to ingeniously combine the worst aspects of
-        * both polling and interrupt-driven designs.  There is no way
-        * to support proper interrupt-driven operation, since there
-        * is no way to hook in an interrupt service routine.  A
-        * mockery of interrupts is provided by UEFI timers, which
-        * trigger at a preset rate and can fire at any time.
-        *
-        * We therefore have all of the downsides of a polling design
-        * (inefficiency and inability to sleep until something
-        * interesting happens) combined with all of the downsides of
-        * an interrupt-driven design (the complexity of code that
-        * could be preempted at any time).
-        *
-        * The UEFI specification expects us to litter the entire
-        * codebase with calls to RaiseTPL() as needed for sections of
-        * code that are not reentrant.  Since this doesn't actually
-        * gain us any substantive benefits (since even with such
-        * calls we would still be suffering from the limitations of a
-        * polling design), we instead choose to wrap only calls to
-        * usb_poll().  This should be sufficient for most practical
-        * purposes.
-        *
-        * A "proper" solution would involve rearchitecting the whole
-        * codebase to support interrupt-driven operation.
-        */
-       tpl = bs->RaiseTPL ( TPL_NOTIFY );
-
-       /* Poll bus */
-       usb_poll ( bus );
-
-       /* Restore task priority level */
-       bs->RestoreTPL ( tpl );
-}
-
-/**
- * Poll USB bus (from endpoint event timer)
- *
- * @v event            EFI event
- * @v context          EFI USB endpoint
- */
-static VOID EFIAPI efi_usb_timer ( EFI_EVENT event __unused,
-                                  VOID *context ) {
-       struct efi_usb_endpoint *usbep = context;
-       struct usb_bus *bus = usbep->usbintf->usbdev->usb->port->hub->bus;
-
-       /* Poll bus */
-       usb_poll ( bus );
-
-       /* Refill endpoint */
-       usb_refill ( &usbep->ep );
-}
-
-/**
- * Get endpoint MTU
- *
- * @v usbintf          EFI USB interface
- * @v endpoint         Endpoint address
- * @ret mtu            Endpoint MTU, or negative error
- */
-static int efi_usb_mtu ( struct efi_usb_interface *usbintf,
-                        unsigned int endpoint ) {
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-       struct usb_interface_descriptor *interface;
-       struct usb_endpoint_descriptor *desc;
-
-       /* Locate cached interface descriptor */
-       interface = usb_interface_descriptor ( usbdev->config,
-                                              usbintf->interface,
-                                              usbintf->alternate );
-       if ( ! interface ) {
-               DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
-                      usbintf->name, usbintf->alternate );
-               return -ENOENT;
-       }
-
-       /* Locate and copy cached endpoint descriptor */
-       for_each_interface_descriptor ( desc, usbdev->config, interface ) {
-               if ( ( desc->header.type == USB_ENDPOINT_DESCRIPTOR ) &&
-                    ( desc->endpoint == endpoint ) )
-                       return USB_ENDPOINT_MTU ( le16_to_cpu ( desc->sizes ) );
-       }
-
-       DBGC ( usbdev, "USBDEV %s alt %d ep %02x has no descriptor\n",
-              usbintf->name, usbintf->alternate, endpoint );
-       return -ENOENT;
-}
-
-/**
- * Open endpoint
- *
- * @v usbintf          EFI USB interface
- * @v endpoint         Endpoint address
- * @v attributes       Endpoint attributes
- * @v interval         Interval (in milliseconds)
- * @v driver           Driver operations
- * @ret rc             Return status code
- */
-static int efi_usb_open ( struct efi_usb_interface *usbintf,
-                         unsigned int endpoint, unsigned int attributes,
-                         unsigned int interval,
-                         struct usb_endpoint_driver_operations *driver ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-       struct efi_usb_endpoint *usbep;
-       unsigned int index = USB_ENDPOINT_IDX ( endpoint );
-       int mtu;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Get endpoint MTU */
-       mtu = efi_usb_mtu ( usbintf, endpoint );
-       if ( mtu < 0 ) {
-               rc = mtu;
-               goto err_mtu;
-       }
-
-       /* Allocate and initialise structure */
-       usbep = zalloc ( sizeof ( *usbep ) );
-       if ( ! usbep ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       usbep->usbintf = usbintf;
-       usb_endpoint_init ( &usbep->ep, usbdev->usb, driver );
-       usb_endpoint_describe ( &usbep->ep, endpoint, attributes, mtu, 0,
-                               ( interval << 3 /* microframes */ ) );
-
-       /* Open endpoint */
-       if ( ( rc = usb_endpoint_open ( &usbep->ep ) ) != 0 ) {
-               DBGC ( usbdev, "USBDEV %s %s could not open: %s\n",
-                      usbintf->name, usb_endpoint_name ( &usbep->ep ),
-                      strerror ( rc ) );
-               goto err_open;
-       }
-
-       /* Record opened endpoint */
-       usbintf->endpoint[index] = usbep;
-       DBGC ( usbdev, "USBDEV %s %s opened\n",
-              usbintf->name, usb_endpoint_name ( &usbep->ep ) );
-
-       /* Create event */
-       if ( ( efirc = bs->CreateEvent ( ( EVT_TIMER | EVT_NOTIFY_SIGNAL ),
-                                        TPL_NOTIFY, efi_usb_timer, usbep,
-                                        &usbep->event ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( usbdev, "USBDEV %s %s could not create event: %s\n",
-                      usbintf->name, usb_endpoint_name ( &usbep->ep ),
-                      strerror ( rc ) );
-               goto err_event;
-       }
-
-       return 0;
-
-       bs->CloseEvent ( usbep->event );
- err_event:
-       usbintf->endpoint[index] = usbep;
-       usb_endpoint_close ( &usbep->ep );
- err_open:
-       free ( usbep );
- err_alloc:
- err_mtu:
-       return rc;
-}
-
-/**
- * Close endpoint
- *
- * @v usbep            EFI USB endpoint
- */
-static void efi_usb_close ( struct efi_usb_endpoint *usbep ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       struct efi_usb_interface *usbintf = usbep->usbintf;
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-       unsigned int index = USB_ENDPOINT_IDX ( usbep->ep.address );
-
-       /* Sanity check */
-       assert ( usbintf->endpoint[index] == usbep );
-
-       /* Cancel timer (if applicable) and close event */
-       bs->SetTimer ( usbep->event, TimerCancel, 0 );
-       bs->CloseEvent ( usbep->event );
-
-       /* Close endpoint */
-       usb_endpoint_close ( &usbep->ep );
-       DBGC ( usbdev, "USBDEV %s %s closed\n",
-              usbintf->name, usb_endpoint_name ( &usbep->ep ) );
-
-       /* Free endpoint */
-       free ( usbep );
-
-       /* Record closed endpoint */
-       usbintf->endpoint[index] = NULL;
-}
-
-/**
- * Close all endpoints
- *
- * @v usbintf          EFI USB interface
- */
-static void efi_usb_close_all ( struct efi_usb_interface *usbintf ) {
-       struct efi_usb_endpoint *usbep;
-       unsigned int i;
-
-       for ( i = 0 ; i < ( sizeof ( usbintf->endpoint ) /
-                           sizeof ( usbintf->endpoint[0] ) ) ; i++ ) {
-               usbep = usbintf->endpoint[i];
-               if ( usbep )
-                       efi_usb_close ( usbep );
-       }
-}
-
-/**
- * Complete synchronous transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void efi_usb_sync_complete ( struct usb_endpoint *ep,
-                                   struct io_buffer *iobuf __unused, int rc ) {
-       struct efi_usb_endpoint *usbep =
-               container_of ( ep, struct efi_usb_endpoint, ep );
-
-       /* Record completion status */
-       usbep->rc = rc;
-}
-
-/** Synchronous endpoint operations */
-static struct usb_endpoint_driver_operations efi_usb_sync_driver = {
-       .complete = efi_usb_sync_complete,
-};
-
-/**
- * Perform synchronous transfer
- *
- * @v usbintf          USB endpoint
- * @v endpoint         Endpoint address
- * @v attributes       Endpoint attributes
- * @v timeout          Timeout (in milliseconds)
- * @v data             Data buffer
- * @v len              Length of data buffer
- * @ret rc             Return status code
- */
-static int efi_usb_sync_transfer ( struct efi_usb_interface *usbintf,
-                                  unsigned int endpoint,
-                                  unsigned int attributes,
-                                  unsigned int timeout,
-                                  void *data, size_t *len ) {
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-       struct efi_usb_endpoint *usbep;
-       struct io_buffer *iobuf;
-       unsigned int index = USB_ENDPOINT_IDX ( endpoint );
-       unsigned int i;
-       int rc;
-
-       /* Open endpoint, if applicable */
-       if ( ( ! usbintf->endpoint[index] ) &&
-            ( ( rc = efi_usb_open ( usbintf, endpoint, attributes, 0,
-                                    &efi_usb_sync_driver ) ) != 0 ) ) {
-               goto err_open;
-       }
-       usbep = usbintf->endpoint[index];
-
-       /* Allocate and construct I/O buffer */
-       iobuf = alloc_iob ( *len );
-       if ( ! iobuf ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       iob_put ( iobuf, *len );
-       if ( ! ( endpoint & USB_ENDPOINT_IN ) )
-               memcpy ( iobuf->data, data, *len );
-
-       /* Initialise completion status */
-       usbep->rc = -EINPROGRESS;
-
-       /* Enqueue transfer */
-       if ( ( rc = usb_stream ( &usbep->ep, iobuf, 0 ) ) != 0 ) {
-               DBGC ( usbdev, "USBDEV %s %s could not enqueue: %s\n",
-                      usbintf->name, usb_endpoint_name ( &usbep->ep ),
-                      strerror ( rc ) );
-               goto err_stream;
-       }
-
-       /* Wait for completion */
-       rc = -ETIMEDOUT;
-       for ( i = 0 ; ( ( timeout == 0 ) || ( i < timeout ) ) ; i++ ) {
-
-               /* Poll bus */
-               efi_usb_poll ( usbdev );
-
-               /* Check for completion */
-               if ( usbep->rc != -EINPROGRESS ) {
-                       rc = usbep->rc;
-                       break;
-               }
-
-               /* Delay */
-               mdelay ( 1 );
-       }
-
-       /* Check for errors */
-       if ( rc != 0 ) {
-               DBGC ( usbdev, "USBDEV %s %s failed: %s\n", usbintf->name,
-                      usb_endpoint_name ( &usbep->ep ), strerror ( rc ) );
-               goto err_completion;
-       }
-
-       /* Copy completion to data buffer, if applicable */
-       assert ( iob_len ( iobuf ) <= *len );
-       if ( endpoint & USB_ENDPOINT_IN )
-               memcpy ( data, iobuf->data, iob_len ( iobuf ) );
-       *len = iob_len ( iobuf );
-
-       /* Free I/O buffer */
-       free_iob ( iobuf );
-
-       /* Leave endpoint open */
-       return 0;
-
- err_completion:
- err_stream:
-       free_iob ( iobuf );
- err_alloc:
-       efi_usb_close ( usbep );
- err_open:
-       return EFIRC ( rc );
-}
-
-/**
- * Complete asynchronous transfer
- *
- * @v ep               USB endpoint
- * @v iobuf            I/O buffer
- * @v rc               Completion status code
- */
-static void efi_usb_async_complete ( struct usb_endpoint *ep,
-                                    struct io_buffer *iobuf, int rc ) {
-       struct efi_usb_endpoint *usbep =
-               container_of ( ep, struct efi_usb_endpoint, ep );
-       UINT32 status;
-
-       /* Ignore packets cancelled when the endpoint closes */
-       if ( ! ep->open )
-               goto drop;
-
-       /* Construct status */
-       status = ( ( rc == 0 ) ? 0 : EFI_USB_ERR_STALL );
-
-       /* Report completion */
-       usbep->callback ( iobuf->data, iob_len ( iobuf ), usbep->context,
-                         status );
-
- drop:
-       /* Recycle I/O buffer */
-       usb_recycle ( &usbep->ep, iobuf );
-}
-
-/** Asynchronous endpoint operations */
-static struct usb_endpoint_driver_operations efi_usb_async_driver = {
-       .complete = efi_usb_async_complete,
-};
-
-/**
- * Start asynchronous transfer
- *
- * @v usbintf          EFI USB interface
- * @v endpoint         Endpoint address
- * @v interval         Interval (in milliseconds)
- * @v len              Transfer length
- * @v callback         Callback function
- * @v context          Context for callback function
- * @ret rc             Return status code
- */
-static int efi_usb_async_start ( struct efi_usb_interface *usbintf,
-                                unsigned int endpoint, unsigned int interval,
-                                size_t len,
-                                EFI_ASYNC_USB_TRANSFER_CALLBACK callback,
-                                void *context ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-       struct efi_usb_endpoint *usbep;
-       unsigned int index = USB_ENDPOINT_IDX ( endpoint );
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Open endpoint */
-       if ( ( rc = efi_usb_open ( usbintf, endpoint,
-                                  USB_ENDPOINT_ATTR_INTERRUPT, interval,
-                                  &efi_usb_async_driver ) ) != 0 )
-               goto err_open;
-       usbep = usbintf->endpoint[index];
-
-       /* Record callback parameters */
-       usbep->callback = callback;
-       usbep->context = context;
-
-       /* Prefill endpoint */
-       usb_refill_init ( &usbep->ep, 0, len, EFI_USB_ASYNC_FILL );
-       if ( ( rc = usb_prefill ( &usbep->ep ) ) != 0 ) {
-               DBGC ( usbdev, "USBDEV %s %s could not prefill: %s\n",
-                      usbintf->name, usb_endpoint_name ( &usbep->ep ),
-                      strerror ( rc ) );
-               goto err_prefill;
-       }
-
-       /* Start timer */
-       if ( ( efirc = bs->SetTimer ( usbep->event, TimerPeriodic,
-                                     ( interval * 10000 ) ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( usbdev, "USBDEV %s %s could not set timer: %s\n",
-                      usbintf->name, usb_endpoint_name ( &usbep->ep ),
-                      strerror ( rc ) );
-               goto err_timer;
-       }
-
-       return 0;
-
-       bs->SetTimer ( usbep->event, TimerCancel, 0 );
- err_timer:
- err_prefill:
-       efi_usb_close ( usbep );
- err_open:
-       return rc;
-}
-
-/**
- * Stop asynchronous transfer
- *
- * @v usbintf          EFI USB interface
- * @v endpoint         Endpoint address
- */
-static void efi_usb_async_stop ( struct efi_usb_interface *usbintf,
-                                unsigned int endpoint ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       struct efi_usb_endpoint *usbep;
-       unsigned int index = USB_ENDPOINT_IDX ( endpoint );
-
-       /* Do nothing if endpoint is already closed */
-       usbep = usbintf->endpoint[index];
-       if ( ! usbep )
-               return;
-
-       /* Stop timer */
-       bs->SetTimer ( usbep->event, TimerCancel, 0 );
-
-       /* Close endpoint */
-       efi_usb_close ( usbep );
-}
-
-/******************************************************************************
- *
- * USB I/O protocol
- *
- ******************************************************************************
- */
-
-/**
- * Perform control transfer
- *
- * @v usbio            USB I/O protocol
- * @v packet           Setup packet
- * @v direction                Data direction
- * @v timeout          Timeout (in milliseconds)
- * @v data             Data buffer
- * @v len              Length of data
- * @ret status         Transfer status
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_usb_control_transfer ( EFI_USB_IO_PROTOCOL *usbio,
-                          EFI_USB_DEVICE_REQUEST *packet,
-                          EFI_USB_DATA_DIRECTION direction,
-                          UINT32 timeout, VOID *data, UINTN len,
-                          UINT32 *status ) {
-       struct efi_usb_interface *usbintf =
-               container_of ( usbio, struct efi_usb_interface, usbio );
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-       unsigned int request = ( packet->RequestType |
-                                USB_REQUEST_TYPE ( packet->Request ) );
-       unsigned int value = le16_to_cpu ( packet->Value );
-       unsigned int index = le16_to_cpu ( packet->Index );
-       int rc;
-
-       DBGC2 ( usbdev, "USBDEV %s control %04x:%04x:%04x:%04x %s %dms "
-               "%p+%zx\n", usbintf->name, request, value, index,
-               le16_to_cpu ( packet->Length ),
-               efi_usb_direction_name ( direction ), timeout, data,
-               ( ( size_t ) len ) );
-
-       /* Clear status */
-       *status = 0;
-
-       /* Block attempts to change the device configuration, since
-        * this is logically impossible to do given the constraints of
-        * the EFI_USB_IO_PROTOCOL design.
-        */
-       if ( ( request == USB_SET_CONFIGURATION ) &&
-            ( value != usbdev->config->config ) ) {
-               DBGC ( usbdev, "USBDEV %s cannot set configuration %d: not "
-                      "logically possible\n", usbintf->name, index );
-               rc = -ENOTSUP;
-               goto err_change_config;
-       }
-
-       /* If we are selecting a new alternate setting then close all
-        * open endpoints.
-        */
-       if ( ( request == USB_SET_INTERFACE ) &&
-            ( value != usbintf->alternate ) )
-               efi_usb_close_all ( usbintf );
-
-       /* Issue control transfer */
-       if ( ( rc = usb_control ( usbdev->usb, request, value, index,
-                                 data, len ) ) != 0 ) {
-               DBGC ( usbdev, "USBDEV %s control %04x:%04x:%04x:%04x %p+%zx "
-                      "failed: %s\n", usbintf->name, request, value, index,
-                      le16_to_cpu ( packet->Length ), data, ( ( size_t ) len ),
-                      strerror ( rc ) );
-               /* Assume that any error represents a stall */
-               *status = EFI_USB_ERR_STALL;
-               goto err_control;
-       }
-
-       /* Update alternate setting, if applicable */
-       if ( request == USB_SET_INTERFACE ) {
-               usbintf->alternate = value;
-               DBGC ( usbdev, "USBDEV %s alt %d selected\n",
-                      usbintf->name, usbintf->alternate );
-       }
-
- err_control:
- err_change_config:
-       return EFIRC ( rc );
-}
-
-/**
- * Perform bulk transfer
- *
- * @v usbio            USB I/O protocol
- * @v endpoint         Endpoint address
- * @v data             Data buffer
- * @v len              Length of data
- * @v timeout          Timeout (in milliseconds)
- * @ret status         Transfer status
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_usb_bulk_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data,
-                       UINTN *len, UINTN timeout, UINT32 *status ) {
-       struct efi_usb_interface *usbintf =
-               container_of ( usbio, struct efi_usb_interface, usbio );
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-       size_t actual = *len;
-       int rc;
-
-       DBGC2 ( usbdev, "USBDEV %s bulk %s %p+%zx %dms\n", usbintf->name,
-               ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
-               ( ( size_t ) *len ), ( ( unsigned int ) timeout ) );
-
-       /* Clear status */
-       *status = 0;
-
-       /* Perform synchronous transfer */
-       if ( ( rc = efi_usb_sync_transfer ( usbintf, endpoint,
-                                           USB_ENDPOINT_ATTR_BULK, timeout,
-                                           data, &actual ) ) != 0 ) {
-               /* Assume that any error represents a timeout */
-               *status = EFI_USB_ERR_TIMEOUT;
-               return rc;
-       }
-
-       return 0;
-}
-
-/**
- * Perform synchronous interrupt transfer
- *
- * @v usbio            USB I/O protocol
- * @v endpoint         Endpoint address
- * @v data             Data buffer
- * @v len              Length of data
- * @v timeout          Timeout (in milliseconds)
- * @ret status         Transfer status
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_usb_sync_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
-                                 VOID *data, UINTN *len, UINTN timeout,
-                                 UINT32 *status ) {
-       struct efi_usb_interface *usbintf =
-               container_of ( usbio, struct efi_usb_interface, usbio );
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-       size_t actual = *len;
-       int rc;
-
-       DBGC2 ( usbdev, "USBDEV %s sync intr %s %p+%zx %dms\n", usbintf->name,
-               ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
-               ( ( size_t ) *len ), ( ( unsigned int ) timeout ) );
-
-       /* Clear status */
-       *status = 0;
-
-       /* Perform synchronous transfer */
-       if ( ( rc = efi_usb_sync_transfer ( usbintf, endpoint,
-                                           USB_ENDPOINT_ATTR_INTERRUPT,
-                                           timeout, data, &actual ) ) != 0 ) {
-               /* Assume that any error represents a timeout */
-               *status = EFI_USB_ERR_TIMEOUT;
-               return rc;
-       }
-
-       return 0;
-}
-
-/**
- * Perform asynchronous interrupt transfer
- *
- * @v usbio            USB I/O protocol
- * @v endpoint         Endpoint address
- * @v start            Start (rather than stop) transfer
- * @v interval         Polling interval (in milliseconds)
- * @v len              Data length
- * @v callback         Callback function
- * @v context          Context for callback function
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_usb_async_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
-                                  BOOLEAN start, UINTN interval, UINTN len,
-                                  EFI_ASYNC_USB_TRANSFER_CALLBACK callback,
-                                  VOID *context ) {
-       struct efi_usb_interface *usbintf =
-               container_of ( usbio, struct efi_usb_interface, usbio );
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-       int rc;
-
-       DBGC2 ( usbdev, "USBDEV %s async intr %s len %#zx int %d %p/%p\n",
-               usbintf->name,
-               ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ),
-               ( ( size_t ) len ), ( ( unsigned int ) interval ),
-               callback, context );
-
-       /* Start/stop transfer as applicable */
-       if ( start ) {
-
-               /* Start new transfer */
-               if ( ( rc = efi_usb_async_start ( usbintf, endpoint, interval,
-                                                 len, callback,
-                                                 context ) ) != 0 )
-                       goto err_start;
-
-       } else {
-
-               /* Stop transfer */
-               efi_usb_async_stop ( usbintf, endpoint );
-
-       }
-
-       return 0;
-
- err_start:
-       return EFIRC ( rc );
-}
-
-/**
- * Perform synchronous isochronous transfer
- *
- * @v usbio            USB I/O protocol
- * @v endpoint         Endpoint address
- * @v data             Data buffer
- * @v len              Length of data
- * @ret status         Transfer status
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_usb_isochronous_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
-                              VOID *data, UINTN len, UINT32 *status ) {
-       struct efi_usb_interface *usbintf =
-               container_of ( usbio, struct efi_usb_interface, usbio );
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-
-       DBGC2 ( usbdev, "USBDEV %s sync iso %s %p+%zx\n", usbintf->name,
-               ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
-               ( ( size_t ) len ) );
-
-       /* Clear status */
-       *status = 0;
-
-       /* Not supported */
-       return EFI_UNSUPPORTED;
-}
-
-/**
- * Perform asynchronous isochronous transfers
- *
- * @v usbio            USB I/O protocol
- * @v endpoint         Endpoint address
- * @v data             Data buffer
- * @v len              Length of data
- * @v callback         Callback function
- * @v context          Context for callback function
- * @ret status         Transfer status
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_usb_async_isochronous_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
-                                    VOID *data, UINTN len,
-                                    EFI_ASYNC_USB_TRANSFER_CALLBACK callback,
-                                    VOID *context ) {
-       struct efi_usb_interface *usbintf =
-               container_of ( usbio, struct efi_usb_interface, usbio );
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-
-       DBGC2 ( usbdev, "USBDEV %s async iso %s %p+%zx %p/%p\n", usbintf->name,
-               ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
-               ( ( size_t ) len ), callback, context );
-
-       /* Not supported */
-       return EFI_UNSUPPORTED;
-}
-
-/**
- * Get device descriptor
- *
- * @v usbio            USB I/O protocol
- * @ret efidesc                EFI device descriptor
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_usb_get_device_descriptor ( EFI_USB_IO_PROTOCOL *usbio,
-                               EFI_USB_DEVICE_DESCRIPTOR *efidesc ) {
-       struct efi_usb_interface *usbintf =
-               container_of ( usbio, struct efi_usb_interface, usbio );
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-
-       DBGC2 ( usbdev, "USBDEV %s get device descriptor\n", usbintf->name );
-
-       /* Copy cached device descriptor */
-       memcpy ( efidesc, &usbdev->usb->device, sizeof ( *efidesc ) );
-
-       return 0;
-}
-
-/**
- * Get configuration descriptor
- *
- * @v usbio            USB I/O protocol
- * @ret efidesc                EFI interface descriptor
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_usb_get_config_descriptor ( EFI_USB_IO_PROTOCOL *usbio,
-                               EFI_USB_CONFIG_DESCRIPTOR *efidesc ) {
-       struct efi_usb_interface *usbintf =
-               container_of ( usbio, struct efi_usb_interface, usbio );
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-
-       DBGC2 ( usbdev, "USBDEV %s get configuration descriptor\n",
-               usbintf->name );
-
-       /* Copy cached configuration descriptor */
-       memcpy ( efidesc, usbdev->config, sizeof ( *efidesc ) );
-
-       return 0;
-}
-
-/**
- * Get interface descriptor
- *
- * @v usbio            USB I/O protocol
- * @ret efidesc                EFI interface descriptor
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_usb_get_interface_descriptor ( EFI_USB_IO_PROTOCOL *usbio,
-                                  EFI_USB_INTERFACE_DESCRIPTOR *efidesc ) {
-       struct efi_usb_interface *usbintf =
-               container_of ( usbio, struct efi_usb_interface, usbio );
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-       struct usb_interface_descriptor *desc;
-
-       DBGC2 ( usbdev, "USBDEV %s get interface descriptor\n", usbintf->name );
-
-       /* Locate cached interface descriptor */
-       desc = usb_interface_descriptor ( usbdev->config, usbintf->interface,
-                                         usbintf->alternate );
-       if ( ! desc ) {
-               DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
-                      usbintf->name, usbintf->alternate );
-               return -ENOENT;
-       }
-
-       /* Copy cached interface descriptor */
-       memcpy ( efidesc, desc, sizeof ( *efidesc ) );
-
-       return 0;
-}
-
-/**
- * Get endpoint descriptor
- *
- * @v usbio            USB I/O protocol
- * @v address          Endpoint index
- * @ret efidesc                EFI interface descriptor
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_usb_get_endpoint_descriptor ( EFI_USB_IO_PROTOCOL *usbio, UINT8 index,
-                                 EFI_USB_ENDPOINT_DESCRIPTOR *efidesc ) {
-       struct efi_usb_interface *usbintf =
-               container_of ( usbio, struct efi_usb_interface, usbio );
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-       struct usb_interface_descriptor *interface;
-       struct usb_endpoint_descriptor *desc;
-
-       DBGC2 ( usbdev, "USBDEV %s get endpoint %d descriptor\n",
-               usbintf->name, index );
-
-       /* Locate cached interface descriptor */
-       interface = usb_interface_descriptor ( usbdev->config,
-                                              usbintf->interface,
-                                              usbintf->alternate );
-       if ( ! interface ) {
-               DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
-                      usbintf->name, usbintf->alternate );
-               return -ENOENT;
-       }
-
-       /* Locate and copy cached endpoint descriptor */
-       for_each_interface_descriptor ( desc, usbdev->config, interface ) {
-               if ( ( desc->header.type == USB_ENDPOINT_DESCRIPTOR ) &&
-                    ( index-- == 0 ) ) {
-                       memcpy ( efidesc, desc, sizeof ( *efidesc ) );
-                       return 0;
-               }
-       }
-       return -ENOENT;
-}
-
-/**
- * Get string descriptor
- *
- * @v usbio            USB I/O protocol
- * @v language         Language ID
- * @v index            String index
- * @ret string         String
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_usb_get_string_descriptor ( EFI_USB_IO_PROTOCOL *usbio, UINT16 language,
-                               UINT8 index, CHAR16 **string ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       struct efi_usb_interface *usbintf =
-               container_of ( usbio, struct efi_usb_interface, usbio );
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-       struct usb_descriptor_header header;
-       VOID *buffer;
-       size_t len;
-       EFI_STATUS efirc;
-       int rc;
-
-       DBGC2 ( usbdev, "USBDEV %s get string %d:%d descriptor\n",
-               usbintf->name, language, index );
-
-       /* Read descriptor header */
-       if ( ( rc = usb_get_descriptor ( usbdev->usb, 0, USB_STRING_DESCRIPTOR,
-                                        index, language, &header,
-                                        sizeof ( header ) ) ) != 0 ) {
-               DBGC ( usbdev, "USBDEV %s could not get string %d:%d "
-                      "descriptor header: %s\n", usbintf->name, language,
-                      index, strerror ( rc ) );
-               goto err_get_header;
-       }
-       len = header.len;
-
-       /* Allocate buffer */
-       if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, len,
-                                         &buffer ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               goto err_alloc;
-       }
-
-       /* Read whole descriptor */
-       if ( ( rc = usb_get_descriptor ( usbdev->usb, 0, USB_STRING_DESCRIPTOR,
-                                        index, language, buffer,
-                                        len ) ) != 0 ) {
-               DBGC ( usbdev, "USBDEV %s could not get string %d:%d "
-                      "descriptor: %s\n", usbintf->name, language,
-                      index, strerror ( rc ) );
-               goto err_get_descriptor;
-       }
-
-       /* Shuffle down and terminate string */
-       memmove ( buffer, ( buffer + sizeof ( header ) ),
-                 ( len - sizeof ( header ) ) );
-       memset ( ( buffer + len - sizeof ( header ) ), 0, sizeof ( **string ) );
-
-       /* Return allocated string */
-       *string = buffer;
-       return 0;
-
- err_get_descriptor:
-       bs->FreePool ( buffer );
- err_alloc:
- err_get_header:
-       return EFIRC ( rc );
-}
-
-/**
- * Get supported languages
- *
- * @v usbio            USB I/O protocol
- * @ret languages      Language ID table
- * @ret len            Length of language ID table
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_usb_get_supported_languages ( EFI_USB_IO_PROTOCOL *usbio,
-                                 UINT16 **languages, UINT16 *len ) {
-       struct efi_usb_interface *usbintf =
-               container_of ( usbio, struct efi_usb_interface, usbio );
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-
-       DBGC2 ( usbdev, "USBDEV %s get supported languages\n", usbintf->name );
-
-       /* Return cached supported languages */
-       *languages = ( ( ( void * ) usbdev->languages ) +
-                      sizeof ( *(usbdev->languages) ) );
-       *len = usbdev->languages->len;
-
-       return 0;
-}
-
-/**
- * Reset port
- *
- * @v usbio            USB I/O protocol
- * @ret efirc          EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_usb_port_reset ( EFI_USB_IO_PROTOCOL *usbio ) {
-       struct efi_usb_interface *usbintf =
-               container_of ( usbio, struct efi_usb_interface, usbio );
-       struct efi_usb_device *usbdev = usbintf->usbdev;
-
-       DBGC2 ( usbdev, "USBDEV %s reset port\n", usbintf->name );
-
-       /* This is logically impossible to do, since resetting the
-        * port may destroy state belonging to other
-        * EFI_USB_IO_PROTOCOL instances belonging to the same USB
-        * device.  (This is yet another artifact of the incredibly
-        * poor design of the EFI_USB_IO_PROTOCOL.)
-        */
-       return EFI_INVALID_PARAMETER;
-}
-
-/** USB I/O protocol */
-static EFI_USB_IO_PROTOCOL efi_usb_io_protocol = {
-       .UsbControlTransfer             = efi_usb_control_transfer,
-       .UsbBulkTransfer                = efi_usb_bulk_transfer,
-       .UsbAsyncInterruptTransfer      = efi_usb_async_interrupt_transfer,
-       .UsbSyncInterruptTransfer       = efi_usb_sync_interrupt_transfer,
-       .UsbIsochronousTransfer         = efi_usb_isochronous_transfer,
-       .UsbAsyncIsochronousTransfer    = efi_usb_async_isochronous_transfer,
-       .UsbGetDeviceDescriptor         = efi_usb_get_device_descriptor,
-       .UsbGetConfigDescriptor         = efi_usb_get_config_descriptor,
-       .UsbGetInterfaceDescriptor      = efi_usb_get_interface_descriptor,
-       .UsbGetEndpointDescriptor       = efi_usb_get_endpoint_descriptor,
-       .UsbGetStringDescriptor         = efi_usb_get_string_descriptor,
-       .UsbGetSupportedLanguages       = efi_usb_get_supported_languages,
-       .UsbPortReset                   = efi_usb_port_reset,
-};
-
-/******************************************************************************
- *
- * USB driver
- *
- ******************************************************************************
- */
-
-/**
- * Install interface
- *
- * @v usbdev           EFI USB device
- * @v interface                Interface number
- * @ret rc             Return status code
- */
-static int efi_usb_install ( struct efi_usb_device *usbdev,
-                            unsigned int interface ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       struct efi_device *efidev = usbdev->efidev;
-       struct efi_usb_interface *usbintf;
-       struct usb_device *usb;
-       EFI_DEVICE_PATH_PROTOCOL *path_end;
-       USB_DEVICE_PATH *usbpath;
-       unsigned int path_count;
-       size_t path_prefix_len;
-       size_t path_len;
-       EFI_STATUS efirc;
-       int rc;
-
-       /* Calculate device path length */
-       path_count = ( usb_depth ( usbdev->usb ) + 1 );
-       path_prefix_len = efi_devpath_len ( efidev->path );
-       path_len = ( path_prefix_len + ( path_count * sizeof ( *usbpath ) ) +
-                    sizeof ( *path_end ) );
-
-       /* Allocate and initialise structure */
-       usbintf = zalloc ( sizeof ( *usbintf ) + path_len );
-       if ( ! usbintf ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       snprintf ( usbintf->name, sizeof ( usbintf->name ), "%s[%d]",
-                  usbdev->name, interface );
-       usbintf->usbdev = usbdev;
-       usbintf->interface = interface;
-       memcpy ( &usbintf->usbio, &efi_usb_io_protocol,
-                sizeof ( usbintf->usbio ) );
-       usbintf->path = ( ( ( void * ) usbintf ) + sizeof ( *usbintf ) );
-
-       /* Construct device path */
-       memcpy ( usbintf->path, efidev->path, path_prefix_len );
-       path_end = ( ( ( void * ) usbintf->path ) + path_len -
-                    sizeof ( *path_end ) );
-       path_end->Type = END_DEVICE_PATH_TYPE;
-       path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
-       path_end->Length[0] = sizeof ( *path_end );
-       usbpath = ( ( ( void * ) path_end ) - sizeof ( *usbpath ) );
-       usbpath->InterfaceNumber = interface;
-       for ( usb = usbdev->usb ; usb ; usbpath--, usb = usb->port->hub->usb ) {
-               usbpath->Header.Type = MESSAGING_DEVICE_PATH;
-               usbpath->Header.SubType = MSG_USB_DP;
-               usbpath->Header.Length[0] = sizeof ( *usbpath );
-               usbpath->ParentPortNumber = usb->port->address;
-       }
-
-       /* Add to list of interfaces */
-       list_add_tail ( &usbintf->list, &usbdev->interfaces );
-
-       /* Install protocols */
-       if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
-                       &usbintf->handle,
-                       &efi_usb_io_protocol_guid, &usbintf->usbio,
-                       &efi_device_path_protocol_guid, usbintf->path,
-                       NULL ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( usbdev, "USBDEV %s could not install protocols: %s\n",
-                      usbintf->name, strerror ( rc ) );
-               goto err_install_protocol;
-       }
-
-       DBGC ( usbdev, "USBDEV %s installed as %s\n",
-              usbintf->name, efi_handle_name ( usbintf->handle ) );
-       return 0;
-
-       efi_usb_close_all ( usbintf );
-       bs->UninstallMultipleProtocolInterfaces (
-                       usbintf->handle,
-                       &efi_usb_io_protocol_guid, &usbintf->usbio,
-                       &efi_device_path_protocol_guid, usbintf->path,
-                       NULL );
- err_install_protocol:
-       list_del ( &usbintf->list );
-       free ( usbintf );
- err_alloc:
-       return rc;
-}
-
-/**
- * Uninstall interface
- *
- * @v usbintf          EFI USB interface
- */
-static void efi_usb_uninstall ( struct efi_usb_interface *usbintf ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-
-       /* Close all endpoints */
-       efi_usb_close_all ( usbintf );
-
-       /* Uninstall protocols */
-       bs->UninstallMultipleProtocolInterfaces (
-                       usbintf->handle,
-                       &efi_usb_io_protocol_guid, &usbintf->usbio,
-                       &efi_device_path_protocol_guid, usbintf->path,
-                       NULL );
-
-       /* Remove from list of interfaces */
-       list_del ( &usbintf->list );
-
-       /* Free interface */
-       free ( usbintf );
-}
-
-/**
- * Uninstall all interfaces
- *
- * @v usbdev           EFI USB device
- */
-static void efi_usb_uninstall_all ( struct efi_usb_device *efiusb ) {
-       struct efi_usb_interface *usbintf;
-
-       /* Uninstall all interfaces */
-       while ( ( usbintf = list_first_entry ( &efiusb->interfaces,
-                                              struct efi_usb_interface,
-                                              list ) ) ) {
-               efi_usb_uninstall ( usbintf );
-       }
-}
-
-/**
- * Probe device
- *
- * @v func             USB function
- * @v config           Configuration descriptor
- * @ret rc             Return status code
- */
-static int efi_usb_probe ( struct usb_function *func,
-                          struct usb_configuration_descriptor *config ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       struct usb_device *usb = func->usb;
-       struct efi_usb_device *usbdev;
-       struct efi_usb_interface *usbintf;
-       struct efi_device *efidev;
-       struct usb_descriptor_header header;
-       size_t config_len;
-       unsigned int i;
-       int rc;
-
-       /* Find parent EFI device */
-       efidev = efidev_parent ( &func->dev );
-       if ( ! efidev ) {
-               rc = -ENOTTY;
-               goto err_no_efidev;
-       }
-
-       /* Get configuration length */
-       config_len = le16_to_cpu ( config->len );
-
-       /* Get supported languages descriptor header */
-       if ( ( rc = usb_get_descriptor ( usb, 0, USB_STRING_DESCRIPTOR, 0, 0,
-                                        &header, sizeof ( header ) ) ) != 0 ) {
-               /* Assume no strings are present */
-               header.len = 0;
-       }
-
-       /* Allocate and initialise structure */
-       usbdev = zalloc ( sizeof ( *usbdev ) + config_len + header.len );
-       if ( ! usbdev ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       usb_func_set_drvdata ( func, usbdev );
-       usbdev->name = func->name;
-       usbdev->usb = usb;
-       usbdev->efidev = efidev;
-       usbdev->config = ( ( ( void * ) usbdev ) + sizeof ( *usbdev ) );
-       memcpy ( usbdev->config, config, config_len );
-       usbdev->languages = ( ( ( void * ) usbdev->config ) + config_len );
-       INIT_LIST_HEAD ( &usbdev->interfaces );
-
-       /* Get supported languages descriptor */
-       if ( header.len &&
-            ( rc = usb_get_descriptor ( usb, 0, USB_STRING_DESCRIPTOR, 0, 0,
-                                        usbdev->languages,
-                                        header.len ) ) != 0 ) {
-               DBGC ( usbdev, "USBDEV %s could not get supported languages: "
-                      "%s\n", usbdev->name, strerror ( rc ) );
-               goto err_get_languages;
-       }
-
-       /* Install interfaces */
-       for ( i = 0 ; i < func->desc.count ; i++ ) {
-               if ( ( rc = efi_usb_install ( usbdev,
-                                             func->interface[i] ) ) != 0 )
-                       goto err_install;
-       }
-
-       /* Connect any external drivers */
-       list_for_each_entry ( usbintf, &usbdev->interfaces, list )
-               bs->ConnectController ( usbintf->handle, NULL, NULL, TRUE );
-
-       return 0;
-
- err_install:
-       efi_usb_uninstall_all ( usbdev );
-       assert ( list_empty ( &usbdev->interfaces ) );
- err_get_languages:
-       free ( usbdev );
- err_alloc:
- err_no_efidev:
-       return rc;
-}
-
-/**
- * Remove device
- *
- * @v func             USB function
- */
-static void efi_usb_remove ( struct usb_function *func ) {
-       struct efi_usb_device *usbdev = usb_func_get_drvdata ( func );
-
-       /* Uninstall all interfaces */
-       efi_usb_uninstall_all ( usbdev );
-       assert ( list_empty ( &usbdev->interfaces ) );
-
-       /* Free device */
-       free ( usbdev );
-}
-
-/** USB I/O protocol device IDs */
-static struct usb_device_id efi_usb_ids[] = {
-       {
-               .name = "usbio",
-               .vendor = USB_ANY_ID,
-               .product = USB_ANY_ID,
-       },
-};
-
-/** USB I/O protocol driver */
-struct usb_driver usbio_driver __usb_driver = {
-       .ids = efi_usb_ids,
-       .id_count = ( sizeof ( efi_usb_ids ) / sizeof ( efi_usb_ids[0] ) ),
-       .class = USB_CLASS_ID ( USB_ANY_ID, USB_ANY_ID, USB_ANY_ID ),
-       .score = USB_SCORE_FALLBACK,
-       .probe = efi_usb_probe,
-       .remove = efi_usb_remove,
-};
index 4dc7541..936ad48 100644 (file)
@@ -51,18 +51,6 @@ EFI_DEVICE_PATH_PROTOCOL * efi_devpath_end ( EFI_DEVICE_PATH_PROTOCOL *path ) {
 }
 
 /**
- * Find length of device path (excluding terminator)
- *
- * @v path             Path to device
- * @ret path_len       Length of device path
- */
-size_t efi_devpath_len ( EFI_DEVICE_PATH_PROTOCOL *path ) {
-       EFI_DEVICE_PATH_PROTOCOL *end = efi_devpath_end ( path );
-
-       return ( ( ( void * ) end ) - ( ( void * ) path ) );
-}
-
-/**
  * Locate parent device supporting a given protocol
  *
  * @v device           EFI device handle
@@ -88,8 +76,8 @@ int efi_locate_device ( EFI_HANDLE device, EFI_GUID *protocol,
                                          efi_image_handle, device,
                                          EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
                rc = -EEFI ( efirc );
-               DBGC ( device, "EFIDEV %s cannot open device path: %s\n",
-                      efi_handle_name ( device ), strerror ( rc ) );
+               DBGC ( device, "EFIDEV %p %s cannot open device path: %s\n",
+                      device, efi_handle_name ( device ), strerror ( rc ) );
                goto err_open_device_path;
        }
        devpath = path.path;
@@ -98,8 +86,8 @@ int efi_locate_device ( EFI_HANDLE device, EFI_GUID *protocol,
        if ( ( efirc = bs->LocateDevicePath ( protocol, &devpath,
                                              parent ) ) != 0 ) {
                rc = -EEFI ( efirc );
-               DBGC ( device, "EFIDEV %s has no parent supporting %s: %s\n",
-                      efi_handle_name ( device ),
+               DBGC ( device, "EFIDEV %p %s has no parent supporting %s: %s\n",
+                      device, efi_handle_name ( device ),
                       efi_guid_ntoa ( protocol ), strerror ( rc ) );
                goto err_locate_protocol;
        }
@@ -135,17 +123,18 @@ int efi_child_add ( EFI_HANDLE parent, EFI_HANDLE child ) {
                                          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                                          ) ) != 0 ) {
                rc = -EEFI ( efirc );
-               DBGC ( parent, "EFIDEV %s could not add child",
-                      efi_handle_name ( parent ) );
-               DBGC ( parent, " %s: %s\n",
+               DBGC ( parent, "EFIDEV %p %s could not add child",
+                      parent, efi_handle_name ( parent ) );
+               DBGC ( parent, " %p %s: %s\n", child,
                       efi_handle_name ( child ), strerror ( rc ) );
                DBGC_EFI_OPENERS ( parent, parent,
                                   &efi_device_path_protocol_guid );
                return rc;
        }
 
-       DBGC2 ( parent, "EFIDEV %s added child", efi_handle_name ( parent ) );
-       DBGC2 ( parent, " %s\n", efi_handle_name ( child ) );
+       DBGC2 ( parent, "EFIDEV %p %s added child",
+               parent, efi_handle_name ( parent ) );
+       DBGC2 ( parent, " %p %s\n", child, efi_handle_name ( child ) );
        return 0;
 }
 
@@ -160,8 +149,10 @@ void efi_child_del ( EFI_HANDLE parent, EFI_HANDLE child ) {
 
        bs->CloseProtocol ( parent, &efi_device_path_protocol_guid,
                            efi_image_handle, child );
-       DBGC2 ( parent, "EFIDEV %s removed child", efi_handle_name ( parent ) );
-       DBGC2 ( parent, " %s\n", efi_handle_name ( child ) );
+       DBGC2 ( parent, "EFIDEV %p %s removed child",
+               parent, efi_handle_name ( parent ) );
+       DBGC2 ( parent, " %p %s\n",
+               child, efi_handle_name ( child ) );
 }
 
 /**
@@ -181,15 +172,16 @@ static int efi_pci_info ( EFI_HANDLE device, const char *prefix,
        /* Find parent PCI device */
        if ( ( rc = efi_locate_device ( device, &efi_pci_io_protocol_guid,
                                        &pci_device ) ) != 0 ) {
-               DBGC ( device, "EFIDEV %s is not a PCI device: %s\n",
-                      efi_handle_name ( device ), strerror ( rc ) );
+               DBGC ( device, "EFIDEV %p %s is not a PCI device: %s\n",
+                      device, efi_handle_name ( device ), strerror ( rc ) );
                return rc;
        }
 
        /* Get PCI device information */
        if ( ( rc = efipci_info ( pci_device, &pci ) ) != 0 ) {
-               DBGC ( device, "EFIDEV %s could not get PCI information: %s\n",
-                      efi_handle_name ( device ), strerror ( rc ) );
+               DBGC ( device, "EFIDEV %p %s could not get PCI information: "
+                      "%s\n", device, efi_handle_name ( device ),
+                      strerror ( rc ) );
                return rc;
        }
 
@@ -219,8 +211,8 @@ void efi_device_info ( EFI_HANDLE device, const char *prefix,
        /* If we cannot get any underlying device information, fall
         * back to providing information about the EFI handle.
         */
-       DBGC ( device, "EFIDEV %s could not get underlying device "
-              "information\n", efi_handle_name ( device ) );
+       DBGC ( device, "EFIDEV %p %s could not get underlying device "
+              "information\n", device, efi_handle_name ( device ) );
        dev->desc.bus_type = BUS_TYPE_EFI;
        snprintf ( dev->name, sizeof ( dev->name ), "%s-%p", prefix, device );
 }
index c0c40ee..2ea184e 100644 (file)
@@ -101,81 +101,6 @@ static const char * efi_status ( EFI_STATUS efirc ) {
 }
 
 /**
- * Convert EFI boolean to text
- *
- * @v boolean          Boolean value
- * @ret text           Boolean value text
- */
-static const char * efi_boolean ( BOOLEAN boolean ) {
-
-       return ( boolean ? "TRUE" : "FALSE" );
-}
-
-/**
- * Wrap InstallProtocolInterface()
- *
- */
-static EFI_STATUS EFIAPI
-efi_install_protocol_interface_wrapper ( EFI_HANDLE *handle, EFI_GUID *protocol,
-                                        EFI_INTERFACE_TYPE interface_type,
-                                        VOID *interface ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       void *retaddr = __builtin_return_address ( 0 );
-       EFI_STATUS efirc;
-
-       DBGC ( colour, "InstallProtocolInterface ( %s, %s, %d, %p ) ",
-              efi_handle_name ( *handle ), efi_guid_ntoa ( protocol ),
-              interface_type, interface );
-       efirc = bs->InstallProtocolInterface ( handle, protocol, interface_type,
-                                              interface );
-       DBGC ( colour, "= %s ( %s ) -> %p\n",
-              efi_status ( efirc ), efi_handle_name ( *handle ), retaddr );
-       return efirc;
-}
-
-/**
- * Wrap ReinstallProtocolInterface()
- *
- */
-static EFI_STATUS EFIAPI
-efi_reinstall_protocol_interface_wrapper ( EFI_HANDLE handle,
-                                          EFI_GUID *protocol,
-                                          VOID *old_interface,
-                                          VOID *new_interface ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       void *retaddr = __builtin_return_address ( 0 );
-       EFI_STATUS efirc;
-
-       DBGC ( colour, "ReinstallProtocolInterface ( %s, %s, %p, %p ) ",
-              efi_handle_name ( handle ), efi_guid_ntoa ( protocol ),
-              old_interface, new_interface );
-       efirc = bs->ReinstallProtocolInterface ( handle, protocol,
-                                                old_interface, new_interface );
-       DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
-       return efirc;
-}
-
-/**
- * Wrap UninstallProtocolInterface()
- *
- */
-static EFI_STATUS EFIAPI
-efi_uninstall_protocol_interface_wrapper ( EFI_HANDLE handle,
-                                          EFI_GUID *protocol,
-                                          VOID *interface ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       void *retaddr = __builtin_return_address ( 0 );
-       EFI_STATUS efirc;
-
-       DBGC ( colour, "UninstallProtocolInterface ( %s, %s, %p ) ",
-              efi_handle_name ( handle ), efi_guid_ntoa ( protocol ),
-              interface );
-       efirc = bs->UninstallProtocolInterface ( handle, protocol, interface );
-       DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
-       return efirc;
-}
-
-/**
  * Wrap HandleProtocol()
  *
  */
@@ -186,7 +111,7 @@ efi_handle_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
        void *retaddr = __builtin_return_address ( 0 );
        EFI_STATUS efirc;
 
-       DBGC ( colour, "HandleProtocol ( %s, %s ) ",
+       DBGC ( colour, "HandleProtocol ( %p %s, %s, ... ) ", handle,
               efi_handle_name ( handle ), efi_guid_ntoa ( protocol ) );
        efirc = bs->HandleProtocol ( handle, protocol, interface );
        DBGC ( colour, "= %s ( %p ) -> %p\n",
@@ -204,26 +129,14 @@ efi_locate_handle_wrapper ( EFI_LOCATE_SEARCH_TYPE search_type,
                            UINTN *buffer_size, EFI_HANDLE *buffer ) {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        void *retaddr = __builtin_return_address ( 0 );
-       unsigned int i;
        EFI_STATUS efirc;
 
-       DBGC ( colour, "LocateHandle ( %s, %s, %p, %zd ) ",
-              efi_locate_search_type_name ( search_type ),
-              efi_guid_ntoa ( protocol ), search_key,
-              ( ( size_t ) *buffer_size ) );
+       DBGC ( colour, "LocateHandle ( %d, %s, ..., %zd, ... ) ", search_type,
+              efi_guid_ntoa ( protocol ), ( ( size_t ) *buffer_size ) );
        efirc = bs->LocateHandle ( search_type, protocol, search_key,
                                   buffer_size, buffer );
-       DBGC ( colour, "= %s ( %zd", efi_status ( efirc ),
-              ( ( size_t ) *buffer_size ) );
-       if ( efirc == 0 ) {
-               DBGC ( colour, ", {" );
-               for ( i = 0; i < ( *buffer_size / sizeof ( buffer[0] ) ); i++ ){
-                       DBGC ( colour, "%s%s", ( i ? ", " : " " ),
-                              efi_handle_name ( buffer[i] ) );
-               }
-               DBGC ( colour, " }" );
-       }
-       DBGC ( colour, " ) -> %p\n", retaddr );
+       DBGC ( colour, "= %s ( %zd ) -> %p\n",
+              efi_status ( efirc ), ( ( size_t ) *buffer_size ), retaddr );
        return efirc;
 }
 
@@ -239,12 +152,13 @@ efi_locate_device_path_wrapper ( EFI_GUID *protocol,
        void *retaddr = __builtin_return_address ( 0 );
        EFI_STATUS efirc;
 
-       DBGC ( colour, "LocateDevicePath ( %s, %s ) ",
+       DBGC ( colour, "LocateDevicePath ( %s, %s, ... ) ",
               efi_guid_ntoa ( protocol ), efi_devpath_text ( *device_path ) );
        efirc = bs->LocateDevicePath ( protocol, device_path, device );
-       DBGC ( colour, "= %s ( %s, ",
+       DBGC ( colour, "= %s ( %p, ",
               efi_status ( efirc ), efi_devpath_text ( *device_path ) );
-       DBGC ( colour, "%s ) -> %p\n", efi_handle_name ( *device ), retaddr );
+       DBGC ( colour, "%p %s ) -> %p\n",
+              *device, efi_handle_name ( *device ), retaddr );
        return efirc;
 }
 
@@ -261,16 +175,18 @@ efi_load_image_wrapper ( BOOLEAN boot_policy, EFI_HANDLE parent_image_handle,
        void *retaddr = __builtin_return_address ( 0 );
        EFI_STATUS efirc;
 
-       DBGC ( colour, "LoadImage ( %s, %s, ", efi_boolean ( boot_policy ),
-              efi_handle_name ( parent_image_handle ) );
-       DBGC ( colour, "%s, %p, %#llx ) ",
+       DBGC ( colour, "LoadImage ( %d, %p %s, ", boot_policy,
+              parent_image_handle, efi_handle_name ( parent_image_handle ) );
+       DBGC ( colour, "%s, %p, %#llx, ... ) ",
               efi_devpath_text ( device_path ), source_buffer,
               ( ( unsigned long long ) source_size ) );
        efirc = bs->LoadImage ( boot_policy, parent_image_handle, device_path,
                                source_buffer, source_size, image_handle );
        DBGC ( colour, "= %s ( ", efi_status ( efirc ) );
-       if ( efirc == 0 )
-               DBGC ( colour, "%s ", efi_handle_name ( *image_handle ) );
+       if ( efirc == 0 ) {
+               DBGC ( colour, "%p %s ", *image_handle,
+                      efi_handle_name ( *image_handle ) );
+       }
        DBGC ( colour, ") -> %p\n", retaddr );
 
        /* Wrap the new image */
@@ -281,69 +197,6 @@ efi_load_image_wrapper ( BOOLEAN boot_policy, EFI_HANDLE parent_image_handle,
 }
 
 /**
- * Wrap StartImage()
- *
- */
-static EFI_STATUS EFIAPI
-efi_start_image_wrapper ( EFI_HANDLE image_handle, UINTN *exit_data_size,
-                         CHAR16 **exit_data ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       void *retaddr = __builtin_return_address ( 0 );
-       EFI_STATUS efirc;
-
-       DBGC ( colour, "StartImage ( %s ) ", efi_handle_name ( image_handle ) );
-       efirc = bs->StartImage ( image_handle, exit_data_size, exit_data );
-       DBGC ( colour, "= %s", efi_status ( efirc ) );
-       if ( ( efirc != 0 ) && exit_data && *exit_data_size )
-               DBGC ( colour, " ( \"%ls\" )", *exit_data );
-       DBGC ( colour, " -> %p\n", retaddr );
-       if ( ( efirc != 0 ) && exit_data && *exit_data_size )
-               DBGC_HD ( colour, *exit_data, *exit_data_size );
-       return efirc;
-}
-
-/**
- * Wrap Exit()
- *
- */
-static EFI_STATUS EFIAPI
-efi_exit_wrapper ( EFI_HANDLE image_handle, EFI_STATUS exit_status,
-                  UINTN exit_data_size, CHAR16 *exit_data ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       void *retaddr = __builtin_return_address ( 0 );
-       EFI_STATUS efirc;
-
-       if ( ( exit_status != 0 ) && exit_data && exit_data_size )
-               DBGC_HD ( colour, exit_data, exit_data_size );
-       DBGC ( colour, "Exit ( %s, %s",
-              efi_handle_name ( image_handle ), efi_status ( exit_status ) );
-       if ( ( exit_status != 0 ) && exit_data && exit_data_size )
-               DBGC ( colour, ", \"%ls\"", exit_data );
-       DBGC ( colour, " ) " );
-       efirc = bs->Exit ( image_handle, exit_status, exit_data_size,
-                          exit_data );
-       DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
-       return efirc;
-}
-
-/**
- * Wrap UnloadImage()
- *
- */
-static EFI_STATUS EFIAPI
-efi_unload_image_wrapper ( EFI_HANDLE image_handle ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       void *retaddr = __builtin_return_address ( 0 );
-       EFI_STATUS efirc;
-
-       DBGC ( colour, "UnloadImage ( %s ) ",
-              efi_handle_name ( image_handle ) );
-       efirc = bs->UnloadImage ( image_handle );
-       DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
-       return efirc;
-}
-
-/**
  * Wrap ExitBootServices()
  *
  */
@@ -353,8 +206,8 @@ efi_exit_boot_services_wrapper ( EFI_HANDLE image_handle, UINTN map_key ) {
        void *retaddr = __builtin_return_address ( 0 );
        EFI_STATUS efirc;
 
-       DBGC ( colour, "ExitBootServices ( %s, %#llx ) ",
-              efi_handle_name ( image_handle ),
+       DBGC ( colour, "ExitBootServices ( %p %s, %#llx ) ",
+              image_handle, efi_handle_name ( image_handle ),
               ( ( unsigned long long ) map_key ) );
        efirc = bs->ExitBootServices ( image_handle, map_key );
        DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
@@ -362,60 +215,6 @@ efi_exit_boot_services_wrapper ( EFI_HANDLE image_handle, UINTN map_key ) {
 }
 
 /**
- * Wrap ConnectController()
- *
- */
-static EFI_STATUS EFIAPI
-efi_connect_controller_wrapper ( EFI_HANDLE controller_handle,
-                                EFI_HANDLE *driver_image_handle,
-                                EFI_DEVICE_PATH_PROTOCOL *remaining_path,
-                                BOOLEAN recursive ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       void *retaddr = __builtin_return_address ( 0 );
-       EFI_HANDLE *tmp;
-       EFI_STATUS efirc;
-
-       DBGC ( colour, "ConnectController ( %s, {",
-              efi_handle_name ( controller_handle ) );
-       if ( driver_image_handle ) {
-               for ( tmp = driver_image_handle ; *tmp ; tmp++ ) {
-                       DBGC ( colour, "%s%s",
-                              ( ( tmp == driver_image_handle ) ? " " : ", " ),
-                              efi_handle_name ( *tmp ) );
-               }
-       }
-       DBGC ( colour, " }, %s, %s ) ", efi_devpath_text ( remaining_path ),
-              efi_boolean ( recursive ) );
-       efirc = bs->ConnectController ( controller_handle, driver_image_handle,
-                                       remaining_path, recursive );
-       DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
-       return efirc;
-}
-
-/**
- * Wrap DisconnectController()
- *
- */
-static EFI_STATUS EFIAPI
-efi_disconnect_controller_wrapper ( EFI_HANDLE controller_handle,
-                                   EFI_HANDLE driver_image_handle,
-                                   EFI_HANDLE child_handle ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       void *retaddr = __builtin_return_address ( 0 );
-       EFI_STATUS efirc;
-
-       DBGC ( colour, "DisconnectController ( %s",
-              efi_handle_name ( controller_handle ) );
-       DBGC ( colour, ", %s", efi_handle_name ( driver_image_handle ) );
-       DBGC ( colour, ", %s ) ", efi_handle_name ( child_handle ) );
-       efirc = bs->DisconnectController ( controller_handle,
-                                          driver_image_handle,
-                                          child_handle );
-       DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
-       return efirc;
-}
-
-/**
  * Wrap OpenProtocol()
  *
  */
@@ -427,11 +226,12 @@ efi_open_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
        void *retaddr = __builtin_return_address ( 0 );
        EFI_STATUS efirc;
 
-       DBGC ( colour, "OpenProtocol ( %s, %s, ",
+       DBGC ( colour, "OpenProtocol ( %p %s, %s, ..., ", handle,
               efi_handle_name ( handle ), efi_guid_ntoa ( protocol ) );
-       DBGC ( colour, "%s, ", efi_handle_name ( agent_handle ) );
-       DBGC ( colour, "%s, %s ) ", efi_handle_name ( controller_handle ),
-              efi_open_attributes_name ( attributes ) );
+       DBGC ( colour, "%p %s, ", agent_handle,
+              efi_handle_name ( agent_handle ) );
+       DBGC ( colour, "%p %s, %#x ) ", controller_handle,
+              efi_handle_name ( controller_handle ), attributes );
        efirc = bs->OpenProtocol ( handle, protocol, interface, agent_handle,
                                   controller_handle, attributes );
        DBGC ( colour, "= %s ( %p ) -> %p\n",
@@ -440,90 +240,6 @@ efi_open_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
 }
 
 /**
- * Wrap CloseProtocol()
- *
- */
-static EFI_STATUS EFIAPI
-efi_close_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
-                            EFI_HANDLE agent_handle,
-                            EFI_HANDLE controller_handle ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       void *retaddr = __builtin_return_address ( 0 );
-       EFI_STATUS efirc;
-
-       DBGC ( colour, "CloseProtocol ( %s, %s, ",
-              efi_handle_name ( handle ), efi_guid_ntoa ( protocol ) );
-       DBGC ( colour, "%s, ", efi_handle_name ( agent_handle ) );
-       DBGC ( colour, "%s ) ", efi_handle_name ( controller_handle ) );
-       efirc = bs->CloseProtocol ( handle, protocol, agent_handle,
-                                   controller_handle );
-       DBGC ( colour, "= %s -> %p\n",
-              efi_status ( efirc ), retaddr );
-       return efirc;
-}
-
-/**
- * Wrap ProtocolsPerHandle()
- *
- */
-static EFI_STATUS EFIAPI
-efi_protocols_per_handle_wrapper ( EFI_HANDLE handle,
-                                  EFI_GUID ***protocol_buffer,
-                                  UINTN *protocol_buffer_count ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       void *retaddr = __builtin_return_address ( 0 );
-       unsigned int i;
-       EFI_STATUS efirc;
-
-       DBGC ( colour, "ProtocolsPerHandle ( %s ) ",
-              efi_handle_name ( handle ) );
-       efirc = bs->ProtocolsPerHandle ( handle, protocol_buffer,
-                                        protocol_buffer_count );
-       DBGC ( colour, "= %s", efi_status ( efirc ) );
-       if ( efirc == 0 ) {
-               DBGC ( colour, " ( {" );
-               for ( i = 0 ; i < *protocol_buffer_count ; i++ ) {
-                       DBGC ( colour, "%s%s", ( i ? ", " : " " ),
-                              efi_guid_ntoa ( (*protocol_buffer)[i] ) );
-               }
-               DBGC ( colour, " } )" );
-       }
-       DBGC ( colour, " -> %p\n", retaddr );
-       return efirc;
-}
-
-/**
- * Wrap LocateHandleBuffer()
- *
- */
-static EFI_STATUS EFIAPI
-efi_locate_handle_buffer_wrapper ( EFI_LOCATE_SEARCH_TYPE search_type,
-                                  EFI_GUID *protocol, VOID *search_key,
-                                  UINTN *no_handles, EFI_HANDLE **buffer ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       void *retaddr = __builtin_return_address ( 0 );
-       unsigned int i;
-       EFI_STATUS efirc;
-
-       DBGC ( colour, "LocateHandleBuffer ( %s, %s, %p ) ",
-              efi_locate_search_type_name ( search_type ),
-              efi_guid_ntoa ( protocol ), search_key );
-       efirc = bs->LocateHandleBuffer ( search_type, protocol, search_key,
-                                        no_handles, buffer );
-       DBGC ( colour, "= %s", efi_status ( efirc ) );
-       if ( efirc == 0 ) {
-               DBGC ( colour, " ( %d, {", ( ( unsigned int ) *no_handles ) );
-               for ( i = 0 ; i < *no_handles ; i++ ) {
-                       DBGC ( colour, "%s%s", ( i ? ", " : " " ),
-                              efi_handle_name ( (*buffer)[i] ) );
-               }
-               DBGC ( colour, " } )" );
-       }
-       DBGC ( colour, " -> %p\n", retaddr );
-       return efirc;
-}
-
-/**
  * Wrap LocateProtocol()
  *
  */
@@ -534,7 +250,7 @@ efi_locate_protocol_wrapper ( EFI_GUID *protocol, VOID *registration,
        void *retaddr = __builtin_return_address ( 0 );
        EFI_STATUS efirc;
 
-       DBGC ( colour, "LocateProtocol ( %s, %p ) ",
+       DBGC ( colour, "LocateProtocol ( %s, %p, ... ) ",
               efi_guid_ntoa ( protocol ), registration );
        efirc = bs->LocateProtocol ( protocol, registration, interface );
        DBGC ( colour, "= %s ( %p ) -> %p\n",
@@ -565,30 +281,12 @@ efi_locate_protocol_wrapper ( EFI_GUID *protocol, VOID *registration,
                 sizeof ( efi_systab_wrapper ) );
        memcpy ( &efi_bs_wrapper, bs, sizeof ( efi_bs_wrapper ) );
        efi_systab_wrapper.BootServices = &efi_bs_wrapper;
-       efi_bs_wrapper.InstallProtocolInterface
-               = efi_install_protocol_interface_wrapper;
-       efi_bs_wrapper.ReinstallProtocolInterface
-               = efi_reinstall_protocol_interface_wrapper;
-       efi_bs_wrapper.UninstallProtocolInterface
-               = efi_uninstall_protocol_interface_wrapper;
        efi_bs_wrapper.HandleProtocol   = efi_handle_protocol_wrapper;
        efi_bs_wrapper.LocateHandle     = efi_locate_handle_wrapper;
        efi_bs_wrapper.LocateDevicePath = efi_locate_device_path_wrapper;
        efi_bs_wrapper.LoadImage        = efi_load_image_wrapper;
-       efi_bs_wrapper.StartImage       = efi_start_image_wrapper;
-       efi_bs_wrapper.Exit             = efi_exit_wrapper;
-       efi_bs_wrapper.UnloadImage      = efi_unload_image_wrapper;
        efi_bs_wrapper.ExitBootServices = efi_exit_boot_services_wrapper;
-       efi_bs_wrapper.ConnectController
-               = efi_connect_controller_wrapper;
-       efi_bs_wrapper.DisconnectController
-               = efi_disconnect_controller_wrapper;
        efi_bs_wrapper.OpenProtocol     = efi_open_protocol_wrapper;
-       efi_bs_wrapper.CloseProtocol    = efi_close_protocol_wrapper;
-       efi_bs_wrapper.ProtocolsPerHandle
-               = efi_protocols_per_handle_wrapper;
-       efi_bs_wrapper.LocateHandleBuffer
-               = efi_locate_handle_buffer_wrapper;
        efi_bs_wrapper.LocateProtocol   = efi_locate_protocol_wrapper;
 
        /* Open loaded image protocol */
@@ -597,22 +295,23 @@ efi_locate_protocol_wrapper ( EFI_GUID *protocol, VOID *registration,
                                          &loaded.intf, efi_image_handle, NULL,
                                          EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
                rc = -EEFI ( efirc );
-               DBGC ( colour, "WRAP %s could not get loaded image protocol: "
-                      "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
+               DBGC ( colour, "Could not get loaded image protocol for %p %s: "
+                      "%s\n", handle, efi_handle_name ( handle ),
+                      strerror ( rc ) );
                return;
        }
 
        /* Provide system table wrapper to image */
        loaded.image->SystemTable = &efi_systab_wrapper;
-       DBGC ( colour, "WRAP %s at base %p has protocols:\n",
-              efi_handle_name ( handle ), loaded.image->ImageBase );
+       DBGC ( colour, "Wrapped image %p %s at base %p has protocols:\n",
+              handle, efi_handle_name ( handle ), loaded.image->ImageBase );
        DBGC_EFI_PROTOCOLS ( colour, handle );
-       DBGC ( colour, "WRAP %s parent", efi_handle_name ( handle ) );
-       DBGC ( colour, " %s\n", efi_handle_name ( loaded.image->ParentHandle ));
-       DBGC ( colour, "WRAP %s device", efi_handle_name ( handle ) );
-       DBGC ( colour, " %s\n", efi_handle_name ( loaded.image->DeviceHandle ));
-       DBGC ( colour, "WRAP %s file", efi_handle_name ( handle ) );
-       DBGC ( colour, " %s\n", efi_devpath_text ( loaded.image->FilePath ) );
+       DBGC ( colour, "Parent image %p %s\n", loaded.image->ParentHandle,
+              efi_handle_name ( loaded.image->ParentHandle ) );
+       DBGC ( colour, "Device %p %s ", loaded.image->DeviceHandle,
+              efi_handle_name ( loaded.image->DeviceHandle ) );
+       DBGC ( colour, "file %p %s\n", loaded.image->FilePath,
+              efi_devpath_text ( loaded.image->FilePath ) );
 
        /* Close loaded image protocol */
        bs->CloseProtocol ( handle, &efi_loaded_image_protocol_guid,
index fd809dd..795929e 100644 (file)
@@ -39,7 +39,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/nap.h>
 #include <ipxe/malloc.h>
 #include <ipxe/iobuf.h>
-#include <ipxe/bitops.h>
 #include <ipxe/hyperv.h>
 #include <ipxe/vmbus.h>
 
@@ -560,7 +559,7 @@ static void vmbus_signal_monitor ( struct vmbus_device *vmdev ) {
        group = ( vmdev->monitor / ( 8 * sizeof ( trigger->pending ) ));
        bit = ( vmdev->monitor % ( 8 * sizeof ( trigger->pending ) ) );
        trigger = &vmbus->monitor_out->trigger[group];
-       set_bit ( bit, trigger );
+       hv_set_bit ( trigger, bit );
 }
 
 /**
@@ -721,7 +720,7 @@ static int vmbus_send ( struct vmbus_device *vmdev,
                return 0;
 
        /* Set channel bit in interrupt page */
-       set_bit ( vmdev->channel, vmbus->intr->out );
+       hv_set_bit ( vmbus->intr->out, vmdev->channel );
 
        /* Signal the host */
        vmdev->signal ( vmdev );
index 2d571f2..5eadfa0 100644 (file)
@@ -248,7 +248,7 @@ const struct setting asset_setting __setting ( SETTING_HOST_EXTRA, asset ) = {
 
 /** Board serial number setting (may differ from chassis serial number) */
 const struct setting board_serial_setting __setting ( SETTING_HOST_EXTRA,
-                                                     board-serial ) = {
+                                                     board_serial ) = {
        .name = "board-serial",
        .description = "Base board serial",
        .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_BASE_BOARD_INFORMATION,
index 224bb69..7097b11 100644 (file)
@@ -6,5 +6,21 @@
 
 __libgcc int64_t __divdi3(int64_t num, int64_t den)
 {
-  return __divmoddi4(num, den, NULL);
+  int minus = 0;
+  int64_t v;
+
+  if ( num < 0 ) {
+    num = -num;
+    minus = 1;
+  }
+  if ( den < 0 ) {
+    den = -den;
+    minus ^= 1;
+  }
+
+  v = __udivmoddi4(num, den, NULL);
+  if ( minus )
+    v = -v;
+
+  return v;
 }
diff --git a/roms/ipxe/src/libgcc/__divmoddi4.c b/roms/ipxe/src/libgcc/__divmoddi4.c
deleted file mode 100644 (file)
index 95e328d..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#include "libgcc.h"
-
-__libgcc int64_t __divmoddi4(int64_t num, int64_t den, int64 *rem_p)
-{
-  int minus = 0;
-  int64_t v;
-
-  if ( num < 0 ) {
-    num = -num;
-    minus = 1;
-  }
-  if ( den < 0 ) {
-    den = -den;
-    minus ^= 1;
-  }
-
-  v = __udivmoddi4(num, den, (uint64_t *)rem_p);
-  if ( minus ) {
-    v = -v;
-    if ( rem_p )
-      *rem_p = -(*rem_p);
-  }
-
-  return v;
-}
index ea6fd6f..d671bbc 100644 (file)
@@ -6,8 +6,21 @@
 
 __libgcc int64_t __moddi3(int64_t num, int64_t den)
 {
+  int minus = 0;
   int64_t v;
 
-  (void) __divmoddi4(num, den, &v);
+  if ( num < 0 ) {
+    num = -num;
+    minus = 1;
+  }
+  if ( den < 0 ) {
+    den = -den;
+    minus ^= 1;
+  }
+
+  (void) __udivmoddi4(num, den, (uint64_t *)&v);
+  if ( minus )
+    v = -v;
+
   return v;
 }
diff --git a/roms/ipxe/src/libgcc/implicit.c b/roms/ipxe/src/libgcc/implicit.c
deleted file mode 100644 (file)
index 645ae6d..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/** @file
- *
- * gcc sometimes likes to insert implicit calls to memcpy() and
- * memset().  Unfortunately, there doesn't seem to be any way to
- * prevent it from doing this, or to force it to use the optimised
- * versions as seen by C code; it insists on inserting symbol
- * references to "memcpy" and "memset".  We therefore include wrapper
- * functions just to keep gcc happy.
- *
- */
-
-#include <string.h>
-
-void * gcc_implicit_memcpy ( void *dest, const void *src,
-                            size_t len ) asm ( "memcpy" );
-
-void * gcc_implicit_memcpy ( void *dest, const void *src, size_t len ) {
-       return memcpy ( dest, src, len );
-}
-
-void * gcc_implicit_memset ( void *dest, int character,
-                            size_t len ) asm ( "memset" );
-
-void * gcc_implicit_memset ( void *dest, int character, size_t len ) {
-       return memset ( dest, character, len );
-}
index eb7c68e..d3e9bdd 100644 (file)
@@ -8,7 +8,6 @@ extern __libgcc uint64_t __udivmoddi4 ( uint64_t num, uint64_t den,
                                        uint64_t *rem );
 extern __libgcc uint64_t __udivdi3  (uint64_t num, uint64_t den );
 extern __libgcc uint64_t __umoddi3 ( uint64_t num, uint64_t den );
-extern __libgcc int64_t __divmoddi4 ( int64_t num, int64_t den, int64_t *rem );
 extern __libgcc int64_t __divdi3 ( int64_t num, int64_t den );
 extern __libgcc int64_t __moddi3 ( int64_t num, int64_t den );
 
diff --git a/roms/ipxe/src/libgcc/memcpy.c b/roms/ipxe/src/libgcc/memcpy.c
new file mode 100644 (file)
index 0000000..e98b783
--- /dev/null
@@ -0,0 +1,18 @@
+/** @file
+ *
+ * gcc sometimes likes to insert implicit calls to memcpy().
+ * Unfortunately, there doesn't seem to be any way to prevent it from
+ * doing this, or to force it to use the optimised memcpy() as seen by
+ * C code; it insists on inserting a symbol reference to "memcpy".  We
+ * therefore include wrapper functions just to keep gcc happy.
+ *
+ */
+
+#include <string.h>
+
+void * gcc_implicit_memcpy ( void *dest, const void *src,
+                            size_t len ) asm ( "memcpy" );
+
+void * gcc_implicit_memcpy ( void *dest, const void *src, size_t len ) {
+       return memcpy ( dest, src, len );
+}
index c9b4109..1e27c44 100644 (file)
@@ -139,15 +139,8 @@ static int arp_rx ( struct io_buffer *iobuf, struct net_device *netdev,
        struct arp_net_protocol *arp_net_protocol;
        struct net_protocol *net_protocol;
        struct ll_protocol *ll_protocol;
-       size_t len = iob_len ( iobuf );
        int rc;
 
-       /* Sanity check */
-       if ( ( len < sizeof ( *arphdr ) ) || ( len < arp_len ( arphdr ) ) ) {
-               rc = -EINVAL;
-               goto done;
-       }
-
        /* Identify network-layer and link-layer protocols */
        arp_net_protocol = arp_find_protocol ( arphdr->ar_pro );
        if ( ! arp_net_protocol ) {
index 26fdede..6ddf053 100644 (file)
@@ -278,3 +278,6 @@ REQUIRING_SYMBOL ( ethernet_protocol );
 
 /* Drag in Ethernet configuration */
 REQUIRE_OBJECT ( config_ethernet );
+
+/* Drag in Ethernet slow protocols */
+REQUIRE_OBJECT ( eth_slow );
index 009b12c..b6c456a 100644 (file)
@@ -199,10 +199,6 @@ int create_fakepxebsack ( struct net_device *netdev,
                return rc;
        }
 
-       /* Populate ciaddr */
-       fetch_ipv4_setting ( netdev_settings ( netdev ), &ip_setting,
-                            &dhcppkt.dhcphdr->ciaddr );
-
        /* Merge in ProxyDHCP options */
        if ( proxy_settings &&
             ( ( rc = copy_settings ( &dhcppkt, proxy_settings ) ) != 0 ) ) {
index 15ff052..2e3d76d 100644 (file)
@@ -37,7 +37,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/netdevice.h>
 #include <ipxe/iobuf.h>
 #include <ipxe/process.h>
-#include <ipxe/profile.h>
 #include <ipxe/infiniband.h>
 #include <ipxe/ib_mi.h>
 #include <ipxe/ib_sma.h>
@@ -54,17 +53,6 @@ struct list_head ib_devices = LIST_HEAD_INIT ( ib_devices );
 /** List of open Infiniband devices, in reverse order of opening */
 static struct list_head open_ib_devices = LIST_HEAD_INIT ( open_ib_devices );
 
-/** Infiniband device index */
-static unsigned int ibdev_index = 0;
-
-/** Post send work queue entry profiler */
-static struct profiler ib_post_send_profiler __profiler =
-       { .name = "ib.post_send" };
-
-/** Post receive work queue entry profiler */
-static struct profiler ib_post_recv_profiler __profiler =
-       { .name = "ib.post_recv" };
-
 /* Disambiguate the various possible EINPROGRESSes */
 #define EINPROGRESS_INIT __einfo_error ( EINFO_EINPROGRESS_INIT )
 #define EINFO_EINPROGRESS_INIT __einfo_uniqify \
@@ -100,27 +88,27 @@ ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
        struct ib_completion_queue *cq;
        int rc;
 
-       DBGC ( ibdev, "IBDEV %s creating completion queue\n", ibdev->name );
+       DBGC ( ibdev, "IBDEV %p creating completion queue\n", ibdev );
 
        /* Allocate and initialise data structure */
        cq = zalloc ( sizeof ( *cq ) );
        if ( ! cq )
                goto err_alloc_cq;
        cq->ibdev = ibdev;
-       list_add_tail ( &cq->list, &ibdev->cqs );
+       list_add ( &cq->list, &ibdev->cqs );
        cq->num_cqes = num_cqes;
        INIT_LIST_HEAD ( &cq->work_queues );
        cq->op = op;
 
        /* Perform device-specific initialisation and get CQN */
        if ( ( rc = ibdev->op->create_cq ( ibdev, cq ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s could not initialise completion "
-                      "queue: %s\n", ibdev->name, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p could not initialise completion "
+                      "queue: %s\n", ibdev, strerror ( rc ) );
                goto err_dev_create_cq;
        }
 
-       DBGC ( ibdev, "IBDEV %s created %d-entry completion queue %p (%p) "
-              "with CQN %#lx\n", ibdev->name, num_cqes, cq,
+       DBGC ( ibdev, "IBDEV %p created %d-entry completion queue %p (%p) "
+              "with CQN %#lx\n", ibdev, num_cqes, cq,
               ib_cq_get_drvdata ( cq ), cq->cqn );
        return cq;
 
@@ -140,8 +128,8 @@ ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
  */
 void ib_destroy_cq ( struct ib_device *ibdev,
                     struct ib_completion_queue *cq ) {
-       DBGC ( ibdev, "IBDEV %s destroying completion queue %#lx\n",
-              ibdev->name, cq->cqn );
+       DBGC ( ibdev, "IBDEV %p destroying completion queue %#lx\n",
+              ibdev, cq->cqn );
        assert ( list_empty ( &cq->work_queues ) );
        ibdev->op->destroy_cq ( ibdev, cq );
        list_del ( &cq->list );
@@ -185,7 +173,6 @@ void ib_poll_cq ( struct ib_device *ibdev,
  * @v num_recv_wqes    Number of receive work queue entries
  * @v recv_cq          Receive completion queue
  * @v op               Queue pair operations
- * @v name             Queue pair name
  * @ret qp             Queue pair
  *
  * The queue pair will be left in the INIT state; you must call
@@ -197,13 +184,12 @@ struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev,
                                      struct ib_completion_queue *send_cq,
                                      unsigned int num_recv_wqes,
                                      struct ib_completion_queue *recv_cq,
-                                     struct ib_queue_pair_operations *op,
-                                     const char *name ) {
+                                     struct ib_queue_pair_operations *op ) {
        struct ib_queue_pair *qp;
        size_t total_size;
        int rc;
 
-       DBGC ( ibdev, "IBDEV %s creating queue pair\n", ibdev->name );
+       DBGC ( ibdev, "IBDEV %p creating queue pair\n", ibdev );
 
        /* Allocate and initialise data structure */
        total_size = ( sizeof ( *qp ) +
@@ -213,39 +199,38 @@ struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev,
        if ( ! qp )
                goto err_alloc_qp;
        qp->ibdev = ibdev;
-       list_add_tail ( &qp->list, &ibdev->qps );
+       list_add ( &qp->list, &ibdev->qps );
        qp->type = type;
        qp->send.qp = qp;
        qp->send.is_send = 1;
        qp->send.cq = send_cq;
-       list_add_tail ( &qp->send.list, &send_cq->work_queues );
+       list_add ( &qp->send.list, &send_cq->work_queues );
        qp->send.psn = ( random() & 0xffffffUL );
        qp->send.num_wqes = num_send_wqes;
        qp->send.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) );
        qp->recv.qp = qp;
        qp->recv.cq = recv_cq;
-       list_add_tail ( &qp->recv.list, &recv_cq->work_queues );
+       list_add ( &qp->recv.list, &recv_cq->work_queues );
        qp->recv.psn = ( random() & 0xffffffUL );
        qp->recv.num_wqes = num_recv_wqes;
        qp->recv.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) +
                            ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) ));
        INIT_LIST_HEAD ( &qp->mgids );
        qp->op = op;
-       qp->name = name;
 
        /* Perform device-specific initialisation and get QPN */
        if ( ( rc = ibdev->op->create_qp ( ibdev, qp ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s could not initialise queue pair: "
-                      "%s\n", ibdev->name, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p could not initialise queue pair: "
+                      "%s\n", ibdev, strerror ( rc ) );
                goto err_dev_create_qp;
        }
-       DBGC ( ibdev, "IBDEV %s created queue pair %p (%p) with QPN %#lx\n",
-              ibdev->name, qp, ib_qp_get_drvdata ( qp ), qp->qpn );
-       DBGC ( ibdev, "IBDEV %s QPN %#lx has %d send entries at [%p,%p)\n",
-              ibdev->name, qp->qpn, num_send_wqes, qp->send.iobufs,
+       DBGC ( ibdev, "IBDEV %p created queue pair %p (%p) with QPN %#lx\n",
+              ibdev, qp, ib_qp_get_drvdata ( qp ), qp->qpn );
+       DBGC ( ibdev, "IBDEV %p QPN %#lx has %d send entries at [%p,%p)\n",
+              ibdev, qp->qpn, num_send_wqes, qp->send.iobufs,
               qp->recv.iobufs );
-       DBGC ( ibdev, "IBDEV %s QPN %#lx has %d receive entries at [%p,%p)\n",
-              ibdev->name, qp->qpn, num_recv_wqes, qp->recv.iobufs,
+       DBGC ( ibdev, "IBDEV %p QPN %#lx has %d receive entries at [%p,%p)\n",
+              ibdev, qp->qpn, num_recv_wqes, qp->recv.iobufs,
               ( ( ( void * ) qp ) + total_size ) );
 
        /* Calculate externally-visible QPN */
@@ -261,8 +246,8 @@ struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev,
                break;
        }
        if ( qp->ext_qpn != qp->qpn ) {
-               DBGC ( ibdev, "IBDEV %s QPN %#lx has external QPN %#lx\n",
-                      ibdev->name, qp->qpn, qp->ext_qpn );
+               DBGC ( ibdev, "IBDEV %p QPN %#lx has external QPN %#lx\n",
+                      ibdev, qp->qpn, qp->ext_qpn );
        }
 
        return qp;
@@ -287,11 +272,11 @@ struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev,
 int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
        int rc;
 
-       DBGC ( ibdev, "IBDEV %s modifying QPN %#lx\n", ibdev->name, qp->qpn );
+       DBGC ( ibdev, "IBDEV %p modifying QPN %#lx\n", ibdev, qp->qpn );
 
        if ( ( rc = ibdev->op->modify_qp ( ibdev, qp ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s could not modify QPN %#lx: %s\n",
-                      ibdev->name, qp->qpn, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p could not modify QPN %#lx: %s\n",
+                      ibdev, qp->qpn, strerror ( rc ) );
                return rc;
        }
 
@@ -308,8 +293,8 @@ void ib_destroy_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
        struct io_buffer *iobuf;
        unsigned int i;
 
-       DBGC ( ibdev, "IBDEV %s destroying QPN %#lx\n",
-              ibdev->name, qp->qpn );
+       DBGC ( ibdev, "IBDEV %p destroying QPN %#lx\n",
+              ibdev, qp->qpn );
 
        assert ( list_empty ( &qp->mgids ) );
 
@@ -412,13 +397,10 @@ int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
        struct ib_address_vector dest_copy;
        int rc;
 
-       /* Start profiling */
-       profile_start ( &ib_post_send_profiler );
-
        /* Check queue fill level */
        if ( qp->send.fill >= qp->send.num_wqes ) {
-               DBGC ( ibdev, "IBDEV %s QPN %#lx send queue full\n",
-                      ibdev->name, qp->qpn );
+               DBGC ( ibdev, "IBDEV %p QPN %#lx send queue full\n",
+                      ibdev, qp->qpn );
                return -ENOBUFS;
        }
 
@@ -438,17 +420,12 @@ int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
 
        /* Post to hardware */
        if ( ( rc = ibdev->op->post_send ( ibdev, qp, dest, iobuf ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s QPN %#lx could not post send WQE: "
-                      "%s\n", ibdev->name, qp->qpn, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p QPN %#lx could not post send WQE: "
+                      "%s\n", ibdev, qp->qpn, strerror ( rc ) );
                return rc;
        }
 
-       /* Increase fill level */
        qp->send.fill++;
-
-       /* Stop profiling */
-       profile_stop ( &ib_post_send_profiler );
-
        return 0;
 }
 
@@ -464,36 +441,28 @@ int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
                   struct io_buffer *iobuf ) {
        int rc;
 
-       /* Start profiling */
-       profile_start ( &ib_post_recv_profiler );
-
        /* Check packet length */
        if ( iob_tailroom ( iobuf ) < IB_MAX_PAYLOAD_SIZE ) {
-               DBGC ( ibdev, "IBDEV %s QPN %#lx wrong RX buffer size (%zd)\n",
-                      ibdev->name, qp->qpn, iob_tailroom ( iobuf ) );
+               DBGC ( ibdev, "IBDEV %p QPN %#lx wrong RX buffer size (%zd)\n",
+                      ibdev, qp->qpn, iob_tailroom ( iobuf ) );
                return -EINVAL;
        }
 
        /* Check queue fill level */
        if ( qp->recv.fill >= qp->recv.num_wqes ) {
-               DBGC ( ibdev, "IBDEV %s QPN %#lx receive queue full\n",
-                      ibdev->name, qp->qpn );
+               DBGC ( ibdev, "IBDEV %p QPN %#lx receive queue full\n",
+                      ibdev, qp->qpn );
                return -ENOBUFS;
        }
 
        /* Post to hardware */
        if ( ( rc = ibdev->op->post_recv ( ibdev, qp, iobuf ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s QPN %#lx could not post receive WQE: "
-                      "%s\n", ibdev->name, qp->qpn, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p QPN %#lx could not post receive WQE: "
+                      "%s\n", ibdev, qp->qpn, strerror ( rc ) );
                return rc;
        }
 
-       /* Increase fill level */
        qp->recv.fill++;
-
-       /* Stop profiling */
-       profile_stop ( &ib_post_recv_profiler );
-
        return 0;
 }
 
@@ -562,8 +531,8 @@ void ib_refill_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
 
                /* Post I/O buffer */
                if ( ( rc = ib_post_recv ( ibdev, qp, iobuf ) ) != 0 ) {
-                       DBGC ( ibdev, "IBDEV %s could not refill: %s\n",
-                              ibdev->name, strerror ( rc ) );
+                       DBGC ( ibdev, "IBDEV %p could not refill: %s\n",
+                              ibdev, strerror ( rc ) );
                        free_iob ( iobuf );
                        /* Give up */
                        return;
@@ -629,8 +598,8 @@ static void ib_notify ( struct ib_device *ibdev ) {
  */
 void ib_link_state_changed ( struct ib_device *ibdev ) {
 
-       DBGC ( ibdev, "IBDEV %s link state is %s\n",
-              ibdev->name, ib_link_state_text ( ibdev ) );
+       DBGC ( ibdev, "IBDEV %p link state is %s\n",
+              ibdev, ib_link_state_text ( ibdev ) );
 
        /* Notify drivers of link state change */
        ib_notify ( ibdev );
@@ -653,30 +622,30 @@ int ib_open ( struct ib_device *ibdev ) {
 
        /* Open device */
        if ( ( rc = ibdev->op->open ( ibdev ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s could not open: %s\n",
-                      ibdev->name, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p could not open: %s\n",
+                      ibdev, strerror ( rc ) );
                goto err_open;
        }
 
        /* Create subnet management interface */
        ibdev->smi = ib_create_mi ( ibdev, IB_QPT_SMI );
        if ( ! ibdev->smi ) {
-               DBGC ( ibdev, "IBDEV %s could not create SMI\n", ibdev->name );
+               DBGC ( ibdev, "IBDEV %p could not create SMI\n", ibdev );
                rc = -ENOMEM;
                goto err_create_smi;
        }
 
        /* Create subnet management agent */
        if ( ( rc = ib_create_sma ( ibdev, ibdev->smi ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s could not create SMA: %s\n",
-                      ibdev->name, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p could not create SMA: %s\n",
+                      ibdev, strerror ( rc ) );
                goto err_create_sma;
        }
 
        /* Create general services interface */
        ibdev->gsi = ib_create_mi ( ibdev, IB_QPT_GSI );
        if ( ! ibdev->gsi ) {
-               DBGC ( ibdev, "IBDEV %s could not create GSI\n", ibdev->name );
+               DBGC ( ibdev, "IBDEV %p could not create GSI\n", ibdev );
                rc = -ENOMEM;
                goto err_create_gsi;
        }
@@ -759,7 +728,7 @@ int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
                goto err_alloc_mgid;
        }
        memcpy ( &mgid->gid, gid, sizeof ( mgid->gid ) );
-       list_add_tail ( &mgid->list, &qp->mgids );
+       list_add ( &mgid->list, &qp->mgids );
 
        /* Add to hardware multicast GID list */
        if ( ( rc = ibdev->op->mcast_attach ( ibdev, qp, gid ) ) != 0 )
@@ -839,14 +808,14 @@ int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad ) {
 
        /* Adapters with embedded SMAs do not need to support this method */
        if ( ! ibdev->op->set_port_info ) {
-               DBGC ( ibdev, "IBDEV %s does not support setting port "
-                      "information\n", ibdev->name );
+               DBGC ( ibdev, "IBDEV %p does not support setting port "
+                      "information\n", ibdev );
                return -ENOTSUP;
        }
 
        if ( ( rc = ibdev->op->set_port_info ( ibdev, mad ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s could not set port information: %s\n",
-                      ibdev->name, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p could not set port information: %s\n",
+                      ibdev, strerror ( rc ) );
                return rc;
        }
 
@@ -864,14 +833,14 @@ int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad ) {
 
        /* Adapters with embedded SMAs do not need to support this method */
        if ( ! ibdev->op->set_pkey_table ) {
-               DBGC ( ibdev, "IBDEV %s does not support setting partition "
-                      "key table\n", ibdev->name );
+               DBGC ( ibdev, "IBDEV %p does not support setting partition "
+                      "key table\n", ibdev );
                return -ENOTSUP;
        }
 
        if ( ( rc = ibdev->op->set_pkey_table ( ibdev, mad ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s could not set partition key table: "
-                      "%s\n", ibdev->name, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p could not set partition key table: "
+                      "%s\n", ibdev, strerror ( rc ) );
                return rc;
        }
 
@@ -960,24 +929,17 @@ int register_ibdev ( struct ib_device *ibdev ) {
        struct ib_driver *driver;
        int rc;
 
-       /* Record device index and create device name */
-       if ( ibdev->name[0] == '\0' ) {
-               snprintf ( ibdev->name, sizeof ( ibdev->name ), "inf%d",
-                          ibdev_index );
-       }
-       ibdev->index = ++ibdev_index;
-
        /* Add to device list */
        ibdev_get ( ibdev );
        list_add_tail ( &ibdev->list, &ib_devices );
-       DBGC ( ibdev, "IBDEV %s registered (phys %s)\n", ibdev->name,
+       DBGC ( ibdev, "IBDEV %p registered (phys %s)\n", ibdev,
               ibdev->dev->name );
 
        /* Probe device */
        for_each_table_entry ( driver, IB_DRIVERS ) {
                if ( ( rc = driver->probe ( ibdev ) ) != 0 ) {
-                       DBGC ( ibdev, "IBDEV %s could not add %s device: %s\n",
-                              ibdev->name, driver->name, strerror ( rc ) );
+                       DBGC ( ibdev, "IBDEV %p could not add %s device: %s\n",
+                              ibdev, driver->name, strerror ( rc ) );
                        goto err_probe;
                }
        }
@@ -1007,11 +969,7 @@ void unregister_ibdev ( struct ib_device *ibdev ) {
        /* Remove from device list */
        list_del ( &ibdev->list );
        ibdev_put ( ibdev );
-       DBGC ( ibdev, "IBDEV %s unregistered\n", ibdev->name );
-
-       /* Reset device index if no devices remain */
-       if ( list_empty ( &ib_devices ) )
-               ibdev_index = 0;
+       DBGC ( ibdev, "IBDEV %p unregistered\n", ibdev );
 }
 
 /**
@@ -1052,3 +1010,6 @@ REQUIRING_SYMBOL ( register_ibdev );
 
 /* Drag in Infiniband configuration */
 REQUIRE_OBJECT ( config_infiniband );
+
+/* Drag in IPoIB */
+REQUIRE_OBJECT ( ipoib );
index 247b8e7..85982f0 100644 (file)
@@ -65,7 +65,6 @@ static struct ib_connection * ib_cm_find ( uint32_t local_id ) {
  *
  * @v ibdev            Infiniband device
  * @v mi               Management interface
- * @v tid              Transaction identifier
  * @v av               Address vector
  * @v local_id         Local communication ID
  * @v remote_id                Remote communication ID
@@ -73,7 +72,6 @@ static struct ib_connection * ib_cm_find ( uint32_t local_id ) {
  */
 static int ib_cm_send_rtu ( struct ib_device *ibdev,
                            struct ib_mad_interface *mi,
-                           struct ib_mad_tid *tid,
                            struct ib_address_vector *av,
                            uint32_t local_id, uint32_t remote_id ) {
        union ib_mad mad;
@@ -85,13 +83,11 @@ static int ib_cm_send_rtu ( struct ib_device *ibdev,
        mad.hdr.mgmt_class = IB_MGMT_CLASS_CM;
        mad.hdr.class_version = IB_CM_CLASS_VERSION;
        mad.hdr.method = IB_MGMT_METHOD_SEND;
-       memcpy ( &mad.hdr.tid, tid, sizeof ( mad.hdr.tid ) );
        mad.hdr.attr_id = htons ( IB_CM_ATTR_READY_TO_USE );
        rtu->local_id = htonl ( local_id );
        rtu->remote_id = htonl ( remote_id );
-       if ( ( rc = ib_mi_send ( ibdev, mi, &mad, av ) ) != 0 ) {
-               DBGC ( local_id, "CM %08x could not send RTU: %s\n",
-                      local_id, strerror ( rc ) );
+       if ( ( rc = ib_mi_send ( ibdev, mi, &mad, av ) ) != 0 ){
+               DBG ( "CM could not send RTU: %s\n", strerror ( rc ) );
                return rc;
        }
 
@@ -124,13 +120,12 @@ static void ib_cm_recv_rep ( struct ib_device *ibdev,
        conn = ib_cm_find ( local_id );
        if ( conn ) {
                /* Try to send "ready to use" reply */
-               if ( ( rc = ib_cm_send_rtu ( ibdev, mi, &mad->hdr.tid, av,
-                                            conn->local_id,
+               if ( ( rc = ib_cm_send_rtu ( ibdev, mi, av, conn->local_id,
                                             conn->remote_id ) ) != 0 ) {
                        /* Ignore errors; the remote end will retry */
                }
        } else {
-               DBGC ( local_id, "CM %08x unexpected REP\n", local_id );
+               DBG ( "CM unidentified connection %08x\n", local_id );
        }
 }
 
@@ -139,7 +134,6 @@ static void ib_cm_recv_rep ( struct ib_device *ibdev,
  *
  * @v ibdev            Infiniband device
  * @v mi               Management interface
- * @v tid              Transaction identifier
  * @v av               Address vector
  * @v local_id         Local communication ID
  * @v remote_id                Remote communication ID
@@ -147,7 +141,6 @@ static void ib_cm_recv_rep ( struct ib_device *ibdev,
  */
 static int ib_cm_send_drep ( struct ib_device *ibdev,
                             struct ib_mad_interface *mi,
-                            struct ib_mad_tid *tid,
                             struct ib_address_vector *av,
                             uint32_t local_id, uint32_t remote_id ) {
        union ib_mad mad;
@@ -159,13 +152,11 @@ static int ib_cm_send_drep ( struct ib_device *ibdev,
        mad.hdr.mgmt_class = IB_MGMT_CLASS_CM;
        mad.hdr.class_version = IB_CM_CLASS_VERSION;
        mad.hdr.method = IB_MGMT_METHOD_SEND;
-       memcpy ( &mad.hdr.tid, tid, sizeof ( mad.hdr.tid ) );
        mad.hdr.attr_id = htons ( IB_CM_ATTR_DISCONNECT_REPLY );
        drep->local_id = htonl ( local_id );
        drep->remote_id = htonl ( remote_id );
-       if ( ( rc = ib_mi_send ( ibdev, mi, &mad, av ) ) != 0 ) {
-               DBGC ( local_id, "CM %08x could not send DREP: %s\n",
-                      local_id, strerror ( rc ) );
+       if ( ( rc = ib_mi_send ( ibdev, mi, &mad, av ) ) != 0 ){
+               DBG ( "CM could not send DREP: %s\n", strerror ( rc ) );
                return rc;
        }
 
@@ -200,11 +191,11 @@ static void ib_cm_recv_dreq ( struct ib_device *ibdev,
                                    &dreq->private_data,
                                    sizeof ( dreq->private_data ) );
        } else {
-               DBGC ( local_id, "CM %08x unexpected DREQ\n", local_id );
+               DBG ( "CM unidentified connection %08x\n", local_id );
        }
 
        /* Send reply */
-       if ( ( rc = ib_cm_send_drep ( ibdev, mi, &mad->hdr.tid, av, local_id,
+       if ( ( rc = ib_cm_send_drep ( ibdev, mi, av, local_id,
                                      remote_id ) ) != 0 ) {
                /* Ignore errors; the remote end will retry */
        }
@@ -265,7 +256,6 @@ static void ib_cm_req_complete ( struct ib_device *ibdev,
        struct ib_cm_common *common = &mad->cm.cm_data.common;
        struct ib_cm_connect_reply *rep = &mad->cm.cm_data.connect_reply;
        struct ib_cm_connect_reject *rej = &mad->cm.cm_data.connect_reject;
-       uint32_t local_id = conn->local_id;
        void *private_data = NULL;
        size_t private_data_len = 0;
 
@@ -273,8 +263,8 @@ static void ib_cm_req_complete ( struct ib_device *ibdev,
        if ( ( rc == 0 ) && ( mad->hdr.status != htons ( IB_MGMT_STATUS_OK ) ))
                rc = -EIO;
        if ( rc != 0 ) {
-               DBGC ( local_id, "CM %08x connection request failed: %s\n",
-                      local_id, strerror ( rc ) );
+               DBGC ( conn, "CM %p connection request failed: %s\n",
+                      conn, strerror ( rc ) );
                goto out;
        }
 
@@ -290,19 +280,18 @@ static void ib_cm_req_complete ( struct ib_device *ibdev,
                qp->send.psn = ( ntohl ( rep->starting_psn ) >> 8 );
                private_data = &rep->private_data;
                private_data_len = sizeof ( rep->private_data );
-               DBGC ( local_id, "CM %08x connected to QPN %#lx PSN %#x\n",
-                      local_id, qp->av.qpn, qp->send.psn );
+               DBGC ( conn, "CM %p connected to QPN %lx PSN %x\n",
+                      conn, qp->av.qpn, qp->send.psn );
 
                /* Modify queue pair */
                if ( ( rc = ib_modify_qp ( ibdev, qp ) ) != 0 ) {
-                       DBGC ( local_id, "CM %08x could not modify queue "
-                              "pair: %s\n", local_id, strerror ( rc ) );
+                       DBGC ( conn, "CM %p could not modify queue pair: %s\n",
+                              conn, strerror ( rc ) );
                        goto out;
                }
 
                /* Send "ready to use" reply */
-               if ( ( rc = ib_cm_send_rtu ( ibdev, mi, &mad->hdr.tid, av,
-                                            conn->local_id,
+               if ( ( rc = ib_cm_send_rtu ( ibdev, mi, av, conn->local_id,
                                             conn->remote_id ) ) != 0 ) {
                        /* Treat as non-fatal */
                        rc = 0;
@@ -311,8 +300,8 @@ static void ib_cm_req_complete ( struct ib_device *ibdev,
 
        case htons ( IB_CM_ATTR_CONNECT_REJECT ) :
                /* Extract fields */
-               DBGC ( local_id, "CM %08x connection rejected (reason %d)\n",
-                      local_id, ntohs ( rej->reason ) );
+               DBGC ( conn, "CM %p connection rejected (reason %d)\n",
+                      conn, ntohs ( rej->reason ) );
                /* Private data is valid only for a Consumer Reject */
                if ( rej->reason == htons ( IB_CM_REJECT_CONSUMER ) ) {
                        private_data = &rej->private_data;
@@ -322,8 +311,8 @@ static void ib_cm_req_complete ( struct ib_device *ibdev,
                break;
 
        default:
-               DBGC ( local_id, "CM %08x unexpected response (attribute "
-                      "%04x)\n", local_id, ntohs ( mad->hdr.attr_id ) );
+               DBGC ( conn, "CM %p unexpected response (attribute %04x)\n",
+                      conn, ntohs ( mad->hdr.attr_id ) );
                rc = -ENOTSUP;
                break;
        }
@@ -358,13 +347,12 @@ static void ib_cm_path_complete ( struct ib_device *ibdev,
        struct ib_queue_pair *qp = conn->qp;
        union ib_mad mad;
        struct ib_cm_connect_request *req = &mad.cm.cm_data.connect_request;
-       uint32_t local_id = conn->local_id;
        size_t private_data_len;
 
        /* Report failures */
        if ( rc != 0 ) {
-               DBGC ( local_id, "CM %08x path lookup failed: %s\n",
-                      local_id, strerror ( rc ) );
+               DBGC ( conn, "CM %p path lookup failed: %s\n",
+                      conn, strerror ( rc ) );
                conn->op->changed ( ibdev, qp, conn, rc, NULL, 0 );
                goto out;
        }
@@ -417,8 +405,8 @@ static void ib_cm_path_complete ( struct ib_device *ibdev,
        conn->madx = ib_create_madx ( ibdev, ibdev->gsi, &mad, av,
                                      &ib_cm_req_op );
        if ( ! conn->madx ) {
-               DBGC ( local_id, "CM %08x could not create connection "
-                      "request\n", local_id );
+               DBGC ( conn, "CM %p could not create connection request\n",
+                      conn );
                conn->op->changed ( ibdev, qp, conn, rc, NULL, 0 );
                goto out;
        }
@@ -453,7 +441,6 @@ ib_create_conn ( struct ib_device *ibdev, struct ib_queue_pair *qp,
                 void *private_data, size_t private_data_len,
                 struct ib_connection_operations *op ) {
        struct ib_connection *conn;
-       uint32_t local_id;
 
        /* Allocate and initialise request */
        conn = zalloc ( sizeof ( *conn ) + private_data_len );
@@ -464,7 +451,7 @@ ib_create_conn ( struct ib_device *ibdev, struct ib_queue_pair *qp,
        memset ( &qp->av, 0, sizeof ( qp->av ) );
        qp->av.gid_present = 1;
        memcpy ( &qp->av.gid, dgid, sizeof ( qp->av.gid ) );
-       conn->local_id = local_id = random();
+       conn->local_id = random();
        memcpy ( &conn->service_id, service_id, sizeof ( conn->service_id ) );
        conn->op = op;
        conn->private_data_len = private_data_len;
@@ -479,11 +466,10 @@ ib_create_conn ( struct ib_device *ibdev, struct ib_queue_pair *qp,
        /* Add to list of connections */
        list_add ( &conn->list, &ib_cm_conns );
 
-       DBGC ( local_id, "CM %08x created for IBDEV %s QPN %#lx\n",
-              local_id, ibdev->name, qp->qpn );
-       DBGC ( local_id, "CM %08x connecting to " IB_GID_FMT " "
-              IB_GUID_FMT "\n", local_id, IB_GID_ARGS ( dgid ),
-              IB_GUID_ARGS ( service_id ) );
+       DBGC ( conn, "CM %p created for IBDEV %p QPN %lx\n",
+              conn, ibdev, qp->qpn );
+       DBGC ( conn, "CM %p connecting to " IB_GID_FMT " " IB_GUID_FMT "\n",
+              conn, IB_GID_ARGS ( dgid ), IB_GUID_ARGS ( service_id ) );
 
        return conn;
 
index 2cd4901..1cc0fcf 100644 (file)
@@ -69,8 +69,6 @@ FILE_LICENCE ( BSD2 );
 struct ib_cmrc_connection {
        /** Reference count */
        struct refcnt refcnt;
-       /** Name */
-       const char *name;
        /** Data transfer interface */
        struct interface xfer;
        /** Infiniband device */
@@ -110,19 +108,14 @@ struct ib_cmrc_connection {
  * shutdown process has run.
  */
 static void ib_cmrc_shutdown ( struct ib_cmrc_connection *cmrc ) {
-       struct ib_device *ibdev = cmrc->ibdev;
 
-       DBGC ( cmrc, "CMRC %s %s shutting down\n",
-              ibdev->name, cmrc->name );
+       DBGC ( cmrc, "CMRC %p shutting down\n", cmrc );
 
        /* Shut down Infiniband interface */
-       ib_destroy_conn ( ibdev, cmrc->qp, cmrc->conn );
-       ib_destroy_qp ( ibdev, cmrc->qp );
-       ib_destroy_cq ( ibdev, cmrc->cq );
-       ib_close ( ibdev );
-
-       /* Cancel any pending shutdown */
-       process_del ( &cmrc->shutdown );
+       ib_destroy_conn ( cmrc->ibdev, cmrc->qp, cmrc->conn );
+       ib_destroy_qp ( cmrc->ibdev, cmrc->qp );
+       ib_destroy_cq ( cmrc->ibdev, cmrc->cq );
+       ib_close ( cmrc->ibdev );
 
        /* Drop the remaining reference */
        ref_put ( &cmrc->refcnt );
@@ -153,7 +146,7 @@ static void ib_cmrc_close ( struct ib_cmrc_connection *cmrc, int rc ) {
  * @v private_data     Private data, if available
  * @v private_data_len Length of private data
  */
-static void ib_cmrc_changed ( struct ib_device *ibdev,
+static void ib_cmrc_changed ( struct ib_device *ibdev __unused,
                              struct ib_queue_pair *qp,
                              struct ib_connection *conn __unused, int rc_cm,
                              void *private_data, size_t private_data_len ) {
@@ -162,24 +155,22 @@ static void ib_cmrc_changed ( struct ib_device *ibdev,
 
        /* Record connection status */
        if ( rc_cm == 0 ) {
-               DBGC ( cmrc, "CMRC %s %s connected\n",
-                      ibdev->name, cmrc->name );
+               DBGC ( cmrc, "CMRC %p connected\n", cmrc );
                cmrc->connected = 1;
        } else {
-               DBGC ( cmrc, "CMRC %s %s disconnected: %s\n",
-                      ibdev->name, cmrc->name, strerror ( rc_cm ) );
+               DBGC ( cmrc, "CMRC %p disconnected: %s\n",
+                      cmrc, strerror ( rc_cm ) );
                cmrc->connected = 0;
        }
 
        /* Pass up any private data */
-       DBGC2 ( cmrc, "CMRC %s %s received private data:\n",
-               ibdev->name, cmrc->name );
+       DBGC2 ( cmrc, "CMRC %p received private data:\n", cmrc );
        DBGC2_HDA ( cmrc, 0, private_data, private_data_len );
        if ( private_data &&
             ( rc_xfer = xfer_deliver_raw ( &cmrc->xfer, private_data,
                                            private_data_len ) ) != 0 ) {
-               DBGC ( cmrc, "CMRC %s %s could not deliver private data: %s\n",
-                      ibdev->name, cmrc->name, strerror ( rc_xfer ) );
+               DBGC ( cmrc, "CMRC %p could not deliver private data: %s\n",
+                      cmrc, strerror ( rc_xfer ) );
                ib_cmrc_close ( cmrc, rc_xfer );
                return;
        }
@@ -207,7 +198,7 @@ static struct ib_connection_operations ib_cmrc_conn_op = {
  * @v iobuf            I/O buffer
  * @v rc               Completion status code
  */
-static void ib_cmrc_complete_send ( struct ib_device *ibdev,
+static void ib_cmrc_complete_send ( struct ib_device *ibdev __unused,
                                    struct ib_queue_pair *qp,
                                    struct io_buffer *iobuf, int rc ) {
        struct ib_cmrc_connection *cmrc = ib_qp_get_ownerdata ( qp );
@@ -217,8 +208,8 @@ static void ib_cmrc_complete_send ( struct ib_device *ibdev,
 
        /* Close the connection on any send errors */
        if ( rc != 0 ) {
-               DBGC ( cmrc, "CMRC %s %s send error: %s\n",
-                      ibdev->name, cmrc->name, strerror ( rc ) );
+               DBGC ( cmrc, "CMRC %p send error: %s\n",
+                      cmrc, strerror ( rc ) );
                ib_cmrc_close ( cmrc, rc );
                return;
        }
@@ -234,7 +225,7 @@ static void ib_cmrc_complete_send ( struct ib_device *ibdev,
  * @v iobuf            I/O buffer
  * @v rc               Completion status code
  */
-static void ib_cmrc_complete_recv ( struct ib_device *ibdev,
+static void ib_cmrc_complete_recv ( struct ib_device *ibdev __unused,
                                    struct ib_queue_pair *qp,
                                    struct ib_address_vector *dest __unused,
                                    struct ib_address_vector *source __unused,
@@ -243,20 +234,20 @@ static void ib_cmrc_complete_recv ( struct ib_device *ibdev,
 
        /* Close the connection on any receive errors */
        if ( rc != 0 ) {
-               DBGC ( cmrc, "CMRC %s %s receive error: %s\n",
-                      ibdev->name, cmrc->name, strerror ( rc ) );
+               DBGC ( cmrc, "CMRC %p receive error: %s\n",
+                      cmrc, strerror ( rc ) );
                free_iob ( iobuf );
                ib_cmrc_close ( cmrc, rc );
                return;
        }
 
-       DBGC2 ( cmrc, "CMRC %s %s received:\n", ibdev->name, cmrc->name );
+       DBGC2 ( cmrc, "CMRC %p received:\n", cmrc );
        DBGC2_HDA ( cmrc, 0, iobuf->data, iob_len ( iobuf ) );
 
        /* Pass up data */
        if ( ( rc = xfer_deliver_iob ( &cmrc->xfer, iobuf ) ) != 0 ) {
-               DBGC ( cmrc, "CMRC %s %s could not deliver data: %s\n",
-                      ibdev->name, cmrc->name, strerror ( rc ) );
+               DBGC ( cmrc, "CMRC %p could not deliver data: %s\n",
+                      cmrc, strerror ( rc ) );
                ib_cmrc_close ( cmrc, rc );
                return;
        }
@@ -284,7 +275,6 @@ static struct ib_queue_pair_operations ib_cmrc_queue_pair_ops = {
 static int ib_cmrc_xfer_deliver ( struct ib_cmrc_connection *cmrc,
                                  struct io_buffer *iobuf,
                                  struct xfer_metadata *meta __unused ) {
-       struct ib_device *ibdev = cmrc->ibdev;
        int rc;
 
        /* If no connection has yet been attempted, send this datagram
@@ -294,9 +284,8 @@ static int ib_cmrc_xfer_deliver ( struct ib_cmrc_connection *cmrc,
 
                /* Abort if we have already sent a CM connection request */
                if ( cmrc->conn ) {
-                       DBGC ( cmrc, "CMRC %s %s attempt to send before "
-                              "connection is complete\n",
-                              ibdev->name, cmrc->name );
+                       DBGC ( cmrc, "CMRC %p attempt to send before "
+                              "connection is complete\n", cmrc );
                        rc = -EIO;
                        goto out;
                }
@@ -307,21 +296,18 @@ static int ib_cmrc_xfer_deliver ( struct ib_cmrc_connection *cmrc,
                                              iobuf->data, iob_len ( iobuf ),
                                              &ib_cmrc_conn_op );
                if ( ! cmrc->conn ) {
-                       DBGC ( cmrc, "CMRC %s %s could not connect\n",
-                              ibdev->name, cmrc->name );
+                       DBGC ( cmrc, "CMRC %p could not connect\n", cmrc );
                        rc = -ENOMEM;
                        goto out;
                }
-               DBGC ( cmrc, "CMRC %s %s using CM %08x\n",
-                      ibdev->name, cmrc->name, cmrc->conn->local_id );
 
        } else {
 
                /* Send via QP */
                if ( ( rc = ib_post_send ( cmrc->ibdev, cmrc->qp, NULL,
                                           iob_disown ( iobuf ) ) ) != 0 ) {
-                       DBGC ( cmrc, "CMRC %s %s could not send: %s\n",
-                              ibdev->name, cmrc->name, strerror ( rc ) );
+                       DBGC ( cmrc, "CMRC %p could not send: %s\n",
+                              cmrc, strerror ( rc ) );
                        goto out;
                }
 
@@ -391,12 +377,10 @@ static struct process_descriptor ib_cmrc_shutdown_desc =
  * @v ibdev            Infiniband device
  * @v dgid             Destination GID
  * @v service_id       Service ID
- * @v name             Connection name
  * @ret rc             Returns status code
  */
 int ib_cmrc_open ( struct interface *xfer, struct ib_device *ibdev,
-                  union ib_gid *dgid, union ib_guid *service_id,
-                  const char *name ) {
+                  union ib_gid *dgid, union ib_guid *service_id ) {
        struct ib_cmrc_connection *cmrc;
        int rc;
 
@@ -407,7 +391,6 @@ int ib_cmrc_open ( struct interface *xfer, struct ib_device *ibdev,
                goto err_alloc;
        }
        ref_init ( &cmrc->refcnt, NULL );
-       cmrc->name = name;
        intf_init ( &cmrc->xfer, &ib_cmrc_xfer_desc, &cmrc->refcnt );
        cmrc->ibdev = ibdev;
        memcpy ( &cmrc->dgid, dgid, sizeof ( cmrc->dgid ) );
@@ -417,8 +400,8 @@ int ib_cmrc_open ( struct interface *xfer, struct ib_device *ibdev,
 
        /* Open Infiniband device */
        if ( ( rc = ib_open ( ibdev ) ) != 0 ) {
-               DBGC ( cmrc, "CMRC %s %s could not open device: %s\n",
-                      ibdev->name, cmrc->name, strerror ( rc ) );
+               DBGC ( cmrc, "CMRC %p could not open device: %s\n",
+                      cmrc, strerror ( rc ) );
                goto err_open;
        }
 
@@ -426,8 +409,8 @@ int ib_cmrc_open ( struct interface *xfer, struct ib_device *ibdev,
        cmrc->cq = ib_create_cq ( ibdev, IB_CMRC_NUM_CQES,
                                  &ib_cmrc_completion_ops );
        if ( ! cmrc->cq ) {
-               DBGC ( cmrc, "CMRC %s %s could not create completion queue\n",
-                      ibdev->name, cmrc->name );
+               DBGC ( cmrc, "CMRC %p could not create completion queue\n",
+                      cmrc );
                rc = -ENOMEM;
                goto err_create_cq;
        }
@@ -435,16 +418,14 @@ int ib_cmrc_open ( struct interface *xfer, struct ib_device *ibdev,
        /* Create queue pair */
        cmrc->qp = ib_create_qp ( ibdev, IB_QPT_RC, IB_CMRC_NUM_SEND_WQES,
                                  cmrc->cq, IB_CMRC_NUM_RECV_WQES, cmrc->cq,
-                                 &ib_cmrc_queue_pair_ops, name );
+                                 &ib_cmrc_queue_pair_ops );
        if ( ! cmrc->qp ) {
-               DBGC ( cmrc, "CMRC %s %s could not create queue pair\n",
-                      ibdev->name, cmrc->name );
+               DBGC ( cmrc, "CMRC %p could not create queue pair\n", cmrc );
                rc = -ENOMEM;
                goto err_create_qp;
        }
        ib_qp_set_ownerdata ( cmrc->qp, cmrc );
-       DBGC ( cmrc, "CMRC %s %s using QPN %#lx\n",
-              ibdev->name, cmrc->name, cmrc->qp->qpn );
+       DBGC ( cmrc, "CMRC %p using QPN %lx\n", cmrc, cmrc->qp->qpn );
 
        /* Attach to parent interface, transfer reference (implicitly)
         * to our shutdown process, and return.
index f726428..fc4ff7f 100644 (file)
@@ -42,34 +42,26 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  * Generate multicast membership MAD
  *
  * @v ibdev            Infiniband device
- * @v av               Address vector
- * @v method           Method (IB_MGMT_METHOD_SET or IB_MGMT_METHOD_DELETE)
- * @v mask             Additional component mask
+ * @v gid              Multicast GID
+ * @v join             Join (rather than leave) group
  * @v mad              MAD to fill in
  */
-static void ib_mcast_mad ( struct ib_device *ibdev,
-                          struct ib_address_vector *av,
-                          unsigned int method, unsigned int mask,
-                          union ib_mad *mad ) {
+static void ib_mcast_mad ( struct ib_device *ibdev, union ib_gid *gid,
+                          int join, union ib_mad *mad ) {
        struct ib_mad_sa *sa = &mad->sa;
 
        /* Construct multicast membership record request */
        memset ( sa, 0, sizeof ( *sa ) );
        sa->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
        sa->mad_hdr.class_version = IB_SA_CLASS_VERSION;
-       sa->mad_hdr.method = method;
+       sa->mad_hdr.method =
+               ( join ? IB_MGMT_METHOD_SET : IB_MGMT_METHOD_DELETE );
        sa->mad_hdr.attr_id = htons ( IB_SA_ATTR_MC_MEMBER_REC );
        sa->sa_hdr.comp_mask[1] =
                htonl ( IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
-                       IB_SA_MCMEMBER_REC_JOIN_STATE | mask );
-       sa->sa_data.mc_member_record.qkey = htonl ( av->qkey );
-       sa->sa_data.mc_member_record.pkey =
-               htons ( ibdev->pkey | IB_PKEY_FULL );
-       sa->sa_data.mc_member_record.rate_selector__rate = av->rate;
-       sa->sa_data.mc_member_record.sl__flow_label__hop_limit =
-               htonl ( av->sl << 28 );
-       sa->sa_data.mc_member_record.scope__join_state = 0x01;
-       memcpy ( &sa->sa_data.mc_member_record.mgid, &av->gid,
+                       IB_SA_MCMEMBER_REC_JOIN_STATE );
+       sa->sa_data.mc_member_record.scope__join_state = 1;
+       memcpy ( &sa->sa_data.mc_member_record.mgid, gid,
                 sizeof ( sa->sa_data.mc_member_record.mgid ) );
        memcpy ( &sa->sa_data.mc_member_record.port_gid, &ibdev->gid,
                 sizeof ( sa->sa_data.mc_member_record.port_gid ) );
@@ -83,45 +75,42 @@ static void ib_mcast_mad ( struct ib_device *ibdev,
  * @v madx             Management transaction
  * @v rc               Status code
  * @v mad              Received MAD (or NULL on error)
- * @v src              Source address vector (or NULL on error)
+ * @v av               Source address vector (or NULL on error)
  */
 static void ib_mcast_complete ( struct ib_device *ibdev,
                                struct ib_mad_interface *mi __unused,
                                struct ib_mad_transaction *madx,
                                int rc, union ib_mad *mad,
-                               struct ib_address_vector *src __unused ) {
+                               struct ib_address_vector *av __unused ) {
        struct ib_mc_membership *membership = ib_madx_get_ownerdata ( madx );
        struct ib_queue_pair *qp = membership->qp;
-       struct ib_address_vector *av = membership->av;
+       union ib_gid *gid = &membership->gid;
        struct ib_mc_member_record *mc_member_record =
                &mad->sa.sa_data.mc_member_record;
        int joined;
+       unsigned long qkey;
 
        /* Report failures */
        if ( ( rc == 0 ) && ( mad->hdr.status != htons ( IB_MGMT_STATUS_OK ) ))
                rc = -ENOTCONN;
        if ( rc != 0 ) {
-               DBGC ( ibdev, "IBDEV %s QPN %#lx join failed: %s\n",
-                      ibdev->name, qp->qpn, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p QPN %lx join failed: %s\n",
+                      ibdev, qp->qpn, strerror ( rc ) );
                goto out;
        }
 
        /* Extract values from MAD */
        joined = ( mad->hdr.method == IB_MGMT_METHOD_GET_RESP );
-       av->qkey = ntohl ( mc_member_record->qkey );
-       av->lid = ntohs ( mc_member_record->mlid );
-       av->rate = ( mc_member_record->rate_selector__rate & 0x3f );
-       av->sl = ( ( ntohl ( mc_member_record->sl__flow_label__hop_limit )
-                    >> 28 ) & 0x0f );
-       DBGC ( ibdev, "IBDEV %s QPN %#lx %s " IB_GID_FMT " qkey %#lx\n",
-              ibdev->name, qp->qpn, ( joined ? "joined" : "left" ),
-              IB_GID_ARGS ( &av->gid ), av->qkey );
+       qkey = ntohl ( mc_member_record->qkey );
+       DBGC ( ibdev, "IBDEV %p QPN %lx %s " IB_GID_FMT " qkey %lx\n",
+              ibdev, qp->qpn, ( joined ? "joined" : "left" ),
+              IB_GID_ARGS ( gid ), qkey );
 
        /* Set queue key */
-       qp->qkey = av->qkey;
+       qp->qkey = qkey;
        if ( ( rc = ib_modify_qp ( ibdev, qp ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s QPN %#lx could not modify qkey: %s\n",
-                      ibdev->name, qp->qpn, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p QPN %lx could not modify qkey: %s\n",
+                      ibdev, qp->qpn, strerror ( rc ) );
                goto out;
        }
 
@@ -131,7 +120,7 @@ static void ib_mcast_complete ( struct ib_device *ibdev,
        membership->madx = NULL;
 
        /* Hand off to upper completion handler */
-       membership->complete ( membership, rc );
+       membership->complete ( ibdev, qp, membership, rc, mad );
 }
 
 /** Multicast membership management transaction completion operations */
@@ -145,45 +134,44 @@ static struct ib_mad_transaction_operations ib_mcast_op = {
  * @v ibdev            Infiniband device
  * @v qp               Queue pair
  * @v membership       Multicast group membership
- * @v av               Address vector to fill in
+ * @v gid              Multicast GID to join
  * @v joined           Join completion handler
  * @ret rc             Return status code
  */
 int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
-                   struct ib_mc_membership *membership,
-                   struct ib_address_vector *av, unsigned int mask,
-                   void ( * complete ) ( struct ib_mc_membership *membership,
-                                         int rc ) ) {
+                   struct ib_mc_membership *membership, union ib_gid *gid,
+                   void ( * complete ) ( struct ib_device *ibdev,
+                                         struct ib_queue_pair *qp,
+                                         struct ib_mc_membership *membership,
+                                         int rc, union ib_mad *mad ) ) {
        union ib_mad mad;
        int rc;
 
-       DBGC ( ibdev, "IBDEV %s QPN %#lx joining " IB_GID_FMT "\n",
-              ibdev->name, qp->qpn, IB_GID_ARGS ( &av->gid ) );
+       DBGC ( ibdev, "IBDEV %p QPN %lx joining " IB_GID_FMT "\n",
+              ibdev, qp->qpn, IB_GID_ARGS ( gid ) );
 
-       /* Sanity checks */
+       /* Sanity check */
        assert ( qp != NULL );
-       assert ( ! membership->attached );
 
        /* Initialise structure */
        membership->qp = qp;
-       membership->av = av;
+       memcpy ( &membership->gid, gid, sizeof ( membership->gid ) );
        membership->complete = complete;
 
        /* Attach queue pair to multicast GID */
-       if ( ( rc = ib_mcast_attach ( ibdev, qp, &av->gid ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s QPN %#lx could not attach: %s\n",
-                      ibdev->name, qp->qpn, strerror ( rc ) );
+       if ( ( rc = ib_mcast_attach ( ibdev, qp, gid ) ) != 0 ) {
+               DBGC ( ibdev, "IBDEV %p QPN %lx could not attach: %s\n",
+                      ibdev, qp->qpn, strerror ( rc ) );
                goto err_mcast_attach;
        }
-       membership->attached = 1;
 
        /* Initiate multicast membership join */
-       ib_mcast_mad ( ibdev, av, IB_MGMT_METHOD_SET, mask, &mad );
+       ib_mcast_mad ( ibdev, gid, 1, &mad );
        membership->madx = ib_create_madx ( ibdev, ibdev->gsi, &mad, NULL,
                                            &ib_mcast_op );
        if ( ! membership->madx ) {
-               DBGC ( ibdev, "IBDEV %s QPN %#lx could not create join "
-                      "transaction\n", ibdev->name, qp->qpn );
+               DBGC ( ibdev, "IBDEV %p QPN %lx could not create join "
+                      "transaction\n", ibdev, qp->qpn );
                rc = -ENOMEM;
                goto err_create_madx;
        }
@@ -193,8 +181,7 @@ int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
 
        ib_destroy_madx ( ibdev, ibdev->gsi, membership->madx );
  err_create_madx:
-       ib_mcast_detach ( ibdev, qp, &av->gid );
-       membership->attached = 0;
+       ib_mcast_detach ( ibdev, qp, gid );
  err_mcast_attach:
        return rc;
 }
@@ -208,23 +195,18 @@ int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
  */
 void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp,
                      struct ib_mc_membership *membership ) {
-       struct ib_address_vector *av = membership->av;
+       union ib_gid *gid = &membership->gid;
        union ib_mad mad;
        int rc;
 
-       /* Do nothing if we are already detached from the multicast GID */
-       if ( ! membership->attached )
-               return;
-
-       DBGC ( ibdev, "IBDEV %s QPN %#lx leaving " IB_GID_FMT "\n",
-              ibdev->name, qp->qpn, IB_GID_ARGS ( &av->gid ) );
+       DBGC ( ibdev, "IBDEV %p QPN %lx leaving " IB_GID_FMT "\n",
+              ibdev, qp->qpn, IB_GID_ARGS ( gid ) );
 
        /* Sanity check */
        assert ( qp != NULL );
 
        /* Detach from multicast GID */
-       ib_mcast_detach ( ibdev, qp, &av->gid );
-       membership->attached = 0;
+       ib_mcast_detach ( ibdev, qp, &membership->gid );
 
        /* Cancel multicast membership join, if applicable */
        if ( membership->madx ) {
@@ -233,9 +215,9 @@ void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp,
        }
 
        /* Send a single group leave MAD */
-       ib_mcast_mad ( ibdev, av, IB_MGMT_METHOD_DELETE, 0, &mad );
+       ib_mcast_mad ( ibdev, &membership->gid, 0, &mad );
        if ( ( rc = ib_mi_send ( ibdev, ibdev->gsi, &mad, NULL ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s QPN %#lx could not send leave request: "
-                      "%s\n", ibdev->name, qp->qpn, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p QPN %lx could not send leave request: "
+                      "%s\n", ibdev, qp->qpn, strerror ( rc ) );
        }
 }
index 548a1c8..b432129 100644 (file)
@@ -106,7 +106,7 @@ static int ib_mi_handle ( struct ib_device *ibdev,
 
        /* Otherwise, ignore it */
        DBGC ( mi, "MI %p RX TID %08x%08x ignored\n",
-              mi, ntohl ( hdr->tid.high ), ntohl ( hdr->tid.low ) );
+              mi, ntohl ( hdr->tid[0] ), ntohl ( hdr->tid[1] ) );
        return -ENOTSUP;
 }
 
@@ -152,7 +152,7 @@ static void ib_mi_complete_recv ( struct ib_device *ibdev,
                goto out;
        }
        DBGC ( mi, "MI %p RX TID %08x%08x (%02x,%02x,%02x,%04x) status "
-              "%04x\n", mi, ntohl ( hdr->tid.high ), ntohl ( hdr->tid.low ),
+              "%04x\n", mi, ntohl ( hdr->tid[0] ), ntohl ( hdr->tid[1] ),
               hdr->mgmt_class, hdr->class_version, hdr->method,
               ntohs ( hdr->attr_id ), ntohs ( hdr->status ) );
        DBGC2_HDA ( mi, 0, mad, sizeof ( *mad ) );
@@ -192,12 +192,12 @@ int ib_mi_send ( struct ib_device *ibdev, struct ib_mad_interface *mi,
 
        /* Set common fields */
        hdr->base_version = IB_MGMT_BASE_VERSION;
-       if ( ( hdr->tid.high == 0 ) && ( hdr->tid.low == 0 ) ) {
-               hdr->tid.high = htonl ( IB_MI_TID_MAGIC );
-               hdr->tid.low = htonl ( ++next_tid );
+       if ( ( hdr->tid[0] == 0 ) && ( hdr->tid[1] == 0 ) ) {
+               hdr->tid[0] = htonl ( IB_MI_TID_MAGIC );
+               hdr->tid[1] = htonl ( ++next_tid );
        }
        DBGC ( mi, "MI %p TX TID %08x%08x (%02x,%02x,%02x,%04x) status "
-              "%04x\n", mi, ntohl ( hdr->tid.high ), ntohl ( hdr->tid.low ),
+              "%04x\n", mi, ntohl ( hdr->tid[0] ), ntohl ( hdr->tid[1] ),
               hdr->mgmt_class, hdr->class_version, hdr->method,
               ntohs ( hdr->attr_id ), ntohs ( hdr->status ) );
        DBGC2_HDA ( mi, 0, mad, sizeof ( *mad ) );
@@ -217,8 +217,8 @@ int ib_mi_send ( struct ib_device *ibdev, struct ib_mad_interface *mi,
                        smp->return_path.hops[hop_pointer] = ibdev->port;
                } else {
                        DBGC ( mi, "MI %p TX TID %08x%08x invalid hop pointer "
-                              "%d\n", mi, ntohl ( hdr->tid.high ),
-                              ntohl ( hdr->tid.low ), hop_pointer );
+                              "%d\n", mi, ntohl ( hdr->tid[0] ),
+                              ntohl ( hdr->tid[1] ), hop_pointer );
                        return -EINVAL;
                }
        }
@@ -228,7 +228,7 @@ int ib_mi_send ( struct ib_device *ibdev, struct ib_mad_interface *mi,
        if ( ! iobuf ) {
                DBGC ( mi, "MI %p could not allocate buffer for TID "
                       "%08x%08x\n",
-                      mi, ntohl ( hdr->tid.high ), ntohl ( hdr->tid.low ) );
+                      mi, ntohl ( hdr->tid[0] ), ntohl ( hdr->tid[1] ) );
                return -ENOMEM;
        }
        memcpy ( iob_put ( iobuf, sizeof ( *mad ) ), mad, sizeof ( *mad ) );
@@ -236,7 +236,7 @@ int ib_mi_send ( struct ib_device *ibdev, struct ib_mad_interface *mi,
        /* Send I/O buffer */
        if ( ( rc = ib_post_send ( ibdev, mi->qp, av, iobuf ) ) != 0 ) {
                DBGC ( mi, "MI %p TX TID %08x%08x failed: %s\n",
-                      mi,  ntohl ( hdr->tid.high ), ntohl ( hdr->tid.low ),
+                      mi,  ntohl ( hdr->tid[0] ), ntohl ( hdr->tid[1] ),
                       strerror ( rc ) );
                free_iob ( iobuf );
                return rc;
@@ -261,7 +261,7 @@ static void ib_mi_timer_expired ( struct retry_timer *timer, int expired ) {
        /* Abandon transaction if we have tried too many times */
        if ( expired ) {
                DBGC ( mi, "MI %p abandoning TID %08x%08x\n",
-                      mi, ntohl ( hdr->tid.high ), ntohl ( hdr->tid.low ) );
+                      mi, ntohl ( hdr->tid[0] ), ntohl ( hdr->tid[1] ) );
                madx->op->complete ( ibdev, mi, madx, -ETIMEDOUT, NULL, NULL );
                return;
        }
@@ -346,7 +346,6 @@ void ib_destroy_madx ( struct ib_device *ibdev __unused,
 struct ib_mad_interface * ib_create_mi ( struct ib_device *ibdev,
                                         enum ib_queue_pair_type type ) {
        struct ib_mad_interface *mi;
-       const char *name;
        int rc;
 
        /* Allocate and initialise fields */
@@ -364,17 +363,16 @@ struct ib_mad_interface * ib_create_mi ( struct ib_device *ibdev,
        }
 
        /* Create queue pair */
-       name = ( ( type == IB_QPT_SMI ) ? "SMI" : "GSI" );
        mi->qp = ib_create_qp ( ibdev, type, IB_MI_NUM_SEND_WQES, mi->cq,
                                IB_MI_NUM_RECV_WQES, mi->cq,
-                               &ib_mi_queue_pair_ops, name );
+                               &ib_mi_queue_pair_ops );
        if ( ! mi->qp ) {
                DBGC ( mi, "MI %p could not allocate queue pair\n", mi );
                goto err_create_qp;
        }
        ib_qp_set_ownerdata ( mi->qp, mi );
        DBGC ( mi, "MI %p (%s) running on QPN %#lx\n",
-              mi, mi->qp->name, mi->qp->qpn );
+              mi, ( ( type == IB_QPT_SMI ) ? "SMI" : "GSI" ), mi->qp->qpn );
 
        /* Set queue key */
        mi->qp->qkey = ( ( type == IB_QPT_SMI ) ? IB_QKEY_SMI : IB_QKEY_GSI );
@@ -410,8 +408,8 @@ void ib_destroy_mi ( struct ib_device *ibdev, struct ib_mad_interface *mi ) {
        /* Flush any outstanding requests */
        list_for_each_entry_safe ( madx, tmp, &mi->madx, list ) {
                DBGC ( mi, "MI %p destroyed while TID %08x%08x in progress\n",
-                      mi, ntohl ( madx->mad.hdr.tid.high ),
-                      ntohl ( madx->mad.hdr.tid.low ) );
+                      mi, ntohl ( madx->mad.hdr.tid[0] ),
+                      ntohl ( madx->mad.hdr.tid[1] ) );
                madx->op->complete ( ibdev, mi, madx, -ECANCELED, NULL, NULL );
        }
 
index 8169925..d3a22d3 100644 (file)
@@ -63,8 +63,8 @@ int ib_push ( struct ib_device *ibdev, struct io_buffer *iobuf,
        unsigned int vl;
        unsigned int lnh;
 
-       DBGC2 ( ibdev, "IBDEV %s TX %04x:%08lx => %04x:%08lx (key %08lx)\n",
-               ibdev->name, ibdev->lid, qp->ext_qpn, dest->lid, dest->qpn,
+       DBGC2 ( ibdev, "IBDEV %p TX %04x:%08lx => %04x:%08lx (key %08lx)\n",
+               ibdev, ibdev->lid, qp->ext_qpn, dest->lid, dest->qpn,
                dest->qkey );
 
        /* Calculate packet length */
@@ -152,8 +152,8 @@ int ib_pull ( struct ib_device *ibdev, struct io_buffer *iobuf,
 
        /* Extract LRH */
        if ( iob_len ( iobuf ) < sizeof ( *lrh ) ) {
-               DBGC ( ibdev, "IBDEV %s RX too short (%zd bytes) for LRH\n",
-                      ibdev->name, iob_len ( iobuf ) );
+               DBGC ( ibdev, "IBDEV %p RX too short (%zd bytes) for LRH\n",
+                      ibdev, iob_len ( iobuf ) );
                return -EINVAL;
        }
        lrh = iobuf->data;
@@ -166,16 +166,16 @@ int ib_pull ( struct ib_device *ibdev, struct io_buffer *iobuf,
 
        /* Reject unsupported packets */
        if ( ! ( ( lnh == IB_LNH_BTH ) || ( lnh == IB_LNH_GRH ) ) ) {
-               DBGC ( ibdev, "IBDEV %s RX unsupported LNH %x\n",
-                      ibdev->name, lnh );
+               DBGC ( ibdev, "IBDEV %p RX unsupported LNH %x\n",
+                      ibdev, lnh );
                return -ENOTSUP;
        }
 
        /* Extract GRH, if present */
        if ( lnh == IB_LNH_GRH ) {
                if ( iob_len ( iobuf ) < sizeof ( *grh ) ) {
-                       DBGC ( ibdev, "IBDEV %s RX too short (%zd bytes) "
-                              "for GRH\n", ibdev->name, iob_len ( iobuf ) );
+                       DBGC ( ibdev, "IBDEV %p RX too short (%zd bytes) "
+                              "for GRH\n", ibdev, iob_len ( iobuf ) );
                        return -EINVAL;
                }
                grh = iobuf->data;
@@ -190,23 +190,23 @@ int ib_pull ( struct ib_device *ibdev, struct io_buffer *iobuf,
 
        /* Extract BTH */
        if ( iob_len ( iobuf ) < sizeof ( *bth ) ) {
-               DBGC ( ibdev, "IBDEV %s RX too short (%zd bytes) for BTH\n",
-                      ibdev->name, iob_len ( iobuf ) );
+               DBGC ( ibdev, "IBDEV %p RX too short (%zd bytes) for BTH\n",
+                      ibdev, iob_len ( iobuf ) );
                return -EINVAL;
        }
        bth = iobuf->data;
        iob_pull ( iobuf, sizeof ( *bth ) );
        if ( bth->opcode != BTH_OPCODE_UD_SEND ) {
-               DBGC ( ibdev, "IBDEV %s unsupported BTH opcode %x\n",
-                      ibdev->name, bth->opcode );
+               DBGC ( ibdev, "IBDEV %p unsupported BTH opcode %x\n",
+                      ibdev, bth->opcode );
                return -ENOTSUP;
        }
        dest->qpn = ntohl ( bth->dest_qp );
 
        /* Extract DETH */
        if ( iob_len ( iobuf ) < sizeof ( *deth ) ) {
-               DBGC ( ibdev, "IBDEV %s RX too short (%zd bytes) for DETH\n",
-                      ibdev->name, iob_len ( iobuf ) );
+               DBGC ( ibdev, "IBDEV %p RX too short (%zd bytes) for DETH\n",
+                      ibdev, iob_len ( iobuf ) );
                return -EINVAL;
        }
        deth = iobuf->data;
@@ -226,25 +226,24 @@ int ib_pull ( struct ib_device *ibdev, struct io_buffer *iobuf,
        if ( qp ) {
                if ( IB_LID_MULTICAST ( dest->lid ) && grh ) {
                        if ( ! ( *qp = ib_find_qp_mgid ( ibdev, &grh->dgid ))){
-                               DBGC ( ibdev, "IBDEV %s RX for unknown MGID "
-                                      IB_GID_FMT "\n", ibdev->name,
-                                      IB_GID_ARGS ( &grh->dgid ) );
+                               DBGC ( ibdev, "IBDEV %p RX for unknown MGID "
+                                      IB_GID_FMT "\n",
+                                      ibdev, IB_GID_ARGS ( &grh->dgid ) );
                                return -ENODEV;
                        }
                } else {
                        if ( ! ( *qp = ib_find_qp_qpn ( ibdev, dest->qpn ) ) ) {
-                               DBGC ( ibdev, "IBDEV %s RX for nonexistent "
-                                      "QPN %#lx\n", ibdev->name, dest->qpn );
+                               DBGC ( ibdev, "IBDEV %p RX for nonexistent "
+                                      "QPN %lx\n", ibdev, dest->qpn );
                                return -ENODEV;
                        }
                }
                assert ( *qp );
        }
 
-       DBGC2 ( ibdev, "IBDEV %s RX %04x:%08lx <= %04x:%08lx (key %08x)\n",
-               ibdev->name, dest->lid,
-               ( IB_LID_MULTICAST ( dest->lid ) ?
-                 ( qp ? (*qp)->ext_qpn : -1UL ) : dest->qpn ),
+       DBGC2 ( ibdev, "IBDEV %p RX %04x:%08lx <= %04x:%08lx (key %08x)\n",
+               ibdev, dest->lid, ( IB_LID_MULTICAST ( dest->lid ) ?
+                             ( qp ? (*qp)->ext_qpn : -1UL ) : dest->qpn ),
                source->lid, source->qpn, ntohl ( deth->qkey ) );
        DBGCP_HDA ( ibdev, 0,
                    ( iobuf->data - ( orig_iob_len - iob_len ( iobuf ) ) ),
index f846710..f9cbab8 100644 (file)
@@ -61,9 +61,9 @@ static void ib_path_complete ( struct ib_device *ibdev,
        if ( ( rc == 0 ) && ( mad->hdr.status != htons ( IB_MGMT_STATUS_OK ) ))
                rc = -ENETUNREACH;
        if ( rc != 0 ) {
-               DBGC ( ibdev, "IBDEV %s path lookup for " IB_GID_FMT
+               DBGC ( ibdev, "IBDEV %p path lookup for " IB_GID_FMT
                       " failed: %s\n",
-                      ibdev->name, IB_GID_ARGS ( dgid ), strerror ( rc ) );
+                      ibdev, IB_GID_ARGS ( dgid ), strerror ( rc ) );
                goto out;
        }
 
@@ -71,15 +71,9 @@ static void ib_path_complete ( struct ib_device *ibdev,
        path->av.lid = ntohs ( pathrec->dlid );
        path->av.sl = ( pathrec->reserved__sl & 0x0f );
        path->av.rate = ( pathrec->rate_selector__rate & 0x3f );
-       DBGC ( ibdev, "IBDEV %s path to " IB_GID_FMT " lid %d sl %d rate "
-              "%d\n", ibdev->name, IB_GID_ARGS ( dgid ), path->av.lid,
-              path->av.sl, path->av.rate );
-
-       /* Use only the LID if no GRH is needed for this path */
-       if ( memcmp ( &path->av.gid.s.prefix, &ibdev->gid.s.prefix,
-                     sizeof ( path->av.gid.s.prefix ) ) == 0 ) {
-               path->av.gid_present = 0;
-       }
+       DBGC ( ibdev, "IBDEV %p path to " IB_GID_FMT " is %04x sl %d rate "
+              "%d\n", ibdev, IB_GID_ARGS ( dgid ), path->av.lid, path->av.sl,
+              path->av.rate );
 
  out:
        /* Destroy the completed transaction */
@@ -251,6 +245,13 @@ int ib_resolve_path ( struct ib_device *ibdev, struct ib_address_vector *av ) {
        struct ib_cached_path *cached;
        unsigned int cache_idx;
 
+       /* Sanity check */
+       if ( ! av->gid_present ) {
+               DBGC ( ibdev, "IBDEV %p attempt to look up path without GID\n",
+                      ibdev );
+               return -EINVAL;
+       }
+
        /* Look in cache for a matching entry */
        cached = ib_find_path_cache_entry ( ibdev, gid );
        if ( cached && cached->path->av.lid ) {
@@ -258,12 +259,11 @@ int ib_resolve_path ( struct ib_device *ibdev, struct ib_address_vector *av ) {
                av->lid = cached->path->av.lid;
                av->rate = cached->path->av.rate;
                av->sl = cached->path->av.sl;
-               av->gid_present = cached->path->av.gid_present;
-               DBGC2 ( ibdev, "IBDEV %s cache hit for " IB_GID_FMT "\n",
-                       ibdev->name, IB_GID_ARGS ( gid ) );
+               DBGC2 ( ibdev, "IBDEV %p cache hit for " IB_GID_FMT "\n",
+                       ibdev, IB_GID_ARGS ( gid ) );
                return 0;
        }
-       DBGC ( ibdev, "IBDEV %s cache miss for " IB_GID_FMT "%s\n", ibdev->name,
+       DBGC ( ibdev, "IBDEV %p cache miss for " IB_GID_FMT "%s\n", ibdev,
               IB_GID_ARGS ( gid ), ( cached ? " (in progress)" : "" ) );
 
        /* If lookup is already in progress, do nothing */
@@ -282,8 +282,8 @@ int ib_resolve_path ( struct ib_device *ibdev, struct ib_address_vector *av ) {
        /* Create new path */
        cached->path = ib_create_path ( ibdev, av, &ib_cached_path_op );
        if ( ! cached->path ) {
-               DBGC ( ibdev, "IBDEV %s could not create path\n",
-                      ibdev->name );
+               DBGC ( ibdev, "IBDEV %p could not create path\n",
+                      ibdev );
                return -ENOMEM;
        }
        ib_path_set_ownerdata ( cached->path, cached );
diff --git a/roms/ipxe/src/net/infiniband/ib_service.c b/roms/ipxe/src/net/infiniband/ib_service.c
deleted file mode 100644 (file)
index f035382..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <string.h>
-#include <stdio.h>
-#include <byteswap.h>
-#include <ipxe/infiniband.h>
-#include <ipxe/ib_mi.h>
-#include <ipxe/ib_service.h>
-
-/** @file
- *
- * Infiniband service records
- *
- */
-
-/**
- * Create service record management transaction
- *
- * @v ibdev            Infiniband device
- * @v mi               Management interface
- * @v name             Service name
- * @v op               Management transaction operations
- * @ret madx           Management transaction, or NULL on error
- */
-struct ib_mad_transaction *
-ib_create_service_madx ( struct ib_device *ibdev,
-                        struct ib_mad_interface *mi, const char *name,
-                        struct ib_mad_transaction_operations *op ) {
-       union ib_mad mad;
-       struct ib_mad_sa *sa = &mad.sa;
-       struct ib_service_record *svc = &sa->sa_data.service_record;
-
-       /* Construct service record request */
-       memset ( sa, 0, sizeof ( *sa ) );
-       sa->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
-       sa->mad_hdr.class_version = IB_SA_CLASS_VERSION;
-       sa->mad_hdr.method = IB_MGMT_METHOD_GET;
-       sa->mad_hdr.attr_id = htons ( IB_SA_ATTR_SERVICE_REC );
-       sa->sa_hdr.comp_mask[1] = htonl ( IB_SA_SERVICE_REC_NAME );
-       snprintf ( svc->name, sizeof ( svc->name ), "%s", name );
-
-       /* Create management transaction */
-       return ib_create_madx ( ibdev, mi, &mad, NULL, op );
-}
index 24ec9f4..a05d7c9 100644 (file)
@@ -176,9 +176,9 @@ static int ib_sma_set_port_info ( struct ib_device *ibdev,
               ( port_info->link_speed_active__link_speed_enabled & 0xf ) ) )
                ibdev->link_speed_enabled = link_speed_enabled;
        ibdev->sm_sl = ( port_info->neighbour_mtu__mastersm_sl & 0xf );
-       DBGC ( mi, "SMA %p set LID %d SMLID %d link width %d speed %d\n",
-              mi, ibdev->lid, ibdev->sm_lid, ibdev->link_width_enabled,
-              ibdev->link_speed_enabled );
+       DBGC ( mi, "SMA %p set LID %04x SMLID %04x link width %02x speed "
+              "%02x\n", mi, ibdev->lid, ibdev->sm_lid,
+              ibdev->link_width_enabled, ibdev->link_speed_enabled );
 
        /* Update parameters on device */
        if ( ( rc = ib_set_port_info ( ibdev, mad ) ) != 0 ) {
@@ -358,7 +358,7 @@ struct ib_mad_agent ib_sma_agent[] __ib_mad_agent = {
 int ib_create_sma ( struct ib_device *ibdev, struct ib_mad_interface *mi ) {
 
        /* Nothing to do */
-       DBGC ( ibdev, "IBDEV %s SMA using SMI %p\n", ibdev->name, mi );
+       DBGC ( ibdev, "IBDEV %p SMA using SMI %p\n", ibdev, mi );
 
        return 0;
 }
index 5de7deb..c1741b2 100644 (file)
@@ -86,8 +86,8 @@ static int ib_smc_get_node_info ( struct ib_device *ibdev,
        /* Issue MAD */
        if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_NODE_INFO ), 0,
                                 local_mad, mad ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s could not get node info: %s\n",
-                      ibdev->name, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p could not get node info: %s\n",
+                      ibdev, strerror ( rc ) );
                return rc;
        }
        return 0;
@@ -109,8 +109,8 @@ static int ib_smc_get_port_info ( struct ib_device *ibdev,
        /* Issue MAD */
        if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_PORT_INFO ),
                                 htonl ( ibdev->port ), local_mad, mad )) !=0){
-               DBGC ( ibdev, "IBDEV %s could not get port info: %s\n",
-                      ibdev->name, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p could not get port info: %s\n",
+                      ibdev, strerror ( rc ) );
                return rc;
        }
        return 0;
@@ -132,8 +132,8 @@ static int ib_smc_get_guid_info ( struct ib_device *ibdev,
        /* Issue MAD */
        if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_GUID_INFO ), 0,
                                 local_mad, mad ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s could not get GUID info: %s\n",
-                      ibdev->name, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p could not get GUID info: %s\n",
+                      ibdev, strerror ( rc ) );
                return rc;
        }
        return 0;
@@ -155,8 +155,8 @@ static int ib_smc_get_pkey_table ( struct ib_device *ibdev,
        /* Issue MAD */
        if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_PKEY_TABLE ), 0,
                                 local_mad, mad ) ) != 0 ) {
-               DBGC ( ibdev, "IBDEV %s could not get pkey table: %s\n",
-                      ibdev->name, strerror ( rc ) );
+               DBGC ( ibdev, "IBDEV %p could not get pkey table: %s\n",
+                      ibdev, strerror ( rc ) );
                return rc;
        }
        return 0;
@@ -216,8 +216,8 @@ static int ib_smc_get ( struct ib_device *ibdev, ib_local_mad_t local_mad ) {
                return rc;
        ibdev->pkey = ntohs ( pkey_table->pkey[0] );
 
-       DBGC ( ibdev, "IBDEV %s port GID is " IB_GID_FMT "\n",
-              ibdev->name, IB_GID_ARGS ( &ibdev->gid ) );
+       DBGC ( ibdev, "IBDEV %p port GID is " IB_GID_FMT "\n",
+              ibdev, IB_GID_ARGS ( &ibdev->gid ) );
 
        return 0;
 }
index 3b4914a..3700184 100644 (file)
@@ -210,7 +210,7 @@ static int ib_srp_open ( struct interface *block, struct ib_device *ibdev,
 
        /* Open CMRC socket */
        if ( ( rc = ib_cmrc_open ( &ib_srp->cmrc, ibdev, dgid,
-                                  service_id, "SRP" ) ) != 0 ) {
+                                  service_id ) ) != 0 ) {
                DBGC ( ib_srp, "IBSRP %p could not open CMRC socket: %s\n",
                       ib_srp, strerror ( rc ) );
                goto err_cmrc_open;
diff --git a/roms/ipxe/src/net/infiniband/xsigo.c b/roms/ipxe/src/net/infiniband/xsigo.c
deleted file mode 100644 (file)
index 91b7b71..0000000
+++ /dev/null
@@ -1,1858 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <byteswap.h>
-#include <ipxe/version.h>
-#include <ipxe/timer.h>
-#include <ipxe/malloc.h>
-#include <ipxe/iobuf.h>
-#include <ipxe/retry.h>
-#include <ipxe/process.h>
-#include <ipxe/settings.h>
-#include <ipxe/infiniband.h>
-#include <ipxe/ib_service.h>
-#include <ipxe/ib_cmrc.h>
-#include <ipxe/if_ether.h>
-#include <ipxe/ethernet.h>
-#include <ipxe/eoib.h>
-#include <ipxe/xsigo.h>
-
-/** @file
- *
- * Xsigo virtual Ethernet devices
- *
- */
-
-/** A Xsigo device */
-struct xsigo_device {
-       /** Reference count */
-       struct refcnt refcnt;
-       /** Underlying Infiniband device */
-       struct ib_device *ibdev;
-       /** List of Xsigo devices */
-       struct list_head list;
-       /** Device name */
-       const char *name;
-
-       /** Link opener timer */
-       struct retry_timer opener;
-
-       /** Discovery timer */
-       struct retry_timer discovery;
-       /** Discovery management transaction (if any) */
-       struct ib_mad_transaction *madx;
-
-       /** List of configuration managers */
-       struct list_head managers;
-};
-
-/** A Xsigo configuration manager */
-struct xsigo_manager {
-       /** Reference count */
-       struct refcnt refcnt;
-       /** Xsigo device */
-       struct xsigo_device *xdev;
-       /** List of managers */
-       struct list_head list;
-       /** Device name */
-       char name[16];
-       /** Manager ID */
-       struct xsigo_manager_id id;
-
-       /** Data transfer interface */
-       struct interface xfer;
-       /** Connection timer */
-       struct retry_timer reopen;
-       /** Keepalive timer */
-       struct retry_timer keepalive;
-       /** Transmission process */
-       struct process process;
-       /** Pending transmissions */
-       unsigned int pending;
-       /** Transmit sequence number */
-       uint32_t seq;
-
-       /** List of virtual Ethernet devices */
-       struct list_head nics;
-};
-
-/** Configuration manager pending transmissions */
-enum xsigo_manager_pending {
-       /** Send connection request */
-       XCM_TX_CONNECT = 0x0001,
-       /** Send registration message */
-       XCM_TX_REGISTER = 0x0002,
-};
-
-/** A Xsigo virtual Ethernet device */
-struct xsigo_nic {
-       /** Configuration manager */
-       struct xsigo_manager *xcm;
-       /** List of virtual Ethernet devices */
-       struct list_head list;
-       /** Device name */
-       char name[16];
-
-       /** Resource identifier */
-       union ib_guid resource;
-       /** MAC address */
-       uint8_t mac[ETH_ALEN];
-       /** Network ID */
-       unsigned long network;
-};
-
-/** Configuration manager service ID */
-static union ib_guid xcm_service_id = {
-       .bytes = XCM_SERVICE_ID,
-};
-
-/** List of all Xsigo devices */
-static LIST_HEAD ( xsigo_devices );
-
-/**
- * Free Xsigo device
- *
- * @v refcnt           Reference count
- */
-static void xsigo_free ( struct refcnt *refcnt ) {
-       struct xsigo_device *xdev =
-               container_of ( refcnt, struct xsigo_device, refcnt );
-
-       /* Sanity checks */
-       assert ( ! timer_running ( &xdev->opener ) );
-       assert ( ! timer_running ( &xdev->discovery ) );
-       assert ( xdev->madx == NULL );
-       assert ( list_empty ( &xdev->managers ) );
-
-       /* Drop reference to Infiniband device */
-       ibdev_put ( xdev->ibdev );
-
-       /* Free device */
-       free ( xdev );
-}
-
-/**
- * Free configuration manager
- *
- * @v refcnt           Reference count
- */
-static void xcm_free ( struct refcnt *refcnt ) {
-       struct xsigo_manager *xcm =
-               container_of ( refcnt, struct xsigo_manager, refcnt );
-
-       /* Sanity checks */
-       assert ( ! timer_running ( &xcm->reopen ) );
-       assert ( ! timer_running ( &xcm->keepalive ) );
-       assert ( ! process_running ( &xcm->process ) );
-       assert ( list_empty ( &xcm->nics ) );
-
-       /* Drop reference to Xsigo device */
-       ref_put ( &xcm->xdev->refcnt );
-
-       /* Free manager */
-       free ( xcm );
-}
-
-/****************************************************************************
- *
- * Virtual Ethernet (XVE) devices
- *
- ****************************************************************************
- */
-
-/**
- * Create virtual Ethernet device
- *
- * @v xcm              Configuration manager
- * @v resource         Resource identifier
- * @v mac              Ethernet MAC
- * @v network          Network identifier
- * @v name             Device name
- * @ret rc             Return status code
- */
-static int xve_create ( struct xsigo_manager *xcm, union ib_guid *resource,
-                       const uint8_t *mac, unsigned long network,
-                       unsigned long qkey, const char *name ) {
-       struct xsigo_device *xdev = xcm->xdev;
-       struct ib_device *ibdev = xdev->ibdev;
-       struct xsigo_nic *xve;
-       struct ib_address_vector broadcast;
-       int rc;
-
-       /* Allocate and initialise structure */
-       xve = zalloc ( sizeof ( *xve ) );
-       if ( ! xve ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       xve->xcm = xcm;
-       snprintf ( xve->name, sizeof ( xve->name ), "%s", name );
-       memcpy ( &xve->resource, resource, sizeof ( xve->resource ) );
-       memcpy ( xve->mac, mac, ETH_ALEN );
-       xve->network = network;
-       DBGC ( xve, "XVE %s created for %s " IB_GUID_FMT "\n",
-              xve->name, xcm->name, IB_GUID_ARGS ( resource ) );
-       DBGC ( xve, "XVE %s is MAC %s on network %ld\n",
-              xve->name, eth_ntoa ( mac ), network );
-
-       /* Construct broadcast address vector */
-       memset ( &broadcast, 0, sizeof ( broadcast ) );
-       broadcast.qpn = IB_QPN_BROADCAST;
-       broadcast.qkey = qkey;
-       broadcast.gid_present = 1;
-       broadcast.gid.dwords[0] = htonl ( XVE_PREFIX );
-       broadcast.gid.words[2] = htons ( ibdev->pkey );
-       broadcast.gid.dwords[3] = htonl ( network );
-
-       /* Create EoIB device */
-       if ( ( rc = eoib_create ( ibdev, xve->mac, &broadcast,
-                                 xve->name ) ) != 0 ) {
-               DBGC ( xve, "XVE %s could not create EoIB device: %s\n",
-                      xve->name, strerror ( rc ) );
-               goto err_create;
-       }
-
-       /* Add to list of virtual Ethernet devices.  Do this only
-        * after creating the EoIB device, so that our net device
-        * notifier won't attempt to send an operational state update
-        * before we have acknowledged the installation.
-        */
-       list_add ( &xve->list, &xcm->nics );
-
-       return 0;
-
-       list_del ( &xve->list );
- err_create:
-       free ( xve );
- err_alloc:
-       return rc;
-}
-
-/**
- * Find virtual Ethernet device
- *
- * @v xcm              Configuration manager
- * @v resource         Resource identifier
- * @ret xve            Virtual Ethernet device, or NULL
- */
-static struct xsigo_nic * xve_find ( struct xsigo_manager *xcm,
-                                    union ib_guid *resource ) {
-       struct xsigo_nic *xve;
-
-       list_for_each_entry ( xve, &xcm->nics, list ) {
-               if ( memcmp ( resource, &xve->resource,
-                             sizeof ( *resource ) ) == 0 )
-                       return xve;
-       }
-       return NULL;
-}
-
-/**
- * Destroy virtual Ethernet device
- *
- * @v xve              Virtual Ethernet device
- */
-static void xve_destroy ( struct xsigo_nic *xve ) {
-       struct xsigo_manager *xcm = xve->xcm;
-       struct xsigo_device *xdev = xcm->xdev;
-       struct ib_device *ibdev = xdev->ibdev;
-       struct eoib_device *eoib;
-
-       /* Destroy corresponding EoIB device, if any */
-       if ( ( eoib = eoib_find ( ibdev, xve->mac ) ) )
-               eoib_destroy ( eoib );
-
-       /* Remove from list of virtual Ethernet devices */
-       list_del ( &xve->list );
-
-       /* Free virtual Ethernet device */
-       DBGC ( xve, "XVE %s destroyed\n", xve->name );
-       free ( xve );
-}
-
-/**
- * Update virtual Ethernet device MTU
- *
- * @v xve              Virtual Ethernet device
- * @v eoib             EoIB device
- * @v mtu              New MTU (excluding Ethernet and EoIB headers)
- * @ret rc             Return status code
- */
-static int xve_update_mtu ( struct xsigo_nic *xve, struct eoib_device *eoib,
-                           size_t mtu ) {
-       struct net_device *netdev = eoib->netdev;
-       size_t max;
-
-       /* Check that we can support this MTU */
-       max = ( IB_MAX_PAYLOAD_SIZE - ( sizeof ( struct ethhdr ) +
-                                       sizeof ( struct eoib_header ) ) );
-       if ( mtu > max ) {
-               DBGC ( xve, "XVE %s cannot support MTU %zd (max %zd)\n",
-                      xve->name, mtu, max );
-               return -ERANGE;
-       }
-
-       /* Update MTU.  No need to close/reopen the network device,
-        * since our Infiniband stack uses a fixed MTU anyway.  Note
-        * that the network device sees the Ethernet frame header but
-        * not the EoIB header.
-        */
-       netdev->max_pkt_len = ( mtu + sizeof ( struct ethhdr ) );
-       DBGC ( xve, "XVE %s has MTU %zd\n", xve->name, mtu );
-
-       return 0;
-}
-
-/**
- * Open virtual Ethernet device
- *
- * @v xve              Virtual Ethernet device
- * @v eoib             EoIB device
- * @v open             New administrative state
- * @ret rc             Return status code
- */
-static int xve_open ( struct xsigo_nic *xve, struct eoib_device *eoib ) {
-       struct net_device *netdev = eoib->netdev;
-       int rc;
-
-       /* Do nothing if network device is already open */
-       if ( netdev_is_open ( netdev ) )
-               return 0;
-       DBGC ( xve, "XVE %s opening network device\n", xve->name );
-
-       /* Open network device */
-       if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
-               DBGC ( xve, "XVE %s could not open: %s\n",
-                      xve->name, strerror ( rc ) );
-               return rc;
-       }
-
-       return 0;
-}
-
-/**
- * Close virtual Ethernet device
- *
- * @v xve              Virtual Ethernet device
- * @v eoib             EoIB device
- */
-static void xve_close ( struct xsigo_nic *xve, struct eoib_device *eoib ) {
-       struct net_device *netdev = eoib->netdev;
-
-       /* Do nothing if network device is already closed */
-       if ( ! netdev_is_open ( netdev ) )
-               return;
-
-       /* Close network device */
-       netdev_close ( netdev );
-       DBGC ( xve, "XVE %s closed network device\n", xve->name );
-}
-
-/**
- * Update virtual Ethernet device administrative state
- *
- * @v xve              Virtual Ethernet device
- * @v eoib             EoIB device
- * @v open             New administrative state
- * @ret rc             Return status code
- */
-static int xve_update_state ( struct xsigo_nic *xve, struct eoib_device *eoib,
-                             int open ) {
-
-       /* Open or close device, as applicable */
-       if ( open ) {
-               return xve_open ( xve, eoib );
-       } else {
-               xve_close ( xve, eoib );
-               return 0;
-       }
-}
-
-/**
- * Update gateway (TCA)
- *
- * @v xve              Virtual Ethernet device
- * @v eoib             EoIB device
- * @v av               Address vector, or NULL if no gateway
- * @ret rc             Return status code
- */
-static int xve_update_tca ( struct xsigo_nic *xve, struct eoib_device *eoib,
-                           struct ib_address_vector *av ) {
-
-       /* Update gateway address */
-       eoib_set_gateway ( eoib, av );
-       if ( av ) {
-               DBGC ( xve, "XVE %s has TCA " IB_GID_FMT " data %#lx qkey "
-                      "%#lx\n", xve->name, IB_GID_ARGS ( &av->gid ), av->qpn,
-                      av->qkey );
-       } else {
-               DBGC ( xve, "XVE %s has no TCA\n", xve->name );
-       }
-
-       /* The Linux driver will modify the local device's link state
-        * to reflect the EoIB-to-Ethernet gateway's link state, but
-        * this seems philosophically incorrect since communication
-        * within the EoIB broadcast domain still works regardless of
-        * the state of the gateway.
-        */
-
-       return 0;
-}
-
-/****************************************************************************
- *
- * Server management protocol (XSMP) session messages
- *
- ****************************************************************************
- */
-
-/**
- * Get session message name (for debugging)
- *
- * @v type             Message type
- * @ret name           Message name
- */
-static const char * xsmp_session_type ( unsigned int type ) {
-       static char buf[16];
-
-       switch ( type ) {
-       case XSMP_SESSION_TYPE_HELLO:           return "HELLO";
-       case XSMP_SESSION_TYPE_REGISTER:        return "REGISTER";
-       case XSMP_SESSION_TYPE_CONFIRM:         return "CONFIRM";
-       case XSMP_SESSION_TYPE_REJECT:          return "REJECT";
-       case XSMP_SESSION_TYPE_SHUTDOWN:        return "SHUTDOWN";
-       default:
-               snprintf ( buf, sizeof ( buf ), "UNKNOWN<%d>", type );
-               return buf;
-       }
-}
-
-/**
- * Extract chassis name (for debugging)
- *
- * @v msg              Session message
- * @ret chassis                Chassis name
- */
-static const char * xsmp_chassis_name ( struct xsmp_session_message *msg ) {
-       static char chassis[ sizeof ( msg->chassis ) + 1 /* NUL */ ];
-
-       memcpy ( chassis, msg->chassis, sizeof ( msg->chassis ) );
-       return chassis;
-}
-
-/**
- * Extract session name (for debugging)
- *
- * @v msg              Session message
- * @ret session                Session name
- */
-static const char * xsmp_session_name ( struct xsmp_session_message *msg ) {
-       static char session[ sizeof ( msg->session ) + 1 /* NUL */ ];
-
-       memcpy ( session, msg->session, sizeof ( msg->session ) );
-       return session;
-}
-
-/**
- * Send session message
- *
- * @v xcm              Configuration manager
- * @v type             Message type
- * @ret rc             Return status code
- */
-static int xsmp_tx_session ( struct xsigo_manager *xcm, unsigned int type ) {
-       struct xsigo_device *xdev = xcm->xdev;
-       struct ib_device *ibdev = xdev->ibdev;
-       struct xsmp_session_message msg;
-       int rc;
-
-       /* Construct session message */
-       memset ( &msg, 0, sizeof ( msg ) );
-       msg.hdr.type = XSMP_TYPE_SESSION;
-       msg.hdr.len = htons ( sizeof ( msg ) );
-       msg.hdr.seq = htonl ( ++xcm->seq );
-       memcpy ( &msg.hdr.src.guid, &ibdev->gid.s.guid,
-                sizeof ( msg.hdr.src.guid ) );
-       memcpy ( &msg.hdr.dst.guid, &xcm->id.guid,
-                sizeof ( msg.hdr.dst.guid ) );
-       msg.type = type;
-       msg.len = htons ( sizeof ( msg ) - sizeof ( msg.hdr ) );
-       msg.os_type = XSIGO_OS_TYPE_GENERIC;
-       msg.resources = htons ( XSIGO_RESOURCE_XVE |
-                               XSIGO_RESOURCE_NO_HA );
-       msg.boot = htonl ( XSMP_BOOT_PXE );
-       DBGCP ( xcm, "XCM %s TX[%d] session %s\n", xcm->name,
-               ntohl ( msg.hdr.seq ), xsmp_session_type ( msg.type ) );
-       DBGCP_HDA ( xcm, 0, &msg, sizeof ( msg ) );
-
-       /* Send session message */
-       if ( ( rc = xfer_deliver_raw ( &xcm->xfer, &msg,
-                                      sizeof ( msg ) ) ) != 0 ) {
-               DBGC ( xcm, "XCM %s TX session %s failed: %s\n", xcm->name,
-                      xsmp_session_type ( msg.type ), strerror ( rc ) );
-               return rc;
-       }
-
-       return 0;
-}
-
-/**
- * Send registration message
- *
- * @v xcm              Configuration manager
- * @ret rc             Return status code
- */
-static inline int xsmp_tx_session_register ( struct xsigo_manager *xcm ) {
-
-       DBGC ( xcm, "XCM %s registering with " IB_GUID_FMT "\n",
-              xcm->name, IB_GUID_ARGS ( &xcm->id.guid ) );
-
-       /* Send registration message */
-       return xsmp_tx_session ( xcm, XSMP_SESSION_TYPE_REGISTER );
-}
-
-/**
- * Send keepalive message
- *
- * @v xcm              Configuration manager
- * @ret rc             Return status code
- */
-static int xsmp_tx_session_hello ( struct xsigo_manager *xcm ) {
-
-       /* Send keepalive message */
-       return xsmp_tx_session ( xcm, XSMP_SESSION_TYPE_HELLO );
-}
-
-/**
- * Handle received keepalive message
- *
- * @v xcm              Configuration manager
- * @v msg              Keepalive message
- * @ret rc             Return status code
- */
-static int xsmp_rx_session_hello ( struct xsigo_manager *xcm,
-                                  struct xsmp_session_message *msg __unused ) {
-
-       /* Respond to keepalive message.  Note that the XCM doesn't
-        * seem to actually ever send these.
-        */
-       return xsmp_tx_session_hello ( xcm );
-}
-
-/**
- * Handle received registration confirmation message
- *
- * @v xcm              Configuration manager
- * @v msg              Registration confirmation message
- * @ret rc             Return status code
- */
-static int xsmp_rx_session_confirm ( struct xsigo_manager *xcm,
-                                    struct xsmp_session_message *msg ) {
-
-       DBGC ( xcm, "XCM %s registered with \"%s\" as \"%s\"\n", xcm->name,
-              xsmp_chassis_name ( msg ), xsmp_session_name ( msg ) );
-
-       return 0;
-}
-
-/**
- * Handle received registration rejection message
- *
- * @v xcm              Configuration manager
- * @v msg              Registration confirmation message
- * @ret rc             Return status code
- */
-static int xsmp_rx_session_reject ( struct xsigo_manager *xcm,
-                                   struct xsmp_session_message *msg ) {
-
-       DBGC ( xcm, "XCM %s rejected by \"%s\":\n",
-              xcm->name, xsmp_chassis_name ( msg ) );
-       DBGC_HDA ( xcm, 0, msg, sizeof ( *msg ) );
-
-       return -EPERM;
-}
-
-/**
- * Handle received shutdown message
- *
- * @v xcm              Configuration manager
- * @v msg              Registration confirmation message
- * @ret rc             Return status code
- */
-static int xsmp_rx_session_shutdown ( struct xsigo_manager *xcm,
-                                     struct xsmp_session_message *msg ) {
-
-       DBGC ( xcm, "XCM %s shut down by \"%s\":\n",
-              xcm->name, xsmp_chassis_name ( msg ) );
-       DBGC_HDA ( xcm, 0, msg, sizeof ( *msg ) );
-
-       return -ENOTCONN;
-}
-
-/**
- * Handle received session message
- *
- * @v xcm              Configuration manager
- * @v msg              Session message
- * @ret rc             Return status code
- */
-static int xsmp_rx_session ( struct xsigo_manager *xcm,
-                            struct xsmp_session_message *msg ) {
-
-       DBGCP ( xcm, "XCM %s RX[%d] session %s\n", xcm->name,
-               ntohl ( msg->hdr.seq ), xsmp_session_type ( msg->type ) );
-       DBGCP_HDA ( xcm, 0, msg, sizeof ( *msg ) );
-
-       /* Handle message according to type */
-       switch ( msg->type ) {
-       case XSMP_SESSION_TYPE_HELLO:
-               return xsmp_rx_session_hello ( xcm, msg );
-       case XSMP_SESSION_TYPE_CONFIRM:
-               return xsmp_rx_session_confirm ( xcm, msg );
-       case XSMP_SESSION_TYPE_REJECT:
-               return xsmp_rx_session_reject ( xcm, msg );
-       case XSMP_SESSION_TYPE_SHUTDOWN:
-               return xsmp_rx_session_shutdown ( xcm, msg );
-       default:
-               DBGC ( xcm, "XCM %s RX[%d] session unexpected %s:\n", xcm->name,
-                      ntohl ( msg->hdr.seq ), xsmp_session_type ( msg->type ));
-               DBGC_HDA ( xcm, 0, msg, sizeof ( *msg ) );
-               return -EPROTO;
-       }
-}
-
-/****************************************************************************
- *
- * Server management protocol (XSMP) virtual Ethernet (XVE) messages
- *
- ****************************************************************************
- */
-
-/**
- * Get virtual Ethernet message name (for debugging)
- *
- * @v type             Message type
- * @ret name           Message name
- */
-static const char * xsmp_xve_type ( unsigned int type ) {
-       static char buf[16];
-
-       switch ( type ) {
-       case XSMP_XVE_TYPE_INSTALL:             return "INSTALL";
-       case XSMP_XVE_TYPE_DELETE:              return "DELETE";
-       case XSMP_XVE_TYPE_UPDATE:              return "UPDATE";
-       case XSMP_XVE_TYPE_OPER_UP:             return "OPER_UP";
-       case XSMP_XVE_TYPE_OPER_DOWN:           return "OPER_DOWN";
-       case XSMP_XVE_TYPE_OPER_REQ:            return "OPER_REQ";
-       case XSMP_XVE_TYPE_READY:               return "READY";
-       default:
-               snprintf ( buf, sizeof ( buf ), "UNKNOWN<%d>", type );
-               return buf;
-       }
-}
-
-/**
- * Send virtual Ethernet message
- *
- * @v xcm              Configuration manager
- * @v msg              Partial message
- * @ret rc             Return status code
- */
-static int xsmp_tx_xve ( struct xsigo_manager *xcm,
-                        struct xsmp_xve_message *msg ) {
-       struct xsigo_device *xdev = xcm->xdev;
-       struct ib_device *ibdev = xdev->ibdev;
-       int rc;
-
-       /* Fill in common header fields */
-       msg->hdr.type = XSMP_TYPE_XVE;
-       msg->hdr.len = htons ( sizeof ( *msg ) );
-       msg->hdr.seq = htonl ( ++xcm->seq );
-       memcpy ( &msg->hdr.src.guid, &ibdev->gid.s.guid,
-                sizeof ( msg->hdr.src.guid ) );
-       memcpy ( &msg->hdr.dst.guid, &xcm->id.guid,
-                sizeof ( msg->hdr.dst.guid ) );
-       msg->len = htons ( sizeof ( *msg ) - sizeof ( msg->hdr ) );
-       DBGCP ( xcm, "XCM %s TX[%d] xve %s code %#02x\n", xcm->name,
-               ntohl ( msg->hdr.seq ), xsmp_xve_type ( msg->type ),
-               msg->code );
-       DBGCP_HDA ( xcm, 0, msg, sizeof ( *msg ) );
-
-       /* Send virtual Ethernet message */
-       if ( ( rc = xfer_deliver_raw ( &xcm->xfer, msg,
-                                      sizeof ( *msg ) ) ) != 0 ) {
-               DBGC ( xcm, "XCM %s TX xve %s failed: %s\n", xcm->name,
-                      xsmp_xve_type ( msg->type ), strerror ( rc ) );
-               return rc;
-       }
-
-       return 0;
-}
-
-/**
- * Send virtual Ethernet message including current device parameters
- *
- * @v xcm              Configuration manager
- * @v msg              Partial virtual Ethernet message
- * @v xve              Virtual Ethernet device
- * @v eoib             EoIB device
- * @ret rc             Return status code
- */
-static int xsmp_tx_xve_params ( struct xsigo_manager *xcm,
-                               struct xsmp_xve_message *msg,
-                               struct xsigo_nic *xve,
-                               struct eoib_device *eoib ) {
-       struct xsigo_device *xdev = xcm->xdev;
-       struct ib_device *ibdev = xdev->ibdev;
-       struct net_device *netdev = eoib->netdev;
-
-       /* Set successful response code */
-       msg->code = 0;
-
-       /* Include network identifier, MTU, and current HCA parameters */
-       msg->network = htonl ( xve->network );
-       msg->mtu = htons ( netdev->max_pkt_len - sizeof ( struct ethhdr ) );
-       msg->hca.prefix_le.qword = bswap_64 ( ibdev->gid.s.prefix.qword );
-       msg->hca.pkey = htons ( ibdev->pkey );
-       msg->hca.qkey = msg->tca.qkey;
-       if ( eoib->qp ) {
-               msg->hca.data = htonl ( eoib->qp->ext_qpn );
-               msg->hca.qkey = htons ( eoib->qp->qkey );
-       }
-
-       /* The message type field is (ab)used to return the current
-        * operational status.
-        */
-       if ( msg->type == XSMP_XVE_TYPE_OPER_REQ ) {
-               msg->type = ( netdev_is_open ( netdev ) ?
-                             XSMP_XVE_TYPE_OPER_UP : XSMP_XVE_TYPE_OPER_DOWN );
-       }
-
-       /* Send message */
-       DBGC ( xve, "XVE %s network %d MTU %d ctrl %#x data %#x qkey %#04x "
-              "%s\n", xve->name, ntohl ( msg->network ), ntohs ( msg->mtu ),
-              ntohl ( msg->hca.ctrl ), ntohl ( msg->hca.data ),
-              ntohs ( msg->hca.qkey ), xsmp_xve_type ( msg->type ) );
-
-       return xsmp_tx_xve ( xcm, msg );
-}
-
-/**
- * Send virtual Ethernet error response
- *
- * @v xcm              Configuration manager
- * @v msg              Partial virtual Ethernet message
- * @ret rc             Return status code
- */
-static inline int xsmp_tx_xve_nack ( struct xsigo_manager *xcm,
-                                    struct xsmp_xve_message *msg ) {
-
-       /* Set error response code.  (There aren't any meaningful
-        * detailed response codes defined by the wire protocol.)
-        */
-       msg->code = XSMP_XVE_CODE_ERROR;
-
-       /* Send message */
-       return xsmp_tx_xve ( xcm, msg );
-}
-
-/**
- * Send virtual Ethernet notification
- *
- * @v xcm              Configuration manager
- * @v type             Message type
- * @v xve              Virtual Ethernet device
- * @v eoib             EoIB device
- * @ret rc             Return status code
- */
-static int xsmp_tx_xve_notify ( struct xsigo_manager *xcm,
-                               unsigned int type,
-                               struct xsigo_nic *xve,
-                               struct eoib_device *eoib ) {
-       struct xsmp_xve_message msg;
-
-       /* Construct message */
-       memset ( &msg, 0, sizeof ( msg ) );
-       msg.type = type;
-       memcpy ( &msg.resource, &xve->resource, sizeof ( msg.resource ) );
-
-       /* Send message */
-       return xsmp_tx_xve_params ( xcm, &msg, xve, eoib );
-}
-
-/**
- * Send virtual Ethernet current operational state
- *
- * @v xcm              Configuration manager
- * @v xve              Virtual Ethernet device
- * @v eoib             EoIB device
- * @ret rc             Return status code
- */
-static inline int xsmp_tx_xve_oper ( struct xsigo_manager *xcm,
-                                    struct xsigo_nic *xve,
-                                    struct eoib_device *eoib ) {
-
-       /* Send notification */
-       return xsmp_tx_xve_notify ( xcm, XSMP_XVE_TYPE_OPER_REQ, xve, eoib );
-}
-
-/**
- * Handle received virtual Ethernet modification message
- *
- * @v xcm              Configuration manager
- * @v msg              Virtual Ethernet message
- * @v update           Update bitmask
- * @ret rc             Return status code
- */
-static int xsmp_rx_xve_modify ( struct xsigo_manager *xcm,
-                               struct xsmp_xve_message *msg,
-                               unsigned int update ) {
-       struct xsigo_device *xdev = xcm->xdev;
-       struct ib_device *ibdev = xdev->ibdev;
-       struct xsigo_nic *xve;
-       struct eoib_device *eoib;
-       struct ib_address_vector tca;
-       size_t mtu;
-       int rc;
-
-       /* Avoid returning uninitialised HCA parameters in response */
-       memset ( &msg->hca, 0, sizeof ( msg->hca ) );
-
-       /* Find virtual Ethernet device */
-       xve = xve_find ( xcm, &msg->resource );
-       if ( ! xve ) {
-               DBGC ( xcm, "XCM %s unrecognised resource " IB_GUID_FMT "\n",
-                      xcm->name, IB_GUID_ARGS ( &msg->resource ) );
-               rc = -ENOENT;
-               goto err_no_xve;
-       }
-
-       /* Find corresponding EoIB device */
-       eoib = eoib_find ( ibdev, xve->mac );
-       if ( ! eoib ) {
-               DBGC ( xve, "XVE %s has no EoIB device\n", xve->name );
-               rc = -EPIPE;
-               goto err_no_eoib;
-       }
-
-       /* The Xsigo management software fails to create the EoIB
-        * multicast group.  This is a fundamental design flaw.
-        */
-       eoib_force_group_creation ( eoib );
-
-       /* Extract modifiable parameters.  Note that the TCA GID is
-        * erroneously transmitted as little-endian.
-        */
-       mtu = ntohs ( msg->mtu );
-       tca.qpn = ntohl ( msg->tca.data );
-       tca.qkey = ntohs ( msg->tca.qkey );
-       tca.gid_present = 1;
-       tca.gid.s.prefix.qword = bswap_64 ( msg->tca.prefix_le.qword );
-       tca.gid.s.guid.qword = bswap_64 ( msg->guid_le.qword );
-
-       /* Update MTU, if applicable */
-       if ( ( update & XSMP_XVE_UPDATE_MTU ) &&
-            ( ( rc = xve_update_mtu ( xve, eoib, mtu ) ) != 0 ) )
-               goto err_mtu;
-       update &= ~XSMP_XVE_UPDATE_MTU;
-
-       /* Update admin state, if applicable */
-       if ( ( update & XSMP_XVE_UPDATE_STATE ) &&
-            ( ( rc = xve_update_state ( xve, eoib, msg->state ) ) != 0 ) )
-               goto err_state;
-       update &= ~XSMP_XVE_UPDATE_STATE;
-
-       /* Remove gateway, if applicable */
-       if ( ( update & XSMP_XVE_UPDATE_GW_DOWN ) &&
-            ( ( rc = xve_update_tca ( xve, eoib, NULL ) ) != 0 ) )
-               goto err_gw_down;
-       update &= ~XSMP_XVE_UPDATE_GW_DOWN;
-
-       /* Update gateway, if applicable */
-       if ( ( update & XSMP_XVE_UPDATE_GW_CHANGE ) &&
-            ( ( rc = xve_update_tca ( xve, eoib, &tca ) ) != 0 ) )
-               goto err_gw_change;
-       update &= ~XSMP_XVE_UPDATE_GW_CHANGE;
-
-       /* Warn about unexpected updates */
-       if ( update ) {
-               DBGC ( xve, "XVE %s unrecognised update(s) %#08x\n",
-                      xve->name, update );
-       }
-
-       xsmp_tx_xve_params ( xcm, msg, xve, eoib );
-       return 0;
-
- err_gw_change:
- err_gw_down:
- err_state:
- err_mtu:
- err_no_eoib:
- err_no_xve:
-       /* Send NACK */
-       xsmp_tx_xve_nack ( xcm, msg );
-       return rc;
-}
-
-/**
- * Handle received virtual Ethernet installation message
- *
- * @v xcm              Configuration manager
- * @v msg              Virtual Ethernet message
- * @ret rc             Return status code
- */
-static int xsmp_rx_xve_install ( struct xsigo_manager *xcm,
-                                struct xsmp_xve_message *msg ) {
-       union {
-               struct xsmp_xve_mac msg;
-               uint8_t raw[ETH_ALEN];
-       } mac;
-       char name[ sizeof ( msg->name ) + 1 /* NUL */ ];
-       unsigned long network;
-       unsigned long qkey;
-       unsigned int update;
-       int rc;
-
-       /* Demangle MAC address (which is erroneously transmitted as
-        * little-endian).
-        */
-       mac.msg.high = bswap_16 ( msg->mac_le.high );
-       mac.msg.low = bswap_32 ( msg->mac_le.low );
-
-       /* Extract interface name (which may not be NUL-terminated) */
-       memcpy ( name, msg->name, ( sizeof ( name ) - 1 /* NUL */ ) );
-       name[ sizeof ( name ) - 1 /* NUL */ ] = '\0';
-
-       /* Extract remaining message parameters */
-       network = ntohl ( msg->network );
-       qkey = ntohs ( msg->tca.qkey );
-       DBGC2 ( xcm, "XCM %s " IB_GUID_FMT " install \"%s\" %s net %ld qkey "
-               "%#lx\n", xcm->name, IB_GUID_ARGS ( &msg->resource ), name,
-               eth_ntoa ( mac.raw ), network, qkey );
-
-       /* Create virtual Ethernet device, if applicable */
-       if ( ( xve_find ( xcm, &msg->resource ) == NULL ) &&
-            ( ( rc = xve_create ( xcm, &msg->resource, mac.raw, network,
-                                  qkey, name ) ) != 0 ) )
-               goto err_create;
-
-       /* Handle remaining parameters as for a modification message */
-       update = XSMP_XVE_UPDATE_MTU;
-       if ( msg->uplink == XSMP_XVE_UPLINK )
-               update |= XSMP_XVE_UPDATE_GW_CHANGE;
-       return xsmp_rx_xve_modify ( xcm, msg, update );
-
- err_create:
-       /* Send NACK */
-       xsmp_tx_xve_nack ( xcm, msg );
-       return rc;
-}
-
-/**
- * Handle received virtual Ethernet deletion message
- *
- * @v xcm              Configuration manager
- * @v msg              Virtual Ethernet message
- * @ret rc             Return status code
- */
-static int xsmp_rx_xve_delete ( struct xsigo_manager *xcm,
-                               struct xsmp_xve_message *msg ) {
-       struct xsigo_nic *xve;
-
-       DBGC2 ( xcm, "XCM %s " IB_GUID_FMT " delete\n",
-               xcm->name, IB_GUID_ARGS ( &msg->resource ) );
-
-       /* Destroy virtual Ethernet device (if any) */
-       if ( ( xve = xve_find ( xcm, &msg->resource ) ) )
-               xve_destroy ( xve );
-
-       /* Send ACK */
-       msg->code = 0;
-       xsmp_tx_xve ( xcm, msg );
-
-       return 0;
-}
-
-/**
- * Handle received virtual Ethernet update message
- *
- * @v xcm              Configuration manager
- * @v msg              Virtual Ethernet message
- * @ret rc             Return status code
- */
-static int xsmp_rx_xve_update ( struct xsigo_manager *xcm,
-                               struct xsmp_xve_message *msg ) {
-       unsigned int update = ntohl ( msg->update );
-
-       DBGC2 ( xcm, "XCM %s " IB_GUID_FMT " update (%08x)\n",
-               xcm->name, IB_GUID_ARGS ( &msg->resource ), update );
-
-       /* Handle as a modification message */
-       return xsmp_rx_xve_modify ( xcm, msg, update );
-}
-
-/**
- * Handle received virtual Ethernet operational request message
- *
- * @v xcm              Configuration manager
- * @v msg              Virtual Ethernet message
- * @ret rc             Return status code
- */
-static int xsmp_rx_xve_oper_req ( struct xsigo_manager *xcm,
-                                 struct xsmp_xve_message *msg ) {
-
-       DBGC2 ( xcm, "XCM %s " IB_GUID_FMT " operational request\n",
-               xcm->name, IB_GUID_ARGS ( &msg->resource ) );
-
-       /* Handle as a nullipotent modification message */
-       return xsmp_rx_xve_modify ( xcm, msg, 0 );
-}
-
-/**
- * Handle received virtual Ethernet readiness message
- *
- * @v xcm              Configuration manager
- * @v msg              Virtual Ethernet message
- * @ret rc             Return status code
- */
-static int xsmp_rx_xve_ready ( struct xsigo_manager *xcm,
-                              struct xsmp_xve_message *msg ) {
-       int rc;
-
-       DBGC2 ( xcm, "XCM %s " IB_GUID_FMT " ready\n",
-               xcm->name, IB_GUID_ARGS ( &msg->resource ) );
-
-       /* Handle as a nullipotent modification message */
-       if ( ( rc = xsmp_rx_xve_modify ( xcm, msg, 0 ) ) != 0 )
-               return rc;
-
-       /* Send an unsolicited operational state update, since there
-        * is no other way to convey the current operational state.
-        */
-       msg->type = XSMP_XVE_TYPE_OPER_REQ;
-       if ( ( rc = xsmp_rx_xve_modify ( xcm, msg, 0 ) ) != 0 )
-               return rc;
-
-       return 0;
-}
-
-/**
- * Handle received virtual Ethernet message
- *
- * @v xcm              Configuration manager
- * @v msg              Virtual Ethernet message
- * @ret rc             Return status code
- */
-static int xsmp_rx_xve ( struct xsigo_manager *xcm,
-                        struct xsmp_xve_message *msg ) {
-
-       DBGCP ( xcm, "XCM %s RX[%d] xve %s\n", xcm->name,
-               ntohl ( msg->hdr.seq ), xsmp_xve_type ( msg->type ) );
-       DBGCP_HDA ( xcm, 0, msg, sizeof ( *msg ) );
-
-       /* Handle message according to type */
-       switch ( msg->type ) {
-       case XSMP_XVE_TYPE_INSTALL:
-               return xsmp_rx_xve_install ( xcm, msg );
-       case XSMP_XVE_TYPE_DELETE:
-               return xsmp_rx_xve_delete ( xcm, msg );
-       case XSMP_XVE_TYPE_UPDATE:
-               return xsmp_rx_xve_update ( xcm, msg );
-       case XSMP_XVE_TYPE_OPER_REQ:
-               return xsmp_rx_xve_oper_req ( xcm, msg );
-       case XSMP_XVE_TYPE_READY:
-               return xsmp_rx_xve_ready ( xcm, msg );
-       default:
-               DBGC ( xcm, "XCM %s RX[%d] xve unexpected %s:\n", xcm->name,
-                      ntohl ( msg->hdr.seq ), xsmp_xve_type ( msg->type ) );
-               DBGC_HDA ( xcm, 0, msg, sizeof ( *msg ) );
-               return -EPROTO;
-       }
-}
-
-/****************************************************************************
- *
- * Configuration managers (XCM)
- *
- ****************************************************************************
- */
-
-/**
- * Close configuration manager connection
- *
- * @v xcm              Configuration manager
- * @v rc               Reason for close
- */
-static void xcm_close ( struct xsigo_manager *xcm, int rc ) {
-
-       DBGC ( xcm, "XCM %s closed: %s\n", xcm->name, strerror ( rc ) );
-
-       /* Stop transmission process */
-       process_del ( &xcm->process );
-
-       /* Stop keepalive timer */
-       stop_timer ( &xcm->keepalive );
-
-       /* Restart data transfer interface */
-       intf_restart ( &xcm->xfer, rc );
-
-       /* Schedule reconnection attempt */
-       start_timer ( &xcm->reopen );
-}
-
-/**
- * Send data to configuration manager
- *
- * @v xcm              Configuration manager
- */
-static void xcm_step ( struct xsigo_manager *xcm ) {
-       int rc;
-
-       /* Do nothing unless we have something to send */
-       if ( ! xcm->pending )
-               return;
-
-       /* Send (empty) connection request, if applicable */
-       if ( xcm->pending & XCM_TX_CONNECT ) {
-               if ( ( rc = xfer_deliver_raw ( &xcm->xfer, NULL, 0 ) ) != 0 ) {
-                       DBGC ( xcm, "XCM %s could not send connection request: "
-                              "%s\n", xcm->name, strerror ( rc ) );
-                       goto err;
-               }
-               xcm->pending &= ~XCM_TX_CONNECT;
-               return;
-       }
-
-       /* Wait until data transfer interface is connected */
-       if ( ! xfer_window ( &xcm->xfer ) )
-               return;
-
-       /* Send registration message, if applicable */
-       if ( xcm->pending & XCM_TX_REGISTER ) {
-               if ( ( rc = xsmp_tx_session_register ( xcm ) ) != 0 )
-                       goto err;
-               xcm->pending &= ~XCM_TX_REGISTER;
-               return;
-       }
-
-       return;
-
- err:
-       xcm_close ( xcm, rc );
-}
-
-/**
- * Receive data from configuration manager
- *
- * @v xcm              Configuration manager
- * @v iobuf            I/O buffer
- * @v meta             Data transfer metadata
- * @ret rc             Return status code
- */
-static int xcm_deliver ( struct xsigo_manager *xcm, struct io_buffer *iobuf,
-                        struct xfer_metadata *meta __unused ) {
-       union xsmp_message *msg;
-       size_t len = iob_len ( iobuf );
-       int rc;
-
-       /* Sanity check */
-       if ( len < sizeof ( msg->hdr ) ) {
-               DBGC ( xcm, "XCM %s underlength message:\n", xcm->name );
-               DBGC_HDA ( xcm, 0, iobuf->data, iob_len ( iobuf ) );
-               rc = -EPROTO;
-               goto out;
-       }
-       msg = iobuf->data;
-
-       /* Handle message according to type */
-       if ( ! msg->hdr.type ) {
-
-               /* Ignore unused communication manager private data blocks */
-               rc = 0;
-
-       } else if ( ( msg->hdr.type == XSMP_TYPE_SESSION ) &&
-                   ( len >= sizeof ( msg->sess ) ) ) {
-
-               /* Session message */
-               rc = xsmp_rx_session ( xcm, &msg->sess );
-
-       } else if ( ( msg->hdr.type == XSMP_TYPE_XVE ) &&
-                   ( len >= sizeof ( msg->xve ) ) ) {
-
-               /* Virtual Ethernet message */
-               xsmp_rx_xve ( xcm, &msg->xve );
-
-               /* Virtual Ethernet message errors are non-fatal */
-               rc = 0;
-
-       } else {
-
-               /* Unknown message */
-               DBGC ( xcm, "XCM %s unexpected message type %d:\n",
-                      xcm->name, msg->hdr.type );
-               DBGC_HDA ( xcm, 0, iobuf->data, iob_len ( iobuf ) );
-               rc = -EPROTO;
-       }
-
- out:
-       free_iob ( iobuf );
-       if ( rc != 0 )
-               xcm_close ( xcm, rc );
-       return rc;
-}
-
-/** Configuration manager data transfer interface operations */
-static struct interface_operation xcm_xfer_op[] = {
-       INTF_OP ( xfer_deliver, struct xsigo_manager *, xcm_deliver ),
-       INTF_OP ( xfer_window_changed, struct xsigo_manager *, xcm_step ),
-       INTF_OP ( intf_close, struct xsigo_manager *, xcm_close ),
-};
-
-/** Configuration manager data transfer interface descriptor */
-static struct interface_descriptor xcm_xfer_desc =
-       INTF_DESC ( struct xsigo_manager, xfer, xcm_xfer_op );
-
-/** Configuration manager process descriptor */
-static struct process_descriptor xcm_process_desc =
-       PROC_DESC_ONCE ( struct xsigo_manager, process, xcm_step );
-
-/**
- * Handle configuration manager connection timer expiry
- *
- * @v timer            Connection timer
- * @v fail             Failure indicator
- */
-static void xcm_reopen ( struct retry_timer *timer, int fail __unused ) {
-       struct xsigo_manager *xcm =
-               container_of ( timer, struct xsigo_manager, reopen );
-       struct xsigo_device *xdev = xcm->xdev;
-       struct ib_device *ibdev = xdev->ibdev;
-       union ib_gid gid;
-       int rc;
-
-       /* Stop transmission process */
-       process_del ( &xcm->process );
-
-       /* Stop keepalive timer */
-       stop_timer ( &xcm->keepalive );
-
-       /* Restart data transfer interface */
-       intf_restart ( &xcm->xfer, -ECANCELED );
-
-       /* Reset sequence number */
-       xcm->seq = 0;
-
-       /* Construct GID */
-       memcpy ( &gid.s.prefix, &ibdev->gid.s.prefix, sizeof ( gid.s.prefix ) );
-       memcpy ( &gid.s.guid, &xcm->id.guid, sizeof ( gid.s.guid ) );
-       DBGC ( xcm, "XCM %s connecting to " IB_GID_FMT "\n",
-              xcm->name, IB_GID_ARGS ( &gid ) );
-
-       /* Open CMRC connection */
-       if ( ( rc = ib_cmrc_open ( &xcm->xfer, ibdev, &gid,
-                                  &xcm_service_id, xcm->name ) ) != 0 ) {
-               DBGC ( xcm, "XCM %s could not open CMRC connection: %s\n",
-                      xcm->name, strerror ( rc ) );
-               start_timer ( &xcm->reopen );
-               return;
-       }
-
-       /* Schedule transmissions */
-       xcm->pending |= ( XCM_TX_CONNECT | XCM_TX_REGISTER );
-       process_add ( &xcm->process );
-
-       /* Start keepalive timer */
-       start_timer_fixed ( &xcm->keepalive, XSIGO_KEEPALIVE_INTERVAL );
-
-       return;
-}
-
-/**
- * Handle configuration manager keepalive timer expiry
- *
- * @v timer            Connection timer
- * @v fail             Failure indicator
- */
-static void xcm_keepalive ( struct retry_timer *timer, int fail __unused ) {
-       struct xsigo_manager *xcm =
-               container_of ( timer, struct xsigo_manager, keepalive );
-       int rc;
-
-       /* Send keepalive message.  The server won't actually respond
-        * to these, but it gives the RC queue pair a chance to
-        * complain if it doesn't ever at least get an ACK.
-        */
-       if ( ( rc = xsmp_tx_session_hello ( xcm ) ) != 0 ) {
-               xcm_close ( xcm, rc );
-               return;
-       }
-
-       /* Restart keepalive timer */
-       start_timer_fixed ( &xcm->keepalive, XSIGO_KEEPALIVE_INTERVAL );
-}
-
-/**
- * Create configuration manager
- *
- * @v xsigo            Xsigo device
- * @v id               Configuration manager ID
- * @ret rc             Return status code
- */
-static int xcm_create ( struct xsigo_device *xdev,
-                       struct xsigo_manager_id *id ) {
-       struct xsigo_manager *xcm;
-
-       /* Allocate and initialise structure */
-       xcm = zalloc ( sizeof ( *xcm ) );
-       if ( ! xcm )
-               return -ENOMEM;
-       ref_init ( &xcm->refcnt, xcm_free );
-       xcm->xdev = xdev;
-       ref_get ( &xcm->xdev->refcnt );
-       snprintf ( xcm->name, sizeof ( xcm->name ), "%s:xcm-%d",
-                  xdev->name, ntohs ( id->lid ) );
-       memcpy ( &xcm->id, id, sizeof ( xcm->id ) );
-       intf_init ( &xcm->xfer, &xcm_xfer_desc, &xcm->refcnt );
-       timer_init ( &xcm->keepalive, xcm_keepalive, &xcm->refcnt );
-       timer_init ( &xcm->reopen, xcm_reopen, &xcm->refcnt );
-       process_init_stopped ( &xcm->process, &xcm_process_desc, &xcm->refcnt );
-       INIT_LIST_HEAD ( &xcm->nics );
-
-       /* Start timer to open connection */
-       start_timer_nodelay ( &xcm->reopen );
-
-       /* Add to list of managers and transfer reference to list */
-       list_add ( &xcm->list, &xdev->managers );
-       DBGC ( xcm, "XCM %s created for " IB_GUID_FMT " (LID %d)\n", xcm->name,
-              IB_GUID_ARGS ( &xcm->id.guid ), ntohs ( id->lid ) );
-       return 0;
-}
-
-/**
- * Find configuration manager
- *
- * @v xsigo            Xsigo device
- * @v id               Configuration manager ID
- * @ret xcm            Configuration manager, or NULL
- */
-static struct xsigo_manager * xcm_find ( struct xsigo_device *xdev,
-                                        struct xsigo_manager_id *id ) {
-       struct xsigo_manager *xcm;
-       union ib_guid *guid = &id->guid;
-
-       /* Find configuration manager */
-       list_for_each_entry ( xcm, &xdev->managers, list ) {
-               if ( memcmp ( guid, &xcm->id.guid, sizeof ( *guid ) ) == 0 )
-                       return xcm;
-       }
-       return NULL;
-}
-
-/**
- * Destroy configuration manager
- *
- * @v xcm              Configuration manager
- */
-static void xcm_destroy ( struct xsigo_manager *xcm ) {
-       struct xsigo_nic *xve;
-
-       /* Remove all EoIB NICs */
-       while ( ( xve = list_first_entry ( &xcm->nics, struct xsigo_nic,
-                                          list ) ) ) {
-               xve_destroy ( xve );
-       }
-
-       /* Stop transmission process */
-       process_del ( &xcm->process );
-
-       /* Stop timers */
-       stop_timer ( &xcm->keepalive );
-       stop_timer ( &xcm->reopen );
-
-       /* Shut down data transfer interface */
-       intf_shutdown ( &xcm->xfer, 0 );
-
-       /* Remove from list of managers and drop list's reference */
-       DBGC ( xcm, "XCM %s destroyed\n", xcm->name );
-       list_del ( &xcm->list );
-       ref_put ( &xcm->refcnt );
-}
-
-/**
- * Synchronise list of configuration managers
- *
- * @v xdev             Xsigo device
- * @v ids              List of manager IDs
- * @v count            Number of manager IDs
- * @ret rc             Return status code
- */
-static int xcm_list ( struct xsigo_device *xdev, struct xsigo_manager_id *ids,
-                     unsigned int count ) {
-       struct xsigo_manager_id *id;
-       struct xsigo_manager *xcm;
-       struct xsigo_manager *tmp;
-       struct list_head list;
-       unsigned int i;
-       int rc;
-
-       /* Create list of managers to be retained */
-       INIT_LIST_HEAD ( &list );
-       for ( i = 0, id = ids ; i < count ; i++, id++ ) {
-               if ( ( xcm = xcm_find ( xdev, id ) ) ) {
-                       list_del ( &xcm->list );
-                       list_add_tail ( &xcm->list, &list );
-               }
-       }
-
-       /* Destroy any managers not in the list */
-       list_for_each_entry_safe ( xcm, tmp, &xdev->managers, list )
-               xcm_destroy ( xcm );
-       list_splice ( &list, &xdev->managers );
-
-       /* Create any new managers in the list, and force reconnection
-        * for any changed LIDs.
-        */
-       for ( i = 0, id = ids ; i < count ; i++, id++ ) {
-               if ( ( xcm = xcm_find ( xdev, id ) ) ) {
-                       if ( xcm->id.lid != id->lid )
-                               start_timer_nodelay ( &xcm->reopen );
-                       continue;
-               }
-               if ( ( rc = xcm_create ( xdev, id ) ) != 0 ) {
-                       DBGC ( xdev, "XDEV %s could not create manager: %s\n",
-                              xdev->name, strerror ( rc ) );
-                       return rc;
-               }
-       }
-
-       return 0;
-}
-
-/****************************************************************************
- *
- * Configuration manager discovery
- *
- ****************************************************************************
- */
-
-/** A stage of discovery */
-struct xsigo_discovery {
-       /** Name */
-       const char *name;
-       /** Management transaction operations */
-       struct ib_mad_transaction_operations op;
-};
-
-/**
- * Handle configuration manager lookup completion
- *
- * @v ibdev            Infiniband device
- * @v mi               Management interface
- * @v madx             Management transaction
- * @v rc               Status code
- * @v mad              Received MAD (or NULL on error)
- * @v av               Source address vector (or NULL on error)
- */
-static void xsigo_xcm_complete ( struct ib_device *ibdev,
-                                struct ib_mad_interface *mi __unused,
-                                struct ib_mad_transaction *madx,
-                                int rc, union ib_mad *mad,
-                                struct ib_address_vector *av __unused ) {
-       struct xsigo_device *xdev = ib_madx_get_ownerdata ( madx );
-       union xsigo_mad *xsmad = container_of ( mad, union xsigo_mad, mad );
-       struct xsigo_managers_reply *reply = &xsmad->reply;
-
-       /* Check for failures */
-       if ( ( rc == 0 ) && ( mad->hdr.status != htons ( IB_MGMT_STATUS_OK ) ) )
-               rc = -ENODEV;
-       if ( rc != 0 ) {
-               DBGC ( xdev, "XDEV %s manager lookup failed: %s\n",
-                      xdev->name, strerror ( rc ) );
-               goto out;
-       }
-
-       /* Sanity checks */
-       if ( reply->count > ( sizeof ( reply->manager ) /
-                             sizeof ( reply->manager[0] ) ) ) {
-               DBGC ( xdev, "XDEV %s has too many managers (%d)\n",
-                      xdev->name, reply->count );
-               goto out;
-       }
-
-       /* Synchronise list of managers */
-       if ( ( rc = xcm_list ( xdev, reply->manager, reply->count ) ) != 0 )
-               goto out;
-
-       /* Report an empty list of managers */
-       if ( reply->count == 0 )
-               DBGC ( xdev, "XDEV %s has no managers\n", xdev->name );
-
-       /* Delay next discovery attempt */
-       start_timer_fixed ( &xdev->discovery, XSIGO_DISCOVERY_SUCCESS_DELAY );
-
-out:
-       /* Destroy the completed transaction */
-       ib_destroy_madx ( ibdev, ibdev->gsi, madx );
-       xdev->madx = NULL;
-}
-
-/** Configuration manager lookup discovery stage */
-static struct xsigo_discovery xsigo_xcm_discovery = {
-       .name = "manager",
-       .op = {
-               .complete = xsigo_xcm_complete,
-       },
-};
-
-/**
- * Handle directory service lookup completion
- *
- * @v ibdev            Infiniband device
- * @v mi               Management interface
- * @v madx             Management transaction
- * @v rc               Status code
- * @v mad              Received MAD (or NULL on error)
- * @v av               Source address vector (or NULL on error)
- */
-static void xsigo_xds_complete ( struct ib_device *ibdev,
-                                struct ib_mad_interface *mi __unused,
-                                struct ib_mad_transaction *madx,
-                                int rc, union ib_mad *mad,
-                                struct ib_address_vector *av __unused ) {
-       struct xsigo_device *xdev = ib_madx_get_ownerdata ( madx );
-       union xsigo_mad *xsmad = container_of ( mad, union xsigo_mad, mad );
-       struct xsigo_managers_request *request = &xsmad->request;
-       struct ib_service_record *svc;
-       struct ib_address_vector dest;
-       union ib_guid *guid;
-
-       /* Allow for reuse of transaction pointer */
-       xdev->madx = NULL;
-
-       /* Check for failures */
-       if ( ( rc == 0 ) && ( mad->hdr.status != htons ( IB_MGMT_STATUS_OK ) ) )
-               rc = -ENODEV;
-       if ( rc != 0 ) {
-               DBGC ( xdev, "XDEV %s directory lookup failed: %s\n",
-                      xdev->name, strerror ( rc ) );
-               goto out;
-       }
-
-       /* Construct address vector */
-       memset ( &dest, 0, sizeof ( dest ) );
-       svc = &mad->sa.sa_data.service_record;
-       dest.lid = ntohs ( svc->data16[0] );
-       dest.sl = ibdev->sm_sl;
-       dest.qpn = IB_QPN_GSI;
-       dest.qkey = IB_QKEY_GSI;
-       guid = ( ( union ib_guid * ) &svc->data64[0] );
-       DBGC2 ( xdev, "XDEV %s found directory at LID %d GUID " IB_GUID_FMT
-               "\n", xdev->name, dest.lid, IB_GUID_ARGS ( guid ) );
-
-       /* Construct request (reusing MAD buffer) */
-       memset ( request, 0, sizeof ( *request ) );
-       request->mad_hdr.mgmt_class = XSIGO_MGMT_CLASS;
-       request->mad_hdr.class_version = XSIGO_MGMT_CLASS_VERSION;
-       request->mad_hdr.method = IB_MGMT_METHOD_GET;
-       request->mad_hdr.attr_id = htons ( XSIGO_ATTR_XCM_REQUEST );
-       memcpy ( &request->server.guid, &ibdev->gid.s.guid,
-                sizeof ( request->server.guid ) );
-       snprintf ( request->os_version, sizeof ( request->os_version ),
-                  "%s %s", product_short_name, product_version );
-       snprintf ( request->arch, sizeof ( request->arch ), _S2 ( ARCH ) );
-       request->os_type = XSIGO_OS_TYPE_GENERIC;
-       request->resources = htons ( XSIGO_RESOURCES_PRESENT |
-                                    XSIGO_RESOURCE_XVE |
-                                    XSIGO_RESOURCE_NO_HA );
-
-       /* The handling of this request on the server side is a
-        * textbook example of how not to design a wire protocol.  The
-        * server uses the _driver_ version number to determine which
-        * fields are present.
-        */
-       request->driver_version = htonl ( 0x2a2a2a );
-
-       /* The build version field is ignored unless it happens to
-        * contain the substring "xg-".
-        */
-       snprintf ( request->build, sizeof ( request->build ),
-                  "not-xg-%08lx", build_id );
-
-       /* The server side user interface occasionally has no way to
-        * refer to an entry with an empty hostname.
-        */
-       fetch_string_setting ( NULL, &hostname_setting, request->hostname,
-                              sizeof ( request->hostname ) );
-       if ( ! request->hostname[0] ) {
-               snprintf ( request->hostname, sizeof ( request->hostname ),
-                          "%s-" IB_GUID_FMT, product_short_name,
-                          IB_GUID_ARGS ( &ibdev->gid.s.guid ) );
-       }
-
-       /* Start configuration manager lookup */
-       xdev->madx = ib_create_madx ( ibdev, ibdev->gsi, mad, &dest,
-                                     &xsigo_xcm_discovery.op );
-       if ( ! xdev->madx ) {
-               DBGC ( xdev, "XDEV %s could not start manager lookup\n",
-                      xdev->name );
-               goto out;
-       }
-       ib_madx_set_ownerdata ( xdev->madx, xdev );
-
-out:
-       /* Destroy the completed transaction */
-       ib_destroy_madx ( ibdev, ibdev->gsi, madx );
-}
-
-/** Directory service lookup discovery stage */
-static struct xsigo_discovery xsigo_xds_discovery = {
-       .name = "directory",
-       .op = {
-               .complete = xsigo_xds_complete,
-       },
-};
-
-/**
- * Discover configuration managers
- *
- * @v timer            Retry timer
- * @v over             Failure indicator
- */
-static void xsigo_discover ( struct retry_timer *timer, int over __unused ) {
-       struct xsigo_device *xdev =
-               container_of ( timer, struct xsigo_device, discovery );
-       struct ib_device *ibdev = xdev->ibdev;
-       struct xsigo_discovery *discovery;
-
-       /* Restart timer */
-       start_timer_fixed ( &xdev->discovery, XSIGO_DISCOVERY_FAILURE_DELAY );
-
-       /* Cancel any pending discovery transaction */
-       if ( xdev->madx ) {
-               discovery = container_of ( xdev->madx->op,
-                                          struct xsigo_discovery, op );
-               DBGC ( xdev, "XDEV %s timed out waiting for %s lookup\n",
-                      xdev->name, discovery->name );
-               ib_destroy_madx ( ibdev, ibdev->gsi, xdev->madx );
-               xdev->madx = NULL;
-       }
-
-       /* Start directory service lookup */
-       xdev->madx = ib_create_service_madx ( ibdev, ibdev->gsi,
-                                             XDS_SERVICE_NAME,
-                                             &xsigo_xds_discovery.op );
-       if ( ! xdev->madx ) {
-               DBGC ( xdev, "XDEV %s could not start directory lookup\n",
-                      xdev->name );
-               return;
-       }
-       ib_madx_set_ownerdata ( xdev->madx, xdev );
-}
-
-/****************************************************************************
- *
- * Infiniband device driver
- *
- ****************************************************************************
- */
-
-/**
- * Open link and start discovery
- *
- * @v opener           Link opener
- * @v over             Failure indicator
- */
-static void xsigo_ib_open ( struct retry_timer *opener, int over __unused ) {
-       struct xsigo_device *xdev =
-               container_of ( opener, struct xsigo_device, opener );
-       struct ib_device *ibdev = xdev->ibdev;
-       int rc;
-
-       /* Open Infiniband device */
-       if ( ( rc = ib_open ( ibdev ) ) != 0 ) {
-               DBGC ( xdev, "XDEV %s could not open: %s\n",
-                      xdev->name, strerror ( rc ) );
-               /* Delay and try again */
-               start_timer_fixed ( &xdev->opener, XSIGO_OPEN_RETRY_DELAY );
-               return;
-       }
-
-       /* If link is already up, then start discovery */
-       if ( ib_link_ok ( ibdev ) )
-               start_timer_nodelay ( &xdev->discovery );
-}
-
-/**
- * Probe Xsigo device
- *
- * @v ibdev            Infiniband device
- * @ret rc             Return status code
- */
-static int xsigo_ib_probe ( struct ib_device *ibdev ) {
-       struct xsigo_device *xdev;
-
-       /* Allocate and initialise structure */
-       xdev = zalloc ( sizeof ( *xdev ) );
-       if ( ! xdev )
-               return -ENOMEM;
-       ref_init ( &xdev->refcnt, xsigo_free );
-       xdev->ibdev = ibdev_get ( ibdev );
-       xdev->name = ibdev->name;
-       timer_init ( &xdev->opener, xsigo_ib_open, &xdev->refcnt );
-       timer_init ( &xdev->discovery, xsigo_discover, &xdev->refcnt );
-       INIT_LIST_HEAD ( &xdev->managers );
-
-       /* Start timer to open Infiniband device.  (We are currently
-        * within the Infiniband device probe callback list; opening
-        * the device here would have interesting side-effects.)
-        */
-       start_timer_nodelay ( &xdev->opener );
-
-       /* Add to list of devices and transfer reference to list */
-       list_add_tail ( &xdev->list, &xsigo_devices );
-       DBGC ( xdev, "XDEV %s created for " IB_GUID_FMT "\n",
-              xdev->name, IB_GUID_ARGS ( &ibdev->gid.s.guid ) );
-       return 0;
-}
-
-/**
- * Handle device or link status change
- *
- * @v ibdev            Infiniband device
- */
-static void xsigo_ib_notify ( struct ib_device *ibdev ) {
-       struct xsigo_device *xdev;
-
-       /* Stop/restart discovery on any attached devices */
-       list_for_each_entry ( xdev, &xsigo_devices, list ) {
-
-               /* Skip non-attached devices */
-               if ( xdev->ibdev != ibdev )
-                       continue;
-
-               /* Stop any ongoing discovery */
-               if ( xdev->madx ) {
-                       ib_destroy_madx ( ibdev, ibdev->gsi, xdev->madx );
-                       xdev->madx = NULL;
-               }
-               stop_timer ( &xdev->discovery );
-
-               /* If link is up, then start discovery */
-               if ( ib_link_ok ( ibdev ) )
-                       start_timer_nodelay ( &xdev->discovery );
-       }
-}
-
-/**
- * Remove Xsigo device
- *
- * @v ibdev            Infiniband device
- */
-static void xsigo_ib_remove ( struct ib_device *ibdev ) {
-       struct xsigo_device *xdev;
-       struct xsigo_device *tmp;
-
-       /* Remove any attached Xsigo devices */
-       list_for_each_entry_safe ( xdev, tmp, &xsigo_devices, list ) {
-
-               /* Skip non-attached devices */
-               if ( xdev->ibdev != ibdev )
-                       continue;
-
-               /* Stop any ongoing discovery */
-               if ( xdev->madx ) {
-                       ib_destroy_madx ( ibdev, ibdev->gsi, xdev->madx );
-                       xdev->madx = NULL;
-               }
-               stop_timer ( &xdev->discovery );
-
-               /* Destroy all configuration managers */
-               xcm_list ( xdev, NULL, 0 );
-
-               /* Close Infiniband device, if applicable */
-               if ( ! timer_running ( &xdev->opener ) )
-                       ib_close ( xdev->ibdev );
-
-               /* Stop link opener */
-               stop_timer ( &xdev->opener );
-
-               /* Remove from list of devices and drop list's reference */
-               DBGC ( xdev, "XDEV %s destroyed\n", xdev->name );
-               list_del ( &xdev->list );
-               ref_put ( &xdev->refcnt );
-       }
-}
-
-/** Xsigo Infiniband driver */
-struct ib_driver xsigo_ib_driver __ib_driver = {
-       .name = "Xsigo",
-       .probe = xsigo_ib_probe,
-       .notify = xsigo_ib_notify,
-       .remove = xsigo_ib_remove,
-};
-
-/****************************************************************************
- *
- * Network device driver
- *
- ****************************************************************************
- */
-
-/**
- * Handle device or link status change
- *
- * @v netdev           Network device
- */
-static void xsigo_net_notify ( struct net_device *netdev ) {
-       struct xsigo_device *xdev;
-       struct ib_device *ibdev;
-       struct xsigo_manager *xcm;
-       struct xsigo_nic *xve;
-       struct eoib_device *eoib;
-
-       /* Send current operational state to XCM, if applicable */
-       list_for_each_entry ( xdev, &xsigo_devices, list ) {
-               ibdev = xdev->ibdev;
-               list_for_each_entry ( xcm, &xdev->managers, list ) {
-                       list_for_each_entry ( xve, &xcm->nics, list ) {
-                               eoib = eoib_find ( ibdev, xve->mac );
-                               if ( ! eoib )
-                                       continue;
-                               if ( eoib->netdev != netdev )
-                                       continue;
-                               xsmp_tx_xve_oper ( xcm, xve, eoib );
-                       }
-               }
-       }
-}
-
-/** Xsigo network driver */
-struct net_driver xsigo_net_driver __net_driver = {
-       .name = "Xsigo",
-       .notify = xsigo_net_notify,
-};
index 8eb04a6..a547840 100644 (file)
@@ -358,11 +358,8 @@ static int ipv4_tx ( struct io_buffer *iobuf,
                               ( ( netdev->rx_stats.good & 0xf ) << 0 ) );
 
        /* Fix up checksums */
-       if ( trans_csum ) {
+       if ( trans_csum )
                *trans_csum = ipv4_pshdr_chksum ( iobuf, *trans_csum );
-               if ( ! *trans_csum )
-                       *trans_csum = tcpip_protocol->zero_csum;
-       }
        iphdr->chksum = tcpip_chksum ( iphdr, sizeof ( *iphdr ) );
 
        /* Print IP4 header for debugging */
@@ -717,7 +714,6 @@ struct tcpip_net_protocol ipv4_tcpip_protocol __tcpip_net_protocol = {
        .name = "IPv4",
        .sa_family = AF_INET,
        .header_len = sizeof ( struct iphdr ),
-       .net_protocol = &ipv4_protocol,
        .tx = ipv4_tx,
        .netdev = ipv4_netdev,
 };
index bbc00d3..a75e72d 100644 (file)
@@ -522,8 +522,6 @@ static int ipv6_tx ( struct io_buffer *iobuf,
                *trans_csum = ipv6_pshdr_chksum ( iphdr, len,
                                                  tcpip_protocol->tcpip_proto,
                                                  *trans_csum );
-               if ( ! *trans_csum )
-                       *trans_csum = tcpip_protocol->zero_csum;
        }
 
        /* Print IPv6 header for debugging */
@@ -1003,7 +1001,6 @@ struct tcpip_net_protocol ipv6_tcpip_protocol __tcpip_net_protocol = {
        .name = "IPv6",
        .sa_family = AF_INET6,
        .header_len = sizeof ( struct ipv6_header ),
-       .net_protocol = &ipv6_protocol,
        .tx = ipv6_tx,
        .netdev = ipv6_netdev,
 };
index 7d893a1..edd4c4b 100644 (file)
@@ -65,11 +65,6 @@ const struct setting chip_setting __setting ( SETTING_NETDEV, chip ) = {
        .description = "Chip",
        .type = &setting_type_string,
 };
-const struct setting ifname_setting __setting ( SETTING_NETDEV, ifname ) = {
-       .name = "ifname",
-       .description = "Interface name",
-       .type = &setting_type_string,
-};
 
 /**
  * Store MAC address setting
@@ -141,8 +136,7 @@ static int netdev_fetch_bustype ( struct net_device *netdev, void *data,
        assert ( desc->bus_type < ( sizeof ( bustypes ) /
                                    sizeof ( bustypes[0] ) ) );
        bustype = bustypes[desc->bus_type];
-       if ( ! bustype )
-               return -ENOENT;
+       assert ( bustype != NULL );
        strncpy ( data, bustype, len );
        return strlen ( bustype );
 }
@@ -205,22 +199,6 @@ static int netdev_fetch_chip ( struct net_device *netdev, void *data,
        return strlen ( chip );
 }
 
-/**
- * Fetch ifname setting
- *
- * @v netdev           Network device
- * @v data             Buffer to fill with setting data
- * @v len              Length of buffer
- * @ret len            Length of setting data, or negative error
- */
-static int netdev_fetch_ifname ( struct net_device *netdev, void *data,
-                                size_t len ) {
-       const char *ifname = netdev->name;
-
-       strncpy ( data, ifname, len );
-       return strlen ( ifname );
-}
-
 /** A network device setting operation */
 struct netdev_setting_operation {
        /** Setting */
@@ -251,7 +229,6 @@ static struct netdev_setting_operation netdev_setting_operations[] = {
        { &busloc_setting, NULL, netdev_fetch_busloc },
        { &busid_setting, NULL, netdev_fetch_busid },
        { &chip_setting, NULL, netdev_fetch_chip },
-       { &ifname_setting, NULL, netdev_fetch_ifname },
 };
 
 /**
index 9df2119..7c40a2a 100644 (file)
@@ -675,14 +675,6 @@ int register_netdev ( struct net_device *netdev ) {
                goto err_duplicate;
        }
 
-       /* Reject named network devices that already exist */
-       if ( netdev->name[0] && ( duplicate = find_netdev ( netdev->name ) ) ) {
-               DBGC ( netdev, "NETDEV rejecting duplicate name %s\n",
-                      duplicate->name );
-               rc = -EEXIST;
-               goto err_duplicate;
-       }
-
        /* Record device index and create device name */
        if ( netdev->name[0] == '\0' ) {
                snprintf ( netdev->name, sizeof ( netdev->name ), "net%d",
@@ -733,8 +725,6 @@ int register_netdev ( struct net_device *netdev ) {
        clear_settings ( netdev_settings ( netdev ) );
        unregister_settings ( netdev_settings ( netdev ) );
  err_register_settings:
-       list_del ( &netdev->list );
-       netdev_put ( netdev );
  err_duplicate:
        return rc;
 }
index 9fd52b7..fd7ea08 100644 (file)
@@ -700,20 +700,17 @@ static int peerblk_parse_header ( struct peerdist_block *peerblk ) {
                return -EPROTO;
        }
 
-       /* Allocate cipher context, if applicable.  Freeing the cipher
-        * context (on error or otherwise) is handled by peerblk_reset().
+       /* Allocate cipher context.  Freeing the cipher context (on
+        * error or otherwise) is handled by peerblk_reset().
         */
        peerblk->cipher = cipher;
        assert ( peerblk->cipherctx == NULL );
-       if ( cipher ) {
-               peerblk->cipherctx = malloc ( cipher->ctxsize );
-               if ( ! peerblk->cipherctx )
-                       return -ENOMEM;
-       }
+       peerblk->cipherctx = malloc ( cipher->ctxsize );
+       if ( ! peerblk->cipherctx )
+               return -ENOMEM;
 
-       /* Initialise cipher, if applicable */
-       if ( cipher &&
-            ( rc = cipher_setkey ( cipher, peerblk->cipherctx, peerblk->secret,
+       /* Initialise cipher */
+       if ( ( rc = cipher_setkey ( cipher, peerblk->cipherctx, peerblk->secret,
                                    keylen ) ) != 0 ) {
                DBGC ( peerblk, "PEERBLK %p %d.%d could not set key: %s\n",
                       peerblk, peerblk->segment, peerblk->block,
index defdaed..d4e65a1 100644 (file)
@@ -40,15 +40,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /* Disambiguate the various error causes */
 #define ENOTSUP_PROTOCOL __einfo_error ( EINFO_ENOTSUP_PROTOCOL )
 #define EINFO_ENOTSUP_PROTOCOL                                 \
-       __einfo_uniqify ( EINFO_ENOTSUP, 0x02,                  \
+       __einfo_uniqify ( EINFO_ENOTSUP, 0x01,                  \
                          "Non-STP packet received" )
 #define ENOTSUP_VERSION __einfo_error ( EINFO_ENOTSUP_VERSION )
 #define EINFO_ENOTSUP_VERSION                                  \
-       __einfo_uniqify ( EINFO_ENOTSUP, 0x03,                  \
+       __einfo_uniqify ( EINFO_ENOTSUP, 0x01,                  \
                          "Legacy STP packet received" )
 #define ENOTSUP_TYPE __einfo_error ( EINFO_ENOTSUP_TYPE )
 #define EINFO_ENOTSUP_TYPE                                     \
-       __einfo_uniqify ( EINFO_ENOTSUP, 0x04,                  \
+       __einfo_uniqify ( EINFO_ENOTSUP, 0x01,                  \
                          "Non-RSTP packet received" )
 
 /**
index 37a202e..c69c83b 100644 (file)
@@ -113,8 +113,6 @@ struct tcp_connection {
        struct process process;
        /** Retransmission timer */
        struct retry_timer timer;
-       /** Keepalive timer */
-       struct retry_timer keepalive;
        /** Shutdown (TIME_WAIT) timer */
        struct retry_timer wait;
 
@@ -179,7 +177,6 @@ static struct profiler tcp_xfer_profiler __profiler = { .name = "tcp.xfer" };
 static struct process_descriptor tcp_process_desc;
 static struct interface_descriptor tcp_xfer_desc;
 static void tcp_expired ( struct retry_timer *timer, int over );
-static void tcp_keepalive_expired ( struct retry_timer *timer, int over );
 static void tcp_wait_expired ( struct retry_timer *timer, int over );
 static struct tcp_connection * tcp_demux ( unsigned int local_port );
 static int tcp_rx_ack ( struct tcp_connection *tcp, uint32_t ack,
@@ -287,7 +284,6 @@ static int tcp_open ( struct interface *xfer, struct sockaddr *peer,
        intf_init ( &tcp->xfer, &tcp_xfer_desc, &tcp->refcnt );
        process_init_stopped ( &tcp->process, &tcp_process_desc, &tcp->refcnt );
        timer_init ( &tcp->timer, tcp_expired, &tcp->refcnt );
-       timer_init ( &tcp->keepalive, tcp_keepalive_expired, &tcp->refcnt );
        timer_init ( &tcp->wait, tcp_wait_expired, &tcp->refcnt );
        tcp->prev_tcp_state = TCP_CLOSED;
        tcp->tcp_state = TCP_STATE_SENT ( TCP_SYN );
@@ -384,7 +380,6 @@ static void tcp_close ( struct tcp_connection *tcp, int rc ) {
                /* Remove from list and drop reference */
                process_del ( &tcp->process );
                stop_timer ( &tcp->timer );
-               stop_timer ( &tcp->keepalive );
                stop_timer ( &tcp->wait );
                list_del ( &tcp->list );
                ref_put ( &tcp->refcnt );
@@ -399,9 +394,6 @@ static void tcp_close ( struct tcp_connection *tcp, int rc ) {
        if ( ! ( tcp->tcp_state & TCP_STATE_ACKED ( TCP_SYN ) ) )
                tcp_rx_ack ( tcp, ( tcp->snd_seq + 1 ), 0 );
 
-       /* Stop keepalive timer */
-       stop_timer ( &tcp->keepalive );
-
        /* If we have no data remaining to send, start sending FIN */
        if ( list_empty ( &tcp->tx_queue ) &&
             ! ( tcp->tcp_state & TCP_STATE_SENT ( TCP_FIN ) ) ) {
@@ -810,32 +802,6 @@ static void tcp_expired ( struct retry_timer *timer, int over ) {
 }
 
 /**
- * Keepalive timer expired
- *
- * @v timer            Keepalive timer
- * @v over             Failure indicator
- */
-static void tcp_keepalive_expired ( struct retry_timer *timer,
-                                   int over __unused ) {
-       struct tcp_connection *tcp =
-               container_of ( timer, struct tcp_connection, keepalive );
-
-       DBGC ( tcp, "TCP %p sending keepalive\n", tcp );
-
-       /* Reset keepalive timer */
-       start_timer_fixed ( &tcp->keepalive, TCP_KEEPALIVE_DELAY );
-
-       /* Send keepalive.  We do this only to preserve or restore
-        * state in intermediate devices (e.g. firewall NAT tables);
-        * we don't actually care about eliciting a response to verify
-        * that the peer is still alive.  We therefore send just a
-        * pure ACK, to keep our transmit path simple.
-        */
-       tcp->flags |= TCP_ACK_PENDING;
-       tcp_xmit ( tcp );
-}
-
-/**
  * Shutdown timer expired
  *
  * @v timer            Shutdown timer
@@ -938,86 +904,50 @@ static struct tcp_connection * tcp_demux ( unsigned int local_port ) {
 /**
  * Parse TCP received options
  *
- * @v tcp              TCP connection (may be NULL)
- * @v tcphdr           TCP header
- * @v hlen             TCP header length
+ * @v tcp              TCP connection
+ * @v data             Raw options data
+ * @v len              Raw options length
  * @v options          Options structure to fill in
- * @ret rc             Return status code
  */
-static int tcp_rx_opts ( struct tcp_connection *tcp,
-                        const struct tcp_header *tcphdr, size_t hlen,
-                        struct tcp_options *options ) {
-       const void *data = ( ( ( void * ) tcphdr ) + sizeof ( *tcphdr ) );
-       const void *end = ( ( ( void * ) tcphdr ) + hlen );
+static void tcp_rx_opts ( struct tcp_connection *tcp, const void *data,
+                         size_t len, struct tcp_options *options ) {
+       const void *end = ( data + len );
        const struct tcp_option *option;
        unsigned int kind;
-       size_t remaining;
-       size_t min;
-
-       /* Sanity check */
-       assert ( hlen >= sizeof ( *tcphdr ) );
 
-       /* Parse options */
        memset ( options, 0, sizeof ( *options ) );
-       while ( ( remaining = ( end - data ) ) ) {
-
-               /* Extract option code */
+       while ( data < end ) {
                option = data;
                kind = option->kind;
-
-               /* Handle single-byte options */
                if ( kind == TCP_OPTION_END )
-                       break;
+                       return;
                if ( kind == TCP_OPTION_NOP ) {
                        data++;
                        continue;
                }
-
-               /* Handle multi-byte options */
-               min = sizeof ( *option );
                switch ( kind ) {
                case TCP_OPTION_MSS:
-                       /* Ignore received MSS */
+                       options->mssopt = data;
                        break;
                case TCP_OPTION_WS:
                        options->wsopt = data;
-                       min = sizeof ( *options->wsopt );
                        break;
                case TCP_OPTION_SACK_PERMITTED:
                        options->spopt = data;
-                       min = sizeof ( *options->spopt );
                        break;
                case TCP_OPTION_SACK:
                        /* Ignore received SACKs */
                        break;
                case TCP_OPTION_TS:
                        options->tsopt = data;
-                       min = sizeof ( *options->tsopt );
                        break;
                default:
                        DBGC ( tcp, "TCP %p received unknown option %d\n",
                               tcp, kind );
                        break;
                }
-               if ( remaining < min ) {
-                       DBGC ( tcp, "TCP %p received truncated option %d\n",
-                              tcp, kind );
-                       return -EINVAL;
-               }
-               if ( option->length < min ) {
-                       DBGC ( tcp, "TCP %p received underlength option %d\n",
-                              tcp, kind );
-                       return -EINVAL;
-               }
-               if ( option->length > remaining ) {
-                       DBGC ( tcp, "TCP %p received overlength option %d\n",
-                              tcp, kind );
-                       return -EINVAL;
-               }
                data += option->length;
        }
-
-       return 0;
 }
 
 /**
@@ -1081,12 +1011,6 @@ static int tcp_rx_syn ( struct tcp_connection *tcp, uint32_t seq,
                        tcp->snd_win_scale = options->wsopt->scale;
                        tcp->rcv_win_scale = TCP_RX_WINDOW_SCALE;
                }
-               DBGC ( tcp, "TCP %p using %stimestamps, %sSACK, TX window "
-                      "x%d, RX window x%d\n", tcp,
-                      ( ( tcp->flags & TCP_TS_ENABLED ) ? "" : "no " ),
-                      ( ( tcp->flags & TCP_SACK_ENABLED ) ? "" : "no " ),
-                      ( 1 << tcp->snd_win_scale ),
-                      ( 1 << tcp->rcv_win_scale ) );
        }
 
        /* Ignore duplicate SYN */
@@ -1139,10 +1063,6 @@ static int tcp_rx_ack ( struct tcp_connection *tcp, uint32_t ack,
        /* Update window size */
        tcp->snd_win = win;
 
-       /* Hold off (or start) the keepalive timer, if applicable */
-       if ( ! ( tcp->tcp_state & TCP_STATE_SENT ( TCP_FIN ) ) )
-               start_timer_fixed ( &tcp->keepalive, TCP_KEEPALIVE_DELAY );
-
        /* Ignore ACKs that don't actually acknowledge any new data.
         * (In particular, do not stop the retransmission timer; this
         * avoids creating a sorceror's apprentice syndrome when a
@@ -1449,8 +1369,8 @@ static int tcp_rx ( struct io_buffer *iobuf,
        ack = ntohl ( tcphdr->ack );
        raw_win = ntohs ( tcphdr->win );
        flags = tcphdr->flags;
-       if ( ( rc = tcp_rx_opts ( tcp, tcphdr, hlen, &options ) ) != 0 )
-               goto discard;
+       tcp_rx_opts ( tcp, ( ( ( void * ) tcphdr ) + sizeof ( *tcphdr ) ),
+                     ( hlen - sizeof ( *tcphdr ) ), &options );
        if ( tcp && options.tsopt )
                tcp->ts_val = ntohl ( options.tsopt->tsval );
        iob_pull ( iobuf, hlen );
index a2c01a4..7e4877b 100644 (file)
@@ -237,7 +237,6 @@ int http_connect ( struct interface *xfer, struct uri *uri ) {
        struct http_scheme *scheme;
        struct sockaddr_tcpip server;
        struct interface *socket;
-       unsigned int port;
        int rc;
 
        /* Identify scheme */
@@ -249,9 +248,6 @@ int http_connect ( struct interface *xfer, struct uri *uri ) {
        if ( ! uri->host )
                return -EINVAL;
 
-       /* Identify port */
-       port = uri_port ( uri, scheme->port );
-
        /* Look for a reusable connection in the pool */
        list_for_each_entry ( conn, &http_connection_pool, pool.list ) {
 
@@ -261,16 +257,15 @@ int http_connect ( struct interface *xfer, struct uri *uri ) {
 
                /* Reuse connection, if possible */
                if ( ( scheme == conn->scheme ) &&
-                    ( strcmp ( uri->host, conn->uri->host ) == 0 ) &&
-                    ( port == uri_port ( conn->uri, scheme->port ) ) ) {
+                    ( strcmp ( uri->host, conn->uri->host ) == 0 ) ) {
 
                        /* Remove from connection pool, stop timer,
                         * attach to parent interface, and return.
                         */
                        pool_del ( &conn->pool );
                        intf_plug_plug ( &conn->xfer, xfer );
-                       DBGC2 ( conn, "HTTPCONN %p reused %s://%s:%d\n", conn,
-                               conn->scheme->name, conn->uri->host, port );
+                       DBGC2 ( conn, "HTTPCONN %p reused %s://%s\n",
+                               conn, conn->scheme->name, conn->uri->host );
                        return 0;
                }
        }
@@ -286,7 +281,7 @@ int http_connect ( struct interface *xfer, struct uri *uri ) {
 
        /* Open socket */
        memset ( &server, 0, sizeof ( server ) );
-       server.st_port = htons ( port );
+       server.st_port = htons ( uri_port ( uri, scheme->port ) );
        socket = &conn->socket;
        if ( scheme->filter &&
             ( ( rc = scheme->filter ( socket, uri->host, &socket ) ) != 0 ) )
@@ -301,13 +296,13 @@ int http_connect ( struct interface *xfer, struct uri *uri ) {
        ref_put ( &conn->refcnt );
 
        DBGC2 ( conn, "HTTPCONN %p created %s://%s:%d\n", conn,
-               conn->scheme->name, conn->uri->host, port );
+               conn->scheme->name, conn->uri->host, ntohs ( server.st_port ) );
        return 0;
 
  err_open:
  err_filter:
-       DBGC2 ( conn, "HTTPCONN %p could not create %s://%s:%d: %s\n", conn,
-               conn->scheme->name, conn->uri->host, port, strerror ( rc ) );
+       DBGC2 ( conn, "HTTPCONN %p could not create %s://%s: %s\n",
+               conn, conn->scheme->name, conn->uri->host, strerror ( rc ) );
        http_conn_close ( conn, rc );
        ref_put ( &conn->refcnt );
        return rc;
index b1f74bc..af3ca97 100644 (file)
@@ -189,8 +189,8 @@ char * http_token ( char **line, char **value ) {
        if ( value )
                *value = NULL;
 
-       /* Skip any initial whitespace or commas */
-       while ( ( isspace ( **line ) ) || ( **line == ',' ) )
+       /* Skip any initial whitespace */
+       while ( isspace ( **line ) )
                (*line)++;
 
        /* Check for end of line and record token position */
@@ -201,8 +201,8 @@ char * http_token ( char **line, char **value ) {
        /* Scan for end of token */
        while ( ( c = **line ) ) {
 
-               /* Terminate if we hit an unquoted whitespace or comma */
-               if ( ( isspace ( c ) || ( c == ',' ) ) && ! quote )
+               /* Terminate if we hit an unquoted whitespace */
+               if ( isspace ( c ) && ! quote )
                        break;
 
                /* Terminate if we hit a closing quote */
@@ -685,51 +685,6 @@ int http_open ( struct interface *xfer, struct http_method *method,
 }
 
 /**
- * Redirect HTTP transaction
- *
- * @v http             HTTP transaction
- * @v location         New location
- * @ret rc             Return status code
- */
-static int http_redirect ( struct http_transaction *http,
-                          const char *location ) {
-       struct uri *location_uri;
-       struct uri *resolved_uri;
-       int rc;
-
-       DBGC2 ( http, "HTTP %p redirecting to \"%s\"\n", http, location );
-
-       /* Parse location URI */
-       location_uri = parse_uri ( location );
-       if ( ! location_uri ) {
-               rc = -ENOMEM;
-               goto err_parse_uri;
-       }
-
-       /* Resolve as relative to original URI */
-       resolved_uri = resolve_uri ( http->uri, location_uri );
-       if ( ! resolved_uri ) {
-               rc = -ENOMEM;
-               goto err_resolve_uri;
-       }
-
-       /* Redirect to new URI */
-       if ( ( rc = xfer_redirect ( &http->xfer, LOCATION_URI,
-                                   resolved_uri ) ) != 0 ) {
-               DBGC ( http, "HTTP %p could not redirect: %s\n",
-                      http, strerror ( rc ) );
-               goto err_redirect;
-       }
-
- err_redirect:
-       uri_put ( resolved_uri );
- err_resolve_uri:
-       uri_put ( location_uri );
- err_parse_uri:
-       return rc;
-}
-
-/**
  * Handle successful transfer completion
  *
  * @v http             HTTP transaction
@@ -762,8 +717,14 @@ static int http_transfer_complete ( struct http_transaction *http ) {
 
        /* Perform redirection, if applicable */
        if ( ( location = http->response.location ) ) {
-               if ( ( rc = http_redirect ( http, location ) ) != 0 )
+               DBGC2 ( http, "HTTP %p redirecting to \"%s\"\n",
+                       http, location );
+               if ( ( rc = xfer_redirect ( &http->xfer, LOCATION_URI_STRING,
+                                           location ) ) != 0 ) {
+                       DBGC ( http, "HTTP %p could not redirect: %s\n",
+                              http, strerror ( rc ) );
                        return rc;
+               }
                http_close ( http, 0 );
                return 0;
        }
@@ -1201,17 +1162,13 @@ static int http_parse_header ( struct http_transaction *http, char *line ) {
        DBGC2 ( http, "HTTP %p RX %s\n", http, line );
 
        /* Extract header name */
-       sep = strchr ( line, ':' );
+       sep = strstr ( line, ": " );
        if ( ! sep ) {
                DBGC ( http, "HTTP %p malformed header \"%s\"\n", http, line );
                return -EINVAL_HEADER;
        }
        *sep = '\0';
-
-       /* Extract remainder of line */
-       line = ( sep + 1 );
-       while ( isspace ( *line ) )
-               line++;
+       line = ( sep + 2 /* ": " */ );
 
        /* Process header, if recognised */
        for_each_table_entry ( header, HTTP_RESPONSE_HEADERS ) {
@@ -1319,17 +1276,19 @@ http_response_transfer_encoding __http_response_header = {
  * @ret rc             Return status code
  */
 static int http_parse_connection ( struct http_transaction *http, char *line ) {
-       char *token;
 
        /* Check for known connection intentions */
-       while ( ( token = http_token ( &line, NULL ) ) ) {
-               if ( strcasecmp ( token, "keep-alive" ) == 0 )
-                       http->response.flags |= HTTP_RESPONSE_KEEPALIVE;
-               if ( strcasecmp ( token, "close" ) == 0 )
-                       http->response.flags &= ~HTTP_RESPONSE_KEEPALIVE;
+       if ( strcasecmp ( line, "keep-alive" ) == 0 ) {
+               http->response.flags |= HTTP_RESPONSE_KEEPALIVE;
+               return 0;
+       }
+       if ( strcasecmp ( line, "close" ) == 0 ) {
+               http->response.flags &= ~HTTP_RESPONSE_KEEPALIVE;
+               return 0;
        }
 
-       return 0;
+       DBGC ( http, "HTTP %p unrecognised Connection \"%s\"\n", http, line );
+       return -ENOTSUP_CONNECTION;
 }
 
 /** HTTP "Connection" header */
@@ -1867,7 +1826,7 @@ static size_t http_params ( struct parameters *params, char *buf, size_t len ) {
                }
 
                /* URI-encode the key */
-               frag_len = uri_encode_string ( 0, param->key, buf, remaining );
+               frag_len = uri_encode ( param->key, 0, buf, remaining );
                buf += frag_len;
                len += frag_len;
                remaining -= frag_len;
@@ -1880,7 +1839,7 @@ static size_t http_params ( struct parameters *params, char *buf, size_t len ) {
                remaining--;
 
                /* URI-encode the value */
-               frag_len = uri_encode_string ( 0, param->value, buf, remaining);
+               frag_len = uri_encode ( param->value, 0, buf, remaining );
                buf += frag_len;
                len += frag_len;
                remaining -= frag_len;
index c9e4ee7..5ad982f 100644 (file)
@@ -62,18 +62,19 @@ int tcpip_rx ( struct io_buffer *iobuf, struct net_device *netdev,
 /**
  * Find TCP/IP network-layer protocol
  *
- * @v sa_family                Address family
+ * @v st_dest          Destination address
  * @ret tcpip_net      TCP/IP network-layer protocol, or NULL if not found
  */
-struct tcpip_net_protocol * tcpip_net_protocol ( sa_family_t sa_family ) {
+static struct tcpip_net_protocol *
+tcpip_net_protocol ( struct sockaddr_tcpip *st_dest ) {
        struct tcpip_net_protocol *tcpip_net;
 
        for_each_table_entry ( tcpip_net, TCPIP_NET_PROTOCOLS ) {
-               if ( tcpip_net->sa_family == sa_family )
+               if ( tcpip_net->sa_family == st_dest->st_family )
                        return tcpip_net;
        }
 
-       DBG ( "Unrecognised TCP/IP address family %d\n", sa_family );
+       DBG ( "Unrecognised TCP/IP address family %d\n", st_dest->st_family );
        return NULL;
 }
 
@@ -94,7 +95,7 @@ int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip_protocol,
        struct tcpip_net_protocol *tcpip_net;
 
        /* Hand off packet to the appropriate network-layer protocol */
-       tcpip_net = tcpip_net_protocol ( st_dest->st_family );
+       tcpip_net = tcpip_net_protocol ( st_dest );
        if ( tcpip_net ) {
                DBG ( "TCP/IP sending %s packet\n", tcpip_net->name );
                return tcpip_net->tx ( iobuf, tcpip_protocol, st_src, st_dest,
@@ -115,7 +116,7 @@ struct net_device * tcpip_netdev ( struct sockaddr_tcpip *st_dest ) {
        struct tcpip_net_protocol *tcpip_net;
 
        /* Hand off to the appropriate network-layer protocol */
-       tcpip_net = tcpip_net_protocol ( st_dest->st_family );
+       tcpip_net = tcpip_net_protocol ( st_dest );
        if ( tcpip_net )
                return tcpip_net->netdev ( st_dest );
 
@@ -134,7 +135,7 @@ size_t tcpip_mtu ( struct sockaddr_tcpip *st_dest ) {
        size_t mtu;
 
        /* Find appropriate network-layer protocol */
-       tcpip_net = tcpip_net_protocol ( st_dest->st_family );
+       tcpip_net = tcpip_net_protocol ( st_dest );
        if ( ! tcpip_net )
                return 0;
 
index 90f9f97..db01fb2 100644 (file)
@@ -1271,9 +1271,10 @@ static int tls_new_alert ( struct tls_session *tls, const void *data,
                uint8_t description;
                char next[0];
        } __attribute__ (( packed )) *alert = data;
+       const void *end = alert->next;
 
        /* Sanity check */
-       if ( sizeof ( *alert ) != len ) {
+       if ( end != ( data + len ) ) {
                DBGC ( tls, "TLS %p received overlength Alert\n", tls );
                DBGC_HD ( tls, data, len );
                return -EINVAL_ALERT;
@@ -1309,28 +1310,24 @@ static int tls_new_server_hello ( struct tls_session *tls,
                uint16_t version;
                uint8_t random[32];
                uint8_t session_id_len;
-               uint8_t session_id[0];
+               char next[0];
        } __attribute__ (( packed )) *hello_a = data;
-       const uint8_t *session_id;
        const struct {
+               uint8_t session_id[hello_a->session_id_len];
                uint16_t cipher_suite;
                uint8_t compression_method;
                char next[0];
-       } __attribute__ (( packed )) *hello_b;
+       } __attribute__ (( packed )) *hello_b = ( void * ) &hello_a->next;
+       const void *end = hello_b->next;
        uint16_t version;
        int rc;
 
-       /* Parse header */
-       if ( ( sizeof ( *hello_a ) > len ) ||
-            ( hello_a->session_id_len > ( len - sizeof ( *hello_a ) ) ) ||
-            ( sizeof ( *hello_b ) > ( len - sizeof ( *hello_a ) -
-                                      hello_a->session_id_len ) ) ) {
+       /* Sanity check */
+       if ( end > ( data + len ) ) {
                DBGC ( tls, "TLS %p received underlength Server Hello\n", tls );
                DBGC_HD ( tls, data, len );
                return -EINVAL_HELLO;
        }
-       session_id = hello_a->session_id;
-       hello_b = ( ( void * ) ( session_id + hello_a->session_id_len ) );
 
        /* Check and store protocol version */
        version = ntohs ( hello_a->version );
@@ -1383,7 +1380,14 @@ static int tls_new_server_hello ( struct tls_session *tls,
  */
 static int tls_parse_chain ( struct tls_session *tls,
                             const void *data, size_t len ) {
-       size_t remaining = len;
+       const void *end = ( data + len );
+       const struct {
+               tls24_t length;
+               uint8_t data[0];
+       } __attribute__ (( packed )) *certificate;
+       size_t certificate_len;
+       struct x509_certificate *cert;
+       const void *next;
        int rc;
 
        /* Free any existing certificate chain */
@@ -1398,37 +1402,25 @@ static int tls_parse_chain ( struct tls_session *tls,
        }
 
        /* Add certificates to chain */
-       while ( remaining ) {
-               const struct {
-                       tls24_t length;
-                       uint8_t data[0];
-               } __attribute__ (( packed )) *certificate = data;
-               size_t certificate_len;
-               size_t record_len;
-               struct x509_certificate *cert;
-
-               /* Parse header */
-               if ( sizeof ( *certificate ) > remaining ) {
-                       DBGC ( tls, "TLS %p underlength certificate:\n", tls );
-                       DBGC_HDA ( tls, 0, data, remaining );
-                       rc = -EINVAL_CERTIFICATE;
-                       goto err_underlength;
-               }
+       while ( data < end ) {
+
+               /* Extract raw certificate data */
+               certificate = data;
                certificate_len = tls_uint24 ( &certificate->length );
-               if ( certificate_len > ( remaining - sizeof ( *certificate ) )){
+               next = ( certificate->data + certificate_len );
+               if ( next > end ) {
                        DBGC ( tls, "TLS %p overlength certificate:\n", tls );
-                       DBGC_HDA ( tls, 0, data, remaining );
+                       DBGC_HDA ( tls, 0, data, ( end - data ) );
                        rc = -EINVAL_CERTIFICATE;
                        goto err_overlength;
                }
-               record_len = ( sizeof ( *certificate ) + certificate_len );
 
                /* Add certificate to chain */
                if ( ( rc = x509_append_raw ( tls->chain, certificate->data,
                                              certificate_len ) ) != 0 ) {
                        DBGC ( tls, "TLS %p could not append certificate: %s\n",
                               tls, strerror ( rc ) );
-                       DBGC_HDA ( tls, 0, data, remaining );
+                       DBGC_HDA ( tls, 0, data, ( end - data ) );
                        goto err_parse;
                }
                cert = x509_last ( tls->chain );
@@ -1436,15 +1428,13 @@ static int tls_parse_chain ( struct tls_session *tls,
                       tls, x509_name ( cert ) );
 
                /* Move to next certificate in list */
-               data += record_len;
-               remaining -= record_len;
+               data = next;
        }
 
        return 0;
 
  err_parse:
  err_overlength:
- err_underlength:
        x509_chain_put ( tls->chain );
        tls->chain = NULL;
  err_alloc_chain:
@@ -1465,18 +1455,12 @@ static int tls_new_certificate ( struct tls_session *tls,
                tls24_t length;
                uint8_t certificates[0];
        } __attribute__ (( packed )) *certificate = data;
-       size_t certificates_len;
+       size_t certificates_len = tls_uint24 ( &certificate->length );
+       const void *end = ( certificate->certificates + certificates_len );
        int rc;
 
-       /* Parse header */
-       if ( sizeof ( *certificate ) > len ) {
-               DBGC ( tls, "TLS %p received underlength Server Certificate\n",
-                      tls );
-               DBGC_HD ( tls, data, len );
-               return -EINVAL_CERTIFICATES;
-       }
-       certificates_len = tls_uint24 ( &certificate->length );
-       if ( certificates_len > ( len - sizeof ( *certificate ) ) ) {
+       /* Sanity check */
+       if ( end != ( data + len ) ) {
                DBGC ( tls, "TLS %p received overlength Server Certificate\n",
                       tls );
                DBGC_HD ( tls, data, len );
@@ -1537,10 +1521,11 @@ static int tls_new_server_hello_done ( struct tls_session *tls,
        const struct {
                char next[0];
        } __attribute__ (( packed )) *hello_done = data;
+       const void *end = hello_done->next;
        int rc;
 
        /* Sanity check */
-       if ( sizeof ( *hello_done ) != len ) {
+       if ( end != ( data + len ) ) {
                DBGC ( tls, "TLS %p received overlength Server Hello Done\n",
                       tls );
                DBGC_HD ( tls, data, len );
@@ -1572,11 +1557,12 @@ static int tls_new_finished ( struct tls_session *tls,
                uint8_t verify_data[12];
                char next[0];
        } __attribute__ (( packed )) *finished = data;
+       const void *end = finished->next;
        uint8_t digest_out[ digest->digestsize ];
        uint8_t verify_data[ sizeof ( finished->verify_data ) ];
 
        /* Sanity check */
-       if ( sizeof ( *finished ) != len ) {
+       if ( end != ( data + len ) ) {
                DBGC ( tls, "TLS %p received overlength Finished\n", tls );
                DBGC_HD ( tls, data, len );
                return -EINVAL_FINISHED;
@@ -1612,37 +1598,27 @@ static int tls_new_finished ( struct tls_session *tls,
  */
 static int tls_new_handshake ( struct tls_session *tls,
                               const void *data, size_t len ) {
-       size_t remaining = len;
+       const void *end = ( data + len );
        int rc;
 
-       while ( remaining ) {
+       while ( data != end ) {
                const struct {
                        uint8_t type;
                        tls24_t length;
                        uint8_t payload[0];
                } __attribute__ (( packed )) *handshake = data;
-               const void *payload;
-               size_t payload_len;
-               size_t record_len;
+               const void *payload = &handshake->payload;
+               size_t payload_len = tls_uint24 ( &handshake->length );
+               const void *next = ( payload + payload_len );
 
-               /* Parse header */
-               if ( sizeof ( *handshake ) > remaining ) {
-                       DBGC ( tls, "TLS %p received underlength Handshake\n",
-                              tls );
-                       DBGC_HD ( tls, data, remaining );
-                       return -EINVAL_HANDSHAKE;
-               }
-               payload_len = tls_uint24 ( &handshake->length );
-               if ( payload_len > ( remaining - sizeof ( *handshake ) ) ) {
+               /* Sanity check */
+               if ( next > end ) {
                        DBGC ( tls, "TLS %p received overlength Handshake\n",
                               tls );
                        DBGC_HD ( tls, data, len );
                        return -EINVAL_HANDSHAKE;
                }
-               payload = &handshake->payload;
-               record_len = ( sizeof ( *handshake ) + payload_len );
 
-               /* Handle payload */
                switch ( handshake->type ) {
                case TLS_SERVER_HELLO:
                        rc = tls_new_server_hello ( tls, payload, payload_len );
@@ -1672,15 +1648,16 @@ static int tls_new_handshake ( struct tls_session *tls,
                 * which are explicitly excluded).
                 */
                if ( handshake->type != TLS_HELLO_REQUEST )
-                       tls_add_handshake ( tls, data, record_len );
+                       tls_add_handshake ( tls, data,
+                                           sizeof ( *handshake ) +
+                                           payload_len );
 
                /* Abort on failure */
                if ( rc != 0 )
                        return rc;
 
                /* Move to next handshake record */
-               data += record_len;
-               remaining -= record_len;
+               data = next;
        }
 
        return 0;
index 1fbc12d..0f7dfb2 100644 (file)
@@ -328,7 +328,6 @@ static int udp_rx ( struct io_buffer *iobuf,
 struct tcpip_protocol udp_protocol __tcpip_protocol = {
        .name = "UDP",
        .rx = udp_rx,
-       .zero_csum = TCPIP_NEGATIVE_ZERO_CSUM,
        .tcpip_proto = IP_UDP,
 };
 
index 9342ad2..aed5ee3 100644 (file)
@@ -296,9 +296,8 @@ static void dhcp_set_state ( struct dhcp_session *dhcp,
  */
 static int dhcp_has_pxeopts ( struct dhcp_packet *dhcppkt ) {
 
-       /* Check for a next-server and boot filename */
-       if ( dhcppkt->dhcphdr->siaddr.s_addr &&
-            ( dhcppkt_fetch ( dhcppkt, DHCP_BOOTFILE_NAME, NULL, 0 ) > 0 ) )
+       /* Check for a boot filename */
+       if ( dhcppkt_fetch ( dhcppkt, DHCP_BOOTFILE_NAME, NULL, 0 ) > 0 )
                return 1;
 
        /* Check for a PXE boot menu */
@@ -444,10 +443,8 @@ static void dhcp_discovery_expired ( struct dhcp_session *dhcp ) {
        unsigned long elapsed = ( currticks() - dhcp->start );
 
        /* If link is blocked, defer DHCP discovery (and reset timeout) */
-       if ( netdev_link_blocked ( dhcp->netdev ) &&
-            ( dhcp->count <= DHCP_DISC_MAX_DEFERRALS ) ) {
+       if ( netdev_link_blocked ( dhcp->netdev ) ) {
                DBGC ( dhcp, "DHCP %p deferring discovery\n", dhcp );
-               dhcp->start = currticks();
                start_timer_fixed ( &dhcp->timer,
                                    ( DHCP_DISC_START_TIMEOUT_SEC *
                                      TICKS_PER_SEC ) );
@@ -1116,7 +1113,7 @@ static int dhcp_tx ( struct dhcp_session *dhcp ) {
         * session state into packet traces.  Useful for extracting
         * debug information from non-debug builds.
         */
-       dhcppkt.dhcphdr->secs = htons ( ( dhcp->count << 2 ) |
+       dhcppkt.dhcphdr->secs = htons ( ( ++(dhcp->count) << 2 ) |
                                        ( dhcp->offer.s_addr ? 0x02 : 0 ) |
                                        ( dhcp->proxy_offer ? 0x01 : 0 ) );
 
@@ -1260,9 +1257,6 @@ static void dhcp_timer_expired ( struct retry_timer *timer, int fail ) {
                return;
        }
 
-       /* Increment transmission counter */
-       dhcp->count++;
-
        /* Handle timer expiry based on current state */
        dhcp->state->expired ( dhcp );
 }
diff --git a/roms/ipxe/src/net/udp/ntp.c b/roms/ipxe/src/net/udp/ntp.c
deleted file mode 100644 (file)
index 11f8ccc..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <time.h>
-#include <ipxe/malloc.h>
-#include <ipxe/refcnt.h>
-#include <ipxe/iobuf.h>
-#include <ipxe/xfer.h>
-#include <ipxe/open.h>
-#include <ipxe/retry.h>
-#include <ipxe/timer.h>
-#include <ipxe/time.h>
-#include <ipxe/tcpip.h>
-#include <ipxe/ntp.h>
-
-/** @file
- *
- * Network Time Protocol
- *
- */
-
-/** An NTP client */
-struct ntp_client {
-       /** Reference count */
-       struct refcnt refcnt;
-       /** Job control interface */
-       struct interface job;
-       /** Data transfer interface */
-       struct interface xfer;
-       /** Retransmission timer */
-       struct retry_timer timer;
-};
-
-/**
- * Close NTP client
- *
- * @v ntp              NTP client
- * @v rc               Reason for close
- */
-static void ntp_close ( struct ntp_client *ntp, int rc ) {
-
-       /* Stop timer */
-       stop_timer ( &ntp->timer );
-
-       /* Shut down interfaces */
-       intf_shutdown ( &ntp->xfer, rc );
-       intf_shutdown ( &ntp->job, rc );
-}
-
-/**
- * Send NTP request
- *
- * @v ntp              NTP client
- * @ret rc             Return status code
- */
-static int ntp_request ( struct ntp_client *ntp ) {
-       struct ntp_header hdr;
-       int rc;
-
-       DBGC ( ntp, "NTP %p sending request\n", ntp );
-
-       /* Construct header */
-       memset ( &hdr, 0, sizeof ( hdr ) );
-       hdr.flags = ( NTP_FL_LI_UNKNOWN | NTP_FL_VN_1 | NTP_FL_MODE_CLIENT );
-       hdr.transmit.seconds = htonl ( time ( NULL ) + NTP_EPOCH );
-       hdr.transmit.fraction = htonl ( NTP_FRACTION_MAGIC );
-
-       /* Send request */
-       if ( ( rc = xfer_deliver_raw ( &ntp->xfer, &hdr,
-                                      sizeof ( hdr ) ) ) != 0 ) {
-               DBGC ( ntp, "NTP %p could not send request: %s\n",
-                      ntp, strerror ( rc ) );
-               return rc;
-       }
-
-       return 0;
-}
-
-/**
- * Handle NTP response
- *
- * @v ntp              NTP client
- * @v iobuf            I/O buffer
- * @v meta             Data transfer metadata
- * @ret rc             Return status code
- */
-static int ntp_deliver ( struct ntp_client *ntp, struct io_buffer *iobuf,
-                        struct xfer_metadata *meta ) {
-       struct ntp_header *hdr;
-       struct sockaddr_tcpip *st_src;
-       int32_t delta;
-       int rc;
-
-       /* Check source port */
-       st_src = ( ( struct sockaddr_tcpip * ) meta->src );
-       if ( st_src->st_port != htons ( NTP_PORT ) ) {
-               DBGC ( ntp, "NTP %p received non-NTP packet:\n", ntp );
-               DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) );
-               goto ignore;
-       }
-
-       /* Check packet length */
-       if ( iob_len ( iobuf ) < sizeof ( *hdr ) ) {
-               DBGC ( ntp, "NTP %p received malformed packet:\n", ntp );
-               DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) );
-               goto ignore;
-       }
-       hdr = iobuf->data;
-
-       /* Check mode */
-       if ( ( hdr->flags & NTP_FL_MODE_MASK ) != NTP_FL_MODE_SERVER ) {
-               DBGC ( ntp, "NTP %p received non-server packet:\n", ntp );
-               DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) );
-               goto ignore;
-       }
-
-       /* Check magic value */
-       if ( hdr->originate.fraction != htonl ( NTP_FRACTION_MAGIC ) ) {
-               DBGC ( ntp, "NTP %p received unrecognised packet:\n", ntp );
-               DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) );
-               goto ignore;
-       }
-
-       /* Check for Kiss-o'-Death packets */
-       if ( ! hdr->stratum ) {
-               DBGC ( ntp, "NTP %p received kiss-o'-death:\n", ntp );
-               DBGC_HDA ( ntp, 0, iobuf->data, iob_len ( iobuf ) );
-               rc = -EPROTO;
-               goto close;
-       }
-
-       /* Calculate clock delta */
-       delta = ( ntohl ( hdr->receive.seconds ) -
-                 ntohl ( hdr->originate.seconds ) );
-       DBGC ( ntp, "NTP %p delta %d seconds\n", ntp, delta );
-
-       /* Adjust system clock */
-       time_adjust ( delta );
-
-       /* Success */
-       rc = 0;
-
- close:
-       ntp_close ( ntp, rc );
- ignore:
-       free_iob ( iobuf );
-       return 0;
-}
-
-/**
- * Handle data transfer window change
- *
- * @v ntp              NTP client
- */
-static void ntp_window_changed ( struct ntp_client *ntp ) {
-
-       /* Start timer to send initial request */
-       start_timer_nodelay ( &ntp->timer );
-}
-
-/** Data transfer interface operations */
-static struct interface_operation ntp_xfer_op[] = {
-       INTF_OP ( xfer_deliver, struct ntp_client *, ntp_deliver ),
-       INTF_OP ( xfer_window_changed, struct ntp_client *,
-                 ntp_window_changed ),
-       INTF_OP ( intf_close, struct ntp_client *, ntp_close ),
-};
-
-/** Data transfer interface descriptor */
-static struct interface_descriptor ntp_xfer_desc =
-       INTF_DESC_PASSTHRU ( struct ntp_client, xfer, ntp_xfer_op, job );
-
-/** Job control interface operations */
-static struct interface_operation ntp_job_op[] = {
-       INTF_OP ( intf_close, struct ntp_client *, ntp_close ),
-};
-
-/** Job control interface descriptor */
-static struct interface_descriptor ntp_job_desc =
-       INTF_DESC_PASSTHRU ( struct ntp_client, job, ntp_job_op, xfer );
-
-/**
- * Handle NTP timer expiry
- *
- * @v timer            Retransmission timer
- * @v fail             Failure indicator
- */
-static void ntp_expired ( struct retry_timer *timer, int fail ) {
-       struct ntp_client *ntp =
-               container_of ( timer, struct ntp_client, timer );
-
-       /* Shut down client if we have failed */
-       if ( fail ) {
-               ntp_close ( ntp, -ETIMEDOUT );
-               return;
-       }
-
-       /* Otherwise, restart timer and (re)transmit request */
-       start_timer ( &ntp->timer );
-       ntp_request ( ntp );
-}
-
-/**
- * Start NTP client
- *
- * @v job              Job control interface
- * @v hostname         NTP server
- * @ret rc             Return status code
- */
-int start_ntp ( struct interface *job, const char *hostname ) {
-       struct ntp_client *ntp;
-       union {
-               struct sockaddr_tcpip st;
-               struct sockaddr sa;
-       } server;
-       int rc;
-
-       /* Allocate and initialise structure*/
-       ntp = zalloc ( sizeof ( *ntp ) );
-       if ( ! ntp ) {
-               rc = -ENOMEM;
-               goto err_alloc;
-       }
-       ref_init ( &ntp->refcnt, NULL );
-       intf_init ( &ntp->job, &ntp_job_desc, &ntp->refcnt );
-       intf_init ( &ntp->xfer, &ntp_xfer_desc, &ntp->refcnt );
-       timer_init ( &ntp->timer, ntp_expired, &ntp->refcnt );
-       set_timer_limits ( &ntp->timer, NTP_MIN_TIMEOUT, NTP_MAX_TIMEOUT );
-
-       /* Open socket */
-       memset ( &server, 0, sizeof ( server ) );
-       server.st.st_port = htons ( NTP_PORT );
-       if ( ( rc = xfer_open_named_socket ( &ntp->xfer, SOCK_DGRAM, &server.sa,
-                                            hostname, NULL ) ) != 0 ) {
-               DBGC ( ntp, "NTP %p could not open socket: %s\n",
-                      ntp, strerror ( rc ) );
-               goto err_open;
-       }
-
-       /* Attach parent interface, mortalise self, and return */
-       intf_plug_plug ( &ntp->job, job );
-       ref_put ( &ntp->refcnt );
-       return 0;
-
- err_open:
-       ntp_close ( ntp, rc );
-       ref_put ( &ntp->refcnt );
- err_alloc:
-       return rc;
-}
index 8fcc976..8b26bfb 100644 (file)
@@ -415,8 +415,6 @@ static int slam_pull_value ( struct slam_request *slam,
 static int slam_pull_header ( struct slam_request *slam,
                              struct io_buffer *iobuf ) {
        void *header = iobuf->data;
-       unsigned long total_bytes;
-       unsigned long block_size;
        int rc;
 
        /* If header matches cached header, just pull it and return */
@@ -433,26 +431,22 @@ static int slam_pull_header ( struct slam_request *slam,
         */
        if ( ( rc = slam_pull_value ( slam, iobuf, NULL ) ) != 0 )
                return rc;
-       if ( ( rc = slam_pull_value ( slam, iobuf, &total_bytes ) ) != 0 )
+       if ( ( rc = slam_pull_value ( slam, iobuf,
+                                     &slam->total_bytes ) ) != 0 )
                return rc;
-       if ( ( rc = slam_pull_value ( slam, iobuf, &block_size ) ) != 0 )
+       if ( ( rc = slam_pull_value ( slam, iobuf,
+                                     &slam->block_size ) ) != 0 )
                return rc;
 
-       /* Sanity check */
-       if ( block_size == 0 ) {
-               DBGC ( slam, "SLAM %p ignoring zero block size\n", slam );
-               return -EINVAL;
-       }
-
        /* Update the cached header */
        slam->header_len = ( iobuf->data - header );
        assert ( slam->header_len <= sizeof ( slam->header ) );
        memcpy ( slam->header, header, slam->header_len );
 
        /* Calculate number of blocks */
-       slam->total_bytes = total_bytes;
-       slam->block_size = block_size;
-       slam->num_blocks = ( ( total_bytes + block_size - 1 ) / block_size );
+       slam->num_blocks = ( ( slam->total_bytes + slam->block_size - 1 ) /
+                            slam->block_size );
+
        DBGC ( slam, "SLAM %p has total bytes %ld, block size %ld, num "
               "blocks %ld\n", slam, slam->total_bytes, slam->block_size,
               slam->num_blocks );
index 4255472..953bcb4 100644 (file)
@@ -325,7 +325,7 @@ void tftp_set_mtftp_port ( unsigned int port ) {
  * @ret rc             Return status code
  */
 static int tftp_send_rrq ( struct tftp_request *tftp ) {
-       const char *path = ( tftp->uri->path + 1 /* skip '/' */ );
+       const char *path = tftp->uri->path;
        struct tftp_rrq *rrq;
        size_t len;
        struct io_buffer *iobuf;
@@ -1067,8 +1067,6 @@ static int tftp_core_open ( struct interface *xfer, struct uri *uri,
                return -EINVAL;
        if ( ! uri->path )
                return -EINVAL;
-       if ( uri->path[0] != '/' )
-               return -EINVAL;
 
        /* Allocate and populate TFTP structure */
        tftp = zalloc ( sizeof ( *tftp ) );
@@ -1182,12 +1180,13 @@ struct uri_opener mtftp_uri_opener __uri_opener = {
  */
 static int tftp_apply_settings ( void ) {
        static struct in_addr tftp_server = { 0 };
-       struct in_addr new_tftp_server;
+       struct in_addr last_tftp_server;
        char uri_string[32];
        struct uri *uri;
 
        /* Retrieve TFTP server setting */
-       fetch_ipv4_setting ( NULL, &next_server_setting, &new_tftp_server );
+       last_tftp_server = tftp_server;
+       fetch_ipv4_setting ( NULL, &next_server_setting, &tftp_server );
 
        /* If TFTP server setting has changed, set the current working
         * URI to match.  Do it only when the TFTP server has changed
@@ -1196,19 +1195,18 @@ static int tftp_apply_settings ( void ) {
         * an unrelated setting and triggered all the settings
         * applicators.
         */
-       if ( new_tftp_server.s_addr &&
-            ( new_tftp_server.s_addr != tftp_server.s_addr ) ) {
-               DBGC ( &tftp_server, "TFTP server changed %s => ",
-                      inet_ntoa ( tftp_server ) );
-               DBGC ( &tftp_server, "%s\n", inet_ntoa ( new_tftp_server ) );
-               snprintf ( uri_string, sizeof ( uri_string ),
-                          "tftp://%s/", inet_ntoa ( new_tftp_server ) );
-               uri = parse_uri ( uri_string );
-               if ( ! uri )
-                       return -ENOMEM;
+       if ( tftp_server.s_addr != last_tftp_server.s_addr ) {
+               if ( tftp_server.s_addr ) {
+                       snprintf ( uri_string, sizeof ( uri_string ),
+                                  "tftp://%s/", inet_ntoa ( tftp_server ) );
+                       uri = parse_uri ( uri_string );
+                       if ( ! uri )
+                               return -ENOMEM;
+               } else {
+                       uri = NULL;
+               }
                churi ( uri );
                uri_put ( uri );
-               tftp_server = new_tftp_server;
        }
 
        return 0;
index 57ad0e7..db96839 100644 (file)
@@ -41,7 +41,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/crc32.h>
 #include <ipxe/ocsp.h>
 #include <ipxe/validator.h>
-#include <config/crypto.h>
 
 /** @file
  *
@@ -134,7 +133,7 @@ const struct setting crosscert_setting __setting ( SETTING_CRYPTO, crosscert )={
 };
 
 /** Default cross-signed certificate source */
-static const char crosscert_default[] = CROSSCERT;
+static const char crosscert_default[] = "http://ca.ipxe.org/auto";
 
 /**
  * Append cross-signing certificates to certificate chain
diff --git a/roms/ipxe/src/tests/bitops_test.c b/roms/ipxe/src/tests/bitops_test.c
deleted file mode 100644 (file)
index f29fc68..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * Bit operations self-tests
- *
- */
-
-/* Forcibly enable assertions */
-#undef NDEBUG
-
-#include <stdint.h>
-#include <string.h>
-#include <assert.h>
-#include <ipxe/bitops.h>
-#include <ipxe/test.h>
-
-/**
- * Perform bit operations self-tests
- *
- */
-static void bitops_test_exec ( void ) {
-       uint8_t bits[32];
-
-       /* Initialise bits */
-       memset ( bits, 0, sizeof ( bits ) );
-
-       /* Test set_bit() */
-       set_bit ( 0, bits );
-       ok ( bits[0] == 0x01 );
-       set_bit ( 17, bits );
-       ok ( bits[2] == 0x02 );
-       set_bit ( 22, bits );
-       ok ( bits[2] == 0x42 );
-       set_bit ( 22, bits );
-       ok ( bits[2] == 0x42 );
-
-       /* Test clear_bit() */
-       clear_bit ( 0, bits );
-       ok ( bits[0] == 0x00 );
-       bits[5] = 0xff;
-       clear_bit ( 42, bits );
-       ok ( bits[5] == 0xfb );
-       clear_bit ( 42, bits );
-       ok ( bits[5] == 0xfb );
-       clear_bit ( 44, bits );
-       ok ( bits[5] == 0xeb );
-
-       /* Test test_and_set_bit() */
-       ok ( test_and_set_bit ( 0, bits ) == 0 );
-       ok ( bits[0] == 0x01 );
-       ok ( test_and_set_bit ( 0, bits ) != 0 );
-       ok ( bits[0] == 0x01 );
-       ok ( test_and_set_bit ( 69, bits ) == 0 );
-       ok ( bits[8] == 0x20 );
-       ok ( test_and_set_bit ( 69, bits ) != 0 );
-       ok ( bits[8] == 0x20 );
-       ok ( test_and_set_bit ( 69, bits ) != 0 );
-       ok ( bits[8] == 0x20 );
-
-       /* Test test_and_clear_bit() */
-       ok ( test_and_clear_bit ( 0, bits ) != 0 );
-       ok ( bits[0] == 0x00 );
-       ok ( test_and_clear_bit ( 0, bits ) == 0 );
-       ok ( bits[0] == 0x00 );
-       bits[31] = 0xeb;
-       ok ( test_and_clear_bit ( 255, bits ) != 0 );
-       ok ( bits[31] == 0x6b );
-       ok ( test_and_clear_bit ( 255, bits ) == 0 );
-       ok ( bits[31] == 0x6b );
-       ok ( test_and_clear_bit ( 255, bits ) == 0 );
-       ok ( bits[31] == 0x6b );
-}
-
-/** Bit operations self-test */
-struct self_test bitops_test __self_test = {
-       .name = "bitops",
-       .exec = bitops_test_exec,
-};
@@ -2,7 +2,7 @@
        org 100h
 
        jmp start
-
+       
 shuffle_start:
        push 0xB800
        pop es
@@ -37,3 +37,4 @@ source:       dd 0
        dd shuffle_len
 
 num_shuffle_descriptors equ 1
+
diff --git a/roms/ipxe/src/tests/iobuf_test.c b/roms/ipxe/src/tests/iobuf_test.c
deleted file mode 100644 (file)
index a417c2e..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * I/O buffer tests
- *
- */
-
-/* Forcibly enable assertions */
-#undef NDEBUG
-
-#include <stdint.h>
-#include <string.h>
-#include <assert.h>
-#include <ipxe/iobuf.h>
-#include <ipxe/io.h>
-#include <ipxe/test.h>
-
-/* Forward declaration */
-struct self_test iobuf_test __self_test;
-
-/**
- * Report I/O buffer allocation test result
- *
- * @v len              Required length of buffer
- * @v align            Physical alignment
- * @v offset           Offset from physical alignment
- * @v file             Test code file
- * @v line             Test code line
- */
-static inline void alloc_iob_okx ( size_t len, size_t align, size_t offset,
-                                  const char *file, unsigned int line ) {
-       struct io_buffer *iobuf;
-
-       /* Allocate I/O buffer */
-       iobuf = alloc_iob_raw ( len, align, offset );
-       okx ( iobuf != NULL, file, line );
-       DBGC ( &iobuf_test, "IOBUF %p (%#08lx+%#zx) for %#zx align %#zx "
-              "offset %#zx\n", iobuf, virt_to_phys ( iobuf->data ),
-              iob_tailroom ( iobuf ), len, align, offset );
-
-       /* Validate requested length and alignment */
-       okx ( ( ( ( intptr_t ) iobuf ) & ( __alignof__ ( *iobuf ) - 1 ) ) == 0,
-               file, line );
-       okx ( iob_tailroom ( iobuf ) >= len, file, line );
-       okx ( ( ( align == 0 ) ||
-               ( ( virt_to_phys ( iobuf->data ) & ( align - 1 ) ) ==
-                 ( offset & ( align - 1 ) ) ) ), file, line );
-
-       /* Overwrite entire content of I/O buffer (for Valgrind) */
-       memset ( iob_put ( iobuf, len ), 0x55, len );
-
-       /* Free I/O buffer */
-       free_iob ( iobuf );
-}
-#define alloc_iob_ok( len, align, offset ) \
-       alloc_iob_okx ( len, align, offset, __FILE__, __LINE__ )
-
-/**
- * Report I/O buffer allocation failure test result
- *
- * @v len              Required length of buffer
- * @v align            Physical alignment
- * @v offset           Offset from physical alignment
- * @v file             Test code file
- * @v line             Test code line
- */
-static inline void alloc_iob_fail_okx ( size_t len, size_t align, size_t offset,
-                                       const char *file, unsigned int line ) {
-       struct io_buffer *iobuf;
-
-       /* Allocate I/O buffer */
-       iobuf = alloc_iob_raw ( len, align, offset );
-       okx ( iobuf == NULL, file, line );
-}
-#define alloc_iob_fail_ok( len, align, offset ) \
-       alloc_iob_fail_okx ( len, align, offset, __FILE__, __LINE__ )
-
-/**
- * Perform I/O buffer self-tests
- *
- */
-static void iobuf_test_exec ( void ) {
-
-       /* Check zero-length allocations */
-       alloc_iob_ok ( 0, 0, 0 );
-       alloc_iob_ok ( 0, 0, 1 );
-       alloc_iob_ok ( 0, 1, 0 );
-       alloc_iob_ok ( 0, 1024, 0 );
-       alloc_iob_ok ( 0, 139, -17 );
-
-       /* Check various sensible allocations */
-       alloc_iob_ok ( 1, 0, 0 );
-       alloc_iob_ok ( 16, 16, 0 );
-       alloc_iob_ok ( 64, 0, 0 );
-       alloc_iob_ok ( 65, 0, 0 );
-       alloc_iob_ok ( 65, 1024, 19 );
-       alloc_iob_ok ( 1536, 1536, 0 );
-       alloc_iob_ok ( 2048, 2048, 0 );
-       alloc_iob_ok ( 2048, 2048, -10 );
-
-       /* Excessively large or excessively aligned allocations should fail */
-       alloc_iob_fail_ok ( -1UL, 0, 0 );
-       alloc_iob_fail_ok ( -1UL, 1024, 0 );
-       alloc_iob_fail_ok ( 0, -1UL, 0 );
-       alloc_iob_fail_ok ( 1024, -1UL, 0 );
-}
-
-/** I/O buffer self-test */
-struct self_test iobuf_test __self_test = {
-       .name = "iobuf",
-       .exec = iobuf_test_exec,
-};
index 91066fa..c0d05d2 100644 (file)
@@ -34,7 +34,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /* Forcibly enable assertions */
 #undef NDEBUG
 
-#include <string.h>
 #include <ipxe/crypto.h>
 #include <ipxe/rsa.h>
 #include <ipxe/md5.h>
index 828901b..f7fb35d 100644 (file)
@@ -166,12 +166,6 @@ static struct setting test_string_setting = {
        .type = &setting_type_string,
 };
 
-/** Test URI-encoded string setting */
-static struct setting test_uristring_setting = {
-       .name = "test_uristring",
-       .type = &setting_type_uristring,
-};
-
 /** Test IPv4 address setting type */
 static struct setting test_ipv4_setting = {
        .name = "test_ipv4",
@@ -271,16 +265,6 @@ static void settings_test_exec ( void ) {
        fetchf_ok ( &test_settings, &test_string_setting,
                    RAW ( 'w', 'o', 'r', 'l', 'd' ), "world" );
 
-       /* "uristring" setting type */
-       storef_ok ( &test_settings, &test_uristring_setting, "hello%20world",
-                   RAW ( 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l',
-                         'd' ) );
-       fetchf_ok ( &test_settings, &test_uristring_setting,
-                   RAW ( 1, 2, 3, 4, 5 ), "%01%02%03%04%05" );
-       fetchf_ok ( &test_settings, &test_uristring_setting,
-                   RAW ( 0, ' ', '%', '/', '#', ':', '@', '?', '=', '&' ),
-                   "%00%20%25%2F%23%3A%40%3F%3D%26" );
-
        /* "ipv4" setting type */
        storef_ok ( &test_settings, &test_ipv4_setting, "192.168.0.1",
                    RAW ( 192, 168, 0, 1 ) );
@@ -422,9 +406,7 @@ static void settings_test_exec ( void ) {
 
        /* "busdevfn" setting type (no store capability) */
        fetchf_ok ( &test_settings, &test_busdevfn_setting,
-                   RAW ( 0x03, 0x45 ), "0000:03:08.5" );
-       fetchf_ok ( &test_settings, &test_busdevfn_setting,
-                   RAW ( 0x00, 0x02, 0x0a, 0x21 ), "0002:0a:04.1" );
+                   RAW ( 0x03, 0x45 ), "03:08.5" );
 
        /* Clear and unregister test settings block */
        clear_settings ( &test_settings );
index fac0ec2..759f886 100644 (file)
@@ -94,12 +94,6 @@ TCPIP_TEST ( one_byte, DATA ( 0xeb ) );
 /** Double byte */
 TCPIP_TEST ( two_bytes, DATA ( 0xba, 0xbe ) );
 
-/** Positive zero data */
-TCPIP_TEST ( positive_zero, DATA ( 0x00, 0x00 ) );
-
-/** Negative zero data */
-TCPIP_TEST ( negative_zero, DATA ( 0xff, 0xff ) );
-
 /** Final wrap-around carry (big-endian) */
 TCPIP_TEST ( final_carry_big,
             DATA ( 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ) );
@@ -132,17 +126,9 @@ TCPIP_RANDOM_TEST ( partial, 0xcafebabe, 121, 5 );
  *
  * This is a reference implementation taken from RFC1071 (and modified
  * to fix compilation without warnings under gcc).
- *
- * The initial value of the one's complement @c sum is changed from
- * positive zero (0x0000) to negative zero (0xffff).  This ensures
- * that the return value will always use the positive representation
- * of zero (0x0000).  Without this change, the return value would use
- * negative zero (0xffff) if the input data is zero length (or all
- * zeros) but positive zero (0x0000) for any other data which sums to
- * zero.
  */
 static uint16_t rfc_tcpip_chksum ( const void *data, size_t len ) {
-       unsigned long sum = 0xffff;
+       unsigned long sum = 0;
 
         while ( len > 1 )  {
                sum += *( ( uint16_t * ) data );
@@ -156,7 +142,6 @@ static uint16_t rfc_tcpip_chksum ( const void *data, size_t len ) {
        while ( sum >> 16 )
                sum = ( ( sum & 0xffff ) + ( sum >> 16 ) );
 
-       assert ( sum != 0x0000 );
        return ~sum;
 }
 
@@ -242,8 +227,6 @@ static void tcpip_test_exec ( void ) {
        tcpip_ok ( &empty );
        tcpip_ok ( &one_byte );
        tcpip_ok ( &two_bytes );
-       tcpip_ok ( &positive_zero );
-       tcpip_ok ( &negative_zero );
        tcpip_ok ( &final_carry_big );
        tcpip_ok ( &final_carry_little );
        tcpip_random_ok ( &random_aligned );
index 0ec885f..54ce866 100644 (file)
@@ -67,5 +67,3 @@ REQUIRE_OBJECT ( profile_test );
 REQUIRE_OBJECT ( setjmp_test );
 REQUIRE_OBJECT ( pccrc_test );
 REQUIRE_OBJECT ( linebuf_test );
-REQUIRE_OBJECT ( iobuf_test );
-REQUIRE_OBJECT ( bitops_test );
index 92c2f90..da7fb8a 100644 (file)
@@ -35,7 +35,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <string.h>
 #include <byteswap.h>
 #include <ipxe/uri.h>
-#include <ipxe/tcpip.h>
 #include <ipxe/params.h>
 #include <ipxe/test.h>
 
@@ -67,15 +66,12 @@ struct uri_resolve_test {
        const char *resolved;
 };
 
-/** A PXE URI test */
-struct uri_pxe_test {
-       /** Server address */
-       union {
-               struct sockaddr sa;
-               struct sockaddr_in sin;
-               struct sockaddr_in6 sin6;
-               struct sockaddr_tcpip st;
-       } server;
+/** A TFTP URI test */
+struct uri_tftp_test {
+       /** Next-server address */
+       struct in_addr next_server;
+       /** Port number */
+       unsigned int port;
        /** Filename */
        const char *filename;
        /** URI */
@@ -327,20 +323,20 @@ static void uri_resolve_path_okx ( struct uri_resolve_test *test,
        uri_resolve_path_okx ( test, __FILE__, __LINE__ )
 
 /**
- * Report URI PXE test result
+ * Report URI TFTP test result
  *
- * @v test             URI PXE test
+ * @v test             URI TFTP test
  * @v file             Test code file
  * @v line             Test code line
  */
-static void uri_pxe_okx ( struct uri_pxe_test *test, const char *file,
-                         unsigned int line ) {
+static void uri_tftp_okx ( struct uri_tftp_test *test, const char *file,
+                          unsigned int line ) {
        char buf[ strlen ( test->string ) + 1 /* NUL */ ];
        struct uri *uri;
        size_t len;
 
        /* Construct URI */
-       uri = pxe_uri ( &test->server.sa, test->filename );
+       uri = tftp_uri ( test->next_server, test->port, test->filename );
        okx ( uri != NULL, file, line );
        if ( uri ) {
                uri_okx ( uri, &test->uri, file, line );
@@ -350,7 +346,7 @@ static void uri_pxe_okx ( struct uri_pxe_test *test, const char *file,
        }
        uri_put ( uri );
 }
-#define uri_pxe_ok( test ) uri_pxe_okx ( test, __FILE__, __LINE__ )
+#define uri_tftp_ok( test ) uri_tftp_okx ( test, __FILE__, __LINE__ )
 
 /**
  * Report current working URI test result
@@ -499,18 +495,6 @@ static struct uri_test uri_mailto = {
        { .scheme = "mailto", .opaque = "ipxe-devel@lists.ipxe.org" }
 };
 
-/** Basic path-only URI */
-static struct uri_test uri_path = {
-       "/var/lib/tftpboot/pxelinux.0",
-       { .path = "/var/lib/tftpboot/pxelinux.0" },
-};
-
-/** Path-only URI with escaped characters */
-static struct uri_test uri_path_escaped = {
-       "/hello%20world%3F",
-       { .path = "/hello world?" },
-};
-
 /** HTTP URI with all the trimmings */
 static struct uri_test uri_http_all = {
        "http://anon:password@example.com:3001/~foo/cgi-bin/foo.pl?a=b&c=d#bit",
@@ -610,34 +594,6 @@ static struct uri_test uri_iscsi = {
        },
 };
 
-/** File URI with relative (opaque) path */
-static struct uri_test uri_file_relative = {
-       "file:boot/script.ipxe",
-       {
-               .scheme = "file",
-               .opaque = "boot/script.ipxe",
-       },
-};
-
-/** File URI with absolute path */
-static struct uri_test uri_file_absolute = {
-       "file:/boot/script.ipxe",
-       {
-               .scheme = "file",
-               .path = "/boot/script.ipxe",
-       },
-};
-
-/** File URI with volume name */
-static struct uri_test uri_file_volume = {
-       "file://hpilo/boot/script.ipxe",
-       {
-               .scheme = "file",
-               .host = "hpilo",
-               .path = "/boot/script.ipxe",
-       },
-};
-
 /** URI with port number */
 static struct uri_port_test uri_explicit_port = {
        "http://192.168.0.1:8080/boot.php",
@@ -722,96 +678,53 @@ static struct uri_resolve_test uri_fragment = {
        "http://192.168.0.254/test#bar",
 };
 
-/** PXE URI with absolute URI */
-static struct uri_pxe_test uri_pxe_absolute = {
-       {
-               /* 192.168.0.3 */
-               .sin = {
-                       .sin_family = AF_INET,
-                       .sin_addr = { .s_addr = htonl ( 0xc0a80003 ) },
-               },
-       },
-       "http://not.a.tftp/uri",
-       {
-               .scheme = "http",
-               .host = "not.a.tftp",
-               .path = "/uri",
-       },
-       "http://not.a.tftp/uri",
-};
-
-/** PXE URI with absolute path */
-static struct uri_pxe_test uri_pxe_absolute_path = {
-       {
-               /* 192.168.0.2 */
-               .sin = {
-                       .sin_family = AF_INET,
-                       .sin_addr = { .s_addr = htonl ( 0xc0a80002 ) },
-               },
-       },
+/** TFTP URI with absolute path */
+static struct uri_tftp_test uri_tftp_absolute = {
+       { .s_addr = htonl ( 0xc0a80002 ) /* 192.168.0.2 */ }, 0,
        "/absolute/path",
        {
                .scheme = "tftp",
                .host = "192.168.0.2",
-               .path = "//absolute/path",
+               .path = "/absolute/path",
        },
-       "tftp://192.168.0.2//absolute/path",
+       "tftp://192.168.0.2/absolute/path",
 };
 
-/** PXE URI with relative path */
-static struct uri_pxe_test uri_pxe_relative_path = {
-       {
-               /* 192.168.0.3 */
-               .sin = {
-                       .sin_family = AF_INET,
-                       .sin_addr = { .s_addr = htonl ( 0xc0a80003 ) },
-               },
-       },
+/** TFTP URI with relative path */
+static struct uri_tftp_test uri_tftp_relative = {
+       { .s_addr = htonl ( 0xc0a80003 ) /* 192.168.0.3 */ }, 0,
        "relative/path",
        {
                .scheme = "tftp",
                .host = "192.168.0.3",
-               .path = "/relative/path",
+               .path = "relative/path",
        },
        "tftp://192.168.0.3/relative/path",
 };
 
-/** PXE URI with path containing special characters */
-static struct uri_pxe_test uri_pxe_icky = {
-       {
-               /* 10.0.0.6 */
-               .sin = {
-                       .sin_family = AF_INET,
-                       .sin_addr = { .s_addr = htonl ( 0x0a000006 ) },
-               },
-       },
+/** TFTP URI with path containing special characters */
+static struct uri_tftp_test uri_tftp_icky = {
+       { .s_addr = htonl ( 0x0a000006 ) /* 10.0.0.6 */ }, 0,
        "C:\\tftpboot\\icky#path",
        {
                .scheme = "tftp",
                .host = "10.0.0.6",
-               .path = "/C:\\tftpboot\\icky#path",
+               .path = "C:\\tftpboot\\icky#path",
        },
        "tftp://10.0.0.6/C%3A\\tftpboot\\icky%23path",
 };
 
-/** PXE URI with custom port */
-static struct uri_pxe_test uri_pxe_port = {
-       {
-               /* 192.168.0.1:4069 */
-               .sin = {
-                       .sin_family = AF_INET,
-                       .sin_addr = { .s_addr = htonl ( 0xc0a80001 ) },
-                       .sin_port = htons ( 4069 ),
-               },
-       },
+/** TFTP URI with custom port */
+static struct uri_tftp_test uri_tftp_port = {
+       { .s_addr = htonl ( 0xc0a80001 ) /* 192.168.0.1 */ }, 4069,
        "/another/path",
        {
                .scheme = "tftp",
                .host = "192.168.0.1",
                .port = "4069",
-               .path = "//another/path",
+               .path = "/another/path",
        },
-       "tftp://192.168.0.1:4069//another/path",
+       "tftp://192.168.0.1:4069/another/path",
 };
 
 /** Current working URI test */
@@ -917,8 +830,6 @@ static void uri_test_exec ( void ) {
        uri_parse_format_dup_ok ( &uri_empty );
        uri_parse_format_dup_ok ( &uri_boot_ipxe_org );
        uri_parse_format_dup_ok ( &uri_mailto );
-       uri_parse_format_dup_ok ( &uri_path );
-       uri_parse_format_dup_ok ( &uri_path_escaped );
        uri_parse_format_dup_ok ( &uri_http_all );
        uri_parse_format_dup_ok ( &uri_http_escaped );
        uri_parse_ok ( &uri_http_escaped_improper ); /* Parse only */
@@ -927,9 +838,6 @@ static void uri_test_exec ( void ) {
        uri_parse_format_dup_ok ( &uri_ipv6_local );
        uri_parse_ok ( &uri_ipv6_local_non_conforming ); /* Parse only */
        uri_parse_format_dup_ok ( &uri_iscsi );
-       uri_parse_format_dup_ok ( &uri_file_relative );
-       uri_parse_format_dup_ok ( &uri_file_absolute );
-       uri_parse_format_dup_ok ( &uri_file_volume );
 
        /** URI port number tests */
        uri_port_ok ( &uri_explicit_port );
@@ -949,12 +857,11 @@ static void uri_test_exec ( void ) {
        uri_resolve_ok ( &uri_query );
        uri_resolve_ok ( &uri_fragment );
 
-       /* PXE URI construction tests */
-       uri_pxe_ok ( &uri_pxe_absolute );
-       uri_pxe_ok ( &uri_pxe_absolute_path );
-       uri_pxe_ok ( &uri_pxe_relative_path );
-       uri_pxe_ok ( &uri_pxe_icky );
-       uri_pxe_ok ( &uri_pxe_port );
+       /* TFTP URI construction tests */
+       uri_tftp_ok ( &uri_tftp_absolute );
+       uri_tftp_ok ( &uri_tftp_relative );
+       uri_tftp_ok ( &uri_tftp_icky );
+       uri_tftp_ok ( &uri_tftp_port );
 
        /* Current working URI tests */
        uri_churi_ok ( uri_churi );
index f388b3d..0ad4f1c 100644 (file)
@@ -39,32 +39,21 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /**
  * Report an snprintf() test result
  *
- * @v len              Buffer length
- * @v expected         Expected result
- * @v file             Test code file
- * @v line             Test code line
- * @v format           Format string
- * @v ...              Arguments
  */
-static void snprintf_okx ( size_t len, const char *expected, const char *file,
-                          unsigned int line, const char *fmt, ... ) {
-       char actual[len];
-       size_t actual_len;
-       va_list args;
-
-       va_start ( args, fmt );
-       actual_len = vsnprintf ( actual, sizeof ( actual ), fmt, args );
-       va_end ( args );
-       okx ( actual_len >= strlen ( expected ), file, line );
-       okx ( strcmp ( actual, expected ) == 0, file, line );
-       if ( strcmp ( actual, expected ) != 0 ) {
-               DBG ( "SNPRINTF expected \"%s\", got \"%s\"\n",
-                     expected, actual );
-       }
-}
-#define snprintf_ok( len, result, format, ... )                                \
-       snprintf_okx ( len, result, __FILE__, __LINE__, format,         \
-                      ##__VA_ARGS__ )
+#define snprintf_ok( len, result, format, ... ) do {                   \
+       char actual[ (len) ];                                           \
+       const char expected[] = result;                                 \
+       size_t actual_len;                                              \
+                                                                       \
+       actual_len = snprintf ( actual, sizeof ( actual ),              \
+                               format, ##__VA_ARGS__ );                \
+       ok ( actual_len >= strlen ( result ) );                         \
+       ok ( strcmp ( actual, expected ) == 0 );                        \
+       if ( strcmp ( actual, expected ) != 0 ) {                       \
+               DBG ( "SNPRINTF expected \"%s\", got \"%s\"\n",         \
+                     expected, actual );                               \
+       }                                                               \
+       } while ( 0 )
 
 /**
  * Perform vsprintf() self-tests
@@ -108,10 +97,6 @@ static void vsprintf_test_exec ( void ) {
        snprintf_ok ( 64, "PCI 00:1f.3", "PCI %02x:%02x.%x", 0x00, 0x1f, 0x03 );
        snprintf_ok ( 64, "Region [1000000,3f000000)", "Region [%llx,%llx)",
                      0x1000000ULL, 0x3f000000ULL );
-
-       /* Null string (used for debug messages) */
-       snprintf_ok ( 16, "<NULL>", "%s", ( ( char * ) NULL ) );
-       snprintf_ok ( 16, "<NULL>", "%ls", ( ( wchar_t * ) NULL ) );
 }
 
 /** vsprintf() self-test */
index 57bf96e..9125438 100644 (file)
@@ -87,6 +87,33 @@ __weak int pxe_menu_boot ( struct net_device *netdev __unused ) {
        return -ENOTSUP;
 }
 
+/**
+ * Parse next-server and filename into a URI
+ *
+ * @v next_server      Next-server address
+ * @v filename         Filename
+ * @ret uri            URI, or NULL on failure
+ */
+static struct uri * parse_next_server_and_filename ( struct in_addr next_server,
+                                                    const char *filename ) {
+       struct uri *uri;
+
+       /* Parse filename */
+       uri = parse_uri ( filename );
+       if ( ! uri )
+               return NULL;
+
+       /* Construct a TFTP URI for the filename, if applicable */
+       if ( next_server.s_addr && filename[0] && ! uri_is_absolute ( uri ) ) {
+               uri_put ( uri );
+               uri = tftp_uri ( next_server, 0, filename );
+               if ( ! uri )
+                       return NULL;
+       }
+
+       return uri;
+}
+
 /** The "keep-san" setting */
 const struct setting keep_san_setting __setting ( SETTING_SANBOOT_EXTRA,
                                                  keep-san ) = {
@@ -127,9 +154,7 @@ int uriboot ( struct uri *filename, struct uri *root_path, int drive,
 
        /* Hook SAN device, if applicable */
        if ( root_path ) {
-               drive = san_hook ( root_path, drive );
-               if ( drive < 0 ) {
-                       rc = drive;
+               if ( ( rc = san_hook ( root_path, drive ) ) != 0 ) {
                        printf ( "Could not open SAN device: %s\n",
                                 strerror ( rc ) );
                        goto err_san_hook;
@@ -138,7 +163,7 @@ int uriboot ( struct uri *filename, struct uri *root_path, int drive,
        }
 
        /* Describe SAN device, if applicable */
-       if ( ! ( flags & URIBOOT_NO_SAN_DESCRIBE ) ) {
+       if ( ( drive >= 0 ) && ! ( flags & URIBOOT_NO_SAN_DESCRIBE ) ) {
                if ( ( rc = san_describe ( drive ) ) != 0 ) {
                        printf ( "Could not describe SAN device %#02x: %s\n",
                                 drive, strerror ( rc ) );
@@ -172,7 +197,7 @@ int uriboot ( struct uri *filename, struct uri *root_path, int drive,
        }
 
        /* Attempt SAN boot if applicable */
-       if ( ! ( flags & URIBOOT_NO_SAN_BOOT ) ) {
+       if ( ( drive >= 0 ) && ! ( flags & URIBOOT_NO_SAN_BOOT ) ) {
                if ( fetch_intz_setting ( NULL, &skip_san_boot_setting) == 0 ) {
                        printf ( "Booting from SAN device %#02x\n", drive );
                        rc = san_boot ( drive );
@@ -190,7 +215,7 @@ int uriboot ( struct uri *filename, struct uri *root_path, int drive,
  err_download:
  err_san_describe:
        /* Unhook SAN device, if applicable */
-       if ( ! ( flags & URIBOOT_NO_SAN_UNHOOK ) ) {
+       if ( ( drive >= 0 ) && ! ( flags & URIBOOT_NO_SAN_UNHOOK ) ) {
                if ( fetch_intz_setting ( NULL, &keep_san_setting ) == 0 ) {
                        san_unhook ( drive );
                        printf ( "Unregistered SAN device %#02x\n", drive );
@@ -225,17 +250,11 @@ static void close_all_netdevs ( void ) {
  * @ret uri            URI, or NULL on failure
  */
 struct uri * fetch_next_server_and_filename ( struct settings *settings ) {
-       union {
-               struct sockaddr sa;
-               struct sockaddr_in sin;
-       } next_server;
+       struct in_addr next_server = { 0 };
        char *raw_filename = NULL;
        struct uri *uri = NULL;
        char *filename;
 
-       /* Initialise server address */
-       memset ( &next_server, 0, sizeof ( next_server ) );
-
        /* If we have a filename, fetch it along with the next-server
         * setting from the same settings block.
         */
@@ -244,27 +263,20 @@ struct uri * fetch_next_server_and_filename ( struct settings *settings ) {
                fetch_string_setting_copy ( settings, &filename_setting,
                                            &raw_filename );
                fetch_ipv4_setting ( settings, &next_server_setting,
-                                    &next_server.sin.sin_addr );
-       }
-       if ( ! raw_filename )
-               goto err_fetch;
-
-       /* Populate server address */
-       if ( next_server.sin.sin_addr.s_addr ) {
-               next_server.sin.sin_family = AF_INET;
-               printf ( "Next server: %s\n",
-                        inet_ntoa ( next_server.sin.sin_addr ) );
+                                    &next_server );
        }
 
        /* Expand filename setting */
-       filename = expand_settings ( raw_filename );
+       filename = expand_settings ( raw_filename ? raw_filename : "" );
        if ( ! filename )
                goto err_expand;
+
+       /* Parse next server and filename */
+       if ( next_server.s_addr )
+               printf ( "Next server: %s\n", inet_ntoa ( next_server ) );
        if ( filename[0] )
                printf ( "Filename: %s\n", filename );
-
-       /* Construct URI */
-       uri = pxe_uri ( &next_server.sa, filename );
+       uri = parse_next_server_and_filename ( next_server, filename );
        if ( ! uri )
                goto err_parse;
 
@@ -272,7 +284,6 @@ struct uri * fetch_next_server_and_filename ( struct settings *settings ) {
        free ( filename );
  err_expand:
        free ( raw_filename );
- err_fetch:
        return uri;
 }
 
@@ -290,11 +301,9 @@ static struct uri * fetch_root_path ( struct settings *settings ) {
        /* Fetch root-path setting */
        fetch_string_setting_copy ( settings, &root_path_setting,
                                    &raw_root_path );
-       if ( ! raw_root_path )
-               goto err_fetch;
 
        /* Expand filename setting */
-       root_path = expand_settings ( raw_root_path );
+       root_path = expand_settings ( raw_root_path ? raw_root_path : "" );
        if ( ! root_path )
                goto err_expand;
 
@@ -309,7 +318,6 @@ static struct uri * fetch_root_path ( struct settings *settings ) {
        free ( root_path );
  err_expand:
        free ( raw_root_path );
- err_fetch:
        return uri;
 }
 
@@ -370,19 +378,32 @@ int netboot ( struct net_device *netdev ) {
                goto err_pxe_menu_boot;
        }
 
-       /* Fetch next server and filename (if any) */
+       /* Fetch next server and filename */
        filename = fetch_next_server_and_filename ( NULL );
+       if ( ! filename )
+               goto err_filename;
+       if ( ! uri_has_path ( filename ) ) {
+               /* Ignore empty filename */
+               uri_put ( filename );
+               filename = NULL;
+       }
 
-       /* Fetch root path (if any) */
+       /* Fetch root path */
        root_path = fetch_root_path ( NULL );
+       if ( ! root_path )
+               goto err_root_path;
+       if ( ! uri_is_absolute ( root_path ) ) {
+               /* Ignore empty root path */
+               uri_put ( root_path );
+               root_path = NULL;
+       }
 
        /* If we have both a filename and a root path, ignore an
-        * unsupported or missing URI scheme in the root path, since
-        * it may represent an NFS root.
+        * unsupported URI scheme in the root path, since it may
+        * represent an NFS root.
         */
        if ( filename && root_path &&
-            ( ( ! uri_is_absolute ( root_path ) ) ||
-              ( xfer_uri_opener ( root_path->scheme ) == NULL ) ) ) {
+            ( xfer_uri_opener ( root_path->scheme ) == NULL ) ) {
                printf ( "Ignoring unsupported root path\n" );
                uri_put ( root_path );
                root_path = NULL;
@@ -403,7 +424,9 @@ int netboot ( struct net_device *netdev ) {
  err_uriboot:
  err_no_boot:
        uri_put ( root_path );
+ err_root_path:
        uri_put ( filename );
+ err_filename:
  err_pxe_menu_boot:
  err_dhcp:
  err_ifopen:
diff --git a/roms/ipxe/src/usr/ibmgmt.c b/roms/ipxe/src/usr/ibmgmt.c
deleted file mode 100644 (file)
index 7857664..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <byteswap.h>
-#include <ipxe/infiniband.h>
-#include <usr/ibmgmt.h>
-
-/** @file
- *
- * Infiniband device management
- *
- */
-
-/**
- * Print status of Infiniband device
- *
- * @v ibdev            Infiniband device
- */
-void ibstat ( struct ib_device *ibdev ) {
-       struct ib_queue_pair *qp;
-
-       printf ( "%s: " IB_GUID_FMT " using %s on %s port %d (%s)\n",
-                ibdev->name, IB_GUID_ARGS ( &ibdev->gid.s.guid ),
-                ibdev->dev->driver_name, ibdev->dev->name, ibdev->port,
-                ( ib_is_open ( ibdev ) ? "open" : "closed" ) );
-       if ( ib_link_ok ( ibdev ) ) {
-               printf ( "  [Link:up LID %d prefix " IB_GUID_FMT "]\n",
-                        ibdev->lid, IB_GUID_ARGS ( &ibdev->gid.s.prefix ) );
-       } else {
-               printf ( "  [Link:down, port state %d]\n", ibdev->port_state );
-       }
-       list_for_each_entry ( qp, &ibdev->qps, list ) {
-               printf ( "  QPN %#lx send %d/%d recv %d/%d %s\n",
-                        qp->qpn, qp->send.fill, qp->send.num_wqes,
-                        qp->recv.fill, qp->recv.num_wqes, qp->name );
-       }
-}
index f367149..aefdaa4 100644 (file)
@@ -33,7 +33,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/job.h>
 #include <ipxe/monojob.h>
 #include <ipxe/timer.h>
-#include <ipxe/errortab.h>
 #include <usr/ifmgmt.h>
 
 /** @file
@@ -51,11 +50,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
        __einfo_uniqify ( EINFO_EADDRNOTAVAIL, 0x01,                    \
                          "No configuration methods succeeded" )
 
-/** Human-readable error message */
-struct errortab ifmgmt_errors[] __errortab = {
-       __einfo_errortab ( EINFO_EADDRNOTAVAIL_CONFIG ),
-};
-
 /**
  * Open network device
  *
index 6b75b50..6b32871 100644 (file)
@@ -188,15 +188,13 @@ static int loopback_wait ( void *data, size_t len ) {
  * @v sender           Sending network device
  * @v receiver         Received network device
  * @v mtu              Packet size (excluding link-layer headers)
- * @v broadcast                Use broadcast link-layer address
  * @ret rc             Return status code
  */
 int loopback_test ( struct net_device *sender, struct net_device *receiver,
-                   size_t mtu, int broadcast ) {
+                   size_t mtu ) {
        uint8_t *buf;
        uint32_t *seq;
        struct io_buffer *iobuf;
-       const void *ll_dest;
        unsigned int i;
        unsigned int successes;
        int rc;
@@ -221,13 +219,9 @@ int loopback_test ( struct net_device *sender, struct net_device *receiver,
                return -ENOMEM;
        seq = ( ( void * ) buf );
 
-       /* Determine destination address */
-       ll_dest = ( broadcast ? sender->ll_broadcast : receiver->ll_addr );
-
        /* Print initial statistics */
-       printf ( "Performing %sloopback test from %s to %s with %zd byte MTU\n",
-                ( broadcast ? "broadcast " : "" ), sender->name,
-                receiver->name, mtu );
+       printf ( "Performing loopback test from %s to %s with %zd byte MTU\n",
+                sender->name, receiver->name, mtu );
        ifstat ( sender );
        ifstat ( receiver );
 
@@ -256,7 +250,7 @@ int loopback_test ( struct net_device *sender, struct net_device *receiver,
 
                /* Transmit packet */
                if ( ( rc = net_tx ( iob_disown ( iobuf ), sender,
-                                    &lotest_protocol, ll_dest,
+                                    &lotest_protocol, receiver->ll_addr,
                                     sender->ll_addr ) ) != 0 ) {
                        printf ( "\nFailed to transmit packet: %s",
                                 strerror ( rc ) );
diff --git a/roms/ipxe/src/usr/ntpmgmt.c b/roms/ipxe/src/usr/ntpmgmt.c
deleted file mode 100644 (file)
index 765c6dc..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <ipxe/ntp.h>
-#include <ipxe/monojob.h>
-#include <usr/ntpmgmt.h>
-
-/** @file
- *
- * NTP management
- *
- */
-
-/**
- * Get time and date via NTP
- *
- * @v hostname         Hostname
- * @ret rc             Return status code
- */
-int ntp ( const char *hostname ) {
-       int rc;
-
-       /* Start NTP client */
-       if ( ( rc = start_ntp ( &monojob, hostname ) ) != 0 )
-               return rc;
-
-       /* Wait for NTP to complete */
-       if ( ( rc = monojob_wait ( NULL, 0 ) ) != 0 )
-               return rc;
-
-       return 0;
-}
index 918e7a3..c02f750 100644 (file)
@@ -17,7 +17,6 @@
  * 02110-1301, USA.
  */
 
-#define FILE_LICENCE(...) extern void __file_licence ( void )
 #include <stdint.h>
 #include <stddef.h>
 #include <stdlib.h>
@@ -28,7 +27,7 @@
 #include <errno.h>
 #include <assert.h>
 #include <getopt.h>
-#include <ipxe/efi/Uefi.h>
+#include <ipxe/efi/efi.h>
 #include <ipxe/efi/IndustryStandard/PeImage.h>
 
 #define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
index 943a669..abee496 100644 (file)
@@ -17,7 +17,6 @@
  * 02110-1301, USA.
  */
 
-#define FILE_LICENCE(...) extern void __file_licence ( void )
 #include <stdint.h>
 #include <stddef.h>
 #include <stdlib.h>
@@ -28,7 +27,7 @@
 #include <errno.h>
 #include <assert.h>
 #include <getopt.h>
-#include <ipxe/efi/Uefi.h>
+#include <ipxe/efi/efi.h>
 #include <ipxe/efi/IndustryStandard/PeImage.h>
 #include <ipxe/efi/IndustryStandard/Pci22.h>
 
@@ -81,11 +80,9 @@ static void read_pe_info ( void *pe, uint16_t *machine,
        *machine = nt->nt32.FileHeader.Machine;
        switch ( *machine ) {
        case EFI_IMAGE_MACHINE_IA32:
-       case EFI_IMAGE_MACHINE_ARMTHUMB_MIXED:
                *subsystem = nt->nt32.OptionalHeader.Subsystem;
                break;
        case EFI_IMAGE_MACHINE_X64:
-       case EFI_IMAGE_MACHINE_AARCH64:
                *subsystem = nt->nt64.OptionalHeader.Subsystem;
                break;
        default:
index 152bf53..e68fa5d 100644 (file)
@@ -17,7 +17,9 @@
  * 02110-1301, USA.
  */
 
-#define FILE_LICENCE(...) extern void __file_licence ( void )
+#define _GNU_SOURCE
+#define PACKAGE "elf2efi"
+#define PACKAGE_VERSION "1"
 #include <stdint.h>
 #include <stddef.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <assert.h>
 #include <getopt.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <elf.h>
-#include <ipxe/efi/Uefi.h>
+#include <bfd.h>
+#include <ipxe/efi/efi.h>
 #include <ipxe/efi/IndustryStandard/PeImage.h>
 #include <libgen.h>
 
 #define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
 
-#ifdef EFI_TARGET32
-
-#define EFI_IMAGE_NT_HEADERS           EFI_IMAGE_NT_HEADERS32
-#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC        EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
-#define EFI_IMAGE_FILE_MACHINE         EFI_IMAGE_FILE_32BIT_MACHINE
-#define ELFCLASS   ELFCLASS32
-#define Elf_Ehdr   Elf32_Ehdr
-#define Elf_Shdr   Elf32_Shdr
-#define Elf_Sym    Elf32_Sym
-#define Elf_Addr   Elf32_Addr
-#define Elf_Rel    Elf32_Rel
-#define Elf_Rela   Elf32_Rela
-#define ELF_R_TYPE ELF32_R_TYPE
-#define ELF_R_SYM  ELF32_R_SYM
-
-#elif defined(EFI_TARGET64)
-
-#define EFI_IMAGE_NT_HEADERS           EFI_IMAGE_NT_HEADERS64
-#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC        EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
-#define EFI_IMAGE_FILE_MACHINE         0
-#define ELFCLASS   ELFCLASS64
-#define Elf_Ehdr   Elf64_Ehdr
-#define Elf_Shdr   Elf64_Shdr
-#define Elf_Sym    Elf64_Sym
-#define Elf_Addr   Elf64_Addr
-#define Elf_Rel    Elf64_Rel
-#define Elf_Rela   Elf64_Rela
-#define ELF_R_TYPE ELF64_R_TYPE
-#define ELF_R_SYM  ELF64_R_SYM
-
-#endif
-
-#define ELF_MREL( mach, type ) ( (mach) | ( (type) << 16 ) )
-
-/* Allow for building with older versions of elf.h */
-#ifndef EM_AARCH64
-#define EM_AARCH64 183
-#define R_AARCH64_NONE 0
-#define R_AARCH64_ABS64 257
-#define R_AARCH64_CALL26 283
-#define R_AARCH64_JUMP26 282
-#define R_AARCH64_ADR_PREL_LO21 274
-#define R_AARCH64_ADR_PREL_PG_HI21 275
-#define R_AARCH64_ADD_ABS_LO12_NC 277
-#define R_AARCH64_LDST8_ABS_LO12_NC 278
-#define R_AARCH64_LDST16_ABS_LO12_NC 284
-#define R_AARCH64_LDST32_ABS_LO12_NC 285
-#define R_AARCH64_LDST64_ABS_LO12_NC 286
-#endif /* EM_AARCH64 */
-#ifndef R_ARM_CALL
-#define R_ARM_CALL 28
-#endif
-#ifndef R_ARM_THM_JUMP24
-#define R_ARM_THM_JUMP24 30
-#endif
-
-/* Seems to be missing from elf.h */
-#ifndef R_AARCH64_NULL
-#define R_AARCH64_NULL 256
-#endif
-
 #define EFI_FILE_ALIGN 0x20
 
-struct elf_file {
-       void *data;
-       size_t len;
-       const Elf_Ehdr *ehdr;
-};
-
 struct pe_section {
        struct pe_section *next;
        EFI_IMAGE_SECTION_HEADER hdr;
-       void ( * fixup ) ( struct pe_section *section );
        uint8_t contents[0];
 };
 
@@ -125,7 +55,11 @@ struct pe_relocs {
 struct pe_header {
        EFI_IMAGE_DOS_HEADER dos;
        uint8_t padding[128];
-       EFI_IMAGE_NT_HEADERS nt;
+#if defined(EFI_TARGET_IA32)
+       EFI_IMAGE_NT_HEADERS32 nt;
+#elif defined(EFI_TARGET_X64)
+       EFI_IMAGE_NT_HEADERS64 nt;
+#endif
 };
 
 static struct pe_header efi_pe_header = {
@@ -136,17 +70,26 @@ static struct pe_header efi_pe_header = {
        .nt = {
                .Signature = EFI_IMAGE_NT_SIGNATURE,
                .FileHeader = {
+#if defined(EFI_TARGET_IA32)
+                       .Machine = EFI_IMAGE_MACHINE_IA32,
+#elif defined(EFI_TARGET_X64)
+                       .Machine = EFI_IMAGE_MACHINE_X64,
+#endif
                        .TimeDateStamp = 0x10d1a884,
                        .SizeOfOptionalHeader =
                                sizeof ( efi_pe_header.nt.OptionalHeader ),
                        .Characteristics = ( EFI_IMAGE_FILE_DLL |
-                                            EFI_IMAGE_FILE_MACHINE |
+#if defined(EFI_TARGET_IA32)
+                                            EFI_IMAGE_FILE_32BIT_MACHINE |
+#endif
                                             EFI_IMAGE_FILE_EXECUTABLE_IMAGE ),
                },
                .OptionalHeader = {
-                       .Magic = EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC,
-                       .MajorLinkerVersion = 42,
-                       .MinorLinkerVersion = 42,
+#if defined(EFI_TARGET_IA32)
+                       .Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC,
+#elif defined(EFI_TARGET_X64)
+                       .Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC,
+#endif
                        .SectionAlignment = EFI_FILE_ALIGN,
                        .FileAlignment = EFI_FILE_ALIGN,
                        .SizeOfImage = sizeof ( efi_pe_header ),
@@ -288,175 +231,110 @@ static size_t output_pe_reltab ( struct pe_relocs *pe_reltab,
 }
 
 /**
- * Read input ELF file
+ * Open input BFD file
  *
- * @v name             File name
- * @v elf              ELF file
+ * @v filename         File name
+ * @ret ibfd           BFD file
  */
-static void read_elf_file ( const char *name, struct elf_file *elf ) {
-       static const unsigned char ident[] = {
-               ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ELFCLASS, ELFDATA2LSB
-       };
-       struct stat stat;
-       const Elf_Ehdr *ehdr;
-       const Elf_Shdr *shdr;
-       void *data;
-       size_t offset;
-       unsigned int i;
-       int fd;
-
-       /* Open file */
-       fd = open ( name, O_RDONLY );
-       if ( fd < 0 ) {
-               eprintf ( "Could not open %s: %s\n", name, strerror ( errno ) );
+static bfd * open_input_bfd ( const char *filename ) {
+       bfd *bfd;
+
+       /* Open the file */
+       bfd = bfd_openr ( filename, NULL );
+       if ( ! bfd ) {
+               eprintf ( "Cannot open %s: ", filename );
+               bfd_perror ( NULL );
                exit ( 1 );
        }
 
-       /* Get file size */
-       if ( fstat ( fd, &stat ) < 0 ) {
-               eprintf ( "Could not get size of %s: %s\n",
-                         name, strerror ( errno ) );
+       /* The call to bfd_check_format() must be present, otherwise
+        * we get a segfault from later BFD calls.
+        */
+       if ( ! bfd_check_format ( bfd, bfd_object ) ) {
+               eprintf ( "%s is not an object file: ", filename );
+               bfd_perror ( NULL );
                exit ( 1 );
        }
-       elf->len = stat.st_size;
 
-       /* Map file */
-       data = mmap ( NULL, elf->len, PROT_READ, MAP_SHARED, fd, 0 );
-       if ( data == MAP_FAILED ) {
-               eprintf ( "Could not map %s: %s\n", name, strerror ( errno ) );
-               exit ( 1 );
-       }
-       elf->data = data;
-
-       /* Close file */
-       close ( fd );
-
-       /* Check header */
-       ehdr = elf->data;
-       if ( ( elf->len < sizeof ( *ehdr ) ) ||
-            ( memcmp ( ident, ehdr->e_ident, sizeof ( ident ) ) != 0 ) ) {
-               eprintf ( "Invalid ELF header in %s\n", name );
-               exit ( 1 );
-       }
-       elf->ehdr = ehdr;
-
-       /* Check section headers */
-       for ( i = 0 ; i < ehdr->e_shnum ; i++ ) {
-               offset = ( ehdr->e_shoff + ( i * ehdr->e_shentsize ) );
-               if ( elf->len < ( offset + sizeof ( *shdr ) ) ) {
-                       eprintf ( "ELF section header outside file in %s\n",
-                                 name );
-                       exit ( 1 );
-               }
-               shdr = ( data + offset );
-               if ( ( shdr->sh_type != SHT_NOBITS ) &&
-                    ( ( elf->len < shdr->sh_offset ) ||
-                      ( ( ( elf->len - shdr->sh_offset ) < shdr->sh_size ) ))){
-                       eprintf ( "ELF section %d outside file in %s\n",
-                                 i, name );
-                       exit ( 1 );
-               }
-               if ( shdr->sh_link >= ehdr->e_shnum ) {
-                       eprintf ( "ELF section %d link section %d out of "
-                                 "range\n", i, shdr->sh_link );
-                       exit ( 1 );
-               }
-       }
+       return bfd;
 }
 
 /**
- * Get ELF string
+ * Read symbol table
  *
- * @v elf              ELF file
- * @v section          String table section number
- * @v offset           String table offset
- * @ret string         ELF string
+ * @v bfd              BFD file
  */
-static const char * elf_string ( struct elf_file *elf, unsigned int section,
-                                size_t offset ) {
-       const Elf_Ehdr *ehdr = elf->ehdr;
-       const Elf_Shdr *shdr;
-       char *string;
-       char *last;
-
-       /* Locate section header */
-       if ( section >= ehdr->e_shnum ) {
-               eprintf ( "Invalid ELF string section %d\n", section );
+static asymbol ** read_symtab ( bfd *bfd ) {
+       long symtab_size;
+       asymbol **symtab;
+       long symcount;
+
+       /* Get symbol table size */
+       symtab_size = bfd_get_symtab_upper_bound ( bfd );
+       if ( symtab_size < 0 ) {
+               bfd_perror ( "Could not get symbol table upper bound" );
                exit ( 1 );
        }
-       shdr = ( elf->data + ehdr->e_shoff + ( section * ehdr->e_shentsize ) );
 
-       /* Sanity check section */
-       if ( shdr->sh_type != SHT_STRTAB ) {
-               eprintf ( "ELF section %d (type %d) is not a string table\n",
-                         section, shdr->sh_type );
-               exit ( 1 );
-       }
-       last = ( elf->data + shdr->sh_offset + shdr->sh_size - 1 );
-       if ( *last != '\0' ) {
-               eprintf ( "ELF section %d is not NUL-terminated\n", section );
+       /* Allocate and read symbol table */
+       symtab = xmalloc ( symtab_size );
+       symcount = bfd_canonicalize_symtab ( bfd, symtab );
+       if ( symcount < 0 ) {
+               bfd_perror ( "Cannot read symbol table" );
                exit ( 1 );
        }
 
-       /* Locate string */
-       if ( offset >= shdr->sh_size ) {
-               eprintf ( "Invalid ELF string offset %zd in section %d\n",
-                         offset, section );
-               exit ( 1 );
-       }
-       string = ( elf->data + shdr->sh_offset + offset );
-
-       return string;
+       return symtab;
 }
 
 /**
- * Set machine architecture
+ * Read relocation table
  *
- * @v elf              ELF file
- * @v pe_header                PE file header
+ * @v bfd              BFD file
+ * @v symtab           Symbol table
+ * @v section          Section
+ * @v symtab           Symbol table
+ * @ret reltab         Relocation table
  */
-static void set_machine ( struct elf_file *elf, struct pe_header *pe_header ) {
-       const Elf_Ehdr *ehdr = elf->ehdr;
-       uint16_t machine;
-
-       /* Identify machine architecture */
-       switch ( ehdr->e_machine ) {
-       case EM_386:
-               machine = EFI_IMAGE_MACHINE_IA32;
-               break;
-       case EM_X86_64:
-               machine = EFI_IMAGE_MACHINE_X64;
-               break;
-       case EM_ARM:
-               machine = EFI_IMAGE_MACHINE_ARMTHUMB_MIXED;
-               break;
-       case EM_AARCH64:
-               machine = EFI_IMAGE_MACHINE_AARCH64;
-               break;
-       default:
-               eprintf ( "Unknown ELF architecture %d\n", ehdr->e_machine );
+static arelent ** read_reltab ( bfd *bfd, asymbol **symtab,
+                               asection *section ) {
+       long reltab_size;
+       arelent **reltab;
+       long numrels;
+
+       /* Get relocation table size */
+       reltab_size = bfd_get_reloc_upper_bound ( bfd, section );
+       if ( reltab_size < 0 ) {
+               bfd_perror ( "Could not get relocation table upper bound" );
                exit ( 1 );
        }
 
-       /* Set machine architecture */
-       pe_header->nt.FileHeader.Machine = machine;
+       /* Allocate and read relocation table */
+       reltab = xmalloc ( reltab_size );
+       numrels = bfd_canonicalize_reloc ( bfd, section, reltab, symtab );
+       if ( numrels < 0 ) {
+               bfd_perror ( "Cannot read relocation table" );
+               exit ( 1 );
+       }
+
+       return reltab;
 }
 
 /**
  * Process section
  *
- * @v elf              ELF file
- * @v shdr             ELF section header
+ * @v bfd              BFD file
  * @v pe_header                PE file header
+ * @v section          Section
  * @ret new            New PE section
  */
-static struct pe_section * process_section ( struct elf_file *elf,
-                                            const Elf_Shdr *shdr,
-                                            struct pe_header *pe_header ) {
+static struct pe_section * process_section ( bfd *bfd,
+                                            struct pe_header *pe_header,
+                                            asection *section ) {
        struct pe_section *new;
-       const char *name;
        size_t section_memsz;
        size_t section_filesz;
+       unsigned long flags = bfd_get_section_flags ( bfd, section );
        unsigned long code_start;
        unsigned long code_end;
        unsigned long data_start;
@@ -467,15 +345,12 @@ static struct pe_section * process_section ( struct elf_file *elf,
        unsigned long *applicable_start;
        unsigned long *applicable_end;
 
-       /* Get section name */
-       name = elf_string ( elf, elf->ehdr->e_shstrndx, shdr->sh_name );
-
        /* Extract current RVA limits from file header */
        code_start = pe_header->nt.OptionalHeader.BaseOfCode;
        code_end = ( code_start + pe_header->nt.OptionalHeader.SizeOfCode );
-#if defined(EFI_TARGET32)
+#if defined(EFI_TARGET_IA32)
        data_start = pe_header->nt.OptionalHeader.BaseOfData;
-#elif defined(EFI_TARGET64)
+#elif defined(EFI_TARGET_X64)
        data_start = code_end;
 #endif
        data_mid = ( data_start +
@@ -484,21 +359,21 @@ static struct pe_section * process_section ( struct elf_file *elf,
                     pe_header->nt.OptionalHeader.SizeOfUninitializedData );
 
        /* Allocate PE section */
-       section_memsz = shdr->sh_size;
-       section_filesz = ( ( shdr->sh_type == SHT_PROGBITS ) ?
+       section_memsz = bfd_section_size ( bfd, section );
+       section_filesz = ( ( flags & SEC_LOAD ) ?
                           efi_file_align ( section_memsz ) : 0 );
        new = xmalloc ( sizeof ( *new ) + section_filesz );
        memset ( new, 0, sizeof ( *new ) + section_filesz );
 
        /* Fill in section header details */
-       strncpy ( ( char * ) new->hdr.Name, name, sizeof ( new->hdr.Name ) );
+       strncpy ( ( char * ) new->hdr.Name, section->name,
+                 sizeof ( new->hdr.Name ) );
        new->hdr.Misc.VirtualSize = section_memsz;
-       new->hdr.VirtualAddress = shdr->sh_addr;
+       new->hdr.VirtualAddress = bfd_get_section_vma ( bfd, section );
        new->hdr.SizeOfRawData = section_filesz;
 
        /* Fill in section characteristics and update RVA limits */
-       if ( ( shdr->sh_type == SHT_PROGBITS ) &&
-            ( shdr->sh_flags & SHF_EXECINSTR ) ) {
+       if ( flags & SEC_CODE ) {
                /* .text-type section */
                new->hdr.Characteristics =
                        ( EFI_IMAGE_SCN_CNT_CODE |
@@ -507,8 +382,7 @@ static struct pe_section * process_section ( struct elf_file *elf,
                          EFI_IMAGE_SCN_MEM_READ );
                applicable_start = &code_start;
                applicable_end = &code_end;
-       } else if ( ( shdr->sh_type == SHT_PROGBITS ) &&
-                   ( shdr->sh_flags & SHF_WRITE ) ) {
+       } else if ( flags & SEC_DATA ) {
                /* .data-type section */
                new->hdr.Characteristics =
                        ( EFI_IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -517,7 +391,7 @@ static struct pe_section * process_section ( struct elf_file *elf,
                          EFI_IMAGE_SCN_MEM_WRITE );
                applicable_start = &data_start;
                applicable_end = &data_mid;
-       } else if ( shdr->sh_type == SHT_PROGBITS ) {
+       } else if ( flags & SEC_READONLY ) {
                /* .rodata-type section */
                new->hdr.Characteristics =
                        ( EFI_IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -525,7 +399,7 @@ static struct pe_section * process_section ( struct elf_file *elf,
                          EFI_IMAGE_SCN_MEM_READ );
                applicable_start = &data_start;
                applicable_end = &data_mid;
-       } else if ( shdr->sh_type == SHT_NOBITS ) {
+       } else if ( ! ( flags & SEC_LOAD ) ) {
                /* .bss-type section */
                new->hdr.Characteristics =
                        ( EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA |
@@ -535,15 +409,19 @@ static struct pe_section * process_section ( struct elf_file *elf,
                applicable_start = &data_mid;
                applicable_end = &data_end;
        } else {
-               eprintf ( "Unrecognised characteristics for section %s\n",
-                         name );
+               eprintf ( "Unrecognised characteristics %#lx for section %s\n",
+                         flags, section->name );
                exit ( 1 );
        }
 
        /* Copy in section contents */
-       if ( shdr->sh_type == SHT_PROGBITS ) {
-               memcpy ( new->contents, ( elf->data + shdr->sh_offset ),
-                        shdr->sh_size );
+       if ( flags & SEC_LOAD ) {
+               if ( ! bfd_get_section_contents ( bfd, section, new->contents,
+                                                 0, section_memsz ) ) {
+                       eprintf ( "Cannot read section %s: ", section->name );
+                       bfd_perror ( NULL );
+                       exit ( 1 );
+               }
        }
 
        /* Update RVA limits */
@@ -563,7 +441,7 @@ static struct pe_section * process_section ( struct elf_file *elf,
        /* Write RVA limits back to file header */
        pe_header->nt.OptionalHeader.BaseOfCode = code_start;
        pe_header->nt.OptionalHeader.SizeOfCode = ( code_end - code_start );
-#if defined(EFI_TARGET32)
+#if defined(EFI_TARGET_IA32)
        pe_header->nt.OptionalHeader.BaseOfData = data_start;
 #endif
        pe_header->nt.OptionalHeader.SizeOfInitializedData =
@@ -583,104 +461,43 @@ static struct pe_section * process_section ( struct elf_file *elf,
 /**
  * Process relocation record
  *
- * @v elf              ELF file
- * @v shdr             ELF section header
- * @v syms             Symbol table
- * @v nsyms            Number of symbol table entries
- * @v rel              Relocation record
+ * @v bfd              BFD file
+ * @v section          Section
+ * @v rel              Relocation entry
  * @v pe_reltab                PE relocation table to fill in
  */
-static void process_reloc ( struct elf_file *elf, const Elf_Shdr *shdr,
-                           const Elf_Sym *syms, unsigned int nsyms,
-                           const Elf_Rel *rel, struct pe_relocs **pe_reltab ) {
-       unsigned int type = ELF_R_TYPE ( rel->r_info );
-       unsigned int sym = ELF_R_SYM ( rel->r_info );
-       unsigned int mrel = ELF_MREL ( elf->ehdr->e_machine, type );
-       size_t offset = ( shdr->sh_addr + rel->r_offset );
-
-       /* Look up symbol and process relocation */
-       if ( sym >= nsyms ) {
-               eprintf ( "Symbol out of range\n" );
-               exit ( 1 );
-       }
-       if ( syms[sym].st_shndx == SHN_ABS ) {
+static void process_reloc ( bfd *bfd __attribute__ (( unused )),
+                           asection *section, arelent *rel,
+                           struct pe_relocs **pe_reltab ) {
+       reloc_howto_type *howto = rel->howto;
+       asymbol *sym = *(rel->sym_ptr_ptr);
+       unsigned long offset = ( bfd_get_section_vma ( bfd, section ) +
+                                rel->address );
+
+       if ( bfd_is_abs_section ( sym->section ) ) {
                /* Skip absolute symbols; the symbol value won't
                 * change when the object is loaded.
                 */
+       } else if ( ( strcmp ( howto->name, "R_386_NONE" ) == 0 ) ||
+                   ( strcmp ( howto->name, "R_X86_64_NONE" ) == 0 ) ) {
+               /* Ignore dummy relocations used by REQUIRE_SYMBOL() */
+       } else if ( strcmp ( howto->name, "R_X86_64_64" ) == 0 ) {
+               /* Generate an 8-byte PE relocation */
+               generate_pe_reloc ( pe_reltab, offset, 8 );
+       } else if ( strcmp ( howto->name, "R_386_32" ) == 0 ) {
+               /* Generate a 4-byte PE relocation */
+               generate_pe_reloc ( pe_reltab, offset, 4 );
+       } else if ( strcmp ( howto->name, "R_386_16" ) == 0 ) {
+               /* Generate a 2-byte PE relocation */
+               generate_pe_reloc ( pe_reltab, offset, 2 );
+       } else if ( ( strcmp ( howto->name, "R_386_PC32" ) == 0 ) ||
+                   ( strcmp ( howto->name, "R_X86_64_PC32" ) == 0 ) ) {
+               /* Skip PC-relative relocations; all relative offsets
+                * remain unaltered when the object is loaded.
+                */
        } else {
-               switch ( mrel ) {
-               case ELF_MREL ( EM_386, R_386_NONE ) :
-               case ELF_MREL ( EM_ARM, R_ARM_NONE ) :
-               case ELF_MREL ( EM_X86_64, R_X86_64_NONE ) :
-               case ELF_MREL ( EM_AARCH64, R_AARCH64_NONE ) :
-               case ELF_MREL ( EM_AARCH64, R_AARCH64_NULL ) :
-                       /* Ignore dummy relocations used by REQUIRE_SYMBOL() */
-                       break;
-               case ELF_MREL ( EM_386, R_386_32 ) :
-               case ELF_MREL ( EM_ARM, R_ARM_ABS32 ) :
-                       /* Generate a 4-byte PE relocation */
-                       generate_pe_reloc ( pe_reltab, offset, 4 );
-                       break;
-               case ELF_MREL ( EM_X86_64, R_X86_64_64 ) :
-               case ELF_MREL ( EM_AARCH64, R_AARCH64_ABS64 ) :
-                       /* Generate an 8-byte PE relocation */
-                       generate_pe_reloc ( pe_reltab, offset, 8 );
-                       break;
-               case ELF_MREL ( EM_386, R_386_PC32 ) :
-               case ELF_MREL ( EM_ARM, R_ARM_CALL ) :
-               case ELF_MREL ( EM_ARM, R_ARM_THM_PC22 ) :
-               case ELF_MREL ( EM_ARM, R_ARM_THM_JUMP24 ) :
-               case ELF_MREL ( EM_X86_64, R_X86_64_PC32 ) :
-               case ELF_MREL ( EM_AARCH64, R_AARCH64_CALL26 ) :
-               case ELF_MREL ( EM_AARCH64, R_AARCH64_JUMP26 ) :
-               case ELF_MREL ( EM_AARCH64, R_AARCH64_ADR_PREL_LO21 ) :
-               case ELF_MREL ( EM_AARCH64, R_AARCH64_ADR_PREL_PG_HI21 ) :
-               case ELF_MREL ( EM_AARCH64, R_AARCH64_ADD_ABS_LO12_NC ) :
-               case ELF_MREL ( EM_AARCH64, R_AARCH64_LDST8_ABS_LO12_NC ) :
-               case ELF_MREL ( EM_AARCH64, R_AARCH64_LDST16_ABS_LO12_NC ) :
-               case ELF_MREL ( EM_AARCH64, R_AARCH64_LDST32_ABS_LO12_NC ) :
-               case ELF_MREL ( EM_AARCH64, R_AARCH64_LDST64_ABS_LO12_NC ) :
-                       /* Skip PC-relative relocations; all relative
-                        * offsets remain unaltered when the object is
-                        * loaded.
-                        */
-                       break;
-               default:
-                       eprintf ( "Unrecognised relocation type %d\n", type );
-                       exit ( 1 );
-               }
-       }
-}
-
-/**
- * Process relocation records
- *
- * @v elf              ELF file
- * @v shdr             ELF section header
- * @v stride           Relocation record size
- * @v pe_reltab                PE relocation table to fill in
- */
-static void process_relocs ( struct elf_file *elf, const Elf_Shdr *shdr,
-                            size_t stride, struct pe_relocs **pe_reltab ) {
-       const Elf_Shdr *symtab;
-       const Elf_Sym *syms;
-       const Elf_Rel *rel;
-       unsigned int nsyms;
-       unsigned int nrels;
-       unsigned int i;
-
-       /* Identify symbol table */
-       symtab = ( elf->data + elf->ehdr->e_shoff +
-                  ( shdr->sh_link * elf->ehdr->e_shentsize ) );
-       syms = ( elf->data + symtab->sh_offset );
-       nsyms = ( symtab->sh_size / sizeof ( syms[0] ) );
-
-       /* Process each relocation */
-       rel = ( elf->data + shdr->sh_offset );
-       nrels = ( shdr->sh_size / stride );
-       for ( i = 0 ; i < nrels ; i++ ) {
-               process_reloc ( elf, shdr, syms, nsyms, rel, pe_reltab );
-               rel = ( ( ( const void * ) rel ) + stride );
+               eprintf ( "Unrecognised relocation type %s\n", howto->name );
+               exit ( 1 );
        }
 }
 
@@ -731,20 +548,6 @@ create_reloc_section ( struct pe_header *pe_header,
 }
 
 /**
- * Fix up debug section
- *
- * @v debug            Debug section
- */
-static void fixup_debug_section ( struct pe_section *debug ) {
-       EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *contents;
-
-       /* Fix up FileOffset */
-       contents = ( ( void * ) debug->contents );
-       contents->FileOffset += ( debug->hdr.PointerToRawData -
-                                 debug->hdr.VirtualAddress );
-}
-
-/**
  * Create debug section
  *
  * @v pe_header                PE file header
@@ -778,7 +581,6 @@ create_debug_section ( struct pe_header *pe_header, const char *filename ) {
        debug->hdr.Characteristics = ( EFI_IMAGE_SCN_CNT_INITIALIZED_DATA |
                                       EFI_IMAGE_SCN_MEM_NOT_PAGED |
                                       EFI_IMAGE_SCN_MEM_READ );
-       debug->fixup = fixup_debug_section;
 
        /* Create section contents */
        contents->debug.TimeDateStamp = 0x10d1a884;
@@ -787,7 +589,6 @@ create_debug_section ( struct pe_header *pe_header, const char *filename ) {
                ( sizeof ( *contents ) - sizeof ( contents->debug ) );
        contents->debug.RVA = ( debug->hdr.VirtualAddress +
                                offsetof ( typeof ( *contents ), rsds ) );
-       contents->debug.FileOffset = contents->debug.RVA;
        contents->rsds.Signature = CODEVIEW_SIGNATURE_RSDS;
        snprintf ( contents->name, sizeof ( contents->name ), "%s",
                   filename );
@@ -799,7 +600,7 @@ create_debug_section ( struct pe_header *pe_header, const char *filename ) {
        debugdir = &(pe_header->nt.OptionalHeader.DataDirectory
                     [EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
        debugdir->VirtualAddress = debug->hdr.VirtualAddress;
-       debugdir->Size = sizeof ( contents->debug );
+       debugdir->Size = debug->hdr.Misc.VirtualSize;
 
        return debug;
 }
@@ -828,8 +629,6 @@ static void write_pe_file ( struct pe_header *pe_header,
                        fpos += section->hdr.SizeOfRawData;
                        fpos = efi_file_align ( fpos );
                }
-               if ( section->fixup )
-                       section->fixup ( section );
        }
 
        /* Write file header */
@@ -875,60 +674,53 @@ static void write_pe_file ( struct pe_header *pe_header,
 static void elf2pe ( const char *elf_name, const char *pe_name,
                     struct options *opts ) {
        char pe_name_tmp[ strlen ( pe_name ) + 1 ];
+       bfd *bfd;
+       asymbol **symtab;
+       asection *section;
+       arelent **reltab;
+       arelent **rel;
        struct pe_relocs *pe_reltab = NULL;
        struct pe_section *pe_sections = NULL;
        struct pe_section **next_pe_section = &pe_sections;
        struct pe_header pe_header;
-       struct elf_file elf;
-       const Elf_Shdr *shdr;
-       size_t offset;
-       unsigned int i;
        FILE *pe;
 
        /* Create a modifiable copy of the PE name */
        memcpy ( pe_name_tmp, pe_name, sizeof ( pe_name_tmp ) );
 
-       /* Read ELF file */
-       read_elf_file ( elf_name, &elf );
+       /* Open the file */
+       bfd = open_input_bfd ( elf_name );
+       symtab = read_symtab ( bfd );
 
        /* Initialise the PE header */
        memcpy ( &pe_header, &efi_pe_header, sizeof ( pe_header ) );
-       set_machine ( &elf, &pe_header );
-       pe_header.nt.OptionalHeader.AddressOfEntryPoint = elf.ehdr->e_entry;
+       pe_header.nt.OptionalHeader.AddressOfEntryPoint =
+               bfd_get_start_address ( bfd );
        pe_header.nt.OptionalHeader.Subsystem = opts->subsystem;
 
-       /* Process input sections */
-       for ( i = 0 ; i < elf.ehdr->e_shnum ; i++ ) {
-               offset = ( elf.ehdr->e_shoff + ( i * elf.ehdr->e_shentsize ) );
-               shdr = ( elf.data + offset );
-
-               /* Process section */
-               if ( shdr->sh_flags & SHF_ALLOC ) {
-
-                       /* Create output section */
-                       *(next_pe_section) = process_section ( &elf, shdr,
-                                                              &pe_header );
-                       next_pe_section = &(*next_pe_section)->next;
-
-               } else if ( shdr->sh_type == SHT_REL ) {
-
-                       /* Process .rel relocations */
-                       process_relocs ( &elf, shdr, sizeof ( Elf_Rel ),
-                                        &pe_reltab );
-
-               } else if ( shdr->sh_type == SHT_RELA ) {
-
-                       /* Process .rela relocations */
-                       process_relocs ( &elf, shdr, sizeof ( Elf_Rela ),
-                                        &pe_reltab );
-               }
+       /* For each input section, build an output section and create
+        * the appropriate relocation records
+        */
+       for ( section = bfd->sections ; section ; section = section->next ) {
+               /* Discard non-allocatable sections */
+               if ( ! ( bfd_get_section_flags ( bfd, section ) & SEC_ALLOC ) )
+                       continue;
+               /* Create output section */
+               *(next_pe_section) = process_section ( bfd, &pe_header,
+                                                      section );
+               next_pe_section = &(*next_pe_section)->next;
+               /* Add relocations from this section */
+               reltab = read_reltab ( bfd, symtab, section );
+               for ( rel = reltab ; *rel ; rel++ )
+                       process_reloc ( bfd, section, *rel, &pe_reltab );
+               free ( reltab );
        }
 
        /* Create the .reloc section */
        *(next_pe_section) = create_reloc_section ( &pe_header, pe_reltab );
        next_pe_section = &(*next_pe_section)->next;
 
-       /* Create the .debug section */
+       /* Create the .reloc section */
        *(next_pe_section) = create_debug_section ( &pe_header,
                                                    basename ( pe_name_tmp ) );
        next_pe_section = &(*next_pe_section)->next;
@@ -943,8 +735,8 @@ static void elf2pe ( const char *elf_name, const char *pe_name,
        write_pe_file ( &pe_header, pe_sections, pe );
        fclose ( pe );
 
-       /* Unmap ELF file */
-       munmap ( elf.data, elf.len );
+       /* Close BFD file */
+       bfd_close ( bfd );
 }
 
 /**
@@ -1011,6 +803,9 @@ int main ( int argc, char **argv ) {
        const char *infile;
        const char *outfile;
 
+       /* Initialise libbfd */
+       bfd_init();
+
        /* Parse command-line arguments */
        infile_index = parse_options ( argc, argv, &opts );
        if ( argc != ( infile_index + 2 ) ) {
diff --git a/roms/ipxe/src/util/genefidsk b/roms/ipxe/src/util/genefidsk
deleted file mode 100755 (executable)
index 7064f99..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/sh
-#
-# Generate an EFI bootable disk image
-
-set -e
-
-function help() {
-       echo "Usage: ${0} [OPTIONS] <ipxe.efi>"
-       echo
-       echo "where OPTIONS are:"
-       echo " -h       Show this help"
-       echo " -b       Specify boot file name (e.g. bootx64.efi)"
-       echo " -o FILE  Save disk image to file"
-}
-
-BOOT=bootx64.efi
-
-while getopts "hb:o:" opt; do
-       case ${opt} in
-               h)
-                       help
-                       exit 0
-                       ;;
-               b)
-                       BOOT="${OPTARG}"
-                       ;;
-               o)
-                       OUT="${OPTARG}"
-                       ;;
-       esac
-done
-
-shift $((OPTIND - 1))
-IN=$1
-
-if [ -z "${IN}" ]; then
-       echo "${0}: no input file given" >&2
-       help
-       exit 1
-fi
-
-if [ -z "${OUT}" ]; then
-       echo "${0}: no output file given" >&2
-       help
-       exit 1
-fi
-
-# Create sparse output file
-rm -f ${OUT}
-truncate -s 1440K ${OUT}
-
-# Format disk
-mformat -i ${OUT} -f 1440 ::
-
-# Create directory structure
-mmd -i ${OUT} ::efi
-mmd -i ${OUT} ::efi/boot
-
-# Copy bootable image
-mcopy -i ${OUT} ${IN} ::efi/boot/${BOOT}
index ff090d4..521c929 100755 (executable)
@@ -123,7 +123,8 @@ case "${LEGACY}" in
                cp ${ISOLINUX_BIN} ${dir}
 
                # syslinux 6.x needs a file called ldlinux.c32
-               if [ -n "${LDLINUX_C32}" -a -s "${LDLINUX_C32}" ]; then
+               LDLINUX_C32=$(dirname ${ISOLINUX_BIN})/ldlinux.c32
+               if [ -s ${LDLINUX_C32} ]; then
                        cp ${LDLINUX_C32} ${dir}
                fi
 
index 5a849a5..28df606 100755 (executable)
@@ -157,7 +157,7 @@ sub process_isa_rom {
 
 # Output Makefile rules for the specified ROM declarations
 sub print_make_rules {
-    my ( $state, $image, $desc, $vendor, $device, $dup ) = @_;
+    my ( $state, my $image, my $desc, my $vendor, my $device, my $dup ) = @_;
     unless ( $state->{'is_header_printed'} ) {
         print "# NIC\t\n";
         print "# NIC\tfamily\t$state->{family}\n";
index 75fba58..1862a38 100644 (file)
@@ -144,7 +144,6 @@ static int read_zinfo_file ( const char *filename,
 
 static int alloc_output_file ( size_t max_len, struct output_file *output ) {
        output->len = 0;
-       output->hdr_len = 0;
        output->max_len = ( max_len );
        output->buf = malloc ( max_len );
        if ( ! output->buf ) {
@@ -242,41 +241,19 @@ static void bcj_filter ( void *data, size_t len ) {
        };
 }
 
-#define CRCPOLY 0xedb88320
-#define CRCSEED 0xffffffff
-
-static uint32_t crc32_le ( uint32_t crc, const void *data, size_t len ) {
-       const uint8_t *src = data;
-       uint32_t mult;
-       unsigned int i;
-
-       while ( len-- ) {
-               crc ^= *(src++);
-               for ( i = 0 ; i < 8 ; i++ ) {
-                       mult = ( ( crc & 1 ) ? CRCPOLY : 0 );
-                       crc = ( ( crc >> 1 ) ^ mult );
-               }
-       }
-       return crc;
-}
-
 static int process_zinfo_pack ( struct input_file *input,
                                struct output_file *output,
                                union zinfo_record *zinfo ) {
        struct zinfo_pack *pack = &zinfo->pack;
        size_t offset = pack->offset;
        size_t len = pack->len;
-       size_t start_len;
        size_t packed_len = 0;
-       size_t remaining;
+       size_t remaining = ( output->max_len - output->len );
        lzma_options_lzma options;
        const lzma_filter filters[] = {
                { .id = LZMA_FILTER_LZMA1, .options = &options },
                { .id = LZMA_VLI_UNKNOWN }
        };
-       void *packed;
-       uint32_t *len32;
-       uint32_t *crc32;
 
        if ( ( offset + len ) > input->len ) {
                fprintf ( stderr, "Input buffer overrun on pack\n" );
@@ -284,9 +261,6 @@ static int process_zinfo_pack ( struct input_file *input,
        }
 
        output->len = align ( output->len, pack->align );
-       start_len = output->len;
-       len32 = ( output->buf + output->len );
-       output->len += sizeof ( *len32 );
        if ( output->len > output->max_len ) {
                fprintf ( stderr, "Output buffer overrun on pack\n" );
                return -1;
@@ -294,34 +268,28 @@ static int process_zinfo_pack ( struct input_file *input,
 
        bcj_filter ( ( input->buf + offset ), len );
 
-       packed = ( output->buf + output->len );
-       remaining = ( output->max_len - output->len );
        lzma_lzma_preset ( &options, LZMA_PRESET );
        options.lc = LZMA_LC;
        options.lp = LZMA_LP;
        options.pb = LZMA_PB;
        if ( lzma_raw_buffer_encode ( filters, NULL, ( input->buf + offset ),
-                                     len, packed, &packed_len,
-                                     remaining ) != LZMA_OK ) {
+                                     len, ( output->buf + output->len ),
+                                     &packed_len, remaining ) != LZMA_OK ) {
                fprintf ( stderr, "Compression failure\n" );
                return -1;
        }
-       output->len += packed_len;
 
-       crc32 = ( output->buf + output->len );
-       output->len += sizeof ( *crc32 );
+       if ( DEBUG ) {
+               fprintf ( stderr, "PACK [%#zx,%#zx) to [%#zx,%#zx)\n",
+                         offset, ( offset + len ), output->len,
+                         ( output->len + packed_len ) );
+       }
+
+       output->len += packed_len;
        if ( output->len > output->max_len ) {
                fprintf ( stderr, "Output buffer overrun on pack\n" );
                return -1;
        }
-       *len32 = ( packed_len + sizeof ( *crc32 ) );
-       *crc32 = crc32_le ( CRCSEED, packed, packed_len );
-
-       if ( DEBUG ) {
-               fprintf ( stderr, "PACK [%#zx,%#zx) to [%#zx,%#zx) crc %#08x\n",
-                         offset, ( offset + len ), start_len, output->len,
-                         *crc32 );
-       }
 
        return 0;
 }
index 33ab51e..2e4df6a 100644 (file)
@@ -97,15 +97,14 @@ init_context(uint8_t *stack, uint32_t stack_size, int num_params)
 /* Switch to another context. */
 struct context *switch_to(struct context *ctx)
 {
-    volatile struct context *save;
-    struct context *ret;
+    struct context *save, *ret;
 
     debug("switching to new context:\n");
     save = __context;
     __context = ctx;
     asm ("pushl %cs; call __switch_context");
     ret = __context;
-    __context = (struct context *)save;
+    __context = save;
     return ret;
 }
 
index e606313..29f6601 100644 (file)
        $(call quiet-command,$(NM) $@.nostrip | sort > $(ODIR)/openbios-qemu.syms,"  GEN   $(TARGET_DIR)$@.syms")
        $(call quiet-command,$(STRIP) $@.nostrip -o $@,"  STRIP $(TARGET_DIR)$@")</rule>
   <object source="qemu/start.S"/>
-  <object source="qemu/switch.S"/>
-  <object source="qemu/context.c"/>
   <object source="timebase.S"/>
   <external-object source="libqemu.a"/>
   <external-object source="libbootstrap.a"/>
diff --git a/roms/openbios/arch/ppc/qemu/context.c b/roms/openbios/arch/ppc/qemu/context.c
deleted file mode 100644 (file)
index 78205a2..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * context switching
- * 2003-10 by SONE Takeshi
- */
-
-#include "config.h"
-#include "kernel/kernel.h"
-#include "context.h"
-#include "libopenbios/sys_info.h"
-
-#define MAIN_STACK_SIZE 16384
-#define IMAGE_STACK_SIZE 4096*2
-
-#define debug printk
-
-#ifdef CONFIG_PPC_64BITSUPPORT
-  #ifdef __powerpc64__
-    #define ULONG_SIZE 8
-    #define STACKFRAME_MINSIZE 48
-    #define STKOFF STACKFRAME_MINSIZE
-    #define SAVE_SPACE 320
-  #else
-    #define ULONG_SIZE 4
-    #define STACKFRAME_MINSIZE 16
-    #define STKOFF 8
-    #define SAVE_SPACE 144
-  #endif
-#endif
-
-static void start_main(void); /* forward decl. */
-void __exit_context(void); /* assembly routine */
-
-unsigned int start_elf(unsigned long entry_point, unsigned long param);
-void entry(void);
-void of_client_callback(void);
-
-/*
- * Main context structure
- * It is placed at the bottom of our stack, and loaded by assembly routine
- * to start us up.
- */
-static struct context main_ctx = {
-    .sp = (unsigned long) &_estack - SAVE_SPACE,
-    .pc = (unsigned long) start_main,
-    .return_addr = (unsigned long) __exit_context,
-};
-
-/* This is used by assembly routine to load/store the context which
- * it is to switch/switched.  */
-struct context * volatile __context = &main_ctx;
-
-/* Stack for loaded ELF image */
-static uint8_t image_stack[IMAGE_STACK_SIZE];
-
-/* Pointer to startup context (physical address) */
-unsigned long __boot_ctx;
-
-/*
- * Main starter
- * This is the C function that runs first.
- */
-static void start_main(void)
-{
-    /* Save startup context, so we can refer to it later.
-     * We have to keep it in physical address since we will relocate. */
-    __boot_ctx = virt_to_phys(__context);
-
-    /* Start the real fun */
-    entry();
-
-    /* Returning from here should jump to __exit_context */
-    __context = boot_ctx;
-}
-
-/* Setup a new context using the given stack.
- */
-struct context *
-init_context(uint8_t *stack, uint32_t stack_size, int num_params)
-{
-    struct context *ctx;
-
-    ctx = (struct context *)
-       (stack + stack_size - (sizeof(*ctx) + num_params*sizeof(unsigned long)));
-    memset(ctx, 0, sizeof(*ctx));
-
-    /* Fill in reasonable default for flat memory model */
-    ctx->sp = virt_to_phys(SP_LOC(ctx));
-    ctx->return_addr = virt_to_phys(__exit_context);
-    
-    return ctx;
-}
-
-/* Switch to another context. */
-struct context *switch_to(struct context *ctx)
-{
-    volatile struct context *save;
-    struct context *ret;
-    unsigned int lr;
-
-    debug("switching to new context:\n");
-    save = __context;
-    __context = ctx;
-
-    asm __volatile__ ("mflr %%r9\n\t"
-                      "stw %%r9, %0\n\t"
-                      "bl __switch_context\n\t"
-                      "lwz %%r9, %0\n\t"
-                      "mtlr %%r9\n\t" : "=m" (lr) : "m" (lr) : "%r9" );
-    
-    ret = __context;
-    __context = (struct context *)save;
-    return ret;
-}
-
-/* Start ELF Boot image */
-unsigned int start_elf(unsigned long entry_point, unsigned long param)
-{
-    struct context *ctx;
-
-    /* According to IEEE 1275, PPC bindings:
-     *
-     *    MSR = FP, ME + (DR|IR)
-     *    r1 = stack (32 K + 32 bytes link area above)
-     *    r5 = client interface handler
-     *    r6 = address of client program arguments (unused)
-     *    r7 = length of client program arguments (unused)
-     *
-     *      Yaboot and Linux use r3 and r4 for initrd address and size
-     */
-    
-    ctx = init_context(image_stack, sizeof image_stack, 1);
-    ctx->pc = entry_point;
-    ctx->regs[REG_R5] = (unsigned long)of_client_callback;
-    ctx->regs[REG_R6] = 0;
-    ctx->regs[REG_R7] = 0;
-    ctx->param[0] = param;
-   
-    ctx = switch_to(ctx);
-    return ctx->regs[REG_R3];
-}
diff --git a/roms/openbios/arch/ppc/qemu/context.h b/roms/openbios/arch/ppc/qemu/context.h
deleted file mode 100644 (file)
index 8135bb4..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef PPC_CONTEXT_H
-#define PPC_CONTEXT_H
-
-struct context {
-#define SP_LOC(ctx) (&(ctx)->sp)
-    unsigned long _sp;
-    unsigned long return_addr;
-    unsigned long sp;
-    unsigned long pc;
-    /* General registers */
-    unsigned long regs[34];
-#define REG_R3 3
-#define REG_R5 8
-#define REG_R6 9
-#define REG_R7 10
-    /* Flags */
-    /* Optional stack contents */
-    unsigned long param[0];
-};
-
-/* Create a new context in the given stack */
-struct context *
-init_context(uint8_t *stack, uint32_t stack_size, int num_param);
-
-/* Switch context */
-struct context *switch_to(struct context *);
-
-/* Holds physical address of boot context */
-extern unsigned long __boot_ctx;
-
-/* This can always be safely used to refer to the boot context */
-#define boot_ctx ((struct context *) phys_to_virt(__boot_ctx))
-
-#endif /* PPC_CONTEXT_H */
index 8f264f4..b76c570 100644 (file)
@@ -35,7 +35,6 @@
 #define NO_QEMU_PROTOS
 #include "arch/common/fw_cfg.h"
 #include "arch/ppc/processor.h"
-#include "context.h"
 
 #define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
 
@@ -596,7 +595,6 @@ id_cpu(void)
 }
 
 static void go(void);
-unsigned int start_elf(unsigned long entry_point, unsigned long param);
 
 static void
 go(void)
@@ -611,7 +609,7 @@ go(void)
     feval("saved-program-state >sps.entry @");
     addr = POP();
 
-    start_elf((unsigned long)addr, 0);
+    call_elf(0, 0, addr);
 }
 
 static void kvm_of_init(void)
index 11ebf4b..8027b39 100644 (file)
@@ -51,11 +51,7 @@ SECTIONS
        *(.bss)
        *(.bss.*)
        *(COMMON)
-       
-       _stack = .;
-       . += CSTACK_SIZE;
-       . = ALIGN(16);
-       _estack = .;
+       _ebss = .;
     }
 
     . = HRESET_ADDR;
index 7b8ced0..6f346a3 100644 (file)
@@ -359,11 +359,9 @@ hash_page_64(unsigned long ea, phys_addr_t phys, ucell mode)
             found = 1;
 
     /* otherwise use a free slot */
-    if (!found) {
-        for (i = 0; !found && i < 8; i++)
-            if (!pp[i].v)
-                found = 1;
-    }
+    for (i = 0; !found && i < 8; i++)
+        if (!pp[i].v)
+            found = 1;
 
     /* out of slots, just evict one */
     if (!found)
@@ -416,11 +414,9 @@ hash_page_32(unsigned long ea, phys_addr_t phys, ucell mode)
             found = 1;
 
     /* otherwise use a free slot */
-    if (!found) {
-        for (i = 0; !found && i < 8; i++)
-            if (!pp[i].v)
-                found = 1;
-    }
+    for (i = 0; !found && i < 8; i++)
+        if (!pp[i].v)
+            found = 1;
 
     /* out of slots, just evict one */
     if (!found)
@@ -482,36 +478,6 @@ isi_exception(void)
     hash_page(nip, phys, mode);
 }
 
-/*
- * Power ISA 2.x has deleted the rfi instruction and rfid shoud be
- * used instead on cpus following this instruction set or later.
- *
- * OpenBIOS 32bits is compiled to use rfi. But, when it runs on a
- * Power ISA 2.x cpu (a 970 for instance), we need to replace the rfi
- * instructions with rfid in the vectors' memory section. Else we
- * won't go any futher than the first exception ...
- */
-#define RFI     0x4c000064
-#define RFID    0x4c000024
-
-extern char __vectors[];
-extern char __vectors_end[];
-
-static void patch_rfi(void)
-{
-    uint32_t* ptr;
-    uint32_t* vec_start = (uint32_t*) 0x100UL;
-    uint32_t* vec_end = (uint32_t*) (__vectors_end - __vectors);
-
-    if (!is_ppc64())
-        return;
-
-    for (ptr = vec_start; ptr != vec_end; ptr++)  {
-        if (*ptr == RFI)
-            *ptr = RFID;
-    }
-    flush_icache_range((char*) vec_start , (char*) vec_end);
-}
 
 /************************************************************************/
 /*     init / cleanup                                                  */
@@ -566,8 +532,6 @@ setup_mmu(unsigned long ramsize)
 
     memcpy((void *)get_rom_base(), (void *)OF_CODE_START, OF_CODE_SIZE);
 
-    patch_rfi();
-
     /* Enable MMU */
 
     mtmsr(mfmsr() | MSR_IR | MSR_DR);
index 33ca1e0..ae2fd53 100644 (file)
@@ -482,15 +482,56 @@ real_entry:
 #endif
 
        bl      BRANCH_LABEL(setup_mmu)
-       bl      BRANCH_LABEL(__switch_context_nosave)
+       bl      BRANCH_LABEL(entry)
 1:     nop
        b       1b
 
+
+       /* According to IEEE 1275, PPC bindings:
+        *
+        *      MSR = FP, ME + (DR|IR)
+        *      r1 = stack (32 K + 32 bytes link area above)
+        *      r5 = client interface handler
+        *      r6 = address of client program arguments (unused)
+        *      r7 = length of client program arguments (unused)
+         *
+         *      Yaboot and Linux use r3 and r4 for initrd address and size
+        */
         .data
-_GLOBAL(saved_stack):
-        DATA_LONG(0)
-        
+saved_stack:
+    DATA_LONG(0)
         .previous
+       /* void call_elf( arg1, arg2, entry ) */
+_GLOBAL(call_elf):
+       mflr    r0
+       PPC_STLU r1, -STACKFRAME_MINSIZE(r1)
+       PPC_STL  r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
+       mtlr    r5
+       LOAD_REG_IMMEDIATE(r8, saved_stack)             // save our stack pointer
+       PPC_STL r1,0(r8)
+       mfsdr1  r1
+       addi    r1, r1, -32768          /* - 32 KiB exception stack */
+       addis   r1, r1, -1                      /* - 64 KiB stack */
+       LOAD_REG_IMMEDIATE(r5, of_client_callback)      // r5 = callback
+       li      r6,0                    // r6 = address of client program arguments (unused)
+       li      r7,0                    // r7 = length of client program arguments (unused)
+       li      r0,MSR_FP | MSR_ME | MSR_DR | MSR_IR
+       MTMSRD(r0)
+       blrl
+
+#ifdef CONFIG_PPC64
+    /* Restore SF bit */
+    LOAD_REG_IMMEDIATE(r0, MSR_SF | MSR_FP | MSR_ME | MSR_DR | MSR_IR)
+    MTMSRD(r0)
+#endif
+       LOAD_REG_IMMEDIATE(r8, saved_stack)             // restore stack pointer
+       mr      r1,r8
+       PPC_LL r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
+       mtlr    r0
+       addi    r1, r1, STACKFRAME_MINSIZE
+       // XXX: should restore r12-r31 etc..
+       // we should not really come here though
+       blr
 
 #ifdef __powerpc64__
 #define STKOFF STACKFRAME_MINSIZE
@@ -499,126 +540,133 @@ _GLOBAL(saved_stack):
 #define STKOFF 8
 #define SAVE_SPACE 144
 #endif
-
 GLOBL(of_client_callback):
+
 #ifdef CONFIG_PPC64
-       PPC_STLU r1, -(STACKFRAME_MINSIZE + 16)(r1)
+    PPC_STLU r1, -(STACKFRAME_MINSIZE + 16)(r1)
 #else
-       PPC_STLU r1, -STACKFRAME_MINSIZE(r1) /* fits within alignment */
+    PPC_STLU r1, -STACKFRAME_MINSIZE(r1) /* fits within alignment */
 #endif
 
        /* save r4 */
-       PPC_STL r4, STKOFF(r1)
-       
+
+    PPC_STL r4, STKOFF(r1)
+
        /* save lr */
+
        mflr    r4
-       PPC_STL r4, PPC_LR_STKOFF(r1)
-       
+    PPC_STL r4, PPC_LR_STKOFF(r1)
+
        /* restore OF stack */
+
        LOAD_REG_IMMEDIATE(r4, saved_stack)
-       PPC_LL  r4, 0(r4)
-       
-       PPC_STLU r4, -SAVE_SPACE(r4)
-       PPC_STL  r1, (STKOFF)(r4)       // save caller stack
+    PPC_LL  r4, 0(r4)
+
+       PPC_STLU r4,-SAVE_SPACE(r4)
+       PPC_STL r1,(STKOFF)(r4)         // save caller stack
        mr      r1,r4
-       
-       PPC_STL  r3,  (STKOFF + 5 * ULONG_SIZE)(r1)
-       PPC_STL  r2,  (STKOFF + 4 * ULONG_SIZE)(r1)
-       PPC_STL  r0,  (STKOFF + 3 * ULONG_SIZE)(r1)
-       
+
+    PPC_STL r2,  (STKOFF +  1 * ULONG_SIZE)(r1)
+    PPC_STL r0,  (STKOFF +  2 * ULONG_SIZE)(r1)
+
        /* save ctr, cr and xer */
+
        mfctr   r2
-       PPC_STL  r2,  (STKOFF + 6 * ULONG_SIZE)(r1)
+    PPC_STL r2,  (STKOFF +  3 * ULONG_SIZE)(r1)
        mfcr    r2
-       PPC_STL  r2,  (STKOFF + 7 * ULONG_SIZE)(r1)
+    PPC_STL r2,  (STKOFF +  4 * ULONG_SIZE)(r1)
        mfxer   r2
-       PPC_STL  r2,  (STKOFF + 8 * ULONG_SIZE)(r1)
-       
+    PPC_STL r2,  (STKOFF +  5 * ULONG_SIZE)(r1)
+
        /* save r5 - r31 */
-       PPC_STL  r5,  (STKOFF + 10 * ULONG_SIZE)(r1)
-       PPC_STL  r6,  (STKOFF + 11 * ULONG_SIZE)(r1)
-       PPC_STL  r7,  (STKOFF + 12 * ULONG_SIZE)(r1)
-       PPC_STL  r8,  (STKOFF + 13 * ULONG_SIZE)(r1)
-       PPC_STL  r9,  (STKOFF + 14 * ULONG_SIZE)(r1)
-       PPC_STL  r10,  (STKOFF + 15 * ULONG_SIZE)(r1)
-       PPC_STL  r11,  (STKOFF + 16 * ULONG_SIZE)(r1)
-       PPC_STL  r12,  (STKOFF + 17 * ULONG_SIZE)(r1)
-       PPC_STL  r13,  (STKOFF + 18 * ULONG_SIZE)(r1)
-       PPC_STL  r14,  (STKOFF + 19 * ULONG_SIZE)(r1)
-       PPC_STL  r15,  (STKOFF + 20 * ULONG_SIZE)(r1)
-       PPC_STL  r16,  (STKOFF + 21 * ULONG_SIZE)(r1)
-       PPC_STL  r17,  (STKOFF + 22 * ULONG_SIZE)(r1)
-       PPC_STL  r18,  (STKOFF + 23 * ULONG_SIZE)(r1)
-       PPC_STL  r19,  (STKOFF + 24 * ULONG_SIZE)(r1)
-       PPC_STL  r20,  (STKOFF + 25 * ULONG_SIZE)(r1)
-       PPC_STL  r21,  (STKOFF + 26 * ULONG_SIZE)(r1)
-       PPC_STL  r22,  (STKOFF + 27 * ULONG_SIZE)(r1)
-       PPC_STL  r23,  (STKOFF + 28 * ULONG_SIZE)(r1)
-       PPC_STL  r24,  (STKOFF + 29 * ULONG_SIZE)(r1)
-       PPC_STL  r25,  (STKOFF + 30 * ULONG_SIZE)(r1)
-       PPC_STL  r26,  (STKOFF + 31 * ULONG_SIZE)(r1)
-       PPC_STL  r27,  (STKOFF + 32 * ULONG_SIZE)(r1)
-       PPC_STL  r28,  (STKOFF + 33 * ULONG_SIZE)(r1)
-       PPC_STL  r29,  (STKOFF + 34 * ULONG_SIZE)(r1)
-       PPC_STL  r30,  (STKOFF + 35 * ULONG_SIZE)(r1)
-       PPC_STL  r31,  (STKOFF + 36 * ULONG_SIZE)(r1)
-       
+
+    PPC_STL r5,  (STKOFF +  6 * ULONG_SIZE)(r1)
+    PPC_STL r6,  (STKOFF +  7 * ULONG_SIZE)(r1)
+    PPC_STL r7,  (STKOFF +  8 * ULONG_SIZE)(r1)
+    PPC_STL r8,  (STKOFF +  9 * ULONG_SIZE)(r1)
+    PPC_STL r9,  (STKOFF + 10 * ULONG_SIZE)(r1)
+    PPC_STL r10, (STKOFF + 11 * ULONG_SIZE)(r1)
+    PPC_STL r11, (STKOFF + 12 * ULONG_SIZE)(r1)
+    PPC_STL r12, (STKOFF + 13 * ULONG_SIZE)(r1)
+    PPC_STL r13, (STKOFF + 14 * ULONG_SIZE)(r1)
+    PPC_STL r14, (STKOFF + 15 * ULONG_SIZE)(r1)
+    PPC_STL r15, (STKOFF + 16 * ULONG_SIZE)(r1)
+    PPC_STL r16, (STKOFF + 17 * ULONG_SIZE)(r1)
+    PPC_STL r17, (STKOFF + 18 * ULONG_SIZE)(r1)
+    PPC_STL r18, (STKOFF + 19 * ULONG_SIZE)(r1)
+    PPC_STL r19, (STKOFF + 20 * ULONG_SIZE)(r1)
+    PPC_STL r20, (STKOFF + 21 * ULONG_SIZE)(r1)
+    PPC_STL r21, (STKOFF + 22 * ULONG_SIZE)(r1)
+    PPC_STL r22, (STKOFF + 23 * ULONG_SIZE)(r1)
+    PPC_STL r23, (STKOFF + 24 * ULONG_SIZE)(r1)
+    PPC_STL r24, (STKOFF + 25 * ULONG_SIZE)(r1)
+    PPC_STL r25, (STKOFF + 26 * ULONG_SIZE)(r1)
+    PPC_STL r26, (STKOFF + 27 * ULONG_SIZE)(r1)
+    PPC_STL r27, (STKOFF + 28 * ULONG_SIZE)(r1)
+    PPC_STL r28, (STKOFF + 29 * ULONG_SIZE)(r1)
+    PPC_STL r29, (STKOFF + 30 * ULONG_SIZE)(r1)
+    PPC_STL r30, (STKOFF + 31 * ULONG_SIZE)(r1)
+    PPC_STL r31, (STKOFF + 32 * ULONG_SIZE)(r1)
+
 #ifdef CONFIG_PPC64
-       LOAD_REG_IMMEDIATE(r2, of_client_interface)
-       ld  r2, 8(r2)
+    LOAD_REG_IMMEDIATE(r2, of_client_interface)
+    ld  r2, 8(r2)
 #endif
-       
-       bl      BRANCH_LABEL(of_client_interface)
-       
+    bl BRANCH_LABEL(of_client_interface)
+
        /* restore r5 - r31 */
-       PPC_LL  r5,  (STKOFF + 10 * ULONG_SIZE)(r1)
-       PPC_LL  r6,  (STKOFF + 11 * ULONG_SIZE)(r1)
-       PPC_LL  r7,  (STKOFF + 12 * ULONG_SIZE)(r1)
-       PPC_LL  r8,  (STKOFF + 13 * ULONG_SIZE)(r1)
-       PPC_LL  r9,  (STKOFF + 14 * ULONG_SIZE)(r1)
-       PPC_LL  r10,  (STKOFF + 15 * ULONG_SIZE)(r1)
-       PPC_LL  r11,  (STKOFF + 16 * ULONG_SIZE)(r1)
-       PPC_LL  r12,  (STKOFF + 17 * ULONG_SIZE)(r1)
-       PPC_LL  r13,  (STKOFF + 18 * ULONG_SIZE)(r1)
-       PPC_LL  r14,  (STKOFF + 19 * ULONG_SIZE)(r1)
-       PPC_LL  r15,  (STKOFF + 20 * ULONG_SIZE)(r1)
-       PPC_LL  r16,  (STKOFF + 21 * ULONG_SIZE)(r1)
-       PPC_LL  r17,  (STKOFF + 22 * ULONG_SIZE)(r1)
-       PPC_LL  r18,  (STKOFF + 23 * ULONG_SIZE)(r1)
-       PPC_LL  r19,  (STKOFF + 24 * ULONG_SIZE)(r1)
-       PPC_LL  r20,  (STKOFF + 25 * ULONG_SIZE)(r1)
-       PPC_LL  r21,  (STKOFF + 26 * ULONG_SIZE)(r1)
-       PPC_LL  r22,  (STKOFF + 27 * ULONG_SIZE)(r1)
-       PPC_LL  r23,  (STKOFF + 28 * ULONG_SIZE)(r1)
-       PPC_LL  r24,  (STKOFF + 29 * ULONG_SIZE)(r1)
-       PPC_LL  r25,  (STKOFF + 30 * ULONG_SIZE)(r1)
-       PPC_LL  r26,  (STKOFF + 31 * ULONG_SIZE)(r1)
-       PPC_LL  r27,  (STKOFF + 32 * ULONG_SIZE)(r1)
-       PPC_LL  r28,  (STKOFF + 33 * ULONG_SIZE)(r1)
-       PPC_LL  r29,  (STKOFF + 34 * ULONG_SIZE)(r1)
-       PPC_LL  r30,  (STKOFF + 35 * ULONG_SIZE)(r1)
-       PPC_LL  r31,  (STKOFF + 36 * ULONG_SIZE)(r1)
-       
+
+    PPC_LL  r5,  (STKOFF +  6 * ULONG_SIZE)(r1)
+    PPC_LL  r6,  (STKOFF +  7 * ULONG_SIZE)(r1)
+    PPC_LL  r7,  (STKOFF +  8 * ULONG_SIZE)(r1)
+    PPC_LL  r8,  (STKOFF +  9 * ULONG_SIZE)(r1)
+    PPC_LL  r9,  (STKOFF + 10 * ULONG_SIZE)(r1)
+    PPC_LL  r10, (STKOFF + 11 * ULONG_SIZE)(r1)
+    PPC_LL  r11, (STKOFF + 12 * ULONG_SIZE)(r1)
+    PPC_LL  r12, (STKOFF + 13 * ULONG_SIZE)(r1)
+    PPC_LL  r13, (STKOFF + 14 * ULONG_SIZE)(r1)
+    PPC_LL  r14, (STKOFF + 15 * ULONG_SIZE)(r1)
+    PPC_LL  r15, (STKOFF + 16 * ULONG_SIZE)(r1)
+    PPC_LL  r16, (STKOFF + 17 * ULONG_SIZE)(r1)
+    PPC_LL  r17, (STKOFF + 18 * ULONG_SIZE)(r1)
+    PPC_LL  r18, (STKOFF + 19 * ULONG_SIZE)(r1)
+    PPC_LL  r19, (STKOFF + 20 * ULONG_SIZE)(r1)
+    PPC_LL  r20, (STKOFF + 21 * ULONG_SIZE)(r1)
+    PPC_LL  r21, (STKOFF + 22 * ULONG_SIZE)(r1)
+    PPC_LL  r22, (STKOFF + 23 * ULONG_SIZE)(r1)
+    PPC_LL  r23, (STKOFF + 24 * ULONG_SIZE)(r1)
+    PPC_LL  r24, (STKOFF + 25 * ULONG_SIZE)(r1)
+    PPC_LL  r25, (STKOFF + 26 * ULONG_SIZE)(r1)
+    PPC_LL  r26, (STKOFF + 27 * ULONG_SIZE)(r1)
+    PPC_LL  r27, (STKOFF + 28 * ULONG_SIZE)(r1)
+    PPC_LL  r28, (STKOFF + 29 * ULONG_SIZE)(r1)
+    PPC_LL  r29, (STKOFF + 30 * ULONG_SIZE)(r1)
+    PPC_LL  r30, (STKOFF + 31 * ULONG_SIZE)(r1)
+    PPC_LL  r31, (STKOFF + 32 * ULONG_SIZE)(r1)
+
        /* restore ctr, cr and xer */
-       PPC_LL r2,  (STKOFF + 6 * ULONG_SIZE)(r1)
+
+    PPC_LL  r2,  (STKOFF +  3 * ULONG_SIZE)(r1)
        mtctr   r2
-       PPC_LL r2,  (STKOFF + 7 * ULONG_SIZE)(r1)
+    PPC_LL  r2,  (STKOFF +  4 * ULONG_SIZE)(r1)
        mtcr    r2
-       PPC_LL r2,  (STKOFF + 8 * ULONG_SIZE)(r1)
+    PPC_LL  r2,  (STKOFF +  5 * ULONG_SIZE)(r1)
        mtxer   r2
-       
+
        /* restore r0 and r2 */
-       PPC_LL r2,  (STKOFF + 4 * ULONG_SIZE)(r1)
-       PPC_LL r0,  (STKOFF + 3 * ULONG_SIZE)(r1)
-       
+
+    PPC_LL  r2,  (STKOFF +  1 * ULONG_SIZE)(r1)
+    PPC_LL  r0,  (STKOFF +  2 * ULONG_SIZE)(r1)
+
        /* restore caller stack */
-       PPC_LL  r1,  (STKOFF)(r1)
-       
-       PPC_LL  r4, PPC_LR_STKOFF(r1)
+
+    PPC_LL  r1,  (STKOFF)(r1)
+
+    PPC_LL  r4, PPC_LR_STKOFF(r1)
        mtlr    r4
-       PPC_LL  r4, STKOFF(r1)
-       PPC_LL  r1, 0(r1)
-       
+    PPC_LL  r4, STKOFF(r1)
+    PPC_LL  r1, 0(r1)
+
        blr
 
        /* rtas glue (must be reloctable) */
diff --git a/roms/openbios/arch/ppc/qemu/switch.S b/roms/openbios/arch/ppc/qemu/switch.S
deleted file mode 100644 (file)
index c3d9d70..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-#include "autoconf.h"
-#include "asm/asmdefs.h"
-#include "asm/processor.h"
-
-
-#ifdef CONFIG_PPC_64BITSUPPORT
-  #ifdef __powerpc64__
-    #define ULONG_SIZE 8
-    #define STACKFRAME_MINSIZE 48
-    #define STKOFF STACKFRAME_MINSIZE
-    #define SAVE_SPACE 320
-  #else
-    #define ULONG_SIZE 4
-    #define STACKFRAME_MINSIZE 16
-    #define STKOFF 8
-    #define SAVE_SPACE 144
-  #endif
-#endif
-
-       /* According to IEEE 1275, PPC bindings:
-        *
-        *      MSR = FP, ME + (DR|IR)
-        *      r1 = stack (32 K + 32 bytes link area above)
-        *      r5 = client interface handler
-        *      r6 = address of client program arguments (unused)
-        *      r7 = length of client program arguments (unused)
-         *
-         *      Yaboot and Linux use r3 and r4 for initrd address and size
-        */
-
-       /* void call_elf( arg1, arg2, entry ) */
-_GLOBAL(call_elf):
-       mflr    r0
-       PPC_STLU r1, -STACKFRAME_MINSIZE(r1)
-       PPC_STL  r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
-       mtlr    r5
-       LOAD_REG_IMMEDIATE(r8, saved_stack)             // save our stack pointer
-       PPC_STL r1,0(r8)
-       mfsdr1  r1
-       addi    r1, r1, -32768          /* - 32 KiB exception stack */
-       addis   r1, r1, -1                      /* - 64 KiB stack */
-       LOAD_REG_IMMEDIATE(r5, of_client_callback)      // r5 = callback
-       li      r6,0                    // r6 = address of client program arguments (unused)
-       li      r7,0                    // r7 = length of client program arguments (unused)
-       li      r0,MSR_FP | MSR_ME | MSR_DR | MSR_IR
-       MTMSRD(r0)
-       blrl
-
-#ifdef CONFIG_PPC64
-    /* Restore SF bit */
-    LOAD_REG_IMMEDIATE(r0, MSR_SF | MSR_FP | MSR_ME | MSR_DR | MSR_IR)
-    MTMSRD(r0)
-#endif
-       LOAD_REG_IMMEDIATE(r8, saved_stack)             // restore stack pointer
-       mr      r1,r8
-       PPC_LL r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
-       mtlr    r0
-       addi    r1, r1, STACKFRAME_MINSIZE
-       // XXX: should restore r12-r31 etc..
-       // we should not really come here though
-       blrl
-
-/*
- * Switch execution context
- * This saves registers in the stack, then
- * switches the stack, and restores everything from the new stack.
- * This function takes no argument. New stack pointer is
- * taken from global variable __context, and old stack pointer
- * is also saved to __context. This way we can just jump to
- * this routine to get back to the original context.
- */
-
-_GLOBAL(__switch_context):
-       /* save internal stack pointer */
-#ifdef CONFIG_PPC64
-       PPC_STL  r1, -(SAVE_SPACE + 16) + STKOFF(r1)
-#else
-       PPC_STL  r1, -SAVE_SPACE + STKOFF(r1)
-#endif
-       
-#ifdef CONFIG_PPC64
-       PPC_STLU r1, -(SAVE_SPACE + 16)(r1)
-#else
-       PPC_STLU r1, -SAVE_SPACE(r1) /* fits within alignment */
-#endif
-       
-       /* r4, r5 */
-       PPC_STL r4, (STKOFF + 9 * ULONG_SIZE)(r1)
-       PPC_STL r5, (STKOFF + 10 * ULONG_SIZE)(r1)
-       
-       /* link register */
-       mflr    r4
-       PPC_STL  r4, PPC_LR_STKOFF(r1)
-       PPC_STL  r4,  (STKOFF + ULONG_SIZE)(r1)
-       
-       PPC_STL  r3,  (STKOFF + 5 * ULONG_SIZE)(r1)
-       PPC_STL  r2,  (STKOFF + 4 * ULONG_SIZE)(r1)
-       PPC_STL  r0,  (STKOFF + 3 * ULONG_SIZE)(r1)
-       
-       /* ctr, cr and xer */
-       mfctr   r4
-       PPC_STL  r4,  (STKOFF + 6 * ULONG_SIZE)(r1)
-       mfcr    r4
-       PPC_STL  r4,  (STKOFF + 7 * ULONG_SIZE)(r1)
-       mfxer   r4
-       PPC_STL  r4,  (STKOFF + 8 * ULONG_SIZE)(r1)
-       
-       /* r6-r31 */
-       PPC_STL  r6,  (STKOFF + 11 * ULONG_SIZE)(r1)
-       PPC_STL  r7,  (STKOFF + 12 * ULONG_SIZE)(r1)
-       PPC_STL  r8,  (STKOFF + 13 * ULONG_SIZE)(r1)
-       PPC_STL  r9,  (STKOFF + 14 * ULONG_SIZE)(r1)
-       PPC_STL  r10,  (STKOFF + 15 * ULONG_SIZE)(r1)
-       PPC_STL  r11,  (STKOFF + 16 * ULONG_SIZE)(r1)
-       PPC_STL  r12,  (STKOFF + 17 * ULONG_SIZE)(r1)
-       PPC_STL  r13,  (STKOFF + 18 * ULONG_SIZE)(r1)
-       PPC_STL  r14,  (STKOFF + 19 * ULONG_SIZE)(r1)
-       PPC_STL  r15,  (STKOFF + 20 * ULONG_SIZE)(r1)
-       PPC_STL  r16,  (STKOFF + 21 * ULONG_SIZE)(r1)
-       PPC_STL  r17,  (STKOFF + 22 * ULONG_SIZE)(r1)
-       PPC_STL  r18,  (STKOFF + 23 * ULONG_SIZE)(r1)
-       PPC_STL  r19,  (STKOFF + 24 * ULONG_SIZE)(r1)
-       PPC_STL  r20,  (STKOFF + 25 * ULONG_SIZE)(r1)
-       PPC_STL  r21,  (STKOFF + 26 * ULONG_SIZE)(r1)
-       PPC_STL  r22,  (STKOFF + 27 * ULONG_SIZE)(r1)
-       PPC_STL  r23,  (STKOFF + 28 * ULONG_SIZE)(r1)
-       PPC_STL  r24,  (STKOFF + 29 * ULONG_SIZE)(r1)
-       PPC_STL  r25,  (STKOFF + 30 * ULONG_SIZE)(r1)
-       PPC_STL  r26,  (STKOFF + 31 * ULONG_SIZE)(r1)
-       PPC_STL  r27,  (STKOFF + 32 * ULONG_SIZE)(r1)
-       PPC_STL  r28,  (STKOFF + 33 * ULONG_SIZE)(r1)
-       PPC_STL  r29,  (STKOFF + 34 * ULONG_SIZE)(r1)
-       PPC_STL  r30,  (STKOFF + 35 * ULONG_SIZE)(r1)
-       PPC_STL  r31,  (STKOFF + 36 * ULONG_SIZE)(r1)
-       
-       /* swap context */
-       LOAD_REG_IMMEDIATE(r4, __context)
-       PPC_LL   r5, 0(r4)
-       PPC_STL  r1, 0(r4)
-       mr      r4, r5
-       
-       b       __set_context
-       
-_GLOBAL(__switch_context_nosave):
-       LOAD_REG_IMMEDIATE(r4, __context)
-       PPC_LL  r4, 0(r4)
-       
-__set_context:
-       /* link register */
-       PPC_LL  r5, (STKOFF + ULONG_SIZE)(r4)
-       mtlr    r5
-       
-       PPC_LL r3,  (STKOFF + 5 * ULONG_SIZE)(r4)
-       PPC_LL r2,  (STKOFF + 4 * ULONG_SIZE)(r4)
-       PPC_LL r0,  (STKOFF + 3 * ULONG_SIZE)(r4)
-       
-       /* ctr, cr and xer */
-       PPC_LL r5,  (STKOFF + 6 * ULONG_SIZE)(r4)
-       mtctr   r5
-       PPC_LL r5,  (STKOFF + 7 * ULONG_SIZE)(r4)
-       mtcr    r5
-       PPC_LL r5,  (STKOFF + 8 * ULONG_SIZE)(r4)
-       mtxer   r5
-       
-       /* r5-r31 */
-       PPC_LL  r5,  (STKOFF + 10 * ULONG_SIZE)(r4)
-       PPC_LL  r6,  (STKOFF + 11 * ULONG_SIZE)(r4)
-       PPC_LL  r7,  (STKOFF + 12 * ULONG_SIZE)(r4)
-       PPC_LL  r8,  (STKOFF + 13 * ULONG_SIZE)(r4)
-       PPC_LL  r9,  (STKOFF + 14 * ULONG_SIZE)(r4)
-       PPC_LL  r10,  (STKOFF + 15 * ULONG_SIZE)(r4)
-       PPC_LL  r11,  (STKOFF + 16 * ULONG_SIZE)(r4)
-       PPC_LL  r12,  (STKOFF + 17 * ULONG_SIZE)(r4)
-       PPC_LL  r13,  (STKOFF + 18 * ULONG_SIZE)(r4)
-       PPC_LL  r14,  (STKOFF + 19 * ULONG_SIZE)(r4)
-       PPC_LL  r15,  (STKOFF + 20 * ULONG_SIZE)(r4)
-       PPC_LL  r16,  (STKOFF + 21 * ULONG_SIZE)(r4)
-       PPC_LL  r17,  (STKOFF + 22 * ULONG_SIZE)(r4)
-       PPC_LL  r18,  (STKOFF + 23 * ULONG_SIZE)(r4)
-       PPC_LL  r19,  (STKOFF + 24 * ULONG_SIZE)(r4)
-       PPC_LL  r20,  (STKOFF + 25 * ULONG_SIZE)(r4)
-       PPC_LL  r21,  (STKOFF + 26 * ULONG_SIZE)(r4)
-       PPC_LL  r22,  (STKOFF + 27 * ULONG_SIZE)(r4)
-       PPC_LL  r23,  (STKOFF + 28 * ULONG_SIZE)(r4)
-       PPC_LL  r24,  (STKOFF + 29 * ULONG_SIZE)(r4)
-       PPC_LL  r25,  (STKOFF + 30 * ULONG_SIZE)(r4)
-       PPC_LL  r26,  (STKOFF + 31 * ULONG_SIZE)(r4)
-       PPC_LL  r27,  (STKOFF + 32 * ULONG_SIZE)(r4)
-       PPC_LL  r28,  (STKOFF + 33 * ULONG_SIZE)(r4)
-       PPC_LL  r29,  (STKOFF + 34 * ULONG_SIZE)(r4)
-       PPC_LL  r30,  (STKOFF + 35 * ULONG_SIZE)(r4)
-       PPC_LL  r31,  (STKOFF + 36 * ULONG_SIZE)(r4)
-       
-       /* r4, r1 */
-       PPC_LL  r1,  STKOFF(r4)
-       PPC_LL  r4,  (STKOFF + 8 * ULONG_SIZE)(r4)
-       
-       LOAD_REG_IMMEDIATE(r0, MSR_FP | MSR_ME | MSR_DR | MSR_IR)
-       MTMSRD(r0)
-       
-       blrl
-       
-#ifdef CONFIG_PPC64
-       /* Restore SF bit */
-       LOAD_REG_IMMEDIATE(r0, MSR_SF | MSR_FP | MSR_ME | MSR_DR | MSR_IR)
-       MTMSRD(r0)
-#endif
-       
-_GLOBAL(__exit_context):
-       /* Get back to the original context */
-       b       __switch_context
index 10ac9b9..6f4ee45 100644 (file)
@@ -897,7 +897,7 @@ arch_init( void )
                push_str("floppy");
                break;
        case 'c':
-               push_str("disk:a disk");
+               push_str("disk");
                break;
        default:
        case 'd':
index 823116f..98932ee 100644 (file)
@@ -88,8 +88,7 @@ init_context(uint8_t *stack, uint64_t stack_size, int num_params)
 /* Switch to another context. */
 struct context *switch_to(struct context *ctx)
 {
-    volatile struct context *save;
-    struct context *ret;
+    struct context *save, *ret;
 
     debug("switching to new context: entry point %#llx stack 0x%016llx\n", ctx->pc, ctx->regs[REG_SP]);
     save = __context;
@@ -97,7 +96,7 @@ struct context *switch_to(struct context *ctx)
     //asm ("pushl %cs; call __switch_context");
     asm ("call __switch_context_nosave; nop");
     ret = __context;
-    __context = (struct context *)save;
+    __context = save;
     return ret;
 }
 
index f02000f..5187058 100644 (file)
@@ -163,11 +163,9 @@ defer outer-interpreter
 : evaluate ( str len -- ?? )
   2dup + -rot
   over + over do 
-    i c@ dup 0a = swap 0d = or if
+    i c@ 0a = if 
       i over - 
-      rot >r
       (evaluate)
-      r>
       i 1+ 
     then 
   loop 
index f1c9a45..34eee40 100644 (file)
@@ -8,7 +8,6 @@
   -->
  
  <dictionary name="openbios" target="forth">
-  <object source="rstack.fs"/>
   <object source="vocabulary.fs"/>
   <object source="string.fs"/>
   <object source="preprocessor.fs"/>
diff --git a/roms/openbios/forth/lib/rstack.fs b/roms/openbios/forth/lib/rstack.fs
deleted file mode 100644 (file)
index c095a9e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-\ tag: pseudo r-stack implementation for openbios
-\ 
-\ Copyright (C) 2016 Mark Cave-Ayland
-\ 
-\ See the file "COPYING" for further information about
-\ the copyright and warranty status of this work.
-\ 
-
-\
-\ Pseudo r-stack implementation for interpret mode
-\
-
-create prstack h# 20 cells allot
-variable #prstack 0 #prstack !
-
-: prstack-push  prstack #prstack @ cells + ! 1 #prstack +! ;
-: prstack-pop   -1 #prstack +! prstack #prstack @ cells + @ ;
-
-: >r state @ if ['] >r , exit then r> swap prstack-push >r ; immediate
-: r> state @ if ['] r> , exit then r> prstack-pop swap >r ; immediate
-: r@ state @ if ['] r@ , exit then r> prstack-pop dup prstack-push swap >r ; immediate
index 39c60d7..3449c5b 100644 (file)
@@ -6,7 +6,7 @@
 #define NO_QEMU_PROTOS
 #include "arch/common/fw_cfg.h"
 
-extern char _start, _end, _estack;
+extern char _start, _end;
 extern unsigned long virt_offset;
 
 #define phys_to_virt(phys) ((void *) ((unsigned long) (phys) - virt_offset))
index 9043250..89c0c6a 100644 (file)
@@ -1 +1 @@
-rel-1.9.3-0-ge2fc41e
+rel-1.9.1-0-gb3ef39f
index 6616721..b976fb0 100755 (executable)
@@ -34,22 +34,18 @@ COMMONTRAILER = """
 # Determine section locations
 ######################################################################
 
-# Align 'pos' up to 'alignbytes' offset
+# Align 'pos' to 'alignbytes' offset
 def alignpos(pos, alignbytes):
     mask = alignbytes - 1
     return (pos + mask) & ~mask
 
-# Align 'pos' down to 'alignbytes' offset
-def aligndown(pos, alignbytes):
-    mask = alignbytes - 1
-    return pos & ~mask
-
 # Determine the final addresses for a list of sections that end at an
 # address.
 def setSectionsStart(sections, endaddr, minalign=1, segoffset=0):
     totspace = 0
     for section in sections:
-        minalign = max(minalign, section.align)
+        if section.align > minalign:
+            minalign = section.align
         totspace = alignpos(totspace, section.align) + section.size
     startaddr = int((endaddr - totspace) / minalign) * minalign
     curaddr = startaddr
@@ -273,7 +269,7 @@ def doLayout(sections, config, genreloc):
         final_sec32low_end = BUILD_LOWRAM_END
         zonelow_base = final_sec32low_end - 64*1024
     relocdelta = final_sec32low_end - sec32low_end
-    li.sec32low_start, sec32low_align = setSectionsStart(
+    li.sec32low_start, li.sec32low_align = setSectionsStart(
         sections32low, sec32low_end, 16
         , segoffset=zonelow_base - relocdelta)
     li.sec32low_end = sec32low_end
@@ -409,8 +405,6 @@ def writeLinkerScripts(li, out16, out32seg, out32flat):
     if li.config.get('CONFIG_MULTIBOOT'):
         multiboot_header = "LONG(0x1BADB002) LONG(0) LONG(-0x1BADB002)"
         sec32all_start -= 3 * 4
-    sec32all_align = max([section.align for section in li.sections])
-    sec32all_start = aligndown(sec32all_start, sec32all_align)
     out += outXRefs(filesections32flat, exportsyms=[li.entrysym]) + """
     _reloc_min_align = 0x%x ;
     zonefseg_start = 0x%x ;
index e8e419e..3fae13a 100644 (file)
@@ -130,15 +130,6 @@ qemu_preinit(void)
     dprintf(1, "RamSize: 0x%08x [cmos]\n", RamSize);
 }
 
-#define MSR_IA32_FEATURE_CONTROL 0x0000003a
-
-static void msr_feature_control_setup(void)
-{
-    u64 feature_control_bits = romfile_loadint("etc/msr_feature_control", 0);
-    if (feature_control_bits)
-        wrmsr_smp(MSR_IA32_FEATURE_CONTROL, feature_control_bits);
-}
-
 void
 qemu_platform_setup(void)
 {
@@ -157,9 +148,8 @@ qemu_platform_setup(void)
     smm_device_setup();
     smm_setup();
 
-    // Initialize mtrr, msr_feature_control and smp
+    // Initialize mtrr and smp
     mtrr_setup();
-    msr_feature_control_setup();
     smp_setup();
 
     // Create bios tables
index 66e9f5a..c31c2fa 100644 (file)
@@ -149,22 +149,6 @@ static void piix_isa_bridge_setup(struct pci_device *pci, void *arg)
     dprintf(1, "PIIX3/PIIX4 init: elcr=%02x %02x\n", elcr[0], elcr[1]);
 }
 
-static void mch_isa_lpc_setup(u16 bdf)
-{
-    /* pm io base */
-    pci_config_writel(bdf, ICH9_LPC_PMBASE,
-                      acpi_pm_base | ICH9_LPC_PMBASE_RTE);
-
-    /* acpi enable, SCI: IRQ9 000b = irq9*/
-    pci_config_writeb(bdf, ICH9_LPC_ACPI_CTRL, ICH9_LPC_ACPI_CTRL_ACPI_EN);
-
-    /* set root complex register block BAR */
-    pci_config_writel(bdf, ICH9_LPC_RCBA,
-                      ICH9_LPC_RCBA_ADDR | ICH9_LPC_RCBA_EN);
-}
-
-static int ICH9LpcBDF = -1;
-
 /* ICH9 LPC PCI to ISA bridge */
 /* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */
 static void mch_isa_bridge_setup(struct pci_device *dev, void *arg)
@@ -192,10 +176,16 @@ static void mch_isa_bridge_setup(struct pci_device *dev, void *arg)
     outb(elcr[1], ICH9_LPC_PORT_ELCR2);
     dprintf(1, "Q35 LPC init: elcr=%02x %02x\n", elcr[0], elcr[1]);
 
-    ICH9LpcBDF = bdf;
+    /* pm io base */
+    pci_config_writel(bdf, ICH9_LPC_PMBASE,
+                      acpi_pm_base | ICH9_LPC_PMBASE_RTE);
 
-    mch_isa_lpc_setup(bdf);
+    /* acpi enable, SCI: IRQ9 000b = irq9*/
+    pci_config_writeb(bdf, ICH9_LPC_ACPI_CTRL, ICH9_LPC_ACPI_CTRL_ACPI_EN);
 
+    /* set root complex register block BAR */
+    pci_config_writel(bdf, ICH9_LPC_RCBA,
+                      ICH9_LPC_RCBA_ADDR | ICH9_LPC_RCBA_EN);
     e820_add(ICH9_LPC_RCBA_ADDR, 16*1024, E820_RESERVED);
 
     acpi_pm1a_cnt = acpi_pm_base + 0x04;
@@ -254,8 +244,11 @@ static void piix4_pm_setup(struct pci_device *pci, void *arg)
     pmtimer_setup(acpi_pm_base + 0x08);
 }
 
-static void ich9_smbus_enable(u16 bdf)
+/* ICH9 SMBUS */
+/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_SMBUS */
+static void ich9_smbus_setup(struct pci_device *dev, void *arg)
 {
+    u16 bdf = dev->bdf;
     /* map smbus into io space */
     pci_config_writel(bdf, ICH9_SMB_SMB_BASE,
                       (acpi_pm_base + 0x100) | PCI_BASE_ADDRESS_SPACE_IO);
@@ -264,61 +257,6 @@ static void ich9_smbus_enable(u16 bdf)
     pci_config_writeb(bdf, ICH9_SMB_HOSTC, ICH9_SMB_HOSTC_HST_EN);
 }
 
-static int ICH9SmbusBDF = -1;
-
-/* ICH9 SMBUS */
-/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_SMBUS */
-static void ich9_smbus_setup(struct pci_device *dev, void *arg)
-{
-    ICH9SmbusBDF = dev->bdf;
-
-    ich9_smbus_enable(dev->bdf);
-}
-
-static void intel_igd_setup(struct pci_device *dev, void *arg)
-{
-    struct romfile_s *opregion = romfile_find("etc/igd-opregion");
-    u64 bdsm_size = le64_to_cpu(romfile_loadint("etc/igd-bdsm-size", 0));
-    void *addr;
-    u16 bdf = dev->bdf;
-
-    /* Apply OpRegion to any Intel VGA device, more than one is undefined */
-    if (opregion && opregion->size) {
-        addr = memalign_high(PAGE_SIZE, opregion->size);
-        if (!addr) {
-            warn_noalloc();
-            return;
-        }
-
-        if (opregion->copy(opregion, addr, opregion->size) < 0) {
-            free(addr);
-            return;
-        }
-
-        pci_config_writel(bdf, 0xFC, cpu_to_le32((u32)addr));
-
-        dprintf(1, "Intel IGD OpRegion enabled at 0x%08x, size %dKB, dev "
-                "%02x:%02x.%x\n", (u32)addr, opregion->size >> 10,
-                pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf));
-    }
-
-    /* Apply BDSM only to Intel VGA at 00:02.0 */
-    if (bdsm_size && (bdf == pci_to_bdf(0, 2, 0))) {
-        addr = memalign_tmphigh(1024 * 1024, bdsm_size);
-        if (!addr) {
-            warn_noalloc();
-            return;
-        }
-
-        e820_add((u32)addr, bdsm_size, E820_RESERVED);
-
-        pci_config_writel(bdf, 0x5C, cpu_to_le32((u32)addr));
-
-        dprintf(1, "Intel IGD BDSM enabled at 0x%08x, size %lldMB, dev "
-                "00:02.0\n", (u32)addr, bdsm_size >> 20);
-    }
-}
-
 static const struct pci_device_id pci_device_tbl[] = {
     /* PIIX3/PIIX4 PCI to ISA bridge */
     PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0,
@@ -352,16 +290,9 @@ static const struct pci_device_id pci_device_tbl[] = {
     PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0017, 0xff00, apple_macio_setup),
     PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0022, 0xff00, apple_macio_setup),
 
-    /* Intel IGD OpRegion setup */
-    PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA,
-                     intel_igd_setup),
-
     PCI_DEVICE_END,
 };
 
-static int MCHMmcfgBDF = -1;
-static void mch_mmconfig_setup(u16 bdf);
-
 void pci_resume(void)
 {
     if (!CONFIG_QEMU) {
@@ -371,18 +302,6 @@ void pci_resume(void)
     if (PiixPmBDF >= 0) {
         piix4_pm_config_setup(PiixPmBDF);
     }
-
-    if (ICH9LpcBDF >= 0) {
-        mch_isa_lpc_setup(ICH9LpcBDF);
-    }
-
-    if (ICH9SmbusBDF >= 0) {
-        ich9_smbus_enable(ICH9SmbusBDF);
-    }
-
-    if(MCHMmcfgBDF >= 0) {
-        mch_mmconfig_setup(MCHMmcfgBDF);
-    }
 }
 
 static void pci_bios_init_device(struct pci_device *pci)
@@ -469,24 +388,18 @@ static void i440fx_mem_addr_setup(struct pci_device *dev, void *arg)
     pci_slot_get_irq = piix_pci_slot_get_irq;
 }
 
-static void mch_mmconfig_setup(u16 bdf)
+static void mch_mem_addr_setup(struct pci_device *dev, void *arg)
 {
     u64 addr = Q35_HOST_BRIDGE_PCIEXBAR_ADDR;
+    u32 size = Q35_HOST_BRIDGE_PCIEXBAR_SIZE;
+
+    /* setup mmconfig */
+    u16 bdf = dev->bdf;
     u32 upper = addr >> 32;
     u32 lower = (addr & 0xffffffff) | Q35_HOST_BRIDGE_PCIEXBAREN;
     pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, 0);
     pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR + 4, upper);
     pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, lower);
-}
-
-static void mch_mem_addr_setup(struct pci_device *dev, void *arg)
-{
-    u64 addr = Q35_HOST_BRIDGE_PCIEXBAR_ADDR;
-    u32 size = Q35_HOST_BRIDGE_PCIEXBAR_SIZE;
-
-    /* setup mmconfig */
-    MCHMmcfgBDF = dev->bdf;
-    mch_mmconfig_setup(dev->bdf);
     e820_add(addr, size, E820_RESERVED);
 
     /* setup pci i/o window (above mmconfig) */
index 6e706e4..579acdb 100644 (file)
@@ -10,7 +10,7 @@
 #include "output.h" // dprintf
 #include "romfile.h" // romfile_loadint
 #include "stacks.h" // yield
-#include "util.h" // smp_setup, msr_feature_control_setup
+#include "util.h" // smp_setup
 #include "x86.h" // wrmsr
 
 #define APIC_ICR_LOW ((u8*)BUILD_APIC_ADDR + 0x300)
 
 #define APIC_ENABLED 0x0100
 
-static struct { u32 index; u64 val; } smp_msr[32];
-static u32 smp_msr_count;
+static struct { u32 index; u64 val; } smp_mtrr[32];
+static u32 smp_mtrr_count;
 
 void
 wrmsr_smp(u32 index, u64 val)
 {
     wrmsr(index, val);
-    if (smp_msr_count >= ARRAY_SIZE(smp_msr)) {
+    if (smp_mtrr_count >= ARRAY_SIZE(smp_mtrr)) {
         warn_noalloc();
         return;
     }
-    smp_msr[smp_msr_count].index = index;
-    smp_msr[smp_msr_count].val = val;
-    smp_msr_count++;
+    smp_mtrr[smp_mtrr_count].index = index;
+    smp_mtrr[smp_mtrr_count].val = val;
+    smp_mtrr_count++;
 }
 
 u32 MaxCountCPUs;
@@ -58,10 +58,10 @@ handle_smp(void)
     u8 apic_id = ebx>>24;
     dprintf(DEBUG_HDL_smp, "handle_smp: apic_id=%d\n", apic_id);
 
-    // MTRR and MSR_IA32_FEATURE_CONTROL setup
+    // MTRR setup
     int i;
-    for (i=0; i<smp_msr_count; i++)
-        wrmsr(smp_msr[i].index, smp_msr[i].val);
+    for (i=0; i<smp_mtrr_count; i++)
+        wrmsr(smp_mtrr[i].index, smp_mtrr[i].val);
 
     // Set bit on FoundAPICIDs
     FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32));
index 99cd0b3..d1ff311 100644 (file)
--- a/rules.mak
+++ b/rules.mak
@@ -1,6 +1,4 @@
 
-COMMA := ,
-
 # Don't use implicit rules or variables
 # we have explicit rules for everything
 MAKEFLAGS += -rR
@@ -68,8 +66,11 @@ LINK = $(call quiet-command, $(LINKPROG) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o
        $(call process-archive-undefs, $1) \
        $(version-obj-y) $(call extract-libs,$1) $(LIBS),"  LINK  $(TARGET_DIR)$@")
 
-%.o: %.S
-       $(call quiet-command,$(CCAS) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  CCAS  $(TARGET_DIR)$@")
+%.asm: %.S
+       $(call quiet-command,$(CPP) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -o $@ $<,"  CPP   $(TARGET_DIR)$@")
+
+%.o: %.asm
+       $(call quiet-command,$(AS) $(ASFLAGS) -o $@ $<,"  AS    $(TARGET_DIR)$@")
 
 %.o: %.cc
        $(call quiet-command,$(CXX) $(QEMU_INCLUDES) $(QEMU_CXXFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) -c -o $@ $<,"  CXX   $(TARGET_DIR)$@")
@@ -92,7 +93,7 @@ module-common.o: CFLAGS += $(DSO_OBJ_CFLAGS)
        $(if $(findstring /,$@),$(call quiet-command,cp $@ $(subst /,-,$@), "  CP    $(subst /,-,$@)"))
 
 
-LD_REL := $(CC) -nostdlib -Wl,-r $(LD_REL_FLAGS)
+LD_REL := $(CC) -nostdlib -Wl,-r
 
 %.mo:
        $(call quiet-command,$(LD_REL) -o $@ $^,"  LD -r $(TARGET_DIR)$@")
@@ -113,8 +114,6 @@ quiet-command = $(if $(V),$1,$(if $(2),@echo $2 && $1, @$1))
 
 cc-option = $(if $(shell $(CC) $1 $2 -S -o /dev/null -xc /dev/null \
               >/dev/null 2>&1 && echo OK), $2, $3)
-cc-c-option = $(if $(shell $(CC) $1 $2 -c -o /dev/null -xc /dev/null \
-                >/dev/null 2>&1 && echo OK), $2, $3)
 
 VPATH_SUFFIXES = %.c %.h %.S %.cc %.cpp %.m %.mak %.texi %.sh %.rc
 set-vpath = $(if $1,$(foreach PATTERN,$(VPATH_SUFFIXES),$(eval vpath $(PATTERN) $1)))
@@ -171,7 +170,7 @@ TRACETOOL=$(PYTHON) $(SRC_PATH)/scripts/tracetool.py
 config-%.h: config-%.h-timestamp
        @cmp $< $@ >/dev/null 2>&1 || cp $< $@
 
-config-%.h-timestamp: config-%.mak $(SRC_PATH)/scripts/create_config
+config-%.h-timestamp: config-%.mak
        $(call quiet-command, sh $(SRC_PATH)/scripts/create_config < $< > $@, "  GEN   $(TARGET_DIR)config-$*.h")
 
 .PHONY: clean-timestamp
diff --git a/scripts/analyze-inclusions b/scripts/analyze-inclusions
deleted file mode 100644 (file)
index a8108d9..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2016 Red Hat, Inc.
-#
-# Author: Paolo Bonzini <pbonzini@redhat.com>
-#
-# Print statistics about header file inclusions.
-#
-# The script has two modes of execution:
-#
-# 1) if invoked with a path on the command line (possibly
-# preceded by a "--" argument), it will run the analysis on
-# an existing build directory
-#
-# 2) otherwise, it will configure and builds QEMU itself in a
-# "+build" subdirectory which is left around when the script
-# exits.  In this case the command line is passed directly to
-# "make" (typically used for a "-j" argument suitable for your
-# system).
-#
-# Inspired by a post by Markus Armbruster.
-
-case "x$1" in
-x--)
-  shift
-  cd "$1" || exit $?
-  ;;
-x-* | x)
-  mkdir -p +build
-  cd +build
-  test -f Makefile && make distclean
-  ../configure
-  make "$@"
-  ;;
-*)
-  cd "$1" || exit $?
-esac
-
-QEMU_CFLAGS=$(sed -n s/^QEMU_CFLAGS=//p config-host.mak)
-QEMU_INCLUDES=$(sed -n s/^QEMU_INCLUDES=//p config-host.mak | \
-    sed 's/$(SRC_PATH)/../g' )
-CFLAGS=$(sed -n s/^CFLAGS=//p config-host.mak)
-
-grep_include() {
-  find . -name "*.d" -exec grep -l "$@" {} + | wc -l
-}
-
-echo Found $(find . -name "*.d" | wc -l) object files
-echo $(grep_include -F 'include/qemu-common.h') files include qemu-common.h
-echo $(grep_include -F 'hw/hw.h') files include hw/hw.h
-echo $(grep_include 'target-[a-z0-9]*/cpu\.h') files include cpu.h
-echo $(grep_include -F 'qapi-types.h') files include qapi-types.h
-echo $(grep_include -F 'trace/generated-tracers.h') files include generated-tracers.h
-echo $(grep_include -F 'qapi/error.h') files include qapi/error.h
-echo $(grep_include -F 'qom/object.h') files include qom/object.h
-echo $(grep_include -F 'block/aio.h') files include block/aio.h
-echo $(grep_include -F 'exec/memory.h') files include exec/memory.h
-echo $(grep_include -F 'fpu/softfloat.h') files include fpu/softfloat.h
-echo $(grep_include -F 'qemu/bswap.h') files include qemu/bswap.h
-echo
-
-awk1='
-    /^# / { file = $3;next }
-    NR>1 { bytes[file]+=length()+1; lines[file]++ }
-    END { for(i in lines) print i,lines[i],bytes[i] }'
-
-awk2='
-    {tot_l+=$2;tot_b+=$3;tot_f++}
-    /\/usr.*\/glib/ {glib_l+=$2;glib_b+=$3;glib_f++;next}
-    /\/usr/ {sys_l+=$2;sys_b+=$3;sys_f++;next}
-    {qemu_l+=$2;qemu_b+=$3;qemu_f++;next}
-    END {
-      printf "%s\t %s\t %s\t %s\n", "lines", "bytes", "files", "source"
-      printf "%s\t %s\t %s\t %s\n", qemu_l, qemu_b, qemu_f, "QEMU"
-      printf "%s\t %s\t %s\t %s\n", sys_l, sys_b, sys_f, "system"
-      printf "%s\t %s\t %s\t %s\n", glib_l, glib_b, glib_f, "glib"
-      printf "%s\t %s\t %s\t %s\n", tot_l, tot_b, tot_f, "total"
-    }'
-
-analyze() {
-  cc $QEMU_CFLAGS $QEMU_INCLUDES $CFLAGS  -E -o - "$@" | \
-    awk "$awk1" | awk "$awk2"
-  echo
-}
-
-echo osdep.h:
-analyze ../include/qemu/osdep.h
-
-echo qemu-common.h:
-analyze  -include ../include/qemu/osdep.h ../include/qemu-common.h
-
-echo hw/hw.h:
-analyze -include ../include/qemu/osdep.h ../include/hw/hw.h
-
-echo trace/generated-tracers.h:
-analyze -include ../include/qemu/osdep.h trace/generated-tracers.h
-
-echo target-i386/cpu.h:
-analyze -DNEED_CPU_H -I../target-i386 -Ii386-softmmu -include ../include/qemu/osdep.h ../target-i386/cpu.h
-
-echo hw/hw.h + NEED_CPU_H:
-analyze -DNEED_CPU_H -I../target-i386 -Ii386-softmmu -include ../include/qemu/osdep.h ../include/hw/hw.h
index b0096a4..c939a32 100755 (executable)
@@ -22,7 +22,7 @@ my $tst_only;
 my $emacs = 0;
 my $terse = 0;
 my $file = 0;
-my $no_warnings = 0;
+my $check = 0;
 my $summary = 1;
 my $mailback = 0;
 my $summary_file = 0;
@@ -45,7 +45,7 @@ Options:
   --emacs                    emacs compile window format
   --terse                    one line per report
   -f, --file                 treat FILE as regular source file
-  --strict                   fail if only warnings are found
+  --subjective, --strict     enable more subjective tests
   --root=PATH                PATH to the kernel tree root
   --no-summary               suppress the per-file summary
   --mailback                 only produce a report in case of warnings/errors
@@ -71,7 +71,8 @@ GetOptions(
        'emacs!'        => \$emacs,
        'terse!'        => \$terse,
        'f|file!'       => \$file,
-       'strict!'       => \$no_warnings,
+       'subjective!'   => \$check,
+       'strict!'       => \$check,
        'root=s'        => \$root,
        'summary!'      => \$summary,
        'mailback!'     => \$mailback,
@@ -1071,6 +1072,12 @@ sub WARN {
                our $cnt_warn++;
        }
 }
+sub CHK {
+       if ($check && report("CHECK: $_[0]\n")) {
+               our $clean = 0;
+               our $cnt_chk++;
+       }
+}
 
 sub process {
        my $filename = shift;
@@ -1272,21 +1279,16 @@ sub process {
                        }
                }
 
-# Accept git diff extended headers as valid patches
-               if ($line =~ /^(?:rename|copy) (?:from|to) [\w\/\.\-]+\s*$/) {
-                       $is_patch = 1;
-               }
-
 #check the patch for a signoff:
                if ($line =~ /^\s*signed-off-by:/i) {
                        # This is a signoff, if ugly, so do not double report.
                        $signoff++;
                        if (!($line =~ /^\s*Signed-off-by:/)) {
-                               ERROR("The correct form is \"Signed-off-by\"\n" .
+                               WARN("Signed-off-by: is the preferred form\n" .
                                        $herecurr);
                        }
                        if ($line =~ /^\s*signed-off-by:\S/i) {
-                               ERROR("space required after Signed-off-by:\n" .
+                               WARN("space required after Signed-off-by:\n" .
                                        $herecurr);
                        }
                }
@@ -1312,9 +1314,6 @@ sub process {
 # ignore non-hunk lines and lines being removed
                next if (!$hunk_line || $line =~ /^-/);
 
-# ignore files that are being periodically imported from Linux
-               next if ($realfile =~ /^(linux-headers|include\/standard-headers)\//);
-
 #trailing whitespace
                if ($line =~ /^\+.*\015/) {
                        my $herevet = "$here\n" . cat_vet($rawline) . "\n";
@@ -1327,40 +1326,30 @@ sub process {
                }
 
 # check we are in a valid source file if not then ignore this hunk
-               next if ($realfile !~ /\.(h|c|cpp|s|S|pl|py|sh)$/);
+               next if ($realfile !~ /\.(h|c|cpp|s|S|pl|sh)$/);
 
-#90 column limit
+#80 column limit
                if ($line =~ /^\+/ &&
                    !($line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
                    $length > 80)
                {
-                       if ($length > 90) {
-                               ERROR("line over 90 characters\n" . $herecurr);
-                       } else {
-                               WARN("line over 80 characters\n" . $herecurr);
-                       }
+                       WARN("line over 80 characters\n" . $herecurr);
                }
 
 # check for spaces before a quoted newline
                if ($rawline =~ /^.*\".*\s\\n/) {
-                       ERROR("unnecessary whitespace before a quoted newline\n" . $herecurr);
+                       WARN("unnecessary whitespace before a quoted newline\n" . $herecurr);
                }
 
 # check for adding lines without a newline.
                if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
-                       ERROR("adding a line without newline at end of file\n" . $herecurr);
-               }
-
-# check for RCS/CVS revision markers
-               if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|\b)/) {
-                       ERROR("CVS style keyword markers, these will _not_ be updated\n". $herecurr);
+                       WARN("adding a line without newline at end of file\n" . $herecurr);
                }
 
-# tabs are only allowed in assembly source code, and in
-# some scripts we imported from other projects.
-               next if ($realfile =~ /\.(s|S)$/);
-               next if ($realfile =~ /(checkpatch|get_maintainer|texi2pod)\.pl$/);
+# check we are in a valid source file C or perl if not then ignore this hunk
+               next if ($realfile !~ /\.(h|c|cpp|pl)$/);
 
+# in QEMU, no tabs are allowed
                if ($rawline =~ /^\+.*\t/) {
                        my $herevet = "$here\n" . cat_vet($rawline) . "\n";
                        ERROR("code indent should never use tabs\n" . $herevet);
@@ -1370,6 +1359,11 @@ sub process {
 # check we are in a valid C source file if not then ignore this hunk
                next if ($realfile !~ /\.(h|c|cpp)$/);
 
+# check for RCS/CVS revision markers
+               if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
+                       WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr);
+               }
+
 # Check for potential 'bare' types
                my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
                    $realline_next);
@@ -1499,7 +1493,7 @@ sub process {
                        {
                                my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
                                if ($nindent > $indent) {
-                                       ERROR("trailing semicolon indicates no statements, indent implies otherwise\n" .
+                                       WARN("trailing semicolon indicates no statements, indent implies otherwise\n" .
                                                "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
                                }
                        }
@@ -1587,7 +1581,7 @@ sub process {
 
                        if ($check && (($sindent % 4) != 0 ||
                            ($sindent <= $indent && $s ne ''))) {
-                               ERROR("suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
+                               WARN("suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
                        }
                }
 
@@ -1765,7 +1759,7 @@ sub process {
                        } elsif ($ctx =~ /$Type$/) {
 
                        } else {
-                               ERROR("space prohibited between function name and open parenthesis '('\n" . $herecurr);
+                               WARN("space prohibited between function name and open parenthesis '('\n" . $herecurr);
                        }
                }
 # Check operator spacing.
@@ -2004,7 +1998,7 @@ sub process {
                if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) {
                        my $name = $1;
                        if ($name ne 'EOF' && $name ne 'ERROR') {
-                               ERROR("return of an errno should typically be -ve (return -$1)\n" . $herecurr);
+                               WARN("return of an errno should typically be -ve (return -$1)\n" . $herecurr);
                        }
                }
 
@@ -2076,7 +2070,7 @@ sub process {
                                (?:\&\&|\|\||\)|\])
                        )/x)
                {
-                       ERROR("boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
+                       WARN("boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
                }
 
 # if and else should not have general statements after it
@@ -2132,7 +2126,7 @@ sub process {
 
 #no spaces allowed after \ in define
                if ($line=~/\#\s*define.*\\\s$/) {
-                       ERROR("Whitespace after \\ makes next lines useless\n" . $herecurr);
+                       WARN("Whitepspace after \\ makes next lines useless\n" . $herecurr);
                }
 
 # multi-statement macros should be enclosed in a do while loop, grab the
@@ -2284,7 +2278,7 @@ sub process {
                                        }
                                }
                                if ($seen != ($#chunks + 1)) {
-                                       ERROR("braces {} are necessary for all arms of this statement\n" . $herectx);
+                                       WARN("braces {} are necessary for all arms of this statement\n" . $herectx);
                                }
                        }
                }
@@ -2352,19 +2346,19 @@ sub process {
                                        $herectx .= raw_line($linenr, $n) . "\n";;
                                }
 
-                               ERROR("braces {} are necessary even for single statement blocks\n" . $herectx);
+                               WARN("braces {} are necessary even for single statement blocks\n" . $herectx);
                        }
                }
 
 # no volatiles please
                my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
                if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
-                       ERROR("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
+                       WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
                }
 
 # warn about #if 0
                if ($line =~ /^.\s*\#\s*if\s+0\b/) {
-                       ERROR("if this code is redundant consider removing it\n" .
+                       WARN("if this code is redundant consider removing it\n" .
                                $herecurr);
                }
 
@@ -2372,7 +2366,7 @@ sub process {
                if ($prevline =~ /\bif\s*\(([^\)]*)\)/) {
                        my $expr = $1;
                        if ($line =~ /\bg_free\(\Q$expr\E\);/) {
-                               ERROR("g_free(NULL) is safe this check is probably not required\n" . $hereprev);
+                               WARN("g_free(NULL) is safe this check is probably not required\n" . $hereprev);
                        }
                }
 
@@ -2390,19 +2384,19 @@ sub process {
 # check for memory barriers without a comment.
                if ($line =~ /\b(smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {
                        if (!ctx_has_comment($first_line, $linenr)) {
-                               ERROR("memory barrier without comment\n" . $herecurr);
+                               WARN("memory barrier without comment\n" . $herecurr);
                        }
                }
 # check of hardware specific defines
 # we have e.g. CONFIG_LINUX and CONFIG_WIN32 for common cases
 # where they might be necessary.
                if ($line =~ m@^.\s*\#\s*if.*\b__@) {
-                       ERROR("architecture specific defines should be avoided\n" .  $herecurr);
+                       WARN("architecture specific defines should be avoided\n" .  $herecurr);
                }
 
 # Check that the storage class is at the beginning of a declaration
                if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
-                       ERROR("storage class should be at the beginning of the declaration\n" . $herecurr)
+                       WARN("storage class should be at the beginning of the declaration\n" . $herecurr)
                }
 
 # check the location of the inline attribute, that it is between
@@ -2414,7 +2408,7 @@ sub process {
 
 # check for sizeof(&)
                if ($line =~ /\bsizeof\s*\(\s*\&/) {
-                       ERROR("sizeof(& should be avoided\n" . $herecurr);
+                       WARN("sizeof(& should be avoided\n" . $herecurr);
                }
 
 # check for new externs in .c files.
@@ -2431,40 +2425,40 @@ sub process {
                        if ($s =~ /^\s*;/ &&
                            $function_name ne 'uninitialized_var')
                        {
-                               ERROR("externs should be avoided in .c files\n" .  $herecurr);
+                               WARN("externs should be avoided in .c files\n" .  $herecurr);
                        }
 
                        if ($paren_space =~ /\n/) {
-                               ERROR("arguments for function declarations should follow identifier\n" . $herecurr);
+                               WARN("arguments for function declarations should follow identifier\n" . $herecurr);
                        }
 
                } elsif ($realfile =~ /\.c$/ && defined $stat &&
                    $stat =~ /^.\s*extern\s+/)
                {
-                       ERROR("externs should be avoided in .c files\n" .  $herecurr);
+                       WARN("externs should be avoided in .c files\n" .  $herecurr);
                }
 
 # check for pointless casting of g_malloc return
                if ($line =~ /\*\s*\)\s*g_(try)?(m|re)alloc(0?)(_n)?\b/) {
                        if ($2 == 'm') {
-                               ERROR("unnecessary cast may hide bugs, use g_$1new$3 instead\n" . $herecurr);
+                               WARN("unnecessary cast may hide bugs, use g_$1new$3 instead\n" . $herecurr);
                        } else {
-                               ERROR("unnecessary cast may hide bugs, use g_$1renew$3 instead\n" . $herecurr);
+                               WARN("unnecessary cast may hide bugs, use g_$1renew$3 instead\n" . $herecurr);
                        }
                }
 
 # check for gcc specific __FUNCTION__
                if ($line =~ /__FUNCTION__/) {
-                       ERROR("__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);
+                       WARN("__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);
                }
 
 # recommend qemu_strto* over strto* for numeric conversions
-               if ($line =~ /\b(strto[^kd].*?)\s*\(/) {
-                       ERROR("consider using qemu_$1 in preference to $1\n" . $herecurr);
+               if ($line =~ /\b(strto[^k].*?)\s*\(/) {
+                       WARN("consider using qemu_$1 in preference to $1\n" . $herecurr);
                }
 # check for module_init(), use category-specific init macros explicitly please
                if ($line =~ /^module_init\s*\(/) {
-                       ERROR("please use block_init(), type_init() etc. instead of module_init()\n" . $herecurr);
+                       WARN("please use block_init(), type_init() etc. instead of module_init()\n" . $herecurr);
                }
 # check for various ops structs, ensure they are const.
                my $struct_ops = qr{AIOCBInfo|
@@ -2489,7 +2483,7 @@ sub process {
                                VMStateInfo}x;
                if ($line !~ /\bconst\b/ &&
                    $line =~ /\b($struct_ops)\b/) {
-                       ERROR("struct $1 should normally be const\n" .
+                       WARN("struct $1 should normally be const\n" .
                                $herecurr);
                }
 
@@ -2499,14 +2493,14 @@ sub process {
                        $string = substr($rawline, $-[1], $+[1] - $-[1]);
                        $string =~ s/%%/__/g;
                        if ($string =~ /(?<!%)%L[udi]/) {
-                               ERROR("\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
+                               WARN("\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
                                last;
                        }
                }
 
 # QEMU specific tests
                if ($rawline =~ /\b(?:Qemu|QEmu)\b/) {
-                       ERROR("use QEMU instead of Qemu or QEmu\n" . $herecurr);
+                       WARN("use QEMU instead of Qemu or QEmu\n" . $herecurr);
                }
 
 # Qemu error function tests
@@ -2515,15 +2509,12 @@ sub process {
        my $qemu_error_funcs = qr{error_setg|
                                error_setg_errno|
                                error_setg_win32|
-                               error_setg_file_open|
                                error_set|
-                               error_prepend|
-                               error_reportf_err|
                                error_vreport|
                                error_report}x;
 
-       if ($rawline =~ /\b(?:$qemu_error_funcs)\s*\(.*\".*\\n/) {
-               ERROR("Error messages should not contain newlines\n" . $herecurr);
+       if ($rawline =~ /\b(?:$qemu_error_funcs)\s*\(\s*\".*\\n/) {
+               WARN("Error messages should not contain newlines\n" . $herecurr);
        }
 
        # Continue checking for error messages that contains newlines. This
@@ -2544,11 +2535,11 @@ sub process {
                }
 
                if ($rawlines[$i] =~ /\b(?:$qemu_error_funcs)\s*\(/) {
-                       ERROR("Error messages should not contain newlines\n" . $herecurr);
+                       WARN("Error messages should not contain newlines\n" . $herecurr);
                }
        }
 
-# check for non-portable libc calls that have portable alternatives in QEMU
+# check for non-portable ffs() calls that have portable alternatives in QEMU
                if ($line =~ /\bffs\(/) {
                        ERROR("use ctz32() instead of ffs()\n" . $herecurr);
                }
@@ -2558,9 +2549,6 @@ sub process {
                if ($line =~ /\bffsll\(/) {
                        ERROR("use ctz64() instead of ffsll()\n" . $herecurr);
                }
-               if ($line =~ /\bbzero\(/) {
-                       ERROR("use memset() instead of bzero()\n" . $herecurr);
-               }
        }
 
        # If we have no input at all, then there is nothing to report on
@@ -2592,6 +2580,7 @@ sub process {
        if ($summary && !($clean == 1 && $quiet == 1)) {
                print "$filename " if ($summary_file);
                print "total: $cnt_error errors, $cnt_warn warnings, " .
+                       (($check)? "$cnt_chk checks, " : "") .
                        "$cnt_lines lines checked\n";
                print "\n" if ($quiet == 0);
        }
@@ -2614,5 +2603,5 @@ sub process {
                print "CHECKPATCH in MAINTAINERS.\n";
        }
 
-       return ($no_warnings ? $clean : $cnt_error == 0);
+       return $clean;
 }
diff --git a/scripts/clean-header-guards.pl b/scripts/clean-header-guards.pl
deleted file mode 100755 (executable)
index 54ab99a..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-#!/usr/bin/perl -w
-#
-# Clean up include guards in headers
-#
-# Copyright (C) 2016 Red Hat, Inc.
-#
-# Authors:
-#  Markus Armbruster <armbru@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or
-# (at your option) any later version. See the COPYING file in the
-# top-level directory.
-#
-# Usage: scripts/clean-header-guards.pl [OPTION]... [FILE]...
-#     -c CC     Use a compiler other than cc
-#     -n        Suppress actual cleanup
-#     -v        Show which files are cleaned up, and which are skipped
-#
-# Does the following:
-# - Header files without a recognizable header guard are skipped.
-# - Clean up any untidy header guards in-place.  Warn if the cleanup
-#   renames guard symbols, and explain how to find occurences of these
-#   symbols that may have to be updated manually.
-# - Warn about duplicate header guard symbols.  To make full use of
-#   this warning, you should clean up *all* headers in one run.
-# - Warn when preprocessing a header with its guard symbol defined
-#   produces anything but whitespace.  The preprocessor is run like
-#   "cc -E -DGUARD_H -c -P -", and fed the test program on stdin.
-
-use strict;
-use Getopt::Std;
-
-# Stuff we don't want to clean because we import it into our tree:
-my $exclude = qr,^(disas/libvixl/|include/standard-headers/
-    |linux-headers/|pc-bios/|tests/tcg/|tests/multiboot/),x;
-# Stuff that is expected to fail the preprocessing test:
-my $exclude_cpp = qr,^include/libdecnumber/decNumberLocal.h,;
-
-my %guarded = ();
-my %old_guard = ();
-
-our $opt_c = "cc";
-our $opt_n = 0;
-our $opt_v = 0;
-getopts("c:nv");
-
-sub skipping {
-    my ($fname, $msg, $line1, $line2) = @_;
-
-    return if !$opt_v or $fname =~ $exclude;
-    print "$fname skipped: $msg\n";
-    print "    $line1" if defined $line1;
-    print "    $line2" if defined $line2;
-}
-
-sub gripe {
-    my ($fname, $msg) = @_;
-    return if $fname =~ $exclude;
-    print STDERR "$fname: warning: $msg\n";
-}
-
-sub slurp {
-    my ($fname) = @_;
-    local $/;                   # slurp
-    open(my $in, "<", $fname)
-        or die "can't open $fname for reading: $!";
-    return <$in>;
-}
-
-sub unslurp {
-    my ($fname, $contents) = @_;
-    open (my $out, ">", $fname)
-        or die "can't open $fname for writing: $!";
-    print $out $contents
-        or die "error writing $fname: $!";
-    close $out
-        or die "error writing $fname: $!";
-}
-
-sub fname2guard {
-    my ($fname) = @_;
-    $fname =~ tr/a-z/A-Z/;
-    $fname =~ tr/A-Z0-9/_/cs;
-    return $fname;
-}
-
-sub preprocess {
-    my ($fname, $guard) = @_;
-
-    open(my $pipe, "-|", "$opt_c -E -D$guard -c -P - <$fname")
-        or die "can't run $opt_c: $!";
-    while (<$pipe>) {
-        if ($_ =~ /\S/) {
-            gripe($fname, "not blank after preprocessing");
-            last;
-        }
-    }
-    close $pipe
-        or gripe($fname, "preprocessing failed ($opt_c exit status $?)");
-}
-
-for my $fname (@ARGV) {
-    my $text = slurp($fname);
-
-    $text =~ m,\A(\s*\n|\s*//\N*\n|\s*/\*.*?\*/\s*\n)*|,msg;
-    my $pre = $&;
-    unless ($text =~ /\G(.*\n)/g) {
-        $text =~ /\G.*/;
-        skipping($fname, "no recognizable header guard", "$&\n");
-        next;
-    }
-    my $line1 = $1;
-    unless ($text =~ /\G(.*\n)/g) {
-        $text =~ /\G.*/;
-        skipping($fname, "no recognizable header guard", "$&\n");
-        next;
-    }
-    my $line2 = $1;
-    my $body = substr($text, pos($text));
-
-    unless ($line1 =~ /^\s*\#\s*(if\s*\!\s*defined(\s*\()?|ifndef)\s*
-                       ([A-Za-z0-9_]+)/x) {
-        skipping($fname, "no recognizable header guard", $line1, $line2);
-        next;
-    }
-    my $guard = $3;
-    unless ($line2 =~ /^\s*\#\s*define\s+([A-Za-z0-9_]+)/) {
-        skipping($fname, "no recognizable header guard", $line1, $line2);
-        next;
-    }
-    my $guard2 = $1;
-    unless ($guard2 eq $guard) {
-        skipping($fname, "mismatched header guard ($guard vs. $guard2) ",
-                 $line1, $line2);
-        next;
-    }
-
-    unless ($body =~ m,\A((.*\n)*)
-                       (\s*\#\s*endif\s*(/\*\s*.*\s*\*/\s*)?\n?)
-                       (\n|\s)*\Z,x) {
-        skipping($fname, "can't find end of header guard");
-        next;
-    }
-    $body = $1;
-    my $line3 = $3;
-    my $endif_comment = $4;
-
-    my $oldg = $guard;
-
-    unless ($fname =~ $exclude) {
-        my @issues = ();
-        $guard =~ tr/a-z/A-Z/
-            and push @issues, "contains lowercase letters";
-        $guard =~ s/^_+//
-            and push @issues, "is a reserved identifier";
-        $guard =~ s/(_H)?_*$/_H/
-            and $& ne "_H" and push @issues, "doesn't end with _H";
-        unless ($guard =~ /^[A-Z][A-Z0-9_]*_H/) {
-            skipping($fname, "can't clean up odd guard symbol $oldg\n",
-                     $line1, $line2);
-            next;
-        }
-
-        my $exp = fname2guard($fname =~ s,.*/,,r);
-        unless ($guard =~ /\Q$exp\E\Z/) {
-            $guard = fname2guard($fname =~ s,^include/,,r);
-            push @issues, "doesn't match the file name";
-        }
-        if (@issues and $opt_v) {
-            print "$fname guard $oldg needs cleanup:\n    ",
-                join(", ", @issues), "\n";
-        }
-    }
-
-    $old_guard{$guard} = $oldg
-        if $guard ne $oldg;
-
-    if (exists $guarded{$guard}) {
-        gripe($fname, "guard $guard also used by $guarded{$guard}");
-    } else {
-        $guarded{$guard} = $fname;
-    }
-
-    unless ($fname =~ $exclude) {
-        my $newl1 = "#ifndef $guard\n";
-        my $newl2 = "#define $guard\n";
-        my $newl3 = "#endif\n";
-        $newl3 =~ s,\Z, /* $guard */, if defined $endif_comment;
-        if ($line1 ne $newl1 or $line2 ne $newl2 or $line3 ne $newl3) {
-            $pre =~ s/\n*\Z/\n\n/ if $pre =~ /\N/;
-            $body =~ s/\A\n*/\n/;
-            if ($opt_n) {
-                print "$fname would be cleaned up\n" if $opt_v;
-            } else {
-                unslurp($fname, "$pre$newl1$newl2$body$newl3");
-                print "$fname cleaned up\n" if $opt_v;
-            }
-        }
-    }
-
-    preprocess($fname, $opt_n ? $oldg : $guard)
-        unless $fname =~ $exclude or $fname =~ $exclude_cpp;
-}
-
-if (%old_guard) {
-    print STDERR "warning: guard symbol renaming may break things\n";
-    for my $guard (sort keys %old_guard) {
-        print STDERR "    $old_guard{$guard} -> $guard\n";
-    }
-    print STDERR "To find uses that may have to be updated try:\n";
-    print STDERR "    git grep -Ew '", join("|", sort values %old_guard),
-        "'\n";
-}
index 4412a55..72b47f1 100755 (executable)
@@ -39,7 +39,7 @@
 # However some caution is required regarding files that might be part
 # of the guest agent or standalone tests.
 
-# for i in $(git ls-tree --name-only HEAD) ; do test -f $i && \
+# for i in `git ls-tree --name-only HEAD`  ; do test -f $i && \
 #   grep -E '^# *include' $i | head -1 | grep 'osdep.h' ; test $? != 0 && \
 #   echo $i ; done
 
@@ -104,9 +104,6 @@ for f in "$@"; do
       ;;
     *include/qemu/osdep.h | \
     *include/qemu/compiler.h | \
-    *include/glib-compat.h | \
-    *include/sysemu/os-posix.h | \
-    *include/sysemu/os-win32.h | \
     *include/standard-headers/ )
       # Removing include lines from osdep.h itself would be counterproductive.
       echo "SKIPPING $f (special case header)"
@@ -146,8 +143,7 @@ for f in "$@"; do
            <setjmp.h> <stdarg.h> <stddef.h> <stdbool.h> <stdint.h> <sys/types.h>
            <stdlib.h> <stdio.h> <string.h> <strings.h> <inttypes.h>
            <limits.h> <unistd.h> <time.h> <ctype.h> <errno.h> <fcntl.h>
-           <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h>
-           <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h> <sys/mman.h>
+           <sys/stat.h> <sys/time.h> <assert.h> <signal.h>
            "sysemu/os-posix.h, sysemu/os-win32.h "glib-compat.h"
            "qemu/typedefs.h"
             ))' "$f"
index 9f2e72e..eceb4be 100644 (file)
@@ -117,9 +117,3 @@ struct {                                                                \
         type *tqe_next;       /* next element */                        \
         type **tqe_prev;      /* address of previous next element */    \
 }
-
-/* From glib */
-#define g_assert_cmpint(a, op, b)   g_assert(a op b)
-#define g_assert_cmpuint(a, op, b)   g_assert(a op b)
-#define g_assert_cmphex(a, op, b)   g_assert(a op b)
-#define g_assert_cmpstr(a, op, b)   g_assert(strcmp(a, b) op 0)
diff --git a/scripts/coccinelle/err-bad-newline.cocci b/scripts/coccinelle/err-bad-newline.cocci
deleted file mode 100644 (file)
index 1316cc8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// Error messages should not contain newlines.  This script finds
-// messages that do.  Fixing them is manual.
-@r@
-expression errp, eno, cls, fmt;
-position p;
-@@
-(
-error_report(fmt, ...)@p
-|
-error_setg(errp, fmt, ...)@p
-|
-error_setg_errno(errp, eno, fmt, ...)@p
-|
-error_setg_win32(errp, eno, cls, fmt, ...)@p
-|
-error_prepend(errp, fmt, ...)@p
-|
-error_setg_file_open(errp, eno, cls, fmt, ...)@p
-|
-error_reportf_err(errp, fmt, ...)@p
-|
-error_set(errp, cls, fmt, ...)@p
-)
-@script:python@
-fmt << r.fmt;
-p << r.p;
-@@
-if "\\n" in str(fmt):
-    print "%s:%s:%s:%s" % (p[0].file, p[0].line, p[0].column, fmt)
diff --git a/scripts/coccinelle/error_propagate_null.cocci b/scripts/coccinelle/error_propagate_null.cocci
deleted file mode 100644 (file)
index c236380..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// error_propagate() already ignores local_err==NULL, so there's
-// no need to check it before calling.
-
-@@
-identifier L;
-expression E;
-@@
--if (L) {
-     error_propagate(E, L);
--}
diff --git a/scripts/coccinelle/overflow_muldiv64.cocci b/scripts/coccinelle/overflow_muldiv64.cocci
deleted file mode 100644 (file)
index 08ec4a8..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Find muldiv64(i64, i64, x) for potential overflow
-@filter@
-typedef uint64_t;
-typedef int64_t;
-{ uint64_t, int64_t, long, unsigned long } a, b;
-expression c;
-position p;
-@@
-
-muldiv64(a,b,c)@p
-
-@script:python@
-p << filter.p;
-@@
-
-cocci.print_main("potential muldiv64() overflow", p)
diff --git a/scripts/coccinelle/remove_local_err.cocci b/scripts/coccinelle/remove_local_err.cocci
deleted file mode 100644 (file)
index 9261c99..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// Replace unnecessary usage of local_err variable with
-// direct usage of errp argument
-
-@@
-identifier F;
-expression list ARGS;
-expression F2;
-identifier LOCAL_ERR;
-identifier ERRP;
-idexpression V;
-typedef Error;
-@@
- F(..., Error **ERRP)
- {
-     ...
--    Error *LOCAL_ERR;
-     ... when != LOCAL_ERR
-         when != ERRP
-(
--    F2(ARGS, &LOCAL_ERR);
--    error_propagate(ERRP, LOCAL_ERR);
-+    F2(ARGS, ERRP);
-|
--    V = F2(ARGS, &LOCAL_ERR);
--    error_propagate(ERRP, LOCAL_ERR);
-+    V = F2(ARGS, ERRP);
-)
-     ... when != LOCAL_ERR
- }
diff --git a/scripts/coccinelle/remove_muldiv64.cocci b/scripts/coccinelle/remove_muldiv64.cocci
deleted file mode 100644 (file)
index 4c10bd5..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// replace muldiv64(a, 1, b) by "a / b"
-@@
-expression a, b;
-@@
--muldiv64(a, 1, b)
-+a / b
diff --git a/scripts/coccinelle/return_directly.cocci b/scripts/coccinelle/return_directly.cocci
deleted file mode 100644 (file)
index 48680f2..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// replace 'R = X; return R;' with 'return R;'
-@@
-identifier VAR;
-expression E;
-type T;
-identifier F;
-@@
- T F(...)
- {
-     ...
--    T VAR;
-     ... when != VAR
-
--    VAR =
-+    return
-     E;
--    return VAR;
-     ... when != VAR
- }
diff --git a/scripts/coccinelle/round.cocci b/scripts/coccinelle/round.cocci
deleted file mode 100644 (file)
index ed06773..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Use macro DIV_ROUND_UP instead of (((n) + (d) - 1) /(d))
-@@
-expression e1;
-expression e2;
-@@
-(
-- ((e1) + e2 - 1) / (e2)
-+ DIV_ROUND_UP(e1,e2)
-|
-- ((e1) + (e2 - 1)) / (e2)
-+ DIV_ROUND_UP(e1,e2)
-)
-
-@@
-expression e1;
-expression e2;
-@@
--(DIV_ROUND_UP(e1,e2))
-+DIV_ROUND_UP(e1,e2)
diff --git a/scripts/coccinelle/simplify_muldiv64.cocci b/scripts/coccinelle/simplify_muldiv64.cocci
deleted file mode 100644 (file)
index 3d7c974..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// replace muldiv64(i32, i32, x) by (uint64_t)i32 * i32 / x
-@@
-typedef uint32_t;
-typedef int32_t;
-{ uint32_t, int32_t, int, unsigned int } a, b;
-typedef uint64_t;
-expression c;
-@@
-
--muldiv64(a,b,c)
-+(uint64_t) a * b / c
diff --git a/scripts/coccinelle/swap_muldiv64.cocci b/scripts/coccinelle/swap_muldiv64.cocci
deleted file mode 100644 (file)
index b48b0d0..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// replace muldiv64(i32, i64, x) by muldiv64(i64, i32, x)
-@@
-typedef uint64_t;
-typedef int64_t;
-typedef uint32_t;
-typedef int32_t;
-{ uint32_t, int32_t, int, unsigned int } a;
-{ uint64_t, int64_t, long, unsigned long } b;
-expression c;
-@@
-
--muldiv64(a,b,c)
-+muldiv64(b,a,c)
index 1dd6a35..9cb176f 100755 (executable)
@@ -9,10 +9,14 @@ case $line in
     version=${line#*=}
     echo "#define QEMU_VERSION \"$version\""
     ;;
+ PKGVERSION=*) # configuration
+    pkgversion=${line#*=}
+    echo "#define QEMU_PKGVERSION \"$pkgversion\""
+    ;;
  qemu_*dir=*) # qemu-specific directory configuration
     name=${line%=*}
     value=${line#*=}
-    define_name=$(echo $name | LC_ALL=C tr '[a-z]' '[A-Z]')
+    define_name=`echo $name | LC_ALL=C tr '[a-z]' '[A-Z]'`
     eval "define_value=\"$value\""
     echo "#define CONFIG_$define_name \"$define_value\""
     # save for the next definitions
@@ -48,7 +52,7 @@ case $line in
     done
     echo "    NULL"
     ;;
- CONFIG_*='$(CONFIG_SOFTMMU)'|CONFIG_*=y) # configuration
+ CONFIG_*=y) # configuration
     name=${line%=*}
     echo "#define $name 1"
     ;;
@@ -68,7 +72,7 @@ case $line in
     ;;
  ARCH=*) # configuration
     arch=${line#*=}
-    arch_name=$(echo $arch | LC_ALL=C tr '[a-z]' '[A-Z]')
+    arch_name=`echo $arch | LC_ALL=C tr '[a-z]' '[A-Z]'`
     echo "#define HOST_$arch_name 1"
     ;;
  HOST_USB=*)
@@ -88,7 +92,7 @@ case $line in
     ;;
  TARGET_BASE_ARCH=*) # configuration
     target_base_arch=${line#*=}
-    base_arch_name=$(echo $target_base_arch | LC_ALL=C tr '[a-z]' '[A-Z]')
+    base_arch_name=`echo $target_base_arch | LC_ALL=C tr '[a-z]' '[A-Z]'`
     echo "#define TARGET_$base_arch_name 1"
     ;;
  TARGET_XML_FILES=*)
index 9956fc0..c0a2e99 100644 (file)
@@ -53,44 +53,44 @@ class ELF(object):
         self.notes = []
         self.segments = []
         self.notes_size = 0
-        self.endianness = None
+        self.endianess = None
         self.elfclass = ELFCLASS64
 
         if arch == 'aarch64-le':
-            self.endianness = ELFDATA2LSB
+            self.endianess = ELFDATA2LSB
             self.elfclass = ELFCLASS64
-            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
+            self.ehdr = get_arch_ehdr(self.endianess, self.elfclass)
             self.ehdr.e_machine = EM_AARCH
 
         elif arch == 'aarch64-be':
-            self.endianness = ELFDATA2MSB
-            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
+            self.endianess = ELFDATA2MSB
+            self.ehdr = get_arch_ehdr(self.endianess, self.elfclass)
             self.ehdr.e_machine = EM_AARCH
 
         elif arch == 'X86_64':
-            self.endianness = ELFDATA2LSB
-            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
+            self.endianess = ELFDATA2LSB
+            self.ehdr = get_arch_ehdr(self.endianess, self.elfclass)
             self.ehdr.e_machine = EM_X86_64
 
         elif arch == '386':
-            self.endianness = ELFDATA2LSB
+            self.endianess = ELFDATA2LSB
             self.elfclass = ELFCLASS32
-            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
+            self.ehdr = get_arch_ehdr(self.endianess, self.elfclass)
             self.ehdr.e_machine = EM_386
 
         elif arch == 's390':
-            self.endianness = ELFDATA2MSB
-            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
+            self.endianess = ELFDATA2MSB
+            self.ehdr = get_arch_ehdr(self.endianess, self.elfclass)
             self.ehdr.e_machine = EM_S390
 
         elif arch == 'ppc64-le':
-            self.endianness = ELFDATA2LSB
-            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
+            self.endianess = ELFDATA2LSB
+            self.ehdr = get_arch_ehdr(self.endianess, self.elfclass)
             self.ehdr.e_machine = EM_PPC64
 
         elif arch == 'ppc64-be':
-            self.endianness = ELFDATA2MSB
-            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
+            self.endianess = ELFDATA2MSB
+            self.ehdr = get_arch_ehdr(self.endianess, self.elfclass)
             self.ehdr.e_machine = EM_PPC64
 
         else:
@@ -104,7 +104,7 @@ class ELF(object):
     def add_note(self, n_name, n_desc, n_type):
         """Adds a note to the ELF."""
 
-        note = get_arch_note(self.endianness, len(n_name), len(n_desc))
+        note = get_arch_note(self.endianess, len(n_name), len(n_desc))
         note.n_namesz = len(n_name) + 1
         note.n_descsz = len(n_desc)
         note.n_name = n_name.encode()
@@ -123,7 +123,7 @@ class ELF(object):
     def add_segment(self, p_type, p_paddr, p_size):
         """Adds a segment to the elf."""
 
-        phdr = get_arch_phdr(self.endianness, self.elfclass)
+        phdr = get_arch_phdr(self.endianess, self.elfclass)
         phdr.p_type = p_type
         phdr.p_paddr = p_paddr
         phdr.p_filesz = p_size
@@ -155,10 +155,10 @@ class ELF(object):
             elf_file.write(note)
 
 
-def get_arch_note(endianness, len_name, len_desc):
-    """Returns a Note class with the specified endianness."""
+def get_arch_note(endianess, len_name, len_desc):
+    """Returns a Note class with the specified endianess."""
 
-    if endianness == ELFDATA2LSB:
+    if endianess == ELFDATA2LSB:
         superclass = ctypes.LittleEndianStructure
     else:
         superclass = ctypes.BigEndianStructure
@@ -190,20 +190,20 @@ class Ident(ctypes.Structure):
                 ('ei_abiversion', ctypes.c_ubyte),
                 ('ei_pad', ctypes.c_ubyte * 7)]
 
-    def __init__(self, endianness, elfclass):
+    def __init__(self, endianess, elfclass):
         self.ei_mag0 = 0x7F
         self.ei_mag1 = ord('E')
         self.ei_mag2 = ord('L')
         self.ei_mag3 = ord('F')
         self.ei_class = elfclass
-        self.ei_data = endianness
+        self.ei_data = endianess
         self.ei_version = EV_CURRENT
 
 
-def get_arch_ehdr(endianness, elfclass):
-    """Returns a EHDR64 class with the specified endianness."""
+def get_arch_ehdr(endianess, elfclass):
+    """Returns a EHDR64 class with the specified endianess."""
 
-    if endianness == ELFDATA2LSB:
+    if endianess == ELFDATA2LSB:
         superclass = ctypes.LittleEndianStructure
     else:
         superclass = ctypes.BigEndianStructure
@@ -228,12 +228,12 @@ def get_arch_ehdr(endianness, elfclass):
 
         def __init__(self):
             super(superclass, self).__init__()
-            self.e_ident = Ident(endianness, elfclass)
+            self.e_ident = Ident(endianess, elfclass)
             self.e_type = ET_CORE
             self.e_version = EV_CURRENT
             self.e_ehsize = ctypes.sizeof(self)
             self.e_phoff = ctypes.sizeof(self)
-            self.e_phentsize = ctypes.sizeof(get_arch_phdr(endianness, elfclass))
+            self.e_phentsize = ctypes.sizeof(get_arch_phdr(endianess, elfclass))
             self.e_phnum = 0
 
 
@@ -257,12 +257,12 @@ def get_arch_ehdr(endianness, elfclass):
 
         def __init__(self):
             super(superclass, self).__init__()
-            self.e_ident = Ident(endianness, elfclass)
+            self.e_ident = Ident(endianess, elfclass)
             self.e_type = ET_CORE
             self.e_version = EV_CURRENT
             self.e_ehsize = ctypes.sizeof(self)
             self.e_phoff = ctypes.sizeof(self)
-            self.e_phentsize = ctypes.sizeof(get_arch_phdr(endianness, elfclass))
+            self.e_phentsize = ctypes.sizeof(get_arch_phdr(endianess, elfclass))
             self.e_phnum = 0
 
     # End get_arch_ehdr
@@ -272,10 +272,10 @@ def get_arch_ehdr(endianness, elfclass):
         return EHDR32()
 
 
-def get_arch_phdr(endianness, elfclass):
-    """Returns a 32 or 64 bit PHDR class with the specified endianness."""
+def get_arch_phdr(endianess, elfclass):
+    """Returns a 32 or 64 bit PHDR class with the specified endianess."""
 
-    if endianness == ELFDATA2LSB:
+    if endianess == ELFDATA2LSB:
         superclass = ctypes.LittleEndianStructure
     else:
         superclass = ctypes.BigEndianStructure
@@ -328,10 +328,23 @@ def qlist_foreach(head, field_str):
         yield var
 
 
-def qemu_map_ram_ptr(block, offset):
+def qemu_get_ram_block(ram_addr):
+    """Returns the RAMBlock struct to which the given address belongs."""
+
+    ram_blocks = gdb.parse_and_eval("ram_list.blocks")
+
+    for block in qlist_foreach(ram_blocks, "next"):
+        if (ram_addr - block["offset"]) < block["used_length"]:
+            return block
+
+    raise gdb.GdbError("Bad ram offset %x" % ram_addr)
+
+
+def qemu_get_ram_ptr(ram_addr):
     """Returns qemu vaddr for given guest physical address."""
 
-    return block["host"] + offset
+    block = qemu_get_ram_block(ram_addr)
+    return block["host"] + (ram_addr - block["offset"])
 
 
 def memory_region_get_ram_ptr(memory_region):
@@ -339,7 +352,7 @@ def memory_region_get_ram_ptr(memory_region):
         return (memory_region_get_ram_ptr(memory_region["alias"].dereference())
                 + memory_region["alias_offset"])
 
-    return qemu_map_ram_ptr(memory_region["ram_block"], 0)
+    return qemu_get_ram_ptr(memory_region["ram_block"]["offset"])
 
 
 def get_guest_phys_blocks():
index c8ce9b8..fb1f336 100644 (file)
@@ -33,10 +33,12 @@ if test -e "$output"; then
 fi
 
 for input; do
-  arrayname=xml_feature_$(echo $input | sed 's,.*/,,; s/[-.]/_/g')
+  arrayname=xml_feature_`echo $input | sed 's,.*/,,; s/[-.]/_/g'`
 
   ${AWK:-awk} 'BEGIN { n = 0
       printf "#include \"qemu/osdep.h\"\n"
+      printf "#include \"qemu-common.h\"\n"
+      printf "#include \"exec/gdbstub.h\"\n"
       print "static const char '$arrayname'[] = {"
       for (i = 0; i < 255; i++)
         _ord_[sprintf("%c", i)] = i
@@ -67,8 +69,8 @@ echo >> $output
 echo "const char *const xml_builtin[][2] = {" >> $output
 
 for input; do
-  basename=$(echo $input | sed 's,.*/,,')
-  arrayname=xml_feature_$(echo $input | sed 's,.*/,,; s/[-.]/_/g')
+  basename=`echo $input | sed 's,.*/,,'`
+  arrayname=xml_feature_`echo $input | sed 's,.*/,,; s/[-.]/_/g'`
   echo "  { \"$basename\", $arrayname }," >> $output
 done
 
diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
new file mode 100755 (executable)
index 0000000..27d217a
--- /dev/null
@@ -0,0 +1,827 @@
+#!/usr/bin/python
+#
+# top-like utility for displaying kvm statistics
+#
+# Copyright 2006-2008 Qumranet Technologies
+# Copyright 2008-2011 Red Hat, Inc.
+#
+# Authors:
+#  Avi Kivity <avi@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2.  See
+# the COPYING file in the top-level directory.
+
+import curses
+import sys
+import os
+import time
+import optparse
+import ctypes
+import fcntl
+import resource
+import struct
+import re
+from collections import defaultdict
+from time import sleep
+
+VMX_EXIT_REASONS = {
+    'EXCEPTION_NMI':        0,
+    'EXTERNAL_INTERRUPT':   1,
+    'TRIPLE_FAULT':         2,
+    'PENDING_INTERRUPT':    7,
+    'NMI_WINDOW':           8,
+    'TASK_SWITCH':          9,
+    'CPUID':                10,
+    'HLT':                  12,
+    'INVLPG':               14,
+    'RDPMC':                15,
+    'RDTSC':                16,
+    'VMCALL':               18,
+    'VMCLEAR':              19,
+    'VMLAUNCH':             20,
+    'VMPTRLD':              21,
+    'VMPTRST':              22,
+    'VMREAD':               23,
+    'VMRESUME':             24,
+    'VMWRITE':              25,
+    'VMOFF':                26,
+    'VMON':                 27,
+    'CR_ACCESS':            28,
+    'DR_ACCESS':            29,
+    'IO_INSTRUCTION':       30,
+    'MSR_READ':             31,
+    'MSR_WRITE':            32,
+    'INVALID_STATE':        33,
+    'MWAIT_INSTRUCTION':    36,
+    'MONITOR_INSTRUCTION':  39,
+    'PAUSE_INSTRUCTION':    40,
+    'MCE_DURING_VMENTRY':   41,
+    'TPR_BELOW_THRESHOLD':  43,
+    'APIC_ACCESS':          44,
+    'EPT_VIOLATION':        48,
+    'EPT_MISCONFIG':        49,
+    'WBINVD':               54,
+    'XSETBV':               55,
+    'APIC_WRITE':           56,
+    'INVPCID':              58,
+}
+
+SVM_EXIT_REASONS = {
+    'READ_CR0':       0x000,
+    'READ_CR3':       0x003,
+    'READ_CR4':       0x004,
+    'READ_CR8':       0x008,
+    'WRITE_CR0':      0x010,
+    'WRITE_CR3':      0x013,
+    'WRITE_CR4':      0x014,
+    'WRITE_CR8':      0x018,
+    'READ_DR0':       0x020,
+    'READ_DR1':       0x021,
+    'READ_DR2':       0x022,
+    'READ_DR3':       0x023,
+    'READ_DR4':       0x024,
+    'READ_DR5':       0x025,
+    'READ_DR6':       0x026,
+    'READ_DR7':       0x027,
+    'WRITE_DR0':      0x030,
+    'WRITE_DR1':      0x031,
+    'WRITE_DR2':      0x032,
+    'WRITE_DR3':      0x033,
+    'WRITE_DR4':      0x034,
+    'WRITE_DR5':      0x035,
+    'WRITE_DR6':      0x036,
+    'WRITE_DR7':      0x037,
+    'EXCP_BASE':      0x040,
+    'INTR':           0x060,
+    'NMI':            0x061,
+    'SMI':            0x062,
+    'INIT':           0x063,
+    'VINTR':          0x064,
+    'CR0_SEL_WRITE':  0x065,
+    'IDTR_READ':      0x066,
+    'GDTR_READ':      0x067,
+    'LDTR_READ':      0x068,
+    'TR_READ':        0x069,
+    'IDTR_WRITE':     0x06a,
+    'GDTR_WRITE':     0x06b,
+    'LDTR_WRITE':     0x06c,
+    'TR_WRITE':       0x06d,
+    'RDTSC':          0x06e,
+    'RDPMC':          0x06f,
+    'PUSHF':          0x070,
+    'POPF':           0x071,
+    'CPUID':          0x072,
+    'RSM':            0x073,
+    'IRET':           0x074,
+    'SWINT':          0x075,
+    'INVD':           0x076,
+    'PAUSE':          0x077,
+    'HLT':            0x078,
+    'INVLPG':         0x079,
+    'INVLPGA':        0x07a,
+    'IOIO':           0x07b,
+    'MSR':            0x07c,
+    'TASK_SWITCH':    0x07d,
+    'FERR_FREEZE':    0x07e,
+    'SHUTDOWN':       0x07f,
+    'VMRUN':          0x080,
+    'VMMCALL':        0x081,
+    'VMLOAD':         0x082,
+    'VMSAVE':         0x083,
+    'STGI':           0x084,
+    'CLGI':           0x085,
+    'SKINIT':         0x086,
+    'RDTSCP':         0x087,
+    'ICEBP':          0x088,
+    'WBINVD':         0x089,
+    'MONITOR':        0x08a,
+    'MWAIT':          0x08b,
+    'MWAIT_COND':     0x08c,
+    'XSETBV':         0x08d,
+    'NPF':            0x400,
+}
+
+# EC definition of HSR (from arch/arm64/include/asm/kvm_arm.h)
+AARCH64_EXIT_REASONS = {
+    'UNKNOWN':      0x00,
+    'WFI':          0x01,
+    'CP15_32':      0x03,
+    'CP15_64':      0x04,
+    'CP14_MR':      0x05,
+    'CP14_LS':      0x06,
+    'FP_ASIMD':     0x07,
+    'CP10_ID':      0x08,
+    'CP14_64':      0x0C,
+    'ILL_ISS':      0x0E,
+    'SVC32':        0x11,
+    'HVC32':        0x12,
+    'SMC32':        0x13,
+    'SVC64':        0x15,
+    'HVC64':        0x16,
+    'SMC64':        0x17,
+    'SYS64':        0x18,
+    'IABT':         0x20,
+    'IABT_HYP':     0x21,
+    'PC_ALIGN':     0x22,
+    'DABT':         0x24,
+    'DABT_HYP':     0x25,
+    'SP_ALIGN':     0x26,
+    'FP_EXC32':     0x28,
+    'FP_EXC64':     0x2C,
+    'SERROR':       0x2F,
+    'BREAKPT':      0x30,
+    'BREAKPT_HYP':  0x31,
+    'SOFTSTP':      0x32,
+    'SOFTSTP_HYP':  0x33,
+    'WATCHPT':      0x34,
+    'WATCHPT_HYP':  0x35,
+    'BKPT32':       0x38,
+    'VECTOR32':     0x3A,
+    'BRK64':        0x3C,
+}
+
+# From include/uapi/linux/kvm.h, KVM_EXIT_xxx
+USERSPACE_EXIT_REASONS = {
+    'UNKNOWN':          0,
+    'EXCEPTION':        1,
+    'IO':               2,
+    'HYPERCALL':        3,
+    'DEBUG':            4,
+    'HLT':              5,
+    'MMIO':             6,
+    'IRQ_WINDOW_OPEN':  7,
+    'SHUTDOWN':         8,
+    'FAIL_ENTRY':       9,
+    'INTR':             10,
+    'SET_TPR':          11,
+    'TPR_ACCESS':       12,
+    'S390_SIEIC':       13,
+    'S390_RESET':       14,
+    'DCR':              15,
+    'NMI':              16,
+    'INTERNAL_ERROR':   17,
+    'OSI':              18,
+    'PAPR_HCALL':       19,
+    'S390_UCONTROL':    20,
+    'WATCHDOG':         21,
+    'S390_TSCH':        22,
+    'EPR':              23,
+    'SYSTEM_EVENT':     24,
+}
+
+IOCTL_NUMBERS = {
+    'SET_FILTER':  0x40082406,
+    'ENABLE':      0x00002400,
+    'DISABLE':     0x00002401,
+    'RESET':       0x00002403,
+}
+
+class Arch(object):
+    """Class that encapsulates global architecture specific data like
+    syscall and ioctl numbers.
+
+    """
+    @staticmethod
+    def get_arch():
+        machine = os.uname()[4]
+
+        if machine.startswith('ppc'):
+            return ArchPPC()
+        elif machine.startswith('aarch64'):
+            return ArchA64()
+        elif machine.startswith('s390'):
+            return ArchS390()
+        else:
+            # X86_64
+            for line in open('/proc/cpuinfo'):
+                if not line.startswith('flags'):
+                    continue
+
+                flags = line.split()
+                if 'vmx' in flags:
+                    return ArchX86(VMX_EXIT_REASONS)
+                if 'svm' in flags:
+                    return ArchX86(SVM_EXIT_REASONS)
+                return
+
+class ArchX86(Arch):
+    def __init__(self, exit_reasons):
+        self.sc_perf_evt_open = 298
+        self.ioctl_numbers = IOCTL_NUMBERS
+        self.exit_reasons = exit_reasons
+
+class ArchPPC(Arch):
+    def __init__(self):
+        self.sc_perf_evt_open = 319
+        self.ioctl_numbers = IOCTL_NUMBERS
+        self.ioctl_numbers['ENABLE'] = 0x20002400
+        self.ioctl_numbers['DISABLE'] = 0x20002401
+        self.ioctl_numbers['RESET'] = 0x20002403
+
+        # PPC comes in 32 and 64 bit and some generated ioctl
+        # numbers depend on the wordsize.
+        char_ptr_size = ctypes.sizeof(ctypes.c_char_p)
+        self.ioctl_numbers['SET_FILTER'] = 0x80002406 | char_ptr_size << 16
+        self.exit_reasons = {}
+
+class ArchA64(Arch):
+    def __init__(self):
+        self.sc_perf_evt_open = 241
+        self.ioctl_numbers = IOCTL_NUMBERS
+        self.exit_reasons = AARCH64_EXIT_REASONS
+
+class ArchS390(Arch):
+    def __init__(self):
+        self.sc_perf_evt_open = 331
+        self.ioctl_numbers = IOCTL_NUMBERS
+        self.exit_reasons = None
+
+ARCH = Arch.get_arch()
+
+
+def walkdir(path):
+    """Returns os.walk() data for specified directory.
+
+    As it is only a wrapper it returns the same 3-tuple of (dirpath,
+    dirnames, filenames).
+    """
+    return next(os.walk(path))
+
+
+def parse_int_list(list_string):
+    """Returns an int list from a string of comma separated integers and
+    integer ranges."""
+    integers = []
+    members = list_string.split(',')
+
+    for member in members:
+        if '-' not in member:
+            integers.append(int(member))
+        else:
+            int_range = member.split('-')
+            integers.extend(range(int(int_range[0]),
+                                  int(int_range[1]) + 1))
+
+    return integers
+
+
+def get_online_cpus():
+    with open('/sys/devices/system/cpu/online') as cpu_list:
+        cpu_string = cpu_list.readline()
+        return parse_int_list(cpu_string)
+
+
+def get_filters():
+    filters = {}
+    filters['kvm_userspace_exit'] = ('reason', USERSPACE_EXIT_REASONS)
+    if ARCH.exit_reasons:
+        filters['kvm_exit'] = ('exit_reason', ARCH.exit_reasons)
+    return filters
+
+libc = ctypes.CDLL('libc.so.6', use_errno=True)
+syscall = libc.syscall
+
+class perf_event_attr(ctypes.Structure):
+    _fields_ = [('type', ctypes.c_uint32),
+                ('size', ctypes.c_uint32),
+                ('config', ctypes.c_uint64),
+                ('sample_freq', ctypes.c_uint64),
+                ('sample_type', ctypes.c_uint64),
+                ('read_format', ctypes.c_uint64),
+                ('flags', ctypes.c_uint64),
+                ('wakeup_events', ctypes.c_uint32),
+                ('bp_type', ctypes.c_uint32),
+                ('bp_addr', ctypes.c_uint64),
+                ('bp_len', ctypes.c_uint64),
+                ]
+
+    def __init__(self):
+        super(self.__class__, self).__init__()
+        self.type = PERF_TYPE_TRACEPOINT
+        self.size = ctypes.sizeof(self)
+        self.read_format = PERF_FORMAT_GROUP
+
+def perf_event_open(attr, pid, cpu, group_fd, flags):
+    return syscall(ARCH.sc_perf_evt_open, ctypes.pointer(attr),
+                   ctypes.c_int(pid), ctypes.c_int(cpu),
+                   ctypes.c_int(group_fd), ctypes.c_long(flags))
+
+PERF_TYPE_TRACEPOINT = 2
+PERF_FORMAT_GROUP = 1 << 3
+
+PATH_DEBUGFS_TRACING = '/sys/kernel/debug/tracing'
+PATH_DEBUGFS_KVM = '/sys/kernel/debug/kvm'
+
+class Group(object):
+    def __init__(self):
+        self.events = []
+
+    def add_event(self, event):
+        self.events.append(event)
+
+    def read(self):
+        length = 8 * (1 + len(self.events))
+        read_format = 'xxxxxxxx' + 'Q' * len(self.events)
+        return dict(zip([event.name for event in self.events],
+                        struct.unpack(read_format,
+                                      os.read(self.events[0].fd, length))))
+
+class Event(object):
+    def __init__(self, name, group, trace_cpu, trace_point, trace_filter,
+                 trace_set='kvm'):
+        self.name = name
+        self.fd = None
+        self.setup_event(group, trace_cpu, trace_point, trace_filter,
+                         trace_set)
+
+    def setup_event_attribute(self, trace_set, trace_point):
+        id_path = os.path.join(PATH_DEBUGFS_TRACING, 'events', trace_set,
+                               trace_point, 'id')
+
+        event_attr = perf_event_attr()
+        event_attr.config = int(open(id_path).read())
+        return event_attr
+
+    def setup_event(self, group, trace_cpu, trace_point, trace_filter,
+                    trace_set):
+        event_attr = self.setup_event_attribute(trace_set, trace_point)
+
+        group_leader = -1
+        if group.events:
+            group_leader = group.events[0].fd
+
+        fd = perf_event_open(event_attr, -1, trace_cpu,
+                             group_leader, 0)
+        if fd == -1:
+            err = ctypes.get_errno()
+            raise OSError(err, os.strerror(err),
+                          'while calling sys_perf_event_open().')
+
+        if trace_filter:
+            fcntl.ioctl(fd, ARCH.ioctl_numbers['SET_FILTER'],
+                        trace_filter)
+
+        self.fd = fd
+
+    def enable(self):
+        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['ENABLE'], 0)
+
+    def disable(self):
+        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['DISABLE'], 0)
+
+    def reset(self):
+        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['RESET'], 0)
+
+class TracepointProvider(object):
+    def __init__(self):
+        self.group_leaders = []
+        self.filters = get_filters()
+        self._fields = self.get_available_fields()
+        self.setup_traces()
+        self.fields = self._fields
+
+    def get_available_fields(self):
+        path = os.path.join(PATH_DEBUGFS_TRACING, 'events', 'kvm')
+        fields = walkdir(path)[1]
+        extra = []
+        for field in fields:
+            if field in self.filters:
+                filter_name_, filter_dicts = self.filters[field]
+                for name in filter_dicts:
+                    extra.append(field + '(' + name + ')')
+        fields += extra
+        return fields
+
+    def setup_traces(self):
+        cpus = get_online_cpus()
+
+        # The constant is needed as a buffer for python libs, std
+        # streams and other files that the script opens.
+        newlim = len(cpus) * len(self._fields) + 50
+        try:
+            softlim_, hardlim = resource.getrlimit(resource.RLIMIT_NOFILE)
+
+            if hardlim < newlim:
+                # Now we need CAP_SYS_RESOURCE, to increase the hard limit.
+                resource.setrlimit(resource.RLIMIT_NOFILE, (newlim, newlim))
+            else:
+                # Raising the soft limit is sufficient.
+                resource.setrlimit(resource.RLIMIT_NOFILE, (newlim, hardlim))
+
+        except ValueError:
+            sys.exit("NOFILE rlimit could not be raised to {0}".format(newlim))
+
+        for cpu in cpus:
+            group = Group()
+            for name in self._fields:
+                tracepoint = name
+                tracefilter = None
+                match = re.match(r'(.*)\((.*)\)', name)
+                if match:
+                    tracepoint, sub = match.groups()
+                    tracefilter = ('%s==%d\0' %
+                                   (self.filters[tracepoint][0],
+                                    self.filters[tracepoint][1][sub]))
+
+                group.add_event(Event(name=name,
+                                      group=group,
+                                      trace_cpu=cpu,
+                                      trace_point=tracepoint,
+                                      trace_filter=tracefilter))
+            self.group_leaders.append(group)
+
+    def available_fields(self):
+        return self.get_available_fields()
+
+    @property
+    def fields(self):
+        return self._fields
+
+    @fields.setter
+    def fields(self, fields):
+        self._fields = fields
+        for group in self.group_leaders:
+            for index, event in enumerate(group.events):
+                if event.name in fields:
+                    event.reset()
+                    event.enable()
+                else:
+                    # Do not disable the group leader.
+                    # It would disable all of its events.
+                    if index != 0:
+                        event.disable()
+
+    def read(self):
+        ret = defaultdict(int)
+        for group in self.group_leaders:
+            for name, val in group.read().iteritems():
+                if name in self._fields:
+                    ret[name] += val
+        return ret
+
+class DebugfsProvider(object):
+    def __init__(self):
+        self._fields = self.get_available_fields()
+
+    def get_available_fields(self):
+        return walkdir(PATH_DEBUGFS_KVM)[2]
+
+    @property
+    def fields(self):
+        return self._fields
+
+    @fields.setter
+    def fields(self, fields):
+        self._fields = fields
+
+    def read(self):
+        def val(key):
+            return int(file(PATH_DEBUGFS_KVM + '/' + key).read())
+        return dict([(key, val(key)) for key in self._fields])
+
+class Stats(object):
+    def __init__(self, providers, fields=None):
+        self.providers = providers
+        self._fields_filter = fields
+        self.values = {}
+        self.update_provider_filters()
+
+    def update_provider_filters(self):
+        def wanted(key):
+            if not self._fields_filter:
+                return True
+            return re.match(self._fields_filter, key) is not None
+
+        # As we reset the counters when updating the fields we can
+        # also clear the cache of old values.
+        self.values = {}
+        for provider in self.providers:
+            provider_fields = [key for key in provider.get_available_fields()
+                               if wanted(key)]
+            provider.fields = provider_fields
+
+    @property
+    def fields_filter(self):
+        return self._fields_filter
+
+    @fields_filter.setter
+    def fields_filter(self, fields_filter):
+        self._fields_filter = fields_filter
+        self.update_provider_filters()
+
+    def get(self):
+        for provider in self.providers:
+            new = provider.read()
+            for key in provider.fields:
+                oldval = self.values.get(key, (0, 0))
+                newval = new.get(key, 0)
+                newdelta = None
+                if oldval is not None:
+                    newdelta = newval - oldval[0]
+                self.values[key] = (newval, newdelta)
+        return self.values
+
+LABEL_WIDTH = 40
+NUMBER_WIDTH = 10
+
+class Tui(object):
+    def __init__(self, stats):
+        self.stats = stats
+        self.screen = None
+        self.drilldown = False
+        self.update_drilldown()
+
+    def __enter__(self):
+        """Initialises curses for later use.  Based on curses.wrapper
+           implementation from the Python standard library."""
+        self.screen = curses.initscr()
+        curses.noecho()
+        curses.cbreak()
+
+        # The try/catch works around a minor bit of
+        # over-conscientiousness in the curses module, the error
+        # return from C start_color() is ignorable.
+        try:
+            curses.start_color()
+        except:
+            pass
+
+        curses.use_default_colors()
+        return self
+
+    def __exit__(self, *exception):
+        """Resets the terminal to its normal state.  Based on curses.wrappre
+           implementation from the Python standard library."""
+        if self.screen:
+            self.screen.keypad(0)
+            curses.echo()
+            curses.nocbreak()
+            curses.endwin()
+
+    def update_drilldown(self):
+        if not self.stats.fields_filter:
+            self.stats.fields_filter = r'^[^\(]*$'
+
+        elif self.stats.fields_filter == r'^[^\(]*$':
+            self.stats.fields_filter = None
+
+    def refresh(self, sleeptime):
+        self.screen.erase()
+        self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
+        self.screen.addstr(2, 1, 'Event')
+        self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH -
+                           len('Total'), 'Total')
+        self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 -
+                           len('Current'), 'Current')
+        row = 3
+        stats = self.stats.get()
+        def sortkey(x):
+            if stats[x][1]:
+                return (-stats[x][1], -stats[x][0])
+            else:
+                return (0, -stats[x][0])
+        for key in sorted(stats.keys(), key=sortkey):
+
+            if row >= self.screen.getmaxyx()[0]:
+                break
+            values = stats[key]
+            if not values[0] and not values[1]:
+                break
+            col = 1
+            self.screen.addstr(row, col, key)
+            col += LABEL_WIDTH
+            self.screen.addstr(row, col, '%10d' % (values[0],))
+            col += NUMBER_WIDTH
+            if values[1] is not None:
+                self.screen.addstr(row, col, '%8d' % (values[1] / sleeptime,))
+            row += 1
+        self.screen.refresh()
+
+    def show_filter_selection(self):
+        while True:
+            self.screen.erase()
+            self.screen.addstr(0, 0,
+                               "Show statistics for events matching a regex.",
+                               curses.A_BOLD)
+            self.screen.addstr(2, 0,
+                               "Current regex: {0}"
+                               .format(self.stats.fields_filter))
+            self.screen.addstr(3, 0, "New regex: ")
+            curses.echo()
+            regex = self.screen.getstr()
+            curses.noecho()
+            if len(regex) == 0:
+                return
+            try:
+                re.compile(regex)
+                self.stats.fields_filter = regex
+                return
+            except re.error:
+                continue
+
+    def show_stats(self):
+        sleeptime = 0.25
+        while True:
+            self.refresh(sleeptime)
+            curses.halfdelay(int(sleeptime * 10))
+            sleeptime = 3
+            try:
+                char = self.screen.getkey()
+                if char == 'x':
+                    self.drilldown = not self.drilldown
+                    self.update_drilldown()
+                if char == 'q':
+                    break
+                if char == 'f':
+                    self.show_filter_selection()
+            except KeyboardInterrupt:
+                break
+            except curses.error:
+                continue
+
+def batch(stats):
+    s = stats.get()
+    time.sleep(1)
+    s = stats.get()
+    for key in sorted(s.keys()):
+        values = s[key]
+        print '%-42s%10d%10d' % (key, values[0], values[1])
+
+def log(stats):
+    keys = sorted(stats.get().iterkeys())
+    def banner():
+        for k in keys:
+            print '%s' % k,
+        print
+    def statline():
+        s = stats.get()
+        for k in keys:
+            print ' %9d' % s[k][1],
+        print
+    line = 0
+    banner_repeat = 20
+    while True:
+        time.sleep(1)
+        if line % banner_repeat == 0:
+            banner()
+        statline()
+        line += 1
+
+def get_options():
+    description_text = """
+This script displays various statistics about VMs running under KVM.
+The statistics are gathered from the KVM debugfs entries and / or the
+currently available perf traces.
+
+The monitoring takes additional cpu cycles and might affect the VM's
+performance.
+
+Requirements:
+- Access to:
+    /sys/kernel/debug/kvm
+    /sys/kernel/debug/trace/events/*
+    /proc/pid/task
+- /proc/sys/kernel/perf_event_paranoid < 1 if user has no
+  CAP_SYS_ADMIN and perf events are used.
+- CAP_SYS_RESOURCE if the hard limit is not high enough to allow
+  the large number of files that are possibly opened.
+"""
+
+    class PlainHelpFormatter(optparse.IndentedHelpFormatter):
+        def format_description(self, description):
+            if description:
+                return description + "\n"
+            else:
+                return ""
+
+    optparser = optparse.OptionParser(description=description_text,
+                                      formatter=PlainHelpFormatter())
+    optparser.add_option('-1', '--once', '--batch',
+                         action='store_true',
+                         default=False,
+                         dest='once',
+                         help='run in batch mode for one second',
+                         )
+    optparser.add_option('-l', '--log',
+                         action='store_true',
+                         default=False,
+                         dest='log',
+                         help='run in logging mode (like vmstat)',
+                         )
+    optparser.add_option('-t', '--tracepoints',
+                         action='store_true',
+                         default=False,
+                         dest='tracepoints',
+                         help='retrieve statistics from tracepoints',
+                         )
+    optparser.add_option('-d', '--debugfs',
+                         action='store_true',
+                         default=False,
+                         dest='debugfs',
+                         help='retrieve statistics from debugfs',
+                         )
+    optparser.add_option('-f', '--fields',
+                         action='store',
+                         default=None,
+                         dest='fields',
+                         help='fields to display (regex)',
+                         )
+    (options, _) = optparser.parse_args(sys.argv)
+    return options
+
+def get_providers(options):
+    providers = []
+
+    if options.tracepoints:
+        providers.append(TracepointProvider())
+    if options.debugfs:
+        providers.append(DebugfsProvider())
+    if len(providers) == 0:
+        providers.append(TracepointProvider())
+
+    return providers
+
+def check_access(options):
+    if not os.path.exists('/sys/kernel/debug'):
+        sys.stderr.write('Please enable CONFIG_DEBUG_FS in your kernel.')
+        sys.exit(1)
+
+    if not os.path.exists(PATH_DEBUGFS_KVM):
+        sys.stderr.write("Please make sure, that debugfs is mounted and "
+                         "readable by the current user:\n"
+                         "('mount -t debugfs debugfs /sys/kernel/debug')\n"
+                         "Also ensure, that the kvm modules are loaded.\n")
+        sys.exit(1)
+
+    if not os.path.exists(PATH_DEBUGFS_TRACING) and (options.tracepoints
+                                                     or not options.debugfs):
+        sys.stderr.write("Please enable CONFIG_TRACING in your kernel "
+                         "when using the option -t (default).\n"
+                         "If it is enabled, make {0} readable by the "
+                         "current user.\n"
+                         .format(PATH_DEBUGFS_TRACING))
+        if options.tracepoints:
+            sys.exit(1)
+
+        sys.stderr.write("Falling back to debugfs statistics!\n")
+        options.debugfs = True
+        sleep(5)
+
+    return options
+
+def main():
+    options = get_options()
+    options = check_access(options)
+    providers = get_providers(options)
+    stats = Stats(providers, fields=options.fields)
+
+    if options.log:
+        log(stats)
+    elif not options.once:
+        with Tui(stats) as tui:
+            tui.show_stats()
+    else:
+        batch(stats)
+
+if __name__ == "__main__":
+    main()
diff --git a/scripts/kvm/kvm_stat.texi b/scripts/kvm/kvm_stat.texi
new file mode 100644 (file)
index 0000000..6ce00d8
--- /dev/null
@@ -0,0 +1,55 @@
+@example
+@c man begin SYNOPSIS
+usage: kvm_stat [OPTION]...
+@c man end
+@end example
+
+@c man begin DESCRIPTION
+
+kvm_stat prints counts of KVM kernel module trace events.  These events signify
+state transitions such as guest mode entry and exit.
+
+This tool is useful for observing guest behavior from the host perspective.
+Often conclusions about performance or buggy behavior can be drawn from the
+output.
+
+The set of KVM kernel module trace events may be specific to the kernel version
+or architecture.  It is best to check the KVM kernel module source code for the
+meaning of events.
+
+Note that trace events are counted globally across all running guests.
+
+@c man end
+
+@c man begin OPTIONS
+@table @option
+@item -1, --once, --batch
+  run in batch mode for one second
+@item -l, --log
+  run in logging mode (like vmstat)
+@item -t, --tracepoints
+  retrieve statistics from tracepoints
+@item -d, --debugfs
+  retrieve statistics from debugfs
+@item -f, --fields=@var{fields}
+  fields to display (regex)
+@item -h, --help
+  show help message
+@end table
+
+@c man end
+
+@ignore
+
+@setfilename kvm_stat
+@settitle Report KVM kernel module event counters.
+
+@c man begin AUTHOR
+Stefan Hajnoczi <stefanha@redhat.com>
+@c man end
+
+@c man begin SEEALSO
+perf(1), trace-cmd(1)
+@c man end
+
+@end ignore
index 354af31..c1afb3f 100644 (file)
@@ -7,7 +7,7 @@
 src=$1
 dep=$2
 target=$3
-src_dir=$(dirname $src)
+src_dir=`dirname $src`
 all_includes=
 
 process_includes () {
@@ -20,7 +20,7 @@ process_includes () {
 
 f=$src
 while [ -n "$f" ] ; do
-  f=$(cat $f | tr -d '\r' | awk '/^include / {printf "'$src_dir'/%s ", $2}')
+  f=`cat $f | tr -d '\r' | awk '/^include / {printf "'$src_dir'/%s ", $2}'`
   [ $? = 0 ] || exit 1
   all_includes="$all_includes $f"
 done
index a06a2c4..b570069 100644 (file)
@@ -16,23 +16,20 @@ from qapi import *
 import re
 
 
-def gen_command_decl(name, arg_type, boxed, ret_type):
+def gen_command_decl(name, arg_type, ret_type):
     return mcgen('''
 %(c_type)s qmp_%(c_name)s(%(params)s);
 ''',
                  c_type=(ret_type and ret_type.c_type()) or 'void',
                  c_name=c_name(name),
-                 params=gen_params(arg_type, boxed, 'Error **errp'))
+                 params=gen_params(arg_type, 'Error **errp'))
 
 
-def gen_call(name, arg_type, boxed, ret_type):
+def gen_call(name, arg_type, ret_type):
     ret = ''
 
     argstr = ''
-    if boxed:
-        assert arg_type and not arg_type.is_empty()
-        argstr = '&arg, '
-    elif arg_type:
+    if arg_type:
         assert not arg_type.variants
         for memb in arg_type.members:
             if memb.optional:
@@ -49,10 +46,8 @@ def gen_call(name, arg_type, boxed, ret_type):
 ''',
                 c_name=c_name(name), args=argstr, lhs=lhs)
     if ret_type:
+        ret += gen_err_check()
         ret += mcgen('''
-    if (err) {
-        goto out;
-    }
 
     qmp_marshal_output_%(c_name)s(retval, ret, &err);
 ''',
@@ -66,18 +61,24 @@ def gen_marshal_output(ret_type):
 static void qmp_marshal_output_%(c_name)s(%(c_type)s ret_in, QObject **ret_out, Error **errp)
 {
     Error *err = NULL;
+    QmpOutputVisitor *qov = qmp_output_visitor_new();
+    QapiDeallocVisitor *qdv;
     Visitor *v;
 
-    v = qmp_output_visitor_new(ret_out);
+    v = qmp_output_get_visitor(qov);
     visit_type_%(c_name)s(v, "unused", &ret_in, &err);
-    if (!err) {
-        visit_complete(v, ret_out);
+    if (err) {
+        goto out;
     }
+    *ret_out = qmp_output_get_qobject(qov);
+
+out:
     error_propagate(errp, err);
-    visit_free(v);
-    v = qapi_dealloc_visitor_new();
+    qmp_output_visitor_cleanup(qov);
+    qdv = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(qdv);
     visit_type_%(c_name)s(v, "unused", &ret_in, NULL);
-    visit_free(v);
+    qapi_dealloc_visitor_cleanup(qdv);
 }
 ''',
                  c_type=ret_type.c_type(), c_name=ret_type.c_name())
@@ -97,7 +98,7 @@ def gen_marshal_decl(name):
                  proto=gen_marshal_proto(name))
 
 
-def gen_marshal(name, arg_type, boxed, ret_type):
+def gen_marshal(name, arg_type, ret_type):
     ret = mcgen('''
 
 %(proto)s
@@ -112,21 +113,15 @@ def gen_marshal(name, arg_type, boxed, ret_type):
 ''',
                      c_type=ret_type.c_type())
 
-    if arg_type and not arg_type.is_empty():
+    if arg_type and arg_type.members:
         ret += mcgen('''
+    QmpInputVisitor *qiv = qmp_input_visitor_new_strict(QOBJECT(args));
+    QapiDeallocVisitor *qdv;
     Visitor *v;
     %(c_name)s arg = {0};
 
-    v = qmp_input_visitor_new(QOBJECT(args), true);
-    visit_start_struct(v, NULL, NULL, 0, &err);
-    if (err) {
-        goto out;
-    }
+    v = qmp_input_get_visitor(qiv);
     visit_type_%(c_name)s_members(v, &arg, &err);
-    if (!err) {
-        visit_check_struct(v, &err);
-    }
-    visit_end_struct(v, NULL);
     if (err) {
         goto out;
     }
@@ -139,10 +134,10 @@ def gen_marshal(name, arg_type, boxed, ret_type):
     (void)args;
 ''')
 
-    ret += gen_call(name, arg_type, boxed, ret_type)
+    ret += gen_call(name, arg_type, ret_type)
 
     # 'goto out' produced above for arg_type, and by gen_call() for ret_type
-    if (arg_type and not arg_type.is_empty()) or ret_type:
+    if (arg_type and arg_type.members) or ret_type:
         ret += mcgen('''
 
 out:
@@ -150,14 +145,13 @@ out:
     ret += mcgen('''
     error_propagate(errp, err);
 ''')
-    if arg_type and not arg_type.is_empty():
+    if arg_type and arg_type.members:
         ret += mcgen('''
-    visit_free(v);
-    v = qapi_dealloc_visitor_new();
-    visit_start_struct(v, NULL, NULL, 0, NULL);
+    qmp_input_visitor_cleanup(qiv);
+    qdv = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(qdv);
     visit_type_%(c_name)s_members(v, &arg, NULL);
-    visit_end_struct(v, NULL);
-    visit_free(v);
+    qapi_dealloc_visitor_cleanup(qdv);
 ''',
                      c_name=arg_type.c_name())
 
@@ -215,16 +209,16 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
         self._visited_ret_types = None
 
     def visit_command(self, name, info, arg_type, ret_type,
-                      gen, success_response, boxed):
+                      gen, success_response):
         if not gen:
             return
-        self.decl += gen_command_decl(name, arg_type, boxed, ret_type)
+        self.decl += gen_command_decl(name, arg_type, ret_type)
         if ret_type and ret_type not in self._visited_ret_types:
             self._visited_ret_types.add(ret_type)
             self.defn += gen_marshal_output(ret_type)
         if middle_mode:
             self.decl += gen_marshal_decl(name)
-        self.defn += gen_marshal(name, arg_type, boxed, ret_type)
+        self.defn += gen_marshal(name, arg_type, ret_type)
         if not middle_mode:
             self._regy += gen_register_command(name, success_response)
 
index 38d8211..9b5c5b5 100644 (file)
 from qapi import *
 
 
-def gen_event_send_proto(name, arg_type, boxed):
+def gen_event_send_proto(name, arg_type):
     return 'void qapi_event_send_%(c_name)s(%(param)s)' % {
         'c_name': c_name(name.lower()),
-        'param': gen_params(arg_type, boxed, 'Error **errp')}
+        'param': gen_params(arg_type, 'Error **errp')}
 
 
-def gen_event_send_decl(name, arg_type, boxed):
+def gen_event_send_decl(name, arg_type):
     return mcgen('''
 
 %(proto)s;
 ''',
-                 proto=gen_event_send_proto(name, arg_type, boxed))
+                 proto=gen_event_send_proto(name, arg_type))
 
 
 # Declare and initialize an object 'qapi' using parameters from gen_params()
@@ -49,15 +49,10 @@ def gen_param_var(typ):
 
     };
 ''')
-    if not typ.is_implicit():
-        ret += mcgen('''
-    %(c_name)s *arg = &param;
-''',
-                     c_name=typ.c_name())
     return ret
 
 
-def gen_event_send(name, arg_type, boxed):
+def gen_event_send(name, arg_type):
     # FIXME: Our declaration of local variables (and of 'errp' in the
     # parameter list) can collide with exploded members of the event's
     # data type passed in as parameters.  If this collision ever hits in
@@ -72,17 +67,14 @@ def gen_event_send(name, arg_type, boxed):
     Error *err = NULL;
     QMPEventFuncEmit emit;
 ''',
-                proto=gen_event_send_proto(name, arg_type, boxed))
+                proto=gen_event_send_proto(name, arg_type))
 
-    if arg_type and not arg_type.is_empty():
+    if arg_type and arg_type.members:
         ret += mcgen('''
-    QObject *obj;
+    QmpOutputVisitor *qov;
     Visitor *v;
 ''')
-        if not boxed:
-            ret += gen_param_var(arg_type)
-    else:
-        assert not boxed
+        ret += gen_param_var(arg_type)
 
     ret += mcgen('''
 
@@ -96,37 +88,24 @@ def gen_event_send(name, arg_type, boxed):
 ''',
                  name=name)
 
-    if arg_type and not arg_type.is_empty():
+    if arg_type and arg_type.members:
         ret += mcgen('''
-    v = qmp_output_visitor_new(&obj);
-''')
-        if not arg_type.is_implicit():
-            ret += mcgen('''
-    visit_type_%(c_name)s(v, "%(name)s", &arg, &err);
-''',
-                         name=name, c_name=arg_type.c_name())
-        else:
-            ret += mcgen('''
+    qov = qmp_output_visitor_new();
+    v = qmp_output_get_visitor(qov);
 
     visit_start_struct(v, "%(name)s", NULL, 0, &err);
     if (err) {
         goto out;
     }
     visit_type_%(c_name)s_members(v, &param, &err);
-    if (!err) {
-        visit_check_struct(v, &err);
-    }
-    visit_end_struct(v, NULL);
-''',
-                         name=name, c_name=arg_type.c_name())
-        ret += mcgen('''
+    visit_end_struct(v, err ? NULL : &err);
     if (err) {
         goto out;
     }
 
-    visit_complete(v, &obj);
-    qdict_put_obj(qmp, "data", obj);
-''')
+    qdict_put_obj(qmp, "data", qmp_output_get_qobject(qov));
+''',
+                     name=name, c_name=arg_type.c_name())
 
     ret += mcgen('''
     emit(%(c_enum)s, qmp, &err);
@@ -134,10 +113,10 @@ def gen_event_send(name, arg_type, boxed):
 ''',
                  c_enum=c_enum_const(event_enum_name, name))
 
-    if arg_type and not arg_type.is_empty():
+    if arg_type and arg_type.members:
         ret += mcgen('''
 out:
-    visit_free(v);
+    qmp_output_visitor_cleanup(qov);
 ''')
     ret += mcgen('''
     error_propagate(errp, err);
@@ -163,9 +142,9 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
         self.defn += gen_enum_lookup(event_enum_name, self._event_names)
         self._event_names = None
 
-    def visit_event(self, name, info, arg_type, boxed):
-        self.decl += gen_event_send_decl(name, arg_type, boxed)
-        self.defn += gen_event_send(name, arg_type, boxed)
+    def visit_event(self, name, info, arg_type):
+        self.decl += gen_event_send_decl(name, arg_type)
+        self.defn += gen_event_send(name, arg_type)
         self._event_names.append(name)
 
 
index 541644e..e0f926b 100644 (file)
@@ -154,14 +154,14 @@ const char %(c_name)s[] = %(c_string)s;
                                     for m in variants.variants]})
 
     def visit_command(self, name, info, arg_type, ret_type,
-                      gen, success_response, boxed):
+                      gen, success_response):
         arg_type = arg_type or self._schema.the_empty_object_type
         ret_type = ret_type or self._schema.the_empty_object_type
         self._gen_json(name, 'command',
                        {'arg-type': self._use_type(arg_type),
                         'ret-type': self._use_type(ret_type)})
 
-    def visit_event(self, name, info, arg_type, boxed):
+    def visit_event(self, name, info, arg_type):
         arg_type = arg_type or self._schema.the_empty_object_type
         self._gen_json(name, 'event', {'arg-type': self._use_type(arg_type)})
 
index dabc42e..437cf6c 100644 (file)
@@ -91,7 +91,7 @@ struct %(c_name)s {
     # potential issues with attempting to malloc space for zero-length
     # structs in C, and also incompatibility with C++ (where an empty
     # struct is size 1).
-    if (not base or base.is_empty()) and not members and not variants:
+    if not (base and base.members) and not members and not variants:
         ret += mcgen('''
     char qapi_dummy_for_empty_struct;
 ''')
@@ -150,15 +150,17 @@ def gen_type_cleanup(name):
 
 void qapi_free_%(c_name)s(%(c_name)s *obj)
 {
+    QapiDeallocVisitor *qdv;
     Visitor *v;
 
     if (!obj) {
         return;
     }
 
-    v = qapi_dealloc_visitor_new();
+    qdv = qapi_dealloc_visitor_new();
+    v = qapi_dealloc_get_visitor(qdv);
     visit_type_%(c_name)s(v, NULL, &obj, NULL);
-    visit_free(v);
+    qapi_dealloc_visitor_cleanup(qdv);
 }
 ''',
                 c_name=c_name(name))
index 96f2491..6c1c1fb 100644 (file)
@@ -47,11 +47,9 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
     if base:
         ret += mcgen('''
     visit_type_%(c_type)s_members(v, (%(c_type)s *)obj, &err);
-    if (err) {
-        goto out;
-    }
 ''',
                      c_type=base.c_name())
+        ret += gen_err_check()
 
     for memb in members:
         if memb.optional:
@@ -62,12 +60,10 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
             push_indent()
         ret += mcgen('''
     visit_type_%(c_type)s(v, "%(name)s", &obj->%(c_name)s, &err);
-    if (err) {
-        goto out;
-    }
 ''',
                      c_type=memb.type.c_name(), name=memb.name,
                      c_name=c_name(memb.name))
+        ret += gen_err_check()
         if memb.optional:
             pop_indent()
             ret += mcgen('''
@@ -112,32 +108,30 @@ out:
 
 
 def gen_visit_list(name, element_type):
+    # FIXME: if *obj is NULL on entry, and the first visit_next_list()
+    # assigns to *obj, while a later one fails, we should clean up *obj
+    # rather than leaving it non-NULL. As currently written, the caller must
+    # call qapi_free_FOOList() to avoid a memory leak of the partial FOOList.
     return mcgen('''
 
 void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp)
 {
     Error *err = NULL;
-    %(c_name)s *tail;
-    size_t size = sizeof(**obj);
+    GenericList *i, **prev;
 
-    visit_start_list(v, name, (GenericList **)obj, size, &err);
+    visit_start_list(v, name, &err);
     if (err) {
         goto out;
     }
 
-    for (tail = *obj; tail;
-         tail = (%(c_name)s *)visit_next_list(v, (GenericList *)tail, size)) {
-        visit_type_%(c_elt_type)s(v, NULL, &tail->value, &err);
-        if (err) {
-            break;
-        }
+    for (prev = (GenericList **)obj;
+         !err && (i = visit_next_list(v, prev, sizeof(**obj))) != NULL;
+         prev = &i) {
+        %(c_name)s *native_i = (%(c_name)s *)i;
+        visit_type_%(c_elt_type)s(v, NULL, &native_i->value, &err);
     }
 
-    visit_end_list(v, (void **)obj);
-    if (err && visit_is_input(v)) {
-        qapi_free_%(c_name)s(*obj);
-        *obj = NULL;
-    }
+    visit_end_list(v);
 out:
     error_propagate(errp, err);
 }
@@ -195,10 +189,9 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error
             break;
         }
         visit_type_%(c_type)s_members(v, &(*obj)->u.%(c_name)s, &err);
-        if (!err) {
-            visit_check_struct(v, &err);
-        }
-        visit_end_struct(v, NULL);
+        error_propagate(errp, err);
+        err = NULL;
+        visit_end_struct(v, &err);
 ''',
                          c_type=var.type.c_name(),
                          c_name=c_name(var.name))
@@ -220,21 +213,21 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error
                    "%(name)s");
     }
 out_obj:
-    visit_end_alternate(v, (void **)obj);
-    if (err && visit_is_input(v)) {
-        qapi_free_%(c_name)s(*obj);
-        *obj = NULL;
-    }
+    visit_end_alternate(v);
 out:
     error_propagate(errp, err);
 }
 ''',
-                 name=name, c_name=c_name(name))
+                 name=name)
 
     return ret
 
 
 def gen_visit_object(name, base, members, variants):
+    # FIXME: if *obj is NULL on entry, and visit_start_struct() assigns to
+    # *obj, but then visit_type_FOO_members() fails, we should clean up *obj
+    # rather than leaving it non-NULL. As currently written, the caller must
+    # call qapi_free_FOO() to avoid a memory leak of the partial FOO.
     return mcgen('''
 
 void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp)
@@ -249,16 +242,10 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error
         goto out_obj;
     }
     visit_type_%(c_name)s_members(v, *obj, &err);
-    if (err) {
-        goto out_obj;
-    }
-    visit_check_struct(v, &err);
+    error_propagate(errp, err);
+    err = NULL;
 out_obj:
-    visit_end_struct(v, (void **)obj);
-    if (err && visit_is_input(v)) {
-        qapi_free_%(c_name)s(*obj);
-        *obj = NULL;
-    }
+    visit_end_struct(v, &err);
 out:
     error_propagate(errp, err);
 }
index 21bc32f..b13ae47 100644 (file)
@@ -522,14 +522,10 @@ def check_type(expr_info, source, value, allow_array=False,
 
 def check_command(expr, expr_info):
     name = expr['command']
-    boxed = expr.get('boxed', False)
 
-    args_meta = ['struct']
-    if boxed:
-        args_meta += ['union', 'alternate']
     check_type(expr_info, "'data' for command '%s'" % name,
-               expr.get('data'), allow_dict=not boxed, allow_optional=True,
-               allow_metas=args_meta)
+               expr.get('data'), allow_dict=True, allow_optional=True,
+               allow_metas=['struct'])
     returns_meta = ['union', 'struct']
     if name in returns_whitelist:
         returns_meta += ['built-in', 'alternate', 'enum']
@@ -541,15 +537,11 @@ def check_command(expr, expr_info):
 def check_event(expr, expr_info):
     global events
     name = expr['event']
-    boxed = expr.get('boxed', False)
 
-    meta = ['struct']
-    if boxed:
-        meta += ['union', 'alternate']
     events.append(name)
     check_type(expr_info, "'data' for event '%s'" % name,
-               expr.get('data'), allow_dict=not boxed, allow_optional=True,
-               allow_metas=meta)
+               expr.get('data'), allow_dict=True, allow_optional=True,
+               allow_metas=['struct'])
 
 
 def check_union(expr, expr_info):
@@ -620,14 +612,6 @@ def check_union(expr, expr_info):
                                     "enum '%s'" %
                                     (key, enum_define["enum_name"]))
 
-    # If discriminator is user-defined, ensure all values are covered
-    if enum_define:
-        for value in enum_define['enum_values']:
-            if value not in members.keys():
-                raise QAPIExprError(expr_info,
-                                    "Union '%s' data missing '%s' branch"
-                                    % (name, value))
-
 
 def check_alternate(expr, expr_info):
     name = expr['alternate']
@@ -702,10 +686,6 @@ def check_keys(expr_elem, meta, required, optional=[]):
             raise QAPIExprError(info,
                                 "'%s' of %s '%s' should only use false value"
                                 % (key, meta, name))
-        if key == 'boxed' and value is not True:
-            raise QAPIExprError(info,
-                                "'%s' of %s '%s' should only use true value"
-                                % (key, meta, name))
     for key in required:
         if key not in expr:
             raise QAPIExprError(info,
@@ -737,10 +717,10 @@ def check_exprs(exprs):
             add_struct(expr, info)
         elif 'command' in expr:
             check_keys(expr_elem, 'command', [],
-                       ['data', 'returns', 'gen', 'success-response', 'boxed'])
+                       ['data', 'returns', 'gen', 'success-response'])
             add_name(expr['command'], info, 'command')
         elif 'event' in expr:
-            check_keys(expr_elem, 'event', [], ['data', 'boxed'])
+            check_keys(expr_elem, 'event', [], ['data'])
             add_name(expr['event'], info, 'event')
         else:
             raise QAPIExprError(expr_elem['info'],
@@ -838,10 +818,10 @@ class QAPISchemaVisitor(object):
         pass
 
     def visit_command(self, name, info, arg_type, ret_type,
-                      gen, success_response, boxed):
+                      gen, success_response):
         pass
 
-    def visit_event(self, name, info, arg_type, boxed):
+    def visit_event(self, name, info, arg_type):
         pass
 
 
@@ -1011,12 +991,7 @@ class QAPISchemaObjectType(QAPISchemaType):
         # _def_predefineds()
         return self.name.startswith('q_')
 
-    def is_empty(self):
-        assert self.members is not None
-        return not self.members and not self.variants
-
     def c_name(self):
-        assert self.name != 'q_empty'
         return QAPISchemaType.c_name(self)
 
     def c_type(self):
@@ -1109,7 +1084,7 @@ class QAPISchemaObjectTypeVariants(object):
         assert len(variants) > 0
         for v in variants:
             assert isinstance(v, QAPISchemaObjectTypeVariant)
-        self._tag_name = tag_name
+        self.tag_name = tag_name
         self.tag_member = tag_member
         self.variants = variants
 
@@ -1119,8 +1094,8 @@ class QAPISchemaObjectTypeVariants(object):
 
     def check(self, schema, seen):
         if not self.tag_member:    # flat union
-            self.tag_member = seen[c_name(self._tag_name)]
-            assert self._tag_name == self.tag_member.name
+            self.tag_member = seen[c_name(self.tag_name)]
+            assert self.tag_name == self.tag_member.name
         assert isinstance(self.tag_member.type, QAPISchemaEnumType)
         for v in self.variants:
             v.check(schema)
@@ -1150,7 +1125,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
     def __init__(self, name, info, variants):
         QAPISchemaType.__init__(self, name, info)
         assert isinstance(variants, QAPISchemaObjectTypeVariants)
-        assert variants.tag_member
+        assert not variants.tag_name
         variants.set_owner(name)
         variants.tag_member.set_owner(self.name)
         self.variants = variants
@@ -1175,13 +1150,9 @@ class QAPISchemaAlternateType(QAPISchemaType):
     def visit(self, visitor):
         visitor.visit_alternate_type(self.name, self.info, self.variants)
 
-    def is_empty(self):
-        return False
-
 
 class QAPISchemaCommand(QAPISchemaEntity):
-    def __init__(self, name, info, arg_type, ret_type, gen, success_response,
-                 boxed):
+    def __init__(self, name, info, arg_type, ret_type, gen, success_response):
         QAPISchemaEntity.__init__(self, name, info)
         assert not arg_type or isinstance(arg_type, str)
         assert not ret_type or isinstance(ret_type, str)
@@ -1191,24 +1162,12 @@ class QAPISchemaCommand(QAPISchemaEntity):
         self.ret_type = None
         self.gen = gen
         self.success_response = success_response
-        self.boxed = boxed
 
     def check(self, schema):
         if self._arg_type_name:
             self.arg_type = schema.lookup_type(self._arg_type_name)
-            assert (isinstance(self.arg_type, QAPISchemaObjectType) or
-                    isinstance(self.arg_type, QAPISchemaAlternateType))
-            self.arg_type.check(schema)
-            if self.boxed:
-                if self.arg_type.is_empty():
-                    raise QAPIExprError(self.info,
-                                        "Cannot use 'boxed' with empty type")
-            else:
-                assert not isinstance(self.arg_type, QAPISchemaAlternateType)
-                assert not self.arg_type.variants
-        elif self.boxed:
-            raise QAPIExprError(self.info,
-                                "Use of 'boxed' requires 'data'")
+            assert isinstance(self.arg_type, QAPISchemaObjectType)
+            assert not self.arg_type.variants   # not implemented
         if self._ret_type_name:
             self.ret_type = schema.lookup_type(self._ret_type_name)
             assert isinstance(self.ret_type, QAPISchemaType)
@@ -1216,36 +1175,24 @@ class QAPISchemaCommand(QAPISchemaEntity):
     def visit(self, visitor):
         visitor.visit_command(self.name, self.info,
                               self.arg_type, self.ret_type,
-                              self.gen, self.success_response, self.boxed)
+                              self.gen, self.success_response)
 
 
 class QAPISchemaEvent(QAPISchemaEntity):
-    def __init__(self, name, info, arg_type, boxed):
+    def __init__(self, name, info, arg_type):
         QAPISchemaEntity.__init__(self, name, info)
         assert not arg_type or isinstance(arg_type, str)
         self._arg_type_name = arg_type
         self.arg_type = None
-        self.boxed = boxed
 
     def check(self, schema):
         if self._arg_type_name:
             self.arg_type = schema.lookup_type(self._arg_type_name)
-            assert (isinstance(self.arg_type, QAPISchemaObjectType) or
-                    isinstance(self.arg_type, QAPISchemaAlternateType))
-            self.arg_type.check(schema)
-            if self.boxed:
-                if self.arg_type.is_empty():
-                    raise QAPIExprError(self.info,
-                                        "Cannot use 'boxed' with empty type")
-            else:
-                assert not isinstance(self.arg_type, QAPISchemaAlternateType)
-                assert not self.arg_type.variants
-        elif self.boxed:
-            raise QAPIExprError(self.info,
-                                "Use of 'boxed' requires 'data'")
+            assert isinstance(self.arg_type, QAPISchemaObjectType)
+            assert not self.arg_type.variants   # not implemented
 
     def visit(self, visitor):
-        visitor.visit_event(self.name, self.info, self.arg_type, self.boxed)
+        visitor.visit_event(self.name, self.info, self.arg_type)
 
 
 class QAPISchema(object):
@@ -1421,7 +1368,6 @@ class QAPISchema(object):
         rets = expr.get('returns')
         gen = expr.get('gen', True)
         success_response = expr.get('success-response', True)
-        boxed = expr.get('boxed', False)
         if isinstance(data, OrderedDict):
             data = self._make_implicit_object_type(
                 name, info, 'arg', self._make_members(data, info))
@@ -1429,16 +1375,15 @@ class QAPISchema(object):
             assert len(rets) == 1
             rets = self._make_array_type(rets[0], info)
         self._def_entity(QAPISchemaCommand(name, info, data, rets, gen,
-                                           success_response, boxed))
+                                           success_response))
 
     def _def_event(self, expr, info):
         name = expr['event']
         data = expr.get('data')
-        boxed = expr.get('boxed', False)
         if isinstance(data, OrderedDict):
             data = self._make_implicit_object_type(
                 name, info, 'arg', self._make_members(data, info))
-        self._def_entity(QAPISchemaEvent(name, info, data, boxed))
+        self._def_entity(QAPISchemaEvent(name, info, data))
 
     def _def_exprs(self):
         for expr_elem in self.exprs:
@@ -1681,29 +1626,31 @@ extern const char *const %(c_name)s_lookup[];
     return ret
 
 
-def gen_params(arg_type, boxed, extra):
+def gen_params(arg_type, extra):
     if not arg_type:
-        assert not boxed
         return extra
+    assert not arg_type.variants
     ret = ''
     sep = ''
-    if boxed:
-        ret += '%s arg' % arg_type.c_param_type()
+    for memb in arg_type.members:
+        ret += sep
         sep = ', '
-    else:
-        assert not arg_type.variants
-        for memb in arg_type.members:
-            ret += sep
-            sep = ', '
-            if memb.optional:
-                ret += 'bool has_%s, ' % c_name(memb.name)
-            ret += '%s %s' % (memb.type.c_param_type(),
-                              c_name(memb.name))
+        if memb.optional:
+            ret += 'bool has_%s, ' % c_name(memb.name)
+        ret += '%s %s' % (memb.type.c_param_type(), c_name(memb.name))
     if extra:
         ret += sep + extra
     return ret
 
 
+def gen_err_check():
+    return mcgen('''
+    if (err) {
+        goto out;
+    }
+''')
+
+
 #
 # Common command line parsing
 #
old mode 100755 (executable)
new mode 100644 (file)
index de4d1c1..289b1a3
 #!/bin/sh
 # enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program execution by the kernel
 
-qemu_target_list="i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le m68k \
-mips mipsel mipsn32 mipsn32el mips64 mips64el \
-sh4 sh4eb s390x aarch64"
-
-i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'
-i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
-i386_family=i386
-
-i486_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00'
-i486_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
-i486_family=i386
-
-alpha_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90'
-alpha_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
-alpha_family=alpha
-
-arm_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00'
-arm_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
-arm_family=arm
-
-armeb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28'
-armeb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
-armeb_family=arm
-
-sparc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02'
-sparc_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
-sparc_family=sparc
-
-sparc32plus_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12'
-sparc32plus_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
-sparc32plus_family=sparc
-
-ppc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14'
-ppc_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
-ppc_family=ppc
-
-ppc64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15'
-ppc64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
-ppc64_family=ppc
-
-ppc64le_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00'
-ppc64le_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00'
-ppc64le_family=ppcle
-
-m68k_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04'
-m68k_mask='\xff\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
-m68k_family=m68k
-
-# FIXME: We could use the other endianness on a MIPS host.
-
-mips_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
-mips_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
-mips_family=mips
-
-mipsel_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
-mipsel_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
-mipsel_family=mips
-
-mipsn32_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
-mipsn32_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
-mipsn32_family=mips
-
-mipsn32el_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
-mipsn32el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
-mipsn32el_family=mips
-
-mips64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
-mips64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
-mips64_family=mips
-
-mips64el_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
-mips64el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
-mips64el_family=mips
-
-sh4_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00'
-sh4_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
-sh4_family=sh4
-
-sh4eb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a'
-sh4eb_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
-sh4eb_family=sh4
-
-s390x_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16'
-s390x_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
-s390x_family=s390x
-
-aarch64_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00'
-aarch64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
-aarch64_family=arm
-
-qemu_get_family() {
-    cpu=${HOST_ARCH:-$(uname -m)}
-    case "$cpu" in
-    amd64|i386|i486|i586|i686|i86pc|BePC|x86_64)
-        echo "i386"
-        ;;
-    mips*)
-        echo "mips"
-        ;;
-    "Power Macintosh"|ppc64|powerpc|ppc)
-        echo "ppc"
-        ;;
-    ppc64el|ppc64le)
-        echo "ppcle"
-        ;;
-    arm|armel|armhf|arm64|armv[4-9]*)
-        echo "arm"
-        ;;
-    sparc*)
-        echo "sparc"
-        ;;
-    *)
-        echo "$cpu"
-        ;;
-    esac
-}
-
-usage() {
-    cat <<EOF
-Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian][--systemd CPU]
-                           [--help][--credential yes|no][--exportdir PATH]
-
-       Configure binfmt_misc to use qemu interpreter
-
-       --help:       display this usage
-       --qemu-path:  set path to qemu interpreter ($QEMU_PATH)
-       --debian:     don't write into /proc,
-                     instead generate update-binfmts templates
-       --systemd:    don't write into /proc,
-                     instead generate file for systemd-binfmt.service
-                     for the given CPU
-       --exportdir:  define where to write configuration files
-                     (default: $SYSTEMDDIR or $DEBIANDIR)
-       --credential: if yes, credential and security tokens are
-                     calculated according to the binary to interpret
-
-    To import templates with update-binfmts, use :
-
-        sudo update-binfmts --importdir ${EXPORTDIR:-$DEBIANDIR} --import qemu-CPU
-
-    To remove interpreter, use :
-
-        sudo update-binfmts --package qemu-CPU --remove qemu-CPU $QEMU_PATH
-
-    With systemd, binfmt files are loaded by systemd-binfmt.service
-
-    The environment variable HOST_ARCH allows to override 'uname' to generate
-    configuration files for a different architecture than the current one.
-
-    where CPU is one of:
-
-        $qemu_target_list
-
-EOF
-}
-
-qemu_check_access() {
-    if [ ! -w "$1" ] ; then
-        echo "ERROR: cannot write to $1" 1>&2
-        exit 1
-    fi
-}
-
-qemu_check_bintfmt_misc() {
-    # load the binfmt_misc module
-    if [ ! -d /proc/sys/fs/binfmt_misc ]; then
-      if ! /sbin/modprobe binfmt_misc ; then
-          exit 1
-      fi
-    fi
-    if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
-      if ! mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc ; then
-          exit 1
-      fi
-    fi
-
-    qemu_check_access /proc/sys/fs/binfmt_misc/register
-}
-
-installed_dpkg() {
-    dpkg --status "$1" > /dev/null 2>&1
-}
-
-qemu_check_debian() {
-    if [ ! -e /etc/debian_version ] ; then
-        echo "WARNING: your system is not a Debian based distro" 1>&2
-    elif ! installed_dpkg binfmt-support ; then
-        echo "WARNING: package binfmt-support is needed" 1>&2
-    fi
-    qemu_check_access "$EXPORTDIR"
-}
-
-qemu_check_systemd() {
-    if ! systemctl -q is-enabled systemd-binfmt.service ; then
-        echo "WARNING: systemd-binfmt.service is missing or disabled" 1>&2
-    fi
-    qemu_check_access "$EXPORTDIR"
-}
-
-qemu_generate_register() {
-    echo ":qemu-$cpu:M::$magic:$mask:$qemu:$FLAGS"
-}
-
-qemu_register_interpreter() {
-    echo "Setting $qemu as binfmt interpreter for $cpu"
-    qemu_generate_register > /proc/sys/fs/binfmt_misc/register
-}
-
-qemu_generate_systemd() {
-    echo "Setting $qemu as binfmt interpreter for $cpu for systemd-binfmt.service"
-    qemu_generate_register > "$EXPORTDIR/qemu-$cpu.conf"
-}
-
-qemu_generate_debian() {
-    cat > "$EXPORTDIR/qemu-$cpu" <<EOF
-package qemu-$cpu
-interpreter $qemu
-magic $magic
-mask $mask
-EOF
-    if [ "$FLAGS" = "OC" ] ; then
-        echo "credentials yes" >> "$EXPORTDIR/qemu-$cpu"
-    fi
-}
-
-qemu_set_binfmts() {
-    # probe cpu type
-    host_family=$(qemu_get_family)
-
-    # register the interpreter for each cpu except for the native one
-
-    for cpu in ${qemu_target_list} ; do
-        magic=$(eval echo \$${cpu}_magic)
-        mask=$(eval echo \$${cpu}_mask)
-        family=$(eval echo \$${cpu}_family)
-
-        if [ "$magic" = "" ] || [ "$mask" = "" ] || [ "$family" = "" ] ; then
-            echo "INTERNAL ERROR: unknown cpu $cpu" 1>&2
-            continue
-        fi
-
-        qemu="$QEMU_PATH/qemu-$cpu"
-        if [ "$cpu" = "i486" ] ; then
-            qemu="$QEMU_PATH/qemu-i386"
-        fi
-
-        if [ "$host_family" != "$family" ] ; then
-            $BINFMT_SET
-        fi
-    done
-}
-
-CHECK=qemu_check_bintfmt_misc
-BINFMT_SET=qemu_register_interpreter
-
-SYSTEMDDIR="/etc/binfmt.d"
-DEBIANDIR="/usr/share/binfmts"
-
-QEMU_PATH=/usr/local/bin
-FLAGS=""
-
-options=$(getopt -o ds:Q:e:hc: -l debian,systemd:,qemu-path:,exportdir:,help,credential: -- "$@")
-eval set -- "$options"
-
-while true ; do
-    case "$1" in
-    -d|--debian)
-        CHECK=qemu_check_debian
-        BINFMT_SET=qemu_generate_debian
-        EXPORTDIR=${EXPORTDIR:-$DEBIANDIR}
-        ;;
-    -s|--systemd)
-        CHECK=qemu_check_systemd
-        BINFMT_SET=qemu_generate_systemd
-        EXPORTDIR=${EXPORTDIR:-$SYSTEMDDIR}
-        shift
-        # check given cpu is in the supported CPU list
-        for cpu in ${qemu_target_list} ; do
-            if [ "$cpu" == "$1" ] ; then
-                break
-            fi
-        done
-
-        if [ "$cpu" == "$1" ] ; then
-            qemu_target_list="$1"
-        else
-            echo "ERROR: unknown CPU \"$1\"" 1>&2
-            usage
-            exit 1
-        fi
-        ;;
-    -Q|--qemu-path)
-        shift
-        QEMU_PATH="$1"
-        ;;
-    -e|--exportdir)
-        shift
-        EXPORTDIR="$1"
-        ;;
-    -h|--help)
-        usage
-        exit 1
-        ;;
-    -c|--credential)
-        shift
-        if [ "$1" = "yes" ] ; then
-            FLAGS="OC"
-        else
-            FLAGS=""
-        fi
-        ;;
-    *)
-        break
-        ;;
-    esac
-    shift
-done
-
-$CHECK
-qemu_set_binfmts
+# load the binfmt_misc module
+if [ ! -d /proc/sys/fs/binfmt_misc ]; then
+  /sbin/modprobe binfmt_misc
+fi
+if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
+  mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
+fi
+
+# probe cpu type
+cpu=`uname -m`
+case "$cpu" in
+  i386|i486|i586|i686|i86pc|BePC|x86_64)
+    cpu="i386"
+  ;;
+  m68k)
+    cpu="m68k"
+  ;;
+  mips*)
+    cpu="mips"
+  ;;
+  "Power Macintosh"|ppc|ppc64)
+    cpu="ppc"
+  ;;
+  armv[4-9]*)
+    cpu="arm"
+  ;;
+esac
+
+# register the interpreter for each cpu except for the native one
+if [ $cpu != "i386" ] ; then
+    echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
+    echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
+fi
+if [ $cpu != "alpha" ] ; then
+    echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register
+fi
+if [ $cpu != "arm" ] ; then
+    echo   ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
+fi
+if [ $cpu != "aarch64" ] ; then
+    echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-aarch64:' > /proc/sys/fs/binfmt_misc/register
+fi
+if [ $cpu != "sparc" ] ; then
+    echo   ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
+fi
+if [ $cpu != "ppc" ] ; then
+    echo   ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
+fi
+if [ $cpu != "m68k" ] ; then
+    echo   'Please check cpu value and header information for m68k!'
+    echo   ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
+fi
+if [ $cpu != "mips" ] ; then
+    # FIXME: We could use the other endianness on a MIPS host.
+    echo   ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register
+fi
+if [ $cpu != "sh" ] ; then
+    echo    ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register
+    echo    ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register
+fi
+if [ $cpu != "s390x" ] ; then
+    echo   ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x:' > /proc/sys/fs/binfmt_misc/register
+fi
diff --git a/scripts/qemu.py b/scripts/qemu.py
deleted file mode 100644 (file)
index 6d1b623..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-# QEMU library
-#
-# Copyright (C) 2015-2016 Red Hat Inc.
-# Copyright (C) 2012 IBM Corp.
-#
-# Authors:
-#  Fam Zheng <famz@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2.  See
-# the COPYING file in the top-level directory.
-#
-# Based on qmp.py.
-#
-
-import errno
-import string
-import os
-import sys
-import subprocess
-import qmp.qmp
-
-
-class QEMUMachine(object):
-    '''A QEMU VM'''
-
-    def __init__(self, binary, args=[], wrapper=[], name=None, test_dir="/var/tmp",
-                 monitor_address=None, socket_scm_helper=None, debug=False):
-        if name is None:
-            name = "qemu-%d" % os.getpid()
-        if monitor_address is None:
-            monitor_address = os.path.join(test_dir, name + "-monitor.sock")
-        self._monitor_address = monitor_address
-        self._qemu_log_path = os.path.join(test_dir, name + ".log")
-        self._popen = None
-        self._binary = binary
-        self._args = list(args) # Force copy args in case we modify them
-        self._wrapper = wrapper
-        self._events = []
-        self._iolog = None
-        self._socket_scm_helper = socket_scm_helper
-        self._debug = debug
-
-    # This can be used to add an unused monitor instance.
-    def add_monitor_telnet(self, ip, port):
-        args = 'tcp:%s:%d,server,nowait,telnet' % (ip, port)
-        self._args.append('-monitor')
-        self._args.append(args)
-
-    def add_fd(self, fd, fdset, opaque, opts=''):
-        '''Pass a file descriptor to the VM'''
-        options = ['fd=%d' % fd,
-                   'set=%d' % fdset,
-                   'opaque=%s' % opaque]
-        if opts:
-            options.append(opts)
-
-        self._args.append('-add-fd')
-        self._args.append(','.join(options))
-        return self
-
-    def send_fd_scm(self, fd_file_path):
-        # In iotest.py, the qmp should always use unix socket.
-        assert self._qmp.is_scm_available()
-        if self._socket_scm_helper is None:
-            print >>sys.stderr, "No path to socket_scm_helper set"
-            return -1
-        if os.path.exists(self._socket_scm_helper) == False:
-            print >>sys.stderr, "%s does not exist" % self._socket_scm_helper
-            return -1
-        fd_param = ["%s" % self._socket_scm_helper,
-                    "%d" % self._qmp.get_sock_fd(),
-                    "%s" % fd_file_path]
-        devnull = open('/dev/null', 'rb')
-        p = subprocess.Popen(fd_param, stdin=devnull, stdout=sys.stdout,
-                             stderr=sys.stderr)
-        return p.wait()
-
-    @staticmethod
-    def _remove_if_exists(path):
-        '''Remove file object at path if it exists'''
-        try:
-            os.remove(path)
-        except OSError as exception:
-            if exception.errno == errno.ENOENT:
-                return
-            raise
-
-    def get_pid(self):
-        if not self._popen:
-            return None
-        return self._popen.pid
-
-    def _load_io_log(self):
-        with open(self._qemu_log_path, "r") as fh:
-            self._iolog = fh.read()
-
-    def _base_args(self):
-        if isinstance(self._monitor_address, tuple):
-            moncdev = "socket,id=mon,host=%s,port=%s" % (
-                self._monitor_address[0],
-                self._monitor_address[1])
-        else:
-            moncdev = 'socket,id=mon,path=%s' % self._monitor_address
-        return ['-chardev', moncdev,
-                '-mon', 'chardev=mon,mode=control',
-                '-display', 'none', '-vga', 'none']
-
-    def _pre_launch(self):
-        self._qmp = qmp.qmp.QEMUMonitorProtocol(self._monitor_address, server=True,
-                                                debug=self._debug)
-
-    def _post_launch(self):
-        self._qmp.accept()
-
-    def _post_shutdown(self):
-        if not isinstance(self._monitor_address, tuple):
-            self._remove_if_exists(self._monitor_address)
-        self._remove_if_exists(self._qemu_log_path)
-
-    def launch(self):
-        '''Launch the VM and establish a QMP connection'''
-        devnull = open('/dev/null', 'rb')
-        qemulog = open(self._qemu_log_path, 'wb')
-        try:
-            self._pre_launch()
-            args = self._wrapper + [self._binary] + self._base_args() + self._args
-            self._popen = subprocess.Popen(args, stdin=devnull, stdout=qemulog,
-                                           stderr=subprocess.STDOUT, shell=False)
-            self._post_launch()
-        except:
-            if self._popen:
-                self._popen.kill()
-            self._load_io_log()
-            self._post_shutdown()
-            self._popen = None
-            raise
-
-    def shutdown(self):
-        '''Terminate the VM and clean up'''
-        if not self._popen is None:
-            try:
-                self._qmp.cmd('quit')
-                self._qmp.close()
-            except:
-                self._popen.kill()
-
-            exitcode = self._popen.wait()
-            if exitcode < 0:
-                sys.stderr.write('qemu received signal %i: %s\n' % (-exitcode, ' '.join(self._args)))
-            self._load_io_log()
-            self._post_shutdown()
-            self._popen = None
-
-    underscore_to_dash = string.maketrans('_', '-')
-    def qmp(self, cmd, conv_keys=True, **args):
-        '''Invoke a QMP command and return the result dict'''
-        qmp_args = dict()
-        for k in args.keys():
-            if conv_keys:
-                qmp_args[k.translate(self.underscore_to_dash)] = args[k]
-            else:
-                qmp_args[k] = args[k]
-
-        return self._qmp.cmd(cmd, args=qmp_args)
-
-    def command(self, cmd, conv_keys=True, **args):
-        reply = self.qmp(cmd, conv_keys, **args)
-        if reply is None:
-            raise Exception("Monitor is closed")
-        if "error" in reply:
-            raise Exception(reply["error"]["desc"])
-        return reply["return"]
-
-    def get_qmp_event(self, wait=False):
-        '''Poll for one queued QMP events and return it'''
-        if len(self._events) > 0:
-            return self._events.pop(0)
-        return self._qmp.pull_event(wait=wait)
-
-    def get_qmp_events(self, wait=False):
-        '''Poll for queued QMP events and return a list of dicts'''
-        events = self._qmp.get_events(wait=wait)
-        events.extend(self._events)
-        del self._events[:]
-        self._qmp.clear_events()
-        return events
-
-    def event_wait(self, name, timeout=60.0, match=None):
-        # Test if 'match' is a recursive subset of 'event'
-        def event_match(event, match=None):
-            if match is None:
-                return True
-
-            for key in match:
-                if key in event:
-                    if isinstance(event[key], dict):
-                        if not event_match(event[key], match[key]):
-                            return False
-                    elif event[key] != match[key]:
-                        return False
-                else:
-                    return False
-
-            return True
-
-        # Search cached events
-        for event in self._events:
-            if (event['event'] == name) and event_match(event, match):
-                self._events.remove(event)
-                return event
-
-        # Poll for new events
-        while True:
-            event = self._qmp.pull_event(wait=timeout)
-            if (event['event'] == name) and event_match(event, match):
-                return event
-            self._events.append(event)
-
-        return None
-
-    def get_log(self):
-        return self._iolog
diff --git a/scripts/qmp/__init__.py b/scripts/qmp/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
index 62d3651..779332f 100644 (file)
@@ -11,7 +11,6 @@
 import json
 import errno
 import socket
-import sys
 
 class QMPError(Exception):
     pass
@@ -26,7 +25,7 @@ class QMPTimeoutError(QMPError):
     pass
 
 class QEMUMonitorProtocol:
-    def __init__(self, address, server=False, debug=False):
+    def __init__(self, address, server=False):
         """
         Create a QEMUMonitorProtocol class.
 
@@ -40,10 +39,8 @@ class QEMUMonitorProtocol:
         """
         self.__events = []
         self.__address = address
-        self._debug = debug
         self.__sock = self.__get_sock()
         if server:
-            self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
             self.__sock.bind(self.__address)
             self.__sock.listen(1)
 
@@ -71,8 +68,6 @@ class QEMUMonitorProtocol:
                 return
             resp = json.loads(data)
             if 'event' in resp:
-                if self._debug:
-                    print >>sys.stderr, "QMP:<<< %s" % resp
                 self.__events.append(resp)
                 if not only_event:
                     continue
@@ -141,7 +136,6 @@ class QEMUMonitorProtocol:
         @raise QMPConnectError if the greeting is not received
         @raise QMPCapabilitiesError if fails to negotiate capabilities
         """
-        self.__sock.settimeout(15)
         self.__sock, _ = self.__sock.accept()
         self.__sockfile = self.__sock.makefile()
         return self.__negotiate_capabilities()
@@ -154,18 +148,13 @@ class QEMUMonitorProtocol:
         @return QMP response as a Python dict or None if the connection has
                 been closed
         """
-        if self._debug:
-            print >>sys.stderr, "QMP:>>> %s" % qmp_cmd
         try:
             self.__sock.sendall(json.dumps(qmp_cmd))
         except socket.error as err:
             if err[0] == errno.EPIPE:
                 return
             raise socket.error(err)
-        resp = self.__json_read()
-        if self._debug:
-            print >>sys.stderr, "QMP:<<< %s" % resp
-        return resp
+        return self.__json_read()
 
     def cmd(self, name, args=None, id=None):
         """
index d5aecb5..a971445 100644 (file)
 
 import errno
 import socket
-import string
-import os
-import subprocess
-import qmp.qmp
-import qemu
 
 class QEMUQtestProtocol(object):
     def __init__(self, address, server=False):
@@ -74,37 +69,3 @@ class QEMUQtestProtocol(object):
 
     def settimeout(self, timeout):
         self._sock.settimeout(timeout)
-
-
-class QEMUQtestMachine(qemu.QEMUMachine):
-    '''A QEMU VM'''
-
-    def __init__(self, binary, args=[], name=None, test_dir="/var/tmp",
-                 socket_scm_helper=None):
-        if name is None:
-            name = "qemu-%d" % os.getpid()
-        super(QEMUQtestMachine, self).__init__(binary, args, name=name, test_dir=test_dir,
-                                               socket_scm_helper=socket_scm_helper)
-        self._qtest_path = os.path.join(test_dir, name + "-qtest.sock")
-
-    def _base_args(self):
-        args = super(QEMUQtestMachine, self)._base_args()
-        args.extend(['-qtest', 'unix:path=' + self._qtest_path,
-                     '-machine', 'accel=qtest'])
-        return args
-
-    def _pre_launch(self):
-        super(QEMUQtestMachine, self)._pre_launch()
-        self._qtest = QEMUQtestProtocol(self._qtest_path, server=True)
-
-    def _post_launch(self):
-        super(QEMUQtestMachine, self)._post_launch()
-        self._qtest.accept()
-
-    def _post_shutdown(self):
-        super(QEMUQtestMachine, self)._post_shutdown()
-        self._remove_if_exists(self._qtest_path)
-
-    def qtest(self, cmd):
-        '''Send a qtest command to guest'''
-        return self._qtest.cmd(cmd)
index d1dabe0..f9c35cc 100644 (file)
@@ -17,28 +17,11 @@ if len(sys.argv) < 3:
 fin = open(sys.argv[1], 'rb')
 fout = open(sys.argv[2], 'wb')
 
-magic = fin.read(2)
-if magic != '\x55\xaa':
-    sys.exit("%s: option ROM does not begin with magic 55 aa" % sys.argv[1])
+fin.seek(2)
+size = ord(fin.read(1)) * 512 - 1
 
-size_byte = ord(fin.read(1))
 fin.seek(0)
-data = fin.read()
-
-size = size_byte * 512
-if len(data) > size:
-    sys.stderr.write('error: ROM is too large (%d > %d)\n' % (len(data), size))
-    sys.exit(1)
-elif len(data) < size:
-    # Add padding if necessary, rounding the whole input to a multiple of
-    # 512 bytes according to the third byte of the input.
-    # size-1 because a final byte is added below to store the checksum.
-    data = data.ljust(size-1, '\0')
-else:
-    if ord(data[-1:]) != 0:
-        sys.stderr.write('WARNING: ROM includes nonzero checksum\n')
-    data = data[:size-1]
-
+data = fin.read(size)
 fout.write(data)
 
 checksum = 0
index ab9ecfa..fabfe99 100644 (file)
@@ -6,7 +6,7 @@ DTrace/SystemTAP backend.
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -41,6 +41,6 @@ def generate_h_begin(events):
 
 
 def generate_h(event):
-    out('        QEMU_%(uppername)s(%(argnames)s);',
+    out('    QEMU_%(uppername)s(%(argnames)s);',
         uppername=event.name.upper(),
         argnames=", ".join(event.args.names()))
index 80dcf30..d798c71 100644 (file)
@@ -30,17 +30,17 @@ def generate_h(event):
     if len(event.args) > 0:
         argnames = ", " + argnames
 
-    out('        {',
-        '            char ftrace_buf[MAX_TRACE_STRLEN];',
-        '            int unused __attribute__ ((unused));',
-        '            int trlen;',
-        '            if (trace_event_get_state(%(event_id)s)) {',
-        '                trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,',
-        '                                 "%(name)s " %(fmt)s "\\n" %(argnames)s);',
-        '                trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);',
-        '                unused = write(trace_marker_fd, ftrace_buf, trlen);',
-        '            }',
+    out('    {',
+        '        char ftrace_buf[MAX_TRACE_STRLEN];',
+        '        int unused __attribute__ ((unused));',
+        '        int trlen;',
+        '        if (trace_event_get_state(%(event_id)s)) {',
+        '            trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,',
+        '                             "%(name)s " %(fmt)s "\\n" %(argnames)s);',
+        '            trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);',
+        '            unused = write(trace_marker_fd, ftrace_buf, trlen);',
         '        }',
+        '    }',
         name=event.name,
         args=event.args,
         event_id="TRACE_" + event.name.upper(),
index b3ff064..e409b73 100644 (file)
@@ -6,7 +6,7 @@ Stderr built-in backend.
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -30,21 +30,15 @@ def generate_h(event):
     if len(event.args) > 0:
         argnames = ", " + argnames
 
-    if "vcpu" in event.properties:
-        # already checked on the generic format code
-        cond = "true"
-    else:
-        cond = "trace_event_get_state(%s)" % ("TRACE_" + event.name.upper())
-
-    out('        if (%(cond)s) {',
-        '            struct timeval _now;',
-        '            gettimeofday(&_now, NULL);',
-        '            qemu_log_mask(LOG_TRACE, "%%d@%%zd.%%06zd:%(name)s " %(fmt)s "\\n",',
-        '                          getpid(),',
-        '                          (size_t)_now.tv_sec, (size_t)_now.tv_usec',
-        '                          %(argnames)s);',
-        '        }',
-        cond=cond,
+    out('    if (trace_event_get_state(%(event_id)s)) {',
+        '        struct timeval _now;',
+        '        gettimeofday(&_now, NULL);',
+        '        qemu_log_mask(LOG_TRACE, "%%d@%%zd.%%06zd:%(name)s " %(fmt)s "\\n",',
+        '                      getpid(),',
+        '                      (size_t)_now.tv_sec, (size_t)_now.tv_usec',
+        '                      %(argnames)s);',
+        '    }',
+        event_id="TRACE_" + event.name.upper(),
         name=event.name,
         fmt=event.fmt.rstrip("\n"),
         argnames=argnames)
index 1bccada..3246c20 100644 (file)
@@ -36,7 +36,7 @@ def generate_h_begin(events):
 
 
 def generate_h(event):
-    out('        _simple_%(api)s(%(args)s);',
+    out('    _simple_%(api)s(%(args)s);',
         api=event.api(),
         args=", ".join(event.args.names()))
 
@@ -68,23 +68,16 @@ def generate_c(event):
     if len(event.args) == 0:
         sizestr = '0'
 
-    event_id = 'TRACE_' + event.name.upper()
-    if "vcpu" in event.properties:
-        # already checked on the generic format code
-        cond = "true"
-    else:
-        cond = "trace_event_get_state(%s)" % event_id
 
     out('',
-        '    if (!%(cond)s) {',
+        '    if (!trace_event_get_state(%(event_id)s)) {',
         '        return;',
         '    }',
         '',
         '    if (trace_record_start(&rec, %(event_id)s, %(size_str)s)) {',
         '        return; /* Trace Buffer Full, Event Dropped ! */',
         '    }',
-        cond=cond,
-        event_id=event_id,
+        event_id='TRACE_' + event.name.upper(),
         size_str=sizestr)
 
     if len(event.args) > 0:
index ed4c227..2f8f44a 100644 (file)
@@ -6,7 +6,7 @@ LTTng User Space Tracing backend.
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -30,6 +30,6 @@ def generate_h(event):
     if len(event.args) > 0:
         argnames = ", " + argnames
 
-    out('        tracepoint(qemu, %(name)s%(tp_args)s);',
+    out('    tracepoint(qemu, %(name)s%(tp_args)s);',
         name=event.name,
         tp_args=argnames)
index 4012063..1cc6a49 100644 (file)
@@ -6,7 +6,7 @@ trace/generated-events.c
 """
 
 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__  = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
 __license__    = "GPL version 2 or (at your option) any later version"
 
 __maintainer__ = "Stefan Hajnoczi"
@@ -28,15 +28,8 @@ def generate(events, backend):
     out('TraceEvent trace_events[TRACE_EVENT_COUNT] = {')
 
     for e in events:
-        if "vcpu" in e.properties:
-            vcpu_id = "TRACE_VCPU_" + e.name.upper()
-        else:
-            vcpu_id = "TRACE_VCPU_EVENT_COUNT"
-        out('    { .id = %(id)s, .vcpu_id = %(vcpu_id)s,'
-            ' .name = \"%(name)s\",'
-            ' .sstate = %(sstate)s },',
+        out('    { .id = %(id)s, .name = \"%(name)s\", .sstate = %(sstate)s },',
             id = "TRACE_" + e.name.upper(),
-            vcpu_id = vcpu_id,
             name = e.name,
             sstate = "TRACE_%s_ENABLED" % e.name.upper())
 
index a9da60b..4529263 100644 (file)
@@ -32,23 +32,13 @@ def generate(events, backend):
     out('    TRACE_EVENT_COUNT',
         '} TraceEventID;')
 
-    # per-vCPU event identifiers
-    out('typedef enum {')
-
-    for e in events:
-        if "vcpu" in e.properties:
-            out('    TRACE_VCPU_%s,' % e.name.upper())
-
-    out('    TRACE_VCPU_EVENT_COUNT',
-        '} TraceEventVCPUID;')
-
     # static state
     for e in events:
         if 'disable' in e.properties:
             enabled = 0
         else:
             enabled = 1
-        if "tcg-exec" in e.properties:
+        if "tcg-trans" in e.properties:
             # a single define for the two "sub-events"
             out('#define TRACE_%(name)s_ENABLED %(enabled)d',
                 name=e.original.name.upper(),
index 3763e9a..0835406 100644 (file)
@@ -23,36 +23,21 @@ def generate(events, backend):
         '#define TRACE__GENERATED_TRACERS_H',
         '',
         '#include "qemu-common.h"',
-        '#include "trace/control.h"',
         '')
 
     backend.generate_begin(events)
 
     for e in events:
-        if "vcpu" in e.properties:
-            trace_cpu = next(iter(e.args))[1]
-            cond = "trace_event_get_vcpu_state(%(cpu)s,"\
-                   " TRACE_%(id)s,"\
-                   " TRACE_VCPU_%(id)s)"\
-                   % dict(
-                       cpu=trace_cpu,
-                       id=e.name.upper())
-        else:
-            cond = "true"
-
         out('',
             'static inline void %(api)s(%(args)s)',
             '{',
-            '    if (%(cond)s) {',
             api=e.api(),
-            args=e.args,
-            cond=cond)
+            args=e.args)
 
         if "disable" not in e.properties:
             backend.generate(e)
 
-        out('    }',
-            '}')
+        out('}')
 
     backend.generate_end(events)
 
index e3485b7..a089b0b 100644 (file)
@@ -48,7 +48,6 @@ def generate(events, backend):
         '',
         '#include "qemu/osdep.h"',
         '#include "qemu-common.h"',
-        '#include "cpu.h"',
         '#include "trace.h"',
         '#include "exec/helper-proto.h"',
         '',
index 08c4c4a..f7d62d9 100755 (executable)
@@ -10,7 +10,7 @@
 # This work is licensed under the terms of the GNU GPL version 2.
 # See the COPYING file in the top-level directory.
 
-tmpdir=$(mktemp -d)
+tmpdir=`mktemp -d`
 linux="$1"
 output="$2"
 
index 14a27e7..b5ecaf6 100755 (executable)
@@ -185,7 +185,7 @@ def check_fields(src_fields, dest_fields, desc, sec):
             if unused_count == 0:
                 advance_dest = True
 
-        if unused_count != 0:
+        if unused_count > 0:
             if advance_dest == False:
                 unused_count = unused_count - s_item["size"]
                 if unused_count == 0:
index 1baa1f1..6748e4f 100644 (file)
@@ -1,5 +1,5 @@
 common-obj-y = cksum.o if.o ip_icmp.o ip6_icmp.o ip6_input.o ip6_output.o \
-               ip_input.o ip_output.o dnssearch.o dhcpv6.o
+               ip_input.o ip_output.o dnssearch.o
 common-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
 common-obj-y += tcp_subr.o tcp_timer.o udp.o udp6.o bootp.o tftp.o arp_table.o \
                 ndp_table.o
index 5a4646c..7b3232b 100644 (file)
@@ -22,7 +22,7 @@
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
 
 #if defined(_WIN32)
 /* Windows ntohl() returns an u_long value.
index 3945257..ec3b687 100644 (file)
@@ -1,7 +1,6 @@
 /* bootp/dhcp defines */
-
 #ifndef SLIRP_BOOTP_H
-#define SLIRP_BOOTP_H
+#define SLIRP_BOOTP_H 1
 
 #define BOOTP_SERVER   67
 #define BOOTP_CLIENT   68
index 6d73abf..2ad0e65 100644 (file)
@@ -31,7 +31,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
 
 /*
  * Checksum routine for Internet Protocol family headers (Portable Version).
diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c
deleted file mode 100644 (file)
index 02c51c7..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * SLIRP stateless DHCPv6
- *
- * We only support stateless DHCPv6, e.g. for network booting.
- * See RFC 3315, RFC 3736, RFC 3646 and RFC 5970 for details.
- *
- * Copyright 2016 Thomas Huth, Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License,
- * or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "slirp.h"
-#include "dhcpv6.h"
-
-/* DHCPv6 message types */
-#define MSGTYPE_REPLY        7
-#define MSGTYPE_INFO_REQUEST 11
-
-/* DHCPv6 option types */
-#define OPTION_CLIENTID      1
-#define OPTION_IAADDR        5
-#define OPTION_ORO           6
-#define OPTION_DNS_SERVERS   23
-#define OPTION_BOOTFILE_URL  59
-
-struct requested_infos {
-    uint8_t *client_id;
-    int client_id_len;
-    bool want_dns;
-    bool want_boot_url;
-};
-
-/**
- * Analyze the info request message sent by the client to see what data it
- * provided and what it wants to have. The information is gathered in the
- * "requested_infos" struct. Note that client_id (if provided) points into
- * the odata region, thus the caller must keep odata valid as long as it
- * needs to access the requested_infos struct.
- */
-static int dhcpv6_parse_info_request(uint8_t *odata, int olen,
-                                     struct requested_infos *ri)
-{
-    int i, req_opt;
-
-    while (olen > 4) {
-        /* Parse one option */
-        int option = odata[0] << 8 | odata[1];
-        int len = odata[2] << 8 | odata[3];
-
-        if (len + 4 > olen) {
-            qemu_log_mask(LOG_GUEST_ERROR, "Guest sent bad DHCPv6 packet!\n");
-            return -E2BIG;
-        }
-
-        switch (option) {
-        case OPTION_IAADDR:
-            /* According to RFC3315, we must discard requests with IA option */
-            return -EINVAL;
-        case OPTION_CLIENTID:
-            if (len > 256) {
-                /* Avoid very long IDs which could cause problems later */
-                return -E2BIG;
-            }
-            ri->client_id = odata + 4;
-            ri->client_id_len = len;
-            break;
-        case OPTION_ORO:        /* Option request option */
-            if (len & 1) {
-                return -EINVAL;
-            }
-            /* Check which options the client wants to have */
-            for (i = 0; i < len; i += 2) {
-                req_opt = odata[4 + i] << 8 | odata[4 + i + 1];
-                switch (req_opt) {
-                case OPTION_DNS_SERVERS:
-                    ri->want_dns = true;
-                    break;
-                case OPTION_BOOTFILE_URL:
-                    ri->want_boot_url = true;
-                    break;
-                default:
-                    DEBUG_MISC((dfd, "dhcpv6: Unsupported option request %d\n",
-                                req_opt));
-                }
-            }
-            break;
-        default:
-            DEBUG_MISC((dfd, "dhcpv6 info req: Unsupported option %d, len=%d\n",
-                        option, len));
-        }
-
-        odata += len + 4;
-        olen -= len + 4;
-    }
-
-    return 0;
-}
-
-
-/**
- * Handle information request messages
- */
-static void dhcpv6_info_request(Slirp *slirp, struct sockaddr_in6 *srcsas,
-                                uint32_t xid, uint8_t *odata, int olen)
-{
-    struct requested_infos ri = { NULL };
-    struct sockaddr_in6 sa6, da6;
-    struct mbuf *m;
-    uint8_t *resp;
-
-    if (dhcpv6_parse_info_request(odata, olen, &ri) < 0) {
-        return;
-    }
-
-    m = m_get(slirp);
-    if (!m) {
-        return;
-    }
-    memset(m->m_data, 0, m->m_size);
-    m->m_data += IF_MAXLINKHDR;
-    resp = (uint8_t *)m->m_data + sizeof(struct ip6) + sizeof(struct udphdr);
-
-    /* Fill in response */
-    *resp++ = MSGTYPE_REPLY;
-    *resp++ = (uint8_t)(xid >> 16);
-    *resp++ = (uint8_t)(xid >> 8);
-    *resp++ = (uint8_t)xid;
-
-    if (ri.client_id) {
-        *resp++ = OPTION_CLIENTID >> 8;         /* option-code high byte */
-        *resp++ = OPTION_CLIENTID;              /* option-code low byte */
-        *resp++ = ri.client_id_len >> 8;        /* option-len high byte */
-        *resp++ = ri.client_id_len;             /* option-len low byte */
-        memcpy(resp, ri.client_id, ri.client_id_len);
-        resp += ri.client_id_len;
-    }
-    if (ri.want_dns) {
-        *resp++ = OPTION_DNS_SERVERS >> 8;      /* option-code high byte */
-        *resp++ = OPTION_DNS_SERVERS;           /* option-code low byte */
-        *resp++ = 0;                            /* option-len high byte */
-        *resp++ = 16;                           /* option-len low byte */
-        memcpy(resp, &slirp->vnameserver_addr6, 16);
-        resp += 16;
-    }
-    if (ri.want_boot_url) {
-        uint8_t *sa = slirp->vhost_addr6.s6_addr;
-        int slen, smaxlen;
-
-        *resp++ = OPTION_BOOTFILE_URL >> 8;     /* option-code high byte */
-        *resp++ = OPTION_BOOTFILE_URL;          /* option-code low byte */
-        smaxlen = (uint8_t *)m->m_data + IF_MTU - (resp + 2);
-        slen = snprintf((char *)resp + 2, smaxlen,
-                        "tftp://[%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
-                                "%02x%02x:%02x%02x:%02x%02x:%02x%02x]/%s",
-                        sa[0], sa[1], sa[2], sa[3], sa[4], sa[5], sa[6], sa[7],
-                        sa[8], sa[9], sa[10], sa[11], sa[12], sa[13], sa[14],
-                        sa[15], slirp->bootp_filename);
-        slen = min(slen, smaxlen);
-        *resp++ = slen >> 8;                    /* option-len high byte */
-        *resp++ = slen;                         /* option-len low byte */
-        resp += slen;
-    }
-
-    sa6.sin6_addr = slirp->vhost_addr6;
-    sa6.sin6_port = DHCPV6_SERVER_PORT;
-    da6.sin6_addr = srcsas->sin6_addr;
-    da6.sin6_port = srcsas->sin6_port;
-    m->m_data += sizeof(struct ip6) + sizeof(struct udphdr);
-    m->m_len = resp - (uint8_t *)m->m_data;
-    udp6_output(NULL, m, &sa6, &da6);
-}
-
-/**
- * Handle DHCPv6 messages sent by the client
- */
-void dhcpv6_input(struct sockaddr_in6 *srcsas, struct mbuf *m)
-{
-    uint8_t *data = (uint8_t *)m->m_data + sizeof(struct udphdr);
-    int data_len = m->m_len - sizeof(struct udphdr);
-    uint32_t xid;
-
-    if (data_len < 4) {
-        return;
-    }
-
-    xid = ntohl(*(uint32_t *)data) & 0xffffff;
-
-    switch (data[0]) {
-    case MSGTYPE_INFO_REQUEST:
-        dhcpv6_info_request(m->slirp, srcsas, xid, &data[4], data_len - 4);
-        break;
-    default:
-        DEBUG_MISC((dfd, "dhcpv6_input: Unsupported message type 0x%x\n",
-                    data[0]));
-    }
-}
diff --git a/slirp/dhcpv6.h b/slirp/dhcpv6.h
deleted file mode 100644 (file)
index 9189cd3..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Definitions and prototypes for SLIRP stateless DHCPv6
- *
- * Copyright 2016 Thomas Huth, Red Hat Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2
- * or later. See the COPYING file in the top-level directory.
- */
-#ifndef SLIRP_DHCPV6_H
-#define SLIRP_DHCPV6_H
-
-#define DHCPV6_SERVER_PORT 547
-
-#define ALLDHCP_MULTICAST { .s6_addr = \
-                            { 0xff, 0x02, 0x00, 0x00,\
-                            0x00, 0x00, 0x00, 0x00,\
-                            0x00, 0x00, 0x00, 0x00,\
-                            0x00, 0x01, 0x00, 0x02 } }
-
-void dhcpv6_input(struct sockaddr_in6 *srcsas, struct mbuf *m);
-
-#endif
index 8fb5633..aed2f13 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "slirp.h"
 
 static const uint8_t RFC3397_OPT_DOMAIN_SEARCH = 119;
@@ -261,7 +262,7 @@ int translate_dnssearch(Slirp *s, const char **names)
     }
 
     /* reserve extra 2 header bytes for each 255 bytes of output */
-    memreq += DIV_ROUND_UP(memreq, MAX_OPT_LEN) * OPT_HEADER_LEN;
+    memreq += ((memreq + MAX_OPT_LEN - 1) / MAX_OPT_LEN) * OPT_HEADER_LEN;
     result = g_malloc(memreq * sizeof(*result));
 
     outptr = result;
@@ -288,7 +289,7 @@ int translate_dnssearch(Slirp *s, const char **names)
     domain_mkxrefs(domains, domains + num_domains - 1, 0);
     memreq = domain_compactify(domains, num_domains);
 
-    blocks = DIV_ROUND_UP(memreq, MAX_OPT_LEN);
+    blocks = (memreq + MAX_OPT_LEN - 1) / MAX_OPT_LEN;
     bsrc_end = memreq;
     bsrc_start = (blocks - 1) * MAX_OPT_LEN;
     bdst_start = bsrc_start + blocks * OPT_HEADER_LEN;
index 51ae0d0..9b02180 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
 #include "qemu/timer.h"
 
 static void
index 69569c1..c7a5c57 100644 (file)
@@ -5,8 +5,8 @@
  * terms and conditions of the copyright.
  */
 
-#ifndef IF_H
-#define IF_H
+#ifndef _IF_H_
+#define _IF_H_
 
 #define IF_COMPRESS    0x01    /* We want compression */
 #define IF_NOCOMPRESS  0x02    /* Do not do compression */
index 1df6723..e2ee5e3 100644 (file)
@@ -30,8 +30,8 @@
  * ip.h,v 1.3 1994/08/21 05:27:30 paul Exp
  */
 
-#ifndef IP_H
-#define IP_H
+#ifndef _IP_H_
+#define _IP_H_
 
 #ifdef HOST_WORDS_BIGENDIAN
 # undef NTOHL
index 0908855..8ddfa24 100644 (file)
@@ -3,8 +3,8 @@
  * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
  */
 
-#ifndef SLIRP_IP6_H
-#define SLIRP_IP6_H
+#ifndef SLIRP_IP6_H_
+#define SLIRP_IP6_H_
 
 #include "net/eth.h"
 
                         0x00, 0x00, 0x00, 0x00,\
                         0x00, 0x00, 0x00, 0x02 } }
 
-#define ZERO_ADDR  { .s6_addr = \
-                        { 0x00, 0x00, 0x00, 0x00,\
-                        0x00, 0x00, 0x00, 0x00,\
-                        0x00, 0x00, 0x00, 0x00,\
-                        0x00, 0x00, 0x00, 0x00 } }
-
 static inline bool in6_equal(const struct in6_addr *a, const struct in6_addr *b)
 {
     return memcmp(a, b, sizeof(*a)) == 0;
@@ -90,9 +84,6 @@ static inline bool in6_equal_mach(const struct in6_addr *a,
 #define in6_solicitednode_multicast(a)\
     (in6_equal_net(a, &(struct in6_addr)SOLICITED_NODE_PREFIX, 104))
 
-#define in6_zero(a)\
-    (in6_equal(a, &(struct in6_addr)ZERO_ADDR))
-
 /* Compute emulated host MAC address from its ipv6 address */
 static inline void in6_compute_ethaddr(struct in6_addr ip,
                                        uint8_t eth[ETH_ALEN])
index 6d18e28..09571bc 100644 (file)
@@ -9,6 +9,7 @@
 #include "qemu/timer.h"
 #include "qemu/error-report.h"
 #include "qemu/log.h"
+#include <time.h>
 
 #define NDP_Interval g_rand_int_range(slirp->grand, \
         NDP_MinRtrAdvInterval, NDP_MaxRtrAdvInterval)
@@ -148,11 +149,7 @@ void ndp_send_ra(Slirp *slirp)
     rip->ip_nh = IPPROTO_ICMPV6;
     rip->ip_pl = htons(ICMP6_NDP_RA_MINLEN
                         + NDPOPT_LINKLAYER_LEN
-                        + NDPOPT_PREFIXINFO_LEN
-#ifndef _WIN32
-                        + NDPOPT_RDNSS_LEN
-#endif
-                        );
+                        + NDPOPT_PREFIXINFO_LEN);
     t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl);
 
     /* Build ICMPv6 packet */
@@ -170,16 +167,16 @@ void ndp_send_ra(Slirp *slirp)
     ricmp->icmp6_nra.lifetime = htons(NDP_AdvDefaultLifetime);
     ricmp->icmp6_nra.reach_time = htonl(NDP_AdvReachableTime);
     ricmp->icmp6_nra.retrans_time = htonl(NDP_AdvRetransTime);
-    t->m_data += ICMP6_NDP_RA_MINLEN;
 
     /* Source link-layer address (NDP option) */
+    t->m_data += ICMP6_NDP_RA_MINLEN;
     struct ndpopt *opt = mtod(t, struct ndpopt *);
     opt->ndpopt_type = NDPOPT_LINKLAYER_SOURCE;
     opt->ndpopt_len = NDPOPT_LINKLAYER_LEN / 8;
     in6_compute_ethaddr(rip->ip_src, opt->ndpopt_linklayer);
-    t->m_data += NDPOPT_LINKLAYER_LEN;
 
     /* Prefix information (NDP option) */
+    t->m_data += NDPOPT_LINKLAYER_LEN;
     struct ndpopt *opt2 = mtod(t, struct ndpopt *);
     opt2->ndpopt_type = NDPOPT_PREFIX_INFO;
     opt2->ndpopt_len = NDPOPT_PREFIXINFO_LEN / 8;
@@ -191,25 +188,8 @@ void ndp_send_ra(Slirp *slirp)
     opt2->ndpopt_prefixinfo.pref_lt = htonl(NDP_AdvPrefLifetime);
     opt2->ndpopt_prefixinfo.reserved2 = 0;
     opt2->ndpopt_prefixinfo.prefix = slirp->vprefix_addr6;
-    t->m_data += NDPOPT_PREFIXINFO_LEN;
-
-#ifndef _WIN32
-    /* Prefix information (NDP option) */
-    /* disabled for windows for now, until get_dns6_addr is implemented */
-    struct ndpopt *opt3 = mtod(t, struct ndpopt *);
-    opt3->ndpopt_type = NDPOPT_RDNSS;
-    opt3->ndpopt_len = NDPOPT_RDNSS_LEN / 8;
-    opt3->ndpopt_rdnss.reserved = 0;
-    opt3->ndpopt_rdnss.lifetime = htonl(2 * NDP_MaxRtrAdvInterval);
-    opt3->ndpopt_rdnss.addr = slirp->vnameserver_addr6;
-    t->m_data += NDPOPT_RDNSS_LEN;
-#endif
 
     /* ICMPv6 Checksum */
-#ifndef _WIN32
-    t->m_data -= NDPOPT_RDNSS_LEN;
-#endif
-    t->m_data -= NDPOPT_PREFIXINFO_LEN;
     t->m_data -= NDPOPT_LINKLAYER_LEN;
     t->m_data -= ICMP6_NDP_RA_MINLEN;
     t->m_data -= sizeof(struct ip6);
index b3378b1..9460bf8 100644 (file)
@@ -3,8 +3,8 @@
  * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
  */
 
-#ifndef SLIRP_IP6_ICMP_H
-#define SLIRP_IP6_ICMP_H
+#ifndef SLIRP_NETINET_ICMP6_H_
+#define SLIRP_NETINET_ICMP6_H_
 
 /*
  * Interface Control Message Protocol version 6 Definitions.
@@ -122,7 +122,6 @@ struct ndpopt {
     uint8_t     ndpopt_len;                     /* /!\ In units of 8 octets */
     union {
         unsigned char   linklayer_addr[6];      /* Source/Target Link-layer */
-#define ndpopt_linklayer ndpopt_body.linklayer_addr
         struct prefixinfo {                     /* Prefix Information */
             uint8_t     prefix_length;
 #ifdef HOST_WORDS_BIGENDIAN
@@ -135,26 +134,19 @@ struct ndpopt {
             uint32_t    reserved2;
             struct in6_addr prefix;
         } QEMU_PACKED prefixinfo;
-#define ndpopt_prefixinfo ndpopt_body.prefixinfo
-        struct rdnss {
-            uint16_t reserved;
-            uint32_t lifetime;
-            struct in6_addr addr;
-        } QEMU_PACKED rdnss;
-#define ndpopt_rdnss ndpopt_body.rdnss
     } ndpopt_body;
+#define ndpopt_linklayer ndpopt_body.linklayer_addr
+#define ndpopt_prefixinfo ndpopt_body.prefixinfo
 } QEMU_PACKED;
 
 /* NDP options type */
 #define NDPOPT_LINKLAYER_SOURCE     1   /* Source Link-Layer Address */
 #define NDPOPT_LINKLAYER_TARGET     2   /* Target Link-Layer Address */
 #define NDPOPT_PREFIX_INFO          3   /* Prefix Information */
-#define NDPOPT_RDNSS                25  /* Recursive DNS Server Address */
 
 /* NDP options size, in octets. */
 #define NDPOPT_LINKLAYER_LEN    8
 #define NDPOPT_PREFIXINFO_LEN   32
-#define NDPOPT_RDNSS_LEN        24
 
 /*
  * Definition of type and code field values.
index d88ab34..846761d 100644 (file)
@@ -30,8 +30,8 @@
  * ip_icmp.h,v 1.4 1995/05/30 08:09:43 rgrimes Exp
  */
 
-#ifndef NETINET_IP_ICMP_H
-#define NETINET_IP_ICMP_H
+#ifndef _NETINET_IP_ICMP_H_
+#define _NETINET_IP_ICMP_H_
 
 /*
  * Interface Control Message Protocol Definitions.
index 348e1dc..cdd5483 100644 (file)
@@ -39,7 +39,8 @@
  */
 
 #include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
+#include <qemu/osdep.h>
 #include "ip_icmp.h"
 
 static struct ip *ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp);
index db403f0..0d6b3b8 100644 (file)
@@ -39,7 +39,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
 
 /* Number of packets queued before we start sending
  * (to prevent allocing too many mbufs) */
index f90f0f5..127aa41 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef LIBSLIRP_H
-#define LIBSLIRP_H
+#ifndef _LIBSLIRP_H
+#define _LIBSLIRP_H
 
 #include "qemu-common.h"
 
@@ -7,7 +7,6 @@ struct Slirp;
 typedef struct Slirp Slirp;
 
 int get_dns_addr(struct in_addr *pdns_addr);
-int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id);
 
 Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
                   struct in_addr vnetmask, struct in_addr vhost,
index 90053ce..f2e58cf 100644 (file)
@@ -4,9 +4,8 @@
  * Please read the file COPYRIGHT for the
  * terms and conditions of the copyright.
  */
-
 #ifndef SLIRP_MAIN_H
-#define SLIRP_MAIN_H
+#define SLIRP_MAIN_H 1
 
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
index 7eddc21..d136988 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
 
 #define MBUF_THRESH 30
 
index 893601f..36fb814 100644 (file)
@@ -30,8 +30,8 @@
  * mbuf.h,v 1.9 1994/11/14 13:54:20 bde Exp
  */
 
-#ifndef MBUF_H
-#define MBUF_H
+#ifndef _MBUF_H_
+#define _MBUF_H_
 
 #define MINCSIZE 4096  /* Amount to increase mbuf if too small */
 
index 88e9d94..2fbd048 100644 (file)
@@ -6,8 +6,9 @@
  */
 
 #include "qemu/osdep.h"
-#include "slirp.h"
-#include "libslirp.h"
+#include <slirp.h>
+#include <libslirp.h>
+
 #include "monitor/monitor.h"
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
@@ -59,6 +60,27 @@ int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec,
        return 0;
 }
 
+#ifndef HAVE_STRERROR
+
+/*
+ * For systems with no strerror
+ */
+
+extern int sys_nerr;
+extern char *sys_errlist[];
+
+char *
+strerror(error)
+       int error;
+{
+       if (error < sys_nerr)
+          return sys_errlist[error];
+       else
+          return "Unknown error.";
+}
+
+#endif
+
 
 #ifdef _WIN32
 
index 5211bbd..0d0c059 100644 (file)
@@ -5,8 +5,8 @@
  * terms and conditions of the copyright.
  */
 
-#ifndef MISC_H
-#define MISC_H
+#ifndef _MISC_H_
+#define _MISC_H_
 
 struct ex_list {
        int ex_pty;                     /* Do we want a pty? */
index 10119d3..dd4cb8c 100644 (file)
@@ -6,8 +6,8 @@
  */
 
 #include "qemu/osdep.h"
-#include "slirp.h"
-#include "qemu/main-loop.h"
+#include <slirp.h>
+#include <qemu/main-loop.h>
 
 static void sbappendsb(struct sbuf *sb, struct mbuf *m);
 
index efcec39..4f22e7c 100644 (file)
@@ -5,8 +5,8 @@
  * terms and conditions of the copyright.
  */
 
-#ifndef SBUF_H
-#define SBUF_H
+#ifndef _SBUF_H_
+#define _SBUF_H_
 
 #define sbflush(sb) sbdrop((sb),(sb)->sb_cc)
 #define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc)
index d67eda1..9f4bea3 100644 (file)
 #include "hw/hw.h"
 #include "qemu/cutils.h"
 
-#ifndef _WIN32
-#include <net/if.h>
-#endif
-
 /* host loopback address */
 struct in_addr loopback_addr;
 /* host loopback network mask */
@@ -50,13 +46,7 @@ static QTAILQ_HEAD(slirp_instances, Slirp) slirp_instances =
     QTAILQ_HEAD_INITIALIZER(slirp_instances);
 
 static struct in_addr dns_addr;
-#ifndef _WIN32
-static struct in6_addr dns6_addr;
-#endif
 static u_int dns_addr_time;
-#ifndef _WIN32
-static u_int dns6_addr_time;
-#endif
 
 #define TIMEOUT_FAST 2  /* milliseconds */
 #define TIMEOUT_SLOW 499  /* milliseconds */
@@ -110,11 +100,6 @@ int get_dns_addr(struct in_addr *pdns_addr)
     return 0;
 }
 
-int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id)
-{
-    return -1;
-}
-
 static void winsock_cleanup(void)
 {
     WSACleanup();
@@ -122,39 +107,33 @@ static void winsock_cleanup(void)
 
 #else
 
-static int get_dns_addr_cached(void *pdns_addr, void *cached_addr,
-                               socklen_t addrlen,
-                               struct stat *cached_stat, u_int *cached_time)
-{
-    struct stat old_stat;
-    if (curtime - *cached_time < TIMEOUT_DEFAULT) {
-        memcpy(pdns_addr, cached_addr, addrlen);
-        return 0;
-    }
-    old_stat = *cached_stat;
-    if (stat("/etc/resolv.conf", cached_stat) != 0) {
-        return -1;
-    }
-    if (cached_stat->st_dev == old_stat.st_dev
-        && cached_stat->st_ino == old_stat.st_ino
-        && cached_stat->st_size == old_stat.st_size
-        && cached_stat->st_mtime == old_stat.st_mtime) {
-        memcpy(pdns_addr, cached_addr, addrlen);
-        return 0;
-    }
-    return 1;
-}
+static struct stat dns_addr_stat;
 
-static int get_dns_addr_resolv_conf(int af, void *pdns_addr, void *cached_addr,
-                                    socklen_t addrlen, uint32_t *scope_id,
-                                    u_int *cached_time)
+int get_dns_addr(struct in_addr *pdns_addr)
 {
     char buff[512];
     char buff2[257];
     FILE *f;
     int found = 0;
-    void *tmp_addr = alloca(addrlen);
-    unsigned if_index;
+    struct in_addr tmp_addr;
+
+    if (dns_addr.s_addr != 0) {
+        struct stat old_stat;
+        if ((curtime - dns_addr_time) < TIMEOUT_DEFAULT) {
+            *pdns_addr = dns_addr;
+            return 0;
+        }
+        old_stat = dns_addr_stat;
+        if (stat("/etc/resolv.conf", &dns_addr_stat) != 0)
+            return -1;
+        if ((dns_addr_stat.st_dev == old_stat.st_dev)
+            && (dns_addr_stat.st_ino == old_stat.st_ino)
+            && (dns_addr_stat.st_size == old_stat.st_size)
+            && (dns_addr_stat.st_mtime == old_stat.st_mtime)) {
+            *pdns_addr = dns_addr;
+            return 0;
+        }
+    }
 
     f = fopen("/etc/resolv.conf", "r");
     if (!f)
@@ -165,25 +144,13 @@ static int get_dns_addr_resolv_conf(int af, void *pdns_addr, void *cached_addr,
 #endif
     while (fgets(buff, 512, f) != NULL) {
         if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
-            char *c = strchr(buff2, '%');
-            if (c) {
-                if_index = if_nametoindex(c + 1);
-                *c = '\0';
-            } else {
-                if_index = 0;
-            }
-
-            if (!inet_pton(af, buff2, tmp_addr)) {
+            if (!inet_aton(buff2, &tmp_addr))
                 continue;
-            }
             /* If it's the first one, set it to dns_addr */
             if (!found) {
-                memcpy(pdns_addr, tmp_addr, addrlen);
-                memcpy(cached_addr, tmp_addr, addrlen);
-                if (scope_id) {
-                    *scope_id = if_index;
-                }
-                *cached_time = curtime;
+                *pdns_addr = tmp_addr;
+                dns_addr = tmp_addr;
+                dns_addr_time = curtime;
             }
 #ifdef DEBUG
             else
@@ -196,14 +163,8 @@ static int get_dns_addr_resolv_conf(int af, void *pdns_addr, void *cached_addr,
                 break;
             }
 #ifdef DEBUG
-            else {
-                char s[INET6_ADDRSTRLEN];
-                char *res = inet_ntop(af, tmp_addr, s, sizeof(s));
-                if (!res) {
-                    res = "(string conversion error)";
-                }
-                fprintf(stderr, "%s", res);
-            }
+            else
+                fprintf(stderr, "%s", inet_ntoa(tmp_addr));
 #endif
         }
     }
@@ -213,39 +174,6 @@ static int get_dns_addr_resolv_conf(int af, void *pdns_addr, void *cached_addr,
     return 0;
 }
 
-int get_dns_addr(struct in_addr *pdns_addr)
-{
-    static struct stat dns_addr_stat;
-
-    if (dns_addr.s_addr != 0) {
-        int ret;
-        ret = get_dns_addr_cached(pdns_addr, &dns_addr, sizeof(dns_addr),
-                                  &dns_addr_stat, &dns_addr_time);
-        if (ret <= 0) {
-            return ret;
-        }
-    }
-    return get_dns_addr_resolv_conf(AF_INET, pdns_addr, &dns_addr,
-                                    sizeof(dns_addr), NULL, &dns_addr_time);
-}
-
-int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id)
-{
-    static struct stat dns6_addr_stat;
-
-    if (!in6_zero(&dns6_addr)) {
-        int ret;
-        ret = get_dns_addr_cached(pdns6_addr, &dns6_addr, sizeof(dns6_addr),
-                                  &dns6_addr_stat, &dns6_addr_time);
-        if (ret <= 0) {
-            return ret;
-        }
-    }
-    return get_dns_addr_resolv_conf(AF_INET6, pdns6_addr, &dns6_addr,
-                                    sizeof(dns6_addr),
-                                    scope_id, &dns6_addr_time);
-}
-
 #endif
 
 static void slirp_init_once(void)
@@ -773,10 +701,10 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
 
 static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
 {
-    struct slirp_arphdr *ah = (struct slirp_arphdr *)(pkt + ETH_HLEN);
-    uint8_t arp_reply[max(ETH_HLEN + sizeof(struct slirp_arphdr), 64)];
+    struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
+    uint8_t arp_reply[max(ETH_HLEN + sizeof(struct arphdr), 64)];
     struct ethhdr *reh = (struct ethhdr *)arp_reply;
-    struct slirp_arphdr *rah = (struct slirp_arphdr *)(arp_reply + ETH_HLEN);
+    struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
     int ar_op;
     struct ex_list *ex_ptr;
 
@@ -890,9 +818,9 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
         return 1;
     }
     if (!arp_table_search(slirp, iph->ip_dst.s_addr, ethaddr)) {
-        uint8_t arp_req[ETH_HLEN + sizeof(struct slirp_arphdr)];
+        uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
         struct ethhdr *reh = (struct ethhdr *)arp_req;
-        struct slirp_arphdr *rah = (struct slirp_arphdr *)(arp_req + ETH_HLEN);
+        struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
 
         if (!ifm->resolution_requested) {
             /* If the client addr is not known, send an ARP request */
@@ -1197,8 +1125,8 @@ static void slirp_socket_save(QEMUFile *f, struct socket *so)
         qemu_put_be16(f, so->so_fport);
         break;
     default:
-        error_report("so_ffamily unknown, unable to save so_faddr and"
-                     " so_fport");
+        error_report(
+                "so_ffamily unknown, unable to save so_faddr and so_fport\n");
     }
     qemu_put_be16(f, so->so_lfamily);
     switch (so->so_lfamily) {
@@ -1207,8 +1135,8 @@ static void slirp_socket_save(QEMUFile *f, struct socket *so)
         qemu_put_be16(f, so->so_lport);
         break;
     default:
-        error_report("so_ffamily unknown, unable to save so_laddr and"
-                     " so_lport");
+        error_report(
+                "so_ffamily unknown, unable to save so_laddr and so_lport\n");
     }
     qemu_put_byte(f, so->so_iptos);
     qemu_put_byte(f, so->so_emu);
index a1f3139..203deec 100644 (file)
@@ -1,7 +1,6 @@
-#ifndef SLIRP_H
-#define SLIRP_H
+#ifndef __COMMON_H__
+#define __COMMON_H__
 
-#include "qemu/host-utils.h"
 #include "slirp_config.h"
 
 #ifdef _WIN32
@@ -24,6 +23,11 @@ typedef char *caddr_t;
 # include <sys/bitypes.h>
 #endif
 
+
+#ifndef HAVE_MEMMOVE
+#define memmove(x, y, z) bcopy(y, x, z)
+#endif
+
 #ifndef _WIN32
 #include <sys/uio.h>
 #endif
@@ -33,6 +37,17 @@ typedef char *caddr_t;
 #include <arpa/inet.h>
 #endif
 
+/* Systems lacking strdup() definition in <string.h>. */
+#if defined(ultrix)
+char *strdup(const char *);
+#endif
+
+/* Systems lacking malloc() definition in <stdlib.h>. */
+#if defined(ultrix) || defined(hcx)
+void *malloc(size_t arg);
+void free(void *ptr);
+#endif
+
 #ifndef NO_UNIX_SOCKETS
 #include <sys/un.h>
 #endif
@@ -59,6 +74,10 @@ typedef char *caddr_t;
 # include <sys/filio.h>
 #endif
 
+#ifdef USE_PPP
+#include <ppp/slirppp.h>
+#endif
+
 /* Avoid conflicting with the libc insque() and remque(), which
    have different prototypes. */
 #define insque slirp_insque
@@ -69,6 +88,7 @@ typedef char *caddr_t;
 #include <sys/stropts.h>
 #endif
 
+#include <glib.h>
 
 #include "debug.h"
 
@@ -92,6 +112,10 @@ typedef char *caddr_t;
 #include "if.h"
 #include "main.h"
 #include "misc.h"
+#ifdef USE_PPP
+#include "ppp/pppd.h"
+#include "ppp/ppp.h"
+#endif
 
 #include "bootp.h"
 #include "tftp.h"
@@ -105,7 +129,7 @@ struct ethhdr {
     unsigned short h_proto;            /* packet type ID field */
 };
 
-struct slirp_arphdr {
+struct arphdr {
     unsigned short ar_hrd;      /* format of hardware address */
     unsigned short ar_pro;      /* format of protocol address */
     unsigned char  ar_hln;      /* length of hardware address */
@@ -124,7 +148,7 @@ struct slirp_arphdr {
 #define ARP_TABLE_SIZE 16
 
 typedef struct ArpTable {
-    struct slirp_arphdr table[ARP_TABLE_SIZE];
+    struct arphdr table[ARP_TABLE_SIZE];
     int next_victim;
 } ArpTable;
 
@@ -229,12 +253,30 @@ extern Slirp *slirp_instance;
 #define NULL (void *)0
 #endif
 
+#ifndef FULL_BOLT
 void if_start(Slirp *);
+#else
+void if_start(struct ttys *);
+#endif
+
+#ifndef HAVE_STRERROR
+ char *strerror(int error);
+#endif
+
+#ifndef HAVE_INDEX
+ char *index(const char *, int);
+#endif
+
+#ifndef HAVE_GETHOSTID
+ long gethostid(void);
+#endif
 
 #ifndef _WIN32
 #include <netdb.h>
 #endif
 
+#define DEFAULT_BAUD 115200
+
 #define SO_OPTIONS DO_KEEPALIVE
 #define TCP_MAXIDLE (TCPTV_KEEPCNT * TCPTV_KEEPINTVL)
 
@@ -292,6 +334,14 @@ int tcp_emu(struct socket *, struct mbuf *);
 int tcp_ctl(struct socket *);
 struct tcpcb *tcp_drop(struct tcpcb *tp, int err);
 
+#ifdef USE_PPP
+#define MIN_MRU MINMRU
+#define MAX_MRU MAXMRU
+#else
+#define MIN_MRU 128
+#define MAX_MRU 16384
+#endif
+
 #ifndef _WIN32
 #define min(x,y) ((x) < (y) ? (x) : (y))
 #define max(x,y) ((x) > (y) ? (x) : (y))
index c59f655..896d802 100644 (file)
@@ -9,6 +9,19 @@
 /* Define to 1 if you want KEEPALIVE timers */
 #define DO_KEEPALIVE 0
 
+/* Define to MAX interfaces you expect to use at once */
+/* MAX_INTERFACES determines the max. TOTAL number of interfaces (SLIP and PPP) */
+/* MAX_PPP_INTERFACES determines max. number of PPP interfaces */
+#define MAX_INTERFACES 1
+#define MAX_PPP_INTERFACES 1
+
+/* Define if you want slirp's socket in /tmp */
+/* XXXXXX Do this in ./configure */
+#undef USE_TMPSOCKET
+
+/* Define if you want slirp to use cfsetXspeed() on the terminal */
+#undef DO_CFSETSPEED
+
 /* Define this if you want slirp to write to the tty as fast as it can */
 /* This should only be set if you are using load-balancing, slirp does a */
 /* pretty good job on single modems already, and seting this will make */
 /* XXXXX Talk about having fast modem as unit 0 */
 #undef FULL_BOLT
 
+/*
+ * Define if you want slirp to use less CPU
+ * You will notice a small lag in interactive sessions, but it's not that bad
+ * Things like Netscape/ftp/etc. are completely unaffected
+ * This is mainly for sysadmins who have many slirp users
+ */
+#undef USE_LOWCPU
+
+/* Define this if your compiler doesn't like prototypes */
+#ifndef __STDC__
+#define NO_PROTOTYPES
+#endif
+
 /*********************************************************/
 /*
  * Autoconf defined configuration options
  * You shouldn't need to touch any of these
  */
 
+/* Ignore this */
+#undef DUMMY_PPP
+
+/* Define if you have unistd.h */
+#define HAVE_UNISTD_H
+
+/* Define if you have stdlib.h */
+#define HAVE_STDLIB_H
+
 /* Define if you have sys/ioctl.h */
 #undef HAVE_SYS_IOCTL_H
 #ifndef _WIN32
 #define HAVE_SYS_FILIO_H
 #endif
 
+/* Define if you have strerror */
+#define HAVE_STRERROR
+
+/* Define according to how time.h should be included */
+#define TIME_WITH_SYS_TIME 0
+#undef HAVE_SYS_TIME_H
+
 /* Define if you have sys/bitypes.h */
 #undef HAVE_SYS_BITYPES_H
 
 #define HAVE_SYS_SELECT_H
 #endif
 
+/* Define if you have strings.h */
+#define HAVE_STRING_H
+
 /* Define if you have arpa/inet.h */
 #undef HAVE_ARPA_INET_H
 #ifndef _WIN32
 /* Define if you have sys/stropts.h */
 #undef HAVE_SYS_STROPTS_H
 
+/* Define to whatever your compiler thinks inline should be */
+//#define inline inline
+
+/* Define to whatever your compiler thinks const should be */
+//#define const const
+
+/* Define if your compiler doesn't like prototypes */
+#undef NO_PROTOTYPES
+
+/* Define to sizeof(char) */
+#define SIZEOF_CHAR 1
+
+/* Define to sizeof(short) */
+#define SIZEOF_SHORT 2
+
+/* Define to sizeof(int) */
+#define SIZEOF_INT 4
+
 /* Define to sizeof(char *) */
 #define SIZEOF_CHAR_P (HOST_LONG_BITS / 8)
 
+/* Define if you have random() */
+#undef HAVE_RANDOM
+
+/* Define if you have srandom() */
+#undef HAVE_SRANDOM
+
 /* Define if you have inet_aton */
 #undef HAVE_INET_ATON
 #ifndef _WIN32
 #define HAVE_INET_ATON
 #endif
 
+/* Define if you have setenv */
+#undef HAVE_SETENV
+
+/* Define if you have index() */
+#define HAVE_INDEX
+
+/* Define if you have bcmp() */
+#undef HAVE_BCMP
+
+/* Define if you have drand48 */
+#undef HAVE_DRAND48
+
+/* Define if you have memmove */
+#define HAVE_MEMMOVE
+
+/* Define if you have gethostid */
+#define HAVE_GETHOSTID
+
 /* Define if you DON'T have unix-domain sockets */
 #undef NO_UNIX_SOCKETS
 #ifdef _WIN32
 #define NO_UNIX_SOCKETS
 #endif
+
+/* Define if you have revoke() */
+#undef HAVE_REVOKE
+
+/* Define if you have the sysv method of opening pty's (/dev/ptmx, etc.) */
+#undef HAVE_GRANTPT
+
+/* Define if you have fchmod */
+#undef HAVE_FCHMOD
+
+/* Define if you have <sys/type32.h> */
+#undef HAVE_SYS_TYPES32_H
index 280050a..b336586 100644 (file)
@@ -7,7 +7,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "slirp.h"
+#include <slirp.h>
 #include "ip_icmp.h"
 #ifdef __sun__
 #include <sys/filio.h>
@@ -816,12 +816,9 @@ void sotranslate_out(struct socket *so, struct sockaddr_storage *addr)
         if (in6_equal_net(&so->so_faddr6, &slirp->vprefix_addr6,
                     slirp->vprefix_len)) {
             if (in6_equal(&so->so_faddr6, &slirp->vnameserver_addr6)) {
-                uint32_t scope_id;
-                if (get_dns6_addr(&sin6->sin6_addr, &scope_id) >= 0) {
-                    sin6->sin6_scope_id = scope_id;
-                } else {
+                /*if (get_dns_addr(&addr) < 0) {*/ /* TODO */
                     sin6->sin6_addr = in6addr_loopback;
-                }
+                /*}*/
             } else {
                 sin6->sin6_addr = in6addr_loopback;
             }
index 8feed2a..b602e69 100644 (file)
@@ -5,8 +5,8 @@
  * terms and conditions of the copyright.
  */
 
-#ifndef SLIRP_SOCKET_H
-#define SLIRP_SOCKET_H
+#ifndef _SLIRP_SOCKET_H_
+#define _SLIRP_SOCKET_H_
 
 #define SO_EXPIRE 240000
 #define SO_EXPIREFAST 10000
@@ -158,4 +158,4 @@ void sotranslate_in(struct socket *, struct sockaddr_storage *);
 void sotranslate_accept(struct socket *);
 
 
-#endif /* SLIRP_SOCKET_H */
+#endif /* _SOCKET_H_ */
index 174d3d9..61befcd 100644 (file)
@@ -30,8 +30,8 @@
  * tcp.h,v 1.3 1994/08/21 05:27:34 paul Exp
  */
 
-#ifndef TCP_H
-#define TCP_H
+#ifndef _TCP_H_
+#define _TCP_H_
 
 typedef        uint32_t tcp_seq;
 
index c5063a9..e2b5d4e 100644 (file)
@@ -39,7 +39,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
 #include "ip_icmp.h"
 
 #define        TCPREXMTTHRESH 3
index 819db27..99b0a9b 100644 (file)
@@ -39,7 +39,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
 
 static const u_char  tcp_outflags[TCP_NSTATES] = {
        TH_RST|TH_ACK, 0,      TH_SYN,        TH_SYN|TH_ACK,
index ed16e18..6b9fef2 100644 (file)
@@ -39,7 +39,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
 
 /* patchable/settable parameters for tcp */
 /* Don't do rfc1323 performance enhancements */
index f9060c7..8f5dd77 100644 (file)
@@ -31,7 +31,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
 
 static struct tcpcb *tcp_timers(register struct tcpcb *tp, int timer);
 
index b25b391..ff17914 100644 (file)
@@ -30,8 +30,8 @@
  * tcp_timer.h,v 1.4 1994/08/21 05:27:38 paul Exp
  */
 
-#ifndef TCP_TIMER_H
-#define TCP_TIMER_H
+#ifndef _TCP_TIMER_H_
+#define _TCP_TIMER_H_
 
 /*
  * Definitions of the TCP timers.  These timers are counted
index 0f8f187..004193f 100644 (file)
@@ -30,8 +30,8 @@
  * tcp_var.h,v 1.3 1994/08/21 05:27:39 paul Exp
  */
 
-#ifndef TCP_VAR_H
-#define TCP_VAR_H
+#ifndef _TCP_VAR_H_
+#define _TCP_VAR_H_
 
 #include "tcpip.h"
 #include "tcp_timer.h"
index 7bdb971..124b4a9 100644 (file)
@@ -30,8 +30,8 @@
  * tcpip.h,v 1.3 1994/08/21 05:27:40 paul Exp
  */
 
-#ifndef TCPIP_H
-#define TCPIP_H
+#ifndef _TCPIP_H_
+#define _TCPIP_H_
 
 /*
  * Tcp+ip header, after ip options removed.
index c185906..12b5ff6 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
 #include "qemu-common.h"
 #include "qemu/cutils.h"
 
@@ -208,6 +208,8 @@ static void tftp_send_error(struct tftp_session *spt,
     goto out;
   }
 
+  memset(m->m_data, 0, m->m_size);
+
   tp = tftp_prep_mbuf_data(spt, m);
 
   tp->tp_op = htons(TFTP_ERROR);
@@ -235,6 +237,8 @@ static void tftp_send_next_block(struct tftp_session *spt,
     return;
   }
 
+  memset(m->m_data, 0, m->m_size);
+
   tp = tftp_prep_mbuf_data(spt, m);
 
   tp->tp_op = htons(TFTP_DATA);
index 2cd276d..1cb1adf 100644 (file)
@@ -1,7 +1,6 @@
 /* tftp defines */
-
 #ifndef SLIRP_TFTP_H
-#define SLIRP_TFTP_H
+#define SLIRP_TFTP_H 1
 
 #define TFTP_SESSIONS_MAX 20
 
index 93d7224..247024f 100644 (file)
@@ -39,7 +39,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
 #include "ip_icmp.h"
 
 static uint8_t udp_tos(struct socket *so);
index be657cf..10cc780 100644 (file)
@@ -30,8 +30,8 @@
  * udp.h,v 1.3 1994/08/21 05:27:41 paul Exp
  */
 
-#ifndef UDP_H
-#define UDP_H
+#ifndef _UDP_H_
+#define _UDP_H_
 
 #define UDP_TTL 0x60
 #define UDP_UDPDATALEN 16192
index 9fa314b..a23026f 100644 (file)
@@ -6,8 +6,8 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "slirp.h"
+#include "qemu/osdep.h"
 #include "udp.h"
-#include "dhcpv6.h"
 
 void udp6_input(struct mbuf *m)
 {
@@ -62,17 +62,7 @@ void udp6_input(struct mbuf *m)
     lhost.sin6_addr = ip->ip_src;
     lhost.sin6_port = uh->uh_sport;
 
-    /* handle DHCPv6 */
-    if (ntohs(uh->uh_dport) == DHCPV6_SERVER_PORT &&
-        (in6_equal(&ip->ip_dst, &slirp->vhost_addr6) ||
-         in6_equal(&ip->ip_dst, &(struct in6_addr)ALLDHCP_MULTICAST))) {
-        m->m_data += iphlen;
-        m->m_len -= iphlen;
-        dhcpv6_input(&lhost, m);
-        m->m_data -= iphlen;
-        m->m_len += iphlen;
-        goto bad;
-    }
+    /* TODO handle DHCP/BOOTP */
 
     /* handle TFTP */
     if (ntohs(uh->uh_dport) == TFTP_SERVER &&
index 284ab2c..208f808 100644 (file)
 # define helper_te_st_name  helper_le_st_name
 #endif
 
+/* macro to check the victim tlb */
+#define VICTIM_TLB_HIT(ty)                                                    \
+({                                                                            \
+    /* we are about to do a page table walk. our last hope is the             \
+     * victim tlb. try to refill from the victim tlb before walking the       \
+     * page table. */                                                         \
+    int vidx;                                                                 \
+    CPUIOTLBEntry tmpiotlb;                                                   \
+    CPUTLBEntry tmptlb;                                                       \
+    for (vidx = CPU_VTLB_SIZE-1; vidx >= 0; --vidx) {                         \
+        if (env->tlb_v_table[mmu_idx][vidx].ty == (addr & TARGET_PAGE_MASK)) {\
+            /* found entry in victim tlb, swap tlb and iotlb */               \
+            tmptlb = env->tlb_table[mmu_idx][index];                          \
+            env->tlb_table[mmu_idx][index] = env->tlb_v_table[mmu_idx][vidx]; \
+            env->tlb_v_table[mmu_idx][vidx] = tmptlb;                         \
+            tmpiotlb = env->iotlb[mmu_idx][index];                            \
+            env->iotlb[mmu_idx][index] = env->iotlb_v[mmu_idx][vidx];         \
+            env->iotlb_v[mmu_idx][vidx] = tmpiotlb;                           \
+            break;                                                            \
+        }                                                                     \
+    }                                                                         \
+    /* return true when there is a vtlb hit, i.e. vidx >=0 */                 \
+    vidx >= 0;                                                                \
+})
+
 #ifndef SOFTMMU_CODE_ACCESS
 static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
                                               CPUIOTLBEntry *iotlbentry,
@@ -146,22 +171,21 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
     unsigned mmu_idx = get_mmuidx(oi);
     int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
-    int a_bits = get_alignment_bits(get_memop(oi));
     uintptr_t haddr;
     DATA_TYPE res;
 
     /* Adjust the given return address.  */
     retaddr -= GETPC_ADJ;
 
-    if (a_bits > 0 && (addr & ((1 << a_bits) - 1)) != 0) {
-        cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
-                             mmu_idx, retaddr);
-    }
-
     /* If the TLB entry is for a different page, reload and try again.  */
     if ((addr & TARGET_PAGE_MASK)
          != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        if (!VICTIM_TLB_HIT(ADDR_READ, addr)) {
+        if ((addr & (DATA_SIZE - 1)) != 0
+            && (get_memop(oi) & MO_AMASK) == MO_ALIGN) {
+            cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
+                                 mmu_idx, retaddr);
+        }
+        if (!VICTIM_TLB_HIT(ADDR_READ)) {
             tlb_fill(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
                      mmu_idx, retaddr);
         }
@@ -191,6 +215,10 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
         DATA_TYPE res1, res2;
         unsigned shift;
     do_unaligned_access:
+        if ((get_memop(oi) & MO_AMASK) == MO_ALIGN) {
+            cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
+                                 mmu_idx, retaddr);
+        }
         addr1 = addr & ~(DATA_SIZE - 1);
         addr2 = addr1 + DATA_SIZE;
         /* Note the adjustment at the beginning of the function.
@@ -204,6 +232,13 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
         return res;
     }
 
+    /* Handle aligned access or unaligned access in the same page.  */
+    if ((addr & (DATA_SIZE - 1)) != 0
+        && (get_memop(oi) & MO_AMASK) == MO_ALIGN) {
+        cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
+                             mmu_idx, retaddr);
+    }
+
     haddr = addr + env->tlb_table[mmu_idx][index].addend;
 #if DATA_SIZE == 1
     res = glue(glue(ld, LSUFFIX), _p)((uint8_t *)haddr);
@@ -220,22 +255,21 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
     unsigned mmu_idx = get_mmuidx(oi);
     int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
-    int a_bits = get_alignment_bits(get_memop(oi));
     uintptr_t haddr;
     DATA_TYPE res;
 
     /* Adjust the given return address.  */
     retaddr -= GETPC_ADJ;
 
-    if (a_bits > 0 && (addr & ((1 << a_bits) - 1)) != 0) {
-        cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
-                             mmu_idx, retaddr);
-    }
-
     /* If the TLB entry is for a different page, reload and try again.  */
     if ((addr & TARGET_PAGE_MASK)
          != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        if (!VICTIM_TLB_HIT(ADDR_READ, addr)) {
+        if ((addr & (DATA_SIZE - 1)) != 0
+            && (get_memop(oi) & MO_AMASK) == MO_ALIGN) {
+            cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
+                                 mmu_idx, retaddr);
+        }
+        if (!VICTIM_TLB_HIT(ADDR_READ)) {
             tlb_fill(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
                      mmu_idx, retaddr);
         }
@@ -265,6 +299,10 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
         DATA_TYPE res1, res2;
         unsigned shift;
     do_unaligned_access:
+        if ((get_memop(oi) & MO_AMASK) == MO_ALIGN) {
+            cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
+                                 mmu_idx, retaddr);
+        }
         addr1 = addr & ~(DATA_SIZE - 1);
         addr2 = addr1 + DATA_SIZE;
         /* Note the adjustment at the beginning of the function.
@@ -278,6 +316,13 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
         return res;
     }
 
+    /* Handle aligned access or unaligned access in the same page.  */
+    if ((addr & (DATA_SIZE - 1)) != 0
+        && (get_memop(oi) & MO_AMASK) == MO_ALIGN) {
+        cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
+                             mmu_idx, retaddr);
+    }
+
     haddr = addr + env->tlb_table[mmu_idx][index].addend;
     res = glue(glue(ld, LSUFFIX), _be_p)((uint8_t *)haddr);
     return res;
@@ -331,21 +376,20 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
     unsigned mmu_idx = get_mmuidx(oi);
     int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
-    int a_bits = get_alignment_bits(get_memop(oi));
     uintptr_t haddr;
 
     /* Adjust the given return address.  */
     retaddr -= GETPC_ADJ;
 
-    if (a_bits > 0 && (addr & ((1 << a_bits) - 1)) != 0) {
-        cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
-                             mmu_idx, retaddr);
-    }
-
     /* If the TLB entry is for a different page, reload and try again.  */
     if ((addr & TARGET_PAGE_MASK)
         != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        if (!VICTIM_TLB_HIT(addr_write, addr)) {
+        if ((addr & (DATA_SIZE - 1)) != 0
+            && (get_memop(oi) & MO_AMASK) == MO_ALIGN) {
+            cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
+                                 mmu_idx, retaddr);
+        }
+        if (!VICTIM_TLB_HIT(addr_write)) {
             tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr);
         }
         tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
@@ -370,25 +414,16 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
     if (DATA_SIZE > 1
         && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
                      >= TARGET_PAGE_SIZE)) {
-        int i, index2;
-        target_ulong page2, tlb_addr2;
+        int i;
     do_unaligned_access:
-        /* Ensure the second page is in the TLB.  Note that the first page
-           is already guaranteed to be filled, and that the second page
-           cannot evict the first.  */
-        page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
-        index2 = (page2 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-        tlb_addr2 = env->tlb_table[mmu_idx][index2].addr_write;
-        if (page2 != (tlb_addr2 & (TARGET_PAGE_MASK | TLB_INVALID_MASK))
-            && !VICTIM_TLB_HIT(addr_write, page2)) {
-            tlb_fill(ENV_GET_CPU(env), page2, MMU_DATA_STORE,
-                     mmu_idx, retaddr);
+        if ((get_memop(oi) & MO_AMASK) == MO_ALIGN) {
+            cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
+                                 mmu_idx, retaddr);
         }
-
-        /* XXX: not efficient, but simple.  */
-        /* This loop must go in the forward direction to avoid issues
-           with self-modifying code in Windows 64-bit.  */
-        for (i = 0; i < DATA_SIZE; ++i) {
+        /* XXX: not efficient, but simple */
+        /* Note: relies on the fact that tlb_fill() does not remove the
+         * previous page from the TLB cache.  */
+        for (i = DATA_SIZE - 1; i >= 0; i--) {
             /* Little-endian extract.  */
             uint8_t val8 = val >> (i * 8);
             /* Note the adjustment at the beginning of the function.
@@ -399,6 +434,13 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
         return;
     }
 
+    /* Handle aligned access or unaligned access in the same page.  */
+    if ((addr & (DATA_SIZE - 1)) != 0
+        && (get_memop(oi) & MO_AMASK) == MO_ALIGN) {
+        cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
+                             mmu_idx, retaddr);
+    }
+
     haddr = addr + env->tlb_table[mmu_idx][index].addend;
 #if DATA_SIZE == 1
     glue(glue(st, SUFFIX), _p)((uint8_t *)haddr, val);
@@ -414,21 +456,20 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
     unsigned mmu_idx = get_mmuidx(oi);
     int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
-    int a_bits = get_alignment_bits(get_memop(oi));
     uintptr_t haddr;
 
     /* Adjust the given return address.  */
     retaddr -= GETPC_ADJ;
 
-    if (a_bits > 0 && (addr & ((1 << a_bits) - 1)) != 0) {
-        cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
-                             mmu_idx, retaddr);
-    }
-
     /* If the TLB entry is for a different page, reload and try again.  */
     if ((addr & TARGET_PAGE_MASK)
         != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        if (!VICTIM_TLB_HIT(addr_write, addr)) {
+        if ((addr & (DATA_SIZE - 1)) != 0
+            && (get_memop(oi) & MO_AMASK) == MO_ALIGN) {
+            cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
+                                 mmu_idx, retaddr);
+        }
+        if (!VICTIM_TLB_HIT(addr_write)) {
             tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr);
         }
         tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
@@ -453,25 +494,16 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
     if (DATA_SIZE > 1
         && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
                      >= TARGET_PAGE_SIZE)) {
-        int i, index2;
-        target_ulong page2, tlb_addr2;
+        int i;
     do_unaligned_access:
-        /* Ensure the second page is in the TLB.  Note that the first page
-           is already guaranteed to be filled, and that the second page
-           cannot evict the first.  */
-        page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
-        index2 = (page2 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-        tlb_addr2 = env->tlb_table[mmu_idx][index2].addr_write;
-        if (page2 != (tlb_addr2 & (TARGET_PAGE_MASK | TLB_INVALID_MASK))
-            && !VICTIM_TLB_HIT(addr_write, page2)) {
-            tlb_fill(ENV_GET_CPU(env), page2, MMU_DATA_STORE,
-                     mmu_idx, retaddr);
+        if ((get_memop(oi) & MO_AMASK) == MO_ALIGN) {
+            cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
+                                 mmu_idx, retaddr);
         }
-
         /* XXX: not efficient, but simple */
-        /* This loop must go in the forward direction to avoid issues
-           with self-modifying code.  */
-        for (i = 0; i < DATA_SIZE; ++i) {
+        /* Note: relies on the fact that tlb_fill() does not remove the
+         * previous page from the TLB cache.  */
+        for (i = DATA_SIZE - 1; i >= 0; i--) {
             /* Big-endian extract.  */
             uint8_t val8 = val >> (((DATA_SIZE - 1) * 8) - (i * 8));
             /* Note the adjustment at the beginning of the function.
@@ -482,6 +514,13 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
         return;
     }
 
+    /* Handle aligned access or unaligned access in the same page.  */
+    if ((addr & (DATA_SIZE - 1)) != 0
+        && (get_memop(oi) & MO_AMASK) == MO_ALIGN) {
+        cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
+                             mmu_idx, retaddr);
+    }
+
     haddr = addr + env->tlb_table[mmu_idx][index].addend;
     glue(glue(st, SUFFIX), _be_p)((uint8_t *)haddr, val);
 }
@@ -503,7 +542,7 @@ void probe_write(CPUArchState *env, target_ulong addr, int mmu_idx,
     if ((addr & TARGET_PAGE_MASK)
         != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
         /* TLB entry is for a different page */
-        if (!VICTIM_TLB_HIT(addr_write, addr)) {
+        if (!VICTIM_TLB_HIT(addr_write)) {
             tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr);
         }
     }
index 55edd15..4b258a6 100644 (file)
@@ -30,7 +30,6 @@ stub-obj-y += runstate-check.o
 stub-obj-y += set-fd-handler.o
 stub-obj-y += slirp.o
 stub-obj-y += sysbus.o
-stub-obj-y += trace-control.o
 stub-obj-y += uuid.o
 stub-obj-y += vm-stop.o
 stub-obj-y += vmstate.o
@@ -42,6 +41,3 @@ stub-obj-y += target-monitor-defs.o
 stub-obj-y += target-get-monitor-def.o
 stub-obj-y += vhost.o
 stub-obj-y += iohandler.o
-stub-obj-y += smbios_type_38.o
-stub-obj-y += ipmi.o
-stub-obj-y += pc_madt_cpu_entry.o
index 2e8b63b..3a6f2ab 100644 (file)
@@ -1,7 +1,6 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qemu/timer.h"
-#include "sysemu/cpus.h"
 
 int use_icount;
 
diff --git a/stubs/ipmi.c b/stubs/ipmi.c
deleted file mode 100644 (file)
index 98b6dce..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * IPMI ACPI firmware handling
- *
- * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "hw/acpi/ipmi.h"
-
-void build_acpi_ipmi_devices(Aml *table, BusState *bus)
-{
-}
diff --git a/stubs/pc_madt_cpu_entry.c b/stubs/pc_madt_cpu_entry.c
deleted file mode 100644 (file)
index 427e772..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "qemu/osdep.h"
-#include "hw/i386/pc.h"
-
-void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
-                       CPUArchIdList *apic_ids, GArray *entry)
-{
-}
index 42f7e1a..dcae51f 100644 (file)
@@ -1,6 +1,5 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "qemu/host-utils.h"
 #include "slirp/slirp.h"
 
 void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
diff --git a/stubs/smbios_type_38.c b/stubs/smbios_type_38.c
deleted file mode 100644 (file)
index 9528c2c..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * IPMI SMBIOS firmware handling
- *
- * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "hw/smbios/ipmi.h"
-
-void smbios_build_type_38_table(void)
-{
-}
diff --git a/stubs/trace-control.c b/stubs/trace-control.c
deleted file mode 100644 (file)
index fe59836..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Interface for configuring and controlling the state of tracing events.
- *
- * Copyright (C) 2014-2016 Lluís Vilanova <vilanova@ac.upc.edu>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "trace/control.h"
-
-
-void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
-{
-    TraceEventID id;
-    assert(trace_event_get_state_static(ev));
-    id = trace_event_get_id(ev);
-    trace_events_enabled_count += state - trace_events_dstate[id];
-    trace_events_dstate[id] = state;
-}
-
-void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
-                                        TraceEvent *ev, bool state)
-{
-    /* should never be called on non-target binaries */
-    abort();
-}
index bae4945..b01c6c8 100644 (file)
@@ -21,6 +21,7 @@
 #define QEMU_ALPHA_CPU_QOM_H
 
 #include "qom/cpu.h"
+#include "cpu.h"
 
 #define TYPE_ALPHA_CPU "alpha-cpu"
 
@@ -47,6 +48,44 @@ typedef struct AlphaCPUClass {
     void (*parent_reset)(CPUState *cpu);
 } AlphaCPUClass;
 
-typedef struct AlphaCPU AlphaCPU;
+/**
+ * AlphaCPU:
+ * @env: #CPUAlphaState
+ *
+ * An Alpha CPU.
+ */
+typedef struct AlphaCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUAlphaState env;
+
+    /* This alarm doesn't exist in real hardware; we wish it did.  */
+    QEMUTimer *alarm_timer;
+} AlphaCPU;
+
+static inline AlphaCPU *alpha_env_get_cpu(CPUAlphaState *env)
+{
+    return container_of(env, AlphaCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(alpha_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(AlphaCPU, env)
+
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_alpha_cpu;
+#endif
+
+void alpha_cpu_do_interrupt(CPUState *cpu);
+bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
+void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                          int flags);
+hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int alpha_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
+                                   int is_write, int is_user, uintptr_t retaddr);
 
 #endif
index 6d01d7f..8a155ca 100644 (file)
@@ -24,7 +24,6 @@
 #include "cpu.h"
 #include "qemu-common.h"
 #include "migration/vmstate.h"
-#include "exec/exec-all.h"
 
 
 static void alpha_cpu_set_pc(CPUState *cs, vaddr value)
index ac5e801..420f2a5 100644 (file)
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef ALPHA_CPU_H
-#define ALPHA_CPU_H
+#if !defined (__CPU_ALPHA_H__)
+#define __CPU_ALPHA_H__
 
 #include "qemu-common.h"
-#include "cpu-qom.h"
 
 #define TARGET_LONG_BITS 64
 #define ALIGNED_ONLY
@@ -285,51 +284,12 @@ struct CPUAlphaState {
     int implver;
 };
 
-/**
- * AlphaCPU:
- * @env: #CPUAlphaState
- *
- * An Alpha CPU.
- */
-struct AlphaCPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPUAlphaState env;
-
-    /* This alarm doesn't exist in real hardware; we wish it did.  */
-    QEMUTimer *alarm_timer;
-};
-
-static inline AlphaCPU *alpha_env_get_cpu(CPUAlphaState *env)
-{
-    return container_of(env, AlphaCPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(alpha_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(AlphaCPU, env)
-
-#ifndef CONFIG_USER_ONLY
-extern const struct VMStateDescription vmstate_alpha_cpu;
-#endif
-
-void alpha_cpu_do_interrupt(CPUState *cpu);
-bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
-void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-                          int flags);
-hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-int alpha_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
-                                   MMUAccessType access_type,
-                                   int mmu_idx, uintptr_t retaddr);
-
 #define cpu_list alpha_cpu_list
+#define cpu_exec cpu_alpha_exec
 #define cpu_signal_handler cpu_alpha_signal_handler
 
 #include "exec/cpu-all.h"
+#include "cpu-qom.h"
 
 enum {
     FEATURE_ASN    = 0x00000001,
@@ -467,6 +427,7 @@ AlphaCPU *cpu_alpha_init(const char *cpu_model);
 #define cpu_init(cpu_model) CPU(cpu_alpha_init(cpu_model))
 
 void alpha_cpu_list(FILE *f, fprintf_function cpu_fprintf);
+int cpu_alpha_exec(CPUState *cpu);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
@@ -504,7 +465,7 @@ enum {
 };
 
 static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *pflags)
+                                        target_ulong *cs_base, int *pflags)
 {
     int flags = 0;
 
@@ -524,4 +485,6 @@ static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, target_ulong *pc,
     *pflags = flags;
 }
 
-#endif /* ALPHA_CPU_H */
+#include "exec/exec-all.h"
+
+#endif /* !defined (__CPU_ALPHA_H__) */
index 9645978..5ab7d5e 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 #include "fpu/softfloat.h"
 
index d64bccc..199f028 100644 (file)
@@ -19,7 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
 
 int alpha_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
index 85168b7..6dec263 100644 (file)
@@ -20,7 +20,6 @@
 #include "qemu/osdep.h"
 
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "fpu/softfloat.h"
 #include "exec/helper-proto.h"
 
index 19bebfe..777e48d 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 #include "qemu/host-utils.h"
 
index 710b783..9ab0928 100644 (file)
@@ -1,9 +1,6 @@
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "hw/hw.h"
 #include "hw/boards.h"
-#include "migration/cpu.h"
 
 static int get_fpcr(QEMUFile *f, void *opaque, size_t size)
 {
index 1b2be50..7fee9a6 100644 (file)
@@ -20,7 +20,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 /* Softmmu support */
@@ -99,8 +98,7 @@ uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
 }
 
 void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
-                                   MMUAccessType access_type,
-                                   int mmu_idx, uintptr_t retaddr)
+                                   int is_write, int is_user, uintptr_t retaddr)
 {
     AlphaCPU *cpu = ALPHA_CPU(cs);
     CPUAlphaState *env = &cpu->env;
@@ -145,12 +143,12 @@ void alpha_cpu_unassigned_access(CPUState *cs, hwaddr addr,
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write,
               int mmu_idx, uintptr_t retaddr)
 {
     int ret;
 
-    ret = alpha_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = alpha_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (unlikely(ret != 0)) {
         if (retaddr) {
             cpu_restore_state(cs, retaddr);
index bec1e17..e2dec15 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 #include "sysemu/sysemu.h"
 #include "qemu/timer.h"
index 0ea0e6e..5b86992 100644 (file)
@@ -21,7 +21,6 @@
 #include "cpu.h"
 #include "disas/disas.h"
 #include "qemu/host-utils.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "exec/cpu_ldst.h"
 
@@ -151,7 +150,6 @@ void alpha_translate_init(void)
     done_init = 1;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
 
     for (i = 0; i < 31; i++) {
         cpu_std_ir[i] = tcg_global_mem_new_i64(cpu_env,
@@ -449,13 +447,10 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
 
 static bool in_superpage(DisasContext *ctx, int64_t addr)
 {
-#ifndef CONFIG_USER_ONLY
     return ((ctx->tb->flags & TB_FLAGS_USER_MODE) == 0
-            && addr >> TARGET_VIRT_ADDR_SPACE_BITS == -1
-            && ((addr >> 41) & 3) == 2);
-#else
-    return false;
-#endif
+            && addr < 0
+            && ((addr >> 41) & 3) == 2
+            && addr >> TARGET_VIRT_ADDR_SPACE_BITS == addr >> 63);
 }
 
 static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
@@ -465,16 +460,12 @@ static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
         || ctx->singlestep_enabled || singlestep) {
         return false;
     }
-#ifndef CONFIG_USER_ONLY
     /* If the destination is in the superpage, the page perms can't change.  */
     if (in_superpage(ctx, dest)) {
         return true;
     }
     /* Check for the dest on the same page as the start of the TB.  */
     return ((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0;
-#else
-    return true;
-#endif
 }
 
 static ExitStatus gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
@@ -2998,8 +2989,7 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
     tb->icount = num_insns;
 
 #ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
         log_target_disas(cs, pc_start, ctx.pc - pc_start, 1);
         qemu_log("\n");
index 2b0c178..e74ac3e 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 #include "fpu/softfloat.h"
 
index f206411..82cbe6b 100644 (file)
@@ -9,4 +9,3 @@ obj-y += neon_helper.o iwmmxt_helper.o
 obj-y += gdbstub.o
 obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
 obj-y += crypto_helper.o
-obj-y += arm-powerctl.o
diff --git a/target-arm/arm-powerctl.c b/target-arm/arm-powerctl.c
deleted file mode 100644 (file)
index 6519d52..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * QEMU support -- ARM Power Control specific functions.
- *
- * Copyright (c) 2016 Jean-Christophe Dubois
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "cpu-qom.h"
-#include "internals.h"
-#include "arm-powerctl.h"
-#include "qemu/log.h"
-#include "exec/exec-all.h"
-
-#ifndef DEBUG_ARM_POWERCTL
-#define DEBUG_ARM_POWERCTL 0
-#endif
-
-#define DPRINTF(fmt, args...) \
-    do { \
-        if (DEBUG_ARM_POWERCTL) { \
-            fprintf(stderr, "[ARM]%s: " fmt , __func__, ##args); \
-        } \
-    } while (0)
-
-CPUState *arm_get_cpu_by_id(uint64_t id)
-{
-    CPUState *cpu;
-
-    DPRINTF("cpu %" PRId64 "\n", id);
-
-    CPU_FOREACH(cpu) {
-        ARMCPU *armcpu = ARM_CPU(cpu);
-
-        if (armcpu->mp_affinity == id) {
-            return cpu;
-        }
-    }
-
-    qemu_log_mask(LOG_GUEST_ERROR,
-                  "[ARM]%s: Requesting unknown CPU %" PRId64 "\n",
-                  __func__, id);
-
-    return NULL;
-}
-
-int arm_set_cpu_on(uint64_t cpuid, uint64_t entry, uint64_t context_id,
-                   uint32_t target_el, bool target_aa64)
-{
-    CPUState *target_cpu_state;
-    ARMCPU *target_cpu;
-
-    DPRINTF("cpu %" PRId64 " (EL %d, %s) @ 0x%" PRIx64 " with R0 = 0x%" PRIx64
-            "\n", cpuid, target_el, target_aa64 ? "aarch64" : "aarch32", entry,
-            context_id);
-
-    /* requested EL level need to be in the 1 to 3 range */
-    assert((target_el > 0) && (target_el < 4));
-
-    if (target_aa64 && (entry & 3)) {
-        /*
-         * if we are booting in AArch64 mode then "entry" needs to be 4 bytes
-         * aligned.
-         */
-        return QEMU_ARM_POWERCTL_INVALID_PARAM;
-    }
-
-    /* Retrieve the cpu we are powering up */
-    target_cpu_state = arm_get_cpu_by_id(cpuid);
-    if (!target_cpu_state) {
-        /* The cpu was not found */
-        return QEMU_ARM_POWERCTL_INVALID_PARAM;
-    }
-
-    target_cpu = ARM_CPU(target_cpu_state);
-    if (!target_cpu->powered_off) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "[ARM]%s: CPU %" PRId64 " is already on\n",
-                      __func__, cpuid);
-        return QEMU_ARM_POWERCTL_ALREADY_ON;
-    }
-
-    /*
-     * The newly brought CPU is requested to enter the exception level
-     * "target_el" and be in the requested mode (AArch64 or AArch32).
-     */
-
-    if (((target_el == 3) && !arm_feature(&target_cpu->env, ARM_FEATURE_EL3)) ||
-        ((target_el == 2) && !arm_feature(&target_cpu->env, ARM_FEATURE_EL2))) {
-        /*
-         * The CPU does not support requested level
-         */
-        return QEMU_ARM_POWERCTL_INVALID_PARAM;
-    }
-
-    if (!target_aa64 && arm_feature(&target_cpu->env, ARM_FEATURE_AARCH64)) {
-        /*
-         * For now we don't support booting an AArch64 CPU in AArch32 mode
-         * TODO: We should add this support later
-         */
-        qemu_log_mask(LOG_UNIMP,
-                      "[ARM]%s: Starting AArch64 CPU %" PRId64
-                      " in AArch32 mode is not supported yet\n",
-                      __func__, cpuid);
-        return QEMU_ARM_POWERCTL_INVALID_PARAM;
-    }
-
-    /* Initialize the cpu we are turning on */
-    cpu_reset(target_cpu_state);
-    target_cpu->powered_off = false;
-    target_cpu_state->halted = 0;
-
-    if (target_aa64) {
-        if ((target_el < 3) && arm_feature(&target_cpu->env, ARM_FEATURE_EL3)) {
-            /*
-             * As target mode is AArch64, we need to set lower
-             * exception level (the requested level 2) to AArch64
-             */
-            target_cpu->env.cp15.scr_el3 |= SCR_RW;
-        }
-
-        if ((target_el < 2) && arm_feature(&target_cpu->env, ARM_FEATURE_EL2)) {
-            /*
-             * As target mode is AArch64, we need to set lower
-             * exception level (the requested level 1) to AArch64
-             */
-            target_cpu->env.cp15.hcr_el2 |= HCR_RW;
-        }
-
-        target_cpu->env.pstate = aarch64_pstate_mode(target_el, true);
-    } else {
-        /* We are requested to boot in AArch32 mode */
-        static uint32_t mode_for_el[] = { 0,
-                                          ARM_CPU_MODE_SVC,
-                                          ARM_CPU_MODE_HYP,
-                                          ARM_CPU_MODE_SVC };
-
-        cpsr_write(&target_cpu->env, mode_for_el[target_el], CPSR_M,
-                   CPSRWriteRaw);
-    }
-
-    if (target_el == 3) {
-        /* Processor is in secure mode */
-        target_cpu->env.cp15.scr_el3 &= ~SCR_NS;
-    } else {
-        /* Processor is not in secure mode */
-        target_cpu->env.cp15.scr_el3 |= SCR_NS;
-    }
-
-    /* We check if the started CPU is now at the correct level */
-    assert(target_el == arm_current_el(&target_cpu->env));
-
-    if (target_aa64) {
-        target_cpu->env.xregs[0] = context_id;
-        target_cpu->env.thumb = false;
-    } else {
-        target_cpu->env.regs[0] = context_id;
-        target_cpu->env.thumb = entry & 1;
-        entry &= 0xfffffffe;
-    }
-
-    /* Start the new CPU at the requested address */
-    cpu_set_pc(target_cpu_state, entry);
-
-    /* We are good to go */
-    return QEMU_ARM_POWERCTL_RET_SUCCESS;
-}
-
-int arm_set_cpu_off(uint64_t cpuid)
-{
-    CPUState *target_cpu_state;
-    ARMCPU *target_cpu;
-
-    DPRINTF("cpu %" PRId64 "\n", cpuid);
-
-    /* change to the cpu we are powering up */
-    target_cpu_state = arm_get_cpu_by_id(cpuid);
-    if (!target_cpu_state) {
-        return QEMU_ARM_POWERCTL_INVALID_PARAM;
-    }
-    target_cpu = ARM_CPU(target_cpu_state);
-    if (target_cpu->powered_off) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "[ARM]%s: CPU %" PRId64 " is already off\n",
-                      __func__, cpuid);
-        return QEMU_ARM_POWERCTL_IS_OFF;
-    }
-
-    target_cpu->powered_off = true;
-    target_cpu_state->halted = 1;
-    target_cpu_state->exception_index = EXCP_HLT;
-    cpu_loop_exit(target_cpu_state);
-    /* notreached */
-
-    return QEMU_ARM_POWERCTL_RET_SUCCESS;
-}
-
-int arm_reset_cpu(uint64_t cpuid)
-{
-    CPUState *target_cpu_state;
-    ARMCPU *target_cpu;
-
-    DPRINTF("cpu %" PRId64 "\n", cpuid);
-
-    /* change to the cpu we are resetting */
-    target_cpu_state = arm_get_cpu_by_id(cpuid);
-    if (!target_cpu_state) {
-        return QEMU_ARM_POWERCTL_INVALID_PARAM;
-    }
-    target_cpu = ARM_CPU(target_cpu_state);
-    if (target_cpu->powered_off) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "[ARM]%s: CPU %" PRId64 " is off\n",
-                      __func__, cpuid);
-        return QEMU_ARM_POWERCTL_IS_OFF;
-    }
-
-    /* Reset the cpu */
-    cpu_reset(target_cpu_state);
-
-    return QEMU_ARM_POWERCTL_RET_SUCCESS;
-}
diff --git a/target-arm/arm-powerctl.h b/target-arm/arm-powerctl.h
deleted file mode 100644 (file)
index 98ee049..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * QEMU support -- ARM Power Control specific functions.
- *
- * Copyright (c) 2016 Jean-Christophe Dubois
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QEMU_ARM_POWERCTL_H
-#define QEMU_ARM_POWERCTL_H
-
-#include "kvm-consts.h"
-
-#define QEMU_ARM_POWERCTL_RET_SUCCESS QEMU_PSCI_RET_SUCCESS
-#define QEMU_ARM_POWERCTL_INVALID_PARAM QEMU_PSCI_RET_INVALID_PARAMS
-#define QEMU_ARM_POWERCTL_ALREADY_ON QEMU_PSCI_RET_ALREADY_ON
-#define QEMU_ARM_POWERCTL_IS_OFF QEMU_PSCI_RET_DENIED
-
-/*
- * arm_get_cpu_by_id:
- * @cpuid: the id of the CPU we want to retrieve the state
- *
- * Retrieve a CPUState object from its CPU ID provided in @cpuid.
- *
- * Returns: a pointer to the CPUState structure of the requested CPU.
- */
-CPUState *arm_get_cpu_by_id(uint64_t cpuid);
-
-/*
- * arm_set_cpu_on:
- * @cpuid: the id of the CPU we want to start/wake up.
- * @entry: the address the CPU shall start from.
- * @context_id: the value to put in r0/x0.
- * @target_el: The desired exception level.
- * @target_aa64: 1 if the requested mode is AArch64. 0 otherwise.
- *
- * Start the cpu designated by @cpuid in @target_el exception level. The mode
- * shall be AArch64 if @target_aa64 is set to 1. Otherwise the mode is
- * AArch32. The CPU shall start at @entry with @context_id in r0/x0.
- *
- * Returns: QEMU_ARM_POWERCTL_RET_SUCCESS on success.
- * QEMU_ARM_POWERCTL_INVALID_PARAM if bad parameters are provided.
- * QEMU_ARM_POWERCTL_ALREADY_ON if the CPU was already started.
- */
-int arm_set_cpu_on(uint64_t cpuid, uint64_t entry, uint64_t context_id,
-                   uint32_t target_el, bool target_aa64);
-
-/*
- * arm_set_cpu_off:
- * @cpuid: the id of the CPU we want to stop/shut down.
- *
- * Stop the cpu designated by @cpuid.
- *
- * Returns: QEMU_ARM_POWERCTL_RET_SUCCESS on success.
- * QEMU_ARM_POWERCTL_INVALID_PARAM if bad parameters are provided.
- * QEMU_ARM_POWERCTL_IS_OFF if CPU is already off
- */
-
-int arm_set_cpu_off(uint64_t cpuid);
-
-/*
- * arm_reset_cpu:
- * @cpuid: the id of the CPU we want to reset.
- *
- * Reset the cpu designated by @cpuid.
- *
- * Returns: QEMU_ARM_POWERCTL_RET_SUCCESS on success.
- * QEMU_ARM_POWERCTL_INVALID_PARAM if bad parameters are provided.
- * QEMU_ARM_POWERCTL_IS_OFF if CPU is off
- */
-int arm_reset_cpu(uint64_t cpuid);
-
-#endif
index 7cac873..8be0645 100644 (file)
@@ -564,10 +564,8 @@ target_ulong do_arm_semihosting(CPUARMState *env)
         }
     case TARGET_SYS_HEAPINFO:
         {
-            target_ulong retvals[4];
-            target_ulong limit;
-            int i;
-
+            uint32_t *ptr;
+            uint32_t limit;
             GET_ARG(0);
 
 #ifdef CONFIG_USER_ONLY
@@ -589,33 +587,30 @@ target_ulong do_arm_semihosting(CPUARMState *env)
                 ts->heap_limit = limit;
             }
 
-            retvals[0] = ts->heap_base;
-            retvals[1] = ts->heap_limit;
-            retvals[2] = ts->stack_base;
-            retvals[3] = 0; /* Stack limit.  */
+            ptr = lock_user(VERIFY_WRITE, arg0, 16, 0);
+            if (!ptr) {
+                /* FIXME - should this error code be -TARGET_EFAULT ? */
+                return (uint32_t)-1;
+            }
+            ptr[0] = tswap32(ts->heap_base);
+            ptr[1] = tswap32(ts->heap_limit);
+            ptr[2] = tswap32(ts->stack_base);
+            ptr[3] = tswap32(0); /* Stack limit.  */
+            unlock_user(ptr, arg0, 16);
 #else
             limit = ram_size;
+            ptr = lock_user(VERIFY_WRITE, arg0, 16, 0);
+            if (!ptr) {
+                /* FIXME - should this error code be -TARGET_EFAULT ? */
+                return (uint32_t)-1;
+            }
             /* TODO: Make this use the limit of the loaded application.  */
-            retvals[0] = limit / 2;
-            retvals[1] = limit;
-            retvals[2] = limit; /* Stack base */
-            retvals[3] = 0; /* Stack limit.  */
+            ptr[0] = tswap32(limit / 2);
+            ptr[1] = tswap32(limit);
+            ptr[2] = tswap32(limit); /* Stack base */
+            ptr[3] = tswap32(0); /* Stack limit.  */
+            unlock_user(ptr, arg0, 16);
 #endif
-
-            for (i = 0; i < ARRAY_SIZE(retvals); i++) {
-                bool fail;
-
-                if (is_a64(env)) {
-                    fail = put_user_u64(retvals[i], arg0 + i * 8);
-                } else {
-                    fail = put_user_u32(retvals[i], arg0 + i * 4);
-                }
-
-                if (fail) {
-                    /* Couldn't write back to argument block */
-                    return -1;
-                }
-            }
             return 0;
         }
     case TARGET_SYS_EXIT:
index a76d89f..35c2c43 100644 (file)
@@ -20,7 +20,6 @@
 #ifndef ARM_LDST_H
 #define ARM_LDST_H
 
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "qemu/bswap.h"
 
index 3991173..1061c08 100644 (file)
@@ -22,8 +22,6 @@
 
 #include "qom/cpu.h"
 
-struct arm_boot_info;
-
 #define TYPE_ARM_CPU "arm-cpu"
 
 #define ARM_CPU_CLASS(klass) \
@@ -49,7 +47,145 @@ typedef struct ARMCPUClass {
     void (*parent_reset)(CPUState *cpu);
 } ARMCPUClass;
 
-typedef struct ARMCPU ARMCPU;
+/**
+ * ARMCPU:
+ * @env: #CPUARMState
+ *
+ * An ARM CPU core.
+ */
+typedef struct ARMCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUARMState env;
+
+    /* Coprocessor information */
+    GHashTable *cp_regs;
+    /* For marshalling (mostly coprocessor) register state between the
+     * kernel and QEMU (for KVM) and between two QEMUs (for migration),
+     * we use these arrays.
+     */
+    /* List of register indexes managed via these arrays; (full KVM style
+     * 64 bit indexes, not CPRegInfo 32 bit indexes)
+     */
+    uint64_t *cpreg_indexes;
+    /* Values of the registers (cpreg_indexes[i]'s value is cpreg_values[i]) */
+    uint64_t *cpreg_values;
+    /* Length of the indexes, values, reset_values arrays */
+    int32_t cpreg_array_len;
+    /* These are used only for migration: incoming data arrives in
+     * these fields and is sanity checked in post_load before copying
+     * to the working data structures above.
+     */
+    uint64_t *cpreg_vmstate_indexes;
+    uint64_t *cpreg_vmstate_values;
+    int32_t cpreg_vmstate_array_len;
+
+    /* Timers used by the generic (architected) timer */
+    QEMUTimer *gt_timer[NUM_GTIMERS];
+    /* GPIO outputs for generic timer */
+    qemu_irq gt_timer_outputs[NUM_GTIMERS];
+
+    /* MemoryRegion to use for secure physical accesses */
+    MemoryRegion *secure_memory;
+
+    /* 'compatible' string for this CPU for Linux device trees */
+    const char *dtb_compatible;
+
+    /* PSCI version for this CPU
+     * Bits[31:16] = Major Version
+     * Bits[15:0] = Minor Version
+     */
+    uint32_t psci_version;
+
+    /* Should CPU start in PSCI powered-off state? */
+    bool start_powered_off;
+    /* CPU currently in PSCI powered-off state */
+    bool powered_off;
+    /* CPU has security extension */
+    bool has_el3;
+
+    /* CPU has memory protection unit */
+    bool has_mpu;
+    /* PMSAv7 MPU number of supported regions */
+    uint32_t pmsav7_dregion;
+
+    /* PSCI conduit used to invoke PSCI methods
+     * 0 - disabled, 1 - smc, 2 - hvc
+     */
+    uint32_t psci_conduit;
+
+    /* [QEMU_]KVM_ARM_TARGET_* constant for this CPU, or
+     * QEMU_KVM_ARM_TARGET_NONE if the kernel doesn't support this CPU type.
+     */
+    uint32_t kvm_target;
+
+    /* KVM init features for this CPU */
+    uint32_t kvm_init_features[7];
+
+    /* Uniprocessor system with MP extensions */
+    bool mp_is_up;
+
+    /* The instance init functions for implementation-specific subclasses
+     * set these fields to specify the implementation-dependent values of
+     * various constant registers and reset values of non-constant
+     * registers.
+     * Some of these might become QOM properties eventually.
+     * Field names match the official register names as defined in the
+     * ARMv7AR ARM Architecture Reference Manual. A reset_ prefix
+     * is used for reset values of non-constant registers; no reset_
+     * prefix means a constant register.
+     */
+    uint32_t midr;
+    uint32_t revidr;
+    uint32_t reset_fpsid;
+    uint32_t mvfr0;
+    uint32_t mvfr1;
+    uint32_t mvfr2;
+    uint32_t ctr;
+    uint32_t reset_sctlr;
+    uint32_t id_pfr0;
+    uint32_t id_pfr1;
+    uint32_t id_dfr0;
+    uint32_t pmceid0;
+    uint32_t pmceid1;
+    uint32_t id_afr0;
+    uint32_t id_mmfr0;
+    uint32_t id_mmfr1;
+    uint32_t id_mmfr2;
+    uint32_t id_mmfr3;
+    uint32_t id_mmfr4;
+    uint32_t id_isar0;
+    uint32_t id_isar1;
+    uint32_t id_isar2;
+    uint32_t id_isar3;
+    uint32_t id_isar4;
+    uint32_t id_isar5;
+    uint64_t id_aa64pfr0;
+    uint64_t id_aa64pfr1;
+    uint64_t id_aa64dfr0;
+    uint64_t id_aa64dfr1;
+    uint64_t id_aa64afr0;
+    uint64_t id_aa64afr1;
+    uint64_t id_aa64isar0;
+    uint64_t id_aa64isar1;
+    uint64_t id_aa64mmfr0;
+    uint64_t id_aa64mmfr1;
+    uint32_t dbgdidr;
+    uint32_t clidr;
+    uint64_t mp_affinity; /* MP ID without feature bits */
+    /* The elements of this array are the CCSIDR values for each cache,
+     * in the order L1DCache, L1ICache, L2DCache, L2ICache, etc.
+     */
+    uint32_t ccsidr[16];
+    uint64_t reset_cbar;
+    uint32_t reset_auxcr;
+    bool reset_hivecs;
+    /* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
+    uint32_t dcz_blocksize;
+    uint64_t rvbar;
+} ARMCPU;
 
 #define TYPE_AARCH64_CPU "aarch64-cpu"
 #define AARCH64_CPU_CLASS(klass) \
@@ -63,9 +199,40 @@ typedef struct AArch64CPUClass {
     /*< public >*/
 } AArch64CPUClass;
 
+static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
+{
+    return container_of(env, ARMCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(arm_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(ARMCPU, env)
+
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_arm_cpu;
+#endif
+
 void register_cp_regs_for_features(ARMCPU *cpu);
 void init_cpreg_list(ARMCPU *cpu);
 
+void arm_cpu_do_interrupt(CPUState *cpu);
+void arm_v7m_cpu_do_interrupt(CPUState *cpu);
+bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
+
+void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags);
+
+hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
+                                         MemTxAttrs *attrs);
+
+int arm_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int arm_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+
+int arm_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
+                             int cpuid, void *opaque);
+int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
+                             int cpuid, void *opaque);
+
 /* Callback functions for the generic timer's timers. */
 void arm_gt_ptimer_cb(void *opaque);
 void arm_gt_vtimer_cb(void *opaque);
@@ -85,4 +252,9 @@ void arm_gt_stimer_cb(void *opaque);
 #define ARM64_AFFINITY_MASK \
     (ARM_AFF0_MASK|ARM_AFF1_MASK|ARM_AFF2_MASK|ARM_AFF3_MASK)
 
+#ifdef TARGET_AARCH64
+int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+#endif
+
 #endif
index ce8b8f4..e48e83a 100644 (file)
@@ -23,7 +23,6 @@
 #include "cpu.h"
 #include "internals.h"
 #include "qemu-common.h"
-#include "exec/exec-all.h"
 #include "hw/qdev-properties.h"
 #if !defined(CONFIG_USER_ONLY)
 #include "hw/loader.h"
@@ -51,15 +50,6 @@ static bool arm_cpu_has_work(CPUState *cs)
          | CPU_INTERRUPT_EXITTB);
 }
 
-void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHook *hook,
-                                 void *opaque)
-{
-    /* We currently only support registering a single hook function */
-    assert(!cpu->el_change_hook);
-    cpu->el_change_hook = hook;
-    cpu->el_change_hook_opaque = opaque;
-}
-
 static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
 {
     /* Reset a single ARMCPRegInfo register */
@@ -1415,7 +1405,6 @@ static Property arm_cpu_properties[] = {
     DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
     DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
     DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
-    DEFINE_PROP_UINT64("mp-affinity", ARMCPU, mp_affinity, 0),
     DEFINE_PROP_END_OF_LIST()
 };
 
index 76d824d..066ff67 100644 (file)
@@ -16,9 +16,9 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
+#ifndef CPU_ARM_H
+#define CPU_ARM_H
 
-#ifndef ARM_CPU_H
-#define ARM_CPU_H
 
 #include "kvm-consts.h"
 
 #  define TARGET_LONG_BITS 32
 #endif
 
+#define TARGET_IS_BIENDIAN 1
+
 #define CPUArchState struct CPUARMState
 
 #include "qemu-common.h"
-#include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 
 #include "fpu/softfloat.h"
 #define ARM_CPU_VIRQ 2
 #define ARM_CPU_VFIQ 3
 
-#define NB_MMU_MODES 7
-/* ARM-specific extra insn start words:
- * 1: Conditional execution bits
- * 2: Partial exception syndrome for data aborts
- */
-#define TARGET_INSN_START_EXTRA_WORDS 2
+struct arm_boot_info;
 
-/* The 2nd extra word holding syndrome info for data aborts does not use
- * the upper 6 bits nor the lower 14 bits. We mask and shift it down to
- * help the sleb128 encoder do a better job.
- * When restoring the CPU state, we shift it back up.
- */
-#define ARM_INSN_START_WORD2_MASK ((1 << 26) - 1)
-#define ARM_INSN_START_WORD2_SHIFT 14
+#define NB_MMU_MODES 7
+#define TARGET_INSN_START_EXTRA_WORDS 1
 
 /* We currently assume float and double are IEEE single and double
    precision respectively.
@@ -288,7 +279,6 @@ typedef struct CPUARMState {
             uint64_t far_el[4];
         };
         uint64_t hpfar_el2;
-        uint64_t hstr_el2;
         union { /* Translation result. */
             struct {
                 uint64_t _unused_par_0;
@@ -514,195 +504,10 @@ typedef struct CPUARMState {
     const struct arm_boot_info *boot_info;
 } CPUARMState;
 
-/**
- * ARMELChangeHook:
- * type of a function which can be registered via arm_register_el_change_hook()
- * to get callbacks when the CPU changes its exception level or mode.
- */
-typedef void ARMELChangeHook(ARMCPU *cpu, void *opaque);
-
-/**
- * ARMCPU:
- * @env: #CPUARMState
- *
- * An ARM CPU core.
- */
-struct ARMCPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPUARMState env;
-
-    /* Coprocessor information */
-    GHashTable *cp_regs;
-    /* For marshalling (mostly coprocessor) register state between the
-     * kernel and QEMU (for KVM) and between two QEMUs (for migration),
-     * we use these arrays.
-     */
-    /* List of register indexes managed via these arrays; (full KVM style
-     * 64 bit indexes, not CPRegInfo 32 bit indexes)
-     */
-    uint64_t *cpreg_indexes;
-    /* Values of the registers (cpreg_indexes[i]'s value is cpreg_values[i]) */
-    uint64_t *cpreg_values;
-    /* Length of the indexes, values, reset_values arrays */
-    int32_t cpreg_array_len;
-    /* These are used only for migration: incoming data arrives in
-     * these fields and is sanity checked in post_load before copying
-     * to the working data structures above.
-     */
-    uint64_t *cpreg_vmstate_indexes;
-    uint64_t *cpreg_vmstate_values;
-    int32_t cpreg_vmstate_array_len;
-
-    /* Timers used by the generic (architected) timer */
-    QEMUTimer *gt_timer[NUM_GTIMERS];
-    /* GPIO outputs for generic timer */
-    qemu_irq gt_timer_outputs[NUM_GTIMERS];
-
-    /* MemoryRegion to use for secure physical accesses */
-    MemoryRegion *secure_memory;
-
-    /* 'compatible' string for this CPU for Linux device trees */
-    const char *dtb_compatible;
-
-    /* PSCI version for this CPU
-     * Bits[31:16] = Major Version
-     * Bits[15:0] = Minor Version
-     */
-    uint32_t psci_version;
-
-    /* Should CPU start in PSCI powered-off state? */
-    bool start_powered_off;
-    /* CPU currently in PSCI powered-off state */
-    bool powered_off;
-    /* CPU has security extension */
-    bool has_el3;
-    /* CPU has PMU (Performance Monitor Unit) */
-    bool has_pmu;
-
-    /* CPU has memory protection unit */
-    bool has_mpu;
-    /* PMSAv7 MPU number of supported regions */
-    uint32_t pmsav7_dregion;
-
-    /* PSCI conduit used to invoke PSCI methods
-     * 0 - disabled, 1 - smc, 2 - hvc
-     */
-    uint32_t psci_conduit;
-
-    /* [QEMU_]KVM_ARM_TARGET_* constant for this CPU, or
-     * QEMU_KVM_ARM_TARGET_NONE if the kernel doesn't support this CPU type.
-     */
-    uint32_t kvm_target;
-
-    /* KVM init features for this CPU */
-    uint32_t kvm_init_features[7];
-
-    /* Uniprocessor system with MP extensions */
-    bool mp_is_up;
-
-    /* The instance init functions for implementation-specific subclasses
-     * set these fields to specify the implementation-dependent values of
-     * various constant registers and reset values of non-constant
-     * registers.
-     * Some of these might become QOM properties eventually.
-     * Field names match the official register names as defined in the
-     * ARMv7AR ARM Architecture Reference Manual. A reset_ prefix
-     * is used for reset values of non-constant registers; no reset_
-     * prefix means a constant register.
-     */
-    uint32_t midr;
-    uint32_t revidr;
-    uint32_t reset_fpsid;
-    uint32_t mvfr0;
-    uint32_t mvfr1;
-    uint32_t mvfr2;
-    uint32_t ctr;
-    uint32_t reset_sctlr;
-    uint32_t id_pfr0;
-    uint32_t id_pfr1;
-    uint32_t id_dfr0;
-    uint32_t pmceid0;
-    uint32_t pmceid1;
-    uint32_t id_afr0;
-    uint32_t id_mmfr0;
-    uint32_t id_mmfr1;
-    uint32_t id_mmfr2;
-    uint32_t id_mmfr3;
-    uint32_t id_mmfr4;
-    uint32_t id_isar0;
-    uint32_t id_isar1;
-    uint32_t id_isar2;
-    uint32_t id_isar3;
-    uint32_t id_isar4;
-    uint32_t id_isar5;
-    uint64_t id_aa64pfr0;
-    uint64_t id_aa64pfr1;
-    uint64_t id_aa64dfr0;
-    uint64_t id_aa64dfr1;
-    uint64_t id_aa64afr0;
-    uint64_t id_aa64afr1;
-    uint64_t id_aa64isar0;
-    uint64_t id_aa64isar1;
-    uint64_t id_aa64mmfr0;
-    uint64_t id_aa64mmfr1;
-    uint32_t dbgdidr;
-    uint32_t clidr;
-    uint64_t mp_affinity; /* MP ID without feature bits */
-    /* The elements of this array are the CCSIDR values for each cache,
-     * in the order L1DCache, L1ICache, L2DCache, L2ICache, etc.
-     */
-    uint32_t ccsidr[16];
-    uint64_t reset_cbar;
-    uint32_t reset_auxcr;
-    bool reset_hivecs;
-    /* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
-    uint32_t dcz_blocksize;
-    uint64_t rvbar;
-
-    ARMELChangeHook *el_change_hook;
-    void *el_change_hook_opaque;
-};
-
-static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
-{
-    return container_of(env, ARMCPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(arm_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(ARMCPU, env)
-
-#ifndef CONFIG_USER_ONLY
-extern const struct VMStateDescription vmstate_arm_cpu;
-#endif
-
-void arm_cpu_do_interrupt(CPUState *cpu);
-void arm_v7m_cpu_do_interrupt(CPUState *cpu);
-bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
-
-void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-                        int flags);
-
-hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
-                                         MemTxAttrs *attrs);
-
-int arm_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int arm_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-
-int arm_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
-                             int cpuid, void *opaque);
-int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
-                             int cpuid, void *opaque);
-
-#ifdef TARGET_AARCH64
-int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-#endif
+#include "cpu-qom.h"
 
 ARMCPU *cpu_arm_init(const char *cpu_model);
+int cpu_arm_exec(CPUState *cpu);
 target_ulong do_arm_semihosting(CPUARMState *env);
 void aarch64_sync_32_to_64(CPUARMState *env);
 void aarch64_sync_64_to_32(CPUARMState *env);
@@ -1155,8 +960,8 @@ static inline bool arm_is_secure_below_el3(CPUARMState *env)
     }
 }
 
-/* Return true if the CPU is AArch64 EL3 or AArch32 Mon */
-static inline bool arm_is_el3_or_mon(CPUARMState *env)
+/* Return true if the processor is in secure state */
+static inline bool arm_is_secure(CPUARMState *env)
 {
     if (arm_feature(env, ARM_FEATURE_EL3)) {
         if (is_a64(env) && extract32(env->pstate, 2, 2) == 3) {
@@ -1168,15 +973,6 @@ static inline bool arm_is_el3_or_mon(CPUARMState *env)
             return true;
         }
     }
-    return false;
-}
-
-/* Return true if the processor is in secure state */
-static inline bool arm_is_secure(CPUARMState *env)
-{
-    if (arm_is_el3_or_mon(env)) {
-        return true;
-    }
     return arm_is_secure_below_el3(env);
 }
 
@@ -1890,6 +1686,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
 
 #define cpu_init(cpu_model) CPU(cpu_arm_init(cpu_model))
 
+#define cpu_exec cpu_arm_exec
 #define cpu_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
 
@@ -2320,7 +2117,7 @@ static inline bool arm_cpu_bswap_data(CPUARMState *env)
 #endif
 
 static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     if (is_a64(env)) {
         *pc = env->pc;
@@ -2371,6 +2168,8 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
     *cs_base = 0;
 }
 
+#include "exec/exec-all.h"
+
 enum {
     QEMU_PSCI_CONDUIT_DISABLED = 0,
     QEMU_PSCI_CONDUIT_SMC = 1,
@@ -2394,28 +2193,4 @@ static inline AddressSpace *arm_addressspace(CPUState *cs, MemTxAttrs attrs)
 }
 #endif
 
-/**
- * arm_register_el_change_hook:
- * Register a hook function which will be called back whenever this
- * CPU changes exception level or mode. The hook function will be
- * passed a pointer to the ARMCPU and the opaque data pointer passed
- * to this function when the hook was registered.
- *
- * Note that we currently only support registering a single hook function,
- * and will assert if this function is called twice.
- * This facility is intended for the use of the GICv3 emulation.
- */
-void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHook *hook,
-                                 void *opaque);
-
-/**
- * arm_get_el_change_hook_opaque:
- * Return the opaque data that will be used by the el_change_hook
- * for this CPU.
- */
-static inline void *arm_get_el_change_hook_opaque(ARMCPU *cpu)
-{
-    return cpu->el_change_hook_opaque;
-}
-
 #endif
index 04c1208..3ba9aad 100644 (file)
@@ -19,7 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
 
 /* Old gdb always expect FPA registers.  Newer (xml-aware) gdb only expect
index 49bc3fc..634c6bc 100644 (file)
@@ -18,7 +18,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
 
 int aarch64_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
index 41e48a4..c7bfb4d 100644 (file)
@@ -22,7 +22,6 @@
 #include "exec/gdbstub.h"
 #include "exec/helper-proto.h"
 #include "qemu/host-utils.h"
-#include "qemu/log.h"
 #include "sysemu/sysemu.h"
 #include "qemu/bitops.h"
 #include "internals.h"
@@ -344,12 +343,12 @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
 
     if (float32_is_any_nan(a)) {
         float32 nan = a;
-        if (float32_is_signaling_nan(a, fpst)) {
+        if (float32_is_signaling_nan(a)) {
             float_raise(float_flag_invalid, fpst);
-            nan = float32_maybe_silence_nan(a, fpst);
+            nan = float32_maybe_silence_nan(a);
         }
         if (fpst->default_nan_mode) {
-            nan = float32_default_nan(fpst);
+            nan = float32_default_nan;
         }
         return nan;
     }
@@ -373,12 +372,12 @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
 
     if (float64_is_any_nan(a)) {
         float64 nan = a;
-        if (float64_is_signaling_nan(a, fpst)) {
+        if (float64_is_signaling_nan(a)) {
             float_raise(float_flag_invalid, fpst);
-            nan = float64_maybe_silence_nan(a, fpst);
+            nan = float64_maybe_silence_nan(a);
         }
         if (fpst->default_nan_mode) {
-            nan = float64_default_nan(fpst);
+            nan = float64_default_nan;
         }
         return nan;
     }
@@ -407,7 +406,7 @@ float32 HELPER(fcvtx_f64_to_f32)(float64 a, CPUARMState *env)
     set_float_rounding_mode(float_round_to_zero, &tstat);
     set_float_exception_flags(0, &tstat);
     r = float64_to_float32(a, &tstat);
-    r = float32_maybe_silence_nan(r, &tstat);
+    r = float32_maybe_silence_nan(r);
     exflags = get_float_exception_flags(&tstat);
     if (exflags & float_flag_inexact) {
         r = make_float32(float32_val(r) | 1);
index bdb842c..09638b2 100644 (file)
@@ -8,7 +8,6 @@
 #include "sysemu/sysemu.h"
 #include "qemu/bitops.h"
 #include "qemu/crc32c.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "arm_ldst.h"
 #include <zlib.h> /* For crc32 */
@@ -572,102 +571,6 @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
     }
 }
 
-static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                               uint64_t value)
-{
-    CPUState *cs = ENV_GET_CPU(env);
-
-    tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0,
-                        ARMMMUIdx_S2NS, -1);
-}
-
-static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                                  uint64_t value)
-{
-    CPUState *other_cs;
-
-    CPU_FOREACH(other_cs) {
-        tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1,
-                            ARMMMUIdx_S12NSE0, ARMMMUIdx_S2NS, -1);
-    }
-}
-
-static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                            uint64_t value)
-{
-    /* Invalidate by IPA. This has to invalidate any structures that
-     * contain only stage 2 translation information, but does not need
-     * to apply to structures that contain combined stage 1 and stage 2
-     * translation information.
-     * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
-     */
-    CPUState *cs = ENV_GET_CPU(env);
-    uint64_t pageaddr;
-
-    if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
-        return;
-    }
-
-    pageaddr = sextract64(value << 12, 0, 40);
-
-    tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S2NS, -1);
-}
-
-static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                               uint64_t value)
-{
-    CPUState *other_cs;
-    uint64_t pageaddr;
-
-    if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
-        return;
-    }
-
-    pageaddr = sextract64(value << 12, 0, 40);
-
-    CPU_FOREACH(other_cs) {
-        tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S2NS, -1);
-    }
-}
-
-static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                              uint64_t value)
-{
-    CPUState *cs = ENV_GET_CPU(env);
-
-    tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1E2, -1);
-}
-
-static void tlbiall_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                                 uint64_t value)
-{
-    CPUState *other_cs;
-
-    CPU_FOREACH(other_cs) {
-        tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1E2, -1);
-    }
-}
-
-static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                              uint64_t value)
-{
-    CPUState *cs = ENV_GET_CPU(env);
-    uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12);
-
-    tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S1E2, -1);
-}
-
-static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                                 uint64_t value)
-{
-    CPUState *other_cs;
-    uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12);
-
-    CPU_FOREACH(other_cs) {
-        tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1E2, -1);
-    }
-}
-
 static const ARMCPRegInfo cp_reginfo[] = {
     /* Define the secure and non-secure FCSE identifier CP registers
      * separately because there is no secure bank in V8 (no _EL3).  This allows
@@ -3369,29 +3272,6 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
       .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
     { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
       .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write },
-    { .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
-      .type = ARM_CP_NO_RAW, .access = PL2_W,
-      .writefn = tlbimva_hyp_write },
-    { .name = "TLBIMVALHIS",
-      .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5,
-      .type = ARM_CP_NO_RAW, .access = PL2_W,
-      .writefn = tlbimva_hyp_is_write },
-    { .name = "TLBIIPAS2",
-      .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
-      .type = ARM_CP_NO_RAW, .access = PL2_W,
-      .writefn = tlbiipas2_write },
-    { .name = "TLBIIPAS2IS",
-      .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
-      .type = ARM_CP_NO_RAW, .access = PL2_W,
-      .writefn = tlbiipas2_is_write },
-    { .name = "TLBIIPAS2L",
-      .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
-      .type = ARM_CP_NO_RAW, .access = PL2_W,
-      .writefn = tlbiipas2_write },
-    { .name = "TLBIIPAS2LIS",
-      .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
-      .type = ARM_CP_NO_RAW, .access = PL2_W,
-      .writefn = tlbiipas2_is_write },
     /* 32 bit cache operations */
     { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
       .type = ARM_CP_NOP, .access = PL1_W },
@@ -3590,9 +3470,6 @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
       .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
       .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any,
       .type = ARM_CP_CONST, .resetvalue = 0 },
-    { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
-      .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
     REGINFO_SENTINEL
 };
 
@@ -3682,10 +3559,8 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
       .resetvalue = 0 },
     { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
-      .access = PL2_RW,
-      /* no .writefn needed as this can't cause an ASID change;
-       * no .raw_writefn or .resetfn needed as we never use mask/base_mask
-       */
+      .access = PL2_RW, .writefn = vmsa_tcr_el1_write,
+      .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
       .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[2]) },
     { .name = "VTCR", .state = ARM_CP_STATE_AA32,
       .cp = 15, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
@@ -3724,26 +3599,6 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
     { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
       .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
       .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
-    { .name = "TLBIALLNSNH",
-      .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
-      .type = ARM_CP_NO_RAW, .access = PL2_W,
-      .writefn = tlbiall_nsnh_write },
-    { .name = "TLBIALLNSNHIS",
-      .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
-      .type = ARM_CP_NO_RAW, .access = PL2_W,
-      .writefn = tlbiall_nsnh_is_write },
-    { .name = "TLBIALLH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
-      .type = ARM_CP_NO_RAW, .access = PL2_W,
-      .writefn = tlbiall_hyp_write },
-    { .name = "TLBIALLHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0,
-      .type = ARM_CP_NO_RAW, .access = PL2_W,
-      .writefn = tlbiall_hyp_is_write },
-    { .name = "TLBIMVAH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
-      .type = ARM_CP_NO_RAW, .access = PL2_W,
-      .writefn = tlbimva_hyp_write },
-    { .name = "TLBIMVAHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1,
-      .type = ARM_CP_NO_RAW, .access = PL2_W,
-      .writefn = tlbimva_hyp_is_write },
     { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
       .type = ARM_CP_NO_RAW, .access = PL2_W,
@@ -3848,10 +3703,6 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
       .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
       .access = PL2_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.hpfar_el2) },
-    { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
-      .cp = 15, .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
-      .access = PL2_RW,
-      .fieldoffset = offsetof(CPUARMState, cp15.hstr_el2) },
     REGINFO_SENTINEL
 };
 
@@ -3902,13 +3753,8 @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
       .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[3]) },
     { .name = "TCR_EL3", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 2,
-      .access = PL3_RW,
-      /* no .writefn needed as this can't cause an ASID change;
-       * we must provide a .raw_writefn and .resetfn because we handle
-       * reset and migration for the AArch32 TTBCR(S), which might be
-       * using mask and base_mask.
-       */
-      .resetfn = vmsa_ttbcr_reset, .raw_writefn = vmsa_ttbcr_raw_write,
+      .access = PL3_RW, .writefn = vmsa_tcr_el1_write,
+      .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
       .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[3]) },
     { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS,
@@ -5969,21 +5815,6 @@ static void do_v7m_exception_exit(CPUARMState *env)
        pointer.  */
 }
 
-static void arm_log_exception(int idx)
-{
-    if (qemu_loglevel_mask(CPU_LOG_INT)) {
-        const char *exc = NULL;
-
-        if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
-            exc = excnames[idx];
-        }
-        if (!exc) {
-            exc = "unknown";
-        }
-        qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc);
-    }
-}
-
 void arm_v7m_cpu_do_interrupt(CPUState *cs)
 {
     ARMCPU *cpu = ARM_CPU(cs);
@@ -6507,6 +6338,9 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
         env->elr_el[new_el] = env->pc;
     } else {
         env->banked_spsr[aarch64_banked_spsr_index(new_el)] = cpsr_read(env);
+        if (!env->thumb) {
+            env->cp15.esr_el[new_el] |= 1 << 25;
+        }
         env->elr_el[new_el] = env->regs[15];
 
         aarch64_sync_32_to_64(env);
@@ -6642,8 +6476,6 @@ void arm_cpu_do_interrupt(CPUState *cs)
         arm_cpu_do_interrupt_aarch32(cs);
     }
 
-    arm_call_el_change_hook(cpu);
-
     if (!kvm_enabled()) {
         cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
     }
@@ -6876,9 +6708,7 @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn)
         prot |= PAGE_WRITE;
     }
     if (!xn) {
-        if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
-            prot |= PAGE_EXEC;
-        }
+        prot |= PAGE_EXEC;
     }
     return prot;
 }
@@ -7418,12 +7248,12 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
     uint32_t tg;
     uint64_t ttbr;
     int ttbr_select;
-    hwaddr descaddr, indexmask, indexmask_grainsize;
+    hwaddr descaddr, descmask;
     uint32_t tableattrs;
     target_ulong page_size;
     uint32_t attrs;
     int32_t stride = 9;
-    int32_t addrsize;
+    int32_t va_size;
     int inputsize;
     int32_t tbi = 0;
     TCR *tcr = regime_tcr(env, mmu_idx);
@@ -7431,7 +7261,6 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
     uint32_t el = regime_el(env, mmu_idx);
     bool ttbr1_valid = true;
     uint64_t descaddrmask;
-    bool aarch64 = arm_el_is_aa64(env, el);
 
     /* TODO:
      * This code does not handle the different format TCR for VTCR_EL2.
@@ -7439,9 +7268,9 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
      * Attribute and permission bit handling should also be checked when adding
      * support for those page table walks.
      */
-    if (aarch64) {
+    if (arm_el_is_aa64(env, el)) {
         level = 0;
-        addrsize = 64;
+        va_size = 64;
         if (el > 1) {
             if (mmu_idx != ARMMMUIdx_S2NS) {
                 tbi = extract64(tcr->raw_tcr, 20, 1);
@@ -7463,7 +7292,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
         }
     } else {
         level = 1;
-        addrsize = 32;
+        va_size = 32;
         /* There is no TTBR1 for EL2 */
         if (el == 2) {
             ttbr1_valid = false;
@@ -7475,7 +7304,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
      * This is a Non-secure PL0/1 stage 1 translation, so controlled by
      * TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32:
      */
-    if (aarch64) {
+    if (va_size == 64) {
         /* AArch64 translation.  */
         t0sz = extract32(tcr->raw_tcr, 0, 6);
         t0sz = MIN(t0sz, 39);
@@ -7487,12 +7316,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
         /* AArch32 stage 2 translation.  */
         bool sext = extract32(tcr->raw_tcr, 4, 1);
         bool sign = extract32(tcr->raw_tcr, 3, 1);
-        /* Address size is 40-bit for a stage 2 translation,
-         * and t0sz can be negative (from -8 to 7),
-         * so we need to adjust it to use the TTBR selecting logic below.
-         */
-        addrsize = 40;
-        t0sz = sextract32(tcr->raw_tcr, 0, 4) + 8;
+        t0sz = sextract32(tcr->raw_tcr, 0, 4);
 
         /* If the sign-extend bit is not the same as t0sz[3], the result
          * is unpredictable. Flag this as a guest error.  */
@@ -7502,15 +7326,15 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
         }
     }
     t1sz = extract32(tcr->raw_tcr, 16, 6);
-    if (aarch64) {
+    if (va_size == 64) {
         t1sz = MIN(t1sz, 39);
         t1sz = MAX(t1sz, 16);
     }
-    if (t0sz && !extract64(address, addrsize - t0sz, t0sz - tbi)) {
+    if (t0sz && !extract64(address, va_size - t0sz, t0sz - tbi)) {
         /* there is a ttbr0 region and we are in it (high bits all zero) */
         ttbr_select = 0;
     } else if (ttbr1_valid && t1sz &&
-               !extract64(~address, addrsize - t1sz, t1sz - tbi)) {
+               !extract64(~address, va_size - t1sz, t1sz - tbi)) {
         /* there is a ttbr1 region and we are in it (high bits all one) */
         ttbr_select = 1;
     } else if (!t0sz) {
@@ -7537,7 +7361,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
         if (el < 2) {
             epd = extract32(tcr->raw_tcr, 7, 1);
         }
-        inputsize = addrsize - t0sz;
+        inputsize = va_size - t0sz;
 
         tg = extract32(tcr->raw_tcr, 14, 2);
         if (tg == 1) { /* 64KB pages */
@@ -7552,7 +7376,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
 
         ttbr = regime_ttbr(env, mmu_idx, 1);
         epd = extract32(tcr->raw_tcr, 23, 1);
-        inputsize = addrsize - t1sz;
+        inputsize = va_size - t1sz;
 
         tg = extract32(tcr->raw_tcr, 30, 2);
         if (tg == 3)  { /* 64KB pages */
@@ -7564,7 +7388,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
     }
 
     /* Here we should have set up all the parameters for the translation:
-     * inputsize, ttbr, epd, stride, tbi
+     * va_size, inputsize, ttbr, epd, stride, tbi
      */
 
     if (epd) {
@@ -7595,7 +7419,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
         uint32_t startlevel;
         bool ok;
 
-        if (!aarch64 || stride == 9) {
+        if (va_size == 32 || stride == 9) {
             /* AArch32 or 4KB pages */
             startlevel = 2 - sl0;
         } else {
@@ -7604,7 +7428,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
         }
 
         /* Check that the starting level is valid. */
-        ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
+        ok = check_s2_mmu_setup(cpu, va_size == 64, startlevel,
                                 inputsize, stride);
         if (!ok) {
             fault_type = translation_fault;
@@ -7613,20 +7437,28 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
         level = startlevel;
     }
 
-    indexmask_grainsize = (1ULL << (stride + 3)) - 1;
-    indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
+    /* Clear the vaddr bits which aren't part of the within-region address,
+     * so that we don't have to special case things when calculating the
+     * first descriptor address.
+     */
+    if (va_size != inputsize) {
+        address &= (1ULL << inputsize) - 1;
+    }
+
+    descmask = (1ULL << (stride + 3)) - 1;
 
     /* Now we can extract the actual base address from the TTBR */
     descaddr = extract64(ttbr, 0, 48);
-    descaddr &= ~indexmask;
+    descaddr &= ~((1ULL << (inputsize - (stride * (4 - level)))) - 1);
 
     /* The address field in the descriptor goes up to bit 39 for ARMv7
-     * but up to bit 47 for ARMv8, but we use the descaddrmask
-     * up to bit 39 for AArch32, because we don't need other bits in that case
-     * to construct next descriptor address (anyway they should be all zeroes).
+     * but up to bit 47 for ARMv8.
      */
-    descaddrmask = ((1ull << (aarch64 ? 48 : 40)) - 1) &
-                   ~indexmask_grainsize;
+    if (arm_feature(env, ARM_FEATURE_V8)) {
+        descaddrmask = 0xfffffffff000ULL;
+    } else {
+        descaddrmask = 0xfffffff000ULL;
+    }
 
     /* Secure accesses start with the page table in secure memory and
      * can be downgraded to non-secure at any step. Non-secure accesses
@@ -7638,7 +7470,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
         uint64_t descriptor;
         bool nstable;
 
-        descaddr |= (address >> (stride * (4 - level))) & indexmask;
+        descaddr |= (address >> (stride * (4 - level))) & descmask;
         descaddr &= ~7ULL;
         nstable = extract32(tableattrs, 4, 1);
         descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fsr, fi);
@@ -7661,7 +7493,6 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
              */
             tableattrs |= extract64(descriptor, 59, 5);
             level++;
-            indexmask = indexmask_grainsize;
             continue;
         }
         /* Block entry at level 1 or 2, or page entry at level 3.
@@ -7708,7 +7539,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
     } else {
         ns = extract32(attrs, 3, 1);
         pxn = extract32(attrs, 11, 1);
-        *prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
+        *prot = get_S1prot(env, mmu_idx, va_size == 64, ap, ns, xn, pxn);
     }
 
     fault_type = permission_fault;
@@ -8817,7 +8648,7 @@ float64 VFP_HELPER(fcvtd, s)(float32 x, CPUARMState *env)
     /* ARM requires that S<->D conversion of any kind of NaN generates
      * a quiet NaN by forcing the most significant frac bit to 1.
      */
-    return float64_maybe_silence_nan(r, &env->vfp.fp_status);
+    return float64_maybe_silence_nan(r);
 }
 
 float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
@@ -8826,7 +8657,7 @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
     /* ARM requires that S<->D conversion of any kind of NaN generates
      * a quiet NaN by forcing the most significant frac bit to 1.
      */
-    return float32_maybe_silence_nan(r, &env->vfp.fp_status);
+    return float32_maybe_silence_nan(r);
 }
 
 /* VFP3 fixed point conversion.  */
@@ -8925,7 +8756,7 @@ static float32 do_fcvt_f16_to_f32(uint32_t a, CPUARMState *env, float_status *s)
     int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
     float32 r = float16_to_float32(make_float16(a), ieee, s);
     if (ieee) {
-        return float32_maybe_silence_nan(r, s);
+        return float32_maybe_silence_nan(r);
     }
     return r;
 }
@@ -8935,7 +8766,7 @@ static uint32_t do_fcvt_f32_to_f16(float32 a, CPUARMState *env, float_status *s)
     int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
     float16 r = float32_to_float16(a, ieee, s);
     if (ieee) {
-        r = float16_maybe_silence_nan(r, s);
+        r = float16_maybe_silence_nan(r);
     }
     return float16_val(r);
 }
@@ -8965,7 +8796,7 @@ float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, CPUARMState *env)
     int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
     float64 r = float16_to_float64(make_float16(a), ieee, &env->vfp.fp_status);
     if (ieee) {
-        return float64_maybe_silence_nan(r, &env->vfp.fp_status);
+        return float64_maybe_silence_nan(r);
     }
     return r;
 }
@@ -8975,7 +8806,7 @@ uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, CPUARMState *env)
     int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
     float16 r = float64_to_float16(a, ieee, &env->vfp.fp_status);
     if (ieee) {
-        r = float16_maybe_silence_nan(r, &env->vfp.fp_status);
+        r = float16_maybe_silence_nan(r);
     }
     return float16_val(r);
 }
@@ -9125,12 +8956,12 @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
 
     if (float32_is_any_nan(f32)) {
         float32 nan = f32;
-        if (float32_is_signaling_nan(f32, fpst)) {
+        if (float32_is_signaling_nan(f32)) {
             float_raise(float_flag_invalid, fpst);
-            nan = float32_maybe_silence_nan(f32, fpst);
+            nan = float32_maybe_silence_nan(f32);
         }
         if (fpst->default_nan_mode) {
-            nan =  float32_default_nan(fpst);
+            nan =  float32_default_nan;
         }
         return nan;
     } else if (float32_is_infinity(f32)) {
@@ -9179,12 +9010,12 @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
     /* Deal with any special cases */
     if (float64_is_any_nan(f64)) {
         float64 nan = f64;
-        if (float64_is_signaling_nan(f64, fpst)) {
+        if (float64_is_signaling_nan(f64)) {
             float_raise(float_flag_invalid, fpst);
-            nan = float64_maybe_silence_nan(f64, fpst);
+            nan = float64_maybe_silence_nan(f64);
         }
         if (fpst->default_nan_mode) {
-            nan =  float64_default_nan(fpst);
+            nan =  float64_default_nan;
         }
         return nan;
     } else if (float64_is_infinity(f64)) {
@@ -9286,12 +9117,12 @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
 
     if (float32_is_any_nan(f32)) {
         float32 nan = f32;
-        if (float32_is_signaling_nan(f32, s)) {
+        if (float32_is_signaling_nan(f32)) {
             float_raise(float_flag_invalid, s);
-            nan = float32_maybe_silence_nan(f32, s);
+            nan = float32_maybe_silence_nan(f32);
         }
         if (s->default_nan_mode) {
-            nan =  float32_default_nan(s);
+            nan =  float32_default_nan;
         }
         return nan;
     } else if (float32_is_zero(f32)) {
@@ -9299,7 +9130,7 @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
         return float32_set_sign(float32_infinity, float32_is_neg(f32));
     } else if (float32_is_neg(f32)) {
         float_raise(float_flag_invalid, s);
-        return float32_default_nan(s);
+        return float32_default_nan;
     } else if (float32_is_infinity(f32)) {
         return float32_zero;
     }
@@ -9350,12 +9181,12 @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
 
     if (float64_is_any_nan(f64)) {
         float64 nan = f64;
-        if (float64_is_signaling_nan(f64, s)) {
+        if (float64_is_signaling_nan(f64)) {
             float_raise(float_flag_invalid, s);
-            nan = float64_maybe_silence_nan(f64, s);
+            nan = float64_maybe_silence_nan(f64);
         }
         if (s->default_nan_mode) {
-            nan =  float64_default_nan(s);
+            nan =  float64_default_nan;
         }
         return nan;
     } else if (float64_is_zero(f64)) {
@@ -9363,7 +9194,7 @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
         return float64_set_sign(float64_infinity, float64_is_neg(f64));
     } else if (float64_is_neg(f64)) {
         float_raise(float_flag_invalid, s);
-        return float64_default_nan(s);
+        return float64_default_nan;
     } else if (float64_is_infinity(f64)) {
         return float64_zero;
     }
index cd57401..2e70272 100644 (file)
@@ -72,6 +72,21 @@ static const char * const excnames[] = {
     [EXCP_SEMIHOST] = "Semihosting call",
 };
 
+static inline void arm_log_exception(int idx)
+{
+    if (qemu_loglevel_mask(CPU_LOG_INT)) {
+        const char *exc = NULL;
+
+        if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
+            exc = excnames[idx];
+        }
+        if (!exc) {
+            exc = "unknown";
+        }
+        qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc);
+    }
+}
+
 /* Scale factor for generic timers, ie number of ns per tick.
  * This gives a 62.5MHz timer.
  */
@@ -248,9 +263,7 @@ enum arm_exception_class {
 
 #define ARM_EL_EC_SHIFT 26
 #define ARM_EL_IL_SHIFT 25
-#define ARM_EL_ISV_SHIFT 24
 #define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
-#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
 
 /* Utility functions for constructing various kinds of syndrome value.
  * Note that in general we follow the AArch64 syndrome values; in a
@@ -367,42 +380,26 @@ static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit)
 static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
 {
     return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
-        | ARM_EL_IL | (ea << 9) | (s1ptw << 7) | fsc;
+        | (ea << 9) | (s1ptw << 7) | fsc;
 }
 
-static inline uint32_t syn_data_abort_no_iss(int same_el,
-                                             int ea, int cm, int s1ptw,
-                                             int wnr, int fsc)
+static inline uint32_t syn_data_abort(int same_el, int ea, int cm, int s1ptw,
+                                      int wnr, int fsc)
 {
     return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
-           | ARM_EL_IL
-           | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
-}
-
-static inline uint32_t syn_data_abort_with_iss(int same_el,
-                                               int sas, int sse, int srt,
-                                               int sf, int ar,
-                                               int ea, int cm, int s1ptw,
-                                               int wnr, int fsc,
-                                               bool is_16bit)
-{
-    return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
-           | (is_16bit ? 0 : ARM_EL_IL)
-           | ARM_EL_ISV | (sas << 22) | (sse << 21) | (srt << 16)
-           | (sf << 15) | (ar << 14)
-           | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
+        | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
 }
 
 static inline uint32_t syn_swstep(int same_el, int isv, int ex)
 {
     return (EC_SOFTWARESTEP << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
-        | ARM_EL_IL | (isv << 24) | (ex << 6) | 0x22;
+        | (isv << 24) | (ex << 6) | 0x22;
 }
 
 static inline uint32_t syn_watchpoint(int same_el, int cm, int wnr)
 {
     return (EC_WATCHPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
-        | ARM_EL_IL | (cm << 8) | (wnr << 6) | 0x22;
+        | (cm << 8) | (wnr << 6) | 0x22;
 }
 
 static inline uint32_t syn_breakpoint(int same_el)
@@ -476,16 +473,7 @@ bool arm_tlb_fill(CPUState *cpu, vaddr address, int rw, int mmu_idx,
 bool arm_s1_regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx);
 
 /* Raise a data fault alignment exception for the specified virtual address */
-void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
-                                 MMUAccessType access_type,
-                                 int mmu_idx, uintptr_t retaddr);
-
-/* Call the EL change hook if one has been registered */
-static inline void arm_call_el_change_hook(ARMCPU *cpu)
-{
-    if (cpu->el_change_hook) {
-        cpu->el_change_hook(cpu, cpu->el_change_hook_opaque);
-    }
-}
+void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, int is_write,
+                                 int is_user, uintptr_t retaddr);
 
 #endif
index b2c66df..38bf433 100644 (file)
@@ -11,7 +11,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "kvm_arm.h"
 
 bool write_kvmstate_to_list(ARMCPU *cpu)
index dbe393c..3671032 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "qemu/osdep.h"
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 
 #include <linux/kvm.h>
 
@@ -24,7 +25,6 @@
 #include "hw/arm/arm.h"
 #include "exec/memattrs.h"
 #include "hw/boards.h"
-#include "qemu/log.h"
 
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
     KVM_CAP_LAST_INFO
@@ -622,17 +622,6 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
     return 0;
 }
 
-int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
-                                int vector, PCIDevice *dev)
-{
-    return 0;
-}
-
-int kvm_arch_release_virq_post(int virq)
-{
-    return 0;
-}
-
 int kvm_arch_msi_data_to_gsi(uint32_t data)
 {
     return (data - 32) & 0xffff;
index 069da0c..d44a7f9 100644 (file)
 
 #include "qemu/osdep.h"
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 
 #include <linux/kvm.h>
 
 #include "qemu-common.h"
-#include "cpu.h"
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
 #include "kvm_arm.h"
+#include "cpu.h"
 #include "internals.h"
 #include "hw/arm/arm.h"
-#include "qemu/log.h"
 
 static inline void set_feature(uint64_t *features, int feature)
 {
@@ -521,9 +521,3 @@ bool kvm_arm_hw_debug_active(CPUState *cs)
 {
     return false;
 }
-
-int kvm_arm_pmu_create(CPUState *cs, int irq)
-{
-    qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
-    return 0;
-}
index 5faa76c..e8527bf 100644 (file)
 
 #include "qemu/osdep.h"
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 #include <sys/ptrace.h>
 
 #include <linux/elf.h>
 #include <linux/kvm.h>
 
 #include "qemu-common.h"
-#include "cpu.h"
 #include "qemu/timer.h"
 #include "qemu/error-report.h"
 #include "qemu/host-utils.h"
@@ -25,6 +25,7 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
 #include "kvm_arm.h"
+#include "cpu.h"
 #include "internals.h"
 #include "hw/arm/arm.h"
 
@@ -381,47 +382,6 @@ static CPUWatchpoint *find_hw_watchpoint(CPUState *cpu, target_ulong addr)
     return NULL;
 }
 
-static bool kvm_arm_pmu_support_ctrl(CPUState *cs, struct kvm_device_attr *attr)
-{
-    return kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr) == 0;
-}
-
-int kvm_arm_pmu_create(CPUState *cs, int irq)
-{
-    int err;
-
-    struct kvm_device_attr attr = {
-        .group = KVM_ARM_VCPU_PMU_V3_CTRL,
-        .addr = (intptr_t)&irq,
-        .attr = KVM_ARM_VCPU_PMU_V3_IRQ,
-        .flags = 0,
-    };
-
-    if (!kvm_arm_pmu_support_ctrl(cs, &attr)) {
-        return 0;
-    }
-
-    err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr);
-    if (err < 0) {
-        fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n",
-                strerror(-err));
-        abort();
-    }
-
-    attr.group = KVM_ARM_VCPU_PMU_V3_CTRL;
-    attr.attr = KVM_ARM_VCPU_PMU_V3_INIT;
-    attr.addr = 0;
-    attr.flags = 0;
-
-    err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr);
-    if (err < 0) {
-        fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n",
-                strerror(-err));
-        abort();
-    }
-
-    return 1;
-}
 
 static inline void set_feature(uint64_t *features, int feature)
 {
@@ -501,11 +461,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
     if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
         cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_EL1_32BIT;
     }
-    if (kvm_irqchip_in_kernel() &&
-        kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) {
-        cpu->has_pmu = true;
-        cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PMU_V3;
-    }
 
     /* Do KVM_ARM_VCPU_INIT ioctl */
     ret = kvm_arm_vcpu_init(cs);
index a419368..345233c 100644 (file)
@@ -194,8 +194,6 @@ int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu);
 
 int kvm_arm_vgic_probe(void);
 
-int kvm_arm_pmu_create(CPUState *cs, int irq);
-
 #else
 
 static inline int kvm_arm_vgic_probe(void)
@@ -203,11 +201,6 @@ static inline int kvm_arm_vgic_probe(void)
     return 0;
 }
 
-static inline int kvm_arm_pmu_create(CPUState *cs, int irq)
-{
-    return 0;
-}
-
 #endif
 
 static inline const char *gic_class_name(void)
index 7a6ca31..03a73d9 100644 (file)
@@ -1,13 +1,10 @@
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "hw/hw.h"
 #include "hw/boards.h"
 #include "qemu/error-report.h"
 #include "sysemu/kvm.h"
 #include "kvm_arm.h"
 #include "internals.h"
-#include "migration/cpu.h"
 
 static bool vfp_needed(void *opaque)
 {
@@ -340,9 +337,11 @@ const char *gicv3_class_name(void)
 #else
         error_report("KVM GICv3 acceleration is not supported on this "
                      "platform");
-        exit(1);
 #endif
     } else {
-        return "arm-gicv3";
+        /* TODO: Software emulation is not implemented yet */
+        error_report("KVM is currently required for GICv3 emulation");
     }
+
+    exit(1);
 }
index 299cb80..1ee59a2 100644 (file)
@@ -72,7 +72,8 @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
     GICCapability *v2 = gic_cap_new(2), *v3 = gic_cap_new(3);
 
     v2->emulated = true;
-    v3->emulated = true;
+    /* TODO: we'd change to true after we get emulated GICv3. */
+    v3->emulated = false;
 
     gic_cap_kvm_probe(v2, v3);
 
index ebdf7c9..1f1844f 100644 (file)
@@ -1051,7 +1051,7 @@ uint64_t HELPER(neon_qrshl_u64)(CPUARMState *env, uint64_t val, uint64_t shiftop
     if (tmp >= (ssize_t)sizeof(src1) * 8) { \
         if (src1) { \
             SET_QC(); \
-            dest = (typeof(dest))(1 << (sizeof(src1) * 8 - 1)); \
+            dest = (1 << (sizeof(src1) * 8 - 1)); \
             if (src1 > 0) { \
                 dest--; \
             } \
index 3e8588e..d626ff1 100644 (file)
@@ -20,7 +20,6 @@
 #include "cpu.h"
 #include "exec/helper-proto.h"
 #include "internals.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 #define SIGNBIT (uint32_t)0x80000000
@@ -76,55 +75,18 @@ uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
 
 #if !defined(CONFIG_USER_ONLY)
 
-static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
-                                            unsigned int target_el,
-                                            bool same_el,
-                                            bool s1ptw, bool is_write,
-                                            int fsc)
-{
-    uint32_t syn;
-
-    /* ISV is only set for data aborts routed to EL2 and
-     * never for stage-1 page table walks faulting on stage 2.
-     *
-     * Furthermore, ISV is only set for certain kinds of load/stores.
-     * If the template syndrome does not have ISV set, we should leave
-     * it cleared.
-     *
-     * See ARMv8 specs, D7-1974:
-     * ISS encoding for an exception from a Data Abort, the
-     * ISV field.
-     */
-    if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) {
-        syn = syn_data_abort_no_iss(same_el,
-                                    0, 0, s1ptw, is_write, fsc);
-    } else {
-        /* Fields: IL, ISV, SAS, SSE, SRT, SF and AR come from the template
-         * syndrome created at translation time.
-         * Now we create the runtime syndrome with the remaining fields.
-         */
-        syn = syn_data_abort_with_iss(same_el,
-                                      0, 0, 0, 0, 0,
-                                      0, 0, s1ptw, is_write, fsc,
-                                      false);
-        /* Merge the runtime syndrome with the template syndrome.  */
-        syn |= template_syn;
-    }
-    return syn;
-}
-
 /* try to fill the TLB and return an exception if error. If retaddr is
  * NULL, it means that the function was called in C code (i.e. not
  * from generated code or from helper.c)
  */
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr)
 {
     bool ret;
     uint32_t fsr = 0;
     ARMMMUFaultInfo fi = {};
 
-    ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fsr, &fi);
+    ret = arm_tlb_fill(cs, addr, is_write, mmu_idx, &fsr, &fi);
     if (unlikely(ret)) {
         ARMCPU *cpu = ARM_CPU(cs);
         CPUARMState *env = &cpu->env;
@@ -149,15 +111,12 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
         /* For insn and data aborts we assume there is no instruction syndrome
          * information; this is always true for exceptions reported to EL1.
          */
-        if (access_type == MMU_INST_FETCH) {
+        if (is_write == 2) {
             syn = syn_insn_abort(same_el, 0, fi.s1ptw, syn);
             exc = EXCP_PREFETCH_ABORT;
         } else {
-            syn = merge_syn_data_abort(env->exception.syndrome, target_el,
-                                       same_el, fi.s1ptw,
-                                       access_type == MMU_DATA_STORE, syn);
-            if (access_type == MMU_DATA_STORE
-                && arm_feature(env, ARM_FEATURE_V6)) {
+            syn = syn_data_abort(same_el, 0, 0, fi.s1ptw, is_write == 1, syn);
+            if (is_write == 1 && arm_feature(env, ARM_FEATURE_V6)) {
                 fsr |= (1 << 11);
             }
             exc = EXCP_DATA_ABORT;
@@ -170,15 +129,13 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
 }
 
 /* Raise a data fault alignment exception for the specified virtual address */
-void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
-                                 MMUAccessType access_type,
-                                 int mmu_idx, uintptr_t retaddr)
+void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, int is_write,
+                                 int is_user, uintptr_t retaddr)
 {
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
     int target_el;
     bool same_el;
-    uint32_t syn;
 
     if (retaddr) {
         /* now we have a real cpu fault */
@@ -199,14 +156,13 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
         env->exception.fsr = 0x1;
     }
 
-    if (access_type == MMU_DATA_STORE && arm_feature(env, ARM_FEATURE_V6)) {
+    if (is_write == 1 && arm_feature(env, ARM_FEATURE_V6)) {
         env->exception.fsr |= (1 << 11);
     }
 
-    syn = merge_syn_data_abort(env->exception.syndrome, target_el,
-                               same_el, 0, access_type == MMU_DATA_STORE,
-                               0x21);
-    raise_exception(env, EXCP_DATA_ABORT, syn, target_el);
+    raise_exception(env, EXCP_DATA_ABORT,
+                    syn_data_abort(same_el, 0, 0, 0, is_write == 1, 0x21),
+                    target_el);
 }
 
 #endif /* !defined(CONFIG_USER_ONLY) */
@@ -478,8 +434,6 @@ void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
 void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
 {
     cpsr_write(env, val, CPSR_ERET_MASK, CPSRWriteExceptionReturn);
-
-    arm_call_el_change_hook(arm_env_get_cpu(env));
 }
 
 /* Access to user mode registers from privileged modes.  */
@@ -975,8 +929,6 @@ void HELPER(exception_return)(CPUARMState *env)
         env->pc = env->elr_el[cur_el];
     }
 
-    arm_call_el_change_hook(arm_env_get_cpu(env));
-
     return;
 
 illegal_return:
index 14316eb..c55487f 100644 (file)
  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "kvm-consts.h"
-#include "sysemu/sysemu.h"
+#include <cpu.h>
+#include <cpu-qom.h>
+#include <exec/helper-proto.h>
+#include <kvm-consts.h>
+#include <sysemu/sysemu.h>
 #include "internals.h"
-#include "arm-powerctl.h"
-#include "exec/exec-all.h"
 
 bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
 {
@@ -74,6 +73,21 @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
     }
 }
 
+static CPUState *get_cpu_by_id(uint64_t id)
+{
+    CPUState *cpu;
+
+    CPU_FOREACH(cpu) {
+        ARMCPU *armcpu = ARM_CPU(cpu);
+
+        if (armcpu->mp_affinity == id) {
+            return cpu;
+        }
+    }
+
+    return NULL;
+}
+
 void arm_handle_psci_call(ARMCPU *cpu)
 {
     /*
@@ -84,6 +98,7 @@ void arm_handle_psci_call(ARMCPU *cpu)
      * Additional information about the calling convention used is available in
      * the document 'SMC Calling Convention' (ARM DEN 0028)
      */
+    CPUState *cs = CPU(cpu);
     CPUARMState *env = &cpu->env;
     uint64_t param[4];
     uint64_t context_id, mpidr;
@@ -108,6 +123,7 @@ void arm_handle_psci_call(ARMCPU *cpu)
     switch (param[0]) {
         CPUState *target_cpu_state;
         ARMCPU *target_cpu;
+        CPUClass *target_cpu_class;
 
     case QEMU_PSCI_0_2_FN_PSCI_VERSION:
         ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
@@ -121,7 +137,7 @@ void arm_handle_psci_call(ARMCPU *cpu)
 
         switch (param[2]) {
         case 0:
-            target_cpu_state = arm_get_cpu_by_id(mpidr);
+            target_cpu_state = get_cpu_by_id(mpidr);
             if (!target_cpu_state) {
                 ret = QEMU_PSCI_RET_INVALID_PARAMS;
                 break;
@@ -151,13 +167,52 @@ void arm_handle_psci_call(ARMCPU *cpu)
         mpidr = param[1];
         entry = param[2];
         context_id = param[3];
+
+        /* change to the cpu we are powering up */
+        target_cpu_state = get_cpu_by_id(mpidr);
+        if (!target_cpu_state) {
+            ret = QEMU_PSCI_RET_INVALID_PARAMS;
+            break;
+        }
+        target_cpu = ARM_CPU(target_cpu_state);
+        if (!target_cpu->powered_off) {
+            ret = QEMU_PSCI_RET_ALREADY_ON;
+            break;
+        }
+        target_cpu_class = CPU_GET_CLASS(target_cpu);
+
+        /* Initialize the cpu we are turning on */
+        cpu_reset(target_cpu_state);
+        target_cpu->powered_off = false;
+        target_cpu_state->halted = 0;
+
         /*
          * The PSCI spec mandates that newly brought up CPUs enter the
          * exception level of the caller in the same execution mode as
          * the caller, with context_id in x0/r0, respectively.
+         *
+         * For now, it is sufficient to assert() that CPUs come out of
+         * reset in the same mode as the calling CPU, since we only
+         * implement EL1, which means that
+         * (a) there is no EL2 for the calling CPU to trap into to change
+         *     its state
+         * (b) the newly brought up CPU enters EL1 immediately after coming
+         *     out of reset in the default state
          */
-        ret = arm_set_cpu_on(mpidr, entry, context_id, arm_current_el(env),
-                             is_a64(env));
+        assert(is_a64(env) == is_a64(&target_cpu->env));
+        if (is_a64(env)) {
+            if (entry & 1) {
+                ret = QEMU_PSCI_RET_INVALID_PARAMS;
+                break;
+            }
+            target_cpu->env.xregs[0] = context_id;
+        } else {
+            target_cpu->env.regs[0] = context_id;
+            target_cpu->env.thumb = entry & 1;
+        }
+        target_cpu_class->set_pc(target_cpu_state, entry);
+
+        ret = 0;
         break;
     case QEMU_PSCI_0_1_FN_CPU_OFF:
     case QEMU_PSCI_0_2_FN_CPU_OFF:
@@ -195,8 +250,9 @@ err:
     return;
 
 cpu_off:
-    ret = arm_set_cpu_off(cpu->mp_affinity);
+    cpu->powered_off = true;
+    cs->halted = 1;
+    cs->exception_index = EXCP_HLT;
+    cpu_loop_exit(cs);
     /* notreached */
-    /* sanity check in case something failed */
-    assert(ret == QEMU_ARM_POWERCTL_RET_SUCCESS);
 }
index f5e29d2..b13cff7 100644 (file)
@@ -19,7 +19,6 @@
 #include "qemu/osdep.h"
 
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "qemu/log.h"
 #include "arm_ldst.h"
@@ -275,12 +274,10 @@ static inline bool use_goto_tb(DisasContext *s, int n, uint64_t dest)
         return false;
     }
 
-#ifndef CONFIG_USER_ONLY
     /* Only link tbs from inside the same guest page */
     if ((s->tb->pc & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
         return false;
     }
-#endif
 
     return true;
 }
@@ -308,20 +305,6 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
     }
 }
 
-static void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
-{
-    /* We don't need to save all of the syndrome so we mask and shift
-     * out uneeded bits to help the sleb128 encoder do a better job.
-     */
-    syn &= ARM_INSN_START_WORD2_MASK;
-    syn >>= ARM_INSN_START_WORD2_SHIFT;
-
-    /* We check and clear insn_start_idx to catch multiple updates.  */
-    assert(s->insn_start_idx != 0);
-    tcg_set_insn_param(s->insn_start_idx, 2, syn);
-    s->insn_start_idx = 0;
-}
-
 static void unallocated_encoding(DisasContext *s)
 {
     /* Unallocated and reserved encodings are uncategorized */
@@ -737,47 +720,23 @@ static void gen_adc_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
  * Store from GPR register to memory.
  */
 static void do_gpr_st_memidx(DisasContext *s, TCGv_i64 source,
-                             TCGv_i64 tcg_addr, int size, int memidx,
-                             bool iss_valid,
-                             unsigned int iss_srt,
-                             bool iss_sf, bool iss_ar)
+                             TCGv_i64 tcg_addr, int size, int memidx)
 {
     g_assert(size <= 3);
     tcg_gen_qemu_st_i64(source, tcg_addr, memidx, s->be_data + size);
-
-    if (iss_valid) {
-        uint32_t syn;
-
-        syn = syn_data_abort_with_iss(0,
-                                      size,
-                                      false,
-                                      iss_srt,
-                                      iss_sf,
-                                      iss_ar,
-                                      0, 0, 0, 0, 0, false);
-        disas_set_insn_syndrome(s, syn);
-    }
 }
 
 static void do_gpr_st(DisasContext *s, TCGv_i64 source,
-                      TCGv_i64 tcg_addr, int size,
-                      bool iss_valid,
-                      unsigned int iss_srt,
-                      bool iss_sf, bool iss_ar)
+                      TCGv_i64 tcg_addr, int size)
 {
-    do_gpr_st_memidx(s, source, tcg_addr, size, get_mem_index(s),
-                     iss_valid, iss_srt, iss_sf, iss_ar);
+    do_gpr_st_memidx(s, source, tcg_addr, size, get_mem_index(s));
 }
 
 /*
  * Load from memory to GPR register
  */
-static void do_gpr_ld_memidx(DisasContext *s,
-                             TCGv_i64 dest, TCGv_i64 tcg_addr,
-                             int size, bool is_signed,
-                             bool extend, int memidx,
-                             bool iss_valid, unsigned int iss_srt,
-                             bool iss_sf, bool iss_ar)
+static void do_gpr_ld_memidx(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
+                             int size, bool is_signed, bool extend, int memidx)
 {
     TCGMemOp memop = s->be_data + size;
 
@@ -793,30 +752,13 @@ static void do_gpr_ld_memidx(DisasContext *s,
         g_assert(size < 3);
         tcg_gen_ext32u_i64(dest, dest);
     }
-
-    if (iss_valid) {
-        uint32_t syn;
-
-        syn = syn_data_abort_with_iss(0,
-                                      size,
-                                      is_signed,
-                                      iss_srt,
-                                      iss_sf,
-                                      iss_ar,
-                                      0, 0, 0, 0, 0, false);
-        disas_set_insn_syndrome(s, syn);
-    }
 }
 
-static void do_gpr_ld(DisasContext *s,
-                      TCGv_i64 dest, TCGv_i64 tcg_addr,
-                      int size, bool is_signed, bool extend,
-                      bool iss_valid, unsigned int iss_srt,
-                      bool iss_sf, bool iss_ar)
+static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
+                      int size, bool is_signed, bool extend)
 {
     do_gpr_ld_memidx(s, dest, tcg_addr, size, is_signed, extend,
-                     get_mem_index(s),
-                     iss_valid, iss_srt, iss_sf, iss_ar);
+                     get_mem_index(s));
 }
 
 /*
@@ -1872,22 +1814,6 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
 }
 #endif
 
-/* Update the Sixty-Four bit (SF) registersize. This logic is derived
- * from the ARMv8 specs for LDR (Shared decode for all encodings).
- */
-static bool disas_ldst_compute_iss_sf(int size, bool is_signed, int opc)
-{
-    int opc0 = extract32(opc, 0, 1);
-    int regsize;
-
-    if (is_signed) {
-        regsize = opc0 ? 32 : 64;
-    } else {
-        regsize = size == 3 ? 64 : 32;
-    }
-    return regsize == 64;
-}
-
 /* C3.3.6 Load/store exclusive
  *
  *  31 30 29         24  23  22   21  20  16  15  14   10 9    5 4    0
@@ -1939,15 +1865,10 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
         }
     } else {
         TCGv_i64 tcg_rt = cpu_reg(s, rt);
-        bool iss_sf = disas_ldst_compute_iss_sf(size, false, 0);
-
-        /* Generate ISS for non-exclusive accesses including LASR.  */
         if (is_store) {
-            do_gpr_st(s, tcg_rt, tcg_addr, size,
-                      true, rt, iss_sf, is_lasr);
+            do_gpr_st(s, tcg_rt, tcg_addr, size);
         } else {
-            do_gpr_ld(s, tcg_rt, tcg_addr, size, false, false,
-                      true, rt, iss_sf, is_lasr);
+            do_gpr_ld(s, tcg_rt, tcg_addr, size, false, false);
         }
     }
 }
@@ -1999,11 +1920,7 @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
     if (is_vector) {
         do_fp_ld(s, rt, tcg_addr, size);
     } else {
-        /* Only unsigned 32bit loads target 32bit registers.  */
-        bool iss_sf = opc == 0 ? 32 : 64;
-
-        do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false,
-                  true, rt, iss_sf, false);
+        do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false);
     }
     tcg_temp_free_i64(tcg_addr);
 }
@@ -2122,11 +2039,9 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
     } else {
         TCGv_i64 tcg_rt = cpu_reg(s, rt);
         if (is_load) {
-            do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false,
-                      false, 0, false, false);
+            do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false);
         } else {
-            do_gpr_st(s, tcg_rt, tcg_addr, size,
-                      false, 0, false, false);
+            do_gpr_st(s, tcg_rt, tcg_addr, size);
         }
     }
     tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
@@ -2139,11 +2054,9 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
     } else {
         TCGv_i64 tcg_rt2 = cpu_reg(s, rt2);
         if (is_load) {
-            do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false,
-                      false, 0, false, false);
+            do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false);
         } else {
-            do_gpr_st(s, tcg_rt2, tcg_addr, size,
-                      false, 0, false, false);
+            do_gpr_st(s, tcg_rt2, tcg_addr, size);
         }
     }
 
@@ -2173,20 +2086,19 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
  * size: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64bit
  * opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
  */
-static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
-                                int opc,
-                                int size,
-                                int rt,
-                                bool is_vector)
+static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
 {
+    int rt = extract32(insn, 0, 5);
     int rn = extract32(insn, 5, 5);
     int imm9 = sextract32(insn, 12, 9);
+    int opc = extract32(insn, 22, 2);
+    int size = extract32(insn, 30, 2);
     int idx = extract32(insn, 10, 2);
     bool is_signed = false;
     bool is_store = false;
     bool is_extended = false;
     bool is_unpriv = (idx == 2);
-    bool iss_valid = !is_vector;
+    bool is_vector = extract32(insn, 26, 1);
     bool post_index;
     bool writeback;
 
@@ -2216,8 +2128,8 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
             return;
         }
         is_store = (opc == 0);
-        is_signed = extract32(opc, 1, 1);
-        is_extended = (size < 3) && extract32(opc, 0, 1);
+        is_signed = opc & (1<<1);
+        is_extended = (size < 3) && (opc & 1);
     }
 
     switch (idx) {
@@ -2254,15 +2166,12 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
     } else {
         TCGv_i64 tcg_rt = cpu_reg(s, rt);
         int memidx = is_unpriv ? get_a64_user_mem_index(s) : get_mem_index(s);
-        bool iss_sf = disas_ldst_compute_iss_sf(size, is_signed, opc);
 
         if (is_store) {
-            do_gpr_st_memidx(s, tcg_rt, tcg_addr, size, memidx,
-                             iss_valid, rt, iss_sf, false);
+            do_gpr_st_memidx(s, tcg_rt, tcg_addr, size, memidx);
         } else {
             do_gpr_ld_memidx(s, tcg_rt, tcg_addr, size,
-                             is_signed, is_extended, memidx,
-                             iss_valid, rt, iss_sf, false);
+                             is_signed, is_extended, memidx);
         }
     }
 
@@ -2296,19 +2205,19 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
  * Rn: address register or SP for base
  * Rm: offset register or ZR for offset
  */
-static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn,
-                                   int opc,
-                                   int size,
-                                   int rt,
-                                   bool is_vector)
+static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn)
 {
+    int rt = extract32(insn, 0, 5);
     int rn = extract32(insn, 5, 5);
     int shift = extract32(insn, 12, 1);
     int rm = extract32(insn, 16, 5);
+    int opc = extract32(insn, 22, 2);
     int opt = extract32(insn, 13, 3);
+    int size = extract32(insn, 30, 2);
     bool is_signed = false;
     bool is_store = false;
     bool is_extended = false;
+    bool is_vector = extract32(insn, 26, 1);
 
     TCGv_i64 tcg_rm;
     TCGv_i64 tcg_addr;
@@ -2360,14 +2269,10 @@ static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn,
         }
     } else {
         TCGv_i64 tcg_rt = cpu_reg(s, rt);
-        bool iss_sf = disas_ldst_compute_iss_sf(size, is_signed, opc);
         if (is_store) {
-            do_gpr_st(s, tcg_rt, tcg_addr, size,
-                      true, rt, iss_sf, false);
+            do_gpr_st(s, tcg_rt, tcg_addr, size);
         } else {
-            do_gpr_ld(s, tcg_rt, tcg_addr, size,
-                      is_signed, is_extended,
-                      true, rt, iss_sf, false);
+            do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
         }
     }
 }
@@ -2389,14 +2294,14 @@ static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn,
  * Rn: base address register (inc SP)
  * Rt: target register
  */
-static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn,
-                                        int opc,
-                                        int size,
-                                        int rt,
-                                        bool is_vector)
+static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn)
 {
+    int rt = extract32(insn, 0, 5);
     int rn = extract32(insn, 5, 5);
     unsigned int imm12 = extract32(insn, 10, 12);
+    bool is_vector = extract32(insn, 26, 1);
+    int size = extract32(insn, 30, 2);
+    int opc = extract32(insn, 22, 2);
     unsigned int offset;
 
     TCGv_i64 tcg_addr;
@@ -2444,13 +2349,10 @@ static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn,
         }
     } else {
         TCGv_i64 tcg_rt = cpu_reg(s, rt);
-        bool iss_sf = disas_ldst_compute_iss_sf(size, is_signed, opc);
         if (is_store) {
-            do_gpr_st(s, tcg_rt, tcg_addr, size,
-                      true, rt, iss_sf, false);
+            do_gpr_st(s, tcg_rt, tcg_addr, size);
         } else {
-            do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended,
-                      true, rt, iss_sf, false);
+            do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
         }
     }
 }
@@ -2458,25 +2360,20 @@ static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn,
 /* Load/store register (all forms) */
 static void disas_ldst_reg(DisasContext *s, uint32_t insn)
 {
-    int rt = extract32(insn, 0, 5);
-    int opc = extract32(insn, 22, 2);
-    bool is_vector = extract32(insn, 26, 1);
-    int size = extract32(insn, 30, 2);
-
     switch (extract32(insn, 24, 2)) {
     case 0:
         if (extract32(insn, 21, 1) == 1 && extract32(insn, 10, 2) == 2) {
-            disas_ldst_reg_roffset(s, insn, opc, size, rt, is_vector);
+            disas_ldst_reg_roffset(s, insn);
         } else {
             /* Load/store register (unscaled immediate)
              * Load/store immediate pre/post-indexed
              * Load/store register unprivileged
              */
-            disas_ldst_reg_imm9(s, insn, opc, size, rt, is_vector);
+            disas_ldst_reg_imm9(s, insn);
         }
         break;
     case 1:
-        disas_ldst_reg_unsigned_imm(s, insn, opc, size, rt, is_vector);
+        disas_ldst_reg_unsigned_imm(s, insn);
         break;
     default:
         unallocated_encoding(s);
@@ -11197,8 +11094,7 @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb)
     tcg_clear_temp_count();
 
     do {
-        dc->insn_start_idx = tcg_op_buf_count();
-        tcg_gen_insn_start(dc->pc, 0, 0);
+        tcg_gen_insn_start(dc->pc, 0);
         num_insns++;
 
         if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
index bd5d5cb..940ec8d 100644 (file)
@@ -23,7 +23,6 @@
 #include "cpu.h"
 #include "internals.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "qemu/log.h"
 #include "qemu/bitops.h"
@@ -85,7 +84,6 @@ void arm_translate_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
 
     for (i = 0; i < 16; i++) {
         cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
@@ -4051,22 +4049,15 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
     return 0;
 }
 
-static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
-{
-#ifndef CONFIG_USER_ONLY
-    return (s->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
-           ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
 {
-    if (use_goto_tb(s, dest)) {
+    TranslationBlock *tb;
+
+    tb = s->tb;
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         gen_set_pc_im(s, dest);
-        tcg_gen_exit_tb((uintptr_t)s->tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         gen_set_pc_im(s, dest);
         tcg_gen_exit_tb(0);
@@ -5312,30 +5303,6 @@ static int neon_2rm_is_float_op(int op)
             op >= NEON_2RM_VRECPE_F);
 }
 
-static bool neon_2rm_is_v8_op(int op)
-{
-    /* Return true if this neon 2reg-misc op is ARMv8 and up */
-    switch (op) {
-    case NEON_2RM_VRINTN:
-    case NEON_2RM_VRINTA:
-    case NEON_2RM_VRINTM:
-    case NEON_2RM_VRINTP:
-    case NEON_2RM_VRINTZ:
-    case NEON_2RM_VRINTX:
-    case NEON_2RM_VCVTAU:
-    case NEON_2RM_VCVTAS:
-    case NEON_2RM_VCVTNU:
-    case NEON_2RM_VCVTNS:
-    case NEON_2RM_VCVTPU:
-    case NEON_2RM_VCVTPS:
-    case NEON_2RM_VCVTMU:
-    case NEON_2RM_VCVTMS:
-        return true;
-    default:
-        return false;
-    }
-}
-
 /* Each entry in this array has bit n set if the insn allows
  * size value n (otherwise it will UNDEF). Since unallocated
  * op values will have no bits set they always UNDEF.
@@ -6823,10 +6790,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
                 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
                     return 1;
                 }
-                if (neon_2rm_is_v8_op(op) &&
-                    !arm_dc_feature(s, ARM_FEATURE_V8)) {
-                    return 1;
-                }
                 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
                     q && ((rm | rd) & 1)) {
                     return 1;
@@ -11761,8 +11724,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
       }
     do {
         tcg_gen_insn_start(dc->pc,
-                           (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
-                           0);
+                           (dc->condexec_cond << 4) | (dc->condexec_mask >> 1));
         num_insns++;
 
 #ifdef CONFIG_USER_ONLY
@@ -12079,10 +12041,8 @@ void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
     if (is_a64(env)) {
         env->pc = data[0];
         env->condexec_bits = 0;
-        env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
     } else {
         env->regs[15] = data[0];
         env->condexec_bits = data[1];
-        env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
     }
 }
index dbd7ac8..6a18d7b 100644 (file)
@@ -59,8 +59,6 @@ typedef struct DisasContext {
     bool ss_same_el;
     /* Bottom two bits of XScale c15_cpar coprocessor access control reg */
     int c15_cpar;
-    /* TCG op index of the current insn_start.  */
-    int insn_start_idx;
 #define TMP_A64_MAX 16
     int tmp_a64_count;
     TCGv_i64 tmp_a64[TMP_A64_MAX];
index 7556e9f..df4c0b5 100644 (file)
@@ -50,6 +50,44 @@ typedef struct CRISCPUClass {
     uint32_t vr;
 } CRISCPUClass;
 
-typedef struct CRISCPU CRISCPU;
+/**
+ * CRISCPU:
+ * @env: #CPUCRISState
+ *
+ * A CRIS CPU.
+ */
+typedef struct CRISCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUCRISState env;
+} CRISCPU;
+
+static inline CRISCPU *cris_env_get_cpu(CPUCRISState *env)
+{
+    return container_of(env, CRISCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(cris_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(CRISCPU, env)
+
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_cris_cpu;
+#endif
+
+void cris_cpu_do_interrupt(CPUState *cpu);
+void crisv10_cpu_do_interrupt(CPUState *cpu);
+bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
+
+void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
+
+hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+
+int crisv10_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int cris_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int cris_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
index c5a656b..1cb79dd 100644 (file)
@@ -26,7 +26,6 @@
 #include "cpu.h"
 #include "qemu-common.h"
 #include "mmu.h"
-#include "exec/exec-all.h"
 
 
 static void cris_cpu_set_pc(CPUState *cs, vaddr value)
index 7d7fe6e..415cf91 100644 (file)
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-
-#ifndef CRIS_CPU_H
-#define CRIS_CPU_H
+#ifndef CPU_CRIS_H
+#define CPU_CRIS_H
 
 #include "qemu-common.h"
-#include "cpu-qom.h"
 
 #define TARGET_LONG_BITS 32
 
@@ -173,47 +171,10 @@ typedef struct CPUCRISState {
     void *load_info;
 } CPUCRISState;
 
-/**
- * CRISCPU:
- * @env: #CPUCRISState
- *
- * A CRIS CPU.
- */
-struct CRISCPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPUCRISState env;
-};
-
-static inline CRISCPU *cris_env_get_cpu(CPUCRISState *env)
-{
-    return container_of(env, CRISCPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(cris_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(CRISCPU, env)
-
-#ifndef CONFIG_USER_ONLY
-extern const struct VMStateDescription vmstate_cris_cpu;
-#endif
-
-void cris_cpu_do_interrupt(CPUState *cpu);
-void crisv10_cpu_do_interrupt(CPUState *cpu);
-bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
-
-void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-                         int flags);
-
-hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-
-int crisv10_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int cris_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int cris_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+#include "cpu-qom.h"
 
 CRISCPU *cpu_cris_init(const char *cpu_model);
+int cpu_cris_exec(CPUState *cpu);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
@@ -260,6 +221,7 @@ enum {
 
 #define cpu_init(cpu_model) CPU(cpu_cris_init(cpu_model))
 
+#define cpu_exec cpu_cris_exec
 #define cpu_signal_handler cpu_cris_signal_handler
 
 /* MMU modes definitions */
@@ -287,7 +249,7 @@ int cris_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
 #include "exec/cpu-all.h"
 
 static inline void cpu_get_tb_cpu_state(CPUCRISState *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *pc = env->pc;
     *cs_base = 0;
@@ -299,4 +261,6 @@ static inline void cpu_get_tb_cpu_state(CPUCRISState *env, target_ulong *pc,
 #define cpu_list cris_cpu_list
 void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 
+#include "exec/exec-all.h"
+
 #endif
index cdc2f8c..cdba377 100644 (file)
@@ -17,9 +17,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-
 #ifndef CRISV32_DECODE_H
-#define CRISV32_DECODE_H
+#define CRISV32_DECODE_H 1
 
 /* Convenient binary macros.  */
 #define HEX__(n) 0x##n##LU
index 3a72ee2..1bbf17b 100644 (file)
@@ -19,7 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
 
 int crisv10_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
index af78cca..1eb9fd9 100644 (file)
@@ -22,7 +22,6 @@
 #include "cpu.h"
 #include "mmu.h"
 #include "qemu/host-utils.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 
index 6b797e8..9cc2820 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "hw/hw.h"
-#include "migration/cpu.h"
 
 static const VMStateDescription vmstate_tlbset = {
     .name = "cpu/tlbset",
index b8db908..4278d2d 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "mmu.h"
 
 #ifdef DEBUG
index 5043039..320f2b8 100644 (file)
@@ -23,7 +23,6 @@
 #include "mmu.h"
 #include "exec/helper-proto.h"
 #include "qemu/host-utils.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 //#define CRIS_OP_HELPER_DEBUG
@@ -41,8 +40,8 @@
 /* Try to fill the TLB and return an exception if error. If retaddr is
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr)
 {
     CRISCPU *cpu = CRIS_CPU(cs);
     CPUCRISState *env = &cpu->env;
@@ -50,7 +49,7 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
 
     D_LOG("%s pc=%x tpc=%x ra=%p\n", __func__,
           env->pc, env->pregs[PR_EDA], (void *)retaddr);
-    ret = cris_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = cris_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
index f4a8d7d..5227f65 100644 (file)
@@ -26,7 +26,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "exec/helper-proto.h"
 #include "mmu.h"
@@ -521,22 +520,14 @@ static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
     gen_set_label(l1);
 }
 
-static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
-{
-#ifndef CONFIG_USER_ONLY
-    return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
-           (dc->ppc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 {
-    if (use_goto_tb(dc, dest)) {
+    TranslationBlock *tb;
+    tb = dc->tb;
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(env_pc, dest);
-                tcg_gen_exit_tb((uintptr_t)dc->tb + n);
+                tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_tl(env_pc, dest);
         tcg_gen_exit_tb(0);
@@ -3311,8 +3302,7 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
 
 #ifdef DEBUG_DISAS
 #if !DISAS_CRIS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         log_target_disas(cs, pc_start, dc->pc - pc_start,
                          env->pregs[PR_VR]);
         qemu_log("\nisize=%d osize=%d\n",
@@ -3374,7 +3364,6 @@ void cris_initialize_tcg(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
     cc_x = tcg_global_mem_new(cpu_env,
                               offsetof(CPUCRISState, cc_x), "cc_x");
     cc_src = tcg_global_mem_new(cpu_env,
index 4707a18..06ba1ef 100644 (file)
@@ -1250,7 +1250,6 @@ void cris_initialize_crisv10_tcg(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
     cc_x = tcg_global_mem_new(cpu_env,
                               offsetof(CPUCRISState, cc_x), "cc_x");
     cc_src = tcg_global_mem_new(cpu_env,
index 6fd7fe0..f47df19 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 
 
@@ -218,7 +217,7 @@ void breakpoint_handler(CPUState *cs)
             if (check_hw_breakpoints(env, false)) {
                 raise_exception(env, EXCP01_DB);
             } else {
-                cpu_loop_exit_noexc(cs);
+                cpu_resume_from_signal(cs, NULL);
             }
         }
     } else {
index 5dde658..cb75017 100644 (file)
@@ -21,6 +21,7 @@
 #define QEMU_I386_CPU_QOM_H
 
 #include "qom/cpu.h"
+#include "cpu.h"
 #include "qemu/notify.h"
 
 #ifdef TARGET_X86_64
@@ -67,6 +68,101 @@ typedef struct X86CPUClass {
     void (*parent_reset)(CPUState *cpu);
 } X86CPUClass;
 
-typedef struct X86CPU X86CPU;
+/**
+ * X86CPU:
+ * @env: #CPUX86State
+ * @migratable: If set, only migratable flags will be accepted when "enforce"
+ * mode is used, and only migratable flags will be included in the "host"
+ * CPU model.
+ *
+ * An x86 CPU.
+ */
+typedef struct X86CPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUX86State env;
+
+    bool hyperv_vapic;
+    bool hyperv_relaxed_timing;
+    int hyperv_spinlock_attempts;
+    char *hyperv_vendor_id;
+    bool hyperv_time;
+    bool hyperv_crash;
+    bool hyperv_reset;
+    bool hyperv_vpindex;
+    bool hyperv_runtime;
+    bool hyperv_synic;
+    bool hyperv_stimer;
+    bool check_cpuid;
+    bool enforce_cpuid;
+    bool expose_kvm;
+    bool migratable;
+    bool host_features;
+    int64_t apic_id;
+
+    /* if true the CPUID code directly forward host cache leaves to the guest */
+    bool cache_info_passthrough;
+
+    /* Features that were filtered out because of missing host capabilities */
+    uint32_t filtered_features[FEATURE_WORDS];
+
+    /* Enable PMU CPUID bits. This can't be enabled by default yet because
+     * it doesn't have ABI stability guarantees, as it passes all PMU CPUID
+     * bits returned by GET_SUPPORTED_CPUID (that depend on host CPU and kernel
+     * capabilities) directly to the guest.
+     */
+    bool enable_pmu;
+
+    /* in order to simplify APIC support, we leave this pointer to the
+       user */
+    struct DeviceState *apic_state;
+    struct MemoryRegion *cpu_as_root, *cpu_as_mem, *smram;
+    Notifier machine_done;
+} X86CPU;
+
+static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
+{
+    return container_of(env, X86CPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(x86_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(X86CPU, env)
+
+#ifndef CONFIG_USER_ONLY
+extern struct VMStateDescription vmstate_x86_cpu;
+#endif
+
+/**
+ * x86_cpu_do_interrupt:
+ * @cpu: vCPU the interrupt is to be handled by.
+ */
+void x86_cpu_do_interrupt(CPUState *cpu);
+bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
+
+int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
+                             int cpuid, void *opaque);
+int x86_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu,
+                             int cpuid, void *opaque);
+int x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
+                                 void *opaque);
+int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
+                                 void *opaque);
+
+void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
+                                Error **errp);
+
+void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags);
+
+hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+
+int x86_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int x86_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+
+void x86_cpu_exec_enter(CPUState *cpu);
+void x86_cpu_exec_exit(CPUState *cpu);
 
 #endif
index 6a1afab..da5d081 100644 (file)
@@ -20,7 +20,6 @@
 #include "qemu/cutils.h"
 
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "sysemu/kvm.h"
 #include "sysemu/cpus.h"
 #include "kvm_i386.h"
 #include "qapi/visitor.h"
 #include "sysemu/arch_init.h"
 
+#include "hw/hw.h"
 #if defined(CONFIG_KVM)
 #include <linux/kvm_para.h>
 #endif
 
 #include "sysemu/sysemu.h"
 #include "hw/qdev-properties.h"
-#include "hw/i386/topology.h"
 #ifndef CONFIG_USER_ONLY
 #include "exec/address-spaces.h"
-#include "hw/hw.h"
 #include "hw/xen/xen.h"
 #include "hw/i386/apic_internal.h"
 #endif
@@ -245,47 +243,6 @@ static const char *kvm_feature_name[] = {
     NULL, NULL, NULL, NULL,
 };
 
-static const char *hyperv_priv_feature_name[] = {
-    NULL /* hv_msr_vp_runtime_access */, NULL /* hv_msr_time_refcount_access */,
-    NULL /* hv_msr_synic_access */, NULL /* hv_msr_stimer_access */,
-    NULL /* hv_msr_apic_access */, NULL /* hv_msr_hypercall_access */,
-    NULL /* hv_vpindex_access */, NULL /* hv_msr_reset_access */,
-    NULL /* hv_msr_stats_access */, NULL /* hv_reftsc_access */,
-    NULL /* hv_msr_idle_access */, NULL /* hv_msr_frequency_access */,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-};
-
-static const char *hyperv_ident_feature_name[] = {
-    NULL /* hv_create_partitions */, NULL /* hv_access_partition_id */,
-    NULL /* hv_access_memory_pool */, NULL /* hv_adjust_message_buffers */,
-    NULL /* hv_post_messages */, NULL /* hv_signal_events */,
-    NULL /* hv_create_port */, NULL /* hv_connect_port */,
-    NULL /* hv_access_stats */, NULL, NULL, NULL /* hv_debugging */,
-    NULL /* hv_cpu_power_management */, NULL /* hv_configure_profiler */,
-    NULL, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-};
-
-static const char *hyperv_misc_feature_name[] = {
-    NULL /* hv_mwait */, NULL /* hv_guest_debugging */,
-    NULL /* hv_perf_monitor */, NULL /* hv_cpu_dynamic_part */,
-    NULL /* hv_hypercall_params_xmm */, NULL /* hv_guest_idle_state */,
-    NULL, NULL,
-    NULL, NULL, NULL /* hv_guest_crash_msr */, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-};
-
 static const char *svm_feature_name[] = {
     "npt", "lbrv", "svm_lock", "nrip_save",
     "tsc_scale", "vmcb_clean",  "flushbyasid", "decodeassists",
@@ -305,12 +262,12 @@ static const char *cpuid_7_0_ebx_feature_name[] = {
 };
 
 static const char *cpuid_7_0_ecx_feature_name[] = {
-    NULL, NULL, "umip", "pku",
+    NULL, NULL, NULL, "pku",
     "ospke", NULL, NULL, NULL,
     NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL,
-    NULL, NULL, "rdpid", NULL,
+    NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL,
 };
@@ -399,11 +356,10 @@ static const char *cpuid_6_feature_name[] = {
 #define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
           CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
           CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT |            \
-          CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE | \
-          CPUID_7_0_EBX_ERMS)
+          CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE)
           /* missing:
           CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
-          CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
+          CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
           CPUID_7_0_EBX_RDSEED */
 #define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE)
 #define TCG_APM_FEATURES 0
@@ -453,18 +409,6 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
         .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX,
         .tcg_features = TCG_KVM_FEATURES,
     },
-    [FEAT_HYPERV_EAX] = {
-        .feat_names = hyperv_priv_feature_name,
-        .cpuid_eax = 0x40000003, .cpuid_reg = R_EAX,
-    },
-    [FEAT_HYPERV_EBX] = {
-        .feat_names = hyperv_ident_feature_name,
-        .cpuid_eax = 0x40000003, .cpuid_reg = R_EBX,
-    },
-    [FEAT_HYPERV_EDX] = {
-        .feat_names = hyperv_misc_feature_name,
-        .cpuid_eax = 0x40000003, .cpuid_reg = R_EDX,
-    },
     [FEAT_SVM] = {
         .feat_names = svm_feature_name,
         .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX,
@@ -529,32 +473,25 @@ static const X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
 const ExtSaveArea x86_ext_save_areas[] = {
     [XSTATE_YMM_BIT] =
           { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
-            .offset = offsetof(X86XSaveArea, avx_state),
-            .size = sizeof(XSaveAVX) },
+            .offset = 0x240, .size = 0x100 },
     [XSTATE_BNDREGS_BIT] =
           { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
-            .offset = offsetof(X86XSaveArea, bndreg_state),
-            .size = sizeof(XSaveBNDREG)  },
+            .offset = 0x3c0, .size = 0x40  },
     [XSTATE_BNDCSR_BIT] =
           { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
-            .offset = offsetof(X86XSaveArea, bndcsr_state),
-            .size = sizeof(XSaveBNDCSR)  },
+            .offset = 0x400, .size = 0x40  },
     [XSTATE_OPMASK_BIT] =
           { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
-            .offset = offsetof(X86XSaveArea, opmask_state),
-            .size = sizeof(XSaveOpmask) },
+            .offset = 0x440, .size = 0x40 },
     [XSTATE_ZMM_Hi256_BIT] =
           { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
-            .offset = offsetof(X86XSaveArea, zmm_hi256_state),
-            .size = sizeof(XSaveZMM_Hi256) },
+            .offset = 0x480, .size = 0x200 },
     [XSTATE_Hi16_ZMM_BIT] =
           { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
-            .offset = offsetof(X86XSaveArea, hi16_zmm_state),
-            .size = sizeof(XSaveHi16_ZMM) },
+            .offset = 0x680, .size = 0x400 },
     [XSTATE_PKRU_BIT] =
           { .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_PKU,
-            .offset = offsetof(X86XSaveArea, pkru_state),
-            .size = sizeof(XSavePKRU) },
+            .offset = 0xA80, .size = 0x8 },
 };
 
 const char *get_register_name_32(unsigned int reg)
@@ -732,14 +669,6 @@ static ObjectClass *x86_cpu_class_by_name(const char *cpu_model)
     return oc;
 }
 
-static char *x86_cpu_class_get_model_name(X86CPUClass *cc)
-{
-    const char *class_name = object_class_get_name(OBJECT_CLASS(cc));
-    assert(g_str_has_suffix(class_name, X86_CPU_TYPE_SUFFIX));
-    return g_strndup(class_name,
-                     strlen(class_name) - strlen(X86_CPU_TYPE_SUFFIX));
-}
-
 struct X86CPUDefinition {
     const char *name;
     uint32_t level;
@@ -773,7 +702,6 @@ static X86CPUDefinition builtin_x86_defs[] = {
         .features[FEAT_8000_0001_ECX] =
             CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM,
         .xlevel = 0x8000000A,
-        .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
     },
     {
         .name = "phenom",
@@ -870,7 +798,6 @@ static X86CPUDefinition builtin_x86_defs[] = {
         .features[FEAT_1_ECX] =
             CPUID_EXT_SSE3,
         .xlevel = 0x80000004,
-        .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
     },
     {
         .name = "kvm32",
@@ -967,7 +894,6 @@ static X86CPUDefinition builtin_x86_defs[] = {
         .features[FEAT_8000_0001_EDX] =
             CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
         .xlevel = 0x80000008,
-        .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
     },
     {
         .name = "n270",
@@ -1302,51 +1228,6 @@ static X86CPUDefinition builtin_x86_defs[] = {
         .model_id = "Intel Core Processor (Broadwell)",
     },
     {
-        .name = "Skylake-Client",
-        .level = 0xd,
-        .vendor = CPUID_VENDOR_INTEL,
-        .family = 6,
-        .model = 94,
-        .stepping = 3,
-        .features[FEAT_1_EDX] =
-            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
-            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
-            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
-            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
-            CPUID_DE | CPUID_FP87,
-        .features[FEAT_1_ECX] =
-            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
-            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
-            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
-            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
-            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
-            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
-        .features[FEAT_8000_0001_EDX] =
-            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
-            CPUID_EXT2_SYSCALL,
-        .features[FEAT_8000_0001_ECX] =
-            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
-        .features[FEAT_7_0_EBX] =
-            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
-            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
-            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
-            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
-            CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX,
-        /* Missing: XSAVES (not supported by some Linux versions,
-         * including v4.1 to v4.6).
-         * KVM doesn't yet expose any XSAVES state save component,
-         * and the only one defined in Skylake (processor tracing)
-         * probably will block migration anyway.
-         */
-        .features[FEAT_XSAVE] =
-            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
-            CPUID_XSAVE_XGETBV1,
-        .features[FEAT_6_EAX] =
-            CPUID_6_EAX_ARAT,
-        .xlevel = 0x80000008,
-        .model_id = "Intel Core Processor (Skylake)",
-    },
-    {
         .name = "Opteron_G1",
         .level = 5,
         .vendor = CPUID_VENDOR_AMD,
@@ -1547,17 +1428,6 @@ static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
 
 #ifdef CONFIG_KVM
 
-static bool lmce_supported(void)
-{
-    uint64_t mce_cap;
-
-    if (kvm_ioctl(kvm_state, KVM_X86_GET_MCE_CAP_SUPPORTED, &mce_cap) < 0) {
-        return false;
-    }
-
-    return !!(mce_cap & MCG_LMCE_P);
-}
-
 static int cpu_x86_fill_model_id(char *str)
 {
     uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
@@ -1620,21 +1490,16 @@ static void host_x86_cpu_initfn(Object *obj)
     CPUX86State *env = &cpu->env;
     KVMState *s = kvm_state;
 
+    assert(kvm_enabled());
+
     /* We can't fill the features array here because we don't know yet if
      * "migratable" is true or false.
      */
     cpu->host_features = true;
 
-    /* If KVM is disabled, x86_cpu_realizefn() will report an error later */
-    if (kvm_enabled()) {
-        env->cpuid_level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
-        env->cpuid_xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
-        env->cpuid_xlevel2 = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
-
-        if (lmce_supported()) {
-            object_property_set_bool(OBJECT(cpu), true, "lmce", &error_abort);
-        }
-    }
+    env->cpuid_level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
+    env->cpuid_xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
+    env->cpuid_xlevel2 = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
 
     object_property_set_bool(OBJECT(cpu), true, "pmu", &error_abort);
 }
@@ -1893,6 +1758,50 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, const char *name,
     cpu->env.tsc_khz = cpu->env.user_tsc_khz = value / 1000;
 }
 
+static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, const char *name,
+                                  void *opaque, Error **errp)
+{
+    X86CPU *cpu = X86_CPU(obj);
+    int64_t value = cpu->apic_id;
+
+    visit_type_int(v, name, &value, errp);
+}
+
+static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, const char *name,
+                                  void *opaque, Error **errp)
+{
+    X86CPU *cpu = X86_CPU(obj);
+    DeviceState *dev = DEVICE(obj);
+    const int64_t min = 0;
+    const int64_t max = UINT32_MAX;
+    Error *error = NULL;
+    int64_t value;
+
+    if (dev->realized) {
+        error_setg(errp, "Attempt to set property '%s' on '%s' after "
+                   "it was realized", name, object_get_typename(obj));
+        return;
+    }
+
+    visit_type_int(v, name, &value, &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
+    if (value < min || value > max) {
+        error_setg(errp, "Property %s.%s doesn't take value %" PRId64
+                   " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
+                   object_get_typename(obj), name, value, min, max);
+        return;
+    }
+
+    if ((value != cpu->apic_id) && cpu_exists(value)) {
+        error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
+        return;
+    }
+    cpu->apic_id = value;
+}
+
 /* Generic getter for "feature-words" and "filtered-features" properties */
 static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
                                       const char *name, void *opaque,
@@ -1900,6 +1809,7 @@ static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
 {
     uint32_t *array = (uint32_t *)opaque;
     FeatureWord w;
+    Error *err = NULL;
     X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
     X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
     X86CPUFeatureWordInfoList *list = NULL;
@@ -1919,7 +1829,8 @@ static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
         list = &list_entries[w];
     }
 
-    visit_type_X86CPUFeatureWordInfoList(v, "feature-words", &list, errp);
+    visit_type_X86CPUFeatureWordInfoList(v, "feature-words", &list, &err);
+    error_propagate(errp, err);
 }
 
 static void x86_get_hv_spinlocks(Object *obj, Visitor *v, const char *name,
@@ -1972,87 +1883,104 @@ static inline void feat2prop(char *s)
     }
 }
 
-/* Compatibily hack to maintain legacy +-feat semantic,
- * where +-feat overwrites any feature set by
- * feat=on|feat even if the later is parsed after +-feat
- * (i.e. "-x2apic,x2apic=on" will result in x2apic disabled)
- */
-static FeatureWordArray plus_features = { 0 };
-static FeatureWordArray minus_features = { 0 };
-
 /* Parse "+feature,-feature,feature=foo" CPU feature string
  */
-static void x86_cpu_parse_featurestr(const char *typename, char *features,
+static void x86_cpu_parse_featurestr(CPUState *cs, char *features,
                                      Error **errp)
 {
+    X86CPU *cpu = X86_CPU(cs);
     char *featurestr; /* Single 'key=value" string being parsed */
+    FeatureWord w;
+    /* Features to be added */
+    FeatureWordArray plus_features = { 0 };
+    /* Features to be removed */
+    FeatureWordArray minus_features = { 0 };
+    uint32_t numvalue;
+    CPUX86State *env = &cpu->env;
     Error *local_err = NULL;
-    static bool cpu_globals_initialized;
-
-    if (cpu_globals_initialized) {
-        return;
-    }
-    cpu_globals_initialized = true;
 
-    if (!features) {
-        return;
-    }
+    featurestr = features ? strtok(features, ",") : NULL;
 
-    for (featurestr = strtok(features, ",");
-         featurestr  && !local_err;
-         featurestr = strtok(NULL, ",")) {
-        const char *name;
-        const char *val = NULL;
-        char *eq = NULL;
-        char num[32];
-        GlobalProperty *prop;
-
-        /* Compatibility syntax: */
+    while (featurestr) {
+        char *val;
         if (featurestr[0] == '+') {
             add_flagname_to_bitmaps(featurestr + 1, plus_features, &local_err);
-            continue;
         } else if (featurestr[0] == '-') {
             add_flagname_to_bitmaps(featurestr + 1, minus_features, &local_err);
-            continue;
-        }
-
-        eq = strchr(featurestr, '=');
-        if (eq) {
-            *eq++ = 0;
-            val = eq;
+        } else if ((val = strchr(featurestr, '='))) {
+            *val = 0; val++;
+            feat2prop(featurestr);
+            if (!strcmp(featurestr, "xlevel")) {
+                char *err;
+                char num[32];
+
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err) {
+                    error_setg(errp, "bad numerical value %s", val);
+                    return;
+                }
+                if (numvalue < 0x80000000) {
+                    error_report("xlevel value shall always be >= 0x80000000"
+                                 ", fixup will be removed in future versions");
+                    numvalue += 0x80000000;
+                }
+                snprintf(num, sizeof(num), "%" PRIu32, numvalue);
+                object_property_parse(OBJECT(cpu), num, featurestr, &local_err);
+            } else if (!strcmp(featurestr, "tsc-freq")) {
+                int64_t tsc_freq;
+                char *err;
+                char num[32];
+
+                tsc_freq = qemu_strtosz_suffix_unit(val, &err,
+                                               QEMU_STRTOSZ_DEFSUFFIX_B, 1000);
+                if (tsc_freq < 0 || *err) {
+                    error_setg(errp, "bad numerical value %s", val);
+                    return;
+                }
+                snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
+                object_property_parse(OBJECT(cpu), num, "tsc-frequency",
+                                      &local_err);
+            } else if (!strcmp(featurestr, "hv-spinlocks")) {
+                char *err;
+                const int min = 0xFFF;
+                char num[32];
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err) {
+                    error_setg(errp, "bad numerical value %s", val);
+                    return;
+                }
+                if (numvalue < min) {
+                    error_report("hv-spinlocks value shall always be >= 0x%x"
+                                 ", fixup will be removed in future versions",
+                                 min);
+                    numvalue = min;
+                }
+                snprintf(num, sizeof(num), "%" PRId32, numvalue);
+                object_property_parse(OBJECT(cpu), num, featurestr, &local_err);
+            } else {
+                object_property_parse(OBJECT(cpu), val, featurestr, &local_err);
+            }
         } else {
-            val = "on";
+            feat2prop(featurestr);
+            object_property_parse(OBJECT(cpu), "on", featurestr, &local_err);
         }
-
-        feat2prop(featurestr);
-        name = featurestr;
-
-        /* Special case: */
-        if (!strcmp(name, "tsc-freq")) {
-            int64_t tsc_freq;
-            char *err;
-
-            tsc_freq = qemu_strtosz_suffix_unit(val, &err,
-                                           QEMU_STRTOSZ_DEFSUFFIX_B, 1000);
-            if (tsc_freq < 0 || *err) {
-                error_setg(errp, "bad numerical value %s", val);
-                return;
-            }
-            snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
-            val = num;
-            name = "tsc-frequency";
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
         }
+        featurestr = strtok(NULL, ",");
+    }
 
-        prop = g_new0(typeof(*prop), 1);
-        prop->driver = typename;
-        prop->property = g_strdup(name);
-        prop->value = g_strdup(val);
-        prop->errp = &error_fatal;
-        qdev_prop_register_global(prop);
+    if (cpu->host_features) {
+        for (w = 0; w < FEATURE_WORDS; w++) {
+            env->features[w] =
+                x86_cpu_get_supported_feature_word(w, cpu->migratable);
+        }
     }
 
-    if (local_err) {
-        error_propagate(errp, local_err);
+    for (w = 0; w < FEATURE_WORDS; w++) {
+        env->features[w] |= plus_features[w];
+        env->features[w] &= ~minus_features[w];
     }
 }
 
@@ -2233,9 +2161,75 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
 
 }
 
+X86CPU *cpu_x86_create(const char *cpu_model, Error **errp)
+{
+    X86CPU *cpu = NULL;
+    X86CPUClass *xcc;
+    ObjectClass *oc;
+    gchar **model_pieces;
+    char *name, *features;
+    Error *error = NULL;
+
+    model_pieces = g_strsplit(cpu_model, ",", 2);
+    if (!model_pieces[0]) {
+        error_setg(&error, "Invalid/empty CPU model name");
+        goto out;
+    }
+    name = model_pieces[0];
+    features = model_pieces[1];
+
+    oc = x86_cpu_class_by_name(name);
+    if (oc == NULL) {
+        error_setg(&error, "Unable to find CPU definition: %s", name);
+        goto out;
+    }
+    xcc = X86_CPU_CLASS(oc);
+
+    if (xcc->kvm_required && !kvm_enabled()) {
+        error_setg(&error, "CPU model '%s' requires KVM", name);
+        goto out;
+    }
+
+    cpu = X86_CPU(object_new(object_class_get_name(oc)));
+
+    x86_cpu_parse_featurestr(CPU(cpu), features, &error);
+    if (error) {
+        goto out;
+    }
+
+out:
+    if (error != NULL) {
+        error_propagate(errp, error);
+        if (cpu) {
+            object_unref(OBJECT(cpu));
+            cpu = NULL;
+        }
+    }
+    g_strfreev(model_pieces);
+    return cpu;
+}
+
 X86CPU *cpu_x86_init(const char *cpu_model)
 {
-    return X86_CPU(cpu_generic_init(TYPE_X86_CPU, cpu_model));
+    Error *error = NULL;
+    X86CPU *cpu;
+
+    cpu = cpu_x86_create(cpu_model, &error);
+    if (error) {
+        goto out;
+    }
+
+    object_property_set_bool(OBJECT(cpu), true, "realized", &error);
+
+out:
+    if (error) {
+        error_report_err(error);
+        if (cpu != NULL) {
+            object_unref(OBJECT(cpu));
+            cpu = NULL;
+        }
+    }
+    return cpu;
 }
 
 static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
@@ -2269,6 +2263,30 @@ void cpu_clear_apic_feature(CPUX86State *env)
 
 #endif /* !CONFIG_USER_ONLY */
 
+/* Initialize list of CPU models, filling some non-static fields if necessary
+ */
+void x86_cpudef_setup(void)
+{
+    int i, j;
+    static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
+
+    for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
+        X86CPUDefinition *def = &builtin_x86_defs[i];
+
+        /* Look for specific "cpudef" models that */
+        /* have the QEMU version in .model_id */
+        for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
+            if (strcmp(model_with_versions[j], def->name) == 0) {
+                pstrcpy(def->model_id, sizeof(def->model_id),
+                        "QEMU Virtual CPU version ");
+                pstrcat(def->model_id, sizeof(def->model_id),
+                        qemu_hw_version());
+                break;
+            }
+        }
+    }
+}
+
 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
                    uint32_t *eax, uint32_t *ebx,
                    uint32_t *ecx, uint32_t *edx)
@@ -2442,36 +2460,6 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
             *edx = 0;
         }
         break;
-    case 0xB:
-        /* Extended Topology Enumeration Leaf */
-        if (!cpu->enable_cpuid_0xb) {
-                *eax = *ebx = *ecx = *edx = 0;
-                break;
-        }
-
-        *ecx = count & 0xff;
-        *edx = cpu->apic_id;
-
-        switch (count) {
-        case 0:
-            *eax = apicid_core_offset(smp_cores, smp_threads);
-            *ebx = smp_threads;
-            *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
-            break;
-        case 1:
-            *eax = apicid_pkg_offset(smp_cores, smp_threads);
-            *ebx = smp_cores * smp_threads;
-            *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
-            break;
-        default:
-            *eax = 0;
-            *ebx = 0;
-            *ecx |= CPUID_TOPOLOGY_LEVEL_INVALID;
-        }
-
-        assert(!(*eax & ~0x1f));
-        *ebx &= 0xffff; /* The count doesn't need to be reliable. */
-        break;
     case 0xD: {
         KVMState *s = cs->kvm_state;
         uint64_t ena_mask;
@@ -2597,13 +2585,17 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         break;
     case 0x80000008:
         /* virtual & phys address size in low 2 bytes. */
+/* XXX: This value must match the one used in the MMU code. */
         if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
-            /* 64 bit processor, 48 bits virtual, configurable
-             * physical bits.
-             */
-            *eax = 0x00003000 + cpu->phys_bits;
+            /* 64 bit processor */
+/* XXX: The physical address space is limited to 42 bits in exec.c. */
+            *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
         } else {
-            *eax = cpu->phys_bits;
+            if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
+                *eax = 0x00000024; /* 36 bits physical */
+            } else {
+                *eax = 0x00000020; /* 32 bits physical */
+            }
         }
         *ebx = 0;
         *ecx = 0;
@@ -2677,6 +2669,9 @@ static void x86_cpu_reset(CPUState *s)
 
     /* init to reset state */
 
+#ifdef CONFIG_SOFTMMU
+    env->hflags |= HF_SOFTMMU_MASK;
+#endif
     env->hflags2 |= HF2_GIF_MASK;
 
     cpu_x86_update_cr0(env, 0x60000010);
@@ -2803,8 +2798,7 @@ static void mce_init(X86CPU *cpu)
     if (((cenv->cpuid_version >> 8) & 0xf) >= 6
         && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
             (CPUID_MCE | CPUID_MCA)) {
-        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF |
-                        (cpu->enable_lmce ? MCG_LMCE_P : 0);
+        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
         cenv->mcg_ctl = ~(uint64_t)0;
         for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
             cenv->mce_banks[bank * 4] = ~(uint64_t)0;
@@ -2826,10 +2820,8 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
 
     cpu->apic_state = DEVICE(object_new(apic_type));
 
-    object_property_add_child(OBJECT(cpu), "lapic",
-                              OBJECT(cpu->apic_state), &error_abort);
-    object_unref(OBJECT(cpu->apic_state));
-
+    object_property_add_child(OBJECT(cpu), "apic",
+                              OBJECT(cpu->apic_state), NULL);
     qdev_prop_set_uint8(cpu->apic_state, "id", cpu->apic_id);
     /* TODO: convert to link<> */
     apic = APIC_COMMON(cpu->apic_state);
@@ -2880,31 +2872,6 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
 }
 #endif
 
-/* Note: Only safe for use on x86(-64) hosts */
-static uint32_t x86_host_phys_bits(void)
-{
-    uint32_t eax;
-    uint32_t host_phys_bits;
-
-    host_cpuid(0x80000000, 0, &eax, NULL, NULL, NULL);
-    if (eax >= 0x80000008) {
-        host_cpuid(0x80000008, 0, &eax, NULL, NULL, NULL);
-        /* Note: According to AMD doc 25481 rev 2.34 they have a field
-         * at 23:16 that can specify a maximum physical address bits for
-         * the guest that can override this value; but I've not seen
-         * anything with that set.
-         */
-        host_phys_bits = eax & 0xff;
-    } else {
-        /* It's an odd 64 bit machine that doesn't have the leaf for
-         * physical address bits; fall back to 36 that's most older
-         * Intel.
-         */
-        host_phys_bits = 36;
-    }
-
-    return host_phys_bits;
-}
 
 #define IS_INTEL_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_INTEL_1 && \
                            (env)->cpuid_vendor2 == CPUID_VENDOR_INTEL_2 && \
@@ -2920,37 +2887,12 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
     CPUX86State *env = &cpu->env;
     Error *local_err = NULL;
     static bool ht_warned;
-    FeatureWord w;
-
-    if (xcc->kvm_required && !kvm_enabled()) {
-        char *name = x86_cpu_class_get_model_name(xcc);
-        error_setg(&local_err, "CPU model '%s' requires KVM", name);
-        g_free(name);
-        goto out;
-    }
 
-    if (cpu->apic_id == UNASSIGNED_APIC_ID) {
+    if (cpu->apic_id < 0) {
         error_setg(errp, "apic-id property was not initialized properly");
         return;
     }
 
-    /*TODO: cpu->host_features incorrectly overwrites features
-     * set using "feat=on|off". Once we fix this, we can convert
-     * plus_features & minus_features to global properties
-     * inside x86_cpu_parse_featurestr() too.
-     */
-    if (cpu->host_features) {
-        for (w = 0; w < FEATURE_WORDS; w++) {
-            env->features[w] =
-                x86_cpu_get_supported_feature_word(w, cpu->migratable);
-        }
-    }
-
-    for (w = 0; w < FEATURE_WORDS; w++) {
-        cpu->env.features[w] |= plus_features[w];
-        cpu->env.features[w] &= ~minus_features[w];
-    }
-
     if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
         env->cpuid_level = 7;
     }
@@ -2972,75 +2914,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
            & CPUID_EXT2_AMD_ALIASES);
     }
 
-    /* For 64bit systems think about the number of physical bits to present.
-     * ideally this should be the same as the host; anything other than matching
-     * the host can cause incorrect guest behaviour.
-     * QEMU used to pick the magic value of 40 bits that corresponds to
-     * consumer AMD devices but nothing else.
-     */
-    if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
-        if (kvm_enabled()) {
-            uint32_t host_phys_bits = x86_host_phys_bits();
-            static bool warned;
-
-            if (cpu->host_phys_bits) {
-                /* The user asked for us to use the host physical bits */
-                cpu->phys_bits = host_phys_bits;
-            }
-
-            /* Print a warning if the user set it to a value that's not the
-             * host value.
-             */
-            if (cpu->phys_bits != host_phys_bits && cpu->phys_bits != 0 &&
-                !warned) {
-                error_report("Warning: Host physical bits (%u)"
-                                 " does not match phys-bits property (%u)",
-                                 host_phys_bits, cpu->phys_bits);
-                warned = true;
-            }
-
-            if (cpu->phys_bits &&
-                (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||
-                cpu->phys_bits < 32)) {
-                error_setg(errp, "phys-bits should be between 32 and %u "
-                                 " (but is %u)",
-                                 TARGET_PHYS_ADDR_SPACE_BITS, cpu->phys_bits);
-                return;
-            }
-        } else {
-            if (cpu->phys_bits && cpu->phys_bits != TCG_PHYS_ADDR_BITS) {
-                error_setg(errp, "TCG only supports phys-bits=%u",
-                                  TCG_PHYS_ADDR_BITS);
-                return;
-            }
-        }
-        /* 0 means it was not explicitly set by the user (or by machine
-         * compat_props or by the host code above). In this case, the default
-         * is the value used by TCG (40).
-         */
-        if (cpu->phys_bits == 0) {
-            cpu->phys_bits = TCG_PHYS_ADDR_BITS;
-        }
-    } else {
-        /* For 32 bit systems don't use the user set value, but keep
-         * phys_bits consistent with what we tell the guest.
-         */
-        if (cpu->phys_bits != 0) {
-            error_setg(errp, "phys-bits is not user-configurable in 32 bit");
-            return;
-        }
-
-        if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
-            cpu->phys_bits = 36;
-        } else {
-            cpu->phys_bits = 32;
-        }
-    }
-    cpu_exec_init(cs, &error_abort);
-
-    if (tcg_enabled()) {
-        tcg_x86_init();
-    }
 
 #ifndef CONFIG_USER_ONLY
     qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
@@ -3114,21 +2987,6 @@ out:
     }
 }
 
-static void x86_cpu_unrealizefn(DeviceState *dev, Error **errp)
-{
-    X86CPU *cpu = X86_CPU(dev);
-
-#ifndef CONFIG_USER_ONLY
-    cpu_remove_sync(CPU(dev));
-    qemu_unregister_reset(x86_cpu_machine_reset_cb, dev);
-#endif
-
-    if (cpu->apic_state) {
-        object_unparent(OBJECT(cpu->apic_state));
-        cpu->apic_state = NULL;
-    }
-}
-
 typedef struct BitProperty {
     uint32_t *ptr;
     uint32_t mask;
@@ -3243,8 +3101,10 @@ static void x86_cpu_initfn(Object *obj)
     X86CPUClass *xcc = X86_CPU_GET_CLASS(obj);
     CPUX86State *env = &cpu->env;
     FeatureWord w;
+    static int inited;
 
     cs->env_ptr = env;
+    cpu_exec_init(cs, &error_abort);
 
     object_property_add(obj, "family", "int",
                         x86_cpuid_version_get_family,
@@ -3264,6 +3124,9 @@ static void x86_cpu_initfn(Object *obj)
     object_property_add(obj, "tsc-frequency", "int",
                         x86_cpuid_get_tsc_freq,
                         x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
+    object_property_add(obj, "apic-id", "int",
+                        x86_cpuid_get_apic_id,
+                        x86_cpuid_set_apic_id, NULL, NULL, NULL);
     object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
                         x86_cpu_get_feature_words,
                         NULL, NULL, (void *)env->features, NULL);
@@ -3273,6 +3136,11 @@ static void x86_cpu_initfn(Object *obj)
 
     cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
 
+#ifndef CONFIG_USER_ONLY
+    /* Any code creating new X86CPU objects have to set apic-id explicitly */
+    cpu->apic_id = -1;
+#endif
+
     for (w = 0; w < FEATURE_WORDS; w++) {
         int bitnr;
 
@@ -3282,6 +3150,12 @@ static void x86_cpu_initfn(Object *obj)
     }
 
     x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort);
+
+    /* init various static tables used in TCG mode */
+    if (tcg_enabled() && !inited) {
+        inited = 1;
+        tcg_x86_init();
+    }
 }
 
 static int64_t x86_cpu_get_arch_id(CPUState *cs)
@@ -3329,18 +3203,6 @@ static bool x86_cpu_has_work(CPUState *cs)
 }
 
 static Property x86_cpu_properties[] = {
-#ifdef CONFIG_USER_ONLY
-    /* apic_id = 0 by default for *-user, see commit 9886e834 */
-    DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, 0),
-    DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, 0),
-    DEFINE_PROP_INT32("core-id", X86CPU, core_id, 0),
-    DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, 0),
-#else
-    DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, UNASSIGNED_APIC_ID),
-    DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, -1),
-    DEFINE_PROP_INT32("core-id", X86CPU, core_id, -1),
-    DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, -1),
-#endif
     DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
     { .name  = "hv-spinlocks", .info  = &qdev_prop_spinlocks },
     DEFINE_PROP_BOOL("hv-relaxed", X86CPU, hyperv_relaxed_timing, false),
@@ -3355,15 +3217,10 @@ static Property x86_cpu_properties[] = {
     DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
     DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
     DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
-    DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0),
-    DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false),
-    DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, true),
     DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, 0),
     DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, 0),
     DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0),
     DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id),
-    DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
-    DEFINE_PROP_BOOL("lmce", X86CPU, enable_lmce, false),
     DEFINE_PROP_END_OF_LIST()
 };
 
@@ -3375,7 +3232,6 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
 
     xcc->parent_realize = dc->realize;
     dc->realize = x86_cpu_realizefn;
-    dc->unrealize = x86_cpu_unrealizefn;
     dc->props = x86_cpu_properties;
 
     xcc->parent_reset = cc->reset;
@@ -3412,7 +3268,6 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->cpu_exec_enter = x86_cpu_exec_enter;
     cc->cpu_exec_exit = x86_cpu_exec_exit;
 
-    dc->cannot_instantiate_with_device_add_yet = false;
     /*
      * Reason: x86_cpu_initfn() calls cpu_exec_init(), which saves the
      * object in cpus -> dangling pointer after final object_unref().
index 65615c0..ea86758 100644 (file)
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-
-#ifndef I386_CPU_H
-#define I386_CPU_H
+#ifndef CPU_I386_H
+#define CPU_I386_H
 
 #include "qemu-common.h"
-#include "cpu-qom.h"
 #include "standard-headers/asm-x86/hyperv.h"
 
 #ifdef TARGET_X86_64
    positions to ease oring with eflags. */
 /* current cpl */
 #define HF_CPL_SHIFT         0
+/* true if soft mmu is being used */
+#define HF_SOFTMMU_SHIFT     2
 /* true if hardware interrupts must be disabled for next instruction */
 #define HF_INHIBIT_IRQ_SHIFT 3
 /* 16 or 32 segments */
 #define HF_MPX_IU_SHIFT     26 /* BND registers in-use */
 
 #define HF_CPL_MASK          (3 << HF_CPL_SHIFT)
+#define HF_SOFTMMU_MASK      (1 << HF_SOFTMMU_SHIFT)
 #define HF_INHIBIT_IRQ_MASK  (1 << HF_INHIBIT_IRQ_SHIFT)
 #define HF_CS32_MASK         (1 << HF_CS32_SHIFT)
 #define HF_SS32_MASK         (1 << HF_SS32_SHIFT)
 
 #define MCG_CTL_P       (1ULL<<8)   /* MCG_CAP register available */
 #define MCG_SER_P       (1ULL<<24) /* MCA recovery/new status bits */
-#define MCG_LMCE_P      (1ULL<<27) /* Local Machine Check Supported */
 
 #define MCE_CAP_DEF     (MCG_CTL_P|MCG_SER_P)
 #define MCE_BANKS_DEF   10
 #define MCG_STATUS_RIPV (1ULL<<0)   /* restart ip valid */
 #define MCG_STATUS_EIPV (1ULL<<1)   /* ip points to correct instruction */
 #define MCG_STATUS_MCIP (1ULL<<2)   /* machine check in progress */
-#define MCG_STATUS_LMCE (1ULL<<3)   /* Local MCE signaled */
-
-#define MCG_EXT_CTL_LMCE_EN (1ULL<<0) /* Local MCE enabled */
 
 #define MCI_STATUS_VAL   (1ULL<<63)  /* valid error */
 #define MCI_STATUS_OVER  (1ULL<<62)  /* previous errors lost */
 #define MSR_TSC_ADJUST                  0x0000003b
 #define MSR_IA32_TSCDEADLINE            0x6e0
 
-#define FEATURE_CONTROL_LOCKED                    (1<<0)
-#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2)
-#define FEATURE_CONTROL_LMCE                      (1<<20)
-
 #define MSR_P6_PERFCTR0                 0xc1
 
 #define MSR_IA32_SMBASE                 0x9e
 #define MSR_MCG_CAP                     0x179
 #define MSR_MCG_STATUS                  0x17a
 #define MSR_MCG_CTL                     0x17b
-#define MSR_MCG_EXT_CTL                 0x4d0
 
 #define MSR_P6_EVNTSEL0                 0x186
 
@@ -447,9 +439,6 @@ typedef enum FeatureWord {
     FEAT_8000_0007_EDX, /* CPUID[8000_0007].EDX */
     FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */
     FEAT_KVM,           /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */
-    FEAT_HYPERV_EAX,    /* CPUID[4000_0003].EAX */
-    FEAT_HYPERV_EBX,    /* CPUID[4000_0003].EBX */
-    FEAT_HYPERV_EDX,    /* CPUID[4000_0003].EDX */
     FEAT_SVM,           /* CPUID[8000_000A].EDX */
     FEAT_XSAVE,         /* CPUID[EAX=0xd,ECX=1].EAX */
     FEAT_6_EAX,         /* CPUID[6].EAX */
@@ -616,10 +605,8 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_7_0_EBX_AVX512ER (1U << 27) /* AVX-512 Exponential and Reciprocal */
 #define CPUID_7_0_EBX_AVX512CD (1U << 28) /* AVX-512 Conflict Detection */
 
-#define CPUID_7_0_ECX_UMIP     (1U << 2)
 #define CPUID_7_0_ECX_PKU      (1U << 3)
 #define CPUID_7_0_ECX_OSPKE    (1U << 4)
-#define CPUID_7_0_ECX_RDPID    (1U << 22)
 
 #define CPUID_XSAVE_XSAVEOPT   (1U << 0)
 #define CPUID_XSAVE_XSAVEC     (1U << 1)
@@ -648,11 +635,6 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_MWAIT_IBE     (1U << 1) /* Interrupts can exit capability */
 #define CPUID_MWAIT_EMX     (1U << 0) /* enumeration supported */
 
-/* CPUID[0xB].ECX level types */
-#define CPUID_TOPOLOGY_LEVEL_INVALID  (0U << 8)
-#define CPUID_TOPOLOGY_LEVEL_SMT      (1U << 8)
-#define CPUID_TOPOLOGY_LEVEL_CORE     (2U << 8)
-
 #ifndef HYPERV_SPINLOCK_NEVER_RETRY
 #define HYPERV_SPINLOCK_NEVER_RETRY             0xFFFFFFFF
 #endif
@@ -847,106 +829,6 @@ typedef struct {
 
 #define NB_OPMASK_REGS 8
 
-/* CPU can't have 0xFFFFFFFF APIC ID, use that value to distinguish
- * that APIC ID hasn't been set yet
- */
-#define UNASSIGNED_APIC_ID 0xFFFFFFFF
-
-typedef union X86LegacyXSaveArea {
-    struct {
-        uint16_t fcw;
-        uint16_t fsw;
-        uint8_t ftw;
-        uint8_t reserved;
-        uint16_t fpop;
-        uint64_t fpip;
-        uint64_t fpdp;
-        uint32_t mxcsr;
-        uint32_t mxcsr_mask;
-        FPReg fpregs[8];
-        uint8_t xmm_regs[16][16];
-    };
-    uint8_t data[512];
-} X86LegacyXSaveArea;
-
-typedef struct X86XSaveHeader {
-    uint64_t xstate_bv;
-    uint64_t xcomp_bv;
-    uint8_t reserved[48];
-} X86XSaveHeader;
-
-/* Ext. save area 2: AVX State */
-typedef struct XSaveAVX {
-    uint8_t ymmh[16][16];
-} XSaveAVX;
-
-/* Ext. save area 3: BNDREG */
-typedef struct XSaveBNDREG {
-    BNDReg bnd_regs[4];
-} XSaveBNDREG;
-
-/* Ext. save area 4: BNDCSR */
-typedef union XSaveBNDCSR {
-    BNDCSReg bndcsr;
-    uint8_t data[64];
-} XSaveBNDCSR;
-
-/* Ext. save area 5: Opmask */
-typedef struct XSaveOpmask {
-    uint64_t opmask_regs[NB_OPMASK_REGS];
-} XSaveOpmask;
-
-/* Ext. save area 6: ZMM_Hi256 */
-typedef struct XSaveZMM_Hi256 {
-    uint8_t zmm_hi256[16][32];
-} XSaveZMM_Hi256;
-
-/* Ext. save area 7: Hi16_ZMM */
-typedef struct XSaveHi16_ZMM {
-    uint8_t hi16_zmm[16][64];
-} XSaveHi16_ZMM;
-
-/* Ext. save area 9: PKRU state */
-typedef struct XSavePKRU {
-    uint32_t pkru;
-    uint32_t padding;
-} XSavePKRU;
-
-typedef struct X86XSaveArea {
-    X86LegacyXSaveArea legacy;
-    X86XSaveHeader header;
-
-    /* Extended save areas: */
-
-    /* AVX State: */
-    XSaveAVX avx_state;
-    uint8_t padding[960 - 576 - sizeof(XSaveAVX)];
-    /* MPX State: */
-    XSaveBNDREG bndreg_state;
-    XSaveBNDCSR bndcsr_state;
-    /* AVX-512 State: */
-    XSaveOpmask opmask_state;
-    XSaveZMM_Hi256 zmm_hi256_state;
-    XSaveHi16_ZMM hi16_zmm_state;
-    /* PKRU State: */
-    XSavePKRU pkru_state;
-} X86XSaveArea;
-
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, avx_state) != 0x240);
-QEMU_BUILD_BUG_ON(sizeof(XSaveAVX) != 0x100);
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, bndreg_state) != 0x3c0);
-QEMU_BUILD_BUG_ON(sizeof(XSaveBNDREG) != 0x40);
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, bndcsr_state) != 0x400);
-QEMU_BUILD_BUG_ON(sizeof(XSaveBNDCSR) != 0x40);
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, opmask_state) != 0x440);
-QEMU_BUILD_BUG_ON(sizeof(XSaveOpmask) != 0x40);
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, zmm_hi256_state) != 0x480);
-QEMU_BUILD_BUG_ON(sizeof(XSaveZMM_Hi256) != 0x200);
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, hi16_zmm_state) != 0x680);
-QEMU_BUILD_BUG_ON(sizeof(XSaveHi16_ZMM) != 0x400);
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, pkru_state) != 0xA80);
-QEMU_BUILD_BUG_ON(sizeof(XSavePKRU) != 0x8);
-
 typedef enum TPRAccess {
     TPR_ACCESS_READ,
     TPR_ACCESS_WRITE,
@@ -1128,7 +1010,6 @@ typedef struct CPUX86State {
 
     uint64_t mcg_cap;
     uint64_t mcg_ctl;
-    uint64_t mcg_ext_ctl;
     uint64_t mce_banks[MCE_BANKS_DEF*4];
 
     uint64_t tsc_aux;
@@ -1147,131 +1028,13 @@ typedef struct CPUX86State {
     TPRAccess tpr_access_type;
 } CPUX86State;
 
-struct kvm_msrs;
-
-/**
- * X86CPU:
- * @env: #CPUX86State
- * @migratable: If set, only migratable flags will be accepted when "enforce"
- * mode is used, and only migratable flags will be included in the "host"
- * CPU model.
- *
- * An x86 CPU.
- */
-struct X86CPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPUX86State env;
-
-    bool hyperv_vapic;
-    bool hyperv_relaxed_timing;
-    int hyperv_spinlock_attempts;
-    char *hyperv_vendor_id;
-    bool hyperv_time;
-    bool hyperv_crash;
-    bool hyperv_reset;
-    bool hyperv_vpindex;
-    bool hyperv_runtime;
-    bool hyperv_synic;
-    bool hyperv_stimer;
-    bool check_cpuid;
-    bool enforce_cpuid;
-    bool expose_kvm;
-    bool migratable;
-    bool host_features;
-    uint32_t apic_id;
-
-    /* if true the CPUID code directly forward host cache leaves to the guest */
-    bool cache_info_passthrough;
-
-    /* Features that were filtered out because of missing host capabilities */
-    uint32_t filtered_features[FEATURE_WORDS];
-
-    /* Enable PMU CPUID bits. This can't be enabled by default yet because
-     * it doesn't have ABI stability guarantees, as it passes all PMU CPUID
-     * bits returned by GET_SUPPORTED_CPUID (that depend on host CPU and kernel
-     * capabilities) directly to the guest.
-     */
-    bool enable_pmu;
-
-    /* LMCE support can be enabled/disabled via cpu option 'lmce=on/off'. It is
-     * disabled by default to avoid breaking migration between QEMU with
-     * different LMCE configurations.
-     */
-    bool enable_lmce;
-
-    /* Compatibility bits for old machine types: */
-    bool enable_cpuid_0xb;
-
-    /* if true fill the top bits of the MTRR_PHYSMASKn variable range */
-    bool fill_mtrr_mask;
-
-    /* if true override the phys_bits value with a value read from the host */
-    bool host_phys_bits;
-
-    /* Number of physical address bits supported */
-    uint32_t phys_bits;
-
-    /* in order to simplify APIC support, we leave this pointer to the
-       user */
-    struct DeviceState *apic_state;
-    struct MemoryRegion *cpu_as_root, *cpu_as_mem, *smram;
-    Notifier machine_done;
-
-    struct kvm_msrs *kvm_msr_buf;
-
-    int32_t socket_id;
-    int32_t core_id;
-    int32_t thread_id;
-};
-
-static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
-{
-    return container_of(env, X86CPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(x86_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(X86CPU, env)
-
-#ifndef CONFIG_USER_ONLY
-extern struct VMStateDescription vmstate_x86_cpu;
-#endif
-
-/**
- * x86_cpu_do_interrupt:
- * @cpu: vCPU the interrupt is to be handled by.
- */
-void x86_cpu_do_interrupt(CPUState *cpu);
-bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
-
-int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
-                             int cpuid, void *opaque);
-int x86_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu,
-                             int cpuid, void *opaque);
-int x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
-                                 void *opaque);
-int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
-                                 void *opaque);
-
-void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
-                                Error **errp);
-
-void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-                        int flags);
-
-hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-
-int x86_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int x86_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-
-void x86_cpu_exec_enter(CPUState *cpu);
-void x86_cpu_exec_exit(CPUState *cpu);
+#include "cpu-qom.h"
 
 X86CPU *cpu_x86_init(const char *cpu_model);
+X86CPU *cpu_x86_create(const char *cpu_model, Error **errp);
+int cpu_x86_exec(CPUState *cpu);
 void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf);
+void x86_cpudef_setup(void);
 int cpu_x86_support_mca_broadcast(CPUX86State *env);
 
 int cpu_get_pic_interrupt(CPUX86State *s);
@@ -1439,17 +1202,17 @@ uint64_t cpu_get_tsc(CPUX86State *env);
 /* XXX: This value should match the one returned by CPUID
  * and in exec.c */
 # if defined(TARGET_X86_64)
-# define TCG_PHYS_ADDR_BITS 40
+# define PHYS_ADDR_MASK 0xffffffffffLL
 # else
-# define TCG_PHYS_ADDR_BITS 36
+# define PHYS_ADDR_MASK 0xfffffffffLL
 # endif
 
-#define PHYS_ADDR_MASK MAKE_64BIT_MASK(0, TCG_PHYS_ADDR_BITS)
-
 #define cpu_init(cpu_model) CPU(cpu_x86_init(cpu_model))
 
+#define cpu_exec cpu_x86_exec
 #define cpu_signal_handler cpu_x86_signal_handler
 #define cpu_list x86_cpu_list
+#define cpudef_setup x86_cpudef_setup
 
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _ksmap
@@ -1503,8 +1266,10 @@ void tcg_x86_init(void);
 #include "hw/i386/apic.h"
 #endif
 
+#include "exec/exec-all.h"
+
 static inline void cpu_get_tb_cpu_state(CPUX86State *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *cs_base = env->segs[R_CS].base;
     *pc = *cs_base + env->eip;
@@ -1594,11 +1359,7 @@ void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw);
 void do_smm_enter(X86CPU *cpu);
 void cpu_smm_update(X86CPU *cpu);
 
-/* apic.c */
 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access);
-void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
-                                   TPRAccess access);
-
 
 /* Change the value of a KVM-specific default
  *
@@ -1624,7 +1385,4 @@ void enable_compat_apic_id_mode(void);
 void x86_cpu_dump_local_apic_state(CPUState *cs, FILE *f,
                                    fprintf_function cpu_fprintf, int flags);
 
-/* cpu.c */
-bool cpu_is_bsp(X86CPU *cpu);
-
-#endif /* I386_CPU_H */
+#endif /* CPU_I386_H */
index f0dc499..ef37f42 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "qemu/log.h"
 #include "sysemu/sysemu.h"
 #include "exec/helper-proto.h"
index 929489b..fee5573 100644 (file)
@@ -22,7 +22,6 @@
 #include "cpu.h"
 #include "exec/helper-proto.h"
 #include "qemu/host-utils.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 #define FPU_RC_MASK         0xc00
@@ -298,12 +297,18 @@ int32_t helper_fistt_ST0(CPUX86State *env)
 
 int32_t helper_fisttl_ST0(CPUX86State *env)
 {
-    return floatx80_to_int32_round_to_zero(ST0, &env->fp_status);
+    int32_t val;
+
+    val = floatx80_to_int32_round_to_zero(ST0, &env->fp_status);
+    return val;
 }
 
 int64_t helper_fisttll_ST0(CPUX86State *env)
 {
-    return floatx80_to_int64_round_to_zero(ST0, &env->fp_status);
+    int64_t val;
+
+    val = floatx80_to_int64_round_to_zero(ST0, &env->fp_status);
+    return val;
 }
 
 void helper_fldt_ST0(CPUX86State *env, target_ulong ptr)
index c494535..4b50713 100644 (file)
@@ -19,7 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
 
 #ifdef TARGET_X86_64
index 1c250b8..bf3e762 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "sysemu/kvm.h"
 #include "kvm_i386.h"
 #ifndef CONFIG_USER_ONLY
@@ -701,8 +700,6 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
     env->error_code = (is_write << PG_ERROR_W_BIT);
     env->error_code |= PG_ERROR_U_MASK;
     cs->exception_index = EXCP0E_PAGE;
-    env->exception_is_int = 0;
-    env->exception_next_eip = -1;
     return 1;
 }
 
index 0c3b562..b26201f 100644 (file)
@@ -11,8 +11,8 @@
  *
  */
 
-#ifndef TARGET_I386_HYPERV_H
-#define TARGET_I386_HYPERV_H
+#ifndef HYPERV_I386_H
+#define HYPERV_I386_H
 
 #include "cpu.h"
 #include "sysemu/kvm.h"
index 9e873ac..cf5bbb0 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
 
index cdf1506..8df9c59 100644 (file)
@@ -11,7 +11,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "kvm_i386.h"
 
 bool kvm_allows_irq0_override(void)
index d1a25c5..799fdfa 100644 (file)
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 #include <sys/utsname.h>
 
 #include <linux/kvm.h>
 #include <linux/kvm_para.h>
 
 #include "qemu-common.h"
-#include "cpu.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm_int.h"
 #include "kvm_i386.h"
+#include "cpu.h"
 #include "hyperv.h"
 
 #include "exec/gdbstub.h"
@@ -35,8 +36,6 @@
 #include "hw/i386/apic.h"
 #include "hw/i386/apic_internal.h"
 #include "hw/i386/apic-msidef.h"
-#include "hw/i386/intel_iommu.h"
-#include "hw/i386/x86-iommu.h"
 
 #include "exec/ioport.h"
 #include "standard-headers/asm-x86/hyperv.h"
@@ -44,7 +43,6 @@
 #include "hw/pci/msi.h"
 #include "migration/migration.h"
 #include "exec/memattrs.h"
-#include "trace.h"
 
 //#define DEBUG_KVM
 
 #define MSR_KVM_WALL_CLOCK  0x11
 #define MSR_KVM_SYSTEM_TIME 0x12
 
-/* A 4096-byte buffer can hold the 8-byte kvm_msrs header, plus
- * 255 kvm_msr_entry structs */
-#define MSR_BUF_SIZE 4096
-
 #ifndef BUS_MCEERR_AR
 #define BUS_MCEERR_AR 4
 #endif
@@ -109,10 +103,6 @@ static int has_xsave;
 static int has_xcrs;
 static int has_pit_state2;
 
-static bool has_msr_mcg_ext_ctl;
-
-static struct kvm_cpuid2 *cpuid_cache;
-
 int kvm_has_pit_state2(void)
 {
     return has_pit_state2;
@@ -206,14 +196,9 @@ static struct kvm_cpuid2 *get_supported_cpuid(KVMState *s)
 {
     struct kvm_cpuid2 *cpuid;
     int max = 1;
-
-    if (cpuid_cache != NULL) {
-        return cpuid_cache;
-    }
     while ((cpuid = try_get_cpuid(s, max)) == NULL) {
         max *= 2;
     }
-    cpuid_cache = cpuid;
     return cpuid;
 }
 
@@ -329,15 +314,10 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
          */
         cpuid_1_edx = kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
         ret |= cpuid_1_edx & CPUID_EXT2_AMD_ALIASES;
-    } else if (function == KVM_CPUID_FEATURES && reg == R_EAX) {
-        /* kvm_pv_unhalt is reported by GET_SUPPORTED_CPUID, but it can't
-         * be enabled without the in-kernel irqchip
-         */
-        if (!kvm_irqchip_in_kernel()) {
-            ret &= ~(1U << KVM_FEATURE_PV_UNHALT);
-        }
     }
 
+    g_free(cpuid);
+
     /* fallback for older kernels */
     if ((function == KVM_CPUID_FEATURES) && !found) {
         ret = get_para_features(s);
@@ -394,12 +374,10 @@ static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap,
 
 static void kvm_mce_inject(X86CPU *cpu, hwaddr paddr, int code)
 {
-    CPUState *cs = CPU(cpu);
     CPUX86State *env = &cpu->env;
     uint64_t status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN |
                       MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S;
     uint64_t mcg_status = MCG_STATUS_MCIP;
-    int flags = 0;
 
     if (code == BUS_MCEERR_AR) {
         status |= MCI_STATUS_AR | 0x134;
@@ -408,19 +386,10 @@ static void kvm_mce_inject(X86CPU *cpu, hwaddr paddr, int code)
         status |= 0xc0;
         mcg_status |= MCG_STATUS_RIPV;
     }
-
-    flags = cpu_x86_support_mca_broadcast(env) ? MCE_INJECT_BROADCAST : 0;
-    /* We need to read back the value of MSR_EXT_MCG_CTL that was set by the
-     * guest kernel back into env->mcg_ext_ctl.
-     */
-    cpu_synchronize_state(cs);
-    if (env->mcg_ext_ctl & MCG_EXT_CTL_LMCE_EN) {
-        mcg_status |= MCG_STATUS_LMCE;
-        flags = 0;
-    }
-
     cpu_x86_inject_mce(NULL, cpu, 9, status, mcg_status, paddr,
-                       (MCM_ADDR_PHYS << 6) | 0xc, flags);
+                       (MCM_ADDR_PHYS << 6) | 0xc,
+                       cpu_x86_support_mca_broadcast(env) ?
+                       MCE_INJECT_BROADCAST : 0);
 }
 
 static void hardware_memory_error(void)
@@ -438,8 +407,7 @@ int kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
 
     if ((env->mcg_cap & MCG_SER_P) && addr
         && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
-        ram_addr = qemu_ram_addr_from_host(addr);
-        if (ram_addr == RAM_ADDR_INVALID ||
+        if (qemu_ram_addr_from_host(addr, &ram_addr) == NULL ||
             !kvm_physical_memory_addr_from_host(c->kvm_state, addr, &paddr)) {
             fprintf(stderr, "Hardware memory error for memory used by "
                     "QEMU itself instead of guest system!\n");
@@ -473,8 +441,7 @@ int kvm_arch_on_sigbus(int code, void *addr)
         hwaddr paddr;
 
         /* Hope we are lucky for AO MCE */
-        ram_addr = qemu_ram_addr_from_host(addr);
-        if (ram_addr == RAM_ADDR_INVALID ||
+        if (qemu_ram_addr_from_host(addr, &ram_addr) == NULL ||
             !kvm_physical_memory_addr_from_host(first_cpu->kvm_state,
                                                 addr, &paddr)) {
             fprintf(stderr, "Hardware memory error for memory used by "
@@ -589,9 +556,7 @@ static int kvm_arch_set_tsc_khz(CPUState *cs)
                        -ENOTSUP;
         if (cur_freq <= 0 || cur_freq != env->tsc_khz) {
             error_report("warning: TSC frequency mismatch between "
-                         "VM (%" PRId64 " kHz) and host (%d kHz), "
-                         "and TSC scaling unavailable",
-                         env->tsc_khz, cur_freq);
+                         "VM and host, and TSC scaling unavailable");
             return r;
         }
     }
@@ -599,64 +564,6 @@ static int kvm_arch_set_tsc_khz(CPUState *cs)
     return 0;
 }
 
-static int hyperv_handle_properties(CPUState *cs)
-{
-    X86CPU *cpu = X86_CPU(cs);
-    CPUX86State *env = &cpu->env;
-
-    if (cpu->hyperv_relaxed_timing) {
-        env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_HYPERCALL_AVAILABLE;
-    }
-    if (cpu->hyperv_vapic) {
-        env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_HYPERCALL_AVAILABLE;
-        env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_APIC_ACCESS_AVAILABLE;
-        has_msr_hv_vapic = true;
-    }
-    if (cpu->hyperv_time &&
-            kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV_TIME) > 0) {
-        env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_HYPERCALL_AVAILABLE;
-        env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_TIME_REF_COUNT_AVAILABLE;
-        env->features[FEAT_HYPERV_EAX] |= 0x200;
-        has_msr_hv_tsc = true;
-    }
-    if (cpu->hyperv_crash && has_msr_hv_crash) {
-        env->features[FEAT_HYPERV_EDX] |= HV_X64_GUEST_CRASH_MSR_AVAILABLE;
-    }
-    env->features[FEAT_HYPERV_EDX] |= HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE;
-    if (cpu->hyperv_reset && has_msr_hv_reset) {
-        env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_RESET_AVAILABLE;
-    }
-    if (cpu->hyperv_vpindex && has_msr_hv_vpindex) {
-        env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_VP_INDEX_AVAILABLE;
-    }
-    if (cpu->hyperv_runtime && has_msr_hv_runtime) {
-        env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_VP_RUNTIME_AVAILABLE;
-    }
-    if (cpu->hyperv_synic) {
-        int sint;
-
-        if (!has_msr_hv_synic ||
-            kvm_vcpu_enable_cap(cs, KVM_CAP_HYPERV_SYNIC, 0)) {
-            fprintf(stderr, "Hyper-V SynIC is not supported by kernel\n");
-            return -ENOSYS;
-        }
-
-        env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_SYNIC_AVAILABLE;
-        env->msr_hv_synic_version = HV_SYNIC_VERSION_1;
-        for (sint = 0; sint < ARRAY_SIZE(env->msr_hv_synic_sint); sint++) {
-            env->msr_hv_synic_sint[sint] = HV_SYNIC_SINT_MASKED;
-        }
-    }
-    if (cpu->hyperv_stimer) {
-        if (!has_msr_hv_stimer) {
-            fprintf(stderr, "Hyper-V timers aren't supported by kernel\n");
-            return -ENOSYS;
-        }
-        env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_SYNTIMER_AVAILABLE;
-    }
-    return 0;
-}
-
 static Error *invtsc_mig_blocker;
 
 #define KVM_MAX_CPUID_ENTRIES  100
@@ -716,14 +623,56 @@ int kvm_arch_init_vcpu(CPUState *cs)
 
         c = &cpuid_data.entries[cpuid_i++];
         c->function = HYPERV_CPUID_FEATURES;
-        r = hyperv_handle_properties(cs);
-        if (r) {
-            return r;
+        if (cpu->hyperv_relaxed_timing) {
+            c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE;
+        }
+        if (cpu->hyperv_vapic) {
+            c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE;
+            c->eax |= HV_X64_MSR_APIC_ACCESS_AVAILABLE;
+            has_msr_hv_vapic = true;
+        }
+        if (cpu->hyperv_time &&
+            kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV_TIME) > 0) {
+            c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE;
+            c->eax |= HV_X64_MSR_TIME_REF_COUNT_AVAILABLE;
+            c->eax |= 0x200;
+            has_msr_hv_tsc = true;
+        }
+        if (cpu->hyperv_crash && has_msr_hv_crash) {
+            c->edx |= HV_X64_GUEST_CRASH_MSR_AVAILABLE;
         }
-        c->eax = env->features[FEAT_HYPERV_EAX];
-        c->ebx = env->features[FEAT_HYPERV_EBX];
-        c->edx = env->features[FEAT_HYPERV_EDX];
+        c->edx |= HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE;
+        if (cpu->hyperv_reset && has_msr_hv_reset) {
+            c->eax |= HV_X64_MSR_RESET_AVAILABLE;
+        }
+        if (cpu->hyperv_vpindex && has_msr_hv_vpindex) {
+            c->eax |= HV_X64_MSR_VP_INDEX_AVAILABLE;
+        }
+        if (cpu->hyperv_runtime && has_msr_hv_runtime) {
+            c->eax |= HV_X64_MSR_VP_RUNTIME_AVAILABLE;
+        }
+        if (cpu->hyperv_synic) {
+            int sint;
 
+            if (!has_msr_hv_synic ||
+                kvm_vcpu_enable_cap(cs, KVM_CAP_HYPERV_SYNIC, 0)) {
+                fprintf(stderr, "Hyper-V SynIC is not supported by kernel\n");
+                return -ENOSYS;
+            }
+
+            c->eax |= HV_X64_MSR_SYNIC_AVAILABLE;
+            env->msr_hv_synic_version = HV_SYNIC_VERSION_1;
+            for (sint = 0; sint < ARRAY_SIZE(env->msr_hv_synic_sint); sint++) {
+                env->msr_hv_synic_sint[sint] = HV_SYNIC_SINT_MASKED;
+            }
+        }
+        if (cpu->hyperv_stimer) {
+            if (!has_msr_hv_stimer) {
+                fprintf(stderr, "Hyper-V timers aren't supported by kernel\n");
+                return -ENOSYS;
+            }
+            c->eax |= HV_X64_MSR_SYNTIMER_AVAILABLE;
+        }
         c = &cpuid_data.entries[cpuid_i++];
         c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
         if (cpu->hyperv_relaxed_timing) {
@@ -906,10 +855,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
 
         unsupported_caps = env->mcg_cap & ~(mcg_cap | MCG_CAP_BANKS_MASK);
         if (unsupported_caps) {
-            if (unsupported_caps & MCG_LMCE_P) {
-                error_report("kvm: LMCE not supported");
-                return -ENOTSUP;
-            }
             error_report("warning: Unsupported MCG_CAP bits: 0x%" PRIx64,
                          unsupported_caps);
         }
@@ -930,10 +875,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
                                   !!(c->ecx & CPUID_EXT_SMX);
     }
 
-    if (env->mcg_cap & MCG_LMCE_P) {
-        has_msr_mcg_ext_ctl = has_msr_feature_control = true;
-    }
-
     c = cpuid_find_entry(&cpuid_data.cpuid, 0x80000007, 0);
     if (c && (c->edx & 1<<8) && invtsc_mig_blocker == NULL) {
         /* for migration */
@@ -973,7 +914,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
     if (has_xsave) {
         env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave));
     }
-    cpu->kvm_msr_buf = g_malloc0(MSR_BUF_SIZE);
 
     if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
         has_msr_mtrr = true;
@@ -1367,35 +1307,13 @@ static int kvm_put_fpu(X86CPU *cpu)
 #define XSAVE_Hi16_ZMM    416
 #define XSAVE_PKRU        672
 
-#define XSAVE_BYTE_OFFSET(word_offset) \
-    ((word_offset) * sizeof(((struct kvm_xsave *)0)->region[0]))
-
-#define ASSERT_OFFSET(word_offset, field) \
-    QEMU_BUILD_BUG_ON(XSAVE_BYTE_OFFSET(word_offset) != \
-                      offsetof(X86XSaveArea, field))
-
-ASSERT_OFFSET(XSAVE_FCW_FSW, legacy.fcw);
-ASSERT_OFFSET(XSAVE_FTW_FOP, legacy.ftw);
-ASSERT_OFFSET(XSAVE_CWD_RIP, legacy.fpip);
-ASSERT_OFFSET(XSAVE_CWD_RDP, legacy.fpdp);
-ASSERT_OFFSET(XSAVE_MXCSR, legacy.mxcsr);
-ASSERT_OFFSET(XSAVE_ST_SPACE, legacy.fpregs);
-ASSERT_OFFSET(XSAVE_XMM_SPACE, legacy.xmm_regs);
-ASSERT_OFFSET(XSAVE_XSTATE_BV, header.xstate_bv);
-ASSERT_OFFSET(XSAVE_YMMH_SPACE, avx_state);
-ASSERT_OFFSET(XSAVE_BNDREGS, bndreg_state);
-ASSERT_OFFSET(XSAVE_BNDCSR, bndcsr_state);
-ASSERT_OFFSET(XSAVE_OPMASK, opmask_state);
-ASSERT_OFFSET(XSAVE_ZMM_Hi256, zmm_hi256_state);
-ASSERT_OFFSET(XSAVE_Hi16_ZMM, hi16_zmm_state);
-ASSERT_OFFSET(XSAVE_PKRU, pkru_state);
-
 static int kvm_put_xsave(X86CPU *cpu)
 {
     CPUX86State *env = &cpu->env;
-    X86XSaveArea *xsave = env->kvm_xsave_buf;
+    struct kvm_xsave* xsave = env->kvm_xsave_buf;
     uint16_t cwd, swd, twd;
-    int i;
+    uint8_t *xmm, *ymmh, *zmmh;
+    int i, r;
 
     if (!has_xsave) {
         return kvm_put_fpu(cpu);
@@ -1409,26 +1327,25 @@ static int kvm_put_xsave(X86CPU *cpu)
     for (i = 0; i < 8; ++i) {
         twd |= (!env->fptags[i]) << i;
     }
-    xsave->legacy.fcw = cwd;
-    xsave->legacy.fsw = swd;
-    xsave->legacy.ftw = twd;
-    xsave->legacy.fpop = env->fpop;
-    xsave->legacy.fpip = env->fpip;
-    xsave->legacy.fpdp = env->fpdp;
-    memcpy(&xsave->legacy.fpregs, env->fpregs,
+    xsave->region[XSAVE_FCW_FSW] = (uint32_t)(swd << 16) + cwd;
+    xsave->region[XSAVE_FTW_FOP] = (uint32_t)(env->fpop << 16) + twd;
+    memcpy(&xsave->region[XSAVE_CWD_RIP], &env->fpip, sizeof(env->fpip));
+    memcpy(&xsave->region[XSAVE_CWD_RDP], &env->fpdp, sizeof(env->fpdp));
+    memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs,
             sizeof env->fpregs);
-    xsave->legacy.mxcsr = env->mxcsr;
-    xsave->header.xstate_bv = env->xstate_bv;
-    memcpy(&xsave->bndreg_state.bnd_regs, env->bnd_regs,
+    xsave->region[XSAVE_MXCSR] = env->mxcsr;
+    *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv;
+    memcpy(&xsave->region[XSAVE_BNDREGS], env->bnd_regs,
             sizeof env->bnd_regs);
-    xsave->bndcsr_state.bndcsr = env->bndcs_regs;
-    memcpy(&xsave->opmask_state.opmask_regs, env->opmask_regs,
+    memcpy(&xsave->region[XSAVE_BNDCSR], &env->bndcs_regs,
+            sizeof(env->bndcs_regs));
+    memcpy(&xsave->region[XSAVE_OPMASK], env->opmask_regs,
             sizeof env->opmask_regs);
 
-    for (i = 0; i < CPU_NB_REGS; i++) {
-        uint8_t *xmm = xsave->legacy.xmm_regs[i];
-        uint8_t *ymmh = xsave->avx_state.ymmh[i];
-        uint8_t *zmmh = xsave->zmm_hi256_state.zmm_hi256[i];
+    xmm = (uint8_t *)&xsave->region[XSAVE_XMM_SPACE];
+    ymmh = (uint8_t *)&xsave->region[XSAVE_YMMH_SPACE];
+    zmmh = (uint8_t *)&xsave->region[XSAVE_ZMM_Hi256];
+    for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) {
         stq_p(xmm,     env->xmm_regs[i].ZMM_Q(0));
         stq_p(xmm+8,   env->xmm_regs[i].ZMM_Q(1));
         stq_p(ymmh,    env->xmm_regs[i].ZMM_Q(2));
@@ -1440,11 +1357,12 @@ static int kvm_put_xsave(X86CPU *cpu)
     }
 
 #ifdef TARGET_X86_64
-    memcpy(&xsave->hi16_zmm_state.hi16_zmm, &env->xmm_regs[16],
+    memcpy(&xsave->region[XSAVE_Hi16_ZMM], &env->xmm_regs[16],
             16 * sizeof env->xmm_regs[16]);
-    memcpy(&xsave->pkru_state, &env->pkru, sizeof env->pkru);
+    memcpy(&xsave->region[XSAVE_PKRU], &env->pkru, sizeof env->pkru);
 #endif
-    return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave);
+    r = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave);
+    return r;
 }
 
 static int kvm_put_xcrs(X86CPU *cpu)
@@ -1513,38 +1431,35 @@ static int kvm_put_sregs(X86CPU *cpu)
     return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_SREGS, &sregs);
 }
 
-static void kvm_msr_buf_reset(X86CPU *cpu)
+static void kvm_msr_entry_set(struct kvm_msr_entry *entry,
+                              uint32_t index, uint64_t value)
 {
-    memset(cpu->kvm_msr_buf, 0, MSR_BUF_SIZE);
-}
-
-static void kvm_msr_entry_add(X86CPU *cpu, uint32_t index, uint64_t value)
-{
-    struct kvm_msrs *msrs = cpu->kvm_msr_buf;
-    void *limit = ((void *)msrs) + MSR_BUF_SIZE;
-    struct kvm_msr_entry *entry = &msrs->entries[msrs->nmsrs];
-
-    assert((void *)(entry + 1) <= limit);
-
     entry->index = index;
     entry->reserved = 0;
     entry->data = value;
-    msrs->nmsrs++;
 }
 
 static int kvm_put_tscdeadline_msr(X86CPU *cpu)
 {
     CPUX86State *env = &cpu->env;
+    struct {
+        struct kvm_msrs info;
+        struct kvm_msr_entry entries[1];
+    } msr_data;
+    struct kvm_msr_entry *msrs = msr_data.entries;
     int ret;
 
     if (!has_msr_tsc_deadline) {
         return 0;
     }
 
-    kvm_msr_buf_reset(cpu);
-    kvm_msr_entry_add(cpu, MSR_IA32_TSCDEADLINE, env->tsc_deadline);
+    kvm_msr_entry_set(&msrs[0], MSR_IA32_TSCDEADLINE, env->tsc_deadline);
 
-    ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, cpu->kvm_msr_buf);
+    msr_data.info = (struct kvm_msrs) {
+        .nmsrs = 1,
+    };
+
+    ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data);
     if (ret < 0) {
         return ret;
     }
@@ -1561,17 +1476,24 @@ static int kvm_put_tscdeadline_msr(X86CPU *cpu)
  */
 static int kvm_put_msr_feature_control(X86CPU *cpu)
 {
+    struct {
+        struct kvm_msrs info;
+        struct kvm_msr_entry entry;
+    } msr_data;
     int ret;
 
     if (!has_msr_feature_control) {
         return 0;
     }
 
-    kvm_msr_buf_reset(cpu);
-    kvm_msr_entry_add(cpu, MSR_IA32_FEATURE_CONTROL,
+    kvm_msr_entry_set(&msr_data.entry, MSR_IA32_FEATURE_CONTROL,
                       cpu->env.msr_ia32_feature_control);
 
-    ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, cpu->kvm_msr_buf);
+    msr_data.info = (struct kvm_msrs) {
+        .nmsrs = 1,
+    };
+
+    ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data);
     if (ret < 0) {
         return ret;
     }
@@ -1583,46 +1505,49 @@ static int kvm_put_msr_feature_control(X86CPU *cpu)
 static int kvm_put_msrs(X86CPU *cpu, int level)
 {
     CPUX86State *env = &cpu->env;
-    int i;
+    struct {
+        struct kvm_msrs info;
+        struct kvm_msr_entry entries[150];
+    } msr_data;
+    struct kvm_msr_entry *msrs = msr_data.entries;
+    int n = 0, i;
     int ret;
 
-    kvm_msr_buf_reset(cpu);
-
-    kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_CS, env->sysenter_cs);
-    kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
-    kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
-    kvm_msr_entry_add(cpu, MSR_PAT, env->pat);
+    kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs);
+    kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
+    kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
+    kvm_msr_entry_set(&msrs[n++], MSR_PAT, env->pat);
     if (has_msr_star) {
-        kvm_msr_entry_add(cpu, MSR_STAR, env->star);
+        kvm_msr_entry_set(&msrs[n++], MSR_STAR, env->star);
     }
     if (has_msr_hsave_pa) {
-        kvm_msr_entry_add(cpu, MSR_VM_HSAVE_PA, env->vm_hsave);
+        kvm_msr_entry_set(&msrs[n++], MSR_VM_HSAVE_PA, env->vm_hsave);
     }
     if (has_msr_tsc_aux) {
-        kvm_msr_entry_add(cpu, MSR_TSC_AUX, env->tsc_aux);
+        kvm_msr_entry_set(&msrs[n++], MSR_TSC_AUX, env->tsc_aux);
     }
     if (has_msr_tsc_adjust) {
-        kvm_msr_entry_add(cpu, MSR_TSC_ADJUST, env->tsc_adjust);
+        kvm_msr_entry_set(&msrs[n++], MSR_TSC_ADJUST, env->tsc_adjust);
     }
     if (has_msr_misc_enable) {
-        kvm_msr_entry_add(cpu, MSR_IA32_MISC_ENABLE,
+        kvm_msr_entry_set(&msrs[n++], MSR_IA32_MISC_ENABLE,
                           env->msr_ia32_misc_enable);
     }
     if (has_msr_smbase) {
-        kvm_msr_entry_add(cpu, MSR_IA32_SMBASE, env->smbase);
+        kvm_msr_entry_set(&msrs[n++], MSR_IA32_SMBASE, env->smbase);
     }
     if (has_msr_bndcfgs) {
-        kvm_msr_entry_add(cpu, MSR_IA32_BNDCFGS, env->msr_bndcfgs);
+        kvm_msr_entry_set(&msrs[n++], MSR_IA32_BNDCFGS, env->msr_bndcfgs);
     }
     if (has_msr_xss) {
-        kvm_msr_entry_add(cpu, MSR_IA32_XSS, env->xss);
+        kvm_msr_entry_set(&msrs[n++], MSR_IA32_XSS, env->xss);
     }
 #ifdef TARGET_X86_64
     if (lm_capable_kernel) {
-        kvm_msr_entry_add(cpu, MSR_CSTAR, env->cstar);
-        kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, env->kernelgsbase);
-        kvm_msr_entry_add(cpu, MSR_FMASK, env->fmask);
-        kvm_msr_entry_add(cpu, MSR_LSTAR, env->lstar);
+        kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
+        kvm_msr_entry_set(&msrs[n++], MSR_KERNELGSBASE, env->kernelgsbase);
+        kvm_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask);
+        kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar);
     }
 #endif
     /*
@@ -1630,85 +1555,91 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
      * for normal writeback. Limit them to reset or full state updates.
      */
     if (level >= KVM_PUT_RESET_STATE) {
-        kvm_msr_entry_add(cpu, MSR_IA32_TSC, env->tsc);
-        kvm_msr_entry_add(cpu, MSR_KVM_SYSTEM_TIME, env->system_time_msr);
-        kvm_msr_entry_add(cpu, MSR_KVM_WALL_CLOCK, env->wall_clock_msr);
+        kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc);
+        kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME,
+                          env->system_time_msr);
+        kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr);
         if (has_msr_async_pf_en) {
-            kvm_msr_entry_add(cpu, MSR_KVM_ASYNC_PF_EN, env->async_pf_en_msr);
+            kvm_msr_entry_set(&msrs[n++], MSR_KVM_ASYNC_PF_EN,
+                              env->async_pf_en_msr);
         }
         if (has_msr_pv_eoi_en) {
-            kvm_msr_entry_add(cpu, MSR_KVM_PV_EOI_EN, env->pv_eoi_en_msr);
+            kvm_msr_entry_set(&msrs[n++], MSR_KVM_PV_EOI_EN,
+                              env->pv_eoi_en_msr);
         }
         if (has_msr_kvm_steal_time) {
-            kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, env->steal_time_msr);
+            kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME,
+                              env->steal_time_msr);
         }
         if (has_msr_architectural_pmu) {
             /* Stop the counter.  */
-            kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
-            kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0);
+            kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
+            kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_CTRL, 0);
 
             /* Set the counter values.  */
             for (i = 0; i < MAX_FIXED_COUNTERS; i++) {
-                kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR0 + i,
+                kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_FIXED_CTR0 + i,
                                   env->msr_fixed_counters[i]);
             }
             for (i = 0; i < num_architectural_pmu_counters; i++) {
-                kvm_msr_entry_add(cpu, MSR_P6_PERFCTR0 + i,
+                kvm_msr_entry_set(&msrs[n++], MSR_P6_PERFCTR0 + i,
                                   env->msr_gp_counters[i]);
-                kvm_msr_entry_add(cpu, MSR_P6_EVNTSEL0 + i,
+                kvm_msr_entry_set(&msrs[n++], MSR_P6_EVNTSEL0 + i,
                                   env->msr_gp_evtsel[i]);
             }
-            kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS,
+            kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_STATUS,
                               env->msr_global_status);
-            kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL,
+            kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_OVF_CTRL,
                               env->msr_global_ovf_ctrl);
 
             /* Now start the PMU.  */
-            kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL,
+            kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_FIXED_CTR_CTRL,
                               env->msr_fixed_ctr_ctrl);
-            kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL,
+            kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_CTRL,
                               env->msr_global_ctrl);
         }
         if (has_msr_hv_hypercall) {
-            kvm_msr_entry_add(cpu, HV_X64_MSR_GUEST_OS_ID,
+            kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID,
                               env->msr_hv_guest_os_id);
-            kvm_msr_entry_add(cpu, HV_X64_MSR_HYPERCALL,
+            kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL,
                               env->msr_hv_hypercall);
         }
         if (has_msr_hv_vapic) {
-            kvm_msr_entry_add(cpu, HV_X64_MSR_APIC_ASSIST_PAGE,
+            kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_APIC_ASSIST_PAGE,
                               env->msr_hv_vapic);
         }
         if (has_msr_hv_tsc) {
-            kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC, env->msr_hv_tsc);
+            kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_REFERENCE_TSC,
+                              env->msr_hv_tsc);
         }
         if (has_msr_hv_crash) {
             int j;
 
             for (j = 0; j < HV_X64_MSR_CRASH_PARAMS; j++)
-                kvm_msr_entry_add(cpu, HV_X64_MSR_CRASH_P0 + j,
+                kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_CRASH_P0 + j,
                                   env->msr_hv_crash_params[j]);
 
-            kvm_msr_entry_add(cpu, HV_X64_MSR_CRASH_CTL,
+            kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_CRASH_CTL,
                               HV_X64_MSR_CRASH_CTL_NOTIFY);
         }
         if (has_msr_hv_runtime) {
-            kvm_msr_entry_add(cpu, HV_X64_MSR_VP_RUNTIME, env->msr_hv_runtime);
+            kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_VP_RUNTIME,
+                              env->msr_hv_runtime);
         }
         if (cpu->hyperv_synic) {
             int j;
 
-            kvm_msr_entry_add(cpu, HV_X64_MSR_SCONTROL,
+            kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SCONTROL,
                               env->msr_hv_synic_control);
-            kvm_msr_entry_add(cpu, HV_X64_MSR_SVERSION,
+            kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SVERSION,
                               env->msr_hv_synic_version);
-            kvm_msr_entry_add(cpu, HV_X64_MSR_SIEFP,
+            kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SIEFP,
                               env->msr_hv_synic_evt_page);
-            kvm_msr_entry_add(cpu, HV_X64_MSR_SIMP,
+            kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SIMP,
                               env->msr_hv_synic_msg_page);
 
             for (j = 0; j < ARRAY_SIZE(env->msr_hv_synic_sint); j++) {
-                kvm_msr_entry_add(cpu, HV_X64_MSR_SINT0 + j,
+                kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SINT0 + j,
                                   env->msr_hv_synic_sint[j]);
             }
         }
@@ -1716,40 +1647,44 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
             int j;
 
             for (j = 0; j < ARRAY_SIZE(env->msr_hv_stimer_config); j++) {
-                kvm_msr_entry_add(cpu, HV_X64_MSR_STIMER0_CONFIG + j * 2,
+                kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_STIMER0_CONFIG + j*2,
                                 env->msr_hv_stimer_config[j]);
             }
 
             for (j = 0; j < ARRAY_SIZE(env->msr_hv_stimer_count); j++) {
-                kvm_msr_entry_add(cpu, HV_X64_MSR_STIMER0_COUNT + j * 2,
+                kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_STIMER0_COUNT + j*2,
                                 env->msr_hv_stimer_count[j]);
             }
         }
         if (has_msr_mtrr) {
-            uint64_t phys_mask = MAKE_64BIT_MASK(0, cpu->phys_bits);
-
-            kvm_msr_entry_add(cpu, MSR_MTRRdefType, env->mtrr_deftype);
-            kvm_msr_entry_add(cpu, MSR_MTRRfix64K_00000, env->mtrr_fixed[0]);
-            kvm_msr_entry_add(cpu, MSR_MTRRfix16K_80000, env->mtrr_fixed[1]);
-            kvm_msr_entry_add(cpu, MSR_MTRRfix16K_A0000, env->mtrr_fixed[2]);
-            kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C0000, env->mtrr_fixed[3]);
-            kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C8000, env->mtrr_fixed[4]);
-            kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D0000, env->mtrr_fixed[5]);
-            kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D8000, env->mtrr_fixed[6]);
-            kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E0000, env->mtrr_fixed[7]);
-            kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E8000, env->mtrr_fixed[8]);
-            kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F0000, env->mtrr_fixed[9]);
-            kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F8000, env->mtrr_fixed[10]);
+            kvm_msr_entry_set(&msrs[n++], MSR_MTRRdefType, env->mtrr_deftype);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix64K_00000, env->mtrr_fixed[0]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix16K_80000, env->mtrr_fixed[1]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix16K_A0000, env->mtrr_fixed[2]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_C0000, env->mtrr_fixed[3]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_C8000, env->mtrr_fixed[4]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_D0000, env->mtrr_fixed[5]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_D8000, env->mtrr_fixed[6]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_E0000, env->mtrr_fixed[7]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_E8000, env->mtrr_fixed[8]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_F0000, env->mtrr_fixed[9]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_F8000, env->mtrr_fixed[10]);
             for (i = 0; i < MSR_MTRRcap_VCNT; i++) {
-                /* The CPU GPs if we write to a bit above the physical limit of
-                 * the host CPU (and KVM emulates that)
-                 */
-                uint64_t mask = env->mtrr_var[i].mask;
-                mask &= phys_mask;
-
-                kvm_msr_entry_add(cpu, MSR_MTRRphysBase(i),
-                                  env->mtrr_var[i].base);
-                kvm_msr_entry_add(cpu, MSR_MTRRphysMask(i), mask);
+                kvm_msr_entry_set(&msrs[n++],
+                                  MSR_MTRRphysBase(i), env->mtrr_var[i].base);
+                kvm_msr_entry_set(&msrs[n++],
+                                  MSR_MTRRphysMask(i), env->mtrr_var[i].mask);
             }
         }
 
@@ -1759,22 +1694,23 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
     if (env->mcg_cap) {
         int i;
 
-        kvm_msr_entry_add(cpu, MSR_MCG_STATUS, env->mcg_status);
-        kvm_msr_entry_add(cpu, MSR_MCG_CTL, env->mcg_ctl);
-        if (has_msr_mcg_ext_ctl) {
-            kvm_msr_entry_add(cpu, MSR_MCG_EXT_CTL, env->mcg_ext_ctl);
-        }
+        kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status);
+        kvm_msr_entry_set(&msrs[n++], MSR_MCG_CTL, env->mcg_ctl);
         for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++) {
-            kvm_msr_entry_add(cpu, MSR_MC0_CTL + i, env->mce_banks[i]);
+            kvm_msr_entry_set(&msrs[n++], MSR_MC0_CTL + i, env->mce_banks[i]);
         }
     }
 
-    ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, cpu->kvm_msr_buf);
+    msr_data.info = (struct kvm_msrs) {
+        .nmsrs = n,
+    };
+
+    ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data);
     if (ret < 0) {
         return ret;
     }
 
-    assert(ret == cpu->kvm_msr_buf->nmsrs);
+    assert(ret == n);
     return 0;
 }
 
@@ -1812,8 +1748,9 @@ static int kvm_get_fpu(X86CPU *cpu)
 static int kvm_get_xsave(X86CPU *cpu)
 {
     CPUX86State *env = &cpu->env;
-    X86XSaveArea *xsave = env->kvm_xsave_buf;
+    struct kvm_xsave* xsave = env->kvm_xsave_buf;
     int ret, i;
+    const uint8_t *xmm, *ymmh, *zmmh;
     uint16_t cwd, swd, twd;
 
     if (!has_xsave) {
@@ -1825,32 +1762,33 @@ static int kvm_get_xsave(X86CPU *cpu)
         return ret;
     }
 
-    cwd = xsave->legacy.fcw;
-    swd = xsave->legacy.fsw;
-    twd = xsave->legacy.ftw;
-    env->fpop = xsave->legacy.fpop;
+    cwd = (uint16_t)xsave->region[XSAVE_FCW_FSW];
+    swd = (uint16_t)(xsave->region[XSAVE_FCW_FSW] >> 16);
+    twd = (uint16_t)xsave->region[XSAVE_FTW_FOP];
+    env->fpop = (uint16_t)(xsave->region[XSAVE_FTW_FOP] >> 16);
     env->fpstt = (swd >> 11) & 7;
     env->fpus = swd;
     env->fpuc = cwd;
     for (i = 0; i < 8; ++i) {
         env->fptags[i] = !((twd >> i) & 1);
     }
-    env->fpip = xsave->legacy.fpip;
-    env->fpdp = xsave->legacy.fpdp;
-    env->mxcsr = xsave->legacy.mxcsr;
-    memcpy(env->fpregs, &xsave->legacy.fpregs,
+    memcpy(&env->fpip, &xsave->region[XSAVE_CWD_RIP], sizeof(env->fpip));
+    memcpy(&env->fpdp, &xsave->region[XSAVE_CWD_RDP], sizeof(env->fpdp));
+    env->mxcsr = xsave->region[XSAVE_MXCSR];
+    memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE],
             sizeof env->fpregs);
-    env->xstate_bv = xsave->header.xstate_bv;
-    memcpy(env->bnd_regs, &xsave->bndreg_state.bnd_regs,
+    env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV];
+    memcpy(env->bnd_regs, &xsave->region[XSAVE_BNDREGS],
             sizeof env->bnd_regs);
-    env->bndcs_regs = xsave->bndcsr_state.bndcsr;
-    memcpy(env->opmask_regs, &xsave->opmask_state.opmask_regs,
+    memcpy(&env->bndcs_regs, &xsave->region[XSAVE_BNDCSR],
+            sizeof(env->bndcs_regs));
+    memcpy(env->opmask_regs, &xsave->region[XSAVE_OPMASK],
             sizeof env->opmask_regs);
 
-    for (i = 0; i < CPU_NB_REGS; i++) {
-        uint8_t *xmm = xsave->legacy.xmm_regs[i];
-        uint8_t *ymmh = xsave->avx_state.ymmh[i];
-        uint8_t *zmmh = xsave->zmm_hi256_state.zmm_hi256[i];
+    xmm = (const uint8_t *)&xsave->region[XSAVE_XMM_SPACE];
+    ymmh = (const uint8_t *)&xsave->region[XSAVE_YMMH_SPACE];
+    zmmh = (const uint8_t *)&xsave->region[XSAVE_ZMM_Hi256];
+    for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) {
         env->xmm_regs[i].ZMM_Q(0) = ldq_p(xmm);
         env->xmm_regs[i].ZMM_Q(1) = ldq_p(xmm+8);
         env->xmm_regs[i].ZMM_Q(2) = ldq_p(ymmh);
@@ -1862,9 +1800,9 @@ static int kvm_get_xsave(X86CPU *cpu)
     }
 
 #ifdef TARGET_X86_64
-    memcpy(&env->xmm_regs[16], &xsave->hi16_zmm_state.hi16_zmm,
+    memcpy(&env->xmm_regs[16], &xsave->region[XSAVE_Hi16_ZMM],
            16 * sizeof env->xmm_regs[16]);
-    memcpy(&env->pkru, &xsave->pkru_state, sizeof env->pkru);
+    memcpy(&env->pkru, &xsave->region[XSAVE_PKRU], sizeof env->pkru);
 #endif
     return 0;
 }
@@ -1985,126 +1923,125 @@ static int kvm_get_sregs(X86CPU *cpu)
 static int kvm_get_msrs(X86CPU *cpu)
 {
     CPUX86State *env = &cpu->env;
-    struct kvm_msr_entry *msrs = cpu->kvm_msr_buf->entries;
-    int ret, i;
-    uint64_t mtrr_top_bits;
-
-    kvm_msr_buf_reset(cpu);
-
-    kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_CS, 0);
-    kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_ESP, 0);
-    kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_EIP, 0);
-    kvm_msr_entry_add(cpu, MSR_PAT, 0);
+    struct {
+        struct kvm_msrs info;
+        struct kvm_msr_entry entries[150];
+    } msr_data;
+    struct kvm_msr_entry *msrs = msr_data.entries;
+    int ret, i, n;
+
+    n = 0;
+    msrs[n++].index = MSR_IA32_SYSENTER_CS;
+    msrs[n++].index = MSR_IA32_SYSENTER_ESP;
+    msrs[n++].index = MSR_IA32_SYSENTER_EIP;
+    msrs[n++].index = MSR_PAT;
     if (has_msr_star) {
-        kvm_msr_entry_add(cpu, MSR_STAR, 0);
+        msrs[n++].index = MSR_STAR;
     }
     if (has_msr_hsave_pa) {
-        kvm_msr_entry_add(cpu, MSR_VM_HSAVE_PA, 0);
+        msrs[n++].index = MSR_VM_HSAVE_PA;
     }
     if (has_msr_tsc_aux) {
-        kvm_msr_entry_add(cpu, MSR_TSC_AUX, 0);
+        msrs[n++].index = MSR_TSC_AUX;
     }
     if (has_msr_tsc_adjust) {
-        kvm_msr_entry_add(cpu, MSR_TSC_ADJUST, 0);
+        msrs[n++].index = MSR_TSC_ADJUST;
     }
     if (has_msr_tsc_deadline) {
-        kvm_msr_entry_add(cpu, MSR_IA32_TSCDEADLINE, 0);
+        msrs[n++].index = MSR_IA32_TSCDEADLINE;
     }
     if (has_msr_misc_enable) {
-        kvm_msr_entry_add(cpu, MSR_IA32_MISC_ENABLE, 0);
+        msrs[n++].index = MSR_IA32_MISC_ENABLE;
     }
     if (has_msr_smbase) {
-        kvm_msr_entry_add(cpu, MSR_IA32_SMBASE, 0);
+        msrs[n++].index = MSR_IA32_SMBASE;
     }
     if (has_msr_feature_control) {
-        kvm_msr_entry_add(cpu, MSR_IA32_FEATURE_CONTROL, 0);
+        msrs[n++].index = MSR_IA32_FEATURE_CONTROL;
     }
     if (has_msr_bndcfgs) {
-        kvm_msr_entry_add(cpu, MSR_IA32_BNDCFGS, 0);
+        msrs[n++].index = MSR_IA32_BNDCFGS;
     }
     if (has_msr_xss) {
-        kvm_msr_entry_add(cpu, MSR_IA32_XSS, 0);
+        msrs[n++].index = MSR_IA32_XSS;
     }
 
 
     if (!env->tsc_valid) {
-        kvm_msr_entry_add(cpu, MSR_IA32_TSC, 0);
+        msrs[n++].index = MSR_IA32_TSC;
         env->tsc_valid = !runstate_is_running();
     }
 
 #ifdef TARGET_X86_64
     if (lm_capable_kernel) {
-        kvm_msr_entry_add(cpu, MSR_CSTAR, 0);
-        kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, 0);
-        kvm_msr_entry_add(cpu, MSR_FMASK, 0);
-        kvm_msr_entry_add(cpu, MSR_LSTAR, 0);
+        msrs[n++].index = MSR_CSTAR;
+        msrs[n++].index = MSR_KERNELGSBASE;
+        msrs[n++].index = MSR_FMASK;
+        msrs[n++].index = MSR_LSTAR;
     }
 #endif
-    kvm_msr_entry_add(cpu, MSR_KVM_SYSTEM_TIME, 0);
-    kvm_msr_entry_add(cpu, MSR_KVM_WALL_CLOCK, 0);
+    msrs[n++].index = MSR_KVM_SYSTEM_TIME;
+    msrs[n++].index = MSR_KVM_WALL_CLOCK;
     if (has_msr_async_pf_en) {
-        kvm_msr_entry_add(cpu, MSR_KVM_ASYNC_PF_EN, 0);
+        msrs[n++].index = MSR_KVM_ASYNC_PF_EN;
     }
     if (has_msr_pv_eoi_en) {
-        kvm_msr_entry_add(cpu, MSR_KVM_PV_EOI_EN, 0);
+        msrs[n++].index = MSR_KVM_PV_EOI_EN;
     }
     if (has_msr_kvm_steal_time) {
-        kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, 0);
+        msrs[n++].index = MSR_KVM_STEAL_TIME;
     }
     if (has_msr_architectural_pmu) {
-        kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
-        kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0);
-        kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS, 0);
-        kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL, 0);
+        msrs[n++].index = MSR_CORE_PERF_FIXED_CTR_CTRL;
+        msrs[n++].index = MSR_CORE_PERF_GLOBAL_CTRL;
+        msrs[n++].index = MSR_CORE_PERF_GLOBAL_STATUS;
+        msrs[n++].index = MSR_CORE_PERF_GLOBAL_OVF_CTRL;
         for (i = 0; i < MAX_FIXED_COUNTERS; i++) {
-            kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR0 + i, 0);
+            msrs[n++].index = MSR_CORE_PERF_FIXED_CTR0 + i;
         }
         for (i = 0; i < num_architectural_pmu_counters; i++) {
-            kvm_msr_entry_add(cpu, MSR_P6_PERFCTR0 + i, 0);
-            kvm_msr_entry_add(cpu, MSR_P6_EVNTSEL0 + i, 0);
+            msrs[n++].index = MSR_P6_PERFCTR0 + i;
+            msrs[n++].index = MSR_P6_EVNTSEL0 + i;
         }
     }
 
     if (env->mcg_cap) {
-        kvm_msr_entry_add(cpu, MSR_MCG_STATUS, 0);
-        kvm_msr_entry_add(cpu, MSR_MCG_CTL, 0);
-        if (has_msr_mcg_ext_ctl) {
-            kvm_msr_entry_add(cpu, MSR_MCG_EXT_CTL, 0);
-        }
+        msrs[n++].index = MSR_MCG_STATUS;
+        msrs[n++].index = MSR_MCG_CTL;
         for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++) {
-            kvm_msr_entry_add(cpu, MSR_MC0_CTL + i, 0);
+            msrs[n++].index = MSR_MC0_CTL + i;
         }
     }
 
     if (has_msr_hv_hypercall) {
-        kvm_msr_entry_add(cpu, HV_X64_MSR_HYPERCALL, 0);
-        kvm_msr_entry_add(cpu, HV_X64_MSR_GUEST_OS_ID, 0);
+        msrs[n++].index = HV_X64_MSR_HYPERCALL;
+        msrs[n++].index = HV_X64_MSR_GUEST_OS_ID;
     }
     if (has_msr_hv_vapic) {
-        kvm_msr_entry_add(cpu, HV_X64_MSR_APIC_ASSIST_PAGE, 0);
+        msrs[n++].index = HV_X64_MSR_APIC_ASSIST_PAGE;
     }
     if (has_msr_hv_tsc) {
-        kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC, 0);
+        msrs[n++].index = HV_X64_MSR_REFERENCE_TSC;
     }
     if (has_msr_hv_crash) {
         int j;
 
         for (j = 0; j < HV_X64_MSR_CRASH_PARAMS; j++) {
-            kvm_msr_entry_add(cpu, HV_X64_MSR_CRASH_P0 + j, 0);
+            msrs[n++].index = HV_X64_MSR_CRASH_P0 + j;
         }
     }
     if (has_msr_hv_runtime) {
-        kvm_msr_entry_add(cpu, HV_X64_MSR_VP_RUNTIME, 0);
+        msrs[n++].index = HV_X64_MSR_VP_RUNTIME;
     }
     if (cpu->hyperv_synic) {
         uint32_t msr;
 
-        kvm_msr_entry_add(cpu, HV_X64_MSR_SCONTROL, 0);
-        kvm_msr_entry_add(cpu, HV_X64_MSR_SVERSION, 0);
-        kvm_msr_entry_add(cpu, HV_X64_MSR_SIEFP, 0);
-        kvm_msr_entry_add(cpu, HV_X64_MSR_SIMP, 0);
+        msrs[n++].index = HV_X64_MSR_SCONTROL;
+        msrs[n++].index = HV_X64_MSR_SVERSION;
+        msrs[n++].index = HV_X64_MSR_SIEFP;
+        msrs[n++].index = HV_X64_MSR_SIMP;
         for (msr = HV_X64_MSR_SINT0; msr <= HV_X64_MSR_SINT15; msr++) {
-            kvm_msr_entry_add(cpu, msr, 0);
+            msrs[n++].index = msr;
         }
     }
     if (has_msr_hv_stimer) {
@@ -2112,58 +2049,38 @@ static int kvm_get_msrs(X86CPU *cpu)
 
         for (msr = HV_X64_MSR_STIMER0_CONFIG; msr <= HV_X64_MSR_STIMER3_COUNT;
              msr++) {
-            kvm_msr_entry_add(cpu, msr, 0);
+            msrs[n++].index = msr;
         }
     }
     if (has_msr_mtrr) {
-        kvm_msr_entry_add(cpu, MSR_MTRRdefType, 0);
-        kvm_msr_entry_add(cpu, MSR_MTRRfix64K_00000, 0);
-        kvm_msr_entry_add(cpu, MSR_MTRRfix16K_80000, 0);
-        kvm_msr_entry_add(cpu, MSR_MTRRfix16K_A0000, 0);
-        kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C0000, 0);
-        kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C8000, 0);
-        kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D0000, 0);
-        kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D8000, 0);
-        kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E0000, 0);
-        kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E8000, 0);
-        kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F0000, 0);
-        kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F8000, 0);
+        msrs[n++].index = MSR_MTRRdefType;
+        msrs[n++].index = MSR_MTRRfix64K_00000;
+        msrs[n++].index = MSR_MTRRfix16K_80000;
+        msrs[n++].index = MSR_MTRRfix16K_A0000;
+        msrs[n++].index = MSR_MTRRfix4K_C0000;
+        msrs[n++].index = MSR_MTRRfix4K_C8000;
+        msrs[n++].index = MSR_MTRRfix4K_D0000;
+        msrs[n++].index = MSR_MTRRfix4K_D8000;
+        msrs[n++].index = MSR_MTRRfix4K_E0000;
+        msrs[n++].index = MSR_MTRRfix4K_E8000;
+        msrs[n++].index = MSR_MTRRfix4K_F0000;
+        msrs[n++].index = MSR_MTRRfix4K_F8000;
         for (i = 0; i < MSR_MTRRcap_VCNT; i++) {
-            kvm_msr_entry_add(cpu, MSR_MTRRphysBase(i), 0);
-            kvm_msr_entry_add(cpu, MSR_MTRRphysMask(i), 0);
+            msrs[n++].index = MSR_MTRRphysBase(i);
+            msrs[n++].index = MSR_MTRRphysMask(i);
         }
     }
 
-    ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, cpu->kvm_msr_buf);
+    msr_data.info = (struct kvm_msrs) {
+        .nmsrs = n,
+    };
+
+    ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, &msr_data);
     if (ret < 0) {
         return ret;
     }
 
-    assert(ret == cpu->kvm_msr_buf->nmsrs);
-    /*
-     * MTRR masks: Each mask consists of 5 parts
-     * a  10..0: must be zero
-     * b  11   : valid bit
-     * c n-1.12: actual mask bits
-     * d  51..n: reserved must be zero
-     * e  63.52: reserved must be zero
-     *
-     * 'n' is the number of physical bits supported by the CPU and is
-     * apparently always <= 52.   We know our 'n' but don't know what
-     * the destinations 'n' is; it might be smaller, in which case
-     * it masks (c) on loading. It might be larger, in which case
-     * we fill 'd' so that d..c is consistent irrespetive of the 'n'
-     * we're migrating to.
-     */
-
-    if (cpu->fill_mtrr_mask) {
-        QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > 52);
-        assert(cpu->phys_bits <= TARGET_PHYS_ADDR_SPACE_BITS);
-        mtrr_top_bits = MAKE_64BIT_MASK(cpu->phys_bits, 52 - cpu->phys_bits);
-    } else {
-        mtrr_top_bits = 0;
-    }
-
+    assert(ret == n);
     for (i = 0; i < ret; i++) {
         uint32_t index = msrs[i].index;
         switch (index) {
@@ -2223,9 +2140,6 @@ static int kvm_get_msrs(X86CPU *cpu)
         case MSR_MCG_CTL:
             env->mcg_ctl = msrs[i].data;
             break;
-        case MSR_MCG_EXT_CTL:
-            env->mcg_ext_ctl = msrs[i].data;
-            break;
         case MSR_IA32_MISC_ENABLE:
             env->msr_ia32_misc_enable = msrs[i].data;
             break;
@@ -2362,8 +2276,7 @@ static int kvm_get_msrs(X86CPU *cpu)
             break;
         case MSR_MTRRphysBase(0) ... MSR_MTRRphysMask(MSR_MTRRcap_VCNT - 1):
             if (index & 1) {
-                env->mtrr_var[MSR_MTRRphysIndex(index)].mask = msrs[i].data |
-                                                               mtrr_top_bits;
+                env->mtrr_var[MSR_MTRRphysIndex(index)].mask = msrs[i].data;
             } else {
                 env->mtrr_var[MSR_MTRRphysIndex(index)].base = msrs[i].data;
             }
@@ -3243,7 +3156,8 @@ void kvm_arch_init_irq_routing(KVMState *s)
         /* If the ioapic is in QEMU and the lapics are in KVM, reserve
            MSI routes for signaling interrupts to the local apics. */
         for (i = 0; i < IOAPIC_NUM_PINS; i++) {
-            if (kvm_irqchip_add_msi_route(s, 0, NULL) < 0) {
+            struct MSIMessage msg = { 0x0, 0x0 };
+            if (kvm_irqchip_add_msi_route(s, msg, NULL) < 0) {
                 error_report("Could not enable split IRQ mode.");
                 exit(1);
             }
@@ -3257,7 +3171,7 @@ int kvm_arch_irqchip_create(MachineState *ms, KVMState *s)
     if (machine_kernel_irqchip_split(ms)) {
         ret = kvm_vm_enable_cap(s, KVM_CAP_SPLIT_IRQCHIP, 0, 24);
         if (ret) {
-            error_report("Could not enable split irqchip mode: %s",
+            error_report("Could not enable split irqchip mode: %s\n",
                          strerror(-ret));
             exit(1);
         } else {
@@ -3413,109 +3327,6 @@ int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id)
 int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
                              uint64_t address, uint32_t data, PCIDevice *dev)
 {
-    X86IOMMUState *iommu = x86_iommu_get_default();
-
-    if (iommu) {
-        int ret;
-        MSIMessage src, dst;
-        X86IOMMUClass *class = X86_IOMMU_GET_CLASS(iommu);
-
-        src.address = route->u.msi.address_hi;
-        src.address <<= VTD_MSI_ADDR_HI_SHIFT;
-        src.address |= route->u.msi.address_lo;
-        src.data = route->u.msi.data;
-
-        ret = class->int_remap(iommu, &src, &dst, dev ? \
-                               pci_requester_id(dev) : \
-                               X86_IOMMU_SID_INVALID);
-        if (ret) {
-            trace_kvm_x86_fixup_msi_error(route->gsi);
-            return 1;
-        }
-
-        route->u.msi.address_hi = dst.address >> VTD_MSI_ADDR_HI_SHIFT;
-        route->u.msi.address_lo = dst.address & VTD_MSI_ADDR_LO_MASK;
-        route->u.msi.data = dst.data;
-    }
-
-    return 0;
-}
-
-typedef struct MSIRouteEntry MSIRouteEntry;
-
-struct MSIRouteEntry {
-    PCIDevice *dev;             /* Device pointer */
-    int vector;                 /* MSI/MSIX vector index */
-    int virq;                   /* Virtual IRQ index */
-    QLIST_ENTRY(MSIRouteEntry) list;
-};
-
-/* List of used GSI routes */
-static QLIST_HEAD(, MSIRouteEntry) msi_route_list = \
-    QLIST_HEAD_INITIALIZER(msi_route_list);
-
-static void kvm_update_msi_routes_all(void *private, bool global,
-                                      uint32_t index, uint32_t mask)
-{
-    int cnt = 0;
-    MSIRouteEntry *entry;
-    MSIMessage msg;
-    /* TODO: explicit route update */
-    QLIST_FOREACH(entry, &msi_route_list, list) {
-        cnt++;
-        msg = pci_get_msi_message(entry->dev, entry->vector);
-        kvm_irqchip_update_msi_route(kvm_state, entry->virq,
-                                     msg, entry->dev);
-    }
-    kvm_irqchip_commit_routes(kvm_state);
-    trace_kvm_x86_update_msi_routes(cnt);
-}
-
-int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
-                                int vector, PCIDevice *dev)
-{
-    static bool notify_list_inited = false;
-    MSIRouteEntry *entry;
-
-    if (!dev) {
-        /* These are (possibly) IOAPIC routes only used for split
-         * kernel irqchip mode, while what we are housekeeping are
-         * PCI devices only. */
-        return 0;
-    }
-
-    entry = g_new0(MSIRouteEntry, 1);
-    entry->dev = dev;
-    entry->vector = vector;
-    entry->virq = route->gsi;
-    QLIST_INSERT_HEAD(&msi_route_list, entry, list);
-
-    trace_kvm_x86_add_msi_route(route->gsi);
-
-    if (!notify_list_inited) {
-        /* For the first time we do add route, add ourselves into
-         * IOMMU's IEC notify list if needed. */
-        X86IOMMUState *iommu = x86_iommu_get_default();
-        if (iommu) {
-            x86_iommu_iec_register_notifier(iommu,
-                                            kvm_update_msi_routes_all,
-                                            NULL);
-        }
-        notify_list_inited = true;
-    }
-    return 0;
-}
-
-int kvm_arch_release_virq_post(int virq)
-{
-    MSIRouteEntry *entry, *next;
-    QLIST_FOREACH_SAFE(entry, &msi_route_list, list, next) {
-        if (entry->virq == virq) {
-            trace_kvm_x86_remove_msi_route(virq);
-            QLIST_REMOVE(entry, list);
-            break;
-        }
-    }
     return 0;
 }
 
index 71c0e4d..ee5b949 100644 (file)
@@ -1,16 +1,10 @@
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
 #include "hw/hw.h"
 #include "hw/boards.h"
 #include "hw/i386/pc.h"
 #include "hw/isa/isa.h"
-#include "migration/cpu.h"
-#include "exec/exec-all.h"
 
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "sysemu/kvm.h"
 
 #include "qemu/error-report.h"
@@ -896,24 +890,6 @@ static const VMStateDescription vmstate_tsc_khz = {
     }
 };
 
-static bool mcg_ext_ctl_needed(void *opaque)
-{
-    X86CPU *cpu = opaque;
-    CPUX86State *env = &cpu->env;
-    return cpu->enable_lmce && env->mcg_ext_ctl;
-}
-
-static const VMStateDescription vmstate_mcg_ext_ctl = {
-    .name = "cpu/mcg_ext_ctl",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .needed = mcg_ext_ctl_needed,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT64(env.mcg_ext_ctl, X86CPU),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
 VMStateDescription vmstate_x86_cpu = {
     .name = "cpu",
     .version_id = 12,
@@ -1040,7 +1016,6 @@ VMStateDescription vmstate_x86_cpu = {
 #ifdef TARGET_X86_64
         &vmstate_pkru,
 #endif
-        &vmstate_mcg_ext_ctl,
         NULL
     }
 };
index 5bc0594..85e7516 100644 (file)
@@ -20,7 +20,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 /* broken thread support */
@@ -140,12 +139,12 @@ void helper_boundl(CPUX86State *env, target_ulong a0, int v)
  * from generated code or from helper.c)
  */
 /* XXX: fix it to restore all registers */
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr)
 {
     int ret;
 
-    ret = x86_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = x86_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (ret) {
         X86CPU *cpu = X86_CPU(cs);
         CPUX86State *env = &cpu->env;
index 3f666b4..e31ec97 100644 (file)
@@ -20,7 +20,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "exec/address-spaces.h"
 
index 7e44820..4d1785e 100644 (file)
@@ -21,7 +21,6 @@
 #include "cpu.h"
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"
-#include "exec/exec-all.h"
 
 
 void cpu_sync_bndcs_hflags(CPUX86State *env)
index 6cbdf17..b5f3d72 100644 (file)
@@ -22,7 +22,6 @@
 #include "cpu.h"
 #include "qemu/log.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "exec/log.h"
 
@@ -1129,11 +1128,7 @@ static void do_interrupt_real(CPUX86State *env, int intno, int is_int,
 }
 
 #if defined(CONFIG_USER_ONLY)
-/* fake user mode interrupt. is_int is TRUE if coming from the int
- * instruction. next_eip is the env->eip value AFTER the interrupt
- * instruction. It is only relevant if is_int is TRUE or if intno
- * is EXCP_SYSCALL.
- */
+/* fake user mode interrupt */
 static void do_interrupt_user(CPUX86State *env, int intno, int is_int,
                               int error_code, target_ulong next_eip)
 {
index 922c8fd..04193ed 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef SVM_H
-#define SVM_H
+#ifndef __SVM_H
+#define __SVM_H
 
 #define TLB_CONTROL_DO_NOTHING 0
 #define TLB_CONTROL_FLUSH_ALL_ASID 1
index 782b3f1..ab472f6 100644 (file)
@@ -21,7 +21,6 @@
 #include "cpu.h"
 #include "exec/cpu-all.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 /* Secure Virtual Machine helpers */
diff --git a/target-i386/trace-events b/target-i386/trace-events
deleted file mode 100644 (file)
index 05c5453..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# target-i386/kvm.c
-kvm_x86_fixup_msi_error(uint32_t gsi) "VT-d failed to remap interrupt for GSI %" PRIu32
-kvm_x86_add_msi_route(int virq) "Adding route entry for virq %d"
-kvm_x86_remove_msi_route(int virq) "Removing route entry for virq %d"
-kvm_x86_update_msi_routes(int num) "Updated %d MSI routes"
index fa2ac48..922347c 100644 (file)
@@ -21,7 +21,6 @@
 #include "qemu/host-utils.h"
 #include "cpu.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "exec/cpu_ldst.h"
 
@@ -2086,25 +2085,20 @@ static inline int insn_const_size(TCGMemOp ot)
     }
 }
 
-static inline bool use_goto_tb(DisasContext *s, target_ulong pc)
-{
-#ifndef CONFIG_USER_ONLY
-    return (pc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) ||
-           (pc & TARGET_PAGE_MASK) == (s->pc_start & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
 static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
 {
-    target_ulong pc = s->cs_base + eip;
-
-    if (use_goto_tb(s, pc))  {
+    TranslationBlock *tb;
+    target_ulong pc;
+
+    pc = s->cs_base + eip;
+    tb = s->tb;
+    /* NOTE: we handle the case where the TB spans two pages here */
+    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
+        (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
         /* jump to same page: we can use a direct jump */
         tcg_gen_goto_tb(tb_num);
         gen_jmp_im(eip);
-        tcg_gen_exit_tb((uintptr_t)s->tb + tb_num);
+        tcg_gen_exit_tb((uintptr_t)tb + tb_num);
     } else {
         /* jump to another page: currently not optimized */
         gen_jmp_im(eip);
@@ -8144,15 +8138,8 @@ void tcg_x86_init(void)
         "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
     };
     int i;
-    static bool initialized;
-
-    if (initialized) {
-        return;
-    }
-    initialized = true;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
     cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
                                        offsetof(CPUX86State, cc_op), "cc_op");
     cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst),
@@ -8196,7 +8183,7 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
     CPUState *cs = CPU(cpu);
     DisasContext dc1, *dc = &dc1;
     target_ulong pc_ptr;
-    uint32_t flags;
+    uint64_t flags;
     target_ulong pc_start;
     target_ulong cs_base;
     int num_insns;
@@ -8224,9 +8211,9 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
     dc->popl_esp_hack = 0;
     /* select memory access functions */
     dc->mem_index = 0;
-#ifdef CONFIG_SOFTMMU
-    dc->mem_index = cpu_mmu_index(env, false);
-#endif
+    if (flags & HF_SOFTMMU_MASK) {
+       dc->mem_index = cpu_mmu_index(env, false);
+    }
     dc->cpuid_features = env->features[FEAT_1_EDX];
     dc->cpuid_ext_features = env->features[FEAT_1_ECX];
     dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
@@ -8239,7 +8226,11 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
 #endif
     dc->flags = flags;
     dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
-                    (flags & HF_INHIBIT_IRQ_MASK));
+                    (flags & HF_INHIBIT_IRQ_MASK)
+#ifndef CONFIG_SOFTMMU
+                    || (flags & HF_SOFTMMU_MASK)
+#endif
+                    );
     /* Do not optimize repz jumps at all in icount mode, because
        rep movsS instructions are execured with different paths
        in !repz_opt and repz_opt modes. The first one was used
@@ -8351,8 +8342,7 @@ done_generating:
     gen_tb_end(tb, num_insns);
 
 #ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         int disas_flags;
         qemu_log("----------------\n");
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
index b423d25..77bc7b2 100644 (file)
@@ -21,6 +21,7 @@
 #define QEMU_LM32_CPU_QOM_H
 
 #include "qom/cpu.h"
+#include "cpu.h"
 
 #define TYPE_LM32_CPU "lm32-cpu"
 
@@ -47,6 +48,45 @@ typedef struct LM32CPUClass {
     void (*parent_reset)(CPUState *cpu);
 } LM32CPUClass;
 
-typedef struct LM32CPU LM32CPU;
+/**
+ * LM32CPU:
+ * @env: #CPULM32State
+ *
+ * A LatticeMico32 CPU.
+ */
+typedef struct LM32CPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPULM32State env;
+
+    uint32_t revision;
+    uint8_t num_interrupts;
+    uint8_t num_breakpoints;
+    uint8_t num_watchpoints;
+    uint32_t features;
+} LM32CPU;
+
+static inline LM32CPU *lm32_env_get_cpu(CPULM32State *env)
+{
+    return container_of(env, LM32CPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(lm32_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(LM32CPU, env)
+
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_lm32_cpu;
+#endif
+
+void lm32_cpu_do_interrupt(CPUState *cpu);
+bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
+void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
+hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int lm32_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int lm32_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
index a783d46..6e7e1b8 100644 (file)
@@ -22,7 +22,6 @@
 #include "qapi/error.h"
 #include "cpu.h"
 #include "qemu-common.h"
-#include "exec/exec-all.h"
 
 
 static void lm32_cpu_set_pc(CPUState *cs, vaddr value)
index d8a3515..f220fc0 100644 (file)
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef LM32_CPU_H
-#define LM32_CPU_H
+#ifndef CPU_LM32_H
+#define CPU_LM32_H
 
 #define TARGET_LONG_BITS 32
 
 #define CPUArchState struct CPULM32State
 
 #include "qemu-common.h"
-#include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 struct CPULM32State;
 typedef struct CPULM32State CPULM32State;
@@ -181,47 +180,6 @@ struct CPULM32State {
 
 };
 
-/**
- * LM32CPU:
- * @env: #CPULM32State
- *
- * A LatticeMico32 CPU.
- */
-struct LM32CPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPULM32State env;
-
-    uint32_t revision;
-    uint8_t num_interrupts;
-    uint8_t num_breakpoints;
-    uint8_t num_watchpoints;
-    uint32_t features;
-};
-
-static inline LM32CPU *lm32_env_get_cpu(CPULM32State *env)
-{
-    return container_of(env, LM32CPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(lm32_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(LM32CPU, env)
-
-#ifndef CONFIG_USER_ONLY
-extern const struct VMStateDescription vmstate_lm32_cpu;
-#endif
-
-void lm32_cpu_do_interrupt(CPUState *cpu);
-bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
-void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
-                         int flags);
-hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-int lm32_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int lm32_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-
 typedef enum {
     LM32_WP_DISABLED = 0,
     LM32_WP_READ,
@@ -235,7 +193,10 @@ static inline lm32_wp_t lm32_wp_type(uint32_t dc, int idx)
     return (dc >> (idx+1)*2) & 0x3;
 }
 
+#include "cpu-qom.h"
+
 LM32CPU *cpu_lm32_init(const char *cpu_model);
+int cpu_lm32_exec(CPUState *cpu);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
@@ -256,6 +217,7 @@ bool lm32_cpu_do_semihosting(CPUState *cs);
 #define cpu_init(cpu_model) CPU(cpu_lm32_init(cpu_model))
 
 #define cpu_list lm32_cpu_list
+#define cpu_exec cpu_lm32_exec
 #define cpu_signal_handler cpu_lm32_signal_handler
 
 int lm32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
@@ -264,11 +226,13 @@ int lm32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
 #include "exec/cpu-all.h"
 
 static inline void cpu_get_tb_cpu_state(CPULM32State *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *pc = env->pc;
     *cs_base = 0;
     *flags = 0;
 }
 
+#include "exec/exec-all.h"
+
 #endif
index cf929dd..8ac1288 100644 (file)
@@ -19,7 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
 #include "hw/lm32/lm32_pic.h"
 
index 891da18..655248f 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "qemu/host-utils.h"
 #include "sysemu/sysemu.h"
 #include "exec/semihost.h"
@@ -141,7 +140,7 @@ void lm32_debug_excp_handler(CPUState *cs)
             if (check_watchpoints(env)) {
                 raise_exception(env, EXCP_WATCHPOINT);
             } else {
-                cpu_loop_exit_noexc(cs);
+                cpu_resume_from_signal(cs, NULL);
             }
         }
     } else {
index 3c258a4..91c943d 100644 (file)
@@ -1,9 +1,6 @@
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "hw/hw.h"
 #include "hw/boards.h"
-#include "migration/cpu.h"
 
 static const VMStateDescription vmstate_env = {
     .name = "env",
index 2177c8a..b6759e0 100644 (file)
@@ -6,7 +6,6 @@
 #include "hw/lm32/lm32_pic.h"
 #include "hw/char/lm32_juart.h"
 
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 #ifndef CONFIG_USER_ONLY
@@ -144,12 +143,12 @@ uint32_t HELPER(rcsr_jrx)(CPULM32State *env)
  * NULL, it means that the function was called in C code (i.e. not
  * from generated code or from helper.c)
  */
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr)
 {
     int ret;
 
-    ret = lm32_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = lm32_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
index 2d8caeb..256a51f 100644 (file)
@@ -21,7 +21,6 @@
 #include "cpu.h"
 #include "disas/disas.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 
 #include "exec/cpu_ldst.h"
@@ -134,25 +133,16 @@ static inline void t_gen_illegal_insn(DisasContext *dc)
     gen_helper_ill(cpu_env);
 }
 
-static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
-{
-    if (unlikely(dc->singlestep_enabled)) {
-        return false;
-    }
-
-#ifndef CONFIG_USER_ONLY
-    return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 {
-    if (use_goto_tb(dc, dest)) {
+    TranslationBlock *tb;
+
+    tb = dc->tb;
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
+            likely(!dc->singlestep_enabled)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(cpu_pc, dest);
-        tcg_gen_exit_tb((uintptr_t)dc->tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_tl(cpu_pc, dest);
         if (dc->singlestep_enabled) {
@@ -1147,8 +1137,7 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
     tb->icount = num_insns;
 
 #ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("\n");
         log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
         qemu_log("\nisize=%d osize=%d\n",
@@ -1202,7 +1191,6 @@ void lm32_translate_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
 
     for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
         cpu_R[i] = tcg_global_mem_new(cpu_env,
index 9885bba..c28e55d 100644 (file)
@@ -47,6 +47,38 @@ typedef struct M68kCPUClass {
     void (*parent_reset)(CPUState *cpu);
 } M68kCPUClass;
 
-typedef struct M68kCPU M68kCPU;
+/**
+ * M68kCPU:
+ * @env: #CPUM68KState
+ *
+ * A Motorola 68k CPU.
+ */
+typedef struct M68kCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUM68KState env;
+} M68kCPU;
+
+static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env)
+{
+    return container_of(env, M68kCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(m68k_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(M68kCPU, env)
+
+void m68k_cpu_do_interrupt(CPUState *cpu);
+bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req);
+void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
+hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int m68k_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int m68k_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+
+void m68k_cpu_exec_enter(CPUState *cs);
+void m68k_cpu_exec_exit(CPUState *cs);
 
 #endif
index 116b784..0b5f9a5 100644 (file)
@@ -23,7 +23,6 @@
 #include "cpu.h"
 #include "qemu-common.h"
 #include "migration/vmstate.h"
-#include "exec/exec-all.h"
 
 
 static void m68k_cpu_set_pc(CPUState *cs, vaddr value)
index b2faa6b..48b4c87 100644 (file)
@@ -17,9 +17,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-
-#ifndef M68K_CPU_H
-#define M68K_CPU_H
+#ifndef CPU_M68K_H
+#define CPU_M68K_H
 
 #define TARGET_LONG_BITS 32
 
@@ -27,7 +26,7 @@
 
 #include "qemu-common.h"
 #include "exec/cpu-defs.h"
-#include "cpu-qom.h"
+
 #include "fpu/softfloat.h"
 
 #define MAX_QREGS 32
@@ -110,43 +109,12 @@ typedef struct CPUM68KState {
     uint32_t features;
 } CPUM68KState;
 
-/**
- * M68kCPU:
- * @env: #CPUM68KState
- *
- * A Motorola 68k CPU.
- */
-struct M68kCPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPUM68KState env;
-};
-
-static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env)
-{
-    return container_of(env, M68kCPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(m68k_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(M68kCPU, env)
-
-void m68k_cpu_do_interrupt(CPUState *cpu);
-bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req);
-void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
-                         int flags);
-hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-int m68k_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int m68k_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-
-void m68k_cpu_exec_enter(CPUState *cs);
-void m68k_cpu_exec_exit(CPUState *cs);
+#include "cpu-qom.h"
 
 void m68k_tcg_init(void);
 void m68k_cpu_init_gdb(M68kCPU *cpu);
 M68kCPU *cpu_m68k_init(const char *cpu_model);
+int cpu_m68k_exec(CPUState *cpu);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
@@ -243,6 +211,7 @@ void register_m68k_insns (CPUM68KState *env);
 
 #define cpu_init(cpu_model) CPU(cpu_m68k_init(cpu_model))
 
+#define cpu_exec cpu_m68k_exec
 #define cpu_signal_handler cpu_m68k_signal_handler
 #define cpu_list m68k_cpu_list
 
@@ -261,7 +230,7 @@ int m68k_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
 #include "exec/cpu-all.h"
 
 static inline void cpu_get_tb_cpu_state(CPUM68KState *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *pc = env->pc;
     *cs_base = 0;
@@ -270,4 +239,6 @@ static inline void cpu_get_tb_cpu_state(CPUM68KState *env, target_ulong *pc,
             | ((env->macsr >> 4) & 0xf);        /* Bits 0-3 */
 }
 
+#include "exec/exec-all.h"
+
 #endif
index c7f44c9..f02bb5c 100644 (file)
@@ -19,7 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
 
 int m68k_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
index f52d0e3..a8f6d9d 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/gdbstub.h"
 
 #include "exec/helper-proto.h"
@@ -558,10 +557,10 @@ float64 HELPER(sub_cmp_f64)(CPUM68KState *env, float64 a, float64 b)
     /* ??? Should flush denormals to zero.  */
     float64 res;
     res = float64_sub(a, b, &env->fp_status);
-    if (float64_is_quiet_nan(res, &env->fp_status)) {
+    if (float64_is_quiet_nan(res)) {
         /* +/-inf compares equal against itself, but sub returns nan.  */
-        if (!float64_is_quiet_nan(a, &env->fp_status)
-            && !float64_is_quiet_nan(b, &env->fp_status)) {
+        if (!float64_is_quiet_nan(a)
+            && !float64_is_quiet_nan(b)) {
             res = float64_zero;
             if (float64_lt_quiet(a, res, &env->fp_status))
                 res = float64_chs(res);
index 1402145..f360ef3 100644 (file)
@@ -28,7 +28,6 @@
 #include "exec/gdbstub.h"
 #include "exec/softmmu-semi.h"
 #endif
-#include "qemu/log.h"
 #include "sysemu/sysemu.h"
 
 #define HOSTED_EXIT  0
index e41ae46..17d0a11 100644 (file)
@@ -19,7 +19,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "exec/semihost.h"
 
@@ -39,12 +38,12 @@ static inline void do_interrupt_m68k_hardirq(CPUM68KState *env)
 /* Try to fill the TLB and return an exception if error. If retaddr is
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr)
 {
     int ret;
 
-    ret = m68k_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = m68k_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
index ecd5e5c..7560c3a 100644 (file)
@@ -21,7 +21,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "qemu/log.h"
 #include "exec/cpu_ldst.h"
@@ -78,7 +77,6 @@ void m68k_tcg_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
 
 #define DEFO32(name, offset) \
     QREG_##name = tcg_global_mem_new_i32(cpu_env, \
@@ -854,25 +852,19 @@ static inline void gen_addr_fault(DisasContext *s)
         }                                                               \
     } while (0)
 
-static inline bool use_goto_tb(DisasContext *s, uint32_t dest)
-{
-#ifndef CONFIG_USER_ONLY
-    return (s->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
-           (s->insn_pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
 /* Generate a jump to an immediate address.  */
 static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
 {
+    TranslationBlock *tb;
+
+    tb = s->tb;
     if (unlikely(s->singlestep_enabled)) {
         gen_exception(s, dest, EXCP_DEBUG);
-    } else if (use_goto_tb(s, dest)) {
+    } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
+               (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_i32(QREG_PC, dest);
-        tcg_gen_exit_tb((uintptr_t)s->tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         gen_jmp_im(s, dest);
         tcg_gen_exit_tb(0);
@@ -3068,8 +3060,7 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
     gen_tb_end(tb, num_insns);
 
 #ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("----------------\n");
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
         log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
index 1a61db7..34f6273 100644 (file)
@@ -47,6 +47,48 @@ typedef struct MicroBlazeCPUClass {
     void (*parent_reset)(CPUState *cpu);
 } MicroBlazeCPUClass;
 
-typedef struct MicroBlazeCPU MicroBlazeCPU;
+/**
+ * MicroBlazeCPU:
+ * @env: #CPUMBState
+ *
+ * A MicroBlaze CPU.
+ */
+typedef struct MicroBlazeCPU {
+    /*< private >*/
+    CPUState parent_obj;
+
+    /*< public >*/
+
+    /* Microblaze Configuration Settings */
+    struct {
+        bool stackprot;
+        uint32_t base_vectors;
+        uint8_t use_fpu;
+        bool use_mmu;
+        bool dcache_writeback;
+        bool endi;
+        char *version;
+        uint8_t pvr;
+    } cfg;
+
+    CPUMBState env;
+} MicroBlazeCPU;
+
+static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
+{
+    return container_of(env, MicroBlazeCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(mb_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(MicroBlazeCPU, env)
+
+void mb_cpu_do_interrupt(CPUState *cs);
+bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
+void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                       int flags);
+hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int mb_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
index 8edc00a..fdfb019 100644 (file)
@@ -27,7 +27,6 @@
 #include "qemu-common.h"
 #include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
-#include "exec/exec-all.h"
 
 static const struct {
     const char *name;
index beb75ff..2f7335e 100644 (file)
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-
-#ifndef MICROBLAZE_CPU_H
-#define MICROBLAZE_CPU_H
+#ifndef CPU_MICROBLAZE_H
+#define CPU_MICROBLAZE_H
 
 #include "qemu-common.h"
-#include "cpu-qom.h"
 
 #define TARGET_LONG_BITS 32
 
@@ -276,52 +274,11 @@ struct CPUMBState {
     } pvr;
 };
 
-/**
- * MicroBlazeCPU:
- * @env: #CPUMBState
- *
- * A MicroBlaze CPU.
- */
-struct MicroBlazeCPU {
-    /*< private >*/
-    CPUState parent_obj;
-
-    /*< public >*/
-
-    /* Microblaze Configuration Settings */
-    struct {
-        bool stackprot;
-        uint32_t base_vectors;
-        uint8_t use_fpu;
-        bool use_mmu;
-        bool dcache_writeback;
-        bool endi;
-        char *version;
-        uint8_t pvr;
-    } cfg;
-
-    CPUMBState env;
-};
-
-static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
-{
-    return container_of(env, MicroBlazeCPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(mb_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(MicroBlazeCPU, env)
-
-void mb_cpu_do_interrupt(CPUState *cs);
-bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
-void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
-                       int flags);
-hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-int mb_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+#include "cpu-qom.h"
 
 void mb_tcg_init(void);
 MicroBlazeCPU *cpu_mb_init(const char *cpu_model);
+int cpu_mb_exec(CPUState *cpu);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
@@ -336,6 +293,7 @@ int cpu_mb_signal_handler(int host_signum, void *pinfo,
 
 #define cpu_init(cpu_model) CPU(cpu_mb_init(cpu_model))
 
+#define cpu_exec cpu_mb_exec
 #define cpu_signal_handler cpu_mb_signal_handler
 
 /* MMU modes definitions */
@@ -364,7 +322,7 @@ int mb_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
 #include "exec/cpu-all.h"
 
 static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *pc = env->sregs[SR_PC];
     *cs_base = 0;
@@ -378,4 +336,6 @@ void mb_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
                               unsigned size);
 #endif
 
+#include "exec/exec-all.h"
+
 #endif
index 7fb076c..89d3898 100644 (file)
@@ -19,7 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
 
 int mb_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
index da394d1..4de6bdb 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "qemu/host-utils.h"
 #include "exec/log.h"
 
index a22a496..4ac3040 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 
 #define D(x)
 
index 4a856e6..9733388 100644 (file)
@@ -22,7 +22,6 @@
 #include "cpu.h"
 #include "exec/helper-proto.h"
 #include "qemu/host-utils.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 #define D(x)
  * NULL, it means that the function was called in C code (i.e. not
  * from generated code or from helper.c)
  */
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr)
 {
     int ret;
 
-    ret = mb_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = mb_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
@@ -288,14 +287,12 @@ uint32_t helper_fcmp_un(CPUMBState *env, uint32_t a, uint32_t b)
     fa.l = a;
     fb.l = b;
 
-    if (float32_is_signaling_nan(fa.f, &env->fp_status) ||
-        float32_is_signaling_nan(fb.f, &env->fp_status)) {
+    if (float32_is_signaling_nan(fa.f) || float32_is_signaling_nan(fb.f)) {
         update_fpu_flags(env, float_flag_invalid);
         r = 1;
     }
 
-    if (float32_is_quiet_nan(fa.f, &env->fp_status) ||
-        float32_is_quiet_nan(fb.f, &env->fp_status)) {
+    if (float32_is_quiet_nan(fa.f) || float32_is_quiet_nan(fb.f)) {
         r = 1;
     }
 
index 80098ec..f944965 100644 (file)
@@ -21,7 +21,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "exec/helper-proto.h"
 #include "microblaze-decode.h"
@@ -125,21 +124,14 @@ static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
     dc->is_jmp = DISAS_UPDATE;
 }
 
-static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
-{
-#ifndef CONFIG_USER_ONLY
-    return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 {
-    if (use_goto_tb(dc, dest)) {
+    TranslationBlock *tb;
+    tb = dc->tb;
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
-        tcg_gen_exit_tb((uintptr_t)dc->tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
         tcg_gen_exit_tb(0);
@@ -1818,8 +1810,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
 
 #ifdef DEBUG_DISAS
 #if !SIM_COMPAT
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("\n");
 #if DISAS_GNU
         log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
@@ -1878,7 +1869,6 @@ void mb_tcg_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
 
     env_debug = tcg_global_mem_new(cpu_env,
                     offsetof(CPUMBState, debug),
index 3f5bf23..4d6f9de 100644 (file)
@@ -51,6 +51,41 @@ typedef struct MIPSCPUClass {
     void (*parent_reset)(CPUState *cpu);
 } MIPSCPUClass;
 
-typedef struct MIPSCPU MIPSCPU;
+/**
+ * MIPSCPU:
+ * @env: #CPUMIPSState
+ *
+ * A MIPS CPU.
+ */
+typedef struct MIPSCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUMIPSState env;
+} MIPSCPU;
+
+static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
+{
+    return container_of(env, MIPSCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(mips_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(MIPSCPU, env)
+
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_mips_cpu;
+#endif
+
+void mips_cpu_do_interrupt(CPUState *cpu);
+bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
+void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
+hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int mips_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int mips_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+void mips_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
+                                  int is_write, int is_user, uintptr_t retaddr);
 
 #endif
index 64ad112..0e2ecbe 100644 (file)
@@ -24,7 +24,6 @@
 #include "kvm_mips.h"
 #include "qemu-common.h"
 #include "sysemu/kvm.h"
-#include "exec/exec-all.h"
 
 
 static void mips_cpu_set_pc(CPUState *cs, vaddr value)
index 5182dc7..866924d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef MIPS_CPU_H
-#define MIPS_CPU_H
+#if !defined (__MIPS_CPU_H__)
+#define __MIPS_CPU_H__
 
 //#define DEBUG_OP
 
@@ -8,7 +8,6 @@
 #define CPUArchState struct CPUMIPSState
 
 #include "qemu-common.h"
-#include "cpu-qom.h"
 #include "mips-defs.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat.h"
@@ -19,7 +18,7 @@ typedef struct r4k_tlb_t r4k_tlb_t;
 struct r4k_tlb_t {
     target_ulong VPN;
     uint32_t PageMask;
-    uint16_t ASID;
+    uint8_t ASID;
     unsigned int G:1;
     unsigned int C0:3;
     unsigned int C1:3;
@@ -111,9 +110,7 @@ struct CPUMIPSFPUContext {
 #define FCR0_PRID 8
 #define FCR0_REV 0
     /* fcsr */
-    uint32_t fcr31_rw_bitmask;
     uint32_t fcr31;
-#define FCR31_FS 24
 #define FCR31_ABS2008 19
 #define FCR31_NAN2008 18
 #define SET_FP_COND(num,env)     do { ((env).fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
@@ -343,7 +340,6 @@ struct CPUMIPSState {
     int32_t CP0_Count;
     target_ulong CP0_EntryHi;
 #define CP0EnHi_EHINV 10
-    target_ulong CP0_EntryHi_ASID_mask;
     int32_t CP0_Compare;
     int32_t CP0_Status;
 #define CP0St_CU3   31
@@ -468,7 +464,6 @@ struct CPUMIPSState {
     int32_t CP0_Config4_rw_bitmask;
 #define CP0C4_M    31
 #define CP0C4_IE   29
-#define CP0C4_AE   28
 #define CP0C4_KScrExist 16
 #define CP0C4_MMUExtDef 14
 #define CP0C4_FTLBPageSize 8
@@ -505,7 +500,6 @@ struct CPUMIPSState {
     int CP0_LLAddr_shift;
     target_ulong CP0_WatchLo[8];
     int32_t CP0_WatchHi[8];
-#define CP0WH_ASID 16
     target_ulong CP0_XContext;
     int32_t CP0_Framemask;
     int32_t CP0_Debug;
@@ -619,46 +613,9 @@ struct CPUMIPSState {
     void *irq[8];
     QEMUTimer *timer; /* Internal timer */
     MemoryRegion *itc_tag; /* ITC Configuration Tags */
-    target_ulong exception_base; /* ExceptionBase input to the core */
-};
-
-/**
- * MIPSCPU:
- * @env: #CPUMIPSState
- *
- * A MIPS CPU.
- */
-struct MIPSCPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPUMIPSState env;
 };
 
-static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
-{
-    return container_of(env, MIPSCPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(mips_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(MIPSCPU, env)
-
-#ifndef CONFIG_USER_ONLY
-extern const struct VMStateDescription vmstate_mips_cpu;
-#endif
-
-void mips_cpu_do_interrupt(CPUState *cpu);
-bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
-void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
-                         int flags);
-hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-int mips_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int mips_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-void mips_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
-                                  MMUAccessType access_type,
-                                  int mmu_idx, uintptr_t retaddr);
+#include "cpu-qom.h"
 
 #if !defined(CONFIG_USER_ONLY)
 int no_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
@@ -681,6 +638,7 @@ void mips_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
 
 void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf);
 
+#define cpu_exec cpu_mips_exec
 #define cpu_signal_handler cpu_mips_signal_handler
 #define cpu_list mips_cpu_list
 
@@ -806,13 +764,13 @@ enum {
  */
 #define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0
 
+int cpu_mips_exec(CPUState *cpu);
 void mips_tcg_init(void);
 MIPSCPU *cpu_mips_init(const char *cpu_model);
 int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
 
 #define cpu_init(cpu_model) CPU(cpu_mips_init(cpu_model))
 bool cpu_supports_cps_smp(const char *cpu_model);
-void cpu_set_exception_base(int vp_index, target_ulong address);
 
 /* TODO QOM'ify CPU reset and remove */
 void cpu_state_reset(CPUMIPSState *s);
@@ -831,11 +789,6 @@ void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level);
 /* helper.c */
 int mips_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
                               int mmu_idx);
-
-/* op_helper.c */
-uint32_t float_class_s(uint32_t arg, float_status *fst);
-uint64_t float_class_d(uint64_t arg, float_status *fst);
-
 #if !defined(CONFIG_USER_ONLY)
 void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra);
 hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address,
@@ -855,21 +808,14 @@ static inline void restore_rounding_mode(CPUMIPSState *env)
 
 static inline void restore_flush_mode(CPUMIPSState *env)
 {
-    set_flush_to_zero((env->active_fpu.fcr31 & (1 << FCR31_FS)) != 0,
+    set_flush_to_zero((env->active_fpu.fcr31 & (1 << 24)) != 0,
                       &env->active_fpu.fp_status);
 }
 
-static inline void restore_snan_bit_mode(CPUMIPSState *env)
-{
-    set_snan_bit_is_one((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) == 0,
-                        &env->active_fpu.fp_status);
-}
-
 static inline void restore_fp_status(CPUMIPSState *env)
 {
     restore_rounding_mode(env);
     restore_flush_mode(env);
-    restore_snan_bit_mode(env);
 }
 
 static inline void restore_msa_fp_status(CPUMIPSState *env)
@@ -893,7 +839,7 @@ static inline void restore_pamask(CPUMIPSState *env)
 }
 
 static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *pc = env->active_tc.PC;
     *cs_base = 0;
@@ -952,6 +898,8 @@ static inline int mips_vp_active(CPUMIPSState *env)
     return 1;
 }
 
+#include "exec/exec-all.h"
+
 static inline void compute_hflags(CPUMIPSState *env)
 {
     env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
@@ -1051,13 +999,132 @@ static inline void compute_hflags(CPUMIPSState *env)
     }
 }
 
-void cpu_mips_tlb_flush(CPUMIPSState *env, int flush_global);
-void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc);
-void cpu_mips_store_status(CPUMIPSState *env, target_ulong val);
-void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val);
+#ifndef CONFIG_USER_ONLY
+static inline void cpu_mips_tlb_flush(CPUMIPSState *env, int flush_global)
+{
+    MIPSCPU *cpu = mips_env_get_cpu(env);
+
+    /* Flush qemu's TLB and discard all shadowed entries.  */
+    tlb_flush(CPU(cpu), flush_global);
+    env->tlb->tlb_in_use = env->tlb->nb_tlb;
+}
+
+/* Called for updates to CP0_Status.  */
+static inline void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc)
+{
+    int32_t tcstatus, *tcst;
+    uint32_t v = cpu->CP0_Status;
+    uint32_t cu, mx, asid, ksu;
+    uint32_t mask = ((1 << CP0TCSt_TCU3)
+                       | (1 << CP0TCSt_TCU2)
+                       | (1 << CP0TCSt_TCU1)
+                       | (1 << CP0TCSt_TCU0)
+                       | (1 << CP0TCSt_TMX)
+                       | (3 << CP0TCSt_TKSU)
+                       | (0xff << CP0TCSt_TASID));
+
+    cu = (v >> CP0St_CU0) & 0xf;
+    mx = (v >> CP0St_MX) & 0x1;
+    ksu = (v >> CP0St_KSU) & 0x3;
+    asid = env->CP0_EntryHi & 0xff;
+
+    tcstatus = cu << CP0TCSt_TCU0;
+    tcstatus |= mx << CP0TCSt_TMX;
+    tcstatus |= ksu << CP0TCSt_TKSU;
+    tcstatus |= asid;
+
+    if (tc == cpu->current_tc) {
+        tcst = &cpu->active_tc.CP0_TCStatus;
+    } else {
+        tcst = &cpu->tcs[tc].CP0_TCStatus;
+    }
+
+    *tcst &= ~mask;
+    *tcst |= tcstatus;
+    compute_hflags(cpu);
+}
+
+static inline void cpu_mips_store_status(CPUMIPSState *env, target_ulong val)
+{
+    uint32_t mask = env->CP0_Status_rw_bitmask;
+    target_ulong old = env->CP0_Status;
 
-void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env, uint32_t exception,
-                                          int error_code, uintptr_t pc);
+    if (env->insn_flags & ISA_MIPS32R6) {
+        bool has_supervisor = extract32(mask, CP0St_KSU, 2) == 0x3;
+#if defined(TARGET_MIPS64)
+        uint32_t ksux = (1 << CP0St_KX) & val;
+        ksux |= (ksux >> 1) & val; /* KX = 0 forces SX to be 0 */
+        ksux |= (ksux >> 1) & val; /* SX = 0 forces UX to be 0 */
+        val = (val & ~(7 << CP0St_UX)) | ksux;
+#endif
+        if (has_supervisor && extract32(val, CP0St_KSU, 2) == 0x3) {
+            mask &= ~(3 << CP0St_KSU);
+        }
+        mask &= ~(((1 << CP0St_SR) | (1 << CP0St_NMI)) & val);
+    }
+
+    env->CP0_Status = (old & ~mask) | (val & mask);
+#if defined(TARGET_MIPS64)
+    if ((env->CP0_Status ^ old) & (old & (7 << CP0St_UX))) {
+        /* Access to at least one of the 64-bit segments has been disabled */
+        cpu_mips_tlb_flush(env, 1);
+    }
+#endif
+    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
+        sync_c0_status(env, env, env->current_tc);
+    } else {
+        compute_hflags(env);
+    }
+}
+
+static inline void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val)
+{
+    uint32_t mask = 0x00C00300;
+    uint32_t old = env->CP0_Cause;
+    int i;
+
+    if (env->insn_flags & ISA_MIPS32R2) {
+        mask |= 1 << CP0Ca_DC;
+    }
+    if (env->insn_flags & ISA_MIPS32R6) {
+        mask &= ~((1 << CP0Ca_WP) & val);
+    }
+
+    env->CP0_Cause = (env->CP0_Cause & ~mask) | (val & mask);
+
+    if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
+        if (env->CP0_Cause & (1 << CP0Ca_DC)) {
+            cpu_mips_stop_count(env);
+        } else {
+            cpu_mips_start_count(env);
+        }
+    }
+
+    /* Set/reset software interrupts */
+    for (i = 0 ; i < 2 ; i++) {
+        if ((old ^ env->CP0_Cause) & (1 << (CP0Ca_IP + i))) {
+            cpu_mips_soft_irq(env, i, env->CP0_Cause & (1 << (CP0Ca_IP + i)));
+        }
+    }
+}
+#endif
+
+static inline void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env,
+                                                        uint32_t exception,
+                                                        int error_code,
+                                                        uintptr_t pc)
+{
+    CPUState *cs = CPU(mips_env_get_cpu(env));
+
+    if (exception < EXCP_SC) {
+        qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n",
+                      __func__, exception, error_code);
+    }
+    cs->exception_index = exception;
+    env->error_code = error_code;
+
+    cpu_loop_exit_restore(cs, pc);
+}
 
 static inline void QEMU_NORETURN do_raise_exception(CPUMIPSState *env,
                                                     uint32_t exception,
@@ -1066,4 +1133,4 @@ static inline void QEMU_NORETURN do_raise_exception(CPUMIPSState *env,
     do_raise_exception_err(env, exception, 0, pc);
 }
 
-#endif /* MIPS_CPU_H */
+#endif /* !defined (__MIPS_CPU_H__) */
index 7c68228..b0b4a32 100644 (file)
@@ -19,7 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
 
 int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
@@ -90,9 +89,11 @@ int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
     if (env->CP0_Config1 & (1 << CP0C1_FP) && n >= 38 && n < 72) {
         switch (n) {
         case 70:
-            env->active_fpu.fcr31 = (tmp & env->active_fpu.fcr31_rw_bitmask) |
-                  (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask));
-            restore_fp_status(env);
+            env->active_fpu.fcr31 = tmp & 0xFF83FFFF;
+            /* set rounding mode */
+            restore_rounding_mode(env);
+            /* set flush-to-zero mode */
+            restore_flush_mode(env);
             break;
         case 71:
             /* FIR is read-only.  Ignore writes.  */
index c864b15..cfea177 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "cpu.h"
 #include "sysemu/kvm.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "exec/log.h"
 
@@ -67,7 +66,7 @@ int fixed_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
 int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
                      target_ulong address, int rw, int access_type)
 {
-    uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+    uint8_t ASID = env->CP0_EntryHi & 0xFF;
     int i;
 
     for (i = 0; i < env->tlb->tlb_in_use; i++) {
@@ -222,114 +221,6 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
     }
     return ret;
 }
-
-void cpu_mips_tlb_flush(CPUMIPSState *env, int flush_global)
-{
-    MIPSCPU *cpu = mips_env_get_cpu(env);
-
-    /* Flush qemu's TLB and discard all shadowed entries.  */
-    tlb_flush(CPU(cpu), flush_global);
-    env->tlb->tlb_in_use = env->tlb->nb_tlb;
-}
-
-/* Called for updates to CP0_Status.  */
-void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc)
-{
-    int32_t tcstatus, *tcst;
-    uint32_t v = cpu->CP0_Status;
-    uint32_t cu, mx, asid, ksu;
-    uint32_t mask = ((1 << CP0TCSt_TCU3)
-                       | (1 << CP0TCSt_TCU2)
-                       | (1 << CP0TCSt_TCU1)
-                       | (1 << CP0TCSt_TCU0)
-                       | (1 << CP0TCSt_TMX)
-                       | (3 << CP0TCSt_TKSU)
-                       | (0xff << CP0TCSt_TASID));
-
-    cu = (v >> CP0St_CU0) & 0xf;
-    mx = (v >> CP0St_MX) & 0x1;
-    ksu = (v >> CP0St_KSU) & 0x3;
-    asid = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
-
-    tcstatus = cu << CP0TCSt_TCU0;
-    tcstatus |= mx << CP0TCSt_TMX;
-    tcstatus |= ksu << CP0TCSt_TKSU;
-    tcstatus |= asid;
-
-    if (tc == cpu->current_tc) {
-        tcst = &cpu->active_tc.CP0_TCStatus;
-    } else {
-        tcst = &cpu->tcs[tc].CP0_TCStatus;
-    }
-
-    *tcst &= ~mask;
-    *tcst |= tcstatus;
-    compute_hflags(cpu);
-}
-
-void cpu_mips_store_status(CPUMIPSState *env, target_ulong val)
-{
-    uint32_t mask = env->CP0_Status_rw_bitmask;
-    target_ulong old = env->CP0_Status;
-
-    if (env->insn_flags & ISA_MIPS32R6) {
-        bool has_supervisor = extract32(mask, CP0St_KSU, 2) == 0x3;
-#if defined(TARGET_MIPS64)
-        uint32_t ksux = (1 << CP0St_KX) & val;
-        ksux |= (ksux >> 1) & val; /* KX = 0 forces SX to be 0 */
-        ksux |= (ksux >> 1) & val; /* SX = 0 forces UX to be 0 */
-        val = (val & ~(7 << CP0St_UX)) | ksux;
-#endif
-        if (has_supervisor && extract32(val, CP0St_KSU, 2) == 0x3) {
-            mask &= ~(3 << CP0St_KSU);
-        }
-        mask &= ~(((1 << CP0St_SR) | (1 << CP0St_NMI)) & val);
-    }
-
-    env->CP0_Status = (old & ~mask) | (val & mask);
-#if defined(TARGET_MIPS64)
-    if ((env->CP0_Status ^ old) & (old & (7 << CP0St_UX))) {
-        /* Access to at least one of the 64-bit segments has been disabled */
-        cpu_mips_tlb_flush(env, 1);
-    }
-#endif
-    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
-        sync_c0_status(env, env, env->current_tc);
-    } else {
-        compute_hflags(env);
-    }
-}
-
-void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val)
-{
-    uint32_t mask = 0x00C00300;
-    uint32_t old = env->CP0_Cause;
-    int i;
-
-    if (env->insn_flags & ISA_MIPS32R2) {
-        mask |= 1 << CP0Ca_DC;
-    }
-    if (env->insn_flags & ISA_MIPS32R6) {
-        mask &= ~((1 << CP0Ca_WP) & val);
-    }
-
-    env->CP0_Cause = (env->CP0_Cause & ~mask) | (val & mask);
-
-    if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
-        if (env->CP0_Cause & (1 << CP0Ca_DC)) {
-            cpu_mips_stop_count(env);
-        } else {
-            cpu_mips_start_count(env);
-        }
-    }
-
-    /* Set/reset software interrupts */
-    for (i = 0 ; i < 2 ; i++) {
-        if ((old ^ env->CP0_Cause) & (1 << (CP0Ca_IP + i))) {
-            cpu_mips_soft_irq(env, i, env->CP0_Cause & (1 << (CP0Ca_IP + i)));
-        }
-    }
-}
 #endif
 
 static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
@@ -395,9 +286,8 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
     env->CP0_BadVAddr = address;
     env->CP0_Context = (env->CP0_Context & ~0x007fffff) |
                        ((address >> 9) & 0x007ffff0);
-    env->CP0_EntryHi = (env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask) |
-                       (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) |
-                       (address & (TARGET_PAGE_MASK << 1));
+    env->CP0_EntryHi =
+        (env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1));
 #if defined(TARGET_MIPS64)
     env->CP0_EntryHi &= env->SEGMask;
     env->CP0_XContext =
@@ -641,7 +531,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
         /* EJTAG probe trap enable is not implemented... */
         if (!(env->CP0_Status & (1 << CP0St_EXL)))
             env->CP0_Cause &= ~(1U << CP0Ca_BD);
-        env->active_tc.PC = env->exception_base + 0x480;
+        env->active_tc.PC = (int32_t)0xBFC00480;
         set_hflags_for_handler(env);
         break;
     case EXCP_RESET:
@@ -668,7 +558,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
         env->hflags &= ~(MIPS_HFLAG_KSU);
         if (!(env->CP0_Status & (1 << CP0St_EXL)))
             env->CP0_Cause &= ~(1U << CP0Ca_BD);
-        env->active_tc.PC = env->exception_base;
+        env->active_tc.PC = (int32_t)0xBFC00000;
         set_hflags_for_handler(env);
         break;
     case EXCP_EXT_INTERRUPT:
@@ -850,7 +740,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
         }
         env->hflags &= ~MIPS_HFLAG_BMASK;
         if (env->CP0_Status & (1 << CP0St_BEV)) {
-            env->active_tc.PC = env->exception_base + 0x200;
+            env->active_tc.PC = (int32_t)0xBFC00200;
         } else {
             env->active_tc.PC = (int32_t)(env->CP0_EBase & ~0x3ff);
         }
@@ -899,7 +789,7 @@ void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra)
     r4k_tlb_t *tlb;
     target_ulong addr;
     target_ulong end;
-    uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+    uint8_t ASID = env->CP0_EntryHi & 0xFF;
     target_ulong mask;
 
     tlb = &env->tlb->mmu.r4k.tlb[idx];
@@ -950,20 +840,3 @@ void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra)
     }
 }
 #endif
-
-void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env,
-                                          uint32_t exception,
-                                          int error_code,
-                                          uintptr_t pc)
-{
-    CPUState *cs = CPU(mips_env_get_cpu(env));
-
-    if (exception < EXCP_SC) {
-        qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n",
-                      __func__, exception, error_code);
-    }
-    cs->exception_index = exception;
-    env->error_code = error_code;
-
-    cpu_loop_exit_restore(cs, pc);
-}
index 666936c..594341d 100644 (file)
@@ -207,6 +207,8 @@ DEF_HELPER_4(ctc1, void, env, tl, i32, i32)
 DEF_HELPER_2(float_cvtd_s, i64, env, i32)
 DEF_HELPER_2(float_cvtd_w, i64, env, i32)
 DEF_HELPER_2(float_cvtd_l, i64, env, i64)
+DEF_HELPER_2(float_cvtl_d, i64, env, i64)
+DEF_HELPER_2(float_cvtl_s, i64, env, i32)
 DEF_HELPER_2(float_cvtps_pw, i64, env, i64)
 DEF_HELPER_2(float_cvtpw_ps, i64, env, i64)
 DEF_HELPER_2(float_cvts_d, i32, env, i64)
@@ -214,12 +216,14 @@ DEF_HELPER_2(float_cvts_w, i32, env, i32)
 DEF_HELPER_2(float_cvts_l, i32, env, i64)
 DEF_HELPER_2(float_cvts_pl, i32, env, i32)
 DEF_HELPER_2(float_cvts_pu, i32, env, i32)
+DEF_HELPER_2(float_cvtw_s, i32, env, i32)
+DEF_HELPER_2(float_cvtw_d, i32, env, i64)
 
 DEF_HELPER_3(float_addr_ps, i64, env, i64, i64)
 DEF_HELPER_3(float_mulr_ps, i64, env, i64, i64)
 
-DEF_HELPER_FLAGS_2(float_class_s, TCG_CALL_NO_RWG_SE, i32, env, i32)
-DEF_HELPER_FLAGS_2(float_class_d, TCG_CALL_NO_RWG_SE, i64, env, i64)
+DEF_HELPER_FLAGS_1(float_class_s, TCG_CALL_NO_RWG_SE, i32, i32)
+DEF_HELPER_FLAGS_1(float_class_d, TCG_CALL_NO_RWG_SE, i64, i64)
 
 #define FOP_PROTO(op)                                     \
 DEF_HELPER_4(float_ ## op ## _s, i32, env, i32, i32, i32) \
@@ -238,20 +242,14 @@ FOP_PROTO(mina)
 #undef FOP_PROTO
 
 #define FOP_PROTO(op)                            \
-DEF_HELPER_2(float_ ## op ## _l_s, i64, env, i32) \
-DEF_HELPER_2(float_ ## op ## _l_d, i64, env, i64) \
-DEF_HELPER_2(float_ ## op ## _w_s, i32, env, i32) \
-DEF_HELPER_2(float_ ## op ## _w_d, i32, env, i64)
-FOP_PROTO(cvt)
+DEF_HELPER_2(float_ ## op ## l_s, i64, env, i32) \
+DEF_HELPER_2(float_ ## op ## l_d, i64, env, i64) \
+DEF_HELPER_2(float_ ## op ## w_s, i32, env, i32) \
+DEF_HELPER_2(float_ ## op ## w_d, i32, env, i64)
 FOP_PROTO(round)
 FOP_PROTO(trunc)
 FOP_PROTO(ceil)
 FOP_PROTO(floor)
-FOP_PROTO(cvt_2008)
-FOP_PROTO(round_2008)
-FOP_PROTO(trunc_2008)
-FOP_PROTO(ceil_2008)
-FOP_PROTO(floor_2008)
 #undef FOP_PROTO
 
 #define FOP_PROTO(op)                            \
index dcf5fbb..950bc05 100644 (file)
 
 #include "qemu/osdep.h"
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 
 #include <linux/kvm.h>
 
 #include "qemu-common.h"
-#include "cpu.h"
 #include "qemu/error-report.h"
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
+#include "cpu.h"
 #include "sysemu/cpus.h"
 #include "kvm_mips.h"
 #include "exec/memattrs.h"
@@ -1043,17 +1044,6 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
     return 0;
 }
 
-int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
-                                int vector, PCIDevice *dev)
-{
-    return 0;
-}
-
-int kvm_arch_release_virq_post(int virq)
-{
-    return 0;
-}
-
 int kvm_arch_msi_data_to_gsi(uint32_t data)
 {
     abort();
index ae957f3..54f5965 100644 (file)
@@ -9,8 +9,8 @@
  * Authors: Sanjay Lal <sanjayl@kymasys.com>
 */
 
-#ifndef KVM_MIPS_H
-#define KVM_MIPS_H
+#ifndef __KVM_MIPS_H__
+#define __KVM_MIPS_H__
 
 /**
  * kvm_mips_reset_vcpu:
@@ -23,4 +23,4 @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu);
 int kvm_mips_set_interrupt(MIPSCPU *cpu, int irq, int level);
 int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level);
 
-#endif /* KVM_MIPS_H */
+#endif /* __KVM_MIPS_H__ */
index a27f2f1..22bca18 100644 (file)
@@ -1,9 +1,7 @@
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "hw/hw.h"
+
 #include "cpu.h"
-#include "migration/cpu.h"
 
 static int cpu_post_load(void *opaque, int version_id)
 {
@@ -132,7 +130,7 @@ static int get_tlb(QEMUFile *f, void *pv, size_t size)
 
     qemu_get_betls(f, &v->VPN);
     qemu_get_be32s(f, &v->PageMask);
-    qemu_get_be16s(f, &v->ASID);
+    qemu_get_8s(f, &v->ASID);
     qemu_get_be16s(f, &flags);
     v->G = (flags >> 10) & 1;
     v->C0 = (flags >> 7) & 3;
@@ -156,7 +154,7 @@ static void put_tlb(QEMUFile *f, void *pv, size_t size)
 {
     r4k_tlb_t *v = pv;
 
-    uint16_t asid = v->ASID;
+    uint8_t asid = v->ASID;
     uint16_t flags = ((v->EHINV << 15) |
                       (v->RI1 << 14) |
                       (v->RI0 << 13) |
@@ -172,7 +170,7 @@ static void put_tlb(QEMUFile *f, void *pv, size_t size)
 
     qemu_put_betls(f, &v->VPN);
     qemu_put_be32s(f, &v->PageMask);
-    qemu_put_be16s(f, &asid);
+    qemu_put_8s(f, &asid);
     qemu_put_be16s(f, &flags);
     qemu_put_be64s(f, &v->PFN[0]);
     qemu_put_be64s(f, &v->PFN[1]);
@@ -192,8 +190,8 @@ const VMStateInfo vmstate_info_tlb = {
 
 const VMStateDescription vmstate_tlb = {
     .name = "cpu/tlb",
-    .version_id = 2,
-    .minimum_version_id = 2,
+    .version_id = 1,
+    .minimum_version_id = 1,
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(nb_tlb, CPUMIPSTLBContext),
         VMSTATE_UINT32(tlb_in_use, CPUMIPSTLBContext),
index 047554e..53b185e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef QEMU_MIPS_DEFS_H
-#define QEMU_MIPS_DEFS_H
+#if !defined (__QEMU_MIPS_DEFS_H__)
+#define __QEMU_MIPS_DEFS_H__
 
 /* If we want to use host float regs... */
 //#define USE_HOST_FLOAT_REGS
@@ -88,4 +88,4 @@
    Note that we still maintain Count/Compare to match the host clock. */
 //#define MIPS_STRICT_STANDARD 1
 
-#endif /* QEMU_MIPS_DEFS_H */
+#endif /* !defined (__QEMU_MIPS_DEFS_H__) */
index a7aefba..ed235de 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "qemu/log.h"
 #include "exec/helper-proto.h"
 #include "exec/softmmu-semi.h"
 #include "exec/semihost.h"
index 1fdb0d9..654a0d2 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 
 /* Data format min and max values */
@@ -1495,11 +1494,11 @@ MSA_UNOP_DF(pcnt)
 #define FLOAT_ONE32 make_float32(0x3f8 << 20)
 #define FLOAT_ONE64 make_float64(0x3ffULL << 52)
 
-#define FLOAT_SNAN16(s) (float16_default_nan(s) ^ 0x0220)
+#define FLOAT_SNAN16 (float16_default_nan ^ 0x0220)
         /* 0x7c20 */
-#define FLOAT_SNAN32(s) (float32_default_nan(s) ^ 0x00400020)
+#define FLOAT_SNAN32 (float32_default_nan ^ 0x00400020)
         /* 0x7f800020 */
-#define FLOAT_SNAN64(s) (float64_default_nan(s) ^ 0x0008000000000020ULL)
+#define FLOAT_SNAN64 (float64_default_nan ^ 0x0008000000000020ULL)
         /* 0x7ff0000000000020 */
 
 static inline void clear_msacsr_cause(CPUMIPSState *env)
@@ -1612,7 +1611,7 @@ static inline float16 float16_from_float32(int32_t a, flag ieee,
       float16 f_val;
 
       f_val = float32_to_float16((float32)a, ieee, status);
-      f_val = float16_maybe_silence_nan(f_val, status);
+      f_val = float16_maybe_silence_nan(f_val);
 
       return a < 0 ? (f_val | (1 << 15)) : f_val;
 }
@@ -1622,7 +1621,7 @@ static inline float32 float32_from_float64(int64_t a, float_status *status)
       float32 f_val;
 
       f_val = float64_to_float32((float64)a, status);
-      f_val = float32_maybe_silence_nan(f_val, status);
+      f_val = float32_maybe_silence_nan(f_val);
 
       return a < 0 ? (f_val | (1 << 31)) : f_val;
 }
@@ -1633,7 +1632,7 @@ static inline float32 float32_from_float16(int16_t a, flag ieee,
       float32 f_val;
 
       f_val = float16_to_float32((float16)a, ieee, status);
-      f_val = float32_maybe_silence_nan(f_val, status);
+      f_val = float32_maybe_silence_nan(f_val);
 
       return a < 0 ? (f_val | (1 << 31)) : f_val;
 }
@@ -1643,7 +1642,7 @@ static inline float64 float64_from_float32(int32_t a, float_status *status)
       float64 f_val;
 
       f_val = float32_to_float64((float64)a, status);
-      f_val = float64_maybe_silence_nan(f_val, status);
+      f_val = float64_maybe_silence_nan(f_val);
 
       return a < 0 ? (f_val | (1ULL << 63)) : f_val;
 }
@@ -1789,7 +1788,7 @@ static inline int32_t float64_to_q32(float64 a, float_status *status)
         c = update_msacsr(env, CLEAR_IS_INEXACT, 0);                        \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
-            DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
+            DEST = ((FLOAT_SNAN ## BITS >> 6) << 6) | c;                    \
         }                                                                   \
     } while (0)
 
@@ -2388,7 +2387,7 @@ void helper_msa_fsne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
-            DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
+            DEST = ((FLOAT_SNAN ## BITS >> 6) << 6) | c;                    \
         }                                                                   \
     } while (0)
 
@@ -2524,7 +2523,7 @@ void helper_msa_fdiv_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
-            DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
+            DEST = ((FLOAT_SNAN ## BITS >> 6) << 6) | c;                    \
         }                                                                   \
     } while (0)
 
@@ -2643,7 +2642,7 @@ void helper_msa_fexp2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
-            DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
+            DEST = ((FLOAT_SNAN ## BITS >> 6) << 6) | c;                    \
         }                                                                   \
     } while (0)
 
@@ -2694,7 +2693,7 @@ void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0);                      \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
-            DEST = ((FLOAT_SNAN ## XBITS(status) >> 6) << 6) | c;           \
+            DEST = ((FLOAT_SNAN ## XBITS >> 6) << 6) | c;                   \
         }                                                                   \
     } while (0)
 
@@ -2731,9 +2730,9 @@ void helper_msa_ftq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
     msa_move_v(pwd, pwx);
 }
 
-#define NUMBER_QNAN_PAIR(ARG1, ARG2, BITS, STATUS)      \
-    !float ## BITS ## _is_any_nan(ARG1)                 \
-    && float ## BITS ## _is_quiet_nan(ARG2, STATUS)
+#define NUMBER_QNAN_PAIR(ARG1, ARG2, BITS)      \
+    !float ## BITS ## _is_any_nan(ARG1)         \
+    && float ## BITS ## _is_quiet_nan(ARG2)
 
 #define MSA_FLOAT_MAXOP(DEST, OP, ARG1, ARG2, BITS)                         \
     do {                                                                    \
@@ -2745,18 +2744,18 @@ void helper_msa_ftq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         c = update_msacsr(env, 0, 0);                                       \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
-            DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
+            DEST = ((FLOAT_SNAN ## BITS >> 6) << 6) | c;                    \
         }                                                                   \
     } while (0)
 
-#define FMAXMIN_A(F, G, X, _S, _T, BITS, STATUS)                    \
+#define FMAXMIN_A(F, G, X, _S, _T, BITS)                            \
     do {                                                            \
         uint## BITS ##_t S = _S, T = _T;                            \
         uint## BITS ##_t as, at, xs, xt, xd;                        \
-        if (NUMBER_QNAN_PAIR(S, T, BITS, STATUS)) {                 \
+        if (NUMBER_QNAN_PAIR(S, T, BITS)) {                         \
             T = S;                                                  \
         }                                                           \
-        else if (NUMBER_QNAN_PAIR(T, S, BITS, STATUS)) {            \
+        else if (NUMBER_QNAN_PAIR(T, S, BITS)) {                    \
             S = T;                                                  \
         }                                                           \
         as = float## BITS ##_abs(S);                                \
@@ -2770,7 +2769,6 @@ void helper_msa_ftq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
 void helper_msa_fmin_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         uint32_t ws, uint32_t wt)
 {
-    float_status *status = &env->active_tc.msa_fp_status;
     wr_t wx, *pwx = &wx;
     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
@@ -2782,9 +2780,9 @@ void helper_msa_fmin_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
     switch (df) {
     case DF_WORD:
         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
-            if (NUMBER_QNAN_PAIR(pws->w[i], pwt->w[i], 32, status)) {
+            if (NUMBER_QNAN_PAIR(pws->w[i], pwt->w[i], 32)) {
                 MSA_FLOAT_MAXOP(pwx->w[i], min, pws->w[i], pws->w[i], 32);
-            } else if (NUMBER_QNAN_PAIR(pwt->w[i], pws->w[i], 32, status)) {
+            } else if (NUMBER_QNAN_PAIR(pwt->w[i], pws->w[i], 32)) {
                 MSA_FLOAT_MAXOP(pwx->w[i], min, pwt->w[i], pwt->w[i], 32);
             } else {
                 MSA_FLOAT_MAXOP(pwx->w[i], min, pws->w[i], pwt->w[i], 32);
@@ -2793,9 +2791,9 @@ void helper_msa_fmin_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         break;
     case DF_DOUBLE:
         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
-            if (NUMBER_QNAN_PAIR(pws->d[i], pwt->d[i], 64, status)) {
+            if (NUMBER_QNAN_PAIR(pws->d[i], pwt->d[i], 64)) {
                 MSA_FLOAT_MAXOP(pwx->d[i], min, pws->d[i], pws->d[i], 64);
-            } else if (NUMBER_QNAN_PAIR(pwt->d[i], pws->d[i], 64, status)) {
+            } else if (NUMBER_QNAN_PAIR(pwt->d[i], pws->d[i], 64)) {
                 MSA_FLOAT_MAXOP(pwx->d[i], min, pwt->d[i], pwt->d[i], 64);
             } else {
                 MSA_FLOAT_MAXOP(pwx->d[i], min, pws->d[i], pwt->d[i], 64);
@@ -2814,7 +2812,6 @@ void helper_msa_fmin_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
 void helper_msa_fmin_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         uint32_t ws, uint32_t wt)
 {
-    float_status *status = &env->active_tc.msa_fp_status;
     wr_t wx, *pwx = &wx;
     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
@@ -2826,12 +2823,12 @@ void helper_msa_fmin_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
     switch (df) {
     case DF_WORD:
         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
-            FMAXMIN_A(min, max, pwx->w[i], pws->w[i], pwt->w[i], 32, status);
+            FMAXMIN_A(min, max, pwx->w[i], pws->w[i], pwt->w[i], 32);
         }
         break;
     case DF_DOUBLE:
         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
-            FMAXMIN_A(min, max, pwx->d[i], pws->d[i], pwt->d[i], 64, status);
+            FMAXMIN_A(min, max, pwx->d[i], pws->d[i], pwt->d[i], 64);
         }
         break;
     default:
@@ -2846,7 +2843,6 @@ void helper_msa_fmin_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
 void helper_msa_fmax_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         uint32_t ws, uint32_t wt)
 {
-    float_status *status = &env->active_tc.msa_fp_status;
     wr_t wx, *pwx = &wx;
     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
@@ -2858,9 +2854,9 @@ void helper_msa_fmax_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
     switch (df) {
     case DF_WORD:
         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
-            if (NUMBER_QNAN_PAIR(pws->w[i], pwt->w[i], 32, status)) {
+            if (NUMBER_QNAN_PAIR(pws->w[i], pwt->w[i], 32)) {
                 MSA_FLOAT_MAXOP(pwx->w[i], max, pws->w[i], pws->w[i], 32);
-            } else if (NUMBER_QNAN_PAIR(pwt->w[i], pws->w[i], 32, status)) {
+            } else if (NUMBER_QNAN_PAIR(pwt->w[i], pws->w[i], 32)) {
                 MSA_FLOAT_MAXOP(pwx->w[i], max, pwt->w[i], pwt->w[i], 32);
             } else {
                 MSA_FLOAT_MAXOP(pwx->w[i], max, pws->w[i], pwt->w[i], 32);
@@ -2869,9 +2865,9 @@ void helper_msa_fmax_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         break;
     case DF_DOUBLE:
         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
-            if (NUMBER_QNAN_PAIR(pws->d[i], pwt->d[i], 64, status)) {
+            if (NUMBER_QNAN_PAIR(pws->d[i], pwt->d[i], 64)) {
                 MSA_FLOAT_MAXOP(pwx->d[i], max, pws->d[i], pws->d[i], 64);
-            } else if (NUMBER_QNAN_PAIR(pwt->d[i], pws->d[i], 64, status)) {
+            } else if (NUMBER_QNAN_PAIR(pwt->d[i], pws->d[i], 64)) {
                 MSA_FLOAT_MAXOP(pwx->d[i], max, pwt->d[i], pwt->d[i], 64);
             } else {
                 MSA_FLOAT_MAXOP(pwx->d[i], max, pws->d[i], pwt->d[i], 64);
@@ -2890,7 +2886,6 @@ void helper_msa_fmax_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
 void helper_msa_fmax_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         uint32_t ws, uint32_t wt)
 {
-    float_status *status = &env->active_tc.msa_fp_status;
     wr_t wx, *pwx = &wx;
     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
@@ -2902,12 +2897,12 @@ void helper_msa_fmax_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
     switch (df) {
     case DF_WORD:
         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
-            FMAXMIN_A(max, min, pwx->w[i], pws->w[i], pwt->w[i], 32, status);
+            FMAXMIN_A(max, min, pwx->w[i], pws->w[i], pwt->w[i], 32);
         }
         break;
     case DF_DOUBLE:
         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
-            FMAXMIN_A(max, min, pwx->d[i], pws->d[i], pwt->d[i], 64, status);
+            FMAXMIN_A(max, min, pwx->d[i], pws->d[i], pwt->d[i], 64);
         }
         break;
     default:
@@ -2922,18 +2917,16 @@ void helper_msa_fmax_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
 void helper_msa_fclass_df(CPUMIPSState *env, uint32_t df,
         uint32_t wd, uint32_t ws)
 {
-    float_status* status = &env->active_tc.msa_fp_status;
-
     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
     if (df == DF_WORD) {
-        pwd->w[0] = float_class_s(pws->w[0], status);
-        pwd->w[1] = float_class_s(pws->w[1], status);
-        pwd->w[2] = float_class_s(pws->w[2], status);
-        pwd->w[3] = float_class_s(pws->w[3], status);
+        pwd->w[0] = helper_float_class_s(pws->w[0]);
+        pwd->w[1] = helper_float_class_s(pws->w[1]);
+        pwd->w[2] = helper_float_class_s(pws->w[2]);
+        pwd->w[3] = helper_float_class_s(pws->w[3]);
     } else {
-        pwd->d[0] = float_class_d(pws->d[0], status);
-        pwd->d[1] = float_class_d(pws->d[1], status);
+        pwd->d[0] = helper_float_class_d(pws->d[0]);
+        pwd->d[1] = helper_float_class_d(pws->d[1]);
     }
 }
 
@@ -2947,7 +2940,7 @@ void helper_msa_fclass_df(CPUMIPSState *env, uint32_t df,
         c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0);                      \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
-            DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
+            DEST = ((FLOAT_SNAN ## BITS >> 6) << 6) | c;                    \
         } else if (float ## BITS ## _is_any_nan(ARG)) {                     \
             DEST = 0;                                                       \
         }                                                                   \
@@ -3051,12 +3044,12 @@ void helper_msa_fsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         set_float_exception_flags(0, status);                               \
         DEST = float ## BITS ## _ ## div(FLOAT_ONE ## BITS, ARG, status);   \
         c = update_msacsr(env, float ## BITS ## _is_infinity(ARG) ||        \
-                          float ## BITS ## _is_quiet_nan(DEST, status) ?    \
+                          float ## BITS ## _is_quiet_nan(DEST) ?            \
                           0 : RECIPROCAL_INEXACT,                           \
                           IS_DENORMAL(DEST, BITS));                         \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
-            DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
+            DEST = ((FLOAT_SNAN ## BITS >> 6) << 6) | c;                    \
         }                                                                   \
     } while (0)
 
@@ -3172,7 +3165,7 @@ void helper_msa_frint_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
-            DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
+            DEST = ((FLOAT_SNAN ## BITS >> 6) << 6) | c;                    \
         }                                                                   \
     } while (0)
 
index ea2f2ab..ba847ab 100644 (file)
@@ -20,7 +20,6 @@
 #include "cpu.h"
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "sysemu/kvm.h"
 
@@ -133,8 +132,10 @@ static inline uint64_t get_HILO(CPUMIPSState *env)
 
 static inline target_ulong set_HIT0_LO(CPUMIPSState *env, uint64_t HILO)
 {
+    target_ulong tmp;
     env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF);
-    return env->active_tc.HI[0] = (int32_t)(HILO >> 32);
+    tmp = env->active_tc.HI[0] = (int32_t)(HILO >> 32);
+    return tmp;
 }
 
 static inline target_ulong set_HI_LOT0(CPUMIPSState *env, uint64_t HILO)
@@ -679,7 +680,7 @@ static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc,
 
     tcu = (v >> CP0TCSt_TCU0) & 0xf;
     tmx = (v >> CP0TCSt_TMX) & 0x1;
-    tasid = v & cpu->CP0_EntryHi_ASID_mask;
+    tasid = v & 0xff;
     tksu = (v >> CP0TCSt_TKSU) & 0x3;
 
     status = tcu << CP0St_CU0;
@@ -690,7 +691,7 @@ static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc,
     cpu->CP0_Status |= status;
 
     /* Sync the TASID with EntryHi.  */
-    cpu->CP0_EntryHi &= ~cpu->CP0_EntryHi_ASID_mask;
+    cpu->CP0_EntryHi &= ~0xff;
     cpu->CP0_EntryHi |= tasid;
 
     compute_hflags(cpu);
@@ -702,7 +703,7 @@ static void sync_c0_entryhi(CPUMIPSState *cpu, int tc)
     int32_t *tcst;
     uint32_t asid, v = cpu->CP0_EntryHi;
 
-    asid = v & cpu->CP0_EntryHi_ASID_mask;
+    asid = v & 0xff;
 
     if (tc == cpu->current_tc) {
         tcst = &cpu->active_tc.CP0_TCStatus;
@@ -710,7 +711,7 @@ static void sync_c0_entryhi(CPUMIPSState *cpu, int tc)
         tcst = &cpu->tcs[tc].CP0_TCStatus;
     }
 
-    *tcst &= ~cpu->CP0_EntryHi_ASID_mask;
+    *tcst &= ~0xff;
     *tcst |= asid;
 }
 
@@ -1403,7 +1404,7 @@ void helper_mtc0_count(CPUMIPSState *env, target_ulong arg1)
 void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1)
 {
     target_ulong old, val, mask;
-    mask = (TARGET_PAGE_MASK << 1) | env->CP0_EntryHi_ASID_mask;
+    mask = (TARGET_PAGE_MASK << 1) | 0xFF;
     if (((env->CP0_Config4 >> CP0C4_IE) & 0x3) >= 2) {
         mask |= 1 << CP0EnHi_EHINV;
     }
@@ -1429,10 +1430,8 @@ void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1)
         sync_c0_entryhi(env, env->current_tc);
     }
     /* If the ASID changes, flush qemu's TLB.  */
-    if ((old & env->CP0_EntryHi_ASID_mask) !=
-        (val & env->CP0_EntryHi_ASID_mask)) {
+    if ((old & 0xFF) != (val & 0xFF))
         cpu_mips_tlb_flush(env, 1);
-    }
 }
 
 void helper_mttc0_entryhi(CPUMIPSState *env, target_ulong arg1)
@@ -1633,8 +1632,7 @@ void helper_mtc0_watchlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
 
 void helper_mtc0_watchhi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
 {
-    int mask = 0x40000FF8 | (env->CP0_EntryHi_ASID_mask << CP0WH_ASID);
-    env->CP0_WatchHi[sel] = arg1 & mask;
+    env->CP0_WatchHi[sel] = (arg1 & 0x40FF0FF8);
     env->CP0_WatchHi[sel] &= ~(env->CP0_WatchHi[sel] & arg1 & 0x7);
 }
 
@@ -1992,7 +1990,7 @@ static void r4k_fill_tlb(CPUMIPSState *env, int idx)
 #if defined(TARGET_MIPS64)
     tlb->VPN &= env->SEGMask;
 #endif
-    tlb->ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+    tlb->ASID = env->CP0_EntryHi & 0xFF;
     tlb->PageMask = env->CP0_PageMask;
     tlb->G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;
     tlb->V0 = (env->CP0_EntryLo0 & 2) != 0;
@@ -2013,7 +2011,7 @@ void r4k_helper_tlbinv(CPUMIPSState *env)
 {
     int idx;
     r4k_tlb_t *tlb;
-    uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+    uint8_t ASID = env->CP0_EntryHi & 0xFF;
 
     for (idx = 0; idx < env->tlb->nb_tlb; idx++) {
         tlb = &env->tlb->mmu.r4k.tlb[idx];
@@ -2039,7 +2037,7 @@ void r4k_helper_tlbwi(CPUMIPSState *env)
     r4k_tlb_t *tlb;
     int idx;
     target_ulong VPN;
-    uint16_t ASID;
+    uint8_t ASID;
     bool G, V0, D0, V1, D1;
 
     idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb;
@@ -2048,7 +2046,7 @@ void r4k_helper_tlbwi(CPUMIPSState *env)
 #if defined(TARGET_MIPS64)
     VPN &= env->SEGMask;
 #endif
-    ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+    ASID = env->CP0_EntryHi & 0xff;
     G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;
     V0 = (env->CP0_EntryLo0 & 2) != 0;
     D0 = (env->CP0_EntryLo0 & 4) != 0;
@@ -2081,10 +2079,10 @@ void r4k_helper_tlbp(CPUMIPSState *env)
     target_ulong mask;
     target_ulong tag;
     target_ulong VPN;
-    uint16_t ASID;
+    uint8_t ASID;
     int i;
 
-    ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+    ASID = env->CP0_EntryHi & 0xFF;
     for (i = 0; i < env->tlb->nb_tlb; i++) {
         tlb = &env->tlb->mmu.r4k.tlb[i];
         /* 1k pages are not supported. */
@@ -2136,10 +2134,10 @@ static inline uint64_t get_entrylo_pfn_from_tlb(uint64_t tlb_pfn)
 void r4k_helper_tlbr(CPUMIPSState *env)
 {
     r4k_tlb_t *tlb;
-    uint16_t ASID;
+    uint8_t ASID;
     int idx;
 
-    ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+    ASID = env->CP0_EntryHi & 0xFF;
     idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb;
     tlb = &env->tlb->mmu.r4k.tlb[idx];
 
@@ -2384,8 +2382,8 @@ void helper_wait(CPUMIPSState *env)
 #if !defined(CONFIG_USER_ONLY)
 
 void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
-                                  MMUAccessType access_type,
-                                  int mmu_idx, uintptr_t retaddr)
+                                  int access_type, int is_user,
+                                  uintptr_t retaddr)
 {
     MIPSCPU *cpu = MIPS_CPU(cs);
     CPUMIPSState *env = &cpu->env;
@@ -2406,12 +2404,12 @@ void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
     do_raise_exception_err(env, excp, error_code, retaddr);
 }
 
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr)
 {
     int ret;
 
-    ret = mips_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = mips_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (ret) {
         MIPSCPU *cpu = MIPS_CPU(cs);
         CPUMIPSState *env = &cpu->env;
@@ -2450,7 +2448,6 @@ void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr,
 
 #define FLOAT_TWO32 make_float32(1 << 30)
 #define FLOAT_TWO64 make_float64(1ULL << 62)
-
 #define FP_TO_INT32_OVERFLOW 0x7fffffff
 #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
 
@@ -2578,13 +2575,21 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
                      ((arg1 & 0x4) << 22);
         break;
     case 31:
-        env->active_fpu.fcr31 = (arg1 & env->active_fpu.fcr31_rw_bitmask) |
-               (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask));
+        if (env->insn_flags & ISA_MIPS32R6) {
+            uint32_t mask = 0xfefc0000;
+            env->active_fpu.fcr31 = (arg1 & ~mask) |
+                (env->active_fpu.fcr31 & mask);
+        } else if (!(arg1 & 0x007c0000)) {
+            env->active_fpu.fcr31 = arg1;
+        }
         break;
     default:
         return;
     }
-    restore_fp_status(env);
+    /* set rounding mode */
+    restore_rounding_mode(env);
+    /* set flush-to-zero mode */
+    restore_flush_mode(env);
     set_float_exception_flags(0, &env->active_fpu.fp_status);
     if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) & GET_FP_CAUSE(env->active_fpu.fcr31))
         do_raise_exception(env, EXCP_FPE, GETPC());
@@ -2655,7 +2660,7 @@ uint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0)
     uint64_t fdt2;
 
     fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status);
-    fdt2 = float64_maybe_silence_nan(fdt2, &env->active_fpu.fp_status);
+    fdt2 = float64_maybe_silence_nan(fdt2);
     update_fcr31(env, GETPC());
     return fdt2;
 }
@@ -2678,7 +2683,7 @@ uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0)
     return fdt2;
 }
 
-uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0)
+uint64_t helper_float_cvtl_d(CPUMIPSState *env, uint64_t fdt0)
 {
     uint64_t dt2;
 
@@ -2691,7 +2696,7 @@ uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0)
     return dt2;
 }
 
-uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0)
+uint64_t helper_float_cvtl_s(CPUMIPSState *env, uint32_t fst0)
 {
     uint64_t dt2;
 
@@ -2745,7 +2750,7 @@ uint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0)
     uint32_t fst2;
 
     fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status);
-    fst2 = float32_maybe_silence_nan(fst2, &env->active_fpu.fp_status);
+    fst2 = float32_maybe_silence_nan(fst2);
     update_fcr31(env, GETPC());
     return fst2;
 }
@@ -2786,7 +2791,7 @@ uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0)
     return wt2;
 }
 
-uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0)
+uint32_t helper_float_cvtw_s(CPUMIPSState *env, uint32_t fst0)
 {
     uint32_t wt2;
 
@@ -2799,7 +2804,7 @@ uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0)
     return wt2;
 }
 
-uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0)
+uint32_t helper_float_cvtw_d(CPUMIPSState *env, uint64_t fdt0)
 {
     uint32_t wt2;
 
@@ -2812,7 +2817,7 @@ uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0)
     return wt2;
 }
 
-uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0)
+uint64_t helper_float_roundl_d(CPUMIPSState *env, uint64_t fdt0)
 {
     uint64_t dt2;
 
@@ -2827,7 +2832,7 @@ uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0)
     return dt2;
 }
 
-uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0)
+uint64_t helper_float_roundl_s(CPUMIPSState *env, uint32_t fst0)
 {
     uint64_t dt2;
 
@@ -2842,7 +2847,7 @@ uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0)
     return dt2;
 }
 
-uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0)
+uint32_t helper_float_roundw_d(CPUMIPSState *env, uint64_t fdt0)
 {
     uint32_t wt2;
 
@@ -2857,7 +2862,7 @@ uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0)
     return wt2;
 }
 
-uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0)
+uint32_t helper_float_roundw_s(CPUMIPSState *env, uint32_t fst0)
 {
     uint32_t wt2;
 
@@ -2872,7 +2877,7 @@ uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0)
     return wt2;
 }
 
-uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0)
+uint64_t helper_float_truncl_d(CPUMIPSState *env, uint64_t fdt0)
 {
     uint64_t dt2;
 
@@ -2885,7 +2890,7 @@ uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0)
     return dt2;
 }
 
-uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0)
+uint64_t helper_float_truncl_s(CPUMIPSState *env, uint32_t fst0)
 {
     uint64_t dt2;
 
@@ -2898,7 +2903,7 @@ uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0)
     return dt2;
 }
 
-uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0)
+uint32_t helper_float_truncw_d(CPUMIPSState *env, uint64_t fdt0)
 {
     uint32_t wt2;
 
@@ -2911,7 +2916,7 @@ uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0)
     return wt2;
 }
 
-uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0)
+uint32_t helper_float_truncw_s(CPUMIPSState *env, uint32_t fst0)
 {
     uint32_t wt2;
 
@@ -2924,7 +2929,7 @@ uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0)
     return wt2;
 }
 
-uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0)
+uint64_t helper_float_ceill_d(CPUMIPSState *env, uint64_t fdt0)
 {
     uint64_t dt2;
 
@@ -2939,7 +2944,7 @@ uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0)
     return dt2;
 }
 
-uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0)
+uint64_t helper_float_ceill_s(CPUMIPSState *env, uint32_t fst0)
 {
     uint64_t dt2;
 
@@ -2954,7 +2959,7 @@ uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0)
     return dt2;
 }
 
-uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0)
+uint32_t helper_float_ceilw_d(CPUMIPSState *env, uint64_t fdt0)
 {
     uint32_t wt2;
 
@@ -2969,7 +2974,7 @@ uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0)
     return wt2;
 }
 
-uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0)
+uint32_t helper_float_ceilw_s(CPUMIPSState *env, uint32_t fst0)
 {
     uint32_t wt2;
 
@@ -2984,7 +2989,7 @@ uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0)
     return wt2;
 }
 
-uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0)
+uint64_t helper_float_floorl_d(CPUMIPSState *env, uint64_t fdt0)
 {
     uint64_t dt2;
 
@@ -2999,7 +3004,7 @@ uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0)
     return dt2;
 }
 
-uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0)
+uint64_t helper_float_floorl_s(CPUMIPSState *env, uint32_t fst0)
 {
     uint64_t dt2;
 
@@ -3014,7 +3019,7 @@ uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0)
     return dt2;
 }
 
-uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0)
+uint32_t helper_float_floorw_d(CPUMIPSState *env, uint64_t fdt0)
 {
     uint32_t wt2;
 
@@ -3029,7 +3034,7 @@ uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0)
     return wt2;
 }
 
-uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0)
+uint32_t helper_float_floorw_s(CPUMIPSState *env, uint32_t fst0)
 {
     uint32_t wt2;
 
@@ -3044,334 +3049,6 @@ uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0)
     return wt2;
 }
 
-uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
-{
-    uint64_t dt2;
-
-    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float64_is_any_nan(fdt0)) {
-            dt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return dt2;
-}
-
-uint64_t helper_float_cvt_2008_l_s(CPUMIPSState *env, uint32_t fst0)
-{
-    uint64_t dt2;
-
-    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float32_is_any_nan(fst0)) {
-            dt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return dt2;
-}
-
-uint32_t helper_float_cvt_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
-{
-    uint32_t wt2;
-
-    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float64_is_any_nan(fdt0)) {
-            wt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return wt2;
-}
-
-uint32_t helper_float_cvt_2008_w_s(CPUMIPSState *env, uint32_t fst0)
-{
-    uint32_t wt2;
-
-    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float32_is_any_nan(fst0)) {
-            wt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return wt2;
-}
-
-uint64_t helper_float_round_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
-{
-    uint64_t dt2;
-
-    set_float_rounding_mode(float_round_nearest_even,
-            &env->active_fpu.fp_status);
-    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
-    restore_rounding_mode(env);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float64_is_any_nan(fdt0)) {
-            dt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return dt2;
-}
-
-uint64_t helper_float_round_2008_l_s(CPUMIPSState *env, uint32_t fst0)
-{
-    uint64_t dt2;
-
-    set_float_rounding_mode(float_round_nearest_even,
-            &env->active_fpu.fp_status);
-    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
-    restore_rounding_mode(env);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float32_is_any_nan(fst0)) {
-            dt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return dt2;
-}
-
-uint32_t helper_float_round_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
-{
-    uint32_t wt2;
-
-    set_float_rounding_mode(float_round_nearest_even,
-            &env->active_fpu.fp_status);
-    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
-    restore_rounding_mode(env);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float64_is_any_nan(fdt0)) {
-            wt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return wt2;
-}
-
-uint32_t helper_float_round_2008_w_s(CPUMIPSState *env, uint32_t fst0)
-{
-    uint32_t wt2;
-
-    set_float_rounding_mode(float_round_nearest_even,
-            &env->active_fpu.fp_status);
-    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
-    restore_rounding_mode(env);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float32_is_any_nan(fst0)) {
-            wt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return wt2;
-}
-
-uint64_t helper_float_trunc_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
-{
-    uint64_t dt2;
-
-    dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float64_is_any_nan(fdt0)) {
-            dt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return dt2;
-}
-
-uint64_t helper_float_trunc_2008_l_s(CPUMIPSState *env, uint32_t fst0)
-{
-    uint64_t dt2;
-
-    dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float32_is_any_nan(fst0)) {
-            dt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return dt2;
-}
-
-uint32_t helper_float_trunc_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
-{
-    uint32_t wt2;
-
-    wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float64_is_any_nan(fdt0)) {
-            wt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return wt2;
-}
-
-uint32_t helper_float_trunc_2008_w_s(CPUMIPSState *env, uint32_t fst0)
-{
-    uint32_t wt2;
-
-    wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float32_is_any_nan(fst0)) {
-            wt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return wt2;
-}
-
-uint64_t helper_float_ceil_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
-{
-    uint64_t dt2;
-
-    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
-    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
-    restore_rounding_mode(env);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float64_is_any_nan(fdt0)) {
-            dt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return dt2;
-}
-
-uint64_t helper_float_ceil_2008_l_s(CPUMIPSState *env, uint32_t fst0)
-{
-    uint64_t dt2;
-
-    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
-    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
-    restore_rounding_mode(env);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float32_is_any_nan(fst0)) {
-            dt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return dt2;
-}
-
-uint32_t helper_float_ceil_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
-{
-    uint32_t wt2;
-
-    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
-    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
-    restore_rounding_mode(env);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float64_is_any_nan(fdt0)) {
-            wt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return wt2;
-}
-
-uint32_t helper_float_ceil_2008_w_s(CPUMIPSState *env, uint32_t fst0)
-{
-    uint32_t wt2;
-
-    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
-    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
-    restore_rounding_mode(env);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float32_is_any_nan(fst0)) {
-            wt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return wt2;
-}
-
-uint64_t helper_float_floor_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
-{
-    uint64_t dt2;
-
-    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
-    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
-    restore_rounding_mode(env);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float64_is_any_nan(fdt0)) {
-            dt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return dt2;
-}
-
-uint64_t helper_float_floor_2008_l_s(CPUMIPSState *env, uint32_t fst0)
-{
-    uint64_t dt2;
-
-    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
-    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
-    restore_rounding_mode(env);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float32_is_any_nan(fst0)) {
-            dt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return dt2;
-}
-
-uint32_t helper_float_floor_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
-{
-    uint32_t wt2;
-
-    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
-    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
-    restore_rounding_mode(env);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float64_is_any_nan(fdt0)) {
-            wt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return wt2;
-}
-
-uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, uint32_t fst0)
-{
-    uint32_t wt2;
-
-    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
-    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
-    restore_rounding_mode(env);
-    if (get_float_exception_flags(&env->active_fpu.fp_status)
-            & float_flag_invalid) {
-        if (float32_is_any_nan(fst0)) {
-            wt2 = 0;
-        }
-    }
-    update_fcr31(env, GETPC());
-    return wt2;
-}
-
 /* unary operations, not modifying fp status  */
 #define FLOAT_UNOP(name)                                       \
 uint64_t helper_float_ ## name ## _d(uint64_t fdt0)                \
@@ -3523,12 +3200,11 @@ FLOAT_RINT(rint_d, 64)
 #define FLOAT_CLASS_POSITIVE_ZERO      0x200
 
 #define FLOAT_CLASS(name, bits)                                      \
-uint ## bits ## _t float_ ## name (uint ## bits ## _t arg,           \
-                                   float_status *status)             \
+uint ## bits ## _t helper_float_ ## name (uint ## bits ## _t arg)    \
 {                                                                    \
-    if (float ## bits ## _is_signaling_nan(arg, status)) {           \
+    if (float ## bits ## _is_signaling_nan(arg)) {                   \
         return FLOAT_CLASS_SIGNALING_NAN;                            \
-    } else if (float ## bits ## _is_quiet_nan(arg, status)) {        \
+    } else if (float ## bits ## _is_quiet_nan(arg)) {                \
         return FLOAT_CLASS_QUIET_NAN;                                \
     } else if (float ## bits ## _is_neg(arg)) {                      \
         if (float ## bits ## _is_infinity(arg)) {                    \
@@ -3551,12 +3227,6 @@ uint ## bits ## _t float_ ## name (uint ## bits ## _t arg,           \
             return FLOAT_CLASS_POSITIVE_NORMAL;                      \
         }                                                            \
     }                                                                \
-}                                                                    \
-                                                                     \
-uint ## bits ## _t helper_float_ ## name (CPUMIPSState *env,         \
-                                          uint ## bits ## _t arg)    \
-{                                                                    \
-    return float_ ## name(arg, &env->active_fpu.fp_status);          \
 }
 
 FLOAT_CLASS(class_s, 32)
index bab52cb..a3a05ec 100644 (file)
@@ -24,7 +24,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "exec/cpu_ldst.h"
 
@@ -1435,8 +1434,6 @@ typedef struct DisasContext {
     bool vp;
     bool cmgcr;
     bool mrp;
-    bool nan2008;
-    bool abs2008;
 } DisasContext;
 
 enum {
@@ -4194,25 +4191,15 @@ static void gen_trap (DisasContext *ctx, uint32_t opc,
     tcg_temp_free(t1);
 }
 
-static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
-{
-    if (unlikely(ctx->singlestep_enabled)) {
-        return false;
-    }
-
-#ifndef CONFIG_USER_ONLY
-    return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
 {
-    if (use_goto_tb(ctx, dest)) {
+    TranslationBlock *tb;
+    tb = ctx->tb;
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
+        likely(!ctx->singlestep_enabled)) {
         tcg_gen_goto_tb(n);
         gen_save_pc(dest);
-        tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         gen_save_pc(dest);
         if (ctx->singlestep_enabled) {
@@ -8892,11 +8879,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i32 fp0 = tcg_temp_new_i32();
 
             gen_load_fpr32(ctx, fp0, fs);
-            if (ctx->abs2008) {
-                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
-            } else {
-                gen_helper_float_abs_s(fp0, fp0);
-            }
+            gen_helper_float_abs_s(fp0, fp0);
             gen_store_fpr32(ctx, fp0, fd);
             tcg_temp_free_i32(fp0);
         }
@@ -8915,11 +8898,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i32 fp0 = tcg_temp_new_i32();
 
             gen_load_fpr32(ctx, fp0, fs);
-            if (ctx->abs2008) {
-                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
-            } else {
-                gen_helper_float_chs_s(fp0, fp0);
-            }
+            gen_helper_float_chs_s(fp0, fp0);
             gen_store_fpr32(ctx, fp0, fd);
             tcg_temp_free_i32(fp0);
         }
@@ -8931,11 +8910,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp64 = tcg_temp_new_i64();
 
             gen_load_fpr32(ctx, fp32, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
-            } else {
-                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
-            }
+            gen_helper_float_roundl_s(fp64, cpu_env, fp32);
             tcg_temp_free_i32(fp32);
             gen_store_fpr64(ctx, fp64, fd);
             tcg_temp_free_i64(fp64);
@@ -8948,11 +8923,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp64 = tcg_temp_new_i64();
 
             gen_load_fpr32(ctx, fp32, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
-            } else {
-                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
-            }
+            gen_helper_float_truncl_s(fp64, cpu_env, fp32);
             tcg_temp_free_i32(fp32);
             gen_store_fpr64(ctx, fp64, fd);
             tcg_temp_free_i64(fp64);
@@ -8965,11 +8936,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp64 = tcg_temp_new_i64();
 
             gen_load_fpr32(ctx, fp32, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
-            } else {
-                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
-            }
+            gen_helper_float_ceill_s(fp64, cpu_env, fp32);
             tcg_temp_free_i32(fp32);
             gen_store_fpr64(ctx, fp64, fd);
             tcg_temp_free_i64(fp64);
@@ -8982,11 +8949,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp64 = tcg_temp_new_i64();
 
             gen_load_fpr32(ctx, fp32, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
-            } else {
-                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
-            }
+            gen_helper_float_floorl_s(fp64, cpu_env, fp32);
             tcg_temp_free_i32(fp32);
             gen_store_fpr64(ctx, fp64, fd);
             tcg_temp_free_i64(fp64);
@@ -8997,11 +8960,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i32 fp0 = tcg_temp_new_i32();
 
             gen_load_fpr32(ctx, fp0, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
-            } else {
-                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
-            }
+            gen_helper_float_roundw_s(fp0, cpu_env, fp0);
             gen_store_fpr32(ctx, fp0, fd);
             tcg_temp_free_i32(fp0);
         }
@@ -9011,11 +8970,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i32 fp0 = tcg_temp_new_i32();
 
             gen_load_fpr32(ctx, fp0, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
-            } else {
-                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
-            }
+            gen_helper_float_truncw_s(fp0, cpu_env, fp0);
             gen_store_fpr32(ctx, fp0, fd);
             tcg_temp_free_i32(fp0);
         }
@@ -9025,11 +8980,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i32 fp0 = tcg_temp_new_i32();
 
             gen_load_fpr32(ctx, fp0, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
-            } else {
-                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
-            }
+            gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
             gen_store_fpr32(ctx, fp0, fd);
             tcg_temp_free_i32(fp0);
         }
@@ -9039,11 +8990,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i32 fp0 = tcg_temp_new_i32();
 
             gen_load_fpr32(ctx, fp0, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
-            } else {
-                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
-            }
+            gen_helper_float_floorw_s(fp0, cpu_env, fp0);
             gen_store_fpr32(ctx, fp0, fd);
             tcg_temp_free_i32(fp0);
         }
@@ -9163,7 +9110,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         {
             TCGv_i32 fp0 = tcg_temp_new_i32();
             gen_load_fpr32(ctx, fp0, fs);
-            gen_helper_float_class_s(fp0, cpu_env, fp0);
+            gen_helper_float_class_s(fp0, fp0);
             gen_store_fpr32(ctx, fp0, fd);
             tcg_temp_free_i32(fp0);
         }
@@ -9292,11 +9239,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i32 fp0 = tcg_temp_new_i32();
 
             gen_load_fpr32(ctx, fp0, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
-            } else {
-                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
-            }
+            gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
             gen_store_fpr32(ctx, fp0, fd);
             tcg_temp_free_i32(fp0);
         }
@@ -9308,11 +9251,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp64 = tcg_temp_new_i64();
 
             gen_load_fpr32(ctx, fp32, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
-            } else {
-                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
-            }
+            gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
             tcg_temp_free_i32(fp32);
             gen_store_fpr64(ctx, fp64, fd);
             tcg_temp_free_i64(fp64);
@@ -9430,11 +9369,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
             gen_load_fpr64(ctx, fp0, fs);
-            if (ctx->abs2008) {
-                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
-            } else {
-                gen_helper_float_abs_d(fp0, fp0);
-            }
+            gen_helper_float_abs_d(fp0, fp0);
             gen_store_fpr64(ctx, fp0, fd);
             tcg_temp_free_i64(fp0);
         }
@@ -9455,11 +9390,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
             gen_load_fpr64(ctx, fp0, fs);
-            if (ctx->abs2008) {
-                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
-            } else {
-                gen_helper_float_chs_d(fp0, fp0);
-            }
+            gen_helper_float_chs_d(fp0, fp0);
             gen_store_fpr64(ctx, fp0, fd);
             tcg_temp_free_i64(fp0);
         }
@@ -9470,11 +9401,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
             gen_load_fpr64(ctx, fp0, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
-            } else {
-                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
-            }
+            gen_helper_float_roundl_d(fp0, cpu_env, fp0);
             gen_store_fpr64(ctx, fp0, fd);
             tcg_temp_free_i64(fp0);
         }
@@ -9485,11 +9412,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
             gen_load_fpr64(ctx, fp0, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
-            } else {
-                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
-            }
+            gen_helper_float_truncl_d(fp0, cpu_env, fp0);
             gen_store_fpr64(ctx, fp0, fd);
             tcg_temp_free_i64(fp0);
         }
@@ -9500,11 +9423,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
             gen_load_fpr64(ctx, fp0, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
-            } else {
-                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
-            }
+            gen_helper_float_ceill_d(fp0, cpu_env, fp0);
             gen_store_fpr64(ctx, fp0, fd);
             tcg_temp_free_i64(fp0);
         }
@@ -9515,11 +9434,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
             gen_load_fpr64(ctx, fp0, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
-            } else {
-                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
-            }
+            gen_helper_float_floorl_d(fp0, cpu_env, fp0);
             gen_store_fpr64(ctx, fp0, fd);
             tcg_temp_free_i64(fp0);
         }
@@ -9531,11 +9446,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp64 = tcg_temp_new_i64();
 
             gen_load_fpr64(ctx, fp64, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
-            } else {
-                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
-            }
+            gen_helper_float_roundw_d(fp32, cpu_env, fp64);
             tcg_temp_free_i64(fp64);
             gen_store_fpr32(ctx, fp32, fd);
             tcg_temp_free_i32(fp32);
@@ -9548,11 +9459,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp64 = tcg_temp_new_i64();
 
             gen_load_fpr64(ctx, fp64, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
-            } else {
-                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
-            }
+            gen_helper_float_truncw_d(fp32, cpu_env, fp64);
             tcg_temp_free_i64(fp64);
             gen_store_fpr32(ctx, fp32, fd);
             tcg_temp_free_i32(fp32);
@@ -9565,11 +9472,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp64 = tcg_temp_new_i64();
 
             gen_load_fpr64(ctx, fp64, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
-            } else {
-                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
-            }
+            gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
             tcg_temp_free_i64(fp64);
             gen_store_fpr32(ctx, fp32, fd);
             tcg_temp_free_i32(fp32);
@@ -9582,11 +9485,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp64 = tcg_temp_new_i64();
 
             gen_load_fpr64(ctx, fp64, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
-            } else {
-                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
-            }
+            gen_helper_float_floorw_d(fp32, cpu_env, fp64);
             tcg_temp_free_i64(fp64);
             gen_store_fpr32(ctx, fp32, fd);
             tcg_temp_free_i32(fp32);
@@ -9709,7 +9608,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
             gen_load_fpr64(ctx, fp0, fs);
-            gen_helper_float_class_d(fp0, cpu_env, fp0);
+            gen_helper_float_class_d(fp0, fp0);
             gen_store_fpr64(ctx, fp0, fd);
             tcg_temp_free_i64(fp0);
         }
@@ -9859,11 +9758,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp64 = tcg_temp_new_i64();
 
             gen_load_fpr64(ctx, fp64, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
-            } else {
-                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
-            }
+            gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
             tcg_temp_free_i64(fp64);
             gen_store_fpr32(ctx, fp32, fd);
             tcg_temp_free_i32(fp32);
@@ -9875,11 +9770,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
             gen_load_fpr64(ctx, fp0, fs);
-            if (ctx->nan2008) {
-                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
-            } else {
-                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
-            }
+            gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
             gen_store_fpr64(ctx, fp0, fd);
             tcg_temp_free_i64(fp0);
         }
@@ -19884,8 +19775,6 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
     ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
     ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
-    ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
-    ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
     restore_cpu_state(env, &ctx);
 #ifdef CONFIG_USER_ONLY
         ctx.mem_idx = MIPS_HFLAG_UM;
@@ -20013,8 +19902,7 @@ done_generating:
 
 #ifdef DEBUG_DISAS
     LOG_DISAS("\n");
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
         log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
         qemu_log("\n");
@@ -20105,7 +19993,6 @@ void mips_tcg_init(void)
         return;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
 
     TCGV_UNUSED(cpu_gpr[0]);
     for (i = 1; i < 32; i++)
@@ -20169,7 +20056,6 @@ MIPSCPU *cpu_mips_init(const char *cpu_model)
     cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
     env = &cpu->env;
     env->cpu_model = def;
-    env->exception_base = (int32_t)0xBFC00000;
 
 #ifndef CONFIG_USER_ONLY
     mmu_init(env, def);
@@ -20192,12 +20078,6 @@ bool cpu_supports_cps_smp(const char *cpu_model)
     return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
 }
 
-void cpu_set_exception_base(int vp_index, target_ulong address)
-{
-    MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
-    vp->env.exception_base = address;
-}
-
 void cpu_state_reset(CPUMIPSState *env)
 {
     MIPSCPU *cpu = mips_env_get_cpu(env);
@@ -20248,7 +20128,6 @@ void cpu_state_reset(CPUMIPSState *env)
     env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
     env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
     env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
-    env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
     env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
     env->msair = env->cpu_model->MSAIR;
     env->insn_flags = env->cpu_model->insn_flags;
@@ -20288,7 +20167,7 @@ void cpu_state_reset(CPUMIPSState *env)
     } else {
         env->CP0_ErrorEPC = env->active_tc.PC;
     }
-    env->active_tc.PC = env->exception_base;
+    env->active_tc.PC = (int32_t)0xBFC00000;
     env->CP0_Random = env->tlb->nb_tlb - 1;
     env->tlb->tlb_in_use = env->tlb->nb_tlb;
     env->CP0_Wired = 0;
@@ -20302,8 +20181,6 @@ void cpu_state_reset(CPUMIPSState *env)
     if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
         env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
     }
-    env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
-                                 0x3ff : 0xff;
     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
     /* vectored interrupts not implemented, timer on int 7,
        no performance counters. */
@@ -20361,7 +20238,8 @@ void cpu_state_reset(CPUMIPSState *env)
     }
 
     compute_hflags(env);
-    restore_fp_status(env);
+    restore_rounding_mode(env);
+    restore_flush_mode(env);
     restore_pamask(env);
     cs->exception_index = EXCP_NONE;
 
index 39ed5c4..5af077d 100644 (file)
@@ -84,7 +84,6 @@ struct mips_def_t {
     int32_t CP0_TCStatus_rw_bitmask;
     int32_t CP0_SRSCtl;
     int32_t CP1_fcr0;
-    int32_t CP1_fcr31_rw_bitmask;
     int32_t CP1_fcr31;
     int32_t MSAIR;
     int32_t SEGBITS;
@@ -274,8 +273,6 @@ static const mips_def_t mips_defs[] =
         .CP0_Status_rw_bitmask = 0x3678FF1F,
         .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
                     (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
-        .CP1_fcr31 = 0,
-        .CP1_fcr31_rw_bitmask = 0xFF83FFFF,
         .SEGBITS = 32,
         .PABITS = 32,
         .insn_flags = CPU_MIPS32R2 | ASE_MIPS16,
@@ -306,8 +303,6 @@ static const mips_def_t mips_defs[] =
                     (0xff << CP0TCSt_TASID),
         .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
                     (1 << FCR0_D) | (1 << FCR0_S) | (0x95 << FCR0_PRID),
-        .CP1_fcr31 = 0,
-        .CP1_fcr31_rw_bitmask = 0xFF83FFFF,
         .CP0_SRSCtl = (0xf << CP0SRSCtl_HSS),
         .CP0_SRSConf0_rw_bitmask = 0x3fffffff,
         .CP0_SRSConf0 = (1U << CP0SRSC0_M) | (0x3fe << CP0SRSC0_SRS3) |
@@ -348,8 +343,6 @@ static const mips_def_t mips_defs[] =
         .CP0_Status_rw_bitmask = 0x3778FF1F,
         .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
                     (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
-        .CP1_fcr31 = 0,
-        .CP1_fcr31_rw_bitmask = 0xFF83FFFF,
         .SEGBITS = 32,
         .PABITS = 32,
         .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_DSPR2,
@@ -434,7 +427,6 @@ static const mips_def_t mips_defs[] =
                     (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
                     (1 << FCR0_D) | (1 << FCR0_S) | (0x03 << FCR0_PRID),
         .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008),
-        .CP1_fcr31_rw_bitmask = 0xFF83FFFF,
         .SEGBITS = 32,
         .PABITS = 40,
         .insn_flags = CPU_MIPS32R5 | ASE_MSA,
@@ -473,7 +465,6 @@ static const mips_def_t mips_defs[] =
                     (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
                     (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
         .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008),
-        .CP1_fcr31_rw_bitmask = 0x0103FFFF,
         .SEGBITS = 32,
         .PABITS = 32,
         .insn_flags = CPU_MIPS32R6 | ASE_MICROMIPS,
@@ -494,8 +485,6 @@ static const mips_def_t mips_defs[] =
         .CP0_Status_rw_bitmask = 0x3678FFFF,
         /* The R4000 has a full 64bit FPU but doesn't use the fcr0 bits. */
         .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
-        .CP1_fcr31 = 0,
-        .CP1_fcr31_rw_bitmask = 0x0183FFFF,
         .SEGBITS = 40,
         .PABITS = 36,
         .insn_flags = CPU_MIPS3,
@@ -514,8 +503,6 @@ static const mips_def_t mips_defs[] =
         .CP0_Status_rw_bitmask = 0x3678FFFF,
         /* The VR5432 has a full 64bit FPU but doesn't use the fcr0 bits. */
         .CP1_fcr0 = (0x54 << FCR0_PRID) | (0x0 << FCR0_REV),
-        .CP1_fcr31 = 0,
-        .CP1_fcr31_rw_bitmask = 0xFF83FFFF,
         .SEGBITS = 40,
         .PABITS = 32,
         .insn_flags = CPU_VR54XX,
@@ -561,8 +548,6 @@ static const mips_def_t mips_defs[] =
         /* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */
         .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
                     (0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
-        .CP1_fcr31 = 0,
-        .CP1_fcr31_rw_bitmask = 0xFF83FFFF,
         .SEGBITS = 42,
         .PABITS = 36,
         .insn_flags = CPU_MIPS64,
@@ -590,8 +575,6 @@ static const mips_def_t mips_defs[] =
         .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) |
                     (1 << FCR0_D) | (1 << FCR0_S) |
                     (0x82 << FCR0_PRID) | (0x0 << FCR0_REV),
-        .CP1_fcr31 = 0,
-        .CP1_fcr31_rw_bitmask = 0xFF83FFFF,
         .SEGBITS = 40,
         .PABITS = 36,
         .insn_flags = CPU_MIPS64 | ASE_MIPS3D,
@@ -618,8 +601,6 @@ static const mips_def_t mips_defs[] =
         .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) |
                     (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
                     (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
-        .CP1_fcr31 = 0,
-        .CP1_fcr31_rw_bitmask = 0xFF83FFFF,
         .SEGBITS = 42,
         .PABITS = 36,
         .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
@@ -671,23 +652,26 @@ static const mips_def_t mips_defs[] =
         .mmu_type = MMU_TYPE_R4000,
     },
     {
-        .name = "I6400",
-        .CP0_PRid = 0x1A900,
+        /* A generic CPU supporting MIPS64 Release 6 ISA.
+           FIXME: Support IEEE 754-2008 FP.
+                  Eventually this should be replaced by a real CPU model. */
+        .name = "MIPS64R6-generic",
+        .CP0_PRid = 0x00010000,
         .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) | (0x2 << CP0C0_AT) |
                        (MMU_TYPE_R4000 << CP0C0_MT),
-        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) |
-                       (2 << CP0C1_IS) | (5 << CP0C1_IL) | (3 << CP0C1_IA) |
-                       (2 << CP0C1_DS) | (5 << CP0C1_DL) | (3 << CP0C1_DA) |
+        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) |
+                       (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
+                       (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
                        (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) |
                        (1 << CP0C3_CMGCR) | (1 << CP0C3_MSAP) |
                        (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) |
-                       (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << CP0C3_VInt),
+                       (1 << CP0C3_RXI) | (1 << CP0C3_LPA),
         .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) |
-                       (1 << CP0C4_AE) | (0xfc << CP0C4_KScrExist),
+                       (0xfc << CP0C4_KScrExist),
         .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_VP) |
-                       (1 << CP0C5_LLB) | (1 << CP0C5_MRP),
+                       (1 << CP0C5_LLB),
         .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) |
                                   (1 << CP0C5_FRE) | (1 << CP0C5_UFE),
         .CP0_LLAddr_rw_bitmask = 0,
@@ -700,10 +684,8 @@ static const mips_def_t mips_defs[] =
         .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA),
         .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) |
                     (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
-                    (1 << FCR0_S) | (0x03 << FCR0_PRID) | (0x0 << FCR0_REV),
+                    (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
         .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008),
-        .CP1_fcr31_rw_bitmask = 0x0103FFFF,
-        .MSAIR = 0x03 << MSAIR_ProcID,
         .SEGBITS = 48,
         .PABITS = 48,
         .insn_flags = CPU_MIPS64R6 | ASE_MSA,
@@ -722,8 +704,6 @@ static const mips_def_t mips_defs[] =
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x35D0FFFF,
         .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
-        .CP1_fcr31 = 0,
-        .CP1_fcr31_rw_bitmask = 0xFF83FFFF,
         .SEGBITS = 40,
         .PABITS = 40,
         .insn_flags = CPU_LOONGSON2E,
@@ -742,8 +722,6 @@ static const mips_def_t mips_defs[] =
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0xF5D0FF1F,   /* Bits 7:5 not writable.  */
         .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
-        .CP1_fcr31 = 0,
-        .CP1_fcr31_rw_bitmask = 0xFF83FFFF,
         .SEGBITS = 40,
         .PABITS = 40,
         .insn_flags = CPU_LOONGSON2F,
@@ -771,8 +749,6 @@ static const mips_def_t mips_defs[] =
         .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) |
                     (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
                     (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
-        .CP1_fcr31 = 0,
-        .CP1_fcr31_rw_bitmask = 0xFF83FFFF,
         .SEGBITS = 42,
         .PABITS = 36,
         .insn_flags = CPU_MIPS64R2 | ASE_DSP | ASE_DSPR2,
@@ -916,7 +892,4 @@ static void msa_reset(CPUMIPSState *env)
 
     /* clear float_status nan mode */
     set_default_nan_mode(0, &env->active_tc.msa_fp_status);
-
-    /* set proper signanling bit meaning ("1" means "quiet") */
-    set_snan_bit_is_one(0, &env->active_tc.msa_fp_status);
 }
index 50a0899..b4ee84e 100644 (file)
@@ -23,7 +23,6 @@
 #include "qemu-common.h"
 #include "migration/vmstate.h"
 #include "machine.h"
-#include "exec/exec-all.h"
 
 static void moxie_cpu_set_pc(CPUState *cs, vaddr value)
 {
index 3e880fa..4ee2077 100644 (file)
@@ -16,9 +16,8 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-
-#ifndef MOXIE_CPU_H
-#define MOXIE_CPU_H
+#ifndef _CPU_MOXIE_H
+#define _CPU_MOXIE_H
 
 #include "qemu-common.h"
 
@@ -110,6 +109,7 @@ static inline MoxieCPU *moxie_env_get_cpu(CPUMoxieState *env)
 #define ENV_OFFSET offsetof(MoxieCPU, env)
 
 MoxieCPU *cpu_moxie_init(const char *cpu_model);
+int cpu_moxie_exec(CPUState *cpu);
 void moxie_cpu_do_interrupt(CPUState *cs);
 void moxie_cpu_dump_state(CPUState *cpu, FILE *f,
                           fprintf_function cpu_fprintf, int flags);
@@ -120,6 +120,7 @@ int cpu_moxie_signal_handler(int host_signum, void *pinfo,
 
 #define cpu_init(cpu_model) CPU(cpu_moxie_init(cpu_model))
 
+#define cpu_exec cpu_moxie_exec
 #define cpu_signal_handler cpu_moxie_signal_handler
 
 static inline int cpu_mmu_index(CPUMoxieState *env, bool ifetch)
@@ -128,9 +129,10 @@ static inline int cpu_mmu_index(CPUMoxieState *env, bool ifetch)
 }
 
 #include "exec/cpu-all.h"
+#include "exec/exec-all.h"
 
 static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *pc = env->pc;
     *cs_base = 0;
@@ -140,4 +142,4 @@ static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc,
 int moxie_cpu_handle_mmu_fault(CPUState *cpu, vaddr address,
                                int rw, int mmu_idx);
 
-#endif /* MOXIE_CPU_H */
+#endif /* _CPU_MOXIE_H */
index 330299f..d51e9b9 100644 (file)
 /* Try to fill the TLB and return an exception if error. If retaddr is
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr)
 {
     int ret;
 
-    ret = moxie_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = moxie_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             cpu_restore_state(cs, retaddr);
index 282dcd8..912b791 100644 (file)
@@ -1,10 +1,7 @@
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "hw/hw.h"
 #include "hw/boards.h"
 #include "machine.h"
-#include "migration/cpu.h"
 
 const VMStateDescription vmstate_moxie_cpu = {
     .name = "cpu",
index 284a44d..abc7929 100644 (file)
@@ -6,6 +6,11 @@
 typedef struct {
     uint32_t phy;
     uint32_t pfn;
+    unsigned g:1;
+    unsigned v:1;
+    unsigned k:1;
+    unsigned w:1;
+    unsigned e:1;
     int cause_op;
 } MoxieMMUResult;
 
index 0660b44..a437e2a 100644 (file)
@@ -106,7 +106,6 @@ void moxie_translate_init(void)
         return;
     }
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
     cpu_pc = tcg_global_mem_new_i32(cpu_env,
                                     offsetof(CPUMoxieState, pc), "$pc");
     for (i = 0; i < 16; i++)
@@ -122,26 +121,17 @@ void moxie_translate_init(void)
     done_init = 1;
 }
 
-static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
-{
-    if (unlikely(ctx->singlestep_enabled)) {
-        return false;
-    }
-
-#ifndef CONFIG_USER_ONLY
-    return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
 static inline void gen_goto_tb(CPUMoxieState *env, DisasContext *ctx,
                                int n, target_ulong dest)
 {
-    if (use_goto_tb(ctx, dest)) {
+    TranslationBlock *tb;
+    tb = ctx->tb;
+
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
+        !ctx->singlestep_enabled) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_i32(cpu_pc, dest);
-        tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_i32(cpu_pc, dest);
         if (ctx->singlestep_enabled) {
index 155913f..ae6ed9e 100644 (file)
@@ -21,7 +21,6 @@
 #include "qapi/error.h"
 #include "cpu.h"
 #include "qemu-common.h"
-#include "exec/exec-all.h"
 
 static void openrisc_cpu_set_pc(CPUState *cs, vaddr value)
 {
index aaf1535..4b63f25 100644 (file)
@@ -17,8 +17,8 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef OPENRISC_CPU_H
-#define OPENRISC_CPU_H
+#ifndef CPU_OPENRISC_H
+#define CPU_OPENRISC_H
 
 #define TARGET_LONG_BITS 32
 
@@ -344,6 +344,7 @@ static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env)
 OpenRISCCPU *cpu_openrisc_init(const char *cpu_model);
 
 void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf);
+int cpu_openrisc_exec(CPUState *cpu);
 void openrisc_cpu_do_interrupt(CPUState *cpu);
 bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
@@ -357,6 +358,7 @@ int openrisc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address,
 int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc);
 
 #define cpu_list cpu_openrisc_list
+#define cpu_exec cpu_openrisc_exec
 #define cpu_signal_handler cpu_openrisc_signal_handler
 
 #ifndef CONFIG_USER_ONLY
@@ -390,7 +392,7 @@ int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
 
 static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
                                         target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *pc = env->pc;
     *cs_base = 0;
@@ -408,4 +410,6 @@ static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
 
 #define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
 
-#endif /* OPENRISC_CPU_H */
+#include "exec/exec-all.h"
+
+#endif /* CPU_OPENRISC_H */
index 49470be..ace3184 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exception.h"
 
 void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t excp)
index 4ec56b4..4b64430 100644 (file)
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef TARGET_OPENRISC_EXCEPTION_H
-#define TARGET_OPENRISC_EXCEPTION_H
+#ifndef QEMU_OPENRISC_EXCP_H
+#define QEMU_OPENRISC_EXCP_H
 
 #include "cpu.h"
 #include "qemu-common.h"
 
 void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t excp);
 
-#endif /* TARGET_OPENRISC_EXCEPTION_H */
+#endif /* QEMU_OPENRISC_EXCP_H */
index cb16e76..edc301a 100644 (file)
@@ -19,7 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
 
 int openrisc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
index 5fe3f11..963eb14 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "qemu-common.h"
 #include "exec/gdbstub.h"
 #include "qemu/host-utils.h"
index 116f910..11b4b20 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 
 void HELPER(rfe)(CPUOpenRISCState *env)
index 17b0c77..b4dc08d 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
 #include "hw/hw.h"
 #include "hw/boards.h"
-#include "migration/cpu.h"
 
 static const VMStateDescription vmstate_env = {
     .name = "env",
index 505dcdc..4ab414a 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "qemu-common.h"
 #include "exec/gdbstub.h"
 #include "qemu/host-utils.h"
index a44d0aa..d7952d4 100644 (file)
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 #ifndef CONFIG_USER_ONLY
 
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write,
               int mmu_idx, uintptr_t retaddr)
 {
     int ret;
 
-    ret = openrisc_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = openrisc_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
 
     if (ret) {
         if (retaddr) {
index a719e45..f917be6 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 
 #define TO_SPR(group, number) (((group) << 11) + (number))
index 28c9446..5d0ab44 100644 (file)
@@ -78,7 +78,6 @@ void openrisc_translate_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
     cpu_sr = tcg_global_mem_new(cpu_env,
                                 offsetof(CPUOpenRISCState, sr), "sr");
     env_flags = tcg_global_mem_new_i32(cpu_env,
@@ -191,25 +190,15 @@ static void check_ov64s(DisasContext *dc)
 }
 #endif*/
 
-static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
-{
-    if (unlikely(dc->singlestep_enabled)) {
-        return false;
-    }
-
-#ifndef CONFIG_USER_ONLY
-    return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 {
-    if (use_goto_tb(dc, dest)) {
+    TranslationBlock *tb;
+    tb = dc->tb;
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
+                                       likely(!dc->singlestep_enabled)) {
         tcg_gen_movi_tl(cpu_pc, dest);
         tcg_gen_goto_tb(n);
-        tcg_gen_exit_tb((uintptr_t)dc->tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_tl(cpu_pc, dest);
         if (dc->singlestep_enabled) {
@@ -1752,8 +1741,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
     tb->icount = num_insns;
 
 #ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("\n");
         log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
         qemu_log("\nisize=%d osize=%d\n",
index 2864105..7d5e2b3 100644 (file)
@@ -21,6 +21,7 @@
 #define QEMU_PPC_CPU_QOM_H
 
 #include "qom/cpu.h"
+#include "cpu.h"
 
 #ifdef TARGET_PPC64
 #define TYPE_POWERPC_CPU "powerpc64-cpu"
     OBJECT_GET_CLASS(PowerPCCPUClass, (obj), TYPE_POWERPC_CPU)
 
 typedef struct PowerPCCPU PowerPCCPU;
-typedef struct CPUPPCState CPUPPCState;
-typedef struct ppc_tb_t ppc_tb_t;
-typedef struct ppc_dcr_t ppc_dcr_t;
-
-/*****************************************************************************/
-/* MMU model                                                                 */
-typedef enum powerpc_mmu_t powerpc_mmu_t;
-enum powerpc_mmu_t {
-    POWERPC_MMU_UNKNOWN    = 0x00000000,
-    /* Standard 32 bits PowerPC MMU                            */
-    POWERPC_MMU_32B        = 0x00000001,
-    /* PowerPC 6xx MMU with software TLB                       */
-    POWERPC_MMU_SOFT_6xx   = 0x00000002,
-    /* PowerPC 74xx MMU with software TLB                      */
-    POWERPC_MMU_SOFT_74xx  = 0x00000003,
-    /* PowerPC 4xx MMU with software TLB                       */
-    POWERPC_MMU_SOFT_4xx   = 0x00000004,
-    /* PowerPC 4xx MMU with software TLB and zones protections */
-    POWERPC_MMU_SOFT_4xx_Z = 0x00000005,
-    /* PowerPC MMU in real mode only                           */
-    POWERPC_MMU_REAL       = 0x00000006,
-    /* Freescale MPC8xx MMU model                              */
-    POWERPC_MMU_MPC8xx     = 0x00000007,
-    /* BookE MMU model                                         */
-    POWERPC_MMU_BOOKE      = 0x00000008,
-    /* BookE 2.06 MMU model                                    */
-    POWERPC_MMU_BOOKE206   = 0x00000009,
-    /* PowerPC 601 MMU model (specific BATs format)            */
-    POWERPC_MMU_601        = 0x0000000A,
-#define POWERPC_MMU_64       0x00010000
-#define POWERPC_MMU_1TSEG    0x00020000
-#define POWERPC_MMU_AMR      0x00040000
-#define POWERPC_MMU_64K      0x00080000
-    /* 64 bits PowerPC MMU                                     */
-    POWERPC_MMU_64B        = POWERPC_MMU_64 | 0x00000001,
-    /* Architecture 2.03 and later (has LPCR) */
-    POWERPC_MMU_2_03       = POWERPC_MMU_64 | 0x00000002,
-    /* Architecture 2.06 variant                               */
-    POWERPC_MMU_2_06       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
-                             | POWERPC_MMU_64K
-                             | POWERPC_MMU_AMR | 0x00000003,
-    /* Architecture 2.06 "degraded" (no 1T segments)           */
-    POWERPC_MMU_2_06a      = POWERPC_MMU_64 | POWERPC_MMU_AMR
-                             | 0x00000003,
-    /* Architecture 2.07 variant                               */
-    POWERPC_MMU_2_07       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
-                             | POWERPC_MMU_64K
-                             | POWERPC_MMU_AMR | 0x00000004,
-    /* Architecture 2.07 "degraded" (no 1T segments)           */
-    POWERPC_MMU_2_07a      = POWERPC_MMU_64 | POWERPC_MMU_AMR
-                             | 0x00000004,
-};
-
-/*****************************************************************************/
-/* Exception model                                                           */
-typedef enum powerpc_excp_t powerpc_excp_t;
-enum powerpc_excp_t {
-    POWERPC_EXCP_UNKNOWN   = 0,
-    /* Standard PowerPC exception model */
-    POWERPC_EXCP_STD,
-    /* PowerPC 40x exception model      */
-    POWERPC_EXCP_40x,
-    /* PowerPC 601 exception model      */
-    POWERPC_EXCP_601,
-    /* PowerPC 602 exception model      */
-    POWERPC_EXCP_602,
-    /* PowerPC 603 exception model      */
-    POWERPC_EXCP_603,
-    /* PowerPC 603e exception model     */
-    POWERPC_EXCP_603E,
-    /* PowerPC G2 exception model       */
-    POWERPC_EXCP_G2,
-    /* PowerPC 604 exception model      */
-    POWERPC_EXCP_604,
-    /* PowerPC 7x0 exception model      */
-    POWERPC_EXCP_7x0,
-    /* PowerPC 7x5 exception model      */
-    POWERPC_EXCP_7x5,
-    /* PowerPC 74xx exception model     */
-    POWERPC_EXCP_74xx,
-    /* BookE exception model            */
-    POWERPC_EXCP_BOOKE,
-    /* PowerPC 970 exception model      */
-    POWERPC_EXCP_970,
-    /* POWER7 exception model           */
-    POWERPC_EXCP_POWER7,
-    /* POWER8 exception model           */
-    POWERPC_EXCP_POWER8,
-};
-
-/*****************************************************************************/
-/* PM instructions */
-typedef enum {
-    PPC_PM_DOZE,
-    PPC_PM_NAP,
-    PPC_PM_SLEEP,
-    PPC_PM_RVWINKLE,
-} powerpc_pm_insn_t;
-
-/*****************************************************************************/
-/* Input pins model                                                          */
-typedef enum powerpc_input_t powerpc_input_t;
-enum powerpc_input_t {
-    PPC_FLAGS_INPUT_UNKNOWN = 0,
-    /* PowerPC 6xx bus                  */
-    PPC_FLAGS_INPUT_6xx,
-    /* BookE bus                        */
-    PPC_FLAGS_INPUT_BookE,
-    /* PowerPC 405 bus                  */
-    PPC_FLAGS_INPUT_405,
-    /* PowerPC 970 bus                  */
-    PPC_FLAGS_INPUT_970,
-    /* PowerPC POWER7 bus               */
-    PPC_FLAGS_INPUT_POWER7,
-    /* PowerPC 401 bus                  */
-    PPC_FLAGS_INPUT_401,
-    /* Freescale RCPU bus               */
-    PPC_FLAGS_INPUT_RCPU,
-};
-
-struct ppc_segment_page_sizes;
 
 /**
  * PowerPCCPUClass:
@@ -177,8 +57,7 @@ typedef struct PowerPCCPUClass {
 
     uint32_t pvr;
     bool (*pvr_match)(struct PowerPCCPUClass *pcc, uint32_t pvr);
-    uint64_t pcr_mask;          /* Available bits in PCR register */
-    uint64_t pcr_supported;     /* Bits for supported PowerISA versions */
+    uint64_t pcr_mask;
     uint32_t svr;
     uint64_t insns_flags;
     uint64_t insns_flags2;
@@ -189,14 +68,69 @@ typedef struct PowerPCCPUClass {
     uint32_t flags;
     int bfd_mach;
     uint32_t l1_dcache_size, l1_icache_size;
+#if defined(TARGET_PPC64)
     const struct ppc_segment_page_sizes *sps;
+#endif
     void (*init_proc)(CPUPPCState *env);
     int  (*check_pow)(CPUPPCState *env);
-    int (*handle_mmu_fault)(PowerPCCPU *cpu, vaddr eaddr, int rwx, int mmu_idx);
+#if defined(CONFIG_SOFTMMU)
+    int (*handle_mmu_fault)(PowerPCCPU *cpu, target_ulong eaddr, int rwx,
+                            int mmu_idx);
+#endif
     bool (*interrupts_big_endian)(PowerPCCPU *cpu);
 } PowerPCCPUClass;
 
+/**
+ * PowerPCCPU:
+ * @env: #CPUPPCState
+ * @cpu_dt_id: CPU index used in the device tree. KVM uses this index too
+ * @max_compat: Maximal supported logical PVR from the command line
+ * @cpu_version: Current logical PVR, zero if in "raw" mode
+ *
+ * A PowerPC CPU.
+ */
+struct PowerPCCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUPPCState env;
+    int cpu_dt_id;
+    uint32_t max_compat;
+    uint32_t cpu_version;
+};
+
+static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
+{
+    return container_of(env, PowerPCCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(ppc_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(PowerPCCPU, env)
+
+PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
+PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr);
+
+void ppc_cpu_do_interrupt(CPUState *cpu);
+bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
+void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                        int flags);
+void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
+                             fprintf_function cpu_fprintf, int flags);
+int ppc_cpu_get_monitor_def(CPUState *cs, const char *name,
+                            uint64_t *pval);
+hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int ppc_cpu_gdb_read_register_apple(CPUState *cpu, uint8_t *buf, int reg);
+int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+int ppc_cpu_gdb_write_register_apple(CPUState *cpu, uint8_t *buf, int reg);
+int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
+                               int cpuid, void *opaque);
 #ifndef CONFIG_USER_ONLY
+void ppc_cpu_do_system_reset(CPUState *cs);
+extern const struct VMStateDescription vmstate_ppc_cpu;
+
 typedef struct PPCTimebase {
     uint64_t guest_timebase;
     int64_t time_of_the_day_ns;
index 786ab5c..5282533 100644 (file)
@@ -16,9 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-
-#ifndef PPC_CPU_H
-#define PPC_CPU_H
+#if !defined (__CPU_PPC_H__)
+#define __CPU_PPC_H__
 
 #include "qemu-common.h"
 
@@ -29,6 +28,8 @@
 #define TARGET_LONG_BITS 64
 #define TARGET_PAGE_BITS 12
 
+#define TARGET_IS_BIENDIAN 1
+
 /* Note that the official physical address space bits is 62-M where M
    is implementation dependent.  I've not looked up M for the set of
    cpus we emulate at the system level.  */
@@ -75,7 +76,7 @@
 #define CPUArchState struct CPUPPCState
 
 #include "exec/cpu-defs.h"
-#include "cpu-qom.h"
+
 #include "fpu/softfloat.h"
 
 #if defined (TARGET_PPC64)
 #endif
 
 /*****************************************************************************/
+/* MMU model                                                                 */
+typedef enum powerpc_mmu_t powerpc_mmu_t;
+enum powerpc_mmu_t {
+    POWERPC_MMU_UNKNOWN    = 0x00000000,
+    /* Standard 32 bits PowerPC MMU                            */
+    POWERPC_MMU_32B        = 0x00000001,
+    /* PowerPC 6xx MMU with software TLB                       */
+    POWERPC_MMU_SOFT_6xx   = 0x00000002,
+    /* PowerPC 74xx MMU with software TLB                      */
+    POWERPC_MMU_SOFT_74xx  = 0x00000003,
+    /* PowerPC 4xx MMU with software TLB                       */
+    POWERPC_MMU_SOFT_4xx   = 0x00000004,
+    /* PowerPC 4xx MMU with software TLB and zones protections */
+    POWERPC_MMU_SOFT_4xx_Z = 0x00000005,
+    /* PowerPC MMU in real mode only                           */
+    POWERPC_MMU_REAL       = 0x00000006,
+    /* Freescale MPC8xx MMU model                              */
+    POWERPC_MMU_MPC8xx     = 0x00000007,
+    /* BookE MMU model                                         */
+    POWERPC_MMU_BOOKE      = 0x00000008,
+    /* BookE 2.06 MMU model                                    */
+    POWERPC_MMU_BOOKE206   = 0x00000009,
+    /* PowerPC 601 MMU model (specific BATs format)            */
+    POWERPC_MMU_601        = 0x0000000A,
+#if defined(TARGET_PPC64)
+#define POWERPC_MMU_64       0x00010000
+#define POWERPC_MMU_1TSEG    0x00020000
+#define POWERPC_MMU_AMR      0x00040000
+    /* 64 bits PowerPC MMU                                     */
+    POWERPC_MMU_64B        = POWERPC_MMU_64 | 0x00000001,
+    /* Architecture 2.03 and later (has LPCR) */
+    POWERPC_MMU_2_03       = POWERPC_MMU_64 | 0x00000002,
+    /* Architecture 2.06 variant                               */
+    POWERPC_MMU_2_06       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
+                             | POWERPC_MMU_AMR | 0x00000003,
+    /* Architecture 2.06 "degraded" (no 1T segments)           */
+    POWERPC_MMU_2_06a      = POWERPC_MMU_64 | POWERPC_MMU_AMR
+                             | 0x00000003,
+    /* Architecture 2.07 variant                               */
+    POWERPC_MMU_2_07       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
+                             | POWERPC_MMU_AMR | 0x00000004,
+    /* Architecture 2.07 "degraded" (no 1T segments)           */
+    POWERPC_MMU_2_07a      = POWERPC_MMU_64 | POWERPC_MMU_AMR
+                             | 0x00000004,
+#endif /* defined(TARGET_PPC64) */
+};
+
+/*****************************************************************************/
+/* Exception model                                                           */
+typedef enum powerpc_excp_t powerpc_excp_t;
+enum powerpc_excp_t {
+    POWERPC_EXCP_UNKNOWN   = 0,
+    /* Standard PowerPC exception model */
+    POWERPC_EXCP_STD,
+    /* PowerPC 40x exception model      */
+    POWERPC_EXCP_40x,
+    /* PowerPC 601 exception model      */
+    POWERPC_EXCP_601,
+    /* PowerPC 602 exception model      */
+    POWERPC_EXCP_602,
+    /* PowerPC 603 exception model      */
+    POWERPC_EXCP_603,
+    /* PowerPC 603e exception model     */
+    POWERPC_EXCP_603E,
+    /* PowerPC G2 exception model       */
+    POWERPC_EXCP_G2,
+    /* PowerPC 604 exception model      */
+    POWERPC_EXCP_604,
+    /* PowerPC 7x0 exception model      */
+    POWERPC_EXCP_7x0,
+    /* PowerPC 7x5 exception model      */
+    POWERPC_EXCP_7x5,
+    /* PowerPC 74xx exception model     */
+    POWERPC_EXCP_74xx,
+    /* BookE exception model            */
+    POWERPC_EXCP_BOOKE,
+#if defined(TARGET_PPC64)
+    /* PowerPC 970 exception model      */
+    POWERPC_EXCP_970,
+    /* POWER7 exception model           */
+    POWERPC_EXCP_POWER7,
+    /* POWER8 exception model           */
+    POWERPC_EXCP_POWER8,
+#endif /* defined(TARGET_PPC64) */
+};
+
+/*****************************************************************************/
 /* Exception vectors definitions                                             */
 enum {
     POWERPC_EXCP_NONE    = -1,
@@ -117,9 +205,6 @@ enum {
     POWERPC_EXCP_HYPPRIV  = 41, /* Embedded hypervisor priv instruction      */
     /* Vectors 42 to 63 are reserved                                         */
     /* Exceptions defined in the PowerPC server specification                */
-    /* Server doorbell variants */
-#define POWERPC_EXCP_SDOOR      POWERPC_EXCP_GDOORI
-#define POWERPC_EXCP_SDOOR_HV   POWERPC_EXCP_DOORI
     POWERPC_EXCP_RESET    = 64, /* System reset exception                    */
     POWERPC_EXCP_DSEG     = 65, /* Data segment exception                    */
     POWERPC_EXCP_ISEG     = 66, /* Instruction segment exception             */
@@ -162,12 +247,8 @@ enum {
     /* VSX Unavailable (Power ISA 2.06 and later)                            */
     POWERPC_EXCP_VSXU     = 94, /* VSX Unavailable                           */
     POWERPC_EXCP_FU       = 95, /* Facility Unavailable                      */
-    /* Additional ISA 2.06 and later server exceptions                       */
-    POWERPC_EXCP_HV_EMU   = 96, /* HV emulation assistance                   */
-    POWERPC_EXCP_HV_MAINT = 97, /* HMI                                       */
-    POWERPC_EXCP_HV_FU    = 98, /* Hypervisor Facility unavailable           */
     /* EOL                                                                   */
-    POWERPC_EXCP_NB       = 99,
+    POWERPC_EXCP_NB       = 96,
     /* QEMU exceptions: used internally during code translation              */
     POWERPC_EXCP_STOP         = 0x200, /* stop translation                   */
     POWERPC_EXCP_BRANCH       = 0x201, /* branch instruction                 */
@@ -216,6 +297,27 @@ enum {
     POWERPC_EXCP_TRAP          = 0x40,
 };
 
+/*****************************************************************************/
+/* Input pins model                                                          */
+typedef enum powerpc_input_t powerpc_input_t;
+enum powerpc_input_t {
+    PPC_FLAGS_INPUT_UNKNOWN = 0,
+    /* PowerPC 6xx bus                  */
+    PPC_FLAGS_INPUT_6xx,
+    /* BookE bus                        */
+    PPC_FLAGS_INPUT_BookE,
+    /* PowerPC 405 bus                  */
+    PPC_FLAGS_INPUT_405,
+    /* PowerPC 970 bus                  */
+    PPC_FLAGS_INPUT_970,
+    /* PowerPC POWER7 bus               */
+    PPC_FLAGS_INPUT_POWER7,
+    /* PowerPC 401 bus                  */
+    PPC_FLAGS_INPUT_401,
+    /* Freescale RCPU bus               */
+    PPC_FLAGS_INPUT_RCPU,
+};
+
 #define PPC_INPUT(env) (env->bus_model)
 
 /*****************************************************************************/
@@ -223,8 +325,11 @@ typedef struct opc_handler_t opc_handler_t;
 
 /*****************************************************************************/
 /* Types used to describe some PowerPC registers */
+typedef struct CPUPPCState CPUPPCState;
 typedef struct DisasContext DisasContext;
+typedef struct ppc_tb_t ppc_tb_t;
 typedef struct ppc_spr_t ppc_spr_t;
+typedef struct ppc_dcr_t ppc_dcr_t;
 typedef union ppc_avr_t ppc_avr_t;
 typedef union ppc_tlb_t ppc_tlb_t;
 
@@ -365,8 +470,6 @@ struct ppc_slb_t {
 #define MSR_EP   6  /* Exception prefix on 601                               */
 #define MSR_IR   5  /* Instruction relocate                                  */
 #define MSR_DR   4  /* Data relocate                                         */
-#define MSR_IS   5  /* Instruction address space (BookE)                     */
-#define MSR_DS   4  /* Data address space (BookE)                            */
 #define MSR_PE   3  /* Protection enable on 403                              */
 #define MSR_PX   2  /* Protection exclusive on 403                  x        */
 #define MSR_PMM  2  /* Performance monitor mark on POWER            x        */
@@ -378,30 +481,12 @@ struct ppc_slb_t {
 #define LPCR_VPM1         (1ull << (63 - 1))
 #define LPCR_ISL          (1ull << (63 - 2))
 #define LPCR_KBV          (1ull << (63 - 3))
-#define LPCR_DPFD_SHIFT   (63 - 11)
-#define LPCR_DPFD         (0x3ull << LPCR_DPFD_SHIFT)
-#define LPCR_VRMASD_SHIFT (63 - 16)
-#define LPCR_VRMASD       (0x1full << LPCR_VRMASD_SHIFT)
-#define LPCR_RMLS_SHIFT   (63 - 37)
-#define LPCR_RMLS         (0xfull << LPCR_RMLS_SHIFT)
 #define LPCR_ILE          (1ull << (63 - 38))
-#define LPCR_AIL_SHIFT    (63 - 40)      /* Alternate interrupt location */
-#define LPCR_AIL          (3ull << LPCR_AIL_SHIFT)
-#define LPCR_ONL          (1ull << (63 - 45))
-#define LPCR_P7_PECE0     (1ull << (63 - 49))
-#define LPCR_P7_PECE1     (1ull << (63 - 50))
-#define LPCR_P7_PECE2     (1ull << (63 - 51))
-#define LPCR_P8_PECE0     (1ull << (63 - 47))
-#define LPCR_P8_PECE1     (1ull << (63 - 48))
-#define LPCR_P8_PECE2     (1ull << (63 - 49))
-#define LPCR_P8_PECE3     (1ull << (63 - 50))
-#define LPCR_P8_PECE4     (1ull << (63 - 51))
 #define LPCR_MER          (1ull << (63 - 52))
-#define LPCR_TC           (1ull << (63 - 54))
 #define LPCR_LPES0        (1ull << (63 - 60))
 #define LPCR_LPES1        (1ull << (63 - 61))
-#define LPCR_RMI          (1ull << (63 - 62))
-#define LPCR_HDICE        (1ull << (63 - 63))
+#define LPCR_AIL_SHIFT    (63 - 40)      /* Alternate interrupt location */
+#define LPCR_AIL          (3ull << LPCR_AIL_SHIFT)
 
 #define msr_sf   ((env->msr >> MSR_SF)   & 1)
 #define msr_isf  ((env->msr >> MSR_ISF)  & 1)
@@ -436,8 +521,6 @@ struct ppc_slb_t {
 #define msr_ep   ((env->msr >> MSR_EP)   & 1)
 #define msr_ir   ((env->msr >> MSR_IR)   & 1)
 #define msr_dr   ((env->msr >> MSR_DR)   & 1)
-#define msr_is   ((env->msr >> MSR_IS)   & 1)
-#define msr_ds   ((env->msr >> MSR_DS)   & 1)
 #define msr_pe   ((env->msr >> MSR_PE)   & 1)
 #define msr_px   ((env->msr >> MSR_PX)   & 1)
 #define msr_pmm  ((env->msr >> MSR_PMM)  & 1)
@@ -917,7 +1000,7 @@ struct ppc_segment_page_sizes {
 
 /*****************************************************************************/
 /* The whole PowerPC CPU context */
-#define NB_MMU_MODES    8
+#define NB_MMU_MODES 3
 
 #define PPC_CPU_OPCODES_LEN          0x40
 #define PPC_CPU_INDIRECT_OPCODES_LEN 0x20
@@ -982,7 +1065,6 @@ struct CPUPPCState {
     /* PowerPC 64 SLB area */
     ppc_slb_t slb[MAX_SLB_ENTRIES];
     int32_t slb_nr;
-    /* tcg TLB needs flush (deferred slb inval instruction typically) */
 #endif
     /* segment registers */
     hwaddr htab_base;
@@ -1008,7 +1090,6 @@ struct CPUPPCState {
     target_ulong pb[4];
     bool tlb_dirty;   /* Set to non-zero when modifying TLB                  */
     bool kvm_sw_tlb;  /* non-zero if KVM SW TLB API is active                */
-    uint32_t tlb_need_flush; /* Delayed flush needed */
 #endif
 
     /* Other registers */
@@ -1048,8 +1129,6 @@ struct CPUPPCState {
     uint64_t insns_flags2;
 #if defined(TARGET_PPC64)
     struct ppc_segment_page_sizes sps;
-    ppc_slb_t vrma_slb;
-    target_ulong rmls;
     bool ci_large_pages;
 #endif
 
@@ -1076,15 +1155,6 @@ struct CPUPPCState {
     hwaddr mpic_iack;
     /* true when the external proxy facility mode is enabled */
     bool mpic_proxy;
-    /* set when the processor has an HV mode, thus HV priv
-     * instructions and SPRs are diallowed if MSR:HV is 0
-     */
-    bool has_hv_mode;
-    /* On P7/P8, set when in PM state, we need to handle resume
-     * in a special way (such as routing some resume causes to
-     * 0x100), so flag this here.
-     */
-    bool in_pm_state;
 #endif
 
     /* Those resources are used only during code translation */
@@ -1094,8 +1164,7 @@ struct CPUPPCState {
     /* Those resources are used only in QEMU core */
     target_ulong hflags;      /* hflags is a MSR & HFLAGS_MASK         */
     target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */
-    int immu_idx;         /* precomputed MMU index to speed up insn access */
-    int dmmu_idx;         /* precomputed MMU index to speed up data accesses */
+    int mmu_idx;         /* precomputed MMU index to speed up mem accesses */
 
     /* Power management */
     int (*check_pow)(CPUPPCState *env);
@@ -1146,63 +1215,13 @@ do {                                            \
     env->wdt_period[3] = (d_);                  \
  } while (0)
 
-/**
- * PowerPCCPU:
- * @env: #CPUPPCState
- * @cpu_dt_id: CPU index used in the device tree. KVM uses this index too
- * @max_compat: Maximal supported logical PVR from the command line
- * @cpu_version: Current logical PVR, zero if in "raw" mode
- *
- * A PowerPC CPU.
- */
-struct PowerPCCPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPUPPCState env;
-    int cpu_dt_id;
-    uint32_t max_compat;
-    uint32_t cpu_version;
-};
-
-static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
-{
-    return container_of(env, PowerPCCPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(ppc_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(PowerPCCPU, env)
-
-PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
-PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr);
-
-void ppc_cpu_do_interrupt(CPUState *cpu);
-bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
-void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
-                        int flags);
-void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
-                             fprintf_function cpu_fprintf, int flags);
-int ppc_cpu_get_monitor_def(CPUState *cs, const char *name,
-                            uint64_t *pval);
-hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int ppc_cpu_gdb_read_register_apple(CPUState *cpu, uint8_t *buf, int reg);
-int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-int ppc_cpu_gdb_write_register_apple(CPUState *cpu, uint8_t *buf, int reg);
-int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
-                               int cpuid, void *opaque);
-#ifndef CONFIG_USER_ONLY
-void ppc_cpu_do_system_reset(CPUState *cs);
-extern const struct VMStateDescription vmstate_ppc_cpu;
-#endif
+#include "cpu-qom.h"
 
 /*****************************************************************************/
 PowerPCCPU *cpu_ppc_init(const char *cpu_model);
 void ppc_translate_init(void);
-const char *ppc_cpu_lookup_alias(const char *alias);
 void gen_update_current_nip(void *opaque);
+int cpu_ppc_exec (CPUState *s);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
@@ -1220,9 +1239,7 @@ void ppc_store_msr (CPUPPCState *env, target_ulong value);
 
 void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf);
 int ppc_get_compat_smt_threads(PowerPCCPU *cpu);
-#if defined(TARGET_PPC64)
 void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp);
-#endif
 
 /* Time-base and decrementer management */
 #ifndef NO_CPU_IO_DEFS
@@ -1281,14 +1298,18 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val);
 
 #define cpu_init(cpu_model) CPU(cpu_ppc_init(cpu_model))
 
+#define cpu_exec cpu_ppc_exec
 #define cpu_signal_handler cpu_ppc_signal_handler
 #define cpu_list ppc_cpu_list
 
 /* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _user
+#define MMU_MODE1_SUFFIX _kernel
+#define MMU_MODE2_SUFFIX _hypv
 #define MMU_USER_IDX 0
 static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)
 {
-    return ifetch ? env->immu_idx : env->dmmu_idx;
+    return env->mmu_idx;
 }
 
 #include "exec/cpu-all.h"
@@ -1937,8 +1958,6 @@ enum {
     PPC_POPCNTB        = 0x0000000000001000ULL,
     /*   string load / store                                                 */
     PPC_STRING         = 0x0000000000002000ULL,
-    /*   real mode cache inhibited load / store                              */
-    PPC_CILDST         = 0x0000000000004000ULL,
 
     /* Floating-point unit extensions                                        */
     /*   Optional floating point instructions                                */
@@ -2053,7 +2072,7 @@ enum {
                         | PPC_MFAPIDI | PPC_TLBIVA | PPC_TLBIVAX \
                         | PPC_4xx_COMMON | PPC_40x_ICBT | PPC_RFMCI \
                         | PPC_RFDI | PPC_DCR | PPC_DCRX | PPC_DCRUX \
-                        | PPC_POPCNTWD | PPC_CILDST)
+                        | PPC_POPCNTWD)
 
     /* extended type values */
 
@@ -2093,8 +2112,6 @@ enum {
     PPC2_FP_CVT_S64    = 0x0000000000010000ULL,
     /* Transactional Memory (ISA 2.07, Book II)                              */
     PPC2_TM            = 0x0000000000020000ULL,
-    /* Server PM instructgions (ISA 2.06, Book III)                          */
-    PPC2_PM_ISA206     = 0x0000000000040000ULL,
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
                         PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
@@ -2102,7 +2119,7 @@ enum {
                         PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | \
                         PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | \
                         PPC2_ALTIVEC_207 | PPC2_ISA207S | PPC2_DFP | \
-                        PPC2_FP_CVT_S64 | PPC2_TM | PPC2_PM_ISA206)
+                        PPC2_FP_CVT_S64 | PPC2_TM)
 };
 
 /*****************************************************************************/
@@ -2232,15 +2249,12 @@ enum {
     PPC_INTERRUPT_CDOORBELL,      /* Critical doorbell interrupt          */
     PPC_INTERRUPT_DOORBELL,       /* Doorbell interrupt                   */
     PPC_INTERRUPT_PERFM,          /* Performance monitor interrupt        */
-    PPC_INTERRUPT_HMI,            /* Hypervisor Maintainance interrupt    */
-    PPC_INTERRUPT_HDOORBELL,      /* Hypervisor Doorbell interrupt        */
 };
 
 /* Processor Compatibility mask (PCR) */
 enum {
     PCR_COMPAT_2_05     = 1ull << (63-62),
     PCR_COMPAT_2_06     = 1ull << (63-61),
-    PCR_COMPAT_2_07     = 1ull << (63-60),
     PCR_VEC_DIS         = 1ull << (63-0), /* Vec. disable (bit NA since POWER8) */
     PCR_VSX_DIS         = 1ull << (63-1), /* VSX disable (bit NA since POWER8) */
     PCR_TM_DIS          = 1ull << (63-2), /* Trans. memory disable (POWER8) */
@@ -2289,7 +2303,7 @@ static inline void cpu_write_xer(CPUPPCState *env, target_ulong xer)
 }
 
 static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *pc = env->nip;
     *cs_base = 0;
@@ -2413,6 +2427,8 @@ static inline bool lsw_reg_in_range(int start, int nregs, int rx)
 
 extern void (*cpu_ppc_hypercall)(PowerPCCPU *);
 
+#include "exec/exec-all.h"
+
 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
 
 /**
@@ -2434,4 +2450,4 @@ int ppc_get_vcpu_dt_id(PowerPCCPU *cpu);
 PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id);
 
 void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len);
-#endif /* PPC_CPU_H */
+#endif /* !defined (__CPU_PPC_H__) */
index d6e1678..ca4ffe8 100644 (file)
@@ -19,7 +19,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 #include "helper_regs.h"
@@ -77,8 +76,18 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
     target_ulong msr, new_msr, vector;
-    int srr0, srr1, asrr0, asrr1, lev, ail;
-    bool lpes0;
+    int srr0, srr1, asrr0, asrr1;
+    int lpes0, lpes1, lev, ail;
+
+    if (0) {
+        /* XXX: find a suitable condition to enable the hypervisor mode */
+        lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;
+        lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;
+    } else {
+        /* Those values ensure we won't enter the hypervisor mode */
+        lpes0 = 0;
+        lpes1 = 1;
+    }
 
     qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
                   " => %08x (%02x)\n", env->nip, excp, env->error_code);
@@ -90,10 +99,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         msr = env->msr & ~0x783f0000ULL;
     }
 
-    /* new interrupt handler msr preserves existing HV and ME unless
-     * explicitly overriden
-     */
-    new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
+    /* new interrupt handler msr */
+    new_msr = env->msr & ((target_ulong)1 << MSR_ME);
 
     /* target registers */
     srr0 = SPR_SRR0;
@@ -101,59 +108,14 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     asrr0 = -1;
     asrr1 = -1;
 
-    /* check for special resume at 0x100 from doze/nap/sleep/winkle on P7/P8 */
-    if (env->in_pm_state) {
-        env->in_pm_state = false;
-
-        /* Pretend to be returning from doze always as we don't lose state */
-        msr |= (0x1ull << (63 - 47));
-
-        /* Non-machine check are routed to 0x100 with a wakeup cause
-         * encoded in SRR1
-         */
-        if (excp != POWERPC_EXCP_MCHECK) {
-            switch (excp) {
-            case POWERPC_EXCP_RESET:
-                msr |= 0x4ull << (63 - 45);
-                break;
-            case POWERPC_EXCP_EXTERNAL:
-                msr |= 0x8ull << (63 - 45);
-                break;
-            case POWERPC_EXCP_DECR:
-                msr |= 0x6ull << (63 - 45);
-                break;
-            case POWERPC_EXCP_SDOOR:
-                msr |= 0x5ull << (63 - 45);
-                break;
-            case POWERPC_EXCP_SDOOR_HV:
-                msr |= 0x3ull << (63 - 45);
-                break;
-            case POWERPC_EXCP_HV_MAINT:
-                msr |= 0xaull << (63 - 45);
-                break;
-            default:
-                cpu_abort(cs, "Unsupported exception %d in Power Save mode\n",
-                          excp);
-            }
-            excp = POWERPC_EXCP_RESET;
-        }
-    }
-
     /* Exception targetting modifiers
      *
-     * LPES0 is supported on POWER7/8
-     * LPES1 is not supported (old iSeries mode)
-     *
-     * On anything else, we behave as if LPES0 is 1
-     * (externals don't alter MSR:HV)
-     *
      * AIL is initialized here but can be cleared by
      * selected exceptions
      */
 #if defined(TARGET_PPC64)
     if (excp_model == POWERPC_EXCP_POWER7 ||
         excp_model == POWERPC_EXCP_POWER8) {
-        lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
         if (excp_model == POWERPC_EXCP_POWER8) {
             ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
         } else {
@@ -162,23 +124,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     } else
 #endif /* defined(TARGET_PPC64) */
     {
-        lpes0 = true;
         ail = 0;
     }
 
-    /* Hypervisor emulation assistance interrupt only exists on server
-     * arch 2.05 server or later. We also don't want to generate it if
-     * we don't have HVB in msr_mask (PAPR mode).
-     */
-    if (excp == POWERPC_EXCP_HV_EMU
-#if defined(TARGET_PPC64)
-        && !((env->mmu_model & POWERPC_MMU_64) && (env->msr_mask & MSR_HVB))
-#endif /* defined(TARGET_PPC64) */
-
-    ) {
-        excp = POWERPC_EXCP_PROGRAM;
-    }
-
     switch (excp) {
     case POWERPC_EXCP_NONE:
         /* Should never happen */
@@ -213,7 +161,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             cs->halted = 1;
             cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
         }
-        new_msr |= (target_ulong)MSR_HVB;
+        if (0) {
+            /* XXX: find a suitable condition to enable the hypervisor mode */
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         ail = 0;
 
         /* machine check exceptions don't have ME set */
@@ -239,20 +190,23 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
         LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
                  "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
+        if (lpes1 == 0) {
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         goto store_next;
     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
         LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
                  "\n", msr, env->nip);
+        if (lpes1 == 0) {
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         msr |= env->error_code;
         goto store_next;
     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
         cs = CPU(cpu);
 
-        if (!lpes0) {
+        if (lpes0 == 1) {
             new_msr |= (target_ulong)MSR_HVB;
-            new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
-            srr0 = SPR_HSRR0;
-            srr1 = SPR_HSRR1;
         }
         if (env->mpic_proxy) {
             /* IACK the IRQ on delivery */
@@ -260,6 +214,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
         goto store_next;
     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
+        if (lpes1 == 0) {
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         /* XXX: this is false */
         /* Get rS/rD and rA from faulting opcode */
         env->spr[SPR_DSISR] |= (cpu_ldl_code(env, (env->nip - 4))
@@ -274,6 +231,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
                 env->error_code = 0;
                 return;
             }
+            if (lpes1 == 0) {
+                new_msr |= (target_ulong)MSR_HVB;
+            }
             msr |= 0x00100000;
             if (msr_fe0 == msr_fe1) {
                 goto store_next;
@@ -282,14 +242,23 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             break;
         case POWERPC_EXCP_INVAL:
             LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
+            if (lpes1 == 0) {
+                new_msr |= (target_ulong)MSR_HVB;
+            }
             msr |= 0x00080000;
             env->spr[SPR_BOOKE_ESR] = ESR_PIL;
             break;
         case POWERPC_EXCP_PRIV:
+            if (lpes1 == 0) {
+                new_msr |= (target_ulong)MSR_HVB;
+            }
             msr |= 0x00040000;
             env->spr[SPR_BOOKE_ESR] = ESR_PPR;
             break;
         case POWERPC_EXCP_TRAP:
+            if (lpes1 == 0) {
+                new_msr |= (target_ulong)MSR_HVB;
+            }
             msr |= 0x00020000;
             env->spr[SPR_BOOKE_ESR] = ESR_PTR;
             break;
@@ -300,30 +269,28 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             break;
         }
         goto store_current;
-    case POWERPC_EXCP_HV_EMU:
-        srr0 = SPR_HSRR0;
-        srr1 = SPR_HSRR1;
-        new_msr |= (target_ulong)MSR_HVB;
-        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
-        goto store_current;
     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
+        if (lpes1 == 0) {
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         goto store_current;
     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
         dump_syscall(env);
         lev = env->error_code;
-
-        /* "PAPR mode" built-in hypercall emulation */
         if ((lev == 1) && cpu_ppc_hypercall) {
             cpu_ppc_hypercall(cpu);
             return;
         }
-        if (lev == 1) {
+        if (lev == 1 || (lpes0 == 0 && lpes1 == 0)) {
             new_msr |= (target_ulong)MSR_HVB;
         }
         goto store_next;
     case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
         goto store_current;
     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
+        if (lpes1 == 0) {
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         goto store_next;
     case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
         /* FIT on 4xx */
@@ -393,12 +360,21 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             new_msr &= ~((target_ulong)1 << MSR_ME);
         }
 
-        new_msr |= (target_ulong)MSR_HVB;
+        if (0) {
+            /* XXX: find a suitable condition to enable the hypervisor mode */
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         ail = 0;
         goto store_next;
     case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
+        if (lpes1 == 0) {
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         goto store_next;
     case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
+        if (lpes1 == 0) {
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         goto store_next;
     case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
         srr0 = SPR_HSRR0;
@@ -407,6 +383,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
         goto store_next;
     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
+        if (lpes1 == 0) {
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         goto store_next;
     case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
         srr0 = SPR_HSRR0;
@@ -433,10 +412,19 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
         goto store_next;
     case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
+        if (lpes1 == 0) {
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         goto store_current;
     case POWERPC_EXCP_VSXU:       /* VSX unavailable exception               */
+        if (lpes1 == 0) {
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         goto store_current;
     case POWERPC_EXCP_FU:         /* Facility unavailable exception          */
+        if (lpes1 == 0) {
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         goto store_current;
     case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
         LOG_EXCP("PIT exception\n");
@@ -455,6 +443,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
                   "is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
+        if (lpes1 == 0) { /* XXX: check this */
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         switch (excp_model) {
         case POWERPC_EXCP_602:
         case POWERPC_EXCP_603:
@@ -471,6 +462,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
         break;
     case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
+        if (lpes1 == 0) { /* XXX: check this */
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         switch (excp_model) {
         case POWERPC_EXCP_602:
         case POWERPC_EXCP_603:
@@ -487,6 +481,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
         break;
     case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
+        if (lpes1 == 0) { /* XXX: check this */
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         switch (excp_model) {
         case POWERPC_EXCP_602:
         case POWERPC_EXCP_603:
@@ -592,6 +589,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
                   "is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
+        if (lpes1 == 0) {
+            new_msr |= (target_ulong)MSR_HVB;
+        }
         /* XXX: TODO */
         cpu_abort(cs,
                   "Performance counter exception is not implemented yet !\n");
@@ -635,13 +635,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     }
     /* Save MSR */
     env->spr[srr1] = msr;
-
-    /* Sanity check */
-    if (!(env->msr_mask & MSR_HVB) && (srr0 == SPR_HSRR0)) {
-        cpu_abort(cs, "Trying to deliver HV exception %d with "
-                  "no HV support\n", excp);
-    }
-
     /* If any alternate SRR register are defined, duplicate saved values */
     if (asrr0 != -1) {
         env->spr[asrr0] = env->spr[srr0];
@@ -650,20 +643,17 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         env->spr[asrr1] = env->spr[srr1];
     }
 
-    /* Sort out endianness of interrupt, this differs depending on the
-     * CPU, the HV mode, etc...
-     */
+    if (env->spr[SPR_LPCR] & LPCR_AIL) {
+        new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
+    } else if (msr & ((1 << MSR_IR) | (1 << MSR_DR))) {
+        /* If we disactivated any translation, flush TLBs */
+        tlb_flush(cs, 1);
+    }
+
 #ifdef TARGET_PPC64
-    if (excp_model == POWERPC_EXCP_POWER7) {
-        if (!(new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) {
-            new_msr |= (target_ulong)1 << MSR_LE;
-        }
-    } else if (excp_model == POWERPC_EXCP_POWER8) {
-        if (new_msr & MSR_HVB) {
-            if (env->spr[SPR_HID0] & HID0_HILE) {
-                new_msr |= (target_ulong)1 << MSR_LE;
-            }
-        } else if (env->spr[SPR_LPCR] & LPCR_ILE) {
+    if (excp_model == POWERPC_EXCP_POWER7 ||
+        excp_model == POWERPC_EXCP_POWER8) {
+        if (env->spr[SPR_LPCR] & LPCR_ILE) {
             new_msr |= (target_ulong)1 << MSR_LE;
         }
     } else if (msr_ile) {
@@ -686,8 +676,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     /* AIL only works if there is no HV transition and we are running with
      * translations enabled
      */
-    if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1) ||
-        ((new_msr & MSR_HVB) && !(msr & MSR_HVB))) {
+    if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1)) {
         ail = 0;
     }
     /* Handle AIL */
@@ -722,12 +711,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
     }
 #endif
-    /* We don't use hreg_store_msr here as already have treated
-     * any special case that could occur. Just store MSR and update hflags
-     *
-     * Note: We *MUST* not use hreg_store_msr() as-is anyway because it
-     * will prevent setting of the HV bit which some exceptions might need
-     * to do.
+    /* XXX: we don't use hreg_store_msr here as already have treated
+     *      any special case that could occur. Just store MSR and update hflags
      */
     env->msr = new_msr & env->msr_mask;
     hreg_compute_hflags(env);
@@ -736,10 +721,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     cs->exception_index = POWERPC_EXCP_NONE;
     env->error_code = 0;
 
-    /* Any interrupt is context synchronizing, check if TCG TLB
-     * needs a delayed flush on ppc64
-     */
-    check_tlb_flush(env);
+    if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
+        (env->mmu_model == POWERPC_MMU_BOOKE206)) {
+        /* XXX: The BookE changes address space when switching modes,
+                we should probably implement that as different MMU indexes,
+                but for the moment we do it the slow way and flush all.  */
+        tlb_flush(cs, 1);
+    }
 }
 
 void ppc_cpu_do_interrupt(CPUState *cs)
@@ -753,6 +741,7 @@ void ppc_cpu_do_interrupt(CPUState *cs)
 static void ppc_hw_interrupt(CPUPPCState *env)
 {
     PowerPCCPU *cpu = ppc_env_get_cpu(env);
+    int hdice;
 #if 0
     CPUState *cs = CPU(cpu);
 
@@ -780,22 +769,16 @@ static void ppc_hw_interrupt(CPUPPCState *env)
         return;
     }
 #endif
-    /* Hypervisor decrementer exception */
-    if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
-        /* LPCR will be clear when not supported so this will work */
-        bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
-        if ((msr_ee != 0 || msr_hv == 0) && hdice) {
-            /* HDEC clears on delivery */
-            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
-            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HDECR);
-            return;
-        }
+    if (0) {
+        /* XXX: find a suitable condition to enable the hypervisor mode */
+        hdice = env->spr[SPR_LPCR] & 1;
+    } else {
+        hdice = 0;
     }
-    /* Extermal interrupt can ignore MSR:EE under some circumstances */
-    if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
-        bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
-        if (msr_ee != 0 || (env->has_hv_mode && msr_hv == 0 && !lpes0)) {
-            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL);
+    if ((msr_ee != 0 || msr_hv == 0 || msr_pr != 0) && hdice != 0) {
+        /* Hypervisor decrementer exception */
+        if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
+            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HDECR);
             return;
         }
     }
@@ -844,6 +827,17 @@ static void ppc_hw_interrupt(CPUPPCState *env)
             powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DECR);
             return;
         }
+        /* External interrupt */
+        if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
+            /* Taking an external interrupt does not clear the external
+             * interrupt status
+             */
+#if 0
+            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
+#endif
+            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL);
+            return;
+        }
         if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
             powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);
@@ -929,46 +923,25 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
     }
 }
 
-#if defined(TARGET_PPC64)
-void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn)
-{
-    CPUState *cs;
-
-    cs = CPU(ppc_env_get_cpu(env));
-    cs->halted = 1;
-    env->in_pm_state = true;
-
-    /* The architecture specifies that HDEC interrupts are
-     * discarded in PM states
-     */
-    env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
-
-    /* Technically, nap doesn't set EE, but if we don't set it
-     * then ppc_hw_interrupt() won't deliver. We could add some
-     * other tests there based on LPCR but it's simpler to just
-     * whack EE in. It will be cleared by the 0x100 at wakeup
-     * anyway. It will still be observable by the guest in SRR1
-     * but this doesn't seem to be a problem.
-     */
-    env->msr |= (1ull << MSR_EE);
-    helper_raise_exception(env, EXCP_HLT);
-}
-#endif /* defined(TARGET_PPC64) */
-
-static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
+static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
+                          target_ulong msrm, int keep_msrh)
 {
     CPUState *cs = CPU(ppc_env_get_cpu(env));
 
-    /* MSR:POW cannot be set by any form of rfi */
-    msr &= ~(1ULL << MSR_POW);
-
 #if defined(TARGET_PPC64)
-    /* Switching to 32-bit ? Crop the nip */
-    if (!msr_is_64bit(env, msr)) {
+    if (msr_is_64bit(env, msr)) {
+        nip = (uint64_t)nip;
+        msr &= (uint64_t)msrm;
+    } else {
         nip = (uint32_t)nip;
+        msr = (uint32_t)(msr & msrm);
+        if (keep_msrh) {
+            msr |= env->msr & ~((uint64_t)0xFFFFFFFF);
+        }
     }
 #else
     nip = (uint32_t)nip;
+    msr &= (uint32_t)msrm;
 #endif
     /* XXX: beware: this is false if VLE is supported */
     env->nip = nip & ~((target_ulong)0x00000003);
@@ -980,31 +953,30 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
      * as rfi is always the last insn of a TB
      */
     cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
-
-    /* Context synchronizing: check if TCG TLB needs flush */
-    check_tlb_flush(env);
 }
 
 void helper_rfi(CPUPPCState *env)
 {
-    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
+    if (env->excp_model == POWERPC_EXCP_BOOKE) {
+        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
+               ~((target_ulong)0), 0);
+    } else {
+        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
+               ~((target_ulong)0x783F0000), 1);
+    }
 }
 
-#define MSR_BOOK3S_MASK
 #if defined(TARGET_PPC64)
 void helper_rfid(CPUPPCState *env)
 {
-    /* The architeture defines a number of rules for which bits
-     * can change but in practice, we handle this in hreg_store_msr()
-     * which will be called by do_rfi(), so there is no need to filter
-     * here
-     */
-    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
+    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
+           ~((target_ulong)0x783F0000), 0);
 }
 
 void helper_hrfid(CPUPPCState *env)
 {
-    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
+    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
+           ~((target_ulong)0x783F0000), 0);
 }
 #endif
 
@@ -1012,24 +984,28 @@ void helper_hrfid(CPUPPCState *env)
 /* Embedded PowerPC specific helpers */
 void helper_40x_rfci(CPUPPCState *env)
 {
-    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
+    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3],
+           ~((target_ulong)0xFFFF0000), 0);
 }
 
 void helper_rfci(CPUPPCState *env)
 {
-    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
+    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
+           ~((target_ulong)0), 0);
 }
 
 void helper_rfdi(CPUPPCState *env)
 {
     /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
-    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
+    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1],
+           ~((target_ulong)0), 0);
 }
 
 void helper_rfmci(CPUPPCState *env)
 {
     /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
-    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
+    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1],
+           ~((target_ulong)0), 0);
 }
 #endif
 
@@ -1067,7 +1043,7 @@ void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
 
 void helper_rfsvc(CPUPPCState *env)
 {
-    do_rfi(env, env->lr, env->ctr & 0x0000FFFF);
+    do_rfi(env, env->lr, env->ctr, 0x0000FFFF, 0);
 }
 
 /* Embedded.Processor Control */
index d9795d0..b67ebca 100644 (file)
@@ -73,7 +73,7 @@ void helper_compute_fprf(CPUPPCState *env, uint64_t arg)
     farg.ll = arg;
     isneg = float64_is_neg(farg.d);
     if (unlikely(float64_is_any_nan(farg.d))) {
-        if (float64_is_signaling_nan(farg.d, &env->fp_status)) {
+        if (float64_is_signaling_nan(farg.d)) {
             /* Signaling NaN: flags are undefined */
             fprf = 0x00;
         } else {
@@ -534,8 +534,8 @@ uint64_t helper_fadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
         /* Magnitude subtraction of infinities */
         farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
     } else {
-        if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
-                     float64_is_signaling_nan(farg2.d, &env->fp_status))) {
+        if (unlikely(float64_is_signaling_nan(farg1.d) ||
+                     float64_is_signaling_nan(farg2.d))) {
             /* sNaN addition */
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
@@ -558,8 +558,8 @@ uint64_t helper_fsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
         /* Magnitude subtraction of infinities */
         farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
     } else {
-        if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
-                     float64_is_signaling_nan(farg2.d, &env->fp_status))) {
+        if (unlikely(float64_is_signaling_nan(farg1.d) ||
+                     float64_is_signaling_nan(farg2.d))) {
             /* sNaN subtraction */
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
@@ -582,8 +582,8 @@ uint64_t helper_fmul(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
         /* Multiplication of zero by infinity */
         farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
     } else {
-        if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
-                     float64_is_signaling_nan(farg2.d, &env->fp_status))) {
+        if (unlikely(float64_is_signaling_nan(farg1.d) ||
+                     float64_is_signaling_nan(farg2.d))) {
             /* sNaN multiplication */
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
@@ -609,8 +609,8 @@ uint64_t helper_fdiv(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
         /* Division of zero by zero */
         farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, 1);
     } else {
-        if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
-                     float64_is_signaling_nan(farg2.d, &env->fp_status))) {
+        if (unlikely(float64_is_signaling_nan(farg1.d) ||
+                     float64_is_signaling_nan(farg2.d))) {
             /* sNaN division */
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
@@ -632,7 +632,7 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg)                   \
     if (unlikely(env->fp_status.float_exception_flags)) {              \
         if (float64_is_any_nan(arg)) {                                 \
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1);      \
-            if (float64_is_signaling_nan(arg, &env->fp_status)) {      \
+            if (float64_is_signaling_nan(arg)) {                       \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); \
             }                                                          \
             farg.ll = nanval;                                          \
@@ -681,7 +681,7 @@ static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg,
 
     farg.ll = arg;
 
-    if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
+    if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN round */
         fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         farg.ll = arg | 0x0008000000000000ULL;
@@ -737,9 +737,9 @@ uint64_t helper_fmadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
         /* Multiplication of zero by infinity */
         farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
     } else {
-        if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
-                     float64_is_signaling_nan(farg2.d, &env->fp_status) ||
-                     float64_is_signaling_nan(farg3.d, &env->fp_status))) {
+        if (unlikely(float64_is_signaling_nan(farg1.d) ||
+                     float64_is_signaling_nan(farg2.d) ||
+                     float64_is_signaling_nan(farg3.d))) {
             /* sNaN operation */
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
@@ -780,9 +780,9 @@ uint64_t helper_fmsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
         /* Multiplication of zero by infinity */
         farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
     } else {
-        if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
-                     float64_is_signaling_nan(farg2.d, &env->fp_status) ||
-                     float64_is_signaling_nan(farg3.d, &env->fp_status))) {
+        if (unlikely(float64_is_signaling_nan(farg1.d) ||
+                     float64_is_signaling_nan(farg2.d) ||
+                     float64_is_signaling_nan(farg3.d))) {
             /* sNaN operation */
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
@@ -821,9 +821,9 @@ uint64_t helper_fnmadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
         /* Multiplication of zero by infinity */
         farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
     } else {
-        if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
-                     float64_is_signaling_nan(farg2.d, &env->fp_status) ||
-                     float64_is_signaling_nan(farg3.d, &env->fp_status))) {
+        if (unlikely(float64_is_signaling_nan(farg1.d) ||
+                     float64_is_signaling_nan(farg2.d) ||
+                     float64_is_signaling_nan(farg3.d))) {
             /* sNaN operation */
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
@@ -866,9 +866,9 @@ uint64_t helper_fnmsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
         /* Multiplication of zero by infinity */
         farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
     } else {
-        if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
-                     float64_is_signaling_nan(farg2.d, &env->fp_status) ||
-                     float64_is_signaling_nan(farg3.d, &env->fp_status))) {
+        if (unlikely(float64_is_signaling_nan(farg1.d) ||
+                     float64_is_signaling_nan(farg2.d) ||
+                     float64_is_signaling_nan(farg3.d))) {
             /* sNaN operation */
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
@@ -903,7 +903,7 @@ uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)
 
     farg.ll = arg;
 
-    if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
+    if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN square root */
         fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
     }
@@ -921,7 +921,7 @@ uint64_t helper_fsqrt(CPUPPCState *env, uint64_t arg)
     farg.ll = arg;
 
     if (unlikely(float64_is_any_nan(farg.d))) {
-        if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
+        if (unlikely(float64_is_signaling_nan(farg.d))) {
             /* sNaN reciprocal square root */
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
             farg.ll = float64_snan_to_qnan(farg.ll);
@@ -942,7 +942,7 @@ uint64_t helper_fre(CPUPPCState *env, uint64_t arg)
 
     farg.ll = arg;
 
-    if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
+    if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN reciprocal */
         fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
     }
@@ -958,7 +958,7 @@ uint64_t helper_fres(CPUPPCState *env, uint64_t arg)
 
     farg.ll = arg;
 
-    if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
+    if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN reciprocal */
         fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
     }
@@ -977,7 +977,7 @@ uint64_t helper_frsqrte(CPUPPCState *env, uint64_t arg)
     farg.ll = arg;
 
     if (unlikely(float64_is_any_nan(farg.d))) {
-        if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
+        if (unlikely(float64_is_signaling_nan(farg.d))) {
             /* sNaN reciprocal square root */
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
             farg.ll = float64_snan_to_qnan(farg.ll);
@@ -1100,8 +1100,8 @@ void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
     env->fpscr |= ret << FPSCR_FPRF;
     env->crf[crfD] = ret;
     if (unlikely(ret == 0x01UL
-                 && (float64_is_signaling_nan(farg1.d, &env->fp_status) ||
-                     float64_is_signaling_nan(farg2.d, &env->fp_status)))) {
+                 && (float64_is_signaling_nan(farg1.d) ||
+                     float64_is_signaling_nan(farg2.d)))) {
         /* sNaN comparison */
         fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
     }
@@ -1131,8 +1131,8 @@ void helper_fcmpo(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
     env->fpscr |= ret << FPSCR_FPRF;
     env->crf[crfD] = ret;
     if (unlikely(ret == 0x01UL)) {
-        if (float64_is_signaling_nan(farg1.d, &env->fp_status) ||
-            float64_is_signaling_nan(farg2.d, &env->fp_status)) {
+        if (float64_is_signaling_nan(farg1.d) ||
+            float64_is_signaling_nan(farg2.d)) {
             /* sNaN comparison */
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
                                   POWERPC_EXCP_FP_VXVC, 1);
@@ -1168,7 +1168,7 @@ static inline int32_t efsctsi(CPUPPCState *env, uint32_t val)
 
     u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(float32_is_quiet_nan(u.f, &env->vec_status))) {
+    if (unlikely(float32_is_quiet_nan(u.f))) {
         return 0;
     }
 
@@ -1181,7 +1181,7 @@ static inline uint32_t efsctui(CPUPPCState *env, uint32_t val)
 
     u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(float32_is_quiet_nan(u.f, &env->vec_status))) {
+    if (unlikely(float32_is_quiet_nan(u.f))) {
         return 0;
     }
 
@@ -1194,7 +1194,7 @@ static inline uint32_t efsctsiz(CPUPPCState *env, uint32_t val)
 
     u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(float32_is_quiet_nan(u.f, &env->vec_status))) {
+    if (unlikely(float32_is_quiet_nan(u.f))) {
         return 0;
     }
 
@@ -1207,7 +1207,7 @@ static inline uint32_t efsctuiz(CPUPPCState *env, uint32_t val)
 
     u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(float32_is_quiet_nan(u.f, &env->vec_status))) {
+    if (unlikely(float32_is_quiet_nan(u.f))) {
         return 0;
     }
 
@@ -1245,7 +1245,7 @@ static inline uint32_t efsctsf(CPUPPCState *env, uint32_t val)
 
     u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(float32_is_quiet_nan(u.f, &env->vec_status))) {
+    if (unlikely(float32_is_quiet_nan(u.f))) {
         return 0;
     }
     tmp = uint64_to_float32(1ULL << 32, &env->vec_status);
@@ -1261,7 +1261,7 @@ static inline uint32_t efsctuf(CPUPPCState *env, uint32_t val)
 
     u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(float32_is_quiet_nan(u.f, &env->vec_status))) {
+    if (unlikely(float32_is_quiet_nan(u.f))) {
         return 0;
     }
     tmp = uint64_to_float32(1ULL << 32, &env->vec_status);
@@ -1442,7 +1442,7 @@ static inline uint32_t efststeq(CPUPPCState *env, uint32_t op1, uint32_t op2)
 #define HELPER_SINGLE_SPE_CMP(name)                                     \
     uint32_t helper_e##name(CPUPPCState *env, uint32_t op1, uint32_t op2) \
     {                                                                   \
-        return e##name(env, op1, op2);                                  \
+        return e##name(env, op1, op2) << 2;                             \
     }
 /* efststlt */
 HELPER_SINGLE_SPE_CMP(fststlt);
@@ -1839,8 +1839,8 @@ void helper_##name(CPUPPCState *env, uint32_t opcode)                        \
         if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {    \
             if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) {      \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf);    \
-            } else if (tp##_is_signaling_nan(xa.fld, &tstat) ||              \
-                       tp##_is_signaling_nan(xb.fld, &tstat)) {              \
+            } else if (tp##_is_signaling_nan(xa.fld) ||                      \
+                       tp##_is_signaling_nan(xb.fld)) {                      \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);   \
             }                                                                \
         }                                                                    \
@@ -1894,8 +1894,8 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
             if ((tp##_is_infinity(xa.fld) && tp##_is_zero(xb.fld)) ||        \
                 (tp##_is_infinity(xb.fld) && tp##_is_zero(xa.fld))) {        \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, sfprf);    \
-            } else if (tp##_is_signaling_nan(xa.fld, &tstat) ||              \
-                       tp##_is_signaling_nan(xb.fld, &tstat)) {              \
+            } else if (tp##_is_signaling_nan(xa.fld) ||                      \
+                       tp##_is_signaling_nan(xb.fld)) {                      \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);   \
             }                                                                \
         }                                                                    \
@@ -1948,8 +1948,8 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
             } else if (tp##_is_zero(xa.fld) &&                                \
                 tp##_is_zero(xb.fld)) {                                       \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, sfprf);     \
-            } else if (tp##_is_signaling_nan(xa.fld, &tstat) ||               \
-                tp##_is_signaling_nan(xb.fld, &tstat)) {                      \
+            } else if (tp##_is_signaling_nan(xa.fld) ||                       \
+                tp##_is_signaling_nan(xb.fld)) {                              \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);    \
             }                                                                 \
         }                                                                     \
@@ -1990,7 +1990,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
     helper_reset_fpstatus(env);                                               \
                                                                               \
     for (i = 0; i < nels; i++) {                                              \
-        if (unlikely(tp##_is_signaling_nan(xb.fld, &env->fp_status))) {       \
+        if (unlikely(tp##_is_signaling_nan(xb.fld))) {                        \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);    \
         }                                                                     \
         xt.fld = tp##_div(tp##_one, xb.fld, &env->fp_status);                 \
@@ -2039,7 +2039,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
         if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {    \
             if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) {              \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf);   \
-            } else if (tp##_is_signaling_nan(xb.fld, &tstat)) {              \
+            } else if (tp##_is_signaling_nan(xb.fld)) {                      \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);   \
             }                                                                \
         }                                                                    \
@@ -2089,7 +2089,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
         if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {    \
             if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) {              \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf);   \
-            } else if (tp##_is_signaling_nan(xb.fld, &tstat)) {              \
+            } else if (tp##_is_signaling_nan(xb.fld)) {                      \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);   \
             }                                                                \
         }                                                                    \
@@ -2274,9 +2274,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
         env->fp_status.float_exception_flags |= tstat.float_exception_flags;  \
                                                                               \
         if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {     \
-            if (tp##_is_signaling_nan(xa.fld, &tstat) ||                      \
-                tp##_is_signaling_nan(b->fld, &tstat) ||                      \
-                tp##_is_signaling_nan(c->fld, &tstat)) {                      \
+            if (tp##_is_signaling_nan(xa.fld) ||                              \
+                tp##_is_signaling_nan(b->fld) ||                              \
+                tp##_is_signaling_nan(c->fld)) {                              \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);    \
                 tstat.float_exception_flags &= ~float_flag_invalid;           \
             }                                                                 \
@@ -2358,8 +2358,8 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                      \
                                                                          \
     if (unlikely(float64_is_any_nan(xa.VsrD(0)) ||                       \
                  float64_is_any_nan(xb.VsrD(0)))) {                      \
-        if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) ||     \
-            float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) {     \
+        if (float64_is_signaling_nan(xa.VsrD(0)) ||                      \
+            float64_is_signaling_nan(xb.VsrD(0))) {                      \
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);       \
         }                                                                \
         if (ordered) {                                                   \
@@ -2406,8 +2406,8 @@ void helper_##name(CPUPPCState *env, uint32_t opcode)                         \
                                                                               \
     for (i = 0; i < nels; i++) {                                              \
         xt.fld = tp##_##op(xa.fld, xb.fld, &env->fp_status);                  \
-        if (unlikely(tp##_is_signaling_nan(xa.fld, &env->fp_status) ||        \
-                     tp##_is_signaling_nan(xb.fld, &env->fp_status))) {       \
+        if (unlikely(tp##_is_signaling_nan(xa.fld) ||                         \
+                     tp##_is_signaling_nan(xb.fld))) {                        \
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);            \
         }                                                                     \
     }                                                                         \
@@ -2446,8 +2446,8 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                       \
     for (i = 0; i < nels; i++) {                                          \
         if (unlikely(tp##_is_any_nan(xa.fld) ||                           \
                      tp##_is_any_nan(xb.fld))) {                          \
-            if (tp##_is_signaling_nan(xa.fld, &env->fp_status) ||         \
-                tp##_is_signaling_nan(xb.fld, &env->fp_status)) {         \
+            if (tp##_is_signaling_nan(xa.fld) ||                          \
+                tp##_is_signaling_nan(xb.fld)) {                          \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);    \
             }                                                             \
             if (svxvc) {                                                  \
@@ -2500,8 +2500,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                \
                                                                    \
     for (i = 0; i < nels; i++) {                                   \
         xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status);        \
-        if (unlikely(stp##_is_signaling_nan(xb.sfld,               \
-                                            &env->fp_status))) {   \
+        if (unlikely(stp##_is_signaling_nan(xb.sfld))) {           \
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
             xt.tfld = ttp##_snan_to_qnan(xt.tfld);                 \
         }                                                          \
@@ -2556,7 +2555,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
                                                                              \
     for (i = 0; i < nels; i++) {                                             \
         if (unlikely(stp##_is_any_nan(xb.sfld))) {                           \
-            if (stp##_is_signaling_nan(xb.sfld, &env->fp_status)) {          \
+            if (stp##_is_signaling_nan(xb.sfld)) {                           \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);       \
             }                                                                \
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0);            \
@@ -2665,8 +2664,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                    \
     }                                                                  \
                                                                        \
     for (i = 0; i < nels; i++) {                                       \
-        if (unlikely(tp##_is_signaling_nan(xb.fld,                     \
-                                           &env->fp_status))) {        \
+        if (unlikely(tp##_is_signaling_nan(xb.fld))) {                 \
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);     \
             xt.fld = tp##_snan_to_qnan(xb.fld);                        \
         } else {                                                       \
@@ -2689,19 +2687,19 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                    \
     helper_float_check_status(env);                                    \
 }
 
-VSX_ROUND(xsrdpi, 1, float64, VsrD(0), float_round_ties_away, 1)
+VSX_ROUND(xsrdpi, 1, float64, VsrD(0), float_round_nearest_even, 1)
 VSX_ROUND(xsrdpic, 1, float64, VsrD(0), FLOAT_ROUND_CURRENT, 1)
 VSX_ROUND(xsrdpim, 1, float64, VsrD(0), float_round_down, 1)
 VSX_ROUND(xsrdpip, 1, float64, VsrD(0), float_round_up, 1)
 VSX_ROUND(xsrdpiz, 1, float64, VsrD(0), float_round_to_zero, 1)
 
-VSX_ROUND(xvrdpi, 2, float64, VsrD(i), float_round_ties_away, 0)
+VSX_ROUND(xvrdpi, 2, float64, VsrD(i), float_round_nearest_even, 0)
 VSX_ROUND(xvrdpic, 2, float64, VsrD(i), FLOAT_ROUND_CURRENT, 0)
 VSX_ROUND(xvrdpim, 2, float64, VsrD(i), float_round_down, 0)
 VSX_ROUND(xvrdpip, 2, float64, VsrD(i), float_round_up, 0)
 VSX_ROUND(xvrdpiz, 2, float64, VsrD(i), float_round_to_zero, 0)
 
-VSX_ROUND(xvrspi, 4, float32, VsrW(i), float_round_ties_away, 0)
+VSX_ROUND(xvrspi, 4, float32, VsrW(i), float_round_nearest_even, 0)
 VSX_ROUND(xvrspic, 4, float32, VsrW(i), FLOAT_ROUND_CURRENT, 0)
 VSX_ROUND(xvrspim, 4, float32, VsrW(i), float_round_down, 0)
 VSX_ROUND(xvrspip, 4, float32, VsrW(i), float_round_up, 0)
index 7a33813..569c380 100644 (file)
@@ -19,7 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
 
 static int ppc_gdb_register_len_apple(int n)
index 1f5cfd0..e5a8f7b 100644 (file)
@@ -13,12 +13,9 @@ DEF_HELPER_1(rfci, void, env)
 DEF_HELPER_1(rfdi, void, env)
 DEF_HELPER_1(rfmci, void, env)
 #if defined(TARGET_PPC64)
-DEF_HELPER_2(pminsn, void, env, i32)
 DEF_HELPER_1(rfid, void, env)
 DEF_HELPER_1(hrfid, void, env)
-DEF_HELPER_2(store_lpcr, void, env, tl)
 #endif
-DEF_HELPER_1(check_tlb_flush, void, env)
 #endif
 
 DEF_HELPER_3(lmw, void, env, tl, i32)
@@ -552,7 +549,6 @@ DEF_HELPER_FLAGS_2(tlbiva, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_FLAGS_3(store_slb, TCG_CALL_NO_RWG, void, env, tl, tl)
 DEF_HELPER_2(load_slb_esid, tl, env, tl)
 DEF_HELPER_2(load_slb_vsid, tl, env, tl)
-DEF_HELPER_2(find_slb_vsid, tl, env, tl)
 DEF_HELPER_FLAGS_1(slbia, TCG_CALL_NO_RWG, void, env)
 DEF_HELPER_FLAGS_2(slbie, TCG_CALL_NO_RWG, void, env, tl)
 #endif
@@ -600,8 +596,6 @@ DEF_HELPER_2(store_601_rtcl, void, env, tl)
 DEF_HELPER_2(store_601_rtcu, void, env, tl)
 DEF_HELPER_1(load_decr, tl, env)
 DEF_HELPER_2(store_decr, void, env, tl)
-DEF_HELPER_1(load_hdecr, tl, env)
-DEF_HELPER_2(store_hdecr, void, env, tl)
 DEF_HELPER_2(store_hid0_601, void, env, tl)
 DEF_HELPER_3(store_403_pbr, void, env, i32, tl)
 DEF_HELPER_1(load_40x_pit, tl, env)
@@ -674,4 +668,3 @@ DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscliq, void, env, fprp, fprp, i32)
 
 DEF_HELPER_1(tbegin, void, env)
-DEF_HELPER_1(fixup_thrm, void, env)
index 3d279f1..271fddf 100644 (file)
@@ -17,8 +17,8 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef HELPER_REGS_H
-#define HELPER_REGS_H
+#if !defined(__HELPER_REGS_H__)
+#define __HELPER_REGS_H__
 
 /* Swap temporary saved registers with GPRs */
 static inline void hreg_swap_gpr_tgpr(CPUPPCState *env)
@@ -41,43 +41,11 @@ static inline void hreg_swap_gpr_tgpr(CPUPPCState *env)
 
 static inline void hreg_compute_mem_idx(CPUPPCState *env)
 {
-    /* This is our encoding for server processors. The architecture
-     * specifies that there is no such thing as userspace with
-     * translation off, however it appears that MacOS does it and
-     * some 32-bit CPUs support it. Weird...
-     *
-     *   0 = Guest User space virtual mode
-     *   1 = Guest Kernel space virtual mode
-     *   2 = Guest User space real mode
-     *   3 = Guest Kernel space real mode
-     *   4 = HV User space virtual mode
-     *   5 = HV Kernel space virtual mode
-     *   6 = HV User space real mode
-     *   7 = HV Kernel space real mode
-     *
-     * For BookE, we need 8 MMU modes as follow:
-     *
-     *  0 = AS 0 HV User space
-     *  1 = AS 0 HV Kernel space
-     *  2 = AS 1 HV User space
-     *  3 = AS 1 HV Kernel space
-     *  4 = AS 0 Guest User space
-     *  5 = AS 0 Guest Kernel space
-     *  6 = AS 1 Guest User space
-     *  7 = AS 1 Guest Kernel space
-     */
-    if (env->mmu_model & POWERPC_MMU_BOOKE) {
-        env->immu_idx = env->dmmu_idx = msr_pr ? 0 : 1;
-        env->immu_idx += msr_is ? 2 : 0;
-        env->dmmu_idx += msr_ds ? 2 : 0;
-        env->immu_idx += msr_gs ? 4 : 0;
-        env->dmmu_idx += msr_gs ? 4 : 0;
+    /* Precompute MMU index */
+    if (msr_pr == 0 && msr_hv != 0) {
+        env->mmu_idx = 2;
     } else {
-        env->immu_idx = env->dmmu_idx = msr_pr ? 0 : 1;
-        env->immu_idx += msr_ir ? 0 : 2;
-        env->dmmu_idx += msr_dr ? 0 : 2;
-        env->immu_idx += msr_hv ? 4 : 0;
-        env->dmmu_idx += msr_hv ? 4 : 0;
+        env->mmu_idx = 1 - msr_pr;
     }
 }
 
@@ -88,7 +56,7 @@ static inline void hreg_compute_hflags(CPUPPCState *env)
     /* We 'forget' FE0 & FE1: we'll never generate imprecise exceptions */
     hflags_mask = (1 << MSR_VR) | (1 << MSR_AP) | (1 << MSR_SA) |
         (1 << MSR_PR) | (1 << MSR_FP) | (1 << MSR_SE) | (1 << MSR_BE) |
-        (1 << MSR_LE) | (1 << MSR_VSX) | (1 << MSR_IR) | (1 << MSR_DR);
+        (1 << MSR_LE) | (1 << MSR_VSX);
     hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF) | MSR_HVB;
     hreg_compute_mem_idx(env);
     env->hflags = env->msr & hflags_mask;
@@ -107,17 +75,16 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
     excp = 0;
     value &= env->msr_mask;
 #if !defined(CONFIG_USER_ONLY)
-    /* Neither mtmsr nor guest state can alter HV */
-    if (!alter_hv || !(env->msr & MSR_HVB)) {
+    if (!alter_hv) {
+        /* mtmsr cannot alter the hypervisor state */
         value &= ~MSR_HVB;
         value |= env->msr & MSR_HVB;
     }
     if (((value >> MSR_IR) & 1) != msr_ir ||
         ((value >> MSR_DR) & 1) != msr_dr) {
-        cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
-    }
-    if ((env->mmu_model & POWERPC_MMU_BOOKE) &&
-        ((value >> MSR_GS) & 1) != msr_gs) {
+        /* Flush all tlb when changing translation mode */
+        tlb_flush(cs, 1);
+        excp = POWERPC_EXCP_NONE;
         cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
     }
     if (unlikely((env->flags & POWERPC_FLAG_TGPR) &&
@@ -129,15 +96,6 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
         /* Change the exception prefix on PowerPC 601 */
         env->excp_prefix = ((value >> MSR_EP) & 1) * 0xFFF00000;
     }
-    /* If PR=1 then EE, IR and DR must be 1
-     *
-     * Note: We only enforce this on 64-bit processors. It appears that
-     * 32-bit implementations supports PR=1 and EE/DR/IR=0 and MacOS
-     * exploits it.
-     */
-    if ((env->insns_flags & PPC_64B) && ((value >> MSR_PR) & 1)) {
-        value |= (1 << MSR_EE) | (1 << MSR_DR) | (1 << MSR_IR);
-    }
 #endif
     env->msr = value;
     hreg_compute_hflags(env);
@@ -153,17 +111,4 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
     return excp;
 }
 
-#if !defined(CONFIG_USER_ONLY)
-static inline void check_tlb_flush(CPUPPCState *env)
-{
-    CPUState *cs = CPU(ppc_env_get_cpu(env));
-    if (env->tlb_need_flush) {
-        env->tlb_need_flush = 0;
-        tlb_flush(cs, 1);
-    }
-}
-#else
-static inline void check_tlb_flush(CPUPPCState *env) { }
-#endif
-
-#endif /* HELPER_REGS_H */
+#endif /* !defined(__HELPER_REGS_H__) */
index 7445376..27b0258 100644 (file)
@@ -18,7 +18,6 @@
  */
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
 #include "crypto/aes.h"
index efeafca..627bcb4 100644 (file)
@@ -11,7 +11,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "hw/ppc/openpic.h"
 
 int kvm_openpic_connect_vcpu(DeviceState *d, CPUState *cs)
index dcb68b9..c4c8146 100644 (file)
 #include "qemu/osdep.h"
 #include <dirent.h>
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 #include <sys/vfs.h>
 
 #include <linux/kvm.h>
 
 #include "qemu-common.h"
 #include "qemu/error-report.h"
-#include "cpu.h"
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
-#include "sysemu/numa.h"
 #include "kvm_ppc.h"
+#include "cpu.h"
 #include "sysemu/cpus.h"
 #include "sysemu/device_tree.h"
 #include "mmu-hash64.h"
@@ -43,9 +43,6 @@
 #include "exec/memattrs.h"
 #include "sysemu/hostmem.h"
 #include "qemu/cutils.h"
-#if defined(TARGET_PPC64)
-#include "hw/ppc/spapr_cpu_core.h"
-#endif
 
 //#define DEBUG_KVM
 
@@ -366,13 +363,10 @@ static int find_max_supported_pagesize(Object *obj, void *opaque)
 static long getrampagesize(void)
 {
     long hpsize = LONG_MAX;
-    long mainrampagesize;
     Object *memdev_root;
 
     if (mem_path) {
-        mainrampagesize = gethugepagesize(mem_path);
-    } else {
-        mainrampagesize = getpagesize();
+        return gethugepagesize(mem_path);
     }
 
     /* it's possible we have memory-backend objects with
@@ -386,29 +380,13 @@ static long getrampagesize(void)
      * backend isn't backed by hugepages.
      */
     memdev_root = object_resolve_path("/objects", NULL);
-    if (memdev_root) {
-        object_child_foreach(memdev_root, find_max_supported_pagesize, &hpsize);
-    }
-    if (hpsize == LONG_MAX) {
-        /* No additional memory regions found ==> Report main RAM page size */
-        return mainrampagesize;
+    if (!memdev_root) {
+        return getpagesize();
     }
 
-    /* If NUMA is disabled or the NUMA nodes are not backed with a
-     * memory-backend, then there is at least one node using "normal" RAM,
-     * so if its page size is smaller we have got to report that size instead.
-     */
-    if (hpsize > mainrampagesize &&
-        (nb_numa_nodes == 0 || numa_info[0].node_memdev == NULL)) {
-        static bool warned;
-        if (!warned) {
-            error_report("Huge page support disabled (n/a for main memory).");
-            warned = true;
-        }
-        return mainrampagesize;
-    }
+    object_child_foreach(memdev_root, find_max_supported_pagesize, &hpsize);
 
-    return hpsize;
+    return (hpsize == LONG_MAX) ? getpagesize() : hpsize;
 }
 
 static bool kvm_valid_page_size(uint32_t flags, long rampgsize, uint32_t shift)
@@ -2351,32 +2329,6 @@ static PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
     return POWERPC_CPU_CLASS(oc);
 }
 
-PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
-{
-    uint32_t host_pvr = mfpvr();
-    PowerPCCPUClass *pvr_pcc;
-
-    pvr_pcc = ppc_cpu_class_by_pvr(host_pvr);
-    if (pvr_pcc == NULL) {
-        pvr_pcc = ppc_cpu_class_by_pvr_mask(host_pvr);
-    }
-
-    return pvr_pcc;
-}
-
-#if defined(TARGET_PPC64)
-static void spapr_cpu_core_host_initfn(Object *obj)
-{
-    sPAPRCPUCore *core = SPAPR_CPU_CORE(obj);
-    char *name = g_strdup_printf("%s-" TYPE_POWERPC_CPU, "host");
-    ObjectClass *oc = object_class_by_name(name);
-
-    g_assert(oc);
-    g_free((void *)name);
-    core->cpu_class = oc;
-}
-#endif
-
 static int kvm_ppc_register_host_cpu_type(void)
 {
     TypeInfo type_info = {
@@ -2384,10 +2336,14 @@ static int kvm_ppc_register_host_cpu_type(void)
         .instance_init = kvmppc_host_cpu_initfn,
         .class_init = kvmppc_host_cpu_class_init,
     };
+    uint32_t host_pvr = mfpvr();
     PowerPCCPUClass *pvr_pcc;
     DeviceClass *dc;
 
-    pvr_pcc = kvm_ppc_get_host_cpu_class();
+    pvr_pcc = ppc_cpu_class_by_pvr(host_pvr);
+    if (pvr_pcc == NULL) {
+        pvr_pcc = ppc_cpu_class_by_pvr_mask(host_pvr);
+    }
     if (pvr_pcc == NULL) {
         return -1;
     }
@@ -2401,21 +2357,6 @@ static int kvm_ppc_register_host_cpu_type(void)
     type_info.name = g_strdup_printf("%s-"TYPE_POWERPC_CPU, dc->desc);
     type_register(&type_info);
 
-#if defined(TARGET_PPC64)
-    type_info.name = g_strdup_printf("%s-"TYPE_SPAPR_CPU_CORE, "host");
-    type_info.parent = TYPE_SPAPR_CPU_CORE,
-    type_info.instance_size = sizeof(sPAPRCPUCore),
-    type_info.instance_init = spapr_cpu_core_host_initfn,
-    type_info.class_init = NULL;
-    type_register(&type_info);
-    g_free((void *)type_info.name);
-
-    /* Register generic spapr CPU family class for current host CPU type */
-    type_info.name = g_strdup_printf("%s-"TYPE_SPAPR_CPU_CORE, dc->desc);
-    type_register(&type_info);
-    g_free((void *)type_info.name);
-#endif
-
     return 0;
 }
 
@@ -2625,17 +2566,6 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
     return 0;
 }
 
-int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
-                                int vector, PCIDevice *dev)
-{
-    return 0;
-}
-
-int kvm_arch_release_virq_post(int virq)
-{
-    return 0;
-}
-
 int kvm_arch_msi_data_to_gsi(uint32_t data)
 {
     return data & 0xffff;
index 5461d10..fc79312 100644 (file)
@@ -6,8 +6,8 @@
  *
  */
 
-#ifndef KVM_PPC_H
-#define KVM_PPC_H
+#ifndef __KVM_PPC_H__
+#define __KVM_PPC_H__
 
 #define TYPE_HOST_POWERPC_CPU "host-" TYPE_POWERPC_CPU
 
@@ -56,7 +56,6 @@ void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index,
 bool kvmppc_has_cap_fixup_hcalls(void);
 int kvmppc_enable_hwrng(void);
 int kvmppc_put_books_sregs(PowerPCCPU *cpu);
-PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
 
 #else
 
@@ -164,7 +163,7 @@ static inline bool kvmppc_spapr_use_multitce(void)
 
 static inline void *kvmppc_create_spapr_tce(uint32_t liobn,
                                             uint32_t window_size, int *fd,
-                                            bool need_vfio)
+                                            bool vfio_accel)
 {
     return NULL;
 }
@@ -253,12 +252,6 @@ static inline int kvmppc_put_books_sregs(PowerPCCPU *cpu)
 {
     abort();
 }
-
-static inline PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
-{
-    return NULL;
-}
-
 #endif
 
 #ifndef CONFIG_KVM
@@ -316,4 +309,4 @@ static inline void kvmppc_icbi_range(PowerPCCPU *cpu, uint8_t *addr, int len)
 #define KVM_INTERRUPT_SET_LEVEL -3
 #endif
 
-#endif /* KVM_PPC_H */
+#endif /* __KVM_PPC_H__ */
index 4820f22..46684fb 100644 (file)
@@ -1,14 +1,9 @@
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
 #include "hw/hw.h"
 #include "hw/boards.h"
 #include "sysemu/kvm.h"
 #include "helper_regs.h"
 #include "mmu-hash64.h"
-#include "migration/cpu.h"
-#include "exec/exec-all.h"
 
 static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
 {
@@ -97,12 +92,9 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
     qemu_get_betls(f, &env->nip);
     qemu_get_betls(f, &env->hflags);
     qemu_get_betls(f, &env->hflags_nmsr);
-    qemu_get_sbe32(f); /* Discard unused mmu_idx */
+    qemu_get_sbe32s(f, &env->mmu_idx);
     qemu_get_sbe32(f); /* Discard unused power_mode */
 
-    /* Recompute mmu indices */
-    hreg_compute_mem_idx(env);
-
     return 0;
 }
 
index e4ed377..6d584c9 100644 (file)
  */
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
 
 #include "helper_regs.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 //#define DEBUG_OP
@@ -232,16 +230,16 @@ target_ulong helper_lscbx(CPUPPCState *env, target_ulong addr, uint32_t reg,
                                                                 \
         if (needs_byteswap(env)) {                              \
             r->element[LO_IDX ? index : (adjust - index)] =     \
-                swap(access(env, addr, GETPC()));               \
+                swap(access(env, addr));                        \
         } else {                                                \
             r->element[LO_IDX ? index : (adjust - index)] =     \
-                access(env, addr, GETPC());                     \
+                access(env, addr);                              \
         }                                                       \
     }
 #define I(x) (x)
-LVE(lvebx, cpu_ldub_data_ra, I, u8)
-LVE(lvehx, cpu_lduw_data_ra, bswap16, u16)
-LVE(lvewx, cpu_ldl_data_ra, bswap32, u32)
+LVE(lvebx, cpu_ldub_data, I, u8)
+LVE(lvehx, cpu_lduw_data, bswap16, u16)
+LVE(lvewx, cpu_ldl_data, bswap32, u32)
 #undef I
 #undef LVE
 
@@ -259,17 +257,16 @@ LVE(lvewx, cpu_ldl_data_ra, bswap32, u32)
                                                                         \
         if (needs_byteswap(env)) {                                      \
             access(env, addr, swap(r->element[LO_IDX ? index :          \
-                                              (adjust - index)]),       \
-                        GETPC());                                       \
+                                              (adjust - index)]));      \
         } else {                                                        \
             access(env, addr, r->element[LO_IDX ? index :               \
-                                         (adjust - index)], GETPC());   \
+                                         (adjust - index)]);            \
         }                                                               \
     }
 #define I(x) (x)
-STVE(stvebx, cpu_stb_data_ra, I, u8)
-STVE(stvehx, cpu_stw_data_ra, bswap16, u16)
-STVE(stvewx, cpu_stl_data_ra, bswap32, u32)
+STVE(stvebx, cpu_stb_data, I, u8)
+STVE(stvehx, cpu_stw_data, bswap16, u16)
+STVE(stvewx, cpu_stl_data, bswap32, u32)
 #undef I
 #undef LVE
 
index cb5ebf5..73e3b05 100644 (file)
@@ -18,7 +18,6 @@
  */
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 
 #include "helper_regs.h"
@@ -166,44 +165,3 @@ void ppc_store_msr(CPUPPCState *env, target_ulong value)
 {
     hreg_store_msr(env, value, 0);
 }
-
-/* This code is lifted from MacOnLinux. It is called whenever
- * THRM1,2 or 3 is read an fixes up the values in such a way
- * that will make MacOS not hang. These registers exist on some
- * 75x and 74xx processors.
- */
-void helper_fixup_thrm(CPUPPCState *env)
-{
-    target_ulong v, t;
-    int i;
-
-#define THRM1_TIN       (1 << 31)
-#define THRM1_TIV       (1 << 30)
-#define THRM1_THRES(x)  (((x) & 0x7f) << 23)
-#define THRM1_TID       (1 << 2)
-#define THRM1_TIE       (1 << 1)
-#define THRM1_V         (1 << 0)
-#define THRM3_E         (1 << 0)
-
-    if (!(env->spr[SPR_THRM3] & THRM3_E)) {
-        return;
-    }
-
-    /* Note: Thermal interrupts are unimplemented */
-    for (i = SPR_THRM1; i <= SPR_THRM2; i++) {
-        v = env->spr[i];
-        if (!(v & THRM1_V)) {
-            continue;
-        }
-        v |= THRM1_TIV;
-        v &= ~THRM1_TIN;
-        t = v & THRM1_THRES(127);
-        if ((v & THRM1_TID) && t < THRM1_THRES(24)) {
-            v |= THRM1_TIN;
-        }
-        if (!(v & THRM1_TID) && t > THRM1_THRES(24)) {
-            v |= THRM1_TIN;
-        }
-        env->spr[i] = v;
-    }
-}
index 29bace6..39abb2f 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 #include "sysemu/kvm.h"
 #include "kvm_ppc.h"
@@ -384,7 +383,7 @@ static hwaddr ppc_hash32_pte_raddr(target_ulong sr, ppc_hash_pte32_t pte,
     return (rpn & ~mask) | (eaddr & mask);
 }
 
-int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
+int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, target_ulong eaddr, int rwx,
                                 int mmu_idx)
 {
     CPUState *cs = CPU(cpu);
index 5b9fb08..afbb9dd 100644 (file)
@@ -1,11 +1,11 @@
-#ifndef MMU_HASH32_H
-#define MMU_HASH32_H
+#if !defined (__MMU_HASH32_H__)
+#define __MMU_HASH32_H__
 
 #ifndef CONFIG_USER_ONLY
 
 hwaddr get_pteg_offset32(PowerPCCPU *cpu, hwaddr hash);
 hwaddr ppc_hash32_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr);
-int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr address, int rw,
+int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, target_ulong address, int rw,
                                 int mmu_idx);
 
 /*
@@ -109,4 +109,4 @@ typedef struct {
 
 #endif /* CONFIG_USER_ONLY */
 
-#endif /* MMU_HASH32_H */
+#endif /* __MMU_HASH32_H__ */
index 5de1358..72c4ab5 100644 (file)
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 #include "qemu/error-report.h"
 #include "sysemu/kvm.h"
+#include "qemu/error-report.h"
 #include "kvm_ppc.h"
 #include "mmu-hash64.h"
 #include "exec/log.h"
@@ -98,8 +98,10 @@ void dump_slb(FILE *f, fprintf_function cpu_fprintf, PowerPCCPU *cpu)
 
 void helper_slbia(CPUPPCState *env)
 {
-    int n;
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+    int n, do_invalidate;
 
+    do_invalidate = 0;
     /* XXX: Warning: slbia never invalidates the first segment */
     for (n = 1; n < env->slb_nr; n++) {
         ppc_slb_t *slb = &env->slb[n];
@@ -110,9 +112,12 @@ void helper_slbia(CPUPPCState *env)
              *      and we still don't have a tlb_flush_mask(env, n, mask)
              *      in QEMU, we just invalidate all TLBs
              */
-            env->tlb_need_flush = 1;
+            do_invalidate = 1;
         }
     }
+    if (do_invalidate) {
+        tlb_flush(CPU(cpu), 1);
+    }
 }
 
 void helper_slbie(CPUPPCState *env, target_ulong addr)
@@ -132,7 +137,7 @@ void helper_slbie(CPUPPCState *env, target_ulong addr)
          *      and we still don't have a tlb_flush_mask(env, n, mask)
          *      in QEMU, we just invalidate all TLBs
          */
-        env->tlb_need_flush = 1;
+        tlb_flush(CPU(cpu), 1);
     }
 }
 
@@ -218,24 +223,6 @@ static int ppc_load_slb_vsid(PowerPCCPU *cpu, target_ulong rb,
     return 0;
 }
 
-static int ppc_find_slb_vsid(PowerPCCPU *cpu, target_ulong rb,
-                             target_ulong *rt)
-{
-    CPUPPCState *env = &cpu->env;
-    ppc_slb_t *slb;
-
-    if (!msr_is_64bit(env, env->msr)) {
-        rb &= 0xffffffff;
-    }
-    slb = slb_lookup(cpu, rb);
-    if (slb == NULL) {
-        *rt = (target_ulong)-1ul;
-    } else {
-        *rt = slb->vsid;
-    }
-    return 0;
-}
-
 void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs)
 {
     PowerPCCPU *cpu = ppc_env_get_cpu(env);
@@ -258,18 +245,6 @@ target_ulong helper_load_slb_esid(CPUPPCState *env, target_ulong rb)
     return rt;
 }
 
-target_ulong helper_find_slb_vsid(CPUPPCState *env, target_ulong rb)
-{
-    PowerPCCPU *cpu = ppc_env_get_cpu(env);
-    target_ulong rt = 0;
-
-    if (ppc_find_slb_vsid(cpu, rb, &rt) < 0) {
-        helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
-                                   POWERPC_EXCP_INVAL);
-    }
-    return rt;
-}
-
 target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb)
 {
     PowerPCCPU *cpu = ppc_env_get_cpu(env);
@@ -308,6 +283,8 @@ void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int shift,
     CPUPPCState *env = &cpu->env;
     Error *local_err = NULL;
 
+    cpu_synchronize_state(CPU(cpu));
+
     if (hpt) {
         env->external_htab = hpt;
     } else {
@@ -449,47 +426,9 @@ void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t token)
     }
 }
 
-static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
-    uint64_t pte0, uint64_t pte1)
-{
-    int i;
-
-    if (!(pte0 & HPTE64_V_LARGE)) {
-        if (sps->page_shift != 12) {
-            /* 4kiB page in a non 4kiB segment */
-            return 0;
-        }
-        /* Normal 4kiB page */
-        return 12;
-    }
-
-    for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
-        const struct ppc_one_page_size *ps = &sps->enc[i];
-        uint64_t mask;
-
-        if (!ps->page_shift) {
-            break;
-        }
-
-        if (ps->page_shift == 12) {
-            /* L bit is set so this can't be a 4kiB page */
-            continue;
-        }
-
-        mask = ((1ULL << ps->page_shift) - 1) & HPTE64_R_RPN;
-
-        if ((pte1 & mask) == ((uint64_t)ps->pte_enc << HPTE64_R_RPN_SHIFT)) {
-            return ps->page_shift;
-        }
-    }
-
-    return 0; /* Bad page size encoding */
-}
-
 static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
-                                     const struct ppc_one_seg_page_size *sps,
-                                     target_ulong ptem,
-                                     ppc_hash_pte64_t *pte, unsigned *pshift)
+                                     bool secondary, target_ulong ptem,
+                                     ppc_hash_pte64_t *pte)
 {
     CPUPPCState *env = &cpu->env;
     int i;
@@ -506,22 +445,9 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
         pte0 = ppc_hash64_load_hpte0(cpu, token, i);
         pte1 = ppc_hash64_load_hpte1(cpu, token, i);
 
-        /* This compares V, B, H (secondary) and the AVPN */
-        if (HPTE64_V_COMPARE(pte0, ptem)) {
-            *pshift = hpte_page_shift(sps, pte0, pte1);
-            /*
-             * If there is no match, ignore the PTE, it could simply
-             * be for a different segment size encoding and the
-             * architecture specifies we should not match. Linux will
-             * potentially leave behind PTEs for the wrong base page
-             * size when demoting segments.
-             */
-            if (*pshift == 0) {
-                continue;
-            }
-            /* We don't do anything with pshift yet as qemu TLB only deals
-             * with 4K pages anyway
-             */
+        if ((pte0 & HPTE64_V_VALID)
+            && (secondary == !!(pte0 & HPTE64_V_SECONDARY))
+            && HPTE64_V_COMPARE(pte0, ptem)) {
             pte->pte0 = pte0;
             pte->pte1 = pte1;
             ppc_hash64_stop_access(cpu, token);
@@ -537,40 +463,31 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
 
 static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu,
                                      ppc_slb_t *slb, target_ulong eaddr,
-                                     ppc_hash_pte64_t *pte, unsigned *pshift)
+                                     ppc_hash_pte64_t *pte)
 {
     CPUPPCState *env = &cpu->env;
     hwaddr pte_offset;
     hwaddr hash;
     uint64_t vsid, epnmask, epn, ptem;
-    const struct ppc_one_seg_page_size *sps = slb->sps;
 
     /* The SLB store path should prevent any bad page size encodings
      * getting in there, so: */
-    assert(sps);
+    assert(slb->sps);
 
-    /* If ISL is set in LPCR we need to clamp the page size to 4K */
-    if (env->spr[SPR_LPCR] & LPCR_ISL) {
-        /* We assume that when using TCG, 4k is first entry of SPS */
-        sps = &env->sps.sps[0];
-        assert(sps->page_shift == 12);
-    }
-
-    epnmask = ~((1ULL << sps->page_shift) - 1);
+    epnmask = ~((1ULL << slb->sps->page_shift) - 1);
 
     if (slb->vsid & SLB_VSID_B) {
         /* 1TB segment */
         vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T;
         epn = (eaddr & ~SEGMENT_MASK_1T) & epnmask;
-        hash = vsid ^ (vsid << 25) ^ (epn >> sps->page_shift);
+        hash = vsid ^ (vsid << 25) ^ (epn >> slb->sps->page_shift);
     } else {
         /* 256M segment */
         vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
         epn = (eaddr & ~SEGMENT_MASK_256M) & epnmask;
-        hash = vsid ^ (epn >> sps->page_shift);
+        hash = vsid ^ (epn >> slb->sps->page_shift);
     }
     ptem = (slb->vsid & SLB_VSID_PTEM) | ((epn >> 16) & HPTE64_V_AVPN);
-    ptem |= HPTE64_V_VALID;
 
     /* Page address translation */
     qemu_log_mask(CPU_LOG_MMU,
@@ -584,30 +501,68 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu,
             " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
             " hash=" TARGET_FMT_plx "\n",
             env->htab_base, env->htab_mask, vsid, ptem,  hash);
-    pte_offset = ppc_hash64_pteg_search(cpu, hash, sps, ptem, pte, pshift);
+    pte_offset = ppc_hash64_pteg_search(cpu, hash, 0, ptem, pte);
 
     if (pte_offset == -1) {
         /* Secondary PTEG lookup */
-        ptem |= HPTE64_V_SECONDARY;
         qemu_log_mask(CPU_LOG_MMU,
                 "1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
                 " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
                 " hash=" TARGET_FMT_plx "\n", env->htab_base,
                 env->htab_mask, vsid, ptem, ~hash);
 
-        pte_offset = ppc_hash64_pteg_search(cpu, ~hash, sps, ptem, pte, pshift);
+        pte_offset = ppc_hash64_pteg_search(cpu, ~hash, 1, ptem, pte);
     }
 
     return pte_offset;
 }
 
+static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
+    uint64_t pte0, uint64_t pte1)
+{
+    int i;
+
+    if (!(pte0 & HPTE64_V_LARGE)) {
+        if (sps->page_shift != 12) {
+            /* 4kiB page in a non 4kiB segment */
+            return 0;
+        }
+        /* Normal 4kiB page */
+        return 12;
+    }
+
+    for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
+        const struct ppc_one_page_size *ps = &sps->enc[i];
+        uint64_t mask;
+
+        if (!ps->page_shift) {
+            break;
+        }
+
+        if (ps->page_shift == 12) {
+            /* L bit is set so this can't be a 4kiB page */
+            continue;
+        }
+
+        mask = ((1ULL << ps->page_shift) - 1) & HPTE64_R_RPN;
+
+        if ((pte1 & mask) == (ps->pte_enc << HPTE64_R_RPN_SHIFT)) {
+            return ps->page_shift;
+        }
+    }
+
+    return 0; /* Bad page size encoding */
+}
+
 unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
-                                          uint64_t pte0, uint64_t pte1)
+                                          uint64_t pte0, uint64_t pte1,
+                                          unsigned *seg_page_shift)
 {
     CPUPPCState *env = &cpu->env;
     int i;
 
     if (!(pte0 & HPTE64_V_LARGE)) {
+        *seg_page_shift = 12;
         return 12;
     }
 
@@ -625,55 +580,16 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
 
         shift = hpte_page_shift(sps, pte0, pte1);
         if (shift) {
+            *seg_page_shift = sps->page_shift;
             return shift;
         }
     }
 
+    *seg_page_shift = 0;
     return 0;
 }
 
-static void ppc_hash64_set_isi(CPUState *cs, CPUPPCState *env,
-                               uint64_t error_code)
-{
-    bool vpm;
-
-    if (msr_ir) {
-        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
-    } else {
-        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
-    }
-    if (vpm && !msr_hv) {
-        cs->exception_index = POWERPC_EXCP_HISI;
-    } else {
-        cs->exception_index = POWERPC_EXCP_ISI;
-    }
-    env->error_code = error_code;
-}
-
-static void ppc_hash64_set_dsi(CPUState *cs, CPUPPCState *env, uint64_t dar,
-                               uint64_t dsisr)
-{
-    bool vpm;
-
-    if (msr_dr) {
-        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
-    } else {
-        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
-    }
-    if (vpm && !msr_hv) {
-        cs->exception_index = POWERPC_EXCP_HDSI;
-        env->spr[SPR_HDAR] = dar;
-        env->spr[SPR_HDSISR] = dsisr;
-    } else {
-        cs->exception_index = POWERPC_EXCP_DSI;
-        env->spr[SPR_DAR] = dar;
-        env->spr[SPR_DSISR] = dsisr;
-   }
-    env->error_code = 0;
-}
-
-
-int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
+int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, target_ulong eaddr,
                                 int rwx, int mmu_idx)
 {
     CPUState *cs = CPU(cpu);
@@ -683,58 +599,17 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
     hwaddr pte_offset;
     ppc_hash_pte64_t pte;
     int pp_prot, amr_prot, prot;
-    uint64_t new_pte1, dsisr;
+    uint64_t new_pte1;
     const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
     hwaddr raddr;
 
     assert((rwx == 0) || (rwx == 1) || (rwx == 2));
 
-    /* Note on LPCR usage: 970 uses HID4, but our special variant
-     * of store_spr copies relevant fields into env->spr[SPR_LPCR].
-     * Similarily we filter unimplemented bits when storing into
-     * LPCR depending on the MMU version. This code can thus just
-     * use the LPCR "as-is".
-     */
-
     /* 1. Handle real mode accesses */
     if (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0))) {
-        /* Translation is supposedly "off"  */
-        /* In real mode the top 4 effective address bits are (mostly) ignored */
+        /* Translation is off */
+        /* In real mode the top 4 effective address bits are ignored */
         raddr = eaddr & 0x0FFFFFFFFFFFFFFFULL;
-
-        /* In HV mode, add HRMOR if top EA bit is clear */
-        if (msr_hv || !env->has_hv_mode) {
-            if (!(eaddr >> 63)) {
-                raddr |= env->spr[SPR_HRMOR];
-            }
-        } else {
-            /* Otherwise, check VPM for RMA vs VRMA */
-            if (env->spr[SPR_LPCR] & LPCR_VPM0) {
-                slb = &env->vrma_slb;
-                if (slb->sps) {
-                    goto skip_slb_search;
-                }
-                /* Not much else to do here */
-                cs->exception_index = POWERPC_EXCP_MCHECK;
-                env->error_code = 0;
-                return 1;
-            } else if (raddr < env->rmls) {
-                /* RMA. Check bounds in RMLS */
-                raddr |= env->spr[SPR_RMOR];
-            } else {
-                /* The access failed, generate the approriate interrupt */
-                if (rwx == 2) {
-                    ppc_hash64_set_isi(cs, env, 0x08000000);
-                } else {
-                    dsisr = 0x08000000;
-                    if (rwx == 1) {
-                        dsisr |= 0x02000000;
-                    }
-                    ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
-                }
-                return 1;
-            }
-        }
         tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
                      PAGE_READ | PAGE_WRITE | PAGE_EXEC, mmu_idx,
                      TARGET_PAGE_SIZE);
@@ -743,6 +618,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
 
     /* 2. Translation is on, so look up the SLB */
     slb = slb_lookup(cpu, eaddr);
+
     if (!slb) {
         if (rwx == 2) {
             cs->exception_index = POWERPC_EXCP_ISEG;
@@ -755,31 +631,46 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
         return 1;
     }
 
-skip_slb_search:
-
     /* 3. Check for segment level no-execute violation */
     if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
-        ppc_hash64_set_isi(cs, env, 0x10000000);
+        cs->exception_index = POWERPC_EXCP_ISI;
+        env->error_code = 0x10000000;
         return 1;
     }
 
     /* 4. Locate the PTE in the hash table */
-    pte_offset = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte, &apshift);
+    pte_offset = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte);
     if (pte_offset == -1) {
-        dsisr = 0x40000000;
         if (rwx == 2) {
-            ppc_hash64_set_isi(cs, env, dsisr);
+            cs->exception_index = POWERPC_EXCP_ISI;
+            env->error_code = 0x40000000;
         } else {
+            cs->exception_index = POWERPC_EXCP_DSI;
+            env->error_code = 0;
+            env->spr[SPR_DAR] = eaddr;
             if (rwx == 1) {
-                dsisr |= 0x02000000;
+                env->spr[SPR_DSISR] = 0x42000000;
+            } else {
+                env->spr[SPR_DSISR] = 0x40000000;
             }
-            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
         }
         return 1;
     }
     qemu_log_mask(CPU_LOG_MMU,
                 "found PTE at offset %08" HWADDR_PRIx "\n", pte_offset);
 
+    /* Validate page size encoding */
+    apshift = hpte_page_shift(slb->sps, pte.pte0, pte.pte1);
+    if (!apshift) {
+        error_report("Bad page size encoding in HPTE 0x%"PRIx64" - 0x%"PRIx64
+                     " @ 0x%"HWADDR_PRIx, pte.pte0, pte.pte1, pte_offset);
+        /* Not entirely sure what the right action here, but machine
+         * check seems reasonable */
+        cs->exception_index = POWERPC_EXCP_MCHECK;
+        env->error_code = 0;
+        return 1;
+    }
+
     /* 5. Check access permissions */
 
     pp_prot = ppc_hash64_pte_prot(cpu, slb, pte);
@@ -790,9 +681,14 @@ skip_slb_search:
         /* Access right violation */
         qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
         if (rwx == 2) {
-            ppc_hash64_set_isi(cs, env, 0x08000000);
+            cs->exception_index = POWERPC_EXCP_ISI;
+            env->error_code = 0x08000000;
         } else {
-            dsisr = 0;
+            target_ulong dsisr = 0;
+
+            cs->exception_index = POWERPC_EXCP_DSI;
+            env->error_code = 0;
+            env->spr[SPR_DAR] = eaddr;
             if (need_prot[rwx] & ~pp_prot) {
                 dsisr |= 0x08000000;
             }
@@ -802,7 +698,7 @@ skip_slb_search:
             if (need_prot[rwx] & ~amr_prot) {
                 dsisr |= 0x00200000;
             }
-            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
+            env->spr[SPR_DSISR] = dsisr;
         }
         return 1;
     }
@@ -839,44 +735,30 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr)
 {
     CPUPPCState *env = &cpu->env;
     ppc_slb_t *slb;
-    hwaddr pte_offset, raddr;
+    hwaddr pte_offset;
     ppc_hash_pte64_t pte;
     unsigned apshift;
 
-    /* Handle real mode */
     if (msr_dr == 0) {
         /* In real mode the top 4 effective address bits are ignored */
-        raddr = addr & 0x0FFFFFFFFFFFFFFFULL;
-
-        /* In HV mode, add HRMOR if top EA bit is clear */
-        if ((msr_hv || !env->has_hv_mode) && !(addr >> 63)) {
-            return raddr | env->spr[SPR_HRMOR];
-        }
+        return addr & 0x0FFFFFFFFFFFFFFFULL;
+    }
 
-        /* Otherwise, check VPM for RMA vs VRMA */
-        if (env->spr[SPR_LPCR] & LPCR_VPM0) {
-            slb = &env->vrma_slb;
-            if (!slb->sps) {
-                return -1;
-            }
-        } else if (raddr < env->rmls) {
-            /* RMA. Check bounds in RMLS */
-            return raddr | env->spr[SPR_RMOR];
-        } else {
-            return -1;
-        }
-    } else {
-        slb = slb_lookup(cpu, addr);
-        if (!slb) {
-            return -1;
-        }
+    slb = slb_lookup(cpu, addr);
+    if (!slb) {
+        return -1;
     }
 
-    pte_offset = ppc_hash64_htab_lookup(cpu, slb, addr, &pte, &apshift);
+    pte_offset = ppc_hash64_htab_lookup(cpu, slb, addr, &pte);
     if (pte_offset == -1) {
         return -1;
     }
 
+    apshift = hpte_page_shift(slb->sps, pte.pte0, pte.pte1);
+    if (!apshift) {
+        return -1;
+    }
+
     return deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, addr)
         & TARGET_PAGE_MASK;
 }
@@ -914,146 +796,3 @@ void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu,
      */
     tlb_flush(CPU(cpu), 1);
 }
-
-void ppc_hash64_update_rmls(CPUPPCState *env)
-{
-    uint64_t lpcr = env->spr[SPR_LPCR];
-
-    /*
-     * This is the full 4 bits encoding of POWER8. Previous
-     * CPUs only support a subset of these but the filtering
-     * is done when writing LPCR
-     */
-    switch ((lpcr & LPCR_RMLS) >> LPCR_RMLS_SHIFT) {
-    case 0x8: /* 32MB */
-        env->rmls = 0x2000000ull;
-        break;
-    case 0x3: /* 64MB */
-        env->rmls = 0x4000000ull;
-        break;
-    case 0x7: /* 128MB */
-        env->rmls = 0x8000000ull;
-        break;
-    case 0x4: /* 256MB */
-        env->rmls = 0x10000000ull;
-        break;
-    case 0x2: /* 1GB */
-        env->rmls = 0x40000000ull;
-        break;
-    case 0x1: /* 16GB */
-        env->rmls = 0x400000000ull;
-        break;
-    default:
-        /* What to do here ??? */
-        env->rmls = 0;
-    }
-}
-
-void ppc_hash64_update_vrma(CPUPPCState *env)
-{
-    const struct ppc_one_seg_page_size *sps = NULL;
-    target_ulong esid, vsid, lpcr;
-    ppc_slb_t *slb = &env->vrma_slb;
-    uint32_t vrmasd;
-    int i;
-
-    /* First clear it */
-    slb->esid = slb->vsid = 0;
-    slb->sps = NULL;
-
-    /* Is VRMA enabled ? */
-    lpcr = env->spr[SPR_LPCR];
-    if (!(lpcr & LPCR_VPM0)) {
-        return;
-    }
-
-    /* Make one up. Mostly ignore the ESID which will not be
-     * needed for translation
-     */
-    vsid = SLB_VSID_VRMA;
-    vrmasd = (lpcr & LPCR_VRMASD) >> LPCR_VRMASD_SHIFT;
-    vsid |= (vrmasd << 4) & (SLB_VSID_L | SLB_VSID_LP);
-    esid = SLB_ESID_V;
-
-   for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
-        const struct ppc_one_seg_page_size *sps1 = &env->sps.sps[i];
-
-        if (!sps1->page_shift) {
-            break;
-        }
-
-        if ((vsid & SLB_VSID_LLP_MASK) == sps1->slb_enc) {
-            sps = sps1;
-            break;
-        }
-    }
-
-    if (!sps) {
-        error_report("Bad page size encoding esid 0x"TARGET_FMT_lx
-                     " vsid 0x"TARGET_FMT_lx, esid, vsid);
-        return;
-    }
-
-    slb->vsid = vsid;
-    slb->esid = esid;
-    slb->sps = sps;
-}
-
-void helper_store_lpcr(CPUPPCState *env, target_ulong val)
-{
-    uint64_t lpcr = 0;
-
-    /* Filter out bits */
-    switch (env->mmu_model) {
-    case POWERPC_MMU_64B: /* 970 */
-        if (val & 0x40) {
-            lpcr |= LPCR_LPES0;
-        }
-        if (val & 0x8000000000000000ull) {
-            lpcr |= LPCR_LPES1;
-        }
-        if (val & 0x20) {
-            lpcr |= (0x4ull << LPCR_RMLS_SHIFT);
-        }
-        if (val & 0x4000000000000000ull) {
-            lpcr |= (0x2ull << LPCR_RMLS_SHIFT);
-        }
-        if (val & 0x2000000000000000ull) {
-            lpcr |= (0x1ull << LPCR_RMLS_SHIFT);
-        }
-        env->spr[SPR_RMOR] = ((lpcr >> 41) & 0xffffull) << 26;
-
-        /* XXX We could also write LPID from HID4 here
-         * but since we don't tag any translation on it
-         * it doesn't actually matter
-         */
-        /* XXX For proper emulation of 970 we also need
-         * to dig HRMOR out of HID5
-         */
-        break;
-    case POWERPC_MMU_2_03: /* P5p */
-        lpcr = val & (LPCR_RMLS | LPCR_ILE |
-                      LPCR_LPES0 | LPCR_LPES1 |
-                      LPCR_RMI | LPCR_HDICE);
-        break;
-    case POWERPC_MMU_2_06: /* P7 */
-        lpcr = val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD |
-                      LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
-                      LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 |
-                      LPCR_MER | LPCR_TC |
-                      LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE);
-        break;
-    case POWERPC_MMU_2_07: /* P8 */
-        lpcr = val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV |
-                      LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
-                      LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 |
-                      LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 |
-                      LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE);
-        break;
-    default:
-        ;
-    }
-    env->spr[SPR_LPCR] = lpcr;
-    ppc_hash64_update_rmls(env);
-    ppc_hash64_update_vrma(env);
-}
index db265e3..9bf8b9b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef MMU_HASH64_H
-#define MMU_HASH64_H
+#if !defined (__MMU_HASH64_H__)
+#define __MMU_HASH64_H__
 
 #ifndef CONFIG_USER_ONLY
 
@@ -9,7 +9,7 @@ void dump_slb(FILE *f, fprintf_function cpu_fprintf, PowerPCCPU *cpu);
 int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot,
                   target_ulong esid, target_ulong vsid);
 hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr);
-int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr address, int rw,
+int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, target_ulong address, int rw,
                                 int mmu_idx);
 void ppc_hash64_store_hpte(PowerPCCPU *cpu, target_ulong index,
                            target_ulong pte0, target_ulong pte1);
@@ -17,9 +17,8 @@ void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu,
                                target_ulong pte_index,
                                target_ulong pte0, target_ulong pte1);
 unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
-                                          uint64_t pte0, uint64_t pte1);
-void ppc_hash64_update_vrma(CPUPPCState *env);
-void ppc_hash64_update_rmls(CPUPPCState *env);
+                                          uint64_t pte0, uint64_t pte1,
+                                          unsigned *seg_page_shift);
 #endif
 
 /*
@@ -38,7 +37,6 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
 #define SLB_VSID_B_256M         0x0000000000000000ULL
 #define SLB_VSID_B_1T           0x4000000000000000ULL
 #define SLB_VSID_VSID           0x3FFFFFFFFFFFF000ULL
-#define SLB_VSID_VRMA           (0x0001FFFFFF000000ULL | SLB_VSID_B_1T)
 #define SLB_VSID_PTEM           (SLB_VSID_B | SLB_VSID_VSID)
 #define SLB_VSID_KS             0x0000000000000800ULL
 #define SLB_VSID_KP             0x0000000000000400ULL
@@ -65,7 +63,7 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
 #define HPTE64_V_AVPN_SHIFT     7
 #define HPTE64_V_AVPN           0x3fffffffffffff80ULL
 #define HPTE64_V_AVPN_VAL(x)    (((x) & HPTE64_V_AVPN) >> HPTE64_V_AVPN_SHIFT)
-#define HPTE64_V_COMPARE(x, y)  (!(((x) ^ (y)) & 0xffffffffffffff83ULL))
+#define HPTE64_V_COMPARE(x, y)  (!(((x) ^ (y)) & 0xffffffffffffff80ULL))
 #define HPTE64_V_LARGE          0x0000000000000004ULL
 #define HPTE64_V_SECONDARY      0x0000000000000002ULL
 #define HPTE64_V_VALID          0x0000000000000001ULL
@@ -134,4 +132,4 @@ typedef struct {
 
 #endif /* CONFIG_USER_ONLY */
 
-#endif /* MMU_HASH64_H */
+#endif /* !defined (__MMU_HASH64_H__) */
index 3eb3cd7..ff21794 100644 (file)
 #include "kvm_ppc.h"
 #include "mmu-hash64.h"
 #include "mmu-hash32.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "exec/log.h"
-#include "helper_regs.h"
 
 //#define DEBUG_MMU
 //#define DEBUG_BATS
@@ -512,20 +510,18 @@ static inline int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
             /* Software TLB search */
             ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
 #if defined(DUMP_PAGE_TABLES)
-            if (qemu_loglevel_mask(CPU_LOG_MMU)) {
-                CPUState *cs = ENV_GET_CPU(env);
+            if (qemu_log_mask(CPU_LOG_MMU)) {
                 hwaddr curaddr;
                 uint32_t a0, a1, a2, a3;
 
                 qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx
-                         "\n", env->htab_base, env->htab_mask + 0x80);
-                for (curaddr = env->htab_base;
-                     curaddr < (env->htab_base + env->htab_mask + 0x80);
+                         "\n", sdr, mask + 0x80);
+                for (curaddr = sdr; curaddr < (sdr + mask + 0x80);
                      curaddr += 16) {
-                    a0 = ldl_phys(cs->as, curaddr);
-                    a1 = ldl_phys(cs->as, curaddr + 4);
-                    a2 = ldl_phys(cs->as, curaddr + 8);
-                    a3 = ldl_phys(cs->as, curaddr + 12);
+                    a0 = ldl_phys(curaddr);
+                    a1 = ldl_phys(curaddr + 4);
+                    a2 = ldl_phys(curaddr + 8);
+                    a3 = ldl_phys(curaddr + 12);
                     if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
                         qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n",
                                  curaddr, a0, a1, a2, a3);
@@ -896,9 +892,9 @@ static int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb,
 
     mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
     LOG_SWTLB("%s: TLB ADDR=0x" TARGET_FMT_lx " PID=0x%x MAS1=0x%x MAS2=0x%"
-              PRIx64 " mask=0x%" HWADDR_PRIx " MAS7_3=0x%" PRIx64 " MAS8=0x%"
-              PRIx32 "\n", __func__, address, pid, tlb->mas1, tlb->mas2, mask,
-              tlb->mas7_3, tlb->mas8);
+              PRIx64 " mask=0x" TARGET_FMT_lx " MAS7_3=0x%" PRIx64 " MAS8=%x\n",
+              __func__, address, pid, tlb->mas1, tlb->mas2, mask, tlb->mas7_3,
+              tlb->mas8);
 
     /* Check PID */
     tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT;
@@ -1748,9 +1744,6 @@ static inline void dump_store_bat(CPUPPCState *env, char ID, int ul, int nr,
 void helper_store_ibatu(CPUPPCState *env, uint32_t nr, target_ulong value)
 {
     target_ulong mask;
-#if defined(FLUSH_ALL_TLBS)
-    PowerPCCPU *cpu = ppc_env_get_cpu(env);
-#endif
 
     dump_store_bat(env, 'I', 0, nr, value);
     if (env->IBAT[0][nr] != value) {
@@ -1769,7 +1762,7 @@ void helper_store_ibatu(CPUPPCState *env, uint32_t nr, target_ulong value)
 #if !defined(FLUSH_ALL_TLBS)
         do_invalidate_BAT(env, env->IBAT[0][nr], mask);
 #else
-        tlb_flush(CPU(cpu), 1);
+        tlb_flush(env, 1);
 #endif
     }
 }
@@ -1783,9 +1776,6 @@ void helper_store_ibatl(CPUPPCState *env, uint32_t nr, target_ulong value)
 void helper_store_dbatu(CPUPPCState *env, uint32_t nr, target_ulong value)
 {
     target_ulong mask;
-#if defined(FLUSH_ALL_TLBS)
-    PowerPCCPU *cpu = ppc_env_get_cpu(env);
-#endif
 
     dump_store_bat(env, 'D', 0, nr, value);
     if (env->DBAT[0][nr] != value) {
@@ -1804,7 +1794,7 @@ void helper_store_dbatu(CPUPPCState *env, uint32_t nr, target_ulong value)
 #if !defined(FLUSH_ALL_TLBS)
         do_invalidate_BAT(env, env->DBAT[0][nr], mask);
 #else
-        tlb_flush(CPU(cpu), 1);
+        tlb_flush(env, 1);
 #endif
     }
 }
@@ -1819,7 +1809,6 @@ void helper_store_601_batu(CPUPPCState *env, uint32_t nr, target_ulong value)
 {
     target_ulong mask;
 #if defined(FLUSH_ALL_TLBS)
-    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     int do_inval;
 #endif
 
@@ -1852,7 +1841,7 @@ void helper_store_601_batu(CPUPPCState *env, uint32_t nr, target_ulong value)
         }
 #if defined(FLUSH_ALL_TLBS)
         if (do_inval) {
-            tlb_flush(CPU(cpu), 1);
+            tlb_flush(env, 1);
         }
 #endif
     }
@@ -1863,7 +1852,6 @@ void helper_store_601_batl(CPUPPCState *env, uint32_t nr, target_ulong value)
 #if !defined(FLUSH_ALL_TLBS)
     target_ulong mask;
 #else
-    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     int do_inval;
 #endif
 
@@ -1892,7 +1880,7 @@ void helper_store_601_batl(CPUPPCState *env, uint32_t nr, target_ulong value)
         env->DBAT[1][nr] = value;
 #if defined(FLUSH_ALL_TLBS)
         if (do_inval) {
-            tlb_flush(CPU(cpu), 1);
+            tlb_flush(env, 1);
         }
 #endif
     }
@@ -1936,7 +1924,6 @@ void ppc_tlb_invalidate_all(CPUPPCState *env)
     case POWERPC_MMU_2_07:
     case POWERPC_MMU_2_07a:
 #endif /* defined(TARGET_PPC64) */
-        env->tlb_need_flush = 0;
         tlb_flush(CPU(cpu), 1);
         break;
     default:
@@ -1949,6 +1936,9 @@ void ppc_tlb_invalidate_all(CPUPPCState *env)
 void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
 {
 #if !defined(FLUSH_ALL_TLBS)
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+    CPUState *cs;
+
     addr &= TARGET_PAGE_MASK;
     switch (env->mmu_model) {
     case POWERPC_MMU_SOFT_6xx:
@@ -1960,12 +1950,28 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
         break;
     case POWERPC_MMU_32B:
     case POWERPC_MMU_601:
-        /* Actual CPUs invalidate entire congruence classes based on the
-         * geometry of their TLBs and some OSes take that into account,
-         * we just mark the TLB to be flushed later (context synchronizing
-         * event or sync instruction on 32-bit).
+        /* tlbie invalidate TLBs for all segments */
+        addr &= ~((target_ulong)-1ULL << 28);
+        cs = CPU(cpu);
+        /* XXX: this case should be optimized,
+         * giving a mask to tlb_flush_page
          */
-        env->tlb_need_flush = 1;
+        tlb_flush_page(cs, addr | (0x0 << 28));
+        tlb_flush_page(cs, addr | (0x1 << 28));
+        tlb_flush_page(cs, addr | (0x2 << 28));
+        tlb_flush_page(cs, addr | (0x3 << 28));
+        tlb_flush_page(cs, addr | (0x4 << 28));
+        tlb_flush_page(cs, addr | (0x5 << 28));
+        tlb_flush_page(cs, addr | (0x6 << 28));
+        tlb_flush_page(cs, addr | (0x7 << 28));
+        tlb_flush_page(cs, addr | (0x8 << 28));
+        tlb_flush_page(cs, addr | (0x9 << 28));
+        tlb_flush_page(cs, addr | (0xA << 28));
+        tlb_flush_page(cs, addr | (0xB << 28));
+        tlb_flush_page(cs, addr | (0xC << 28));
+        tlb_flush_page(cs, addr | (0xD << 28));
+        tlb_flush_page(cs, addr | (0xE << 28));
+        tlb_flush_page(cs, addr | (0xF << 28));
         break;
 #if defined(TARGET_PPC64)
     case POWERPC_MMU_64B:
@@ -1979,7 +1985,7 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
          *      and we still don't have a tlb_flush_mask(env, n, mask) in QEMU,
          *      we just invalidate all TLBs
          */
-        env->tlb_need_flush = 1;
+        tlb_flush(CPU(cpu), 1);
         break;
 #endif /* defined(TARGET_PPC64) */
     default:
@@ -2031,12 +2037,13 @@ target_ulong helper_load_sr(CPUPPCState *env, target_ulong sr_num)
 
 void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+
     qemu_log_mask(CPU_LOG_MMU,
             "%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__,
             (int)srnum, value, env->sr[srnum]);
 #if defined(TARGET_PPC64)
     if (env->mmu_model & POWERPC_MMU_64) {
-        PowerPCCPU *cpu = ppc_env_get_cpu(env);
         uint64_t esid, vsid;
 
         /* ESID = srnum */
@@ -2065,7 +2072,7 @@ void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value)
             }
         }
 #else
-        env->tlb_need_flush = 1;
+        tlb_flush(CPU(cpu), 1);
 #endif
     }
 }
@@ -2867,19 +2874,14 @@ void helper_booke206_tlbflush(CPUPPCState *env, target_ulong type)
 }
 
 
-void helper_check_tlb_flush(CPUPPCState *env)
-{
-    check_tlb_flush(env);
-}
-
 /*****************************************************************************/
 
 /* try to fill the TLB and return an exception if error. If retaddr is
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
@@ -2887,9 +2889,9 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
     int ret;
 
     if (pcc->handle_mmu_fault) {
-        ret = pcc->handle_mmu_fault(cpu, addr, access_type, mmu_idx);
+        ret = pcc->handle_mmu_fault(cpu, addr, is_write, mmu_idx);
     } else {
-        ret = cpu_ppc_handle_mmu_fault(env, addr, access_type, mmu_idx);
+        ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx);
     }
     if (unlikely(ret != 0)) {
         if (likely(retaddr)) {
index a07faa4..3b340d7 100644 (file)
@@ -19,7 +19,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/helper-proto.h"
-#include "qemu/log.h"
 
 /*****************************************************************************/
 /* SPR accesses */
@@ -102,16 +101,6 @@ void helper_store_decr(CPUPPCState *env, target_ulong val)
     cpu_ppc_store_decr(env, val);
 }
 
-target_ulong helper_load_hdecr(CPUPPCState *env)
-{
-    return cpu_ppc_load_hdecr(env);
-}
-
-void helper_store_hdecr(CPUPPCState *env, target_ulong val)
-{
-    cpu_ppc_store_hdecr(env, val);
-}
-
 target_ulong helper_load_40x_pit(CPUPPCState *env)
 {
     return load_40x_pit(env);
diff --git a/target-ppc/trace-events b/target-ppc/trace-events
deleted file mode 100644 (file)
index 8fcc3ce..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# target-ppc/kvm.c
-kvm_failed_spr_set(int str, const char *msg) "Warning: Unable to set SPR %d to KVM: %s"
-kvm_failed_spr_get(int str, const char *msg) "Warning: Unable to retrieve SPR %d from KVM: %s"
index 92030b6..b3860ec 100644 (file)
@@ -21,7 +21,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "qemu/host-utils.h"
 #include "exec/cpu_ldst.h"
@@ -88,7 +87,6 @@ void ppc_translate_init(void)
         return;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
 
     p = cpu_reg_names;
     cpu_reg_names_size = sizeof(cpu_reg_names);
@@ -193,21 +191,21 @@ struct DisasContext {
     uint32_t opcode;
     uint32_t exception;
     /* Routine used to access memory */
-    bool pr, hv, dr, le_mode;
-    bool lazy_tlb_flush;
+    bool pr, hv;
     int mem_idx;
     int access_type;
     /* Translation flags */
+    int le_mode;
     TCGMemOp default_tcg_memop_mask;
 #if defined(TARGET_PPC64)
-    bool sf_mode;
-    bool has_cfar;
-#endif
-    bool fpu_enabled;
-    bool altivec_enabled;
-    bool vsx_enabled;
-    bool spe_enabled;
-    bool tm_enabled;
+    int sf_mode;
+    int has_cfar;
+#endif
+    int fpu_enabled;
+    int altivec_enabled;
+    int vsx_enabled;
+    int spe_enabled;
+    int tm_enabled;
     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
     int singlestep_enabled;
     uint64_t insns_flags;
@@ -284,7 +282,7 @@ void gen_update_current_nip(void *opaque)
     tcg_gen_movi_tl(cpu_nip, ctx->nip);
 }
 
-static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
+static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
 {
     TCGv_i32 t0, t1;
     if (ctx->exception == POWERPC_EXCP_NONE) {
@@ -298,7 +296,7 @@ static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
     ctx->exception = (excp);
 }
 
-static void gen_exception(DisasContext *ctx, uint32_t excp)
+static inline void gen_exception(DisasContext *ctx, uint32_t excp)
 {
     TCGv_i32 t0;
     if (ctx->exception == POWERPC_EXCP_NONE) {
@@ -310,7 +308,7 @@ static void gen_exception(DisasContext *ctx, uint32_t excp)
     ctx->exception = (excp);
 }
 
-static void gen_debug_exception(DisasContext *ctx)
+static inline void gen_debug_exception(DisasContext *ctx)
 {
     TCGv_i32 t0;
 
@@ -325,19 +323,7 @@ static void gen_debug_exception(DisasContext *ctx)
 
 static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
 {
-    /* Will be converted to program check if needed */
-    gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_INVAL | error);
-}
-
-static inline void gen_priv_exception(DisasContext *ctx, uint32_t error)
-{
-    gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_PRIV | error);
-}
-
-static inline void gen_hvpriv_exception(DisasContext *ctx, uint32_t error)
-{
-    /* Will be converted to program check if needed */
-    gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_PRIV | error);
+    gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
 }
 
 /* Stop translation */
@@ -378,40 +364,6 @@ typedef struct opcode_t {
     const char *oname;
 } opcode_t;
 
-/* Helpers for priv. check */
-#define GEN_PRIV                                                \
-    do {                                                        \
-        gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; \
-    } while (0)
-
-#if defined(CONFIG_USER_ONLY)
-#define CHK_HV GEN_PRIV
-#define CHK_SV GEN_PRIV
-#define CHK_HVRM GEN_PRIV
-#else
-#define CHK_HV                                                          \
-    do {                                                                \
-        if (unlikely(ctx->pr || !ctx->hv)) {                            \
-            GEN_PRIV;                                                   \
-        }                                                               \
-    } while (0)
-#define CHK_SV                   \
-    do {                         \
-        if (unlikely(ctx->pr)) { \
-            GEN_PRIV;            \
-        }                        \
-    } while (0)
-#define CHK_HVRM                                            \
-    do {                                                    \
-        if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) {     \
-            GEN_PRIV;                                       \
-        }                                                   \
-    } while (0)
-#endif
-
-#define CHK_NONE
-
-
 /*****************************************************************************/
 /***                           Instruction decoding                        ***/
 #define EXTRACT_HELPER(name, shift, nb)                                       \
@@ -803,20 +755,27 @@ static void gen_cmpli(DisasContext *ctx)
 /* isel (PowerPC 2.03 specification) */
 static void gen_isel(DisasContext *ctx)
 {
+    TCGLabel *l1, *l2;
     uint32_t bi = rC(ctx->opcode);
-    uint32_t mask = 0x08 >> (bi & 0x03);
-    TCGv t0 = tcg_temp_new();
-    TCGv zr;
+    uint32_t mask;
+    TCGv_i32 t0;
 
-    tcg_gen_extu_i32_tl(t0, cpu_crf[bi >> 2]);
-    tcg_gen_andi_tl(t0, t0, mask);
+    l1 = gen_new_label();
+    l2 = gen_new_label();
 
-    zr = tcg_const_tl(0);
-    tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rD(ctx->opcode)], t0, zr,
-                       rA(ctx->opcode) ? cpu_gpr[rA(ctx->opcode)] : zr,
-                       cpu_gpr[rB(ctx->opcode)]);
-    tcg_temp_free(zr);
-    tcg_temp_free(t0);
+    mask = 0x08 >> (bi & 0x03);
+    t0 = tcg_temp_new_i32();
+    tcg_gen_andi_i32(t0, cpu_crf[bi >> 2], mask);
+    tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
+    if (rA(ctx->opcode) == 0)
+        tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
+    else
+        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
+    tcg_gen_br(l2);
+    gen_set_label(l1);
+    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+    gen_set_label(l2);
+    tcg_temp_free_i32(t0);
 }
 
 /* cmpb: PowerPC 2.05 specification */
@@ -1439,19 +1398,6 @@ GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
 /* nor & nor. */
 GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
 
-#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
-static void gen_pause(DisasContext *ctx)
-{
-    TCGv_i32 t0 = tcg_const_i32(0);
-    tcg_gen_st_i32(t0, cpu_env,
-                   -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
-    tcg_temp_free_i32(t0);
-
-    /* Stop translation, this gives other CPUs a chance to run */
-    gen_exception_err(ctx, EXCP_HLT, 1);
-}
-#endif /* defined(TARGET_PPC64) */
-
 /* or & or. */
 static void gen_or(DisasContext *ctx)
 {
@@ -1471,7 +1417,7 @@ static void gen_or(DisasContext *ctx)
     } else if (unlikely(Rc(ctx->opcode) != 0)) {
         gen_set_Rc0(ctx, cpu_gpr[rs]);
 #if defined(TARGET_PPC64)
-    } else if (rs != 0) { /* 0 is nop */
+    } else {
         int prio = 0;
 
         switch (rs) {
@@ -1507,13 +1453,14 @@ static void gen_or(DisasContext *ctx)
             }
             break;
         case 7:
-            if (ctx->hv && !ctx->pr) {
+            if (ctx->hv) {
                 /* Set process priority to very high */
                 prio = 7;
             }
             break;
 #endif
         default:
+            /* nop */
             break;
         }
         if (prio) {
@@ -1524,14 +1471,6 @@ static void gen_or(DisasContext *ctx)
             gen_store_spr(SPR_PPR, t0);
             tcg_temp_free(t0);
         }
-#if !defined(CONFIG_USER_ONLY)
-        /* Pause out of TCG otherwise spin loops with smt_low eat too much
-         * CPU and the kernel hangs.  This applies to all encodings other
-         * than no-op, e.g., miso(rs=26), yield(27), mdoio(29), mdoom(30),
-         * and all currently undefined.
-         */
-        gen_pause(ctx);
-#endif
 #endif
     }
 }
@@ -1556,6 +1495,8 @@ static void gen_ori(DisasContext *ctx)
     target_ulong uimm = UIMM(ctx->opcode);
 
     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
+        /* NOP */
+        /* XXX: should handle special NOPs for POWER series */
         return;
     }
     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
@@ -1675,138 +1616,141 @@ static void gen_cntlzd(DisasContext *ctx)
 /* rlwimi & rlwimi. */
 static void gen_rlwimi(DisasContext *ctx)
 {
-    TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
-    TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
-    uint32_t sh = SH(ctx->opcode);
-    uint32_t mb = MB(ctx->opcode);
-    uint32_t me = ME(ctx->opcode);
+    uint32_t mb, me, sh;
 
-    if (sh == (31-me) && mb <= me) {
-        tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
+    mb = MB(ctx->opcode);
+    me = ME(ctx->opcode);
+    sh = SH(ctx->opcode);
+    if (likely(sh == (31-me) && mb <= me)) {
+        tcg_gen_deposit_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
+                           cpu_gpr[rS(ctx->opcode)], sh, me - mb + 1);
     } else {
         target_ulong mask;
         TCGv t1;
-
+        TCGv t0 = tcg_temp_new();
+#if defined(TARGET_PPC64)
+        tcg_gen_deposit_i64(t0, cpu_gpr[rS(ctx->opcode)],
+            cpu_gpr[rS(ctx->opcode)], 32, 32);
+        tcg_gen_rotli_i64(t0, t0, sh);
+#else
+        tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
+#endif
 #if defined(TARGET_PPC64)
         mb += 32;
         me += 32;
 #endif
         mask = MASK(mb, me);
-
         t1 = tcg_temp_new();
-        if (mask <= 0xffffffffu) {
-            TCGv_i32 t0 = tcg_temp_new_i32();
-            tcg_gen_trunc_tl_i32(t0, t_rs);
-            tcg_gen_rotli_i32(t0, t0, sh);
-            tcg_gen_extu_i32_tl(t1, t0);
-            tcg_temp_free_i32(t0);
-        } else {
-#if defined(TARGET_PPC64)
-            tcg_gen_deposit_i64(t1, t_rs, t_rs, 32, 32);
-            tcg_gen_rotli_i64(t1, t1, sh);
-#else
-            g_assert_not_reached();
-#endif
-        }
-
-        tcg_gen_andi_tl(t1, t1, mask);
-        tcg_gen_andi_tl(t_ra, t_ra, ~mask);
-        tcg_gen_or_tl(t_ra, t_ra, t1);
+        tcg_gen_andi_tl(t0, t0, mask);
+        tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
+        tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
+        tcg_temp_free(t0);
         tcg_temp_free(t1);
     }
-    if (unlikely(Rc(ctx->opcode) != 0)) {
-        gen_set_Rc0(ctx, t_ra);
-    }
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
 
 /* rlwinm & rlwinm. */
 static void gen_rlwinm(DisasContext *ctx)
 {
-    TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
-    TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
-    uint32_t sh = SH(ctx->opcode);
-    uint32_t mb = MB(ctx->opcode);
-    uint32_t me = ME(ctx->opcode);
+    uint32_t mb, me, sh;
 
-    if (mb == 0 && me == (31 - sh)) {
-        tcg_gen_shli_tl(t_ra, t_rs, sh);
-        tcg_gen_ext32u_tl(t_ra, t_ra);
-    } else if (sh != 0 && me == 31 && sh == (32 - mb)) {
-        tcg_gen_ext32u_tl(t_ra, t_rs);
-        tcg_gen_shri_tl(t_ra, t_ra, mb);
-    } else {
-        target_ulong mask;
-#if defined(TARGET_PPC64)
-        mb += 32;
-        me += 32;
-#endif
-        mask = MASK(mb, me);
+    sh = SH(ctx->opcode);
+    mb = MB(ctx->opcode);
+    me = ME(ctx->opcode);
 
-        if (mask <= 0xffffffffu) {
-            TCGv_i32 t0 = tcg_temp_new_i32();
-            tcg_gen_trunc_tl_i32(t0, t_rs);
-            tcg_gen_rotli_i32(t0, t0, sh);
-            tcg_gen_andi_i32(t0, t0, mask);
-            tcg_gen_extu_i32_tl(t_ra, t0);
-            tcg_temp_free_i32(t0);
+    if (likely(mb == 0 && me == (31 - sh))) {
+        if (likely(sh == 0)) {
+            tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
         } else {
+            TCGv t0 = tcg_temp_new();
+            tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
+            tcg_gen_shli_tl(t0, t0, sh);
+            tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
+            tcg_temp_free(t0);
+        }
+    } else if (likely(sh != 0 && me == 31 && sh == (32 - mb))) {
+        TCGv t0 = tcg_temp_new();
+        tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
+        tcg_gen_shri_tl(t0, t0, mb);
+        tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
+        tcg_temp_free(t0);
+    } else if (likely(mb == 0 && me == 31)) {
+        TCGv_i32 t0 = tcg_temp_new_i32();
+        tcg_gen_trunc_tl_i32(t0, cpu_gpr[rS(ctx->opcode)]);
+        tcg_gen_rotli_i32(t0, t0, sh);
+        tcg_gen_extu_i32_tl(cpu_gpr[rA(ctx->opcode)], t0);
+        tcg_temp_free_i32(t0);
+    } else {
+        TCGv t0 = tcg_temp_new();
 #if defined(TARGET_PPC64)
-            tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
-            tcg_gen_rotli_i64(t_ra, t_ra, sh);
-            tcg_gen_andi_i64(t_ra, t_ra, mask);
+        tcg_gen_deposit_i64(t0, cpu_gpr[rS(ctx->opcode)],
+            cpu_gpr[rS(ctx->opcode)], 32, 32);
+        tcg_gen_rotli_i64(t0, t0, sh);
 #else
-            g_assert_not_reached();
+        tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
 #endif
-        }
-    }
-    if (unlikely(Rc(ctx->opcode) != 0)) {
-        gen_set_Rc0(ctx, t_ra);
+#if defined(TARGET_PPC64)
+        mb += 32;
+        me += 32;
+#endif
+        tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
+        tcg_temp_free(t0);
     }
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
 
 /* rlwnm & rlwnm. */
 static void gen_rlwnm(DisasContext *ctx)
 {
-    TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
-    TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
-    TCGv t_rb = cpu_gpr[rB(ctx->opcode)];
-    uint32_t mb = MB(ctx->opcode);
-    uint32_t me = ME(ctx->opcode);
-    target_ulong mask;
+    uint32_t mb, me;
+    mb = MB(ctx->opcode);
+    me = ME(ctx->opcode);
 
-#if defined(TARGET_PPC64)
-    mb += 32;
-    me += 32;
-#endif
-    mask = MASK(mb, me);
-
-    if (mask <= 0xffffffffu) {
-        TCGv_i32 t0 = tcg_temp_new_i32();
-        TCGv_i32 t1 = tcg_temp_new_i32();
-        tcg_gen_trunc_tl_i32(t0, t_rb);
-        tcg_gen_trunc_tl_i32(t1, t_rs);
+    if (likely(mb == 0 && me == 31)) {
+        TCGv_i32 t0, t1;
+        t0 = tcg_temp_new_i32();
+        t1 = tcg_temp_new_i32();
+        tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);
+        tcg_gen_trunc_tl_i32(t1, cpu_gpr[rS(ctx->opcode)]);
         tcg_gen_andi_i32(t0, t0, 0x1f);
         tcg_gen_rotl_i32(t1, t1, t0);
-        tcg_gen_extu_i32_tl(t_ra, t1);
+        tcg_gen_extu_i32_tl(cpu_gpr[rA(ctx->opcode)], t1);
         tcg_temp_free_i32(t0);
         tcg_temp_free_i32(t1);
     } else {
+        TCGv t0;
 #if defined(TARGET_PPC64)
-        TCGv_i64 t0 = tcg_temp_new_i64();
-        tcg_gen_andi_i64(t0, t_rb, 0x1f);
-        tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
-        tcg_gen_rotl_i64(t_ra, t_ra, t0);
-        tcg_temp_free_i64(t0);
-#else
-        g_assert_not_reached();
+        TCGv t1;
 #endif
-    }
-
-    tcg_gen_andi_tl(t_ra, t_ra, mask);
 
-    if (unlikely(Rc(ctx->opcode) != 0)) {
-        gen_set_Rc0(ctx, t_ra);
+        t0 = tcg_temp_new();
+        tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1f);
+#if defined(TARGET_PPC64)
+        t1 = tcg_temp_new_i64();
+        tcg_gen_deposit_i64(t1, cpu_gpr[rS(ctx->opcode)],
+                            cpu_gpr[rS(ctx->opcode)], 32, 32);
+        tcg_gen_rotl_i64(t0, t1, t0);
+        tcg_temp_free_i64(t1);
+#else
+        tcg_gen_rotl_i32(t0, cpu_gpr[rS(ctx->opcode)], t0);
+#endif
+        if (unlikely(mb != 0 || me != 31)) {
+#if defined(TARGET_PPC64)
+            mb += 32;
+            me += 32;
+#endif
+            tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
+        } else {
+            tcg_gen_andi_tl(t0, t0, MASK(32, 63));
+            tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
+        }
+        tcg_temp_free(t0);
     }
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
 
 #if defined(TARGET_PPC64)
@@ -1841,24 +1785,26 @@ static void glue(gen_, name##3)(DisasContext *ctx)                            \
     gen_##name(ctx, 1, 1);                                                    \
 }
 
-static void gen_rldinm(DisasContext *ctx, int mb, int me, int sh)
+static inline void gen_rldinm(DisasContext *ctx, uint32_t mb, uint32_t me,
+                              uint32_t sh)
 {
-    TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
-    TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
-
-    if (sh != 0 && mb == 0 && me == (63 - sh)) {
-        tcg_gen_shli_tl(t_ra, t_rs, sh);
-    } else if (sh != 0 && me == 63 && sh == (64 - mb)) {
-        tcg_gen_shri_tl(t_ra, t_rs, mb);
+    if (likely(sh != 0 && mb == 0 && me == (63 - sh))) {
+        tcg_gen_shli_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
+    } else if (likely(sh != 0 && me == 63 && sh == (64 - mb))) {
+        tcg_gen_shri_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], mb);
     } else {
-        tcg_gen_rotli_tl(t_ra, t_rs, sh);
-        tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
-    }
-    if (unlikely(Rc(ctx->opcode) != 0)) {
-        gen_set_Rc0(ctx, t_ra);
+        TCGv t0 = tcg_temp_new();
+        tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
+        if (likely(mb == 0 && me == 63)) {
+            tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
+        } else {
+            tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
+        }
+        tcg_temp_free(t0);
     }
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
-
 /* rldicl - rldicl. */
 static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn)
 {
@@ -1869,7 +1815,6 @@ static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn)
     gen_rldinm(ctx, mb, 63, sh);
 }
 GEN_PPC64_R4(rldicl, 0x1E, 0x00);
-
 /* rldicr - rldicr. */
 static inline void gen_rldicr(DisasContext *ctx, int men, int shn)
 {
@@ -1880,7 +1825,6 @@ static inline void gen_rldicr(DisasContext *ctx, int men, int shn)
     gen_rldinm(ctx, 0, me, sh);
 }
 GEN_PPC64_R4(rldicr, 0x1E, 0x02);
-
 /* rldic - rldic. */
 static inline void gen_rldic(DisasContext *ctx, int mbn, int shn)
 {
@@ -1892,22 +1836,21 @@ static inline void gen_rldic(DisasContext *ctx, int mbn, int shn)
 }
 GEN_PPC64_R4(rldic, 0x1E, 0x04);
 
-static void gen_rldnm(DisasContext *ctx, int mb, int me)
+static inline void gen_rldnm(DisasContext *ctx, uint32_t mb, uint32_t me)
 {
-    TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
-    TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
-    TCGv t_rb = cpu_gpr[rB(ctx->opcode)];
     TCGv t0;
 
     t0 = tcg_temp_new();
-    tcg_gen_andi_tl(t0, t_rb, 0x3f);
-    tcg_gen_rotl_tl(t_ra, t_rs, t0);
-    tcg_temp_free(t0);
-
-    tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
-    if (unlikely(Rc(ctx->opcode) != 0)) {
-        gen_set_Rc0(ctx, t_ra);
+    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
+    tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
+    if (unlikely(mb != 0 || me != 63)) {
+        tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
+    } else {
+        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
     }
+    tcg_temp_free(t0);
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
 
 /* rldcl - rldcl. */
@@ -1919,7 +1862,6 @@ static inline void gen_rldcl(DisasContext *ctx, int mbn)
     gen_rldnm(ctx, mb, 63);
 }
 GEN_PPC64_R2(rldcl, 0x1E, 0x08);
-
 /* rldcr - rldcr. */
 static inline void gen_rldcr(DisasContext *ctx, int men)
 {
@@ -1929,31 +1871,32 @@ static inline void gen_rldcr(DisasContext *ctx, int men)
     gen_rldnm(ctx, 0, me);
 }
 GEN_PPC64_R2(rldcr, 0x1E, 0x09);
-
 /* rldimi - rldimi. */
-static void gen_rldimi(DisasContext *ctx, int mbn, int shn)
+static inline void gen_rldimi(DisasContext *ctx, int mbn, int shn)
 {
-    TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
-    TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
-    uint32_t sh = SH(ctx->opcode) | (shn << 5);
-    uint32_t mb = MB(ctx->opcode) | (mbn << 5);
-    uint32_t me = 63 - sh;
+    uint32_t sh, mb, me;
 
-    if (mb <= me) {
-        tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
+    sh = SH(ctx->opcode) | (shn << 5);
+    mb = MB(ctx->opcode) | (mbn << 5);
+    me = 63 - sh;
+    if (unlikely(sh == 0 && mb == 0)) {
+        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
     } else {
-        target_ulong mask = MASK(mb, me);
-        TCGv t1 = tcg_temp_new();
+        TCGv t0, t1;
+        target_ulong mask;
 
-        tcg_gen_rotli_tl(t1, t_rs, sh);
-        tcg_gen_andi_tl(t1, t1, mask);
-        tcg_gen_andi_tl(t_ra, t_ra, ~mask);
-        tcg_gen_or_tl(t_ra, t_ra, t1);
+        t0 = tcg_temp_new();
+        tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
+        t1 = tcg_temp_new();
+        mask = MASK(mb, me);
+        tcg_gen_andi_tl(t0, t0, mask);
+        tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
+        tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
+        tcg_temp_free(t0);
         tcg_temp_free(t1);
     }
-    if (unlikely(Rc(ctx->opcode) != 0)) {
-        gen_set_Rc0(ctx, t_ra);
-    }
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
 GEN_PPC64_R4(rldimi, 0x1E, 0x06);
 #endif
@@ -2934,23 +2877,18 @@ static void glue(gen_, name##ux)(DisasContext *ctx)
     tcg_temp_free(EA);                                                        \
 }
 
-#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
+#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
 static void glue(gen_, name##x)(DisasContext *ctx)                            \
 {                                                                             \
     TCGv EA;                                                                  \
-    chk;                                                                      \
     gen_set_access_type(ctx, ACCESS_INT);                                     \
     EA = tcg_temp_new();                                                      \
     gen_addr_reg_index(ctx, EA);                                              \
     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
     tcg_temp_free(EA);                                                        \
 }
-
 #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
-    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_NONE)
-
-#define GEN_LDX_HVRM(name, ldop, opc2, opc3, type)                            \
-    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
+    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE)
 
 #define GEN_LDS(name, ldop, op, type)                                         \
 GEN_LD(name, ldop, op | 0x20, type);                                          \
@@ -2976,12 +2914,6 @@ GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B);
 /* ldx */
 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
 
-/* CI load/store variants */
-GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST)
-GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST)
-GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
-GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
-
 static void gen_ld(DisasContext *ctx)
 {
     TCGv EA;
@@ -3018,7 +2950,7 @@ static void gen_lq(DisasContext *ctx)
     bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
 
     if (!legal_in_user_mode && ctx->pr) {
-        gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
         return;
     }
 
@@ -3100,11 +3032,10 @@ static void glue(gen_, name##ux)(DisasContext *ctx)
     tcg_temp_free(EA);                                                        \
 }
 
-#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
+#define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
 static void glue(gen_, name##x)(DisasContext *ctx)                            \
 {                                                                             \
     TCGv EA;                                                                  \
-    chk;                                                                      \
     gen_set_access_type(ctx, ACCESS_INT);                                     \
     EA = tcg_temp_new();                                                      \
     gen_addr_reg_index(ctx, EA);                                              \
@@ -3112,10 +3043,7 @@ static void glue(gen_, name##x)(DisasContext *ctx)                            \
     tcg_temp_free(EA);                                                        \
 }
 #define GEN_STX(name, stop, opc2, opc3, type)                                 \
-    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_NONE)
-
-#define GEN_STX_HVRM(name, stop, opc2, opc3, type)                            \
-    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
+    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE)
 
 #define GEN_STS(name, stop, op, type)                                         \
 GEN_ST(name, stop, op | 0x20, type);                                          \
@@ -3132,10 +3060,6 @@ GEN_STS(stw, st32, 0x04, PPC_INTEGER);
 #if defined(TARGET_PPC64)
 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
 GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
-GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST)
-GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
-GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
-GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
 
 static void gen_std(DisasContext *ctx)
 {
@@ -3144,15 +3068,12 @@ static void gen_std(DisasContext *ctx)
 
     rs = rS(ctx->opcode);
     if ((ctx->opcode & 0x3) == 0x2) { /* stq */
+
         bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
         bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
 
-        if (!(ctx->insns_flags & PPC_64BX)) {
-            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
-        }
-
         if (!legal_in_user_mode && ctx->pr) {
-            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
             return;
         }
 
@@ -3224,7 +3145,7 @@ static inline void gen_qemu_ld64ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
     TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
     tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, op);
 }
-GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE);
+GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX);
 #endif  /* TARGET_PPC64 */
 
 /* sthbrx */
@@ -3250,7 +3171,7 @@ static inline void gen_qemu_st64r(DisasContext *ctx, TCGv arg1, TCGv arg2)
     TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
     tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, op);
 }
-GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE);
+GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX);
 #endif  /* TARGET_PPC64 */
 
 /***                    Integer load and store multiple                    ***/
@@ -3391,37 +3312,9 @@ static void gen_eieio(DisasContext *ctx)
 {
 }
 
-#if !defined(CONFIG_USER_ONLY)
-static inline void gen_check_tlb_flush(DisasContext *ctx)
-{
-    TCGv_i32 t;
-    TCGLabel *l;
-
-    if (!ctx->lazy_tlb_flush) {
-        return;
-    }
-    l = gen_new_label();
-    t = tcg_temp_new_i32();
-    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
-    tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, l);
-    gen_helper_check_tlb_flush(cpu_env);
-    gen_set_label(l);
-    tcg_temp_free_i32(t);
-}
-#else
-static inline void gen_check_tlb_flush(DisasContext *ctx) { }
-#endif
-
 /* isync */
 static void gen_isync(DisasContext *ctx)
 {
-    /*
-     * We need to check for a pending TLB flush. This can only happen in
-     * kernel mode however so check MSR_PR
-     */
-    if (!ctx->pr) {
-        gen_check_tlb_flush(ctx);
-    }
     gen_stop_exception(ctx);
 }
 
@@ -3578,25 +3471,12 @@ STCX(stqcx_, 16);
 /* sync */
 static void gen_sync(DisasContext *ctx)
 {
-    uint32_t l = (ctx->opcode >> 21) & 3;
-
-    /*
-     * We may need to check for a pending TLB flush.
-     *
-     * We do this on ptesync (l == 2) on ppc64 and any sync pn ppc32.
-     *
-     * Additionally, this can only happen in kernel mode however so
-     * check MSR_PR as well.
-     */
-    if (((l == 2) || !(ctx->insns_flags & PPC_64B)) && !ctx->pr) {
-        gen_check_tlb_flush(ctx);
-    }
 }
 
 /* wait */
 static void gen_wait(DisasContext *ctx)
 {
-    TCGv_i32 t0 = tcg_const_i32(1);
+    TCGv_i32 t0 = tcg_temp_new_i32();
     tcg_gen_st_i32(t0, cpu_env,
                    -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
     tcg_temp_free_i32(t0);
@@ -3604,68 +3484,6 @@ static void gen_wait(DisasContext *ctx)
     gen_exception_err(ctx, EXCP_HLT, 1);
 }
 
-#if defined(TARGET_PPC64)
-static void gen_doze(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
-#else
-    TCGv_i32 t;
-
-    CHK_HV;
-    t = tcg_const_i32(PPC_PM_DOZE);
-    gen_helper_pminsn(cpu_env, t);
-    tcg_temp_free_i32(t);
-    gen_stop_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_nap(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
-#else
-    TCGv_i32 t;
-
-    CHK_HV;
-    t = tcg_const_i32(PPC_PM_NAP);
-    gen_helper_pminsn(cpu_env, t);
-    tcg_temp_free_i32(t);
-    gen_stop_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_sleep(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
-#else
-    TCGv_i32 t;
-
-    CHK_HV;
-    t = tcg_const_i32(PPC_PM_SLEEP);
-    gen_helper_pminsn(cpu_env, t);
-    tcg_temp_free_i32(t);
-    gen_stop_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_rvwinkle(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
-#else
-    TCGv_i32 t;
-
-    CHK_HV;
-    t = tcg_const_i32(PPC_PM_RVWINKLE);
-    gen_helper_pminsn(cpu_env, t);
-    tcg_temp_free_i32(t);
-    gen_stop_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-#endif /* #if defined(TARGET_PPC64) */
-
 /***                         Floating-point load                           ***/
 #define GEN_LDF(name, ldop, opc, type)                                        \
 static void glue(gen_, name)(DisasContext *ctx)                                       \
@@ -4004,29 +3822,19 @@ static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
 #endif
 }
 
-static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
-{
-    if (unlikely(ctx->singlestep_enabled)) {
-        return false;
-    }
-
-#ifndef CONFIG_USER_ONLY
-    return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
 /***                                Branch                                 ***/
 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
 {
+    TranslationBlock *tb;
+    tb = ctx->tb;
     if (NARROW_MODE(ctx)) {
         dest = (uint32_t) dest;
     }
-    if (use_goto_tb(ctx, dest)) {
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
+        likely(!ctx->singlestep_enabled)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(cpu_nip, dest & ~3);
-        tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_tl(cpu_nip, dest & ~3);
         if (unlikely(ctx->singlestep_enabled)) {
@@ -4244,14 +4052,13 @@ static void gen_mcrf(DisasContext *ctx)
 static void gen_rfi(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    /* FIXME: This instruction doesn't exist anymore on 64-bit server
-     * processors compliant with arch 2.x, we should remove it there,
-     * but we need to fix OpenBIOS not to use it on 970 first
-     */
     /* Restore CPU state */
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_update_cfar(ctx, ctx->nip);
     gen_helper_rfi(cpu_env);
     gen_sync_exception(ctx);
@@ -4262,10 +4069,13 @@ static void gen_rfi(DisasContext *ctx)
 static void gen_rfid(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
     /* Restore CPU state */
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_update_cfar(ctx, ctx->nip);
     gen_helper_rfid(cpu_env);
     gen_sync_exception(ctx);
@@ -4275,10 +4085,13 @@ static void gen_rfid(DisasContext *ctx)
 static void gen_hrfid(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
     /* Restore CPU state */
-    CHK_HV;
+    if (unlikely(!ctx->hv)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_helper_hrfid(cpu_env);
     gen_sync_exception(ctx);
 #endif
@@ -4441,8 +4254,15 @@ static void gen_mfcr(DisasContext *ctx)
 /* mfmsr */
 static void gen_mfmsr(DisasContext *ctx)
 {
-    CHK_SV;
+#if defined(CONFIG_USER_ONLY)
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+#else
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
+#endif
 }
 
 static void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
@@ -4488,15 +4308,9 @@ static inline void gen_op_mfspr(DisasContext *ctx)
                              TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
                 }
             }
-            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
+            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
         }
     } else {
-        /* ISA 2.07 defines these as no-ops */
-        if ((ctx->insns_flags2 & PPC2_ISA207S) &&
-            (sprn >= 808 && sprn <= 811)) {
-            /* This is a nop */
-            return;
-        }
         /* Not defined */
         fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at "
                 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
@@ -4504,19 +4318,7 @@ static inline void gen_op_mfspr(DisasContext *ctx)
             qemu_log("Trying to read invalid spr %d (0x%03x) at "
                      TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
         }
-
-        /* The behaviour depends on MSR:PR and SPR# bit 0x10,
-         * it can generate a priv, a hv emu or a no-op
-         */
-        if (sprn & 0x10) {
-            if (ctx->pr) {
-                gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
-            }
-        } else {
-            if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) {
-                gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
-            }
-        }
+        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
     }
 }
 
@@ -4563,14 +4365,18 @@ static void gen_mtcrf(DisasContext *ctx)
 #if defined(TARGET_PPC64)
 static void gen_mtmsrd(DisasContext *ctx)
 {
-    CHK_SV;
-
-#if !defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+#else
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     if (ctx->opcode & 0x00010000) {
         /* Special form that does not need any synchronisation */
         TCGv t0 = tcg_temp_new();
         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
-        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
+        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
         tcg_temp_free(t0);
     } else {
@@ -4584,20 +4390,24 @@ static void gen_mtmsrd(DisasContext *ctx)
         /* Note that mtmsr is not always defined as context-synchronizing */
         gen_stop_exception(ctx);
     }
-#endif /* !defined(CONFIG_USER_ONLY) */
+#endif
 }
-#endif /* defined(TARGET_PPC64) */
+#endif
 
 static void gen_mtmsr(DisasContext *ctx)
 {
-    CHK_SV;
-
-#if !defined(CONFIG_USER_ONLY)
-   if (ctx->opcode & 0x00010000) {
+#if defined(CONFIG_USER_ONLY)
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+#else
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
+    if (ctx->opcode & 0x00010000) {
         /* Special form that does not need any synchronisation */
         TCGv t0 = tcg_temp_new();
         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
-        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
+        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
         tcg_temp_free(t0);
     } else {
@@ -4650,16 +4460,9 @@ static void gen_mtspr(DisasContext *ctx)
                 qemu_log("Trying to write privileged spr %d (0x%03x) at "
                          TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
             }
-            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
+            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
         }
     } else {
-        /* ISA 2.07 defines these as no-ops */
-        if ((ctx->insns_flags2 & PPC2_ISA207S) &&
-            (sprn >= 808 && sprn <= 811)) {
-            /* This is a nop */
-            return;
-        }
-
         /* Not defined */
         if (qemu_log_separate()) {
             qemu_log("Trying to write invalid spr %d (0x%03x) at "
@@ -4667,20 +4470,7 @@ static void gen_mtspr(DisasContext *ctx)
         }
         fprintf(stderr, "Trying to write invalid spr %d (0x%03x) at "
                 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
-
-
-        /* The behaviour depends on MSR:PR and SPR# bit 0x10,
-         * it can generate a priv, a hv emu or a no-op
-         */
-        if (sprn & 0x10) {
-            if (ctx->pr) {
-                gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
-            }
-        } else {
-            if (ctx->pr || sprn == 0) {
-                gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
-            }
-        }
+        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
     }
 }
 
@@ -4702,11 +4492,13 @@ static void gen_dcbf(DisasContext *ctx)
 static void gen_dcbi(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
     TCGv EA, val;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     EA = tcg_temp_new();
     gen_set_access_type(ctx, ACCESS_CACHE);
     gen_addr_reg_index(ctx, EA);
@@ -4716,7 +4508,7 @@ static void gen_dcbi(DisasContext *ctx)
     gen_qemu_st8(ctx, val, EA);
     tcg_temp_free(val);
     tcg_temp_free(EA);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* dcdst */
@@ -4837,64 +4629,72 @@ static void gen_dcba(DisasContext *ctx)
 static void gen_mfsr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
     TCGv t0;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     t0 = tcg_const_tl(SR(ctx->opcode));
     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* mfsrin */
 static void gen_mfsrin(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
     TCGv t0;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* mtsr */
 static void gen_mtsr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
     TCGv t0;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     t0 = tcg_const_tl(SR(ctx->opcode));
     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* mtsrin */
 static void gen_mtsrin(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
     TCGv t0;
-    CHK_SV;
-
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rD(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 #if defined(TARGET_PPC64)
@@ -4904,125 +4704,114 @@ static void gen_mtsrin(DisasContext *ctx)
 static void gen_mfsr_64b(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
     TCGv t0;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     t0 = tcg_const_tl(SR(ctx->opcode));
     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* mfsrin */
 static void gen_mfsrin_64b(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
     TCGv t0;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* mtsr */
 static void gen_mtsr_64b(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
     TCGv t0;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     t0 = tcg_const_tl(SR(ctx->opcode));
     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* mtsrin */
 static void gen_mtsrin_64b(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
     TCGv t0;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* slbmte */
 static void gen_slbmte(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
-    CHK_SV;
-
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)],
                          cpu_gpr[rS(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 static void gen_slbmfee(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
-    CHK_SV;
-
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,
                              cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 static void gen_slbmfev(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
-#else
-    CHK_SV;
-
-    gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
-                             cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_slbfee_(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
-    TCGLabel *l1, *l2;
-
     if (unlikely(ctx->pr)) {
         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
         return;
     }
-    gen_helper_find_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
+    gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
                              cpu_gpr[rB(ctx->opcode)]);
-    l1 = gen_new_label();
-    l2 = gen_new_label();
-    tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
-    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rS(ctx->opcode)], -1, l1);
-    tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
-    tcg_gen_br(l2);
-    gen_set_label(l1);
-    tcg_gen_movi_tl(cpu_gpr[rS(ctx->opcode)], 0);
-    gen_set_label(l2);
 #endif
 }
 #endif /* defined(TARGET_PPC64) */
@@ -5034,34 +4823,40 @@ static void gen_slbfee_(DisasContext *ctx)
 static void gen_tlbia(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_HV;
-
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_helper_tlbia(cpu_env);
-#endif  /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* tlbiel */
 static void gen_tlbiel(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
-
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* tlbie */
 static void gen_tlbie(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_HV;
-
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     if (NARROW_MODE(ctx)) {
         TCGv t0 = tcg_temp_new();
         tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
@@ -5070,23 +4865,24 @@ static void gen_tlbie(DisasContext *ctx)
     } else {
         gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
     }
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* tlbsync */
 static void gen_tlbsync(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_HV;
-
-    /* tlbsync is a nop for server, ptesync handles delayed tlb flush,
-     * embedded however needs to deal with tlbsync. We don't try to be
-     * fancy and swallow the overhead of checking for both.
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
+    /* This has no effect: it should ensure that all previous
+     * tlbie have completed
      */
-    gen_check_tlb_flush(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
+    gen_stop_exception(ctx);
+#endif
 }
 
 #if defined(TARGET_PPC64)
@@ -5094,26 +4890,30 @@ static void gen_tlbsync(DisasContext *ctx)
 static void gen_slbia(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
-
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_helper_slbia(cpu_env);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* slbie */
 static void gen_slbie(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
-
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
-#endif  /* defined(TARGET_PPC64) */
+#endif
 
 /***                              External control                         ***/
 /* Optional: */
@@ -5812,11 +5612,14 @@ static void gen_esa(DisasContext *ctx)
 static void gen_mfrom(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* 602 - 603 - G2 TLB management */
@@ -5825,22 +5628,28 @@ static void gen_mfrom(DisasContext *ctx)
 static void gen_tlbld_6xx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* tlbli */
 static void gen_tlbli_6xx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* 74xx TLB management */
@@ -5849,22 +5658,28 @@ static void gen_tlbli_6xx(DisasContext *ctx)
 static void gen_tlbld_74xx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_helper_74xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* tlbli */
 static void gen_tlbli_74xx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_helper_74xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* POWER instructions not in PowerPC 601 */
@@ -5878,12 +5693,15 @@ static void gen_clf(DisasContext *ctx)
 /* cli */
 static void gen_cli(DisasContext *ctx)
 {
+    /* Cache line invalidate: privileged and treated as no-op */
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    /* Cache line invalidate: privileged and treated as no-op */
-    CHK_SV;
-#endif /* defined(CONFIG_USER_ONLY) */
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
+#endif
 }
 
 /* dclst */
@@ -5895,13 +5713,15 @@ static void gen_dclst(DisasContext *ctx)
 static void gen_mfsri(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
     int ra = rA(ctx->opcode);
     int rd = rD(ctx->opcode);
     TCGv t0;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     tcg_gen_shri_tl(t0, t0, 28);
@@ -5910,34 +5730,38 @@ static void gen_mfsri(DisasContext *ctx)
     tcg_temp_free(t0);
     if (ra != 0 && ra != rd)
         tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 static void gen_rac(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
     TCGv t0;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     gen_helper_rac(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 static void gen_rfsvc(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
-
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_helper_rfsvc(cpu_env);
     gen_sync_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* svc is not implemented for now */
@@ -6090,16 +5914,18 @@ static void gen_mfapidi(DisasContext *ctx)
 static void gen_tlbiva(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
     TCGv t0;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* All 405 MAC instructions are translated here */
@@ -6321,34 +6147,38 @@ GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
 static void gen_mfdcr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
     TCGv dcrn;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     dcrn = tcg_const_tl(SPR(ctx->opcode));
     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn);
     tcg_temp_free(dcrn);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* mtdcr */
 static void gen_mtdcr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
     TCGv dcrn;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     dcrn = tcg_const_tl(SPR(ctx->opcode));
     gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(dcrn);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* mfdcrx */
@@ -6356,15 +6186,18 @@ static void gen_mtdcr(DisasContext *ctx)
 static void gen_mfdcrx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
                         cpu_gpr[rA(ctx->opcode)]);
     /* Note: Rc update flag set leads to undefined state of Rc0 */
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* mtdcrx */
@@ -6372,15 +6205,18 @@ static void gen_mfdcrx(DisasContext *ctx)
 static void gen_mtdcrx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
                          cpu_gpr[rS(ctx->opcode)]);
     /* Note: Rc update flag set leads to undefined state of Rc0 */
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* mfdcrux (PPC 460) : user-mode access to DCR */
@@ -6406,19 +6242,28 @@ static void gen_mtdcrux(DisasContext *ctx)
 /* dccci */
 static void gen_dccci(DisasContext *ctx)
 {
-    CHK_SV;
+#if defined(CONFIG_USER_ONLY)
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+#else
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     /* interpreted as no-op */
+#endif
 }
 
 /* dcread */
 static void gen_dcread(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
     TCGv EA, val;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_set_access_type(ctx, ACCESS_CACHE);
     EA = tcg_temp_new();
     gen_addr_reg_index(ctx, EA);
@@ -6427,7 +6272,7 @@ static void gen_dcread(DisasContext *ctx)
     tcg_temp_free(val);
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
     tcg_temp_free(EA);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* icbt */
@@ -6442,40 +6287,60 @@ static void gen_icbt_40x(DisasContext *ctx)
 /* iccci */
 static void gen_iccci(DisasContext *ctx)
 {
-    CHK_SV;
+#if defined(CONFIG_USER_ONLY)
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+#else
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     /* interpreted as no-op */
+#endif
 }
 
 /* icread */
 static void gen_icread(DisasContext *ctx)
 {
-    CHK_SV;
+#if defined(CONFIG_USER_ONLY)
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+#else
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     /* interpreted as no-op */
+#endif
 }
 
 /* rfci (supervisor only) */
 static void gen_rfci_40x(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     /* Restore CPU state */
     gen_helper_40x_rfci(cpu_env);
     gen_sync_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 static void gen_rfci(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     /* Restore CPU state */
     gen_helper_rfci(cpu_env);
     gen_sync_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* BookE specific */
@@ -6484,26 +6349,32 @@ static void gen_rfci(DisasContext *ctx)
 static void gen_rfdi(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     /* Restore CPU state */
     gen_helper_rfdi(cpu_env);
     gen_sync_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* XXX: not implemented on 440 ? */
 static void gen_rfmci(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     /* Restore CPU state */
     gen_helper_rfmci(cpu_env);
     gen_sync_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* TLB management - PowerPC 405 implementation */
@@ -6512,9 +6383,12 @@ static void gen_rfmci(DisasContext *ctx)
 static void gen_tlbre_40x(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     switch (rB(ctx->opcode)) {
     case 0:
         gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env,
@@ -6528,18 +6402,20 @@ static void gen_tlbre_40x(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         break;
     }
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* tlbsx - tlbsx. */
 static void gen_tlbsx_40x(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
     TCGv t0;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
@@ -6551,17 +6427,19 @@ static void gen_tlbsx_40x(DisasContext *ctx)
         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
         gen_set_label(l1);
     }
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* tlbwe */
 static void gen_tlbwe_40x(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
-
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     switch (rB(ctx->opcode)) {
     case 0:
         gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)],
@@ -6575,7 +6453,7 @@ static void gen_tlbwe_40x(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         break;
     }
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* TLB management - PowerPC 440 implementation */
@@ -6584,10 +6462,12 @@ static void gen_tlbwe_40x(DisasContext *ctx)
 static void gen_tlbre_440(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
-
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     switch (rB(ctx->opcode)) {
     case 0:
     case 1:
@@ -6603,18 +6483,20 @@ static void gen_tlbre_440(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         break;
     }
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* tlbsx - tlbsx. */
 static void gen_tlbsx_440(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
     TCGv t0;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
@@ -6626,16 +6508,19 @@ static void gen_tlbsx_440(DisasContext *ctx)
         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
         gen_set_label(l1);
     }
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* tlbwe */
 static void gen_tlbwe_440(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     switch (rB(ctx->opcode)) {
     case 0:
     case 1:
@@ -6651,7 +6536,7 @@ static void gen_tlbwe_440(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         break;
     }
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* TLB management - PowerPC BookE 2.06 implementation */
@@ -6659,23 +6544,30 @@ static void gen_tlbwe_440(DisasContext *ctx)
 /* tlbre */
 static void gen_tlbre_booke206(DisasContext *ctx)
 {
- #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+#if defined(CONFIG_USER_ONLY)
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-   CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
+
     gen_helper_booke206_tlbre(cpu_env);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* tlbsx - tlbsx. */
 static void gen_tlbsx_booke206(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
     TCGv t0;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
 
-    CHK_SV;
     if (rA(ctx->opcode)) {
         t0 = tcg_temp_new();
         tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
@@ -6686,44 +6578,54 @@ static void gen_tlbsx_booke206(DisasContext *ctx)
     tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
     gen_helper_booke206_tlbsx(cpu_env, t0);
     tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* tlbwe */
 static void gen_tlbwe_booke206(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     gen_update_nip(ctx, ctx->nip - 4);
     gen_helper_booke206_tlbwe(cpu_env);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 static void gen_tlbivax_booke206(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
     TCGv t0;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
 
-    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
+
     gen_helper_booke206_tlbivax(cpu_env, t0);
     tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 static void gen_tlbilx_booke206(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
     TCGv t0;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
 
-    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
 
@@ -6743,7 +6645,7 @@ static void gen_tlbilx_booke206(DisasContext *ctx)
     }
 
     tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 
@@ -6751,11 +6653,13 @@ static void gen_tlbilx_booke206(DisasContext *ctx)
 static void gen_wrtee(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
     TCGv t0;
-
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     t0 = tcg_temp_new();
     tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
     tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
@@ -6765,16 +6669,19 @@ static void gen_wrtee(DisasContext *ctx)
      * if we just set msr_ee to 1
      */
     gen_stop_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* wrteei */
 static void gen_wrteei(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
     if (ctx->opcode & 0x00008000) {
         tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
         /* Stop translation to have a chance to raise an exception */
@@ -6782,7 +6689,7 @@ static void gen_wrteei(DisasContext *ctx)
     } else {
         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
     }
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /* PowerPC 440 specific instructions */
@@ -6822,21 +6729,29 @@ static void gen_icbt_440(DisasContext *ctx)
 static void gen_msgclr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
+
     gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 static void gen_msgsnd(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
-    CHK_SV;
+    if (unlikely(ctx->pr)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
+
     gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
+#endif
 }
 
 /***                      Altivec vector extension                         ***/
@@ -9838,7 +9753,7 @@ static void gen_tcheck(DisasContext *ctx)
 #define GEN_TM_PRIV_NOOP(name)                                 \
 static inline void gen_##name(DisasContext *ctx)               \
 {                                                              \
-    gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);           \
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);           \
 }
 
 #else
@@ -9846,7 +9761,10 @@ static inline void gen_##name(DisasContext *ctx)               \
 #define GEN_TM_PRIV_NOOP(name)                                 \
 static inline void gen_##name(DisasContext *ctx)               \
 {                                                              \
-    CHK_SV;                                                    \
+    if (unlikely(ctx->pr)) {                                   \
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);       \
+        return;                                                \
+    }                                                          \
     if (unlikely(!ctx->tm_enabled)) {                          \
         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);   \
         return;                                                \
@@ -9974,10 +9892,6 @@ GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
 #if defined(TARGET_PPC64)
 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
-GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
-GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
-GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
-GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
 GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
 #endif
 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
@@ -9996,7 +9910,7 @@ GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
 #if defined(TARGET_PPC64)
 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
 #endif
-GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001EF801, PPC_MISC),
+GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC),
 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC),
 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
@@ -10024,16 +9938,13 @@ GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
 GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
 GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
 GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
-GEN_HANDLER2(slbfee_, "slbfee.", 0x1F, 0x13, 0x1E, 0x001F0000, PPC_SEGMENT_64B),
 #endif
 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
-/* XXX Those instructions will need to be handled differently for
- * different ISA versions */
-GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x001F0001, PPC_MEM_TLBIE),
-GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x001F0001, PPC_MEM_TLBIE),
+GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),
+GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE),
 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
 #if defined(TARGET_PPC64)
-GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x031FFC01, PPC_SLBI),
+GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI),
 GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
 #endif
 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
@@ -10330,7 +10241,7 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
 #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
-#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
+#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
 #define GEN_LDS(name, ldop, op, type)                                         \
 GEN_LD(name, ldop, op | 0x20, type)                                           \
@@ -10347,13 +10258,7 @@ GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
 GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
-GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE)
-
-/* HV/P7 and later only */
-GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST)
-GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x18, PPC_CILDST)
-GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
-GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
+GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX)
 #endif
 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
@@ -10369,7 +10274,7 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
 GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
 #define GEN_STUX(name, stop, opc2, opc3, type)                                \
 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
-#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
+#define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
 #define GEN_STS(name, stop, op, type)                                         \
 GEN_ST(name, stop, op | 0x20, type)                                           \
@@ -10383,11 +10288,7 @@ GEN_STS(stw, st32, 0x04, PPC_INTEGER)
 #if defined(TARGET_PPC64)
 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
 GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
-GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE)
-GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST)
-GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
-GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
-GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
+GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX)
 #endif
 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
@@ -11346,9 +11247,8 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                 env->nip, env->lr, env->ctr, cpu_read_xer(env),
                 cs->cpu_index);
     cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
-                TARGET_FMT_lx " iidx %d didx %d\n",
-                env->msr, env->spr[SPR_HID0],
-                env->hflags, env->immu_idx, env->dmmu_idx);
+                TARGET_FMT_lx " idx %d\n", env->msr, env->spr[SPR_HID0],
+                env->hflags, env->mmu_idx);
 #if !defined(NO_TIMER_DUMP)
     cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
 #if !defined(CONFIG_USER_ONLY)
@@ -11408,13 +11308,6 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                 env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
                 env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
 
-#if defined(TARGET_PPC64)
-    if (env->excp_model == POWERPC_EXCP_POWER7 ||
-        env->excp_model == POWERPC_EXCP_POWER8) {
-        cpu_fprintf(f, "HSRR0 " TARGET_FMT_lx " HSRR1 " TARGET_FMT_lx "\n",
-                    env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
-    }
-#endif
     if (env->excp_model == POWERPC_EXCP_BOOKE) {
         cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
                        " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
@@ -11561,44 +11454,36 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
     ctx.exception = POWERPC_EXCP_NONE;
     ctx.spr_cb = env->spr_cb;
     ctx.pr = msr_pr;
-    ctx.mem_idx = env->dmmu_idx;
-    ctx.dr = msr_dr;
-#if !defined(CONFIG_USER_ONLY)
-    ctx.hv = msr_hv || !env->has_hv_mode;
-#endif
+    ctx.hv = !msr_pr && msr_hv;
+    ctx.mem_idx = env->mmu_idx;
     ctx.insns_flags = env->insns_flags;
     ctx.insns_flags2 = env->insns_flags2;
     ctx.access_type = -1;
-    ctx.le_mode = !!(env->hflags & (1 << MSR_LE));
+    ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
     ctx.default_tcg_memop_mask = ctx.le_mode ? MO_LE : MO_BE;
 #if defined(TARGET_PPC64)
     ctx.sf_mode = msr_is_64bit(env, env->msr);
     ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
 #endif
-    if (env->mmu_model == POWERPC_MMU_32B ||
-        env->mmu_model == POWERPC_MMU_601 ||
-        (env->mmu_model & POWERPC_MMU_64B))
-            ctx.lazy_tlb_flush = true;
-
-    ctx.fpu_enabled = !!msr_fp;
+    ctx.fpu_enabled = msr_fp;
     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
-        ctx.spe_enabled = !!msr_spe;
+        ctx.spe_enabled = msr_spe;
     else
-        ctx.spe_enabled = false;
+        ctx.spe_enabled = 0;
     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
-        ctx.altivec_enabled = !!msr_vr;
+        ctx.altivec_enabled = msr_vr;
     else
-        ctx.altivec_enabled = false;
+        ctx.altivec_enabled = 0;
     if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) {
-        ctx.vsx_enabled = !!msr_vsx;
+        ctx.vsx_enabled = msr_vsx;
     } else {
-        ctx.vsx_enabled = false;
+        ctx.vsx_enabled = 0;
     }
 #if defined(TARGET_PPC64)
     if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
-        ctx.tm_enabled = !!msr_tm;
+        ctx.tm_enabled = msr_tm;
     } else {
-        ctx.tm_enabled = false;
+        ctx.tm_enabled = 0;
     }
 #endif
     if ((env->flags & POWERPC_FLAG_SE) && msr_se)
@@ -11733,8 +11618,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
     tb->icount = num_insns;
 
 #if defined(DEBUG_DISAS)
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         int flags;
         flags = env->bfd_mach;
         flags |= ctx.le_mode << 16;
index 7a9b15e..f515725 100644 (file)
@@ -21,7 +21,7 @@
 #include "qemu/osdep.h"
 #include "disas/bfd.h"
 #include "exec/gdbstub.h"
-#include "sysemu/kvm.h"
+#include <sysemu/kvm.h>
 #include "kvm_ppc.h"
 #include "sysemu/arch_init.h"
 #include "sysemu/cpus.h"
 #include "qemu/error-report.h"
 #include "qapi/visitor.h"
 #include "hw/qdev-properties.h"
-#include "hw/ppc/ppc.h"
 
 //#define PPC_DUMP_CPU
 //#define PPC_DEBUG_SPR
 //#define PPC_DUMP_SPR_ACCESSES
 /* #define USE_APPLE_GDB */
 
+/* For user-mode emulation, we don't emulate any IRQ controller */
+#if defined(CONFIG_USER_ONLY)
+#define PPC_IRQ_INIT_FN(name)                                                 \
+static inline void glue(glue(ppc, name),_irq_init) (CPUPPCState *env)         \
+{                                                                             \
+}
+#else
+#define PPC_IRQ_INIT_FN(name)                                                 \
+void glue(glue(ppc, name),_irq_init) (CPUPPCState *env);
+#endif
+
+PPC_IRQ_INIT_FN(40x);
+PPC_IRQ_INIT_FN(6xx);
+PPC_IRQ_INIT_FN(970);
+PPC_IRQ_INIT_FN(POWER7);
+PPC_IRQ_INIT_FN(e500);
+
 /* Generic callbacks:
  * do nothing but store/retrieve spr value
  */
@@ -277,32 +293,6 @@ static void spr_read_purr (DisasContext *ctx, int gprn, int sprn)
 {
     gen_helper_load_purr(cpu_gpr[gprn], cpu_env);
 }
-
-/* HDECR */
-static void spr_read_hdecr(DisasContext *ctx, int gprn, int sprn)
-{
-    if (ctx->tb->cflags & CF_USE_ICOUNT) {
-        gen_io_start();
-    }
-    gen_helper_load_hdecr(cpu_gpr[gprn], cpu_env);
-    if (ctx->tb->cflags & CF_USE_ICOUNT) {
-        gen_io_end();
-        gen_stop_exception(ctx);
-    }
-}
-
-static void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn)
-{
-    if (ctx->tb->cflags & CF_USE_ICOUNT) {
-        gen_io_start();
-    }
-    gen_helper_store_hdecr(cpu_env, cpu_gpr[gprn]);
-    if (ctx->tb->cflags & CF_USE_ICOUNT) {
-        gen_io_end();
-        gen_stop_exception(ctx);
-    }
-}
-
 #endif
 #endif
 
@@ -1205,32 +1195,23 @@ static void gen_spr_amr(CPUPPCState *env, bool has_iamr)
 }
 #endif /* TARGET_PPC64 */
 
-#ifndef CONFIG_USER_ONLY
-static void spr_read_thrm(DisasContext *ctx, int gprn, int sprn)
-{
-    gen_helper_fixup_thrm(cpu_env);
-    gen_load_spr(cpu_gpr[gprn], sprn);
-    spr_load_dump_spr(sprn);
-}
-#endif /* !CONFIG_USER_ONLY */
-
 static void gen_spr_thrm (CPUPPCState *env)
 {
     /* Thermal management */
     /* XXX : not implemented */
     spr_register(env, SPR_THRM1, "THRM1",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_thrm, &spr_write_generic,
+                 &spr_read_generic, &spr_write_generic,
                  0x00000000);
     /* XXX : not implemented */
     spr_register(env, SPR_THRM2, "THRM2",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_thrm, &spr_write_generic,
+                 &spr_read_generic, &spr_write_generic,
                  0x00000000);
     /* XXX : not implemented */
     spr_register(env, SPR_THRM3, "THRM3",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_thrm, &spr_write_generic,
+                 &spr_read_generic, &spr_write_generic,
                  0x00000000);
 }
 
@@ -3206,30 +3187,18 @@ static void init_excp_POWER7 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_HDECR]    = 0x00000980;
     env->excp_vectors[POWERPC_EXCP_SYSCALL]  = 0x00000C00;
     env->excp_vectors[POWERPC_EXCP_TRACE]    = 0x00000D00;
-    env->excp_vectors[POWERPC_EXCP_HDSI]     = 0x00000E00;
-    env->excp_vectors[POWERPC_EXCP_HISI]     = 0x00000E20;
-    env->excp_vectors[POWERPC_EXCP_HV_EMU]   = 0x00000E40;
-    env->excp_vectors[POWERPC_EXCP_HV_MAINT] = 0x00000E60;
     env->excp_vectors[POWERPC_EXCP_PERFM]    = 0x00000F00;
     env->excp_vectors[POWERPC_EXCP_VPU]      = 0x00000F20;
     env->excp_vectors[POWERPC_EXCP_VSXU]     = 0x00000F40;
+    env->excp_vectors[POWERPC_EXCP_FU]       = 0x00000F60;
+    env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
+    env->excp_vectors[POWERPC_EXCP_MAINT]    = 0x00001600;
+    env->excp_vectors[POWERPC_EXCP_VPUA]     = 0x00001700;
+    env->excp_vectors[POWERPC_EXCP_THERM]    = 0x00001800;
     /* Hardware reset vector */
     env->hreset_vector = 0x0000000000000100ULL;
 #endif
 }
-
-static void init_excp_POWER8(CPUPPCState *env)
-{
-    init_excp_POWER7(env);
-
-#if !defined(CONFIG_USER_ONLY)
-    env->excp_vectors[POWERPC_EXCP_SDOOR]    = 0x00000A00;
-    env->excp_vectors[POWERPC_EXCP_FU]       = 0x00000F60;
-    env->excp_vectors[POWERPC_EXCP_HV_FU]    = 0x00000F80;
-    env->excp_vectors[POWERPC_EXCP_SDOOR_HV] = 0x00000E80;
-#endif
-}
-
 #endif
 
 /*****************************************************************************/
@@ -3306,7 +3275,7 @@ static void init_proc_401 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc40x_irq_init(ppc_env_get_cpu(env));
+    ppc40x_irq_init(env);
 
     SET_FIT_PERIOD(12, 16, 20, 24);
     SET_WDT_PERIOD(16, 20, 24, 28);
@@ -3360,7 +3329,7 @@ static void init_proc_401x2 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc40x_irq_init(ppc_env_get_cpu(env));
+    ppc40x_irq_init(env);
 
     SET_FIT_PERIOD(12, 16, 20, 24);
     SET_WDT_PERIOD(16, 20, 24, 28);
@@ -3412,7 +3381,7 @@ static void init_proc_401x3 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc40x_irq_init(ppc_env_get_cpu(env));
+    ppc40x_irq_init(env);
 
     SET_FIT_PERIOD(12, 16, 20, 24);
     SET_WDT_PERIOD(16, 20, 24, 28);
@@ -3471,7 +3440,7 @@ static void init_proc_IOP480 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc40x_irq_init(ppc_env_get_cpu(env));
+    ppc40x_irq_init(env);
 
     SET_FIT_PERIOD(8, 12, 16, 20);
     SET_WDT_PERIOD(16, 20, 24, 28);
@@ -3522,7 +3491,7 @@ static void init_proc_403 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc40x_irq_init(ppc_env_get_cpu(env));
+    ppc40x_irq_init(env);
 
     SET_FIT_PERIOD(8, 12, 16, 20);
     SET_WDT_PERIOD(16, 20, 24, 28);
@@ -3588,7 +3557,7 @@ static void init_proc_403GCX (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc40x_irq_init(ppc_env_get_cpu(env));
+    ppc40x_irq_init(env);
 
     SET_FIT_PERIOD(8, 12, 16, 20);
     SET_WDT_PERIOD(16, 20, 24, 28);
@@ -3654,7 +3623,7 @@ static void init_proc_405 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc40x_irq_init(ppc_env_get_cpu(env));
+    ppc40x_irq_init(env);
 
     SET_FIT_PERIOD(8, 12, 16, 20);
     SET_WDT_PERIOD(16, 20, 24, 28);
@@ -3752,7 +3721,7 @@ static void init_proc_440EP (CPUPPCState *env)
     init_excp_BookE(env);
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
-    ppc40x_irq_init(ppc_env_get_cpu(env));
+    ppc40x_irq_init(env);
 
     SET_FIT_PERIOD(12, 16, 20, 24);
     SET_WDT_PERIOD(20, 24, 28, 32);
@@ -4022,7 +3991,7 @@ static void init_proc_440x5 (CPUPPCState *env)
     init_excp_BookE(env);
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
-    ppc40x_irq_init(ppc_env_get_cpu(env));
+    ppc40x_irq_init(env);
 
     SET_FIT_PERIOD(12, 16, 20, 24);
     SET_WDT_PERIOD(20, 24, 28, 32);
@@ -4444,7 +4413,7 @@ static void init_proc_G2 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
@@ -4523,7 +4492,7 @@ static void init_proc_G2LE (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
@@ -4776,7 +4745,7 @@ static void init_proc_e300 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
@@ -5031,7 +5000,7 @@ static void init_proc_e500 (CPUPPCState *env, int version)
 
     init_excp_e200(env, ivpr_mask);
     /* Allocate hardware IRQ controller */
-    ppce500_irq_init(ppc_env_get_cpu(env));
+    ppce500_irq_init(env);
 }
 
 static void init_proc_e500v1(CPUPPCState *env)
@@ -5133,7 +5102,7 @@ POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
     dc->desc = "e500mc core";
     pcc->init_proc = init_proc_e500mc;
     pcc->check_pow = check_pow_none;
-    pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
+    pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
                        PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
                        PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
@@ -5179,7 +5148,7 @@ POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
     dc->desc = "e5500 core";
     pcc->init_proc = init_proc_e5500;
     pcc->check_pow = check_pow_none;
-    pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
+    pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
                        PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
                        PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
                        PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
@@ -5275,7 +5244,7 @@ static void init_proc_601 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 64;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
@@ -5379,7 +5348,7 @@ static void init_proc_602 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
@@ -5448,7 +5417,7 @@ static void init_proc_603 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
@@ -5514,7 +5483,7 @@ static void init_proc_603E (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
@@ -5574,7 +5543,7 @@ static void init_proc_604 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
@@ -5657,7 +5626,7 @@ static void init_proc_604E (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
@@ -5727,7 +5696,7 @@ static void init_proc_740 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
@@ -5805,7 +5774,7 @@ static void init_proc_750 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
@@ -5968,7 +5937,7 @@ static void init_proc_750cl (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
@@ -6088,7 +6057,7 @@ static void init_proc_750cx (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
@@ -6175,7 +6144,7 @@ static void init_proc_750fx (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
@@ -6262,7 +6231,7 @@ static void init_proc_750gx (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
@@ -6340,7 +6309,7 @@ static void init_proc_745 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
@@ -6426,7 +6395,7 @@ static void init_proc_755 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
@@ -6495,7 +6464,7 @@ static void init_proc_7400 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
@@ -6579,7 +6548,7 @@ static void init_proc_7410 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
@@ -6689,7 +6658,7 @@ static void init_proc_7440 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
@@ -6822,7 +6791,7 @@ static void init_proc_7450 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
@@ -6958,7 +6927,7 @@ static void init_proc_7445 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
@@ -7096,7 +7065,7 @@ static void init_proc_7455 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
@@ -7258,7 +7227,7 @@ static void init_proc_7457 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
@@ -7395,7 +7364,7 @@ static void init_proc_e600 (CPUPPCState *env)
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
-    ppc6xx_irq_init(ppc_env_get_cpu(env));
+    ppc6xx_irq_init(env);
 }
 
 POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
@@ -7551,6 +7520,16 @@ static void gen_spr_970_hior(CPUPPCState *env)
                  0x00000000);
 }
 
+static void gen_spr_970_lpar(CPUPPCState *env)
+{
+    /* Logical partitionning */
+    /* PPC970: HID4 is effectively the LPCR */
+    spr_register(env, SPR_970_HID4, "HID4",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+}
+
 static void gen_spr_book3s_common(CPUPPCState *env)
 {
     spr_register(env, SPR_CTRL, "SPR_CTRL",
@@ -7803,155 +7782,21 @@ static void gen_spr_power5p_ear(CPUPPCState *env)
                  0x00000000);
 }
 
-#if !defined(CONFIG_USER_ONLY)
-static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
-{
-    TCGv hmer = tcg_temp_new();
-
-    gen_load_spr(hmer, sprn);
-    tcg_gen_and_tl(hmer, cpu_gpr[gprn], hmer);
-    gen_store_spr(sprn, hmer);
-    spr_store_dump_spr(sprn);
-    tcg_temp_free(hmer);
-}
-
-static void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn)
-{
-    gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
-}
-
-static void spr_write_970_hid4(DisasContext *ctx, int sprn, int gprn)
-{
-#if defined(TARGET_PPC64)
-    spr_write_generic(ctx, sprn, gprn);
-    gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
-#endif
-}
-
-#endif /* !defined(CONFIG_USER_ONLY) */
-
-static void gen_spr_970_lpar(CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
-    /* Logical partitionning */
-    /* PPC970: HID4 is effectively the LPCR */
-    spr_register(env, SPR_970_HID4, "HID4",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_970_hid4,
-                 0x00000000);
-#endif
-}
-
 static void gen_spr_power5p_lpar(CPUPPCState *env)
 {
-#if !defined(CONFIG_USER_ONLY)
     /* Logical partitionning */
-    spr_register_kvm_hv(env, SPR_LPCR, "LPCR",
-                        SPR_NOACCESS, SPR_NOACCESS,
-                        SPR_NOACCESS, SPR_NOACCESS,
-                        &spr_read_generic, &spr_write_lpcr,
-                        KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1);
-    spr_register_hv(env, SPR_HDEC, "HDEC",
-                    SPR_NOACCESS, SPR_NOACCESS,
-                    SPR_NOACCESS, SPR_NOACCESS,
-                    &spr_read_hdecr, &spr_write_hdecr, 0);
-#endif
+    spr_register_kvm(env, SPR_LPCR, "LPCR",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     KVM_REG_PPC_LPCR, 0x00000000);
 }
 
 static void gen_spr_book3s_ids(CPUPPCState *env)
 {
-    /* FIXME: Will need to deal with thread vs core only SPRs */
-
     /* Processor identification */
-    spr_register_hv(env, SPR_PIR, "PIR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, NULL,
-                 0x00000000);
-    spr_register_hv(env, SPR_HID0, "HID0",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_TSCR, "TSCR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_HMER, "HMER",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_hmer,
-                 0x00000000);
-    spr_register_hv(env, SPR_HMEER, "HMEER",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_TFMR, "TFMR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_LPIDR, "LPIDR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_HFSCR, "HFSCR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_MMCRC, "MMCRC",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_MMCRH, "MMCRH",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_HSPRG0, "HSPRG0",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_HSPRG1, "HSPRG1",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_HSRR0, "HSRR0",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_HSRR1, "HSRR1",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_HDAR, "HDAR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_HDSISR, "HDSISR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_RMOR, "RMOR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    spr_register_hv(env, SPR_HRMOR, "HRMOR",
-                 SPR_NOACCESS, SPR_NOACCESS,
+    spr_register(env, SPR_PIR, "PIR",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, &spr_write_pir,
                  0x00000000);
 }
 
@@ -8195,32 +8040,6 @@ static void gen_spr_power8_book4(CPUPPCState *env)
 #endif
 }
 
-static void gen_spr_power7_book4(CPUPPCState *env)
-{
-    /* Add a number of P7 book4 registers */
-#if !defined(CONFIG_USER_ONLY)
-    spr_register_kvm(env, SPR_ACOP, "ACOP",
-                     SPR_NOACCESS, SPR_NOACCESS,
-                     &spr_read_generic, &spr_write_generic,
-                     KVM_REG_PPC_ACOP, 0);
-    spr_register_kvm(env, SPR_BOOKS_PID, "PID",
-                     SPR_NOACCESS, SPR_NOACCESS,
-                     &spr_read_generic, &spr_write_generic,
-                     KVM_REG_PPC_PID, 0);
-#endif
-}
-
-static void gen_spr_power8_rpr(CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
-    spr_register_hv(env, SPR_RPR, "RPR",
-                    SPR_NOACCESS, SPR_NOACCESS,
-                    SPR_NOACCESS, SPR_NOACCESS,
-                    &spr_read_generic, &spr_write_generic,
-                    0x00000103070F1F3F);
-#endif
-}
-
 static void init_proc_book3s_64(CPUPPCState *env, int version)
 {
     gen_spr_ne_601(env);
@@ -8263,9 +8082,6 @@ static void init_proc_book3s_64(CPUPPCState *env, int version)
         gen_spr_power6_common(env);
         gen_spr_power6_dbg(env);
     }
-    if (version == BOOK3S_CPU_POWER7) {
-        gen_spr_power7_book4(env);
-    }
     if (version >= BOOK3S_CPU_POWER8) {
         gen_spr_power8_tce_address_control(env);
         gen_spr_power8_ids(env);
@@ -8278,7 +8094,6 @@ static void init_proc_book3s_64(CPUPPCState *env, int version)
         gen_spr_vtb(env);
         gen_spr_power8_ic(env);
         gen_spr_power8_book4(env);
-        gen_spr_power8_rpr(env);
     }
     if (version < BOOK3S_CPU_POWER8) {
         gen_spr_book3s_dbg(env);
@@ -8303,15 +8118,12 @@ static void init_proc_book3s_64(CPUPPCState *env, int version)
     case BOOK3S_CPU_970:
     case BOOK3S_CPU_POWER5PLUS:
         init_excp_970(env);
-        ppc970_irq_init(ppc_env_get_cpu(env));
+        ppc970_irq_init(env);
         break;
     case BOOK3S_CPU_POWER7:
-        init_excp_POWER7(env);
-        ppcPOWER7_irq_init(ppc_env_get_cpu(env));
-        break;
     case BOOK3S_CPU_POWER8:
-        init_excp_POWER8(env);
-        ppcPOWER7_irq_init(ppc_env_get_cpu(env));
+        init_excp_POWER7(env);
+        ppcPOWER7_irq_init(env);
         break;
     default:
         g_assert_not_reached();
@@ -8446,8 +8258,8 @@ static void powerpc_get_compat(Object *obj, Visitor *v, const char *name,
     case 0:
         break;
     default:
-        error_report("Internal error: compat is set to %x", *max_compat);
-        abort();
+        error_setg(errp, "Internal error: compat is set to %x",
+                   max_compat ? *max_compat : -1);
         break;
     }
 
@@ -8542,55 +8354,18 @@ static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)
     return false;
 }
 
-static bool cpu_has_work_POWER7(CPUState *cs)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-    CPUPPCState *env = &cpu->env;
-
-    if (cs->halted) {
-        if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
-            return false;
-        }
-        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
-            (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
-            return true;
-        }
-        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
-            (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
-            return true;
-        }
-        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
-            (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
-            return true;
-        }
-        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
-            (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
-            return true;
-        }
-        if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
-            return true;
-        }
-        return false;
-    } else {
-        return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
-    }
-}
-
 POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
     PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-    CPUClass *cc = CPU_CLASS(oc);
 
     dc->fw_name = "PowerPC,POWER7";
     dc->desc = "POWER7";
     dc->props = powerpc_servercpu_properties;
     pcc->pvr_match = ppc_pvr_match_power7;
-    pcc->pcr_mask = PCR_VEC_DIS | PCR_VSX_DIS | PCR_COMPAT_2_05;
-    pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
+    pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06;
     pcc->init_proc = init_proc_POWER7;
     pcc->check_pow = check_pow_nocheck;
-    cc->has_work = cpu_has_work_POWER7;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -8600,15 +8375,13 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-                       PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
+                       PPC_64B | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
-                       PPC_POPCNTB | PPC_POPCNTWD |
-                       PPC_CILDST;
+                       PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
                         PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
-                        PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 |
-                        PPC2_PM_ISA206;
+                        PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64;
     pcc->msr_mask = (1ull << MSR_SF) |
                     (1ull << MSR_VR) |
                     (1ull << MSR_VSX) |
@@ -8661,63 +8434,18 @@ static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)
     return false;
 }
 
-static bool cpu_has_work_POWER8(CPUState *cs)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-    CPUPPCState *env = &cpu->env;
-
-    if (cs->halted) {
-        if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
-            return false;
-        }
-        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
-            (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
-            return true;
-        }
-        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
-            (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
-            return true;
-        }
-        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
-            (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
-            return true;
-        }
-        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
-            (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
-            return true;
-        }
-        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
-            (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
-            return true;
-        }
-        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
-            (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
-            return true;
-        }
-        if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
-            return true;
-        }
-        return false;
-    } else {
-        return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
-    }
-}
-
 POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
     PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-    CPUClass *cc = CPU_CLASS(oc);
 
     dc->fw_name = "PowerPC,POWER8";
     dc->desc = "POWER8";
     dc->props = powerpc_servercpu_properties;
     pcc->pvr_match = ppc_pvr_match_power8;
-    pcc->pcr_mask = PCR_TM_DIS | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
-    pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
+    pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06;
     pcc->init_proc = init_proc_POWER8;
     pcc->check_pow = check_pow_nocheck;
-    cc->has_work = cpu_has_work_POWER8;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -8727,19 +8455,17 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-                       PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
+                       PPC_64B | PPC_64BX | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
-                       PPC_POPCNTB | PPC_POPCNTWD |
-                       PPC_CILDST;
+                       PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
                         PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
                         PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
                         PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
                         PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
-                        PPC2_TM | PPC2_PM_ISA206;
+                        PPC2_TM;
     pcc->msr_mask = (1ull << MSR_SF) |
-                    (1ull << MSR_SHV) |
                     (1ull << MSR_TM) |
                     (1ull << MSR_VR) |
                     (1ull << MSR_VSX) |
@@ -8778,7 +8504,6 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
 void cpu_ppc_set_papr(PowerPCCPU *cpu)
 {
     CPUPPCState *env = &cpu->env;
-    ppc_spr_t *lpcr = &env->spr_cb[SPR_LPCR];
     ppc_spr_t *amor = &env->spr_cb[SPR_AMOR];
 
     /* PAPR always has exception vectors in RAM not ROM. To ensure this,
@@ -8788,41 +8513,9 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)
      */
     env->msr_mask &= ~((1ull << MSR_EP) | MSR_HVB);
 
-    /* Set emulated LPCR to not send interrupts to hypervisor. Note that
-     * under KVM, the actual HW LPCR will be set differently by KVM itself,
-     * the settings below ensure proper operations with TCG in absence of
-     * a real hypervisor.
-     *
-     * Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for
-     * real mode accesses, which thankfully defaults to 0 and isn't
-     * accessible in guest mode.
-     */
-    lpcr->default_value &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV);
-    lpcr->default_value |= LPCR_LPES0 | LPCR_LPES1;
-
-    /* Set RMLS to the max (ie, 16G) */
-    lpcr->default_value &= ~LPCR_RMLS;
-    lpcr->default_value |= 1ull << LPCR_RMLS_SHIFT;
-
-    /* P7 and P8 has slightly different PECE bits, mostly because P8 adds
-     * bit 47 and 48 which are reserved on P7. Here we set them all, which
-     * will work as expected for both implementations
-     */
-    lpcr->default_value |= LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 |
-                           LPCR_P8_PECE3 | LPCR_P8_PECE4;
-
-    /* We should be followed by a CPU reset but update the active value
-     * just in case...
-     */
-    env->spr[SPR_LPCR] = lpcr->default_value;
-
     /* Set a full AMOR so guest can use the AMR as it sees fit */
     env->spr[SPR_AMOR] = amor->default_value = 0xffffffffffffffffull;
 
-    /* Update some env bits based on new LPCR value */
-    ppc_hash64_update_rmls(env);
-    ppc_hash64_update_vrma(env);
-
     /* Tell KVM that we're in PAPR mode */
     if (kvm_enabled()) {
         kvmppc_set_papr(cpu);
@@ -9528,7 +9221,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
     Error *local_err = NULL;
 #if !defined(CONFIG_USER_ONLY)
-    int max_smt = kvmppc_smt_threads();
+    int max_smt = kvm_enabled() ? kvmppc_smt_threads() : 1;
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
@@ -9554,14 +9247,6 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
 #if !defined(CONFIG_USER_ONLY)
     cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
         + (cs->cpu_index % smp_threads);
-
-    if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu->cpu_dt_id)) {
-        error_setg(errp, "Can't create CPU with id %d in KVM", cpu->cpu_dt_id);
-        error_append_hint(errp, "Adjust the number of cpus to %d "
-                          "or try to raise the number of threads per core\n",
-                          cpu->cpu_dt_id * smp_threads / max_smt);
-        return;
-    }
 #endif
 
     if (tcg_enabled()) {
@@ -9817,37 +9502,28 @@ int ppc_get_compat_smt_threads(PowerPCCPU *cpu)
     return ret;
 }
 
-#ifdef TARGET_PPC64
 void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp)
 {
     int ret = 0;
     CPUPPCState *env = &cpu->env;
-    PowerPCCPUClass *host_pcc;
 
     cpu->cpu_version = cpu_version;
 
     switch (cpu_version) {
     case CPU_POWERPC_LOGICAL_2_05:
-        env->spr[SPR_PCR] = PCR_TM_DIS | PCR_VSX_DIS | PCR_COMPAT_2_07 |
-                            PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
+        env->spr[SPR_PCR] = PCR_COMPAT_2_05;
         break;
     case CPU_POWERPC_LOGICAL_2_06:
-    case CPU_POWERPC_LOGICAL_2_06_PLUS:
-        env->spr[SPR_PCR] = PCR_TM_DIS | PCR_COMPAT_2_07 | PCR_COMPAT_2_06;
+        env->spr[SPR_PCR] = PCR_COMPAT_2_06;
         break;
-    case CPU_POWERPC_LOGICAL_2_07:
-        env->spr[SPR_PCR] = PCR_COMPAT_2_07;
+    case CPU_POWERPC_LOGICAL_2_06_PLUS:
+        env->spr[SPR_PCR] = PCR_COMPAT_2_06;
         break;
     default:
         env->spr[SPR_PCR] = 0;
         break;
     }
 
-    host_pcc = kvm_ppc_get_host_cpu_class();
-    if (host_pcc) {
-        env->spr[SPR_PCR] &= host_pcc->pcr_mask;
-    }
-
     if (kvm_enabled()) {
         ret = kvmppc_set_compat(cpu, cpu->cpu_version);
         if (ret < 0) {
@@ -9856,7 +9532,6 @@ void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp)
         }
     }
 }
-#endif
 
 static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
 {
@@ -10012,19 +9687,6 @@ static ObjectClass *ppc_cpu_class_by_name(const char *name)
     return NULL;
 }
 
-const char *ppc_cpu_lookup_alias(const char *alias)
-{
-    int ai;
-
-    for (ai = 0; ppc_cpu_aliases[ai].alias != NULL; ai++) {
-        if (strcmp(ppc_cpu_aliases[ai].alias, alias) == 0) {
-            return ppc_cpu_aliases[ai].model;
-        }
-    }
-
-    return NULL;
-}
-
 PowerPCCPU *cpu_ppc_init(const char *cpu_model)
 {
     return POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, cpu_model));
@@ -10200,7 +9862,10 @@ static void ppc_cpu_reset(CPUState *s)
     pcc->parent_reset(s);
 
     msr = (target_ulong)0;
-    msr |= (target_ulong)MSR_HVB;
+    if (0) {
+        /* XXX: find a suitable condition to enable the hypervisor mode */
+        msr |= (target_ulong)MSR_HVB;
+    }
     msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
     msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
     msr |= (target_ulong)1 << MSR_EP;
@@ -10301,53 +9966,24 @@ static void ppc_cpu_initfn(Object *obj)
     env->bfd_mach = pcc->bfd_mach;
     env->check_pow = pcc->check_pow;
 
-    /* Mark HV mode as supported if the CPU has an MSR_HV bit
-     * in the msr_mask. The mask can later be cleared by PAPR
-     * mode but the hv mode support will remain, thus enforcing
-     * that we cannot use priv. instructions in guest in PAPR
-     * mode. For 970 we currently simply don't set HV in msr_mask
-     * thus simulating an "Apple mode" 970. If we ever want to
-     * support 970 HV mode, we'll have to add a processor attribute
-     * of some sort.
-     */
-#if !defined(CONFIG_USER_ONLY)
-    env->has_hv_mode = !!(env->msr_mask & MSR_HVB);
-#endif
-
 #if defined(TARGET_PPC64)
     if (pcc->sps) {
         env->sps = *pcc->sps;
     } else if (env->mmu_model & POWERPC_MMU_64) {
-        /* Use default sets of page sizes. We don't support MPSS */
-        static const struct ppc_segment_page_sizes defsps_4k = {
-            .sps = {
-                { .page_shift = 12, /* 4K */
-                  .slb_enc = 0,
-                  .enc = { { .page_shift = 12, .pte_enc = 0 } }
-                },
-                { .page_shift = 24, /* 16M */
-                  .slb_enc = 0x100,
-                  .enc = { { .page_shift = 24, .pte_enc = 0 } }
-                },
-            },
-        };
-        static const struct ppc_segment_page_sizes defsps_64k = {
+        /* Use default sets of page sizes */
+        static const struct ppc_segment_page_sizes defsps = {
             .sps = {
                 { .page_shift = 12, /* 4K */
                   .slb_enc = 0,
                   .enc = { { .page_shift = 12, .pte_enc = 0 } }
                 },
-                { .page_shift = 16, /* 64K */
-                  .slb_enc = 0x110,
-                  .enc = { { .page_shift = 16, .pte_enc = 1 } }
-                },
                 { .page_shift = 24, /* 16M */
                   .slb_enc = 0x100,
                   .enc = { { .page_shift = 24, .pte_enc = 0 } }
                 },
             },
         };
-        env->sps = (env->mmu_model & POWERPC_MMU_64K) ? defsps_64k : defsps_4k;
+        env->sps = defsps;
     }
 #endif /* defined(TARGET_PPC64) */
 
index 1cf8551..0d9411b 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 #include "qemu/host-utils.h"
 
index 66b5d18..1c90933 100644 (file)
@@ -21,6 +21,7 @@
 #define QEMU_S390_CPU_QOM_H
 
 #include "qom/cpu.h"
+#include "cpu.h"
 
 #define TYPE_S390_CPU "s390-cpu"
 
@@ -55,6 +56,49 @@ typedef struct S390CPUClass {
     void (*initial_cpu_reset)(CPUState *cpu);
 } S390CPUClass;
 
-typedef struct S390CPU S390CPU;
+/**
+ * S390CPU:
+ * @env: #CPUS390XState.
+ *
+ * An S/390 CPU.
+ */
+typedef struct S390CPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUS390XState env;
+    int64_t id;
+    /* needed for live migration */
+    void *irqstate;
+    uint32_t irqstate_saved_size;
+} S390CPU;
+
+static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
+{
+    return container_of(env, S390CPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(s390_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(S390CPU, env)
+
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_s390_cpu;
+#endif
+
+void s390_cpu_do_interrupt(CPUState *cpu);
+bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
+void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
+int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
+                              int cpuid, void *opaque);
+
+hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+hwaddr s390_cpu_get_phys_addr_debug(CPUState *cpu, vaddr addr);
+int s390_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int s390_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+void s390_cpu_gdb_init(CPUState *cs);
+void s390x_cpu_debug_excp_handler(CPUState *cs);
 
 #endif
index e43e2d6..4bfff34 100644 (file)
 #include "qemu/cutils.h"
 #include "qemu/timer.h"
 #include "qemu/error-report.h"
+#include "hw/hw.h"
 #include "trace.h"
 #include "qapi/visitor.h"
-#include "migration/vmstate.h"
-#include "exec/exec-all.h"
 #ifndef CONFIG_USER_ONLY
-#include "hw/hw.h"
 #include "sysemu/arch_init.h"
 #include "sysemu/sysemu.h"
 #include "hw/s390x/sclp.h"
index c216bda..6d97c08 100644 (file)
  * You should have received a copy of the GNU (Lesser) General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-
-#ifndef S390X_CPU_H
-#define S390X_CPU_H
+#ifndef CPU_S390X_H
+#define CPU_S390X_H
 
 #include "qemu-common.h"
-#include "cpu-qom.h"
 
 #define TARGET_LONG_BITS 64
 
@@ -137,8 +135,6 @@ typedef struct CPUS390XState {
     uint64_t gbea;
     uint64_t pp;
 
-    uint8_t riccb[64];
-
     CPU_COMMON
 
     /* reset does memset(0) up to here */
@@ -175,52 +171,8 @@ static inline CPU_DoubleU *get_freg(CPUS390XState *cs, int nr)
     return &cs->vregs[nr][0];
 }
 
-/**
- * S390CPU:
- * @env: #CPUS390XState.
- *
- * An S/390 CPU.
- */
-struct S390CPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPUS390XState env;
-    int64_t id;
-    /* needed for live migration */
-    void *irqstate;
-    uint32_t irqstate_saved_size;
-};
-
-static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
-{
-    return container_of(env, S390CPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(s390_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(S390CPU, env)
-
-#ifndef CONFIG_USER_ONLY
-extern const struct VMStateDescription vmstate_s390_cpu;
-#endif
-
-void s390_cpu_do_interrupt(CPUState *cpu);
-bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
-void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
-                         int flags);
-int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
-                              int cpuid, void *opaque);
-
-hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-hwaddr s390_cpu_get_phys_addr_debug(CPUState *cpu, vaddr addr);
-int s390_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int s390_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-void s390_cpu_gdb_init(CPUState *cs);
-void s390x_cpu_debug_excp_handler(CPUState *cs);
-
-#include "sysemu/kvm.h"
+#include "cpu-qom.h"
+#include <sysemu/kvm.h>
 
 /* distinguish between 24 bit and 31 bit addressing */
 #define HIGH_ORDER_BIT 0x80000000
@@ -386,7 +338,7 @@ static inline uint64_t cpu_mmu_idx_to_asc(int mmu_idx)
 }
 
 static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *pc = env->psw.addr;
     *cs_base = 0;
@@ -464,6 +416,7 @@ S390CPU *cpu_s390x_init(const char *cpu_model);
 S390CPU *s390x_new_cpu(const char *cpu_model, int64_t id, Error **errp);
 S390CPU *cpu_s390x_create(const char *cpu_model, Error **errp);
 void s390x_translate_init(void);
+int cpu_s390x_exec(CPUState *cpu);
 
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
@@ -473,6 +426,8 @@ int cpu_s390x_signal_handler(int host_signum, void *pinfo,
 int s390_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
                               int mmu_idx);
 
+#include "ioinst.h"
+
 
 #ifndef CONFIG_USER_ONLY
 void do_restart_interrupt(CPUS390XState *env);
@@ -583,26 +538,6 @@ static inline uint8_t s390_cpu_get_state(S390CPU *cpu)
 void gtod_save(QEMUFile *f, void *opaque);
 int gtod_load(QEMUFile *f, void *opaque, int version_id);
 
-void cpu_inject_ext(S390CPU *cpu, uint32_t code, uint32_t param,
-                    uint64_t param64);
-
-/* ioinst.c */
-void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1);
-void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1);
-void ioinst_handle_hsch(S390CPU *cpu, uint64_t reg1);
-void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
-void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
-void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb);
-void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
-int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
-void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb);
-int ioinst_handle_tpi(S390CPU *cpu, uint32_t ipb);
-void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2,
-                        uint32_t ipb);
-void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1);
-void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1);
-void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1);
-
 /* service interrupts are floating therefore we must not pass an cpustate */
 void s390_sclp_extint(uint32_t parm);
 
@@ -624,14 +559,45 @@ static inline unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
 void cpu_lock(void);
 void cpu_unlock(void);
 
+typedef struct SubchDev SubchDev;
+
+#ifndef CONFIG_USER_ONLY
 extern void subsystem_reset(void);
+SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid,
+                         uint16_t schid);
+bool css_subch_visible(SubchDev *sch);
+void css_conditional_io_interrupt(SubchDev *sch);
+int css_do_stsch(SubchDev *sch, SCHIB *schib);
+bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid);
+int css_do_msch(SubchDev *sch, const SCHIB *schib);
+int css_do_xsch(SubchDev *sch);
+int css_do_csch(SubchDev *sch);
+int css_do_hsch(SubchDev *sch);
+int css_do_ssch(SubchDev *sch, ORB *orb);
+int css_do_tsch_get_irb(SubchDev *sch, IRB *irb, int *irb_len);
+void css_do_tsch_update_subch(SubchDev *sch);
+int css_do_stcrw(CRW *crw);
+void css_undo_stcrw(CRW *crw);
+int css_do_tpi(IOIntCode *int_code, int lowcore);
+int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid,
+                         int rfmt, void *buf);
+void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo);
+int css_enable_mcsse(void);
+int css_enable_mss(void);
+int css_do_rsch(SubchDev *sch);
+int css_do_rchp(uint8_t cssid, uint8_t chpid);
+bool css_present(uint8_t cssid);
+#endif
 
 #define cpu_init(model) CPU(cpu_s390x_init(model))
+#define cpu_exec cpu_s390x_exec
 #define cpu_signal_handler cpu_s390x_signal_handler
 
 void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 #define cpu_list s390_cpu_list
 
+#include "exec/exec-all.h"
+
 #define EXCP_EXT 1 /* external interrupt */
 #define EXCP_SVC 2 /* supervisor call (syscall) */
 #define EXCP_PGM 3 /* program interruption */
@@ -1096,6 +1062,69 @@ static inline uint64_t tod2time(uint64_t t) {
     return (t * 125) >> 9;
 }
 
+static inline void cpu_inject_ext(S390CPU *cpu, uint32_t code, uint32_t param,
+                                  uint64_t param64)
+{
+    CPUS390XState *env = &cpu->env;
+
+    if (env->ext_index == MAX_EXT_QUEUE - 1) {
+        /* ugh - can't queue anymore. Let's drop. */
+        return;
+    }
+
+    env->ext_index++;
+    assert(env->ext_index < MAX_EXT_QUEUE);
+
+    env->ext_queue[env->ext_index].code = code;
+    env->ext_queue[env->ext_index].param = param;
+    env->ext_queue[env->ext_index].param64 = param64;
+
+    env->pending_int |= INTERRUPT_EXT;
+    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+}
+
+static inline void cpu_inject_io(S390CPU *cpu, uint16_t subchannel_id,
+                                 uint16_t subchannel_number,
+                                 uint32_t io_int_parm, uint32_t io_int_word)
+{
+    CPUS390XState *env = &cpu->env;
+    int isc = IO_INT_WORD_ISC(io_int_word);
+
+    if (env->io_index[isc] == MAX_IO_QUEUE - 1) {
+        /* ugh - can't queue anymore. Let's drop. */
+        return;
+    }
+
+    env->io_index[isc]++;
+    assert(env->io_index[isc] < MAX_IO_QUEUE);
+
+    env->io_queue[env->io_index[isc]][isc].id = subchannel_id;
+    env->io_queue[env->io_index[isc]][isc].nr = subchannel_number;
+    env->io_queue[env->io_index[isc]][isc].parm = io_int_parm;
+    env->io_queue[env->io_index[isc]][isc].word = io_int_word;
+
+    env->pending_int |= INTERRUPT_IO;
+    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+}
+
+static inline void cpu_inject_crw_mchk(S390CPU *cpu)
+{
+    CPUS390XState *env = &cpu->env;
+
+    if (env->mchk_index == MAX_MCHK_QUEUE - 1) {
+        /* ugh - can't queue anymore. Let's drop. */
+        return;
+    }
+
+    env->mchk_index++;
+    assert(env->mchk_index < MAX_MCHK_QUEUE);
+
+    env->mchk_queue[env->mchk_index].type = 1;
+
+    env->pending_int |= INTERRUPT_MCHK;
+    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+}
+
 /* from s390-virtio-ccw */
 #define MEM_SECTION_SIZE             0x10000000UL
 #define MAX_AVAIL_SLOTS              32
@@ -1130,7 +1159,6 @@ void kvm_s390_reset_vcpu(S390CPU *cpu);
 int kvm_s390_set_mem_limit(KVMState *s, uint64_t new_limit, uint64_t *hw_limit);
 void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu);
 int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu);
-int kvm_s390_get_ri(void);
 void kvm_s390_crypto_reset(void);
 #else
 static inline void kvm_s390_io_interrupt(uint16_t subchannel_id,
@@ -1181,10 +1209,6 @@ static inline int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu)
 {
     return 0;
 }
-static inline int kvm_s390_get_ri(void)
-{
-    return 0;
-}
 static inline void kvm_s390_crypto_reset(void)
 {
 }
@@ -1240,6 +1264,21 @@ static inline void s390_crypto_reset(void)
     }
 }
 
+#ifdef CONFIG_KVM
+static inline bool vregs_needed(void *opaque)
+{
+    if (kvm_enabled()) {
+        return kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS);
+    }
+    return 0;
+}
+#else
+static inline bool vregs_needed(void *opaque)
+{
+    return 0;
+}
+#endif
+
 /* machine check interruption code */
 
 /* subclasses */
index e604e9f..1c7f673 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "exec/helper-proto.h"
 
@@ -267,7 +266,7 @@ uint64_t HELPER(ldeb)(CPUS390XState *env, uint64_t f2)
 {
     float64 ret = float32_to_float64(f2, &env->fpu_status);
     handle_exceptions(env, GETPC());
-    return float64_maybe_silence_nan(ret, &env->fpu_status);
+    return float64_maybe_silence_nan(ret);
 }
 
 /* convert 128-bit float to 64-bit float */
@@ -275,7 +274,7 @@ uint64_t HELPER(ldxb)(CPUS390XState *env, uint64_t ah, uint64_t al)
 {
     float64 ret = float128_to_float64(make_float128(ah, al), &env->fpu_status);
     handle_exceptions(env, GETPC());
-    return float64_maybe_silence_nan(ret, &env->fpu_status);
+    return float64_maybe_silence_nan(ret);
 }
 
 /* convert 64-bit float to 128-bit float */
@@ -283,7 +282,7 @@ uint64_t HELPER(lxdb)(CPUS390XState *env, uint64_t f2)
 {
     float128 ret = float64_to_float128(f2, &env->fpu_status);
     handle_exceptions(env, GETPC());
-    return RET128(float128_maybe_silence_nan(ret, &env->fpu_status));
+    return RET128(float128_maybe_silence_nan(ret));
 }
 
 /* convert 32-bit float to 128-bit float */
@@ -291,7 +290,7 @@ uint64_t HELPER(lxeb)(CPUS390XState *env, uint64_t f2)
 {
     float128 ret = float32_to_float128(f2, &env->fpu_status);
     handle_exceptions(env, GETPC());
-    return RET128(float128_maybe_silence_nan(ret, &env->fpu_status));
+    return RET128(float128_maybe_silence_nan(ret));
 }
 
 /* convert 64-bit float to 32-bit float */
@@ -299,7 +298,7 @@ uint64_t HELPER(ledb)(CPUS390XState *env, uint64_t f2)
 {
     float32 ret = float64_to_float32(f2, &env->fpu_status);
     handle_exceptions(env, GETPC());
-    return float32_maybe_silence_nan(ret, &env->fpu_status);
+    return float32_maybe_silence_nan(ret);
 }
 
 /* convert 128-bit float to 32-bit float */
@@ -307,7 +306,7 @@ uint64_t HELPER(lexb)(CPUS390XState *env, uint64_t ah, uint64_t al)
 {
     float32 ret = float128_to_float32(make_float128(ah, al), &env->fpu_status);
     handle_exceptions(env, GETPC());
-    return float32_maybe_silence_nan(ret, &env->fpu_status);
+    return float32_maybe_silence_nan(ret);
 }
 
 /* 32-bit FP compare */
@@ -624,7 +623,7 @@ uint64_t HELPER(msdb)(CPUS390XState *env, uint64_t f1,
 }
 
 /* test data class 32-bit */
-uint32_t HELPER(tceb)(CPUS390XState *env, uint64_t f1, uint64_t m2)
+uint32_t HELPER(tceb)(uint64_t f1, uint64_t m2)
 {
     float32 v1 = f1;
     int neg = float32_is_neg(v1);
@@ -633,8 +632,7 @@ uint32_t HELPER(tceb)(CPUS390XState *env, uint64_t f1, uint64_t m2)
     if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
         (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
         (float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
-        (float32_is_signaling_nan(v1, &env->fpu_status) &&
-         (m2 & (1 << (1-neg))))) {
+        (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
         cc = 1;
     } else if (m2 & (1 << (9-neg))) {
         /* assume normalized number */
@@ -645,7 +643,7 @@ uint32_t HELPER(tceb)(CPUS390XState *env, uint64_t f1, uint64_t m2)
 }
 
 /* test data class 64-bit */
-uint32_t HELPER(tcdb)(CPUS390XState *env, uint64_t v1, uint64_t m2)
+uint32_t HELPER(tcdb)(uint64_t v1, uint64_t m2)
 {
     int neg = float64_is_neg(v1);
     uint32_t cc = 0;
@@ -653,8 +651,7 @@ uint32_t HELPER(tcdb)(CPUS390XState *env, uint64_t v1, uint64_t m2)
     if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
         (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
         (float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
-        (float64_is_signaling_nan(v1, &env->fpu_status) &&
-         (m2 & (1 << (1-neg))))) {
+        (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
         cc = 1;
     } else if (m2 & (1 << (9-neg))) {
         /* assume normalized number */
@@ -665,8 +662,7 @@ uint32_t HELPER(tcdb)(CPUS390XState *env, uint64_t v1, uint64_t m2)
 }
 
 /* test data class 128-bit */
-uint32_t HELPER(tcxb)(CPUS390XState *env, uint64_t ah,
-                      uint64_t al, uint64_t m2)
+uint32_t HELPER(tcxb)(uint64_t ah, uint64_t al, uint64_t m2)
 {
     float128 v1 = make_float128(ah, al);
     int neg = float128_is_neg(v1);
@@ -675,8 +671,7 @@ uint32_t HELPER(tcxb)(CPUS390XState *env, uint64_t ah,
     if ((float128_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
         (float128_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
         (float128_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
-        (float128_is_signaling_nan(v1, &env->fpu_status) &&
-         (m2 & (1 << (1-neg))))) {
+        (float128_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
         cc = 1;
     } else if (m2 & (1 << (9-neg))) {
         /* assume normalized number */
index 3d223de..9fc36cb 100644 (file)
@@ -19,8 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/gdbstub.h"
 #include "qemu/bitops.h"
 
index 54a5177..92abe7e 100644 (file)
@@ -23,9 +23,7 @@
 #include "cpu.h"
 #include "exec/gdbstub.h"
 #include "qemu/timer.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
-#include "hw/s390x/ioinst.h"
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/sysemu.h"
 #endif
@@ -70,7 +68,11 @@ void s390x_cpu_timer(void *opaque)
 
 S390CPU *cpu_s390x_create(const char *cpu_model, Error **errp)
 {
-    return S390_CPU(object_new(TYPE_S390_CPU));
+    S390CPU *cpu;
+
+    cpu = S390_CPU(object_new(TYPE_S390_CPU));
+
+    return cpu;
 }
 
 S390CPU *s390x_new_cpu(const char *cpu_model, int64_t id, Error **errp)
@@ -684,7 +686,7 @@ void s390x_cpu_debug_excp_handler(CPUState *cs)
            will be triggered, it will call load_psw which will recompute
            the watchpoints.  */
         cpu_watchpoint_remove_all(cs, BP_CPU);
-        cpu_loop_exit_noexc(cs);
+        cpu_resume_from_signal(cs, NULL);
     }
 }
 #endif /* CONFIG_USER_ONLY */
index 207a6e7..7e06119 100644 (file)
@@ -67,9 +67,9 @@ DEF_HELPER_FLAGS_4(maeb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
 DEF_HELPER_FLAGS_4(madb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
 DEF_HELPER_FLAGS_4(mseb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
 DEF_HELPER_FLAGS_4(msdb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
-DEF_HELPER_FLAGS_3(tceb, TCG_CALL_NO_RWG_SE, i32, env, i64, i64)
-DEF_HELPER_FLAGS_3(tcdb, TCG_CALL_NO_RWG_SE, i32, env, i64, i64)
-DEF_HELPER_FLAGS_4(tcxb, TCG_CALL_NO_RWG_SE, i32, env, i64, i64, i64)
+DEF_HELPER_FLAGS_2(tceb, TCG_CALL_NO_RWG_SE, i32, i64, i64)
+DEF_HELPER_FLAGS_2(tcdb, TCG_CALL_NO_RWG_SE, i32, i64, i64)
+DEF_HELPER_FLAGS_3(tcxb, TCG_CALL_NO_RWG_SE, i32, i64, i64, i64)
 DEF_HELPER_FLAGS_1(clz, TCG_CALL_NO_RWG_SE, i64, i64)
 DEF_HELPER_FLAGS_2(sqeb, TCG_CALL_NO_WG, i64, env, i64)
 DEF_HELPER_FLAGS_2(sqdb, TCG_CALL_NO_WG, i64, env, i64)
index 370c94d..cc1071e 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
 
index 9edef96..bad60a7 100644 (file)
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "sysemu/kvm.h"
-#include "hw/s390x/ioinst.h"
-
-#if !defined(CONFIG_USER_ONLY)
-void cpu_inject_ext(S390CPU *cpu, uint32_t code, uint32_t param,
-                    uint64_t param64)
-{
-    CPUS390XState *env = &cpu->env;
-
-    if (env->ext_index == MAX_EXT_QUEUE - 1) {
-        /* ugh - can't queue anymore. Let's drop. */
-        return;
-    }
-
-    env->ext_index++;
-    assert(env->ext_index < MAX_EXT_QUEUE);
-
-    env->ext_queue[env->ext_index].code = code;
-    env->ext_queue[env->ext_index].param = param;
-    env->ext_queue[env->ext_index].param64 = param64;
-
-    env->pending_int |= INTERRUPT_EXT;
-    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
-}
-
-static void cpu_inject_io(S390CPU *cpu, uint16_t subchannel_id,
-                          uint16_t subchannel_number,
-                          uint32_t io_int_parm, uint32_t io_int_word)
-{
-    CPUS390XState *env = &cpu->env;
-    int isc = IO_INT_WORD_ISC(io_int_word);
-
-    if (env->io_index[isc] == MAX_IO_QUEUE - 1) {
-        /* ugh - can't queue anymore. Let's drop. */
-        return;
-    }
-
-    env->io_index[isc]++;
-    assert(env->io_index[isc] < MAX_IO_QUEUE);
-
-    env->io_queue[env->io_index[isc]][isc].id = subchannel_id;
-    env->io_queue[env->io_index[isc]][isc].nr = subchannel_number;
-    env->io_queue[env->io_index[isc]][isc].parm = io_int_parm;
-    env->io_queue[env->io_index[isc]][isc].word = io_int_word;
-
-    env->pending_int |= INTERRUPT_IO;
-    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
-}
-
-static void cpu_inject_crw_mchk(S390CPU *cpu)
-{
-    CPUS390XState *env = &cpu->env;
-
-    if (env->mchk_index == MAX_MCHK_QUEUE - 1) {
-        /* ugh - can't queue anymore. Let's drop. */
-        return;
-    }
-
-    env->mchk_index++;
-    assert(env->mchk_index < MAX_MCHK_QUEUE);
-
-    env->mchk_queue[env->mchk_index].type = 1;
-
-    env->pending_int |= INTERRUPT_MCHK;
-    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
-}
 
 /*
  * All of the following interrupts are floating, i.e. not per-vcpu.
  * We just need a dummy cpustate in order to be able to inject in the
  * non-kvm case.
  */
+#if !defined(CONFIG_USER_ONLY)
 void s390_sclp_extint(uint32_t parm)
 {
     if (kvm_enabled()) {
index a5a288b..142ff93 100644 (file)
@@ -12,7 +12,7 @@
 #include "qemu/osdep.h"
 
 #include "cpu.h"
-#include "hw/s390x/ioinst.h"
+#include "ioinst.h"
 #include "trace.h"
 #include "hw/s390x/s390-pci-bus.h"
 
@@ -509,7 +509,6 @@ static void ioinst_handle_chsc_scsc(ChscReq *req, ChscResp *res)
 
     general_chars[0] = cpu_to_be32(0x03000000);
     general_chars[1] = cpu_to_be32(0x00059000);
-    general_chars[3] = cpu_to_be32(0x00080000);
 
     chsc_chars[0] = cpu_to_be32(0x40000000);
     chsc_chars[3] = cpu_to_be32(0x00040000);
similarity index 87%
rename from include/hw/s390x/ioinst.h
rename to target-s390x/ioinst.h
index c559f53..013cc91 100644 (file)
@@ -9,9 +9,8 @@
  * directory.
 */
 
-#ifndef S390X_IOINST_H
-#define S390X_IOINST_H
-
+#ifndef IOINST_S390X_H
+#define IOINST_S390X_H
 /*
  * Channel I/O related definitions, as defined in the Principles
  * Of Operation (and taken from the Linux implementation).
@@ -228,5 +227,20 @@ typedef struct IOIntCode {
 
 int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
                                  int *schid);
+void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1);
+void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1);
+void ioinst_handle_hsch(S390CPU *cpu, uint64_t reg1);
+void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
+void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
+void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb);
+void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
+int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb);
+void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb);
+int ioinst_handle_tpi(S390CPU *cpu, uint32_t ipb);
+void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2,
+                        uint32_t ipb);
+void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1);
+void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1);
+void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1);
 
 #endif
index 80ac621..e1859ca 100644 (file)
 
 #include "qemu/osdep.h"
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 
 #include <linux/kvm.h>
 #include <asm/ptrace.h>
 
 #include "qemu-common.h"
-#include "cpu.h"
 #include "qemu/error-report.h"
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
 #include "hw/hw.h"
+#include "cpu.h"
 #include "sysemu/device_tree.h"
 #include "qapi/qmp/qjson.h"
 #include "exec/gdbstub.h"
@@ -45,7 +46,6 @@
 #include "hw/s390x/ipl.h"
 #include "hw/s390x/ebcdic.h"
 #include "exec/memattrs.h"
-#include "hw/s390x/s390-virtio-ccw.h"
 
 /* #define DEBUG_KVM */
 
@@ -135,7 +135,6 @@ static int cap_sync_regs;
 static int cap_async_pf;
 static int cap_mem_op;
 static int cap_s390_irq;
-static int cap_ri;
 
 static void *legacy_s390_alloc(size_t size, uint64_t *align);
 
@@ -271,11 +270,6 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
     kvm_vm_enable_cap(s, KVM_CAP_S390_USER_SIGP, 0);
     kvm_vm_enable_cap(s, KVM_CAP_S390_VECTOR_REGISTERS, 0);
     kvm_vm_enable_cap(s, KVM_CAP_S390_USER_STSI, 0);
-    if (ri_allowed()) {
-        if (kvm_vm_enable_cap(s, KVM_CAP_S390_RI, 0) == 0) {
-            cap_ri = 1;
-        }
-    }
 
     return 0;
 }
@@ -392,11 +386,6 @@ int kvm_arch_put_registers(CPUState *cs, int level)
         kvm_set_one_reg(cs, KVM_REG_S390_PP, &env->pp);
     }
 
-    if (can_sync_regs(cs, KVM_SYNC_RICCB)) {
-        memcpy(cs->kvm_run->s.regs.riccb, env->riccb, 64);
-        cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_RICCB;
-    }
-
     /* pfault parameters */
     if (can_sync_regs(cs, KVM_SYNC_PFAULT)) {
         cs->kvm_run->s.regs.pft = env->pfault_token;
@@ -539,10 +528,6 @@ int kvm_arch_get_registers(CPUState *cs)
         kvm_get_one_reg(cs, KVM_REG_S390_PP, &env->pp);
     }
 
-    if (can_sync_regs(cs, KVM_SYNC_RICCB)) {
-        memcpy(env->riccb, cs->kvm_run->s.regs.riccb, 64);
-    }
-
     /* pfault parameters */
     if (can_sync_regs(cs, KVM_SYNC_PFAULT)) {
         env->pfault_token = cs->kvm_run->s.regs.pft;
@@ -2070,9 +2055,8 @@ void kvm_s390_io_interrupt(uint16_t subchannel_id,
     if (io_int_word & IO_INT_WORD_AI) {
         irq.type = KVM_S390_INT_IO(1, 0, 0, 0);
     } else {
-        irq.type = KVM_S390_INT_IO(0, (subchannel_id & 0xff00) >> 8,
-                                      (subchannel_id & 0x0006),
-                                      subchannel_nr);
+        irq.type = ((subchannel_id & 0xff00) << 24) |
+            ((subchannel_id & 0x00060) << 22) | (subchannel_nr << 16);
     }
     kvm_s390_floating_interrupt(&irq);
 }
@@ -2152,11 +2136,6 @@ int kvm_s390_get_memslot_count(KVMState *s)
     return kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
 }
 
-int kvm_s390_get_ri(void)
-{
-    return cap_ri;
-}
-
 int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state)
 {
     struct kvm_mp_state mp_state = {};
@@ -2246,10 +2225,10 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
                              uint64_t address, uint32_t data, PCIDevice *dev)
 {
     S390PCIBusDevice *pbdev;
-    uint32_t idx = data >> ZPCI_MSI_VEC_BITS;
+    uint32_t fid = data >> ZPCI_MSI_VEC_BITS;
     uint32_t vec = data & ZPCI_MSI_VEC_MASK;
 
-    pbdev = s390_pci_find_dev_by_idx(idx);
+    pbdev = s390_pci_find_dev_by_fid(fid);
     if (!pbdev) {
         DPRINTF("add_msi_route no dev\n");
         return -ENODEV;
@@ -2267,17 +2246,6 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
     return 0;
 }
 
-int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
-                                int vector, PCIDevice *dev)
-{
-    return 0;
-}
-
-int kvm_arch_release_virq_post(int virq)
-{
-    return 0;
-}
-
 int kvm_arch_msi_data_to_gsi(uint32_t data)
 {
     abort();
index aa39e5d..6b26090 100644 (file)
@@ -76,16 +76,6 @@ static const VMStateDescription vmstate_fpu = {
     }
 };
 
-static bool vregs_needed(void *opaque)
-{
-#ifdef CONFIG_KVM
-    if (kvm_enabled()) {
-        return kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS);
-    }
-#endif
-    return 0;
-}
-
 static const VMStateDescription vmstate_vregs = {
     .name = "cpu/vregs",
     .version_id = 1,
@@ -145,27 +135,6 @@ static const VMStateDescription vmstate_vregs = {
     }
 };
 
-static bool riccb_needed(void *opaque)
-{
-#ifdef CONFIG_KVM
-    if (kvm_enabled()) {
-        return kvm_s390_get_ri();
-    }
-#endif
-    return 0;
-}
-
-const VMStateDescription vmstate_riccb = {
-    .name = "cpu/riccb",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .needed = riccb_needed,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT8_ARRAY(env.riccb, S390CPU, 64),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
 const VMStateDescription vmstate_s390_cpu = {
     .name = "cpu",
     .post_load = cpu_post_load,
@@ -197,7 +166,6 @@ const VMStateDescription vmstate_s390_cpu = {
     .subsections = (const VMStateDescription*[]) {
         &vmstate_fpu,
         &vmstate_vregs,
-        &vmstate_riccb,
         NULL
     },
 };
index 99bc5e2..7078622 100644 (file)
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
-
-#if !defined(CONFIG_USER_ONLY)
 #include "hw/s390x/storage-keys.h"
-#endif
 
 /*****************************************************************************/
 /* Softmmu support */
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr)
 {
     int ret;
 
-    ret = s390_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = s390_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (unlikely(ret != 0)) {
         if (likely(retaddr)) {
             /* now we have a real cpu fault */
index 86da194..71cbe34 100644 (file)
 #ifdef CONFIG_KVM
 #include <linux/kvm.h>
 #endif
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
+#include "hw/watchdog/wdt_diag288.h"
 
 #if !defined(CONFIG_USER_ONLY)
-#include "hw/watchdog/wdt_diag288.h"
 #include "sysemu/cpus.h"
 #include "sysemu/sysemu.h"
 #include "hw/s390x/ebcdic.h"
@@ -233,23 +232,10 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
             program_interrupt(env, PGM_ADDRESSING, ILEN_LATER_INC);
             return;
         }
-        iplb = g_malloc0(sizeof(IplParameterBlock));
-        cpu_physical_memory_read(addr, iplb, sizeof(iplb->len));
-        if (!iplb_valid_len(iplb)) {
-            env->regs[r1 + 1] = DIAG_308_RC_INVALID;
-            goto out;
-        }
-
-        cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
-
-        if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) {
-            env->regs[r1 + 1] = DIAG_308_RC_INVALID;
-            goto out;
-        }
-
+        iplb = g_malloc0(sizeof(struct IplParameterBlock));
+        cpu_physical_memory_read(addr, iplb, sizeof(struct IplParameterBlock));
         s390_ipl_update_diag308(iplb);
         env->regs[r1 + 1] = DIAG_308_RC_OK;
-out:
         g_free(iplb);
         return;
     case 6:
@@ -264,7 +250,8 @@ out:
         }
         iplb = s390_ipl_get_iplb();
         if (iplb) {
-            cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len));
+            cpu_physical_memory_write(addr, iplb,
+                                      sizeof(struct IplParameterBlock));
             env->regs[r1 + 1] = DIAG_308_RC_OK;
         } else {
             env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;
diff --git a/target-s390x/trace-events b/target-s390x/trace-events
deleted file mode 100644 (file)
index df59f5f..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# target-s390x/mmu_helper.c
-get_skeys_nonzero(int rc) "SKEY: Call to get_skeys unexpectedly returned %d"
-set_skeys_nonzero(int rc) "SKEY: Call to set_skeys unexpectedly returned %d"
-
-# target-s390x/ioinst.c
-ioinst(const char *insn) "IOINST: %s"
-ioinst_sch_id(const char *insn, int cssid, int ssid, int schid) "IOINST: %s (%x.%x.%04x)"
-ioinst_chp_id(const char *insn, int cssid, int chpid) "IOINST: %s (%x.%02x)"
-ioinst_chsc_cmd(uint16_t cmd, uint16_t len) "IOINST: chsc command %04x, len %04x"
-
-# target-s390x/kvm.c
-kvm_enable_cmma(int rc) "CMMA: enabling with result code %d"
-kvm_clear_cmma(int rc) "CMMA: clearing with result code %d"
-kvm_failed_cpu_state_set(int cpu_index, uint8_t state, const char *msg) "Warning: Unable to set cpu %d state %" PRIu8 " to KVM: %s"
-kvm_sigp_finished(uint8_t order, int cpu_index, int dst_index, int cc) "SIGP: Finished order %u on cpu %d -> cpu %d with cc=%d"
-
-# target-s390x/cpu.c
-cpu_set_state(int cpu_index, uint8_t state) "setting cpu %d state to %" PRIu8
-cpu_halt(int cpu_index) "halting cpu %d"
-cpu_unhalt(int cpu_index) "unhalting cpu %d"
index 1a07d70..c871ef2 100644 (file)
@@ -31,7 +31,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "qemu/log.h"
 #include "qemu/host-utils.h"
@@ -169,7 +168,6 @@ void s390x_translate_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
     psw_addr = tcg_global_mem_new_i64(cpu_env,
                                       offsetof(CPUS390XState, psw.addr),
                                       "psw_addr");
@@ -610,17 +608,12 @@ static void gen_op_calc_cc(DisasContext *s)
 
 static int use_goto_tb(DisasContext *s, uint64_t dest)
 {
-    if (unlikely(s->singlestep_enabled) ||
-        (s->tb->cflags & CF_LAST_IO) ||
-        (s->tb->flags & FLAG_MASK_PER)) {
-        return false;
-    }
-#ifndef CONFIG_USER_ONLY
-    return (dest & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) ||
-           (dest & TARGET_PAGE_MASK) == (s->pc & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
+    /* NOTE: we handle the case where the TB spans two pages here */
+    return (((dest & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK)
+             || (dest & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))
+            && !s->singlestep_enabled
+            && !(s->tb->cflags & CF_LAST_IO)
+            && !(s->tb->flags & FLAG_MASK_PER));
 }
 
 static void account_noninline_branch(DisasContext *s, int cc_op)
@@ -3986,21 +3979,21 @@ static ExitStatus op_svc(DisasContext *s, DisasOps *o)
 
 static ExitStatus op_tceb(DisasContext *s, DisasOps *o)
 {
-    gen_helper_tceb(cc_op, cpu_env, o->in1, o->in2);
+    gen_helper_tceb(cc_op, o->in1, o->in2);
     set_cc_static(s);
     return NO_EXIT;
 }
 
 static ExitStatus op_tcdb(DisasContext *s, DisasOps *o)
 {
-    gen_helper_tcdb(cc_op, cpu_env, o->in1, o->in2);
+    gen_helper_tcdb(cc_op, o->in1, o->in2);
     set_cc_static(s);
     return NO_EXIT;
 }
 
 static ExitStatus op_tcxb(DisasContext *s, DisasOps *o)
 {
-    gen_helper_tcxb(cc_op, cpu_env, o->out, o->out2, o->in2);
+    gen_helper_tcxb(cc_op, o->out, o->out2, o->in2);
     set_cc_static(s);
     return NO_EXIT;
 }
@@ -5430,8 +5423,7 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
     tb->icount = num_insns;
 
 #if defined(S390X_DEBUG_DISAS)
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
         log_target_disas(cs, pc_start, dc.pc - pc_start, 1);
         qemu_log("\n");
index 01abb20..6341238 100644 (file)
@@ -60,6 +60,35 @@ typedef struct SuperHCPUClass {
     uint32_t cvr;
 } SuperHCPUClass;
 
-typedef struct SuperHCPU SuperHCPU;
+/**
+ * SuperHCPU:
+ * @env: #CPUSH4State
+ *
+ * A SuperH CPU.
+ */
+typedef struct SuperHCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUSH4State env;
+} SuperHCPU;
+
+static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env)
+{
+    return container_of(env, SuperHCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(sh_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(SuperHCPU, env)
+
+void superh_cpu_do_interrupt(CPUState *cpu);
+bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
+void superh_cpu_dump_state(CPUState *cpu, FILE *f,
+                           fprintf_function cpu_fprintf, int flags);
+hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int superh_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int superh_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
index f589532..86ba388 100644 (file)
@@ -24,7 +24,6 @@
 #include "cpu.h"
 #include "qemu-common.h"
 #include "migration/vmstate.h"
-#include "exec/exec-all.h"
 
 
 static void superh_cpu_set_pc(CPUState *cs, vaddr value)
@@ -71,7 +70,6 @@ static void superh_cpu_reset(CPUState *s)
     set_flush_to_zero(1, &env->fp_status);
 #endif
     set_default_nan_mode(1, &env->fp_status);
-    set_snan_bit_is_one(1, &env->fp_status);
 }
 
 static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
index 478ab55..3b23e96 100644 (file)
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-
-#ifndef SH4_CPU_H
-#define SH4_CPU_H
+#ifndef _CPU_SH4_H
+#define _CPU_SH4_H
 
 #include "qemu-common.h"
-#include "cpu-qom.h"
 
 #define TARGET_LONG_BITS 32
 
@@ -189,39 +187,11 @@ typedef struct CPUSH4State {
     memory_content **movcal_backup_tail;
 } CPUSH4State;
 
-/**
- * SuperHCPU:
- * @env: #CPUSH4State
- *
- * A SuperH CPU.
- */
-struct SuperHCPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPUSH4State env;
-};
-
-static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env)
-{
-    return container_of(env, SuperHCPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(sh_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(SuperHCPU, env)
-
-void superh_cpu_do_interrupt(CPUState *cpu);
-bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
-void superh_cpu_dump_state(CPUState *cpu, FILE *f,
-                           fprintf_function cpu_fprintf, int flags);
-hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-int superh_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int superh_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+#include "cpu-qom.h"
 
 void sh4_translate_init(void);
 SuperHCPU *cpu_sh4_init(const char *cpu_model);
+int cpu_sh4_exec(CPUState *s);
 int cpu_sh4_signal_handler(int host_signum, void *pinfo,
                            void *puc);
 int superh_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
@@ -254,6 +224,7 @@ void cpu_load_tlb(CPUSH4State * env);
 
 #define cpu_init(cpu_model) CPU(cpu_sh4_init(cpu_model))
 
+#define cpu_exec cpu_sh4_exec
 #define cpu_signal_handler cpu_sh4_signal_handler
 #define cpu_list sh4_cpu_list
 
@@ -376,7 +347,7 @@ static inline void cpu_write_sr(CPUSH4State *env, target_ulong sr)
 }
 
 static inline void cpu_get_tb_cpu_state(CPUSH4State *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *pc = env->pc;
     *cs_base = 0;
@@ -388,4 +359,6 @@ static inline void cpu_get_tb_cpu_state(CPUSH4State *env, target_ulong *pc,
             | (env->movcal_backup ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 4 */
 }
 
-#endif /* SH4_CPU_H */
+#include "exec/exec-all.h"
+
+#endif                         /* _CPU_SH4_H */
index 13bea00..1b59ea8 100644 (file)
@@ -19,7 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
 
 /* Hint: Use "set architecture sh4" in GDB to see fpu registers */
index a33ac69..6438338 100644 (file)
@@ -19,7 +19,6 @@
 #include "qemu/osdep.h"
 
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/log.h"
 
 #if !defined(CONFIG_USER_ONLY)
index 684d3f3..368e687 100644 (file)
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 #ifndef CONFIG_USER_ONLY
 
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr)
 {
     int ret;
 
-    ret = superh_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = superh_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (ret) {
         /* now we have a real cpu fault */
         if (retaddr) {
@@ -109,8 +108,7 @@ void helper_movcal(CPUSH4State *env, uint32_t address, uint32_t value)
 {
     if (cpu_sh4_is_cached (env, address))
     {
-        memory_content *r = g_new(memory_content, 1);
-
+       memory_content *r = malloc (sizeof(memory_content));
        r->address = address;
        r->value = value;
        r->next = NULL;
@@ -127,7 +125,7 @@ void helper_discard_movcal_backup(CPUSH4State *env)
     while(current)
     {
        memory_content *next = current->next;
-        g_free(current);
+       free (current);
        env->movcal_backup = current = next;
        if (current == NULL)
            env->movcal_backup_tail = &(env->movcal_backup);
@@ -150,7 +148,7 @@ void helper_ocbi(CPUSH4State *env, uint32_t address)
                env->movcal_backup_tail = current;
            }
 
-            g_free(*current);
+           free (*current);
            *current = next;
            break;
        }
index ca80cf7..7c18968 100644 (file)
@@ -22,7 +22,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "exec/cpu_ldst.h"
 
@@ -101,7 +100,6 @@ void sh4_translate_init(void)
         return;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
 
     for (i = 0; i < 24; i++)
         cpu_gregs[i] = tcg_global_mem_new_i32(cpu_env,
@@ -207,26 +205,17 @@ static void gen_write_sr(TCGv src)
     tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
 }
 
-static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
+static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
 {
-    if (unlikely(ctx->singlestep_enabled)) {
-        return false;
-    }
-
-#ifndef CONFIG_USER_ONLY
-    return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
+    TranslationBlock *tb;
+    tb = ctx->tb;
 
-static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
-{
-    if (use_goto_tb(ctx, dest)) {
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
+       !ctx->singlestep_enabled) {
        /* Use a direct jump if in same page and singlestep not enabled */
         tcg_gen_goto_tb(n);
         tcg_gen_movi_i32(cpu_pc, dest);
-        tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_i32(cpu_pc, dest);
         if (ctx->singlestep_enabled)
@@ -1925,8 +1914,7 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
     tb->icount = num_insns;
 
 #ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
        qemu_log("IN:\n");      /* , lookup_symbol(pc_start)); */
         log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
        qemu_log("\n");
diff --git a/target-sparc/asi.h b/target-sparc/asi.h
deleted file mode 100644 (file)
index c9a1849..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-#ifndef _SPARC_ASI_H
-#define _SPARC_ASI_H
-
-/* asi.h:  Address Space Identifier values for the sparc.
- *
- * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
- *
- * Pioneer work for sun4m: Paul Hatchman (paul@sfe.com.au)
- * Joint edition for sun4c+sun4m: Pete A. Zaitcev <zaitcev@ipmce.su>
- */
-
-/* The first batch are for the sun4c. */
-
-#define ASI_NULL1           0x00
-#define ASI_NULL2           0x01
-
-/* sun4c and sun4 control registers and mmu/vac ops */
-#define ASI_CONTROL         0x02
-#define ASI_SEGMAP          0x03
-#define ASI_PTE             0x04
-#define ASI_HWFLUSHSEG      0x05
-#define ASI_HWFLUSHPAGE     0x06
-#define ASI_REGMAP          0x06
-#define ASI_HWFLUSHCONTEXT  0x07
-
-#define ASI_USERTXT         0x08
-#define ASI_KERNELTXT       0x09
-#define ASI_USERDATA        0x0a
-#define ASI_KERNELDATA      0x0b
-
-/* VAC Cache flushing on sun4c and sun4 */
-#define ASI_FLUSHSEG        0x0c
-#define ASI_FLUSHPG         0x0d
-#define ASI_FLUSHCTX        0x0e
-
-/* SPARCstation-5: only 6 bits are decoded. */
-/* wo = Write Only, rw = Read Write;        */
-/* ss = Single Size, as = All Sizes;        */
-#define ASI_M_RES00         0x00   /* Don't touch... */
-#define ASI_M_UNA01         0x01   /* Same here... */
-#define ASI_M_MXCC          0x02   /* Access to TI VIKING MXCC registers */
-#define ASI_M_FLUSH_PROBE   0x03   /* Reference MMU Flush/Probe; rw, ss */
-#define ASI_M_MMUREGS       0x04   /* MMU Registers; rw, ss */
-#define ASI_M_TLBDIAG       0x05   /* MMU TLB only Diagnostics */
-#define ASI_M_DIAGS         0x06   /* Reference MMU Diagnostics */
-#define ASI_M_IODIAG        0x07   /* MMU I/O TLB only Diagnostics */
-#define ASI_M_USERTXT       0x08   /* Same as ASI_USERTXT; rw, as */
-#define ASI_M_KERNELTXT     0x09   /* Same as ASI_KERNELTXT; rw, as */
-#define ASI_M_USERDATA      0x0A   /* Same as ASI_USERDATA; rw, as */
-#define ASI_M_KERNELDATA    0x0B   /* Same as ASI_KERNELDATA; rw, as */
-#define ASI_M_TXTC_TAG      0x0C   /* Instruction Cache Tag; rw, ss */
-#define ASI_M_TXTC_DATA     0x0D   /* Instruction Cache Data; rw, ss */
-#define ASI_M_DATAC_TAG     0x0E   /* Data Cache Tag; rw, ss */
-#define ASI_M_DATAC_DATA    0x0F   /* Data Cache Data; rw, ss */
-
-/* The following cache flushing ASIs work only with the 'sta'
- * instruction. Results are unpredictable for 'swap' and 'ldstuba',
- * so don't do it.
- */
-
-/* These ASI flushes affect external caches too. */
-#define ASI_M_FLUSH_PAGE    0x10   /* Flush I&D Cache Line (page); wo, ss */
-#define ASI_M_FLUSH_SEG     0x11   /* Flush I&D Cache Line (seg); wo, ss */
-#define ASI_M_FLUSH_REGION  0x12   /* Flush I&D Cache Line (region); wo, ss */
-#define ASI_M_FLUSH_CTX     0x13   /* Flush I&D Cache Line (context); wo, ss */
-#define ASI_M_FLUSH_USER    0x14   /* Flush I&D Cache Line (user); wo, ss */
-
-/* Block-copy operations are available only on certain V8 cpus. */
-#define ASI_M_BCOPY         0x17   /* Block copy */
-
-/* These affect only the ICACHE and are Ross HyperSparc and TurboSparc specific. */
-#define ASI_M_IFLUSH_PAGE   0x18   /* Flush I Cache Line (page); wo, ss */
-#define ASI_M_IFLUSH_SEG    0x19   /* Flush I Cache Line (seg); wo, ss */
-#define ASI_M_IFLUSH_REGION 0x1A   /* Flush I Cache Line (region); wo, ss */
-#define ASI_M_IFLUSH_CTX    0x1B   /* Flush I Cache Line (context); wo, ss */
-#define ASI_M_IFLUSH_USER   0x1C   /* Flush I Cache Line (user); wo, ss */
-
-/* Block-fill operations are available on certain V8 cpus */
-#define ASI_M_BFILL         0x1F
-
-/* This allows direct access to main memory, actually 0x20 to 0x2f are
- * the available ASI's for physical ram pass-through, but I don't have
- * any idea what the other ones do....
- */
-
-#define ASI_M_BYPASS       0x20   /* Reference MMU bypass; rw, as */
-#define ASI_M_FBMEM        0x29   /* Graphics card frame buffer access */
-#define ASI_M_VMEUS        0x2A   /* VME user 16-bit access */
-#define ASI_M_VMEPS        0x2B   /* VME priv 16-bit access */
-#define ASI_M_VMEUT        0x2C   /* VME user 32-bit access */
-#define ASI_M_VMEPT        0x2D   /* VME priv 32-bit access */
-#define ASI_M_SBUS         0x2E   /* Direct SBus access */
-#define ASI_M_CTL          0x2F   /* Control Space (ECC and MXCC are here) */
-
-
-/* This is ROSS HyperSparc only. */
-#define ASI_M_FLUSH_IWHOLE 0x31   /* Flush entire ICACHE; wo, ss */
-
-/* Tsunami/Viking/TurboSparc i/d cache flash clear. */
-#define ASI_M_IC_FLCLEAR   0x36
-#define ASI_M_DC_FLCLEAR   0x37
-
-#define ASI_M_DCDR         0x39   /* Data Cache Diagnostics Register rw, ss */
-
-#define ASI_M_VIKING_TMP1  0x40          /* Emulation temporary 1 on Viking */
-/* only available on SuperSparc I */
-/* #define ASI_M_VIKING_TMP2  0x41 */  /* Emulation temporary 2 on Viking */
-
-#define ASI_M_ACTION       0x4c   /* Breakpoint Action Register (GNU/Viking) */
-
-/* LEON ASI */
-#define ASI_LEON_NOCACHE        0x01
-
-#define ASI_LEON_DCACHE_MISS    0x01
-
-#define ASI_LEON_CACHEREGS      0x02
-#define ASI_LEON_IFLUSH         0x10
-#define ASI_LEON_DFLUSH         0x11
-
-#define ASI_LEON_MMUFLUSH       0x18
-#define ASI_LEON_MMUREGS        0x19
-#define ASI_LEON_BYPASS         0x1c
-#define ASI_LEON_FLUSH_PAGE     0x10
-
-/* V9 Architecture mandary ASIs. */
-#define ASI_N                  0x04 /* Nucleus                         */
-#define ASI_NL                 0x0c /* Nucleus, little endian          */
-#define ASI_AIUP               0x10 /* Primary, user                   */
-#define ASI_AIUS               0x11 /* Secondary, user                 */
-#define ASI_AIUPL              0x18 /* Primary, user, little endian    */
-#define ASI_AIUSL              0x19 /* Secondary, user, little endian  */
-#define ASI_P                  0x80 /* Primary, implicit               */
-#define ASI_S                  0x81 /* Secondary, implicit             */
-#define ASI_PNF                        0x82 /* Primary, no fault               */
-#define ASI_SNF                        0x83 /* Secondary, no fault             */
-#define ASI_PL                 0x88 /* Primary, implicit, l-endian     */
-#define ASI_SL                 0x89 /* Secondary, implicit, l-endian   */
-#define ASI_PNFL               0x8a /* Primary, no fault, l-endian     */
-#define ASI_SNFL               0x8b /* Secondary, no fault, l-endian   */
-
-/* SpitFire and later extended ASIs.  The "(III)" marker designates
- * UltraSparc-III and later specific ASIs.  The "(CMT)" marker designates
- * Chip Multi Threading specific ASIs.  "(NG)" designates Niagara specific
- * ASIs, "(4V)" designates SUN4V specific ASIs.  "(NG4)" designates SPARC-T4
- * and later ASIs.
- */
-#define ASI_REAL                0x14 /* Real address, cachable          */
-#define ASI_PHYS_USE_EC                0x14 /* PADDR, E-cachable               */
-#define ASI_REAL_IO             0x15 /* Real address, non-cachable      */
-#define ASI_PHYS_BYPASS_EC_E   0x15 /* PADDR, E-bit                    */
-#define ASI_BLK_AIUP_4V                0x16 /* (4V) Prim, user, block ld/st    */
-#define ASI_BLK_AIUS_4V                0x17 /* (4V) Sec, user, block ld/st     */
-#define ASI_REAL_L              0x1c /* Real address, cachable, LE      */
-#define ASI_PHYS_USE_EC_L      0x1c /* PADDR, E-cachable, little endian*/
-#define ASI_REAL_IO_L           0x1d /* Real address, non-cachable, LE  */
-#define ASI_PHYS_BYPASS_EC_E_L 0x1d /* PADDR, E-bit, little endian     */
-#define ASI_BLK_AIUP_L_4V      0x1e /* (4V) Prim, user, block, l-endian*/
-#define ASI_BLK_AIUS_L_4V      0x1f /* (4V) Sec, user, block, l-endian */
-#define ASI_SCRATCHPAD         0x20 /* (4V) Scratch Pad Registers      */
-#define ASI_MMU                        0x21 /* (4V) MMU Context Registers      */
-#define ASI_TWINX_AIUP          0x22 /* twin load, primary user         */
-#define ASI_TWINX_AIUS          0x23 /* twin load, secondary user       */
-#define ASI_BLK_INIT_QUAD_LDD_AIUS 0x23 /* (NG) init-store, twin load,
-                                        * secondary, user
-                                        */
-#define ASI_NUCLEUS_QUAD_LDD   0x24 /* Cachable, qword load            */
-#define ASI_QUEUE              0x25 /* (4V) Interrupt Queue Registers  */
-#define ASI_TWINX_REAL          0x26 /* twin load, real, cachable       */
-#define ASI_QUAD_LDD_PHYS_4V   0x26 /* (4V) Physical, qword load       */
-#define ASI_TWINX_N             0x27 /* twin load, nucleus              */
-#define ASI_TWINX_AIUP_L        0x2a /* twin load, primary user, LE     */
-#define ASI_TWINX_AIUS_L        0x2b /* twin load, secondary user, LE   */
-#define ASI_NUCLEUS_QUAD_LDD_L 0x2c /* Cachable, qword load, l-endian  */
-#define ASI_TWINX_REAL_L        0x2e /* twin load, real, cachable, LE   */
-#define ASI_QUAD_LDD_PHYS_L_4V 0x2e /* (4V) Phys, qword load, l-endian */
-#define ASI_TWINX_NL            0x2f /* twin load, nucleus, LE          */
-#define ASI_PCACHE_DATA_STATUS 0x30 /* (III) PCache data stat RAM diag */
-#define ASI_PCACHE_DATA                0x31 /* (III) PCache data RAM diag      */
-#define ASI_PCACHE_TAG         0x32 /* (III) PCache tag RAM diag       */
-#define ASI_PCACHE_SNOOP_TAG   0x33 /* (III) PCache snoop tag RAM diag */
-#define ASI_QUAD_LDD_PHYS      0x34 /* (III+) PADDR, qword load        */
-#define ASI_WCACHE_VALID_BITS  0x38 /* (III) WCache Valid Bits diag    */
-#define ASI_WCACHE_DATA                0x39 /* (III) WCache data RAM diag      */
-#define ASI_WCACHE_TAG         0x3a /* (III) WCache tag RAM diag       */
-#define ASI_WCACHE_SNOOP_TAG   0x3b /* (III) WCache snoop tag RAM diag */
-#define ASI_QUAD_LDD_PHYS_L    0x3c /* (III+) PADDR, qw-load, l-endian */
-#define ASI_SRAM_FAST_INIT     0x40 /* (III+) Fast SRAM init           */
-#define ASI_CORE_AVAILABLE     0x41 /* (CMT) LP Available              */
-#define ASI_CORE_ENABLE_STAT   0x41 /* (CMT) LP Enable Status          */
-#define ASI_CORE_ENABLE                0x41 /* (CMT) LP Enable RW              */
-#define ASI_XIR_STEERING       0x41 /* (CMT) XIR Steering RW           */
-#define ASI_CORE_RUNNING_RW    0x41 /* (CMT) LP Running RW             */
-#define ASI_CORE_RUNNING_W1S   0x41 /* (CMT) LP Running Write-One Set  */
-#define ASI_CORE_RUNNING_W1C   0x41 /* (CMT) LP Running Write-One Clr  */
-#define ASI_CORE_RUNNING_STAT  0x41 /* (CMT) LP Running Status         */
-#define ASI_CMT_ERROR_STEERING 0x41 /* (CMT) Error Steering RW         */
-#define ASI_DCACHE_INVALIDATE  0x42 /* (III) DCache Invalidate diag    */
-#define ASI_DCACHE_UTAG                0x43 /* (III) DCache uTag diag          */
-#define ASI_DCACHE_SNOOP_TAG   0x44 /* (III) DCache snoop tag RAM diag */
-#define ASI_LSU_CONTROL                0x45 /* Load-store control unit         */
-#define ASI_DCU_CONTROL_REG    0x45 /* (III) DCache Unit Control reg   */
-#define ASI_DCACHE_DATA                0x46 /* DCache data-ram diag access     */
-#define ASI_DCACHE_TAG         0x47 /* Dcache tag/valid ram diag access*/
-#define ASI_INTR_DISPATCH_STAT 0x48 /* IRQ vector dispatch status      */
-#define ASI_INTR_RECEIVE       0x49 /* IRQ vector receive status       */
-#define ASI_UPA_CONFIG         0x4a /* UPA config space                */
-#define ASI_JBUS_CONFIG                0x4a /* (IIIi) JBUS Config Register     */
-#define ASI_SAFARI_CONFIG      0x4a /* (III) Safari Config Register    */
-#define ASI_SAFARI_ADDRESS     0x4a /* (III) Safari Address Register   */
-#define ASI_ESTATE_ERROR_EN    0x4b /* E-cache error enable space      */
-#define ASI_AFSR               0x4c /* Async fault status register     */
-#define ASI_AFAR               0x4d /* Async fault address register    */
-#define ASI_EC_TAG_DATA                0x4e /* E-cache tag/valid ram diag acc  */
-#define ASI_IMMU               0x50 /* Insn-MMU main register space    */
-#define ASI_IMMU_TSB_8KB_PTR   0x51 /* Insn-MMU 8KB TSB pointer reg    */
-#define ASI_IMMU_TSB_64KB_PTR  0x52 /* Insn-MMU 64KB TSB pointer reg   */
-#define ASI_ITLB_DATA_IN       0x54 /* Insn-MMU TLB data in reg        */
-#define ASI_ITLB_DATA_ACCESS   0x55 /* Insn-MMU TLB data access reg    */
-#define ASI_ITLB_TAG_READ      0x56 /* Insn-MMU TLB tag read reg       */
-#define ASI_IMMU_DEMAP         0x57 /* Insn-MMU TLB demap              */
-#define ASI_DMMU               0x58 /* Data-MMU main register space    */
-#define ASI_DMMU_TSB_8KB_PTR   0x59 /* Data-MMU 8KB TSB pointer reg    */
-#define ASI_DMMU_TSB_64KB_PTR  0x5a /* Data-MMU 16KB TSB pointer reg   */
-#define ASI_DMMU_TSB_DIRECT_PTR        0x5b /* Data-MMU TSB direct pointer reg */
-#define ASI_DTLB_DATA_IN       0x5c /* Data-MMU TLB data in reg        */
-#define ASI_DTLB_DATA_ACCESS   0x5d /* Data-MMU TLB data access reg    */
-#define ASI_DTLB_TAG_READ      0x5e /* Data-MMU TLB tag read reg       */
-#define ASI_DMMU_DEMAP         0x5f /* Data-MMU TLB demap              */
-#define ASI_IIU_INST_TRAP      0x60 /* (III) Instruction Breakpoint    */
-#define ASI_INTR_ID            0x63 /* (CMT) Interrupt ID register     */
-#define ASI_CORE_ID            0x63 /* (CMT) LP ID register            */
-#define ASI_CESR_ID            0x63 /* (CMT) CESR ID register          */
-#define ASI_IC_INSTR           0x66 /* Insn cache instrucion ram diag  */
-#define ASI_IC_TAG             0x67 /* Insn cache tag/valid ram diag   */
-#define ASI_IC_STAG            0x68 /* (III) Insn cache snoop tag ram  */
-#define ASI_IC_PRE_DECODE      0x6e /* Insn cache pre-decode ram diag  */
-#define ASI_IC_NEXT_FIELD      0x6f /* Insn cache next-field ram diag  */
-#define ASI_BRPRED_ARRAY       0x6f /* (III) Branch Prediction RAM diag*/
-#define ASI_BLK_AIUP           0x70 /* Primary, user, block load/store */
-#define ASI_BLK_AIUS           0x71 /* Secondary, user, block ld/st    */
-#define ASI_MCU_CTRL_REG       0x72 /* (III) Memory controller regs    */
-#define ASI_EC_DATA            0x74 /* (III) E-cache data staging reg  */
-#define ASI_EC_CTRL            0x75 /* (III) E-cache control reg       */
-#define ASI_EC_W               0x76 /* E-cache diag write access       */
-#define ASI_UDB_ERROR_W                0x77 /* External UDB error regs W       */
-#define ASI_UDB_CONTROL_W      0x77 /* External UDB control regs W     */
-#define ASI_INTR_W             0x77 /* IRQ vector dispatch write       */
-#define ASI_INTR_DATAN_W       0x77 /* (III) Out irq vector data reg N */
-#define ASI_INTR_DISPATCH_W    0x77 /* (III) Interrupt vector dispatch */
-#define ASI_BLK_AIUPL          0x78 /* Primary, user, little, blk ld/st*/
-#define ASI_BLK_AIUSL          0x79 /* Secondary, user, little, blk ld/st*/
-#define ASI_EC_R               0x7e /* E-cache diag read access        */
-#define ASI_UDBH_ERROR_R       0x7f /* External UDB error regs rd hi   */
-#define ASI_UDBL_ERROR_R       0x7f /* External UDB error regs rd low  */
-#define ASI_UDBH_CONTROL_R     0x7f /* External UDB control regs rd hi */
-#define ASI_UDBL_CONTROL_R     0x7f /* External UDB control regs rd low*/
-#define ASI_INTR_R             0x7f /* IRQ vector dispatch read        */
-#define ASI_INTR_DATAN_R       0x7f /* (III) In irq vector data reg N  */
-#define ASI_PIC                        0xb0 /* (NG4) PIC registers             */
-#define ASI_PST8_P             0xc0 /* Primary, 8 8-bit, partial       */
-#define ASI_PST8_S             0xc1 /* Secondary, 8 8-bit, partial     */
-#define ASI_PST16_P            0xc2 /* Primary, 4 16-bit, partial      */
-#define ASI_PST16_S            0xc3 /* Secondary, 4 16-bit, partial    */
-#define ASI_PST32_P            0xc4 /* Primary, 2 32-bit, partial      */
-#define ASI_PST32_S            0xc5 /* Secondary, 2 32-bit, partial    */
-#define ASI_PST8_PL            0xc8 /* Primary, 8 8-bit, partial, L    */
-#define ASI_PST8_SL            0xc9 /* Secondary, 8 8-bit, partial, L  */
-#define ASI_PST16_PL           0xca /* Primary, 4 16-bit, partial, L   */
-#define ASI_PST16_SL           0xcb /* Secondary, 4 16-bit, partial, L */
-#define ASI_PST32_PL           0xcc /* Primary, 2 32-bit, partial, L   */
-#define ASI_PST32_SL           0xcd /* Secondary, 2 32-bit, partial, L */
-#define ASI_FL8_P              0xd0 /* Primary, 1 8-bit, fpu ld/st     */
-#define ASI_FL8_S              0xd1 /* Secondary, 1 8-bit, fpu ld/st   */
-#define ASI_FL16_P             0xd2 /* Primary, 1 16-bit, fpu ld/st    */
-#define ASI_FL16_S             0xd3 /* Secondary, 1 16-bit, fpu ld/st  */
-#define ASI_FL8_PL             0xd8 /* Primary, 1 8-bit, fpu ld/st, L  */
-#define ASI_FL8_SL             0xd9 /* Secondary, 1 8-bit, fpu ld/st, L*/
-#define ASI_FL16_PL            0xda /* Primary, 1 16-bit, fpu ld/st, L */
-#define ASI_FL16_SL            0xdb /* Secondary, 1 16-bit, fpu ld/st,L*/
-#define ASI_BLK_COMMIT_P       0xe0 /* Primary, blk store commit       */
-#define ASI_BLK_COMMIT_S       0xe1 /* Secondary, blk store commit     */
-#define ASI_TWINX_P             0xe2 /* twin load, primary implicit     */
-#define ASI_BLK_INIT_QUAD_LDD_P        0xe2 /* (NG) init-store, twin load,
-                                     * primary, implicit */
-#define ASI_TWINX_S             0xe3 /* twin load, secondary implicit   */
-#define ASI_BLK_INIT_QUAD_LDD_S        0xe3 /* (NG) init-store, twin load,
-                                     * secondary, implicit */
-#define ASI_TWINX_PL            0xea /* twin load, primary implicit, LE */
-#define ASI_TWINX_SL            0xeb /* twin load, secondary implicit, LE */
-#define ASI_BLK_P              0xf0 /* Primary, blk ld/st              */
-#define ASI_BLK_S              0xf1 /* Secondary, blk ld/st            */
-#define ASI_ST_BLKINIT_MRU_P   0xf2 /* (NG4) init-store, twin load,
-                                     * Most-Recently-Used, primary,
-                                     * implicit
-                                     */
-#define ASI_ST_BLKINIT_MRU_S   0xf2 /* (NG4) init-store, twin load,
-                                     * Most-Recently-Used, secondary,
-                                     * implicit
-                                     */
-#define ASI_BLK_PL             0xf8 /* Primary, blk ld/st, little      */
-#define ASI_BLK_SL             0xf9 /* Secondary, blk ld/st, little    */
-#define ASI_ST_BLKINIT_MRU_PL  0xfa /* (NG4) init-store, twin load,
-                                     * Most-Recently-Used, primary,
-                                     * implicit, little-endian
-                                     */
-#define ASI_ST_BLKINIT_MRU_SL  0xfb /* (NG4) init-store, twin load,
-                                     * Most-Recently-Used, secondary,
-                                     * implicit, little-endian
-                                     */
-
-#endif /* _SPARC_ASI_H */
index a410a0b..44c4409 100644 (file)
@@ -200,7 +200,10 @@ static uint32_t compute_all_addx_xcc(CPUSPARCState *env)
 
 static uint32_t compute_C_addx_xcc(CPUSPARCState *env)
 {
-    return get_C_addx_xcc(CC_DST, CC_SRC, CC_SRC2);
+    uint32_t ret;
+
+    ret = get_C_addx_xcc(CC_DST, CC_SRC, CC_SRC2);
+    return ret;
 }
 #endif
 
@@ -216,7 +219,10 @@ static uint32_t compute_all_addx(CPUSPARCState *env)
 
 static uint32_t compute_C_addx(CPUSPARCState *env)
 {
-    return get_C_addx_icc(CC_DST, CC_SRC, CC_SRC2);
+    uint32_t ret;
+
+    ret = get_C_addx_icc(CC_DST, CC_SRC, CC_SRC2);
+    return ret;
 }
 
 static inline uint32_t get_V_tag_icc(target_ulong src1, target_ulong src2)
@@ -359,7 +365,10 @@ static uint32_t compute_all_subx_xcc(CPUSPARCState *env)
 
 static uint32_t compute_C_subx_xcc(CPUSPARCState *env)
 {
-    return get_C_subx_xcc(CC_DST, CC_SRC, CC_SRC2);
+    uint32_t ret;
+
+    ret = get_C_subx_xcc(CC_DST, CC_SRC, CC_SRC2);
+    return ret;
 }
 #endif
 
@@ -375,7 +384,10 @@ static uint32_t compute_all_subx(CPUSPARCState *env)
 
 static uint32_t compute_C_subx(CPUSPARCState *env)
 {
-    return get_C_subx_icc(CC_DST, CC_SRC, CC_SRC2);
+    uint32_t ret;
+
+    ret = get_C_subx_icc(CC_DST, CC_SRC, CC_SRC2);
+    return ret;
 }
 
 static uint32_t compute_all_tsub(CPUSPARCState *env)
@@ -467,5 +479,8 @@ void helper_compute_psr(CPUSPARCState *env)
 
 uint32_t helper_compute_C_icc(CPUSPARCState *env)
 {
-    return icc_table[CC_OP].compute_c(env) >> PSR_CARRY_SHIFT;
+    uint32_t ret;
+
+    ret = icc_table[CC_OP].compute_c(env) >> PSR_CARRY_SHIFT;
+    return ret;
 }
index f63af72..5096b10 100644 (file)
@@ -21,6 +21,7 @@
 #define QEMU_SPARC_CPU_QOM_H
 
 #include "qom/cpu.h"
+#include "cpu.h"
 
 #ifdef TARGET_SPARC64
 #define TYPE_SPARC_CPU "sparc64-cpu"
@@ -51,6 +52,41 @@ typedef struct SPARCCPUClass {
     void (*parent_reset)(CPUState *cpu);
 } SPARCCPUClass;
 
-typedef struct SPARCCPU SPARCCPU;
+/**
+ * SPARCCPU:
+ * @env: #CPUSPARCState
+ *
+ * A SPARC CPU.
+ */
+typedef struct SPARCCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUSPARCState env;
+} SPARCCPU;
+
+static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
+{
+    return container_of(env, SPARCCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(sparc_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(SPARCCPU, env)
+
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_sparc_cpu;
+#endif
+
+void sparc_cpu_do_interrupt(CPUState *cpu);
+void sparc_cpu_dump_state(CPUState *cpu, FILE *f,
+                          fprintf_function cpu_fprintf, int flags);
+hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int sparc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int sparc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cpu,
+                                                 vaddr addr, int is_write,
+                                                 int is_user, uintptr_t retaddr);
 
 #endif
index e4089f2..fe4119e 100644 (file)
@@ -21,7 +21,6 @@
 #include "qapi/error.h"
 #include "cpu.h"
 #include "qemu/error-report.h"
-#include "exec/exec-all.h"
 
 //#define DEBUG_FEATURES
 
@@ -101,11 +100,9 @@ static void cpu_sparc_disas_set_info(CPUState *cpu, disassemble_info *info)
 #endif
 }
 
-static void sparc_cpu_parse_features(CPUState *cs, char *features,
-                                     Error **errp);
-
 static int cpu_sparc_register(SPARCCPU *cpu, const char *cpu_model)
 {
+    CPUClass *cc = CPU_GET_CLASS(cpu);
     CPUSPARCState *env = &cpu->env;
     char *s = g_strdup(cpu_model);
     char *featurestr, *name = strtok(s, ",");
@@ -121,7 +118,7 @@ static int cpu_sparc_register(SPARCCPU *cpu, const char *cpu_model)
     memcpy(env->def, def, sizeof(*def));
 
     featurestr = strtok(NULL, ",");
-    sparc_cpu_parse_features(CPU(cpu), featurestr, &err);
+    cc->parse_features(CPU(cpu), featurestr, &err);
     g_free(s);
     if (err) {
         error_report_err(err);
@@ -842,6 +839,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     scc->parent_reset = cc->reset;
     cc->reset = sparc_cpu_reset;
 
+    cc->parse_features = sparc_cpu_parse_features;
     cc->has_work = sparc_cpu_has_work;
     cc->do_interrupt = sparc_cpu_do_interrupt;
     cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
index a3d64a4..dc46122 100644 (file)
@@ -1,9 +1,8 @@
-#ifndef SPARC_CPU_H
-#define SPARC_CPU_H
+#ifndef CPU_SPARC_H
+#define CPU_SPARC_H
 
 #include "qemu-common.h"
 #include "qemu/bswap.h"
-#include "cpu-qom.h"
 
 #define ALIGNED_ONLY
 
@@ -507,43 +506,7 @@ struct CPUSPARCState {
     uint32_t cache_control;
 };
 
-/**
- * SPARCCPU:
- * @env: #CPUSPARCState
- *
- * A SPARC CPU.
- */
-struct SPARCCPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPUSPARCState env;
-};
-
-static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
-{
-    return container_of(env, SPARCCPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(sparc_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(SPARCCPU, env)
-
-#ifndef CONFIG_USER_ONLY
-extern const struct VMStateDescription vmstate_sparc_cpu;
-#endif
-
-void sparc_cpu_do_interrupt(CPUState *cpu);
-void sparc_cpu_dump_state(CPUState *cpu, FILE *f,
-                          fprintf_function cpu_fprintf, int flags);
-hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-int sparc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int sparc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
-                                                 MMUAccessType access_type,
-                                                 int mmu_idx,
-                                                 uintptr_t retaddr);
+#include "cpu-qom.h"
 
 #ifndef NO_CPU_IO_DEFS
 /* cpu_init.c */
@@ -566,6 +529,7 @@ int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
 void gen_intermediate_code_init(CPUSPARCState *env);
 
 /* cpu-exec.c */
+int cpu_sparc_exec(CPUState *cpu);
 
 /* win_helper.c */
 target_ulong cpu_get_psr(CPUSPARCState *env1);
@@ -626,6 +590,7 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
 #define cpu_init(cpu_model) CPU(cpu_sparc_init(cpu_model))
 #endif
 
+#define cpu_exec cpu_sparc_exec
 #define cpu_signal_handler cpu_sparc_signal_handler
 #define cpu_list sparc_cpu_list
 
@@ -719,34 +684,34 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit);
 trap_state* cpu_tsptr(CPUSPARCState* env);
 #endif
 
-#define TB_FLAG_MMU_MASK     7
-#define TB_FLAG_FPU_ENABLED  (1 << 4)
-#define TB_FLAG_AM_ENABLED   (1 << 5)
-#define TB_FLAG_ASI_SHIFT    24
+#define TB_FLAG_FPU_ENABLED (1 << 4)
+#define TB_FLAG_AM_ENABLED (1 << 5)
 
 static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *pflags)
+                                        target_ulong *cs_base, int *flags)
 {
-    uint32_t flags;
     *pc = env->pc;
     *cs_base = env->npc;
-    flags = cpu_mmu_index(env, false);
 #ifdef TARGET_SPARC64
+    // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
+    *flags = (env->pstate & PS_PRIV)               /* 2 */
+        | ((env->lsu & (DMMU_E | IMMU_E)) >> 2)    /* 1, 0 */
+        | ((env->tl & 0xff) << 8)
+        | (env->dmmu.mmu_primary_context << 16);   /* 16... */
     if (env->pstate & PS_AM) {
-        flags |= TB_FLAG_AM_ENABLED;
+        *flags |= TB_FLAG_AM_ENABLED;
     }
-    if ((env->def->features & CPU_FEATURE_FLOAT)
-        && (env->pstate & PS_PEF)
+    if ((env->def->features & CPU_FEATURE_FLOAT) && (env->pstate & PS_PEF)
         && (env->fprs & FPRS_FEF)) {
-        flags |= TB_FLAG_FPU_ENABLED;
+        *flags |= TB_FLAG_FPU_ENABLED;
     }
-    flags |= env->asi << TB_FLAG_ASI_SHIFT;
 #else
+    // FPU enable . Supervisor
+    *flags = env->psrs;
     if ((env->def->features & CPU_FEATURE_FLOAT) && env->psref) {
-        flags |= TB_FLAG_FPU_ENABLED;
+        *flags |= TB_FLAG_FPU_ENABLED;
     }
 #endif
-    *pflags = flags;
 }
 
 static inline bool tb_fpu_enabled(int tb_flags)
@@ -767,4 +732,6 @@ static inline bool tb_am_enabled(int tb_flags)
 #endif
 }
 
+#include "exec/exec-all.h"
+
 #endif
index c7fb176..0830643 100644 (file)
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 
 #define QT0 (env->qt0)
 #define QT1 (env->qt1)
 
-static target_ulong do_check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
+static void check_ieee_exceptions(CPUSPARCState *env)
 {
-    target_ulong status = get_float_exception_flags(&env->fp_status);
-    target_ulong fsr = env->fsr;
-
-    if (unlikely(status)) {
-        /* Keep exception flags clear for next time.  */
-        set_float_exception_flags(0, &env->fp_status);
+    target_ulong status;
 
+    status = get_float_exception_flags(&env->fp_status);
+    if (status) {
         /* Copy IEEE 754 flags into FSR */
         if (status & float_flag_invalid) {
-            fsr |= FSR_NVC;
+            env->fsr |= FSR_NVC;
         }
         if (status & float_flag_overflow) {
-            fsr |= FSR_OFC;
+            env->fsr |= FSR_OFC;
         }
         if (status & float_flag_underflow) {
-            fsr |= FSR_UFC;
+            env->fsr |= FSR_UFC;
         }
         if (status & float_flag_divbyzero) {
-            fsr |= FSR_DZC;
+            env->fsr |= FSR_DZC;
         }
         if (status & float_flag_inexact) {
-            fsr |= FSR_NXC;
+            env->fsr |= FSR_NXC;
         }
 
-        if ((fsr & FSR_CEXC_MASK) & ((fsr & FSR_TEM_MASK) >> 23)) {
-            CPUState *cs = CPU(sparc_env_get_cpu(env));
-
-            /* Unmasked exception, generate a trap.  Note that while
-               the helper is marked as NO_WG, we can get away with
-               writing to cpu state along the exception path, since
-               TCG generated code will never see the write.  */
-            env->fsr = fsr | FSR_FTT_IEEE_EXCP;
-            cs->exception_index = TT_FP_EXCP;
-            cpu_loop_exit_restore(cs, ra);
+        if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23)) {
+            /* Unmasked exception, generate a trap */
+            env->fsr |= FSR_FTT_IEEE_EXCP;
+            helper_raise_exception(env, TT_FP_EXCP);
         } else {
             /* Accumulate exceptions */
-            fsr |= (fsr & FSR_CEXC_MASK) << 5;
+            env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5;
         }
     }
-
-    return fsr;
 }
 
-target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
+static inline void clear_float_exceptions(CPUSPARCState *env)
 {
-    return do_check_ieee_exceptions(env, GETPC());
+    set_float_exception_flags(0, &env->fp_status);
 }
 
 #define F_HELPER(name, p) void helper_f##name##p(CPUSPARCState *env)
@@ -81,16 +69,26 @@ target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
     float32 helper_f ## name ## s (CPUSPARCState *env, float32 src1, \
                                    float32 src2)                \
     {                                                           \
-        return float32_ ## name (src1, src2, &env->fp_status);  \
+        float32 ret;                                            \
+        clear_float_exceptions(env);                            \
+        ret = float32_ ## name (src1, src2, &env->fp_status);   \
+        check_ieee_exceptions(env);                             \
+        return ret;                                             \
     }                                                           \
     float64 helper_f ## name ## d (CPUSPARCState * env, float64 src1,\
                                    float64 src2)                \
     {                                                           \
-        return float64_ ## name (src1, src2, &env->fp_status);  \
+        float64 ret;                                            \
+        clear_float_exceptions(env);                            \
+        ret = float64_ ## name (src1, src2, &env->fp_status);   \
+        check_ieee_exceptions(env);                             \
+        return ret;                                             \
     }                                                           \
     F_HELPER(name, q)                                           \
     {                                                           \
+        clear_float_exceptions(env);                            \
         QT0 = float128_ ## name (QT0, QT1, &env->fp_status);    \
+        check_ieee_exceptions(env);                             \
     }
 
 F_BINOP(add);
@@ -101,16 +99,22 @@ F_BINOP(div);
 
 float64 helper_fsmuld(CPUSPARCState *env, float32 src1, float32 src2)
 {
-    return float64_mul(float32_to_float64(src1, &env->fp_status),
-                       float32_to_float64(src2, &env->fp_status),
-                       &env->fp_status);
+    float64 ret;
+    clear_float_exceptions(env);
+    ret = float64_mul(float32_to_float64(src1, &env->fp_status),
+                      float32_to_float64(src2, &env->fp_status),
+                      &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 void helper_fdmulq(CPUSPARCState *env, float64 src1, float64 src2)
 {
+    clear_float_exceptions(env);
     QT0 = float128_mul(float64_to_float128(src1, &env->fp_status),
                        float64_to_float128(src2, &env->fp_status),
                        &env->fp_status);
+    check_ieee_exceptions(env);
 }
 
 float32 helper_fnegs(float32 src)
@@ -133,32 +137,48 @@ F_HELPER(neg, q)
 /* Integer to float conversion.  */
 float32 helper_fitos(CPUSPARCState *env, int32_t src)
 {
-    return int32_to_float32(src, &env->fp_status);
+    /* Inexact error possible converting int to float.  */
+    float32 ret;
+    clear_float_exceptions(env);
+    ret = int32_to_float32(src, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 float64 helper_fitod(CPUSPARCState *env, int32_t src)
 {
+    /* No possible exceptions converting int to double.  */
     return int32_to_float64(src, &env->fp_status);
 }
 
 void helper_fitoq(CPUSPARCState *env, int32_t src)
 {
+    /* No possible exceptions converting int to long double.  */
     QT0 = int32_to_float128(src, &env->fp_status);
 }
 
 #ifdef TARGET_SPARC64
 float32 helper_fxtos(CPUSPARCState *env, int64_t src)
 {
-    return int64_to_float32(src, &env->fp_status);
+    float32 ret;
+    clear_float_exceptions(env);
+    ret = int64_to_float32(src, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 float64 helper_fxtod(CPUSPARCState *env, int64_t src)
 {
-    return int64_to_float64(src, &env->fp_status);
+    float64 ret;
+    clear_float_exceptions(env);
+    ret = int64_to_float64(src, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 void helper_fxtoq(CPUSPARCState *env, int64_t src)
 {
+    /* No possible exceptions converting long long to long double.  */
     QT0 = int64_to_float128(src, &env->fp_status);
 }
 #endif
@@ -167,64 +187,108 @@ void helper_fxtoq(CPUSPARCState *env, int64_t src)
 /* floating point conversion */
 float32 helper_fdtos(CPUSPARCState *env, float64 src)
 {
-    return float64_to_float32(src, &env->fp_status);
+    float32 ret;
+    clear_float_exceptions(env);
+    ret = float64_to_float32(src, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 float64 helper_fstod(CPUSPARCState *env, float32 src)
 {
-    return float32_to_float64(src, &env->fp_status);
+    float64 ret;
+    clear_float_exceptions(env);
+    ret = float32_to_float64(src, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 float32 helper_fqtos(CPUSPARCState *env)
 {
-    return float128_to_float32(QT1, &env->fp_status);
+    float32 ret;
+    clear_float_exceptions(env);
+    ret = float128_to_float32(QT1, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 void helper_fstoq(CPUSPARCState *env, float32 src)
 {
+    clear_float_exceptions(env);
     QT0 = float32_to_float128(src, &env->fp_status);
+    check_ieee_exceptions(env);
 }
 
 float64 helper_fqtod(CPUSPARCState *env)
 {
-    return float128_to_float64(QT1, &env->fp_status);
+    float64 ret;
+    clear_float_exceptions(env);
+    ret = float128_to_float64(QT1, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 void helper_fdtoq(CPUSPARCState *env, float64 src)
 {
+    clear_float_exceptions(env);
     QT0 = float64_to_float128(src, &env->fp_status);
+    check_ieee_exceptions(env);
 }
 
 /* Float to integer conversion.  */
 int32_t helper_fstoi(CPUSPARCState *env, float32 src)
 {
-    return float32_to_int32_round_to_zero(src, &env->fp_status);
+    int32_t ret;
+    clear_float_exceptions(env);
+    ret = float32_to_int32_round_to_zero(src, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 int32_t helper_fdtoi(CPUSPARCState *env, float64 src)
 {
-    return float64_to_int32_round_to_zero(src, &env->fp_status);
+    int32_t ret;
+    clear_float_exceptions(env);
+    ret = float64_to_int32_round_to_zero(src, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 int32_t helper_fqtoi(CPUSPARCState *env)
 {
-    return float128_to_int32_round_to_zero(QT1, &env->fp_status);
+    int32_t ret;
+    clear_float_exceptions(env);
+    ret = float128_to_int32_round_to_zero(QT1, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 #ifdef TARGET_SPARC64
 int64_t helper_fstox(CPUSPARCState *env, float32 src)
 {
-    return float32_to_int64_round_to_zero(src, &env->fp_status);
+    int64_t ret;
+    clear_float_exceptions(env);
+    ret = float32_to_int64_round_to_zero(src, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 int64_t helper_fdtox(CPUSPARCState *env, float64 src)
 {
-    return float64_to_int64_round_to_zero(src, &env->fp_status);
+    int64_t ret;
+    clear_float_exceptions(env);
+    ret = float64_to_int64_round_to_zero(src, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 int64_t helper_fqtox(CPUSPARCState *env)
 {
-    return float128_to_int64_round_to_zero(QT1, &env->fp_status);
+    int64_t ret;
+    clear_float_exceptions(env);
+    ret = float128_to_int64_round_to_zero(QT1, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 #endif
 
@@ -247,79 +311,87 @@ void helper_fabsq(CPUSPARCState *env)
 
 float32 helper_fsqrts(CPUSPARCState *env, float32 src)
 {
-    return float32_sqrt(src, &env->fp_status);
+    float32 ret;
+    clear_float_exceptions(env);
+    ret = float32_sqrt(src, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 float64 helper_fsqrtd(CPUSPARCState *env, float64 src)
 {
-    return float64_sqrt(src, &env->fp_status);
+    float64 ret;
+    clear_float_exceptions(env);
+    ret = float64_sqrt(src, &env->fp_status);
+    check_ieee_exceptions(env);
+    return ret;
 }
 
 void helper_fsqrtq(CPUSPARCState *env)
 {
+    clear_float_exceptions(env);
     QT0 = float128_sqrt(QT1, &env->fp_status);
+    check_ieee_exceptions(env);
 }
 
 #define GEN_FCMP(name, size, reg1, reg2, FS, E)                         \
-    target_ulong glue(helper_, name) (CPUSPARCState *env)               \
+    void glue(helper_, name) (CPUSPARCState *env)                       \
     {                                                                   \
         int ret;                                                        \
-        target_ulong fsr;                                               \
+        clear_float_exceptions(env);                                    \
         if (E) {                                                        \
             ret = glue(size, _compare)(reg1, reg2, &env->fp_status);    \
         } else {                                                        \
             ret = glue(size, _compare_quiet)(reg1, reg2,                \
                                              &env->fp_status);          \
         }                                                               \
-        fsr = do_check_ieee_exceptions(env, GETPC());                   \
+        check_ieee_exceptions(env);                                     \
         switch (ret) {                                                  \
         case float_relation_unordered:                                  \
-            fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                         \
-            fsr |= FSR_NVA;                                             \
+            env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                    \
+            env->fsr |= FSR_NVA;                                        \
             break;                                                      \
         case float_relation_less:                                       \
-            fsr &= ~(FSR_FCC1) << FS;                                   \
-            fsr |= FSR_FCC0 << FS;                                      \
+            env->fsr &= ~(FSR_FCC1) << FS;                              \
+            env->fsr |= FSR_FCC0 << FS;                                 \
             break;                                                      \
         case float_relation_greater:                                    \
-            fsr &= ~(FSR_FCC0) << FS;                                   \
-            fsr |= FSR_FCC1 << FS;                                      \
+            env->fsr &= ~(FSR_FCC0) << FS;                              \
+            env->fsr |= FSR_FCC1 << FS;                                 \
             break;                                                      \
         default:                                                        \
-            fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                      \
+            env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                 \
             break;                                                      \
         }                                                               \
-        return fsr;                                                     \
     }
 #define GEN_FCMP_T(name, size, FS, E)                                   \
-    target_ulong glue(helper_, name)(CPUSPARCState *env, size src1, size src2)\
+    void glue(helper_, name)(CPUSPARCState *env, size src1, size src2)  \
     {                                                                   \
         int ret;                                                        \
-        target_ulong fsr;                                               \
+        clear_float_exceptions(env);                                    \
         if (E) {                                                        \
             ret = glue(size, _compare)(src1, src2, &env->fp_status);    \
         } else {                                                        \
             ret = glue(size, _compare_quiet)(src1, src2,                \
                                              &env->fp_status);          \
         }                                                               \
-        fsr = do_check_ieee_exceptions(env, GETPC());                   \
+        check_ieee_exceptions(env);                                     \
         switch (ret) {                                                  \
         case float_relation_unordered:                                  \
-            fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                         \
+            env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                    \
             break;                                                      \
         case float_relation_less:                                       \
-            fsr &= ~(FSR_FCC1 << FS);                                   \
-            fsr |= FSR_FCC0 << FS;                                      \
+            env->fsr &= ~(FSR_FCC1 << FS);                              \
+            env->fsr |= FSR_FCC0 << FS;                                 \
             break;                                                      \
         case float_relation_greater:                                    \
-            fsr &= ~(FSR_FCC0 << FS);                                   \
-            fsr |= FSR_FCC1 << FS;                                      \
+            env->fsr &= ~(FSR_FCC0 << FS);                              \
+            env->fsr |= FSR_FCC1 << FS;                                 \
             break;                                                      \
         default:                                                        \
-            fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                      \
+            env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                 \
             break;                                                      \
         }                                                               \
-        return fsr;                                                     \
     }
 
 GEN_FCMP_T(fcmps, float32, 0, 0);
@@ -359,11 +431,11 @@ GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1);
 #undef GEN_FCMP_T
 #undef GEN_FCMP
 
-static void set_fsr(CPUSPARCState *env, target_ulong fsr)
+static inline void set_fsr(CPUSPARCState *env)
 {
     int rnd_mode;
 
-    switch (fsr & FSR_RD_MASK) {
+    switch (env->fsr & FSR_RD_MASK) {
     case FSR_RD_NEAREST:
         rnd_mode = float_round_nearest_even;
         break;
@@ -381,20 +453,16 @@ static void set_fsr(CPUSPARCState *env, target_ulong fsr)
     set_float_rounding_mode(rnd_mode, &env->fp_status);
 }
 
-target_ulong helper_ldfsr(CPUSPARCState *env, target_ulong old_fsr,
-                          uint32_t new_fsr)
+void helper_ldfsr(CPUSPARCState *env, uint32_t new_fsr)
 {
-    old_fsr = (new_fsr & FSR_LDFSR_MASK) | (old_fsr & FSR_LDFSR_OLDMASK);
-    set_fsr(env, old_fsr);
-    return old_fsr;
+    env->fsr = (new_fsr & FSR_LDFSR_MASK) | (env->fsr & FSR_LDFSR_OLDMASK);
+    set_fsr(env);
 }
 
 #ifdef TARGET_SPARC64
-target_ulong helper_ldxfsr(CPUSPARCState *env, target_ulong old_fsr,
-                           uint64_t new_fsr)
+void helper_ldxfsr(CPUSPARCState *env, uint64_t new_fsr)
 {
-    old_fsr = (new_fsr & FSR_LDXFSR_MASK) | (old_fsr & FSR_LDXFSR_OLDMASK);
-    set_fsr(env, old_fsr);
-    return old_fsr;
+    env->fsr = (new_fsr & FSR_LDXFSR_MASK) | (env->fsr & FSR_LDXFSR_OLDMASK);
+    set_fsr(env);
 }
 #endif
index ffc2baa..e530dc5 100644 (file)
@@ -19,7 +19,6 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
 
 #ifdef TARGET_ABI32
index bedc672..8349cbe 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
 #include "sysemu/sysemu.h"
index caa2a89..4374f0d 100644 (file)
@@ -4,32 +4,34 @@ DEF_HELPER_2(wrpsr, void, env, tl)
 DEF_HELPER_1(rdpsr, tl, env)
 DEF_HELPER_1(power_down, void, env)
 #else
-DEF_HELPER_FLAGS_2(wrpil, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_2(wrpil, void, env, tl)
 DEF_HELPER_2(wrpstate, void, env, tl)
 DEF_HELPER_1(done, void, env)
 DEF_HELPER_1(retry, void, env)
-DEF_HELPER_FLAGS_1(flushw, TCG_CALL_NO_WG, void, env)
-DEF_HELPER_FLAGS_1(saved, TCG_CALL_NO_RWG, void, env)
-DEF_HELPER_FLAGS_1(restored, TCG_CALL_NO_RWG, void, env)
+DEF_HELPER_1(flushw, void, env)
+DEF_HELPER_1(saved, void, env)
+DEF_HELPER_1(restored, void, env)
 DEF_HELPER_1(rdccr, tl, env)
 DEF_HELPER_2(wrccr, void, env, tl)
 DEF_HELPER_1(rdcwp, tl, env)
 DEF_HELPER_2(wrcwp, void, env, tl)
 DEF_HELPER_FLAGS_2(array8, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_1(popc, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_FLAGS_3(ldda_asi, TCG_CALL_NO_WG, void, env, tl, int)
-DEF_HELPER_FLAGS_5(casx_asi, TCG_CALL_NO_WG, tl, env, tl, tl, tl, i32)
-DEF_HELPER_FLAGS_2(set_softint, TCG_CALL_NO_RWG, void, env, i64)
-DEF_HELPER_FLAGS_2(clear_softint, TCG_CALL_NO_RWG, void, env, i64)
-DEF_HELPER_FLAGS_2(write_softint, TCG_CALL_NO_RWG, void, env, i64)
-DEF_HELPER_FLAGS_2(tick_set_count, TCG_CALL_NO_RWG, void, ptr, i64)
-DEF_HELPER_FLAGS_3(tick_get_count, TCG_CALL_NO_WG, i64, env, ptr, int)
-DEF_HELPER_FLAGS_2(tick_set_limit, TCG_CALL_NO_RWG, void, ptr, i64)
+DEF_HELPER_1(popc, tl, tl)
+DEF_HELPER_4(ldda_asi, void, env, tl, int, int)
+DEF_HELPER_5(ldf_asi, void, env, tl, int, int, int)
+DEF_HELPER_5(stf_asi, void, env, tl, int, int, int)
+DEF_HELPER_5(casx_asi, tl, env, tl, tl, tl, i32)
+DEF_HELPER_2(set_softint, void, env, i64)
+DEF_HELPER_2(clear_softint, void, env, i64)
+DEF_HELPER_2(write_softint, void, env, i64)
+DEF_HELPER_2(tick_set_count, void, ptr, i64)
+DEF_HELPER_3(tick_get_count, i64, env, ptr, int)
+DEF_HELPER_2(tick_set_limit, void, ptr, i64)
 #endif
 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
-DEF_HELPER_FLAGS_5(cas_asi, TCG_CALL_NO_WG, tl, env, tl, tl, tl, i32)
+DEF_HELPER_5(cas_asi, tl, env, tl, tl, tl, i32)
 #endif
-DEF_HELPER_FLAGS_3(check_align, TCG_CALL_NO_WG, void, env, tl, i32)
+DEF_HELPER_3(check_align, void, env, tl, i32)
 DEF_HELPER_1(debug, void, env)
 DEF_HELPER_1(save, void, env)
 DEF_HELPER_1(restore, void, env)
@@ -40,97 +42,95 @@ DEF_HELPER_3(sdiv_cc, tl, env, tl, tl)
 DEF_HELPER_3(taddcctv, tl, env, tl, tl)
 DEF_HELPER_3(tsubcctv, tl, env, tl, tl)
 #ifdef TARGET_SPARC64
-DEF_HELPER_FLAGS_3(sdivx, TCG_CALL_NO_WG, s64, env, s64, s64)
-DEF_HELPER_FLAGS_3(udivx, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_3(sdivx, s64, env, s64, s64)
+DEF_HELPER_3(udivx, i64, env, i64, i64)
 #endif
-DEF_HELPER_FLAGS_3(ldqf, TCG_CALL_NO_WG, void, env, tl, int)
-DEF_HELPER_FLAGS_3(stqf, TCG_CALL_NO_WG, void, env, tl, int)
+DEF_HELPER_3(ldqf, void, env, tl, int)
+DEF_HELPER_3(stqf, void, env, tl, int)
 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
-DEF_HELPER_FLAGS_4(ld_asi, TCG_CALL_NO_WG, i64, env, tl, int, i32)
-DEF_HELPER_FLAGS_5(st_asi, TCG_CALL_NO_WG, void, env, tl, i64, int, i32)
+DEF_HELPER_5(ld_asi, i64, env, tl, int, int, int)
+DEF_HELPER_5(st_asi, void, env, tl, i64, int, int)
 #endif
-DEF_HELPER_FLAGS_1(check_ieee_exceptions, TCG_CALL_NO_WG, tl, env)
-DEF_HELPER_FLAGS_3(ldfsr, TCG_CALL_NO_RWG, tl, env, tl, i32)
+DEF_HELPER_2(ldfsr, void, env, i32)
 DEF_HELPER_FLAGS_1(fabss, TCG_CALL_NO_RWG_SE, f32, f32)
-DEF_HELPER_FLAGS_2(fsqrts, TCG_CALL_NO_RWG, f32, env, f32)
-DEF_HELPER_FLAGS_2(fsqrtd, TCG_CALL_NO_RWG, f64, env, f64)
-DEF_HELPER_FLAGS_3(fcmps, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpes, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_1(fsqrtq, TCG_CALL_NO_RWG, void, env)
-DEF_HELPER_FLAGS_1(fcmpq, TCG_CALL_NO_WG, tl, env)
-DEF_HELPER_FLAGS_1(fcmpeq, TCG_CALL_NO_WG, tl, env)
+DEF_HELPER_2(fsqrts, f32, env, f32)
+DEF_HELPER_2(fsqrtd, f64, env, f64)
+DEF_HELPER_3(fcmps, void, env, f32, f32)
+DEF_HELPER_3(fcmpd, void, env, f64, f64)
+DEF_HELPER_3(fcmpes, void, env, f32, f32)
+DEF_HELPER_3(fcmped, void, env, f64, f64)
+DEF_HELPER_1(fsqrtq, void, env)
+DEF_HELPER_1(fcmpq, void, env)
+DEF_HELPER_1(fcmpeq, void, env)
 #ifdef TARGET_SPARC64
-DEF_HELPER_FLAGS_3(ldxfsr, TCG_CALL_NO_RWG, tl, env, tl, i64)
+DEF_HELPER_2(ldxfsr, void, env, i64)
 DEF_HELPER_FLAGS_1(fabsd, TCG_CALL_NO_RWG_SE, f64, f64)
-DEF_HELPER_FLAGS_3(fcmps_fcc1, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmps_fcc2, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmps_fcc3, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpd_fcc1, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpd_fcc2, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpd_fcc3, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpes_fcc1, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpes_fcc2, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpes_fcc3, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmped_fcc1, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmped_fcc2, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmped_fcc3, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_1(fabsq, TCG_CALL_NO_RWG, void, env)
-DEF_HELPER_FLAGS_1(fcmpq_fcc1, TCG_CALL_NO_WG, tl, env)
-DEF_HELPER_FLAGS_1(fcmpq_fcc2, TCG_CALL_NO_WG, tl, env)
-DEF_HELPER_FLAGS_1(fcmpq_fcc3, TCG_CALL_NO_WG, tl, env)
-DEF_HELPER_FLAGS_1(fcmpeq_fcc1, TCG_CALL_NO_WG, tl, env)
-DEF_HELPER_FLAGS_1(fcmpeq_fcc2, TCG_CALL_NO_WG, tl, env)
-DEF_HELPER_FLAGS_1(fcmpeq_fcc3, TCG_CALL_NO_WG, tl, env)
+DEF_HELPER_3(fcmps_fcc1, void, env, f32, f32)
+DEF_HELPER_3(fcmps_fcc2, void, env, f32, f32)
+DEF_HELPER_3(fcmps_fcc3, void, env, f32, f32)
+DEF_HELPER_3(fcmpd_fcc1, void, env, f64, f64)
+DEF_HELPER_3(fcmpd_fcc2, void, env, f64, f64)
+DEF_HELPER_3(fcmpd_fcc3, void, env, f64, f64)
+DEF_HELPER_3(fcmpes_fcc1, void, env, f32, f32)
+DEF_HELPER_3(fcmpes_fcc2, void, env, f32, f32)
+DEF_HELPER_3(fcmpes_fcc3, void, env, f32, f32)
+DEF_HELPER_3(fcmped_fcc1, void, env, f64, f64)
+DEF_HELPER_3(fcmped_fcc2, void, env, f64, f64)
+DEF_HELPER_3(fcmped_fcc3, void, env, f64, f64)
+DEF_HELPER_1(fabsq, void, env)
+DEF_HELPER_1(fcmpq_fcc1, void, env)
+DEF_HELPER_1(fcmpq_fcc2, void, env)
+DEF_HELPER_1(fcmpq_fcc3, void, env)
+DEF_HELPER_1(fcmpeq_fcc1, void, env)
+DEF_HELPER_1(fcmpeq_fcc2, void, env)
+DEF_HELPER_1(fcmpeq_fcc3, void, env)
 #endif
 DEF_HELPER_2(raise_exception, noreturn, env, int)
-#define F_HELPER_0_1(name) \
-  DEF_HELPER_FLAGS_1(f ## name, TCG_CALL_NO_RWG, void, env)
+#define F_HELPER_0_1(name) DEF_HELPER_1(f ## name, void, env)
 
-DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_RWG, f64, env, f64, f64)
-DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_RWG, f64, env, f64, f64)
-DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_RWG, f64, env, f64, f64)
-DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_RWG, f64, env, f64, f64)
+DEF_HELPER_3(faddd, f64, env, f64, f64)
+DEF_HELPER_3(fsubd, f64, env, f64, f64)
+DEF_HELPER_3(fmuld, f64, env, f64, f64)
+DEF_HELPER_3(fdivd, f64, env, f64, f64)
 F_HELPER_0_1(addq)
 F_HELPER_0_1(subq)
 F_HELPER_0_1(mulq)
 F_HELPER_0_1(divq)
 
-DEF_HELPER_FLAGS_3(fadds, TCG_CALL_NO_RWG, f32, env, f32, f32)
-DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_RWG, f32, env, f32, f32)
-DEF_HELPER_FLAGS_3(fmuls, TCG_CALL_NO_RWG, f32, env, f32, f32)
-DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_RWG, f32, env, f32, f32)
+DEF_HELPER_3(fadds, f32, env, f32, f32)
+DEF_HELPER_3(fsubs, f32, env, f32, f32)
+DEF_HELPER_3(fmuls, f32, env, f32, f32)
+DEF_HELPER_3(fdivs, f32, env, f32, f32)
 
-DEF_HELPER_FLAGS_3(fsmuld, TCG_CALL_NO_RWG, f64, env, f32, f32)
-DEF_HELPER_FLAGS_3(fdmulq, TCG_CALL_NO_RWG, void, env, f64, f64)
+DEF_HELPER_3(fsmuld, f64, env, f32, f32)
+DEF_HELPER_3(fdmulq, void, env, f64, f64)
 
 DEF_HELPER_FLAGS_1(fnegs, TCG_CALL_NO_RWG_SE, f32, f32)
-DEF_HELPER_FLAGS_2(fitod, TCG_CALL_NO_RWG_SE, f64, env, s32)
-DEF_HELPER_FLAGS_2(fitoq, TCG_CALL_NO_RWG, void, env, s32)
+DEF_HELPER_2(fitod, f64, env, s32)
+DEF_HELPER_2(fitoq, void, env, s32)
 
-DEF_HELPER_FLAGS_2(fitos, TCG_CALL_NO_RWG, f32, env, s32)
+DEF_HELPER_2(fitos, f32, env, s32)
 
 #ifdef TARGET_SPARC64
 DEF_HELPER_FLAGS_1(fnegd, TCG_CALL_NO_RWG_SE, f64, f64)
-DEF_HELPER_FLAGS_1(fnegq, TCG_CALL_NO_RWG, void, env)
-DEF_HELPER_FLAGS_2(fxtos, TCG_CALL_NO_RWG, f32, env, s64)
-DEF_HELPER_FLAGS_2(fxtod, TCG_CALL_NO_RWG, f64, env, s64)
-DEF_HELPER_FLAGS_2(fxtoq, TCG_CALL_NO_RWG, void, env, s64)
+DEF_HELPER_1(fnegq, void, env)
+DEF_HELPER_2(fxtos, f32, env, s64)
+DEF_HELPER_2(fxtod, f64, env, s64)
+DEF_HELPER_2(fxtoq, void, env, s64)
 #endif
-DEF_HELPER_FLAGS_2(fdtos, TCG_CALL_NO_RWG, f32, env, f64)
-DEF_HELPER_FLAGS_2(fstod, TCG_CALL_NO_RWG, f64, env, f32)
-DEF_HELPER_FLAGS_1(fqtos, TCG_CALL_NO_RWG, f32, env)
-DEF_HELPER_FLAGS_2(fstoq, TCG_CALL_NO_RWG, void, env, f32)
-DEF_HELPER_FLAGS_1(fqtod, TCG_CALL_NO_RWG, f64, env)
-DEF_HELPER_FLAGS_2(fdtoq, TCG_CALL_NO_RWG, void, env, f64)
-DEF_HELPER_FLAGS_2(fstoi, TCG_CALL_NO_RWG, s32, env, f32)
-DEF_HELPER_FLAGS_2(fdtoi, TCG_CALL_NO_RWG, s32, env, f64)
-DEF_HELPER_FLAGS_1(fqtoi, TCG_CALL_NO_RWG, s32, env)
+DEF_HELPER_2(fdtos, f32, env, f64)
+DEF_HELPER_2(fstod, f64, env, f32)
+DEF_HELPER_1(fqtos, f32, env)
+DEF_HELPER_2(fstoq, void, env, f32)
+DEF_HELPER_1(fqtod, f64, env)
+DEF_HELPER_2(fdtoq, void, env, f64)
+DEF_HELPER_2(fstoi, s32, env, f32)
+DEF_HELPER_2(fdtoi, s32, env, f64)
+DEF_HELPER_1(fqtoi, s32, env)
 #ifdef TARGET_SPARC64
-DEF_HELPER_FLAGS_2(fstox, TCG_CALL_NO_RWG, s64, env, f32)
-DEF_HELPER_FLAGS_2(fdtox, TCG_CALL_NO_RWG, s64, env, f64)
-DEF_HELPER_FLAGS_1(fqtox, TCG_CALL_NO_RWG, s64, env)
+DEF_HELPER_2(fstox, s64, env, f32)
+DEF_HELPER_2(fdtox, s64, env, f64)
+DEF_HELPER_1(fqtox, s64, env)
 
 DEF_HELPER_FLAGS_2(fpmerge, TCG_CALL_NO_RWG_SE, i64, i64, i64)
 DEF_HELPER_FLAGS_2(fmul8x16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
@@ -172,4 +172,4 @@ VIS_CMPHELPER(cmpne)
 #undef VIS_HELPER
 #undef VIS_CMPHELPER
 DEF_HELPER_1(compute_psr, void, env)
-DEF_HELPER_FLAGS_1(compute_C_icc, TCG_CALL_NO_WG_SE, i32, env)
+DEF_HELPER_1(compute_C_icc, i32, env)
index 6ce5ccc..658e7d8 100644 (file)
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "tcg.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
-#include "asi.h"
 
 //#define DEBUG_MMU
 //#define DEBUG_MXCC
@@ -429,11 +426,9 @@ static uint64_t leon3_cache_control_ld(CPUSPARCState *env, target_ulong addr,
     return ret;
 }
 
-uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
-                       int asi, uint32_t memop)
+uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
+                       int sign)
 {
-    int size = 1 << (memop & MO_SIZE);
-    int sign = memop & MO_SIGN;
     CPUState *cs = CPU(sparc_env_get_cpu(env));
     uint64_t ret = 0;
 #if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
@@ -442,8 +437,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
 
     helper_check_align(env, addr, size - 1);
     switch (asi) {
-    case ASI_M_MXCC: /* SuperSparc MXCC registers, or... */
-    /* case ASI_LEON_CACHEREGS:  Leon3 cache control */
+    case 2: /* SuperSparc MXCC registers and Leon3 cache control */
         switch (addr) {
         case 0x00:          /* Leon3 Cache Control */
         case 0x08:          /* Leon3 Instruction Cache config */
@@ -502,8 +496,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
         dump_mxcc(env);
 #endif
         break;
-    case ASI_M_FLUSH_PROBE: /* SuperSparc MMU probe */
-    case ASI_LEON_MMUFLUSH: /* LEON3 MMU probe */
+    case 3: /* MMU probe */
+    case 0x18: /* LEON3 MMU probe */
         {
             int mmulev;
 
@@ -517,8 +511,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
                         addr, mmulev, ret);
         }
         break;
-    case ASI_M_MMUREGS: /* SuperSparc MMU regs */
-    case ASI_LEON_MMUREGS: /* LEON3 MMU regs */
+    case 4: /* read MMU regs */
+    case 0x19: /* LEON3 read MMU regs */
         {
             int reg = (addr >> 8) & 0x1f;
 
@@ -533,11 +527,11 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             DPRINTF_MMU("mmu_read: reg[%d] = 0x%08" PRIx64 "\n", reg, ret);
         }
         break;
-    case ASI_M_TLBDIAG: /* Turbosparc ITLB Diagnostic */
-    case ASI_M_DIAGS:   /* Turbosparc DTLB Diagnostic */
-    case ASI_M_IODIAG:  /* Turbosparc IOTLB Diagnostic */
+    case 5: /* Turbosparc ITLB Diagnostic */
+    case 6: /* Turbosparc DTLB Diagnostic */
+    case 7: /* Turbosparc IOTLB Diagnostic */
         break;
-    case ASI_KERNELTXT: /* Supervisor code access */
+    case 9: /* Supervisor code access */
         switch (size) {
         case 1:
             ret = cpu_ldub_code(env, addr);
@@ -554,7 +548,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             break;
         }
         break;
-    case ASI_USERDATA: /* User data access */
+    case 0xa: /* User data access */
         switch (size) {
         case 1:
             ret = cpu_ldub_user(env, addr);
@@ -571,8 +565,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             break;
         }
         break;
-    case ASI_KERNELDATA: /* Supervisor data access */
-    case ASI_P: /* Implicit primary context data access (v9 only?) */
+    case 0xb: /* Supervisor data access */
+    case 0x80:
         switch (size) {
         case 1:
             ret = cpu_ldub_kernel(env, addr);
@@ -589,13 +583,13 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             break;
         }
         break;
-    case ASI_M_TXTC_TAG:   /* SparcStation 5 I-cache tag */
-    case ASI_M_TXTC_DATA:  /* SparcStation 5 I-cache data */
-    case ASI_M_DATAC_TAG:  /* SparcStation 5 D-cache tag */
-    case ASI_M_DATAC_DATA: /* SparcStation 5 D-cache data */
+    case 0xc: /* I-cache tag */
+    case 0xd: /* I-cache data */
+    case 0xe: /* D-cache tag */
+    case 0xf: /* D-cache data */
         break;
-    case ASI_M_BYPASS:    /* MMU passthrough */
-    case ASI_LEON_BYPASS: /* LEON MMU passthrough */
+    case 0x20: /* MMU passthrough */
+    case 0x1c: /* LEON MMU passthrough */
         switch (size) {
         case 1:
             ret = ldub_phys(cs->as, addr);
@@ -674,7 +668,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
     case 0x4c: /* SuperSPARC MMU Breakpoint Action */
         ret = env->mmubpaction;
         break;
-    case ASI_USERTXT: /* User code access, XXX */
+    case 8: /* User code access, XXX */
     default:
         cpu_unassigned_access(cs, addr, false, false, asi, size);
         ret = 0;
@@ -701,17 +695,15 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
     return ret;
 }
 
-void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
-                   int asi, uint32_t memop)
+void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val, int asi,
+                   int size)
 {
-    int size = 1 << (memop & MO_SIZE);
     SPARCCPU *cpu = sparc_env_get_cpu(env);
     CPUState *cs = CPU(cpu);
 
     helper_check_align(env, addr, size - 1);
     switch (asi) {
-    case ASI_M_MXCC: /* SuperSparc MXCC registers, or... */
-    /* case ASI_LEON_CACHEREGS:  Leon3 cache control */
+    case 2: /* SuperSparc MXCC registers and Leon3 cache control */
         switch (addr) {
         case 0x00:          /* Leon3 Cache Control */
         case 0x08:          /* Leon3 Instruction Cache config */
@@ -845,8 +837,8 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
         dump_mxcc(env);
 #endif
         break;
-    case ASI_M_FLUSH_PROBE: /* SuperSparc MMU flush */
-    case ASI_LEON_MMUFLUSH: /* LEON3 MMU flush */
+    case 3: /* MMU flush */
+    case 0x18: /* LEON3 MMU flush */
         {
             int mmulev;
 
@@ -870,8 +862,8 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
 #endif
         }
         break;
-    case ASI_M_MMUREGS: /* write MMU regs */
-    case ASI_LEON_MMUREGS: /* LEON3 write MMU regs */
+    case 4: /* write MMU regs */
+    case 0x19: /* LEON3 write MMU regs */
         {
             int reg = (addr >> 8) & 0x1f;
             uint32_t oldreg;
@@ -925,11 +917,11 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
 #endif
         }
         break;
-    case ASI_M_TLBDIAG: /* Turbosparc ITLB Diagnostic */
-    case ASI_M_DIAGS:   /* Turbosparc DTLB Diagnostic */
-    case ASI_M_IODIAG:  /* Turbosparc IOTLB Diagnostic */
+    case 5: /* Turbosparc ITLB Diagnostic */
+    case 6: /* Turbosparc DTLB Diagnostic */
+    case 7: /* Turbosparc IOTLB Diagnostic */
         break;
-    case ASI_USERDATA: /* User data access */
+    case 0xa: /* User data access */
         switch (size) {
         case 1:
             cpu_stb_user(env, addr, val);
@@ -946,8 +938,8 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
             break;
         }
         break;
-    case ASI_KERNELDATA: /* Supervisor data access */
-    case ASI_P:
+    case 0xb: /* Supervisor data access */
+    case 0x80:
         switch (size) {
         case 1:
             cpu_stb_kernel(env, addr, val);
@@ -964,17 +956,17 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
             break;
         }
         break;
-    case ASI_M_TXTC_TAG:   /* I-cache tag */
-    case ASI_M_TXTC_DATA:  /* I-cache data */
-    case ASI_M_DATAC_TAG:  /* D-cache tag */
-    case ASI_M_DATAC_DATA: /* D-cache data */
-    case ASI_M_FLUSH_PAGE:   /* I/D-cache flush page */
-    case ASI_M_FLUSH_SEG:    /* I/D-cache flush segment */
-    case ASI_M_FLUSH_REGION: /* I/D-cache flush region */
-    case ASI_M_FLUSH_CTX:    /* I/D-cache flush context */
-    case ASI_M_FLUSH_USER:   /* I/D-cache flush user */
+    case 0xc: /* I-cache tag */
+    case 0xd: /* I-cache data */
+    case 0xe: /* D-cache tag */
+    case 0xf: /* D-cache data */
+    case 0x10: /* I/D-cache flush page */
+    case 0x11: /* I/D-cache flush segment */
+    case 0x12: /* I/D-cache flush region */
+    case 0x13: /* I/D-cache flush context */
+    case 0x14: /* I/D-cache flush user */
         break;
-    case ASI_M_BCOPY: /* Block copy, sta access */
+    case 0x17: /* Block copy, sta access */
         {
             /* val = src
                addr = dst
@@ -988,20 +980,20 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
             }
         }
         break;
-    case ASI_M_BFILL: /* Block fill, stda access */
+    case 0x1f: /* Block fill, stda access */
         {
             /* addr = dst
                fill 32 bytes with val */
             unsigned int i;
-            uint32_t dst = addr & ~7;
+            uint32_t dst = addr & 7;
 
             for (i = 0; i < 32; i += 8, dst += 8) {
                 cpu_stq_kernel(env, dst, val);
             }
         }
         break;
-    case ASI_M_BYPASS:    /* MMU passthrough */
-    case ASI_LEON_BYPASS: /* LEON MMU passthrough */
+    case 0x20: /* MMU passthrough */
+    case 0x1c: /* LEON MMU passthrough */
         {
             switch (size) {
             case 1:
@@ -1085,8 +1077,8 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
     case 0x4c: /* SuperSPARC MMU Breakpoint Action */
         env->mmubpaction = val & 0x1fff;
         break;
-    case ASI_USERTXT: /* User code access, XXX */
-    case ASI_KERNELTXT: /* Supervisor code access, XXX */
+    case 8: /* User code access, XXX */
+    case 9: /* Supervisor code access, XXX */
     default:
         cpu_unassigned_access(CPU(sparc_env_get_cpu(env)),
                               addr, true, false, asi, size);
@@ -1101,11 +1093,9 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
 #else /* TARGET_SPARC64 */
 
 #ifdef CONFIG_USER_ONLY
-uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
-                       int asi, uint32_t memop)
+uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
+                       int sign)
 {
-    int size = 1 << (memop & MO_SIZE);
-    int sign = memop & MO_SIGN;
     uint64_t ret = 0;
 #if defined(DEBUG_ASI)
     target_ulong last_addr = addr;
@@ -1119,8 +1109,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
     addr = asi_address_mask(env, asi, addr);
 
     switch (asi) {
-    case ASI_PNF:  /* Primary no-fault */
-    case ASI_PNFL: /* Primary no-fault LE */
+    case 0x82: /* Primary no-fault */
+    case 0x8a: /* Primary no-fault LE */
         if (page_check_range(addr, size, PAGE_READ) == -1) {
 #ifdef DEBUG_ASI
             dump_asi("read ", last_addr, asi, size, ret);
@@ -1128,8 +1118,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             return 0;
         }
         /* Fall through */
-    case ASI_P: /* Primary */
-    case ASI_PL: /* Primary LE */
+    case 0x80: /* Primary */
+    case 0x88: /* Primary LE */
         {
             switch (size) {
             case 1:
@@ -1148,8 +1138,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             }
         }
         break;
-    case ASI_SNF:  /* Secondary no-fault */
-    case ASI_SNFL: /* Secondary no-fault LE */
+    case 0x83: /* Secondary no-fault */
+    case 0x8b: /* Secondary no-fault LE */
         if (page_check_range(addr, size, PAGE_READ) == -1) {
 #ifdef DEBUG_ASI
             dump_asi("read ", last_addr, asi, size, ret);
@@ -1157,8 +1147,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             return 0;
         }
         /* Fall through */
-    case ASI_S:  /* Secondary */
-    case ASI_SL: /* Secondary LE */
+    case 0x81: /* Secondary */
+    case 0x89: /* Secondary LE */
         /* XXX */
         break;
     default:
@@ -1167,10 +1157,10 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
 
     /* Convert from little endian */
     switch (asi) {
-    case ASI_PL:   /* Primary LE */
-    case ASI_SL:   /* Secondary LE */
-    case ASI_PNFL: /* Primary no-fault LE */
-    case ASI_SNFL: /* Secondary no-fault LE */
+    case 0x88: /* Primary LE */
+    case 0x89: /* Secondary LE */
+    case 0x8a: /* Primary no-fault LE */
+    case 0x8b: /* Secondary no-fault LE */
         switch (size) {
         case 2:
             ret = bswap16(ret);
@@ -1211,9 +1201,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
 }
 
 void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
-                   int asi, uint32_t memop)
+                   int asi, int size)
 {
-    int size = 1 << (memop & MO_SIZE);
 #ifdef DEBUG_ASI
     dump_asi("write", addr, asi, size, val);
 #endif
@@ -1226,8 +1215,8 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
 
     /* Convert to little endian */
     switch (asi) {
-    case ASI_PL: /* Primary LE */
-    case ASI_SL: /* Secondary LE */
+    case 0x88: /* Primary LE */
+    case 0x89: /* Secondary LE */
         switch (size) {
         case 2:
             val = bswap16(val);
@@ -1246,8 +1235,8 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
     }
 
     switch (asi) {
-    case ASI_P:  /* Primary */
-    case ASI_PL: /* Primary LE */
+    case 0x80: /* Primary */
+    case 0x88: /* Primary LE */
         {
             switch (size) {
             case 1:
@@ -1266,15 +1255,15 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
             }
         }
         break;
-    case ASI_S:  /* Secondary */
-    case ASI_SL: /* Secondary LE */
+    case 0x81: /* Secondary */
+    case 0x89: /* Secondary LE */
         /* XXX */
         return;
 
-    case ASI_PNF:  /* Primary no-fault, RO */
-    case ASI_SNF:  /* Secondary no-fault, RO */
-    case ASI_PNFL: /* Primary no-fault LE, RO */
-    case ASI_SNFL: /* Secondary no-fault LE, RO */
+    case 0x82: /* Primary no-fault, RO */
+    case 0x83: /* Secondary no-fault, RO */
+    case 0x8a: /* Primary no-fault LE, RO */
+    case 0x8b: /* Secondary no-fault LE, RO */
     default:
         helper_raise_exception(env, TT_DATA_ACCESS);
         return;
@@ -1283,11 +1272,9 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
 
 #else /* CONFIG_USER_ONLY */
 
-uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
-                       int asi, uint32_t memop)
+uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
+                       int sign)
 {
-    int size = 1 << (memop & MO_SIZE);
-    int sign = memop & MO_SIGN;
     CPUState *cs = CPU(sparc_env_get_cpu(env));
     uint64_t ret = 0;
 #if defined(DEBUG_ASI)
@@ -1330,14 +1317,16 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
     }
 
     switch (asi) {
-    case ASI_AIUP:  /* As if user primary */
-    case ASI_AIUS:  /* As if user secondary */
-    case ASI_AIUPL: /* As if user primary LE */
-    case ASI_AIUSL: /* As if user secondary LE */
-    case ASI_P:  /* Primary */
-    case ASI_S:  /* Secondary */
-    case ASI_PL: /* Primary LE */
-    case ASI_SL: /* Secondary LE */
+    case 0x10: /* As if user primary */
+    case 0x11: /* As if user secondary */
+    case 0x18: /* As if user primary LE */
+    case 0x19: /* As if user secondary LE */
+    case 0x80: /* Primary */
+    case 0x81: /* Secondary */
+    case 0x88: /* Primary LE */
+    case 0x89: /* Secondary LE */
+    case 0xe2: /* UA2007 Primary block init */
+    case 0xe3: /* UA2007 Secondary block init */
         if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
             if (cpu_hypervisor_mode(env)) {
                 switch (size) {
@@ -1428,10 +1417,10 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             }
         }
         break;
-    case ASI_REAL:        /* Bypass */
-    case ASI_REAL_IO:   /* Bypass, non-cacheable */
-    case ASI_REAL_L:      /* Bypass LE */
-    case ASI_REAL_IO_L: /* Bypass, non-cacheable LE */
+    case 0x14: /* Bypass */
+    case 0x15: /* Bypass, non-cacheable */
+    case 0x1c: /* Bypass LE */
+    case 0x1d: /* Bypass, non-cacheable LE */
         {
             switch (size) {
             case 1:
@@ -1450,8 +1439,13 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             }
             break;
         }
-    case ASI_N:  /* Nucleus */
-    case ASI_NL: /* Nucleus Little Endian (LE) */
+    case 0x24: /* Nucleus quad LDD 128 bit atomic */
+    case 0x2c: /* Nucleus quad LDD 128 bit atomic LE
+                  Only ldda allowed */
+        helper_raise_exception(env, TT_ILL_INSN);
+        return 0;
+    case 0x04: /* Nucleus */
+    case 0x0c: /* Nucleus Little Endian (LE) */
         {
             switch (size) {
             case 1:
@@ -1470,13 +1464,13 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             }
             break;
         }
-    case ASI_UPA_CONFIG: /* UPA config */
+    case 0x4a: /* UPA config */
         /* XXX */
         break;
-    case ASI_LSU_CONTROL: /* LSU */
+    case 0x45: /* LSU */
         ret = env->lsu;
         break;
-    case ASI_IMMU: /* I-MMU regs */
+    case 0x50: /* I-MMU regs */
         {
             int reg = (addr >> 3) & 0xf;
 
@@ -1489,7 +1483,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
 
             break;
         }
-    case ASI_IMMU_TSB_8KB_PTR: /* I-MMU 8k TSB pointer */
+    case 0x51: /* I-MMU 8k TSB pointer */
         {
             /* env->immuregs[5] holds I-MMU TSB register value
                env->immuregs[6] holds I-MMU Tag Access register value */
@@ -1497,7 +1491,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
                                          8*1024);
             break;
         }
-    case ASI_IMMU_TSB_64KB_PTR: /* I-MMU 64k TSB pointer */
+    case 0x52: /* I-MMU 64k TSB pointer */
         {
             /* env->immuregs[5] holds I-MMU TSB register value
                env->immuregs[6] holds I-MMU Tag Access register value */
@@ -1505,21 +1499,21 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
                                          64*1024);
             break;
         }
-    case ASI_ITLB_DATA_ACCESS: /* I-MMU data access */
+    case 0x55: /* I-MMU data access */
         {
             int reg = (addr >> 3) & 0x3f;
 
             ret = env->itlb[reg].tte;
             break;
         }
-    case ASI_ITLB_TAG_READ: /* I-MMU tag read */
+    case 0x56: /* I-MMU tag read */
         {
             int reg = (addr >> 3) & 0x3f;
 
             ret = env->itlb[reg].tag;
             break;
         }
-    case ASI_DMMU: /* D-MMU regs */
+    case 0x58: /* D-MMU regs */
         {
             int reg = (addr >> 3) & 0xf;
 
@@ -1531,7 +1525,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             }
             break;
         }
-    case ASI_DMMU_TSB_8KB_PTR: /* D-MMU 8k TSB pointer */
+    case 0x59: /* D-MMU 8k TSB pointer */
         {
             /* env->dmmuregs[5] holds D-MMU TSB register value
                env->dmmuregs[6] holds D-MMU Tag Access register value */
@@ -1539,7 +1533,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
                                          8*1024);
             break;
         }
-    case ASI_DMMU_TSB_64KB_PTR: /* D-MMU 64k TSB pointer */
+    case 0x5a: /* D-MMU 64k TSB pointer */
         {
             /* env->dmmuregs[5] holds D-MMU TSB register value
                env->dmmuregs[6] holds D-MMU Tag Access register value */
@@ -1547,26 +1541,26 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
                                          64*1024);
             break;
         }
-    case ASI_DTLB_DATA_ACCESS: /* D-MMU data access */
+    case 0x5d: /* D-MMU data access */
         {
             int reg = (addr >> 3) & 0x3f;
 
             ret = env->dtlb[reg].tte;
             break;
         }
-    case ASI_DTLB_TAG_READ: /* D-MMU tag read */
+    case 0x5e: /* D-MMU tag read */
         {
             int reg = (addr >> 3) & 0x3f;
 
             ret = env->dtlb[reg].tag;
             break;
         }
-    case ASI_INTR_DISPATCH_STAT: /* Interrupt dispatch, RO */
+    case 0x48: /* Interrupt dispatch, RO */
         break;
-    case ASI_INTR_RECEIVE: /* Interrupt data receive */
+    case 0x49: /* Interrupt data receive */
         ret = env->ivec_status;
         break;
-    case ASI_INTR_R: /* Incoming interrupt vector, RO */
+    case 0x7f: /* Incoming interrupt vector, RO */
         {
             int reg = (addr >> 4) & 0x3;
             if (reg < 3) {
@@ -1574,59 +1568,40 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             }
             break;
         }
-    case ASI_DCACHE_DATA:     /* D-cache data */
-    case ASI_DCACHE_TAG:      /* D-cache tag access */
-    case ASI_ESTATE_ERROR_EN: /* E-cache error enable */
-    case ASI_AFSR:            /* E-cache asynchronous fault status */
-    case ASI_AFAR:            /* E-cache asynchronous fault address */
-    case ASI_EC_TAG_DATA:     /* E-cache tag data */
-    case ASI_IC_INSTR:        /* I-cache instruction access */
-    case ASI_IC_TAG:          /* I-cache tag access */
-    case ASI_IC_PRE_DECODE:   /* I-cache predecode */
-    case ASI_IC_NEXT_FIELD:   /* I-cache LRU etc. */
-    case ASI_EC_W:            /* E-cache tag */
-    case ASI_EC_R:            /* E-cache tag */
-        break;
-    case ASI_DMMU_TSB_DIRECT_PTR: /* D-MMU data pointer */
-    case ASI_ITLB_DATA_IN:        /* I-MMU data in, WO */
-    case ASI_IMMU_DEMAP:          /* I-MMU demap, WO */
-    case ASI_DTLB_DATA_IN:        /* D-MMU data in, WO */
-    case ASI_DMMU_DEMAP:          /* D-MMU demap, WO */
-    case ASI_INTR_W:              /* Interrupt vector, WO */
+    case 0x46: /* D-cache data */
+    case 0x47: /* D-cache tag access */
+    case 0x4b: /* E-cache error enable */
+    case 0x4c: /* E-cache asynchronous fault status */
+    case 0x4d: /* E-cache asynchronous fault address */
+    case 0x4e: /* E-cache tag data */
+    case 0x66: /* I-cache instruction access */
+    case 0x67: /* I-cache tag access */
+    case 0x6e: /* I-cache predecode */
+    case 0x6f: /* I-cache LRU etc. */
+    case 0x76: /* E-cache tag */
+    case 0x7e: /* E-cache tag */
+        break;
+    case 0x5b: /* D-MMU data pointer */
+    case 0x54: /* I-MMU data in, WO */
+    case 0x57: /* I-MMU demap, WO */
+    case 0x5c: /* D-MMU data in, WO */
+    case 0x5f: /* D-MMU demap, WO */
+    case 0x77: /* Interrupt vector, WO */
     default:
         cpu_unassigned_access(cs, addr, false, false, 1, size);
         ret = 0;
         break;
-
-    case ASI_NUCLEUS_QUAD_LDD:   /* Nucleus quad LDD 128 bit atomic */
-    case ASI_NUCLEUS_QUAD_LDD_L: /* Nucleus quad LDD 128 bit atomic LE */
-    case ASI_TWINX_AIUP:   /* As if user primary, twinx */
-    case ASI_TWINX_AIUS:   /* As if user secondary, twinx */
-    case ASI_TWINX_REAL:   /* Real address, twinx */
-    case ASI_TWINX_AIUP_L: /* As if user primary, twinx, LE */
-    case ASI_TWINX_AIUS_L: /* As if user secondary, twinx, LE */
-    case ASI_TWINX_REAL_L: /* Real address, twinx, LE */
-    case ASI_TWINX_N:  /* Nucleus, twinx */
-    case ASI_TWINX_NL: /* Nucleus, twinx, LE */
-    /* ??? From the UA2011 document; overlaps BLK_INIT_QUAD_LDD_* */
-    case ASI_TWINX_P:  /* Primary, twinx */
-    case ASI_TWINX_PL: /* Primary, twinx, LE */
-    case ASI_TWINX_S:  /* Secondary, twinx */
-    case ASI_TWINX_SL: /* Secondary, twinx, LE */
-        /* These are all 128-bit atomic; only ldda (now ldtxa) allowed */
-        helper_raise_exception(env, TT_ILL_INSN);
-        return 0;
     }
 
     /* Convert from little endian */
     switch (asi) {
-    case ASI_NL: /* Nucleus Little Endian (LE) */
-    case ASI_AIUPL: /* As if user primary LE */
-    case ASI_AIUSL: /* As if user secondary LE */
-    case ASI_REAL_L:      /* Bypass LE */
-    case ASI_REAL_IO_L: /* Bypass, non-cacheable LE */
-    case ASI_PL: /* Primary LE */
-    case ASI_SL: /* Secondary LE */
+    case 0x0c: /* Nucleus Little Endian (LE) */
+    case 0x18: /* As if user primary LE */
+    case 0x19: /* As if user secondary LE */
+    case 0x1c: /* Bypass LE */
+    case 0x1d: /* Bypass, non-cacheable LE */
+    case 0x88: /* Primary LE */
+    case 0x89: /* Secondary LE */
         switch(size) {
         case 2:
             ret = bswap16(ret);
@@ -1667,9 +1642,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
 }
 
 void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
-                   int asi, uint32_t memop)
+                   int asi, int size)
 {
-    int size = 1 << (memop & MO_SIZE);
     SPARCCPU *cpu = sparc_env_get_cpu(env);
     CPUState *cs = CPU(cpu);
 
@@ -1691,13 +1665,13 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
 
     /* Convert to little endian */
     switch (asi) {
-    case ASI_NL: /* Nucleus Little Endian (LE) */
-    case ASI_AIUPL: /* As if user primary LE */
-    case ASI_AIUSL: /* As if user secondary LE */
-    case ASI_REAL_L: /* Bypass LE */
-    case ASI_REAL_IO_L: /* Bypass, non-cacheable LE */
-    case ASI_PL: /* Primary LE */
-    case ASI_SL: /* Secondary LE */
+    case 0x0c: /* Nucleus Little Endian (LE) */
+    case 0x18: /* As if user primary LE */
+    case 0x19: /* As if user secondary LE */
+    case 0x1c: /* Bypass LE */
+    case 0x1d: /* Bypass, non-cacheable LE */
+    case 0x88: /* Primary LE */
+    case 0x89: /* Secondary LE */
         switch (size) {
         case 2:
             val = bswap16(val);
@@ -1716,14 +1690,16 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
     }
 
     switch (asi) {
-    case ASI_AIUP:  /* As if user primary */
-    case ASI_AIUS:  /* As if user secondary */
-    case ASI_AIUPL: /* As if user primary LE */
-    case ASI_AIUSL: /* As if user secondary LE */
-    case ASI_P:  /* Primary */
-    case ASI_S:  /* Secondary */
-    case ASI_PL: /* Primary LE */
-    case ASI_SL: /* Secondary LE */
+    case 0x10: /* As if user primary */
+    case 0x11: /* As if user secondary */
+    case 0x18: /* As if user primary LE */
+    case 0x19: /* As if user secondary LE */
+    case 0x80: /* Primary */
+    case 0x81: /* Secondary */
+    case 0x88: /* Primary LE */
+    case 0x89: /* Secondary LE */
+    case 0xe2: /* UA2007 Primary block init */
+    case 0xe3: /* UA2007 Secondary block init */
         if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
             if (cpu_hypervisor_mode(env)) {
                 switch (size) {
@@ -1814,10 +1790,10 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
             }
         }
         break;
-    case ASI_REAL:      /* Bypass */
-    case ASI_REAL_IO:   /* Bypass, non-cacheable */
-    case ASI_REAL_L:    /* Bypass LE */
-    case ASI_REAL_IO_L: /* Bypass, non-cacheable LE */
+    case 0x14: /* Bypass */
+    case 0x15: /* Bypass, non-cacheable */
+    case 0x1c: /* Bypass LE */
+    case 0x1d: /* Bypass, non-cacheable LE */
         {
             switch (size) {
             case 1:
@@ -1836,8 +1812,13 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
             }
         }
         return;
-    case ASI_N:  /* Nucleus */
-    case ASI_NL: /* Nucleus Little Endian (LE) */
+    case 0x24: /* Nucleus quad LDD 128 bit atomic */
+    case 0x2c: /* Nucleus quad LDD 128 bit atomic LE
+                  Only ldda allowed */
+        helper_raise_exception(env, TT_ILL_INSN);
+        return;
+    case 0x04: /* Nucleus */
+    case 0x0c: /* Nucleus Little Endian (LE) */
         {
             switch (size) {
             case 1:
@@ -1857,10 +1838,10 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
             break;
         }
 
-    case ASI_UPA_CONFIG: /* UPA config */
+    case 0x4a: /* UPA config */
         /* XXX */
         return;
-    case ASI_LSU_CONTROL: /* LSU */
+    case 0x45: /* LSU */
         {
             uint64_t oldreg;
 
@@ -1878,7 +1859,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
             }
             return;
         }
-    case ASI_IMMU: /* I-MMU regs */
+    case 0x50: /* I-MMU regs */
         {
             int reg = (addr >> 3) & 0xf;
             uint64_t oldreg;
@@ -1922,10 +1903,10 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
 #endif
             return;
         }
-    case ASI_ITLB_DATA_IN: /* I-MMU data in */
+    case 0x54: /* I-MMU data in */
         replace_tlb_1bit_lru(env->itlb, env->immu.tag_access, val, "immu", env);
         return;
-    case ASI_ITLB_DATA_ACCESS: /* I-MMU data access */
+    case 0x55: /* I-MMU data access */
         {
             /* TODO: auto demap */
 
@@ -1939,10 +1920,10 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
 #endif
             return;
         }
-    case ASI_IMMU_DEMAP: /* I-MMU demap */
+    case 0x57: /* I-MMU demap */
         demap_tlb(env->itlb, addr, "immu", env);
         return;
-    case ASI_DMMU: /* D-MMU regs */
+    case 0x58: /* D-MMU regs */
         {
             int reg = (addr >> 3) & 0xf;
             uint64_t oldreg;
@@ -1995,10 +1976,10 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
 #endif
             return;
         }
-    case ASI_DTLB_DATA_IN: /* D-MMU data in */
+    case 0x5c: /* D-MMU data in */
         replace_tlb_1bit_lru(env->dtlb, env->dmmu.tag_access, val, "dmmu", env);
         return;
-    case ASI_DTLB_DATA_ACCESS: /* D-MMU data access */
+    case 0x5d: /* D-MMU data access */
         {
             unsigned int i = (addr >> 3) & 0x3f;
 
@@ -2010,56 +1991,38 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
 #endif
             return;
         }
-    case ASI_DMMU_DEMAP: /* D-MMU demap */
+    case 0x5f: /* D-MMU demap */
         demap_tlb(env->dtlb, addr, "dmmu", env);
         return;
-    case ASI_INTR_RECEIVE: /* Interrupt data receive */
+    case 0x49: /* Interrupt data receive */
         env->ivec_status = val & 0x20;
         return;
-    case ASI_NUCLEUS_QUAD_LDD:   /* Nucleus quad LDD 128 bit atomic */
-    case ASI_NUCLEUS_QUAD_LDD_L: /* Nucleus quad LDD 128 bit atomic LE */
-    case ASI_TWINX_AIUP:   /* As if user primary, twinx */
-    case ASI_TWINX_AIUS:   /* As if user secondary, twinx */
-    case ASI_TWINX_REAL:   /* Real address, twinx */
-    case ASI_TWINX_AIUP_L: /* As if user primary, twinx, LE */
-    case ASI_TWINX_AIUS_L: /* As if user secondary, twinx, LE */
-    case ASI_TWINX_REAL_L: /* Real address, twinx, LE */
-    case ASI_TWINX_N:  /* Nucleus, twinx */
-    case ASI_TWINX_NL: /* Nucleus, twinx, LE */
-    /* ??? From the UA2011 document; overlaps BLK_INIT_QUAD_LDD_* */
-    case ASI_TWINX_P:  /* Primary, twinx */
-    case ASI_TWINX_PL: /* Primary, twinx, LE */
-    case ASI_TWINX_S:  /* Secondary, twinx */
-    case ASI_TWINX_SL: /* Secondary, twinx, LE */
-        /* Only stda allowed */
-        helper_raise_exception(env, TT_ILL_INSN);
-        return;
-    case ASI_DCACHE_DATA: /* D-cache data */
-    case ASI_DCACHE_TAG: /* D-cache tag access */
-    case ASI_ESTATE_ERROR_EN: /* E-cache error enable */
-    case ASI_AFSR: /* E-cache asynchronous fault status */
-    case ASI_AFAR: /* E-cache asynchronous fault address */
-    case ASI_EC_TAG_DATA: /* E-cache tag data */
-    case ASI_IC_INSTR: /* I-cache instruction access */
-    case ASI_IC_TAG: /* I-cache tag access */
-    case ASI_IC_PRE_DECODE: /* I-cache predecode */
-    case ASI_IC_NEXT_FIELD: /* I-cache LRU etc. */
-    case ASI_EC_W: /* E-cache tag */
-    case ASI_EC_R: /* E-cache tag */
+    case 0x46: /* D-cache data */
+    case 0x47: /* D-cache tag access */
+    case 0x4b: /* E-cache error enable */
+    case 0x4c: /* E-cache asynchronous fault status */
+    case 0x4d: /* E-cache asynchronous fault address */
+    case 0x4e: /* E-cache tag data */
+    case 0x66: /* I-cache instruction access */
+    case 0x67: /* I-cache tag access */
+    case 0x6e: /* I-cache predecode */
+    case 0x6f: /* I-cache LRU etc. */
+    case 0x76: /* E-cache tag */
+    case 0x7e: /* E-cache tag */
         return;
-    case ASI_IMMU_TSB_8KB_PTR: /* I-MMU 8k TSB pointer, RO */
-    case ASI_IMMU_TSB_64KB_PTR: /* I-MMU 64k TSB pointer, RO */
-    case ASI_ITLB_TAG_READ: /* I-MMU tag read, RO */
-    case ASI_DMMU_TSB_8KB_PTR: /* D-MMU 8k TSB pointer, RO */
-    case ASI_DMMU_TSB_64KB_PTR: /* D-MMU 64k TSB pointer, RO */
-    case ASI_DMMU_TSB_DIRECT_PTR: /* D-MMU data pointer, RO */
-    case ASI_DTLB_TAG_READ: /* D-MMU tag read, RO */
-    case ASI_INTR_DISPATCH_STAT: /* Interrupt dispatch, RO */
-    case ASI_INTR_R: /* Incoming interrupt vector, RO */
-    case ASI_PNF: /* Primary no-fault, RO */
-    case ASI_SNF: /* Secondary no-fault, RO */
-    case ASI_PNFL: /* Primary no-fault LE, RO */
-    case ASI_SNFL: /* Secondary no-fault LE, RO */
+    case 0x51: /* I-MMU 8k TSB pointer, RO */
+    case 0x52: /* I-MMU 64k TSB pointer, RO */
+    case 0x56: /* I-MMU tag read, RO */
+    case 0x59: /* D-MMU 8k TSB pointer, RO */
+    case 0x5a: /* D-MMU 64k TSB pointer, RO */
+    case 0x5b: /* D-MMU data pointer, RO */
+    case 0x5e: /* D-MMU tag read, RO */
+    case 0x48: /* Interrupt dispatch, RO */
+    case 0x7f: /* Incoming interrupt vector, RO */
+    case 0x82: /* Primary no-fault, RO */
+    case 0x83: /* Secondary no-fault, RO */
+    case 0x8a: /* Primary no-fault LE, RO */
+    case 0x8b: /* Secondary no-fault LE, RO */
     default:
         cpu_unassigned_access(cs, addr, true, false, 1, size);
         return;
@@ -2067,11 +2030,8 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
 }
 #endif /* CONFIG_USER_ONLY */
 
-/* 128-bit LDDA; result returned in QT0.  */
-void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi)
+void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi, int rd)
 {
-    uint64_t h, l;
-
     if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
         || (cpu_has_hypervisor(env)
             && asi >= 0x30 && asi < 0x80
@@ -2083,82 +2043,191 @@ void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi)
 
     switch (asi) {
 #if !defined(CONFIG_USER_ONLY)
-    case ASI_TWINX_AIUP:   /* As if user primary, twinx */
-    case ASI_TWINX_AIUP_L: /* As if user primary, twinx, LE */
-        helper_check_align(env, addr, 0xf);
-        h = cpu_ldq_user(env, addr);
-        l = cpu_ldq_user(env, addr + 8);
-        break;
-    case ASI_TWINX_AIUS:   /* As if user secondary, twinx */
-    case ASI_TWINX_AIUS_L: /* As if user secondary, twinx, LE */
+    case 0x24: /* Nucleus quad LDD 128 bit atomic */
+    case 0x2c: /* Nucleus quad LDD 128 bit atomic LE */
         helper_check_align(env, addr, 0xf);
-        h = cpu_ldq_user_secondary(env, addr);
-        l = cpu_ldq_user_secondary(env, addr + 8);
+        if (rd == 0) {
+            env->gregs[1] = cpu_ldq_nucleus(env, addr + 8);
+            if (asi == 0x2c) {
+                bswap64s(&env->gregs[1]);
+            }
+        } else if (rd < 8) {
+            env->gregs[rd] = cpu_ldq_nucleus(env, addr);
+            env->gregs[rd + 1] = cpu_ldq_nucleus(env, addr + 8);
+            if (asi == 0x2c) {
+                bswap64s(&env->gregs[rd]);
+                bswap64s(&env->gregs[rd + 1]);
+            }
+        } else {
+            env->regwptr[rd - 8] = cpu_ldq_nucleus(env, addr);
+            env->regwptr[rd + 1 - 8] = cpu_ldq_nucleus(env, addr + 8);
+            if (asi == 0x2c) {
+                bswap64s(&env->regwptr[rd - 8]);
+                bswap64s(&env->regwptr[rd + 1 - 8]);
+            }
+        }
         break;
-    case ASI_TWINX_REAL:   /* Real address, twinx */
-    case ASI_TWINX_REAL_L: /* Real address, twinx, LE */
-        helper_check_align(env, addr, 0xf);
-        {
-            CPUState *cs = CPU(sparc_env_get_cpu(env));
-            h = ldq_phys(cs->as, addr);
-            l = ldq_phys(cs->as, addr + 8);
+#endif
+    default:
+        helper_check_align(env, addr, 0x3);
+        if (rd == 0) {
+            env->gregs[1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
+        } else if (rd < 8) {
+            env->gregs[rd] = helper_ld_asi(env, addr, asi, 4, 0);
+            env->gregs[rd + 1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
+        } else {
+            env->regwptr[rd - 8] = helper_ld_asi(env, addr, asi, 4, 0);
+            env->regwptr[rd + 1 - 8] = helper_ld_asi(env, addr + 4, asi, 4, 0);
         }
         break;
-    case ASI_NUCLEUS_QUAD_LDD:
-    case ASI_NUCLEUS_QUAD_LDD_L:
-    case ASI_TWINX_N:  /* Nucleus, twinx */
-    case ASI_TWINX_NL: /* Nucleus, twinx, LE */
-        helper_check_align(env, addr, 0xf);
-        h = cpu_ldq_nucleus(env, addr);
-        l = cpu_ldq_nucleus(env, addr + 8);
-        break;
-    case ASI_TWINX_S: /* Secondary, twinx */
-    case ASI_TWINX_SL: /* Secondary, twinx, LE */
-        if (!cpu_hypervisor_mode(env)) {
-            helper_check_align(env, addr, 0xf);
-            if (env->pstate & PS_PRIV) {
-                h = cpu_ldq_kernel_secondary(env, addr);
-                l = cpu_ldq_kernel_secondary(env, addr + 8);
-            } else {
-                h = cpu_ldq_user_secondary(env, addr);
-                l = cpu_ldq_user_secondary(env, addr + 8);
-            }
-            break;
+    }
+}
+
+void helper_ldf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
+                    int rd)
+{
+    unsigned int i;
+    target_ulong val;
+
+    helper_check_align(env, addr, 3);
+    addr = asi_address_mask(env, asi, addr);
+
+    switch (asi) {
+    case 0xf0: /* UA2007/JPS1 Block load primary */
+    case 0xf1: /* UA2007/JPS1 Block load secondary */
+    case 0xf8: /* UA2007/JPS1 Block load primary LE */
+    case 0xf9: /* UA2007/JPS1 Block load secondary LE */
+        if (rd & 7) {
+            helper_raise_exception(env, TT_ILL_INSN);
+            return;
         }
-        /* fallthru */
-    case ASI_TWINX_P:  /* Primary, twinx */
-    case ASI_TWINX_PL: /* Primary, twinx, LE */
-        helper_check_align(env, addr, 0xf);
-        h = cpu_ldq_data(env, addr);
-        l = cpu_ldq_data(env, addr + 8);
+        helper_check_align(env, addr, 0x3f);
+        for (i = 0; i < 8; i++, rd += 2, addr += 8) {
+            env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi & 0x8f, 8, 0);
+        }
+        return;
+
+    case 0x16: /* UA2007 Block load primary, user privilege */
+    case 0x17: /* UA2007 Block load secondary, user privilege */
+    case 0x1e: /* UA2007 Block load primary LE, user privilege */
+    case 0x1f: /* UA2007 Block load secondary LE, user privilege */
+    case 0x70: /* JPS1 Block load primary, user privilege */
+    case 0x71: /* JPS1 Block load secondary, user privilege */
+    case 0x78: /* JPS1 Block load primary LE, user privilege */
+    case 0x79: /* JPS1 Block load secondary LE, user privilege */
+        if (rd & 7) {
+            helper_raise_exception(env, TT_ILL_INSN);
+            return;
+        }
+        helper_check_align(env, addr, 0x3f);
+        for (i = 0; i < 8; i++, rd += 2, addr += 8) {
+            env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi & 0x19, 8, 0);
+        }
+        return;
+
+    default:
         break;
-#else
-    case ASI_TWINX_P:  /* Primary, twinx */
-    case ASI_TWINX_PL: /* Primary, twinx, LE */
-    case ASI_TWINX_S:  /* Primary, twinx */
-    case ASI_TWINX_SL: /* Primary, twinx, LE */
-        /* ??? Should be available, but we need to implement
-           an atomic 128-bit load.  */
-        helper_raise_exception(env, TT_PRIV_ACT);
-#endif
+    }
+
+    switch (size) {
     default:
-        /* Non-twinx asi, so this is the legacy ldda insn, which
-           performs two word sized operations.  */
-        /* ??? The UA2011 manual recommends emulating this with
-           a single 64-bit load.  However, LE asis *are* treated
-           as two 32-bit loads individually byte swapped.  */
-        helper_check_align(env, addr, 0x7);
-        QT0.high = (uint32_t)helper_ld_asi(env, addr, asi, MO_UL);
-        QT0.low = (uint32_t)helper_ld_asi(env, addr + 4, asi, MO_UL);
+    case 4:
+        val = helper_ld_asi(env, addr, asi, size, 0);
+        if (rd & 1) {
+            env->fpr[rd / 2].l.lower = val;
+        } else {
+            env->fpr[rd / 2].l.upper = val;
+        }
+        break;
+    case 8:
+        env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi, size, 0);
+        break;
+    case 16:
+        env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi, 8, 0);
+        env->fpr[rd / 2 + 1].ll = helper_ld_asi(env, addr + 8, asi, 8, 0);
+        break;
+    }
+}
+
+void helper_stf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
+                    int rd)
+{
+    unsigned int i;
+    target_ulong val;
+
+    addr = asi_address_mask(env, asi, addr);
+
+    switch (asi) {
+    case 0xe0: /* UA2007/JPS1 Block commit store primary (cache flush) */
+    case 0xe1: /* UA2007/JPS1 Block commit store secondary (cache flush) */
+    case 0xf0: /* UA2007/JPS1 Block store primary */
+    case 0xf1: /* UA2007/JPS1 Block store secondary */
+    case 0xf8: /* UA2007/JPS1 Block store primary LE */
+    case 0xf9: /* UA2007/JPS1 Block store secondary LE */
+        if (rd & 7) {
+            helper_raise_exception(env, TT_ILL_INSN);
+            return;
+        }
+        helper_check_align(env, addr, 0x3f);
+        for (i = 0; i < 8; i++, rd += 2, addr += 8) {
+            helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi & 0x8f, 8);
+        }
+
+        return;
+    case 0x16: /* UA2007 Block load primary, user privilege */
+    case 0x17: /* UA2007 Block load secondary, user privilege */
+    case 0x1e: /* UA2007 Block load primary LE, user privilege */
+    case 0x1f: /* UA2007 Block load secondary LE, user privilege */
+    case 0x70: /* JPS1 Block store primary, user privilege */
+    case 0x71: /* JPS1 Block store secondary, user privilege */
+    case 0x78: /* JPS1 Block load primary LE, user privilege */
+    case 0x79: /* JPS1 Block load secondary LE, user privilege */
+        if (rd & 7) {
+            helper_raise_exception(env, TT_ILL_INSN);
+            return;
+        }
+        helper_check_align(env, addr, 0x3f);
+        for (i = 0; i < 8; i++, rd += 2, addr += 8) {
+            helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi & 0x19, 8);
+        }
+
+        return;
+    case 0xd2: /* 16-bit floating point load primary */
+    case 0xd3: /* 16-bit floating point load secondary */
+    case 0xda: /* 16-bit floating point load primary, LE */
+    case 0xdb: /* 16-bit floating point load secondary, LE */
+        helper_check_align(env, addr, 1);
+        /* Fall through */
+    case 0xd0: /* 8-bit floating point load primary */
+    case 0xd1: /* 8-bit floating point load secondary */
+    case 0xd8: /* 8-bit floating point load primary, LE */
+    case 0xd9: /* 8-bit floating point load secondary, LE */
+        val = env->fpr[rd / 2].l.lower;
+        helper_st_asi(env, addr, val, asi & 0x8d, ((asi & 2) >> 1) + 1);
         return;
+    default:
+        helper_check_align(env, addr, 3);
+        break;
     }
 
-    if (asi & 8) {
-        h = bswap64(h);
-        l = bswap64(l);
+    switch (size) {
+    default:
+    case 4:
+        if (rd & 1) {
+            val = env->fpr[rd / 2].l.lower;
+        } else {
+            val = env->fpr[rd / 2].l.upper;
+        }
+        helper_st_asi(env, addr, val, asi, size);
+        break;
+    case 8:
+        helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi, size);
+        break;
+    case 16:
+        helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi, 8);
+        helper_st_asi(env, addr + 8, env->fpr[rd / 2 + 1].ll, asi, 8);
+        break;
     }
-    QT0.high = h;
-    QT0.low = l;
 }
 
 target_ulong helper_casx_asi(CPUSPARCState *env, target_ulong addr,
@@ -2167,9 +2236,9 @@ target_ulong helper_casx_asi(CPUSPARCState *env, target_ulong addr,
 {
     target_ulong ret;
 
-    ret = helper_ld_asi(env, addr, asi, MO_Q);
+    ret = helper_ld_asi(env, addr, asi, 8, 0);
     if (val2 == ret) {
-        helper_st_asi(env, addr, val1, asi, MO_Q);
+        helper_st_asi(env, addr, val1, asi, 8);
     }
     return ret;
 }
@@ -2182,10 +2251,10 @@ target_ulong helper_cas_asi(CPUSPARCState *env, target_ulong addr,
     target_ulong ret;
 
     val2 &= 0xffffffffUL;
-    ret = helper_ld_asi(env, addr, asi, MO_UL);
+    ret = helper_ld_asi(env, addr, asi, 4, 0);
     ret &= 0xffffffffUL;
     if (val2 == ret) {
-        helper_st_asi(env, addr, val1 & 0xffffffffUL, asi, MO_UL);
+        helper_st_asi(env, addr, val1 & 0xffffffffUL, asi, 4);
     }
     return ret;
 }
@@ -2350,10 +2419,9 @@ void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr,
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
-void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
-                                                 MMUAccessType access_type,
-                                                 int mmu_idx,
-                                                 uintptr_t retaddr)
+void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cs,
+                                                 vaddr addr, int is_write,
+                                                 int is_user, uintptr_t retaddr)
 {
     SPARCCPU *cpu = SPARC_CPU(cs);
     CPUSPARCState *env = &cpu->env;
@@ -2372,12 +2440,12 @@ void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr)
 {
     int ret;
 
-    ret = sparc_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = sparc_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (ret) {
         if (retaddr) {
             cpu_restore_state(cs, retaddr);
index 59c92f7..1046016 100644 (file)
@@ -1,15 +1,9 @@
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
 #include "hw/hw.h"
 #include "hw/boards.h"
 #include "qemu/timer.h"
 
 #include "cpu.h"
-#include "exec/exec-all.h"
-#include "migration/cpu.h"
-#include "exec/exec-all.h"
 
 #ifdef TARGET_SPARC64
 static const VMStateDescription vmstate_cpu_timer = {
index 32b629f..aa80c48 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "trace.h"
 #include "exec/address-spaces.h"
 
diff --git a/target-sparc/trace-events b/target-sparc/trace-events
deleted file mode 100644 (file)
index bf52d97..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# target-sparc/mmu_helper.c
-mmu_helper_dfault(uint64_t address, uint64_t context, int mmu_idx, uint32_t tl) "DFAULT at %"PRIx64" context %"PRIx64" mmu_idx=%d tl=%d"
-mmu_helper_dprot(uint64_t address, uint64_t context, int mmu_idx, uint32_t tl) "DPROT at %"PRIx64" context %"PRIx64" mmu_idx=%d tl=%d"
-mmu_helper_dmiss(uint64_t address, uint64_t context) "DMISS at %"PRIx64" context %"PRIx64
-mmu_helper_tfault(uint64_t address, uint64_t context) "TFAULT at %"PRIx64" context %"PRIx64
-mmu_helper_tmiss(uint64_t address, uint64_t context) "TMISS at %"PRIx64" context %"PRIx64
-mmu_helper_get_phys_addr_code(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address) "tl=%d mmu_idx=%d primary context=%"PRIx64" secondary context=%"PRIx64" address=%"PRIx64
-mmu_helper_get_phys_addr_data(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address) "tl=%d mmu_idx=%d primary context=%"PRIx64" secondary context=%"PRIx64" address=%"PRIx64
-mmu_helper_mmu_fault(uint64_t address, uint64_t paddr, int mmu_idx, uint32_t tl, uint64_t prim_context, uint64_t sec_context) "Translate at %"PRIx64" -> %"PRIx64", mmu_idx=%d tl=%d primary context=%"PRIx64" secondary context=%"PRIx64
-
-# target-sparc/int64_helper.c
-int_helper_set_softint(uint32_t softint) "new %08x"
-int_helper_clear_softint(uint32_t softint) "new %08x"
-int_helper_write_softint(uint32_t softint) "new %08x"
-
-# target-sparc/int32_helper.c
-int_helper_icache_freeze(void) "Instruction cache: freeze"
-int_helper_dcache_freeze(void) "Data cache: freeze"
-
-# target-sparc/win_helper.c
-win_helper_gregset_error(uint32_t pstate) "ERROR in get_gregset: active pstate bits=%x"
-win_helper_switch_pstate(uint32_t pstate_regs, uint32_t new_pstate_regs) "change_pstate: switching regs old=%x new=%x"
-win_helper_no_switch_pstate(uint32_t new_pstate_regs) "change_pstate: regs new=%x (unchanged)"
-win_helper_wrpil(uint32_t psrpil, uint32_t new_pil) "old=%x new=%x"
-win_helper_done(uint32_t tl) "tl=%d"
-win_helper_retry(uint32_t tl) "tl=%d"
index e7691e4..502510c 100644 (file)
@@ -23,7 +23,6 @@
 #include "cpu.h"
 #include "disas/disas.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "exec/cpu_ldst.h"
 
@@ -31,7 +30,6 @@
 
 #include "trace-tcg.h"
 #include "exec/log.h"
-#include "asi.h"
 
 
 #define DEBUG_DISAS
@@ -54,10 +52,11 @@ static TCGv cpu_tbr;
 #endif
 static TCGv cpu_cond;
 #ifdef TARGET_SPARC64
-static TCGv_i32 cpu_xcc, cpu_fprs;
+static TCGv_i32 cpu_xcc, cpu_asi, cpu_fprs;
 static TCGv cpu_gsr;
 static TCGv cpu_tick_cmpr, cpu_stick_cmpr, cpu_hstick_cmpr;
 static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
+static TCGv_i32 cpu_softint;
 #else
 static TCGv cpu_wim;
 #endif
@@ -82,10 +81,6 @@ typedef struct DisasContext {
     TCGv ttl[5];
     int n_t32;
     int n_ttl;
-#ifdef TARGET_SPARC64
-    int fprs_dirty;
-    int asi;
-#endif
 } DisasContext;
 
 typedef struct {
@@ -141,16 +136,10 @@ static inline TCGv get_temp_tl(DisasContext *dc)
     return t;
 }
 
-static inline void gen_update_fprs_dirty(DisasContext *dc, int rd)
+static inline void gen_update_fprs_dirty(int rd)
 {
 #if defined(TARGET_SPARC64)
-    int bit = (rd < 32) ? 1 : 2;
-    /* If we know we've already set this bit within the TB,
-       we can avoid setting it again.  */
-    if (!(dc->fprs_dirty & bit)) {
-        dc->fprs_dirty |= bit;
-        tcg_gen_ori_i32(cpu_fprs, cpu_fprs, bit);
-    }
+    tcg_gen_ori_i32(cpu_fprs, cpu_fprs, (rd < 32) ? 1 : 2);
 #endif
 }
 
@@ -192,7 +181,7 @@ static void gen_store_fpr_F(DisasContext *dc, unsigned int dst, TCGv_i32 v)
     tcg_gen_deposit_i64(cpu_fpr[dst / 2], cpu_fpr[dst / 2], t,
                         (dst & 1 ? 0 : 32), 32);
 #endif
-    gen_update_fprs_dirty(dc, dst);
+    gen_update_fprs_dirty(dst);
 }
 
 static TCGv_i32 gen_dest_fpr_F(DisasContext *dc)
@@ -210,7 +199,7 @@ static void gen_store_fpr_D(DisasContext *dc, unsigned int dst, TCGv_i64 v)
 {
     dst = DFPREG(dst);
     tcg_gen_mov_i64(cpu_fpr[dst / 2], v);
-    gen_update_fprs_dirty(dc, dst);
+    gen_update_fprs_dirty(dst);
 }
 
 static TCGv_i64 gen_dest_fpr_D(DisasContext *dc, unsigned int dst)
@@ -243,14 +232,14 @@ static void gen_op_store_QT0_fpr(unsigned int dst)
 }
 
 #ifdef TARGET_SPARC64
-static void gen_move_Q(DisasContext *dc, unsigned int rd, unsigned int rs)
+static void gen_move_Q(unsigned int rd, unsigned int rs)
 {
     rd = QFPREG(rd);
     rs = QFPREG(rs);
 
     tcg_gen_mov_i64(cpu_fpr[rd / 2], cpu_fpr[rs / 2]);
     tcg_gen_mov_i64(cpu_fpr[rd / 2 + 1], cpu_fpr[rs / 2 + 1]);
-    gen_update_fprs_dirty(dc, rd);
+    gen_update_fprs_dirty(rd);
 }
 #endif
 
@@ -314,30 +303,20 @@ static inline TCGv gen_dest_gpr(DisasContext *dc, int reg)
     }
 }
 
-static inline bool use_goto_tb(DisasContext *s, target_ulong pc,
-                               target_ulong npc)
-{
-    if (unlikely(s->singlestep)) {
-        return false;
-    }
-
-#ifndef CONFIG_USER_ONLY
-    return (pc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) &&
-           (npc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
 static inline void gen_goto_tb(DisasContext *s, int tb_num,
                                target_ulong pc, target_ulong npc)
 {
-    if (use_goto_tb(s, pc, npc))  {
+    TranslationBlock *tb;
+
+    tb = s->tb;
+    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
+        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
+        !s->singlestep)  {
         /* jump to same page: we can use a direct jump */
         tcg_gen_goto_tb(tb_num);
         tcg_gen_movi_tl(cpu_pc, pc);
         tcg_gen_movi_tl(cpu_npc, npc);
-        tcg_gen_exit_tb((uintptr_t)s->tb + tb_num);
+        tcg_gen_exit_tb((uintptr_t)tb + tb_num);
     } else {
         /* jump to another page: currently not optimized */
         tcg_gen_movi_tl(cpu_pc, pc);
@@ -1054,24 +1033,6 @@ static inline void save_state(DisasContext *dc)
     save_npc(dc);
 }
 
-static void gen_exception(DisasContext *dc, int which)
-{
-    TCGv_i32 t;
-
-    save_state(dc);
-    t = tcg_const_i32(which);
-    gen_helper_raise_exception(cpu_env, t);
-    tcg_temp_free_i32(t);
-    dc->is_br = 1;
-}
-
-static void gen_check_align(TCGv addr, int mask)
-{
-    TCGv_i32 r_mask = tcg_const_i32(mask);
-    gen_helper_check_align(cpu_env, addr, r_mask);
-    tcg_temp_free_i32(r_mask);
-}
-
 static inline void gen_mov_pc_npc(DisasContext *dc)
 {
     if (dc->npc == JUMP_PC) {
@@ -1525,16 +1486,16 @@ static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
 {
     switch (fccno) {
     case 0:
-        gen_helper_fcmps(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmps(cpu_env, r_rs1, r_rs2);
         break;
     case 1:
-        gen_helper_fcmps_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmps_fcc1(cpu_env, r_rs1, r_rs2);
         break;
     case 2:
-        gen_helper_fcmps_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmps_fcc2(cpu_env, r_rs1, r_rs2);
         break;
     case 3:
-        gen_helper_fcmps_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmps_fcc3(cpu_env, r_rs1, r_rs2);
         break;
     }
 }
@@ -1543,16 +1504,16 @@ static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
 {
     switch (fccno) {
     case 0:
-        gen_helper_fcmpd(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmpd(cpu_env, r_rs1, r_rs2);
         break;
     case 1:
-        gen_helper_fcmpd_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmpd_fcc1(cpu_env, r_rs1, r_rs2);
         break;
     case 2:
-        gen_helper_fcmpd_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmpd_fcc2(cpu_env, r_rs1, r_rs2);
         break;
     case 3:
-        gen_helper_fcmpd_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmpd_fcc3(cpu_env, r_rs1, r_rs2);
         break;
     }
 }
@@ -1561,16 +1522,16 @@ static inline void gen_op_fcmpq(int fccno)
 {
     switch (fccno) {
     case 0:
-        gen_helper_fcmpq(cpu_fsr, cpu_env);
+        gen_helper_fcmpq(cpu_env);
         break;
     case 1:
-        gen_helper_fcmpq_fcc1(cpu_fsr, cpu_env);
+        gen_helper_fcmpq_fcc1(cpu_env);
         break;
     case 2:
-        gen_helper_fcmpq_fcc2(cpu_fsr, cpu_env);
+        gen_helper_fcmpq_fcc2(cpu_env);
         break;
     case 3:
-        gen_helper_fcmpq_fcc3(cpu_fsr, cpu_env);
+        gen_helper_fcmpq_fcc3(cpu_env);
         break;
     }
 }
@@ -1579,16 +1540,16 @@ static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
 {
     switch (fccno) {
     case 0:
-        gen_helper_fcmpes(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmpes(cpu_env, r_rs1, r_rs2);
         break;
     case 1:
-        gen_helper_fcmpes_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmpes_fcc1(cpu_env, r_rs1, r_rs2);
         break;
     case 2:
-        gen_helper_fcmpes_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmpes_fcc2(cpu_env, r_rs1, r_rs2);
         break;
     case 3:
-        gen_helper_fcmpes_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmpes_fcc3(cpu_env, r_rs1, r_rs2);
         break;
     }
 }
@@ -1597,16 +1558,16 @@ static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
 {
     switch (fccno) {
     case 0:
-        gen_helper_fcmped(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmped(cpu_env, r_rs1, r_rs2);
         break;
     case 1:
-        gen_helper_fcmped_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmped_fcc1(cpu_env, r_rs1, r_rs2);
         break;
     case 2:
-        gen_helper_fcmped_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmped_fcc2(cpu_env, r_rs1, r_rs2);
         break;
     case 3:
-        gen_helper_fcmped_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
+        gen_helper_fcmped_fcc3(cpu_env, r_rs1, r_rs2);
         break;
     }
 }
@@ -1615,16 +1576,16 @@ static inline void gen_op_fcmpeq(int fccno)
 {
     switch (fccno) {
     case 0:
-        gen_helper_fcmpeq(cpu_fsr, cpu_env);
+        gen_helper_fcmpeq(cpu_env);
         break;
     case 1:
-        gen_helper_fcmpeq_fcc1(cpu_fsr, cpu_env);
+        gen_helper_fcmpeq_fcc1(cpu_env);
         break;
     case 2:
-        gen_helper_fcmpeq_fcc2(cpu_fsr, cpu_env);
+        gen_helper_fcmpeq_fcc2(cpu_env);
         break;
     case 3:
-        gen_helper_fcmpeq_fcc3(cpu_fsr, cpu_env);
+        gen_helper_fcmpeq_fcc3(cpu_env);
         break;
     }
 }
@@ -1633,47 +1594,57 @@ static inline void gen_op_fcmpeq(int fccno)
 
 static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
 {
-    gen_helper_fcmps(cpu_fsr, cpu_env, r_rs1, r_rs2);
+    gen_helper_fcmps(cpu_env, r_rs1, r_rs2);
 }
 
 static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
 {
-    gen_helper_fcmpd(cpu_fsr, cpu_env, r_rs1, r_rs2);
+    gen_helper_fcmpd(cpu_env, r_rs1, r_rs2);
 }
 
 static inline void gen_op_fcmpq(int fccno)
 {
-    gen_helper_fcmpq(cpu_fsr, cpu_env);
+    gen_helper_fcmpq(cpu_env);
 }
 
 static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
 {
-    gen_helper_fcmpes(cpu_fsr, cpu_env, r_rs1, r_rs2);
+    gen_helper_fcmpes(cpu_env, r_rs1, r_rs2);
 }
 
 static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
 {
-    gen_helper_fcmped(cpu_fsr, cpu_env, r_rs1, r_rs2);
+    gen_helper_fcmped(cpu_env, r_rs1, r_rs2);
 }
 
 static inline void gen_op_fcmpeq(int fccno)
 {
-    gen_helper_fcmpeq(cpu_fsr, cpu_env);
+    gen_helper_fcmpeq(cpu_env);
 }
 #endif
 
-static void gen_op_fpexception_im(DisasContext *dc, int fsr_flags)
+static inline void gen_op_fpexception_im(int fsr_flags)
 {
+    TCGv_i32 r_const;
+
     tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
     tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
-    gen_exception(dc, TT_FP_EXCP);
+    r_const = tcg_const_i32(TT_FP_EXCP);
+    gen_helper_raise_exception(cpu_env, r_const);
+    tcg_temp_free_i32(r_const);
 }
 
 static int gen_trap_ifnofpu(DisasContext *dc)
 {
 #if !defined(CONFIG_USER_ONLY)
     if (!dc->fpu_enabled) {
-        gen_exception(dc, TT_NFPU_INSN);
+        TCGv_i32 r_const;
+
+        save_state(dc);
+        r_const = tcg_const_i32(TT_NFPU_INSN);
+        gen_helper_raise_exception(cpu_env, r_const);
+        tcg_temp_free_i32(r_const);
+        dc->is_br = 1;
         return 1;
     }
 #endif
@@ -1694,7 +1665,6 @@ static inline void gen_fop_FF(DisasContext *dc, int rd, int rs,
     dst = gen_dest_fpr_F(dc);
 
     gen(dst, cpu_env, src);
-    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
     gen_store_fpr_F(dc, rd, dst);
 }
@@ -1722,7 +1692,6 @@ static inline void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2,
     dst = gen_dest_fpr_F(dc);
 
     gen(dst, cpu_env, src1, src2);
-    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
     gen_store_fpr_F(dc, rd, dst);
 }
@@ -1752,7 +1721,6 @@ static inline void gen_fop_DD(DisasContext *dc, int rd, int rs,
     dst = gen_dest_fpr_D(dc, rd);
 
     gen(dst, cpu_env, src);
-    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
     gen_store_fpr_D(dc, rd, dst);
 }
@@ -1782,7 +1750,6 @@ static inline void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
     dst = gen_dest_fpr_D(dc, rd);
 
     gen(dst, cpu_env, src1, src2);
-    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
     gen_store_fpr_D(dc, rd, dst);
 }
@@ -1838,10 +1805,9 @@ static inline void gen_fop_QQ(DisasContext *dc, int rd, int rs,
     gen_op_load_fpr_QT1(QFPREG(rs));
 
     gen(cpu_env);
-    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
     gen_op_store_QT0_fpr(QFPREG(rd));
-    gen_update_fprs_dirty(dc, QFPREG(rd));
+    gen_update_fprs_dirty(QFPREG(rd));
 }
 
 #ifdef TARGET_SPARC64
@@ -1853,7 +1819,7 @@ static inline void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
     gen(cpu_env);
 
     gen_op_store_QT0_fpr(QFPREG(rd));
-    gen_update_fprs_dirty(dc, QFPREG(rd));
+    gen_update_fprs_dirty(QFPREG(rd));
 }
 #endif
 
@@ -1864,10 +1830,9 @@ static inline void gen_fop_QQQ(DisasContext *dc, int rd, int rs1, int rs2,
     gen_op_load_fpr_QT1(QFPREG(rs2));
 
     gen(cpu_env);
-    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
     gen_op_store_QT0_fpr(QFPREG(rd));
-    gen_update_fprs_dirty(dc, QFPREG(rd));
+    gen_update_fprs_dirty(QFPREG(rd));
 }
 
 static inline void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2,
@@ -1881,7 +1846,6 @@ static inline void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2,
     dst = gen_dest_fpr_D(dc, rd);
 
     gen(dst, cpu_env, src1, src2);
-    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
     gen_store_fpr_D(dc, rd, dst);
 }
@@ -1895,10 +1859,9 @@ static inline void gen_fop_QDD(DisasContext *dc, int rd, int rs1, int rs2,
     src2 = gen_load_fpr_D(dc, rs2);
 
     gen(cpu_env, src1, src2);
-    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
     gen_op_store_QT0_fpr(QFPREG(rd));
-    gen_update_fprs_dirty(dc, QFPREG(rd));
+    gen_update_fprs_dirty(QFPREG(rd));
 }
 
 #ifdef TARGET_SPARC64
@@ -1912,7 +1875,6 @@ static inline void gen_fop_DF(DisasContext *dc, int rd, int rs,
     dst = gen_dest_fpr_D(dc, rd);
 
     gen(dst, cpu_env, src);
-    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
     gen_store_fpr_D(dc, rd, dst);
 }
@@ -1942,7 +1904,6 @@ static inline void gen_fop_FD(DisasContext *dc, int rd, int rs,
     dst = gen_dest_fpr_F(dc);
 
     gen(dst, cpu_env, src);
-    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
     gen_store_fpr_F(dc, rd, dst);
 }
@@ -1956,7 +1917,6 @@ static inline void gen_fop_FQ(DisasContext *dc, int rd, int rs,
     dst = gen_dest_fpr_F(dc);
 
     gen(dst, cpu_env);
-    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
     gen_store_fpr_F(dc, rd, dst);
 }
@@ -1970,7 +1930,6 @@ static inline void gen_fop_DQ(DisasContext *dc, int rd, int rs,
     dst = gen_dest_fpr_D(dc, rd);
 
     gen(dst, cpu_env);
-    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
     gen_store_fpr_D(dc, rd, dst);
 }
@@ -1985,7 +1944,7 @@ static inline void gen_ne_fop_QF(DisasContext *dc, int rd, int rs,
     gen(cpu_env, src);
 
     gen_op_store_QT0_fpr(QFPREG(rd));
-    gen_update_fprs_dirty(dc, QFPREG(rd));
+    gen_update_fprs_dirty(QFPREG(rd));
 }
 
 static inline void gen_ne_fop_QD(DisasContext *dc, int rd, int rs,
@@ -1998,734 +1957,266 @@ static inline void gen_ne_fop_QD(DisasContext *dc, int rd, int rs,
     gen(cpu_env, src);
 
     gen_op_store_QT0_fpr(QFPREG(rd));
-    gen_update_fprs_dirty(dc, QFPREG(rd));
+    gen_update_fprs_dirty(QFPREG(rd));
 }
 
 /* asi moves */
-#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
-typedef enum {
-    GET_ASI_HELPER,
-    GET_ASI_EXCP,
-    GET_ASI_DIRECT,
-    GET_ASI_DTWINX,
-    GET_ASI_BLOCK,
-    GET_ASI_SHORT,
-} ASIType;
-
-typedef struct {
-    ASIType type;
-    int asi;
-    int mem_idx;
-    TCGMemOp memop;
-} DisasASI;
-
-static DisasASI get_asi(DisasContext *dc, int insn, TCGMemOp memop)
+#ifdef TARGET_SPARC64
+static inline TCGv_i32 gen_get_asi(int insn, TCGv r_addr)
 {
-    int asi = GET_FIELD(insn, 19, 26);
-    ASIType type = GET_ASI_HELPER;
-    int mem_idx = dc->mem_idx;
+    int asi;
+    TCGv_i32 r_asi;
 
-#ifndef TARGET_SPARC64
-    /* Before v9, all asis are immediate and privileged.  */
     if (IS_IMM) {
-        gen_exception(dc, TT_ILL_INSN);
-        type = GET_ASI_EXCP;
-    } else if (supervisor(dc)
-               /* Note that LEON accepts ASI_USERDATA in user mode, for
-                  use with CASA.  Also note that previous versions of
-                  QEMU allowed (and old versions of gcc emitted) ASI_P
-                  for LEON, which is incorrect.  */
-               || (asi == ASI_USERDATA
-                   && (dc->def->features & CPU_FEATURE_CASA))) {
-        switch (asi) {
-        case ASI_USERDATA:   /* User data access */
-            mem_idx = MMU_USER_IDX;
-            type = GET_ASI_DIRECT;
-            break;
-        case ASI_KERNELDATA: /* Supervisor data access */
-            mem_idx = MMU_KERNEL_IDX;
-            type = GET_ASI_DIRECT;
-            break;
-        }
+        r_asi = tcg_temp_new_i32();
+        tcg_gen_mov_i32(r_asi, cpu_asi);
     } else {
-        gen_exception(dc, TT_PRIV_INSN);
-        type = GET_ASI_EXCP;
-    }
-#else
-    if (IS_IMM) {
-        asi = dc->asi;
+        asi = GET_FIELD(insn, 19, 26);
+        r_asi = tcg_const_i32(asi);
     }
-    /* With v9, all asis below 0x80 are privileged.  */
-    /* ??? We ought to check cpu_has_hypervisor, but we didn't copy
-       down that bit into DisasContext.  For the moment that's ok,
-       since the direct implementations below doesn't have any ASIs
-       in the restricted [0x30, 0x7f] range, and the check will be
-       done properly in the helper.  */
-    if (!supervisor(dc) && asi < 0x80) {
-        gen_exception(dc, TT_PRIV_ACT);
-        type = GET_ASI_EXCP;
-    } else {
-        switch (asi) {
-        case ASI_N:  /* Nucleus */
-        case ASI_NL: /* Nucleus LE */
-        case ASI_TWINX_N:
-        case ASI_TWINX_NL:
-            mem_idx = MMU_NUCLEUS_IDX;
-            break;
-        case ASI_AIUP:  /* As if user primary */
-        case ASI_AIUPL: /* As if user primary LE */
-        case ASI_TWINX_AIUP:
-        case ASI_TWINX_AIUP_L:
-        case ASI_BLK_AIUP_4V:
-        case ASI_BLK_AIUP_L_4V:
-        case ASI_BLK_AIUP:
-        case ASI_BLK_AIUPL:
-            mem_idx = MMU_USER_IDX;
-            break;
-        case ASI_AIUS:  /* As if user secondary */
-        case ASI_AIUSL: /* As if user secondary LE */
-        case ASI_TWINX_AIUS:
-        case ASI_TWINX_AIUS_L:
-        case ASI_BLK_AIUS_4V:
-        case ASI_BLK_AIUS_L_4V:
-        case ASI_BLK_AIUS:
-        case ASI_BLK_AIUSL:
-            mem_idx = MMU_USER_SECONDARY_IDX;
-            break;
-        case ASI_S:  /* Secondary */
-        case ASI_SL: /* Secondary LE */
-        case ASI_TWINX_S:
-        case ASI_TWINX_SL:
-        case ASI_BLK_COMMIT_S:
-        case ASI_BLK_S:
-        case ASI_BLK_SL:
-        case ASI_FL8_S:
-        case ASI_FL8_SL:
-        case ASI_FL16_S:
-        case ASI_FL16_SL:
-            if (mem_idx == MMU_USER_IDX) {
-                mem_idx = MMU_USER_SECONDARY_IDX;
-            } else if (mem_idx == MMU_KERNEL_IDX) {
-                mem_idx = MMU_KERNEL_SECONDARY_IDX;
-            }
-            break;
-        case ASI_P:  /* Primary */
-        case ASI_PL: /* Primary LE */
-        case ASI_TWINX_P:
-        case ASI_TWINX_PL:
-        case ASI_BLK_COMMIT_P:
-        case ASI_BLK_P:
-        case ASI_BLK_PL:
-        case ASI_FL8_P:
-        case ASI_FL8_PL:
-        case ASI_FL16_P:
-        case ASI_FL16_PL:
-            break;
-        }
-        switch (asi) {
-        case ASI_N:
-        case ASI_NL:
-        case ASI_AIUP:
-        case ASI_AIUPL:
-        case ASI_AIUS:
-        case ASI_AIUSL:
-        case ASI_S:
-        case ASI_SL:
-        case ASI_P:
-        case ASI_PL:
-            type = GET_ASI_DIRECT;
-            break;
-        case ASI_TWINX_N:
-        case ASI_TWINX_NL:
-        case ASI_TWINX_AIUP:
-        case ASI_TWINX_AIUP_L:
-        case ASI_TWINX_AIUS:
-        case ASI_TWINX_AIUS_L:
-        case ASI_TWINX_P:
-        case ASI_TWINX_PL:
-        case ASI_TWINX_S:
-        case ASI_TWINX_SL:
-            type = GET_ASI_DTWINX;
-            break;
-        case ASI_BLK_COMMIT_P:
-        case ASI_BLK_COMMIT_S:
-        case ASI_BLK_AIUP_4V:
-        case ASI_BLK_AIUP_L_4V:
-        case ASI_BLK_AIUP:
-        case ASI_BLK_AIUPL:
-        case ASI_BLK_AIUS_4V:
-        case ASI_BLK_AIUS_L_4V:
-        case ASI_BLK_AIUS:
-        case ASI_BLK_AIUSL:
-        case ASI_BLK_S:
-        case ASI_BLK_SL:
-        case ASI_BLK_P:
-        case ASI_BLK_PL:
-            type = GET_ASI_BLOCK;
-            break;
-        case ASI_FL8_S:
-        case ASI_FL8_SL:
-        case ASI_FL8_P:
-        case ASI_FL8_PL:
-            memop = MO_UB;
-            type = GET_ASI_SHORT;
-            break;
-        case ASI_FL16_S:
-        case ASI_FL16_SL:
-        case ASI_FL16_P:
-        case ASI_FL16_PL:
-            memop = MO_TEUW;
-            type = GET_ASI_SHORT;
-            break;
-        }
-        /* The little-endian asis all have bit 3 set.  */
-        if (asi & 8) {
-            memop ^= MO_BSWAP;
-        }
-    }
-#endif
-
-    return (DisasASI){ type, asi, mem_idx, memop };
+    return r_asi;
 }
 
-static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
-                       int insn, TCGMemOp memop)
+static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
+                              int sign)
 {
-    DisasASI da = get_asi(dc, insn, memop);
-
-    switch (da.type) {
-    case GET_ASI_EXCP:
-        break;
-    case GET_ASI_DTWINX: /* Reserved for ldda.  */
-        gen_exception(dc, TT_ILL_INSN);
-        break;
-    case GET_ASI_DIRECT:
-        gen_address_mask(dc, addr);
-        tcg_gen_qemu_ld_tl(dst, addr, da.mem_idx, da.memop);
-        break;
-    default:
-        {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(memop);
+    TCGv_i32 r_asi, r_size, r_sign;
 
-            save_state(dc);
-#ifdef TARGET_SPARC64
-            gen_helper_ld_asi(dst, cpu_env, addr, r_asi, r_mop);
-#else
-            {
-                TCGv_i64 t64 = tcg_temp_new_i64();
-                gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
-                tcg_gen_trunc_i64_tl(dst, t64);
-                tcg_temp_free_i64(t64);
-            }
-#endif
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
-        }
-        break;
-    }
+    r_asi = gen_get_asi(insn, addr);
+    r_size = tcg_const_i32(size);
+    r_sign = tcg_const_i32(sign);
+    gen_helper_ld_asi(dst, cpu_env, addr, r_asi, r_size, r_sign);
+    tcg_temp_free_i32(r_sign);
+    tcg_temp_free_i32(r_size);
+    tcg_temp_free_i32(r_asi);
 }
 
-static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
-                       int insn, TCGMemOp memop)
+static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
 {
-    DisasASI da = get_asi(dc, insn, memop);
-
-    switch (da.type) {
-    case GET_ASI_EXCP:
-        break;
-    case GET_ASI_DTWINX: /* Reserved for stda.  */
-        gen_exception(dc, TT_ILL_INSN);
-        break;
-    case GET_ASI_DIRECT:
-        gen_address_mask(dc, addr);
-        tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop);
-        break;
-    default:
-        {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(memop & MO_SIZE);
+    TCGv_i32 r_asi, r_size;
 
-            save_state(dc);
-#ifdef TARGET_SPARC64
-            gen_helper_st_asi(cpu_env, addr, src, r_asi, r_mop);
-#else
-            {
-                TCGv_i64 t64 = tcg_temp_new_i64();
-                tcg_gen_extu_tl_i64(t64, src);
-                gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
-                tcg_temp_free_i64(t64);
-            }
-#endif
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
-
-            /* A write to a TLB register may alter page maps.  End the TB. */
-            dc->npc = DYNAMIC_PC;
-        }
-        break;
-    }
+    r_asi = gen_get_asi(insn, addr);
+    r_size = tcg_const_i32(size);
+    gen_helper_st_asi(cpu_env, addr, src, r_asi, r_size);
+    tcg_temp_free_i32(r_size);
+    tcg_temp_free_i32(r_asi);
 }
 
-static void gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src,
-                         TCGv addr, int insn)
+static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
 {
-    DisasASI da = get_asi(dc, insn, MO_TEUL);
+    TCGv_i32 r_asi, r_size, r_rd;
 
-    switch (da.type) {
-    case GET_ASI_EXCP:
-        break;
-    default:
-        {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(MO_UL);
-            TCGv_i64 s64, t64;
-
-            save_state(dc);
-            t64 = tcg_temp_new_i64();
-            gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
-
-            s64 = tcg_temp_new_i64();
-            tcg_gen_extu_tl_i64(s64, src);
-            gen_helper_st_asi(cpu_env, addr, s64, r_asi, r_mop);
-            tcg_temp_free_i64(s64);
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
-
-            tcg_gen_trunc_i64_tl(dst, t64);
-            tcg_temp_free_i64(t64);
-        }
-        break;
-    }
+    r_asi = gen_get_asi(insn, addr);
+    r_size = tcg_const_i32(size);
+    r_rd = tcg_const_i32(rd);
+    gen_helper_ldf_asi(cpu_env, addr, r_asi, r_size, r_rd);
+    tcg_temp_free_i32(r_rd);
+    tcg_temp_free_i32(r_size);
+    tcg_temp_free_i32(r_asi);
 }
 
-static void gen_cas_asi(DisasContext *dc, TCGv addr, TCGv val2,
-                        int insn, int rd)
+static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
 {
-    DisasASI da = get_asi(dc, insn, MO_TEUL);
-    TCGv val1, dst;
-    TCGv_i32 r_asi;
+    TCGv_i32 r_asi, r_size, r_rd;
 
-    if (da.type == GET_ASI_EXCP) {
-        return;
-    }
-
-    save_state(dc);
-    val1 = gen_load_gpr(dc, rd);
-    dst = gen_dest_gpr(dc, rd);
-    r_asi = tcg_const_i32(da.asi);
-    gen_helper_cas_asi(dst, cpu_env, addr, val1, val2, r_asi);
+    r_asi = gen_get_asi(insn, addr);
+    r_size = tcg_const_i32(size);
+    r_rd = tcg_const_i32(rd);
+    gen_helper_stf_asi(cpu_env, addr, r_asi, r_size, r_rd);
+    tcg_temp_free_i32(r_rd);
+    tcg_temp_free_i32(r_size);
     tcg_temp_free_i32(r_asi);
-    gen_store_gpr(dc, rd, dst);
 }
 
-static void gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
+static inline void gen_swap_asi(TCGv dst, TCGv src, TCGv addr, int insn)
 {
-    DisasASI da = get_asi(dc, insn, MO_UB);
+    TCGv_i32 r_asi, r_size, r_sign;
+    TCGv_i64 t64 = tcg_temp_new_i64();
 
-    switch (da.type) {
-    case GET_ASI_EXCP:
-        break;
-    default:
-        {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(MO_UB);
-            TCGv_i64 s64, t64;
-
-            save_state(dc);
-            t64 = tcg_temp_new_i64();
-            gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
-
-            s64 = tcg_const_i64(0xff);
-            gen_helper_st_asi(cpu_env, addr, s64, r_asi, r_mop);
-            tcg_temp_free_i64(s64);
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
-
-            tcg_gen_trunc_i64_tl(dst, t64);
-            tcg_temp_free_i64(t64);
-        }
-        break;
-    }
+    r_asi = gen_get_asi(insn, addr);
+    r_size = tcg_const_i32(4);
+    r_sign = tcg_const_i32(0);
+    gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_size, r_sign);
+    tcg_temp_free_i32(r_sign);
+    gen_helper_st_asi(cpu_env, addr, src, r_asi, r_size);
+    tcg_temp_free_i32(r_size);
+    tcg_temp_free_i32(r_asi);
+    tcg_gen_trunc_i64_tl(dst, t64);
+    tcg_temp_free_i64(t64);
 }
-#endif
 
-#ifdef TARGET_SPARC64
-static void gen_ldf_asi(DisasContext *dc, TCGv addr,
-                        int insn, int size, int rd)
+static inline void gen_ldda_asi(DisasContext *dc, TCGv hi, TCGv addr,
+                                int insn, int rd)
 {
-    DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ));
-    TCGv_i32 d32;
-
-    switch (da.type) {
-    case GET_ASI_EXCP:
-        break;
-
-    case GET_ASI_DIRECT:
-        gen_address_mask(dc, addr);
-        switch (size) {
-        case 4:
-            d32 = gen_dest_fpr_F(dc);
-            tcg_gen_qemu_ld_i32(d32, addr, da.mem_idx, da.memop);
-            gen_store_fpr_F(dc, rd, d32);
-            break;
-        case 8:
-            tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
-            break;
-        case 16:
-            tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
-            tcg_gen_addi_tl(addr, addr, 8);
-            tcg_gen_qemu_ld_i64(cpu_fpr[rd/2+1], addr, da.mem_idx, da.memop);
-            break;
-        default:
-            g_assert_not_reached();
-        }
-        break;
-
-    case GET_ASI_BLOCK:
-        /* Valid for lddfa on aligned registers only.  */
-        if (size == 8 && (rd & 7) == 0) {
-            TCGv eight;
-            int i;
-
-            gen_check_align(addr, 0x3f);
-            gen_address_mask(dc, addr);
-
-            eight = tcg_const_tl(8);
-            for (i = 0; ; ++i) {
-                tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + i], addr,
-                                    da.mem_idx, da.memop);
-                if (i == 7) {
-                    break;
-                }
-                tcg_gen_add_tl(addr, addr, eight);
-            }
-            tcg_temp_free(eight);
-        } else {
-            gen_exception(dc, TT_ILL_INSN);
-        }
-        break;
+    TCGv_i32 r_asi, r_rd;
 
-    case GET_ASI_SHORT:
-        /* Valid for lddfa only.  */
-        if (size == 8) {
-            gen_address_mask(dc, addr);
-            tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
-        } else {
-            gen_exception(dc, TT_ILL_INSN);
-        }
-        break;
-
-    default:
-        {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(da.memop);
-
-            save_state(dc);
-            /* According to the table in the UA2011 manual, the only
-               other asis that are valid for ldfa/lddfa/ldqfa are
-               the NO_FAULT asis.  We still need a helper for these,
-               but we can just use the integer asi helper for them.  */
-            switch (size) {
-            case 4:
-                {
-                    TCGv d64 = tcg_temp_new_i64();
-                    gen_helper_ld_asi(d64, cpu_env, addr, r_asi, r_mop);
-                    d32 = gen_dest_fpr_F(dc);
-                    tcg_gen_extrl_i64_i32(d32, d64);
-                    tcg_temp_free_i64(d64);
-                    gen_store_fpr_F(dc, rd, d32);
-                }
-                break;
-            case 8:
-                gen_helper_ld_asi(cpu_fpr[rd / 2], cpu_env, addr, r_asi, r_mop);
-                break;
-            case 16:
-                gen_helper_ld_asi(cpu_fpr[rd / 2], cpu_env, addr, r_asi, r_mop);
-                tcg_gen_addi_tl(addr, addr, 8);
-                gen_helper_ld_asi(cpu_fpr[rd/2+1], cpu_env, addr, r_asi, r_mop);
-                break;
-            default:
-                g_assert_not_reached();
-            }
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
-        }
-        break;
-    }
+    r_asi = gen_get_asi(insn, addr);
+    r_rd = tcg_const_i32(rd);
+    gen_helper_ldda_asi(cpu_env, addr, r_asi, r_rd);
+    tcg_temp_free_i32(r_rd);
+    tcg_temp_free_i32(r_asi);
 }
 
-static void gen_stf_asi(DisasContext *dc, TCGv addr,
-                        int insn, int size, int rd)
+static inline void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
+                                int insn, int rd)
 {
-    DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ));
-    TCGv_i32 d32;
-
-    switch (da.type) {
-    case GET_ASI_EXCP:
-        break;
-
-    case GET_ASI_DIRECT:
-        gen_address_mask(dc, addr);
-        switch (size) {
-        case 4:
-            d32 = gen_load_fpr_F(dc, rd);
-            tcg_gen_qemu_st_i32(d32, addr, da.mem_idx, da.memop);
-            break;
-        case 8:
-            tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
-            break;
-        case 16:
-            tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
-            tcg_gen_addi_tl(addr, addr, 8);
-            tcg_gen_qemu_st_i64(cpu_fpr[rd/2+1], addr, da.mem_idx, da.memop);
-            break;
-        default:
-            g_assert_not_reached();
-        }
-        break;
-
-    case GET_ASI_BLOCK:
-        /* Valid for stdfa on aligned registers only.  */
-        if (size == 8 && (rd & 7) == 0) {
-            TCGv eight;
-            int i;
-
-            gen_check_align(addr, 0x3f);
-            gen_address_mask(dc, addr);
-
-            eight = tcg_const_tl(8);
-            for (i = 0; ; ++i) {
-                tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + i], addr,
-                                    da.mem_idx, da.memop);
-                if (i == 7) {
-                    break;
-                }
-                tcg_gen_add_tl(addr, addr, eight);
-            }
-            tcg_temp_free(eight);
-        } else {
-            gen_exception(dc, TT_ILL_INSN);
-        }
-        break;
-
-    case GET_ASI_SHORT:
-        /* Valid for stdfa only.  */
-        if (size == 8) {
-            gen_address_mask(dc, addr);
-            tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
-        } else {
-            gen_exception(dc, TT_ILL_INSN);
-        }
-        break;
+    TCGv_i32 r_asi, r_size;
+    TCGv lo = gen_load_gpr(dc, rd + 1);
+    TCGv_i64 t64 = tcg_temp_new_i64();
 
-    default:
-        /* According to the table in the UA2011 manual, the only
-           other asis that are valid for ldfa/lddfa/ldqfa are
-           the PST* asis, which aren't currently handled.  */
-        gen_exception(dc, TT_ILL_INSN);
-        break;
-    }
+    tcg_gen_concat_tl_i64(t64, lo, hi);
+    r_asi = gen_get_asi(insn, addr);
+    r_size = tcg_const_i32(8);
+    gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_size);
+    tcg_temp_free_i32(r_size);
+    tcg_temp_free_i32(r_asi);
+    tcg_temp_free_i64(t64);
 }
 
-static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
+static inline void gen_casx_asi(DisasContext *dc, TCGv addr,
+                                TCGv val2, int insn, int rd)
 {
-    DisasASI da = get_asi(dc, insn, MO_TEQ);
-    TCGv_i64 hi = gen_dest_gpr(dc, rd);
-    TCGv_i64 lo = gen_dest_gpr(dc, rd + 1);
-
-    switch (da.type) {
-    case GET_ASI_EXCP:
-        return;
-
-    case GET_ASI_DTWINX:
-        gen_check_align(addr, 15);
-        gen_address_mask(dc, addr);
-        tcg_gen_qemu_ld_i64(hi, addr, da.mem_idx, da.memop);
-        tcg_gen_addi_tl(addr, addr, 8);
-        tcg_gen_qemu_ld_i64(lo, addr, da.mem_idx, da.memop);
-        break;
-
-    case GET_ASI_DIRECT:
-        {
-            TCGv_i64 tmp = tcg_temp_new_i64();
-
-            gen_address_mask(dc, addr);
-            tcg_gen_qemu_ld_i64(tmp, addr, da.mem_idx, da.memop);
-
-            /* Note that LE ldda acts as if each 32-bit register
-               result is byte swapped.  Having just performed one
-               64-bit bswap, we need now to swap the writebacks.  */
-            if ((da.memop & MO_BSWAP) == MO_TE) {
-                tcg_gen_extr32_i64(lo, hi, tmp);
-            } else {
-                tcg_gen_extr32_i64(hi, lo, tmp);
-            }
-            tcg_temp_free_i64(tmp);
-        }
-        break;
+    TCGv val1 = gen_load_gpr(dc, rd);
+    TCGv dst = gen_dest_gpr(dc, rd);
+    TCGv_i32 r_asi = gen_get_asi(insn, addr);
 
-    default:
-        {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
+    gen_helper_casx_asi(dst, cpu_env, addr, val1, val2, r_asi);
+    tcg_temp_free_i32(r_asi);
+    gen_store_gpr(dc, rd, dst);
+}
 
-            save_state(dc);
-            gen_helper_ldda_asi(cpu_env, addr, r_asi);
-            tcg_temp_free_i32(r_asi);
+#elif !defined(CONFIG_USER_ONLY)
 
-            tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUSPARCState, qt0.high));
-            tcg_gen_ld_i64(lo, cpu_env, offsetof(CPUSPARCState, qt0.low));
-        }
-        break;
-    }
+static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
+                              int sign)
+{
+    TCGv_i32 r_asi, r_size, r_sign;
+    TCGv_i64 t64 = tcg_temp_new_i64();
 
-    gen_store_gpr(dc, rd, hi);
-    gen_store_gpr(dc, rd + 1, lo);
+    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
+    r_size = tcg_const_i32(size);
+    r_sign = tcg_const_i32(sign);
+    gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_size, r_sign);
+    tcg_temp_free_i32(r_sign);
+    tcg_temp_free_i32(r_size);
+    tcg_temp_free_i32(r_asi);
+    tcg_gen_trunc_i64_tl(dst, t64);
+    tcg_temp_free_i64(t64);
 }
 
-static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
-                         int insn, int rd)
+static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
 {
-    DisasASI da = get_asi(dc, insn, MO_TEQ);
-    TCGv lo = gen_load_gpr(dc, rd + 1);
-
-    switch (da.type) {
-    case GET_ASI_EXCP:
-        break;
-
-    case GET_ASI_DTWINX:
-        gen_check_align(addr, 15);
-        gen_address_mask(dc, addr);
-        tcg_gen_qemu_st_i64(hi, addr, da.mem_idx, da.memop);
-        tcg_gen_addi_tl(addr, addr, 8);
-        tcg_gen_qemu_st_i64(lo, addr, da.mem_idx, da.memop);
-        break;
-
-    case GET_ASI_DIRECT:
-        {
-            TCGv_i64 t64 = tcg_temp_new_i64();
-
-            /* Note that LE stda acts as if each 32-bit register result is
-               byte swapped.  We will perform one 64-bit LE store, so now
-               we must swap the order of the construction.  */
-            if ((da.memop & MO_BSWAP) == MO_TE) {
-                tcg_gen_concat32_i64(t64, lo, hi);
-            } else {
-                tcg_gen_concat32_i64(t64, hi, lo);
-            }
-            gen_address_mask(dc, addr);
-            tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop);
-            tcg_temp_free_i64(t64);
-        }
-        break;
+    TCGv_i32 r_asi, r_size;
+    TCGv_i64 t64 = tcg_temp_new_i64();
 
-    default:
-        {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(MO_Q);
-            TCGv_i64 t64;
-
-            save_state(dc);
-
-            t64 = tcg_temp_new_i64();
-            tcg_gen_concat_tl_i64(t64, lo, hi);
-            gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
-            tcg_temp_free_i64(t64);
-        }
-        break;
-    }
+    tcg_gen_extu_tl_i64(t64, src);
+    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
+    r_size = tcg_const_i32(size);
+    gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_size);
+    tcg_temp_free_i32(r_size);
+    tcg_temp_free_i32(r_asi);
+    tcg_temp_free_i64(t64);
 }
 
-static void gen_casx_asi(DisasContext *dc, TCGv addr, TCGv val2,
-                         int insn, int rd)
+static inline void gen_swap_asi(TCGv dst, TCGv src, TCGv addr, int insn)
 {
-    DisasASI da = get_asi(dc, insn, MO_TEQ);
-    TCGv val1 = gen_load_gpr(dc, rd);
-    TCGv dst = gen_dest_gpr(dc, rd);
-    TCGv_i32 r_asi;
-
-    if (da.type == GET_ASI_EXCP) {
-        return;
-    }
+    TCGv_i32 r_asi, r_size, r_sign;
+    TCGv_i64 r_val, t64;
 
-    save_state(dc);
-    r_asi = tcg_const_i32(da.asi);
-    gen_helper_casx_asi(dst, cpu_env, addr, val1, val2, r_asi);
+    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
+    r_size = tcg_const_i32(4);
+    r_sign = tcg_const_i32(0);
+    t64 = tcg_temp_new_i64();
+    gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_size, r_sign);
+    tcg_temp_free(r_sign);
+    r_val = tcg_temp_new_i64();
+    tcg_gen_extu_tl_i64(r_val, src);
+    gen_helper_st_asi(cpu_env, addr, r_val, r_asi, r_size);
+    tcg_temp_free_i64(r_val);
+    tcg_temp_free_i32(r_size);
     tcg_temp_free_i32(r_asi);
-    gen_store_gpr(dc, rd, dst);
+    tcg_gen_trunc_i64_tl(dst, t64);
+    tcg_temp_free_i64(t64);
 }
 
-#elif !defined(CONFIG_USER_ONLY)
-static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
+static inline void gen_ldda_asi(DisasContext *dc, TCGv hi, TCGv addr,
+                                int insn, int rd)
 {
+    TCGv_i32 r_asi, r_size, r_sign;
+    TCGv t;
+    TCGv_i64 t64;
+
+    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
+    r_size = tcg_const_i32(8);
+    r_sign = tcg_const_i32(0);
+    t64 = tcg_temp_new_i64();
+    gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_size, r_sign);
+    tcg_temp_free_i32(r_sign);
+    tcg_temp_free_i32(r_size);
+    tcg_temp_free_i32(r_asi);
+
     /* ??? Work around an apparent bug in Ubuntu gcc 4.8.2-10ubuntu2+12,
        whereby "rd + 1" elicits "error: array subscript is above array".
        Since we have already asserted that rd is even, the semantics
        are unchanged.  */
-    TCGv lo = gen_dest_gpr(dc, rd | 1);
-    TCGv hi = gen_dest_gpr(dc, rd);
-    TCGv_i64 t64 = tcg_temp_new_i64();
-    DisasASI da = get_asi(dc, insn, MO_TEQ);
-
-    switch (da.type) {
-    case GET_ASI_EXCP:
-        tcg_temp_free_i64(t64);
-        return;
-    case GET_ASI_DIRECT:
-        gen_address_mask(dc, addr);
-        tcg_gen_qemu_ld_i64(t64, addr, da.mem_idx, da.memop);
-        break;
-    default:
-        {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(MO_Q);
+    t = gen_dest_gpr(dc, rd | 1);
+    tcg_gen_trunc_i64_tl(t, t64);
+    gen_store_gpr(dc, rd | 1, t);
 
-            save_state(dc);
-            gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
-        }
-        break;
-    }
-
-    tcg_gen_extr_i64_i32(lo, hi, t64);
+    tcg_gen_shri_i64(t64, t64, 32);
+    tcg_gen_trunc_i64_tl(hi, t64);
     tcg_temp_free_i64(t64);
-    gen_store_gpr(dc, rd | 1, lo);
     gen_store_gpr(dc, rd, hi);
 }
 
-static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
-                         int insn, int rd)
+static inline void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
+                                int insn, int rd)
 {
-    DisasASI da = get_asi(dc, insn, MO_TEQ);
+    TCGv_i32 r_asi, r_size;
     TCGv lo = gen_load_gpr(dc, rd + 1);
     TCGv_i64 t64 = tcg_temp_new_i64();
 
     tcg_gen_concat_tl_i64(t64, lo, hi);
+    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
+    r_size = tcg_const_i32(8);
+    gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_size);
+    tcg_temp_free_i32(r_size);
+    tcg_temp_free_i32(r_asi);
+    tcg_temp_free_i64(t64);
+}
+#endif
 
-    switch (da.type) {
-    case GET_ASI_EXCP:
-        break;
-    case GET_ASI_DIRECT:
-        gen_address_mask(dc, addr);
-        tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop);
-        break;
-    default:
-        {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(MO_Q);
+#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
+static inline void gen_cas_asi(DisasContext *dc, TCGv addr,
+                               TCGv val2, int insn, int rd)
+{
+    TCGv val1 = gen_load_gpr(dc, rd);
+    TCGv dst = gen_dest_gpr(dc, rd);
+#ifdef TARGET_SPARC64
+    TCGv_i32 r_asi = gen_get_asi(insn, addr);
+#else
+    TCGv_i32 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
+#endif
 
-            save_state(dc);
-            gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
-        }
-        break;
-    }
+    gen_helper_cas_asi(dst, cpu_env, addr, val1, val2, r_asi);
+    tcg_temp_free_i32(r_asi);
+    gen_store_gpr(dc, rd, dst);
+}
 
-    tcg_temp_free_i64(t64);
+static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
+{
+    TCGv_i64 r_val;
+    TCGv_i32 r_asi, r_size;
+
+    gen_ld_asi(dst, addr, insn, 1, 0);
+
+    r_val = tcg_const_i64(0xffULL);
+    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
+    r_size = tcg_const_i32(1);
+    gen_helper_st_asi(cpu_env, addr, r_val, r_asi, r_size);
+    tcg_temp_free_i32(r_size);
+    tcg_temp_free_i32(r_asi);
+    tcg_temp_free_i64(r_val);
 }
 #endif
 
@@ -2797,7 +2288,7 @@ static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
     tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2 + 1], cmp->c1, cmp->c2,
                         cpu_fpr[qs / 2 + 1], cpu_fpr[qd / 2 + 1]);
 
-    gen_update_fprs_dirty(dc, qd);
+    gen_update_fprs_dirty(qd);
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -3209,7 +2700,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     gen_store_gpr(dc, rd, cpu_dst);
                     break;
                 case 0x3: /* V9 rdasi */
-                    tcg_gen_movi_tl(cpu_dst, dc->asi);
+                    tcg_gen_ext_i32_tl(cpu_dst, cpu_asi);
                     gen_store_gpr(dc, rd, cpu_dst);
                     break;
                 case 0x4: /* V9 rdtick */
@@ -3252,8 +2743,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     gen_store_gpr(dc, rd, cpu_gsr);
                     break;
                 case 0x16: /* Softint */
-                    tcg_gen_ld32s_tl(cpu_dst, cpu_env,
-                                     offsetof(CPUSPARCState, softint));
+                    tcg_gen_ext_i32_tl(cpu_dst, cpu_softint);
                     gen_store_gpr(dc, rd, cpu_dst);
                     break;
                 case 0x17: /* Tick compare */
@@ -3471,7 +2961,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 rs1 = GET_FIELD(insn, 13, 17);
                 rs2 = GET_FIELD(insn, 27, 31);
                 xop = GET_FIELD(insn, 18, 26);
-
+                save_state(dc);
                 switch (xop) {
                 case 0x1: /* fmovs */
                     cpu_src1_32 = gen_load_fpr_F(dc, rs2);
@@ -3595,7 +3085,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     break;
                 case 0x3: /* V9 fmovq */
                     CHECK_FPU_FEATURE(dc, FLOAT128);
-                    gen_move_Q(dc, rd, rs2);
+                    gen_move_Q(rd, rs2);
                     break;
                 case 0x6: /* V9 fnegd */
                     gen_ne_fop_DD(dc, rd, rs2, gen_helper_fnegd);
@@ -3646,6 +3136,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 rs1 = GET_FIELD(insn, 13, 17);
                 rs2 = GET_FIELD(insn, 27, 31);
                 xop = GET_FIELD(insn, 18, 26);
+                save_state(dc);
 
 #ifdef TARGET_SPARC64
 #define FMOVR(sz)                                                  \
@@ -4134,18 +3625,11 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                             case 0x3: /* V9 wrasi */
                                 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
                                 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xff);
-                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
-                                                offsetof(CPUSPARCState, asi));
-                                /* End TB to notice changed ASI.  */
-                                save_state(dc);
-                                gen_op_next_insn();
-                                tcg_gen_exit_tb(0);
-                                dc->is_br = 1;
+                                tcg_gen_trunc_tl_i32(cpu_asi, cpu_tmp0);
                                 break;
                             case 0x6: /* V9 wrfprs */
                                 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
                                 tcg_gen_trunc_tl_i32(cpu_fprs, cpu_tmp0);
-                                dc->fprs_dirty = 0;
                                 save_state(dc);
                                 gen_op_next_insn();
                                 tcg_gen_exit_tb(0);
@@ -4988,6 +4472,8 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
 #endif
 #ifdef TARGET_SPARC64
             } else if (xop == 0x39) { /* V9 return */
+                TCGv_i32 r_const;
+
                 save_state(dc);
                 cpu_src1 = get_src1(dc, insn);
                 cpu_tmp0 = get_temp_tl(dc);
@@ -5005,7 +4491,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 }
                 gen_helper_restore(cpu_env);
                 gen_mov_pc_npc(dc);
-                gen_check_align(cpu_tmp0, 3);
+                r_const = tcg_const_i32(3);
+                gen_helper_check_align(cpu_env, cpu_tmp0, r_const);
+                tcg_temp_free_i32(r_const);
                 tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
                 dc->npc = DYNAMIC_PC;
                 goto jmp_insn;
@@ -5028,12 +4516,16 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 switch (xop) {
                 case 0x38:      /* jmpl */
                     {
-                        TCGv t = gen_dest_gpr(dc, rd);
+                        TCGv t;
+                        TCGv_i32 r_const;
+
+                        t = gen_dest_gpr(dc, rd);
                         tcg_gen_movi_tl(t, dc->pc);
                         gen_store_gpr(dc, rd, t);
-
                         gen_mov_pc_npc(dc);
-                        gen_check_align(cpu_tmp0, 3);
+                        r_const = tcg_const_i32(3);
+                        gen_helper_check_align(cpu_env, cpu_tmp0, r_const);
+                        tcg_temp_free_i32(r_const);
                         gen_address_mask(dc, cpu_tmp0);
                         tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
                         dc->npc = DYNAMIC_PC;
@@ -5042,10 +4534,14 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
 #if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
                 case 0x39:      /* rett, V9 return */
                     {
+                        TCGv_i32 r_const;
+
                         if (!supervisor(dc))
                             goto priv_insn;
                         gen_mov_pc_npc(dc);
-                        gen_check_align(cpu_tmp0, 3);
+                        r_const = tcg_const_i32(3);
+                        gen_helper_check_align(cpu_env, cpu_tmp0, r_const);
+                        tcg_temp_free_i32(r_const);
                         tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
                         dc->npc = DYNAMIC_PC;
                         gen_helper_rett(cpu_env);
@@ -5141,8 +4637,14 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     if (rd & 1)
                         goto illegal_insn;
                     else {
+                        TCGv_i32 r_const;
                         TCGv_i64 t64;
 
+                        save_state(dc);
+                        r_const = tcg_const_i32(7);
+                        /* XXX remove alignment check */
+                        gen_helper_check_align(cpu_env, cpu_addr, r_const);
+                        tcg_temp_free_i32(r_const);
                         gen_address_mask(dc, cpu_addr);
                         t64 = tcg_temp_new_i64();
                         tcg_gen_qemu_ld64(t64, cpu_addr, dc->mem_idx);
@@ -5191,34 +4693,89 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     break;
 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
                 case 0x10:      /* lda, V9 lduwa, load word alternate */
-                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
+#ifndef TARGET_SPARC64
+                    if (IS_IMM)
+                        goto illegal_insn;
+                    if (!supervisor(dc))
+                        goto priv_insn;
+#endif
+                    save_state(dc);
+                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
                     break;
                 case 0x11:      /* lduba, load unsigned byte alternate */
-                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
+#ifndef TARGET_SPARC64
+                    if (IS_IMM)
+                        goto illegal_insn;
+                    if (!supervisor(dc))
+                        goto priv_insn;
+#endif
+                    save_state(dc);
+                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
                     break;
                 case 0x12:      /* lduha, load unsigned halfword alternate */
-                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUW);
+#ifndef TARGET_SPARC64
+                    if (IS_IMM)
+                        goto illegal_insn;
+                    if (!supervisor(dc))
+                        goto priv_insn;
+#endif
+                    save_state(dc);
+                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
                     break;
                 case 0x13:      /* ldda, load double word alternate */
-                    if (rd & 1) {
+#ifndef TARGET_SPARC64
+                    if (IS_IMM)
                         goto illegal_insn;
-                    }
-                    gen_ldda_asi(dc, cpu_addr, insn, rd);
+                    if (!supervisor(dc))
+                        goto priv_insn;
+#endif
+                    if (rd & 1)
+                        goto illegal_insn;
+                    save_state(dc);
+                    gen_ldda_asi(dc, cpu_val, cpu_addr, insn, rd);
                     goto skip_move;
                 case 0x19:      /* ldsba, load signed byte alternate */
-                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_SB);
+#ifndef TARGET_SPARC64
+                    if (IS_IMM)
+                        goto illegal_insn;
+                    if (!supervisor(dc))
+                        goto priv_insn;
+#endif
+                    save_state(dc);
+                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
                     break;
                 case 0x1a:      /* ldsha, load signed halfword alternate */
-                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESW);
+#ifndef TARGET_SPARC64
+                    if (IS_IMM)
+                        goto illegal_insn;
+                    if (!supervisor(dc))
+                        goto priv_insn;
+#endif
+                    save_state(dc);
+                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
                     break;
                 case 0x1d:      /* ldstuba -- XXX: should be atomically */
-                    gen_ldstub_asi(dc, cpu_val, cpu_addr, insn);
+#ifndef TARGET_SPARC64
+                    if (IS_IMM)
+                        goto illegal_insn;
+                    if (!supervisor(dc))
+                        goto priv_insn;
+#endif
+                    save_state(dc);
+                    gen_ldstub_asi(cpu_val, cpu_addr, insn);
                     break;
                 case 0x1f:      /* swapa, swap reg with alt. memory. Also
                                    atomically */
                     CHECK_IU_FEATURE(dc, SWAP);
+#ifndef TARGET_SPARC64
+                    if (IS_IMM)
+                        goto illegal_insn;
+                    if (!supervisor(dc))
+                        goto priv_insn;
+#endif
+                    save_state(dc);
                     cpu_src1 = gen_load_gpr(dc, rd);
-                    gen_swap_asi(dc, cpu_val, cpu_src1, cpu_addr, insn);
+                    gen_swap_asi(cpu_val, cpu_src1, cpu_addr, insn);
                     break;
 
 #ifndef TARGET_SPARC64
@@ -5238,10 +4795,12 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
                     break;
                 case 0x18: /* V9 ldswa */
-                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESL);
+                    save_state(dc);
+                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
                     break;
                 case 0x1b: /* V9 ldxa */
-                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEQ);
+                    save_state(dc);
+                    gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
                     break;
                 case 0x2d: /* V9 prefetch, no effect */
                     goto skip_move;
@@ -5249,15 +4808,17 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     if (gen_trap_ifnofpu(dc)) {
                         goto jmp_insn;
                     }
-                    gen_ldf_asi(dc, cpu_addr, insn, 4, rd);
-                    gen_update_fprs_dirty(dc, rd);
+                    save_state(dc);
+                    gen_ldf_asi(cpu_addr, insn, 4, rd);
+                    gen_update_fprs_dirty(rd);
                     goto skip_move;
                 case 0x33: /* V9 lddfa */
                     if (gen_trap_ifnofpu(dc)) {
                         goto jmp_insn;
                     }
-                    gen_ldf_asi(dc, cpu_addr, insn, 8, DFPREG(rd));
-                    gen_update_fprs_dirty(dc, DFPREG(rd));
+                    save_state(dc);
+                    gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
+                    gen_update_fprs_dirty(DFPREG(rd));
                     goto skip_move;
                 case 0x3d: /* V9 prefetcha, no effect */
                     goto skip_move;
@@ -5266,8 +4827,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     if (gen_trap_ifnofpu(dc)) {
                         goto jmp_insn;
                     }
-                    gen_ldf_asi(dc, cpu_addr, insn, 16, QFPREG(rd));
-                    gen_update_fprs_dirty(dc, QFPREG(rd));
+                    save_state(dc);
+                    gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
+                    gen_update_fprs_dirty(QFPREG(rd));
                     goto skip_move;
 #endif
                 default:
@@ -5283,6 +4845,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 if (gen_trap_ifnofpu(dc)) {
                     goto jmp_insn;
                 }
+                save_state(dc);
                 switch (xop) {
                 case 0x20:      /* ldf, load fpreg */
                     gen_address_mask(dc, cpu_addr);
@@ -5298,7 +4861,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     if (rd == 1) {
                         TCGv_i64 t64 = tcg_temp_new_i64();
                         tcg_gen_qemu_ld64(t64, cpu_addr, dc->mem_idx);
-                        gen_helper_ldxfsr(cpu_fsr, cpu_env, cpu_fsr, t64);
+                        gen_helper_ldxfsr(cpu_env, t64);
                         tcg_temp_free_i64(t64);
                         break;
                     }
@@ -5307,7 +4870,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     t0 = get_temp_tl(dc);
                     tcg_gen_qemu_ld32u(t0, cpu_addr, dc->mem_idx);
                     tcg_gen_trunc_tl_i32(cpu_dst_32, t0);
-                    gen_helper_ldfsr(cpu_fsr, cpu_env, cpu_fsr, cpu_dst_32);
+                    gen_helper_ldfsr(cpu_env, cpu_dst_32);
                     break;
                 case 0x22:      /* ldqf, load quad fpreg */
                     {
@@ -5319,7 +4882,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                         gen_helper_ldqf(cpu_env, cpu_addr, r_const);
                         tcg_temp_free_i32(r_const);
                         gen_op_store_QT0_fpr(QFPREG(rd));
-                        gen_update_fprs_dirty(dc, QFPREG(rd));
+                        gen_update_fprs_dirty(QFPREG(rd));
                     }
                     break;
                 case 0x23:      /* lddf, load double fpreg */
@@ -5352,11 +4915,18 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     if (rd & 1)
                         goto illegal_insn;
                     else {
+                        TCGv_i32 r_const;
                         TCGv_i64 t64;
                         TCGv lo;
 
+                        save_state(dc);
                         gen_address_mask(dc, cpu_addr);
+                        r_const = tcg_const_i32(7);
+                        /* XXX remove alignment check */
+                        gen_helper_check_align(cpu_env, cpu_addr, r_const);
+                        tcg_temp_free_i32(r_const);
                         lo = gen_load_gpr(dc, rd + 1);
+
                         t64 = tcg_temp_new_i64();
                         tcg_gen_concat_tl_i64(t64, lo, cpu_val);
                         tcg_gen_qemu_st64(t64, cpu_addr, dc->mem_idx);
@@ -5365,19 +4935,51 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     break;
 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
                 case 0x14: /* sta, V9 stwa, store word alternate */
-                    gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
+#ifndef TARGET_SPARC64
+                    if (IS_IMM)
+                        goto illegal_insn;
+                    if (!supervisor(dc))
+                        goto priv_insn;
+#endif
+                    save_state(dc);
+                    gen_st_asi(cpu_val, cpu_addr, insn, 4);
+                    dc->npc = DYNAMIC_PC;
                     break;
                 case 0x15: /* stba, store byte alternate */
-                    gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
+#ifndef TARGET_SPARC64
+                    if (IS_IMM)
+                        goto illegal_insn;
+                    if (!supervisor(dc))
+                        goto priv_insn;
+#endif
+                    save_state(dc);
+                    gen_st_asi(cpu_val, cpu_addr, insn, 1);
+                    dc->npc = DYNAMIC_PC;
                     break;
                 case 0x16: /* stha, store halfword alternate */
-                    gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUW);
+#ifndef TARGET_SPARC64
+                    if (IS_IMM)
+                        goto illegal_insn;
+                    if (!supervisor(dc))
+                        goto priv_insn;
+#endif
+                    save_state(dc);
+                    gen_st_asi(cpu_val, cpu_addr, insn, 2);
+                    dc->npc = DYNAMIC_PC;
                     break;
                 case 0x17: /* stda, store double word alternate */
-                    if (rd & 1) {
+#ifndef TARGET_SPARC64
+                    if (IS_IMM)
+                        goto illegal_insn;
+                    if (!supervisor(dc))
+                        goto priv_insn;
+#endif
+                    if (rd & 1)
                         goto illegal_insn;
+                    else {
+                        save_state(dc);
+                        gen_stda_asi(dc, cpu_val, cpu_addr, insn, rd);
                     }
-                    gen_stda_asi(dc, cpu_val, cpu_addr, insn, rd);
                     break;
 #endif
 #ifdef TARGET_SPARC64
@@ -5386,7 +4988,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
                     break;
                 case 0x1e: /* V9 stxa */
-                    gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEQ);
+                    save_state(dc);
+                    gen_st_asi(cpu_val, cpu_addr, insn, 8);
+                    dc->npc = DYNAMIC_PC;
                     break;
 #endif
                 default:
@@ -5396,6 +5000,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 if (gen_trap_ifnofpu(dc)) {
                     goto jmp_insn;
                 }
+                save_state(dc);
                 switch (xop) {
                 case 0x24: /* stf, store fpreg */
                     {
@@ -5408,14 +5013,17 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     break;
                 case 0x25: /* stfsr, V9 stxfsr */
                     {
+                        TCGv t = get_temp_tl(dc);
+
+                        tcg_gen_ld_tl(t, cpu_env, offsetof(CPUSPARCState, fsr));
 #ifdef TARGET_SPARC64
                         gen_address_mask(dc, cpu_addr);
                         if (rd == 1) {
-                            tcg_gen_qemu_st64(cpu_fsr, cpu_addr, dc->mem_idx);
+                            tcg_gen_qemu_st64(t, cpu_addr, dc->mem_idx);
                             break;
                         }
 #endif
-                        tcg_gen_qemu_st32(cpu_fsr, cpu_addr, dc->mem_idx);
+                        tcg_gen_qemu_st32(t, cpu_addr, dc->mem_idx);
                     }
                     break;
                 case 0x26:
@@ -5454,29 +5062,34 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     goto illegal_insn;
                 }
             } else if (xop > 0x33 && xop < 0x3f) {
+                save_state(dc);
                 switch (xop) {
 #ifdef TARGET_SPARC64
                 case 0x34: /* V9 stfa */
                     if (gen_trap_ifnofpu(dc)) {
                         goto jmp_insn;
                     }
-                    gen_stf_asi(dc, cpu_addr, insn, 4, rd);
+                    gen_stf_asi(cpu_addr, insn, 4, rd);
                     break;
                 case 0x36: /* V9 stqfa */
                     {
+                        TCGv_i32 r_const;
+
                         CHECK_FPU_FEATURE(dc, FLOAT128);
                         if (gen_trap_ifnofpu(dc)) {
                             goto jmp_insn;
                         }
-                        gen_check_align(cpu_addr, 7);
-                        gen_stf_asi(dc, cpu_addr, insn, 16, QFPREG(rd));
+                        r_const = tcg_const_i32(7);
+                        gen_helper_check_align(cpu_env, cpu_addr, r_const);
+                        tcg_temp_free_i32(r_const);
+                        gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
                     }
                     break;
                 case 0x37: /* V9 stdfa */
                     if (gen_trap_ifnofpu(dc)) {
                         goto jmp_insn;
                     }
-                    gen_stf_asi(dc, cpu_addr, insn, 8, DFPREG(rd));
+                    gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
                     break;
                 case 0x3e: /* V9 casxa */
                     rs2 = GET_FIELD(insn, 27, 31);
@@ -5494,6 +5107,13 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 case 0x3c: /* V9 or LEON3 casa */
 #ifndef TARGET_SPARC64
                     CHECK_IU_FEATURE(dc, CASA);
+                    if (IS_IMM) {
+                        goto illegal_insn;
+                    }
+                    /* LEON3 allows CASA from user space with ASI 0xa */
+                    if ((GET_FIELD(insn, 19, 26) != 0xa) && !supervisor(dc)) {
+                        goto priv_insn;
+                    }
 #endif
                     rs2 = GET_FIELD(insn, 27, 31);
                     cpu_src2 = gen_load_gpr(dc, rs2);
@@ -5524,27 +5144,63 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
  jmp_insn:
     goto egress;
  illegal_insn:
-    gen_exception(dc, TT_ILL_INSN);
+    {
+        TCGv_i32 r_const;
+
+        save_state(dc);
+        r_const = tcg_const_i32(TT_ILL_INSN);
+        gen_helper_raise_exception(cpu_env, r_const);
+        tcg_temp_free_i32(r_const);
+        dc->is_br = 1;
+    }
     goto egress;
  unimp_flush:
-    gen_exception(dc, TT_UNIMP_FLUSH);
+    {
+        TCGv_i32 r_const;
+
+        save_state(dc);
+        r_const = tcg_const_i32(TT_UNIMP_FLUSH);
+        gen_helper_raise_exception(cpu_env, r_const);
+        tcg_temp_free_i32(r_const);
+        dc->is_br = 1;
+    }
     goto egress;
 #if !defined(CONFIG_USER_ONLY)
  priv_insn:
-    gen_exception(dc, TT_PRIV_INSN);
+    {
+        TCGv_i32 r_const;
+
+        save_state(dc);
+        r_const = tcg_const_i32(TT_PRIV_INSN);
+        gen_helper_raise_exception(cpu_env, r_const);
+        tcg_temp_free_i32(r_const);
+        dc->is_br = 1;
+    }
     goto egress;
 #endif
  nfpu_insn:
-    gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP);
+    save_state(dc);
+    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
+    dc->is_br = 1;
     goto egress;
 #if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
  nfq_insn:
-    gen_op_fpexception_im(dc, FSR_FTT_SEQ_ERROR);
+    save_state(dc);
+    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
+    dc->is_br = 1;
     goto egress;
 #endif
 #ifndef TARGET_SPARC64
  ncp_insn:
-    gen_exception(dc, TT_NCP_INSN);
+    {
+        TCGv r_const;
+
+        save_state(dc);
+        r_const = tcg_const_i32(TT_NCP_INSN);
+        gen_helper_raise_exception(cpu_env, r_const);
+        tcg_temp_free(r_const);
+        dc->is_br = 1;
+    }
     goto egress;
 #endif
  egress:
@@ -5581,15 +5237,11 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
     last_pc = dc->pc;
     dc->npc = (target_ulong) tb->cs_base;
     dc->cc_op = CC_OP_DYNAMIC;
-    dc->mem_idx = tb->flags & TB_FLAG_MMU_MASK;
+    dc->mem_idx = cpu_mmu_index(env, false);
     dc->def = env->def;
     dc->fpu_enabled = tb_fpu_enabled(tb->flags);
     dc->address_mask_32bit = tb_am_enabled(tb->flags);
     dc->singlestep = (cs->singlestep_enabled || singlestep);
-#ifdef TARGET_SPARC64
-    dc->fprs_dirty = 0;
-    dc->asi = (tb->flags >> TB_FLAG_ASI_SHIFT) & 0xff;
-#endif
 
     num_insns = 0;
     max_insns = tb->cflags & CF_COUNT_MASK;
@@ -5670,8 +5322,7 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
     tb->icount = num_insns;
 
 #ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("--------------\n");
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
         log_target_disas(cs, pc_start, last_pc + 4 - pc_start, 0);
@@ -5699,7 +5350,9 @@ void gen_intermediate_code_init(CPUSPARCState *env)
     static const struct { TCGv_i32 *ptr; int off; const char *name; } r32[] = {
 #ifdef TARGET_SPARC64
         { &cpu_xcc, offsetof(CPUSPARCState, xcc), "xcc" },
+        { &cpu_asi, offsetof(CPUSPARCState, asi), "asi" },
         { &cpu_fprs, offsetof(CPUSPARCState, fprs), "fprs" },
+        { &cpu_softint, offsetof(CPUSPARCState, softint), "softint" },
 #else
         { &cpu_wim, offsetof(CPUSPARCState, wim), "wim" },
 #endif
@@ -5742,7 +5395,6 @@ void gen_intermediate_code_init(CPUSPARCState *env)
     inited = 1;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
 
     cpu_regwptr = tcg_global_mem_new_ptr(cpu_env,
                                          offsetof(CPUSPARCState, regwptr),
index 7017cb6..d2d0912 100644 (file)
@@ -25,7 +25,6 @@
 #include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
 #include "linux-user/syscall_defs.h"
-#include "exec/exec-all.h"
 
 static void tilegx_cpu_dump_state(CPUState *cs, FILE *f,
                                   fprintf_function cpu_fprintf, int flags)
index 1735427..022cad1 100644 (file)
@@ -16,9 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-
-#ifndef TILEGX_CPU_H
-#define TILEGX_CPU_H
+#ifndef CPU_TILEGX_H
+#define CPU_TILEGX_H
 
 #include "qemu-common.h"
 
@@ -159,20 +158,24 @@ static inline TileGXCPU *tilegx_env_get_cpu(CPUTLGState *env)
 #include "exec/cpu-all.h"
 
 void tilegx_tcg_init(void);
+int cpu_tilegx_exec(CPUState *s);
 int cpu_tilegx_signal_handler(int host_signum, void *pinfo, void *puc);
 
 TileGXCPU *cpu_tilegx_init(const char *cpu_model);
 
 #define cpu_init(cpu_model) CPU(cpu_tilegx_init(cpu_model))
 
+#define cpu_exec cpu_tilegx_exec
 #define cpu_signal_handler cpu_tilegx_signal_handler
 
 static inline void cpu_get_tb_cpu_state(CPUTLGState *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *pc = env->pc;
     *cs_base = 0;
     *flags = 0;
 }
 
+#include "exec/exec-all.h"
+
 #endif
index b4fba9c..616c5c7 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "qemu-common.h"
 #include "exec/helper-proto.h"
 #include <zlib.h> /* For crc32 */
index 55376be..989436d 100644 (file)
@@ -18,8 +18,8 @@
  *
  */
 
-#ifndef OPCODE_TILEGX_H
-#define OPCODE_TILEGX_H
+#ifndef __ARCH_OPCODE_H__
+#define __ARCH_OPCODE_H__
 
 #ifndef __ASSEMBLER__
 
@@ -1403,4 +1403,4 @@ enum
 
 #endif /* __ASSEMBLER__ */
 
-#endif /* OPCODE_TILEGX_H */
+#endif /* __ARCH_OPCODE_H__ */
index 11c9732..03918eb 100644 (file)
@@ -23,7 +23,6 @@
 #include "qemu/log.h"
 #include "exec/log.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "exec/cpu_ldst.h"
 #include "linux-user/syscall_defs.h"
@@ -2443,7 +2442,6 @@ void tilegx_tcg_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
     cpu_pc = tcg_global_mem_new_i64(cpu_env, offsetof(CPUTLGState, pc), "pc");
     for (i = 0; i < TILEGX_R_COUNT; i++) {
         cpu_regs[i] = tcg_global_mem_new_i64(cpu_env,
index 6a69756..66c9664 100644 (file)
@@ -39,6 +39,32 @@ typedef struct TriCoreCPUClass {
     void (*parent_reset)(CPUState *cpu);
 } TriCoreCPUClass;
 
-typedef struct TriCoreCPU TriCoreCPU;
+/**
+ * TriCoreCPU:
+ * @env: #CPUTriCoreState
+ *
+ * A TriCore CPU.
+ */
+typedef struct TriCoreCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUTriCoreState env;
+} TriCoreCPU;
+
+static inline TriCoreCPU *tricore_env_get_cpu(CPUTriCoreState *env)
+{
+    return TRICORE_CPU(container_of(env, TriCoreCPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(tricore_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(TriCoreCPU, env)
+
+hwaddr tricore_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+void tricore_cpu_dump_state(CPUState *cpu, FILE *f,
+                            fprintf_function cpu_fprintf, int flags);
+
 
-#endif /* QEMU_TRICORE_CPU_QOM_H */
+#endif /*QEMU_TRICORE_CPU_QOM_H */
index 35d4ee4..69fca8c 100644 (file)
@@ -21,7 +21,6 @@
 #include "qapi/error.h"
 #include "cpu.h"
 #include "qemu-common.h"
-#include "exec/exec-all.h"
 
 static inline void set_feature(CPUTriCoreState *env, int feature)
 {
index a3493a1..90045a9 100644 (file)
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-
-#ifndef TRICORE_CPU_H
-#define TRICORE_CPU_H
+#if !defined(__TRICORE_CPU_H__)
+#define __TRICORE_CPU_H__
 
 #include "tricore-defs.h"
 #include "qemu-common.h"
-#include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat.h"
 
@@ -200,34 +198,6 @@ struct CPUTriCoreState {
     struct QEMUTimer *timer; /* Internal timer */
 };
 
-/**
- * TriCoreCPU:
- * @env: #CPUTriCoreState
- *
- * A TriCore CPU.
- */
-struct TriCoreCPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPUTriCoreState env;
-};
-
-static inline TriCoreCPU *tricore_env_get_cpu(CPUTriCoreState *env)
-{
-    return TRICORE_CPU(container_of(env, TriCoreCPU, env));
-}
-
-#define ENV_GET_CPU(e) CPU(tricore_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(TriCoreCPU, env)
-
-hwaddr tricore_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-void tricore_cpu_dump_state(CPUState *cpu, FILE *f,
-                            fprintf_function cpu_fprintf, int flags);
-
-
 #define MASK_PCXI_PCPN 0xff000000
 #define MASK_PCXI_PIE  0x00800000
 #define MASK_PCXI_UL   0x00400000
@@ -371,10 +341,12 @@ void psw_write(CPUTriCoreState *env, uint32_t val);
 
 void fpu_set_state(CPUTriCoreState *env);
 
+#include "cpu-qom.h"
 #define MMU_USER_IDX 2
 
 void tricore_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 
+#define cpu_exec cpu_tricore_exec
 #define cpu_signal_handler cpu_tricore_signal_handler
 #define cpu_list tricore_cpu_list
 
@@ -400,11 +372,12 @@ enum {
 };
 
 void cpu_state_reset(CPUTriCoreState *s);
+int cpu_tricore_exec(CPUState *cpu);
 void tricore_tcg_init(void);
 int cpu_tricore_signal_handler(int host_signum, void *pinfo, void *puc);
 
 static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *pc = env->PC;
     *cs_base = 0;
@@ -421,4 +394,6 @@ int cpu_tricore_handle_mmu_fault(CPUState *cpu, target_ulong address,
                                  int rw, int mmu_idx);
 #define cpu_handle_mmu_fault cpu_tricore_handle_mmu_fault
 
-#endif /* TRICORE_CPU_H */
+#include "exec/exec-all.h"
+
+#endif /*__TRICORE_CPU_H__ */
index 3118905..71b31cd 100644 (file)
@@ -18,7 +18,6 @@
 #include "qemu/osdep.h"
 
 #include "cpu.h"
-#include "exec/exec-all.h"
 
 enum {
     TLBRET_DIRTY = -4,
index ac02e0a..40656c3 100644 (file)
@@ -18,7 +18,6 @@
 #include "cpu.h"
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include <zlib.h> /* for crc32 */
 
@@ -2117,7 +2116,7 @@ uint64_t helper_dvadj(uint64_t r1, uint32_t r2)
     int32_t eq_pos = x_sign & ((r1 >> 32) == r2);
     int32_t eq_neg = x_sign & ((r1 >> 32) == -r2);
     uint32_t quotient;
-    uint64_t remainder;
+    uint64_t ret, remainder;
 
     if ((q_sign & ~eq_neg) | eq_pos) {
         quotient = (r1 + 1) & 0xffffffff;
@@ -2130,7 +2129,8 @@ uint64_t helper_dvadj(uint64_t r1, uint32_t r2)
     } else {
         remainder = (r1 & 0xffffffff00000000ull);
     }
-    return remainder | quotient;
+    ret = remainder|quotient;
+    return ret;
 }
 
 uint64_t helper_dvstep(uint64_t r1, uint32_t r2)
@@ -2235,6 +2235,7 @@ uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
 uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
                       uint32_t arg10, uint32_t arg11, uint32_t n)
 {
+    uint64_t ret;
     uint32_t result0, result1;
 
     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
@@ -2251,7 +2252,8 @@ uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
     } else {
         result0 = (((uint32_t)(arg01 * arg11)) << n);
     }
-    return (((uint64_t)result1 << 32)) | result0;
+    ret = (((uint64_t)result1 << 32)) | result0;
+    return ret;
 }
 
 uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
@@ -2305,9 +2307,11 @@ uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
 uint32_t helper_crc32(uint32_t arg0, uint32_t arg1)
 {
     uint8_t buf[4];
+    uint32_t ret;
     stl_be_p(buf, arg0);
 
-    return crc32(arg1, buf, 4);
+    ret = crc32(arg1, buf, 4);
+    return ret;
 }
 
 /* context save area (CSA) related helpers */
@@ -2828,11 +2832,11 @@ static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
     cpu_loop_exit(cs);
 }
 
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
+              uintptr_t retaddr)
 {
     int ret;
-    ret = cpu_tricore_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (ret) {
         TriCoreCPU *cpu = TRICORE_CPU(cs);
         CPUTriCoreState *env = &cpu->env;
index 9a50df9..26e86d6 100644 (file)
@@ -21,7 +21,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "exec/cpu_ldst.h"
 
@@ -3237,25 +3236,15 @@ static inline void gen_save_pc(target_ulong pc)
     tcg_gen_movi_tl(cpu_PC, pc);
 }
 
-static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
-{
-    if (unlikely(ctx->singlestep_enabled)) {
-        return false;
-    }
-
-#ifndef CONFIG_USER_ONLY
-    return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
 {
-    if (use_goto_tb(ctx, dest)) {
+    TranslationBlock *tb;
+    tb = ctx->tb;
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
+        likely(!ctx->singlestep_enabled)) {
         tcg_gen_goto_tb(n);
         gen_save_pc(dest);
-        tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         gen_save_pc(dest);
         if (ctx->singlestep_enabled) {
@@ -8787,8 +8776,7 @@ void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb)
     }
 
 #ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
         log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
         qemu_log("\n");
@@ -8835,7 +8823,6 @@ void tricore_tcg_init(void)
         return;
     }
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
     /* reg init */
     for (i = 0 ; i < 16 ; i++) {
         cpu_gpr_a[i] = tcg_global_mem_new(cpu_env,
index 40abfaa..4350b03 100644 (file)
@@ -15,8 +15,8 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef QEMU_TRICORE_DEFS_H
-#define QEMU_TRICORE_DEFS_H
+#if !defined(__QEMU_TRICORE_DEFS_H__)
+#define __QEMU_TRICORE_DEFS_H__
 
 #define TARGET_PAGE_BITS 14
 #define TARGET_LONG_BITS 32
@@ -25,4 +25,4 @@
 
 #define TRICORE_TLB_MAX 128
 
-#endif /* QEMU_TRICORE_DEFS_H */
+#endif /* __QEMU_TRICORE_DEFS_H__ */
index bc68e78..ea65b83 100644 (file)
@@ -12,6 +12,7 @@
 #define QEMU_UC32_CPU_QOM_H
 
 #include "qom/cpu.h"
+#include "cpu.h"
 
 #define TYPE_UNICORE32_CPU "unicore32-cpu"
 
@@ -36,6 +37,33 @@ typedef struct UniCore32CPUClass {
     DeviceRealize parent_realize;
 } UniCore32CPUClass;
 
-typedef struct UniCore32CPU UniCore32CPU;
+/**
+ * UniCore32CPU:
+ * @env: #CPUUniCore32State
+ *
+ * A UniCore32 CPU.
+ */
+typedef struct UniCore32CPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUUniCore32State env;
+} UniCore32CPU;
+
+static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env)
+{
+    return container_of(env, UniCore32CPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(uc32_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(UniCore32CPU, env)
+
+void uc32_cpu_do_interrupt(CPUState *cpu);
+bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req);
+void uc32_cpu_dump_state(CPUState *cpu, FILE *f,
+                         fprintf_function cpu_fprintf, int flags);
+hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 
 #endif
index e7a4984..66f43ac 100644 (file)
@@ -17,7 +17,6 @@
 #include "cpu.h"
 #include "qemu-common.h"
 #include "migration/vmstate.h"
-#include "exec/exec-all.h"
 
 static void uc32_cpu_set_pc(CPUState *cs, vaddr value)
 {
@@ -78,7 +77,6 @@ static void unicore_ii_cpu_initfn(Object *obj)
 
     set_feature(env, UC32_HWCAP_CMOV);
     set_feature(env, UC32_HWCAP_UCF64);
-    set_snan_bit_is_one(1, &env->ucf64.fp_status);
 }
 
 static void uc32_any_cpu_initfn(Object *obj)
@@ -91,7 +89,6 @@ static void uc32_any_cpu_initfn(Object *obj)
 
     set_feature(env, UC32_HWCAP_CMOV);
     set_feature(env, UC32_HWCAP_UCF64);
-    set_snan_bit_is_one(1, &env->ucf64.fp_status);
 }
 
 static const UniCore32CPUInfo uc32_cpus[] = {
index 7b5b405..9c1fbf9 100644 (file)
@@ -8,9 +8,8 @@
  * published by the Free Software Foundation, or (at your option) any
  * later version. See the COPYING file in the top-level directory.
  */
-
-#ifndef UNICORE32_CPU_H
-#define UNICORE32_CPU_H
+#ifndef QEMU_UNICORE32_CPU_H
+#define QEMU_UNICORE32_CPU_H
 
 #define TARGET_LONG_BITS                32
 #define TARGET_PAGE_BITS                12
@@ -21,7 +20,6 @@
 #define CPUArchState                struct CPUUniCore32State
 
 #include "qemu-common.h"
-#include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat.h"
 
@@ -73,35 +71,6 @@ typedef struct CPUUniCore32State {
 
 } CPUUniCore32State;
 
-/**
- * UniCore32CPU:
- * @env: #CPUUniCore32State
- *
- * A UniCore32 CPU.
- */
-struct UniCore32CPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPUUniCore32State env;
-};
-
-static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env)
-{
-    return container_of(env, UniCore32CPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(uc32_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(UniCore32CPU, env)
-
-void uc32_cpu_do_interrupt(CPUState *cpu);
-bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req);
-void uc32_cpu_dump_state(CPUState *cpu, FILE *f,
-                         fprintf_function cpu_fprintf, int flags);
-hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-
 #define ASR_M                   (0x1f)
 #define ASR_MODE_USER           (0x10)
 #define ASR_MODE_INTR           (0x12)
@@ -150,6 +119,7 @@ void cpu_asr_write(CPUUniCore32State *env1, target_ulong val, target_ulong mask)
 #define UC32_HWCAP_CMOV                 4 /* 1 << 2 */
 #define UC32_HWCAP_UCF64                8 /* 1 << 3 */
 
+#define cpu_exec                        uc32_cpu_exec
 #define cpu_signal_handler              uc32_cpu_signal_handler
 
 int uc32_cpu_signal_handler(int host_signum, void *pinfo, void *puc);
@@ -164,13 +134,17 @@ static inline int cpu_mmu_index(CPUUniCore32State *env, bool ifetch)
 }
 
 #include "exec/cpu-all.h"
+#include "cpu-qom.h"
+#include "exec/exec-all.h"
+
+int uc32_cpu_exec(CPUState *s);
 
 UniCore32CPU *uc32_cpu_init(const char *cpu_model);
 
 #define cpu_init(cpu_model) CPU(uc32_cpu_init(cpu_model))
 
 static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+                                        target_ulong *cs_base, int *flags)
 {
     *pc = env->regs[31];
     *cs_base = 0;
@@ -185,4 +159,4 @@ int uc32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
 void uc32_translate_init(void);
 void switch_mode(CPUUniCore32State *, int);
 
-#endif /* UNICORE32_CPU_H */
+#endif /* QEMU_UNICORE32_CPU_H */
index d603bde..21f5f35 100644 (file)
@@ -11,7 +11,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "exec/exec-all.h"
 #include "exec/gdbstub.h"
 #include "exec/helper-proto.h"
 #include "qemu/host-utils.h"
index 0872c29..f584730 100644 (file)
@@ -11,7 +11,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/helper-proto.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
 #define SIGNBIT (uint32_t)0x80000000
@@ -244,12 +243,12 @@ uint32_t HELPER(ror_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
 }
 
 #ifndef CONFIG_USER_ONLY
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write,
               int mmu_idx, uintptr_t retaddr)
 {
     int ret;
 
-    ret = uc32_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+    ret = uc32_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
index e7152e7..d267fed 100644 (file)
@@ -13,8 +13,7 @@
 #endif
 
 #include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
+#include <cpu.h>
 
 #undef DEBUG_UC32
 
index 09354f9..39af3af 100644 (file)
@@ -12,7 +12,6 @@
 
 #include "cpu.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "qemu/log.h"
 #include "exec/cpu_ldst.h"
@@ -70,7 +69,6 @@ void uc32_translate_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
 
     for (i = 0; i < 32; i++) {
         cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
@@ -1091,21 +1089,15 @@ static void disas_ucf64_insn(CPUUniCore32State *env, DisasContext *s, uint32_t i
     }
 }
 
-static inline bool use_goto_tb(DisasContext *s, uint32_t dest)
-{
-#ifndef CONFIG_USER_ONLY
-    return (s->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
-    return true;
-#endif
-}
-
 static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
 {
-    if (use_goto_tb(s, dest)) {
+    TranslationBlock *tb;
+
+    tb = s->tb;
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         gen_set_pc_im(dest);
-        tcg_gen_exit_tb((uintptr_t)s->tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         gen_set_pc_im(dest);
         tcg_gen_exit_tb(0);
@@ -2022,8 +2014,7 @@ done_generating:
     gen_tb_end(tb, num_insns);
 
 #ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("----------------\n");
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
         log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
index a9935b8..69f1065 100644 (file)
@@ -8,8 +8,9 @@
  * Copyright (c) 1999-2007 Tensilica Inc.
  */
 
-#ifndef XTENSA_DC232B_CORE_ISA_H
-#define XTENSA_DC232B_CORE_ISA_H
+#ifndef _XTENSA_CORE_CONFIGURATION_H
+#define _XTENSA_CORE_CONFIGURATION_H
+
 
 /****************************************************************************
             Parameters Useful for Any Code, USER or PRIVILEGED
 #endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
 
 
-#endif /* XTENSA_DC232B_CORE_ISA_H */
+#endif /* _XTENSA_CORE_CONFIGURATION_H */
index ff92b7f..e82c3cb 100644 (file)
@@ -28,8 +28,9 @@
    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
 
-#ifndef XTENSA_DC233C_CORE_ISA_H
-#define XTENSA_DC233C_CORE_ISA_H
+#ifndef _XTENSA_CORE_CONFIGURATION_H
+#define _XTENSA_CORE_CONFIGURATION_H
+
 
 /****************************************************************************
             Parameters Useful for Any Code, USER or PRIVILEGED
@@ -470,4 +471,4 @@ usable for an MMU-based OS */
 #endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
 
 
-#endif /* XTENSA_DC233C_CORE_ISA_H */
+#endif /* _XTENSA_CORE_CONFIGURATION_H */
index fb2bb8f..b519d6c 100644 (file)
@@ -8,8 +8,9 @@
  * Copyright (C) 1999-2006 Tensilica Inc.
  */
 
-#ifndef XTENSA_FSF_CORE_ISA_H
-#define XTENSA_FSF_CORE_ISA_H
+#ifndef _XTENSA_CORE_H
+#define _XTENSA_CORE_H
+
 
 /****************************************************************************
             Parameters Useful for Any Code, USER or PRIVILEGED
 #endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
 
 
-#endif /* XTENSA_FSF_CORE_ISA_H */
+#endif /* _XTENSA_CORE_CONFIGURATION_H */
index 403bd95..2258224 100644 (file)
@@ -30,6 +30,7 @@
 #define QEMU_XTENSA_CPU_QOM_H
 
 #include "qom/cpu.h"
+#include "cpu.h"
 
 #define TYPE_XTENSA_CPU "xtensa-cpu"
 
@@ -40,8 +41,6 @@
 #define XTENSA_CPU_GET_CLASS(obj) \
     OBJECT_GET_CLASS(XtensaCPUClass, (obj), TYPE_XTENSA_CPU)
 
-typedef struct XtensaConfig XtensaConfig;
-
 /**
  * XtensaCPUClass:
  * @parent_realize: The parent class' realize handler.
@@ -61,6 +60,40 @@ typedef struct XtensaCPUClass {
     const XtensaConfig *config;
 } XtensaCPUClass;
 
-typedef struct XtensaCPU XtensaCPU;
+/**
+ * XtensaCPU:
+ * @env: #CPUXtensaState
+ *
+ * An Xtensa CPU.
+ */
+typedef struct XtensaCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUXtensaState env;
+} XtensaCPU;
+
+static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
+{
+    return container_of(env, XtensaCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(xtensa_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(XtensaCPU, env)
+
+void xtensa_cpu_do_interrupt(CPUState *cpu);
+bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
+void xtensa_cpu_do_unassigned_access(CPUState *cpu, hwaddr addr,
+                                     bool is_write, bool is_exec, int opaque,
+                                     unsigned size);
+void xtensa_cpu_dump_state(CPUState *cpu, FILE *f,
+                           fprintf_function cpu_fprintf, int flags);
+hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int xtensa_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int xtensa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
+                                    int is_write, int is_user, uintptr_t retaddr);
 
 #endif
index 5ad08a2..01b251f 100644 (file)
@@ -33,7 +33,6 @@
 #include "cpu.h"
 #include "qemu-common.h"
 #include "migration/vmstate.h"
-#include "exec/exec-all.h"
 
 
 static void xtensa_cpu_set_pc(CPUState *cs, vaddr value)
index 7fe82a3..d0bd9da 100644 (file)
@@ -25,8 +25,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef XTENSA_CPU_H
-#define XTENSA_CPU_H
+#ifndef CPU_XTENSA_H
+#define CPU_XTENSA_H
 
 #define ALIGNED_ONLY
 #define TARGET_LONG_BITS 32
@@ -34,7 +34,6 @@
 #define CPUArchState struct CPUXtensaState
 
 #include "qemu-common.h"
-#include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat.h"
 
@@ -297,7 +296,7 @@ typedef struct XtensaGdbRegmap {
     XtensaGdbReg reg[1 + 16 + 64 + 256 + 256];
 } XtensaGdbRegmap;
 
-struct XtensaConfig {
+typedef struct XtensaConfig {
     const char *name;
     uint64_t options;
     XtensaGdbRegmap gdb_regmap;
@@ -330,7 +329,7 @@ struct XtensaConfig {
 
     xtensa_tlb itlb;
     xtensa_tlb dtlb;
-};
+} XtensaConfig;
 
 typedef struct XtensaConfigList {
     const XtensaConfig *config;
@@ -380,43 +379,9 @@ typedef struct CPUXtensaState {
     CPU_COMMON
 } CPUXtensaState;
 
-/**
- * XtensaCPU:
- * @env: #CPUXtensaState
- *
- * An Xtensa CPU.
- */
-struct XtensaCPU {
-    /*< private >*/
-    CPUState parent_obj;
-    /*< public >*/
-
-    CPUXtensaState env;
-};
-
-static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
-{
-    return container_of(env, XtensaCPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(xtensa_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(XtensaCPU, env)
-
-void xtensa_cpu_do_interrupt(CPUState *cpu);
-bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
-void xtensa_cpu_do_unassigned_access(CPUState *cpu, hwaddr addr,
-                                     bool is_write, bool is_exec, int opaque,
-                                     unsigned size);
-void xtensa_cpu_dump_state(CPUState *cpu, FILE *f,
-                           fprintf_function cpu_fprintf, int flags);
-hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-int xtensa_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int xtensa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
-                                    MMUAccessType access_type,
-                                    int mmu_idx, uintptr_t retaddr);
+#include "cpu-qom.h"
 
+#define cpu_exec cpu_xtensa_exec
 #define cpu_signal_handler cpu_xtensa_signal_handler
 #define cpu_list xtensa_cpu_list
 
@@ -432,6 +397,7 @@ XtensaCPU *cpu_xtensa_init(const char *cpu_model);
 
 void xtensa_translate_init(void);
 void xtensa_breakpoint_handler(CPUState *cs);
+int cpu_xtensa_exec(CPUState *cpu);
 void xtensa_finalize_config(XtensaConfig *config);
 void xtensa_register_core(XtensaConfigList *node);
 void check_interrupts(CPUXtensaState *s);
@@ -541,7 +507,7 @@ static inline int cpu_mmu_index(CPUXtensaState *env, bool ifetch)
 #define XTENSA_TBFLAG_WINDOW_SHIFT 15
 
 static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
-        target_ulong *cs_base, uint32_t *flags)
+        target_ulong *cs_base, int *flags)
 {
     CPUState *cs = CPU(xtensa_env_get_cpu(env));
 
@@ -583,5 +549,6 @@ static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
 }
 
 #include "exec/cpu-all.h"
+#include "exec/exec-all.h"
 
 #endif
index fa5469a..51d4db0 100644 (file)
@@ -19,9 +19,7 @@
  */
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "cpu.h"
 #include "exec/gdbstub.h"
-#include "qemu/log.h"
 
 int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
 {
index 768b32c..839f4a7 100644 (file)
@@ -108,7 +108,7 @@ void xtensa_breakpoint_handler(CPUState *cs)
             if (cause) {
                 debug_exception_env(env, cause);
             }
-            cpu_loop_exit_noexc(cs);
+            cpu_resume_from_signal(cs, NULL);
         }
     }
 }
index 0a4b214..62fa33d 100644 (file)
 #include "cpu.h"
 #include "exec/helper-proto.h"
 #include "qemu/host-utils.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "exec/address-spaces.h"
 #include "qemu/timer.h"
 
 void xtensa_cpu_do_unaligned_access(CPUState *cs,
-        vaddr addr, MMUAccessType access_type,
-        int mmu_idx, uintptr_t retaddr)
+        vaddr addr, int is_write, int is_user, uintptr_t retaddr)
 {
     XtensaCPU *cpu = XTENSA_CPU(cs);
     CPUXtensaState *env = &cpu->env;
@@ -49,19 +47,19 @@ void xtensa_cpu_do_unaligned_access(CPUState *cs,
     }
 }
 
-void tlb_fill(CPUState *cs, target_ulong vaddr, MMUAccessType access_type,
-              int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs,
+              target_ulong vaddr, int is_write, int mmu_idx, uintptr_t retaddr)
 {
     XtensaCPU *cpu = XTENSA_CPU(cs);
     CPUXtensaState *env = &cpu->env;
     uint32_t paddr;
     uint32_t page_size;
     unsigned access;
-    int ret = xtensa_get_physical_addr(env, true, vaddr, access_type, mmu_idx,
+    int ret = xtensa_get_physical_addr(env, true, vaddr, is_write, mmu_idx,
             &paddr, &page_size, &access);
 
     qemu_log_mask(CPU_LOG_MMU, "%s(%08x, %d, %d) -> %08x, ret = %d\n",
-                  __func__, vaddr, access_type, mmu_idx, paddr, ret);
+                  __func__, vaddr, is_write, mmu_idx, paddr, ret);
 
     if (ret == 0) {
         tlb_set_page(cs,
index 4c1e487..9894488 100644 (file)
@@ -36,7 +36,6 @@
 #include "tcg-op.h"
 #include "qemu/log.h"
 #include "sysemu/sysemu.h"
-#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "exec/semihost.h"
 
@@ -219,7 +218,6 @@ void xtensa_translate_init(void)
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    tcg_ctx.tcg_env = cpu_env;
     cpu_pc = tcg_global_mem_new_i32(cpu_env,
             offsetof(CPUXtensaState, pc), "pc");
 
@@ -420,11 +418,9 @@ static void gen_jump(DisasContext *dc, TCGv dest)
 static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
 {
     TCGv_i32 tmp = tcg_const_i32(dest);
-#ifndef CONFIG_USER_ONLY
     if (((dc->tb->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
         slot = -1;
     }
-#endif
     gen_jump_slot(dc, tmp, slot);
     tcg_temp_free(tmp);
 }
@@ -450,11 +446,9 @@ static void gen_callw(DisasContext *dc, int callinc, TCGv_i32 dest)
 static void gen_callwi(DisasContext *dc, int callinc, uint32_t dest, int slot)
 {
     TCGv_i32 tmp = tcg_const_i32(dest);
-#ifndef CONFIG_USER_ONLY
     if (((dc->tb->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
         slot = -1;
     }
-#endif
     gen_callw_slot(dc, callinc, tmp, slot);
     tcg_temp_free(tmp);
 }
@@ -3154,8 +3148,7 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
     gen_tb_end(tb, insn_count);
 
 #ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("----------------\n");
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
         log_target_disas(cs, pc_start, dc.pc - pc_start, 0);
index a1d101f..19a04a6 100644 (file)
@@ -10,8 +10,8 @@
  * See the COPYING file in the top-level directory for details.
  */
 
-#ifndef AARCH64_TCG_TARGET_H
-#define AARCH64_TCG_TARGET_H
+#ifndef TCG_TARGET_AARCH64
+#define TCG_TARGET_AARCH64 1
 
 #define TCG_TARGET_INSN_UNIT_SIZE  4
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 24
@@ -106,4 +106,4 @@ static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
     __builtin___clear_cache((char *)start, (char *)stop);
 }
 
-#endif /* AARCH64_TCG_TARGET_H */
+#endif /* TCG_TARGET_AARCH64 */
index 08b2d03..a8fb442 100644 (file)
@@ -73,18 +73,6 @@ static inline void reloc_pc26(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
     *code_ptr = deposit32(*code_ptr, 0, 26, offset);
 }
 
-static inline void reloc_pc26_atomic(tcg_insn_unit *code_ptr,
-                                     tcg_insn_unit *target)
-{
-    ptrdiff_t offset = target - code_ptr;
-    tcg_insn_unit insn;
-    tcg_debug_assert(offset == sextract64(offset, 0, 26));
-    /* read instruction, mask away previous PC_REL26 parameter contents,
-       set the proper offset, then write back the instruction. */
-    insn = atomic_read(code_ptr);
-    atomic_set(code_ptr, deposit32(insn, 0, 26, offset));
-}
-
 static inline void reloc_pc19(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
 {
     ptrdiff_t offset = target - code_ptr;
@@ -716,16 +704,6 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
                  arg, arg1, arg2);
 }
 
-static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
-                               TCGReg base, intptr_t ofs)
-{
-    if (val == 0) {
-        tcg_out_st(s, type, TCG_REG_XZR, base, ofs);
-        return true;
-    }
-    return false;
-}
-
 static inline void tcg_out_bfm(TCGContext *s, TCGType ext, TCGReg rd,
                                TCGReg rn, unsigned int a, unsigned int b)
 {
@@ -857,7 +835,7 @@ void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
     tcg_insn_unit *code_ptr = (tcg_insn_unit *)jmp_addr;
     tcg_insn_unit *target = (tcg_insn_unit *)addr;
 
-    reloc_pc26_atomic(code_ptr, target);
+    reloc_pc26(code_ptr, target);
     flush_icache_range(jmp_addr, jmp_addr + 4);
 }
 
@@ -1081,20 +1059,19 @@ static void tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, TCGMemOp opc,
     int tlb_offset = is_read ?
         offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
         : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
-    int a_bits = get_alignment_bits(opc);
+    int s_mask = (1 << (opc & MO_SIZE)) - 1;
     TCGReg base = TCG_AREG0, x3;
     uint64_t tlb_mask;
 
     /* For aligned accesses, we check the first byte and include the alignment
        bits within the address.  For unaligned access, we check that we don't
        cross pages using the address of the last byte of the access.  */
-    if (a_bits >= 0) {
-        /* A byte access or an alignment check required */
-        tlb_mask = TARGET_PAGE_MASK | ((1 << a_bits) - 1);
+    if ((opc & MO_AMASK) == MO_ALIGN || s_mask == 0) {
+        tlb_mask = TARGET_PAGE_MASK | s_mask;
         x3 = addr_reg;
     } else {
         tcg_out_insn(s, 3401, ADDI, TARGET_LONG_BITS == 64,
-                     TCG_REG_X3, addr_reg, (1 << (opc & MO_SIZE)) - 1);
+                     TCG_REG_X3, addr_reg, s_mask);
         tlb_mask = TARGET_PAGE_MASK;
         x3 = TCG_REG_X3;
     }
@@ -1317,13 +1294,12 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 #ifndef USE_DIRECT_JUMP
 #error "USE_DIRECT_JUMP required for aarch64"
 #endif
-        /* consistency for USE_DIRECT_JUMP */
-        tcg_debug_assert(s->tb_jmp_insn_offset != NULL);
-        s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
+        tcg_debug_assert(s->tb_jmp_offset != NULL); /* consistency for USE_DIRECT_JUMP */
+        s->tb_jmp_offset[a0] = tcg_current_code_size(s);
         /* actual branch destination will be patched by
            aarch64_tb_set_jmp_target later, beware retranslation. */
         tcg_out_goto_noaddr(s);
-        s->tb_jmp_reset_offset[a0] = tcg_current_code_size(s);
+        s->tb_next_offset[a0] = tcg_current_code_size(s);
         break;
 
     case INDEX_op_br:
index a0e1acf..6559f80 100644 (file)
@@ -22,9 +22,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
-#ifndef ARM_TCG_TARGET_H
-#define ARM_TCG_TARGET_H
+#ifndef TCG_TARGET_ARM 
+#define TCG_TARGET_ARM 1
 
 #undef TCG_TARGET_STACK_GROWSUP
 #define TCG_TARGET_INSN_UNIT_SIZE 4
index 172feba..2b7fbdd 100644 (file)
@@ -121,14 +121,6 @@ static inline void reloc_pc24(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
     *code_ptr = (*code_ptr & ~0xffffff) | (offset & 0xffffff);
 }
 
-static inline void reloc_pc24_atomic(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
-{
-    ptrdiff_t offset = (tcg_ptr_byte_diff(target, code_ptr) - 8) >> 2;
-    tcg_insn_unit insn = atomic_read(code_ptr);
-    tcg_debug_assert(offset == sextract32(offset, 0, 24));
-    atomic_set(code_ptr, deposit32(insn, 0, 24, offset));
-}
-
 static void patch_reloc(tcg_insn_unit *code_ptr, int type,
                         intptr_t value, intptr_t addend)
 {
@@ -1046,16 +1038,6 @@ static void tcg_out_call(TCGContext *s, tcg_insn_unit *addr)
     }
 }
 
-void arm_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
-{
-    tcg_insn_unit *code_ptr = (tcg_insn_unit *)jmp_addr;
-    tcg_insn_unit *target = (tcg_insn_unit *)addr;
-
-    /* we could use a ldr pc, [pc, #-4] kind of branch and avoid the flush */
-    reloc_pc24_atomic(code_ptr, target);
-    flush_icache_range(jmp_addr, jmp_addr + 4);
-}
-
 static inline void tcg_out_goto_label(TCGContext *s, int cond, TCGLabel *l)
 {
     if (l->has_value) {
@@ -1665,17 +1647,17 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         tcg_out_goto(s, COND_AL, tb_ret_addr);
         break;
     case INDEX_op_goto_tb:
-        if (s->tb_jmp_insn_offset) {
+        if (s->tb_jmp_offset) {
             /* Direct jump method */
-            s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
+            s->tb_jmp_offset[args[0]] = tcg_current_code_size(s);
             tcg_out_b_noaddr(s, COND_AL);
         } else {
             /* Indirect jump method */
-            intptr_t ptr = (intptr_t)(s->tb_jmp_target_addr + args[0]);
+            intptr_t ptr = (intptr_t)(s->tb_next + args[0]);
             tcg_out_movi32(s, COND_AL, TCG_REG_R0, ptr & ~0xfff);
             tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, ptr & 0xfff);
         }
-        s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
+        s->tb_next_offset[args[0]] = tcg_current_code_size(s);
         break;
     case INDEX_op_br:
         tcg_out_goto_label(s, COND_AL, arg_label(args[0]));
@@ -2046,12 +2028,6 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
     tcg_out_st32(s, COND_AL, arg, arg1, arg2);
 }
 
-static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
-                               TCGReg base, intptr_t ofs)
-{
-    return false;
-}
-
 static inline void tcg_out_mov(TCGContext *s, TCGType type,
                                TCGReg ret, TCGReg arg)
 {
index 524cfc6..92be341 100644 (file)
@@ -21,9 +21,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
-#ifndef I386_TCG_TARGET_H
-#define I386_TCG_TARGET_H
+#ifndef TCG_TARGET_I386 
+#define TCG_TARGET_I386 1
 
 #define TCG_TARGET_INSN_UNIT_SIZE  1
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 31
index 6f8cdca..007407c 100644 (file)
@@ -710,19 +710,12 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
     tcg_out_modrm_offset(s, opc, arg, arg1, arg2);
 }
 
-static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
-                        TCGReg base, intptr_t ofs)
+static inline void tcg_out_sti(TCGContext *s, TCGType type, TCGReg base,
+                               tcg_target_long ofs, tcg_target_long val)
 {
-    int rexw = 0;
-    if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I64) {
-        if (val != (int32_t)val) {
-            return false;
-        }
-        rexw = P_REXW;
-    }
-    tcg_out_modrm_offset(s, OPC_MOVL_EvIz | rexw, 0, base, ofs);
+    int opc = OPC_MOVL_EvIz + (type == TCG_TYPE_I64 ? P_REXW : 0);
+    tcg_out_modrm_offset(s, opc, 0, base, ofs);
     tcg_out32(s, val);
-    return true;
 }
 
 static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
@@ -1130,21 +1123,6 @@ static void tcg_out_jmp(TCGContext *s, tcg_insn_unit *dest)
     tcg_out_branch(s, 0, dest);
 }
 
-static void tcg_out_nopn(TCGContext *s, int n)
-{
-    int i;
-    /* Emit 1 or 2 operand size prefixes for the standard one byte nop,
-     * "xchg %eax,%eax", forming "xchg %ax,%ax". All cores accept the
-     * duplicate prefix, and all of the interesting recent cores can
-     * decode and discard the duplicates in a single cycle.
-     */
-    tcg_debug_assert(n >= 1);
-    for (i = 1; i < n; ++i) {
-        tcg_out8(s, 0x66);
-    }
-    tcg_out8(s, 0x90);
-}
-
 #if defined(CONFIG_SOFTMMU)
 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
  *                                     int mmu_idx, uintptr_t ra)
@@ -1202,8 +1180,8 @@ static inline void tcg_out_tlb_load(TCGContext *s, TCGReg addrlo, TCGReg addrhi,
     TCGType ttype = TCG_TYPE_I32;
     TCGType tlbtype = TCG_TYPE_I32;
     int trexw = 0, hrexw = 0, tlbrexw = 0;
-    int a_bits = get_alignment_bits(opc);
-    target_ulong tlb_mask;
+    int s_mask = (1 << (opc & MO_SIZE)) - 1;
+    bool aligned = (opc & MO_AMASK) == MO_ALIGN || s_mask == 0;
 
     if (TCG_TARGET_REG_BITS == 64) {
         if (TARGET_LONG_BITS == 64) {
@@ -1220,22 +1198,19 @@ static inline void tcg_out_tlb_load(TCGContext *s, TCGReg addrlo, TCGReg addrhi,
     }
 
     tcg_out_mov(s, tlbtype, r0, addrlo);
-    if (a_bits >= 0) {
-        /* A byte access or an alignment check required */
+    if (aligned) {
         tcg_out_mov(s, ttype, r1, addrlo);
-        tlb_mask = TARGET_PAGE_MASK | ((1 << a_bits) - 1);
     } else {
         /* For unaligned access check that we don't cross pages using
            the page address of the last byte.  */
-        tcg_out_modrm_offset(s, OPC_LEA + trexw, r1, addrlo,
-                             (1 << (opc & MO_SIZE)) - 1);
-        tlb_mask = TARGET_PAGE_MASK;
+        tcg_out_modrm_offset(s, OPC_LEA + trexw, r1, addrlo, s_mask);
     }
 
     tcg_out_shifti(s, SHIFT_SHR + tlbrexw, r0,
                    TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
 
-    tgen_arithi(s, ARITH_AND + trexw, r1, tlb_mask, 0);
+    tgen_arithi(s, ARITH_AND + trexw, r1,
+                TARGET_PAGE_MASK | (aligned ? s_mask : 0), 0);
     tgen_arithi(s, ARITH_AND + tlbrexw, r0,
                 (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
 
@@ -1331,10 +1306,10 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
             ofs += 4;
         }
 
-        tcg_out_sti(s, TCG_TYPE_I32, oi, TCG_REG_ESP, ofs);
+        tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, oi);
         ofs += 4;
 
-        tcg_out_sti(s, TCG_TYPE_PTR, (uintptr_t)l->raddr, TCG_REG_ESP, ofs);
+        tcg_out_sti(s, TCG_TYPE_PTR, TCG_REG_ESP, ofs, (uintptr_t)l->raddr);
     } else {
         tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
         /* The second argument is already loaded with addrlo.  */
@@ -1423,7 +1398,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
             ofs += 4;
         }
 
-        tcg_out_sti(s, TCG_TYPE_I32, oi, TCG_REG_ESP, ofs);
+        tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, oi);
         ofs += 4;
 
         retaddr = TCG_REG_EAX;
@@ -1800,25 +1775,17 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         tcg_out_jmp(s, tb_ret_addr);
         break;
     case INDEX_op_goto_tb:
-        if (s->tb_jmp_insn_offset) {
+        if (s->tb_jmp_offset) {
             /* direct jump method */
-            int gap;
-            /* jump displacement must be aligned for atomic patching;
-             * see if we need to add extra nops before jump
-             */
-            gap = tcg_pcrel_diff(s, QEMU_ALIGN_PTR_UP(s->code_ptr + 1, 4));
-            if (gap != 1) {
-                tcg_out_nopn(s, gap - 1);
-            }
             tcg_out8(s, OPC_JMP_long); /* jmp im */
-            s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
+            s->tb_jmp_offset[args[0]] = tcg_current_code_size(s);
             tcg_out32(s, 0);
         } else {
             /* indirect jump method */
             tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
-                                 (intptr_t)(s->tb_jmp_target_addr + args[0]));
+                                 (intptr_t)(s->tb_next + args[0]));
         }
-        s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
+        s->tb_next_offset[args[0]] = tcg_current_code_size(s);
         break;
     case INDEX_op_br:
         tcg_out_jxx(s, JCC_JMP, arg_label(args[0]), 0);
index 6dddb7f..ae9b79f 100644 (file)
@@ -22,9 +22,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
-#ifndef IA64_TCG_TARGET_H
-#define IA64_TCG_TARGET_H
+#ifndef TCG_TARGET_IA64 
+#define TCG_TARGET_IA64 1
 
 #define TCG_TARGET_INSN_UNIT_SIZE 16
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 21
index c91f392..7557e6a 100644 (file)
@@ -881,13 +881,13 @@ static void tcg_out_exit_tb(TCGContext *s, tcg_target_long arg)
 
 static inline void tcg_out_goto_tb(TCGContext *s, TCGArg arg)
 {
-    if (s->tb_jmp_insn_offset) {
+    if (s->tb_jmp_offset) {
         /* direct jump method */
         tcg_abort();
     } else {
         /* indirect jump method */
         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2,
-                     (tcg_target_long)(s->tb_jmp_target_addr + arg));
+                     (tcg_target_long)(s->tb_next + arg));
         tcg_out_bundle(s, MmI,
                        tcg_opc_m1 (TCG_REG_P0, OPC_LD8_M1,
                                    TCG_REG_R2, TCG_REG_R2),
@@ -900,7 +900,7 @@ static inline void tcg_out_goto_tb(TCGContext *s, TCGArg arg)
                        tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4,
                                    TCG_REG_B6));
     }
-    s->tb_jmp_reset_offset[arg] = tcg_current_code_size(s);
+    s->tb_next_offset[arg] = tcg_current_code_size(s);
 }
 
 static inline void tcg_out_jmp(TCGContext *s, TCGArg addr)
@@ -973,16 +973,6 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
     }
 }
 
-static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
-                               TCGReg base, intptr_t ofs)
-{
-    if (val == 0) {
-        tcg_out_st(s, type, TCG_REG_R0, base, ofs);
-        return true;
-    }
-    return false;
-}
-
 static inline void tcg_out_alu(TCGContext *s, uint64_t opc_a1, uint64_t opc_a3,
                                TCGReg ret, TCGArg arg1, int const_arg1,
                                TCGArg arg2, int const_arg2)
index 3aeac87..b1cda37 100644 (file)
@@ -23,9 +23,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
-#ifndef MIPS_TCG_TARGET_H
-#define MIPS_TCG_TARGET_H
+#ifndef TCG_TARGET_MIPS 
+#define TCG_TARGET_MIPS 1
 
 #define TCG_TARGET_INSN_UNIT_SIZE 4
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 16
index 2f9be48..aaf881c 100644 (file)
@@ -576,16 +576,6 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
     tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
 }
 
-static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
-                               TCGReg base, intptr_t ofs)
-{
-    if (val == 0) {
-        tcg_out_st(s, type, TCG_REG_ZERO, base, ofs);
-        return true;
-    }
-    return false;
-}
-
 static inline void tcg_out_addi(TCGContext *s, TCGReg reg, TCGArg val)
 {
     if (val == (int16_t)val) {
@@ -1407,19 +1397,19 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         }
         break;
     case INDEX_op_goto_tb:
-        if (s->tb_jmp_insn_offset) {
+        if (s->tb_jmp_offset) {
             /* direct jump method */
-            s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
+            s->tb_jmp_offset[a0] = tcg_current_code_size(s);
             /* Avoid clobbering the address during retranslation.  */
             tcg_out32(s, OPC_J | (*(uint32_t *)s->code_ptr & 0x3ffffff));
         } else {
             /* indirect jump method */
             tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_REG_ZERO,
-                       (uintptr_t)(s->tb_jmp_target_addr + a0));
+                       (uintptr_t)(s->tb_next + a0));
             tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
         }
         tcg_out_nop(s);
-        s->tb_jmp_reset_offset[a0] = tcg_current_code_size(s);
+        s->tb_next_offset[a0] = tcg_current_code_size(s);
         break;
     case INDEX_op_br:
         tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO,
@@ -1895,6 +1885,7 @@ static void tcg_target_init(TCGContext *s)
 
 void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
 {
-    atomic_set((uint32_t *)jmp_addr, deposit32(OPC_J, 0, 26, addr >> 2));
+    uint32_t *ptr = (uint32_t *)jmp_addr;
+    *ptr = deposit32(*ptr, 0, 26, addr >> 2);
     flush_icache_range(jmp_addr, jmp_addr + 4);
 }
index cffe89b..f011608 100644 (file)
@@ -24,8 +24,9 @@
  */
 
 #include "qemu/osdep.h"
+
+
 #include "qemu-common.h"
-#include "exec/cpu-common.h"
 #include "tcg-op.h"
 
 #define CASE_OP_32_64(x)                        \
@@ -82,6 +83,37 @@ static void init_temp_info(TCGArg temp)
     }
 }
 
+static TCGOp *insert_op_before(TCGContext *s, TCGOp *old_op,
+                                TCGOpcode opc, int nargs)
+{
+    int oi = s->gen_next_op_idx;
+    int pi = s->gen_next_parm_idx;
+    int prev = old_op->prev;
+    int next = old_op - s->gen_op_buf;
+    TCGOp *new_op;
+
+    tcg_debug_assert(oi < OPC_BUF_SIZE);
+    tcg_debug_assert(pi + nargs <= OPPARAM_BUF_SIZE);
+    s->gen_next_op_idx = oi + 1;
+    s->gen_next_parm_idx = pi + nargs;
+
+    new_op = &s->gen_op_buf[oi];
+    *new_op = (TCGOp){
+        .opc = opc,
+        .args = pi,
+        .prev = prev,
+        .next = next
+    };
+    if (prev >= 0) {
+        s->gen_op_buf[prev].next = oi;
+    } else {
+        s->gen_first_op_idx = oi;
+    }
+    old_op->prev = oi;
+
+    return new_op;
+}
+
 static int op_bits(TCGOpcode op)
 {
     const TCGOpDef *def = &tcg_op_defs[op];
@@ -552,7 +584,7 @@ void tcg_optimize(TCGContext *s)
     nb_globals = s->nb_globals;
     reset_all_temps(nb_temps);
 
-    for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
+    for (oi = s->gen_first_op_idx; oi >= 0; oi = oi_next) {
         tcg_target_ulong mask, partmask, affected;
         int nb_oargs, nb_iargs, i;
         TCGArg tmp;
@@ -1089,7 +1121,7 @@ void tcg_optimize(TCGContext *s)
                 uint64_t a = ((uint64_t)ah << 32) | al;
                 uint64_t b = ((uint64_t)bh << 32) | bl;
                 TCGArg rl, rh;
-                TCGOp *op2 = tcg_op_insert_before(s, op, INDEX_op_movi_i32, 2);
+                TCGOp *op2 = insert_op_before(s, op, INDEX_op_movi_i32, 2);
                 TCGArg *args2 = &s->gen_opparam_buf[op2->args];
 
                 if (opc == INDEX_op_add2_i32) {
@@ -1115,7 +1147,7 @@ void tcg_optimize(TCGContext *s)
                 uint32_t b = temps[args[3]].val;
                 uint64_t r = (uint64_t)a * b;
                 TCGArg rl, rh;
-                TCGOp *op2 = tcg_op_insert_before(s, op, INDEX_op_movi_i32, 2);
+                TCGOp *op2 = insert_op_before(s, op, INDEX_op_movi_i32, 2);
                 TCGArg *args2 = &s->gen_opparam_buf[op2->args];
 
                 rl = args[0];
index dd032f2..b4f0818 100644 (file)
@@ -21,9 +21,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
-#ifndef PPC_TCG_TARGET_H
-#define PPC_TCG_TARGET_H
+#ifndef TCG_TARGET_PPC64 
+#define TCG_TARGET_PPC64 1
 
 #ifdef _ARCH_PPC64
 # define TCG_TARGET_REG_BITS  64
index eaf1bd9..00bb90f 100644 (file)
@@ -857,12 +857,6 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
     tcg_out_mem_long(s, opi, opx, arg, arg1, arg2);
 }
 
-static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
-                               TCGReg base, intptr_t ofs)
-{
-    return false;
-}
-
 static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
                         int const_arg2, int cr, TCGType type)
 {
@@ -1243,7 +1237,6 @@ static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
     tcg_out_bc(s, BC | BI(7, CR_EQ) | BO_COND_TRUE, arg_label(args[5]));
 }
 
-#ifdef __powerpc64__
 void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
 {
     tcg_insn_unit i1, i2;
@@ -1272,18 +1265,11 @@ void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
     pair = (uint64_t)i2 << 32 | i1;
 #endif
 
-    atomic_set((uint64_t *)jmp_addr, pair);
+    /* ??? __atomic_store_8, presuming there's some way to do that
+       for 32-bit, otherwise this is good enough for 64-bit.  */
+    *(uint64_t *)jmp_addr = pair;
     flush_icache_range(jmp_addr, jmp_addr + 8);
 }
-#else
-void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
-{
-    intptr_t diff = addr - jmp_addr;
-    tcg_debug_assert(in_range_b(diff));
-    atomic_set((uint32_t *)jmp_addr, B | (diff & 0x3fffffc));
-    flush_icache_range(jmp_addr, jmp_addr + 4);
-}
-#endif
 
 static void tcg_out_call(TCGContext *s, tcg_insn_unit *target)
 {
@@ -1405,7 +1391,6 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp opc,
     int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
     TCGReg base = TCG_AREG0;
     TCGMemOp s_bits = opc & MO_SIZE;
-    int a_bits = get_alignment_bits(opc);
 
     /* Extract the page index, shifted into place for tlb index.  */
     if (TCG_TARGET_REG_BITS == 64) {
@@ -1463,17 +1448,14 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp opc,
          * the bottom bits and thus trigger a comparison failure on
          * unaligned accesses
          */
-        if (a_bits < 0) {
-            a_bits = s_bits;
-        }
         tcg_out_rlw(s, RLWINM, TCG_REG_R0, addrlo, 0,
-                    (32 - a_bits) & 31, 31 - TARGET_PAGE_BITS);
-    } else if (a_bits) {
-        /* More than byte access, we need to handle alignment */
-        if (a_bits > 0) {
+                    (32 - s_bits) & 31, 31 - TARGET_PAGE_BITS);
+    } else if (s_bits) {
+        /* > byte access, we need to handle alignment */
+        if ((opc & MO_AMASK) == MO_ALIGN) {
             /* Alignment required by the front-end, same as 32-bits */
             tcg_out_rld(s, RLDICL, TCG_REG_R0, addrlo,
-                        64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - a_bits);
+                        64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - s_bits);
             tcg_out_rld(s, RLDICL, TCG_REG_R0, TCG_REG_R0, TARGET_PAGE_BITS, 0);
        } else {
            /* We support unaligned accesses, we need to make sure we fail
@@ -1912,23 +1894,17 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         tcg_out_b(s, 0, tb_ret_addr);
         break;
     case INDEX_op_goto_tb:
-        tcg_debug_assert(s->tb_jmp_insn_offset);
-        /* Direct jump. */
-#ifdef __powerpc64__
-        /* Ensure the next insns are 8-byte aligned. */
+        tcg_debug_assert(s->tb_jmp_offset);
+        /* Direct jump.  Ensure the next insns are 8-byte aligned. */
         if ((uintptr_t)s->code_ptr & 7) {
             tcg_out32(s, NOP);
         }
-        s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
+        s->tb_jmp_offset[args[0]] = tcg_current_code_size(s);
         /* To be replaced by either a branch+nop or a load into TMP1.  */
         s->code_ptr += 2;
         tcg_out32(s, MTSPR | RS(TCG_REG_TMP1) | CTR);
         tcg_out32(s, BCCTR | BO_ALWAYS);
-#else
-        /* To be replaced by a branch.  */
-        s->code_ptr++;
-#endif
-        s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
+        s->tb_next_offset[args[0]] = tcg_current_code_size(s);
         break;
     case INDEX_op_br:
         {
index 0c1af24..d9dc038 100644 (file)
@@ -21,9 +21,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
-#ifndef S390_TCG_TARGET_H
-#define S390_TCG_TARGET_H
+#ifndef TCG_TARGET_S390 
+#define TCG_TARGET_S390 1
 
 #define TCG_TARGET_INSN_UNIT_SIZE 2
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 19
index 5a7495b..5805532 100644 (file)
@@ -219,8 +219,6 @@ typedef enum S390Opcode {
     RX_ST       = 0x50,
     RX_STC      = 0x42,
     RX_STH      = 0x40,
-
-    NOP         = 0x0707,
 } S390Opcode;
 
 #ifdef CONFIG_DEBUG_TCG
@@ -798,12 +796,6 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
     }
 }
 
-static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
-                               TCGReg base, intptr_t ofs)
-{
-    return false;
-}
-
 /* load data from an absolute host address */
 static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs)
 {
@@ -1505,19 +1497,18 @@ QEMU_BUILD_BUG_ON(offsetof(CPUArchState, tlb_table[NB_MMU_MODES - 1][1])
 static TCGReg tcg_out_tlb_read(TCGContext* s, TCGReg addr_reg, TCGMemOp opc,
                                int mem_index, bool is_ld)
 {
-    int a_bits = get_alignment_bits(opc);
+    int s_mask = (1 << (opc & MO_SIZE)) - 1;
     int ofs, a_off;
     uint64_t tlb_mask;
 
     /* For aligned accesses, we check the first byte and include the alignment
        bits within the address.  For unaligned access, we check that we don't
        cross pages using the address of the last byte of the access.  */
-    if (a_bits >= 0) {
-        /* A byte access or an alignment check required */
+    if ((opc & MO_AMASK) == MO_ALIGN || s_mask == 0) {
         a_off = 0;
-        tlb_mask = TARGET_PAGE_MASK | ((1 << a_bits) - 1);
+        tlb_mask = TARGET_PAGE_MASK | s_mask;
     } else {
-        a_off = (1 << (opc & MO_SIZE)) - 1;
+        a_off = s_mask;
         tlb_mask = TARGET_PAGE_MASK;
     }
 
@@ -1724,24 +1715,17 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         break;
 
     case INDEX_op_goto_tb:
-        if (s->tb_jmp_insn_offset) {
-            /* branch displacement must be aligned for atomic patching;
-             * see if we need to add extra nop before branch
-             */
-            if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
-                tcg_out16(s, NOP);
-            }
+        if (s->tb_jmp_offset) {
             tcg_out16(s, RIL_BRCL | (S390_CC_ALWAYS << 4));
-            s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
+            s->tb_jmp_offset[args[0]] = tcg_current_code_size(s);
             s->code_ptr += 2;
         } else {
-            /* load address stored at s->tb_jmp_target_addr + args[0] */
-            tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_TMP0,
-                           s->tb_jmp_target_addr + args[0]);
+            /* load address stored at s->tb_next + args[0] */
+            tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_TMP0, s->tb_next + args[0]);
             /* and go there */
             tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_TMP0);
         }
-        s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
+        s->tb_next_offset[args[0]] = tcg_current_code_size(s);
         break;
 
     OP_32_64(ld8u):
index 88f9c90..2cd72d2 100644 (file)
@@ -21,9 +21,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
-#ifndef SPARC_TCG_TARGET_H
-#define SPARC_TCG_TARGET_H
+#ifndef TCG_TARGET_SPARC 
+#define TCG_TARGET_SPARC 1
 
 #define TCG_TARGET_REG_BITS 64
 
index 8e98172..d641cfd 100644 (file)
@@ -504,16 +504,6 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
     tcg_out_ldst(s, arg, arg1, arg2, (type == TCG_TYPE_I32 ? STW : STX));
 }
 
-static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
-                               TCGReg base, intptr_t ofs)
-{
-    if (val == 0) {
-        tcg_out_st(s, type, TCG_REG_G0, base, ofs);
-        return true;
-    }
-    return false;
-}
-
 static void tcg_out_ld_ptr(TCGContext *s, TCGReg ret, uintptr_t arg)
 {
     tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ff);
@@ -1239,19 +1229,18 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         }
         break;
     case INDEX_op_goto_tb:
-        if (s->tb_jmp_insn_offset) {
+        if (s->tb_jmp_offset) {
             /* direct jump method */
-            s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
+            s->tb_jmp_offset[a0] = tcg_current_code_size(s);
             /* Make sure to preserve links during retranslation.  */
             tcg_out32(s, CALL | (*s->code_ptr & ~INSN_OP(-1)));
         } else {
             /* indirect jump method */
-            tcg_out_ld_ptr(s, TCG_REG_T1,
-                           (uintptr_t)(s->tb_jmp_target_addr + a0));
+            tcg_out_ld_ptr(s, TCG_REG_T1, (uintptr_t)(s->tb_next + a0));
             tcg_out_arithi(s, TCG_REG_G0, TCG_REG_T1, 0, JMPL);
         }
         tcg_out_nop(s);
-        s->tb_jmp_reset_offset[a0] = tcg_current_code_size(s);
+        s->tb_next_offset[a0] = tcg_current_code_size(s);
         break;
     case INDEX_op_br:
         tcg_out_bpcc(s, COND_A, BPCC_PT, arg_label(a0));
@@ -1658,6 +1647,6 @@ void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
        the code_gen_buffer can't be larger than 2GB.  */
     tcg_debug_assert(disp == (int32_t)disp);
 
-    atomic_set(ptr, deposit32(CALL, 0, 30, disp >> 2));
+    *ptr = CALL | (uint32_t)disp >> 2;
     flush_icache_range(jmp_addr, jmp_addr + 4);
 }
index 2f139de..97305a3 100644 (file)
@@ -23,8 +23,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "exec/cpu-common.h"
 #include "tcg/tcg.h"
 
 #if defined(CONFIG_TCG_INTERPRETER)
index 0243c99..f554b86 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
 #include "tcg.h"
 #include "tcg-op.h"
-#include "trace-tcg.h"
-#include "trace/mem.h"
 
 /* Reduce the number of ifdefs below.  This assumes that all uses of
    TCGV_HIGH and TCGV_LOW are properly protected by a conditional that
@@ -52,7 +47,7 @@ static void tcg_emit_op(TCGContext *ctx, TCGOpcode opc, int args)
     int pi = oi - 1;
 
     tcg_debug_assert(oi < OPC_BUF_SIZE);
-    ctx->gen_op_buf[0].prev = oi;
+    ctx->gen_last_op_idx = oi;
     ctx->gen_next_op_idx = ni;
 
     ctx->gen_op_buf[oi] = (TCGOp){
@@ -1851,9 +1846,6 @@ void tcg_gen_goto_tb(unsigned idx)
 
 static inline TCGMemOp tcg_canonicalize_memop(TCGMemOp op, bool is64, bool st)
 {
-    /* Trigger the asserts within as early as possible.  */
-    (void)get_alignment_bits(op);
-
     switch (op & MO_SIZE) {
     case MO_8:
         op &= ~MO_BSWAP;
@@ -1915,16 +1907,12 @@ static void gen_ldst_i64(TCGOpcode opc, TCGv_i64 val, TCGv addr,
 void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
 {
     memop = tcg_canonicalize_memop(memop, 0, 0);
-    trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env,
-                               addr, trace_mem_get_info(memop, 0));
     gen_ldst_i32(INDEX_op_qemu_ld_i32, val, addr, memop, idx);
 }
 
 void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
 {
     memop = tcg_canonicalize_memop(memop, 0, 1);
-    trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env,
-                               addr, trace_mem_get_info(memop, 1));
     gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx);
 }
 
@@ -1941,8 +1929,6 @@ void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
     }
 
     memop = tcg_canonicalize_memop(memop, 1, 0);
-    trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env,
-                               addr, trace_mem_get_info(memop, 0));
     gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, memop, idx);
 }
 
@@ -1954,7 +1940,5 @@ void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
     }
 
     memop = tcg_canonicalize_memop(memop, 1, 1);
-    trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env,
-                               addr, trace_mem_get_info(memop, 1));
     gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, memop, idx);
 }
index f217e80..c446d3d 100644 (file)
@@ -753,19 +753,6 @@ static inline void tcg_gen_exit_tb(uintptr_t val)
     tcg_gen_op1i(INDEX_op_exit_tb, val);
 }
 
-/**
- * tcg_gen_goto_tb() - output goto_tb TCG operation
- * @idx: Direct jump slot index (0 or 1)
- *
- * See tcg/README for more info about this TCG operation.
- *
- * NOTE: In softmmu emulation, direct jumps with goto_tb are only safe within
- * the pages this TB resides in because we don't take care of direct jumps when
- * address mapping changes, e.g. in tlb_flush(). In user mode, there's only a
- * static address translation, so the destination address is always valid, TBs
- * are always invalidated properly, and direct jumps are reset when mapping
- * changes.
- */
 void tcg_gen_goto_tb(unsigned idx);
 
 #if TARGET_LONG_BITS == 32
index 42417bd..796addd 100644 (file)
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -23,6 +23,7 @@
  */
 
 /* define it to use liveness analysis (better code) */
+#define USE_LIVENESS_ANALYSIS
 #define USE_TCG_OPTIMIZATIONS
 
 #include "qemu/osdep.h"
 #define NO_CPU_IO_DEFS
 #include "cpu.h"
 
-#include "qemu/host-utils.h"
-#include "qemu/timer.h"
-#include "exec/cpu-common.h"
-#include "exec/exec-all.h"
-
 #include "tcg-op.h"
 
 #if UINTPTR_MAX == UINT32_MAX
@@ -107,8 +103,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
                        const int *const_args);
 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
                        intptr_t arg2);
-static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
-                        TCGReg base, intptr_t ofs);
 static void tcg_out_call(TCGContext *s, tcg_insn_unit *target);
 static int tcg_target_const_match(tcg_target_long val, TCGType type,
                                   const TCGArgConstraint *arg_ct);
@@ -332,7 +326,7 @@ void tcg_context_init(TCGContext *s)
 
     memset(s, 0, sizeof(*s));
     s->nb_globals = 0;
-
+    
     /* Count total number of arguments and allocate the corresponding
        space */
     total_args = 0;
@@ -437,9 +431,9 @@ void tcg_func_start(TCGContext *s)
     s->goto_tb_issue_mask = 0;
 #endif
 
-    s->gen_op_buf[0].next = 1;
-    s->gen_op_buf[0].prev = 0;
-    s->gen_next_op_idx = 1;
+    s->gen_first_op_idx = 0;
+    s->gen_last_op_idx = -1;
+    s->gen_next_op_idx = 0;
     s->gen_next_parm_idx = 0;
 
     s->be = tcg_malloc(sizeof(TCGBackendData));
@@ -531,12 +525,8 @@ int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
 #endif
 
     if (!base_ts->fixed_reg) {
-        /* We do not support double-indirect registers.  */
-        tcg_debug_assert(!base_ts->indirect_reg);
-        base_ts->indirect_base = 1;
-        s->nb_indirects += (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64
-                            ? 2 : 1);
         indirect_reg = 1;
+        base_ts->indirect_base = 1;
     }
 
     if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) {
@@ -562,7 +552,7 @@ int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
         ts2->mem_offset = offset + (1 - bigendian) * 4;
         pstrcpy(buf, sizeof(buf), name);
         pstrcat(buf, sizeof(buf), "_1");
-        ts2->name = strdup(buf);
+        ts->name = strdup(buf);
     } else {
         ts->base_type = type;
         ts->type = type;
@@ -828,16 +818,16 @@ void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret,
                 real_args++;
             }
 #endif
-           /* If stack grows up, then we will be placing successive
-              arguments at lower addresses, which means we need to
-              reverse the order compared to how we would normally
-              treat either big or little-endian.  For those arguments
-              that will wind up in registers, this still works for
-              HPPA (the only current STACK_GROWSUP target) since the
-              argument registers are *also* allocated in decreasing
-              order.  If another such target is added, this logic may
-              have to get more complicated to differentiate between
-              stack arguments and register arguments.  */
+           /* If stack grows up, then we will be placing successive
+              arguments at lower addresses, which means we need to
+              reverse the order compared to how we would normally
+              treat either big or little-endian.  For those arguments
+              that will wind up in registers, this still works for
+              HPPA (the only current STACK_GROWSUP target) since the
+              argument registers are *also* allocated in decreasing
+              order.  If another such target is added, this logic may
+              have to get more complicated to differentiate between
+              stack arguments and register arguments.  */
 #if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
             s->gen_opparam_buf[pi++] = args[i] + 1;
             s->gen_opparam_buf[pi++] = args[i];
@@ -872,7 +862,7 @@ void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret,
     /* Make sure the calli field didn't overflow.  */
     tcg_debug_assert(s->gen_op_buf[i].calli == real_args);
 
-    s->gen_op_buf[0].prev = i;
+    s->gen_last_op_idx = i;
     s->gen_next_op_idx = i + 1;
     s->gen_next_parm_idx = pi;
 
@@ -1002,34 +992,17 @@ static const char * const ldst_name[] =
     [MO_BEQ]  = "beq",
 };
 
-static const char * const alignment_name[(MO_AMASK >> MO_ASHIFT) + 1] = {
-#ifdef ALIGNED_ONLY
-    [MO_UNALN >> MO_ASHIFT]    = "un+",
-    [MO_ALIGN >> MO_ASHIFT]    = "",
-#else
-    [MO_UNALN >> MO_ASHIFT]    = "",
-    [MO_ALIGN >> MO_ASHIFT]    = "al+",
-#endif
-    [MO_ALIGN_2 >> MO_ASHIFT]  = "al2+",
-    [MO_ALIGN_4 >> MO_ASHIFT]  = "al4+",
-    [MO_ALIGN_8 >> MO_ASHIFT]  = "al8+",
-    [MO_ALIGN_16 >> MO_ASHIFT] = "al16+",
-    [MO_ALIGN_32 >> MO_ASHIFT] = "al32+",
-    [MO_ALIGN_64 >> MO_ASHIFT] = "al64+",
-};
-
 void tcg_dump_ops(TCGContext *s)
 {
     char buf[128];
     TCGOp *op;
     int oi;
 
-    for (oi = s->gen_op_buf[0].next; oi != 0; oi = op->next) {
+    for (oi = s->gen_first_op_idx; oi >= 0; oi = op->next) {
         int i, k, nb_oargs, nb_iargs, nb_cargs;
         const TCGOpDef *def;
         const TCGArg *args;
         TCGOpcode c;
-        int col = 0;
 
         op = &s->gen_op_buf[oi];
         c = op->opc;
@@ -1037,7 +1010,7 @@ void tcg_dump_ops(TCGContext *s)
         args = &s->gen_opparam_buf[op->args];
 
         if (c == INDEX_op_insn_start) {
-            col += qemu_log("%s ----", oi != s->gen_op_buf[0].next ? "\n" : "");
+            qemu_log("%s ----", oi != s->gen_first_op_idx ? "\n" : "");
 
             for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
                 target_ulong a;
@@ -1046,7 +1019,7 @@ void tcg_dump_ops(TCGContext *s)
 #else
                 a = args[i];
 #endif
-                col += qemu_log(" " TARGET_FMT_lx, a);
+                qemu_log(" " TARGET_FMT_lx, a);
             }
         } else if (c == INDEX_op_call) {
             /* variable number of arguments */
@@ -1055,12 +1028,12 @@ void tcg_dump_ops(TCGContext *s)
             nb_cargs = def->nb_cargs;
 
             /* function name, flags, out args */
-            col += qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name,
-                            tcg_find_helper(s, args[nb_oargs + nb_iargs]),
-                            args[nb_oargs + nb_iargs + 1], nb_oargs);
+            qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name,
+                     tcg_find_helper(s, args[nb_oargs + nb_iargs]),
+                     args[nb_oargs + nb_iargs + 1], nb_oargs);
             for (i = 0; i < nb_oargs; i++) {
-                col += qemu_log(",%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
-                                                           args[i]));
+                qemu_log(",%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
+                                                   args[i]));
             }
             for (i = 0; i < nb_iargs; i++) {
                 TCGArg arg = args[nb_oargs + i];
@@ -1068,10 +1041,10 @@ void tcg_dump_ops(TCGContext *s)
                 if (arg != TCG_CALL_DUMMY_ARG) {
                     t = tcg_get_arg_str_idx(s, buf, sizeof(buf), arg);
                 }
-                col += qemu_log(",%s", t);
+                qemu_log(",%s", t);
             }
         } else {
-            col += qemu_log(" %s ", def->name);
+            qemu_log(" %s ", def->name);
 
             nb_oargs = def->nb_oargs;
             nb_iargs = def->nb_iargs;
@@ -1080,17 +1053,17 @@ void tcg_dump_ops(TCGContext *s)
             k = 0;
             for (i = 0; i < nb_oargs; i++) {
                 if (k != 0) {
-                    col += qemu_log(",");
+                    qemu_log(",");
                 }
-                col += qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
-                                                          args[k++]));
+                qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
+                                                   args[k++]));
             }
             for (i = 0; i < nb_iargs; i++) {
                 if (k != 0) {
-                    col += qemu_log(",");
+                    qemu_log(",");
                 }
-                col += qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
-                                                          args[k++]));
+                qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
+                                                   args[k++]));
             }
             switch (c) {
             case INDEX_op_brcond_i32:
@@ -1102,9 +1075,9 @@ void tcg_dump_ops(TCGContext *s)
             case INDEX_op_setcond_i64:
             case INDEX_op_movcond_i64:
                 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
-                    col += qemu_log(",%s", cond_name[args[k++]]);
+                    qemu_log(",%s", cond_name[args[k++]]);
                 } else {
-                    col += qemu_log(",$0x%" TCG_PRIlx, args[k++]);
+                    qemu_log(",$0x%" TCG_PRIlx, args[k++]);
                 }
                 i = 1;
                 break;
@@ -1118,12 +1091,18 @@ void tcg_dump_ops(TCGContext *s)
                     unsigned ix = get_mmuidx(oi);
 
                     if (op & ~(MO_AMASK | MO_BSWAP | MO_SSIZE)) {
-                        col += qemu_log(",$0x%x,%u", op, ix);
+                        qemu_log(",$0x%x,%u", op, ix);
                     } else {
-                        const char *s_al, *s_op;
-                        s_al = alignment_name[(op & MO_AMASK) >> MO_ASHIFT];
+                        const char *s_al = "", *s_op;
+                        if (op & MO_AMASK) {
+                            if ((op & MO_AMASK) == MO_ALIGN) {
+                                s_al = "al+";
+                            } else {
+                                s_al = "un+";
+                            }
+                        }
                         s_op = ldst_name[op & (MO_BSWAP | MO_SSIZE)];
-                        col += qemu_log(",%s%s,%u", s_al, s_op, ix);
+                        qemu_log(",%s%s,%u", s_al, s_op, ix);
                     }
                     i = 1;
                 }
@@ -1138,39 +1117,14 @@ void tcg_dump_ops(TCGContext *s)
             case INDEX_op_brcond_i32:
             case INDEX_op_brcond_i64:
             case INDEX_op_brcond2_i32:
-                col += qemu_log("%s$L%d", k ? "," : "", arg_label(args[k])->id);
+                qemu_log("%s$L%d", k ? "," : "", arg_label(args[k])->id);
                 i++, k++;
                 break;
             default:
                 break;
             }
             for (; i < nb_cargs; i++, k++) {
-                col += qemu_log("%s$0x%" TCG_PRIlx, k ? "," : "", args[k]);
-            }
-        }
-        if (op->life) {
-            unsigned life = op->life;
-
-            for (; col < 48; ++col) {
-                putc(' ', qemu_logfile);
-            }
-
-            if (life & (SYNC_ARG * 3)) {
-                qemu_log("  sync:");
-                for (i = 0; i < 2; ++i) {
-                    if (life & (SYNC_ARG << i)) {
-                        qemu_log(" %d", i);
-                    }
-                }
-            }
-            life /= DEAD_ARG;
-            if (life) {
-                qemu_log("  dead:");
-                for (i = 0; life; ++i, life >>= 1) {
-                    if (life & 1) {
-                        qemu_log(" %d", i);
-                    }
-                }
+                qemu_log("%s$0x%" TCG_PRIlx, k ? "," : "", args[k]);
             }
         }
         qemu_log("\n");
@@ -1327,116 +1281,71 @@ void tcg_op_remove(TCGContext *s, TCGOp *op)
     int next = op->next;
     int prev = op->prev;
 
-    /* We should never attempt to remove the list terminator.  */
-    tcg_debug_assert(op != &s->gen_op_buf[0]);
-
-    s->gen_op_buf[next].prev = prev;
-    s->gen_op_buf[prev].next = next;
+    if (next >= 0) {
+        s->gen_op_buf[next].prev = prev;
+    } else {
+        s->gen_last_op_idx = prev;
+    }
+    if (prev >= 0) {
+        s->gen_op_buf[prev].next = next;
+    } else {
+        s->gen_first_op_idx = next;
+    }
 
-    memset(op, 0, sizeof(*op));
+    memset(op, -1, sizeof(*op));
 
 #ifdef CONFIG_PROFILER
     s->del_op_count++;
 #endif
 }
 
-TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *old_op,
-                            TCGOpcode opc, int nargs)
-{
-    int oi = s->gen_next_op_idx;
-    int pi = s->gen_next_parm_idx;
-    int prev = old_op->prev;
-    int next = old_op - s->gen_op_buf;
-    TCGOp *new_op;
-
-    tcg_debug_assert(oi < OPC_BUF_SIZE);
-    tcg_debug_assert(pi + nargs <= OPPARAM_BUF_SIZE);
-    s->gen_next_op_idx = oi + 1;
-    s->gen_next_parm_idx = pi + nargs;
-
-    new_op = &s->gen_op_buf[oi];
-    *new_op = (TCGOp){
-        .opc = opc,
-        .args = pi,
-        .prev = prev,
-        .next = next
-    };
-    s->gen_op_buf[prev].next = oi;
-    old_op->prev = oi;
-
-    return new_op;
-}
-
-TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op,
-                           TCGOpcode opc, int nargs)
-{
-    int oi = s->gen_next_op_idx;
-    int pi = s->gen_next_parm_idx;
-    int prev = old_op - s->gen_op_buf;
-    int next = old_op->next;
-    TCGOp *new_op;
-
-    tcg_debug_assert(oi < OPC_BUF_SIZE);
-    tcg_debug_assert(pi + nargs <= OPPARAM_BUF_SIZE);
-    s->gen_next_op_idx = oi + 1;
-    s->gen_next_parm_idx = pi + nargs;
-
-    new_op = &s->gen_op_buf[oi];
-    *new_op = (TCGOp){
-        .opc = opc,
-        .args = pi,
-        .prev = prev,
-        .next = next
-    };
-    s->gen_op_buf[next].prev = oi;
-    old_op->next = oi;
-
-    return new_op;
-}
-
-#define TS_DEAD  1
-#define TS_MEM   2
-
-#define IS_DEAD_ARG(n)   (arg_life & (DEAD_ARG << (n)))
-#define NEED_SYNC_ARG(n) (arg_life & (SYNC_ARG << (n)))
-
+#ifdef USE_LIVENESS_ANALYSIS
 /* liveness analysis: end of function: all temps are dead, and globals
    should be in memory. */
-static inline void tcg_la_func_end(TCGContext *s, uint8_t *temp_state)
+static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps,
+                                   uint8_t *mem_temps)
 {
-    memset(temp_state, TS_DEAD | TS_MEM, s->nb_globals);
-    memset(temp_state + s->nb_globals, TS_DEAD, s->nb_temps - s->nb_globals);
+    memset(dead_temps, 1, s->nb_temps);
+    memset(mem_temps, 1, s->nb_globals);
+    memset(mem_temps + s->nb_globals, 0, s->nb_temps - s->nb_globals);
 }
 
 /* liveness analysis: end of basic block: all temps are dead, globals
    and local temps should be in memory. */
-static inline void tcg_la_bb_end(TCGContext *s, uint8_t *temp_state)
+static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps,
+                                 uint8_t *mem_temps)
 {
-    int i, n;
+    int i;
 
-    tcg_la_func_end(s, temp_state);
-    for (i = s->nb_globals, n = s->nb_temps; i < n; i++) {
-        if (s->temps[i].temp_local) {
-            temp_state[i] |= TS_MEM;
-        }
+    memset(dead_temps, 1, s->nb_temps);
+    memset(mem_temps, 1, s->nb_globals);
+    for(i = s->nb_globals; i < s->nb_temps; i++) {
+        mem_temps[i] = s->temps[i].temp_local;
     }
 }
 
-/* Liveness analysis : update the opc_arg_life array to tell if a
+/* Liveness analysis : update the opc_dead_args array to tell if a
    given input arguments is dead. Instructions updating dead
    temporaries are removed. */
-static void liveness_pass_1(TCGContext *s, uint8_t *temp_state)
+static void tcg_liveness_analysis(TCGContext *s)
 {
-    int nb_globals = s->nb_globals;
-    int oi, oi_prev;
+    uint8_t *dead_temps, *mem_temps;
+    int oi, oi_prev, nb_ops;
 
-    tcg_la_func_end(s, temp_state);
+    nb_ops = s->gen_next_op_idx;
+    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
+    s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
+    
+    dead_temps = tcg_malloc(s->nb_temps);
+    mem_temps = tcg_malloc(s->nb_temps);
+    tcg_la_func_end(s, dead_temps, mem_temps);
 
-    for (oi = s->gen_op_buf[0].prev; oi != 0; oi = oi_prev) {
+    for (oi = s->gen_last_op_idx; oi >= 0; oi = oi_prev) {
         int i, nb_iargs, nb_oargs;
         TCGOpcode opc_new, opc_new2;
         bool have_opc_new2;
-        TCGLifeData arg_life = 0;
+        uint16_t dead_args;
+        uint8_t sync_args;
         TCGArg arg;
 
         TCGOp * const op = &s->gen_op_buf[oi];
@@ -1459,7 +1368,7 @@ static void liveness_pass_1(TCGContext *s, uint8_t *temp_state)
                 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
                     for (i = 0; i < nb_oargs; i++) {
                         arg = args[i];
-                        if (temp_state[arg] != TS_DEAD) {
+                        if (!dead_temps[arg] || mem_temps[arg]) {
                             goto do_not_remove_call;
                         }
                     }
@@ -1468,44 +1377,46 @@ static void liveness_pass_1(TCGContext *s, uint8_t *temp_state)
                 do_not_remove_call:
 
                     /* output args are dead */
+                    dead_args = 0;
+                    sync_args = 0;
                     for (i = 0; i < nb_oargs; i++) {
                         arg = args[i];
-                        if (temp_state[arg] & TS_DEAD) {
-                            arg_life |= DEAD_ARG << i;
+                        if (dead_temps[arg]) {
+                            dead_args |= (1 << i);
                         }
-                        if (temp_state[arg] & TS_MEM) {
-                            arg_life |= SYNC_ARG << i;
+                        if (mem_temps[arg]) {
+                            sync_args |= (1 << i);
                         }
-                        temp_state[arg] = TS_DEAD;
+                        dead_temps[arg] = 1;
+                        mem_temps[arg] = 0;
                     }
 
+                    if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
+                        /* globals should be synced to memory */
+                        memset(mem_temps, 1, s->nb_globals);
+                    }
                     if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
                                         TCG_CALL_NO_READ_GLOBALS))) {
                         /* globals should go back to memory */
-                        memset(temp_state, TS_DEAD | TS_MEM, nb_globals);
-                    } else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
-                        /* globals should be synced to memory */
-                        for (i = 0; i < nb_globals; i++) {
-                            temp_state[i] |= TS_MEM;
-                        }
+                        memset(dead_temps, 1, s->nb_globals);
                     }
 
                     /* record arguments that die in this helper */
                     for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
                         arg = args[i];
                         if (arg != TCG_CALL_DUMMY_ARG) {
-                            if (temp_state[arg] & TS_DEAD) {
-                                arg_life |= DEAD_ARG << i;
+                            if (dead_temps[arg]) {
+                                dead_args |= (1 << i);
                             }
                         }
                     }
                     /* input arguments are live for preceding opcodes */
-                    for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
+                    for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
                         arg = args[i];
-                        if (arg != TCG_CALL_DUMMY_ARG) {
-                            temp_state[arg] &= ~TS_DEAD;
-                        }
+                        dead_temps[arg] = 0;
                     }
+                    s->op_dead_args[oi] = dead_args;
+                    s->op_sync_args[oi] = sync_args;
                 }
             }
             break;
@@ -1513,7 +1424,8 @@ static void liveness_pass_1(TCGContext *s, uint8_t *temp_state)
             break;
         case INDEX_op_discard:
             /* mark the temporary as dead */
-            temp_state[args[0]] = TS_DEAD;
+            dead_temps[args[0]] = 1;
+            mem_temps[args[0]] = 0;
             break;
 
         case INDEX_op_add2_i32:
@@ -1534,8 +1446,8 @@ static void liveness_pass_1(TCGContext *s, uint8_t *temp_state)
                the low part.  The result can be optimized to a simple
                add or sub.  This happens often for x86_64 guest when the
                cpu mode is set to 32 bit.  */
-            if (temp_state[args[1]] == TS_DEAD) {
-                if (temp_state[args[0]] == TS_DEAD) {
+            if (dead_temps[args[1]] && !mem_temps[args[1]]) {
+                if (dead_temps[args[0]] && !mem_temps[args[0]]) {
                     goto do_remove;
                 }
                 /* Replace the opcode and adjust the args in place,
@@ -1572,8 +1484,8 @@ static void liveness_pass_1(TCGContext *s, uint8_t *temp_state)
         do_mul2:
             nb_iargs = 2;
             nb_oargs = 2;
-            if (temp_state[args[1]] == TS_DEAD) {
-                if (temp_state[args[0]] == TS_DEAD) {
+            if (dead_temps[args[1]] && !mem_temps[args[1]]) {
+                if (dead_temps[args[0]] && !mem_temps[args[0]]) {
                     /* Both parts of the operation are dead.  */
                     goto do_remove;
                 }
@@ -1581,7 +1493,8 @@ static void liveness_pass_1(TCGContext *s, uint8_t *temp_state)
                 op->opc = opc = opc_new;
                 args[1] = args[2];
                 args[2] = args[3];
-            } else if (temp_state[args[0]] == TS_DEAD && have_opc_new2) {
+            } else if (have_opc_new2 && dead_temps[args[0]]
+                       && !mem_temps[args[0]]) {
                 /* The low part of the operation is dead; generate the high. */
                 op->opc = opc = opc_new2;
                 args[0] = args[1];
@@ -1604,7 +1517,8 @@ static void liveness_pass_1(TCGContext *s, uint8_t *temp_state)
                implies side effects */
             if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
                 for (i = 0; i < nb_oargs; i++) {
-                    if (temp_state[args[i]] != TS_DEAD) {
+                    arg = args[i];
+                    if (!dead_temps[arg] || mem_temps[arg]) {
                         goto do_not_remove;
                     }
                 }
@@ -1613,203 +1527,59 @@ static void liveness_pass_1(TCGContext *s, uint8_t *temp_state)
             } else {
             do_not_remove:
                 /* output args are dead */
+                dead_args = 0;
+                sync_args = 0;
                 for (i = 0; i < nb_oargs; i++) {
                     arg = args[i];
-                    if (temp_state[arg] & TS_DEAD) {
-                        arg_life |= DEAD_ARG << i;
+                    if (dead_temps[arg]) {
+                        dead_args |= (1 << i);
                     }
-                    if (temp_state[arg] & TS_MEM) {
-                        arg_life |= SYNC_ARG << i;
+                    if (mem_temps[arg]) {
+                        sync_args |= (1 << i);
                     }
-                    temp_state[arg] = TS_DEAD;
+                    dead_temps[arg] = 1;
+                    mem_temps[arg] = 0;
                 }
 
                 /* if end of basic block, update */
                 if (def->flags & TCG_OPF_BB_END) {
-                    tcg_la_bb_end(s, temp_state);
+                    tcg_la_bb_end(s, dead_temps, mem_temps);
                 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
                     /* globals should be synced to memory */
-                    for (i = 0; i < nb_globals; i++) {
-                        temp_state[i] |= TS_MEM;
-                    }
+                    memset(mem_temps, 1, s->nb_globals);
                 }
 
                 /* record arguments that die in this opcode */
                 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
                     arg = args[i];
-                    if (temp_state[arg] & TS_DEAD) {
-                        arg_life |= DEAD_ARG << i;
+                    if (dead_temps[arg]) {
+                        dead_args |= (1 << i);
                     }
                 }
                 /* input arguments are live for preceding opcodes */
                 for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
-                    temp_state[args[i]] &= ~TS_DEAD;
+                    arg = args[i];
+                    dead_temps[arg] = 0;
                 }
+                s->op_dead_args[oi] = dead_args;
+                s->op_sync_args[oi] = sync_args;
             }
             break;
         }
-        op->life = arg_life;
     }
 }
-
-/* Liveness analysis: Convert indirect regs to direct temporaries.  */
-static bool liveness_pass_2(TCGContext *s, uint8_t *temp_state)
+#else
+/* dummy liveness analysis */
+static void tcg_liveness_analysis(TCGContext *s)
 {
-    int nb_globals = s->nb_globals;
-    int16_t *dir_temps;
-    int i, oi, oi_next;
-    bool changes = false;
-
-    dir_temps = tcg_malloc(nb_globals * sizeof(int16_t));
-    memset(dir_temps, 0, nb_globals * sizeof(int16_t));
-
-    /* Create a temporary for each indirect global.  */
-    for (i = 0; i < nb_globals; ++i) {
-        TCGTemp *its = &s->temps[i];
-        if (its->indirect_reg) {
-            TCGTemp *dts = tcg_temp_alloc(s);
-            dts->type = its->type;
-            dts->base_type = its->base_type;
-            dir_temps[i] = temp_idx(s, dts);
-        }
-    }
-
-    memset(temp_state, TS_DEAD, nb_globals);
-
-    for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
-        TCGOp *op = &s->gen_op_buf[oi];
-        TCGArg *args = &s->gen_opparam_buf[op->args];
-        TCGOpcode opc = op->opc;
-        const TCGOpDef *def = &tcg_op_defs[opc];
-        TCGLifeData arg_life = op->life;
-        int nb_iargs, nb_oargs, call_flags;
-        TCGArg arg, dir;
-
-        oi_next = op->next;
-
-        if (opc == INDEX_op_call) {
-            nb_oargs = op->callo;
-            nb_iargs = op->calli;
-            call_flags = args[nb_oargs + nb_iargs + 1];
-        } else {
-            nb_iargs = def->nb_iargs;
-            nb_oargs = def->nb_oargs;
-
-            /* Set flags similar to how calls require.  */
-            if (def->flags & TCG_OPF_BB_END) {
-                /* Like writing globals: save_globals */
-                call_flags = 0;
-            } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
-                /* Like reading globals: sync_globals */
-                call_flags = TCG_CALL_NO_WRITE_GLOBALS;
-            } else {
-                /* No effect on globals.  */
-                call_flags = (TCG_CALL_NO_READ_GLOBALS |
-                              TCG_CALL_NO_WRITE_GLOBALS);
-            }
-        }
-
-        /* Make sure that input arguments are available.  */
-        for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
-            arg = args[i];
-            /* Note this unsigned test catches TCG_CALL_ARG_DUMMY too.  */
-            if (arg < nb_globals) {
-                dir = dir_temps[arg];
-                if (dir != 0 && temp_state[arg] == TS_DEAD) {
-                    TCGTemp *its = &s->temps[arg];
-                    TCGOpcode lopc = (its->type == TCG_TYPE_I32
-                                      ? INDEX_op_ld_i32
-                                      : INDEX_op_ld_i64);
-                    TCGOp *lop = tcg_op_insert_before(s, op, lopc, 3);
-                    TCGArg *largs = &s->gen_opparam_buf[lop->args];
-
-                    largs[0] = dir;
-                    largs[1] = temp_idx(s, its->mem_base);
-                    largs[2] = its->mem_offset;
-
-                    /* Loaded, but synced with memory.  */
-                    temp_state[arg] = TS_MEM;
-                }
-            }
-        }
-
-        /* Perform input replacement, and mark inputs that became dead.
-           No action is required except keeping temp_state up to date
-           so that we reload when needed.  */
-        for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
-            arg = args[i];
-            if (arg < nb_globals) {
-                dir = dir_temps[arg];
-                if (dir != 0) {
-                    args[i] = dir;
-                    changes = true;
-                    if (IS_DEAD_ARG(i)) {
-                        temp_state[arg] = TS_DEAD;
-                    }
-                }
-            }
-        }
-
-        /* Liveness analysis should ensure that the following are
-           all correct, for call sites and basic block end points.  */
-        if (call_flags & TCG_CALL_NO_READ_GLOBALS) {
-            /* Nothing to do */
-        } else if (call_flags & TCG_CALL_NO_WRITE_GLOBALS) {
-            for (i = 0; i < nb_globals; ++i) {
-                /* Liveness should see that globals are synced back,
-                   that is, either TS_DEAD or TS_MEM.  */
-                tcg_debug_assert(dir_temps[i] == 0
-                                 || temp_state[i] != 0);
-            }
-        } else {
-            for (i = 0; i < nb_globals; ++i) {
-                /* Liveness should see that globals are saved back,
-                   that is, TS_DEAD, waiting to be reloaded.  */
-                tcg_debug_assert(dir_temps[i] == 0
-                                 || temp_state[i] == TS_DEAD);
-            }
-        }
-
-        /* Outputs become available.  */
-        for (i = 0; i < nb_oargs; i++) {
-            arg = args[i];
-            if (arg >= nb_globals) {
-                continue;
-            }
-            dir = dir_temps[arg];
-            if (dir == 0) {
-                continue;
-            }
-            args[i] = dir;
-            changes = true;
-
-            /* The output is now live and modified.  */
-            temp_state[arg] = 0;
-
-            /* Sync outputs upon their last write.  */
-            if (NEED_SYNC_ARG(i)) {
-                TCGTemp *its = &s->temps[arg];
-                TCGOpcode sopc = (its->type == TCG_TYPE_I32
-                                  ? INDEX_op_st_i32
-                                  : INDEX_op_st_i64);
-                TCGOp *sop = tcg_op_insert_after(s, op, sopc, 3);
-                TCGArg *sargs = &s->gen_opparam_buf[sop->args];
-
-                sargs[0] = dir;
-                sargs[1] = temp_idx(s, its->mem_base);
-                sargs[2] = its->mem_offset;
-
-                temp_state[arg] = TS_MEM;
-            }
-            /* Drop outputs that are dead.  */
-            if (IS_DEAD_ARG(i)) {
-                temp_state[arg] = TS_DEAD;
-            }
-        }
-    }
+    int nb_ops = s->gen_next_op_idx;
 
-    return changes;
+    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
+    memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
+    s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
+    memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t));
 }
+#endif
 
 #ifdef CONFIG_DEBUG_TCG
 static void dump_regs(TCGContext *s)
@@ -1905,81 +1675,35 @@ static void temp_allocate_frame(TCGContext *s, int temp)
 
 static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet);
 
-/* Mark a temporary as free or dead.  If 'free_or_dead' is negative,
-   mark it free; otherwise mark it dead.  */
-static void temp_free_or_dead(TCGContext *s, TCGTemp *ts, int free_or_dead)
+/* sync register 'reg' by saving it to the corresponding temporary */
+static void tcg_reg_sync(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs)
 {
-    if (ts->fixed_reg) {
-        return;
-    }
-    if (ts->val_type == TEMP_VAL_REG) {
-        s->reg_to_temp[ts->reg] = NULL;
-    }
-    ts->val_type = (free_or_dead < 0
-                    || ts->temp_local
-                    || temp_idx(s, ts) < s->nb_globals
-                    ? TEMP_VAL_MEM : TEMP_VAL_DEAD);
-}
-
-/* Mark a temporary as dead.  */
-static inline void temp_dead(TCGContext *s, TCGTemp *ts)
-{
-    temp_free_or_dead(s, ts, 1);
-}
+    TCGTemp *ts = s->reg_to_temp[reg];
 
-/* Sync a temporary to memory. 'allocated_regs' is used in case a temporary
-   registers needs to be allocated to store a constant.  If 'free_or_dead'
-   is non-zero, subsequently release the temporary; if it is positive, the
-   temp is dead; if it is negative, the temp is free.  */
-static void temp_sync(TCGContext *s, TCGTemp *ts,
-                      TCGRegSet allocated_regs, int free_or_dead)
-{
-    if (ts->fixed_reg) {
-        return;
-    }
-    if (!ts->mem_coherent) {
+    tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
+    if (!ts->mem_coherent && !ts->fixed_reg) {
         if (!ts->mem_allocated) {
             temp_allocate_frame(s, temp_idx(s, ts));
-        }
-        switch (ts->val_type) {
-        case TEMP_VAL_CONST:
-            /* If we're going to free the temp immediately, then we won't
-               require it later in a register, so attempt to store the
-               constant to memory directly.  */
-            if (free_or_dead
-                && tcg_out_sti(s, ts->type, ts->val,
-                               ts->mem_base->reg, ts->mem_offset)) {
-                break;
-            }
-            temp_load(s, ts, tcg_target_available_regs[ts->type],
+        } else if (ts->indirect_reg) {
+            tcg_regset_set_reg(allocated_regs, ts->reg);
+            temp_load(s, ts->mem_base,
+                      tcg_target_available_regs[TCG_TYPE_PTR],
                       allocated_regs);
-            /* fallthrough */
-
-        case TEMP_VAL_REG:
-            tcg_out_st(s, ts->type, ts->reg,
-                       ts->mem_base->reg, ts->mem_offset);
-            break;
-
-        case TEMP_VAL_MEM:
-            break;
-
-        case TEMP_VAL_DEAD:
-        default:
-            tcg_abort();
         }
-        ts->mem_coherent = 1;
-    }
-    if (free_or_dead) {
-        temp_free_or_dead(s, ts, free_or_dead);
+        tcg_out_st(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
     }
+    ts->mem_coherent = 1;
 }
 
 /* free register 'reg' by spilling the corresponding temporary if necessary */
 static void tcg_reg_free(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs)
 {
     TCGTemp *ts = s->reg_to_temp[reg];
+
     if (ts != NULL) {
-        temp_sync(s, ts, allocated_regs, -1);
+        tcg_reg_sync(s, reg, allocated_regs);
+        ts->val_type = TEMP_VAL_MEM;
+        s->reg_to_temp[reg] = NULL;
     }
 }
 
@@ -2031,6 +1755,12 @@ static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
         break;
     case TEMP_VAL_MEM:
         reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base);
+        if (ts->indirect_reg) {
+            tcg_regset_set_reg(allocated_regs, reg);
+            temp_load(s, ts->mem_base,
+                      tcg_target_available_regs[TCG_TYPE_PTR],
+                      allocated_regs);
+        }
         tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
         ts->mem_coherent = 1;
         break;
@@ -2043,13 +1773,57 @@ static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
     s->reg_to_temp[reg] = ts;
 }
 
-/* Save a temporary to memory. 'allocated_regs' is used in case a
-   temporary registers needs to be allocated to store a constant.  */
-static void temp_save(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
+/* mark a temporary as dead. */
+static inline void temp_dead(TCGContext *s, TCGTemp *ts)
 {
-    /* The liveness analysis already ensures that globals are back
-       in memory. Keep an tcg_debug_assert for safety. */
-    tcg_debug_assert(ts->val_type == TEMP_VAL_MEM || ts->fixed_reg);
+    if (ts->fixed_reg) {
+        return;
+    }
+    if (ts->val_type == TEMP_VAL_REG) {
+        s->reg_to_temp[ts->reg] = NULL;
+    }
+    ts->val_type = (temp_idx(s, ts) < s->nb_globals || ts->temp_local
+                    ? TEMP_VAL_MEM : TEMP_VAL_DEAD);
+}
+
+/* sync a temporary to memory. 'allocated_regs' is used in case a
+   temporary registers needs to be allocated to store a constant. */
+static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs)
+{
+    if (ts->fixed_reg) {
+        return;
+    }
+    switch (ts->val_type) {
+    case TEMP_VAL_CONST:
+        temp_load(s, ts, tcg_target_available_regs[ts->type], allocated_regs);
+        /* fallthrough */
+    case TEMP_VAL_REG:
+        tcg_reg_sync(s, ts->reg, allocated_regs);
+        break;
+    case TEMP_VAL_DEAD:
+    case TEMP_VAL_MEM:
+        break;
+    default:
+        tcg_abort();
+    }
+}
+
+/* save a temporary to memory. 'allocated_regs' is used in case a
+   temporary registers needs to be allocated to store a constant. */
+static inline void temp_save(TCGContext *s, TCGTemp *ts,
+                             TCGRegSet allocated_regs)
+{
+#ifdef USE_LIVENESS_ANALYSIS
+    /* ??? Liveness does not yet incorporate indirect bases.  */
+    if (!ts->indirect_base) {
+        /* The liveness analysis already ensures that globals are back
+           in memory. Keep an tcg_debug_assert for safety. */
+        tcg_debug_assert(ts->val_type == TEMP_VAL_MEM || ts->fixed_reg);
+        return;
+    }
+#endif
+    temp_sync(s, ts, allocated_regs);
+    temp_dead(s, ts);
 }
 
 /* save globals to their canonical location and assume they can be
@@ -2073,9 +1847,16 @@ static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
 
     for (i = 0; i < s->nb_globals; i++) {
         TCGTemp *ts = &s->temps[i];
-        tcg_debug_assert(ts->val_type != TEMP_VAL_REG
-                         || ts->fixed_reg
-                         || ts->mem_coherent);
+#ifdef USE_LIVENESS_ANALYSIS
+        /* ??? Liveness does not yet incorporate indirect bases.  */
+        if (!ts->indirect_base) {
+            tcg_debug_assert(ts->val_type != TEMP_VAL_REG
+                             || ts->fixed_reg
+                             || ts->mem_coherent);
+            continue;
+        }
+#endif
+        temp_sync(s, ts, allocated_regs);
     }
 }
 
@@ -2090,17 +1871,27 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
         if (ts->temp_local) {
             temp_save(s, ts, allocated_regs);
         } else {
-            /* The liveness analysis already ensures that temps are dead.
-               Keep an tcg_debug_assert for safety. */
-            tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
+#ifdef USE_LIVENESS_ANALYSIS
+            /* ??? Liveness does not yet incorporate indirect bases.  */
+            if (!ts->indirect_base) {
+                /* The liveness analysis already ensures that temps are dead.
+                   Keep an tcg_debug_assert for safety. */
+                tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
+                continue;
+            }
+#endif
+            temp_dead(s, ts);
         }
     }
 
     save_globals(s, allocated_regs);
 }
 
+#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
+#define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1)
+
 static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
-                               TCGLifeData arg_life)
+                               uint16_t dead_args, uint8_t sync_args)
 {
     TCGTemp *ots;
     tcg_target_ulong val;
@@ -2109,27 +1900,28 @@ static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
     val = args[1];
 
     if (ots->fixed_reg) {
-        /* For fixed registers, we do not do any constant propagation.  */
+        /* for fixed registers, we do not do any constant
+           propagation */
         tcg_out_movi(s, ots->type, ots->reg, val);
-        return;
-    }
-
-    /* The movi is not explicitly generated here.  */
-    if (ots->val_type == TEMP_VAL_REG) {
-        s->reg_to_temp[ots->reg] = NULL;
+    } else {
+        /* The movi is not explicitly generated here */
+        if (ots->val_type == TEMP_VAL_REG) {
+            s->reg_to_temp[ots->reg] = NULL;
+        }
+        ots->val_type = TEMP_VAL_CONST;
+        ots->val = val;
     }
-    ots->val_type = TEMP_VAL_CONST;
-    ots->val = val;
-    ots->mem_coherent = 0;
     if (NEED_SYNC_ARG(0)) {
-        temp_sync(s, ots, s->reserved_regs, IS_DEAD_ARG(0));
-    } else if (IS_DEAD_ARG(0)) {
+        temp_sync(s, ots, s->reserved_regs);
+    }
+    if (IS_DEAD_ARG(0)) {
         temp_dead(s, ots);
     }
 }
 
 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
-                              const TCGArg *args, TCGLifeData arg_life)
+                              const TCGArg *args, uint16_t dead_args,
+                              uint8_t sync_args)
 {
     TCGRegSet allocated_regs;
     TCGTemp *ts, *ots;
@@ -2161,6 +1953,12 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
         if (!ots->mem_allocated) {
             temp_allocate_frame(s, args[0]);
         }
+        if (ots->indirect_reg) {
+            tcg_regset_set_reg(allocated_regs, ts->reg);
+            temp_load(s, ots->mem_base,
+                      tcg_target_available_regs[TCG_TYPE_PTR],
+                      allocated_regs);
+        }
         tcg_out_st(s, otype, ts->reg, ots->mem_base->reg, ots->mem_offset);
         if (IS_DEAD_ARG(1)) {
             temp_dead(s, ts);
@@ -2201,14 +1999,15 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
         ots->mem_coherent = 0;
         s->reg_to_temp[ots->reg] = ots;
         if (NEED_SYNC_ARG(0)) {
-            temp_sync(s, ots, allocated_regs, 0);
+            tcg_reg_sync(s, ots->reg, allocated_regs);
         }
     }
 }
 
 static void tcg_reg_alloc_op(TCGContext *s, 
                              const TCGOpDef *def, TCGOpcode opc,
-                             const TCGArg *args, TCGLifeData arg_life)
+                             const TCGArg *args, uint16_t dead_args,
+                             uint8_t sync_args)
 {
     TCGRegSet allocated_regs;
     int i, k, nb_iargs, nb_oargs;
@@ -2359,8 +2158,9 @@ static void tcg_reg_alloc_op(TCGContext *s,
             tcg_out_mov(s, ts->type, ts->reg, reg);
         }
         if (NEED_SYNC_ARG(i)) {
-            temp_sync(s, ts, allocated_regs, IS_DEAD_ARG(i));
-        } else if (IS_DEAD_ARG(i)) {
+            tcg_reg_sync(s, reg, allocated_regs);
+        }
+        if (IS_DEAD_ARG(i)) {
             temp_dead(s, ts);
         }
     }
@@ -2373,7 +2173,8 @@ static void tcg_reg_alloc_op(TCGContext *s,
 #endif
 
 static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
-                               const TCGArg * const args, TCGLifeData arg_life)
+                               const TCGArg * const args, uint16_t dead_args,
+                               uint8_t sync_args)
 {
     int flags, nb_regs, i;
     TCGReg reg;
@@ -2492,8 +2293,9 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
             ts->mem_coherent = 0;
             s->reg_to_temp[reg] = ts;
             if (NEED_SYNC_ARG(i)) {
-                temp_sync(s, ts, allocated_regs, IS_DEAD_ARG(i));
-            } else if (IS_DEAD_ARG(i)) {
+                tcg_reg_sync(s, reg, allocated_regs);
+            }
+            if (IS_DEAD_ARG(i)) {
                 temp_dead(s, ts);
             }
         }
@@ -2529,7 +2331,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
     {
         int n;
 
-        n = s->gen_op_buf[0].prev + 1;
+        n = s->gen_last_op_idx + 1;
         s->op_count += n;
         if (n > s->op_count_max) {
             s->op_count_max = n;
@@ -2565,27 +2367,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
     s->la_time -= profile_getclock();
 #endif
 
-    {
-        uint8_t *temp_state = tcg_malloc(s->nb_temps + s->nb_indirects);
-
-        liveness_pass_1(s, temp_state);
-
-        if (s->nb_indirects > 0) {
-#ifdef DEBUG_DISAS
-            if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND)
-                         && qemu_log_in_addr_range(tb->pc))) {
-                qemu_log("OP before indirect lowering:\n");
-                tcg_dump_ops(s);
-                qemu_log("\n");
-            }
-#endif
-            /* Replace indirect temps with direct temps.  */
-            if (liveness_pass_2(s, temp_state)) {
-                /* If changes were made, re-run liveness.  */
-                liveness_pass_1(s, temp_state);
-            }
-        }
-    }
+    tcg_liveness_analysis(s);
 
 #ifdef CONFIG_PROFILER
     s->la_time += profile_getclock();
@@ -2608,12 +2390,13 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
     tcg_out_tb_init(s);
 
     num_insns = -1;
-    for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
+    for (oi = s->gen_first_op_idx; oi >= 0; oi = oi_next) {
         TCGOp * const op = &s->gen_op_buf[oi];
         TCGArg * const args = &s->gen_opparam_buf[op->args];
         TCGOpcode opc = op->opc;
         const TCGOpDef *def = &tcg_op_defs[opc];
-        TCGLifeData arg_life = op->life;
+        uint16_t dead_args = s->op_dead_args[oi];
+        uint8_t sync_args = s->op_sync_args[oi];
 
         oi_next = op->next;
 #ifdef CONFIG_PROFILER
@@ -2623,11 +2406,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
         switch (opc) {
         case INDEX_op_mov_i32:
         case INDEX_op_mov_i64:
-            tcg_reg_alloc_mov(s, def, args, arg_life);
+            tcg_reg_alloc_mov(s, def, args, dead_args, sync_args);
             break;
         case INDEX_op_movi_i32:
         case INDEX_op_movi_i64:
-            tcg_reg_alloc_movi(s, args, arg_life);
+            tcg_reg_alloc_movi(s, args, dead_args, sync_args);
             break;
         case INDEX_op_insn_start:
             if (num_insns >= 0) {
@@ -2652,7 +2435,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
             tcg_out_label(s, arg_label(args[0]), s->code_ptr);
             break;
         case INDEX_op_call:
-            tcg_reg_alloc_call(s, op->callo, op->calli, args, arg_life);
+            tcg_reg_alloc_call(s, op->callo, op->calli, args,
+                               dead_args, sync_args);
             break;
         default:
             /* Sanity check that we've not introduced any unhandled opcodes. */
@@ -2662,7 +2446,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
             /* Note: in order to speed up the code, it would be much
                faster to have specialized register allocator functions for
                some common argument patterns */
-            tcg_reg_alloc_op(s, def, opc, args, arg_life);
+            tcg_reg_alloc_op(s, def, opc, args, dead_args, sync_args);
             break;
         }
 #ifdef CONFIG_DEBUG_TCG
index 1bcabca..40c8fbe 100644 (file)
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
 #define TCG_H
 
 #include "qemu-common.h"
-#include "cpu.h"
-#include "exec/tb-context.h"
 #include "qemu/bitops.h"
 #include "tcg-target.h"
 
-/* XXX: make safe guess about sizes */
-#define MAX_OP_PER_INSTR 266
-
-#if HOST_LONG_BITS == 32
-#define MAX_OPC_PARAM_PER_ARG 2
-#else
-#define MAX_OPC_PARAM_PER_ARG 1
-#endif
-#define MAX_OPC_PARAM_IARGS 5
-#define MAX_OPC_PARAM_OARGS 1
-#define MAX_OPC_PARAM_ARGS (MAX_OPC_PARAM_IARGS + MAX_OPC_PARAM_OARGS)
-
-/* A Call op needs up to 4 + 2N parameters on 32-bit archs,
- * and up to 4 + N parameters on 64-bit archs
- * (N = number of input arguments + output arguments).  */
-#define MAX_OPC_PARAM (4 + (MAX_OPC_PARAM_PER_ARG * MAX_OPC_PARAM_ARGS))
-#define OPC_BUF_SIZE 640
-#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
-
-#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM)
-
 #define CPU_TEMP_BUF_NLONGS 128
 
 /* Default target word size to pointer size.  */
@@ -191,15 +168,6 @@ typedef uint64_t tcg_insn_unit;
 #endif
 
 
-#if defined CONFIG_DEBUG_TCG || defined QEMU_STATIC_ANALYSIS
-# define tcg_debug_assert(X) do { assert(X); } while (0)
-#elif QEMU_GNUC_PREREQ(4, 5)
-# define tcg_debug_assert(X) \
-    do { if (!(X)) { __builtin_unreachable(); } } while (0)
-#else
-# define tcg_debug_assert(X) do { (void)(X); } while (0)
-#endif
-
 typedef struct TCGRelocation {
     struct TCGRelocation *next;
     int type;
@@ -284,26 +252,10 @@ typedef enum TCGMemOp {
 #endif
 
     /* MO_UNALN accesses are never checked for alignment.
-     * MO_ALIGN accesses will result in a call to the CPU's
-     * do_unaligned_access hook if the guest address is not aligned.
-     * The default depends on whether the target CPU defines ALIGNED_ONLY.
-     * Some architectures (e.g. ARMv8) need the address which is aligned
-     * to a size more than the size of the memory access.
-     * To support such check it's enough the current costless alignment
-     * check implementation in QEMU, but we need to support
-     * an alignment size specifying.
-     * MO_ALIGN supposes a natural alignment
-     * (i.e. the alignment size is the size of a memory access).
-     * Note that an alignment size must be equal or greater
-     * than an access size.
-     * There are three options:
-     * - an alignment to the size of an access (MO_ALIGN);
-     * - an alignment to the specified size that is equal or greater than
-     *   an access size (MO_ALIGN_x where 'x' is a size in bytes);
-     * - unaligned access permitted (MO_UNALN).
-     */
-    MO_ASHIFT = 4,
-    MO_AMASK = 7 << MO_ASHIFT,
+       MO_ALIGN accesses will result in a call to the CPU's
+       do_unaligned_access hook if the guest address is not aligned.
+       The default depends on whether the target CPU defines ALIGNED_ONLY.  */
+    MO_AMASK = 16,
 #ifdef ALIGNED_ONLY
     MO_ALIGN = 0,
     MO_UNALN = MO_AMASK,
@@ -311,12 +263,6 @@ typedef enum TCGMemOp {
     MO_ALIGN = MO_AMASK,
     MO_UNALN = 0,
 #endif
-    MO_ALIGN_2  = 1 << MO_ASHIFT,
-    MO_ALIGN_4  = 2 << MO_ASHIFT,
-    MO_ALIGN_8  = 3 << MO_ASHIFT,
-    MO_ALIGN_16 = 4 << MO_ASHIFT,
-    MO_ALIGN_32 = 5 << MO_ASHIFT,
-    MO_ALIGN_64 = 6 << MO_ASHIFT,
 
     /* Combinations of the above, for ease of use.  */
     MO_UB    = MO_8,
@@ -348,45 +294,6 @@ typedef enum TCGMemOp {
     MO_SSIZE = MO_SIZE | MO_SIGN,
 } TCGMemOp;
 
-/**
- * get_alignment_bits
- * @memop: TCGMemOp value
- *
- * Extract the alignment size from the memop.
- *
- * Returns: 0 in case of byte access (which is always aligned);
- *          positive value - number of alignment bits;
- *          negative value if unaligned access enabled
- *          and this is not a byte access.
- */
-static inline int get_alignment_bits(TCGMemOp memop)
-{
-    int a = memop & MO_AMASK;
-    int s = memop & MO_SIZE;
-    int r;
-
-    if (a == MO_UNALN) {
-        /* Negative value if unaligned access enabled,
-         * or zero value in case of byte access.
-         */
-        return -s;
-    } else if (a == MO_ALIGN) {
-        /* A natural alignment: return a number of access size bits */
-        r = s;
-    } else {
-        /* Specific alignment size. It must be equal or greater
-         * than the access size.
-         */
-        r = a >> MO_ASHIFT;
-        tcg_debug_assert(r >= s);
-    }
-#if defined(CONFIG_SOFTMMU)
-    /* The requested alignment cannot overlap the TLB flags.  */
-    tcg_debug_assert((TLB_FLAGS_MASK & ((1 << r) - 1)) == 0);
-#endif
-    return r;
-}
-
 typedef tcg_target_ulong TCGArg;
 
 /* Define a type and accessor macros for variables.  Using pointer types
@@ -575,41 +482,24 @@ typedef struct TCGTempSet {
     unsigned long l[BITS_TO_LONGS(TCG_MAX_TEMPS)];
 } TCGTempSet;
 
-/* While we limit helpers to 6 arguments, for 32-bit hosts, with padding,
-   this imples a max of 6*2 (64-bit in) + 2 (64-bit out) = 14 operands.
-   There are never more than 2 outputs, which means that we can store all
-   dead + sync data within 16 bits.  */
-#define DEAD_ARG  4
-#define SYNC_ARG  1
-typedef uint16_t TCGLifeData;
-
-/* The layout here is designed to avoid crossing of a 32-bit boundary.
-   If we do so, gcc adds padding, expanding the size to 12.  */
 typedef struct TCGOp {
-    TCGOpcode opc   : 8;        /*  8 */
-
-    /* Index of the prev/next op, or 0 for the end of the list.  */
-    unsigned prev   : 10;       /* 18 */
-    unsigned next   : 10;       /* 28 */
+    TCGOpcode opc   : 8;
 
     /* The number of out and in parameter for a call.  */
-    unsigned calli  : 4;        /* 32 */
-    unsigned callo  : 2;        /* 34 */
+    unsigned callo  : 2;
+    unsigned calli  : 6;
 
-    /* Index of the arguments for this op, or 0 for zero-operand ops.  */
-    unsigned args   : 14;       /* 48 */
+    /* Index of the arguments for this op, or -1 for zero-operand ops.  */
+    signed args     : 16;
 
-    /* Lifetime data of the operands.  */
-    unsigned life   : 16;       /* 64 */
+    /* Index of the prex/next op, or -1 for the end of the list.  */
+    signed prev     : 16;
+    signed next     : 16;
 } TCGOp;
 
-/* Make sure operands fit in the bitfields above.  */
-QEMU_BUILD_BUG_ON(NB_OPS > (1 << 8));
-QEMU_BUILD_BUG_ON(OPC_BUF_SIZE > (1 << 10));
-QEMU_BUILD_BUG_ON(OPPARAM_BUF_SIZE > (1 << 14));
-
-/* Make sure that we don't overflow 64 bits without noticing.  */
-QEMU_BUILD_BUG_ON(sizeof(TCGOp) > 8);
+QEMU_BUILD_BUG_ON(NB_OPS > 0xff);
+QEMU_BUILD_BUG_ON(OPC_BUF_SIZE >= 0x7fff);
+QEMU_BUILD_BUG_ON(OPPARAM_BUF_SIZE >= 0x7fff);
 
 struct TCGContext {
     uint8_t *pool_cur, *pool_end;
@@ -617,14 +507,20 @@ struct TCGContext {
     int nb_labels;
     int nb_globals;
     int nb_temps;
-    int nb_indirects;
 
     /* goto_tb support */
     tcg_insn_unit *code_buf;
-    uint16_t *tb_jmp_reset_offset; /* tb->jmp_reset_offset */
-    uint16_t *tb_jmp_insn_offset; /* tb->jmp_insn_offset if USE_DIRECT_JUMP */
-    uintptr_t *tb_jmp_target_addr; /* tb->jmp_target_addr if !USE_DIRECT_JUMP */
-
+    uintptr_t *tb_next;
+    uint16_t *tb_next_offset;
+    uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */
+
+    /* liveness analysis */
+    uint16_t *op_dead_args; /* for each operation, each bit tells if the
+                               corresponding argument is dead */
+    uint8_t *op_sync_args;  /* for each operation, each bit tells if the
+                               corresponding output argument needs to be
+                               sync to memory. */
+    
     TCGRegSet reserved_regs;
     intptr_t current_frame_offset;
     intptr_t frame_start;
@@ -660,6 +556,8 @@ struct TCGContext {
     int goto_tb_issue_mask;
 #endif
 
+    int gen_first_op_idx;
+    int gen_last_op_idx;
     int gen_next_op_idx;
     int gen_next_parm_idx;
 
@@ -678,10 +576,6 @@ struct TCGContext {
 
     TBContext tb_ctx;
 
-    /* Track which vCPU triggers events */
-    CPUState *cpu;                      /* *_trans */
-    TCGv_env tcg_env;                   /* *_exec  */
-
     /* The TCGBackendData structure is private to tcg-target.inc.c.  */
     struct TCGBackendData *be;
 
@@ -701,12 +595,6 @@ struct TCGContext {
 
 extern TCGContext tcg_ctx;
 
-static inline void tcg_set_insn_param(int op_idx, int arg, TCGArg v)
-{
-    int op_argi = tcg_ctx.gen_op_buf[op_idx].args;
-    tcg_ctx.gen_opparam_buf[op_argi + arg] = v;
-}
-
 /* The number of opcodes emitted so far.  */
 static inline int tcg_op_buf_count(void)
 {
@@ -869,6 +757,15 @@ do {\
     abort();\
 } while (0)
 
+#ifdef CONFIG_DEBUG_TCG
+# define tcg_debug_assert(X) do { assert(X); } while (0)
+#elif QEMU_GNUC_PREREQ(4, 5)
+# define tcg_debug_assert(X) \
+    do { if (!(X)) { __builtin_unreachable(); } } while (0)
+#else
+# define tcg_debug_assert(X) do { (void)(X); } while (0)
+#endif
+
 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
 
 #if UINTPTR_MAX == UINT32_MAX
@@ -899,9 +796,6 @@ void tcg_gen_callN(TCGContext *s, void *func,
                    TCGArg ret, int nargs, TCGArg *args);
 
 void tcg_op_remove(TCGContext *s, TCGOp *op);
-TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op, TCGOpcode opc, int narg);
-TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, TCGOpcode opc, int narg);
-
 void tcg_optimize(TCGContext *s);
 
 /* only used for debugging purposes */
@@ -1025,7 +919,7 @@ static inline unsigned get_mmuidx(TCGMemOpIdx oi)
 
 /**
  * tcg_qemu_tb_exec:
- * @env: pointer to CPUArchState for the CPU
+ * @env: CPUArchState * for the CPU
  * @tb_ptr: address of generated code for the TB to execute
  *
  * Start executing code from a given translation block.
@@ -1036,31 +930,30 @@ static inline unsigned get_mmuidx(TCGMemOpIdx oi)
  * which has not yet been directly linked, or an asynchronous
  * event such as an interrupt needs handling.
  *
- * Return: The return value is the value passed to the corresponding
- * tcg_gen_exit_tb() at translation time of the last TB attempted to execute.
- * The value is either zero or a 4-byte aligned pointer to that TB combined
- * with additional information in its two least significant bits. The
- * additional information is encoded as follows:
+ * The return value is a pointer to the next TB to execute
+ * (if known; otherwise zero). This pointer is assumed to be
+ * 4-aligned, and the bottom two bits are used to return further
+ * information:
  *  0, 1: the link between this TB and the next is via the specified
  *        TB index (0 or 1). That is, we left the TB via (the equivalent
  *        of) "goto_tb <index>". The main loop uses this to determine
  *        how to link the TB just executed to the next.
  *  2:    we are using instruction counting code generation, and we
  *        did not start executing this TB because the instruction counter
- *        would hit zero midway through it. In this case the pointer
+ *        would hit zero midway through it. In this case the next-TB pointer
  *        returned is the TB we were about to execute, and the caller must
  *        arrange to execute the remaining count of instructions.
  *  3:    we stopped because the CPU's exit_request flag was set
  *        (usually meaning that there is an interrupt that needs to be
- *        handled). The pointer returned is the TB we were about to execute
- *        when we noticed the pending exit request.
+ *        handled). The next-TB pointer returned is the TB we were
+ *        about to execute when we noticed the pending exit request.
  *
  * If the bottom two bits indicate an exit-via-index then the CPU
  * state is correctly synchronised and ready for execution of the next
  * TB (and in particular the guest PC is the address to execute next).
  * Otherwise, we gave up on execution of this TB before it started, and
  * the caller must fix up the CPU state by calling the CPU's
- * synchronize_from_tb() method with the TB pointer we return (falling
+ * synchronize_from_tb() method with the next-TB pointer we return (falling
  * back to calling the CPU's set_pc method with tb->pb if no
  * synchronize_from_tb() method exists).
  *
index 868228b..3942f9c 100644 (file)
  * Therefore, we need both 32 and 64 bit virtual machines (interpreter).
  */
 
-#ifndef TCG_TARGET_H
+#if !defined(TCG_TARGET_H)
 #define TCG_TARGET_H
 
+
 #define TCG_TARGET_INTERPRETER 1
 #define TCG_TARGET_INSN_UNIT_SIZE 1
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
index 3c47ea7..e2fc52a 100644 (file)
@@ -553,19 +553,17 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         tcg_out64(s, args[0]);
         break;
     case INDEX_op_goto_tb:
-        if (s->tb_jmp_insn_offset) {
+        if (s->tb_jmp_offset) {
             /* Direct jump method. */
-            tcg_debug_assert(args[0] < ARRAY_SIZE(s->tb_jmp_insn_offset));
-            /* Align for atomic patching and thread safety */
-            s->code_ptr = QEMU_ALIGN_PTR_UP(s->code_ptr, 4);
-            s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
+            tcg_debug_assert(args[0] < ARRAY_SIZE(s->tb_jmp_offset));
+            s->tb_jmp_offset[args[0]] = tcg_current_code_size(s);
             tcg_out32(s, 0);
         } else {
             /* Indirect jump method. */
             TODO();
         }
-        tcg_debug_assert(args[0] < ARRAY_SIZE(s->tb_jmp_reset_offset));
-        s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
+        tcg_debug_assert(args[0] < ARRAY_SIZE(s->tb_next_offset));
+        s->tb_next_offset[args[0]] = tcg_current_code_size(s);
         break;
     case INDEX_op_br:
         tci_out_label(s, arg_label(args[0]));
@@ -834,12 +832,6 @@ static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
     old_code_ptr[1] = s->code_ptr - old_code_ptr;
 }
 
-static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
-                               TCGReg base, intptr_t ofs)
-{
-    return false;
-}
-
 /* Test if a constant matches the constraint. */
 static int tcg_target_const_match(tcg_target_long val, TCGType type,
                                   const TCGArgConstraint *arg_ct)
diff --git a/tci.c b/tci.c
index b488c0d..82705fe 100644 (file)
--- a/tci.c
+++ b/tci.c
@@ -28,7 +28,7 @@
 #endif
 
 #include "qemu-common.h"
-#include "tcg/tcg.h"           /* MAX_OPC_PARAM_IARGS */
+#include "exec/exec-all.h"           /* MAX_OPC_PARAM_IARGS */
 #include "exec/cpu_ldst.h"
 #include "tcg-op.h"
 
@@ -467,7 +467,7 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
 {
     long tcg_temps[CPU_TEMP_BUF_NLONGS];
     uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS);
-    uintptr_t ret = 0;
+    uintptr_t next_tb = 0;
 
     tci_reg[TCG_AREG0] = (tcg_target_ulong)env;
     tci_reg[TCG_REG_CALL_STACK] = sp_value;
@@ -1085,14 +1085,11 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
             /* QEMU specific operations. */
 
         case INDEX_op_exit_tb:
-            ret = *(uint64_t *)tb_ptr;
+            next_tb = *(uint64_t *)tb_ptr;
             goto exit;
             break;
         case INDEX_op_goto_tb:
-            /* Jump address is aligned */
-            tb_ptr = QEMU_ALIGN_PTR_UP(tb_ptr, 4);
-            t0 = atomic_read((int32_t *)tb_ptr);
-            tb_ptr += sizeof(int32_t);
+            t0 = tci_read_i32(&tb_ptr);
             tci_assert(tb_ptr == old_code_ptr + op_size);
             tb_ptr += (int32_t)t0;
             continue;
@@ -1243,5 +1240,5 @@ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
         tci_assert(tb_ptr == old_code_ptr + op_size);
     }
 exit:
-    return ret;
+    return next_tb;
 }
index dbb5263..9eed229 100644 (file)
@@ -3,17 +3,14 @@ check-qfloat
 check-qint
 check-qjson
 check-qlist
-check-qnull
 check-qstring
 check-qom-interface
 check-qom-proplist
-qht-bench
 rcutorture
 test-aio
 test-base64
 test-bitops
 test-blockjob-txn
-test-clone-visitor
 test-coroutine
 test-crypto-afsplit
 test-crypto-block
@@ -50,10 +47,7 @@ test-qapi-types.[ch]
 test-qapi-visit.[ch]
 test-qdev-global-props
 test-qemu-opts
-test-qdist
 test-qga
-test-qht
-test-qht-par
 test-qmp-commands
 test-qmp-commands.h
 test-qmp-event
similarity index 91%
rename from tests/Makefile.include
rename to tests/Makefile
index 14be491..9194f18 100644 (file)
@@ -16,14 +16,10 @@ check-unit-y += tests/check-qstring$(EXESUF)
 gcov-files-check-qstring-y = qobject/qstring.c
 check-unit-y += tests/check-qlist$(EXESUF)
 gcov-files-check-qlist-y = qobject/qlist.c
-check-unit-y += tests/check-qnull$(EXESUF)
-gcov-files-check-qnull-y = qobject/qnull.c
 check-unit-y += tests/check-qjson$(EXESUF)
 gcov-files-check-qjson-y = qobject/qjson.c
 check-unit-y += tests/test-qmp-output-visitor$(EXESUF)
 gcov-files-test-qmp-output-visitor-y = qapi/qmp-output-visitor.c
-check-unit-y += tests/test-clone-visitor$(EXESUF)
-gcov-files-test-clone-visitor-y = qapi/qapi-clone-visitor.c
 check-unit-y += tests/test-qmp-input-visitor$(EXESUF)
 gcov-files-test-qmp-input-visitor-y = qapi/qmp-input-visitor.c
 check-unit-y += tests/test-qmp-input-strict$(EXESUF)
@@ -52,7 +48,6 @@ gcov-files-test-thread-pool-y = thread-pool.c
 gcov-files-test-hbitmap-y = util/hbitmap.c
 check-unit-y += tests/test-hbitmap$(EXESUF)
 gcov-files-test-hbitmap-y = blockjob.c
-check-unit-y += tests/test-blockjob$(EXESUF)
 check-unit-y += tests/test-blockjob-txn$(EXESUF)
 check-unit-y += tests/test-x86-cpuid$(EXESUF)
 # all code tested by test-x86-cpuid is inside topology.h
@@ -73,12 +68,6 @@ check-unit-y += tests/rcutorture$(EXESUF)
 gcov-files-rcutorture-y = util/rcu.c
 check-unit-y += tests/test-rcu-list$(EXESUF)
 gcov-files-test-rcu-list-y = util/rcu.c
-check-unit-y += tests/test-qdist$(EXESUF)
-gcov-files-test-qdist-y = util/qdist.c
-check-unit-y += tests/test-qht$(EXESUF)
-gcov-files-test-qht-y = util/qht.c
-check-unit-y += tests/test-qht-par$(EXESUF)
-gcov-files-test-qht-par-y = util/qht.c
 check-unit-y += tests/test-bitops$(EXESUF)
 check-unit-$(CONFIG_HAS_GLIB_SUBPROCESS_TESTS) += tests/test-qdev-global-props$(EXESUF)
 check-unit-y += tests/check-qom-interface$(EXESUF)
@@ -89,7 +78,7 @@ check-unit-y += tests/test-qemu-opts$(EXESUF)
 gcov-files-test-qemu-opts-y = qom/test-qemu-opts.c
 check-unit-y += tests/test-write-threshold$(EXESUF)
 gcov-files-test-write-threshold-y = block/write-threshold.c
-check-unit-y += tests/test-crypto-hash$(EXESUF)
+check-unit-$(CONFIG_GNUTLS_HASH) += tests/test-crypto-hash$(EXESUF)
 check-unit-y += tests/test-crypto-cipher$(EXESUF)
 check-unit-y += tests/test-crypto-secret$(EXESUF)
 check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF)
@@ -151,8 +140,6 @@ gcov-files-virtio-y += $(gcov-files-virtioserial-y)
 
 check-qtest-pci-y += tests/e1000-test$(EXESUF)
 gcov-files-pci-y += hw/net/e1000.c
-check-qtest-pci-y += tests/e1000e-test$(EXESUF)
-gcov-files-pci-y += hw/net/e1000e.c hw/net/e1000e_core.c
 check-qtest-pci-y += tests/rtl8139-test$(EXESUF)
 gcov-files-pci-y += hw/net/rtl8139.c
 check-qtest-pci-y += tests/pcnet-test$(EXESUF)
@@ -209,8 +196,8 @@ check-qtest-i386-y += $(check-qtest-pci-y)
 gcov-files-i386-y += $(gcov-files-pci-y)
 check-qtest-i386-y += tests/vmxnet3-test$(EXESUF)
 gcov-files-i386-y += hw/net/vmxnet3.c
-gcov-files-i386-y += hw/net/net_rx_pkt.c
-gcov-files-i386-y += hw/net/net_tx_pkt.c
+gcov-files-i386-y += hw/net/vmxnet_rx_pkt.c
+gcov-files-i386-y += hw/net/vmxnet_tx_pkt.c
 check-qtest-i386-y += tests/pvpanic-test$(EXESUF)
 gcov-files-i386-y += i386-softmmu/hw/misc/pvpanic.c
 check-qtest-i386-y += tests/i82801b11-test$(EXESUF)
@@ -237,8 +224,7 @@ endif
 check-qtest-i386-y += tests/test-netfilter$(EXESUF)
 check-qtest-i386-y += tests/test-filter-mirror$(EXESUF)
 check-qtest-i386-y += tests/test-filter-redirector$(EXESUF)
-check-qtest-i386-y += tests/postcopy-test$(EXESUF)
-check-qtest-x86_64-y += $(check-qtest-i386-y)
+check-qtest-x86_64-y = $(check-qtest-i386-y)
 gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
 gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
 check-qtest-mips-y = tests/endianness-test$(EXESUF)
@@ -254,24 +240,16 @@ check-qtest-sparc64-y = tests/endianness-test$(EXESUF)
 gcov-files-sparc-y += hw/timer/m48t59.c
 gcov-files-sparc64-y += hw/timer/m48t59.c
 check-qtest-arm-y = tests/tmp105-test$(EXESUF)
-check-qtest-arm-y += tests/ds1338-test$(EXESUF)
+check-qtest-arm-y = tests/ds1338-test$(EXESUF)
 gcov-files-arm-y += hw/misc/tmp105.c
 check-qtest-arm-y += tests/virtio-blk-test$(EXESUF)
 gcov-files-arm-y += arm-softmmu/hw/block/virtio-blk.c
 check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
 check-qtest-ppc64-y += tests/boot-order-test$(EXESUF)
-check-qtest-ppc-y += tests/drive_del-test$(EXESUF)
-check-qtest-ppc64-y += tests/drive_del-test$(EXESUF)
 check-qtest-ppc64-y += tests/spapr-phb-test$(EXESUF)
 gcov-files-ppc64-y += ppc64-softmmu/hw/ppc/spapr_pci.c
-check-qtest-ppc-y += tests/prom-env-test$(EXESUF)
-check-qtest-ppc64-y += tests/prom-env-test$(EXESUF)
-check-qtest-sparc-y += tests/prom-env-test$(EXESUF)
-#Disabled for now, triggers a TCG bug on 32-bit hosts
-#check-qtest-sparc64-y += tests/prom-env-test$(EXESUF)
 check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
 check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
-check-qtest-ppc64-y += tests/postcopy-test$(EXESUF)
 
 check-qtest-generic-y += tests/qom-test$(EXESUF)
 
@@ -288,10 +266,6 @@ qapi-schema += args-alternate.json
 qapi-schema += args-any.json
 qapi-schema += args-array-empty.json
 qapi-schema += args-array-unknown.json
-qapi-schema += args-bad-boxed.json
-qapi-schema += args-boxed-anon.json
-qapi-schema += args-boxed-empty.json
-qapi-schema += args-boxed-string.json
 qapi-schema += args-int.json
 qapi-schema += args-invalid.json
 qapi-schema += args-member-array-bad.json
@@ -325,7 +299,6 @@ qapi-schema += enum-wrong-data.json
 qapi-schema += escape-outside-string.json
 qapi-schema += escape-too-big.json
 qapi-schema += escape-too-short.json
-qapi-schema += event-boxed-empty.json
 qapi-schema += event-case.json
 qapi-schema += event-nest-struct.json
 qapi-schema += flat-union-array-branch.json
@@ -335,7 +308,6 @@ qapi-schema += flat-union-base-any.json
 qapi-schema += flat-union-base-union.json
 qapi-schema += flat-union-clash-member.json
 qapi-schema += flat-union-empty.json
-qapi-schema += flat-union-incomplete-branch.json
 qapi-schema += flat-union-inline.json
 qapi-schema += flat-union-int-branch.json
 qapi-schema += flat-union-invalid-branch-key.json
@@ -410,18 +382,14 @@ GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h \
        tests/test-qmp-introspect.h
 
 test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \
-       tests/check-qlist.o tests/check-qfloat.o tests/check-qnull.o \
-       tests/check-qjson.o \
+       tests/check-qlist.o tests/check-qfloat.o tests/check-qjson.o \
        tests/test-coroutine.o tests/test-string-output-visitor.o \
        tests/test-string-input-visitor.o tests/test-qmp-output-visitor.o \
-       tests/test-clone-visitor.o \
        tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \
        tests/test-qmp-commands.o tests/test-visitor-serialization.o \
        tests/test-x86-cpuid.o tests/test-mul64.o tests/test-int128.o \
        tests/test-opts-visitor.o tests/test-qmp-event.o \
-       tests/rcutorture.o tests/test-rcu-list.o \
-       tests/test-qdist.o \
-       tests/test-qht.o tests/qht-bench.o tests/test-qht-par.o
+       tests/rcutorture.o tests/test-rcu-list.o
 
 $(test-obj-y): QEMU_INCLUDES += -Itests
 QEMU_CFLAGS += -I$(SRC_PATH)/tests
@@ -442,7 +410,6 @@ tests/check-qstring$(EXESUF): tests/check-qstring.o $(test-util-obj-y)
 tests/check-qdict$(EXESUF): tests/check-qdict.o $(test-util-obj-y)
 tests/check-qlist$(EXESUF): tests/check-qlist.o $(test-util-obj-y)
 tests/check-qfloat$(EXESUF): tests/check-qfloat.o $(test-util-obj-y)
-tests/check-qnull$(EXESUF): tests/check-qnull.o $(test-util-obj-y)
 tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y)
 tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y)
 tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y)
@@ -450,7 +417,6 @@ tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y)
 tests/test-aio$(EXESUF): tests/test-aio.o $(test-block-obj-y)
 tests/test-rfifolock$(EXESUF): tests/test-rfifolock.o $(test-util-obj-y)
 tests/test-throttle$(EXESUF): tests/test-throttle.o $(test-block-obj-y)
-tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-util-obj-y)
 tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
 tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
 tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)
@@ -461,21 +427,16 @@ tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o
 tests/test-int128$(EXESUF): tests/test-int128.o
 tests/rcutorture$(EXESUF): tests/rcutorture.o $(test-util-obj-y)
 tests/test-rcu-list$(EXESUF): tests/test-rcu-list.o $(test-util-obj-y)
-tests/test-qdist$(EXESUF): tests/test-qdist.o $(test-util-obj-y)
-tests/test-qht$(EXESUF): tests/test-qht.o $(test-util-obj-y)
-tests/test-qht-par$(EXESUF): tests/test-qht-par.o tests/qht-bench$(EXESUF) $(test-util-obj-y)
-tests/qht-bench$(EXESUF): tests/qht-bench.o $(test-util-obj-y)
 
 tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
        hw/core/qdev.o hw/core/qdev-properties.o hw/core/hotplug.o\
-       hw/core/bus.o \
        hw/core/irq.o \
        hw/core/fw-path-provider.o \
        $(test-qapi-obj-y)
 tests/test-vmstate$(EXESUF): tests/test-vmstate.o \
-       migration/vmstate.o migration/qemu-file.o \
-        migration/qemu-file-channel.o migration/qjson.o \
-       $(test-io-obj-y)
+       migration/vmstate.o migration/qemu-file.o migration/qemu-file-buf.o \
+        migration/qemu-file-unix.o qjson.o \
+       $(test-qom-obj-y)
 tests/test-timed-average$(EXESUF): tests/test-timed-average.o qemu-timer.o \
        $(test-util-obj-y)
 tests/test-base64$(EXESUF): tests/test-base64.o \
@@ -513,7 +474,6 @@ tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(
 tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y)
 tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y)
 tests/test-qmp-output-visitor$(EXESUF): tests/test-qmp-output-visitor.o $(test-qapi-obj-y)
-tests/test-clone-visitor$(EXESUF): tests/test-clone-visitor.o $(test-qapi-obj-y)
 tests/test-qmp-input-visitor$(EXESUF): tests/test-qmp-input-visitor.o $(test-qapi-obj-y)
 tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y)
 tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y)
@@ -570,7 +530,6 @@ tests/rtc-test$(EXESUF): tests/rtc-test.o
 tests/m48t59-test$(EXESUF): tests/m48t59-test.o
 tests/endianness-test$(EXESUF): tests/endianness-test.o
 tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y)
-tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y)
 tests/fdc-test$(EXESUF): tests/fdc-test.o
 tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
 tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y)
@@ -587,7 +546,6 @@ tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
 tests/q35-test$(EXESUF): tests/q35-test.o $(libqos-pc-obj-y)
 tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
 tests/e1000-test$(EXESUF): tests/e1000-test.o
-tests/e1000e-test$(EXESUF): tests/e1000e-test.o $(libqos-pc-obj-y)
 tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o $(libqos-pc-obj-y)
 tests/pcnet-test$(EXESUF): tests/pcnet-test.o
 tests/eepro100-test$(EXESUF): tests/eepro100-test.o
@@ -621,7 +579,6 @@ tests/usb-hcd-uhci-test$(EXESUF): tests/usb-hcd-uhci-test.o $(libqos-usb-obj-y)
 tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-usb-obj-y)
 tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y)
 tests/pc-cpu-test$(EXESUF): tests/pc-cpu-test.o
-tests/postcopy-test$(EXESUF): tests/postcopy-test.o
 tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y) $(test-io-obj-y)
 tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
 tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
@@ -632,18 +589,6 @@ tests/test-filter-redirector$(EXESUF): tests/test-filter-redirector.o $(qtest-ob
 tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y)
 tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o
 
-tests/migration/stress$(EXESUF): tests/migration/stress.o
-       $(call quiet-command, $(LINKPROG) -static -O3 $(PTHREAD_LIB) -o $@ $< ,"  LINK  $(TARGET_DIR)$@")
-
-INITRD_WORK_DIR=tests/migration/initrd
-
-tests/migration/initrd-stress.img: tests/migration/stress$(EXESUF)
-       mkdir -p $(INITRD_WORK_DIR)
-       cp $< $(INITRD_WORK_DIR)/init
-       (cd $(INITRD_WORK_DIR) && (find | cpio --quiet -o -H newc | gzip -9)) > $@
-       rm $(INITRD_WORK_DIR)/init
-       rmdir $(INITRD_WORK_DIR)
-
 ifeq ($(CONFIG_POSIX),y)
 LIBS += -lutil
 endif
index e0d177b..75cab8f 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
diff --git a/tests/acpi-test-data/pc/APIC.cphp b/tests/acpi-test-data/pc/APIC.cphp
deleted file mode 100644 (file)
index 1bf8a0a..0000000
Binary files a/tests/acpi-test-data/pc/APIC.cphp and /dev/null differ
index 8053d71..9d1274d 100644 (file)
Binary files a/tests/acpi-test-data/pc/DSDT and b/tests/acpi-test-data/pc/DSDT differ
index 850e71a..cf48c62 100644 (file)
Binary files a/tests/acpi-test-data/pc/DSDT.bridge and b/tests/acpi-test-data/pc/DSDT.bridge differ
diff --git a/tests/acpi-test-data/pc/DSDT.cphp b/tests/acpi-test-data/pc/DSDT.cphp
deleted file mode 100644 (file)
index e8b1462..0000000
Binary files a/tests/acpi-test-data/pc/DSDT.cphp and /dev/null differ
diff --git a/tests/acpi-test-data/pc/DSDT.ipmikcs b/tests/acpi-test-data/pc/DSDT.ipmikcs
deleted file mode 100644 (file)
index 8ac48af..0000000
Binary files a/tests/acpi-test-data/pc/DSDT.ipmikcs and /dev/null differ
diff --git a/tests/acpi-test-data/q35/APIC.cphp b/tests/acpi-test-data/q35/APIC.cphp
deleted file mode 100644 (file)
index 1bf8a0a..0000000
Binary files a/tests/acpi-test-data/q35/APIC.cphp and /dev/null differ
index 58fbb3d..1c089c3 100644 (file)
Binary files a/tests/acpi-test-data/q35/DSDT and b/tests/acpi-test-data/q35/DSDT differ
index c392802..b29fcda 100644 (file)
Binary files a/tests/acpi-test-data/q35/DSDT.bridge and b/tests/acpi-test-data/q35/DSDT.bridge differ
diff --git a/tests/acpi-test-data/q35/DSDT.cphp b/tests/acpi-test-data/q35/DSDT.cphp
deleted file mode 100644 (file)
index 6cc28c6..0000000
Binary files a/tests/acpi-test-data/q35/DSDT.cphp and /dev/null differ
diff --git a/tests/acpi-test-data/q35/DSDT.ipmibt b/tests/acpi-test-data/q35/DSDT.ipmibt
deleted file mode 100644 (file)
index 0ea38e1..0000000
Binary files a/tests/acpi-test-data/q35/DSDT.ipmibt and /dev/null differ
index 9c0adce..6869f7f 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "qemu/osdep.h"
 #include <getopt.h>
+#include <glib.h>
 
 #include "libqtest.h"
 #include "libqos/libqos-pc.h"
@@ -1063,34 +1064,11 @@ static void test_dma_fragmented(void)
     g_free(tx);
 }
 
-/*
- * Write sector 1 with random data to make AHCI storage dirty
- * Needed for flush tests so that flushes actually go though the block layer
- */
-static void make_dirty(AHCIQState* ahci, uint8_t port)
-{
-    uint64_t ptr;
-    unsigned bufsize = 512;
-
-    ptr = ahci_alloc(ahci, bufsize);
-    g_assert(ptr);
-
-    ahci_guest_io(ahci, port, CMD_WRITE_DMA, ptr, bufsize, 1);
-    ahci_free(ahci, ptr);
-}
-
 static void test_flush(void)
 {
     AHCIQState *ahci;
-    uint8_t port;
 
     ahci = ahci_boot_and_enable(NULL);
-
-    port = ahci_port_select(ahci);
-    ahci_port_clear(ahci, port);
-
-    make_dirty(ahci, port);
-
     ahci_test_flush(ahci);
     ahci_shutdown(ahci);
 }
@@ -1110,13 +1088,10 @@ static void test_flush_retry(void)
                                 debug_path,
                                 tmp_path, imgfmt);
 
+    /* Issue Flush Command and wait for error */
     port = ahci_port_select(ahci);
     ahci_port_clear(ahci, port);
 
-    /* Issue write so that flush actually goes to disk */
-    make_dirty(ahci, port);
-
-    /* Issue Flush Command and wait for error */
     cmd = ahci_guest_io_halt(ahci, port, CMD_FLUSH_CACHE, 0, 0, 0);
     ahci_guest_io_resume(ahci, cmd);
 
@@ -1369,13 +1344,9 @@ static void test_flush_migrate(void)
 
     set_context(src->parent);
 
+    /* Issue Flush Command */
     px = ahci_port_select(src);
     ahci_port_clear(src, px);
-
-    /* Dirty device so that flush reaches disk */
-    make_dirty(src, px);
-
-    /* Issue Flush Command */
     cmd = ahci_command_create(CMD_FLUSH_CACHE);
     ahci_command_commit(src, cmd, px);
     ahci_command_issue_async(src, cmd);
index de4019e..0352814 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <glib/gstdio.h>
 #include "qemu-common.h"
 #include "libqtest.h"
@@ -49,8 +50,6 @@ typedef struct {
     GArray *tables;
     uint32_t smbios_ep_addr;
     struct smbios_21_entry_point smbios_ep_table;
-    uint8_t *required_struct_types;
-    int required_struct_types_len;
 } test_data;
 
 #define ACPI_READ_FIELD(field, addr)           \
@@ -336,7 +335,7 @@ static void test_acpi_tables(test_data *data)
     for (i = 0; i < tables_nr; i++) {
         AcpiSdtTable ssdt_table;
 
-        memset(&ssdt_table, 0, sizeof(ssdt_table));
+        memset(&ssdt_table, 0 , sizeof(ssdt_table));
         uint32_t addr = data->rsdt_tables_addr[i + 1]; /* fadt is first */
         test_dst_table(&ssdt_table, addr);
         g_array_append_val(data->tables, ssdt_table);
@@ -465,6 +464,7 @@ static GArray *load_expected_aml(test_data *data)
 {
     int i;
     AcpiSdtTable *sdt;
+    gchar *aml_file = NULL;
     GError *error = NULL;
     gboolean ret;
 
@@ -472,7 +472,6 @@ static GArray *load_expected_aml(test_data *data)
     for (i = 0; i < data->tables->len; ++i) {
         AcpiSdtTable exp_sdt;
         uint32_t signature;
-        gchar *aml_file = NULL;
         const char *ext = data->variant ? data->variant : "";
 
         sdt = &g_array_index(data->tables, AcpiSdtTable, i);
@@ -485,21 +484,13 @@ static GArray *load_expected_aml(test_data *data)
 try_again:
         aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine,
                                    (gchar *)&signature, ext);
-        if (getenv("V")) {
-            fprintf(stderr, "\nLooking for expected file '%s'\n", aml_file);
-        }
-        if (g_file_test(aml_file, G_FILE_TEST_EXISTS)) {
-            exp_sdt.aml_file = aml_file;
-        } else if (*ext != '\0') {
-            /* try fallback to generic (extention less) expected file */
-            ext = "";
+        if (data->variant && !g_file_test(aml_file, G_FILE_TEST_EXISTS)) {
             g_free(aml_file);
+            ext = "";
             goto try_again;
         }
-        g_assert(exp_sdt.aml_file);
-        if (getenv("V")) {
-            fprintf(stderr, "\nUsing expected file '%s'\n", aml_file);
-        }
+        exp_sdt.aml_file = aml_file;
+        g_assert(g_file_test(aml_file, G_FILE_TEST_EXISTS));
         ret = g_file_get_contents(aml_file, &exp_sdt.aml,
                                   &exp_sdt.aml_len, &error);
         g_assert(ret);
@@ -663,6 +654,7 @@ static void test_smbios_structs(test_data *data)
     uint32_t addr = ep_table->structure_table_address;
     int i, len, max_len = 0;
     uint8_t type, prv, crt;
+    uint8_t required_struct_types[] = {0, 1, 3, 4, 16, 17, 19, 32, 127};
 
     /* walk the smbios tables */
     for (i = 0; i < ep_table->number_of_structures; i++) {
@@ -702,8 +694,8 @@ static void test_smbios_structs(test_data *data)
     g_assert_cmpuint(ep_table->max_structure_size, ==, max_len);
 
     /* required struct types must all be present */
-    for (i = 0; i < data->required_struct_types_len; i++) {
-        g_assert(test_bit(data->required_struct_types[i], struct_bitmap));
+    for (i = 0; i < ARRAY_SIZE(required_struct_types); i++) {
+        g_assert(test_bit(required_struct_types[i], struct_bitmap));
     }
 }
 
@@ -743,10 +735,6 @@ static void test_acpi_one(const char *params, test_data *data)
     g_free(args);
 }
 
-static uint8_t base_required_struct_types[] = {
-    0, 1, 3, 4, 16, 17, 19, 32, 127
-};
-
 static void test_acpi_piix4_tcg(void)
 {
     test_data data;
@@ -756,8 +744,6 @@ static void test_acpi_piix4_tcg(void)
      */
     memset(&data, 0, sizeof(data));
     data.machine = MACHINE_PC;
-    data.required_struct_types = base_required_struct_types;
-    data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
     test_acpi_one("-machine accel=tcg", &data);
     free_test_data(&data);
 }
@@ -769,8 +755,6 @@ static void test_acpi_piix4_tcg_bridge(void)
     memset(&data, 0, sizeof(data));
     data.machine = MACHINE_PC;
     data.variant = ".bridge";
-    data.required_struct_types = base_required_struct_types;
-    data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
     test_acpi_one("-machine accel=tcg -device pci-bridge,chassis_nr=1", &data);
     free_test_data(&data);
 }
@@ -781,8 +765,6 @@ static void test_acpi_q35_tcg(void)
 
     memset(&data, 0, sizeof(data));
     data.machine = MACHINE_Q35;
-    data.required_struct_types = base_required_struct_types;
-    data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
     test_acpi_one("-machine q35,accel=tcg", &data);
     free_test_data(&data);
 }
@@ -794,76 +776,11 @@ static void test_acpi_q35_tcg_bridge(void)
     memset(&data, 0, sizeof(data));
     data.machine = MACHINE_Q35;
     data.variant = ".bridge";
-    data.required_struct_types = base_required_struct_types;
-    data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
     test_acpi_one("-machine q35,accel=tcg -device pci-bridge,chassis_nr=1",
                   &data);
     free_test_data(&data);
 }
 
-static void test_acpi_piix4_tcg_cphp(void)
-{
-    test_data data;
-
-    memset(&data, 0, sizeof(data));
-    data.machine = MACHINE_PC;
-    data.variant = ".cphp";
-    test_acpi_one("-machine accel=tcg"
-                  " -smp 2,cores=3,sockets=2,maxcpus=6",
-                  &data);
-    free_test_data(&data);
-}
-
-static void test_acpi_q35_tcg_cphp(void)
-{
-    test_data data;
-
-    memset(&data, 0, sizeof(data));
-    data.machine = MACHINE_Q35;
-    data.variant = ".cphp";
-    test_acpi_one("-machine q35,accel=tcg"
-                  " -smp 2,cores=3,sockets=2,maxcpus=6",
-                  &data);
-    free_test_data(&data);
-}
-
-static uint8_t ipmi_required_struct_types[] = {
-    0, 1, 3, 4, 16, 17, 19, 32, 38, 127
-};
-
-static void test_acpi_q35_tcg_ipmi(void)
-{
-    test_data data;
-
-    memset(&data, 0, sizeof(data));
-    data.machine = MACHINE_Q35;
-    data.variant = ".ipmibt";
-    data.required_struct_types = ipmi_required_struct_types;
-    data.required_struct_types_len = ARRAY_SIZE(ipmi_required_struct_types);
-    test_acpi_one("-machine q35,accel=tcg -device ipmi-bmc-sim,id=bmc0"
-                  " -device isa-ipmi-bt,bmc=bmc0",
-                  &data);
-    free_test_data(&data);
-}
-
-static void test_acpi_piix4_tcg_ipmi(void)
-{
-    test_data data;
-
-    /* Supplying -machine accel argument overrides the default (qtest).
-     * This is to make guest actually run.
-     */
-    memset(&data, 0, sizeof(data));
-    data.machine = MACHINE_PC;
-    data.variant = ".ipmikcs";
-    data.required_struct_types = ipmi_required_struct_types;
-    data.required_struct_types_len = ARRAY_SIZE(ipmi_required_struct_types);
-    test_acpi_one("-machine accel=tcg -device ipmi-bmc-sim,id=bmc0"
-                  " -device isa-ipmi-kcs,irq=0,bmc=bmc0",
-                  &data);
-    free_test_data(&data);
-}
-
 int main(int argc, char *argv[])
 {
     const char *arch = qtest_get_arch();
@@ -880,10 +797,6 @@ int main(int argc, char *argv[])
         qtest_add_func("acpi/piix4/tcg/bridge", test_acpi_piix4_tcg_bridge);
         qtest_add_func("acpi/q35/tcg", test_acpi_q35_tcg);
         qtest_add_func("acpi/q35/tcg/bridge", test_acpi_q35_tcg_bridge);
-        qtest_add_func("acpi/piix4/tcg/ipmi", test_acpi_piix4_tcg_ipmi);
-        qtest_add_func("acpi/q35/tcg/ipmi", test_acpi_q35_tcg_ipmi);
-        qtest_add_func("acpi/piix4/tcg/cpuhp", test_acpi_piix4_tcg_cphp);
-        qtest_add_func("acpi/q35/tcg/cpuhp", test_acpi_q35_tcg_cphp);
     }
     ret = g_test_run();
     boot_sector_cleanup(disk);
index fc1e794..a6d8bd5 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqos/fw_cfg.h"
 #include "libqtest.h"
 
index f64b477..38be029 100644 (file)
@@ -11,8 +11,8 @@
  * See the COPYING file in the top-level directory.
  */
 
-#ifndef TEST_BOOT_SECTOR_H
-#define TEST_BOOT_SECTOR_H
+#ifndef TEST_BOOT_SECTOR
+#define TEST_BOOT_SECTOR
 
 /* Create boot disk file.  */
 int boot_sector_init(const char *fname);
@@ -23,4 +23,4 @@ void boot_sector_test(void);
 /* unlink boot disk file.  */
 void boot_sector_cleanup(const char *fname);
 
-#endif /* TEST_BOOT_SECTOR_H */
+#endif /* TEST_BOOT_SECTOR */
index 42da1e6..a43056c 100644 (file)
@@ -10,6 +10,7 @@
  * See the COPYING.LIB file in the top-level directory.
  */
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qapi/qmp/qint.h"
 #include "qapi/qmp/qdict.h"
index 1da2cda..3102608 100644 (file)
@@ -11,6 +11,7 @@
  *
  */
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qapi/qmp/qfloat.h"
 #include "qemu-common.h"
index b6e4555..c86f7df 100644 (file)
@@ -10,6 +10,7 @@
  * See the COPYING.LIB file in the top-level directory.
  */
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qapi/qmp/qint.h"
 #include "qemu-common.h"
index 8595574..99de6f5 100644 (file)
  *
  */
 #include "qemu/osdep.h"
-
-#include "qapi/qmp/types.h"
+#include <glib.h>
+
+#include "qapi/qmp/qstring.h"
+#include "qapi/qmp/qint.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qfloat.h"
+#include "qapi/qmp/qbool.h"
 #include "qapi/qmp/qjson.h"
+
 #include "qemu-common.h"
 
 static void escaped_string(void)
index e16da5e..f231d5f 100644 (file)
@@ -10,6 +10,7 @@
  * See the COPYING.LIB file in the top-level directory.
  */
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qapi/qmp/qint.h"
 #include "qapi/qmp/qlist.h"
diff --git a/tests/check-qnull.c b/tests/check-qnull.c
deleted file mode 100644 (file)
index dc906b1..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * QNull unit-tests.
- *
- * Copyright (C) 2016 Red Hat Inc.
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-#include "qemu/osdep.h"
-
-#include "qapi/qmp/qobject.h"
-#include "qemu-common.h"
-#include "qapi/qmp-input-visitor.h"
-#include "qapi/qmp-output-visitor.h"
-#include "qapi/error.h"
-
-/*
- * Public Interface test-cases
- *
- * (with some violations to access 'private' data)
- */
-
-static void qnull_ref_test(void)
-{
-    QObject *obj;
-
-    g_assert(qnull_.refcnt == 1);
-    obj = qnull();
-    g_assert(obj);
-    g_assert(obj == &qnull_);
-    g_assert(qnull_.refcnt == 2);
-    g_assert(qobject_type(obj) == QTYPE_QNULL);
-    qobject_decref(obj);
-    g_assert(qnull_.refcnt == 1);
-}
-
-static void qnull_visit_test(void)
-{
-    QObject *obj;
-    Visitor *v;
-
-    /*
-     * Most tests of interactions between QObject and visitors are in
-     * test-qmp-*-visitor; but these tests live here because they
-     * depend on layering violations to check qnull_ refcnt.
-     */
-
-    g_assert(qnull_.refcnt == 1);
-    obj = qnull();
-    v = qmp_input_visitor_new(obj, true);
-    qobject_decref(obj);
-    visit_type_null(v, NULL, &error_abort);
-    visit_free(v);
-
-    v = qmp_output_visitor_new(&obj);
-    visit_type_null(v, NULL, &error_abort);
-    visit_complete(v, &obj);
-    g_assert(obj == &qnull_);
-    qobject_decref(obj);
-    visit_free(v);
-
-    g_assert(qnull_.refcnt == 1);
-}
-
-int main(int argc, char **argv)
-{
-    g_test_init(&argc, &argv, NULL);
-
-    g_test_add_func("/public/qnull_ref", qnull_ref_test);
-    g_test_add_func("/public/qnull_visit", qnull_visit_test);
-
-    return g_test_run();
-}
index 719ddcf..09354de 100644 (file)
@@ -10,6 +10,7 @@
  * See the COPYING.LIB file in the top-level directory.
  */
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qom/object.h"
 #include "qemu/module.h"
index 42defe7..ffffd87 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qapi/error.h"
 #include "qom/object.h"
index 239e9d9..9877b42 100644 (file)
@@ -10,6 +10,7 @@
  * See the COPYING.LIB file in the top-level directory.
  */
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qapi/qmp/qstring.h"
 #include "qemu-common.h"
diff --git a/tests/data/test-qga-config b/tests/data/test-qga-config
deleted file mode 100644 (file)
index 4bb721a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-[general]
-daemon=false
-method=virtio-serial
-path=/path/to/org.qemu.guest_agent.0
-pidfile=/var/foo/qemu-ga.pid
-statedir=/var/state
-verbose=true
-blacklist=guest-ping;guest-get-time
index 37debc1..4477926 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu-common.h"
 #include "qapi/qmp/qstring.h"
 #include "libqtest.h"
index 9146021..5706d33 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 static void pci_cirrus(void)
@@ -50,6 +51,8 @@ static void pci_virtio_vga(void)
 
 int main(int argc, char **argv)
 {
+    int ret;
+
     g_test_init(&argc, &argv, NULL);
 
     qtest_add_func("/display/pci/cirrus", pci_cirrus);
@@ -60,5 +63,7 @@ int main(int argc, char **argv)
 #ifdef CONFIG_VIRTIO_VGA
     qtest_add_func("/display/pci/virtio-vga", pci_virtio_vga);
 #endif
-    return g_test_run();
+    ret = g_test_run();
+
+    return ret;
 }
diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include
deleted file mode 100644 (file)
index 4f4707d..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-# Makefile for Docker tests
-
-.PHONY: docker docker-test docker-clean docker-image docker-qemu-src
-
-DOCKER_SUFFIX := .docker
-DOCKER_FILES_DIR := $(SRC_PATH)/tests/docker/dockerfiles
-DOCKER_IMAGES := $(notdir $(basename $(wildcard $(DOCKER_FILES_DIR)/*.docker)))
-DOCKER_TARGETS := $(patsubst %,docker-image-%,$(DOCKER_IMAGES))
-# Use a global constant ccache directory to speed up repetitive builds
-DOCKER_CCACHE_DIR := $$HOME/.cache/qemu-docker-ccache
-
-DOCKER_TESTS := $(notdir $(shell \
-       find $(SRC_PATH)/tests/docker/ -name 'test-*' -type f))
-
-DOCKER_TOOLS := travis
-
-TESTS ?= %
-IMAGES ?= %
-
-# Make archive from git repo $1 to tar.gz $2
-make-archive-maybe = $(if $(wildcard $1/*), \
-       $(call quiet-command, \
-               (cd $1; if git diff-index --quiet HEAD -- &>/dev/null; then \
-                       git archive -1 HEAD --format=tar.gz; \
-               else \
-                       git archive -1 $$(git stash create) --format=tar.gz; \
-               fi) > $2, \
-               "  ARCHIVE $(notdir $2)"))
-
-CUR_TIME := $(shell date +%Y-%m-%d-%H.%M.%S.$$$$)
-DOCKER_SRC_COPY := docker-src.$(CUR_TIME)
-
-$(DOCKER_SRC_COPY):
-       @mkdir $@
-       $(call make-archive-maybe, $(SRC_PATH), $@/qemu.tgz)
-       $(call make-archive-maybe, $(SRC_PATH)/dtc, $@/dtc.tgz)
-       $(call make-archive-maybe, $(SRC_PATH)/pixman, $@/pixman.tgz)
-       $(call quiet-command, cp $(SRC_PATH)/tests/docker/run $@/run, \
-               "  COPY RUNNER")
-
-docker-qemu-src: $(DOCKER_SRC_COPY)
-
-docker-image: ${DOCKER_TARGETS}
-
-# General rule for building docker images
-docker-image-%: $(DOCKER_FILES_DIR)/%.docker
-       $(call quiet-command,\
-               $(SRC_PATH)/tests/docker/docker.py build qemu:$* $< \
-               $(if $V,,--quiet) $(if $(NOCACHE),--no-cache) \
-               $(if $(EXECUTABLE),--include-executable=$(EXECUTABLE)),\
-               "  BUILD $*")
-
-# Expand all the pre-requistes for each docker image and test combination
-$(foreach i,$(DOCKER_IMAGES), \
-       $(foreach t,$(DOCKER_TESTS) $(DOCKER_TOOLS), \
-               $(eval .PHONY: docker-$t@$i) \
-               $(eval docker-$t@$i: docker-image-$i docker-run-$t@$i) \
-       ) \
-       $(foreach t,$(DOCKER_TESTS), \
-               $(eval docker-test: docker-$t@$i) \
-       ) \
-)
-
-docker:
-       @echo 'Build QEMU and run tests inside Docker containers'
-       @echo
-       @echo 'Available targets:'
-       @echo
-       @echo '    docker:              Print this help.'
-       @echo '    docker-test:         Run all image/test combinations.'
-       @echo '    docker-clean:        Kill and remove residual docker testing containers.'
-       @echo '    docker-TEST@IMAGE:   Run "TEST" in container "IMAGE".'
-       @echo '                         Note: "TEST" is one of the listed test name,'
-       @echo '                         or a script name under $$QEMU_SRC/tests/docker/;'
-       @echo '                         "IMAGE" is one of the listed container name."'
-       @echo '    docker-image:        Build all images.'
-       @echo '    docker-image-IMAGE:  Build image "IMAGE".'
-       @echo
-       @echo 'Available container images:'
-       @echo '    $(DOCKER_IMAGES)'
-       @echo
-       @echo 'Available tests:'
-       @echo '    $(DOCKER_TESTS)'
-       @echo
-       @echo 'Available tools:'
-       @echo '    $(DOCKER_TOOLS)'
-       @echo
-       @echo 'Special variables:'
-       @echo '    TARGET_LIST=a,b,c    Override target list in builds.'
-       @echo '    EXTRA_CONFIGURE_OPTS="..."'
-       @echo '                         Extra configure options.'
-       @echo '    IMAGES="a b c ..":   Filters which images to build or run.'
-       @echo '    TESTS="x y z .."     Filters which tests to run (for docker-test).'
-       @echo '    J=[0..9]*            Overrides the -jN parameter for make commands'
-       @echo '                         (default is 1)'
-       @echo '    DEBUG=1              Stop and drop to shell in the created container'
-       @echo '                         before running the command.'
-       @echo '    NOCACHE=1            Ignore cache when build images.'
-       @echo '    EXECUTABLE=<path>    Include executable in image.'
-
-docker-run-%: CMD = $(shell echo '$@' | sed -e 's/docker-run-\([^@]*\)@\(.*\)/\1/')
-docker-run-%: IMAGE = $(shell echo '$@' | sed -e 's/docker-run-\([^@]*\)@\(.*\)/\2/')
-docker-run-%: docker-qemu-src
-       @mkdir -p "$(DOCKER_CCACHE_DIR)"
-       @if test -z "$(IMAGE)" || test -z "$(CMD)"; \
-               then echo "Invalid target"; exit 1; \
-       fi
-       $(if $(filter $(TESTS),$(CMD)),$(if $(filter $(IMAGES),$(IMAGE)), \
-               $(call quiet-command,\
-                       if $(SRC_PATH)/tests/docker/docker.py images | \
-                               awk '$$1=="qemu" && $$2=="$(IMAGE)"{found=1} END{exit(!found)}'; then \
-                               $(SRC_PATH)/tests/docker/docker.py run $(if $V,,--rm) \
-                               -t \
-                               $(if $(DEBUG),-i,--net=none) \
-                               -e TARGET_LIST=$(TARGET_LIST) \
-                               -e EXTRA_CONFIGURE_OPTS=$(EXTRA_CONFIGURE_OPTS) \
-                               -e V=$V -e J=$J -e DEBUG=$(DEBUG)\
-                               -e CCACHE_DIR=/var/tmp/ccache \
-                               -v $$(realpath $(DOCKER_SRC_COPY)):/var/tmp/qemu:z$(COMMA)ro \
-                               -v $(DOCKER_CCACHE_DIR):/var/tmp/ccache:z \
-                               qemu:$(IMAGE) \
-                               /var/tmp/qemu/run \
-                               $(CMD); \
-                       fi \
-                       , "  RUN $(CMD) in $(IMAGE)")))
-
-docker-clean:
-       $(call quiet-command, $(SRC_PATH)/tests/docker/docker.py clean)
diff --git a/tests/docker/common.rc b/tests/docker/common.rc
deleted file mode 100755 (executable)
index 0c6d8d5..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-#
-# Common routines for docker test scripts.
-#
-# Copyright (c) 2016 Red Hat Inc.
-#
-# Authors:
-#  Fam Zheng <famz@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2
-# or (at your option) any later version. See the COPYING file in
-# the top-level directory.
-
-requires()
-{
-    for c in $@; do
-        if ! echo "$FEATURES" | grep -wq -e "$c"; then
-            echo "Prerequisite '$c' not present, skip"
-            exit 0
-        fi
-    done
-}
-
-build_qemu()
-{
-    $QEMU_SRC/configure \
-        --enable-werror \
-        ${TARGET_LIST:+"--target-list=${TARGET_LIST}"} \
-        --prefix="$PWD/install" \
-        $EXTRA_CONFIGURE_OPTS \
-        "$@"
-    make $MAKEFLAGS
-}
diff --git a/tests/docker/docker.py b/tests/docker/docker.py
deleted file mode 100755 (executable)
index 222a105..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
-#!/usr/bin/env python2
-#
-# Docker controlling module
-#
-# Copyright (c) 2016 Red Hat Inc.
-#
-# Authors:
-#  Fam Zheng <famz@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2
-# or (at your option) any later version. See the COPYING file in
-# the top-level directory.
-
-import os
-import sys
-import subprocess
-import json
-import hashlib
-import atexit
-import uuid
-import argparse
-import tempfile
-import re
-from tarfile import TarFile, TarInfo
-from StringIO import StringIO
-from shutil import copy, rmtree
-
-def _text_checksum(text):
-    """Calculate a digest string unique to the text content"""
-    return hashlib.sha1(text).hexdigest()
-
-def _guess_docker_command():
-    """ Guess a working docker command or raise exception if not found"""
-    commands = [["docker"], ["sudo", "-n", "docker"]]
-    for cmd in commands:
-        if subprocess.call(cmd + ["images"],
-                           stdout=subprocess.PIPE,
-                           stderr=subprocess.PIPE) == 0:
-            return cmd
-    commands_txt = "\n".join(["  " + " ".join(x) for x in commands])
-    raise Exception("Cannot find working docker command. Tried:\n%s" % \
-                    commands_txt)
-
-def _copy_with_mkdir(src, root_dir, sub_path):
-    """Copy src into root_dir, creating sub_path as needed."""
-    dest_dir = os.path.normpath("%s/%s" % (root_dir, sub_path))
-    try:
-        os.makedirs(dest_dir)
-    except OSError:
-        # we can safely ignore already created directories
-        pass
-
-    dest_file = "%s/%s" % (dest_dir, os.path.basename(src))
-    copy(src, dest_file)
-
-
-def _get_so_libs(executable):
-    """Return a list of libraries associated with an executable.
-
-    The paths may be symbolic links which would need to be resolved to
-    ensure theright data is copied."""
-
-    libs = []
-    ldd_re = re.compile(r"(/.*/)(\S*)")
-    try:
-        ldd_output = subprocess.check_output(["ldd", executable])
-        for line in ldd_output.split("\n"):
-            search = ldd_re.search(line)
-            if search and len(search.groups()) == 2:
-                so_path = search.groups()[0]
-                so_lib = search.groups()[1]
-                libs.append("%s/%s" % (so_path, so_lib))
-    except subprocess.CalledProcessError:
-        print "%s had no associated libraries (static build?)" % (executable)
-
-    return libs
-
-def _copy_binary_with_libs(src, dest_dir):
-    """Copy a binary executable and all its dependant libraries.
-
-    This does rely on the host file-system being fairly multi-arch
-    aware so the file don't clash with the guests layout."""
-
-    _copy_with_mkdir(src, dest_dir, "/usr/bin")
-
-    libs = _get_so_libs(src)
-    if libs:
-        for l in libs:
-            so_path = os.path.dirname(l)
-            _copy_with_mkdir(l , dest_dir, so_path)
-
-class Docker(object):
-    """ Running Docker commands """
-    def __init__(self):
-        self._command = _guess_docker_command()
-        self._instances = []
-        atexit.register(self._kill_instances)
-
-    def _do(self, cmd, quiet=True, infile=None, **kwargs):
-        if quiet:
-            kwargs["stdout"] = subprocess.PIPE
-        if infile:
-            kwargs["stdin"] = infile
-        return subprocess.call(self._command + cmd, **kwargs)
-
-    def _do_kill_instances(self, only_known, only_active=True):
-        cmd = ["ps", "-q"]
-        if not only_active:
-            cmd.append("-a")
-        for i in self._output(cmd).split():
-            resp = self._output(["inspect", i])
-            labels = json.loads(resp)[0]["Config"]["Labels"]
-            active = json.loads(resp)[0]["State"]["Running"]
-            if not labels:
-                continue
-            instance_uuid = labels.get("com.qemu.instance.uuid", None)
-            if not instance_uuid:
-                continue
-            if only_known and instance_uuid not in self._instances:
-                continue
-            print "Terminating", i
-            if active:
-                self._do(["kill", i])
-            self._do(["rm", i])
-
-    def clean(self):
-        self._do_kill_instances(False, False)
-        return 0
-
-    def _kill_instances(self):
-        return self._do_kill_instances(True)
-
-    def _output(self, cmd, **kwargs):
-        return subprocess.check_output(self._command + cmd,
-                                       stderr=subprocess.STDOUT,
-                                       **kwargs)
-
-    def get_image_dockerfile_checksum(self, tag):
-        resp = self._output(["inspect", tag])
-        labels = json.loads(resp)[0]["Config"].get("Labels", {})
-        return labels.get("com.qemu.dockerfile-checksum", "")
-
-    def build_image(self, tag, docker_dir, dockerfile, quiet=True, argv=None):
-        if argv == None:
-            argv = []
-
-        tmp_df = tempfile.NamedTemporaryFile(dir=docker_dir, suffix=".docker")
-        tmp_df.write(dockerfile)
-
-        tmp_df.write("\n")
-        tmp_df.write("LABEL com.qemu.dockerfile-checksum=%s" %
-                     _text_checksum(dockerfile))
-        tmp_df.flush()
-
-        self._do(["build", "-t", tag, "-f", tmp_df.name] + argv + \
-                 [docker_dir],
-                 quiet=quiet)
-
-    def update_image(self, tag, tarball, quiet=True):
-        "Update a tagged image using "
-
-        self._do(["build", "-t", tag, "-"], quiet=quiet, infile=tarball)
-
-    def image_matches_dockerfile(self, tag, dockerfile):
-        try:
-            checksum = self.get_image_dockerfile_checksum(tag)
-        except Exception:
-            return False
-        return checksum == _text_checksum(dockerfile)
-
-    def run(self, cmd, keep, quiet):
-        label = uuid.uuid1().hex
-        if not keep:
-            self._instances.append(label)
-        ret = self._do(["run", "--label",
-                        "com.qemu.instance.uuid=" + label] + cmd,
-                       quiet=quiet)
-        if not keep:
-            self._instances.remove(label)
-        return ret
-
-    def command(self, cmd, argv, quiet):
-        return self._do([cmd] + argv, quiet=quiet)
-
-class SubCommand(object):
-    """A SubCommand template base class"""
-    name = None # Subcommand name
-    def shared_args(self, parser):
-        parser.add_argument("--quiet", action="store_true",
-                            help="Run quietly unless an error occured")
-
-    def args(self, parser):
-        """Setup argument parser"""
-        pass
-    def run(self, args, argv):
-        """Run command.
-        args: parsed argument by argument parser.
-        argv: remaining arguments from sys.argv.
-        """
-        pass
-
-class RunCommand(SubCommand):
-    """Invoke docker run and take care of cleaning up"""
-    name = "run"
-    def args(self, parser):
-        parser.add_argument("--keep", action="store_true",
-                            help="Don't remove image when command completes")
-    def run(self, args, argv):
-        return Docker().run(argv, args.keep, quiet=args.quiet)
-
-class BuildCommand(SubCommand):
-    """ Build docker image out of a dockerfile. Arguments: <tag> <dockerfile>"""
-    name = "build"
-    def args(self, parser):
-        parser.add_argument("--include-executable", "-e",
-                            help="""Specify a binary that will be copied to the
-                            container together with all its dependent
-                            libraries""")
-        parser.add_argument("tag",
-                            help="Image Tag")
-        parser.add_argument("dockerfile",
-                            help="Dockerfile name")
-
-    def run(self, args, argv):
-        dockerfile = open(args.dockerfile, "rb").read()
-        tag = args.tag
-
-        dkr = Docker()
-        if dkr.image_matches_dockerfile(tag, dockerfile):
-            if not args.quiet:
-                print "Image is up to date."
-        else:
-            # Create a docker context directory for the build
-            docker_dir = tempfile.mkdtemp(prefix="docker_build")
-
-            # Is there a .pre file to run in the build context?
-            docker_pre = os.path.splitext(args.dockerfile)[0]+".pre"
-            if os.path.exists(docker_pre):
-                rc = subprocess.call(os.path.realpath(docker_pre),
-                                     cwd=docker_dir)
-                if rc == 3:
-                    print "Skip"
-                    return 0
-                elif rc != 0:
-                    print "%s exited with code %d" % (docker_pre, rc)
-                    return 1
-
-            # Do we include a extra binary?
-            if args.include_executable:
-                _copy_binary_with_libs(args.include_executable,
-                                       docker_dir)
-
-            dkr.build_image(tag, docker_dir, dockerfile,
-                            quiet=args.quiet, argv=argv)
-
-            rmtree(docker_dir)
-
-        return 0
-
-class UpdateCommand(SubCommand):
-    """ Update a docker image with new executables. Arguments: <tag> <executable>"""
-    name = "update"
-    def args(self, parser):
-        parser.add_argument("tag",
-                            help="Image Tag")
-        parser.add_argument("executable",
-                            help="Executable to copy")
-
-    def run(self, args, argv):
-        # Create a temporary tarball with our whole build context and
-        # dockerfile for the update
-        tmp = tempfile.NamedTemporaryFile(suffix="dckr.tar.gz")
-        tmp_tar = TarFile(fileobj=tmp, mode='w')
-
-        # Add the executable to the tarball
-        bn = os.path.basename(args.executable)
-        ff = "/usr/bin/%s" % bn
-        tmp_tar.add(args.executable, arcname=ff)
-
-        # Add any associated libraries
-        libs = _get_so_libs(args.executable)
-        if libs:
-            for l in libs:
-                tmp_tar.add(os.path.realpath(l), arcname=l)
-
-        # Create a Docker buildfile
-        df = StringIO()
-        df.write("FROM %s\n" % args.tag)
-        df.write("ADD . /\n")
-        df.seek(0)
-
-        df_tar = TarInfo(name="Dockerfile")
-        df_tar.size = len(df.buf)
-        tmp_tar.addfile(df_tar, fileobj=df)
-
-        tmp_tar.close()
-
-        # reset the file pointers
-        tmp.flush()
-        tmp.seek(0)
-
-        # Run the build with our tarball context
-        dkr = Docker()
-        dkr.update_image(args.tag, tmp, quiet=args.quiet)
-
-        return 0
-
-class CleanCommand(SubCommand):
-    """Clean up docker instances"""
-    name = "clean"
-    def run(self, args, argv):
-        Docker().clean()
-        return 0
-
-class ImagesCommand(SubCommand):
-    """Run "docker images" command"""
-    name = "images"
-    def run(self, args, argv):
-        return Docker().command("images", argv, args.quiet)
-
-def main():
-    parser = argparse.ArgumentParser(description="A Docker helper",
-            usage="%s <subcommand> ..." % os.path.basename(sys.argv[0]))
-    subparsers = parser.add_subparsers(title="subcommands", help=None)
-    for cls in SubCommand.__subclasses__():
-        cmd = cls()
-        subp = subparsers.add_parser(cmd.name, help=cmd.__doc__)
-        cmd.shared_args(subp)
-        cmd.args(subp)
-        subp.set_defaults(cmdobj=cmd)
-    args, argv = parser.parse_known_args()
-    return args.cmdobj.run(args, argv)
-
-if __name__ == "__main__":
-    sys.exit(main())
diff --git a/tests/docker/dockerfiles/centos6.docker b/tests/docker/dockerfiles/centos6.docker
deleted file mode 100644 (file)
index 8f4fe46..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-FROM centos:6
-RUN yum install -y \
-    tar git make gcc g++ \
-    zlib-devel glib2-devel SDL-devel pixman-devel \
-    epel-release
-RUN yum install -y libfdt-devel ccache
diff --git a/tests/docker/dockerfiles/debian-bootstrap.docker b/tests/docker/dockerfiles/debian-bootstrap.docker
deleted file mode 100644 (file)
index 3a9125e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# Create Debian Bootstrap Image
-#
-# This is intended to be pre-poluated by:
-#  - a first stage debootstrap (see debian-bootstrap.pre)
-#  - a native qemu-$arch that binfmt_misc will run
-FROM scratch
-
-# Add everything from the context into the container
-ADD . /
-
-# Patch all mounts as docker already has stuff set up
-RUN sed -i 's/in_target mount/echo not for docker in_target mount/g' /debootstrap/functions
-
-# Run stage 2
-RUN /debootstrap/debootstrap --second-stage
-
-# At this point we can install additional packages if we want
-# Duplicate deb line as deb-src
-RUN cat /etc/apt/sources.list | sed "s/deb/deb-src/" >> /etc/apt/sources.list
-RUN apt-get update
-RUN apt-get -y build-dep qemu
diff --git a/tests/docker/dockerfiles/debian-bootstrap.pre b/tests/docker/dockerfiles/debian-bootstrap.pre
deleted file mode 100755 (executable)
index 5d9c8d5..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/bin/sh
-#
-# Simple wrapper for debootstrap, run in the docker build context
-#
-FAKEROOT=`which fakeroot 2> /dev/null`
-
-exit_and_skip()
-{
-    exit 3
-}
-
-#
-# fakeroot is needed to run the bootstrap stage
-#
-if [ -z $FAKEROOT ]; then
-    echo "Please install fakeroot to enable bootstraping"
-    exit_and_skip
-fi
-
-# We check in order for
-#
-#  - DEBOOTSTRAP_DIR pointing at a development checkout
-#  - PATH for the debootstrap script (installed)
-#
-# If neither option works then we checkout debootstrap from its
-# upstream SCM and run it from there.
-#
-
-if [ -z $DEBOOTSTRAP_DIR ]; then
-    DEBOOTSTRAP=`which debootstrap 2> /dev/null`
-    if [ -z $DEBOOTSTRAP ]; then
-        echo "No debootstrap installed, attempting to install from SCM"
-        DEBOOTSTRAP_SOURCE=https://anonscm.debian.org/git/d-i/debootstrap.git
-        git clone ${DEBOOTSTRAP_SOURCE} ./debootstrap.git
-        export DEBOOTSTRAP_DIR=./debootstrap.git
-        DEBOOTSTRAP=./debootstrap.git/debootstrap
-    fi
-else
-    DEBOOTSTRAP=${DEBOOTSTRAP_DIR}/debootstrap
-    if [ ! -f $DEBOOTSTRAP ]; then
-        echo "Couldn't find script at ${DEBOOTSTRAP}"
-        exit_and_skip
-    fi
-fi
-
-#
-# Finally check to see if any qemu's are installed
-#
-BINFMT_DIR=/proc/sys/fs/binfmt_misc
-if [ ! -e $BINFMT_DIR ]; then
-   echo "binfmt_misc needs enabling for a QEMU bootstrap to work"
-   exit_and_skip
-else
-    # DEB_ARCH and QEMU arch names are not totally aligned
-    case "${DEB_ARCH}" in
-        amd64)
-            QEMU=qemu-i386
-            ;;
-        armel|armhf)
-            QEMU=qemu-arm
-            ;;
-        arm64)
-            QEMU=qemu-aarch64
-            ;;
-        powerpc)
-            QEMU=qemu-ppc
-            ;;
-        ppc64el)
-            QEMU=qemu-ppc64le
-            ;;
-        s390)
-            QEMU=qemu-s390x
-            ;;
-        *)
-            QEMU=qemu-${DEB_ARCH}
-        ;;
-    esac
-    if [ ! -e "${BINFMT_DIR}/$QEMU" ]; then
-        echo "No binfmt_misc rule to run $QEMU, can't bootstrap"
-        exit_and_skip
-    fi
-fi
-
-echo "Building a rootfs using ${FAKEROOT} and ${DEBOOTSTRAP} ${DEB_ARCH}/${DEB_TYPE}"
-
-${FAKEROOT} ${DEBOOTSTRAP} --variant=buildd --foreign --arch=$DEB_ARCH $DEB_TYPE . http://httpredir.debian.org/debian || exit 1
-exit 0
diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker
deleted file mode 100644 (file)
index 1d26a8e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-FROM fedora:23
-RUN dnf install -y \
-    ccache git tar PyYAML sparse flex bison \
-    glib2-devel pixman-devel zlib-devel SDL-devel libfdt-devel \
-    gcc gcc-c++ clang make perl which bc findutils \
-    mingw{32,64}-{pixman,glib2,gmp,SDL,pkg-config,gtk2,gtk3,gnutls,nettle,libtasn1,libjpeg-turbo,libpng,curl,libssh2,bzip2}
-ENV FEATURES mingw clang pyyaml
diff --git a/tests/docker/dockerfiles/ubuntu.docker b/tests/docker/dockerfiles/ubuntu.docker
deleted file mode 100644 (file)
index a8b88c3..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-FROM ubuntu:14.04
-RUN echo "deb http://archive.ubuntu.com/ubuntu/ trusty universe multiverse" >> \
-    /etc/apt/sources.list
-RUN apt-get update
-RUN apt-get -y install flex bison \
-    libusb-1.0-0-dev libiscsi-dev librados-dev libncurses5-dev \
-    libseccomp-dev libgnutls-dev libssh2-1-dev  libspice-server-dev \
-    libspice-protocol-dev libnss3-dev libfdt-dev \
-    libgtk-3-dev libvte-2.90-dev libsdl1.2-dev libpng12-dev libpixman-1-dev \
-    git make ccache python-yaml gcc clang sparse
-ENV FEATURES clang pyyaml
diff --git a/tests/docker/run b/tests/docker/run
deleted file mode 100755 (executable)
index d85d49a..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/bin/bash -e
-#
-# Docker test runner
-#
-# Copyright (c) 2016 Red Hat Inc.
-#
-# Authors:
-#  Fam Zheng <famz@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2
-# or (at your option) any later version. See the COPYING file in
-# the top-level directory.
-
-set -e
-
-if test -n "$V"; then
-    set -x
-fi
-
-BASE="$(dirname $(readlink -e $0))"
-
-# Prepare the environment
-. /etc/profile || true
-export PATH=/usr/lib/ccache:$PATH
-
-if test -n "$J"; then
-    export MAKEFLAGS="$MAKEFLAGS -j$J"
-fi
-
-# We are in the container so the whole file system belong to us
-export TEST_DIR=/tmp/qemu-test
-mkdir -p $TEST_DIR/{src,build,install}
-
-# Extract the source tarballs
-tar -C $TEST_DIR/src -xzf $BASE/qemu.tgz
-for p in dtc pixman; do
-    if test -f $BASE/$p.tgz; then
-        tar -C $TEST_DIR/src/$p -xzf $BASE/$p.tgz
-        export FEATURES="$FEATURES $p"
-    fi
-done
-
-export QEMU_SRC="$TEST_DIR/src"
-
-cd "$QEMU_SRC/tests/docker"
-
-CMD="$QEMU_SRC/tests/docker/$@"
-
-if test -n "$DEBUG"; then
-    echo "* Prepared to run command:"
-    echo "  $CMD"
-    echo "* Hit Ctrl-D to continue, or type 'exit 1' to abort"
-    echo
-    $SHELL
-fi
-
-if "$CMD"; then
-    exit 0
-elif test -n "$DEBUG"; then
-    echo "* Command failed:"
-    echo "  $CMD"
-    echo "* Hit Ctrl-D to exit"
-    echo
-    # Force error after shell exits
-    $SHELL && exit 1
-else
-    exit 1
-fi
diff --git a/tests/docker/test-clang b/tests/docker/test-clang
deleted file mode 100755 (executable)
index 60e4e97..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash -e
-#
-# Compile and check with clang.
-#
-# Copyright (c) 2016 Red Hat Inc.
-#
-# Authors:
-#  Fam Zheng <famz@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2
-# or (at your option) any later version. See the COPYING file in
-# the top-level directory.
-
-. common.rc
-
-requires clang
-
-OPTS="--enable-debug --cxx=clang++ --cc=clang --host-cc=clang"
-# -fsanitize=undefined is broken on Fedora 23, skip it for now
-# See also: https://bugzilla.redhat.com/show_bug.cgi?id=1263834
-#OPTS="$OPTS --extra-cflags=-fsanitize=undefined \
-    #--extra-cflags=-fno-sanitize=float-divide-by-zero"
-build_qemu $OPTS
-make $MAKEFLAGS check
diff --git a/tests/docker/test-full b/tests/docker/test-full
deleted file mode 100755 (executable)
index fd9b798..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash -e
-#
-# Compile all the targets.
-#
-# Copyright (c) 2016 Red Hat Inc.
-#
-# Authors:
-#  Fam Zheng <famz@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2
-# or (at your option) any later version. See the COPYING file in
-# the top-level directory.
-
-. common.rc
-
-build_qemu
-make check $MAKEFLAGS
diff --git a/tests/docker/test-mingw b/tests/docker/test-mingw
deleted file mode 100755 (executable)
index c03757a..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash -e
-#
-# Cross compile QEMU with mingw toolchain on Linux.
-#
-# Copyright (c) 2016 Red Hat Inc.
-#
-# Authors:
-#  Fam Zheng <famz@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2
-# or (at your option) any later version. See the COPYING file in
-# the top-level directory.
-
-. common.rc
-
-requires mingw dtc
-
-for prefix in x86_64-w64-mingw32- i686-w64-mingw32-; do
-    TARGET_LIST=x86_64-softmmu,aarch64-softmmu \
-        build_qemu --cross-prefix=$prefix \
-        --enable-trace-backends=simple \
-        --enable-debug \
-        --enable-gnutls \
-        --enable-nettle \
-        --enable-curl \
-        --enable-vnc \
-        --enable-bzip2 \
-        --enable-guest-agent \
-        --with-sdlabi=1.2 \
-        --with-gtkabi=2.0
-    make clean
-
-done
-
diff --git a/tests/docker/test-quick b/tests/docker/test-quick
deleted file mode 100755 (executable)
index 07cdc59..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash -e
-#
-# Quick compiling test that everyone already does. But why not automate it?
-#
-# Copyright (c) 2016 Red Hat Inc.
-#
-# Authors:
-#  Fam Zheng <famz@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2
-# or (at your option) any later version. See the COPYING file in
-# the top-level directory.
-
-. common.rc
-
-DEF_TARGET_LIST="$(echo {x86_64,aarch64}-softmmu)"
-TARGET_LIST=${TARGET_LIST:-$DEF_TARGET_LIST} \
-build_qemu
-make check $MAKEFLAGS
diff --git a/tests/docker/travis b/tests/docker/travis
deleted file mode 100755 (executable)
index d345393..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash -e
-#
-# Mimic a travis testing matrix
-#
-# Copyright (c) 2016 Red Hat Inc.
-#
-# Authors:
-#  Fam Zheng <famz@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2
-# or (at your option) any later version. See the COPYING file in
-# the top-level directory.
-
-. common.rc
-
-requires pyyaml
-cmdfile=/tmp/travis_cmd_list.sh
-$QEMU_SRC/tests/docker/travis.py $QEMU_SRC/.travis.yml > $cmdfile
-chmod +x $cmdfile
-cd "$QEMU_SRC"
-$cmdfile
diff --git a/tests/docker/travis.py b/tests/docker/travis.py
deleted file mode 100755 (executable)
index 8dcc964..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python
-#
-# Travis YAML config parser
-#
-# Copyright (c) 2016 Red Hat Inc.
-#
-# Authors:
-#  Fam Zheng <famz@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2
-# or (at your option) any later version. See the COPYING file in
-# the top-level directory.
-
-import sys
-import yaml
-import itertools
-
-def load_yaml(fname):
-    return yaml.load(open(fname, "r").read())
-
-def conf_iter(conf):
-    def env_to_list(env):
-        return env if isinstance(env, list) else [env]
-    global_env = conf["env"]["global"]
-    for entry in conf["matrix"]["include"]:
-        yield {"env": global_env + env_to_list(entry["env"]),
-               "compiler": entry["compiler"]}
-    for entry in itertools.product(conf["compiler"],
-                                   conf["env"]["matrix"]):
-        yield {"env": global_env + env_to_list(entry[1]),
-               "compiler": entry[0]}
-
-def main():
-    if len(sys.argv) < 2:
-        sys.stderr.write("Usage: %s <travis-file>\n" % sys.argv[0])
-        return 1
-    conf = load_yaml(sys.argv[1])
-    for config in conf_iter(conf):
-        print "("
-        print "\n".join(config["env"])
-        print "alias cc=" + config["compiler"]
-        print "\n".join(conf["before_script"])
-        print "\n".join(conf["script"])
-        print ")"
-    return 0
-
-if __name__ == "__main__":
-    sys.exit(main())
index 121b9c9..fe03236 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 static void drive_add(void)
@@ -115,8 +116,7 @@ int main(int argc, char **argv)
     qtest_add_func("/drive_del/without-dev", test_drive_without_dev);
 
     /* TODO I guess any arch with PCI would do */
-    if (!strcmp(arch, "i386") || !strcmp(arch, "x86_64") ||
-        !strcmp(arch, "ppc") || !strcmp(arch, "ppc64")) {
+    if (!strcmp(arch, "i386") || !strcmp(arch, "x86_64")) {
         qtest_add_func("/drive_del/after_failed_device_add",
                        test_after_failed_device_add);
         qtest_add_func("/blockdev/drive_del_device_del",
index 26968bc..2792415 100644 (file)
@@ -21,6 +21,8 @@
 #include "libqtest.h"
 #include "libqos/i2c.h"
 
+#include <glib.h>
+
 #define IMX25_I2C_0_BASE 0x43F80000
 
 #define DS1338_ADDR 0x68
index 59cab68..a42b381 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
diff --git a/tests/e1000e-test.c b/tests/e1000e-test.c
deleted file mode 100644 (file)
index d497b08..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
- /*
- * QTest testcase for e1000e NIC
- *
- * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
- * Developed by Daynix Computing LTD (http://www.daynix.com)
- *
- * Authors:
- * Dmitry Fleytman <dmitry@daynix.com>
- * Leonid Bloch <leonid@daynix.com>
- * Yan Vugenfirer <yan@daynix.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "qemu/osdep.h"
-#include "libqtest.h"
-#include "qemu-common.h"
-#include "libqos/pci-pc.h"
-#include "qemu/sockets.h"
-#include "qemu/iov.h"
-#include "qemu/bitops.h"
-#include "libqos/malloc.h"
-#include "libqos/malloc-pc.h"
-#include "libqos/malloc-generic.h"
-
-#define E1000E_IMS      (0x00d0)
-
-#define E1000E_STATUS   (0x0008)
-#define E1000E_STATUS_LU BIT(1)
-#define E1000E_STATUS_ASDV1000 BIT(9)
-
-#define E1000E_CTRL     (0x0000)
-#define E1000E_CTRL_RESET BIT(26)
-
-#define E1000E_RCTL     (0x0100)
-#define E1000E_RCTL_EN  BIT(1)
-#define E1000E_RCTL_UPE BIT(3)
-#define E1000E_RCTL_MPE BIT(4)
-
-#define E1000E_RFCTL     (0x5008)
-#define E1000E_RFCTL_EXTEN  BIT(15)
-
-#define E1000E_TCTL     (0x0400)
-#define E1000E_TCTL_EN  BIT(1)
-
-#define E1000E_CTRL_EXT             (0x0018)
-#define E1000E_CTRL_EXT_DRV_LOAD    BIT(28)
-#define E1000E_CTRL_EXT_TXLSFLOW    BIT(22)
-
-#define E1000E_RX0_MSG_ID           (0)
-#define E1000E_TX0_MSG_ID           (1)
-#define E1000E_OTHER_MSG_ID         (2)
-
-#define E1000E_IVAR                 (0x00E4)
-#define E1000E_IVAR_TEST_CFG        ((E1000E_RX0_MSG_ID << 0)    | BIT(3)  | \
-                                     (E1000E_TX0_MSG_ID << 8)    | BIT(11) | \
-                                     (E1000E_OTHER_MSG_ID << 16) | BIT(19) | \
-                                     BIT(31))
-
-#define E1000E_RING_LEN             (0x1000)
-#define E1000E_TXD_LEN              (16)
-#define E1000E_RXD_LEN              (16)
-
-#define E1000E_TDBAL    (0x3800)
-#define E1000E_TDBAH    (0x3804)
-#define E1000E_TDLEN    (0x3808)
-#define E1000E_TDH      (0x3810)
-#define E1000E_TDT      (0x3818)
-
-#define E1000E_RDBAL    (0x2800)
-#define E1000E_RDBAH    (0x2804)
-#define E1000E_RDLEN    (0x2808)
-#define E1000E_RDH      (0x2810)
-#define E1000E_RDT      (0x2818)
-
-typedef struct e1000e_device {
-    QPCIDevice *pci_dev;
-    void *mac_regs;
-
-    uint64_t tx_ring;
-    uint64_t rx_ring;
-} e1000e_device;
-
-static int test_sockets[2];
-static QGuestAllocator *test_alloc;
-static QPCIBus *test_bus;
-
-static void e1000e_pci_foreach_callback(QPCIDevice *dev, int devfn, void *data)
-{
-    *(QPCIDevice **) data = dev;
-}
-
-static QPCIDevice *e1000e_device_find(QPCIBus *bus)
-{
-    static const int e1000e_vendor_id = 0x8086;
-    static const int e1000e_dev_id = 0x10D3;
-
-    QPCIDevice *e1000e_dev = NULL;
-
-    qpci_device_foreach(bus, e1000e_vendor_id, e1000e_dev_id,
-        e1000e_pci_foreach_callback, &e1000e_dev);
-
-    g_assert_nonnull(e1000e_dev);
-
-    return e1000e_dev;
-}
-
-static void e1000e_macreg_write(e1000e_device *d, uint32_t reg, uint32_t val)
-{
-    qpci_io_writel(d->pci_dev, d->mac_regs + reg, val);
-}
-
-static uint32_t e1000e_macreg_read(e1000e_device *d, uint32_t reg)
-{
-    return qpci_io_readl(d->pci_dev, d->mac_regs + reg);
-}
-
-static void e1000e_device_init(QPCIBus *bus, e1000e_device *d)
-{
-    uint32_t val;
-
-    d->pci_dev = e1000e_device_find(bus);
-
-    /* Enable the device */
-    qpci_device_enable(d->pci_dev);
-
-    /* Map BAR0 (mac registers) */
-    d->mac_regs = qpci_iomap(d->pci_dev, 0, NULL);
-    g_assert_nonnull(d->mac_regs);
-
-    /* Reset the device */
-    val = e1000e_macreg_read(d, E1000E_CTRL);
-    e1000e_macreg_write(d, E1000E_CTRL, val | E1000E_CTRL_RESET);
-
-    /* Enable and configure MSI-X */
-    qpci_msix_enable(d->pci_dev);
-    e1000e_macreg_write(d, E1000E_IVAR, E1000E_IVAR_TEST_CFG);
-
-    /* Check the device status - link and speed */
-    val = e1000e_macreg_read(d, E1000E_STATUS);
-    g_assert_cmphex(val & (E1000E_STATUS_LU | E1000E_STATUS_ASDV1000),
-        ==, E1000E_STATUS_LU | E1000E_STATUS_ASDV1000);
-
-    /* Initialize TX/RX logic */
-    e1000e_macreg_write(d, E1000E_RCTL, 0);
-    e1000e_macreg_write(d, E1000E_TCTL, 0);
-
-    /* Notify the device that the driver is ready */
-    val = e1000e_macreg_read(d, E1000E_CTRL_EXT);
-    e1000e_macreg_write(d, E1000E_CTRL_EXT,
-        val | E1000E_CTRL_EXT_DRV_LOAD | E1000E_CTRL_EXT_TXLSFLOW);
-
-    /* Allocate and setup TX ring */
-    d->tx_ring = guest_alloc(test_alloc, E1000E_RING_LEN);
-    g_assert(d->tx_ring != 0);
-
-    e1000e_macreg_write(d, E1000E_TDBAL, (uint32_t) d->tx_ring);
-    e1000e_macreg_write(d, E1000E_TDBAH, (uint32_t) (d->tx_ring >> 32));
-    e1000e_macreg_write(d, E1000E_TDLEN, E1000E_RING_LEN);
-    e1000e_macreg_write(d, E1000E_TDT, 0);
-    e1000e_macreg_write(d, E1000E_TDH, 0);
-
-    /* Enable transmit */
-    e1000e_macreg_write(d, E1000E_TCTL, E1000E_TCTL_EN);
-
-    /* Allocate and setup RX ring */
-    d->rx_ring = guest_alloc(test_alloc, E1000E_RING_LEN);
-    g_assert(d->rx_ring != 0);
-
-    e1000e_macreg_write(d, E1000E_RDBAL, (uint32_t)d->rx_ring);
-    e1000e_macreg_write(d, E1000E_RDBAH, (uint32_t)(d->rx_ring >> 32));
-    e1000e_macreg_write(d, E1000E_RDLEN, E1000E_RING_LEN);
-    e1000e_macreg_write(d, E1000E_RDT, 0);
-    e1000e_macreg_write(d, E1000E_RDH, 0);
-
-    /* Enable receive */
-    e1000e_macreg_write(d, E1000E_RFCTL, E1000E_RFCTL_EXTEN);
-    e1000e_macreg_write(d, E1000E_RCTL, E1000E_RCTL_EN  |
-                                        E1000E_RCTL_UPE |
-                                        E1000E_RCTL_MPE);
-
-    /* Enable all interrupts */
-    e1000e_macreg_write(d, E1000E_IMS, 0xFFFFFFFF);
-}
-
-static void e1000e_tx_ring_push(e1000e_device *d, void *descr)
-{
-    uint32_t tail = e1000e_macreg_read(d, E1000E_TDT);
-    uint32_t len = e1000e_macreg_read(d, E1000E_TDLEN) / E1000E_TXD_LEN;
-
-    memwrite(d->tx_ring + tail * E1000E_TXD_LEN, descr, E1000E_TXD_LEN);
-    e1000e_macreg_write(d, E1000E_TDT, (tail + 1) % len);
-
-    /* Read WB data for the packet transmitted */
-    memread(d->tx_ring + tail * E1000E_TXD_LEN, descr, E1000E_TXD_LEN);
-}
-
-static void e1000e_rx_ring_push(e1000e_device *d, void *descr)
-{
-    uint32_t tail = e1000e_macreg_read(d, E1000E_RDT);
-    uint32_t len = e1000e_macreg_read(d, E1000E_RDLEN) / E1000E_RXD_LEN;
-
-    memwrite(d->rx_ring + tail * E1000E_RXD_LEN, descr, E1000E_RXD_LEN);
-    e1000e_macreg_write(d, E1000E_RDT, (tail + 1) % len);
-
-    /* Read WB data for the packet received */
-    memread(d->rx_ring + tail * E1000E_RXD_LEN, descr, E1000E_RXD_LEN);
-}
-
-static void e1000e_wait_isr(e1000e_device *d, uint16_t msg_id)
-{
-    guint64 end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
-
-    do {
-        if (qpci_msix_pending(d->pci_dev, msg_id)) {
-            return;
-        }
-        clock_step(10000);
-    } while (g_get_monotonic_time() < end_time);
-
-    g_error("Timeout expired");
-}
-
-static void e1000e_send_verify(e1000e_device *d)
-{
-    struct {
-        uint64_t buffer_addr;
-        union {
-            uint32_t data;
-            struct {
-                uint16_t length;
-                uint8_t cso;
-                uint8_t cmd;
-            } flags;
-        } lower;
-        union {
-            uint32_t data;
-            struct {
-                uint8_t status;
-                uint8_t css;
-                uint16_t special;
-            } fields;
-        } upper;
-    } descr;
-
-    static const uint32_t dtyp_data = BIT(20);
-    static const uint32_t dtyp_ext  = BIT(29);
-    static const uint32_t dcmd_rs   = BIT(27);
-    static const uint32_t dcmd_eop  = BIT(24);
-    static const uint32_t dsta_dd   = BIT(0);
-    static const int data_len = 64;
-    char buffer[64];
-    int ret;
-    uint32_t recv_len;
-
-    /* Prepare test data buffer */
-    uint64_t data = guest_alloc(test_alloc, data_len);
-    memwrite(data, "TEST", 5);
-
-    /* Prepare TX descriptor */
-    memset(&descr, 0, sizeof(descr));
-    descr.buffer_addr = cpu_to_le64(data);
-    descr.lower.data = cpu_to_le32(dcmd_rs   |
-                                   dcmd_eop  |
-                                   dtyp_ext  |
-                                   dtyp_data |
-                                   data_len);
-
-    /* Put descriptor to the ring */
-    e1000e_tx_ring_push(d, &descr);
-
-    /* Wait for TX WB interrupt */
-    e1000e_wait_isr(d, E1000E_TX0_MSG_ID);
-
-    /* Check DD bit */
-    g_assert_cmphex(le32_to_cpu(descr.upper.data) & dsta_dd, ==, dsta_dd);
-
-    /* Check data sent to the backend */
-    ret = qemu_recv(test_sockets[0], &recv_len, sizeof(recv_len), 0);
-    g_assert_cmpint(ret, == , sizeof(recv_len));
-    qemu_recv(test_sockets[0], buffer, 64, 0);
-    g_assert_cmpstr(buffer, == , "TEST");
-
-    /* Free test data buffer */
-    guest_free(test_alloc, data);
-}
-
-static void e1000e_receive_verify(e1000e_device *d)
-{
-    union {
-        struct {
-            uint64_t buffer_addr;
-            uint64_t reserved;
-        } read;
-        struct {
-            struct {
-                uint32_t mrq;
-                union {
-                    uint32_t rss;
-                    struct {
-                        uint16_t ip_id;
-                        uint16_t csum;
-                    } csum_ip;
-                } hi_dword;
-            } lower;
-            struct {
-                uint32_t status_error;
-                uint16_t length;
-                uint16_t vlan;
-            } upper;
-        } wb;
-    } descr;
-
-    static const uint32_t esta_dd = BIT(0);
-
-    char test[] = "TEST";
-    int len = htonl(sizeof(test));
-    struct iovec iov[] = {
-        {
-            .iov_base = &len,
-            .iov_len = sizeof(len),
-        },{
-            .iov_base = test,
-            .iov_len = sizeof(test),
-        },
-    };
-
-    static const int data_len = 64;
-    char buffer[64];
-    int ret;
-
-    /* Send a dummy packet to device's socket*/
-    ret = iov_send(test_sockets[0], iov, 2, 0, sizeof(len) + sizeof(test));
-    g_assert_cmpint(ret, == , sizeof(test) + sizeof(len));
-
-    /* Prepare test data buffer */
-    uint64_t data = guest_alloc(test_alloc, data_len);
-
-    /* Prepare RX descriptor */
-    memset(&descr, 0, sizeof(descr));
-    descr.read.buffer_addr = cpu_to_le64(data);
-
-    /* Put descriptor to the ring */
-    e1000e_rx_ring_push(d, &descr);
-
-    /* Wait for TX WB interrupt */
-    e1000e_wait_isr(d, E1000E_RX0_MSG_ID);
-
-    /* Check DD bit */
-    g_assert_cmphex(le32_to_cpu(descr.wb.upper.status_error) &
-        esta_dd, ==, esta_dd);
-
-    /* Check data sent to the backend */
-    memread(data, buffer, sizeof(buffer));
-    g_assert_cmpstr(buffer, == , "TEST");
-
-    /* Free test data buffer */
-    guest_free(test_alloc, data);
-}
-
-static void e1000e_device_clear(QPCIBus *bus, e1000e_device *d)
-{
-    qpci_iounmap(d->pci_dev, d->mac_regs);
-    qpci_msix_disable(d->pci_dev);
-}
-
-static void data_test_init(e1000e_device *d)
-{
-    char *cmdline;
-
-    int ret = socketpair(PF_UNIX, SOCK_STREAM, 0, test_sockets);
-    g_assert_cmpint(ret, != , -1);
-
-    cmdline = g_strdup_printf("-netdev socket,fd=%d,id=hs0 "
-                              "-device e1000e,netdev=hs0", test_sockets[1]);
-    g_assert_nonnull(cmdline);
-
-    qtest_start(cmdline);
-    g_free(cmdline);
-
-    test_bus = qpci_init_pc();
-    g_assert_nonnull(test_bus);
-
-    test_alloc = pc_alloc_init();
-    g_assert_nonnull(test_alloc);
-
-    e1000e_device_init(test_bus, d);
-}
-
-static void data_test_clear(e1000e_device *d)
-{
-    e1000e_device_clear(test_bus, d);
-    close(test_sockets[0]);
-    pc_alloc_uninit(test_alloc);
-    qpci_free_pc(test_bus);
-    qtest_end();
-}
-
-static void test_e1000e_init(gconstpointer data)
-{
-    e1000e_device d;
-
-    data_test_init(&d);
-    data_test_clear(&d);
-}
-
-static void test_e1000e_tx(gconstpointer data)
-{
-    e1000e_device d;
-
-    data_test_init(&d);
-    e1000e_send_verify(&d);
-    data_test_clear(&d);
-}
-
-static void test_e1000e_rx(gconstpointer data)
-{
-    e1000e_device d;
-
-    data_test_init(&d);
-    e1000e_receive_verify(&d);
-    data_test_clear(&d);
-}
-
-static void test_e1000e_multiple_transfers(gconstpointer data)
-{
-    static const long iterations = 4 * 1024;
-    long i;
-
-    e1000e_device d;
-
-    data_test_init(&d);
-
-    for (i = 0; i < iterations; i++) {
-        e1000e_send_verify(&d);
-        e1000e_receive_verify(&d);
-    }
-
-    data_test_clear(&d);
-}
-
-static void test_e1000e_hotplug(gconstpointer data)
-{
-    static const uint8_t slot = 0x06;
-
-    qtest_start("-device e1000e");
-
-    qpci_plug_device_test("e1000e", "e1000e_net", slot, NULL);
-    qpci_unplug_acpi_device_test("e1000e_net", slot);
-
-    qtest_end();
-}
-
-int main(int argc, char **argv)
-{
-    g_test_init(&argc, &argv, NULL);
-
-    qtest_add_data_func("e1000e/init", NULL, test_e1000e_init);
-    qtest_add_data_func("e1000e/tx", NULL, test_e1000e_tx);
-    qtest_add_data_func("e1000e/rx", NULL, test_e1000e_rx);
-    qtest_add_data_func("e1000e/multiple_transfers", NULL,
-        test_e1000e_multiple_transfers);
-    qtest_add_data_func("e1000e/hotplug", NULL, test_e1000e_hotplug);
-
-    return g_test_run();
-}
index ed23258..e17eed0 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 static void test_device(gconstpointer data)
index b7a120e..cc5bccd 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "libqtest.h"
 #include "qemu/bswap.h"
@@ -282,6 +283,7 @@ static void test_endianness_combine(gconstpointer data)
 int main(int argc, char **argv)
 {
     const char *arch = qtest_get_arch();
+    int ret;
     int i;
 
     g_test_init(&argc, &argv, NULL);
@@ -304,5 +306,7 @@ int main(int argc, char **argv)
         qtest_add_data_func(path, &test_cases[i], test_endianness_combine);
     }
 
-    return g_test_run();
+    ret = g_test_run();
+
+    return ret;
 }
index 199fe19..824dc31 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
index 738c6b4..53df1d0 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "qemu/osdep.h"
 
+#include <glib.h>
 
 #include "libqtest.h"
 #include "qemu-common.h"
index 688342b..b4392c2 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "libqtest.h"
 #include "hw/nvram/fw_cfg_keys.h"
index 12ee392..c8e669a 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu-common.h"
 #include "libqtest.h"
 
index 3542ad1..05029e9 100644 (file)
@@ -13,6 +13,8 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
+#include <sys/mman.h>
 
 #include "libqtest.h"
 #include "libqos/pci.h"
@@ -394,6 +396,7 @@ static void request_pflash(FirmwareTestFixture *fixture,
 int main(int argc, char **argv)
 {
     TestData data;
+    int ret;
 
     g_test_init(&argc, &argv, NULL);
 
@@ -404,5 +407,6 @@ int main(int argc, char **argv)
     add_firmware_test("i440fx/firmware/bios", request_bios);
     add_firmware_test("i440fx/firmware/pflash", request_pflash);
 
-    return g_test_run();
+    ret = g_test_run();
+    return ret;
 }
index a6e3159..c3b5ebb 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
index 1e51af2..0d9ab4d 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "qemu/osdep.h"
 
+#include <glib.h>
 
 #include "libqtest.h"
 #include "libqos/libqos.h"
@@ -31,7 +32,6 @@
 #include "libqos/malloc-pc.h"
 
 #include "qemu-common.h"
-#include "qemu/bswap.h"
 #include "hw/pci/pci_ids.h"
 #include "hw/pci/pci_regs.h"
 
@@ -499,39 +499,6 @@ static void test_identify(void)
     ide_test_quit();
 }
 
-/*
- * Write sector 1 with random data to make IDE storage dirty
- * Needed for flush tests so that flushes actually go though the block layer
- */
-static void make_dirty(uint8_t device)
-{
-    uint8_t status;
-    size_t len = 512;
-    uintptr_t guest_buf;
-    void* buf;
-
-    guest_buf = guest_alloc(guest_malloc, len);
-    buf = g_malloc(len);
-    g_assert(guest_buf);
-    g_assert(buf);
-
-    memwrite(guest_buf, buf, len);
-
-    PrdtEntry prdt[] = {
-        {
-            .addr = cpu_to_le32(guest_buf),
-            .size = cpu_to_le32(len | PRDT_EOT),
-        },
-    };
-
-    status = send_dma_request(CMD_WRITE_DMA, 1, 1, prdt,
-                              ARRAY_SIZE(prdt), NULL);
-    g_assert_cmphex(status, ==, BM_STS_INTR);
-    assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
-
-    g_free(buf);
-}
-
 static void test_flush(void)
 {
     uint8_t data;
@@ -540,11 +507,6 @@ static void test_flush(void)
         "-drive file=blkdebug::%s,if=ide,cache=writeback,format=raw",
         tmp_path);
 
-    qtest_irq_intercept_in(global_qtest, "ioapic");
-
-    /* Dirty media so that CMD_FLUSH_CACHE will actually go to disk */
-    make_dirty(0);
-
     /* Delay the completion of the flush request until we explicitly do it */
     g_free(hmp("qemu-io ide0-hd0 \"break flush_to_os A\""));
 
@@ -587,11 +549,6 @@ static void test_retry_flush(const char *machine)
         "rerror=stop,werror=stop",
         debug_path, tmp_path);
 
-    qtest_irq_intercept_in(global_qtest, "ioapic");
-
-    /* Dirty media so that CMD_FLUSH_CACHE will actually go to disk */
-    make_dirty(0);
-
     /* FLUSH CACHE command on device 0*/
     outb(IDE_BASE + reg_device, 0);
     outb(IDE_BASE + reg_command, CMD_FLUSH_CACHE);
index b782b2e..1be6add 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 #define HDA_ID "hda0"
@@ -31,9 +32,13 @@ static void ich9_test(void)
 
 int main(int argc, char **argv)
 {
+    int ret;
+
     g_test_init(&argc, &argv, NULL);
     qtest_add_func("/intel-hda/ich6", ich6_test);
     qtest_add_func("/intel-hda/ich9", ich9_test);
 
-    return g_test_run();
+    ret = g_test_run();
+
+    return ret;
 }
index b54c4b9..93eb2f7 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
index be9005e..812907f 100644 (file)
@@ -29,6 +29,7 @@
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
 
+#include <glib.h>
 
 #include "libqtest.h"
 #include "qemu-common.h"
index 3750389..42c4b97 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "qemu/osdep.h"
 
+#include <glib.h>
 
 #include "libqtest.h"
 
index 6849141..846aaf5 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
index 0957ee7..c027ff1 100644 (file)
@@ -9,7 +9,9 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <glib/gstdio.h>
+#include <sys/mman.h>
 #include "contrib/ivshmem-server/ivshmem-server.h"
 #include "libqos/pci-pc.h"
 #include "libqtest.h"
index f3be550..ac6c155 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "libqtest.h"
 #include "libqos/ahci.h"
index c69fb5a..71dd7a6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef LIBQOS_AHCI_H
-#define LIBQOS_AHCI_H
+#ifndef __libqos_ahci_h
+#define __libqos_ahci_h
 
 /*
  * AHCI qtest library functions and definitions
index 4d9dc3f..76894d5 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqos/fw_cfg.h"
 #include "libqtest.h"
 #include "qemu/bswap.h"
index 1c4b431..51c3468 100644 (file)
@@ -20,6 +20,7 @@
 #include "qemu/osdep.h"
 #include "libqos/i2c.h"
 
+#include <glib.h>
 
 #include "libqtest.h"
 
index f603fdf..2028f2f 100644 (file)
@@ -9,6 +9,7 @@
 #include "qemu/osdep.h"
 #include "libqos/i2c.h"
 
+#include <glib.h>
 
 #include "qemu/bswap.h"
 #include "libqtest.h"
index a0e4c45..b1820c5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef LIBQOS_PC_H
-#define LIBQOS_PC_H
+#ifndef __libqos_pc_h
+#define __libqos_pc_h
 
 #include "libqos/libqos.h"
 
index c7ba441..79b0b29 100644 (file)
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <sys/wait.h>
 
 #include "libqtest.h"
index 604980d..ca14d2e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef LIBQOS_H
-#define LIBQOS_H
+#ifndef __libqos_h
+#define __libqos_h
 
 #include "libqtest.h"
 #include "libqos/pci.h"
index 33ce90b..6000df2 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqos/malloc-generic.h"
 #include "libqos/malloc.h"
 
index dd2b900..eee706b 100644 (file)
@@ -17,6 +17,7 @@
 #include "hw/nvram/fw_cfg_keys.h"
 
 #include "qemu-common.h"
+#include <glib.h>
 
 #define PAGE_SIZE (4096)
 
index b8eff5f..c0df52f 100644 (file)
@@ -13,7 +13,7 @@
 #include "qemu/osdep.h"
 #include "libqos/malloc.h"
 #include "qemu-common.h"
-#include "qemu/host-utils.h"
+#include <glib.h>
 
 typedef QTAILQ_HEAD(MemList, MemBlock) MemList;
 
index 1ae2d37..77f15e5 100644 (file)
@@ -19,6 +19,7 @@
 #include "qemu-common.h"
 #include "qemu/host-utils.h"
 
+#include <glib.h>
 
 #define ACPI_PCIHP_ADDR         0xae00
 #define PCI_EJ_BASE             0x0008
index ed78d91..0e104e1 100644 (file)
@@ -14,6 +14,7 @@
 #include "libqos/pci.h"
 
 #include "hw/pci/pci_regs.h"
+#include <glib.h>
 
 void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id,
                          void (*func)(QPCIDevice *dev, int devfn, void *data),
index f794d92..87efb90 100644 (file)
@@ -12,6 +12,7 @@
  * See the COPYING file in the top-level directory.
  */
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "hw/usb/uhci-regs.h"
 #include "libqos/usb.h"
index 0cab38f..a4382f3 100644 (file)
@@ -8,12 +8,12 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "libqos/virtio.h"
 #include "libqos/virtio-mmio.h"
 #include "libqos/malloc.h"
 #include "libqos/malloc-generic.h"
-#include "standard-headers/linux/virtio_ring.h"
 
 static uint8_t qvirtio_mmio_config_readb(QVirtioDevice *d, uint64_t addr)
 {
@@ -136,8 +136,8 @@ static QVirtQueue *qvirtio_mmio_virtqueue_setup(QVirtioDevice *d,
     vq->free_head = 0;
     vq->num_free = vq->size;
     vq->align = dev->page_size;
-    vq->indirect = (dev->features & (1u << VIRTIO_RING_F_INDIRECT_DESC)) != 0;
-    vq->event = (dev->features & (1u << VIRTIO_RING_F_EVENT_IDX)) != 0;
+    vq->indirect = (dev->features & QVIRTIO_F_RING_INDIRECT_DESC) != 0;
+    vq->event = (dev->features & QVIRTIO_F_RING_EVENT_IDX) != 0;
 
     writel(dev->addr + QVIRTIO_MMIO_QUEUE_NUM, vq->size);
 
@@ -154,13 +154,6 @@ static QVirtQueue *qvirtio_mmio_virtqueue_setup(QVirtioDevice *d,
     return vq;
 }
 
-static void qvirtio_mmio_virtqueue_cleanup(QVirtQueue *vq,
-                                           QGuestAllocator *alloc)
-{
-    guest_free(alloc, vq->desc);
-    g_free(vq);
-}
-
 static void qvirtio_mmio_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq)
 {
     QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
@@ -183,7 +176,6 @@ const QVirtioBus qvirtio_mmio = {
     .get_queue_size = qvirtio_mmio_get_queue_size,
     .set_queue_address = qvirtio_mmio_set_queue_address,
     .virtqueue_setup = qvirtio_mmio_virtqueue_setup,
-    .virtqueue_cleanup = qvirtio_mmio_virtqueue_cleanup,
     .virtqueue_kick = qvirtio_mmio_virtqueue_kick,
 };
 
index 18b92b9..fde2ff0 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "libqos/virtio.h"
 #include "libqos/virtio-pci.h"
 #include "libqos/pci-pc.h"
 #include "libqos/malloc.h"
 #include "libqos/malloc-pc.h"
-#include "standard-headers/linux/virtio_ring.h"
-#include "standard-headers/linux/virtio_pci.h"
 
-#include "hw/pci/pci.h"
 #include "hw/pci/pci_regs.h"
 
 typedef struct QVirtioPCIForeachData {
@@ -104,31 +102,31 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t addr)
 static uint32_t qvirtio_pci_get_features(QVirtioDevice *d)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    return qpci_io_readl(dev->pdev, dev->addr + VIRTIO_PCI_HOST_FEATURES);
+    return qpci_io_readl(dev->pdev, dev->addr + QVIRTIO_PCI_DEVICE_FEATURES);
 }
 
 static void qvirtio_pci_set_features(QVirtioDevice *d, uint32_t features)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    qpci_io_writel(dev->pdev, dev->addr + VIRTIO_PCI_GUEST_FEATURES, features);
+    qpci_io_writel(dev->pdev, dev->addr + QVIRTIO_PCI_GUEST_FEATURES, features);
 }
 
 static uint32_t qvirtio_pci_get_guest_features(QVirtioDevice *d)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    return qpci_io_readl(dev->pdev, dev->addr + VIRTIO_PCI_GUEST_FEATURES);
+    return qpci_io_readl(dev->pdev, dev->addr + QVIRTIO_PCI_GUEST_FEATURES);
 }
 
 static uint8_t qvirtio_pci_get_status(QVirtioDevice *d)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    return qpci_io_readb(dev->pdev, dev->addr + VIRTIO_PCI_STATUS);
+    return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_PCI_DEVICE_STATUS);
 }
 
 static void qvirtio_pci_set_status(QVirtioDevice *d, uint8_t status)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    qpci_io_writeb(dev->pdev, dev->addr + VIRTIO_PCI_STATUS, status);
+    qpci_io_writeb(dev->pdev, dev->addr + QVIRTIO_PCI_DEVICE_STATUS, status);
 }
 
 static bool qvirtio_pci_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq)
@@ -152,7 +150,7 @@ static bool qvirtio_pci_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq)
             }
         }
     } else {
-        return qpci_io_readb(dev->pdev, dev->addr + VIRTIO_PCI_ISR) & 1;
+        return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_PCI_ISR_STATUS) & 1;
     }
 }
 
@@ -176,26 +174,26 @@ static bool qvirtio_pci_get_config_isr_status(QVirtioDevice *d)
             }
         }
     } else {
-        return qpci_io_readb(dev->pdev, dev->addr + VIRTIO_PCI_ISR) & 2;
+        return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_PCI_ISR_STATUS) & 2;
     }
 }
 
 static void qvirtio_pci_queue_select(QVirtioDevice *d, uint16_t index)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    qpci_io_writeb(dev->pdev, dev->addr + VIRTIO_PCI_QUEUE_SEL, index);
+    qpci_io_writeb(dev->pdev, dev->addr + QVIRTIO_PCI_QUEUE_SELECT, index);
 }
 
 static uint16_t qvirtio_pci_get_queue_size(QVirtioDevice *d)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    return qpci_io_readw(dev->pdev, dev->addr + VIRTIO_PCI_QUEUE_NUM);
+    return qpci_io_readw(dev->pdev, dev->addr + QVIRTIO_PCI_QUEUE_SIZE);
 }
 
 static void qvirtio_pci_set_queue_address(QVirtioDevice *d, uint32_t pfn)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    qpci_io_writel(dev->pdev, dev->addr + VIRTIO_PCI_QUEUE_PFN, pfn);
+    qpci_io_writel(dev->pdev, dev->addr + QVIRTIO_PCI_QUEUE_ADDRESS, pfn);
 }
 
 static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
@@ -213,9 +211,9 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
     vqpci->vq.size = qvirtio_pci_get_queue_size(d);
     vqpci->vq.free_head = 0;
     vqpci->vq.num_free = vqpci->vq.size;
-    vqpci->vq.align = VIRTIO_PCI_VRING_ALIGN;
-    vqpci->vq.indirect = (feat & (1u << VIRTIO_RING_F_INDIRECT_DESC)) != 0;
-    vqpci->vq.event = (feat & (1u << VIRTIO_RING_F_EVENT_IDX)) != 0;
+    vqpci->vq.align = QVIRTIO_PCI_ALIGN;
+    vqpci->vq.indirect = (feat & QVIRTIO_F_RING_INDIRECT_DESC) != 0;
+    vqpci->vq.event = (feat & QVIRTIO_F_RING_EVENT_IDX) != 0;
 
     vqpci->msix_entry = -1;
     vqpci->msix_addr = 0;
@@ -227,27 +225,17 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
     /* Check power of 2 */
     g_assert_cmpint(vqpci->vq.size & (vqpci->vq.size - 1), ==, 0);
 
-    addr = guest_alloc(alloc, qvring_size(vqpci->vq.size,
-                                          VIRTIO_PCI_VRING_ALIGN));
+    addr = guest_alloc(alloc, qvring_size(vqpci->vq.size, QVIRTIO_PCI_ALIGN));
     qvring_init(alloc, &vqpci->vq, addr);
-    qvirtio_pci_set_queue_address(d, vqpci->vq.desc / VIRTIO_PCI_VRING_ALIGN);
+    qvirtio_pci_set_queue_address(d, vqpci->vq.desc / QVIRTIO_PCI_ALIGN);
 
     return &vqpci->vq;
 }
 
-static void qvirtio_pci_virtqueue_cleanup(QVirtQueue *vq,
-                                          QGuestAllocator *alloc)
-{
-    QVirtQueuePCI *vqpci = container_of(vq, QVirtQueuePCI, vq);
-
-    guest_free(alloc, vq->desc);
-    g_free(vqpci);
-}
-
 static void qvirtio_pci_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    qpci_io_writew(dev->pdev, dev->addr + VIRTIO_PCI_QUEUE_NOTIFY, vq->index);
+    qpci_io_writew(dev->pdev, dev->addr + QVIRTIO_PCI_QUEUE_NOTIFY, vq->index);
 }
 
 const QVirtioBus qvirtio_pci = {
@@ -266,7 +254,6 @@ const QVirtioBus qvirtio_pci = {
     .get_queue_size = qvirtio_pci_get_queue_size,
     .set_queue_address = qvirtio_pci_set_queue_address,
     .virtqueue_setup = qvirtio_pci_virtqueue_setup,
-    .virtqueue_cleanup = qvirtio_pci_virtqueue_cleanup,
     .virtqueue_kick = qvirtio_pci_virtqueue_kick,
 };
 
@@ -277,7 +264,7 @@ void qvirtio_pci_foreach(QPCIBus *bus, uint16_t device_type,
                                 .device_type = device_type,
                                 .user_data = data };
 
-    qpci_device_foreach(bus, PCI_VENDOR_ID_REDHAT_QUMRANET, -1,
+    qpci_device_foreach(bus, QVIRTIO_VENDOR_ID, -1,
                                 qvirtio_pci_foreach_callback, &d);
 }
 
@@ -328,9 +315,9 @@ void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci,
                                         control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
 
     qvirtio_pci_queue_select(&d->vdev, vqpci->vq.index);
-    qpci_io_writew(d->pdev, d->addr + VIRTIO_MSI_QUEUE_VECTOR, entry);
-    vector = qpci_io_readw(d->pdev, d->addr + VIRTIO_MSI_QUEUE_VECTOR);
-    g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);
+    qpci_io_writew(d->pdev, d->addr + QVIRTIO_PCI_MSIX_QUEUE_VECTOR, entry);
+    vector = qpci_io_readw(d->pdev, d->addr + QVIRTIO_PCI_MSIX_QUEUE_VECTOR);
+    g_assert_cmphex(vector, !=, QVIRTIO_MSI_NO_VECTOR);
 }
 
 void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
@@ -360,7 +347,7 @@ void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
     qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL,
                                         control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
 
-    qpci_io_writew(d->pdev, d->addr + VIRTIO_MSI_CONFIG_VECTOR, entry);
-    vector = qpci_io_readw(d->pdev, d->addr + VIRTIO_MSI_CONFIG_VECTOR);
-    g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);
+    qpci_io_writew(d->pdev, d->addr + QVIRTIO_PCI_MSIX_CONF_VECTOR, entry);
+    vector = qpci_io_readw(d->pdev, d->addr + QVIRTIO_PCI_MSIX_CONF_VECTOR);
+    g_assert_cmphex(vector, !=, QVIRTIO_MSI_NO_VECTOR);
 }
index efcac2d..8f0e52a 100644 (file)
 #include "libqos/virtio.h"
 #include "libqos/pci.h"
 
+#define QVIRTIO_PCI_DEVICE_FEATURES         0x00
+#define QVIRTIO_PCI_GUEST_FEATURES          0x04
+#define QVIRTIO_PCI_QUEUE_ADDRESS           0x08
+#define QVIRTIO_PCI_QUEUE_SIZE              0x0C
+#define QVIRTIO_PCI_QUEUE_SELECT            0x0E
+#define QVIRTIO_PCI_QUEUE_NOTIFY            0x10
+#define QVIRTIO_PCI_DEVICE_STATUS           0x12
+#define QVIRTIO_PCI_ISR_STATUS              0x13
+#define QVIRTIO_PCI_MSIX_CONF_VECTOR        0x14
+#define QVIRTIO_PCI_MSIX_QUEUE_VECTOR       0x16
+#define QVIRTIO_PCI_DEVICE_SPECIFIC_MSIX    0x18
+#define QVIRTIO_PCI_DEVICE_SPECIFIC_NO_MSIX 0x14
+
+#define QVIRTIO_PCI_ALIGN   4096
+
+#define QVIRTIO_MSI_NO_VECTOR   0xFFFF
+
 typedef struct QVirtioPCIDevice {
     QVirtioDevice vdev;
     QPCIDevice *pdev;
index d8c2970..613dece 100644 (file)
@@ -8,10 +8,9 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "libqos/virtio.h"
-#include "standard-headers/linux/virtio_config.h"
-#include "standard-headers/linux/virtio_ring.h"
 
 uint8_t qvirtio_config_readb(const QVirtioBus *bus, QVirtioDevice *d,
                                                                 uint64_t addr)
@@ -54,36 +53,30 @@ QVirtQueue *qvirtqueue_setup(const QVirtioBus *bus, QVirtioDevice *d,
     return bus->virtqueue_setup(d, alloc, index);
 }
 
-void qvirtqueue_cleanup(const QVirtioBus *bus, QVirtQueue *vq,
-                        QGuestAllocator *alloc)
-{
-    return bus->virtqueue_cleanup(vq, alloc);
-}
-
 void qvirtio_reset(const QVirtioBus *bus, QVirtioDevice *d)
 {
-    bus->set_status(d, 0);
-    g_assert_cmphex(bus->get_status(d), ==, 0);
+    bus->set_status(d, QVIRTIO_RESET);
+    g_assert_cmphex(bus->get_status(d), ==, QVIRTIO_RESET);
 }
 
 void qvirtio_set_acknowledge(const QVirtioBus *bus, QVirtioDevice *d)
 {
-    bus->set_status(d, bus->get_status(d) | VIRTIO_CONFIG_S_ACKNOWLEDGE);
-    g_assert_cmphex(bus->get_status(d), ==, VIRTIO_CONFIG_S_ACKNOWLEDGE);
+    bus->set_status(d, bus->get_status(d) | QVIRTIO_ACKNOWLEDGE);
+    g_assert_cmphex(bus->get_status(d), ==, QVIRTIO_ACKNOWLEDGE);
 }
 
 void qvirtio_set_driver(const QVirtioBus *bus, QVirtioDevice *d)
 {
-    bus->set_status(d, bus->get_status(d) | VIRTIO_CONFIG_S_DRIVER);
+    bus->set_status(d, bus->get_status(d) | QVIRTIO_DRIVER);
     g_assert_cmphex(bus->get_status(d), ==,
-                    VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE);
+                                    QVIRTIO_DRIVER | QVIRTIO_ACKNOWLEDGE);
 }
 
 void qvirtio_set_driver_ok(const QVirtioBus *bus, QVirtioDevice *d)
 {
-    bus->set_status(d, bus->get_status(d) | VIRTIO_CONFIG_S_DRIVER_OK);
-    g_assert_cmphex(bus->get_status(d), ==, VIRTIO_CONFIG_S_DRIVER_OK |
-                    VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE);
+    bus->set_status(d, bus->get_status(d) | QVIRTIO_DRIVER_OK);
+    g_assert_cmphex(bus->get_status(d), ==,
+                QVIRTIO_DRIVER_OK | QVIRTIO_DRIVER | QVIRTIO_ACKNOWLEDGE);
 }
 
 void qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,
@@ -141,7 +134,7 @@ void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr)
     int i;
 
     vq->desc = addr;
-    vq->avail = vq->desc + vq->size * sizeof(struct vring_desc);
+    vq->avail = vq->desc + vq->size*sizeof(QVRingDesc);
     vq->used = (uint64_t)((vq->avail + sizeof(uint16_t) * (3 + vq->size)
         + vq->align - 1) & ~(vq->align - 1));
 
@@ -162,7 +155,7 @@ void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr)
     /* vq->used->flags */
     writew(vq->used, 0);
     /* vq->used->avail_event */
-    writew(vq->used + 2 + sizeof(struct vring_used_elem) * vq->size, 0);
+    writew(vq->used+2+(sizeof(struct QVRingUsedElem)*vq->size), 0);
 }
 
 QVRingIndirectDesc *qvring_indirect_desc_setup(QVirtioDevice *d,
@@ -173,13 +166,13 @@ QVRingIndirectDesc *qvring_indirect_desc_setup(QVirtioDevice *d,
 
     indirect->index = 0;
     indirect->elem = elem;
-    indirect->desc = guest_alloc(alloc, sizeof(struct vring_desc) * elem);
+    indirect->desc = guest_alloc(alloc, sizeof(QVRingDesc)*elem);
 
     for (i = 0; i < elem - 1; ++i) {
         /* indirect->desc[i].addr */
         writeq(indirect->desc + (16 * i), 0);
         /* indirect->desc[i].flags */
-        writew(indirect->desc + (16 * i) + 12, VRING_DESC_F_NEXT);
+        writew(indirect->desc + (16 * i) + 12, QVRING_DESC_F_NEXT);
         /* indirect->desc[i].next */
         writew(indirect->desc + (16 * i) + 14, i + 1);
     }
@@ -197,7 +190,7 @@ void qvring_indirect_desc_add(QVRingIndirectDesc *indirect, uint64_t data,
     flags = readw(indirect->desc + (16 * indirect->index) + 12);
 
     if (write) {
-        flags |= VRING_DESC_F_WRITE;
+        flags |= QVRING_DESC_F_WRITE;
     }
 
     /* indirect->desc[indirect->index].addr */
@@ -217,11 +210,11 @@ uint32_t qvirtqueue_add(QVirtQueue *vq, uint64_t data, uint32_t len, bool write,
     vq->num_free--;
 
     if (write) {
-        flags |= VRING_DESC_F_WRITE;
+        flags |= QVRING_DESC_F_WRITE;
     }
 
     if (next) {
-        flags |= VRING_DESC_F_NEXT;
+        flags |= QVRING_DESC_F_NEXT;
     }
 
     /* vq->desc[vq->free_head].addr */
@@ -246,9 +239,9 @@ uint32_t qvirtqueue_add_indirect(QVirtQueue *vq, QVRingIndirectDesc *indirect)
     writeq(vq->desc + (16 * vq->free_head), indirect->desc);
     /* vq->desc[vq->free_head].len */
     writel(vq->desc + (16 * vq->free_head) + 8,
-           sizeof(struct vring_desc) * indirect->elem);
+                                        sizeof(QVRingDesc) * indirect->elem);
     /* vq->desc[vq->free_head].flags */
-    writew(vq->desc + (16 * vq->free_head) + 12, VRING_DESC_F_INDIRECT);
+    writew(vq->desc + (16 * vq->free_head) + 12, QVRING_DESC_F_INDIRECT);
 
     return vq->free_head++; /* Return and increase, in this order */
 }
@@ -271,10 +264,10 @@ void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq,
     /* Must read after idx is updated */
     flags = readw(vq->avail);
     avail_event = readw(vq->used + 4 +
-                                sizeof(struct vring_used_elem) * vq->size);
+                                (sizeof(struct QVRingUsedElem) * vq->size));
 
     /* < 1 because we add elements to avail queue one by one */
-    if ((flags & VRING_USED_F_NO_NOTIFY) == 0 &&
+    if ((flags & QVRING_USED_F_NO_NOTIFY) == 0 &&
                             (!vq->event || (uint16_t)(idx-avail_event) < 1)) {
         bus->virtqueue_kick(d, vq);
     }
index 0250842..0101278 100644 (file)
 #define LIBQOS_VIRTIO_H
 
 #include "libqos/malloc.h"
-#include "standard-headers/linux/virtio_ring.h"
 
+#define QVIRTIO_VENDOR_ID       0x1AF4
+
+#define QVIRTIO_RESET           0x0
+#define QVIRTIO_ACKNOWLEDGE     0x1
+#define QVIRTIO_DRIVER          0x2
+#define QVIRTIO_DRIVER_OK       0x4
+
+#define QVIRTIO_NET_DEVICE_ID       0x1
+#define QVIRTIO_BLK_DEVICE_ID       0x2
+#define QVIRTIO_CONSOLE_DEVICE_ID   0x3
+#define QVIRTIO_RNG_DEVICE_ID       0x4
+#define QVIRTIO_BALLOON_DEVICE_ID   0x5
+#define QVIRTIO_RPMSG_DEVICE_ID     0x7
+#define QVIRTIO_SCSI_DEVICE_ID      0x8
+#define QVIRTIO_9P_DEVICE_ID        0x9
+
+#define QVIRTIO_F_NOTIFY_ON_EMPTY       0x01000000
+#define QVIRTIO_F_ANY_LAYOUT            0x08000000
+#define QVIRTIO_F_RING_INDIRECT_DESC    0x10000000
+#define QVIRTIO_F_RING_EVENT_IDX        0x20000000
 #define QVIRTIO_F_BAD_FEATURE           0x40000000
 
+#define QVRING_DESC_F_NEXT      0x1
+#define QVRING_DESC_F_WRITE     0x2
+#define QVRING_DESC_F_INDIRECT  0x4
+
+#define QVIRTIO_F_NOTIFY_ON_EMPTY       0x01000000
+#define QVIRTIO_F_ANY_LAYOUT            0x08000000
+#define QVIRTIO_F_RING_INDIRECT_DESC    0x10000000
+#define QVIRTIO_F_RING_EVENT_IDX        0x20000000
+#define QVIRTIO_F_BAD_FEATURE           0x40000000
+
+#define QVRING_AVAIL_F_NO_INTERRUPT     1
+
+#define QVRING_USED_F_NO_NOTIFY     1
+
 typedef struct QVirtioDevice {
     /* Device type */
     uint16_t device_type;
 } QVirtioDevice;
 
+typedef struct QVRingDesc {
+    uint64_t addr;
+    uint32_t len;
+    uint16_t flags;
+    uint16_t next;
+} QVRingDesc;
+
+typedef struct QVRingAvail {
+    uint16_t flags;
+    uint16_t idx;
+    uint16_t ring[0]; /* This is an array of uint16_t */
+    uint16_t used_event;
+} QVRingAvail;
+
+typedef struct QVRingUsedElem {
+    uint32_t id;
+    uint32_t len;
+} QVRingUsedElem;
+
+typedef struct QVRingUsed {
+    uint16_t flags;
+    uint16_t idx;
+    QVRingUsedElem ring[0]; /* This is an array of QVRingUsedElem structs */
+    uint16_t avail_event;
+} QVRingUsed;
+
 typedef struct QVirtQueue {
-    uint64_t desc; /* This points to an array of struct vring_desc */
-    uint64_t avail; /* This points to a struct vring_avail */
-    uint64_t used; /* This points to a struct vring_desc */
+    uint64_t desc; /* This points to an array of QVRingDesc */
+    uint64_t avail; /* This points to a QVRingAvail */
+    uint64_t used; /* This points to a QVRingDesc */
     uint16_t index;
     uint32_t size;
     uint32_t free_head;
@@ -34,7 +93,7 @@ typedef struct QVirtQueue {
 } QVirtQueue;
 
 typedef struct QVRingIndirectDesc {
-    uint64_t desc; /* This points to an array fo struct vring_desc */
+    uint64_t desc; /* This points to an array fo QVRingDesc */
     uint16_t index;
     uint16_t elem;
 } QVRingIndirectDesc;
@@ -79,18 +138,15 @@ typedef struct QVirtioBus {
     QVirtQueue *(*virtqueue_setup)(QVirtioDevice *d, QGuestAllocator *alloc,
                                                                 uint16_t index);
 
-    /* Free virtqueue resources */
-    void (*virtqueue_cleanup)(QVirtQueue *vq, QGuestAllocator *alloc);
-
     /* Notify changes in virtqueue */
     void (*virtqueue_kick)(QVirtioDevice *d, QVirtQueue *vq);
 } QVirtioBus;
 
 static inline uint32_t qvring_size(uint32_t num, uint32_t align)
 {
-    return ((sizeof(struct vring_desc) * num + sizeof(uint16_t) * (3 + num)
+    return ((sizeof(struct QVRingDesc) * num + sizeof(uint16_t) * (3 + num)
         + align - 1) & ~(align - 1))
-        + sizeof(uint16_t) * 3 + sizeof(struct vring_used_elem) * num;
+        + sizeof(uint16_t) * 3 + sizeof(struct QVRingUsedElem) * num;
 }
 
 uint8_t qvirtio_config_readb(const QVirtioBus *bus, QVirtioDevice *d,
@@ -121,8 +177,6 @@ void qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d,
                              gint64 timeout_us);
 QVirtQueue *qvirtqueue_setup(const QVirtioBus *bus, QVirtioDevice *d,
                                         QGuestAllocator *alloc, uint16_t index);
-void qvirtqueue_cleanup(const QVirtioBus *bus, QVirtQueue *vq,
-                        QGuestAllocator *alloc);
 
 void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr);
 QVRingIndirectDesc *qvring_indirect_desc_setup(QVirtioDevice *d,
index eb00f13..b12a9e4 100644 (file)
@@ -17,6 +17,7 @@
 #include "qemu/osdep.h"
 #include "libqtest.h"
 
+#include <glib.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
 #include <sys/un.h>
@@ -26,7 +27,7 @@
 #include "qapi/qmp/qjson.h"
 
 #define MAX_IRQ 256
-#define SOCKET_TIMEOUT 50
+#define SOCKET_TIMEOUT 5
 
 QTestState *global_qtest;
 
index 0f921ef..a751fd3 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "libqtest.h"
 
diff --git a/tests/migration/.gitignore b/tests/migration/.gitignore
deleted file mode 100644 (file)
index 84f3755..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-initrd-stress.img
-stress
diff --git a/tests/migration/guestperf-batch.py b/tests/migration/guestperf-batch.py
deleted file mode 100755 (executable)
index cb150ce..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/python
-#
-# Migration test batch comparison invokation
-#
-# Copyright (c) 2016 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#
-
-import sys
-
-from guestperf.shell import BatchShell
-
-shell = BatchShell()
-sys.exit(shell.run(sys.argv[1:]))
diff --git a/tests/migration/guestperf-plot.py b/tests/migration/guestperf-plot.py
deleted file mode 100755 (executable)
index d70bb7a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/python
-#
-# Migration test graph plotting command
-#
-# Copyright (c) 2016 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#
-
-import sys
-
-from guestperf.shell import PlotShell
-
-shell = PlotShell()
-sys.exit(shell.run(sys.argv[1:]))
diff --git a/tests/migration/guestperf.py b/tests/migration/guestperf.py
deleted file mode 100755 (executable)
index 99b027e..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/python
-#
-# Migration test direct invokation command
-#
-# Copyright (c) 2016 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#
-
-
-import sys
-
-from guestperf.shell import Shell
-
-shell = Shell()
-sys.exit(shell.run(sys.argv[1:]))
diff --git a/tests/migration/guestperf/__init__.py b/tests/migration/guestperf/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/tests/migration/guestperf/comparison.py b/tests/migration/guestperf/comparison.py
deleted file mode 100644 (file)
index d0b7df9..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-#
-# Migration test scenario comparison mapping
-#
-# Copyright (c) 2016 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#
-
-from guestperf.scenario import Scenario
-
-class Comparison(object):
-    def __init__(self, name, scenarios):
-        self._name = name
-        self._scenarios = scenarios
-
-COMPARISONS = [
-    # Looking at effect of pausing guest during migration
-    # at various stages of iteration over RAM
-    Comparison("pause-iters", scenarios = [
-        Scenario("pause-iters-0",
-                 pause=True, pause_iters=0),
-        Scenario("pause-iters-1",
-                 pause=True, pause_iters=1),
-        Scenario("pause-iters-5",
-                 pause=True, pause_iters=5),
-        Scenario("pause-iters-20",
-                 pause=True, pause_iters=20),
-    ]),
-
-
-    # Looking at use of post-copy in relation to bandwidth
-    # available for migration
-    Comparison("post-copy-bandwidth", scenarios = [
-        Scenario("post-copy-bw-100mbs",
-                 post_copy=True, bandwidth=12),
-        Scenario("post-copy-bw-300mbs",
-                 post_copy=True, bandwidth=37),
-        Scenario("post-copy-bw-1gbs",
-                 post_copy=True, bandwidth=125),
-        Scenario("post-copy-bw-10gbs",
-                 post_copy=True, bandwidth=1250),
-        Scenario("post-copy-bw-100gbs",
-                 post_copy=True, bandwidth=12500),
-    ]),
-
-
-    # Looking at effect of starting post-copy at different
-    # stages of the migration
-    Comparison("post-copy-iters", scenarios = [
-        Scenario("post-copy-iters-0",
-                 post_copy=True, post_copy_iters=0),
-        Scenario("post-copy-iters-1",
-                 post_copy=True, post_copy_iters=1),
-        Scenario("post-copy-iters-5",
-                 post_copy=True, post_copy_iters=5),
-        Scenario("post-copy-iters-20",
-                 post_copy=True, post_copy_iters=20),
-    ]),
-
-
-    # Looking at effect of auto-converge with different
-    # throttling percentage step rates
-    Comparison("auto-converge-iters", scenarios = [
-        Scenario("auto-converge-step-5",
-                 auto_converge=True, auto_converge_step=5),
-        Scenario("auto-converge-step-10",
-                 auto_converge=True, auto_converge_step=10),
-        Scenario("auto-converge-step-20",
-                 auto_converge=True, auto_converge_step=20),
-    ]),
-
-
-    # Looking at use of auto-converge in relation to bandwidth
-    # available for migration
-    Comparison("auto-converge-bandwidth", scenarios = [
-        Scenario("auto-converge-bw-100mbs",
-                 auto_converge=True, bandwidth=12),
-        Scenario("auto-converge-bw-300mbs",
-                 auto_converge=True, bandwidth=37),
-        Scenario("auto-converge-bw-1gbs",
-                 auto_converge=True, bandwidth=125),
-        Scenario("auto-converge-bw-10gbs",
-                 auto_converge=True, bandwidth=1250),
-        Scenario("auto-converge-bw-100gbs",
-                 auto_converge=True, bandwidth=12500),
-    ]),
-
-
-    # Looking at effect of multi-thread compression with
-    # varying numbers of threads
-    Comparison("compr-mt", scenarios = [
-        Scenario("compr-mt-threads-1",
-                 compression_mt=True, compression_mt_threads=1),
-        Scenario("compr-mt-threads-2",
-                 compression_mt=True, compression_mt_threads=2),
-        Scenario("compr-mt-threads-4",
-                 compression_mt=True, compression_mt_threads=4),
-    ]),
-
-
-    # Looking at effect of xbzrle compression with varying
-    # cache sizes
-    Comparison("compr-xbzrle", scenarios = [
-        Scenario("compr-xbzrle-cache-5",
-                 compression_xbzrle=True, compression_xbzrle_cache=5),
-        Scenario("compr-xbzrle-cache-10",
-                 compression_xbzrle=True, compression_xbzrle_cache=10),
-        Scenario("compr-xbzrle-cache-20",
-                 compression_xbzrle=True, compression_xbzrle_cache=10),
-        Scenario("compr-xbzrle-cache-50",
-                 compression_xbzrle=True, compression_xbzrle_cache=50),
-    ]),
-]
diff --git a/tests/migration/guestperf/engine.py b/tests/migration/guestperf/engine.py
deleted file mode 100644 (file)
index 0a13050..0000000
+++ /dev/null
@@ -1,439 +0,0 @@
-#
-# Migration test main engine
-#
-# Copyright (c) 2016 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#
-
-
-import os
-import re
-import sys
-import time
-
-sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'scripts'))
-import qemu
-import qmp.qmp
-from guestperf.progress import Progress, ProgressStats
-from guestperf.report import Report
-from guestperf.timings import TimingRecord, Timings
-
-
-class Engine(object):
-
-    def __init__(self, binary, dst_host, kernel, initrd, transport="tcp",
-                 sleep=15, verbose=False, debug=False):
-
-        self._binary = binary # Path to QEMU binary
-        self._dst_host = dst_host # Hostname of target host
-        self._kernel = kernel # Path to kernel image
-        self._initrd = initrd # Path to stress initrd
-        self._transport = transport # 'unix' or 'tcp' or 'rdma'
-        self._sleep = sleep
-        self._verbose = verbose
-        self._debug = debug
-
-        if debug:
-            self._verbose = debug
-
-    def _vcpu_timing(self, pid, tid_list):
-        records = []
-        now = time.time()
-
-        jiffies_per_sec = os.sysconf(os.sysconf_names['SC_CLK_TCK'])
-        for tid in tid_list:
-            statfile = "/proc/%d/task/%d/stat" % (pid, tid)
-            with open(statfile, "r") as fh:
-                stat = fh.readline()
-                fields = stat.split(" ")
-                stime = int(fields[13])
-                utime = int(fields[14])
-                records.append(TimingRecord(tid, now, 1000 * (stime + utime) / jiffies_per_sec))
-        return records
-
-    def _cpu_timing(self, pid):
-        records = []
-        now = time.time()
-
-        jiffies_per_sec = os.sysconf(os.sysconf_names['SC_CLK_TCK'])
-        statfile = "/proc/%d/stat" % pid
-        with open(statfile, "r") as fh:
-            stat = fh.readline()
-            fields = stat.split(" ")
-            stime = int(fields[13])
-            utime = int(fields[14])
-            return TimingRecord(pid, now, 1000 * (stime + utime) / jiffies_per_sec)
-
-    def _migrate_progress(self, vm):
-        info = vm.command("query-migrate")
-
-        if "ram" not in info:
-            info["ram"] = {}
-
-        return Progress(
-            info.get("status", "active"),
-            ProgressStats(
-                info["ram"].get("transferred", 0),
-                info["ram"].get("remaining", 0),
-                info["ram"].get("total", 0),
-                info["ram"].get("duplicate", 0),
-                info["ram"].get("skipped", 0),
-                info["ram"].get("normal", 0),
-                info["ram"].get("normal-bytes", 0),
-                info["ram"].get("dirty-pages-rate", 0),
-                info["ram"].get("mbps", 0),
-                info["ram"].get("dirty-sync-count", 0)
-            ),
-            time.time(),
-            info.get("total-time", 0),
-            info.get("downtime", 0),
-            info.get("expected-downtime", 0),
-            info.get("setup-time", 0),
-            info.get("x-cpu-throttle-percentage", 0),
-        )
-
-    def _migrate(self, hardware, scenario, src, dst, connect_uri):
-        src_qemu_time = []
-        src_vcpu_time = []
-        src_pid = src.get_pid()
-
-        vcpus = src.command("query-cpus")
-        src_threads = []
-        for vcpu in vcpus:
-            src_threads.append(vcpu["thread_id"])
-
-        # XXX how to get dst timings on remote host ?
-
-        if self._verbose:
-            print "Sleeping %d seconds for initial guest workload run" % self._sleep
-        sleep_secs = self._sleep
-        while sleep_secs > 1:
-            src_qemu_time.append(self._cpu_timing(src_pid))
-            src_vcpu_time.extend(self._vcpu_timing(src_pid, src_threads))
-            time.sleep(1)
-            sleep_secs -= 1
-
-        if self._verbose:
-            print "Starting migration"
-        if scenario._auto_converge:
-            resp = src.command("migrate-set-capabilities",
-                               capabilities = [
-                                   { "capability": "auto-converge",
-                                     "state": True }
-                               ])
-            resp = src.command("migrate-set-parameters",
-                               x_cpu_throttle_increment=scenario._auto_converge_step)
-
-        if scenario._post_copy:
-            resp = src.command("migrate-set-capabilities",
-                               capabilities = [
-                                   { "capability": "postcopy-ram",
-                                     "state": True }
-                               ])
-            resp = dst.command("migrate-set-capabilities",
-                               capabilities = [
-                                   { "capability": "postcopy-ram",
-                                     "state": True }
-                               ])
-
-        resp = src.command("migrate_set_speed",
-                           value=scenario._bandwidth * 1024 * 1024)
-
-        resp = src.command("migrate_set_downtime",
-                           value=scenario._downtime / 1024.0)
-
-        if scenario._compression_mt:
-            resp = src.command("migrate-set-capabilities",
-                               capabilities = [
-                                   { "capability": "compress",
-                                     "state": True }
-                               ])
-            resp = src.command("migrate-set-parameters",
-                               compress_threads=scenario._compression_mt_threads)
-            resp = dst.command("migrate-set-capabilities",
-                               capabilities = [
-                                   { "capability": "compress",
-                                     "state": True }
-                               ])
-            resp = dst.command("migrate-set-parameters",
-                               decompress_threads=scenario._compression_mt_threads)
-
-        if scenario._compression_xbzrle:
-            resp = src.command("migrate-set-capabilities",
-                               capabilities = [
-                                   { "capability": "xbzrle",
-                                     "state": True }
-                               ])
-            resp = dst.command("migrate-set-capabilities",
-                               capabilities = [
-                                   { "capability": "xbzrle",
-                                     "state": True }
-                               ])
-            resp = src.command("migrate-set-cache-size",
-                               value=(hardware._mem * 1024 * 1024 * 1024 / 100 *
-                                      scenario._compression_xbzrle_cache))
-
-        resp = src.command("migrate", uri=connect_uri)
-
-        post_copy = False
-        paused = False
-
-        progress_history = []
-
-        start = time.time()
-        loop = 0
-        while True:
-            loop = loop + 1
-            time.sleep(0.05)
-
-            progress = self._migrate_progress(src)
-            if (loop % 20) == 0:
-                src_qemu_time.append(self._cpu_timing(src_pid))
-                src_vcpu_time.extend(self._vcpu_timing(src_pid, src_threads))
-
-            if (len(progress_history) == 0 or
-                (progress_history[-1]._ram._iterations <
-                 progress._ram._iterations)):
-                progress_history.append(progress)
-
-            if progress._status in ("completed", "failed", "cancelled"):
-                if progress._status == "completed" and paused:
-                    dst.command("cont")
-                if progress_history[-1] != progress:
-                    progress_history.append(progress)
-
-                if progress._status == "completed":
-                    if self._verbose:
-                        print "Sleeping %d seconds for final guest workload run" % self._sleep
-                    sleep_secs = self._sleep
-                    while sleep_secs > 1:
-                        time.sleep(1)
-                        src_qemu_time.append(self._cpu_timing(src_pid))
-                        src_vcpu_time.extend(self._vcpu_timing(src_pid, src_threads))
-                        sleep_secs -= 1
-
-                return [progress_history, src_qemu_time, src_vcpu_time]
-
-            if self._verbose and (loop % 20) == 0:
-                print "Iter %d: remain %5dMB of %5dMB (total %5dMB @ %5dMb/sec)" % (
-                    progress._ram._iterations,
-                    progress._ram._remaining_bytes / (1024 * 1024),
-                    progress._ram._total_bytes / (1024 * 1024),
-                    progress._ram._transferred_bytes / (1024 * 1024),
-                    progress._ram._transfer_rate_mbs,
-                )
-
-            if progress._ram._iterations > scenario._max_iters:
-                if self._verbose:
-                    print "No completion after %d iterations over RAM" % scenario._max_iters
-                src.command("migrate_cancel")
-                continue
-
-            if time.time() > (start + scenario._max_time):
-                if self._verbose:
-                    print "No completion after %d seconds" % scenario._max_time
-                src.command("migrate_cancel")
-                continue
-
-            if (scenario._post_copy and
-                progress._ram._iterations >= scenario._post_copy_iters and
-                not post_copy):
-                if self._verbose:
-                    print "Switching to post-copy after %d iterations" % scenario._post_copy_iters
-                resp = src.command("migrate-start-postcopy")
-                post_copy = True
-
-            if (scenario._pause and
-                progress._ram._iterations >= scenario._pause_iters and
-                not paused):
-                if self._verbose:
-                    print "Pausing VM after %d iterations" % scenario._pause_iters
-                resp = src.command("stop")
-                paused = True
-
-    def _get_common_args(self, hardware, tunnelled=False):
-        args = [
-            "noapic",
-            "edd=off",
-            "printk.time=1",
-            "noreplace-smp",
-            "cgroup_disable=memory",
-            "pci=noearly",
-            "console=ttyS0",
-        ]
-        if self._debug:
-            args.append("debug")
-        else:
-            args.append("quiet")
-
-        args.append("ramsize=%s" % hardware._mem)
-
-        cmdline = " ".join(args)
-        if tunnelled:
-            cmdline = "'" + cmdline + "'"
-
-        argv = [
-            "-machine", "accel=kvm",
-            "-cpu", "host",
-            "-kernel", self._kernel,
-            "-initrd", self._initrd,
-            "-append", cmdline,
-            "-chardev", "stdio,id=cdev0",
-            "-device", "isa-serial,chardev=cdev0",
-            "-m", str((hardware._mem * 1024) + 512),
-            "-smp", str(hardware._cpus),
-        ]
-
-        if self._debug:
-            argv.extend(["-device", "sga"])
-
-        if hardware._prealloc_pages:
-            argv_source += ["-mem-path", "/dev/shm",
-                            "-mem-prealloc"]
-        if hardware._locked_pages:
-            argv_source += ["-realtime", "mlock=on"]
-        if hardware._huge_pages:
-            pass
-
-        return argv
-
-    def _get_src_args(self, hardware):
-        return self._get_common_args(hardware)
-
-    def _get_dst_args(self, hardware, uri):
-        tunnelled = False
-        if self._dst_host != "localhost":
-            tunnelled = True
-        argv = self._get_common_args(hardware, tunnelled)
-        return argv + ["-incoming", uri]
-
-    @staticmethod
-    def _get_common_wrapper(cpu_bind, mem_bind):
-        wrapper = []
-        if len(cpu_bind) > 0 or len(mem_bind) > 0:
-            wrapper.append("numactl")
-            if cpu_bind:
-                wrapper.append("--physcpubind=%s" % ",".join(cpu_bind))
-            if mem_bind:
-                wrapper.append("--membind=%s" % ",".join(mem_bind))
-
-        return wrapper
-
-    def _get_src_wrapper(self, hardware):
-        return self._get_common_wrapper(hardware._src_cpu_bind, hardware._src_mem_bind)
-
-    def _get_dst_wrapper(self, hardware):
-        wrapper = self._get_common_wrapper(hardware._dst_cpu_bind, hardware._dst_mem_bind)
-        if self._dst_host != "localhost":
-            return ["ssh",
-                    "-R", "9001:localhost:9001",
-                    self._dst_host] + wrapper
-        else:
-            return wrapper
-
-    def _get_timings(self, vm):
-        log = vm.get_log()
-        if not log:
-            return []
-        if self._debug:
-            print log
-
-        regex = r"[^\s]+\s\((\d+)\):\sINFO:\s(\d+)ms\scopied\s\d+\sGB\sin\s(\d+)ms"
-        matcher = re.compile(regex)
-        records = []
-        for line in log.split("\n"):
-            match = matcher.match(line)
-            if match:
-                records.append(TimingRecord(int(match.group(1)),
-                                            int(match.group(2)) / 1000.0,
-                                            int(match.group(3))))
-        return records
-
-    def run(self, hardware, scenario, result_dir=os.getcwd()):
-        abs_result_dir = os.path.join(result_dir, scenario._name)
-
-        if self._transport == "tcp":
-            uri = "tcp:%s:9000" % self._dst_host
-        elif self._transport == "rdma":
-            uri = "rdma:%s:9000" % self._dst_host
-        elif self._transport == "unix":
-            if self._dst_host != "localhost":
-                raise Exception("Running use unix migration transport for non-local host")
-            uri = "unix:/var/tmp/qemu-migrate-%d.migrate" % os.getpid()
-            try:
-                os.remove(uri[5:])
-                os.remove(monaddr)
-            except:
-                pass
-
-        if self._dst_host != "localhost":
-            dstmonaddr = ("localhost", 9001)
-        else:
-            dstmonaddr = "/var/tmp/qemu-dst-%d-monitor.sock" % os.getpid()
-        srcmonaddr = "/var/tmp/qemu-src-%d-monitor.sock" % os.getpid()
-
-        src = qemu.QEMUMachine(self._binary,
-                               args=self._get_src_args(hardware),
-                               wrapper=self._get_src_wrapper(hardware),
-                               name="qemu-src-%d" % os.getpid(),
-                               monitor_address=srcmonaddr,
-                               debug=self._debug)
-
-        dst = qemu.QEMUMachine(self._binary,
-                               args=self._get_dst_args(hardware, uri),
-                               wrapper=self._get_dst_wrapper(hardware),
-                               name="qemu-dst-%d" % os.getpid(),
-                               monitor_address=dstmonaddr,
-                               debug=self._debug)
-
-        try:
-            src.launch()
-            dst.launch()
-
-            ret = self._migrate(hardware, scenario, src, dst, uri)
-            progress_history = ret[0]
-            qemu_timings = ret[1]
-            vcpu_timings = ret[2]
-            if uri[0:5] == "unix:":
-                os.remove(uri[5:])
-            if self._verbose:
-                print "Finished migration"
-
-            src.shutdown()
-            dst.shutdown()
-
-            return Report(hardware, scenario, progress_history,
-                          Timings(self._get_timings(src) + self._get_timings(dst)),
-                          Timings(qemu_timings),
-                          Timings(vcpu_timings),
-                          self._binary, self._dst_host, self._kernel,
-                          self._initrd, self._transport, self._sleep)
-        except Exception as e:
-            if self._debug:
-                print "Failed: %s" % str(e)
-            try:
-                src.shutdown()
-            except:
-                pass
-            try:
-                dst.shutdown()
-            except:
-                pass
-
-            if self._debug:
-                print src.get_log()
-                print dst.get_log()
-            raise
-
diff --git a/tests/migration/guestperf/hardware.py b/tests/migration/guestperf/hardware.py
deleted file mode 100644 (file)
index a66c9dd..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# Migration test hardware configuration description
-#
-# Copyright (c) 2016 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#
-
-
-class Hardware(object):
-    def __init__(self, cpus=1, mem=1,
-                 src_cpu_bind=None, src_mem_bind=None,
-                 dst_cpu_bind=None, dst_mem_bind=None,
-                 prealloc_pages = False,
-                 huge_pages=False, locked_pages=False):
-        self._cpus = cpus
-        self._mem = mem # GiB
-        self._src_mem_bind = src_mem_bind # List of NUMA nodes
-        self._src_cpu_bind = src_cpu_bind # List of pCPUs
-        self._dst_mem_bind = dst_mem_bind # List of NUMA nodes
-        self._dst_cpu_bind = dst_cpu_bind # List of pCPUs
-        self._prealloc_pages = prealloc_pages
-        self._huge_pages = huge_pages
-        self._locked_pages = locked_pages
-
-
-    def serialize(self):
-        return {
-            "cpus": self._cpus,
-            "mem": self._mem,
-            "src_mem_bind": self._src_mem_bind,
-            "dst_mem_bind": self._dst_mem_bind,
-            "src_cpu_bind": self._src_cpu_bind,
-            "dst_cpu_bind": self._dst_cpu_bind,
-            "prealloc_pages": self._prealloc_pages,
-            "huge_pages": self._huge_pages,
-            "locked_pages": self._locked_pages,
-        }
-
-    @classmethod
-    def deserialize(cls, data):
-        return cls(
-            data["cpus"],
-            data["mem"],
-            data["src_cpu_bind"],
-            data["src_mem_bind"],
-            data["dst_cpu_bind"],
-            data["dst_mem_bind"],
-            data["prealloc_pages"],
-            data["huge_pages"],
-            data["locked_pages"])
diff --git a/tests/migration/guestperf/plot.py b/tests/migration/guestperf/plot.py
deleted file mode 100644 (file)
index bc42249..0000000
+++ /dev/null
@@ -1,623 +0,0 @@
-#
-# Migration test graph plotting
-#
-# Copyright (c) 2016 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#
-
-import sys
-
-
-class Plot(object):
-
-    # Generated using
-    # http://tools.medialab.sciences-po.fr/iwanthue/
-    COLORS = ["#CD54D0",
-              "#79D94C",
-              "#7470CD",
-              "#D2D251",
-              "#863D79",
-              "#76DDA6",
-              "#D4467B",
-              "#61923D",
-              "#CB9CCA",
-              "#D98F36",
-              "#8CC8DA",
-              "#CE4831",
-              "#5E7693",
-              "#9B803F",
-              "#412F4C",
-              "#CECBA6",
-              "#6D3229",
-              "#598B73",
-              "#C8827C",
-              "#394427"]
-
-    def __init__(self,
-                 reports,
-                 migration_iters,
-                 total_guest_cpu,
-                 split_guest_cpu,
-                 qemu_cpu,
-                 vcpu_cpu):
-
-        self._reports = reports
-        self._migration_iters = migration_iters
-        self._total_guest_cpu = total_guest_cpu
-        self._split_guest_cpu = split_guest_cpu
-        self._qemu_cpu = qemu_cpu
-        self._vcpu_cpu = vcpu_cpu
-        self._color_idx = 0
-
-    def _next_color(self):
-        color = self.COLORS[self._color_idx]
-        self._color_idx += 1
-        if self._color_idx >= len(self.COLORS):
-            self._color_idx = 0
-        return color
-
-    def _get_progress_label(self, progress):
-        if progress:
-            return "\n\n" + "\n".join(
-                ["Status: %s" % progress._status,
-                 "Iteration: %d" % progress._ram._iterations,
-                 "Throttle: %02d%%" % progress._throttle_pcent,
-                 "Dirty rate: %dMB/s" % (progress._ram._dirty_rate_pps * 4 / 1024.0)])
-        else:
-            return "\n\n" + "\n".join(
-                ["Status: %s" % "none",
-                 "Iteration: %d" % 0])
-
-    def _find_start_time(self, report):
-        startqemu = report._qemu_timings._records[0]._timestamp
-        startguest = report._guest_timings._records[0]._timestamp
-        if startqemu < startguest:
-            return startqemu
-        else:
-            return stasrtguest
-
-    def _get_guest_max_value(self, report):
-        maxvalue = 0
-        for record in report._guest_timings._records:
-            if record._value > maxvalue:
-                maxvalue = record._value
-        return maxvalue
-
-    def _get_qemu_max_value(self, report):
-        maxvalue = 0
-        oldvalue = None
-        oldtime = None
-        for record in report._qemu_timings._records:
-            if oldvalue is not None:
-                cpudelta = (record._value - oldvalue) / 1000.0
-                timedelta = record._timestamp - oldtime
-                if timedelta == 0:
-                    continue
-                util = cpudelta / timedelta * 100.0
-            else:
-                util = 0
-            oldvalue = record._value
-            oldtime = record._timestamp
-
-            if util > maxvalue:
-                maxvalue = util
-        return maxvalue
-
-    def _get_total_guest_cpu_graph(self, report, starttime):
-        xaxis = []
-        yaxis = []
-        labels = []
-        progress_idx = -1
-        for record in report._guest_timings._records:
-            while ((progress_idx + 1) < len(report._progress_history) and
-                   report._progress_history[progress_idx + 1]._now < record._timestamp):
-                progress_idx = progress_idx + 1
-
-            if progress_idx >= 0:
-                progress = report._progress_history[progress_idx]
-            else:
-                progress = None
-
-            xaxis.append(record._timestamp - starttime)
-            yaxis.append(record._value)
-            labels.append(self._get_progress_label(progress))
-
-        from plotly import graph_objs as go
-        return go.Scatter(x=xaxis,
-                          y=yaxis,
-                          name="Guest PIDs: %s" % report._scenario._name,
-                          mode='lines',
-                          line={
-                              "dash": "solid",
-                              "color": self._next_color(),
-                              "shape": "linear",
-                              "width": 1
-                          },
-                          text=labels)
-
-    def _get_split_guest_cpu_graphs(self, report, starttime):
-        threads = {}
-        for record in report._guest_timings._records:
-            if record._tid in threads:
-                continue
-            threads[record._tid] = {
-                "xaxis": [],
-                "yaxis": [],
-                "labels": [],
-            }
-
-        progress_idx = -1
-        for record in report._guest_timings._records:
-            while ((progress_idx + 1) < len(report._progress_history) and
-                   report._progress_history[progress_idx + 1]._now < record._timestamp):
-                progress_idx = progress_idx + 1
-
-            if progress_idx >= 0:
-                progress = report._progress_history[progress_idx]
-            else:
-                progress = None
-
-            threads[record._tid]["xaxis"].append(record._timestamp - starttime)
-            threads[record._tid]["yaxis"].append(record._value)
-            threads[record._tid]["labels"].append(self._get_progress_label(progress))
-
-
-        graphs = []
-        from plotly import graph_objs as go
-        for tid in threads.keys():
-            graphs.append(
-                go.Scatter(x=threads[tid]["xaxis"],
-                           y=threads[tid]["yaxis"],
-                           name="PID %s: %s" % (tid, report._scenario._name),
-                           mode="lines",
-                           line={
-                               "dash": "solid",
-                               "color": self._next_color(),
-                               "shape": "linear",
-                               "width": 1
-                           },
-                           text=threads[tid]["labels"]))
-        return graphs
-
-    def _get_migration_iters_graph(self, report, starttime):
-        xaxis = []
-        yaxis = []
-        labels = []
-        for progress in report._progress_history:
-            xaxis.append(progress._now - starttime)
-            yaxis.append(0)
-            labels.append(self._get_progress_label(progress))
-
-        from plotly import graph_objs as go
-        return go.Scatter(x=xaxis,
-                          y=yaxis,
-                          text=labels,
-                          name="Migration iterations",
-                          mode="markers",
-                          marker={
-                              "color": self._next_color(),
-                              "symbol": "star",
-                              "size": 5
-                          })
-
-    def _get_qemu_cpu_graph(self, report, starttime):
-        xaxis = []
-        yaxis = []
-        labels = []
-        progress_idx = -1
-
-        first = report._qemu_timings._records[0]
-        abstimestamps = [first._timestamp]
-        absvalues = [first._value]
-
-        for record in report._qemu_timings._records[1:]:
-            while ((progress_idx + 1) < len(report._progress_history) and
-                   report._progress_history[progress_idx + 1]._now < record._timestamp):
-                progress_idx = progress_idx + 1
-
-            if progress_idx >= 0:
-                progress = report._progress_history[progress_idx]
-            else:
-                progress = None
-
-            oldvalue = absvalues[-1]
-            oldtime = abstimestamps[-1]
-
-            cpudelta = (record._value - oldvalue) / 1000.0
-            timedelta = record._timestamp - oldtime
-            if timedelta == 0:
-                continue
-            util = cpudelta / timedelta * 100.0
-
-            abstimestamps.append(record._timestamp)
-            absvalues.append(record._value)
-
-            xaxis.append(record._timestamp - starttime)
-            yaxis.append(util)
-            labels.append(self._get_progress_label(progress))
-
-        from plotly import graph_objs as go
-        return go.Scatter(x=xaxis,
-                          y=yaxis,
-                          yaxis="y2",
-                          name="QEMU: %s" % report._scenario._name,
-                          mode='lines',
-                          line={
-                              "dash": "solid",
-                              "color": self._next_color(),
-                              "shape": "linear",
-                              "width": 1
-                          },
-                          text=labels)
-
-    def _get_vcpu_cpu_graphs(self, report, starttime):
-        threads = {}
-        for record in report._vcpu_timings._records:
-            if record._tid in threads:
-                continue
-            threads[record._tid] = {
-                "xaxis": [],
-                "yaxis": [],
-                "labels": [],
-                "absvalue": [record._value],
-                "abstime": [record._timestamp],
-            }
-
-        progress_idx = -1
-        for record in report._vcpu_timings._records:
-            while ((progress_idx + 1) < len(report._progress_history) and
-                   report._progress_history[progress_idx + 1]._now < record._timestamp):
-                progress_idx = progress_idx + 1
-
-            if progress_idx >= 0:
-                progress = report._progress_history[progress_idx]
-            else:
-                progress = None
-
-            oldvalue = threads[record._tid]["absvalue"][-1]
-            oldtime = threads[record._tid]["abstime"][-1]
-
-            cpudelta = (record._value - oldvalue) / 1000.0
-            timedelta = record._timestamp - oldtime
-            if timedelta == 0:
-                continue
-            util = cpudelta / timedelta * 100.0
-            if util > 100:
-                util = 100
-
-            threads[record._tid]["absvalue"].append(record._value)
-            threads[record._tid]["abstime"].append(record._timestamp)
-
-            threads[record._tid]["xaxis"].append(record._timestamp - starttime)
-            threads[record._tid]["yaxis"].append(util)
-            threads[record._tid]["labels"].append(self._get_progress_label(progress))
-
-
-        graphs = []
-        from plotly import graph_objs as go
-        for tid in threads.keys():
-            graphs.append(
-                go.Scatter(x=threads[tid]["xaxis"],
-                           y=threads[tid]["yaxis"],
-                           yaxis="y2",
-                           name="VCPU %s: %s" % (tid, report._scenario._name),
-                           mode="lines",
-                           line={
-                               "dash": "solid",
-                               "color": self._next_color(),
-                               "shape": "linear",
-                               "width": 1
-                           },
-                           text=threads[tid]["labels"]))
-        return graphs
-
-    def _generate_chart_report(self, report):
-        graphs = []
-        starttime = self._find_start_time(report)
-        if self._total_guest_cpu:
-            graphs.append(self._get_total_guest_cpu_graph(report, starttime))
-        if self._split_guest_cpu:
-            graphs.extend(self._get_split_guest_cpu_graphs(report, starttime))
-        if self._qemu_cpu:
-            graphs.append(self._get_qemu_cpu_graph(report, starttime))
-        if self._vcpu_cpu:
-            graphs.extend(self._get_vcpu_cpu_graphs(report, starttime))
-        if self._migration_iters:
-            graphs.append(self._get_migration_iters_graph(report, starttime))
-        return graphs
-
-    def _generate_annotation(self, starttime, progress):
-        return {
-            "text": progress._status,
-            "x": progress._now - starttime,
-            "y": 10,
-        }
-
-    def _generate_annotations(self, report):
-        starttime = self._find_start_time(report)
-        annotations = {}
-        started = False
-        for progress in report._progress_history:
-            if progress._status == "setup":
-                continue
-            if progress._status not in annotations:
-                annotations[progress._status] = self._generate_annotation(starttime, progress)
-
-        return annotations.values()
-
-    def _generate_chart(self):
-        from plotly.offline import plot
-        from plotly import graph_objs as go
-
-        graphs = []
-        yaxismax = 0
-        yaxismax2 = 0
-        for report in self._reports:
-            graphs.extend(self._generate_chart_report(report))
-
-            maxvalue = self._get_guest_max_value(report)
-            if maxvalue > yaxismax:
-                yaxismax = maxvalue
-
-            maxvalue = self._get_qemu_max_value(report)
-            if maxvalue > yaxismax2:
-                yaxismax2 = maxvalue
-
-        yaxismax += 100
-        if not self._qemu_cpu:
-            yaxismax2 = 110
-        yaxismax2 += 10
-
-        annotations = []
-        if self._migration_iters:
-            for report in self._reports:
-                annotations.extend(self._generate_annotations(report))
-
-        layout = go.Layout(title="Migration comparison",
-                           xaxis={
-                               "title": "Wallclock time (secs)",
-                               "showgrid": False,
-                           },
-                           yaxis={
-                               "title": "Memory update speed (ms/GB)",
-                               "showgrid": False,
-                               "range": [0, yaxismax],
-                           },
-                           yaxis2={
-                               "title": "Hostutilization (%)",
-                               "overlaying": "y",
-                               "side": "right",
-                               "range": [0, yaxismax2],
-                               "showgrid": False,
-                           },
-                           annotations=annotations)
-
-        figure = go.Figure(data=graphs, layout=layout)
-
-        return plot(figure,
-                    show_link=False,
-                    include_plotlyjs=False,
-                    output_type="div")
-
-
-    def _generate_report(self):
-        pieces = []
-        for report in self._reports:
-            pieces.append("""
-<h3>Report %s</h3>
-<table>
-""" % report._scenario._name)
-
-            pieces.append("""
-  <tr class="subhead">
-    <th colspan="2">Test config</th>
-  </tr>
-  <tr>
-    <th>Emulator:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>Kernel:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>Ramdisk:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>Transport:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>Host:</th>
-    <td>%s</td>
-  </tr>
-""" % (report._binary, report._kernel,
-       report._initrd, report._transport, report._dst_host))
-
-            hardware = report._hardware
-            pieces.append("""
-  <tr class="subhead">
-    <th colspan="2">Hardware config</th>
-  </tr>
-  <tr>
-    <th>CPUs:</th>
-    <td>%d</td>
-  </tr>
-  <tr>
-    <th>RAM:</th>
-    <td>%d GB</td>
-  </tr>
-  <tr>
-    <th>Source CPU bind:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>Source RAM bind:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>Dest CPU bind:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>Dest RAM bind:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>Preallocate RAM:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>Locked RAM:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>Huge pages:</th>
-    <td>%s</td>
-  </tr>
-""" % (hardware._cpus, hardware._mem,
-       ",".join(hardware._src_cpu_bind),
-       ",".join(hardware._src_mem_bind),
-       ",".join(hardware._dst_cpu_bind),
-       ",".join(hardware._dst_mem_bind),
-       "yes" if hardware._prealloc_pages else "no",
-       "yes" if hardware._locked_pages else "no",
-       "yes" if hardware._huge_pages else "no"))
-
-            scenario = report._scenario
-            pieces.append("""
-  <tr class="subhead">
-    <th colspan="2">Scenario config</th>
-  </tr>
-  <tr>
-    <th>Max downtime:</th>
-    <td>%d milli-sec</td>
-  </tr>
-  <tr>
-    <th>Max bandwidth:</th>
-    <td>%d MB/sec</td>
-  </tr>
-  <tr>
-    <th>Max iters:</th>
-    <td>%d</td>
-  </tr>
-  <tr>
-    <th>Max time:</th>
-    <td>%d secs</td>
-  </tr>
-  <tr>
-    <th>Pause:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>Pause iters:</th>
-    <td>%d</td>
-  </tr>
-  <tr>
-    <th>Post-copy:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>Post-copy iters:</th>
-    <td>%d</td>
-  </tr>
-  <tr>
-    <th>Auto-converge:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>Auto-converge iters:</th>
-    <td>%d</td>
-  </tr>
-  <tr>
-    <th>MT compression:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>MT compression threads:</th>
-    <td>%d</td>
-  </tr>
-  <tr>
-    <th>XBZRLE compression:</th>
-    <td>%s</td>
-  </tr>
-  <tr>
-    <th>XBZRLE compression cache:</th>
-    <td>%d%% of RAM</td>
-  </tr>
-""" % (scenario._downtime, scenario._bandwidth,
-       scenario._max_iters, scenario._max_time,
-       "yes" if scenario._pause else "no", scenario._pause_iters,
-       "yes" if scenario._post_copy else "no", scenario._post_copy_iters,
-       "yes" if scenario._auto_converge else "no", scenario._auto_converge_step,
-       "yes" if scenario._compression_mt else "no", scenario._compression_mt_threads,
-       "yes" if scenario._compression_xbzrle else "no", scenario._compression_xbzrle_cache))
-
-            pieces.append("""
-</table>
-""")
-
-        return "\n".join(pieces)
-
-    def _generate_style(self):
-        return """
-#report table tr th {
-    text-align: right;
-}
-#report table tr td {
-    text-align: left;
-}
-#report table tr.subhead th {
-    background: rgb(192, 192, 192);
-    text-align: center;
-}
-
-"""
-
-    def generate_html(self, fh):
-        print >>fh, """<html>
-  <head>
-    <script type="text/javascript" src="plotly.min.js">
-    </script>
-    <style type="text/css">
-%s
-    </style>
-    <title>Migration report</title>
-  </head>
-  <body>
-    <h1>Migration report</h1>
-    <h2>Chart summary</h2>
-    <div id="chart">
-""" % self._generate_style()
-        print >>fh, self._generate_chart()
-        print >>fh, """
-    </div>
-    <h2>Report details</h2>
-    <div id="report">
-"""
-        print >>fh, self._generate_report()
-        print >>fh, """
-    </div>
-  </body>
-</html>
-"""
-
-    def generate(self, filename):
-        if filename is None:
-            self.generate_html(sys.stdout)
-        else:
-            with open(filename, "w") as fh:
-                self.generate_html(fh)
diff --git a/tests/migration/guestperf/progress.py b/tests/migration/guestperf/progress.py
deleted file mode 100644 (file)
index 46d2157..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-#
-# Migration test migration operation progress
-#
-# Copyright (c) 2016 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#
-
-
-class ProgressStats(object):
-
-    def __init__(self,
-                 transferred_bytes,
-                 remaining_bytes,
-                 total_bytes,
-                 duplicate_pages,
-                 skipped_pages,
-                 normal_pages,
-                 normal_bytes,
-                 dirty_rate_pps,
-                 transfer_rate_mbs,
-                 iterations):
-        self._transferred_bytes = transferred_bytes
-        self._remaining_bytes = remaining_bytes
-        self._total_bytes = total_bytes
-        self._duplicate_pages = duplicate_pages
-        self._skipped_pages = skipped_pages
-        self._normal_pages = normal_pages
-        self._normal_bytes = normal_bytes
-        self._dirty_rate_pps = dirty_rate_pps
-        self._transfer_rate_mbs = transfer_rate_mbs
-        self._iterations = iterations
-
-    def serialize(self):
-        return {
-            "transferred_bytes": self._transferred_bytes,
-            "remaining_bytes": self._remaining_bytes,
-            "total_bytes": self._total_bytes,
-            "duplicate_pages": self._duplicate_pages,
-            "skipped_pages": self._skipped_pages,
-            "normal_pages": self._normal_pages,
-            "normal_bytes": self._normal_bytes,
-            "dirty_rate_pps": self._dirty_rate_pps,
-            "transfer_rate_mbs": self._transfer_rate_mbs,
-            "iterations": self._iterations,
-        }
-
-    @classmethod
-    def deserialize(cls, data):
-        return cls(
-            data["transferred_bytes"],
-            data["remaining_bytes"],
-            data["total_bytes"],
-            data["duplicate_pages"],
-            data["skipped_pages"],
-            data["normal_pages"],
-            data["normal_bytes"],
-            data["dirty_rate_pps"],
-            data["transfer_rate_mbs"],
-            data["iterations"])
-
-
-class Progress(object):
-
-    def __init__(self,
-                 status,
-                 ram,
-                 now,
-                 duration,
-                 downtime,
-                 downtime_expected,
-                 setup_time,
-                 throttle_pcent):
-
-        self._status = status
-        self._ram = ram
-        self._now = now
-        self._duration = duration
-        self._downtime = downtime
-        self._downtime_expected = downtime_expected
-        self._setup_time = setup_time
-        self._throttle_pcent = throttle_pcent
-
-    def serialize(self):
-        return {
-            "status": self._status,
-            "ram": self._ram.serialize(),
-            "now": self._now,
-            "duration": self._duration,
-            "downtime": self._downtime,
-            "downtime_expected": self._downtime_expected,
-            "setup_time": self._setup_time,
-            "throttle_pcent": self._throttle_pcent,
-        }
-
-    @classmethod
-    def deserialize(cls, data):
-        return cls(
-            data["status"],
-            ProgressStats.deserialize(data["ram"]),
-            data["now"],
-            data["duration"],
-            data["downtime"],
-            data["downtime_expected"],
-            data["setup_time"],
-            data["throttle_pcent"])
diff --git a/tests/migration/guestperf/report.py b/tests/migration/guestperf/report.py
deleted file mode 100644 (file)
index 6a1f971..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-#
-# Migration test output result reporting
-#
-# Copyright (c) 2016 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#
-
-import json
-
-from guestperf.hardware import Hardware
-from guestperf.scenario import Scenario
-from guestperf.progress import Progress
-from guestperf.timings import Timings
-
-class Report(object):
-
-    def __init__(self,
-                 hardware,
-                 scenario,
-                 progress_history,
-                 guest_timings,
-                 qemu_timings,
-                 vcpu_timings,
-                 binary,
-                 dst_host,
-                 kernel,
-                 initrd,
-                 transport,
-                 sleep):
-
-        self._hardware = hardware
-        self._scenario = scenario
-        self._progress_history = progress_history
-        self._guest_timings = guest_timings
-        self._qemu_timings = qemu_timings
-        self._vcpu_timings = vcpu_timings
-        self._binary = binary
-        self._dst_host = dst_host
-        self._kernel = kernel
-        self._initrd = initrd
-        self._transport = transport
-        self._sleep = sleep
-
-    def serialize(self):
-        return {
-            "hardware": self._hardware.serialize(),
-            "scenario": self._scenario.serialize(),
-            "progress_history": [progress.serialize() for progress in self._progress_history],
-            "guest_timings": self._guest_timings.serialize(),
-            "qemu_timings": self._qemu_timings.serialize(),
-            "vcpu_timings": self._vcpu_timings.serialize(),
-            "binary": self._binary,
-            "dst_host": self._dst_host,
-            "kernel": self._kernel,
-            "initrd": self._initrd,
-            "transport": self._transport,
-            "sleep": self._sleep,
-        }
-
-    @classmethod
-    def deserialize(cls, data):
-        return cls(
-            Hardware.deserialize(data["hardware"]),
-            Scenario.deserialize(data["scenario"]),
-            [Progress.deserialize(record) for record in data["progress_history"]],
-            Timings.deserialize(data["guest_timings"]),
-            Timings.deserialize(data["qemu_timings"]),
-            Timings.deserialize(data["vcpu_timings"]),
-            data["binary"],
-            data["dst_host"],
-            data["kernel"],
-            data["initrd"],
-            data["transport"],
-            data["sleep"])
-
-    def to_json(self):
-        return json.dumps(self.serialize(), indent=4)
-
-    @classmethod
-    def from_json(cls, data):
-        return cls.deserialize(json.loads(data))
-
-    @classmethod
-    def from_json_file(cls, filename):
-        with open(filename, "r") as fh:
-            return cls.deserialize(json.load(fh))
diff --git a/tests/migration/guestperf/scenario.py b/tests/migration/guestperf/scenario.py
deleted file mode 100644 (file)
index 705c2e8..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-#
-# Migration test scenario parameter description
-#
-# Copyright (c) 2016 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#
-
-
-class Scenario(object):
-
-    def __init__(self, name,
-                 downtime=500,
-                 bandwidth=125000, # 1000 gig-e, effectively unlimited
-                 max_iters=30,
-                 max_time=300,
-                 pause=False, pause_iters=5,
-                 post_copy=False, post_copy_iters=5,
-                 auto_converge=False, auto_converge_step=10,
-                 compression_mt=False, compression_mt_threads=1,
-                 compression_xbzrle=False, compression_xbzrle_cache=10):
-
-        self._name = name
-
-        # General migration tunables
-        self._downtime = downtime  # milliseconds
-        self._bandwidth = bandwidth # MiB per second
-        self._max_iters = max_iters
-        self._max_time = max_time # seconds
-
-
-        # Strategies for ensuring completion
-        self._pause = pause
-        self._pause_iters = pause_iters
-
-        self._post_copy = post_copy
-        self._post_copy_iters = post_copy_iters
-
-        self._auto_converge = auto_converge
-        self._auto_converge_step = auto_converge_step # percentage CPU time
-
-        self._compression_mt = compression_mt
-        self._compression_mt_threads = compression_mt_threads
-
-        self._compression_xbzrle = compression_xbzrle
-        self._compression_xbzrle_cache = compression_xbzrle_cache # percentage of guest RAM
-
-    def serialize(self):
-        return {
-            "name": self._name,
-            "downtime": self._downtime,
-            "bandwidth": self._bandwidth,
-            "max_iters": self._max_iters,
-            "max_time": self._max_time,
-            "pause": self._pause,
-            "pause_iters": self._pause_iters,
-            "post_copy": self._post_copy,
-            "post_copy_iters": self._post_copy_iters,
-            "auto_converge": self._auto_converge,
-            "auto_converge_step": self._auto_converge_step,
-            "compression_mt": self._compression_mt,
-            "compression_mt_threads": self._compression_mt_threads,
-            "compression_xbzrle": self._compression_xbzrle,
-            "compression_xbzrle_cache": self._compression_xbzrle_cache,
-        }
-
-    @classmethod
-    def deserialize(cls, data):
-        return cls(
-            data["name"],
-            data["downtime"],
-            data["bandwidth"],
-            data["max_iters"],
-            data["max_time"],
-            data["pause"],
-            data["pause_iters"],
-            data["post_copy"],
-            data["post_copy_iters"],
-            data["auto_converge"],
-            data["auto_converge_step"],
-            data["compression_mt"],
-            data["compression_mt_threads"],
-            data["compression_xbzrle"],
-            data["compression_xbzrle_cache"])
diff --git a/tests/migration/guestperf/shell.py b/tests/migration/guestperf/shell.py
deleted file mode 100644 (file)
index 185c569..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-#
-# Migration test command line shell integration
-#
-# Copyright (c) 2016 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#
-
-
-import argparse
-import fnmatch
-import os
-import os.path
-import platform
-import sys
-
-from guestperf.hardware import Hardware
-from guestperf.engine import Engine
-from guestperf.scenario import Scenario
-from guestperf.comparison import COMPARISONS
-from guestperf.plot import Plot
-from guestperf.report import Report
-
-
-class BaseShell(object):
-
-    def __init__(self):
-        parser = argparse.ArgumentParser(description="Migration Test Tool")
-
-        # Test args
-        parser.add_argument("--debug", dest="debug", default=False, action="store_true")
-        parser.add_argument("--verbose", dest="verbose", default=False, action="store_true")
-        parser.add_argument("--sleep", dest="sleep", default=15, type=int)
-        parser.add_argument("--binary", dest="binary", default="/usr/bin/qemu-system-x86_64")
-        parser.add_argument("--dst-host", dest="dst_host", default="localhost")
-        parser.add_argument("--kernel", dest="kernel", default="/boot/vmlinuz-%s" % platform.release())
-        parser.add_argument("--initrd", dest="initrd", default="tests/migration/initrd-stress.img")
-        parser.add_argument("--transport", dest="transport", default="unix")
-
-
-        # Hardware args
-        parser.add_argument("--cpus", dest="cpus", default=1, type=int)
-        parser.add_argument("--mem", dest="mem", default=1, type=int)
-        parser.add_argument("--src-cpu-bind", dest="src_cpu_bind", default="")
-        parser.add_argument("--src-mem-bind", dest="src_mem_bind", default="")
-        parser.add_argument("--dst-cpu-bind", dest="dst_cpu_bind", default="")
-        parser.add_argument("--dst-mem-bind", dest="dst_mem_bind", default="")
-        parser.add_argument("--prealloc-pages", dest="prealloc_pages", default=False)
-        parser.add_argument("--huge-pages", dest="huge_pages", default=False)
-        parser.add_argument("--locked-pages", dest="locked_pages", default=False)
-
-        self._parser = parser
-
-    def get_engine(self, args):
-        return Engine(binary=args.binary,
-                      dst_host=args.dst_host,
-                      kernel=args.kernel,
-                      initrd=args.initrd,
-                      transport=args.transport,
-                      sleep=args.sleep,
-                      debug=args.debug,
-                      verbose=args.verbose)
-
-    def get_hardware(self, args):
-        def split_map(value):
-            if value == "":
-                return []
-            return value.split(",")
-
-        return Hardware(cpus=args.cpus,
-                        mem=args.mem,
-
-                        src_cpu_bind=split_map(args.src_cpu_bind),
-                        src_mem_bind=split_map(args.src_mem_bind),
-                        dst_cpu_bind=split_map(args.dst_cpu_bind),
-                        dst_mem_bind=split_map(args.dst_mem_bind),
-
-                        locked_pages=args.locked_pages,
-                        huge_pages=args.huge_pages,
-                        prealloc_pages=args.prealloc_pages)
-
-
-class Shell(BaseShell):
-
-    def __init__(self):
-        super(Shell, self).__init__()
-
-        parser = self._parser
-
-        parser.add_argument("--output", dest="output", default=None)
-
-        # Scenario args
-        parser.add_argument("--max-iters", dest="max_iters", default=30, type=int)
-        parser.add_argument("--max-time", dest="max_time", default=300, type=int)
-        parser.add_argument("--bandwidth", dest="bandwidth", default=125000, type=int)
-        parser.add_argument("--downtime", dest="downtime", default=500, type=int)
-
-        parser.add_argument("--pause", dest="pause", default=False, action="store_true")
-        parser.add_argument("--pause-iters", dest="pause_iters", default=5, type=int)
-
-        parser.add_argument("--post-copy", dest="post_copy", default=False, action="store_true")
-        parser.add_argument("--post-copy-iters", dest="post_copy_iters", default=5, type=int)
-
-        parser.add_argument("--auto-converge", dest="auto_converge", default=False, action="store_true")
-        parser.add_argument("--auto-converge-step", dest="auto_converge_step", default=10, type=int)
-
-        parser.add_argument("--compression-mt", dest="compression_mt", default=False, action="store_true")
-        parser.add_argument("--compression-mt-threads", dest="compression_mt_threads", default=1, type=int)
-
-        parser.add_argument("--compression-xbzrle", dest="compression_xbzrle", default=False, action="store_true")
-        parser.add_argument("--compression-xbzrle-cache", dest="compression_xbzrle_cache", default=10, type=int)
-
-    def get_scenario(self, args):
-        return Scenario(name="perfreport",
-                        downtime=args.downtime,
-                        bandwidth=args.bandwidth,
-                        max_iters=args.max_iters,
-                        max_time=args.max_time,
-
-                        pause=args.pause,
-                        pause_iters=args.pause_iters,
-
-                        post_copy=args.post_copy,
-                        post_copy_iters=args.post_copy_iters,
-
-                        auto_converge=args.auto_converge,
-                        auto_converge_step=args.auto_converge_step,
-
-                        compression_mt=args.compression_mt,
-                        compression_mt_threads=args.compression_mt_threads,
-
-                        compression_xbzrle=args.compression_xbzrle,
-                        compression_xbzrle_cache=args.compression_xbzrle_cache)
-
-    def run(self, argv):
-        args = self._parser.parse_args(argv)
-
-        engine = self.get_engine(args)
-        hardware = self.get_hardware(args)
-        scenario = self.get_scenario(args)
-
-        try:
-            report = engine.run(hardware, scenario)
-            if args.output is None:
-                print report.to_json()
-            else:
-                with open(args.output, "w") as fh:
-                    print >>fh, report.to_json()
-            return 0
-        except Exception as e:
-            print >>sys.stderr, "Error: %s" % str(e)
-            if args.debug:
-                raise
-            return 1
-
-
-class BatchShell(BaseShell):
-
-    def __init__(self):
-        super(BatchShell, self).__init__()
-
-        parser = self._parser
-
-        parser.add_argument("--filter", dest="filter", default="*")
-        parser.add_argument("--output", dest="output", default=os.getcwd())
-
-    def run(self, argv):
-        args = self._parser.parse_args(argv)
-
-        engine = self.get_engine(args)
-        hardware = self.get_hardware(args)
-
-        try:
-            for comparison in COMPARISONS:
-                compdir = os.path.join(args.output, comparison._name)
-                for scenario in comparison._scenarios:
-                    name = os.path.join(comparison._name, scenario._name)
-                    if not fnmatch.fnmatch(name, args.filter):
-                        if args.verbose:
-                            print "Skipping %s" % name
-                        continue
-
-                    if args.verbose:
-                        print "Running %s" % name
-
-                    dirname = os.path.join(args.output, comparison._name)
-                    filename = os.path.join(dirname, scenario._name + ".json")
-                    if not os.path.exists(dirname):
-                        os.makedirs(dirname)
-                    report = engine.run(hardware, scenario)
-                    with open(filename, "w") as fh:
-                        print >>fh, report.to_json()
-        except Exception as e:
-            print >>sys.stderr, "Error: %s" % str(e)
-            if args.debug:
-                raise
-
-
-class PlotShell(object):
-
-    def __init__(self):
-        super(PlotShell, self).__init__()
-
-        self._parser = argparse.ArgumentParser(description="Migration Test Tool")
-
-        self._parser.add_argument("--output", dest="output", default=None)
-
-        self._parser.add_argument("--debug", dest="debug", default=False, action="store_true")
-        self._parser.add_argument("--verbose", dest="verbose", default=False, action="store_true")
-
-        self._parser.add_argument("--migration-iters", dest="migration_iters", default=False, action="store_true")
-        self._parser.add_argument("--total-guest-cpu", dest="total_guest_cpu", default=False, action="store_true")
-        self._parser.add_argument("--split-guest-cpu", dest="split_guest_cpu", default=False, action="store_true")
-        self._parser.add_argument("--qemu-cpu", dest="qemu_cpu", default=False, action="store_true")
-        self._parser.add_argument("--vcpu-cpu", dest="vcpu_cpu", default=False, action="store_true")
-
-        self._parser.add_argument("reports", nargs='*')
-
-    def run(self, argv):
-        args = self._parser.parse_args(argv)
-
-        if len(args.reports) == 0:
-            print >>sys.stderr, "At least one report required"
-            return 1
-
-        if not (args.qemu_cpu or
-                args.vcpu_cpu or
-                args.total_guest_cpu or
-                args.split_guest_cpu):
-            print >>sys.stderr, "At least one chart type is required"
-            return 1
-
-        reports = []
-        for report in args.reports:
-            reports.append(Report.from_json_file(report))
-
-        plot = Plot(reports,
-                    args.migration_iters,
-                    args.total_guest_cpu,
-                    args.split_guest_cpu,
-                    args.qemu_cpu,
-                    args.vcpu_cpu)
-
-        plot.generate(args.output)
diff --git a/tests/migration/guestperf/timings.py b/tests/migration/guestperf/timings.py
deleted file mode 100644 (file)
index f94d809..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#
-# Migration test timing records
-#
-# Copyright (c) 2016 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, see <http://www.gnu.org/licenses/>.
-#
-
-
-class TimingRecord(object):
-
-    def __init__(self, tid, timestamp, value):
-
-        self._tid = tid
-        self._timestamp = timestamp
-        self._value = value
-
-    def serialize(self):
-        return {
-            "tid": self._tid,
-            "timestamp": self._timestamp,
-            "value": self._value
-        }
-
-    @classmethod
-    def deserialize(cls, data):
-        return cls(
-            data["tid"],
-            data["timestamp"],
-            data["value"])
-
-
-class Timings(object):
-
-    def __init__(self, records):
-
-        self._records = records
-
-    def serialize(self):
-        return [record.serialize() for record in self._records]
-
-    @classmethod
-    def deserialize(cls, data):
-        return Timings([TimingRecord.deserialize(record) for record in data])
diff --git a/tests/migration/stress.c b/tests/migration/stress.c
deleted file mode 100644 (file)
index cf8ce8b..0000000
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Migration stress workload
- *
- * Copyright (c) 2016 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <getopt.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/reboot.h>
-#include <sys/syscall.h>
-#include <linux/random.h>
-#include <sys/time.h>
-#include <pthread.h>
-#include <fcntl.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-const char *argv0;
-
-#define PAGE_SIZE 4096
-
-static int gettid(void)
-{
-    return syscall(SYS_gettid);
-}
-
-static __attribute__((noreturn)) void exit_failure(void)
-{
-    if (getpid() == 1) {
-        sync();
-        reboot(RB_POWER_OFF);
-        fprintf(stderr, "%s (%05d): ERROR: cannot reboot: %s\n",
-                argv0, gettid(), strerror(errno));
-        abort();
-    } else {
-        exit(1);
-    }
-}
-
-static __attribute__((noreturn)) void exit_success(void)
-{
-    if (getpid() == 1) {
-        sync();
-        reboot(RB_POWER_OFF);
-        fprintf(stderr, "%s (%05d): ERROR: cannot reboot: %s\n",
-                argv0, gettid(), strerror(errno));
-        abort();
-    } else {
-        exit(0);
-    }
-}
-
-static int get_command_arg_str(const char *name,
-                               char **val)
-{
-    static char line[1024];
-    FILE *fp = fopen("/proc/cmdline", "r");
-    char *start, *end;
-
-    if (fp == NULL) {
-        fprintf(stderr, "%s (%05d): ERROR: cannot open /proc/cmdline: %s\n",
-                argv0, gettid(), strerror(errno));
-        return -1;
-    }
-
-    if (!fgets(line, sizeof line, fp)) {
-        fprintf(stderr, "%s (%05d): ERROR: cannot read /proc/cmdline: %s\n",
-                argv0, gettid(), strerror(errno));
-        fclose(fp);
-        return -1;
-    }
-    fclose(fp);
-
-    start = strstr(line, name);
-    if (!start)
-        return 0;
-
-    start += strlen(name);
-
-    if (*start != '=') {
-        fprintf(stderr, "%s (%05d): ERROR: no value provided for '%s' in /proc/cmdline\n",
-                argv0, gettid(), name);
-    }
-    start++;
-
-    end = strstr(start, " ");
-    if (!end)
-        end = strstr(start, "\n");
-
-    if (end == start) {
-        fprintf(stderr, "%s (%05d): ERROR: no value provided for '%s' in /proc/cmdline\n",
-                argv0, gettid(), name);
-        return -1;
-    }
-
-    if (end)
-        *val = strndup(start, end - start);
-    else
-        *val = strdup(start);
-    return 1;
-}
-
-
-static int get_command_arg_ull(const char *name,
-                               unsigned long long *val)
-{
-    char *valstr;
-    char *end;
-
-    int ret = get_command_arg_str(name, &valstr);
-    if (ret <= 0)
-        return ret;
-
-    errno = 0;
-    *val = strtoll(valstr, &end, 10);
-    if (errno || *end) {
-        fprintf(stderr, "%s (%05d): ERROR: cannot parse %s value %s\n",
-                argv0, gettid(), name, valstr);
-        free(valstr);
-        return -1;
-    }
-    free(valstr);
-    return 0;
-}
-
-
-static int random_bytes(char *buf, size_t len)
-{
-    int fd;
-
-    fd = open("/dev/urandom", O_RDONLY);
-    if (fd < 0) {
-        fprintf(stderr, "%s (%05d): ERROR: cannot open /dev/urandom: %s\n",
-                argv0, gettid(), strerror(errno));
-        return -1;
-    }
-
-    if (read(fd, buf, len) != len) {
-        fprintf(stderr, "%s (%05d): ERROR: cannot read /dev/urandom: %s\n",
-                argv0, gettid(), strerror(errno));
-        close(fd);
-        return -1;
-    }
-
-    close(fd);
-
-    return 0;
-}
-
-
-static unsigned long long now(void)
-{
-    struct timeval tv;
-
-    gettimeofday(&tv, NULL);
-
-    return (tv.tv_sec * 1000ull) + (tv.tv_usec / 1000ull);
-}
-
-static int stressone(unsigned long long ramsizeMB)
-{
-    size_t pagesPerMB = 1024 * 1024 / PAGE_SIZE;
-    char *ram = malloc(ramsizeMB * 1024 * 1024);
-    char *ramptr;
-    size_t i, j, k;
-    char *data = malloc(PAGE_SIZE);
-    char *dataptr;
-    size_t nMB = 0;
-    unsigned long long before, after;
-
-    if (!ram) {
-        fprintf(stderr, "%s (%05d): ERROR: cannot allocate %llu MB of RAM: %s\n",
-                argv0, gettid(), ramsizeMB, strerror(errno));
-        return -1;
-    }
-    if (!data) {
-        fprintf(stderr, "%s (%d): ERROR: cannot allocate %d bytes of RAM: %s\n",
-                argv0, gettid(), PAGE_SIZE, strerror(errno));
-        free(ram);
-        return -1;
-    }
-
-    /* We don't care about initial state, but we do want
-     * to fault it all into RAM, otherwise the first iter
-     * of the loop below will be quite slow. We cna't use
-     * 0x0 as the byte as gcc optimizes that away into a
-     * calloc instead :-) */
-    memset(ram, 0xfe, ramsizeMB * 1024 * 1024);
-
-    if (random_bytes(data, PAGE_SIZE) < 0) {
-        free(ram);
-        free(data);
-        return -1;
-    }
-
-    before = now();
-
-    while (1) {
-
-        ramptr = ram;
-        for (i = 0; i < ramsizeMB; i++, nMB++) {
-            for (j = 0; j < pagesPerMB; j++) {
-                dataptr = data;
-                for (k = 0; k < PAGE_SIZE; k += sizeof(long long)) {
-                    ramptr += sizeof(long long);
-                    dataptr += sizeof(long long);
-                    *(unsigned long long *)ramptr ^= *(unsigned long long *)dataptr;
-                }
-            }
-
-            if (nMB == 1024) {
-                after = now();
-                fprintf(stderr, "%s (%05d): INFO: %06llums copied 1 GB in %05llums\n",
-                        argv0, gettid(), after, after - before);
-                before = now();
-                nMB = 0;
-            }
-        }
-    }
-
-    free(data);
-    free(ram);
-}
-
-
-static void *stressthread(void *arg)
-{
-    unsigned long long ramsizeMB = *(unsigned long long *)arg;
-
-    stressone(ramsizeMB);
-
-    return NULL;
-}
-
-static int stress(unsigned long long ramsizeGB, int ncpus)
-{
-    size_t i;
-    unsigned long long ramsizeMB = ramsizeGB * 1024 / ncpus;
-    ncpus--;
-
-    for (i = 0; i < ncpus; i++) {
-        pthread_t thr;
-        pthread_create(&thr, NULL,
-                       stressthread,   &ramsizeMB);
-    }
-
-    stressone(ramsizeMB);
-
-    return 0;
-}
-
-
-static int mount_misc(const char *fstype, const char *dir)
-{
-    if (mkdir(dir, 0755) < 0 && errno != EEXIST) {
-        fprintf(stderr, "%s (%05d): ERROR: cannot create %s: %s\n",
-                argv0, gettid(), dir, strerror(errno));
-        return -1;
-    }
-
-    if (mount("none", dir, fstype, 0, NULL) < 0) {
-        fprintf(stderr, "%s (%05d): ERROR: cannot mount %s: %s\n",
-                argv0, gettid(), dir, strerror(errno));
-        return -1;
-    }
-
-    return 0;
-}
-
-static int mount_all(void)
-{
-    if (mount_misc("proc", "/proc") < 0 ||
-        mount_misc("sysfs", "/sys") < 0 ||
-        mount_misc("tmpfs", "/dev") < 0)
-        return -1;
-
-    mknod("/dev/urandom", 0777 | S_IFCHR, makedev(1, 9));
-    mknod("/dev/random", 0777 | S_IFCHR, makedev(1, 8));
-
-    return 0;
-}
-
-int main(int argc, char **argv)
-{
-    unsigned long long ramsizeGB = 1;
-    char *end;
-    int ch;
-    int opt_ind = 0;
-    const char *sopt = "hr:c:";
-    struct option lopt[] = {
-        { "help", no_argument, NULL, 'h' },
-        { "ramsize", required_argument, NULL, 'r' },
-        { "cpus", required_argument, NULL, 'c' },
-        { NULL, 0, NULL, 0 }
-    };
-    int ret;
-    int ncpus = 0;
-
-    argv0 = argv[0];
-
-    while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
-        switch (ch) {
-        case 'r':
-            errno = 0;
-            ramsizeGB = strtoll(optarg, &end, 10);
-            if (errno != 0 || *end) {
-                fprintf(stderr, "%s (%05d): ERROR: Cannot parse RAM size %s\n",
-                        argv0, gettid(), optarg);
-                exit_failure();
-            }
-            break;
-
-        case 'c':
-            errno = 0;
-            ncpus = strtoll(optarg, &end, 10);
-            if (errno != 0 || *end) {
-                fprintf(stderr, "%s (%05d): ERROR: Cannot parse CPU count %s\n",
-                        argv0, gettid(), optarg);
-                exit_failure();
-            }
-            break;
-
-        case '?':
-        case 'h':
-            fprintf(stderr, "%s: [--help][--ramsize GB][--cpus N]\n", argv0);
-            exit_failure();
-        }
-    }
-
-    if (getpid() == 1) {
-        if (mount_all() < 0)
-            exit_failure();
-
-        ret = get_command_arg_ull("ramsize", &ramsizeGB);
-        if (ret < 0)
-            exit_failure();
-    }
-
-    if (ncpus == 0)
-        ncpus = sysconf(_SC_NPROCESSORS_ONLN);
-
-    fprintf(stdout, "%s (%05d): INFO: RAM %llu GiB across %d CPUs\n",
-            argv0, gettid(), ramsizeGB, ncpus);
-
-    if (stress(ramsizeGB, ncpus) < 0)
-        exit_failure();
-
-    exit_success();
-}
index b7cf3dd..3727875 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
index c8bece4..ec06893 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
index 4428cea..6b34ca5 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu-common.h"
 #include "libqtest.h"
index efb1ef4..2ddf496 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
diff --git a/tests/postcopy-test.c b/tests/postcopy-test.c
deleted file mode 100644 (file)
index 229e9e9..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * QTest testcase for postcopy
- *
- * Copyright (c) 2016 Red Hat, Inc. and/or its affiliates
- *   based on the vhost-user-test.c that is:
- *      Copyright (c) 2014 Virtual Open Systems Sarl.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-
-#include "libqtest.h"
-#include "qemu/option.h"
-#include "qemu/range.h"
-#include "qemu/sockets.h"
-#include "sysemu/char.h"
-#include "sysemu/sysemu.h"
-#include "hw/nvram/openbios_firmware_abi.h"
-
-#define MIN_NVRAM_SIZE 8192 /* from spapr_nvram.c */
-
-const unsigned start_address = 1024 * 1024;
-const unsigned end_address = 100 * 1024 * 1024;
-bool got_stop;
-
-#if defined(__linux__)
-#include <sys/syscall.h>
-#include <sys/vfs.h>
-#endif
-
-#if defined(__linux__) && defined(__NR_userfaultfd) && defined(CONFIG_EVENTFD)
-#include <sys/eventfd.h>
-#include <sys/ioctl.h>
-#include <linux/userfaultfd.h>
-
-static bool ufd_version_check(void)
-{
-    struct uffdio_api api_struct;
-    uint64_t ioctl_mask;
-
-    int ufd = ufd = syscall(__NR_userfaultfd, O_CLOEXEC);
-
-    if (ufd == -1) {
-        g_test_message("Skipping test: userfaultfd not available");
-        return false;
-    }
-
-    api_struct.api = UFFD_API;
-    api_struct.features = 0;
-    if (ioctl(ufd, UFFDIO_API, &api_struct)) {
-        g_test_message("Skipping test: UFFDIO_API failed");
-        return false;
-    }
-
-    ioctl_mask = (__u64)1 << _UFFDIO_REGISTER |
-                 (__u64)1 << _UFFDIO_UNREGISTER;
-    if ((api_struct.ioctls & ioctl_mask) != ioctl_mask) {
-        g_test_message("Skipping test: Missing userfault feature");
-        return false;
-    }
-
-    return true;
-}
-
-#else
-static bool ufd_version_check(void)
-{
-    g_test_message("Skipping test: Userfault not available (builtdtime)");
-    return false;
-}
-
-#endif
-
-static const char *tmpfs;
-
-/* A simple PC boot sector that modifies memory (1-100MB) quickly
- * outputing a 'B' every so often if it's still running.
- */
-unsigned char bootsect[] = {
-  0xfa, 0x0f, 0x01, 0x16, 0x74, 0x7c, 0x66, 0xb8, 0x01, 0x00, 0x00, 0x00,
-  0x0f, 0x22, 0xc0, 0x66, 0xea, 0x20, 0x7c, 0x00, 0x00, 0x08, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x92, 0x0c, 0x02,
-  0xe6, 0x92, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x8e, 0xd8, 0x66, 0xb8, 0x41,
-  0x00, 0x66, 0xba, 0xf8, 0x03, 0xee, 0xb3, 0x00, 0xb8, 0x00, 0x00, 0x10,
-  0x00, 0xfe, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x40,
-  0x06, 0x7c, 0xf2, 0xfe, 0xc3, 0x75, 0xe9, 0x66, 0xb8, 0x42, 0x00, 0x66,
-  0xba, 0xf8, 0x03, 0xee, 0xeb, 0xde, 0x66, 0x90, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00,
-  0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00, 0x27, 0x00, 0x5c, 0x7c,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
-};
-
-static void init_bootfile_x86(const char *bootpath)
-{
-    FILE *bootfile = fopen(bootpath, "wb");
-
-    g_assert_cmpint(fwrite(bootsect, 512, 1, bootfile), ==, 1);
-    fclose(bootfile);
-}
-
-static void init_bootfile_ppc(const char *bootpath)
-{
-    FILE *bootfile;
-    char buf[MIN_NVRAM_SIZE];
-    struct OpenBIOS_nvpart_v1 *header = (struct OpenBIOS_nvpart_v1 *)buf;
-
-    memset(buf, 0, MIN_NVRAM_SIZE);
-
-    /* Create a "common" partition in nvram to store boot-command property */
-
-    header->signature = OPENBIOS_PART_SYSTEM;
-    memcpy(header->name, "common", 6);
-    OpenBIOS_finish_partition(header, MIN_NVRAM_SIZE);
-
-    /* FW_MAX_SIZE is 4MB, but slof.bin is only 900KB,
-     * so let's modify memory between 1MB and 100MB
-     * to do like PC bootsector
-     */
-
-    sprintf(buf + 16,
-            "boot-command=hex .\" _\" begin %x %x do i c@ 1 + i c! 1000 +loop "
-            ".\" B\" 0 until", end_address, start_address);
-
-    /* Write partition to the NVRAM file */
-
-    bootfile = fopen(bootpath, "wb");
-    g_assert_cmpint(fwrite(buf, MIN_NVRAM_SIZE, 1, bootfile), ==, 1);
-    fclose(bootfile);
-}
-
-/*
- * Wait for some output in the serial output file,
- * we get an 'A' followed by an endless string of 'B's
- * but on the destination we won't have the A.
- */
-static void wait_for_serial(const char *side)
-{
-    char *serialpath = g_strdup_printf("%s/%s", tmpfs, side);
-    FILE *serialfile = fopen(serialpath, "r");
-    const char *arch = qtest_get_arch();
-    int started = (strcmp(side, "src_serial") == 0 &&
-                   strcmp(arch, "ppc64") == 0) ? 0 : 1;
-
-    do {
-        int readvalue = fgetc(serialfile);
-
-        if (!started) {
-            /* SLOF prints its banner before starting test,
-             * to ignore it, mark the start of the test with '_',
-             * ignore all characters until this marker
-             */
-            switch (readvalue) {
-            case '_':
-                started = 1;
-                break;
-            case EOF:
-                fseek(serialfile, 0, SEEK_SET);
-                usleep(1000);
-                break;
-            }
-            continue;
-        }
-        switch (readvalue) {
-        case 'A':
-            /* Fine */
-            break;
-
-        case 'B':
-            /* It's alive! */
-            fclose(serialfile);
-            g_free(serialpath);
-            return;
-
-        case EOF:
-            started = (strcmp(side, "src_serial") == 0 &&
-                       strcmp(arch, "ppc64") == 0) ? 0 : 1;
-            fseek(serialfile, 0, SEEK_SET);
-            usleep(1000);
-            break;
-
-        default:
-            fprintf(stderr, "Unexpected %d on %s serial\n", readvalue, side);
-            g_assert_not_reached();
-        }
-    } while (true);
-}
-
-/*
- * Events can get in the way of responses we are actually waiting for.
- */
-static QDict *return_or_event(QDict *response)
-{
-    const char *event_string;
-    if (!qdict_haskey(response, "event")) {
-        return response;
-    }
-
-    /* OK, it was an event */
-    event_string = qdict_get_str(response, "event");
-    if (!strcmp(event_string, "STOP")) {
-        got_stop = true;
-    }
-    QDECREF(response);
-    return return_or_event(qtest_qmp_receive(global_qtest));
-}
-
-
-/*
- * It's tricky to use qemu's migration event capability with qtest,
- * events suddenly appearing confuse the qmp()/hmp() responses.
- * so wait for a couple of passes to have happened before
- * going postcopy.
- */
-
-static uint64_t get_migration_pass(void)
-{
-    QDict *rsp, *rsp_return, *rsp_ram;
-    uint64_t result;
-
-    rsp = return_or_event(qmp("{ 'execute': 'query-migrate' }"));
-    rsp_return = qdict_get_qdict(rsp, "return");
-    if (!qdict_haskey(rsp_return, "ram")) {
-        /* Still in setup */
-        result = 0;
-    } else {
-        rsp_ram = qdict_get_qdict(rsp_return, "ram");
-        result = qdict_get_try_int(rsp_ram, "dirty-sync-count", 0);
-        QDECREF(rsp);
-    }
-    return result;
-}
-
-static void wait_for_migration_complete(void)
-{
-    QDict *rsp, *rsp_return;
-    bool completed;
-
-    do {
-        const char *status;
-
-        rsp = return_or_event(qmp("{ 'execute': 'query-migrate' }"));
-        rsp_return = qdict_get_qdict(rsp, "return");
-        status = qdict_get_str(rsp_return, "status");
-        completed = strcmp(status, "completed") == 0;
-        g_assert_cmpstr(status, !=,  "failed");
-        QDECREF(rsp);
-        usleep(1000 * 100);
-    } while (!completed);
-}
-
-static void wait_for_migration_pass(void)
-{
-    uint64_t initial_pass = get_migration_pass();
-    uint64_t pass;
-
-    /* Wait for the 1st sync */
-    do {
-        initial_pass = get_migration_pass();
-        if (got_stop || initial_pass) {
-            break;
-        }
-        usleep(1000 * 100);
-    } while (true);
-
-    do {
-        usleep(1000 * 100);
-        pass = get_migration_pass();
-    } while (pass == initial_pass && !got_stop);
-}
-
-static void check_guests_ram(void)
-{
-    /* Our ASM test will have been incrementing one byte from each page from
-     * 1MB to <100MB in order.
-     * This gives us a constraint that any page's byte should be equal or less
-     * than the previous pages byte (mod 256); and they should all be equal
-     * except for one transition at the point where we meet the incrementer.
-     * (We're running this with the guest stopped).
-     */
-    unsigned address;
-    uint8_t first_byte;
-    uint8_t last_byte;
-    bool hit_edge = false;
-    bool bad = false;
-
-    qtest_memread(global_qtest, start_address, &first_byte, 1);
-    last_byte = first_byte;
-
-    for (address = start_address + 4096; address < end_address; address += 4096)
-    {
-        uint8_t b;
-        qtest_memread(global_qtest, address, &b, 1);
-        if (b != last_byte) {
-            if (((b + 1) % 256) == last_byte && !hit_edge) {
-                /* This is OK, the guest stopped at the point of
-                 * incrementing the previous page but didn't get
-                 * to us yet.
-                 */
-                hit_edge = true;
-            } else {
-                fprintf(stderr, "Memory content inconsistency at %x"
-                                " first_byte = %x last_byte = %x current = %x"
-                                " hit_edge = %x\n",
-                                address, first_byte, last_byte, b, hit_edge);
-                bad = true;
-            }
-        }
-        last_byte = b;
-    }
-    g_assert_false(bad);
-}
-
-static void cleanup(const char *filename)
-{
-    char *path = g_strdup_printf("%s/%s", tmpfs, filename);
-
-    unlink(path);
-}
-
-static void test_migrate(void)
-{
-    char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
-    QTestState *global = global_qtest, *from, *to;
-    unsigned char dest_byte_a, dest_byte_b, dest_byte_c, dest_byte_d;
-    gchar *cmd, *cmd_src, *cmd_dst;
-    QDict *rsp;
-
-    char *bootpath = g_strdup_printf("%s/bootsect", tmpfs);
-    const char *arch = qtest_get_arch();
-
-    got_stop = false;
-
-    if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
-        init_bootfile_x86(bootpath);
-        cmd_src = g_strdup_printf("-machine accel=kvm:tcg -m 150M"
-                                  " -name pcsource,debug-threads=on"
-                                  " -serial file:%s/src_serial"
-                                  " -drive file=%s,format=raw",
-                                  tmpfs, bootpath);
-        cmd_dst = g_strdup_printf("-machine accel=kvm:tcg -m 150M"
-                                  " -name pcdest,debug-threads=on"
-                                  " -serial file:%s/dest_serial"
-                                  " -drive file=%s,format=raw"
-                                  " -incoming %s",
-                                  tmpfs, bootpath, uri);
-    } else if (strcmp(arch, "ppc64") == 0) {
-        init_bootfile_ppc(bootpath);
-        cmd_src = g_strdup_printf("-machine accel=kvm:tcg -m 256M"
-                                  " -name pcsource,debug-threads=on"
-                                  " -serial file:%s/src_serial"
-                                  " -drive file=%s,if=pflash,format=raw",
-                                  tmpfs, bootpath);
-        cmd_dst = g_strdup_printf("-machine accel=kvm:tcg -m 256M"
-                                  " -name pcdest,debug-threads=on"
-                                  " -serial file:%s/dest_serial"
-                                  " -incoming %s",
-                                  tmpfs, uri);
-    } else {
-        g_assert_not_reached();
-    }
-
-    from = qtest_start(cmd_src);
-    g_free(cmd_src);
-
-    to = qtest_init(cmd_dst);
-    g_free(cmd_dst);
-
-    global_qtest = from;
-    rsp = qmp("{ 'execute': 'migrate-set-capabilities',"
-                  "'arguments': { "
-                      "'capabilities': [ {"
-                          "'capability': 'postcopy-ram',"
-                          "'state': true } ] } }");
-    g_assert(qdict_haskey(rsp, "return"));
-    QDECREF(rsp);
-
-    global_qtest = to;
-    rsp = qmp("{ 'execute': 'migrate-set-capabilities',"
-                  "'arguments': { "
-                      "'capabilities': [ {"
-                          "'capability': 'postcopy-ram',"
-                          "'state': true } ] } }");
-    g_assert(qdict_haskey(rsp, "return"));
-    QDECREF(rsp);
-
-    /* We want to pick a speed slow enough that the test completes
-     * quickly, but that it doesn't complete precopy even on a slow
-     * machine, so also set the downtime.
-     */
-    global_qtest = from;
-    rsp = qmp("{ 'execute': 'migrate_set_speed',"
-              "'arguments': { 'value': 100000000 } }");
-    g_assert(qdict_haskey(rsp, "return"));
-    QDECREF(rsp);
-
-    /* 1ms downtime - it should never finish precopy */
-    rsp = qmp("{ 'execute': 'migrate_set_downtime',"
-              "'arguments': { 'value': 0.001 } }");
-    g_assert(qdict_haskey(rsp, "return"));
-    QDECREF(rsp);
-
-
-    /* Wait for the first serial output from the source */
-    wait_for_serial("src_serial");
-
-    cmd = g_strdup_printf("{ 'execute': 'migrate',"
-                          "'arguments': { 'uri': '%s' } }",
-                          uri);
-    rsp = qmp(cmd);
-    g_free(cmd);
-    g_assert(qdict_haskey(rsp, "return"));
-    QDECREF(rsp);
-
-    wait_for_migration_pass();
-
-    rsp = return_or_event(qmp("{ 'execute': 'migrate-start-postcopy' }"));
-    g_assert(qdict_haskey(rsp, "return"));
-    QDECREF(rsp);
-
-    if (!got_stop) {
-        qmp_eventwait("STOP");
-    }
-
-    global_qtest = to;
-    qmp_eventwait("RESUME");
-
-    wait_for_serial("dest_serial");
-    global_qtest = from;
-    wait_for_migration_complete();
-
-    qtest_quit(from);
-
-    global_qtest = to;
-
-    qtest_memread(to, start_address, &dest_byte_a, 1);
-
-    /* Destination still running, wait for a byte to change */
-    do {
-        qtest_memread(to, start_address, &dest_byte_b, 1);
-        usleep(10 * 1000);
-    } while (dest_byte_a == dest_byte_b);
-
-    qmp("{ 'execute' : 'stop'}");
-    /* With it stopped, check nothing changes */
-    qtest_memread(to, start_address, &dest_byte_c, 1);
-    sleep(1);
-    qtest_memread(to, start_address, &dest_byte_d, 1);
-    g_assert_cmpint(dest_byte_c, ==, dest_byte_d);
-
-    check_guests_ram();
-
-    qtest_quit(to);
-    g_free(uri);
-
-    global_qtest = global;
-
-    cleanup("bootsect");
-    cleanup("migsocket");
-    cleanup("src_serial");
-    cleanup("dest_serial");
-}
-
-int main(int argc, char **argv)
-{
-    char template[] = "/tmp/postcopy-test-XXXXXX";
-    int ret;
-
-    g_test_init(&argc, &argv, NULL);
-
-    if (!ufd_version_check()) {
-        return 0;
-    }
-
-    tmpfs = mkdtemp(template);
-    if (!tmpfs) {
-        g_test_message("mkdtemp on path (%s): %s\n", template, strerror(errno));
-    }
-    g_assert(tmpfs);
-
-    module_call_init(MODULE_INIT_QOM);
-
-    qtest_add_func("/postcopy", test_migrate);
-
-    ret = g_test_run();
-
-    g_assert_cmpint(ret, ==, 0);
-
-    ret = rmdir(tmpfs);
-    if (ret != 0) {
-        g_test_message("unable to rmdir: path (%s): %s\n",
-                       tmpfs, strerror(errno));
-    }
-
-    return ret;
-}
diff --git a/tests/prom-env-test.c b/tests/prom-env-test.c
deleted file mode 100644 (file)
index 7a62857..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Test OpenBIOS-based machines.
- *
- * Copyright (c) 2016 Red Hat Inc.
- *
- * Author:
- *    Thomas Huth <thuth@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2
- * or later. See the COPYING file in the top-level directory.
- *
- * This test is used to check that some OpenBIOS machines can be started
- * successfully in TCG mode. To do this, we first put some Forth code into
- * the "boot-command" Open Firmware environment variable. This Forth code
- * writes a well-known magic value to a known location in memory. Then we
- * start the guest so that OpenBIOS can boot and finally run the Forth code.
- * The testing code here then can finally check whether the value has been
- * successfully written into the guest memory.
- */
-
-#include "qemu/osdep.h"
-#include "libqtest.h"
-
-#define MAGIC   0xcafec0de
-#define ADDRESS 0x4000
-
-static void check_guest_memory(void)
-{
-    uint32_t signature;
-    int i;
-
-    /* Poll until code has run and modified memory. Wait at most 30 seconds */
-    for (i = 0; i < 10000; ++i) {
-        signature = readl(ADDRESS);
-        if (signature == MAGIC) {
-            break;
-        }
-        g_usleep(10000);
-    }
-
-    g_assert_cmphex(signature, ==, MAGIC);
-}
-
-static void test_machine(const void *machine)
-{
-    char *args;
-
-    args = g_strdup_printf("-M %s,accel=tcg -prom-env 'boot-command=%x %x l!'",
-                           (const char *)machine, MAGIC, ADDRESS);
-
-    qtest_start(args);
-    check_guest_memory();
-    qtest_quit(global_qtest);
-
-    g_free(args);
-}
-
-static void add_tests(const char *machines[])
-{
-    int i;
-    char *name;
-
-    for (i = 0; machines[i] != NULL; i++) {
-        name = g_strdup_printf("prom-env/%s", machines[i]);
-        qtest_add_data_func(name, machines[i], test_machine);
-        g_free(name);
-    }
-}
-
-int main(int argc, char *argv[])
-{
-    const char *sparc_machines[] = { "SPARCbook", "Voyager", "SS-20", NULL };
-    const char *sparc64_machines[] = { "sun4u", "sun4v", NULL };
-    const char *mac_machines[] = { "mac99", "g3beige", NULL };
-    const char *arch = qtest_get_arch();
-
-    g_test_init(&argc, &argv, NULL);
-
-    if (!strcmp(arch, "ppc") || !strcmp(arch, "ppc64")) {
-        add_tests(mac_machines);
-    } else if (!strcmp(arch, "sparc")) {
-        add_tests(sparc_machines);
-    } else if (!strcmp(arch, "sparc64")) {
-        add_tests(sparc64_machines);
-    } else {
-        g_assert_not_reached();
-    }
-
-    return g_test_run();
-}
index 3bfa678..d435833 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 static void test_panic(void)
index b2cc355..875e4c4 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <glib/gstdio.h>
 #include "qemu-common.h"
 #include "libqtest.h"
index 71538fc..a105f10 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "libqos/pci.h"
 #include "libqos/pci-pc.h"
diff --git a/tests/qapi-schema/args-bad-boxed.err b/tests/qapi-schema/args-bad-boxed.err
deleted file mode 100644 (file)
index ad0d417..0000000
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/args-bad-boxed.json:2: 'boxed' of command 'foo' should only use true value
diff --git a/tests/qapi-schema/args-bad-boxed.exit b/tests/qapi-schema/args-bad-boxed.exit
deleted file mode 100644 (file)
index d00491f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/tests/qapi-schema/args-bad-boxed.json b/tests/qapi-schema/args-bad-boxed.json
deleted file mode 100644 (file)
index dea0cd0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# 'boxed' should only appear with value true
-{ 'command': 'foo', 'boxed': false }
diff --git a/tests/qapi-schema/args-bad-boxed.out b/tests/qapi-schema/args-bad-boxed.out
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/tests/qapi-schema/args-boxed-anon.err b/tests/qapi-schema/args-boxed-anon.err
deleted file mode 100644 (file)
index f24f345..0000000
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/args-boxed-anon.json:2: 'data' for command 'foo' should be a type name
diff --git a/tests/qapi-schema/args-boxed-anon.exit b/tests/qapi-schema/args-boxed-anon.exit
deleted file mode 100644 (file)
index d00491f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/tests/qapi-schema/args-boxed-anon.json b/tests/qapi-schema/args-boxed-anon.json
deleted file mode 100644 (file)
index 95f60da..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# 'boxed' can only be used with named types
-{ 'command': 'foo', 'boxed': true, 'data': { 'string': 'str' } }
diff --git a/tests/qapi-schema/args-boxed-anon.out b/tests/qapi-schema/args-boxed-anon.out
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/tests/qapi-schema/args-boxed-empty.err b/tests/qapi-schema/args-boxed-empty.err
deleted file mode 100644 (file)
index 039603e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/args-boxed-empty.json:3: Cannot use 'boxed' with empty type
diff --git a/tests/qapi-schema/args-boxed-empty.exit b/tests/qapi-schema/args-boxed-empty.exit
deleted file mode 100644 (file)
index d00491f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/tests/qapi-schema/args-boxed-empty.json b/tests/qapi-schema/args-boxed-empty.json
deleted file mode 100644 (file)
index 52717e0..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# 'boxed' requires a non-empty type
-{ 'struct': 'Empty', 'data': {} }
-{ 'command': 'foo', 'boxed': true, 'data': 'Empty' }
diff --git a/tests/qapi-schema/args-boxed-empty.out b/tests/qapi-schema/args-boxed-empty.out
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/tests/qapi-schema/args-boxed-string.err b/tests/qapi-schema/args-boxed-string.err
deleted file mode 100644 (file)
index d326b48..0000000
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/args-boxed-string.json:2: 'data' for command 'foo' cannot use built-in type 'str'
diff --git a/tests/qapi-schema/args-boxed-string.exit b/tests/qapi-schema/args-boxed-string.exit
deleted file mode 100644 (file)
index d00491f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/tests/qapi-schema/args-boxed-string.json b/tests/qapi-schema/args-boxed-string.json
deleted file mode 100644 (file)
index f91a150..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# 'boxed' requires a complex (not built-in) type
-{ 'command': 'foo', 'boxed': true, 'data': 'str' }
diff --git a/tests/qapi-schema/args-boxed-string.out b/tests/qapi-schema/args-boxed-string.out
deleted file mode 100644 (file)
index e69de29..0000000
index f8ad223..1d693d7 100644 (file)
@@ -1 +1 @@
-tests/qapi-schema/args-union.json:3: 'data' for command 'oops' cannot use union type 'Uni'
+tests/qapi-schema/args-union.json:4: 'data' for command 'oops' cannot use union type 'Uni'
index 2fcaeaa..7bdcbb7 100644 (file)
@@ -1,3 +1,4 @@
-# use of union arguments requires 'boxed':true
+# we do not allow union arguments
+# TODO should we support this?
 { 'union': 'Uni', 'data': { 'case1': 'int', 'case2': 'str' } }
 { 'command': 'oops', 'data': 'Uni' }
diff --git a/tests/qapi-schema/event-boxed-empty.err b/tests/qapi-schema/event-boxed-empty.err
deleted file mode 100644 (file)
index 68ec6f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/event-boxed-empty.json:2: Use of 'boxed' requires 'data'
diff --git a/tests/qapi-schema/event-boxed-empty.exit b/tests/qapi-schema/event-boxed-empty.exit
deleted file mode 100644 (file)
index d00491f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/tests/qapi-schema/event-boxed-empty.json b/tests/qapi-schema/event-boxed-empty.json
deleted file mode 100644 (file)
index cb145f1..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# 'boxed' requires a non-empty type
-{ 'event': 'FOO', 'boxed': true }
diff --git a/tests/qapi-schema/event-boxed-empty.out b/tests/qapi-schema/event-boxed-empty.out
deleted file mode 100644 (file)
index e69de29..0000000
index 5a0f2bf..b6b4134 100644 (file)
@@ -1,5 +1,4 @@
 enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
     prefix QTYPE
 event oops None
-   boxed=False
 object q_empty
diff --git a/tests/qapi-schema/flat-union-incomplete-branch.err b/tests/qapi-schema/flat-union-incomplete-branch.err
deleted file mode 100644 (file)
index e826bf0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/flat-union-incomplete-branch.json:6: Union 'TestUnion' data missing 'value2' branch
diff --git a/tests/qapi-schema/flat-union-incomplete-branch.exit b/tests/qapi-schema/flat-union-incomplete-branch.exit
deleted file mode 100644 (file)
index d00491f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/tests/qapi-schema/flat-union-incomplete-branch.json b/tests/qapi-schema/flat-union-incomplete-branch.json
deleted file mode 100644 (file)
index 25a411b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# we require all branches of the union to be covered
-{ 'enum': 'TestEnum',
-  'data': [ 'value1', 'value2' ] }
-{ 'struct': 'TestTypeA',
-  'data': { 'string': 'str' } }
-{ 'union': 'TestUnion',
-  'base': { 'type': 'TestEnum' },
-  'discriminator': 'type',
-  'data': { 'value1': 'TestTypeA' } }
diff --git a/tests/qapi-schema/flat-union-incomplete-branch.out b/tests/qapi-schema/flat-union-incomplete-branch.out
deleted file mode 100644 (file)
index e69de29..0000000
index 1d2722c..382ce2f 100644 (file)
@@ -1,7 +1,7 @@
 enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
     prefix QTYPE
 command fooA q_obj_fooA-arg -> None
-   gen=True success_response=True boxed=False
+   gen=True success_response=True
 object q_empty
 object q_obj_fooA-arg
     member bar1: str optional=False
index e8171c9..ae3293a 100644 (file)
@@ -1,7 +1,7 @@
 enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
     prefix QTYPE
 command eins None -> None
-   gen=True success_response=True boxed=False
+   gen=True success_response=True
 object q_empty
 command zwei None -> None
-   gen=True success_response=True boxed=False
+   gen=True success_response=True
index 1719463..f571e1b 100644 (file)
 { 'command': 'guest-get-time', 'data': {'a': 'int', '*b': 'int' },
   'returns': 'int' }
 { 'command': 'guest-sync', 'data': { 'arg': 'any' }, 'returns': 'any' }
-{ 'command': 'boxed-struct', 'boxed': true, 'data': 'UserDefZero' }
-{ 'command': 'boxed-union', 'data': 'UserDefNativeListUnion', 'boxed': true }
 
 # For testing integer range flattening in opts-visitor. The following schema
 # corresponds to the option format:
   'data': { '*a': 'int', '*b': 'UserDefOne', 'c': 'str' } }
 { 'event': 'EVENT_D',
   'data': { 'a' : 'EventStructOne', 'b' : 'str', '*c': 'str', '*enum3': 'EnumOne' } }
-{ 'event': 'EVENT_E', 'boxed': true, 'data': 'UserDefZero' }
-{ 'event': 'EVENT_F', 'boxed': true, 'data': 'UserDefAlternate' }
 
 # test that we correctly compile downstream extensions, as well as munge
 # ticklish names
index 9d99c4e..19cd214 100644 (file)
@@ -1,39 +1,25 @@
 alternate AltIntNum
-    tag type
     case i: int
     case n: number
 alternate AltNumInt
-    tag type
     case n: number
     case i: int
 alternate AltNumStr
-    tag type
     case n: number
     case s: str
 alternate AltStrBool
-    tag type
     case s: str
     case b: bool
 alternate AltStrInt
-    tag type
     case s: str
     case i: int
 alternate AltStrNum
-    tag type
     case s: str
     case n: number
 event EVENT_A None
-   boxed=False
 event EVENT_B None
-   boxed=False
 event EVENT_C q_obj_EVENT_C-arg
-   boxed=False
 event EVENT_D q_obj_EVENT_D-arg
-   boxed=False
-event EVENT_E UserDefZero
-   boxed=True
-event EVENT_F UserDefAlternate
-   boxed=True
 object Empty1
 object Empty2
     base Empty1
@@ -64,7 +50,6 @@ object UserDefA
     member boolean: bool optional=False
     member a_b: int optional=True
 alternate UserDefAlternate
-    tag type
     case udfu: UserDefFlatUnion
     case s: str
     case i: int
@@ -87,7 +72,6 @@ object UserDefFlatUnion2
     case value2: UserDefB
 object UserDefNativeListUnion
     member type: UserDefNativeListUnionKind optional=False
-    tag type
     case integer: q_obj_intList-wrapper
     case s8: q_obj_int8List-wrapper
     case s16: q_obj_int16List-wrapper
@@ -132,9 +116,7 @@ object UserDefZero
 object WrapAlternate
     member alt: UserDefAlternate optional=False
 event __ORG.QEMU_X-EVENT __org.qemu_x-Struct
-   boxed=False
 alternate __org.qemu_x-Alt
-    tag type
     case __org.qemu_x-branch: str
     case b: __org.qemu_x-Base
 object __org.qemu_x-Base
@@ -148,7 +130,6 @@ object __org.qemu_x-Struct2
     member array: __org.qemu_x-Union1List optional=False
 object __org.qemu_x-Union1
     member type: __org.qemu_x-Union1Kind optional=False
-    tag type
     case __org.qemu_x-branch: q_obj_str-wrapper
 enum __org.qemu_x-Union1Kind ['__org.qemu_x-branch']
 object __org.qemu_x-Union2
@@ -156,15 +137,11 @@ object __org.qemu_x-Union2
     tag __org.qemu_x-member1
     case __org.qemu_x-value: __org.qemu_x-Struct2
 command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> __org.qemu_x-Union1
-   gen=True success_response=True boxed=False
-command boxed-struct UserDefZero -> None
-   gen=True success_response=True boxed=True
-command boxed-union UserDefNativeListUnion -> None
-   gen=True success_response=True boxed=True
+   gen=True success_response=True
 command guest-get-time q_obj_guest-get-time-arg -> int
-   gen=True success_response=True boxed=False
+   gen=True success_response=True
 command guest-sync q_obj_guest-sync-arg -> any
-   gen=True success_response=True boxed=False
+   gen=True success_response=True
 object q_empty
 object q_obj_EVENT_C-arg
     member a: int optional=True
@@ -225,10 +202,10 @@ object q_obj_user_def_cmd2-arg
     member ud1a: UserDefOne optional=False
     member ud1b: UserDefOne optional=True
 command user_def_cmd None -> None
-   gen=True success_response=True boxed=False
+   gen=True success_response=True
 command user_def_cmd0 Empty2 -> Empty2
-   gen=True success_response=True boxed=False
+   gen=True success_response=True
 command user_def_cmd1 q_obj_user_def_cmd1-arg -> None
-   gen=True success_response=True boxed=False
+   gen=True success_response=True
 command user_def_cmd2 q_obj_user_def_cmd2-arg -> UserDefTwo
-   gen=True success_response=True boxed=False
+   gen=True success_response=True
index ef74e2c..649677e 100644 (file)
@@ -36,20 +36,19 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
         self._print_variants(variants)
 
     def visit_command(self, name, info, arg_type, ret_type,
-                      gen, success_response, boxed):
+                      gen, success_response):
         print 'command %s %s -> %s' % \
             (name, arg_type and arg_type.name, ret_type and ret_type.name)
-        print '   gen=%s success_response=%s boxed=%s' % \
-            (gen, success_response, boxed)
+        print '   gen=%s success_response=%s' % (gen, success_response)
 
-    def visit_event(self, name, info, arg_type, boxed):
+    def visit_event(self, name, info, arg_type):
         print 'event %s %s' % (name, arg_type and arg_type.name)
-        print '   boxed=%s' % boxed
 
     @staticmethod
     def _print_variants(variants):
         if variants:
-            print '    tag %s' % variants.tag_member.name
+            if variants.tag_name:
+                print '    tag %s' % variants.tag_name
             for v in variants.variants:
                 print '    case %s: %s' % (v.name, v.type.name)
 
index 6f2aa3d..67e1beb 100755 (executable)
@@ -37,7 +37,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 . ./common.rc
 . ./common.filter
 
-_supported_fmt raw qcow qcow2 qed vdi vmdk vhdx luks
+_supported_fmt raw qcow qcow2 qed vdi vmdk vhdx
 _supported_proto generic
 _supported_os Linux
 
index 01a770d..d1d3f22 100755 (executable)
@@ -43,16 +43,13 @@ _supported_fmt generic
 _supported_proto file
 _supported_os Linux
 
-# Remove once all tests are fixed to use TEST_IMG_FILE
-# correctly and common.rc sets it unconditionally
-test -z "$TEST_IMG_FILE" && TEST_IMG_FILE=$TEST_IMG
 
 size=128M
 _make_test_img $size
 
 echo
 echo "== mark image read-only"
-chmod a-w "$TEST_IMG_FILE"
+chmod a-w "$TEST_IMG"
 
 echo
 echo "== read from read-only image"
index 664871b..d4e9be2 100644 (file)
@@ -225,78 +225,42 @@ wrote 512/512 bytes at offset 108544
 wrote 512/512 bytes at offset 109568
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 216
-wrote 512/512 bytes at offset 110848
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 111872
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 112896
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 113920
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 114944
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 115968
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 116992
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 118016
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 119040
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 120064
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 121088
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 122112
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 123136
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 124160
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 125184
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 126208
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 127232
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 128256
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 129280
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 130304
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 131328
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 132352
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 133376
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 134400
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 135424
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 136448
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 137472
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 138496
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 139520
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 140544
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 141568
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 142592
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 143616
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 144640
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 145664
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 146688
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 110848 is not sector aligned
+offset 111872 is not sector aligned
+offset 112896 is not sector aligned
+offset 113920 is not sector aligned
+offset 114944 is not sector aligned
+offset 115968 is not sector aligned
+offset 116992 is not sector aligned
+offset 118016 is not sector aligned
+offset 119040 is not sector aligned
+offset 120064 is not sector aligned
+offset 121088 is not sector aligned
+offset 122112 is not sector aligned
+offset 123136 is not sector aligned
+offset 124160 is not sector aligned
+offset 125184 is not sector aligned
+offset 126208 is not sector aligned
+offset 127232 is not sector aligned
+offset 128256 is not sector aligned
+offset 129280 is not sector aligned
+offset 130304 is not sector aligned
+offset 131328 is not sector aligned
+offset 132352 is not sector aligned
+offset 133376 is not sector aligned
+offset 134400 is not sector aligned
+offset 135424 is not sector aligned
+offset 136448 is not sector aligned
+offset 137472 is not sector aligned
+offset 138496 is not sector aligned
+offset 139520 is not sector aligned
+offset 140544 is not sector aligned
+offset 141568 is not sector aligned
+offset 142592 is not sector aligned
+offset 143616 is not sector aligned
+offset 144640 is not sector aligned
+offset 145664 is not sector aligned
+offset 146688 is not sector aligned
 === IO: pattern 33
 wrote 2048/2048 bytes at offset 147968
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -543,78 +507,42 @@ read 512/512 bytes at offset 108544
 read 512/512 bytes at offset 109568
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 216
-read 512/512 bytes at offset 110848
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 111872
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 112896
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 113920
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 114944
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 115968
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 116992
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 118016
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 119040
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 120064
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 121088
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 122112
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 123136
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 124160
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 125184
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 126208
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 127232
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 128256
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 129280
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 130304
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 131328
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 132352
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 133376
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 134400
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 135424
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 136448
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 137472
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 138496
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 139520
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 140544
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 141568
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 142592
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 143616
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 144640
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 145664
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 146688
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 110848 is not sector aligned
+offset 111872 is not sector aligned
+offset 112896 is not sector aligned
+offset 113920 is not sector aligned
+offset 114944 is not sector aligned
+offset 115968 is not sector aligned
+offset 116992 is not sector aligned
+offset 118016 is not sector aligned
+offset 119040 is not sector aligned
+offset 120064 is not sector aligned
+offset 121088 is not sector aligned
+offset 122112 is not sector aligned
+offset 123136 is not sector aligned
+offset 124160 is not sector aligned
+offset 125184 is not sector aligned
+offset 126208 is not sector aligned
+offset 127232 is not sector aligned
+offset 128256 is not sector aligned
+offset 129280 is not sector aligned
+offset 130304 is not sector aligned
+offset 131328 is not sector aligned
+offset 132352 is not sector aligned
+offset 133376 is not sector aligned
+offset 134400 is not sector aligned
+offset 135424 is not sector aligned
+offset 136448 is not sector aligned
+offset 137472 is not sector aligned
+offset 138496 is not sector aligned
+offset 139520 is not sector aligned
+offset 140544 is not sector aligned
+offset 141568 is not sector aligned
+offset 142592 is not sector aligned
+offset 143616 is not sector aligned
+offset 144640 is not sector aligned
+offset 145664 is not sector aligned
+offset 146688 is not sector aligned
 === IO: pattern 33
 read 2048/2048 bytes at offset 147968
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -861,78 +789,42 @@ wrote 512/512 bytes at offset 108544
 wrote 512/512 bytes at offset 109568
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 216
-wrote 512/512 bytes at offset 110848
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 111872
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 112896
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 113920
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 114944
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 115968
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 116992
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 118016
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 119040
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 120064
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 121088
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 122112
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 123136
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 124160
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 125184
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 126208
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 127232
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 128256
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 129280
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 130304
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 131328
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 132352
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 133376
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 134400
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 135424
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 136448
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 137472
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 138496
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 139520
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 140544
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 141568
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 142592
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 143616
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 144640
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 145664
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 146688
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 110848 is not sector aligned
+offset 111872 is not sector aligned
+offset 112896 is not sector aligned
+offset 113920 is not sector aligned
+offset 114944 is not sector aligned
+offset 115968 is not sector aligned
+offset 116992 is not sector aligned
+offset 118016 is not sector aligned
+offset 119040 is not sector aligned
+offset 120064 is not sector aligned
+offset 121088 is not sector aligned
+offset 122112 is not sector aligned
+offset 123136 is not sector aligned
+offset 124160 is not sector aligned
+offset 125184 is not sector aligned
+offset 126208 is not sector aligned
+offset 127232 is not sector aligned
+offset 128256 is not sector aligned
+offset 129280 is not sector aligned
+offset 130304 is not sector aligned
+offset 131328 is not sector aligned
+offset 132352 is not sector aligned
+offset 133376 is not sector aligned
+offset 134400 is not sector aligned
+offset 135424 is not sector aligned
+offset 136448 is not sector aligned
+offset 137472 is not sector aligned
+offset 138496 is not sector aligned
+offset 139520 is not sector aligned
+offset 140544 is not sector aligned
+offset 141568 is not sector aligned
+offset 142592 is not sector aligned
+offset 143616 is not sector aligned
+offset 144640 is not sector aligned
+offset 145664 is not sector aligned
+offset 146688 is not sector aligned
 === IO: pattern 33
 wrote 2048/2048 bytes at offset 147968
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -1179,78 +1071,42 @@ read 512/512 bytes at offset 108544
 read 512/512 bytes at offset 109568
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 216
-read 512/512 bytes at offset 110848
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 111872
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 112896
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 113920
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 114944
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 115968
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 116992
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 118016
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 119040
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 120064
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 121088
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 122112
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 123136
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 124160
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 125184
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 126208
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 127232
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 128256
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 129280
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 130304
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 131328
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 132352
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 133376
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 134400
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 135424
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 136448
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 137472
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 138496
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 139520
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 140544
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 141568
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 142592
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 143616
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 144640
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 145664
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 146688
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 110848 is not sector aligned
+offset 111872 is not sector aligned
+offset 112896 is not sector aligned
+offset 113920 is not sector aligned
+offset 114944 is not sector aligned
+offset 115968 is not sector aligned
+offset 116992 is not sector aligned
+offset 118016 is not sector aligned
+offset 119040 is not sector aligned
+offset 120064 is not sector aligned
+offset 121088 is not sector aligned
+offset 122112 is not sector aligned
+offset 123136 is not sector aligned
+offset 124160 is not sector aligned
+offset 125184 is not sector aligned
+offset 126208 is not sector aligned
+offset 127232 is not sector aligned
+offset 128256 is not sector aligned
+offset 129280 is not sector aligned
+offset 130304 is not sector aligned
+offset 131328 is not sector aligned
+offset 132352 is not sector aligned
+offset 133376 is not sector aligned
+offset 134400 is not sector aligned
+offset 135424 is not sector aligned
+offset 136448 is not sector aligned
+offset 137472 is not sector aligned
+offset 138496 is not sector aligned
+offset 139520 is not sector aligned
+offset 140544 is not sector aligned
+offset 141568 is not sector aligned
+offset 142592 is not sector aligned
+offset 143616 is not sector aligned
+offset 144640 is not sector aligned
+offset 145664 is not sector aligned
+offset 146688 is not sector aligned
 === IO: pattern 33
 read 2048/2048 bytes at offset 147968
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -1499,78 +1355,42 @@ wrote 512/512 bytes at offset 4295075840
 wrote 512/512 bytes at offset 4295076864
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 216
-wrote 512/512 bytes at offset 4295078144
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295079168
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295080192
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295081216
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295082240
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295083264
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295084288
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295085312
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295086336
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295087360
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295088384
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295089408
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295090432
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295091456
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295092480
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295093504
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295094528
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295095552
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295096576
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295097600
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295098624
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295099648
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295100672
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295101696
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295102720
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295103744
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295104768
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295105792
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295106816
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295107840
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295108864
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295109888
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295110912
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295111936
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295112960
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295113984
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 4295078144 is not sector aligned
+offset 4295079168 is not sector aligned
+offset 4295080192 is not sector aligned
+offset 4295081216 is not sector aligned
+offset 4295082240 is not sector aligned
+offset 4295083264 is not sector aligned
+offset 4295084288 is not sector aligned
+offset 4295085312 is not sector aligned
+offset 4295086336 is not sector aligned
+offset 4295087360 is not sector aligned
+offset 4295088384 is not sector aligned
+offset 4295089408 is not sector aligned
+offset 4295090432 is not sector aligned
+offset 4295091456 is not sector aligned
+offset 4295092480 is not sector aligned
+offset 4295093504 is not sector aligned
+offset 4295094528 is not sector aligned
+offset 4295095552 is not sector aligned
+offset 4295096576 is not sector aligned
+offset 4295097600 is not sector aligned
+offset 4295098624 is not sector aligned
+offset 4295099648 is not sector aligned
+offset 4295100672 is not sector aligned
+offset 4295101696 is not sector aligned
+offset 4295102720 is not sector aligned
+offset 4295103744 is not sector aligned
+offset 4295104768 is not sector aligned
+offset 4295105792 is not sector aligned
+offset 4295106816 is not sector aligned
+offset 4295107840 is not sector aligned
+offset 4295108864 is not sector aligned
+offset 4295109888 is not sector aligned
+offset 4295110912 is not sector aligned
+offset 4295111936 is not sector aligned
+offset 4295112960 is not sector aligned
+offset 4295113984 is not sector aligned
 === IO: pattern 33
 wrote 2048/2048 bytes at offset 4295115264
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -1817,78 +1637,42 @@ read 512/512 bytes at offset 4295075840
 read 512/512 bytes at offset 4295076864
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 216
-read 512/512 bytes at offset 4295078144
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295079168
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295080192
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295081216
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295082240
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295083264
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295084288
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295085312
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295086336
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295087360
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295088384
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295089408
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295090432
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295091456
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295092480
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295093504
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295094528
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295095552
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295096576
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295097600
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295098624
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295099648
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295100672
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295101696
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295102720
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295103744
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295104768
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295105792
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295106816
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295107840
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295108864
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295109888
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295110912
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295111936
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295112960
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295113984
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 4295078144 is not sector aligned
+offset 4295079168 is not sector aligned
+offset 4295080192 is not sector aligned
+offset 4295081216 is not sector aligned
+offset 4295082240 is not sector aligned
+offset 4295083264 is not sector aligned
+offset 4295084288 is not sector aligned
+offset 4295085312 is not sector aligned
+offset 4295086336 is not sector aligned
+offset 4295087360 is not sector aligned
+offset 4295088384 is not sector aligned
+offset 4295089408 is not sector aligned
+offset 4295090432 is not sector aligned
+offset 4295091456 is not sector aligned
+offset 4295092480 is not sector aligned
+offset 4295093504 is not sector aligned
+offset 4295094528 is not sector aligned
+offset 4295095552 is not sector aligned
+offset 4295096576 is not sector aligned
+offset 4295097600 is not sector aligned
+offset 4295098624 is not sector aligned
+offset 4295099648 is not sector aligned
+offset 4295100672 is not sector aligned
+offset 4295101696 is not sector aligned
+offset 4295102720 is not sector aligned
+offset 4295103744 is not sector aligned
+offset 4295104768 is not sector aligned
+offset 4295105792 is not sector aligned
+offset 4295106816 is not sector aligned
+offset 4295107840 is not sector aligned
+offset 4295108864 is not sector aligned
+offset 4295109888 is not sector aligned
+offset 4295110912 is not sector aligned
+offset 4295111936 is not sector aligned
+offset 4295112960 is not sector aligned
+offset 4295113984 is not sector aligned
 === IO: pattern 33
 read 2048/2048 bytes at offset 4295115264
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -2135,78 +1919,42 @@ wrote 512/512 bytes at offset 4295075840
 wrote 512/512 bytes at offset 4295076864
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 216
-wrote 512/512 bytes at offset 4295078144
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295079168
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295080192
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295081216
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295082240
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295083264
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295084288
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295085312
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295086336
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295087360
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295088384
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295089408
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295090432
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295091456
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295092480
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295093504
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295094528
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295095552
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295096576
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295097600
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295098624
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295099648
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295100672
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295101696
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295102720
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295103744
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295104768
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295105792
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295106816
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295107840
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295108864
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295109888
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295110912
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295111936
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295112960
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295113984
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 4295078144 is not sector aligned
+offset 4295079168 is not sector aligned
+offset 4295080192 is not sector aligned
+offset 4295081216 is not sector aligned
+offset 4295082240 is not sector aligned
+offset 4295083264 is not sector aligned
+offset 4295084288 is not sector aligned
+offset 4295085312 is not sector aligned
+offset 4295086336 is not sector aligned
+offset 4295087360 is not sector aligned
+offset 4295088384 is not sector aligned
+offset 4295089408 is not sector aligned
+offset 4295090432 is not sector aligned
+offset 4295091456 is not sector aligned
+offset 4295092480 is not sector aligned
+offset 4295093504 is not sector aligned
+offset 4295094528 is not sector aligned
+offset 4295095552 is not sector aligned
+offset 4295096576 is not sector aligned
+offset 4295097600 is not sector aligned
+offset 4295098624 is not sector aligned
+offset 4295099648 is not sector aligned
+offset 4295100672 is not sector aligned
+offset 4295101696 is not sector aligned
+offset 4295102720 is not sector aligned
+offset 4295103744 is not sector aligned
+offset 4295104768 is not sector aligned
+offset 4295105792 is not sector aligned
+offset 4295106816 is not sector aligned
+offset 4295107840 is not sector aligned
+offset 4295108864 is not sector aligned
+offset 4295109888 is not sector aligned
+offset 4295110912 is not sector aligned
+offset 4295111936 is not sector aligned
+offset 4295112960 is not sector aligned
+offset 4295113984 is not sector aligned
 === IO: pattern 33
 wrote 2048/2048 bytes at offset 4295115264
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -2453,78 +2201,42 @@ read 512/512 bytes at offset 4295075840
 read 512/512 bytes at offset 4295076864
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 216
-read 512/512 bytes at offset 4295078144
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295079168
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295080192
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295081216
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295082240
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295083264
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295084288
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295085312
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295086336
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295087360
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295088384
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295089408
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295090432
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295091456
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295092480
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295093504
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295094528
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295095552
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295096576
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295097600
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295098624
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295099648
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295100672
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295101696
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295102720
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295103744
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295104768
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295105792
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295106816
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295107840
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295108864
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295109888
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295110912
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295111936
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295112960
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295113984
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 4295078144 is not sector aligned
+offset 4295079168 is not sector aligned
+offset 4295080192 is not sector aligned
+offset 4295081216 is not sector aligned
+offset 4295082240 is not sector aligned
+offset 4295083264 is not sector aligned
+offset 4295084288 is not sector aligned
+offset 4295085312 is not sector aligned
+offset 4295086336 is not sector aligned
+offset 4295087360 is not sector aligned
+offset 4295088384 is not sector aligned
+offset 4295089408 is not sector aligned
+offset 4295090432 is not sector aligned
+offset 4295091456 is not sector aligned
+offset 4295092480 is not sector aligned
+offset 4295093504 is not sector aligned
+offset 4295094528 is not sector aligned
+offset 4295095552 is not sector aligned
+offset 4295096576 is not sector aligned
+offset 4295097600 is not sector aligned
+offset 4295098624 is not sector aligned
+offset 4295099648 is not sector aligned
+offset 4295100672 is not sector aligned
+offset 4295101696 is not sector aligned
+offset 4295102720 is not sector aligned
+offset 4295103744 is not sector aligned
+offset 4295104768 is not sector aligned
+offset 4295105792 is not sector aligned
+offset 4295106816 is not sector aligned
+offset 4295107840 is not sector aligned
+offset 4295108864 is not sector aligned
+offset 4295109888 is not sector aligned
+offset 4295110912 is not sector aligned
+offset 4295111936 is not sector aligned
+offset 4295112960 is not sector aligned
+offset 4295113984 is not sector aligned
 === IO: pattern 33
 read 2048/2048 bytes at offset 4295115264
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -2777,78 +2489,42 @@ read 512/512 bytes at offset 108544
 read 512/512 bytes at offset 109568
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 216
-read 512/512 bytes at offset 110848
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 111872
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 112896
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 113920
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 114944
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 115968
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 116992
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 118016
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 119040
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 120064
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 121088
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 122112
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 123136
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 124160
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 125184
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 126208
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 127232
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 128256
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 129280
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 130304
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 131328
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 132352
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 133376
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 134400
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 135424
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 136448
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 137472
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 138496
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 139520
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 140544
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 141568
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 142592
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 143616
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 144640
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 145664
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 146688
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 110848 is not sector aligned
+offset 111872 is not sector aligned
+offset 112896 is not sector aligned
+offset 113920 is not sector aligned
+offset 114944 is not sector aligned
+offset 115968 is not sector aligned
+offset 116992 is not sector aligned
+offset 118016 is not sector aligned
+offset 119040 is not sector aligned
+offset 120064 is not sector aligned
+offset 121088 is not sector aligned
+offset 122112 is not sector aligned
+offset 123136 is not sector aligned
+offset 124160 is not sector aligned
+offset 125184 is not sector aligned
+offset 126208 is not sector aligned
+offset 127232 is not sector aligned
+offset 128256 is not sector aligned
+offset 129280 is not sector aligned
+offset 130304 is not sector aligned
+offset 131328 is not sector aligned
+offset 132352 is not sector aligned
+offset 133376 is not sector aligned
+offset 134400 is not sector aligned
+offset 135424 is not sector aligned
+offset 136448 is not sector aligned
+offset 137472 is not sector aligned
+offset 138496 is not sector aligned
+offset 139520 is not sector aligned
+offset 140544 is not sector aligned
+offset 141568 is not sector aligned
+offset 142592 is not sector aligned
+offset 143616 is not sector aligned
+offset 144640 is not sector aligned
+offset 145664 is not sector aligned
+offset 146688 is not sector aligned
 === IO: pattern 33
 read 2048/2048 bytes at offset 147968
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -3095,78 +2771,42 @@ read 512/512 bytes at offset 108544
 read 512/512 bytes at offset 109568
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 216
-read 512/512 bytes at offset 110848
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 111872
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 112896
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 113920
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 114944
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 115968
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 116992
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 118016
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 119040
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 120064
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 121088
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 122112
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 123136
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 124160
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 125184
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 126208
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 127232
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 128256
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 129280
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 130304
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 131328
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 132352
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 133376
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 134400
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 135424
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 136448
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 137472
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 138496
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 139520
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 140544
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 141568
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 142592
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 143616
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 144640
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 145664
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 146688
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 110848 is not sector aligned
+offset 111872 is not sector aligned
+offset 112896 is not sector aligned
+offset 113920 is not sector aligned
+offset 114944 is not sector aligned
+offset 115968 is not sector aligned
+offset 116992 is not sector aligned
+offset 118016 is not sector aligned
+offset 119040 is not sector aligned
+offset 120064 is not sector aligned
+offset 121088 is not sector aligned
+offset 122112 is not sector aligned
+offset 123136 is not sector aligned
+offset 124160 is not sector aligned
+offset 125184 is not sector aligned
+offset 126208 is not sector aligned
+offset 127232 is not sector aligned
+offset 128256 is not sector aligned
+offset 129280 is not sector aligned
+offset 130304 is not sector aligned
+offset 131328 is not sector aligned
+offset 132352 is not sector aligned
+offset 133376 is not sector aligned
+offset 134400 is not sector aligned
+offset 135424 is not sector aligned
+offset 136448 is not sector aligned
+offset 137472 is not sector aligned
+offset 138496 is not sector aligned
+offset 139520 is not sector aligned
+offset 140544 is not sector aligned
+offset 141568 is not sector aligned
+offset 142592 is not sector aligned
+offset 143616 is not sector aligned
+offset 144640 is not sector aligned
+offset 145664 is not sector aligned
+offset 146688 is not sector aligned
 === IO: pattern 33
 read 2048/2048 bytes at offset 147968
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -3415,78 +3055,42 @@ read 512/512 bytes at offset 4295075840
 read 512/512 bytes at offset 4295076864
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 216
-read 512/512 bytes at offset 4295078144
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295079168
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295080192
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295081216
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295082240
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295083264
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295084288
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295085312
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295086336
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295087360
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295088384
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295089408
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295090432
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295091456
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295092480
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295093504
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295094528
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295095552
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295096576
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295097600
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295098624
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295099648
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295100672
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295101696
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295102720
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295103744
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295104768
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295105792
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295106816
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295107840
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295108864
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295109888
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295110912
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295111936
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295112960
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295113984
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 4295078144 is not sector aligned
+offset 4295079168 is not sector aligned
+offset 4295080192 is not sector aligned
+offset 4295081216 is not sector aligned
+offset 4295082240 is not sector aligned
+offset 4295083264 is not sector aligned
+offset 4295084288 is not sector aligned
+offset 4295085312 is not sector aligned
+offset 4295086336 is not sector aligned
+offset 4295087360 is not sector aligned
+offset 4295088384 is not sector aligned
+offset 4295089408 is not sector aligned
+offset 4295090432 is not sector aligned
+offset 4295091456 is not sector aligned
+offset 4295092480 is not sector aligned
+offset 4295093504 is not sector aligned
+offset 4295094528 is not sector aligned
+offset 4295095552 is not sector aligned
+offset 4295096576 is not sector aligned
+offset 4295097600 is not sector aligned
+offset 4295098624 is not sector aligned
+offset 4295099648 is not sector aligned
+offset 4295100672 is not sector aligned
+offset 4295101696 is not sector aligned
+offset 4295102720 is not sector aligned
+offset 4295103744 is not sector aligned
+offset 4295104768 is not sector aligned
+offset 4295105792 is not sector aligned
+offset 4295106816 is not sector aligned
+offset 4295107840 is not sector aligned
+offset 4295108864 is not sector aligned
+offset 4295109888 is not sector aligned
+offset 4295110912 is not sector aligned
+offset 4295111936 is not sector aligned
+offset 4295112960 is not sector aligned
+offset 4295113984 is not sector aligned
 === IO: pattern 33
 read 2048/2048 bytes at offset 4295115264
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -3733,78 +3337,42 @@ read 512/512 bytes at offset 4295075840
 read 512/512 bytes at offset 4295076864
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 216
-read 512/512 bytes at offset 4295078144
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295079168
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295080192
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295081216
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295082240
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295083264
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295084288
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295085312
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295086336
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295087360
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295088384
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295089408
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295090432
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295091456
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295092480
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295093504
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295094528
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295095552
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295096576
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295097600
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295098624
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295099648
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295100672
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295101696
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295102720
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295103744
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295104768
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295105792
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295106816
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295107840
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295108864
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295109888
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295110912
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295111936
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295112960
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295113984
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 4295078144 is not sector aligned
+offset 4295079168 is not sector aligned
+offset 4295080192 is not sector aligned
+offset 4295081216 is not sector aligned
+offset 4295082240 is not sector aligned
+offset 4295083264 is not sector aligned
+offset 4295084288 is not sector aligned
+offset 4295085312 is not sector aligned
+offset 4295086336 is not sector aligned
+offset 4295087360 is not sector aligned
+offset 4295088384 is not sector aligned
+offset 4295089408 is not sector aligned
+offset 4295090432 is not sector aligned
+offset 4295091456 is not sector aligned
+offset 4295092480 is not sector aligned
+offset 4295093504 is not sector aligned
+offset 4295094528 is not sector aligned
+offset 4295095552 is not sector aligned
+offset 4295096576 is not sector aligned
+offset 4295097600 is not sector aligned
+offset 4295098624 is not sector aligned
+offset 4295099648 is not sector aligned
+offset 4295100672 is not sector aligned
+offset 4295101696 is not sector aligned
+offset 4295102720 is not sector aligned
+offset 4295103744 is not sector aligned
+offset 4295104768 is not sector aligned
+offset 4295105792 is not sector aligned
+offset 4295106816 is not sector aligned
+offset 4295107840 is not sector aligned
+offset 4295108864 is not sector aligned
+offset 4295109888 is not sector aligned
+offset 4295110912 is not sector aligned
+offset 4295111936 is not sector aligned
+offset 4295112960 is not sector aligned
+offset 4295113984 is not sector aligned
 === IO: pattern 33
 read 2048/2048 bytes at offset 4295115264
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -4048,85 +3616,49 @@ wrote 512/512 bytes at offset 105984
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 512/512 bytes at offset 107008
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 108032
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 109056
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 110080
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-=== IO: pattern 217
-wrote 512/512 bytes at offset 111360
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 112384
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 113408
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 114432
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 115456
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 116480
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 117504
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 118528
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 119552
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 120576
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 121600
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 122624
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 123648
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 124672
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 125696
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 126720
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 127744
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 128768
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 129792
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 130816
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 131840
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 132864
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 133888
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 134912
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 135936
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 136960
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 137984
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 139008
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 140032
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 141056
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 142080
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 143104
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 144128
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 145152
+wrote 512/512 bytes at offset 108032
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 146176
+wrote 512/512 bytes at offset 109056
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 147200
+wrote 512/512 bytes at offset 110080
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+=== IO: pattern 217
+offset 111360 is not sector aligned
+offset 112384 is not sector aligned
+offset 113408 is not sector aligned
+offset 114432 is not sector aligned
+offset 115456 is not sector aligned
+offset 116480 is not sector aligned
+offset 117504 is not sector aligned
+offset 118528 is not sector aligned
+offset 119552 is not sector aligned
+offset 120576 is not sector aligned
+offset 121600 is not sector aligned
+offset 122624 is not sector aligned
+offset 123648 is not sector aligned
+offset 124672 is not sector aligned
+offset 125696 is not sector aligned
+offset 126720 is not sector aligned
+offset 127744 is not sector aligned
+offset 128768 is not sector aligned
+offset 129792 is not sector aligned
+offset 130816 is not sector aligned
+offset 131840 is not sector aligned
+offset 132864 is not sector aligned
+offset 133888 is not sector aligned
+offset 134912 is not sector aligned
+offset 135936 is not sector aligned
+offset 136960 is not sector aligned
+offset 137984 is not sector aligned
+offset 139008 is not sector aligned
+offset 140032 is not sector aligned
+offset 141056 is not sector aligned
+offset 142080 is not sector aligned
+offset 143104 is not sector aligned
+offset 144128 is not sector aligned
+offset 145152 is not sector aligned
+offset 146176 is not sector aligned
+offset 147200 is not sector aligned
 === IO: pattern 34
 wrote 2048/2048 bytes at offset 148480
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -4373,78 +3905,42 @@ read 512/512 bytes at offset 109056
 read 512/512 bytes at offset 110080
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 217
-read 512/512 bytes at offset 111360
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 112384
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 113408
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 114432
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 115456
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 116480
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 117504
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 118528
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 119552
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 120576
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 121600
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 122624
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 123648
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 124672
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 125696
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 126720
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 127744
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 128768
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 129792
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 130816
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 131840
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 132864
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 133888
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 134912
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 135936
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 136960
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 137984
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 139008
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 140032
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 141056
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 142080
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 143104
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 144128
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 145152
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 146176
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 147200
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 111360 is not sector aligned
+offset 112384 is not sector aligned
+offset 113408 is not sector aligned
+offset 114432 is not sector aligned
+offset 115456 is not sector aligned
+offset 116480 is not sector aligned
+offset 117504 is not sector aligned
+offset 118528 is not sector aligned
+offset 119552 is not sector aligned
+offset 120576 is not sector aligned
+offset 121600 is not sector aligned
+offset 122624 is not sector aligned
+offset 123648 is not sector aligned
+offset 124672 is not sector aligned
+offset 125696 is not sector aligned
+offset 126720 is not sector aligned
+offset 127744 is not sector aligned
+offset 128768 is not sector aligned
+offset 129792 is not sector aligned
+offset 130816 is not sector aligned
+offset 131840 is not sector aligned
+offset 132864 is not sector aligned
+offset 133888 is not sector aligned
+offset 134912 is not sector aligned
+offset 135936 is not sector aligned
+offset 136960 is not sector aligned
+offset 137984 is not sector aligned
+offset 139008 is not sector aligned
+offset 140032 is not sector aligned
+offset 141056 is not sector aligned
+offset 142080 is not sector aligned
+offset 143104 is not sector aligned
+offset 144128 is not sector aligned
+offset 145152 is not sector aligned
+offset 146176 is not sector aligned
+offset 147200 is not sector aligned
 === IO: pattern 34
 read 2048/2048 bytes at offset 148480
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -4691,78 +4187,42 @@ wrote 512/512 bytes at offset 109056
 wrote 512/512 bytes at offset 110080
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 217
-wrote 512/512 bytes at offset 111360
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 112384
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 113408
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 114432
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 115456
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 116480
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 117504
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 118528
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 119552
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 120576
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 121600
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 122624
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 123648
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 124672
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 125696
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 126720
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 127744
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 128768
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 129792
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 130816
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 131840
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 132864
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 133888
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 134912
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 135936
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 136960
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 137984
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 139008
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 140032
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 141056
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 142080
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 143104
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 144128
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 145152
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 146176
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 147200
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 111360 is not sector aligned
+offset 112384 is not sector aligned
+offset 113408 is not sector aligned
+offset 114432 is not sector aligned
+offset 115456 is not sector aligned
+offset 116480 is not sector aligned
+offset 117504 is not sector aligned
+offset 118528 is not sector aligned
+offset 119552 is not sector aligned
+offset 120576 is not sector aligned
+offset 121600 is not sector aligned
+offset 122624 is not sector aligned
+offset 123648 is not sector aligned
+offset 124672 is not sector aligned
+offset 125696 is not sector aligned
+offset 126720 is not sector aligned
+offset 127744 is not sector aligned
+offset 128768 is not sector aligned
+offset 129792 is not sector aligned
+offset 130816 is not sector aligned
+offset 131840 is not sector aligned
+offset 132864 is not sector aligned
+offset 133888 is not sector aligned
+offset 134912 is not sector aligned
+offset 135936 is not sector aligned
+offset 136960 is not sector aligned
+offset 137984 is not sector aligned
+offset 139008 is not sector aligned
+offset 140032 is not sector aligned
+offset 141056 is not sector aligned
+offset 142080 is not sector aligned
+offset 143104 is not sector aligned
+offset 144128 is not sector aligned
+offset 145152 is not sector aligned
+offset 146176 is not sector aligned
+offset 147200 is not sector aligned
 === IO: pattern 34
 wrote 2048/2048 bytes at offset 148480
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -5009,78 +4469,42 @@ read 512/512 bytes at offset 109056
 read 512/512 bytes at offset 110080
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 217
-read 512/512 bytes at offset 111360
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 112384
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 113408
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 114432
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 115456
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 116480
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 117504
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 118528
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 119552
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 120576
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 121600
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 122624
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 123648
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 124672
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 125696
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 126720
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 127744
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 128768
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 129792
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 130816
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 131840
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 132864
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 133888
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 134912
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 135936
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 136960
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 137984
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 139008
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 140032
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 141056
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 142080
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 143104
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 144128
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 145152
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 146176
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 147200
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 111360 is not sector aligned
+offset 112384 is not sector aligned
+offset 113408 is not sector aligned
+offset 114432 is not sector aligned
+offset 115456 is not sector aligned
+offset 116480 is not sector aligned
+offset 117504 is not sector aligned
+offset 118528 is not sector aligned
+offset 119552 is not sector aligned
+offset 120576 is not sector aligned
+offset 121600 is not sector aligned
+offset 122624 is not sector aligned
+offset 123648 is not sector aligned
+offset 124672 is not sector aligned
+offset 125696 is not sector aligned
+offset 126720 is not sector aligned
+offset 127744 is not sector aligned
+offset 128768 is not sector aligned
+offset 129792 is not sector aligned
+offset 130816 is not sector aligned
+offset 131840 is not sector aligned
+offset 132864 is not sector aligned
+offset 133888 is not sector aligned
+offset 134912 is not sector aligned
+offset 135936 is not sector aligned
+offset 136960 is not sector aligned
+offset 137984 is not sector aligned
+offset 139008 is not sector aligned
+offset 140032 is not sector aligned
+offset 141056 is not sector aligned
+offset 142080 is not sector aligned
+offset 143104 is not sector aligned
+offset 144128 is not sector aligned
+offset 145152 is not sector aligned
+offset 146176 is not sector aligned
+offset 147200 is not sector aligned
 === IO: pattern 34
 read 2048/2048 bytes at offset 148480
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -5329,78 +4753,42 @@ wrote 512/512 bytes at offset 4295076352
 wrote 512/512 bytes at offset 4295077376
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 217
-wrote 512/512 bytes at offset 4295078656
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295079680
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295080704
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295081728
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295082752
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295083776
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295084800
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295085824
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295086848
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295087872
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295088896
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295089920
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295090944
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295091968
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295092992
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295094016
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295095040
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295096064
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295097088
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295098112
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295099136
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295100160
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295101184
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295102208
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295103232
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295104256
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295105280
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295106304
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295107328
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295108352
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295109376
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295110400
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295111424
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295112448
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295113472
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295114496
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 4295078656 is not sector aligned
+offset 4295079680 is not sector aligned
+offset 4295080704 is not sector aligned
+offset 4295081728 is not sector aligned
+offset 4295082752 is not sector aligned
+offset 4295083776 is not sector aligned
+offset 4295084800 is not sector aligned
+offset 4295085824 is not sector aligned
+offset 4295086848 is not sector aligned
+offset 4295087872 is not sector aligned
+offset 4295088896 is not sector aligned
+offset 4295089920 is not sector aligned
+offset 4295090944 is not sector aligned
+offset 4295091968 is not sector aligned
+offset 4295092992 is not sector aligned
+offset 4295094016 is not sector aligned
+offset 4295095040 is not sector aligned
+offset 4295096064 is not sector aligned
+offset 4295097088 is not sector aligned
+offset 4295098112 is not sector aligned
+offset 4295099136 is not sector aligned
+offset 4295100160 is not sector aligned
+offset 4295101184 is not sector aligned
+offset 4295102208 is not sector aligned
+offset 4295103232 is not sector aligned
+offset 4295104256 is not sector aligned
+offset 4295105280 is not sector aligned
+offset 4295106304 is not sector aligned
+offset 4295107328 is not sector aligned
+offset 4295108352 is not sector aligned
+offset 4295109376 is not sector aligned
+offset 4295110400 is not sector aligned
+offset 4295111424 is not sector aligned
+offset 4295112448 is not sector aligned
+offset 4295113472 is not sector aligned
+offset 4295114496 is not sector aligned
 === IO: pattern 34
 wrote 2048/2048 bytes at offset 4295115776
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -5647,78 +5035,42 @@ read 512/512 bytes at offset 4295076352
 read 512/512 bytes at offset 4295077376
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 217
-read 512/512 bytes at offset 4295078656
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295079680
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295080704
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295081728
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295082752
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295083776
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295084800
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295085824
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295086848
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295087872
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295088896
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295089920
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295090944
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295091968
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295092992
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295094016
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295095040
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295096064
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295097088
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295098112
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295099136
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295100160
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295101184
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295102208
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295103232
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295104256
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295105280
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295106304
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295107328
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295108352
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295109376
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295110400
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295111424
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295112448
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295113472
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295114496
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 4295078656 is not sector aligned
+offset 4295079680 is not sector aligned
+offset 4295080704 is not sector aligned
+offset 4295081728 is not sector aligned
+offset 4295082752 is not sector aligned
+offset 4295083776 is not sector aligned
+offset 4295084800 is not sector aligned
+offset 4295085824 is not sector aligned
+offset 4295086848 is not sector aligned
+offset 4295087872 is not sector aligned
+offset 4295088896 is not sector aligned
+offset 4295089920 is not sector aligned
+offset 4295090944 is not sector aligned
+offset 4295091968 is not sector aligned
+offset 4295092992 is not sector aligned
+offset 4295094016 is not sector aligned
+offset 4295095040 is not sector aligned
+offset 4295096064 is not sector aligned
+offset 4295097088 is not sector aligned
+offset 4295098112 is not sector aligned
+offset 4295099136 is not sector aligned
+offset 4295100160 is not sector aligned
+offset 4295101184 is not sector aligned
+offset 4295102208 is not sector aligned
+offset 4295103232 is not sector aligned
+offset 4295104256 is not sector aligned
+offset 4295105280 is not sector aligned
+offset 4295106304 is not sector aligned
+offset 4295107328 is not sector aligned
+offset 4295108352 is not sector aligned
+offset 4295109376 is not sector aligned
+offset 4295110400 is not sector aligned
+offset 4295111424 is not sector aligned
+offset 4295112448 is not sector aligned
+offset 4295113472 is not sector aligned
+offset 4295114496 is not sector aligned
 === IO: pattern 34
 read 2048/2048 bytes at offset 4295115776
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -5965,78 +5317,42 @@ wrote 512/512 bytes at offset 4295076352
 wrote 512/512 bytes at offset 4295077376
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 217
-wrote 512/512 bytes at offset 4295078656
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295079680
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295080704
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295081728
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295082752
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295083776
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295084800
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295085824
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295086848
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295087872
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295088896
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295089920
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295090944
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295091968
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295092992
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295094016
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295095040
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295096064
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295097088
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295098112
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295099136
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295100160
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295101184
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295102208
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295103232
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295104256
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295105280
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295106304
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295107328
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295108352
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295109376
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295110400
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295111424
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295112448
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295113472
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 512/512 bytes at offset 4295114496
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 4295078656 is not sector aligned
+offset 4295079680 is not sector aligned
+offset 4295080704 is not sector aligned
+offset 4295081728 is not sector aligned
+offset 4295082752 is not sector aligned
+offset 4295083776 is not sector aligned
+offset 4295084800 is not sector aligned
+offset 4295085824 is not sector aligned
+offset 4295086848 is not sector aligned
+offset 4295087872 is not sector aligned
+offset 4295088896 is not sector aligned
+offset 4295089920 is not sector aligned
+offset 4295090944 is not sector aligned
+offset 4295091968 is not sector aligned
+offset 4295092992 is not sector aligned
+offset 4295094016 is not sector aligned
+offset 4295095040 is not sector aligned
+offset 4295096064 is not sector aligned
+offset 4295097088 is not sector aligned
+offset 4295098112 is not sector aligned
+offset 4295099136 is not sector aligned
+offset 4295100160 is not sector aligned
+offset 4295101184 is not sector aligned
+offset 4295102208 is not sector aligned
+offset 4295103232 is not sector aligned
+offset 4295104256 is not sector aligned
+offset 4295105280 is not sector aligned
+offset 4295106304 is not sector aligned
+offset 4295107328 is not sector aligned
+offset 4295108352 is not sector aligned
+offset 4295109376 is not sector aligned
+offset 4295110400 is not sector aligned
+offset 4295111424 is not sector aligned
+offset 4295112448 is not sector aligned
+offset 4295113472 is not sector aligned
+offset 4295114496 is not sector aligned
 === IO: pattern 34
 wrote 2048/2048 bytes at offset 4295115776
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -6283,78 +5599,42 @@ read 512/512 bytes at offset 4295076352
 read 512/512 bytes at offset 4295077376
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 === IO: pattern 217
-read 512/512 bytes at offset 4295078656
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295079680
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295080704
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295081728
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295082752
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295083776
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295084800
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295085824
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295086848
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295087872
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295088896
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295089920
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295090944
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295091968
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295092992
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295094016
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295095040
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295096064
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295097088
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295098112
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295099136
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295100160
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295101184
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295102208
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295103232
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295104256
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295105280
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295106304
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295107328
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295108352
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295109376
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295110400
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295111424
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295112448
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295113472
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 512/512 bytes at offset 4295114496
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+offset 4295078656 is not sector aligned
+offset 4295079680 is not sector aligned
+offset 4295080704 is not sector aligned
+offset 4295081728 is not sector aligned
+offset 4295082752 is not sector aligned
+offset 4295083776 is not sector aligned
+offset 4295084800 is not sector aligned
+offset 4295085824 is not sector aligned
+offset 4295086848 is not sector aligned
+offset 4295087872 is not sector aligned
+offset 4295088896 is not sector aligned
+offset 4295089920 is not sector aligned
+offset 4295090944 is not sector aligned
+offset 4295091968 is not sector aligned
+offset 4295092992 is not sector aligned
+offset 4295094016 is not sector aligned
+offset 4295095040 is not sector aligned
+offset 4295096064 is not sector aligned
+offset 4295097088 is not sector aligned
+offset 4295098112 is not sector aligned
+offset 4295099136 is not sector aligned
+offset 4295100160 is not sector aligned
+offset 4295101184 is not sector aligned
+offset 4295102208 is not sector aligned
+offset 4295103232 is not sector aligned
+offset 4295104256 is not sector aligned
+offset 4295105280 is not sector aligned
+offset 4295106304 is not sector aligned
+offset 4295107328 is not sector aligned
+offset 4295108352 is not sector aligned
+offset 4295109376 is not sector aligned
+offset 4295110400 is not sector aligned
+offset 4295111424 is not sector aligned
+offset 4295112448 is not sector aligned
+offset 4295113472 is not sector aligned
+offset 4295114496 is not sector aligned
 === IO: pattern 34
 read 2048/2048 bytes at offset 4295115776
 2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
index 8531735..d84d82c 100644 (file)
@@ -14,6 +14,7 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_update; errno: 5; imm: off; once: off; write
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 
@@ -22,6 +23,7 @@ This means waste of disk space, but no harm to data.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_update; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 
@@ -40,6 +42,7 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_update; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 
@@ -48,6 +51,7 @@ This means waste of disk space, but no harm to data.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_update; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 
@@ -74,7 +78,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 Event: l2_load; errno: 5; imm: off; once: off; write
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 read failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@@ -82,7 +90,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 Event: l2_load; errno: 5; imm: off; once: off; write -b
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 read failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@@ -106,7 +118,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 Event: l2_load; errno: 28; imm: off; once: off; write
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 read failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@@ -114,7 +130,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 Event: l2_load; errno: 28; imm: off; once: off; write -b
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 read failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@@ -286,12 +306,14 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_load; errno: 5; imm: off; once: off; write
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_load; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
@@ -308,12 +330,14 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_load; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_load; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
@@ -330,12 +354,14 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_update_part; errno: 5; imm: off; once: off; write
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_update_part; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
@@ -352,12 +378,14 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_update_part; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_update_part; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
@@ -374,12 +402,14 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc; errno: 5; imm: off; once: off; write
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
@@ -396,12 +426,14 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
@@ -418,11 +450,15 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: cluster_alloc; errno: 5; imm: off; once: off; write
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: cluster_alloc; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@@ -438,11 +474,15 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: cluster_alloc; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: cluster_alloc; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
 
@@ -513,6 +553,7 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 
@@ -521,6 +562,7 @@ This means waste of disk space, but no harm to data.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 
@@ -539,6 +581,7 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 
@@ -547,6 +590,7 @@ This means waste of disk space, but no harm to data.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 
@@ -591,6 +635,8 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_alloc_table; errno: 5; imm: off; once: off
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@@ -601,6 +647,8 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_alloc_table; errno: 28; imm: off; once: off
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@@ -611,6 +659,7 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_write_table; errno: 5; imm: off; once: off
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
@@ -622,6 +671,7 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_write_table; errno: 28; imm: off; once: off
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
index 672d77c..9c2c8a9 100644 (file)
@@ -14,6 +14,7 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: l1_update; errno: 5; imm: off; once: off; write 
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 
@@ -22,6 +23,7 @@ This means waste of disk space, but no harm to data.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: l1_update; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 
@@ -40,6 +42,7 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: l1_update; errno: 28; imm: off; once: off; write 
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 
@@ -48,6 +51,7 @@ This means waste of disk space, but no harm to data.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: l1_update; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 
@@ -74,7 +78,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 Event: l2_load; errno: 5; imm: off; once: off; write 
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 read failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
@@ -82,7 +90,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 Event: l2_load; errno: 5; imm: off; once: off; write -b
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 read failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
@@ -106,7 +118,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 Event: l2_load; errno: 28; imm: off; once: off; write 
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 read failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
@@ -114,7 +130,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 Event: l2_load; errno: 28; imm: off; once: off; write -b
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 read failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
@@ -294,12 +314,14 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_load; errno: 5; imm: off; once: off; write 
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_load; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
@@ -316,12 +338,14 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_load; errno: 28; imm: off; once: off; write 
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_load; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
@@ -338,12 +362,14 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_update_part; errno: 5; imm: off; once: off; write 
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_update_part; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
@@ -360,12 +386,14 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_update_part; errno: 28; imm: off; once: off; write 
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_update_part; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
@@ -382,12 +410,14 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_alloc; errno: 5; imm: off; once: off; write 
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_alloc; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
@@ -404,12 +434,14 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_alloc; errno: 28; imm: off; once: off; write 
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_alloc; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
@@ -426,11 +458,15 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: cluster_alloc; errno: 5; imm: off; once: off; write 
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: cluster_alloc; errno: 5; imm: off; once: off; write -b
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
@@ -446,11 +482,15 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: cluster_alloc; errno: 28; imm: off; once: off; write 
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: cluster_alloc; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
 
@@ -521,6 +561,7 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write 
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 
@@ -529,6 +570,7 @@ This means waste of disk space, but no harm to data.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 
@@ -547,6 +589,7 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write 
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 
@@ -555,6 +598,7 @@ This means waste of disk space, but no harm to data.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write -b
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 
@@ -599,6 +643,8 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: l1_grow_alloc_table; errno: 5; imm: off; once: off
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
@@ -609,6 +655,8 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: l1_grow_alloc_table; errno: 28; imm: off; once: off
+Failed to flush the L2 table cache: No space left on device
+Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
@@ -619,6 +667,7 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: l1_grow_write_table; errno: 5; imm: off; once: off
+Failed to flush the L2 table cache: Input/output error
 Failed to flush the refcount block cache: Input/output error
 write failed: Input/output error
 No errors were found on the image.
@@ -630,6 +679,7 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
 
 Event: l1_grow_write_table; errno: 28; imm: off; once: off
+Failed to flush the L2 table cache: No space left on device
 Failed to flush the refcount block cache: No space left on device
 write failed: No space left on device
 No errors were found on the image.
index 1b28bda..c711cfc 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/bash
 #
-# Test bdrv_pwrite_zeroes with backing files (see also 154)
+# Test bdrv_write_zeroes with backing files
 #
 # Copyright (C) 2012 Red Hat, Inc.
 #
index c6e0ac2..32c8846 100644 (file)
@@ -12,9 +12,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 ./common.config: Killed                  ( if [ "${VALGRIND_QEMU}" == "y" ]; then
-    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 else
-    exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 fi )
 incompatible_features     0x1
 ERROR cluster 5 refcount=0 reference=1
@@ -51,9 +51,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 ./common.config: Killed                  ( if [ "${VALGRIND_QEMU}" == "y" ]; then
-    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 else
-    exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 fi )
 incompatible_features     0x1
 ERROR cluster 5 refcount=0 reference=1
@@ -69,9 +69,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 ./common.config: Killed                  ( if [ "${VALGRIND_QEMU}" == "y" ]; then
-    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 else
-    exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 fi )
 incompatible_features     0x0
 No errors were found on the image.
@@ -92,9 +92,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 ./common.config: Killed                  ( if [ "${VALGRIND_QEMU}" == "y" ]; then
-    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 else
-    exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 fi )
 incompatible_features     0x1
 ERROR cluster 5 refcount=0 reference=1
@@ -106,9 +106,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 ./common.config: Killed                  ( if [ "${VALGRIND_QEMU}" == "y" ]; then
-    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 else
-    exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 fi )
 incompatible_features     0x0
 No errors were found on the image.
index cbf5e0b..b1c542f 100755 (executable)
@@ -207,6 +207,33 @@ class TestSingleBlockdev(TestSingleDrive):
     test_image_not_found = None
     test_small_buffer2 = None
 
+class TestBlockdevAttached(iotests.QMPTestCase):
+    image_len = 1 * 1024 * 1024 # MB
+
+    def setUp(self):
+        iotests.create_image(backing_img, self.image_len)
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img)
+        self.vm = iotests.VM().add_drive(test_img)
+        self.vm.launch()
+
+    def tearDown(self):
+        self.vm.shutdown()
+        os.remove(test_img)
+        os.remove(target_img)
+
+    def test_blockdev_attached(self):
+        self.assert_no_active_block_jobs()
+        args = {'options':
+                    {'driver': iotests.imgfmt,
+                     'id': 'drive1',
+                     'file': { 'filename': target_img, 'driver': 'file' } } }
+        result = self.vm.qmp("blockdev-add", **args)
+        self.assert_qmp(result, 'return', {})
+        result = self.vm.qmp('blockdev-mirror', device='drive0', sync='full',
+                             target='drive1')
+        self.assert_qmp(result, 'error/class', 'GenericError')
+
 class TestSingleDriveZeroLength(TestSingleDrive):
     image_len = 0
     test_small_buffer2 = None
@@ -727,36 +754,6 @@ class TestUnbackedSource(iotests.QMPTestCase):
         self.complete_and_wait()
         self.assert_no_active_block_jobs()
 
-class TestGranularity(iotests.QMPTestCase):
-    image_len = 10 * 1024 * 1024 # MB
-
-    def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, test_img,
-                 str(TestGranularity.image_len))
-        qemu_io('-c', 'write 0 %d' % (self.image_len),
-                test_img)
-        self.vm = iotests.VM().add_drive(test_img)
-        self.vm.launch()
-
-    def tearDown(self):
-        self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
-                        'target image does not match source after mirroring')
-        os.remove(test_img)
-        os.remove(target_img)
-
-    def test_granularity(self):
-        self.assert_no_active_block_jobs()
-        result = self.vm.qmp('drive-mirror', device='drive0',
-                             sync='full', target=target_img,
-                             mode='absolute-paths', granularity=8192)
-        self.assert_qmp(result, 'return', {})
-        event = self.vm.get_qmp_event(wait=60.0)
-        # Failures will manifest as COMPLETED/ERROR.
-        self.assert_qmp(event, 'event', 'BLOCK_JOB_READY')
-        self.complete_and_wait(drive='drive0', wait_ready=False)
-        self.assert_no_active_block_jobs()
-
 class TestRepairQuorum(iotests.QMPTestCase):
     """ This class test quorum file repair using drive-mirror.
         It's mostly a fork of TestSingleDrive """
index 203c04f..e1eeac2 100755 (executable)
@@ -31,13 +31,13 @@ _cleanup()
 {
     echo "Cleanup"
     _cleanup_test_img
-    rm "${TEST_IMG_FILE2}"
+    rm "${TEST_IMG2}"
 }
 trap "_cleanup; exit \$status" 0 1 2 3 15
 
 _compare()
 {
-    $QEMU_IMG compare $QEMU_IMG_EXTRA_ARGS "$@" "$TEST_IMG" "${TEST_IMG2}"
+    $QEMU_IMG compare "$@" "$TEST_IMG" "${TEST_IMG2}"
     echo $?
 }
 
@@ -46,37 +46,25 @@ _compare()
 . ./common.filter
 . ./common.pattern
 
-_supported_fmt raw qcow qcow2 qed luks
+_supported_fmt raw qcow qcow2 qed
 _supported_proto file
 _supported_os Linux
 
-# Remove once all tests are fixed to use TEST_IMG_FILE
-# correctly and common.rc sets it unconditionally
-test -z "$TEST_IMG_FILE" && TEST_IMG_FILE=$TEST_IMG
-
 # Setup test basic parameters
 TEST_IMG2=$TEST_IMG.2
-TEST_IMG_FILE2=$TEST_IMG_FILE.2
 CLUSTER_SIZE=4096
-size=128M
+size=1024M
 
 _make_test_img $size
 io_pattern write 524288 $CLUSTER_SIZE $CLUSTER_SIZE 4 45
 
 # Compare identical images
-cp "$TEST_IMG_FILE" "${TEST_IMG_FILE2}"
+cp "$TEST_IMG" "${TEST_IMG2}"
 _compare
 _compare -q
 
 # Compare images with different size
-if [ "$IMGOPTSSYNTAX" = "true" ]; then
-    $QEMU_IMG resize $QEMU_IMG_EXTRA_ARGS "$TEST_IMG" +32M
-else
-    $QEMU_IMG resize -f $IMGFMT "$TEST_IMG" +32M
-fi
-# Ensure extended space is zero-initialized
-$QEMU_IO "$TEST_IMG" -c "write -z $size 32M" | _filter_qemu_io
-
+$QEMU_IMG resize -f $IMGFMT "$TEST_IMG" +512M
 _compare
 _compare -s
 
@@ -89,7 +77,7 @@ _compare
 # Test unaligned case of mismatch offsets in allocated clusters
 _make_test_img $size
 io_pattern write 0 512 0 1 100
-cp "$TEST_IMG_FILE" "$TEST_IMG_FILE2"
+cp "$TEST_IMG" "$TEST_IMG2"
 io_pattern write 512 512 0 1 101
 _compare
 
index 0bcf663..57100dc 100644 (file)
@@ -1,5 +1,5 @@
 QA output created by 048
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 === IO: pattern 45
 wrote 4096/4096 bytes at offset 524288
 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -13,8 +13,6 @@ Images are identical.
 0
 0
 Image resized.
-wrote 33554432/33554432 bytes at offset 134217728
-32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 Warning: Image size mismatch!
 Images are identical.
 0
@@ -30,7 +28,7 @@ wrote 4096/4096 bytes at offset 0
 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 Content mismatch at offset 0!
 1
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 === IO: pattern 100
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
index 842eace..4b64724 100755 (executable)
@@ -48,10 +48,6 @@ size=128M
 _make_test_img $size
 
 echo
-echo "== initializing whole image =="
-$QEMU_IO -c "write -z 0 $size" "$TEST_IMG" | _filter_qemu_io
-
-echo
 echo "== reading whole image =="
 $QEMU_IO -s -c "read 0 $size" "$TEST_IMG" | _filter_qemu_io
 
index a377d30..9dab51c 100644 (file)
@@ -1,10 +1,6 @@
 QA output created by 052
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
 
-== initializing whole image ==
-wrote 134217728/134217728 bytes at offset 0
-128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
 == reading whole image ==
 read 134217728/134217728 bytes at offset 0
 128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
index a431b7f..a03732e 100644 (file)
@@ -58,9 +58,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 ./common.config: Killed                  ( if [ "${VALGRIND_QEMU}" == "y" ]; then
-    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 else
-    exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 fi )
 magic                     0x514649fb
 version                   3
@@ -220,9 +220,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 ./common.config: Killed                  ( if [ "${VALGRIND_QEMU}" == "y" ]; then
-    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 else
-    exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 fi )
 magic                     0x514649fb
 version                   3
index 8c6851e..2b40ead 100644 (file)
@@ -30,10 +30,14 @@ blkverify: read sector_num=0 nb_sectors=1 contents mismatch in sector 0
 
 === Testing blkdebug through filename ===
 
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 read failed: Input/output error
 
 === Testing blkdebug through file blockref ===
 
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 read failed: Input/output error
 
 === Testing blkdebug on existing block device ===
@@ -47,6 +51,8 @@ read failed: Input/output error
 {"return": ""}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
+QEMU_PROG: Failed to flush the L2 table cache: Input/output error
+QEMU_PROG: Failed to flush the refcount block cache: Input/output error
 
 
 === Testing blkverify on existing block device ===
@@ -86,5 +92,7 @@ read failed: Input/output error
 {"return": ""}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
+QEMU_PROG: Failed to flush the L2 table cache: Input/output error
+QEMU_PROG: Failed to flush the refcount block cache: Input/output error
 
 *** done
index d2d2a2d..4dc680b 100755 (executable)
@@ -60,7 +60,7 @@ EOF
 
 # Sequential RMW requests on the same physical sector
 off=0x1000
-for ev in "head" "after_head"; do
+for ev in "head" "after_head" "tail" "after_tail"; do
 cat  <<EOF
 break pwritev_rmw_$ev A
 aio_write -P 10 $((off + 0x200)) 0x200
@@ -211,6 +211,16 @@ function verify_io()
     echo read -P 11 0x2400 0x200
     echo read -P 0  0x2600 0xa00
 
+    echo read -P 0  0x3000 0x200
+    echo read -P 10 0x3200 0x200
+    echo read -P 11 0x3400 0x200
+    echo read -P 0  0x3600 0xa00
+
+    echo read -P 0  0x4000 0x200
+    echo read -P 10 0x4200 0x200
+    echo read -P 11 0x4400 0x200
+    echo read -P 0  0x4600 0xa00
+
     # Chained dependencies
     echo read -P 10 0x5000 0x200
     echo read -P 11 0x5200 0x200
index 16f951f..eab14ae 100644 (file)
@@ -19,6 +19,16 @@ wrote XXX/XXX bytes at offset XXX
 XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote XXX/XXX bytes at offset XXX
 XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+blkdebug: Resuming request 'A'
+wrote XXX/XXX bytes at offset XXX
+XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote XXX/XXX bytes at offset XXX
+XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+blkdebug: Resuming request 'A'
+wrote XXX/XXX bytes at offset XXX
+XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote XXX/XXX bytes at offset XXX
+XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote XXX/XXX bytes at offset XXX
 XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote XXX/XXX bytes at offset XXX
@@ -104,6 +114,22 @@ read 512/512 bytes at offset 9216
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 read 2560/2560 bytes at offset 9728
 2.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 12288
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 12800
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 13312
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 2560/2560 bytes at offset 13824
+2.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 16384
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 16896
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 17408
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 2560/2560 bytes at offset 17920
+2.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 read 512/512 bytes at offset 20480
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 read 512/512 bytes at offset 20992
index bff9360..bc724ae 100755 (executable)
@@ -43,7 +43,7 @@ choose_tcp_port() {
 
 wait_for_tcp_port() {
        while ! (netstat --tcp --listening --numeric | \
-                grep "$1.*0\\.0\\.0\\.0:\\*.*LISTEN") >/dev/null 2>&1; do
+                grep "$1.*0\\.0\\.0\\.0:\\*.*LISTEN") 2>&1 >/dev/null; do
                sleep 0.1
        done
 }
@@ -70,7 +70,7 @@ EOF
                nbd_url="nbd:127.0.0.1:$port:exportname=foo"
        fi
 
-       $PYTHON nbd-fault-injector.py $extra_args "127.0.0.1:$port" "$TEST_DIR/nbd-fault-injector.conf" >/dev/null 2>&1 &
+       $PYTHON nbd-fault-injector.py $extra_args "127.0.0.1:$port" "$TEST_DIR/nbd-fault-injector.conf" 2>&1 >/dev/null &
        wait_for_tcp_port "127\\.0\\.0\\.1:$port"
        $QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | _filter_nbd
 
index a95c4b0..055c553 100644 (file)
@@ -42,14 +42,22 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
 Testing: -S
 QMP_VERSION
 {"return": {}}
-{"error": {"class": "GenericError", "desc": "Use of AES-CBC encrypted IMGFMT images is no longer supported in system emulators"}}
+IMGFMT built-in AES encryption is deprecated
+Support for it will be removed in a future release.
+You can use 'qemu-img convert' to switch to an
+unencrypted IMGFMT image, or a LUKS raw image.
+{"error": {"class": "GenericError", "desc": "blockdev-add doesn't support encrypted devices"}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
 
 Testing:
 QMP_VERSION
 {"return": {}}
-{"error": {"class": "GenericError", "desc": "Use of AES-CBC encrypted IMGFMT images is no longer supported in system emulators"}}
+IMGFMT built-in AES encryption is deprecated
+Support for it will be removed in a future release.
+You can use 'qemu-img convert' to switch to an
+unencrypted IMGFMT image, or a LUKS raw image.
+{"error": {"class": "GenericError", "desc": "Guest must be stopped for opening of encrypted image"}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
 
index 18f5fdd..5b541a3 100644 (file)
@@ -24,6 +24,8 @@ read 512/512 bytes at offset 0
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 wrote 512/512 bytes at offset 229376
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Failed to flush the L2 table cache: Input/output error
+Failed to flush the refcount block cache: Input/output error
 read failed: Input/output error
 
 === Testing qemu-img info output ===
index 030adb2..dad04b9 100755 (executable)
@@ -74,8 +74,6 @@ _send_qemu_cmd $h "{ 'execute': 'block-commit',
                                  'arguments': { 'device': 'test',
                                  'top': '"${TEST_IMG}.snp1"' } }" "BLOCK_JOB_COMPLETED"
 
-_cleanup_qemu
-
 echo
 echo "=== Base image info after commit and resize ==="
 TEST_IMG="${TEST_IMG}.base" _img_info | _filter_img_info
index aeeb375..e34204b 100644 (file)
@@ -45,9 +45,8 @@ class TestLiveSnapshot(iotests.QMPTestCase):
         os.remove(self.target_img)
 
     def checkConfig(self, active_layer):
-        result = self.vm.qmp('query-block')
+        result = self.vm.qmp('query-named-block-nodes')
         for r in result['return']:
-            r = r['inserted']
             if r['node-name'] == active_layer:
                 self.assertEqual(r['group'], self.group)
                 self.assertEqual(r['iops'], self.iops)
diff --git a/tests/qemu-iotests/100 b/tests/qemu-iotests/100
new file mode 100755 (executable)
index 0000000..5b2fb33
--- /dev/null
@@ -0,0 +1,145 @@
+#!/bin/bash
+#
+# Test simple read/write using plain bdrv_read/bdrv_write
+#
+# Copyright (C) 2014 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=stefanha@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1       # failure is the default!
+
+_cleanup()
+{
+       _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt generic
+_supported_proto generic
+_supported_os Linux
+
+
+size=128M
+
+echo
+echo "== Single request =="
+_make_test_img $size
+$QEMU_IO -c "multiwrite 0 4k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== verify pattern =="
+$QEMU_IO -c "read -P 0xcd 0 4k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0 4k 4k" "$TEST_IMG" | _filter_qemu_io
+
+_cleanup_test_img
+
+echo
+echo "== Sequential requests =="
+_make_test_img $size
+$QEMU_IO -c "multiwrite 0 4k ; 4k 4k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== verify pattern =="
+$QEMU_IO -c "read -P 0xcd 0 4k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0xce 4k 4k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0 8k 4k" "$TEST_IMG" | _filter_qemu_io
+
+_cleanup_test_img
+
+echo
+echo "== Superset overlapping requests =="
+_make_test_img $size
+$QEMU_IO -c "multiwrite 0 4k ; 1k 2k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== verify pattern =="
+# Order of overlapping in-flight requests is not guaranteed so we cannot verify
+# [1k, 3k) since it could have either pattern 0xcd or 0xce.
+$QEMU_IO -c "read -P 0xcd 0 1k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0xcd 3k 1k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0 4k 4k" "$TEST_IMG" | _filter_qemu_io
+
+_cleanup_test_img
+
+echo
+echo "== Subset overlapping requests =="
+_make_test_img $size
+$QEMU_IO -c "multiwrite 1k 2k ; 0k 4k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== verify pattern =="
+# Order of overlapping in-flight requests is not guaranteed so we cannot verify
+# [1k, 3k) since it could have either pattern 0xcd or 0xce.
+$QEMU_IO -c "read -P 0xce 0 1k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0xce 3k 1k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0 4k 4k" "$TEST_IMG" | _filter_qemu_io
+
+_cleanup_test_img
+
+echo
+echo "== Head overlapping requests =="
+_make_test_img $size
+$QEMU_IO -c "multiwrite 0k 2k ; 0k 4k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== verify pattern =="
+# Order of overlapping in-flight requests is not guaranteed so we cannot verify
+# [0k, 2k) since it could have either pattern 0xcd or 0xce.
+$QEMU_IO -c "read -P 0xce 2k 2k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0 4k 4k" "$TEST_IMG" | _filter_qemu_io
+
+_cleanup_test_img
+
+echo
+echo "== Tail overlapping requests =="
+_make_test_img $size
+$QEMU_IO -c "multiwrite 2k 2k ; 0k 4k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== verify pattern =="
+# Order of overlapping in-flight requests is not guaranteed so we cannot verify
+# [2k, 4k) since it could have either pattern 0xcd or 0xce.
+$QEMU_IO -c "read -P 0xce 0k 2k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0 4k 4k" "$TEST_IMG" | _filter_qemu_io
+
+_cleanup_test_img
+
+echo
+echo "== Disjoint requests =="
+_make_test_img $size
+$QEMU_IO -c "multiwrite 0 4k ; 64k 4k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== verify pattern =="
+$QEMU_IO -c "read -P 0xcd 0 4k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0 4k 60k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0xce 64k 4k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0 68k 4k" "$TEST_IMG" | _filter_qemu_io
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/100.out b/tests/qemu-iotests/100.out
new file mode 100644 (file)
index 0000000..0564903
--- /dev/null
@@ -0,0 +1,89 @@
+QA output created by 100
+
+== Single request ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+wrote 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verify pattern ==
+read 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 4096
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Sequential requests ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+wrote 8192/8192 bytes at offset 0
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verify pattern ==
+read 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 4096
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 8192
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Superset overlapping requests ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+wrote 6144/6144 bytes at offset 0
+6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verify pattern ==
+read 1024/1024 bytes at offset 0
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1024/1024 bytes at offset 3072
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 4096
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Subset overlapping requests ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+wrote 6144/6144 bytes at offset 1024
+6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verify pattern ==
+read 1024/1024 bytes at offset 0
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1024/1024 bytes at offset 3072
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 4096
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Head overlapping requests ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+wrote 6144/6144 bytes at offset 0
+6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verify pattern ==
+read 2048/2048 bytes at offset 2048
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 4096
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Tail overlapping requests ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+wrote 6144/6144 bytes at offset 2048
+6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verify pattern ==
+read 2048/2048 bytes at offset 0
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 4096
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Disjoint requests ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+wrote 8192/8192 bytes at offset 0
+8 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verify pattern ==
+read 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 61440/61440 bytes at offset 4096
+60 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 65536
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4096/4096 bytes at offset 69632
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+*** done
index 280ed27..f980b0c 100755 (executable)
@@ -100,10 +100,12 @@ for sample_img in empty.bochs iotest-dirtylog-10G-4M.vhdx parallels-v1 \
     _make_test_img 64M
     bzcat "$SAMPLE_IMG_DIR/$sample_img.bz2" > "$TEST_IMG.src"
 
-    run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR" | _filter_block_job_offset
+    run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR"
     $QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io
 
     run_qemu "$TEST_IMG" "$TEST_IMG.src" "'format': 'raw'," "BLOCK_JOB_READY"
+    # qemu-img compare can't handle unaligned file sizes
+    $QEMU_IMG resize -f raw "$TEST_IMG.src" +0
     $QEMU_IMG compare -f raw -F raw "$TEST_IMG" "$TEST_IMG.src"
 done
 
index e5d70d7..38bc073 100644 (file)
@@ -135,7 +135,7 @@ Automatically detecting the format is dangerous for raw images, write operations
 Specify the 'raw' format explicitly to remove the restrictions.
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
 {"return": []}
 read 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -143,6 +143,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
 {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Image resized.
 Warning: Image size mismatch!
 Images are identical.
 
@@ -155,7 +156,7 @@ Automatically detecting the format is dangerous for raw images, write operations
 Specify the 'raw' format explicitly to remove the restrictions.
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
 {"return": []}
 read 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -163,6 +164,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}}
 {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 31457280, "offset": 31457280, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Image resized.
 Warning: Image size mismatch!
 Images are identical.
 
@@ -175,7 +177,7 @@ Automatically detecting the format is dangerous for raw images, write operations
 Specify the 'raw' format explicitly to remove the restrictions.
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
 {"return": []}
 read 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -183,6 +185,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
 {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Image resized.
 Warning: Image size mismatch!
 Images are identical.
 
@@ -195,7 +198,7 @@ Automatically detecting the format is dangerous for raw images, write operations
 Specify the 'raw' format explicitly to remove the restrictions.
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2048, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2048, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
 {"return": []}
 read 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -203,6 +206,7 @@ read 65536/65536 bytes at offset 0
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}}
 {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2048, "offset": 2048, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
+Image resized.
 Warning: Image size mismatch!
 Images are identical.
 
index 635b977..e8c6937 100644 (file)
@@ -226,11 +226,18 @@ sector = "%d"
 
         highest_offset = wr_ops * wr_size
 
-        for i in range(invalid_rd_ops):
-            ops.append("aio_read -i 0 512")
+        # Two types of invalid operations: unaligned length and unaligned offset
+        for i in range(invalid_rd_ops / 2):
+            ops.append("aio_read 0 511")
 
-        for i in range(invalid_wr_ops):
-            ops.append("aio_write -i 0 512")
+        for i in range(invalid_rd_ops / 2, invalid_rd_ops):
+            ops.append("aio_read 13 512")
+
+        for i in range(invalid_wr_ops / 2):
+            ops.append("aio_write 0 511")
+
+        for i in range(invalid_wr_ops / 2, invalid_wr_ops):
+            ops.append("aio_write 13 512")
 
         for i in range(failed_rd_ops):
             ops.append("aio_read %d 512" % bad_offset)
@@ -241,6 +248,14 @@ sector = "%d"
         if failed_wr_ops > 0:
             highest_offset = max(highest_offset, bad_offset + 512)
 
+        for i in range(wr_merged):
+            first = i * wr_size * 2
+            second = first + wr_size
+            ops.append("multiwrite %d %d ; %d %d" %
+                       (first, wr_size, second, wr_size))
+
+        highest_offset = max(highest_offset, wr_merged * wr_size * 2)
+
         # Now perform all operations
         for op in ops:
             self.vm.hmp_qemu_io("drive0", op)
@@ -294,15 +309,19 @@ sector = "%d"
     def test_flush(self):
         self.do_test_stats(flush_ops = 8)
 
+    def test_merged(self):
+        for i in range(5):
+            self.do_test_stats(wr_merged = i * 3)
+
     def test_all(self):
         # rd_size, rd_ops, wr_size, wr_ops, flush_ops
         # invalid_rd_ops,  invalid_wr_ops,
         # failed_rd_ops,   failed_wr_ops
         # wr_merged
-        test_values = [[512,    1, 512,   1, 1, 4, 7, 5, 2, 0],
-                       [65536,  1, 2048, 12, 7, 7, 5, 2, 5, 0],
-                       [32768,  9, 8192,  1, 4, 3, 2, 4, 6, 0],
-                       [16384, 11, 3584, 16, 9, 8, 6, 7, 3, 0]]
+        test_values = [[512,    1, 512,   1, 1, 4, 7, 5, 2, 1],
+                       [65536,  1, 2048, 12, 7, 7, 5, 2, 5, 5],
+                       [32768,  9, 8192,  1, 4, 3, 2, 4, 6, 4],
+                       [16384, 11, 3584, 16, 9, 8, 6, 7, 3, 4]]
         for i in test_values:
             self.do_test_stats(*i)
 
index cfa5c0d..0a5e958 100644 (file)
@@ -1,5 +1,5 @@
-...................................
+........................................
 ----------------------------------------------------------------------
-Ran 35 tests
+Ran 40 tests
 
 OK
index c0e7534..88c702c 100644 (file)
@@ -32,9 +32,9 @@ Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of t
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 ./common.config: Killed                  ( if [ "${VALGRIND_QEMU}" == "y" ]; then
-    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 else
-    exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
+    exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@";
 fi )
 incompatible_features     0x0
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
index eaf1e60..adceac1 100644 (file)
@@ -18,8 +18,8 @@ Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
 
 {"return": {}}
 Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "drv0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
 {"return": {}}
+{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "drv0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
 {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: mirror"}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "drv0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
@@ -28,8 +28,8 @@ Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
 === Testing active block-commit ===
 
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "drv0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
 {"return": {}}
+{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "drv0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
 {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "drv0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
index 387855c..410d741 100644 (file)
@@ -12,8 +12,8 @@ Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/
 
 === Performing block-commit on active layer ===
 
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "virtio0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
 {"return": {}}
+{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "virtio0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "virtio0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
 
index 8407251..52e23d2 100755 (executable)
@@ -153,8 +153,6 @@ def cryptsetup_format(config):
     cipher = config.cipher + "-" + config.mode + "-" + config.ivgen
     if config.ivgen_hash is not None:
         cipher = cipher + ":" + config.ivgen_hash
-    elif config.ivgen == "essiv":
-        cipher = cipher + ":" + "sha256"
     args.extend(["--cipher", cipher])
     if config.mode == "xts":
         args.extend(["--key-size", str(config.keylen * 2)])
@@ -481,16 +479,6 @@ configs = [
                    "6": "slot6",
                    "7": "slot7",
                }),
-
-    # Check handling of default hash alg (sha256) with essiv
-    LUKSConfig("aes-256-cbc-essiv-auto-sha1",
-               "aes", 256, "cbc", "essiv", None, "sha1"),
-
-    # Check that a useless hash provided for 'plain64' iv gen
-    # is ignored and no error raised
-    LUKSConfig("aes-256-cbc-plain64-sha256-sha1",
-               "aes", 256, "cbc", "plain64", "sha256", "sha1"),
-
 ]
 
 blacklist = [
index 90b5b55..287f013 100644 (file)
@@ -1878,243 +1878,3 @@ sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain-sha1-pwallslots
 # Delete image
 unlink TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img
 
-# ================= dm-crypt aes-256-cbc-essiv-auto-sha1 =================
-# Create image
-truncate TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img --size 4194304MB
-# Format image
-sudo cryptsetup -q -v luksFormat --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
-# Open dev
-sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img qiotest-145-aes-256-cbc-essiv-auto-sha1
-# Set dev owner
-sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1
-# Write test pattern 0xa7
-qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1
-wrote 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Write test pattern 0x13
-qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1
-wrote 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Close dev
-sudo cryptsetup -q -v luksClose qiotest-145-aes-256-cbc-essiv-auto-sha1
-# Read test pattern 0xa7
-qemu-io -c read -P 0xa7 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
-read 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Read test pattern 0x13
-qemu-io -c read -P 0x13 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
-read 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Write test pattern 0x91
-qemu-io -c write -P 0x91 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
-wrote 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Write test pattern 0x5e
-qemu-io -c write -P 0x5e 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
-wrote 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Open dev
-sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img qiotest-145-aes-256-cbc-essiv-auto-sha1
-# Set dev owner
-sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1
-# Read test pattern 0x91
-qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1
-read 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Read test pattern 0x5e
-qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1
-read 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Close dev
-sudo cryptsetup -q -v luksClose qiotest-145-aes-256-cbc-essiv-auto-sha1
-# Delete image
-unlink TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
-
-# ================= qemu-img aes-256-cbc-essiv-auto-sha1 =================
-# Create image
-qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=aes-256,cipher-mode=cbc,ivgen-alg=essiv,hash-alg=sha1 TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img 4194304M
-Formatting 'TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=cbc ivgen-alg=essiv hash-alg=sha1
-
-# Open dev
-sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img qiotest-145-aes-256-cbc-essiv-auto-sha1
-# Set dev owner
-sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1
-# Write test pattern 0xa7
-qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1
-wrote 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Write test pattern 0x13
-qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1
-wrote 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Close dev
-sudo cryptsetup -q -v luksClose qiotest-145-aes-256-cbc-essiv-auto-sha1
-# Read test pattern 0xa7
-qemu-io -c read -P 0xa7 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
-read 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Read test pattern 0x13
-qemu-io -c read -P 0x13 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
-read 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Write test pattern 0x91
-qemu-io -c write -P 0x91 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
-wrote 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Write test pattern 0x5e
-qemu-io -c write -P 0x5e 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
-wrote 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Open dev
-sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img qiotest-145-aes-256-cbc-essiv-auto-sha1
-# Set dev owner
-sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1
-# Read test pattern 0x91
-qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1
-read 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Read test pattern 0x5e
-qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1
-read 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Close dev
-sudo cryptsetup -q -v luksClose qiotest-145-aes-256-cbc-essiv-auto-sha1
-# Delete image
-unlink TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
-
-# ================= dm-crypt aes-256-cbc-plain64-sha256-sha1 =================
-# Create image
-truncate TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img --size 4194304MB
-# Format image
-sudo cryptsetup -q -v luksFormat --cipher aes-cbc-plain64:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
-# Open dev
-sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img qiotest-145-aes-256-cbc-plain64-sha256-sha1
-# Set dev owner
-sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1
-# Write test pattern 0xa7
-qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1
-wrote 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Write test pattern 0x13
-qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1
-wrote 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Close dev
-sudo cryptsetup -q -v luksClose qiotest-145-aes-256-cbc-plain64-sha256-sha1
-# Read test pattern 0xa7
-qemu-io -c read -P 0xa7 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
-read 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Read test pattern 0x13
-qemu-io -c read -P 0x13 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
-read 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Write test pattern 0x91
-qemu-io -c write -P 0x91 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
-wrote 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Write test pattern 0x5e
-qemu-io -c write -P 0x5e 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
-wrote 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Open dev
-sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img qiotest-145-aes-256-cbc-plain64-sha256-sha1
-# Set dev owner
-sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1
-# Read test pattern 0x91
-qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1
-read 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Read test pattern 0x5e
-qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1
-read 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Close dev
-sudo cryptsetup -q -v luksClose qiotest-145-aes-256-cbc-plain64-sha256-sha1
-# Delete image
-unlink TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
-
-# ================= qemu-img aes-256-cbc-plain64-sha256-sha1 =================
-# Create image
-qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=aes-256,cipher-mode=cbc,ivgen-alg=plain64,hash-alg=sha1,ivgen-hash-alg=sha256 TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img 4194304M
-Formatting 'TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=cbc ivgen-alg=plain64 ivgen-hash-alg=sha256 hash-alg=sha1
-
-# Open dev
-sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img qiotest-145-aes-256-cbc-plain64-sha256-sha1
-# Set dev owner
-sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1
-# Write test pattern 0xa7
-qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1
-wrote 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Write test pattern 0x13
-qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1
-wrote 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Close dev
-sudo cryptsetup -q -v luksClose qiotest-145-aes-256-cbc-plain64-sha256-sha1
-# Read test pattern 0xa7
-qemu-io -c read -P 0xa7 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
-read 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Read test pattern 0x13
-qemu-io -c read -P 0x13 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
-read 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Write test pattern 0x91
-qemu-io -c write -P 0x91 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
-wrote 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Write test pattern 0x5e
-qemu-io -c write -P 0x5e 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
-wrote 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Open dev
-sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img qiotest-145-aes-256-cbc-plain64-sha256-sha1
-# Set dev owner
-sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1
-# Read test pattern 0x91
-qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1
-read 10485760/10485760 bytes at offset 104857600
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Read test pattern 0x5e
-qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1
-read 10485760/10485760 bytes at offset 3298534883328
-10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-# Close dev
-sudo cryptsetup -q -v luksClose qiotest-145-aes-256-cbc-plain64-sha256-sha1
-# Delete image
-unlink TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
-
diff --git a/tests/qemu-iotests/154 b/tests/qemu-iotests/154
deleted file mode 100755 (executable)
index 7ca7219..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-#!/bin/bash
-#
-# qcow2 specific bdrv_pwrite_zeroes tests with backing files (complements 034)
-#
-# Copyright (C) 2016 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-# creator
-owner=kwolf@redhat.com
-
-seq=`basename $0`
-echo "QA output created by $seq"
-
-here=`pwd`
-status=1       # failure is the default!
-
-_cleanup()
-{
-       _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
-# get standard environment, filters and checks
-. ./common.rc
-. ./common.filter
-
-_supported_fmt qcow2
-_supported_proto file
-_supported_os Linux
-
-CLUSTER_SIZE=4k
-size=128M
-
-echo
-echo == backing file contains zeros ==
-
-CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
-_make_test_img -b "$TEST_IMG.base"
-
-# Make sure that the whole cluster is allocated even for partial write_zeroes
-# when the backing file contains zeros
-
-# X = non-zero data sector in backing file
-# - = sector unallocated in whole backing chain
-# 0 = sector touched by write_zeroes request
-
-# 1. Tail unaligned:    00 00 -- --
-# 2. Head unaligned:    -- -- 00 00
-# 3. Both unaligned:    -- 00 00 --
-# 4. Both, 2 clusters:  -- -- -- 00 | 00 -- -- --
-
-$QEMU_IO -c "write -z 0 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "write -z 10k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "write -z 17k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "write -z 27k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
-
-echo
-echo == backing file contains non-zero data before write_zeroes ==
-
-CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
-_make_test_img -b "$TEST_IMG.base"
-
-# Single cluster; non-zero data at the cluster start
-# ... | XX -- 00 -- | ...
-$QEMU_IO -c "write -P 0x11 32k 1k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 34k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 32k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 33k 3k" "$TEST_IMG" | _filter_qemu_io
-
-# Single cluster; non-zero data exists, but not at the cluster start
-# ... | -- XX 00 -- | ...
-$QEMU_IO -c "write -P 0x11 65k 1k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 66k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 65k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 64k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 66k 2k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
-
-echo
-echo == backing file contains non-zero data after write_zeroes ==
-
-CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
-_make_test_img -b "$TEST_IMG.base"
-
-# Single cluster; non-zero data directly after request
-# ... | -- 00 XX -- | ...
-$QEMU_IO -c "write -P 0x11 34k 1k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 33k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 32k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 34k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 35k 1k" "$TEST_IMG" | _filter_qemu_io
-
-# Single cluster; non-zero data exists, but not directly after request
-# ... | -- 00 -- XX | ...
-$QEMU_IO -c "write -P 0x11 43k 1k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 41k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 43k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 40k 3k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
-
-echo
-echo == write_zeroes covers non-zero data ==
-
-CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
-_make_test_img -b "$TEST_IMG.base"
-
-# non-zero data at front of request
-# Backing file: -- XX -- --
-# Active layer: -- 00 00 --
-
-$QEMU_IO -c "write -P 0x11 5k 1k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 5k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 4k 4k" "$TEST_IMG" | _filter_qemu_io
-
-# non-zero data at end of request
-# Backing file: -- -- XX --
-# Active layer: -- 00 00 --
-
-$QEMU_IO -c "write -P 0x11 14k 1k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 13k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 12k 4k" "$TEST_IMG" | _filter_qemu_io
-
-# non-zero data matches size of request
-# Backing file: -- XX XX --
-# Active layer: -- 00 00 --
-
-$QEMU_IO -c "write -P 0x11 21k 2k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 21k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 20k 4k" "$TEST_IMG" | _filter_qemu_io
-
-# non-zero data smaller than request
-# Backing file: -- -X X- --
-# Active layer: -- 00 00 --
-
-$QEMU_IO -c "write -P 0x11 30208 1k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 29k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 28k 4k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
-
-echo
-echo == spanning two clusters, non-zero before request ==
-
-CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
-_make_test_img -b "$TEST_IMG.base"
-
-# Two clusters; non-zero data before request:
-# 1. At cluster start:          32k: XX -- -- 00 | 00 -- -- --
-# 2. Between unallocated space: 48k: -- XX -- 00 | 00 -- -- --
-# 3. Directly before request:   64k: -- -- XX 00 | 00 -- -- --
-
-$QEMU_IO -c "write -P 0x11 32k 1k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 35k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 32k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 33k 7k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IO -c "write -P 0x11 49k 1k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 51k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 48k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 49k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 50k 6k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IO -c "write -P 0x11 66k 1k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 67k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 64k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 66k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 67k 5k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
-
-echo
-echo == spanning two clusters, non-zero after request ==
-
-CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
-_make_test_img -b "$TEST_IMG.base"
-
-# Two clusters; non-zero data after request:
-# 1. Directly after request:    32k: -- -- -- 00 | 00 XX -- --
-# 2. Between unallocated space: 48k: -- -- -- 00 | 00 -- XX --
-# 3. At cluster end:            64k: -- -- -- 00 | 00 -- -- XX
-
-$QEMU_IO -c "write -P 0x11 37k 1k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 35k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 32k 5k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 37k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 38k 2k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IO -c "write -P 0x11 54k 1k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 51k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 48k 6k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 54k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 55k 1k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IO -c "write -P 0x11 71k 1k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 67k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 64k 7k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 71k 1k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
-
-echo
-echo == spanning two clusters, partially overwriting backing file ==
-
-CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
-_make_test_img -b "$TEST_IMG.base"
-
-# Backing file: -- -- XX XX | XX XX -- --
-# Active layer: -- -- XX 00 | 00 XX -- --
-
-$QEMU_IO -c "write -P 0x11 2k 4k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 3k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 0k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 2k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 3k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 5k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 6k 2k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
-
-echo
-echo == spanning multiple clusters, non-zero in first cluster ==
-
-CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
-_make_test_img -b "$TEST_IMG.base"
-
-# Backing file: 64k: XX XX -- -- | -- -- -- -- | -- -- -- --
-# Active layer: 64k: XX XX 00 00 | 00 00 00 00 | 00 -- -- --
-
-$QEMU_IO -c "write -P 0x11 64k 2k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 66k 7k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 64k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 66k 10k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
-
-echo
-echo == spanning multiple clusters, non-zero in intermediate cluster ==
-
-CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
-_make_test_img -b "$TEST_IMG.base"
-
-# Backing file: 64k: -- -- -- -- | -- XX XX -- | -- -- -- --
-# Active layer: 64k: -- -- 00 00 | 00 00 00 00 | 00 -- -- --
-
-$QEMU_IO -c "write -P 0x11 69k 2k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 66k 7k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 64k 12k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
-
-echo
-echo == spanning multiple clusters, non-zero in final cluster ==
-
-CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
-_make_test_img -b "$TEST_IMG.base"
-
-# Backing file: 64k: -- -- -- -- | -- -- -- -- | -- -- XX XX
-# Active layer: 64k: -- -- 00 00 | 00 00 00 00 | 00 -- XX XX
-
-$QEMU_IO -c "write -P 0x11 74k 2k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 66k 7k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 64k 10k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 74k 2k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
-
-echo
-echo == spanning multiple clusters, partially overwriting backing file ==
-
-CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
-_make_test_img -b "$TEST_IMG.base"
-
-# Backing file: 64k: -- XX XX XX | XX XX XX XX | XX XX XX --
-# Active layer: 64k: -- XX 00 00 | 00 00 00 00 | 00 XX XX --
-
-$QEMU_IO -c "write -P 0x11 65k 10k" "$TEST_IMG.base" | _filter_qemu_io
-$QEMU_IO -c "write -z 66k 7k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 64k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 65k 1k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 66k 7k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0x11 73k 2k" "$TEST_IMG" | _filter_qemu_io
-$QEMU_IO -c "read -P 0 75k 1k" "$TEST_IMG" | _filter_qemu_io
-
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
-
-# success, all done
-echo "*** done"
-rm -f $seq.full
-status=0
diff --git a/tests/qemu-iotests/154.out b/tests/qemu-iotests/154.out
deleted file mode 100644 (file)
index da9eabd..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-QA output created by 154
-
-== backing file contains zeros ==
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
-wrote 2048/2048 bytes at offset 0
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 10240
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 17408
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 27648
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 4096, "length": 4096, "depth": 1, "zero": true, "data": false},
-{ "start": 8192, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 12288, "length": 4096, "depth": 1, "zero": true, "data": false},
-{ "start": 16384, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 20480, "length": 4096, "depth": 1, "zero": true, "data": false},
-{ "start": 24576, "length": 8192, "depth": 0, "zero": true, "data": false},
-{ "start": 32768, "length": 134184960, "depth": 1, "zero": true, "data": false}]
-
-== backing file contains non-zero data before write_zeroes ==
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
-wrote 1024/1024 bytes at offset 32768
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 1024/1024 bytes at offset 34816
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 32768
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 3072/3072 bytes at offset 33792
-3 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 1024/1024 bytes at offset 66560
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 1024/1024 bytes at offset 67584
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 66560
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 65536
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 2048/2048 bytes at offset 67584
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 32768, "depth": 1, "zero": true, "data": false},
-{ "start": 32768, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 20480},
-{ "start": 36864, "length": 28672, "depth": 1, "zero": true, "data": false},
-{ "start": 65536, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 24576},
-{ "start": 69632, "length": 134148096, "depth": 1, "zero": true, "data": false}]
-
-== backing file contains non-zero data after write_zeroes ==
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
-wrote 1024/1024 bytes at offset 34816
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 1024/1024 bytes at offset 33792
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 2048/2048 bytes at offset 32768
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 34816
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 35840
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 1024/1024 bytes at offset 44032
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 1024/1024 bytes at offset 41984
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 44032
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 3072/3072 bytes at offset 40960
-3 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 32768, "depth": 1, "zero": true, "data": false},
-{ "start": 32768, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 20480},
-{ "start": 36864, "length": 4096, "depth": 1, "zero": true, "data": false},
-{ "start": 40960, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 24576},
-{ "start": 45056, "length": 134172672, "depth": 1, "zero": true, "data": false}]
-
-== write_zeroes covers non-zero data ==
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
-wrote 1024/1024 bytes at offset 5120
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 5120
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 4096/4096 bytes at offset 4096
-4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 1024/1024 bytes at offset 14336
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 13312
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 4096/4096 bytes at offset 12288
-4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 21504
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 21504
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 4096/4096 bytes at offset 20480
-4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 1024/1024 bytes at offset 30208
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 29696
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 4096/4096 bytes at offset 28672
-4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 4096, "depth": 1, "zero": true, "data": false},
-{ "start": 4096, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 8192, "length": 4096, "depth": 1, "zero": true, "data": false},
-{ "start": 12288, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 16384, "length": 4096, "depth": 1, "zero": true, "data": false},
-{ "start": 20480, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 24576, "length": 4096, "depth": 1, "zero": true, "data": false},
-{ "start": 28672, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 32768, "length": 134184960, "depth": 1, "zero": true, "data": false}]
-
-== spanning two clusters, non-zero before request ==
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
-wrote 1024/1024 bytes at offset 32768
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 35840
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 32768
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 7168/7168 bytes at offset 33792
-7 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 1024/1024 bytes at offset 50176
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 52224
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 49152
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 50176
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 6144/6144 bytes at offset 51200
-6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 1024/1024 bytes at offset 67584
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 68608
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 2048/2048 bytes at offset 65536
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 67584
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 5120/5120 bytes at offset 68608
-5 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 32768, "depth": 1, "zero": true, "data": false},
-{ "start": 32768, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 20480},
-{ "start": 36864, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 40960, "length": 8192, "depth": 1, "zero": true, "data": false},
-{ "start": 49152, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 24576},
-{ "start": 53248, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 57344, "length": 8192, "depth": 1, "zero": true, "data": false},
-{ "start": 65536, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 28672},
-{ "start": 69632, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 73728, "length": 134144000, "depth": 1, "zero": true, "data": false}]
-
-== spanning two clusters, non-zero after request ==
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
-wrote 1024/1024 bytes at offset 37888
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 35840
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 5120/5120 bytes at offset 32768
-5 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 37888
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 2048/2048 bytes at offset 38912
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 1024/1024 bytes at offset 55296
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 52224
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 6144/6144 bytes at offset 49152
-6 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 55296
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 56320
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 1024/1024 bytes at offset 72704
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 68608
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 7168/7168 bytes at offset 65536
-7 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 72704
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 32768, "depth": 1, "zero": true, "data": false},
-{ "start": 32768, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 36864, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 20480},
-{ "start": 40960, "length": 8192, "depth": 1, "zero": true, "data": false},
-{ "start": 49152, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 53248, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 24576},
-{ "start": 57344, "length": 8192, "depth": 1, "zero": true, "data": false},
-{ "start": 65536, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 69632, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 28672},
-{ "start": 73728, "length": 134144000, "depth": 1, "zero": true, "data": false}]
-
-== spanning two clusters, partially overwriting backing file ==
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
-wrote 4096/4096 bytes at offset 2048
-4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 2048/2048 bytes at offset 3072
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 2048/2048 bytes at offset 0
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 2048
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 2048/2048 bytes at offset 3072
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 5120
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 2048/2048 bytes at offset 6144
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 8192, "depth": 0, "zero": false, "data": true, "offset": 20480},
-{ "start": 8192, "length": 134209536, "depth": 1, "zero": true, "data": false}]
-
-== spanning multiple clusters, non-zero in first cluster ==
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
-wrote 2048/2048 bytes at offset 65536
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 7168/7168 bytes at offset 67584
-7 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 2048/2048 bytes at offset 65536
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 10240/10240 bytes at offset 67584
-10 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 65536, "depth": 1, "zero": true, "data": false},
-{ "start": 65536, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 20480},
-{ "start": 69632, "length": 8192, "depth": 0, "zero": true, "data": false},
-{ "start": 77824, "length": 134139904, "depth": 1, "zero": true, "data": false}]
-
-== spanning multiple clusters, non-zero in intermediate cluster ==
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
-wrote 2048/2048 bytes at offset 70656
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 7168/7168 bytes at offset 67584
-7 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 12288/12288 bytes at offset 65536
-12 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 65536, "depth": 1, "zero": true, "data": false},
-{ "start": 65536, "length": 12288, "depth": 0, "zero": true, "data": false},
-{ "start": 77824, "length": 134139904, "depth": 1, "zero": true, "data": false}]
-
-== spanning multiple clusters, non-zero in final cluster ==
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
-wrote 2048/2048 bytes at offset 75776
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 7168/7168 bytes at offset 67584
-7 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 10240/10240 bytes at offset 65536
-10 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 2048/2048 bytes at offset 75776
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 65536, "depth": 1, "zero": true, "data": false},
-{ "start": 65536, "length": 8192, "depth": 0, "zero": true, "data": false},
-{ "start": 73728, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 20480},
-{ "start": 77824, "length": 134139904, "depth": 1, "zero": true, "data": false}]
-
-== spanning multiple clusters, partially overwriting backing file ==
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
-wrote 10240/10240 bytes at offset 66560
-10 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 7168/7168 bytes at offset 67584
-7 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 65536
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 66560
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 7168/7168 bytes at offset 67584
-7 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 2048/2048 bytes at offset 74752
-2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 1024/1024 bytes at offset 76800
-1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 65536, "depth": 1, "zero": true, "data": false},
-{ "start": 65536, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 20480},
-{ "start": 69632, "length": 4096, "depth": 0, "zero": true, "data": false},
-{ "start": 73728, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 24576},
-{ "start": 77824, "length": 134139904, "depth": 1, "zero": true, "data": false}]
-*** done
diff --git a/tests/qemu-iotests/155 b/tests/qemu-iotests/155
deleted file mode 100755 (executable)
index 4057b5e..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-#!/usr/bin/env python
-#
-# Test whether the backing BDSs are correct after completion of a
-# mirror block job; in "existing" modes (drive-mirror with
-# mode=existing and blockdev-mirror) the backing chain should not be
-# overridden.
-#
-# Copyright (C) 2016 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-import os
-import iotests
-from iotests import qemu_img
-
-back0_img = os.path.join(iotests.test_dir, 'back0.' + iotests.imgfmt)
-back1_img = os.path.join(iotests.test_dir, 'back1.' + iotests.imgfmt)
-back2_img = os.path.join(iotests.test_dir, 'back2.' + iotests.imgfmt)
-source_img = os.path.join(iotests.test_dir, 'source.' + iotests.imgfmt)
-target_img = os.path.join(iotests.test_dir, 'target.' + iotests.imgfmt)
-
-
-# Class variables for controlling its behavior:
-#
-# existing: If True, explicitly create the target image and blockdev-add it
-# target_backing: If existing is True: Use this filename as the backing file
-#                 of the target image
-#                 (None: no backing file)
-# target_blockdev_backing: If existing is True: Pass this dict as "backing"
-#                          for the blockdev-add command
-#                          (None: do not pass "backing")
-# target_real_backing: If existing is True: The real filename of the backing
-#                      image during runtime, only makes sense if
-#                      target_blockdev_backing is not None
-#                      (None: same as target_backing)
-
-class BaseClass(iotests.QMPTestCase):
-    target_blockdev_backing = None
-    target_real_backing = None
-
-    def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, back0_img, '1M')
-        qemu_img('create', '-f', iotests.imgfmt, '-b', back0_img, back1_img)
-        qemu_img('create', '-f', iotests.imgfmt, '-b', back1_img, back2_img)
-        qemu_img('create', '-f', iotests.imgfmt, '-b', back2_img, source_img)
-
-        self.vm = iotests.VM()
-        self.vm.add_drive(None, '', 'none')
-        self.vm.launch()
-
-        # Add the BDS via blockdev-add so it stays around after the mirror block
-        # job has been completed
-        result = self.vm.qmp('blockdev-add',
-                             options={'node-name': 'source',
-                                      'driver': iotests.imgfmt,
-                                      'file': {'driver': 'file',
-                                               'filename': source_img}})
-        self.assert_qmp(result, 'return', {})
-
-        result = self.vm.qmp('x-blockdev-insert-medium',
-                             device='drive0', node_name='source')
-        self.assert_qmp(result, 'return', {})
-
-        self.assertIntactSourceBackingChain()
-
-        if self.existing:
-            if self.target_backing:
-                qemu_img('create', '-f', iotests.imgfmt,
-                         '-b', self.target_backing, target_img, '1M')
-            else:
-                qemu_img('create', '-f', iotests.imgfmt, target_img, '1M')
-
-            if self.cmd == 'blockdev-mirror':
-                options = { 'node-name': 'target',
-                            'driver': iotests.imgfmt,
-                            'file': { 'driver': 'file',
-                                      'filename': target_img } }
-                if self.target_blockdev_backing:
-                    options['backing'] = self.target_blockdev_backing
-
-                result = self.vm.qmp('blockdev-add', options=options)
-                self.assert_qmp(result, 'return', {})
-
-    def tearDown(self):
-        self.vm.shutdown()
-        os.remove(source_img)
-        os.remove(back2_img)
-        os.remove(back1_img)
-        os.remove(back0_img)
-        try:
-            os.remove(target_img)
-        except OSError:
-            pass
-
-    def findBlockNode(self, node_name, id=None):
-        if id:
-            result = self.vm.qmp('query-block')
-            for device in result['return']:
-                if device['device'] == id:
-                    if node_name:
-                        self.assert_qmp(device, 'inserted/node-name', node_name)
-                    return device['inserted']
-        else:
-            result = self.vm.qmp('query-named-block-nodes')
-            for node in result['return']:
-                if node['node-name'] == node_name:
-                    return node
-
-        self.fail('Cannot find node %s/%s' % (id, node_name))
-
-    def assertIntactSourceBackingChain(self):
-        node = self.findBlockNode('source')
-
-        self.assert_qmp(node, 'image' + '/backing-image' * 0 + '/filename',
-                        source_img)
-        self.assert_qmp(node, 'image' + '/backing-image' * 1 + '/filename',
-                        back2_img)
-        self.assert_qmp(node, 'image' + '/backing-image' * 2 + '/filename',
-                        back1_img)
-        self.assert_qmp(node, 'image' + '/backing-image' * 3 + '/filename',
-                        back0_img)
-        self.assert_qmp_absent(node, 'image' + '/backing-image' * 4)
-
-    def assertCorrectBackingImage(self, node, default_image):
-        if self.existing:
-            if self.target_real_backing:
-                image = self.target_real_backing
-            else:
-                image = self.target_backing
-        else:
-            image = default_image
-
-        if image:
-            self.assert_qmp(node, 'image/backing-image/filename', image)
-        else:
-            self.assert_qmp_absent(node, 'image/backing-image')
-
-
-# Class variables for controlling its behavior:
-#
-# cmd: Mirroring command to execute, either drive-mirror or blockdev-mirror
-
-class MirrorBaseClass(BaseClass):
-    def runMirror(self, sync):
-        if self.cmd == 'blockdev-mirror':
-            result = self.vm.qmp(self.cmd, device='drive0', sync=sync,
-                                 target='target')
-        else:
-            if self.existing:
-                mode = 'existing'
-            else:
-                mode = 'absolute-paths'
-            result = self.vm.qmp(self.cmd, device='drive0', sync=sync,
-                                 target=target_img, format=iotests.imgfmt,
-                                 mode=mode, node_name='target')
-
-        self.assert_qmp(result, 'return', {})
-
-        self.vm.event_wait('BLOCK_JOB_READY')
-
-        result = self.vm.qmp('block-job-complete', device='drive0')
-        self.assert_qmp(result, 'return', {})
-
-        self.vm.event_wait('BLOCK_JOB_COMPLETED')
-
-    def testFull(self):
-        self.runMirror('full')
-
-        node = self.findBlockNode('target', 'drive0')
-        self.assertCorrectBackingImage(node, None)
-        self.assertIntactSourceBackingChain()
-
-    def testTop(self):
-        self.runMirror('top')
-
-        node = self.findBlockNode('target', 'drive0')
-        self.assertCorrectBackingImage(node, back2_img)
-        self.assertIntactSourceBackingChain()
-
-    def testNone(self):
-        self.runMirror('none')
-
-        node = self.findBlockNode('target', 'drive0')
-        self.assertCorrectBackingImage(node, source_img)
-        self.assertIntactSourceBackingChain()
-
-
-class TestDriveMirrorAbsolutePaths(MirrorBaseClass):
-    cmd = 'drive-mirror'
-    existing = False
-
-class TestDriveMirrorExistingNoBacking(MirrorBaseClass):
-    cmd = 'drive-mirror'
-    existing = True
-    target_backing = None
-
-class TestDriveMirrorExistingBacking(MirrorBaseClass):
-    cmd = 'drive-mirror'
-    existing = True
-    target_backing = 'null-co://'
-
-class TestBlockdevMirrorNoBacking(MirrorBaseClass):
-    cmd = 'blockdev-mirror'
-    existing = True
-    target_backing = None
-
-class TestBlockdevMirrorBacking(MirrorBaseClass):
-    cmd = 'blockdev-mirror'
-    existing = True
-    target_backing = 'null-co://'
-
-class TestBlockdevMirrorForcedBacking(MirrorBaseClass):
-    cmd = 'blockdev-mirror'
-    existing = True
-    target_backing = None
-    target_blockdev_backing = { 'driver': 'null-co' }
-    target_real_backing = 'null-co://'
-
-
-class TestCommit(BaseClass):
-    existing = False
-
-    def testCommit(self):
-        result = self.vm.qmp('block-commit', device='drive0', base=back1_img)
-        self.assert_qmp(result, 'return', {})
-
-        self.vm.event_wait('BLOCK_JOB_READY')
-
-        result = self.vm.qmp('block-job-complete', device='drive0')
-        self.assert_qmp(result, 'return', {})
-
-        self.vm.event_wait('BLOCK_JOB_COMPLETED')
-
-        node = self.findBlockNode(None, 'drive0')
-        self.assert_qmp(node, 'image' + '/backing-image' * 0 + '/filename',
-                        back1_img)
-        self.assert_qmp(node, 'image' + '/backing-image' * 1 + '/filename',
-                        back0_img)
-        self.assert_qmp_absent(node, 'image' + '/backing-image' * 2 +
-                               '/filename')
-
-        self.assertIntactSourceBackingChain()
-
-
-BaseClass = None
-MirrorBaseClass = None
-
-if __name__ == '__main__':
-    iotests.main(supported_fmts=['qcow2'])
diff --git a/tests/qemu-iotests/155.out b/tests/qemu-iotests/155.out
deleted file mode 100644 (file)
index 4176bb9..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-...................
-----------------------------------------------------------------------
-Ran 19 tests
-
-OK
diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
deleted file mode 100755 (executable)
index cc95ff1..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-#!/bin/bash
-#
-# Tests oVirt-like storage migration:
-#  - Create snapshot
-#  - Create target image with (not yet existing) target backing chain
-#    (i.e. just write the name of a soon-to-be-copied-over backing file into it)
-#  - drive-mirror the snapshot to the target with mode=existing and sync=top
-#  - In the meantime, copy the original source files to the destination via
-#    conventional means (i.e. outside of qemu)
-#  - Complete the drive-mirror job
-#  - Delete all source images
-#
-# Copyright (C) 2016 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-# creator
-owner=mreitz@redhat.com
-
-seq="$(basename $0)"
-echo "QA output created by $seq"
-
-here="$PWD"
-status=1       # failure is the default!
-
-_cleanup()
-{
-    rm -f "$TEST_IMG{,.target}{,.backing,.overlay}"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
-# get standard environment, filters and checks
-. ./common.rc
-. ./common.filter
-. ./common.qemu
-
-_supported_fmt qcow2 qed
-_supported_proto generic
-_supported_os Linux
-
-# Create source disk
-TEST_IMG="$TEST_IMG.backing" _make_test_img 1M
-_make_test_img -b "$TEST_IMG.backing" 1M
-
-$QEMU_IO -c 'write -P 1 0 256k' "$TEST_IMG.backing" | _filter_qemu_io
-$QEMU_IO -c 'write -P 2 64k 192k' "$TEST_IMG" | _filter_qemu_io
-
-_launch_qemu -drive if=none,id=source,file="$TEST_IMG"
-
-_send_qemu_cmd $QEMU_HANDLE \
-    "{ 'execute': 'qmp_capabilities' }" \
-    'return'
-
-# Create snapshot
-TEST_IMG="$TEST_IMG.overlay" _make_test_img -b "$TEST_IMG" 1M
-_send_qemu_cmd $QEMU_HANDLE \
-    "{ 'execute': 'blockdev-snapshot-sync',
-       'arguments': { 'device': 'source',
-                      'snapshot-file': '$TEST_IMG.overlay',
-                      'format': '$IMGFMT',
-                      'mode': 'existing' } }" \
-    'return'
-
-# Write something to the snapshot
-_send_qemu_cmd $QEMU_HANDLE \
-    "{ 'execute': 'human-monitor-command',
-       'arguments': { 'command-line':
-                      'qemu-io source \"write -P 3 128k 128k\"' } }" \
-    'return'
-
-# Create target image
-TEST_IMG="$TEST_IMG.target.overlay" _make_test_img -b "$TEST_IMG.target" 1M
-
-# Mirror snapshot
-_send_qemu_cmd $QEMU_HANDLE \
-    "{ 'execute': 'drive-mirror',
-       'arguments': { 'device': 'source',
-                      'target': '$TEST_IMG.target.overlay',
-                      'mode': 'existing',
-                      'sync': 'top' } }" \
-    'return'
-
-# Wait for convergence
-_send_qemu_cmd $QEMU_HANDLE \
-    '' \
-    'BLOCK_JOB_READY'
-
-# Write some more
-_send_qemu_cmd $QEMU_HANDLE \
-    "{ 'execute': 'human-monitor-command',
-       'arguments': { 'command-line':
-                      'qemu-io source \"write -P 4 192k 64k\"' } }" \
-    'return'
-
-# Copy source backing chain to the target before completing the job
-cp "$TEST_IMG.backing" "$TEST_IMG.target.backing"
-cp "$TEST_IMG" "$TEST_IMG.target"
-$QEMU_IMG rebase -u -b "$TEST_IMG.target.backing" "$TEST_IMG.target"
-
-# Complete block job
-_send_qemu_cmd $QEMU_HANDLE \
-    "{ 'execute': 'block-job-complete',
-       'arguments': { 'device': 'source' } }" \
-    ''
-
-_send_qemu_cmd $QEMU_HANDLE \
-    '' \
-    'BLOCK_JOB_COMPLETED'
-
-# Remove the source images
-rm -f "$TEST_IMG{,.backing,.overlay}"
-
-echo
-
-# Check online disk contents
-_send_qemu_cmd $QEMU_HANDLE \
-    "{ 'execute': 'human-monitor-command',
-       'arguments': { 'command-line':
-                      'qemu-io source \"read -P 1 0k 64k\"' } }" \
-    'return'
-
-_send_qemu_cmd $QEMU_HANDLE \
-    "{ 'execute': 'human-monitor-command',
-       'arguments': { 'command-line':
-                      'qemu-io source \"read -P 2 64k 64k\"' } }" \
-    'return'
-
-_send_qemu_cmd $QEMU_HANDLE \
-    "{ 'execute': 'human-monitor-command',
-       'arguments': { 'command-line':
-                      'qemu-io source \"read -P 3 128k 64k\"' } }" \
-    'return'
-
-_send_qemu_cmd $QEMU_HANDLE \
-    "{ 'execute': 'human-monitor-command',
-       'arguments': { 'command-line':
-                      'qemu-io source \"read -P 4 192k 64k\"' } }" \
-    'return'
-
-echo
-
-_send_qemu_cmd $QEMU_HANDLE \
-    "{ 'execute': 'quit' }" \
-    'return'
-
-wait=1 _cleanup_qemu
-
-echo
-
-# Check offline disk contents
-$QEMU_IO -c 'read -P 1 0k 64k' \
-         -c 'read -P 2 64k 64k' \
-         -c 'read -P 3 128k 64k' \
-         -c 'read -P 4 192k 64k' \
-         "$TEST_IMG.target.overlay" | _filter_qemu_io
-
-echo
-
-# success, all done
-echo '*** done'
-rm -f $seq.full
-status=0
diff --git a/tests/qemu-iotests/156.out b/tests/qemu-iotests/156.out
deleted file mode 100644 (file)
index 3af82ae..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-QA output created by 156
-Formatting 'TEST_DIR/t.IMGFMT.backing', fmt=IMGFMT size=1048576
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.backing
-wrote 262144/262144 bytes at offset 0
-256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-wrote 196608/196608 bytes at offset 65536
-192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-{"return": {}}
-Formatting 'TEST_DIR/t.IMGFMT.overlay', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT
-{"return": {}}
-wrote 131072/131072 bytes at offset 131072
-128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-{"return": ""}
-Formatting 'TEST_DIR/t.IMGFMT.target.overlay', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.target
-{"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "source", "len": 131072, "offset": 131072, "speed": 0, "type": "mirror"}}
-wrote 65536/65536 bytes at offset 196608
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-{"return": ""}
-{"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "source", "len": 196608, "offset": 196608, "speed": 0, "type": "mirror"}}
-
-read 65536/65536 bytes at offset 0
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-{"return": ""}
-read 65536/65536 bytes at offset 65536
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-{"return": ""}
-read 65536/65536 bytes at offset 131072
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-{"return": ""}
-read 65536/65536 bytes at offset 196608
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-{"return": ""}
-
-{"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
-
-read 65536/65536 bytes at offset 0
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 65536/65536 bytes at offset 65536
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 65536/65536 bytes at offset 131072
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 65536/65536 bytes at offset 196608
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-
-*** done
diff --git a/tests/qemu-iotests/157 b/tests/qemu-iotests/157
deleted file mode 100755 (executable)
index 8d939cb..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/bin/bash
-#
-# Test command line configuration of block devices with qdev
-#
-# Copyright (C) 2016 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-# creator
-owner=kwolf@redhat.com
-
-seq="$(basename $0)"
-echo "QA output created by $seq"
-
-here="$PWD"
-status=1       # failure is the default!
-
-_cleanup()
-{
-       _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
-# get standard environment, filters and checks
-. ./common.rc
-. ./common.filter
-
-_supported_fmt generic
-_supported_proto file
-_supported_os Linux
-
-function do_run_qemu()
-{
-    echo Testing: "$@"
-    (
-        if ! test -t 0; then
-            while read cmd; do
-                echo $cmd
-            done
-        fi
-        echo quit
-    ) | $QEMU -nodefaults -nographic -monitor stdio -serial none "$@"
-    echo
-}
-
-function run_qemu()
-{
-    do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_imgfmt \
-                          | _filter_qemu | _filter_generated_node_ids
-}
-
-
-size=128M
-drive="if=none,file=$TEST_IMG,driver=$IMGFMT"
-
-_make_test_img $size
-
-echo
-echo "=== Setting WCE with qdev and with manually created BB ==="
-echo
-
-# The qdev option takes precedence, but if it isn't given or 'auto', the BB
-# option is used instead.
-
-for cache in "writeback" "writethrough"; do
-    for wce in "" ",write-cache=auto" ",write-cache=on" ",write-cache=off"; do
-        echo "info block" \
-            | run_qemu -drive "$drive,cache=$cache" \
-                       -device "virtio-blk,drive=none0$wce" \
-            | grep -e "Testing" -e "Cache mode"
-    done
-done
-
-# success, all done
-echo "*** done"
-rm -f $seq.full
-status=0
diff --git a/tests/qemu-iotests/157.out b/tests/qemu-iotests/157.out
deleted file mode 100644 (file)
index 77a9c03..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-QA output created by 157
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
-
-=== Setting WCE with qdev and with manually created BB ===
-
-Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writeback -device virtio-blk,drive=none0
-    Cache mode:       writeback
-Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writeback -device virtio-blk,drive=none0,write-cache=auto
-    Cache mode:       writeback
-Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writeback -device virtio-blk,drive=none0,write-cache=on
-    Cache mode:       writeback
-Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writeback -device virtio-blk,drive=none0,write-cache=off
-    Cache mode:       writethrough
-Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writethrough -device virtio-blk,drive=none0
-    Cache mode:       writethrough
-Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writethrough -device virtio-blk,drive=none0,write-cache=auto
-    Cache mode:       writethrough
-Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writethrough -device virtio-blk,drive=none0,write-cache=on
-    Cache mode:       writeback
-Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writethrough -device virtio-blk,drive=none0,write-cache=off
-    Cache mode:       writethrough
-*** done
diff --git a/tests/qemu-iotests/162 b/tests/qemu-iotests/162
deleted file mode 100755 (executable)
index 0b43ea3..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/bin/bash
-#
-# Test case for specifying runtime options of the wrong type to some
-# block drivers
-#
-# Copyright (C) 2016 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-# creator
-owner=mreitz@redhat.com
-
-seq="$(basename $0)"
-echo "QA output created by $seq"
-
-here="$PWD"
-status=1       # failure is the default!
-
-# get standard environment, filters and checks
-. ./common.rc
-. ./common.filter
-
-_supported_fmt generic
-_supported_os Linux
-
-echo
-echo '=== NBD ==='
-# NBD expects all of its arguments to be strings
-
-# So this should not crash
-$QEMU_IMG info 'json:{"driver": "nbd", "host": 42}'
-
-# And this should not treat @port as if it had not been specified
-# (We cannot use localhost with an invalid port here, but we need to use a
-#  non-existing domain, because otherwise the error message will not contain
-#  the port)
-$QEMU_IMG info 'json:{"driver": "nbd", "host": "does.not.exist.example.com", "port": 42}'
-
-# This is a test for NBD's bdrv_refresh_filename() implementation: It expects
-# either host or path to be set, but it must not assume that they are set to
-# strings in the options QDict
-$QEMU_NBD -k "$PWD/42" -f raw null-co:// &
-sleep 0.5
-$QEMU_IMG info 'json:{"driver": "nbd", "path": 42}' | grep '^image'
-rm -f 42
-
-
-echo
-echo '=== SSH ==='
-# SSH expects all of its arguments to be strings, except for @port, which is
-# expected to be an integer
-
-# So "0" should be converted to an integer here (instead of crashing)
-$QEMU_IMG info 'json:{"driver": "ssh", "host": "localhost", "port": "0", "path": "/foo"}'
-# The same, basically (all values for --image-opts are seen as strings in qemu)
-$QEMU_IMG info --image-opts \
-    driver=ssh,host=localhost,port=0,path=/foo
-
-# This, however, should fail because of the wrong type
-$QEMU_IMG info 'json:{"driver": "ssh", "host": "localhost", "port": 0.42, "path": "/foo"}'
-# Not really the same: Here, "0.42" will be passed instead of 0.42, but still,
-# qemu should not try to convert "0.42" to an integer
-$QEMU_IMG info --image-opts \
-    driver=ssh,host=localhost,port=0.42,path=/foo
-
-
-echo
-echo '=== blkdebug ==='
-# blkdebug expects all of its arguments to be strings, but its
-# bdrv_refresh_filename() implementation should not assume that they have been
-# passed as strings in the original options QDict.
-# So this should emit blkdebug:42:null-co:// as the filename:
-touch 42
-$QEMU_IMG info 'json:{"driver": "blkdebug", "config": 42,
-                      "image.driver": "null-co"}' \
-    | grep '^image'
-rm -f 42
-
-
-# success, all done
-echo
-echo '*** done'
-rm -f $seq.full
-status=0
diff --git a/tests/qemu-iotests/162.out b/tests/qemu-iotests/162.out
deleted file mode 100644 (file)
index 9bba723..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-QA output created by 162
-
-=== NBD ===
-qemu-img: Could not open 'json:{"driver": "nbd", "host": 42}': Failed to connect socket: Invalid argument
-qemu-img: Could not open 'json:{"driver": "nbd", "host": "does.not.exist.example.com", "port": 42}': address resolution failed for does.not.exist.example.com:42: Name or service not known
-image: nbd+unix://?socket=42
-
-=== SSH ===
-qemu-img: Could not open 'json:{"driver": "ssh", "host": "localhost", "port": "0", "path": "/foo"}': Failed to connect socket: Connection refused
-qemu-img: Could not open 'driver=ssh,host=localhost,port=0,path=/foo': Failed to connect socket: Connection refused
-qemu-img: Could not open 'json:{"driver": "ssh", "host": "localhost", "port": 0.42, "path": "/foo"}': Parameter 'port' expects a number
-qemu-img: Could not open 'driver=ssh,host=localhost,port=0.42,path=/foo': Parameter 'port' expects a number
-
-=== blkdebug ===
-image: blkdebug:42:null-co://
-
-*** done
index 6079b40..4ccfdd1 100644 (file)
@@ -17,5 +17,4 @@ additional options to test further image formats or I/O methods.
 * Feedback and patches
 
 Please send improvements to the test suite, general feedback or just
-reports of failing tests cases to qemu-devel@nongnu.org with a CC:
-to qemu-block@nongnu.org.
+reports of failing tests cases to qemu-devel@savannah.nongnu.org.
index d60ea2c..49e1931 100644 (file)
@@ -53,8 +53,6 @@ export QEMU_IO_OPTIONS=""
 export CACHEMODE_IS_DEFAULT=true
 export QEMU_OPTIONS="-nodefaults"
 export VALGRIND_QEMU=
-export IMGKEYSECRET=
-export IMGOPTSSYNTAX=false
 
 for r
 do
@@ -209,13 +207,6 @@ testlist options
             xpand=false
             ;;
 
-        -luks)
-            IMGOPTSSYNTAX=true
-            IMGFMT=luks
-            IMGKEYSECRET=123456
-            xpand=false
-            ;;
-
         -qed)
             IMGFMT=qed
             xpand=false
@@ -408,11 +399,7 @@ BEGIN        { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
 done
 
 # Set qemu-io cache mode with $CACHEMODE we have
-if [ "$IMGOPTSSYNTAX" = "true" ]; then
-    QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE"
-else
-    QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT --cache $CACHEMODE"
-fi
+QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT --cache $CACHEMODE"
 
 # Set default options for qemu-img create -o if they were not specified
 _set_default_imgopts
index f6384fb..f824651 100644 (file)
@@ -123,19 +123,12 @@ _qemu_img_wrapper()
 _qemu_io_wrapper()
 {
     local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
-    local QEMU_IO_ARGS="$QEMU_IO_OPTIONS"
-    if [ "$IMGOPTSSYNTAX" = "true" ]; then
-        QEMU_IO_ARGS="--image-opts $QEMU_IO_ARGS"
-        if [ -n "$IMGKEYSECRET" ]; then
-            QEMU_IO_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IO_ARGS"
-        fi
-    fi
     local RETVAL
     (
         if [ "${VALGRIND_QEMU}" == "y" ]; then
-            exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
+            exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"
         else
-            exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
+            exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@"
         fi
     )
     RETVAL=$?
@@ -161,16 +154,6 @@ export QEMU_IMG=_qemu_img_wrapper
 export QEMU_IO=_qemu_io_wrapper
 export QEMU_NBD=_qemu_nbd_wrapper
 
-QEMU_IMG_EXTRA_ARGS=
-if [ "$IMGOPTSSYNTAX" = "true" ]; then
-    QEMU_IMG_EXTRA_ARGS="--image-opts $QEMU_IMG_EXTRA_ARGS"
-    if [ -n "$IMGKEYSECRET" ]; then
-        QEMU_IMG_EXTRA_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IMG_EXTRA_ARGS"
-    fi
-fi
-export QEMU_IMG_EXTRA_ARGS
-
-
 default_machine=$($QEMU -machine help | sed -n '/(default)/ s/ .*//p')
 default_alias_machine=$($QEMU -machine help | \
    sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }")
index 3ab6e4d..8a6e1b5 100644 (file)
@@ -77,12 +77,6 @@ _filter_qmp()
         -e '    QMP_VERSION'
 }
 
-# replace block job offset
-_filter_block_job_offset()
-{
-    sed -e 's/, "offset": [0-9]\+,/, "offset": OFFSET,/'
-}
-
 # replace driver-specific options in the "Formatting..." line
 _filter_img_create()
 {
@@ -98,14 +92,12 @@ _filter_img_create()
         -e "s# zeroed_grain=\\(on\\|off\\)##g" \
         -e "s# subformat='[^']*'##g" \
         -e "s# adapter_type='[^']*'##g" \
-        -e "s# hwversion=[^ ]*##g" \
         -e "s# lazy_refcounts=\\(on\\|off\\)##g" \
         -e "s# block_size=[0-9]\\+##g" \
         -e "s# block_state_zero=\\(on\\|off\\)##g" \
         -e "s# log_size=[0-9]\\+##g" \
         -e "s/archipelago:a/TEST_DIR\//g" \
-        -e "s# refcount_bits=[0-9]\\+##g" \
-        -e "s# key-secret=[a-zA-Z0-9]\\+##g"
+        -e "s# refcount_bits=[0-9]\\+##g"
 }
 
 _filter_img_info()
@@ -123,7 +115,6 @@ _filter_img_info()
         -e "/zeroed_grain: \\(on\\|off\\)/d" \
         -e "/subformat: '[^']*'/d" \
         -e "/adapter_type: '[^']*'/d" \
-        -e "/hwversion: '[^']*'/d" \
         -e "/lazy_refcounts: \\(on\\|off\\)/d" \
         -e "/block_size: [0-9]\\+/d" \
         -e "/block_state_zero: \\(on\\|off\\)/d" \
index 306b00c..5249ec5 100644 (file)
@@ -53,45 +53,21 @@ fi
 # make sure we have a standard umask
 umask 022
 
-if [ "$IMGOPTSSYNTAX" = "true" ]; then
-    DRIVER="driver=$IMGFMT"
-    if [ "$IMGFMT" = "luks" ]; then
-        DRIVER="$DRIVER,key-secret=keysec0"
-    fi
-    if [ "$IMGPROTO" = "file" ]; then
-        TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
-        TEST_IMG="$DRIVER,file.filename=$TEST_DIR/t.$IMGFMT"
-    elif [ "$IMGPROTO" = "nbd" ]; then
-        TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
-        TEST_IMG="$DRIVER,file.driver=nbd,file.host=127.0.0.1,file.port=10810"
-    elif [ "$IMGPROTO" = "ssh" ]; then
-        TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
-        TEST_IMG="$DRIVER,file.driver=ssh,file.host=127.0.0.1,file.path=$TEST_IMG_FILE"
-    elif [ "$IMGPROTO" = "nfs" ]; then
-        TEST_DIR="$DRIVER,file.driver=nfs,file.filename=nfs://127.0.0.1/$TEST_DIR"
-        TEST_IMG=$TEST_DIR_OPTS/t.$IMGFMT
-    elif [ "$IMGPROTO" = "archipelago" ]; then
-        TEST_IMG="$DRIVER,file.driver=archipelago,file.volume=:at.$IMGFMT"
-    else
-        TEST_IMG="$DRIVER,file.driver=$IMGPROTO,file.filename=$TEST_DIR/t.$IMGFMT"
-    fi
+if [ "$IMGPROTO" = "file" ]; then
+    TEST_IMG=$TEST_DIR/t.$IMGFMT
+elif [ "$IMGPROTO" = "nbd" ]; then
+    TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
+    TEST_IMG="nbd:127.0.0.1:10810"
+elif [ "$IMGPROTO" = "ssh" ]; then
+    TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
+    TEST_IMG="ssh://127.0.0.1$TEST_IMG_FILE"
+elif [ "$IMGPROTO" = "nfs" ]; then
+    TEST_DIR="nfs://127.0.0.1/$TEST_DIR"
+    TEST_IMG=$TEST_DIR/t.$IMGFMT
+elif [ "$IMGPROTO" = "archipelago" ]; then
+    TEST_IMG="archipelago:at.$IMGFMT"
 else
-    if [ "$IMGPROTO" = "file" ]; then
-        TEST_IMG=$TEST_DIR/t.$IMGFMT
-    elif [ "$IMGPROTO" = "nbd" ]; then
-        TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
-        TEST_IMG="nbd:127.0.0.1:10810"
-    elif [ "$IMGPROTO" = "ssh" ]; then
-        TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
-        TEST_IMG="ssh://127.0.0.1$TEST_IMG_FILE"
-    elif [ "$IMGPROTO" = "nfs" ]; then
-        TEST_DIR="nfs://127.0.0.1/$TEST_DIR"
-        TEST_IMG=$TEST_DIR/t.$IMGFMT
-    elif [ "$IMGPROTO" = "archipelago" ]; then
-        TEST_IMG="archipelago:at.$IMGFMT"
-    else
-        TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
-    fi
+    TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
 fi
 
 _optstr_add()
@@ -132,7 +108,6 @@ _make_test_img()
     local img_name=""
     local use_backing=0
     local backing_file=""
-    local object_options=""
 
     if [ -n "$TEST_IMG_FILE" ]; then
         img_name=$TEST_IMG_FILE
@@ -143,10 +118,6 @@ _make_test_img()
     if [ -n "$IMGOPTS" ]; then
         optstr=$(_optstr_add "$optstr" "$IMGOPTS")
     fi
-    if [ -n "$IMGKEYSECRET" ]; then
-        object_options="--object secret,id=keysec0,data=$IMGKEYSECRET"
-        optstr=$(_optstr_add "$optstr" "key-secret=keysec0")
-    fi
 
     if [ "$1" = "-b" ]; then
         use_backing=1
@@ -164,9 +135,9 @@ _make_test_img()
     # XXX(hch): have global image options?
     (
      if [ $use_backing = 1 ]; then
-        $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options -b "$backing_file" "$img_name" $image_size 2>&1
+        $QEMU_IMG create -f $IMGFMT $extra_img_options -b "$backing_file" "$img_name" $image_size 2>&1
      else
-        $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options "$img_name" $image_size 2>&1
+        $QEMU_IMG create -f $IMGFMT $extra_img_options "$img_name" $image_size 2>&1
      fi
     ) | _filter_img_create
 
@@ -228,13 +199,7 @@ _cleanup_test_img()
 
 _check_test_img()
 {
-    (
-        if [ "$IMGOPTSSYNTAX" = "true" ]; then
-            $QEMU_IMG check $QEMU_IMG_EXTRA_ARGS "$@" "$TEST_IMG" 2>&1
-        else
-            $QEMU_IMG check "$@" -f $IMGFMT "$TEST_IMG" 2>&1
-        fi
-    ) | _filter_testdir | \
+    $QEMU_IMG check "$@" -f $IMGFMT "$TEST_IMG" 2>&1 | _filter_testdir | \
         sed -e '/allocated.*fragmented.*compressed clusters/d' \
             -e 's/qemu-img: This image format does not support checks/No errors were found on the image./' \
             -e '/Image end offset: [0-9]\+/d'
index 50ddeed..822953b 100644 (file)
 097 rw auto backing
 098 rw auto backing quick
 099 rw auto quick
-# 100 was removed, do not reuse
+100 rw auto quick
 101 rw auto quick
 102 rw auto quick
 103 rw auto quick
 149 rw auto sudo
 150 rw auto quick
 152 rw auto quick
-154 rw auto backing quick
-155 rw auto
-156 rw auto quick
-157 auto
-162 auto quick
index dbe0ee5..56f988a 100644 (file)
@@ -24,6 +24,8 @@ import string
 import unittest
 import sys
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts'))
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts', 'qmp'))
+import qmp
 import qtest
 import struct
 import json
@@ -39,12 +41,13 @@ qemu_io_args = [os.environ.get('QEMU_IO_PROG', 'qemu-io')]
 if os.environ.get('QEMU_IO_OPTIONS'):
     qemu_io_args += os.environ['QEMU_IO_OPTIONS'].strip().split(' ')
 
-qemu_prog = os.environ.get('QEMU_PROG', 'qemu')
-qemu_opts = os.environ.get('QEMU_OPTIONS', '').strip().split(' ')
+qemu_args = [os.environ.get('QEMU_PROG', 'qemu')]
+if os.environ.get('QEMU_OPTIONS'):
+    qemu_args += os.environ['QEMU_OPTIONS'].strip().split(' ')
 
 imgfmt = os.environ.get('IMGFMT', 'raw')
 imgproto = os.environ.get('IMGPROTO', 'file')
-test_dir = os.environ.get('TEST_DIR')
+test_dir = os.environ.get('TEST_DIR', '/var/tmp')
 output_dir = os.environ.get('OUTPUT_DIR', '.')
 cachemode = os.environ.get('CACHEMODE')
 qemu_default_machine = os.environ.get('QEMU_DEFAULT_MACHINE')
@@ -128,13 +131,44 @@ def log(msg, filters=[]):
         msg = flt(msg)
     print msg
 
-class VM(qtest.QEMUQtestMachine):
+# Test if 'match' is a recursive subset of 'event'
+def event_match(event, match=None):
+    if match is None:
+        return True
+
+    for key in match:
+        if key in event:
+            if isinstance(event[key], dict):
+                if not event_match(event[key], match[key]):
+                    return False
+            elif event[key] != match[key]:
+                return False
+        else:
+            return False
+
+    return True
+
+class VM(object):
     '''A QEMU VM'''
 
     def __init__(self):
-        super(VM, self).__init__(qemu_prog, qemu_opts, test_dir=test_dir,
-                                 socket_scm_helper=socket_scm_helper)
+        self._monitor_path = os.path.join(test_dir, 'qemu-mon.%d' % os.getpid())
+        self._qemu_log_path = os.path.join(test_dir, 'qemu-log.%d' % os.getpid())
+        self._qtest_path = os.path.join(test_dir, 'qemu-qtest.%d' % os.getpid())
+        self._args = qemu_args + ['-chardev',
+                     'socket,id=mon,path=' + self._monitor_path,
+                     '-mon', 'chardev=mon,mode=control',
+                     '-qtest', 'unix:path=' + self._qtest_path,
+                     '-machine', 'accel=qtest',
+                     '-display', 'none', '-vga', 'none']
         self._num_drives = 0
+        self._events = []
+
+    # This can be used to add an unused monitor instance.
+    def add_monitor_telnet(self, ip, port):
+        args = 'tcp:%s:%d,server,nowait,telnet' % (ip, port)
+        self._args.append('-monitor')
+        self._args.append(args)
 
     def add_drive_raw(self, opts):
         self._args.append('-drive')
@@ -177,6 +211,106 @@ class VM(qtest.QEMUQtestMachine):
         return self.qmp('human-monitor-command',
                         command_line='qemu-io %s "%s"' % (drive, cmd))
 
+    def add_fd(self, fd, fdset, opaque, opts=''):
+        '''Pass a file descriptor to the VM'''
+        options = ['fd=%d' % fd,
+                   'set=%d' % fdset,
+                   'opaque=%s' % opaque]
+        if opts:
+            options.append(opts)
+
+        self._args.append('-add-fd')
+        self._args.append(','.join(options))
+        return self
+
+    def send_fd_scm(self, fd_file_path):
+        # In iotest.py, the qmp should always use unix socket.
+        assert self._qmp.is_scm_available()
+        bin = socket_scm_helper
+        if os.path.exists(bin) == False:
+            print "Scm help program does not present, path '%s'." % bin
+            return -1
+        fd_param = ["%s" % bin,
+                    "%d" % self._qmp.get_sock_fd(),
+                    "%s" % fd_file_path]
+        devnull = open('/dev/null', 'rb')
+        p = subprocess.Popen(fd_param, stdin=devnull, stdout=sys.stdout,
+                             stderr=sys.stderr)
+        return p.wait()
+
+    def launch(self):
+        '''Launch the VM and establish a QMP connection'''
+        devnull = open('/dev/null', 'rb')
+        qemulog = open(self._qemu_log_path, 'wb')
+        try:
+            self._qmp = qmp.QEMUMonitorProtocol(self._monitor_path, server=True)
+            self._qtest = qtest.QEMUQtestProtocol(self._qtest_path, server=True)
+            self._popen = subprocess.Popen(self._args, stdin=devnull, stdout=qemulog,
+                                           stderr=subprocess.STDOUT)
+            self._qmp.accept()
+            self._qtest.accept()
+        except:
+            _remove_if_exists(self._monitor_path)
+            _remove_if_exists(self._qtest_path)
+            raise
+
+    def shutdown(self):
+        '''Terminate the VM and clean up'''
+        if not self._popen is None:
+            self._qmp.cmd('quit')
+            exitcode = self._popen.wait()
+            if exitcode < 0:
+                sys.stderr.write('qemu received signal %i: %s\n' % (-exitcode, ' '.join(self._args)))
+            os.remove(self._monitor_path)
+            os.remove(self._qtest_path)
+            os.remove(self._qemu_log_path)
+            self._popen = None
+
+    underscore_to_dash = string.maketrans('_', '-')
+    def qmp(self, cmd, conv_keys=True, **args):
+        '''Invoke a QMP command and return the result dict'''
+        qmp_args = dict()
+        for k in args.keys():
+            if conv_keys:
+                qmp_args[k.translate(self.underscore_to_dash)] = args[k]
+            else:
+                qmp_args[k] = args[k]
+
+        return self._qmp.cmd(cmd, args=qmp_args)
+
+    def qtest(self, cmd):
+        '''Send a qtest command to guest'''
+        return self._qtest.cmd(cmd)
+
+    def get_qmp_event(self, wait=False):
+        '''Poll for one queued QMP events and return it'''
+        if len(self._events) > 0:
+            return self._events.pop(0)
+        return self._qmp.pull_event(wait=wait)
+
+    def get_qmp_events(self, wait=False):
+        '''Poll for queued QMP events and return a list of dicts'''
+        events = self._qmp.get_events(wait=wait)
+        events.extend(self._events)
+        del self._events[:]
+        self._qmp.clear_events()
+        return events
+
+    def event_wait(self, name='BLOCK_JOB_COMPLETED', timeout=60.0, match=None):
+        # Search cached events
+        for event in self._events:
+            if (event['event'] == name) and event_match(event, match):
+                self._events.remove(event)
+                return event
+
+        # Poll for new events
+        while True:
+            event = self._qmp.pull_event(wait=timeout)
+            if (event['event'] == name) and event_match(event, match):
+                return event
+            self._events.append(event)
+
+        return None
 
 index_re = re.compile(r'([^\[]+)\[([^\]]+)\]')
 
@@ -293,6 +427,15 @@ class QMPTestCase(unittest.TestCase):
         event = self.wait_until_completed(drive=drive)
         self.assert_qmp(event, 'data/type', 'mirror')
 
+def _remove_if_exists(path):
+    '''Remove file object at path if it exists'''
+    try:
+        os.remove(path)
+    except OSError as exception:
+        if exception.errno == errno.ENOENT:
+           return
+        raise
+
 def notrun(reason):
     '''Skip this test suite'''
     # Each test in qemu-iotests has a number ("seq")
@@ -318,14 +461,6 @@ def verify_quorum():
 def main(supported_fmts=[], supported_oses=['linux']):
     '''Run tests'''
 
-    # We are using TEST_DIR and QEMU_DEFAULT_MACHINE as proxies to
-    # indicate that we're not being run via "check". There may be
-    # other things set up by "check" that individual test cases rely
-    # on.
-    if test_dir is None or qemu_default_machine is None:
-        sys.stderr.write('Please run this test via the "check" script\n')
-        sys.exit(os.EX_USAGE)
-
     debug = '-d' in sys.argv
     verbosity = 1
     verify_image_format(supported_fmts)
diff --git a/tests/qht-bench.c b/tests/qht-bench.c
deleted file mode 100644 (file)
index 76360a0..0000000
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * Copyright (C) 2016, Emilio G. Cota <cota@braap.org>
- *
- * License: GNU GPL, version 2 or later.
- *   See the COPYING file in the top-level directory.
- */
-#include "qemu/osdep.h"
-#include "qemu/processor.h"
-#include "qemu/atomic.h"
-#include "qemu/qht.h"
-#include "qemu/rcu.h"
-#include "exec/tb-hash-xx.h"
-
-struct thread_stats {
-    size_t rd;
-    size_t not_rd;
-    size_t in;
-    size_t not_in;
-    size_t rm;
-    size_t not_rm;
-    size_t rz;
-    size_t not_rz;
-};
-
-struct thread_info {
-    void (*func)(struct thread_info *);
-    struct thread_stats stats;
-    uint64_t r;
-    bool write_op; /* writes alternate between insertions and removals */
-    bool resize_down;
-} QEMU_ALIGNED(64); /* avoid false sharing among threads */
-
-static struct qht ht;
-static QemuThread *rw_threads;
-
-#define DEFAULT_RANGE (4096)
-#define DEFAULT_QHT_N_ELEMS DEFAULT_RANGE
-
-static unsigned int duration = 1;
-static unsigned int n_rw_threads = 1;
-static unsigned long lookup_range = DEFAULT_RANGE;
-static unsigned long update_range = DEFAULT_RANGE;
-static size_t init_range = DEFAULT_RANGE;
-static size_t init_size = DEFAULT_RANGE;
-static size_t n_ready_threads;
-static long populate_offset;
-static long *keys;
-
-static size_t resize_min;
-static size_t resize_max;
-static struct thread_info *rz_info;
-static unsigned long resize_delay = 1000;
-static double resize_rate; /* 0.0 to 1.0 */
-static unsigned int n_rz_threads = 1;
-static QemuThread *rz_threads;
-
-static double update_rate; /* 0.0 to 1.0 */
-static uint64_t update_threshold;
-static uint64_t resize_threshold;
-
-static size_t qht_n_elems = DEFAULT_QHT_N_ELEMS;
-static int qht_mode;
-
-static bool test_start;
-static bool test_stop;
-
-static struct thread_info *rw_info;
-
-static const char commands_string[] =
-    " -d = duration, in seconds\n"
-    " -n = number of threads\n"
-    "\n"
-    " -o = offset at which keys start\n"
-    "\n"
-    " -g = set -s,-k,-K,-l,-r to the same value\n"
-    " -s = initial size hint\n"
-    " -k = initial number of keys\n"
-    " -K = initial range of keys (will be rounded up to pow2)\n"
-    " -l = lookup range of keys (will be rounded up to pow2)\n"
-    " -r = update range of keys (will be rounded up to pow2)\n"
-    "\n"
-    " -u = update rate (0.0 to 100.0), 50/50 split of insertions/removals\n"
-    "\n"
-    " -R = enable auto-resize\n"
-    " -S = resize rate (0.0 to 100.0)\n"
-    " -D = delay (in us) between potential resizes\n"
-    " -N = number of resize threads";
-
-static void usage_complete(int argc, char *argv[])
-{
-    fprintf(stderr, "Usage: %s [options]\n", argv[0]);
-    fprintf(stderr, "options:\n%s\n", commands_string);
-    exit(-1);
-}
-
-static bool is_equal(const void *obj, const void *userp)
-{
-    const long *a = obj;
-    const long *b = userp;
-
-    return *a == *b;
-}
-
-static inline uint32_t h(unsigned long v)
-{
-    return tb_hash_func5(v, 0, 0);
-}
-
-/*
- * From: https://en.wikipedia.org/wiki/Xorshift
- * This is faster than rand_r(), and gives us a wider range (RAND_MAX is only
- * guaranteed to be >= INT_MAX).
- */
-static uint64_t xorshift64star(uint64_t x)
-{
-    x ^= x >> 12; /* a */
-    x ^= x << 25; /* b */
-    x ^= x >> 27; /* c */
-    return x * UINT64_C(2685821657736338717);
-}
-
-static void do_rz(struct thread_info *info)
-{
-    struct thread_stats *stats = &info->stats;
-
-    if (info->r < resize_threshold) {
-        size_t size = info->resize_down ? resize_min : resize_max;
-        bool resized;
-
-        resized = qht_resize(&ht, size);
-        info->resize_down = !info->resize_down;
-
-        if (resized) {
-            stats->rz++;
-        } else {
-            stats->not_rz++;
-        }
-    }
-    g_usleep(resize_delay);
-}
-
-static void do_rw(struct thread_info *info)
-{
-    struct thread_stats *stats = &info->stats;
-    uint32_t hash;
-    long *p;
-
-    if (info->r >= update_threshold) {
-        bool read;
-
-        p = &keys[info->r & (lookup_range - 1)];
-        hash = h(*p);
-        read = qht_lookup(&ht, is_equal, p, hash);
-        if (read) {
-            stats->rd++;
-        } else {
-            stats->not_rd++;
-        }
-    } else {
-        p = &keys[info->r & (update_range - 1)];
-        hash = h(*p);
-        if (info->write_op) {
-            bool written = false;
-
-            if (qht_lookup(&ht, is_equal, p, hash) == NULL) {
-                written = qht_insert(&ht, p, hash);
-            }
-            if (written) {
-                stats->in++;
-            } else {
-                stats->not_in++;
-            }
-        } else {
-            bool removed = false;
-
-            if (qht_lookup(&ht, is_equal, p, hash)) {
-                removed = qht_remove(&ht, p, hash);
-            }
-            if (removed) {
-                stats->rm++;
-            } else {
-                stats->not_rm++;
-            }
-        }
-        info->write_op = !info->write_op;
-    }
-}
-
-static void *thread_func(void *p)
-{
-    struct thread_info *info = p;
-
-    rcu_register_thread();
-
-    atomic_inc(&n_ready_threads);
-    while (!atomic_mb_read(&test_start)) {
-        cpu_relax();
-    }
-
-    rcu_read_lock();
-    while (!atomic_read(&test_stop)) {
-        info->r = xorshift64star(info->r);
-        info->func(info);
-    }
-    rcu_read_unlock();
-
-    rcu_unregister_thread();
-    return NULL;
-}
-
-/* sets everything except info->func */
-static void prepare_thread_info(struct thread_info *info, int i)
-{
-    /* seed for the RNG; each thread should have a different one */
-    info->r = (i + 1) ^ time(NULL);
-    /* the first update will be a write */
-    info->write_op = true;
-    /* the first resize will be down */
-    info->resize_down = true;
-
-    memset(&info->stats, 0, sizeof(info->stats));
-}
-
-static void
-th_create_n(QemuThread **threads, struct thread_info **infos, const char *name,
-            void (*func)(struct thread_info *), int offset, int n)
-{
-    struct thread_info *info;
-    QemuThread *th;
-    int i;
-
-    th = g_malloc(sizeof(*th) * n);
-    *threads = th;
-
-    info = qemu_memalign(64, sizeof(*info) * n);
-    *infos = info;
-
-    for (i = 0; i < n; i++) {
-        prepare_thread_info(&info[i], offset + i);
-        info[i].func = func;
-        qemu_thread_create(&th[i], name, thread_func, &info[i],
-                           QEMU_THREAD_JOINABLE);
-    }
-}
-
-static void create_threads(void)
-{
-    th_create_n(&rw_threads, &rw_info, "rw", do_rw, 0, n_rw_threads);
-    th_create_n(&rz_threads, &rz_info, "rz", do_rz, n_rw_threads, n_rz_threads);
-}
-
-static void pr_params(void)
-{
-    printf("Parameters:\n");
-    printf(" duration:          %d s\n", duration);
-    printf(" # of threads:      %u\n", n_rw_threads);
-    printf(" initial # of keys: %zu\n", init_size);
-    printf(" initial size hint: %zu\n", qht_n_elems);
-    printf(" auto-resize:       %s\n",
-           qht_mode & QHT_MODE_AUTO_RESIZE ? "on" : "off");
-    if (resize_rate) {
-        printf(" resize_rate:       %f%%\n", resize_rate * 100.0);
-        printf(" resize range:      %zu-%zu\n", resize_min, resize_max);
-        printf(" # resize threads   %u\n", n_rz_threads);
-    }
-    printf(" update rate:       %f%%\n", update_rate * 100.0);
-    printf(" offset:            %ld\n", populate_offset);
-    printf(" initial key range: %zu\n", init_range);
-    printf(" lookup range:      %lu\n", lookup_range);
-    printf(" update range:      %lu\n", update_range);
-}
-
-static void do_threshold(double rate, uint64_t *threshold)
-{
-    if (rate == 1.0) {
-        *threshold = UINT64_MAX;
-    } else {
-        *threshold = rate * UINT64_MAX;
-    }
-}
-
-static void htable_init(void)
-{
-    unsigned long n = MAX(init_range, update_range);
-    uint64_t r = time(NULL);
-    size_t retries = 0;
-    size_t i;
-
-    /* avoid allocating memory later by allocating all the keys now */
-    keys = g_malloc(sizeof(*keys) * n);
-    for (i = 0; i < n; i++) {
-        keys[i] = populate_offset + i;
-    }
-
-    /* some sanity checks */
-    g_assert_cmpuint(lookup_range, <=, n);
-
-    /* compute thresholds */
-    do_threshold(update_rate, &update_threshold);
-    do_threshold(resize_rate, &resize_threshold);
-
-    if (resize_rate) {
-        resize_min = n / 2;
-        resize_max = n;
-        assert(resize_min < resize_max);
-    } else {
-        n_rz_threads = 0;
-    }
-
-    /* initialize the hash table */
-    qht_init(&ht, qht_n_elems, qht_mode);
-    assert(init_size <= init_range);
-
-    pr_params();
-
-    fprintf(stderr, "Initialization: populating %zu items...", init_size);
-    for (i = 0; i < init_size; i++) {
-        for (;;) {
-            uint32_t hash;
-            long *p;
-
-            r = xorshift64star(r);
-            p = &keys[r & (init_range - 1)];
-            hash = h(*p);
-            if (qht_insert(&ht, p, hash)) {
-                break;
-            }
-            retries++;
-        }
-    }
-    fprintf(stderr, " populated after %zu retries\n", retries);
-}
-
-static void add_stats(struct thread_stats *s, struct thread_info *info, int n)
-{
-    int i;
-
-    for (i = 0; i < n; i++) {
-        struct thread_stats *stats = &info[i].stats;
-
-        s->rd += stats->rd;
-        s->not_rd += stats->not_rd;
-
-        s->in += stats->in;
-        s->not_in += stats->not_in;
-
-        s->rm += stats->rm;
-        s->not_rm += stats->not_rm;
-
-        s->rz += stats->rz;
-        s->not_rz += stats->not_rz;
-    }
-}
-
-static void pr_stats(void)
-{
-    struct thread_stats s = {};
-    double tx;
-
-    add_stats(&s, rw_info, n_rw_threads);
-    add_stats(&s, rz_info, n_rz_threads);
-
-    printf("Results:\n");
-
-    if (resize_rate) {
-        printf(" Resizes:           %zu (%.2f%% of %zu)\n",
-               s.rz, (double)s.rz / (s.rz + s.not_rz) * 100, s.rz + s.not_rz);
-    }
-
-    printf(" Read:              %.2f M (%.2f%% of %.2fM)\n",
-           (double)s.rd / 1e6,
-           (double)s.rd / (s.rd + s.not_rd) * 100,
-           (double)(s.rd + s.not_rd) / 1e6);
-    printf(" Inserted:          %.2f M (%.2f%% of %.2fM)\n",
-           (double)s.in / 1e6,
-           (double)s.in / (s.in + s.not_in) * 100,
-           (double)(s.in + s.not_in) / 1e6);
-    printf(" Removed:           %.2f M (%.2f%% of %.2fM)\n",
-           (double)s.rm / 1e6,
-           (double)s.rm / (s.rm + s.not_rm) * 100,
-           (double)(s.rm + s.not_rm) / 1e6);
-
-    tx = (s.rd + s.not_rd + s.in + s.not_in + s.rm + s.not_rm) / 1e6 / duration;
-    printf(" Throughput:        %.2f MT/s\n", tx);
-    printf(" Throughput/thread: %.2f MT/s/thread\n", tx / n_rw_threads);
-}
-
-static void run_test(void)
-{
-    unsigned int remaining;
-    int i;
-
-    while (atomic_read(&n_ready_threads) != n_rw_threads + n_rz_threads) {
-        cpu_relax();
-    }
-    atomic_mb_set(&test_start, true);
-    do {
-        remaining = sleep(duration);
-    } while (remaining);
-    atomic_mb_set(&test_stop, true);
-
-    for (i = 0; i < n_rw_threads; i++) {
-        qemu_thread_join(&rw_threads[i]);
-    }
-    for (i = 0; i < n_rz_threads; i++) {
-        qemu_thread_join(&rz_threads[i]);
-    }
-}
-
-static void parse_args(int argc, char *argv[])
-{
-    int c;
-
-    for (;;) {
-        c = getopt(argc, argv, "d:D:g:k:K:l:hn:N:o:r:Rs:S:u:");
-        if (c < 0) {
-            break;
-        }
-        switch (c) {
-        case 'd':
-            duration = atoi(optarg);
-            break;
-        case 'D':
-            resize_delay = atol(optarg);
-            break;
-        case 'g':
-            init_range = pow2ceil(atol(optarg));
-            lookup_range = pow2ceil(atol(optarg));
-            update_range = pow2ceil(atol(optarg));
-            qht_n_elems = atol(optarg);
-            init_size = atol(optarg);
-            break;
-        case 'h':
-            usage_complete(argc, argv);
-            exit(0);
-        case 'k':
-            init_size = atol(optarg);
-            break;
-        case 'K':
-            init_range = pow2ceil(atol(optarg));
-            break;
-        case 'l':
-            lookup_range = pow2ceil(atol(optarg));
-            break;
-        case 'n':
-            n_rw_threads = atoi(optarg);
-            break;
-        case 'N':
-            n_rz_threads = atoi(optarg);
-            break;
-        case 'o':
-            populate_offset = atol(optarg);
-            break;
-        case 'r':
-            update_range = pow2ceil(atol(optarg));
-            break;
-        case 'R':
-            qht_mode |= QHT_MODE_AUTO_RESIZE;
-            break;
-        case 's':
-            qht_n_elems = atol(optarg);
-            break;
-        case 'S':
-            resize_rate = atof(optarg) / 100.0;
-            if (resize_rate > 1.0) {
-                resize_rate = 1.0;
-            }
-            break;
-        case 'u':
-            update_rate = atof(optarg) / 100.0;
-            if (update_rate > 1.0) {
-                update_rate = 1.0;
-            }
-            break;
-        }
-    }
-}
-
-int main(int argc, char *argv[])
-{
-    parse_args(argc, argv);
-    htable_init();
-    create_threads();
-    run_test();
-    pr_stats();
-    return 0;
-}
index 23493a2..bd5cdde 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu-common.h"
 #include "qemu/cutils.h"
index 4002ecf..244f0f2 100644 (file)
@@ -61,6 +61,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu/atomic.h"
 #include "qemu/rcu.h"
 #include "qemu/thread.h"
index a086efd..fa7029a 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "libqtest.h"
 #include "hw/timer/mc146818rtc_regs.h"
index 13de7ee..54e5aa7 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "libqos/pci-pc.h"
 #include "qemu/timer.h"
index 21004a7..f53911d 100644 (file)
@@ -8,6 +8,7 @@
  * See the COPYING file in the top-level directory.
  */
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "libqtest.h"
 
index 5902302..f1e7fa9 100644 (file)
@@ -1,4 +1,4 @@
-#include "core-isa.h"
+#include <core-isa.h>
 
 #if XTENSA_HAVE_BE
 OUTPUT_FORMAT("elf32-xtensa-be")
index 0d13aa8..ac11175 100644 (file)
@@ -7,6 +7,7 @@
  * See the COPYING file in the top-level directory.
  */
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "libqtest.h"
 #include "libqos/pci.h"
index 03aa846..39b8ce8 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "block/aio.h"
 #include "qapi/error.h"
 #include "qemu/timer.h"
index ec122ce..922e839 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qapi/error.h"
 #include "qemu/base64.h"
index 5a791d2..5050950 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu/bitops.h"
 
 typedef struct {
@@ -65,82 +66,10 @@ static void test_sextract64(void)
     }
 }
 
-typedef struct {
-    uint32_t unshuffled;
-    uint32_t shuffled;
-} Shuffle32Test;
-
-typedef struct {
-    uint64_t unshuffled;
-    uint64_t shuffled;
-} Shuffle64Test;
-
-static const Shuffle32Test test_shuffle32_data[] = {
-    { 0x0000FFFF, 0x55555555 },
-    { 0x000081C5, 0x40015011 },
-};
-
-static const Shuffle64Test test_shuffle64_data[] = {
-    { 0x00000000FFFFFFFFULL, 0x5555555555555555ULL },
-    { 0x00000000493AB02CULL, 0x1041054445000450ULL },
-};
-
-static void test_half_shuffle32(void)
-{
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(test_shuffle32_data); i++) {
-        const Shuffle32Test *test = &test_shuffle32_data[i];
-        uint32_t r = half_shuffle32(test->unshuffled);
-
-        g_assert_cmpint(r, ==, test->shuffled);
-    }
-}
-
-static void test_half_shuffle64(void)
-{
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(test_shuffle64_data); i++) {
-        const Shuffle64Test *test = &test_shuffle64_data[i];
-        uint64_t r = half_shuffle64(test->unshuffled);
-
-        g_assert_cmpint(r, ==, test->shuffled);
-    }
-}
-
-static void test_half_unshuffle32(void)
-{
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(test_shuffle32_data); i++) {
-        const Shuffle32Test *test = &test_shuffle32_data[i];
-        uint32_t r = half_unshuffle32(test->shuffled);
-
-        g_assert_cmpint(r, ==, test->unshuffled);
-    }
-}
-
-static void test_half_unshuffle64(void)
-{
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(test_shuffle64_data); i++) {
-        const Shuffle64Test *test = &test_shuffle64_data[i];
-        uint64_t r = half_unshuffle64(test->shuffled);
-
-        g_assert_cmpint(r, ==, test->unshuffled);
-    }
-}
-
 int main(int argc, char **argv)
 {
     g_test_init(&argc, &argv, NULL);
     g_test_add_func("/bitops/sextract32", test_sextract32);
     g_test_add_func("/bitops/sextract64", test_sextract64);
-    g_test_add_func("/bitops/half_shuffle32", test_half_shuffle32);
-    g_test_add_func("/bitops/half_shuffle64", test_half_shuffle64);
-    g_test_add_func("/bitops/half_unshuffle32", test_half_unshuffle32);
-    g_test_add_func("/bitops/half_unshuffle64", test_half_unshuffle64);
     return g_test_run();
 }
index d049cba..55fad95 100644 (file)
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qapi/error.h"
 #include "qemu/main-loop.h"
 #include "block/blockjob.h"
-#include "sysemu/block-backend.h"
 
 typedef struct {
     BlockJob common;
@@ -30,7 +30,7 @@ static const BlockJobDriver test_block_job_driver = {
 
 static void test_block_job_complete(BlockJob *job, void *opaque)
 {
-    BlockDriverState *bs = blk_bs(job->blk);
+    BlockDriverState *bs = job->bs;
     int rc = (intptr_t)opaque;
 
     if (block_job_is_cancelled(job)) {
@@ -91,22 +91,19 @@ static BlockJob *test_block_job_start(unsigned int iterations,
     BlockDriverState *bs;
     TestBlockJob *s;
     TestBlockJobCBData *data;
-    static unsigned counter;
-    char job_id[24];
 
     data = g_new0(TestBlockJobCBData, 1);
     bs = bdrv_new();
-    snprintf(job_id, sizeof(job_id), "job%u", counter++);
-    s = block_job_create(job_id, &test_block_job_driver, bs, 0,
-                         test_block_job_cb, data, &error_abort);
+    s = block_job_create(&test_block_job_driver, bs, 0, test_block_job_cb,
+                         data, &error_abort);
     s->iterations = iterations;
     s->use_timer = use_timer;
     s->rc = rc;
     s->result = result;
-    s->common.co = qemu_coroutine_create(test_block_job_run, s);
+    s->common.co = qemu_coroutine_create(test_block_job_run);
     data->job = s;
     data->result = result;
-    qemu_coroutine_enter(s->common.co);
+    qemu_coroutine_enter(s->common.co, s);
     return &s->common;
 }
 
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
deleted file mode 100644 (file)
index 5b0e934..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Blockjob tests
- *
- * Copyright Igalia, S.L. 2016
- *
- * Authors:
- *  Alberto Garcia   <berto@igalia.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu/main-loop.h"
-#include "block/blockjob.h"
-#include "sysemu/block-backend.h"
-
-static const BlockJobDriver test_block_job_driver = {
-    .instance_size = sizeof(BlockJob),
-};
-
-static void block_job_cb(void *opaque, int ret)
-{
-}
-
-static BlockJob *do_test_id(BlockBackend *blk, const char *id,
-                            bool should_succeed)
-{
-    BlockJob *job;
-    Error *errp = NULL;
-
-    job = block_job_create(id, &test_block_job_driver, blk_bs(blk), 0,
-                           block_job_cb, NULL, &errp);
-    if (should_succeed) {
-        g_assert_null(errp);
-        g_assert_nonnull(job);
-        if (id) {
-            g_assert_cmpstr(job->id, ==, id);
-        } else {
-            g_assert_cmpstr(job->id, ==, blk_name(blk));
-        }
-    } else {
-        g_assert_nonnull(errp);
-        g_assert_null(job);
-        error_free(errp);
-    }
-
-    return job;
-}
-
-/* This creates a BlockBackend (optionally with a name) with a
- * BlockDriverState inserted. */
-static BlockBackend *create_blk(const char *name)
-{
-    BlockBackend *blk = blk_new();
-    BlockDriverState *bs = bdrv_new();
-
-    blk_insert_bs(blk, bs);
-    bdrv_unref(bs);
-
-    if (name) {
-        Error *errp = NULL;
-        monitor_add_blk(blk, name, &errp);
-        g_assert_null(errp);
-    }
-
-    return blk;
-}
-
-/* This destroys the backend */
-static void destroy_blk(BlockBackend *blk)
-{
-    if (blk_name(blk)[0] != '\0') {
-        monitor_remove_blk(blk);
-    }
-
-    blk_remove_bs(blk);
-    blk_unref(blk);
-}
-
-static void test_job_ids(void)
-{
-    BlockBackend *blk[3];
-    BlockJob *job[3];
-
-    blk[0] = create_blk(NULL);
-    blk[1] = create_blk("drive1");
-    blk[2] = create_blk("drive2");
-
-    /* No job ID provided and the block backend has no name */
-    job[0] = do_test_id(blk[0], NULL, false);
-
-    /* These are all invalid job IDs */
-    job[0] = do_test_id(blk[0], "0id", false);
-    job[0] = do_test_id(blk[0], "",    false);
-    job[0] = do_test_id(blk[0], "   ", false);
-    job[0] = do_test_id(blk[0], "123", false);
-    job[0] = do_test_id(blk[0], "_id", false);
-    job[0] = do_test_id(blk[0], "-id", false);
-    job[0] = do_test_id(blk[0], ".id", false);
-    job[0] = do_test_id(blk[0], "#id", false);
-
-    /* This one is valid */
-    job[0] = do_test_id(blk[0], "id0", true);
-
-    /* We cannot have two jobs in the same BDS */
-    do_test_id(blk[0], "id1", false);
-
-    /* Duplicate job IDs are not allowed */
-    job[1] = do_test_id(blk[1], "id0", false);
-
-    /* But once job[0] finishes we can reuse its ID */
-    block_job_unref(job[0]);
-    job[1] = do_test_id(blk[1], "id0", true);
-
-    /* No job ID specified, defaults to the backend name ('drive1') */
-    block_job_unref(job[1]);
-    job[1] = do_test_id(blk[1], NULL, true);
-
-    /* Duplicate job ID */
-    job[2] = do_test_id(blk[2], "drive1", false);
-
-    /* The ID of job[2] would default to 'drive2' but it is already in use */
-    job[0] = do_test_id(blk[0], "drive2", true);
-    job[2] = do_test_id(blk[2], NULL, false);
-
-    /* This one is valid */
-    job[2] = do_test_id(blk[2], "id_2", true);
-
-    block_job_unref(job[0]);
-    block_job_unref(job[1]);
-    block_job_unref(job[2]);
-
-    destroy_blk(blk[0]);
-    destroy_blk(blk[1]);
-    destroy_blk(blk[2]);
-}
-
-int main(int argc, char **argv)
-{
-    qemu_init_main_loop(&error_abort);
-
-    g_test_init(&argc, &argv, NULL);
-    g_test_add_func("/blockjob/ids", test_job_ids);
-    return g_test_run();
-}
diff --git a/tests/test-clone-visitor.c b/tests/test-clone-visitor.c
deleted file mode 100644 (file)
index df0c045..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * QAPI Clone Visitor unit-tests.
- *
- * Copyright (C) 2016 Red Hat Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include <glib.h>
-
-#include "qemu-common.h"
-#include "qapi/clone-visitor.h"
-#include "test-qapi-types.h"
-#include "test-qapi-visit.h"
-#include "qapi/qmp/types.h"
-
-static void test_clone_struct(void)
-{
-    UserDefOne *src, *dst;
-
-    src = g_new0(UserDefOne, 1);
-    src->integer = 42;
-    src->string = g_strdup("Hello");
-    src->has_enum1 = false;
-    src->enum1 = ENUM_ONE_VALUE2;
-
-    dst = QAPI_CLONE(UserDefOne, src);
-    g_assert(dst);
-    g_assert_cmpint(dst->integer, ==, 42);
-    g_assert(dst->string != src->string);
-    g_assert_cmpstr(dst->string, ==, "Hello");
-    g_assert_cmpint(dst->has_enum1, ==, false);
-    /* Our implementation does this, but it is not required:
-    g_assert_cmpint(dst->enum1, ==, ENUM_ONE_VALUE2);
-    */
-
-    qapi_free_UserDefOne(src);
-    qapi_free_UserDefOne(dst);
-}
-
-static void test_clone_alternate(void)
-{
-    AltStrBool *b_src, *s_src, *b_dst, *s_dst;
-
-    b_src = g_new0(AltStrBool, 1);
-    b_src->type = QTYPE_QBOOL;
-    b_src->u.b = true;
-    s_src = g_new0(AltStrBool, 1);
-    s_src->type = QTYPE_QSTRING;
-    s_src->u.s = g_strdup("World");
-
-    b_dst = QAPI_CLONE(AltStrBool, b_src);
-    g_assert(b_dst);
-    g_assert_cmpint(b_dst->type, ==, b_src->type);
-    g_assert_cmpint(b_dst->u.b, ==, b_src->u.b);
-    s_dst = QAPI_CLONE(AltStrBool, s_src);
-    g_assert(s_dst);
-    g_assert_cmpint(s_dst->type, ==, s_src->type);
-    g_assert_cmpstr(s_dst->u.s, ==, s_src->u.s);
-    g_assert(s_dst->u.s != s_src->u.s);
-
-    qapi_free_AltStrBool(b_src);
-    qapi_free_AltStrBool(s_src);
-    qapi_free_AltStrBool(b_dst);
-    qapi_free_AltStrBool(s_dst);
-}
-
-static void test_clone_native_list(void)
-{
-    uint8List *src, *dst;
-    uint8List *tmp = NULL;
-    int i;
-
-    /* Build list in reverse */
-    for (i = 10; i; i--) {
-        src = g_new0(uint8List, 1);
-        src->next = tmp;
-        src->value = i;
-        tmp = src;
-    }
-
-    dst = QAPI_CLONE(uint8List, src);
-    for (tmp = dst, i = 1; i <= 10; i++) {
-        g_assert(tmp);
-        g_assert_cmpint(tmp->value, ==, i);
-        tmp = tmp->next;
-    }
-    g_assert(!tmp);
-
-    qapi_free_uint8List(src);
-    qapi_free_uint8List(dst);
-}
-
-static void test_clone_empty(void)
-{
-    Empty2 *src, *dst;
-
-    src = g_new0(Empty2, 1);
-    dst = QAPI_CLONE(Empty2, src);
-    g_assert(dst);
-    qapi_free_Empty2(src);
-    qapi_free_Empty2(dst);
-}
-
-static void test_clone_complex1(void)
-{
-    UserDefNativeListUnion *src, *dst;
-
-    src = g_new0(UserDefNativeListUnion, 1);
-    src->type = USER_DEF_NATIVE_LIST_UNION_KIND_STRING;
-
-    dst = QAPI_CLONE(UserDefNativeListUnion, src);
-    g_assert(dst);
-    g_assert_cmpint(dst->type, ==, src->type);
-    g_assert(!dst->u.string.data);
-
-    qapi_free_UserDefNativeListUnion(src);
-    qapi_free_UserDefNativeListUnion(dst);
-}
-
-static void test_clone_complex2(void)
-{
-    WrapAlternate *src, *dst;
-
-    src = g_new0(WrapAlternate, 1);
-    src->alt = g_new(UserDefAlternate, 1);
-    src->alt->type = QTYPE_QDICT;
-    src->alt->u.udfu.integer = 42;
-    /* Clone intentionally converts NULL into "" for strings */
-    src->alt->u.udfu.string = NULL;
-    src->alt->u.udfu.enum1 = ENUM_ONE_VALUE3;
-    src->alt->u.udfu.u.value3.intb = 99;
-    src->alt->u.udfu.u.value3.has_a_b = true;
-    src->alt->u.udfu.u.value3.a_b = true;
-
-    dst = QAPI_CLONE(WrapAlternate, src);
-    g_assert(dst);
-    g_assert(dst->alt);
-    g_assert_cmpint(dst->alt->type, ==, QTYPE_QDICT);
-    g_assert_cmpint(dst->alt->u.udfu.integer, ==, 42);
-    g_assert_cmpstr(dst->alt->u.udfu.string, ==, "");
-    g_assert_cmpint(dst->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE3);
-    g_assert_cmpint(dst->alt->u.udfu.u.value3.intb, ==, 99);
-    g_assert_cmpint(dst->alt->u.udfu.u.value3.has_a_b, ==, true);
-    g_assert_cmpint(dst->alt->u.udfu.u.value3.a_b, ==, true);
-
-    qapi_free_WrapAlternate(src);
-    qapi_free_WrapAlternate(dst);
-}
-
-static void test_clone_complex3(void)
-{
-    __org_qemu_x_Struct2 *src, *dst;
-    __org_qemu_x_Union1List *tmp;
-
-    src = g_new0(__org_qemu_x_Struct2, 1);
-    tmp = src->array = g_new0(__org_qemu_x_Union1List, 1);
-    tmp->value = g_new0(__org_qemu_x_Union1, 1);
-    tmp->value->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;
-    tmp->value->u.__org_qemu_x_branch.data = g_strdup("one");
-    tmp = tmp->next = g_new0(__org_qemu_x_Union1List, 1);
-    tmp->value = g_new0(__org_qemu_x_Union1, 1);
-    tmp->value->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;
-    tmp->value->u.__org_qemu_x_branch.data = g_strdup("two");
-    tmp = tmp->next = g_new0(__org_qemu_x_Union1List, 1);
-    tmp->value = g_new0(__org_qemu_x_Union1, 1);
-    tmp->value->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;
-    tmp->value->u.__org_qemu_x_branch.data = g_strdup("three");
-
-    dst = QAPI_CLONE(__org_qemu_x_Struct2, src);
-    g_assert(dst);
-    tmp = dst->array;
-    g_assert(tmp);
-    g_assert(tmp->value);
-    g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch.data, ==, "one");
-    tmp = tmp->next;
-    g_assert(tmp);
-    g_assert(tmp->value);
-    g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch.data, ==, "two");
-    tmp = tmp->next;
-    g_assert(tmp);
-    g_assert(tmp->value);
-    g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch.data, ==, "three");
-    tmp = tmp->next;
-    g_assert(!tmp);
-
-    qapi_free___org_qemu_x_Struct2(src);
-    qapi_free___org_qemu_x_Struct2(dst);
-}
-
-int main(int argc, char **argv)
-{
-    g_test_init(&argc, &argv, NULL);
-
-    g_test_add_func("/visitor/clone/struct", test_clone_struct);
-    g_test_add_func("/visitor/clone/alternate", test_clone_alternate);
-    g_test_add_func("/visitor/clone/native_list", test_clone_native_list);
-    g_test_add_func("/visitor/clone/empty", test_clone_empty);
-    g_test_add_func("/visitor/clone/complex1", test_clone_complex1);
-    g_test_add_func("/visitor/clone/complex2", test_clone_complex2);
-    g_test_add_func("/visitor/clone/complex3", test_clone_complex3);
-
-    return g_test_run();
-}
index ee5e06d..dd4ced9 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu/coroutine.h"
 #include "qemu/coroutine_int.h"
 
@@ -30,8 +31,8 @@ static void test_in_coroutine(void)
 
     g_assert(!qemu_in_coroutine());
 
-    coroutine = qemu_coroutine_create(verify_in_coroutine, NULL);
-    qemu_coroutine_enter(coroutine);
+    coroutine = qemu_coroutine_create(verify_in_coroutine);
+    qemu_coroutine_enter(coroutine, NULL);
 }
 
 /*
@@ -40,16 +41,15 @@ static void test_in_coroutine(void)
 
 static void coroutine_fn verify_self(void *opaque)
 {
-    Coroutine **p_co = opaque;
-    g_assert(qemu_coroutine_self() == *p_co);
+    g_assert(qemu_coroutine_self() == opaque);
 }
 
 static void test_self(void)
 {
     Coroutine *coroutine;
 
-    coroutine = qemu_coroutine_create(verify_self, &coroutine);
-    qemu_coroutine_enter(coroutine);
+    coroutine = qemu_coroutine_create(verify_self);
+    qemu_coroutine_enter(coroutine, coroutine);
 }
 
 /*
@@ -71,8 +71,8 @@ static void coroutine_fn nest(void *opaque)
     if (nd->n_enter < nd->max) {
         Coroutine *child;
 
-        child = qemu_coroutine_create(nest, nd);
-        qemu_coroutine_enter(child);
+        child = qemu_coroutine_create(nest);
+        qemu_coroutine_enter(child, nd);
     }
 
     nd->n_return++;
@@ -87,8 +87,8 @@ static void test_nesting(void)
         .max      = 128,
     };
 
-    root = qemu_coroutine_create(nest, &nd);
-    qemu_coroutine_enter(root);
+    root = qemu_coroutine_create(nest);
+    qemu_coroutine_enter(root, &nd);
 
     /* Must enter and return from max nesting level */
     g_assert_cmpint(nd.n_enter, ==, nd.max);
@@ -116,9 +116,9 @@ static void test_yield(void)
     bool done = false;
     int i = -1; /* one extra time to return from coroutine */
 
-    coroutine = qemu_coroutine_create(yield_5_times, &done);
+    coroutine = qemu_coroutine_create(yield_5_times);
     while (!done) {
-        qemu_coroutine_enter(coroutine);
+        qemu_coroutine_enter(coroutine, &done);
         i++;
     }
     g_assert_cmpint(i, ==, 5); /* coroutine must yield 5 times */
@@ -132,7 +132,7 @@ static void coroutine_fn c2_fn(void *opaque)
 static void coroutine_fn c1_fn(void *opaque)
 {
     Coroutine *c2 = opaque;
-    qemu_coroutine_enter(c2);
+    qemu_coroutine_enter(c2, NULL);
 }
 
 static void test_co_queue(void)
@@ -140,12 +140,12 @@ static void test_co_queue(void)
     Coroutine *c1;
     Coroutine *c2;
 
-    c2 = qemu_coroutine_create(c2_fn, NULL);
-    c1 = qemu_coroutine_create(c1_fn, c2);
+    c1 = qemu_coroutine_create(c1_fn);
+    c2 = qemu_coroutine_create(c2_fn);
 
-    qemu_coroutine_enter(c1);
+    qemu_coroutine_enter(c1, c2);
     memset(c1, 0xff, sizeof(Coroutine));
-    qemu_coroutine_enter(c2);
+    qemu_coroutine_enter(c2, NULL);
 }
 
 /*
@@ -165,14 +165,14 @@ static void test_lifecycle(void)
     bool done = false;
 
     /* Create, enter, and return from coroutine */
-    coroutine = qemu_coroutine_create(set_and_exit, &done);
-    qemu_coroutine_enter(coroutine);
+    coroutine = qemu_coroutine_create(set_and_exit);
+    qemu_coroutine_enter(coroutine, &done);
     g_assert(done); /* expect done to be true (first time) */
 
     /* Repeat to check that no state affects this test */
     done = false;
-    coroutine = qemu_coroutine_create(set_and_exit, &done);
-    qemu_coroutine_enter(coroutine);
+    coroutine = qemu_coroutine_create(set_and_exit);
+    qemu_coroutine_enter(coroutine, &done);
     g_assert(done); /* expect done to be true (second time) */
 }
 
@@ -206,12 +206,12 @@ static void do_order_test(void)
 {
     Coroutine *co;
 
-    co = qemu_coroutine_create(co_order_test, NULL);
+    co = qemu_coroutine_create(co_order_test);
     record_push(1, 1);
-    qemu_coroutine_enter(co);
+    qemu_coroutine_enter(co, NULL);
     record_push(1, 2);
     g_assert(!qemu_in_coroutine());
-    qemu_coroutine_enter(co);
+    qemu_coroutine_enter(co, NULL);
     record_push(1, 3);
     g_assert(!qemu_in_coroutine());
 }
@@ -248,8 +248,8 @@ static void perf_lifecycle(void)
 
     g_test_timer_start();
     for (i = 0; i < max; i++) {
-        coroutine = qemu_coroutine_create(empty_coroutine, NULL);
-        qemu_coroutine_enter(coroutine);
+        coroutine = qemu_coroutine_create(empty_coroutine);
+        qemu_coroutine_enter(coroutine, NULL);
     }
     duration = g_test_timer_elapsed();
 
@@ -272,8 +272,8 @@ static void perf_nesting(void)
             .n_return = 0,
             .max      = maxnesting,
         };
-        root = qemu_coroutine_create(nest, &nd);
-        qemu_coroutine_enter(root);
+        root = qemu_coroutine_create(nest);
+        qemu_coroutine_enter(root, &nd);
     }
     duration = g_test_timer_elapsed();
 
@@ -302,11 +302,11 @@ static void perf_yield(void)
 
     maxcycles = 100000000;
     i = maxcycles;
-    Coroutine *coroutine = qemu_coroutine_create(yield_loop, &i);
+    Coroutine *coroutine = qemu_coroutine_create(yield_loop);
 
     g_test_timer_start();
     while (i > 0) {
-        qemu_coroutine_enter(coroutine);
+        qemu_coroutine_enter(coroutine, &i);
     }
     duration = g_test_timer_elapsed();
 
@@ -352,9 +352,9 @@ static void perf_cost(void)
 
     g_test_timer_start();
     while (i++ < maxcycles) {
-        co = qemu_coroutine_create(perf_cost_func, &i);
-        qemu_coroutine_enter(co);
-        qemu_coroutine_enter(co);
+        co = qemu_coroutine_create(perf_cost_func);
+        qemu_coroutine_enter(co, &i);
+        qemu_coroutine_enter(co, NULL);
     }
     duration = g_test_timer_elapsed();
     ops = (long)(maxcycles / (duration * 1000));
@@ -369,15 +369,7 @@ static void perf_cost(void)
 int main(int argc, char **argv)
 {
     g_test_init(&argc, &argv, NULL);
-
-    /* This test assumes there is a freelist and marks freed coroutine memory
-     * with a sentinel value.  If there is no freelist this would legitimately
-     * crash, so skip it.
-     */
-    if (CONFIG_COROUTINE_POOL) {
-        g_test_add_func("/basic/co_queue", test_co_queue);
-    }
-
+    g_test_add_func("/basic/co_queue", test_co_queue);
     g_test_add_func("/basic/lifecycle", test_lifecycle);
     g_test_add_func("/basic/yield", test_yield);
     g_test_add_func("/basic/nesting", test_nesting);
index 1b5130d..66d1c63 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "crypto/init.h"
 #include "crypto/cipher.h"
index 42fc77a..735d6d7 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "crypto/init.h"
 #include "crypto/hash.h"
 
 #define OUTPUT_MD5 "628d206371563035ab8ef62f492bdec9"
 #define OUTPUT_SHA1 "b2e74f26758a3a421e509cee045244b78753cc02"
-#define OUTPUT_SHA224 "e2f7415aad33ef79f6516b0986d7175f" \
-                      "9ca3389a85bf6cfed078737b"
 #define OUTPUT_SHA256 "bc757abb0436586f392b437e5dd24096" \
                       "f7f224de6b74d4d86e2abc6121b160d0"
-#define OUTPUT_SHA384 "887ce52efb4f46700376356583b7e279" \
-                      "4f612bd024e4495087ddb946c448c69d" \
-                      "56dbf7152a94a5e63a80f3ba9f0eed78"
-#define OUTPUT_SHA512 "3a90d79638235ec6c4c11bebd84d83c0" \
-                      "549bc1e84edc4b6ec7086487641256cb" \
-                      "63b54e4cb2d2032b393994aa263c0dbb" \
-                      "e00a9f2fe9ef6037352232a1eec55ee7"
-#define OUTPUT_RIPEMD160 "f3d658fad3fdfb2b52c9369cf0d441249ddfa8a0"
 
 #define OUTPUT_MD5_B64 "Yo0gY3FWMDWrjvYvSSveyQ=="
 #define OUTPUT_SHA1_B64 "sudPJnWKOkIeUJzuBFJEt4dTzAI="
-#define OUTPUT_SHA224_B64 "4vdBWq0z73n2UWsJhtcXX5yjOJqFv2z+0Hhzew=="
 #define OUTPUT_SHA256_B64 "vHV6uwQ2WG85K0N+XdJAlvfyJN5rdNTYbiq8YSGxYNA="
-#define OUTPUT_SHA384_B64 "iHzlLvtPRnADdjVlg7fieU9hK9Ak5ElQh925RsRI" \
-                          "xp1W2/cVKpSl5jqA87qfDu14"
-#define OUTPUT_SHA512_B64 "OpDXljgjXsbEwRvr2E2DwFSbwehO3Etuxwhkh2QS" \
-                          "VstjtU5MstIDKzk5lKomPA274AqfL+nvYDc1IjKh" \
-                          "7sVe5w=="
-#define OUTPUT_RIPEMD160_B64 "89ZY+tP9+ytSyTac8NRBJJ3fqKA="
 
 static const char *expected_outputs[] = {
     [QCRYPTO_HASH_ALG_MD5] = OUTPUT_MD5,
     [QCRYPTO_HASH_ALG_SHA1] = OUTPUT_SHA1,
-    [QCRYPTO_HASH_ALG_SHA224] = OUTPUT_SHA224,
     [QCRYPTO_HASH_ALG_SHA256] = OUTPUT_SHA256,
-    [QCRYPTO_HASH_ALG_SHA384] = OUTPUT_SHA384,
-    [QCRYPTO_HASH_ALG_SHA512] = OUTPUT_SHA512,
-    [QCRYPTO_HASH_ALG_RIPEMD160] = OUTPUT_RIPEMD160,
 };
 static const char *expected_outputs_b64[] = {
     [QCRYPTO_HASH_ALG_MD5] = OUTPUT_MD5_B64,
     [QCRYPTO_HASH_ALG_SHA1] = OUTPUT_SHA1_B64,
-    [QCRYPTO_HASH_ALG_SHA224] = OUTPUT_SHA224_B64,
     [QCRYPTO_HASH_ALG_SHA256] = OUTPUT_SHA256_B64,
-    [QCRYPTO_HASH_ALG_SHA384] = OUTPUT_SHA384_B64,
-    [QCRYPTO_HASH_ALG_SHA512] = OUTPUT_SHA512_B64,
-    [QCRYPTO_HASH_ALG_RIPEMD160] = OUTPUT_RIPEMD160_B64,
 };
 static const int expected_lens[] = {
     [QCRYPTO_HASH_ALG_MD5] = 16,
     [QCRYPTO_HASH_ALG_SHA1] = 20,
-    [QCRYPTO_HASH_ALG_SHA224] = 28,
     [QCRYPTO_HASH_ALG_SHA256] = 32,
-    [QCRYPTO_HASH_ALG_SHA384] = 48,
-    [QCRYPTO_HASH_ALG_SHA512] = 64,
-    [QCRYPTO_HASH_ALG_RIPEMD160] = 20,
 };
 
 static const char hex[] = "0123456789abcdef";
@@ -97,10 +69,6 @@ static void test_hash_alloc(void)
         int ret;
         size_t j;
 
-        if (!qcrypto_hash_supports(i)) {
-            continue;
-        }
-
         ret = qcrypto_hash_bytes(i,
                                  INPUT_TEXT,
                                  strlen(INPUT_TEXT),
@@ -131,10 +99,6 @@ static void test_hash_prealloc(void)
         int ret;
         size_t j;
 
-        if (!qcrypto_hash_supports(i)) {
-            continue;
-        }
-
         resultlen = expected_lens[i];
         result = g_new0(uint8_t, resultlen);
 
@@ -174,10 +138,6 @@ static void test_hash_iov(void)
         int ret;
         size_t j;
 
-        if (!qcrypto_hash_supports(i)) {
-            continue;
-        }
-
         ret = qcrypto_hash_bytesv(i,
                                   iov, 3,
                                   &result,
@@ -206,10 +166,6 @@ static void test_hash_digest(void)
         char *digest;
         size_t digestsize;
 
-        if (!qcrypto_hash_supports(i)) {
-            continue;
-        }
-
         digestsize = qcrypto_hash_digest_len(i);
 
         g_assert_cmpint(digestsize * 2, ==, strlen(expected_outputs[i]));
@@ -220,7 +176,7 @@ static void test_hash_digest(void)
                                   &digest,
                                   NULL);
         g_assert(ret == 0);
-        g_assert_cmpstr(digest, ==, expected_outputs[i]);
+        g_assert(g_str_equal(digest, expected_outputs[i]));
         g_free(digest);
     }
 }
@@ -236,17 +192,13 @@ static void test_hash_base64(void)
         int ret;
         char *digest;
 
-        if (!qcrypto_hash_supports(i)) {
-            continue;
-        }
-
         ret = qcrypto_hash_base64(i,
                                   INPUT_TEXT,
                                   strlen(INPUT_TEXT),
                                   &digest,
                                   NULL);
         g_assert(ret == 0);
-        g_assert_cmpstr(digest, ==, expected_outputs_b64[i]);
+        g_assert(g_str_equal(digest, expected_outputs_b64[i]));
         g_free(digest);
     }
 }
index 13fc6c4..aa26c20 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "crypto/init.h"
 #include "crypto/secret.h"
@@ -49,7 +50,7 @@ static void test_secret_indirect_good(void)
 {
     Object *sec;
     char *fname = NULL;
-    int fd = g_file_open_tmp("qemu-test-crypto-secret-XXXXXX",
+    int fd = g_file_open_tmp("secretXXXXXX",
                              &fname,
                              NULL);
 
@@ -74,7 +75,6 @@ static void test_secret_indirect_good(void)
     object_unparent(sec);
     g_free(pw);
     close(fd);
-    unlink(fname);
     g_free(fname);
 }
 
@@ -97,7 +97,7 @@ static void test_secret_indirect_emptyfile(void)
 {
     Object *sec;
     char *fname = NULL;
-    int fd = g_file_open_tmp("qemu-test-crypto-secretXXXXXX",
+    int fd = g_file_open_tmp("secretXXXXXX",
                              &fname,
                              NULL);
 
@@ -120,7 +120,6 @@ static void test_secret_indirect_emptyfile(void)
     object_unparent(sec);
     g_free(pw);
     close(fd);
-    unlink(fname);
     g_free(fname);
 }
 
index 1f1412c..7f68b06 100644 (file)
@@ -340,7 +340,7 @@ static void test_xts_aes_decrypt(const void *ctx,
 static void test_xts(const void *opaque)
 {
     const QCryptoXTSTestData *data = opaque;
-    unsigned char out[512], Torg[16], T[16];
+    unsigned char OUT[512], Torg[16], T[16];
     uint64_t seq;
     int j;
     unsigned long len;
@@ -371,38 +371,38 @@ static void test_xts(const void *opaque)
             xts_encrypt(&aesdata, &aestweak,
                         test_xts_aes_encrypt,
                         test_xts_aes_decrypt,
-                        T, data->PTLEN, out, data->PTX);
+                        T, data->PTLEN, OUT, data->PTX);
         } else {
             xts_encrypt(&aesdata, &aestweak,
                         test_xts_aes_encrypt,
                         test_xts_aes_decrypt,
-                        T, len, out, data->PTX);
+                        T, len, OUT, data->PTX);
             xts_encrypt(&aesdata, &aestweak,
                         test_xts_aes_encrypt,
                         test_xts_aes_decrypt,
-                        T, len, &out[len], &data->PTX[len]);
+                        T, len, &OUT[len], &data->PTX[len]);
         }
 
-        g_assert(memcmp(out, data->CTX, data->PTLEN) == 0);
+        g_assert(memcmp(OUT, data->CTX, data->PTLEN) == 0);
 
         memcpy(T, Torg, sizeof(T));
         if (j == 0) {
             xts_decrypt(&aesdata, &aestweak,
                         test_xts_aes_encrypt,
                         test_xts_aes_decrypt,
-                        T, data->PTLEN, out, data->CTX);
+                        T, data->PTLEN, OUT, data->CTX);
         } else {
             xts_decrypt(&aesdata, &aestweak,
                         test_xts_aes_encrypt,
                         test_xts_aes_decrypt,
-                        T, len, out, data->CTX);
+                        T, len, OUT, data->CTX);
             xts_decrypt(&aesdata, &aestweak,
                         test_xts_aes_encrypt,
                         test_xts_aes_decrypt,
-                        T, len, &out[len], &data->CTX[len]);
+                        T, len, &OUT[len], &data->CTX[len]);
         }
 
-        g_assert(memcmp(out, data->PTX, data->PTLEN) == 0);
+        g_assert(memcmp(OUT, data->PTX, data->PTLEN) == 0);
     }
 }
 
index 64e3e95..fb8f5b5 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu/cutils.h"
 
index ffaaffa..f60bf2a 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "qemu/iov.h"
 #include "qemu/sockets.h"
index c63b68f..b93012c 100644 (file)
@@ -51,6 +51,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "qemu/iov.h"
 #include "qemu/sockets.h"
@@ -209,8 +210,12 @@ static void test_redirector_rx(void)
 
 int main(int argc, char **argv)
 {
+    int ret;
+
     g_test_init(&argc, &argv, NULL);
     qtest_add_func("/netfilter/redirector_tx", test_redirector_tx);
     qtest_add_func("/netfilter/redirector_rx", test_redirector_rx);
-    return g_test_run();
+    ret = g_test_run();
+
+    return ret;
 }
index c0e9895..abe1427 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu/hbitmap.h"
 
 #define LOG_BITS_PER_LONG          (BITS_PER_LONG == 32 ? 5 : 6)
@@ -79,7 +80,7 @@ static void hbitmap_test_init(TestHBitmapData *data,
     size_t n;
     data->hb = hbitmap_alloc(size, granularity);
 
-    n = DIV_ROUND_UP(size, BITS_PER_LONG);
+    n = (size + BITS_PER_LONG - 1) / BITS_PER_LONG;
     if (n == 0) {
         n = 1;
     }
@@ -93,7 +94,7 @@ static void hbitmap_test_init(TestHBitmapData *data,
 
 static inline size_t hbitmap_test_array_size(size_t bits)
 {
-    size_t n = DIV_ROUND_UP(bits, BITS_PER_LONG);
+    size_t n = (bits + BITS_PER_LONG - 1) / BITS_PER_LONG;
     return n ? n : 1;
 }
 
@@ -185,7 +186,7 @@ static void hbitmap_test_reset_all(TestHBitmapData *data)
 
     hbitmap_reset_all(data->hb);
 
-    n = DIV_ROUND_UP(data->size, BITS_PER_LONG);
+    n = (data->size + BITS_PER_LONG - 1) / BITS_PER_LONG;
     if (n == 0) {
         n = 1;
     }
index 4390123..cacf6be 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu/int128.h"
 
 /* clang doesn't support __noclone__ but it does have a mechanism for
index f73e063..855306b 100644 (file)
@@ -383,7 +383,7 @@ static void test_io_channel_unix(bool async)
 
     qapi_free_SocketAddress(listen_addr);
     qapi_free_SocketAddress(connect_addr);
-    g_assert(g_file_test(TEST_SOCKET, G_FILE_TEST_EXISTS) == FALSE);
+    unlink(TEST_SOCKET);
 }
 
 
index e091c12..5a97750 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "io/task.h"
 #include "qapi/error.h"
@@ -110,7 +111,7 @@ static void test_task_data_free(void)
 }
 
 
-static void test_task_failure(void)
+static void test_task_error(void)
 {
     QIOTask *task;
     Object *obj = object_new(TYPE_DUMMY);
@@ -214,7 +215,7 @@ static void test_task_thread_complete(void)
 }
 
 
-static void test_task_thread_failure(void)
+static void test_task_thread_error(void)
 {
     QIOTask *task;
     Object *obj = object_new(TYPE_DUMMY);
@@ -262,8 +263,8 @@ int main(int argc, char **argv)
     type_register_static(&dummy_info);
     g_test_add_func("/crypto/task/complete", test_task_complete);
     g_test_add_func("/crypto/task/datafree", test_task_data_free);
-    g_test_add_func("/crypto/task/failure", test_task_failure);
+    g_test_add_func("/crypto/task/error", test_task_error);
     g_test_add_func("/crypto/task/thread_complete", test_task_thread_complete);
-    g_test_add_func("/crypto/task/thread_failure", test_task_thread_failure);
+    g_test_add_func("/crypto/task/thread_error", test_task_thread_error);
     return g_test_run();
 }
index 46ae25e..3f25268 100644 (file)
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu-common.h"
 #include "qemu/iov.h"
 #include "qemu/sockets.h"
index a12585f..ac8deed 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include <glib/gstdio.h>
+#include <glib.h>
 
 #include "qemu-common.h"
-#include "qapi/error.h"
-#include "qemu/log.h"
+#include "include/qemu/log.h"
 
 static void test_parse_range(void)
 {
-    Error *err = NULL;
-
-    qemu_set_dfilter_ranges("0x1000+0x100", &error_abort);
+    qemu_set_dfilter_ranges("0x1000+0x100");
 
     g_assert_false(qemu_log_in_addr_range(0xfff));
     g_assert(qemu_log_in_addr_range(0x1000));
@@ -43,101 +40,102 @@ static void test_parse_range(void)
     g_assert(qemu_log_in_addr_range(0x10ff));
     g_assert_false(qemu_log_in_addr_range(0x1100));
 
-    qemu_set_dfilter_ranges("0x1000-0x100", &error_abort);
+    qemu_set_dfilter_ranges("0x1000-0x100");
 
     g_assert_false(qemu_log_in_addr_range(0x1001));
     g_assert(qemu_log_in_addr_range(0x1000));
     g_assert(qemu_log_in_addr_range(0x0f01));
     g_assert_false(qemu_log_in_addr_range(0x0f00));
 
-    qemu_set_dfilter_ranges("0x1000..0x1100", &error_abort);
+    qemu_set_dfilter_ranges("0x1000..0x1100");
 
     g_assert_false(qemu_log_in_addr_range(0xfff));
     g_assert(qemu_log_in_addr_range(0x1000));
     g_assert(qemu_log_in_addr_range(0x1100));
     g_assert_false(qemu_log_in_addr_range(0x1101));
 
-    qemu_set_dfilter_ranges("0x1000..0x1000", &error_abort);
+    qemu_set_dfilter_ranges("0x1000..0x1000");
 
     g_assert_false(qemu_log_in_addr_range(0xfff));
     g_assert(qemu_log_in_addr_range(0x1000));
     g_assert_false(qemu_log_in_addr_range(0x1001));
 
-    qemu_set_dfilter_ranges("0x1000+0x100,0x2100-0x100,0x3000..0x3100",
-                            &error_abort);
+    qemu_set_dfilter_ranges("0x1000+0x100,0x2100-0x100,0x3000..0x3100");
     g_assert(qemu_log_in_addr_range(0x1050));
     g_assert(qemu_log_in_addr_range(0x2050));
     g_assert(qemu_log_in_addr_range(0x3050));
-
-    qemu_set_dfilter_ranges("0xffffffffffffffff-1", &error_abort);
-    g_assert(qemu_log_in_addr_range(UINT64_MAX));
-    g_assert_false(qemu_log_in_addr_range(UINT64_MAX - 1));
-
-    qemu_set_dfilter_ranges("0..0xffffffffffffffff", &err);
-    g_assert(qemu_log_in_addr_range(0));
-    g_assert(qemu_log_in_addr_range(UINT64_MAX));
-    qemu_set_dfilter_ranges("2..1", &err);
-    error_free_or_abort(&err);
-
-    qemu_set_dfilter_ranges("0x1000+onehundred", &err);
-    error_free_or_abort(&err);
-
-    qemu_set_dfilter_ranges("0x1000+0", &err);
-    error_free_or_abort(&err);
 }
 
-static void set_log_path_tmp(char const *dir, char const *tpl, Error **errp)
+#ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS
+static void test_parse_invalid_range_subprocess(void)
 {
-    gchar *file_path = g_build_filename(dir, tpl, NULL);
-
-    qemu_set_log_filename(file_path, errp);
-    g_free(file_path);
+    qemu_set_dfilter_ranges("0x1000+onehundred");
 }
-
-static void test_parse_path(gconstpointer data)
+static void test_parse_invalid_range(void)
 {
-    gchar const *tmp_path = data;
-    Error *err = NULL;
-
-    set_log_path_tmp(tmp_path, "qemu.log", &error_abort);
-    set_log_path_tmp(tmp_path, "qemu-%d.log", &error_abort);
-    set_log_path_tmp(tmp_path, "qemu.log.%d", &error_abort);
-
-    set_log_path_tmp(tmp_path, "qemu-%d%d.log", &err);
-    error_free_or_abort(&err);
+    g_test_trap_subprocess("/logging/parse_invalid_range/subprocess", 0, 0);
+    g_test_trap_assert_failed();
+    g_test_trap_assert_stdout("");
+    g_test_trap_assert_stderr("*Failed to parse range in: 0x1000+onehundred\n");
+}
+static void test_parse_zero_range_subprocess(void)
+{
+    qemu_set_dfilter_ranges("0x1000+0");
+}
+static void test_parse_zero_range(void)
+{
+    g_test_trap_subprocess("/logging/parse_zero_range/subprocess", 0, 0);
+    g_test_trap_assert_failed();
+    g_test_trap_assert_stdout("");
+    g_test_trap_assert_stderr("*Failed to parse range in: 0x1000+0\n");
 }
 
-/* Remove a directory and all its entries (non-recursive). */
-static void rmdir_full(gchar const *root)
+/* As the only real failure from a bad log filename path spec is
+ * reporting to the user we have to use the g_test_trap_subprocess
+ * mechanism and check no errors reported on stderr.
+ */
+static void test_parse_path_subprocess(void)
+{
+    /* All these should work without issue */
+    qemu_set_log_filename("/tmp/qemu.log");
+    qemu_set_log_filename("/tmp/qemu-%d.log");
+    qemu_set_log_filename("/tmp/qemu.log.%d");
+}
+static void test_parse_path(void)
+{
+    g_test_trap_subprocess ("/logging/parse_path/subprocess", 0, 0);
+    g_test_trap_assert_passed();
+    g_test_trap_assert_stdout("");
+    g_test_trap_assert_stderr("");
+}
+static void test_parse_invalid_path_subprocess(void)
 {
-    GDir *root_gdir = g_dir_open(root, 0, NULL);
-    gchar const *entry_name;
-
-    g_assert_nonnull(root_gdir);
-    while ((entry_name = g_dir_read_name(root_gdir)) != NULL) {
-        gchar *entry_path = g_build_filename(root, entry_name, NULL);
-        g_assert(g_remove(entry_path) == 0);
-        g_free(entry_path);
-    }
-    g_dir_close(root_gdir);
-    g_assert(g_rmdir(root) == 0);
+    qemu_set_log_filename("/tmp/qemu-%d%d.log");
 }
+static void test_parse_invalid_path(void)
+{
+    g_test_trap_subprocess ("/logging/parse_invalid_path/subprocess", 0, 0);
+    g_test_trap_assert_passed();
+    g_test_trap_assert_stdout("");
+    g_test_trap_assert_stderr("Bad logfile format: /tmp/qemu-%d%d.log\n");
+}
+#endif /* CONFIG_HAS_GLIB_SUBPROCESS_TESTS */
 
 int main(int argc, char **argv)
 {
-    gchar *tmp_path = g_dir_make_tmp("qemu-test-logging.XXXXXX", NULL);
-    int rc;
-
     g_test_init(&argc, &argv, NULL);
-    g_assert_nonnull(tmp_path);
 
     g_test_add_func("/logging/parse_range", test_parse_range);
-    g_test_add_data_func("/logging/parse_path", tmp_path, test_parse_path);
-
-    rc = g_test_run();
-
-    rmdir_full(tmp_path);
-    g_free(tmp_path);
-    return rc;
+#ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS
+    g_test_add_func("/logging/parse_invalid_range/subprocess", test_parse_invalid_range_subprocess);
+    g_test_add_func("/logging/parse_invalid_range", test_parse_invalid_range);
+    g_test_add_func("/logging/parse_zero_range/subprocess", test_parse_zero_range_subprocess);
+    g_test_add_func("/logging/parse_zero_range", test_parse_zero_range);
+    g_test_add_func("/logging/parse_path", test_parse_path);
+    g_test_add_func("/logging/parse_path/subprocess", test_parse_path_subprocess);
+    g_test_add_func("/logging/parse_invalid_path", test_parse_invalid_path);
+    g_test_add_func("/logging/parse_invalid_path/subprocess", test_parse_invalid_path_subprocess);
+#endif
+
+    return g_test_run();
 }
index 9be775d..1282ec5 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu/host-utils.h"
 
 
index 8b5a9b2..7d105c3 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* add a netfilter to a netdev and then remove it */
index 0a9e75f..008e677 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu/config-file.h"     /* qemu_add_opts() */
 #include "qemu/option.h"          /* qemu_opts_parse() */
@@ -37,15 +38,16 @@ setup_fixture(OptsVisitorFixture *f, gconstpointer test_data)
 {
     const char *opts_string = test_data;
     QemuOpts *opts;
-    Visitor *v;
+    OptsVisitor *ov;
 
     opts = qemu_opts_parse(qemu_find_opts("userdef"), opts_string, false,
                            NULL);
     g_assert(opts != NULL);
 
-    v = opts_visitor_new(opts);
-    visit_type_UserDefOptions(v, NULL, &f->userdef, &f->err);
-    visit_free(v);
+    ov = opts_visitor_new(opts);
+    visit_type_UserDefOptions(opts_get_visitor(ov), NULL, &f->userdef,
+                              &f->err);
+    opts_visitor_cleanup(ov);
     qemu_opts_del(opts);
 }
 
index 48e5b73..f0cc31e 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "hw/qdev.h"
 #include "qom/object.h"
diff --git a/tests/test-qdist.c b/tests/test-qdist.c
deleted file mode 100644 (file)
index 9541ce3..0000000
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (C) 2016, Emilio G. Cota <cota@braap.org>
- *
- * License: GNU GPL, version 2 or later.
- *   See the COPYING file in the top-level directory.
- */
-#include "qemu/osdep.h"
-#include "qemu/qdist.h"
-
-#include <math.h>
-
-struct entry_desc {
-    double x;
-    unsigned long count;
-
-    /* 0 prints a space, 1-8 prints from qdist_blocks[] */
-    int fill_code;
-};
-
-/* See: https://en.wikipedia.org/wiki/Block_Elements */
-static const gunichar qdist_blocks[] = {
-    0x2581,
-    0x2582,
-    0x2583,
-    0x2584,
-    0x2585,
-    0x2586,
-    0x2587,
-    0x2588
-};
-
-#define QDIST_NR_BLOCK_CODES ARRAY_SIZE(qdist_blocks)
-
-static char *pr_hist(const struct entry_desc *darr, size_t n)
-{
-    GString *s = g_string_new("");
-    size_t i;
-
-    for (i = 0; i < n; i++) {
-        int fill = darr[i].fill_code;
-
-        if (fill) {
-            assert(fill <= QDIST_NR_BLOCK_CODES);
-            g_string_append_unichar(s, qdist_blocks[fill - 1]);
-        } else {
-            g_string_append_c(s, ' ');
-        }
-    }
-    return g_string_free(s, FALSE);
-}
-
-static void
-histogram_check(const struct qdist *dist, const struct entry_desc *darr,
-                size_t n, size_t n_bins)
-{
-    char *pr = qdist_pr_plain(dist, n_bins);
-    char *str = pr_hist(darr, n);
-
-    g_assert_cmpstr(pr, ==, str);
-    g_free(pr);
-    g_free(str);
-}
-
-static void histogram_check_single_full(const struct qdist *dist, size_t n_bins)
-{
-    struct entry_desc desc = { .fill_code = 8 };
-
-    histogram_check(dist, &desc, 1, n_bins);
-}
-
-static void
-entries_check(const struct qdist *dist, const struct entry_desc *darr, size_t n)
-{
-    size_t i;
-
-    for (i = 0; i < n; i++) {
-        struct qdist_entry *e = &dist->entries[i];
-
-        g_assert_cmpuint(e->count, ==, darr[i].count);
-    }
-}
-
-static void
-entries_insert(struct qdist *dist, const struct entry_desc *darr, size_t n)
-{
-    size_t i;
-
-    for (i = 0; i < n; i++) {
-        qdist_add(dist, darr[i].x, darr[i].count);
-    }
-}
-
-static void do_test_bin(const struct entry_desc *a, size_t n_a,
-                        const struct entry_desc *b, size_t n_b)
-{
-    struct qdist qda;
-    struct qdist qdb;
-
-    qdist_init(&qda);
-
-    entries_insert(&qda, a, n_a);
-    qdist_inc(&qda, a[0].x);
-    qdist_add(&qda, a[0].x, -1);
-
-    g_assert_cmpuint(qdist_unique_entries(&qda), ==, n_a);
-    g_assert_cmpfloat(qdist_xmin(&qda), ==, a[0].x);
-    g_assert_cmpfloat(qdist_xmax(&qda), ==, a[n_a - 1].x);
-    histogram_check(&qda, a, n_a, 0);
-    histogram_check(&qda, a, n_a, n_a);
-
-    qdist_bin__internal(&qdb, &qda, n_b);
-    g_assert_cmpuint(qdb.n, ==, n_b);
-    entries_check(&qdb, b, n_b);
-    g_assert_cmpuint(qdist_sample_count(&qda), ==, qdist_sample_count(&qdb));
-    /*
-     * No histogram_check() for $qdb, since we'd rebin it and that is a bug.
-     * Instead, regenerate it from $qda.
-     */
-    histogram_check(&qda, b, n_b, n_b);
-
-    qdist_destroy(&qdb);
-    qdist_destroy(&qda);
-}
-
-static void do_test_pr(uint32_t opt)
-{
-    static const struct entry_desc desc[] = {
-        [0] = { 1, 900, 8 },
-        [1] = { 2, 1, 1 },
-        [2] = { 3, 2, 1 }
-    };
-    static const char border[] = "|";
-    const char *llabel = NULL;
-    const char *rlabel = NULL;
-    struct qdist dist;
-    GString *s;
-    char *str;
-    char *pr;
-    size_t n;
-
-    n = ARRAY_SIZE(desc);
-    qdist_init(&dist);
-
-    entries_insert(&dist, desc, n);
-    histogram_check(&dist, desc, n, 0);
-
-    s = g_string_new("");
-
-    if (opt & QDIST_PR_LABELS) {
-        unsigned int lopts = opt & (QDIST_PR_NODECIMAL |
-                                    QDIST_PR_PERCENT |
-                                    QDIST_PR_100X |
-                                    QDIST_PR_NOBINRANGE);
-
-        if (lopts == 0) {
-            llabel = "[1.0,1.7)";
-            rlabel = "[2.3,3.0]";
-        } else if (lopts == QDIST_PR_NODECIMAL) {
-            llabel = "[1,2)";
-            rlabel = "[2,3]";
-        } else if (lopts == (QDIST_PR_PERCENT | QDIST_PR_NODECIMAL)) {
-            llabel = "[1,2)%";
-            rlabel = "[2,3]%";
-        } else if (lopts == QDIST_PR_100X) {
-            llabel = "[100.0,166.7)";
-            rlabel = "[233.3,300.0]";
-        } else if (lopts == (QDIST_PR_NOBINRANGE | QDIST_PR_NODECIMAL)) {
-            llabel = "1";
-            rlabel = "3";
-        } else {
-            g_assert_cmpstr("BUG", ==, "This is not meant to be exhaustive");
-        }
-    }
-
-    if (llabel) {
-        g_string_append(s, llabel);
-    }
-    if (opt & QDIST_PR_BORDER) {
-        g_string_append(s, border);
-    }
-
-    str = pr_hist(desc, n);
-    g_string_append(s, str);
-    g_free(str);
-
-    if (opt & QDIST_PR_BORDER) {
-        g_string_append(s, border);
-    }
-    if (rlabel) {
-        g_string_append(s, rlabel);
-    }
-
-    str = g_string_free(s, FALSE);
-    pr = qdist_pr(&dist, n, opt);
-    g_assert_cmpstr(pr, ==, str);
-    g_free(pr);
-    g_free(str);
-
-    qdist_destroy(&dist);
-}
-
-static inline void do_test_pr_label(uint32_t opt)
-{
-    opt |= QDIST_PR_LABELS;
-    do_test_pr(opt);
-}
-
-static void test_pr(void)
-{
-    do_test_pr(0);
-
-    do_test_pr(QDIST_PR_BORDER);
-
-    /* 100X should be ignored because we're not setting LABELS */
-    do_test_pr(QDIST_PR_100X);
-
-    do_test_pr_label(0);
-    do_test_pr_label(QDIST_PR_NODECIMAL);
-    do_test_pr_label(QDIST_PR_PERCENT | QDIST_PR_NODECIMAL);
-    do_test_pr_label(QDIST_PR_100X);
-    do_test_pr_label(QDIST_PR_NOBINRANGE | QDIST_PR_NODECIMAL);
-}
-
-static void test_bin_shrink(void)
-{
-    static const struct entry_desc a[] = {
-        [0] = { 0.0,   42922, 7 },
-        [1] = { 0.25,  47834, 8 },
-        [2] = { 0.50,  26628, 0 },
-        [3] = { 0.625, 597,   4 },
-        [4] = { 0.75,  10298, 1 },
-        [5] = { 0.875, 22,    2 },
-        [6] = { 1.0,   2771,  1 }
-    };
-    static const struct entry_desc b[] = {
-        [0] = { 0.0, 42922, 7 },
-        [1] = { 0.25, 47834, 8 },
-        [2] = { 0.50, 27225, 3 },
-        [3] = { 0.75, 13091, 1 }
-    };
-
-    return do_test_bin(a, ARRAY_SIZE(a), b, ARRAY_SIZE(b));
-}
-
-static void test_bin_expand(void)
-{
-    static const struct entry_desc a[] = {
-        [0] = { 0.0,   11713, 5 },
-        [1] = { 0.25,  20294, 0 },
-        [2] = { 0.50,  17266, 8 },
-        [3] = { 0.625, 1506,  0 },
-        [4] = { 0.75,  10355, 6 },
-        [5] = { 0.833, 2,     1 },
-        [6] = { 0.875, 99,    4 },
-        [7] = { 1.0,   4301,  2 }
-    };
-    static const struct entry_desc b[] = {
-        [0] = { 0.0, 11713, 5 },
-        [1] = { 0.0, 0,     0 },
-        [2] = { 0.0, 20294, 8 },
-        [3] = { 0.0, 0,     0 },
-        [4] = { 0.0, 0,     0 },
-        [5] = { 0.0, 17266, 6 },
-        [6] = { 0.0, 1506,  1 },
-        [7] = { 0.0, 10355, 4 },
-        [8] = { 0.0, 101,   1 },
-        [9] = { 0.0, 4301,  2 }
-    };
-
-    return do_test_bin(a, ARRAY_SIZE(a), b, ARRAY_SIZE(b));
-}
-
-static void test_bin_precision(void)
-{
-    static const struct entry_desc a[] = {
-        [0] = { 0, 213549, 8 },
-        [1] = { 1, 70, 1 },
-    };
-    static const struct entry_desc b[] = {
-        [0] = { 0, 213549, 8 },
-        [1] = { 0, 70, 1 },
-    };
-
-    return do_test_bin(a, ARRAY_SIZE(a), b, ARRAY_SIZE(b));
-}
-
-static void test_bin_simple(void)
-{
-    static const struct entry_desc a[] = {
-        [0] = { 10, 101, 8 },
-        [1] = { 11, 0, 0 },
-        [2] = { 12, 2, 1 }
-    };
-    static const struct entry_desc b[] = {
-        [0] = { 0, 101, 8 },
-        [1] = { 0, 0, 0 },
-        [2] = { 0, 0, 0 },
-        [3] = { 0, 0, 0 },
-        [4] = { 0, 2, 1 }
-    };
-
-    return do_test_bin(a, ARRAY_SIZE(a), b, ARRAY_SIZE(b));
-}
-
-static void test_single_full(void)
-{
-    struct qdist dist;
-
-    qdist_init(&dist);
-
-    qdist_add(&dist, 3, 102);
-    g_assert_cmpfloat(qdist_avg(&dist), ==, 3);
-    g_assert_cmpfloat(qdist_xmin(&dist), ==, 3);
-    g_assert_cmpfloat(qdist_xmax(&dist), ==, 3);
-
-    histogram_check_single_full(&dist, 0);
-    histogram_check_single_full(&dist, 1);
-    histogram_check_single_full(&dist, 10);
-
-    qdist_destroy(&dist);
-}
-
-static void test_single_empty(void)
-{
-    struct qdist dist;
-    char *pr;
-
-    qdist_init(&dist);
-
-    qdist_add(&dist, 3, 0);
-    g_assert_cmpuint(qdist_sample_count(&dist), ==, 0);
-    g_assert(isnan(qdist_avg(&dist)));
-    g_assert_cmpfloat(qdist_xmin(&dist), ==, 3);
-    g_assert_cmpfloat(qdist_xmax(&dist), ==, 3);
-
-    pr = qdist_pr_plain(&dist, 0);
-    g_assert_cmpstr(pr, ==, " ");
-    g_free(pr);
-
-    pr = qdist_pr_plain(&dist, 1);
-    g_assert_cmpstr(pr, ==, " ");
-    g_free(pr);
-
-    pr = qdist_pr_plain(&dist, 2);
-    g_assert_cmpstr(pr, ==, " ");
-    g_free(pr);
-
-    qdist_destroy(&dist);
-}
-
-static void test_none(void)
-{
-    struct qdist dist;
-    char *pr;
-
-    qdist_init(&dist);
-
-    g_assert(isnan(qdist_avg(&dist)));
-    g_assert(isnan(qdist_xmin(&dist)));
-    g_assert(isnan(qdist_xmax(&dist)));
-
-    pr = qdist_pr_plain(&dist, 0);
-    g_assert_cmpstr(pr, ==, "(empty)");
-    g_free(pr);
-
-    pr = qdist_pr_plain(&dist, 2);
-    g_assert_cmpstr(pr, ==, "(empty)");
-    g_free(pr);
-
-    pr = qdist_pr(&dist, 0, QDIST_PR_BORDER);
-    g_assert_cmpstr(pr, ==, "(empty)");
-    g_free(pr);
-
-    qdist_destroy(&dist);
-}
-
-int main(int argc, char *argv[])
-{
-    g_test_init(&argc, &argv, NULL);
-    g_test_add_func("/qdist/none", test_none);
-    g_test_add_func("/qdist/single/empty", test_single_empty);
-    g_test_add_func("/qdist/single/full", test_single_full);
-    g_test_add_func("/qdist/binning/simple", test_bin_simple);
-    g_test_add_func("/qdist/binning/precision", test_bin_precision);
-    g_test_add_func("/qdist/binning/expand", test_bin_expand);
-    g_test_add_func("/qdist/binning/shrink", test_bin_shrink);
-    g_test_add_func("/qdist/pr", test_pr);
-    return g_test_run();
-}
index a505a3e..32abed5 100644 (file)
@@ -12,6 +12,7 @@
 #include "qapi/qmp/qstring.h"
 #include "qemu/config-file.h"
 
+#include <glib.h>
 
 static QemuOptsList opts_list_01 = {
     .name = "opts_list_01",
index dac8fb8..72a89de 100644 (file)
@@ -1,5 +1,6 @@
 #include "qemu/osdep.h"
 #include <locale.h>
+#include <glib.h>
 #include <glib/gstdio.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -691,11 +692,28 @@ static void test_qga_blacklist(gconstpointer data)
 static void test_qga_config(gconstpointer data)
 {
     GError *error = NULL;
-    char *cwd, *cmd, *out, *err, *str, **strv, **argv = NULL;
+    char *cwd, *cmd, *out, *err, *str, **strv, *conf, **argv = NULL;
     char *env[2];
-    int status;
+    int status, tmp;
     gsize n;
     GKeyFile *kf;
+    const char *qga_config =
+        "[general]\n"
+        "daemon=false\n"
+        "method=virtio-serial\n"
+        "path=/path/to/org.qemu.guest_agent.0\n"
+        "pidfile=/var/foo/qemu-ga.pid\n"
+        "statedir=/var/state\n"
+        "verbose=true\n"
+        "blacklist=guest-ping;guest-get-time\n";
+
+    tmp = g_file_open_tmp(NULL, &conf, &error);
+    g_assert_no_error(error);
+    g_assert_cmpint(tmp, >=, 0);
+    g_assert_cmpstr(conf, !=, "");
+
+    g_file_set_contents(conf, qga_config, -1, &error);
+    g_assert_no_error(error);
 
     cwd = g_get_current_dir();
     cmd = g_strdup_printf("%s%cqemu-ga -D",
@@ -703,8 +721,7 @@ static void test_qga_config(gconstpointer data)
     g_shell_parse_argv(cmd, NULL, &argv, &error);
     g_assert_no_error(error);
 
-    env[0] = g_strdup_printf("QGA_CONF=tests%cdata%ctest-qga-config",
-                             G_DIR_SEPARATOR, G_DIR_SEPARATOR);
+    env[0] = g_strdup_printf("QGA_CONF=%s", conf);
     env[1] = NULL;
     g_spawn_sync(NULL, argv, env, 0,
                  NULL, NULL, &out, &err, &status, &error);
@@ -759,8 +776,11 @@ static void test_qga_config(gconstpointer data)
 
     g_free(out);
     g_free(err);
+    g_free(conf);
     g_free(env[0]);
     g_key_file_free(kf);
+
+    close(tmp);
 }
 
 static void test_qga_fsfreeze_status(gconstpointer fix)
@@ -803,84 +823,6 @@ static void test_qga_fsfreeze_and_thaw(gconstpointer fix)
     QDECREF(ret);
 }
 
-static void test_qga_guest_exec(gconstpointer fix)
-{
-    const TestFixture *fixture = fix;
-    QDict *ret, *val;
-    const gchar *out;
-    guchar *decoded;
-    int64_t pid, now, exitcode;
-    gsize len;
-    bool exited;
-
-    /* exec 'echo foo bar' */
-    ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
-                 " 'path': '/bin/echo', 'arg': [ '-n', '\" test_str \"' ],"
-                 " 'capture-output': true } }");
-    g_assert_nonnull(ret);
-    qmp_assert_no_error(ret);
-    val = qdict_get_qdict(ret, "return");
-    pid = qdict_get_int(val, "pid");
-    g_assert_cmpint(pid, >, 0);
-    QDECREF(ret);
-
-    /* wait for completion */
-    now = g_get_monotonic_time();
-    do {
-        ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec-status',"
-                     " 'arguments': { 'pid': %" PRId64 "  } }", pid);
-        g_assert_nonnull(ret);
-        val = qdict_get_qdict(ret, "return");
-        exited = qdict_get_bool(val, "exited");
-        if (!exited) {
-            QDECREF(ret);
-        }
-    } while (!exited &&
-             g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND);
-    g_assert(exited);
-
-    /* check stdout */
-    exitcode = qdict_get_int(val, "exitcode");
-    g_assert_cmpint(exitcode, ==, 0);
-    out = qdict_get_str(val, "out-data");
-    decoded = g_base64_decode(out, &len);
-    g_assert_cmpint(len, ==, 12);
-    g_assert_cmpstr((char *)decoded, ==, "\" test_str \"");
-    g_free(decoded);
-    QDECREF(ret);
-}
-
-static void test_qga_guest_exec_invalid(gconstpointer fix)
-{
-    const TestFixture *fixture = fix;
-    QDict *ret, *error;
-    const gchar *class, *desc;
-
-    /* invalid command */
-    ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
-                 " 'path': '/bin/invalid-cmd42' } }");
-    g_assert_nonnull(ret);
-    error = qdict_get_qdict(ret, "error");
-    g_assert_nonnull(error);
-    class = qdict_get_str(error, "class");
-    desc = qdict_get_str(error, "desc");
-    g_assert_cmpstr(class, ==, "GenericError");
-    g_assert_cmpint(strlen(desc), >, 0);
-    QDECREF(ret);
-
-    /* invalid pid */
-    ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec-status',"
-                 " 'arguments': { 'pid': 0 } }");
-    g_assert_nonnull(ret);
-    error = qdict_get_qdict(ret, "error");
-    g_assert_nonnull(error);
-    class = qdict_get_str(error, "class");
-    desc = qdict_get_str(error, "desc");
-    g_assert_cmpstr(class, ==, "GenericError");
-    g_assert_cmpint(strlen(desc), >, 0);
-    QDECREF(ret);
-}
-
 int main(int argc, char **argv)
 {
     TestFixture fix;
@@ -911,9 +853,6 @@ int main(int argc, char **argv)
 
     g_test_add_data_func("/qga/blacklist", NULL, test_qga_blacklist);
     g_test_add_data_func("/qga/config", NULL, test_qga_config);
-    g_test_add_data_func("/qga/guest-exec", &fix, test_qga_guest_exec);
-    g_test_add_data_func("/qga/guest-exec-invalid", &fix,
-                         test_qga_guest_exec_invalid);
 
     if (g_getenv("QGA_TEST_SIDE_EFFECTING")) {
         g_test_add_data_func("/qga/fsfreeze-and-thaw", &fix,
diff --git a/tests/test-qht-par.c b/tests/test-qht-par.c
deleted file mode 100644 (file)
index d8a83ca..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2016, Emilio G. Cota <cota@braap.org>
- *
- * License: GNU GPL, version 2 or later.
- *   See the COPYING file in the top-level directory.
- */
-#include "qemu/osdep.h"
-
-#define TEST_QHT_STRING "tests/qht-bench 1>/dev/null 2>&1 -R -S0.1 -D10000 -N1 "
-
-static void test_qht(int n_threads, int update_rate, int duration)
-{
-    char *str;
-    int rc;
-
-    str = g_strdup_printf(TEST_QHT_STRING "-n %d -u %d -d %d",
-                          n_threads, update_rate, duration);
-    rc = system(str);
-    g_free(str);
-    g_assert_cmpint(rc, ==, 0);
-}
-
-static void test_2th0u1s(void)
-{
-    test_qht(2, 0, 1);
-}
-
-static void test_2th20u1s(void)
-{
-    test_qht(2, 20, 1);
-}
-
-static void test_2th0u5s(void)
-{
-    test_qht(2, 0, 5);
-}
-
-static void test_2th20u5s(void)
-{
-    test_qht(2, 20, 5);
-}
-
-int main(int argc, char *argv[])
-{
-    g_test_init(&argc, &argv, NULL);
-
-    if (g_test_quick()) {
-        g_test_add_func("/qht/parallel/2threads-0%updates-1s", test_2th0u1s);
-        g_test_add_func("/qht/parallel/2threads-20%updates-1s", test_2th20u1s);
-    } else {
-        g_test_add_func("/qht/parallel/2threads-0%updates-5s", test_2th0u5s);
-        g_test_add_func("/qht/parallel/2threads-20%updates-5s", test_2th20u5s);
-    }
-    return g_test_run();
-}
diff --git a/tests/test-qht.c b/tests/test-qht.c
deleted file mode 100644 (file)
index 46a64b6..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2016, Emilio G. Cota <cota@braap.org>
- *
- * License: GNU GPL, version 2 or later.
- *   See the COPYING file in the top-level directory.
- */
-#include "qemu/osdep.h"
-#include "qemu/qht.h"
-
-#define N 5000
-
-static struct qht ht;
-static int32_t arr[N * 2];
-
-static bool is_equal(const void *obj, const void *userp)
-{
-    const int32_t *a = obj;
-    const int32_t *b = userp;
-
-    return *a == *b;
-}
-
-static void insert(int a, int b)
-{
-    int i;
-
-    for (i = a; i < b; i++) {
-        uint32_t hash;
-
-        arr[i] = i;
-        hash = i;
-
-        qht_insert(&ht, &arr[i], hash);
-    }
-}
-
-static void rm(int init, int end)
-{
-    int i;
-
-    for (i = init; i < end; i++) {
-        uint32_t hash;
-
-        hash = arr[i];
-        g_assert_true(qht_remove(&ht, &arr[i], hash));
-    }
-}
-
-static void check(int a, int b, bool expected)
-{
-    struct qht_stats stats;
-    int i;
-
-    for (i = a; i < b; i++) {
-        void *p;
-        uint32_t hash;
-        int32_t val;
-
-        val = i;
-        hash = i;
-        p = qht_lookup(&ht, is_equal, &val, hash);
-        g_assert_true(!!p == expected);
-    }
-    qht_statistics_init(&ht, &stats);
-    if (stats.used_head_buckets) {
-        g_assert_cmpfloat(qdist_avg(&stats.chain), >=, 1.0);
-    }
-    g_assert_cmpuint(stats.head_buckets, >, 0);
-    qht_statistics_destroy(&stats);
-}
-
-static void count_func(struct qht *ht, void *p, uint32_t hash, void *userp)
-{
-    unsigned int *curr = userp;
-
-    (*curr)++;
-}
-
-static void check_n(size_t expected)
-{
-    struct qht_stats stats;
-
-    qht_statistics_init(&ht, &stats);
-    g_assert_cmpuint(stats.entries, ==, expected);
-    qht_statistics_destroy(&stats);
-}
-
-static void iter_check(unsigned int count)
-{
-    unsigned int curr = 0;
-
-    qht_iter(&ht, count_func, &curr);
-    g_assert_cmpuint(curr, ==, count);
-}
-
-static void qht_do_test(unsigned int mode, size_t init_entries)
-{
-    /* under KVM we might fetch stats from an uninitialized qht */
-    check_n(0);
-
-    qht_init(&ht, 0, mode);
-
-    check_n(0);
-    insert(0, N);
-    check(0, N, true);
-    check_n(N);
-    check(-N, -1, false);
-    iter_check(N);
-
-    rm(101, 102);
-    check_n(N - 1);
-    insert(N, N * 2);
-    check_n(N + N - 1);
-    rm(N, N * 2);
-    check_n(N - 1);
-    insert(101, 102);
-    check_n(N);
-
-    rm(10, 200);
-    check_n(N - 190);
-    insert(150, 200);
-    check_n(N - 190 + 50);
-    insert(10, 150);
-    check_n(N);
-
-    rm(1, 2);
-    check_n(N - 1);
-    qht_reset_size(&ht, 0);
-    check_n(0);
-    check(0, N, false);
-
-    qht_destroy(&ht);
-}
-
-static void qht_test(unsigned int mode)
-{
-    qht_do_test(mode, 0);
-    qht_do_test(mode, 1);
-    qht_do_test(mode, 2);
-    qht_do_test(mode, 8);
-    qht_do_test(mode, 16);
-    qht_do_test(mode, 8192);
-    qht_do_test(mode, 16384);
-}
-
-static void test_default(void)
-{
-    qht_test(0);
-}
-
-static void test_resize(void)
-{
-    qht_test(QHT_MODE_AUTO_RESIZE);
-}
-
-int main(int argc, char *argv[])
-{
-    g_test_init(&argc, &argv, NULL);
-    g_test_add_func("/qht/mode/default", test_default);
-    g_test_add_func("/qht/mode/resize", test_resize);
-    return g_test_run();
-}
index 261fd9e..14a9ebb 100644 (file)
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu-common.h"
 #include "qapi/qmp/types.h"
 #include "test-qmp-commands.h"
@@ -59,14 +60,6 @@ QObject *qmp_guest_sync(QObject *arg, Error **errp)
     return arg;
 }
 
-void qmp_boxed_struct(UserDefZero *arg, Error **errp)
-{
-}
-
-void qmp_boxed_union(UserDefNativeListUnion *arg, Error **errp)
-{
-}
-
 __org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,
                                               __org_qemu_x_StructList *b,
                                               __org_qemu_x_Union2 *c,
@@ -103,7 +96,7 @@ static void test_dispatch_cmd(void)
 }
 
 /* test commands that return an error due to invalid parameters */
-static void test_dispatch_cmd_failure(void)
+static void test_dispatch_cmd_error(void)
 {
     QDict *req = qdict_new();
     QObject *resp;
@@ -224,24 +217,25 @@ static void test_dealloc_partial(void)
     /* create partial object */
     {
         QDict *ud2_dict;
-        Visitor *v;
+        QmpInputVisitor *qiv;
 
         ud2_dict = qdict_new();
         qdict_put_obj(ud2_dict, "string0", QOBJECT(qstring_from_str(text)));
 
-        v = qmp_input_visitor_new(QOBJECT(ud2_dict), true);
-        visit_type_UserDefTwo(v, NULL, &ud2, &err);
-        visit_free(v);
+        qiv = qmp_input_visitor_new(QOBJECT(ud2_dict));
+        visit_type_UserDefTwo(qmp_input_get_visitor(qiv), NULL, &ud2, &err);
+        qmp_input_visitor_cleanup(qiv);
         QDECREF(ud2_dict);
     }
 
-    /* verify that visit_type_XXX() cleans up properly on error */
-    error_free_or_abort(&err);
-    assert(!ud2);
+    /* verify partial success */
+    assert(ud2 != NULL);
+    assert(ud2->string0 != NULL);
+    assert(strcmp(ud2->string0, text) == 0);
+    assert(ud2->dict1 == NULL);
 
-    /* Manually create a partial object, leaving ud2->dict1 at NULL */
-    ud2 = g_new0(UserDefTwo, 1);
-    ud2->string0 = g_strdup(text);
+    /* confirm & release construction error */
+    error_free_or_abort(&err);
 
     /* tear down partial object */
     qapi_free_UserDefTwo(ud2);
@@ -253,7 +247,7 @@ int main(int argc, char **argv)
     g_test_init(&argc, &argv, NULL);
 
     g_test_add_func("/0.15/dispatch_cmd", test_dispatch_cmd);
-    g_test_add_func("/0.15/dispatch_cmd_failure", test_dispatch_cmd_failure);
+    g_test_add_func("/0.15/dispatch_cmd_error", test_dispatch_cmd_error);
     g_test_add_func("/0.15/dispatch_cmd_io", test_dispatch_cmd_io);
     g_test_add_func("/0.15/dealloc_types", test_dealloc_types);
     g_test_add_func("/0.15/dealloc_partial", test_dealloc_partial);
index 633dc87..a296fdb 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu-common.h"
 #include "test-qapi-types.h"
index 814550a..d71727e 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu-common.h"
 #include "qapi/error.h"
 #include "test-qapi-types.h"
 #include "test-qapi-visit.h"
 #include "qapi/qmp/types.h"
-#include "qapi/qmp/qjson.h"
 #include "test-qmp-introspect.h"
 #include "qmp-introspect.h"
 #include "qapi-visit.h"
 
 typedef struct TestInputVisitorData {
     QObject *obj;
-    Visitor *qiv;
+    QmpInputVisitor *qiv;
 } TestInputVisitorData;
 
 static void validate_teardown(TestInputVisitorData *data,
@@ -36,7 +36,7 @@ static void validate_teardown(TestInputVisitorData *data,
     data->obj = NULL;
 
     if (data->qiv) {
-        visit_free(data->qiv);
+        qmp_input_visitor_cleanup(data->qiv);
         data->qiv = NULL;
     }
 }
@@ -48,14 +48,20 @@ static Visitor *validate_test_init_internal(TestInputVisitorData *data,
                                             const char *json_string,
                                             va_list *ap)
 {
+    Visitor *v;
+
     validate_teardown(data, NULL);
 
     data->obj = qobject_from_jsonv(json_string, ap);
     g_assert(data->obj);
 
-    data->qiv = qmp_input_visitor_new(data->obj, true);
+    data->qiv = qmp_input_visitor_new_strict(data->obj);
     g_assert(data->qiv);
-    return data->qiv;
+
+    v = qmp_input_get_visitor(data->qiv);
+    g_assert(v);
+
+    return v;
 }
 
 static GCC_FMT_ATTR(2, 3)
@@ -176,7 +182,10 @@ static void test_validate_fail_struct(TestInputVisitorData *data,
 
     visit_type_TestStruct(v, NULL, &p, &err);
     error_free_or_abort(&err);
-    g_assert(!p);
+    if (p) {
+        g_free(p->string);
+    }
+    g_free(p);
 }
 
 static void test_validate_fail_struct_nested(TestInputVisitorData *data,
@@ -190,7 +199,7 @@ static void test_validate_fail_struct_nested(TestInputVisitorData *data,
 
     visit_type_UserDefTwo(v, NULL, &udp, &err);
     error_free_or_abort(&err);
-    g_assert(!udp);
+    qapi_free_UserDefTwo(udp);
 }
 
 static void test_validate_fail_list(TestInputVisitorData *data,
@@ -204,7 +213,7 @@ static void test_validate_fail_list(TestInputVisitorData *data,
 
     visit_type_UserDefOneList(v, NULL, &head, &err);
     error_free_or_abort(&err);
-    g_assert(!head);
+    qapi_free_UserDefOneList(head);
 }
 
 static void test_validate_fail_union_native_list(TestInputVisitorData *data,
@@ -219,7 +228,7 @@ static void test_validate_fail_union_native_list(TestInputVisitorData *data,
 
     visit_type_UserDefNativeListUnion(v, NULL, &tmp, &err);
     error_free_or_abort(&err);
-    g_assert(!tmp);
+    qapi_free_UserDefNativeListUnion(tmp);
 }
 
 static void test_validate_fail_union_flat(TestInputVisitorData *data,
@@ -233,7 +242,7 @@ static void test_validate_fail_union_flat(TestInputVisitorData *data,
 
     visit_type_UserDefFlatUnion(v, NULL, &tmp, &err);
     error_free_or_abort(&err);
-    g_assert(!tmp);
+    qapi_free_UserDefFlatUnion(tmp);
 }
 
 static void test_validate_fail_union_flat_no_discrim(TestInputVisitorData *data,
@@ -248,13 +257,13 @@ static void test_validate_fail_union_flat_no_discrim(TestInputVisitorData *data,
 
     visit_type_UserDefFlatUnion2(v, NULL, &tmp, &err);
     error_free_or_abort(&err);
-    g_assert(!tmp);
+    qapi_free_UserDefFlatUnion2(tmp);
 }
 
 static void test_validate_fail_alternate(TestInputVisitorData *data,
                                          const void *unused)
 {
-    UserDefAlternate *tmp;
+    UserDefAlternate *tmp = NULL;
     Visitor *v;
     Error *err = NULL;
 
@@ -262,7 +271,7 @@ static void test_validate_fail_alternate(TestInputVisitorData *data,
 
     visit_type_UserDefAlternate(v, NULL, &tmp, &err);
     error_free_or_abort(&err);
-    g_assert(!tmp);
+    qapi_free_UserDefAlternate(tmp);
 }
 
 static void do_test_validate_qmp_introspect(TestInputVisitorData *data,
index f583dce..8523283 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu-common.h"
 #include "qapi/error.h"
 #include "test-qapi-types.h"
 #include "test-qapi-visit.h"
 #include "qapi/qmp/types.h"
-#include "qapi/qmp/qjson.h"
 
 typedef struct TestInputVisitorData {
     QObject *obj;
-    Visitor *qiv;
+    QmpInputVisitor *qiv;
 } TestInputVisitorData;
 
 static void visitor_input_teardown(TestInputVisitorData *data,
@@ -32,7 +32,7 @@ static void visitor_input_teardown(TestInputVisitorData *data,
     data->obj = NULL;
 
     if (data->qiv) {
-        visit_free(data->qiv);
+        qmp_input_visitor_cleanup(data->qiv);
         data->qiv = NULL;
     }
 }
@@ -44,14 +44,20 @@ static Visitor *visitor_input_test_init_internal(TestInputVisitorData *data,
                                                  const char *json_string,
                                                  va_list *ap)
 {
+    Visitor *v;
+
     visitor_input_teardown(data, NULL);
 
     data->obj = qobject_from_jsonv(json_string, ap);
     g_assert(data->obj);
 
-    data->qiv = qmp_input_visitor_new(data->obj, false);
+    data->qiv = qmp_input_visitor_new(data->obj);
     g_assert(data->qiv);
-    return data->qiv;
+
+    v = qmp_input_get_visitor(data->qiv);
+    g_assert(v);
+
+    return v;
 }
 
 static GCC_FMT_ATTR(2, 3)
@@ -273,34 +279,6 @@ static void test_visitor_in_any(TestInputVisitorData *data,
     qobject_decref(res);
 }
 
-static void test_visitor_in_null(TestInputVisitorData *data,
-                                 const void *unused)
-{
-    Visitor *v;
-    Error *err = NULL;
-    char *tmp;
-
-    /*
-     * FIXME: Since QAPI doesn't know the 'null' type yet, we can't
-     * test visit_type_null() by reading into a QAPI struct then
-     * checking that it was populated correctly.  The best we can do
-     * for now is ensure that we consumed null from the input, proven
-     * by the fact that we can't re-read the key; and that we detect
-     * when input is not null.
-     */
-
-    v = visitor_input_test_init(data, "{ 'a': null, 'b': '' }");
-    visit_start_struct(v, NULL, NULL, 0, &error_abort);
-    visit_type_null(v, "a", &error_abort);
-    visit_type_str(v, "a", &tmp, &err);
-    g_assert(!tmp);
-    error_free_or_abort(&err);
-    visit_type_null(v, "b", &err);
-    error_free_or_abort(&err);
-    visit_check_struct(v, &error_abort);
-    visit_end_struct(v, NULL);
-}
-
 static void test_visitor_in_union_flat(TestInputVisitorData *data,
                                        const void *unused)
 {
@@ -769,22 +747,30 @@ static void test_visitor_in_errors(TestInputVisitorData *data,
 
     visit_type_TestStruct(v, NULL, &p, &err);
     error_free_or_abort(&err);
-    g_assert(!p);
+    /* FIXME - a failed parse should not leave a partially-allocated p
+     * for us to clean up; this could cause callers to leak memory. */
+    g_assert(p->string == NULL);
+
+    g_free(p->string);
+    g_free(p);
 
     v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]");
     visit_type_strList(v, NULL, &q, &err);
     error_free_or_abort(&err);
-    assert(!q);
+    assert(q);
+    qapi_free_strList(q);
 
     v = visitor_input_test_init(data, "{ 'str':'hi' }");
     visit_type_UserDefTwo(v, NULL, &r, &err);
     error_free_or_abort(&err);
-    assert(!r);
+    assert(r);
+    qapi_free_UserDefTwo(r);
 
     v = visitor_input_test_init(data, "{ }");
     visit_type_WrapAlternate(v, NULL, &s, &err);
     error_free_or_abort(&err);
-    assert(!s);
+    assert(s);
+    qapi_free_WrapAlternate(s);
 }
 
 static void test_visitor_in_wrong_type(TestInputVisitorData *data,
@@ -857,8 +843,6 @@ int main(int argc, char **argv)
                            &in_visitor_data, test_visitor_in_list);
     input_visitor_test_add("/visitor/input/any",
                            &in_visitor_data, test_visitor_in_any);
-    input_visitor_test_add("/visitor/input/null",
-                           &in_visitor_data, test_visitor_in_null);
     input_visitor_test_add("/visitor/input/union-flat",
                            &in_visitor_data, test_visitor_in_union_flat);
     input_visitor_test_add("/visitor/input/alternate",
index 513d71f..c709267 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu-common.h"
 #include "qapi/error.h"
 #include "test-qapi-types.h"
 #include "test-qapi-visit.h"
 #include "qapi/qmp/types.h"
-#include "qapi/qmp/qjson.h"
 
 typedef struct TestOutputVisitorData {
+    QmpOutputVisitor *qov;
     Visitor *ov;
-    QObject *obj;
 } TestOutputVisitorData;
 
 static void visitor_output_setup(TestOutputVisitorData *data,
                                  const void *unused)
 {
-    data->ov = qmp_output_visitor_new(&data->obj);
-    g_assert(data->ov);
+    data->qov = qmp_output_visitor_new();
+    g_assert(data->qov != NULL);
+
+    data->ov = qmp_output_get_visitor(data->qov);
+    g_assert(data->ov != NULL);
 }
 
 static void visitor_output_teardown(TestOutputVisitorData *data,
                                     const void *unused)
 {
-    visit_free(data->ov);
+    qmp_output_visitor_cleanup(data->qov);
+    data->qov = NULL;
     data->ov = NULL;
-    qobject_decref(data->obj);
-    data->obj = NULL;
-}
-
-static QObject *visitor_get(TestOutputVisitorData *data)
-{
-    visit_complete(data->ov, &data->obj);
-    g_assert(data->obj);
-    return data->obj;
-}
-
-static void visitor_reset(TestOutputVisitorData *data)
-{
-    visitor_output_teardown(data, NULL);
-    visitor_output_setup(data, NULL);
 }
 
 static void test_visitor_out_int(TestOutputVisitorData *data,
@@ -62,9 +51,12 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
 
     visit_type_int(data->ov, NULL, &value, &error_abort);
 
-    obj = visitor_get(data);
+    obj = qmp_output_get_qobject(data->qov);
+    g_assert(obj != NULL);
     g_assert(qobject_type(obj) == QTYPE_QINT);
     g_assert_cmpint(qint_get_int(qobject_to_qint(obj)), ==, value);
+
+    qobject_decref(obj);
 }
 
 static void test_visitor_out_bool(TestOutputVisitorData *data,
@@ -75,9 +67,12 @@ static void test_visitor_out_bool(TestOutputVisitorData *data,
 
     visit_type_bool(data->ov, NULL, &value, &error_abort);
 
-    obj = visitor_get(data);
+    obj = qmp_output_get_qobject(data->qov);
+    g_assert(obj != NULL);
     g_assert(qobject_type(obj) == QTYPE_QBOOL);
     g_assert(qbool_get_bool(qobject_to_qbool(obj)) == value);
+
+    qobject_decref(obj);
 }
 
 static void test_visitor_out_number(TestOutputVisitorData *data,
@@ -88,9 +83,12 @@ static void test_visitor_out_number(TestOutputVisitorData *data,
 
     visit_type_number(data->ov, NULL, &value, &error_abort);
 
-    obj = visitor_get(data);
+    obj = qmp_output_get_qobject(data->qov);
+    g_assert(obj != NULL);
     g_assert(qobject_type(obj) == QTYPE_QFLOAT);
     g_assert(qfloat_get_double(qobject_to_qfloat(obj)) == value);
+
+    qobject_decref(obj);
 }
 
 static void test_visitor_out_string(TestOutputVisitorData *data,
@@ -101,9 +99,12 @@ static void test_visitor_out_string(TestOutputVisitorData *data,
 
     visit_type_str(data->ov, NULL, &string, &error_abort);
 
-    obj = visitor_get(data);
+    obj = qmp_output_get_qobject(data->qov);
+    g_assert(obj != NULL);
     g_assert(qobject_type(obj) == QTYPE_QSTRING);
     g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==, string);
+
+    qobject_decref(obj);
 }
 
 static void test_visitor_out_no_string(TestOutputVisitorData *data,
@@ -115,9 +116,12 @@ static void test_visitor_out_no_string(TestOutputVisitorData *data,
     /* A null string should return "" */
     visit_type_str(data->ov, NULL, &string, &error_abort);
 
-    obj = visitor_get(data);
+    obj = qmp_output_get_qobject(data->qov);
+    g_assert(obj != NULL);
     g_assert(qobject_type(obj) == QTYPE_QSTRING);
     g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==, "");
+
+    qobject_decref(obj);
 }
 
 static void test_visitor_out_enum(TestOutputVisitorData *data,
@@ -129,11 +133,12 @@ static void test_visitor_out_enum(TestOutputVisitorData *data,
     for (i = 0; i < ENUM_ONE__MAX; i++) {
         visit_type_EnumOne(data->ov, "unused", &i, &error_abort);
 
-        obj = visitor_get(data);
+        obj = qmp_output_get_qobject(data->qov);
+        g_assert(obj != NULL);
         g_assert(qobject_type(obj) == QTYPE_QSTRING);
         g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==,
                         EnumOne_lookup[i]);
-        visitor_reset(data);
+        qobject_decref(obj);
     }
 }
 
@@ -148,7 +153,6 @@ static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
         visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err);
         g_assert(err);
         error_free(err);
-        visitor_reset(data);
     }
 }
 
@@ -165,7 +169,8 @@ static void test_visitor_out_struct(TestOutputVisitorData *data,
 
     visit_type_TestStruct(data->ov, NULL, &p, &error_abort);
 
-    obj = visitor_get(data);
+    obj = qmp_output_get_qobject(data->qov);
+    g_assert(obj != NULL);
     g_assert(qobject_type(obj) == QTYPE_QDICT);
 
     qdict = qobject_to_qdict(obj);
@@ -173,6 +178,8 @@ static void test_visitor_out_struct(TestOutputVisitorData *data,
     g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 42);
     g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, false);
     g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "foo");
+
+    QDECREF(qdict);
 }
 
 static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
@@ -207,7 +214,8 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
 
     visit_type_UserDefTwo(data->ov, "unused", &ud2, &error_abort);
 
-    obj = visitor_get(data);
+    obj = qmp_output_get_qobject(data->qov);
+    g_assert(obj != NULL);
     g_assert(qobject_type(obj) == QTYPE_QDICT);
 
     qdict = qobject_to_qdict(obj);
@@ -234,6 +242,7 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
     g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
     g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
 
+    QDECREF(qdict);
     qapi_free_UserDefTwo(ud2);
 }
 
@@ -253,7 +262,6 @@ static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
         visit_type_UserDefOne(data->ov, "unused", &pu, &err);
         g_assert(err);
         error_free(err);
-        visitor_reset(data);
     }
 }
 
@@ -285,7 +293,8 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
 
     visit_type_TestStructList(data->ov, NULL, &head, &error_abort);
 
-    obj = visitor_get(data);
+    obj = qmp_output_get_qobject(data->qov);
+    g_assert(obj != NULL);
     g_assert(qobject_type(obj) == QTYPE_QLIST);
 
     qlist = qobject_to_qlist(obj);
@@ -306,6 +315,7 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
     }
     g_assert_cmpint(i, ==, max_items);
 
+    QDECREF(qlist);
     qapi_free_TestStructList(head);
 }
 
@@ -349,12 +359,13 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
 
     qobj = QOBJECT(qint_from_int(-42));
     visit_type_any(data->ov, NULL, &qobj, &error_abort);
-    obj = visitor_get(data);
+    obj = qmp_output_get_qobject(data->qov);
+    g_assert(obj != NULL);
     g_assert(qobject_type(obj) == QTYPE_QINT);
     g_assert_cmpint(qint_get_int(qobject_to_qint(obj)), ==, -42);
+    qobject_decref(obj);
     qobject_decref(qobj);
 
-    visitor_reset(data);
     qdict = qdict_new();
     qdict_put(qdict, "integer", qint_from_int(-42));
     qdict_put(qdict, "boolean", qbool_from_bool(true));
@@ -362,7 +373,8 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
     qobj = QOBJECT(qdict);
     visit_type_any(data->ov, NULL, &qobj, &error_abort);
     qobject_decref(qobj);
-    obj = visitor_get(data);
+    obj = qmp_output_get_qobject(data->qov);
+    g_assert(obj != NULL);
     qdict = qobject_to_qdict(obj);
     g_assert(qdict);
     qobj = qdict_get(qdict, "integer");
@@ -380,6 +392,7 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
     qstring = qobject_to_qstring(qobj);
     g_assert(qstring);
     g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
+    qobject_decref(obj);
 }
 
 static void test_visitor_out_union_flat(TestOutputVisitorData *data,
@@ -395,7 +408,7 @@ static void test_visitor_out_union_flat(TestOutputVisitorData *data,
     tmp->u.value1.boolean = true;
 
     visit_type_UserDefFlatUnion(data->ov, NULL, &tmp, &error_abort);
-    arg = visitor_get(data);
+    arg = qmp_output_get_qobject(data->qov);
 
     g_assert(qobject_type(arg) == QTYPE_QDICT);
     qdict = qobject_to_qdict(arg);
@@ -406,6 +419,7 @@ static void test_visitor_out_union_flat(TestOutputVisitorData *data,
     g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
 
     qapi_free_UserDefFlatUnion(tmp);
+    QDECREF(qdict);
 }
 
 static void test_visitor_out_alternate(TestOutputVisitorData *data,
@@ -420,27 +434,27 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
     tmp->u.i = 42;
 
     visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
-    arg = visitor_get(data);
+    arg = qmp_output_get_qobject(data->qov);
 
     g_assert(qobject_type(arg) == QTYPE_QINT);
     g_assert_cmpint(qint_get_int(qobject_to_qint(arg)), ==, 42);
 
     qapi_free_UserDefAlternate(tmp);
+    qobject_decref(arg);
 
-    visitor_reset(data);
     tmp = g_new0(UserDefAlternate, 1);
     tmp->type = QTYPE_QSTRING;
     tmp->u.s = g_strdup("hello");
 
     visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
-    arg = visitor_get(data);
+    arg = qmp_output_get_qobject(data->qov);
 
     g_assert(qobject_type(arg) == QTYPE_QSTRING);
     g_assert_cmpstr(qstring_get_str(qobject_to_qstring(arg)), ==, "hello");
 
     qapi_free_UserDefAlternate(tmp);
+    qobject_decref(arg);
 
-    visitor_reset(data);
     tmp = g_new0(UserDefAlternate, 1);
     tmp->type = QTYPE_QDICT;
     tmp->u.udfu.integer = 1;
@@ -449,7 +463,7 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
     tmp->u.udfu.u.value1.boolean = true;
 
     visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
-    arg = visitor_get(data);
+    arg = qmp_output_get_qobject(data->qov);
 
     g_assert_cmpint(qobject_type(arg), ==, QTYPE_QDICT);
     qdict = qobject_to_qdict(arg);
@@ -460,26 +474,19 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
     g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
 
     qapi_free_UserDefAlternate(tmp);
+    qobject_decref(arg);
 }
 
-static void test_visitor_out_null(TestOutputVisitorData *data,
-                                  const void *unused)
+static void test_visitor_out_empty(TestOutputVisitorData *data,
+                                   const void *unused)
 {
     QObject *arg;
-    QDict *qdict;
-    QObject *nil;
 
-    visit_start_struct(data->ov, NULL, NULL, 0, &error_abort);
-    visit_type_null(data->ov, "a", &error_abort);
-    visit_check_struct(data->ov, &error_abort);
-    visit_end_struct(data->ov, NULL);
-    arg = visitor_get(data);
-    g_assert(qobject_type(arg) == QTYPE_QDICT);
-    qdict = qobject_to_qdict(arg);
-    g_assert_cmpint(qdict_size(qdict), ==, 1);
-    nil = qdict_get(qdict, "a");
-    g_assert(nil);
-    g_assert(qobject_type(nil) == QTYPE_QNULL);
+    arg = qmp_output_get_qobject(data->qov);
+    g_assert(qobject_type(arg) == QTYPE_QNULL);
+    /* Check that qnull reference counting is sane */
+    g_assert(arg->refcnt == 2);
+    qobject_decref(arg);
 }
 
 static void init_native_list(UserDefNativeListUnion *cvalue)
@@ -710,9 +717,10 @@ static void test_native_list(TestOutputVisitorData *data,
 
     visit_type_UserDefNativeListUnion(data->ov, NULL, &cvalue, &error_abort);
 
-    obj = visitor_get(data);
+    obj = qmp_output_get_qobject(data->qov);
     check_native_list(obj, cvalue->type);
     qapi_free_UserDefNativeListUnion(cvalue);
+    qobject_decref(obj);
 }
 
 static void test_visitor_out_native_list_int(TestOutputVisitorData *data,
@@ -831,8 +839,8 @@ int main(int argc, char **argv)
                             &out_visitor_data, test_visitor_out_union_flat);
     output_visitor_test_add("/visitor/output/alternate",
                             &out_visitor_data, test_visitor_out_alternate);
-    output_visitor_test_add("/visitor/output/null",
-                            &out_visitor_data, test_visitor_out_null);
+    output_visitor_test_add("/visitor/output/empty",
+                            &out_visitor_data, test_visitor_out_empty);
     output_visitor_test_add("/visitor/output/native_list/int",
                             &out_visitor_data,
                             test_visitor_out_native_list_int);
index 1514d7e..79d3750 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu/atomic.h"
 #include "qemu/rcu.h"
 #include "qemu/thread.h"
index 471a811..9a3cb24 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu-common.h"
 #include "qemu/rfifolock.h"
 
index d837ebe..9e6906a 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu-common.h"
 #include "qapi/error.h"
 #include "qapi/qmp/types.h"
 
 typedef struct TestInputVisitorData {
-    Visitor *v;
+    StringInputVisitor *siv;
 } TestInputVisitorData;
 
 static void visitor_input_teardown(TestInputVisitorData *data,
                                    const void *unused)
 {
-    if (data->v) {
-        visit_free(data->v);
-        data->v = NULL;
+    if (data->siv) {
+        string_input_visitor_cleanup(data->siv);
+        data->siv = NULL;
     }
 }
 
@@ -39,9 +40,15 @@ static
 Visitor *visitor_input_test_init(TestInputVisitorData *data,
                                  const char *string)
 {
-    data->v = string_input_visitor_new(string);
-    g_assert(data->v);
-    return data->v;
+    Visitor *v;
+
+    data->siv = string_input_visitor_new(string);
+    g_assert(data->siv != NULL);
+
+    v = string_input_get_visitor(data->siv);
+    g_assert(v != NULL);
+
+    return v;
 }
 
 static void test_visitor_in_int(TestInputVisitorData *data,
@@ -56,13 +63,6 @@ static void test_visitor_in_int(TestInputVisitorData *data,
     visit_type_int(v, NULL, &res, &err);
     g_assert(!err);
     g_assert_cmpint(res, ==, value);
-
-    visitor_input_teardown(data, unused);
-
-    v = visitor_input_test_init(data, "not an int");
-
-    visit_type_int(v, NULL, &res, &err);
-    error_free_or_abort(&err);
 }
 
 static void test_visitor_in_intList(TestInputVisitorData *data,
@@ -70,7 +70,6 @@ static void test_visitor_in_intList(TestInputVisitorData *data,
 {
     int64_t value[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20};
     int16List *res = NULL, *tmp;
-    Error *err = NULL;
     Visitor *v;
     int i = 0;
 
@@ -85,15 +84,12 @@ static void test_visitor_in_intList(TestInputVisitorData *data,
     }
     g_assert(!tmp);
 
-    qapi_free_int16List(res);
-
-    visitor_input_teardown(data, unused);
-
-    v = visitor_input_test_init(data, "not an int list");
-
-    visit_type_int16List(v, NULL, &res, &err);
-    error_free_or_abort(&err);
-    g_assert(!res);
+    tmp = res;
+    while (tmp) {
+        res = res->next;
+        g_free(tmp);
+        tmp = res;
+    }
 }
 
 static void test_visitor_in_bool(TestInputVisitorData *data,
@@ -193,6 +189,8 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
 
         visitor_input_teardown(data, NULL);
     }
+
+    data->siv = NULL;
 }
 
 /* Try to crash the visitors */
index 444844a..1ecd75b 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu-common.h"
 #include "qapi/error.h"
 #include "qapi/qmp/types.h"
 
 typedef struct TestOutputVisitorData {
+    StringOutputVisitor *sov;
     Visitor *ov;
-    char *str;
     bool human;
 } TestOutputVisitorData;
 
-static void visitor_output_setup_internal(TestOutputVisitorData *data,
-                                          bool human)
-{
-    data->human = human;
-    data->ov = string_output_visitor_new(human, &data->str);
-    g_assert(data->ov);
-}
-
 static void visitor_output_setup(TestOutputVisitorData *data,
                                  const void *unused)
 {
-    return visitor_output_setup_internal(data, false);
+    data->human = false;
+    data->sov = string_output_visitor_new(data->human);
+    g_assert(data->sov != NULL);
+
+    data->ov = string_output_get_visitor(data->sov);
+    g_assert(data->ov != NULL);
 }
 
 static void visitor_output_setup_human(TestOutputVisitorData *data,
                                        const void *unused)
 {
-    return visitor_output_setup_internal(data, true);
+    data->human = true;
+    data->sov = string_output_visitor_new(data->human);
+    g_assert(data->sov != NULL);
+
+    data->ov = string_output_get_visitor(data->sov);
+    g_assert(data->ov != NULL);
 }
 
 static void visitor_output_teardown(TestOutputVisitorData *data,
                                     const void *unused)
 {
-    visit_free(data->ov);
+    string_output_visitor_cleanup(data->sov);
+    data->sov = NULL;
     data->ov = NULL;
-    g_free(data->str);
-    data->str = NULL;
-}
-
-static char *visitor_get(TestOutputVisitorData *data)
-{
-    visit_complete(data->ov, &data->str);
-    g_assert(data->str);
-    return data->str;
-}
-
-static void visitor_reset(TestOutputVisitorData *data)
-{
-    bool human = data->human;
-
-    visitor_output_teardown(data, NULL);
-    visitor_output_setup_internal(data, human);
 }
 
 static void test_visitor_out_int(TestOutputVisitorData *data,
@@ -79,12 +66,14 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
     visit_type_int(data->ov, NULL, &value, &err);
     g_assert(!err);
 
-    str = visitor_get(data);
+    str = string_output_get_string(data->sov);
+    g_assert(str != NULL);
     if (data->human) {
         g_assert_cmpstr(str, ==, "42 (0x2a)");
     } else {
         g_assert_cmpstr(str, ==, "42");
     }
+    g_free(str);
 }
 
 static void test_visitor_out_intList(TestOutputVisitorData *data,
@@ -106,7 +95,8 @@ static void test_visitor_out_intList(TestOutputVisitorData *data,
     visit_type_intList(data->ov, NULL, &list, &err);
     g_assert(err == NULL);
 
-    str = visitor_get(data);
+    str = string_output_get_string(data->sov);
+    g_assert(str != NULL);
     if (data->human) {
         g_assert_cmpstr(str, ==,
             "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807 "
@@ -116,7 +106,13 @@ static void test_visitor_out_intList(TestOutputVisitorData *data,
         g_assert_cmpstr(str, ==,
             "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807");
     }
-    qapi_free_intList(list);
+    g_free(str);
+    while (list) {
+        intList *tmp2;
+        tmp2 = list->next;
+        g_free(list);
+        list = tmp2;
+    }
 }
 
 static void test_visitor_out_bool(TestOutputVisitorData *data,
@@ -129,8 +125,10 @@ static void test_visitor_out_bool(TestOutputVisitorData *data,
     visit_type_bool(data->ov, NULL, &value, &err);
     g_assert(!err);
 
-    str = visitor_get(data);
+    str = string_output_get_string(data->sov);
+    g_assert(str != NULL);
     g_assert_cmpstr(str, ==, "true");
+    g_free(str);
 }
 
 static void test_visitor_out_number(TestOutputVisitorData *data,
@@ -143,8 +141,10 @@ static void test_visitor_out_number(TestOutputVisitorData *data,
     visit_type_number(data->ov, NULL, &value, &err);
     g_assert(!err);
 
-    str = visitor_get(data);
+    str = string_output_get_string(data->sov);
+    g_assert(str != NULL);
     g_assert_cmpstr(str, ==, "3.140000");
+    g_free(str);
 }
 
 static void test_visitor_out_string(TestOutputVisitorData *data,
@@ -158,50 +158,61 @@ static void test_visitor_out_string(TestOutputVisitorData *data,
     visit_type_str(data->ov, NULL, &string, &err);
     g_assert(!err);
 
-    str = visitor_get(data);
+    str = string_output_get_string(data->sov);
+    g_assert(str != NULL);
     if (data->human) {
         g_assert_cmpstr(str, ==, string_human);
     } else {
         g_assert_cmpstr(str, ==, string);
     }
+    g_free(str);
 }
 
 static void test_visitor_out_no_string(TestOutputVisitorData *data,
                                        const void *unused)
 {
     char *string = NULL;
+    Error *err = NULL;
     char *str;
 
     /* A null string should return "" */
-    visit_type_str(data->ov, NULL, &string, &error_abort);
+    visit_type_str(data->ov, NULL, &string, &err);
+    g_assert(!err);
 
-    str = visitor_get(data);
+    str = string_output_get_string(data->sov);
+    g_assert(str != NULL);
     if (data->human) {
         g_assert_cmpstr(str, ==, "<null>");
     } else {
         g_assert_cmpstr(str, ==, "");
     }
+    g_free(str);
 }
 
 static void test_visitor_out_enum(TestOutputVisitorData *data,
                                   const void *unused)
 {
+    Error *err = NULL;
     char *str;
     EnumOne i;
 
     for (i = 0; i < ENUM_ONE__MAX; i++) {
-        visit_type_EnumOne(data->ov, "unused", &i, &error_abort);
+        char *str_human;
 
-        str = visitor_get(data);
-        if (data->human) {
-            char *str_human = g_strdup_printf("\"%s\"", EnumOne_lookup[i]);
+        visit_type_EnumOne(data->ov, "unused", &i, &err);
+        g_assert(!err);
 
+        str_human = g_strdup_printf("\"%s\"", EnumOne_lookup[i]);
+
+        str = string_output_get_string(data->sov);
+        g_assert(str != NULL);
+        if (data->human) {
             g_assert_cmpstr(str, ==, str_human);
-            g_free(str_human);
         } else {
             g_assert_cmpstr(str, ==, EnumOne_lookup[i]);
         }
-        visitor_reset(data);
+        g_free(str_human);
+       g_free(str);
     }
 }
 
@@ -214,7 +225,8 @@ static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
     for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
         err = NULL;
         visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err);
-        error_free_or_abort(&err);
+        g_assert(err);
+        error_free(err);
     }
 }
 
index 8dbf66a..88dc731 100644 (file)
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu-common.h"
 #include "block/aio.h"
 #include "block/thread-pool.h"
@@ -91,9 +92,9 @@ static void co_test_cb(void *opaque)
 static void test_submit_co(void)
 {
     WorkerTestData data;
-    Coroutine *co = qemu_coroutine_create(co_test_cb, &data);
+    Coroutine *co = qemu_coroutine_create(co_test_cb);
 
-    qemu_coroutine_enter(co);
+    qemu_coroutine_enter(co, &data);
 
     /* Back here once the worker has started.  */
 
index 363b59a..744a524 100644 (file)
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <math.h>
 #include "block/aio.h"
 #include "qapi/error.h"
 #include "qemu/throttle.h"
 #include "qemu/error-report.h"
 #include "block/throttle-groups.h"
-#include "sysemu/block-backend.h"
 
 static AioContext     *ctx;
 static LeakyBucket    bkt;
@@ -394,25 +394,9 @@ static void test_max_is_missing_limit(void)
         cfg.buckets[i].max = 0;
         cfg.buckets[i].avg = 100;
         g_assert(throttle_is_valid(&cfg, NULL));
-
-        cfg.buckets[i].max = 30;
-        cfg.buckets[i].avg = 100;
-        g_assert(!throttle_is_valid(&cfg, NULL));
-
-        cfg.buckets[i].max = 100;
-        cfg.buckets[i].avg = 100;
-        g_assert(throttle_is_valid(&cfg, NULL));
     }
 }
 
-static void test_iops_size_is_missing_limit(void)
-{
-    /* A total/read/write iops limit is required */
-    throttle_config_init(&cfg);
-    cfg.op_size = 4096;
-    g_assert(!throttle_is_valid(&cfg, NULL));
-}
-
 static void test_have_timer(void)
 {
     /* zero structures */
@@ -590,32 +574,27 @@ static void test_accounting(void)
 static void test_groups(void)
 {
     ThrottleConfig cfg1, cfg2;
-    BlockBackend *blk1, *blk2, *blk3;
-    BlockBackendPublic *blkp1, *blkp2, *blkp3;
-
-    blk1 = blk_new();
-    blk2 = blk_new();
-    blk3 = blk_new();
+    BlockDriverState *bdrv1, *bdrv2, *bdrv3;
 
-    blkp1 = blk_get_public(blk1);
-    blkp2 = blk_get_public(blk2);
-    blkp3 = blk_get_public(blk3);
+    bdrv1 = bdrv_new();
+    bdrv2 = bdrv_new();
+    bdrv3 = bdrv_new();
 
-    g_assert(blkp1->throttle_state == NULL);
-    g_assert(blkp2->throttle_state == NULL);
-    g_assert(blkp3->throttle_state == NULL);
+    g_assert(bdrv1->throttle_state == NULL);
+    g_assert(bdrv2->throttle_state == NULL);
+    g_assert(bdrv3->throttle_state == NULL);
 
-    throttle_group_register_blk(blk1, "bar");
-    throttle_group_register_blk(blk2, "foo");
-    throttle_group_register_blk(blk3, "bar");
+    throttle_group_register_bs(bdrv1, "bar");
+    throttle_group_register_bs(bdrv2, "foo");
+    throttle_group_register_bs(bdrv3, "bar");
 
-    g_assert(blkp1->throttle_state != NULL);
-    g_assert(blkp2->throttle_state != NULL);
-    g_assert(blkp3->throttle_state != NULL);
+    g_assert(bdrv1->throttle_state != NULL);
+    g_assert(bdrv2->throttle_state != NULL);
+    g_assert(bdrv3->throttle_state != NULL);
 
-    g_assert(!strcmp(throttle_group_get_name(blk1), "bar"));
-    g_assert(!strcmp(throttle_group_get_name(blk2), "foo"));
-    g_assert(blkp1->throttle_state == blkp3->throttle_state);
+    g_assert(!strcmp(throttle_group_get_name(bdrv1), "bar"));
+    g_assert(!strcmp(throttle_group_get_name(bdrv2), "foo"));
+    g_assert(bdrv1->throttle_state == bdrv3->throttle_state);
 
     /* Setting the config of a group member affects the whole group */
     throttle_config_init(&cfg1);
@@ -623,29 +602,29 @@ static void test_groups(void)
     cfg1.buckets[THROTTLE_BPS_WRITE].avg = 285000;
     cfg1.buckets[THROTTLE_OPS_READ].avg  = 20000;
     cfg1.buckets[THROTTLE_OPS_WRITE].avg = 12000;
-    throttle_group_config(blk1, &cfg1);
+    throttle_group_config(bdrv1, &cfg1);
 
-    throttle_group_get_config(blk1, &cfg1);
-    throttle_group_get_config(blk3, &cfg2);
+    throttle_group_get_config(bdrv1, &cfg1);
+    throttle_group_get_config(bdrv3, &cfg2);
     g_assert(!memcmp(&cfg1, &cfg2, sizeof(cfg1)));
 
     cfg2.buckets[THROTTLE_BPS_READ].avg  = 4547;
     cfg2.buckets[THROTTLE_BPS_WRITE].avg = 1349;
     cfg2.buckets[THROTTLE_OPS_READ].avg  = 123;
     cfg2.buckets[THROTTLE_OPS_WRITE].avg = 86;
-    throttle_group_config(blk3, &cfg1);
+    throttle_group_config(bdrv3, &cfg1);
 
-    throttle_group_get_config(blk1, &cfg1);
-    throttle_group_get_config(blk3, &cfg2);
+    throttle_group_get_config(bdrv1, &cfg1);
+    throttle_group_get_config(bdrv3, &cfg2);
     g_assert(!memcmp(&cfg1, &cfg2, sizeof(cfg1)));
 
-    throttle_group_unregister_blk(blk1);
-    throttle_group_unregister_blk(blk2);
-    throttle_group_unregister_blk(blk3);
+    throttle_group_unregister_bs(bdrv1);
+    throttle_group_unregister_bs(bdrv2);
+    throttle_group_unregister_bs(bdrv3);
 
-    g_assert(blkp1->throttle_state == NULL);
-    g_assert(blkp2->throttle_state == NULL);
-    g_assert(blkp3->throttle_state == NULL);
+    g_assert(bdrv1->throttle_state == NULL);
+    g_assert(bdrv2->throttle_state == NULL);
+    g_assert(bdrv3->throttle_state == NULL);
 }
 
 int main(int argc, char **argv)
@@ -668,8 +647,6 @@ int main(int argc, char **argv)
     g_test_add_func("/throttle/config/conflicting", test_conflicting_config);
     g_test_add_func("/throttle/config/is_valid",    test_is_valid);
     g_test_add_func("/throttle/config/max",         test_max_is_missing_limit);
-    g_test_add_func("/throttle/config/iops_size",
-                    test_iops_size_is_missing_limit);
     g_test_add_func("/throttle/config_functions",   test_config_functions);
     g_test_add_func("/throttle/accounting",         test_accounting);
     g_test_add_func("/throttle/groups",             test_groups);
index e2bcf5f..1cc4ab3 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu/timed-average.h"
 
index dba4670..9adbc30 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <float.h>
 
 #include "qemu-common.h"
@@ -19,7 +20,6 @@
 #include "test-qapi-visit.h"
 #include "qapi/error.h"
 #include "qapi/qmp/types.h"
-#include "qapi/qmp/qjson.h"
 #include "qapi/qmp-input-visitor.h"
 #include "qapi/qmp-output-visitor.h"
 #include "qapi/string-input-visitor.h"
@@ -89,11 +89,11 @@ typedef void (*VisitorFunc)(Visitor *v, void **native, Error **errp);
 
 static void dealloc_helper(void *native_in, VisitorFunc visit, Error **errp)
 {
-    Visitor *v = qapi_dealloc_visitor_new();
+    QapiDeallocVisitor *qdv = qapi_dealloc_visitor_new();
 
-    visit(v, &native_in, errp);
+    visit(qapi_dealloc_get_visitor(qdv), &native_in, errp);
 
-    visit_free(v);
+    qapi_dealloc_visitor_cleanup(qdv);
 }
 
 static void visit_primitive_type(Visitor *v, void **native, Error **errp)
@@ -1012,9 +1012,8 @@ static PrimitiveType pt_values[] = {
 /* visitor-specific op implementations */
 
 typedef struct QmpSerializeData {
-    Visitor *qov;
-    QObject *obj;
-    Visitor *qiv;
+    QmpOutputVisitor *qov;
+    QmpInputVisitor *qiv;
 } QmpSerializeData;
 
 static void qmp_serialize(void *native_in, void **datap,
@@ -1022,8 +1021,8 @@ static void qmp_serialize(void *native_in, void **datap,
 {
     QmpSerializeData *d = g_malloc0(sizeof(*d));
 
-    d->qov = qmp_output_visitor_new(&d->obj);
-    visit(d->qov, &native_in, errp);
+    d->qov = qmp_output_visitor_new();
+    visit(qmp_output_get_visitor(d->qov), &native_in, errp);
     *datap = d;
 }
 
@@ -1034,31 +1033,30 @@ static void qmp_deserialize(void **native_out, void *datap,
     QString *output_json;
     QObject *obj_orig, *obj;
 
-    visit_complete(d->qov, &d->obj);
-    obj_orig = d->obj;
+    obj_orig = qmp_output_get_qobject(d->qov);
     output_json = qobject_to_json(obj_orig);
     obj = qobject_from_json(qstring_get_str(output_json));
 
     QDECREF(output_json);
-    d->qiv = qmp_input_visitor_new(obj, true);
+    d->qiv = qmp_input_visitor_new(obj);
     qobject_decref(obj_orig);
     qobject_decref(obj);
-    visit(d->qiv, native_out, errp);
+    visit(qmp_input_get_visitor(d->qiv), native_out, errp);
 }
 
 static void qmp_cleanup(void *datap)
 {
     QmpSerializeData *d = datap;
-    visit_free(d->qov);
-    visit_free(d->qiv);
+    qmp_output_visitor_cleanup(d->qov);
+    qmp_input_visitor_cleanup(d->qiv);
 
     g_free(d);
 }
 
 typedef struct StringSerializeData {
     char *string;
-    Visitor *sov;
-    Visitor *siv;
+    StringOutputVisitor *sov;
+    StringInputVisitor *siv;
 } StringSerializeData;
 
 static void string_serialize(void *native_in, void **datap,
@@ -1066,8 +1064,8 @@ static void string_serialize(void *native_in, void **datap,
 {
     StringSerializeData *d = g_malloc0(sizeof(*d));
 
-    d->sov = string_output_visitor_new(false, &d->string);
-    visit(d->sov, &native_in, errp);
+    d->sov = string_output_visitor_new(false);
+    visit(string_output_get_visitor(d->sov), &native_in, errp);
     *datap = d;
 }
 
@@ -1076,17 +1074,17 @@ static void string_deserialize(void **native_out, void *datap,
 {
     StringSerializeData *d = datap;
 
-    visit_complete(d->sov, &d->string);
+    d->string = string_output_get_string(d->sov);
     d->siv = string_input_visitor_new(d->string);
-    visit(d->siv, native_out, errp);
+    visit(string_input_get_visitor(d->siv), native_out, errp);
 }
 
 static void string_cleanup(void *datap)
 {
     StringSerializeData *d = datap;
 
-    visit_free(d->sov);
-    visit_free(d->siv);
+    string_output_visitor_cleanup(d->sov);
+    string_input_visitor_cleanup(d->siv);
     g_free(d->string);
     g_free(d);
 }
index 41fd841..713d444 100644 (file)
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu-common.h"
 #include "migration/migration.h"
 #include "migration/vmstate.h"
 #include "qemu/coroutine.h"
-#include "io/channel-file.h"
 
 static char temp_file[] = "/tmp/vmst.test.XXXXXX";
 static int temp_fd;
@@ -44,22 +44,35 @@ void yield_until_fd_readable(int fd)
     select(fd + 1, &fds, NULL, NULL, NULL);
 }
 
+/*
+ * Some tests use 'open_test_file' to work on a real fd, some use
+ * an in memory file (QEMUSizedBuffer+qemu_bufopen); we could pick one
+ * but this way we test both.
+ */
 
 /* Duplicate temp_fd and seek to the beginning of the file */
 static QEMUFile *open_test_file(bool write)
 {
     int fd = dup(temp_fd);
-    QIOChannel *ioc;
     lseek(fd, 0, SEEK_SET);
     if (write) {
         g_assert_cmpint(ftruncate(fd, 0), ==, 0);
     }
-    ioc = QIO_CHANNEL(qio_channel_file_new_fd(fd));
-    if (write) {
-        return qemu_fopen_channel_output(ioc);
-    } else {
-        return qemu_fopen_channel_input(ioc);
-    }
+    return qemu_fdopen(fd, write ? "wb" : "rb");
+}
+
+/*
+ * Check that the contents of the memory-buffered file f match
+ * the given size/data.
+ */
+static void check_mem_file(QEMUFile *f, void *data, size_t size)
+{
+    uint8_t *result = g_malloc(size);
+    const QEMUSizedBuffer *qsb = qemu_buf_get(f);
+    g_assert_cmpint(qsb_get_length(qsb), ==, size);
+    g_assert_cmpint(qsb_get_buffer(qsb, 0, size, result), ==, size);
+    g_assert_cmpint(memcmp(result, data, size), ==, 0);
+    g_free(result);
 }
 
 #define SUCCESS(val) \
@@ -379,7 +392,7 @@ static const VMStateDescription vmstate_skipping = {
 
 static void test_save_noskip(void)
 {
-    QEMUFile *fsave = open_test_file(true);
+    QEMUFile *fsave = qemu_bufopen("w", NULL);
     TestStruct obj = { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6,
                        .skip_c_e = false };
     vmstate_save_state(fsave, &vmstate_skipping, &obj, NULL);
@@ -393,14 +406,13 @@ static void test_save_noskip(void)
         0, 0, 0, 5,             /* e */
         0, 0, 0, 0, 0, 0, 0, 6, /* f */
     };
-
+    check_mem_file(fsave, expected, sizeof(expected));
     qemu_fclose(fsave);
-    compare_vmstate(expected, sizeof(expected));
 }
 
 static void test_save_skip(void)
 {
-    QEMUFile *fsave = open_test_file(true);
+    QEMUFile *fsave = qemu_bufopen("w", NULL);
     TestStruct obj = { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6,
                        .skip_c_e = true };
     vmstate_save_state(fsave, &vmstate_skipping, &obj, NULL);
@@ -412,14 +424,13 @@ static void test_save_skip(void)
         0, 0, 0, 0, 0, 0, 0, 4, /* d */
         0, 0, 0, 0, 0, 0, 0, 6, /* f */
     };
+    check_mem_file(fsave, expected, sizeof(expected));
 
     qemu_fclose(fsave);
-    compare_vmstate(expected, sizeof(expected));
 }
 
 static void test_load_noskip(void)
 {
-    QEMUFile *fsave = open_test_file(true);
     uint8_t buf[] = {
         0, 0, 0, 10,             /* a */
         0, 0, 0, 20,             /* b */
@@ -429,10 +440,10 @@ static void test_load_noskip(void)
         0, 0, 0, 0, 0, 0, 0, 60, /* f */
         QEMU_VM_EOF, /* just to ensure we won't get EOF reported prematurely */
     };
-    qemu_put_buffer(fsave, buf, sizeof(buf));
-    qemu_fclose(fsave);
 
-    QEMUFile *loading = open_test_file(false);
+    QEMUSizedBuffer *qsb = qsb_create(buf, sizeof(buf));
+    g_assert(qsb);
+    QEMUFile *loading = qemu_bufopen("r", qsb);
     TestStruct obj = { .skip_c_e = false };
     vmstate_load_state(loading, &vmstate_skipping, &obj, 2);
     g_assert(!qemu_file_get_error(loading));
@@ -443,11 +454,11 @@ static void test_load_noskip(void)
     g_assert_cmpint(obj.e, ==, 50);
     g_assert_cmpint(obj.f, ==, 60);
     qemu_fclose(loading);
+    qsb_free(qsb);
 }
 
 static void test_load_skip(void)
 {
-    QEMUFile *fsave = open_test_file(true);
     uint8_t buf[] = {
         0, 0, 0, 10,             /* a */
         0, 0, 0, 20,             /* b */
@@ -455,10 +466,10 @@ static void test_load_skip(void)
         0, 0, 0, 0, 0, 0, 0, 60, /* f */
         QEMU_VM_EOF, /* just to ensure we won't get EOF reported prematurely */
     };
-    qemu_put_buffer(fsave, buf, sizeof(buf));
-    qemu_fclose(fsave);
 
-    QEMUFile *loading = open_test_file(false);
+    QEMUSizedBuffer *qsb = qsb_create(buf, sizeof(buf));
+    g_assert(qsb);
+    QEMUFile *loading = qemu_bufopen("r", qsb);
     TestStruct obj = { .skip_c_e = true, .c = 300, .e = 500 };
     vmstate_load_state(loading, &vmstate_skipping, &obj, 2);
     g_assert(!qemu_file_get_error(loading));
@@ -469,14 +480,13 @@ static void test_load_skip(void)
     g_assert_cmpint(obj.e, ==, 500);
     g_assert_cmpint(obj.f, ==, 60);
     qemu_fclose(loading);
+    qsb_free(qsb);
 }
 
 int main(int argc, char **argv)
 {
     temp_fd = mkstemp(temp_file);
 
-    module_call_init(MODULE_INIT_QOM);
-
     g_test_init(&argc, &argv, NULL);
     g_test_add_func("/vmstate/simple/primitive", test_simple_primitive);
     g_test_add_func("/vmstate/versioned/load/v1", test_load_v1);
index 97ca12f..fdbc802 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "block/block_int.h"
 #include "block/write-threshold.h"
 
index ff22500..8eb0bc6 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "hw/i386/topology.h"
 
index a7940a4..235cae0 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "libqtest.h"
 #include "libqos/i2c.h"
index 0321ec2..cb2b00c 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
index eb247ad..a0f13ef 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "libqos/pci-pc.h"
 #include "hw/usb/uhci-regs.h"
index 4758813..efd6669 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "libqos/usb.h"
 
index 5cd59ad..71ff2ea 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "libqos/usb.h"
 #include "hw/usb/uhci-regs.h"
index 22513e9..7e2e212 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "libqos/usb.h"
 
index 775e031..0779ba2 100644 (file)
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <sys/unistd.h>
+#include <sys/mman.h>
 #include <sys/eventfd.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#include <qemu/osdep.h>
+
 #include <linux/vhost.h>
 
 #include "qemu/atomic.h"
@@ -943,13 +946,6 @@ vubr_set_vring_addr_exec(VubrDev *dev, VhostUserMsg *vmsg)
     DPRINT("    vring_avail at %p\n", vq->avail);
 
     vq->last_used_index = vq->used->idx;
-
-    if (vq->last_avail_index != vq->used->idx) {
-        DPRINT("Last avail index != used index: %d != %d, resuming",
-               vq->last_avail_index, vq->used->idx);
-        vq->last_avail_index = vq->used->idx;
-    }
-
     return 0;
 }
 
@@ -1208,13 +1204,12 @@ vubr_accept_cb(int sock, void *ctx)
 }
 
 static VubrDev *
-vubr_new(const char *path, bool client)
+vubr_new(const char *path)
 {
     VubrDev *dev = (VubrDev *) calloc(1, sizeof(VubrDev));
     dev->nregions = 0;
     int i;
     struct sockaddr_un un;
-    CallbackFunc cb;
     size_t len;
 
     for (i = 0; i < MAX_NR_VIRTQUEUE; i++) {
@@ -1243,30 +1238,21 @@ vubr_new(const char *path, bool client)
     un.sun_family = AF_UNIX;
     strcpy(un.sun_path, path);
     len = sizeof(un.sun_family) + strlen(path);
+    unlink(path);
 
-    if (!client) {
-        unlink(path);
-
-        if (bind(dev->sock, (struct sockaddr *) &un, len) == -1) {
-            vubr_die("bind");
-        }
-
-        if (listen(dev->sock, 1) == -1) {
-            vubr_die("listen");
-        }
-        cb = vubr_accept_cb;
+    if (bind(dev->sock, (struct sockaddr *) &un, len) == -1) {
+        vubr_die("bind");
+    }
 
-        DPRINT("Waiting for connections on UNIX socket %s ...\n", path);
-    } else {
-        if (connect(dev->sock, (struct sockaddr *)&un, len) == -1) {
-            vubr_die("connect");
-        }
-        cb = vubr_receive_cb;
+    if (listen(dev->sock, 1) == -1) {
+        vubr_die("listen");
     }
 
     dispatcher_init(&dev->dispatcher);
-    dispatcher_add(&dev->dispatcher, dev->sock, (void *)dev, cb);
+    dispatcher_add(&dev->dispatcher, dev->sock, (void *)dev,
+                   vubr_accept_cb);
 
+    DPRINT("Waiting for connections on UNIX socket %s ...\n", path);
     return dev;
 }
 
@@ -1383,9 +1369,8 @@ main(int argc, char *argv[])
 {
     VubrDev *dev;
     int opt;
-    bool client = false;
 
-    while ((opt = getopt(argc, argv, "l:r:u:c")) != -1) {
+    while ((opt = getopt(argc, argv, "l:r:u:")) != -1) {
 
         switch (opt) {
         case 'l':
@@ -1401,20 +1386,16 @@ main(int argc, char *argv[])
         case 'u':
             ud_socket_path = strdup(optarg);
             break;
-        case 'c':
-            client = true;
-            break;
         default:
             goto out;
         }
     }
 
-    DPRINT("ud socket: %s (%s)\n", ud_socket_path,
-           client ? "client" : "server");
+    DPRINT("ud socket: %s\n", ud_socket_path);
     DPRINT("local:     %s:%s\n", lhost, lport);
     DPRINT("remote:    %s:%s\n", rhost, rport);
 
-    dev = vubr_new(ud_socket_path, client);
+    dev = vubr_new(ud_socket_path);
     if (!dev) {
         return 1;
     }
@@ -1425,14 +1406,13 @@ main(int argc, char *argv[])
 
 out:
     fprintf(stderr, "Usage: %s ", argv[0]);
-    fprintf(stderr, "[-c] [-u ud_socket_path] [-l lhost:lport] [-r rhost:rport]\n");
+    fprintf(stderr, "[-u ud_socket_path] [-l lhost:lport] [-r rhost:rport]\n");
     fprintf(stderr, "\t-u path to unix doman socket. default: %s\n",
             DEFAULT_UD_SOCKET);
     fprintf(stderr, "\t-l local host and port. default: %s:%s\n",
             DEFAULT_LHOST, DEFAULT_LPORT);
     fprintf(stderr, "\t-r remote host and port. default: %s:%s\n",
             DEFAULT_RHOST, DEFAULT_RPORT);
-    fprintf(stderr, "\t-c client mode\n");
 
     return 1;
 }
index 27b10c1..6961596 100644 (file)
@@ -9,16 +9,18 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "libqtest.h"
 #include "qemu/option.h"
 #include "qemu/range.h"
-#include "qemu/sockets.h"
 #include "sysemu/char.h"
 #include "sysemu/sysemu.h"
 
 #include <linux/vhost.h>
+#include <sys/mman.h>
 #include <sys/vfs.h>
+#include <qemu/sockets.h>
 
 /* GLIB version compatibility flags */
 #if !GLIB_CHECK_VERSION(2, 26, 0)
@@ -32,7 +34,7 @@
 #define QEMU_CMD_ACCEL  " -machine accel=tcg"
 #define QEMU_CMD_MEM    " -m %d -object memory-backend-file,id=mem,size=%dM,"\
                         "mem-path=%s,share=on -numa node,memdev=mem"
-#define QEMU_CMD_CHR    " -chardev socket,id=%s,path=%s%s"
+#define QEMU_CMD_CHR    " -chardev socket,id=%s,path=%s"
 #define QEMU_CMD_NETDEV " -netdev vhost-user,id=net0,chardev=%s,vhostforce"
 #define QEMU_CMD_NET    " -device virtio-net-pci,netdev=net0,romfile=./pc-bios/pxe-virtio.rom"
 
@@ -127,12 +129,25 @@ typedef struct TestServer {
     int fds_num;
     int fds[VHOST_MEMORY_MAX_NREGIONS];
     VhostUserMemory memory;
-    CompatGMutex data_mutex;
-    CompatGCond data_cond;
+    GMutex data_mutex;
+    GCond data_cond;
     int log_fd;
     uint64_t rings;
 } TestServer;
 
+#if !GLIB_CHECK_VERSION(2, 32, 0)
+static gboolean g_cond_wait_until(CompatGCond cond, CompatGMutex mutex,
+                                  gint64 end_time)
+{
+    gboolean ret = FALSE;
+    end_time -= g_get_monotonic_time();
+    GTimeVal time = { end_time / G_TIME_SPAN_SECOND,
+                      end_time % G_TIME_SPAN_SECOND };
+    ret = g_cond_timed_wait(cond, mutex, &time);
+    return ret;
+}
+#endif
+
 static const char *tmpfs;
 static const char *root;
 
@@ -231,12 +246,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
 
     if (msg.size) {
         p += VHOST_USER_HDR_SIZE;
-        size = qemu_chr_fe_read_all(chr, p, msg.size);
-        if (size != msg.size) {
-            g_test_message("Wrong message size received %d != %d\n",
-                           size, msg.size);
-            return;
-        }
+        g_assert_cmpint(qemu_chr_fe_read_all(chr, p, msg.size), ==, msg.size);
     }
 
     switch (msg.request) {
@@ -353,10 +363,17 @@ static const char *init_hugepagefs(const char *path)
 static TestServer *test_server_new(const gchar *name)
 {
     TestServer *server = g_new0(TestServer, 1);
+    gchar *chr_path;
 
     server->socket_path = g_strdup_printf("%s/%s.sock", tmpfs, name);
     server->mig_path = g_strdup_printf("%s/%s.mig", tmpfs, name);
+
+    chr_path = g_strdup_printf("unix:%s,server,nowait", server->socket_path);
     server->chr_name = g_strdup_printf("chr-%s", name);
+    server->chr = qemu_chr_new(server->chr_name, chr_path, NULL);
+    g_free(chr_path);
+
+    qemu_chr_add_handlers(server->chr, chr_can_read, chr_read, NULL, server);
 
     g_mutex_init(&server->data_mutex);
     g_cond_init(&server->data_cond);
@@ -366,34 +383,13 @@ static TestServer *test_server_new(const gchar *name)
     return server;
 }
 
-static void test_server_create_chr(TestServer *server, const gchar *opt)
-{
-    gchar *chr_path;
-
-    chr_path = g_strdup_printf("unix:%s%s", server->socket_path, opt);
-    server->chr = qemu_chr_new(server->chr_name, chr_path, NULL);
-    g_free(chr_path);
-
-    qemu_chr_add_handlers(server->chr, chr_can_read, chr_read, NULL, server);
-}
-
-static void test_server_listen(TestServer *server)
-{
-    test_server_create_chr(server, ",server,nowait");
-}
-
-static inline void test_server_connect(TestServer *server)
-{
-    test_server_create_chr(server, ",reconnect=1");
-}
-
-#define GET_QEMU_CMD(s)                                         \
-    g_strdup_printf(QEMU_CMD, 512, 512, (root), (s)->chr_name,  \
-                    (s)->socket_path, "", (s)->chr_name)
+#define GET_QEMU_CMD(s)                                                        \
+    g_strdup_printf(QEMU_CMD, 512, 512, (root), (s)->chr_name,                 \
+                    (s)->socket_path, (s)->chr_name)
 
-#define GET_QEMU_CMDE(s, mem, chr_opts, extra, ...)                     \
-    g_strdup_printf(QEMU_CMD extra, (mem), (mem), (root), (s)->chr_name, \
-                    (s)->socket_path, (chr_opts), (s)->chr_name, ##__VA_ARGS__)
+#define GET_QEMU_CMDE(s, mem, extra, ...)                                      \
+    g_strdup_printf(QEMU_CMD extra, (mem), (mem), (root), (s)->chr_name,       \
+                    (s)->socket_path, (s)->chr_name, ##__VA_ARGS__)
 
 static gboolean _test_server_free(TestServer *server)
 {
@@ -541,10 +537,7 @@ static void test_migrate(void)
     guint8 *log;
     guint64 size;
 
-    test_server_listen(s);
-    test_server_listen(dest);
-
-    cmd = GET_QEMU_CMDE(s, 2, "", "");
+    cmd = GET_QEMU_CMDE(s, 2, "");
     from = qtest_start(cmd);
     g_free(cmd);
 
@@ -552,7 +545,7 @@ static void test_migrate(void)
     size = get_log_size(s);
     g_assert_cmpint(size, ==, (2 * 1024 * 1024) / (VHOST_LOG_PAGE * 8));
 
-    cmd = GET_QEMU_CMDE(dest, 2, "", " -incoming %s", uri);
+    cmd = GET_QEMU_CMDE(dest, 2, " -incoming %s", uri);
     to = qtest_init(cmd);
     g_free(cmd);
 
@@ -612,81 +605,6 @@ static void test_migrate(void)
     global_qtest = global;
 }
 
-#ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS
-static void wait_for_rings_started(TestServer *s, size_t count)
-{
-    gint64 end_time;
-
-    g_mutex_lock(&s->data_mutex);
-    end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
-    while (ctpop64(s->rings) != count) {
-        if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) {
-            /* timeout has passed */
-            g_assert_cmpint(ctpop64(s->rings), ==, count);
-            break;
-        }
-    }
-
-    g_mutex_unlock(&s->data_mutex);
-}
-
-static gboolean
-reconnect_cb(gpointer user_data)
-{
-    TestServer *s = user_data;
-
-    qemu_chr_disconnect(s->chr);
-
-    return FALSE;
-}
-
-static gpointer
-connect_thread(gpointer data)
-{
-    TestServer *s = data;
-
-    /* wait for qemu to start before first try, to avoid extra warnings */
-    g_usleep(G_USEC_PER_SEC);
-    test_server_connect(s);
-
-    return NULL;
-}
-
-static void test_reconnect_subprocess(void)
-{
-    TestServer *s = test_server_new("reconnect");
-    char *cmd;
-
-    g_thread_new("connect", connect_thread, s);
-    cmd = GET_QEMU_CMDE(s, 2, ",server", "");
-    qtest_start(cmd);
-    g_free(cmd);
-
-    wait_for_fds(s);
-    wait_for_rings_started(s, 2);
-
-    /* reconnect */
-    s->fds_num = 0;
-    s->rings = 0;
-    g_idle_add(reconnect_cb, s);
-    wait_for_fds(s);
-    wait_for_rings_started(s, 2);
-
-    qtest_end();
-    test_server_free(s);
-    return;
-}
-
-static void test_reconnect(void)
-{
-    gchar *path = g_strdup_printf("/%s/vhost-user/reconnect/subprocess",
-                                  qtest_get_arch());
-    g_test_trap_subprocess(path, 0, 0);
-    g_test_trap_assert_passed();
-    g_free(path);
-}
-#endif
-
 int main(int argc, char **argv)
 {
     QTestState *s = NULL;
@@ -718,7 +636,6 @@ int main(int argc, char **argv)
     }
 
     server = test_server_new("test");
-    test_server_listen(server);
 
     loop = g_main_loop_new(NULL, FALSE);
     /* run the main loop thread so the chardev may operate */
@@ -731,11 +648,6 @@ int main(int argc, char **argv)
 
     qtest_add_data_func("/vhost-user/read-guest-mem", server, read_guest_mem);
     qtest_add_func("/vhost-user/migrate", test_migrate);
-#ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS
-    qtest_add_func("/vhost-user/reconnect/subprocess",
-                   test_reconnect_subprocess);
-    qtest_add_func("/vhost-user/reconnect", test_reconnect);
-#endif
 
     ret = g_test_run();
 
index 1e39335..59d0f1f 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "qemu-common.h"
 
index 0d0046b..b010ce9 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
index 811cf75..3a66630 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "libqos/virtio.h"
 #include "libqos/virtio-pci.h"
 #include "libqos/malloc-pc.h"
 #include "libqos/malloc-generic.h"
 #include "qemu/bswap.h"
-#include "standard-headers/linux/virtio_ids.h"
-#include "standard-headers/linux/virtio_config.h"
-#include "standard-headers/linux/virtio_ring.h"
-#include "standard-headers/linux/virtio_blk.h"
-#include "standard-headers/linux/virtio_pci.h"
+
+#define QVIRTIO_BLK_F_BARRIER       0x00000001
+#define QVIRTIO_BLK_F_SIZE_MAX      0x00000002
+#define QVIRTIO_BLK_F_SEG_MAX       0x00000004
+#define QVIRTIO_BLK_F_GEOMETRY      0x00000010
+#define QVIRTIO_BLK_F_RO            0x00000020
+#define QVIRTIO_BLK_F_BLK_SIZE      0x00000040
+#define QVIRTIO_BLK_F_SCSI          0x00000080
+#define QVIRTIO_BLK_F_WCE           0x00000200
+#define QVIRTIO_BLK_F_TOPOLOGY      0x00000400
+#define QVIRTIO_BLK_F_CONFIG_WCE    0x00000800
+
+#define QVIRTIO_BLK_T_IN            0
+#define QVIRTIO_BLK_T_OUT           1
+#define QVIRTIO_BLK_T_SCSI_CMD      2
+#define QVIRTIO_BLK_T_SCSI_CMD_OUT  3
+#define QVIRTIO_BLK_T_FLUSH         4
+#define QVIRTIO_BLK_T_FLUSH_OUT     5
+#define QVIRTIO_BLK_T_GET_ID        8
 
 #define TEST_IMAGE_SIZE         (64 * 1024 * 1024)
 #define QVIRTIO_BLK_TIMEOUT_US  (30 * 1000 * 1000)
@@ -104,9 +119,9 @@ static QVirtioPCIDevice *virtio_blk_pci_init(QPCIBus *bus, int slot)
 {
     QVirtioPCIDevice *dev;
 
-    dev = qvirtio_pci_device_find(bus, VIRTIO_ID_BLOCK);
+    dev = qvirtio_pci_device_find(bus, QVIRTIO_BLK_DEVICE_ID);
     g_assert(dev != NULL);
-    g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_BLOCK);
+    g_assert_cmphex(dev->vdev.device_type, ==, QVIRTIO_BLK_DEVICE_ID);
     g_assert_cmphex(dev->pdev->devfn, ==, ((slot << 3) | PCI_FN));
 
     qvirtio_pci_device_enable(dev);
@@ -167,16 +182,15 @@ static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
 
     features = qvirtio_get_features(bus, dev);
     features = features & ~(QVIRTIO_F_BAD_FEATURE |
-                    (1u << VIRTIO_RING_F_INDIRECT_DESC) |
-                    (1u << VIRTIO_RING_F_EVENT_IDX) |
-                    (1u << VIRTIO_BLK_F_SCSI));
+                    QVIRTIO_F_RING_INDIRECT_DESC | QVIRTIO_F_RING_EVENT_IDX |
+                            QVIRTIO_BLK_F_SCSI);
     qvirtio_set_features(bus, dev, features);
 
     qvirtio_set_driver_ok(bus, dev);
 
     /* Write and read with 3 descriptor layout */
     /* Write request */
-    req.type = VIRTIO_BLK_T_OUT;
+    req.type = QVIRTIO_BLK_T_OUT;
     req.ioprio = 1;
     req.sector = 0;
     req.data = g_malloc0(512);
@@ -199,7 +213,7 @@ static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
     guest_free(alloc, req_addr);
 
     /* Read request */
-    req.type = VIRTIO_BLK_T_IN;
+    req.type = QVIRTIO_BLK_T_IN;
     req.ioprio = 1;
     req.sector = 0;
     req.data = g_malloc0(512);
@@ -225,10 +239,10 @@ static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
 
     guest_free(alloc, req_addr);
 
-    if (features & (1u << VIRTIO_F_ANY_LAYOUT)) {
+    if (features & QVIRTIO_F_ANY_LAYOUT) {
         /* Write and read with 2 descriptor layout */
         /* Write request */
-        req.type = VIRTIO_BLK_T_OUT;
+        req.type = QVIRTIO_BLK_T_OUT;
         req.ioprio = 1;
         req.sector = 1;
         req.data = g_malloc0(512);
@@ -249,7 +263,7 @@ static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
         guest_free(alloc, req_addr);
 
         /* Read request */
-        req.type = VIRTIO_BLK_T_IN;
+        req.type = QVIRTIO_BLK_T_IN;
         req.ioprio = 1;
         req.sector = 1;
         req.data = g_malloc0(512);
@@ -292,13 +306,13 @@ static void pci_basic(void)
                                                                     alloc, 0);
 
     /* MSI-X is not enabled */
-    addr = dev->addr + VIRTIO_PCI_CONFIG_OFF(false);
+    addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_NO_MSIX;
 
     test_basic(&qvirtio_pci, &dev->vdev, alloc, &vqpci->vq,
                                                     (uint64_t)(uintptr_t)addr);
 
     /* End test */
-    qvirtqueue_cleanup(&qvirtio_pci, &vqpci->vq, alloc);
+    guest_free(alloc, vqpci->vq.desc);
     pc_alloc_uninit(alloc);
     qvirtio_pci_device_disable(dev);
     g_free(dev);
@@ -327,17 +341,16 @@ static void pci_indirect(void)
     dev = virtio_blk_pci_init(bus, PCI_SLOT);
 
     /* MSI-X is not enabled */
-    addr = dev->addr + VIRTIO_PCI_CONFIG_OFF(false);
+    addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_NO_MSIX;
 
     capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
                                                     (uint64_t)(uintptr_t)addr);
     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
     features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
-    g_assert_cmphex(features & (1u << VIRTIO_RING_F_INDIRECT_DESC), !=, 0);
-    features = features & ~(QVIRTIO_F_BAD_FEATURE |
-                            (1u << VIRTIO_RING_F_EVENT_IDX) |
-                            (1u << VIRTIO_BLK_F_SCSI));
+    g_assert_cmphex(features & QVIRTIO_F_RING_INDIRECT_DESC, !=, 0);
+    features = features & ~(QVIRTIO_F_BAD_FEATURE | QVIRTIO_F_RING_EVENT_IDX |
+                                                            QVIRTIO_BLK_F_SCSI);
     qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
 
     alloc = pc_alloc_init();
@@ -346,7 +359,7 @@ static void pci_indirect(void)
     qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
 
     /* Write request */
-    req.type = VIRTIO_BLK_T_OUT;
+    req.type = QVIRTIO_BLK_T_OUT;
     req.ioprio = 1;
     req.sector = 0;
     req.data = g_malloc0(512);
@@ -371,7 +384,7 @@ static void pci_indirect(void)
     guest_free(alloc, req_addr);
 
     /* Read request */
-    req.type = VIRTIO_BLK_T_IN;
+    req.type = QVIRTIO_BLK_T_IN;
     req.ioprio = 1;
     req.sector = 0;
     req.data = g_malloc0(512);
@@ -401,7 +414,7 @@ static void pci_indirect(void)
     guest_free(alloc, req_addr);
 
     /* End test */
-    qvirtqueue_cleanup(&qvirtio_pci, &vqpci->vq, alloc);
+    guest_free(alloc, vqpci->vq.desc);
     pc_alloc_uninit(alloc);
     qvirtio_pci_device_disable(dev);
     g_free(dev);
@@ -422,7 +435,7 @@ static void pci_config(void)
     dev = virtio_blk_pci_init(bus, PCI_SLOT);
 
     /* MSI-X is not enabled */
-    addr = dev->addr + VIRTIO_PCI_CONFIG_OFF(false);
+    addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_NO_MSIX;
 
     capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
                                                     (uint64_t)(uintptr_t)addr);
@@ -469,7 +482,7 @@ static void pci_msix(void)
     qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0);
 
     /* MSI-X is enabled */
-    addr = dev->addr + VIRTIO_PCI_CONFIG_OFF(true);
+    addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_MSIX;
 
     capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
                                                     (uint64_t)(uintptr_t)addr);
@@ -477,9 +490,8 @@ static void pci_msix(void)
 
     features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
     features = features & ~(QVIRTIO_F_BAD_FEATURE |
-                            (1u << VIRTIO_RING_F_INDIRECT_DESC) |
-                            (1u << VIRTIO_RING_F_EVENT_IDX) |
-                            (1u << VIRTIO_BLK_F_SCSI));
+                            QVIRTIO_F_RING_INDIRECT_DESC |
+                            QVIRTIO_F_RING_EVENT_IDX | QVIRTIO_BLK_F_SCSI);
     qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
 
     vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
@@ -498,7 +510,7 @@ static void pci_msix(void)
     g_assert_cmpint(capacity, ==, n_size / 512);
 
     /* Write request */
-    req.type = VIRTIO_BLK_T_OUT;
+    req.type = QVIRTIO_BLK_T_OUT;
     req.ioprio = 1;
     req.sector = 0;
     req.data = g_malloc0(512);
@@ -522,7 +534,7 @@ static void pci_msix(void)
     guest_free(alloc, req_addr);
 
     /* Read request */
-    req.type = VIRTIO_BLK_T_IN;
+    req.type = QVIRTIO_BLK_T_IN;
     req.ioprio = 1;
     req.sector = 0;
     req.data = g_malloc0(512);
@@ -552,7 +564,7 @@ static void pci_msix(void)
     guest_free(alloc, req_addr);
 
     /* End test */
-    qvirtqueue_cleanup(&qvirtio_pci, &vqpci->vq, alloc);
+    guest_free(alloc, vqpci->vq.desc);
     pc_alloc_uninit(alloc);
     qpci_msix_disable(dev->pdev);
     qvirtio_pci_device_disable(dev);
@@ -585,7 +597,7 @@ static void pci_idx(void)
     qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0);
 
     /* MSI-X is enabled */
-    addr = dev->addr + VIRTIO_PCI_CONFIG_OFF(true);
+    addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_MSIX;
 
     capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
                                                     (uint64_t)(uintptr_t)addr);
@@ -593,9 +605,8 @@ static void pci_idx(void)
 
     features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
     features = features & ~(QVIRTIO_F_BAD_FEATURE |
-                            (1u << VIRTIO_RING_F_INDIRECT_DESC) |
-                            (1u << VIRTIO_F_NOTIFY_ON_EMPTY) |
-                            (1u << VIRTIO_BLK_F_SCSI));
+                            QVIRTIO_F_RING_INDIRECT_DESC |
+                            QVIRTIO_F_NOTIFY_ON_EMPTY | QVIRTIO_BLK_F_SCSI);
     qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
 
     vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
@@ -605,7 +616,7 @@ static void pci_idx(void)
     qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
 
     /* Write request */
-    req.type = VIRTIO_BLK_T_OUT;
+    req.type = QVIRTIO_BLK_T_OUT;
     req.ioprio = 1;
     req.sector = 0;
     req.data = g_malloc0(512);
@@ -624,7 +635,7 @@ static void pci_idx(void)
                            QVIRTIO_BLK_TIMEOUT_US);
 
     /* Write request */
-    req.type = VIRTIO_BLK_T_OUT;
+    req.type = QVIRTIO_BLK_T_OUT;
     req.ioprio = 1;
     req.sector = 1;
     req.data = g_malloc0(512);
@@ -650,7 +661,7 @@ static void pci_idx(void)
     guest_free(alloc, req_addr);
 
     /* Read request */
-    req.type = VIRTIO_BLK_T_IN;
+    req.type = QVIRTIO_BLK_T_IN;
     req.ioprio = 1;
     req.sector = 1;
     req.data = g_malloc0(512);
@@ -679,7 +690,7 @@ static void pci_idx(void)
     guest_free(alloc, req_addr);
 
     /* End test */
-    qvirtqueue_cleanup(&qvirtio_pci, &vqpci->vq, alloc);
+    guest_free(alloc, vqpci->vq.desc);
     pc_alloc_uninit(alloc);
     qpci_msix_disable(dev->pdev);
     qvirtio_pci_device_disable(dev);
@@ -722,7 +733,7 @@ static void mmio_basic(void)
 
     dev = qvirtio_mmio_init_device(MMIO_DEV_BASE_ADDR, MMIO_PAGE_SIZE);
     g_assert(dev != NULL);
-    g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_BLOCK);
+    g_assert_cmphex(dev->vdev.device_type, ==, QVIRTIO_BLK_DEVICE_ID);
 
     qvirtio_reset(&qvirtio_mmio, &dev->vdev);
     qvirtio_set_acknowledge(&qvirtio_mmio, &dev->vdev);
@@ -745,7 +756,7 @@ static void mmio_basic(void)
     g_assert_cmpint(capacity, ==, n_size / 512);
 
     /* End test */
-    qvirtqueue_cleanup(&qvirtio_mmio, vq, alloc);
+    guest_free(alloc, vq->desc);
     generic_alloc_uninit(alloc);
     g_free(dev);
     test_end();
@@ -753,6 +764,7 @@ static void mmio_basic(void)
 
 int main(int argc, char **argv)
 {
+    int ret;
     const char *arch = qtest_get_arch();
 
     g_test_init(&argc, &argv, NULL);
@@ -768,5 +780,7 @@ int main(int argc, char **argv)
         qtest_add_func("/virtio/blk/mmio/basic", mmio_basic);
     }
 
-    return g_test_run();
+    ret = g_test_run();
+
+    return ret;
 }
index 1c3de07..0b9c2a5 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
@@ -27,9 +28,13 @@ static void serialport_pci_nop(void)
 
 int main(int argc, char **argv)
 {
+    int ret;
+
     g_test_init(&argc, &argv, NULL);
     qtest_add_func("/virtio/console/pci/nop", console_pci_nop);
     qtest_add_func("/virtio/serialport/pci/nop", serialport_pci_nop);
 
-    return g_test_run();
+    ret = g_test_run();
+
+    return ret;
 }
index 361506f..04cfcd5 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "qemu-common.h"
 #include "qemu/sockets.h"
@@ -20,8 +21,6 @@
 #include "libqos/malloc-generic.h"
 #include "qemu/bswap.h"
 #include "hw/virtio/virtio-net.h"
-#include "standard-headers/linux/virtio_ids.h"
-#include "standard-headers/linux/virtio_ring.h"
 
 #define PCI_SLOT_HP             0x06
 #define PCI_SLOT                0x04
@@ -41,9 +40,9 @@ static QVirtioPCIDevice *virtio_net_pci_init(QPCIBus *bus, int slot)
 {
     QVirtioPCIDevice *dev;
 
-    dev = qvirtio_pci_device_find(bus, VIRTIO_ID_NET);
+    dev = qvirtio_pci_device_find(bus, QVIRTIO_NET_DEVICE_ID);
     g_assert(dev != NULL);
-    g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_NET);
+    g_assert_cmphex(dev->vdev.device_type, ==, QVIRTIO_NET_DEVICE_ID);
 
     qvirtio_pci_device_enable(dev);
     qvirtio_reset(&qvirtio_pci, &dev->vdev);
@@ -71,8 +70,8 @@ static void driver_init(const QVirtioBus *bus, QVirtioDevice *dev)
 
     features = qvirtio_get_features(bus, dev);
     features = features & ~(QVIRTIO_F_BAD_FEATURE |
-                            (1u << VIRTIO_RING_F_INDIRECT_DESC) |
-                            (1u << VIRTIO_RING_F_EVENT_IDX));
+                            QVIRTIO_F_RING_INDIRECT_DESC |
+                            QVIRTIO_F_RING_EVENT_IDX);
     qvirtio_set_features(bus, dev, features);
 
     qvirtio_set_driver_ok(bus, dev);
@@ -149,7 +148,6 @@ static void rx_stop_cont_test(const QVirtioBus *bus, QVirtioDevice *dev,
     char test[] = "TEST";
     char buffer[64];
     int len = htonl(sizeof(test));
-    QDict *rsp;
     struct iovec iov[] = {
         {
             .iov_base = &len,
@@ -166,8 +164,7 @@ static void rx_stop_cont_test(const QVirtioBus *bus, QVirtioDevice *dev,
     free_head = qvirtqueue_add(vq, req_addr, 64, true, false);
     qvirtqueue_kick(bus, dev, vq, free_head);
 
-    rsp = qmp("{ 'execute' : 'stop'}");
-    QDECREF(rsp);
+    qmp("{ 'execute' : 'stop'}");
 
     ret = iov_send(socket, iov, 2, 0, sizeof(len) + sizeof(test));
     g_assert_cmpint(ret, ==, sizeof(test) + sizeof(len));
@@ -175,10 +172,8 @@ static void rx_stop_cont_test(const QVirtioBus *bus, QVirtioDevice *dev,
     /* We could check the status, but this command is more importantly to
      * ensure the packet data gets queued in QEMU, before we do 'cont'.
      */
-    rsp = qmp("{ 'execute' : 'query-status'}");
-    QDECREF(rsp);
-    rsp = qmp("{ 'execute' : 'cont'}");
-    QDECREF(rsp);
+    qmp("{ 'execute' : 'query-status'}");
+    qmp("{ 'execute' : 'cont'}");
 
     qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_NET_TIMEOUT_US);
     memread(req_addr + VNET_HDR_SIZE, buffer, sizeof(test));
@@ -233,11 +228,9 @@ static void pci_basic(gconstpointer data)
 
     /* End test */
     close(sv[0]);
-    qvirtqueue_cleanup(&qvirtio_pci, &tx->vq, alloc);
-    qvirtqueue_cleanup(&qvirtio_pci, &rx->vq, alloc);
+    guest_free(alloc, tx->vq.desc);
     pc_alloc_uninit(alloc);
     qvirtio_pci_device_disable(dev);
-    g_free(dev->pdev);
     g_free(dev);
     qpci_free_pc(bus);
     test_end();
@@ -256,6 +249,8 @@ static void hotplug(void)
 
 int main(int argc, char **argv)
 {
+    int ret;
+
     g_test_init(&argc, &argv, NULL);
 #ifndef _WIN32
     qtest_add_data_func("/virtio/net/pci/basic", send_recv_test, pci_basic);
@@ -264,5 +259,7 @@ int main(int argc, char **argv)
 #endif
     qtest_add_func("/virtio/net/pci/hotplug", hotplug);
 
-    return g_test_run();
+    ret = g_test_run();
+
+    return ret;
 }
index e1b2640..771dbd7 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "libqos/pci.h"
 
index f1489e6..d78747a 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "block/scsi.h"
 #include "libqos/virtio.h"
 #include "libqos/malloc.h"
 #include "libqos/malloc-pc.h"
 #include "libqos/malloc-generic.h"
-#include "standard-headers/linux/virtio_ids.h"
-#include "standard-headers/linux/virtio_pci.h"
-#include "standard-headers/linux/virtio_scsi.h"
 
 #define PCI_SLOT                0x02
 #define PCI_FN                  0x00
 #define QVIRTIO_SCSI_TIMEOUT_US (1 * 1000 * 1000)
+#define CDB_SIZE 32
 
 #define MAX_NUM_QUEUES 64
 
@@ -35,6 +34,24 @@ typedef struct {
     QVirtQueue *vq[MAX_NUM_QUEUES + 2];
 } QVirtIOSCSI;
 
+typedef struct {
+    uint8_t lun[8];
+    int64_t tag;
+    uint8_t task_attr;
+    uint8_t prio;
+    uint8_t crn;
+    uint8_t cdb[CDB_SIZE];
+} QEMU_PACKED QVirtIOSCSICmdReq;
+
+typedef struct {
+    uint32_t sense_len;
+    uint32_t resid;
+    uint16_t status_qualifier;
+    uint8_t status;
+    uint8_t response;
+    uint8_t sense[96];
+} QEMU_PACKED QVirtIOSCSICmdResp;
+
 static void qvirtio_scsi_start(const char *extra_opts)
 {
     char *cmdline;
@@ -58,7 +75,7 @@ static void qvirtio_scsi_pci_free(QVirtIOSCSI *vs)
     int i;
 
     for (i = 0; i < vs->num_queues + 2; i++) {
-        qvirtqueue_cleanup(&qvirtio_pci, vs->vq[i], vs->alloc);
+        guest_free(vs->alloc, vs->vq[i]->desc);
     }
     pc_alloc_uninit(vs->alloc);
     qvirtio_pci_device_disable(container_of(vs->dev, QVirtioPCIDevice, vdev));
@@ -83,11 +100,11 @@ static uint8_t virtio_scsi_do_command(QVirtIOSCSI *vs, const uint8_t *cdb,
                                       const uint8_t *data_in,
                                       size_t data_in_len,
                                       uint8_t *data_out, size_t data_out_len,
-                                      struct virtio_scsi_cmd_resp *resp_out)
+                                      QVirtIOSCSICmdResp *resp_out)
 {
     QVirtQueue *vq;
-    struct virtio_scsi_cmd_req req = { { 0 } };
-    struct virtio_scsi_cmd_resp resp = { .response = 0xff, .status = 0xff };
+    QVirtIOSCSICmdReq req = { { 0 } };
+    QVirtIOSCSICmdResp resp = { .response = 0xff, .status = 0xff };
     uint64_t req_addr, resp_addr, data_in_addr = 0, data_out_addr = 0;
     uint8_t response;
     uint32_t free_head;
@@ -96,7 +113,7 @@ static uint8_t virtio_scsi_do_command(QVirtIOSCSI *vs, const uint8_t *cdb,
 
     req.lun[0] = 1; /* Select LUN */
     req.lun[1] = 1; /* Select target 1 */
-    memcpy(req.cdb, cdb, VIRTIO_SCSI_CDB_SIZE);
+    memcpy(req.cdb, cdb, CDB_SIZE);
 
     /* XXX: Fix endian if any multi-byte field in req/resp is used */
 
@@ -121,8 +138,7 @@ static uint8_t virtio_scsi_do_command(QVirtIOSCSI *vs, const uint8_t *cdb,
     qvirtqueue_kick(&qvirtio_pci, vs->dev, vq, free_head);
     qvirtio_wait_queue_isr(&qvirtio_pci, vs->dev, vq, QVIRTIO_SCSI_TIMEOUT_US);
 
-    response = readb(resp_addr +
-                     offsetof(struct virtio_scsi_cmd_resp, response));
+    response = readb(resp_addr + offsetof(QVirtIOSCSICmdResp, response));
 
     if (resp_out) {
         memread(resp_addr, resp_out, sizeof(*resp_out));
@@ -137,10 +153,10 @@ static uint8_t virtio_scsi_do_command(QVirtIOSCSI *vs, const uint8_t *cdb,
 
 static QVirtIOSCSI *qvirtio_scsi_pci_init(int slot)
 {
-    const uint8_t test_unit_ready_cdb[VIRTIO_SCSI_CDB_SIZE] = {};
+    const uint8_t test_unit_ready_cdb[CDB_SIZE] = {};
     QVirtIOSCSI *vs;
     QVirtioPCIDevice *dev;
-    struct virtio_scsi_cmd_resp resp;
+    QVirtIOSCSICmdResp resp;
     void *addr;
     int i;
 
@@ -148,17 +164,17 @@ static QVirtIOSCSI *qvirtio_scsi_pci_init(int slot)
     vs->alloc = pc_alloc_init();
     vs->bus = qpci_init_pc();
 
-    dev = qvirtio_pci_device_find(vs->bus, VIRTIO_ID_SCSI);
+    dev = qvirtio_pci_device_find(vs->bus, QVIRTIO_SCSI_DEVICE_ID);
     vs->dev = (QVirtioDevice *)dev;
     g_assert(dev != NULL);
-    g_assert_cmphex(vs->dev->device_type, ==, VIRTIO_ID_SCSI);
+    g_assert_cmphex(vs->dev->device_type, ==, QVIRTIO_SCSI_DEVICE_ID);
 
     qvirtio_pci_device_enable(dev);
     qvirtio_reset(&qvirtio_pci, vs->dev);
     qvirtio_set_acknowledge(&qvirtio_pci, vs->dev);
     qvirtio_set_driver(&qvirtio_pci, vs->dev);
 
-    addr = dev->addr + VIRTIO_PCI_CONFIG_OFF(false);
+    addr = dev->addr + QVIRTIO_PCI_DEVICE_SPECIFIC_NO_MSIX;
     vs->num_queues = qvirtio_config_readl(&qvirtio_pci, vs->dev,
                                           (uint64_t)(uintptr_t)addr);
 
@@ -223,12 +239,10 @@ static void test_unaligned_write_same(void)
     QVirtIOSCSI *vs;
     uint8_t buf1[512] = { 0 };
     uint8_t buf2[512] = { 1 };
-    const uint8_t write_same_cdb_1[VIRTIO_SCSI_CDB_SIZE] = {
-        0x41, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00
-    };
-    const uint8_t write_same_cdb_2[VIRTIO_SCSI_CDB_SIZE] = {
-        0x41, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x33, 0x00, 0x00
-    };
+    const uint8_t write_same_cdb_1[CDB_SIZE] = { 0x41, 0x00, 0x00, 0x00, 0x00,
+                                               0x01, 0x00, 0x00, 0x02, 0x00 };
+    const uint8_t write_same_cdb_2[CDB_SIZE] = { 0x41, 0x00, 0x00, 0x00, 0x00,
+                                               0x01, 0x00, 0x33, 0x00, 0x00 };
 
     qvirtio_scsi_start("-drive file=blkdebug::null-co://,if=none,id=dr1"
                        ",format=raw,file.align=4k "
@@ -247,11 +261,15 @@ static void test_unaligned_write_same(void)
 
 int main(int argc, char **argv)
 {
+    int ret;
+
     g_test_init(&argc, &argv, NULL);
     qtest_add_func("/virtio/scsi/pci/nop", pci_nop);
     qtest_add_func("/virtio/scsi/pci/hotplug", hotplug);
     qtest_add_func("/virtio/scsi/pci/scsi-disk/unaligned-write-same",
                    test_unaligned_write_same);
 
-    return g_test_run();
+    ret = g_test_run();
+
+    return ret;
 }
index b14d943..480d4ab 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
index 159c0ad..6ef0e2f 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
index 49f4f0c..efe3370 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "libqtest.h"
 #include "qemu/timer.h"
 
@@ -117,11 +118,15 @@ static void ib700_none(void)
 
 int main(int argc, char **argv)
 {
+    int ret;
+
     g_test_init(&argc, &argv, NULL);
     qtest_add_func("/wdt_ib700/pause", ib700_pause);
     qtest_add_func("/wdt_ib700/reset", ib700_reset);
     qtest_add_func("/wdt_ib700/shutdown", ib700_shutdown);
     qtest_add_func("/wdt_ib700/none", ib700_none);
 
-    return g_test_run();
+    ret = g_test_run();
+
+    return ret;
 }
index 6fba913..03ba0b0 100644 (file)
@@ -267,7 +267,7 @@ static void thread_pool_co_cb(void *opaque, int ret)
     ThreadPoolCo *co = opaque;
 
     co->ret = ret;
-    qemu_coroutine_enter(co->co);
+    qemu_coroutine_enter(co->co, NULL);
 }
 
 int coroutine_fn thread_pool_submit_co(ThreadPool *pool, ThreadPoolFunc *func,
diff --git a/thunk.c b/thunk.c
index 2dac366..f057d86 100644 (file)
--- a/thunk.c
+++ b/thunk.c
@@ -273,36 +273,37 @@ const argtype *thunk_convert(void *dst, const void *src,
 /* from em86 */
 
 /* Utility function: Table-driven functions to translate bitmasks
- * between host and target formats
+ * between X86 and Alpha formats...
  */
-unsigned int target_to_host_bitmask(unsigned int target_mask,
+unsigned int target_to_host_bitmask(unsigned int x86_mask,
                                     const bitmask_transtbl * trans_tbl)
 {
     const bitmask_transtbl *btp;
-    unsigned int host_mask = 0;
+    unsigned int       alpha_mask = 0;
 
-    for (btp = trans_tbl; btp->target_mask && btp->host_mask; btp++) {
-        if ((target_mask & btp->target_mask) == btp->target_bits) {
-            host_mask |= btp->host_bits;
-        }
+    for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
+       if((x86_mask & btp->x86_mask) == btp->x86_bits) {
+           alpha_mask |= btp->alpha_bits;
+       }
     }
-    return host_mask;
+    return(alpha_mask);
 }
 
-unsigned int host_to_target_bitmask(unsigned int host_mask,
+unsigned int host_to_target_bitmask(unsigned int alpha_mask,
                                     const bitmask_transtbl * trans_tbl)
 {
     const bitmask_transtbl *btp;
-    unsigned int target_mask = 0;
+    unsigned int       x86_mask = 0;
 
-    for (btp = trans_tbl; btp->target_mask && btp->host_mask; btp++) {
-        if ((host_mask & btp->host_mask) == btp->host_bits) {
-            target_mask |= btp->target_bits;
-        }
+    for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
+       if((alpha_mask & btp->alpha_mask) == btp->alpha_bits) {
+           x86_mask |= btp->x86_bits;
+       }
     }
-    return target_mask;
+    return(x86_mask);
 }
 
+#ifndef NO_THUNK_TYPE_SIZE
 int thunk_type_size_array(const argtype *type_ptr, int is_host)
 {
     return thunk_type_size(type_ptr, is_host);
@@ -312,6 +313,7 @@ int thunk_type_align_array(const argtype *type_ptr, int is_host)
 {
     return thunk_type_align(type_ptr, is_host);
 }
+#endif /* ndef NO_THUNK_TYPE_SIZE */
 
 void thunk_init(unsigned int max_structs)
 {
index 616cc52..8350743 100644 (file)
 #
 # The <format-string> should be a sprintf()-compatible format string.
 
+# util/oslib-win32.c
+# util/oslib-posix.c
+qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu ptr %p"
+qemu_anon_ram_alloc(size_t size, void *ptr) "size %zu ptr %p"
+qemu_vfree(void *ptr) "ptr %p"
+qemu_anon_ram_free(void *ptr, size_t size) "ptr %p size %zu"
+
+# hw/virtio/virtio.c
+virtqueue_fill(void *vq, const void *elem, unsigned int len, unsigned int idx) "vq %p elem %p len %u idx %u"
+virtqueue_flush(void *vq, unsigned int count) "vq %p count %u"
+virtqueue_pop(void *vq, void *elem, unsigned int in_num, unsigned int out_num) "vq %p elem %p in_num %u out_num %u"
+virtio_queue_notify(void *vdev, int n, void *vq) "vdev %p n %d vq %p"
+virtio_irq(void *vq) "vq %p"
+virtio_notify(void *vdev, void *vq) "vdev %p vq %p"
+virtio_set_status(void *vdev, uint8_t val) "vdev %p val %u"
+
+# hw/virtio/virtio-rng.c
+virtio_rng_guest_not_ready(void *rng) "rng %p: guest not ready"
+virtio_rng_pushed(void *rng, size_t len) "rng %p: %zd bytes pushed"
+virtio_rng_request(void *rng, size_t size, unsigned quota) "rng %p: %zd bytes requested, %u bytes quota left"
+
+# hw/char/virtio-serial-bus.c
+virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t value) "port %u, event %u, value %u"
+virtio_serial_throttle_port(unsigned int port, bool throttle) "port %u, throttle %d"
+virtio_serial_handle_control_message(uint16_t event, uint16_t value) "event %u, value %u"
+virtio_serial_handle_control_message_port(unsigned int port) "port %u"
+
+# hw/char/virtio-console.c
+virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret) "port %u, in_len %zu, out_len %zd"
+virtio_console_chr_read(unsigned int port, int size) "port %u, size %d"
+virtio_console_chr_event(unsigned int port, int event) "port %u, event %d"
+
+# block.c
+bdrv_open_common(void *bs, const char *filename, int flags, const char *format_name) "bs %p filename \"%s\" flags %#x format_name \"%s\""
+bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
+
+# block/io.c
+multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
+bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d"
+bdrv_aio_discard(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
+bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
+bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
+bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
+bdrv_aio_write_zeroes(void *bs, int64_t sector_num, int nb_sectors, int flags, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d flags %#x opaque %p"
+bdrv_co_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
+bdrv_co_copy_on_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
+bdrv_co_readv_no_serialising(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
+bdrv_co_writev(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
+bdrv_co_write_zeroes(void *bs, int64_t sector_num, int nb_sector, int flags) "bs %p sector_num %"PRId64" nb_sectors %d flags %#x"
+bdrv_co_io_em(void *bs, int64_t sector_num, int nb_sectors, int is_write, void *acb) "bs %p sector_num %"PRId64" nb_sectors %d is_write %d acb %p"
+bdrv_co_do_copy_on_readv(void *bs, int64_t sector_num, int nb_sectors, int64_t cluster_sector_num, int cluster_nb_sectors) "bs %p sector_num %"PRId64" nb_sectors %d cluster_sector_num %"PRId64" cluster_nb_sectors %d"
+
+# block/stream.c
+stream_one_iteration(void *s, int64_t sector_num, int nb_sectors, int is_allocated) "s %p sector_num %"PRId64" nb_sectors %d is_allocated %d"
+stream_start(void *bs, void *base, void *s, void *co, void *opaque) "bs %p base %p s %p co %p opaque %p"
+
+# block/commit.c
+commit_one_iteration(void *s, int64_t sector_num, int nb_sectors, int is_allocated) "s %p sector_num %"PRId64" nb_sectors %d is_allocated %d"
+commit_start(void *bs, void *base, void *top, void *s, void *co, void *opaque) "bs %p base %p top %p s %p co %p opaque %p"
+
+# block/mirror.c
+mirror_start(void *bs, void *s, void *co, void *opaque) "bs %p s %p co %p opaque %p"
+mirror_restart_iter(void *s, int64_t cnt) "s %p dirty count %"PRId64
+mirror_before_flush(void *s) "s %p"
+mirror_before_drain(void *s, int64_t cnt) "s %p dirty count %"PRId64
+mirror_before_sleep(void *s, int64_t cnt, int synced, uint64_t delay_ns) "s %p dirty count %"PRId64" synced %d delay %"PRIu64"ns"
+mirror_one_iteration(void *s, int64_t sector_num, int nb_sectors) "s %p sector_num %"PRId64" nb_sectors %d"
+mirror_iteration_done(void *s, int64_t sector_num, int nb_sectors, int ret) "s %p sector_num %"PRId64" nb_sectors %d ret %d"
+mirror_yield(void *s, int64_t cnt, int buf_free_count, int in_flight) "s %p dirty count %"PRId64" free buffers %d in_flight %d"
+mirror_yield_in_flight(void *s, int64_t sector_num, int in_flight) "s %p sector_num %"PRId64" in_flight %d"
+mirror_yield_buf_busy(void *s, int nb_chunks, int in_flight) "s %p requested chunks %d in_flight %d"
+mirror_break_buf_busy(void *s, int nb_chunks, int in_flight) "s %p requested chunks %d in_flight %d"
+
+# block/backup.c
+backup_do_cow_enter(void *job, int64_t start, int64_t sector_num, int nb_sectors) "job %p start %"PRId64" sector_num %"PRId64" nb_sectors %d"
+backup_do_cow_return(void *job, int64_t sector_num, int nb_sectors, int ret) "job %p sector_num %"PRId64" nb_sectors %d ret %d"
+backup_do_cow_skip(void *job, int64_t start) "job %p start %"PRId64
+backup_do_cow_process(void *job, int64_t start) "job %p start %"PRId64
+backup_do_cow_read_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d"
+backup_do_cow_write_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d"
+
+# blockdev.c
+qmp_block_job_cancel(void *job) "job %p"
+qmp_block_job_pause(void *job) "job %p"
+qmp_block_job_resume(void *job) "job %p"
+qmp_block_job_complete(void *job) "job %p"
+block_job_cb(void *bs, void *job, int ret) "bs %p job %p ret %d"
+qmp_block_stream(void *bs, void *job) "bs %p job %p"
+
+# hw/block/virtio-blk.c
+virtio_blk_req_complete(void *req, int status) "req %p status %d"
+virtio_blk_rw_complete(void *req, int ret) "req %p ret %d"
+virtio_blk_handle_write(void *req, uint64_t sector, size_t nsectors) "req %p sector %"PRIu64" nsectors %zu"
+virtio_blk_handle_read(void *req, uint64_t sector, size_t nsectors) "req %p sector %"PRIu64" nsectors %zu"
+virtio_blk_submit_multireq(void *mrb, int start, int num_reqs, uint64_t sector, size_t nsectors, bool is_write) "mrb %p start %d num_reqs %d sector %"PRIu64" nsectors %zu is_write %d"
+
+# hw/block/dataplane/virtio-blk.c
+virtio_blk_data_plane_start(void *s) "dataplane %p"
+virtio_blk_data_plane_stop(void *s) "dataplane %p"
+virtio_blk_data_plane_process_request(void *s, unsigned int out_num, unsigned int in_num, unsigned int head) "dataplane %p out_num %u in_num %u head %u"
+
 # thread-pool.c
 thread_pool_submit(void *pool, void *req, void *opaque) "pool %p req %p opaque %p"
 thread_pool_complete(void *pool, void *req, void *opaque, int ret) "pool %p req %p opaque %p ret %d"
 thread_pool_cancel(void *req, void *opaque) "req %p opaque %p"
 
+# block/raw-win32.c
+# block/raw-posix.c
+paio_submit_co(int64_t sector_num, int nb_sectors, int type) "sector_num %"PRId64" nb_sectors %d type %d"
+paio_submit(void *acb, void *opaque, int64_t sector_num, int nb_sectors, int type) "acb %p opaque %p sector_num %"PRId64" nb_sectors %d type %d"
+
 # ioport.c
 cpu_in(unsigned int addr, char size, unsigned int val) "addr %#x(%c) value %u"
 cpu_out(unsigned int addr, char size, unsigned int val) "addr %#x(%c) value %u"
@@ -42,6 +148,457 @@ virtio_balloon_get_config(uint32_t num_pages, uint32_t actual) "num_pages: %d ac
 virtio_balloon_set_config(uint32_t actual, uint32_t oldactual) "actual: %d oldactual: %d"
 virtio_balloon_to_target(uint64_t target, uint32_t num_pages) "balloon target: %"PRIx64" num_pages: %d"
 
+# hw/intc/apic_common.c
+cpu_set_apic_base(uint64_t val) "%016"PRIx64
+cpu_get_apic_base(uint64_t val) "%016"PRIx64
+# coalescing
+apic_report_irq_delivered(int apic_irq_delivered) "coalescing %d"
+apic_reset_irq_delivered(int apic_irq_delivered) "old coalescing %d"
+apic_get_irq_delivered(int apic_irq_delivered) "returning coalescing %d"
+
+# hw/intc/apic.c
+apic_local_deliver(int vector, uint32_t lvt) "vector %d delivery mode %d"
+apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, uint8_t trigger_mode) "dest %d dest_mode %d delivery_mode %d vector %d trigger_mode %d"
+apic_mem_readl(uint64_t addr, uint32_t val)  "%"PRIx64" = %08x"
+apic_mem_writel(uint64_t addr, uint32_t val) "%"PRIx64" = %08x"
+
+# hw/audio/cs4231.c
+cs4231_mem_readl_dreg(uint32_t reg, uint32_t ret) "read dreg %d: 0x%02x"
+cs4231_mem_readl_reg(uint32_t reg, uint32_t ret) "read reg %d: 0x%08x"
+cs4231_mem_writel_reg(uint32_t reg, uint32_t old, uint32_t val) "write reg %d: 0x%08x -> 0x%08x"
+cs4231_mem_writel_dreg(uint32_t reg, uint32_t old, uint32_t val) "write dreg %d: 0x%02x -> 0x%02x"
+
+# hw/nvram/ds1225y.c
+nvram_read(uint32_t addr, uint32_t ret) "read addr %d: 0x%02x"
+nvram_write(uint32_t addr, uint32_t old, uint32_t val) "write addr %d: 0x%02x -> 0x%02x"
+
+# hw/misc/eccmemctl.c
+ecc_mem_writel_mer(uint32_t val) "Write memory enable %08x"
+ecc_mem_writel_mdr(uint32_t val) "Write memory delay %08x"
+ecc_mem_writel_mfsr(uint32_t val) "Write memory fault status %08x"
+ecc_mem_writel_vcr(uint32_t val) "Write slot configuration %08x"
+ecc_mem_writel_dr(uint32_t val) "Write diagnostic %08x"
+ecc_mem_writel_ecr0(uint32_t val) "Write event count 1 %08x"
+ecc_mem_writel_ecr1(uint32_t val) "Write event count 2 %08x"
+ecc_mem_readl_mer(uint32_t ret) "Read memory enable %08x"
+ecc_mem_readl_mdr(uint32_t ret) "Read memory delay %08x"
+ecc_mem_readl_mfsr(uint32_t ret) "Read memory fault status %08x"
+ecc_mem_readl_vcr(uint32_t ret) "Read slot configuration %08x"
+ecc_mem_readl_mfar0(uint32_t ret) "Read memory fault address 0 %08x"
+ecc_mem_readl_mfar1(uint32_t ret) "Read memory fault address 1 %08x"
+ecc_mem_readl_dr(uint32_t ret) "Read diagnostic %08x"
+ecc_mem_readl_ecr0(uint32_t ret) "Read event count 1 %08x"
+ecc_mem_readl_ecr1(uint32_t ret) "Read event count 2 %08x"
+ecc_diag_mem_writeb(uint64_t addr, uint32_t val) "Write diagnostic %"PRId64" = %02x"
+ecc_diag_mem_readb(uint64_t addr, uint32_t ret) "Read diagnostic %"PRId64"= %02x"
+
+# hw/nvram/fw_cfg.c
+fw_cfg_select(void *s, uint16_t key, int ret) "%p key %d = %d"
+fw_cfg_read(void *s, uint64_t ret) "%p = %"PRIx64
+fw_cfg_add_file(void *s, int index, char *name, size_t len) "%p #%d: %s (%zd bytes)"
+
+# hw/block/hd-geometry.c
+hd_geometry_lchs_guess(void *blk, int cyls, int heads, int secs) "blk %p LCHS %d %d %d"
+hd_geometry_guess(void *blk, uint32_t cyls, uint32_t heads, uint32_t secs, int trans) "blk %p CHS %u %u %u trans %d"
+
+# hw/display/jazz_led.c
+jazz_led_read(uint64_t addr, uint8_t val) "read addr=0x%"PRIx64": 0x%x"
+jazz_led_write(uint64_t addr, uint8_t new) "write addr=0x%"PRIx64": 0x%x"
+
+# hw/display/xenfb.c
+xenfb_mouse_event(void *opaque, int dx, int dy, int dz, int button_state, int abs_pointer_wanted) "%p x %d y %d z %d bs %#x abs %d"
+xenfb_input_connected(void *xendev, int abs_pointer_wanted) "%p abs %d"
+
+# hw/net/lance.c
+lance_mem_readw(uint64_t addr, uint32_t ret) "addr=%"PRIx64"val=0x%04x"
+lance_mem_writew(uint64_t addr, uint32_t val) "addr=%"PRIx64"val=0x%04x"
+
+# hw/intc/slavio_intctl.c
+slavio_intctl_mem_readl(uint32_t cpu, uint64_t addr, uint32_t ret) "read cpu %d reg 0x%"PRIx64" = %x"
+slavio_intctl_mem_writel(uint32_t cpu, uint64_t addr, uint32_t val) "write cpu %d reg 0x%"PRIx64" = %x"
+slavio_intctl_mem_writel_clear(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Cleared cpu %d irq mask %x, curmask %x"
+slavio_intctl_mem_writel_set(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Set cpu %d irq mask %x, curmask %x"
+slavio_intctlm_mem_readl(uint64_t addr, uint32_t ret) "read system reg 0x%"PRIx64" = %x"
+slavio_intctlm_mem_writel(uint64_t addr, uint32_t val) "write system reg 0x%"PRIx64" = %x"
+slavio_intctlm_mem_writel_enable(uint32_t val, uint32_t intregm_disabled) "Enabled master irq mask %x, curmask %x"
+slavio_intctlm_mem_writel_disable(uint32_t val, uint32_t intregm_disabled) "Disabled master irq mask %x, curmask %x"
+slavio_intctlm_mem_writel_target(uint32_t cpu) "Set master irq cpu %d"
+slavio_check_interrupts(uint32_t pending, uint32_t intregm_disabled) "pending %x disabled %x"
+slavio_set_irq(uint32_t target_cpu, int irq, uint32_t pil, int level) "Set cpu %d irq %d -> pil %d level %d"
+slavio_set_timer_irq_cpu(int cpu, int level) "Set cpu %d local timer level %d"
+
+# hw/input/ps2.c
+ps2_put_keycode(void *opaque, int keycode) "%p keycode %d"
+ps2_read_data(void *opaque) "%p"
+ps2_set_ledstate(void *s, int ledstate) "%p ledstate %d"
+ps2_reset_keyboard(void *s) "%p"
+ps2_write_keyboard(void *opaque, int val) "%p val %d"
+ps2_keyboard_set_translation(void *opaque, int mode) "%p mode %d"
+ps2_mouse_send_packet(void *s, int dx1, int dy1, int dz1, int b) "%p x %d y %d z %d bs %#x"
+ps2_mouse_event_disabled(void *opaque, int dx, int dy, int dz, int buttons_state, int mouse_dx, int mouse_dy, int mouse_dz) "%p x %d y %d z %d bs %#x mx %d my %d mz %d "
+ps2_mouse_event(void *opaque, int dx, int dy, int dz, int buttons_state, int mouse_dx, int mouse_dy, int mouse_dz) "%p x %d y %d z %d bs %#x mx %d my %d mz %d "
+ps2_mouse_fake_event(void *opaque) "%p"
+ps2_write_mouse(void *opaque, int val) "%p val %d"
+ps2_kbd_reset(void *opaque) "%p"
+ps2_mouse_reset(void *opaque) "%p"
+ps2_kbd_init(void *s) "%p"
+ps2_mouse_init(void *s) "%p"
+
+# hw/misc/slavio_misc.c
+slavio_misc_update_irq_raise(void) "Raise IRQ"
+slavio_misc_update_irq_lower(void) "Lower IRQ"
+slavio_set_power_fail(int power_failing, uint8_t config) "Power fail: %d, config: %d"
+slavio_cfg_mem_writeb(uint32_t val) "Write config %02x"
+slavio_cfg_mem_readb(uint32_t ret) "Read config %02x"
+slavio_diag_mem_writeb(uint32_t val) "Write diag %02x"
+slavio_diag_mem_readb(uint32_t ret) "Read diag %02x"
+slavio_mdm_mem_writeb(uint32_t val) "Write modem control %02x"
+slavio_mdm_mem_readb(uint32_t ret) "Read modem control %02x"
+slavio_aux1_mem_writeb(uint32_t val) "Write aux1 %02x"
+slavio_aux1_mem_readb(uint32_t ret) "Read aux1 %02x"
+slavio_aux2_mem_writeb(uint32_t val) "Write aux2 %02x"
+slavio_aux2_mem_readb(uint32_t ret) "Read aux2 %02x"
+apc_mem_writeb(uint32_t val) "Write power management %02x"
+apc_mem_readb(uint32_t ret) "Read power management %02x"
+slavio_sysctrl_mem_writel(uint32_t val) "Write system control %08x"
+slavio_sysctrl_mem_readl(uint32_t ret) "Read system control %08x"
+slavio_led_mem_writew(uint32_t val) "Write diagnostic LED %04x"
+slavio_led_mem_readw(uint32_t ret) "Read diagnostic LED %04x"
+
+# hw/timer/slavio_timer.c
+slavio_timer_get_out(uint64_t limit, uint32_t counthigh, uint32_t count) "limit %"PRIx64" count %x%08x"
+slavio_timer_irq(uint32_t counthigh, uint32_t count) "callback: count %x%08x"
+slavio_timer_mem_readl_invalid(uint64_t addr) "invalid read address %"PRIx64
+slavio_timer_mem_readl(uint64_t addr, uint32_t ret) "read %"PRIx64" = %08x"
+slavio_timer_mem_writel(uint64_t addr, uint32_t val) "write %"PRIx64" = %08x"
+slavio_timer_mem_writel_limit(unsigned int timer_index, uint64_t count) "processor %d user timer set to %016"PRIx64
+slavio_timer_mem_writel_counter_invalid(void) "not user timer"
+slavio_timer_mem_writel_status_start(unsigned int timer_index) "processor %d user timer started"
+slavio_timer_mem_writel_status_stop(unsigned int timer_index) "processor %d user timer stopped"
+slavio_timer_mem_writel_mode_user(unsigned int timer_index) "processor %d changed from counter to user timer"
+slavio_timer_mem_writel_mode_counter(unsigned int timer_index) "processor %d changed from user timer to counter"
+slavio_timer_mem_writel_mode_invalid(void) "not system timer"
+slavio_timer_mem_writel_invalid(uint64_t addr) "invalid write address %"PRIx64
+
+# hw/dma/rc4030.c
+jazzio_read(uint64_t addr, uint32_t ret) "read reg[0x%"PRIx64"] = 0x%x"
+jazzio_write(uint64_t addr, uint32_t val) "write reg[0x%"PRIx64"] = 0x%x"
+rc4030_read(uint64_t addr, uint32_t ret) "read reg[0x%"PRIx64"] = 0x%x"
+rc4030_write(uint64_t addr, uint32_t val) "write reg[0x%"PRIx64"] = 0x%x"
+
+# hw/dma/sparc32_dma.c
+ledma_memory_read(uint64_t addr) "DMA read addr 0x%"PRIx64
+ledma_memory_write(uint64_t addr) "DMA write addr 0x%"PRIx64
+sparc32_dma_set_irq_raise(void) "Raise IRQ"
+sparc32_dma_set_irq_lower(void) "Lower IRQ"
+espdma_memory_read(uint32_t addr) "DMA read addr 0x%08x"
+espdma_memory_write(uint32_t addr) "DMA write addr 0x%08x"
+sparc32_dma_mem_readl(uint64_t addr, uint32_t ret) "read dmareg %"PRIx64": 0x%08x"
+sparc32_dma_mem_writel(uint64_t addr, uint32_t old, uint32_t val) "write dmareg %"PRIx64": 0x%08x -> 0x%08x"
+sparc32_dma_enable_raise(void) "Raise DMA enable"
+sparc32_dma_enable_lower(void) "Lower DMA enable"
+
+# hw/sparc/sun4m.c
+sun4m_cpu_interrupt(unsigned int level) "Set CPU IRQ %d"
+sun4m_cpu_reset_interrupt(unsigned int level) "Reset CPU IRQ %d"
+sun4m_cpu_set_irq_raise(int level) "Raise CPU IRQ %d"
+sun4m_cpu_set_irq_lower(int level) "Lower CPU IRQ %d"
+
+# hw/dma/sun4m_iommu.c
+sun4m_iommu_mem_readl(uint64_t addr, uint32_t ret) "read reg[%"PRIx64"] = %x"
+sun4m_iommu_mem_writel(uint64_t addr, uint32_t val) "write reg[%"PRIx64"] = %x"
+sun4m_iommu_mem_writel_ctrl(uint64_t iostart) "iostart = %"PRIx64
+sun4m_iommu_mem_writel_tlbflush(uint32_t val) "tlb flush %x"
+sun4m_iommu_mem_writel_pgflush(uint32_t val) "page flush %x"
+sun4m_iommu_page_get_flags(uint64_t pa, uint64_t iopte, uint32_t ret) "get flags addr %"PRIx64" => pte %"PRIx64", *pte = %x"
+sun4m_iommu_translate_pa(uint64_t addr, uint64_t pa, uint32_t iopte) "xlate dva %"PRIx64" => pa %"PRIx64" iopte = %x"
+sun4m_iommu_bad_addr(uint64_t addr) "bad addr %"PRIx64
+
+# hw/usb/core.c
+usb_packet_state_change(int bus, const char *port, int ep, void *p, const char *o, const char *n) "bus %d, port %s, ep %d, packet %p, state %s -> %s"
+usb_packet_state_fault(int bus, const char *port, int ep, void *p, const char *o, const char *n) "bus %d, port %s, ep %d, packet %p, state %s, expected %s"
+
+# hw/usb/bus.c
+usb_port_claim(int bus, const char *port) "bus %d, port %s"
+usb_port_attach(int bus, const char *port, const char *devspeed, const char *portspeed) "bus %d, port %s, devspeed %s, portspeed %s"
+usb_port_detach(int bus, const char *port) "bus %d, port %s"
+usb_port_release(int bus, const char *port) "bus %d, port %s"
+
+# hw/usb/hcd-ohci.c
+usb_ohci_iso_td_read_failed(uint32_t addr) "ISO_TD read error at %x"
+usb_ohci_iso_td_head(uint32_t head, uint32_t tail, uint32_t flags, uint32_t bp, uint32_t next, uint32_t be, uint32_t framenum, uint32_t startframe, uint32_t framecount, int rel_frame_num) "ISO_TD ED head 0x%.8x tailp 0x%.8x\n0x%.8x 0x%.8x 0x%.8x 0x%.8x\nframe_number 0x%.8x starting_frame 0x%.8x\nframe_count  0x%.8x relative %d"
+usb_ohci_iso_td_head_offset(uint32_t o0, uint32_t o1, uint32_t o2, uint32_t o3, uint32_t o4, uint32_t o5, uint32_t o6, uint32_t o7) "0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x"
+usb_ohci_iso_td_relative_frame_number_neg(int rel) "ISO_TD R=%d < 0"
+usb_ohci_iso_td_relative_frame_number_big(int rel, int count) "ISO_TD R=%d > FC=%d"
+usb_ohci_iso_td_bad_direction(int dir) "Bad direction %d"
+usb_ohci_iso_td_bad_bp_be(uint32_t bp, uint32_t be) "ISO_TD bp 0x%.8x be 0x%.8x"
+usb_ohci_iso_td_bad_cc_not_accessed(uint32_t start, uint32_t next) "ISO_TD cc != not accessed 0x%.8x 0x%.8x"
+usb_ohci_iso_td_bad_cc_overrun(uint32_t start, uint32_t next) "ISO_TD start_offset=0x%.8x > next_offset=0x%.8x"
+usb_ohci_iso_td_so(uint32_t so, uint32_t eo, uint32_t s, uint32_t e, const char *str, ssize_t len, int ret) "0x%.8x eo 0x%.8x\nsa 0x%.8x ea 0x%.8x\ndir %s len %zu ret %d"
+usb_ohci_iso_td_data_overrun(int ret, ssize_t len) "DataOverrun %d > %zu"
+usb_ohci_iso_td_data_underrun(int ret) "DataUnderrun %d"
+usb_ohci_iso_td_nak(int ret) "got NAK/STALL %d"
+usb_ohci_iso_td_bad_response(int ret) "Bad device response %d"
+usb_ohci_port_attach(int index) "port #%d"
+usb_ohci_port_detach(int index) "port #%d"
+usb_ohci_port_wakeup(int index) "port #%d"
+usb_ohci_port_suspend(int index) "port #%d"
+usb_ohci_port_reset(int index) "port #%d"
+usb_ohci_remote_wakeup(const char *s) "%s: SUSPEND->RESUME"
+usb_ohci_reset(const char *s) "%s"
+usb_ohci_start(const char *s) "%s: USB Operational"
+usb_ohci_resume(const char *s) "%s: USB Resume"
+usb_ohci_stop(const char *s) "%s: USB Suspended"
+usb_ohci_exit(const char *s) "%s"
+usb_ohci_set_ctl(const char *s, uint32_t new_state) "%s: new state 0x%x"
+usb_ohci_td_underrun(void) ""
+usb_ohci_td_dev_error(void) ""
+usb_ohci_td_nak(void) ""
+usb_ohci_td_stall(void) ""
+usb_ohci_td_babble(void) ""
+usb_ohci_td_bad_device_response(int rc) "%d"
+usb_ohci_td_read_error(uint32_t addr) "TD read error at %x"
+usb_ohci_td_bad_direction(int dir) "Bad direction %d"
+usb_ohci_td_skip_async(void) ""
+usb_ohci_td_pkt_hdr(uint32_t addr, int64_t pktlen, int64_t len, const char *s, int flag_r, uint32_t cbp, uint32_t be) " TD @ 0x%.8x %" PRId64 " of %" PRId64 " bytes %s r=%d cbp=0x%.8x be=0x%.8x"
+usb_ohci_td_pkt_short(const char *dir, const char *buf) "%s data: %s"
+usb_ohci_td_pkt_full(const char *dir, const char *buf) "%s data: %s"
+usb_ohci_td_too_many_pending(void) ""
+usb_ohci_td_packet_status(int status) "status=%d"
+usb_ohci_ed_read_error(uint32_t addr) "ED read error at %x"
+usb_ohci_ed_pkt(uint32_t cur, int h, int c, uint32_t head, uint32_t tail, uint32_t next) "ED @ 0x%.8x h=%u c=%u\n  head=0x%.8x tailp=0x%.8x next=0x%.8x"
+usb_ohci_ed_pkt_flags(uint32_t fa, uint32_t en, uint32_t d, int s, int k, int f, uint32_t mps) "fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u"
+usb_ohci_hcca_read_error(uint32_t addr) "HCCA read error at %x"
+usb_ohci_mem_read_unaligned(uint32_t addr) "at %x"
+usb_ohci_mem_read_bad_offset(uint32_t addr) "%x"
+usb_ohci_mem_write_unaligned(uint32_t addr) "at %x"
+usb_ohci_mem_write_bad_offset(uint32_t addr) "%x"
+usb_ohci_process_lists(uint32_t head, uint32_t cur) "head %x, cur %x"
+usb_ohci_bus_eof_timer_failed(const char *name) "%s: timer_new_ns failed"
+usb_ohci_set_frame_interval(const char *name, uint16_t fi_x, uint16_t fi_u) "%s: FrameInterval = 0x%x (%u)"
+usb_ohci_hub_power_up(void) "powered up all ports"
+usb_ohci_hub_power_down(void) "powered down all ports"
+usb_ohci_init_time(int64_t frametime, int64_t bittime) "usb_bit_time=%" PRId64 " usb_frame_time=%" PRId64
+usb_ohci_die(void) ""
+usb_ohci_async_complete(void) ""
+
+# hw/usb/hcd-ehci.c
+usb_ehci_reset(void) "=== RESET ==="
+usb_ehci_unrealize(void) "=== UNREALIZE ==="
+usb_ehci_opreg_read(uint32_t addr, const char *str, uint32_t val) "rd mmio %04x [%s] = %x"
+usb_ehci_opreg_write(uint32_t addr, const char *str, uint32_t val) "wr mmio %04x [%s] = %x"
+usb_ehci_opreg_change(uint32_t addr, const char *str, uint32_t new, uint32_t old) "ch mmio %04x [%s] = %x (old: %x)"
+usb_ehci_portsc_read(uint32_t addr, uint32_t port, uint32_t val) "rd mmio %04x [port %d] = %x"
+usb_ehci_portsc_write(uint32_t addr, uint32_t port, uint32_t val) "wr mmio %04x [port %d] = %x"
+usb_ehci_portsc_change(uint32_t addr, uint32_t port, uint32_t new, uint32_t old) "ch mmio %04x [port %d] = %x (old: %x)"
+usb_ehci_usbsts(const char *sts, int state) "usbsts %s %d"
+usb_ehci_state(const char *schedule, const char *state) "%s schedule %s"
+usb_ehci_qh_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t c_qtd, uint32_t n_qtd, uint32_t a_qtd) "q %p - QH @ %08x: next %08x qtds %08x,%08x,%08x"
+usb_ehci_qh_fields(uint32_t addr, int rl, int mplen, int eps, int ep, int devaddr) "QH @ %08x - rl %d, mplen %d, eps %d, ep %d, dev %d"
+usb_ehci_qh_bits(uint32_t addr, int c, int h, int dtc, int i) "QH @ %08x - c %d, h %d, dtc %d, i %d"
+usb_ehci_qtd_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t altnext) "q %p - QTD @ %08x: next %08x altnext %08x"
+usb_ehci_qtd_fields(uint32_t addr, int tbytes, int cpage, int cerr, int pid) "QTD @ %08x - tbytes %d, cpage %d, cerr %d, pid %d"
+usb_ehci_qtd_bits(uint32_t addr, int ioc, int active, int halt, int babble, int xacterr) "QTD @ %08x - ioc %d, active %d, halt %d, babble %d, xacterr %d"
+usb_ehci_itd(uint32_t addr, uint32_t nxt, uint32_t mplen, uint32_t mult, uint32_t ep, uint32_t devaddr) "ITD @ %08x: next %08x - mplen %d, mult %d, ep %d, dev %d"
+usb_ehci_sitd(uint32_t addr, uint32_t nxt, uint32_t active) "ITD @ %08x: next %08x - active %d"
+usb_ehci_port_attach(uint32_t port, const char *owner, const char *device) "attach port #%d, owner %s, device %s"
+usb_ehci_port_detach(uint32_t port, const char *owner) "detach port #%d, owner %s"
+usb_ehci_port_reset(uint32_t port, int enable) "reset port #%d - %d"
+usb_ehci_port_suspend(uint32_t port) "port #%d"
+usb_ehci_port_wakeup(uint32_t port) "port #%d"
+usb_ehci_port_resume(uint32_t port) "port #%d"
+usb_ehci_queue_action(void *q, const char *action) "q %p: %s"
+usb_ehci_packet_action(void *q, void *p, const char *action) "q %p p %p: %s"
+usb_ehci_irq(uint32_t level, uint32_t frindex, uint32_t sts, uint32_t mask) "level %d, frindex 0x%04x, sts 0x%x, mask 0x%x"
+usb_ehci_guest_bug(const char *reason) "%s"
+usb_ehci_doorbell_ring(void) ""
+usb_ehci_doorbell_ack(void) ""
+usb_ehci_dma_error(void) ""
+
+# hw/usb/hcd-uhci.c
+usb_uhci_reset(void) "=== RESET ==="
+usb_uhci_exit(void) "=== EXIT ==="
+usb_uhci_schedule_start(void) ""
+usb_uhci_schedule_stop(void) ""
+usb_uhci_frame_start(uint32_t num) "nr %d"
+usb_uhci_frame_stop_bandwidth(void) ""
+usb_uhci_frame_loop_stop_idle(void) ""
+usb_uhci_frame_loop_continue(void) ""
+usb_uhci_mmio_readw(uint32_t addr, uint32_t val) "addr 0x%04x, ret 0x%04x"
+usb_uhci_mmio_writew(uint32_t addr, uint32_t val) "addr 0x%04x, val 0x%04x"
+usb_uhci_queue_add(uint32_t token) "token 0x%x"
+usb_uhci_queue_del(uint32_t token, const char *reason) "token 0x%x: %s"
+usb_uhci_packet_add(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_link_async(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_unlink_async(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_cancel(uint32_t token, uint32_t addr, int done) "token 0x%x, td 0x%x, done %d"
+usb_uhci_packet_complete_success(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_complete_shortxfer(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_complete_stall(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_complete_babble(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_complete_error(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_packet_del(uint32_t token, uint32_t addr) "token 0x%x, td 0x%x"
+usb_uhci_qh_load(uint32_t qh) "qh 0x%x"
+usb_uhci_td_load(uint32_t qh, uint32_t td, uint32_t ctrl, uint32_t token) "qh 0x%x, td 0x%x, ctrl 0x%x, token 0x%x"
+usb_uhci_td_queue(uint32_t td, uint32_t ctrl, uint32_t token) "td 0x%x, ctrl 0x%x, token 0x%x"
+usb_uhci_td_nextqh(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x"
+usb_uhci_td_async(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x"
+usb_uhci_td_complete(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x"
+
+# hw/usb/hcd-xhci.c
+usb_xhci_reset(void) "=== RESET ==="
+usb_xhci_exit(void) "=== EXIT ==="
+usb_xhci_run(void) ""
+usb_xhci_stop(void) ""
+usb_xhci_cap_read(uint32_t off, uint32_t val) "off 0x%04x, ret 0x%08x"
+usb_xhci_oper_read(uint32_t off, uint32_t val) "off 0x%04x, ret 0x%08x"
+usb_xhci_port_read(uint32_t port, uint32_t off, uint32_t val) "port %d, off 0x%04x, ret 0x%08x"
+usb_xhci_runtime_read(uint32_t off, uint32_t val) "off 0x%04x, ret 0x%08x"
+usb_xhci_doorbell_read(uint32_t off, uint32_t val) "off 0x%04x, ret 0x%08x"
+usb_xhci_oper_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
+usb_xhci_port_write(uint32_t port, uint32_t off, uint32_t val) "port %d, off 0x%04x, val 0x%08x"
+usb_xhci_runtime_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
+usb_xhci_doorbell_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
+usb_xhci_irq_intx(uint32_t level) "level %d"
+usb_xhci_irq_msi(uint32_t nr) "nr %d"
+usb_xhci_irq_msix(uint32_t nr) "nr %d"
+usb_xhci_irq_msix_use(uint32_t nr) "nr %d"
+usb_xhci_irq_msix_unuse(uint32_t nr) "nr %d"
+usb_xhci_queue_event(uint32_t vector, uint32_t idx, const char *trb, const char *evt, uint64_t param, uint32_t status, uint32_t control) "v %d, idx %d, %s, %s, p %016" PRIx64 ", s %08x, c 0x%08x"
+usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x"
+usb_xhci_port_reset(uint32_t port, bool warm) "port %d, warm %d"
+usb_xhci_port_link(uint32_t port, uint32_t pls) "port %d, pls %d"
+usb_xhci_port_notify(uint32_t port, uint32_t pls) "port %d, bits %x"
+usb_xhci_slot_enable(uint32_t slotid) "slotid %d"
+usb_xhci_slot_disable(uint32_t slotid) "slotid %d"
+usb_xhci_slot_address(uint32_t slotid, const char *port) "slotid %d, port %s"
+usb_xhci_slot_configure(uint32_t slotid) "slotid %d"
+usb_xhci_slot_evaluate(uint32_t slotid) "slotid %d"
+usb_xhci_slot_reset(uint32_t slotid) "slotid %d"
+usb_xhci_ep_enable(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
+usb_xhci_ep_disable(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
+usb_xhci_ep_set_dequeue(uint32_t slotid, uint32_t epid, uint32_t streamid, uint64_t param) "slotid %d, epid %d, streamid %d, ptr %016" PRIx64
+usb_xhci_ep_kick(uint32_t slotid, uint32_t epid, uint32_t streamid) "slotid %d, epid %d, streamid %d"
+usb_xhci_ep_stop(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
+usb_xhci_ep_reset(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
+usb_xhci_ep_state(uint32_t slotid, uint32_t epid, const char *os, const char *ns) "slotid %d, epid %d, %s -> %s"
+usb_xhci_xfer_start(void *xfer, uint32_t slotid, uint32_t epid, uint32_t streamid) "%p: slotid %d, epid %d, streamid %d"
+usb_xhci_xfer_async(void *xfer) "%p"
+usb_xhci_xfer_nak(void *xfer) "%p"
+usb_xhci_xfer_retry(void *xfer) "%p"
+usb_xhci_xfer_success(void *xfer, uint32_t bytes) "%p: len %d"
+usb_xhci_xfer_error(void *xfer, uint32_t ret) "%p: ret %d"
+usb_xhci_unimplemented(const char *item, int nr) "%s (0x%x)"
+
+# hw/usb/desc.c
+usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
+usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d"
+usb_desc_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
+usb_desc_other_speed_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
+usb_desc_string(int addr, int index, int len, int ret) "dev %d query string %d, len %d, ret %d"
+usb_desc_bos(int addr, int len, int ret) "dev %d bos, len %d, ret %d"
+usb_desc_msos(int addr, int index, int len, int ret) "dev %d msos, index 0x%x, len %d, ret %d"
+usb_set_addr(int addr) "dev %d"
+usb_set_config(int addr, int config, int ret) "dev %d, config %d, ret %d"
+usb_set_interface(int addr, int iface, int alt, int ret) "dev %d, interface %d, altsetting %d, ret %d"
+usb_clear_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
+usb_set_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
+
+# hw/usb/dev-hub.c
+usb_hub_reset(int addr) "dev %d"
+usb_hub_control(int addr, int request, int value, int index, int length) "dev %d, req 0x%x, value %d, index %d, langth %d"
+usb_hub_get_port_status(int addr, int nr, int status, int changed) "dev %d, port %d, status 0x%x, changed 0x%x"
+usb_hub_set_port_feature(int addr, int nr, const char *f) "dev %d, port %d, feature %s"
+usb_hub_clear_port_feature(int addr, int nr, const char *f) "dev %d, port %d, feature %s"
+usb_hub_attach(int addr, int nr) "dev %d, port %d"
+usb_hub_detach(int addr, int nr) "dev %d, port %d"
+usb_hub_status_report(int addr, int status) "dev %d, status 0x%x"
+
+# hw/usb/dev-uas.c
+usb_uas_reset(int addr) "dev %d"
+usb_uas_command(int addr, uint16_t tag, int lun, uint32_t lun64_1, uint32_t lun64_2) "dev %d, tag 0x%x, lun %d, lun64 %08x-%08x"
+usb_uas_response(int addr, uint16_t tag, uint8_t code) "dev %d, tag 0x%x, code 0x%x"
+usb_uas_sense(int addr, uint16_t tag, uint8_t status) "dev %d, tag 0x%x, status 0x%x"
+usb_uas_read_ready(int addr, uint16_t tag) "dev %d, tag 0x%x"
+usb_uas_write_ready(int addr, uint16_t tag) "dev %d, tag 0x%x"
+usb_uas_xfer_data(int addr, uint16_t tag, uint32_t copy, uint32_t uoff, uint32_t usize, uint32_t soff, uint32_t ssize) "dev %d, tag 0x%x, copy %d, usb-pkt %d/%d, scsi-buf %d/%d"
+usb_uas_scsi_data(int addr, uint16_t tag, uint32_t bytes) "dev %d, tag 0x%x, bytes %d"
+usb_uas_scsi_complete(int addr, uint16_t tag, uint32_t status, uint32_t resid) "dev %d, tag 0x%x, status 0x%x, residue %d"
+usb_uas_tmf_abort_task(int addr, uint16_t tag, uint16_t task_tag) "dev %d, tag 0x%x, task-tag 0x%x"
+usb_uas_tmf_logical_unit_reset(int addr, uint16_t tag, int lun) "dev %d, tag 0x%x, lun %d"
+usb_uas_tmf_unsupported(int addr, uint16_t tag, uint32_t function) "dev %d, tag 0x%x, function 0x%x"
+
+# hw/usb/dev-mtp.c
+usb_mtp_reset(int addr) "dev %d"
+usb_mtp_command(int dev, uint16_t code, uint32_t trans, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4) "dev %d, code 0x%x, trans 0x%x, args 0x%x, 0x%x, 0x%x, 0x%x, 0x%x"
+usb_mtp_success(int dev, uint32_t trans, uint32_t arg0, uint32_t arg1) "dev %d, trans 0x%x, args 0x%x, 0x%x"
+usb_mtp_error(int dev, uint16_t code, uint32_t trans, uint32_t arg0, uint32_t arg1) "dev %d, code 0x%x, trans 0x%x, args 0x%x, 0x%x"
+usb_mtp_data_in(int dev, uint32_t trans, uint32_t len) "dev %d, trans 0x%x, len %d"
+usb_mtp_xfer(int dev, uint32_t ep, uint32_t dlen, uint32_t plen) "dev %d, ep %d, %d/%d"
+usb_mtp_nak(int dev, uint32_t ep) "dev %d, ep %d"
+usb_mtp_stall(int dev, const char *reason) "dev %d, reason: %s"
+usb_mtp_op_get_device_info(int dev) "dev %d"
+usb_mtp_op_open_session(int dev) "dev %d"
+usb_mtp_op_close_session(int dev) "dev %d"
+usb_mtp_op_get_storage_ids(int dev) "dev %d"
+usb_mtp_op_get_storage_info(int dev) "dev %d"
+usb_mtp_op_get_num_objects(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
+usb_mtp_op_get_object_handles(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
+usb_mtp_op_get_object_info(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
+usb_mtp_op_get_object(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
+usb_mtp_op_get_partial_object(int dev, uint32_t handle, const char *path, uint32_t offset, uint32_t length) "dev %d, handle 0x%x, path %s, off %d, len %d"
+usb_mtp_op_unknown(int dev, uint32_t code) "dev %d, command code 0x%x"
+usb_mtp_object_alloc(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
+usb_mtp_object_free(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
+usb_mtp_add_child(int dev, uint32_t handle, const char *path) "dev %d, handle 0x%x, path %s"
+usb_mtp_inotify_event(int dev, const char *path, uint32_t mask, const char *s) "dev %d, path %s mask 0x%x event %s"
+
+# hw/usb/host-libusb.c
+usb_host_open_started(int bus, int addr) "dev %d:%d"
+usb_host_open_success(int bus, int addr) "dev %d:%d"
+usb_host_open_failure(int bus, int addr) "dev %d:%d"
+usb_host_close(int bus, int addr) "dev %d:%d"
+usb_host_attach_kernel(int bus, int addr, int interface) "dev %d:%d, if %d"
+usb_host_detach_kernel(int bus, int addr, int interface) "dev %d:%d, if %d"
+usb_host_set_address(int bus, int addr, int config) "dev %d:%d, address %d"
+usb_host_set_config(int bus, int addr, int config) "dev %d:%d, config %d"
+usb_host_set_interface(int bus, int addr, int interface, int alt) "dev %d:%d, interface %d, alt %d"
+usb_host_claim_interface(int bus, int addr, int config, int interface) "dev %d:%d, config %d, if %d"
+usb_host_release_interface(int bus, int addr, int interface) "dev %d:%d, if %d"
+usb_host_req_control(int bus, int addr, void *p, int req, int value, int index) "dev %d:%d, packet %p, req 0x%x, value %d, index %d"
+usb_host_req_data(int bus, int addr, void *p, int in, int ep, int size) "dev %d:%d, packet %p, in %d, ep %d, size %d"
+usb_host_req_complete(int bus, int addr, void *p, int status, int length) "dev %d:%d, packet %p, status %d, length %d"
+usb_host_req_emulated(int bus, int addr, void *p, int status) "dev %d:%d, packet %p, status %d"
+usb_host_req_canceled(int bus, int addr, void *p) "dev %d:%d, packet %p"
+usb_host_iso_start(int bus, int addr, int ep) "dev %d:%d, ep %d"
+usb_host_iso_stop(int bus, int addr, int ep) "dev %d:%d, ep %d"
+usb_host_iso_out_of_bufs(int bus, int addr, int ep) "dev %d:%d, ep %d"
+usb_host_reset(int bus, int addr) "dev %d:%d"
+usb_host_auto_scan_enabled(void)
+usb_host_auto_scan_disabled(void)
+usb_host_parse_config(int bus, int addr, int value, int active) "dev %d:%d, value %d, active %d"
+usb_host_parse_interface(int bus, int addr, int num, int alt, int active) "dev %d:%d, num %d, alt %d, active %d"
+usb_host_parse_endpoint(int bus, int addr, int ep, const char *dir, const char *type, int active) "dev %d:%d, ep %d, %s, %s, active %d"
+usb_host_parse_error(int bus, int addr, const char *errmsg) "dev %d:%d, msg %s"
+
+# hw/scsi/scsi-bus.c
+scsi_req_alloc(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_cancel(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_data(int target, int lun, int tag, int len) "target %d lun %d tag %d len %d"
+scsi_req_data_canceled(int target, int lun, int tag, int len) "target %d lun %d tag %d len %d"
+scsi_req_dequeue(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_continue(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_continue_canceled(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) "target %d lun %d tag %d command %d dir %d length %d"
+scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba) "target %d lun %d tag %d command %d lba %"PRIu64
+scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d tag %d command %d"
+scsi_req_build_sense(int target, int lun, int tag, int key, int asc, int ascq) "target %d lun %d tag %d key %#02x asc %#02x ascq %#02x"
+scsi_device_set_ua(int target, int lun, int key, int asc, int ascq) "target %d lun %d key %#02x asc %#02x ascq %#02x"
+scsi_report_luns(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_inquiry(int target, int lun, int tag, int cdb1, int cdb2) "target %d lun %d tag %d page %#02x/%#02x"
+scsi_test_unit_ready(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_request_sense(int target, int lun, int tag) "target %d lun %d tag %d"
+
 # vl.c
 vm_state_notify(int running, int reason) "running %d reason %d"
 load_file(const char *name, const char *path) "name %s location %s"
@@ -50,6 +607,88 @@ system_wakeup_request(int reason) "reason=%d"
 qemu_system_shutdown_request(void) ""
 qemu_system_powerdown_request(void) ""
 
+# block/qcow2.c
+qcow2_writev_start_req(void *co, int64_t sector, int nb_sectors) "co %p sector %" PRIx64 " nb_sectors %d"
+qcow2_writev_done_req(void *co, int ret) "co %p ret %d"
+qcow2_writev_start_part(void *co) "co %p"
+qcow2_writev_done_part(void *co, int cur_nr_sectors) "co %p cur_nr_sectors %d"
+qcow2_writev_data(void *co, uint64_t offset) "co %p offset %" PRIx64
+
+# block/qcow2-cluster.c
+qcow2_alloc_clusters_offset(void *co, uint64_t offset, int num) "co %p offset %" PRIx64 " num %d"
+qcow2_handle_copied(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64
+qcow2_handle_alloc(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64
+qcow2_do_alloc_clusters_offset(void *co, uint64_t guest_offset, uint64_t host_offset, int nb_clusters) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " nb_clusters %d"
+qcow2_cluster_alloc_phys(void *co) "co %p"
+qcow2_cluster_link_l2(void *co, int nb_clusters) "co %p nb_clusters %d"
+
+qcow2_l2_allocate(void *bs, int l1_index) "bs %p l1_index %d"
+qcow2_l2_allocate_get_empty(void *bs, int l1_index) "bs %p l1_index %d"
+qcow2_l2_allocate_write_l2(void *bs, int l1_index) "bs %p l1_index %d"
+qcow2_l2_allocate_write_l1(void *bs, int l1_index) "bs %p l1_index %d"
+qcow2_l2_allocate_done(void *bs, int l1_index, int ret) "bs %p l1_index %d ret %d"
+
+# block/qcow2-cache.c
+qcow2_cache_get(void *co, int c, uint64_t offset, bool read_from_disk) "co %p is_l2_cache %d offset %" PRIx64 " read_from_disk %d"
+qcow2_cache_get_replace_entry(void *co, int c, int i) "co %p is_l2_cache %d index %d"
+qcow2_cache_get_read(void *co, int c, int i) "co %p is_l2_cache %d index %d"
+qcow2_cache_get_done(void *co, int c, int i) "co %p is_l2_cache %d index %d"
+qcow2_cache_flush(void *co, int c) "co %p is_l2_cache %d"
+qcow2_cache_entry_flush(void *co, int c, int i) "co %p is_l2_cache %d index %d"
+
+# block/qed-l2-cache.c
+qed_alloc_l2_cache_entry(void *l2_cache, void *entry) "l2_cache %p entry %p"
+qed_unref_l2_cache_entry(void *entry, int ref) "entry %p ref %d"
+qed_find_l2_cache_entry(void *l2_cache, void *entry, uint64_t offset, int ref) "l2_cache %p entry %p offset %"PRIu64" ref %d"
+
+# block/qed-table.c
+qed_read_table(void *s, uint64_t offset, void *table) "s %p offset %"PRIu64" table %p"
+qed_read_table_cb(void *s, void *table, int ret) "s %p table %p ret %d"
+qed_write_table(void *s, uint64_t offset, void *table, unsigned int index, unsigned int n) "s %p offset %"PRIu64" table %p index %u n %u"
+qed_write_table_cb(void *s, void *table, int flush, int ret) "s %p table %p flush %d ret %d"
+
+# block/qed.c
+qed_need_check_timer_cb(void *s) "s %p"
+qed_start_need_check_timer(void *s) "s %p"
+qed_cancel_need_check_timer(void *s) "s %p"
+qed_aio_complete(void *s, void *acb, int ret) "s %p acb %p ret %d"
+qed_aio_setup(void *s, void *acb, int64_t sector_num, int nb_sectors, void *opaque, int flags) "s %p acb %p sector_num %"PRId64" nb_sectors %d opaque %p flags %#x"
+qed_aio_next_io(void *s, void *acb, int ret, uint64_t cur_pos) "s %p acb %p ret %d cur_pos %"PRIu64
+qed_aio_read_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
+qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
+qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
+qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
+qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
+
+# hw/display/g364fb.c
+g364fb_read(uint64_t addr, uint32_t val) "read addr=0x%"PRIx64": 0x%x"
+g364fb_write(uint64_t addr, uint32_t new) "write addr=0x%"PRIx64": 0x%x"
+
+# hw/timer/grlib_gptimer.c
+grlib_gptimer_enable(int id, uint32_t count) "timer:%d set count 0x%x and run"
+grlib_gptimer_disabled(int id, uint32_t config) "timer:%d Timer disable config 0x%x"
+grlib_gptimer_restart(int id, uint32_t reload) "timer:%d reload val: 0x%x"
+grlib_gptimer_set_scaler(uint32_t scaler, uint32_t freq) "scaler:0x%x freq: 0x%x"
+grlib_gptimer_hit(int id) "timer:%d HIT"
+grlib_gptimer_readl(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
+grlib_gptimer_writel(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
+
+# hw/intc/grlib_irqmp.c
+grlib_irqmp_check_irqs(uint32_t pend, uint32_t force, uint32_t mask, uint32_t lvl1, uint32_t lvl2) "pend:0x%04x force:0x%04x mask:0x%04x lvl1:0x%04x lvl0:0x%04x"
+grlib_irqmp_ack(int intno) "interrupt:%d"
+grlib_irqmp_set_irq(int irq) "Raise CPU IRQ %d"
+grlib_irqmp_readl_unknown(uint64_t addr) "addr 0x%"PRIx64
+grlib_irqmp_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
+
+# hw/char/grlib_apbuart.c
+grlib_apbuart_event(int event) "event:%d"
+grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
+grlib_apbuart_readl_unknown(uint64_t addr) "addr 0x%"PRIx64
+
+# hw/sparc/leon3.c
+leon3_set_irq(int intno) "Set CPU IRQ %d"
+leon3_reset_irq(int intno) "Reset CPU IRQ %d"
+
 # spice-qemu-char.c
 spice_vmc_write(ssize_t out, int len) "spice wrottn %zd of requested %d"
 spice_vmc_read(int bytes, int len) "spice read %d of requested %d"
@@ -57,10 +696,257 @@ spice_vmc_register_interface(void *scd) "spice vmc registered interface %p"
 spice_vmc_unregister_interface(void *scd) "spice vmc unregistered interface %p"
 spice_vmc_event(int event) "spice vmc event %d"
 
+# hw/intc/lm32_pic.c
+lm32_pic_raise_irq(void) "Raise CPU interrupt"
+lm32_pic_lower_irq(void) "Lower CPU interrupt"
+lm32_pic_interrupt(int irq, int level) "Set IRQ%d %d"
+lm32_pic_set_im(uint32_t im) "im 0x%08x"
+lm32_pic_set_ip(uint32_t ip) "ip 0x%08x"
+lm32_pic_get_im(uint32_t im) "im 0x%08x"
+lm32_pic_get_ip(uint32_t ip) "ip 0x%08x"
+
+# hw/char/lm32_juart.c
+lm32_juart_get_jtx(uint32_t value) "jtx 0x%08x"
+lm32_juart_set_jtx(uint32_t value) "jtx 0x%08x"
+lm32_juart_get_jrx(uint32_t value) "jrx 0x%08x"
+lm32_juart_set_jrx(uint32_t value) "jrx 0x%08x"
+
+# hw/timer/lm32_timer.c
+lm32_timer_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_timer_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_timer_hit(void) "timer hit"
+lm32_timer_irq_state(int level) "irq state %d"
+
+# hw/char/lm32_uart.c
+lm32_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_uart_irq_state(int level) "irq state %d"
+
+# hw/scsi/mptsas.c
+mptsas_command_complete(void *dev, uint32_t ctx, uint32_t status, uint32_t resid) "dev %p context 0x%08x status %x resid %d"
+mptsas_diag_read(void *dev, uint32_t addr, uint32_t val) "dev %p addr 0x%08x value 0x%08x"
+mptsas_diag_write(void *dev, uint32_t addr, uint32_t val) "dev %p addr 0x%08x value 0x%08x"
+mptsas_irq_intx(void *dev, int level) "dev %p level %d"
+mptsas_irq_msi(void *dev) "dev %p "
+mptsas_mmio_read(void *dev, uint32_t addr, uint32_t val) "dev %p addr 0x%08x value 0x%x"
+mptsas_mmio_unhandled_read(void *dev, uint32_t addr) "dev %p addr 0x%08x"
+mptsas_mmio_unhandled_write(void *dev, uint32_t addr, uint32_t val) "dev %p addr 0x%08x value 0x%x"
+mptsas_mmio_write(void *dev, uint32_t addr, uint32_t val) "dev %p addr 0x%08x value 0x%x"
+mptsas_process_message(void *dev, int msg, uint32_t ctx) "dev %p cmd %d context 0x%08x\n"
+mptsas_process_scsi_io_request(void *dev, int bus, int target, int lun, uint64_t len) "dev %p dev %d:%d:%d length %"PRIu64""
+mptsas_reset(void *dev) "dev %p "
+mptsas_scsi_overflow(void *dev, uint32_t ctx, uint64_t req, uint64_t found) "dev %p context 0x%08x: %"PRIu64"/%"PRIu64""
+mptsas_sgl_overflow(void *dev, uint32_t ctx, uint64_t req, uint64_t found) "dev %p context 0x%08x: %"PRIu64"/%"PRIu64""
+mptsas_unhandled_cmd(void *dev, uint32_t ctx, uint8_t msg_cmd) "dev %p context 0x%08x: Unhandled cmd %x"
+mptsas_unhandled_doorbell_cmd(void *dev, int cmd) "dev %p value 0x%08x"
+
+# hw/scsi/mptconfig.c
+mptsas_config_sas_device(void *dev, int address, int port, int phy_handle, int dev_handle, int page) "dev %p address %d (port %d, handles: phy %d dev %d) page %d"
+mptsas_config_sas_phy(void *dev, int address, int port, int phy_handle, int dev_handle, int page) "dev %p address %d (port %d, handles: phy %d dev %d) page %d"
+
+# hw/scsi/megasas.c
+megasas_init_firmware(uint64_t pa) "pa %" PRIx64 " "
+megasas_init_queue(uint64_t queue_pa, int queue_len, uint64_t head, uint64_t tail, uint32_t flags) "queue at %" PRIx64 " len %d head %" PRIx64 " tail %" PRIx64 " flags %x"
+megasas_initq_map_failed(int frame) "scmd %d: failed to map queue"
+megasas_initq_mapped(uint64_t pa) "queue already mapped at %" PRIx64
+megasas_initq_mismatch(int queue_len, int fw_cmds) "queue size %d max fw cmds %d"
+megasas_qf_mapped(unsigned int index) "skip mapped frame %x"
+megasas_qf_new(unsigned int index, uint64_t frame) "frame %x addr %" PRIx64
+megasas_qf_busy(unsigned long pa) "all frames busy for frame %lx"
+megasas_qf_enqueue(unsigned int index, unsigned int count, uint64_t context, unsigned int head, unsigned int tail, int busy) "frame %x count %d context %" PRIx64 " head %x tail %x busy %d"
+megasas_qf_update(unsigned int head, unsigned int tail, unsigned int busy) "head %x tail %x busy %d"
+megasas_qf_map_failed(int cmd, unsigned long frame) "scmd %d: frame %lu"
+megasas_qf_complete_noirq(uint64_t context) "context %" PRIx64 " "
+megasas_qf_complete(uint64_t context, unsigned int head, unsigned int tail, int busy) "context %" PRIx64 " head %x tail %x busy %d"
+megasas_frame_busy(uint64_t addr) "frame %" PRIx64 " busy"
+megasas_unhandled_frame_cmd(int cmd, uint8_t frame_cmd) "scmd %d: MFI cmd %x"
+megasas_handle_scsi(const char *frame, int bus, int dev, int lun, void *sdev, unsigned long size) "%s dev %x/%x/%x sdev %p xfer %lu"
+megasas_scsi_target_not_present(const char *frame, int bus, int dev, int lun) "%s dev %x/%x/%x"
+megasas_scsi_invalid_cdb_len(const char *frame, int bus, int dev, int lun, int len) "%s dev %x/%x/%x invalid cdb len %d"
+megasas_iov_read_overflow(int cmd, int bytes, int len) "scmd %d: %d/%d bytes"
+megasas_iov_write_overflow(int cmd, int bytes, int len) "scmd %d: %d/%d bytes"
+megasas_iov_read_underflow(int cmd, int bytes, int len) "scmd %d: %d/%d bytes"
+megasas_iov_write_underflow(int cmd, int bytes, int len) "scmd %d: %d/%d bytes"
+megasas_scsi_req_alloc_failed(const char *frame, int dev, int lun) "%s dev %x/%x"
+megasas_scsi_read_start(int cmd, int len) "scmd %d: transfer %d bytes of data"
+megasas_scsi_write_start(int cmd, int len) "scmd %d: transfer %d bytes of data"
+megasas_scsi_nodata(int cmd) "scmd %d: no data to be transferred"
+megasas_scsi_complete(int cmd, uint32_t status, int len, int xfer) "scmd %d: status %x, len %u/%u"
+megasas_command_complete(int cmd, uint32_t status, uint32_t resid) "scmd %d: status %x, residual %d"
+megasas_handle_io(int cmd, const char *frame, int dev, int lun, unsigned long lba, unsigned long count) "scmd %d: %s dev %x/%x lba %lx count %lu"
+megasas_io_target_not_present(int cmd, const char *frame, int dev, int lun) "scmd %d: %s dev 1/%x/%x LUN not present"
+megasas_io_read_start(int cmd, unsigned long lba, unsigned long count, unsigned long len) "scmd %d: start LBA %lx %lu blocks (%lu bytes)"
+megasas_io_write_start(int cmd, unsigned long lba, unsigned long count, unsigned long len) "scmd %d: start LBA %lx %lu blocks (%lu bytes)"
+megasas_io_complete(int cmd, uint32_t len) "scmd %d: %d bytes"
+megasas_iovec_sgl_overflow(int cmd, int index, int limit) "scmd %d: iovec count %d limit %d"
+megasas_iovec_sgl_underflow(int cmd, int index) "scmd %d: iovec count %d"
+megasas_iovec_sgl_invalid(int cmd, int index, uint64_t pa, uint32_t len) "scmd %d: element %d pa %" PRIx64 " len %u"
+megasas_iovec_overflow(int cmd, int len, int limit) "scmd %d: len %d limit %d"
+megasas_iovec_underflow(int cmd, int len, int limit) "scmd %d: len %d limit %d"
+megasas_handle_dcmd(int cmd, int opcode) "scmd %d: MFI DCMD opcode %x"
+megasas_finish_dcmd(int cmd, int size) "scmd %d: MFI DCMD wrote %d bytes"
+megasas_dcmd_req_alloc_failed(int cmd, const char *desc) "scmd %d: %s"
+megasas_dcmd_internal_submit(int cmd, const char *desc, int dev) "scmd %d: %s to dev %d"
+megasas_dcmd_internal_finish(int cmd, int opcode, int lun) "scmd %d: cmd %x lun %d"
+megasas_dcmd_internal_invalid(int cmd, int opcode) "scmd %d: DCMD %x"
+megasas_dcmd_unhandled(int cmd, int opcode, int len) "scmd %d: opcode %x, len %d"
+megasas_dcmd_zero_sge(int cmd) "scmd %d: zero DCMD sge count"
+megasas_dcmd_invalid_sge(int cmd, int count) "scmd %d: DCMD sge count %d"
+megasas_dcmd_invalid_xfer_len(int cmd, unsigned long size, unsigned long max) "scmd %d: xfer len %ld, max %ld"
+megasas_dcmd_enter(int cmd, const char *dcmd, int len) "scmd %d: DCMD %s len %d"
+megasas_dcmd_dummy(int cmd, unsigned long size) "scmd %d: xfer len %ld"
+megasas_dcmd_set_fw_time(int cmd, unsigned long time) "scmd %d: Set FW time %lx"
+megasas_dcmd_pd_get_list(int cmd, int num, int max, int offset) "scmd %d: DCMD PD get list: %d / %d PDs, size %d"
+megasas_dcmd_ld_get_list(int cmd, int num, int max) "scmd %d: DCMD LD get list: found %d / %d LDs"
+megasas_dcmd_ld_get_info(int cmd, int ld_id) "scmd %d: dev %d"
+megasas_dcmd_ld_list_query(int cmd, int flags) "scmd %d: query flags %x"
+megasas_dcmd_pd_get_info(int cmd, int pd_id) "scmd %d: dev %d"
+megasas_dcmd_pd_list_query(int cmd, int flags) "scmd %d: query flags %x"
+megasas_dcmd_reset_ld(int cmd, int target_id) "scmd %d: dev %d"
+megasas_dcmd_unsupported(int cmd, unsigned long size) "scmd %d: set properties len %ld"
+megasas_abort_frame(int cmd, int abort_cmd) "scmd %d: frame %x"
+megasas_abort_no_cmd(int cmd, uint64_t context) "scmd %d: no active command for frame context %" PRIx64
+megasas_abort_invalid_context(int cmd, uint64_t context, int abort_cmd) "scmd %d: invalid frame context %" PRIx64 " for abort frame %x"
+megasas_reset(int fw_state) "firmware state %x"
+megasas_init(int sges, int cmds, const char *mode) "Using %d sges, %d cmds, %s mode"
+megasas_msix_raise(int vector) "vector %d"
+megasas_msi_raise(int vector) "vector %d"
+megasas_irq_lower(void) "INTx"
+megasas_irq_raise(void) "INTx"
+megasas_intr_enabled(void) "Interrupts enabled"
+megasas_intr_disabled(void) "Interrupts disabled"
+megasas_msix_enabled(int vector) "vector %d"
+megasas_msi_enabled(int vector) "vector %d"
+megasas_mmio_readl(const char *reg, uint32_t val) "reg %s: 0x%x"
+megasas_mmio_invalid_readl(unsigned long addr) "addr 0x%lx"
+megasas_mmio_writel(const char *reg, uint32_t val) "reg %s: 0x%x"
+megasas_mmio_invalid_writel(uint32_t addr, uint32_t val) "addr 0x%x: 0x%x"
+
+# hw/audio/milkymist-ac97.c
+milkymist_ac97_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_ac97_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_ac97_pulse_irq_crrequest(void) "Pulse IRQ CR request"
+milkymist_ac97_pulse_irq_crreply(void) "Pulse IRQ CR reply"
+milkymist_ac97_pulse_irq_dmaw(void) "Pulse IRQ DMA write"
+milkymist_ac97_pulse_irq_dmar(void) "Pulse IRQ DMA read"
+milkymist_ac97_in_cb(int avail, uint32_t remaining) "avail %d remaining %u"
+milkymist_ac97_in_cb_transferred(int transferred) "transferred %d"
+milkymist_ac97_out_cb(int free, uint32_t remaining) "free %d remaining %u"
+milkymist_ac97_out_cb_transferred(int transferred) "transferred %d"
+
+# hw/misc/milkymist-hpdmc.c
+milkymist_hpdmc_memory_read(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
+milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
+
+# hw/sd/milkymist-memcard.c
+milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+
+# hw/net/milkymist-minimac2.c
+milkymist_minimac2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_minimac2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_minimac2_mdio_write(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
+milkymist_minimac2_mdio_read(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
+milkymist_minimac2_tx_frame(uint32_t length) "length %u"
+milkymist_minimac2_rx_frame(const void *buf, uint32_t length) "buf %p length %u"
+milkymist_minimac2_rx_transfer(const void *buf, uint32_t length) "buf %p length %d"
+milkymist_minimac2_raise_irq_rx(void) "Raise IRQ RX"
+milkymist_minimac2_lower_irq_rx(void) "Lower IRQ RX"
+milkymist_minimac2_pulse_irq_tx(void) "Pulse IRQ TX"
+
+# hw/misc/milkymist-pfpu.c
+milkymist_pfpu_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_pfpu_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_pfpu_vectout(uint32_t a, uint32_t b, uint32_t dma_ptr) "a %08x b %08x dma_ptr %08x"
+milkymist_pfpu_pulse_irq(void) "Pulse IRQ"
+
+# hw/input/milkymist-softusb.c
+milkymist_softusb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_softusb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_softusb_mevt(uint8_t m) "m %d"
+milkymist_softusb_kevt(uint8_t m) "m %d"
+milkymist_softusb_pulse_irq(void) "Pulse IRQ"
+
+# hw/timer/milkymist-sysctl.c
+milkymist_sysctl_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_sysctl_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_sysctl_icap_write(uint32_t value) "value %08x"
+milkymist_sysctl_start_timer0(void) "Start timer0"
+milkymist_sysctl_stop_timer0(void) "Stop timer0"
+milkymist_sysctl_start_timer1(void) "Start timer1"
+milkymist_sysctl_stop_timer1(void) "Stop timer1"
+milkymist_sysctl_pulse_irq_timer0(void) "Pulse IRQ Timer0"
+milkymist_sysctl_pulse_irq_timer1(void) "Pulse IRQ Timer1"
+
+# hw/display/milkymist-tmu2.c
+milkymist_tmu2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_tmu2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_tmu2_start(void) "Start TMU"
+milkymist_tmu2_pulse_irq(void) "Pulse IRQ"
+
+# hw/char/milkymist-uart.c
+milkymist_uart_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_uart_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_uart_raise_irq(void) "Raise IRQ"
+milkymist_uart_lower_irq(void) "Lower IRQ"
+
+# hw/display/milkymist-vgafb.c
+milkymist_vgafb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_vgafb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+
+# hw/net/mipsnet.c
+mipsnet_send(uint32_t size) "sending len=%u"
+mipsnet_receive(uint32_t size) "receiving len=%u"
+mipsnet_read(uint64_t addr, uint32_t val) "read addr=0x%" PRIx64 " val=0x%x"
+mipsnet_write(uint64_t addr, uint64_t val) "write addr=0x%" PRIx64 " val=0x%" PRIx64
+mipsnet_irq(uint32_t isr, uint32_t intctl) "set irq to %d (%02x)"
+
+# hw/isa/pc87312.c
+pc87312_io_read(uint32_t addr, uint32_t val) "read addr=%x val=%x"
+pc87312_io_write(uint32_t addr, uint32_t val) "write addr=%x val=%x"
+pc87312_info_floppy(uint32_t base) "base 0x%x"
+pc87312_info_ide(uint32_t base) "base 0x%x"
+pc87312_info_parallel(uint32_t base, uint32_t irq) "base 0x%x, irq %u"
+pc87312_info_serial(int n, uint32_t base, uint32_t irq) "id=%d, base 0x%x, irq %u"
+
+# hw/scsi/vmw_pvscsi.c
+pvscsi_ring_init_data(uint32_t txr_len_log2, uint32_t rxr_len_log2) "TX/RX rings logarithms set to %d/%d"
+pvscsi_ring_init_msg(uint32_t len_log2) "MSG ring logarithm set to %d"
+pvscsi_ring_flush_cmp(uint64_t filled_cmp_ptr) "new production counter of completion ring is 0x%"PRIx64
+pvscsi_ring_flush_msg(uint64_t filled_cmp_ptr) "new production counter of message ring is 0x%"PRIx64
+pvscsi_update_irq_level(bool raise, uint64_t mask, uint64_t status) "interrupt level set to %d (MASK: 0x%"PRIx64", STATUS: 0x%"PRIx64")"
+pvscsi_update_irq_msi(void) "sending MSI notification"
+pvscsi_cmp_ring_put(unsigned long addr) "got completion descriptor 0x%lx"
+pvscsi_msg_ring_put(unsigned long addr) "got message descriptor 0x%lx"
+pvscsi_complete_request(uint64_t context, uint64_t len, uint8_t sense_key) "completion: ctx: 0x%"PRIx64", len: 0x%"PRIx64", sense key: %u"
+pvscsi_get_sg_list(int nsg, size_t size) "get SG list: depth: %u, size: %zu"
+pvscsi_get_next_sg_elem(uint32_t flags) "unknown flags in SG element (val: 0x%x)"
+pvscsi_command_complete_not_found(uint32_t tag) "can't find request for tag 0x%x"
+pvscsi_command_complete_data_run(void) "not all data required for command transferred"
+pvscsi_command_complete_sense_len(int len) "sense information length is %d bytes"
+pvscsi_convert_sglist(uint64_t context, unsigned long addr, uint32_t resid) "element: ctx: 0x%"PRIx64" addr: 0x%lx, len: %ul"
+pvscsi_process_req_descr(uint8_t cmd, uint64_t ctx) "SCSI cmd 0x%x, ctx: 0x%"PRIx64
+pvscsi_process_req_descr_unknown_device(void) "command directed to unknown device rejected"
+pvscsi_process_req_descr_invalid_dir(void) "command with invalid transfer direction rejected"
+pvscsi_process_io(unsigned long addr) "got descriptor 0x%lx"
+pvscsi_on_cmd_noimpl(const char* cmd) "unimplemented command %s ignored"
+pvscsi_on_cmd_reset_dev(uint32_t tgt, int lun, void* dev) "PVSCSI_CMD_RESET_DEVICE[target %u lun %d (dev 0x%p)]"
+pvscsi_on_cmd_arrived(const char* cmd) "command %s arrived"
+pvscsi_on_cmd_abort(uint64_t ctx, uint32_t tgt) "command PVSCSI_CMD_ABORT_CMD for ctx 0x%"PRIx64", target %u"
+pvscsi_on_cmd_unknown(uint64_t cmd_id) "unknown command %"PRIx64
+pvscsi_on_cmd_unknown_data(uint32_t data) "data for unknown command 0x:%x"
+pvscsi_io_write(const char* cmd, uint64_t val) "%s write: %"PRIx64
+pvscsi_io_write_unknown(unsigned long addr, unsigned sz, uint64_t val) "unknown write address: 0x%lx size: %u bytes value: 0x%"PRIx64
+pvscsi_io_read(const char* cmd, uint64_t status) "%s read: 0x%"PRIx64
+pvscsi_io_read_unknown(unsigned long addr, unsigned sz) "unknown read address: 0x%lx size: %u bytes"
+pvscsi_init_msi_fail(int res) "failed to initialize MSI, error %d"
+pvscsi_state(const char* state) "starting %s ..."
+pvscsi_tx_rings_ppn(const char* label, uint64_t ppn) "%s page: %"PRIx64
+pvscsi_tx_rings_num_pages(const char* label, uint32_t num) "Number of %s pages: %u"
+
 # xen-hvm.c
 xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: %#lx, size %#lx"
 xen_client_set_memory(uint64_t start_addr, unsigned long size, bool log_dirty) "%#"PRIx64" size %#lx, log_dirty %i"
-xen_default_ioreq_server(void) ""
 xen_ioreq_server_create(uint32_t id) "id: %u"
 xen_ioreq_server_destroy(uint32_t id) "id: %u"
 xen_ioreq_server_state(uint32_t id, bool enable) "id: %u: enable: %i"
@@ -83,6 +969,9 @@ xen_map_cache(uint64_t phys_addr) "want %#"PRIx64
 xen_remap_bucket(uint64_t index) "index %#"PRIx64
 xen_map_cache_return(void* ptr) "%p"
 
+# hw/i386/xen/xen_platform.c
+xen_platform_log(char *s) "xen platform: %s"
+
 # qemu-coroutine.c
 qemu_coroutine_enter(void *from, void *to, void *opaque) "from %p to %p opaque %p"
 qemu_coroutine_yield(void *from, void *to) "from %p to %p"
@@ -96,6 +985,71 @@ qemu_co_mutex_lock_return(void *mutex, void *self) "mutex %p self %p"
 qemu_co_mutex_unlock_entry(void *mutex, void *self) "mutex %p self %p"
 qemu_co_mutex_unlock_return(void *mutex, void *self) "mutex %p self %p"
 
+# hw/char/escc.c
+escc_put_queue(char channel, int b) "channel %c put: 0x%02x"
+escc_get_queue(char channel, int val) "channel %c get 0x%02x"
+escc_update_irq(int irq) "IRQ = %d"
+escc_update_parameters(char channel, int speed, int parity, int data_bits, int stop_bits) "channel %c: speed=%d parity=%c data=%d stop=%d"
+escc_mem_writeb_ctrl(char channel, uint32_t reg, uint32_t val) "Write channel %c, reg[%d] = %2.2x"
+escc_mem_writeb_data(char channel, uint32_t val) "Write channel %c, ch %d"
+escc_mem_readb_ctrl(char channel, uint32_t reg, uint8_t val) "Read channel %c, reg[%d] = %2.2x"
+escc_mem_readb_data(char channel, uint32_t ret) "Read channel %c, ch %d"
+escc_serial_receive_byte(char channel, int ch) "channel %c put ch %d"
+escc_sunkbd_event_in(int ch, const char *name, int down) "QKeyCode 0x%2.2x [%s], down %d"
+escc_sunkbd_event_out(int ch) "Translated keycode 0x%2.2x"
+escc_kbd_command(int val) "Command %d"
+escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=%01x"
+
+# hw/scsi/esp.c
+esp_error_fifo_overrun(void) "FIFO overrun"
+esp_error_unhandled_command(uint32_t val) "unhandled command (%2.2x)"
+esp_error_invalid_write(uint32_t val, uint32_t addr) "invalid write of 0x%02x at [0x%x]"
+esp_raise_irq(void) "Raise IRQ"
+esp_lower_irq(void) "Lower IRQ"
+esp_dma_enable(void) "Raise enable"
+esp_dma_disable(void) "Lower enable"
+esp_get_cmd(uint32_t dmalen, int target) "len %d target %d"
+esp_do_busid_cmd(uint8_t busid) "busid 0x%x"
+esp_handle_satn_stop(uint32_t cmdlen) "cmdlen %d"
+esp_write_response(uint32_t status) "Transfer status (status=%d)"
+esp_do_dma(uint32_t cmdlen, uint32_t len) "command len %d + %d"
+esp_command_complete(void) "SCSI Command complete"
+esp_command_complete_unexpected(void) "SCSI command completed unexpectedly"
+esp_command_complete_fail(void) "Command failed"
+esp_transfer_data(uint32_t dma_left, int32_t ti_size) "transfer %d/%d"
+esp_handle_ti(uint32_t minlen) "Transfer Information len %d"
+esp_handle_ti_cmd(uint32_t cmdlen) "command len %d"
+esp_mem_readb(uint32_t saddr, uint8_t reg) "reg[%d]: 0x%2.2x"
+esp_mem_writeb(uint32_t saddr, uint8_t reg, uint32_t val) "reg[%d]: 0x%2.2x -> 0x%2.2x"
+esp_mem_writeb_cmd_nop(uint32_t val) "NOP (%2.2x)"
+esp_mem_writeb_cmd_flush(uint32_t val) "Flush FIFO (%2.2x)"
+esp_mem_writeb_cmd_reset(uint32_t val) "Chip reset (%2.2x)"
+esp_mem_writeb_cmd_bus_reset(uint32_t val) "Bus reset (%2.2x)"
+esp_mem_writeb_cmd_iccs(uint32_t val) "Initiator Command Complete Sequence (%2.2x)"
+esp_mem_writeb_cmd_msgacc(uint32_t val) "Message Accepted (%2.2x)"
+esp_mem_writeb_cmd_pad(uint32_t val) "Transfer padding (%2.2x)"
+esp_mem_writeb_cmd_satn(uint32_t val) "Set ATN (%2.2x)"
+esp_mem_writeb_cmd_rstatn(uint32_t val) "Reset ATN (%2.2x)"
+esp_mem_writeb_cmd_sel(uint32_t val) "Select without ATN (%2.2x)"
+esp_mem_writeb_cmd_selatn(uint32_t val) "Select with ATN (%2.2x)"
+esp_mem_writeb_cmd_selatns(uint32_t val) "Select with ATN & stop (%2.2x)"
+esp_mem_writeb_cmd_ensel(uint32_t val) "Enable selection (%2.2x)"
+esp_mem_writeb_cmd_dissel(uint32_t val) "Disable selection (%2.2x)"
+
+# hw/scsi/esp-pci.c
+esp_pci_error_invalid_dma_direction(void) "invalid DMA transfer direction"
+esp_pci_error_invalid_read(uint32_t reg) "read access outside bounds (reg 0x%x)"
+esp_pci_error_invalid_write(uint32_t reg) "write access outside bounds (reg 0x%x)"
+esp_pci_error_invalid_write_dma(uint32_t val, uint32_t addr) "invalid write of 0x%02x at [0x%x]"
+esp_pci_dma_read(uint32_t saddr, uint32_t reg) "reg[%d]: 0x%8.8x"
+esp_pci_dma_write(uint32_t saddr, uint32_t reg, uint32_t val) "reg[%d]: 0x%8.8x -> 0x%8.8x"
+esp_pci_dma_idle(uint32_t val) "IDLE (%.8x)"
+esp_pci_dma_blast(uint32_t val) "BLAST (%.8x)"
+esp_pci_dma_abort(uint32_t val) "ABORT (%.8x)"
+esp_pci_dma_start(uint32_t val) "START (%.8x)"
+esp_pci_sbac_read(uint32_t reg) "sbac: 0x%8.8x"
+esp_pci_sbac_write(uint32_t reg, uint32_t val) "sbac: 0x%8.8x -> 0x%8.8x"
+
 # monitor.c
 handle_qmp_command(void *mon, const char *cmd_name) "mon %p cmd_name \"%s\""
 monitor_protocol_emitter(void *mon) "mon %p"
@@ -104,13 +1058,546 @@ monitor_protocol_event_emit(uint32_t event, void *data) "event=%d data=%p"
 monitor_protocol_event_queue(uint32_t event, void *qdict, uint64_t rate) "event=%d data=%p rate=%" PRId64
 monitor_protocol_event_throttle(uint32_t event, uint64_t rate) "event=%d rate=%" PRId64
 
+# hw/net/opencores_eth.c
+open_eth_mii_write(unsigned idx, uint16_t v) "MII[%02x] <- %04x"
+open_eth_mii_read(unsigned idx, uint16_t v) "MII[%02x] -> %04x"
+open_eth_update_irq(uint32_t v) "IRQ <- %x"
+open_eth_receive(unsigned len) "RX: len: %u"
+open_eth_receive_mcast(unsigned idx, uint32_t h0, uint32_t h1) "MCAST: idx = %u, hash: %08x:%08x"
+open_eth_receive_reject(void) "RX: rejected"
+open_eth_receive_desc(uint32_t addr, uint32_t len_flags) "RX: %08x, len_flags: %08x"
+open_eth_start_xmit(uint32_t addr, unsigned len, unsigned tx_len) "TX: %08x, len: %u, tx_len: %u"
+open_eth_reg_read(uint32_t addr, uint32_t v) "MAC[%02x] -> %08x"
+open_eth_reg_write(uint32_t addr, uint32_t v) "MAC[%02x] <- %08x"
+open_eth_desc_read(uint32_t addr, uint32_t v) "DESC[%04x] -> %08x"
+open_eth_desc_write(uint32_t addr, uint32_t v) "DESC[%04x] <- %08x"
+
+# hw/9pfs/virtio-9p.c
+v9fs_rerror(uint16_t tag, uint8_t id, int err) "tag %d id %d err %d"
+v9fs_version(uint16_t tag, uint8_t id, int32_t msize, char* version) "tag %d id %d msize %d version %s"
+v9fs_version_return(uint16_t tag, uint8_t id, int32_t msize, char* version) "tag %d id %d msize %d version %s"
+v9fs_attach(uint16_t tag, uint8_t id, int32_t fid, int32_t afid, char* uname, char* aname) "tag %u id %u fid %d afid %d uname %s aname %s"
+v9fs_attach_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) "tag %d id %d type %d version %d path %"PRId64
+v9fs_stat(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
+v9fs_stat_return(uint16_t tag, uint8_t id, int32_t mode, int32_t atime, int32_t mtime, int64_t length) "tag %d id %d stat={mode %d atime %d mtime %d length %"PRId64"}"
+v9fs_getattr(uint16_t tag, uint8_t id, int32_t fid, uint64_t request_mask) "tag %d id %d fid %d request_mask %"PRIu64
+v9fs_getattr_return(uint16_t tag, uint8_t id, uint64_t result_mask, uint32_t mode, uint32_t uid, uint32_t gid) "tag %d id %d getattr={result_mask %"PRId64" mode %u uid %u gid %u}"
+v9fs_walk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, uint16_t nwnames) "tag %d id %d fid %d newfid %d nwnames %d"
+v9fs_walk_return(uint16_t tag, uint8_t id, uint16_t nwnames, void* qids) "tag %d id %d nwnames %d qids %p"
+v9fs_open(uint16_t tag, uint8_t id, int32_t fid, int32_t mode) "tag %d id %d fid %d mode %d"
+v9fs_open_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
+v9fs_lcreate(uint16_t tag, uint8_t id, int32_t dfid, int32_t flags, int32_t mode, uint32_t gid) "tag %d id %d dfid %d flags %d mode %d gid %u"
+v9fs_lcreate_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int32_t iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
+v9fs_fsync(uint16_t tag, uint8_t id, int32_t fid, int datasync) "tag %d id %d fid %d datasync %d"
+v9fs_clunk(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
+v9fs_read(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t max_count) "tag %d id %d fid %d off %"PRIu64" max_count %u"
+v9fs_read_return(uint16_t tag, uint8_t id, int32_t count, ssize_t err) "tag %d id %d count %d err %zd"
+v9fs_readdir(uint16_t tag, uint8_t id, int32_t fid, uint64_t offset, uint32_t max_count) "tag %d id %d fid %d offset %"PRIu64" max_count %u"
+v9fs_readdir_return(uint16_t tag, uint8_t id, uint32_t count, ssize_t retval) "tag %d id %d count %u retval %zd"
+v9fs_write(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t count, int cnt) "tag %d id %d fid %d off %"PRIu64" count %u cnt %d"
+v9fs_write_return(uint16_t tag, uint8_t id, int32_t total, ssize_t err) "tag %d id %d total %d err %zd"
+v9fs_create(uint16_t tag, uint8_t id, int32_t fid, char* name, int32_t perm, int8_t mode) "tag %d id %d fid %d name %s perm %d mode %d"
+v9fs_create_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
+v9fs_symlink(uint16_t tag, uint8_t id, int32_t fid,  char* name, char* symname, uint32_t gid) "tag %d id %d fid %d name %s symname %s gid %u"
+v9fs_symlink_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) "tag %d id %d qid={type %d version %d path %"PRId64"}"
+v9fs_flush(uint16_t tag, uint8_t id, int16_t flush_tag) "tag %d id %d flush_tag %d"
+v9fs_link(uint16_t tag, uint8_t id, int32_t dfid, int32_t oldfid, char* name) "tag %d id %d dfid %d oldfid %d name %s"
+v9fs_remove(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
+v9fs_wstat(uint16_t tag, uint8_t id, int32_t fid, int32_t mode, int32_t atime, int32_t mtime) "tag %u id %u fid %d stat={mode %d atime %d mtime %d}"
+v9fs_mknod(uint16_t tag, uint8_t id, int32_t fid, int mode, int major, int minor) "tag %d id %d fid %d mode %d major %d minor %d"
+v9fs_mknod_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) "tag %d id %d qid={type %d version %d path %"PRId64"}"
+v9fs_lock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length) "tag %d id %d fid %d type %d start %"PRIu64" length %"PRIu64
+v9fs_lock_return(uint16_t tag, uint8_t id, int8_t status) "tag %d id %d status %d"
+v9fs_getlock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length)"tag %d id %d fid %d type %d start %"PRIu64" length %"PRIu64
+v9fs_getlock_return(uint16_t tag, uint8_t id, uint8_t type, uint64_t start, uint64_t length, uint32_t proc_id) "tag %d id %d type %d start %"PRIu64" length %"PRIu64" proc_id %u"
+v9fs_mkdir(uint16_t tag, uint8_t id, int32_t fid, char* name, int mode, uint32_t gid) "tag %u id %u fid %d name %s mode %d gid %u"
+v9fs_mkdir_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int err) "tag %u id %u qid={type %d version %d path %"PRId64"} err %d"
+v9fs_xattrwalk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, char* name) "tag %d id %d fid %d newfid %d name %s"
+v9fs_xattrwalk_return(uint16_t tag, uint8_t id, int64_t size) "tag %d id %d size %"PRId64
+v9fs_xattrcreate(uint16_t tag, uint8_t id, int32_t fid, char* name, int64_t size, int flags) "tag %d id %d fid %d name %s size %"PRId64" flags %d"
+v9fs_readlink(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
+v9fs_readlink_return(uint16_t tag, uint8_t id, char* target) "tag %d id %d name %s"
+
+# target-sparc/mmu_helper.c
+mmu_helper_dfault(uint64_t address, uint64_t context, int mmu_idx, uint32_t tl) "DFAULT at %"PRIx64" context %"PRIx64" mmu_idx=%d tl=%d"
+mmu_helper_dprot(uint64_t address, uint64_t context, int mmu_idx, uint32_t tl) "DPROT at %"PRIx64" context %"PRIx64" mmu_idx=%d tl=%d"
+mmu_helper_dmiss(uint64_t address, uint64_t context) "DMISS at %"PRIx64" context %"PRIx64
+mmu_helper_tfault(uint64_t address, uint64_t context) "TFAULT at %"PRIx64" context %"PRIx64
+mmu_helper_tmiss(uint64_t address, uint64_t context) "TMISS at %"PRIx64" context %"PRIx64
+mmu_helper_get_phys_addr_code(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address) "tl=%d mmu_idx=%d primary context=%"PRIx64" secondary context=%"PRIx64" address=%"PRIx64
+mmu_helper_get_phys_addr_data(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address) "tl=%d mmu_idx=%d primary context=%"PRIx64" secondary context=%"PRIx64" address=%"PRIx64
+mmu_helper_mmu_fault(uint64_t address, uint64_t paddr, int mmu_idx, uint32_t tl, uint64_t prim_context, uint64_t sec_context) "Translate at %"PRIx64" -> %"PRIx64", mmu_idx=%d tl=%d primary context=%"PRIx64" secondary context=%"PRIx64
+
+# target-sparc/int64_helper.c
+int_helper_set_softint(uint32_t softint) "new %08x"
+int_helper_clear_softint(uint32_t softint) "new %08x"
+int_helper_write_softint(uint32_t softint) "new %08x"
+
+# target-sparc/int32_helper.c
+int_helper_icache_freeze(void) "Instruction cache: freeze"
+int_helper_dcache_freeze(void) "Data cache: freeze"
+
+# target-sparc/win_helper.c
+win_helper_gregset_error(uint32_t pstate) "ERROR in get_gregset: active pstate bits=%x"
+win_helper_switch_pstate(uint32_t pstate_regs, uint32_t new_pstate_regs) "change_pstate: switching regs old=%x new=%x"
+win_helper_no_switch_pstate(uint32_t new_pstate_regs) "change_pstate: regs new=%x (unchanged)"
+win_helper_wrpil(uint32_t psrpil, uint32_t new_pil) "old=%x new=%x"
+win_helper_done(uint32_t tl) "tl=%d"
+win_helper_retry(uint32_t tl) "tl=%d"
+
 # dma-helpers.c
-dma_blk_io(void *dbs, void *bs, int64_t offset, bool to_dev) "dbs=%p bs=%p offset=%" PRId64 " to_dev=%d"
+dma_blk_io(void *dbs, void *bs, int64_t sector_num, bool to_dev) "dbs=%p bs=%p sector_num=%" PRId64 " to_dev=%d"
 dma_aio_cancel(void *dbs) "dbs=%p"
 dma_complete(void *dbs, int ret, void *cb) "dbs=%p ret=%d cb=%p"
 dma_blk_cb(void *dbs, int ret) "dbs=%p ret=%d"
 dma_map_wait(void *dbs) "dbs=%p"
 
+# ui/console.c
+console_gfx_new(void) ""
+console_putchar_csi(int esc_param0, int esc_param1, int ch, int nb_esc_params) "escape sequence CSI%d;%d%c, %d parameters"
+console_putchar_unhandled(int ch) "unhandled escape character '%c'"
+console_txt_new(int w, int h) "%dx%d"
+console_select(int nr) "%d"
+console_refresh(int interval) "interval %d ms"
+displaysurface_create(void *display_surface, int w, int h) "surface=%p, %dx%d"
+displaysurface_create_from(void *display_surface, int w, int h, uint32_t format) "surface=%p, %dx%d, format 0x%x"
+displaysurface_create_pixman(void *display_surface) "surface=%p"
+displaysurface_free(void *display_surface) "surface=%p"
+displaychangelistener_register(void *dcl, const char *name) "%p [ %s ]"
+displaychangelistener_unregister(void *dcl, const char *name) "%p [ %s ]"
+ppm_save(const char *filename, void *display_surface) "%s surface=%p"
+
+# ui/gtk.c
+gd_switch(const char *tab, int width, int height) "tab=%s, width=%d, height=%d"
+gd_update(const char *tab, int x, int y, int w, int h) "tab=%s, x=%d, y=%d, w=%d, h=%d"
+gd_key_event(const char *tab, int gdk_keycode, int qemu_keycode, const char *action) "tab=%s, translated GDK keycode %d to QEMU keycode %d (%s)"
+gd_grab(const char *tab, const char *device, const char *reason) "tab=%s, dev=%s, reason=%s"
+gd_ungrab(const char *tab, const char *device) "tab=%s, dev=%s"
+
+# ui/vnc.c
+vnc_key_guest_leds(bool caps, bool num, bool scroll) "caps %d, num %d, scroll %d"
+vnc_key_map_init(const char *layout) "%s"
+vnc_key_event_ext(bool down, int sym, int keycode, const char *name) "down %d, sym 0x%x, keycode 0x%x [%s]"
+vnc_key_event_map(bool down, int sym, int keycode, const char *name) "down %d, sym 0x%x -> keycode 0x%x [%s]"
+vnc_key_sync_numlock(bool on) "%d"
+vnc_key_sync_capslock(bool on) "%d"
+
+# ui/input.c
+input_event_key_number(int conidx, int number, const char *qcode, bool down) "con %d, key number 0x%x [%s], down %d"
+input_event_key_qcode(int conidx, const char *qcode, bool down) "con %d, key qcode %s, down %d"
+input_event_btn(int conidx, const char *btn, bool down) "con %d, button %s, down %d"
+input_event_rel(int conidx, const char *axis, int value) "con %d, axis %s, value %d"
+input_event_abs(int conidx, const char *axis, int value) "con %d, axis %s, value 0x%x"
+input_event_sync(void) ""
+input_mouse_mode(int absolute) "absolute %d"
+
+# hw/display/vmware_vga.c
+vmware_value_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
+vmware_value_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
+vmware_palette_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
+vmware_palette_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
+vmware_scratch_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
+vmware_scratch_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
+vmware_setmode(uint32_t w, uint32_t h, uint32_t bpp) "%dx%d @ %d bpp"
+
+# hw/display/virtio-gpu.c
+virtio_gpu_features(bool virgl) "virgl %d"
+virtio_gpu_cmd_get_display_info(void) ""
+virtio_gpu_cmd_get_caps(void) ""
+virtio_gpu_cmd_set_scanout(uint32_t id, uint32_t res, uint32_t w, uint32_t h, uint32_t x, uint32_t y) "id %d, res 0x%x, w %d, h %d, x %d, y %d"
+virtio_gpu_cmd_res_create_2d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h) "res 0x%x, fmt 0x%x, w %d, h %d"
+virtio_gpu_cmd_res_create_3d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h, uint32_t d) "res 0x%x, fmt 0x%x, w %d, h %d, d %d"
+virtio_gpu_cmd_res_unref(uint32_t res) "res 0x%x"
+virtio_gpu_cmd_res_back_attach(uint32_t res) "res 0x%x"
+virtio_gpu_cmd_res_back_detach(uint32_t res) "res 0x%x"
+virtio_gpu_cmd_res_xfer_toh_2d(uint32_t res) "res 0x%x"
+virtio_gpu_cmd_res_xfer_toh_3d(uint32_t res) "res 0x%x"
+virtio_gpu_cmd_res_xfer_fromh_3d(uint32_t res) "res 0x%x"
+virtio_gpu_cmd_res_flush(uint32_t res, uint32_t w, uint32_t h, uint32_t x, uint32_t y) "res 0x%x, w %d, h %d, x %d, y %d"
+virtio_gpu_cmd_ctx_create(uint32_t ctx, const char *name) "ctx 0x%x, name %s"
+virtio_gpu_cmd_ctx_destroy(uint32_t ctx) "ctx 0x%x"
+virtio_gpu_cmd_ctx_res_attach(uint32_t ctx, uint32_t res) "ctx 0x%x, res 0x%x"
+virtio_gpu_cmd_ctx_res_detach(uint32_t ctx, uint32_t res) "ctx 0x%x, res 0x%x"
+virtio_gpu_cmd_ctx_submit(uint32_t ctx, uint32_t size) "ctx 0x%x, size %d"
+virtio_gpu_update_cursor(uint32_t scanout, uint32_t x, uint32_t y, const char *type, uint32_t res) "scanout %d, x %d, y %d, %s, res 0x%x"
+virtio_gpu_fence_ctrl(uint64_t fence, uint32_t type) "fence 0x%" PRIx64 ", type 0x%x"
+virtio_gpu_fence_resp(uint64_t fence) "fence 0x%" PRIx64
+
+# migration/savevm.c
+qemu_loadvm_state_section(unsigned int section_type) "%d"
+qemu_loadvm_state_section_command(int ret) "%d"
+qemu_loadvm_state_section_partend(uint32_t section_id) "%u"
+qemu_loadvm_state_main(void) ""
+qemu_loadvm_state_main_quit_parent(void) ""
+qemu_loadvm_state_post_main(int ret) "%d"
+qemu_loadvm_state_section_startfull(uint32_t section_id, const char *idstr, uint32_t instance_id, uint32_t version_id) "%u(%s) %u %u"
+qemu_savevm_send_packaged(void) ""
+loadvm_handle_cmd_packaged(unsigned int length) "%u"
+loadvm_handle_cmd_packaged_main(int ret) "%d"
+loadvm_handle_cmd_packaged_received(int ret) "%d"
+loadvm_postcopy_handle_advise(void) ""
+loadvm_postcopy_handle_listen(void) ""
+loadvm_postcopy_handle_run(void) ""
+loadvm_postcopy_handle_run_cpu_sync(void) ""
+loadvm_postcopy_handle_run_vmstart(void) ""
+loadvm_postcopy_ram_handle_discard(void) ""
+loadvm_postcopy_ram_handle_discard_end(void) ""
+loadvm_postcopy_ram_handle_discard_header(const char *ramid, uint16_t len) "%s: %ud"
+loadvm_process_command(uint16_t com, uint16_t len) "com=0x%x len=%d"
+loadvm_process_command_ping(uint32_t val) "%x"
+postcopy_ram_listen_thread_exit(void) ""
+postcopy_ram_listen_thread_start(void) ""
+qemu_savevm_send_postcopy_advise(void) ""
+qemu_savevm_send_postcopy_ram_discard(const char *id, uint16_t len) "%s: %ud"
+savevm_command_send(uint16_t command, uint16_t len) "com=0x%x len=%d"
+savevm_section_start(const char *id, unsigned int section_id) "%s, section_id %u"
+savevm_section_end(const char *id, unsigned int section_id, int ret) "%s, section_id %u -> %d"
+savevm_section_skip(const char *id, unsigned int section_id) "%s, section_id %u"
+savevm_send_open_return_path(void) ""
+savevm_send_ping(uint32_t val) "%x"
+savevm_send_postcopy_listen(void) ""
+savevm_send_postcopy_run(void) ""
+savevm_state_begin(void) ""
+savevm_state_header(void) ""
+savevm_state_iterate(void) ""
+savevm_state_cleanup(void) ""
+savevm_state_complete_precopy(void) ""
+vmstate_save(const char *idstr, const char *vmsd_name) "%s, %s"
+vmstate_load(const char *idstr, const char *vmsd_name) "%s, %s"
+qemu_announce_self_iter(const char *mac) "%s"
+
+# vmstate.c
+vmstate_load_field_error(const char *field, int ret) "field \"%s\" load failed, ret = %d"
+vmstate_load_state(const char *name, int version_id) "%s v%d"
+vmstate_load_state_end(const char *name, const char *reason, int val) "%s %s/%d"
+vmstate_load_state_field(const char *name, const char *field) "%s:%s"
+vmstate_subsection_load(const char *parent) "%s"
+vmstate_subsection_load_bad(const char *parent,  const char *sub) "%s: %s"
+vmstate_subsection_load_good(const char *parent) "%s"
+
+# qemu-file.c
+qemu_file_fclose(void) ""
+
+# migration/ram.c
+get_queued_page(const char *block_name, uint64_t tmp_offset, uint64_t ram_addr) "%s/%" PRIx64 " ram_addr=%" PRIx64
+get_queued_page_not_dirty(const char *block_name, uint64_t tmp_offset, uint64_t ram_addr, int sent) "%s/%" PRIx64 " ram_addr=%" PRIx64 " (sent=%d)"
+migration_bitmap_sync_start(void) ""
+migration_bitmap_sync_end(uint64_t dirty_pages) "dirty_pages %" PRIu64
+migration_throttle(void) ""
+ram_load_postcopy_loop(uint64_t addr, int flags) "@%" PRIx64 " %x"
+ram_postcopy_send_discard_bitmap(void) ""
+ram_save_queue_pages(const char *rbname, size_t start, size_t len) "%s: start: %zx len: %zx"
+
+# hw/display/qxl.c
+disable qxl_interface_set_mm_time(int qid, uint32_t mm_time) "%d %d"
+disable qxl_io_write_vga(int qid, const char *mode, uint32_t addr, uint32_t val) "%d %s addr=%u val=%u"
+qxl_create_guest_primary(int qid, uint32_t width, uint32_t height, uint64_t mem, uint32_t format, uint32_t position) "%d %ux%u mem=%" PRIx64 " %u,%u"
+qxl_create_guest_primary_rest(int qid, int32_t stride, uint32_t type, uint32_t flags) "%d %d,%d,%d"
+qxl_destroy_primary(int qid) "%d"
+qxl_enter_vga_mode(int qid) "%d"
+qxl_exit_vga_mode(int qid) "%d"
+qxl_hard_reset(int qid, int64_t loadvm) "%d loadvm=%"PRId64
+qxl_interface_async_complete_io(int qid, uint32_t current_async, void *cookie) "%d current=%d cookie=%p"
+qxl_interface_attach_worker(int qid) "%d"
+qxl_interface_get_init_info(int qid) "%d"
+qxl_interface_set_compression_level(int qid, int64_t level) "%d %"PRId64
+qxl_interface_update_area_complete(int qid, uint32_t surface_id, uint32_t dirty_left, uint32_t dirty_right, uint32_t dirty_top, uint32_t dirty_bottom) "%d surface=%d [%d,%d,%d,%d]"
+qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d #=%d"
+qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d"
+qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) "%d #dirty=%d"
+qxl_io_destroy_primary_ignored(int qid, const char *mode) "%d %s"
+qxl_io_log(int qid, const uint8_t *log_buf) "%d %s"
+qxl_io_read_unexpected(int qid) "%d"
+qxl_io_unexpected_vga_mode(int qid, uint64_t addr, uint64_t val, const char *desc) "%d 0x%"PRIx64"=%"PRIu64" (%s)"
+qxl_io_write(int qid, const char *mode, uint64_t addr, const char *aname, uint64_t val, unsigned size, int async) "%d %s addr=%"PRIu64 " (%s) val=%"PRIu64" size=%u async=%d"
+qxl_memslot_add_guest(int qid, uint32_t slot_id, uint64_t guest_start, uint64_t guest_end) "%d %u: guest phys 0x%"PRIx64 " - 0x%" PRIx64
+qxl_post_load(int qid, const char *mode) "%d %s"
+qxl_pre_load(int qid) "%d"
+qxl_pre_save(int qid) "%d"
+qxl_reset_surfaces(int qid) "%d"
+qxl_ring_command_check(int qid, const char *mode) "%d %s"
+qxl_ring_command_get(int qid, const char *mode) "%d %s"
+qxl_ring_command_req_notification(int qid) "%d"
+qxl_ring_cursor_check(int qid, const char *mode) "%d %s"
+qxl_ring_cursor_get(int qid, const char *mode) "%d %s"
+qxl_ring_cursor_req_notification(int qid) "%d"
+qxl_ring_res_push(int qid, const char *mode, uint32_t surface_count, uint32_t free_res, void *last_release, const char *notify) "%d %s s#=%d res#=%d last=%p notify=%s"
+qxl_ring_res_push_rest(int qid, uint32_t ring_has, uint32_t ring_size, uint32_t prod, uint32_t cons) "%d ring %d/%d [%d,%d]"
+qxl_ring_res_put(int qid, uint32_t free_res) "%d #res=%d"
+qxl_set_mode(int qid, int modenr, uint32_t x_res, uint32_t y_res, uint32_t bits, uint64_t devmem) "%d mode=%d [ x=%d y=%d @ bpp=%d devmem=0x%" PRIx64 " ]"
+qxl_soft_reset(int qid) "%d"
+qxl_spice_destroy_surfaces_complete(int qid) "%d"
+qxl_spice_destroy_surfaces(int qid, int async) "%d async=%d"
+qxl_spice_destroy_surface_wait_complete(int qid, uint32_t id) "%d sid=%d"
+qxl_spice_destroy_surface_wait(int qid, uint32_t id, int async) "%d sid=%d async=%d"
+qxl_spice_flush_surfaces_async(int qid, uint32_t surface_count, uint32_t num_free_res) "%d s#=%d, res#=%d"
+qxl_spice_monitors_config(int qid) "%d"
+qxl_spice_loadvm_commands(int qid, void *ext, uint32_t count) "%d ext=%p count=%d"
+qxl_spice_oom(int qid) "%d"
+qxl_spice_reset_cursor(int qid) "%d"
+qxl_spice_reset_image_cache(int qid) "%d"
+qxl_spice_reset_memslots(int qid) "%d"
+qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "%d sid=%d [%d,%d,%d,%d]"
+qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d"
+qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d"
+qxl_send_events(int qid, uint32_t events) "%d %d"
+qxl_send_events_vm_stopped(int qid, uint32_t events) "%d %d"
+qxl_set_guest_bug(int qid) "%d"
+qxl_interrupt_client_monitors_config(int qid, int num_heads, void *heads) "%d %d %p"
+qxl_client_monitors_config_unsupported_by_guest(int qid, uint32_t int_mask, void *client_monitors_config) "%d %X %p"
+qxl_client_monitors_config_unsupported_by_device(int qid, int revision) "%d revision=%d"
+qxl_client_monitors_config_capped(int qid, int requested, int limit) "%d %d %d"
+qxl_client_monitors_config_crc(int qid, unsigned size, uint32_t crc32) "%d %u %u"
+qxl_set_client_capabilities_unsupported_by_revision(int qid, int revision) "%d revision=%d"
+
+# ui/spice-display.c
+qemu_spice_add_memslot(int qid, uint32_t slot_id, unsigned long virt_start, unsigned long virt_end, int async) "%d %u: host virt 0x%lx - 0x%lx async=%d"
+qemu_spice_del_memslot(int qid, uint32_t gid, uint32_t slot_id) "%d gid=%u sid=%u"
+qemu_spice_create_primary_surface(int qid, uint32_t sid, void *surface, int async) "%d sid=%u surface=%p async=%d"
+qemu_spice_destroy_primary_surface(int qid, uint32_t sid, int async) "%d sid=%u async=%d"
+qemu_spice_wakeup(uint32_t qid) "%d"
+qemu_spice_create_update(uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "lr %d -> %d,  tb -> %d -> %d"
+
+# hw/display/qxl-render.c
+qxl_render_blit(int32_t stride, int32_t left, int32_t right, int32_t top, int32_t bottom) "stride=%d [%d, %d, %d, %d]"
+qxl_render_guest_primary_resized(int32_t width, int32_t height, int32_t stride, int32_t bytes_pp, int32_t bits_pp) "%dx%d, stride %d, bpp %d, depth %d"
+qxl_render_update_area_done(void *cookie) "%p"
+
+# hw/ppc/spapr_pci.c
+spapr_pci_msi(const char *msg, uint32_t ca) "%s (cfg=%x)"
+spapr_pci_msi_setup(const char *name, unsigned vector, uint64_t addr) "dev\"%s\" vector %u, addr=%"PRIx64
+spapr_pci_rtas_ibm_change_msi(unsigned cfg, unsigned func, unsigned req, unsigned first) "cfgaddr %x func %u, requested %u, first irq %u"
+spapr_pci_rtas_ibm_query_interrupt_source_number(unsigned ioa, unsigned intr) "queries for #%u, IRQ%u"
+spapr_pci_msi_write(uint64_t addr, uint64_t data, uint32_t dt_irq) "@%"PRIx64"<=%"PRIx64" IRQ %u"
+spapr_pci_lsi_set(const char *busname, int pin, uint32_t irq) "%s PIN%d IRQ %u"
+spapr_pci_msi_retry(unsigned config_addr, unsigned req_num, unsigned max_irqs) "Guest device at %x asked %u, have only %u"
+
+# hw/pci/pci.c
+pci_update_mappings_del(void *d, uint32_t bus, uint32_t slot, uint32_t func, int bar, uint64_t addr, uint64_t size) "d=%p %02x:%02x.%x %d,%#"PRIx64"+%#"PRIx64
+pci_update_mappings_add(void *d, uint32_t bus, uint32_t slot, uint32_t func, int bar, uint64_t addr, uint64_t size) "d=%p %02x:%02x.%x %d,%#"PRIx64"+%#"PRIx64
+
+# hw/net/pcnet.c
+pcnet_s_reset(void *s) "s=%p"
+pcnet_user_int(void *s) "s=%p"
+pcnet_isr_change(void *s, uint32_t isr, uint32_t isr_old) "s=%p INTA=%d<=%d"
+pcnet_init(void *s, uint64_t init_addr) "s=%p init_addr=%#"PRIx64
+pcnet_rlen_tlen(void *s, uint32_t rlen, uint32_t tlen) "s=%p rlen=%d tlen=%d"
+pcnet_ss32_rdra_tdra(void *s, uint32_t ss32, uint32_t rdra, uint32_t rcvrl, uint32_t tdra, uint32_t xmtrl) "s=%p ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]"
+
+# hw/net/pcnet-pci.c
+pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val) "opaque=%p addr=0x%08x val=0x%02x"
+pcnet_aprom_readb(void *opaque, uint32_t addr, uint32_t val) "opaque=%p addr=0x%08x val=0x%02x"
+pcnet_ioport_read(void *opaque, uint64_t addr, unsigned size) "opaque=%p addr=%#"PRIx64" size=%d"
+pcnet_ioport_write(void *opaque, uint64_t addr, uint64_t data, unsigned size) "opaque=%p addr=%#"PRIx64" data=%#"PRIx64" size=%d"
+pcnet_mmio_writeb(void *opaque, uint64_t addr, uint32_t val) "opaque=%p addr=%#"PRIx64" val=0x%x"
+pcnet_mmio_writew(void *opaque, uint64_t addr, uint32_t val) "opaque=%p addr=%#"PRIx64" val=0x%x"
+pcnet_mmio_writel(void *opaque, uint64_t addr, uint32_t val) "opaque=%p addr=%#"PRIx64" val=0x%x"
+pcnet_mmio_readb(void *opaque, uint64_t addr, uint32_t val) "opaque=%p addr=%#"PRIx64" val=0x%x"
+pcnet_mmio_readw(void *opaque, uint64_t addr, uint32_t val) "opaque=%p addr=%#"PRIx64" val=0x%x"
+pcnet_mmio_readl(void *opaque, uint64_t addr, uint32_t val) "opaque=%p addr=%#"PRIx64" val=0x%x"
+
+# hw/intc/xics.c
+xics_icp_check_ipi(int server, uint8_t mfrr) "CPU %d can take IPI mfrr=%#x"
+xics_icp_accept(uint32_t old_xirr, uint32_t new_xirr) "icp_accept: XIRR %#"PRIx32"->%#"PRIx32
+xics_icp_eoi(int server, uint32_t xirr, uint32_t new_xirr) "icp_eoi: server %d given XIRR %#"PRIx32" new XIRR %#"PRIx32
+xics_icp_irq(int server, int nr, uint8_t priority) "cpu %d trying to deliver irq %#"PRIx32" priority %#x"
+xics_icp_raise(uint32_t xirr, uint8_t pending_priority) "raising IRQ new XIRR=%#x new pending priority=%#x"
+xics_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq %#x]"
+xics_masked_pending(void) "set_irq_msi: masked pending"
+xics_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq %#x]"
+xics_ics_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_xive: irq %#x [src %d] server %#x prio %#x"
+xics_ics_reject(int nr, int srcno) "reject irq %#x [src %d]"
+xics_ics_eoi(int nr) "ics_eoi: irq %#x"
+xics_alloc(int src, int irq) "source#%d, irq %d"
+xics_alloc_block(int src, int first, int num, bool lsi, int align) "source#%d, first irq %d, %d irqs, lsi=%d, alignnum %d"
+xics_ics_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs"
+xics_ics_free_warn(int src, int irq) "Source#%d, irq %d is already free"
+
+# hw/ppc/spapr.c
+spapr_cas_failed(unsigned long n) "DT diff buffer is too small: %ld bytes"
+spapr_cas_continue(unsigned long n) "Copy changes to the guest: %ld bytes"
+
+# hw/ppc/spapr_hcall.c
+spapr_cas_pvr_try(uint32_t pvr) "%x"
+spapr_cas_pvr(uint32_t cur_pvr, bool cpu_match, uint32_t new_pvr, uint64_t pcr) "current=%x, cpu_match=%u, new=%x, compat flags=%"PRIx64
+
+# hw/ppc/spapr_iommu.c
+spapr_iommu_put(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tce=0x%"PRIx64" ret=%"PRId64
+spapr_iommu_get(uint64_t liobn, uint64_t ioba, uint64_t ret, uint64_t tce) "liobn=%"PRIx64" ioba=0x%"PRIx64" ret=%"PRId64" tce=0x%"PRIx64
+spapr_iommu_indirect(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t iobaN, uint64_t tceN, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tcelist=0x%"PRIx64" iobaN=0x%"PRIx64" tceN=0x%"PRIx64" ret=%"PRId64
+spapr_iommu_stuff(uint64_t liobn, uint64_t ioba, uint64_t tce_value, uint64_t npages, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tcevalue=0x%"PRIx64" npages=%"PRId64" ret=%"PRId64
+spapr_iommu_pci_put(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tce=0x%"PRIx64" ret=%"PRId64
+spapr_iommu_pci_get(uint64_t liobn, uint64_t ioba, uint64_t ret, uint64_t tce) "liobn=%"PRIx64" ioba=0x%"PRIx64" ret=%"PRId64" tce=0x%"PRIx64
+spapr_iommu_pci_indirect(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t iobaN, uint64_t tceN, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tcelist=0x%"PRIx64" iobaN=0x%"PRIx64" tceN=0x%"PRIx64" ret=%"PRId64
+spapr_iommu_pci_stuff(uint64_t liobn, uint64_t ioba, uint64_t tce_value, uint64_t npages, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tcevalue=0x%"PRIx64" npages=%"PRId64" ret=%"PRId64
+spapr_iommu_xlate(uint64_t liobn, uint64_t ioba, uint64_t tce, unsigned perm, unsigned pgsize) "liobn=%"PRIx64" 0x%"PRIx64" -> 0x%"PRIx64" perm=%u mask=%x"
+spapr_iommu_new_table(uint64_t liobn, void *tcet, void *table, int fd) "liobn=%"PRIx64" tcet=%p table=%p fd=%d"
+
+# hw/ppc/ppc.c
+ppc_tb_adjust(uint64_t offs1, uint64_t offs2, int64_t diff, int64_t seconds) "adjusted from 0x%"PRIx64" to 0x%"PRIx64", diff %"PRId64" (%"PRId64"s)"
+
+# hw/ppc/prep.c
+prep_io_800_writeb(uint32_t addr, uint32_t val) "0x%08" PRIx32 " => 0x%02" PRIx32
+prep_io_800_readb(uint32_t addr, uint32_t retval) "0x%08" PRIx32 " <= 0x%02" PRIx32
+
+# io/buffer.c
+buffer_resize(const char *buf, size_t olen, size_t len) "%s: old %zd, new %zd"
+buffer_move_empty(const char *buf, size_t len, const char *from) "%s: %zd bytes from %s"
+buffer_move(const char *buf, size_t len, const char *from) "%s: %zd bytes from %s"
+buffer_free(const char *buf, size_t len) "%s: capacity %zd"
+
+# util/hbitmap.c
+hbitmap_iter_skip_words(const void *hb, void *hbi, uint64_t pos, unsigned long cur) "hb %p hbi %p pos %"PRId64" cur 0x%lx"
+hbitmap_reset(void *hb, uint64_t start, uint64_t count, uint64_t sbit, uint64_t ebit) "hb %p items %"PRIu64",%"PRIu64" bits %"PRIu64"..%"PRIu64
+hbitmap_set(void *hb, uint64_t start, uint64_t count, uint64_t sbit, uint64_t ebit) "hb %p items %"PRIu64",%"PRIu64" bits %"PRIu64"..%"PRIu64
+
+# target-s390x/mmu_helper.c
+get_skeys_nonzero(int rc) "SKEY: Call to get_skeys unexpectedly returned %d"
+set_skeys_nonzero(int rc) "SKEY: Call to set_skeys unexpectedly returned %d"
+
+# target-s390x/ioinst.c
+ioinst(const char *insn) "IOINST: %s"
+ioinst_sch_id(const char *insn, int cssid, int ssid, int schid) "IOINST: %s (%x.%x.%04x)"
+ioinst_chp_id(const char *insn, int cssid, int chpid) "IOINST: %s (%x.%02x)"
+ioinst_chsc_cmd(uint16_t cmd, uint16_t len) "IOINST: chsc command %04x, len %04x"
+
+# hw/s390x/css.c
+css_enable_facility(const char *facility) "CSS: enable %s"
+css_crw(uint8_t rsc, uint8_t erc, uint16_t rsid, const char *chained) "CSS: queueing crw: rsc=%x, erc=%x, rsid=%x %s"
+css_chpid_add(uint8_t cssid, uint8_t chpid, uint8_t type) "CSS: add chpid %x.%02x (type %02x)"
+css_new_image(uint8_t cssid, const char *default_cssid) "CSS: add css image %02x %s"
+css_assign_subch(const char *do_assign, uint8_t cssid, uint8_t ssid, uint16_t schid, uint16_t devno) "CSS: %s %x.%x.%04x (devno %04x)"
+css_io_interrupt(int cssid, int ssid, int schid, uint32_t intparm, uint8_t isc, const char *conditional) "CSS: I/O interrupt on sch %x.%x.%04x (intparm %08x, isc %x) %s"
+css_adapter_interrupt(uint8_t isc) "CSS: adapter I/O interrupt (isc %x)"
+
+# hw/s390x/virtio-ccw.c
+virtio_ccw_interpret_ccw(int cssid, int ssid, int schid, int cmd_code) "VIRTIO-CCW: %x.%x.%04x: interpret command %x"
+virtio_ccw_new_device(int cssid, int ssid, int schid, int devno, const char *devno_mode) "VIRTIO-CCW: add subchannel %x.%x.%04x, devno %04x (%s)"
+
+# hw/intc/s390_flic_kvm.c
+flic_create_device(int err) "flic: create device failed %d"
+flic_no_device_api(int err) "flic: no Device Contral API support %d"
+flic_reset_failed(int err) "flic: reset failed %d"
+
+# migration.c
+await_return_path_close_on_source_close(void) ""
+await_return_path_close_on_source_joining(void) ""
+migrate_set_state(int new_state) "new state %d"
+migrate_fd_cleanup(void) ""
+migrate_fd_error(void) ""
+migrate_fd_cancel(void) ""
+migrate_handle_rp_req_pages(const char *rbname, size_t start, size_t len) "in %s at %zx len %zx"
+migrate_pending(uint64_t size, uint64_t max, uint64_t post, uint64_t nonpost) "pending size %" PRIu64 " max %" PRIu64 " (post=%" PRIu64 " nonpost=%" PRIu64 ")"
+migrate_send_rp_message(int msg_type, uint16_t len) "%d: len %d"
+migration_completion_file_err(void) ""
+migration_completion_postcopy_end(void) ""
+migration_completion_postcopy_end_after_complete(void) ""
+migration_completion_postcopy_end_before_rp(void) ""
+migration_completion_postcopy_end_after_rp(int rp_error) "%d"
+migration_thread_after_loop(void) ""
+migration_thread_file_err(void) ""
+migration_thread_setup_complete(void) ""
+open_return_path_on_source(void) ""
+open_return_path_on_source_continue(void) ""
+postcopy_start(void) ""
+postcopy_start_set_run(void) ""
+source_return_path_thread_bad_end(void) ""
+source_return_path_thread_end(void) ""
+source_return_path_thread_entry(void) ""
+source_return_path_thread_loop_top(void) ""
+source_return_path_thread_pong(uint32_t val) "%x"
+source_return_path_thread_shut(uint32_t val) "%x"
+migrate_global_state_post_load(const char *state) "loaded state: %s"
+migrate_global_state_pre_save(const char *state) "saved state: %s"
+migration_thread_low_pending(uint64_t pending) "%" PRIu64
+migrate_state_too_big(void) ""
+migrate_transferred(uint64_t tranferred, uint64_t time_spent, double bandwidth, uint64_t size) "transferred %" PRIu64 " time_spent %" PRIu64 " bandwidth %g max_size %" PRId64
+process_incoming_migration_co_end(int ret, int ps) "ret=%d postcopy-state=%d"
+process_incoming_migration_co_postcopy_end_main(void) ""
+
+# migration/rdma.c
+qemu_rdma_accept_incoming_migration(void) ""
+qemu_rdma_accept_incoming_migration_accepted(void) ""
+qemu_rdma_accept_pin_state(bool pin) "%d"
+qemu_rdma_accept_pin_verbsc(void *verbs) "Verbs context after listen: %p"
+qemu_rdma_block_for_wrid_miss(const char *wcompstr, int wcomp, const char *gcompstr, uint64_t req) "A Wanted wrid %s (%d) but got %s (%" PRIu64 ")"
+qemu_rdma_block_for_wrid_miss_b(const char *wcompstr, int wcomp, const char *gcompstr, uint64_t req) "B Wanted wrid %s (%d) but got %s (%" PRIu64 ")"
+qemu_rdma_cleanup_disconnect(void) ""
+qemu_rdma_cleanup_waiting_for_disconnect(void) ""
+qemu_rdma_close(void) ""
+qemu_rdma_connect_pin_all_requested(void) ""
+qemu_rdma_connect_pin_all_outcome(bool pin) "%d"
+qemu_rdma_dest_init_trying(const char *host, const char *ip) "%s => %s"
+qemu_rdma_dump_gid(const char *who, const char *src, const char *dst) "%s Source GID: %s, Dest GID: %s"
+qemu_rdma_exchange_get_response_start(const char *desc) "CONTROL: %s receiving..."
+qemu_rdma_exchange_get_response_none(const char *desc, int type) "Surprise: got %s (%d)"
+qemu_rdma_exchange_send_issue_callback(void) ""
+qemu_rdma_exchange_send_waiting(const char *desc) "Waiting for response %s"
+qemu_rdma_exchange_send_received(const char *desc) "Response %s received."
+qemu_rdma_fill(size_t control_len, size_t size) "RDMA %zd of %zd bytes already in buffer"
+qemu_rdma_init_ram_blocks(int blocks) "Allocated %d local ram block structures"
+qemu_rdma_poll_recv(const char *compstr, int64_t comp, int64_t id, int sent) "completion %s #%" PRId64 " received (%" PRId64 ") left %d"
+qemu_rdma_poll_write(const char *compstr, int64_t comp, int left, uint64_t block, uint64_t chunk, void *local, void *remote) "completions %s (%" PRId64 ") left %d, block %" PRIu64 ", chunk: %" PRIu64 " %p %p"
+qemu_rdma_poll_other(const char *compstr, int64_t comp, int left) "other completion %s (%" PRId64 ") received left %d"
+qemu_rdma_post_send_control(const char *desc) "CONTROL: sending %s.."
+qemu_rdma_register_and_get_keys(uint64_t len, void *start) "Registering %" PRIu64 " bytes @ %p"
+qemu_rdma_registration_handle_compress(int64_t length, int index, int64_t offset) "Zapping zero chunk: %" PRId64 " bytes, index %d, offset %" PRId64
+qemu_rdma_registration_handle_finished(void) ""
+qemu_rdma_registration_handle_ram_blocks(void) ""
+qemu_rdma_registration_handle_ram_blocks_loop(const char *name, uint64_t offset, uint64_t length, void *local_host_addr, unsigned int src_index) "%s: @%" PRIx64 "/%" PRIu64 " host:@%p src_index: %u"
+qemu_rdma_registration_handle_register(int requests) "%d requests"
+qemu_rdma_registration_handle_register_loop(int req, int index, uint64_t addr, uint64_t chunks) "Registration request (%d): index %d, current_addr %" PRIu64 " chunks: %" PRIu64
+qemu_rdma_registration_handle_register_rkey(int rkey) "%x"
+qemu_rdma_registration_handle_unregister(int requests) "%d requests"
+qemu_rdma_registration_handle_unregister_loop(int count, int index, uint64_t chunk) "Unregistration request (%d): index %d, chunk %" PRIu64
+qemu_rdma_registration_handle_unregister_success(uint64_t chunk) "%" PRIu64
+qemu_rdma_registration_handle_wait(void) ""
+qemu_rdma_registration_start(uint64_t flags) "%" PRIu64
+qemu_rdma_registration_stop(uint64_t flags) "%" PRIu64
+qemu_rdma_registration_stop_ram(void) ""
+qemu_rdma_resolve_host_trying(const char *host, const char *ip) "Trying %s => %s"
+qemu_rdma_signal_unregister_append(uint64_t chunk, int pos) "Appending unregister chunk %" PRIu64 " at position %d"
+qemu_rdma_signal_unregister_already(uint64_t chunk) "Unregister chunk %" PRIu64 " already in queue"
+qemu_rdma_unregister_waiting_inflight(uint64_t chunk) "Cannot unregister inflight chunk: %" PRIu64
+qemu_rdma_unregister_waiting_proc(uint64_t chunk, int pos) "Processing unregister for chunk: %" PRIu64 " at position %d"
+qemu_rdma_unregister_waiting_send(uint64_t chunk) "Sending unregister for chunk: %" PRIu64
+qemu_rdma_unregister_waiting_complete(uint64_t chunk) "Unregister for chunk: %" PRIu64 " complete."
+qemu_rdma_write_flush(int sent) "sent total: %d"
+qemu_rdma_write_one_block(int count, int block, uint64_t chunk, uint64_t current, uint64_t len, int nb_sent, int nb_chunks) "(%d) Not clobbering: block: %d chunk %" PRIu64 " current %" PRIu64 " len %" PRIu64 " %d %d"
+qemu_rdma_write_one_post(uint64_t chunk, long addr, long remote, uint32_t len) "Posting chunk: %" PRIu64 ", addr: %lx remote: %lx, bytes %" PRIu32
+qemu_rdma_write_one_queue_full(void) ""
+qemu_rdma_write_one_recvregres(int mykey, int theirkey, uint64_t chunk) "Received registration result: my key: %x their key %x, chunk %" PRIu64
+qemu_rdma_write_one_sendreg(uint64_t chunk, int len, int index, int64_t offset) "Sending registration request chunk %" PRIu64 " for %d bytes, index: %d, offset: %" PRId64
+qemu_rdma_write_one_top(uint64_t chunks, uint64_t size) "Writing %" PRIu64 " chunks, (%" PRIu64 " MB)"
+qemu_rdma_write_one_zero(uint64_t chunk, int len, int index, int64_t offset) "Entire chunk is zero, sending compress: %" PRIu64 " for %d bytes, index: %d, offset: %" PRId64
+rdma_add_block(const char *block_name, int block, uint64_t addr, uint64_t offset, uint64_t len, uint64_t end, uint64_t bits, int chunks) "Added Block: '%s':%d, addr: %" PRIu64 ", offset: %" PRIu64 " length: %" PRIu64 " end: %" PRIu64 " bits %" PRIu64 " chunks %d"
+rdma_block_notification_handle(const char *name, int index) "%s at %d"
+rdma_delete_block(void *block, uint64_t addr, uint64_t offset, uint64_t len, uint64_t end, uint64_t bits, int chunks) "Deleted Block: %p, addr: %" PRIu64 ", offset: %" PRIu64 " length: %" PRIu64 " end: %" PRIu64 " bits %" PRIu64 " chunks %d"
+rdma_start_incoming_migration(void) ""
+rdma_start_incoming_migration_after_dest_init(void) ""
+rdma_start_incoming_migration_after_rdma_listen(void) ""
+rdma_start_outgoing_migration_after_rdma_connect(void) ""
+rdma_start_outgoing_migration_after_rdma_source_init(void) ""
+
+# migration/postcopy-ram.c
+postcopy_discard_send_finish(const char *ramblock, int nwords, int ncmds) "%s mask words sent=%d in %d commands"
+postcopy_discard_send_range(const char *ramblock, unsigned long start, unsigned long length) "%s:%lx/%lx"
+postcopy_ram_discard_range(void *start, size_t length) "%p,+%zx"
+postcopy_cleanup_range(const char *ramblock, void *host_addr, size_t offset, size_t length) "%s: %p offset=%zx length=%zx"
+postcopy_init_range(const char *ramblock, void *host_addr, size_t offset, size_t length) "%s: %p offset=%zx length=%zx"
+postcopy_nhp_range(const char *ramblock, void *host_addr, size_t offset, size_t length) "%s: %p offset=%zx length=%zx"
+postcopy_place_page(void *host_addr) "host=%p"
+postcopy_place_page_zero(void *host_addr) "host=%p"
+postcopy_ram_enable_notify(void) ""
+postcopy_ram_fault_thread_entry(void) ""
+postcopy_ram_fault_thread_exit(void) ""
+postcopy_ram_fault_thread_quit(void) ""
+postcopy_ram_fault_thread_request(uint64_t hostaddr, const char *ramblock, size_t offset) "Request for HVA=%" PRIx64 " rb=%s offset=%zx"
+postcopy_ram_incoming_cleanup_closeuf(void) ""
+postcopy_ram_incoming_cleanup_entry(void) ""
+postcopy_ram_incoming_cleanup_exit(void) ""
+postcopy_ram_incoming_cleanup_join(void) ""
+
 # kvm-all.c
 kvm_ioctl(int type, void *arg) "type 0x%x, arg %p"
 kvm_vm_ioctl(int type, void *arg) "type 0x%x, arg %p"
@@ -119,15 +1606,16 @@ kvm_run_exit(int cpu_index, uint32_t reason) "cpu_index %d, reason %d"
 kvm_device_ioctl(int fd, int type, void *arg) "dev fd %d, type 0x%x, arg %p"
 kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve ONEREG %" PRIu64 " from KVM: %s"
 kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set ONEREG %" PRIu64 " to KVM: %s"
-kvm_irqchip_commit_routes(void) ""
-kvm_irqchip_add_msi_route(int virq) "Adding MSI route virq=%d"
-kvm_irqchip_update_msi_route(int virq) "Updating MSI route virq=%d"
+
+# target-ppc/kvm.c
+kvm_failed_spr_set(int str, const char *msg) "Warning: Unable to set SPR %d to KVM: %s"
+kvm_failed_spr_get(int str, const char *msg) "Warning: Unable to retrieve SPR %d from KVM: %s"
 
 # TCG related tracing (mostly disabled by default)
 # cpu-exec.c
 disable exec_tb(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
 disable exec_tb_nocache(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
-disable exec_tb_exit(void *last_tb, unsigned int flags) "tb:%p flags=%x"
+disable exec_tb_exit(void *next_tb, unsigned int flags) "tb:%p flags=%x"
 
 # translate-all.c
 translate_block(void *tb, uintptr_t pc, uint8_t *tb_code) "tb:%p, pc:0x%"PRIxPTR", tb_code:%p"
@@ -140,39 +1628,284 @@ memory_region_subpage_write(int cpu_index, void *mr, uint64_t offset, uint64_t v
 memory_region_tb_read(int cpu_index, uint64_t addr, uint64_t value, unsigned size) "cpu %d addr %#"PRIx64" value %#"PRIx64" size %u"
 memory_region_tb_write(int cpu_index, uint64_t addr, uint64_t value, unsigned size) "cpu %d addr %#"PRIx64" value %#"PRIx64" size %u"
 
-### Guest events, keep at bottom
+# qom/object.c
+object_dynamic_cast_assert(const char *type, const char *target, const char *file, int line, const char *func) "%s->%s (%s:%d:%s)"
+object_class_dynamic_cast_assert(const char *type, const char *target, const char *file, int line, const char *func) "%s->%s (%s:%d:%s)"
 
-# @vaddr: Access' virtual address.
-# @info : Access' information (see below).
-#
-# Start virtual memory access (before any potential access violation).
-#
-# Does not include memory accesses performed by devices.
-#
-# Access information can be parsed as:
-#
-# struct mem_info {
-#     uint8_t size_shift : 2; /* interpreted as "1 << size_shift" bytes */
-#     bool    sign_extend: 1; /* sign-extended */
-#     uint8_t endianness : 1; /* 0: little, 1: big */
-#     bool    store      : 1; /* wheter it's a store operation */
-# };
-#
-# Targets: TCG(all)
-disable vcpu tcg guest_mem_before(TCGv vaddr, uint8_t info) "info=%d", "vaddr=0x%016"PRIx64" info=%d"
+# hw/i386/xen/xen_pvdevice.c
+xen_pv_mmio_read(uint64_t addr) "WARNING: read from Xen PV Device MMIO space (address %"PRIx64")"
+xen_pv_mmio_write(uint64_t addr) "WARNING: write to Xen PV Device MMIO space (address %"PRIx64")"
 
-# @num: System call number.
-# @arg*: System call argument value.
-#
-# Start executing a guest system call in syscall emulation mode.
-#
-# Targets: TCG(all)
-disable vcpu guest_user_syscall(uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8) "num=0x%016"PRIx64" arg1=0x%016"PRIx64" arg2=0x%016"PRIx64" arg3=0x%016"PRIx64" arg4=0x%016"PRIx64" arg5=0x%016"PRIx64" arg6=0x%016"PRIx64" arg7=0x%016"PRIx64" arg8=0x%016"PRIx64
+# hw/pci/pci_host.c
+pci_cfg_read(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x -> 0x%x"
+pci_cfg_write(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x <- 0x%x"
 
-# @num: System call number.
-# @ret: System call result value.
-#
-# Finish executing a guest system call in syscall emulation mode.
-#
-# Targets: TCG(all)
-disable vcpu guest_user_syscall_ret(uint64_t num, uint64_t ret) "num=0x%016"PRIx64" ret=0x%016"PRIx64
+# hw/vfio/pci.c
+vfio_intx_interrupt(const char *name, char line) " (%s) Pin %c"
+vfio_intx_eoi(const char *name) " (%s) EOI"
+vfio_intx_enable_kvm(const char *name) " (%s) KVM INTx accel enabled"
+vfio_intx_disable_kvm(const char *name) " (%s) KVM INTx accel disabled"
+vfio_intx_update(const char *name, int new_irq, int target_irq) " (%s) IRQ moved %d -> %d"
+vfio_intx_enable(const char *name) " (%s)"
+vfio_intx_disable(const char *name) " (%s)"
+vfio_msi_interrupt(const char *name, int index, uint64_t addr, int data) " (%s) vector %d 0x%"PRIx64"/0x%x"
+vfio_msix_vector_do_use(const char *name, int index) " (%s) vector %d used"
+vfio_msix_vector_release(const char *name, int index) " (%s) vector %d released"
+vfio_msix_enable(const char *name) " (%s)"
+vfio_msix_pba_disable(const char *name) " (%s)"
+vfio_msix_pba_enable(const char *name) " (%s)"
+vfio_msix_disable(const char *name) " (%s)"
+vfio_msix_fixup(const char *name, int bar, uint64_t start, uint64_t end) " (%s) MSI-X region %d mmap fixup [0x%"PRIx64" - 0x%"PRIx64"]"
+vfio_msi_enable(const char *name, int nr_vectors) " (%s) Enabled %d MSI vectors"
+vfio_msi_disable(const char *name) " (%s)"
+vfio_pci_load_rom(const char *name, unsigned long size, unsigned long offset, unsigned long flags) "Device %s ROM:\n  size: 0x%lx, offset: 0x%lx, flags: 0x%lx"
+vfio_rom_read(const char *name, uint64_t addr, int size, uint64_t data) " (%s, 0x%"PRIx64", 0x%x) = 0x%"PRIx64
+vfio_pci_size_rom(const char *name, int size) "%s ROM size 0x%x"
+vfio_vga_write(uint64_t addr, uint64_t data, int size) " (0x%"PRIx64", 0x%"PRIx64", %d)"
+vfio_vga_read(uint64_t addr, int size, uint64_t data) " (0x%"PRIx64", %d) = 0x%"PRIx64
+vfio_pci_read_config(const char *name, int addr, int len, int val) " (%s, @0x%x, len=0x%x) %x"
+vfio_pci_write_config(const char *name, int addr, int val, int len) " (%s, @0x%x, 0x%x, len=0x%x)"
+vfio_msi_setup(const char *name, int pos) "%s PCI MSI CAP @0x%x"
+vfio_msix_early_setup(const char *name, int pos, int table_bar, int offset, int entries) "%s PCI MSI-X CAP @0x%x, BAR %d, offset 0x%x, entries %d"
+vfio_check_pcie_flr(const char *name) "%s Supports FLR via PCIe cap"
+vfio_check_pm_reset(const char *name) "%s Supports PM reset"
+vfio_check_af_flr(const char *name) "%s Supports FLR via AF cap"
+vfio_pci_hot_reset(const char *name, const char *type) " (%s) %s"
+vfio_pci_hot_reset_has_dep_devices(const char *name) "%s: hot reset dependent devices:"
+vfio_pci_hot_reset_dep_devices(int domain, int bus, int slot, int function, int group_id) "\t%04x:%02x:%02x.%x group %d"
+vfio_pci_hot_reset_result(const char *name, const char *result) "%s hot reset: %s"
+vfio_populate_device_config(const char *name, unsigned long size, unsigned long offset, unsigned long flags) "Device %s config:\n  size: 0x%lx, offset: 0x%lx, flags: 0x%lx"
+vfio_populate_device_get_irq_info_failure(void) "VFIO_DEVICE_GET_IRQ_INFO failure: %m"
+vfio_initfn(const char *name, int group_id) " (%s) group %d"
+vfio_pci_reset(const char *name) " (%s)"
+vfio_pci_reset_flr(const char *name) "%s FLR/VFIO_DEVICE_RESET"
+vfio_pci_reset_pm(const char *name) "%s PCI PM Reset"
+vfio_pci_emulated_vendor_id(const char *name, uint16_t val) "%s %04x"
+vfio_pci_emulated_device_id(const char *name, uint16_t val) "%s %04x"
+vfio_pci_emulated_sub_vendor_id(const char *name, uint16_t val) "%s %04x"
+vfio_pci_emulated_sub_device_id(const char *name, uint16_t val) "%s %04x"
+
+# hw/vfio/pci-quirks.
+vfio_quirk_rom_blacklisted(const char *name, uint16_t vid, uint16_t did) "%s %04x:%04x"
+vfio_quirk_generic_window_address_write(const char *name, const char * region_name, uint64_t data) "%s %s 0x%"PRIx64
+vfio_quirk_generic_window_data_read(const char *name, const char * region_name, uint64_t data) "%s %s 0x%"PRIx64
+vfio_quirk_generic_window_data_write(const char *name, const char * region_name, uint64_t data) "%s %s 0x%"PRIx64
+vfio_quirk_generic_mirror_read(const char *name, const char * region_name, uint64_t addr, uint64_t data) "%s %s 0x%"PRIx64": 0x%"PRIx64
+vfio_quirk_generic_mirror_write(const char *name, const char * region_name, uint64_t addr, uint64_t data) "%s %s 0x%"PRIx64": 0x%"PRIx64
+vfio_quirk_ati_3c3_read(const char *name, uint64_t data) "%s 0x%"PRIx64
+vfio_quirk_ati_3c3_probe(const char *name) "%s"
+vfio_quirk_ati_bar4_probe(const char *name) "%s"
+vfio_quirk_ati_bar2_probe(const char *name) "%s"
+vfio_quirk_nvidia_3d0_state(const char *name, const char *state) "%s %s"
+vfio_quirk_nvidia_3d0_read(const char *name, uint8_t offset, unsigned size, uint64_t val) " (%s, @0x%x, len=0x%x) %"PRIx64
+vfio_quirk_nvidia_3d0_write(const char *name, uint8_t offset, uint64_t data, unsigned size) "(%s, @0x%x, 0x%"PRIx64", len=0x%x)"
+vfio_quirk_nvidia_3d0_probe(const char *name) "%s"
+vfio_quirk_nvidia_bar5_state(const char *name, const char *state) "%s %s"
+vfio_quirk_nvidia_bar5_probe(const char *name) "%s"
+vfio_quirk_nvidia_bar0_msi_ack(const char *name) "%s"
+vfio_quirk_nvidia_bar0_probe(const char *name) "%s"
+vfio_quirk_rtl8168_fake_latch(const char *name, uint64_t val) "%s 0x%"PRIx64
+vfio_quirk_rtl8168_msix_write(const char *name, uint16_t offset, uint64_t val) "%s MSI-X table write[0x%x]: 0x%"PRIx64
+vfio_quirk_rtl8168_msix_read(const char *name, uint16_t offset, uint64_t val) "%s MSI-X table read[0x%x]: 0x%"PRIx64
+vfio_quirk_rtl8168_probe(const char *name) "%s"
+
+vfio_quirk_ati_bonaire_reset_skipped(const char *name) "%s"
+vfio_quirk_ati_bonaire_reset_no_smc(const char *name) "%s"
+vfio_quirk_ati_bonaire_reset_timeout(const char *name) "%s"
+vfio_quirk_ati_bonaire_reset_done(const char *name) "%s"
+vfio_quirk_ati_bonaire_reset(const char *name) "%s"
+
+
+# hw/vfio/vfio-common.c
+vfio_region_write(const char *name, int index, uint64_t addr, uint64_t data, unsigned size) " (%s:region%d+0x%"PRIx64", 0x%"PRIx64 ", %d)"
+vfio_region_read(char *name, int index, uint64_t addr, unsigned size, uint64_t data) " (%s:region%d+0x%"PRIx64", %d) = 0x%"PRIx64
+vfio_iommu_map_notify(uint64_t iova_start, uint64_t iova_end) "iommu map @ %"PRIx64" - %"PRIx64
+vfio_listener_region_add_skip(uint64_t start, uint64_t end) "SKIPPING region_add %"PRIx64" - %"PRIx64
+vfio_listener_region_add_iommu(uint64_t start, uint64_t end) "region_add [iommu] %"PRIx64" - %"PRIx64
+vfio_listener_region_add_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] %"PRIx64" - %"PRIx64" [%p]"
+vfio_listener_region_del_skip(uint64_t start, uint64_t end) "SKIPPING region_del %"PRIx64" - %"PRIx64
+vfio_listener_region_del(uint64_t start, uint64_t end) "region_del %"PRIx64" - %"PRIx64
+vfio_disconnect_container(int fd) "close container->fd=%d"
+vfio_put_group(int fd) "close group->fd=%d"
+vfio_get_device(const char * name, unsigned int flags, unsigned int num_regions, unsigned int num_irqs) "Device %s flags: %u, regions: %u, irqs: %u"
+vfio_put_base_device(int fd) "close vdev->fd=%d"
+vfio_region_setup(const char *dev, int index, const char *name, unsigned long flags, unsigned long offset, unsigned long size) "Device %s, region %d \"%s\", flags: %lx, offset: %lx, size: %lx"
+vfio_region_mmap_fault(const char *name, int index, unsigned long offset, unsigned long size, int fault) "Region %s mmaps[%d], [%lx - %lx], fault: %d"
+vfio_region_mmap(const char *name, unsigned long offset, unsigned long end) "Region %s [%lx - %lx]"
+vfio_region_exit(const char *name, int index) "Device %s, region %d"
+vfio_region_finalize(const char *name, int index) "Device %s, region %d"
+vfio_region_mmaps_set_enabled(const char *name, bool enabled) "Region %s mmaps enabled: %d"
+
+# hw/vfio/platform.c
+vfio_platform_base_device_init(char *name, int groupid) "%s belongs to group #%d"
+vfio_platform_realize(char *name, char *compat) "vfio device %s, compat = %s"
+vfio_platform_eoi(int pin, int fd) "EOI IRQ pin %d (fd=%d)"
+vfio_platform_intp_mmap_enable(int pin) "IRQ #%d still active, stay in slow path"
+vfio_platform_intp_interrupt(int pin, int fd) "Inject IRQ #%d (fd = %d)"
+vfio_platform_intp_inject_pending_lockheld(int pin, int fd) "Inject pending IRQ #%d (fd = %d)"
+vfio_platform_populate_interrupts(int pin, int count, int flags) "- IRQ index %d: count %d, flags=0x%x"
+vfio_intp_interrupt_set_pending(int index) "irq %d is set PENDING"
+vfio_platform_start_level_irqfd_injection(int index, int fd, int resamplefd) "IRQ index=%d, fd = %d, resamplefd = %d"
+vfio_platform_start_edge_irqfd_injection(int index, int fd) "IRQ index=%d, fd = %d"
+
+
+#hw/acpi/memory_hotplug.c
+mhp_acpi_invalid_slot_selected(uint32_t slot) "0x%"PRIx32
+mhp_acpi_ejecting_invalid_slot(uint32_t slot) "0x%"PRIx32
+mhp_acpi_read_addr_lo(uint32_t slot, uint32_t addr) "slot[0x%"PRIx32"] addr lo: 0x%"PRIx32
+mhp_acpi_read_addr_hi(uint32_t slot, uint32_t addr) "slot[0x%"PRIx32"] addr hi: 0x%"PRIx32
+mhp_acpi_read_size_lo(uint32_t slot, uint32_t size) "slot[0x%"PRIx32"] size lo: 0x%"PRIx32
+mhp_acpi_read_size_hi(uint32_t slot, uint32_t size) "slot[0x%"PRIx32"] size hi: 0x%"PRIx32
+mhp_acpi_read_pxm(uint32_t slot, uint32_t pxm) "slot[0x%"PRIx32"] proximity: 0x%"PRIx32
+mhp_acpi_read_flags(uint32_t slot, uint32_t flags) "slot[0x%"PRIx32"] flags: 0x%"PRIx32
+mhp_acpi_write_slot(uint32_t slot) "set active slot: 0x%"PRIx32
+mhp_acpi_write_ost_ev(uint32_t slot, uint32_t ev) "slot[0x%"PRIx32"] OST EVENT: 0x%"PRIx32
+mhp_acpi_write_ost_status(uint32_t slot, uint32_t st) "slot[0x%"PRIx32"] OST STATUS: 0x%"PRIx32
+mhp_acpi_clear_insert_evt(uint32_t slot) "slot[0x%"PRIx32"] clear insert event"
+mhp_acpi_clear_remove_evt(uint32_t slot) "slot[0x%"PRIx32"] clear remove event"
+mhp_acpi_pc_dimm_deleted(uint32_t slot) "slot[0x%"PRIx32"] pc-dimm deleted"
+mhp_acpi_pc_dimm_delete_failed(uint32_t slot) "slot[0x%"PRIx32"] pc-dimm delete failed"
+
+# hw/i386/pc.c
+mhp_pc_dimm_assigned_slot(int slot) "0x%d"
+mhp_pc_dimm_assigned_address(uint64_t addr) "0x%"PRIx64
+
+# target-s390x/kvm.c
+kvm_enable_cmma(int rc) "CMMA: enabling with result code %d"
+kvm_clear_cmma(int rc) "CMMA: clearing with result code %d"
+kvm_failed_cpu_state_set(int cpu_index, uint8_t state, const char *msg) "Warning: Unable to set cpu %d state %" PRIu8 " to KVM: %s"
+kvm_sigp_finished(uint8_t order, int cpu_index, int dst_index, int cc) "SIGP: Finished order %u on cpu %d -> cpu %d with cc=%d"
+
+# hw/dma/i8257.c
+i8257_unregistered_dma(int nchan, int dma_pos, int dma_len) "unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d"
+
+# target-s390x/cpu.c
+cpu_set_state(int cpu_index, uint8_t state) "setting cpu %d state to %" PRIu8
+cpu_halt(int cpu_index) "halting cpu %d"
+cpu_unhalt(int cpu_index) "unhalting cpu %d"
+
+# hw/arm/virt-acpi-build.c
+virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
+
+# hw/alpha/pci.c
+alpha_pci_iack_write(void) ""
+
+# audio/alsaaudio.c
+alsa_revents(int revents) "revents = %d"
+alsa_pollout(int i, int fd) "i = %d fd = %d"
+alsa_set_handler(int events, int index, int fd, int err) "events=%#x index=%d fd=%d err=%d"
+alsa_wrote_zero(int len) "Failed to write %d frames (wrote zero)"
+alsa_read_zero(long len) "Failed to read %ld frames (read zero)"
+alsa_xrun_out(void) "Recovering from playback xrun"
+alsa_xrun_in(void) "Recovering from capture xrun"
+alsa_resume_out(void) "Resuming suspended output stream"
+alsa_resume_in(void) "Resuming suspended input stream"
+alsa_no_frames(int state) "No frames available and ALSA state is %d"
+
+# audio/ossaudio.c
+oss_version(int version) "OSS version = %#x"
+oss_invalid_available_size(int size, int bufsize) "Invalid available size, size=%d bufsize=%d"
+
+# crypto/tlscreds.c
+qcrypto_tls_creds_load_dh(void *creds, const char *filename) "TLS creds load DH creds=%p filename=%s"
+qcrypto_tls_creds_get_path(void *creds, const char *filename, const char *path) "TLS creds path creds=%p filename=%s path=%s"
+
+# crypto/tlscredsanon.c
+qcrypto_tls_creds_anon_load(void *creds, const char *dir) "TLS creds anon load creds=%p dir=%s"
+
+# crypto/tlscredsx509.c
+qcrypto_tls_creds_x509_load(void *creds, const char *dir) "TLS creds x509 load creds=%p dir=%s"
+qcrypto_tls_creds_x509_check_basic_constraints(void *creds, const char *file, int status) "TLS creds x509 check basic constraints creds=%p file=%s status=%d"
+qcrypto_tls_creds_x509_check_key_usage(void *creds, const char *file, int status, int usage, int critical) "TLS creds x509 check key usage creds=%p file=%s status=%d usage=%d critical=%d"
+qcrypto_tls_creds_x509_check_key_purpose(void *creds, const char *file, int status, const char *usage, int critical) "TLS creds x509 check key usage creds=%p file=%s status=%d usage=%s critical=%d"
+qcrypto_tls_creds_x509_load_cert(void *creds, int isServer, const char *file) "TLS creds x509 load cert creds=%p isServer=%d file=%s"
+qcrypto_tls_creds_x509_load_cert_list(void *creds, const char *file) "TLS creds x509 load cert list creds=%p file=%s"
+
+# crypto/tlssession.c
+qcrypto_tls_session_new(void *session, void *creds, const char *hostname, const char *aclname, int endpoint) "TLS session new session=%p creds=%p hostname=%s aclname=%s endpoint=%d"
+
+# net/vhost-user.c
+vhost_user_event(const char *chr, int event) "chr: %s got event: %d"
+
+# linux-user/signal.c
+user_setup_frame(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64
+user_setup_rt_frame(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64
+user_do_rt_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64
+user_do_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64
+user_force_sig(void *env, int target_sig, int host_sig) "env=%p signal %d (host %d)"
+user_handle_signal(void *env, int target_sig) "env=%p signal %d"
+user_host_signal(void *env, int host_sig, int target_sig) "env=%p signal %d (target %d("
+user_queue_signal(void *env, int target_sig) "env=%p signal %d"
+user_s390x_restore_sigregs(void *env, uint64_t sc_psw_addr, uint64_t env_psw_addr) "env=%p frame psw.addr %"PRIx64 " current psw.addr %"PRIx64
+
+# io/task.c
+qio_task_new(void *task, void *source, void *func, void *opaque) "Task new task=%p source=%p func=%p opaque=%p"
+qio_task_complete(void *task) "Task complete task=%p"
+qio_task_abort(void *task) "Task abort task=%p"
+qio_task_thread_start(void *task, void *worker, void *opaque) "Task thread start task=%p worker=%p opaque=%p"
+qio_task_thread_run(void *task) "Task thread run task=%p"
+qio_task_thread_exit(void *task) "Task thread exit task=%p"
+qio_task_thread_result(void *task) "Task thread result task=%p"
+
+# io/channel-socket.c
+qio_channel_socket_new(void *ioc) "Socket new ioc=%p"
+qio_channel_socket_new_fd(void *ioc, int fd) "Socket new ioc=%p fd=%d"
+qio_channel_socket_connect_sync(void *ioc, void *addr) "Socket connect sync ioc=%p addr=%p"
+qio_channel_socket_connect_async(void *ioc, void *addr) "Socket connect async ioc=%p addr=%p"
+qio_channel_socket_connect_fail(void *ioc) "Socket connect fail ioc=%p"
+qio_channel_socket_connect_complete(void *ioc, int fd) "Socket connect complete ioc=%p fd=%d"
+qio_channel_socket_listen_sync(void *ioc, void *addr) "Socket listen sync ioc=%p addr=%p"
+qio_channel_socket_listen_async(void *ioc, void *addr) "Socket listen async ioc=%p addr=%p"
+qio_channel_socket_listen_fail(void *ioc) "Socket listen fail ioc=%p"
+qio_channel_socket_listen_complete(void *ioc, int fd) "Socket listen complete ioc=%p fd=%d"
+qio_channel_socket_dgram_sync(void *ioc, void *localAddr, void *remoteAddr) "Socket dgram sync ioc=%p localAddr=%p remoteAddr=%p"
+qio_channel_socket_dgram_async(void *ioc, void *localAddr, void *remoteAddr) "Socket dgram async ioc=%p localAddr=%p remoteAddr=%p"
+qio_channel_socket_dgram_fail(void *ioc) "Socket dgram fail ioc=%p"
+qio_channel_socket_dgram_complete(void *ioc, int fd) "Socket dgram complete ioc=%p fd=%d"
+qio_channel_socket_accept(void *ioc) "Socket accept start ioc=%p"
+qio_channel_socket_accept_fail(void *ioc) "Socket accept fail ioc=%p"
+qio_channel_socket_accept_complete(void *ioc, void *cioc, int fd) "Socket accept complete ioc=%p cioc=%p fd=%d"
+
+# io/channel-file.c
+qio_channel_file_new_fd(void *ioc, int fd) "File new fd ioc=%p fd=%d"
+qio_channel_file_new_path(void *ioc, const char *path, int flags, int mode, int fd) "File new fd ioc=%p path=%s flags=%d mode=%d fd=%d"
+
+# io/channel-tls.c
+qio_channel_tls_new_client(void *ioc, void *master, void *creds, const char *hostname) "TLS new client ioc=%p master=%p creds=%p hostname=%s"
+qio_channel_tls_new_server(void *ioc, void *master, void *creds, const char *aclname) "TLS new client ioc=%p master=%p creds=%p acltname=%s"
+qio_channel_tls_handshake_start(void *ioc) "TLS handshake start ioc=%p"
+qio_channel_tls_handshake_pending(void *ioc, int status) "TLS handshake pending ioc=%p status=%d"
+qio_channel_tls_handshake_fail(void *ioc) "TLS handshake fail ioc=%p"
+qio_channel_tls_handshake_complete(void *ioc) "TLS handshake complete ioc=%p"
+qio_channel_tls_credentials_allow(void *ioc) "TLS credentials allow ioc=%p"
+qio_channel_tls_credentials_deny(void *ioc) "TLS credentials deny ioc=%p"
+
+# io/channel-websock.c
+qio_channel_websock_new_server(void *ioc, void *master) "Websock new client ioc=%p master=%p"
+qio_channel_websock_handshake_start(void *ioc) "Websock handshake start ioc=%p"
+qio_channel_websock_handshake_pending(void *ioc, int status) "Websock handshake pending ioc=%p status=%d"
+qio_channel_websock_handshake_reply(void *ioc) "Websock handshake reply ioc=%p"
+qio_channel_websock_handshake_fail(void *ioc) "Websock handshake fail ioc=%p"
+qio_channel_websock_handshake_complete(void *ioc) "Websock handshake complete ioc=%p"
+
+# io/channel-command.c
+qio_channel_command_new_pid(void *ioc, int writefd, int readfd, int pid) "Command new pid ioc=%p writefd=%d readfd=%d pid=%d"
+qio_channel_command_new_spawn(void *ioc, const char *binary, int flags) "Command new spawn ioc=%p binary=%s flags=%d"
+qio_channel_command_abort(void *ioc, int pid) "Command abort ioc=%p pid=%d"
+qio_channel_command_wait(void *ioc, int pid, int ret, int status) "Command abort ioc=%p pid=%d ret=%d status=%d"
+
+# hw/timer/aspeed_timer.c
+aspeed_timer_ctrl_enable(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
+aspeed_timer_ctrl_external_clock(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
+aspeed_timer_ctrl_overflow_interrupt(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
+aspeed_timer_ctrl_pulse_enable(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
+aspeed_timer_set_ctrl2(uint32_t value) "Value: 0x%" PRIx32
+aspeed_timer_set_value(int timer, int reg, uint32_t value) "Timer %d register %d: 0x%" PRIx32
+aspeed_timer_read(uint64_t offset, unsigned size, uint64_t value) "From 0x%" PRIx64 ": of size %u: 0x%" PRIx64
+
+# hw/intc/aspeed_vic.c
+aspeed_vic_set_irq(int irq, int level) "Enabling IRQ %d: %d"
+aspeed_vic_update_fiq(int flags) "Raising FIQ: %d"
+aspeed_vic_update_irq(int flags) "Raising IRQ: %d"
+aspeed_vic_read(uint64_t offset, unsigned size, uint32_t value) "From 0x%" PRIx64 " of size %u: 0x%" PRIx32
+aspeed_vic_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
index 4d91b3b..5145b34 100644 (file)
@@ -8,17 +8,13 @@
 tracetool-y = $(SRC_PATH)/scripts/tracetool.py
 tracetool-y += $(shell find $(SRC_PATH)/scripts/tracetool -name "*.py")
 
-$(BUILD_DIR)/trace-events-all: $(trace-events-y:%=$(SRC_PATH)/%)
-       $(call quiet-command,cat $^ > $@)
-
 ######################################################################
 # Auto-generated event descriptions for LTTng ust code
 
 ifeq ($(findstring ust,$(TRACE_BACKENDS)),ust)
-
 $(obj)/generated-ust-provider.h: $(obj)/generated-ust-provider.h-timestamp
        @cmp $< $@ >/dev/null 2>&1 || cp $< $@
-$(obj)/generated-ust-provider.h-timestamp: $(BUILD_DIR)/trace-events-all $(tracetool-y)
+$(obj)/generated-ust-provider.h-timestamp: $(SRC_PATH)/trace-events $(tracetool-y)
        $(call quiet-command,$(TRACETOOL) \
                --format=ust-events-h \
                --backends=$(TRACE_BACKENDS) \
@@ -26,7 +22,7 @@ $(obj)/generated-ust-provider.h-timestamp: $(BUILD_DIR)/trace-events-all $(trace
 
 $(obj)/generated-ust.c: $(obj)/generated-ust.c-timestamp $(BUILD_DIR)/config-host.mak
        @cmp $< $@ >/dev/null 2>&1 || cp $< $@
-$(obj)/generated-ust.c-timestamp: $(BUILD_DIR)/trace-events-all $(tracetool-y)
+$(obj)/generated-ust.c-timestamp: $(SRC_PATH)/trace-events $(tracetool-y)
        $(call quiet-command,$(TRACETOOL) \
                --format=ust-events-c \
                --backends=$(TRACE_BACKENDS) \
@@ -34,7 +30,6 @@ $(obj)/generated-ust.c-timestamp: $(BUILD_DIR)/trace-events-all $(tracetool-y)
 
 $(obj)/generated-events.h: $(obj)/generated-ust-provider.h
 $(obj)/generated-events.c: $(obj)/generated-ust.c
-
 endif
 
 ######################################################################
@@ -42,7 +37,7 @@ endif
 
 $(obj)/generated-events.h: $(obj)/generated-events.h-timestamp
        @cmp $< $@ >/dev/null 2>&1 || cp $< $@
-$(obj)/generated-events.h-timestamp: $(BUILD_DIR)/trace-events-all $(tracetool-y)
+$(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events $(tracetool-y)
        $(call quiet-command,$(TRACETOOL) \
                --format=events-h \
                --backends=$(TRACE_BACKENDS) \
@@ -50,7 +45,7 @@ $(obj)/generated-events.h-timestamp: $(BUILD_DIR)/trace-events-all $(tracetool-y
 
 $(obj)/generated-events.c: $(obj)/generated-events.c-timestamp $(BUILD_DIR)/config-host.mak
        @cmp $< $@ >/dev/null 2>&1 || cp $< $@
-$(obj)/generated-events.c-timestamp: $(BUILD_DIR)/trace-events-all $(tracetool-y)
+$(obj)/generated-events.c-timestamp: $(SRC_PATH)/trace-events $(tracetool-y)
        $(call quiet-command,$(TRACETOOL) \
                --format=events-c \
                --backends=$(TRACE_BACKENDS) \
@@ -67,7 +62,7 @@ util-obj-y += generated-events.o
 
 $(obj)/generated-tracers.h: $(obj)/generated-tracers.h-timestamp
        @cmp -s $< $@ || cp $< $@
-$(obj)/generated-tracers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
+$(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
        $(call quiet-command,$(TRACETOOL) \
                --format=h \
                --backends=$(TRACE_BACKENDS) \
@@ -78,7 +73,7 @@ $(obj)/generated-tracers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)
 
 $(obj)/generated-tracers.c: $(obj)/generated-tracers.c-timestamp
        @cmp -s $< $@ || cp $< $@
-$(obj)/generated-tracers.c-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
+$(obj)/generated-tracers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
        $(call quiet-command,$(TRACETOOL) \
                --format=c \
                --backends=$(TRACE_BACKENDS) \
@@ -93,10 +88,9 @@ $(obj)/generated-tracers.o: $(obj)/generated-tracers.c $(obj)/generated-tracers.
 # but that gets picked up by QEMU's Makefile as an external dependency
 # rule file. So we use '.dtrace' instead
 ifeq ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace)
-
 $(obj)/generated-tracers-dtrace.dtrace: $(obj)/generated-tracers-dtrace.dtrace-timestamp
        @cmp $< $@ >/dev/null 2>&1 || cp $< $@
-$(obj)/generated-tracers-dtrace.dtrace-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
+$(obj)/generated-tracers-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
        $(call quiet-command,$(TRACETOOL) \
                --format=d \
                --backends=$(TRACE_BACKENDS) \
@@ -115,7 +109,7 @@ endif
 
 $(obj)/generated-helpers-wrappers.h: $(obj)/generated-helpers-wrappers.h-timestamp
        @cmp $< $@ >/dev/null 2>&1 || cp $< $@
-$(obj)/generated-helpers-wrappers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
+$(obj)/generated-helpers-wrappers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
        $(call quiet-command,$(TRACETOOL) \
                --format=tcg-helper-wrapper-h \
                --backend=$(TRACE_BACKENDS) \
@@ -123,7 +117,7 @@ $(obj)/generated-helpers-wrappers.h-timestamp: $(BUILD_DIR)/trace-events-all $(B
 
 $(obj)/generated-helpers.h: $(obj)/generated-helpers.h-timestamp
        @cmp $< $@ >/dev/null 2>&1 || cp $< $@
-$(obj)/generated-helpers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
+$(obj)/generated-helpers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
        $(call quiet-command,$(TRACETOOL) \
                --format=tcg-helper-h \
                --backend=$(TRACE_BACKENDS) \
@@ -131,7 +125,7 @@ $(obj)/generated-helpers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)
 
 $(obj)/generated-helpers.c: $(obj)/generated-helpers.c-timestamp
        @cmp $< $@ >/dev/null 2>&1 || cp $< $@
-$(obj)/generated-helpers.c-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
+$(obj)/generated-helpers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
        $(call quiet-command,$(TRACETOOL) \
                --format=tcg-helper-c \
                --backend=$(TRACE_BACKENDS) \
@@ -144,7 +138,7 @@ target-obj-y += generated-helpers.o
 
 $(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp
        @cmp $< $@ >/dev/null 2>&1 || cp $< $@
-$(obj)/generated-tcg-tracers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
+$(obj)/generated-tcg-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
        $(call quiet-command,$(TRACETOOL) \
                --format=tcg-h \
                --backend=$(TRACE_BACKENDS) \
@@ -158,5 +152,4 @@ util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o generated-tracers.o
 util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o
 util-obj-$(CONFIG_TRACE_UST) += generated-ust.o
 util-obj-y += control.o
-target-obj-y += control-target.o
 util-obj-y += qmp.o
index a4e5f4a..dcf67f5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Interface for configuring and controlling the state of tracing events.
  *
- * Copyright (C) 2011-2016 Lluís Vilanova <vilanova@ac.upc.edu>
+ * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu>
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
 #ifndef TRACE__CONTROL_INTERNAL_H
 #define TRACE__CONTROL_INTERNAL_H
 
-#include <stddef.h>                     /* size_t */
-
-#include "qom/cpu.h"
 
 
 extern TraceEvent trace_events[];
-extern uint16_t trace_events_dstate[];
+extern bool trace_events_dstate[];
 extern int trace_events_enabled_count;
 
 
@@ -43,16 +40,6 @@ static inline TraceEventID trace_event_get_id(TraceEvent *ev)
     return ev->id;
 }
 
-static inline TraceEventVCPUID trace_event_get_vcpu_id(TraceEvent *ev)
-{
-    return ev->vcpu_id;
-}
-
-static inline bool trace_event_is_vcpu(TraceEvent *ev)
-{
-    return ev->vcpu_id != TRACE_VCPU_EVENT_COUNT;
-}
-
 static inline const char * trace_event_get_name(TraceEvent *ev)
 {
     assert(ev != NULL);
@@ -65,38 +52,24 @@ static inline bool trace_event_get_state_static(TraceEvent *ev)
     return ev->sstate;
 }
 
-static inline bool trace_event_get_state_dynamic_by_id(TraceEventID id)
+static inline bool trace_event_get_state_dynamic_by_id(int id)
 {
-    /* it's on fast path, avoid consistency checks (asserts) */
     return unlikely(trace_events_enabled_count) && trace_events_dstate[id];
 }
 
 static inline bool trace_event_get_state_dynamic(TraceEvent *ev)
 {
-    TraceEventID id;
-    assert(trace_event_get_state_static(ev));
-    id = trace_event_get_id(ev);
+    int id = trace_event_get_id(ev);
     return trace_event_get_state_dynamic_by_id(id);
 }
 
-static inline bool trace_event_get_vcpu_state_dynamic_by_vcpu_id(CPUState *vcpu,
-                                                                 TraceEventVCPUID id)
-{
-    /* it's on fast path, avoid consistency checks (asserts) */
-    if (unlikely(trace_events_enabled_count)) {
-        return test_bit(id, vcpu->trace_dstate);
-    } else {
-        return false;
-    }
-}
-
-static inline bool trace_event_get_vcpu_state_dynamic(CPUState *vcpu,
-                                                      TraceEvent *ev)
+static inline void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
 {
-    TraceEventVCPUID id;
-    assert(trace_event_is_vcpu(ev));
-    id = trace_event_get_vcpu_id(ev);
-    return trace_event_get_vcpu_state_dynamic_by_vcpu_id(vcpu, id);
+    int id = trace_event_get_id(ev);
+    assert(ev != NULL);
+    assert(trace_event_get_state_static(ev));
+    trace_events_enabled_count += state - trace_events_dstate[id];
+    trace_events_dstate[id] = state;
 }
 
-#endif /* TRACE__CONTROL_INTERNAL_H */
+#endif  /* TRACE__CONTROL_INTERNAL_H */
diff --git a/trace/control-target.c b/trace/control-target.c
deleted file mode 100644 (file)
index 74c029a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Interface for configuring and controlling the state of tracing events.
- *
- * Copyright (C) 2014-2016 Lluís Vilanova <vilanova@ac.upc.edu>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "trace/control.h"
-#include "translate-all.h"
-
-
-void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
-{
-    CPUState *vcpu;
-    assert(trace_event_get_state_static(ev));
-    if (trace_event_is_vcpu(ev)) {
-        CPU_FOREACH(vcpu) {
-            trace_event_set_vcpu_state_dynamic(vcpu, ev, state);
-        }
-    } else {
-        TraceEventID id = trace_event_get_id(ev);
-        trace_events_enabled_count += state - trace_events_dstate[id];
-        trace_events_dstate[id] = state;
-    }
-}
-
-void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
-                                        TraceEvent *ev, bool state)
-{
-    TraceEventID id;
-    TraceEventVCPUID vcpu_id;
-    bool state_pre;
-    assert(trace_event_get_state_static(ev));
-    assert(trace_event_is_vcpu(ev));
-    id = trace_event_get_id(ev);
-    vcpu_id = trace_event_get_vcpu_id(ev);
-    state_pre = test_bit(vcpu_id, vcpu->trace_dstate);
-    if (state_pre != state) {
-        if (state) {
-            trace_events_enabled_count++;
-            set_bit(vcpu_id, vcpu->trace_dstate);
-            trace_events_dstate[id]++;
-        } else {
-            trace_events_enabled_count--;
-            clear_bit(vcpu_id, vcpu->trace_dstate);
-            trace_events_dstate[id]--;
-        }
-    }
-}
index d173c09..d099f73 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Interface for configuring and controlling the state of tracing events.
  *
- * Copyright (C) 2011-2016 Lluís Vilanova <vilanova@ac.upc.edu>
+ * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu>
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
 #ifdef CONFIG_TRACE_LOG
 #include "qemu/log.h"
 #endif
-#include "qapi/error.h"
 #include "qemu/error-report.h"
-#include "qemu/config-file.h"
 #include "monitor/monitor.h"
 
 int trace_events_enabled_count;
-/*
- * Interpretation depends on wether the event has the 'vcpu' property:
- * - false: Boolean value indicating whether the event is active.
- * - true : Integral counting the number of vCPUs that have this event enabled.
- */
-uint16_t trace_events_dstate[TRACE_EVENT_COUNT];
-/* Marks events for late vCPU state init */
-static bool trace_events_dstate_init[TRACE_EVENT_COUNT];
-
-QemuOptsList qemu_trace_opts = {
-    .name = "trace",
-    .implied_opt_name = "enable",
-    .head = QTAILQ_HEAD_INITIALIZER(qemu_trace_opts.head),
-    .desc = {
-        {
-            .name = "enable",
-            .type = QEMU_OPT_STRING,
-        },
-        {
-            .name = "events",
-            .type = QEMU_OPT_STRING,
-        },{
-            .name = "file",
-            .type = QEMU_OPT_STRING,
-        },
-        { /* end of list */ }
-    },
-};
-
+bool trace_events_dstate[TRACE_EVENT_COUNT];
 
 TraceEvent *trace_event_name(const char *name)
 {
@@ -142,10 +112,7 @@ static void do_trace_enable_events(const char *line_buf)
         TraceEvent *ev = NULL;
         while ((ev = trace_event_pattern(line_ptr, ev)) != NULL) {
             if (trace_event_get_state_static(ev)) {
-                /* start tracing */
                 trace_event_set_state_dynamic(ev, enable);
-                /* mark for late vCPU init */
-                trace_events_dstate_init[ev->id] = true;
             }
         }
     } else {
@@ -157,10 +124,7 @@ static void do_trace_enable_events(const char *line_buf)
             error_report("WARNING: trace event '%s' is not traceable",
                          line_ptr);
         } else {
-            /* start tracing */
             trace_event_set_state_dynamic(ev, enable);
-            /* mark for late vCPU init */
-            trace_events_dstate_init[ev->id] = true;
         }
     }
 }
@@ -177,7 +141,7 @@ void trace_enable_events(const char *line_buf)
     }
 }
 
-static void trace_init_events(const char *fname)
+void trace_init_events(const char *fname)
 {
     Location loc;
     FILE *fp;
@@ -223,7 +187,7 @@ void trace_init_file(const char *file)
      * only applies to the simple backend; use "-D" for the log backend.
      */
     if (file) {
-        qemu_set_log_filename(file, &error_fatal);
+        qemu_set_log_filename(file);
     }
 #else
     if (file) {
@@ -252,33 +216,3 @@ bool trace_init_backends(void)
 
     return true;
 }
-
-char *trace_opt_parse(const char *optarg)
-{
-    char *trace_file;
-    QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("trace"),
-                                             optarg, true);
-    if (!opts) {
-        exit(1);
-    }
-    if (qemu_opt_get(opts, "enable")) {
-        trace_enable_events(qemu_opt_get(opts, "enable"));
-    }
-    trace_init_events(qemu_opt_get(opts, "events"));
-    trace_file = g_strdup(qemu_opt_get(opts, "file"));
-    qemu_opts_del(opts);
-
-    return trace_file;
-}
-
-void trace_init_vcpu_events(void)
-{
-    TraceEvent *ev = NULL;
-    while ((ev = trace_event_pattern("*", ev)) != NULL) {
-        if (trace_event_is_vcpu(ev) &&
-            trace_event_get_state_static(ev) &&
-            trace_events_dstate_init[ev->id]) {
-            trace_event_set_state_dynamic(ev, true);
-        }
-    }
-}
index 0413b28..e2ba6d4 100644 (file)
@@ -86,23 +86,6 @@ static TraceEventID trace_event_count(void);
 static TraceEventID trace_event_get_id(TraceEvent *ev);
 
 /**
- * trace_event_get_vcpu_id:
- *
- * Get the per-vCPU identifier of an event.
- *
- * Special value #TRACE_VCPU_EVENT_COUNT means the event is not vCPU-specific
- * (does not have the "vcpu" property).
- */
-static TraceEventVCPUID trace_event_get_vcpu_id(TraceEvent *ev);
-
-/**
- * trace_event_is_vcpu:
- *
- * Whether this is a per-vCPU event.
- */
-static bool trace_event_is_vcpu(TraceEvent *ev);
-
-/**
  * trace_event_get_name:
  *
  * Get the name of an event.
@@ -124,23 +107,6 @@ static const char * trace_event_get_name(TraceEvent *ev);
     ((id ##_ENABLED) && trace_event_get_state_dynamic_by_id(id))
 
 /**
- * trace_event_get_vcpu_state:
- * @vcpu: Target vCPU.
- * @id: Event identifier (TraceEventID).
- * @vcpu_id: Per-vCPU event identifier (TraceEventVCPUID).
- *
- * Get the tracing state of an event (both static and dynamic) for the given
- * vCPU.
- *
- * If the event has the disabled property, the check will have no performance
- * impact.
- *
- * As a down side, you must always use an immediate #TraceEventID value.
- */
-#define trace_event_get_vcpu_state(vcpu, id, vcpu_id)                   \
-    ((id ##_ENABLED) && trace_event_get_vcpu_state_dynamic_by_vcpu_id(vcpu, vcpu_id))
-
-/**
  * trace_event_get_state_static:
  * @id: Event identifier.
  *
@@ -155,19 +121,10 @@ static bool trace_event_get_state_static(TraceEvent *ev);
  * trace_event_get_state_dynamic:
  *
  * Get the dynamic tracing state of an event.
- *
- * If the event has the 'vcpu' property, gets the OR'ed state of all vCPUs.
  */
 static bool trace_event_get_state_dynamic(TraceEvent *ev);
 
 /**
- * trace_event_get_vcpu_state_dynamic:
- *
- * Get the dynamic tracing state of an event for the given vCPU.
- */
-static bool trace_event_get_vcpu_state_dynamic(CPUState *vcpu, TraceEvent *ev);
-
-/**
  * trace_event_set_state:
  *
  * Set the tracing state of an event (only if possible).
@@ -181,38 +138,13 @@ static bool trace_event_get_vcpu_state_dynamic(CPUState *vcpu, TraceEvent *ev);
     } while (0)
 
 /**
- * trace_event_set_vcpu_state:
- *
- * Set the tracing state of an event for the given vCPU (only if not disabled).
- */
-#define trace_event_set_vcpu_state(vcpu, id, state)                     \
-    do {                                                                \
-        if ((id ##_ENABLED)) {                                          \
-            TraceEvent *_e = trace_event_id(id);                        \
-            trace_event_set_vcpu_state_dynamic(vcpu, _e, state);        \
-        }                                                               \
-    } while (0)
-
-/**
  * trace_event_set_state_dynamic:
  *
  * Set the dynamic tracing state of an event.
  *
- * If the event has the 'vcpu' property, sets the state on all vCPUs.
- *
  * Pre-condition: trace_event_get_state_static(ev) == true
  */
-void trace_event_set_state_dynamic(TraceEvent *ev, bool state);
-
-/**
- * trace_event_set_vcpu_state_dynamic:
- *
- * Set the dynamic tracing state of an event for the given vCPU.
- *
- * Pre-condition: trace_event_get_vcpu_state_static(ev) == true
- */
-void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
-                                        TraceEvent *ev, bool state);
+static void trace_event_set_state_dynamic(TraceEvent *ev, bool state);
 
 
 
@@ -228,6 +160,17 @@ void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
 bool trace_init_backends(void);
 
 /**
+ * trace_init_events:
+ * @events: Name of file with events to be enabled at startup; may be NULL.
+ *          Corresponds to commandline option "-trace events=...".
+ *
+ * Read the list of enabled tracing events.
+ *
+ * Returns: Whether the backends could be successfully initialized.
+ */
+void trace_init_events(const char *file);
+
+/**
  * trace_init_file:
  * @file:   Name of trace output file; may be NULL.
  *          Corresponds to commandline option "-trace file=...".
@@ -254,30 +197,7 @@ void trace_list_events(void);
  */
 void trace_enable_events(const char *line_buf);
 
-/**
- * Definition of QEMU options describing trace subsystem configuration
- */
-extern QemuOptsList qemu_trace_opts;
-
-/**
- * trace_opt_parse:
- * @optarg: A string argument of --trace command line argument
- *
- * Initialize tracing subsystem.
- *
- * Returns the filename to save trace to.  It must be freed with g_free().
- */
-char *trace_opt_parse(const char *optarg);
-
-/**
- * trace_init_vcpu_events:
- *
- * Re-synchronize initial event state with vCPUs (which can be created after
- * trace_init_events()).
- */
-void trace_init_vcpu_events(void);
-
 
 #include "trace/control-internal.h"
 
-#endif /* TRACE__CONTROL_H */
+#endif  /* TRACE__CONTROL_H */
index 5d8fa97..86f6a51 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Interface for configuring and controlling the state of tracing events.
  *
- * Copyright (C) 2012-2016 Lluís Vilanova <vilanova@ac.upc.edu>
+ * Copyright (C) 2012 Lluís Vilanova <vilanova@ac.upc.edu>
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -16,7 +16,6 @@
 /**
  * TraceEvent:
  * @id: Unique event identifier.
- * @vcpu_id: Unique per-vCPU event identifier.
  * @name: Event name.
  * @sstate: Static tracing state.
  *
  */
 typedef struct TraceEvent {
     TraceEventID id;
-    TraceEventVCPUID vcpu_id;
     const char * name;
     const bool sstate;
 } TraceEvent;
 
 
-#endif /* TRACE__EVENT_INTERNAL_H */
+#endif  /* TRACE__EVENT_INTERNAL_H */
index cb5e35d..92372e3 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef TRACE_FTRACE_H
 #define TRACE_FTRACE_H
 
+
+
 #define MAX_TRACE_STRLEN 512
 #define _STR(x) #x
 #define STR(x) _STR(x)
@@ -9,4 +11,4 @@ extern int trace_marker_fd;
 
 bool ftrace_init(void);
 
-#endif /* TRACE_FTRACE_H */
+#endif /* TRACE_FTRACE_H */
diff --git a/trace/mem-internal.h b/trace/mem-internal.h
deleted file mode 100644 (file)
index ddda934..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Helper functions for guest memory tracing
- *
- * Copyright (C) 2016 Lluís Vilanova <vilanova@ac.upc.edu>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef TRACE__MEM_INTERNAL_H
-#define TRACE__MEM_INTERNAL_H
-
-static inline uint8_t trace_mem_get_info(TCGMemOp op, bool store)
-{
-    uint8_t res = op;
-    bool be = (op & MO_BSWAP) == MO_BE;
-
-    /* remove untraced fields */
-    res &= (1ULL << 4) - 1;
-    /* make endianness absolute */
-    res &= ~MO_BSWAP;
-    if (be) {
-        res |= 1ULL << 3;
-    }
-    /* add fields */
-    if (store) {
-        res |= 1ULL << 4;
-    }
-
-    return res;
-}
-
-static inline uint8_t trace_mem_build_info(
-    TCGMemOp size, bool sign_extend, TCGMemOp endianness, bool store)
-{
-    uint8_t res = 0;
-    res |= size;
-    res |= (sign_extend << 2);
-    if (endianness == MO_BE) {
-        res |= (1ULL << 3);
-    }
-    res |= (store << 4);
-    return res;
-}
-
-#endif /* TRACE__MEM_INTERNAL_H */
diff --git a/trace/mem.h b/trace/mem.h
deleted file mode 100644 (file)
index 9c88bcb..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Helper functions for guest memory tracing
- *
- * Copyright (C) 2016 Lluís Vilanova <vilanova@ac.upc.edu>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef TRACE__MEM_H
-#define TRACE__MEM_H
-
-#include "tcg/tcg.h"
-
-
-/**
- * trace_mem_get_info:
- *
- * Return a value for the 'info' argument in guest memory access traces.
- */
-static uint8_t trace_mem_get_info(TCGMemOp op, bool store);
-
-/**
- * trace_mem_build_info:
- *
- * Return a value for the 'info' argument in guest memory access traces.
- */
-static uint8_t trace_mem_build_info(TCGMemOp size, bool sign_extend,
-                                    TCGMemOp endianness, bool store);
-
-
-#include "trace/mem-internal.h"
-
-#endif /* TRACE__MEM_H */
index 11d2564..8aa2660 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * QMP commands for tracing events.
  *
- * Copyright (C) 2014-2016 Lluís Vilanova <vilanova@ac.upc.edu>
+ * Copyright (C) 2014 Lluís Vilanova <vilanova@ac.upc.edu>
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
 #include "trace/control.h"
 
 
-static CPUState *get_cpu(bool has_vcpu, int vcpu, Error **errp)
+TraceEventInfoList *qmp_trace_event_get_state(const char *name, Error **errp)
 {
-    if (has_vcpu) {
-        CPUState *cpu = qemu_get_cpu(vcpu);
-        if (cpu == NULL) {
-            error_setg(errp, "invalid vCPU index %u", vcpu);
-        }
-        return cpu;
-    } else {
-        return NULL;
-    }
-}
-
-static bool check_events(bool has_vcpu, bool ignore_unavailable, bool is_pattern,
-                         const char *name, Error **errp)
-{
-    if (!is_pattern) {
-        TraceEvent *ev = trace_event_name(name);
-
-        /* error for non-existing event */
-        if (ev == NULL) {
-            error_setg(errp, "unknown event \"%s\"", name);
-            return false;
-        }
-
-        /* error for non-vcpu event */
-        if (has_vcpu && !trace_event_is_vcpu(ev)) {
-            error_setg(errp, "event \"%s\" is not vCPU-specific", name);
-            return false;
-        }
-
-        /* error for unavailable event */
-        if (!ignore_unavailable && !trace_event_get_state_static(ev)) {
-            error_setg(errp, "event \"%s\" is disabled", name);
-            return false;
-        }
-
-        return true;
-    } else {
-        /* error for unavailable events */
-        TraceEvent *ev = NULL;
-        while ((ev = trace_event_pattern(name, ev)) != NULL) {
-            if (!ignore_unavailable && !trace_event_get_state_static(ev)) {
-                error_setg(errp, "event \"%s\" is disabled", trace_event_get_name(ev));
-                return false;
-            }
-        }
-        return true;
-    }
-}
-
-TraceEventInfoList *qmp_trace_event_get_state(const char *name,
-                                              bool has_vcpu, int64_t vcpu,
-                                              Error **errp)
-{
-    Error *err = NULL;
     TraceEventInfoList *events = NULL;
+    bool found = false;
     TraceEvent *ev;
-    bool is_pattern = trace_event_is_pattern(name);
-    CPUState *cpu;
 
-    /* Check provided vcpu */
-    cpu = get_cpu(has_vcpu, vcpu, &err);
-    if (err) {
-        error_propagate(errp, err);
-        return NULL;
-    }
-
-    /* Check events */
-    if (!check_events(has_vcpu, true, is_pattern, name, errp)) {
-        return NULL;
-    }
-
-    /* Get states (all errors checked above) */
     ev = NULL;
     while ((ev = trace_event_pattern(name, ev)) != NULL) {
-        TraceEventInfoList *elem;
-        bool is_vcpu = trace_event_is_vcpu(ev);
-        if (has_vcpu && !is_vcpu) {
-            continue;
-        }
-
-        elem = g_new(TraceEventInfoList, 1);
+        TraceEventInfoList *elem = g_new(TraceEventInfoList, 1);
         elem->value = g_new(TraceEventInfo, 1);
-        elem->value->vcpu = is_vcpu;
         elem->value->name = g_strdup(trace_event_get_name(ev));
-
         if (!trace_event_get_state_static(ev)) {
             elem->value->state = TRACE_EVENT_STATE_UNAVAILABLE;
+        } else if (!trace_event_get_state_dynamic(ev)) {
+            elem->value->state = TRACE_EVENT_STATE_DISABLED;
         } else {
-            if (has_vcpu) {
-                if (is_vcpu) {
-                    if (trace_event_get_vcpu_state_dynamic(cpu, ev)) {
-                        elem->value->state = TRACE_EVENT_STATE_ENABLED;
-                    } else {
-                        elem->value->state = TRACE_EVENT_STATE_DISABLED;
-                    }
-                }
-                /* else: already skipped above */
-            } else {
-                if (trace_event_get_state_dynamic(ev)) {
-                    elem->value->state = TRACE_EVENT_STATE_ENABLED;
-                } else {
-                    elem->value->state = TRACE_EVENT_STATE_DISABLED;
-                }
-            }
+            elem->value->state = TRACE_EVENT_STATE_ENABLED;
         }
         elem->next = events;
         events = elem;
+        found = true;
+    }
+
+    if (!found && !trace_event_is_pattern(name)) {
+        error_setg(errp, "unknown event \"%s\"", name);
     }
 
     return events;
 }
 
 void qmp_trace_event_set_state(const char *name, bool enable,
-                               bool has_ignore_unavailable, bool ignore_unavailable,
-                               bool has_vcpu, int64_t vcpu,
-                               Error **errp)
+                               bool has_ignore_unavailable,
+                               bool ignore_unavailable, Error **errp)
 {
-    Error *err = NULL;
+    bool found = false;
     TraceEvent *ev;
-    bool is_pattern = trace_event_is_pattern(name);
-    CPUState *cpu;
 
-    /* Check provided vcpu */
-    cpu = get_cpu(has_vcpu, vcpu, &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
+    /* Check all selected events are dynamic */
+    ev = NULL;
+    while ((ev = trace_event_pattern(name, ev)) != NULL) {
+        found = true;
+        if (!(has_ignore_unavailable && ignore_unavailable) &&
+            !trace_event_get_state_static(ev)) {
+            error_setg(errp, "cannot set dynamic tracing state for \"%s\"",
+                       trace_event_get_name(ev));
+            return;
+        }
     }
-
-    /* Check events */
-    if (!check_events(has_vcpu, has_ignore_unavailable && ignore_unavailable,
-                      is_pattern, name, errp)) {
+    if (!found && !trace_event_is_pattern(name)) {
+        error_setg(errp, "unknown event \"%s\"", name);
         return;
     }
 
-    /* Apply changes (all errors checked above) */
+    /* Apply changes */
     ev = NULL;
     while ((ev = trace_event_pattern(name, ev)) != NULL) {
-        if (!trace_event_get_state_static(ev) ||
-            (has_vcpu && !trace_event_is_vcpu(ev))) {
-            continue;
-        }
-        if (has_vcpu) {
-            trace_event_set_vcpu_state_dynamic(cpu, ev, enable);
-        } else {
+        if (trace_event_get_state_static(ev)) {
             trace_event_set_state_dynamic(ev, enable);
         }
     }
index 0dd6466..8329ea6 100644 (file)
@@ -18,6 +18,8 @@
  */
 #ifdef _WIN32
 #include <windows.h>
+#else
+#include <sys/mman.h>
 #endif
 #include "qemu/osdep.h"
 
@@ -27,7 +29,6 @@
 #include "cpu.h"
 #include "trace.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg.h"
 #if defined(CONFIG_USER_ONLY)
 #include "qemu.h"
 typedef struct PageDesc {
     /* list of TBs intersecting this ram page */
     TranslationBlock *first_tb;
-#ifdef CONFIG_SOFTMMU
     /* in order to optimize self modifying code, we count the number
        of lookups we do to a given page to use a bitmap */
     unsigned int code_write_count;
     unsigned long *code_bitmap;
-#else
+#if defined(CONFIG_USER_ONLY)
     unsigned long flags;
 #endif
 } PageDesc;
@@ -153,6 +153,8 @@ void tb_lock_reset(void)
 #endif
 }
 
+static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
+                         tb_page_addr_t phys_page2);
 static TranslationBlock *tb_find_pc(uintptr_t tc_ptr);
 
 void cpu_gen_init(void)
@@ -304,6 +306,7 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t retaddr)
         cpu_restore_state_from_tb(cpu, tb, retaddr);
         if (tb->cflags & CF_NOCACHE) {
             /* one-shot translation, invalidate it immediately */
+            cpu->current_tb = NULL;
             tb_phys_invalidate(tb, -1);
             tb_free(tb);
         }
@@ -461,8 +464,6 @@ static inline PageDesc *page_find(tb_page_addr_t index)
 # define MAX_CODE_GEN_BUFFER_SIZE  (2ul * 1024 * 1024 * 1024)
 #elif defined(__powerpc64__)
 # define MAX_CODE_GEN_BUFFER_SIZE  (2ul * 1024 * 1024 * 1024)
-#elif defined(__powerpc__)
-# define MAX_CODE_GEN_BUFFER_SIZE  (32u * 1024 * 1024)
 #elif defined(__aarch64__)
 # define MAX_CODE_GEN_BUFFER_SIZE  (128ul * 1024 * 1024)
 #elif defined(__arm__)
@@ -504,6 +505,7 @@ static inline size_t size_code_gen_buffer(size_t tb_size)
     if (tb_size > MAX_CODE_GEN_BUFFER_SIZE) {
         tb_size = MAX_CODE_GEN_BUFFER_SIZE;
     }
+    tcg_ctx.code_gen_buffer_size = tb_size;
     return tb_size;
 }
 
@@ -512,7 +514,7 @@ static inline size_t size_code_gen_buffer(size_t tb_size)
    that the buffer not cross a 256MB boundary.  */
 static inline bool cross_256mb(void *addr, size_t size)
 {
-    return ((uintptr_t)addr ^ ((uintptr_t)addr + size)) & ~0x0ffffffful;
+    return ((uintptr_t)addr ^ ((uintptr_t)addr + size)) & 0xf0000000;
 }
 
 /* We weren't able to allocate a buffer without crossing that boundary,
@@ -520,7 +522,7 @@ static inline bool cross_256mb(void *addr, size_t size)
    Returns the new base of the buffer, and adjusts code_gen_buffer_size.  */
 static inline void *split_cross_256mb(void *buf1, size_t size1)
 {
-    void *buf2 = (void *)(((uintptr_t)buf1 + size1) & ~0x0ffffffful);
+    void *buf2 = (void *)(((uintptr_t)buf1 + size1) & 0xf0000000);
     size_t size2 = buf1 + size1 - buf2;
 
     size1 = buf2 - buf1;
@@ -681,11 +683,11 @@ static inline void *alloc_code_gen_buffer(void)
         case 1:
             if (!cross_256mb(buf2, size)) {
                 /* Success!  Use the new buffer.  */
-                munmap(buf, size + qemu_real_host_page_size);
+                munmap(buf, size);
                 break;
             }
             /* Failure.  Work with what we had.  */
-            munmap(buf2, size + qemu_real_host_page_size);
+            munmap(buf2, size);
             /* fallthru */
         default:
             /* Split the original buffer.  Free the smaller half.  */
@@ -733,13 +735,6 @@ static inline void code_gen_alloc(size_t tb_size)
     qemu_mutex_init(&tcg_ctx.tb_ctx.tb_lock);
 }
 
-static void tb_htable_init(void)
-{
-    unsigned int mode = QHT_MODE_AUTO_RESIZE;
-
-    qht_init(&tcg_ctx.tb_ctx.htable, CODE_GEN_HTABLE_SIZE, mode);
-}
-
 /* Must be called before using the QEMU cpus. 'tb_size' is the size
    (in bytes) allocated to the translation buffer. Zero means default
    size. */
@@ -747,7 +742,6 @@ void tcg_exec_init(unsigned long tb_size)
 {
     cpu_gen_init();
     page_init();
-    tb_htable_init();
     code_gen_alloc(tb_size);
 #if defined(CONFIG_SOFTMMU)
     /* There's no guest base to take into account, so go ahead and
@@ -790,11 +784,9 @@ void tb_free(TranslationBlock *tb)
 
 static inline void invalidate_page_bitmap(PageDesc *p)
 {
-#ifdef CONFIG_SOFTMMU
     g_free(p->code_bitmap);
     p->code_bitmap = NULL;
     p->code_write_count = 0;
-#endif
 }
 
 /* Set to NULL all the 'first_tb' fields in all PageDescs. */
@@ -834,9 +826,6 @@ static void page_flush_tb(void)
 /* XXX: tb_flush is currently not thread safe */
 void tb_flush(CPUState *cpu)
 {
-    if (!tcg_enabled()) {
-        return;
-    }
 #if defined(DEBUG_FLUSH)
     printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
            (unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer),
@@ -852,10 +841,9 @@ void tb_flush(CPUState *cpu)
 
     CPU_FOREACH(cpu) {
         memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
-        cpu->tb_flushed = true;
     }
 
-    qht_reset_size(&tcg_ctx.tb_ctx.htable, CODE_GEN_HTABLE_SIZE);
+    memset(tcg_ctx.tb_ctx.tb_phys_hash, 0, sizeof(tcg_ctx.tb_ctx.tb_phys_hash));
     page_flush_tb();
 
     tcg_ctx.code_gen_ptr = tcg_ctx.code_gen_buffer;
@@ -866,46 +854,60 @@ void tb_flush(CPUState *cpu)
 
 #ifdef DEBUG_TB_CHECK
 
-static void
-do_tb_invalidate_check(struct qht *ht, void *p, uint32_t hash, void *userp)
-{
-    TranslationBlock *tb = p;
-    target_ulong addr = *(target_ulong *)userp;
-
-    if (!(addr + TARGET_PAGE_SIZE <= tb->pc || addr >= tb->pc + tb->size)) {
-        printf("ERROR invalidate: address=" TARGET_FMT_lx
-               " PC=%08lx size=%04x\n", addr, (long)tb->pc, tb->size);
-    }
-}
-
 static void tb_invalidate_check(target_ulong address)
 {
-    address &= TARGET_PAGE_MASK;
-    qht_iter(&tcg_ctx.tb_ctx.htable, do_tb_invalidate_check, &address);
-}
-
-static void
-do_tb_page_check(struct qht *ht, void *p, uint32_t hash, void *userp)
-{
-    TranslationBlock *tb = p;
-    int flags1, flags2;
+    TranslationBlock *tb;
+    int i;
 
-    flags1 = page_get_flags(tb->pc);
-    flags2 = page_get_flags(tb->pc + tb->size - 1);
-    if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
-        printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
-               (long)tb->pc, tb->size, flags1, flags2);
+    address &= TARGET_PAGE_MASK;
+    for (i = 0; i < CODE_GEN_PHYS_HASH_SIZE; i++) {
+        for (tb = tcg_ctx.tb_ctx.tb_phys_hash[i]; tb != NULL;
+             tb = tb->phys_hash_next) {
+            if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
+                  address >= tb->pc + tb->size)) {
+                printf("ERROR invalidate: address=" TARGET_FMT_lx
+                       " PC=%08lx size=%04x\n",
+                       address, (long)tb->pc, tb->size);
+            }
+        }
     }
 }
 
 /* verify that all the pages have correct rights for code */
 static void tb_page_check(void)
 {
-    qht_iter(&tcg_ctx.tb_ctx.htable, do_tb_page_check, NULL);
+    TranslationBlock *tb;
+    int i, flags1, flags2;
+
+    for (i = 0; i < CODE_GEN_PHYS_HASH_SIZE; i++) {
+        for (tb = tcg_ctx.tb_ctx.tb_phys_hash[i]; tb != NULL;
+                tb = tb->phys_hash_next) {
+            flags1 = page_get_flags(tb->pc);
+            flags2 = page_get_flags(tb->pc + tb->size - 1);
+            if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
+                printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
+                       (long)tb->pc, tb->size, flags1, flags2);
+            }
+        }
+    }
 }
 
 #endif
 
+static inline void tb_hash_remove(TranslationBlock **ptb, TranslationBlock *tb)
+{
+    TranslationBlock *tb1;
+
+    for (;;) {
+        tb1 = *ptb;
+        if (tb1 == tb) {
+            *ptb = tb1->phys_hash_next;
+            break;
+        }
+        ptb = &tb1->phys_hash_next;
+    }
+}
+
 static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
 {
     TranslationBlock *tb1;
@@ -923,33 +925,32 @@ static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
     }
 }
 
-/* remove the TB from a list of TBs jumping to the n-th jump target of the TB */
-static inline void tb_remove_from_jmp_list(TranslationBlock *tb, int n)
+static inline void tb_jmp_remove(TranslationBlock *tb, int n)
 {
-    TranslationBlock *tb1;
-    uintptr_t *ptb, ntb;
+    TranslationBlock *tb1, **ptb;
     unsigned int n1;
 
-    ptb = &tb->jmp_list_next[n];
-    if (*ptb) {
+    ptb = &tb->jmp_next[n];
+    tb1 = *ptb;
+    if (tb1) {
         /* find tb(n) in circular list */
         for (;;) {
-            ntb = *ptb;
-            n1 = ntb & 3;
-            tb1 = (TranslationBlock *)(ntb & ~3);
+            tb1 = *ptb;
+            n1 = (uintptr_t)tb1 & 3;
+            tb1 = (TranslationBlock *)((uintptr_t)tb1 & ~3);
             if (n1 == n && tb1 == tb) {
                 break;
             }
             if (n1 == 2) {
-                ptb = &tb1->jmp_list_first;
+                ptb = &tb1->jmp_first;
             } else {
-                ptb = &tb1->jmp_list_next[n1];
+                ptb = &tb1->jmp_next[n1];
             }
         }
         /* now we can suppress tb(n) from the list */
-        *ptb = tb->jmp_list_next[n];
+        *ptb = tb->jmp_next[n];
 
-        tb->jmp_list_next[n] = (uintptr_t)NULL;
+        tb->jmp_next[n] = NULL;
     }
 }
 
@@ -957,29 +958,7 @@ static inline void tb_remove_from_jmp_list(TranslationBlock *tb, int n)
    another TB */
 static inline void tb_reset_jump(TranslationBlock *tb, int n)
 {
-    uintptr_t addr = (uintptr_t)(tb->tc_ptr + tb->jmp_reset_offset[n]);
-    tb_set_jmp_target(tb, n, addr);
-}
-
-/* remove any jumps to the TB */
-static inline void tb_jmp_unlink(TranslationBlock *tb)
-{
-    TranslationBlock *tb1;
-    uintptr_t *ptb, ntb;
-    unsigned int n1;
-
-    ptb = &tb->jmp_list_first;
-    for (;;) {
-        ntb = *ptb;
-        n1 = ntb & 3;
-        tb1 = (TranslationBlock *)(ntb & ~3);
-        if (n1 == 2) {
-            break;
-        }
-        tb_reset_jump(tb1, n1);
-        *ptb = tb1->jmp_list_next[n1];
-        tb1->jmp_list_next[n1] = (uintptr_t)NULL;
-    }
+    tb_set_jmp_target(tb, n, (uintptr_t)(tb->tc_ptr + tb->tb_next_offset[n]));
 }
 
 /* invalidate one TB */
@@ -987,13 +966,14 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
 {
     CPUState *cpu;
     PageDesc *p;
-    uint32_t h;
+    unsigned int h, n1;
     tb_page_addr_t phys_pc;
+    TranslationBlock *tb1, *tb2;
 
     /* remove the TB from the hash list */
     phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
-    h = tb_hash_func(phys_pc, tb->pc, tb->flags);
-    qht_remove(&tcg_ctx.tb_ctx.htable, tb, h);
+    h = tb_phys_hash_func(phys_pc);
+    tb_hash_remove(&tcg_ctx.tb_ctx.tb_phys_hash[h], tb);
 
     /* remove the TB from the page list */
     if (tb->page_addr[0] != page_addr) {
@@ -1007,6 +987,8 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
         invalidate_page_bitmap(p);
     }
 
+    tcg_ctx.tb_ctx.tb_invalidated_flag = 1;
+
     /* remove the TB from the hash list */
     h = tb_jmp_cache_hash_func(tb->pc);
     CPU_FOREACH(cpu) {
@@ -1016,16 +998,27 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
     }
 
     /* suppress this TB from the two jump lists */
-    tb_remove_from_jmp_list(tb, 0);
-    tb_remove_from_jmp_list(tb, 1);
+    tb_jmp_remove(tb, 0);
+    tb_jmp_remove(tb, 1);
 
     /* suppress any remaining jumps to this TB */
-    tb_jmp_unlink(tb);
+    tb1 = tb->jmp_first;
+    for (;;) {
+        n1 = (uintptr_t)tb1 & 3;
+        if (n1 == 2) {
+            break;
+        }
+        tb1 = (TranslationBlock *)((uintptr_t)tb1 & ~3);
+        tb2 = tb1->jmp_next[n1];
+        tb_reset_jump(tb1, n1);
+        tb1->jmp_next[n1] = NULL;
+        tb1 = tb2;
+    }
+    tb->jmp_first = (TranslationBlock *)((uintptr_t)tb | 2); /* fail safe */
 
     tcg_ctx.tb_ctx.tb_phys_invalidate_count++;
 }
 
-#ifdef CONFIG_SOFTMMU
 static void build_page_bitmap(PageDesc *p)
 {
     int n, tb_start, tb_end;
@@ -1054,97 +1047,11 @@ static void build_page_bitmap(PageDesc *p)
         tb = tb->page_next[n];
     }
 }
-#endif
-
-/* add the tb in the target page and protect it if necessary
- *
- * Called with mmap_lock held for user-mode emulation.
- */
-static inline void tb_alloc_page(TranslationBlock *tb,
-                                 unsigned int n, tb_page_addr_t page_addr)
-{
-    PageDesc *p;
-#ifndef CONFIG_USER_ONLY
-    bool page_already_protected;
-#endif
-
-    tb->page_addr[n] = page_addr;
-    p = page_find_alloc(page_addr >> TARGET_PAGE_BITS, 1);
-    tb->page_next[n] = p->first_tb;
-#ifndef CONFIG_USER_ONLY
-    page_already_protected = p->first_tb != NULL;
-#endif
-    p->first_tb = (TranslationBlock *)((uintptr_t)tb | n);
-    invalidate_page_bitmap(p);
-
-#if defined(CONFIG_USER_ONLY)
-    if (p->flags & PAGE_WRITE) {
-        target_ulong addr;
-        PageDesc *p2;
-        int prot;
-
-        /* force the host page as non writable (writes will have a
-           page fault + mprotect overhead) */
-        page_addr &= qemu_host_page_mask;
-        prot = 0;
-        for (addr = page_addr; addr < page_addr + qemu_host_page_size;
-            addr += TARGET_PAGE_SIZE) {
-
-            p2 = page_find(addr >> TARGET_PAGE_BITS);
-            if (!p2) {
-                continue;
-            }
-            prot |= p2->flags;
-            p2->flags &= ~PAGE_WRITE;
-          }
-        mprotect(g2h(page_addr), qemu_host_page_size,
-                 (prot & PAGE_BITS) & ~PAGE_WRITE);
-#ifdef DEBUG_TB_INVALIDATE
-        printf("protecting code page: 0x" TARGET_FMT_lx "\n",
-               page_addr);
-#endif
-    }
-#else
-    /* if some code is already present, then the pages are already
-       protected. So we handle the case where only the first TB is
-       allocated in a physical page */
-    if (!page_already_protected) {
-        tlb_protect_code(page_addr);
-    }
-#endif
-}
-
-/* add a new TB and link it to the physical page tables. phys_page2 is
- * (-1) to indicate that only one page contains the TB.
- *
- * Called with mmap_lock held for user-mode emulation.
- */
-static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
-                         tb_page_addr_t phys_page2)
-{
-    uint32_t h;
-
-    /* add in the hash table */
-    h = tb_hash_func(phys_pc, tb->pc, tb->flags);
-    qht_insert(&tcg_ctx.tb_ctx.htable, tb, h);
-
-    /* add in the page list */
-    tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK);
-    if (phys_page2 != -1) {
-        tb_alloc_page(tb, 1, phys_page2);
-    } else {
-        tb->page_addr[1] = -1;
-    }
-
-#ifdef DEBUG_TB_CHECK
-    tb_page_check();
-#endif
-}
 
 /* Called with mmap_lock held for user mode emulation.  */
 TranslationBlock *tb_gen_code(CPUState *cpu,
                               target_ulong pc, target_ulong cs_base,
-                              uint32_t flags, int cflags)
+                              int flags, int cflags)
 {
     CPUArchState *env = cpu->env_ptr;
     TranslationBlock *tb;
@@ -1169,6 +1076,8 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
         /* cannot fail at this point */
         tb = tb_alloc(pc);
         assert(tb != NULL);
+        /* Don't forget to invalidate previous TB info.  */
+        tcg_ctx.tb_ctx.tb_invalidated_flag = 1;
     }
 
     gen_code_buf = tcg_ctx.code_gen_ptr;
@@ -1185,22 +1094,20 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
 
     tcg_func_start(&tcg_ctx);
 
-    tcg_ctx.cpu = ENV_GET_CPU(env);
     gen_intermediate_code(env, tb);
-    tcg_ctx.cpu = NULL;
 
     trace_translate_block(tb, tb->pc, tb->tc_ptr);
 
     /* generate machine code */
-    tb->jmp_reset_offset[0] = TB_JMP_RESET_OFFSET_INVALID;
-    tb->jmp_reset_offset[1] = TB_JMP_RESET_OFFSET_INVALID;
-    tcg_ctx.tb_jmp_reset_offset = tb->jmp_reset_offset;
+    tb->tb_next_offset[0] = 0xffff;
+    tb->tb_next_offset[1] = 0xffff;
+    tcg_ctx.tb_next_offset = tb->tb_next_offset;
 #ifdef USE_DIRECT_JUMP
-    tcg_ctx.tb_jmp_insn_offset = tb->jmp_insn_offset;
-    tcg_ctx.tb_jmp_target_addr = NULL;
+    tcg_ctx.tb_jmp_offset = tb->tb_jmp_offset;
+    tcg_ctx.tb_next = NULL;
 #else
-    tcg_ctx.tb_jmp_insn_offset = NULL;
-    tcg_ctx.tb_jmp_target_addr = tb->jmp_target_addr;
+    tcg_ctx.tb_jmp_offset = NULL;
+    tcg_ctx.tb_next = tb->tb_next;
 #endif
 
 #ifdef CONFIG_PROFILER
@@ -1244,31 +1151,12 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
         ROUND_UP((uintptr_t)gen_code_buf + gen_code_size + search_size,
                  CODE_GEN_ALIGN);
 
-    /* init jump list */
-    assert(((uintptr_t)tb & 3) == 0);
-    tb->jmp_list_first = (uintptr_t)tb | 2;
-    tb->jmp_list_next[0] = (uintptr_t)NULL;
-    tb->jmp_list_next[1] = (uintptr_t)NULL;
-
-    /* init original jump addresses wich has been set during tcg_gen_code() */
-    if (tb->jmp_reset_offset[0] != TB_JMP_RESET_OFFSET_INVALID) {
-        tb_reset_jump(tb, 0);
-    }
-    if (tb->jmp_reset_offset[1] != TB_JMP_RESET_OFFSET_INVALID) {
-        tb_reset_jump(tb, 1);
-    }
-
     /* check next page if needed */
     virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
     phys_page2 = -1;
     if ((pc & TARGET_PAGE_MASK) != virt_page2) {
         phys_page2 = get_page_addr_code(env, virt_page2);
     }
-    /* As long as consistency of the TB stuff is provided by tb_lock in user
-     * mode and is implicit in single-threaded softmmu emulation, no explicit
-     * memory barrier is required before tb_link_page() makes the TB visible
-     * through the physical hash table and physical page list.
-     */
     tb_link_page(tb, phys_pc, phys_page2);
     return tb;
 }
@@ -1303,9 +1191,9 @@ void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end)
 void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
                                    int is_cpu_write_access)
 {
-    TranslationBlock *tb, *tb_next;
-#if defined(TARGET_HAS_PRECISE_SMC)
+    TranslationBlock *tb, *tb_next, *saved_tb;
     CPUState *cpu = current_cpu;
+#if defined(TARGET_HAS_PRECISE_SMC)
     CPUArchState *env = NULL;
 #endif
     tb_page_addr_t tb_start, tb_end;
@@ -1317,7 +1205,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
     int current_tb_modified = 0;
     target_ulong current_pc = 0;
     target_ulong current_cs_base = 0;
-    uint32_t current_flags = 0;
+    int current_flags = 0;
 #endif /* TARGET_HAS_PRECISE_SMC */
 
     p = page_find(start >> TARGET_PAGE_BITS);
@@ -1372,7 +1260,20 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
                                      &current_flags);
             }
 #endif /* TARGET_HAS_PRECISE_SMC */
+            /* we need to do that to handle the case where a signal
+               occurs while doing tb_phys_invalidate() */
+            saved_tb = NULL;
+            if (cpu != NULL) {
+                saved_tb = cpu->current_tb;
+                cpu->current_tb = NULL;
+            }
             tb_phys_invalidate(tb, -1);
+            if (cpu != NULL) {
+                cpu->current_tb = saved_tb;
+                if (cpu->interrupt_request && cpu->current_tb) {
+                    cpu_interrupt(cpu, cpu->interrupt_request);
+                }
+            }
         }
         tb = tb_next;
     }
@@ -1388,13 +1289,13 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
         /* we generate a block containing just the instruction
            modifying the memory. It will ensure that it cannot modify
            itself */
+        cpu->current_tb = NULL;
         tb_gen_code(cpu, current_pc, current_cs_base, current_flags, 1);
-        cpu_loop_exit_noexc(cpu);
+        cpu_resume_from_signal(cpu, NULL);
     }
 #endif
 }
 
-#ifdef CONFIG_SOFTMMU
 /* len must be <= 8 and start must be a multiple of len */
 void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
 {
@@ -1432,14 +1333,12 @@ void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
         tb_invalidate_phys_page_range(start, start + len, 1);
     }
 }
-#else
-/* Called with mmap_lock held. If pc is not 0 then it indicates the
- * host PC of the faulting store instruction that caused this invalidate.
- * Returns true if the caller needs to abort execution of the current
- * TB (because it was modified by this store and the guest CPU has
- * precise-SMC semantics).
- */
-static bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc)
+
+#if !defined(CONFIG_SOFTMMU)
+/* Called with mmap_lock held.  */
+static void tb_invalidate_phys_page(tb_page_addr_t addr,
+                                    uintptr_t pc, void *puc,
+                                    bool locked)
 {
     TranslationBlock *tb;
     PageDesc *p;
@@ -1451,13 +1350,13 @@ static bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc)
     int current_tb_modified = 0;
     target_ulong current_pc = 0;
     target_ulong current_cs_base = 0;
-    uint32_t current_flags = 0;
+    int current_flags = 0;
 #endif
 
     addr &= TARGET_PAGE_MASK;
     p = page_find(addr >> TARGET_PAGE_BITS);
     if (!p) {
-        return false;
+        return;
     }
     tb = p->first_tb;
 #ifdef TARGET_HAS_PRECISE_SMC
@@ -1495,13 +1394,116 @@ static bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc)
         /* we generate a block containing just the instruction
            modifying the memory. It will ensure that it cannot modify
            itself */
+        cpu->current_tb = NULL;
         tb_gen_code(cpu, current_pc, current_cs_base, current_flags, 1);
-        return true;
+        if (locked) {
+            mmap_unlock();
+        }
+        cpu_resume_from_signal(cpu, puc);
+    }
+#endif
+}
+#endif
+
+/* add the tb in the target page and protect it if necessary
+ *
+ * Called with mmap_lock held for user-mode emulation.
+ */
+static inline void tb_alloc_page(TranslationBlock *tb,
+                                 unsigned int n, tb_page_addr_t page_addr)
+{
+    PageDesc *p;
+#ifndef CONFIG_USER_ONLY
+    bool page_already_protected;
+#endif
+
+    tb->page_addr[n] = page_addr;
+    p = page_find_alloc(page_addr >> TARGET_PAGE_BITS, 1);
+    tb->page_next[n] = p->first_tb;
+#ifndef CONFIG_USER_ONLY
+    page_already_protected = p->first_tb != NULL;
+#endif
+    p->first_tb = (TranslationBlock *)((uintptr_t)tb | n);
+    invalidate_page_bitmap(p);
+
+#if defined(CONFIG_USER_ONLY)
+    if (p->flags & PAGE_WRITE) {
+        target_ulong addr;
+        PageDesc *p2;
+        int prot;
+
+        /* force the host page as non writable (writes will have a
+           page fault + mprotect overhead) */
+        page_addr &= qemu_host_page_mask;
+        prot = 0;
+        for (addr = page_addr; addr < page_addr + qemu_host_page_size;
+            addr += TARGET_PAGE_SIZE) {
+
+            p2 = page_find(addr >> TARGET_PAGE_BITS);
+            if (!p2) {
+                continue;
+            }
+            prot |= p2->flags;
+            p2->flags &= ~PAGE_WRITE;
+          }
+        mprotect(g2h(page_addr), qemu_host_page_size,
+                 (prot & PAGE_BITS) & ~PAGE_WRITE);
+#ifdef DEBUG_TB_INVALIDATE
+        printf("protecting code page: 0x" TARGET_FMT_lx "\n",
+               page_addr);
+#endif
+    }
+#else
+    /* if some code is already present, then the pages are already
+       protected. So we handle the case where only the first TB is
+       allocated in a physical page */
+    if (!page_already_protected) {
+        tlb_protect_code(page_addr);
     }
 #endif
-    return false;
 }
+
+/* add a new TB and link it to the physical page tables. phys_page2 is
+ * (-1) to indicate that only one page contains the TB.
+ *
+ * Called with mmap_lock held for user-mode emulation.
+ */
+static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
+                         tb_page_addr_t phys_page2)
+{
+    unsigned int h;
+    TranslationBlock **ptb;
+
+    /* add in the physical hash table */
+    h = tb_phys_hash_func(phys_pc);
+    ptb = &tcg_ctx.tb_ctx.tb_phys_hash[h];
+    tb->phys_hash_next = *ptb;
+    *ptb = tb;
+
+    /* add in the page list */
+    tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK);
+    if (phys_page2 != -1) {
+        tb_alloc_page(tb, 1, phys_page2);
+    } else {
+        tb->page_addr[1] = -1;
+    }
+
+    tb->jmp_first = (TranslationBlock *)((uintptr_t)tb | 2);
+    tb->jmp_next[0] = NULL;
+    tb->jmp_next[1] = NULL;
+
+    /* init original jump addresses */
+    if (tb->tb_next_offset[0] != 0xffff) {
+        tb_reset_jump(tb, 0);
+    }
+    if (tb->tb_next_offset[1] != 0xffff) {
+        tb_reset_jump(tb, 1);
+    }
+
+#ifdef DEBUG_TB_CHECK
+    tb_page_check();
 #endif
+}
 
 /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <
    tb[1].tc_ptr. Return NULL if not found */
@@ -1550,7 +1552,8 @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
         rcu_read_unlock();
         return;
     }
-    ram_addr = memory_region_get_ram_addr(mr) + addr;
+    ram_addr = (memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK)
+        + addr;
     tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
     rcu_read_unlock();
 }
@@ -1571,7 +1574,7 @@ void tb_check_watchpoint(CPUState *cpu)
         CPUArchState *env = cpu->env_ptr;
         target_ulong pc, cs_base;
         tb_page_addr_t addr;
-        uint32_t flags;
+        int flags;
 
         cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
         addr = get_page_addr_code(env, pc);
@@ -1590,7 +1593,7 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
     TranslationBlock *tb;
     uint32_t n, cflags;
     target_ulong pc, cs_base;
-    uint32_t flags;
+    uint64_t flags;
 
     tb = tb_find_pc(retaddr);
     if (!tb) {
@@ -1648,7 +1651,7 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
        repeating the fault, which is horribly inefficient.
        Better would be to execute just this insn uncached, or generate a
        second new TB.  */
-    cpu_loop_exit_noexc(cpu);
+    cpu_resume_from_signal(cpu, NULL);
 }
 
 void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr)
@@ -1666,50 +1669,11 @@ void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr)
            TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
 }
 
-static void print_qht_statistics(FILE *f, fprintf_function cpu_fprintf,
-                                 struct qht_stats hst)
-{
-    uint32_t hgram_opts;
-    size_t hgram_bins;
-    char *hgram;
-
-    if (!hst.head_buckets) {
-        return;
-    }
-    cpu_fprintf(f, "TB hash buckets     %zu/%zu (%0.2f%% head buckets used)\n",
-                hst.used_head_buckets, hst.head_buckets,
-                (double)hst.used_head_buckets / hst.head_buckets * 100);
-
-    hgram_opts =  QDIST_PR_BORDER | QDIST_PR_LABELS;
-    hgram_opts |= QDIST_PR_100X   | QDIST_PR_PERCENT;
-    if (qdist_xmax(&hst.occupancy) - qdist_xmin(&hst.occupancy) == 1) {
-        hgram_opts |= QDIST_PR_NODECIMAL;
-    }
-    hgram = qdist_pr(&hst.occupancy, 10, hgram_opts);
-    cpu_fprintf(f, "TB hash occupancy   %0.2f%% avg chain occ. Histogram: %s\n",
-                qdist_avg(&hst.occupancy) * 100, hgram);
-    g_free(hgram);
-
-    hgram_opts = QDIST_PR_BORDER | QDIST_PR_LABELS;
-    hgram_bins = qdist_xmax(&hst.chain) - qdist_xmin(&hst.chain);
-    if (hgram_bins > 10) {
-        hgram_bins = 10;
-    } else {
-        hgram_bins = 0;
-        hgram_opts |= QDIST_PR_NODECIMAL | QDIST_PR_NOBINRANGE;
-    }
-    hgram = qdist_pr(&hst.chain, hgram_bins, hgram_opts);
-    cpu_fprintf(f, "TB hash avg chain   %0.3f buckets. Histogram: %s\n",
-                qdist_avg(&hst.chain), hgram);
-    g_free(hgram);
-}
-
 void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
 {
     int i, target_code_size, max_target_code_size;
     int direct_jmp_count, direct_jmp2_count, cross_page;
     TranslationBlock *tb;
-    struct qht_stats hst;
 
     target_code_size = 0;
     max_target_code_size = 0;
@@ -1725,9 +1689,9 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
         if (tb->page_addr[1] != -1) {
             cross_page++;
         }
-        if (tb->jmp_reset_offset[0] != TB_JMP_RESET_OFFSET_INVALID) {
+        if (tb->tb_next_offset[0] != 0xffff) {
             direct_jmp_count++;
-            if (tb->jmp_reset_offset[1] != TB_JMP_RESET_OFFSET_INVALID) {
+            if (tb->tb_next_offset[1] != 0xffff) {
                 direct_jmp2_count++;
             }
         }
@@ -1760,11 +1724,6 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
                 direct_jmp2_count,
                 tcg_ctx.tb_ctx.nb_tbs ? (direct_jmp2_count * 100) /
                         tcg_ctx.tb_ctx.nb_tbs : 0);
-
-    qht_statistics_init(&tcg_ctx.tb_ctx.htable, &hst);
-    print_qht_statistics(f, cpu_fprintf, hst);
-    qht_statistics_destroy(&hst);
-
     cpu_fprintf(f, "\nStatistics:\n");
     cpu_fprintf(f, "TB flush count      %d\n", tcg_ctx.tb_ctx.tb_flush_count);
     cpu_fprintf(f, "TB invalidate count %d\n",
@@ -1941,7 +1900,7 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
         if (!(p->flags & PAGE_WRITE) &&
             (flags & PAGE_WRITE) &&
             p->first_tb) {
-            tb_invalidate_phys_page(addr, 0);
+            tb_invalidate_phys_page(addr, 0, NULL, false);
         }
         p->flags = flags;
     }
@@ -1993,7 +1952,7 @@ int page_check_range(target_ulong start, target_ulong len, int flags)
             /* unprotect the page if it was put read-only because it
                contains translated code */
             if (!(p->flags & PAGE_WRITE)) {
-                if (!page_unprotect(addr, 0)) {
+                if (!page_unprotect(addr, 0, NULL)) {
                     return -1;
                 }
             }
@@ -2003,15 +1962,10 @@ int page_check_range(target_ulong start, target_ulong len, int flags)
 }
 
 /* called from signal handler: invalidate the code and unprotect the
- * page. Return 0 if the fault was not handled, 1 if it was handled,
- * and 2 if it was handled but the caller must cause the TB to be
- * immediately exited. (We can only return 2 if the 'pc' argument is
- * non-zero.)
- */
-int page_unprotect(target_ulong address, uintptr_t pc)
+   page. Return TRUE if the fault was successfully handled. */
+int page_unprotect(target_ulong address, uintptr_t pc, void *puc)
 {
     unsigned int prot;
-    bool current_tb_invalidated;
     PageDesc *p;
     target_ulong host_start, host_end, addr;
 
@@ -2033,7 +1987,6 @@ int page_unprotect(target_ulong address, uintptr_t pc)
         host_end = host_start + qemu_host_page_size;
 
         prot = 0;
-        current_tb_invalidated = false;
         for (addr = host_start ; addr < host_end ; addr += TARGET_PAGE_SIZE) {
             p = page_find(addr >> TARGET_PAGE_BITS);
             p->flags |= PAGE_WRITE;
@@ -2041,7 +1994,7 @@ int page_unprotect(target_ulong address, uintptr_t pc)
 
             /* and since the content will be modified, we must invalidate
                the corresponding translated code. */
-            current_tb_invalidated |= tb_invalidate_phys_page(addr, pc);
+            tb_invalidate_phys_page(addr, pc, puc, true);
 #ifdef DEBUG_TB_CHECK
             tb_invalidate_check(addr);
 #endif
@@ -2050,8 +2003,7 @@ int page_unprotect(target_ulong address, uintptr_t pc)
                  prot & PAGE_BITS);
 
         mmap_unlock();
-        /* If current TB was invalidated return to main loop */
-        return current_tb_invalidated ? 2 : 1;
+        return 1;
     }
     mmap_unlock();
     return 0;
index ba8e4d6..0384640 100644 (file)
@@ -19,9 +19,6 @@
 #ifndef TRANSLATE_ALL_H
 #define TRANSLATE_ALL_H
 
-#include "exec/exec-all.h"
-
-
 /* translate-all.c */
 void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len);
 void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
@@ -30,7 +27,7 @@ void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end);
 void tb_check_watchpoint(CPUState *cpu);
 
 #ifdef CONFIG_USER_ONLY
-int page_unprotect(target_ulong address, uintptr_t pc);
+int page_unprotect(target_ulong address, uintptr_t pc, void *puc);
 #endif
 
 #endif /* TRANSLATE_ALL_H */
index 5e989cd..ffbfe85 100644 (file)
@@ -20,7 +20,6 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qom/cpu.h"
-#include "sysemu/cpus.h"
 
 uintptr_t qemu_real_host_page_size;
 intptr_t qemu_real_host_page_mask;
index 5165e21..74b1bed 100644 (file)
@@ -88,11 +88,6 @@ void surface_gl_create_texture(ConsoleGLState *gls,
         surface->glformat = GL_BGRA_EXT;
         surface->gltype = GL_UNSIGNED_BYTE;
         break;
-    case PIXMAN_BE_x8r8g8b8:
-    case PIXMAN_BE_a8r8g8b8:
-        surface->glformat = GL_RGBA;
-        surface->gltype = GL_UNSIGNED_BYTE;
-        break;
     case PIXMAN_r5g6b5:
         surface->glformat = GL_RGB;
         surface->gltype = GL_UNSIGNED_SHORT_5_6_5;
index c24bfe4..bf38579 100644 (file)
@@ -1453,21 +1453,16 @@ bool dpy_ui_info_supported(QemuConsole *con)
 int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info)
 {
     assert(con != NULL);
-
+    con->ui_info = *info;
     if (!dpy_ui_info_supported(con)) {
         return -1;
     }
-    if (memcmp(&con->ui_info, info, sizeof(con->ui_info)) == 0) {
-        /* nothing changed -- ignore */
-        return 0;
-    }
 
     /*
      * Typically we get a flood of these as the user resizes the window.
      * Wait until the dust has settled (one second without updates), then
      * go notify the guest.
      */
-    con->ui_info = *info;
     timer_mod(con->ui_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
     return 0;
 }
@@ -1709,13 +1704,11 @@ QEMUGLContext dpy_gl_ctx_get_current(QemuConsole *con)
 
 void dpy_gl_scanout(QemuConsole *con,
                     uint32_t backing_id, bool backing_y_0_top,
-                    uint32_t backing_width, uint32_t backing_height,
                     uint32_t x, uint32_t y, uint32_t width, uint32_t height)
 {
     assert(con->gl);
     con->gl->ops->dpy_gl_scanout(con->gl, backing_id,
                                  backing_y_0_top,
-                                 backing_width, backing_height,
                                  x, y, width, height);
 }
 
index e39ef9e..f746744 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #ifndef QEMU_CURSES_KEYS_H
-#define QEMU_CURSES_KEYS_H
+#define QEMU_CURSES_KEYS_H 1
 
 #include <curses.h>
 #include "keymaps.h"
index 5155b39..a276e01 100644 (file)
@@ -81,12 +81,18 @@ void cursor_print_ascii_art(QEMUCursor *c, const char *prefix)
 
 QEMUCursor *cursor_builtin_hidden(void)
 {
-    return cursor_parse_xpm(cursor_hidden_xpm);
+    QEMUCursor *c;
+
+    c = cursor_parse_xpm(cursor_hidden_xpm);
+    return c;
 }
 
 QEMUCursor *cursor_builtin_left_ptr(void)
 {
-    return cursor_parse_xpm(cursor_left_ptr_xpm);
+    QEMUCursor *c;
+
+    c = cursor_parse_xpm(cursor_left_ptr_xpm);
+    return c;
 }
 
 QEMUCursor *cursor_alloc(int width, int height)
index 79cee05..558edfd 100644 (file)
@@ -2,7 +2,6 @@
 #include <glob.h>
 #include <dirent.h>
 
-#include "qemu/error-report.h"
 #include "ui/egl-helpers.h"
 
 EGLDisplay *qemu_egl_display;
@@ -50,15 +49,18 @@ int qemu_egl_rendernode_open(void)
             continue;
         }
 
-        p = g_strdup_printf("/dev/dri/%s", e->d_name);
+        r = asprintf(&p, "/dev/dri/%s", e->d_name);
+        if (r < 0) {
+            return -1;
+        }
 
         r = open(p, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
         if (r < 0) {
-            g_free(p);
+            free(p);
             continue;
         }
         fd = r;
-        g_free(p);
+        free(p);
         break;
     }
 
@@ -75,13 +77,13 @@ int egl_rendernode_init(void)
 
     qemu_egl_rn_fd = qemu_egl_rendernode_open();
     if (qemu_egl_rn_fd == -1) {
-        error_report("egl: no drm render node available");
+        fprintf(stderr, "egl: no drm render node available\n");
         goto err;
     }
 
     qemu_egl_rn_gbm_dev = gbm_create_device(qemu_egl_rn_fd);
     if (!qemu_egl_rn_gbm_dev) {
-        error_report("egl: gbm_create_device failed");
+        fprintf(stderr, "egl: gbm_create_device failed\n");
         goto err;
     }
 
@@ -89,18 +91,18 @@ int egl_rendernode_init(void)
 
     if (!epoxy_has_egl_extension(qemu_egl_display,
                                  "EGL_KHR_surfaceless_context")) {
-        error_report("egl: EGL_KHR_surfaceless_context not supported");
+        fprintf(stderr, "egl: EGL_KHR_surfaceless_context not supported\n");
         goto err;
     }
     if (!epoxy_has_egl_extension(qemu_egl_display,
                                  "EGL_MESA_image_dma_buf_export")) {
-        error_report("egl: EGL_MESA_image_dma_buf_export not supported");
+        fprintf(stderr, "egl: EGL_MESA_image_dma_buf_export not supported\n");
         goto err;
     }
 
     qemu_egl_rn_ctx = qemu_egl_init_ctx();
     if (!qemu_egl_rn_ctx) {
-        error_report("egl: egl_init_ctx failed");
+        fprintf(stderr, "egl: egl_init_ctx failed\n");
         goto err;
     }
 
@@ -157,13 +159,13 @@ EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win)
                                       qemu_egl_config,
                                       (EGLNativeWindowType)win, NULL);
     if (esurface == EGL_NO_SURFACE) {
-        error_report("egl: eglCreateWindowSurface failed");
+        fprintf(stderr, "egl: eglCreateWindowSurface failed\n");
         return NULL;
     }
 
     b = eglMakeCurrent(qemu_egl_display, esurface, esurface, ectx);
     if (b == EGL_FALSE) {
-        error_report("egl: eglMakeCurrent failed");
+        fprintf(stderr, "egl: eglMakeCurrent failed\n");
         return NULL;
     }
 
@@ -205,21 +207,21 @@ int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug)
     egl_dbg("eglGetDisplay (dpy %p) ...\n", dpy);
     qemu_egl_display = eglGetDisplay(dpy);
     if (qemu_egl_display == EGL_NO_DISPLAY) {
-        error_report("egl: eglGetDisplay failed");
+        fprintf(stderr, "egl: eglGetDisplay failed\n");
         return -1;
     }
 
     egl_dbg("eglInitialize ...\n");
     b = eglInitialize(qemu_egl_display, &major, &minor);
     if (b == EGL_FALSE) {
-        error_report("egl: eglInitialize failed");
+        fprintf(stderr, "egl: eglInitialize failed\n");
         return -1;
     }
 
     egl_dbg("eglBindAPI ...\n");
     b = eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API);
     if (b == EGL_FALSE) {
-        error_report("egl: eglBindAPI failed");
+        fprintf(stderr, "egl: eglBindAPI failed\n");
         return -1;
     }
 
@@ -228,7 +230,7 @@ int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug)
                         gles ? conf_att_gles : conf_att_gl,
                         &qemu_egl_config, 1, &n);
     if (b == EGL_FALSE || n != 1) {
-        error_report("egl: eglChooseConfig failed");
+        fprintf(stderr, "egl: eglChooseConfig failed\n");
         return -1;
     }
 
@@ -253,13 +255,13 @@ EGLContext qemu_egl_init_ctx(void)
     ectx = eglCreateContext(qemu_egl_display, qemu_egl_config, EGL_NO_CONTEXT,
                             egl_gles ? ctx_att_gles : ctx_att_gl);
     if (ectx == EGL_NO_CONTEXT) {
-        error_report("egl: eglCreateContext failed");
+        fprintf(stderr, "egl: eglCreateContext failed\n");
         return NULL;
     }
 
     b = eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, ectx);
     if (b == EGL_FALSE) {
-        error_report("egl: eglMakeCurrent failed");
+        fprintf(stderr, "egl: eglMakeCurrent failed\n");
         return NULL;
     }
 
index 3f5d328..431457c 100644 (file)
@@ -172,7 +172,6 @@ QEMUGLContext gd_egl_create_context(DisplayChangeListener *dcl,
 
 void gd_egl_scanout(DisplayChangeListener *dcl,
                     uint32_t backing_id, bool backing_y_0_top,
-                    uint32_t backing_width, uint32_t backing_height,
                     uint32_t x, uint32_t y,
                     uint32_t w, uint32_t h)
 {
index 0df5a36..b86ff3c 100644 (file)
@@ -169,7 +169,6 @@ void gd_gl_area_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)
 
 void gd_gl_area_scanout(DisplayChangeListener *dcl,
                         uint32_t backing_id, bool backing_y_0_top,
-                        uint32_t backing_width, uint32_t backing_height,
                         uint32_t x, uint32_t y,
                         uint32_t w, uint32_t h)
 {
index 58d20ee..9876d89 100644 (file)
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -139,7 +139,6 @@ struct GtkDisplayState {
     GtkWidget *view_menu_item;
     GtkWidget *view_menu;
     GtkWidget *full_screen_item;
-    GtkWidget *copy_item;
     GtkWidget *zoom_in_item;
     GtkWidget *zoom_out_item;
     GtkWidget *zoom_fixed_item;
@@ -329,23 +328,7 @@ static void gd_update_geometry_hints(VirtualConsole *vc)
 #if defined(CONFIG_VTE)
     } else if (vc->type == GD_VC_VTE) {
         VteTerminal *term = VTE_TERMINAL(vc->vte.terminal);
-        GtkBorder padding = { 0 };
-
-#if VTE_CHECK_VERSION(0, 37, 0)
-        gtk_style_context_get_padding(
-                gtk_widget_get_style_context(vc->vte.terminal),
-                gtk_widget_get_state_flags(vc->vte.terminal),
-                &padding);
-#else
-        {
-            GtkBorder *ib = NULL;
-            gtk_widget_style_get(vc->vte.terminal, "inner-border", &ib, NULL);
-            if (ib) {
-                padding = *ib;
-                gtk_border_free(ib);
-            }
-        }
-#endif
+        GtkBorder *ib;
 
         geo.width_inc  = vte_terminal_get_char_width(term);
         geo.height_inc = vte_terminal_get_char_height(term);
@@ -356,11 +339,13 @@ static void gd_update_geometry_hints(VirtualConsole *vc)
         geo.min_width  = geo.width_inc * VC_TERM_X_MIN;
         geo.min_height = geo.height_inc * VC_TERM_Y_MIN;
         mask |= GDK_HINT_MIN_SIZE;
-
-        geo.base_width  += padding.left + padding.right;
-        geo.base_height += padding.top + padding.bottom;
-        geo.min_width   += padding.left + padding.right;
-        geo.min_height  += padding.top + padding.bottom;
+        gtk_widget_style_get(vc->vte.terminal, "inner-border", &ib, NULL);
+        if (ib) {
+            geo.base_width  += ib->left + ib->right;
+            geo.base_height += ib->top + ib->bottom;
+            geo.min_width   += ib->left + ib->right;
+            geo.min_height  += ib->top + ib->bottom;
+        }
         geo_widget = vc->vte.terminal;
 #endif
     }
@@ -480,21 +465,12 @@ static void gd_refresh(DisplayChangeListener *dcl)
 }
 
 #if GTK_CHECK_VERSION(3, 0, 0)
-static GdkDevice *gd_get_pointer(GdkDisplay *dpy)
-{
-#if GTK_CHECK_VERSION(3, 20, 0)
-    return gdk_seat_get_pointer(gdk_display_get_default_seat(dpy));
-#else
-    return gdk_device_manager_get_client_pointer(
-        gdk_display_get_device_manager(dpy));
-#endif
-}
-
 static void gd_mouse_set(DisplayChangeListener *dcl,
                          int x, int y, int visible)
 {
     VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
     GdkDisplay *dpy;
+    GdkDeviceManager *mgr;
     gint x_root, y_root;
 
     if (qemu_input_is_absolute()) {
@@ -502,9 +478,10 @@ static void gd_mouse_set(DisplayChangeListener *dcl,
     }
 
     dpy = gtk_widget_get_display(vc->gfx.drawing_area);
+    mgr = gdk_display_get_device_manager(dpy);
     gdk_window_get_root_coords(gtk_widget_get_window(vc->gfx.drawing_area),
                                x, y, &x_root, &y_root);
-    gdk_device_warp(gd_get_pointer(dpy),
+    gdk_device_warp(gdk_device_manager_get_client_pointer(mgr),
                     gtk_widget_get_screen(vc->gfx.drawing_area),
                     x_root, y_root);
     vc->s->last_x = x;
@@ -1332,31 +1309,7 @@ static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
     gd_update_full_redraw(vc);
 }
 
-#if GTK_CHECK_VERSION(3, 20, 0)
-static void gd_grab_update(VirtualConsole *vc, bool kbd, bool ptr)
-{
-    GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area);
-    GdkSeat *seat = gdk_display_get_default_seat(display);
-    GdkWindow *window = gtk_widget_get_window(vc->gfx.drawing_area);
-    GdkSeatCapabilities caps = 0;
-    GdkCursor *cursor = NULL;
-
-    if (kbd) {
-        caps |= GDK_SEAT_CAPABILITY_KEYBOARD;
-    }
-    if (ptr) {
-        caps |= GDK_SEAT_CAPABILITY_ALL_POINTING;
-        cursor = vc->s->null_cursor;
-    }
-
-    if (caps) {
-        gdk_seat_grab(seat, window, caps, false, cursor,
-                      NULL, NULL, NULL);
-    } else {
-        gdk_seat_ungrab(seat);
-    }
-}
-#elif GTK_CHECK_VERSION(3, 0, 0)
+#if GTK_CHECK_VERSION(3, 0, 0)
 static void gd_grab_devices(VirtualConsole *vc, bool grab,
                             GdkInputSource source, GdkEventMask mask,
                             GdkCursor *cursor)
@@ -1393,9 +1346,7 @@ static void gd_grab_keyboard(VirtualConsole *vc, const char *reason)
         }
     }
 
-#if GTK_CHECK_VERSION(3, 20, 0)
-    gd_grab_update(vc, true, vc->s->ptr_owner == vc);
-#elif GTK_CHECK_VERSION(3, 0, 0)
+#if GTK_CHECK_VERSION(3, 0, 0)
     gd_grab_devices(vc, true, GDK_SOURCE_KEYBOARD,
                    GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
                    NULL);
@@ -1418,9 +1369,7 @@ static void gd_ungrab_keyboard(GtkDisplayState *s)
     }
     s->kbd_owner = NULL;
 
-#if GTK_CHECK_VERSION(3, 20, 0)
-    gd_grab_update(vc, false, vc->s->ptr_owner == vc);
-#elif GTK_CHECK_VERSION(3, 0, 0)
+#if GTK_CHECK_VERSION(3, 0, 0)
     gd_grab_devices(vc, false, GDK_SOURCE_KEYBOARD, 0, NULL);
 #else
     gdk_keyboard_ungrab(GDK_CURRENT_TIME);
@@ -1441,11 +1390,8 @@ static void gd_grab_pointer(VirtualConsole *vc, const char *reason)
         }
     }
 
-#if GTK_CHECK_VERSION(3, 20, 0)
-    gd_grab_update(vc, vc->s->kbd_owner == vc, true);
-    gdk_device_get_position(gd_get_pointer(display),
-                            NULL, &vc->s->grab_x_root, &vc->s->grab_y_root);
-#elif GTK_CHECK_VERSION(3, 0, 0)
+#if GTK_CHECK_VERSION(3, 0, 0)
+    GdkDeviceManager *mgr = gdk_display_get_device_manager(display);
     gd_grab_devices(vc, true, GDK_SOURCE_MOUSE,
                     GDK_POINTER_MOTION_MASK |
                     GDK_BUTTON_PRESS_MASK |
@@ -1453,7 +1399,7 @@ static void gd_grab_pointer(VirtualConsole *vc, const char *reason)
                     GDK_BUTTON_MOTION_MASK |
                     GDK_SCROLL_MASK,
                     vc->s->null_cursor);
-    gdk_device_get_position(gd_get_pointer(display),
+    gdk_device_get_position(gdk_device_manager_get_client_pointer(mgr),
                             NULL, &vc->s->grab_x_root, &vc->s->grab_y_root);
 #else
     gdk_pointer_grab(gtk_widget_get_window(vc->gfx.drawing_area),
@@ -1477,22 +1423,17 @@ static void gd_grab_pointer(VirtualConsole *vc, const char *reason)
 static void gd_ungrab_pointer(GtkDisplayState *s)
 {
     VirtualConsole *vc = s->ptr_owner;
-    GdkDisplay *display;
 
     if (vc == NULL) {
         return;
     }
     s->ptr_owner = NULL;
 
-    display = gtk_widget_get_display(vc->gfx.drawing_area);
-#if GTK_CHECK_VERSION(3, 20, 0)
-    gd_grab_update(vc, vc->s->kbd_owner == vc, false);
-    gdk_device_warp(gd_get_pointer(display),
-                    gtk_widget_get_screen(vc->gfx.drawing_area),
-                    vc->s->grab_x_root, vc->s->grab_y_root);
-#elif GTK_CHECK_VERSION(3, 0, 0)
+    GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area);
+#if GTK_CHECK_VERSION(3, 0, 0)
+    GdkDeviceManager *mgr = gdk_display_get_device_manager(display);
     gd_grab_devices(vc, false, GDK_SOURCE_MOUSE, 0, NULL);
-    gdk_device_warp(gd_get_pointer(display),
+    gdk_device_warp(gdk_device_manager_get_client_pointer(mgr),
                     gtk_widget_get_screen(vc->gfx.drawing_area),
                     vc->s->grab_x_root, vc->s->grab_y_root);
 #else
@@ -1631,14 +1572,6 @@ static GSList *gd_vc_menu_init(GtkDisplayState *s, VirtualConsole *vc,
 }
 
 #if defined(CONFIG_VTE)
-static void gd_menu_copy(GtkMenuItem *item, void *opaque)
-{
-    GtkDisplayState *s = opaque;
-    VirtualConsole *vc = gd_vc_find_current(s);
-
-    vte_terminal_copy_clipboard(VTE_TERMINAL(vc->vte.terminal));
-}
-
 static void gd_vc_adjustment_changed(GtkAdjustment *adjustment, void *opaque)
 {
     VirtualConsole *vc = opaque;
@@ -1748,7 +1681,7 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc,
     /* The documentation says that the default is UTF-8, but actually it is
      * 7-bit ASCII at least in VTE 0.38.
      */
-#if VTE_CHECK_VERSION(0, 38, 0)
+#if VTE_CHECK_VERSION(0, 40, 0)
     vte_terminal_set_encoding(VTE_TERMINAL(vc->vte.terminal), "UTF-8", NULL);
 #else
     vte_terminal_set_encoding(VTE_TERMINAL(vc->vte.terminal), "UTF-8");
@@ -1875,10 +1808,6 @@ static void gd_connect_signals(GtkDisplayState *s)
                      G_CALLBACK(gd_menu_powerdown), s);
     g_signal_connect(s->quit_item, "activate",
                      G_CALLBACK(gd_menu_quit), s);
-#if defined(CONFIG_VTE)
-    g_signal_connect(s->copy_item, "activate",
-                     G_CALLBACK(gd_menu_copy), s);
-#endif
     g_signal_connect(s->full_screen_item, "activate",
                      G_CALLBACK(gd_menu_full_screen), s);
     g_signal_connect(s->zoom_in_item, "activate",
@@ -2012,11 +1941,6 @@ static GtkWidget *gd_create_menu_view(GtkDisplayState *s)
 
     s->full_screen_item = gtk_menu_item_new_with_mnemonic(_("_Fullscreen"));
 
-#if defined(CONFIG_VTE)
-    s->copy_item = gtk_menu_item_new_with_mnemonic(_("_Copy"));
-    gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->copy_item);
-#endif
-
     gtk_accel_group_connect(s->accel_group, GDK_KEY_f, HOTKEY_MODIFIERS, 0,
             g_cclosure_new_swap(G_CALLBACK(gd_accel_full_screen), s, NULL));
 #if GTK_CHECK_VERSION(3, 8, 0)
index 0e230ce..1d33b5c 100644 (file)
@@ -129,17 +129,6 @@ static int qemu_input_linux_to_qcode(unsigned int lnx)
     return linux_to_qcode[lnx];
 }
 
-static bool linux_is_button(unsigned int lnx)
-{
-    if (lnx < 0x100) {
-        return false;
-    }
-    if (lnx >= 0x160 && lnx < 0x2c0) {
-        return false;
-    }
-    return true;
-}
-
 #define TYPE_INPUT_LINUX "input-linux"
 #define INPUT_LINUX(obj) \
     OBJECT_CHECK(InputLinux, (obj), TYPE_INPUT_LINUX)
@@ -164,12 +153,6 @@ struct InputLinux {
     int         keycount;
     int         wheel;
     bool        initialized;
-
-    bool        has_rel_x;
-    bool        has_abs_x;
-    int         num_keys;
-    int         num_btns;
-
     QTAILQ_ENTRY(InputLinux) next;
 };
 
@@ -205,55 +188,71 @@ static void input_linux_toggle_grab(InputLinux *il)
     }
 }
 
-static void input_linux_handle_keyboard(InputLinux *il,
-                                        struct input_event *event)
+static void input_linux_event_keyboard(void *opaque)
 {
-    if (event->type == EV_KEY) {
-        if (event->value > 2 || (event->value > 1 && !il->repeat)) {
-            /*
-             * ignore autorepeat + unknown key events
-             * 0 == up, 1 == down, 2 == autorepeat, other == undefined
-             */
-            return;
-        }
-        if (event->code >= KEY_CNT) {
-            /*
-             * Should not happen.  But better safe than sorry,
-             * and we make Coverity happy too.
-             */
-            return;
-        }
+    InputLinux *il = opaque;
+    struct input_event event;
+    int rc;
 
-        /* keep track of key state */
-        if (!il->keydown[event->code] && event->value) {
-            il->keydown[event->code] = true;
-            il->keycount++;
-        }
-        if (il->keydown[event->code] && !event->value) {
-            il->keydown[event->code] = false;
-            il->keycount--;
+    for (;;) {
+        rc = read(il->fd, &event, sizeof(event));
+        if (rc != sizeof(event)) {
+            if (rc < 0 && errno != EAGAIN) {
+                fprintf(stderr, "%s: read: %s\n", __func__, strerror(errno));
+                qemu_set_fd_handler(il->fd, NULL, NULL, NULL);
+                close(il->fd);
+            }
+            break;
         }
 
-        /* send event to guest when grab is active */
-        if (il->grab_active) {
-            int qcode = qemu_input_linux_to_qcode(event->code);
-            qemu_input_event_send_key_qcode(NULL, qcode, event->value);
-        }
+        switch (event.type) {
+        case EV_KEY:
+            if (event.value > 2 || (event.value > 1 && !il->repeat)) {
+                /*
+                 * ignore autorepeat + unknown key events
+                 * 0 == up, 1 == down, 2 == autorepeat, other == undefined
+                 */
+                continue;
+            }
+            if (event.code >= KEY_CNT) {
+                /*
+                 * Should not happen.  But better safe than sorry,
+                 * and we make Coverity happy too.
+                 */
+                continue;
+            }
+            /* keep track of key state */
+            if (!il->keydown[event.code] && event.value) {
+                il->keydown[event.code] = true;
+                il->keycount++;
+            }
+            if (il->keydown[event.code] && !event.value) {
+                il->keydown[event.code] = false;
+                il->keycount--;
+            }
 
-        /* hotkey -> record switch request ... */
-        if (il->keydown[KEY_LEFTCTRL] &&
-            il->keydown[KEY_RIGHTCTRL]) {
-            il->grab_request = true;
-        }
+            /* send event to guest when grab is active */
+            if (il->grab_active) {
+                int qcode = qemu_input_linux_to_qcode(event.code);
+                qemu_input_event_send_key_qcode(NULL, qcode, event.value);
+            }
+
+            /* hotkey -> record switch request ... */
+            if (il->keydown[KEY_LEFTCTRL] &&
+                il->keydown[KEY_RIGHTCTRL]) {
+                il->grab_request = true;
+            }
 
-        /*
-         * ... and do the switch when all keys are lifted, so we
-         * confuse neither guest nor host with keys which seem to
-         * be stuck due to missing key-up events.
-         */
-        if (il->grab_request && !il->keycount) {
-            il->grab_request = false;
-            input_linux_toggle_grab(il);
+            /*
+             * ... and do the switch when all keys are lifted, so we
+             * confuse neither guest nor host with keys which seem to
+             * be stuck due to missing key-up events.
+             */
+            if (il->grab_request && !il->keycount) {
+                il->grab_request = false;
+                input_linux_toggle_grab(il);
+            }
+            break;
         }
     }
 }
@@ -266,59 +265,7 @@ static void input_linux_event_mouse_button(int button)
     qemu_input_event_sync();
 }
 
-static void input_linux_handle_mouse(InputLinux *il, struct input_event *event)
-{
-    if (!il->grab_active) {
-        return;
-    }
-
-    switch (event->type) {
-    case EV_KEY:
-        switch (event->code) {
-        case BTN_LEFT:
-            qemu_input_queue_btn(NULL, INPUT_BUTTON_LEFT, event->value);
-            break;
-        case BTN_RIGHT:
-            qemu_input_queue_btn(NULL, INPUT_BUTTON_RIGHT, event->value);
-            break;
-        case BTN_MIDDLE:
-            qemu_input_queue_btn(NULL, INPUT_BUTTON_MIDDLE, event->value);
-            break;
-        case BTN_GEAR_UP:
-            qemu_input_queue_btn(NULL, INPUT_BUTTON_WHEEL_UP, event->value);
-            break;
-        case BTN_GEAR_DOWN:
-            qemu_input_queue_btn(NULL, INPUT_BUTTON_WHEEL_DOWN,
-                                 event->value);
-            break;
-        };
-        break;
-    case EV_REL:
-        switch (event->code) {
-        case REL_X:
-            qemu_input_queue_rel(NULL, INPUT_AXIS_X, event->value);
-            break;
-        case REL_Y:
-            qemu_input_queue_rel(NULL, INPUT_AXIS_Y, event->value);
-            break;
-        case REL_WHEEL:
-            il->wheel = event->value;
-            break;
-        }
-        break;
-    case EV_SYN:
-        qemu_input_event_sync();
-        if (il->wheel != 0) {
-            input_linux_event_mouse_button((il->wheel > 0)
-                                           ? INPUT_BUTTON_WHEEL_UP
-                                           : INPUT_BUTTON_WHEEL_DOWN);
-            il->wheel = 0;
-        }
-        break;
-    }
-}
-
-static void input_linux_event(void *opaque)
+static void input_linux_event_mouse(void *opaque)
 {
     InputLinux *il = opaque;
     struct input_event event;
@@ -335,11 +282,54 @@ static void input_linux_event(void *opaque)
             break;
         }
 
-        if (il->num_keys) {
-            input_linux_handle_keyboard(il, &event);
+        /* only send event to guest when grab is active */
+        if (!il->grab_active) {
+            continue;
         }
-        if (il->has_rel_x && il->num_btns) {
-            input_linux_handle_mouse(il, &event);
+
+        switch (event.type) {
+        case EV_KEY:
+            switch (event.code) {
+            case BTN_LEFT:
+                qemu_input_queue_btn(NULL, INPUT_BUTTON_LEFT, event.value);
+                break;
+            case BTN_RIGHT:
+                qemu_input_queue_btn(NULL, INPUT_BUTTON_RIGHT, event.value);
+                break;
+            case BTN_MIDDLE:
+                qemu_input_queue_btn(NULL, INPUT_BUTTON_MIDDLE, event.value);
+                break;
+            case BTN_GEAR_UP:
+                qemu_input_queue_btn(NULL, INPUT_BUTTON_WHEEL_UP, event.value);
+                break;
+            case BTN_GEAR_DOWN:
+                qemu_input_queue_btn(NULL, INPUT_BUTTON_WHEEL_DOWN,
+                                     event.value);
+                break;
+            };
+            break;
+        case EV_REL:
+            switch (event.code) {
+            case REL_X:
+                qemu_input_queue_rel(NULL, INPUT_AXIS_X, event.value);
+                break;
+            case REL_Y:
+                qemu_input_queue_rel(NULL, INPUT_AXIS_Y, event.value);
+                break;
+            case REL_WHEEL:
+                il->wheel = event.value;
+                break;
+            }
+            break;
+        case EV_SYN:
+            qemu_input_event_sync();
+            if (il->wheel != 0) {
+                input_linux_event_mouse_button((il->wheel > 0)
+                                               ? INPUT_BUTTON_WHEEL_UP
+                                               : INPUT_BUTTON_WHEEL_DOWN);
+                il->wheel = 0;
+            }
+            break;
         }
     }
 }
@@ -347,8 +337,7 @@ static void input_linux_event(void *opaque)
 static void input_linux_complete(UserCreatable *uc, Error **errp)
 {
     InputLinux *il = INPUT_LINUX(uc);
-    uint8_t evtmap, relmap, absmap, keymap[KEY_CNT / 8];
-    unsigned int i;
+    uint32_t evtmap, relmap, absmap;
     int rc, ver;
 
     if (!il->evdev) {
@@ -376,36 +365,36 @@ static void input_linux_complete(UserCreatable *uc, Error **errp)
     }
 
     if (evtmap & (1 << EV_REL)) {
-        relmap = 0;
         rc = ioctl(il->fd, EVIOCGBIT(EV_REL, sizeof(relmap)), &relmap);
-        if (relmap & (1 << REL_X)) {
-            il->has_rel_x = true;
+        if (rc < 0) {
+            relmap = 0;
         }
     }
 
     if (evtmap & (1 << EV_ABS)) {
-        absmap = 0;
-        rc = ioctl(il->fd, EVIOCGBIT(EV_ABS, sizeof(absmap)), &absmap);
-        if (absmap & (1 << ABS_X)) {
-            il->has_abs_x = true;
+        ioctl(il->fd, EVIOCGBIT(EV_ABS, sizeof(absmap)), &absmap);
+        if (rc < 0) {
+            absmap = 0;
         }
     }
 
-    if (evtmap & (1 << EV_KEY)) {
-        memset(keymap, 0, sizeof(keymap));
-        rc = ioctl(il->fd, EVIOCGBIT(EV_KEY, sizeof(keymap)), keymap);
-        for (i = 0; i < KEY_CNT; i++) {
-            if (keymap[i / 8] & (1 << (i % 8))) {
-                if (linux_is_button(i)) {
-                    il->num_btns++;
-                } else {
-                    il->num_keys++;
-                }
-            }
-        }
+    if ((evtmap & (1 << EV_REL)) &&
+        (relmap & (1 << REL_X))) {
+        /* has relative x axis -> assume mouse */
+        qemu_set_fd_handler(il->fd, input_linux_event_mouse, NULL, il);
+    } else if ((evtmap & (1 << EV_ABS)) &&
+               (absmap & (1 << ABS_X))) {
+        /* has absolute x axis -> not supported */
+        error_setg(errp, "tablet/touchscreen not supported");
+        goto err_close;
+    } else if (evtmap & (1 << EV_KEY)) {
+        /* has keys/buttons (and no x axis) -> assume keyboard */
+        qemu_set_fd_handler(il->fd, input_linux_event_keyboard, NULL, il);
+    } else {
+        /* Huh? What is this? */
+        error_setg(errp, "unknown kind of input device");
+        goto err_close;
     }
-
-    qemu_set_fd_handler(il->fd, input_linux_event, NULL, il);
     input_linux_toggle_grab(il);
     QTAILQ_INSERT_TAIL(&inputs, il, next);
     il->initialized = true;
index 47d0613..a7600d5 100644 (file)
@@ -22,8 +22,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef QEMU_KEYMAPS_H
-#define QEMU_KEYMAPS_H
+#ifndef __QEMU_KEYMAPS_H__
+#define __QEMU_KEYMAPS_H__
 
 #include "qemu-common.h"
 
@@ -74,4 +74,4 @@ int keysym2scancode(void *kbd_layout, int keysym);
 int keycode_is_keypad(void *kbd_layout, int keycode);
 int keysym_is_numlock(void *kbd_layout, int keysym);
 
-#endif /* QEMU_KEYMAPS_H */
+#endif /* __QEMU_KEYMAPS_H__ */
index 6e8b83a..c9f8dce 100644 (file)
@@ -180,11 +180,14 @@ void qemu_pixman_linebuf_copy(pixman_image_t *fb, int width, int x, int y,
 pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
                                           pixman_image_t *image)
 {
-    return pixman_image_create_bits(format,
-                                    pixman_image_get_width(image),
-                                    pixman_image_get_height(image),
-                                    NULL,
-                                    pixman_image_get_stride(image));
+    pixman_image_t *mirror;
+
+    mirror = pixman_image_create_bits(format,
+                                      pixman_image_get_width(image),
+                                      pixman_image_get_height(image),
+                                      NULL,
+                                      pixman_image_get_stride(image));
+    return mirror;
 }
 
 void qemu_pixman_image_unref(pixman_image_t *image)
index 8ab68d6..9593006 100644 (file)
@@ -116,9 +116,6 @@ void sdl2_2d_switch(DisplayChangeListener *dcl,
     case PIXMAN_r8g8b8x8:
         format = SDL_PIXELFORMAT_RGBA8888;
         break;
-    case PIXMAN_b8g8r8x8:
-        format = SDL_PIXELFORMAT_BGRX8888;
-        break;
     default:
         g_assert_not_reached();
     }
index 039645d..a324eca 100644 (file)
@@ -186,7 +186,6 @@ QEMUGLContext sdl2_gl_get_current_context(DisplayChangeListener *dcl)
 
 void sdl2_gl_scanout(DisplayChangeListener *dcl,
                      uint32_t backing_id, bool backing_y_0_top,
-                     uint32_t backing_width, uint32_t backing_height,
                      uint32_t x, uint32_t y,
                      uint32_t w, uint32_t h)
 {
index b96196b..72622c2 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "qemu/osdep.h"
 #include "sdl_zoom.h"
+#include <glib.h>
 
 static void sdl_zoom_rgb16(SDL_Surface *src, SDL_Surface *dst, int smooth,
                            SDL_Rect *dst_rect);
index 39696dd..74955bc 100644 (file)
@@ -11,8 +11,8 @@
  *
  */
 
-#ifndef SDL_ZOOM_H
-#define SDL_ZOOM_H
+#ifndef SDL_zoom_h
+#define SDL_zoom_h
 
 #include <SDL.h>
 
@@ -22,4 +22,4 @@
 int sdl_zoom_blit(SDL_Surface *src_sfc, SDL_Surface *dst_sfc,
                   int smooth, SDL_Rect *src_rect);
 
-#endif /* SDL_ZOOM_H */
+#endif /* SDL_zoom_h */
index 1ffddbe..9264009 100644 (file)
@@ -83,12 +83,12 @@ GLuint qemu_gl_create_compile_shader(GLenum type, const GLchar *src)
     glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
     if (!status) {
         glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
-        errmsg = g_malloc(length);
+        errmsg = malloc(length);
         glGetShaderInfoLog(shader, length, &length, errmsg);
         fprintf(stderr, "%s: compile %s error\n%s\n", __func__,
                 (type == GL_VERTEX_SHADER) ? "vertex" : "fragment",
                 errmsg);
-        g_free(errmsg);
+        free(errmsg);
         return 0;
     }
     return shader;
@@ -108,10 +108,10 @@ GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag)
     glGetProgramiv(program, GL_LINK_STATUS, &status);
     if (!status) {
         glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
-        errmsg = g_malloc(length);
+        errmsg = malloc(length);
         glGetProgramInfoLog(program, length, &length, errmsg);
         fprintf(stderr, "%s: link program: %s\n", __func__, errmsg);
-        g_free(errmsg);
+        free(errmsg);
         return 0;
     }
     return program;
index 99132b6..2a77a54 100644 (file)
@@ -197,7 +197,7 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd,
 static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
 {
     static const int blksize = 32;
-    int blocks = DIV_ROUND_UP(surface_width(ssd->ds), blksize);
+    int blocks = (surface_width(ssd->ds) + blksize - 1) / blksize;
     int dirty_top[blocks];
     int y, yoff1, yoff2, x, xoff, blk, bw;
     int bpp = surface_bytes_per_pixel(ssd->ds);
@@ -527,13 +527,11 @@ static void interface_set_compression_level(QXLInstance *sin, int level)
     /* nothing to do */
 }
 
-#if SPICE_NEEDS_SET_MM_TIME
 static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
 {
     dprint(3, "%s/%d:\n", __func__, sin->id);
     /* nothing to do */
 }
-#endif
 
 static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
 {
@@ -688,7 +686,6 @@ static int interface_client_monitors_config(QXLInstance *sin,
 {
     SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
     QemuUIInfo info;
-    int head;
 
     if (!dpy_ui_info_supported(ssd->dcl.con)) {
         return 0; /* == not supported by guest */
@@ -698,12 +695,14 @@ static int interface_client_monitors_config(QXLInstance *sin,
         return 1;
     }
 
+    /*
+     * FIXME: multihead is tricky due to the way
+     * spice has multihead implemented.
+     */
     memset(&info, 0, sizeof(info));
-
-    head = qemu_console_get_head(ssd->dcl.con);
-    if (mc->num_of_monitors > head) {
-        info.width  = mc->monitors[head].width;
-        info.height = mc->monitors[head].height;
+    if (mc->num_of_monitors > 0) {
+        info.width  = mc->monitors[0].width;
+        info.height = mc->monitors[0].height;
     }
     dpy_set_ui_info(ssd->dcl.con, &info);
     dprint(1, "%s/%d: size %dx%d\n", __func__, ssd->qxl.id,
@@ -719,9 +718,7 @@ static const QXLInterface dpy_interface = {
 
     .attache_worker          = interface_attach_worker,
     .set_compression_level   = interface_set_compression_level,
-#if SPICE_NEEDS_SET_MM_TIME
     .set_mm_time             = interface_set_mm_time,
-#endif
     .get_init_info           = interface_get_init_info,
 
     /* the callbacks below are called from spice server thread context */
@@ -777,7 +774,9 @@ static void display_mouse_define(DisplayChangeListener *dcl,
     SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
 
     qemu_mutex_lock(&ssd->lock);
-    cursor_get(c);
+    if (c) {
+        cursor_get(c);
+    }
     cursor_put(ssd->cursor);
     ssd->cursor = c;
     ssd->hot_x = c->hot_x;
@@ -861,8 +860,6 @@ static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *dcl,
 static void qemu_spice_gl_scanout(DisplayChangeListener *dcl,
                                   uint32_t tex_id,
                                   bool y_0_top,
-                                  uint32_t backing_width,
-                                  uint32_t backing_height,
                                   uint32_t x, uint32_t y,
                                   uint32_t w, uint32_t h)
 {
@@ -885,7 +882,9 @@ static void qemu_spice_gl_scanout(DisplayChangeListener *dcl,
     assert(!tex_id || fd >= 0);
 
     /* note: spice server will close the fd */
-    spice_qxl_gl_scanout(&ssd->qxl, fd, backing_width, backing_height,
+    spice_qxl_gl_scanout(&ssd->qxl, fd,
+                         surface_width(ssd->ds),
+                         surface_height(ssd->ds),
                          stride, fourcc, y_0_top);
 
     qemu_spice_gl_monitor_config(ssd, x, y, w, h);
diff --git a/ui/trace-events b/ui/trace-events
deleted file mode 100644 (file)
index 93fe548..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# ui/console.c
-console_gfx_new(void) ""
-console_putchar_csi(int esc_param0, int esc_param1, int ch, int nb_esc_params) "escape sequence CSI%d;%d%c, %d parameters"
-console_putchar_unhandled(int ch) "unhandled escape character '%c'"
-console_txt_new(int w, int h) "%dx%d"
-console_select(int nr) "%d"
-console_refresh(int interval) "interval %d ms"
-displaysurface_create(void *display_surface, int w, int h) "surface=%p, %dx%d"
-displaysurface_create_from(void *display_surface, int w, int h, uint32_t format) "surface=%p, %dx%d, format 0x%x"
-displaysurface_create_pixman(void *display_surface) "surface=%p"
-displaysurface_free(void *display_surface) "surface=%p"
-displaychangelistener_register(void *dcl, const char *name) "%p [ %s ]"
-displaychangelistener_unregister(void *dcl, const char *name) "%p [ %s ]"
-ppm_save(const char *filename, void *display_surface) "%s surface=%p"
-
-# ui/gtk.c
-gd_switch(const char *tab, int width, int height) "tab=%s, width=%d, height=%d"
-gd_update(const char *tab, int x, int y, int w, int h) "tab=%s, x=%d, y=%d, w=%d, h=%d"
-gd_key_event(const char *tab, int gdk_keycode, int qemu_keycode, const char *action) "tab=%s, translated GDK keycode %d to QEMU keycode %d (%s)"
-gd_grab(const char *tab, const char *device, const char *reason) "tab=%s, dev=%s, reason=%s"
-gd_ungrab(const char *tab, const char *device) "tab=%s, dev=%s"
-
-# ui/vnc.c
-vnc_key_guest_leds(bool caps, bool num, bool scroll) "caps %d, num %d, scroll %d"
-vnc_key_map_init(const char *layout) "%s"
-vnc_key_event_ext(bool down, int sym, int keycode, const char *name) "down %d, sym 0x%x, keycode 0x%x [%s]"
-vnc_key_event_map(bool down, int sym, int keycode, const char *name) "down %d, sym 0x%x -> keycode 0x%x [%s]"
-vnc_key_sync_numlock(bool on) "%d"
-vnc_key_sync_capslock(bool on) "%d"
-
-# ui/input.c
-input_event_key_number(int conidx, int number, const char *qcode, bool down) "con %d, key number 0x%x [%s], down %d"
-input_event_key_qcode(int conidx, const char *qcode, bool down) "con %d, key qcode %s, down %d"
-input_event_btn(int conidx, const char *btn, bool down) "con %d, button %s, down %d"
-input_event_rel(int conidx, const char *axis, int value) "con %d, axis %s, value %d"
-input_event_abs(int conidx, const char *axis, int value) "con %d, axis %s, value 0x%x"
-input_event_sync(void) ""
-input_mouse_mode(int absolute) "absolute %d"
-
-# ui/spice-display.c
-qemu_spice_add_memslot(int qid, uint32_t slot_id, unsigned long virt_start, unsigned long virt_end, int async) "%d %u: host virt 0x%lx - 0x%lx async=%d"
-qemu_spice_del_memslot(int qid, uint32_t gid, uint32_t slot_id) "%d gid=%u sid=%u"
-qemu_spice_create_primary_surface(int qid, uint32_t sid, void *surface, int async) "%d sid=%u surface=%p async=%d"
-qemu_spice_destroy_primary_surface(int qid, uint32_t sid, int async) "%d sid=%u async=%d"
-qemu_spice_wakeup(uint32_t qid) "%d"
-qemu_spice_create_update(uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "lr %d -> %d,  tb -> %d -> %d"
index cb42745..3f59da6 100644 (file)
  * THE SOFTWARE.
  */
 
-#ifndef QEMU_VNC_AUTH_SASL_H
-#define QEMU_VNC_AUTH_SASL_H
+
+#ifndef __QEMU_VNC_AUTH_SASL_H__
+#define __QEMU_VNC_AUTH_SASL_H__
+
 
 #include <sasl/sasl.h>
 
@@ -69,4 +71,5 @@ long vnc_client_write_sasl(VncState *vs);
 
 void start_auth_sasl(VncState *vs);
 
-#endif /* QEMU_VNC_AUTH_SASL_H */
+#endif /* __QEMU_VNC_AUTH_SASL_H__ */
+
index 1e35406..9f674c5 100644 (file)
  * THE SOFTWARE.
  */
 
-#ifndef QEMU_VNC_AUTH_VENCRYPT_H
-#define QEMU_VNC_AUTH_VENCRYPT_H
+
+#ifndef __QEMU_VNC_AUTH_VENCRYPT_H__
+#define __QEMU_VNC_AUTH_VENCRYPT_H__
 
 void start_auth_vencrypt(VncState *vs);
 
-#endif /* QEMU_VNC_AUTH_VENCRYPT_H */
+#endif /* __QEMU_VNC_AUTH_VENCRYPT_H__ */
index 49df85e..e5cba0e 100644 (file)
@@ -349,7 +349,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h)
     tight_fill_palette##bpp(VncState *vs, int x, int y,                 \
                             int max, size_t count,                      \
                             uint32_t *bg, uint32_t *fg,                 \
-                            VncPalette *palette) {                      \
+                            VncPalette **palette) {                     \
         uint##bpp##_t *data;                                            \
         uint##bpp##_t c0, c1, ci;                                       \
         int i, n0, n1;                                                  \
@@ -396,23 +396,23 @@ tight_detect_smooth_image(VncState *vs, int w, int h)
             return 0;                                                   \
         }                                                               \
                                                                         \
-        palette_init(palette, max, bpp);                                \
-        palette_put(palette, c0);                                       \
-        palette_put(palette, c1);                                       \
-        palette_put(palette, ci);                                       \
+        *palette = palette_new(max, bpp);                               \
+        palette_put(*palette, c0);                                      \
+        palette_put(*palette, c1);                                      \
+        palette_put(*palette, ci);                                      \
                                                                         \
         for (i++; i < count; i++) {                                     \
             if (data[i] == ci) {                                        \
                 continue;                                               \
             } else {                                                    \
                 ci = data[i];                                           \
-                if (!palette_put(palette, (uint32_t)ci)) {              \
+                if (!palette_put(*palette, (uint32_t)ci)) {             \
                     return 0;                                           \
                 }                                                       \
             }                                                           \
         }                                                               \
                                                                         \
-        return palette_size(palette);                                   \
+        return palette_size(*palette);                                  \
     }
 
 DEFINE_FILL_PALETTE_FUNCTION(8)
@@ -421,7 +421,7 @@ DEFINE_FILL_PALETTE_FUNCTION(32)
 
 static int tight_fill_palette(VncState *vs, int x, int y,
                               size_t count, uint32_t *bg, uint32_t *fg,
-                              VncPalette *palette)
+                              VncPalette **palette)
 {
     int max;
 
@@ -461,10 +461,9 @@ static int tight_fill_palette(VncState *vs, int x, int y,
                                                                         \
         src = (uint##bpp##_t *) buf;                                    \
                                                                         \
-        for (i = 0; i < count; ) {                                      \
+        for (i = 0; i < count; i++) {                                   \
                                                                         \
             rgb = *src++;                                               \
-            i++;                                                        \
             rep = 0;                                                    \
             while (i < count && *src == rgb) {                          \
                 rep++, src++, i++;                                      \
@@ -1458,17 +1457,9 @@ static int send_sub_rect_jpeg(VncState *vs, int x, int y, int w, int h,
 }
 #endif
 
-static __thread VncPalette *color_count_palette;
-static __thread Notifier vnc_tight_cleanup_notifier;
-
-static void vnc_tight_cleanup(Notifier *n, void *value)
-{
-    g_free(color_count_palette);
-    color_count_palette = NULL;
-}
-
 static int send_sub_rect(VncState *vs, int x, int y, int w, int h)
 {
+    VncPalette *palette = NULL;
     uint32_t bg = 0, fg = 0;
     int colors;
     int ret = 0;
@@ -1477,12 +1468,6 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h)
     bool allow_jpeg = true;
 #endif
 
-    if (!color_count_palette) {
-        color_count_palette = g_malloc(sizeof(VncPalette));
-        vnc_tight_cleanup_notifier.notify = vnc_tight_cleanup;
-        qemu_thread_atexit_add(&vnc_tight_cleanup_notifier);
-    }
-
     vnc_framebuffer_update(vs, x, y, w, h, vs->tight.type);
 
     vnc_tight_start(vs);
@@ -1503,21 +1488,20 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h)
     }
 #endif
 
-    colors = tight_fill_palette(vs, x, y, w * h, &bg, &fg, color_count_palette);
+    colors = tight_fill_palette(vs, x, y, w * h, &bg, &fg, &palette);
 
 #ifdef CONFIG_VNC_JPEG
     if (allow_jpeg && vs->tight.quality != (uint8_t)-1) {
-        ret = send_sub_rect_jpeg(vs, x, y, w, h, bg, fg, colors,
-                                 color_count_palette, force_jpeg);
+        ret = send_sub_rect_jpeg(vs, x, y, w, h, bg, fg, colors, palette,
+                                 force_jpeg);
     } else {
-        ret = send_sub_rect_nojpeg(vs, x, y, w, h, bg, fg, colors,
-                                   color_count_palette);
+        ret = send_sub_rect_nojpeg(vs, x, y, w, h, bg, fg, colors, palette);
     }
 #else
-    ret = send_sub_rect_nojpeg(vs, x, y, w, h, bg, fg, colors,
-                               color_count_palette);
+    ret = send_sub_rect_nojpeg(vs, x, y, w, h, bg, fg, colors, palette);
 #endif
 
+    palette_destroy(palette);
     return ret;
 }
 
index 95c3dac..a3add78 100644 (file)
@@ -27,8 +27,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef VNC_ENC_TIGHT_H
-#define VNC_ENC_TIGHT_H
+#ifndef VNC_ENCODING_TIGHT_H
+#define VNC_ENCODING_TIGHT_H
 
 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  * Tight Encoding.
 #define VNC_TIGHT_DETECT_MIN_WIDTH           8
 #define VNC_TIGHT_DETECT_MIN_HEIGHT          8
 
-#endif /* VNC_ENC_TIGHT_H */
+#endif /* VNC_ENCODING_TIGHT_H */
index 6535cb2..6b18213 100644 (file)
@@ -26,8 +26,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef VNC_ENC_ZRLE_H
-#define VNC_ENC_ZRLE_H
+#ifndef VNC_ENCODING_ZRLE_H
+#define VNC_ENCODING_ZRLE_H
 
 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  * ZRLE - encoding combining Zlib compression, tiling, palettisation and
index 610bd79..d436d58 100644 (file)
@@ -41,8 +41,8 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  ********************************************************************/
 
-#ifndef VNC_ENC_ZYWRLE_H
-#define VNC_ENC_ZYWRLE_H
+#ifndef VNC_ENCODING_ZYWRLE_H
+#define VNC_ENCODING_ZYWRLE_H
 
 /* Tables for Coefficients filtering. */
 #ifndef ZYWRLE_QUANTIZE
index dc7c0ba..3b89d1a 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "qemu/osdep.h"
 #include "vnc-palette.h"
+#include <glib.h>
 
 static VncPaletteEntry *palette_find(const VncPalette *palette,
                                      uint32_t color, unsigned int hash)
index 3bac46e..7c79a4c 100644 (file)
@@ -22,7 +22,6 @@
 #include "qapi/error.h"
 #include "vnc.h"
 #include "io/channel-websock.h"
-#include "qemu/bswap.h"
 
 static void vncws_tls_handshake_done(Object *source,
                                      Error *err,
index 396cacf..652b6fc 100644 (file)
@@ -18,8 +18,8 @@
  * along with this software; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef QEMU_UI_VNC_WS_H
-#define QEMU_UI_VNC_WS_H
+#ifndef __QEMU_UI_VNC_WS_H
+#define __QEMU_UI_VNC_WS_H
 
 gboolean vncws_tls_handshake_io(QIOChannel *ioc,
                                 GIOCondition condition,
@@ -28,4 +28,4 @@ gboolean vncws_handshake_io(QIOChannel *ioc,
                             GIOCondition condition,
                             void *opaque);
 
-#endif /* QEMU_UI_VNC_WS_H */
+#endif /* __QEMU_UI_VNC_WS_H */
index d1087c9..3e89dad 100644 (file)
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -143,11 +143,6 @@ static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
 {
     SocketAddress *addr = NULL;
 
-    if (!ioc) {
-        error_setg(errp, "No listener socket available");
-        return;
-    }
-
     addr = qio_channel_socket_get_local_address(ioc, errp);
     if (!addr) {
         return;
@@ -224,7 +219,7 @@ static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
     VncServerInfo *info;
     Error *err = NULL;
 
-    info = g_malloc0(sizeof(*info));
+    info = g_malloc(sizeof(*info));
     vnc_init_basic_info_from_server_addr(vd->lsock,
                                          qapi_VncServerInfo_base(info), &err);
     info->has_auth = true;
@@ -692,8 +687,6 @@ void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
 
 static void vnc_update_server_surface(VncDisplay *vd)
 {
-    int width, height;
-
     qemu_pixman_image_unref(vd->server);
     vd->server = NULL;
 
@@ -701,15 +694,10 @@ static void vnc_update_server_surface(VncDisplay *vd)
         return;
     }
 
-    width = vnc_width(vd);
-    height = vnc_height(vd);
     vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
-                                          width, height,
+                                          vnc_width(vd),
+                                          vnc_height(vd),
                                           NULL, 0);
-
-    memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
-    vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
-                       width, height);
 }
 
 static void vnc_dpy_switch(DisplayChangeListener *dcl,
@@ -717,6 +705,7 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
 {
     VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
     VncState *vs;
+    int width, height;
 
     vnc_abort_display_jobs(vd);
     vd->ds = surface;
@@ -728,6 +717,11 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
     qemu_pixman_image_unref(vd->guest.fb);
     vd->guest.fb = pixman_image_ref(surface->image);
     vd->guest.format = surface->format;
+    width = vnc_width(vd);
+    height = vnc_height(vd);
+    memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
+    vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
+                       width, height);
 
     QTAILQ_FOREACH(vs, &vd->clients, next) {
         vnc_colordepth(vs);
@@ -737,8 +731,7 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
         }
         memset(vs->dirty, 0x00, sizeof(vs->dirty));
         vnc_set_area_dirty(vs->dirty, vd, 0, 0,
-                           vnc_width(vd),
-                           vnc_height(vd));
+                           width, height);
     }
 }
 
@@ -1031,13 +1024,8 @@ static int find_and_clear_dirty_height(VncState *vs,
 
 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
 {
-    if (vs->disconnecting) {
-        vnc_disconnect_finish(vs);
-        return 0;
-    }
-
     vs->has_dirty += has_dirty;
-    if (vs->need_update && !vs->disconnecting) {
+    if (vs->need_update && vs->ioc != NULL) {
         VncDisplay *vd = vs->vd;
         VncJob *job;
         int y;
@@ -1448,9 +1436,8 @@ static void vnc_jobs_bh(void *opaque)
  * First function called whenever there is more data to be read from
  * the client socket. Will delegate actual work according to whether
  * SASL SSF layers are enabled (thus requiring decryption calls)
- * Returns 0 on success, -1 if client disconnected
  */
-static int vnc_client_read(VncState *vs)
+static void vnc_client_read(VncState *vs)
 {
     ssize_t ret;
 
@@ -1463,9 +1450,8 @@ static int vnc_client_read(VncState *vs)
     if (!ret) {
         if (vs->disconnecting) {
             vnc_disconnect_finish(vs);
-            return -1;
         }
-        return 0;
+        return;
     }
 
     while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
@@ -1475,7 +1461,7 @@ static int vnc_client_read(VncState *vs)
         ret = vs->read_handler(vs, vs->input.buffer, len);
         if (vs->disconnecting) {
             vnc_disconnect_finish(vs);
-            return -1;
+            return;
         }
 
         if (!ret) {
@@ -1484,7 +1470,6 @@ static int vnc_client_read(VncState *vs)
             vs->read_handler_expect = ret;
         }
     }
-    return 0;
 }
 
 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
@@ -1492,9 +1477,7 @@ gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
 {
     VncState *vs = opaque;
     if (condition & G_IO_IN) {
-        if (vnc_client_read(vs) < 0) {
-            return TRUE;
-        }
+        vnc_client_read(vs);
     }
     if (condition & G_IO_OUT) {
         vnc_client_write(vs);
@@ -1646,7 +1629,6 @@ static void reset_keys(VncState *vs)
     for(i = 0; i < 256; i++) {
         if (vs->modifiers_state[i]) {
             qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
-            qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
             vs->modifiers_state[i] = 0;
         }
     }
@@ -1656,9 +1638,9 @@ static void press_key(VncState *vs, int keysym)
 {
     int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
     qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
-    qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
+    qemu_input_event_send_key_delay(0);
     qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
-    qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
+    qemu_input_event_send_key_delay(0);
 }
 
 static int current_led_state(VncState *vs)
@@ -1810,7 +1792,6 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
 
     if (qemu_console_is_graphic(NULL)) {
         qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
-        qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
     } else {
         bool numlock = vs->modifiers_state[0x45];
         bool control = (vs->modifiers_state[0x1d] ||
@@ -1932,7 +1913,6 @@ static void vnc_release_modifiers(VncState *vs)
             continue;
         }
         qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
-        qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
     }
 }
 
@@ -2114,38 +2094,15 @@ static void set_pixel_conversion(VncState *vs)
     }
 }
 
-static void send_color_map(VncState *vs)
-{
-    int i;
-
-    vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
-    vnc_write_u8(vs,  0);    /* padding     */
-    vnc_write_u16(vs, 0);    /* first color */
-    vnc_write_u16(vs, 256);  /* # of colors */
-
-    for (i = 0; i < 256; i++) {
-        PixelFormat *pf = &vs->client_pf;
-
-        vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
-        vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
-        vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
-    }
-}
-
-static void set_pixel_format(VncState *vs, int bits_per_pixel,
+static void set_pixel_format(VncState *vs,
+                             int bits_per_pixel, int depth,
                              int big_endian_flag, int true_color_flag,
                              int red_max, int green_max, int blue_max,
                              int red_shift, int green_shift, int blue_shift)
 {
     if (!true_color_flag) {
-        /* Expose a reasonable default 256 color map */
-        bits_per_pixel = 8;
-        red_max = 7;
-        green_max = 7;
-        blue_max = 3;
-        red_shift = 0;
-        green_shift = 3;
-        blue_shift = 6;
+        vnc_client_error(vs);
+        return;
     }
 
     switch (bits_per_pixel) {
@@ -2175,10 +2132,6 @@ static void set_pixel_format(VncState *vs, int bits_per_pixel,
     vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
     vs->client_be = big_endian_flag;
 
-    if (!true_color_flag) {
-        send_color_map(vs);
-    }
-
     set_pixel_conversion(vs);
 
     graphic_hw_invalidate(vs->vd->dcl.con);
@@ -2246,7 +2199,7 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
         if (len == 1)
             return 20;
 
-        set_pixel_format(vs, read_u8(data, 4),
+        set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
                          read_u8(data, 6), read_u8(data, 7),
                          read_u16(data, 8), read_u16(data, 10),
                          read_u16(data, 12), read_u8(data, 14),
@@ -3152,9 +3105,6 @@ void vnc_display_init(const char *id)
     if (!vs->kbd_layout)
         exit(1);
 
-    vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
-    vs->connections_limit = 32;
-
     qemu_mutex_init(&vs->mutex);
     vnc_start_worker_thread();
 
@@ -3203,7 +3153,7 @@ int vnc_display_password(const char *id, const char *password)
     }
     if (vs->auth == VNC_AUTH_NONE) {
         error_printf_unless_qmp("If you want use passwords please enable "
-                                "password auth using '-vnc ${dpy},password'.\n");
+                                "password auth using '-vnc ${dpy},password'.");
         return -EINVAL;
     }
 
@@ -3225,24 +3175,29 @@ int vnc_display_pw_expire(const char *id, time_t expires)
     return 0;
 }
 
-static void vnc_display_print_local_addr(VncDisplay *vs)
+char *vnc_display_local_addr(const char *id)
 {
+    VncDisplay *vs = vnc_display_find(id);
     SocketAddress *addr;
+    char *ret;
     Error *err = NULL;
 
+    assert(vs);
+
     addr = qio_channel_socket_get_local_address(vs->lsock, &err);
     if (!addr) {
-        return;
+        return NULL;
     }
 
     if (addr->type != SOCKET_ADDRESS_KIND_INET) {
         qapi_free_SocketAddress(addr);
-        return;
+        return NULL;
     }
-    error_printf_unless_qmp("VNC server running on %s:%s\n",
-                            addr->u.inet.data->host,
-                            addr->u.inet.data->port);
+    ret = g_strdup_printf("%s:%s", addr->u.inet.data->host,
+                          addr->u.inet.data->port);
     qapi_free_SocketAddress(addr);
+
+    return ret;
 }
 
 static QemuOptsList qemu_vnc_opts = {
@@ -3294,9 +3249,6 @@ static QemuOptsList qemu_vnc_opts = {
             .name = "lock-key-sync",
             .type = QEMU_OPT_BOOL,
         },{
-            .name = "key-delay-ms",
-            .type = QEMU_OPT_NUMBER,
-        },{
             .name = "sasl",
             .type = QEMU_OPT_BOOL,
         },{
@@ -3528,14 +3480,12 @@ void vnc_display_open(const char *id, Error **errp)
     const char *vnc;
     char *h;
     const char *credid;
-    int show_vnc_port = 0;
     bool sasl = false;
 #ifdef CONFIG_VNC_SASL
     int saslErr;
 #endif
     int acl = 0;
     int lock_key_sync = 1;
-    int key_delay_ms;
 
     if (!vs) {
         error_setg(errp, "VNC display not active");
@@ -3608,7 +3558,6 @@ void vnc_display_open(const char *id, Error **errp)
             if (to) {
                 inet->has_to = true;
                 inet->to = to + 5900;
-                show_vnc_port = 1;
             }
             inet->ipv4 = ipv4;
             inet->has_ipv4 = has_ipv4;
@@ -3655,7 +3604,6 @@ void vnc_display_open(const char *id, Error **errp)
 
     reverse = qemu_opt_get_bool(opts, "reverse", false);
     lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
-    key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 1);
     sasl = qemu_opt_get_bool(opts, "sasl", false);
 #ifndef CONFIG_VNC_SASL
     if (sasl) {
@@ -3787,7 +3735,6 @@ void vnc_display_open(const char *id, Error **errp)
     }
 #endif
     vs->lock_key_sync = lock_key_sync;
-    vs->key_delay_ms = key_delay_ms;
 
     device_id = qemu_opt_get(opts, "display");
     if (device_id) {
@@ -3853,10 +3800,6 @@ void vnc_display_open(const char *id, Error **errp)
         }
     }
 
-    if (show_vnc_port) {
-        vnc_display_print_local_addr(vs);
-    }
-
     qapi_free_SocketAddress(saddr);
     qapi_free_SocketAddress(wsaddr);
     return;
index ab5f244..81a3261 100644 (file)
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -24,8 +24,8 @@
  * THE SOFTWARE.
  */
 
-#ifndef QEMU_VNC_H
-#define QEMU_VNC_H
+#ifndef __QEMU_VNC_H
+#define __QEMU_VNC_H
 
 #include "qemu-common.h"
 #include "qemu/queue.h"
@@ -155,7 +155,6 @@ struct VncDisplay
     DisplayChangeListener dcl;
     kbd_layout_t *kbd_layout;
     int lock_key_sync;
-    int key_delay_ms;
     QemuMutex mutex;
 
     QEMUCursor *cursor;
@@ -577,4 +576,4 @@ int vnc_zrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
 int vnc_zywrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
 void vnc_zrle_clear(VncState *vs);
 
-#endif /* QEMU_VNC_H */
+#endif /* __QEMU_VNC_H */
index 95f9f97..d8d597b 100644 (file)
@@ -19,7 +19,6 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "disas/disas.h"
-#include "exec/exec-all.h"
 #include "tcg.h"
 #include "qemu/bitops.h"
 #include "exec/cpu_ldst.h"
 
 //#define DEBUG_SIGNAL
 
+static void exception_action(CPUState *cpu)
+{
+#if defined(TARGET_I386)
+    X86CPU *x86_cpu = X86_CPU(cpu);
+    CPUX86State *env1 = &x86_cpu->env;
+
+    raise_exception_err(env1, cpu->exception_index, env1->error_code);
+#else
+    cpu_loop_exit(cpu);
+#endif
+}
+
 /* exit the current TB from a signal handler. The host registers are
    restored in a state compatible with the CPU emulator
  */
-static void cpu_exit_tb_from_sighandler(CPUState *cpu, sigset_t *old_set)
+void cpu_resume_from_signal(CPUState *cpu, void *puc)
 {
-    /* XXX: use siglongjmp ? */
-    sigprocmask(SIG_SETMASK, old_set, NULL);
-    cpu_loop_exit_noexc(cpu);
+#ifdef __linux__
+    struct ucontext *uc = puc;
+#elif defined(__OpenBSD__)
+    struct sigcontext *uc = puc;
+#endif
+
+    if (puc) {
+        /* XXX: use siglongjmp ? */
+#ifdef __linux__
+#ifdef __ia64
+        sigprocmask(SIG_SETMASK, (sigset_t *)&uc->uc_sigmask, NULL);
+#else
+        sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
+#endif
+#elif defined(__OpenBSD__)
+        sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
+#endif
+    }
+    cpu->exception_index = -1;
+    siglongjmp(cpu->jmp_env, 1);
 }
 
 /* 'pc' is the host PC at which the exception was raised. 'address' is
@@ -55,7 +83,8 @@ static void cpu_exit_tb_from_sighandler(CPUState *cpu, sigset_t *old_set)
    write caused the exception and otherwise 0'. 'old_set' is the
    signal set which should be restored */
 static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
-                                    int is_write, sigset_t *old_set)
+                                    int is_write, sigset_t *old_set,
+                                    void *puc)
 {
     CPUState *cpu;
     CPUClass *cc;
@@ -66,28 +95,9 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
            pc, address, is_write, *(unsigned long *)old_set);
 #endif
     /* XXX: locking issue */
-    if (is_write && h2g_valid(address)) {
-        switch (page_unprotect(h2g(address), pc)) {
-        case 0:
-            /* Fault not caused by a page marked unwritable to protect
-             * cached translations, must be the guest binary's problem
-             */
-            break;
-        case 1:
-            /* Fault caused by protection of cached translation; TBs
-             * invalidated, so resume execution
-             */
-            return 1;
-        case 2:
-            /* Fault caused by protection of cached translation, and the
-             * currently executing TB was modified and must be exited
-             * immediately.
-             */
-            cpu_exit_tb_from_sighandler(current_cpu, old_set);
-            g_assert_not_reached();
-        default:
-            g_assert_not_reached();
-        }
+    if (is_write && h2g_valid(address)
+        && page_unprotect(h2g(address), pc, puc)) {
+        return 1;
     }
 
     /* Convert forcefully to guest address space, invalid addresses
@@ -108,8 +118,10 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
     /* now we have a real cpu fault */
     cpu_restore_state(cpu, pc);
 
+    /* we restore the process signal mask as the sigreturn should
+       do it (XXX: use sigsetjmp) */
     sigprocmask(SIG_SETMASK, old_set, NULL);
-    cpu_loop_exit(cpu);
+    exception_action(cpu);
 
     /* never comes here */
     return 1;
@@ -117,7 +129,14 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
 
 #if defined(__i386__)
 
-#if defined(__NetBSD__)
+#if defined(__APPLE__)
+#include <sys/ucontext.h>
+
+#define EIP_sig(context)  (*((unsigned long *)&(context)->uc_mcontext->ss.eip))
+#define TRAP_sig(context)    ((context)->uc_mcontext->es.trapno)
+#define ERROR_sig(context)   ((context)->uc_mcontext->es.err)
+#define MASK_sig(context)    ((context)->uc_sigmask)
+#elif defined(__NetBSD__)
 #include <ucontext.h>
 
 #define EIP_sig(context)     ((context)->uc_mcontext.__gregs[_REG_EIP])
@@ -168,7 +187,7 @@ int cpu_signal_handler(int host_signum, void *pinfo,
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                              trapno == 0xe ?
                              (ERROR_sig(uc) >> 1) & 1 : 0,
-                             &MASK_sig(uc));
+                             &MASK_sig(uc), puc);
 }
 
 #elif defined(__x86_64__)
@@ -214,7 +233,7 @@ int cpu_signal_handler(int host_signum, void *pinfo,
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                              TRAP_sig(uc) == 0xe ?
                              (ERROR_sig(uc) >> 1) & 1 : 0,
-                             &MASK_sig(uc));
+                             &MASK_sig(uc), puc);
 }
 
 #elif defined(_ARCH_PPC)
@@ -267,6 +286,44 @@ int cpu_signal_handler(int host_signum, void *pinfo,
 #define TRAP_sig(context)              ((context)->uc_mcontext.mc_exc)
 #endif /* __FreeBSD__|| __FreeBSD_kernel__ */
 
+#ifdef __APPLE__
+#include <sys/ucontext.h>
+typedef struct ucontext SIGCONTEXT;
+/* All Registers access - only for local access */
+#define REG_sig(reg_name, context)              \
+    ((context)->uc_mcontext->ss.reg_name)
+#define FLOATREG_sig(reg_name, context)         \
+    ((context)->uc_mcontext->fs.reg_name)
+#define EXCEPREG_sig(reg_name, context)         \
+    ((context)->uc_mcontext->es.reg_name)
+#define VECREG_sig(reg_name, context)           \
+    ((context)->uc_mcontext->vs.reg_name)
+/* Gpr Registers access */
+#define GPR_sig(reg_num, context)              REG_sig(r##reg_num, context)
+/* Program counter */
+#define IAR_sig(context)                       REG_sig(srr0, context)
+/* Machine State Register (Supervisor) */
+#define MSR_sig(context)                       REG_sig(srr1, context)
+#define CTR_sig(context)                       REG_sig(ctr, context)
+/* Link register */
+#define XER_sig(context)                       REG_sig(xer, context)
+/* User's integer exception register */
+#define LR_sig(context)                        REG_sig(lr, context)
+/* Condition register */
+#define CR_sig(context)                        REG_sig(cr, context)
+/* Float Registers access */
+#define FLOAT_sig(reg_num, context)             \
+    FLOATREG_sig(fpregs[reg_num], context)
+#define FPSCR_sig(context)                      \
+    ((double)FLOATREG_sig(fpscr, context))
+/* Exception Registers access */
+/* Fault registers for coredump */
+#define DAR_sig(context)                       EXCEPREG_sig(dar, context)
+#define DSISR_sig(context)                     EXCEPREG_sig(dsisr, context)
+/* number of powerpc exception taken */
+#define TRAP_sig(context)                      EXCEPREG_sig(exception, context)
+#endif /* __APPLE__ */
+
 int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)
 {
@@ -292,7 +349,7 @@ int cpu_signal_handler(int host_signum, void *pinfo,
     }
 #endif
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write, &uc->uc_sigmask);
+                             is_write, &uc->uc_sigmask, puc);
 }
 
 #elif defined(__alpha__)
@@ -323,7 +380,7 @@ int cpu_signal_handler(int host_signum, void *pinfo,
     }
 
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write, &uc->uc_sigmask);
+                             is_write, &uc->uc_sigmask, puc);
 }
 #elif defined(__sparc__)
 
@@ -383,7 +440,7 @@ int cpu_signal_handler(int host_signum, void *pinfo,
         }
     }
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write, sigmask);
+                             is_write, sigmask, NULL);
 }
 
 #elif defined(__arm__)
@@ -418,7 +475,7 @@ int cpu_signal_handler(int host_signum, void *pinfo,
     is_write = extract32(uc->uc_mcontext.error_code, 11, 1);
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                              is_write,
-                             &uc->uc_sigmask);
+                             &uc->uc_sigmask, puc);
 }
 
 #elif defined(__aarch64__)
@@ -446,7 +503,25 @@ int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
                 || (insn & 0x3a400000) == 0x28000000); /* C3.3.7,14-16 */
 
     return handle_cpu_signal(pc, (uintptr_t)info->si_addr,
-                             is_write, &uc->uc_sigmask);
+                             is_write, &uc->uc_sigmask, puc);
+}
+
+#elif defined(__mc68000)
+
+int cpu_signal_handler(int host_signum, void *pinfo,
+                       void *puc)
+{
+    siginfo_t *info = pinfo;
+    struct ucontext *uc = puc;
+    unsigned long pc;
+    int is_write;
+
+    pc = uc->uc_mcontext.gregs[16];
+    /* XXX: compute is_write */
+    is_write = 0;
+    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+                             is_write,
+                             &uc->uc_sigmask, puc);
 }
 
 #elif defined(__ia64)
@@ -481,7 +556,7 @@ int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
     }
     return handle_cpu_signal(ip, (unsigned long)info->si_addr,
                              is_write,
-                             (sigset_t *)&uc->uc_sigmask);
+                             (sigset_t *)&uc->uc_sigmask, puc);
 }
 
 #elif defined(__s390__)
@@ -534,7 +609,7 @@ int cpu_signal_handler(int host_signum, void *pinfo,
         break;
     }
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write, &uc->uc_sigmask);
+                             is_write, &uc->uc_sigmask, puc);
 }
 
 #elif defined(__mips__)
@@ -550,7 +625,49 @@ int cpu_signal_handler(int host_signum, void *pinfo,
     /* XXX: compute is_write */
     is_write = 0;
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write, &uc->uc_sigmask);
+                             is_write, &uc->uc_sigmask, puc);
+}
+
+#elif defined(__hppa__)
+
+int cpu_signal_handler(int host_signum, void *pinfo,
+                       void *puc)
+{
+    siginfo_t *info = pinfo;
+    struct ucontext *uc = puc;
+    unsigned long pc = uc->uc_mcontext.sc_iaoq[0];
+    uint32_t insn = *(uint32_t *)pc;
+    int is_write = 0;
+
+    /* XXX: need kernel patch to get write flag faster.  */
+    switch (insn >> 26) {
+    case 0x1a: /* STW */
+    case 0x19: /* STH */
+    case 0x18: /* STB */
+    case 0x1b: /* STWM */
+        is_write = 1;
+        break;
+
+    case 0x09: /* CSTWX, FSTWX, FSTWS */
+    case 0x0b: /* CSTDX, FSTDX, FSTDS */
+        /* Distinguish from coprocessor load ... */
+        is_write = (insn >> 9) & 1;
+        break;
+
+    case 0x03:
+        switch ((insn >> 6) & 15) {
+        case 0xa: /* STWS */
+        case 0x9: /* STHS */
+        case 0x8: /* STBS */
+        case 0xe: /* STWAS */
+        case 0xc: /* STBYS */
+            is_write = 1;
+        }
+        break;
+    }
+
+    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+                             is_write, &uc->uc_sigmask, puc);
 }
 
 #else
index 96cb1e0..a8a777e 100644 (file)
@@ -32,6 +32,3 @@ util-obj-y += buffer.o
 util-obj-y += timed-average.o
 util-obj-y += base64.o
 util-obj-y += log.o
-util-obj-y += qdist.o
-util-obj-y += qht.o
-util-obj-y += range.o
index c105add..723b6a8 100644 (file)
@@ -177,3 +177,12 @@ int qemu_acl_remove(qemu_acl *acl,
     }
     return -1;
 }
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 8
+ * End:
+ */
index d8bb874..a6118bf 100644 (file)
  */
 
 #include "qemu/osdep.h"
-#include "qemu/host-utils.h"
 #include "qemu/buffer.h"
 #include "trace.h"
 
 #define BUFFER_MIN_INIT_SIZE     4096
 #define BUFFER_MIN_SHRINK_SIZE  65536
 
-/* define the factor alpha for the exponential smoothing
+/* define the factor alpha for the expentional smoothing
  * that is used in the average size calculation. a shift
  * of 7 results in an alpha of 1/2^7. */
 #define BUFFER_AVG_SIZE_SHIFT       7
@@ -46,7 +45,7 @@ static void buffer_adj_size(Buffer *buffer, size_t len)
                         old, buffer->capacity);
 
     /* make it even harder for the buffer to shrink, reset average size
-     * to current capacity if it is larger than the average. */
+     * to currenty capacity if it is larger than the average. */
     buffer->avg_size = MAX(buffer->avg_size,
                            buffer->capacity << BUFFER_AVG_SIZE_SHIFT);
 }
index 62bfb40..fb697eb 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu-common.h"
 #include "qemu/coroutine_int.h"
 
index 7505fda..43d1afb 100644 (file)
@@ -184,13 +184,6 @@ int qemu_fdatasync(int fd)
 #define SPLAT(p)       _mm_set1_epi8(*(p))
 #define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0xFFFF)
 #define VEC_OR(v1, v2) (_mm_or_si128(v1, v2))
-#elif defined(__aarch64__)
-#include "arm_neon.h"
-#define VECTYPE        uint64x2_t
-#define ALL_EQ(v1, v2) \
-        ((vgetq_lane_u64(v1, 0) == vgetq_lane_u64(v2, 0)) && \
-         (vgetq_lane_u64(v1, 1) == vgetq_lane_u64(v2, 1)))
-#define VEC_OR(v1, v2) ((v1) | (v2))
 #else
 #define VECTYPE        unsigned long
 #define SPLAT(p)       (*(p) * (~0UL / 255))
@@ -263,7 +256,13 @@ static size_t buffer_find_nonzero_offset_inner(const void *buf, size_t len)
     return i * sizeof(VECTYPE);
 }
 
-#if defined CONFIG_AVX2_OPT
+/*
+ * GCC before version 4.9 has a bug which will cause the target
+ * attribute work incorrectly and failed to compile in some case,
+ * restrict the gcc version to 4.9+ to prevent the failure.
+ */
+
+#if defined CONFIG_AVX2_OPT && QEMU_GNUC_PREREQ(4, 9)
 #pragma GCC push_options
 #pragma GCC target("avx2")
 #include <cpuid.h>
index 9c40b1f..cae2511 100644 (file)
@@ -217,7 +217,7 @@ ErrorClass error_get_class(const Error *err)
     return err->err_class;
 }
 
-const char *error_get_pretty(const Error *err)
+const char *error_get_pretty(Error *err)
 {
     return err->msg;
 }
index 99fd2ba..b22b87d 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 #include "qemu/hbitmap.h"
 #include "qemu/host-utils.h"
 #include "trace.h"
@@ -269,7 +270,6 @@ void hbitmap_set(HBitmap *hb, uint64_t start, uint64_t count)
     start >>= hb->granularity;
     last >>= hb->granularity;
     count = last - start + 1;
-    assert(last < hb->size);
 
     hb->count += count - hb_count_between(hb, start, last);
     hb_set_between(hb, HBITMAP_LEVELS - 1, start, last);
@@ -349,7 +349,6 @@ void hbitmap_reset(HBitmap *hb, uint64_t start, uint64_t count)
 
     start >>= hb->granularity;
     last >>= hb->granularity;
-    assert(last < hb->size);
 
     hb->count -= hb_count_between(hb, start, last);
     hb_reset_between(hb, HBITMAP_LEVELS - 1, start, last);
@@ -373,7 +372,6 @@ bool hbitmap_get(const HBitmap *hb, uint64_t item)
     /* Compute position and bit in the last layer.  */
     uint64_t pos = item >> hb->granularity;
     unsigned long bit = 1UL << (pos & (BITS_PER_LONG - 1));
-    assert(pos < hb->size);
 
     return (hb->levels[HBITMAP_LEVELS - 1][pos >> BITS_PER_LEVEL] & bit) != 0;
 }
index 74e6ca8..003fcce 100644 (file)
@@ -247,8 +247,7 @@ unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
 {
     size_t len;
     unsigned int i, j;
-    for (i = 0, j = 0;
-         i < iov_cnt && j < dst_iov_cnt && (offset || bytes); i++) {
+    for (i = 0, j = 0; i < iov_cnt && j < dst_iov_cnt && bytes; i++) {
         if (offset >= iov[i].iov_len) {
             offset -= iov[i].iov_len;
             continue;
index 54b54e8..1857730 100644 (file)
@@ -22,7 +22,6 @@
 #include "qemu/log.h"
 #include "qemu/range.h"
 #include "qemu/error-report.h"
-#include "qapi/error.h"
 #include "qemu/cutils.h"
 #include "trace/control.h"
 
@@ -32,28 +31,19 @@ int qemu_loglevel;
 static int log_append = 0;
 static GArray *debug_regions;
 
-/* Return the number of characters emitted.  */
-int qemu_log(const char *fmt, ...)
+void qemu_log(const char *fmt, ...)
 {
-    int ret = 0;
-    if (qemu_logfile) {
-        va_list ap;
-        va_start(ap, fmt);
-        ret = vfprintf(qemu_logfile, fmt, ap);
-        va_end(ap);
+    va_list ap;
 
-        /* Don't pass back error results.  */
-        if (ret < 0) {
-            ret = 0;
-        }
+    va_start(ap, fmt);
+    if (qemu_logfile) {
+        vfprintf(qemu_logfile, fmt, ap);
     }
-    return ret;
+    va_end(ap);
 }
 
-static bool log_uses_own_buffers;
-
 /* enable or disable low levels log */
-void qemu_set_log(int log_flags)
+void do_qemu_set_log(int log_flags, bool use_own_buffers)
 {
     qemu_loglevel = log_flags;
 #ifdef CONFIG_TRACE_LOG
@@ -80,7 +70,7 @@ void qemu_set_log(int log_flags)
             qemu_logfile = stderr;
         }
         /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
-        if (log_uses_own_buffers) {
+        if (use_own_buffers) {
             static char logfile_buf[4096];
 
             setvbuf(qemu_logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
@@ -99,18 +89,12 @@ void qemu_set_log(int log_flags)
         qemu_log_close();
     }
 }
-
-void qemu_log_needs_buffers(void)
-{
-    log_uses_own_buffers = true;
-}
-
 /*
  * Allow the user to include %d in their logfile which will be
  * substituted with the current PID. This is useful for debugging many
  * nested linux-user tasks but will result in lots of logs.
  */
-void qemu_set_log_filename(const char *filename, Error **errp)
+void qemu_set_log_filename(const char *filename)
 {
     char *pidstr;
     g_free(logfilename);
@@ -119,8 +103,8 @@ void qemu_set_log_filename(const char *filename, Error **errp)
     if (pidstr) {
         /* We only accept one %d, no other format strings */
         if (pidstr[1] != 'd' || strchr(pidstr + 2, '%')) {
-            error_setg(errp, "Bad logfile format: %s", filename);
-            return;
+            error_report("Bad logfile format: %s", filename);
+            logfilename = NULL;
         } else {
             logfilename = g_strdup_printf(filename, getpid());
         }
@@ -138,8 +122,8 @@ bool qemu_log_in_addr_range(uint64_t addr)
     if (debug_regions) {
         int i = 0;
         for (i = 0; i < debug_regions->len; i++) {
-            Range *range = &g_array_index(debug_regions, Range, i);
-            if (range_contains(range, addr)) {
+            struct Range *range = &g_array_index(debug_regions, Range, i);
+            if (addr >= range->begin && addr <= range->end) {
                 return true;
             }
         }
@@ -150,76 +134,68 @@ bool qemu_log_in_addr_range(uint64_t addr)
 }
 
 
-void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
+void qemu_set_dfilter_ranges(const char *filter_spec)
 {
     gchar **ranges = g_strsplit(filter_spec, ",", 0);
-    int i;
-
-    if (debug_regions) {
-        g_array_unref(debug_regions);
-        debug_regions = NULL;
-    }
+    if (ranges) {
+        gchar **next = ranges;
+        gchar *r = *next++;
+        debug_regions = g_array_sized_new(FALSE, FALSE,
+                                          sizeof(Range), g_strv_length(ranges));
+        while (r) {
+            char *range_op = strstr(r, "-");
+            char *r2 = range_op ? range_op + 1 : NULL;
+            if (!range_op) {
+                range_op = strstr(r, "+");
+                r2 = range_op ? range_op + 1 : NULL;
+            }
+            if (!range_op) {
+                range_op = strstr(r, "..");
+                r2 = range_op ? range_op + 2 : NULL;
+            }
+            if (range_op) {
+                const char *e = NULL;
+                uint64_t r1val, r2val;
 
-    debug_regions = g_array_sized_new(FALSE, FALSE,
-                                      sizeof(Range), g_strv_length(ranges));
-    for (i = 0; ranges[i]; i++) {
-        const char *r = ranges[i];
-        const char *range_op, *r2, *e;
-        uint64_t r1val, r2val, lob, upb;
-        struct Range range;
+                if ((qemu_strtoull(r, &e, 0, &r1val) == 0) &&
+                    (qemu_strtoull(r2, NULL, 0, &r2val) == 0) &&
+                    r2val > 0) {
+                    struct Range range;
 
-        range_op = strstr(r, "-");
-        r2 = range_op ? range_op + 1 : NULL;
-        if (!range_op) {
-            range_op = strstr(r, "+");
-            r2 = range_op ? range_op + 1 : NULL;
-        }
-        if (!range_op) {
-            range_op = strstr(r, "..");
-            r2 = range_op ? range_op + 2 : NULL;
-        }
-        if (!range_op) {
-            error_setg(errp, "Bad range specifier");
-            goto out;
-        }
+                    g_assert(e == range_op);
 
-        if (qemu_strtoull(r, &e, 0, &r1val)
-            || e != range_op) {
-            error_setg(errp, "Invalid number to the left of %.*s",
-                       (int)(r2 - range_op), range_op);
-            goto out;
-        }
-        if (qemu_strtoull(r2, NULL, 0, &r2val)) {
-            error_setg(errp, "Invalid number to the right of %.*s",
-                       (int)(r2 - range_op), range_op);
-            goto out;
-        }
+                    switch (*range_op) {
+                    case '+':
+                    {
+                        range.begin = r1val;
+                        range.end = r1val + (r2val - 1);
+                        break;
+                    }
+                    case '-':
+                    {
+                        range.end = r1val;
+                        range.begin = r1val - (r2val - 1);
+                        break;
+                    }
+                    case '.':
+                        range.begin = r1val;
+                        range.end = r2val;
+                        break;
+                    default:
+                        g_assert_not_reached();
+                    }
+                    g_array_append_val(debug_regions, range);
 
-        switch (*range_op) {
-        case '+':
-            lob = r1val;
-            upb = r1val + r2val - 1;
-            break;
-        case '-':
-            upb = r1val;
-            lob = r1val - (r2val - 1);
-            break;
-        case '.':
-            lob = r1val;
-            upb = r2val;
-            break;
-        default:
-            g_assert_not_reached();
-        }
-        if (lob > upb) {
-            error_setg(errp, "Invalid range");
-            goto out;
+                } else {
+                    g_error("Failed to parse range in: %s", r);
+                }
+            } else {
+                g_error("Bad range specifier in: %s", r);
+            }
+            r = *next++;
         }
-        range_set_bounds(&range, lob, upb);
-        g_array_append_val(debug_regions, range);
+        g_strfreev(ranges);
     }
-out:
-    g_strfreev(ranges);
 }
 
 /* fflush() the log file */
@@ -247,9 +223,8 @@ const QEMULogItem qemu_log_items[] = {
     { CPU_LOG_TB_OP, "op",
       "show micro ops for each compiled TB" },
     { CPU_LOG_TB_OP_OPT, "op_opt",
-      "show micro ops after optimization" },
-    { CPU_LOG_TB_OP_IND, "op_ind",
-      "show micro ops before indirect lowering" },
+      "show micro ops (x86 only: before eflags optimization) and\n"
+      "after liveness analysis" },
     { CPU_LOG_INT, "int",
       "show interrupts/exceptions in short format" },
     { CPU_LOG_EXEC, "exec",
index 4571d1a..7c40691 100644 (file)
 
 #include "qemu/osdep.h"
 
+#include <glib.h>
 #include <glib/gprintf.h>
 
+#include <sys/mman.h>
+
 #include "qemu/memfd.h"
 
 #ifdef CONFIG_MEMFD
index 5a85aa3..0b4cc7f 100644 (file)
@@ -9,9 +9,9 @@
  * This work is licensed under the terms of the GNU GPL, version 2 or
  * later.  See the COPYING file in the top-level directory.
  */
-
 #include "qemu/osdep.h"
-#include "qemu/mmap-alloc.h"
+#include <qemu/mmap-alloc.h>
+#include <sys/mman.h>
 
 #define HUGETLBFS_MAGIC       0x958458f6
 
index 86e3f7a..ce058ae 100644 (file)
@@ -55,9 +55,13 @@ static void init_lists(void)
 
 static ModuleTypeList *find_type(module_init_type type)
 {
+    ModuleTypeList *l;
+
     init_lists();
 
-    return &init_type_list[type];
+    l = &init_type_list[type];
+
+    return l;
 }
 
 void register_module_init(void (*fn)(void), module_init_type type)
index 06fb1cf..d56d071 100644 (file)
 
 /* Needed early for CONFIG_BSD etc. */
 
+#if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE)
+#include <sys/mman.h>
+#endif
+
 #ifdef CONFIG_SOLARIS
 #include <sys/statvfs.h>
 /* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
@@ -40,7 +44,14 @@ extern int madvise(caddr_t, size_t, int);
 
 static bool fips_enabled = false;
 
-static const char *hw_version = QEMU_HW_VERSION;
+/* Starting on QEMU 2.5, qemu_hw_version() returns "2.5+" by default
+ * instead of QEMU_VERSION, so setting hw_version on MachineClass
+ * is no longer mandatory.
+ *
+ * Do NOT change this string, or it will break compatibility on all
+ * machine classes that don't set hw_version.
+ */
+static const char *hw_version = "2.5+";
 
 int socket_set_cork(int fd, int v)
 {
@@ -83,7 +94,14 @@ static int qemu_dup_flags(int fd, int flags)
     int serrno;
     int dup_flags;
 
-    ret = qemu_dup(fd);
+#ifdef F_DUPFD_CLOEXEC
+    ret = fcntl(fd, F_DUPFD_CLOEXEC, 0);
+#else
+    ret = dup(fd);
+    if (ret != -1) {
+        qemu_set_cloexec(ret);
+    }
+#endif
     if (ret == -1) {
         goto fail;
     }
@@ -122,20 +140,6 @@ fail:
     return -1;
 }
 
-int qemu_dup(int fd)
-{
-    int ret;
-#ifdef F_DUPFD_CLOEXEC
-    ret = fcntl(fd, F_DUPFD_CLOEXEC, 0);
-#else
-    ret = dup(fd);
-    if (ret != -1) {
-        qemu_set_cloexec(ret);
-    }
-#endif
-    return ret;
-}
-
 static int qemu_parse_fdset(const char *param)
 {
     return qemu_parse_fd(param);
index f2d4e9e..4adde93 100644 (file)
@@ -36,6 +36,7 @@
 #include "trace.h"
 #include "qapi/error.h"
 #include "qemu/sockets.h"
+#include <sys/mman.h>
 #include <libgen.h>
 #include <sys/signal.h>
 #include "qemu/cutils.h"
@@ -48,7 +49,7 @@
 #include <sys/sysctl.h>
 #endif
 
-#include "qemu/mmap-alloc.h"
+#include <qemu/mmap-alloc.h>
 
 int qemu_get_thread_id(void)
 {
@@ -299,11 +300,9 @@ void qemu_init_exec_dir(const char *argv0)
             return;
         }
     }
-    dir = g_path_get_dirname(p);
+    dir = dirname(p);
 
     pstrcpy(exec_dir, sizeof(exec_dir), dir);
-
-    g_free(dir);
 }
 
 char *qemu_get_exec_dir(void)
@@ -318,7 +317,7 @@ static void sigbus_handler(int signal)
     siglongjmp(sigjump, 1);
 }
 
-void os_mem_prealloc(int fd, char *area, size_t memory, Error **errp)
+void os_mem_prealloc(int fd, char *area, size_t memory)
 {
     int ret;
     struct sigaction act, oldact;
@@ -330,9 +329,8 @@ void os_mem_prealloc(int fd, char *area, size_t memory, Error **errp)
 
     ret = sigaction(SIGBUS, &act, &oldact);
     if (ret) {
-        error_setg_errno(errp, errno,
-            "os_mem_prealloc: failed to install signal handler");
-        return;
+        perror("os_mem_prealloc: failed to install signal handler");
+        exit(1);
     }
 
     /* unblock SIGBUS */
@@ -341,8 +339,9 @@ void os_mem_prealloc(int fd, char *area, size_t memory, Error **errp)
     pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
 
     if (sigsetjmp(sigjump, 1)) {
-        error_setg(errp, "os_mem_prealloc: Insufficient free host memory "
-            "pages available to allocate guest RAM\n");
+        fprintf(stderr, "os_mem_prealloc: Insufficient free host memory "
+                        "pages available to allocate guest RAM\n");
+        exit(1);
     } else {
         int i;
         size_t hpagesize = qemu_fd_getpagesize(fd);
@@ -352,15 +351,15 @@ void os_mem_prealloc(int fd, char *area, size_t memory, Error **errp)
         for (i = 0; i < numpages; i++) {
             memset(area + (hpagesize * i), 0, 1);
         }
-    }
 
-    ret = sigaction(SIGBUS, &oldact, NULL);
-    if (ret) {
-        /* Terminate QEMU since it can't recover from error */
-        perror("os_mem_prealloc: failed to reinstall signal handler");
-        exit(1);
+        ret = sigaction(SIGBUS, &oldact, NULL);
+        if (ret) {
+            perror("os_mem_prealloc: failed to reinstall signal handler");
+            exit(1);
+        }
+
+        pthread_sigmask(SIG_SETMASK, &oldset, NULL);
     }
-    pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 }
 
 
index 4c1dcf1..c926db4 100644 (file)
@@ -31,6 +31,7 @@
  */
 #include "qemu/osdep.h"
 #include <windows.h>
+#include <glib.h>
 #include "qapi/error.h"
 #include "sysemu/sysemu.h"
 #include "qemu/main-loop.h"
@@ -539,7 +540,7 @@ int getpagesize(void)
     return system_info.dwPageSize;
 }
 
-void os_mem_prealloc(int fd, char *area, size_t memory, Error **errp)
+void os_mem_prealloc(int fd, char *area, size_t memory)
 {
     int i;
     size_t pagesize = getpagesize();
diff --git a/util/qdist.c b/util/qdist.c
deleted file mode 100644 (file)
index 5f75e24..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * qdist.c - QEMU helpers for handling frequency distributions of data.
- *
- * Copyright (C) 2016, Emilio G. Cota <cota@braap.org>
- *
- * License: GNU GPL, version 2 or later.
- *   See the COPYING file in the top-level directory.
- */
-#include "qemu/osdep.h"
-#include "qemu/qdist.h"
-
-#include <math.h>
-#ifndef NAN
-#define NAN (0.0 / 0.0)
-#endif
-
-#define QDIST_EMPTY_STR "(empty)"
-
-void qdist_init(struct qdist *dist)
-{
-    dist->entries = g_new(struct qdist_entry, 1);
-    dist->size = 1;
-    dist->n = 0;
-}
-
-void qdist_destroy(struct qdist *dist)
-{
-    g_free(dist->entries);
-}
-
-static inline int qdist_cmp_double(double a, double b)
-{
-    if (a > b) {
-        return 1;
-    } else if (a < b) {
-        return -1;
-    }
-    return 0;
-}
-
-static int qdist_cmp(const void *ap, const void *bp)
-{
-    const struct qdist_entry *a = ap;
-    const struct qdist_entry *b = bp;
-
-    return qdist_cmp_double(a->x, b->x);
-}
-
-void qdist_add(struct qdist *dist, double x, long count)
-{
-    struct qdist_entry *entry = NULL;
-
-    if (dist->n) {
-        struct qdist_entry e;
-
-        e.x = x;
-        entry = bsearch(&e, dist->entries, dist->n, sizeof(e), qdist_cmp);
-    }
-
-    if (entry) {
-        entry->count += count;
-        return;
-    }
-
-    if (unlikely(dist->n == dist->size)) {
-        dist->size *= 2;
-        dist->entries = g_renew(struct qdist_entry, dist->entries, dist->size);
-    }
-    dist->n++;
-    entry = &dist->entries[dist->n - 1];
-    entry->x = x;
-    entry->count = count;
-    qsort(dist->entries, dist->n, sizeof(*entry), qdist_cmp);
-}
-
-void qdist_inc(struct qdist *dist, double x)
-{
-    qdist_add(dist, x, 1);
-}
-
-/*
- * Unicode for block elements. See:
- *   https://en.wikipedia.org/wiki/Block_Elements
- */
-static const gunichar qdist_blocks[] = {
-    0x2581,
-    0x2582,
-    0x2583,
-    0x2584,
-    0x2585,
-    0x2586,
-    0x2587,
-    0x2588
-};
-
-#define QDIST_NR_BLOCK_CODES ARRAY_SIZE(qdist_blocks)
-
-/*
- * Print a distribution into a string.
- *
- * This function assumes that appropriate binning has been done on the input;
- * see qdist_bin__internal() and qdist_pr_plain().
- *
- * Callers must free the returned string with g_free().
- */
-static char *qdist_pr_internal(const struct qdist *dist)
-{
-    double min, max;
-    GString *s = g_string_new("");
-    size_t i;
-
-    /* if only one entry, its printout will be either full or empty */
-    if (dist->n == 1) {
-        if (dist->entries[0].count) {
-            g_string_append_unichar(s, qdist_blocks[QDIST_NR_BLOCK_CODES - 1]);
-        } else {
-            g_string_append_c(s, ' ');
-        }
-        goto out;
-    }
-
-    /* get min and max counts */
-    min = dist->entries[0].count;
-    max = min;
-    for (i = 0; i < dist->n; i++) {
-        struct qdist_entry *e = &dist->entries[i];
-
-        if (e->count < min) {
-            min = e->count;
-        }
-        if (e->count > max) {
-            max = e->count;
-        }
-    }
-
-    for (i = 0; i < dist->n; i++) {
-        struct qdist_entry *e = &dist->entries[i];
-        int index;
-
-        /* make an exception with 0; instead of using block[0], print a space */
-        if (e->count) {
-            /* divide first to avoid loss of precision when e->count == max */
-            index = (e->count - min) / (max - min) * (QDIST_NR_BLOCK_CODES - 1);
-            g_string_append_unichar(s, qdist_blocks[index]);
-        } else {
-            g_string_append_c(s, ' ');
-        }
-    }
- out:
-    return g_string_free(s, FALSE);
-}
-
-/*
- * Bin the distribution in @from into @n bins of consecutive, non-overlapping
- * intervals, copying the result to @to.
- *
- * This function is internal to qdist: only this file and test code should
- * ever call it.
- *
- * Note: calling this function on an already-binned qdist is a bug.
- *
- * If @n == 0 or @from->n == 1, use @from->n.
- */
-void qdist_bin__internal(struct qdist *to, const struct qdist *from, size_t n)
-{
-    double xmin, xmax;
-    double step;
-    size_t i, j;
-
-    qdist_init(to);
-
-    if (from->n == 0) {
-        return;
-    }
-    if (n == 0 || from->n == 1) {
-        n = from->n;
-    }
-
-    /* set equally-sized bins between @from's left and right */
-    xmin = qdist_xmin(from);
-    xmax = qdist_xmax(from);
-    step = (xmax - xmin) / n;
-
-    if (n == from->n) {
-        /* if @from's entries are equally spaced, no need to re-bin */
-        for (i = 0; i < from->n; i++) {
-            if (from->entries[i].x != xmin + i * step) {
-                goto rebin;
-            }
-        }
-        /* they're equally spaced, so copy the dist and bail out */
-        to->entries = g_renew(struct qdist_entry, to->entries, n);
-        to->n = from->n;
-        memcpy(to->entries, from->entries, sizeof(*to->entries) * to->n);
-        return;
-    }
-
- rebin:
-    j = 0;
-    for (i = 0; i < n; i++) {
-        double x;
-        double left, right;
-
-        left = xmin + i * step;
-        right = xmin + (i + 1) * step;
-
-        /* Add x, even if it might not get any counts later */
-        x = left;
-        qdist_add(to, x, 0);
-
-        /*
-         * To avoid double-counting we capture [left, right) ranges, except for
-         * the righmost bin, which captures a [left, right] range.
-         */
-        while (j < from->n && (from->entries[j].x < right || i == n - 1)) {
-            struct qdist_entry *o = &from->entries[j];
-
-            qdist_add(to, x, o->count);
-            j++;
-        }
-    }
-}
-
-/*
- * Print @dist into a string, after re-binning it into @n bins of consecutive,
- * non-overlapping intervals.
- *
- * If @n == 0, use @orig->n.
- *
- * Callers must free the returned string with g_free().
- */
-char *qdist_pr_plain(const struct qdist *dist, size_t n)
-{
-    struct qdist binned;
-    char *ret;
-
-    if (dist->n == 0) {
-        return g_strdup(QDIST_EMPTY_STR);
-    }
-    qdist_bin__internal(&binned, dist, n);
-    ret = qdist_pr_internal(&binned);
-    qdist_destroy(&binned);
-    return ret;
-}
-
-static char *qdist_pr_label(const struct qdist *dist, size_t n_bins,
-                            uint32_t opt, bool is_left)
-{
-    const char *percent;
-    const char *lparen;
-    const char *rparen;
-    GString *s;
-    double x1, x2, step;
-    double x;
-    double n;
-    int dec;
-
-    s = g_string_new("");
-    if (!(opt & QDIST_PR_LABELS)) {
-        goto out;
-    }
-
-    dec = opt & QDIST_PR_NODECIMAL ? 0 : 1;
-    percent = opt & QDIST_PR_PERCENT ? "%" : "";
-
-    n = n_bins ? n_bins : dist->n;
-    x = is_left ? qdist_xmin(dist) : qdist_xmax(dist);
-    step = (qdist_xmax(dist) - qdist_xmin(dist)) / n;
-
-    if (opt & QDIST_PR_100X) {
-        x *= 100.0;
-        step *= 100.0;
-    }
-    if (opt & QDIST_PR_NOBINRANGE) {
-        lparen = rparen = "";
-        x1 = x;
-        x2 = x; /* unnecessary, but a dumb compiler might not figure it out */
-    } else {
-        lparen = "[";
-        rparen = is_left ? ")" : "]";
-        if (is_left) {
-            x1 = x;
-            x2 = x + step;
-        } else {
-            x1 = x - step;
-            x2 = x;
-        }
-    }
-    g_string_append_printf(s, "%s%.*f", lparen, dec, x1);
-    if (!(opt & QDIST_PR_NOBINRANGE)) {
-        g_string_append_printf(s, ",%.*f%s", dec, x2, rparen);
-    }
-    g_string_append(s, percent);
- out:
-    return g_string_free(s, FALSE);
-}
-
-/*
- * Print the distribution's histogram into a string.
- *
- * See also: qdist_pr_plain().
- *
- * Callers must free the returned string with g_free().
- */
-char *qdist_pr(const struct qdist *dist, size_t n_bins, uint32_t opt)
-{
-    const char *border = opt & QDIST_PR_BORDER ? "|" : "";
-    char *llabel, *rlabel;
-    char *hgram;
-    GString *s;
-
-    if (dist->n == 0) {
-        return g_strdup(QDIST_EMPTY_STR);
-    }
-
-    s = g_string_new("");
-
-    llabel = qdist_pr_label(dist, n_bins, opt, true);
-    rlabel = qdist_pr_label(dist, n_bins, opt, false);
-    hgram = qdist_pr_plain(dist, n_bins);
-    g_string_append_printf(s, "%s%s%s%s%s",
-                           llabel, border, hgram, border, rlabel);
-    g_free(llabel);
-    g_free(rlabel);
-    g_free(hgram);
-
-    return g_string_free(s, FALSE);
-}
-
-static inline double qdist_x(const struct qdist *dist, int index)
-{
-    if (dist->n == 0) {
-        return NAN;
-    }
-    return dist->entries[index].x;
-}
-
-double qdist_xmin(const struct qdist *dist)
-{
-    return qdist_x(dist, 0);
-}
-
-double qdist_xmax(const struct qdist *dist)
-{
-    return qdist_x(dist, dist->n - 1);
-}
-
-size_t qdist_unique_entries(const struct qdist *dist)
-{
-    return dist->n;
-}
-
-unsigned long qdist_sample_count(const struct qdist *dist)
-{
-    unsigned long count = 0;
-    size_t i;
-
-    for (i = 0; i < dist->n; i++) {
-        struct qdist_entry *e = &dist->entries[i];
-
-        count += e->count;
-    }
-    return count;
-}
-
-static double qdist_pairwise_avg(const struct qdist *dist, size_t index,
-                                 size_t n, unsigned long count)
-{
-    /* amortize the recursion by using a base case > 2 */
-    if (n <= 8) {
-        size_t i;
-        double ret = 0;
-
-        for (i = 0; i < n; i++) {
-            struct qdist_entry *e = &dist->entries[index + i];
-
-            ret += e->x * e->count / count;
-        }
-        return ret;
-    } else {
-        size_t n2 = n / 2;
-
-        return qdist_pairwise_avg(dist, index, n2, count) +
-               qdist_pairwise_avg(dist, index + n2, n - n2, count);
-    }
-}
-
-double qdist_avg(const struct qdist *dist)
-{
-    unsigned long count;
-
-    count = qdist_sample_count(dist);
-    if (!count) {
-        return NAN;
-    }
-    return qdist_pairwise_avg(dist, 0, dist->n, count);
-}
index 44a8969..91b9357 100644 (file)
@@ -75,7 +75,7 @@ static void fd_coroutine_enter(void *opaque)
 {
     FDYieldUntilData *data = opaque;
     qemu_set_fd_handler(data->fd, NULL, NULL, NULL);
-    qemu_coroutine_enter(data->co);
+    qemu_coroutine_enter(data->co, NULL);
 }
 
 void coroutine_fn yield_until_fd_readable(int fd)
index 22aa9ab..da37ca7 100644 (file)
 
 void qemu_co_queue_init(CoQueue *queue)
 {
-    QSIMPLEQ_INIT(&queue->entries);
+    QTAILQ_INIT(&queue->entries);
 }
 
 void coroutine_fn qemu_co_queue_wait(CoQueue *queue)
 {
     Coroutine *self = qemu_coroutine_self();
-    QSIMPLEQ_INSERT_TAIL(&queue->entries, self, co_queue_next);
+    QTAILQ_INSERT_TAIL(&queue->entries, self, co_queue_next);
     qemu_coroutine_yield();
     assert(qemu_in_coroutine());
 }
@@ -55,9 +55,9 @@ void qemu_co_queue_run_restart(Coroutine *co)
     Coroutine *next;
 
     trace_qemu_co_queue_run_restart(co);
-    while ((next = QSIMPLEQ_FIRST(&co->co_queue_wakeup))) {
-        QSIMPLEQ_REMOVE_HEAD(&co->co_queue_wakeup, co_queue_next);
-        qemu_coroutine_enter(next);
+    while ((next = QTAILQ_FIRST(&co->co_queue_wakeup))) {
+        QTAILQ_REMOVE(&co->co_queue_wakeup, next, co_queue_next);
+        qemu_coroutine_enter(next, NULL);
     }
 }
 
@@ -66,13 +66,13 @@ static bool qemu_co_queue_do_restart(CoQueue *queue, bool single)
     Coroutine *self = qemu_coroutine_self();
     Coroutine *next;
 
-    if (QSIMPLEQ_EMPTY(&queue->entries)) {
+    if (QTAILQ_EMPTY(&queue->entries)) {
         return false;
     }
 
-    while ((next = QSIMPLEQ_FIRST(&queue->entries)) != NULL) {
-        QSIMPLEQ_REMOVE_HEAD(&queue->entries, co_queue_next);
-        QSIMPLEQ_INSERT_TAIL(&self->co_queue_wakeup, next, co_queue_next);
+    while ((next = QTAILQ_FIRST(&queue->entries)) != NULL) {
+        QTAILQ_REMOVE(&queue->entries, next, co_queue_next);
+        QTAILQ_INSERT_TAIL(&self->co_queue_wakeup, next, co_queue_next);
         trace_qemu_co_queue_next(next);
         if (single) {
             break;
@@ -97,19 +97,19 @@ bool qemu_co_enter_next(CoQueue *queue)
 {
     Coroutine *next;
 
-    next = QSIMPLEQ_FIRST(&queue->entries);
+    next = QTAILQ_FIRST(&queue->entries);
     if (!next) {
         return false;
     }
 
-    QSIMPLEQ_REMOVE_HEAD(&queue->entries, co_queue_next);
-    qemu_coroutine_enter(next);
+    QTAILQ_REMOVE(&queue->entries, next, co_queue_next);
+    qemu_coroutine_enter(next, NULL);
     return true;
 }
 
 bool qemu_co_queue_empty(CoQueue *queue)
 {
-    return QSIMPLEQ_FIRST(&queue->entries) == NULL;
+    return QTAILQ_FIRST(&queue->entries) == NULL;
 }
 
 void qemu_co_mutex_init(CoMutex *mutex)
index 25de3ed..6966831 100644 (file)
@@ -25,7 +25,7 @@ static void co_sleep_cb(void *opaque)
 {
     CoSleepCB *sleep_cb = opaque;
 
-    qemu_coroutine_enter(sleep_cb->co);
+    qemu_coroutine_enter(sleep_cb->co, NULL);
 }
 
 void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type,
index 89f21a9..5816702 100644 (file)
@@ -42,7 +42,7 @@ static void coroutine_pool_cleanup(Notifier *n, void *value)
     }
 }
 
-Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque)
+Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
 {
     Coroutine *co = NULL;
 
@@ -76,8 +76,7 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque)
     }
 
     co->entry = entry;
-    co->entry_arg = opaque;
-    QSIMPLEQ_INIT(&co->co_queue_wakeup);
+    QTAILQ_INIT(&co->co_queue_wakeup);
     return co;
 }
 
@@ -101,12 +100,12 @@ static void coroutine_delete(Coroutine *co)
     qemu_coroutine_delete(co);
 }
 
-void qemu_coroutine_enter(Coroutine *co)
+void qemu_coroutine_enter(Coroutine *co, void *opaque)
 {
     Coroutine *self = qemu_coroutine_self();
     CoroutineAction ret;
 
-    trace_qemu_coroutine_enter(self, co, co->entry_arg);
+    trace_qemu_coroutine_enter(self, co, opaque);
 
     if (co->caller) {
         fprintf(stderr, "Co-routine re-entered recursively\n");
@@ -114,6 +113,7 @@ void qemu_coroutine_enter(Coroutine *co)
     }
 
     co->caller = self;
+    co->entry_arg = opaque;
     ret = qemu_coroutine_switch(self, co, COROUTINE_ENTER);
 
     qemu_co_queue_run_restart(co);
index 2aed799..0d53691 100644 (file)
@@ -93,7 +93,7 @@ NetworkAddressFamily inet_netfamily(int family)
  *   t     f       PF_INET
  *   t     t       PF_INET6
  *
- * NB, this matrix is only about getting the necessary results
+ * NB, this matrix is only about getting the neccessary results
  * from getaddrinfo(). Some of the cases require further work
  * after reading results from getaddrinfo in order to fully
  * apply the logic the end user wants. eg with the last case
@@ -624,6 +624,34 @@ fail:
     return NULL;
 }
 
+int inet_listen(const char *str, char *ostr, int olen,
+                int socktype, int port_offset, Error **errp)
+{
+    char *optstr;
+    int sock = -1;
+    InetSocketAddress *addr;
+
+    addr = inet_parse(str, errp);
+    if (addr != NULL) {
+        sock = inet_listen_saddr(addr, port_offset, true, errp);
+        if (sock != -1 && ostr) {
+            optstr = strchr(str, ',');
+            if (addr->ipv6) {
+                snprintf(ostr, olen, "[%s]:%s%s",
+                         addr->host,
+                         addr->port,
+                         optstr ? optstr : "");
+            } else {
+                snprintf(ostr, olen, "%s:%s%s",
+                         addr->host,
+                         addr->port,
+                         optstr ? optstr : "");
+            }
+        }
+        qapi_free_InetSocketAddress(addr);
+    }
+    return sock;
+}
 
 /**
  * Create a blocking socket and connect it to an address.
@@ -646,6 +674,36 @@ int inet_connect(const char *str, Error **errp)
     return sock;
 }
 
+/**
+ * Create a non-blocking socket and connect it to an address.
+ * Calls the callback function with fd in case of success or -1 in case of
+ * error.
+ *
+ * @str: address string
+ * @callback: callback function that is called when connect completes,
+ *            cannot be NULL.
+ * @opaque: opaque for callback function
+ * @errp: set in case of an error
+ *
+ * Returns: -1 on immediate error, file descriptor on success.
+ **/
+int inet_nonblocking_connect(const char *str,
+                             NonBlockingConnectHandler *callback,
+                             void *opaque, Error **errp)
+{
+    int sock = -1;
+    InetSocketAddress *addr;
+
+    g_assert(callback != NULL);
+
+    addr = inet_parse(str, errp);
+    if (addr != NULL) {
+        sock = inet_connect_saddr(addr, errp, callback, opaque);
+        qapi_free_InetSocketAddress(addr);
+    }
+    return sock;
+}
+
 #ifndef _WIN32
 
 static int unix_listen_saddr(UnixSocketAddress *saddr,
@@ -835,6 +893,22 @@ int unix_connect(const char *path, Error **errp)
 }
 
 
+int unix_nonblocking_connect(const char *path,
+                             NonBlockingConnectHandler *callback,
+                             void *opaque, Error **errp)
+{
+    UnixSocketAddress *saddr;
+    int sock = -1;
+
+    g_assert(callback != NULL);
+
+    saddr = g_new0(UnixSocketAddress, 1);
+    saddr->path = g_strdup(path);
+    sock = unix_connect_saddr(saddr, errp, callback, opaque);
+    qapi_free_UnixSocketAddress(saddr);
+    return sock;
+}
+
 SocketAddress *socket_parse(const char *str, Error **errp)
 {
     SocketAddress *addr;
@@ -923,24 +997,6 @@ int socket_listen(SocketAddress *addr, Error **errp)
     return fd;
 }
 
-void socket_listen_cleanup(int fd, Error **errp)
-{
-    SocketAddress *addr;
-
-    addr = socket_local_address(fd, errp);
-
-    if (addr->type == SOCKET_ADDRESS_KIND_UNIX
-        && addr->u.q_unix.data->path) {
-        if (unlink(addr->u.q_unix.data->path) < 0 && errno != ENOENT) {
-            error_setg_errno(errp, errno,
-                             "Failed to unlink socket %s",
-                             addr->u.q_unix.data->path);
-        }
-    }
-
-    qapi_free_SocketAddress(addr);
-}
-
 int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
 {
     int fd;
@@ -1069,38 +1125,29 @@ SocketAddress *socket_remote_address(int fd, Error **errp)
     return socket_sockaddr_to_address(&ss, sslen, errp);
 }
 
-char *socket_address_to_string(struct SocketAddress *addr, Error **errp)
-{
-    char *buf;
-    InetSocketAddress *inet;
-    char host_port[INET6_ADDRSTRLEN + 5 + 4];
-
-    switch (addr->type) {
-    case SOCKET_ADDRESS_KIND_INET:
-        inet = addr->u.inet.data;
-        if (strchr(inet->host, ':') == NULL) {
-            snprintf(host_port, sizeof(host_port), "%s:%s", inet->host,
-                    inet->port);
-            buf = g_strdup(host_port);
-        } else {
-            snprintf(host_port, sizeof(host_port), "[%s]:%s", inet->host,
-                    inet->port);
-            buf = g_strdup(host_port);
-        }
-        break;
-
-    case SOCKET_ADDRESS_KIND_UNIX:
-        buf = g_strdup(addr->u.q_unix.data->path);
-        break;
-
-    case SOCKET_ADDRESS_KIND_FD:
-        buf = g_strdup(addr->u.fd.data->str);
-        break;
 
-    default:
-        error_setg(errp, "socket family %d unsupported",
-                   addr->type);
-        return NULL;
-    }
-    return buf;
+void qapi_copy_SocketAddress(SocketAddress **p_dest,
+                             SocketAddress *src)
+{
+    QmpOutputVisitor *qov;
+    QmpInputVisitor *qiv;
+    Visitor *ov, *iv;
+    QObject *obj;
+
+    *p_dest = NULL;
+
+    qov = qmp_output_visitor_new();
+    ov = qmp_output_get_visitor(qov);
+    visit_type_SocketAddress(ov, NULL, &src, &error_abort);
+    obj = qmp_output_get_qobject(qov);
+    qmp_output_visitor_cleanup(qov);
+    if (!obj) {
+        return;
+    }
+
+    qiv = qmp_input_visitor_new(obj);
+    iv = qmp_input_get_visitor(qiv);
+    visit_type_SocketAddress(iv, NULL, p_dest, &error_abort);
+    qmp_input_visitor_cleanup(qiv);
+    qobject_decref(obj);
 }
diff --git a/util/qht.c b/util/qht.c
deleted file mode 100644 (file)
index 16a8d79..0000000
+++ /dev/null
@@ -1,844 +0,0 @@
-/*
- * qht.c - QEMU Hash Table, designed to scale for read-mostly workloads.
- *
- * Copyright (C) 2016, Emilio G. Cota <cota@braap.org>
- *
- * License: GNU GPL, version 2 or later.
- *   See the COPYING file in the top-level directory.
- *
- * Assumptions:
- * - NULL cannot be inserted/removed as a pointer value.
- * - Trying to insert an already-existing hash-pointer pair is OK. However,
- *   it is not OK to insert into the same hash table different hash-pointer
- *   pairs that have the same pointer value, but not the hashes.
- * - Lookups are performed under an RCU read-critical section; removals
- *   must wait for a grace period to elapse before freeing removed objects.
- *
- * Features:
- * - Reads (i.e. lookups and iterators) can be concurrent with other reads.
- *   Lookups that are concurrent with writes to the same bucket will retry
- *   via a seqlock; iterators acquire all bucket locks and therefore can be
- *   concurrent with lookups and are serialized wrt writers.
- * - Writes (i.e. insertions/removals) can be concurrent with writes to
- *   different buckets; writes to the same bucket are serialized through a lock.
- * - Optional auto-resizing: the hash table resizes up if the load surpasses
- *   a certain threshold. Resizing is done concurrently with readers; writes
- *   are serialized with the resize operation.
- *
- * The key structure is the bucket, which is cacheline-sized. Buckets
- * contain a few hash values and pointers; the u32 hash values are stored in
- * full so that resizing is fast. Having this structure instead of directly
- * chaining items has two advantages:
- * - Failed lookups fail fast, and touch a minimum number of cache lines.
- * - Resizing the hash table with concurrent lookups is easy.
- *
- * There are two types of buckets:
- * 1. "head" buckets are the ones allocated in the array of buckets in qht_map.
- * 2. all "non-head" buckets (i.e. all others) are members of a chain that
- *    starts from a head bucket.
- * Note that the seqlock and spinlock of a head bucket applies to all buckets
- * chained to it; these two fields are unused in non-head buckets.
- *
- * On removals, we move the last valid item in the chain to the position of the
- * just-removed entry. This makes lookups slightly faster, since the moment an
- * invalid entry is found, the (failed) lookup is over.
- *
- * Resizing is done by taking all bucket spinlocks (so that no other writers can
- * race with us) and then copying all entries into a new hash map. Then, the
- * ht->map pointer is set, and the old map is freed once no RCU readers can see
- * it anymore.
- *
- * Writers check for concurrent resizes by comparing ht->map before and after
- * acquiring their bucket lock. If they don't match, a resize has occured
- * while the bucket spinlock was being acquired.
- *
- * Related Work:
- * - Idea of cacheline-sized buckets with full hashes taken from:
- *   David, Guerraoui & Trigonakis, "Asynchronized Concurrency:
- *   The Secret to Scaling Concurrent Search Data Structures", ASPLOS'15.
- * - Why not RCU-based hash tables? They would allow us to get rid of the
- *   seqlock, but resizing would take forever since RCU read critical
- *   sections in QEMU take quite a long time.
- *   More info on relativistic hash tables:
- *   + Triplett, McKenney & Walpole, "Resizable, Scalable, Concurrent Hash
- *     Tables via Relativistic Programming", USENIX ATC'11.
- *   + Corbet, "Relativistic hash tables, part 1: Algorithms", @ lwn.net, 2014.
- *     https://lwn.net/Articles/612021/
- */
-#include "qemu/osdep.h"
-#include "qemu/qht.h"
-#include "qemu/atomic.h"
-#include "qemu/rcu.h"
-
-//#define QHT_DEBUG
-
-/*
- * We want to avoid false sharing of cache lines. Most systems have 64-byte
- * cache lines so we go with it for simplicity.
- *
- * Note that systems with smaller cache lines will be fine (the struct is
- * almost 64-bytes); systems with larger cache lines might suffer from
- * some false sharing.
- */
-#define QHT_BUCKET_ALIGN 64
-
-/* define these to keep sizeof(qht_bucket) within QHT_BUCKET_ALIGN */
-#if HOST_LONG_BITS == 32
-#define QHT_BUCKET_ENTRIES 6
-#else /* 64-bit */
-#define QHT_BUCKET_ENTRIES 4
-#endif
-
-/*
- * Note: reading partially-updated pointers in @pointers could lead to
- * segfaults. We thus access them with atomic_read/set; this guarantees
- * that the compiler makes all those accesses atomic. We also need the
- * volatile-like behavior in atomic_read, since otherwise the compiler
- * might refetch the pointer.
- * atomic_read's are of course not necessary when the bucket lock is held.
- *
- * If both ht->lock and b->lock are grabbed, ht->lock should always
- * be grabbed first.
- */
-struct qht_bucket {
-    QemuSpin lock;
-    QemuSeqLock sequence;
-    uint32_t hashes[QHT_BUCKET_ENTRIES];
-    void *pointers[QHT_BUCKET_ENTRIES];
-    struct qht_bucket *next;
-} QEMU_ALIGNED(QHT_BUCKET_ALIGN);
-
-QEMU_BUILD_BUG_ON(sizeof(struct qht_bucket) > QHT_BUCKET_ALIGN);
-
-/**
- * struct qht_map - structure to track an array of buckets
- * @rcu: used by RCU. Keep it as the top field in the struct to help valgrind
- *       find the whole struct.
- * @buckets: array of head buckets. It is constant once the map is created.
- * @n_buckets: number of head buckets. It is constant once the map is created.
- * @n_added_buckets: number of added (i.e. "non-head") buckets
- * @n_added_buckets_threshold: threshold to trigger an upward resize once the
- *                             number of added buckets surpasses it.
- *
- * Buckets are tracked in what we call a "map", i.e. this structure.
- */
-struct qht_map {
-    struct rcu_head rcu;
-    struct qht_bucket *buckets;
-    size_t n_buckets;
-    size_t n_added_buckets;
-    size_t n_added_buckets_threshold;
-};
-
-/* trigger a resize when n_added_buckets > n_buckets / div */
-#define QHT_NR_ADDED_BUCKETS_THRESHOLD_DIV 8
-
-static void qht_do_resize(struct qht *ht, struct qht_map *new);
-static void qht_grow_maybe(struct qht *ht);
-
-#ifdef QHT_DEBUG
-
-#define qht_debug_assert(X) do { assert(X); } while (0)
-
-static void qht_bucket_debug__locked(struct qht_bucket *b)
-{
-    bool seen_empty = false;
-    bool corrupt = false;
-    int i;
-
-    do {
-        for (i = 0; i < QHT_BUCKET_ENTRIES; i++) {
-            if (b->pointers[i] == NULL) {
-                seen_empty = true;
-                continue;
-            }
-            if (seen_empty) {
-                fprintf(stderr, "%s: b: %p, pos: %i, hash: 0x%x, p: %p\n",
-                        __func__, b, i, b->hashes[i], b->pointers[i]);
-                corrupt = true;
-            }
-        }
-        b = b->next;
-    } while (b);
-    qht_debug_assert(!corrupt);
-}
-
-static void qht_map_debug__all_locked(struct qht_map *map)
-{
-    int i;
-
-    for (i = 0; i < map->n_buckets; i++) {
-        qht_bucket_debug__locked(&map->buckets[i]);
-    }
-}
-#else
-
-#define qht_debug_assert(X) do { (void)(X); } while (0)
-
-static inline void qht_bucket_debug__locked(struct qht_bucket *b)
-{ }
-
-static inline void qht_map_debug__all_locked(struct qht_map *map)
-{ }
-#endif /* QHT_DEBUG */
-
-static inline size_t qht_elems_to_buckets(size_t n_elems)
-{
-    return pow2ceil(n_elems / QHT_BUCKET_ENTRIES);
-}
-
-static inline void qht_head_init(struct qht_bucket *b)
-{
-    memset(b, 0, sizeof(*b));
-    qemu_spin_init(&b->lock);
-    seqlock_init(&b->sequence);
-}
-
-static inline
-struct qht_bucket *qht_map_to_bucket(struct qht_map *map, uint32_t hash)
-{
-    return &map->buckets[hash & (map->n_buckets - 1)];
-}
-
-/* acquire all bucket locks from a map */
-static void qht_map_lock_buckets(struct qht_map *map)
-{
-    size_t i;
-
-    for (i = 0; i < map->n_buckets; i++) {
-        struct qht_bucket *b = &map->buckets[i];
-
-        qemu_spin_lock(&b->lock);
-    }
-}
-
-static void qht_map_unlock_buckets(struct qht_map *map)
-{
-    size_t i;
-
-    for (i = 0; i < map->n_buckets; i++) {
-        struct qht_bucket *b = &map->buckets[i];
-
-        qemu_spin_unlock(&b->lock);
-    }
-}
-
-/*
- * Call with at least a bucket lock held.
- * @map should be the value read before acquiring the lock (or locks).
- */
-static inline bool qht_map_is_stale__locked(struct qht *ht, struct qht_map *map)
-{
-    return map != ht->map;
-}
-
-/*
- * Grab all bucket locks, and set @pmap after making sure the map isn't stale.
- *
- * Pairs with qht_map_unlock_buckets(), hence the pass-by-reference.
- *
- * Note: callers cannot have ht->lock held.
- */
-static inline
-void qht_map_lock_buckets__no_stale(struct qht *ht, struct qht_map **pmap)
-{
-    struct qht_map *map;
-
-    map = atomic_rcu_read(&ht->map);
-    qht_map_lock_buckets(map);
-    if (likely(!qht_map_is_stale__locked(ht, map))) {
-        *pmap = map;
-        return;
-    }
-    qht_map_unlock_buckets(map);
-
-    /* we raced with a resize; acquire ht->lock to see the updated ht->map */
-    qemu_mutex_lock(&ht->lock);
-    map = ht->map;
-    qht_map_lock_buckets(map);
-    qemu_mutex_unlock(&ht->lock);
-    *pmap = map;
-    return;
-}
-
-/*
- * Get a head bucket and lock it, making sure its parent map is not stale.
- * @pmap is filled with a pointer to the bucket's parent map.
- *
- * Unlock with qemu_spin_unlock(&b->lock).
- *
- * Note: callers cannot have ht->lock held.
- */
-static inline
-struct qht_bucket *qht_bucket_lock__no_stale(struct qht *ht, uint32_t hash,
-                                             struct qht_map **pmap)
-{
-    struct qht_bucket *b;
-    struct qht_map *map;
-
-    map = atomic_rcu_read(&ht->map);
-    b = qht_map_to_bucket(map, hash);
-
-    qemu_spin_lock(&b->lock);
-    if (likely(!qht_map_is_stale__locked(ht, map))) {
-        *pmap = map;
-        return b;
-    }
-    qemu_spin_unlock(&b->lock);
-
-    /* we raced with a resize; acquire ht->lock to see the updated ht->map */
-    qemu_mutex_lock(&ht->lock);
-    map = ht->map;
-    b = qht_map_to_bucket(map, hash);
-    qemu_spin_lock(&b->lock);
-    qemu_mutex_unlock(&ht->lock);
-    *pmap = map;
-    return b;
-}
-
-static inline bool qht_map_needs_resize(struct qht_map *map)
-{
-    return atomic_read(&map->n_added_buckets) > map->n_added_buckets_threshold;
-}
-
-static inline void qht_chain_destroy(struct qht_bucket *head)
-{
-    struct qht_bucket *curr = head->next;
-    struct qht_bucket *prev;
-
-    while (curr) {
-        prev = curr;
-        curr = curr->next;
-        qemu_vfree(prev);
-    }
-}
-
-/* pass only an orphan map */
-static void qht_map_destroy(struct qht_map *map)
-{
-    size_t i;
-
-    for (i = 0; i < map->n_buckets; i++) {
-        qht_chain_destroy(&map->buckets[i]);
-    }
-    qemu_vfree(map->buckets);
-    g_free(map);
-}
-
-static struct qht_map *qht_map_create(size_t n_buckets)
-{
-    struct qht_map *map;
-    size_t i;
-
-    map = g_malloc(sizeof(*map));
-    map->n_buckets = n_buckets;
-
-    map->n_added_buckets = 0;
-    map->n_added_buckets_threshold = n_buckets /
-        QHT_NR_ADDED_BUCKETS_THRESHOLD_DIV;
-
-    /* let tiny hash tables to at least add one non-head bucket */
-    if (unlikely(map->n_added_buckets_threshold == 0)) {
-        map->n_added_buckets_threshold = 1;
-    }
-
-    map->buckets = qemu_memalign(QHT_BUCKET_ALIGN,
-                                 sizeof(*map->buckets) * n_buckets);
-    for (i = 0; i < n_buckets; i++) {
-        qht_head_init(&map->buckets[i]);
-    }
-    return map;
-}
-
-void qht_init(struct qht *ht, size_t n_elems, unsigned int mode)
-{
-    struct qht_map *map;
-    size_t n_buckets = qht_elems_to_buckets(n_elems);
-
-    ht->mode = mode;
-    qemu_mutex_init(&ht->lock);
-    map = qht_map_create(n_buckets);
-    atomic_rcu_set(&ht->map, map);
-}
-
-/* call only when there are no readers/writers left */
-void qht_destroy(struct qht *ht)
-{
-    qht_map_destroy(ht->map);
-    memset(ht, 0, sizeof(*ht));
-}
-
-static void qht_bucket_reset__locked(struct qht_bucket *head)
-{
-    struct qht_bucket *b = head;
-    int i;
-
-    seqlock_write_begin(&head->sequence);
-    do {
-        for (i = 0; i < QHT_BUCKET_ENTRIES; i++) {
-            if (b->pointers[i] == NULL) {
-                goto done;
-            }
-            b->hashes[i] = 0;
-            atomic_set(&b->pointers[i], NULL);
-        }
-        b = b->next;
-    } while (b);
- done:
-    seqlock_write_end(&head->sequence);
-}
-
-/* call with all bucket locks held */
-static void qht_map_reset__all_locked(struct qht_map *map)
-{
-    size_t i;
-
-    for (i = 0; i < map->n_buckets; i++) {
-        qht_bucket_reset__locked(&map->buckets[i]);
-    }
-    qht_map_debug__all_locked(map);
-}
-
-void qht_reset(struct qht *ht)
-{
-    struct qht_map *map;
-
-    qht_map_lock_buckets__no_stale(ht, &map);
-    qht_map_reset__all_locked(map);
-    qht_map_unlock_buckets(map);
-}
-
-bool qht_reset_size(struct qht *ht, size_t n_elems)
-{
-    struct qht_map *new;
-    struct qht_map *map;
-    size_t n_buckets;
-    bool resize = false;
-
-    n_buckets = qht_elems_to_buckets(n_elems);
-
-    qemu_mutex_lock(&ht->lock);
-    map = ht->map;
-    if (n_buckets != map->n_buckets) {
-        new = qht_map_create(n_buckets);
-        resize = true;
-    }
-
-    qht_map_lock_buckets(map);
-    qht_map_reset__all_locked(map);
-    if (resize) {
-        qht_do_resize(ht, new);
-    }
-    qht_map_unlock_buckets(map);
-    qemu_mutex_unlock(&ht->lock);
-
-    return resize;
-}
-
-static inline
-void *qht_do_lookup(struct qht_bucket *head, qht_lookup_func_t func,
-                    const void *userp, uint32_t hash)
-{
-    struct qht_bucket *b = head;
-    int i;
-
-    do {
-        for (i = 0; i < QHT_BUCKET_ENTRIES; i++) {
-            if (b->hashes[i] == hash) {
-                /* The pointer is dereferenced before seqlock_read_retry,
-                 * so (unlike qht_insert__locked) we need to use
-                 * atomic_rcu_read here.
-                 */
-                void *p = atomic_rcu_read(&b->pointers[i]);
-
-                if (likely(p) && likely(func(p, userp))) {
-                    return p;
-                }
-            }
-        }
-        b = atomic_rcu_read(&b->next);
-    } while (b);
-
-    return NULL;
-}
-
-static __attribute__((noinline))
-void *qht_lookup__slowpath(struct qht_bucket *b, qht_lookup_func_t func,
-                           const void *userp, uint32_t hash)
-{
-    unsigned int version;
-    void *ret;
-
-    do {
-        version = seqlock_read_begin(&b->sequence);
-        ret = qht_do_lookup(b, func, userp, hash);
-    } while (seqlock_read_retry(&b->sequence, version));
-    return ret;
-}
-
-void *qht_lookup(struct qht *ht, qht_lookup_func_t func, const void *userp,
-                 uint32_t hash)
-{
-    struct qht_bucket *b;
-    struct qht_map *map;
-    unsigned int version;
-    void *ret;
-
-    map = atomic_rcu_read(&ht->map);
-    b = qht_map_to_bucket(map, hash);
-
-    version = seqlock_read_begin(&b->sequence);
-    ret = qht_do_lookup(b, func, userp, hash);
-    if (likely(!seqlock_read_retry(&b->sequence, version))) {
-        return ret;
-    }
-    /*
-     * Removing the do/while from the fastpath gives a 4% perf. increase when
-     * running a 100%-lookup microbenchmark.
-     */
-    return qht_lookup__slowpath(b, func, userp, hash);
-}
-
-/* call with head->lock held */
-static bool qht_insert__locked(struct qht *ht, struct qht_map *map,
-                               struct qht_bucket *head, void *p, uint32_t hash,
-                               bool *needs_resize)
-{
-    struct qht_bucket *b = head;
-    struct qht_bucket *prev = NULL;
-    struct qht_bucket *new = NULL;
-    int i;
-
-    do {
-        for (i = 0; i < QHT_BUCKET_ENTRIES; i++) {
-            if (b->pointers[i]) {
-                if (unlikely(b->pointers[i] == p)) {
-                    return false;
-                }
-            } else {
-                goto found;
-            }
-        }
-        prev = b;
-        b = b->next;
-    } while (b);
-
-    b = qemu_memalign(QHT_BUCKET_ALIGN, sizeof(*b));
-    memset(b, 0, sizeof(*b));
-    new = b;
-    i = 0;
-    atomic_inc(&map->n_added_buckets);
-    if (unlikely(qht_map_needs_resize(map)) && needs_resize) {
-        *needs_resize = true;
-    }
-
- found:
-    /* found an empty key: acquire the seqlock and write */
-    seqlock_write_begin(&head->sequence);
-    if (new) {
-        atomic_rcu_set(&prev->next, b);
-    }
-    b->hashes[i] = hash;
-    /* smp_wmb() implicit in seqlock_write_begin.  */
-    atomic_set(&b->pointers[i], p);
-    seqlock_write_end(&head->sequence);
-    return true;
-}
-
-static __attribute__((noinline)) void qht_grow_maybe(struct qht *ht)
-{
-    struct qht_map *map;
-
-    /*
-     * If the lock is taken it probably means there's an ongoing resize,
-     * so bail out.
-     */
-    if (qemu_mutex_trylock(&ht->lock)) {
-        return;
-    }
-    map = ht->map;
-    /* another thread might have just performed the resize we were after */
-    if (qht_map_needs_resize(map)) {
-        struct qht_map *new = qht_map_create(map->n_buckets * 2);
-
-        qht_map_lock_buckets(map);
-        qht_do_resize(ht, new);
-        qht_map_unlock_buckets(map);
-    }
-    qemu_mutex_unlock(&ht->lock);
-}
-
-bool qht_insert(struct qht *ht, void *p, uint32_t hash)
-{
-    struct qht_bucket *b;
-    struct qht_map *map;
-    bool needs_resize = false;
-    bool ret;
-
-    /* NULL pointers are not supported */
-    qht_debug_assert(p);
-
-    b = qht_bucket_lock__no_stale(ht, hash, &map);
-    ret = qht_insert__locked(ht, map, b, p, hash, &needs_resize);
-    qht_bucket_debug__locked(b);
-    qemu_spin_unlock(&b->lock);
-
-    if (unlikely(needs_resize) && ht->mode & QHT_MODE_AUTO_RESIZE) {
-        qht_grow_maybe(ht);
-    }
-    return ret;
-}
-
-static inline bool qht_entry_is_last(struct qht_bucket *b, int pos)
-{
-    if (pos == QHT_BUCKET_ENTRIES - 1) {
-        if (b->next == NULL) {
-            return true;
-        }
-        return b->next->pointers[0] == NULL;
-    }
-    return b->pointers[pos + 1] == NULL;
-}
-
-static void
-qht_entry_move(struct qht_bucket *to, int i, struct qht_bucket *from, int j)
-{
-    qht_debug_assert(!(to == from && i == j));
-    qht_debug_assert(to->pointers[i]);
-    qht_debug_assert(from->pointers[j]);
-
-    to->hashes[i] = from->hashes[j];
-    atomic_set(&to->pointers[i], from->pointers[j]);
-
-    from->hashes[j] = 0;
-    atomic_set(&from->pointers[j], NULL);
-}
-
-/*
- * Find the last valid entry in @head, and swap it with @orig[pos], which has
- * just been invalidated.
- */
-static inline void qht_bucket_remove_entry(struct qht_bucket *orig, int pos)
-{
-    struct qht_bucket *b = orig;
-    struct qht_bucket *prev = NULL;
-    int i;
-
-    if (qht_entry_is_last(orig, pos)) {
-        orig->hashes[pos] = 0;
-        atomic_set(&orig->pointers[pos], NULL);
-        return;
-    }
-    do {
-        for (i = 0; i < QHT_BUCKET_ENTRIES; i++) {
-            if (b->pointers[i]) {
-                continue;
-            }
-            if (i > 0) {
-                return qht_entry_move(orig, pos, b, i - 1);
-            }
-            qht_debug_assert(prev);
-            return qht_entry_move(orig, pos, prev, QHT_BUCKET_ENTRIES - 1);
-        }
-        prev = b;
-        b = b->next;
-    } while (b);
-    /* no free entries other than orig[pos], so swap it with the last one */
-    qht_entry_move(orig, pos, prev, QHT_BUCKET_ENTRIES - 1);
-}
-
-/* call with b->lock held */
-static inline
-bool qht_remove__locked(struct qht_map *map, struct qht_bucket *head,
-                        const void *p, uint32_t hash)
-{
-    struct qht_bucket *b = head;
-    int i;
-
-    do {
-        for (i = 0; i < QHT_BUCKET_ENTRIES; i++) {
-            void *q = b->pointers[i];
-
-            if (unlikely(q == NULL)) {
-                return false;
-            }
-            if (q == p) {
-                qht_debug_assert(b->hashes[i] == hash);
-                seqlock_write_begin(&head->sequence);
-                qht_bucket_remove_entry(b, i);
-                seqlock_write_end(&head->sequence);
-                return true;
-            }
-        }
-        b = b->next;
-    } while (b);
-    return false;
-}
-
-bool qht_remove(struct qht *ht, const void *p, uint32_t hash)
-{
-    struct qht_bucket *b;
-    struct qht_map *map;
-    bool ret;
-
-    /* NULL pointers are not supported */
-    qht_debug_assert(p);
-
-    b = qht_bucket_lock__no_stale(ht, hash, &map);
-    ret = qht_remove__locked(map, b, p, hash);
-    qht_bucket_debug__locked(b);
-    qemu_spin_unlock(&b->lock);
-    return ret;
-}
-
-static inline void qht_bucket_iter(struct qht *ht, struct qht_bucket *b,
-                                   qht_iter_func_t func, void *userp)
-{
-    int i;
-
-    do {
-        for (i = 0; i < QHT_BUCKET_ENTRIES; i++) {
-            if (b->pointers[i] == NULL) {
-                return;
-            }
-            func(ht, b->pointers[i], b->hashes[i], userp);
-        }
-        b = b->next;
-    } while (b);
-}
-
-/* call with all of the map's locks held */
-static inline void qht_map_iter__all_locked(struct qht *ht, struct qht_map *map,
-                                            qht_iter_func_t func, void *userp)
-{
-    size_t i;
-
-    for (i = 0; i < map->n_buckets; i++) {
-        qht_bucket_iter(ht, &map->buckets[i], func, userp);
-    }
-}
-
-void qht_iter(struct qht *ht, qht_iter_func_t func, void *userp)
-{
-    struct qht_map *map;
-
-    map = atomic_rcu_read(&ht->map);
-    qht_map_lock_buckets(map);
-    /* Note: ht here is merely for carrying ht->mode; ht->map won't be read */
-    qht_map_iter__all_locked(ht, map, func, userp);
-    qht_map_unlock_buckets(map);
-}
-
-static void qht_map_copy(struct qht *ht, void *p, uint32_t hash, void *userp)
-{
-    struct qht_map *new = userp;
-    struct qht_bucket *b = qht_map_to_bucket(new, hash);
-
-    /* no need to acquire b->lock because no thread has seen this map yet */
-    qht_insert__locked(ht, new, b, p, hash, NULL);
-}
-
-/*
- * Call with ht->lock and all bucket locks held.
- *
- * Creating the @new map here would add unnecessary delay while all the locks
- * are held--holding up the bucket locks is particularly bad, since no writes
- * can occur while these are held. Thus, we let callers create the new map,
- * hopefully without the bucket locks held.
- */
-static void qht_do_resize(struct qht *ht, struct qht_map *new)
-{
-    struct qht_map *old;
-
-    old = ht->map;
-    g_assert_cmpuint(new->n_buckets, !=, old->n_buckets);
-
-    qht_map_iter__all_locked(ht, old, qht_map_copy, new);
-    qht_map_debug__all_locked(new);
-
-    atomic_rcu_set(&ht->map, new);
-    call_rcu(old, qht_map_destroy, rcu);
-}
-
-bool qht_resize(struct qht *ht, size_t n_elems)
-{
-    size_t n_buckets = qht_elems_to_buckets(n_elems);
-    size_t ret = false;
-
-    qemu_mutex_lock(&ht->lock);
-    if (n_buckets != ht->map->n_buckets) {
-        struct qht_map *new;
-        struct qht_map *old = ht->map;
-
-        new = qht_map_create(n_buckets);
-        qht_map_lock_buckets(old);
-        qht_do_resize(ht, new);
-        qht_map_unlock_buckets(old);
-        ret = true;
-    }
-    qemu_mutex_unlock(&ht->lock);
-
-    return ret;
-}
-
-/* pass @stats to qht_statistics_destroy() when done */
-void qht_statistics_init(struct qht *ht, struct qht_stats *stats)
-{
-    struct qht_map *map;
-    int i;
-
-    map = atomic_rcu_read(&ht->map);
-
-    stats->used_head_buckets = 0;
-    stats->entries = 0;
-    qdist_init(&stats->chain);
-    qdist_init(&stats->occupancy);
-    /* bail out if the qht has not yet been initialized */
-    if (unlikely(map == NULL)) {
-        stats->head_buckets = 0;
-        return;
-    }
-    stats->head_buckets = map->n_buckets;
-
-    for (i = 0; i < map->n_buckets; i++) {
-        struct qht_bucket *head = &map->buckets[i];
-        struct qht_bucket *b;
-        unsigned int version;
-        size_t buckets;
-        size_t entries;
-        int j;
-
-        do {
-            version = seqlock_read_begin(&head->sequence);
-            buckets = 0;
-            entries = 0;
-            b = head;
-            do {
-                for (j = 0; j < QHT_BUCKET_ENTRIES; j++) {
-                    if (atomic_read(&b->pointers[j]) == NULL) {
-                        break;
-                    }
-                    entries++;
-                }
-                buckets++;
-                b = atomic_rcu_read(&b->next);
-            } while (b);
-        } while (seqlock_read_retry(&head->sequence, version));
-
-        if (entries) {
-            qdist_inc(&stats->chain, buckets);
-            qdist_inc(&stats->occupancy,
-                      (double)entries / QHT_BUCKET_ENTRIES / buckets);
-            stats->used_head_buckets++;
-            stats->entries += entries;
-        } else {
-            qdist_inc(&stats->occupancy, 0);
-        }
-    }
-}
-
-void qht_statistics_destroy(struct qht_stats *stats)
-{
-    qdist_destroy(&stats->occupancy);
-    qdist_destroy(&stats->chain);
-}
diff --git a/util/range.c b/util/range.c
deleted file mode 100644 (file)
index 416df7c..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * QEMU 64-bit address ranges
- *
- * Copyright (c) 2015-2016 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qemu/range.h"
-
-/*
- * Return -1 if @a < @b, 1 @a > @b, and 0 if they touch or overlap.
- * Both @a and @b must not be empty.
- */
-static inline int range_compare(Range *a, Range *b)
-{
-    assert(!range_is_empty(a) && !range_is_empty(b));
-
-    /* Careful, avoid wraparound */
-    if (b->lob && b->lob - 1 > a->upb) {
-        return -1;
-    }
-    if (a->lob && a->lob - 1 > b->upb) {
-        return 1;
-    }
-    return 0;
-}
-
-/* Insert @data into @list of ranges; caller no longer owns @data */
-GList *range_list_insert(GList *list, Range *data)
-{
-    GList *l;
-
-    assert(!range_is_empty(data));
-
-    /* Skip all list elements strictly less than data */
-    for (l = list; l && range_compare(l->data, data) < 0; l = l->next) {
-    }
-
-    if (!l || range_compare(l->data, data) > 0) {
-        /* Rest of the list (if any) is strictly greater than @data */
-        return g_list_insert_before(list, l, data);
-    }
-
-    /* Current list element overlaps @data, merge the two */
-    range_extend(l->data, data);
-    g_free(data);
-
-    /* Merge any subsequent list elements that now also overlap */
-    while (l->next && range_compare(l->data, l->next->data) == 0) {
-        GList *new_l;
-
-        range_extend(l->data, l->next->data);
-        g_free(l->next->data);
-        new_l = g_list_delete_link(list, l->next);
-        assert(new_l == list);
-    }
-
-    return list;
-}
index 084c2f0..c22f5fe 100644 (file)
@@ -58,9 +58,9 @@ void rfifolock_lock(RFifoLock *r)
             }
             qemu_cond_wait(&r->cond, &r->lock);
         }
-        qemu_thread_get_self(&r->owner_thread);
     }
 
+    qemu_thread_get_self(&r->owner_thread);
     r->nesting++;
     qemu_mutex_unlock(&r->lock);
 }
index 3817d9b..71246b2 100644 (file)
@@ -315,14 +315,6 @@ bool throttle_is_valid(ThrottleConfig *cfg, Error **errp)
         return false;
     }
 
-    if (cfg->op_size &&
-        !cfg->buckets[THROTTLE_OPS_TOTAL].avg &&
-        !cfg->buckets[THROTTLE_OPS_READ].avg &&
-        !cfg->buckets[THROTTLE_OPS_WRITE].avg) {
-        error_setg(errp, "iops size requires an iops value to be set");
-        return false;
-    }
-
     for (i = 0; i < BUCKETS_COUNT; i++) {
         if (cfg->buckets[i].avg < 0 ||
             cfg->buckets[i].max < 0 ||
@@ -348,11 +340,6 @@ bool throttle_is_valid(ThrottleConfig *cfg, Error **errp)
                        " bps/iops values");
             return false;
         }
-
-        if (cfg->buckets[i].max && cfg->buckets[i].max < cfg->buckets[i].avg) {
-            error_setg(errp, "bps_max/iops_max cannot be lower than bps/iops");
-            return false;
-        }
     }
 
     return true;
diff --git a/util/trace-events b/util/trace-events
deleted file mode 100644 (file)
index 747e6ba..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# util/oslib-win32.c
-# util/oslib-posix.c
-qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu ptr %p"
-qemu_anon_ram_alloc(size_t size, void *ptr) "size %zu ptr %p"
-qemu_vfree(void *ptr) "ptr %p"
-qemu_anon_ram_free(void *ptr, size_t size) "ptr %p size %zu"
-
-# util/hbitmap.c
-hbitmap_iter_skip_words(const void *hb, void *hbi, uint64_t pos, unsigned long cur) "hb %p hbi %p pos %"PRId64" cur 0x%lx"
-hbitmap_reset(void *hb, uint64_t start, uint64_t count, uint64_t sbit, uint64_t ebit) "hb %p items %"PRIu64",%"PRIu64" bits %"PRIu64"..%"PRIu64
-hbitmap_set(void *hb, uint64_t start, uint64_t count, uint64_t sbit, uint64_t ebit) "hb %p items %"PRIu64",%"PRIu64" bits %"PRIu64"..%"PRIu64
index 70a9cbc..d109d6c 100644 (file)
@@ -52,6 +52,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib.h>
 
 #include "qemu/uri.h"
 
diff --git a/vl.c b/vl.c
index b3c80d5..5db5dc2 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -22,7 +22,6 @@
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
-#include "qemu-version.h"
 #include "qemu/cutils.h"
 #include "qemu/help_option.h"
 
@@ -52,6 +51,7 @@ int main(int argc, char **argv)
 #define main qemu_main
 #endif /* CONFIG_COCOA */
 
+#include <glib.h>
 
 #include "qemu/error-report.h"
 #include "qemu/sockets.h"
@@ -80,7 +80,6 @@ int main(int argc, char **argv)
 #include "qemu/timer.h"
 #include "sysemu/char.h"
 #include "qemu/bitmap.h"
-#include "qemu/log.h"
 #include "sysemu/blockdev.h"
 #include "hw/block/block.h"
 #include "migration/block.h"
@@ -88,7 +87,6 @@ int main(int argc, char **argv)
 #include "sysemu/dma.h"
 #include "audio/audio.h"
 #include "migration/migration.h"
-#include "sysemu/cpus.h"
 #include "sysemu/kvm.h"
 #include "qapi/qmp/qjson.h"
 #include "qemu/option.h"
@@ -129,8 +127,10 @@ static const char *data_dir[16];
 static int data_dir_idx;
 const char *bios_name = NULL;
 enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
+DisplayType display_type = DT_DEFAULT;
 int request_opengl = -1;
 int display_opengl;
+static int display_remote;
 const char* keyboard_layout = NULL;
 ram_addr_t ram_size;
 const char *mem_path = NULL;
@@ -146,7 +146,9 @@ int vga_interface_type = VGA_NONE;
 static int full_screen = 0;
 static int no_frame = 0;
 int no_quit = 0;
+#ifdef CONFIG_GTK
 static bool grab_on_hover;
+#endif
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
 CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
@@ -154,7 +156,7 @@ CharDriverState *sclp_hds[MAX_SCLP_CONSOLES];
 int win2k_install_hack = 0;
 int singlestep = 0;
 int smp_cpus = 1;
-int max_cpus = 1;
+int max_cpus = 0;
 int smp_cores = 1;
 int smp_threads = 1;
 int acpi_enabled = 1;
@@ -207,7 +209,6 @@ static int default_floppy = 1;
 static int default_cdrom = 1;
 static int default_sdcard = 1;
 static int default_vga = 1;
-static int default_net = 1;
 
 static struct {
     const char *driver;
@@ -262,6 +263,26 @@ static QemuOptsList qemu_sandbox_opts = {
     },
 };
 
+static QemuOptsList qemu_trace_opts = {
+    .name = "trace",
+    .implied_opt_name = "enable",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_trace_opts.head),
+    .desc = {
+        {
+            .name = "enable",
+            .type = QEMU_OPT_STRING,
+        },
+        {
+            .name = "events",
+            .type = QEMU_OPT_STRING,
+        },{
+            .name = "file",
+            .type = QEMU_OPT_STRING,
+        },
+        { /* end of list */ }
+    },
+};
+
 static QemuOptsList qemu_option_rom_opts = {
     .name = "option-rom",
     .implied_opt_name = "romfile",
@@ -873,13 +894,16 @@ static void configure_rtc(QemuOpts *opts)
     value = qemu_opt_get(opts, "driftfix");
     if (value) {
         if (!strcmp(value, "slew")) {
-            static GlobalProperty slew_lost_ticks = {
-                .driver   = "mc146818rtc",
-                .property = "lost_tick_policy",
-                .value    = "slew",
+            static GlobalProperty slew_lost_ticks[] = {
+                {
+                    .driver   = "mc146818rtc",
+                    .property = "lost_tick_policy",
+                    .value    = "slew",
+                },
+                { /* end of list */ }
             };
 
-            qdev_prop_register_global(&slew_lost_ticks);
+            qdev_prop_register_global_list(slew_lost_ticks);
         } else if (!strcmp(value, "none")) {
             /* discard is default */
         } else {
@@ -1052,6 +1076,11 @@ bool defaults_enabled(void)
     return has_defaults;
 }
 
+bool usb_enabled(void)
+{
+    return machine_usb(current_machine);
+}
+
 #ifndef _WIN32
 static int parse_add_fd(void *opaque, QemuOpts *opts, Error **errp)
 {
@@ -1198,6 +1227,7 @@ static QemuOptsList qemu_smp_opts = {
 static void smp_parse(QemuOpts *opts)
 {
     if (opts) {
+
         unsigned cpus    = qemu_opt_get_number(opts, "cpus", 0);
         unsigned sockets = qemu_opt_get_number(opts, "sockets", 0);
         unsigned cores   = qemu_opt_get_number(opts, "cores", 0);
@@ -1214,10 +1244,8 @@ static void smp_parse(QemuOpts *opts)
         } else if (cores == 0) {
             threads = threads > 0 ? threads : 1;
             cores = cpus / (sockets * threads);
-            cores = cores > 0 ? cores : 1;
         } else if (threads == 0) {
             threads = cpus / (cores * sockets);
-            threads = threads > 0 ? threads : 1;
         } else if (sockets * cores * threads < cpus) {
             error_report("cpu topology: "
                          "sockets (%u) * cores (%u) * threads (%u) < "
@@ -1227,17 +1255,6 @@ static void smp_parse(QemuOpts *opts)
         }
 
         max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus);
-
-        if (max_cpus > MAX_CPUMASK_BITS) {
-            error_report("unsupported number of maxcpus");
-            exit(1);
-        }
-
-        if (max_cpus < cpus) {
-            error_report("maxcpus must be equal to or greater than smp");
-            exit(1);
-        }
-
         if (sockets * cores * threads > max_cpus) {
             error_report("cpu topology: "
                          "sockets (%u) * cores (%u) * threads (%u) > "
@@ -1247,11 +1264,25 @@ static void smp_parse(QemuOpts *opts)
         }
 
         smp_cpus = cpus;
-        smp_cores = cores;
-        smp_threads = threads;
+        smp_cores = cores > 0 ? cores : 1;
+        smp_threads = threads > 0 ? threads : 1;
+
     }
 
-    if (smp_cpus > 1) {
+    if (max_cpus == 0) {
+        max_cpus = smp_cpus;
+    }
+
+    if (max_cpus > MAX_CPUMASK_BITS) {
+        error_report("unsupported number of maxcpus");
+        exit(1);
+    }
+    if (max_cpus < smp_cpus) {
+        error_report("maxcpus must be equal to or greater than smp");
+        exit(1);
+    }
+
+    if (smp_cpus > 1 || smp_cores > 1 || smp_threads > 1) {
         Error *blocker = NULL;
         error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp");
         replay_add_blocker(blocker);
@@ -1366,7 +1397,7 @@ static int usb_device_add(const char *devname)
     const char *p;
 #endif
 
-    if (!machine_usb(current_machine)) {
+    if (!usb_enabled()) {
         return -1;
     }
 
@@ -1398,7 +1429,7 @@ static int usb_device_del(const char *devname)
         return -1;
     }
 
-    if (!machine_usb(current_machine)) {
+    if (!usb_enabled()) {
         return -1;
     }
 
@@ -1506,7 +1537,6 @@ MachineInfoList *qmp_query_machines(Error **errp)
 
         info->name = g_strdup(mc->name);
         info->cpu_max = !mc->max_cpus ? 1 : mc->max_cpus;
-        info->hotpluggable_cpus = !!mc->query_hotpluggable_cpus;
 
         entry = g_malloc0(sizeof(*entry));
         entry->value = info;
@@ -1914,8 +1944,7 @@ static void main_loop(void)
 
 static void version(void)
 {
-    printf("QEMU emulator version " QEMU_VERSION QEMU_PKGVERSION ", "
-           QEMU_COPYRIGHT "\n");
+    printf("QEMU emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
 }
 
 static void help(int exitcode)
@@ -1954,86 +1983,99 @@ static const QEMUOption qemu_options[] = {
     { NULL },
 };
 
-typedef struct VGAInterfaceInfo {
-    const char *opt_name;    /* option name */
-    const char *name;        /* human-readable name */
-    /* Class names indicating that support is available.
-     * If no class is specified, the interface is always available */
-    const char *class_names[2];
-} VGAInterfaceInfo;
-
-static VGAInterfaceInfo vga_interfaces[VGA_TYPE_MAX] = {
-    [VGA_NONE] = {
-        .opt_name = "none",
-    },
-    [VGA_STD] = {
-        .opt_name = "std",
-        .name = "standard VGA",
-        .class_names = { "VGA", "isa-vga" },
-    },
-    [VGA_CIRRUS] = {
-        .opt_name = "cirrus",
-        .name = "Cirrus VGA",
-        .class_names = { "cirrus-vga", "isa-cirrus-vga" },
-    },
-    [VGA_VMWARE] = {
-        .opt_name = "vmware",
-        .name = "VMWare SVGA",
-        .class_names = { "vmware-svga" },
-    },
-    [VGA_VIRTIO] = {
-        .opt_name = "virtio",
-        .name = "Virtio VGA",
-        .class_names = { "virtio-vga" },
-    },
-    [VGA_QXL] = {
-        .opt_name = "qxl",
-        .name = "QXL VGA",
-        .class_names = { "qxl-vga" },
-    },
-    [VGA_TCX] = {
-        .opt_name = "tcx",
-        .name = "TCX framebuffer",
-        .class_names = { "SUNW,tcx" },
-    },
-    [VGA_CG3] = {
-        .opt_name = "cg3",
-        .name = "CG3 framebuffer",
-        .class_names = { "cgthree" },
-    },
-    [VGA_XENFB] = {
-        .opt_name = "xenfb",
-    },
-};
+static bool vga_available(void)
+{
+    return object_class_by_name("VGA") || object_class_by_name("isa-vga");
+}
+
+static bool cirrus_vga_available(void)
+{
+    return object_class_by_name("cirrus-vga")
+           || object_class_by_name("isa-cirrus-vga");
+}
 
-static bool vga_interface_available(VGAInterfaceType t)
+static bool vmware_vga_available(void)
 {
-    VGAInterfaceInfo *ti = &vga_interfaces[t];
+    return object_class_by_name("vmware-svga");
+}
 
-    assert(t < VGA_TYPE_MAX);
-    return !ti->class_names[0] ||
-           object_class_by_name(ti->class_names[0]) ||
-           object_class_by_name(ti->class_names[1]);
+static bool qxl_vga_available(void)
+{
+    return object_class_by_name("qxl-vga");
 }
 
-static void select_vgahw(const char *p)
+static bool tcx_vga_available(void)
+{
+    return object_class_by_name("SUNW,tcx");
+}
+
+static bool cg3_vga_available(void)
+{
+    return object_class_by_name("cgthree");
+}
+
+static bool virtio_vga_available(void)
+{
+    return object_class_by_name("virtio-vga");
+}
+
+static void select_vgahw (const char *p)
 {
     const char *opts;
-    int t;
 
     assert(vga_interface_type == VGA_NONE);
-    for (t = 0; t < VGA_TYPE_MAX; t++) {
-        VGAInterfaceInfo *ti = &vga_interfaces[t];
-        if (ti->opt_name && strstart(p, ti->opt_name, &opts)) {
-            if (!vga_interface_available(t)) {
-                error_report("%s not available", ti->name);
-                exit(1);
-            }
-            vga_interface_type = t;
-            break;
+    if (strstart(p, "std", &opts)) {
+        if (vga_available()) {
+            vga_interface_type = VGA_STD;
+        } else {
+            error_report("standard VGA not available");
+            exit(0);
         }
-    }
-    if (t == VGA_TYPE_MAX) {
+    } else if (strstart(p, "cirrus", &opts)) {
+        if (cirrus_vga_available()) {
+            vga_interface_type = VGA_CIRRUS;
+        } else {
+            error_report("Cirrus VGA not available");
+            exit(0);
+        }
+    } else if (strstart(p, "vmware", &opts)) {
+        if (vmware_vga_available()) {
+            vga_interface_type = VGA_VMWARE;
+        } else {
+            error_report("VMWare SVGA not available");
+            exit(0);
+        }
+    } else if (strstart(p, "virtio", &opts)) {
+        if (virtio_vga_available()) {
+            vga_interface_type = VGA_VIRTIO;
+        } else {
+            error_report("Virtio VGA not available");
+            exit(0);
+        }
+    } else if (strstart(p, "xenfb", &opts)) {
+        vga_interface_type = VGA_XENFB;
+    } else if (strstart(p, "qxl", &opts)) {
+        if (qxl_vga_available()) {
+            vga_interface_type = VGA_QXL;
+        } else {
+            error_report("QXL VGA not available");
+            exit(0);
+        }
+    } else if (strstart(p, "tcx", &opts)) {
+        if (tcx_vga_available()) {
+            vga_interface_type = VGA_TCX;
+        } else {
+            error_report("TCX framebuffer not available");
+            exit(0);
+        }
+    } else if (strstart(p, "cg3", &opts)) {
+        if (cg3_vga_available()) {
+            vga_interface_type = VGA_CG3;
+        } else {
+            error_report("CG3 framebuffer not available");
+            exit(0);
+        }
+    } else if (!strstart(p, "none", &opts)) {
     invalid_vga:
         error_report("unknown vga type: %s", p);
         exit(1);
@@ -2053,15 +2095,6 @@ static void select_vgahw(const char *p)
     }
 }
 
-typedef enum DisplayType {
-    DT_DEFAULT,
-    DT_CURSES,
-    DT_SDL,
-    DT_COCOA,
-    DT_GTK,
-    DT_NONE,
-} DisplayType;
-
 static DisplayType select_display(const char *p)
 {
     const char *opts;
@@ -2130,12 +2163,21 @@ static DisplayType select_display(const char *p)
         exit(1);
 #endif
     } else if (strstart(p, "vnc", &opts)) {
+#ifdef CONFIG_VNC
         if (*opts == '=') {
-            vnc_parse(opts + 1, &error_fatal);
+            Error *err = NULL;
+            if (vnc_parse(opts + 1, &err) == NULL) {
+                error_report_err(err);
+                exit(1);
+            }
         } else {
             error_report("VNC requires a display argument vnc=<display>");
             exit(1);
         }
+#else
+        error_report("VNC support is disabled");
+        exit(1);
+#endif
     } else if (strstart(p, "curses", &opts)) {
 #ifdef CONFIG_CURSES
         display = DT_CURSES;
@@ -2336,7 +2378,10 @@ static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp)
 #ifdef CONFIG_VIRTFS
 static int fsdev_init_func(void *opaque, QemuOpts *opts, Error **errp)
 {
-    return qemu_fsdev_add(opts);
+    int ret;
+    ret = qemu_fsdev_add(opts);
+
+    return ret;
 }
 #endif
 
@@ -2381,6 +2426,7 @@ static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
 static void monitor_parse(const char *optarg, const char *mode, bool pretty)
 {
     static int monitor_device_index = 0;
+    Error *local_err = NULL;
     QemuOpts *opts;
     const char *p;
     char label[32];
@@ -2401,7 +2447,11 @@ static void monitor_parse(const char *optarg, const char *mode, bool pretty)
         }
     }
 
-    opts = qemu_opts_create(qemu_find_opts("mon"), label, 1, &error_fatal);
+    opts = qemu_opts_create(qemu_find_opts("mon"), label, 1, &local_err);
+    if (!opts) {
+        error_report_err(local_err);
+        exit(1);
+    }
     qemu_opt_set(opts, "mode", mode, &error_abort);
     qemu_opt_set(opts, "chardev", label, &error_abort);
     qemu_opt_set_bool(opts, "pretty", pretty, &error_abort);
@@ -2676,11 +2726,6 @@ void qemu_add_machine_init_done_notifier(Notifier *notify)
     }
 }
 
-void qemu_remove_machine_init_done_notifier(Notifier *notify)
-{
-    notifier_remove(notify);
-}
-
 static void qemu_run_machine_init_done_notifiers(void)
 {
     notifier_list_notify(&machine_init_done_notifiers, NULL);
@@ -2914,20 +2959,6 @@ static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size,
     loc_pop(&loc);
 }
 
-static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
-{
-    GlobalProperty *g;
-
-    g = g_malloc0(sizeof(*g));
-    g->driver   = qemu_opt_get(opts, "driver");
-    g->property = qemu_opt_get(opts, "property");
-    g->value    = qemu_opt_get(opts, "value");
-    g->user_provided = true;
-    g->errp = &error_fatal;
-    qdev_prop_register_global(g);
-    return 0;
-}
-
 int main(int argc, char **argv, char **envp)
 {
     int i;
@@ -2950,11 +2981,11 @@ int main(int argc, char **argv, char **envp)
     const char *qtest_log = NULL;
     const char *pid_file = NULL;
     const char *incoming = NULL;
+#ifdef CONFIG_VNC
+    int show_vnc_port = 0;
+#endif
     bool defconfig = true;
     bool userconfig = true;
-    bool nographic = false;
-    DisplayType display_type = DT_DEFAULT;
-    int display_remote = 0;
     const char *log_mask = NULL;
     const char *log_file = NULL;
     char *trace_file = NULL;
@@ -2963,7 +2994,6 @@ int main(int argc, char **argv, char **envp)
     FILE *vmstate_dump_file = NULL;
     Error *main_loop_err = NULL;
     Error *err = NULL;
-    bool list_data_dirs = false;
 
     qemu_init_cpu_loop();
     qemu_mutex_lock_iothread();
@@ -3067,7 +3097,7 @@ int main(int argc, char **argv, char **envp)
 
             popt = lookup_opt(argc, argv, &optarg, &optind);
             if (!(popt->arch_mask & arch_type)) {
-                error_report("Option not supported for this target");
+                printf("Option %s not supported for this target\n", popt->name);
                 exit(1);
             }
             switch(popt->index) {
@@ -3200,10 +3230,7 @@ int main(int argc, char **argv, char **envp)
                 display_type = select_display(optarg);
                 break;
             case QEMU_OPTION_nographic:
-                olist = qemu_find_opts("machine");
-                qemu_opts_parse_noisily(olist, "graphics=off", false);
-                nographic = true;
-                display_type = DT_NONE;
+                display_type = DT_NOGRAPHIC;
                 break;
             case QEMU_OPTION_curses:
 #ifdef CONFIG_CURSES
@@ -3259,13 +3286,11 @@ int main(int argc, char **argv, char **envp)
                 fd_bootchk = 0;
                 break;
             case QEMU_OPTION_netdev:
-                default_net = 0;
                 if (net_client_parse(qemu_find_opts("netdev"), optarg) == -1) {
                     exit(1);
                 }
                 break;
             case QEMU_OPTION_net:
-                default_net = 0;
                 if (net_client_parse(qemu_find_opts("net"), optarg) == -1) {
                     exit(1);
                 }
@@ -3341,7 +3366,7 @@ int main(int argc, char **argv, char **envp)
                 log_file = optarg;
                 break;
             case QEMU_OPTION_DFILTER:
-                qemu_set_dfilter_ranges(optarg, &error_fatal);
+                qemu_set_dfilter_ranges(optarg);
                 break;
             case QEMU_OPTION_s:
                 add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT);
@@ -3350,9 +3375,7 @@ int main(int argc, char **argv, char **envp)
                 add_device_config(DEV_GDB, optarg);
                 break;
             case QEMU_OPTION_L:
-                if (is_help_option(optarg)) {
-                    list_data_dirs = true;
-                } else if (data_dir_idx < ARRAY_SIZE(data_dir)) {
+                if (data_dir_idx < ARRAY_SIZE(data_dir)) {
                     data_dir[data_dir_idx++] = optarg;
                 }
                 break;
@@ -3614,13 +3637,16 @@ int main(int argc, char **argv, char **envp)
                 win2k_install_hack = 1;
                 break;
             case QEMU_OPTION_rtc_td_hack: {
-                static GlobalProperty slew_lost_ticks = {
-                    .driver   = "mc146818rtc",
-                    .property = "lost_tick_policy",
-                    .value    = "slew",
+                static GlobalProperty slew_lost_ticks[] = {
+                    {
+                        .driver   = "mc146818rtc",
+                        .property = "lost_tick_policy",
+                        .value    = "slew",
+                    },
+                    { /* end of list */ }
                 };
 
-                qdev_prop_register_global(&slew_lost_ticks);
+                qdev_prop_register_global_list(slew_lost_ticks);
                 break;
             }
             case QEMU_OPTION_acpitable:
@@ -3667,15 +3693,18 @@ int main(int argc, char **argv, char **envp)
                 break;
             }
             case QEMU_OPTION_no_kvm_pit_reinjection: {
-                static GlobalProperty kvm_pit_lost_tick_policy = {
-                    .driver   = "kvm-pit",
-                    .property = "lost_tick_policy",
-                    .value    = "discard",
+                static GlobalProperty kvm_pit_lost_tick_policy[] = {
+                    {
+                        .driver   = "kvm-pit",
+                        .property = "lost_tick_policy",
+                        .value    = "discard",
+                    },
+                    { /* end of list */ }
                 };
 
                 error_report("warning: deprecated, replaced by "
                              "-global kvm-pit.lost_tick_policy=discard");
-                qdev_prop_register_global(&kvm_pit_lost_tick_policy);
+                qdev_prop_register_global_list(kvm_pit_lost_tick_policy);
                 break;
             }
             case QEMU_OPTION_usb:
@@ -3700,8 +3729,20 @@ int main(int argc, char **argv, char **envp)
                 }
                 break;
             case QEMU_OPTION_vnc:
-                vnc_parse(optarg, &error_fatal);
+            {
+#ifdef CONFIG_VNC
+                Error *local_err = NULL;
+
+                if (vnc_parse(optarg, &local_err) == NULL) {
+                    error_report_err(local_err);
+                    exit(1);
+                }
+#else
+                error_report("VNC support is disabled");
+                exit(1);
+#endif
                 break;
+            }
             case QEMU_OPTION_no_acpi:
                 acpi_enabled = 0;
                 break;
@@ -3845,29 +3886,43 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_xen_domid:
                 if (!(xen_available())) {
-                    error_report("Option not supported for this target");
+                    printf("Option %s not supported for this target\n", popt->name);
                     exit(1);
                 }
                 xen_domid = atoi(optarg);
                 break;
             case QEMU_OPTION_xen_create:
                 if (!(xen_available())) {
-                    error_report("Option not supported for this target");
+                    printf("Option %s not supported for this target\n", popt->name);
                     exit(1);
                 }
                 xen_mode = XEN_CREATE;
                 break;
             case QEMU_OPTION_xen_attach:
                 if (!(xen_available())) {
-                    error_report("Option not supported for this target");
+                    printf("Option %s not supported for this target\n", popt->name);
                     exit(1);
                 }
                 xen_mode = XEN_ATTACH;
                 break;
             case QEMU_OPTION_trace:
-                g_free(trace_file);
-                trace_file = trace_opt_parse(optarg);
+            {
+                opts = qemu_opts_parse_noisily(qemu_find_opts("trace"),
+                                               optarg, true);
+                if (!opts) {
+                    exit(1);
+                }
+                if (qemu_opt_get(opts, "enable")) {
+                    trace_enable_events(qemu_opt_get(opts, "enable"));
+                }
+                trace_init_events(qemu_opt_get(opts, "events"));
+                if (trace_file) {
+                    g_free(trace_file);
+                }
+                trace_file = g_strdup(qemu_opt_get(opts, "file"));
+                qemu_opts_del(opts);
                 break;
+            }
             case QEMU_OPTION_readconfig:
                 {
                     int ret = qemu_read_config_file(optarg);
@@ -4029,6 +4084,13 @@ int main(int argc, char **argv, char **envp)
         qemu_set_hw_version(machine_class->hw_version);
     }
 
+    /* Init CPU def lists, based on config
+     * - Must be called after all the qemu_read_config_file() calls
+     * - Must be called before list_cpus()
+     * - Must be called before machine->init()
+     */
+    cpudef_init();
+
     if (cpu_model && is_help_option(cpu_model)) {
         list_cpus(stdout, &fprintf, cpu_model);
         exit(0);
@@ -4042,7 +4104,7 @@ int main(int argc, char **argv, char **envp)
     /* Open the logfile at this point and set the log mask if necessary.
      */
     if (log_file) {
-        qemu_set_log_filename(log_file, &error_fatal);
+        qemu_set_log_filename(log_file);
     }
 
     if (log_mask) {
@@ -4070,14 +4132,6 @@ int main(int argc, char **argv, char **envp)
         data_dir[data_dir_idx++] = CONFIG_QEMU_DATADIR;
     }
 
-    /* -L help lists the data directories and exits. */
-    if (list_data_dirs) {
-        for (i = 0; i < data_dir_idx; i++) {
-            printf("%s\n", data_dir[i]);
-        }
-        exit(0);
-    }
-
     smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
 
     machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */
@@ -4142,7 +4196,7 @@ int main(int argc, char **argv, char **envp)
          * -nographic _and_ redirects all ports explicitly - this is valid
          * usage, -nographic is just a no-op in this case.
          */
-        if (nographic
+        if (display_type == DT_NOGRAPHIC
             && (default_parallel || default_serial
                 || default_monitor || default_virtcon)) {
             error_report("-nographic cannot be used with -daemonize");
@@ -4156,7 +4210,7 @@ int main(int argc, char **argv, char **envp)
 #endif
     }
 
-    if (nographic) {
+    if (display_type == DT_NOGRAPHIC) {
         if (default_parallel)
             add_device_config(DEV_PARALLEL, "null");
         if (default_serial && default_monitor) {
@@ -4198,12 +4252,11 @@ int main(int argc, char **argv, char **envp)
     if (display_type == DT_DEFAULT && !display_remote) {
 #if defined(CONFIG_GTK)
         display_type = DT_GTK;
-#elif defined(CONFIG_SDL)
+#elif defined(CONFIG_SDL) || defined(CONFIG_COCOA)
         display_type = DT_SDL;
-#elif defined(CONFIG_COCOA)
-        display_type = DT_COCOA;
 #elif defined(CONFIG_VNC)
         vnc_parse("localhost:0,to=99,id=default", &error_abort);
+        show_vnc_port = 1;
 #else
         display_type = DT_NONE;
 #endif
@@ -4218,14 +4271,16 @@ int main(int argc, char **argv, char **envp)
                      "ignoring option");
     }
 
+#if defined(CONFIG_GTK)
     if (display_type == DT_GTK) {
         early_gtk_display_init(request_opengl);
     }
-
+#endif
+#if defined(CONFIG_SDL)
     if (display_type == DT_SDL) {
         sdl_display_early_init(request_opengl);
     }
-
+#endif
     if (request_opengl == 1 && display_opengl == 0) {
 #if defined(CONFIG_OPENGL)
         error_report("OpenGL is not supported by the display");
@@ -4334,8 +4389,10 @@ int main(int argc, char **argv, char **envp)
 
     os_set_line_buffering();
 
+#ifdef CONFIG_SPICE
     /* spice needs the timers to be initialized by this point */
     qemu_spice_init();
+#endif
 
     cpu_ticks_init();
     if (icount_opts) {
@@ -4347,13 +4404,8 @@ int main(int argc, char **argv, char **envp)
         qemu_opts_del(icount_opts);
     }
 
-    if (default_net) {
-        QemuOptsList *net = qemu_find_opts("net");
-        qemu_opts_set(net, NULL, "type", "nic", &error_abort);
-#ifdef CONFIG_SLIRP
-        qemu_opts_set(net, NULL, "type", "user", &error_abort);
-#endif
-    }
+    /* clean up network at qemu process termination */
+    atexit(&net_cleanup);
 
     if (net_init_clients() < 0) {
         exit(1);
@@ -4431,9 +4483,9 @@ int main(int argc, char **argv, char **envp)
     if (default_vga) {
         if (machine_class->default_display) {
             vga_model = machine_class->default_display;
-        } else if (vga_interface_available(VGA_CIRRUS)) {
+        } else if (cirrus_vga_available()) {
             vga_model = "cirrus";
-        } else if (vga_interface_available(VGA_STD)) {
+        } else if (vga_available()) {
             vga_model = "std";
         }
     }
@@ -4447,10 +4499,10 @@ int main(int argc, char **argv, char **envp)
             exit (i == 1 ? 1 : 0);
     }
 
-    machine_register_compat_props(current_machine);
-
-    qemu_opts_foreach(qemu_find_opts("global"),
-                      global_init_func, NULL, NULL);
+    if (machine_class->compat_props) {
+        qdev_prop_register_global_list(machine_class->compat_props);
+    }
+    qemu_add_globals();
 
     /* This checkpoint is required by replay to separate prior clock
        reading from the other reads, because timer polling functions query
@@ -4480,7 +4532,7 @@ int main(int argc, char **argv, char **envp)
     }
 
     /* init USB devices */
-    if (machine_usb(current_machine)) {
+    if (usb_enabled()) {
         if (foreach_device_config(DEV_USB, usb_parse) < 0)
             exit(1);
     }
@@ -4499,18 +4551,7 @@ int main(int argc, char **argv, char **envp)
     /* Did we create any drives that we failed to create a device for? */
     drive_check_orphaned();
 
-    /* Don't warn about the default network setup that you get if
-     * no command line -net or -netdev options are specified. There
-     * are two cases that we would otherwise complain about:
-     * (1) board doesn't support a NIC but the implicit "-net nic"
-     * requested one
-     * (2) CONFIG_SLIRP not set, in which case the implicit "-net nic"
-     * sets up a nic that isn't connected to anything.
-     */
-    if (!default_net) {
-        net_check_clients();
-    }
-
+    net_check_clients();
 
     if (boot_once) {
         qemu_boot_set(boot_once, &error_fatal);
@@ -4521,18 +4562,28 @@ int main(int argc, char **argv, char **envp)
 
     /* init local displays */
     switch (display_type) {
+    case DT_NOGRAPHIC:
+        (void)ds;      /* avoid warning if no display is configured */
+        break;
+#if defined(CONFIG_CURSES)
     case DT_CURSES:
         curses_display_init(ds, full_screen);
         break;
+#endif
+#if defined(CONFIG_SDL)
     case DT_SDL:
         sdl_display_init(ds, full_screen, no_frame);
         break;
-    case DT_COCOA:
+#elif defined(CONFIG_COCOA)
+    case DT_SDL:
         cocoa_display_init(ds, full_screen);
         break;
+#endif
+#if defined(CONFIG_GTK)
     case DT_GTK:
         gtk_display_init(ds, full_screen, grab_on_hover);
         break;
+#endif
     default:
         break;
     }
@@ -4540,15 +4591,21 @@ int main(int argc, char **argv, char **envp)
     /* must be after terminal init, SDL library changes signal handlers */
     os_setup_signal_handling();
 
-    /* init remote displays */
 #ifdef CONFIG_VNC
+    /* init remote displays */
     qemu_opts_foreach(qemu_find_opts("vnc"),
                       vnc_init_func, NULL, NULL);
+    if (show_vnc_port) {
+        char *ret = vnc_display_local_addr("default");
+        printf("VNC server running on '%s'\n", ret);
+        g_free(ret);
+    }
 #endif
-
+#ifdef CONFIG_SPICE
     if (using_spice) {
         qemu_spice_display_init();
     }
+#endif
 
     if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
         exit(1);
@@ -4600,7 +4657,6 @@ int main(int argc, char **argv, char **envp)
 
     os_setup_post();
 
-    trace_init_vcpu_events();
     main_loop();
     replay_disable_events();
 
@@ -4611,11 +4667,5 @@ int main(int argc, char **argv, char **envp)
     tpm_cleanup();
 #endif
 
-    /* vhost-user must be cleaned up before chardevs.  */
-    net_cleanup();
-    audio_cleanup();
-    monitor_cleanup();
-    qemu_chr_cleanup();
-
     return 0;
 }
index 2f348ed..039680a 100644 (file)
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -9,8 +9,8 @@
  */
 
 #include "qemu/osdep.h"
+#include <sys/mman.h>
 
-#include "cpu.h"
 #include "hw/pci/pci.h"
 #include "hw/i386/pc.h"
 #include "hw/i386/apic-msidef.h"
@@ -190,9 +190,6 @@ static void xen_ram_init(PCMachineState *pcms,
     /* Handle the machine opt max-ram-below-4g.  It is basically doing
      * min(xen limit, user limit).
      */
-    if (!user_lowmem) {
-        user_lowmem = HVM_BELOW_4G_RAM_END; /* default */
-    }
     if (HVM_BELOW_4G_RAM_END <= user_lowmem) {
         user_lowmem = HVM_BELOW_4G_RAM_END;
     }
@@ -513,13 +510,8 @@ static void xen_io_add(MemoryListener *listener,
                        MemoryRegionSection *section)
 {
     XenIOState *state = container_of(listener, XenIOState, io_listener);
-    MemoryRegion *mr = section->mr;
-
-    if (mr->ops == &unassigned_io_ops) {
-        return;
-    }
 
-    memory_region_ref(mr);
+    memory_region_ref(section->mr);
 
     xen_map_io_section(xen_xc, xen_domid, state->ioservid, section);
 }
@@ -528,15 +520,10 @@ static void xen_io_del(MemoryListener *listener,
                        MemoryRegionSection *section)
 {
     XenIOState *state = container_of(listener, XenIOState, io_listener);
-    MemoryRegion *mr = section->mr;
-
-    if (mr->ops == &unassigned_io_ops) {
-        return;
-    }
 
     xen_unmap_io_section(xen_xc, xen_domid, state->ioservid, section);
 
-    memory_region_unref(mr);
+    memory_region_unref(section->mr);
 }
 
 static void xen_device_realize(DeviceListener *listener,
@@ -569,7 +556,7 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
 {
     hwaddr npages = size >> TARGET_PAGE_BITS;
     const int width = sizeof(unsigned long) * 8;
-    unsigned long bitmap[DIV_ROUND_UP(npages, width)];
+    unsigned long bitmap[(npages + width - 1) / width];
     int rc, i, j;
     const XenPhysmap *physmap = NULL;
 
@@ -738,7 +725,7 @@ static ioreq_t *cpu_get_ioreq(XenIOState *state)
     return NULL;
 }
 
-static uint32_t do_inp(uint32_t addr, unsigned long size)
+static uint32_t do_inp(pio_addr_t addr, unsigned long size)
 {
     switch (size) {
         case 1:
@@ -748,11 +735,11 @@ static uint32_t do_inp(uint32_t addr, unsigned long size)
         case 4:
             return cpu_inl(addr);
         default:
-            hw_error("inp: bad size: %04x %lx", addr, size);
+            hw_error("inp: bad size: %04"FMT_pioaddr" %lx", addr, size);
     }
 }
 
-static void do_outp(uint32_t addr,
+static void do_outp(pio_addr_t addr,
         unsigned long size, uint32_t val)
 {
     switch (size) {
@@ -763,7 +750,7 @@ static void do_outp(uint32_t addr,
         case 4:
             return cpu_outl(addr, val);
         default:
-            hw_error("outp: bad size: %04x %lx", addr, size);
+            hw_error("outp: bad size: %04"FMT_pioaddr" %lx", addr, size);
     }
 }
 
@@ -1203,7 +1190,11 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
         goto err;
     }
 
-    xen_create_ioreq_server(xen_xc, xen_domid, &state->ioservid);
+    rc = xen_create_ioreq_server(xen_xc, xen_domid, &state->ioservid);
+    if (rc < 0) {
+        perror("xen: ioreq server create");
+        goto err;
+    }
 
     state->exit.notify = xen_exit_notifier;
     qemu_add_exit_notifier(&state->exit);
@@ -1314,7 +1305,9 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
         error_report("xen backend core setup failed");
         goto err;
     }
-    xen_be_register_common();
+    xen_be_register("console", &xen_console_ops);
+    xen_be_register("vkbd", &xen_kbdmouse_ops);
+    xen_be_register("qdisk", &xen_blkdev_ops);
     xen_read_physmap(state);
     return;
 
index 8f3a592..49f394a 100644 (file)
@@ -17,6 +17,7 @@
 #include "qemu/bitmap.h"
 
 #include <xen/hvm/params.h>
+#include <sys/mman.h>
 
 #include "sysemu/xen-mapcache.h"
 #include "trace.h"